agent-device 0.12.5 → 0.12.7

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.
@@ -1 +1 @@
1
- import{promises as e}from"node:fs";import t from"node:path";import{PNG as n}from"pngjs";import{asAppError as r,AppError as a,normalizeAgentDeviceError as i}from"../152.js";import{whichCmd as s,runCmd as o}from"../818.js";import{centerOfRect as l,findNodeByRef as c,normalizeRef as u}from"../57.js";import{findSelectorChainMatch as d,extractNodeText as h,findNearestHittableAncestor as f,resolveSelectorChain as m,parseSelectorChain as p,findNodeByLabel as w,resolveRefLabel as g,isNodeVisible as b,formatSelectorFailure as x,normalizeType as y,isNodeEditable as v,isFillableType as M}from"../selectors.js";import{findBestMatchesByLocator as k}from"../556.js";function N(e){return e?{message:e}:{}}async function I(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 r(e)}}async function A(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 r(e)}}async function R(e,t){try{return await e.artifacts.createTempFile(t)}catch(e){throw r(e)}}let S=async(e,t)=>{let n;if(!e.backend.captureScreenshot)throw new a("UNSUPPORTED_OPERATION","screenshot is not supported by this backend");let r=await A(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,surface:t.surface}),n=await r.publish()}catch(e){throw await r.cleanup?.(),e}return{path:r.path,...n?{artifacts:[n]}:{},...N(`Saved screenshot: ${r.path}`)}};function P(e,t){try{return n.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)})}}let $=[0,187,255,255];function _(e,t,n,r){if(t<0||t>=e.width||n<0||n>=e.height)return;let a=(n*e.width+t)*4;e.data[a]=r[0],e.data[a+1]=r[1],e.data[a+2]=r[2],e.data[a+3]=r[3]}function C(e,t,n){return Math.min(Math.max(e,t),n)}let O={icon:90,toggle:90,chevron:75,separator:45,visual:35,background:10},D={leading:20,trailing:20,separator:10,unknown:0,background:-30};function L(e){return"background"!==e.likelyKind}function T(e,t){return e.width>=.25*t.width||e.height>=.06*t.height}function E(e,t){let n,r=0;for(let a of t){let t=U(e,a.rect);t<=r||(r=t,n=a)}return n}function X(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,U(t,r=n.rect)>0||Math.abs(B(t).y-B(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=function(e){let t=1/0,n=1/0,r=-1/0,a=-1/0;for(let i of e)t=Math.min(t,i.x),n=Math.min(n,i.y),r=Math.max(r,i.x+i.width),a=Math.max(a,i.y+i.height);return{x:t,y:n,width:r-t,height:a-n}}([e.rect,n.rect])}return t}function F(e,t){let n,r=B(e);for(let e of t){var a,i;let t=Math.sqrt((a=r,i=B(e.rect),(a.x-i.x)**2+(a.y-i.y)**2));n&&t>=n.distance||(n={block:e,distance:t})}return n}function Y(e){let t=q(e);return e.differentPixels>=24&&t.width>=3&&t.height>=3}function q(e){return{x:e.minX,y:e.minY,width:e.maxX-e.minX+1,height:e.maxY-e.minY+1}}function U(e,t){return Math.max(0,Math.min(e.y+e.height,t.y+t.height)-Math.max(e.y,t.y))}function B(e){return{x:e.x+e.width/2,y:e.y+e.height/2}}function G(e,t,n){return Math.min(Math.max(e,t),n)}async function V(e){if(await s("tesseract"))try{let[t,n]=await Promise.all([H(e.baselinePath),H(e.currentPath)]);if(0!==t.exitCode||0!==n.exitCode)return;let r=z(t.stdout,e.width,e.height),a=z(n.stdout,e.width,e.height),i=function(e,t){let n=new Set,r=[];for(let i of e){var a;let e=ee(i.text),s=function(e,t,n,r){let a=null,i=1/0;for(let l=0;l<n.length;l+=1){var s,o;if(r.has(l))continue;let c=n[l];if(ee(c.text)!==t)continue;let u=(s=J(e.normalizedRect),o=J(c.normalizedRect),(s.x-o.x)**2+(s.y-o.y)**2);u>=i||(a=l,i=u)}return a}(i,e,t,n);if(null===s)continue;n.add(s);let o=function(e,t){let n={x:t.rect.x-e.rect.x,y:t.rect.y-e.rect.y,width:t.rect.width-e.rect.width,height:t.rect.height-e.rect.height},r=er(t.rect.width/e.rect.width),a=er(t.rect.height/e.rect.height),i=Math.abs(r-1)>=.08||Math.abs(a-1)>=.12;return{text:e.text,baselineRect:e.rect,currentRect:t.rect,delta:n,confidence:Math.round(100*Math.min(e.confidence,t.confidence))/100,possibleTextMetricMismatch:i}}(i,t[s]);a=o,(Math.abs(a.delta.x)>=2||Math.abs(a.delta.y)>=2||Math.abs(a.delta.width)>=2||Math.abs(a.delta.height)>=2||a.possibleTextMetricMismatch)&&r.push(o)}return r.sort((e,t)=>K(t)-K(e)).slice(0,12)}(r,a),s=function(e){let t=[];for(let n of[...e].sort((e,t)=>e.currentRect.y-t.currentRect.y)){let e=t.find(e=>32>=Math.abs(n.delta.x-et(e.map(e=>e.delta.x))));e?e.push(n):t.push([n])}return t.filter(e=>e.length>=2).map(j).filter(e=>e.yRange.max-e.yRange.min<=60).sort((e,t)=>W(t)-W(e)).slice(0,4)}(i);if(0===r.length&&0===a.length)return;return{provider:"tesseract",baselineBlocks:r.length,currentBlocks:a.length,baselineBlocksRaw:r,currentBlocksRaw:a,matches:i,...s.length>0?{movementClusters:s}:{}}}catch{return}}function z(e,t,n){let[r,...a]=e.split(/\r?\n/);if(!r)return[];let i=new Map(r.split(" ").map((e,t)=>[e,t])),s=[];for(let e of a){var o;if(!e.trim())continue;let t=e.split(" "),n=Q(t,i,"level"),r=Z(t,i,"text").trim(),a=Q(t,i,"conf");if(5!==n||(o=r,!/[\p{L}\p{N}]/u.test(o))||a<0)continue;let l=Q(t,i,"left"),c=Q(t,i,"top"),u=Q(t,i,"width"),d=Q(t,i,"height");u<=0||d<=0||s.push({key:[Z(t,i,"page_num"),Z(t,i,"block_num"),Z(t,i,"par_num"),Z(t,i,"line_num")].join(":"),text:r,confidence:a,rect:{x:l,y:c,width:u,height:d}})}let l=new Map;for(let e of s){let t=l.get(e.key);t?t.push(e):l.set(e.key,[e])}return Array.from(l.values()).flatMap(e=>(function(e){let t=[...e].sort((e,t)=>e.rect.x-t.rect.x),n=[],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),a=function(e){let t=1/0,n=1/0,r=-1/0,a=-1/0;for(let i of e)t=Math.min(t,i.x),n=Math.min(n,i.y),r=Math.max(r,i.x+i.width),a=Math.max(a,i.y+i.height);return{x:t,y:n,width:r-t,height:a-n}}(r.map(e=>e.rect)),i=Math.round(100*et(r.map(e=>e.confidence)))/100;return{text:r.map(e=>e.text).join(" "),confidence:i,rect:a,normalizedRect:{x:en(a.x/t),y:en(a.y/n),width:en(a.width/t),height:en(a.height/n)}}})(e,t,n)).filter(e=>null!==e)}function H(e){return o("tesseract",[e,"stdout","-l","eng","tsv"],{allowFailure:!0,timeoutMs:1e4})}function K(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 j(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 W(e){return 2*Math.abs((e.xRange.min+e.xRange.max)/2)+Math.abs((e.yRange.min+e.yRange.max)/2)}function J(e){return{x:e.x+e.width/2,y:e.y+e.height/2}}function Z(e,t,n){let r=t.get(n);return void 0===r?"":e[r]??""}function Q(e,t,n){let r=Number(Z(e,t,n));return Number.isFinite(r)?r:0}function ee(e){return e.trim().replace(/\s+/g," ").toLowerCase()}function et(e){return e.reduce((e,t)=>e+t,0)/e.length}function en(e){return Math.round(100*e*100)/100}function er(e){return Math.round(1e3*e)/1e3}function ea(e,t,n,r){return{r:Math.round(e/r),g:Math.round(t/r),b:Math.round(n/r)}}function ei(e){return .2126*e.r+.7152*e.g+.0722*e.b}function es(e){return`#${eo(e.r)}${eo(e.g)}${eo(e.b)}`}function eo(e){return e.toString(16).padStart(2,"0")}function el(e){return Math.round(100*e*100)/100}let ec=255*Math.sqrt(3);async function eu(r,a,i={}){let s,o,l,c;await ed(r,"Baseline image not found"),await ed(a,"Current screenshot not found");let u=i.outputPath,[d,h]=await Promise.all([e.readFile(r),e.readFile(a)]),f=P(d,"baseline screenshot"),m=P(h,"current screenshot");eh(f.width,f.height,"baseline screenshot",i.maxPixels),eh(m.width,m.height,"current screenshot",i.maxPixels);let p=i.threshold??.1;if(f.width!==m.width||f.height!==m.height){let e=f.width*f.height;return await ef(i.outputPath),{match:!1,mismatchPercentage:100,totalPixels:e,differentPixels:e,dimensionMismatch:{expected:{width:f.width,height:f.height},actual:{width:m.width,height:m.height}}}}let w=f.width*f.height,g=p*ec,b=new n({width:f.width,height:f.height}),x=new Uint8Array(w),y=0;for(let e=0,t=0;e<f.data.length;e+=4,t+=1){if(Math.sqrt((f.data[e]-m.data[e])**2+(f.data[e+1]-m.data[e+1])**2+(f.data[e+2]-m.data[e+2])**2)>g){y+=1,x[t]=1;let n=em(m,e);b.data[e]=ep(n,220,.78),b.data[e+1]=ep(n,0,.78),b.data[e+2]=ep(n,0,.78),b.data[e+3]=255;continue}let n=em(m,e);b.data[e]=n,b.data[e+1]=n,b.data[e+2]=n,b.data[e+3]=255}let v=y>0?(k=(s=function(e){let{diffMask:t,baseline:n,current:r}=e,{width:a,height:i}=n,s=new Uint8Array(t.length),o=new Int32Array(t.length),l=[];for(let e=0;e<t.length;e+=1){if(1!==t[e]||1===s[e])continue;let c=0,u=0;o[0]=e,u+=1,s[e]=1;let d=e%a,h=Math.floor(e/a),f={minX:d,minY:h,maxX:d,maxY:h,differentPixels:0,baselineRed:0,baselineGreen:0,baselineBlue:0,currentRed:0,currentGreen:0,currentBlue:0};for(;c<u;){let e=o[c];c+=1,function(e,t,n,r,a){let i=t%n,s=Math.floor(t/n),o=4*t;e.minX=Math.min(e.minX,i),e.minY=Math.min(e.minY,s),e.maxX=Math.max(e.maxX,i),e.maxY=Math.max(e.maxY,s),e.differentPixels+=1,e.baselineRed+=r.data[o],e.baselineGreen+=r.data[o+1],e.baselineBlue+=r.data[o+2],e.currentRed+=a.data[o],e.currentGreen+=a.data[o+1],e.currentBlue+=a.data[o+2]}(f,e,a,n,r);let l=e%a,d=Math.floor(e/a);for(let e=-1;e<=1;e+=1){let n=d+e;if(!(n<0)&&!(n>=i))for(let r=-1;r<=1;r+=1){if(0===r&&0===e)continue;let i=l+r;if(i<0||i>=a)continue;let c=n*a+i;1===t[c]&&1!==s[c]&&(s[c]=1,o[u]=c,u+=1)}}}l.push(f)}return l}(M={diffMask:x,baseline:f,current:m,totalPixels:w,differentPixels:y,maxRegions:i.maxRegions})).length<=2e3?function(e){let t=[];for(let a 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=a,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({...a});continue}n=e,r=a,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}(s):s,k.flatMap(e=>{var t,n,r;let a;return(t=e,n=M.baseline.width,r=M.baseline.height,a=t.maxX-t.minX+1,t.maxY-t.minY+1>=Math.max(48,Math.round(.07*r))&&a>=.35*n)?function(e,t,n){var r;let a=function(e,t){let n=[],r=null;for(let a=0;a<e.length;a+=1){if(e[a]<=t){r??=a;continue}null!==r&&(a-r>=6&&n.push([r,a-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 a=e.minY;a<=e.maxY;a+=1){let i=0;for(let r=e.minX;r<=e.maxX;r+=1)1===t[a*n+r]&&(i+=1);r.push(i)}return r}(e,t.diffMask,t.baseline.width)).map((e,t)=>{let n=0,a=0,i=Math.max(0,t-3),s=Math.min(r.length-1,t+3);for(let e=i;e<=s;e+=1)n+=r[e],a+=1;return Math.round(n/a)}),Math.max(1,Math.round((e.maxX-e.minX+1)*.08))),i=function(e,t,n){let r=[],a=e.minY;for(let[i,s]of t){let t=e.minY+Math.round((i+s)/2);t-a+1<n||e.maxY-t<n||(r.push([a,t]),a=t+1)}return r.push([a,e.maxY]),r}(e,a,n);if(i.length<=1)return[e];let s=i.map(([n,r])=>(function(e,t,n,r){let a=null;for(let o=t;o<=n;o+=1)for(let t=e.minX;t<=e.maxX;t+=1){var i,s;let e=o*r.baseline.width+t;1===r.diffMask[e]&&function(e,t,n,r,a,i){let s=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+=a.data[s],e.baselineGreen+=a.data[s+1],e.baselineBlue+=a.data[s+2],e.currentRed+=i.data[s],e.currentGreen+=i.data[s+1],e.currentBlue+=i.data[s+2]}(a??={minX:i=t,minY:s=o,maxX:i,maxY:s,differentPixels:0,baselineRed:0,baselineGreen:0,baselineBlue:0,currentRed:0,currentGreen:0,currentBlue:0},e,t,o,r.baseline,r.current)}return a})(e,n,r,t)).filter(e=>null!==e);return s.length>1?s:[e]}(e,M,Math.max(24,Math.round(.03*M.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,M.maxRegions??8)).map((e,t)=>{var n,r,a,i,s,o,l,c,u,d,h;let f,m,p,w,g,b,x,y,v,k,N,I,A,R,S,P,$;return n=e,r=t+1,a={width:M.baseline.width,height:M.baseline.height,totalPixels:M.totalPixels,differentPixels:M.differentPixels},b={x:n.minX,y:n.minY,width:n.maxX-n.minX+1,height:n.maxY-n.minY+1},x={x:Math.round(n.minX+b.width/2),y:Math.round(n.minY+b.height/2)},y=ea(n.baselineRed,n.baselineGreen,n.baselineBlue,n.differentPixels),v=ea(n.currentRed,n.currentGreen,n.currentBlue,n.differentPixels),k=b.width*b.height,N=el(n.differentPixels/k),I=Math.round(ei(y)),A=Math.round(ei(v)),R=(i=b,s=a.width,o=a.height,i.width>=.55*s&&i.height>=.12*o?"large-area":i.width>=2.5*i.height?"horizontal-band":i.height>=2.5*i.width?"vertical-band":"compact"),S=(f=k/a.totalPixels)>=.04?"large":f>=.01?"medium":"small",P=(l=y,c=v,m=ei(l),Math.abs(p=ei(c)-m)>=12?p>0?"brighter":"darker":Math.max(Math.abs(c.r-l.r),Math.abs(c.g-l.g),Math.abs(c.b-l.b))>=12?"color-shift":"mixed"),$=(u=x,d=a.width,h=a.height,w=u.x<d/3?"left":u.x>2*d/3?"right":"center",g=u.y<h/3?"top":u.y>2*h/3?"bottom":"middle","center"===w&&"middle"===g?"center":`${g}-${w}`),{index:r,rect:b,normalizedRect:{x:el(b.x/a.width),y:el(b.y/a.height),width:el(b.width/a.width),height:el(b.height/a.height)},differentPixels:n.differentPixels,shareOfDiffPercentage:el(n.differentPixels/a.differentPixels),densityPercentage:N,shape:R,size:S,location:$,averageBaselineColorHex:es(y),averageCurrentColorHex:es(v),baselineLuminance:I,currentLuminance:A,dominantChange:P}}):[];if(y>0&&u){var M,k,N;for(let e of v)e.rect.width<4||e.rect.height<4||function(e,t){let n=C(t.x,0,e.width-1),r=C(t.y,0,e.height-1),a=C(t.x+t.width-1,0,e.width-1),i=C(t.y+t.height-1,0,e.height-1);for(let t=0;t<2;t+=1){for(let s=n;s<=a;s+=1)_(e,s,r+t,$),_(e,s,i-t,$);for(let s=r;s<=i;s+=1)_(e,n+t,s,$),_(e,a-t,s,$)}}(b,e.rect);await e.mkdir(t.dirname(u),{recursive:!0}),await e.writeFile(u,n.sync.write(b))}else await ef(i.outputPath);let I=y>0?await V({baselinePath:r,currentPath:a,width:f.width,height:f.height}):void 0,A=I&&(I.matches.length>0||(I.movementClusters?.length??0)>0)?{provider:I.provider,baselineBlocks:I.baselineBlocks,currentBlocks:I.currentBlocks,matches:I.matches,...I.movementClusters?{movementClusters:I.movementClusters}:{}}:void 0,R=y>0&&I?(o=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,a;return t=e,r=n,a=10,t.minX-a<=r.maxX&&r.minX-a<=t.maxX&&t.minY-a<=r.maxY&&r.minY-a<=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}(function(e,t,n){let r=new Uint8Array(e.length),a=new Int32Array(e.length),i=[];for(let s=0;s<e.length;s+=1){if(1!==e[s]||1===r[s])continue;let o=0,l=0;a[0]=s,l+=1,r[s]=1;let c=s%t,u=Math.floor(s/t),d={minX:c,minY:u,maxX:c,maxY:u,differentPixels:0};for(;o<l;){let i=a[o];o+=1;let s=i%t,c=Math.floor(i/t);d.minX=Math.min(d.minX,s),d.minY=Math.min(d.minY,c),d.maxX=Math.max(d.maxX,s),d.maxY=Math.max(d.maxY,c),d.differentPixels+=1;for(let i=-1;i<=1;i+=1){let o=c+i;if(!(o<0)&&!(o>=n))for(let n=-1;n<=1;n+=1){if(0===n&&0===i)continue;let c=s+n;if(c<0||c>=t)continue;let u=o*t+c;1===e[u]&&1!==r[u]&&(r[u]=1,a[l]=u,l+=1)}}}i.push(d)}return i}(function(e,t,n,r){let a=new Uint8Array(e);if(!r)return a;for(let e of[...r.baselineBlocksRaw,...r.currentBlocksRaw]){var i;!function(e,t,n,r){let a=G(Math.floor(r.x),0,t-1),i=G(Math.floor(r.y),0,n-1),s=G(Math.ceil(r.x+r.width),0,t),o=G(Math.ceil(r.y+r.height),0,n);for(let n=i;n<o;n+=1)for(let r=a;r<s;r+=1)e[n*t+r]=0}(a,t,n,{x:(i=e.rect).x-8,y:i.y-8,width:i.width+16,height:i.height+16})}return a}((N={diffMask:x,width:f.width,height:f.height,regions:v,ocr:I}).diffMask,N.width,N.height,N.ocr),N.width,N.height)),l=X(N.ocr?.currentBlocksRaw??[]),c=X(N.ocr?.baselineBlocksRaw??[]),o.filter(Y).map(e=>{var t,n,r,a,i,s,o,u,d,h,f;let m,p,w,g,b,x,y,v,M,k;return t=e,n=N,r=l,a=c,g=function(e,t){let n,r=0;for(let a of t){let t=function(e,t){let n=Math.max(e.x,t.x),r=Math.max(e.y,t.y),a=Math.min(e.x+e.width,t.x+t.width),i=Math.min(e.y+e.height,t.y+t.height);return a<=n||i<=r?0:(a-n)*(i-r)}(e,a.rect);t<=r||(r=t,n=a)}return n?.index}(w=q(t),n.regions),b=function(e,t,n){let r=E(e,t);if(r)return F(e,r.blocks);let a=E(e,n);return a?F(e,a.blocks):void 0}(w,r,a),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,a=t.x+t.width/2;return r<a-t.width/2?"leading":r>a+t.width/2?"trailing":e.width>=.35*n?"background":"unknown"}(w,b?.block.rect,n.width),y=(i=w,s=x,o=t.differentPixels,u=n,m=i.width/i.height,p=o/(i.width*i.height),"separator"===s?"separator":"background"===s?"background":"trailing"===s&&m>=1.5&&m<=3.8&&p>=.35?"toggle":"trailing"===s&&i.width<=.06*u.width&&i.height<=.04*u.height?"chevron":"leading"===s&&m>=.55&&m<=1.8?"icon":T(i,u)?"background":"visual"),v={...g?{regionIndex:g}:{},slot:x,likelyKind:y,rect:w},{...g?{regionIndex:g}:{},slot:x,likelyKind:y,rect:w,...b?{nearestText:b.block.text.trim().replace(/^[^\p{L}\p{N}]+/u,"").replace(/^\p{L}\s+/u,"")}:{},score:(d=v,h=t.differentPixels,f=n,M=T(d.rect,f)?-35:0,k=20*!!d.regionIndex,O[d.likelyKind]+D[d.slot]+k+M+Math.min(20,h/200))}}).filter(e=>e.rect.y>=.08*N.height).filter(L).sort((e,t)=>t.score-e.score).slice(0,Math.max(0,N.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=w>0?Math.round(y/w*1e4)/100:0;return{...y>0&&u?{diffPath:u}:{},...v.length>0?{regions:v}:{},...A?{ocr:A}:{},...R.length>0?{nonTextDeltas:R}:{},totalPixels:w,differentPixels:y,mismatchPercentage:S,match:0===y}}async function ed(t,n){try{await e.access(t)}catch{throw new a("INVALID_ARGS",`${n}: ${t}`)}}function eh(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 ef(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 em(e,t){return ep(Math.round(.299*e.data[t]+.587*e.data[t+1]+.114*e.data[t+2]),255,.72)}function ep(e,t,n){return Math.round(e*(1-n)+t*n)}function ew(e){return e.width*e.height}function eg(e){return Math.round(100*e*100)/100}let eb=async(e,t)=>{let n,r,i;if(!t.baseline)throw new a("INVALID_ARGS","diff screenshot requires a baseline image");let s=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),o=t.current??{kind:"live"};if(t.overlayRefs&&!eI(o))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 I(e,t.baseline,{usage:"diff screenshot baseline",field:"baseline"}),c=[];try{let a;a=eI(o)?(r=await ex(e,t)).path:(n=await I(e,o,{usage:"diff screenshot current",field:"current"})).path,i=t.out?await A(e,t.out,{field:"diffPath",ext:".png"}):void 0;let u=await eu(l.path,a,{threshold:s,outputPath:i?.path,maxPixels:e.policy.maxImagePixels});eI(o)&&(u=await ey(e,t,i?.path,u,c));let d=u.diffPath?await i?.publish():void 0;return d&&c.push(d),u.diffPath||await i?.cleanup?.(),{...u,...c.length>0?{artifacts:c}:{}}}catch(e){throw await i?.cleanup?.(),e}finally{await l.cleanup?.(),await n?.cleanup?.(),await r?.cleanup?.()}};async function ex(e,t){let n=await R(e,{prefix:"agent-device-diff-current",ext:".png"});try{await ev(e,t,n.path,eM(t))}catch(e){throw await n.cleanup(),e}return n}async function ey(e,t,n,r,a){var i,s,o,l;if(!t.overlayRefs)return r;if(r.match||r.dimensionMismatch)return n&&await eN(n),r;let c=(i=t,s=n,i.currentOverlayOut?i.currentOverlayOut:i.out?.kind==="path"?{kind:"path",path:ek(s??i.out.path)}:i.out?.kind==="downloadableArtifact"?{kind:"downloadableArtifact",...i.out.clientPath?{clientPath:ek(i.out.clientPath)}:{},...i.out.fileName?{fileName:ek(i.out.fileName)}:{}}:void 0),u=await A(e,c,{field:"currentOverlayPath",ext:".png"});try{let n=await ev(e,t,u.path,{overlayRefs:!0,...eM(t)}),i=await u.publish();return i&&a.push(i),{...r,currentOverlayPath:n.path??u.path,...n.overlayRefs?{currentOverlayRefCount:n.overlayRefs.length}:{},...r.regions&&n.overlayRefs?{regions:(o=r.regions,l=n.overlayRefs,o.map(e=>{var t,n;let r,a=(t=e,n=l,r=ew(t.rect),n.map(e=>{var n,a;let i,s,o,l,c=e.overlayRect,u=(n=t.rect,a=c,i=Math.max(n.x,a.x),s=Math.max(n.y,a.y),o=Math.min(n.x+n.width,a.x+a.width),l=Math.min(n.y+n.height,a.y+a.height),o<=i||l<=s?0:(o-i)*(l-s));return u<=0?null:{ref:e.ref,...e.label?{label:e.label}:{},rect:c,overlayCoveragePercentage:eg(u/ew(c)),regionCoveragePercentage:eg(u/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 a.length>0?{...e,currentOverlayMatches:a}:e}))}:{}}}catch(e){throw await u.cleanup?.(),e}}async function ev(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 eM(e){return e.surface?{surface:e.surface}:{}}function ek(e){let n=t.extname(e),r=n?e.slice(0,-n.length):e;return`${r}.current-overlay${n||".png"}`}async function eN(t){try{await e.unlink(ek(t))}catch(e){var n;if(!("object"==typeof(n=e)&&null!==n&&"code"in n&&"ENOENT"===n.code))throw e}}function eI(e){return"live"===e.kind}function eA(e){var t;let n,r=eR(e.label),a=eR(e.value),i=eR(e.identifier),s=(t=i)&&!/^[\w.]+:id\/[\w.-]+$/i.test(t)&&!/^_?NS:\d+$/i.test(t)?i:"";return(n=eS(e.type??"")).includes("textfield")||n.includes("securetextfield")||n.includes("searchfield")||n.includes("edittext")||n.includes("textview")||n.includes("textarea")?a||r||s:r||a||s}function eR(e){return"string"==typeof e?e.trim():""}function eS(e){let t=e.trim().replace(/XCUIElementType/gi,"").replace(/^AX/,"").toLowerCase(),n=Math.max(t.lastIndexOf("."),t.lastIndexOf("/"));return -1!==n&&(t=t.slice(n+1)),t}function eP(e,t,n,r,a={}){var i,s,o,l,c;let u,d,h=r??e_(e.type??"Element"),f=(u=eA(e),{text:u,isLargeSurface:d=function(e,t){if("text-view"===t||"text-field"===t||"search"===t)return!0;let n=eS(e.type??""),r=`${e.role??""} ${e.subrole??""}`.toLowerCase();return n.includes("textview")||n.includes("textarea")||n.includes("textfield")||n.includes("securetextfield")||n.includes("searchfield")||n.includes("edittext")||r.includes("text area")||r.includes("text field")}(e,h),shouldSummarize:d&&!!(i=u)&&(i.length>80||/[\r\n]/.test(i))}),m=(s=e,o=h,l=a,c=f,l.summarizeTextSurfaces&&c.shouldSummarize&&function(e,t,n){let r=eR(e.label);if(r&&r!==n)return r;let a=eR(e.identifier);if(a&&!eO(a)&&a!==n)return a;switch(t){case"text":case"text-view":return"Text view";case"text-field":return"Text field";case"search":return"Search field";default:return""}}(s,o,c.text)||e$(s,o)),p=" ".repeat(t),w=e.ref?`@${e.ref}`:"",g=(function(e,t,n,r){let a,i=[];if(!1===e.enabled&&i.push("disabled"),!n.summarizeTextSurfaces||(!0===e.selected&&i.push("selected"),eC(t)&&i.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")}(e,t)&&i.push("scrollable"),!r.shouldSummarize))return i;return i.push(`preview:"${((a=r.text.replace(/\s+/g," ").trim()).length<=48?a:`${a.slice(0,45)}...`).replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`),i.push("truncated"),[...new Set(i)]})(e,h,a,f).map(e=>` [${e}]`).join(""),b=m?` "${m}"`:"";return n?`${p}${w} [${h}]${g}`.trimEnd():`${p}${w} [${h}]${b}${g}`.trimEnd()}function e$(e,t){var n,r;let a,i=e.label?.trim();if(i&&(n=t,r=i,("scroll-area"===n||"list"===n||"collection"===n||"table"===n)&&(a=r.trim().toLowerCase())&&/^(vertical|horizontal)\s+scroll\s+bar(?:,?\s*\d+\s+pages?)?$/.test(a)))return"";let s=e.value?.trim();if(eC(t)){if(s)return s;if(i)return i}else if(i)return i;if(s)return s;let o=e.identifier?.trim();return!o||eO(o)&&("group"===t||"image"===t||"list"===t||"collection"===t)?"":o}function e_(e){let t=e.replace(/XCUIElementType/gi,"").toLowerCase(),n=e.includes(".")&&(e.startsWith("android.")||e.startsWith("androidx.")||e.startsWith("com."));switch(t.includes(".")&&(t=t.replace(/^android\.widget\./,"").replace(/^android\.view\./,"").replace(/^android\.webkit\./,"").replace(/^androidx\./,"").replace(/^com\.google\.android\./,"").replace(/^com\.android\./,""),n&&t.includes(".")&&(t=t.slice(t.lastIndexOf(".")+1))),t){case"application":return"application";case"navigationbar":return"navigation-bar";case"tabbar":return"tab-bar";case"button":case"imagebutton":return"button";case"link":return"link";case"cell":return"cell";case"statictext":case"checkedtextview":return"text";case"textfield":case"edittext":return"text-field";case"textview":return n?"text":"text-view";case"textarea":return"text-view";case"switch":return"switch";case"slider":return"slider";case"image":case"imageview":return"image";case"webview":return"webview";case"framelayout":case"linearlayout":case"relativelayout":case"constraintlayout":case"viewgroup":case"view":case"group":return"group";case"listview":case"recyclerview":return"list";case"collectionview":return"collection";case"searchfield":return"search";case"segmentedcontrol":return"segmented-control";case"window":return"window";case"checkbox":return"checkbox";case"radio":return"radio";case"menuitem":return"menu-item";case"toolbar":return"toolbar";case"scrollarea":case"scrollview":case"nestedscrollview":return"scroll-area";case"table":return"table";default:return t||"element"}}function eC(e){return"text-field"===e||"text-view"===e||"search"===e}function eO(e){return/^[\w.]+:id\/[\w.-]+$/i.test(e)}function eD(e,t){let n=e_(e.type??"Element"),r=e$(e,n),a=!1===e.enabled?"disabled":"enabled",i=!0===e.selected?"selected":"unselected",s=!0===e.hittable?"hittable":"not-hittable";return[String(t??e.depth??0),n,r,a,i,s].join("|")}function eL(e,t){return t.flatten?e.map(e=>({text:eP(e,0,!1),comparable:eD(e,0)})):(function(e,t={}){let n=[],r=[];for(let a of e){let e=a.depth??0,i=a.label?.trim()||a.value?.trim()||a.identifier?.trim()||"",s=e_(a.type??"Element");if("group"===s&&!i)continue;for(;n.length>0&&e<=n[n.length-1];)n.pop();let o=n.length;n.push(e),r.push({node:a,depth:o,type:s,text:eP(a,o,!1,s,t)})}return r})(e).map(e=>({text:e.text,comparable:eD(e.node,e.depth)}))}function eT(e,t){return e.get(t)??0}function eE(e,t,n){return t>=e.x&&t<=e.x+e.width&&n>=e.y&&n<=e.y+e.height}function eX(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 eF(e,t,n,r){return Math.max(e,n)<=Math.min(t,r)}function eY(e){return new Map(e.map(e=>[e.index,e]))}function eq(e){return e.label?.trim()||e.value?.trim()||e.identifier?.trim()||""}function eU(e){var t;let n;return t=e.type,!!((n=`${t??""}`.toLowerCase()).includes("scroll")||n.includes("recyclerview")||n.includes("listview")||n.includes("gridview")||n.includes("collectionview"))||"table"===n||`${e.role??""} ${e.subrole??""}`.toLowerCase().includes("scroll")}function eB(e,t,n=eY(t)){var r;if(!e.rect)return!0;let a=eG(e,t,n);return!a||(r=e.rect,eF(r.x,r.x+r.width,a.x,a.x+a.width)&&eF(r.y,r.y+r.height,a.y,a.y+a.height))}function eG(e,t,n=eY(t)){let r=function(e,t){let n="number"==typeof e.parentIndex?t.get(e.parentIndex):void 0,r=new Set;for(;n&&!r.has(n.index);){if(r.add(n.index),n.rect&&eU(n))return n.rect;n="number"==typeof n.parentIndex?t.get(n.parentIndex):void 0}return null}(e,n);return r||function(e,t){let n=l(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)}),a=r.filter(e=>{let t=(e.type??"").toLowerCase();return t.includes("application")||t.includes("window")}),i=eX(a.map(e=>e.rect).filter(e=>eE(e,n.x,n.y)));if(i)return i;let s=eX(a.map(e=>e.rect));if(s)return s;let o=eX(r.map(e=>e.rect).filter(e=>eE(e,n.x,n.y)));return o||null}(t,e.rect??{x:0,y:0,width:0,height:0})}function eV(e,t){return e.y+e.height<=t.y?"above":e.y>=t.y+t.height?"below":null}function ez(e,t,n){let r="number"==typeof e.parentIndex?n.get(e.parentIndex):void 0,a=new Set;for(;r&&!a.has(r.index);){if(a.add(r.index),t.has(r.index)&&eU(r))return r;r="number"==typeof r.parentIndex?n.get(r.parentIndex):void 0}return null}let eH=async(e,t)=>{var n;let r,a,i=await ej(e,t);return await e.sessions.set(eW(t.session,i)),{nodes:i.snapshot.nodes,truncated:i.snapshot.truncated??!1,visibility:function(e){var t;let{nodes:n,backend:r,snapshotRaw:a}=e;if(a||"macos-helper"===(t=r)||"linux-atspi"===t)return{partial:!1,visibleNodeCount:n.length,totalNodeCount:n.length,reasons:[]};let i=function(e){if(0===e.length)return{nodes:e,hiddenCount:0,summaryLines:[]};let t=eY(e),n=new Set,r=[];for(let a of e){if(eB(a,e,t)){!function(e,t,n){let r=e,a=new Set;for(;r&&!a.has(r.index);)a.add(r.index),t.add(r.index),r="number"==typeof r.parentIndex?n.get(r.parentIndex):void 0}(a,n,t);continue}r.push(a)}let a=function(e,t,n,r){let a=new Map,i=new Set;for(let e of t){if(!e.rect)continue;let t=ez(e,n,r);if(!t?.rect)continue;let s=eV(e.rect,t.rect);if(!s)continue;let o=a.get(t.index)??new Set;o.add(s),a.set(t.index,o),i.add(e.index)}return function(e,t,n,r){for(let a of e){let e=function(e){let t=function(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}}(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 i=ez(a,t,n);if(!i)continue;let s=r.get(i.index)??new Set;for(let t of e)s.add(t);r.set(i.index,s)}}(e,n,r,a),{directionsByContainer:a,coveredNodeIndexes:i}}(e,r,n,t),i=0===n.size?e:e.filter(e=>n.has(e.index));return{nodes:i.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,a=!!(!0===e.hiddenContentBelow||n.has("below"))||void 0;return{...e,hiddenContentAbove:r,hiddenContentBelow:a}})(e,a.directionsByContainer)),hiddenCount:0===n.size?0:e.length-i.length,summaryLines:function(e,t,n){let r=new Map;for(let a of e){let e=function(e,t,n){if(!e.rect)return null;let r=eG(e,t,n);return r?eV(e.rect,r):null}(a,t,n);if(!e)continue;let i=r.get(e)??[];i.push(a),r.set(e,i)}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=eq(r);!e||t.has(e)||(t.add(e),n.push(e))}return n})(t).slice(0,3).map(e=>`"${e}"`),a=1===t.length?"interactive item":"interactive items",i=n.length>0?`: ${n.join(", ")}`:"";return[`[off-screen ${e}] ${t.length} ${a}${i}`]})}(r.filter(e=>!a.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")||!!eq(e)}(e)),e,t)}}(n),s=new Set;return i.hiddenCount>0&&s.add("offscreen-nodes"),i.nodes.some(e=>e.hiddenContentAbove)&&s.add("scroll-hidden-above"),i.nodes.some(e=>e.hiddenContentBelow)&&s.add("scroll-hidden-below"),{partial:s.size>0,visibleNodeCount:i.nodes.length,totalNodeCount:n.length,reasons:[...s]}}({nodes:i.snapshot.nodes,backend:i.snapshot.backend,snapshotRaw:t.raw}),...i.warnings.length>0?{warnings:i.warnings}:{},...(r=(n=i).result.appName??n.session?.appName,a=n.result.appBundleId??n.session?.appBundleId,{...r||a?{appName:r??a}:{},...a?{appBundleId:a}:{}})}},eK=async(e,t)=>{let n=await ej(e,t),r=!0===t.interactiveOnly,a=n.session?.snapshot,i=eW(t.session,n);if(!a){let t=function(e,t={}){return eL(e,t).length}(n.snapshot.nodes,{flatten:r});return await e.sessions.set(i),{mode:"snapshot",baselineInitialized:!0,summary:{additions:0,removals:0,unchanged:t},lines:[],...n.warnings.length>0?{warnings:n.warnings}:{}}}let s=function(e,t,n={}){let r=function(e,t){let n=e.length,r=t.length,a=n+r,i=new Map,s=[];i.set(1,0);for(let o=0;o<=a;o+=1){s.push(new Map(i));for(let a=-o;a<=o;a+=2){let l=a===-o||a!==o&&eT(i,a-1)<eT(i,a+1)?eT(i,a+1):eT(i,a-1)+1,c=l-a;for(;l<n&&c<r&&e[l].comparable===t[c].comparable;)l+=1,c+=1;if(i.set(a,l),l>=n&&c>=r)return function(e,t,n,r,a){let i=[],s=r,o=a;for(let r=e.length-1;r>=0;r-=1){let a=e[r],l=s-o,c=l===-r||l!==r&&eT(a,l-1)<eT(a,l+1)?l+1:l-1,u=eT(a,c),d=u-c;for(;s>u&&o>d;)i.push({kind:"unchanged",text:n[o-1].text}),s-=1,o-=1;if(0===r)break;s===u?(i.push({kind:"added",text:n[d].text}),o=d):(i.push({kind:"removed",text:t[u].text}),s=u)}return i.reverse(),i}(s,e,t,n,r)}}return[]}(eL(e,n),eL(t,n)),a={additions:0,removals:0,unchanged:0};for(let e of r)"added"===e.kind&&(a.additions+=1),"removed"===e.kind&&(a.removals+=1),"unchanged"===e.kind&&(a.unchanged+=1);return{summary:a,lines:r}}(a.nodes,n.snapshot.nodes,{flatten:r});return await e.sessions.set(i),{mode:"snapshot",baselineInitialized:!1,summary:s.summary,lines:s.lines,...n.warnings.length>0?{warnings:n.warnings}:{}}};async function ej(e,t){var n,r,i,s,o;let l,c,u,d,h,f;if(!e.backend.captureSnapshot)throw new a("UNSUPPORTED_OPERATION","snapshot is not supported by this backend");let m=t.session??"default",p=await e.sessions.get(m),w=await e.backend.captureSnapshot({session:m,requestId:t.requestId,appId:p?.appId,appBundleId:p?.appBundleId,signal:t.signal??e.signal,metadata:t.metadata},{interactiveOnly:t.interactiveOnly,compact:t.compact,depth:t.depth,scope:t.scope,raw:t.raw}),g=(n=w,r=e,n.snapshot?n.snapshot:{nodes:n.nodes??[],truncated:n.truncated,backend:n.backend,createdAt:eJ(r)}),b=eJ(e);return{snapshot:g,result:w,session:p,warnings:(l=[...(i={result:w,snapshot:g,options:t,session:p,capturedAt:g.createdAt??b,runtimeNow:b}).result.warnings??[]],c=!0===i.options.interactiveOnly,u=i.result.analysis,"android"===i.snapshot.backend&&c&&0===i.snapshot.nodes.length&&u&&(u.rawNodeCount??0)>=12&&(l.push(`Interactive snapshot is empty after filtering ${u.rawNodeCount} raw Android nodes. Likely causes: depth too low, transient route change, or collector filtering.`),"number"==typeof i.options.depth&&"number"==typeof u.maxDepth&&u.maxDepth>=i.options.depth+2&&l.push(`Interactive output is empty at depth ${i.options.depth}; retry without -d.`)),h=!!(d=i.session?.snapshot)&&[i.capturedAt,i.runtimeNow].some(e=>{let t=e-d.createdAt;return t>=0&&t<=2e3}),!i.result.freshness&&d&&h&&(s=d.nodes.length,o=i.snapshot.nodes.length,!(s<12)&&o<=Math.floor(.2*s))&&l.push("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."),f=i.result.freshness,f?.staleAfterRetries&&"android"===i.snapshot.backend&&("stuck-route"===f.reason?l.push(`Recent ${f.action} was followed by a nearly identical snapshot after ${f.retryCount} automatic retr${1===f.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"===f.reason&&l.push("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.")),Array.from(new Set(l)))}}function eW(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}}function eJ(e){return e.clock?.now()??Date.now()}function eZ(e,t,n={}){let r=[],a=y(e.type??""),i=e0(e.identifier),s=e0(e.label),o=e0(e.value),l=e0(h(e)),c="fill"===n.action;i&&r.push(`id=${eQ(i)}`),a&&s&&r.push(c?`role=${eQ(a)} label=${eQ(s)} editable=true`:`role=${eQ(a)} label=${eQ(s)}`),s&&r.push(c?`label=${eQ(s)} editable=true`:`label=${eQ(s)}`),o&&r.push(c?`value=${eQ(o)} editable=true`:`value=${eQ(o)}`),l&&l!==s&&l!==o&&r.push(c?`text=${eQ(l)} editable=true`:`text=${eQ(l)}`),a&&c&&!r.some(e=>e.includes("editable=true"))&&r.push(`role=${eQ(a)} editable=true`);let u=Array.from(new Set(r));return 0===u.length&&a&&u.push(c?`role=${eQ(a)} editable=true`:`role=${eQ(a)}`),0===u.length&&b(e)&&u.push("visible=true"),u}function eQ(e){return JSON.stringify(e)}function e0(e){if(!e)return null;let t=e.trim();return t||null}function e1(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)}function e2(e){return"text"===e||"label"===e||"any"===e}function e5(e,t){return{session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata}}function e3(e){return e.clock?.now()??Date.now()}async function e4(e,t){e.clock?await e.clock.sleep(t):await new Promise(e=>setTimeout(e,t))}async function e8(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 e6(e,t,n={updateSession:!0}){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),s=await e.backend.captureSnapshot(e5(e,t),{interactiveOnly:!1,compact:!1,depth:t.depth,scope:n.scope??t.scope,raw:t.raw}),o=s.snapshot??{nodes:s.nodes??[],truncated:s.truncated,backend:s.backend,createdAt:e3(e)};return n.updateSession&&i&&await e.sessions.set({...i,snapshot:o}),{sessionName:r,session:i,snapshot:o}}async function e7(e,t,n){if(e.backend.readText){let r=await e.backend.readText(e5(e,{session:t.sessionName}),n);if(r.text.trim())return r.text}return eA(n)}function e9(e){return{kind:"selector",selector:e}}function te(e,t={}){return{kind:"ref",ref:e,...t.fallbackLabel?{fallbackLabel:t.fallbackLabel}:{}}}let tt=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 tu(e,t,n);let r=await e6(e,t,{updateSession:!0,scope:e2(n)?t.query:void 0}),i=k(r.snapshot.nodes,n,t.query,{requireRect:!1}).matches[0];if(!i)throw new a("COMMAND_FAILED","find did not match any element");if("exists"===t.action)return{kind:"found",found:!0};let s=`@${i.ref}`;return"get_attrs"===t.action?{kind:"attrs",ref:s,node:i}:{kind:"text",ref:s,text:await e7(e,r,i),node:i}},tn=async(e,t)=>{if("ref"===t.target.kind){let n=await e8(e,t.session),r=function(e,t,n){let r=u(t);if(!r)throw new a("INVALID_ARGS",n.invalidRefMessage);let i=c(e,r)??(n.fallbackLabel.length>0?w(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=eZ(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 e7(e,n,r.node),node:r.node,selectorChain:i}}let n=await tm(e,t,t.session??"default",{selector:t.target.selector,disambiguateAmbiguous:"text"===t.property}),r=eZ(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 e7(e,n.capture,n.node);return{kind:"text",target:{kind:"selector",selector:n.selector},text:i,node:n.node,selectorChain:r}},tr=async(e,t)=>{let n=await tn(e,{...t,property:"text",target:t.target});if("text"!==n.kind)throw new a("COMMAND_FAILED","getText returned non-text result");return n},ta=async(e,t)=>{let n=await tn(e,{...t,property:"attrs",target:t.target});if("attrs"!==n.kind)throw new a("COMMAND_FAILED","getAttrs returned non-attrs result");return n},ti=async(e,t)=>{if(!["visible","hidden","exists","editable","selected","text"].includes(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 e6(e,t,{updateSession:!0}),r=p(t.selector);if("exists"===t.predicate){let i=d(n.snapshot.nodes,r,{platform:e.backend.platform});if(!i)throw new a("COMMAND_FAILED",x(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=m(n.snapshot.nodes,r,{platform:e.backend.platform,requireRect:!1,requireUnique:!0,disambiguateAmbiguous:!1});if(!i)throw new a("COMMAND_FAILED",x(r,[],{unique:!0}));let s=function(e){let{predicate:t,node:n,nodes:r,expectedText:a,platform:i}=e,s=h(n),o=v(n,i),l=!0===n.selected,c="text"===t?b(n):function(e,t){if(!0===e.hittable)return!0;if(e1(e.rect))return eB(e,t);if(e.rect)return!1;let n=function(e,t){let n=new Map(t.map(e=>[e.index,e])),r=e,a=new Set;for(;"number"==typeof r.parentIndex&&!a.has(r.index);){a.add(r.index);let e=n.get(r.parentIndex);if(!e)break;if(function(e){let t=y(e.type??"");return!(t.includes("application")||t.includes("window")||t.includes("scrollview")||t.includes("tableview")||t.includes("collectionview"))&&"table"!==t&&"list"!==t&&"listview"!==t&&(!0===e.hittable||e1(e.rect))}(e))return e;r=e}return null}(e,t);return!!n&&(!0===n.hittable||!!e1(n.rect)&&eB(n,t))}(n,r),u=!1;switch(t){case"visible":u=c;break;case"hidden":u=!c;break;case"editable":u=o;break;case"selected":u=l;break;case"text":u=s===(a??"")}let d="text"===t?`expected="${a??""}" actual="${s}"`:`actual=${JSON.stringify({visible:c,editable:o,selected:l})}`;return{pass:u,actualText:s,details:d}}({predicate:t.predicate,node:i.node,nodes:n.snapshot.nodes,expectedText:t.expectedText,platform:e.backend.platform});if(!s.pass)throw new a("COMMAND_FAILED",`is ${t.predicate} failed for selector ${i.selector.raw}: ${s.details}`);return{predicate:t.predicate,pass:!0,selector:i.selector.raw,..."text"===t.predicate?{text:s.actualText}:{},selectorChain:r.selectors.map(e=>e.raw)}},ts=async(e,t)=>await ti(e,{...t,predicate:"visible",selector:t.target.selector}),to=async(e,t)=>await ti(e,{...t,predicate:"hidden",selector:t.target.selector}),tl=async(e,t)=>{if("sleep"===t.target.kind)return await e4(e,t.target.durationMs),{kind:"sleep",waitedMs:t.target.durationMs};if("ref"===t.target.kind){let n=await e8(e,t.session),r=u(t.target.ref);if(!r)throw new a("INVALID_ARGS",`Invalid ref: ${t.target.ref}`);let i=c(n.snapshot.nodes,r),s=i?g(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 th(e,t,s,t.target.timeoutMs)}if("selector"===t.target.kind)return await td(e,t,t.target.selector,t.target.timeoutMs);if(!t.target.text)throw new a("INVALID_ARGS","wait requires text");return await th(e,t,t.target.text,t.target.timeoutMs)},tc=async(e,t)=>{let n=await tl(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 tu(e,t,n){let r=t.timeoutMs??1e4,i=e3(e);for(;e3(e)-i<r;){if(k((await e6(e,t,{updateSession:!0,scope:e2(n)?t.query:void 0})).snapshot.nodes,n,t.query,{requireRect:!1}).matches[0])return{kind:"found",found:!0,waitedMs:e3(e)-i};await e4(e,300)}throw new a("COMMAND_FAILED","find wait timed out")}async function td(e,t,n,r){let i=r??1e4,s=e3(e),o=p(n);for(;e3(e)-s<i;){let n=d((await e6(e,t,{updateSession:!0})).snapshot.nodes,o,{platform:e.backend.platform});if(n)return{kind:"selector",selector:n.selector.raw,waitedMs:e3(e)-s};await e4(e,300)}throw new a("COMMAND_FAILED",`wait timed out for selector: ${n}`)}async function th(e,t,n,r){let i=r??1e4,s=e3(e);for(;e3(e)-s<i;){if(e.backend.findText?(await e.backend.findText(e5(e,t),n)).found:await tf(e,t,n))return{kind:"text",text:n,waitedMs:e3(e)-s};await e4(e,300)}throw new a("COMMAND_FAILED",`wait timed out for text: ${n}`)}async function tf(e,t,n){return!!w((await e6(e,t,{updateSession:!0})).snapshot.nodes,n)}async function tm(e,t,n,r){let i=await e6(e,{...t,session:n},{updateSession:!0}),s=p(r.selector),o=m(i.snapshot.nodes,s,{platform:e.backend.platform,requireRect:!1,requireUnique:!0,disambiguateAmbiguous:r.disambiguateAmbiguous});if(!o)throw new a("COMMAND_FAILED",x(s,[],{unique:!0}));return{capture:i,node:o.node,selector:o.selector.raw,ref:`@${o.node.ref}`}}function tp(e,t){let n=function(e,t){let n=tg(t.rect);if(!n)return null;let r=t,a=new Set;for(;!a.has(r.ref);){a.add(r.ref);let t=e.filter(e=>{if(e.parentIndex!==r.index||!e.hittable)return!1;let t=tg(e.rect);return!!t&&tb(t,n)});if(1!==t.length)break;r=t[0]}return r===t?null:r}(e,t);if(n?.rect&&tw(n.rect))return n;let r=f(e,t);return r?.rect&&tw(r.rect)?!function(e,t,n){var r,a,i,s;let o,c,u,d=tg(e.rect),h=tg(t.rect);if(!d||!h)return!1;let f=function(e,t){let n=l(t),r=e.filter(e=>{let t=(e.type??"").toLowerCase();return t.includes("application")||t.includes("window")}).map(e=>tg(e.rect)).filter(e=>null!==e);if(0===r.length)return null;let a=r.filter(e=>eE(e,n.x,n.y));return eX(a.length>0?a:r)}(n,d);return!!f&&(r=h,a=f,o=(i=r,s=a,Math.max(0,Math.min(i.x+i.width,s.x+s.width)-Math.max(i.x,s.x))*Math.max(0,Math.min(i.y+i.height,s.y+s.height)-Math.max(i.y,s.y))),c=r.width*r.height,u=a.width*a.height,!(o<=0)&&!(c<=0)&&!(u<=0)&&!!(o/u>=.9)&&!!(o/c>=.8))&&!tb(d,h)}(t,r,e)?r:t:t}function tw(e){let t=tg(e);if(!t)return null;let n=l(t);return Number.isFinite(n.x)&&Number.isFinite(n.y)?n:null}function tg(e){if(!e)return null;let t=Number(e.x),n=Number(e.y),r=Number(e.width),a=Number(e.height);return Number.isFinite(t)&&Number.isFinite(n)&&Number.isFinite(r)&&Number.isFinite(a)&&!(r<0)&&!(a<0)?{x:t,y:n,width:r,height:a}:null}function tb(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)}let tx=async(e,t)=>await tv(e,t,"press"),ty=async(e,t)=>await tv(e,t,"click");async function tv(e,t,n){let r=await tN(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=await e.backend.tap(e5(e,t),r.point,{button:t.button,count:t.count,intervalMs:t.intervalMs,holdMs:t.holdMs,jitterPx:t.jitterPx,doubleTap:t.doubleTap});return{...r,...tC(i)?{backendResult:tC(i)}:{}}}let tM=async(e,t)=>{var n;if(!t.text)throw new a("INVALID_ARGS","fill requires text");let r=await tN(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=await e.backend.fill(e5(e,t),r.point,t.text,{delayMs:t.delayMs}),s="node"in r?r.node.type??"":"",o=s&&!M(s,e.backend.platform)?`fill target ${n=r,n.target?.kind==="ref"?n.target.ref:n.target?.kind==="selector"?n.target.selector:"point"} resolved to "${s}", attempting fill anyway.`:void 0;return{...r,text:t.text,...o?{warning:o}:{},...tC(i)?{backendResult:tC(i)}:{}}},tk=async(e,t)=>{var n;let r=t.text;if(!r)throw new a("INVALID_ARGS","type requires text");let i=function(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}(r);if(i)throw new a("INVALID_ARGS",`type does not accept a target ref like "${i}"`,{hint:`Use fill ${i} "text" to target that field, or press ${i} then type "text" to append.`});if(!e.backend.typeText)throw new a("UNSUPPORTED_OPERATION","type is not supported by this backend");let s=function(e,t){if(!Number.isFinite(e)||!Number.isInteger(e)||e<0||e>1e4)throw new a("INVALID_ARGS",`${t} must be an integer between 0 and 10000`);return e}(t.delayMs??0,"delay-ms"),o=await e.backend.typeText(e5(e,t),r,{delayMs:s}),l=(n=r,`Typed ${Array.from(n).length} chars`);return{kind:"text",text:r,delayMs:s,...tC(o)?{backendResult:tC(o)}:{},...N(l)}};async function tN(e,t,n){if(await tI(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 tS(e,t,t.target),i=r.resolved,s=n.promoteToHittableAncestor?tp(r.snapshot.nodes,i.node):i.node;return function(e,t,n,r){let i=e.rect?eG(e,t):null;if(!(!e.rect||!i||eB(e,t)))throw new a("COMMAND_FAILED",`Ref ${n} is off-screen and not safe to ${r}`,{reason:"offscreen_ref",ref:u(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:t$(s,`Ref ${t.target.ref} not found or has invalid bounds`),target:{kind:"ref",ref:`@${i.ref}`},node:s,selectorChain:eZ(s,e.backend.platform,{action:"fill"===n.action?"fill":"click"}),refLabel:g(s,r.snapshot.nodes)}}let r=await tR(e,t,n.requireInteractive),i=p(t.target.selector),s=m(r.snapshot.nodes,i,{platform:e.backend.platform,requireRect:!0,requireUnique:!0,disambiguateAmbiguous:!0});if(!s||!s.node.rect)throw new a("COMMAND_FAILED",x(i,s?.diagnostics??[],{unique:!0}));let o=n.promoteToHittableAncestor?tp(r.snapshot.nodes,s.node):s.node;return{kind:"selector",point:t$(o,`Selector ${s.selector.raw} resolved to invalid bounds`),target:{kind:"selector",selector:s.selector.raw},node:o,selectorChain:eZ(o,e.backend.platform,{action:"fill"===n.action?"fill":"click"}),refLabel:g(o,r.snapshot.nodes)}}async function tI(e,t,n){if("macos"!==e.backend.platform)return;let r=await tA(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 tA(e,t){let n=await e.sessions.get(t.session??"default");return n?.metadata?.surface}async function tR(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 s=await e.backend.captureSnapshot(e5(e,t),{interactiveOnly:n,compact:n}),o=s.snapshot??{nodes:s.nodes??[],truncated:s.truncated,backend:s.backend,createdAt:e3(e)};return await e.sessions.set({...i,snapshot:o}),{snapshot:o}}async function tS(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 s=n.fallbackLabel??"",o=tP(i.snapshot.nodes,n.ref,{fallbackLabel:s,requireRect:!0});if(o)return{snapshot:i.snapshot,resolved:o};let l=await tR(e,t,!0),c=tP(l.snapshot.nodes,n.ref,{fallbackLabel:s,requireRect:!0});if(!c)throw new a("COMMAND_FAILED",`Ref ${n.ref} not found or has no bounds`);return{...l,resolved:c}}function tP(e,t,n){let r=u(t);if(!r)throw new a("INVALID_ARGS",`Invalid ref: ${t}`);let i=c(e,r);if(t_(i,n.requireRect))return{ref:r,node:i};let s=n.fallbackLabel.length>0?w(e,n.fallbackLabel):null;return t_(s,n.requireRect)?{ref:r,node:s}:null}function t$(e,t){if(!e.rect)throw new a("COMMAND_FAILED",t);let n=l(e.rect);if(!Number.isFinite(n.x)||!Number.isFinite(n.y))throw new a("COMMAND_FAILED",t);return n}function t_(e,t){if(!e)return!1;if(!t)return!0;if(!e.rect)return!1;let{x:n,y:r,width:a,height:i}=e.rect;if(!Number.isFinite(Number(n))||!Number.isFinite(Number(r))||!Number.isFinite(Number(a))||!Number.isFinite(Number(i))||0>Number(a)||0>Number(i))return!1;let s=l(e.rect);return Number.isFinite(s.x)&&Number.isFinite(s.y)}function tC(e){return e&&"object"==typeof e?e:void 0}let tO=[{command:"screenshot",category:"portable-runtime",status:"implemented"},{command:"diff screenshot",category:"portable-runtime",status:"implemented"},{command:"snapshot",category:"portable-runtime",status:"implemented"},{command:"diff snapshot",category:"portable-runtime",status:"implemented"},{command:"find read-only",category:"portable-runtime",status:"implemented"},{command:"get",category:"portable-runtime",status:"implemented"},{command:"is",category:"portable-runtime",status:"implemented"},{command:"wait",category:"portable-runtime",status:"implemented"},{command:"alert",category:"portable-runtime",status:"planned"},{command:"click",category:"portable-runtime",status:"implemented"},{command:"press",category:"portable-runtime",status:"implemented"},{command:"fill",category:"portable-runtime",status:"implemented"},{command:"longpress",category:"portable-runtime",status:"planned"},{command:"swipe",category:"portable-runtime",status:"planned"},{command:"focus",category:"portable-runtime",status:"planned"},{command:"type",category:"portable-runtime",status:"implemented"},{command:"scroll",category:"portable-runtime",status:"planned"},{command:"pinch",category:"portable-runtime",status:"planned"},{command:"open",category:"portable-runtime",status:"planned"},{command:"close",category:"portable-runtime",status:"planned"},{command:"apps",category:"portable-runtime",status:"planned"},{command:"appstate",category:"portable-runtime",status:"planned"},{command:"back",category:"portable-runtime",status:"planned"},{command:"home",category:"portable-runtime",status:"planned"},{command:"rotate",category:"portable-runtime",status:"planned"},{command:"app-switcher",category:"portable-runtime",status:"planned"},{command:"keyboard",category:"portable-runtime",status:"planned"},{command:"clipboard",category:"portable-runtime",status:"planned"},{command:"settings",category:"portable-runtime",status:"planned"},{command:"push",category:"portable-runtime",status:"planned"},{command:"trigger-app-event",category:"portable-runtime",status:"planned"},{command:"devices",category:"backend-admin",status:"planned"},{command:"boot",category:"backend-admin",status:"planned"},{command:"ensure-simulator",category:"backend-admin",status:"planned"},{command:"install",category:"backend-admin",status:"planned"},{command:"reinstall",category:"backend-admin",status:"planned"},{command:"install-from-source",category:"backend-admin",status:"planned"},{command:"session",category:"transport-session",status:"planned"},{command:"connect",category:"environment",status:"planned"},{command:"disconnect",category:"environment",status:"planned"},{command:"connection",category:"environment",status:"planned"},{command:"metro",category:"environment",status:"planned"},{command:"record",category:"capability-gated",status:"planned"},{command:"trace",category:"capability-gated",status:"planned"},{command:"replay",category:"capability-gated",status:"planned"},{command:"test",category:"capability-gated",status:"planned"},{command:"batch",category:"capability-gated",status:"planned"},{command:"logs",category:"capability-gated",status:"planned"},{command:"network",category:"capability-gated",status:"planned"},{command:"perf",category:"capability-gated",status:"planned"}];function tD(e){return{dispatch:async t=>{try{(function(e){if(tL.has(e.command))return;let t=tO.find(t=>t.command===e.command);if(t?.status==="planned")throw new a("NOT_IMPLEMENTED",`Command ${e.command} is planned but not implemented in the runtime router yet`,{command:e.command});throw new a("UNSUPPORTED_OPERATION",`Unknown runtime command: ${e.command}`,{command:e.command})})(t),await e.beforeDispatch?.(t);let n=await e.createRuntime(t);return{ok:!0,data:await tT(n,t)}}catch(n){return{ok:!1,error:e.formatError?.(n,t)??i(n)}}}}}let tL=new Set(["capture.screenshot","capture.diffScreenshot","capture.snapshot","capture.diffSnapshot","selectors.find","selectors.get","selectors.is","selectors.wait","interactions.click","interactions.press","interactions.fill","interactions.typeText"]);async function tT(e,t){switch(t.command){case"capture.screenshot":return await S(e,t.options);case"capture.diffScreenshot":return await eb(e,t.options);case"capture.snapshot":return await eH(e,t.options);case"capture.diffSnapshot":return await eK(e,t.options);case"selectors.find":return await tt(e,t.options);case"selectors.get":return await tn(e,t.options);case"selectors.is":return await ti(e,t.options);case"selectors.wait":return await tl(e,t.options);case"interactions.click":return await ty(e,t.options);case"interactions.press":return await tx(e,t.options);case"interactions.fill":return await tM(e,t.options);case"interactions.typeText":return await tk(e,t.options)}}let tE={capture:{screenshot:S,diffScreenshot:eb,snapshot:eH,diffSnapshot:eK},selectors:{find:tt,get:tn,getText:tr,getAttrs:ta,is:ti,isVisible:ts,isHidden:to,wait:tl,waitForText:tc},interactions:{click:ty,press:tx,fill:tM,typeText:tk}};function tX(e){return{capture:{screenshot:t=>tE.capture.screenshot(e,t),diffScreenshot:t=>tE.capture.diffScreenshot(e,t),snapshot:t=>tE.capture.snapshot(e,t),diffSnapshot:t=>tE.capture.diffSnapshot(e,t)},selectors:{find:t=>tE.selectors.find(e,t),get:t=>tE.selectors.get(e,t),getText:(t,n={})=>tE.selectors.getText(e,{...n,target:t}),getAttrs:(t,n={})=>tE.selectors.getAttrs(e,{...n,target:t}),is:t=>tE.selectors.is(e,t),isVisible:(t,n={})=>tE.selectors.isVisible(e,{...n,target:t}),isHidden:(t,n={})=>tE.selectors.isHidden(e,{...n,target:t}),wait:t=>tE.selectors.wait(e,t),waitForText:(t,n={})=>tE.selectors.waitForText(e,{...n,text:t})},interactions:{click:(t,n={})=>tE.interactions.click(e,{...n,target:t}),press:(t,n={})=>tE.interactions.press(e,{...n,target:t}),fill:(t,n,r={})=>tE.interactions.fill(e,{...r,target:t,text:n}),typeText:(t,n={})=>tE.interactions.typeText(e,{...n,text:t})}}}export{tX as bindCommands,tO as commandCatalog,tE as commands,tD as createCommandRouter,e9 as selector,te as ref};
1
+ import{promises as e}from"node:fs";import t from"node:path";import{PNG as n}from"pngjs";import{asAppError as a,AppError as r,normalizeAgentDeviceError as i}from"../152.js";import{whichCmd as s,runCmd as o}from"../818.js";import{centerOfRect as l,findNodeByRef as c,normalizeRef as d}from"../57.js";import{findSelectorChainMatch as u,extractNodeText as p,findNearestHittableAncestor as m,resolveSelectorChain as h,parseSelectorChain as f,findNodeByLabel as w,resolveRefLabel as b,isNodeVisible as g,formatSelectorFailure as y,normalizeType as x,isNodeEditable as k,isFillableType as v}from"../selectors.js";import{findBestMatchesByLocator as A}from"../556.js";function I(e){return e?{message:e}:{}}async function N(e,t,n){if("path"===t.kind&&!e.policy.allowLocalInputPaths)throw new r("INVALID_ARGS",`Local ${n.field??"input"} paths are not allowed by command policy`);try{return await e.artifacts.resolveInput(t,n)}catch(e){throw a(e)}}async function R(e,t,n){if(t?.kind==="path"&&!e.policy.allowLocalOutputPaths)throw new r("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 a(e)}}async function M(e,t){try{return await e.artifacts.createTempFile(t)}catch(e){throw a(e)}}let S=async(e,t)=>{let n;if(!e.backend.captureScreenshot)throw new r("UNSUPPORTED_OPERATION","screenshot is not supported by this backend");let a=await R(e,t.out,{field:"path",ext:".png"});try{await e.backend.captureScreenshot({session:t.session,requestId:t.requestId,appId:t.appId,appBundleId:t.appBundleId,signal:t.signal??e.signal,metadata:t.metadata},a.path,{fullscreen:t.fullscreen,overlayRefs:t.overlayRefs,surface:t.surface}),n=await a.publish()}catch(e){throw await a.cleanup?.(),e}return{path:a.path,...n?{artifacts:[n]}:{},...I(`Saved screenshot: ${a.path}`)}};function P(e,t){try{return n.sync.read(e)}catch(e){throw new r("COMMAND_FAILED",`Failed to decode ${t} as PNG`,{label:t,reason:e instanceof Error?e.message:String(e)})}}let O=[0,187,255,255];function D(e,t,n,a){if(t<0||t>=e.width||n<0||n>=e.height)return;let r=(n*e.width+t)*4;e.data[r]=a[0],e.data[r+1]=a[1],e.data[r+2]=a[2],e.data[r+3]=a[3]}function _(e,t,n){return Math.min(Math.max(e,t),n)}let $={icon:90,toggle:90,chevron:75,separator:45,visual:35,background:10},E={leading:20,trailing:20,separator:10,unknown:0,background:-30};function T(e){return"background"!==e.likelyKind}function L(e,t){return e.width>=.25*t.width||e.height>=.06*t.height}function C(e,t){let n,a=0;for(let r of t){let t=X(e,r.rect);t<=a||(a=t,n=r)}return n}function U(e){let t=[];for(let n of[...e].sort((e,t)=>e.rect.y-t.rect.y)){let e=t.find(e=>{var t,a;return t=e.rect,X(t,a=n.rect)>0||Math.abs(V(t).y-V(a).y)<=.5*Math.max(t.height,a.height)});if(!e){t.push({rect:n.rect,blocks:[n]});continue}e.blocks.push(n),e.blocks.sort((e,t)=>e.rect.x-t.rect.x),e.rect=function(e){let t=1/0,n=1/0,a=-1/0,r=-1/0;for(let i of e)t=Math.min(t,i.x),n=Math.min(n,i.y),a=Math.max(a,i.x+i.width),r=Math.max(r,i.y+i.height);return{x:t,y:n,width:a-t,height:r-n}}([e.rect,n.rect])}return t}function F(e,t){let n,a=V(e);for(let e of t){var r,i;let t=Math.sqrt((r=a,i=V(e.rect),(r.x-i.x)**2+(r.y-i.y)**2));n&&t>=n.distance||(n={block:e,distance:t})}return n}function q(e){let t=G(e);return e.differentPixels>=24&&t.width>=3&&t.height>=3}function G(e){return{x:e.minX,y:e.minY,width:e.maxX-e.minX+1,height:e.maxY-e.minY+1}}function X(e,t){return Math.max(0,Math.min(e.y+e.height,t.y+t.height)-Math.max(e.y,t.y))}function V(e){return{x:e.x+e.width/2,y:e.y+e.height/2}}function Y(e,t,n){return Math.min(Math.max(e,t),n)}async function B(e){if(await s("tesseract"))try{let[t,n]=await Promise.all([H(e.baselinePath),H(e.currentPath)]);if(0!==t.exitCode||0!==n.exitCode)return;let a=j(t.stdout,e.width,e.height),r=j(n.stdout,e.width,e.height),i=function(e,t){let n=new Set,a=[];for(let i of e){var r;let e=ee(i.text),s=function(e,t,n,a){let r=null,i=1/0;for(let l=0;l<n.length;l+=1){var s,o;if(a.has(l))continue;let c=n[l];if(ee(c.text)!==t)continue;let d=(s=J(e.normalizedRect),o=J(c.normalizedRect),(s.x-o.x)**2+(s.y-o.y)**2);d>=i||(r=l,i=d)}return r}(i,e,t,n);if(null===s)continue;n.add(s);let o=function(e,t){let n={x:t.rect.x-e.rect.x,y:t.rect.y-e.rect.y,width:t.rect.width-e.rect.width,height:t.rect.height-e.rect.height},a=ea(t.rect.width/e.rect.width),r=ea(t.rect.height/e.rect.height),i=Math.abs(a-1)>=.08||Math.abs(r-1)>=.12;return{text:e.text,baselineRect:e.rect,currentRect:t.rect,delta:n,confidence:Math.round(100*Math.min(e.confidence,t.confidence))/100,possibleTextMetricMismatch:i}}(i,t[s]);r=o,(Math.abs(r.delta.x)>=2||Math.abs(r.delta.y)>=2||Math.abs(r.delta.width)>=2||Math.abs(r.delta.height)>=2||r.possibleTextMetricMismatch)&&a.push(o)}return a.sort((e,t)=>K(t)-K(e)).slice(0,12)}(a,r),s=function(e){let t=[];for(let n of[...e].sort((e,t)=>e.currentRect.y-t.currentRect.y)){let e=t.find(e=>32>=Math.abs(n.delta.x-et(e.map(e=>e.delta.x))));e?e.push(n):t.push([n])}return t.filter(e=>e.length>=2).map(z).filter(e=>e.yRange.max-e.yRange.min<=60).sort((e,t)=>W(t)-W(e)).slice(0,4)}(i);if(0===a.length&&0===r.length)return;return{provider:"tesseract",baselineBlocks:a.length,currentBlocks:r.length,baselineBlocksRaw:a,currentBlocksRaw:r,matches:i,...s.length>0?{movementClusters:s}:{}}}catch{return}}function j(e,t,n){let[a,...r]=e.split(/\r?\n/);if(!a)return[];let i=new Map(a.split(" ").map((e,t)=>[e,t])),s=[];for(let e of r){var o;if(!e.trim())continue;let t=e.split(" "),n=Q(t,i,"level"),a=Z(t,i,"text").trim(),r=Q(t,i,"conf");if(5!==n||(o=a,!/[\p{L}\p{N}]/u.test(o))||r<0)continue;let l=Q(t,i,"left"),c=Q(t,i,"top"),d=Q(t,i,"width"),u=Q(t,i,"height");d<=0||u<=0||s.push({key:[Z(t,i,"page_num"),Z(t,i,"block_num"),Z(t,i,"par_num"),Z(t,i,"line_num")].join(":"),text:a,confidence:r,rect:{x:l,y:c,width:d,height:u}})}let l=new Map;for(let e of s){let t=l.get(e.key);t?t.push(e):l.set(e.key,[e])}return Array.from(l.values()).flatMap(e=>(function(e){let t=[...e].sort((e,t)=>e.rect.x-t.rect.x),n=[],a=[];for(let e of t){let t=a.at(-1);if(!t){a.push(e);continue}if(e.rect.x-(t.rect.x+t.rect.width)>Math.max(48,2.5*Math.max(t.rect.height,e.rect.height))){n.push(a),a=[e];continue}a.push(e)}return a.length>0&&n.push(a),n})(e)).map(e=>(function(e,t,n){if(0===e.length)return null;let a=[...e].sort((e,t)=>e.rect.x-t.rect.x),r=function(e){let t=1/0,n=1/0,a=-1/0,r=-1/0;for(let i of e)t=Math.min(t,i.x),n=Math.min(n,i.y),a=Math.max(a,i.x+i.width),r=Math.max(r,i.y+i.height);return{x:t,y:n,width:a-t,height:r-n}}(a.map(e=>e.rect)),i=Math.round(100*et(a.map(e=>e.confidence)))/100;return{text:a.map(e=>e.text).join(" "),confidence:i,rect:r,normalizedRect:{x:en(r.x/t),y:en(r.y/n),width:en(r.width/t),height:en(r.height/n)}}})(e,t,n)).filter(e=>null!==e)}function H(e){return o("tesseract",[e,"stdout","-l","eng","tsv"],{allowFailure:!0,timeoutMs:1e4})}function K(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 z(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 W(e){return 2*Math.abs((e.xRange.min+e.xRange.max)/2)+Math.abs((e.yRange.min+e.yRange.max)/2)}function J(e){return{x:e.x+e.width/2,y:e.y+e.height/2}}function Z(e,t,n){let a=t.get(n);return void 0===a?"":e[a]??""}function Q(e,t,n){let a=Number(Z(e,t,n));return Number.isFinite(a)?a:0}function ee(e){return e.trim().replace(/\s+/g," ").toLowerCase()}function et(e){return e.reduce((e,t)=>e+t,0)/e.length}function en(e){return Math.round(100*e*100)/100}function ea(e){return Math.round(1e3*e)/1e3}function er(e,t,n,a){return{r:Math.round(e/a),g:Math.round(t/a),b:Math.round(n/a)}}function ei(e){return .2126*e.r+.7152*e.g+.0722*e.b}function es(e){return`#${eo(e.r)}${eo(e.g)}${eo(e.b)}`}function eo(e){return e.toString(16).padStart(2,"0")}function el(e){return Math.round(100*e*100)/100}let ec=255*Math.sqrt(3);async function ed(a,r,i={}){let s,o,l,c;await eu(a,"Baseline image not found"),await eu(r,"Current screenshot not found");let d=i.outputPath,[u,p]=await Promise.all([e.readFile(a),e.readFile(r)]),m=P(u,"baseline screenshot"),h=P(p,"current screenshot");ep(m.width,m.height,"baseline screenshot",i.maxPixels),ep(h.width,h.height,"current screenshot",i.maxPixels);let f=i.threshold??.1;if(m.width!==h.width||m.height!==h.height){let e=m.width*m.height;return await em(i.outputPath),{match:!1,mismatchPercentage:100,totalPixels:e,differentPixels:e,dimensionMismatch:{expected:{width:m.width,height:m.height},actual:{width:h.width,height:h.height}}}}let w=m.width*m.height,b=f*ec,g=new n({width:m.width,height:m.height}),y=new Uint8Array(w),x=0;for(let e=0,t=0;e<m.data.length;e+=4,t+=1){if(Math.sqrt((m.data[e]-h.data[e])**2+(m.data[e+1]-h.data[e+1])**2+(m.data[e+2]-h.data[e+2])**2)>b){x+=1,y[t]=1;let n=eh(h,e);g.data[e]=ef(n,220,.78),g.data[e+1]=ef(n,0,.78),g.data[e+2]=ef(n,0,.78),g.data[e+3]=255;continue}let n=eh(h,e);g.data[e]=n,g.data[e+1]=n,g.data[e+2]=n,g.data[e+3]=255}let k=x>0?(A=(s=function(e){let{diffMask:t,baseline:n,current:a}=e,{width:r,height:i}=n,s=new Uint8Array(t.length),o=new Int32Array(t.length),l=[];for(let e=0;e<t.length;e+=1){if(1!==t[e]||1===s[e])continue;let c=0,d=0;o[0]=e,d+=1,s[e]=1;let u=e%r,p=Math.floor(e/r),m={minX:u,minY:p,maxX:u,maxY:p,differentPixels:0,baselineRed:0,baselineGreen:0,baselineBlue:0,currentRed:0,currentGreen:0,currentBlue:0};for(;c<d;){let e=o[c];c+=1,function(e,t,n,a,r){let i=t%n,s=Math.floor(t/n),o=4*t;e.minX=Math.min(e.minX,i),e.minY=Math.min(e.minY,s),e.maxX=Math.max(e.maxX,i),e.maxY=Math.max(e.maxY,s),e.differentPixels+=1,e.baselineRed+=a.data[o],e.baselineGreen+=a.data[o+1],e.baselineBlue+=a.data[o+2],e.currentRed+=r.data[o],e.currentGreen+=r.data[o+1],e.currentBlue+=r.data[o+2]}(m,e,r,n,a);let l=e%r,u=Math.floor(e/r);for(let e=-1;e<=1;e+=1){let n=u+e;if(!(n<0)&&!(n>=i))for(let a=-1;a<=1;a+=1){if(0===a&&0===e)continue;let i=l+a;if(i<0||i>=r)continue;let c=n*r+i;1===t[c]&&1!==s[c]&&(s[c]=1,o[d]=c,d+=1)}}}l.push(m)}return l}(v={diffMask:y,baseline:m,current:h,totalPixels:w,differentPixels:x,maxRegions:i.maxRegions})).length<=2e3?function(e){let t=[];for(let r of e.sort((e,t)=>{let n=e.minY-t.minY;return 0!==n?n:e.minX-t.minX})){var n,a;let e=t.find(e=>{var t,n,a;return t=e,n=r,a=12,t.minX-a<=n.maxX&&n.minX-a<=t.maxX&&t.minY-a<=n.maxY&&n.minY-a<=t.maxY});if(!e){t.push({...r});continue}n=e,a=r,n.minX=Math.min(n.minX,a.minX),n.minY=Math.min(n.minY,a.minY),n.maxX=Math.max(n.maxX,a.maxX),n.maxY=Math.max(n.maxY,a.maxY),n.differentPixels+=a.differentPixels,n.baselineRed+=a.baselineRed,n.baselineGreen+=a.baselineGreen,n.baselineBlue+=a.baselineBlue,n.currentRed+=a.currentRed,n.currentGreen+=a.currentGreen,n.currentBlue+=a.currentBlue}return t}(s):s,A.flatMap(e=>{var t,n,a;let r;return(t=e,n=v.baseline.width,a=v.baseline.height,r=t.maxX-t.minX+1,t.maxY-t.minY+1>=Math.max(48,Math.round(.07*a))&&r>=.35*n)?function(e,t,n){var a;let r=function(e,t){let n=[],a=null;for(let r=0;r<e.length;r+=1){if(e[r]<=t){a??=r;continue}null!==a&&(r-a>=6&&n.push([a,r-1]),a=null)}return null!==a&&e.length-a>=6&&n.push([a,e.length-1]),n}((a=function(e,t,n){let a=[];for(let r=e.minY;r<=e.maxY;r+=1){let i=0;for(let a=e.minX;a<=e.maxX;a+=1)1===t[r*n+a]&&(i+=1);a.push(i)}return a}(e,t.diffMask,t.baseline.width)).map((e,t)=>{let n=0,r=0,i=Math.max(0,t-3),s=Math.min(a.length-1,t+3);for(let e=i;e<=s;e+=1)n+=a[e],r+=1;return Math.round(n/r)}),Math.max(1,Math.round((e.maxX-e.minX+1)*.08))),i=function(e,t,n){let a=[],r=e.minY;for(let[i,s]of t){let t=e.minY+Math.round((i+s)/2);t-r+1<n||e.maxY-t<n||(a.push([r,t]),r=t+1)}return a.push([r,e.maxY]),a}(e,r,n);if(i.length<=1)return[e];let s=i.map(([n,a])=>(function(e,t,n,a){let r=null;for(let o=t;o<=n;o+=1)for(let t=e.minX;t<=e.maxX;t+=1){var i,s;let e=o*a.baseline.width+t;1===a.diffMask[e]&&function(e,t,n,a,r,i){let s=4*t;e.minX=Math.min(e.minX,n),e.minY=Math.min(e.minY,a),e.maxX=Math.max(e.maxX,n),e.maxY=Math.max(e.maxY,a),e.differentPixels+=1,e.baselineRed+=r.data[s],e.baselineGreen+=r.data[s+1],e.baselineBlue+=r.data[s+2],e.currentRed+=i.data[s],e.currentGreen+=i.data[s+1],e.currentBlue+=i.data[s+2]}(r??={minX:i=t,minY:s=o,maxX:i,maxY:s,differentPixels:0,baselineRed:0,baselineGreen:0,baselineBlue:0,currentRed:0,currentGreen:0,currentBlue:0},e,t,o,a.baseline,a.current)}return r})(e,n,a,t)).filter(e=>null!==e);return s.length>1?s:[e]}(e,v,Math.max(24,Math.round(.03*v.baseline.height))):[e]})).sort((e,t)=>{let n=t.differentPixels-e.differentPixels;if(0!==n)return n;let a=e.minY-t.minY;return 0!==a?a:e.minX-t.minX}).slice(0,Math.max(0,v.maxRegions??8)).map((e,t)=>{var n,a,r,i,s,o,l,c,d,u,p;let m,h,f,w,b,g,y,x,k,A,I,N,R,M,S,P,O;return n=e,a=t+1,r={width:v.baseline.width,height:v.baseline.height,totalPixels:v.totalPixels,differentPixels:v.differentPixels},g={x:n.minX,y:n.minY,width:n.maxX-n.minX+1,height:n.maxY-n.minY+1},y={x:Math.round(n.minX+g.width/2),y:Math.round(n.minY+g.height/2)},x=er(n.baselineRed,n.baselineGreen,n.baselineBlue,n.differentPixels),k=er(n.currentRed,n.currentGreen,n.currentBlue,n.differentPixels),A=g.width*g.height,I=el(n.differentPixels/A),N=Math.round(ei(x)),R=Math.round(ei(k)),M=(i=g,s=r.width,o=r.height,i.width>=.55*s&&i.height>=.12*o?"large-area":i.width>=2.5*i.height?"horizontal-band":i.height>=2.5*i.width?"vertical-band":"compact"),S=(m=A/r.totalPixels)>=.04?"large":m>=.01?"medium":"small",P=(l=x,c=k,h=ei(l),Math.abs(f=ei(c)-h)>=12?f>0?"brighter":"darker":Math.max(Math.abs(c.r-l.r),Math.abs(c.g-l.g),Math.abs(c.b-l.b))>=12?"color-shift":"mixed"),O=(d=y,u=r.width,p=r.height,w=d.x<u/3?"left":d.x>2*u/3?"right":"center",b=d.y<p/3?"top":d.y>2*p/3?"bottom":"middle","center"===w&&"middle"===b?"center":`${b}-${w}`),{index:a,rect:g,normalizedRect:{x:el(g.x/r.width),y:el(g.y/r.height),width:el(g.width/r.width),height:el(g.height/r.height)},differentPixels:n.differentPixels,shareOfDiffPercentage:el(n.differentPixels/r.differentPixels),densityPercentage:I,shape:M,size:S,location:O,averageBaselineColorHex:es(x),averageCurrentColorHex:es(k),baselineLuminance:N,currentLuminance:R,dominantChange:P}}):[];if(x>0&&d){var v,A,I;for(let e of k)e.rect.width<4||e.rect.height<4||function(e,t){let n=_(t.x,0,e.width-1),a=_(t.y,0,e.height-1),r=_(t.x+t.width-1,0,e.width-1),i=_(t.y+t.height-1,0,e.height-1);for(let t=0;t<2;t+=1){for(let s=n;s<=r;s+=1)D(e,s,a+t,O),D(e,s,i-t,O);for(let s=a;s<=i;s+=1)D(e,n+t,s,O),D(e,r-t,s,O)}}(g,e.rect);await e.mkdir(t.dirname(d),{recursive:!0}),await e.writeFile(d,n.sync.write(g))}else await em(i.outputPath);let N=x>0?await B({baselinePath:a,currentPath:r,width:m.width,height:m.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,M=x>0&&N?(o=function(e){let t=[];for(let n of e.sort((e,t)=>e.minY-t.minY||e.minX-t.minX)){let e=t.find(e=>{var t,a,r;return t=e,a=n,r=10,t.minX-r<=a.maxX&&a.minX-r<=t.maxX&&t.minY-r<=a.maxY&&a.minY-r<=t.maxY});if(!e){t.push({...n});continue}e.minX=Math.min(e.minX,n.minX),e.minY=Math.min(e.minY,n.minY),e.maxX=Math.max(e.maxX,n.maxX),e.maxY=Math.max(e.maxY,n.maxY),e.differentPixels+=n.differentPixels}return t}(function(e,t,n){let a=new Uint8Array(e.length),r=new Int32Array(e.length),i=[];for(let s=0;s<e.length;s+=1){if(1!==e[s]||1===a[s])continue;let o=0,l=0;r[0]=s,l+=1,a[s]=1;let c=s%t,d=Math.floor(s/t),u={minX:c,minY:d,maxX:c,maxY:d,differentPixels:0};for(;o<l;){let i=r[o];o+=1;let s=i%t,c=Math.floor(i/t);u.minX=Math.min(u.minX,s),u.minY=Math.min(u.minY,c),u.maxX=Math.max(u.maxX,s),u.maxY=Math.max(u.maxY,c),u.differentPixels+=1;for(let i=-1;i<=1;i+=1){let o=c+i;if(!(o<0)&&!(o>=n))for(let n=-1;n<=1;n+=1){if(0===n&&0===i)continue;let c=s+n;if(c<0||c>=t)continue;let d=o*t+c;1===e[d]&&1!==a[d]&&(a[d]=1,r[l]=d,l+=1)}}}i.push(u)}return i}(function(e,t,n,a){let r=new Uint8Array(e);if(!a)return r;for(let e of[...a.baselineBlocksRaw,...a.currentBlocksRaw]){var i;!function(e,t,n,a){let r=Y(Math.floor(a.x),0,t-1),i=Y(Math.floor(a.y),0,n-1),s=Y(Math.ceil(a.x+a.width),0,t),o=Y(Math.ceil(a.y+a.height),0,n);for(let n=i;n<o;n+=1)for(let a=r;a<s;a+=1)e[n*t+a]=0}(r,t,n,{x:(i=e.rect).x-8,y:i.y-8,width:i.width+16,height:i.height+16})}return r}((I={diffMask:y,width:m.width,height:m.height,regions:k,ocr:N}).diffMask,I.width,I.height,I.ocr),I.width,I.height)),l=U(I.ocr?.currentBlocksRaw??[]),c=U(I.ocr?.baselineBlocksRaw??[]),o.filter(q).map(e=>{var t,n,a,r,i,s,o,d,u,p,m;let h,f,w,b,g,y,x,k,v,A;return t=e,n=I,a=l,r=c,b=function(e,t){let n,a=0;for(let r of t){let t=function(e,t){let n=Math.max(e.x,t.x),a=Math.max(e.y,t.y),r=Math.min(e.x+e.width,t.x+t.width),i=Math.min(e.y+e.height,t.y+t.height);return r<=n||i<=a?0:(r-n)*(i-a)}(e,r.rect);t<=a||(a=t,n=r)}return n?.index}(w=G(t),n.regions),g=function(e,t,n){let a=C(e,t);if(a)return F(e,a.blocks);let r=C(e,n);return r?F(e,r.blocks):void 0}(w,a,r),y=function(e,t,n){if(e.height<=3&&e.width>=.12*n)return"separator";if(!t)return e.width>=.4*n?"background":"unknown";if(e.width>=.4*n)return"background";let a=e.x+e.width/2,r=t.x+t.width/2;return a<r-t.width/2?"leading":a>r+t.width/2?"trailing":e.width>=.35*n?"background":"unknown"}(w,g?.block.rect,n.width),x=(i=w,s=y,o=t.differentPixels,d=n,h=i.width/i.height,f=o/(i.width*i.height),"separator"===s?"separator":"background"===s?"background":"trailing"===s&&h>=1.5&&h<=3.8&&f>=.35?"toggle":"trailing"===s&&i.width<=.06*d.width&&i.height<=.04*d.height?"chevron":"leading"===s&&h>=.55&&h<=1.8?"icon":L(i,d)?"background":"visual"),k={...b?{regionIndex:b}:{},slot:y,likelyKind:x,rect:w},{...b?{regionIndex:b}:{},slot:y,likelyKind:x,rect:w,...g?{nearestText:g.block.text.trim().replace(/^[^\p{L}\p{N}]+/u,"").replace(/^\p{L}\s+/u,"")}:{},score:(u=k,p=t.differentPixels,m=n,v=L(u.rect,m)?-35:0,A=20*!!u.regionIndex,$[u.likelyKind]+E[u.slot]+A+v+Math.min(20,p/200))}}).filter(e=>e.rect.y>=.08*I.height).filter(T).sort((e,t)=>t.score-e.score).slice(0,Math.max(0,I.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=w>0?Math.round(x/w*1e4)/100:0;return{...x>0&&d?{diffPath:d}:{},...k.length>0?{regions:k}:{},...R?{ocr:R}:{},...M.length>0?{nonTextDeltas:M}:{},totalPixels:w,differentPixels:x,mismatchPercentage:S,match:0===x}}async function eu(t,n){try{await e.access(t)}catch{throw new r("INVALID_ARGS",`${n}: ${t}`)}}function ep(e,t,n,a){if(null==a||a<=0)return;let i=e*t;if(!(i<=a))throw new r("INVALID_ARGS",`${n} is ${i} pixels, which exceeds the configured maxImagePixels limit of ${a}`)}async function em(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 eh(e,t){return ef(Math.round(.299*e.data[t]+.587*e.data[t+1]+.114*e.data[t+2]),255,.72)}function ef(e,t,n){return Math.round(e*(1-n)+t*n)}function ew(e){return e.width*e.height}function eb(e){return Math.round(100*e*100)/100}let eg=async(e,t)=>{let n,a,i;if(!t.baseline)throw new r("INVALID_ARGS","diff screenshot requires a baseline image");let s=function(e){if(null==e||""===e)return .1;let t=Number(e);if(Number.isNaN(t)||t<0||t>1)throw new r("INVALID_ARGS","--threshold must be a number between 0 and 1");return t}(t.threshold),o=t.current??{kind:"live"};if(t.overlayRefs&&!eN(o))throw new r("INVALID_ARGS","diff screenshot <current.png> cannot use --overlay-refs because saved-image comparisons have no live accessibility refs");let l=await N(e,t.baseline,{usage:"diff screenshot baseline",field:"baseline"}),c=[];try{let r;r=eN(o)?(a=await ey(e,t)).path:(n=await N(e,o,{usage:"diff screenshot current",field:"current"})).path,i=t.out?await R(e,t.out,{field:"diffPath",ext:".png"}):void 0;let d=await ed(l.path,r,{threshold:s,outputPath:i?.path,maxPixels:e.policy.maxImagePixels});eN(o)&&(d=await ex(e,t,i?.path,d,c));let u=d.diffPath?await i?.publish():void 0;return u&&c.push(u),d.diffPath||await i?.cleanup?.(),{...d,...c.length>0?{artifacts:c}:{}}}catch(e){throw await i?.cleanup?.(),e}finally{await l.cleanup?.(),await n?.cleanup?.(),await a?.cleanup?.()}};async function ey(e,t){let n=await M(e,{prefix:"agent-device-diff-current",ext:".png"});try{await ek(e,t,n.path,ev(t))}catch(e){throw await n.cleanup(),e}return n}async function ex(e,t,n,a,r){var i,s,o,l;if(!t.overlayRefs)return a;if(a.match||a.dimensionMismatch)return n&&await eI(n),a;let c=(i=t,s=n,i.currentOverlayOut?i.currentOverlayOut:i.out?.kind==="path"?{kind:"path",path:eA(s??i.out.path)}:i.out?.kind==="downloadableArtifact"?{kind:"downloadableArtifact",...i.out.clientPath?{clientPath:eA(i.out.clientPath)}:{},...i.out.fileName?{fileName:eA(i.out.fileName)}:{}}:void 0),d=await R(e,c,{field:"currentOverlayPath",ext:".png"});try{let n=await ek(e,t,d.path,{overlayRefs:!0,...ev(t)}),i=await d.publish();return i&&r.push(i),{...a,currentOverlayPath:n.path??d.path,...n.overlayRefs?{currentOverlayRefCount:n.overlayRefs.length}:{},...a.regions&&n.overlayRefs?{regions:(o=a.regions,l=n.overlayRefs,o.map(e=>{var t,n;let a,r=(t=e,n=l,a=ew(t.rect),n.map(e=>{var n,r;let i,s,o,l,c=e.overlayRect,d=(n=t.rect,r=c,i=Math.max(n.x,r.x),s=Math.max(n.y,r.y),o=Math.min(n.x+n.width,r.x+r.width),l=Math.min(n.y+n.height,r.y+r.height),o<=i||l<=s?0:(o-i)*(l-s));return d<=0?null:{ref:e.ref,...e.label?{label:e.label}:{},rect:c,overlayCoveragePercentage:eb(d/ew(c)),regionCoveragePercentage:eb(d/a)}}).filter(e=>null!==e).sort((e,t)=>{let n=t.regionCoveragePercentage-e.regionCoveragePercentage;return 0!==n?n:t.overlayCoveragePercentage-e.overlayCoveragePercentage}).slice(0,3).map(e=>({ref:e.ref,...e.label?{label:e.label}:{},rect:e.rect,regionCoveragePercentage:e.regionCoveragePercentage})));return r.length>0?{...e,currentOverlayMatches:r}:e}))}:{}}}catch(e){throw await d.cleanup?.(),e}}async function ek(e,t,n,a={}){if(!e.backend.captureScreenshot)throw new r("UNSUPPORTED_OPERATION","screenshot is not supported by this backend");return await e.backend.captureScreenshot({session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata},n,a)??{}}function ev(e){return e.surface?{surface:e.surface}:{}}function eA(e){let n=t.extname(e),a=n?e.slice(0,-n.length):e;return`${a}.current-overlay${n||".png"}`}async function eI(t){try{await e.unlink(eA(t))}catch(e){var n;if(!("object"==typeof(n=e)&&null!==n&&"code"in n&&"ENOENT"===n.code))throw e}}function eN(e){return"live"===e.kind}function eR(e){var t;let n,a=eM(e.label),r=eM(e.value),i=eM(e.identifier),s=(t=i)&&!/^[\w.]+:id\/[\w.-]+$/i.test(t)&&!/^_?NS:\d+$/i.test(t)?i:"";return(n=eS(e.type??"")).includes("textfield")||n.includes("securetextfield")||n.includes("searchfield")||n.includes("edittext")||n.includes("textview")||n.includes("textarea")?r||a||s:a||r||s}function eM(e){return"string"==typeof e?e.trim():""}function eS(e){let t=e.trim().replace(/XCUIElementType/gi,"").replace(/^AX/,"").toLowerCase(),n=Math.max(t.lastIndexOf("."),t.lastIndexOf("/"));return -1!==n&&(t=t.slice(n+1)),t}function eP(e,t,n,a,r={}){var i,s,o,l,c;let d,u,p=a??eD(e.type??"Element"),m=(d=eR(e),{text:d,isLargeSurface:u=function(e,t){if("text-view"===t||"text-field"===t||"search"===t)return!0;let n=eS(e.type??""),a=`${e.role??""} ${e.subrole??""}`.toLowerCase();return n.includes("textview")||n.includes("textarea")||n.includes("textfield")||n.includes("securetextfield")||n.includes("searchfield")||n.includes("edittext")||a.includes("text area")||a.includes("text field")}(e,p),shouldSummarize:u&&!!(i=d)&&(i.length>80||/[\r\n]/.test(i))}),h=(s=e,o=p,l=r,c=m,l.summarizeTextSurfaces&&c.shouldSummarize&&function(e,t,n){let a=eM(e.label);if(a&&a!==n)return a;let r=eM(e.identifier);if(r&&!e$(r)&&r!==n)return r;switch(t){case"text":case"text-view":return"Text view";case"text-field":return"Text field";case"search":return"Search field";default:return""}}(s,o,c.text)||eO(s,o)),f=" ".repeat(t),w=e.ref?`@${e.ref}`:"",b=(function(e,t,n,a){let r,i=[];if(!1===e.enabled&&i.push("disabled"),!n.summarizeTextSurfaces||(!0===e.selected&&i.push("selected"),e_(t)&&i.push("editable"),function(e,t){if("scroll-area"===t)return!0;let n=(e.type??"").toLowerCase(),a=`${e.role??""} ${e.subrole??""}`.toLowerCase();return n.includes("scroll")||a.includes("scroll")}(e,t)&&i.push("scrollable"),!a.shouldSummarize))return i;return i.push(`preview:"${((r=a.text.replace(/\s+/g," ").trim()).length<=48?r:`${r.slice(0,45)}...`).replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`),i.push("truncated"),[...new Set(i)]})(e,p,r,m).map(e=>` [${e}]`).join(""),g=h?` "${h}"`:"";return n?`${f}${w} [${p}]${b}`.trimEnd():`${f}${w} [${p}]${g}${b}`.trimEnd()}function eO(e,t){var n,a;let r,i=e.label?.trim();if(i&&(n=t,a=i,("scroll-area"===n||"list"===n||"collection"===n||"table"===n)&&(r=a.trim().toLowerCase())&&/^(vertical|horizontal)\s+scroll\s+bar(?:,?\s*\d+\s+pages?)?$/.test(r)))return"";let s=e.value?.trim();if(e_(t)){if(s)return s;if(i)return i}else if(i)return i;if(s)return s;let o=e.identifier?.trim();return!o||e$(o)&&("group"===t||"image"===t||"list"===t||"collection"===t)?"":o}function eD(e){let t=e.replace(/XCUIElementType/gi,"").toLowerCase(),n=e.includes(".")&&(e.startsWith("android.")||e.startsWith("androidx.")||e.startsWith("com."));switch(t.includes(".")&&(t=t.replace(/^android\.widget\./,"").replace(/^android\.view\./,"").replace(/^android\.webkit\./,"").replace(/^androidx\./,"").replace(/^com\.google\.android\./,"").replace(/^com\.android\./,""),n&&t.includes(".")&&(t=t.slice(t.lastIndexOf(".")+1))),t){case"application":return"application";case"navigationbar":return"navigation-bar";case"tabbar":return"tab-bar";case"button":case"imagebutton":return"button";case"link":return"link";case"cell":return"cell";case"statictext":case"checkedtextview":return"text";case"textfield":case"edittext":return"text-field";case"textview":return n?"text":"text-view";case"textarea":return"text-view";case"switch":return"switch";case"slider":return"slider";case"image":case"imageview":return"image";case"webview":return"webview";case"framelayout":case"linearlayout":case"relativelayout":case"constraintlayout":case"viewgroup":case"view":case"group":return"group";case"listview":case"recyclerview":return"list";case"collectionview":return"collection";case"searchfield":return"search";case"segmentedcontrol":return"segmented-control";case"window":return"window";case"checkbox":return"checkbox";case"radio":return"radio";case"menuitem":return"menu-item";case"toolbar":return"toolbar";case"scrollarea":case"scrollview":case"nestedscrollview":return"scroll-area";case"table":return"table";default:return t||"element"}}function e_(e){return"text-field"===e||"text-view"===e||"search"===e}function e$(e){return/^[\w.]+:id\/[\w.-]+$/i.test(e)}function eE(e,t){let n=eD(e.type??"Element"),a=eO(e,n),r=!1===e.enabled?"disabled":"enabled",i=!0===e.selected?"selected":"unselected",s=!0===e.hittable?"hittable":"not-hittable";return[String(t??e.depth??0),n,a,r,i,s].join("|")}function eT(e,t){return t.flatten?e.map(e=>({text:eP(e,0,!1),comparable:eE(e,0)})):(function(e,t={}){let n=[],a=[];for(let r of e){let e=r.depth??0,i=r.label?.trim()||r.value?.trim()||r.identifier?.trim()||"",s=eD(r.type??"Element");if("group"===s&&!i)continue;for(;n.length>0&&e<=n[n.length-1];)n.pop();let o=n.length;n.push(e),a.push({node:r,depth:o,type:s,text:eP(r,o,!1,s,t)})}return a})(e).map(e=>({text:e.text,comparable:eE(e.node,e.depth)}))}function eL(e,t){return e.get(t)??0}function eC(e,t,n){return t>=e.x&&t<=e.x+e.width&&n>=e.y&&n<=e.y+e.height}function eU(e){let t=null,n=-1;for(let a of e){let e=a.width*a.height;e>n&&(t=a,n=e)}return t}function eF(e,t,n,a){return Math.max(e,n)<=Math.min(t,a)}function eq(e){return new Map(e.map(e=>[e.index,e]))}function eG(e){return e.label?.trim()||e.value?.trim()||e.identifier?.trim()||""}function eX(e){var t;let n;return t=e.type,!!((n=`${t??""}`.toLowerCase()).includes("scroll")||n.includes("recyclerview")||n.includes("listview")||n.includes("gridview")||n.includes("collectionview"))||"table"===n||`${e.role??""} ${e.subrole??""}`.toLowerCase().includes("scroll")}function eV(e,t,n=eq(t)){var a;if(!e.rect)return!0;let r=eY(e,t,n);return!r||(a=e.rect,eF(a.x,a.x+a.width,r.x,r.x+r.width)&&eF(a.y,a.y+a.height,r.y,r.y+r.height))}function eY(e,t,n=eq(t)){let a=function(e,t){let n="number"==typeof e.parentIndex?t.get(e.parentIndex):void 0,a=new Set;for(;n&&!a.has(n.index);){if(a.add(n.index),n.rect&&eX(n))return n.rect;n="number"==typeof n.parentIndex?t.get(n.parentIndex):void 0}return null}(e,n);return a||function(e,t){let n=l(t),a=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)}),r=a.filter(e=>{let t=(e.type??"").toLowerCase();return t.includes("application")||t.includes("window")}),i=eU(r.map(e=>e.rect).filter(e=>eC(e,n.x,n.y)));if(i)return i;let s=eU(r.map(e=>e.rect));if(s)return s;let o=eU(a.map(e=>e.rect).filter(e=>eC(e,n.x,n.y)));return o||null}(t,e.rect??{x:0,y:0,width:0,height:0})}function eB(e,t){return e.y+e.height<=t.y?"above":e.y>=t.y+t.height?"below":null}function ej(e,t,n){let a="number"==typeof e.parentIndex?n.get(e.parentIndex):void 0,r=new Set;for(;a&&!r.has(a.index);){if(r.add(a.index),t.has(a.index)&&eX(a))return a;a="number"==typeof a.parentIndex?n.get(a.parentIndex):void 0}return null}function eH(e){return"text"===e||"label"===e||"any"===e}function eK(e,t){return{session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata}}function ez(e){return e.clock?.now()??Date.now()}async function eW(e,t){e.clock?await e.clock.sleep(t):await new Promise(e=>setTimeout(e,t))}let eJ=async(e,t)=>{var n;let a,r,i=await eQ(e,t);return await e.sessions.set(e0(t.session,i)),{nodes:i.snapshot.nodes,truncated:i.snapshot.truncated??!1,visibility:function(e){var t;let{nodes:n,backend:a,snapshotRaw:r}=e;if(r||"macos-helper"===(t=a)||"linux-atspi"===t)return{partial:!1,visibleNodeCount:n.length,totalNodeCount:n.length,reasons:[]};let i=function(e){if(0===e.length)return{nodes:e,hiddenCount:0,summaryLines:[]};let t=eq(e),n=new Set,a=[];for(let r of e){if(eV(r,e,t)){!function(e,t,n){let a=e,r=new Set;for(;a&&!r.has(a.index);)r.add(a.index),t.add(a.index),a="number"==typeof a.parentIndex?n.get(a.parentIndex):void 0}(r,n,t);continue}a.push(r)}let r=function(e,t,n,a){let r=new Map,i=new Set;for(let e of t){if(!e.rect)continue;let t=ej(e,n,a);if(!t?.rect)continue;let s=eB(e.rect,t.rect);if(!s)continue;let o=r.get(t.index)??new Set;o.add(s),r.set(t.index,o),i.add(e.index)}return function(e,t,n,a){for(let r of e){let e=function(e){let t=function(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}}(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}(r);if(!e||0===e.size)continue;let i=ej(r,t,n);if(!i)continue;let s=a.get(i.index)??new Set;for(let t of e)s.add(t);a.set(i.index,s)}}(e,n,a,r),{directionsByContainer:r,coveredNodeIndexes:i}}(e,a,n,t),i=0===n.size?e:e.filter(e=>n.has(e.index));return{nodes:i.map(e=>(function(e,t){let n=t.get(e.index);if(!n||0===n.size)return e;let a=!!(!0===e.hiddenContentAbove||n.has("above"))||void 0,r=!!(!0===e.hiddenContentBelow||n.has("below"))||void 0;return{...e,hiddenContentAbove:a,hiddenContentBelow:r}})(e,r.directionsByContainer)),hiddenCount:0===n.size?0:e.length-i.length,summaryLines:function(e,t,n){let a=new Map;for(let r of e){let e=function(e,t,n){if(!e.rect)return null;let a=eY(e,t,n);return a?eB(e.rect,a):null}(r,t,n);if(!e)continue;let i=a.get(e)??[];i.push(r),a.set(e,i)}return["above","below"].flatMap(e=>{let t=a.get(e);if(!t||0===t.length)return[];let n=(function(e){let t=new Set,n=[];for(let a of e){let e=eG(a);!e||t.has(e)||(t.add(e),n.push(e))}return n})(t).slice(0,3).map(e=>`"${e}"`),r=1===t.length?"interactive item":"interactive items",i=n.length>0?`: ${n.join(", ")}`:"";return[`[off-screen ${e}] ${t.length} ${r}${i}`]})}(a.filter(e=>!r.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")||!!eG(e)}(e)),e,t)}}(n),s=new Set;return i.hiddenCount>0&&s.add("offscreen-nodes"),i.nodes.some(e=>e.hiddenContentAbove)&&s.add("scroll-hidden-above"),i.nodes.some(e=>e.hiddenContentBelow)&&s.add("scroll-hidden-below"),{partial:s.size>0,visibleNodeCount:i.nodes.length,totalNodeCount:n.length,reasons:[...s]}}({nodes:i.snapshot.nodes,backend:i.snapshot.backend,snapshotRaw:t.raw}),...i.warnings.length>0?{warnings:i.warnings}:{},...(a=(n=i).result.appName??n.session?.appName,r=n.result.appBundleId??n.session?.appBundleId,{...a||r?{appName:a??r}:{},...r?{appBundleId:r}:{}})}},eZ=async(e,t)=>{let n=await eQ(e,t),a=!0===t.interactiveOnly,r=n.session?.snapshot,i=e0(t.session,n);if(!r){let t=function(e,t={}){return eT(e,t).length}(n.snapshot.nodes,{flatten:a});return await e.sessions.set(i),{mode:"snapshot",baselineInitialized:!0,summary:{additions:0,removals:0,unchanged:t},lines:[],...n.warnings.length>0?{warnings:n.warnings}:{}}}let s=function(e,t,n={}){let a=function(e,t){let n=e.length,a=t.length,r=n+a,i=new Map,s=[];i.set(1,0);for(let o=0;o<=r;o+=1){s.push(new Map(i));for(let r=-o;r<=o;r+=2){let l=r===-o||r!==o&&eL(i,r-1)<eL(i,r+1)?eL(i,r+1):eL(i,r-1)+1,c=l-r;for(;l<n&&c<a&&e[l].comparable===t[c].comparable;)l+=1,c+=1;if(i.set(r,l),l>=n&&c>=a)return function(e,t,n,a,r){let i=[],s=a,o=r;for(let a=e.length-1;a>=0;a-=1){let r=e[a],l=s-o,c=l===-a||l!==a&&eL(r,l-1)<eL(r,l+1)?l+1:l-1,d=eL(r,c),u=d-c;for(;s>d&&o>u;)i.push({kind:"unchanged",text:n[o-1].text}),s-=1,o-=1;if(0===a)break;s===d?(i.push({kind:"added",text:n[u].text}),o=u):(i.push({kind:"removed",text:t[d].text}),s=d)}return i.reverse(),i}(s,e,t,n,a)}}return[]}(eT(e,n),eT(t,n)),r={additions:0,removals:0,unchanged:0};for(let e of a)"added"===e.kind&&(r.additions+=1),"removed"===e.kind&&(r.removals+=1),"unchanged"===e.kind&&(r.unchanged+=1);return{summary:r,lines:a}}(r.nodes,n.snapshot.nodes,{flatten:a});return await e.sessions.set(i),{mode:"snapshot",baselineInitialized:!1,summary:s.summary,lines:s.lines,...n.warnings.length>0?{warnings:n.warnings}:{}}};async function eQ(e,t){var n,a,i,s,o;let l,c,d,u,p,m;if(!e.backend.captureSnapshot)throw new r("UNSUPPORTED_OPERATION","snapshot is not supported by this backend");let h=t.session??"default",f=await e.sessions.get(h),w=await e.backend.captureSnapshot({session:h,requestId:t.requestId,appId:f?.appId,appBundleId:f?.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=(n=w,a=e,n.snapshot?n.snapshot:{nodes:n.nodes??[],truncated:n.truncated,backend:n.backend,createdAt:ez(a)}),g=ez(e);return{snapshot:b,result:w,session:f,warnings:(l=[...(i={result:w,snapshot:b,options:t,session:f,capturedAt:b.createdAt??g,runtimeNow:g}).result.warnings??[]],c=!0===i.options.interactiveOnly,d=i.result.analysis,"android"===i.snapshot.backend&&c&&0===i.snapshot.nodes.length&&d&&(d.rawNodeCount??0)>=12&&(l.push(`Interactive snapshot is empty after filtering ${d.rawNodeCount} raw Android nodes. Likely causes: depth too low, transient route change, or collector filtering.`),"number"==typeof i.options.depth&&"number"==typeof d.maxDepth&&d.maxDepth>=i.options.depth+2&&l.push(`Interactive output is empty at depth ${i.options.depth}; retry without -d.`)),p=!!(u=i.session?.snapshot)&&[i.capturedAt,i.runtimeNow].some(e=>{let t=e-u.createdAt;return t>=0&&t<=2e3}),!i.result.freshness&&u&&p&&(s=u.nodes.length,o=i.snapshot.nodes.length,!(s<12)&&o<=Math.floor(.2*s))&&l.push("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."),m=i.result.freshness,m?.staleAfterRetries&&"android"===i.snapshot.backend&&("stuck-route"===m.reason?l.push(`Recent ${m.action} was followed by a nearly identical snapshot after ${m.retryCount} automatic retr${1===m.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"===m.reason&&l.push("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.")),Array.from(new Set(l)))}}function e0(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}}function e1(e,t,n={}){let a=[],r=x(e.type??""),i=e5(e.identifier),s=e5(e.label),o=e5(e.value),l=e5(p(e)),c="fill"===n.action;i&&a.push(`id=${e2(i)}`),r&&s&&a.push(c?`role=${e2(r)} label=${e2(s)} editable=true`:`role=${e2(r)} label=${e2(s)}`),s&&a.push(c?`label=${e2(s)} editable=true`:`label=${e2(s)}`),o&&a.push(c?`value=${e2(o)} editable=true`:`value=${e2(o)}`),l&&l!==s&&l!==o&&a.push(c?`text=${e2(l)} editable=true`:`text=${e2(l)}`),r&&c&&!a.some(e=>e.includes("editable=true"))&&a.push(`role=${e2(r)} editable=true`);let d=Array.from(new Set(a));return 0===d.length&&r&&d.push(c?`role=${e2(r)} editable=true`:`role=${e2(r)}`),0===d.length&&g(e)&&d.push("visible=true"),d}function e2(e){return JSON.stringify(e)}function e5(e){if(!e)return null;let t=e.trim();return t||null}function e4(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 e3(e,t){let n=t??"default",a=await e.sessions.get(n);if(!a)throw new r("SESSION_NOT_FOUND","No active session. Run open first.");if(!a.snapshot)throw new r("INVALID_ARGS","No snapshot in session. Run snapshot first.");return{sessionName:n,session:a,snapshot:a.snapshot}}async function e8(e,t,n={updateSession:!0}){if(!e.backend.captureSnapshot)throw new r("UNSUPPORTED_OPERATION","snapshot is not supported by this backend");let a=t.session??"default",i=await e.sessions.get(a),s=await e.backend.captureSnapshot(eK(e,t),{interactiveOnly:!1,compact:!1,depth:t.depth,scope:n.scope??t.scope,raw:t.raw}),o=s.snapshot??{nodes:s.nodes??[],truncated:s.truncated,backend:s.backend,createdAt:ez(e)};return n.updateSession&&i&&await e.sessions.set({...i,snapshot:o}),{sessionName:a,session:i,snapshot:o}}async function e6(e,t,n){if(e.backend.readText){let a=await e.backend.readText(eK(e,{session:t.sessionName}),n);if(a.text.trim())return a.text}return eR(n)}function e9(e){return{kind:"selector",selector:e}}function e7(e,t={}){return{kind:"ref",ref:e,...t.fallbackLabel?{fallbackLabel:t.fallbackLabel}:{}}}let te=async(e,t)=>{let n=t.locator??"any";if(!t.query)throw new r("INVALID_ARGS","find requires a value");if("wait"===t.action)return await tc(e,t,n);let a=await e8(e,t,{updateSession:!0,scope:eH(n)?t.query:void 0}),i=A(a.snapshot.nodes,n,t.query,{requireRect:!1}).matches[0];if(!i)throw new r("COMMAND_FAILED","find did not match any element");if("exists"===t.action)return{kind:"found",found:!0};let s=`@${i.ref}`;return"get_attrs"===t.action?{kind:"attrs",ref:s,node:i}:{kind:"text",ref:s,text:await e6(e,a,i),node:i}},tt=async(e,t)=>{if("ref"===t.target.kind){let n=await e3(e,t.session),a=function(e,t,n){let a=d(t);if(!a)throw new r("INVALID_ARGS",n.invalidRefMessage);let i=c(e,a)??(n.fallbackLabel.length>0?w(e,n.fallbackLabel):null);if(!i)throw new r("COMMAND_FAILED",n.notFoundMessage);return{ref:a,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=e1(a.node,e.backend.platform,{action:"get"}),s={kind:"ref",ref:`@${a.ref}`};return"attrs"===t.property?{kind:"attrs",target:s,node:a.node,selectorChain:i}:{kind:"text",target:s,text:await e6(e,n,a.node),node:a.node,selectorChain:i}}let n=await tm(e,t,t.session??"default",{selector:t.target.selector,disambiguateAmbiguous:"text"===t.property}),a=e1(n.node,e.backend.platform,{action:"get"});if("attrs"===t.property)return{kind:"attrs",target:{kind:"selector",selector:n.selector},node:n.node,selectorChain:a};let i=await e6(e,n.capture,n.node);return{kind:"text",target:{kind:"selector",selector:n.selector},text:i,node:n.node,selectorChain:a}},tn=async(e,t)=>{let n=await tt(e,{...t,property:"text",target:t.target});if("text"!==n.kind)throw new r("COMMAND_FAILED","getText returned non-text result");return n},ta=async(e,t)=>{let n=await tt(e,{...t,property:"attrs",target:t.target});if("attrs"!==n.kind)throw new r("COMMAND_FAILED","getAttrs returned non-attrs result");return n},tr=async(e,t)=>{if(!["visible","hidden","exists","editable","selected","text"].includes(t.predicate))throw new r("INVALID_ARGS","is requires predicate: visible|hidden|exists|editable|selected|text");if("text"===t.predicate&&!t.expectedText)throw new r("INVALID_ARGS","is text requires expected text value");let n=await e8(e,t,{updateSession:!0}),a=f(t.selector);if("exists"===t.predicate){let i=u(n.snapshot.nodes,a,{platform:e.backend.platform});if(!i)throw new r("COMMAND_FAILED",y(a,[],{unique:!1}));return{predicate:t.predicate,pass:!0,selector:i.selector.raw,matches:i.matches,selectorChain:a.selectors.map(e=>e.raw)}}let i=h(n.snapshot.nodes,a,{platform:e.backend.platform,requireRect:!1,requireUnique:!0,disambiguateAmbiguous:!1});if(!i)throw new r("COMMAND_FAILED",y(a,[],{unique:!0}));let s=function(e){let{predicate:t,node:n,nodes:a,expectedText:r,platform:i}=e,s=p(n),o=k(n,i),l=!0===n.selected,c="text"===t?g(n):function(e,t){if(!0===e.hittable)return!0;if(e4(e.rect))return eV(e,t);if(e.rect)return!1;let n=function(e,t){let n=new Map(t.map(e=>[e.index,e])),a=e,r=new Set;for(;"number"==typeof a.parentIndex&&!r.has(a.index);){r.add(a.index);let e=n.get(a.parentIndex);if(!e)break;if(function(e){let t=x(e.type??"");return!(t.includes("application")||t.includes("window")||t.includes("scrollview")||t.includes("tableview")||t.includes("collectionview"))&&"table"!==t&&"list"!==t&&"listview"!==t&&(!0===e.hittable||e4(e.rect))}(e))return e;a=e}return null}(e,t);return!!n&&(!0===n.hittable||!!e4(n.rect)&&eV(n,t))}(n,a),d=!1;switch(t){case"visible":d=c;break;case"hidden":d=!c;break;case"editable":d=o;break;case"selected":d=l;break;case"text":d=s===(r??"")}let u="text"===t?`expected="${r??""}" actual="${s}"`:`actual=${JSON.stringify({visible:c,editable:o,selected:l})}`;return{pass:d,actualText:s,details:u}}({predicate:t.predicate,node:i.node,nodes:n.snapshot.nodes,expectedText:t.expectedText,platform:e.backend.platform});if(!s.pass)throw new r("COMMAND_FAILED",`is ${t.predicate} failed for selector ${i.selector.raw}: ${s.details}`);return{predicate:t.predicate,pass:!0,selector:i.selector.raw,..."text"===t.predicate?{text:s.actualText}:{},selectorChain:a.selectors.map(e=>e.raw)}},ti=async(e,t)=>await tr(e,{...t,predicate:"visible",selector:t.target.selector}),ts=async(e,t)=>await tr(e,{...t,predicate:"hidden",selector:t.target.selector}),to=async(e,t)=>{if("sleep"===t.target.kind)return await eW(e,t.target.durationMs),{kind:"sleep",waitedMs:t.target.durationMs};if("ref"===t.target.kind){let n=await e3(e,t.session),a=d(t.target.ref);if(!a)throw new r("INVALID_ARGS",`Invalid ref: ${t.target.ref}`);let i=c(n.snapshot.nodes,a),s=i?b(i,n.snapshot.nodes):void 0;if(!s)throw new r("COMMAND_FAILED",`Ref ${t.target.ref} not found or has no label`);return await tu(e,t,s,t.target.timeoutMs)}if("selector"===t.target.kind)return await td(e,t,t.target.selector,t.target.timeoutMs);if(!t.target.text)throw new r("INVALID_ARGS","wait requires text");return await tu(e,t,t.target.text,t.target.timeoutMs)},tl=async(e,t)=>{let n=await to(e,{...t,target:{kind:"text",text:t.text,timeoutMs:t.timeoutMs}});if("text"!==n.kind)throw new r("COMMAND_FAILED","waitForText returned non-text result");return n};async function tc(e,t,n){let a=t.timeoutMs??1e4,i=ez(e);for(;ez(e)-i<a;){if(A((await e8(e,t,{updateSession:!0,scope:eH(n)?t.query:void 0})).snapshot.nodes,n,t.query,{requireRect:!1}).matches[0])return{kind:"found",found:!0,waitedMs:ez(e)-i};await eW(e,300)}throw new r("COMMAND_FAILED","find wait timed out")}async function td(e,t,n,a){let i=a??1e4,s=ez(e),o=f(n);for(;ez(e)-s<i;){let n=u((await e8(e,t,{updateSession:!0})).snapshot.nodes,o,{platform:e.backend.platform});if(n)return{kind:"selector",selector:n.selector.raw,waitedMs:ez(e)-s};await eW(e,300)}throw new r("COMMAND_FAILED",`wait timed out for selector: ${n}`)}async function tu(e,t,n,a){let i=a??1e4,s=ez(e);for(;ez(e)-s<i;){if(e.backend.findText?(await e.backend.findText(eK(e,t),n)).found:await tp(e,t,n))return{kind:"text",text:n,waitedMs:ez(e)-s};await eW(e,300)}throw new r("COMMAND_FAILED",`wait timed out for text: ${n}`)}async function tp(e,t,n){return!!w((await e8(e,t,{updateSession:!0})).snapshot.nodes,n)}async function tm(e,t,n,a){let i=await e8(e,{...t,session:n},{updateSession:!0}),s=f(a.selector),o=h(i.snapshot.nodes,s,{platform:e.backend.platform,requireRect:!1,requireUnique:!0,disambiguateAmbiguous:a.disambiguateAmbiguous});if(!o)throw new r("COMMAND_FAILED",y(s,[],{unique:!0}));return{capture:i,node:o.node,selector:o.selector.raw,ref:`@${o.node.ref}`}}function th(e,t,n,a){if(!Number.isFinite(e)||!Number.isInteger(e)||e<n||e>a)throw new r("INVALID_ARGS",`${t} must be an integer between ${n} and ${a}`);return e}function tf(e,t){let n=function(e,t){let n=tb(t.rect);if(!n)return null;let a=t,r=new Set;for(;!r.has(a.ref);){r.add(a.ref);let t=e.filter(e=>{if(e.parentIndex!==a.index||!e.hittable)return!1;let t=tb(e.rect);return!!t&&tg(t,n)});if(1!==t.length)break;a=t[0]}return a===t?null:a}(e,t);if(n?.rect&&tw(n.rect))return n;let a=m(e,t);return a?.rect&&tw(a.rect)?!function(e,t,n){var a,r,i,s;let o,c,d,u=tb(e.rect),p=tb(t.rect);if(!u||!p)return!1;let m=function(e,t){let n=l(t),a=e.filter(e=>{let t=(e.type??"").toLowerCase();return t.includes("application")||t.includes("window")}).map(e=>tb(e.rect)).filter(e=>null!==e);if(0===a.length)return null;let r=a.filter(e=>eC(e,n.x,n.y));return eU(r.length>0?r:a)}(n,u);return!!m&&(a=p,r=m,o=(i=a,s=r,Math.max(0,Math.min(i.x+i.width,s.x+s.width)-Math.max(i.x,s.x))*Math.max(0,Math.min(i.y+i.height,s.y+s.height)-Math.max(i.y,s.y))),c=a.width*a.height,d=r.width*r.height,!(o<=0)&&!(c<=0)&&!(d<=0)&&!!(o/d>=.9)&&!!(o/c>=.8))&&!tg(u,p)}(t,a,e)?a:t:t}function tw(e){let t=tb(e);if(!t)return null;let n=l(t);return Number.isFinite(n.x)&&Number.isFinite(n.y)?n:null}function tb(e){if(!e)return null;let t=Number(e.x),n=Number(e.y),a=Number(e.width),r=Number(e.height);return Number.isFinite(t)&&Number.isFinite(n)&&Number.isFinite(a)&&Number.isFinite(r)&&!(a<0)&&!(r<0)?{x:t,y:n,width:a,height:r}:null}function tg(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 ty(e,t,n){if(await tk(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 a=await tA(e,t,t.target),i=a.resolved,s=n.promoteToHittableAncestor?tf(a.snapshot.nodes,i.node):i.node;return function(e,t,n,a){let i=e.rect?eY(e,t):null;if(!(!e.rect||!i||eV(e,t)))throw new r("COMMAND_FAILED",`Ref ${n} is off-screen and not safe to ${a}`,{reason:"offscreen_ref",ref:d(n),rect:e.rect,viewport:i,hint:`Use scroll with the direction from the off-screen summary, take a fresh snapshot, then retry ${a} with the new ref or a selector.`})}(s,a.snapshot.nodes,t.target.ref,n.action),{kind:"ref",point:tN(s,`Ref ${t.target.ref} not found or has invalid bounds`),target:{kind:"ref",ref:`@${i.ref}`},node:s,selectorChain:e1(s,e.backend.platform,{action:"fill"===n.action?"fill":"click"}),refLabel:b(s,a.snapshot.nodes)}}let a=await tx(e,t,n.requireInteractive),i=f(t.target.selector),s=h(a.snapshot.nodes,i,{platform:e.backend.platform,requireRect:!0,requireUnique:!0,disambiguateAmbiguous:!0});if(!s||!s.node.rect)throw new r("COMMAND_FAILED",y(i,s?.diagnostics??[],{unique:!0}));let o=n.promoteToHittableAncestor?tf(a.snapshot.nodes,s.node):s.node;return{kind:"selector",point:tN(o,`Selector ${s.selector.raw} resolved to invalid bounds`),target:{kind:"selector",selector:s.selector.raw},node:o,selectorChain:e1(o,e.backend.platform,{action:"fill"===n.action?"fill":"click"}),refLabel:b(o,a.snapshot.nodes)}}async function tx(e,t,n){if(!e.backend.captureSnapshot)throw new r("UNSUPPORTED_OPERATION","snapshot is not supported by this backend");let a=t.session??"default",i=await e.sessions.get(a);if(!i)throw new r("SESSION_NOT_FOUND","No active session. Run open first.");let s=await e.backend.captureSnapshot(eK(e,t),{interactiveOnly:n,compact:n}),o=s.snapshot??{nodes:s.nodes??[],truncated:s.truncated,backend:s.backend,createdAt:ez(e)};return await e.sessions.set({...i,snapshot:o}),{snapshot:o}}async function tk(e,t,n){if("macos"!==e.backend.platform)return;let a=await tv(e,t);if(("desktop"===a||"menubar"===a)&&("menubar"!==a||"click"!==n&&"press"!==n))throw new r("UNSUPPORTED_OPERATION",`${n} is not supported on macOS ${a} sessions yet. Open an app session to act, or use the ${a} surface to inspect.`)}async function tv(e,t){let n=await e.sessions.get(t.session??"default");return n?.metadata?.surface}async function tA(e,t,n){let a=t.session??"default",i=await e.sessions.get(a);if(!i)throw new r("SESSION_NOT_FOUND","No active session. Run open first.");if(!i.snapshot)throw new r("INVALID_ARGS","No snapshot in session. Run snapshot first.");let s=n.fallbackLabel??"",o=tI(i.snapshot.nodes,n.ref,{fallbackLabel:s,requireRect:!0});if(o)return{snapshot:i.snapshot,resolved:o};let l=await tx(e,t,!0),c=tI(l.snapshot.nodes,n.ref,{fallbackLabel:s,requireRect:!0});if(!c)throw new r("COMMAND_FAILED",`Ref ${n.ref} not found or has no bounds`);return{...l,resolved:c}}function tI(e,t,n){let a=d(t);if(!a)throw new r("INVALID_ARGS",`Invalid ref: ${t}`);let i=c(e,a);if(tR(i,n.requireRect))return{ref:a,node:i};let s=n.fallbackLabel.length>0?w(e,n.fallbackLabel):null;return tR(s,n.requireRect)?{ref:a,node:s}:null}function tN(e,t){if(!e.rect)throw new r("COMMAND_FAILED",t);let n=l(e.rect);if(!Number.isFinite(n.x)||!Number.isFinite(n.y))throw new r("COMMAND_FAILED",t);return n}function tR(e,t){if(!e)return!1;if(!t)return!0;if(!e.rect)return!1;let{x:n,y:a,width:r,height:i}=e.rect;if(!Number.isFinite(Number(n))||!Number.isFinite(Number(a))||!Number.isFinite(Number(r))||!Number.isFinite(Number(i))||0>Number(r)||0>Number(i))return!1;let s=l(e.rect);return Number.isFinite(s.x)&&Number.isFinite(s.y)}let tM=async(e,t)=>{let n=await ty(e,t,{action:"focus",requireInteractive:!0,promoteToHittableAncestor:!1});if(!e.backend.focus)throw new r("UNSUPPORTED_OPERATION","focus is not supported by this backend");let a=tU(await e.backend.focus(eK(e,t),n.point));return{...n,...a?{backendResult:a}:{},...I(`Focused (${n.point.x}, ${n.point.y})`)}},tS=async(e,t)=>{let n=await ty(e,t,{action:"longPress",requireInteractive:!0,promoteToHittableAncestor:!0});if(!e.backend.longPress)throw new r("UNSUPPORTED_OPERATION","longPress is not supported by this backend");let a=void 0===t.durationMs?void 0:th(t.durationMs,"durationMs",0,12e4),i=tU(await e.backend.longPress(eK(e,t),n.point,{durationMs:a}));return{...n,...void 0!==a?{durationMs:a}:{},...i?{backendResult:i}:{},...I(`Long pressed (${n.point.x}, ${n.point.y})`)}},tP=async(e,t)=>{var n,a;if(!e.backend.scroll)throw new r("UNSUPPORTED_OPERATION","scroll is not supported by this backend");let i=tE(t.direction,"scroll direction"),s=(n=t.amount,a="scroll amount",void 0===n?void 0:tL(n,a)),o=function(e,t){if(void 0!==e){if(!Number.isFinite(e)||!Number.isInteger(e)||e<=0)throw new r("INVALID_ARGS",`${t} must be a positive integer`);return e}}(t.pixels,"scroll pixels");if(void 0!==s&&void 0!==o)throw new r("INVALID_ARGS","scroll accepts either amount or pixels, not both");let l=await t_(e,t),c="viewport"===l.kind?{kind:"viewport"}:{kind:"point",point:l.point},d=tU(await e.backend.scroll(eK(e,t),c,{direction:i,...void 0!==s?{amount:s}:{},...void 0!==o?{pixels:o}:{}}));return{...l,direction:i,...void 0!==s?{amount:s}:{},...void 0!==o?{pixels:o}:{},...d?{backendResult:d}:{},...I(void 0!==o?`Scrolled ${i} by ${o}px`:void 0!==s?`Scrolled ${i} by ${s}`:`Scrolled ${i}`)}},tO=async(e,t)=>{if(!e.backend.swipe)throw new r("UNSUPPORTED_OPERATION","swipe is not supported by this backend");let n=await t$(e,t),a=function(e,t){if(t.to)return{point:tT(t.to,"to")};let n=tE(t.direction,"swipe direction"),a=tL(t.distance??200,"swipe distance");switch(n){case"up":return{point:{x:e.x,y:e.y-a},direction:n,distance:a};case"down":return{point:{x:e.x,y:e.y+a},direction:n,distance:a};case"left":return{point:{x:e.x-a,y:e.y},direction:n,distance:a};case"right":return{point:{x:e.x+a,y:e.y},direction:n,distance:a}}}(n.point,t),i=void 0===t.durationMs?void 0:th(t.durationMs,"durationMs",16,1e4),s=tU(await e.backend.swipe(eK(e,t),n.point,a.point,{durationMs:i}));return{kind:"swipe",from:n.point,to:a.point,...a.direction?{direction:a.direction}:{},...void 0!==a.distance?{distance:a.distance}:{},...void 0!==i?{durationMs:i}:{},...n.target?{fromTarget:n.target}:{},...s?{backendResult:s}:{},...I("Swiped")}},tD=async(e,t)=>{if(!e.backend.pinch)throw new r("UNSUPPORTED_OPERATION","pinch is not supported by this backend");await tk(e,t,"pinch");let n=tL(t.scale,"pinch scale"),a=t.center?await ty(e,{...t,target:t.center},{action:"pinch",requireInteractive:!1,promoteToHittableAncestor:!1}):void 0,i=tU(await e.backend.pinch(eK(e,t),{scale:n,...a?{center:a.point}:{}}));return{kind:"pinch",scale:n,...a?{center:a.point,centerTarget:a}:{},...i?{backendResult:i}:{},...I(`Pinched to scale ${n}`)}};async function t_(e,t){let n=t.target??{kind:"viewport"};return"viewport"===n.kind?(await tk(e,t,"scroll"),{kind:"viewport"}):await ty(e,{...t,target:n},{action:"scroll",requireInteractive:!1,promoteToHittableAncestor:!1})}async function t$(e,t){if(t.from){var n;if("x"in(n=t.from)&&"y"in n)return await tk(e,t,"swipe"),{point:tT(t.from,"from")};let a=await ty(e,{...t,target:t.from},{action:"swipe",requireInteractive:!1,promoteToHittableAncestor:!1});return{point:a.point,target:a}}if(!t.direction)throw new r("INVALID_ARGS","swipe requires from+to or a direction");return await tk(e,t,"swipe"),{point:l(function(e){let t=e.filter(t=>eV(t,e)).map(e=>e.rect).filter(tC),n=t.length>0?t:e.map(e=>e.rect).filter(tC);if(0===n.length)throw new r("COMMAND_FAILED","Cannot infer viewport for directional swipe");let a=Math.min(...n.map(e=>e.x)),i=Math.min(...n.map(e=>e.y));return{x:a,y:i,width:Math.max(...n.map(e=>e.x+e.width))-a,height:Math.max(...n.map(e=>e.y+e.height))-i}}((await tx(e,t,!1)).snapshot.nodes)),target:{kind:"viewport"}}}function tE(e,t){switch(e){case"up":case"down":case"left":case"right":return e;default:throw new r("INVALID_ARGS",`${t} must be up, down, left, or right`)}}function tT(e,t){let n=Number(e.x),a=Number(e.y);if(!Number.isFinite(n)||!Number.isFinite(a))throw new r("INVALID_ARGS",`${t} point requires finite x and y`);return{x:n,y:a}}function tL(e,t){if(!Number.isFinite(e)||e<=0)throw new r("INVALID_ARGS",`${t} must be a positive number`);return e}function tC(e){return!!(e&&e.width>0&&e.height>0)}function tU(e){return e&&"object"==typeof e?e:void 0}let tF=async(e,t)=>await tV(e,t,"press"),tq=async(e,t)=>await tV(e,t,"click"),tG=async(e,t)=>{var n;if(!t.text)throw new r("INVALID_ARGS","fill requires text");let a=await ty(e,t,{action:"fill",requireInteractive:!0,promoteToHittableAncestor:!1});if(!e.backend.fill)throw new r("UNSUPPORTED_OPERATION","fill is not supported by this backend");let i=tY(await e.backend.fill(eK(e,t),a.point,t.text,{delayMs:t.delayMs})),s="node"in a?a.node.type??"":"",o=s&&!v(s,e.backend.platform)?`fill target ${n=a,n.target?.kind==="ref"?n.target.ref:n.target?.kind==="selector"?n.target.selector:"point"} resolved to "${s}", attempting fill anyway.`:void 0;return{...a,text:t.text,...o?{warning:o}:{},...i?{backendResult:i}:{}}},tX=async(e,t)=>{let n=t.text;if(!n)throw new r("INVALID_ARGS","type requires text");let a=function(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}(n);if(a)throw new r("INVALID_ARGS",`type does not accept a target ref like "${a}"`,{hint:`Use fill ${a} "text" to target that field, or press ${a} then type "text" to append.`});if(!e.backend.typeText)throw new r("UNSUPPORTED_OPERATION","type is not supported by this backend");let i=th(t.delayMs??0,"delay-ms",0,1e4),s=tY(await e.backend.typeText(eK(e,t),n,{delayMs:i}));return{kind:"text",text:n,delayMs:i,...s?{backendResult:s}:{},...I(`Typed ${Array.from(n).length} chars`)}};async function tV(e,t,n){let a=await ty(e,t,{action:n,requireInteractive:!0,promoteToHittableAncestor:!0});if(!e.backend.tap)throw new r("UNSUPPORTED_OPERATION","tap is not supported by this backend");let i=tY(await e.backend.tap(eK(e,t),a.point,{button:t.button,count:t.count,intervalMs:t.intervalMs,holdMs:t.holdMs,jitterPx:t.jitterPx,doubleTap:t.doubleTap}));return{...a,...i?{backendResult:i}:{}}}function tY(e){return e&&"object"==typeof e?e:void 0}let tB=async(e,t={})=>{if(!e.backend.pressBack)throw new r("UNSUPPORTED_OPERATION","system.back is not supported by this backend");let n=t.mode??"in-app";if("in-app"!==n&&"system"!==n)throw new r("INVALID_ARGS","system.back mode must be in-app or system");let a=t0(await e.backend.pressBack(eK(e,t),{mode:n}));return{kind:"systemBack",mode:n,...a?{backendResult:a}:{},...I("Back")}},tj=async(e,t={})=>{if(!e.backend.pressHome)throw new r("UNSUPPORTED_OPERATION","system.home is not supported by this backend");let n=t0(await e.backend.pressHome(eK(e,t)));return{kind:"systemHome",...n?{backendResult:n}:{},...I("Home")}},tH=async(e,t)=>{if(!e.backend.rotate)throw new r("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 r("INVALID_ARGS","system.rotate orientation must be portrait, portrait-upside-down, landscape-left, or landscape-right")}}(t.orientation),a=t0(await e.backend.rotate(eK(e,t),n));return{kind:"systemRotated",orientation:n,...a?{backendResult:a}:{},...I(`Rotated to ${n}`)}},tK=async(e,t={})=>{if(!e.backend.setKeyboard)throw new r("UNSUPPORTED_OPERATION","system.keyboard is not supported by this backend");let n=t.action??"status";if("status"!==n&&"get"!==n&&"dismiss"!==n)throw new r("INVALID_ARGS","system.keyboard action must be status, get, or dismiss");let a=await e.backend.setKeyboard(eK(e,t),{action:n}),i=t0(a);if("dismiss"===n){let e=tQ(a)?a.dismissed:void 0;return{kind:"keyboardDismissed",action:n,state:tQ(a)?a:{},...i?{backendResult:i}:{},...I(!1===e?"Keyboard already hidden":"Keyboard dismissed")}}return{kind:"keyboardState",action:n,state:tQ(a)?a:{},...i?{backendResult:i}:{}}},tz=async(e,t)=>{if("read"===t.action){if(!e.backend.getClipboard)throw new r("UNSUPPORTED_OPERATION","system.clipboard read is not supported by this backend");let n=await e.backend.getClipboard(eK(e,t));return{kind:"clipboardText",action:"read",text:"string"==typeof n?n:n.text}}if("write"!==t.action)throw new r("INVALID_ARGS","system.clipboard action must be read or write");if(!e.backend.setClipboard)throw new r("UNSUPPORTED_OPERATION","system.clipboard write is not supported by this backend");if("string"!=typeof t.text)throw new r("INVALID_ARGS","system.clipboard write requires text");let n=t0(await e.backend.setClipboard(eK(e,t),t.text));return{kind:"clipboardUpdated",action:"write",textLength:Array.from(t.text).length,...n?{backendResult:n}:{},...I("Clipboard updated")}},tW=async(e,t={})=>{if(!e.backend.openSettings)throw new r("UNSUPPORTED_OPERATION","system.settings is not supported by this backend");let n=function(e,t){if(void 0===e)return;let n=e.trim();if(!n)throw new r("INVALID_ARGS",`${t} must be a non-empty string`);return n}(t.target,"target"),a=t0(await e.backend.openSettings(eK(e,t),n));return{kind:"settingsOpened",...n?{target:n}:{},...a?{backendResult:a}:{},...I(n?`Opened settings: ${n}`:"Opened settings")}},tJ=async(e,t={})=>{if(!e.backend.handleAlert)throw new r("UNSUPPORTED_OPERATION","system.alert is not supported by this backend");let n=t.action??"get";if("get"!==n&&"accept"!==n&&"dismiss"!==n&&"wait"!==n)throw new r("INVALID_ARGS","system.alert action must be get, accept, dismiss, or wait");let a=void 0===t.timeoutMs?void 0:th(t.timeoutMs,"timeoutMs",0,12e4),i=await e.backend.handleAlert(eK(e,t),n,{timeoutMs:a});var s=n,o=i;if("get"===s){if("alertStatus"!==o.kind)throw new r("COMMAND_FAILED","system.alert get returned an invalid backend result");return{kind:"alertStatus",action:s,alert:o.alert}}if("wait"===s){if("alertWait"!==o.kind)throw new r("COMMAND_FAILED","system.alert wait returned an invalid backend result");return{kind:"alertWait",action:s,alert:o.alert,...void 0!==o.waitedMs?{waitedMs:o.waitedMs}:{},...void 0!==o.timedOut?{timedOut:o.timedOut}:{},...I(o.alert?"Alert visible":"Alert wait timed out")}}if("alertHandled"!==o.kind)throw new r("COMMAND_FAILED",`system.alert ${s} returned an invalid backend result`);return{kind:"alertHandled",action:s,handled:o.handled,...o.alert?{alert:o.alert}:{},...o.button?{button:o.button}:{},...I(o.handled?`Alert ${s}ed`:"No alert handled")}},tZ=async(e,t={})=>{if(!e.backend.openAppSwitcher)throw new r("UNSUPPORTED_OPERATION","system.appSwitcher is not supported by this backend");let n=t0(await e.backend.openAppSwitcher(eK(e,t)));return{kind:"appSwitcherOpened",...n?{backendResult:n}:{},...I("Opened app switcher")}};function tQ(e){return!!(e&&"object"==typeof e)}function t0(e){return e&&"object"==typeof e?e:void 0}let t1=/^[A-Za-z0-9_.:-]{1,64}$/,t2=async(e,t)=>{var n;if(!e.backend.openApp)throw new r("UNSUPPORTED_OPERATION","apps.open is not supported by this backend");let a=function(e){var t;let n=t9(e.app,"app"),a=t9(e.appId,"appId"),i=t9(e.bundleId,"bundleId"),s=t9(e.packageName,"packageName"),o=t9(e.url,"url"),l=t9(e.activity,"activity"),c={...n?{app:n}:{},...a?{appId:a}:{},...i?{bundleId:i}:{},...s?{packageName:s}:{},...o?{url:o}:{},...l?{activity:l}:{}};if(!((t=c).app??t.appId??t.bundleId??t.packageName??t.url??t.activity))throw new r("INVALID_ARGS","apps.open requires app, appId, bundleId, packageName, url, or activity");return c}(t),i=na(await e.backend.openApp(nn(e,t),a,{relaunch:t.relaunch}));return{kind:"appOpened",target:a,relaunch:!0===t.relaunch,...i?{backendResult:i}:{},...I(`Opened: ${(n=a).app??n.appId??n.bundleId??n.packageName??n.url??n.activity??"app"}`)}},t5=async(e,t={})=>{if(!e.backend.closeApp)throw new r("UNSUPPORTED_OPERATION","apps.close is not supported by this backend");let n=t9(t.app,"app"),a=na(await e.backend.closeApp(nn(e,t),n));return{kind:"appClosed",...n?{app:n}:{},...a?{backendResult:a}:{},...I(n?`Closed: ${n}`:"Closed app")}},t4=async(e,t={})=>{if(!e.backend.listApps)throw new r("UNSUPPORTED_OPERATION","apps.list is not supported by this backend");return{kind:"appsList",apps:await e.backend.listApps(nn(e,t),t.filter??"all")}},t3=async(e,t)=>{if(!e.backend.getAppState)throw new r("UNSUPPORTED_OPERATION","apps.state is not supported by this backend");let n=t7(t.app,"app"),a=await e.backend.getAppState(nn(e,t),n);return{kind:"appState",app:n,state:a}},t8=async(e,t)=>{if(!e.backend.pushFile)throw new r("UNSUPPORTED_OPERATION","apps.push is not supported by this backend");let n=t7(t.app,"app"),a=await ne(e,t.input);try{let r=await e.backend.pushFile(nn(e,t),a.backendInput,n),i=na(r);return{kind:"appPushed",app:n,inputKind:a.inputKind,...i?{backendResult:i}:{},...I(`Pushed to ${n}`)}}finally{await a.cleanup?.()}},t6=async(e,t)=>{var n,a;if(!e.backend.triggerAppEvent)throw new r("UNSUPPORTED_OPERATION","apps.triggerEvent is not supported by this backend");let i=function(e){let t=t7(e,"name");if(!t1.test(t))throw new r("INVALID_ARGS",`Invalid apps.triggerEvent name: ${t}`,{hint:"Use 1-64 chars: letters, numbers, underscore, dot, colon, or dash."});return t}(t.name);n=t.payload,a=`apps.triggerEvent payload for "${i}"`,void 0!==n&&nt(n,a,8192);let s=na(await e.backend.triggerAppEvent(nn(e,t),{name:i,...t.payload?{payload:t.payload}:{}}));return{kind:"appEventTriggered",name:i,...t.payload?{payload:t.payload}:{},...s?{backendResult:s}:{},...I(`Triggered app event: ${i}`)}};function t9(e,t){if(void 0!==e)return t7(e,t)}function t7(e,t){let n=e?.trim();if(!n)throw new r("INVALID_ARGS",`${t} must be a non-empty string`);return n}async function ne(e,t){if(!t||"object"!=typeof t)throw new r("INVALID_ARGS","apps.push requires an input");if("json"===t.kind)return nt(t.payload,"apps.push JSON payload",8192),{backendInput:{kind:"json",payload:t.payload},inputKind:"json"};let n=await N(e,t,{usage:"apps.push",field:"input"});return{backendInput:{kind:"file",path:n.path},inputKind:"file",...n.cleanup?{cleanup:n.cleanup}:{}}}function nt(e,t,n){if(function(e,t){if(!e||"object"!=typeof e||Array.isArray(e))throw new r("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 r("INVALID_ARGS",`${t} must be JSON-serializable`);return n}catch{throw new r("INVALID_ARGS",`${t} must be JSON-serializable`)}}(e,t),"utf8")>n)throw new r("INVALID_ARGS",`${t} exceeds ${n} bytes`)}function nn(e,t){return{session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata}}function na(e){return e&&"object"==typeof e?e:void 0}let nr=async(e,t={})=>{if(!e.backend.listDevices)throw new r("UNSUPPORTED_OPERATION","admin.devices is not supported by this backend");return{kind:"adminDevices",devices:await e.backend.listDevices(eK(e,t),t.filter)}},ni=async(e,t={})=>{if(!e.backend.bootDevice)throw new r("UNSUPPORTED_OPERATION","admin.boot is not supported by this backend");let n=function(e){if(!e)return;let t=nh(e.id,"target.id"),n=nh(e.name,"target.name"),a={...t?{id:t}:{},...n?{name:n}:{},...e.platform?{platform:e.platform}:{},...e.target?{target:e.target}:{},...void 0!==e.headless?{headless:e.headless}:{}};return Object.keys(a).length>0?a:void 0}(t.target),a=nb(await e.backend.bootDevice(eK(e,t),n));return{kind:"deviceBooted",...n?{target:n}:{},...a?{backendResult:a}:{},...I("Booted device")}},ns=async(e,t)=>{if(!e.backend.ensureSimulator)throw new r("UNSUPPORTED_OPERATION","admin.ensureSimulator is not supported by this backend");let n=nf(t.device,"device");return{kind:"simulatorEnsured",...await e.backend.ensureSimulator(eK(e,t),{device:n,...t.runtime?{runtime:nf(t.runtime,"runtime")}:{},...void 0!==t.boot?{boot:t.boot}:{},...void 0!==t.reuseExisting?{reuseExisting:t.reuseExisting}:{}})}},no=async(e,t)=>await nd(e,t,"install"),nl=async(e,t)=>await nd(e,t,"reinstall"),nc=async(e,t)=>await nd(e,t,"installFromSource");async function nd(e,t,n){let a="reinstall"===n?"reinstallApp":"installApp",i=e.backend[a];if(!i)throw new r("UNSUPPORTED_OPERATION",`admin.${n} is not supported by this backend`);let s="app"in t&&void 0!==t.app?nf(t.app,"app"):void 0;if("installFromSource"!==n&&!s)throw new r("INVALID_ARGS",`admin.${n} requires app`);let o=eK(e,t),l=await nu(e,o,t.source);try{var c,d,u,p,m;let t,a,r,h,f,w,b,g,y=await i.call(e.backend,o,{...s?{app:s}:{},source:l.source});return c=n,d=s,u=l.source,p=y,t=nb(p),a=nw(p,"appName"),r=nw(p,"appId"),h=nw(p,"bundleId"),f=nw(p,"packageName"),w=nw(p,"launchTarget"),b=nw(p,"installablePath"),g=nw(p,"archivePath"),{kind:"reinstall"===c?"appReinstalled":"installFromSource"===c?"appInstalledFromSource":"appInstalled",...d?{app:d}:{},source:u,...r?{appId:r}:{},...a?{appName:a}:{},...h?{bundleId:h}:{},...f?{packageName:f}:{},...w?{launchTarget:w}:{},...b?{installablePath:b}:{},...g?{archivePath:g}:{},...t?{backendResult:t}:{},...I(`${"reinstall"===c?"Reinstalled":"Installed"}: ${a??w??d??(m=u,"path"===m.kind?m.path:"uploadedArtifact"===m.kind?m.id:m.url)}`)}}finally{await l.cleanup?.()}}async function nu(e,t,n){let a=nm(n),r=await np(e,a);try{let n=e.backend.resolveInstallSource?await e.backend.resolveInstallSource(t,r.source):r.source;return{source:nm(n),...r.cleanup?{cleanup:r.cleanup}:{}}}catch(e){if(r.cleanup)try{await r.cleanup()}catch{}throw e}}async function np(e,t){if("url"===t.kind)return{source:t};let n=await N(e,t,{usage:"admin.install",field:"source"});return{source:{kind:"path",path:n.path},...n.cleanup?{cleanup:n.cleanup}:{}}}function nm(e){if(!e||"object"!=typeof e)throw new r("INVALID_ARGS","install source is required");if("path"===e.kind)return{kind:"path",path:nf(e.path,"source.path")};if("uploadedArtifact"===e.kind)return{kind:"uploadedArtifact",id:nf(e.id,"source.id")};if("url"===e.kind){let t=nf(e.url,"source.url");return function(e){let t;try{t=new URL(e)}catch{throw new r("INVALID_ARGS",`Invalid install source URL: ${e}`)}if("http:"!==t.protocol&&"https:"!==t.protocol)throw new r("INVALID_ARGS","Install source URL must use http or https")}(t),{kind:"url",url:t}}throw new r("INVALID_ARGS","install source kind must be path, uploadedArtifact, or url")}function nh(e,t){if(void 0!==e)return nf(e,t)}function nf(e,t){let n=e?.trim();if(!n)throw new r("INVALID_ARGS",`${t} must be a non-empty string`);return n}function nw(e,t){let n=e[t];return"string"==typeof n&&n.length>0?n:void 0}function nb(e){return e&&"object"==typeof e?e:void 0}let ng=async(e,t)=>{let n=nx(t.action,"record"),a="start"===n?e.backend.startRecording:e.backend.stopRecording;if(!a)throw new r("UNSUPPORTED_OPERATION",`record ${n} is not supported by this backend`);let i=t.out?await R(e,t.out,{field:"path",ext:".mp4"}):void 0;try{var s,o,l,c,d;let r,u,p=(s=t,o=i?.path,r=void 0===s.fps?void 0:th(s.fps,"fps",1,60),u=void 0===s.quality?void 0:th(s.quality,"quality",5,10),{...o?{outPath:o}:{},...void 0!==r?{fps:r}:{},...void 0!==u?{quality:u}:{},...void 0!==s.hideTouches?{showTouches:!0!==s.hideTouches}:{}}),m=await a.call(e.backend,eK(e,t),p),h=await i?.publish();return l=n,c=m,d=h,{..."string"==typeof c.path?{path:c.path}:{},..."string"==typeof c.telemetryPath?{telemetryPath:c.telemetryPath}:{},..."string"==typeof c.warning?{warning:c.warning}:{},...nk(l,c,d,{startKind:"recordingStarted",stopKind:"recordingStopped",startMessage:"Recording started",stopMessage:"Recording stopped"})}}catch(e){throw await i?.cleanup?.(),e}},ny=async(e,t)=>{let n=nx(t.action,"trace"),a="start"===n?e.backend.startTrace:e.backend.stopTrace;if(!a)throw new r("UNSUPPORTED_OPERATION",`trace ${n} is not supported by this backend`);let i=t.out?await R(e,t.out,{field:"outPath",ext:".trace"}):void 0;try{var s,o,l;let r={...i?.path?{outPath:i.path}:{}},c=await a.call(e.backend,eK(e,t),r),d=await i?.publish();return s=n,o=c,l=d,{..."string"==typeof o.outPath?{outPath:o.outPath}:{},...nk(s,o,l,{startKind:"traceStarted",stopKind:"traceStopped",startMessage:"Trace started",stopMessage:"Trace stopped"})}}catch(e){throw await i?.cleanup?.(),e}};function nx(e,t){if("start"===e||"stop"===e)return e;throw new r("INVALID_ARGS",`${t} action must be start or stop`)}function nk(e,t,n,a){return{kind:"start"===e?a.startKind:a.stopKind,action:e,...n?{artifact:n}:{},backendResult:t,...I("start"===e?a.startMessage:a.stopMessage)}}let nv=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i;function nA(e){if(!e)return{redacted:!1};let t=!1,n={};for(let[a,r]of Object.entries(e))if(nv.test(a))n[a]="[REDACTED]",t=!0;else{let e=nM(r,2048);n[a]=e.value??"",t||=e.redacted}return{value:n,redacted:t}}function nI(e){return void 0===e?{redacted:!1}:function(e){try{let t=JSON.parse(e),n=nR(t,nS);return nP(JSON.stringify(n.value),2048,n.redacted)}catch{return}}(e)??nM(e,2048)}function nN(e){return nR(e,e=>nM(e,2048))}function nR(e,t){if(void 0===e)return{redacted:!1};if("string"==typeof e)return t(e);if(!e||"object"!=typeof e)return{value:e,redacted:!1};if(Array.isArray(e)){let n=!1;return{value:e.map(e=>{let a=nR(e,t);return n||=a.redacted,a.value}),redacted:n}}let n=!1,a={};for(let[r,i]of Object.entries(e)){if(nv.test(r)){a[r]="[REDACTED]",n=!0;continue}let e=nR(i,t);a[r]=e.value,n||=e.redacted}return{value:a,redacted:n}}function nM(e,t){if(void 0===e)return{redacted:!1};let n=nS(e);return nP(n.value,t,n.redacted)}function nS(e){let t=!1,n=e.replaceAll(/(authorization|token|secret|password|passwd|api[-_]?key)=([^&\s]+)/gi,(e,n)=>(t=!0,`${String(n)}=[REDACTED]`));return{value:n=(n=(n=n.replaceAll(/("(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)"\s*:\s*")([^"]*)(")/gi,(e,n,a,r)=>(t=!0,`${String(n)}[REDACTED]${String(r)}`))).replaceAll(/\b(Bearer\s+)([^\s",;]+)/gi,(e,n)=>(t=!0,`${String(n)}[REDACTED]`))).replaceAll(/((?:authorization|cookie|token|secret|password|passwd|api[-_]?key)\s*[:=]\s*)([^\s,;]+)/gi,(e,n)=>(t=!0,`${String(n)}[REDACTED]`)),redacted:t}}function nP(e,t,n){if(void 0===e)return{redacted:n};let a=e;return a.length>t&&(a=`${a.slice(0,t)}...[truncated]`,n=!0),{value:a,redacted:n}}let nO=async(e,t={})=>{var n,a;let i;if(!e.backend.readLogs)throw new r("UNSUPPORTED_OPERATION","diagnostics.logs is not supported by this backend");return i=!0===(n=await e.backend.readLogs(await n$(e,t),{...nE(a=t,100,500,"logs limit"),...void 0!==a.levels?{levels:nL(a.levels,"levels")}:{},...void 0!==a.search?{search:nC(a.search,"search")}:{},...void 0!==a.source?{source:nC(a.source,"source")}:{}})).redacted,{kind:"diagnosticsLogs",entries:n.entries.map(e=>{let t=nM(e.message,4096),n=nN(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}:{}}},nD=async(e,t={})=>{var n,a,i;let s;if(!e.backend.dumpNetwork)throw new r("UNSUPPORTED_OPERATION","diagnostics.network is not supported by this backend");let o={...nE(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 r("INVALID_ARGS","network include must be summary, headers, body, or all")}(i.include)};return n=await e.backend.dumpNetwork(await n$(e,t),o),a=o.include??"summary",s=!0===n.redacted,{kind:"diagnosticsNetwork",entries:n.entries.map(e=>{let t=e.url?function(e){try{let t=new URL(e),n=!1;for(let e of Array.from(t.searchParams.keys()))nv.test(e)&&(t.searchParams.set(e,"[REDACTED]"),n=!0);return{value:t.toString(),redacted:n}}catch{return nM(e,2048)}}(e.url):void 0,n="headers"===a||"all"===a?nA(e.requestHeaders):void 0,r="headers"===a||"all"===a?nA(e.responseHeaders):void 0,i="body"===a||"all"===a?nI(e.requestBody):void 0,o="body"===a||"all"===a?nI(e.responseBody):void 0,l=nN(e.metadata);return s||=(t?.redacted??!1)||(n?.redacted??!1)||(r?.redacted??!1)||(i?.redacted??!1)||(o?.redacted??!1)||l.redacted,{...e.timestamp?{timestamp:e.timestamp}:{},...e.method?{method:e.method}:{},...t?{url:t.value}:{},...void 0!==e.status?{status:e.status}:{},...void 0!==e.durationMs?{durationMs:e.durationMs}:{},...n?.value?{requestHeaders:n.value}:{},...r?.value?{responseHeaders:r.value}:{},...i?.value!==void 0?{requestBody:i.value}:{},...o?.value!==void 0?{responseBody:o.value}:{},...l.value?{metadata:l.value}:{}}}),...n.nextCursor?{nextCursor:n.nextCursor}:{},...n.timeWindow?{timeWindow:n.timeWindow}:{},...n.backend?{backend:n.backend}:{},redacted:s,...n.notes?{notes:n.notes}:{}}},n_=async(e,t={})=>{var n,a;let i;if(!e.backend.measurePerf)throw new r("UNSUPPORTED_OPERATION","diagnostics.perf is not supported by this backend");return i=!0===(n=await e.backend.measurePerf(await n$(e,t),{...nT(a=t),...void 0!==a.sampleMs?{sampleMs:th(a.sampleMs,"sampleMs",100,6e4)}:{},...void 0!==a.metrics?{metrics:nL(a.metrics,"metrics",20)}:{}})).redacted,{kind:"diagnosticsPerf",metrics:n.metrics.map(e=>{let t=nM(e.message,4096),n=nN(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}:{}}};async function n$(e,t){let n=eK(e,t),a=t.session?await e.sessions.get(t.session):void 0;return{...n,...t.appId??a?.appId?{appId:t.appId??a?.appId}:{},...t.appBundleId??a?.appBundleId?{appBundleId:t.appBundleId??a?.appBundleId}:{}}}function nE(e,t,n,a){return{...nT(e),...void 0!==e.cursor?{cursor:nC(e.cursor,"cursor")}:{},limit:void 0===e.limit?t:th(e.limit,a,1,n)}}function nT(e){return{...void 0!==e.since?{since:nC(e.since,"since")}:{},...void 0!==e.until?{until:nC(e.until,"until")}:{}}}function nL(e,t,n=50){if(!Array.isArray(e))throw new r("INVALID_ARGS",`${t} must be an array of strings`);if(e.length>n)throw new r("INVALID_ARGS",`${t} must contain at most ${n} entries`);return e.map((e,n)=>nC(e,`${t}[${n}]`))}function nC(e,t){let n=e.trim();if(!n)throw new r("INVALID_ARGS",`${t} must be a non-empty string`);return n}let nU=[{command:"screenshot",category:"portable-runtime",status:"implemented"},{command:"diff screenshot",category:"portable-runtime",status:"implemented"},{command:"snapshot",category:"portable-runtime",status:"implemented"},{command:"diff snapshot",category:"portable-runtime",status:"implemented"},{command:"capture.screenshot",category:"portable-runtime",status:"implemented"},{command:"capture.diffScreenshot",category:"portable-runtime",status:"implemented"},{command:"capture.snapshot",category:"portable-runtime",status:"implemented"},{command:"capture.diffSnapshot",category:"portable-runtime",status:"implemented"},{command:"find read-only",category:"portable-runtime",status:"implemented"},{command:"get",category:"portable-runtime",status:"implemented"},{command:"is",category:"portable-runtime",status:"implemented"},{command:"wait",category:"portable-runtime",status:"implemented"},{command:"selectors.find",category:"portable-runtime",status:"implemented"},{command:"selectors.get",category:"portable-runtime",status:"implemented"},{command:"selectors.is",category:"portable-runtime",status:"implemented"},{command:"selectors.wait",category:"portable-runtime",status:"implemented"},{command:"alert",category:"portable-runtime",status:"planned"},{command:"click",category:"portable-runtime",status:"implemented"},{command:"press",category:"portable-runtime",status:"implemented"},{command:"fill",category:"portable-runtime",status:"implemented"},{command:"interactions.click",category:"portable-runtime",status:"implemented"},{command:"interactions.press",category:"portable-runtime",status:"implemented"},{command:"interactions.fill",category:"portable-runtime",status:"implemented"},{command:"interactions.typeText",category:"portable-runtime",status:"implemented"},{command:"longpress",category:"portable-runtime",status:"planned"},{command:"swipe",category:"portable-runtime",status:"planned"},{command:"focus",category:"portable-runtime",status:"planned"},{command:"type",category:"portable-runtime",status:"implemented"},{command:"scroll",category:"portable-runtime",status:"planned"},{command:"pinch",category:"portable-runtime",status:"planned"},{command:"interactions.focus",category:"portable-runtime",status:"implemented"},{command:"interactions.longPress",category:"portable-runtime",status:"implemented"},{command:"interactions.swipe",category:"portable-runtime",status:"implemented"},{command:"interactions.scroll",category:"portable-runtime",status:"implemented"},{command:"interactions.pinch",category:"portable-runtime",status:"implemented"},{command:"open",category:"portable-runtime",status:"planned"},{command:"close",category:"portable-runtime",status:"planned"},{command:"apps",category:"portable-runtime",status:"planned"},{command:"appstate",category:"portable-runtime",status:"planned"},{command:"apps.open",category:"portable-runtime",status:"implemented"},{command:"apps.close",category:"portable-runtime",status:"implemented"},{command:"apps.list",category:"portable-runtime",status:"implemented"},{command:"apps.state",category:"portable-runtime",status:"implemented"},{command:"apps.push",category:"portable-runtime",status:"implemented"},{command:"apps.triggerEvent",category:"portable-runtime",status:"implemented"},{command:"back",category:"portable-runtime",status:"planned"},{command:"home",category:"portable-runtime",status:"planned"},{command:"rotate",category:"portable-runtime",status:"planned"},{command:"app-switcher",category:"portable-runtime",status:"planned"},{command:"keyboard",category:"portable-runtime",status:"planned"},{command:"clipboard",category:"portable-runtime",status:"planned"},{command:"settings",category:"portable-runtime",status:"planned"},{command:"system.back",category:"portable-runtime",status:"implemented"},{command:"system.home",category:"portable-runtime",status:"implemented"},{command:"system.rotate",category:"portable-runtime",status:"implemented"},{command:"system.appSwitcher",category:"portable-runtime",status:"implemented"},{command:"system.keyboard",category:"portable-runtime",status:"implemented"},{command:"system.clipboard",category:"portable-runtime",status:"implemented"},{command:"system.settings",category:"portable-runtime",status:"implemented"},{command:"system.alert",category:"portable-runtime",status:"implemented"},{command:"push",category:"portable-runtime",status:"planned"},{command:"trigger-app-event",category:"portable-runtime",status:"planned"},{command:"devices",category:"backend-admin",status:"implemented"},{command:"boot",category:"backend-admin",status:"implemented"},{command:"ensure-simulator",category:"backend-admin",status:"implemented"},{command:"install",category:"backend-admin",status:"implemented"},{command:"reinstall",category:"backend-admin",status:"implemented"},{command:"install-from-source",category:"backend-admin",status:"implemented"},{command:"admin.devices",category:"backend-admin",status:"implemented"},{command:"admin.boot",category:"backend-admin",status:"implemented"},{command:"admin.ensureSimulator",category:"backend-admin",status:"implemented"},{command:"admin.install",category:"backend-admin",status:"implemented"},{command:"admin.reinstall",category:"backend-admin",status:"implemented"},{command:"admin.installFromSource",category:"backend-admin",status:"implemented"},{command:"session",category:"transport-session",status:"planned"},{command:"connect",category:"environment",status:"planned"},{command:"disconnect",category:"environment",status:"planned"},{command:"connection",category:"environment",status:"planned"},{command:"metro",category:"environment",status:"planned"},{command:"record",category:"capability-gated",status:"implemented"},{command:"trace",category:"capability-gated",status:"implemented"},{command:"replay",category:"capability-gated",status:"planned"},{command:"test",category:"capability-gated",status:"planned"},{command:"batch",category:"capability-gated",status:"implemented"},{command:"logs",category:"capability-gated",status:"implemented"},{command:"network",category:"capability-gated",status:"implemented"},{command:"perf",category:"capability-gated",status:"implemented"},{command:"diagnostics.logs",category:"capability-gated",status:"implemented"},{command:"diagnostics.network",category:"capability-gated",status:"implemented"},{command:"diagnostics.perf",category:"capability-gated",status:"implemented"}];async function nF(e,t){let n=function(e,t){let n=t??50;if(!Number.isInteger(n)||n<1||n>50)throw new r("INVALID_ARGS","batch maxSteps must be an integer between 1 and 50");if(!Array.isArray(e)||0===e.length)throw new r("INVALID_ARGS","batch requires a non-empty steps array");if(e.length>n)throw new r("INVALID_ARGS",`batch has ${e.length} steps; max allowed is ${n}`);for(let t=0;t<e.length;t+=1){let n=e[t];if(!n||"object"!=typeof n||"string"!=typeof n.command)throw new r("INVALID_ARGS",`Invalid batch step at index ${t}`);if("batch"===n.command)throw new r("INVALID_ARGS",`Batch step ${t+1} cannot run ${n.command}`)}return e}(e.options.steps,e.options.maxSteps),a=Date.now(),i=[];for(let a=0;a<n.length;a+=1){let r=function(e,t,n){var a;return{...e,context:e.context??n,options:{...(a=t).session?{session:a.session}:{},...a.requestId?{requestId:a.requestId}:{},...a.signal?{signal:a.signal}:{},...a.metadata?{metadata:a.metadata}:{},...e.options??{}}}}(n[a],e.options,e.context),s=Date.now(),o=await t(r),l=Date.now()-s;if(o.ok){i.push({step:a+1,command:r.command,ok:!0,data:o.data,durationMs:l});continue}if(i.push({step:a+1,command:r.command,ok:!1,error:o.error,durationMs:l}),!1!==e.options.stopOnError)break}return{kind:"batch",total:n.length,executed:i.length,failed:i.filter(e=>!e.ok).length,totalDurationMs:Date.now()-a,results:i}}function nq(e){let t=async n=>{try{if(function(e){if("batch"===e.command||Object.hasOwn(nX,e.command))return;let t=nU.find(t=>t.command===e.command);if(t?.status==="planned")throw new r("NOT_IMPLEMENTED",`Command ${e.command} is planned but not implemented in the runtime router yet`,{command:e.command});throw new r("UNSUPPORTED_OPERATION",`Unknown runtime command: ${e.command}`,{command:e.command})}(n),await e.beforeDispatch?.(n),"batch"===n.command)return{ok:!0,data:await nF(n,t)};let a=await e.createRuntime(n);return{ok:!0,data:await nV(a,n)}}catch(t){return{ok:!1,error:e.formatError?.(t,n)??i(t)}}};return{dispatch:t}}function nG(e){return async(t,n)=>await e(t,n.options)}let nX={"capture.screenshot":nG(S),"capture.diffScreenshot":nG(eg),"capture.snapshot":nG(eJ),"capture.diffSnapshot":nG(eZ),"selectors.find":nG(te),"selectors.get":nG(tt),"selectors.is":nG(tr),"selectors.wait":nG(to),"interactions.click":nG(tq),"interactions.press":nG(tF),"interactions.fill":nG(tG),"interactions.typeText":nG(tX),"interactions.focus":nG(tM),"interactions.longPress":nG(tS),"interactions.swipe":nG(tO),"interactions.scroll":nG(tP),"interactions.pinch":nG(tD),"system.back":nG(tB),"system.home":nG(tj),"system.rotate":nG(tH),"system.keyboard":nG(tK),"system.clipboard":nG(tz),"system.settings":nG(tW),"system.alert":nG(tJ),"system.appSwitcher":nG(tZ),"apps.open":nG(t2),"apps.close":nG(t5),"apps.list":nG(t4),"apps.state":nG(t3),"apps.push":nG(t8),"apps.triggerEvent":nG(t6),"admin.devices":nG(nr),"admin.boot":nG(ni),"admin.ensureSimulator":nG(ns),"admin.install":nG(no),"admin.reinstall":nG(nl),"admin.installFromSource":nG(nc),record:nG(ng),trace:nG(ny),"diagnostics.logs":nG(nO),"diagnostics.network":nG(nD),"diagnostics.perf":nG(n_)};async function nV(e,t){let n=nX[t.command];if(!n)throw new r("UNSUPPORTED_OPERATION",`Router command ${t.command} is not a runtime command`);return await n(e,t)}let nY={capture:{screenshot:S,diffScreenshot:eg,snapshot:eJ,diffSnapshot:eZ},selectors:{find:te,get:tt,getText:tn,getAttrs:ta,is:tr,isVisible:ti,isHidden:ts,wait:to,waitForText:tl},interactions:{click:tq,press:tF,fill:tG,typeText:tX,focus:tM,longPress:tS,swipe:tO,scroll:tP,pinch:tD},system:{back:tB,home:tj,rotate:tH,keyboard:tK,clipboard:tz,settings:tW,alert:tJ,appSwitcher:tZ},apps:{open:t2,close:t5,list:t4,state:t3,push:t8,triggerEvent:t6},admin:{devices:nr,boot:ni,ensureSimulator:ns,install:no,reinstall:nl,installFromSource:nc},recording:{record:ng,trace:ny},diagnostics:{logs:nO,network:nD,perf:n_}};function nB(e){return{capture:{screenshot:t=>nY.capture.screenshot(e,t),diffScreenshot:t=>nY.capture.diffScreenshot(e,t),snapshot:t=>nY.capture.snapshot(e,t),diffSnapshot:t=>nY.capture.diffSnapshot(e,t)},selectors:{find:t=>nY.selectors.find(e,t),get:t=>nY.selectors.get(e,t),getText:(t,n={})=>nY.selectors.getText(e,{...n,target:t}),getAttrs:(t,n={})=>nY.selectors.getAttrs(e,{...n,target:t}),is:t=>nY.selectors.is(e,t),isVisible:(t,n={})=>nY.selectors.isVisible(e,{...n,target:t}),isHidden:(t,n={})=>nY.selectors.isHidden(e,{...n,target:t}),wait:t=>nY.selectors.wait(e,t),waitForText:(t,n={})=>nY.selectors.waitForText(e,{...n,text:t})},interactions:{click:(t,n={})=>nY.interactions.click(e,{...n,target:t}),press:(t,n={})=>nY.interactions.press(e,{...n,target:t}),fill:(t,n,a={})=>nY.interactions.fill(e,{...a,target:t,text:n}),typeText:(t,n={})=>nY.interactions.typeText(e,{...n,text:t}),focus:(t,n={})=>nY.interactions.focus(e,{...n,target:t}),longPress:(t,n={})=>nY.interactions.longPress(e,{...n,target:t}),swipe:t=>nY.interactions.swipe(e,t),scroll:t=>nY.interactions.scroll(e,t),pinch:t=>nY.interactions.pinch(e,t)},system:{back:t=>nY.system.back(e,t),home:t=>nY.system.home(e,t),rotate:t=>nY.system.rotate(e,t),keyboard:t=>nY.system.keyboard(e,t),clipboard:t=>nY.system.clipboard(e,t),settings:t=>nY.system.settings(e,t),alert:t=>nY.system.alert(e,t),appSwitcher:t=>nY.system.appSwitcher(e,t)},apps:{open:t=>nY.apps.open(e,t),close:t=>nY.apps.close(e,t),list:t=>nY.apps.list(e,t),state:t=>nY.apps.state(e,t),push:t=>nY.apps.push(e,t),triggerEvent:t=>nY.apps.triggerEvent(e,t)},admin:{devices:t=>nY.admin.devices(e,t),boot:t=>nY.admin.boot(e,t),ensureSimulator:t=>nY.admin.ensureSimulator(e,t),install:t=>nY.admin.install(e,t),reinstall:t=>nY.admin.reinstall(e,t),installFromSource:t=>nY.admin.installFromSource(e,t)},recording:{record:t=>nY.recording.record(e,t),trace:t=>nY.recording.trace(e,t)},observability:{logs:t=>nY.diagnostics.logs(e,t),network:t=>nY.diagnostics.network(e,t),perf:t=>nY.diagnostics.perf(e,t)}}}export{nB as bindCommands,nU as commandCatalog,nY as commands,nq as createCommandRouter,e9 as selector,e7 as ref};