agent-device 0.16.4 → 0.16.6

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 (75) hide show
  1. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.16.4.apk → agent-device-android-multitouch-helper-0.16.6.apk} +0 -0
  2. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.16.6.apk.sha256 +1 -0
  3. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.16.4.manifest.json → agent-device-android-multitouch-helper-0.16.6.manifest.json} +4 -4
  4. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.16.6.apk +0 -0
  5. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.16.6.apk.sha256 +1 -0
  6. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.16.4.manifest.json → agent-device-android-snapshot-helper-0.16.6.manifest.json} +6 -6
  7. package/dist/src/1010.js +1 -0
  8. package/dist/src/1231.js +1 -1
  9. package/dist/src/1352.js +1 -0
  10. package/dist/src/1998.js +1 -0
  11. package/dist/src/208.js +1 -1
  12. package/dist/src/221.js +6 -6
  13. package/dist/src/2415.js +31 -0
  14. package/dist/src/2805.js +1 -0
  15. package/dist/src/5186.js +1 -0
  16. package/dist/src/5310.js +1 -0
  17. package/dist/src/5792.js +1 -0
  18. package/dist/src/6085.js +1 -0
  19. package/dist/src/6629.js +1 -0
  20. package/dist/src/8114.js +4 -0
  21. package/dist/src/8133.js +1 -0
  22. package/dist/src/8502.js +1 -0
  23. package/dist/src/8699.js +1 -0
  24. package/dist/src/8806.js +7 -0
  25. package/dist/src/940.js +1 -1
  26. package/dist/src/9404.js +1 -0
  27. package/dist/src/9471.js +1 -0
  28. package/dist/src/9533.js +1 -0
  29. package/dist/src/9542.js +3 -3
  30. package/dist/src/9639.js +1 -1
  31. package/dist/src/9671.js +1 -0
  32. package/dist/src/android-adb.js +1 -1
  33. package/dist/src/android-snapshot-helper.d.ts +2 -1
  34. package/dist/src/android-snapshot-helper.js +1 -1
  35. package/dist/src/android.js +5 -0
  36. package/dist/src/apple.js +1 -0
  37. package/dist/src/apps.js +13 -0
  38. package/dist/src/args.js +449 -0
  39. package/dist/src/batch.js +1 -1
  40. package/dist/src/cli.js +36 -492
  41. package/dist/src/command-metadata.js +1 -0
  42. package/dist/src/command-surface.js +1 -0
  43. package/dist/src/contracts.d.ts +1 -0
  44. package/dist/src/devices.js +1 -0
  45. package/dist/src/devices~1.js +1 -0
  46. package/dist/src/devices~2.js +1 -0
  47. package/dist/src/find.js +1 -0
  48. package/dist/src/finders.d.ts +1 -0
  49. package/dist/src/generic.js +9 -0
  50. package/dist/src/index.d.ts +12 -0
  51. package/dist/src/input-actions.js +1 -0
  52. package/dist/src/input-actions~1.js +1 -0
  53. package/dist/src/interaction.js +1 -0
  54. package/dist/src/internal/bin.js +5 -2
  55. package/dist/src/internal/daemon.js +1 -100
  56. package/dist/src/lease.js +1 -0
  57. package/dist/src/linux.js +1 -0
  58. package/dist/src/notifications.js +1 -0
  59. package/dist/src/react-native.js +1 -0
  60. package/dist/src/record-trace.js +26 -0
  61. package/dist/src/recording-provider.js +1 -0
  62. package/dist/src/selector-runtime.js +1 -0
  63. package/dist/src/selectors.d.ts +1 -0
  64. package/dist/src/server.js +1 -1
  65. package/dist/src/session.js +29 -0
  66. package/dist/src/snapshot.js +2 -0
  67. package/package.json +4 -1
  68. package/server.json +2 -2
  69. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.16.4.apk.sha256 +0 -1
  70. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.16.4.apk +0 -0
  71. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.16.4.apk.sha256 +0 -1
  72. package/dist/src/1769.js +0 -7
  73. package/dist/src/6277.js +0 -4
  74. package/dist/src/7519.js +0 -1
  75. package/dist/src/89.js +0 -1
@@ -0,0 +1 @@
1
+ import{promises as e}from"node:fs";import{deflateSync as t,inflateSync as n}from"node:zlib";import r from"node:path";import{asAppError as i,AppError as a}from"./9152.js";import{normalizeRef as o,centerOfRect as s,buildSnapshotPresentationKey as l,findNodeByRef as d}from"./4057.js";import{isScrollableNodeLike as c}from"./2842.js";import{successText as u}from"./1998.js";import{whichCmd as h,runCmd as p}from"./9818.js";import{trimText as f,extractNodeText as w,findSnapshotAncestor as m,parseSelectorChain as b,isNodeVisible as g,buildSnapshotNodeByIndex as y,isNodeEditable as x,buildTextPreview as v,findNearestHittableAncestor as k,buildSelectorChainForNode as I,findSelectorChainMatch as M,resolveSelectorChain as A,findNodeByLabel as N,resolveRefLabel as R,describeTextSurface as P,extractReadableText as S,formatSelectorFailure as D,normalizeType as E,isFillableType as O}from"./940.js";import{findBestMatchesByLocator as _}from"./7556.js";import"./7847.js";import{resolveAppsFilter as T,assertResolvedAppsFilter as $}from"./1393.js";let C=["status","get","dismiss","enter","return"];function L(e){return C.includes(e)}function U(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}function B(e){let t=e.direction,n="up"===t||"down"===t?e.referenceHeight:e.referenceWidth,r=function(e){if(void 0===e)return .6;if(!Number.isFinite(e)||e<=0)throw new a("INVALID_ARGS","scroll amount must be a positive number");return e}(e.amount),i=void 0!==e.pixels?function(e){if(!Number.isFinite(e)||e<=0)throw new a("INVALID_ARGS","scroll pixels must be a positive integer");return Math.max(1,Math.round(e))}(e.pixels):Math.round(n*r),o=Math.max(1,Math.round(.05*n)),s=Math.max(1,Math.min(i,Math.max(1,n-2*o))),l=Math.round(s/2),d=Math.round(e.referenceWidth/2),c=Math.round(e.referenceHeight/2),u=(n,r,i,a)=>({direction:t,x1:n,y1:r,x2:i,y2:a,referenceWidth:e.referenceWidth,referenceHeight:e.referenceHeight,amount:e.amount,pixels:s});switch(t){case"up":return u(d,c-l,d,c+l);case"down":return u(d,c+l,d,c-l);case"left":return u(d-l,c,d+l,c);case"right":return u(d+l,c,d-l,c)}}function G(e){return{...B({...e,direction:function(e){switch(e){case"up":return"down";case"down":return"up";case"left":return"right";case"right":return"left"}}(e.direction)}),direction:e.direction}}function F(e,t,n={}){let r=n.marginPx??8,i="android"===n.platform?65:50,[a,o,s]="left"===e?[90,10,i]:"right"===e?[10,90,i]:"left-edge"===e?[99,15,50]:[1,85,50],l=Y(t,a,s,{marginPx:r}),d=Y(t,o,s,{marginPx:r});return{preset:e,x1:l.x,y1:l.y,x2:d.x,y2:d.y,referenceWidth:t.referenceWidth,referenceHeight:t.referenceHeight}}function q(e){switch(e){case"left":case"right":case"left-edge":case"right-edge":return e;default:throw new a("INVALID_ARGS","gesture swipe requires left, right, left-edge, or right-edge")}}function X(e){let t=function(e){let t=e.filter(e=>(function(e){if(!e)return!1;let t=e.toLowerCase();return t.includes("application")||t.includes("window")})(e.type)&&z(e.rect)).map(e=>e.rect).sort((e,t)=>(t?.width??0)*(t?.height??0)-(e?.width??0)*(e?.height??0))[0];if(t)return t;let n=e.map(e=>e.rect).filter(z);if(0===n.length)return;let r=Math.max(...n.map(e=>e.x+e.width)),i=Math.max(...n.map(e=>e.y+e.height));if(!(r<=0)&&!(i<=0))return{x:0,y:0,width:r,height:i}}(e);if(t)return{referenceWidth:t.width,referenceHeight:t.height}}function Y(e,t,n,r={}){let i={x:Math.round(e.referenceWidth*t/100),y:Math.round(e.referenceHeight*n/100)};return void 0===r.marginPx?i:V(i,e,r.marginPx)}function V(e,t,n){return{x:K(e.x,n,t.referenceWidth),y:K(e.y,n,t.referenceHeight)}}function H(e){switch(e){case"up":case"down":case"left":case"right":return e;default:throw new a("INVALID_ARGS",`Unknown direction: ${e}`)}}function z(e){return!!e&&e.width>0&&e.height>0}function K(e,t,n){let r=Math.max(t,n-t);return j(e,t,r)}function j(e,t,n){return Math.min(Math.round(n),Math.max(Math.round(t),Math.round(e)))}function W(e,t,n){return t>=e.x&&t<=e.x+e.width&&n>=e.y&&n<=e.y+e.height}function J(e){let t=null,n=-1;for(let r of e){let e=r.width*r.height;e>n&&(t=r,n=e)}return t}function Z(e,t,n,r){return Math.max(e,n)<=Math.min(t,r)}function Q(e){let t=e.trim().toLowerCase();return!!t&&/^(vertical|horizontal)\s+scroll\s+bar(?:,?\s*\d+\s+pages?)?$/.test(t)}function ee(e,t){if(!(e?.trim().toLowerCase()??"").includes("vertical scroll bar"))return null;let n=function(e){if(!e)return null;let t=/^(\d{1,3})%$/.exec(e.trim());if(!t)return null;let n=Number(t[1]);return Number.isFinite(n)?Math.max(0,Math.min(100,n)):null}(t);return null===n?null:n<=1?{above:!1,below:!0}:n>=99?{above:!0,below:!1}:{above:!0,below:!0}}function et(e){let t=new Map;for(let[n,r]of e.entries())t.set(r.index,n);let n=[],r=[];for(let[i,a]of e.entries()){let e=Math.max(0,a.depth??0);for(;r.length>0&&e<=r[r.length-1].depth;)r.pop();let o="number"==typeof a.parentIndex?t.get(a.parentIndex):void 0,s="number"==typeof o&&o<i?o:r[r.length-1]?.index;n.push({...a,index:i,depth:e,parentIndex:s}),r.push({depth:e,index:i})}return n}function en(e){return new Map(e.map(e=>[e.index,e]))}function er(e){return e.label?.trim()||e.value?.trim()||e.identifier?.trim()||""}function ei(e){if(0===e.length)return{nodes:e,hiddenCount:0,summaryLines:[]};let{byIndex:t,visibleNodeIndexes:n,offscreenNodes:r,hintedContainers:i}=eo(e),a=0===n.size?e:e.filter(e=>n.has(e.index));return{nodes:a.map(e=>(function(e,t){let n=t.get(e.index);if(!n||0===n.size)return e;let r=!!(!0===e.hiddenContentAbove||n.has("above"))||void 0,i=!!(!0===e.hiddenContentBelow||n.has("below"))||void 0;return{...e,hiddenContentAbove:r,hiddenContentBelow:i}})(e,i.directionsByContainer)),hiddenCount:0===n.size?0:e.length-a.length,summaryLines:function(e,t,n){let r=new Map;for(let i of e){let e=function(e,t,n){if(!e.rect)return null;let r=el(e,t,n);return r?ed(e.rect,r):null}(i,t,n);if(!e)continue;let a=r.get(e)??[];a.push(i),r.set(e,a)}return["above","below"].flatMap(e=>{let t=r.get(e);if(!t||0===t.length)return[];let n=(function(e){let t=new Set,n=[];for(let r of e){let e=er(r);!e||t.has(e)||(t.add(e),n.push(e))}return n})(t).slice(0,3).map(e=>`"${e}"`),i=1===t.length?"interactive item":"interactive items",a=n.length>0?`: ${n.join(", ")}`:"";return[`[off-screen ${e}] ${t.length} ${i}${a}`]})}(r.filter(e=>!i.coveredNodeIndexes.has(e.index)&&function(e){if(!0===e.hittable)return!0;let t=(e.type??"").toLowerCase();return t.includes("button")||t.includes("link")||t.includes("textfield")||t.includes("edittext")||t.includes("searchfield")||t.includes("checkbox")||t.includes("radio")||t.includes("switch")||t.includes("menuitem")||!!er(e)}(e)),e,t)}}function ea(e){if(0===e.length)return new Map;let{hintedContainers:t}=eo(e);var n=t.directionsByContainer;let r=new Map;for(let[e,t]of n){let n={};t.has("above")&&(n.hiddenContentAbove=!0),t.has("below")&&(n.hiddenContentBelow=!0),(n.hiddenContentAbove||n.hiddenContentBelow)&&r.set(e,n)}return r}function eo(e){let t=en(e),n=new Set,r=[];for(let i of e){if(es(i,e,t)){!function(e,t,n){let r=e,i=new Set;for(;r&&!i.has(r.index);)i.add(r.index),t.add(r.index),r="number"==typeof r.parentIndex?n.get(r.parentIndex):void 0}(i,n,t);continue}r.push(i)}let i=function(e,t,n,r){let i=new Map,a=new Map,o=new Set;for(let e of t){if(!e.rect)continue;let t=ec(e,n,r);if(!t?.rect)continue;let s=ed(e.rect,t.rect);if(!s)continue;let l=i.get(t.index)??new Set;l.add(s),i.set(t.index,l);let d=a.get(t.index)??new Set;d.add(s),a.set(t.index,d),o.add(e.index)}return function(e,t,n,r,i){for(let a of e){let e=function(e){let t=ee(e.label,e.value);if(!t)return null;let n=new Set;return t.above&&n.add("above"),t.below&&n.add("below"),n.size>0?n:null}(a);if(!e||0===e.size)continue;let o=ec(a,t,n);if(!o)continue;let s=r.get(o.index)??new Set,l=i.get(o.index);for(let t of e)(!l||!(l.size>0)||l.has(t))&&s.add(t);r.set(o.index,s)}}(e,n,r,i,a),{directionsByContainer:i,coveredNodeIndexes:o}}(e,r,n,t);return{byIndex:t,visibleNodeIndexes:n,offscreenNodes:r,hintedContainers:i}}function es(e,t,n=en(t)){var r;if(!e.rect)return!0;let i=el(e,t,n);return!i||(r=e.rect,Z(r.x,r.x+r.width,i.x,i.x+i.width)&&Z(r.y,r.y+r.height,i.y,i.y+i.height))}function el(e,t,n=en(t)){var r,i;let a=(r=e,i=n,eu(r,i,e=>!!e.rect)?.rect??null);return a||function(e,t){let n=s(t),r=e.filter(e=>{var t;return!!(t=e.rect)&&Number.isFinite(t.x)&&Number.isFinite(t.y)&&Number.isFinite(t.width)&&Number.isFinite(t.height)}),i=r.filter(e=>{let t=(e.type??"").toLowerCase();return t.includes("application")||t.includes("window")}),a=J(i.map(e=>e.rect).filter(e=>W(e,n.x,n.y)));if(a)return a;let o=J(i.map(e=>e.rect));if(o)return o;let l=J(r.map(e=>e.rect).filter(e=>W(e,n.x,n.y)));return l||null}(t,e.rect??{x:0,y:0,width:0,height:0})}function ed(e,t){return e.y+e.height<=t.y?"above":e.y>=t.y+t.height?"below":null}function ec(e,t,n){return eu(e,n,e=>t.has(e.index))}function eu(e,t,n){let r="number"==typeof e.parentIndex?t.get(e.parentIndex):void 0,i=new Set;for(;r&&!i.has(r.index);){if(i.add(r.index),n(r)&&c(r))return r;r="number"==typeof r.parentIndex?t.get(r.parentIndex):void 0}return null}async function eh(e){let{edge:t,target:n={},scope:r,captureNodes:i}=e;try{let e=await i(r),a=function(e,t,n={}){var r,i,a;let o,s=(e??[]).map((e,t)=>({...e,ref:"ref"in e&&e.ref?e.ref:`e${t+1}`}));if(0===s.length)return{canScroll:!1,emptySnapshot:!0,signature:""};let l=ea(s),d=function(e,t,n,r){let i=new Map(e.map(e=>[e.index,e])),a=e.filter(e=>c(e)&&ex(e.rect));if(0===a.length)return null;let o=function(e,t){if(void 0===e)return null;let n=t.get(e);for(;n;){if(c(n)&&ex(n.rect))return n;n=void 0===n.parentIndex?void 0:t.get(n.parentIndex)}return null}(r.nodeIndex,i);if(o)return o;let s=r.point;if(s){let e=a.filter(e=>{var t,n;return e.rect&&(t=e.rect,(n=s).x>=t.x&&n.x<=t.x+t.width&&n.y>=t.y&&n.y<=t.y+t.height)}).sort(eb);if(e.length>0)return e.find(e=>ew(e,t.get(e.index),n))??e[0]??null}let l=a.filter(e=>ew(e,t.get(e.index),n)).sort(eg);return l.length>0?l[0]??null:a.filter(t=>es(t,e)).sort(eg)[0]??a.sort(eg)[0]??null}(s,l,t,n),u=(d?(r=s,i=d.index,o=new Map(r.map(e=>[e.index,e])),r.filter(e=>e.index===i||function(e,t,n){let r=void 0===e.parentIndex?void 0:n.get(e.parentIndex);for(;r;){if(r.index===t)return!0;r=void 0===r.parentIndex?void 0:n.get(r.parentIndex)}return!1}(e,i,o))):s).map(e=>{let t=e.rect?["x","y","width","height"].map(t=>{var n;return n=e.rect?.[t],"number"==typeof n&&Number.isFinite(n)?n.toFixed(1):""}).join(","):"";return[String(e.index??""),String(e.parentIndex??""),String(e.type??""),String(e.label??""),String(e.value??""),t].join("|")}).join("\n");return d?{canScroll:ew(d,l.get(d.index),t),emptySnapshot:!1,signature:u,scope:[(a=d).identifier,a.label,a.value].map(e=>"string"==typeof e?e.trim():"").find(em)}:{canScroll:!1,emptySnapshot:!1,signature:u}}(e,t,n);if(r&&a.emptySnapshot)return await eh({edge:t,target:n,captureNodes:i});return a}catch(e){var o,s,l;throw o=t,s=r,l=e,s?new a("COMMAND_FAILED",`Failed to verify scroll ${o} state for scoped container`,{scope:s,hint:`scroll ${o} could not verify the scoped scroll container. Run snapshot -i -c for the current screen and retry with a visible scroll target.`},l):new a("COMMAND_FAILED",`Failed to verify scroll ${o} state`,{hint:`scroll ${o} needs a snapshot showing hidden content ${"bottom"===o?"below":"above"} before it will move.`},l)}}async function ep(e){let t,{edge:n,captureState:r,scroll:i}=e,o=await r();o.scope&&(o=await r(o.scope));let s=0;for(;o.canScroll;){if(s>=40)throw new a("COMMAND_FAILED",`scroll ${n} reached the safety limit before the snapshot showed the edge`,{hint:"The scoped scroll container still reports hidden content. Use a smaller manual scroll + snapshot loop to inspect the current state."});t=await i(),s+=1,o=await r(o.scope)}return{passes:s,result:t}}function ef(e,t,n,r,i){return t&&0===n?`Already at ${t}; no hidden content ${"bottom"===t?"below":"above"} detected`:t?`Scrolled to ${t} with ${n} ${e} passes`:void 0!==i?`Scrolled ${e} by ${i}px`:void 0!==r?`Scrolled ${e} by ${r}`:`Scrolled ${e}`}function ew(e,t,n){return"bottom"===n?!0===e.hiddenContentBelow||t?.hiddenContentBelow===!0:!0===e.hiddenContentAbove||t?.hiddenContentAbove===!0}function em(e){return e.length>0&&e.length<=80&&!/^(true|false)$/i.test(e)&&!/^\d+$/.test(e)&&!/^\d+%$/.test(e)}function eb(e,t){return ey(e.rect)-ey(t.rect)}function eg(e,t){return ey(t.rect)-ey(e.rect)}function ey(e){return e?e.width*e.height:0}function ex(e){return!!(e&&e.width>0&&e.height>0)}function ev(e,t,n,r){if(!Number.isFinite(e)||!Number.isInteger(e)||e<n||e>r)throw new a("INVALID_ARGS",`${t} must be an integer between ${n} and ${r}`);return e}function ek(e){let t=e?.trim().toLowerCase();return!!t&&(t.includes("open debugger to view warnings")||/^!,\s+/.test(t)||/^(warn|warning|error):\s+/.test(t)||/\b(?:possible\s+)?unhandled (?:promise )?rejection\b/.test(t)||t.includes("getsnapshot should be cached to avoid an infinite loop")||t.includes('unique "key" prop')||t.includes("unique 'key' prop")||t.includes("virtualizedlists should never be nested")||t.includes("failed prop type"))}function eI(e){return e.includes("open debugger to view warnings")||/^!,\s+open debugger\b/.test(e)}let eM=Buffer.from([137,80,78,71,13,10,26,10]),eA=new Map([[0,1],[2,3],[3,1],[4,2],[6,4]]),eN=new Map([[0,new Set([1,2,4,8,16])],[2,new Set([8,16])],[3,new Set([1,2,4,8])],[4,new Set([8,16])],[6,new Set([8,16])]]),eR=[{x:0,y:0,dx:8,dy:8},{x:4,y:0,dx:8,dy:8},{x:0,y:4,dx:4,dy:8},{x:2,y:0,dx:4,dy:4},{x:0,y:2,dx:2,dy:4},{x:1,y:0,dx:2,dy:2},{x:0,y:1,dx:1,dy:2}];class eP{width;height;data;static sync={read:eS,write:eD};constructor(e){this.width=eB(e.width,"width"),this.height=eB(e.height,"height");let t=this.width*this.height*4;if(this.data=e.data?Buffer.from(e.data):Buffer.alloc(t),this.data.length!==t)throw Error(`PNG data length must be ${t} bytes`)}}function eS(e){var t;let{metadata:r,idatChunks:i}=function(e){let t,n=[];for(let r of function*(e){if(!e.subarray(0,eM.length).equals(eM))throw Error("Invalid PNG signature");let t=eM.length;for(;t<e.length;){if(t+12>e.length)throw Error("Truncated PNG chunk");let n=e.readUInt32BE(t),r=e.toString("ascii",t+4,t+8),i=t+8,a=i+n;if(a+4>e.length)throw Error(`Truncated PNG ${r} chunk`);let o=e.subarray(i,a),s=e.readUInt32BE(a);if(eU(e.subarray(t+4,a))!==s)throw Error(`Invalid PNG ${r} chunk CRC`);t=a+4,yield{type:r,data:o}}}(e))if("IHDR"===r.type?t=function(e){var t;if(13!==e.length)throw Error("Invalid PNG IHDR length");let n=e.readUInt32BE(0),r=e.readUInt32BE(4),i=e[8],a=e[9],o=e[10],s=e[11],l=e[12];if(t=a,!eA.has(t))throw Error(`Unsupported PNG color type ${a}`);let d=eN.get(a);if(!d?.has(i))throw Error(`Unsupported PNG color type ${a} with bit depth ${i}`);if(0!==o)throw Error(`Unsupported PNG compression method ${o}`);if(0!==s)throw Error(`Unsupported PNG filter method ${s}`);if(0!==l&&1!==l)throw Error(`Unsupported PNG interlace method ${l}`);return{width:eB(n,"width"),height:eB(r,"height"),bitDepth:i,colorType:a,interlace:l}}(r.data):"IDAT"===r.type?n.push(Buffer.from(r.data)):t=function(e,t){if("PLTE"===e.type){if(!t)throw Error("PNG PLTE appeared before IHDR");t.palette=Buffer.from(e.data)}else if("tRNS"===e.type){if(!t)throw Error("PNG tRNS appeared before IHDR");t.transparency=Buffer.from(e.data)}return t}(r,t),"IEND"===r.type)break;return{metadata:t,idatChunks:n}}(e);if(!r)throw Error("PNG is missing IHDR");if(0===i.length)throw Error("PNG is missing IDAT");let a=function(e,t){let r=function(e){if(0===e.interlace)return function(e,t){return(e$(e)+1)*t}(e,e.height);let t=0;for(let n of eR){let r=eO(e.width,n.x,n.dx),i=eO(e.height,n.y,n.dy);0!==r&&0!==i&&(t+=function(e,t){return(e$(e)+1)*t}({...e,width:r,height:i},i))}return t}(t);try{let t=n(Buffer.concat(e),{maxOutputLength:r});if(t.length!==r)throw Error("PNG pixel data is truncated");return t}catch(e){var i;if((i=e)instanceof Error&&"code"in i&&"ERR_BUFFER_TOO_LARGE"===i.code)throw Error(`PNG pixel data exceeds expected length ${r}`);throw e}}(i,r);return new eP({width:r.width,height:r.height,data:1===r.interlace?function(e,t){let n=Buffer.alloc(t.width*t.height*4),r=0;for(let i of eR){let a=eO(t.width,i.x,i.dx),o=eO(t.height,i.y,i.dy);if(0===a||0===o)continue;let s={...t,width:a,height:o,interlace:0},l=eE({inflated:e,offset:r,scanlineLength:e$(s),height:o,bytesPerPixel:eC(s)});r=l.offset;let d=e$(s);for(let e=0;e<o;e+=1){let r=l.raw.subarray(e*d,(e+1)*d);for(let o=0;o<a;o+=1){let a=i.x+o*i.dx,l=((i.y+e*i.dy)*t.width+a)*4,[d,c,u,h]=e_(r,o,s);n[l]=d,n[l+1]=c,n[l+2]=u,n[l+3]=h}}}return n}(a,r):function(e,t){let n=Buffer.alloc(t.width*t.height*4),r=e$(t);for(let i=0;i<t.height;i+=1){let a=e.subarray(i*r,(i+1)*r);for(let e=0;e<t.width;e+=1){let r=(i*t.width+e)*4,[o,s,l,d]=e_(a,e,t);n[r]=o,n[r+1]=s,n[r+2]=l,n[r+3]=d}}return n}(eE({inflated:a,offset:0,scanlineLength:e$(t=r),height:t.height,bytesPerPixel:eC(t)}).raw,r)})}function eD(e){let n=4*e.width,r=Buffer.alloc((n+1)*e.height);for(let t=0;t<e.height;t+=1){let i=t*(n+1);r[i]=0,e.data.copy(r,i+1,t*n,(t+1)*n)}let i=Buffer.alloc(13);return i.writeUInt32BE(e.width,0),i.writeUInt32BE(e.height,4),i[8]=8,i[9]=6,i[10]=0,i[11]=0,i[12]=0,Buffer.concat([eM,eL("IHDR",i),eL("IDAT",t(r)),eL("IEND",Buffer.alloc(0))])}function eE(e){let{inflated:t,offset:n,scanlineLength:r,height:i,bytesPerPixel:a}=e,o=n+(r+1)*i;if(t.length<o)throw Error("PNG pixel data is truncated");let s=Buffer.alloc(r*i);for(let e=0;e<i;e+=1){let i=n+e*(r+1),o=e*r,l=t[i];for(let n=0;n<r;n+=1){let d=t[i+1+n],c=n>=a?s[o+n-a]:0,u=e>0?s[o+n-r]:0,h=e>0&&n>=a?s[o+n-r-a]:0;s[o+n]=function(e,t,n,r,i){if(0===e)return t;if(1===e)return t+n&255;if(2===e)return t+r&255;if(3===e)return t+Math.floor((n+r)/2)&255;if(4===e)return t+function(e,t,n){let r=e+t-n,i=Math.abs(r-e),a=Math.abs(r-t),o=Math.abs(r-n);return i<=a&&i<=o?e:a<=o?t:n}(n,r,i)&255;throw Error(`Unsupported PNG filter type ${e}`)}(l,d,c,u,h)}}return{raw:s,offset:o}}function eO(e,t,n){return e<=t?0:Math.floor((e-t+n-1)/n)}function e_(e,t,n){if(3===n.colorType){var r,i,a,o,s,l,d,c=e,u=t,h=n;if(!h.palette)throw Error("Indexed PNG is missing PLTE");let p=eT(c,u,h.bitDepth),f=3*p;if(f+2>=h.palette.length)throw Error("Indexed PNG palette is invalid");return[h.palette[f],h.palette[f+1],h.palette[f+2],h.transparency?.[p]??255]}if(n.bitDepth<8){let i,a;return[a=Math.round((i=eT(e,t,(r=n).bitDepth))/((1<<r.bitDepth)-1)*255),a,a,255*!(r.transparency&&r.transparency.length>=2&&i===r.transparency.readUInt16BE(0))]}let p=16===n.bitDepth?2:1,f=t*eA.get(n.colorType)*p,w=t=>16===n.bitDepth?e.readUInt16BE(f+2*t):e[f+t*p],m=e=>{var t;return t=w(e),16===n.bitDepth?Math.round(t/65535*255):t};if(0===n.colorType){let e=m(0);return[e,e,e,255*(i=w(0),!(a=n).transparency||!!(a.transparency.length<2)||i!==a.transparency.readUInt16BE(0))]}if(2===n.colorType){return[m(0),m(1),m(2),255*(o=w(0),s=w(1),l=w(2),!(d=n).transparency||!!(d.transparency.length<6)||o!==d.transparency.readUInt16BE(0)||s!==d.transparency.readUInt16BE(2)||l!==d.transparency.readUInt16BE(4))]}if(4===n.colorType){let e=m(0);return[e,e,e,m(1)]}return[m(0),m(1),m(2),m(3)]}function eT(e,t,n){let r=t*n;return e[Math.floor(r/8)]>>8-n-r%8&(1<<n)-1}function e$(e){let t=eA.get(e.colorType);return Math.ceil(e.width*t*e.bitDepth/8)}function eC(e){return Math.max(1,Math.ceil(eA.get(e.colorType)*e.bitDepth/8))}function eL(e,t){let n=Buffer.from(e,"ascii"),r=Buffer.alloc(8+t.length+4);return r.writeUInt32BE(t.length,0),n.copy(r,4),t.copy(r,8),r.writeUInt32BE(eU(Buffer.concat([n,t])),8+t.length),r}function eU(e){let t=0xffffffff;for(let n of e){t^=n;for(let e=0;e<8;e+=1)t=1&t?0xedb88320^t>>>1:t>>>1}return(0xffffffff^t)>>>0}function eB(e,t){if(!Number.isInteger(e)||e<1)throw Error(`PNG ${t} must be positive`);return e}function eG(e,t){try{return eP.sync.read(e)}catch(e){throw new a("COMMAND_FAILED",`Failed to decode ${t} as PNG`,{label:t,reason:e instanceof Error?e.message:String(e)})}}async function eF(t,n){if(!Number.isInteger(n)||n<1)throw new a("INVALID_ARGS","Screenshot max size must be a positive integer");let r=eG(await e.readFile(t),"screenshot"),i=Math.max(r.width,r.height);if(i<=n)return;let o=n/i,s=Math.max(1,Math.round(r.width*o)),l=Math.max(1,Math.round(r.height*o)),d=function(e,t,n){let r=new eP({width:t,height:n});for(let i=0;i<n;i+=1){let a=i*e.height/n,o=(i+1)*e.height/n;for(let n=0;n<t;n+=1){let s=n*e.width/t,l=(n+1)*e.width/t,d=0,c=0,u=0,h=0,p=0;for(let t=Math.floor(a);t<Math.ceil(o);t+=1){let n=Math.min(t+1,o)-Math.max(t,a);for(let r=Math.floor(s);r<Math.ceil(l);r+=1){let i=n*(Math.min(r+1,l)-Math.max(r,s)),a=(t*e.width+r)*4;d+=(e.data[a]??0)*i,c+=(e.data[a+1]??0)*i,u+=(e.data[a+2]??0)*i,h+=(e.data[a+3]??0)*i,p+=i}}let f=(i*r.width+n)*4;r.data[f]=Math.round(d/p),r.data[f+1]=Math.round(c/p),r.data[f+2]=Math.round(u/p),r.data[f+3]=Math.round(h/p)}}return r}(r,s,l);await e.writeFile(t,eP.sync.write(d))}async function eq(e,t,n){if("path"===t.kind&&!e.policy.allowLocalInputPaths)throw new a("INVALID_ARGS",`Local ${n.field??"input"} paths are not allowed by command policy`);try{return await e.artifacts.resolveInput(t,n)}catch(e){throw i(e)}}async function eX(e,t,n){if(t?.kind==="path"&&!e.policy.allowLocalOutputPaths)throw new a("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 i(e)}}async function eY(e,t){try{return await e.artifacts.createTempFile(t)}catch(e){throw i(e)}}let eV=async(e,t)=>{let n;if(!e.backend.captureScreenshot)throw new a("UNSUPPORTED_OPERATION","screenshot is not supported by this backend");let r=await eX(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},r.path,{fullscreen:t.fullscreen,overlayRefs:t.overlayRefs,stabilize:t.stabilize,surface:t.surface}),void 0!==t.maxSize&&await eF(r.path,t.maxSize),n=await r.publish()}catch(e){throw await r.cleanup?.(),e}return{path:r.path,...n?{artifacts:[n]}:{},...u(`Saved screenshot: ${r.path}`)}},eH=[0,187,255,255];function ez(e,t,n,r){if(t<0||t>=e.width||n<0||n>=e.height)return;let i=(n*e.width+t)*4;e.data[i]=r[0],e.data[i+1]=r[1],e.data[i+2]=r[2],e.data[i+3]=r[3]}function eK(e,t,n){return Math.min(Math.max(e,t),n)}let ej=[{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 eW(e){let{mask:t,width:n,height:r,hooks:i}=e,a=new Uint8Array(t.length),o=new Int32Array(t.length),s=[];for(let e=0;e<t.length;e+=1){var l,d;if(!eJ(t,a,e))continue;let c=0,u=(l=o,a[d=e]=1,l[0]=d,1),h=i.create(e);for(;c<u;){let e=o[c];c+=1,i.visit(h,e),u=function(e){let{mask:t,visited:n,queue:r,width:i,height:a,pixelIndex:o}=e,s=o%i,l=Math.floor(o/i),d=e.queueEnd;for(let e of ej){var c,u,h,p;let o=s+e.x,f=l+e.y;if(c=o,u=f,h=i,p=a,!(c>=0)||!(c<h)||!(u>=0)||!(u<p))continue;let w=f*i+o;eJ(t,n,w)&&(d=function(e,t,n,r){return t[r]=1,e[n]=r,n+1}(r,n,d,w))}return d}({mask:t,visited:a,queue:o,queueEnd:u,width:n,height:r,pixelIndex:e})}s.push(h)}return s}function eJ(e,t,n){return 1===e[n]&&1!==t[n]}function eZ(e){let t=1/0,n=1/0,r=-1/0,i=-1/0;for(let a of e)t=Math.min(t,a.x),n=Math.min(n,a.y),r=Math.max(r,a.x+a.width),i=Math.max(i,a.y+a.height);return{x:t,y:n,width:r-t,height:i-n}}function eQ(e,t){let n=Math.max(e.x,t.x),r=Math.max(e.y,t.y),i=Math.min(e.x+e.width,t.x+t.width),a=Math.min(e.y+e.height,t.y+t.height);return i<=n||a<=r?0:(i-n)*(a-r)}function e0(e){return{x:e.x+e.width/2,y:e.y+e.height/2}}function e1(e,t){return(e.x-t.x)**2+(e.y-t.y)**2}function e2(e,t,n){return Math.min(Math.max(e,t),n)}let e5={icon:90,toggle:90,chevron:75,separator:45,visual:35,background:10},e4={leading:20,trailing:20,separator:10,unknown:0,background:-30};function e8(e){return"background"!==e.likelyKind}function e3(e,t){return e.width>=.25*t.width||e.height>=.06*t.height}function e6(e,t){let n,r=0;for(let i of t){let t=tn(e,i.rect);t<=r||(r=t,n=i)}return n}function e9(e){let t=[];for(let n of[...e].sort((e,t)=>e.rect.y-t.rect.y)){let e=t.find(e=>{var t,r;return t=e.rect,tn(t,r=n.rect)>0||Math.abs(e0(t).y-e0(r).y)<=.5*Math.max(t.height,r.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=eZ([e.rect,n.rect])}return t}function e7(e,t){let n,r=e0(e);for(let e of t){let t=Math.sqrt(e1(r,e0(e.rect)));n&&t>=n.distance||(n={block:e,distance:t})}return n}function te(e){let t=tt(e);return e.differentPixels>=24&&t.width>=3&&t.height>=3}function tt(e){return{x:e.minX,y:e.minY,width:e.maxX-e.minX+1,height:e.maxY-e.minY+1}}function tn(e,t){return Math.max(0,Math.min(e.y+e.height,t.y+t.height)-Math.max(e.y,t.y))}async function tr(e){if(await h("tesseract"))try{let[t,n]=await Promise.all([ta(e.baselinePath),ta(e.currentPath)]);if(0!==t.exitCode||0!==n.exitCode)return;let r=ti(t.stdout,e.width,e.height),i=ti(n.stdout,e.width,e.height),a=function(e,t){let n=new Set,r=[];for(let a of e){var i;let e=tu(a.text),o=function(e,t,n,r){let i=null,a=1/0;for(let o=0;o<n.length;o+=1){if(r.has(o))continue;let s=n[o];if(tu(s.text)!==t)continue;let l=e1(e0(e.normalizedRect),e0(s.normalizedRect));l>=a||(i=o,a=l)}return i}(a,e,t,n);if(null===o)continue;n.add(o);let s=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},r=tf(t.rect.width/e.rect.width),i=tf(t.rect.height/e.rect.height),a=Math.abs(r-1)>=.08||Math.abs(i-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:a}}(a,t[o]);i=s,(Math.abs(i.delta.x)>=2||Math.abs(i.delta.y)>=2||Math.abs(i.delta.width)>=2||Math.abs(i.delta.height)>=2||i.possibleTextMetricMismatch)&&r.push(s)}return r.sort((e,t)=>to(t)-to(e)).slice(0,12)}(r,i),o=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-th(e.map(e=>e.delta.x))));e?e.push(n):t.push([n])}return t.filter(e=>e.length>=2).map(ts).filter(e=>e.yRange.max-e.yRange.min<=60).sort((e,t)=>tl(t)-tl(e)).slice(0,4)}(a);if(0===r.length&&0===i.length)return;return{provider:"tesseract",baselineBlocks:r.length,currentBlocks:i.length,baselineBlocksRaw:r,currentBlocksRaw:i,matches:a,...o.length>0?{movementClusters:o}:{}}}catch{return}}function ti(e,t,n){let[r,...i]=e.split(/\r?\n/);if(!r)return[];let a=new Map(r.split(" ").map((e,t)=>[e,t])),o=[];for(let e of i){var s;if(!e.trim())continue;let t=e.split(" "),n=tc(t,a,"level"),r=td(t,a,"text").trim(),i=tc(t,a,"conf");if(5!==n||(s=r,!/[\p{L}\p{N}]/u.test(s))||i<0)continue;let l=tc(t,a,"left"),d=tc(t,a,"top"),c=tc(t,a,"width"),u=tc(t,a,"height");c<=0||u<=0||o.push({key:[td(t,a,"page_num"),td(t,a,"block_num"),td(t,a,"par_num"),td(t,a,"line_num")].join(":"),text:r,confidence:i,rect:{x:l,y:d,width:c,height:u}})}let l=new Map;for(let e of o){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=[],r=[];for(let e of t){let t=r.at(-1);if(!t){r.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(r),r=[e];continue}r.push(e)}return r.length>0&&n.push(r),n})(e)).map(e=>(function(e,t,n){if(0===e.length)return null;let r=[...e].sort((e,t)=>e.rect.x-t.rect.x),i=eZ(r.map(e=>e.rect)),a=Math.round(100*th(r.map(e=>e.confidence)))/100;return{text:r.map(e=>e.text).join(" "),confidence:a,rect:i,normalizedRect:{x:tp(i.x/t),y:tp(i.y/n),width:tp(i.width/t),height:tp(i.height/n)}}})(e,t,n)).filter(e=>null!==e)}function ta(e){return p("tesseract",[e,"stdout","-l","eng","tsv"],{allowFailure:!0,timeoutMs:1e4})}function to(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 ts(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 tl(e){return 2*Math.abs((e.xRange.min+e.xRange.max)/2)+Math.abs((e.yRange.min+e.yRange.max)/2)}function td(e,t,n){let r=t.get(n);return void 0===r?"":e[r]??""}function tc(e,t,n){let r=Number(td(e,t,n));return Number.isFinite(r)?r:0}function tu(e){return e.trim().replace(/\s+/g," ").toLowerCase()}function th(e){return e.reduce((e,t)=>e+t,0)/e.length}function tp(e){return Math.round(100*e*100)/100}function tf(e){return Math.round(1e3*e)/1e3}function tw(e,t,n,r){return{r:Math.round(e/r),g:Math.round(t/r),b:Math.round(n/r)}}function tm(e){return .2126*e.r+.7152*e.g+.0722*e.b}function tb(e){return`#${tg(e.r)}${tg(e.g)}${tg(e.b)}`}function tg(e){return e.toString(16).padStart(2,"0")}function ty(e){return Math.round(100*e*100)/100}let tx=255*Math.sqrt(3);async function tv(t,n,i={}){var a,o,s,l,d;let c,u,h,p;await tk(t,"Baseline image not found"),await tk(n,"Current screenshot not found");let f=i.outputPath,[w,m]=await Promise.all([e.readFile(t),e.readFile(n)]),b=eG(w,"baseline screenshot"),g=eG(m,"current screenshot");tI(b.width,b.height,"baseline screenshot",i.maxPixels),tI(g.width,g.height,"current screenshot",i.maxPixels);let y=i.threshold??.1;if(b.width!==g.width||b.height!==g.height){let e=b.width*b.height;return await tM(i.outputPath),{match:!1,mismatchPercentage:100,totalPixels:e,differentPixels:e,dimensionMismatch:{expected:{width:b.width,height:b.height},actual:{width:g.width,height:g.height}}}}let x=b.width*b.height,v=y*tx,k=new eP({width:b.width,height:b.height}),I=new Uint8Array(x),M=0;for(let e=0,t=0;e<b.data.length;e+=4,t+=1){if(Math.sqrt((b.data[e]-g.data[e])**2+(b.data[e+1]-g.data[e+1])**2+(b.data[e+2]-g.data[e+2])**2)>v){M+=1,I[t]=1;let n=tA(g,e);k.data[e]=tN(n,220,.78),k.data[e+1]=tN(n,0,.78),k.data[e+2]=tN(n,0,.78),k.data[e+3]=255;continue}let n=tA(g,e);k.data[e]=n,k.data[e+1]=n,k.data[e+2]=n,k.data[e+3]=255}let A=M>0?(o=(c=function(e){let{diffMask:t,baseline:n,current:r}=e,{width:i,height:a}=n;return eW({mask:t,width:i,height:a,hooks:{create:e=>{var t,n;let r,a;return r=(t=e)%(n=i),{minX:r,minY:a=Math.floor(t/n),maxX:r,maxY:a,differentPixels:0,baselineRed:0,baselineGreen:0,baselineBlue:0,currentRed:0,currentGreen:0,currentBlue:0}},visit:(e,t)=>{var a,o,s,l,d;let c,u,h;return a=e,o=t,s=i,l=n,d=r,c=o%s,u=Math.floor(o/s),h=4*o,void(a.minX=Math.min(a.minX,c),a.minY=Math.min(a.minY,u),a.maxX=Math.max(a.maxX,c),a.maxY=Math.max(a.maxY,u),a.differentPixels+=1,a.baselineRed+=l.data[h],a.baselineGreen+=l.data[h+1],a.baselineBlue+=l.data[h+2],a.currentRed+=d.data[h],a.currentGreen+=d.data[h+1],a.currentBlue+=d.data[h+2])}}})}(a={diffMask:I,baseline:b,current:g,totalPixels:x,differentPixels:M,maxRegions:i.maxRegions})).length<=2e3?function(e){let t=[];for(let i of e.sort((e,t)=>{let n=e.minY-t.minY;return 0!==n?n:e.minX-t.minX})){var n,r;let e=t.find(e=>{var t,n,r;return t=e,n=i,r=12,t.minX-r<=n.maxX&&n.minX-r<=t.maxX&&t.minY-r<=n.maxY&&n.minY-r<=t.maxY});if(!e){t.push({...i});continue}n=e,r=i,n.minX=Math.min(n.minX,r.minX),n.minY=Math.min(n.minY,r.minY),n.maxX=Math.max(n.maxX,r.maxX),n.maxY=Math.max(n.maxY,r.maxY),n.differentPixels+=r.differentPixels,n.baselineRed+=r.baselineRed,n.baselineGreen+=r.baselineGreen,n.baselineBlue+=r.baselineBlue,n.currentRed+=r.currentRed,n.currentGreen+=r.currentGreen,n.currentBlue+=r.currentBlue}return t}(c):c,o.flatMap(e=>{var t,n,r;let i;return(t=e,n=a.baseline.width,r=a.baseline.height,i=t.maxX-t.minX+1,t.maxY-t.minY+1>=Math.max(48,Math.round(.07*r))&&i>=.35*n)?function(e,t,n){var r;let i=function(e,t){let n=[],r=null;for(let i=0;i<e.length;i+=1){if(e[i]<=t){r??=i;continue}null!==r&&(i-r>=6&&n.push([r,i-1]),r=null)}return null!==r&&e.length-r>=6&&n.push([r,e.length-1]),n}((r=function(e,t,n){let r=[];for(let i=e.minY;i<=e.maxY;i+=1){let a=0;for(let r=e.minX;r<=e.maxX;r+=1)1===t[i*n+r]&&(a+=1);r.push(a)}return r}(e,t.diffMask,t.baseline.width)).map((e,t)=>{let n=0,i=0,a=Math.max(0,t-3),o=Math.min(r.length-1,t+3);for(let e=a;e<=o;e+=1)n+=r[e],i+=1;return Math.round(n/i)}),Math.max(1,Math.round((e.maxX-e.minX+1)*.08))),a=function(e,t,n){let r=[],i=e.minY;for(let[a,o]of t){let t=e.minY+Math.round((a+o)/2);t-i+1<n||e.maxY-t<n||(r.push([i,t]),i=t+1)}return r.push([i,e.maxY]),r}(e,i,n);if(a.length<=1)return[e];let o=a.map(([n,r])=>(function(e,t,n,r){let i=null;for(let s=t;s<=n;s+=1)for(let t=e.minX;t<=e.maxX;t+=1){var a,o;let e=s*r.baseline.width+t;1===r.diffMask[e]&&function(e,t,n,r,i,a){let o=4*t;e.minX=Math.min(e.minX,n),e.minY=Math.min(e.minY,r),e.maxX=Math.max(e.maxX,n),e.maxY=Math.max(e.maxY,r),e.differentPixels+=1,e.baselineRed+=i.data[o],e.baselineGreen+=i.data[o+1],e.baselineBlue+=i.data[o+2],e.currentRed+=a.data[o],e.currentGreen+=a.data[o+1],e.currentBlue+=a.data[o+2]}(i??={minX:a=t,minY:o=s,maxX:a,maxY:o,differentPixels:0,baselineRed:0,baselineGreen:0,baselineBlue:0,currentRed:0,currentGreen:0,currentBlue:0},e,t,s,r.baseline,r.current)}return i})(e,n,r,t)).filter(e=>null!==e);return o.length>1?o:[e]}(e,a,Math.max(24,Math.round(.03*a.baseline.height))):[e]})).sort((e,t)=>{let n=t.differentPixels-e.differentPixels;if(0!==n)return n;let r=e.minY-t.minY;return 0!==r?r:e.minX-t.minX}).slice(0,Math.max(0,a.maxRegions??8)).map((e,t)=>{var n,r,i,o,s,l,d,c,u,h,p;let f,w,m,b,g,y,x,v,k,I,M,A,N,R,P,S,D;return n=e,r=t+1,i={width:a.baseline.width,height:a.baseline.height,totalPixels:a.totalPixels,differentPixels:a.differentPixels},y={x:n.minX,y:n.minY,width:n.maxX-n.minX+1,height:n.maxY-n.minY+1},x={x:Math.round(n.minX+y.width/2),y:Math.round(n.minY+y.height/2)},v=tw(n.baselineRed,n.baselineGreen,n.baselineBlue,n.differentPixels),k=tw(n.currentRed,n.currentGreen,n.currentBlue,n.differentPixels),I=y.width*y.height,M=ty(n.differentPixels/I),A=Math.round(tm(v)),N=Math.round(tm(k)),R=(o=y,s=i.width,l=i.height,o.width>=.55*s&&o.height>=.12*l?"large-area":o.width>=2.5*o.height?"horizontal-band":o.height>=2.5*o.width?"vertical-band":"compact"),P=(f=I/i.totalPixels)>=.04?"large":f>=.01?"medium":"small",S=(d=v,c=k,w=tm(d),Math.abs(m=tm(c)-w)>=12?m>0?"brighter":"darker":Math.max(Math.abs(c.r-d.r),Math.abs(c.g-d.g),Math.abs(c.b-d.b))>=12?"color-shift":"mixed"),D=(u=x,h=i.width,p=i.height,b=u.x<h/3?"left":u.x>2*h/3?"right":"center",g=u.y<p/3?"top":u.y>2*p/3?"bottom":"middle","center"===b&&"middle"===g?"center":`${g}-${b}`),{index:r,rect:y,normalizedRect:{x:ty(y.x/i.width),y:ty(y.y/i.height),width:ty(y.width/i.width),height:ty(y.height/i.height)},differentPixels:n.differentPixels,shareOfDiffPercentage:ty(n.differentPixels/i.differentPixels),densityPercentage:M,shape:R,size:P,location:D,averageBaselineColorHex:tb(v),averageCurrentColorHex:tb(k),baselineLuminance:A,currentLuminance:N,dominantChange:S}}):[];if(M>0&&f){for(let e of A)e.rect.width<4||e.rect.height<4||function(e,t){let n=eK(t.x,0,e.width-1),r=eK(t.y,0,e.height-1),i=eK(t.x+t.width-1,0,e.width-1),a=eK(t.y+t.height-1,0,e.height-1);for(let t=0;t<2;t+=1){for(let o=n;o<=i;o+=1)ez(e,o,r+t,eH),ez(e,o,a-t,eH);for(let o=r;o<=a;o+=1)ez(e,n+t,o,eH),ez(e,i-t,o,eH)}}(k,e.rect);await e.mkdir(r.dirname(f),{recursive:!0}),await e.writeFile(f,eP.sync.write(k))}else await tM(i.outputPath);let N=M>0?await tr({baselinePath:t,currentPath:n,width:b.width,height:b.height}):void 0,R=N&&(N.matches.length>0||(N.movementClusters?.length??0)>0)?{provider:N.provider,baselineBlocks:N.baselineBlocks,currentBlocks:N.currentBlocks,matches:N.matches,...N.movementClusters?{movementClusters:N.movementClusters}:{}}:void 0,P=M>0&&N?(u=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,r,i;return t=e,r=n,i=10,t.minX-i<=r.maxX&&r.minX-i<=t.maxX&&t.minY-i<=r.maxY&&r.minY-i<=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,r){let i=new Uint8Array(e);if(!r)return i;for(let e of[...r.baselineBlocksRaw,...r.currentBlocksRaw]){var a;!function(e,t,n,r){let i=e2(Math.floor(r.x),0,t-1),a=e2(Math.floor(r.y),0,n-1),o=e2(Math.ceil(r.x+r.width),0,t),s=e2(Math.ceil(r.y+r.height),0,n);for(let n=a;n<s;n+=1)for(let r=i;r<o;r+=1)e[n*t+r]=0}(i,t,n,{x:(a=e.rect).x-8,y:a.y-8,width:a.width+16,height:a.height+16})}return i}((s={diffMask:I,width:b.width,height:b.height,regions:A,ocr:N}).diffMask,s.width,s.height,s.ocr),d=s.width,eW({mask:l,width:d,height:s.height,hooks:{create:e=>{var t,n;let r,i;return r=(t=e)%(n=d),{minX:r,minY:i=Math.floor(t/n),maxX:r,maxY:i,differentPixels:0}},visit:(e,t)=>{var n,r,i;let a,o;return n=e,a=(r=t)%(i=d),o=Math.floor(r/i),void(n.minX=Math.min(n.minX,a),n.minY=Math.min(n.minY,o),n.maxX=Math.max(n.maxX,a),n.maxY=Math.max(n.maxY,o),n.differentPixels+=1)}}}))),h=e9(s.ocr?.currentBlocksRaw??[]),p=e9(s.ocr?.baselineBlocksRaw??[]),u.filter(te).map(e=>{var t,n,r,i,a,o,l,d,c,u,f;let w,m,b,g,y,x,v,k,I,M;return t=e,n=s,r=h,i=p,g=function(e,t){let n,r=0;for(let i of t){let t=eQ(e,i.rect);t<=r||(r=t,n=i)}return n?.index}(b=tt(t),n.regions),y=function(e,t,n){let r=e6(e,t);if(r)return e7(e,r.blocks);let i=e6(e,n);return i?e7(e,i.blocks):void 0}(b,r,i),x=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 r=e.x+e.width/2,i=t.x+t.width/2;return r<i-t.width/2?"leading":r>i+t.width/2?"trailing":e.width>=.35*n?"background":"unknown"}(b,y?.block.rect,n.width),v=(a=b,o=x,l=t.differentPixels,d=n,w=a.width/a.height,m=l/(a.width*a.height),"separator"===o?"separator":"background"===o?"background":"trailing"===o&&w>=1.5&&w<=3.8&&m>=.35?"toggle":"trailing"===o&&a.width<=.06*d.width&&a.height<=.04*d.height?"chevron":"leading"===o&&w>=.55&&w<=1.8?"icon":e3(a,d)?"background":"visual"),k={...g?{regionIndex:g}:{},slot:x,likelyKind:v,rect:b},{...g?{regionIndex:g}:{},slot:x,likelyKind:v,rect:b,...y?{nearestText:y.block.text.trim().replace(/^[^\p{L}\p{N}]+/u,"").replace(/^\p{L}\s+/u,"")}:{},score:(c=k,u=t.differentPixels,f=n,I=e3(c.rect,f)?-35:0,M=20*!!c.regionIndex,e5[c.likelyKind]+e4[c.slot]+M+I+Math.min(20,u/200))}}).filter(e=>e.rect.y>=.08*s.height).filter(e8).sort((e,t)=>t.score-e.score).slice(0,Math.max(0,s.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}:{}}})):[],S=x>0?Math.round(M/x*1e4)/100:0;return{...M>0&&f?{diffPath:f}:{},...A.length>0?{regions:A}:{},...R?{ocr:R}:{},...P.length>0?{nonTextDeltas:P}:{},totalPixels:x,differentPixels:M,mismatchPercentage:S,match:0===M}}async function tk(t,n){try{await e.access(t)}catch{throw new a("INVALID_ARGS",`${n}: ${t}`)}}function tI(e,t,n,r){if(null==r||r<=0)return;let i=e*t;if(!(i<=r))throw new a("INVALID_ARGS",`${n} is ${i} pixels, which exceeds the configured maxImagePixels limit of ${r}`)}async function tM(t){if(t)try{await e.unlink(t)}catch(e){var n;if(!("object"==typeof(n=e)&&null!==n&&"code"in n&&"ENOENT"===n.code))throw e}}function tA(e,t){return tN(Math.round(.299*e.data[t]+.587*e.data[t+1]+.114*e.data[t+2]),255,.72)}function tN(e,t,n){return Math.round(e*(1-n)+t*n)}function tR(e){return e.width*e.height}function tP(e){return Math.round(100*e*100)/100}async function tS(e,t){let n=await eY(e,{prefix:"agent-device-diff-current",ext:".png"});try{await tE(e,t,n.path,tO(t))}catch(e){throw await n.cleanup(),e}return n}async function tD(e,t,n,r,i){var a,o,s,l;if(!t.overlayRefs)return r;if(r.match||r.dimensionMismatch)return n&&await tT(n),r;let d=(a=t,o=n,a.currentOverlayOut?a.currentOverlayOut:a.out?.kind==="path"?{kind:"path",path:t_(o??a.out.path)}:a.out?.kind==="downloadableArtifact"?{kind:"downloadableArtifact",...a.out.clientPath?{clientPath:t_(a.out.clientPath)}:{},...a.out.fileName?{fileName:t_(a.out.fileName)}:{}}:void 0),c=await eX(e,d,{field:"currentOverlayPath",ext:".png"});try{let n=await tE(e,t,c.path,{overlayRefs:!0,...tO(t)}),a=await c.publish();return a&&i.push(a),{...r,currentOverlayPath:n.path??c.path,...n.overlayRefs?{currentOverlayRefCount:n.overlayRefs.length}:{},...r.regions&&n.overlayRefs?{regions:(s=r.regions,l=n.overlayRefs,s.map(e=>{var t,n;let r,i=(t=e,n=l,r=tR(t.rect),n.map(e=>{let n=e.overlayRect,i=eQ(t.rect,n);return i<=0?null:{ref:e.ref,...e.label?{label:e.label}:{},rect:n,overlayCoveragePercentage:tP(i/tR(n)),regionCoveragePercentage:tP(i/r)}}).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 i.length>0?{...e,currentOverlayMatches:i}:e}))}:{}}}catch(e){throw await c.cleanup?.(),e}}async function tE(e,t,n,r={}){if(!e.backend.captureScreenshot)throw new a("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,r)??{}}function tO(e){return e.surface?{surface:e.surface}:{}}function t_(e){let t=r.extname(e),n=t?e.slice(0,-t.length):e;return`${n}.current-overlay${t||".png"}`}async function tT(t){try{await e.unlink(t_(t))}catch(e){var n;if(!("object"==typeof(n=e)&&null!==n&&"code"in n&&"ENOENT"===n.code))throw e}}function t$(e){return"live"===e.kind}let tC={application:"application",navigationbar:"navigation-bar",tabbar:"tab-bar",button:"button",imagebutton:"button",link:"link",cell:"cell",statictext:"text",checkedtextview:"text",textfield:"text-field",edittext:"text-field",textarea:"text-view",switch:"switch",slider:"slider",image:"image",imageview:"image",webview:"webview",framelayout:"group",linearlayout:"group",relativelayout:"group",constraintlayout:"group",viewgroup:"group",view:"group",listview:"list",recyclerview:"list",collectionview:"collection",searchfield:"search",segmentedcontrol:"segmented-control",group:"group",window:"window",checkbox:"checkbox",radio:"radio",menuitem:"menu-item",toolbar:"toolbar",scrollarea:"scroll-area",scrollview:"scroll-area",nestedscrollview:"scroll-area",table:"table"};function tL(e,t={}){let n=[],r=[];for(let i of e){let e=i.depth??0,a=i.label?.trim()||i.value?.trim()||i.identifier?.trim()||"",o=tG(i.type??"Element");if("group"===o&&!a)continue;for(;n.length>0&&e<=n[n.length-1];)n.pop();let s=n.length;n.push(e),r.push({node:i,depth:s,type:o,text:tU(i,s,!1,o,t)})}return r}function tU(e,t,n,r,i={}){var a,o,s,l,d,c,u,h;let p,w=r??tG(e.type??"Element"),m=P(e,w),b=(a=e,o=w,s=i,l=m,s.summarizeTextSurfaces&&l.shouldSummarize&&function(e,t,n){let r=f(e.label);if(r&&r!==n)return r;let i=f(e.identifier);if(i&&!tq(i)&&i!==n)return i;switch(t){case"text":case"text-view":return"Text view";case"text-field":return"Text field";case"search":return"Search field";default:return""}}(a,o,l.text)||tB(a,o)),g=" ".repeat(t),y=e.ref?`@${e.ref}`:"",x=(d=e,c=w,u=i,h=m,p=[],(!1===d.enabled&&p.push("disabled"),u.summarizeTextSurfaces)?(!0===d.selected&&p.push("selected"),!0===d.focused&&p.push("focused"),tF(c)&&p.push("editable"),function(e,t){if("scroll-area"===t)return!0;let n=(e.type??"").toLowerCase(),r=`${e.role??""} ${e.subrole??""}`.toLowerCase();return n.includes("scroll")||r.includes("scroll")}(d,c)&&p.push("scrollable"),p.push(...d.presentationHints??[]),h.shouldSummarize&&(p.push(`preview:"${v(h.text).replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`),p.push("truncated")),tX(p)):p).map(e=>` [${e}]`).join(""),k=b?` "${b}"`:"";return n?`${g}${y} [${w}]${x}`.trimEnd():`${g}${y} [${w}]${k}${x}`.trimEnd()}function tB(e,t){var n,r;let i=e.label?.trim();if(i&&(n=t,r=i,("scroll-area"===n||"list"===n||"collection"===n||"table"===n)&&Q(r)))return"";let a=e.value?.trim();if(tF(t)){if(a)return a;if(i)return i}else if(i)return i;if(a)return a;let o=e.identifier?.trim();return!o||tq(o)&&("group"===t||"image"===t||"list"===t||"collection"===t)?"":o}function tG(e){var t;let n=e.replace(/XCUIElementType/gi,"").toLowerCase(),r=e.includes(".")&&(e.startsWith("android.")||e.startsWith("androidx.")||e.startsWith("com."));return(n.includes(".")&&(n=n.replace(/^android\.widget\./,"").replace(/^android\.view\./,"").replace(/^android\.webkit\./,"").replace(/^androidx\./,"").replace(/^com\.google\.android\./,"").replace(/^com\.android\./,""),r&&n.includes(".")&&(n=n.slice(n.lastIndexOf(".")+1))),"textview"===n)?r?"text":"text-view":(t=n,(Object.prototype.hasOwnProperty.call(tC,t)?tC[t]:void 0)||n||"element")}function tF(e){return"text-field"===e||"text-view"===e||"search"===e}function tq(e){return/^[\w.]+:id\/[\w.-]+$/i.test(e)}function tX(e){return[...new Set(e)]}function tY(e,t){let n=tG(e.type??"Element"),r=tB(e,n),i=!1===e.enabled?"disabled":"enabled",a=!0===e.selected?"selected":"unselected",o=!0===e.hittable?"hittable":"not-hittable";return[String(t??e.depth??0),n,r,i,a,o].join("|")}function tV(e,t){return t.flatten?e.map(e=>({text:tU(e,0,!1),comparable:tY(e,0)})):tL(e).map(e=>({text:e.text,comparable:tY(e.node,e.depth)}))}function tH(e,t){return e.get(t)??0}function tz(e){let t=e.map(e=>[e.label,e.value,e.identifier,e.type,e.role].filter(Boolean).join(" ")).join("\n").toLowerCase(),n=tZ(e,tj),r=tZ(e,tW),i=tZ(e,ek,tJ),a=tZ(e,eI),o=tQ(n),s=tQ(r),l=tQ(i),d=/\b[\w.$<>/-]+\.(?:tsx?|jsx?):\d+(?::\d+)?\b/.test(t)||/\b[\w.$<>/-]+\.(?:tsx?|jsx?)\s+\(\d+:\d+\)/.test(t),c=o.length>0||s.length>0||/\b(reload js|copy stack)\b/.test(t),u=/\b(redbox|runtime error|reload js|copy stack|component stack|call stack)\b/.test(t)||d&&c;return{detected:l.length>0||a.length>0||c&&(/\b(logbox|redbox|reload js|copy stack|component stack|call stack|runtime error|open debugger to view warnings)\b/.test(t)||d),redBox:u,dismissRefs:o,minimizeRefs:s,collapsedRefs:l,dismissNodes:n,minimizeNodes:r,collapsedNodes:i}}function tK(e){let t,n=tz(e);if(!n.detected)return null;if(n.redBox){let e=t0(n.minimizeNodes);if(e)return t1(e,"minimize");let t=t0(n.dismissNodes);return t?{...t1(t,t2(t)),warning:"RedBox Minimize control was not exposed; used Dismiss fallback"}:null}let r=t0(n.dismissNodes);if(r)return t1(r,t2(r));let i=0===(t=n.collapsedNodes.filter(e=>e.rect)).length?null:t.sort((e,t)=>{let n=+(!0===e.hittable),r=+(!0===t.hittable);if(n!==r)return r-n;let i=e.rect?.width??0,a=t.rect?.width??0;return i!==a?a-i:(t.rect?.y??0)-(e.rect?.y??0)})[0]??null;return i?.rect?{action:"close-collapsed-banner",point:function(e){var t,n;if(!e.rect)throw Error("Collapsed React Native warning node must have rect");let r=Math.min(e.rect.height,52),i=Math.min(36,Math.max(18,.45*r));return{x:Math.round((t=e.rect.x+e.rect.width-i,n=e.rect.x+1,Math.min(e.rect.x+e.rect.width-1,Math.max(n,t)))),y:Math.round(e.rect.y+r/2)}}(i),ref:i.ref,label:t5(i)}:null}function tj(e){return"dismiss"===e||"close"===e||["x","\xd7","✕","✖","⨯"].includes(e)}function tW(e){return/^minimi[sz]e$/.test(e)}function tJ(e){return!e.rect||e.rect.height<=180}function tZ(e,t,n=()=>!0){let r=[];for(let i of e)i.ref&&n(i)&&[i.label,i.value,i.identifier].map(e=>e?.trim().toLowerCase()).filter(e=>!!e).some(e=>t(e))&&r.push(i);return r}function tQ(e){return e.map(e=>e.ref)}function t0(e){return e.find(e=>e.rect)??null}function t1(e,t){if(!e.rect)throw Error("React Native overlay target node must have rect");return{action:t,point:s(e.rect),ref:e.ref,label:t5(e)}}function t2(e){return"dismiss"===t5(e)?.trim().toLowerCase()?"dismiss":"close"}function t5(e){return e.label??e.value??e.identifier}function t4(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}))}function t8(e,t){return{session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata}}function t3(e){return e.clock?.now()??Date.now()}async function t6(e,t){e.clock?await e.clock.sleep(t):await new Promise(e=>setTimeout(e,t))}async function t9(e,t){var n,r,i,o,s,d;let c,u,h,p;if(!e.backend.captureSnapshot)throw new a("UNSUPPORTED_OPERATION","snapshot is not supported by this backend");let f=t.session??"default",w=await e.sessions.get(f),m=await e.backend.captureSnapshot({session:f,requestId:t.requestId,appId:w?.appId,appBundleId:w?.appBundleId,signal:t.signal??e.signal,metadata:t.metadata},{interactiveOnly:t.interactiveOnly,compact:t.compact,depth:t.depth,scope:t.scope,raw:t.raw}),b=(r=m,i=e,n=r.snapshot?r.snapshot:{nodes:r.nodes??[],truncated:r.truncated,backend:r.backend,createdAt:t3(i)},n.presentationKey?n:{...n,presentationKey:l(t)}),g=t3(e);return{snapshot:b,result:m,session:w,warnings:((c=[...(o={result:m,snapshot:b,options:t,session:w,capturedAt:b.createdAt??g,runtimeNow:g}).result.warnings??[]]).push(...function(e){let t=e.result.analysis;if("android"!==e.snapshot.backend||!0!==e.options.interactiveOnly||e.snapshot.nodes.length>0||!t||(t.rawNodeCount??0)<12)return[];let n=[`Interactive snapshot is empty after filtering ${t.rawNodeCount} raw Android nodes. Likely causes: the app content is not accessibility-visible yet, a transient route change, or depth/filter options hid the target.`];return"number"==typeof e.options.depth&&"number"==typeof t.maxDepth&&t.maxDepth>=e.options.depth+2&&n.push(`Interactive output is empty at depth ${e.options.depth}; retry without -d.`),n}(o)),(u=function(e){if(e?.backend!=="uiautomator-dump")return;let t=e.fallbackReason?` Reason: ${e.fallbackReason}`:"";return`Android snapshot helper unavailable; using stock UIAutomator dump, which can time out on busy React Native UIs.${t}`}(o.result.androidSnapshot))&&c.push(u),(h=function(e){if(tz(e).detected)return"Hint: React Native warning/error overlay detected. It overlays part of the app and should be handled before interacting.\nRun: agent-device react-native dismiss-overlay\nThen run: agent-device snapshot -i -c\nUse refs from the new snapshot."}(o.snapshot.nodes))&&c.push(h),(p=function(e){var t,n;let r=e.session?.snapshot,i=!!r&&[e.capturedAt,e.runtimeNow].some(e=>{let t=e-r.createdAt;return t>=0&&t<=2e3});if(!e.result.freshness&&r&&i&&(t=r.nodes.length,n=e.snapshot.nodes.length,!(t<12)&&n<=Math.floor(.2*t)))return ne}(o))&&c.push(p),c.push(...(s=o.result.freshness,d=o.snapshot.backend,s?.staleAfterRetries&&"android"===d?"stuck-route"===s.reason?[`Recent ${s.action} was followed by a nearly identical snapshot after ${s.retryCount} automatic retr${1===s.retryCount?"y":"ies"}. If you expected navigation or submit, the tree may still be stale. Use screenshot as visual truth, wait briefly, then re-snapshot once.`]:"sharp-drop"===s.reason?[ne]:[]:[])),Array.from(new Set(c)))}}function t7(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 ne="Recent snapshots dropped sharply in node count, which suggests stale or mid-transition UI. Use screenshot as visual truth, wait briefly, then re-snapshot once.";function nt(e){return["visible","hidden","exists","editable","selected","text"].includes(e)}function nn(e){let{predicate:t,node:n,nodes:r,expectedText:i,platform:a}=e,o=w(n),s=x(n,a),l=!0===n.selected,d="text"===t?g(n):function(e,t,n){var r,i,a;let o;if("android"===n&&!1===e.visibleToUser)return!1;if(nr(e.rect))return function(e,t){return es(e,t)}(e,t);if(e.rect)return!1;if("android"!==n&&!0===e.hittable)return!0;let s=(r=e,i=t,a=n,o=y(i),m(i,r,o,e=>!function(e,t){if("android"===t&&!1===e.visibleToUser)return!1;let n=E(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&&nr(e.rect):!0===e.hittable||nr(e.rect))}(e,a)?null:e));return!!s&&(nr(s.rect)?function(e,t){return es(e,t)}(s,t):"android"!==n&&!0===s.hittable)}(n,r,a),c=!1;switch(t){case"visible":c=d;break;case"hidden":c=!d;break;case"editable":c=s;break;case"selected":c=l;break;case"text":c=o===(i??"")}let u="text"===t?`expected="${i??""}" actual="${o}"`:`actual=${JSON.stringify({visible:d,editable:s,selected:l})}`;return{pass:c,actualText:o,details:u}}function nr(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 ni(e,t){let n=t??"default",r=await e.sessions.get(n);if(!r)throw new a("SESSION_NOT_FOUND","No active session. Run open first.");if(!r.snapshot)throw new a("INVALID_ARGS","No snapshot in session. Run snapshot first.");return{sessionName:n,session:r,snapshot:r.snapshot}}async function na(e,t,n={updateSession:!0}){let r=e.backend.captureSnapshot;if(!r)throw new a("UNSUPPORTED_OPERATION","snapshot is not supported by this backend");let i=t.session??"default",o=await e.sessions.get(i),s=await r(t8(e,t),{interactiveOnly:!1,compact:!1,depth:t.depth,scope:n.scope??t.scope,raw:t.raw}),l=s.snapshot??{nodes:s.nodes??[],truncated:s.truncated,backend:s.backend,createdAt:t3(e)};return n.updateSession&&o&&await e.sessions.set({...o,snapshot:l}),{sessionName:i,session:o,snapshot:l}}async function no(e,t,n){if(e.backend.readText){let r=await e.backend.readText(t8(e,{session:t.sessionName}),n);if(r.text.trim())return r.text}return S(n)}let ns=async(e,t)=>{if("ref"===t.target.kind){let n=await ni(e,t.session),r=function(e,t,n){let r=o(t);if(!r)throw new a("INVALID_ARGS",n.invalidRefMessage);let i=d(e,r)??(n.fallbackLabel.length>0?N(e,n.fallbackLabel):null);if(!i)throw new a("COMMAND_FAILED",n.notFoundMessage);return{ref:r,node:i}}(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`}),i=I(r.node,e.backend.platform,{action:"get"}),s={kind:"ref",ref:`@${r.ref}`};return"attrs"===t.property?{kind:"attrs",target:s,node:r.node,selectorChain:i}:{kind:"text",target:s,text:await no(e,n,r.node),node:r.node,selectorChain:i}}let n=await nx(e,t,t.session??"default",{selector:t.target.selector,disambiguateAmbiguous:"text"===t.property}),r=I(n.node,e.backend.platform,{action:"get"});if("attrs"===t.property)return{kind:"attrs",target:{kind:"selector",selector:n.selector},node:n.node,selectorChain:r};let i=await no(e,n.capture,n.node);return{kind:"text",target:{kind:"selector",selector:n.selector},text:i,node:n.node,selectorChain:r}},nl=async(e,t)=>{let n=await ns(e,{...t,property:"text",target:t.target});if("text"!==n.kind)throw new a("COMMAND_FAILED","getText returned non-text result");return n},nd=async(e,t)=>{let n=await ns(e,{...t,property:"attrs",target:t.target});if("attrs"!==n.kind)throw new a("COMMAND_FAILED","getAttrs returned non-attrs result");return n},nc=async(e,t)=>{if(!nt(t.predicate))throw new a("INVALID_ARGS","is requires predicate: visible|hidden|exists|editable|selected|text");if("text"===t.predicate&&!t.expectedText)throw new a("INVALID_ARGS","is text requires expected text value");let n=await na(e,t,{updateSession:!0}),r=b(t.selector);if("exists"===t.predicate){let i=M(n.snapshot.nodes,r,{platform:e.backend.platform});if(!i)throw new a("COMMAND_FAILED",D(r,[],{unique:!1}));return{predicate:t.predicate,pass:!0,selector:i.selector.raw,matches:i.matches,selectorChain:r.selectors.map(e=>e.raw)}}let i=A(n.snapshot.nodes,r,{platform:e.backend.platform,requireRect:!1,requireUnique:!0,disambiguateAmbiguous:!1});if(!i)throw new a("COMMAND_FAILED",D(r,[],{unique:!0}),{command:"is",reason:"selector_not_found",predicate:t.predicate,selector:r.raw});let o=nn({predicate:t.predicate,node:i.node,nodes:n.snapshot.nodes,expectedText:t.expectedText,platform:e.backend.platform});if(!o.pass)throw new a("COMMAND_FAILED",`is ${t.predicate} failed for selector ${i.selector.raw}: ${o.details}`,{command:"is",reason:"predicate_failed",predicate:t.predicate,selector:i.selector.raw,predicateDetails:o.details});return{predicate:t.predicate,pass:!0,selector:i.selector.raw,..."text"===t.predicate?{text:o.actualText}:{},selectorChain:r.selectors.map(e=>e.raw)}},nu=async(e,t)=>await nc(e,{...t,predicate:"visible",selector:t.target.selector}),nh=async(e,t)=>await nc(e,{...t,predicate:"hidden",selector:t.target.selector}),np=async(e,t)=>{if("sleep"===t.target.kind)return await t6(e,t.target.durationMs),{kind:"sleep",waitedMs:t.target.durationMs};if("ref"===t.target.kind){let n=await ni(e,t.session),r=o(t.target.ref);if(!r)throw new a("INVALID_ARGS",`Invalid ref: ${t.target.ref}`);let i=d(n.snapshot.nodes,r),s=i?R(i,n.snapshot.nodes):void 0;if(!s)throw new a("COMMAND_FAILED",`Ref ${t.target.ref} not found or has no label`);return await ng(e,t,s,t.target.timeoutMs)}if("selector"===t.target.kind)return await nb(e,t,t.target.selector,t.target.timeoutMs);if(!t.target.text)throw new a("INVALID_ARGS","wait requires text");return await ng(e,t,t.target.text,t.target.timeoutMs)},nf=async(e,t)=>{let n=await np(e,{...t,target:{kind:"text",text:t.text,timeoutMs:t.timeoutMs}});if("text"!==n.kind)throw new a("COMMAND_FAILED","waitForText returned non-text result");return n};async function nw(e,t,n){let r=t.timeoutMs??1e4,i=t3(e);for(;t3(e)-i<r;){let{match:r}=await nm(e,t,n);if(r)return{kind:"found",found:!0,waitedMs:t3(e)-i};await t6(e,300)}throw new a("COMMAND_FAILED","find wait timed out")}async function nm(e,t,n){let r=await na(e,t,{updateSession:!0,scope:"text"===n||"label"===n||"any"===n?t.query:void 0}),i=_(r.snapshot.nodes,n,t.query,{requireRect:!1}).matches[0];return{capture:r,match:i}}async function nb(e,t,n,r){let i=r??1e4,o=t3(e),s=b(n);for(;t3(e)-o<i;){let n=M((await na(e,t,{updateSession:!0})).snapshot.nodes,s,{platform:e.backend.platform});if(n)return{kind:"selector",selector:n.selector.raw,waitedMs:t3(e)-o};await t6(e,300)}throw new a("COMMAND_FAILED",`wait timed out for selector: ${n}`)}async function ng(e,t,n,r){let i=r??1e4,o=t3(e);for(;t3(e)-o<i;){if(e.backend.findText?(await e.backend.findText(t8(e,t),n)).found:await ny(e,t,n))return{kind:"text",text:n,waitedMs:t3(e)-o};await t6(e,300)}throw new a("COMMAND_FAILED",`wait timed out for text: ${n}`)}async function ny(e,t,n){return!!N((await na(e,t,{updateSession:!0})).snapshot.nodes,n)}async function nx(e,t,n,r){let i=await na(e,{...t,session:n},{updateSession:!0}),o=b(r.selector),s=A(i.snapshot.nodes,o,{platform:e.backend.platform,requireRect:!1,requireUnique:!0,disambiguateAmbiguous:r.disambiguateAmbiguous});if(!s)throw new a("COMMAND_FAILED",D(o,[],{unique:!0}));return{capture:i,node:s.node,selector:s.selector.raw,ref:`@${s.node.ref}`}}function nv(e){let t=nk(e);if(!t)return null;let n=s(t);return Number.isFinite(n.x)&&Number.isFinite(n.y)?n:null}function nk(e){if(!e)return null;let t=Number(e.x),n=Number(e.y),r=Number(e.width),i=Number(e.height);return Number.isFinite(t)&&Number.isFinite(n)&&Number.isFinite(r)&&Number.isFinite(i)&&!(r<0)&&!(i<0)?{x:t,y:n,width:r,height:i}:null}function nI(e){return{x:nM(e.x,e.width),y:nM(e.y,e.height)}}function nM(e,t){if(t<=1)return Math.floor(e);let n=Math.ceil(e);return Math.round(Math.min(Math.floor(e+t-1),Math.max(n,e+t/2)))}let nA=["button","link","menuitem","tabitem","textfield","searchfield","securetextfield","checkbox","radio","switch","cell"];function nN(e,t){return nR(e,t).node}function nR(e,t){var n;let r=function(e,t){let n=nk(t.rect);if(!n)return null;let r=t,i=new Set;for(;!i.has(r.ref);){i.add(r.ref);let t=e.filter(e=>{if(e.parentIndex!==r.index||!e.hittable)return!1;let t=nk(e.rect);return!!t&&nS(t,n)});if(1!==t.length)break;let a=t[0];if(void 0===a)break;r=a}return r===t?null:r}(e,t);if(r?.rect&&nv(r.rect))return{node:r,reason:"same-rect-descendant"};if([(n=t).type,n.role,n.subrole].map(e=>E(e??"")).some(nP)&&t.rect&&nv(t.rect))return{node:t,reason:"semantic-target"};let i=k(e,t);return i?.rect&&nv(i.rect)?!function(e,t,n){var r,i,a,o;let l,d,c,u=nk(e.rect),h=nk(t.rect);if(!u||!h)return!1;let p=function(e,t){let n=s(t),r=e.filter(e=>{let t=(e.type??"").toLowerCase();return t.includes("application")||t.includes("window")}).map(e=>nk(e.rect)).filter(e=>null!==e);if(0===r.length)return null;let i=r.filter(e=>W(e,n.x,n.y));return J(i.length>0?i:r)}(n,u);return!!p&&(r=h,i=p,l=(a=r,o=i,Math.max(0,Math.min(a.x+a.width,o.x+o.width)-Math.max(a.x,o.x))*Math.max(0,Math.min(a.y+a.height,o.y+o.height)-Math.max(a.y,o.y))),d=r.width*r.height,c=i.width*i.height,!(l<=0)&&!(d<=0)&&!(c<=0)&&!!(l/c>=.9)&&!!(l/d>=.8))&&!nS(u,h)}(t,i,e)?{node:i,reason:"hittable-ancestor"}:{node:t,reason:"overly-broad-ancestor"}:{node:t,reason:"original"}}function nP(e){return"tab"===e||nA.some(t=>e.includes(t))}function nS(e,t){return .5>=Math.abs(e.x-t.x)&&.5>=Math.abs(e.y-t.y)&&.5>=Math.abs(e.width-t.width)&&.5>=Math.abs(e.height-t.height)}async function nD(e,t,n){if(await nO(e,t,n.action),"point"===t.target.kind)return{kind:"point",point:{x:t.target.x,y:t.target.y}};if("ref"===t.target.kind){let r=await nT(e,t,t.target),i=r.resolved,s=n.promoteToHittableAncestor?nN(r.snapshot.nodes,i.node):i.node;return function(e,t,n,r){let i=e.rect?el(e,t):null;if(!(!e.rect||!i||es(e,t)))throw new a("COMMAND_FAILED",`Ref ${n} is off-screen and not safe to ${r}`,{reason:"offscreen_ref",ref:o(n),rect:e.rect,viewport:i,hint:`Use scroll with the direction from the off-screen summary, take a fresh snapshot, then retry ${r} with the new ref or a selector.`})}(s,r.snapshot.nodes,t.target.ref,n.action),{kind:"ref",point:nC(s,`Ref ${t.target.ref} not found or has invalid bounds`),target:{kind:"ref",ref:`@${i.ref}`},node:s,selectorChain:I(s,e.backend.platform,{action:"fill"===n.action?"fill":"click"}),refLabel:R(s,r.snapshot.nodes)}}let r=await nE(e,t,n.requireInteractive),i=b(t.target.selector),s=A(r.snapshot.nodes,i,{platform:e.backend.platform,requireRect:!0,requireUnique:!0,disambiguateAmbiguous:!0});if(!s||!s.node.rect)throw new a("COMMAND_FAILED",D(i,s?.diagnostics??[],{unique:!0}));let l=n.promoteToHittableAncestor?nN(r.snapshot.nodes,s.node):s.node;return{kind:"selector",point:nC(l,`Selector ${s.selector.raw} resolved to invalid bounds`),target:{kind:"selector",selector:s.selector.raw},node:l,selectorChain:I(l,e.backend.platform,{action:"fill"===n.action?"fill":"click"}),refLabel:R(l,r.snapshot.nodes)}}async function nE(e,t,n){if(!e.backend.captureSnapshot)throw new a("UNSUPPORTED_OPERATION","snapshot is not supported by this backend");let r=t.session??"default",i=await e.sessions.get(r);if(!i)throw new a("SESSION_NOT_FOUND","No active session. Run open first.");let o=await e.backend.captureSnapshot(t8(e,t),{interactiveOnly:n,compact:n}),s=o.snapshot??{nodes:o.nodes??[],truncated:o.truncated,backend:o.backend,createdAt:t3(e)};return await e.sessions.set({...i,snapshot:s}),{snapshot:s}}async function nO(e,t,n){if("macos"!==e.backend.platform)return;let r=await n_(e,t);if(("desktop"===r||"menubar"===r)&&("menubar"!==r||"click"!==n&&"press"!==n))throw new a("UNSUPPORTED_OPERATION",`${n} is not supported on macOS ${r} sessions yet. Open an app session to act, or use the ${r} surface to inspect.`)}async function n_(e,t){let n=await e.sessions.get(t.session??"default");return n?.metadata?.surface}async function nT(e,t,n){let r=t.session??"default",i=await e.sessions.get(r);if(!i)throw new a("SESSION_NOT_FOUND","No active session. Run open first.");if(!i.snapshot)throw new a("INVALID_ARGS","No snapshot in session. Run snapshot first.");let o=n.fallbackLabel??"",s=n$(i.snapshot.nodes,n.ref,{fallbackLabel:o,requireRect:!0});if(s)return{snapshot:i.snapshot,resolved:s};let l=await nE(e,t,!0),d=n$(l.snapshot.nodes,n.ref,{fallbackLabel:o,requireRect:!0});if(!d)throw new a("COMMAND_FAILED",`Ref ${n.ref} not found or has no bounds`);return{...l,resolved:d}}function n$(e,t,n){let r=o(t);if(!r)throw new a("INVALID_ARGS",`Invalid ref: ${t}`);let i=d(e,r);if(nL(i,n.requireRect))return{ref:r,node:i};let s=n.fallbackLabel.length>0?N(e,n.fallbackLabel):null;return nL(s,n.requireRect)?{ref:r,node:s}:null}function nC(e,t){if(!e.rect)throw new a("COMMAND_FAILED",t);let n=s(e.rect);if(!Number.isFinite(n.x)||!Number.isFinite(n.y))throw new a("COMMAND_FAILED",t);return n}function nL(e,t){if(!e)return!1;if(!t)return!0;if(!e.rect)return!1;let{x:n,y:r,width:i,height:a}=e.rect;if(!Number.isFinite(Number(n))||!Number.isFinite(Number(r))||!Number.isFinite(Number(i))||!Number.isFinite(Number(a))||0>Number(i)||0>Number(a))return!1;let o=s(e.rect);return Number.isFinite(o.x)&&Number.isFinite(o.y)}async function nU(e,t,n){let r;if(t.from||t.to||t.direction||void 0!==t.distance)throw new a("INVALID_ARGS","gesture swipe preset cannot be combined with from, to, direction, or distance");let i=q(t.preset);await nO(e,t,"swipe");let o=F(i,{referenceWidth:(r=nV((await nE(e,t,!1)).snapshot.nodes)).width,referenceHeight:r.height},{platform:e.backend.platform}),s=void 0===t.durationMs?void 0:ev(t.durationMs,"durationMs",16,1e4),l={x:o.x1,y:o.y1},d={x:o.x2,y:o.y2},c=nz(await n(t8(e,t),l,d,{durationMs:s}));return{kind:"swipe",from:l,to:d,preset:i,...void 0!==s?{durationMs:s}:{},fromTarget:{kind:"viewport"},...c?{backendResult:c}:{},...u(`Swiped ${i}`)}}async function nB(e,t){let n=t.target??{kind:"viewport"};return"viewport"===n.kind?(await nO(e,t,"scroll"),{kind:"viewport"}):await nD(e,{...t,target:n},{action:"scroll",requireInteractive:!1,promoteToHittableAncestor:!1})}async function nG(e,t){if(t.from){var n;if("x"in(n=t.from)&&"y"in n)return await nO(e,t,"swipe"),{point:nX(t.from,"from")};let r=await nD(e,{...t,target:t.from},{action:"swipe",requireInteractive:!1,promoteToHittableAncestor:!1});return{point:r.point,target:r}}if(!t.direction)throw new a("INVALID_ARGS","swipe requires from+to or a direction");return await nO(e,t,"swipe"),{point:s(nV((await nE(e,t,!1)).snapshot.nodes)),target:{kind:"viewport"}}}async function nF(e,t,n,r,i){if(!e.backend.captureSnapshot)throw new a("UNSUPPORTED_OPERATION",`scroll ${n} requires snapshot support to verify hidden content before scrolling`);let{captureSnapshot:o}=e.backend;return await eh({edge:n,target:r,scope:i,captureNodes:async n=>{let r=await o(t8(e,t),{compact:!0,scope:n});return r.snapshot?.nodes??r.nodes??[]}})}function nq(e,t){switch(e){case"up":case"down":case"left":case"right":return e;default:throw new a("INVALID_ARGS",`${t} must be up, down, left, or right`)}}function nX(e,t){let n=Number(e.x),r=Number(e.y);if(!Number.isFinite(n)||!Number.isFinite(r))throw new a("INVALID_ARGS",`${t} point requires finite x and y`);return{x:n,y:r}}function nY(e,t){if(!Number.isFinite(e)||e<=0)throw new a("INVALID_ARGS",`${t} must be a positive number`);return e}function nV(e){let t=e.filter(t=>es(t,e)).map(e=>e.rect).filter(nH),n=t.length>0?t:e.map(e=>e.rect).filter(nH);if(0===n.length)throw new a("COMMAND_FAILED","Cannot infer viewport for directional swipe");let r=Math.min(...n.map(e=>e.x)),i=Math.min(...n.map(e=>e.y));return{x:r,y:i,width:Math.max(...n.map(e=>e.x+e.width))-r,height:Math.max(...n.map(e=>e.y+e.height))-i}}function nH(e){return!!(e&&e.width>0&&e.height>0)}function nz(e){return e&&"object"==typeof e?e:void 0}async function nK(e,t,n){let r=await nD(e,t,{action:n,requireInteractive:!0,promoteToHittableAncestor:!0});if(!e.backend.tap)throw new a("UNSUPPORTED_OPERATION","tap is not supported by this backend");let i=nj(await e.backend.tap(t8(e,t),r.point,{button:t.button,count:t.count,intervalMs:t.intervalMs,holdMs:t.holdMs,jitterPx:t.jitterPx,doubleTap:t.doubleTap}));return{...r,...i?{backendResult:i}:{}}}function nj(e){return e&&"object"==typeof e?e:void 0}function nW(e,t){if(void 0!==e)return nJ(e,t)}function nJ(e,t){let n=e?.trim();if(!n)throw new a("INVALID_ARGS",`${t} must be a non-empty string`);return n}function nZ(e){return e&&"object"==typeof e?e:void 0}let nQ=/^[A-Za-z0-9_.:-]{1,64}$/;async function n0(e,t){if(!t||"object"!=typeof t)throw new a("INVALID_ARGS","apps.push requires an input");if("json"===t.kind)return n1(t.payload,"apps.push JSON payload",8192),{backendInput:{kind:"json",payload:t.payload},inputKind:"json"};let n=await eq(e,t,{usage:"apps.push",field:"input"});return{backendInput:{kind:"file",path:n.path},inputKind:"file",...n.cleanup?{cleanup:n.cleanup}:{}}}function n1(e,t,n){if(function(e,t){if(!e||"object"!=typeof e||Array.isArray(e))throw new a("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 a("INVALID_ARGS",`${t} must be JSON-serializable`);return n}catch{throw new a("INVALID_ARGS",`${t} must be JSON-serializable`)}}(e,t),"utf8")>n)throw new a("INVALID_ARGS",`${t} exceeds ${n} bytes`)}function n2(e,t){return{session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata}}function n5(e){return e&&"object"==typeof e?e:void 0}async function n4(e,t,n){let r="reinstall"===n?"reinstallApp":"installApp",i=e.backend[r];if(!i)throw new a("UNSUPPORTED_OPERATION",`admin.${n} is not supported by this backend`);let o="app"in t&&void 0!==t.app?nJ(t.app,"app"):void 0;if("installFromSource"!==n&&!o)throw new a("INVALID_ARGS",`admin.${n} requires app`);let s=t8(e,t),l=await n8(e,s,t.source);try{var d,c,h,p,f;let t,r,a,w,m,b,g,y,x=await i.call(e.backend,s,{...o?{app:o}:{},source:l.source});return d=n,c=o,h=l.source,p=x,t=n7(p),r=n9(p,"appName"),a=n9(p,"appId"),w=n9(p,"bundleId"),m=n9(p,"packageName"),b=n9(p,"launchTarget"),g=n9(p,"installablePath"),y=n9(p,"archivePath"),{kind:"reinstall"===d?"appReinstalled":"installFromSource"===d?"appInstalledFromSource":"appInstalled",...c?{app:c}:{},source:h,...a?{appId:a}:{},...r?{appName:r}:{},...w?{bundleId:w}:{},...m?{packageName:m}:{},...b?{launchTarget:b}:{},...g?{installablePath:g}:{},...y?{archivePath:y}:{},...t?{backendResult:t}:{},...u(`${"reinstall"===d?"Reinstalled":"Installed"}: ${r??b??c??(f=h,"path"===f.kind?f.path:"uploadedArtifact"===f.kind?f.id:f.url)}`)}}finally{await l.cleanup?.()}}async function n8(e,t,n){let r=n6(n),i=await n3(e,r);try{let n=e.backend.resolveInstallSource?await e.backend.resolveInstallSource(t,i.source):i.source;return{source:n6(n),...i.cleanup?{cleanup:i.cleanup}:{}}}catch(e){if(i.cleanup)try{await i.cleanup()}catch{}throw e}}async function n3(e,t){if("url"===t.kind)return{source:t};let n=await eq(e,t,{usage:"admin.install",field:"source"});return{source:{kind:"path",path:n.path},...n.cleanup?{cleanup:n.cleanup}:{}}}function n6(e){if(!e||"object"!=typeof e)throw new a("INVALID_ARGS","install source is required");if("path"===e.kind)return{kind:"path",path:nJ(e.path,"source.path")};if("uploadedArtifact"===e.kind)return{kind:"uploadedArtifact",id:nJ(e.id,"source.id")};if("url"===e.kind){let t=nJ(e.url,"source.url");return function(e){let t;try{t=new URL(e)}catch{throw new a("INVALID_ARGS",`Invalid install source URL: ${e}`)}if("http:"!==t.protocol&&"https:"!==t.protocol)throw new a("INVALID_ARGS","Install source URL must use http or https")}(t),{kind:"url",url:t}}throw new a("INVALID_ARGS","install source kind must be path, uploadedArtifact, or url")}function n9(e,t){let n=e[t];return"string"==typeof n&&n.length>0?n:void 0}function n7(e){return e&&"object"==typeof e?e:void 0}function re(e,t){if("start"===e||"stop"===e)return e;throw new a("INVALID_ARGS",`${t} action must be start or stop`)}function rt(e,t,n,r){return{kind:"start"===e?r.startKind:r.stopKind,action:e,...n?{artifact:n}:{},backendResult:t,...u("start"===e?r.startMessage:r.stopMessage)}}let rn=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i,rr=/\b[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\b/g;function ri(e){var t,n;let r=!1,i=e;return{value:(t=i=(i=(i=(i=(i=i.replaceAll(/(authorization|token|secret|password|passwd|api[-_]?key)=([^&\s]+)/gi,(e,t)=>(r=!0,`${String(t)}=[REDACTED]`))).replaceAll(/("(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)"\s*:\s*")([^"]*)(")/gi,(e,t,n,i)=>(r=!0,`${String(t)}[REDACTED]${String(i)}`))).replaceAll(/\b(Bearer\s+)([^\s",;]+)/gi,(e,t)=>(r=!0,`${String(t)}[REDACTED]`))).replaceAll(/((?:authorization|cookie|token|secret|password|passwd|api[-_]?key)\s*[:=]\s*)([^\s,;&]+)/gi,(e,t)=>(r=!0,`${String(t)}[REDACTED]`))).replaceAll(rr,()=>(r=!0,"[REDACTED]")),n=()=>{r=!0},i=/(https?:\/\/|token|secret|password|authorization|cookie|api[-_]?key)/i.test(t)?t.replaceAll(/https?:\/\/[^\s"'<>)]+/gi,e=>{let t=ra(e);return t?(t.redacted&&n(),t.value):e}):t),redacted:r}}function ra(e){try{let t=new URL(e),n=function(e){let t=!1;for(let n of Array.from(e.searchParams.keys()))rn.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 ro=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i;function rs(e){if(!e)return{redacted:!1};let t=!1,n={};for(let[r,i]of Object.entries(e))if(ro.test(r))n[r]="[REDACTED]",t=!0;else{let e=ru(i,2048);n[r]=e.value??"",t||=e.redacted}return{value:n,redacted:t}}function rl(e){return void 0===e?{redacted:!1}:function(e){try{let t=JSON.parse(e),n=rc(t,ri);return rh(JSON.stringify(n.value),2048,n.redacted)}catch{return}}(e)??ru(e,2048)}function rd(e){return rc(e,e=>ru(e,2048))}function rc(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 r=rc(e,t);return n||=r.redacted,r.value}),redacted:n}}let n=!1,r={};for(let[i,a]of Object.entries(e)){if(ro.test(i)){r[i]="[REDACTED]",n=!0;continue}let e=rc(a,t);r[i]=e.value,n||=e.redacted}return{value:r,redacted:n}}function ru(e,t){if(void 0===e)return{redacted:!1};let n=ri(e);return rh(n.value,t,n.redacted)}function rh(e,t,n){if(void 0===e)return{redacted:n};let r=e;return r.length>t&&(r=`${r.slice(0,t)}...[truncated]`,n=!0),{value:r,redacted:n}}async function rp(e,t){let n=t8(e,t),r=t.session?await e.sessions.get(t.session):void 0;return{...n,...t.appId??r?.appId?{appId:t.appId??r?.appId}:{},...t.appBundleId??r?.appBundleId?{appBundleId:t.appBundleId??r?.appBundleId}:{}}}function rf(e,t,n,r){return{...rw(e),...void 0!==e.cursor?{cursor:nJ(e.cursor,"cursor")}:{},limit:void 0===e.limit?t:ev(e.limit,r,1,n)}}function rw(e){return{...void 0!==e.since?{since:nJ(e.since,"since")}:{},...void 0!==e.until?{until:nJ(e.until,"until")}:{}}}function rm(e,t,n=50){if(!Array.isArray(e))throw new a("INVALID_ARGS",`${t} must be an array of strings`);if(e.length>n)throw new a("INVALID_ARGS",`${t} must contain at most ${n} entries`);return e.map((e,n)=>nJ(e,`${t}[${n}]`))}let rb=eV,rg=async(e,t)=>{let n,r,i;if(!t.baseline)throw new a("INVALID_ARGS","diff screenshot requires a baseline image");let o=function(e){if(null==e||""===e)return .1;let t=Number(e);if(Number.isNaN(t)||t<0||t>1)throw new a("INVALID_ARGS","--threshold must be a number between 0 and 1");return t}(t.threshold),s=t.current??{kind:"live"};if(t.overlayRefs&&!t$(s))throw new a("INVALID_ARGS","diff screenshot <current.png> cannot use --overlay-refs because saved-image comparisons have no live accessibility refs");let l=await eq(e,t.baseline,{usage:"diff screenshot baseline",field:"baseline"}),d=[];try{let a;a=t$(s)?(r=await tS(e,t)).path:(n=await eq(e,s,{usage:"diff screenshot current",field:"current"})).path,i=t.out?await eX(e,t.out,{field:"diffPath",ext:".png"}):void 0;let c=await tv(l.path,a,{threshold:o,outputPath:i?.path,maxPixels:e.policy.maxImagePixels});t$(s)&&(c=await tD(e,t,i?.path,c,d));let u=c.diffPath?await i?.publish():void 0;return u&&d.push(u),c.diffPath||await i?.cleanup?.(),{...c,...d.length>0?{artifacts:d}:{}}}catch(e){throw await i?.cleanup?.(),e}finally{await l.cleanup?.(),await n?.cleanup?.(),await r?.cleanup?.()}},ry=async(e,t)=>{var n;let r,i,a=await t9(e,t),o=function(e){var t,n,r,i,a;let{previous:o,current:s,options:l,identity:d}=e;if(!0===l.forceFull||!0===l.raw||!o||!1===o.comparisonSafe||!1===s.comparisonSafe||(t=o,n=s,r=d,t.backend&&n.backend&&t.backend!==n.backend||r?.previousAppBundleId&&r.currentAppBundleId&&r.previousAppBundleId!==r.currentAppBundleId)||!o.presentationKey||o.presentationKey!==s.presentationKey||(i=o,a=s,i.truncated!==a.truncated||JSON.stringify(t4(i.nodes))!==JSON.stringify(t4(a.nodes))))return;let c=l.scope?.trim();return{ageMs:Math.max(0,s.createdAt-o.createdAt),nodeCount:s.nodes.length,...!0===l.interactiveOnly?{interactiveOnly:!0}:{},...c?{scope:c}:{}}}({previous:a.session?.snapshot,current:a.snapshot,options:t,identity:{previousAppBundleId:a.session?.appBundleId,currentAppBundleId:a.result.appBundleId??a.session?.appBundleId}});return await e.sessions.set(t7(t.session,a)),{nodes:a.snapshot.nodes,truncated:a.snapshot.truncated??!1,visibility:function(e){var t;let{nodes:n,backend:r,snapshotRaw:i}=e;if(i||"macos-helper"===(t=r)||"linux-atspi"===t)return{partial:!1,visibleNodeCount:n.length,totalNodeCount:n.length,reasons:[]};let a=ei(n),o=new Set;return a.hiddenCount>0&&o.add("offscreen-nodes"),a.nodes.some(e=>e.hiddenContentAbove)&&o.add("scroll-hidden-above"),a.nodes.some(e=>e.hiddenContentBelow)&&o.add("scroll-hidden-below"),{partial:o.size>0,visibleNodeCount:a.nodes.length,totalNodeCount:n.length,reasons:[...o]}}({nodes:a.snapshot.nodes,backend:a.snapshot.backend,snapshotRaw:t.raw}),...a.result.androidSnapshot?{androidSnapshot:a.result.androidSnapshot}:{},...a.warnings.length>0?{warnings:a.warnings}:{},...o?{unchanged:o}:{},...(r=(n=a).result.appName??n.session?.appName,i=n.result.appBundleId??n.session?.appBundleId,{...r||i?{appName:r??i}:{},...i?{appBundleId:i}:{}})}},rx=async(e,t)=>{let n=await t9(e,t),r=!0===t.interactiveOnly,i=n.session?.snapshot,a=t7(t.session,n);if(!i){let t=function(e,t={}){return tV(e,t).length}(n.snapshot.nodes,{flatten:r});return await e.sessions.set(a),{mode:"snapshot",baselineInitialized:!0,summary:{additions:0,removals:0,unchanged:t},lines:[],...n.warnings.length>0?{warnings:n.warnings}:{}}}let o=function(e,t,n={}){let r=function(e,t){let n=e.length,r=t.length,i=n+r,a=new Map,o=[];a.set(1,0);for(let s=0;s<=i;s+=1){o.push(new Map(a));for(let i=-s;i<=s;i+=2){let l=i===-s||i!==s&&tH(a,i-1)<tH(a,i+1)?tH(a,i+1):tH(a,i-1)+1,d=l-i;for(;l<n&&d<r&&e[l].comparable===t[d].comparable;)l+=1,d+=1;if(a.set(i,l),l>=n&&d>=r)return function(e,t,n,r,i){let a=[],o=r,s=i;for(let r=e.length-1;r>=0;r-=1){let i=e[r],l=o-s,d=l===-r||l!==r&&tH(i,l-1)<tH(i,l+1)?l+1:l-1,c=tH(i,d),u=c-d;for(;o>c&&s>u;)a.push({kind:"unchanged",text:n[s-1].text}),o-=1,s-=1;if(0===r)break;o===c?(a.push({kind:"added",text:n[u].text}),s=u):(a.push({kind:"removed",text:t[c].text}),o=c)}return a.reverse(),a}(o,e,t,n,r)}}return[]}(tV(e,n),tV(t,n)),i={additions:0,removals:0,unchanged:0};for(let e of r)"added"===e.kind&&(i.additions+=1),"removed"===e.kind&&(i.removals+=1),"unchanged"===e.kind&&(i.unchanged+=1);return{summary:i,lines:r}}(i.nodes,n.snapshot.nodes,{flatten:r});return await e.sessions.set(a),{mode:"snapshot",baselineInitialized:!1,summary:o.summary,lines:o.lines,...n.warnings.length>0?{warnings:n.warnings}:{}}},rv=async(e,t)=>{let n=t.locator??"any";if(!t.query)throw new a("INVALID_ARGS","find requires a value");if("wait"===t.action)return await nw(e,t,n);let{capture:r,match:i}=await nm(e,t,n);if(!i)throw new a("COMMAND_FAILED","find did not match any element");if("exists"===t.action)return{kind:"found",found:!0};let o=`@${i.ref}`;return"get_attrs"===t.action?{kind:"attrs",ref:o,node:i}:{kind:"text",ref:o,text:await no(e,r,i),node:i}},rk=ns,rI=nl,rM=nd,rA=nc,rN=nu,rR=nh,rP=np,rS=nf,rD=async(e,t)=>await nK(e,t,"click"),rE=async(e,t)=>await nK(e,t,"press"),rO=async(e,t)=>{var n;if(!t.text)throw new a("INVALID_ARGS","fill requires text");let r=await nD(e,t,{action:"fill",requireInteractive:!0,promoteToHittableAncestor:!1});if(!e.backend.fill)throw new a("UNSUPPORTED_OPERATION","fill is not supported by this backend");let i=nj(await e.backend.fill(t8(e,t),r.point,t.text,{delayMs:t.delayMs})),o="node"in r?r.node.type??"":"",s=o&&!O(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,...s?{warning:s}:{},...i?{backendResult:i}:{}}},r_=async(e,t)=>{let n=t.text;if(!n)throw new a("INVALID_ARGS","type requires text");let r=U(n);if(r)throw new a("INVALID_ARGS",`type does not accept a target ref like "${r}"`,{hint:`Use fill ${r} "text" to target that field, or press ${r} then type "text" to append.`});if(!e.backend.typeText)throw new a("UNSUPPORTED_OPERATION","type is not supported by this backend");let i=ev(t.delayMs??0,"delay-ms",0,1e4),o=nj(await e.backend.typeText(t8(e,t),n,{delayMs:i}));return{kind:"text",text:n,delayMs:i,...o?{backendResult:o}:{},...u(`Typed ${Array.from(n).length} chars`)}},rT=async(e,t)=>{let n=await nD(e,t,{action:"focus",requireInteractive:!0,promoteToHittableAncestor:!1});if(!e.backend.focus)throw new a("UNSUPPORTED_OPERATION","focus is not supported by this backend");let r=nz(await e.backend.focus(t8(e,t),n.point));return{...n,...r?{backendResult:r}:{},...u(`Focused (${n.point.x}, ${n.point.y})`)}},r$=async(e,t)=>{let n=await nD(e,t,{action:"longPress",requireInteractive:!0,promoteToHittableAncestor:!0});if(!e.backend.longPress)throw new a("UNSUPPORTED_OPERATION","longPress is not supported by this backend");let r=void 0===t.durationMs?void 0:ev(t.durationMs,"durationMs",0,12e4),i=nz(await e.backend.longPress(t8(e,t),n.point,{durationMs:r}));return{...n,...void 0!==r?{durationMs:r}:{},...i?{backendResult:i}:{},...u(`Long pressed (${n.point.x}, ${n.point.y})`)}},rC=async(e,t)=>{if(!e.backend.swipe)throw new a("UNSUPPORTED_OPERATION","swipe is not supported by this backend");if(t.preset)return await nU(e,t,e.backend.swipe);let n=await nG(e,t),r=function(e,t){if(t.to)return{point:nX(t.to,"to")};let n=nq(t.direction,"swipe direction"),r=nY(t.distance??200,"swipe distance");switch(n){case"up":return{point:{x:e.x,y:e.y-r},direction:n,distance:r};case"down":return{point:{x:e.x,y:e.y+r},direction:n,distance:r};case"left":return{point:{x:e.x-r,y:e.y},direction:n,distance:r};case"right":return{point:{x:e.x+r,y:e.y},direction:n,distance:r}}}(n.point,t),i=void 0===t.durationMs?void 0:ev(t.durationMs,"durationMs",16,1e4),o=nz(await e.backend.swipe(t8(e,t),n.point,r.point,{durationMs:i}));return{kind:"swipe",from:n.point,to:r.point,...r.direction?{direction:r.direction}:{},...void 0!==r.distance?{distance:r.distance}:{},...void 0!==i?{durationMs:i}:{},...n.target?{fromTarget:n.target}:{},...o?{backendResult:o}:{},...u("Swiped")}},rL=async(e,t)=>{var n,r,i,o;let s;if(!e.backend.scroll)throw new a("UNSUPPORTED_OPERATION","scroll is not supported by this backend");let l="bottom"===(n=t.direction)?{direction:"down",edge:"bottom"}:"top"===n?{direction:"up",edge:"top"}:{direction:nq(n,"scroll direction")},d=(r=t.amount,i="scroll amount",void 0===r?void 0:nY(r,i)),c=function(e,t){if(void 0!==e){if(!Number.isFinite(e)||!Number.isInteger(e)||e<=0)throw new a("INVALID_ARGS",`${t} must be a positive integer`);return e}}(t.pixels,"scroll pixels");if(void 0!==d&&void 0!==c)throw new a("INVALID_ARGS","scroll accepts either amount or pixels, not both");let h=await nB(e,t),p="viewport"===h.kind?{kind:"viewport"}:{kind:"point",point:h.point},f=e.backend.scroll,w=async()=>await f(t8(e,t),p,{direction:l.direction,...void 0!==d?{amount:d}:{},...void 0!==c?{pixels:c}:{}}),m=0;if(l.edge){let n=l.edge,r="viewport"===(o=h).kind?{}:{point:o.point,nodeIndex:"node"in o?o.node.index:void 0},i=await ep({edge:n,captureState:async i=>await nF(e,t,n,r,i),scroll:w});s=i.result,m=i.passes}else s=await w(),m=1;let b=nz(s);return{...h,direction:l.direction,...l.edge?{edge:l.edge,passes:m}:{},...void 0!==d?{amount:d}:{},...void 0!==c?{pixels:c}:{},...b?{backendResult:b}:{},...u(ef(l.direction,l.edge,m,d,c))}},rU=async(e,t)=>{if(!e.backend.pinch)throw new a("UNSUPPORTED_OPERATION","pinch is not supported by this backend");await nO(e,t,"pinch");let n=nY(t.scale,"pinch scale"),r=t.center?await nD(e,{...t,target:t.center},{action:"pinch",requireInteractive:!1,promoteToHittableAncestor:!1}):void 0,i=nz(await e.backend.pinch(t8(e,t),{scale:n,...r?{center:r.point}:{}}));return{kind:"pinch",scale:n,...r?{center:r.point,centerTarget:r}:{},...i?{backendResult:i}:{},...u(`Pinched to scale ${n}`)}},rB=async(e,t={})=>{if(!e.backend.pressBack)throw new a("UNSUPPORTED_OPERATION","system.back is not supported by this backend");let n=t.mode??"in-app";if("in-app"!==n&&"system"!==n)throw new a("INVALID_ARGS","system.back mode must be in-app or system");let r=nZ(await e.backend.pressBack(t8(e,t),{mode:n}));return{kind:"systemBack",mode:n,...r?{backendResult:r}:{},...u("Back")}},rG=async(e,t={})=>{if(!e.backend.pressHome)throw new a("UNSUPPORTED_OPERATION","system.home is not supported by this backend");let n=nZ(await e.backend.pressHome(t8(e,t)));return{kind:"systemHome",...n?{backendResult:n}:{},...u("Home")}},rF=async(e,t)=>{if(!e.backend.rotate)throw new a("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 a("INVALID_ARGS","system.rotate orientation must be portrait, portrait-upside-down, landscape-left, or landscape-right")}}(t.orientation),r=nZ(await e.backend.rotate(t8(e,t),n));return{kind:"systemRotated",orientation:n,...r?{backendResult:r}:{},...u(`Rotated to ${n}`)}},rq=async(e,t={})=>{var n,r,i,o,s,l,d;if(!e.backend.setKeyboard)throw new a("UNSUPPORTED_OPERATION","system.keyboard is not supported by this backend");let c=t.action??"status";if(!L(c))throw new a("INVALID_ARGS","system.keyboard action must be status, get, dismiss, enter, or return");let h=await e.backend.setKeyboard(t8(e,t),{action:c}),p=nZ(h),f=(n=h)&&"object"==typeof n?h:{};return"enter"===c||"return"===c?{kind:"keyboardEnterPressed",action:"enter",state:f,...(r=p)?{backendResult:r}:{},...u("Keyboard enter pressed")}:"dismiss"===c?(i=c,{kind:"keyboardDismissed",action:i,state:o=f,...(s=p)?{backendResult:s}:{},...u(!1===o.dismissed?"Keyboard already hidden":"Keyboard dismissed")}):(l=c,{kind:"keyboardState",action:l,state:f,...(d=p)?{backendResult:d}:{}})},rX=async(e,t)=>{if("read"===t.action){if(!e.backend.getClipboard)throw new a("UNSUPPORTED_OPERATION","system.clipboard read is not supported by this backend");let n=await e.backend.getClipboard(t8(e,t));return{kind:"clipboardText",action:"read",text:"string"==typeof n?n:n.text}}if("write"!==t.action)throw new a("INVALID_ARGS","system.clipboard action must be read or write");if(!e.backend.setClipboard)throw new a("UNSUPPORTED_OPERATION","system.clipboard write is not supported by this backend");if("string"!=typeof t.text)throw new a("INVALID_ARGS","system.clipboard write requires text");let n=nZ(await e.backend.setClipboard(t8(e,t),t.text));return{kind:"clipboardUpdated",action:"write",textLength:Array.from(t.text).length,...n?{backendResult:n}:{},...u("Clipboard updated")}},rY=async(e,t={})=>{if(!e.backend.openSettings)throw new a("UNSUPPORTED_OPERATION","system.settings is not supported by this backend");let n=nW(t.target,"target"),r=nZ(await e.backend.openSettings(t8(e,t),n));return{kind:"settingsOpened",...n?{target:n}:{},...r?{backendResult:r}:{},...u(n?`Opened settings: ${n}`:"Opened settings")}},rV=async(e,t={})=>{var n,r;if(!e.backend.handleAlert)throw new a("UNSUPPORTED_OPERATION","system.alert is not supported by this backend");let i=t.action??"get";if("get"!==i&&"accept"!==i&&"dismiss"!==i&&"wait"!==i)throw new a("INVALID_ARGS","system.alert action must be get, accept, dismiss, or wait");let o=void 0===t.timeoutMs?void 0:ev(t.timeoutMs,"timeoutMs",0,12e4),s=await e.backend.handleAlert(t8(e,t),i,{timeoutMs:o});return n=i,r=s,"get"===n?function(e){if("alertStatus"!==e.kind)throw new a("COMMAND_FAILED","system.alert get returned an invalid backend result");return{kind:"alertStatus",action:"get",alert:e.alert}}(r):"wait"===n?function(e){if("alertWait"!==e.kind)throw new a("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}:{},...u(e.alert?"Alert visible":"Alert wait timed out")}}(r):function(e,t){if("alertHandled"!==t.kind)throw new a("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}:{},...u(t.handled?`Alert ${e}ed`:"No alert handled")}}(n,r)},rH=async(e,t={})=>{if(!e.backend.openAppSwitcher)throw new a("UNSUPPORTED_OPERATION","system.appSwitcher is not supported by this backend");let n=nZ(await e.backend.openAppSwitcher(t8(e,t)));return{kind:"appSwitcherOpened",...n?{backendResult:n}:{},...u("Opened app switcher")}},rz=async(e,t)=>{var n;if(!e.backend.openApp)throw new a("UNSUPPORTED_OPERATION","apps.open is not supported by this backend");let r=function(e){var t;let n=nW(e.app,"app"),r=nW(e.appId,"appId"),i=nW(e.bundleId,"bundleId"),o=nW(e.packageName,"packageName"),s=nW(e.url,"url"),l=nW(e.activity,"activity"),d={...n?{app:n}:{},...r?{appId:r}:{},...i?{bundleId:i}:{},...o?{packageName:o}:{},...s?{url:s}:{},...l?{activity:l}:{}};if(!((t=d).app??t.appId??t.bundleId??t.packageName??t.url??t.activity))throw new a("INVALID_ARGS","apps.open requires app, appId, bundleId, packageName, url, or activity");return d}(t),i=n5(await e.backend.openApp(n2(e,t),r,{launchArgs:t.launchArgs,relaunch:t.relaunch}));return{kind:"appOpened",target:r,relaunch:!0===t.relaunch,...i?{backendResult:i}:{},...u(`Opened: ${(n=r).app??n.appId??n.bundleId??n.packageName??n.url??n.activity??"app"}`)}},rK=async(e,t={})=>{if(!e.backend.closeApp)throw new a("UNSUPPORTED_OPERATION","apps.close is not supported by this backend");let n=nW(t.app,"app"),r=n5(await e.backend.closeApp(n2(e,t),n));return{kind:"appClosed",...n?{app:n}:{},...r?{backendResult:r}:{},...u(n?`Closed: ${n}`:"Closed app")}},rj=async(e,t={})=>{if(!e.backend.listApps)throw new a("UNSUPPORTED_OPERATION","apps.list is not supported by this backend");return{kind:"appsList",apps:await e.backend.listApps(n2(e,t),$(t.filter))}},rW=async(e,t)=>{if(!e.backend.getAppState)throw new a("UNSUPPORTED_OPERATION","apps.state is not supported by this backend");let n=nJ(t.app,"app"),r=await e.backend.getAppState(n2(e,t),n);return{kind:"appState",app:n,state:r}},rJ=async(e,t)=>{if(!e.backend.pushFile)throw new a("UNSUPPORTED_OPERATION","apps.push is not supported by this backend");let n=nJ(t.app,"app"),r=await n0(e,t.input);try{let i=await e.backend.pushFile(n2(e,t),r.backendInput,n),a=n5(i);return{kind:"appPushed",app:n,inputKind:r.inputKind,...a?{backendResult:a}:{},...u(`Pushed to ${n}`)}}finally{await r.cleanup?.()}},rZ=async(e,t)=>{var n,r;if(!e.backend.triggerAppEvent)throw new a("UNSUPPORTED_OPERATION","apps.triggerEvent is not supported by this backend");let i=function(e){let t=nJ(e,"name");if(!nQ.test(t))throw new a("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,r=`apps.triggerEvent payload for "${i}"`,void 0!==n&&n1(n,r,8192);let o=n5(await e.backend.triggerAppEvent(n2(e,t),{name:i,...t.payload?{payload:t.payload}:{}}));return{kind:"appEventTriggered",name:i,...t.payload?{payload:t.payload}:{},...o?{backendResult:o}:{},...u(`Triggered app event: ${i}`)}},rQ=async(e,t={})=>{if(!e.backend.listDevices)throw new a("UNSUPPORTED_OPERATION","admin.devices is not supported by this backend");return{kind:"adminDevices",devices:await e.backend.listDevices(t8(e,t),t.filter)}},r0=async(e,t={})=>{if(!e.backend.bootDevice)throw new a("UNSUPPORTED_OPERATION","admin.boot is not supported by this backend");let n=function(e){if(!e)return;let t=nW(e.id,"target.id"),n=nW(e.name,"target.name"),r={...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(r).length>0?r:void 0}(t.target),r=n7(await e.backend.bootDevice(t8(e,t),n));return{kind:"deviceBooted",...n?{target:n}:{},...r?{backendResult:r}:{},...u("Booted device")}},r1=async(e,t)=>await n4(e,t,"install"),r2=async(e,t)=>await n4(e,t,"reinstall"),r5=async(e,t)=>await n4(e,t,"installFromSource"),r4=async(e,t)=>{let n=re(t.action,"record"),r="start"===n?e.backend.startRecording:e.backend.stopRecording;if(!r)throw new a("UNSUPPORTED_OPERATION",`record ${n} is not supported by this backend`);let i=t.out?await eX(e,t.out,{field:"path",ext:".mp4"}):void 0;try{var o,s,l,d,c;let a,u,h=(o=t,s=i?.path,a=void 0===o.fps?void 0:ev(o.fps,"fps",1,60),u=void 0===o.quality?void 0:ev(o.quality,"quality",5,10),{...s?{outPath:s}:{},...void 0!==a?{fps:a}:{},...void 0!==u?{quality:u}:{},...void 0!==o.hideTouches?{showTouches:!0!==o.hideTouches}:{}}),p=await r.call(e.backend,t8(e,t),h),f=await i?.publish();return l=n,d=p,c=f,{..."string"==typeof d.path?{path:d.path}:{},..."string"==typeof d.telemetryPath?{telemetryPath:d.telemetryPath}:{},..."string"==typeof d.warning?{warning:d.warning}:{},...rt(l,d,c,{startKind:"recordingStarted",stopKind:"recordingStopped",startMessage:"Recording started",stopMessage:"Recording stopped"})}}catch(e){throw await i?.cleanup?.(),e}},r8=async(e,t)=>{let n=re(t.action,"trace"),r="start"===n?e.backend.startTrace:e.backend.stopTrace;if(!r)throw new a("UNSUPPORTED_OPERATION",`trace ${n} is not supported by this backend`);let i=t.out?await eX(e,t.out,{field:"outPath",ext:".trace"}):void 0;try{var o,s,l;let a={...i?.path?{outPath:i.path}:{}},d=await r.call(e.backend,t8(e,t),a),c=await i?.publish();return o=n,s=d,l=c,{..."string"==typeof s.outPath?{outPath:s.outPath}:{},...rt(o,s,l,{startKind:"traceStarted",stopKind:"traceStopped",startMessage:"Trace started",stopMessage:"Trace stopped"})}}catch(e){throw await i?.cleanup?.(),e}},r3=async(e,t={})=>{var n,r;let i;if(!e.backend.readLogs)throw new a("UNSUPPORTED_OPERATION","diagnostics.logs is not supported by this backend");return i=!0===(n=await e.backend.readLogs(await rp(e,t),{...rf(r=t,100,500,"logs limit"),...void 0!==r.levels?{levels:rm(r.levels,"levels")}:{},...void 0!==r.search?{search:nJ(r.search,"search")}:{},...void 0!==r.source?{source:nJ(r.source,"source")}:{}})).redacted,{kind:"diagnosticsLogs",entries:n.entries.map(e=>{let t=ru(e.message,4096),n=rd(e.metadata);return i||=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:i,...n.notes?{notes:n.notes}:{}}},r6=async(e,t={})=>{var n,r,i;let o;if(!e.backend.dumpNetwork)throw new a("UNSUPPORTED_OPERATION","diagnostics.network is not supported by this backend");let s={...rf(i=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 a("INVALID_ARGS","network include must be summary, headers, body, or all")}(i.include)};return n=await e.backend.dumpNetwork(await rp(e,t),s),r=s.include??"summary",o=!0===n.redacted,{kind:"diagnosticsNetwork",entries:n.entries.map(e=>{var t;let n=e.url?ra(t=e.url)??ru(t,2048):void 0,i="headers"===r||"all"===r?rs(e.requestHeaders):void 0,a="headers"===r||"all"===r?rs(e.responseHeaders):void 0,s="body"===r||"all"===r?rl(e.requestBody):void 0,l="body"===r||"all"===r?rl(e.responseBody):void 0,d=rd(e.metadata);return o||=(n?.redacted??!1)||(i?.redacted??!1)||(a?.redacted??!1)||(s?.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}:{},...i?.value?{requestHeaders:i.value}:{},...a?.value?{responseHeaders:a.value}:{},...s?.value!==void 0?{requestBody:s.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:o,...n.notes?{notes:n.notes}:{}}},r9=async(e,t={})=>{var n,r;let i;if(!e.backend.measurePerf)throw new a("UNSUPPORTED_OPERATION","diagnostics.perf is not supported by this backend");return i=!0===(n=await e.backend.measurePerf(await rp(e,t),{...rw(r=t),...void 0!==r.sampleMs?{sampleMs:ev(r.sampleMs,"sampleMs",100,6e4)}:{},...void 0!==r.metrics?{metrics:rm(r.metrics,"metrics",20)}:{}})).redacted,{kind:"diagnosticsPerf",metrics:n.metrics.map(e=>{let t=ru(e.message,4096),n=rd(e.metadata);return i||=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:i,...n.notes?{notes:n.notes}:{}}};function r7(e){let t={backend:e.backend,artifacts:e.artifacts,sessions:e.sessions??function(e=[]){let t=new Map(e.map(e=>[e.name,ie(e)]));return{get:e=>ie(t.get(e)),set:e=>{t.set(e.name,ie(e))},delete:e=>{t.delete(e)},list:()=>Array.from(t.values(),e=>ie(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=>rb(t,e),diffScreenshot:e=>rg(t,e),snapshot:e=>ry(t,e),diffSnapshot:e=>rx(t,e)},selectors:{find:e=>rv(t,e),get:e=>rk(t,e),getText:(e,n={})=>rI(t,{...n,target:e}),getAttrs:(e,n={})=>rM(t,{...n,target:e}),is:e=>rA(t,e),isVisible:(e,n={})=>rN(t,{...n,target:e}),isHidden:(e,n={})=>rR(t,{...n,target:e}),wait:e=>rP(t,e),waitForText:(e,n={})=>rS(t,{...n,text:e})},interactions:{click:(e,n={})=>rD(t,{...n,target:e}),press:(e,n={})=>rE(t,{...n,target:e}),fill:(e,n,r={})=>rO(t,{...r,target:e,text:n}),typeText:(e,n={})=>r_(t,{...n,text:e}),focus:(e,n={})=>rT(t,{...n,target:e}),longPress:(e,n={})=>r$(t,{...n,target:e}),swipe:e=>rC(t,e),scroll:e=>rL(t,e),pinch:e=>rU(t,e)},system:{back:e=>rB(t,e),home:e=>rG(t,e),rotate:e=>rF(t,e),keyboard:e=>rq(t,e),clipboard:e=>rX(t,e),settings:e=>rY(t,e),alert:e=>rV(t,e),appSwitcher:e=>rH(t,e)},apps:{open:e=>rz(t,e),close:e=>rK(t,e),list:(e={})=>rj(t,{...e,filter:T(e.filter)}),state:e=>rW(t,e),push:e=>rJ(t,e),triggerEvent:e=>rZ(t,e)},admin:{devices:e=>rQ(t,e),boot:e=>r0(t,e),install:e=>r1(t,e),reinstall:e=>r2(t,e),installFromSource:e=>r5(t,e)},recording:{record:e=>r4(t,e),trace:e=>r8(t,e)},observability:{logs:e=>r3(t,e),network:e=>r6(t,e),perf:e=>r9(t,e)}}}function ie(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 it(e={}){return{allowLocalInputPaths:!0,allowLocalOutputPaths:!0,maxImagePixels:2e7,allowNamedBackendCapabilities:[],...e}}export{eP as PNG,ei as buildMobileSnapshotPresentation,B as buildScrollGesturePlan,tL as buildSnapshotDisplayLines,G as buildSwipeGesturePlan,F as buildSwipePresetGesturePlan,eh as captureScrollEdgeState,V as clampGesturePoint,j as clampToRange,r7 as createAgentDevice,eG as decodePng,ea as deriveMobileSnapshotHiddenContentHints,tz as detectReactNativeOverlay,er as displayNodeLabel,nn as evaluateIsPredicate,U as findMistargetedTypeRefToken,ef as formatScrollEdgeMessage,tU as formatSnapshotLine,X as inferGestureReferenceFrame,ee as inferVerticalScrollIndicatorDirections,nM as interiorCoordinate,L as isKeyboardAction,ek as isReactNativeCollapsedWarningLabel,nt as isSupportedPredicate,Q as isSystemScrollIndicatorLabel,it as localCommandPolicy,et as normalizeSnapshotTree,H as parseScrollDirection,q as parseSwipePreset,Y as pointFromPercent,nI as pointInsideRect,ev as requireIntInRange,nN as resolveActionableTouchNode,nR as resolveActionableTouchResolution,tK as resolveReactNativeOverlayDismissTarget,nv as resolveRectCenter,ep as runScrollEdgePasses};
package/dist/src/9542.js CHANGED
@@ -1,3 +1,3 @@
1
- import e from"node:net";import t from"node:http";import a from"node:https";import r from"node:fs";import o from"node:os";import n from"node:path";import{pipeline as i}from"node:stream/promises";import{createHash as s,randomUUID as l}from"node:crypto";import{Writable as c}from"node:stream";import{toAppErrorCode as d,AppError as u}from"./9152.js";import{runCmdSync as p,runCmd as m,runCmdDetached as f}from"./9818.js";import{normalizeSession as h,consumeTextLines as y,PUBLIC_COMMANDS as w,isDaemonResponseEnvelope as I,isDaemonProgressEnvelope as g,prepareDaemonCommandRequest as v,readSnapshotNodes as A,normalizeMaterializationReleaseResult as k,computeDaemonCodeSignature as b,resolveDaemonTransportPreference as P,normalizeDeployResult as _,buildMeta as S,buildFlags as D,readOptionalString as E,resolveSessionName as M,formatRequestProgressEvent as T,shouldStreamRequestProgress as N,INTERNAL_COMMANDS as C,normalizeDevice as L,readRequiredString as U,readVersion as R,findProjectRoot as O,normalizeOpenDevice as x,resolveDaemonPaths as F,resolveDaemonServerMode as q,normalizeRuntimeHints as B,normalizeStartupSample as $,readScreenshotOverlayRefs as j,normalizeInstallFromSourceResult as H}from"./6277.js";import{createRequestId as K,withDiagnosticTimer as z,emitDiagnostic as G}from"./7599.js";import{isAgentDeviceDaemonProcess as V,stopProcessForTakeover as W}from"./8656.js";import{sleep as J}from"./4829.js";import{reloadMetro as Y,prepareMetroRuntime as Q}from"./1974.js";function X(e){return new Promise((t,a)=>{let r="";e.setEncoding("utf8"),e.on("data",e=>{r+=e}),e.on("end",()=>t(r)),e.on("error",a)})}let Z="sha256";async function ee(e){let t=await et(e.localPath,e.platform),a=e.baseUrl.endsWith("/")?e.baseUrl:`${e.baseUrl}/`;try{let r=await en({normalizedBase:a,token:e.token,artifact:t});if(r?.kind==="cache-hit")return r.uploadId;if(r?.kind==="direct-upload")try{return await ei(t.payloadPath,r),await el({normalizedBase:a,token:e.token,uploadId:r.uploadId})}catch{}return await eo({normalizedBase:a,token:e.token,artifact:t})}finally{t.cleanup()}}async function et(e,t){var a,o,i;let s,l=r.statSync(e),c=n.basename(e),d=l.isDirectory(),u=("ios"===(a=t)||"android"===a?a:void 0)??(o=e,i=l,s=o.toLowerCase(),i.isDirectory()&&s.endsWith(".app")||s.endsWith(".ipa")?"ios":s.endsWith(".apk")||s.endsWith(".aab")?"android":void 0),p=[];try{let t=d?await ea(e,p):e,a=r.statSync(t);return{payloadPath:t,fileName:c,artifactType:d?"app-bundle":"file",platform:u,contentType:d?"application/gzip":"application/octet-stream",sha256:await ec(t),sizeBytes:a.size,cleanup:()=>er(p)}}catch(e){throw er(p),e}}async function ea(e,t){let a=r.mkdtempSync(n.join(o.tmpdir(),`agent-device-upload-${l()}-`));t.push(a);let i=n.join(a,`${n.basename(e)}.tar.gz`);return await m("tar",["czf",i,"-C",n.dirname(e),n.basename(e)],{env:{...process.env,COPYFILE_DISABLE:"1"}}),i}function er(e){for(let t of e)r.rmSync(t,{recursive:!0,force:!0})}async function eo(e){let{normalizedBase:t,token:a,artifact:r}=e,o=new URL("upload",t),n={"content-type":r.contentType,"x-artifact-type":r.artifactType,"x-artifact-filename":r.fileName,"x-artifact-hash":r.sha256,"x-artifact-hash-algorithm":Z,"transfer-encoding":"chunked"};a&&(n.authorization=`Bearer ${a}`,n["x-agent-device-token"]=a);let i=await es({url:o,method:"POST",headers:n,payloadPath:r.payloadPath,timeoutMessage:"Artifact upload timed out",timeoutHint:"The upload to the remote daemon exceeded the 5-minute timeout.",errorMessage:"Failed to upload artifact to remote daemon",errorHint:"Verify the remote daemon is reachable and supports artifact uploads."});try{let e=JSON.parse(i.body);if(!e.ok||!e.uploadId)throw new u("COMMAND_FAILED",`Upload failed: ${i.body}`);return e.uploadId}catch(e){if(e instanceof u)throw e;throw new u("COMMAND_FAILED",`Invalid upload response: ${i.body}`)}}async function en(e){let t=new URL("upload/preflight",e.normalizedBase),a={"content-type":"application/json"};e.token&&(a.authorization=`Bearer ${e.token}`,a["x-agent-device-token"]=e.token);let r=await fetch(t,{method:"POST",headers:a,signal:AbortSignal.timeout(3e4),body:JSON.stringify({sha256:e.artifact.sha256,fileName:e.artifact.fileName,sizeBytes:e.artifact.sizeBytes,artifactType:e.artifact.artifactType,...e.artifact.platform?{platform:e.artifact.platform}:{},contentType:e.artifact.contentType})}).catch(()=>void 0);if(r?.ok)return function(e){var t;if(!e||"object"!=typeof e||!0!==e.ok||"string"!=typeof e.uploadId)return;if(!0===e.cacheHit)return{kind:"cache-hit",uploadId:e.uploadId};let a=e.upload;if(!a||"string"!=typeof a.url)return;let r=a.headers??{};if(!(!(t=r)||"object"!=typeof t||Array.isArray(t))&&Object.values(t).every(e=>"string"==typeof e))return{kind:"direct-upload",uploadId:e.uploadId,url:a.url,headers:r}}(await r.json().catch(()=>void 0))}async function ei(e,t){let a=await es({url:new URL(t.url),method:"PUT",headers:t.headers,payloadPath:e,timeoutMessage:"Direct artifact upload timed out",timeoutHint:"The direct upload ticket did not accept the artifact within the timeout.",errorMessage:"Failed to upload artifact with direct upload ticket"});if(a.statusCode<200||a.statusCode>=300)throw new u("COMMAND_FAILED","Direct artifact upload failed",{statusCode:a.statusCode,statusMessage:a.statusMessage})}async function es(e){let o="https:"===e.url.protocol?a:t;return await new Promise((t,a)=>{let n=o.request({protocol:e.url.protocol,host:e.url.hostname,port:e.url.port,method:e.method,path:e.url.pathname+e.url.search,headers:e.headers},e=>{X(e).then(a=>{clearTimeout(s),t({statusCode:e.statusCode??500,statusMessage:e.statusMessage,body:a})}).catch(a)}),s=setTimeout(()=>{n.destroy(),a(new u("COMMAND_FAILED",e.timeoutMessage,{timeoutMs:3e5,...e.timeoutHint?{hint:e.timeoutHint}:{}}))},3e5);n.on("error",t=>{clearTimeout(s),a(new u("COMMAND_FAILED",e.errorMessage,e.errorHint?{hint:e.errorHint}:{},t))}),n.on("close",()=>clearTimeout(s)),i(r.createReadStream(e.payloadPath),n).catch(e=>{n.destroy(),a(new u("COMMAND_FAILED","Failed to read local artifact",{},e instanceof Error?e:Error(String(e))))})})}async function el(e){let t=new URL("upload/finalize",e.normalizedBase),a={"content-type":"application/json"};e.token&&(a.authorization=`Bearer ${e.token}`,a["x-agent-device-token"]=e.token);let r=await fetch(t,{method:"POST",headers:a,signal:AbortSignal.timeout(3e4),body:JSON.stringify({uploadId:e.uploadId})}).catch(e=>{throw new u("COMMAND_FAILED","Failed to finalize direct artifact upload",{},e)});if(!r.ok)throw new u("COMMAND_FAILED","Direct artifact upload finalize failed",{status:r.status,statusText:r.statusText});let o=await r.json().catch(()=>void 0);if(!o?.ok||!o.uploadId)throw new u("COMMAND_FAILED","Invalid upload finalize response");return o.uploadId}async function ec(e){let t=s(Z),a=new c({write(e,a,r){t.update(e),r()}});return await i(r.createReadStream(e),a).catch(e=>{throw new u("COMMAND_FAILED","Failed to read local artifact",{},e instanceof Error?e:void 0)}),t.digest("hex")}function ed(e){let t=T(e);t&&process.stderr.write(`${t}
2
- `)}let eu=["xcodebuild .*AgentDeviceRunnerUITests/RunnerTests/testCommand","xcodebuild .*AgentDeviceRunner\\.env\\.session-","xcodebuild build-for-testing .*ios-runner/AgentDeviceRunner/AgentDeviceRunner\\.xcodeproj"],ep=new e.BlockList;async function em(t){var a,i,s,l,c,d;let p,m,f,h,y,I,g,v=t.meta?.requestId??K(),A=!!(t.meta?.debug||t.flags?.verbose),k=(h=(i=a=t,i.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR),y=(s=a,m=function(e){let t;if(e){try{t=new URL(e)}catch(t){throw new u("INVALID_ARGS","Invalid daemon base URL",{daemonBaseUrl:e},t instanceof Error?t:void 0)}if("http:"!==t.protocol&&"https:"!==t.protocol)throw new u("INVALID_ARGS","Daemon base URL must use http or https",{daemonBaseUrl:e});return t.toString().replace(/\/+$/,"")}}(p=s.flags?.daemonBaseUrl??process.env.AGENT_DEVICE_DAEMON_BASE_URL),function(t,a){let r;if(!(!t||"localhost"===(r=new URL(t).hostname.trim().toLowerCase().replace(/^\[(.*)\]$/,"$1"))||(e.isIPv4(r)?ep.check(r,"ipv4"):!!e.isIPv6(r)&&ep.check(r,"ipv6")))&&("string"!=typeof a||!(a.trim().length>0)))throw new u("INVALID_ARGS","Remote daemon base URL for non-loopback hosts requires daemon authentication",{daemonBaseUrl:t,hint:"Provide --daemon-auth-token or AGENT_DEVICE_DAEMON_AUTH_TOKEN when using a non-loopback remote daemon URL."})}(m,f=s.flags?.daemonAuthToken??process.env.AGENT_DEVICE_DAEMON_AUTH_TOKEN),{rawBaseUrl:p,remoteBaseUrl:m,authToken:f}),I=function(e,t){let a=e.flags?.daemonTransport??process.env.AGENT_DEVICE_DAEMON_TRANSPORT,r=P(a);if(t&&"socket"===r)throw new u("INVALID_ARGS","Remote daemon base URL only supports HTTP transport. Remove --daemon-transport socket.",{daemonBaseUrl:t});return{preference:r,serverMode:q(e.flags?.daemonServerMode??process.env.AGENT_DEVICE_DAEMON_SERVER_MODE??("dual"===a?"dual":void 0))}}(a,y.remoteBaseUrl),{paths:F((g=(l=a,c=h,d=y.rawBaseUrl,e_(l.command)&&!c&&!d))?r.mkdtempSync(n.join(o.tmpdir(),"agent-device-replay-daemon-")):h),transportPreference:I.preference,serverMode:I.serverMode,ownedStateDir:g,remoteBaseUrl:y.remoteBaseUrl,remoteAuthToken:y.authToken}),b=function(e){if(e.command!==w.test)return e.command===w.replay&&"number"==typeof e.flags?.timeoutMs?e.flags.timeoutMs:9e4}(t),_=await z("daemon_startup",async()=>await ev(k),{requestId:v,session:t.session}),S=_.info,D=await ef(t,S),E={...t,positionals:D.positionals,flags:D.flags,token:S.token,meta:{...t.meta??{},requestId:v,debug:A,cwd:t.meta?.cwd,tenantId:t.meta?.tenantId??t.flags?.tenant,runId:t.meta?.runId??t.flags?.runId,leaseId:t.meta?.leaseId??t.flags?.leaseId,sessionIsolation:t.meta?.sessionIsolation??t.flags?.sessionIsolation,lockPolicy:t.meta?.lockPolicy,lockPlatform:t.meta?.lockPlatform,...D.uploadedArtifactId?{uploadedArtifactId:D.uploadedArtifactId}:{},...D.clientArtifactPaths?{clientArtifactPaths:D.clientArtifactPaths}:{},...D.installSource?{installSource:D.installSource}:{}}};G({level:"info",phase:"daemon_request_prepare",data:{requestId:v,command:t.command,session:t.session}});try{return await z("daemon_request",async()=>await eB(S,E,k.transportPreference,b),{requestId:v,command:t.command})}finally{await eP(t,_,k)}}async function ef(e,t){let a,r=[...e.positionals??[]],o=e.flags?{...e.flags}:void 0,i=e.meta?.installSource,s={};if(!eJ(t))return ey({positionals:r,flags:o,installSource:i,uploadedArtifactId:a,clientArtifactPaths:s});o=function(e,t,a,r){var o,i;let s=function(e,t){if("screenshot"===e.command){let a=eI(e,"path",".png");return t[0]?{field:"path",localPath:a,positionalIndex:0,positionalPath:eg("screenshot",".png")}:{field:"path",localPath:a,positionalIndex:0,flagPath:eg("screenshot",".png")}}if("record"===e.command&&"start"===(t[0]??"").toLowerCase()){let t=eI(e,"outPath",".mp4",1);return{field:"outPath",localPath:t,positionalIndex:1,positionalPath:eg("recording",n.extname(t)||".mp4")}}return null}(e,t);if(!s)return a;void 0!==s.positionalPath&&(t[s.positionalIndex]=s.positionalPath);let l=(o=a,void 0===(i=s.flagPath)?o:{...o??{},out:i});return r[s.field]=s.localPath,l}(e,r,o,s);let l=await ew(e,t);l&&(i=l.installSource,a=l.uploadedArtifactId??a);let c=()=>ey({positionals:r,flags:o,installSource:i,uploadedArtifactId:a,clientArtifactPaths:s});return"install"!==e.command&&"reinstall"!==e.command||(a=await eh(e,t,r)??a),c()}async function eh(e,t,a){var o,i;let s,l=a[1];if(void 0===l)return;if(l.startsWith("remote:")){a[1]=l.slice(7);return}let c=(o=l,i=e.meta?.cwd,s=n.isAbsolute(o)?o:n.resolve(i??process.cwd(),o),r.existsSync(s)?s:void 0);if(c)return await ee({localPath:c,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform})}function ey(e){return{positionals:e.positionals,flags:e.flags,installSource:e.installSource,uploadedArtifactId:e.uploadedArtifactId,...Object.keys(e.clientArtifactPaths).length>0?{clientArtifactPaths:e.clientArtifactPaths}:{}}}async function ew(e,t){let a=e.meta?.installSource;if("install_source"!==e.command||!a||"path"!==a.kind)return null;let o=a.path.trim();if(!o)return{installSource:a};if(o.startsWith("remote:"))return{installSource:{...a,path:o.slice(7)}};let i=n.isAbsolute(o)?o:n.resolve(e.meta?.cwd??process.cwd(),o);if(!r.existsSync(i))return{installSource:{...a,path:i}};let s=await ee({localPath:i,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform});return{installSource:{...a,path:i},uploadedArtifactId:s}}function eI(e,t,a,r=0){let o=e.positionals?.[r]??e.flags?.out,i=`${"path"===t?"screenshot":"recording"}-${Date.now()}${a}`,s=o&&o.trim().length>0?o:i;return n.isAbsolute(s)?s:n.resolve(e.meta?.cwd??process.cwd(),s)}function eg(e,t){let a=t.startsWith(".")?t:`.${t}`;return n.posix.join("/tmp",`agent-device-${e}-${Date.now()}-${Math.random().toString(36).slice(2,8)}${a}`)}async function ev(e){if(e.remoteBaseUrl)return await eA(e);let t=await ek(e);return t?{info:t,startedByClient:!1}:(function(e){let t=eU(e);if(!t.hasLock||t.hasInfo)return;let a=eC(e.lockPath);if(!a)return eO(e.lockPath);V(a.pid,a.processStartTime)||eO(e.lockPath)}(e.paths),await eb(e))}async function eA(e){let t={transport:"http",token:e.remoteAuthToken??"",pid:0,baseUrl:e.remoteBaseUrl};if(await ex(t,"http"))return{info:t,startedByClient:!1};throw new u("COMMAND_FAILED","Remote daemon is unavailable",{daemonBaseUrl:e.remoteBaseUrl,hint:"Verify AGENT_DEVICE_DAEMON_BASE_URL points to a reachable daemon with GET /health and POST /rpc."})}async function ek(e){var t,a;let r,o=eM(e.paths.infoPath);if(!o)return null;let n=await ex(o,e.transportPreference);return(t=o,a=n,t.version===R()&&t.codeSignature===b((r=eq()).useSrc?r.srcPath:r.distPath,r.root)&&a)?o:(await eE(o),eO(e.paths.infoPath),null)}async function eb(e){let t,a=0,r=[];for(let o=1;o<=2;o+=1){try{await eF(e)}catch(a){if(t=a instanceof Error?a.message:String(a),r.push(await eL(e.paths,"start_error")),o<2){await J(150);continue}break}let n=await eS(15e3,e);if(n)return{info:n,startedByClient:!0};if(await eD(e.paths)){a+=1;continue}let i=eU(e.paths),s=o<2,l=await eL(e.paths,"startup_timeout",{stopLiveProcesses:!1});if(r.push(l),l.retainedInfoProcess||l.retainedLockProcess){let t=await eS(15e3,e);if(t)return{info:t,startedByClient:!0};break}if(!s)break;i.hasInfo||i.hasLock||await J(150)}let o=eU(e.paths);throw new u("COMMAND_FAILED","Failed to start daemon",{kind:"daemon_startup_failed",infoPath:e.paths.infoPath,lockPath:e.paths.lockPath,startupTimeoutMs:15e3,startupAttempts:2,lockRecoveryCount:a,cleanupResults:r,startError:t,metadataState:o,hint:function(e,t=F(process.env.AGENT_DEVICE_STATE_DIR)){return e.hasLock&&!e.hasInfo?`agent-device attempted to clean stale daemon metadata automatically, but ${t.lockPath} still exists without ${t.infoPath}. Retry with --debug; if this persists, remove ${t.lockPath} after confirming no agent-device daemon process is running.`:e.hasLock&&e.hasInfo?`agent-device attempted to clean stale daemon metadata automatically, but ${t.infoPath} and ${t.lockPath} still remain. Retry with --debug; if this persists, remove both files after confirming no agent-device daemon process is running.`:"agent-device did not observe reachable daemon metadata after retrying. Stale metadata was cleaned automatically when safe; retry with --debug and check daemon diagnostics logs."}(o,e.paths)})}async function eP(e,t,a){if(!e_(e.command)||!t.startedByClient&&!a.ownedStateDir||eJ(t.info))return;let o={pid:t.info.pid,removedInfo:!1,removedLock:!1,removedStateDir:!1,error:void 0};try{await eE(t.info)}catch(e){o.error=e instanceof Error?e.message:String(e)}finally{let e=r.existsSync(a.paths.infoPath);eO(a.paths.infoPath),o.removedInfo=e&&!r.existsSync(a.paths.infoPath);let t=r.existsSync(a.paths.lockPath);eO(a.paths.lockPath),o.removedLock=t&&!r.existsSync(a.paths.lockPath),a.ownedStateDir&&(r.rmSync(a.paths.baseDir,{recursive:!0,force:!0}),o.removedStateDir=!r.existsSync(a.paths.baseDir))}G({level:o.error?"warn":"info",phase:"daemon_replay_cleanup",data:o})}function e_(e){return e===w.replay||e===w.test}async function eS(e,t){let a=Date.now();for(;Date.now()-a<e;){let e=eM(t.paths.infoPath);if(e&&await ex(e,t.transportPreference))return e;await J(100)}return null}async function eD(e){let t=eU(e);if(!t.hasLock||t.hasInfo)return!1;let a=eC(e.lockPath);return!(a&&V(a.pid,a.processStartTime))&&(eO(e.lockPath),!0)}async function eE(e){await W(e.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:e.processStartTime})}function eM(e){var t,a,r;let o,n,i=eR(e);if(!i||"object"!=typeof i)return null;let s="string"==typeof(t=i).token&&t.token.length>0?t.token:null;if(!s)return null;let l=(o=eN((a=i).port),n=eN(a.httpPort),void 0===o&&void 0===n?null:{port:o,httpPort:n});return l?{token:s,...l,transport:"socket"===(r=i.transport)||"http"===r||"dual"===r?r:void 0,pid:eN(i.pid)??0,version:eT(i.version),codeSignature:eT(i.codeSignature),processStartTime:eT(i.processStartTime)}:null}function eT(e){return"string"==typeof e?e:void 0}function eN(e){return Number.isInteger(e)&&Number(e)>0?Number(e):void 0}function eC(e){let t=eR(e);return t&&"object"==typeof t&&Number.isInteger(t.pid)&&Number(t.pid)>0?{pid:Number(t.pid),processStartTime:"string"==typeof t.processStartTime?t.processStartTime:void 0,startedAt:"number"==typeof t.startedAt?t.startedAt:void 0}:null}ep.addSubnet("127.0.0.0",8,"ipv4"),ep.addAddress("::1","ipv6"),ep.addSubnet("::ffff:127.0.0.0",104,"ipv6");async function eL(e,t,a={}){let o=a.stopLiveProcesses??!0,n={reason:t,removedInfo:!1,removedLock:!1,stoppedInfoProcess:!1,stoppedLockProcess:!1};try{var i,s,l,c;let t=r.existsSync(e.infoPath),a=eM(e.infoPath);if(a){let t=V(a.pid,a.processStartTime);t&&!o?n.retainedInfoProcess=!0:(t&&(await eE(a),n.stoppedInfoProcess=!0),i=e.infoPath,eO(i),n.removedInfo=!0)}else t&&(s=e.infoPath,eO(s),n.removedInfo=!0);let d=r.existsSync(e.lockPath),u=eC(e.lockPath);if(u){let t=V(u.pid,u.processStartTime);t&&!o?n.retainedLockProcess=!0:(t&&(await W(u.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:u.processStartTime}),n.stoppedLockProcess=!0),l=e.lockPath,eO(l),n.removedLock=!0)}else d&&(c=e.lockPath,eO(c),n.removedLock=!0)}catch(e){n.error=e instanceof Error?e.message:String(e)}return G({level:n.error?"warn":"info",phase:"daemon_startup_metadata_cleanup",data:n}),n}function eU(e){return{hasInfo:r.existsSync(e.infoPath),hasLock:r.existsSync(e.lockPath)}}function eR(e){if(!r.existsSync(e))return null;try{return JSON.parse(r.readFileSync(e,"utf8"))}catch{return null}}function eO(e){try{r.existsSync(e)&&r.unlinkSync(e)}catch{}}async function ex(r,o){var n;return"http"===e$(r,o)?await function(e){let r=e.baseUrl?eY(e.baseUrl,"health"):e.httpPort?`http://127.0.0.1:${e.httpPort}/health`:null;if(!r)return Promise.resolve(!1);let o=new URL(r),n="https:"===o.protocol?a:t,i=e.baseUrl?3e3:500;return new Promise(e=>{let t=n.request({protocol:o.protocol,host:o.hostname,port:o.port,path:o.pathname+o.search,method:"GET",timeout:i},t=>{t.resume(),e((t.statusCode??500)<500)});t.on("timeout",()=>{t.destroy(),e(!1)}),t.on("error",()=>{e(!1)}),t.end()})}(r):await ((n=r.port)?new Promise(t=>{let a=!1,r=e.createConnection({host:"127.0.0.1",port:n},()=>{o(!0)}),o=e=>{a||(a=!0,r.destroy(),t(e))};r.setTimeout(500),r.on("timeout",()=>{o(!1)}),r.on("error",()=>{o(!1)})}):Promise.resolve(!1))}async function eF(e){let t=eq(),a=t.useSrc?["--experimental-strip-types",t.srcPath]:[t.distPath],r={...process.env,AGENT_DEVICE_STATE_DIR:e.paths.baseDir,AGENT_DEVICE_DAEMON_SERVER_MODE:e.serverMode};f(process.execPath,a,{env:r})}function eq(){let e=O(),t=[n.join(e,"dist","src","internal","daemon.js"),n.join(e,"dist","src","daemon.js")],a=t[0];if(void 0===a)throw new u("COMMAND_FAILED","Daemon dist path list is empty");let o=t.find(e=>r.existsSync(e))??a,i=n.join(e,"src","daemon.ts"),s=t.some(e=>r.existsSync(e)),l=r.existsSync(i);if(!s&&!l)throw new u("COMMAND_FAILED","Daemon entry not found",{distPaths:t,srcPath:i});return{root:e,distPath:o,distPaths:t,srcPath:i,useSrc:process.execArgv.includes("--experimental-strip-types")?l:!s&&l}}async function eB(e,t,a,r){return"http"===e$(e,a)?await eG(e,t,r):await ez(e,t,r)}function e$(e,t){if(e.baseUrl){if("socket"===t)throw new u("COMMAND_FAILED","Remote daemon endpoint only supports HTTP transport",{daemonBaseUrl:e.baseUrl});return"http"}if("http"===t||"socket"===t){var a=e,r=t;if(ej(a,r))return r;throw new u("COMMAND_FAILED","http"===r?"Daemon HTTP endpoint is unavailable":"Daemon socket endpoint is unavailable")}let o=("socket"===e.transport||"dual"===e.transport?["socket","http"]:["http","socket"]).find(t=>ej(e,t));if(o)return o;throw new u("COMMAND_FAILED","Daemon metadata has no reachable transport")}function ej(e,t){return"http"===t?!!e.httpPort:!!e.port}function eH(e,t,a,r,o,n){let i=o?{terminated:0}:function(){let e=0;try{for(let t of eu){let a=p("pkill",["-f",t],{allowFailure:!0});0===a.exitCode&&(e+=1)}return{terminated:e}}catch(t){return{terminated:e,error:t instanceof Error?t.message:String(t)}}}(),s=!o&&"snapshot"!==r,l=s?function(e,t){let a=!1;try{V(e.pid,e.processStartTime)&&(process.kill(e.pid,"SIGKILL"),a=!0)}catch{W(e.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:e.processStartTime})}finally{eO(t.infoPath),eO(t.lockPath)}return{forcedKill:a}}(e,t):{forcedKill:!1};return G({level:"error",phase:"daemon_request_timeout",data:{timeoutMs:n,requestId:a,command:r,timedOutRunnerPidsTerminated:i.terminated,timedOutRunnerCleanupError:i.error,daemonPidReset:s?e.pid:void 0,daemonPidForceKilled:s?l.forcedKill:void 0,daemonPreservedAfterTimeout:!o&&!s,daemonBaseUrl:e.baseUrl}}),new u("COMMAND_FAILED","Daemon request timed out",{timeoutMs:n,requestId:a,hint:function(e){let{remote:t,resetDaemon:a,command:r}=e;return t?"Retry with --debug and verify the remote daemon URL, auth token, and remote host logs.":a?"Retry with --debug and check daemon diagnostics logs. Timed-out iOS runner xcodebuild processes were terminated when detected.":`Retry with --debug and check daemon diagnostics logs. The timed-out ${r??"request"} request was canceled and iOS runner work was aborted when detected; the daemon was kept alive so the session can still be closed or inspected.`}({remote:o,resetDaemon:s,command:r})})}function eK(e,t,a){return G({level:"error",phase:"daemon_request_socket_error",data:{requestId:t,message:e instanceof Error?e.message:String(e)}}),new u("COMMAND_FAILED","Failed to communicate with daemon",{requestId:t,hint:a?"Retry command. If this persists, verify the remote daemon URL, auth token, and remote host reachability.":"Retry command. If this persists, clean stale daemon metadata and start a fresh session."},e instanceof Error?e:void 0)}async function ez(t,a,r){let o=t.port;if(!o)throw new u("COMMAND_FAILED","Daemon socket endpoint is unavailable");return new Promise((n,i)=>{let s=e.createConnection({host:"127.0.0.1",port:o},()=>{s.write(`${JSON.stringify(a)}
3
- `)}),l=F(a.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR),c=!1,d="number"==typeof r?setTimeout(()=>{c=!0,s.destroy(),i(eH(t,l,a.meta?.requestId,a.command,!1,r))},r):void 0,p="";s.setEncoding("utf8"),s.on("data",e=>{if(c)return;let t=y(p,e);for(let e of(p=t.buffer,t.lines))try{let t=JSON.parse(e);if(g(t)){ed(t.event);continue}let a=I(t)?t.response:t;c=!0,s.end(),d&&clearTimeout(d),n(a);return}catch(t){c=!0,d&&clearTimeout(d),i(new u("COMMAND_FAILED","Invalid daemon response",{requestId:a.meta?.requestId,line:e},t instanceof Error?t:void 0));return}}),s.on("error",e=>{c||(c=!0,d&&clearTimeout(d),i(eK(e,a.meta?.requestId,!1)))})})}async function eG(e,r,o){var n,i,s;let l,c=e.baseUrl?new URL(eY(e.baseUrl,"rpc")):e.httpPort?new URL(`http://127.0.0.1:${e.httpPort}/rpc`):null;if(!c)throw new u("COMMAND_FAILED","Daemon HTTP endpoint is unavailable");let d=JSON.stringify((n=r,i={includeTokenParam:!e.baseUrl},l=n.meta?.requestId??K(),"lease_allocate"!==(s=n.command)&&"lease_heartbeat"!==s&&"lease_release"!==s?{jsonrpc:"2.0",id:l,method:"agent_device.command",params:n}:{jsonrpc:"2.0",id:l,method:function(e){switch(e){case"lease_allocate":return"agent_device.lease.allocate";case"lease_heartbeat":return"agent_device.lease.heartbeat";case"lease_release":return"agent_device.lease.release"}}(n.command),params:function(e,t,a){let r={...a.includeTokenParam?{token:e.token}:{},session:e.session,tenantId:e.meta?.tenantId,runId:e.meta?.runId};switch(t){case"lease_allocate":return{...r,ttlMs:e.meta?.leaseTtlMs,backend:e.meta?.leaseBackend};case"lease_heartbeat":return{...r,leaseId:e.meta?.leaseId,ttlMs:e.meta?.leaseTtlMs};case"lease_release":return{...r,leaseId:e.meta?.leaseId}}}(n,n.command,i)})),p={"content-type":"application/json","content-length":Buffer.byteLength(d)};return e.baseUrl&&e.token&&(p.authorization=`Bearer ${e.token}`,p["x-agent-device-token"]=e.token),await new Promise((n,i)=>{let s=F(r.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR),l=("https:"===c.protocol?a:t).request({protocol:c.protocol,host:c.hostname,port:c.port,method:"POST",path:c.pathname+c.search,headers:p},t=>{var a;(a=t.headers?.["content-type"],N(r)&&String(Array.isArray(a)?a.join(","):a??"").includes("application/x-ndjson"))?function(e,t){let{req:a,handleResponseBody:r,reject:o,clearTimeout:n}=t,i="",s=!1,l=e=>{try{let t=JSON.parse(e);if(g(t))return ed(t.event),!1;if(I(t))return s=!0,n(),r(JSON.stringify(t.response)),!0;throw Error("Missing daemon progress response envelope")}catch(t){return s=!0,n(),o(new u("COMMAND_FAILED","Invalid daemon response",{requestId:a.meta?.requestId,line:e},t instanceof Error?t:void 0)),!0}};e.setEncoding("utf8"),e.on("data",e=>{if(s)return;let t=y(i,e);for(let e of(i=t.buffer,t.lines))if(e&&l(e))return}),e.on("end",()=>{if(s)return;let e=i.trim();e&&l(e)||(s=!0,n(),o(new u("COMMAND_FAILED","Invalid daemon response",{requestId:a.meta?.requestId,line:e})))}),e.on("error",e=>{s||(s=!0,n(),o(new u("COMMAND_FAILED","Failed to read daemon response",{requestId:a.meta?.requestId},e instanceof Error?e:void 0)))})}(t,{req:r,reject:i,clearTimeout:()=>{f&&clearTimeout(f)},handleResponseBody:t=>eV(t,{info:e,req:r,resolve:n,reject:i})}):X(t).then(t=>{f&&clearTimeout(f),eV(t,{info:e,req:r,resolve:n,reject:i})}).catch(e=>{f&&clearTimeout(f),i(new u("COMMAND_FAILED","Failed to read daemon response",{requestId:r.meta?.requestId},e instanceof Error?e:void 0))})}),m=eJ(e),f="number"==typeof o?setTimeout(()=>{l.destroy(),i(eH(e,s,r.meta?.requestId,r.command,m,o))},o):void 0;l.on("error",e=>{f&&clearTimeout(f),i(eK(e,r.meta?.requestId,m))}),l.write(d),l.end()})}function eV(e,t){let{info:a,req:r,resolve:o,reject:n}=t;try{var i,s,l;let t=(i=e,JSON.parse(i));if(t.error){let e;return void n((s=t.error,l=r.meta?.requestId,e=s.data??{},new u(d(null!=e.code?String(e.code):void 0,"COMMAND_FAILED"),String(e.message??s.message??"Daemon RPC request failed"),{..."object"==typeof e.details&&e.details?e.details:{},hint:"string"==typeof e.hint?e.hint:void 0,diagnosticId:"string"==typeof e.diagnosticId?e.diagnosticId:void 0,logPath:"string"==typeof e.logPath?e.logPath:void 0,requestId:l})))}if(!t.result||"object"!=typeof t.result)return void n(new u("COMMAND_FAILED","Invalid daemon RPC response",{requestId:r.meta?.requestId}));eW(a,r,t.result,o,n)}catch(t){n(new u("COMMAND_FAILED","Invalid daemon response",{requestId:r.meta?.requestId,line:e},t instanceof Error?t:void 0))}}async function eW(e,t,a,r,o){try{r(e.baseUrl&&a.ok?await eQ(e,t,a):a)}catch(e){o(e)}}function eJ(e){return"string"==typeof e.baseUrl&&e.baseUrl.length>0}function eY(e,t){return new URL(t,e.endsWith("/")?e:`${e}/`).toString()}async function eQ(e,t,a){let r=Array.isArray(a.data?.artifacts)?a.data.artifacts:[];if(0===r.length||!e.baseUrl)return a;let o=a.data?{...a.data}:{},i=[];for(let a of r){if(!a||"object"!=typeof a||"string"!=typeof a.artifactId){i.push(a);continue}let r=function(e,t){if(e.localPath&&e.localPath.trim().length>0)return e.localPath;let a=t.meta?.clientArtifactPaths?.[e.field];if(a&&a.trim().length>0)return a;let r=e.fileName?.trim()||`${e.field}-${Date.now()}`;return n.resolve(t.meta?.cwd??process.cwd(),r)}(a,t);await eX({baseUrl:e.baseUrl,token:e.token,artifactId:a.artifactId,destinationPath:r,requestId:t.meta?.requestId}),o[a.field]=r,i.push({...a,localPath:r})}return o.artifacts=i,{ok:!0,data:o}}async function eX(e){var o,s;let l,c=new URL((o=e.baseUrl,s=e.artifactId,l=o.endsWith("/")?o:`${o}/`,new URL(`artifacts/${encodeURIComponent(s)}`,l).toString())),d="https:"===c.protocol?a:t;await r.promises.mkdir(n.dirname(e.destinationPath),{recursive:!0}),await new Promise((t,a)=>{let o=!1,n=e.timeoutMs??9e4,s=n=>{if(!o){if(o=!0,clearTimeout(p),n)return void r.promises.rm(e.destinationPath,{force:!0}).finally(()=>a(n));t()}},l=d.request({protocol:c.protocol,host:c.hostname,port:c.port,method:"GET",path:c.pathname+c.search,headers:e.token?{authorization:`Bearer ${e.token}`,"x-agent-device-token":e.token}:void 0},t=>{if((t.statusCode??500)>=400){let a="";t.setEncoding("utf8"),t.on("data",e=>{a+=e}),t.on("end",()=>{s(new u("COMMAND_FAILED","Failed to download remote artifact",{artifactId:e.artifactId,statusCode:t.statusCode,requestId:e.requestId,body:a}))});return}t.on("aborted",()=>{s(new u("COMMAND_FAILED","Remote artifact download was interrupted",{artifactId:e.artifactId,requestId:e.requestId}))}),i(t,r.createWriteStream(e.destinationPath)).then(()=>s(),e=>s(e instanceof Error?e:Error(String(e))))}),p=setTimeout(()=>{let t=new u("COMMAND_FAILED","Remote artifact download timed out",{artifactId:e.artifactId,requestId:e.requestId,timeoutMs:n});s(t),l.destroy(t)},n);l.on("error",t=>{t instanceof u?s(t):s(new u("COMMAND_FAILED","Failed to download remote artifact",{artifactId:e.artifactId,requestId:e.requestId,timeoutMs:n},t instanceof Error?t:void 0))}),l.end()})}function eZ(e={},t={}){let a=t.transport??em,r=async(t,r=[],o={})=>{var n,i;let s=(n=e,i=o,{...n,...i}),l=await a({session:M(s.session),command:t,positionals:r,flags:D(s),runtime:s.runtime,meta:S(s)});return l.ok||function(e){throw new u(d(e.code),e.message,{...e.details??{},hint:e.hint,diagnosticId:e.diagnosticId,logPath:e.logPath})}(l.error),l.data??{}},o=async(e={})=>{let t=await r(C.sessionList,[],e);return(Array.isArray(t.sessions)?t.sessions:[]).map(h)},n=async(e,t={})=>{let a=v(e,t);return await r(a.command,a.positionals,a.options)},i=(t={})=>{var a,r;return M((a=e,r=t,{...a,...r}).session)};return{command:{wait:async e=>await n("wait",e),alert:async(e={})=>await n("alert",e),appState:async(e={})=>await n("appstate",e),back:async(e={})=>await n("back",e),home:async(e={})=>await n("home",e),rotate:async e=>await n("rotate",e),appSwitcher:async(e={})=>await n("app-switcher",e),keyboard:async(e={})=>await n("keyboard",e),clipboard:async e=>await n("clipboard",e),reactNative:async e=>await n("react-native",e)},devices:{list:async(e={})=>{let t=await n("devices",e);return(Array.isArray(t.devices)?t.devices:[]).map(L)},boot:async(e={})=>await n("boot",e)},sessions:{list:async(e={})=>await o(e),close:async(e={})=>{let t=i(e),a=(await n("close",e)).shutdown;return{session:t,shutdown:"object"==typeof a&&null!==a?a:void 0,identifiers:{session:t}}}},apps:{install:async e=>_(await n("install",e),i(e)),reinstall:async e=>_(await n("reinstall",e),i(e)),installFromSource:async e=>H(await n("install-from-source",e),i(e)),list:async(e={})=>{let t=await n("apps",e);return Array.isArray(t.apps)?t.apps.filter(e=>"string"==typeof e):[]},open:async e=>{let t=i(e),a=await n("open",e),r=x(a),o=E(a,"appBundleId");return{session:t,appName:E(a,"appName"),appBundleId:o,appId:o,startup:$(a.startup),runtime:B(a.runtime),device:r,identifiers:{session:t,deviceId:r?.id,deviceName:r?.name,udid:r?.ios?.udid,serial:r?.android?.serial,appId:o,appBundleId:o}}},close:async(e={})=>{let t=i(e),a=(await n("close",e)).shutdown;return{session:t,closedApp:e.app,shutdown:"object"==typeof a&&null!==a?a:void 0,identifiers:{session:t}}},push:async e=>await n("push",e),triggerEvent:async e=>await n("trigger-app-event",e)},materializations:{release:async e=>k(await r(C.releaseMaterializedPaths,[],{...e,materializationId:e.materializationId}))},leases:{allocate:async e=>e1(await r(C.leaseAllocate,[],{...e,leaseId:void 0,leaseTtlMs:e.ttlMs})),heartbeat:async e=>e1(await r(C.leaseHeartbeat,[],{...e,leaseTtlMs:e.ttlMs})),release:async e=>({released:!0===(await r(C.leaseRelease,[],e)).released})},metro:{prepare:async t=>await Q({projectRoot:t.projectRoot??e.cwd,kind:t.kind,publicBaseUrl:t.publicBaseUrl,proxyBaseUrl:t.proxyBaseUrl,proxyBearerToken:t.bearerToken,bridgeScope:t.bridgeScope,launchUrl:t.launchUrl,companionProfileKey:t.companionProfileKey,companionConsumerKey:t.companionConsumerKey,metroPort:t.port,listenHost:t.listenHost,statusHost:t.statusHost,startupTimeoutMs:t.startupTimeoutMs,probeTimeoutMs:t.probeTimeoutMs,reuseExisting:t.reuseExisting,installDependenciesIfNeeded:t.installDependenciesIfNeeded,runtimeFilePath:t.runtimeFilePath,logPath:t.logPath}),reload:async(t={})=>await Y({metroHost:t.metroHost,metroPort:t.metroPort,bundleUrl:t.bundleUrl,runtime:e.runtime,timeoutMs:t.timeoutMs})},capture:{snapshot:async(e={})=>{var t,a,r;let o,s,l,c,d,u=i(e);return t=await n("snapshot",e),a=u,o=E(t,"appBundleId"),{nodes:A(t.nodes),truncated:!0===t.truncated,appName:E(t,"appName"),appBundleId:o,...(s=e0((r=t).visibility),l=e0(r.androidSnapshot),c=e0(r.unchanged),d=Array.isArray(r.warnings)?r.warnings.filter(e=>"string"==typeof e):void 0,{...s?{visibility:s}:{},...l?{androidSnapshot:l}:{},...c?{unchanged:c}:{},...d?{warnings:d}:{}}),identifiers:{session:a,appId:o,appBundleId:o}}},screenshot:async(e={})=>{let t=i(e),a=await n("screenshot",e);return{path:U(a,"path"),overlayRefs:j(a),identifiers:{session:t}}},diff:async e=>await n("diff",e)},interactions:{click:async e=>await n("click",e),press:async e=>await n("press",e),longPress:async e=>await n("longpress",e),swipe:async e=>await n("swipe",e),pan:async e=>await n("gesture-pan",e),fling:async e=>await n("gesture-fling",e),focus:async e=>await n("focus",e),type:async e=>await n("type",e),fill:async e=>await n("fill",e),scroll:async e=>await n("scroll",e),pinch:async e=>await n("gesture-pinch",e),rotateGesture:async e=>await n("gesture-rotate",e),transformGesture:async e=>await n("gesture-transform",e),get:async e=>await n("get",e),is:async e=>await n("is",e),find:async e=>await n("find",e)},replay:{run:async e=>await n("replay",e),test:async e=>await n("test",e)},batch:{run:async e=>await n("batch",e)},observability:{perf:async(e={})=>await n("perf",e),logs:async(e={})=>await n("logs",e),network:async(e={})=>await n("network",e)},recording:{record:async e=>await n("record",e),trace:async e=>await n("trace",e)},settings:{update:async e=>await n("settings",e)}}}function e0(e){return"object"==typeof e&&null!==e?e:void 0}function e1(e){let t=e.lease;if(!t||"object"!=typeof t||Array.isArray(t))throw Error("Invalid lease response from daemon");return{leaseId:U(t,"leaseId"),tenantId:U(t,"tenantId"),runId:U(t,"runId"),backend:U(t,"backend"),createdAt:"number"==typeof t.createdAt?t.createdAt:void 0,heartbeatAt:"number"==typeof t.heartbeatAt?t.heartbeatAt:void 0,expiresAt:"number"==typeof t.expiresAt?t.expiresAt:void 0}}export{eZ as createAgentDeviceClient,em as sendToDaemon};
1
+ import e from"node:net";import t from"node:http";import a from"node:https";import r from"node:fs";import o from"node:os";import n from"node:path";import{pipeline as i}from"node:stream/promises";import{createHash as s,randomUUID as l}from"node:crypto";import{Writable as c}from"node:stream";import{toAppErrorCode as d,AppError as u}from"./9152.js";import{runCmdSync as p,runCmd as m,runCmdDetached as f}from"./9818.js";import{formatRequestProgressEvent as h,consumeTextLines as y,shouldStreamRequestProgress as w,isDaemonResponseEnvelope as I,isDaemonProgressEnvelope as g,resolveDaemonPaths as v,resolveDaemonServerMode as A,computeDaemonCodeSignature as _,resolveDaemonTransportPreference as k}from"./8114.js";import{readVersion as P,findProjectRoot as S}from"./9671.js";import{createRequestId as b,withDiagnosticTimer as D,emitDiagnostic as E}from"./7599.js";import{isAgentDeviceDaemonProcess as M,stopProcessForTakeover as T}from"./8656.js";import{INTERNAL_COMMANDS as C,PUBLIC_COMMANDS as N}from"./5792.js";import{sleep as U}from"./4829.js";import{reloadMetro as L,prepareMetroRuntime as R}from"./1974.js";import{normalizeSession as O,resolveSessionName as x,buildFlags as F,normalizeStartupSample as q,normalizeInstallFromSourceResult as B,normalizeMaterializationReleaseResult as $,prepareDaemonCommandRequest as j,readSnapshotNodes as H,normalizeRuntimeHints as K,normalizeDeployResult as G,normalizeOpenDevice as z,readScreenshotOverlayRefs as V,buildMeta as W,normalizeDevice as J}from"./8699.js";import{readRequiredString as Y,readOptionalString as Q}from"./2805.js";function X(e){return new Promise((t,a)=>{let r="";e.setEncoding("utf8"),e.on("data",e=>{r+=e}),e.on("end",()=>t(r)),e.on("error",a)})}let Z="sha256";async function ee(e){let t=await et(e.localPath,e.platform),a=e.baseUrl.endsWith("/")?e.baseUrl:`${e.baseUrl}/`;try{let r=await en({normalizedBase:a,token:e.token,artifact:t});if(r?.kind==="cache-hit")return r.uploadId;if(r?.kind==="direct-upload")try{return await ei(t.payloadPath,r),await el({normalizedBase:a,token:e.token,uploadId:r.uploadId})}catch{}return await eo({normalizedBase:a,token:e.token,artifact:t})}finally{t.cleanup()}}async function et(e,t){var a,o,i;let s,l=r.statSync(e),c=n.basename(e),d=l.isDirectory(),u=("ios"===(a=t)||"android"===a?a:void 0)??(o=e,i=l,s=o.toLowerCase(),i.isDirectory()&&s.endsWith(".app")||s.endsWith(".ipa")?"ios":s.endsWith(".apk")||s.endsWith(".aab")?"android":void 0),p=[];try{let t=d?await ea(e,p):e,a=r.statSync(t);return{payloadPath:t,fileName:c,artifactType:d?"app-bundle":"file",platform:u,contentType:d?"application/gzip":"application/octet-stream",sha256:await ec(t),sizeBytes:a.size,cleanup:()=>er(p)}}catch(e){throw er(p),e}}async function ea(e,t){let a=r.mkdtempSync(n.join(o.tmpdir(),`agent-device-upload-${l()}-`));t.push(a);let i=n.join(a,`${n.basename(e)}.tar.gz`);return await m("tar",["czf",i,"-C",n.dirname(e),n.basename(e)],{env:{...process.env,COPYFILE_DISABLE:"1"}}),i}function er(e){for(let t of e)r.rmSync(t,{recursive:!0,force:!0})}async function eo(e){let{normalizedBase:t,token:a,artifact:r}=e,o=new URL("upload",t),n={"content-type":r.contentType,"x-artifact-type":r.artifactType,"x-artifact-filename":r.fileName,"x-artifact-hash":r.sha256,"x-artifact-hash-algorithm":Z,"transfer-encoding":"chunked"};a&&(n.authorization=`Bearer ${a}`,n["x-agent-device-token"]=a);let i=await es({url:o,method:"POST",headers:n,payloadPath:r.payloadPath,timeoutMessage:"Artifact upload timed out",timeoutHint:"The upload to the remote daemon exceeded the 5-minute timeout.",errorMessage:"Failed to upload artifact to remote daemon",errorHint:"Verify the remote daemon is reachable and supports artifact uploads."});try{let e=JSON.parse(i.body);if(!e.ok||!e.uploadId)throw new u("COMMAND_FAILED",`Upload failed: ${i.body}`);return e.uploadId}catch(e){if(e instanceof u)throw e;throw new u("COMMAND_FAILED",`Invalid upload response: ${i.body}`)}}async function en(e){let t=new URL("upload/preflight",e.normalizedBase),a={"content-type":"application/json"};e.token&&(a.authorization=`Bearer ${e.token}`,a["x-agent-device-token"]=e.token);let r=await fetch(t,{method:"POST",headers:a,signal:AbortSignal.timeout(3e4),body:JSON.stringify({sha256:e.artifact.sha256,fileName:e.artifact.fileName,sizeBytes:e.artifact.sizeBytes,artifactType:e.artifact.artifactType,...e.artifact.platform?{platform:e.artifact.platform}:{},contentType:e.artifact.contentType})}).catch(()=>void 0);if(r?.ok)return function(e){var t;if(!e||"object"!=typeof e||!0!==e.ok||"string"!=typeof e.uploadId)return;if(!0===e.cacheHit)return{kind:"cache-hit",uploadId:e.uploadId};let a=e.upload;if(!a||"string"!=typeof a.url)return;let r=a.headers??{};if(!(!(t=r)||"object"!=typeof t||Array.isArray(t))&&Object.values(t).every(e=>"string"==typeof e))return{kind:"direct-upload",uploadId:e.uploadId,url:a.url,headers:r}}(await r.json().catch(()=>void 0))}async function ei(e,t){let a=await es({url:new URL(t.url),method:"PUT",headers:t.headers,payloadPath:e,timeoutMessage:"Direct artifact upload timed out",timeoutHint:"The direct upload ticket did not accept the artifact within the timeout.",errorMessage:"Failed to upload artifact with direct upload ticket"});if(a.statusCode<200||a.statusCode>=300)throw new u("COMMAND_FAILED","Direct artifact upload failed",{statusCode:a.statusCode,statusMessage:a.statusMessage})}async function es(e){let o="https:"===e.url.protocol?a:t;return await new Promise((t,a)=>{let n=o.request({protocol:e.url.protocol,host:e.url.hostname,port:e.url.port,method:e.method,path:e.url.pathname+e.url.search,headers:e.headers},e=>{X(e).then(a=>{clearTimeout(s),t({statusCode:e.statusCode??500,statusMessage:e.statusMessage,body:a})}).catch(a)}),s=setTimeout(()=>{n.destroy(),a(new u("COMMAND_FAILED",e.timeoutMessage,{timeoutMs:3e5,...e.timeoutHint?{hint:e.timeoutHint}:{}}))},3e5);n.on("error",t=>{clearTimeout(s),a(new u("COMMAND_FAILED",e.errorMessage,e.errorHint?{hint:e.errorHint}:{},t))}),n.on("close",()=>clearTimeout(s)),i(r.createReadStream(e.payloadPath),n).catch(e=>{n.destroy(),a(new u("COMMAND_FAILED","Failed to read local artifact",{},e instanceof Error?e:Error(String(e))))})})}async function el(e){let t=new URL("upload/finalize",e.normalizedBase),a={"content-type":"application/json"};e.token&&(a.authorization=`Bearer ${e.token}`,a["x-agent-device-token"]=e.token);let r=await fetch(t,{method:"POST",headers:a,signal:AbortSignal.timeout(3e4),body:JSON.stringify({uploadId:e.uploadId})}).catch(e=>{throw new u("COMMAND_FAILED","Failed to finalize direct artifact upload",{},e)});if(!r.ok)throw new u("COMMAND_FAILED","Direct artifact upload finalize failed",{status:r.status,statusText:r.statusText});let o=await r.json().catch(()=>void 0);if(!o?.ok||!o.uploadId)throw new u("COMMAND_FAILED","Invalid upload finalize response");return o.uploadId}async function ec(e){let t=s(Z),a=new c({write(e,a,r){t.update(e),r()}});return await i(r.createReadStream(e),a).catch(e=>{throw new u("COMMAND_FAILED","Failed to read local artifact",{},e instanceof Error?e:void 0)}),t.digest("hex")}function ed(e){let t=h(e);t&&process.stderr.write(`${t}
2
+ `)}let eu=["xcodebuild .*AgentDeviceRunnerUITests/RunnerTests/testCommand","xcodebuild .*AgentDeviceRunner\\.env\\.session-","xcodebuild build-for-testing .*ios-runner/AgentDeviceRunner/AgentDeviceRunner\\.xcodeproj"],ep=new e.BlockList;async function em(t){var a,i,s,l,c,d;let p,m,f,h,y,w,I,g=t.meta?.requestId??b(),_=!!(t.meta?.debug||t.flags?.verbose),P=(h=(i=a=t,i.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR),y=(s=a,m=function(e){let t;if(e){try{t=new URL(e)}catch(t){throw new u("INVALID_ARGS","Invalid daemon base URL",{daemonBaseUrl:e},t instanceof Error?t:void 0)}if("http:"!==t.protocol&&"https:"!==t.protocol)throw new u("INVALID_ARGS","Daemon base URL must use http or https",{daemonBaseUrl:e});return t.toString().replace(/\/+$/,"")}}(p=s.flags?.daemonBaseUrl??process.env.AGENT_DEVICE_DAEMON_BASE_URL),function(t,a){let r;if(!(!t||"localhost"===(r=new URL(t).hostname.trim().toLowerCase().replace(/^\[(.*)\]$/,"$1"))||(e.isIPv4(r)?ep.check(r,"ipv4"):!!e.isIPv6(r)&&ep.check(r,"ipv6")))&&("string"!=typeof a||!(a.trim().length>0)))throw new u("INVALID_ARGS","Remote daemon base URL for non-loopback hosts requires daemon authentication",{daemonBaseUrl:t,hint:"Provide --daemon-auth-token or AGENT_DEVICE_DAEMON_AUTH_TOKEN when using a non-loopback remote daemon URL."})}(m,f=s.flags?.daemonAuthToken??process.env.AGENT_DEVICE_DAEMON_AUTH_TOKEN),{rawBaseUrl:p,remoteBaseUrl:m,authToken:f}),w=function(e,t){let a=e.flags?.daemonTransport??process.env.AGENT_DEVICE_DAEMON_TRANSPORT,r=k(a);if(t&&"socket"===r)throw new u("INVALID_ARGS","Remote daemon base URL only supports HTTP transport. Remove --daemon-transport socket.",{daemonBaseUrl:t});return{preference:r,serverMode:A(e.flags?.daemonServerMode??process.env.AGENT_DEVICE_DAEMON_SERVER_MODE??("dual"===a?"dual":void 0))}}(a,y.remoteBaseUrl),{paths:v((I=(l=a,c=h,d=y.rawBaseUrl,eS(l.command)&&!c&&!d))?r.mkdtempSync(n.join(o.tmpdir(),"agent-device-replay-daemon-")):h),transportPreference:w.preference,serverMode:w.serverMode,ownedStateDir:I,remoteBaseUrl:y.remoteBaseUrl,remoteAuthToken:y.authToken}),S=function(e){if(e.command!==N.test)return e.command===N.replay&&"number"==typeof e.flags?.timeoutMs?e.flags.timeoutMs:9e4}(t),M=await D("daemon_startup",async()=>await ev(P),{requestId:g,session:t.session}),T=M.info,C=await ef(t,T),U={...t,positionals:C.positionals,flags:C.flags,token:T.token,meta:{...t.meta??{},requestId:g,debug:_,cwd:t.meta?.cwd,tenantId:t.meta?.tenantId??t.flags?.tenant,runId:t.meta?.runId??t.flags?.runId,leaseId:t.meta?.leaseId??t.flags?.leaseId,sessionIsolation:t.meta?.sessionIsolation??t.flags?.sessionIsolation,lockPolicy:t.meta?.lockPolicy,lockPlatform:t.meta?.lockPlatform,...C.uploadedArtifactId?{uploadedArtifactId:C.uploadedArtifactId}:{},...C.clientArtifactPaths?{clientArtifactPaths:C.clientArtifactPaths}:{},...C.installSource?{installSource:C.installSource}:{}}};E({level:"info",phase:"daemon_request_prepare",data:{requestId:g,command:t.command,session:t.session}});try{return await D("daemon_request",async()=>await eB(T,U,P.transportPreference,S),{requestId:g,command:t.command})}finally{await eP(t,M,P)}}async function ef(e,t){let a,r=[...e.positionals??[]],o=e.flags?{...e.flags}:void 0,i=e.meta?.installSource,s={};if(!eJ(t))return ey({positionals:r,flags:o,installSource:i,uploadedArtifactId:a,clientArtifactPaths:s});o=function(e,t,a,r){var o,i;let s=function(e,t){if("screenshot"===e.command){let a=eI(e,"path",".png");return t[0]?{field:"path",localPath:a,positionalIndex:0,positionalPath:eg("screenshot",".png")}:{field:"path",localPath:a,positionalIndex:0,flagPath:eg("screenshot",".png")}}if("record"===e.command&&"start"===(t[0]??"").toLowerCase()){let t=eI(e,"outPath",".mp4",1);return{field:"outPath",localPath:t,positionalIndex:1,positionalPath:eg("recording",n.extname(t)||".mp4")}}return null}(e,t);if(!s)return a;void 0!==s.positionalPath&&(t[s.positionalIndex]=s.positionalPath);let l=(o=a,void 0===(i=s.flagPath)?o:{...o??{},out:i});return r[s.field]=s.localPath,l}(e,r,o,s);let l=await ew(e,t);l&&(i=l.installSource,a=l.uploadedArtifactId??a);let c=()=>ey({positionals:r,flags:o,installSource:i,uploadedArtifactId:a,clientArtifactPaths:s});return"install"!==e.command&&"reinstall"!==e.command||(a=await eh(e,t,r)??a),c()}async function eh(e,t,a){var o,i;let s,l=a[1];if(void 0===l)return;if(l.startsWith("remote:")){a[1]=l.slice(7);return}let c=(o=l,i=e.meta?.cwd,s=n.isAbsolute(o)?o:n.resolve(i??process.cwd(),o),r.existsSync(s)?s:void 0);if(c)return await ee({localPath:c,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform})}function ey(e){return{positionals:e.positionals,flags:e.flags,installSource:e.installSource,uploadedArtifactId:e.uploadedArtifactId,...Object.keys(e.clientArtifactPaths).length>0?{clientArtifactPaths:e.clientArtifactPaths}:{}}}async function ew(e,t){let a=e.meta?.installSource;if("install_source"!==e.command||!a||"path"!==a.kind)return null;let o=a.path.trim();if(!o)return{installSource:a};if(o.startsWith("remote:"))return{installSource:{...a,path:o.slice(7)}};let i=n.isAbsolute(o)?o:n.resolve(e.meta?.cwd??process.cwd(),o);if(!r.existsSync(i))return{installSource:{...a,path:i}};let s=await ee({localPath:i,baseUrl:t.baseUrl,token:t.token,platform:e.flags?.platform});return{installSource:{...a,path:i},uploadedArtifactId:s}}function eI(e,t,a,r=0){let o=e.positionals?.[r]??e.flags?.out,i=`${"path"===t?"screenshot":"recording"}-${Date.now()}${a}`,s=o&&o.trim().length>0?o:i;return n.isAbsolute(s)?s:n.resolve(e.meta?.cwd??process.cwd(),s)}function eg(e,t){let a=t.startsWith(".")?t:`.${t}`;return n.posix.join("/tmp",`agent-device-${e}-${Date.now()}-${Math.random().toString(36).slice(2,8)}${a}`)}async function ev(e){if(e.remoteBaseUrl)return await eA(e);let t=await e_(e);return t?{info:t,startedByClient:!1}:(function(e){let t=eL(e);if(!t.hasLock||t.hasInfo)return;let a=eN(e.lockPath);if(!a)return eO(e.lockPath);M(a.pid,a.processStartTime)||eO(e.lockPath)}(e.paths),await ek(e))}async function eA(e){let t={transport:"http",token:e.remoteAuthToken??"",pid:0,baseUrl:e.remoteBaseUrl};if(await ex(t,"http"))return{info:t,startedByClient:!1};throw new u("COMMAND_FAILED","Remote daemon is unavailable",{daemonBaseUrl:e.remoteBaseUrl,hint:"Verify AGENT_DEVICE_DAEMON_BASE_URL points to a reachable daemon with GET /health and POST /rpc."})}async function e_(e){var t,a;let r,o=eM(e.paths.infoPath);if(!o)return null;let n=await ex(o,e.transportPreference);return(t=o,a=n,t.version===P()&&t.codeSignature===_((r=eq()).useSrc?r.srcPath:r.distPath,r.root)&&a)?o:(await eE(o),eO(e.paths.infoPath),null)}async function ek(e){let t,a=0,r=[];for(let o=1;o<=2;o+=1){try{await eF(e)}catch(a){if(t=a instanceof Error?a.message:String(a),r.push(await eU(e.paths,"start_error")),o<2){await U(150);continue}break}let n=await eb(15e3,e);if(n)return{info:n,startedByClient:!0};if(await eD(e.paths)){a+=1;continue}let i=eL(e.paths),s=o<2,l=await eU(e.paths,"startup_timeout",{stopLiveProcesses:!1});if(r.push(l),l.retainedInfoProcess||l.retainedLockProcess){let t=await eb(15e3,e);if(t)return{info:t,startedByClient:!0};break}if(!s)break;i.hasInfo||i.hasLock||await U(150)}let o=eL(e.paths);throw new u("COMMAND_FAILED","Failed to start daemon",{kind:"daemon_startup_failed",infoPath:e.paths.infoPath,lockPath:e.paths.lockPath,startupTimeoutMs:15e3,startupAttempts:2,lockRecoveryCount:a,cleanupResults:r,startError:t,metadataState:o,hint:function(e,t=v(process.env.AGENT_DEVICE_STATE_DIR)){return e.hasLock&&!e.hasInfo?`agent-device attempted to clean stale daemon metadata automatically, but ${t.lockPath} still exists without ${t.infoPath}. Retry with --debug; if this persists, remove ${t.lockPath} after confirming no agent-device daemon process is running.`:e.hasLock&&e.hasInfo?`agent-device attempted to clean stale daemon metadata automatically, but ${t.infoPath} and ${t.lockPath} still remain. Retry with --debug; if this persists, remove both files after confirming no agent-device daemon process is running.`:"agent-device did not observe reachable daemon metadata after retrying. Stale metadata was cleaned automatically when safe; retry with --debug and check daemon diagnostics logs."}(o,e.paths)})}async function eP(e,t,a){if(!eS(e.command)||!t.startedByClient&&!a.ownedStateDir||eJ(t.info))return;let o={pid:t.info.pid,removedInfo:!1,removedLock:!1,removedStateDir:!1,error:void 0};try{await eE(t.info)}catch(e){o.error=e instanceof Error?e.message:String(e)}finally{let e=r.existsSync(a.paths.infoPath);eO(a.paths.infoPath),o.removedInfo=e&&!r.existsSync(a.paths.infoPath);let t=r.existsSync(a.paths.lockPath);eO(a.paths.lockPath),o.removedLock=t&&!r.existsSync(a.paths.lockPath),a.ownedStateDir&&(r.rmSync(a.paths.baseDir,{recursive:!0,force:!0}),o.removedStateDir=!r.existsSync(a.paths.baseDir))}E({level:o.error?"warn":"info",phase:"daemon_replay_cleanup",data:o})}function eS(e){return e===N.replay||e===N.test}async function eb(e,t){let a=Date.now();for(;Date.now()-a<e;){let e=eM(t.paths.infoPath);if(e&&await ex(e,t.transportPreference))return e;await U(100)}return null}async function eD(e){let t=eL(e);if(!t.hasLock||t.hasInfo)return!1;let a=eN(e.lockPath);return!(a&&M(a.pid,a.processStartTime))&&(eO(e.lockPath),!0)}async function eE(e){await T(e.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:e.processStartTime})}function eM(e){var t,a,r;let o,n,i=eR(e);if(!i||"object"!=typeof i)return null;let s="string"==typeof(t=i).token&&t.token.length>0?t.token:null;if(!s)return null;let l=(o=eC((a=i).port),n=eC(a.httpPort),void 0===o&&void 0===n?null:{port:o,httpPort:n});return l?{token:s,...l,transport:"socket"===(r=i.transport)||"http"===r||"dual"===r?r:void 0,pid:eC(i.pid)??0,version:eT(i.version),codeSignature:eT(i.codeSignature),processStartTime:eT(i.processStartTime)}:null}function eT(e){return"string"==typeof e?e:void 0}function eC(e){return Number.isInteger(e)&&Number(e)>0?Number(e):void 0}function eN(e){let t=eR(e);return t&&"object"==typeof t&&Number.isInteger(t.pid)&&Number(t.pid)>0?{pid:Number(t.pid),processStartTime:"string"==typeof t.processStartTime?t.processStartTime:void 0,startedAt:"number"==typeof t.startedAt?t.startedAt:void 0}:null}ep.addSubnet("127.0.0.0",8,"ipv4"),ep.addAddress("::1","ipv6"),ep.addSubnet("::ffff:127.0.0.0",104,"ipv6");async function eU(e,t,a={}){let o=a.stopLiveProcesses??!0,n={reason:t,removedInfo:!1,removedLock:!1,stoppedInfoProcess:!1,stoppedLockProcess:!1};try{var i,s,l,c;let t=r.existsSync(e.infoPath),a=eM(e.infoPath);if(a){let t=M(a.pid,a.processStartTime);t&&!o?n.retainedInfoProcess=!0:(t&&(await eE(a),n.stoppedInfoProcess=!0),i=e.infoPath,eO(i),n.removedInfo=!0)}else t&&(s=e.infoPath,eO(s),n.removedInfo=!0);let d=r.existsSync(e.lockPath),u=eN(e.lockPath);if(u){let t=M(u.pid,u.processStartTime);t&&!o?n.retainedLockProcess=!0:(t&&(await T(u.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:u.processStartTime}),n.stoppedLockProcess=!0),l=e.lockPath,eO(l),n.removedLock=!0)}else d&&(c=e.lockPath,eO(c),n.removedLock=!0)}catch(e){n.error=e instanceof Error?e.message:String(e)}return E({level:n.error?"warn":"info",phase:"daemon_startup_metadata_cleanup",data:n}),n}function eL(e){return{hasInfo:r.existsSync(e.infoPath),hasLock:r.existsSync(e.lockPath)}}function eR(e){if(!r.existsSync(e))return null;try{return JSON.parse(r.readFileSync(e,"utf8"))}catch{return null}}function eO(e){try{r.existsSync(e)&&r.unlinkSync(e)}catch{}}async function ex(r,o){var n;return"http"===e$(r,o)?await function(e){let r=e.baseUrl?eY(e.baseUrl,"health"):e.httpPort?`http://127.0.0.1:${e.httpPort}/health`:null;if(!r)return Promise.resolve(!1);let o=new URL(r),n="https:"===o.protocol?a:t,i=e.baseUrl?3e3:500;return new Promise(e=>{let t=n.request({protocol:o.protocol,host:o.hostname,port:o.port,path:o.pathname+o.search,method:"GET",timeout:i},t=>{t.resume(),e((t.statusCode??500)<500)});t.on("timeout",()=>{t.destroy(),e(!1)}),t.on("error",()=>{e(!1)}),t.end()})}(r):await ((n=r.port)?new Promise(t=>{let a=!1,r=e.createConnection({host:"127.0.0.1",port:n},()=>{o(!0)}),o=e=>{a||(a=!0,r.destroy(),t(e))};r.setTimeout(500),r.on("timeout",()=>{o(!1)}),r.on("error",()=>{o(!1)})}):Promise.resolve(!1))}async function eF(e){let t=eq(),a=t.useSrc?["--experimental-strip-types",t.srcPath]:[t.distPath],r={...process.env,AGENT_DEVICE_STATE_DIR:e.paths.baseDir,AGENT_DEVICE_DAEMON_SERVER_MODE:e.serverMode};f(process.execPath,a,{env:r})}function eq(){let e=S(),t=[n.join(e,"dist","src","internal","daemon.js"),n.join(e,"dist","src","daemon.js")],a=t[0];if(void 0===a)throw new u("COMMAND_FAILED","Daemon dist path list is empty");let o=t.find(e=>r.existsSync(e))??a,i=n.join(e,"src","daemon.ts"),s=t.some(e=>r.existsSync(e)),l=r.existsSync(i);if(!s&&!l)throw new u("COMMAND_FAILED","Daemon entry not found",{distPaths:t,srcPath:i});return{root:e,distPath:o,distPaths:t,srcPath:i,useSrc:process.execArgv.includes("--experimental-strip-types")?l:!s&&l}}async function eB(e,t,a,r){return"http"===e$(e,a)?await ez(e,t,r):await eG(e,t,r)}function e$(e,t){if(e.baseUrl){if("socket"===t)throw new u("COMMAND_FAILED","Remote daemon endpoint only supports HTTP transport",{daemonBaseUrl:e.baseUrl});return"http"}if("http"===t||"socket"===t){var a=e,r=t;if(ej(a,r))return r;throw new u("COMMAND_FAILED","http"===r?"Daemon HTTP endpoint is unavailable":"Daemon socket endpoint is unavailable")}let o=("socket"===e.transport||"dual"===e.transport?["socket","http"]:["http","socket"]).find(t=>ej(e,t));if(o)return o;throw new u("COMMAND_FAILED","Daemon metadata has no reachable transport")}function ej(e,t){return"http"===t?!!e.httpPort:!!e.port}function eH(e,t,a,r,o,n){let i=o?{terminated:0}:function(){let e=0;try{for(let t of eu){let a=p("pkill",["-f",t],{allowFailure:!0});0===a.exitCode&&(e+=1)}return{terminated:e}}catch(t){return{terminated:e,error:t instanceof Error?t.message:String(t)}}}(),s=!o&&"snapshot"!==r,l=s?function(e,t){let a=!1;try{M(e.pid,e.processStartTime)&&(process.kill(e.pid,"SIGKILL"),a=!0)}catch{T(e.pid,{termTimeoutMs:3e3,killTimeoutMs:1e3,expectedStartTime:e.processStartTime})}finally{eO(t.infoPath),eO(t.lockPath)}return{forcedKill:a}}(e,t):{forcedKill:!1};return E({level:"error",phase:"daemon_request_timeout",data:{timeoutMs:n,requestId:a,command:r,timedOutRunnerPidsTerminated:i.terminated,timedOutRunnerCleanupError:i.error,daemonPidReset:s?e.pid:void 0,daemonPidForceKilled:s?l.forcedKill:void 0,daemonPreservedAfterTimeout:!o&&!s,daemonBaseUrl:e.baseUrl}}),new u("COMMAND_FAILED","Daemon request timed out",{timeoutMs:n,requestId:a,hint:function(e){let{remote:t,resetDaemon:a,command:r}=e;return t?"Retry with --debug and verify the remote daemon URL, auth token, and remote host logs.":a?"Retry with --debug and check daemon diagnostics logs. Timed-out iOS runner xcodebuild processes were terminated when detected.":`Retry with --debug and check daemon diagnostics logs. The timed-out ${r??"request"} request was canceled and iOS runner work was aborted when detected; the daemon was kept alive so the session can still be closed or inspected.`}({remote:o,resetDaemon:s,command:r})})}function eK(e,t,a){return E({level:"error",phase:"daemon_request_socket_error",data:{requestId:t,message:e instanceof Error?e.message:String(e)}}),new u("COMMAND_FAILED","Failed to communicate with daemon",{requestId:t,hint:a?"Retry command. If this persists, verify the remote daemon URL, auth token, and remote host reachability.":"Retry command. If this persists, clean stale daemon metadata and start a fresh session."},e instanceof Error?e:void 0)}async function eG(t,a,r){let o=t.port;if(!o)throw new u("COMMAND_FAILED","Daemon socket endpoint is unavailable");return new Promise((n,i)=>{let s=e.createConnection({host:"127.0.0.1",port:o},()=>{s.write(`${JSON.stringify(a)}
3
+ `)}),l=v(a.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR),c=!1,d="number"==typeof r?setTimeout(()=>{c=!0,s.destroy(),i(eH(t,l,a.meta?.requestId,a.command,!1,r))},r):void 0,p="";s.setEncoding("utf8"),s.on("data",e=>{if(c)return;let t=y(p,e);for(let e of(p=t.buffer,t.lines))try{let t=JSON.parse(e);if(g(t)){ed(t.event);continue}let a=I(t)?t.response:t;c=!0,s.end(),d&&clearTimeout(d),n(a);return}catch(t){c=!0,d&&clearTimeout(d),i(new u("COMMAND_FAILED","Invalid daemon response",{requestId:a.meta?.requestId,line:e},t instanceof Error?t:void 0));return}}),s.on("error",e=>{c||(c=!0,d&&clearTimeout(d),i(eK(e,a.meta?.requestId,!1)))})})}async function ez(e,r,o){var n,i,s;let l,c=e.baseUrl?new URL(eY(e.baseUrl,"rpc")):e.httpPort?new URL(`http://127.0.0.1:${e.httpPort}/rpc`):null;if(!c)throw new u("COMMAND_FAILED","Daemon HTTP endpoint is unavailable");let d=JSON.stringify((n=r,i={includeTokenParam:!e.baseUrl},l=n.meta?.requestId??b(),"lease_allocate"!==(s=n.command)&&"lease_heartbeat"!==s&&"lease_release"!==s?{jsonrpc:"2.0",id:l,method:"agent_device.command",params:n}:{jsonrpc:"2.0",id:l,method:function(e){switch(e){case"lease_allocate":return"agent_device.lease.allocate";case"lease_heartbeat":return"agent_device.lease.heartbeat";case"lease_release":return"agent_device.lease.release"}}(n.command),params:function(e,t,a){let r={...a.includeTokenParam?{token:e.token}:{},session:e.session,tenantId:e.meta?.tenantId,runId:e.meta?.runId};switch(t){case"lease_allocate":return{...r,ttlMs:e.meta?.leaseTtlMs,backend:e.meta?.leaseBackend};case"lease_heartbeat":return{...r,leaseId:e.meta?.leaseId,ttlMs:e.meta?.leaseTtlMs};case"lease_release":return{...r,leaseId:e.meta?.leaseId}}}(n,n.command,i)})),p={"content-type":"application/json","content-length":Buffer.byteLength(d)};return e.baseUrl&&e.token&&(p.authorization=`Bearer ${e.token}`,p["x-agent-device-token"]=e.token),await new Promise((n,i)=>{let s=v(r.flags?.stateDir??process.env.AGENT_DEVICE_STATE_DIR),l=("https:"===c.protocol?a:t).request({protocol:c.protocol,host:c.hostname,port:c.port,method:"POST",path:c.pathname+c.search,headers:p},t=>{var a;(a=t.headers?.["content-type"],w(r)&&String(Array.isArray(a)?a.join(","):a??"").includes("application/x-ndjson"))?function(e,t){let{req:a,handleResponseBody:r,reject:o,clearTimeout:n}=t,i="",s=!1,l=e=>{try{let t=JSON.parse(e);if(g(t))return ed(t.event),!1;if(I(t))return s=!0,n(),r(JSON.stringify(t.response)),!0;throw Error("Missing daemon progress response envelope")}catch(t){return s=!0,n(),o(new u("COMMAND_FAILED","Invalid daemon response",{requestId:a.meta?.requestId,line:e},t instanceof Error?t:void 0)),!0}};e.setEncoding("utf8"),e.on("data",e=>{if(s)return;let t=y(i,e);for(let e of(i=t.buffer,t.lines))if(e&&l(e))return}),e.on("end",()=>{if(s)return;let e=i.trim();e&&l(e)||(s=!0,n(),o(new u("COMMAND_FAILED","Invalid daemon response",{requestId:a.meta?.requestId,line:e})))}),e.on("error",e=>{s||(s=!0,n(),o(new u("COMMAND_FAILED","Failed to read daemon response",{requestId:a.meta?.requestId},e instanceof Error?e:void 0)))})}(t,{req:r,reject:i,clearTimeout:()=>{f&&clearTimeout(f)},handleResponseBody:t=>eV(t,{info:e,req:r,resolve:n,reject:i})}):X(t).then(t=>{f&&clearTimeout(f),eV(t,{info:e,req:r,resolve:n,reject:i})}).catch(e=>{f&&clearTimeout(f),i(new u("COMMAND_FAILED","Failed to read daemon response",{requestId:r.meta?.requestId},e instanceof Error?e:void 0))})}),m=eJ(e),f="number"==typeof o?setTimeout(()=>{l.destroy(),i(eH(e,s,r.meta?.requestId,r.command,m,o))},o):void 0;l.on("error",e=>{f&&clearTimeout(f),i(eK(e,r.meta?.requestId,m))}),l.write(d),l.end()})}function eV(e,t){let{info:a,req:r,resolve:o,reject:n}=t;try{var i,s,l;let t=(i=e,JSON.parse(i));if(t.error){let e;return void n((s=t.error,l=r.meta?.requestId,e=s.data??{},new u(d(null!=e.code?String(e.code):void 0,"COMMAND_FAILED"),String(e.message??s.message??"Daemon RPC request failed"),{..."object"==typeof e.details&&e.details?e.details:{},hint:"string"==typeof e.hint?e.hint:void 0,diagnosticId:"string"==typeof e.diagnosticId?e.diagnosticId:void 0,logPath:"string"==typeof e.logPath?e.logPath:void 0,requestId:l})))}if(!t.result||"object"!=typeof t.result)return void n(new u("COMMAND_FAILED","Invalid daemon RPC response",{requestId:r.meta?.requestId}));eW(a,r,t.result,o,n)}catch(t){n(new u("COMMAND_FAILED","Invalid daemon response",{requestId:r.meta?.requestId,line:e},t instanceof Error?t:void 0))}}async function eW(e,t,a,r,o){try{r(e.baseUrl&&a.ok?await eQ(e,t,a):a)}catch(e){o(e)}}function eJ(e){return"string"==typeof e.baseUrl&&e.baseUrl.length>0}function eY(e,t){return new URL(t,e.endsWith("/")?e:`${e}/`).toString()}async function eQ(e,t,a){let r=Array.isArray(a.data?.artifacts)?a.data.artifacts:[];if(0===r.length||!e.baseUrl)return a;let o=a.data?{...a.data}:{},i=[];for(let a of r){if(!a||"object"!=typeof a||"string"!=typeof a.artifactId){i.push(a);continue}let r=function(e,t){if(e.localPath&&e.localPath.trim().length>0)return e.localPath;let a=t.meta?.clientArtifactPaths?.[e.field];if(a&&a.trim().length>0)return a;let r=e.fileName?.trim()||`${e.field}-${Date.now()}`;return n.resolve(t.meta?.cwd??process.cwd(),r)}(a,t);await eX({baseUrl:e.baseUrl,token:e.token,artifactId:a.artifactId,destinationPath:r,requestId:t.meta?.requestId}),o[a.field]=r,i.push({...a,localPath:r})}return o.artifacts=i,{ok:!0,data:o}}async function eX(e){var o,s;let l,c=new URL((o=e.baseUrl,s=e.artifactId,l=o.endsWith("/")?o:`${o}/`,new URL(`artifacts/${encodeURIComponent(s)}`,l).toString())),d="https:"===c.protocol?a:t;await r.promises.mkdir(n.dirname(e.destinationPath),{recursive:!0}),await new Promise((t,a)=>{let o=!1,n=e.timeoutMs??9e4,s=n=>{if(!o){if(o=!0,clearTimeout(p),n)return void r.promises.rm(e.destinationPath,{force:!0}).finally(()=>a(n));t()}},l=d.request({protocol:c.protocol,host:c.hostname,port:c.port,method:"GET",path:c.pathname+c.search,headers:e.token?{authorization:`Bearer ${e.token}`,"x-agent-device-token":e.token}:void 0},t=>{if((t.statusCode??500)>=400){let a="";t.setEncoding("utf8"),t.on("data",e=>{a+=e}),t.on("end",()=>{s(new u("COMMAND_FAILED","Failed to download remote artifact",{artifactId:e.artifactId,statusCode:t.statusCode,requestId:e.requestId,body:a}))});return}t.on("aborted",()=>{s(new u("COMMAND_FAILED","Remote artifact download was interrupted",{artifactId:e.artifactId,requestId:e.requestId}))}),i(t,r.createWriteStream(e.destinationPath)).then(()=>s(),e=>s(e instanceof Error?e:Error(String(e))))}),p=setTimeout(()=>{let t=new u("COMMAND_FAILED","Remote artifact download timed out",{artifactId:e.artifactId,requestId:e.requestId,timeoutMs:n});s(t),l.destroy(t)},n);l.on("error",t=>{t instanceof u?s(t):s(new u("COMMAND_FAILED","Failed to download remote artifact",{artifactId:e.artifactId,requestId:e.requestId,timeoutMs:n},t instanceof Error?t:void 0))}),l.end()})}function eZ(e={},t={}){let a=t.transport??em,r=async(t,r=[],o={})=>{var n,i;let s=(n=e,i=o,{...n,...i}),l=await a({session:x(s.session),command:t,positionals:r,flags:F(s),runtime:s.runtime,meta:W(s)});return l.ok||function(e){throw new u(d(e.code),e.message,{...e.details??{},hint:e.hint,diagnosticId:e.diagnosticId,logPath:e.logPath})}(l.error),l.data??{}},o=async(e={})=>{let t=await r(C.sessionList,[],e);return(Array.isArray(t.sessions)?t.sessions:[]).map(O)},n=async(e,t={})=>{let a=j(e,t);return await r(a.command,a.positionals,a.options)},i=(t={})=>{var a,r;return x((a=e,r=t,{...a,...r}).session)};return{command:{wait:async e=>await n("wait",e),alert:async(e={})=>await n("alert",e),appState:async(e={})=>await n("appstate",e),back:async(e={})=>await n("back",e),home:async(e={})=>await n("home",e),rotate:async e=>await n("rotate",e),appSwitcher:async(e={})=>await n("app-switcher",e),keyboard:async(e={})=>await n("keyboard",e),clipboard:async e=>await n("clipboard",e),reactNative:async e=>await n("react-native",e)},devices:{list:async(e={})=>{let t=await n("devices",e);return(Array.isArray(t.devices)?t.devices:[]).map(J)},boot:async(e={})=>await n("boot",e)},sessions:{list:async(e={})=>await o(e),close:async(e={})=>{let t=i(e),a=(await n("close",e)).shutdown;return{session:t,shutdown:"object"==typeof a&&null!==a?a:void 0,identifiers:{session:t}}}},apps:{install:async e=>G(await n("install",e),i(e)),reinstall:async e=>G(await n("reinstall",e),i(e)),installFromSource:async e=>B(await n("install-from-source",e),i(e)),list:async(e={})=>{let t=await n("apps",e);return Array.isArray(t.apps)?t.apps.filter(e=>"string"==typeof e):[]},open:async e=>{let t=i(e),a=await n("open",e),r=z(a),o=Q(a,"appBundleId");return{session:t,appName:Q(a,"appName"),appBundleId:o,appId:o,startup:q(a.startup),runtime:K(a.runtime),device:r,identifiers:{session:t,deviceId:r?.id,deviceName:r?.name,udid:r?.ios?.udid,serial:r?.android?.serial,appId:o,appBundleId:o}}},close:async(e={})=>{let t=i(e),a=(await n("close",e)).shutdown;return{session:t,closedApp:e.app,shutdown:"object"==typeof a&&null!==a?a:void 0,identifiers:{session:t}}},push:async e=>await n("push",e),triggerEvent:async e=>await n("trigger-app-event",e)},materializations:{release:async e=>$(await r(C.releaseMaterializedPaths,[],{...e,materializationId:e.materializationId}))},leases:{allocate:async e=>e1(await r(C.leaseAllocate,[],{...e,leaseId:void 0,leaseTtlMs:e.ttlMs})),heartbeat:async e=>e1(await r(C.leaseHeartbeat,[],{...e,leaseTtlMs:e.ttlMs})),release:async e=>({released:!0===(await r(C.leaseRelease,[],e)).released})},metro:{prepare:async t=>await R({projectRoot:t.projectRoot??e.cwd,kind:t.kind,publicBaseUrl:t.publicBaseUrl,proxyBaseUrl:t.proxyBaseUrl,proxyBearerToken:t.bearerToken,bridgeScope:t.bridgeScope,launchUrl:t.launchUrl,companionProfileKey:t.companionProfileKey,companionConsumerKey:t.companionConsumerKey,metroPort:t.port,listenHost:t.listenHost,statusHost:t.statusHost,startupTimeoutMs:t.startupTimeoutMs,probeTimeoutMs:t.probeTimeoutMs,reuseExisting:t.reuseExisting,installDependenciesIfNeeded:t.installDependenciesIfNeeded,runtimeFilePath:t.runtimeFilePath,logPath:t.logPath}),reload:async(t={})=>await L({metroHost:t.metroHost,metroPort:t.metroPort,bundleUrl:t.bundleUrl,runtime:e.runtime,timeoutMs:t.timeoutMs})},capture:{snapshot:async(e={})=>{var t,a,r;let o,s,l,c,d,u=i(e);return t=await n("snapshot",e),a=u,o=Q(t,"appBundleId"),{nodes:H(t.nodes),truncated:!0===t.truncated,appName:Q(t,"appName"),appBundleId:o,...(s=e0((r=t).visibility),l=e0(r.androidSnapshot),c=e0(r.unchanged),d=Array.isArray(r.warnings)?r.warnings.filter(e=>"string"==typeof e):void 0,{...s?{visibility:s}:{},...l?{androidSnapshot:l}:{},...c?{unchanged:c}:{},...d?{warnings:d}:{}}),identifiers:{session:a,appId:o,appBundleId:o}}},screenshot:async(e={})=>{let t=i(e),a=await n("screenshot",e);return{path:Y(a,"path"),overlayRefs:V(a),identifiers:{session:t}}},diff:async e=>await n("diff",e)},interactions:{click:async e=>await n("click",e),press:async e=>await n("press",e),longPress:async e=>await n("longpress",e),swipe:async e=>await n("swipe",e),pan:async e=>await n("gesture-pan",e),fling:async e=>await n("gesture-fling",e),swipeGesture:async e=>await n("gesture-swipe",e),focus:async e=>await n("focus",e),type:async e=>await n("type",e),fill:async e=>await n("fill",e),scroll:async e=>await n("scroll",e),pinch:async e=>await n("gesture-pinch",e),rotateGesture:async e=>await n("gesture-rotate",e),transformGesture:async e=>await n("gesture-transform",e),get:async e=>await n("get",e),is:async e=>await n("is",e),find:async e=>await n("find",e)},replay:{run:async e=>await n("replay",e),test:async e=>await n("test",e)},batch:{run:async e=>await n("batch",e)},observability:{perf:async(e={})=>await n("perf",e),logs:async(e={})=>await n("logs",e),network:async(e={})=>await n("network",e)},recording:{record:async e=>await n("record",e),trace:async e=>await n("trace",e)},settings:{update:async e=>await n("settings",e)}}}function e0(e){return"object"==typeof e&&null!==e?e:void 0}function e1(e){let t=e.lease;if(!t||"object"!=typeof t||Array.isArray(t))throw Error("Invalid lease response from daemon");return{leaseId:Y(t,"leaseId"),tenantId:Y(t,"tenantId"),runId:Y(t,"runId"),backend:Y(t,"backend"),createdAt:"number"==typeof t.createdAt?t.createdAt:void 0,heartbeatAt:"number"==typeof t.heartbeatAt?t.heartbeatAt:void 0,expiresAt:"number"==typeof t.expiresAt?t.expiresAt:void 0}}export{eZ as createAgentDeviceClient,em as sendToDaemon};
package/dist/src/9639.js CHANGED
@@ -1,2 +1,2 @@
1
- import{AsyncLocalStorage as e}from"node:async_hooks";import{runCmdBackground as r,withoutCommandExecutorOverride as t,runCmd as i,withCommandExecutorOverride as n}from"./9818.js";import{AppError as a}from"./9152.js";let o=new e;function l(e){return async(r,n)=>await t(async()=>await i("adb",["-s",e,...r],n))}function s(e){var t;let i=l(e.id);return{exec:i,spawn:(t=e.id,(e,i)=>{let n=r("adb",["-s",t,...e],{...i,allowFailure:!0,captureOutput:!1});return n.wait.catch(()=>{}),n.child}),reverse:g(i),pull:async(e,r,t)=>await i(["pull",e,r],t),install:async(e,r)=>{let{installArgs:t,execOptions:n}=h(r);return await i(["install",...t,e],n)}}}function d(e,r){let t=o.getStore();return r?r:t?.serial===e.id?t.provider.exec:l(e.id)}function u(e,r){if(r)return v(r);let t=o.getStore();return t?.serial===e.id?v(t.provider):s(e)}function c(e){let r=o.getStore();return r?.serial===e.id?r.provider.text:void 0}function w(e){let r=o.getStore();return r?.serial===e.id?r.provider.touch:void 0}function f(e){let r=v(e),t=r.reverse??g(r.exec),i=new Map;return{async ensure(e,r){let n=i.get(e.local);if(n&&n.ownerId!==e.ownerId)throw new a("COMMAND_FAILED",`Android port reverse ${e.local} is already owned by ${n.ownerId??"another session"}`,{current:n,requested:e});n?.remote!==e.remote&&(await t.ensure(e,r),i.set(e.local,{...e}))},async remove(e,r){i.has(e)?(await t.remove(e,r),i.delete(e)):await t.remove(e,r)},async removeAllOwned(e,r){let n=[...i.values()].filter(r=>r.ownerId===e).map(e=>e.local);if(0===n.length)return void await t.removeAllOwned(e,r);for(let e of n)await t.remove(e,r),i.delete(e)},list:async e=>t.list?await t.list(e):[...i.values()]}}function v(e){return"function"==typeof e?{exec:e}:e}async function p(e,r,i){let{device:n,provider:o,...l}=i??{},s=A(n,o),d=s?.pull;if(d)return await t(async()=>await d(e,r,l));let u=s?.exec;if(!u)throw new a("COMMAND_FAILED","Android adb pull requires an adb provider");return await t(async()=>await u(["pull",e,r],l))}async function m(e,r){let{device:i,provider:n,...o}=r??{},l=A(i,n),s=l?.install;if(s)return await t(async()=>await s(e,o));let d=l?.exec;if(!d)throw new a("COMMAND_FAILED","Android adb install requires an adb provider");let{installArgs:u,execOptions:c}=h(o);return await t(async()=>await d(["install",...u,e],c))}function A(e,r){if(r)return v(r);if(e)return u(e);let t=o.getStore();if(t)return v(t.provider)}async function y(e,r,i){var a;if(!e)return await i();let l={provider:"function"==typeof e?{exec:e}:e,serial:r.serial},s=(a=l,(e,r,i)=>{if("adb"!==e)return;let n=function(e,r){if("-s"===e[0]&&e[1]&&e[1]===r)return e.slice(2)}(r,a.serial);if(n)return t(async()=>await a.provider.exec(n,i))});return await o.run(l,async()=>await n(s,i))}function g(e){let r=new Map;return{async ensure(t,i){if(await e(["reverse",t.local,t.remote],{allowFailure:!1,signal:i?.signal,timeoutMs:i?.timeoutMs}),t.ownerId){let e=r.get(t.ownerId)??new Set;e.add(t.local),r.set(t.ownerId,e)}},async remove(t,i){var n,a;let o,l=await e(["reverse","--remove",t],{allowFailure:!0,signal:i?.signal,timeoutMs:i?.timeoutMs});if(0!==l.exitCode&&(n=l.stdout,a=l.stderr,!((o=`${n}
1
+ import{AsyncLocalStorage as e}from"node:async_hooks";import{runCmdBackground as r,withoutCommandExecutorOverride as t,runCmd as i,withCommandExecutorOverride as n}from"./9818.js";import{AppError as a}from"./9152.js";let o=new e;function l(e){return async(r,n)=>await t(async()=>await i("adb",["-s",e,...r],{...n,detached:"win32"!==process.platform}))}function s(e){var t;let i=l(e.id);return{exec:i,spawn:(t=e.id,(e,i)=>{let n=r("adb",["-s",t,...e],{...i,allowFailure:!0,captureOutput:!1});return n.wait.catch(()=>{}),n.child}),reverse:g(i),pull:async(e,r,t)=>await i(["pull",e,r],t),install:async(e,r)=>{let{installArgs:t,execOptions:n}=h(r);return await i(["install",...t,e],n)}}}function d(e,r){let t=o.getStore();return r?r:t?.serial===e.id?t.provider.exec:l(e.id)}function u(e,r){if(r)return v(r);let t=o.getStore();return t?.serial===e.id?v(t.provider):s(e)}function c(e){let r=o.getStore();return r?.serial===e.id?r.provider.text:void 0}function w(e){let r=o.getStore();return r?.serial===e.id?r.provider.touch:void 0}function f(e){let r=v(e),t=r.reverse??g(r.exec),i=new Map;return{async ensure(e,r){let n=i.get(e.local);if(n&&n.ownerId!==e.ownerId)throw new a("COMMAND_FAILED",`Android port reverse ${e.local} is already owned by ${n.ownerId??"another session"}`,{current:n,requested:e});n?.remote!==e.remote&&(await t.ensure(e,r),i.set(e.local,{...e}))},async remove(e,r){i.has(e)?(await t.remove(e,r),i.delete(e)):await t.remove(e,r)},async removeAllOwned(e,r){let n=[...i.values()].filter(r=>r.ownerId===e).map(e=>e.local);if(0===n.length)return void await t.removeAllOwned(e,r);for(let e of n)await t.remove(e,r),i.delete(e)},list:async e=>t.list?await t.list(e):[...i.values()]}}function v(e){return"function"==typeof e?{exec:e}:e}async function p(e,r,i){let{device:n,provider:o,...l}=i??{},s=A(n,o),d=s?.pull;if(d)return await t(async()=>await d(e,r,l));let u=s?.exec;if(!u)throw new a("COMMAND_FAILED","Android adb pull requires an adb provider");return await t(async()=>await u(["pull",e,r],l))}async function m(e,r){let{device:i,provider:n,...o}=r??{},l=A(i,n),s=l?.install;if(s)return await t(async()=>await s(e,o));let d=l?.exec;if(!d)throw new a("COMMAND_FAILED","Android adb install requires an adb provider");let{installArgs:u,execOptions:c}=h(o);return await t(async()=>await d(["install",...u,e],c))}function A(e,r){if(r)return v(r);if(e)return u(e);let t=o.getStore();if(t)return v(t.provider)}async function y(e,r,i){var a;if(!e)return await i();let l={provider:"function"==typeof e?{exec:e}:e,serial:r.serial},s=(a=l,(e,r,i)=>{if("adb"!==e)return;let n=function(e,r){if("-s"===e[0]&&e[1]&&e[1]===r)return e.slice(2)}(r,a.serial);if(n)return t(async()=>await a.provider.exec(n,i))});return await o.run(l,async()=>await n(s,i))}function g(e){let r=new Map;return{async ensure(t,i){if(await e(["reverse",t.local,t.remote],{allowFailure:!1,signal:i?.signal,timeoutMs:i?.timeoutMs}),t.ownerId){let e=r.get(t.ownerId)??new Set;e.add(t.local),r.set(t.ownerId,e)}},async remove(t,i){var n,a;let o,l=await e(["reverse","--remove",t],{allowFailure:!0,signal:i?.signal,timeoutMs:i?.timeoutMs});if(0!==l.exitCode&&(n=l.stdout,a=l.stderr,!((o=`${n}
2
2
  ${a}`.toLowerCase()).includes("listener")&&o.includes("not found"))))throw Error(`Failed to remove Android port reverse ${t}: ${l.stderr}`);for(let e of r.values())e.delete(t)},async removeAllOwned(e,t){for(let i of[...r.get(e)??[]])await this.remove(i,t);r.delete(e)},async list(t){let i=await e(["reverse","--list"],{allowFailure:!0,signal:t?.signal,timeoutMs:t?.timeoutMs});return 0!==i.exitCode?[]:function(e,r){let t=new Map;for(let[e,i]of r)for(let r of i)t.set(r,e);return e.split("\n").map(e=>e.trim().split(/\s+/)).filter(e=>e.length>=3).map(([,e,r])=>({local:e,remote:r,ownerId:t.get(e)}))}(i.stdout,r)}}}function h(e){let{replace:r,allowTestPackages:t,allowDowngrade:i,grantPermissions:n,...a}=e??{},o=[];return r&&o.push("-r"),t&&o.push("-t"),i&&o.push("-d"),n&&o.push("-g"),{installArgs:o,execOptions:a}}export{f as createAndroidPortReverseManager,s as createLocalAndroidAdbProvider,m as installAndroidAdbPackage,p as pullAndroidAdbFile,d as resolveAndroidAdbExecutor,u as resolveAndroidAdbProvider,c as resolveAndroidTextInjector,w as resolveAndroidTouchInjector,y as withAndroidAdbProvider};
@@ -0,0 +1 @@
1
+ import r from"node:fs";import e from"node:path";import{fileURLToPath as o}from"node:url";function t(){try{let o=n();return JSON.parse(r.readFileSync(e.join(o,"package.json"),"utf8")).version??"0.0.0"}catch{return"0.0.0"}}function n(){let t=e.dirname(o(import.meta.url)),n=t;for(let o=0;o<6;o+=1){let o=e.join(n,"package.json");if(r.existsSync(o))return n;n=e.dirname(n)}return t}export{n as findProjectRoot,t as readVersion};
@@ -1 +1 @@
1
- import{AppError as t}from"./9152.js";import{resolveAppsFilter as e}from"./1393.js";import{parseAndroidForegroundApp as i,parseAndroidLaunchablePackages as a,parseAndroidUserInstalledPackages as r,inferAndroidAppName as o,parseAndroidLaunchComponent as n,isAmStartError as d}from"./1769.js";let l="android.intent.category.LAUNCHER",s="android.intent.category.LEANBACK_LAUNCHER";async function c(t,i={}){let a=await A(t,i.target??"auto");return("user-installed"===e(i.filter)?(await p(t)).filter(t=>a.has(t)):Array.from(a)).map(t=>({package:t,name:o(t)})).sort((t,e)=>t.package.localeCompare(e.package))}async function u(t){let e=await f(t,[["shell","dumpsys","window","windows"],["shell","dumpsys","window"]]);if(e)return e;let i=await f(t,[["shell","dumpsys","activity","activities"],["shell","dumpsys","activity"]]);return i||{}}async function A(t,e){return new Set((await Promise.all((function(t){switch(t){case"mobile":return[l];case"tv":return[s];default:return[l,s]}})(e).map(async e=>{var i;let r=await t(["shell","cmd","package","query-activities","--brief","-a","android.intent.action.MAIN","-c",e],{allowFailure:!0});return 0===r.exitCode?0===(i=r.stdout).trim().length?[]:a(i):[]}))).flat())}async function p(e){let i=await e(["shell","pm","list","packages","-3"],{allowFailure:!0});if(0!==i.exitCode)throw new t("COMMAND_FAILED","Failed to list Android user-installed apps",{stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode});return r(i.stdout)}async function f(t,e){for(let a of e){let e=i((await t(a,{allowFailure:!0})).stdout??"");if(e)return e}return null}let w="android.intent.category.LAUNCHER",m="android.intent.category.DEFAULT";async function h(t,e){await t(["shell","am","force-stop",e])}async function C(t,e,i=[w]){for(let a of i){let i=await t(["shell","cmd","package","resolve-activity","--brief","-a","android.intent.action.MAIN","-c",a,e],{allowFailure:!0});if(0!==i.exitCode)continue;let r=n(i.stdout);if(r)return r}return null}async function _(e,i,a={}){let r=a.category??w;if(a.activity){var o,n;return void await e(["shell","am","start","-W","-a","android.intent.action.MAIN","-c",m,"-c",r,"-n",(o=i,(n=a.activity).includes("/")?n:`${o}/${n.startsWith(".")?n:`.${n}`}`)])}let l=await e(["shell","am","start","-W","-a","android.intent.action.MAIN","-c",m,"-c",r,"-p",i],{allowFailure:!0});if(0===l.exitCode&&!d(l.stdout,l.stderr))return;let s=await C(e,i,[r]);if(!s)throw new t("COMMAND_FAILED",`Failed to resolve Android launch component for ${i}`,{stdout:l.stdout,stderr:l.stderr,exitCode:l.exitCode});await e(["shell","am","start","-W","-a","android.intent.action.MAIN","-c",m,"-c",r,"-n",s])}export{captureAndroidLogcatWithAdb,dismissAndroidKeyboardWithAdb,getAndroidKeyboardStatusWithAdb,readAndroidClipboardWithAdb,streamAndroidLogcatWithAdb,writeAndroidClipboardWithAdb}from"./1769.js";export{createAndroidPortReverseManager,createLocalAndroidAdbProvider}from"./9639.js";export{h as forceStopAndroidAppWithAdb,u as getAndroidAppStateWithAdb,c as listAndroidAppsWithAdb,_ as openAndroidAppWithAdb,C as resolveAndroidLaunchComponentWithAdb};
1
+ import{AppError as t}from"./9152.js";import{resolveAppsFilter as e}from"./1393.js";import{parseAndroidForegroundApp as i,parseAndroidLaunchablePackages as a,parseAndroidUserInstalledPackages as r,inferAndroidAppName as o,parseAndroidLaunchComponent as n,isAmStartError as d}from"./8806.js";let l="android.intent.category.LAUNCHER",s="android.intent.category.LEANBACK_LAUNCHER";async function c(t,i={}){let a=await A(t,i.target??"auto");return("user-installed"===e(i.filter)?(await p(t)).filter(t=>a.has(t)):Array.from(a)).map(t=>({package:t,name:o(t)})).sort((t,e)=>t.package.localeCompare(e.package))}async function u(t){let e=await f(t,[["shell","dumpsys","window","windows"],["shell","dumpsys","window"]]);if(e)return e;let i=await f(t,[["shell","dumpsys","activity","activities"],["shell","dumpsys","activity"]]);return i||{}}async function A(t,e){return new Set((await Promise.all((function(t){switch(t){case"mobile":return[l];case"tv":return[s];default:return[l,s]}})(e).map(async e=>{var i;let r=await t(["shell","cmd","package","query-activities","--brief","-a","android.intent.action.MAIN","-c",e],{allowFailure:!0});return 0===r.exitCode?0===(i=r.stdout).trim().length?[]:a(i):[]}))).flat())}async function p(e){let i=await e(["shell","pm","list","packages","-3"],{allowFailure:!0});if(0!==i.exitCode)throw new t("COMMAND_FAILED","Failed to list Android user-installed apps",{stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode});return r(i.stdout)}async function f(t,e){for(let a of e){let e=i((await t(a,{allowFailure:!0})).stdout??"");if(e)return e}return null}let _="android.intent.category.LAUNCHER",m="android.intent.category.DEFAULT";async function w(t,e){await t(["shell","am","force-stop",e])}async function h(t,e,i=[_]){for(let a of i){let i=await t(["shell","cmd","package","resolve-activity","--brief","-a","android.intent.action.MAIN","-c",a,e],{allowFailure:!0});if(0!==i.exitCode)continue;let r=n(i.stdout);if(r)return r}return null}async function C(e,i,a={}){let r=a.category??_;if(a.activity){var o,n;return void await e(["shell","am","start","-W","-a","android.intent.action.MAIN","-c",m,"-c",r,"-n",(o=i,(n=a.activity).includes("/")?n:`${o}/${n.startsWith(".")?n:`.${n}`}`)])}let l=await e(["shell","am","start","-W","-a","android.intent.action.MAIN","-c",m,"-c",r,"-p",i],{allowFailure:!0});if(0===l.exitCode&&!d(l.stdout,l.stderr))return;let s=await h(e,i,[r]);if(!s)throw new t("COMMAND_FAILED",`Failed to resolve Android launch component for ${i}`,{stdout:l.stdout,stderr:l.stderr,exitCode:l.exitCode});await e(["shell","am","start","-W","-a","android.intent.action.MAIN","-c",m,"-c",r,"-n",s])}export{captureAndroidLogcatWithAdb,streamAndroidLogcatWithAdb}from"./8806.js";export{createAndroidPortReverseManager,createLocalAndroidAdbProvider}from"./9639.js";export{dismissAndroidKeyboardWithAdb,getAndroidKeyboardStatusWithAdb,readAndroidClipboardWithAdb,writeAndroidClipboardWithAdb}from"./8133.js";export{w as forceStopAndroidAppWithAdb,u as getAndroidAppStateWithAdb,c as listAndroidAppsWithAdb,C as openAndroidAppWithAdb,h as resolveAndroidLaunchComponentWithAdb};
@@ -12,7 +12,7 @@ export declare const ANDROID_SNAPSHOT_HELPER_PROTOCOL = "android-snapshot-helper
12
12
 
13
13
  export declare const ANDROID_SNAPSHOT_HELPER_RUNNER = "com.callstack.agentdevice.snapshothelper/.SnapshotInstrumentation";
14
14
 
15
- export declare const ANDROID_SNAPSHOT_HELPER_WAIT_FOR_IDLE_TIMEOUT_MS = 25;
15
+ export declare const ANDROID_SNAPSHOT_HELPER_WAIT_FOR_IDLE_TIMEOUT_MS = 500;
16
16
 
17
17
  /**
18
18
  * Runs device-scoped adb arguments after the device serial has already been selected.
@@ -308,6 +308,7 @@ declare type RawSnapshotNode = {
308
308
  enabled?: boolean;
309
309
  selected?: boolean;
310
310
  focused?: boolean;
311
+ visibleToUser?: boolean;
311
312
  hittable?: boolean;
312
313
  depth?: number;
313
314
  parentIndex?: number;
@@ -1 +1 @@
1
- var _=25;export{ANDROID_SNAPSHOT_HELPER_NAME,ANDROID_SNAPSHOT_HELPER_OUTPUT_FORMAT,ANDROID_SNAPSHOT_HELPER_PACKAGE,ANDROID_SNAPSHOT_HELPER_PROTOCOL,ANDROID_SNAPSHOT_HELPER_RUNNER,captureAndroidSnapshotWithHelper,ensureAndroidSnapshotHelper,parseAndroidSnapshotHelperManifest,parseAndroidSnapshotHelperOutput,parseAndroidSnapshotHelperXml,prepareAndroidSnapshotHelperArtifactFromManifestUrl,verifyAndroidSnapshotHelperArtifact}from"./221.js";export{_ as ANDROID_SNAPSHOT_HELPER_WAIT_FOR_IDLE_TIMEOUT_MS};
1
+ var _=500;export{ANDROID_SNAPSHOT_HELPER_NAME,ANDROID_SNAPSHOT_HELPER_OUTPUT_FORMAT,ANDROID_SNAPSHOT_HELPER_PACKAGE,ANDROID_SNAPSHOT_HELPER_PROTOCOL,ANDROID_SNAPSHOT_HELPER_RUNNER,captureAndroidSnapshotWithHelper,ensureAndroidSnapshotHelper,parseAndroidSnapshotHelperManifest,parseAndroidSnapshotHelperOutput,parseAndroidSnapshotHelperXml,prepareAndroidSnapshotHelperArtifactFromManifestUrl,verifyAndroidSnapshotHelperArtifact}from"./221.js";export{_ as ANDROID_SNAPSHOT_HELPER_WAIT_FOR_IDLE_TIMEOUT_MS};
@@ -0,0 +1,5 @@
1
+ import e from"node:crypto";import t from"node:fs/promises";import r from"node:path";import{promises as i}from"node:fs";import{normalizeError as a,AppError as n}from"./9152.js";import{withDiagnosticTimer as o,emitDiagnostic as s}from"./7599.js";import{readVersion as d,findProjectRoot as l}from"./9671.js";import{resolveAndroidTouchInjector as u,resolveAndroidAdbProvider as c,resolveAndroidAdbExecutor as p,installAndroidAdbPackage as m}from"./9639.js";import{appSwitcherAndroid as h,homeAndroid as f,scrollAndroid as w,longPressAndroid as A,typeAndroid as _,getAndroidScreenSize as g,pressAndroid as y,focusAndroid as N,swipeAndroid as I,rotateAndroid as v,fillAndroid as C,backAndroid as M}from"./input-actions.js";import{requireLocationCoordinates as S}from"./1998.js";import{parseAppearanceAction as R,summarizeCommandAttemptFailures as D,parseSettingState as E,parsePermissionTarget as x,parsePermissionAction as k}from"./6629.js";import{openAndroidDevice as b,runAndroidAdb as O,openAndroidApp as L,resolveAndroidApp as F,closeAndroidApp as P}from"./8806.js";import{writeAndroidClipboardText as T,readAndroidClipboardText as U}from"./8133.js";import{snapshotAndroid as $}from"./2415.js";import{sleep as G}from"./4829.js";let K="android-multitouch-helper-v1",V="ANDROID_MULTITOUCH_HELPER_NO_FINAL_RESULT",H="ANDROID_MULTITOUCH_HELPER_REPORTED_FAILURE";async function q(e,t){if(!Number.isFinite(t.scale)||t.scale<=0)throw new n("INVALID_ARGS","gesture pinch requires scale > 0");let r=await z(e,t.x,t.y);return await J(e,{kind:"pinch",x:r.x,y:r.y,scale:t.scale,durationMs:t.durationMs})}async function B(e,t){if(!Number.isFinite(t.degrees))throw new n("INVALID_ARGS","gesture rotate requires finite degrees");if(void 0!==t.velocity&&(!Number.isFinite(t.velocity)||0===t.velocity))throw new n("INVALID_ARGS","gesture rotate velocity must be a non-zero number");let r=await z(e,t.x,t.y),i=t.degrees;return await J(e,{kind:"rotate",x:r.x,y:r.y,degrees:i,durationMs:t.durationMs})}async function j(e,t){if(!Number.isFinite(t.scale)||t.scale<=0)throw new n("INVALID_ARGS","gesture transform requires scale > 0");if(!Number.isFinite(t.degrees))throw new n("INVALID_ARGS","gesture transform requires finite degrees");if(![t.x,t.y,t.dx,t.dy].every(Number.isFinite))throw new n("INVALID_ARGS","gesture transform requires finite x y dx dy");return await J(e,{kind:"transform",x:t.x,y:t.y,dx:t.dx,dy:t.dy,scale:t.scale,degrees:t.degrees,durationMs:t.durationMs})}async function z(e,t,r){if(void 0!==t&&void 0!==r)return{x:t,y:r};let i=await g(e);return{x:Math.round(i.width/2),y:Math.round(i.height/2)}}async function J(e,t){let r=u(e);if(r)return{backend:"provider-native-touch",...await r(t)??{}};let i=p(e),a=await Q(),n=c(e),d=await o("android_multitouch_helper_install",async()=>{var t;return await Y({adb:i,adbProvider:n,artifact:a,deviceKey:(t=e,`${t.platform}:${t.id}`)})},{packageName:a.manifest.packageName,versionCode:a.manifest.versionCode});s({phase:"android_multitouch_helper_install_decision",data:d});let l=await o("android_multitouch_helper_gesture",async()=>await W({adb:i,request:function(e){var t;let r=Math.round(void 0!==(t=e).durationMs?t.durationMs:"pinch"===t.kind?300:Math.min(Math.max(300,16*Math.ceil(Math.abs(t.degrees)/3)),2400));switch(e.kind){case"pinch":return{kind:"pinch",x:Math.round(e.x),y:Math.round(e.y),scale:e.scale,radius:160,durationMs:r};case"rotate":return{kind:"rotate",x:Math.round(e.x),y:Math.round(e.y),degrees:e.degrees,radius:160,durationMs:r};case"transform":return{kind:"transform",x:Math.round(e.x),y:Math.round(e.y),dx:Math.round(e.dx),dy:Math.round(e.dy),scale:e.scale,degrees:e.degrees,durationMs:r}}}(t),packageName:a.manifest.packageName,instrumentationRunner:a.manifest.instrumentationRunner}),{packageName:a.manifest.packageName,version:a.manifest.version});return{backend:"android-multitouch-helper",helperVersion:a.manifest.version,installReason:d.reason,...l}}async function W(e){let t,r=Buffer.from(JSON.stringify({protocol:K,...e.request})).toString("base64"),i=await e.adb(["shell","am","instrument","-w","-e","payloadBase64",r,e.instrumentationRunner],{allowFailure:!0,timeoutMs:45e3});try{t=function(e){let t=(function(e){let t=[],r=null;for(let i of e.split(/\r?\n/))i.startsWith("INSTRUMENTATION_RESULT: ")?(r??={},function(e,t){let r=e.indexOf("=");r>=0&&(t[e.slice(0,r)]=e.slice(r+1))}(i.slice(24),r)):i.startsWith("INSTRUMENTATION_CODE: ")&&r&&(t.push(r),r=null);return r&&t.push(r),t})(e).find(e=>e.agentDeviceProtocol===K);if(!t)throw new n(V,"Android multi-touch helper did not return a final result");if("true"!==t.ok){var r;throw new n(H,(r=t).message&&"null"!==r.message?r.message:r.errorType||"Android multi-touch helper returned an error",{errorType:t.errorType,helper:t})}return{kind:t.kind,helperApiVersion:t.helperApiVersion,injectedEvents:X(t.injectedEvents),elapsedMs:X(t.elapsedMs)}}(`${i.stdout}
2
+ ${i.stderr}`)}catch(e){if(e instanceof n){if(e.code===H)throw new n("COMMAND_FAILED",e.message,e.details,e);if(e.code!==V)throw e}throw new n("COMMAND_FAILED",0===i.exitCode?"Android multi-touch helper output could not be parsed":"Android multi-touch helper failed before returning parseable output",{stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode},e)}if(0!==i.exitCode)throw new n("COMMAND_FAILED","Android multi-touch helper failed",{stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode,helper:t});return t}function X(e){if(void 0===e)return;let t=Number(e);return Number.isFinite(t)?t:void 0}async function Q(){let e=d(),i=r.join(l(),"android-multitouch-helper","dist"),o=r.join(i,`agent-device-android-multitouch-helper-${e}.manifest.json`);try{let e=function(e){if(!e||"object"!=typeof e||Array.isArray(e))throw new n("INVALID_ARGS","Android multi-touch helper manifest must be an object.");return{name:ea(e.name,"name","android-multitouch-helper"),version:ei(e.version,"version"),assetName:ei(e.assetName,"assetName"),sha256:function(e){let t=ei(e,"sha256").trim().toLowerCase();if(64!==t.length||!/^[0-9a-f]+$/.test(t))throw new n("INVALID_ARGS","Android multi-touch helper manifest sha256 must be a 64-character hex string.");return t}(e.sha256),packageName:ea(e.packageName,"packageName","com.callstack.agentdevice.multitouchhelper"),versionCode:function(e,t){if(!Number.isInteger(e))throw new n("INVALID_ARGS",`Android multi-touch helper manifest ${t} must be an integer.`);return e}(e.versionCode,"versionCode"),instrumentationRunner:ea(e.instrumentationRunner,"instrumentationRunner","com.callstack.agentdevice.multitouchhelper/.MultiTouchInstrumentation"),statusProtocol:ea(e.statusProtocol,"statusProtocol",K)}}(JSON.parse(await t.readFile(o,"utf8"))),a=r.join(i,e.assetName);return await t.access(a),{apkPath:a,manifest:e}}catch(e){throw new n("UNSUPPORTED_OPERATION","gesture pinch/rotate/transform on Android requires the bundled Android multi-touch helper artifact, but it was not found or could not be read",{manifestPath:o,error:a(e).message},e)}}async function Y(e){let{adb:t,artifact:r}=e,i=r.manifest.packageName,a=r.manifest.versionCode,o=`${e.deviceKey}\0${i}\0${a}`;if(Z.has(o))return{packageName:i,versionCode:a,installed:!1,reason:"current"};let s=await ee(t,i);if(void 0!==s&&s>=a)return Z.add(o),{packageName:i,versionCode:a,installedVersionCode:s,installed:!1,reason:"current"};await et(r);let d=await m(r.apkPath,{provider:e.adbProvider,replace:!0,allowTestPackages:!0,allowFailure:!0,timeoutMs:3e4});if(0!==d.exitCode)throw new n("COMMAND_FAILED","Failed to install Android multi-touch helper",{packageName:i,versionCode:a,stdout:d.stdout,stderr:d.stderr,exitCode:d.exitCode});return Z.add(o),{packageName:i,versionCode:a,installedVersionCode:s,installed:!0,reason:void 0===s?"missing":"outdated"}}let Z=new Set;async function ee(e,t){let r=await e(["shell","cmd","package","list","packages","--show-versioncode",t],{allowFailure:!0,timeoutMs:5e3});if(0!==r.exitCode)return;let i=RegExp(`package:${t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}(?:\\s|$).*versionCode:(\\d+)`).exec(`${r.stdout}
3
+ ${r.stderr}`);return i?Number(i[1]):void 0}async function et(e){let t=await er(e.apkPath);if(t!==e.manifest.sha256)throw new n("COMMAND_FAILED","Android multi-touch helper APK checksum mismatch",{apkPath:e.apkPath,expectedSha256:e.manifest.sha256,actualSha256:t})}async function er(r){let i=e.createHash("sha256");return i.update(await t.readFile(r)),i.digest("hex")}function ei(e,t){if("string"!=typeof e||0===e.length)throw new n("INVALID_ARGS",`Android multi-touch helper manifest ${t} is required.`);return e}function ea(e,t,r){if(e!==r)throw new n("INVALID_ARGS",`Android multi-touch helper manifest ${t} must be "${r}".`);return r}let en=["window_animation_scale","transition_animation_scale","animator_duration_scale"];async function eo(e,t,r,i,a){switch(t.toLowerCase()){case"wifi":{let t=E(r);await O(e,["shell","svc","wifi",t?"enable":"disable"]);return}case"airplane":{let t=E(r);await O(e,["shell","settings","put","global","airplane_mode_on",t?"1":"0"]),await O(e,["shell","am","broadcast","-a","android.intent.action.AIRPLANE_MODE","--ez","state",t?"true":"false"]);return}case"location":{if("set"===r.toLowerCase()){if("emulator"!==e.kind)throw new n("UNSUPPORTED_OPERATION","Android precise location coordinates are supported only on emulators.",{deviceId:e.id,hint:"Use an Android emulator for adb emu geo fix, or configure location through device/provider tooling."});let{latitude:t,longitude:r}=S(a);return await O(e,["emu","geo","fix",String(r),String(t)]),{latitude:t,longitude:r}}let t=E(r);await O(e,["shell","settings","put","secure","location_mode",t?"3":"0"]);return}case"animations":{let t=E(r)?"1":"0";for(let r of en)await O(e,["shell","settings","put","global",r,t]);return{scale:t,keys:[...en]}}case"appearance":{let t=await ed(e,r);await O(e,["shell","cmd","uimode","night","dark"===t?"yes":"no"]);return}case"clear-app-state":{if("clear"!==r.toLowerCase())throw new n("INVALID_ARGS","settings clear-app-state only supports clear.");if(!i)throw new n("INVALID_ARGS","settings clear-app-state requires an app id or an active app session.");let t=await F(e,i);if("intent"===t.type)throw new n("INVALID_ARGS","settings clear-app-state requires a package name, not an intent.");await O(e,["shell","am","force-stop",t.value],{allowFailure:!0});let a=await O(e,["shell","pm","clear",t.value],{allowFailure:!0});if(0!==a.exitCode||!/\bSuccess\b/i.test(a.stdout))throw new n("COMMAND_FAILED",`Failed to clear Android app data for ${t.value}`,{package:t.value,stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});return{package:t.value,cleared:!0}}case"fingerprint":{let t=function(e){let t=e.trim().toLowerCase();if("match"===t)return"match";if("nonmatch"===t)return"nonmatch";throw new n("INVALID_ARGS",`Invalid fingerprint state: ${e}. Use match|nonmatch.`)}(r);await es(e,t);return}case"permission":{if(!i)throw new n("INVALID_ARGS","permission setting requires an active app in session");let t=k(r),o=function(e,t){let r=x(e);if(t?.trim())throw new n("INVALID_ARGS",`Permission mode is only supported for photos. Received: ${t}.`);if("camera"===r)return{kind:"pm",value:"android.permission.CAMERA",type:"camera"};if("microphone"===r)return{kind:"pm",value:"android.permission.RECORD_AUDIO",type:"microphone"};if("photos"===r)return{kind:"pm",value:"android.permission.READ_MEDIA_IMAGES",type:"photos"};if("contacts"===r)return{kind:"pm",value:"android.permission.READ_CONTACTS",type:"contacts"};if("notifications"===r)return{kind:"notifications",appOps:"POST_NOTIFICATION",permission:"android.permission.POST_NOTIFICATIONS"};throw new n("INVALID_ARGS",`Unsupported permission target on Android: ${e}. Use camera|microphone|photos|contacts|notifications.`)}(a?.permissionTarget,a?.permissionMode);if("notifications"===o.kind)return void await eu(e,i,t,o);let s="grant"===t?"grant":"revoke";if("photos"===o.type)return void await el(e,i,s);await O(e,["shell","pm",s,i,o.value]);return}default:throw new n("INVALID_ARGS",`Unsupported setting: ${t}`)}}async function es(e,t){var r;let i,a,o=(r=e,a=[["shell","cmd","fingerprint","touch",i="match"===t?"1":"9999"],["shell","cmd","fingerprint","finger",i]],"emulator"===r.kind&&a.push(["emu","finger","touch",i]),a),s=[];for(let t of o){let r=await O(e,t,{allowFailure:!0});if(0===r.exitCode)return;s.push({args:t,stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode})}let d=D(s);if(s.length>0&&s.every(e=>{var t,r;let i;return t=e.stdout,r=e.stderr,(i=`${t}
4
+ ${r}`.toLowerCase()).includes("unknown command")||i.includes("can't find service: fingerprint")||i.includes("service fingerprint was not found")||i.includes("fingerprint cmd unavailable")||i.includes("emu command is not supported")||i.includes("emulator console is not running")||i.includes("fingerprint")&&i.includes("not found")}))throw new n("UNSUPPORTED_OPERATION","Android fingerprint simulation is not supported on this target/runtime.",{deviceId:e.id,action:t,hint:"Use an Android emulator with biometric support, or a device/runtime that exposes cmd fingerprint.",attempts:d});throw new n("COMMAND_FAILED","Failed to simulate Android fingerprint.",{deviceId:e.id,action:t,attempts:d})}async function ed(e,t){let r=R(t);if("toggle"!==r)return r;let i=await O(e,["shell","cmd","uimode","night"],{allowFailure:!0});if(0!==i.exitCode)throw new n("COMMAND_FAILED","Failed to read current Android appearance",{stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode});let a=function(e,t){let r=/night mode:\s*(yes|no|auto)\b/i.exec(`${e}
5
+ ${t}`);if(!r)return null;let i=r[1]?.toLowerCase();return"yes"===i?"dark":"no"===i?"light":"auto"===i?"auto":null}(i.stdout,i.stderr);if(!a)throw new n("COMMAND_FAILED","Unable to determine current Android appearance for toggle",{stdout:i.stdout,stderr:i.stderr});return"auto"===a?"dark":"dark"===a?"light":"dark"}async function el(e,t,r){let i=await ec(e),a=[];for(let n of null!==i&&i>=33?["android.permission.READ_MEDIA_IMAGES","android.permission.READ_EXTERNAL_STORAGE"]:["android.permission.READ_EXTERNAL_STORAGE","android.permission.READ_MEDIA_IMAGES"]){let i=await O(e,["shell","pm",r,t,n],{allowFailure:!0});if(0===i.exitCode)return;a.push({permission:n,stderr:i.stderr,exitCode:i.exitCode})}throw new n("COMMAND_FAILED",`Failed to ${r} Android photos permission`,{appPackage:t,sdkInt:i,attempts:a})}async function eu(e,t,r,i){"grant"===r?await O(e,["shell","pm","grant",t,i.permission],{allowFailure:!0}):(await O(e,["shell","pm","revoke",t,i.permission],{allowFailure:!0}),"reset"===r&&(await O(e,["shell","pm","clear-permission-flags",t,i.permission,"user-set"],{allowFailure:!0}),await O(e,["shell","pm","clear-permission-flags",t,i.permission,"user-fixed"],{allowFailure:!0}))),await O(e,["shell","appops","set",t,i.appOps,"grant"===r?"allow":"deny"===r?"deny":"default"])}async function ec(e){let t=await O(e,["shell","getprop","ro.build.version.sdk"],{allowFailure:!0});if(0!==t.exitCode)return null;let r=Number.parseInt(t.stdout.trim(),10);return!Number.isFinite(r)||r<=0?null:r}let ep=Buffer.from([137,80,78,71,13,10,26,10]);async function em(e,t,r={}){if(!1===r.stabilize)return void await ew(e,t);await eh(e);try{await G(1e3),await ew(e,t)}finally{await ef(e).catch(()=>{})}}async function eh(e){let t=t=>O(e,["shell",t],{allowFailure:!0});await t("settings put global sysui_demo_allowed 1");let r=e=>t(`am broadcast -a com.android.systemui.demo -e command ${e}`);await r("clock -e hhmm 0941"),await r("notifications -e visible false")}async function ef(e){await O(e,["shell","am broadcast -a com.android.systemui.demo -e command exit"],{allowFailure:!0})}async function ew(e,t){let r=await O(e,["exec-out","screencap","-p"],{binaryStdout:!0});if(!r.stdoutBuffer)throw new n("COMMAND_FAILED","Failed to capture screenshot");let a=r.stdoutBuffer.indexOf(ep);if(a<0)throw new n("COMMAND_FAILED","Screenshot data does not contain a valid PNG header");let o=function(e,t){let r=t+ep.length;for(;r+8<=e.length;){let t=e.readUInt32BE(r),i=r+4,a=e.toString("ascii",i,i+4),n=r+12+t;if(n>e.length)break;if("IEND"===a)return n;r=n}return null}(r.stdoutBuffer,a);if(!o)throw new n("COMMAND_FAILED","Screenshot data does not contain a complete PNG payload");await i.writeFile(t,r.stdoutBuffer.subarray(a,o))}function eA(e){return{open:(t,r)=>L(e,t,{activity:r?.activity,appBundleId:r?.appBundleId,launchArgs:r?.launchArgs,url:r?.url}),openDevice:()=>b(e),close:t=>P(e,t),tap:(t,r)=>y(e,t,r),doubleTap:async(t,r)=>{await y(e,t,r),await y(e,t,r)},swipe:(t,r,i,a,n)=>I(e,t,r,i,a,n),pan:(t,r,i,a,n)=>I(e,t,r,i,a,n),fling:(t,r,i,a,n)=>I(e,t,r,i,a,n),longPress:(t,r,i)=>A(e,t,r,i),focus:(t,r)=>N(e,t,r),type:(t,r)=>_(e,t,r),fill:(t,r,i,a)=>C(e,t,r,i,a),scroll:(t,r)=>w(e,t,r),pinch:(t,r,i)=>q(e,{scale:t,x:r,y:i}),screenshot:(t,r)=>em(e,t,r),snapshot:async t=>{let r=await o("snapshot_capture",async()=>await $(e,{interactiveOnly:t?.interactiveOnly,compact:t?.compact,depth:t?.depth,scope:t?.scope,raw:t?.raw}),{backend:"android"});return{nodes:r.nodes??[],truncated:r.truncated??!1,backend:"android",analysis:r.analysis,androidSnapshot:r.androidSnapshot}},back:t=>M(e),home:()=>f(e),rotate:t=>v(e,t),rotateGesture:(t,r,i,a)=>B(e,{degrees:t,x:r,y:i,velocity:a}),transformGesture:t=>j(e,t),appSwitcher:()=>h(e),readClipboard:()=>U(e),writeClipboard:t=>T(e,t),setSetting:(t,r,i,a)=>eo(e,t,r,i,a)}}export{eA as createAndroidInteractor};