agent-device 0.14.2 → 0.14.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.14.2.apk → agent-device-android-snapshot-helper-0.14.4.apk} +0 -0
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.14.4.apk.sha256 +1 -0
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.14.2.manifest.json → agent-device-android-snapshot-helper-0.14.4.manifest.json} +6 -6
- package/dist/src/180.js +1 -0
- package/dist/src/2007.js +23 -30
- package/dist/src/221.js +4 -4
- package/dist/src/6642.js +1 -0
- package/dist/src/7599.js +3 -0
- package/dist/src/8809.js +8 -0
- package/dist/src/9542.js +2 -2
- package/dist/src/9639.js +2 -0
- package/dist/src/9818.js +1 -1
- package/dist/src/android-adb.d.ts +190 -0
- package/dist/src/android-adb.js +1 -0
- package/dist/src/android-snapshot-helper.d.ts +94 -7
- package/dist/src/internal/bin.js +54 -51
- package/dist/src/internal/companion-tunnel.js +1 -1
- package/dist/src/internal/daemon.js +22 -21
- package/package.json +5 -5
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.14.2.apk.sha256 +0 -1
- package/dist/src/8161.js +0 -3
- package/dist/src/9366.js +0 -1
- package/dist/src/android-apps.d.ts +0 -12
- package/dist/src/android-apps.js +0 -1
package/dist/src/2007.js
CHANGED
|
@@ -1,33 +1,26 @@
|
|
|
1
|
-
let e;import{__webpack_require__ as t}from"./rslib-runtime.js";import n,{existsSync as a,promises as r}from"node:fs";import{PNG as i}from"pngjs";import o from"node:path";import s,{hostname as l}from"node:os";import d from"node:net";import{AsyncLocalStorage as u}from"node:async_hooks";import{fileURLToPath as c}from"node:url";import{XMLParser as p}from"fast-xml-parser";import{createHash as f}from"node:crypto";import h from"node:fs/promises";import{toAppErrorCode as m,asAppError as w,normalizeError as g,AppError as y}from"./9152.js";import{splitSelectorFromArgs as b,trimText as v,extractNodeText as I,tryParseSelectorChain as A,parseSelectorChain as x,isNodeVisible as S,isNodeEditable as N,pruneGroupNodes as _,buildTextPreview as M,findNearestHittableAncestor as k,buildSelectorChainForNode as D,extractNodeReadText as E,splitIsSelectorArgs as O,findNodeByLabel as C,resolveRefLabel as R,describeTextSurface as P,extractReadableText as T,findSelectorChainMatch as L,resolveSelectorChain as $,normalizeType as F,formatSelectorFailure as U,isFillableType as G}from"./940.js";import{findNodeByRef as V,centerOfRect as B,normalizeRef as j,attachRefs as q}from"./4057.js";import{parseUiHierarchy as W,ensureAndroidSnapshotHelper as X,parseUiHierarchyTree as H,readNodeAttributes as z,captureAndroidSnapshotWithHelper as Y,parseBounds as K,isScrollableNodeLike as J,parseAndroidSnapshotHelperManifest as Z,forgetAndroidSnapshotHelperInstall as Q,isScrollableType as ee,buildUiHierarchySnapshot as et}from"./221.js";import{readVersion as en,findProjectRoot as ea,getDiagnosticsMeta as er,successText as ei,withDiagnosticTimer as eo,withSuccessText as es,emitDiagnostic as el}from"./8161.js";import{runCmdStreaming as ed,runCmdDetached as eu,runCmdBackground as ec,runCmdSync as ep,runCmd as ef,resolveFileOverridePath as eh,whichCmd as em,resolveExecutableOverridePath as ew}from"./9818.js";import{findBestMatchesByLocator as eg,parseFindArgs as ey}from"./7556.js";import"./7847.js";import{sleep as eb,resolveTimeoutMs as ev,resolveTimeoutSeconds as eI}from"./4829.js";import{isProcessGroupAlive as eA,isProcessAlive as ex,readProcessStartTime as eS}from"./8656.js";import{ensureAndroidSdkPathConfigured as eN,resolveAndroidArchivePackageName as e_}from"./7651.js";import{materializeInstallablePath as eM,isTrustedInstallSourceUrl as ek}from"./989.js";import{parseAndroidForegroundApp as eD,parseAndroidLaunchablePackages as eE,parseAndroidUserInstalledPackages as eO}from"./9366.js";var eC={};t.r(eC),t.d(eC,{ensureAndroidEmulatorBooted:()=>oj,listAndroidDevices:()=>o$,waitForAndroidBoot:()=>oq});var eR={};t.r(eR),t.d(eR,{TM:()=>dM,ensureBootedSimulator:()=>lP,installIosApp:()=>dD,installIosInstallablePath:()=>dO,listIosApps:()=>dL,L5:()=>dN,IJ:()=>d_,TJ:()=>dP,J7:()=>dC,reinstallIosApp:()=>dE,resolveIosApp:()=>dS,kc:()=>ds,Cm:()=>dT,ap:()=>dR});let eP="<wifi|airplane|location> <on|off>",eT="animations <on|off>",eL="appearance <light|dark|toggle>",e$="faceid <match|nonmatch|enroll|unenroll>",eF="touchid <match|nonmatch|enroll|unenroll>",eU="fingerprint <match|nonmatch>",eG="permission <grant|deny|reset> <camera|microphone|photos|contacts|contacts-limited|notifications|calendar|location|location-always|media-library|motion|reminders|siri> [full|limited]",eV="permission <grant|reset> <accessibility|screen-recording|input-monitoring>",eB=`macOS supports only settings ${eL} and settings ${eV}. wifi|airplane|location|animations remain unsupported on macOS.`,ej=`settings ${eP} | settings ${eT} | settings ${eL} | settings ${e$} | settings ${eF} | settings ${eU} | settings ${eG} | settings ${eV}`,eq=`settings requires ${eP}, ${eT}, ${eL}, ${e$}, ${eF}, ${eU}, ${eG}, or ${eV}`;function eW(e){return`Unsupported macOS setting: ${e}. ${eB}`}let eX=["app","frontmost-app","desktop","menubar"];function eH(e){let t=e?.trim().toLowerCase();if("app"===t||"frontmost-app"===t||"desktop"===t||"menubar"===t)return t;throw new y("INVALID_ARGS",`Invalid surface: ${e}. Use ${eX.join("|")}.`)}let ez={application:"application",navigationbar:"navigation-bar",tabbar:"tab-bar",button:"button",imagebutton:"button",link:"link",cell:"cell",statictext:"text",checkedtextview:"text",textfield:"text-field",edittext:"text-field",textarea:"text-view",switch:"switch",slider:"slider",image:"image",imageview:"image",webview:"webview",framelayout:"group",linearlayout:"group",relativelayout:"group",constraintlayout:"group",viewgroup:"group",view:"group",listview:"list",recyclerview:"list",collectionview:"collection",searchfield:"search",segmentedcontrol:"segmented-control",group:"group",window:"window",checkbox:"checkbox",radio:"radio",menuitem:"menu-item",toolbar:"toolbar",scrollarea:"scroll-area",scrollview:"scroll-area",nestedscrollview:"scroll-area",table:"table"};function eY(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()||"",o=eZ(r.type??"Element");if("group"===o&&!i)continue;for(;n.length>0&&e<=n[n.length-1];)n.pop();let s=n.length;n.push(e),a.push({node:r,depth:s,type:o,text:eK(r,s,!1,o,t)})}return a}function eK(e,t,n,a,r={}){var i,o,s,l,d,u,c,p;let f,h=a??eZ(e.type??"Element"),m=P(e,h),w=(i=e,o=h,s=r,l=m,s.summarizeTextSurfaces&&l.shouldSummarize&&function(e,t,n){let a=v(e.label);if(a&&a!==n)return a;let r=v(e.identifier);if(r&&!e0(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""}}(i,o,l.text)||eJ(i,o)),g=" ".repeat(t),y=e.ref?`@${e.ref}`:"",b=(d=e,u=h,c=r,p=m,f=[],(!1===d.enabled&&f.push("disabled"),c.summarizeTextSurfaces&&(!0===d.selected&&f.push("selected"),eQ(u)&&f.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")}(d,u)&&f.push("scrollable"),p.shouldSummarize))?(f.push(`preview:"${M(p.text).replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`),f.push("truncated"),[...new Set(f)]):f).map(e=>` [${e}]`).join(""),I=w?` "${w}"`:"";return n?`${g}${y} [${h}]${b}`.trimEnd():`${g}${y} [${h}]${I}${b}`.trimEnd()}function eJ(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 o=e.value?.trim();if(eQ(t)){if(o)return o;if(i)return i}else if(i)return i;if(o)return o;let s=e.identifier?.trim();return!s||e0(s)&&("group"===t||"image"===t||"list"===t||"collection"===t)?"":s}function eZ(e){var t;let n=e.replace(/XCUIElementType/gi,"").toLowerCase(),a=e.includes(".")&&(e.startsWith("android.")||e.startsWith("androidx.")||e.startsWith("com."));return(n.includes(".")&&(n=n.replace(/^android\.widget\./,"").replace(/^android\.view\./,"").replace(/^android\.webkit\./,"").replace(/^androidx\./,"").replace(/^com\.google\.android\./,"").replace(/^com\.android\./,""),a&&n.includes(".")&&(n=n.slice(n.lastIndexOf(".")+1))),"textview"===n)?a?"text":"text-view":(t=n,(Object.prototype.hasOwnProperty.call(ez,t)?ez[t]:void 0)||n||"element")}function eQ(e){return"text-field"===e||"text-view"===e||"search"===e}function e0(e){return/^[\w.]+:id\/[\w.-]+$/i.test(e)}function e1(e){return new Map(e.map(e=>[e.index,e]))}function e2(e){return e.label?.trim()||e.value?.trim()||e.identifier?.trim()||""}function e3(e,t,n){return t>=e.x&&t<=e.x+e.width&&n>=e.y&&n<=e.y+e.height}function e4(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 e5(e,t,n,a){return Math.max(e,n)<=Math.min(t,a)}function e8(e){if(0===e.length)return{nodes:e,hiddenCount:0,summaryLines:[]};let{byIndex:t,visibleNodeIndexes:n,offscreenNodes:a,hintedContainers:r}=e6(e),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=e7(e,t,n);return a?te(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=e2(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")||!!e2(e)}(e)),e,t)}}function e6(e){let t=e1(e),n=new Set,a=[];for(let r of e){if(e9(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=tt(e,n,a);if(!t?.rect)continue;let o=te(e.rect,t.rect);if(!o)continue;let s=r.get(t.index)??new Set;s.add(o),r.set(t.index,s),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=tt(r,t,n);if(!i)continue;let o=a.get(i.index)??new Set;for(let t of e)o.add(t);a.set(i.index,o)}}(e,n,a,r),{directionsByContainer:r,coveredNodeIndexes:i}}(e,a,n,t);return{byIndex:t,visibleNodeIndexes:n,offscreenNodes:a,hintedContainers:r}}function e9(e,t,n=e1(t)){var a;if(!e.rect)return!0;let r=e7(e,t,n);return!r||(a=e.rect,e5(a.x,a.x+a.width,r.x,r.x+r.width)&&e5(a.y,a.y+a.height,r.y,r.y+r.height))}function e7(e,t,n=e1(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&&J(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=B(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=e4(r.map(e=>e.rect).filter(e=>e3(e,n.x,n.y)));if(i)return i;let o=e4(r.map(e=>e.rect));if(o)return o;let s=e4(a.map(e=>e.rect).filter(e=>e3(e,n.x,n.y)));return s||null}(t,e.rect??{x:0,y:0,width:0,height:0})}function te(e,t){return e.y+e.height<=t.y?"above":e.y>=t.y+t.height?"below":null}function tt(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)&&J(a))return a;a="number"==typeof a.parentIndex?n.get(a.parentIndex):void 0}return null}function tn(e,t){try{return i.sync.read(e)}catch(e){throw new y("COMMAND_FAILED",`Failed to decode ${t} as PNG`,{label:t,reason:e instanceof Error?e.message:String(e)})}}async function ta(e,t){if(!Number.isInteger(t)||t<1)throw new y("INVALID_ARGS","Screenshot max size must be a positive integer");let n=tn(await r.readFile(e),"screenshot"),a=Math.max(n.width,n.height);if(a<=t)return;let o=t/a,s=Math.max(1,Math.round(n.width*o)),l=Math.max(1,Math.round(n.height*o)),d=function(e,t,n){let a=new i({width:t,height:n});for(let r=0;r<n;r+=1){let i=r*e.height/n,o=(r+1)*e.height/n;for(let n=0;n<t;n+=1){let s=n*e.width/t,l=(n+1)*e.width/t,d=0,u=0,c=0,p=0,f=0;for(let t=Math.floor(i);t<Math.ceil(o);t+=1){let n=Math.min(t+1,o)-Math.max(t,i);for(let a=Math.floor(s);a<Math.ceil(l);a+=1){let r=n*(Math.min(a+1,l)-Math.max(a,s)),i=(t*e.width+a)*4;d+=(e.data[i]??0)*r,u+=(e.data[i+1]??0)*r,c+=(e.data[i+2]??0)*r,p+=(e.data[i+3]??0)*r,f+=r}}let h=(r*a.width+n)*4;a.data[h]=Math.round(d/f),a.data[h+1]=Math.round(u/f),a.data[h+2]=Math.round(c/f),a.data[h+3]=Math.round(p/f)}}return a}(n,s,l);await r.writeFile(e,i.sync.write(d))}async function tr(e,t,n){if("path"===t.kind&&!e.policy.allowLocalInputPaths)throw new y("INVALID_ARGS",`Local ${n.field??"input"} paths are not allowed by command policy`);try{return await e.artifacts.resolveInput(t,n)}catch(e){throw w(e)}}async function ti(e,t,n){if(t?.kind==="path"&&!e.policy.allowLocalOutputPaths)throw new y("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 w(e)}}async function to(e,t){try{return await e.artifacts.createTempFile(t)}catch(e){throw w(e)}}let ts=[0,187,255,255];function tl(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 td(e,t,n){return Math.min(Math.max(e,t),n)}let tu={icon:90,toggle:90,chevron:75,separator:45,visual:35,background:10},tc={leading:20,trailing:20,separator:10,unknown:0,background:-30};function tp(e){return"background"!==e.likelyKind}function tf(e,t){return e.width>=.25*t.width||e.height>=.06*t.height}function th(e,t){let n,a=0;for(let r of t){let t=tb(e,r.rect);t<=a||(a=t,n=r)}return n}function tm(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,tb(t,a=n.rect)>0||Math.abs(tv(t).y-tv(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 tw(e,t){let n,a=tv(e);for(let e of t){var r,i;let t=Math.sqrt((r=a,i=tv(e.rect),(r.x-i.x)**2+(r.y-i.y)**2));n&&t>=n.distance||(n={block:e,distance:t})}return n}function tg(e){let t=ty(e);return e.differentPixels>=24&&t.width>=3&&t.height>=3}function ty(e){return{x:e.minX,y:e.minY,width:e.maxX-e.minX+1,height:e.maxY-e.minY+1}}function tb(e,t){return Math.max(0,Math.min(e.y+e.height,t.y+t.height)-Math.max(e.y,t.y))}function tv(e){return{x:e.x+e.width/2,y:e.y+e.height/2}}function tI(e,t,n){return Math.min(Math.max(e,t),n)}async function tA(e){if(await em("tesseract"))try{let[t,n]=await Promise.all([tS(e.baselinePath),tS(e.currentPath)]);if(0!==t.exitCode||0!==n.exitCode)return;let a=tx(t.stdout,e.width,e.height),r=tx(n.stdout,e.width,e.height),i=function(e,t){let n=new Set,a=[];for(let i of e){var r;let e=tO(i.text),o=function(e,t,n,a){let r=null,i=1/0;for(let l=0;l<n.length;l+=1){var o,s;if(a.has(l))continue;let d=n[l];if(tO(d.text)!==t)continue;let u=(o=tk(e.normalizedRect),s=tk(d.normalizedRect),(o.x-s.x)**2+(o.y-s.y)**2);u>=i||(r=l,i=u)}return r}(i,e,t,n);if(null===o)continue;n.add(o);let s=function(e,t){let n={x:t.rect.x-e.rect.x,y:t.rect.y-e.rect.y,width:t.rect.width-e.rect.width,height:t.rect.height-e.rect.height},a=tP(t.rect.width/e.rect.width),r=tP(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[o]);r=s,(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(s)}return a.sort((e,t)=>tN(t)-tN(e)).slice(0,12)}(a,r),o=function(e){let t=[];for(let n of[...e].sort((e,t)=>e.currentRect.y-t.currentRect.y)){let e=t.find(e=>32>=Math.abs(n.delta.x-tC(e.map(e=>e.delta.x))));e?e.push(n):t.push([n])}return t.filter(e=>e.length>=2).map(t_).filter(e=>e.yRange.max-e.yRange.min<=60).sort((e,t)=>tM(t)-tM(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,...o.length>0?{movementClusters:o}:{}}}catch{return}}function tx(e,t,n){let[a,...r]=e.split(/\r?\n/);if(!a)return[];let i=new Map(a.split(" ").map((e,t)=>[e,t])),o=[];for(let e of r){var s;if(!e.trim())continue;let t=e.split(" "),n=tE(t,i,"level"),a=tD(t,i,"text").trim(),r=tE(t,i,"conf");if(5!==n||(s=a,!/[\p{L}\p{N}]/u.test(s))||r<0)continue;let l=tE(t,i,"left"),d=tE(t,i,"top"),u=tE(t,i,"width"),c=tE(t,i,"height");u<=0||c<=0||o.push({key:[tD(t,i,"page_num"),tD(t,i,"block_num"),tD(t,i,"par_num"),tD(t,i,"line_num")].join(":"),text:a,confidence:r,rect:{x:l,y:d,width:u,height:c}})}let l=new Map;for(let e of o){let t=l.get(e.key);t?t.push(e):l.set(e.key,[e])}return Array.from(l.values()).flatMap(e=>(function(e){let t=[...e].sort((e,t)=>e.rect.x-t.rect.x),n=[],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*tC(a.map(e=>e.confidence)))/100;return{text:a.map(e=>e.text).join(" "),confidence:i,rect:r,normalizedRect:{x:tR(r.x/t),y:tR(r.y/n),width:tR(r.width/t),height:tR(r.height/n)}}})(e,t,n)).filter(e=>null!==e)}function tS(e){return ef("tesseract",[e,"stdout","-l","eng","tsv"],{allowFailure:!0,timeoutMs:1e4})}function tN(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 t_(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 tM(e){return 2*Math.abs((e.xRange.min+e.xRange.max)/2)+Math.abs((e.yRange.min+e.yRange.max)/2)}function tk(e){return{x:e.x+e.width/2,y:e.y+e.height/2}}function tD(e,t,n){let a=t.get(n);return void 0===a?"":e[a]??""}function tE(e,t,n){let a=Number(tD(e,t,n));return Number.isFinite(a)?a:0}function tO(e){return e.trim().replace(/\s+/g," ").toLowerCase()}function tC(e){return e.reduce((e,t)=>e+t,0)/e.length}function tR(e){return Math.round(100*e*100)/100}function tP(e){return Math.round(1e3*e)/1e3}function tT(e,t,n,a){return{r:Math.round(e/a),g:Math.round(t/a),b:Math.round(n/a)}}function tL(e){return .2126*e.r+.7152*e.g+.0722*e.b}function t$(e){return`#${tF(e.r)}${tF(e.g)}${tF(e.b)}`}function tF(e){return e.toString(16).padStart(2,"0")}function tU(e){return Math.round(100*e*100)/100}let tG=255*Math.sqrt(3);async function tV(e,t,n={}){let a,s,l,d;await tB(e,"Baseline image not found"),await tB(t,"Current screenshot not found");let u=n.outputPath,[c,p]=await Promise.all([r.readFile(e),r.readFile(t)]),f=tn(c,"baseline screenshot"),h=tn(p,"current screenshot");tj(f.width,f.height,"baseline screenshot",n.maxPixels),tj(h.width,h.height,"current screenshot",n.maxPixels);let m=n.threshold??.1;if(f.width!==h.width||f.height!==h.height){let e=f.width*f.height;return await tq(n.outputPath),{match:!1,mismatchPercentage:100,totalPixels:e,differentPixels:e,dimensionMismatch:{expected:{width:f.width,height:f.height},actual:{width:h.width,height:h.height}}}}let w=f.width*f.height,g=m*tG,y=new i({width:f.width,height:f.height}),b=new Uint8Array(w),v=0;for(let e=0,t=0;e<f.data.length;e+=4,t+=1){if(Math.sqrt((f.data[e]-h.data[e])**2+(f.data[e+1]-h.data[e+1])**2+(f.data[e+2]-h.data[e+2])**2)>g){v+=1,b[t]=1;let n=tW(h,e);y.data[e]=tX(n,220,.78),y.data[e+1]=tX(n,0,.78),y.data[e+2]=tX(n,0,.78),y.data[e+3]=255;continue}let n=tW(h,e);y.data[e]=n,y.data[e+1]=n,y.data[e+2]=n,y.data[e+3]=255}let I=v>0?(x=(a=function(e){let{diffMask:t,baseline:n,current:a}=e,{width:r,height:i}=n,o=new Uint8Array(t.length),s=new Int32Array(t.length),l=[];for(let e=0;e<t.length;e+=1){if(1!==t[e]||1===o[e])continue;let d=0,u=0;s[0]=e,u+=1,o[e]=1;let c=e%r,p=Math.floor(e/r),f={minX:c,minY:p,maxX:c,maxY:p,differentPixels:0,baselineRed:0,baselineGreen:0,baselineBlue:0,currentRed:0,currentGreen:0,currentBlue:0};for(;d<u;){let e=s[d];d+=1,function(e,t,n,a,r){let i=t%n,o=Math.floor(t/n),s=4*t;e.minX=Math.min(e.minX,i),e.minY=Math.min(e.minY,o),e.maxX=Math.max(e.maxX,i),e.maxY=Math.max(e.maxY,o),e.differentPixels+=1,e.baselineRed+=a.data[s],e.baselineGreen+=a.data[s+1],e.baselineBlue+=a.data[s+2],e.currentRed+=r.data[s],e.currentGreen+=r.data[s+1],e.currentBlue+=r.data[s+2]}(f,e,r,n,a);let l=e%r,c=Math.floor(e/r);for(let e=-1;e<=1;e+=1){let n=c+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 d=n*r+i;1===t[d]&&1!==o[d]&&(o[d]=1,s[u]=d,u+=1)}}}l.push(f)}return l}(A={diffMask:b,baseline:f,current:h,totalPixels:w,differentPixels:v,maxRegions:n.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}(a):a,x.flatMap(e=>{var t,n,a;let r;return(t=e,n=A.baseline.width,a=A.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),o=Math.min(a.length-1,t+3);for(let e=i;e<=o;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,o]of t){let t=e.minY+Math.round((i+o)/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 o=i.map(([n,a])=>(function(e,t,n,a){let r=null;for(let s=t;s<=n;s+=1)for(let t=e.minX;t<=e.maxX;t+=1){var i,o;let e=s*a.baseline.width+t;1===a.diffMask[e]&&function(e,t,n,a,r,i){let o=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[o],e.baselineGreen+=r.data[o+1],e.baselineBlue+=r.data[o+2],e.currentRed+=i.data[o],e.currentGreen+=i.data[o+1],e.currentBlue+=i.data[o+2]}(r??={minX:i=t,minY:o=s,maxX:i,maxY:o,differentPixels:0,baselineRed:0,baselineGreen:0,baselineBlue:0,currentRed:0,currentGreen:0,currentBlue:0},e,t,s,a.baseline,a.current)}return r})(e,n,a,t)).filter(e=>null!==e);return o.length>1?o:[e]}(e,A,Math.max(24,Math.round(.03*A.baseline.height))):[e]})).sort((e,t)=>{let n=t.differentPixels-e.differentPixels;if(0!==n)return n;let a=e.minY-t.minY;return 0!==a?a:e.minX-t.minX}).slice(0,Math.max(0,A.maxRegions??8)).map((e,t)=>{var n,a,r,i,o,s,l,d,u,c,p;let f,h,m,w,g,y,b,v,I,x,S,N,_,M,k,D,E;return n=e,a=t+1,r={width:A.baseline.width,height:A.baseline.height,totalPixels:A.totalPixels,differentPixels:A.differentPixels},y={x:n.minX,y:n.minY,width:n.maxX-n.minX+1,height:n.maxY-n.minY+1},b={x:Math.round(n.minX+y.width/2),y:Math.round(n.minY+y.height/2)},v=tT(n.baselineRed,n.baselineGreen,n.baselineBlue,n.differentPixels),I=tT(n.currentRed,n.currentGreen,n.currentBlue,n.differentPixels),x=y.width*y.height,S=tU(n.differentPixels/x),N=Math.round(tL(v)),_=Math.round(tL(I)),M=(i=y,o=r.width,s=r.height,i.width>=.55*o&&i.height>=.12*s?"large-area":i.width>=2.5*i.height?"horizontal-band":i.height>=2.5*i.width?"vertical-band":"compact"),k=(f=x/r.totalPixels)>=.04?"large":f>=.01?"medium":"small",D=(l=v,d=I,h=tL(l),Math.abs(m=tL(d)-h)>=12?m>0?"brighter":"darker":Math.max(Math.abs(d.r-l.r),Math.abs(d.g-l.g),Math.abs(d.b-l.b))>=12?"color-shift":"mixed"),E=(u=b,c=r.width,p=r.height,w=u.x<c/3?"left":u.x>2*c/3?"right":"center",g=u.y<p/3?"top":u.y>2*p/3?"bottom":"middle","center"===w&&"middle"===g?"center":`${g}-${w}`),{index:a,rect:y,normalizedRect:{x:tU(y.x/r.width),y:tU(y.y/r.height),width:tU(y.width/r.width),height:tU(y.height/r.height)},differentPixels:n.differentPixels,shareOfDiffPercentage:tU(n.differentPixels/r.differentPixels),densityPercentage:S,shape:M,size:k,location:E,averageBaselineColorHex:t$(v),averageCurrentColorHex:t$(I),baselineLuminance:N,currentLuminance:_,dominantChange:D}}):[];if(v>0&&u){var A,x,S;for(let e of I)e.rect.width<4||e.rect.height<4||function(e,t){let n=td(t.x,0,e.width-1),a=td(t.y,0,e.height-1),r=td(t.x+t.width-1,0,e.width-1),i=td(t.y+t.height-1,0,e.height-1);for(let t=0;t<2;t+=1){for(let o=n;o<=r;o+=1)tl(e,o,a+t,ts),tl(e,o,i-t,ts);for(let o=a;o<=i;o+=1)tl(e,n+t,o,ts),tl(e,r-t,o,ts)}}(y,e.rect);await r.mkdir(o.dirname(u),{recursive:!0}),await r.writeFile(u,i.sync.write(y))}else await tq(n.outputPath);let N=v>0?await tA({baselinePath:e,currentPath:t,width:f.width,height:f.height}):void 0,_=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=v>0&&N?(s=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 o=0;o<e.length;o+=1){if(1!==e[o]||1===a[o])continue;let s=0,l=0;r[0]=o,l+=1,a[o]=1;let d=o%t,u=Math.floor(o/t),c={minX:d,minY:u,maxX:d,maxY:u,differentPixels:0};for(;s<l;){let i=r[s];s+=1;let o=i%t,d=Math.floor(i/t);c.minX=Math.min(c.minX,o),c.minY=Math.min(c.minY,d),c.maxX=Math.max(c.maxX,o),c.maxY=Math.max(c.maxY,d),c.differentPixels+=1;for(let i=-1;i<=1;i+=1){let s=d+i;if(!(s<0)&&!(s>=n))for(let n=-1;n<=1;n+=1){if(0===n&&0===i)continue;let d=o+n;if(d<0||d>=t)continue;let u=s*t+d;1===e[u]&&1!==a[u]&&(a[u]=1,r[l]=u,l+=1)}}}i.push(c)}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=tI(Math.floor(a.x),0,t-1),i=tI(Math.floor(a.y),0,n-1),o=tI(Math.ceil(a.x+a.width),0,t),s=tI(Math.ceil(a.y+a.height),0,n);for(let n=i;n<s;n+=1)for(let a=r;a<o;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}((S={diffMask:b,width:f.width,height:f.height,regions:I,ocr:N}).diffMask,S.width,S.height,S.ocr),S.width,S.height)),l=tm(S.ocr?.currentBlocksRaw??[]),d=tm(S.ocr?.baselineBlocksRaw??[]),s.filter(tg).map(e=>{var t,n,a,r,i,o,s,u,c,p,f;let h,m,w,g,y,b,v,I,A,x;return t=e,n=S,a=l,r=d,g=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=ty(t),n.regions),y=function(e,t,n){let a=th(e,t);if(a)return tw(e,a.blocks);let r=th(e,n);return r?tw(e,r.blocks):void 0}(w,a,r),b=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,y?.block.rect,n.width),v=(i=w,o=b,s=t.differentPixels,u=n,h=i.width/i.height,m=s/(i.width*i.height),"separator"===o?"separator":"background"===o?"background":"trailing"===o&&h>=1.5&&h<=3.8&&m>=.35?"toggle":"trailing"===o&&i.width<=.06*u.width&&i.height<=.04*u.height?"chevron":"leading"===o&&h>=.55&&h<=1.8?"icon":tf(i,u)?"background":"visual"),I={...g?{regionIndex:g}:{},slot:b,likelyKind:v,rect:w},{...g?{regionIndex:g}:{},slot:b,likelyKind:v,rect:w,...y?{nearestText:y.block.text.trim().replace(/^[^\p{L}\p{N}]+/u,"").replace(/^\p{L}\s+/u,"")}:{},score:(c=I,p=t.differentPixels,f=n,A=tf(c.rect,f)?-35:0,x=20*!!c.regionIndex,tu[c.likelyKind]+tc[c.slot]+x+A+Math.min(20,p/200))}}).filter(e=>e.rect.y>=.08*S.height).filter(tp).sort((e,t)=>t.score-e.score).slice(0,Math.max(0,S.maxDeltas??12)).map((e,t)=>{var n;return n=e,{index:t+1,...n.regionIndex?{regionIndex:n.regionIndex}:{},slot:n.slot,likelyKind:n.likelyKind,rect:n.rect,...n.nearestText?{nearestText:n.nearestText}:{}}})):[],k=w>0?Math.round(v/w*1e4)/100:0;return{...v>0&&u?{diffPath:u}:{},...I.length>0?{regions:I}:{},..._?{ocr:_}:{},...M.length>0?{nonTextDeltas:M}:{},totalPixels:w,differentPixels:v,mismatchPercentage:k,match:0===v}}async function tB(e,t){try{await r.access(e)}catch{throw new y("INVALID_ARGS",`${t}: ${e}`)}}function tj(e,t,n,a){if(null==a||a<=0)return;let r=e*t;if(!(r<=a))throw new y("INVALID_ARGS",`${n} is ${r} pixels, which exceeds the configured maxImagePixels limit of ${a}`)}async function tq(e){if(e)try{await r.unlink(e)}catch(e){var t;if(!("object"==typeof(t=e)&&null!==t&&"code"in t&&"ENOENT"===t.code))throw e}}function tW(e,t){return tX(Math.round(.299*e.data[t]+.587*e.data[t+1]+.114*e.data[t+2]),255,.72)}function tX(e,t,n){return Math.round(e*(1-n)+t*n)}function tH(e){return e.width*e.height}function tz(e){return Math.round(100*e*100)/100}async function tY(e,t){let n=await to(e,{prefix:"agent-device-diff-current",ext:".png"});try{await tJ(e,t,n.path,tZ(t))}catch(e){throw await n.cleanup(),e}return n}async function tK(e,t,n,a,r){var i,o,s,l;if(!t.overlayRefs)return a;if(a.match||a.dimensionMismatch)return n&&await t0(n),a;let d=(i=t,o=n,i.currentOverlayOut?i.currentOverlayOut:i.out?.kind==="path"?{kind:"path",path:tQ(o??i.out.path)}:i.out?.kind==="downloadableArtifact"?{kind:"downloadableArtifact",...i.out.clientPath?{clientPath:tQ(i.out.clientPath)}:{},...i.out.fileName?{fileName:tQ(i.out.fileName)}:{}}:void 0),u=await ti(e,d,{field:"currentOverlayPath",ext:".png"});try{let n=await tJ(e,t,u.path,{overlayRefs:!0,...tZ(t)}),i=await u.publish();return i&&r.push(i),{...a,currentOverlayPath:n.path??u.path,...n.overlayRefs?{currentOverlayRefCount:n.overlayRefs.length}:{},...a.regions&&n.overlayRefs?{regions:(s=a.regions,l=n.overlayRefs,s.map(e=>{var t,n;let a,r=(t=e,n=l,a=tH(t.rect),n.map(e=>{var n,r;let i,o,s,l,d=e.overlayRect,u=(n=t.rect,r=d,i=Math.max(n.x,r.x),o=Math.max(n.y,r.y),s=Math.min(n.x+n.width,r.x+r.width),l=Math.min(n.y+n.height,r.y+r.height),s<=i||l<=o?0:(s-i)*(l-o));return u<=0?null:{ref:e.ref,...e.label?{label:e.label}:{},rect:d,overlayCoveragePercentage:tz(u/tH(d)),regionCoveragePercentage:tz(u/a)}}).filter(e=>null!==e).sort((e,t)=>{let n=t.regionCoveragePercentage-e.regionCoveragePercentage;return 0!==n?n:t.overlayCoveragePercentage-e.overlayCoveragePercentage}).slice(0,3).map(e=>({ref:e.ref,...e.label?{label:e.label}:{},rect:e.rect,regionCoveragePercentage:e.regionCoveragePercentage})));return r.length>0?{...e,currentOverlayMatches:r}:e}))}:{}}}catch(e){throw await u.cleanup?.(),e}}async function tJ(e,t,n,a={}){if(!e.backend.captureScreenshot)throw new y("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 tZ(e){return e.surface?{surface:e.surface}:{}}function tQ(e){let t=o.extname(e),n=t?e.slice(0,-t.length):e;return`${n}.current-overlay${t||".png"}`}async function t0(e){try{await r.unlink(tQ(e))}catch(e){var t;if(!("object"==typeof(t=e)&&null!==t&&"code"in t&&"ENOENT"===t.code))throw e}}function t1(e){return"live"===e.kind}function t2(e,t){let n=eZ(e.type??"Element"),a=eJ(e,n),r=!1===e.enabled?"disabled":"enabled",i=!0===e.selected?"selected":"unselected",o=!0===e.hittable?"hittable":"not-hittable";return[String(t??e.depth??0),n,a,r,i,o].join("|")}function t3(e,t){return t.flatten?e.map(e=>({text:eK(e,0,!1),comparable:t2(e,0)})):eY(e).map(e=>({text:e.text,comparable:t2(e.node,e.depth)}))}function t4(e,t){return e.get(t)??0}function t5(e){return"text"===e||"label"===e||"any"===e}function t8(e,t){return{session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata}}function t6(e){return e.clock?.now()??Date.now()}async function t9(e,t){e.clock?await e.clock.sleep(t):await new Promise(e=>setTimeout(e,t))}async function t7(e,t){var n,a,r,i,o;let s,l,d,u,c,p;if(!e.backend.captureSnapshot)throw new y("UNSUPPORTED_OPERATION","snapshot is not supported by this backend");let f=t.session??"default",h=await e.sessions.get(f),m=await e.backend.captureSnapshot({session:f,requestId:t.requestId,appId:h?.appId,appBundleId:h?.appBundleId,signal:t.signal??e.signal,metadata:t.metadata},{interactiveOnly:t.interactiveOnly,compact:t.compact,depth:t.depth,scope:t.scope,raw:t.raw}),w=(n=m,a=e,n.snapshot?n.snapshot:{nodes:n.nodes??[],truncated:n.truncated,backend:n.backend,createdAt:t6(a)}),g=t6(e);return{snapshot:w,result:m,session:h,warnings:(s=[...(r={result:m,snapshot:w,options:t,session:h,capturedAt:w.createdAt??g,runtimeNow:g}).result.warnings??[]],l=!0===r.options.interactiveOnly,d=r.result.analysis,"android"===r.snapshot.backend&&l&&0===r.snapshot.nodes.length&&d&&(d.rawNodeCount??0)>=12&&(s.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 r.options.depth&&"number"==typeof d.maxDepth&&d.maxDepth>=r.options.depth+2&&s.push(`Interactive output is empty at depth ${r.options.depth}; retry without -d.`)),c=!!(u=r.session?.snapshot)&&[r.capturedAt,r.runtimeNow].some(e=>{let t=e-u.createdAt;return t>=0&&t<=2e3}),!r.result.freshness&&u&&c&&(i=u.nodes.length,o=r.snapshot.nodes.length,!(i<12)&&o<=Math.floor(.2*i))&&s.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."),p=r.result.freshness,p?.staleAfterRetries&&"android"===r.snapshot.backend&&("stuck-route"===p.reason?s.push(`Recent ${p.action} was followed by a nearly identical snapshot after ${p.retryCount} automatic retr${1===p.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"===p.reason&&s.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(s)))}}function ne(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 nt(e){return["visible","hidden","exists","editable","selected","text"].includes(e)}function nn(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 na(e,t){let n=t??"default",a=await e.sessions.get(n);if(!a)throw new y("SESSION_NOT_FOUND","No active session. Run open first.");if(!a.snapshot)throw new y("INVALID_ARGS","No snapshot in session. Run snapshot first.");return{sessionName:n,session:a,snapshot:a.snapshot}}async function nr(e,t,n={updateSession:!0}){if(!e.backend.captureSnapshot)throw new y("UNSUPPORTED_OPERATION","snapshot is not supported by this backend");let a=t.session??"default",r=await e.sessions.get(a),i=await e.backend.captureSnapshot(t8(e,t),{interactiveOnly:!1,compact:!1,depth:t.depth,scope:n.scope??t.scope,raw:t.raw}),o=i.snapshot??{nodes:i.nodes??[],truncated:i.truncated,backend:i.backend,createdAt:t6(e)};return n.updateSession&&r&&await e.sessions.set({...r,snapshot:o}),{sessionName:a,session:r,snapshot:o}}async function ni(e,t,n){if(e.backend.readText){let a=await e.backend.readText(t8(e,{session:t.sessionName}),n);if(a.text.trim())return a.text}return T(n)}let no=async(e,t)=>{if("ref"===t.target.kind){let n=await na(e,t.session),a=function(e,t,n){let a=j(t);if(!a)throw new y("INVALID_ARGS",n.invalidRefMessage);let r=V(e,a)??(n.fallbackLabel.length>0?C(e,n.fallbackLabel):null);if(!r)throw new y("COMMAND_FAILED",n.notFoundMessage);return{ref:a,node:r}}(n.snapshot.nodes,t.target.ref,{fallbackLabel:t.target.fallbackLabel??"",invalidRefMessage:"get text requires a ref like @e2",notFoundMessage:`Ref ${t.target.ref} not found`}),r=D(a.node,e.backend.platform,{action:"get"}),i={kind:"ref",ref:`@${a.ref}`};return"attrs"===t.property?{kind:"attrs",target:i,node:a.node,selectorChain:r}:{kind:"text",target:i,text:await ni(e,n,a.node),node:a.node,selectorChain:r}}let n=await ny(e,t,t.session??"default",{selector:t.target.selector,disambiguateAmbiguous:"text"===t.property}),a=D(n.node,e.backend.platform,{action:"get"});if("attrs"===t.property)return{kind:"attrs",target:{kind:"selector",selector:n.selector},node:n.node,selectorChain:a};let r=await ni(e,n.capture,n.node);return{kind:"text",target:{kind:"selector",selector:n.selector},text:r,node:n.node,selectorChain:a}},ns=async(e,t)=>{let n=await no(e,{...t,property:"text",target:t.target});if("text"!==n.kind)throw new y("COMMAND_FAILED","getText returned non-text result");return n},nl=async(e,t)=>{let n=await no(e,{...t,property:"attrs",target:t.target});if("attrs"!==n.kind)throw new y("COMMAND_FAILED","getAttrs returned non-attrs result");return n},nd=async(e,t)=>{if(!nt(t.predicate))throw new y("INVALID_ARGS","is requires predicate: visible|hidden|exists|editable|selected|text");if("text"===t.predicate&&!t.expectedText)throw new y("INVALID_ARGS","is text requires expected text value");let n=await nr(e,t,{updateSession:!0}),a=x(t.selector);if("exists"===t.predicate){let r=L(n.snapshot.nodes,a,{platform:e.backend.platform});if(!r)throw new y("COMMAND_FAILED",U(a,[],{unique:!1}));return{predicate:t.predicate,pass:!0,selector:r.selector.raw,matches:r.matches,selectorChain:a.selectors.map(e=>e.raw)}}let r=$(n.snapshot.nodes,a,{platform:e.backend.platform,requireRect:!1,requireUnique:!0,disambiguateAmbiguous:!1});if(!r)throw new y("COMMAND_FAILED",U(a,[],{unique:!0}));let i=function(e){let{predicate:t,node:n,nodes:a,expectedText:r,platform:i}=e,o=I(n),s=N(n,i),l=!0===n.selected,d="text"===t?S(n):function(e,t){if(!0===e.hittable)return!0;if(nn(e.rect))return e9(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=F(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||nn(e.rect))}(e))return e;a=e}return null}(e,t);return!!n&&(!0===n.hittable||!!nn(n.rect)&&e9(n,t))}(n,a),u=!1;switch(t){case"visible":u=d;break;case"hidden":u=!d;break;case"editable":u=s;break;case"selected":u=l;break;case"text":u=o===(r??"")}let c="text"===t?`expected="${r??""}" actual="${o}"`:`actual=${JSON.stringify({visible:d,editable:s,selected:l})}`;return{pass:u,actualText:o,details:c}}({predicate:t.predicate,node:r.node,nodes:n.snapshot.nodes,expectedText:t.expectedText,platform:e.backend.platform});if(!i.pass)throw new y("COMMAND_FAILED",`is ${t.predicate} failed for selector ${r.selector.raw}: ${i.details}`);return{predicate:t.predicate,pass:!0,selector:r.selector.raw,..."text"===t.predicate?{text:i.actualText}:{},selectorChain:a.selectors.map(e=>e.raw)}},nu=async(e,t)=>await nd(e,{...t,predicate:"visible",selector:t.target.selector}),nc=async(e,t)=>await nd(e,{...t,predicate:"hidden",selector:t.target.selector}),np=async(e,t)=>{if("sleep"===t.target.kind)return await t9(e,t.target.durationMs),{kind:"sleep",waitedMs:t.target.durationMs};if("ref"===t.target.kind){let n=await na(e,t.session),a=j(t.target.ref);if(!a)throw new y("INVALID_ARGS",`Invalid ref: ${t.target.ref}`);let r=V(n.snapshot.nodes,a),i=r?R(r,n.snapshot.nodes):void 0;if(!i)throw new y("COMMAND_FAILED",`Ref ${t.target.ref} not found or has no label`);return await nw(e,t,i,t.target.timeoutMs)}if("selector"===t.target.kind)return await nm(e,t,t.target.selector,t.target.timeoutMs);if(!t.target.text)throw new y("INVALID_ARGS","wait requires text");return await nw(e,t,t.target.text,t.target.timeoutMs)},nf=async(e,t)=>{let n=await np(e,{...t,target:{kind:"text",text:t.text,timeoutMs:t.timeoutMs}});if("text"!==n.kind)throw new y("COMMAND_FAILED","waitForText returned non-text result");return n};async function nh(e,t,n){let a=t.timeoutMs??1e4,r=t6(e);for(;t6(e)-r<a;){if(eg((await nr(e,t,{updateSession:!0,scope:t5(n)?t.query:void 0})).snapshot.nodes,n,t.query,{requireRect:!1}).matches[0])return{kind:"found",found:!0,waitedMs:t6(e)-r};await t9(e,300)}throw new y("COMMAND_FAILED","find wait timed out")}async function nm(e,t,n,a){let r=a??1e4,i=t6(e),o=x(n);for(;t6(e)-i<r;){let n=L((await nr(e,t,{updateSession:!0})).snapshot.nodes,o,{platform:e.backend.platform});if(n)return{kind:"selector",selector:n.selector.raw,waitedMs:t6(e)-i};await t9(e,300)}throw new y("COMMAND_FAILED",`wait timed out for selector: ${n}`)}async function nw(e,t,n,a){let r=a??1e4,i=t6(e);for(;t6(e)-i<r;){if(e.backend.findText?(await e.backend.findText(t8(e,t),n)).found:await ng(e,t,n))return{kind:"text",text:n,waitedMs:t6(e)-i};await t9(e,300)}throw new y("COMMAND_FAILED",`wait timed out for text: ${n}`)}async function ng(e,t,n){return!!C((await nr(e,t,{updateSession:!0})).snapshot.nodes,n)}async function ny(e,t,n,a){let r=await nr(e,{...t,session:n},{updateSession:!0}),i=x(a.selector),o=$(r.snapshot.nodes,i,{platform:e.backend.platform,requireRect:!1,requireUnique:!0,disambiguateAmbiguous:a.disambiguateAmbiguous});if(!o)throw new y("COMMAND_FAILED",U(i,[],{unique:!0}));return{capture:r,node:o.node,selector:o.selector.raw,ref:`@${o.node.ref}`}}function nb(e,t,n,a){if(!Number.isFinite(e)||!Number.isInteger(e)||e<n||e>a)throw new y("INVALID_ARGS",`${t} must be an integer between ${n} and ${a}`);return e}function nv(e){let t=nI(e);if(!t)return null;let n=B(t);return Number.isFinite(n.x)&&Number.isFinite(n.y)?n:null}function nI(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 nA(e,t){let n=function(e,t){let n=nI(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=nI(e.rect);return!!t&&nx(t,n)});if(1!==t.length)break;a=t[0]}return a===t?null:a}(e,t);if(n?.rect&&nv(n.rect))return n;let a=k(e,t);return a?.rect&&nv(a.rect)?!function(e,t,n){var a,r,i,o;let s,l,d,u=nI(e.rect),c=nI(t.rect);if(!u||!c)return!1;let p=function(e,t){let n=B(t),a=e.filter(e=>{let t=(e.type??"").toLowerCase();return t.includes("application")||t.includes("window")}).map(e=>nI(e.rect)).filter(e=>null!==e);if(0===a.length)return null;let r=a.filter(e=>e3(e,n.x,n.y));return e4(r.length>0?r:a)}(n,u);return!!p&&(a=c,r=p,s=(i=a,o=r,Math.max(0,Math.min(i.x+i.width,o.x+o.width)-Math.max(i.x,o.x))*Math.max(0,Math.min(i.y+i.height,o.y+o.height)-Math.max(i.y,o.y))),l=a.width*a.height,d=r.width*r.height,!(s<=0)&&!(l<=0)&&!(d<=0)&&!!(s/d>=.9)&&!!(s/l>=.8))&&!nx(u,c)}(t,a,e)?a:t:t}function nx(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 nS(e,t,n){if(await n_(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 nk(e,t,t.target),r=a.resolved,i=n.promoteToHittableAncestor?nA(a.snapshot.nodes,r.node):r.node;return function(e,t,n,a){let r=e.rect?e7(e,t):null;if(!(!e.rect||!r||e9(e,t)))throw new y("COMMAND_FAILED",`Ref ${n} is off-screen and not safe to ${a}`,{reason:"offscreen_ref",ref:j(n),rect:e.rect,viewport:r,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.`})}(i,a.snapshot.nodes,t.target.ref,n.action),{kind:"ref",point:nE(i,`Ref ${t.target.ref} not found or has invalid bounds`),target:{kind:"ref",ref:`@${r.ref}`},node:i,selectorChain:D(i,e.backend.platform,{action:"fill"===n.action?"fill":"click"}),refLabel:R(i,a.snapshot.nodes)}}let a=await nN(e,t,n.requireInteractive),r=x(t.target.selector),i=$(a.snapshot.nodes,r,{platform:e.backend.platform,requireRect:!0,requireUnique:!0,disambiguateAmbiguous:!0});if(!i||!i.node.rect)throw new y("COMMAND_FAILED",U(r,i?.diagnostics??[],{unique:!0}));let o=n.promoteToHittableAncestor?nA(a.snapshot.nodes,i.node):i.node;return{kind:"selector",point:nE(o,`Selector ${i.selector.raw} resolved to invalid bounds`),target:{kind:"selector",selector:i.selector.raw},node:o,selectorChain:D(o,e.backend.platform,{action:"fill"===n.action?"fill":"click"}),refLabel:R(o,a.snapshot.nodes)}}async function nN(e,t,n){if(!e.backend.captureSnapshot)throw new y("UNSUPPORTED_OPERATION","snapshot is not supported by this backend");let a=t.session??"default",r=await e.sessions.get(a);if(!r)throw new y("SESSION_NOT_FOUND","No active session. Run open first.");let i=await e.backend.captureSnapshot(t8(e,t),{interactiveOnly:n,compact:n}),o=i.snapshot??{nodes:i.nodes??[],truncated:i.truncated,backend:i.backend,createdAt:t6(e)};return await e.sessions.set({...r,snapshot:o}),{snapshot:o}}async function n_(e,t,n){if("macos"!==e.backend.platform)return;let a=await nM(e,t);if(("desktop"===a||"menubar"===a)&&("menubar"!==a||"click"!==n&&"press"!==n))throw new y("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 nM(e,t){let n=await e.sessions.get(t.session??"default");return n?.metadata?.surface}async function nk(e,t,n){let a=t.session??"default",r=await e.sessions.get(a);if(!r)throw new y("SESSION_NOT_FOUND","No active session. Run open first.");if(!r.snapshot)throw new y("INVALID_ARGS","No snapshot in session. Run snapshot first.");let i=n.fallbackLabel??"",o=nD(r.snapshot.nodes,n.ref,{fallbackLabel:i,requireRect:!0});if(o)return{snapshot:r.snapshot,resolved:o};let s=await nN(e,t,!0),l=nD(s.snapshot.nodes,n.ref,{fallbackLabel:i,requireRect:!0});if(!l)throw new y("COMMAND_FAILED",`Ref ${n.ref} not found or has no bounds`);return{...s,resolved:l}}function nD(e,t,n){let a=j(t);if(!a)throw new y("INVALID_ARGS",`Invalid ref: ${t}`);let r=V(e,a);if(nO(r,n.requireRect))return{ref:a,node:r};let i=n.fallbackLabel.length>0?C(e,n.fallbackLabel):null;return nO(i,n.requireRect)?{ref:a,node:i}:null}function nE(e,t){if(!e.rect)throw new y("COMMAND_FAILED",t);let n=B(e.rect);if(!Number.isFinite(n.x)||!Number.isFinite(n.y))throw new y("COMMAND_FAILED",t);return n}function nO(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 o=B(e.rect);return Number.isFinite(o.x)&&Number.isFinite(o.y)}async function nC(e,t){let n=t.target??{kind:"viewport"};return"viewport"===n.kind?(await n_(e,t,"scroll"),{kind:"viewport"}):await nS(e,{...t,target:n},{action:"scroll",requireInteractive:!1,promoteToHittableAncestor:!1})}async function nR(e,t){if(t.from){var n;if("x"in(n=t.from)&&"y"in n)return await n_(e,t,"swipe"),{point:nT(t.from,"from")};let a=await nS(e,{...t,target:t.from},{action:"swipe",requireInteractive:!1,promoteToHittableAncestor:!1});return{point:a.point,target:a}}if(!t.direction)throw new y("INVALID_ARGS","swipe requires from+to or a direction");return await n_(e,t,"swipe"),{point:B(function(e){let t=e.filter(t=>e9(t,e)).map(e=>e.rect).filter(n$),n=t.length>0?t:e.map(e=>e.rect).filter(n$);if(0===n.length)throw new y("COMMAND_FAILED","Cannot infer viewport for directional swipe");let a=Math.min(...n.map(e=>e.x)),r=Math.min(...n.map(e=>e.y));return{x:a,y:r,width:Math.max(...n.map(e=>e.x+e.width))-a,height:Math.max(...n.map(e=>e.y+e.height))-r}}((await nN(e,t,!1)).snapshot.nodes)),target:{kind:"viewport"}}}function nP(e,t){switch(e){case"up":case"down":case"left":case"right":return e;default:throw new y("INVALID_ARGS",`${t} must be up, down, left, or right`)}}function nT(e,t){let n=Number(e.x),a=Number(e.y);if(!Number.isFinite(n)||!Number.isFinite(a))throw new y("INVALID_ARGS",`${t} point requires finite x and y`);return{x:n,y:a}}function nL(e,t){if(!Number.isFinite(e)||e<=0)throw new y("INVALID_ARGS",`${t} must be a positive number`);return e}function n$(e){return!!(e&&e.width>0&&e.height>0)}function nF(e){return e&&"object"==typeof e?e:void 0}async function nU(e,t,n){let a=await nS(e,t,{action:n,requireInteractive:!0,promoteToHittableAncestor:!0});if(!e.backend.tap)throw new y("UNSUPPORTED_OPERATION","tap is not supported by this backend");let r=nG(await e.backend.tap(t8(e,t),a.point,{button:t.button,count:t.count,intervalMs:t.intervalMs,holdMs:t.holdMs,jitterPx:t.jitterPx,doubleTap:t.doubleTap}));return{...a,...r?{backendResult:r}:{}}}function nG(e){return e&&"object"==typeof e?e:void 0}function nV(e){return!!(e&&"object"==typeof e)}function nB(e){return e&&"object"==typeof e?e:void 0}let nj=/^[A-Za-z0-9_.:-]{1,64}$/;function nq(e,t){if(void 0!==e)return nW(e,t)}function nW(e,t){let n=e?.trim();if(!n)throw new y("INVALID_ARGS",`${t} must be a non-empty string`);return n}async function nX(e,t){if(!t||"object"!=typeof t)throw new y("INVALID_ARGS","apps.push requires an input");if("json"===t.kind)return nH(t.payload,"apps.push JSON payload",8192),{backendInput:{kind:"json",payload:t.payload},inputKind:"json"};let n=await tr(e,t,{usage:"apps.push",field:"input"});return{backendInput:{kind:"file",path:n.path},inputKind:"file",...n.cleanup?{cleanup:n.cleanup}:{}}}function nH(e,t,n){if(function(e,t){if(!e||"object"!=typeof e||Array.isArray(e))throw new y("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 y("INVALID_ARGS",`${t} must be JSON-serializable`);return n}catch{throw new y("INVALID_ARGS",`${t} must be JSON-serializable`)}}(e,t),"utf8")>n)throw new y("INVALID_ARGS",`${t} exceeds ${n} bytes`)}function nz(e,t){return{session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata}}function nY(e){return e&&"object"==typeof e?e:void 0}async function nK(e,t,n){let a="reinstall"===n?"reinstallApp":"installApp",r=e.backend[a];if(!r)throw new y("UNSUPPORTED_OPERATION",`admin.${n} is not supported by this backend`);let i="app"in t&&void 0!==t.app?n1(t.app,"app"):void 0;if("installFromSource"!==n&&!i)throw new y("INVALID_ARGS",`admin.${n} requires app`);let o=t8(e,t),s=await nJ(e,o,t.source);try{var l,d,u,c,p;let t,a,f,h,m,w,g,y,b=await r.call(e.backend,o,{...i?{app:i}:{},source:s.source});return l=n,d=i,u=s.source,c=b,t=n3(c),a=n2(c,"appName"),f=n2(c,"appId"),h=n2(c,"bundleId"),m=n2(c,"packageName"),w=n2(c,"launchTarget"),g=n2(c,"installablePath"),y=n2(c,"archivePath"),{kind:"reinstall"===l?"appReinstalled":"installFromSource"===l?"appInstalledFromSource":"appInstalled",...d?{app:d}:{},source:u,...f?{appId:f}:{},...a?{appName:a}:{},...h?{bundleId:h}:{},...m?{packageName:m}:{},...w?{launchTarget:w}:{},...g?{installablePath:g}:{},...y?{archivePath:y}:{},...t?{backendResult:t}:{},...ei(`${"reinstall"===l?"Reinstalled":"Installed"}: ${a??w??d??(p=u,"path"===p.kind?p.path:"uploadedArtifact"===p.kind?p.id:p.url)}`)}}finally{await s.cleanup?.()}}async function nJ(e,t,n){let a=nQ(n),r=await nZ(e,a);try{let n=e.backend.resolveInstallSource?await e.backend.resolveInstallSource(t,r.source):r.source;return{source:nQ(n),...r.cleanup?{cleanup:r.cleanup}:{}}}catch(e){if(r.cleanup)try{await r.cleanup()}catch{}throw e}}async function nZ(e,t){if("url"===t.kind)return{source:t};let n=await tr(e,t,{usage:"admin.install",field:"source"});return{source:{kind:"path",path:n.path},...n.cleanup?{cleanup:n.cleanup}:{}}}function nQ(e){if(!e||"object"!=typeof e)throw new y("INVALID_ARGS","install source is required");if("path"===e.kind)return{kind:"path",path:n1(e.path,"source.path")};if("uploadedArtifact"===e.kind)return{kind:"uploadedArtifact",id:n1(e.id,"source.id")};if("url"===e.kind){let t=n1(e.url,"source.url");return function(e){let t;try{t=new URL(e)}catch{throw new y("INVALID_ARGS",`Invalid install source URL: ${e}`)}if("http:"!==t.protocol&&"https:"!==t.protocol)throw new y("INVALID_ARGS","Install source URL must use http or https")}(t),{kind:"url",url:t}}throw new y("INVALID_ARGS","install source kind must be path, uploadedArtifact, or url")}function n0(e,t){if(void 0!==e)return n1(e,t)}function n1(e,t){let n=e?.trim();if(!n)throw new y("INVALID_ARGS",`${t} must be a non-empty string`);return n}function n2(e,t){let n=e[t];return"string"==typeof n&&n.length>0?n:void 0}function n3(e){return e&&"object"==typeof e?e:void 0}function n4(e,t){if("start"===e||"stop"===e)return e;throw new y("INVALID_ARGS",`${t} action must be start or stop`)}function n5(e,t,n,a){return{kind:"start"===e?a.startKind:a.stopKind,action:e,...n?{artifact:n}:{},backendResult:t,...ei("start"===e?a.startMessage:a.stopMessage)}}let n8=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i,n6=/\b[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\b/g;function n9(e){var t,n;let a=!1,r=e;return{value:(t=r=(r=(r=(r=(r=r.replaceAll(/(authorization|token|secret|password|passwd|api[-_]?key)=([^&\s]+)/gi,(e,t)=>(a=!0,`${String(t)}=[REDACTED]`))).replaceAll(/("(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)"\s*:\s*")([^"]*)(")/gi,(e,t,n,r)=>(a=!0,`${String(t)}[REDACTED]${String(r)}`))).replaceAll(/\b(Bearer\s+)([^\s",;]+)/gi,(e,t)=>(a=!0,`${String(t)}[REDACTED]`))).replaceAll(/((?:authorization|cookie|token|secret|password|passwd|api[-_]?key)\s*[:=]\s*)([^\s,;&]+)/gi,(e,t)=>(a=!0,`${String(t)}[REDACTED]`))).replaceAll(n6,()=>(a=!0,"[REDACTED]")),n=()=>{a=!0},r=/(https?:\/\/|token|secret|password|authorization|cookie|api[-_]?key)/i.test(t)?t.replaceAll(/https?:\/\/[^\s"'<>)]+/gi,e=>{let t=n7(e);return t?(t.redacted&&n(),t.value):e}):t),redacted:a}}function n7(e){try{let t=new URL(e),n=function(e){let t=!1;for(let n of Array.from(e.searchParams.keys()))n8.test(n)&&(e.searchParams.set(n,"[REDACTED]"),t=!0);return t}(t);return(t.username||t.password)&&(t.username="REDACTED",t.password="REDACTED",n=!0),{value:t.toString(),redacted:n}}catch{return}}let ae=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i;function at(e){if(!e)return{redacted:!1};let t=!1,n={};for(let[a,r]of Object.entries(e))if(ae.test(a))n[a]="[REDACTED]",t=!0;else{let e=ai(r,2048);n[a]=e.value??"",t||=e.redacted}return{value:n,redacted:t}}function an(e){return void 0===e?{redacted:!1}:function(e){try{let t=JSON.parse(e),n=ar(t,n9);return ao(JSON.stringify(n.value),2048,n.redacted)}catch{return}}(e)??ai(e,2048)}function aa(e){return ar(e,e=>ai(e,2048))}function ar(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=ar(e,t);return n||=a.redacted,a.value}),redacted:n}}let n=!1,a={};for(let[r,i]of Object.entries(e)){if(ae.test(r)){a[r]="[REDACTED]",n=!0;continue}let e=ar(i,t);a[r]=e.value,n||=e.redacted}return{value:a,redacted:n}}function ai(e,t){if(void 0===e)return{redacted:!1};let n=n9(e);return ao(n.value,t,n.redacted)}function ao(e,t,n){if(void 0===e)return{redacted:n};let a=e;return a.length>t&&(a=`${a.slice(0,t)}...[truncated]`,n=!0),{value:a,redacted:n}}async function as(e,t){let n=t8(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 al(e,t,n,a){return{...ad(e),...void 0!==e.cursor?{cursor:ac(e.cursor,"cursor")}:{},limit:void 0===e.limit?t:nb(e.limit,a,1,n)}}function ad(e){return{...void 0!==e.since?{since:ac(e.since,"since")}:{},...void 0!==e.until?{until:ac(e.until,"until")}:{}}}function au(e,t,n=50){if(!Array.isArray(e))throw new y("INVALID_ARGS",`${t} must be an array of strings`);if(e.length>n)throw new y("INVALID_ARGS",`${t} must contain at most ${n} entries`);return e.map((e,n)=>ac(e,`${t}[${n}]`))}function ac(e,t){let n=e.trim();if(!n)throw new y("INVALID_ARGS",`${t} must be a non-empty string`);return n}let ap=async(e,t)=>{let n;if(!e.backend.captureScreenshot)throw new y("UNSUPPORTED_OPERATION","screenshot is not supported by this backend");let a=await ti(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}),void 0!==t.maxSize&&await ta(a.path,t.maxSize),n=await a.publish()}catch(e){throw await a.cleanup?.(),e}return{path:a.path,...n?{artifacts:[n]}:{},...ei(`Saved screenshot: ${a.path}`)}},af=async(e,t)=>{let n,a,r;if(!t.baseline)throw new y("INVALID_ARGS","diff screenshot requires a baseline image");let i=function(e){if(null==e||""===e)return .1;let t=Number(e);if(Number.isNaN(t)||t<0||t>1)throw new y("INVALID_ARGS","--threshold must be a number between 0 and 1");return t}(t.threshold),o=t.current??{kind:"live"};if(t.overlayRefs&&!t1(o))throw new y("INVALID_ARGS","diff screenshot <current.png> cannot use --overlay-refs because saved-image comparisons have no live accessibility refs");let s=await tr(e,t.baseline,{usage:"diff screenshot baseline",field:"baseline"}),l=[];try{let d;d=t1(o)?(a=await tY(e,t)).path:(n=await tr(e,o,{usage:"diff screenshot current",field:"current"})).path,r=t.out?await ti(e,t.out,{field:"diffPath",ext:".png"}):void 0;let u=await tV(s.path,d,{threshold:i,outputPath:r?.path,maxPixels:e.policy.maxImagePixels});t1(o)&&(u=await tK(e,t,r?.path,u,l));let c=u.diffPath?await r?.publish():void 0;return c&&l.push(c),u.diffPath||await r?.cleanup?.(),{...u,...l.length>0?{artifacts:l}:{}}}catch(e){throw await r?.cleanup?.(),e}finally{await s.cleanup?.(),await n?.cleanup?.(),await a?.cleanup?.()}},ah=async(e,t)=>{var n;let a,r,i=await t7(e,t);return await e.sessions.set(ne(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=e8(n),o=new Set;return i.hiddenCount>0&&o.add("offscreen-nodes"),i.nodes.some(e=>e.hiddenContentAbove)&&o.add("scroll-hidden-above"),i.nodes.some(e=>e.hiddenContentBelow)&&o.add("scroll-hidden-below"),{partial:o.size>0,visibleNodeCount:i.nodes.length,totalNodeCount:n.length,reasons:[...o]}}({nodes:i.snapshot.nodes,backend:i.snapshot.backend,snapshotRaw:t.raw}),...i.result.androidSnapshot?{androidSnapshot:i.result.androidSnapshot}:{},...i.warnings.length>0?{warnings:i.warnings}:{},...(a=(n=i).result.appName??n.session?.appName,r=n.result.appBundleId??n.session?.appBundleId,{...a||r?{appName:a??r}:{},...r?{appBundleId:r}:{}})}},am=async(e,t)=>{let n=await t7(e,t),a=!0===t.interactiveOnly,r=n.session?.snapshot,i=ne(t.session,n);if(!r){let t=function(e,t={}){return t3(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 o=function(e,t,n={}){let a=function(e,t){let n=e.length,a=t.length,r=n+a,i=new Map,o=[];i.set(1,0);for(let s=0;s<=r;s+=1){o.push(new Map(i));for(let r=-s;r<=s;r+=2){let l=r===-s||r!==s&&t4(i,r-1)<t4(i,r+1)?t4(i,r+1):t4(i,r-1)+1,d=l-r;for(;l<n&&d<a&&e[l].comparable===t[d].comparable;)l+=1,d+=1;if(i.set(r,l),l>=n&&d>=a)return function(e,t,n,a,r){let i=[],o=a,s=r;for(let a=e.length-1;a>=0;a-=1){let r=e[a],l=o-s,d=l===-a||l!==a&&t4(r,l-1)<t4(r,l+1)?l+1:l-1,u=t4(r,d),c=u-d;for(;o>u&&s>c;)i.push({kind:"unchanged",text:n[s-1].text}),o-=1,s-=1;if(0===a)break;o===u?(i.push({kind:"added",text:n[c].text}),s=c):(i.push({kind:"removed",text:t[u].text}),o=u)}return i.reverse(),i}(o,e,t,n,a)}}return[]}(t3(e,n),t3(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:o.summary,lines:o.lines,...n.warnings.length>0?{warnings:n.warnings}:{}}},aw=async(e,t)=>{let n=t.locator??"any";if(!t.query)throw new y("INVALID_ARGS","find requires a value");if("wait"===t.action)return await nh(e,t,n);let a=await nr(e,t,{updateSession:!0,scope:t5(n)?t.query:void 0}),r=eg(a.snapshot.nodes,n,t.query,{requireRect:!1}).matches[0];if(!r)throw new y("COMMAND_FAILED","find did not match any element");if("exists"===t.action)return{kind:"found",found:!0};let i=`@${r.ref}`;return"get_attrs"===t.action?{kind:"attrs",ref:i,node:r}:{kind:"text",ref:i,text:await ni(e,a,r),node:r}},ag=no,ay=ns,ab=nl,av=nd,aI=nu,aA=nc,ax=np,aS=nf,aN=async(e,t)=>await nU(e,t,"click"),a_=async(e,t)=>await nU(e,t,"press"),aM=async(e,t)=>{var n;if(!t.text)throw new y("INVALID_ARGS","fill requires text");let a=await nS(e,t,{action:"fill",requireInteractive:!0,promoteToHittableAncestor:!1});if(!e.backend.fill)throw new y("UNSUPPORTED_OPERATION","fill is not supported by this backend");let r=nG(await e.backend.fill(t8(e,t),a.point,t.text,{delayMs:t.delayMs})),i="node"in a?a.node.type??"":"",o=i&&!G(i,e.backend.platform)?`fill target ${n=a,n.target?.kind==="ref"?n.target.ref:n.target?.kind==="selector"?n.target.selector:"point"} resolved to "${i}", attempting fill anyway.`:void 0;return{...a,text:t.text,...o?{warning:o}:{},...r?{backendResult:r}:{}}},ak=async(e,t)=>{let n=t.text;if(!n)throw new y("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 y("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 y("UNSUPPORTED_OPERATION","type is not supported by this backend");let r=nb(t.delayMs??0,"delay-ms",0,1e4),i=nG(await e.backend.typeText(t8(e,t),n,{delayMs:r}));return{kind:"text",text:n,delayMs:r,...i?{backendResult:i}:{},...ei(`Typed ${Array.from(n).length} chars`)}},aD=async(e,t)=>{let n=await nS(e,t,{action:"focus",requireInteractive:!0,promoteToHittableAncestor:!1});if(!e.backend.focus)throw new y("UNSUPPORTED_OPERATION","focus is not supported by this backend");let a=nF(await e.backend.focus(t8(e,t),n.point));return{...n,...a?{backendResult:a}:{},...ei(`Focused (${n.point.x}, ${n.point.y})`)}},aE=async(e,t)=>{let n=await nS(e,t,{action:"longPress",requireInteractive:!0,promoteToHittableAncestor:!0});if(!e.backend.longPress)throw new y("UNSUPPORTED_OPERATION","longPress is not supported by this backend");let a=void 0===t.durationMs?void 0:nb(t.durationMs,"durationMs",0,12e4),r=nF(await e.backend.longPress(t8(e,t),n.point,{durationMs:a}));return{...n,...void 0!==a?{durationMs:a}:{},...r?{backendResult:r}:{},...ei(`Long pressed (${n.point.x}, ${n.point.y})`)}},aO=async(e,t)=>{if(!e.backend.swipe)throw new y("UNSUPPORTED_OPERATION","swipe is not supported by this backend");let n=await nR(e,t),a=function(e,t){if(t.to)return{point:nT(t.to,"to")};let n=nP(t.direction,"swipe direction"),a=nL(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),r=void 0===t.durationMs?void 0:nb(t.durationMs,"durationMs",16,1e4),i=nF(await e.backend.swipe(t8(e,t),n.point,a.point,{durationMs:r}));return{kind:"swipe",from:n.point,to:a.point,...a.direction?{direction:a.direction}:{},...void 0!==a.distance?{distance:a.distance}:{},...void 0!==r?{durationMs:r}:{},...n.target?{fromTarget:n.target}:{},...i?{backendResult:i}:{},...ei("Swiped")}},aC=async(e,t)=>{var n,a;if(!e.backend.scroll)throw new y("UNSUPPORTED_OPERATION","scroll is not supported by this backend");let r=nP(t.direction,"scroll direction"),i=(n=t.amount,a="scroll amount",void 0===n?void 0:nL(n,a)),o=function(e,t){if(void 0!==e){if(!Number.isFinite(e)||!Number.isInteger(e)||e<=0)throw new y("INVALID_ARGS",`${t} must be a positive integer`);return e}}(t.pixels,"scroll pixels");if(void 0!==i&&void 0!==o)throw new y("INVALID_ARGS","scroll accepts either amount or pixels, not both");let s=await nC(e,t),l="viewport"===s.kind?{kind:"viewport"}:{kind:"point",point:s.point},d=nF(await e.backend.scroll(t8(e,t),l,{direction:r,...void 0!==i?{amount:i}:{},...void 0!==o?{pixels:o}:{}}));return{...s,direction:r,...void 0!==i?{amount:i}:{},...void 0!==o?{pixels:o}:{},...d?{backendResult:d}:{},...ei(void 0!==o?`Scrolled ${r} by ${o}px`:void 0!==i?`Scrolled ${r} by ${i}`:`Scrolled ${r}`)}},aR=async(e,t)=>{if(!e.backend.pinch)throw new y("UNSUPPORTED_OPERATION","pinch is not supported by this backend");await n_(e,t,"pinch");let n=nL(t.scale,"pinch scale"),a=t.center?await nS(e,{...t,target:t.center},{action:"pinch",requireInteractive:!1,promoteToHittableAncestor:!1}):void 0,r=nF(await e.backend.pinch(t8(e,t),{scale:n,...a?{center:a.point}:{}}));return{kind:"pinch",scale:n,...a?{center:a.point,centerTarget:a}:{},...r?{backendResult:r}:{},...ei(`Pinched to scale ${n}`)}},aP=async(e,t={})=>{if(!e.backend.pressBack)throw new y("UNSUPPORTED_OPERATION","system.back is not supported by this backend");let n=t.mode??"in-app";if("in-app"!==n&&"system"!==n)throw new y("INVALID_ARGS","system.back mode must be in-app or system");let a=nB(await e.backend.pressBack(t8(e,t),{mode:n}));return{kind:"systemBack",mode:n,...a?{backendResult:a}:{},...ei("Back")}},aT=async(e,t={})=>{if(!e.backend.pressHome)throw new y("UNSUPPORTED_OPERATION","system.home is not supported by this backend");let n=nB(await e.backend.pressHome(t8(e,t)));return{kind:"systemHome",...n?{backendResult:n}:{},...ei("Home")}},aL=async(e,t)=>{if(!e.backend.rotate)throw new y("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 y("INVALID_ARGS","system.rotate orientation must be portrait, portrait-upside-down, landscape-left, or landscape-right")}}(t.orientation),a=nB(await e.backend.rotate(t8(e,t),n));return{kind:"systemRotated",orientation:n,...a?{backendResult:a}:{},...ei(`Rotated to ${n}`)}},a$=async(e,t={})=>{if(!e.backend.setKeyboard)throw new y("UNSUPPORTED_OPERATION","system.keyboard is not supported by this backend");let n=t.action??"status";if("status"!==n&&"get"!==n&&"dismiss"!==n)throw new y("INVALID_ARGS","system.keyboard action must be status, get, or dismiss");let a=await e.backend.setKeyboard(t8(e,t),{action:n}),r=nB(a);if("dismiss"===n){let e=nV(a)?a.dismissed:void 0;return{kind:"keyboardDismissed",action:n,state:nV(a)?a:{},...r?{backendResult:r}:{},...ei(!1===e?"Keyboard already hidden":"Keyboard dismissed")}}return{kind:"keyboardState",action:n,state:nV(a)?a:{},...r?{backendResult:r}:{}}},aF=async(e,t)=>{if("read"===t.action){if(!e.backend.getClipboard)throw new y("UNSUPPORTED_OPERATION","system.clipboard read is not supported by this backend");let n=await e.backend.getClipboard(t8(e,t));return{kind:"clipboardText",action:"read",text:"string"==typeof n?n:n.text}}if("write"!==t.action)throw new y("INVALID_ARGS","system.clipboard action must be read or write");if(!e.backend.setClipboard)throw new y("UNSUPPORTED_OPERATION","system.clipboard write is not supported by this backend");if("string"!=typeof t.text)throw new y("INVALID_ARGS","system.clipboard write requires text");let n=nB(await e.backend.setClipboard(t8(e,t),t.text));return{kind:"clipboardUpdated",action:"write",textLength:Array.from(t.text).length,...n?{backendResult:n}:{},...ei("Clipboard updated")}},aU=async(e,t={})=>{if(!e.backend.openSettings)throw new y("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 y("INVALID_ARGS",`${t} must be a non-empty string`);return n}(t.target,"target"),a=nB(await e.backend.openSettings(t8(e,t),n));return{kind:"settingsOpened",...n?{target:n}:{},...a?{backendResult:a}:{},...ei(n?`Opened settings: ${n}`:"Opened settings")}},aG=async(e,t={})=>{if(!e.backend.handleAlert)throw new y("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 y("INVALID_ARGS","system.alert action must be get, accept, dismiss, or wait");let a=void 0===t.timeoutMs?void 0:nb(t.timeoutMs,"timeoutMs",0,12e4),r=await e.backend.handleAlert(t8(e,t),n,{timeoutMs:a});var i=n,o=r;if("get"===i){if("alertStatus"!==o.kind)throw new y("COMMAND_FAILED","system.alert get returned an invalid backend result");return{kind:"alertStatus",action:i,alert:o.alert}}if("wait"===i){if("alertWait"!==o.kind)throw new y("COMMAND_FAILED","system.alert wait returned an invalid backend result");return{kind:"alertWait",action:i,alert:o.alert,...void 0!==o.waitedMs?{waitedMs:o.waitedMs}:{},...void 0!==o.timedOut?{timedOut:o.timedOut}:{},...ei(o.alert?"Alert visible":"Alert wait timed out")}}if("alertHandled"!==o.kind)throw new y("COMMAND_FAILED",`system.alert ${i} returned an invalid backend result`);return{kind:"alertHandled",action:i,handled:o.handled,...o.alert?{alert:o.alert}:{},...o.button?{button:o.button}:{},...ei(o.handled?`Alert ${i}ed`:"No alert handled")}},aV=async(e,t={})=>{if(!e.backend.openAppSwitcher)throw new y("UNSUPPORTED_OPERATION","system.appSwitcher is not supported by this backend");let n=nB(await e.backend.openAppSwitcher(t8(e,t)));return{kind:"appSwitcherOpened",...n?{backendResult:n}:{},...ei("Opened app switcher")}},aB=async(e,t)=>{var n;if(!e.backend.openApp)throw new y("UNSUPPORTED_OPERATION","apps.open is not supported by this backend");let a=function(e){var t;let n=nq(e.app,"app"),a=nq(e.appId,"appId"),r=nq(e.bundleId,"bundleId"),i=nq(e.packageName,"packageName"),o=nq(e.url,"url"),s=nq(e.activity,"activity"),l={...n?{app:n}:{},...a?{appId:a}:{},...r?{bundleId:r}:{},...i?{packageName:i}:{},...o?{url:o}:{},...s?{activity:s}:{}};if(!((t=l).app??t.appId??t.bundleId??t.packageName??t.url??t.activity))throw new y("INVALID_ARGS","apps.open requires app, appId, bundleId, packageName, url, or activity");return l}(t),r=nY(await e.backend.openApp(nz(e,t),a,{relaunch:t.relaunch}));return{kind:"appOpened",target:a,relaunch:!0===t.relaunch,...r?{backendResult:r}:{},...ei(`Opened: ${(n=a).app??n.appId??n.bundleId??n.packageName??n.url??n.activity??"app"}`)}},aj=async(e,t={})=>{if(!e.backend.closeApp)throw new y("UNSUPPORTED_OPERATION","apps.close is not supported by this backend");let n=nq(t.app,"app"),a=nY(await e.backend.closeApp(nz(e,t),n));return{kind:"appClosed",...n?{app:n}:{},...a?{backendResult:a}:{},...ei(n?`Closed: ${n}`:"Closed app")}},aq=async(e,t={})=>{if(!e.backend.listApps)throw new y("UNSUPPORTED_OPERATION","apps.list is not supported by this backend");return{kind:"appsList",apps:await e.backend.listApps(nz(e,t),t.filter??"all")}},aW=async(e,t)=>{if(!e.backend.getAppState)throw new y("UNSUPPORTED_OPERATION","apps.state is not supported by this backend");let n=nW(t.app,"app"),a=await e.backend.getAppState(nz(e,t),n);return{kind:"appState",app:n,state:a}},aX=async(e,t)=>{if(!e.backend.pushFile)throw new y("UNSUPPORTED_OPERATION","apps.push is not supported by this backend");let n=nW(t.app,"app"),a=await nX(e,t.input);try{let r=await e.backend.pushFile(nz(e,t),a.backendInput,n),i=nY(r);return{kind:"appPushed",app:n,inputKind:a.inputKind,...i?{backendResult:i}:{},...ei(`Pushed to ${n}`)}}finally{await a.cleanup?.()}},aH=async(e,t)=>{var n,a;if(!e.backend.triggerAppEvent)throw new y("UNSUPPORTED_OPERATION","apps.triggerEvent is not supported by this backend");let r=function(e){let t=nW(e,"name");if(!nj.test(t))throw new y("INVALID_ARGS",`Invalid apps.triggerEvent name: ${t}`,{hint:"Use 1-64 chars: letters, numbers, underscore, dot, colon, or dash."});return t}(t.name);n=t.payload,a=`apps.triggerEvent payload for "${r}"`,void 0!==n&&nH(n,a,8192);let i=nY(await e.backend.triggerAppEvent(nz(e,t),{name:r,...t.payload?{payload:t.payload}:{}}));return{kind:"appEventTriggered",name:r,...t.payload?{payload:t.payload}:{},...i?{backendResult:i}:{},...ei(`Triggered app event: ${r}`)}},az=async(e,t={})=>{if(!e.backend.listDevices)throw new y("UNSUPPORTED_OPERATION","admin.devices is not supported by this backend");return{kind:"adminDevices",devices:await e.backend.listDevices(t8(e,t),t.filter)}},aY=async(e,t={})=>{if(!e.backend.bootDevice)throw new y("UNSUPPORTED_OPERATION","admin.boot is not supported by this backend");let n=function(e){if(!e)return;let t=n0(e.id,"target.id"),n=n0(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=n3(await e.backend.bootDevice(t8(e,t),n));return{kind:"deviceBooted",...n?{target:n}:{},...a?{backendResult:a}:{},...ei("Booted device")}},aK=async(e,t)=>{if(!e.backend.ensureSimulator)throw new y("UNSUPPORTED_OPERATION","admin.ensureSimulator is not supported by this backend");let n=n1(t.device,"device");return{kind:"simulatorEnsured",...await e.backend.ensureSimulator(t8(e,t),{device:n,...t.runtime?{runtime:n1(t.runtime,"runtime")}:{},...void 0!==t.boot?{boot:t.boot}:{},...void 0!==t.reuseExisting?{reuseExisting:t.reuseExisting}:{}})}},aJ=async(e,t)=>await nK(e,t,"install"),aZ=async(e,t)=>await nK(e,t,"reinstall"),aQ=async(e,t)=>await nK(e,t,"installFromSource"),a0=async(e,t)=>{let n=n4(t.action,"record"),a="start"===n?e.backend.startRecording:e.backend.stopRecording;if(!a)throw new y("UNSUPPORTED_OPERATION",`record ${n} is not supported by this backend`);let r=t.out?await ti(e,t.out,{field:"path",ext:".mp4"}):void 0;try{var i,o,s,l,d;let u,c,p=(i=t,o=r?.path,u=void 0===i.fps?void 0:nb(i.fps,"fps",1,60),c=void 0===i.quality?void 0:nb(i.quality,"quality",5,10),{...o?{outPath:o}:{},...void 0!==u?{fps:u}:{},...void 0!==c?{quality:c}:{},...void 0!==i.hideTouches?{showTouches:!0!==i.hideTouches}:{}}),f=await a.call(e.backend,t8(e,t),p),h=await r?.publish();return s=n,l=f,d=h,{..."string"==typeof l.path?{path:l.path}:{},..."string"==typeof l.telemetryPath?{telemetryPath:l.telemetryPath}:{},..."string"==typeof l.warning?{warning:l.warning}:{},...n5(s,l,d,{startKind:"recordingStarted",stopKind:"recordingStopped",startMessage:"Recording started",stopMessage:"Recording stopped"})}}catch(e){throw await r?.cleanup?.(),e}},a1=async(e,t)=>{let n=n4(t.action,"trace"),a="start"===n?e.backend.startTrace:e.backend.stopTrace;if(!a)throw new y("UNSUPPORTED_OPERATION",`trace ${n} is not supported by this backend`);let r=t.out?await ti(e,t.out,{field:"outPath",ext:".trace"}):void 0;try{var i,o,s;let l={...r?.path?{outPath:r.path}:{}},d=await a.call(e.backend,t8(e,t),l),u=await r?.publish();return i=n,o=d,s=u,{..."string"==typeof o.outPath?{outPath:o.outPath}:{},...n5(i,o,s,{startKind:"traceStarted",stopKind:"traceStopped",startMessage:"Trace started",stopMessage:"Trace stopped"})}}catch(e){throw await r?.cleanup?.(),e}},a2=async(e,t={})=>{var n,a;let r;if(!e.backend.readLogs)throw new y("UNSUPPORTED_OPERATION","diagnostics.logs is not supported by this backend");return r=!0===(n=await e.backend.readLogs(await as(e,t),{...al(a=t,100,500,"logs limit"),...void 0!==a.levels?{levels:au(a.levels,"levels")}:{},...void 0!==a.search?{search:ac(a.search,"search")}:{},...void 0!==a.source?{source:ac(a.source,"source")}:{}})).redacted,{kind:"diagnosticsLogs",entries:n.entries.map(e=>{let t=ai(e.message,4096),n=aa(e.metadata);return r||=t.redacted||n.redacted,{...e.timestamp?{timestamp:e.timestamp}:{},...e.level?{level:e.level}:{},message:t.value??"",...e.source?{source:e.source}:{},...n.value?{metadata:n.value}:{}}}),...n.nextCursor?{nextCursor:n.nextCursor}:{},...n.timeWindow?{timeWindow:n.timeWindow}:{},...n.backend?{backend:n.backend}:{},redacted:r,...n.notes?{notes:n.notes}:{}}},a3=async(e,t={})=>{var n,a,r;let i;if(!e.backend.dumpNetwork)throw new y("UNSUPPORTED_OPERATION","diagnostics.network is not supported by this backend");let o={...al(r=t,25,200,"network limit"),include:function(e){if(void 0===e)return"summary";if("summary"===e||"headers"===e||"body"===e||"all"===e)return e;throw new y("INVALID_ARGS","network include must be summary, headers, body, or all")}(r.include)};return n=await e.backend.dumpNetwork(await as(e,t),o),a=o.include??"summary",i=!0===n.redacted,{kind:"diagnosticsNetwork",entries:n.entries.map(e=>{var t;let n=e.url?n7(t=e.url)??ai(t,2048):void 0,r="headers"===a||"all"===a?at(e.requestHeaders):void 0,o="headers"===a||"all"===a?at(e.responseHeaders):void 0,s="body"===a||"all"===a?an(e.requestBody):void 0,l="body"===a||"all"===a?an(e.responseBody):void 0,d=aa(e.metadata);return i||=(n?.redacted??!1)||(r?.redacted??!1)||(o?.redacted??!1)||(s?.redacted??!1)||(l?.redacted??!1)||d.redacted,{...e.timestamp?{timestamp:e.timestamp}:{},...e.method?{method:e.method}:{},...n?{url:n.value}:{},...void 0!==e.status?{status:e.status}:{},...void 0!==e.durationMs?{durationMs:e.durationMs}:{},...r?.value?{requestHeaders:r.value}:{},...o?.value?{responseHeaders:o.value}:{},...s?.value!==void 0?{requestBody:s.value}:{},...l?.value!==void 0?{responseBody:l.value}:{},...d.value?{metadata:d.value}:{}}}),...n.nextCursor?{nextCursor:n.nextCursor}:{},...n.timeWindow?{timeWindow:n.timeWindow}:{},...n.backend?{backend:n.backend}:{},redacted:i,...n.notes?{notes:n.notes}:{}}},a4=async(e,t={})=>{var n,a;let r;if(!e.backend.measurePerf)throw new y("UNSUPPORTED_OPERATION","diagnostics.perf is not supported by this backend");return r=!0===(n=await e.backend.measurePerf(await as(e,t),{...ad(a=t),...void 0!==a.sampleMs?{sampleMs:nb(a.sampleMs,"sampleMs",100,6e4)}:{},...void 0!==a.metrics?{metrics:au(a.metrics,"metrics",20)}:{}})).redacted,{kind:"diagnosticsPerf",metrics:n.metrics.map(e=>{let t=ai(e.message,4096),n=aa(e.metadata);return r||=t.redacted||n.redacted,{name:e.name,...void 0!==e.value?{value:e.value}:{},...e.unit?{unit:e.unit}:{},...e.status?{status:e.status}:{},...void 0!==t.value?{message:t.value}:{},...n.value?{metadata:n.value}:{}}}),...n.startedAt?{startedAt:n.startedAt}:{},...n.endedAt?{endedAt:n.endedAt}:{},...n.backend?{backend:n.backend}:{},redacted:r,...n.notes?{notes:n.notes}:{}}};function a5(e){let t={backend:e.backend,artifacts:e.artifacts,sessions:e.sessions??function(e=[]){let t=new Map(e.map(e=>[e.name,a8(e)]));return{get:e=>a8(t.get(e)),set:e=>{t.set(e.name,a8(e))},delete:e=>{t.delete(e)},list:()=>Array.from(t.values(),e=>a8(e))}}(),policy:e.policy??function(e={}){return{allowLocalInputPaths:!1,allowLocalOutputPaths:!1,maxImagePixels:2e7,allowNamedBackendCapabilities:[],...e}}(),diagnostics:e.diagnostics,clock:e.clock,signal:e.signal};return{...t,capture:{screenshot:e=>ap(t,e),diffScreenshot:e=>af(t,e),snapshot:e=>ah(t,e),diffSnapshot:e=>am(t,e)},selectors:{find:e=>aw(t,e),get:e=>ag(t,e),getText:(e,n={})=>ay(t,{...n,target:e}),getAttrs:(e,n={})=>ab(t,{...n,target:e}),is:e=>av(t,e),isVisible:(e,n={})=>aI(t,{...n,target:e}),isHidden:(e,n={})=>aA(t,{...n,target:e}),wait:e=>ax(t,e),waitForText:(e,n={})=>aS(t,{...n,text:e})},interactions:{click:(e,n={})=>aN(t,{...n,target:e}),press:(e,n={})=>a_(t,{...n,target:e}),fill:(e,n,a={})=>aM(t,{...a,target:e,text:n}),typeText:(e,n={})=>ak(t,{...n,text:e}),focus:(e,n={})=>aD(t,{...n,target:e}),longPress:(e,n={})=>aE(t,{...n,target:e}),swipe:e=>aO(t,e),scroll:e=>aC(t,e),pinch:e=>aR(t,e)},system:{back:e=>aP(t,e),home:e=>aT(t,e),rotate:e=>aL(t,e),keyboard:e=>a$(t,e),clipboard:e=>aF(t,e),settings:e=>aU(t,e),alert:e=>aG(t,e),appSwitcher:e=>aV(t,e)},apps:{open:e=>aB(t,e),close:e=>aj(t,e),list:e=>aq(t,e),state:e=>aW(t,e),push:e=>aX(t,e),triggerEvent:e=>aH(t,e)},admin:{devices:e=>az(t,e),boot:e=>aY(t,e),ensureSimulator:e=>aK(t,e),install:e=>aJ(t,e),reinstall:e=>aZ(t,e),installFromSource:e=>aQ(t,e)},recording:{record:e=>a0(t,e),trace:e=>a1(t,e)},observability:{logs:e=>a2(t,e),network:e=>a3(t,e),perf:e=>a4(t,e)}}}function a8(e){if(e)return{...e,...e.snapshot?{snapshot:structuredClone(e.snapshot)}:{},...e.metadata?{metadata:function(e){try{return structuredClone(e)}catch{return{...e}}}(e.metadata)}:{}}}function a6(e={}){return{allowLocalInputPaths:!0,allowLocalOutputPaths:!0,maxImagePixels:2e7,allowNamedBackendCapabilities:[],...e}}function a9(e,t,n){return{ok:!1,error:{code:e,message:t,...n?{details:n}:{}}}}function a7(e){if(!e)return null;let t=Number(e);return Number.isFinite(t)?t:null}function re(e){if(0===e.length)return null;let t=a7(e[0]);if(null!==t)return{kind:"sleep",durationMs:t};if("text"===e[0]){let t=a7(e[e.length-1]);return{kind:"text",text:(null!==t?e.slice(1,-1).join(" "):e.slice(1).join(" ")).trim(),timeoutMs:t}}if(e[0].startsWith("@")){let t=a7(e[e.length-1]);return{kind:"ref",rawRef:e[0],timeoutMs:t}}let n=a7(e[e.length-1]),a=b(null!==n?e.slice(0,-1):e.slice());if(a&&0===a.rest.length){let e=A(a.selectorExpression);if(e)return{kind:"selector",selector:e,selectorExpression:a.selectorExpression,timeoutMs:n}}return{kind:"text",text:(null!==n?e.slice(0,-1).join(" "):e.join(" ")).trim(),timeoutMs:n}}function rt(e){return e}function rn(e){return"apple"===e||"ios"===e||"macos"===e}function ra(e,t){return!t||("apple"===t?rn(e):e===t)}function rr(e){let{simulatorSetPath:t,platform:n,target:a}=e;if(t&&"macos"!==n&&"desktop"!==a)return t}async function ri(e,t,n={}){let a=e,r=e=>e.toLowerCase().replace(/_/g," ").replace(/\s+/g," ").trim();if(t.platform&&(a=a.filter(e=>ra(e.platform,t.platform))),t.target&&(a=a.filter(e=>(e.target??"mobile")===t.target)),t.udid){let e=a.find(e=>e.id===t.udid&&rn(e.platform));if(!e)throw new y("DEVICE_NOT_FOUND",`No Apple device with UDID ${t.udid}`);return e}if(t.serial){let e=a.find(e=>e.id===t.serial&&"android"===e.platform);if(!e)throw new y("DEVICE_NOT_FOUND",`No Android device with serial ${t.serial}`);return e}if(t.deviceName){let e=r(t.deviceName),n=a.find(t=>r(t.name)===e);if(!n)throw new y("DEVICE_NOT_FOUND",`No device named ${t.deviceName}`);return n}if(1===a.length)return a[0];if(0===a.length){var i;let e=n.simulatorSetPath;if(e&&(!(i=t.platform)||"apple"===i||"ios"===i))throw new y("DEVICE_NOT_FOUND","No devices found in the scoped simulator set",{simulatorSetPath:e,hint:`The simulator set at "${e}" appears to be empty. Create a simulator first:
|
|
2
|
-
xcrun simctl --set "${e}" create "iPhone 16" com.apple.CoreSimulator.SimDeviceType.iPhone-16 com.apple.CoreSimulator.SimRuntime.iOS-18-0`,selector:t});throw new y("DEVICE_NOT_FOUND","No devices found",{selector:t})}let o=
|
|
3
|
-
`)}let rI=new Set,rA=new Map,rx="request_canceled",rS="request canceled";function rN(e,t){if("string"==typeof e&&e.length>0)return e;let n=("string"==typeof t?t:"number"==typeof t&&Number.isFinite(t)?String(t):"generated").trim().replace(/[^a-zA-Z0-9_-]/g,"_").slice(0,32)||"generated",a=Math.random().toString(36).slice(2,10);return`req:${n}:${process.pid}:${Date.now()}:${a}`}function r_(e){if(!e)return;!function(e){if(e.size<=5e4)return;let t=0;for(let n of e.keys()){if(t>=1e4)break;e.delete(n),t++}}(rA);let t=new AbortController;rA.set(e,t),rI.has(e)&&t.abort()}function rM(e){e&&(!function(e){if(e.size<=5e4)return;let t=0;for(let n of e){if(t>=1e4)break;e.delete(n),t++}}(rI),rI.add(e),rA.get(e)?.abort())}function rk(e){e&&(rI.delete(e),rA.delete(e))}function rD(e){return!!e&&rI.has(e)}function rE(e){if(e)return rA.get(e)?.signal}function rO(){return new y("COMMAND_FAILED",rS,{reason:rx})}function rC(e){return e instanceof y&&"COMMAND_FAILED"===e.code&&(e.details?.reason===rx||e.message===rS)}function rR(e){let t=e.error?w(e.error):null,n=e.context?.platform,a=e.context?.phase;if(t?.code==="TOOL_MISSING")return"android"===n?"ADB_TRANSPORT_UNAVAILABLE":"IOS_TOOL_MISSING";let r=t?.details??{},i="string"==typeof r.message?r.message:void 0,o="string"==typeof r.stdout?r.stdout:void 0,s="string"==typeof r.stderr?r.stderr:void 0,l=r.boot&&"object"==typeof r.boot?r.boot:null,d=r.bootstatus&&"object"==typeof r.bootstatus?r.bootstatus:null,u=[e.message,t?.message,e.stdout,e.stderr,i,o,s,"string"==typeof l?.stdout?l.stdout:void 0,"string"==typeof l?.stderr?l.stderr:void 0,"string"==typeof d?.stdout?d.stdout:void 0,"string"==typeof d?.stderr?d.stderr:void 0].filter(Boolean).join("\n").toLowerCase();return"ios"===n&&(u.includes("runner did not accept connection")||"connect"===a&&(u.includes("timed out")||u.includes("timeout")||u.includes("econnrefused")||u.includes("connection refused")||u.includes("fetch failed")||u.includes("socket hang up")))?"IOS_RUNNER_CONNECT_TIMEOUT":"ios"===n&&"boot"===a&&(u.includes("timed out")||u.includes("timeout"))?"IOS_BOOT_TIMEOUT":"android"===n&&"boot"===a&&(u.includes("timed out")||u.includes("timeout"))?"ANDROID_BOOT_TIMEOUT":u.includes("resource temporarily unavailable")||u.includes("killed: 9")||u.includes("cannot allocate memory")||u.includes("system is low on memory")?"CI_RESOURCE_STARVATION_SUSPECTED":"android"===n&&(u.includes("device not found")||u.includes("no devices")||u.includes("device offline")||u.includes("offline")||u.includes("unauthorized")||u.includes("not authorized")||u.includes("unable to locate device")||u.includes("invalid device"))?"ADB_TRANSPORT_UNAVAILABLE":t?.code==="COMMAND_FAILED"||u.length>0?"BOOT_COMMAND_FAILED":"UNKNOWN"}function rP(e){switch(e){case"IOS_BOOT_TIMEOUT":return"Retry simulator boot and inspect simctl bootstatus logs; in CI consider increasing AGENT_DEVICE_IOS_BOOT_TIMEOUT_MS.";case"IOS_RUNNER_CONNECT_TIMEOUT":return"Retry runner startup, inspect xcodebuild logs, and verify simulator responsiveness before command execution.";case"ANDROID_BOOT_TIMEOUT":return"Retry emulator startup and verify sys.boot_completed reaches 1; consider increasing startup budget in CI.";case"ADB_TRANSPORT_UNAVAILABLE":return"Check adb server/device transport (adb devices -l), restart adb, and ensure the target device is online and authorized.";case"CI_RESOURCE_STARVATION_SUSPECTED":return"CI machine may be resource constrained; reduce parallel jobs or use a larger runner.";case"IOS_TOOL_MISSING":return"Xcode command-line tools are missing or not in PATH; run xcode-select --install and verify xcrun works.";case"BOOT_COMMAND_FAILED":return"Inspect command stderr/stdout for the failing boot phase and retry after environment validation.";default:return"Retry once and inspect verbose logs for the failing phase."}}let rT=["AGENT_DEVICE_IOS_SIMULATOR_DEVICE_SET","IOS_SIMULATOR_DEVICE_SET"],rL=["AGENT_DEVICE_ANDROID_DEVICE_ALLOWLIST","ANDROID_DEVICE_ALLOWLIST"];function r$(e){return e?.trim()||void 0}function rF(e,t){for(let n of e){let e=r$(t[n]);if(e)return e}}function rU(e,t=process.env){return r$(e)??rF(rT,t)}function rG(e){return new Set(e.split(/[\s,]+/).map(e=>e.trim()).filter(Boolean))}function rV(e,t=process.env){let n=r$(e)??rF(rL,t);if(n)return rG(n)}function rB(e,t={}){let n=rU(t.simulatorSetPath);return n?["simctl","--set",n,...e]:["simctl",...e]}function rj(e,t){return"ios"!==e.platform||"simulator"!==e.kind?["simctl",...t]:rB(t,{simulatorSetPath:e.simulatorSetPath})}function rq(e){return!(e instanceof y)||"COMMAND_FAILED"!==e.code||!String(e.message??"").toLowerCase().includes("xcodebuild exited early")}function rW(e){let{port:t,endpoints:n,logPath:a,lastError:r}=e,i="Runner did not accept connection";return new y("COMMAND_FAILED",i,{port:t,endpoints:n,logPath:a,lastError:r?String(r):void 0,reason:rR({error:r,message:i,context:{platform:"ios",phase:"connect"}}),hint:rP("IOS_RUNNER_CONNECT_TIMEOUT")})}async function rX(e){var t,n;let a,{session:r,port:i,logPath:o}=e,s=await r.testPromise,l="Runner did not accept connection (xcodebuild exited early)",d=rR({message:l,stdout:s.stdout,stderr:s.stderr,context:{platform:"ios",phase:"connect"}});return new y("COMMAND_FAILED",l,{port:i,logPath:o,xcodebuild:{exitCode:s.exitCode,stdout:s.stdout,stderr:s.stderr},reason:d,hint:(t=s.stdout,n=s.stderr,(a=`${l}
|
|
1
|
+
let e;import{__webpack_require__ as t}from"./rslib-runtime.js";import n,{existsSync as r,promises as a}from"node:fs";import{PNG as i}from"pngjs";import o from"node:path";import s,{hostname as l}from"node:os";import d from"node:net";import{AsyncLocalStorage as u}from"node:async_hooks";import{fileURLToPath as c}from"node:url";import{XMLParser as p}from"fast-xml-parser";import{createHash as f}from"node:crypto";import h from"node:fs/promises";import{toAppErrorCode as m,asAppError as w,normalizeError as g,AppError as y}from"./9152.js";import{splitSelectorFromArgs as b,trimText as v,extractNodeText as I,tryParseSelectorChain as A,parseSelectorChain as x,isNodeVisible as S,isNodeEditable as N,pruneGroupNodes as _,buildTextPreview as k,findNearestHittableAncestor as M,buildSelectorChainForNode as D,extractNodeReadText as E,splitIsSelectorArgs as O,findNodeByLabel as C,resolveRefLabel as R,describeTextSurface as P,extractReadableText as T,findSelectorChainMatch as L,resolveSelectorChain as $,normalizeType as F,formatSelectorFailure as U,isFillableType as G}from"./940.js";import{findNodeByRef as V,centerOfRect as B,normalizeRef as j,attachRefs as q}from"./4057.js";import{parseUiHierarchy as X,ensureAndroidSnapshotHelper as H,parseUiHierarchyTree as K,readNodeAttributes as z,captureAndroidSnapshotWithHelper as Y,parseBounds as W,isScrollableNodeLike as J,parseAndroidSnapshotHelperManifest as Z,forgetAndroidSnapshotHelperInstall as Q,isScrollableType as ee,buildUiHierarchySnapshot as et}from"./221.js";import{readVersion as en,findProjectRoot as er,successText as ea,withSuccessText as ei}from"./180.js";import{runCmdBackground as eo,runCmdStreaming as es,runCmdSync as el,runCmd as ed,whichCmd as eu,resolveExecutableOverridePath as ec}from"./9818.js";import{findBestMatchesByLocator as ep,parseFindArgs as ef}from"./7556.js";import"./7847.js";import{runAndroidAdb as eh,resolveIosSimulatorDeviceSetPath as em,dismissAndroidKeyboard as ew,resolveIosDeviceDeepLinkBundleId as eg,withRetry as ey,Deadline as eb,classifyBootFailure as ev,openAndroidApp as eI,isEnvTruthy as eA,ensureAdb as ex,closeAndroidApp as eS,TIMEOUT_PROFILES as eN,bootFailureHint as e_,openAndroidDevice as ek,writeAndroidClipboardText as eM,getAndroidKeyboardState as eD,listAndroidDevices as eE,getAndroidAppState as eO,retryWithPolicy as eC,resolveAndroidSerialAllowlist as eR,createAppResolutionCache as eP,isDeepLinkTarget as eT,isClipboardShellUnsupported as eL,readAndroidClipboardText as e$}from"./8809.js";import{sleep as eF,resolveTimeoutMs as eU,resolveTimeoutSeconds as eG}from"./4829.js";import{isProcessGroupAlive as eV,isProcessAlive as eB,readProcessStartTime as ej}from"./8656.js";import{withDiagnosticTimer as eq,getDiagnosticsMeta as eX,emitDiagnostic as eH}from"./7599.js";import{resolveAndroidAdbProvider as eK,resolveAndroidAdbExecutor as ez}from"./9639.js";import{materializeInstallablePath as eY,isTrustedInstallSourceUrl as eW}from"./989.js";var eJ={};t.r(eJ),t.d(eJ,{TM:()=>lw,ensureBootedSimulator:()=>sS,installIosApp:()=>ly,installIosInstallablePath:()=>lv,listIosApps:()=>lN,L5:()=>lh,IJ:()=>lm,TJ:()=>lx,J7:()=>lI,reinstallIosApp:()=>lb,resolveIosApp:()=>lf,kc:()=>s8,Cm:()=>lS,ap:()=>lA});let eZ="<wifi|airplane|location> <on|off>",eQ="animations <on|off>",e0="appearance <light|dark|toggle>",e1="faceid <match|nonmatch|enroll|unenroll>",e2="touchid <match|nonmatch|enroll|unenroll>",e3="fingerprint <match|nonmatch>",e5="permission <grant|deny|reset> <camera|microphone|photos|contacts|contacts-limited|notifications|calendar|location|location-always|media-library|motion|reminders|siri> [full|limited]",e4="permission <grant|reset> <accessibility|screen-recording|input-monitoring>",e8=`macOS supports only settings ${e0} and settings ${e4}. wifi|airplane|location|animations remain unsupported on macOS.`,e6=`settings ${eZ} | settings ${eQ} | settings ${e0} | settings ${e1} | settings ${e2} | settings ${e3} | settings ${e5} | settings ${e4}`,e9=`settings requires ${eZ}, ${eQ}, ${e0}, ${e1}, ${e2}, ${e3}, ${e5}, or ${e4}`;function e7(e){return`Unsupported macOS setting: ${e}. ${e8}`}let te=["app","frontmost-app","desktop","menubar"];function tt(e){let t=e?.trim().toLowerCase();if("app"===t||"frontmost-app"===t||"desktop"===t||"menubar"===t)return t;throw new y("INVALID_ARGS",`Invalid surface: ${e}. Use ${te.join("|")}.`)}let tn={application:"application",navigationbar:"navigation-bar",tabbar:"tab-bar",button:"button",imagebutton:"button",link:"link",cell:"cell",statictext:"text",checkedtextview:"text",textfield:"text-field",edittext:"text-field",textarea:"text-view",switch:"switch",slider:"slider",image:"image",imageview:"image",webview:"webview",framelayout:"group",linearlayout:"group",relativelayout:"group",constraintlayout:"group",viewgroup:"group",view:"group",listview:"list",recyclerview:"list",collectionview:"collection",searchfield:"search",segmentedcontrol:"segmented-control",group:"group",window:"window",checkbox:"checkbox",radio:"radio",menuitem:"menu-item",toolbar:"toolbar",scrollarea:"scroll-area",scrollview:"scroll-area",nestedscrollview:"scroll-area",table:"table"};function tr(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()||"",o=to(a.type??"Element");if("group"===o&&!i)continue;for(;n.length>0&&e<=n[n.length-1];)n.pop();let s=n.length;n.push(e),r.push({node:a,depth:s,type:o,text:ta(a,s,!1,o,t)})}return r}function ta(e,t,n,r,a={}){var i,o,s,l,d,u,c,p;let f,h=r??to(e.type??"Element"),m=P(e,h),w=(i=e,o=h,s=a,l=m,s.summarizeTextSurfaces&&l.shouldSummarize&&function(e,t,n){let r=v(e.label);if(r&&r!==n)return r;let a=v(e.identifier);if(a&&!tl(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""}}(i,o,l.text)||ti(i,o)),g=" ".repeat(t),y=e.ref?`@${e.ref}`:"",b=(d=e,u=h,c=a,p=m,f=[],(!1===d.enabled&&f.push("disabled"),c.summarizeTextSurfaces&&(!0===d.selected&&f.push("selected"),ts(u)&&f.push("editable"),function(e,t){if("scroll-area"===t)return!0;let n=(e.type??"").toLowerCase(),r=`${e.role??""} ${e.subrole??""}`.toLowerCase();return n.includes("scroll")||r.includes("scroll")}(d,u)&&f.push("scrollable"),p.shouldSummarize))?(f.push(`preview:"${k(p.text).replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`),f.push("truncated"),[...new Set(f)]):f).map(e=>` [${e}]`).join(""),I=w?` "${w}"`:"";return n?`${g}${y} [${h}]${b}`.trimEnd():`${g}${y} [${h}]${I}${b}`.trimEnd()}function ti(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 o=e.value?.trim();if(ts(t)){if(o)return o;if(i)return i}else if(i)return i;if(o)return o;let s=e.identifier?.trim();return!s||tl(s)&&("group"===t||"image"===t||"list"===t||"collection"===t)?"":s}function to(e){var t;let n=e.replace(/XCUIElementType/gi,"").toLowerCase(),r=e.includes(".")&&(e.startsWith("android.")||e.startsWith("androidx.")||e.startsWith("com."));return(n.includes(".")&&(n=n.replace(/^android\.widget\./,"").replace(/^android\.view\./,"").replace(/^android\.webkit\./,"").replace(/^androidx\./,"").replace(/^com\.google\.android\./,"").replace(/^com\.android\./,""),r&&n.includes(".")&&(n=n.slice(n.lastIndexOf(".")+1))),"textview"===n)?r?"text":"text-view":(t=n,(Object.prototype.hasOwnProperty.call(tn,t)?tn[t]:void 0)||n||"element")}function ts(e){return"text-field"===e||"text-view"===e||"search"===e}function tl(e){return/^[\w.]+:id\/[\w.-]+$/i.test(e)}function td(e){return new Map(e.map(e=>[e.index,e]))}function tu(e){return e.label?.trim()||e.value?.trim()||e.identifier?.trim()||""}function tc(e,t,n){return t>=e.x&&t<=e.x+e.width&&n>=e.y&&n<=e.y+e.height}function tp(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 tf(e,t,n,r){return Math.max(e,n)<=Math.min(t,r)}function th(e){if(0===e.length)return{nodes:e,hiddenCount:0,summaryLines:[]};let{byIndex:t,visibleNodeIndexes:n,offscreenNodes:r,hintedContainers:a}=tm(e),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=tg(e,t,n);return r?ty(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=tu(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")||!!tu(e)}(e)),e,t)}}function tm(e){let t=td(e),n=new Set,r=[];for(let a of e){if(tw(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=tb(e,n,r);if(!t?.rect)continue;let o=ty(e.rect,t.rect);if(!o)continue;let s=a.get(t.index)??new Set;s.add(o),a.set(t.index,s),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=tb(a,t,n);if(!i)continue;let o=r.get(i.index)??new Set;for(let t of e)o.add(t);r.set(i.index,o)}}(e,n,r,a),{directionsByContainer:a,coveredNodeIndexes:i}}(e,r,n,t);return{byIndex:t,visibleNodeIndexes:n,offscreenNodes:r,hintedContainers:a}}function tw(e,t,n=td(t)){var r;if(!e.rect)return!0;let a=tg(e,t,n);return!a||(r=e.rect,tf(r.x,r.x+r.width,a.x,a.x+a.width)&&tf(r.y,r.y+r.height,a.y,a.y+a.height))}function tg(e,t,n=td(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&&J(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=B(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=tp(a.map(e=>e.rect).filter(e=>tc(e,n.x,n.y)));if(i)return i;let o=tp(a.map(e=>e.rect));if(o)return o;let s=tp(r.map(e=>e.rect).filter(e=>tc(e,n.x,n.y)));return s||null}(t,e.rect??{x:0,y:0,width:0,height:0})}function ty(e,t){return e.y+e.height<=t.y?"above":e.y>=t.y+t.height?"below":null}function tb(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)&&J(r))return r;r="number"==typeof r.parentIndex?n.get(r.parentIndex):void 0}return null}function tv(e,t){try{return i.sync.read(e)}catch(e){throw new y("COMMAND_FAILED",`Failed to decode ${t} as PNG`,{label:t,reason:e instanceof Error?e.message:String(e)})}}async function tI(e,t){if(!Number.isInteger(t)||t<1)throw new y("INVALID_ARGS","Screenshot max size must be a positive integer");let n=tv(await a.readFile(e),"screenshot"),r=Math.max(n.width,n.height);if(r<=t)return;let o=t/r,s=Math.max(1,Math.round(n.width*o)),l=Math.max(1,Math.round(n.height*o)),d=function(e,t,n){let r=new i({width:t,height:n});for(let a=0;a<n;a+=1){let i=a*e.height/n,o=(a+1)*e.height/n;for(let n=0;n<t;n+=1){let s=n*e.width/t,l=(n+1)*e.width/t,d=0,u=0,c=0,p=0,f=0;for(let t=Math.floor(i);t<Math.ceil(o);t+=1){let n=Math.min(t+1,o)-Math.max(t,i);for(let r=Math.floor(s);r<Math.ceil(l);r+=1){let a=n*(Math.min(r+1,l)-Math.max(r,s)),i=(t*e.width+r)*4;d+=(e.data[i]??0)*a,u+=(e.data[i+1]??0)*a,c+=(e.data[i+2]??0)*a,p+=(e.data[i+3]??0)*a,f+=a}}let h=(a*r.width+n)*4;r.data[h]=Math.round(d/f),r.data[h+1]=Math.round(u/f),r.data[h+2]=Math.round(c/f),r.data[h+3]=Math.round(p/f)}}return r}(n,s,l);await a.writeFile(e,i.sync.write(d))}async function tA(e,t,n){if("path"===t.kind&&!e.policy.allowLocalInputPaths)throw new y("INVALID_ARGS",`Local ${n.field??"input"} paths are not allowed by command policy`);try{return await e.artifacts.resolveInput(t,n)}catch(e){throw w(e)}}async function tx(e,t,n){if(t?.kind==="path"&&!e.policy.allowLocalOutputPaths)throw new y("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 w(e)}}async function tS(e,t){try{return await e.artifacts.createTempFile(t)}catch(e){throw w(e)}}let tN=[0,187,255,255];function t_(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 tk(e,t,n){return Math.min(Math.max(e,t),n)}let tM={icon:90,toggle:90,chevron:75,separator:45,visual:35,background:10},tD={leading:20,trailing:20,separator:10,unknown:0,background:-30};function tE(e){return"background"!==e.likelyKind}function tO(e,t){return e.width>=.25*t.width||e.height>=.06*t.height}function tC(e,t){let n,r=0;for(let a of t){let t=t$(e,a.rect);t<=r||(r=t,n=a)}return n}function tR(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,t$(t,r=n.rect)>0||Math.abs(tF(t).y-tF(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 tP(e,t){let n,r=tF(e);for(let e of t){var a,i;let t=Math.sqrt((a=r,i=tF(e.rect),(a.x-i.x)**2+(a.y-i.y)**2));n&&t>=n.distance||(n={block:e,distance:t})}return n}function tT(e){let t=tL(e);return e.differentPixels>=24&&t.width>=3&&t.height>=3}function tL(e){return{x:e.minX,y:e.minY,width:e.maxX-e.minX+1,height:e.maxY-e.minY+1}}function t$(e,t){return Math.max(0,Math.min(e.y+e.height,t.y+t.height)-Math.max(e.y,t.y))}function tF(e){return{x:e.x+e.width/2,y:e.y+e.height/2}}function tU(e,t,n){return Math.min(Math.max(e,t),n)}async function tG(e){if(await eu("tesseract"))try{let[t,n]=await Promise.all([tB(e.baselinePath),tB(e.currentPath)]);if(0!==t.exitCode||0!==n.exitCode)return;let r=tV(t.stdout,e.width,e.height),a=tV(n.stdout,e.width,e.height),i=function(e,t){let n=new Set,r=[];for(let i of e){var a;let e=tY(i.text),o=function(e,t,n,r){let a=null,i=1/0;for(let l=0;l<n.length;l+=1){var o,s;if(r.has(l))continue;let d=n[l];if(tY(d.text)!==t)continue;let u=(o=tH(e.normalizedRect),s=tH(d.normalizedRect),(o.x-s.x)**2+(o.y-s.y)**2);u>=i||(a=l,i=u)}return a}(i,e,t,n);if(null===o)continue;n.add(o);let s=function(e,t){let n={x:t.rect.x-e.rect.x,y:t.rect.y-e.rect.y,width:t.rect.width-e.rect.width,height:t.rect.height-e.rect.height},r=tZ(t.rect.width/e.rect.width),a=tZ(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[o]);a=s,(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(s)}return r.sort((e,t)=>tj(t)-tj(e)).slice(0,12)}(r,a),o=function(e){let t=[];for(let n of[...e].sort((e,t)=>e.currentRect.y-t.currentRect.y)){let e=t.find(e=>32>=Math.abs(n.delta.x-tW(e.map(e=>e.delta.x))));e?e.push(n):t.push([n])}return t.filter(e=>e.length>=2).map(tq).filter(e=>e.yRange.max-e.yRange.min<=60).sort((e,t)=>tX(t)-tX(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,...o.length>0?{movementClusters:o}:{}}}catch{return}}function tV(e,t,n){let[r,...a]=e.split(/\r?\n/);if(!r)return[];let i=new Map(r.split(" ").map((e,t)=>[e,t])),o=[];for(let e of a){var s;if(!e.trim())continue;let t=e.split(" "),n=tz(t,i,"level"),r=tK(t,i,"text").trim(),a=tz(t,i,"conf");if(5!==n||(s=r,!/[\p{L}\p{N}]/u.test(s))||a<0)continue;let l=tz(t,i,"left"),d=tz(t,i,"top"),u=tz(t,i,"width"),c=tz(t,i,"height");u<=0||c<=0||o.push({key:[tK(t,i,"page_num"),tK(t,i,"block_num"),tK(t,i,"par_num"),tK(t,i,"line_num")].join(":"),text:r,confidence:a,rect:{x:l,y:d,width:u,height:c}})}let l=new Map;for(let e of o){let t=l.get(e.key);t?t.push(e):l.set(e.key,[e])}return Array.from(l.values()).flatMap(e=>(function(e){let t=[...e].sort((e,t)=>e.rect.x-t.rect.x),n=[],r=[];for(let e of t){let t=r.at(-1);if(!t){r.push(e);continue}if(e.rect.x-(t.rect.x+t.rect.width)>Math.max(48,2.5*Math.max(t.rect.height,e.rect.height))){n.push(r),r=[e];continue}r.push(e)}return r.length>0&&n.push(r),n})(e)).map(e=>(function(e,t,n){if(0===e.length)return null;let r=[...e].sort((e,t)=>e.rect.x-t.rect.x),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*tW(r.map(e=>e.confidence)))/100;return{text:r.map(e=>e.text).join(" "),confidence:i,rect:a,normalizedRect:{x:tJ(a.x/t),y:tJ(a.y/n),width:tJ(a.width/t),height:tJ(a.height/n)}}})(e,t,n)).filter(e=>null!==e)}function tB(e){return ed("tesseract",[e,"stdout","-l","eng","tsv"],{allowFailure:!0,timeoutMs:1e4})}function tj(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 tq(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 tX(e){return 2*Math.abs((e.xRange.min+e.xRange.max)/2)+Math.abs((e.yRange.min+e.yRange.max)/2)}function tH(e){return{x:e.x+e.width/2,y:e.y+e.height/2}}function tK(e,t,n){let r=t.get(n);return void 0===r?"":e[r]??""}function tz(e,t,n){let r=Number(tK(e,t,n));return Number.isFinite(r)?r:0}function tY(e){return e.trim().replace(/\s+/g," ").toLowerCase()}function tW(e){return e.reduce((e,t)=>e+t,0)/e.length}function tJ(e){return Math.round(100*e*100)/100}function tZ(e){return Math.round(1e3*e)/1e3}function tQ(e,t,n,r){return{r:Math.round(e/r),g:Math.round(t/r),b:Math.round(n/r)}}function t0(e){return .2126*e.r+.7152*e.g+.0722*e.b}function t1(e){return`#${t2(e.r)}${t2(e.g)}${t2(e.b)}`}function t2(e){return e.toString(16).padStart(2,"0")}function t3(e){return Math.round(100*e*100)/100}let t5=255*Math.sqrt(3);async function t4(e,t,n={}){let r,s,l,d;await t8(e,"Baseline image not found"),await t8(t,"Current screenshot not found");let u=n.outputPath,[c,p]=await Promise.all([a.readFile(e),a.readFile(t)]),f=tv(c,"baseline screenshot"),h=tv(p,"current screenshot");t6(f.width,f.height,"baseline screenshot",n.maxPixels),t6(h.width,h.height,"current screenshot",n.maxPixels);let m=n.threshold??.1;if(f.width!==h.width||f.height!==h.height){let e=f.width*f.height;return await t9(n.outputPath),{match:!1,mismatchPercentage:100,totalPixels:e,differentPixels:e,dimensionMismatch:{expected:{width:f.width,height:f.height},actual:{width:h.width,height:h.height}}}}let w=f.width*f.height,g=m*t5,y=new i({width:f.width,height:f.height}),b=new Uint8Array(w),v=0;for(let e=0,t=0;e<f.data.length;e+=4,t+=1){if(Math.sqrt((f.data[e]-h.data[e])**2+(f.data[e+1]-h.data[e+1])**2+(f.data[e+2]-h.data[e+2])**2)>g){v+=1,b[t]=1;let n=t7(h,e);y.data[e]=ne(n,220,.78),y.data[e+1]=ne(n,0,.78),y.data[e+2]=ne(n,0,.78),y.data[e+3]=255;continue}let n=t7(h,e);y.data[e]=n,y.data[e+1]=n,y.data[e+2]=n,y.data[e+3]=255}let I=v>0?(x=(r=function(e){let{diffMask:t,baseline:n,current:r}=e,{width:a,height:i}=n,o=new Uint8Array(t.length),s=new Int32Array(t.length),l=[];for(let e=0;e<t.length;e+=1){if(1!==t[e]||1===o[e])continue;let d=0,u=0;s[0]=e,u+=1,o[e]=1;let c=e%a,p=Math.floor(e/a),f={minX:c,minY:p,maxX:c,maxY:p,differentPixels:0,baselineRed:0,baselineGreen:0,baselineBlue:0,currentRed:0,currentGreen:0,currentBlue:0};for(;d<u;){let e=s[d];d+=1,function(e,t,n,r,a){let i=t%n,o=Math.floor(t/n),s=4*t;e.minX=Math.min(e.minX,i),e.minY=Math.min(e.minY,o),e.maxX=Math.max(e.maxX,i),e.maxY=Math.max(e.maxY,o),e.differentPixels+=1,e.baselineRed+=r.data[s],e.baselineGreen+=r.data[s+1],e.baselineBlue+=r.data[s+2],e.currentRed+=a.data[s],e.currentGreen+=a.data[s+1],e.currentBlue+=a.data[s+2]}(f,e,a,n,r);let l=e%a,c=Math.floor(e/a);for(let e=-1;e<=1;e+=1){let n=c+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 d=n*a+i;1===t[d]&&1!==o[d]&&(o[d]=1,s[u]=d,u+=1)}}}l.push(f)}return l}(A={diffMask:b,baseline:f,current:h,totalPixels:w,differentPixels:v,maxRegions:n.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}(r):r,x.flatMap(e=>{var t,n,r;let a;return(t=e,n=A.baseline.width,r=A.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),o=Math.min(r.length-1,t+3);for(let e=i;e<=o;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,o]of t){let t=e.minY+Math.round((i+o)/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 o=i.map(([n,r])=>(function(e,t,n,r){let a=null;for(let s=t;s<=n;s+=1)for(let t=e.minX;t<=e.maxX;t+=1){var i,o;let e=s*r.baseline.width+t;1===r.diffMask[e]&&function(e,t,n,r,a,i){let o=4*t;e.minX=Math.min(e.minX,n),e.minY=Math.min(e.minY,r),e.maxX=Math.max(e.maxX,n),e.maxY=Math.max(e.maxY,r),e.differentPixels+=1,e.baselineRed+=a.data[o],e.baselineGreen+=a.data[o+1],e.baselineBlue+=a.data[o+2],e.currentRed+=i.data[o],e.currentGreen+=i.data[o+1],e.currentBlue+=i.data[o+2]}(a??={minX:i=t,minY:o=s,maxX:i,maxY:o,differentPixels:0,baselineRed:0,baselineGreen:0,baselineBlue:0,currentRed:0,currentGreen:0,currentBlue:0},e,t,s,r.baseline,r.current)}return a})(e,n,r,t)).filter(e=>null!==e);return o.length>1?o:[e]}(e,A,Math.max(24,Math.round(.03*A.baseline.height))):[e]})).sort((e,t)=>{let n=t.differentPixels-e.differentPixels;if(0!==n)return n;let r=e.minY-t.minY;return 0!==r?r:e.minX-t.minX}).slice(0,Math.max(0,A.maxRegions??8)).map((e,t)=>{var n,r,a,i,o,s,l,d,u,c,p;let f,h,m,w,g,y,b,v,I,x,S,N,_,k,M,D,E;return n=e,r=t+1,a={width:A.baseline.width,height:A.baseline.height,totalPixels:A.totalPixels,differentPixels:A.differentPixels},y={x:n.minX,y:n.minY,width:n.maxX-n.minX+1,height:n.maxY-n.minY+1},b={x:Math.round(n.minX+y.width/2),y:Math.round(n.minY+y.height/2)},v=tQ(n.baselineRed,n.baselineGreen,n.baselineBlue,n.differentPixels),I=tQ(n.currentRed,n.currentGreen,n.currentBlue,n.differentPixels),x=y.width*y.height,S=t3(n.differentPixels/x),N=Math.round(t0(v)),_=Math.round(t0(I)),k=(i=y,o=a.width,s=a.height,i.width>=.55*o&&i.height>=.12*s?"large-area":i.width>=2.5*i.height?"horizontal-band":i.height>=2.5*i.width?"vertical-band":"compact"),M=(f=x/a.totalPixels)>=.04?"large":f>=.01?"medium":"small",D=(l=v,d=I,h=t0(l),Math.abs(m=t0(d)-h)>=12?m>0?"brighter":"darker":Math.max(Math.abs(d.r-l.r),Math.abs(d.g-l.g),Math.abs(d.b-l.b))>=12?"color-shift":"mixed"),E=(u=b,c=a.width,p=a.height,w=u.x<c/3?"left":u.x>2*c/3?"right":"center",g=u.y<p/3?"top":u.y>2*p/3?"bottom":"middle","center"===w&&"middle"===g?"center":`${g}-${w}`),{index:r,rect:y,normalizedRect:{x:t3(y.x/a.width),y:t3(y.y/a.height),width:t3(y.width/a.width),height:t3(y.height/a.height)},differentPixels:n.differentPixels,shareOfDiffPercentage:t3(n.differentPixels/a.differentPixels),densityPercentage:S,shape:k,size:M,location:E,averageBaselineColorHex:t1(v),averageCurrentColorHex:t1(I),baselineLuminance:N,currentLuminance:_,dominantChange:D}}):[];if(v>0&&u){var A,x,S;for(let e of I)e.rect.width<4||e.rect.height<4||function(e,t){let n=tk(t.x,0,e.width-1),r=tk(t.y,0,e.height-1),a=tk(t.x+t.width-1,0,e.width-1),i=tk(t.y+t.height-1,0,e.height-1);for(let t=0;t<2;t+=1){for(let o=n;o<=a;o+=1)t_(e,o,r+t,tN),t_(e,o,i-t,tN);for(let o=r;o<=i;o+=1)t_(e,n+t,o,tN),t_(e,a-t,o,tN)}}(y,e.rect);await a.mkdir(o.dirname(u),{recursive:!0}),await a.writeFile(u,i.sync.write(y))}else await t9(n.outputPath);let N=v>0?await tG({baselinePath:e,currentPath:t,width:f.width,height:f.height}):void 0,_=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,k=v>0&&N?(s=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 o=0;o<e.length;o+=1){if(1!==e[o]||1===r[o])continue;let s=0,l=0;a[0]=o,l+=1,r[o]=1;let d=o%t,u=Math.floor(o/t),c={minX:d,minY:u,maxX:d,maxY:u,differentPixels:0};for(;s<l;){let i=a[s];s+=1;let o=i%t,d=Math.floor(i/t);c.minX=Math.min(c.minX,o),c.minY=Math.min(c.minY,d),c.maxX=Math.max(c.maxX,o),c.maxY=Math.max(c.maxY,d),c.differentPixels+=1;for(let i=-1;i<=1;i+=1){let s=d+i;if(!(s<0)&&!(s>=n))for(let n=-1;n<=1;n+=1){if(0===n&&0===i)continue;let d=o+n;if(d<0||d>=t)continue;let u=s*t+d;1===e[u]&&1!==r[u]&&(r[u]=1,a[l]=u,l+=1)}}}i.push(c)}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=tU(Math.floor(r.x),0,t-1),i=tU(Math.floor(r.y),0,n-1),o=tU(Math.ceil(r.x+r.width),0,t),s=tU(Math.ceil(r.y+r.height),0,n);for(let n=i;n<s;n+=1)for(let r=a;r<o;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}((S={diffMask:b,width:f.width,height:f.height,regions:I,ocr:N}).diffMask,S.width,S.height,S.ocr),S.width,S.height)),l=tR(S.ocr?.currentBlocksRaw??[]),d=tR(S.ocr?.baselineBlocksRaw??[]),s.filter(tT).map(e=>{var t,n,r,a,i,o,s,u,c,p,f;let h,m,w,g,y,b,v,I,A,x;return t=e,n=S,r=l,a=d,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=tL(t),n.regions),y=function(e,t,n){let r=tC(e,t);if(r)return tP(e,r.blocks);let a=tC(e,n);return a?tP(e,a.blocks):void 0}(w,r,a),b=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,y?.block.rect,n.width),v=(i=w,o=b,s=t.differentPixels,u=n,h=i.width/i.height,m=s/(i.width*i.height),"separator"===o?"separator":"background"===o?"background":"trailing"===o&&h>=1.5&&h<=3.8&&m>=.35?"toggle":"trailing"===o&&i.width<=.06*u.width&&i.height<=.04*u.height?"chevron":"leading"===o&&h>=.55&&h<=1.8?"icon":tO(i,u)?"background":"visual"),I={...g?{regionIndex:g}:{},slot:b,likelyKind:v,rect:w},{...g?{regionIndex:g}:{},slot:b,likelyKind:v,rect:w,...y?{nearestText:y.block.text.trim().replace(/^[^\p{L}\p{N}]+/u,"").replace(/^\p{L}\s+/u,"")}:{},score:(c=I,p=t.differentPixels,f=n,A=tO(c.rect,f)?-35:0,x=20*!!c.regionIndex,tM[c.likelyKind]+tD[c.slot]+x+A+Math.min(20,p/200))}}).filter(e=>e.rect.y>=.08*S.height).filter(tE).sort((e,t)=>t.score-e.score).slice(0,Math.max(0,S.maxDeltas??12)).map((e,t)=>{var n;return n=e,{index:t+1,...n.regionIndex?{regionIndex:n.regionIndex}:{},slot:n.slot,likelyKind:n.likelyKind,rect:n.rect,...n.nearestText?{nearestText:n.nearestText}:{}}})):[],M=w>0?Math.round(v/w*1e4)/100:0;return{...v>0&&u?{diffPath:u}:{},...I.length>0?{regions:I}:{},..._?{ocr:_}:{},...k.length>0?{nonTextDeltas:k}:{},totalPixels:w,differentPixels:v,mismatchPercentage:M,match:0===v}}async function t8(e,t){try{await a.access(e)}catch{throw new y("INVALID_ARGS",`${t}: ${e}`)}}function t6(e,t,n,r){if(null==r||r<=0)return;let a=e*t;if(!(a<=r))throw new y("INVALID_ARGS",`${n} is ${a} pixels, which exceeds the configured maxImagePixels limit of ${r}`)}async function t9(e){if(e)try{await a.unlink(e)}catch(e){var t;if(!("object"==typeof(t=e)&&null!==t&&"code"in t&&"ENOENT"===t.code))throw e}}function t7(e,t){return ne(Math.round(.299*e.data[t]+.587*e.data[t+1]+.114*e.data[t+2]),255,.72)}function ne(e,t,n){return Math.round(e*(1-n)+t*n)}function nt(e){return e.width*e.height}function nn(e){return Math.round(100*e*100)/100}async function nr(e,t){let n=await tS(e,{prefix:"agent-device-diff-current",ext:".png"});try{await ni(e,t,n.path,no(t))}catch(e){throw await n.cleanup(),e}return n}async function na(e,t,n,r,a){var i,o,s,l;if(!t.overlayRefs)return r;if(r.match||r.dimensionMismatch)return n&&await nl(n),r;let d=(i=t,o=n,i.currentOverlayOut?i.currentOverlayOut:i.out?.kind==="path"?{kind:"path",path:ns(o??i.out.path)}:i.out?.kind==="downloadableArtifact"?{kind:"downloadableArtifact",...i.out.clientPath?{clientPath:ns(i.out.clientPath)}:{},...i.out.fileName?{fileName:ns(i.out.fileName)}:{}}:void 0),u=await tx(e,d,{field:"currentOverlayPath",ext:".png"});try{let n=await ni(e,t,u.path,{overlayRefs:!0,...no(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:(s=r.regions,l=n.overlayRefs,s.map(e=>{var t,n;let r,a=(t=e,n=l,r=nt(t.rect),n.map(e=>{var n,a;let i,o,s,l,d=e.overlayRect,u=(n=t.rect,a=d,i=Math.max(n.x,a.x),o=Math.max(n.y,a.y),s=Math.min(n.x+n.width,a.x+a.width),l=Math.min(n.y+n.height,a.y+a.height),s<=i||l<=o?0:(s-i)*(l-o));return u<=0?null:{ref:e.ref,...e.label?{label:e.label}:{},rect:d,overlayCoveragePercentage:nn(u/nt(d)),regionCoveragePercentage:nn(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 ni(e,t,n,r={}){if(!e.backend.captureScreenshot)throw new y("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 no(e){return e.surface?{surface:e.surface}:{}}function ns(e){let t=o.extname(e),n=t?e.slice(0,-t.length):e;return`${n}.current-overlay${t||".png"}`}async function nl(e){try{await a.unlink(ns(e))}catch(e){var t;if(!("object"==typeof(t=e)&&null!==t&&"code"in t&&"ENOENT"===t.code))throw e}}function nd(e){return"live"===e.kind}function nu(e,t){let n=to(e.type??"Element"),r=ti(e,n),a=!1===e.enabled?"disabled":"enabled",i=!0===e.selected?"selected":"unselected",o=!0===e.hittable?"hittable":"not-hittable";return[String(t??e.depth??0),n,r,a,i,o].join("|")}function nc(e,t){return t.flatten?e.map(e=>({text:ta(e,0,!1),comparable:nu(e,0)})):tr(e).map(e=>({text:e.text,comparable:nu(e.node,e.depth)}))}function np(e,t){return e.get(t)??0}function nf(e){return"text"===e||"label"===e||"any"===e}function nh(e,t){return{session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata}}function nm(e){return e.clock?.now()??Date.now()}async function nw(e,t){e.clock?await e.clock.sleep(t):await new Promise(e=>setTimeout(e,t))}async function ng(e,t){var n,r,a,i,o;let s,l,d,u,c,p;if(!e.backend.captureSnapshot)throw new y("UNSUPPORTED_OPERATION","snapshot is not supported by this backend");let f=t.session??"default",h=await e.sessions.get(f),m=await e.backend.captureSnapshot({session:f,requestId:t.requestId,appId:h?.appId,appBundleId:h?.appBundleId,signal:t.signal??e.signal,metadata:t.metadata},{interactiveOnly:t.interactiveOnly,compact:t.compact,depth:t.depth,scope:t.scope,raw:t.raw}),w=(n=m,r=e,n.snapshot?n.snapshot:{nodes:n.nodes??[],truncated:n.truncated,backend:n.backend,createdAt:nm(r)}),g=nm(e);return{snapshot:w,result:m,session:h,warnings:(s=[...(a={result:m,snapshot:w,options:t,session:h,capturedAt:w.createdAt??g,runtimeNow:g}).result.warnings??[]],l=!0===a.options.interactiveOnly,d=a.result.analysis,"android"===a.snapshot.backend&&l&&0===a.snapshot.nodes.length&&d&&(d.rawNodeCount??0)>=12&&(s.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 a.options.depth&&"number"==typeof d.maxDepth&&d.maxDepth>=a.options.depth+2&&s.push(`Interactive output is empty at depth ${a.options.depth}; retry without -d.`)),c=!!(u=a.session?.snapshot)&&[a.capturedAt,a.runtimeNow].some(e=>{let t=e-u.createdAt;return t>=0&&t<=2e3}),!a.result.freshness&&u&&c&&(i=u.nodes.length,o=a.snapshot.nodes.length,!(i<12)&&o<=Math.floor(.2*i))&&s.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."),p=a.result.freshness,p?.staleAfterRetries&&"android"===a.snapshot.backend&&("stuck-route"===p.reason?s.push(`Recent ${p.action} was followed by a nearly identical snapshot after ${p.retryCount} automatic retr${1===p.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"===p.reason&&s.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(s)))}}function ny(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 nb(e){return["visible","hidden","exists","editable","selected","text"].includes(e)}function nv(e){return!!(e&&Number.isFinite(e.x)&&Number.isFinite(e.y)&&Number.isFinite(e.width)&&Number.isFinite(e.height)&&e.width>0&&e.height>0)}async function nI(e,t){let n=t??"default",r=await e.sessions.get(n);if(!r)throw new y("SESSION_NOT_FOUND","No active session. Run open first.");if(!r.snapshot)throw new y("INVALID_ARGS","No snapshot in session. Run snapshot first.");return{sessionName:n,session:r,snapshot:r.snapshot}}async function nA(e,t,n={updateSession:!0}){if(!e.backend.captureSnapshot)throw new y("UNSUPPORTED_OPERATION","snapshot is not supported by this backend");let r=t.session??"default",a=await e.sessions.get(r),i=await e.backend.captureSnapshot(nh(e,t),{interactiveOnly:!1,compact:!1,depth:t.depth,scope:n.scope??t.scope,raw:t.raw}),o=i.snapshot??{nodes:i.nodes??[],truncated:i.truncated,backend:i.backend,createdAt:nm(e)};return n.updateSession&&a&&await e.sessions.set({...a,snapshot:o}),{sessionName:r,session:a,snapshot:o}}async function nx(e,t,n){if(e.backend.readText){let r=await e.backend.readText(nh(e,{session:t.sessionName}),n);if(r.text.trim())return r.text}return T(n)}let nS=async(e,t)=>{if("ref"===t.target.kind){let n=await nI(e,t.session),r=function(e,t,n){let r=j(t);if(!r)throw new y("INVALID_ARGS",n.invalidRefMessage);let a=V(e,r)??(n.fallbackLabel.length>0?C(e,n.fallbackLabel):null);if(!a)throw new y("COMMAND_FAILED",n.notFoundMessage);return{ref:r,node:a}}(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`}),a=D(r.node,e.backend.platform,{action:"get"}),i={kind:"ref",ref:`@${r.ref}`};return"attrs"===t.property?{kind:"attrs",target:i,node:r.node,selectorChain:a}:{kind:"text",target:i,text:await nx(e,n,r.node),node:r.node,selectorChain:a}}let n=await nL(e,t,t.session??"default",{selector:t.target.selector,disambiguateAmbiguous:"text"===t.property}),r=D(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 a=await nx(e,n.capture,n.node);return{kind:"text",target:{kind:"selector",selector:n.selector},text:a,node:n.node,selectorChain:r}},nN=async(e,t)=>{let n=await nS(e,{...t,property:"text",target:t.target});if("text"!==n.kind)throw new y("COMMAND_FAILED","getText returned non-text result");return n},n_=async(e,t)=>{let n=await nS(e,{...t,property:"attrs",target:t.target});if("attrs"!==n.kind)throw new y("COMMAND_FAILED","getAttrs returned non-attrs result");return n},nk=async(e,t)=>{if(!nb(t.predicate))throw new y("INVALID_ARGS","is requires predicate: visible|hidden|exists|editable|selected|text");if("text"===t.predicate&&!t.expectedText)throw new y("INVALID_ARGS","is text requires expected text value");let n=await nA(e,t,{updateSession:!0}),r=x(t.selector);if("exists"===t.predicate){let a=L(n.snapshot.nodes,r,{platform:e.backend.platform});if(!a)throw new y("COMMAND_FAILED",U(r,[],{unique:!1}));return{predicate:t.predicate,pass:!0,selector:a.selector.raw,matches:a.matches,selectorChain:r.selectors.map(e=>e.raw)}}let a=$(n.snapshot.nodes,r,{platform:e.backend.platform,requireRect:!1,requireUnique:!0,disambiguateAmbiguous:!1});if(!a)throw new y("COMMAND_FAILED",U(r,[],{unique:!0}));let i=function(e){let{predicate:t,node:n,nodes:r,expectedText:a,platform:i}=e,o=I(n),s=N(n,i),l=!0===n.selected,d="text"===t?S(n):function(e,t){if(!0===e.hittable)return!0;if(nv(e.rect))return tw(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=F(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||nv(e.rect))}(e))return e;r=e}return null}(e,t);return!!n&&(!0===n.hittable||!!nv(n.rect)&&tw(n,t))}(n,r),u=!1;switch(t){case"visible":u=d;break;case"hidden":u=!d;break;case"editable":u=s;break;case"selected":u=l;break;case"text":u=o===(a??"")}let c="text"===t?`expected="${a??""}" actual="${o}"`:`actual=${JSON.stringify({visible:d,editable:s,selected:l})}`;return{pass:u,actualText:o,details:c}}({predicate:t.predicate,node:a.node,nodes:n.snapshot.nodes,expectedText:t.expectedText,platform:e.backend.platform});if(!i.pass)throw new y("COMMAND_FAILED",`is ${t.predicate} failed for selector ${a.selector.raw}: ${i.details}`);return{predicate:t.predicate,pass:!0,selector:a.selector.raw,..."text"===t.predicate?{text:i.actualText}:{},selectorChain:r.selectors.map(e=>e.raw)}},nM=async(e,t)=>await nk(e,{...t,predicate:"visible",selector:t.target.selector}),nD=async(e,t)=>await nk(e,{...t,predicate:"hidden",selector:t.target.selector}),nE=async(e,t)=>{if("sleep"===t.target.kind)return await nw(e,t.target.durationMs),{kind:"sleep",waitedMs:t.target.durationMs};if("ref"===t.target.kind){let n=await nI(e,t.session),r=j(t.target.ref);if(!r)throw new y("INVALID_ARGS",`Invalid ref: ${t.target.ref}`);let a=V(n.snapshot.nodes,r),i=a?R(a,n.snapshot.nodes):void 0;if(!i)throw new y("COMMAND_FAILED",`Ref ${t.target.ref} not found or has no label`);return await nP(e,t,i,t.target.timeoutMs)}if("selector"===t.target.kind)return await nR(e,t,t.target.selector,t.target.timeoutMs);if(!t.target.text)throw new y("INVALID_ARGS","wait requires text");return await nP(e,t,t.target.text,t.target.timeoutMs)},nO=async(e,t)=>{let n=await nE(e,{...t,target:{kind:"text",text:t.text,timeoutMs:t.timeoutMs}});if("text"!==n.kind)throw new y("COMMAND_FAILED","waitForText returned non-text result");return n};async function nC(e,t,n){let r=t.timeoutMs??1e4,a=nm(e);for(;nm(e)-a<r;){if(ep((await nA(e,t,{updateSession:!0,scope:nf(n)?t.query:void 0})).snapshot.nodes,n,t.query,{requireRect:!1}).matches[0])return{kind:"found",found:!0,waitedMs:nm(e)-a};await nw(e,300)}throw new y("COMMAND_FAILED","find wait timed out")}async function nR(e,t,n,r){let a=r??1e4,i=nm(e),o=x(n);for(;nm(e)-i<a;){let n=L((await nA(e,t,{updateSession:!0})).snapshot.nodes,o,{platform:e.backend.platform});if(n)return{kind:"selector",selector:n.selector.raw,waitedMs:nm(e)-i};await nw(e,300)}throw new y("COMMAND_FAILED",`wait timed out for selector: ${n}`)}async function nP(e,t,n,r){let a=r??1e4,i=nm(e);for(;nm(e)-i<a;){if(e.backend.findText?(await e.backend.findText(nh(e,t),n)).found:await nT(e,t,n))return{kind:"text",text:n,waitedMs:nm(e)-i};await nw(e,300)}throw new y("COMMAND_FAILED",`wait timed out for text: ${n}`)}async function nT(e,t,n){return!!C((await nA(e,t,{updateSession:!0})).snapshot.nodes,n)}async function nL(e,t,n,r){let a=await nA(e,{...t,session:n},{updateSession:!0}),i=x(r.selector),o=$(a.snapshot.nodes,i,{platform:e.backend.platform,requireRect:!1,requireUnique:!0,disambiguateAmbiguous:r.disambiguateAmbiguous});if(!o)throw new y("COMMAND_FAILED",U(i,[],{unique:!0}));return{capture:a,node:o.node,selector:o.selector.raw,ref:`@${o.node.ref}`}}function n$(e,t,n,r){if(!Number.isFinite(e)||!Number.isInteger(e)||e<n||e>r)throw new y("INVALID_ARGS",`${t} must be an integer between ${n} and ${r}`);return e}function nF(e){let t=nU(e);if(!t)return null;let n=B(t);return Number.isFinite(n.x)&&Number.isFinite(n.y)?n:null}function nU(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 nG(e,t){let n=function(e,t){let n=nU(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=nU(e.rect);return!!t&&nV(t,n)});if(1!==t.length)break;r=t[0]}return r===t?null:r}(e,t);if(n?.rect&&nF(n.rect))return n;let r=M(e,t);return r?.rect&&nF(r.rect)?!function(e,t,n){var r,a,i,o;let s,l,d,u=nU(e.rect),c=nU(t.rect);if(!u||!c)return!1;let p=function(e,t){let n=B(t),r=e.filter(e=>{let t=(e.type??"").toLowerCase();return t.includes("application")||t.includes("window")}).map(e=>nU(e.rect)).filter(e=>null!==e);if(0===r.length)return null;let a=r.filter(e=>tc(e,n.x,n.y));return tp(a.length>0?a:r)}(n,u);return!!p&&(r=c,a=p,s=(i=r,o=a,Math.max(0,Math.min(i.x+i.width,o.x+o.width)-Math.max(i.x,o.x))*Math.max(0,Math.min(i.y+i.height,o.y+o.height)-Math.max(i.y,o.y))),l=r.width*r.height,d=a.width*a.height,!(s<=0)&&!(l<=0)&&!(d<=0)&&!!(s/d>=.9)&&!!(s/l>=.8))&&!nV(u,c)}(t,r,e)?r:t:t}function nV(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 nB(e,t,n){if(await nq(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 nH(e,t,t.target),a=r.resolved,i=n.promoteToHittableAncestor?nG(r.snapshot.nodes,a.node):a.node;return function(e,t,n,r){let a=e.rect?tg(e,t):null;if(!(!e.rect||!a||tw(e,t)))throw new y("COMMAND_FAILED",`Ref ${n} is off-screen and not safe to ${r}`,{reason:"offscreen_ref",ref:j(n),rect:e.rect,viewport:a,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.`})}(i,r.snapshot.nodes,t.target.ref,n.action),{kind:"ref",point:nz(i,`Ref ${t.target.ref} not found or has invalid bounds`),target:{kind:"ref",ref:`@${a.ref}`},node:i,selectorChain:D(i,e.backend.platform,{action:"fill"===n.action?"fill":"click"}),refLabel:R(i,r.snapshot.nodes)}}let r=await nj(e,t,n.requireInteractive),a=x(t.target.selector),i=$(r.snapshot.nodes,a,{platform:e.backend.platform,requireRect:!0,requireUnique:!0,disambiguateAmbiguous:!0});if(!i||!i.node.rect)throw new y("COMMAND_FAILED",U(a,i?.diagnostics??[],{unique:!0}));let o=n.promoteToHittableAncestor?nG(r.snapshot.nodes,i.node):i.node;return{kind:"selector",point:nz(o,`Selector ${i.selector.raw} resolved to invalid bounds`),target:{kind:"selector",selector:i.selector.raw},node:o,selectorChain:D(o,e.backend.platform,{action:"fill"===n.action?"fill":"click"}),refLabel:R(o,r.snapshot.nodes)}}async function nj(e,t,n){if(!e.backend.captureSnapshot)throw new y("UNSUPPORTED_OPERATION","snapshot is not supported by this backend");let r=t.session??"default",a=await e.sessions.get(r);if(!a)throw new y("SESSION_NOT_FOUND","No active session. Run open first.");let i=await e.backend.captureSnapshot(nh(e,t),{interactiveOnly:n,compact:n}),o=i.snapshot??{nodes:i.nodes??[],truncated:i.truncated,backend:i.backend,createdAt:nm(e)};return await e.sessions.set({...a,snapshot:o}),{snapshot:o}}async function nq(e,t,n){if("macos"!==e.backend.platform)return;let r=await nX(e,t);if(("desktop"===r||"menubar"===r)&&("menubar"!==r||"click"!==n&&"press"!==n))throw new y("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 nX(e,t){let n=await e.sessions.get(t.session??"default");return n?.metadata?.surface}async function nH(e,t,n){let r=t.session??"default",a=await e.sessions.get(r);if(!a)throw new y("SESSION_NOT_FOUND","No active session. Run open first.");if(!a.snapshot)throw new y("INVALID_ARGS","No snapshot in session. Run snapshot first.");let i=n.fallbackLabel??"",o=nK(a.snapshot.nodes,n.ref,{fallbackLabel:i,requireRect:!0});if(o)return{snapshot:a.snapshot,resolved:o};let s=await nj(e,t,!0),l=nK(s.snapshot.nodes,n.ref,{fallbackLabel:i,requireRect:!0});if(!l)throw new y("COMMAND_FAILED",`Ref ${n.ref} not found or has no bounds`);return{...s,resolved:l}}function nK(e,t,n){let r=j(t);if(!r)throw new y("INVALID_ARGS",`Invalid ref: ${t}`);let a=V(e,r);if(nY(a,n.requireRect))return{ref:r,node:a};let i=n.fallbackLabel.length>0?C(e,n.fallbackLabel):null;return nY(i,n.requireRect)?{ref:r,node:i}:null}function nz(e,t){if(!e.rect)throw new y("COMMAND_FAILED",t);let n=B(e.rect);if(!Number.isFinite(n.x)||!Number.isFinite(n.y))throw new y("COMMAND_FAILED",t);return n}function nY(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 o=B(e.rect);return Number.isFinite(o.x)&&Number.isFinite(o.y)}async function nW(e,t){let n=t.target??{kind:"viewport"};return"viewport"===n.kind?(await nq(e,t,"scroll"),{kind:"viewport"}):await nB(e,{...t,target:n},{action:"scroll",requireInteractive:!1,promoteToHittableAncestor:!1})}async function nJ(e,t){if(t.from){var n;if("x"in(n=t.from)&&"y"in n)return await nq(e,t,"swipe"),{point:nQ(t.from,"from")};let r=await nB(e,{...t,target:t.from},{action:"swipe",requireInteractive:!1,promoteToHittableAncestor:!1});return{point:r.point,target:r}}if(!t.direction)throw new y("INVALID_ARGS","swipe requires from+to or a direction");return await nq(e,t,"swipe"),{point:B(function(e){let t=e.filter(t=>tw(t,e)).map(e=>e.rect).filter(n1),n=t.length>0?t:e.map(e=>e.rect).filter(n1);if(0===n.length)throw new y("COMMAND_FAILED","Cannot infer viewport for directional swipe");let r=Math.min(...n.map(e=>e.x)),a=Math.min(...n.map(e=>e.y));return{x:r,y:a,width:Math.max(...n.map(e=>e.x+e.width))-r,height:Math.max(...n.map(e=>e.y+e.height))-a}}((await nj(e,t,!1)).snapshot.nodes)),target:{kind:"viewport"}}}function nZ(e,t){switch(e){case"up":case"down":case"left":case"right":return e;default:throw new y("INVALID_ARGS",`${t} must be up, down, left, or right`)}}function nQ(e,t){let n=Number(e.x),r=Number(e.y);if(!Number.isFinite(n)||!Number.isFinite(r))throw new y("INVALID_ARGS",`${t} point requires finite x and y`);return{x:n,y:r}}function n0(e,t){if(!Number.isFinite(e)||e<=0)throw new y("INVALID_ARGS",`${t} must be a positive number`);return e}function n1(e){return!!(e&&e.width>0&&e.height>0)}function n2(e){return e&&"object"==typeof e?e:void 0}async function n3(e,t,n){let r=await nB(e,t,{action:n,requireInteractive:!0,promoteToHittableAncestor:!0});if(!e.backend.tap)throw new y("UNSUPPORTED_OPERATION","tap is not supported by this backend");let a=n5(await e.backend.tap(nh(e,t),r.point,{button:t.button,count:t.count,intervalMs:t.intervalMs,holdMs:t.holdMs,jitterPx:t.jitterPx,doubleTap:t.doubleTap}));return{...r,...a?{backendResult:a}:{}}}function n5(e){return e&&"object"==typeof e?e:void 0}function n4(e){return!!(e&&"object"==typeof e)}function n8(e){return e&&"object"==typeof e?e:void 0}let n6=/^[A-Za-z0-9_.:-]{1,64}$/;function n9(e,t){if(void 0!==e)return n7(e,t)}function n7(e,t){let n=e?.trim();if(!n)throw new y("INVALID_ARGS",`${t} must be a non-empty string`);return n}async function re(e,t){if(!t||"object"!=typeof t)throw new y("INVALID_ARGS","apps.push requires an input");if("json"===t.kind)return rt(t.payload,"apps.push JSON payload",8192),{backendInput:{kind:"json",payload:t.payload},inputKind:"json"};let n=await tA(e,t,{usage:"apps.push",field:"input"});return{backendInput:{kind:"file",path:n.path},inputKind:"file",...n.cleanup?{cleanup:n.cleanup}:{}}}function rt(e,t,n){if(function(e,t){if(!e||"object"!=typeof e||Array.isArray(e))throw new y("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 y("INVALID_ARGS",`${t} must be JSON-serializable`);return n}catch{throw new y("INVALID_ARGS",`${t} must be JSON-serializable`)}}(e,t),"utf8")>n)throw new y("INVALID_ARGS",`${t} exceeds ${n} bytes`)}function rn(e,t){return{session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata}}function rr(e){return e&&"object"==typeof e?e:void 0}async function ra(e,t,n){let r="reinstall"===n?"reinstallApp":"installApp",a=e.backend[r];if(!a)throw new y("UNSUPPORTED_OPERATION",`admin.${n} is not supported by this backend`);let i="app"in t&&void 0!==t.app?rd(t.app,"app"):void 0;if("installFromSource"!==n&&!i)throw new y("INVALID_ARGS",`admin.${n} requires app`);let o=nh(e,t),s=await ri(e,o,t.source);try{var l,d,u,c,p;let t,r,f,h,m,w,g,y,b=await a.call(e.backend,o,{...i?{app:i}:{},source:s.source});return l=n,d=i,u=s.source,c=b,t=rc(c),r=ru(c,"appName"),f=ru(c,"appId"),h=ru(c,"bundleId"),m=ru(c,"packageName"),w=ru(c,"launchTarget"),g=ru(c,"installablePath"),y=ru(c,"archivePath"),{kind:"reinstall"===l?"appReinstalled":"installFromSource"===l?"appInstalledFromSource":"appInstalled",...d?{app:d}:{},source:u,...f?{appId:f}:{},...r?{appName:r}:{},...h?{bundleId:h}:{},...m?{packageName:m}:{},...w?{launchTarget:w}:{},...g?{installablePath:g}:{},...y?{archivePath:y}:{},...t?{backendResult:t}:{},...ea(`${"reinstall"===l?"Reinstalled":"Installed"}: ${r??w??d??(p=u,"path"===p.kind?p.path:"uploadedArtifact"===p.kind?p.id:p.url)}`)}}finally{await s.cleanup?.()}}async function ri(e,t,n){let r=rs(n),a=await ro(e,r);try{let n=e.backend.resolveInstallSource?await e.backend.resolveInstallSource(t,a.source):a.source;return{source:rs(n),...a.cleanup?{cleanup:a.cleanup}:{}}}catch(e){if(a.cleanup)try{await a.cleanup()}catch{}throw e}}async function ro(e,t){if("url"===t.kind)return{source:t};let n=await tA(e,t,{usage:"admin.install",field:"source"});return{source:{kind:"path",path:n.path},...n.cleanup?{cleanup:n.cleanup}:{}}}function rs(e){if(!e||"object"!=typeof e)throw new y("INVALID_ARGS","install source is required");if("path"===e.kind)return{kind:"path",path:rd(e.path,"source.path")};if("uploadedArtifact"===e.kind)return{kind:"uploadedArtifact",id:rd(e.id,"source.id")};if("url"===e.kind){let t=rd(e.url,"source.url");return function(e){let t;try{t=new URL(e)}catch{throw new y("INVALID_ARGS",`Invalid install source URL: ${e}`)}if("http:"!==t.protocol&&"https:"!==t.protocol)throw new y("INVALID_ARGS","Install source URL must use http or https")}(t),{kind:"url",url:t}}throw new y("INVALID_ARGS","install source kind must be path, uploadedArtifact, or url")}function rl(e,t){if(void 0!==e)return rd(e,t)}function rd(e,t){let n=e?.trim();if(!n)throw new y("INVALID_ARGS",`${t} must be a non-empty string`);return n}function ru(e,t){let n=e[t];return"string"==typeof n&&n.length>0?n:void 0}function rc(e){return e&&"object"==typeof e?e:void 0}function rp(e,t){if("start"===e||"stop"===e)return e;throw new y("INVALID_ARGS",`${t} action must be start or stop`)}function rf(e,t,n,r){return{kind:"start"===e?r.startKind:r.stopKind,action:e,...n?{artifact:n}:{},backendResult:t,...ea("start"===e?r.startMessage:r.stopMessage)}}let rh=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i,rm=/\b[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\b/g;function rw(e){var t,n;let r=!1,a=e;return{value:(t=a=(a=(a=(a=(a=a.replaceAll(/(authorization|token|secret|password|passwd|api[-_]?key)=([^&\s]+)/gi,(e,t)=>(r=!0,`${String(t)}=[REDACTED]`))).replaceAll(/("(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)"\s*:\s*")([^"]*)(")/gi,(e,t,n,a)=>(r=!0,`${String(t)}[REDACTED]${String(a)}`))).replaceAll(/\b(Bearer\s+)([^\s",;]+)/gi,(e,t)=>(r=!0,`${String(t)}[REDACTED]`))).replaceAll(/((?:authorization|cookie|token|secret|password|passwd|api[-_]?key)\s*[:=]\s*)([^\s,;&]+)/gi,(e,t)=>(r=!0,`${String(t)}[REDACTED]`))).replaceAll(rm,()=>(r=!0,"[REDACTED]")),n=()=>{r=!0},a=/(https?:\/\/|token|secret|password|authorization|cookie|api[-_]?key)/i.test(t)?t.replaceAll(/https?:\/\/[^\s"'<>)]+/gi,e=>{let t=rg(e);return t?(t.redacted&&n(),t.value):e}):t),redacted:r}}function rg(e){try{let t=new URL(e),n=function(e){let t=!1;for(let n of Array.from(e.searchParams.keys()))rh.test(n)&&(e.searchParams.set(n,"[REDACTED]"),t=!0);return t}(t);return(t.username||t.password)&&(t.username="REDACTED",t.password="REDACTED",n=!0),{value:t.toString(),redacted:n}}catch{return}}let ry=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i;function rb(e){if(!e)return{redacted:!1};let t=!1,n={};for(let[r,a]of Object.entries(e))if(ry.test(r))n[r]="[REDACTED]",t=!0;else{let e=rx(a,2048);n[r]=e.value??"",t||=e.redacted}return{value:n,redacted:t}}function rv(e){return void 0===e?{redacted:!1}:function(e){try{let t=JSON.parse(e),n=rA(t,rw);return rS(JSON.stringify(n.value),2048,n.redacted)}catch{return}}(e)??rx(e,2048)}function rI(e){return rA(e,e=>rx(e,2048))}function rA(e,t){if(void 0===e)return{redacted:!1};if("string"==typeof e)return t(e);if(!e||"object"!=typeof e)return{value:e,redacted:!1};if(Array.isArray(e)){let n=!1;return{value:e.map(e=>{let r=rA(e,t);return n||=r.redacted,r.value}),redacted:n}}let n=!1,r={};for(let[a,i]of Object.entries(e)){if(ry.test(a)){r[a]="[REDACTED]",n=!0;continue}let e=rA(i,t);r[a]=e.value,n||=e.redacted}return{value:r,redacted:n}}function rx(e,t){if(void 0===e)return{redacted:!1};let n=rw(e);return rS(n.value,t,n.redacted)}function rS(e,t,n){if(void 0===e)return{redacted:n};let r=e;return r.length>t&&(r=`${r.slice(0,t)}...[truncated]`,n=!0),{value:r,redacted:n}}async function rN(e,t){let n=nh(e,t),r=t.session?await e.sessions.get(t.session):void 0;return{...n,...t.appId??r?.appId?{appId:t.appId??r?.appId}:{},...t.appBundleId??r?.appBundleId?{appBundleId:t.appBundleId??r?.appBundleId}:{}}}function r_(e,t,n,r){return{...rk(e),...void 0!==e.cursor?{cursor:rD(e.cursor,"cursor")}:{},limit:void 0===e.limit?t:n$(e.limit,r,1,n)}}function rk(e){return{...void 0!==e.since?{since:rD(e.since,"since")}:{},...void 0!==e.until?{until:rD(e.until,"until")}:{}}}function rM(e,t,n=50){if(!Array.isArray(e))throw new y("INVALID_ARGS",`${t} must be an array of strings`);if(e.length>n)throw new y("INVALID_ARGS",`${t} must contain at most ${n} entries`);return e.map((e,n)=>rD(e,`${t}[${n}]`))}function rD(e,t){let n=e.trim();if(!n)throw new y("INVALID_ARGS",`${t} must be a non-empty string`);return n}let rE=async(e,t)=>{let n;if(!e.backend.captureScreenshot)throw new y("UNSUPPORTED_OPERATION","screenshot is not supported by this backend");let r=await tx(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}),void 0!==t.maxSize&&await tI(r.path,t.maxSize),n=await r.publish()}catch(e){throw await r.cleanup?.(),e}return{path:r.path,...n?{artifacts:[n]}:{},...ea(`Saved screenshot: ${r.path}`)}},rO=async(e,t)=>{let n,r,a;if(!t.baseline)throw new y("INVALID_ARGS","diff screenshot requires a baseline image");let i=function(e){if(null==e||""===e)return .1;let t=Number(e);if(Number.isNaN(t)||t<0||t>1)throw new y("INVALID_ARGS","--threshold must be a number between 0 and 1");return t}(t.threshold),o=t.current??{kind:"live"};if(t.overlayRefs&&!nd(o))throw new y("INVALID_ARGS","diff screenshot <current.png> cannot use --overlay-refs because saved-image comparisons have no live accessibility refs");let s=await tA(e,t.baseline,{usage:"diff screenshot baseline",field:"baseline"}),l=[];try{let d;d=nd(o)?(r=await nr(e,t)).path:(n=await tA(e,o,{usage:"diff screenshot current",field:"current"})).path,a=t.out?await tx(e,t.out,{field:"diffPath",ext:".png"}):void 0;let u=await t4(s.path,d,{threshold:i,outputPath:a?.path,maxPixels:e.policy.maxImagePixels});nd(o)&&(u=await na(e,t,a?.path,u,l));let c=u.diffPath?await a?.publish():void 0;return c&&l.push(c),u.diffPath||await a?.cleanup?.(),{...u,...l.length>0?{artifacts:l}:{}}}catch(e){throw await a?.cleanup?.(),e}finally{await s.cleanup?.(),await n?.cleanup?.(),await r?.cleanup?.()}},rC=async(e,t)=>{var n;let r,a,i=await ng(e,t);return await e.sessions.set(ny(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=th(n),o=new Set;return i.hiddenCount>0&&o.add("offscreen-nodes"),i.nodes.some(e=>e.hiddenContentAbove)&&o.add("scroll-hidden-above"),i.nodes.some(e=>e.hiddenContentBelow)&&o.add("scroll-hidden-below"),{partial:o.size>0,visibleNodeCount:i.nodes.length,totalNodeCount:n.length,reasons:[...o]}}({nodes:i.snapshot.nodes,backend:i.snapshot.backend,snapshotRaw:t.raw}),...i.result.androidSnapshot?{androidSnapshot:i.result.androidSnapshot}:{},...i.warnings.length>0?{warnings:i.warnings}:{},...(r=(n=i).result.appName??n.session?.appName,a=n.result.appBundleId??n.session?.appBundleId,{...r||a?{appName:r??a}:{},...a?{appBundleId:a}:{}})}},rR=async(e,t)=>{let n=await ng(e,t),r=!0===t.interactiveOnly,a=n.session?.snapshot,i=ny(t.session,n);if(!a){let t=function(e,t={}){return nc(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 o=function(e,t,n={}){let r=function(e,t){let n=e.length,r=t.length,a=n+r,i=new Map,o=[];i.set(1,0);for(let s=0;s<=a;s+=1){o.push(new Map(i));for(let a=-s;a<=s;a+=2){let l=a===-s||a!==s&&np(i,a-1)<np(i,a+1)?np(i,a+1):np(i,a-1)+1,d=l-a;for(;l<n&&d<r&&e[l].comparable===t[d].comparable;)l+=1,d+=1;if(i.set(a,l),l>=n&&d>=r)return function(e,t,n,r,a){let i=[],o=r,s=a;for(let r=e.length-1;r>=0;r-=1){let a=e[r],l=o-s,d=l===-r||l!==r&&np(a,l-1)<np(a,l+1)?l+1:l-1,u=np(a,d),c=u-d;for(;o>u&&s>c;)i.push({kind:"unchanged",text:n[s-1].text}),o-=1,s-=1;if(0===r)break;o===u?(i.push({kind:"added",text:n[c].text}),s=c):(i.push({kind:"removed",text:t[u].text}),o=u)}return i.reverse(),i}(o,e,t,n,r)}}return[]}(nc(e,n),nc(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:o.summary,lines:o.lines,...n.warnings.length>0?{warnings:n.warnings}:{}}},rP=async(e,t)=>{let n=t.locator??"any";if(!t.query)throw new y("INVALID_ARGS","find requires a value");if("wait"===t.action)return await nC(e,t,n);let r=await nA(e,t,{updateSession:!0,scope:nf(n)?t.query:void 0}),a=ep(r.snapshot.nodes,n,t.query,{requireRect:!1}).matches[0];if(!a)throw new y("COMMAND_FAILED","find did not match any element");if("exists"===t.action)return{kind:"found",found:!0};let i=`@${a.ref}`;return"get_attrs"===t.action?{kind:"attrs",ref:i,node:a}:{kind:"text",ref:i,text:await nx(e,r,a),node:a}},rT=nS,rL=nN,r$=n_,rF=nk,rU=nM,rG=nD,rV=nE,rB=nO,rj=async(e,t)=>await n3(e,t,"click"),rq=async(e,t)=>await n3(e,t,"press"),rX=async(e,t)=>{var n;if(!t.text)throw new y("INVALID_ARGS","fill requires text");let r=await nB(e,t,{action:"fill",requireInteractive:!0,promoteToHittableAncestor:!1});if(!e.backend.fill)throw new y("UNSUPPORTED_OPERATION","fill is not supported by this backend");let a=n5(await e.backend.fill(nh(e,t),r.point,t.text,{delayMs:t.delayMs})),i="node"in r?r.node.type??"":"",o=i&&!G(i,e.backend.platform)?`fill target ${n=r,n.target?.kind==="ref"?n.target.ref:n.target?.kind==="selector"?n.target.selector:"point"} resolved to "${i}", attempting fill anyway.`:void 0;return{...r,text:t.text,...o?{warning:o}:{},...a?{backendResult:a}:{}}},rH=async(e,t)=>{let n=t.text;if(!n)throw new y("INVALID_ARGS","type requires text");let r=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(r)throw new y("INVALID_ARGS",`type does not accept a target ref like "${r}"`,{hint:`Use fill ${r} "text" to target that field, or press ${r} then type "text" to append.`});if(!e.backend.typeText)throw new y("UNSUPPORTED_OPERATION","type is not supported by this backend");let a=n$(t.delayMs??0,"delay-ms",0,1e4),i=n5(await e.backend.typeText(nh(e,t),n,{delayMs:a}));return{kind:"text",text:n,delayMs:a,...i?{backendResult:i}:{},...ea(`Typed ${Array.from(n).length} chars`)}},rK=async(e,t)=>{let n=await nB(e,t,{action:"focus",requireInteractive:!0,promoteToHittableAncestor:!1});if(!e.backend.focus)throw new y("UNSUPPORTED_OPERATION","focus is not supported by this backend");let r=n2(await e.backend.focus(nh(e,t),n.point));return{...n,...r?{backendResult:r}:{},...ea(`Focused (${n.point.x}, ${n.point.y})`)}},rz=async(e,t)=>{let n=await nB(e,t,{action:"longPress",requireInteractive:!0,promoteToHittableAncestor:!0});if(!e.backend.longPress)throw new y("UNSUPPORTED_OPERATION","longPress is not supported by this backend");let r=void 0===t.durationMs?void 0:n$(t.durationMs,"durationMs",0,12e4),a=n2(await e.backend.longPress(nh(e,t),n.point,{durationMs:r}));return{...n,...void 0!==r?{durationMs:r}:{},...a?{backendResult:a}:{},...ea(`Long pressed (${n.point.x}, ${n.point.y})`)}},rY=async(e,t)=>{if(!e.backend.swipe)throw new y("UNSUPPORTED_OPERATION","swipe is not supported by this backend");let n=await nJ(e,t),r=function(e,t){if(t.to)return{point:nQ(t.to,"to")};let n=nZ(t.direction,"swipe direction"),r=n0(t.distance??200,"swipe distance");switch(n){case"up":return{point:{x:e.x,y:e.y-r},direction:n,distance:r};case"down":return{point:{x:e.x,y:e.y+r},direction:n,distance:r};case"left":return{point:{x:e.x-r,y:e.y},direction:n,distance:r};case"right":return{point:{x:e.x+r,y:e.y},direction:n,distance:r}}}(n.point,t),a=void 0===t.durationMs?void 0:n$(t.durationMs,"durationMs",16,1e4),i=n2(await e.backend.swipe(nh(e,t),n.point,r.point,{durationMs:a}));return{kind:"swipe",from:n.point,to:r.point,...r.direction?{direction:r.direction}:{},...void 0!==r.distance?{distance:r.distance}:{},...void 0!==a?{durationMs:a}:{},...n.target?{fromTarget:n.target}:{},...i?{backendResult:i}:{},...ea("Swiped")}},rW=async(e,t)=>{var n,r;if(!e.backend.scroll)throw new y("UNSUPPORTED_OPERATION","scroll is not supported by this backend");let a=nZ(t.direction,"scroll direction"),i=(n=t.amount,r="scroll amount",void 0===n?void 0:n0(n,r)),o=function(e,t){if(void 0!==e){if(!Number.isFinite(e)||!Number.isInteger(e)||e<=0)throw new y("INVALID_ARGS",`${t} must be a positive integer`);return e}}(t.pixels,"scroll pixels");if(void 0!==i&&void 0!==o)throw new y("INVALID_ARGS","scroll accepts either amount or pixels, not both");let s=await nW(e,t),l="viewport"===s.kind?{kind:"viewport"}:{kind:"point",point:s.point},d=n2(await e.backend.scroll(nh(e,t),l,{direction:a,...void 0!==i?{amount:i}:{},...void 0!==o?{pixels:o}:{}}));return{...s,direction:a,...void 0!==i?{amount:i}:{},...void 0!==o?{pixels:o}:{},...d?{backendResult:d}:{},...ea(void 0!==o?`Scrolled ${a} by ${o}px`:void 0!==i?`Scrolled ${a} by ${i}`:`Scrolled ${a}`)}},rJ=async(e,t)=>{if(!e.backend.pinch)throw new y("UNSUPPORTED_OPERATION","pinch is not supported by this backend");await nq(e,t,"pinch");let n=n0(t.scale,"pinch scale"),r=t.center?await nB(e,{...t,target:t.center},{action:"pinch",requireInteractive:!1,promoteToHittableAncestor:!1}):void 0,a=n2(await e.backend.pinch(nh(e,t),{scale:n,...r?{center:r.point}:{}}));return{kind:"pinch",scale:n,...r?{center:r.point,centerTarget:r}:{},...a?{backendResult:a}:{},...ea(`Pinched to scale ${n}`)}},rZ=async(e,t={})=>{if(!e.backend.pressBack)throw new y("UNSUPPORTED_OPERATION","system.back is not supported by this backend");let n=t.mode??"in-app";if("in-app"!==n&&"system"!==n)throw new y("INVALID_ARGS","system.back mode must be in-app or system");let r=n8(await e.backend.pressBack(nh(e,t),{mode:n}));return{kind:"systemBack",mode:n,...r?{backendResult:r}:{},...ea("Back")}},rQ=async(e,t={})=>{if(!e.backend.pressHome)throw new y("UNSUPPORTED_OPERATION","system.home is not supported by this backend");let n=n8(await e.backend.pressHome(nh(e,t)));return{kind:"systemHome",...n?{backendResult:n}:{},...ea("Home")}},r0=async(e,t)=>{if(!e.backend.rotate)throw new y("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 y("INVALID_ARGS","system.rotate orientation must be portrait, portrait-upside-down, landscape-left, or landscape-right")}}(t.orientation),r=n8(await e.backend.rotate(nh(e,t),n));return{kind:"systemRotated",orientation:n,...r?{backendResult:r}:{},...ea(`Rotated to ${n}`)}},r1=async(e,t={})=>{if(!e.backend.setKeyboard)throw new y("UNSUPPORTED_OPERATION","system.keyboard is not supported by this backend");let n=t.action??"status";if("status"!==n&&"get"!==n&&"dismiss"!==n)throw new y("INVALID_ARGS","system.keyboard action must be status, get, or dismiss");let r=await e.backend.setKeyboard(nh(e,t),{action:n}),a=n8(r);if("dismiss"===n){let e=n4(r)?r.dismissed:void 0;return{kind:"keyboardDismissed",action:n,state:n4(r)?r:{},...a?{backendResult:a}:{},...ea(!1===e?"Keyboard already hidden":"Keyboard dismissed")}}return{kind:"keyboardState",action:n,state:n4(r)?r:{},...a?{backendResult:a}:{}}},r2=async(e,t)=>{if("read"===t.action){if(!e.backend.getClipboard)throw new y("UNSUPPORTED_OPERATION","system.clipboard read is not supported by this backend");let n=await e.backend.getClipboard(nh(e,t));return{kind:"clipboardText",action:"read",text:"string"==typeof n?n:n.text}}if("write"!==t.action)throw new y("INVALID_ARGS","system.clipboard action must be read or write");if(!e.backend.setClipboard)throw new y("UNSUPPORTED_OPERATION","system.clipboard write is not supported by this backend");if("string"!=typeof t.text)throw new y("INVALID_ARGS","system.clipboard write requires text");let n=n8(await e.backend.setClipboard(nh(e,t),t.text));return{kind:"clipboardUpdated",action:"write",textLength:Array.from(t.text).length,...n?{backendResult:n}:{},...ea("Clipboard updated")}},r3=async(e,t={})=>{if(!e.backend.openSettings)throw new y("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 y("INVALID_ARGS",`${t} must be a non-empty string`);return n}(t.target,"target"),r=n8(await e.backend.openSettings(nh(e,t),n));return{kind:"settingsOpened",...n?{target:n}:{},...r?{backendResult:r}:{},...ea(n?`Opened settings: ${n}`:"Opened settings")}},r5=async(e,t={})=>{if(!e.backend.handleAlert)throw new y("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 y("INVALID_ARGS","system.alert action must be get, accept, dismiss, or wait");let r=void 0===t.timeoutMs?void 0:n$(t.timeoutMs,"timeoutMs",0,12e4),a=await e.backend.handleAlert(nh(e,t),n,{timeoutMs:r});var i=n,o=a;if("get"===i){if("alertStatus"!==o.kind)throw new y("COMMAND_FAILED","system.alert get returned an invalid backend result");return{kind:"alertStatus",action:i,alert:o.alert}}if("wait"===i){if("alertWait"!==o.kind)throw new y("COMMAND_FAILED","system.alert wait returned an invalid backend result");return{kind:"alertWait",action:i,alert:o.alert,...void 0!==o.waitedMs?{waitedMs:o.waitedMs}:{},...void 0!==o.timedOut?{timedOut:o.timedOut}:{},...ea(o.alert?"Alert visible":"Alert wait timed out")}}if("alertHandled"!==o.kind)throw new y("COMMAND_FAILED",`system.alert ${i} returned an invalid backend result`);return{kind:"alertHandled",action:i,handled:o.handled,...o.alert?{alert:o.alert}:{},...o.button?{button:o.button}:{},...ea(o.handled?`Alert ${i}ed`:"No alert handled")}},r4=async(e,t={})=>{if(!e.backend.openAppSwitcher)throw new y("UNSUPPORTED_OPERATION","system.appSwitcher is not supported by this backend");let n=n8(await e.backend.openAppSwitcher(nh(e,t)));return{kind:"appSwitcherOpened",...n?{backendResult:n}:{},...ea("Opened app switcher")}},r8=async(e,t)=>{var n;if(!e.backend.openApp)throw new y("UNSUPPORTED_OPERATION","apps.open is not supported by this backend");let r=function(e){var t;let n=n9(e.app,"app"),r=n9(e.appId,"appId"),a=n9(e.bundleId,"bundleId"),i=n9(e.packageName,"packageName"),o=n9(e.url,"url"),s=n9(e.activity,"activity"),l={...n?{app:n}:{},...r?{appId:r}:{},...a?{bundleId:a}:{},...i?{packageName:i}:{},...o?{url:o}:{},...s?{activity:s}:{}};if(!((t=l).app??t.appId??t.bundleId??t.packageName??t.url??t.activity))throw new y("INVALID_ARGS","apps.open requires app, appId, bundleId, packageName, url, or activity");return l}(t),a=rr(await e.backend.openApp(rn(e,t),r,{relaunch:t.relaunch}));return{kind:"appOpened",target:r,relaunch:!0===t.relaunch,...a?{backendResult:a}:{},...ea(`Opened: ${(n=r).app??n.appId??n.bundleId??n.packageName??n.url??n.activity??"app"}`)}},r6=async(e,t={})=>{if(!e.backend.closeApp)throw new y("UNSUPPORTED_OPERATION","apps.close is not supported by this backend");let n=n9(t.app,"app"),r=rr(await e.backend.closeApp(rn(e,t),n));return{kind:"appClosed",...n?{app:n}:{},...r?{backendResult:r}:{},...ea(n?`Closed: ${n}`:"Closed app")}},r9=async(e,t={})=>{if(!e.backend.listApps)throw new y("UNSUPPORTED_OPERATION","apps.list is not supported by this backend");return{kind:"appsList",apps:await e.backend.listApps(rn(e,t),t.filter??"all")}},r7=async(e,t)=>{if(!e.backend.getAppState)throw new y("UNSUPPORTED_OPERATION","apps.state is not supported by this backend");let n=n7(t.app,"app"),r=await e.backend.getAppState(rn(e,t),n);return{kind:"appState",app:n,state:r}},ae=async(e,t)=>{if(!e.backend.pushFile)throw new y("UNSUPPORTED_OPERATION","apps.push is not supported by this backend");let n=n7(t.app,"app"),r=await re(e,t.input);try{let a=await e.backend.pushFile(rn(e,t),r.backendInput,n),i=rr(a);return{kind:"appPushed",app:n,inputKind:r.inputKind,...i?{backendResult:i}:{},...ea(`Pushed to ${n}`)}}finally{await r.cleanup?.()}},at=async(e,t)=>{var n,r;if(!e.backend.triggerAppEvent)throw new y("UNSUPPORTED_OPERATION","apps.triggerEvent is not supported by this backend");let a=function(e){let t=n7(e,"name");if(!n6.test(t))throw new y("INVALID_ARGS",`Invalid apps.triggerEvent name: ${t}`,{hint:"Use 1-64 chars: letters, numbers, underscore, dot, colon, or dash."});return t}(t.name);n=t.payload,r=`apps.triggerEvent payload for "${a}"`,void 0!==n&&rt(n,r,8192);let i=rr(await e.backend.triggerAppEvent(rn(e,t),{name:a,...t.payload?{payload:t.payload}:{}}));return{kind:"appEventTriggered",name:a,...t.payload?{payload:t.payload}:{},...i?{backendResult:i}:{},...ea(`Triggered app event: ${a}`)}},an=async(e,t={})=>{if(!e.backend.listDevices)throw new y("UNSUPPORTED_OPERATION","admin.devices is not supported by this backend");return{kind:"adminDevices",devices:await e.backend.listDevices(nh(e,t),t.filter)}},ar=async(e,t={})=>{if(!e.backend.bootDevice)throw new y("UNSUPPORTED_OPERATION","admin.boot is not supported by this backend");let n=function(e){if(!e)return;let t=rl(e.id,"target.id"),n=rl(e.name,"target.name"),r={...t?{id:t}:{},...n?{name:n}:{},...e.platform?{platform:e.platform}:{},...e.target?{target:e.target}:{},...void 0!==e.headless?{headless:e.headless}:{}};return Object.keys(r).length>0?r:void 0}(t.target),r=rc(await e.backend.bootDevice(nh(e,t),n));return{kind:"deviceBooted",...n?{target:n}:{},...r?{backendResult:r}:{},...ea("Booted device")}},aa=async(e,t)=>{if(!e.backend.ensureSimulator)throw new y("UNSUPPORTED_OPERATION","admin.ensureSimulator is not supported by this backend");let n=rd(t.device,"device");return{kind:"simulatorEnsured",...await e.backend.ensureSimulator(nh(e,t),{device:n,...t.runtime?{runtime:rd(t.runtime,"runtime")}:{},...void 0!==t.boot?{boot:t.boot}:{},...void 0!==t.reuseExisting?{reuseExisting:t.reuseExisting}:{}})}},ai=async(e,t)=>await ra(e,t,"install"),ao=async(e,t)=>await ra(e,t,"reinstall"),as=async(e,t)=>await ra(e,t,"installFromSource"),al=async(e,t)=>{let n=rp(t.action,"record"),r="start"===n?e.backend.startRecording:e.backend.stopRecording;if(!r)throw new y("UNSUPPORTED_OPERATION",`record ${n} is not supported by this backend`);let a=t.out?await tx(e,t.out,{field:"path",ext:".mp4"}):void 0;try{var i,o,s,l,d;let u,c,p=(i=t,o=a?.path,u=void 0===i.fps?void 0:n$(i.fps,"fps",1,60),c=void 0===i.quality?void 0:n$(i.quality,"quality",5,10),{...o?{outPath:o}:{},...void 0!==u?{fps:u}:{},...void 0!==c?{quality:c}:{},...void 0!==i.hideTouches?{showTouches:!0!==i.hideTouches}:{}}),f=await r.call(e.backend,nh(e,t),p),h=await a?.publish();return s=n,l=f,d=h,{..."string"==typeof l.path?{path:l.path}:{},..."string"==typeof l.telemetryPath?{telemetryPath:l.telemetryPath}:{},..."string"==typeof l.warning?{warning:l.warning}:{},...rf(s,l,d,{startKind:"recordingStarted",stopKind:"recordingStopped",startMessage:"Recording started",stopMessage:"Recording stopped"})}}catch(e){throw await a?.cleanup?.(),e}},ad=async(e,t)=>{let n=rp(t.action,"trace"),r="start"===n?e.backend.startTrace:e.backend.stopTrace;if(!r)throw new y("UNSUPPORTED_OPERATION",`trace ${n} is not supported by this backend`);let a=t.out?await tx(e,t.out,{field:"outPath",ext:".trace"}):void 0;try{var i,o,s;let l={...a?.path?{outPath:a.path}:{}},d=await r.call(e.backend,nh(e,t),l),u=await a?.publish();return i=n,o=d,s=u,{..."string"==typeof o.outPath?{outPath:o.outPath}:{},...rf(i,o,s,{startKind:"traceStarted",stopKind:"traceStopped",startMessage:"Trace started",stopMessage:"Trace stopped"})}}catch(e){throw await a?.cleanup?.(),e}},au=async(e,t={})=>{var n,r;let a;if(!e.backend.readLogs)throw new y("UNSUPPORTED_OPERATION","diagnostics.logs is not supported by this backend");return a=!0===(n=await e.backend.readLogs(await rN(e,t),{...r_(r=t,100,500,"logs limit"),...void 0!==r.levels?{levels:rM(r.levels,"levels")}:{},...void 0!==r.search?{search:rD(r.search,"search")}:{},...void 0!==r.source?{source:rD(r.source,"source")}:{}})).redacted,{kind:"diagnosticsLogs",entries:n.entries.map(e=>{let t=rx(e.message,4096),n=rI(e.metadata);return a||=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:a,...n.notes?{notes:n.notes}:{}}},ac=async(e,t={})=>{var n,r,a;let i;if(!e.backend.dumpNetwork)throw new y("UNSUPPORTED_OPERATION","diagnostics.network is not supported by this backend");let o={...r_(a=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 y("INVALID_ARGS","network include must be summary, headers, body, or all")}(a.include)};return n=await e.backend.dumpNetwork(await rN(e,t),o),r=o.include??"summary",i=!0===n.redacted,{kind:"diagnosticsNetwork",entries:n.entries.map(e=>{var t;let n=e.url?rg(t=e.url)??rx(t,2048):void 0,a="headers"===r||"all"===r?rb(e.requestHeaders):void 0,o="headers"===r||"all"===r?rb(e.responseHeaders):void 0,s="body"===r||"all"===r?rv(e.requestBody):void 0,l="body"===r||"all"===r?rv(e.responseBody):void 0,d=rI(e.metadata);return i||=(n?.redacted??!1)||(a?.redacted??!1)||(o?.redacted??!1)||(s?.redacted??!1)||(l?.redacted??!1)||d.redacted,{...e.timestamp?{timestamp:e.timestamp}:{},...e.method?{method:e.method}:{},...n?{url:n.value}:{},...void 0!==e.status?{status:e.status}:{},...void 0!==e.durationMs?{durationMs:e.durationMs}:{},...a?.value?{requestHeaders:a.value}:{},...o?.value?{responseHeaders:o.value}:{},...s?.value!==void 0?{requestBody:s.value}:{},...l?.value!==void 0?{responseBody:l.value}:{},...d.value?{metadata:d.value}:{}}}),...n.nextCursor?{nextCursor:n.nextCursor}:{},...n.timeWindow?{timeWindow:n.timeWindow}:{},...n.backend?{backend:n.backend}:{},redacted:i,...n.notes?{notes:n.notes}:{}}},ap=async(e,t={})=>{var n,r;let a;if(!e.backend.measurePerf)throw new y("UNSUPPORTED_OPERATION","diagnostics.perf is not supported by this backend");return a=!0===(n=await e.backend.measurePerf(await rN(e,t),{...rk(r=t),...void 0!==r.sampleMs?{sampleMs:n$(r.sampleMs,"sampleMs",100,6e4)}:{},...void 0!==r.metrics?{metrics:rM(r.metrics,"metrics",20)}:{}})).redacted,{kind:"diagnosticsPerf",metrics:n.metrics.map(e=>{let t=rx(e.message,4096),n=rI(e.metadata);return a||=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:a,...n.notes?{notes:n.notes}:{}}};function af(e){let t={backend:e.backend,artifacts:e.artifacts,sessions:e.sessions??function(e=[]){let t=new Map(e.map(e=>[e.name,ah(e)]));return{get:e=>ah(t.get(e)),set:e=>{t.set(e.name,ah(e))},delete:e=>{t.delete(e)},list:()=>Array.from(t.values(),e=>ah(e))}}(),policy:e.policy??function(e={}){return{allowLocalInputPaths:!1,allowLocalOutputPaths:!1,maxImagePixels:2e7,allowNamedBackendCapabilities:[],...e}}(),diagnostics:e.diagnostics,clock:e.clock,signal:e.signal};return{...t,capture:{screenshot:e=>rE(t,e),diffScreenshot:e=>rO(t,e),snapshot:e=>rC(t,e),diffSnapshot:e=>rR(t,e)},selectors:{find:e=>rP(t,e),get:e=>rT(t,e),getText:(e,n={})=>rL(t,{...n,target:e}),getAttrs:(e,n={})=>r$(t,{...n,target:e}),is:e=>rF(t,e),isVisible:(e,n={})=>rU(t,{...n,target:e}),isHidden:(e,n={})=>rG(t,{...n,target:e}),wait:e=>rV(t,e),waitForText:(e,n={})=>rB(t,{...n,text:e})},interactions:{click:(e,n={})=>rj(t,{...n,target:e}),press:(e,n={})=>rq(t,{...n,target:e}),fill:(e,n,r={})=>rX(t,{...r,target:e,text:n}),typeText:(e,n={})=>rH(t,{...n,text:e}),focus:(e,n={})=>rK(t,{...n,target:e}),longPress:(e,n={})=>rz(t,{...n,target:e}),swipe:e=>rY(t,e),scroll:e=>rW(t,e),pinch:e=>rJ(t,e)},system:{back:e=>rZ(t,e),home:e=>rQ(t,e),rotate:e=>r0(t,e),keyboard:e=>r1(t,e),clipboard:e=>r2(t,e),settings:e=>r3(t,e),alert:e=>r5(t,e),appSwitcher:e=>r4(t,e)},apps:{open:e=>r8(t,e),close:e=>r6(t,e),list:e=>r9(t,e),state:e=>r7(t,e),push:e=>ae(t,e),triggerEvent:e=>at(t,e)},admin:{devices:e=>an(t,e),boot:e=>ar(t,e),ensureSimulator:e=>aa(t,e),install:e=>ai(t,e),reinstall:e=>ao(t,e),installFromSource:e=>as(t,e)},recording:{record:e=>al(t,e),trace:e=>ad(t,e)},observability:{logs:e=>au(t,e),network:e=>ac(t,e),perf:e=>ap(t,e)}}}function ah(e){if(e)return{...e,...e.snapshot?{snapshot:structuredClone(e.snapshot)}:{},...e.metadata?{metadata:function(e){try{return structuredClone(e)}catch{return{...e}}}(e.metadata)}:{}}}function am(e={}){return{allowLocalInputPaths:!0,allowLocalOutputPaths:!0,maxImagePixels:2e7,allowNamedBackendCapabilities:[],...e}}function aw(e,t,n){return{ok:!1,error:{code:e,message:t,...n?{details:n}:{}}}}function ag(e){if(!e)return null;let t=Number(e);return Number.isFinite(t)?t:null}function ay(e){if(0===e.length)return null;let t=ag(e[0]);if(null!==t)return{kind:"sleep",durationMs:t};if("text"===e[0]){let t=ag(e[e.length-1]);return{kind:"text",text:(null!==t?e.slice(1,-1).join(" "):e.slice(1).join(" ")).trim(),timeoutMs:t}}if(e[0].startsWith("@")){let t=ag(e[e.length-1]);return{kind:"ref",rawRef:e[0],timeoutMs:t}}let n=ag(e[e.length-1]),r=b(null!==n?e.slice(0,-1):e.slice());if(r&&0===r.rest.length){let e=A(r.selectorExpression);if(e)return{kind:"selector",selector:e,selectorExpression:r.selectorExpression,timeoutMs:n}}return{kind:"text",text:(null!==n?e.slice(0,-1).join(" "):e.join(" ")).trim(),timeoutMs:n}}function ab(e){return e}function av(e){return"apple"===e||"ios"===e||"macos"===e}function aI(e,t){return!t||("apple"===t?av(e):e===t)}function aA(e){let{simulatorSetPath:t,platform:n,target:r}=e;if(t&&"macos"!==n&&"desktop"!==r)return t}async function ax(e,t,n={}){let r=e,a=e=>e.toLowerCase().replace(/_/g," ").replace(/\s+/g," ").trim();if(t.platform&&(r=r.filter(e=>aI(e.platform,t.platform))),t.target&&(r=r.filter(e=>(e.target??"mobile")===t.target)),t.udid){let e=r.find(e=>e.id===t.udid&&av(e.platform));if(!e)throw new y("DEVICE_NOT_FOUND",`No Apple device with UDID ${t.udid}`);return e}if(t.serial){let e=r.find(e=>e.id===t.serial&&"android"===e.platform);if(!e)throw new y("DEVICE_NOT_FOUND",`No Android device with serial ${t.serial}`);return e}if(t.deviceName){let e=a(t.deviceName),n=r.find(t=>a(t.name)===e);if(!n)throw new y("DEVICE_NOT_FOUND",`No device named ${t.deviceName}`);return n}if(1===r.length)return r[0];if(0===r.length){var i;let e=n.simulatorSetPath;if(e&&(!(i=t.platform)||"apple"===i||"ios"===i))throw new y("DEVICE_NOT_FOUND","No devices found in the scoped simulator set",{simulatorSetPath:e,hint:`The simulator set at "${e}" appears to be empty. Create a simulator first:
|
|
2
|
+
xcrun simctl --set "${e}" create "iPhone 16" com.apple.CoreSimulator.SimDeviceType.iPhone-16 com.apple.CoreSimulator.SimRuntime.iOS-18-0`,selector:t});throw new y("DEVICE_NOT_FOUND","No devices found",{selector:t})}let o=r.filter(e=>"device"!==e.kind);o.length>0&&(r=o);let s=r.filter(e=>e.booted);return 1===s.length?s[0]:s[0]??r[0]}let aS=e=>"macos"!==e.platform,aN=e=>"macos"===e.platform||"simulator"===e.kind,a_={device:!0},ak={},aM={alert:{apple:{simulator:!0,device:!0},android:{},linux:ak,supports:aN},pinch:{apple:{simulator:!0,device:!0},android:{},linux:ak,supports:aN},"app-switcher":{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:ak,supports:aS},apps:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:ak},back:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:a_},boot:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:ak,supports:aS},click:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:a_},clipboard:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:a_,supports:e=>"android"===e.platform||"linux"===e.platform||"macos"===e.platform||"simulator"===e.kind},keyboard:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:ak,supports:e=>"android"===e.platform||"ios"===e.platform&&"tv"!==e.target},close:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:a_},fill:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:a_},diff:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:a_},find:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:a_},focus:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:a_},get:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:a_},is:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:a_},home:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:a_,supports:aS},logs:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:ak},network:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:ak},longpress:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:a_},open:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:a_},perf:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:ak},install:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:ak,supports:aS},"install-from-source":{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:ak,supports:aS},reinstall:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:ak,supports:aS},press:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:a_},push:{apple:{simulator:!0},android:{emulator:!0,device:!0,unknown:!0},linux:ak,supports:aS},record:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:ak},rotate:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:ak,supports:e=>"android"===e.platform||"ios"===e.platform&&"tv"!==e.target},screenshot:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:a_},scroll:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:a_},swipe:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:a_},settings:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:ak,supports:e=>"android"===e.platform||"macos"===e.platform||"simulator"===e.kind},snapshot:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:a_},"trigger-app-event":{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:ak},type:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:a_},wait:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:a_}};function aD(e,t){let n=aM[e];if(!n)return!0;let r=av(t.platform)?n.apple:"linux"===t.platform?n.linux:n.android;return!!r&&(!n.supports||!!n.supports(t))&&!0===r[t.kind??"unknown"]}let aE=new Set,aO=new Map,aC="request_canceled",aR="request canceled";function aP(e,t){if("string"==typeof e&&e.length>0)return e;let n=("string"==typeof t?t:"number"==typeof t&&Number.isFinite(t)?String(t):"generated").trim().replace(/[^a-zA-Z0-9_-]/g,"_").slice(0,32)||"generated",r=Math.random().toString(36).slice(2,10);return`req:${n}:${process.pid}:${Date.now()}:${r}`}function aT(e){if(!e)return;!function(e){if(e.size<=5e4)return;let t=0;for(let n of e.keys()){if(t>=1e4)break;e.delete(n),t++}}(aO);let t=new AbortController;aO.set(e,t),aE.has(e)&&t.abort()}function aL(e){e&&(!function(e){if(e.size<=5e4)return;let t=0;for(let n of e){if(t>=1e4)break;e.delete(n),t++}}(aE),aE.add(e),aO.get(e)?.abort())}function a$(e){e&&(aE.delete(e),aO.delete(e))}function aF(e){return!!e&&aE.has(e)}function aU(e){if(e)return aO.get(e)?.signal}function aG(){return new y("COMMAND_FAILED",aR,{reason:aC})}function aV(e){return e instanceof y&&"COMMAND_FAILED"===e.code&&(e.details?.reason===aC||e.message===aR)}function aB(e,t={}){let n=em(t.simulatorSetPath);return n?["simctl","--set",n,...e]:["simctl",...e]}function aj(e,t){return"ios"!==e.platform||"simulator"!==e.kind?["simctl",...t]:aB(t,{simulatorSetPath:e.simulatorSetPath})}function aq(e){return!(e instanceof y)||"COMMAND_FAILED"!==e.code||!String(e.message??"").toLowerCase().includes("xcodebuild exited early")}function aX(e){let{port:t,endpoints:n,logPath:r,lastError:a}=e,i="Runner did not accept connection";return new y("COMMAND_FAILED",i,{port:t,endpoints:n,logPath:r,lastError:a?String(a):void 0,reason:ev({error:a,message:i,context:{platform:"ios",phase:"connect"}}),hint:e_("IOS_RUNNER_CONNECT_TIMEOUT")})}async function aH(e){var t,n;let r,{session:a,port:i,logPath:o}=e,s=await a.testPromise,l="Runner did not accept connection (xcodebuild exited early)",d=ev({message:l,stdout:s.stdout,stderr:s.stderr,context:{platform:"ios",phase:"connect"}});return new y("COMMAND_FAILED",l,{port:i,logPath:o,xcodebuild:{exitCode:s.exitCode,stdout:s.stdout,stderr:s.stderr},reason:d,hint:(t=s.stdout,n=s.stderr,(r=`${l}
|
|
4
3
|
${t}
|
|
5
|
-
${n}`.toLowerCase()).includes("device is busy")&&a.includes("connecting")?"Target iOS device is still connecting. Keep it unlocked, wait for device trust/connection to settle, then retry.":rP("IOS_RUNNER_CONNECT_TIMEOUT"))})}function rH(e){if(rD(e))throw rO()}let rz=ev(process.env.AGENT_DEVICE_RUNNER_STARTUP_TIMEOUT_MS,45e3,5e3),rY=ev(process.env.AGENT_DEVICE_RUNNER_COMMAND_TIMEOUT_MS,45e3,1e3),rK=ev(process.env.AGENT_DEVICE_RUNNER_CONNECT_ATTEMPT_INTERVAL_MS,250,50),rJ=ev(process.env.AGENT_DEVICE_RUNNER_CONNECT_RETRY_BASE_DELAY_MS,300,10),rZ=ev(process.env.AGENT_DEVICE_RUNNER_CONNECT_RETRY_MAX_DELAY_MS,2e3,10),rQ=ev(process.env.AGENT_DEVICE_RUNNER_CONNECT_REQUEST_TIMEOUT_MS,2e4,250),r0=ev(process.env.AGENT_DEVICE_IOS_DEVICE_INFO_TIMEOUT_MS,1e4,500),r1=eI(process.env.AGENT_DEVICE_RUNNER_DESTINATION_TIMEOUT_SECONDS,20,5),r2=new Map;async function r3(e,t,n,a,r=rz,i,o){let s,l=rg.fromTimeoutMs(r),d=async(n,a=!1)=>{var r,i,o;let l,d=await r5({device:e,timeoutBudgetMs:n,forceRefresh:a,requestTunnelIp:s,setRequestTunnelIp:e=>{s=e}});return{endpoints:(r=e,i=t,o=d.ip,l=[`http://127.0.0.1:${i}/command`],"device"!==r.kind||o&&l.unshift(`http://[${o}]:${i}/command`),l),cached:d.sharedCacheHit}},{endpoints:u}=await d(l.remainingMs()),c=null,p=Math.max(1,Math.ceil(r/rK));try{return await ry(async({deadline:s})=>{if(s?.isExpired())throw new y("COMMAND_FAILED","Runner connection deadline exceeded",{port:t,timeoutMs:r});if(i&&null!==i.child.exitCode&&void 0!==i.child.exitCode)throw await rX({session:i,port:t,logPath:a});let l=!1;if("device"===e.kind){let e=await d(s?.remainingMs());u=e.endpoints,l=e.cached}let p=l?u[0]:null,f=await r4(u,{command:n,port:t,timeoutMs:r,signal:o,attemptDeadline:s,onError:(t,n)=>{var a;c=n,"device"===e.kind&&t===p&&(a=e.id,r2.delete(a))}});if(f)return f;if("device"===e.kind&&l){var h;h=e.id,r2.delete(h),u=(await d(s?.remainingMs(),!0)).endpoints;let a=await r4(u,{command:n,port:t,timeoutMs:r,signal:o,attemptDeadline:s,onError:(e,t)=>{c=t}});if(a)return a}if(o?.aborted)throw rO();throw new y("COMMAND_FAILED","Runner endpoint probe failed",{port:t,endpoints:u,lastError:c?String(c):void 0})},{maxAttempts:p,baseDelayMs:rJ,maxDelayMs:rZ,jitter:.2,shouldRetry:rq},{deadline:l,phase:"ios_runner_connect",signal:o})}catch(e){if(o?.aborted||rC(e))throw rO();c||(c=e)}if(o?.aborted)throw rO();if("simulator"===e.kind){let r=l.remainingMs();if(r<=0)throw rW({port:t,endpoints:u,logPath:a,lastError:c});let i=await r9(e,t,n,r,o);return new Response(i.body,{status:i.status})}throw rW({port:t,endpoints:u,logPath:a,lastError:c})}async function r4(e,t){let{command:n,port:a,timeoutMs:r,signal:i,attemptDeadline:o,onError:s}=t;for(let t of e)try{let e=o?.remainingMs()??r;if(e<=0)throw new y("COMMAND_FAILED","Runner connection deadline exceeded",{port:a,timeoutMs:r});return await r8(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)},Math.min(rQ,e),i)}catch(e){if(i?.aborted||rC(e))throw rO();s(t,e)}return null}async function r5(e){var t,n,a;let{device:r,timeoutBudgetMs:i,forceRefresh:o,requestTunnelIp:s,setRequestTunnelIp:l}=e;if("device"!==r.kind)return{ip:null,sharedCacheHit:!1};if(!o){let e,n=(t=r.id,(e=r2.get(t))?e.expiresAt<=Date.now()?(r2.delete(t),null):e.ip:null);if(n)return{ip:n,sharedCacheHit:!0};if(void 0!==s)return{ip:s,sharedCacheHit:!1}}let d=await r6(r.id,i);return l(d),d&&(n=r.id,a=d,r2.set(n,{ip:a,expiresAt:Date.now()+3e4})),{ip:d,sharedCacheHit:!1}}async function r8(e,t,n,a){let r=AbortSignal.timeout(n),i=a?AbortSignal.any([a,r]):r;return await fetch(e,{...t,signal:i})}async function r6(e,t){if("number"==typeof t&&t<=0)return null;let a="number"==typeof t?Math.max(1,Math.min(r0,t)):r0,r=o.join(s.tmpdir(),`agent-device-devicectl-info-${process.pid}-${Date.now()}.json`);try{let t=Math.max(1,Math.ceil(a/1e3)),i=await ef("xcrun",["devicectl","device","info","details","--device",e,"--json-output",r,"--timeout",String(t)],{allowFailure:!0,timeoutMs:a});if(0!==i.exitCode||!n.existsSync(r))return null;let o=JSON.parse(n.readFileSync(r,"utf8"));if(o.info?.outcome&&"success"!==o.info.outcome)return null;let s=(o.result?.connectionProperties?.tunnelIPAddress??o.result?.device?.connectionProperties?.tunnelIPAddress)?.trim();return s&&s.length>0?s:null}catch{return null}finally{ir(r)}}async function r9(e,t,n,a,r){let i=JSON.stringify(n),o=rj(e,["spawn",e.id,"/usr/bin/curl","-s","-X","POST","-H","Content-Type: application/json","--data",i,`http://127.0.0.1:${t}/command`]),s=await ef("xcrun",o,{allowFailure:!0,timeoutMs:a,signal:r}),l=s.stdout;if(0!==s.exitCode){let e=rR({message:"Runner did not accept connection (simctl spawn)",stdout:s.stdout,stderr:s.stderr,context:{platform:"ios",phase:"connect"}});throw new y("COMMAND_FAILED","Runner did not accept connection (simctl spawn)",{port:t,stdout:s.stdout,stderr:s.stderr,exitCode:s.exitCode,reason:e,hint:rP(e)})}return{status:200,body:l}}async function r7(){return await new Promise((e,t)=>{let n=d.createServer();n.listen(0,"127.0.0.1",()=>{let a=n.address();if("object"==typeof a&&a?.port){let t=a.port;n.close(()=>e(t))}else n.close(()=>t(new y("COMMAND_FAILED","Failed to allocate port")))}),n.on("error",t)})}function ie(e,t,n,a){t&&ia(t,e),n&&ia(n,e),a&&process.stderr.write(e)}let it=new Map;function ia(e,t){let a=(it.get(e)??Promise.resolve()).catch(()=>{}).then(()=>n.promises.appendFile(e,t)).catch(()=>{}).finally(()=>{it.get(e)===a&&it.delete(e)});it.set(e,a)}function ir(e){try{n.existsSync(e)&&n.unlinkSync(e)}catch{}}let ii=new u;async function io(e,t,n){let a=ii.getStore()??[];if(a.some(n=>n.locks===e&&n.key===t))return await n();let r=(e.get(t)??Promise.resolve()).catch(()=>{}).then(()=>ii.run([...a,{locks:e,key:t}],n));return e.set(t,r),r.finally(()=>{e.get(t)===r&&e.delete(t)})}let is=new Set(["RUNNER_PRODUCT_MISSING","RUNNER_PRODUCT_REPAIR_FAILED"]);async function il(e,t,a){if("macos"!==e.platform)return;if(0===t.length)throw new y("COMMAND_FAILED","Missing macOS runner product",{reason:"RUNNER_PRODUCT_MISSING",xctestrunPath:a});let r=Array.from(new Set(t)).sort((e,t)=>t.length-e.length);for(let e of r)if(!n.existsSync(e))throw new y("COMMAND_FAILED","Missing macOS runner product",{reason:"RUNNER_PRODUCT_MISSING",productPath:e,xctestrunPath:a});for(let e of r)if(0!==ep("codesign",["--verify","--deep","--strict",e],{allowFailure:!0}).exitCode){await ef("codesign",["--remove-signature",e],{allowFailure:!0});try{await ef("codesign",["--force","--sign","-",e])}catch(n){let t=n instanceof y?n:new y("COMMAND_FAILED",String(n));throw new y("COMMAND_FAILED","Failed to repair macOS runner product signature",{reason:"RUNNER_PRODUCT_REPAIR_FAILED",productPath:e,xctestrunPath:a,error:t.message,details:t.details})}}}let id=null;function iu(e){return function e(t){if(!Array.isArray(t))return[];let n=[];for(let a of t)if(!(!a||"object"!=typeof a||Array.isArray(a)))for(let[t,r]of Object.entries(a))":@"!==t&&"#text"!==t&&n.push({name:t,attributes:function(e){if(!e||"object"!=typeof e||Array.isArray(e))return{};let t={};for(let[n,a]of Object.entries(e))"string"==typeof a&&(t[n]=a);return t}(a[":@"]),text:ip(r)??ip(a["#text"]),children:e(r)});return n}((id??=new p({ignoreAttributes:!1,attributeNamePrefix:"",preserveOrder:!0,trimValues:!0,parseTagValue:!1})).parse(e))}function ic(e,t){for(let n of e){if("dict"===n.name)for(let e=0;e<n.children.length-1;e+=1){let a=n.children[e],r=n.children[e+1];a?.name==="key"&&a.text&&r&&t(a.text,r)}ic(n.children,t)}}function ip(e){if("string"==typeof e){let t=e.trim();return t.length>0?t:null}if(!Array.isArray(e))return null;let t=e.map(e=>{if(!e||"object"!=typeof e||Array.isArray(e))return null;let t=e["#text"];return"string"==typeof t?t.trim():null}).filter(e=>null!==e&&e.length>0).join("").trim();return t.length>0?t:null}let ih="XCTestDevices",im=".agent-device-backup",iw=".agent-device-xctestdevices-backup-",ig=o.join(s.homedir(),".agent-device","ios-runner"),iy=new Set(["ProductPaths","DependentProductPaths","TestHostPath","TestBundlePath","UITargetAppPath"]),ib=new Map,iv=new Set;function iI(e){return e?.trim()??""}function iA(e=process.env){return iI(e.AGENT_DEVICE_IOS_BUNDLE_ID)||iI(e.AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID)||"com.callstack.agentdevice.runner"}function ix(e=process.env){let t=iI(e.AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID);return t||`${iA(e)}.uitests`}let iS=function(e=process.env){let t=iA(e),n=ix(e);return Array.from(new Set([iI(e.AGENT_DEVICE_IOS_RUNNER_CONTAINER_BUNDLE_ID),`${n}.xctrunner`,t].filter(e=>e.length>0)))}(process.env);function iN(e=s.homedir()){return o.join(e,"Library","Developer","XCTestDevices")}async function i_(e,t={}){if("ios"!==e.platform||"simulator"!==e.kind)return null;let a=rU(e.simulatorSetPath);if(!a)return null;let r=o.resolve(a),i=o.resolve(t.xctestDeviceSetPath??iN()),l=o.resolve(t.backupPath??function(e=iN()){return`${e}${im}`}(i)),d=o.resolve(t.lockDirPath??function(e=s.homedir()){return o.join(e,".agent-device","xctest-device-set.lock")}()),u=t.ownerStartTime??eS(process.pid),c=await iD({lockDirPath:d,owner:{pid:t.ownerPid??process.pid,startTime:u,acquiredAtMs:t.nowMs??Date.now()}});try{if(iM({xctestDeviceSetPath:i,backupPath:l}),function(e,t){if(o.resolve(e)===o.resolve(t))return!0;try{return n.realpathSync.native(e)===n.realpathSync.native(t)}catch{return!1}}(r,i))return await c(),null;n.mkdirSync(r,{recursive:!0}),n.existsSync(i)&&n.renameSync(i,l),function(e){let{requestedSetPath:t,xctestDeviceSetPath:a}=e,r=o.dirname(a),i=o.join(r,`${ih}.agent-device-link-${process.pid}-${Date.now()}`);n.mkdirSync(r,{recursive:!0});try{n.symlinkSync(t,i,"dir"),n.renameSync(i,a)}catch(e){throw n.existsSync(i)&&ik(i),e}}({requestedSetPath:r,xctestDeviceSetPath:i})}catch(e){throw iM({xctestDeviceSetPath:i,backupPath:l}),await c(),new y("COMMAND_FAILED","Failed to redirect XCTest device set path",{requestedSetPath:r,xctestDeviceSetPath:i,backupPath:l,error:String(e)})}let p=!1;return{release:async()=>{if(!p){p=!0;try{iM({xctestDeviceSetPath:i,backupPath:l})}finally{await c()}}}}}function iM(e){let{xctestDeviceSetPath:t,backupPath:a}=e,r=[a,...function(e){let t=o.dirname(e),a=o.basename(e).replace(im,""),r=a===ih?iw:`${a}${iw}`;try{return n.readdirSync(t).filter(e=>e.startsWith(r)).sort().map(e=>o.join(t,e))}catch{return[]}}(a)],i=r.find(e=>n.existsSync(e)),s=n.existsSync(t)&&n.lstatSync(t).isSymbolicLink();if(i){if(s&&ik(t),n.existsSync(t))if(!s)return void el({level:"warn",phase:"ios_runner_xctest_device_set_restore_collision",data:{xctestDeviceSetPath:t,activeBackupPath:i}});else i!==a?n.rmSync(i,{recursive:!0,force:!0}):n.rmSync(a,{recursive:!0,force:!0});else n.mkdirSync(o.dirname(t),{recursive:!0}),n.renameSync(i,t);for(let e of r)e!==i&&n.existsSync(e)&&n.rmSync(e,{recursive:!0,force:!0});return}s&&(el({level:"warn",phase:"ios_runner_xctest_device_set_orphaned_symlink",data:{xctestDeviceSetPath:t}}),ik(t))}function ik(e){!n.existsSync(e)||n.lstatSync(e).isSymbolicLink()&&n.unlinkSync(e)}async function iD(e){let{lockDirPath:t,owner:a}=e,r=o.join(t,"owner.json"),i=Date.now()+3e4;for(n.mkdirSync(o.dirname(t),{recursive:!0});Date.now()<i;)try{n.mkdirSync(t),function(e,t){let a=`${e}.${process.pid}.${Date.now()}.tmp`;n.writeFileSync(a,JSON.stringify(t),"utf8"),n.renameSync(a,e)}(r,a);let e=!1;return async()=>{e||(e=!0,n.rmSync(t,{recursive:!0,force:!0}))}}catch(e){if("EEXIST"!==e.code)throw e;if(function(e,t){let a=null;try{a=n.statSync(e)}catch{return!0}let r=function(e){try{return JSON.parse(n.readFileSync(e,"utf8"))}catch{return null}}(t);if(r){var i;return!(Number.isInteger((i=r).pid)&&!(i.pid<=0)&&ex(i.pid)&&(!i.startTime||eS(i.pid)===i.startTime))&&(n.rmSync(e,{recursive:!0,force:!0}),!0)}return!(Date.now()-a.mtimeMs<5e3)&&(n.rmSync(e,{recursive:!0,force:!0}),!0)}(t,r))continue;await eb(100)}throw new y("COMMAND_FAILED","Timed out waiting for XCTest device set lock",{lockDirPath:t})}async function iE(e,t){var a;let r,i=(a=e,(r=process.env.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim())?o.resolve(r):"macos"===a.platform?o.join(ig,"derived","macos"):"simulator"===a.kind?o.join(ig,"derived"):o.join(ig,"derived",a.kind)),s=function(){let e=o.dirname(c(import.meta.url)),t=e;for(let e=0;e<6;e+=1){let e=o.join(t,"package.json");if(n.existsSync(e))return t;t=o.dirname(t)}return e}();return await io(ib,i,async()=>{rf(process.env.AGENT_DEVICE_IOS_CLEAN_DERIVED)&&(iB("clean","forced_clean",{derived:i}),iV(i),iO(i));let a=function(e){let t=e.findXctestrun(e.derived);if(!t)return{reason:"missing_xctestrun",xctestrunPath:null};let n=e.resolveExistingXctestrunProductPaths(t);return n?e.xctestrunReferencesProjectRoot(t,e.projectRoot)?{reason:"reuse_ready",xctestrunPath:t,productPaths:n}:{reason:"project_root_mismatch",xctestrunPath:t,productPaths:n}:{reason:"missing_products",xctestrunPath:t,productPaths:[]}}({derived:i,projectRoot:s,findXctestrun:t=>iR(t,e),xctestrunReferencesProjectRoot:iT,resolveExistingXctestrunProductPaths:ij});if("reuse_ready"!==a.reason&&iB("rebuild",a.reason,{derived:i,xctestrunPath:a.xctestrunPath}),"reuse_ready"===a.reason)try{return await il(e,a.productPaths,a.xctestrunPath),iB("reuse","reuse_ready",{derived:i,xctestrunPath:a.xctestrunPath}),a.xctestrunPath}catch(e){if(!function(e){if(!(e instanceof y))return!1;let t=e.details&&"object"==typeof e.details?e.details.reason:void 0;return"string"==typeof t&&is.has(t)}(e))throw e;iB("rebuild","repair_failed",{derived:i,xctestrunPath:a.xctestrunPath})}a.xctestrunPath&&(iV(i),iO(i));let r=o.join(s,"ios-runner","AgentDeviceRunner","AgentDeviceRunner.xcodeproj");if(!n.existsSync(r))throw new y("COMMAND_FAILED","iOS runner project not found",{projectPath:r});await i$(e,r,i,t);let l=iR(i,e);if(!l)throw new y("COMMAND_FAILED","Failed to locate .xctestrun after build");let d=ij(l);if(!d)throw new y("COMMAND_FAILED","Runner build is missing expected products",{xctestrunPath:l});return await il(e,d,l),iB("build","built_new",{derived:i,xctestrunPath:l}),l})}function iO(e){try{if(!n.existsSync(e))return;if("derived"!==o.basename(e))return void n.rmSync(e,{recursive:!0,force:!0});for(let a of n.readdirSync(e,{withFileTypes:!0})){var t;t=a.name,iC.has(t)&&n.rmSync(o.join(e,a.name),{recursive:!0,force:!0})}}catch{}}let iC=new Set(["Build","BuildCache.noindex","Index.noindex","Logs","ModuleCache.noindex","SDKStatCaches.noindex","SourcePackages","TextBasedInstallAPI","info.plist"]);function iR(e,t){if(!n.existsSync(e))return null;let a=[],r=[e];for(;r.length>0;){let e=r.pop();for(let t of n.readdirSync(e,{withFileTypes:!0})){let i=o.join(e,t.name);if(t.isDirectory()){r.push(i);continue}if(t.isFile()&&t.name.endsWith(".xctestrun"))try{let e=n.statSync(i);a.push({path:i,mtimeMs:e.mtimeMs})}catch{}}}return 0===a.length?null:(a.sort((e,n)=>{if(t){let a=iP(n.path,t)-iP(e.path,t);if(0!==a)return a}return n.mtimeMs-e.mtimeMs||e.path.localeCompare(n.path)}),a[0]?.path??null)}function iP(e,t){var n;let a=0,r=e.toLowerCase();o.basename(r).startsWith("agentdevicerunner.env.")&&(a-=1e3),r.includes(`${o.sep}macos${o.sep}`)&&(a-=5e3);let i="macos"===(n=t).platform?{preferred:["macos"],disallowed:["iphoneos","iphonesimulator","appletvos","appletvsimulator"]}:"tv"===n.target?"simulator"===n.kind?{preferred:["appletvsimulator"],disallowed:["appletvos","iphoneos","iphonesimulator","macos"]}:{preferred:["appletvos"],disallowed:["appletvsimulator","iphoneos","iphonesimulator","macos"]}:"simulator"===n.kind?{preferred:["iphonesimulator"],disallowed:["iphoneos","appletvos","appletvsimulator","macos"]}:{preferred:["iphoneos"],disallowed:["iphonesimulator","appletvos","appletvsimulator","macos"]};return i.preferred.length>0&&(i.preferred.some(e=>r.includes(e))?a+=2e3:a-=500),i.disallowed.some(e=>r.includes(e))&&(a-=2500),a}function iT(e,t){try{let a=n.readFileSync(e,"utf8"),r=new Set([t]);try{r.add(n.realpathSync(t))}catch{}for(let e of r)if(a.includes(e))return!0;return!1}catch{return!1}}async function iL(e,t,a){let r,i=o.dirname(e),s=a.replace(/[^a-zA-Z0-9._-]/g,"_"),l=o.join(i,`AgentDeviceRunner.env.${s}.json`),d=o.join(i,`AgentDeviceRunner.env.${s}.xctestrun`),u=await ef("plutil",["-convert","json","-o","-",e],{allowFailure:!0});if(0!==u.exitCode||!u.stdout.trim())throw new y("COMMAND_FAILED","Failed to read xctestrun plist",{xctestrunPath:e,stderr:u.stderr});try{let e=JSON.parse(u.stdout);if(!e||"object"!=typeof e||Array.isArray(e))throw Error("Root must be an object");r=e}catch(t){throw new y("COMMAND_FAILED","Failed to parse xctestrun JSON",{xctestrunPath:e,error:String(t)})}let c=e=>{e.EnvironmentVariables={...e.EnvironmentVariables??{},...t},e.UITestEnvironmentVariables={...e.UITestEnvironmentVariables??{},...t},e.UITargetAppEnvironmentVariables={...e.UITargetAppEnvironmentVariables??{},...t},e.TestingEnvironmentVariables={...e.TestingEnvironmentVariables??{},...t}},p=r.TestConfigurations;if(Array.isArray(p))for(let e of p){if(!e||"object"!=typeof e)continue;let t=e.TestTargets;if(Array.isArray(t))for(let e of t)e&&"object"==typeof e&&c(e)}for(let[e,t]of Object.entries(r))t&&"object"==typeof t&&!Array.isArray(t)&&t.TestBundlePath&&(c(t),r[e]=t);n.writeFileSync(l,JSON.stringify(r,null,2));let f=await ef("plutil",["-convert","xml1","-o",d,l],{allowFailure:!0});if(0!==f.exitCode)throw new y("COMMAND_FAILED","Failed to write xctestrun plist",{tmpXctestrunPath:d,stderr:f.stderr});return{xctestrunPath:d,jsonPath:l}}async function i$(e,t,n,a){let r=function(e=process.env){let t=iA(e),n=ix(e);return[`AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID=${t}`,`AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID=${n}`]}(process.env),i=function(e=process.env,t=!1,n="ios"){if("macos"===n)return["CODE_SIGNING_ALLOWED=NO","CODE_SIGNING_REQUIRED=NO","CODE_SIGN_IDENTITY=","DEVELOPMENT_TEAM="];if(!t)return[];let a=e.AGENT_DEVICE_IOS_TEAM_ID?.trim()||"",r=e.AGENT_DEVICE_IOS_SIGNING_IDENTITY?.trim()||"",i=e.AGENT_DEVICE_IOS_PROVISIONING_PROFILE?.trim()||"",o=["CODE_SIGN_STYLE=Automatic"];return a&&o.push(`DEVELOPMENT_TEAM=${a}`),r&&o.push(`CODE_SIGN_IDENTITY=${r}`),i&&o.push(`PROVISIONING_PROFILE_SPECIFIER=${i}`),o}(process.env,"device"===e.kind,e.platform),o="device"===e.kind?["-allowProvisioningUpdates"]:[],s=await i_(e);try{var l;let s;await ed("xcodebuild",["build-for-testing","-project",t,"-scheme","AgentDeviceRunner","-parallel-testing-enabled","NO",iG(e),"1","-destination",(l=e,s=iF(l),"macOS"===s?`platform=macOS,arch=${iU()}`:"simulator"===l.kind?`platform=${s} Simulator,id=${l.id}`:`generic/platform=${s}`),"-derivedDataPath",n,"COMPILER_INDEX_STORE_ENABLE=NO","ENABLE_CODE_COVERAGE=NO",...r,...o,...i],{detached:!0,onSpawn:e=>{iv.add(e),e.on("close",()=>{iv.delete(e)})},onStdoutChunk:e=>{ie(e,a.logPath,a.traceLogPath,a.verbose)},onStderrChunk:e=>{ie(e,a.logPath,a.traceLogPath,a.verbose)}})}catch(i){let e,t,n=i instanceof y?i:new y("COMMAND_FAILED",String(i)),r=(e=n.details?JSON.stringify(n.details):"",(t=`${n.message}
|
|
6
|
-
${e}`.toLowerCase()).includes("failed registering bundle identifier")||t.includes("app identifier")&&t.includes("not available")?"Set AGENT_DEVICE_IOS_BUNDLE_ID to a unique reverse-DNS value (for example, com.yourname.agentdevice.runner), then retry.":t.includes("requires a development team")?"Configure signing in Xcode or set AGENT_DEVICE_IOS_TEAM_ID for physical-device runs.":t.includes("no profiles for")||t.includes("provisioning profile")?"Install/select a valid iOS provisioning profile, or set AGENT_DEVICE_IOS_PROVISIONING_PROFILE.":t.includes("code signing")?"Enable Automatic Signing in Xcode or provide AGENT_DEVICE_IOS_TEAM_ID and optional AGENT_DEVICE_IOS_SIGNING_IDENTITY.":void 0);throw new y("COMMAND_FAILED","xcodebuild build-for-testing failed",{error:n.message,details:n.details,logPath:
|
|
7
|
-
${n.stderr}`.toLowerCase();if(!e.includes("not installed")&&!e.includes("found nothing")&&!e.includes("no such file")&&!e.includes("invalid device")&&!e.includes("could not find"))continue}}}function iz(e){let t=iq.get(e);return t?{sessionId:t.sessionId,alive:i0(t.child.pid)}:null}async function iY(e){await io(
|
|
8
|
-
`,"utf8"),
|
|
9
|
-
${
|
|
10
|
-
${e.stderr}`}function oM(e,t){return["-s",e,...t]}function ok(e){return e.startsWith("emulator-")}function oD(e){return e.toLowerCase().replace(/_/g," ").replace(/\s+/g," ").trim()}async function oE(e,t=rw){return ef("adb",oM(e,["shell","getprop","sys.boot_completed"]),{allowFailure:!0,timeoutMs:t})}async function oO(e,t){let n=t.replace(/_/g," ").trim();if(!ok(e))return n||e;let a=await oR(e);return a?a.replace(/_/g," "):n||e}async function oC(e,t,n){try{return await n("adb",oM(e,t),{allowFailure:!0,timeoutMs:1e4})}catch(e){var a;if("COMMAND_FAILED"===(a=w(e)).code&&"number"==typeof a.details?.timeoutMs)return;throw e}}async function oR(e,t=ef){for(let n of["ro.boot.qemu.avd_name","persist.sys.avd_name"]){let a=await oC(e,["shell","getprop",n],t);if(!a)continue;let r=a.stdout.trim();if(0===a.exitCode&&r.length>0)return r}let n=await oC(e,["emu","avd","name"],t);if(!n)return;let a=function(e){let t=e.split("\n").map(e=>e.trim()).filter(e=>e.length>0);if(0!==t.length)return"OK"===t.at(-1)&&t.pop(),t.join("\n").trim()||void 0}(n.stdout);if(0===n.exitCode&&a)return a}async function oP(e,t){let n=o_(await ef("adb",oM(e,["shell","cmd","package","has-feature",t]),{allowFailure:!0,timeoutMs:rw})).toLowerCase();return!!n.includes("true")||!n.includes("false")&&null}async function oT(e){return(await oN(oS,2,async t=>await oP(e,t))).some(e=>!0===e)}async function oL(e){var t;let n;return"tv"===((n=o_(await ef("adb",oM(e,["shell","getprop","ro.build.characteristics"]),{allowFailure:!0,timeoutMs:rw})).toLowerCase()).includes("tv")||n.includes("leanback")?"tv":null)||await oT(e)?"tv":(t=o_(await ef("adb",oM(e,["shell","pm","list","features"]),{allowFailure:!0,timeoutMs:rw})),/feature:android\.(software\.leanback(_only)?|hardware\.type\.television)\b/i.test(t))?"tv":"mobile"}async function o$(e={}){if(await eN(),!await em("adb"))throw new y("TOOL_MISSING","adb not found in PATH");let t=e.serialAllowlist??rV(void 0),n=(await oF()).filter(e=>!t||t.has(e.serial));return await oN(n,3,async({serial:e,rawModel:t})=>{let[n,a,r]=await Promise.all([oO(e,t),oB(e),oL(e)]);return{platform:"android",id:e,name:n,kind:ok(e)?"emulator":"device",target:r,booted:a}})}async function oF(){return(await ef("adb",["devices","-l"],{timeoutMs:rw})).stdout.split("\n").map(e=>e.trim()).filter(e=>e.length>0&&!e.startsWith("List of devices")).map(e=>e.split(/\s+/)).filter(e=>"device"===e[1]).map(e=>({serial:e[0],rawModel:(e.find(e=>e.startsWith("model:"))??"").replace("model:","")}))}async function oU(){let e=await ef("emulator",["-list-avds"],{allowFailure:!0,timeoutMs:rw});if(0!==e.exitCode)throw new y("COMMAND_FAILED","Failed to list Android emulator AVDs",{stdout:e.stdout,stderr:e.stderr,exitCode:e.exitCode,hint:"Verify Android emulator tooling is installed and available in PATH."});return e.stdout.split("\n").map(e=>e.trim()).filter(e=>e.length>0)}async function oG(e){let t=Date.now();for(;Date.now()-t<e.timeoutMs;){try{let t=await oV(e.avdName,e.serial);if(t)return{platform:"android",id:t,name:e.avdName,kind:"emulator",target:"mobile",booted:!1}}catch{}await eb(1e3)}throw new y("COMMAND_FAILED","Android emulator did not appear in time",{avdName:e.avdName,serial:e.serial,timeoutMs:e.timeoutMs,hint:"Check emulator logs and verify the AVD can start from command line."})}async function oV(e,t){let n=oD(e);for(let e of(await oF()).filter(e=>(!t||e.serial===t)&&ok(e.serial)))if(oD(e.rawModel)===n||oD(await oO(e.serial,e.rawModel))===n)return e.serial}async function oB(e){try{let t=await oE(e);return"1"===t.stdout.trim()}catch{return!1}}async function oj(e){var t,n;let a;await eN();let r=e.avdName.trim();if(!r)throw new y("INVALID_ARGS","Android emulator boot requires a non-empty AVD name.");let i=e.timeoutMs??12e4;if(!await em("adb"))throw new y("TOOL_MISSING","adb not found in PATH");if(!await em("emulator"))throw new y("TOOL_MISSING","emulator not found in PATH");let o=await oU(),s=function(e,t){let n=e.find(e=>e===t);if(n)return n;let a=oD(t);return e.find(e=>oD(e)===a)}(o,r);if(!s)throw new y("DEVICE_NOT_FOUND",`No Android emulator AVD named ${e.avdName}`,{requestedAvdName:r,availableAvds:o,hint:"Run `emulator -list-avds` and pass an existing AVD name to --device."});let l=Date.now(),d=(t=await o$(),n=e.serial,a=oD(s),t.find(e=>"android"===e.platform&&"emulator"===e.kind&&(!n||e.id===n)&&oD(e.name)===a));if(!d){let t=["-avd",s];e.headless&&t.push("-no-window","-no-audio"),eu("emulator",t)}let u=d??await oG({avdName:s,serial:e.serial,timeoutMs:i}),c=Math.max(1e3,i-(Date.now()-l));await oq(u.id,c);let p=(await o$()).find(e=>e.id===u.id);return p?{...p,name:s,booted:!0}:{...u,name:s,booted:!0}}async function oq(e,t=6e4){let n,a=rg.fromTimeoutMs(t),r=Math.max(1,Math.ceil(t/1e3)),i=!1;try{await ry(async({deadline:r})=>{if(r?.isExpired())throw i=!0,new y("COMMAND_FAILED","Android boot deadline exceeded",{serial:e,timeoutMs:t,elapsedMs:a.elapsedMs(),message:"timeout"});let o=Math.max(1e3,r?.remainingMs()??t),s=await oE(e,Math.min(o,rw));if(n=s,"1"!==s.stdout.trim())throw new y("COMMAND_FAILED","Android device is still booting",{serial:e,stdout:s.stdout,stderr:s.stderr,exitCode:s.exitCode})},{maxAttempts:r,baseDelayMs:1e3,maxDelayMs:1e3,jitter:0,shouldRetry:e=>{let t=rR({error:e,stdout:n?.stdout,stderr:n?.stderr,context:{platform:"android",phase:"boot"}});return"ADB_TRANSPORT_UNAVAILABLE"!==t&&"ANDROID_BOOT_TIMEOUT"!==t}},{deadline:a,phase:"boot",classifyReason:e=>rR({error:e,stdout:n?.stdout,stderr:n?.stderr,context:{platform:"android",phase:"boot"}})})}catch(c){let r=w(c),o=n?.stdout,s=n?.stderr,l=n?.exitCode,d=rR({error:c,stdout:o,stderr:s,context:{platform:"android",phase:"boot"}});"BOOT_COMMAND_FAILED"===d&&"Android device is still booting"===r.message&&(d="ANDROID_BOOT_TIMEOUT");let u={serial:e,timeoutMs:t,elapsedMs:a.elapsedMs(),reason:d,hint:rP(d),stdout:o,stderr:s,exitCode:l};if(i||"ANDROID_BOOT_TIMEOUT"===d)throw new y("COMMAND_FAILED","Android device did not finish booting in time",u);if("TOOL_MISSING"===r.code)throw new y("TOOL_MISSING",r.message,{...u,...r.details??{}});if("ADB_TRANSPORT_UNAVAILABLE"===d)throw new y("COMMAND_FAILED",r.message,{...u,...r.details??{}});throw new y(r.code,r.message,{...u,...r.details??{}},r.cause)}}let oW=/\.(?:apk|aab)$/i,oX=/^[A-Za-z_][\w]*(\.[A-Za-z_][\w]*)+$/;function oH(e){var t,n;let a=e.trim();return 0===a.length?"other":oW.test(a)?a.includes("/")||a.includes("\\")||a.startsWith(".")||a.startsWith("~")||(t=a,!oX.test(t))?"binary":"package":(n=a,oX.test(n))?"package":"other"}function oz(e){return`Android runtime hints require an installed package name, not "${e}". Install or reinstall the app first, then relaunch by package.`}async function oY(e,t){let n="url"===e.kind&&ek(e.url),a=await eM({source:e,isInstallablePath:(e,t)=>{var n;let a;return t.isFile()&&(n=e,".apk"===(a=o.extname(n).toLowerCase())||".aab"===a)},installableLabel:"Android installable (.apk or .aab)",allowArchiveExtraction:"url"!==e.kind||n,signal:t?.signal}),r=t?.resolveIdentity===!1?{}:await oK(a.installablePath);return{archivePath:a.archivePath,installablePath:a.installablePath,packageName:r.packageName,cleanup:a.cleanup}}async function oK(e){let t=o.extname(e).toLowerCase();return".apk"!==t&&".aab"!==t?{}:{packageName:await e_(e)}}let oJ={settings:{type:"intent",value:"android.settings.SETTINGS"}},oZ="android.intent.category.LAUNCHER",oQ="android.intent.category.LEANBACK_LAUNCHER",o0="android.intent.category.DEFAULT",o1="Run agent-device apps --platform android to discover the installed package name, then retry open with that exact package.",o2=oA();function o3(e){return{platform:"android",deviceId:e.id,variant:e.target??""}}async function o4(e,t){let n=t.trim();if("package"===oH(n))return{type:"package",value:n};let a=oJ[n.toLowerCase()];if(a)return a;let r=o3(e),i=o2.get(r,n);if(i)return i;let o=(await ef("adb",og(e,["shell","pm","list","packages"]))).stdout.split("\n").map(e=>e.replace("package:","").trim()).filter(Boolean).filter(e=>e.toLowerCase().includes(n.toLowerCase()));if(1===o.length)return o2.set(r,n,{type:"package",value:o[0]});if(o.length>1)throw new y("INVALID_ARGS",`Multiple packages matched "${t}"`,{matches:o,hint:"Run agent-device apps --platform android to see the exact installed package names before retrying open."});throw new y("APP_NOT_INSTALLED",`No package found matching "${t}"`,{hint:o1})}async function o5(e,t="all"){let n=await o8(e);return("user-installed"===t?(await o9(e)).filter(e=>n.has(e)):Array.from(n)).sort((e,t)=>e.localeCompare(t)).map(e=>({package:e,name:o7(e)}))}async function o8(e){let t=new Set;for(let n of o6(e,{includeFallbackWhenUnknown:!0})){let a=await ef("adb",og(e,["shell","cmd","package","query-activities","--brief","-a","android.intent.action.MAIN","-c",n]),{allowFailure:!0});if(0===a.exitCode&&0!==a.stdout.trim().length)for(let e of eE(a.stdout))t.add(e)}return t}function o6(e,t={}){return"tv"===e.target?[oQ]:"mobile"===e.target?[oZ]:t.includeFallbackWhenUnknown?[oZ,oQ]:[oZ]}async function o9(e){return eO((await ef("adb",og(e,["shell","pm","list","packages","-3"]))).stdout)}function o7(e){let t=new Set(["com","android","google","app","apps","service","services","mobile","client"]),n=e.split(".").flatMap(e=>e.split(/[_-]+/)).map(e=>e.trim().toLowerCase()).filter(e=>e.length>0),a=n[n.length-1]??e;for(let e=n.length-1;e>=0;e-=1){let r=n[e];if(!t.has(r)){a=r;break}}return a.split(/[^a-z0-9]+/i).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(" ")}async function se(e){let t=await st(e,[["shell","dumpsys","window","windows"],["shell","dumpsys","window"]]);if(t)return t;let n=await st(e,[["shell","dumpsys","activity","activities"],["shell","dumpsys","activity"]]);return n||{}}async function st(e,t){for(let n of t){let t=eD((await ef("adb",og(e,n),{allowFailure:!0})).stdout??"");if(t)return t}return null}async function sn(e,t,n){var a,r;let i;e.booted||await oq(e.id);let o=t.trim();if(ov(o)){if(n)throw new y("INVALID_ARGS","Activity override is not supported when opening a deep link URL");await ef("adb",og(e,["shell","am","start","-W","-a","android.intent.action.VIEW","-d",o]));return}let s=await o4(e,t),l=o6(e)[0]??oZ;if("intent"===s.type){if(n)throw new y("INVALID_ARGS","Activity override requires a package name, not an intent");await ef("adb",og(e,["shell","am","start","-W","-a",s.value]));return}if(n){let t=n.includes("/")?n:`${s.value}/${n.startsWith(".")?n:`.${n}`}`;try{await ef("adb",og(e,["shell","am","start","-W","-a","android.intent.action.MAIN","-c",o0,"-c",l,"-n",t]))}catch(t){throw await si(e,s.value,t),t}return}let d=await ef("adb",og(e,["shell","am","start","-W","-a","android.intent.action.MAIN","-c",o0,"-c",l,"-p",s.value]),{allowFailure:!0});if(0===d.exitCode&&(a=d.stdout,r=d.stderr,i=`${a}
|
|
11
|
-
${
|
|
12
|
-
${n
|
|
13
|
-
${
|
|
14
|
-
${a.stderr}`.toLowerCase();if(!e.includes("unknown package")&&!e.includes("not installed"))throw new y("COMMAND_FAILED",`adb uninstall failed for ${n.value}`,{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode})}return{package:n.value}}let sc=null;async function sp(){let e=`${process.env.PATH??""}::${process.env.AGENT_DEVICE_BUNDLETOOL_JAR??""}`;if(sc?.key===e)return sc.invocation;if(await em("bundletool")){let t={cmd:"bundletool",prefixArgs:[]};return sc={key:e,invocation:t},t}let t=await eh(process.env.AGENT_DEVICE_BUNDLETOOL_JAR,"AGENT_DEVICE_BUNDLETOOL_JAR");if(!t)throw new y("TOOL_MISSING","bundletool not found in PATH. Install bundletool or set AGENT_DEVICE_BUNDLETOOL_JAR to a bundletool-all.jar path.");let n={cmd:"java",prefixArgs:["-jar",t]};return sc={key:e,invocation:n},n}async function sf(e){let t=await sp();await ef(t.cmd,[...t.prefixArgs,...e])}async function sh(e,t){let n,a=await r.mkdtemp(o.join(s.tmpdir(),"agent-device-aab-")),i=o.join(a,"bundle.apks"),l=(n=process.env.AGENT_DEVICE_ANDROID_BUNDLETOOL_MODE?.trim())&&n.length>0?n:"universal";try{await sf(["build-apks","--bundle",t,"--output",i,"--mode",l]),await sf(["install-apks","--apks",i,"--device-id",e.id])}finally{await r.rm(a,{recursive:!0,force:!0})}}async function sm(e,t){".aab"===o.extname(t).toLowerCase()?await sh(e,t):await ef("adb",og(e,["install","-r",t]))}async function sw(e){return new Set((await ef("adb",og(e,["shell","pm","list","packages"]))).stdout.split("\n").map(e=>e.replace("package:","").trim()).filter(Boolean))}async function sg(e,t){let n=Array.from(await sw(e)).filter(e=>!t.has(e));if(1===n.length)return n[0]}async function sy(e,t){await o2.invalidateWhile(o3(e),async()=>{e.booted||await oq(e.id),await sm(e,t)})}async function sb(e,t,n){let a=n?void 0:await sw(e);return await sy(e,t),n??(a?await sg(e,a):void 0)}async function sv(e,t){e.booted||await oq(e.id);let n=await oY({kind:"path",path:t});try{let t=await sb(e,n.installablePath,n.packageName),a=t?o7(t):void 0;return{archivePath:n.archivePath,installablePath:n.installablePath,packageName:t,appName:a,launchTarget:t}}finally{await n.cleanup()}}async function sI(e,t,n){return await o2.invalidateWhile(o3(e),async()=>{e.booted||await oq(e.id);let{package:a}=await su(e,t),r=await oY({kind:"path",path:n},{resolveIdentity:!1});try{await sy(e,r.installablePath)}finally{await r.cleanup()}return{package:a}})}function sA(e){let t=e.direction,n="up"===t||"down"===t?e.referenceHeight:e.referenceWidth,a=function(e){if(void 0===e)return .6;if(!Number.isFinite(e)||e<=0)throw new y("INVALID_ARGS","scroll amount must be a positive number");return e}(e.amount),r=void 0!==e.pixels?function(e){if(!Number.isFinite(e)||e<=0)throw new y("INVALID_ARGS","scroll pixels must be a positive integer");return Math.max(1,Math.round(e))}(e.pixels):Math.round(n*a),i=Math.max(1,Math.round(.05*n)),o=Math.max(1,Math.min(r,Math.max(1,n-2*i))),s=Math.round(o/2),l=Math.round(e.referenceWidth/2),d=Math.round(e.referenceHeight/2),u=(n,a,r,i)=>({direction:t,x1:n,y1:a,x2:r,y2:i,referenceWidth:e.referenceWidth,referenceHeight:e.referenceHeight,amount:e.amount,pixels:o});switch(t){case"up":return u(l,d-s,l,d+s);case"down":return u(l,d+s,l,d-s);case"left":return u(l-s,d,l+s,d);case"right":return u(l+s,d,l-s,d)}}function sx(e){if(0===e.length)return null;let t=[...e].sort((e,t)=>e-t);return t[Math.floor(t.length/2)]??null}function sS(e,t){let n=Math.max(24,Math.round(.2*Math.min(e.size,t.size))),a=Math.max(48,Math.round(.15*Math.min(e.crossSize,t.crossSize)));return Math.abs(e.size-t.size)<=n&&Math.abs(e.crossSize-t.crossSize)<=a}function sN(e,t){return{start:e.y-t.y,size:e.height,crossSize:e.width}}async function s_(e,t={}){let n=await sM(e,t),a=n.xml;if(!t.interactiveOnly){let r=W(a,800,t);return function(e,t){for(let[n,a]of e){let e=t[n];e&&(a.hiddenContentAbove&&(e.hiddenContentAbove=!0),a.hiddenContentBelow&&(e.hiddenContentBelow=!0))}}(await sE(e,r.nodes),r.nodes),{...r,androidSnapshot:n.metadata}}let r=H(a),i=et(r,800,{...t,interactiveOnly:!1}),o=et(r,800,t),s=await sE(e,i.nodes);sL(s,i,o),0===s.size&&sL(function(e){if(0===e.length)return new Map;let{hintedContainers:t}=e6(e);var n=t.directionsByContainer;let a=new Map;for(let[e,t]of n){let n={};t.has("above")&&(n.hiddenContentAbove=!0),t.has("below")&&(n.hiddenContentBelow=!0),(n.hiddenContentAbove||n.hiddenContentBelow)&&a.set(e,n)}return a}(q(i.nodes)),i,o);let{sourceNodes:l,...d}=o;return{...d,androidSnapshot:n.metadata}}async function sM(e,t){let n=await sk(t.helperArtifact);if(n.artifact){var a,r;let i=(a=e,`${a.platform}:${a.id}`);try{let a=t.helperAdb??(r=e,async(e,t)=>await ef("adb",og(r,e),t)),o=await X({adb:a,artifact:n.artifact,deviceKey:i,installPolicy:t.helperInstallPolicy,timeoutMs:3e4}),s=await Y({adb:a,packageName:n.artifact.manifest.packageName,instrumentationRunner:n.artifact.manifest.instrumentationRunner,waitForIdleTimeoutMs:500,timeoutMs:8e3,commandTimeoutMs:13e3});return{xml:s.xml,metadata:{backend:"android-helper",helperVersion:n.artifact.manifest.version,helperApiVersion:s.metadata.helperApiVersion,installReason:o.reason,waitForIdleTimeoutMs:s.metadata.waitForIdleTimeoutMs,timeoutMs:s.metadata.timeoutMs,maxDepth:s.metadata.maxDepth,maxNodes:s.metadata.maxNodes,rootPresent:s.metadata.rootPresent,captureMode:s.metadata.captureMode,windowCount:s.metadata.windowCount,nodeCount:s.metadata.nodeCount,helperTruncated:s.metadata.truncated,elapsedMs:s.metadata.elapsedMs}}}catch(t){return Q({deviceKey:i,packageName:n.artifact.manifest.packageName,versionCode:n.artifact.manifest.versionCode}),await sD(e,g(t).message)}}return await sD(e,n.fallbackReason)}async function sk(e){if(e)return{artifact:e};let t=en(),n=o.join(ea(),"android-snapshot-helper","dist"),a=o.join(n,`agent-device-android-snapshot-helper-${t}.manifest.json`);try{await h.access(a)}catch{return{}}try{let e=Z(JSON.parse(await h.readFile(a,"utf8"))),t=o.join(n,e.assetName??`agent-device-android-snapshot-helper-${e.version}.apk`);return await h.access(t),{artifact:{apkPath:t,manifest:e}}}catch(e){return{fallbackReason:g(e).message}}}async function sD(e,t){return{xml:await sO(e),metadata:{backend:"uiautomator-dump",...t?{fallbackReason:t}:{}}}}async function sE(e,t){if(!t.some(e=>ee(e.type)))return new Map;let n=await sT(e);return n?function(e,t){let n=function(e){let t={className:"root",rect:{x:0,y:0,width:0,height:0},children:[]},n=[{indent:-1,node:t}],a=/^(\s*)([\w.$]+)\{[^}]* (-?\d+),(-?\d+)-(-?\d+),(-?\d+) #/;for(let t of e.split("\n")){let e=a.exec(t);if(!e)continue;let r=e[1].length,i=Number(e[3]),o=Number(e[4]),s=Number(e[5]),l=Number(e[6]),d={className:e[2],rect:{x:i,y:o,width:Math.max(0,s-i),height:Math.max(0,l-o)},children:[]};for(;n.length>1&&r<=n[n.length-1].indent;)n.pop();n[n.length-1].node.children.push(d),n.push({indent:r,node:d})}return t.children.length>0?t:null}(t);if(!n)return new Map;let a=function(e){let t=[],n=[e];for(;n.length>0;){let e=n.pop();if(ee(e.className)){let n=function(e){let t=e.children[0];if(!t)return null;let n=Math.max(t.rect.height,...t.children.map(e=>e.rect.y+e.rect.height)),a=t.children.filter(e=>e.rect.height>0).map(t=>sN(t.rect,e.rect)).sort((e,t)=>e.start-t.start);return 0===a.length?null:{rect:e.rect,contentExtent:n,contentBlocks:a}}(e);n&&t.push(n)}n.push(...e.children)}return t}(n);if(0===a.length)return new Map;let r=new Map;for(let t of e){if(!t.rect||!ee(t.type))continue;let n=function(e,t){let n=null,a=1/0;for(let r of t){let t=Math.abs(r.rect.width-e.width)+Math.abs(r.rect.height-e.height);if(t>32)continue;let i=4*t+(Math.abs(r.rect.x-e.x)+Math.abs(r.rect.y-e.y));i<a&&(n=r,a=i)}return n}(t.rect,a);if(!n)continue;let i=function(e,t){let n=function(e,t){let n=t,a=new Set;for(;!a.has(n.index);){var r,i;a.add(n.index);let o=e.filter(e=>e.parentIndex===n.index&&e.rect);if(1!==o.length)return n;let s=o[0];if(r=s.rect,i=t.rect,r.x!==i.x||r.y!==i.y||r.width!==i.width||r.height!==i.height)return n;n=s}return t}(e,t);return e.filter(e=>e.parentIndex===n.index&&e.rect).map(e=>e.rect).filter(e=>e.height>0).sort((e,t)=>e.y-t.y).map(e=>sN(e,t.rect))}(e,t),o=function(e){let{viewportRect:t,visibleBlocks:n,nativeScrollView:a}=e;if(0===n.length||0===a.contentBlocks.length)return null;let r=function(e){if(0===e.contentBlocks.length)return null;let t=e.contentBlocks[0],n=e.contentBlocks[e.contentBlocks.length-1];if(!t||!n)return null;let a=sx(e.contentBlocks.map(e=>e.size))??e.rect.height,r=Math.max(48,Math.round(.5*a)),i=Math.max(24,Math.round(.25*a)),o=t.start>=r,s=e.contentExtent-(n.start+n.size)>=i;return o||s?{above:o,below:s}:null}(a),i=function(e,t){let n=new Map;for(let a of e)for(let e of t){if(!sS(a,e))continue;let t=a.start-e.start,r=8*Math.round(t/8),i=n.get(r)??[];i.push(t),n.set(r,i)}let a=null;for(let e of n.values())(!a||e.length>a.length)&&(a=e);if(!a||a.length<2)return null;let r=[...a].sort((e,t)=>e-t);return r[Math.floor(r.length/2)]??null}(a.contentBlocks,n)??function(e){let{nativeBlocks:t,visibleBlocks:n,viewportExtent:a,contentExtent:r}=e,i=[],o=[];for(let e of t)for(let t of n){if(!sS(e,t))continue;let n=e.start-t.start;16>=Math.abs(n)&&i.push(n),16>=Math.abs(n+a-r)&&o.push(n)}return o.length>0?sx(o):i.length>0?sx(i):null}({nativeBlocks:a.contentBlocks,visibleBlocks:n,viewportExtent:t.height,contentExtent:a.contentExtent});if(null===i)return r;let o=t.height;return{above:(r?.above??!1)||i>16,below:(r?.below??!1)||i+o<a.contentExtent-16}}({viewportRect:t.rect,visibleBlocks:i,nativeScrollView:n});if(!o)continue;let s={};o.above&&(s.hiddenContentAbove=!0),o.below&&(s.hiddenContentBelow=!0),(s.hiddenContentAbove||s.hiddenContentBelow)&&r.set(t.index,s)}return r}(t,n):new Map}async function sO(e){try{return await rb(()=>sC(e),{shouldRetry:sP})}catch(e){if(function(e){if(!(e instanceof y)||"COMMAND_FAILED"!==e.code||"number"!=typeof e.details?.timeoutMs)return!1;let t=e.details?.cmd,n=e.details?.args,a=Array.isArray(n)?n.map(String):"string"==typeof n?n.split(/\s+/):[];return"adb"===t&&a.includes("uiautomator")&&a.includes("dump")}(e)){let t="If the app has looping animations, use screenshot as visual truth, try settings animations off, then retry snapshot. Stock Android UIAutomator may still time out on app-owned infinite animations.";throw new y("COMMAND_FAILED",`Android UI hierarchy dump timed out while waiting for the UI to become idle. ${t}`,{...e.details??{},hint:t},e)}throw e}}async function sC(e){var t,n,a;let r,i,o=await ef("adb",og(e,["exec-out","uiautomator","dump","/dev/tty"]),{allowFailure:!0,timeoutMs:8e3}),s=sR(o.stdout,o.stderr);if(s)return s;let l="/sdcard/window_dump.xml",d=await ef("adb",og(e,["shell","uiautomator","dump",l]),{allowFailure:!0,timeoutMs:8e3}),u=(t=l,n=d.stdout,a=d.stderr,r=`${n}
|
|
15
|
-
${a}`,i=/dumped to:\s*(\S+)/i.exec(r),i?.[1]??t),c=await ef("adb",og(e,["shell","cat",u])),p=sR(c.stdout,c.stderr);if(!p)throw new y("COMMAND_FAILED","uiautomator dump did not return XML",{stdout:c.stdout,stderr:c.stderr});return p}function sR(e,t){let n=`${e}
|
|
16
|
-
${t}`,a=n.indexOf("<?xml"),r=a>=0?a:n.indexOf("<hierarchy");if(r<0)return null;let i=n.lastIndexOf("</hierarchy>");if(i<0||i<r)return null;let o=n.slice(r,i+12).trim();return o.length>0?o:null}function sP(e){if(!(e instanceof y)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details?.stderr,n=("string"==typeof t?t:"").toLowerCase();return!!(n.includes("device offline")||n.includes("device not found")||n.includes("transport error")||n.includes("connection reset")||n.includes("broken pipe")||n.includes("timed out")||n.includes("no such file or directory"))}async function sT(e){try{let t=await ef("adb",og(e,["shell","dumpsys","activity","top"]),{allowFailure:!0,timeoutMs:8e3}),n=`${t.stdout}
|
|
17
|
-
${t.stderr}`.trim();return n.length>0?n:null}catch{return null}}function sL(e,t,n){if(0===e.size)return;let a=new Map;for(let[e,t]of n.sourceNodes.entries()){let r=n.nodes[e];r&&a.set(t,r)}for(let[n,r]of e){let e=t.sourceNodes[n];if(!e)continue;let i=a.get(e);i&&(r.hiddenContentAbove&&(i.hiddenContentAbove=!0),r.hiddenContentBelow&&(i.hiddenContentBelow=!0))}}async function s$(e,t,n){await ef("adb",og(e,["shell","input","tap",String(t),String(n)]))}async function sF(e,t,n,a,r,i=250){await ef("adb",og(e,["shell","input","swipe",String(t),String(n),String(a),String(r),String(i)]))}async function sU(e){await ef("adb",og(e,["shell","input","keyevent","4"]))}async function sG(e){await ef("adb",og(e,["shell","input","keyevent","3"]))}async function sV(e,t){let n=function(e){switch(e){case"portrait":return"0";case"landscape-left":return"1";case"portrait-upside-down":return"2";case"landscape-right":return"3";default:throw new y("INVALID_ARGS",`Unsupported Android rotation: ${e}`)}}(t);await ef("adb",og(e,["shell","settings","put","system","accelerometer_rotation","0"])),await ef("adb",og(e,["shell","settings","put","system","user_rotation",n]))}async function sB(e){await ef("adb",og(e,["shell","input","keyevent","187"]))}async function sj(e,t,n,a=800){await ef("adb",og(e,["shell","input","swipe",String(t),String(n),String(t),String(n),String(a)]))}async function sq(e,t,n=0){n>0&&Array.from(t).length>1?await sZ(e,t,1,n):await sW(e,t)}async function sW(e,t){let n=sQ(t);if(!n||"ok"!==await s0(e,t))try{let n=t.replace(/ /g,"%s");await ef("adb",og(e,["shell","input","text",n]))}catch(e){if(n&&function(e){if(!(e instanceof y)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details?.stderr,n=("string"==typeof t?t:"").toLowerCase();return!!(n.includes("exception occurred while executing 'text'")||n.includes("nullpointerexception")&&n.includes("inputshellcommand.sendtext"))}(e))throw new y("COMMAND_FAILED","Non-ASCII text input is not supported on this Android shell. Install an ADB keyboard IME or use ASCII input.",{textPreview:t.slice(0,32)},e instanceof Error?e:void 0);throw e}}async function sX(e,t,n){await s$(e,t,n)}async function sH(e,t,n,a,r=0){let i=Array.from(a).length,o=sQ(a),s=[{strategy:"input_text",clearPadding:12,minClear:8,maxClear:48}];!o&&r<=0&&s.push({strategy:"clipboard_paste",clearPadding:12,minClear:8,maxClear:48}),(!o||r>0)&&s.push({strategy:"chunked_input",clearPadding:24,minClear:16,maxClear:96});let l=null;for(let o of s){var d,u;await sX(e,t,n);let s=(d=i+o.clearPadding,u=o.minClear,Math.max(u,Math.min(o.maxClear,d)));if(await s1(e,s),"input_text"===o.strategy)await sq(e,a,r);else if("clipboard_paste"===o.strategy){if("ok"!==await s0(e,a))continue}else await sZ(e,a,1,r>0?r:15);let c=await sz(e,t,n,a);if(l=c.actual,c.ok)return}throw new y("COMMAND_FAILED","Android fill verification failed",{expected:a,actual:l??null})}async function sz(e,t,n,a){let r=null;for(let i of[0,150,350])if(i>0&&await eb(i),function(e,t){if(e===t)return!0;let n=sY(e),a=sY(t);return!!n&&!!a&&(!!(n===a||n.includes(a))||a.includes(n)&&n.length>=Math.max(4,Math.floor(.8*a.length)))}(r=await s2(e,t,n),a))return{ok:!0,actual:r};return{ok:!1,actual:r}}function sY(e){return(e??"").replace(/\s+/g," ").trim()}async function sK(e,t,n){let a=await sJ(e),r=sA({direction:t,amount:n?.amount,pixels:n?.pixels,referenceWidth:a.width,referenceHeight:a.height});return await ef("adb",og(e,["shell","input","swipe",String(r.x1),String(r.y1),String(r.x2),String(r.y2),"300"])),r}async function sJ(e){let t=(await ef("adb",og(e,["shell","wm","size"]))).stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(!t)throw new y("COMMAND_FAILED","Unable to read screen size");return{width:Number(t[1]),height:Number(t[2])}}async function sZ(e,t,n,a){let r=Math.max(1,Math.floor(n)),i=Array.from(t);for(let t=0;t<i.length;t+=r){let n=i.slice(t,t+r).join("");await sW(e,n),a>0&&t+r<i.length&&await eb(a)}}function sQ(e){for(let t of e){let e=t.codePointAt(0);if(void 0!==e&&(e<32||e>126))return!0}return!1}async function s0(e,t){let n=await ef("adb",og(e,["shell","cmd","clipboard","set","text",t]),{allowFailure:!0});return 0!==n.exitCode?"failed":ob(n.stdout,n.stderr)?"unsupported":0===(await ef("adb",og(e,["shell","input","keyevent","KEYCODE_PASTE"]),{allowFailure:!0})).exitCode||0===(await ef("adb",og(e,["shell","input","keyevent","279"]),{allowFailure:!0})).exitCode?"ok":"failed"}async function s1(e,t){let n=Math.max(0,t);await ef("adb",og(e,["shell","input","keyevent","KEYCODE_MOVE_END"]),{allowFailure:!0});for(let t=0;t<n;t+=24){let a=Math.min(24,n-t);await ef("adb",og(e,["shell","input","keyevent",...Array(a).fill("KEYCODE_DEL")]),{allowFailure:!0})}}async function s2(e,t,n){let a,r=await sO(e),i=/<node\b[^>]*>/g,o=null,s=null,l=null;for(;null!==(a=i.exec(r));){let e=z(a[0]),r=K(e.bounds);if(!r)continue;let i=e.className??"",d=(e.text??"").replace(/"/g,'"').replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">").replace(/&/g,"&"),u=e.focused??!1;if(!d)continue;let c=Math.max(1,r.width*r.height),p=t>=r.x&&t<=r.x+r.width&&n>=r.y&&n<=r.y+r.height;if(u&&s3(i)){(!o||c<=o.area)&&(o={text:d,area:c});continue}if(p&&s3(i)){(!s||c<=s.area)&&(s={text:d,area:c});continue}p&&(!l||c<=l.area)&&(l={text:d,area:c})}return o?.text??s?.text??l?.text??null}function s3(e){let t=e.toLowerCase();return t.includes("edittext")||t.includes("textfield")}async function s4(e){let t=await ef("adb",og(e,["shell","dumpsys","input_method"]),{allowFailure:!0});if(0!==t.exitCode)throw new y("COMMAND_FAILED","Failed to query Android keyboard state",{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode});return function(e){let t=function(e){let t=new Map;for(let n of e.matchAll(/\b(mInputShown|mIsInputViewShown|isInputViewShown)=([a-zA-Z]+)\b/g)){let e=n[1],a=n[2]?.toLowerCase();e&&("true"===a||"false"===a)&&t.set(e,"true"===a)}if(0===t.size)return null;for(let e of t.values())if(e)return!0;return!1}(e),n=t??!1;if(null===t){let t=e.match(/\bmImeWindowVis=0x([0-9a-fA-F]+)\b/);if(t?.[1]){let e=Number.parseInt(t[1],16);Number.isNaN(e)||(n=(1&e)!=0)}}let a=Array.from(e.matchAll(/\binputType=0x([0-9a-fA-F]+)\b/gi)),r=a.length>0?a[a.length-1]?.[1]:void 0,i=r?`0x${r.toLowerCase()}`:void 0;return{visible:n,inputType:i,type:i?function(e){let t=Number.parseInt(e.replace(/^0x/i,""),16);if(Number.isNaN(t))return"unknown";let n=15&t;if(2===n)return"number";if(3===n)return"phone";if(4===n)return"datetime";if(1!==n)return"unknown";let a=4080&t;return 32===a||208===a?"email":128===a||224===a||144===a?"password":"text"}(i):void 0}}(t.stdout)}async function s5(e){let t=await s4(e),n=t,a=0;for(;n.visible&&a<2;)await ef("adb",og(e,["shell","input","keyevent","111"])),a+=1,await eb(120),n=await s4(e);if(t.visible&&n.visible)throw new y("UNSUPPORTED_OPERATION","Android keyboard dismiss is unavailable for the current IME without back navigation.",{attempts:a,inputType:n.inputType,type:n.type});return{attempts:a,wasVisible:t.visible,dismissed:t.visible&&!n.visible,visible:n.visible,inputType:n.inputType,type:n.type}}async function s8(e){let t,n;return(n=(t=(await s9(e,["shell","cmd","clipboard","get","text"],"read")).replace(/\r\n/g,"\n").replace(/\n$/,"")).match(/^clipboard text:\s*(.*)$/i))?n[1]??"":"null"===t.trim().toLowerCase()?"":t}async function s6(e,t){await s9(e,["shell","cmd","clipboard","set","text",t],"write")}async function s9(e,t,n){let a=await ef("adb",og(e,t),{allowFailure:!0});if(ob(a.stdout,a.stderr))throw new y("UNSUPPORTED_OPERATION",`Android shell clipboard ${n} is not supported on this device.`);if(0!==a.exitCode)throw new y("COMMAND_FAILED",`Failed to ${n} Android clipboard text`,{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});return a.stdout}let s7=["camera","microphone","photos","contacts","contacts-limited","notifications","calendar","location","location-always","media-library","motion","reminders","siri"];function le(e){let t=e.trim().toLowerCase();if("grant"===t)return"grant";if("deny"===t)return"deny";if("reset"===t)return"reset";throw new y("INVALID_ARGS",`Invalid permission action: ${e}. Use grant|deny|reset.`)}function lt(e){let t=e?.trim().toLowerCase();if("camera"===t||"microphone"===t||"photos"===t||"contacts"===t||"contacts-limited"===t||"notifications"===t||"calendar"===t||"location"===t||"location-always"===t||"media-library"===t||"motion"===t||"reminders"===t||"siri"===t)return t;throw new y("INVALID_ARGS",`permission setting requires a target: ${s7.join("|")}`)}function ln(e){let t=e.trim().toLowerCase();if("light"===t)return"light";if("dark"===t)return"dark";if("toggle"===t)return"toggle";throw new y("INVALID_ARGS",`Invalid appearance state: ${e}. Use light|dark|toggle.`)}let la=["window_animation_scale","transition_animation_scale","animator_duration_scale"];async function lr(e,t,n,a,r){switch(t.toLowerCase()){case"wifi":{let t=lo(n);await ef("adb",og(e,["shell","svc","wifi",t?"enable":"disable"]));return}case"airplane":{let t=lo(n);await ef("adb",og(e,["shell","settings","put","global","airplane_mode_on",t?"1":"0"])),await ef("adb",og(e,["shell","am","broadcast","-a","android.intent.action.AIRPLANE_MODE","--ez","state",t?"true":"false"]));return}case"location":{let t=lo(n);await ef("adb",og(e,["shell","settings","put","secure","location_mode",t?"3":"0"]));return}case"animations":{let t=lo(n)?"1":"0";for(let n of la)await ef("adb",og(e,["shell","settings","put","global",n,t]));return{scale:t,keys:[...la]}}case"appearance":{let t=await ls(e,n);await ef("adb",og(e,["shell","cmd","uimode","night","dark"===t?"yes":"no"]));return}case"fingerprint":{let t=function(e){let t=e.trim().toLowerCase();if("match"===t)return"match";if("nonmatch"===t)return"nonmatch";throw new y("INVALID_ARGS",`Invalid fingerprint state: ${e}. Use match|nonmatch.`)}(n);await li(e,t);return}case"permission":{if(!a)throw new y("INVALID_ARGS","permission setting requires an active app in session");let t=le(n),i=function(e,t){let n=lt(e);if(t?.trim())throw new y("INVALID_ARGS",`Permission mode is only supported for photos. Received: ${t}.`);if("camera"===n)return{kind:"pm",value:"android.permission.CAMERA",type:"camera"};if("microphone"===n)return{kind:"pm",value:"android.permission.RECORD_AUDIO",type:"microphone"};if("photos"===n)return{kind:"pm",value:"android.permission.READ_MEDIA_IMAGES",type:"photos"};if("contacts"===n)return{kind:"pm",value:"android.permission.READ_CONTACTS",type:"contacts"};if("notifications"===n)return{kind:"notifications",appOps:"POST_NOTIFICATION",permission:"android.permission.POST_NOTIFICATIONS"};throw new y("INVALID_ARGS",`Unsupported permission target on Android: ${e}. Use camera|microphone|photos|contacts|notifications.`)}(r?.permissionTarget,r?.permissionMode);if("notifications"===i.kind)return void await ld(e,a,t,i);let o="grant"===t?"grant":"revoke";if("photos"===i.type)return void await ll(e,a,o);await ef("adb",og(e,["shell","pm",o,a,i.value]));return}default:throw new y("INVALID_ARGS",`Unsupported setting: ${t}`)}}async function li(e,t){var n;let a,r,i=(n=e,r=[["shell","cmd","fingerprint","touch",a="match"===t?"1":"9999"],["shell","cmd","fingerprint","finger",a]],"emulator"===n.kind&&r.push(["emu","finger","touch",a]),r),o=[];for(let t of i){let n=await ef("adb",og(e,t),{allowFailure:!0});if(0===n.exitCode)return;o.push({args:t,stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode})}let s=o.map(e=>({args:e.args.join(" "),exitCode:e.exitCode,stderr:e.stderr.slice(0,400)}));if(o.length>0&&o.every(e=>{var t,n;let a;return t=e.stdout,n=e.stderr,(a=`${t}
|
|
18
|
-
${n}`.toLowerCase()).includes("unknown command")||a.includes("can't find service: fingerprint")||a.includes("service fingerprint was not found")||a.includes("fingerprint cmd unavailable")||a.includes("emu command is not supported")||a.includes("emulator console is not running")||a.includes("fingerprint")&&a.includes("not found")}))throw new y("UNSUPPORTED_OPERATION","Android fingerprint simulation is not supported on this target/runtime.",{deviceId:e.id,action:t,hint:"Use an Android emulator with biometric support, or a device/runtime that exposes cmd fingerprint.",attempts:s});throw new y("COMMAND_FAILED","Failed to simulate Android fingerprint.",{deviceId:e.id,action:t,attempts:s})}function lo(e){let t=e.toLowerCase();if("on"===t||"true"===t||"1"===t)return!0;if("off"===t||"false"===t||"0"===t)return!1;throw new y("INVALID_ARGS",`Invalid setting state: ${e}`)}async function ls(e,t){let n=ln(t);if("toggle"!==n)return n;let a=await ef("adb",og(e,["shell","cmd","uimode","night"]),{allowFailure:!0});if(0!==a.exitCode)throw new y("COMMAND_FAILED","Failed to read current Android appearance",{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});let r=function(e,t){let n=/night mode:\s*(yes|no|auto)\b/i.exec(`${e}
|
|
19
|
-
${t}`);if(!n)return null;let a=n[1].toLowerCase();return"yes"===a?"dark":"no"===a?"light":"auto"===a?"auto":null}(a.stdout,a.stderr);if(!r)throw new y("COMMAND_FAILED","Unable to determine current Android appearance for toggle",{stdout:a.stdout,stderr:a.stderr});return"auto"===r?"dark":"dark"===r?"light":"dark"}async function ll(e,t,n){let a=await lu(e),r=[];for(let i of null!==a&&a>=33?["android.permission.READ_MEDIA_IMAGES","android.permission.READ_EXTERNAL_STORAGE"]:["android.permission.READ_EXTERNAL_STORAGE","android.permission.READ_MEDIA_IMAGES"]){let a=await ef("adb",og(e,["shell","pm",n,t,i]),{allowFailure:!0});if(0===a.exitCode)return;r.push({permission:i,stderr:a.stderr,exitCode:a.exitCode})}throw new y("COMMAND_FAILED",`Failed to ${n} Android photos permission`,{appPackage:t,sdkInt:a,attempts:r})}async function ld(e,t,n,a){"grant"===n?await ef("adb",og(e,["shell","pm","grant",t,a.permission]),{allowFailure:!0}):(await ef("adb",og(e,["shell","pm","revoke",t,a.permission]),{allowFailure:!0}),"reset"===n&&(await ef("adb",og(e,["shell","pm","clear-permission-flags",t,a.permission,"user-set"]),{allowFailure:!0}),await ef("adb",og(e,["shell","pm","clear-permission-flags",t,a.permission,"user-fixed"]),{allowFailure:!0}))),await ef("adb",og(e,["shell","appops","set",t,a.appOps,"grant"===n?"allow":"deny"===n?"deny":"default"]))}async function lu(e){let t=await ef("adb",og(e,["shell","getprop","ro.build.version.sdk"]),{allowFailure:!0});if(0!==t.exitCode)return null;let n=Number.parseInt(t.stdout.trim(),10);return!Number.isFinite(n)||n<=0?null:n}async function lc(e,t,n){let a="string"==typeof n.action&&n.action.trim()?n.action.trim():`${t}.TEST_PUSH`,r=["shell","am","broadcast","-a",a,"-p",t],i="string"==typeof n.receiver?n.receiver.trim():"";i&&r.push("-n",i);let o=n.extras;if(void 0!==o&&("object"!=typeof o||null===o||Array.isArray(o)))throw new y("INVALID_ARGS","Android push payload extras must be an object");let s=0;for(let[e,t]of Object.entries(o??{}))e&&(function(e,t,n){if("string"==typeof n)return e.push("--es",t,n);if("boolean"==typeof n)return e.push("--ez",t,n?"true":"false");if("number"==typeof n&&Number.isFinite(n))return Number.isInteger(n)?e.push("--ei",t,String(n)):e.push("--ef",t,String(n));throw new y("INVALID_ARGS",`Unsupported Android broadcast extra type for "${t}". Use string, boolean, or number.`)}(r,e,t),s+=1);return await ef("adb",og(e,r)),{action:a,extrasCount:s}}let lp=Buffer.from([137,80,78,71,13,10,26,10]);async function lf(e,t){await lh(e);try{await eb(1e3),await lw(e,t)}finally{await lm(e).catch(()=>{})}}async function lh(e){let t=t=>ef("adb",og(e,["shell",t]),{allowFailure:!0});await t("settings put global sysui_demo_allowed 1");let n=e=>t(`am broadcast -a com.android.systemui.demo -e command ${e}`);await n("clock -e hhmm 0941"),await n("notifications -e visible false")}async function lm(e){await ef("adb",og(e,["shell","am broadcast -a com.android.systemui.demo -e command exit"]),{allowFailure:!0})}async function lw(e,t){let n=await ef("adb",og(e,["exec-out","screencap","-p"]),{binaryStdout:!0});if(!n.stdoutBuffer)throw new y("COMMAND_FAILED","Failed to capture screenshot");let a=n.stdoutBuffer.indexOf(lp);if(a<0)throw new y("COMMAND_FAILED","Screenshot data does not contain a valid PNG header");let i=function(e,t){let n=t+lp.length;for(;n+8<=e.length;){let t=e.readUInt32BE(n),a=n+4,r=e.toString("ascii",a,a+4),i=n+12+t;if(i>e.length)break;if("IEND"===r)return i;n=i}return null}(n.stdoutBuffer,a);if(!i)throw new y("COMMAND_FAILED","Screenshot data does not contain a complete PNG payload");await r.writeFile(t,n.stdoutBuffer.subarray(a,i))}let lg=ev(process.env.AGENT_DEVICE_IOS_BOOT_TIMEOUT_MS,rm,5e3),ly=ev(process.env.AGENT_DEVICE_IOS_SIMCTL_LIST_TIMEOUT_MS,rh,1e3),lb=ev(process.env.AGENT_DEVICE_IOS_APP_LAUNCH_TIMEOUT_MS,3e4,5e3),lv=ev(process.env.AGENT_DEVICE_IOS_DEVICECTL_TIMEOUT_MS,2e4,1e3),lI=ev(process.env.AGENT_DEVICE_IOS_SIMULATOR_FOCUS_TIMEOUT_MS,1e4,1e3),lA=ev(process.env.AGENT_DEVICE_IOS_SIMULATOR_SCREENSHOT_TIMEOUT_MS,2e4,1e3),lx=ev(process.env.AGENT_DEVICE_IOS_RUNNER_SCREENSHOT_COPY_TIMEOUT_MS,2e4,1e3),lS=rf(process.env.AGENT_DEVICE_IOS_SIMULATOR_SCREENSHOT_RUNNER_FALLBACK);async function lN(e,t){let n=["devicectl",...e],a=await ef("xcrun",n,{allowFailure:!0,timeoutMs:lv});if(0===a.exitCode)return;let r=String(a.stdout??""),i=String(a.stderr??"");throw new y("COMMAND_FAILED",`Failed to ${t.action}`,{cmd:"xcrun",args:n,exitCode:a.exitCode,stdout:r,stderr:i,deviceId:t.deviceId,hint:lD(r,i)??lk})}async function l_(e,t){let n=o.join(s.tmpdir(),`agent-device-ios-apps-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),a=["devicectl","device","info","apps","--device",e.id,"--include-all-apps","--json-output",n],i=await ef("xcrun",a,{allowFailure:!0,timeoutMs:lv});try{var l,d;if(0!==i.exitCode){let t=String(i.stdout??""),n=String(i.stderr??"");throw new y("COMMAND_FAILED","Failed to list iOS apps",{cmd:"xcrun",args:a,exitCode:i.exitCode,stdout:t,stderr:n,deviceId:e.id,hint:lD(t,n)??lk})}let o=await r.readFile(n,"utf8");return l=function(e){let t=e?.result?.apps;if(!Array.isArray(t))return[];let n=[];for(let e of t){if(!e||"object"!=typeof e)continue;let t="string"==typeof e.bundleIdentifier?e.bundleIdentifier.trim():"";if(!t)continue;let a="string"==typeof e.name&&e.name.trim().length>0?e.name.trim():t,r="string"==typeof e.url&&e.url.trim().length>0?e.url.trim():void 0;n.push({bundleId:t,name:a,url:r})}return n}(JSON.parse(o)),d=t,"user-installed"===d?l.filter(e=>!e.bundleId.startsWith("com.apple.")):l}catch(t){if(t instanceof y)throw t;throw new y("COMMAND_FAILED","Failed to parse iOS apps list",{deviceId:e.id,cause:String(t)})}finally{await r.unlink(n).catch(()=>{})}}async function lM(e){let t=o.join(s.tmpdir(),`agent-device-ios-processes-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),n=["devicectl","device","info","processes","--device",e.id,"--json-output",t],a=await ef("xcrun",n,{allowFailure:!0,timeoutMs:lv});try{if(0!==a.exitCode){let t=String(a.stdout??""),r=String(a.stderr??"");throw new y("COMMAND_FAILED","Failed to list iOS processes",{cmd:"xcrun",args:n,exitCode:a.exitCode,stdout:t,stderr:r,deviceId:e.id,hint:lD(t,r)??lk})}let i=await r.readFile(t,"utf8");return function(e){let t=e?.result?.runningProcesses;if(!Array.isArray(t))return[];let n=[];for(let e of t){if(!e||"object"!=typeof e)continue;let t="string"==typeof e.executable?e.executable.trim():"",a="number"==typeof e.processIdentifier&&Number.isFinite(e.processIdentifier)?e.processIdentifier:NaN;t&&Number.isFinite(a)&&n.push({executable:t,pid:a})}return n}(JSON.parse(i))}catch(t){if(t instanceof y)throw t;throw new y("COMMAND_FAILED","Failed to parse iOS process list",{deviceId:e.id,cause:String(t)})}finally{await r.unlink(t).catch(()=>{})}}let lk="Ensure the iOS device is unlocked, trusted, and available in Xcode > Devices, then retry.";function lD(e,t){let n=`${e}
|
|
20
|
-
${t}`.toLowerCase();return n.includes("device is busy")&&n.includes("connecting")?"iOS device is still connecting. Keep it unlocked and connected by cable until it is fully available in Xcode Devices, then retry.":n.includes("coredeviceservice")&&n.includes("timed out")?"CoreDevice service timed out. Reconnect the device and retry; if it persists restart Xcode and the iOS device.":null}function lE(e){if(!(e instanceof y)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details??{};if(4!==t.exitCode)return!1;let n=String(t.stderr??"").toLowerCase();return n.includes("fbsopenapplicationserviceerrordomain")&&n.includes("the request to open")}async function lO(e,t){let n=await ef("xcrun",rj(e,["get_app_container",e.id,t]),{allowFailure:!0});if(0!==n.exitCode)return{installed:!1};let a=n.stdout.trim();if(!a)return{installed:!1};let r=await ef("plutil",["-extract","CFBundleExecutable","raw","-o","-",`${a}/Info.plist`],{allowFailure:!0});if(0!==r.exitCode||!r.stdout.trim())return{installed:!0};let i=r.stdout.trim(),o=`${a}/${i}`,s=await ef("otool",["-l",o],{allowFailure:!0});if(0!==s.exitCode)return{installed:!0};let l=s.stdout.toLowerCase();return{installed:!0,simulatorCompatible:l.includes("iossimulator")||l.includes("platform 7")}}function lC(e,t){if("simulator"!==e.kind)throw new y("UNSUPPORTED_OPERATION",`${t} is only supported on iOS simulators`)}async function lR(){await ef("open",["-a","Simulator"],{allowFailure:!0,timeoutMs:lI})}async function lP(e){let t,n;if("simulator"!==e.kind||"Booted"===await lL(e))return;let a=rg.fromTimeoutMs(lg);try{await ry(async({deadline:a})=>{if(a?.isExpired())throw new y("COMMAND_FAILED","iOS simulator boot deadline exceeded",{timeoutMs:lg});let r=Math.max(1e3,a?.remainingMs()??lg),i=await ef("xcrun",rj(e,["boot",e.id]),{allowFailure:!0,timeoutMs:r});t={stdout:String(i.stdout??""),stderr:String(i.stderr??""),exitCode:i.exitCode};let o=`${t.stdout}
|
|
21
|
-
${t.stderr}`.toLowerCase(),s=o.includes("already booted")||o.includes("current state: booted");if(0!==t.exitCode&&!s)throw new y("COMMAND_FAILED","simctl boot failed",{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode});let l=await ef("xcrun",rj(e,["bootstatus",e.id,"-b"]),{allowFailure:!0,timeoutMs:r});if(n={stdout:String(l.stdout??""),stderr:String(l.stderr??""),exitCode:l.exitCode},0!==n.exitCode)throw new y("COMMAND_FAILED","simctl bootstatus failed",{stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode});let d=await lL(e);if("Booted"!==d)throw new y("COMMAND_FAILED","Simulator is still booting",{state:d})},{maxAttempts:3,baseDelayMs:500,maxDelayMs:2e3,jitter:.2,shouldRetry:e=>{let a=rR({error:e,stdout:n?.stdout??t?.stdout,stderr:n?.stderr??t?.stderr,context:{platform:"ios",phase:"boot"}});return"IOS_BOOT_TIMEOUT"!==a&&"CI_RESOURCE_STARVATION_SUSPECTED"!==a}},{deadline:a,phase:"boot",classifyReason:e=>rR({error:e,stdout:n?.stdout??t?.stdout,stderr:n?.stderr??t?.stderr,context:{platform:"ios",phase:"boot"}})})}catch(i){let r=rR({error:i,stdout:n?.stdout??t?.stdout,stderr:n?.stderr??t?.stderr,context:{platform:"ios",phase:"boot"}});throw new y("COMMAND_FAILED","iOS simulator failed to boot",{platform:"ios",deviceId:e.id,timeoutMs:lg,elapsedMs:a.elapsedMs(),reason:r,hint:rP(r),boot:t,bootstatus:n})}await lR()}async function lT(e){let t=rj(e,["shutdown",e.id]),n=await ef("xcrun",t,{allowFailure:!0,timeoutMs:15e3});return{success:0===n.exitCode,exitCode:n.exitCode,stdout:String(n.stdout??""),stderr:String(n.stderr??"")}}async function lL(e){let t="string"==typeof e?e:e.id,n="string"==typeof e?rB(["list","devices","-j"]):rj(e,["list","devices","-j"]),a=await ef("xcrun",n,{allowFailure:!0,timeoutMs:ly});if(0!==a.exitCode)return null;try{let e=JSON.parse(String(a.stdout??""));for(let n of Object.values(e.devices??{})){let e=n.find(e=>e.udid===t);if(e)return e.state}return null}catch{return null}}async function l$(e,t){try{let n=await ef("plutil",["-extract",t,"raw","-o","-",e],{allowFailure:!0});if(0===n.exitCode){let e=String(n.stdout??"").trim();if(e.length>0)return e}}catch{}try{var n,a;let i;return n=await r.readFile(e,"utf8"),a=t,ic(iu(n),(e,t)=>{void 0===i&&e===a&&"string"===t.name&&(i=t.text??void 0)}),i}catch{return}}async function lF(e,t){if("url"===e.kind&&!ek(e.url))throw new y("INVALID_ARGS","iOS install_from_source URL sources are only supported for trusted artifact services such as GitHub Actions and EAS. Use a path source for other hosts.");let n=await eM({source:e,isInstallablePath:(e,t)=>t.isDirectory()&&e.toLowerCase().endsWith(".app")||t.isFile()&&e.toLowerCase().endsWith(".ipa"),installableLabel:"iOS installable (.app or .ipa)",allowArchiveExtraction:"url"!==e.kind||ek(e.url),signal:t?.signal}),a=await lG(n.installablePath,t),r=await lU(a.installPath);return{archivePath:n.archivePath??(n.installablePath.toLowerCase().endsWith(".ipa")?n.installablePath:void 0),installablePath:a.installPath,bundleId:r.bundleId,appName:r.appName,cleanup:async()=>{await a.cleanup(),await n.cleanup()}}}async function lU(e){let t=o.join(e,"Info.plist"),[n,a,r]=await Promise.all([l$(t,"CFBundleIdentifier"),l$(t,"CFBundleDisplayName"),l$(t,"CFBundleName")]);return{bundleId:n,appName:a??r}}async function lG(e,t){if(!e.toLowerCase().endsWith(".ipa"))return{installPath:e,cleanup:async()=>{}};let n=await r.mkdtemp(o.join(s.tmpdir(),"agent-device-ios-ipa-")),a=async()=>{await r.rm(n,{recursive:!0,force:!0})};try{await ef("unzip",["-q",e,"-d",n]);let i=o.join(n,"Payload"),s=(await r.readdir(i,{withFileTypes:!0}).catch(()=>{throw new y("INVALID_ARGS","Invalid IPA: missing Payload directory")})).filter(e=>e.isDirectory()&&e.name.toLowerCase().endsWith(".app")).map(e=>({installPath:o.join(i,e.name),bundleName:e.name.replace(/\.app$/i,"")}));if(1===s.length)return{installPath:s[0].installPath,cleanup:a};if(0===s.length)throw new y("INVALID_ARGS","Invalid IPA: expected at least one .app under Payload, found 0");await lV(s);let l=t?.appIdentifierHint?.trim();if(l){let e=function(e,t){let n=t.toLowerCase(),a=e.filter(e=>e.bundleName.toLowerCase()===n);if(1===a.length)return a[0];if(a.length>1)throw new y("INVALID_ARGS",`Invalid IPA: multiple app bundles matched "${t}" by name. Use a bundle id hint instead.`);if(t.includes(".")){let t=e.filter(e=>e.bundleId?.toLowerCase()===n);if(1===t.length)return t[0]}}(s,l);if(e)return{installPath:e.installPath,cleanup:a};throw new y("INVALID_ARGS",`Invalid IPA: found ${s.length} .app bundles under Payload and none matched "${l}". Available bundles: ${s.map(lB).join(", ")}`)}throw new y("INVALID_ARGS",`Invalid IPA: found ${s.length} .app bundles under Payload. Pass an app identifier or bundle name matching one of: ${s.map(lB).join(", ")}`)}catch(e){throw await a(),e}}async function lV(e){await Promise.all(e.map(async e=>{if(e.bundleId&&e.appName)return;let t=await lU(e.installPath);e.bundleId=e.bundleId??t.bundleId,e.appName=e.appName??t.appName}))}function lB(e){let t=e.bundleId??e.appName;return t?`${e.bundleName}.app (${t})`:`${e.bundleName}.app`}function lj(e,t){return"user-installed"===t?e.filter(e=>!e.bundleId.startsWith("com.apple.")):e}let lq={settings:"com.apple.systempreferences"},lW=/^[a-z0-9-]+(?:\.[a-z0-9-]+)+$/,lX={platform:"macos",deviceId:"host",variant:"all"},lH=oA();function lz(e,t){let n=["-b",e];return t&&n.push(t),n}async function lY(e){for(let t of[o.join(e,"Contents","Info.plist"),o.join(e,"Info.plist")]){let[e,n,a]=await Promise.all([l$(t,"CFBundleIdentifier"),l$(t,"CFBundleDisplayName"),l$(t,"CFBundleName")]);if(e||n||a)return{bundleId:e,appName:n??a}}return{}}async function lK(e){let t=e.trim(),n=lq[t.toLowerCase()];if(n)return n;if(lW.test(t))return t;let a=lH.get(lX,t);if(a)return a;let r=(await l3("all")).filter(e=>e.name.toLowerCase()===t.toLowerCase());if(1===r.length)return lH.set(lX,t,r[0].bundleId);if(r.length>1)throw new y("INVALID_ARGS",`Multiple apps matched "${e}"`,{matches:r});throw new y("APP_NOT_INSTALLED",`No app found matching "${e}"`)}async function lJ(e,t,n){let a=n?.url?.trim();if(a){if(!ov(a))throw new y("INVALID_ARGS","open <app> <url> requires a valid URL target");let e=n?.appBundleId??await lK(t);await ef("open",lz(e,a));return}let r=t.trim();if(ov(r))return void await ef("open",[r]);let i=n?.appBundleId??await lK(r);await ef("open",lz(i))}async function lZ(e,t){let n=await lK(t),a=await ou(n);if(a.running&&!a.terminated&&!a.forceTerminated)throw new y("COMMAND_FAILED",`Failed to close macOS app ${t}`,{bundleId:n,running:a.running,terminated:a.terminated,forceTerminated:a.forceTerminated})}async function lQ(){let e=await ef("pbpaste",[],{allowFailure:!0});if(0!==e.exitCode)throw new y("COMMAND_FAILED","Failed to read macOS clipboard",{stdout:e.stdout,stderr:e.stderr,exitCode:e.exitCode});return e.stdout.replace(/\r\n/g,"\n").replace(/\n$/,"")}async function l0(e){let t=await ef("pbcopy",[],{allowFailure:!0,stdin:e});if(0!==t.exitCode)throw new y("COMMAND_FAILED","Failed to write macOS clipboard",{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode})}async function l1(){let e=await ef("osascript",["-e",'tell application "System Events" to tell appearance preferences to get dark mode'],{allowFailure:!0});if(0!==e.exitCode)throw new y("COMMAND_FAILED","Failed to read macOS appearance",{stdout:e.stdout,stderr:e.stderr,exitCode:e.exitCode});let t=e.stdout.trim().toLowerCase();if("true"===t)return!0;if("false"===t)return!1;throw new y("COMMAND_FAILED",`Unable to determine current macOS appearance from osascript output: ${e.stdout.trim()}`)}async function l2(e){let t=ln(e),n="toggle"===t?!await l1():"dark"===t,a=`tell application "System Events" to tell appearance preferences to set dark mode to ${n?"true":"false"}`,r=await ef("osascript",["-e",a],{allowFailure:!0});if(0!==r.exitCode)throw new y("COMMAND_FAILED","Failed to set macOS appearance",{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode})}async function l3(e="all"){let t=["/Applications","/System/Applications",o.join(s.homedir(),"Applications")],n=new Set;for(let e of t){let t=await r.stat(e).catch(()=>null);if(!t?.isDirectory())continue;let a=await ef("find",[e,"-maxdepth","4","-type","d","-name","*.app"],{allowFailure:!0});if(0===a.exitCode)for(let e of a.stdout.split("\n")){let t=e.trim();t&&n.add(t)}}return lj((await Promise.all(Array.from(n).map(async e=>{let t=await lY(e).catch(()=>({})),n=t.bundleId;return n?{bundleId:n,name:t.appName??o.basename(e,".app")}:null}))).filter(e=>null!==e).sort((e,t)=>e.name.localeCompare(t.name)),e)}let l4=["--time","9:41","--dataNetwork","wifi","--wifiMode","active","--wifiBars","3","--batteryState","charged","--batteryLevel","100"],l5={0:"hide",1:"wifi",6:"3g",7:"4g",8:"lte",9:"lte-a",10:"lte+",11:"5g",12:"5g+",13:"5g-uwb",14:"5g-uc"},l8={1:"searching",2:"failed",3:"active"},l6={0:"notSupported",1:"searching",2:"failed",3:"active"};function l9(e,t,n){return ef("xcrun",rj(e,t),n)}async function l7(e,t){var n,a;let r;await dt(e),t&&await dn(e,(r=[],(n=t).dataNetwork&&r.push("--dataNetwork",n.dataNetwork),n.wifiMode&&r.push("--wifiMode",n.wifiMode),void 0!==n.wifiBars&&("wifi"===n.dataNetwork||n.wifiMode)&&r.push("--wifiBars",n.wifiBars),n.cellularMode&&r.push("--cellularMode",n.cellularMode),void 0!==n.cellularBars&&(n.cellularMode||(a=n.dataNetwork)&&"hide"!==a&&"wifi"!==a||void 0!==n.operatorName)&&r.push("--cellularBars",n.cellularBars),void 0!==n.operatorName&&r.push("--operatorName",n.operatorName),r))}async function de(e){let t=await l9(e,["status_bar",e.id,"list"],{allowFailure:!0});if(0!==t.exitCode)throw new y("COMMAND_FAILED","Failed to read simulator status bar overrides",{exitCode:t.exitCode,stdout:t.stdout,stderr:t.stderr});return function(e){let t={};for(let n of e.split("\n").map(e=>e.trim()).filter(e=>e.length>0&&"Current Status Bar Overrides:"!==e&&!/^=+$/.test(e))){let e=/^DataNetworkType:\s+(\d+)$/.exec(n);if(e){let n=Number(e[1]),a=l5[n];if(!a)throw new y("COMMAND_FAILED",`Unsupported simulator data network type: ${n}`);t.dataNetwork=a;continue}let a=/^WiFi Mode:\s+(\d+),\s+WiFi Bars:\s+(\d+)$/.exec(n);if(a){let e=l8[Number(a[1])];e&&(t.wifiMode=e),t.wifiBars=a[2];continue}let r=/^Cell Mode:\s+(\d+),\s+Cell Bars:\s+(\d+)$/.exec(n);if(r){let e=Number(r[1]),n=l6[e];if(!n)throw new y("COMMAND_FAILED",`Unsupported simulator cellular mode: ${e}`);t.cellularMode=n,t.cellularBars=r[2];continue}let i=/^Operator Name:\s*(.*)$/.exec(n);if(i){t.operatorName=i[1]??"";continue}}return 0===Object.keys(t).length?null:t}(t.stdout)}async function dt(e){await l9(e,["status_bar",e.id,"clear"])}async function dn(e,t){0!==t.length&&await l9(e,["status_bar",e.id,"override",...t])}function da(e,t,n){el({level:"warn",phase:`ios_screenshot_status_bar_${t}`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,...function(e){if(!(e instanceof y))return{reason:e instanceof Error?e.message:String(e)};let t=e.details??{},n=Array.isArray(t.args)?t.args.filter(e=>"string"==typeof e).join(" "):void 0;return{errorCode:e.code,reason:e.message,timeoutMs:"number"==typeof t.timeoutMs?t.timeoutMs:void 0,exitCode:"number"==typeof t.exitCode?t.exitCode:void 0,stderr:"string"==typeof t.stderr&&t.stderr.trim()?t.stderr:void 0,stdout:"string"==typeof t.stdout&&t.stdout.trim()?t.stdout:void 0,commandArgs:n}}(n)}})}function dr(e,t,n){return ef("xcrun",rj(e,t),n)}let di={ensureBooted:lP,prepareStatusBarForScreenshot:async function e(e){let t=null,n=!1;try{t=await de(e),n=!0}catch(t){da(e,"snapshot_failed",t)}try{await dt(e),await dn(e,l4)}catch(t){da(e,"prepare_failed",t)}return async()=>{await l7(e,n?t:null)}},captureWithRetry:dd,runnerFallbackEnabled:lS,captureWithRunner:du,shouldFallbackToRunner:dg};async function ds(e,t,n,a){if("macos"===e.platform)return void await du(e,t,n,a);if("simulator"===e.kind)return void await dl(e,t,n,a);try{await lN(["device","screenshot","--device",e.id,t],{action:"capture iOS screenshot",deviceId:e.id});return}catch(t){if(!function(e){if(!(e instanceof y)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details??{},n="string"==typeof t.stdout?t.stdout:"",a="string"==typeof t.stderr?t.stderr:"",r=`${e.message}
|
|
4
|
+
${n}`.toLowerCase()).includes("device is busy")&&r.includes("connecting")?"Target iOS device is still connecting. Keep it unlocked, wait for device trust/connection to settle, then retry.":e_("IOS_RUNNER_CONNECT_TIMEOUT"))})}function aK(e){if(aF(e))throw aG()}let az=eU(process.env.AGENT_DEVICE_RUNNER_STARTUP_TIMEOUT_MS,45e3,5e3),aY=eU(process.env.AGENT_DEVICE_RUNNER_COMMAND_TIMEOUT_MS,45e3,1e3),aW=eU(process.env.AGENT_DEVICE_RUNNER_CONNECT_ATTEMPT_INTERVAL_MS,250,50),aJ=eU(process.env.AGENT_DEVICE_RUNNER_CONNECT_RETRY_BASE_DELAY_MS,300,10),aZ=eU(process.env.AGENT_DEVICE_RUNNER_CONNECT_RETRY_MAX_DELAY_MS,2e3,10),aQ=eU(process.env.AGENT_DEVICE_RUNNER_CONNECT_REQUEST_TIMEOUT_MS,2e4,250),a0=eU(process.env.AGENT_DEVICE_IOS_DEVICE_INFO_TIMEOUT_MS,1e4,500),a1=eG(process.env.AGENT_DEVICE_RUNNER_DESTINATION_TIMEOUT_SECONDS,20,5),a2=new Map;async function a3(e,t,n,r,a=az,i,o){let s,l=eb.fromTimeoutMs(a),d=async(n,r=!1)=>{var a,i,o;let l,d=await a4({device:e,timeoutBudgetMs:n,forceRefresh:r,requestTunnelIp:s,setRequestTunnelIp:e=>{s=e}});return{endpoints:(a=e,i=t,o=d.ip,l=[`http://127.0.0.1:${i}/command`],"device"!==a.kind||o&&l.unshift(`http://[${o}]:${i}/command`),l),cached:d.sharedCacheHit}},{endpoints:u}=await d(l.remainingMs()),c=null,p=Math.max(1,Math.ceil(a/aW));try{return await eC(async({deadline:s})=>{if(s?.isExpired())throw new y("COMMAND_FAILED","Runner connection deadline exceeded",{port:t,timeoutMs:a});if(i&&null!==i.child.exitCode&&void 0!==i.child.exitCode)throw await aH({session:i,port:t,logPath:r});let l=!1;if("device"===e.kind){let e=await d(s?.remainingMs());u=e.endpoints,l=e.cached}let p=l?u[0]:null,f=await a5(u,{command:n,port:t,timeoutMs:a,signal:o,attemptDeadline:s,onError:(t,n)=>{var r;c=n,"device"===e.kind&&t===p&&(r=e.id,a2.delete(r))}});if(f)return f;if("device"===e.kind&&l){var h;h=e.id,a2.delete(h),u=(await d(s?.remainingMs(),!0)).endpoints;let r=await a5(u,{command:n,port:t,timeoutMs:a,signal:o,attemptDeadline:s,onError:(e,t)=>{c=t}});if(r)return r}if(o?.aborted)throw aG();throw new y("COMMAND_FAILED","Runner endpoint probe failed",{port:t,endpoints:u,lastError:c?String(c):void 0})},{maxAttempts:p,baseDelayMs:aJ,maxDelayMs:aZ,jitter:.2,shouldRetry:aq},{deadline:l,phase:"ios_runner_connect",signal:o})}catch(e){if(o?.aborted||aV(e))throw aG();c||(c=e)}if(o?.aborted)throw aG();if("simulator"===e.kind){let a=l.remainingMs();if(a<=0)throw aX({port:t,endpoints:u,logPath:r,lastError:c});let i=await a9(e,t,n,a,o);return new Response(i.body,{status:i.status})}throw aX({port:t,endpoints:u,logPath:r,lastError:c})}async function a5(e,t){let{command:n,port:r,timeoutMs:a,signal:i,attemptDeadline:o,onError:s}=t;for(let t of e)try{let e=o?.remainingMs()??a;if(e<=0)throw new y("COMMAND_FAILED","Runner connection deadline exceeded",{port:r,timeoutMs:a});return await a8(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)},Math.min(aQ,e),i)}catch(e){if(i?.aborted||aV(e))throw aG();s(t,e)}return null}async function a4(e){var t,n,r;let{device:a,timeoutBudgetMs:i,forceRefresh:o,requestTunnelIp:s,setRequestTunnelIp:l}=e;if("device"!==a.kind)return{ip:null,sharedCacheHit:!1};if(!o){let e,n=(t=a.id,(e=a2.get(t))?e.expiresAt<=Date.now()?(a2.delete(t),null):e.ip:null);if(n)return{ip:n,sharedCacheHit:!0};if(void 0!==s)return{ip:s,sharedCacheHit:!1}}let d=await a6(a.id,i);return l(d),d&&(n=a.id,r=d,a2.set(n,{ip:r,expiresAt:Date.now()+3e4})),{ip:d,sharedCacheHit:!1}}async function a8(e,t,n,r){let a=AbortSignal.timeout(n),i=r?AbortSignal.any([r,a]):a;return await fetch(e,{...t,signal:i})}async function a6(e,t){if("number"==typeof t&&t<=0)return null;let r="number"==typeof t?Math.max(1,Math.min(a0,t)):a0,a=o.join(s.tmpdir(),`agent-device-devicectl-info-${process.pid}-${Date.now()}.json`);try{let t=Math.max(1,Math.ceil(r/1e3)),i=await ed("xcrun",["devicectl","device","info","details","--device",e,"--json-output",a,"--timeout",String(t)],{allowFailure:!0,timeoutMs:r});if(0!==i.exitCode||!n.existsSync(a))return null;let o=JSON.parse(n.readFileSync(a,"utf8"));if(o.info?.outcome&&"success"!==o.info.outcome)return null;let s=(o.result?.connectionProperties?.tunnelIPAddress??o.result?.device?.connectionProperties?.tunnelIPAddress)?.trim();return s&&s.length>0?s:null}catch{return null}finally{ia(a)}}async function a9(e,t,n,r,a){let i=JSON.stringify(n),o=aj(e,["spawn",e.id,"/usr/bin/curl","-s","-X","POST","-H","Content-Type: application/json","--data",i,`http://127.0.0.1:${t}/command`]),s=await ed("xcrun",o,{allowFailure:!0,timeoutMs:r,signal:a}),l=s.stdout;if(0!==s.exitCode){let e=ev({message:"Runner did not accept connection (simctl spawn)",stdout:s.stdout,stderr:s.stderr,context:{platform:"ios",phase:"connect"}});throw new y("COMMAND_FAILED","Runner did not accept connection (simctl spawn)",{port:t,stdout:s.stdout,stderr:s.stderr,exitCode:s.exitCode,reason:e,hint:e_(e)})}return{status:200,body:l}}async function a7(){return await new Promise((e,t)=>{let n=d.createServer();n.listen(0,"127.0.0.1",()=>{let r=n.address();if("object"==typeof r&&r?.port){let t=r.port;n.close(()=>e(t))}else n.close(()=>t(new y("COMMAND_FAILED","Failed to allocate port")))}),n.on("error",t)})}function ie(e,t,n,r){t&&ir(t,e),n&&ir(n,e),r&&process.stderr.write(e)}let it=new Map;function ir(e,t){let r=(it.get(e)??Promise.resolve()).catch(()=>{}).then(()=>n.promises.appendFile(e,t)).catch(()=>{}).finally(()=>{it.get(e)===r&&it.delete(e)});it.set(e,r)}function ia(e){try{n.existsSync(e)&&n.unlinkSync(e)}catch{}}let ii=new u;async function io(e,t,n){let r=ii.getStore()??[];if(r.some(n=>n.locks===e&&n.key===t))return await n();let a=(e.get(t)??Promise.resolve()).catch(()=>{}).then(()=>ii.run([...r,{locks:e,key:t}],n));return e.set(t,a),a.finally(()=>{e.get(t)===a&&e.delete(t)})}let is=new Set(["RUNNER_PRODUCT_MISSING","RUNNER_PRODUCT_REPAIR_FAILED"]);async function il(e,t,r){if("macos"!==e.platform)return;if(0===t.length)throw new y("COMMAND_FAILED","Missing macOS runner product",{reason:"RUNNER_PRODUCT_MISSING",xctestrunPath:r});let a=Array.from(new Set(t)).sort((e,t)=>t.length-e.length);for(let e of a)if(!n.existsSync(e))throw new y("COMMAND_FAILED","Missing macOS runner product",{reason:"RUNNER_PRODUCT_MISSING",productPath:e,xctestrunPath:r});for(let e of a)if(0!==el("codesign",["--verify","--deep","--strict",e],{allowFailure:!0}).exitCode){await ed("codesign",["--remove-signature",e],{allowFailure:!0});try{await ed("codesign",["--force","--sign","-",e])}catch(n){let t=n instanceof y?n:new y("COMMAND_FAILED",String(n));throw new y("COMMAND_FAILED","Failed to repair macOS runner product signature",{reason:"RUNNER_PRODUCT_REPAIR_FAILED",productPath:e,xctestrunPath:r,error:t.message,details:t.details})}}}let id=null;function iu(e){return function e(t){if(!Array.isArray(t))return[];let n=[];for(let r of t)if(!(!r||"object"!=typeof r||Array.isArray(r)))for(let[t,a]of Object.entries(r))":@"!==t&&"#text"!==t&&n.push({name:t,attributes:function(e){if(!e||"object"!=typeof e||Array.isArray(e))return{};let t={};for(let[n,r]of Object.entries(e))"string"==typeof r&&(t[n]=r);return t}(r[":@"]),text:ip(a)??ip(r["#text"]),children:e(a)});return n}((id??=new p({ignoreAttributes:!1,attributeNamePrefix:"",preserveOrder:!0,trimValues:!0,parseTagValue:!1})).parse(e))}function ic(e,t){for(let n of e){if("dict"===n.name)for(let e=0;e<n.children.length-1;e+=1){let r=n.children[e],a=n.children[e+1];r?.name==="key"&&r.text&&a&&t(r.text,a)}ic(n.children,t)}}function ip(e){if("string"==typeof e){let t=e.trim();return t.length>0?t:null}if(!Array.isArray(e))return null;let t=e.map(e=>{if(!e||"object"!=typeof e||Array.isArray(e))return null;let t=e["#text"];return"string"==typeof t?t.trim():null}).filter(e=>null!==e&&e.length>0).join("").trim();return t.length>0?t:null}let ih="XCTestDevices",im=".agent-device-backup",iw=".agent-device-xctestdevices-backup-",ig=o.join(s.homedir(),".agent-device","ios-runner"),iy=new Set(["ProductPaths","DependentProductPaths","TestHostPath","TestBundlePath","UITargetAppPath"]),ib=new Map,iv=new Set;function iI(e){return e?.trim()??""}function iA(e=process.env){return iI(e.AGENT_DEVICE_IOS_BUNDLE_ID)||iI(e.AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID)||"com.callstack.agentdevice.runner"}function ix(e=process.env){let t=iI(e.AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID);return t||`${iA(e)}.uitests`}let iS=function(e=process.env){let t=iA(e),n=ix(e);return Array.from(new Set([iI(e.AGENT_DEVICE_IOS_RUNNER_CONTAINER_BUNDLE_ID),`${n}.xctrunner`,t].filter(e=>e.length>0)))}(process.env);function iN(e=s.homedir()){return o.join(e,"Library","Developer","XCTestDevices")}async function i_(e,t={}){if("ios"!==e.platform||"simulator"!==e.kind)return null;let r=em(e.simulatorSetPath);if(!r)return null;let a=o.resolve(r),i=o.resolve(t.xctestDeviceSetPath??iN()),l=o.resolve(t.backupPath??function(e=iN()){return`${e}${im}`}(i)),d=o.resolve(t.lockDirPath??function(e=s.homedir()){return o.join(e,".agent-device","xctest-device-set.lock")}()),u=t.ownerStartTime??ej(process.pid),c=await iD({lockDirPath:d,owner:{pid:t.ownerPid??process.pid,startTime:u,acquiredAtMs:t.nowMs??Date.now()}});try{if(ik({xctestDeviceSetPath:i,backupPath:l}),function(e,t){if(o.resolve(e)===o.resolve(t))return!0;try{return n.realpathSync.native(e)===n.realpathSync.native(t)}catch{return!1}}(a,i))return await c(),null;n.mkdirSync(a,{recursive:!0}),n.existsSync(i)&&n.renameSync(i,l),function(e){let{requestedSetPath:t,xctestDeviceSetPath:r}=e,a=o.dirname(r),i=o.join(a,`${ih}.agent-device-link-${process.pid}-${Date.now()}`);n.mkdirSync(a,{recursive:!0});try{n.symlinkSync(t,i,"dir"),n.renameSync(i,r)}catch(e){throw n.existsSync(i)&&iM(i),e}}({requestedSetPath:a,xctestDeviceSetPath:i})}catch(e){throw ik({xctestDeviceSetPath:i,backupPath:l}),await c(),new y("COMMAND_FAILED","Failed to redirect XCTest device set path",{requestedSetPath:a,xctestDeviceSetPath:i,backupPath:l,error:String(e)})}let p=!1;return{release:async()=>{if(!p){p=!0;try{ik({xctestDeviceSetPath:i,backupPath:l})}finally{await c()}}}}}function ik(e){let{xctestDeviceSetPath:t,backupPath:r}=e,a=[r,...function(e){let t=o.dirname(e),r=o.basename(e).replace(im,""),a=r===ih?iw:`${r}${iw}`;try{return n.readdirSync(t).filter(e=>e.startsWith(a)).sort().map(e=>o.join(t,e))}catch{return[]}}(r)],i=a.find(e=>n.existsSync(e)),s=n.existsSync(t)&&n.lstatSync(t).isSymbolicLink();if(i){if(s&&iM(t),n.existsSync(t))if(!s)return void eH({level:"warn",phase:"ios_runner_xctest_device_set_restore_collision",data:{xctestDeviceSetPath:t,activeBackupPath:i}});else i!==r?n.rmSync(i,{recursive:!0,force:!0}):n.rmSync(r,{recursive:!0,force:!0});else n.mkdirSync(o.dirname(t),{recursive:!0}),n.renameSync(i,t);for(let e of a)e!==i&&n.existsSync(e)&&n.rmSync(e,{recursive:!0,force:!0});return}s&&(eH({level:"warn",phase:"ios_runner_xctest_device_set_orphaned_symlink",data:{xctestDeviceSetPath:t}}),iM(t))}function iM(e){!n.existsSync(e)||n.lstatSync(e).isSymbolicLink()&&n.unlinkSync(e)}async function iD(e){let{lockDirPath:t,owner:r}=e,a=o.join(t,"owner.json"),i=Date.now()+3e4;for(n.mkdirSync(o.dirname(t),{recursive:!0});Date.now()<i;)try{n.mkdirSync(t),function(e,t){let r=`${e}.${process.pid}.${Date.now()}.tmp`;n.writeFileSync(r,JSON.stringify(t),"utf8"),n.renameSync(r,e)}(a,r);let e=!1;return async()=>{e||(e=!0,n.rmSync(t,{recursive:!0,force:!0}))}}catch(e){if("EEXIST"!==e.code)throw e;if(function(e,t){let r=null;try{r=n.statSync(e)}catch{return!0}let a=function(e){try{return JSON.parse(n.readFileSync(e,"utf8"))}catch{return null}}(t);if(a){var i;return!(Number.isInteger((i=a).pid)&&!(i.pid<=0)&&eB(i.pid)&&(!i.startTime||ej(i.pid)===i.startTime))&&(n.rmSync(e,{recursive:!0,force:!0}),!0)}return!(Date.now()-r.mtimeMs<5e3)&&(n.rmSync(e,{recursive:!0,force:!0}),!0)}(t,a))continue;await eF(100)}throw new y("COMMAND_FAILED","Timed out waiting for XCTest device set lock",{lockDirPath:t})}async function iE(e,t){var r;let a,i=(r=e,(a=process.env.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim())?o.resolve(a):"macos"===r.platform?o.join(ig,"derived","macos"):"simulator"===r.kind?o.join(ig,"derived"):o.join(ig,"derived",r.kind)),s=function(){let e=o.dirname(c(import.meta.url)),t=e;for(let e=0;e<6;e+=1){let e=o.join(t,"package.json");if(n.existsSync(e))return t;t=o.dirname(t)}return e}();return await io(ib,i,async()=>{eA(process.env.AGENT_DEVICE_IOS_CLEAN_DERIVED)&&(iB("clean","forced_clean",{derived:i}),iV(i),iO(i));let r=function(e){let t=e.findXctestrun(e.derived);if(!t)return{reason:"missing_xctestrun",xctestrunPath:null};let n=e.resolveExistingXctestrunProductPaths(t);return n?e.xctestrunReferencesProjectRoot(t,e.projectRoot)?{reason:"reuse_ready",xctestrunPath:t,productPaths:n}:{reason:"project_root_mismatch",xctestrunPath:t,productPaths:n}:{reason:"missing_products",xctestrunPath:t,productPaths:[]}}({derived:i,projectRoot:s,findXctestrun:t=>iR(t,e),xctestrunReferencesProjectRoot:iT,resolveExistingXctestrunProductPaths:ij});if("reuse_ready"!==r.reason&&iB("rebuild",r.reason,{derived:i,xctestrunPath:r.xctestrunPath}),"reuse_ready"===r.reason)try{return await il(e,r.productPaths,r.xctestrunPath),iB("reuse","reuse_ready",{derived:i,xctestrunPath:r.xctestrunPath}),r.xctestrunPath}catch(e){if(!function(e){if(!(e instanceof y))return!1;let t=e.details&&"object"==typeof e.details?e.details.reason:void 0;return"string"==typeof t&&is.has(t)}(e))throw e;iB("rebuild","repair_failed",{derived:i,xctestrunPath:r.xctestrunPath})}r.xctestrunPath&&(iV(i),iO(i));let a=o.join(s,"ios-runner","AgentDeviceRunner","AgentDeviceRunner.xcodeproj");if(!n.existsSync(a))throw new y("COMMAND_FAILED","iOS runner project not found",{projectPath:a});await i$(e,a,i,t);let l=iR(i,e);if(!l)throw new y("COMMAND_FAILED","Failed to locate .xctestrun after build");let d=ij(l);if(!d)throw new y("COMMAND_FAILED","Runner build is missing expected products",{xctestrunPath:l});return await il(e,d,l),iB("build","built_new",{derived:i,xctestrunPath:l}),l})}function iO(e){try{if(!n.existsSync(e))return;if("derived"!==o.basename(e))return void n.rmSync(e,{recursive:!0,force:!0});for(let r of n.readdirSync(e,{withFileTypes:!0})){var t;t=r.name,iC.has(t)&&n.rmSync(o.join(e,r.name),{recursive:!0,force:!0})}}catch{}}let iC=new Set(["Build","BuildCache.noindex","Index.noindex","Logs","ModuleCache.noindex","SDKStatCaches.noindex","SourcePackages","TextBasedInstallAPI","info.plist"]);function iR(e,t){if(!n.existsSync(e))return null;let r=[],a=[e];for(;a.length>0;){let e=a.pop();for(let t of n.readdirSync(e,{withFileTypes:!0})){let i=o.join(e,t.name);if(t.isDirectory()){a.push(i);continue}if(t.isFile()&&t.name.endsWith(".xctestrun"))try{let e=n.statSync(i);r.push({path:i,mtimeMs:e.mtimeMs})}catch{}}}return 0===r.length?null:(r.sort((e,n)=>{if(t){let r=iP(n.path,t)-iP(e.path,t);if(0!==r)return r}return n.mtimeMs-e.mtimeMs||e.path.localeCompare(n.path)}),r[0]?.path??null)}function iP(e,t){var n;let r=0,a=e.toLowerCase();o.basename(a).startsWith("agentdevicerunner.env.")&&(r-=1e3),a.includes(`${o.sep}macos${o.sep}`)&&(r-=5e3);let i="macos"===(n=t).platform?{preferred:["macos"],disallowed:["iphoneos","iphonesimulator","appletvos","appletvsimulator"]}:"tv"===n.target?"simulator"===n.kind?{preferred:["appletvsimulator"],disallowed:["appletvos","iphoneos","iphonesimulator","macos"]}:{preferred:["appletvos"],disallowed:["appletvsimulator","iphoneos","iphonesimulator","macos"]}:"simulator"===n.kind?{preferred:["iphonesimulator"],disallowed:["iphoneos","appletvos","appletvsimulator","macos"]}:{preferred:["iphoneos"],disallowed:["iphonesimulator","appletvos","appletvsimulator","macos"]};return i.preferred.length>0&&(i.preferred.some(e=>a.includes(e))?r+=2e3:r-=500),i.disallowed.some(e=>a.includes(e))&&(r-=2500),r}function iT(e,t){try{let r=n.readFileSync(e,"utf8"),a=new Set([t]);try{a.add(n.realpathSync(t))}catch{}for(let e of a)if(r.includes(e))return!0;return!1}catch{return!1}}async function iL(e,t,r){let a,i=o.dirname(e),s=r.replace(/[^a-zA-Z0-9._-]/g,"_"),l=o.join(i,`AgentDeviceRunner.env.${s}.json`),d=o.join(i,`AgentDeviceRunner.env.${s}.xctestrun`),u=await ed("plutil",["-convert","json","-o","-",e],{allowFailure:!0});if(0!==u.exitCode||!u.stdout.trim())throw new y("COMMAND_FAILED","Failed to read xctestrun plist",{xctestrunPath:e,stderr:u.stderr});try{let e=JSON.parse(u.stdout);if(!e||"object"!=typeof e||Array.isArray(e))throw Error("Root must be an object");a=e}catch(t){throw new y("COMMAND_FAILED","Failed to parse xctestrun JSON",{xctestrunPath:e,error:String(t)})}let c=e=>{e.EnvironmentVariables={...e.EnvironmentVariables??{},...t},e.UITestEnvironmentVariables={...e.UITestEnvironmentVariables??{},...t},e.UITargetAppEnvironmentVariables={...e.UITargetAppEnvironmentVariables??{},...t},e.TestingEnvironmentVariables={...e.TestingEnvironmentVariables??{},...t}},p=a.TestConfigurations;if(Array.isArray(p))for(let e of p){if(!e||"object"!=typeof e)continue;let t=e.TestTargets;if(Array.isArray(t))for(let e of t)e&&"object"==typeof e&&c(e)}for(let[e,t]of Object.entries(a))t&&"object"==typeof t&&!Array.isArray(t)&&t.TestBundlePath&&(c(t),a[e]=t);n.writeFileSync(l,JSON.stringify(a,null,2));let f=await ed("plutil",["-convert","xml1","-o",d,l],{allowFailure:!0});if(0!==f.exitCode)throw new y("COMMAND_FAILED","Failed to write xctestrun plist",{tmpXctestrunPath:d,stderr:f.stderr});return{xctestrunPath:d,jsonPath:l}}async function i$(e,t,n,r){let a=function(e=process.env){let t=iA(e),n=ix(e);return[`AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID=${t}`,`AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID=${n}`]}(process.env),i=function(e=process.env,t=!1,n="ios"){if("macos"===n)return["CODE_SIGNING_ALLOWED=NO","CODE_SIGNING_REQUIRED=NO","CODE_SIGN_IDENTITY=","DEVELOPMENT_TEAM="];if(!t)return[];let r=e.AGENT_DEVICE_IOS_TEAM_ID?.trim()||"",a=e.AGENT_DEVICE_IOS_SIGNING_IDENTITY?.trim()||"",i=e.AGENT_DEVICE_IOS_PROVISIONING_PROFILE?.trim()||"",o=["CODE_SIGN_STYLE=Automatic"];return r&&o.push(`DEVELOPMENT_TEAM=${r}`),a&&o.push(`CODE_SIGN_IDENTITY=${a}`),i&&o.push(`PROVISIONING_PROFILE_SPECIFIER=${i}`),o}(process.env,"device"===e.kind,e.platform),o="device"===e.kind?["-allowProvisioningUpdates"]:[],s=await i_(e);try{var l;let s;await es("xcodebuild",["build-for-testing","-project",t,"-scheme","AgentDeviceRunner","-parallel-testing-enabled","NO",iG(e),"1","-destination",(l=e,s=iF(l),"macOS"===s?`platform=macOS,arch=${iU()}`:"simulator"===l.kind?`platform=${s} Simulator,id=${l.id}`:`generic/platform=${s}`),"-derivedDataPath",n,"COMPILER_INDEX_STORE_ENABLE=NO","ENABLE_CODE_COVERAGE=NO",...a,...o,...i],{detached:!0,onSpawn:e=>{iv.add(e),e.on("close",()=>{iv.delete(e)})},onStdoutChunk:e=>{ie(e,r.logPath,r.traceLogPath,r.verbose)},onStderrChunk:e=>{ie(e,r.logPath,r.traceLogPath,r.verbose)}})}catch(i){let e,t,n=i instanceof y?i:new y("COMMAND_FAILED",String(i)),a=(e=n.details?JSON.stringify(n.details):"",(t=`${n.message}
|
|
5
|
+
${e}`.toLowerCase()).includes("failed registering bundle identifier")||t.includes("app identifier")&&t.includes("not available")?"Set AGENT_DEVICE_IOS_BUNDLE_ID to a unique reverse-DNS value (for example, com.yourname.agentdevice.runner), then retry.":t.includes("requires a development team")?"Configure signing in Xcode or set AGENT_DEVICE_IOS_TEAM_ID for physical-device runs.":t.includes("no profiles for")||t.includes("provisioning profile")?"Install/select a valid iOS provisioning profile, or set AGENT_DEVICE_IOS_PROVISIONING_PROFILE.":t.includes("code signing")?"Enable Automatic Signing in Xcode or provide AGENT_DEVICE_IOS_TEAM_ID and optional AGENT_DEVICE_IOS_SIGNING_IDENTITY.":void 0);throw new y("COMMAND_FAILED","xcodebuild build-for-testing failed",{error:n.message,details:n.details,logPath:r.logPath,hint:a})}finally{await s?.release()}}function iF(e){var t;if("ios"!==e.platform&&"macos"!==e.platform)throw new y("UNSUPPORTED_PLATFORM",`Unsupported platform for iOS runner: ${e.platform}`);return"macos"===e.platform?"macOS":"macos"===(t=e.target)||"desktop"===t?"macOS":"tv"===t?"tvOS":"iOS"}function iU(){return"arm64"===process.arch?"arm64":"x86_64"}function iG(e){return"macos"===e.platform||"device"===e.kind?"-maximum-concurrent-test-device-destinations":"-maximum-concurrent-test-simulator-destinations"}function iV(e,t=process.env){if(t.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim()&&!function(e=process.env){return eA(e.AGENT_DEVICE_IOS_ALLOW_OVERRIDE_DERIVED_CLEAN)}(t))throw new y("COMMAND_FAILED","Refusing to clean AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH automatically",{derivedPath:e,hint:"Unset AGENT_DEVICE_IOS_CLEAN_DERIVED, or set AGENT_DEVICE_IOS_ALLOW_OVERRIDE_DERIVED_CLEAN=1 if you trust this path."})}function iB(e,t,n){eH({level:"rebuild"===e?"warn":"info",phase:"runner_xctestrun_cache",data:{action:e,reason:t,...n}})}function ij(e){let t=function(e){let t=function(e){try{let t=el("plutil",["-convert","json","-o","-",e],{allowFailure:!0});if(0!==t.exitCode||!t.stdout.trim())return null;return JSON.parse(t.stdout)}catch{return null}}(e);if(t){var r,a,i=t;let e=new Set,n=t=>{if(t&&"object"==typeof t)for(let n of function(e){let t=new Set(["ProductPaths","DependentProductPaths","TestHostPath","TestBundlePath","UITargetAppPath"]),n=new Set;for(let[r,a]of Object.entries(e))if(t.has(r)){if("string"==typeof a){n.add(a);continue}if(Array.isArray(a))for(let e of a)"string"==typeof e&&n.add(e)}return Array.from(n)}(t))e.add(n)};n(i);let o=i.TestConfigurations;if(Array.isArray(o))for(let e of o){if(!e||"object"!=typeof e)continue;let t=e.TestTargets;if(Array.isArray(t))for(let e of t)n(e)}for(let e of Object.values(i))e&&"object"==typeof e&&"TestBundlePath"in e&&n(e);return Array.from(e)}if("darwin"===process.platform)return null;try{let t;return r=n.readFileSync(e,"utf8"),a=iu(r),t=new Set,ic(a,(e,n)=>{if(iy.has(e)){if("string"===n.name&&n.text)return void t.add(n.text);if("array"===n.name)for(let e of n.children)"string"===e.name&&e.text&&t.add(e.text)}}),Array.from(t)}catch{return null}}(e);if(!t||0===t.length)return null;let r=o.dirname(e),a=new Set,i=new Set,s=[];for(let e of t){if(e.startsWith("__TESTROOT__/")){let t=e.slice(13),s=o.join(r,t);if(!n.existsSync(s))return null;a.add(s);let l=function(e){let t=/\.app(?:\/|$)/.exec(e);return t&&void 0!==t.index?e.slice(0,t.index+4):null}(t);l&&i.add(o.join(r,l));continue}e.startsWith("__TESTHOST__/")&&s.push(e.slice(13))}for(let e of s){let t=Array.from(i).find(t=>n.existsSync(o.join(t,e)));if(!t)return null;a.add(o.join(t,e))}return Array.from(a)}let iq=new Map,iX=new Map;async function iH(e,t){return await io(iX,e.id,async()=>{var n;let r,a,i=iq.get(e.id);if(i){if(i0(i.child.pid))return i;await iW(e.id,i)}await ("simulator"!==(n=e).kind?Promise.resolve():i2(n)),await iK(e);let o=await iE(e,t),s=await a7(),{xctestrunPath:l,jsonPath:d}=await iL(o,{AGENT_DEVICE_RUNNER_PORT:String(s)},`session-${e.id}-${s}`),u=await i_(e);try{let t;({child:r,wait:a}=eo("xcodebuild",["test-without-building","-only-testing","AgentDeviceRunnerUITests/RunnerTests/testCommand","-parallel-testing-enabled","NO","-test-timeouts-enabled","NO","-collect-test-diagnostics","never",iG(e),"1","-destination-timeout",String(a1),"-xctestrun",l,"-destination",(t=iF(e),"macOS"===t?`platform=macOS,arch=${iU()}`:"simulator"===e.kind?`platform=${t} Simulator,id=${e.id}`:`platform=${t},id=${e.id}`)],{allowFailure:!0,env:{...process.env,AGENT_DEVICE_RUNNER_PORT:String(s)},detached:!0}))}catch(e){throw await u?.release(),e}r.stdout?.on("data",e=>{ie(e,t.logPath,t.traceLogPath,t.verbose)}),r.stderr?.on("data",e=>{ie(e,t.logPath,t.traceLogPath,t.verbose)});let c={sessionId:`${e.id}:${s}:${Date.now()}`,device:e,deviceId:e.id,port:s,xctestrunPath:l,jsonPath:d,testPromise:a,child:r,ready:!1,simulatorSetRedirect:u??void 0};return iq.set(e.id,c),c})}async function iK(e){if("simulator"===e.kind)for(let t of iS){let n=await ed("xcrun",aj(e,["uninstall",e.id,t]),{allowFailure:!0});if(0!==n.exitCode){let e=`${n.stdout}
|
|
6
|
+
${n.stderr}`.toLowerCase();if(!e.includes("not installed")&&!e.includes("found nothing")&&!e.includes("no such file")&&!e.includes("invalid device")&&!e.includes("could not find"))continue}}}function iz(e){let t=iq.get(e);return t?{sessionId:t.sessionId,alive:i0(t.child.pid)}:null}async function iY(e){await io(iX,e.deviceId,async()=>{await iW(e.deviceId,e)})}async function iW(e,t){let n=t??iq.get(e);if(n){var r;try{await a3(n.device,n.port,{command:"shutdown"},void 0,15e3)}catch{await i1(n.child.pid,"SIGTERM")}try{await Promise.race([n.testPromise,new Promise(e=>setTimeout(e,1e4))])}catch{}(r=n.child.pid)&&(i0(r)||eV(r))&&await i1(n.child.pid,"SIGKILL"),ia(n.xctestrunPath),ia(n.jsonPath),await n.simulatorSetRedirect?.release(),iq.get(e)===n&&iq.delete(e)}}async function iJ(e){await io(iX,e,async()=>{await iW(e)})}async function iZ(){let e=Array.from(iq.values()),t=Array.from(iv);await Promise.allSettled(e.map(async e=>{await i1(e.child.pid,"SIGINT")})),await Promise.allSettled(t.map(async e=>{await i1(e.pid,"SIGINT")})),await Promise.allSettled(e.map(async e=>{await i1(e.child.pid,"SIGTERM")})),await Promise.allSettled(t.map(async e=>{await i1(e.pid,"SIGTERM")})),await Promise.allSettled(e.map(async e=>{await i1(e.child.pid,"SIGKILL")})),await Promise.allSettled(t.map(async e=>{await i1(e.pid,"SIGKILL"),iv.delete(e)})),await Promise.allSettled(e.map(async e=>{await e.simulatorSetRedirect?.release()}))}async function iQ(){await iZ();let e=Array.from(iq.keys());await Promise.allSettled(e.map(async e=>{await iJ(e)}));let t=Array.from(iv);await Promise.allSettled(t.map(async e=>{try{await i1(e.pid,"SIGTERM"),await i1(e.pid,"SIGKILL")}finally{iv.delete(e)}}))}function i0(e){return!!e&&eB(e)}async function i1(e,t){if(!e||e<=0)return;try{process.kill(-e,t)}catch{}try{process.kill(e,t)}catch{}let n="SIGINT"===t?"INT":"SIGTERM"===t?"TERM":"KILL";try{await ed("pkill",[`-${n}`,"-P",String(e)],{allowFailure:!0})}catch{}}async function i2(e){await ed("xcrun",aj(e,["bootstatus",e.id,"-b"]),{timeoutMs:az})}async function i3(e,t,n,r,a,i){let o=await a3(e,t.port,n,r,a,t,i);return await i5(o,t,r)}async function i5(e,t,n){let r,a=await e.text();try{let e=JSON.parse(a);r=e&&"object"==typeof e?e:{}}catch{throw new y("COMMAND_FAILED","Invalid runner response",{text:a})}if(!r.ok){let e=r.error?.code;throw new y("string"==typeof e&&e.trim().length>0?m(e):"COMMAND_FAILED",("string"==typeof r.error?.message?r.error.message:void 0)??"Runner error",{runner:r,xcodebuild:{exitCode:1,stdout:"",stderr:""},logPath:n})}return(t.ready=!0,r.data&&"object"==typeof r.data&&!Array.isArray(r.data))?r.data:{}}async function i4(e,t,n={}){var r;if("ios"!==e.platform&&"macos"!==e.platform)throw new y("UNSUPPORTED_PLATFORM",`Unsupported platform for iOS runner: ${e.platform}`);if("simulator"!==e.kind&&"device"!==e.kind)throw new y("UNSUPPORTED_OPERATION",`Unsupported iOS device kind for runner: ${e.kind}`);return(aK(n.requestId),"interactionFrame"===(r=t.command)||"snapshot"===r||"screenshot"===r||"findText"===r||"readText"===r||"alert"===r||"uptime"===r)?ey(()=>(aK(n.requestId),i8(e,t,n)),{shouldRetry:e=>{aK(n.requestId);if(!(e instanceof y)||"COMMAND_FAILED"!==e.code)return!1;let t=`${e.message??""}`.toLowerCase();return!(t.includes("xcodebuild exited early")||t.includes("device is busy")&&t.includes("connecting"))&&!!(t.includes("runner did not accept connection")||t.includes("fetch failed")||t.includes("econnrefused")||t.includes("socket hang up"))}}):i8(e,t,n)}async function i8(e,t,n={}){let r;aK(n.requestId);let a=aU(n.requestId);try{let i=(r=await iH(e,n)).ready?aY:az;return await i3(e,r,t,n.logPath,i,a)}catch(o){let i=o instanceof y?o:new y("COMMAND_FAILED",String(o));if("COMMAND_FAILED"===i.code&&"string"==typeof i.message&&i.message.includes("Runner did not accept connection")&&aq(i)&&r?.ready){aK(n.requestId),r?await iY(r):await iJ(e.id),r=await iH(e,n);let i=await a3(r.device,r.port,t,n.logPath,az,void 0,a);return await i5(i,r,n.logPath)}throw o}}let i6="agent-device-macos-helper",i9="AGENT_DEVICE_MACOS_HELPER_BIN",i7=o.join(s.homedir(),".agent-device","macos-helper","current"),oe=o.join(i7,"manifest.json"),ot=/^[A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)+$/;function on(e){let t=e.trim();if(!ot.test(t))throw new y("INVALID_ARGS","macOS bundle id must use reverse-DNS form like com.example.App",{bundleId:e});return t}function or(){return function(e){let t=o.dirname(e);for(;;){let e=o.join(t,"macos-helper");if(r(o.join(e,"Package.swift")))return e;let n=o.dirname(t);if(n===t)break;t=n}throw new y("COMMAND_FAILED","Unable to locate macOS helper package root",{modulePath:e})}(c(import.meta.url))}async function oa(e){let t=await a.readdir(e,{withFileTypes:!0});return(await Promise.all(t.map(async t=>{let n=o.join(e,t.name);return t.isDirectory()?".build"===t.name?[]:await oa(n):t.isFile()&&(t.name.endsWith(".swift")||"Package.swift"===t.name)?[n]:[]}))).flat().sort()}async function oi(e){let t=await oa(e),n=f("sha256");for(let r of t)n.update(o.relative(e,r)),n.update("\0"),n.update(await a.readFile(r)),n.update("\0");let r=await ed("swift",["--version"],{allowFailure:!0,cwd:e,timeoutMs:1e4});return n.update("swift-version"),n.update("\0"),n.update(r.stdout||r.stderr||`exit:${r.exitCode}`),n.update("\0"),n.digest("hex")}async function oo(){try{let e=JSON.parse(await a.readFile(oe,"utf8"));return"string"==typeof e.fingerprint?e.fingerprint:null}catch{return null}}async function os(){let e=await ec(process.env[i9],i9);if(e)return e;let t=or(),n=await oi(t),r=o.join(i7,i6);try{if(await oo()===n)return await a.access(r),r}catch{}let i=o.join(or(),".build","release",i6);process.stderr.write("agent-device: building macOS helper (first run or helper update)\n"),await ed("swift",["build","-c","release","--package-path",t],{cwd:t,timeoutMs:12e4}),await a.mkdir(i7,{recursive:!0});let s=`${r}.tmp`;return await a.copyFile(i,s),await a.rename(s,r),await a.chmod(r,493),await a.writeFile(oe,`${JSON.stringify({fingerprint:n},null,2)}
|
|
7
|
+
`,"utf8"),r}async function ol(e){let t=process.env[i9]?.trim();if("darwin"!==process.platform&&!t)throw new y("UNSUPPORTED_PLATFORM","macOS helper is only available on macOS");let n=await os(),r=await ed(n,e,{allowFailure:!0,timeoutMs:3e4}),a=r.stdout.trim(),i=null;if(a)try{i=JSON.parse(a)}catch{i=null}if(0===r.exitCode&&i?.ok)return i.data;throw new y("COMMAND_FAILED",i&&!i.ok?i.error?.message??`macOS helper exited with code ${r.exitCode}`:a||r.stderr.trim()||`macOS helper exited with code ${r.exitCode}`,{helperPath:n,args:e,stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode,...i&&!i.ok?i.error?.details:{}})}async function od(){return await ol(["app","frontmost"])}async function ou(e){return await ol(["app","quit","--bundle-id",on(e)])}async function oc(e,t){return await ol(["permission",e,t])}async function op(e,t={}){let n=["alert",e];return t.bundleId&&n.push("--bundle-id",on(t.bundleId)),t.surface&&n.push("--surface",t.surface),await ol(n)}async function of(e,t={}){let n=["snapshot","--surface",e];return t.bundleId&&n.push("--bundle-id",on(t.bundleId)),await ol(n)}async function oh(e,t,n={}){let r=["read","--x",String(e),"--y",String(t)];return n.bundleId&&r.push("--bundle-id",on(n.bundleId)),n.surface&&r.push("--surface",n.surface),await ol(r)}async function om(e,t,n={}){let r=["press","--x",String(e),"--y",String(t)];return n.bundleId&&r.push("--bundle-id",on(n.bundleId)),n.surface&&r.push("--surface",n.surface),await ol(r)}async function ow(e,t={}){let n=["screenshot","--out",e];return t.surface&&n.push("--surface",t.surface),t.fullscreen&&n.push("--fullscreen"),await ol(n)}function og(e){let t=e.direction,n="up"===t||"down"===t?e.referenceHeight:e.referenceWidth,r=function(e){if(void 0===e)return .6;if(!Number.isFinite(e)||e<=0)throw new y("INVALID_ARGS","scroll amount must be a positive number");return e}(e.amount),a=void 0!==e.pixels?function(e){if(!Number.isFinite(e)||e<=0)throw new y("INVALID_ARGS","scroll pixels must be a positive integer");return Math.max(1,Math.round(e))}(e.pixels):Math.round(n*r),i=Math.max(1,Math.round(.05*n)),o=Math.max(1,Math.min(a,Math.max(1,n-2*i))),s=Math.round(o/2),l=Math.round(e.referenceWidth/2),d=Math.round(e.referenceHeight/2),u=(n,r,a,i)=>({direction:t,x1:n,y1:r,x2:a,y2:i,referenceWidth:e.referenceWidth,referenceHeight:e.referenceHeight,amount:e.amount,pixels:o});switch(t){case"up":return u(l,d-s,l,d+s);case"down":return u(l,d+s,l,d-s);case"left":return u(l-s,d,l+s,d);case"right":return u(l+s,d,l-s,d)}}function oy(e){if(0===e.length)return null;let t=[...e].sort((e,t)=>e-t);return t[Math.floor(t.length/2)]??null}function ob(e,t){let n=Math.max(24,Math.round(.2*Math.min(e.size,t.size))),r=Math.max(48,Math.round(.15*Math.min(e.crossSize,t.crossSize)));return Math.abs(e.size-t.size)<=n&&Math.abs(e.crossSize-t.crossSize)<=r}function ov(e,t){return{start:e.y-t.y,size:e.height,crossSize:e.width}}async function oI(e,t={}){let n=ez(e,t.helperAdb),r=await oA(e,t,n),a=r.xml;if(!t.interactiveOnly){let i=X(a,800,t);return function(e,t){for(let[n,r]of e){let e=t[n];e&&(r.hiddenContentAbove&&(e.hiddenContentAbove=!0),r.hiddenContentBelow&&(e.hiddenContentBelow=!0))}}(await oN(e,i.nodes,n),i.nodes),{...i,androidSnapshot:r.metadata}}let i=K(a),o=et(i,800,{...t,interactiveOnly:!1}),s=et(i,800,t),l=await oN(e,o.nodes,n);oO(l,o,s),0===l.size&&oO(function(e){if(0===e.length)return new Map;let{hintedContainers:t}=tm(e);var n=t.directionsByContainer;let r=new Map;for(let[e,t]of n){let n={};t.has("above")&&(n.hiddenContentAbove=!0),t.has("below")&&(n.hiddenContentBelow=!0),(n.hiddenContentAbove||n.hiddenContentBelow)&&r.set(e,n)}return r}(q(o.nodes)),o,s);let{sourceNodes:d,...u}=s;return{...u,androidSnapshot:r.metadata}}async function oA(e,t,n){let r=await ox(t.helperArtifact);if(r.artifact){var a;let i=(a=e,`${a.platform}:${a.id}`);try{let a=eK(e,t.helperAdb),o=await H({adb:n,adbProvider:a,artifact:r.artifact,deviceKey:i,installPolicy:t.helperInstallPolicy,timeoutMs:3e4}),s=await Y({adb:n,packageName:r.artifact.manifest.packageName,instrumentationRunner:r.artifact.manifest.instrumentationRunner,waitForIdleTimeoutMs:500,timeoutMs:8e3,commandTimeoutMs:13e3});return{xml:s.xml,metadata:{backend:"android-helper",helperVersion:r.artifact.manifest.version,helperApiVersion:s.metadata.helperApiVersion,installReason:o.reason,waitForIdleTimeoutMs:s.metadata.waitForIdleTimeoutMs,timeoutMs:s.metadata.timeoutMs,maxDepth:s.metadata.maxDepth,maxNodes:s.metadata.maxNodes,rootPresent:s.metadata.rootPresent,captureMode:s.metadata.captureMode,windowCount:s.metadata.windowCount,nodeCount:s.metadata.nodeCount,helperTruncated:s.metadata.truncated,elapsedMs:s.metadata.elapsedMs}}}catch(t){return Q({deviceKey:i,packageName:r.artifact.manifest.packageName,versionCode:r.artifact.manifest.versionCode}),await oS(e,g(t).message,n)}}return await oS(e,r.fallbackReason,n)}async function ox(e){if(e)return{artifact:e};let t=en(),n=o.join(er(),"android-snapshot-helper","dist"),r=o.join(n,`agent-device-android-snapshot-helper-${t}.manifest.json`);try{await h.access(r)}catch{return{}}try{let e=Z(JSON.parse(await h.readFile(r,"utf8"))),t=o.join(n,e.assetName??`agent-device-android-snapshot-helper-${e.version}.apk`);return await h.access(t),{artifact:{apkPath:t,manifest:e}}}catch(e){return{fallbackReason:g(e).message}}}async function oS(e,t,n){return{xml:await o_(e,n),metadata:{backend:"uiautomator-dump",...t?{fallbackReason:t}:{}}}}async function oN(e,t,n){if(!t.some(e=>ee(e.type)))return new Map;let r=await oE(e,n);return r?function(e,t){let n=function(e){let t={className:"root",rect:{x:0,y:0,width:0,height:0},children:[]},n=[{indent:-1,node:t}],r=/^(\s*)([\w.$]+)\{[^}]* (-?\d+),(-?\d+)-(-?\d+),(-?\d+) #/;for(let t of e.split("\n")){let e=r.exec(t);if(!e)continue;let a=e[1].length,i=Number(e[3]),o=Number(e[4]),s=Number(e[5]),l=Number(e[6]),d={className:e[2],rect:{x:i,y:o,width:Math.max(0,s-i),height:Math.max(0,l-o)},children:[]};for(;n.length>1&&a<=n[n.length-1].indent;)n.pop();n[n.length-1].node.children.push(d),n.push({indent:a,node:d})}return t.children.length>0?t:null}(t);if(!n)return new Map;let r=function(e){let t=[],n=[e];for(;n.length>0;){let e=n.pop();if(ee(e.className)){let n=function(e){let t=e.children[0];if(!t)return null;let n=Math.max(t.rect.height,...t.children.map(e=>e.rect.y+e.rect.height)),r=t.children.filter(e=>e.rect.height>0).map(t=>ov(t.rect,e.rect)).sort((e,t)=>e.start-t.start);return 0===r.length?null:{rect:e.rect,contentExtent:n,contentBlocks:r}}(e);n&&t.push(n)}n.push(...e.children)}return t}(n);if(0===r.length)return new Map;let a=new Map;for(let t of e){if(!t.rect||!ee(t.type))continue;let n=function(e,t){let n=null,r=1/0;for(let a of t){let t=Math.abs(a.rect.width-e.width)+Math.abs(a.rect.height-e.height);if(t>32)continue;let i=4*t+(Math.abs(a.rect.x-e.x)+Math.abs(a.rect.y-e.y));i<r&&(n=a,r=i)}return n}(t.rect,r);if(!n)continue;let i=function(e,t){let n=function(e,t){let n=t,r=new Set;for(;!r.has(n.index);){var a,i;r.add(n.index);let o=e.filter(e=>e.parentIndex===n.index&&e.rect);if(1!==o.length)return n;let s=o[0];if(a=s.rect,i=t.rect,a.x!==i.x||a.y!==i.y||a.width!==i.width||a.height!==i.height)return n;n=s}return t}(e,t);return e.filter(e=>e.parentIndex===n.index&&e.rect).map(e=>e.rect).filter(e=>e.height>0).sort((e,t)=>e.y-t.y).map(e=>ov(e,t.rect))}(e,t),o=function(e){let{viewportRect:t,visibleBlocks:n,nativeScrollView:r}=e;if(0===n.length||0===r.contentBlocks.length)return null;let a=function(e){if(0===e.contentBlocks.length)return null;let t=e.contentBlocks[0],n=e.contentBlocks[e.contentBlocks.length-1];if(!t||!n)return null;let r=oy(e.contentBlocks.map(e=>e.size))??e.rect.height,a=Math.max(48,Math.round(.5*r)),i=Math.max(24,Math.round(.25*r)),o=t.start>=a,s=e.contentExtent-(n.start+n.size)>=i;return o||s?{above:o,below:s}:null}(r),i=function(e,t){let n=new Map;for(let r of e)for(let e of t){if(!ob(r,e))continue;let t=r.start-e.start,a=8*Math.round(t/8),i=n.get(a)??[];i.push(t),n.set(a,i)}let r=null;for(let e of n.values())(!r||e.length>r.length)&&(r=e);if(!r||r.length<2)return null;let a=[...r].sort((e,t)=>e-t);return a[Math.floor(a.length/2)]??null}(r.contentBlocks,n)??function(e){let{nativeBlocks:t,visibleBlocks:n,viewportExtent:r,contentExtent:a}=e,i=[],o=[];for(let e of t)for(let t of n){if(!ob(e,t))continue;let n=e.start-t.start;16>=Math.abs(n)&&i.push(n),16>=Math.abs(n+r-a)&&o.push(n)}return o.length>0?oy(o):i.length>0?oy(i):null}({nativeBlocks:r.contentBlocks,visibleBlocks:n,viewportExtent:t.height,contentExtent:r.contentExtent});if(null===i)return a;let o=t.height;return{above:(a?.above??!1)||i>16,below:(a?.below??!1)||i+o<r.contentExtent-16}}({viewportRect:t.rect,visibleBlocks:i,nativeScrollView:n});if(!o)continue;let s={};o.above&&(s.hiddenContentAbove=!0),o.below&&(s.hiddenContentBelow=!0),(s.hiddenContentAbove||s.hiddenContentBelow)&&a.set(t.index,s)}return a}(t,r):new Map}async function o_(e,t=ez(e)){try{return await ey(()=>ok(t),{shouldRetry:oD})}catch(e){if(function(e){if(!(e instanceof y)||"COMMAND_FAILED"!==e.code||"number"!=typeof e.details?.timeoutMs)return!1;let t=e.details?.cmd,n=e.details?.args,r=Array.isArray(n)?n.map(String):"string"==typeof n?n.split(/\s+/):[];return"adb"===t&&r.includes("uiautomator")&&r.includes("dump")}(e)){let t="If the app has looping animations, use screenshot as visual truth, try settings animations off, then retry snapshot. Stock Android UIAutomator may still time out on app-owned infinite animations.";throw new y("COMMAND_FAILED",`Android UI hierarchy dump timed out while waiting for the UI to become idle. ${t}`,{...e.details??{},hint:t},e)}throw e}}async function ok(e){var t,n,r;let a,i,o=await e(["exec-out","uiautomator","dump","/dev/tty"],{allowFailure:!0,timeoutMs:8e3}),s=oM(o.stdout,o.stderr);if(s)return s;let l="/sdcard/window_dump.xml",d=await e(["shell","uiautomator","dump",l],{allowFailure:!0,timeoutMs:8e3}),u=(t=l,n=d.stdout,r=d.stderr,a=`${n}
|
|
8
|
+
${r}`,i=/dumped to:\s*(\S+)/i.exec(a),i?.[1]??t),c=await e(["shell","cat",u]),p=oM(c.stdout,c.stderr);if(!p)throw new y("COMMAND_FAILED","uiautomator dump did not return XML",{stdout:c.stdout,stderr:c.stderr});return p}function oM(e,t){let n=`${e}
|
|
9
|
+
${t}`,r=n.indexOf("<?xml"),a=r>=0?r:n.indexOf("<hierarchy");if(a<0)return null;let i=n.lastIndexOf("</hierarchy>");if(i<0||i<a)return null;let o=n.slice(a,i+12).trim();return o.length>0?o:null}function oD(e){if(!(e instanceof y)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details?.stderr,n=("string"==typeof t?t:"").toLowerCase();return!!(n.includes("device offline")||n.includes("device not found")||n.includes("transport error")||n.includes("connection reset")||n.includes("broken pipe")||n.includes("timed out")||n.includes("no such file or directory"))}async function oE(e,t=ez(e)){try{let e=await t(["shell","dumpsys","activity","top"],{allowFailure:!0,timeoutMs:8e3}),n=`${e.stdout}
|
|
10
|
+
${e.stderr}`.trim();return n.length>0?n:null}catch{return null}}function oO(e,t,n){if(0===e.size)return;let r=new Map;for(let[e,t]of n.sourceNodes.entries()){let a=n.nodes[e];a&&r.set(t,a)}for(let[n,a]of e){let e=t.sourceNodes[n];if(!e)continue;let i=r.get(e);i&&(a.hiddenContentAbove&&(i.hiddenContentAbove=!0),a.hiddenContentBelow&&(i.hiddenContentBelow=!0))}}async function oC(e,t,n){await eh(e,["shell","input","tap",String(t),String(n)])}async function oR(e,t,n,r,a,i=250){await eh(e,["shell","input","swipe",String(t),String(n),String(r),String(a),String(i)])}async function oP(e){await eh(e,["shell","input","keyevent","4"])}async function oT(e){await eh(e,["shell","input","keyevent","3"])}async function oL(e,t){let n=function(e){switch(e){case"portrait":return"0";case"landscape-left":return"1";case"portrait-upside-down":return"2";case"landscape-right":return"3";default:throw new y("INVALID_ARGS",`Unsupported Android rotation: ${e}`)}}(t);await eh(e,["shell","settings","put","system","accelerometer_rotation","0"]),await eh(e,["shell","settings","put","system","user_rotation",n])}async function o$(e){await eh(e,["shell","input","keyevent","187"])}async function oF(e,t,n,r=800){await eh(e,["shell","input","swipe",String(t),String(n),String(t),String(n),String(r)])}async function oU(e,t,n=0){n>0&&Array.from(t).length>1?await oK(e,t,1,n):await oG(e,t)}async function oG(e,t){let n=oz(t);if(!n||"ok"!==await oY(e,t))try{let n=t.replace(/ /g,"%s");await eh(e,["shell","input","text",n])}catch(e){if(n&&function(e){if(!(e instanceof y)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details?.stderr,n=("string"==typeof t?t:"").toLowerCase();return!!(n.includes("exception occurred while executing 'text'")||n.includes("nullpointerexception")&&n.includes("inputshellcommand.sendtext"))}(e))throw new y("COMMAND_FAILED","Non-ASCII text input is not supported on this Android shell. Install an ADB keyboard IME or use ASCII input.",{textPreview:t.slice(0,32)},e instanceof Error?e:void 0);throw e}}async function oV(e,t,n){await oC(e,t,n)}async function oB(e,t,n,r,a=0){let i=Array.from(r).length,o=oz(r),s=[{strategy:"input_text",clearPadding:12,minClear:8,maxClear:48}];!o&&a<=0&&s.push({strategy:"clipboard_paste",clearPadding:12,minClear:8,maxClear:48}),(!o||a>0)&&s.push({strategy:"chunked_input",clearPadding:24,minClear:16,maxClear:96});let l=null;for(let o of s){var d,u;await oV(e,t,n);let s=(d=i+o.clearPadding,u=o.minClear,Math.max(u,Math.min(o.maxClear,d)));if(await oW(e,s),"input_text"===o.strategy)await oU(e,r,a);else if("clipboard_paste"===o.strategy){if("ok"!==await oY(e,r))continue}else await oK(e,r,1,a>0?a:15);let c=await oj(e,t,n,r);if(l=c.actual,c.ok)return}throw new y("COMMAND_FAILED","Android fill verification failed",{expected:r,actual:l??null})}async function oj(e,t,n,r){let a=null;for(let i of[0,150,350])if(i>0&&await eF(i),function(e,t){if(e===t)return!0;let n=oq(e),r=oq(t);return!!n&&!!r&&(!!(n===r||n.includes(r))||r.includes(n)&&n.length>=Math.max(4,Math.floor(.8*r.length)))}(a=await oJ(e,t,n),r))return{ok:!0,actual:a};return{ok:!1,actual:a}}function oq(e){return(e??"").replace(/\s+/g," ").trim()}async function oX(e,t,n){let r=await oH(e),a=og({direction:t,amount:n?.amount,pixels:n?.pixels,referenceWidth:r.width,referenceHeight:r.height});return await eh(e,["shell","input","swipe",String(a.x1),String(a.y1),String(a.x2),String(a.y2),"300"]),a}async function oH(e){let t=(await eh(e,["shell","wm","size"])).stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(!t)throw new y("COMMAND_FAILED","Unable to read screen size");return{width:Number(t[1]),height:Number(t[2])}}async function oK(e,t,n,r){let a=Math.max(1,Math.floor(n)),i=Array.from(t);for(let t=0;t<i.length;t+=a){let n=i.slice(t,t+a).join("");await oG(e,n),r>0&&t+a<i.length&&await eF(r)}}function oz(e){for(let t of e){let e=t.codePointAt(0);if(void 0!==e&&(e<32||e>126))return!0}return!1}async function oY(e,t){let n=await eh(e,["shell","cmd","clipboard","set","text",t],{allowFailure:!0});return 0!==n.exitCode?"failed":eL(n.stdout,n.stderr)?"unsupported":0===(await eh(e,["shell","input","keyevent","KEYCODE_PASTE"],{allowFailure:!0})).exitCode||0===(await eh(e,["shell","input","keyevent","279"],{allowFailure:!0})).exitCode?"ok":"failed"}async function oW(e,t){let n=Math.max(0,t);await eh(e,["shell","input","keyevent","KEYCODE_MOVE_END"],{allowFailure:!0});for(let t=0;t<n;t+=24){let r=Math.min(24,n-t);await eh(e,["shell","input","keyevent",...Array(r).fill("KEYCODE_DEL")],{allowFailure:!0})}}async function oJ(e,t,n){let r,a=await o_(e),i=/<node\b[^>]*>/g,o=null,s=null,l=null;for(;null!==(r=i.exec(a));){let e=z(r[0]),a=W(e.bounds);if(!a)continue;let i=e.className??"",d=(e.text??"").replace(/"/g,'"').replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">").replace(/&/g,"&"),u=e.focused??!1;if(!d)continue;let c=Math.max(1,a.width*a.height),p=t>=a.x&&t<=a.x+a.width&&n>=a.y&&n<=a.y+a.height;if(u&&oZ(i)){(!o||c<=o.area)&&(o={text:d,area:c});continue}if(p&&oZ(i)){(!s||c<=s.area)&&(s={text:d,area:c});continue}p&&(!l||c<=l.area)&&(l={text:d,area:c})}return o?.text??s?.text??l?.text??null}function oZ(e){let t=e.toLowerCase();return t.includes("edittext")||t.includes("textfield")}let oQ=["camera","microphone","photos","contacts","contacts-limited","notifications","calendar","location","location-always","media-library","motion","reminders","siri"];function o0(e){let t=e.trim().toLowerCase();if("grant"===t)return"grant";if("deny"===t)return"deny";if("reset"===t)return"reset";throw new y("INVALID_ARGS",`Invalid permission action: ${e}. Use grant|deny|reset.`)}function o1(e){let t=e?.trim().toLowerCase();if("camera"===t||"microphone"===t||"photos"===t||"contacts"===t||"contacts-limited"===t||"notifications"===t||"calendar"===t||"location"===t||"location-always"===t||"media-library"===t||"motion"===t||"reminders"===t||"siri"===t)return t;throw new y("INVALID_ARGS",`permission setting requires a target: ${oQ.join("|")}`)}function o2(e){let t=e.trim().toLowerCase();if("light"===t)return"light";if("dark"===t)return"dark";if("toggle"===t)return"toggle";throw new y("INVALID_ARGS",`Invalid appearance state: ${e}. Use light|dark|toggle.`)}let o3=["window_animation_scale","transition_animation_scale","animator_duration_scale"];async function o5(e,t,n,r,a){switch(t.toLowerCase()){case"wifi":{let t=o8(n);await eh(e,["shell","svc","wifi",t?"enable":"disable"]);return}case"airplane":{let t=o8(n);await eh(e,["shell","settings","put","global","airplane_mode_on",t?"1":"0"]),await eh(e,["shell","am","broadcast","-a","android.intent.action.AIRPLANE_MODE","--ez","state",t?"true":"false"]);return}case"location":{let t=o8(n);await eh(e,["shell","settings","put","secure","location_mode",t?"3":"0"]);return}case"animations":{let t=o8(n)?"1":"0";for(let n of o3)await eh(e,["shell","settings","put","global",n,t]);return{scale:t,keys:[...o3]}}case"appearance":{let t=await o6(e,n);await eh(e,["shell","cmd","uimode","night","dark"===t?"yes":"no"]);return}case"fingerprint":{let t=function(e){let t=e.trim().toLowerCase();if("match"===t)return"match";if("nonmatch"===t)return"nonmatch";throw new y("INVALID_ARGS",`Invalid fingerprint state: ${e}. Use match|nonmatch.`)}(n);await o4(e,t);return}case"permission":{if(!r)throw new y("INVALID_ARGS","permission setting requires an active app in session");let t=o0(n),i=function(e,t){let n=o1(e);if(t?.trim())throw new y("INVALID_ARGS",`Permission mode is only supported for photos. Received: ${t}.`);if("camera"===n)return{kind:"pm",value:"android.permission.CAMERA",type:"camera"};if("microphone"===n)return{kind:"pm",value:"android.permission.RECORD_AUDIO",type:"microphone"};if("photos"===n)return{kind:"pm",value:"android.permission.READ_MEDIA_IMAGES",type:"photos"};if("contacts"===n)return{kind:"pm",value:"android.permission.READ_CONTACTS",type:"contacts"};if("notifications"===n)return{kind:"notifications",appOps:"POST_NOTIFICATION",permission:"android.permission.POST_NOTIFICATIONS"};throw new y("INVALID_ARGS",`Unsupported permission target on Android: ${e}. Use camera|microphone|photos|contacts|notifications.`)}(a?.permissionTarget,a?.permissionMode);if("notifications"===i.kind)return void await o7(e,r,t,i);let o="grant"===t?"grant":"revoke";if("photos"===i.type)return void await o9(e,r,o);await eh(e,["shell","pm",o,r,i.value]);return}default:throw new y("INVALID_ARGS",`Unsupported setting: ${t}`)}}async function o4(e,t){var n;let r,a,i=(n=e,a=[["shell","cmd","fingerprint","touch",r="match"===t?"1":"9999"],["shell","cmd","fingerprint","finger",r]],"emulator"===n.kind&&a.push(["emu","finger","touch",r]),a),o=[];for(let t of i){let n=await eh(e,t,{allowFailure:!0});if(0===n.exitCode)return;o.push({args:t,stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode})}let s=o.map(e=>({args:e.args.join(" "),exitCode:e.exitCode,stderr:e.stderr.slice(0,400)}));if(o.length>0&&o.every(e=>{var t,n;let r;return t=e.stdout,n=e.stderr,(r=`${t}
|
|
11
|
+
${n}`.toLowerCase()).includes("unknown command")||r.includes("can't find service: fingerprint")||r.includes("service fingerprint was not found")||r.includes("fingerprint cmd unavailable")||r.includes("emu command is not supported")||r.includes("emulator console is not running")||r.includes("fingerprint")&&r.includes("not found")}))throw new y("UNSUPPORTED_OPERATION","Android fingerprint simulation is not supported on this target/runtime.",{deviceId:e.id,action:t,hint:"Use an Android emulator with biometric support, or a device/runtime that exposes cmd fingerprint.",attempts:s});throw new y("COMMAND_FAILED","Failed to simulate Android fingerprint.",{deviceId:e.id,action:t,attempts:s})}function o8(e){let t=e.toLowerCase();if("on"===t||"true"===t||"1"===t)return!0;if("off"===t||"false"===t||"0"===t)return!1;throw new y("INVALID_ARGS",`Invalid setting state: ${e}`)}async function o6(e,t){let n=o2(t);if("toggle"!==n)return n;let r=await eh(e,["shell","cmd","uimode","night"],{allowFailure:!0});if(0!==r.exitCode)throw new y("COMMAND_FAILED","Failed to read current Android appearance",{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode});let a=function(e,t){let n=/night mode:\s*(yes|no|auto)\b/i.exec(`${e}
|
|
12
|
+
${t}`);if(!n)return null;let r=n[1].toLowerCase();return"yes"===r?"dark":"no"===r?"light":"auto"===r?"auto":null}(r.stdout,r.stderr);if(!a)throw new y("COMMAND_FAILED","Unable to determine current Android appearance for toggle",{stdout:r.stdout,stderr:r.stderr});return"auto"===a?"dark":"dark"===a?"light":"dark"}async function o9(e,t,n){let r=await se(e),a=[];for(let i of null!==r&&r>=33?["android.permission.READ_MEDIA_IMAGES","android.permission.READ_EXTERNAL_STORAGE"]:["android.permission.READ_EXTERNAL_STORAGE","android.permission.READ_MEDIA_IMAGES"]){let r=await eh(e,["shell","pm",n,t,i],{allowFailure:!0});if(0===r.exitCode)return;a.push({permission:i,stderr:r.stderr,exitCode:r.exitCode})}throw new y("COMMAND_FAILED",`Failed to ${n} Android photos permission`,{appPackage:t,sdkInt:r,attempts:a})}async function o7(e,t,n,r){"grant"===n?await eh(e,["shell","pm","grant",t,r.permission],{allowFailure:!0}):(await eh(e,["shell","pm","revoke",t,r.permission],{allowFailure:!0}),"reset"===n&&(await eh(e,["shell","pm","clear-permission-flags",t,r.permission,"user-set"],{allowFailure:!0}),await eh(e,["shell","pm","clear-permission-flags",t,r.permission,"user-fixed"],{allowFailure:!0}))),await eh(e,["shell","appops","set",t,r.appOps,"grant"===n?"allow":"deny"===n?"deny":"default"])}async function se(e){let t=await eh(e,["shell","getprop","ro.build.version.sdk"],{allowFailure:!0});if(0!==t.exitCode)return null;let n=Number.parseInt(t.stdout.trim(),10);return!Number.isFinite(n)||n<=0?null:n}async function st(e,t,n){let r="string"==typeof n.action&&n.action.trim()?n.action.trim():`${t}.TEST_PUSH`,a=["shell","am","broadcast","-a",r,"-p",t],i="string"==typeof n.receiver?n.receiver.trim():"";i&&a.push("-n",i);let o=n.extras;if(void 0!==o&&("object"!=typeof o||null===o||Array.isArray(o)))throw new y("INVALID_ARGS","Android push payload extras must be an object");let s=0;for(let[e,t]of Object.entries(o??{}))e&&(function(e,t,n){if("string"==typeof n)return e.push("--es",t,n);if("boolean"==typeof n)return e.push("--ez",t,n?"true":"false");if("number"==typeof n&&Number.isFinite(n))return Number.isInteger(n)?e.push("--ei",t,String(n)):e.push("--ef",t,String(n));throw new y("INVALID_ARGS",`Unsupported Android broadcast extra type for "${t}". Use string, boolean, or number.`)}(a,e,t),s+=1);return await eh(e,a),{action:r,extrasCount:s}}let sn=Buffer.from([137,80,78,71,13,10,26,10]);async function sr(e,t){await sa(e);try{await eF(1e3),await so(e,t)}finally{await si(e).catch(()=>{})}}async function sa(e){let t=t=>eh(e,["shell",t],{allowFailure:!0});await t("settings put global sysui_demo_allowed 1");let n=e=>t(`am broadcast -a com.android.systemui.demo -e command ${e}`);await n("clock -e hhmm 0941"),await n("notifications -e visible false")}async function si(e){await eh(e,["shell","am broadcast -a com.android.systemui.demo -e command exit"],{allowFailure:!0})}async function so(e,t){let n=await eh(e,["exec-out","screencap","-p"],{binaryStdout:!0});if(!n.stdoutBuffer)throw new y("COMMAND_FAILED","Failed to capture screenshot");let r=n.stdoutBuffer.indexOf(sn);if(r<0)throw new y("COMMAND_FAILED","Screenshot data does not contain a valid PNG header");let i=function(e,t){let n=t+sn.length;for(;n+8<=e.length;){let t=e.readUInt32BE(n),r=n+4,a=e.toString("ascii",r,r+4),i=n+12+t;if(i>e.length)break;if("IEND"===a)return i;n=i}return null}(n.stdoutBuffer,r);if(!i)throw new y("COMMAND_FAILED","Screenshot data does not contain a complete PNG payload");await a.writeFile(t,n.stdoutBuffer.subarray(r,i))}let ss=eU(process.env.AGENT_DEVICE_IOS_BOOT_TIMEOUT_MS,eN.ios_boot.totalMs,5e3),sl=eU(process.env.AGENT_DEVICE_IOS_SIMCTL_LIST_TIMEOUT_MS,eN.ios_boot.operationMs,1e3),sd=eU(process.env.AGENT_DEVICE_IOS_APP_LAUNCH_TIMEOUT_MS,3e4,5e3),su=eU(process.env.AGENT_DEVICE_IOS_DEVICECTL_TIMEOUT_MS,2e4,1e3),sc=eU(process.env.AGENT_DEVICE_IOS_SIMULATOR_FOCUS_TIMEOUT_MS,1e4,1e3),sp=eU(process.env.AGENT_DEVICE_IOS_SIMULATOR_SCREENSHOT_TIMEOUT_MS,2e4,1e3),sf=eU(process.env.AGENT_DEVICE_IOS_RUNNER_SCREENSHOT_COPY_TIMEOUT_MS,2e4,1e3),sh=eA(process.env.AGENT_DEVICE_IOS_SIMULATOR_SCREENSHOT_RUNNER_FALLBACK);async function sm(e,t){let n=["devicectl",...e],r=await ed("xcrun",n,{allowFailure:!0,timeoutMs:su});if(0===r.exitCode)return;let a=String(r.stdout??""),i=String(r.stderr??"");throw new y("COMMAND_FAILED",`Failed to ${t.action}`,{cmd:"xcrun",args:n,exitCode:r.exitCode,stdout:a,stderr:i,deviceId:t.deviceId,hint:sb(a,i)??sy})}async function sw(e,t){let n=o.join(s.tmpdir(),`agent-device-ios-apps-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),r=["devicectl","device","info","apps","--device",e.id,"--include-all-apps","--json-output",n],i=await ed("xcrun",r,{allowFailure:!0,timeoutMs:su});try{var l,d;if(0!==i.exitCode){let t=String(i.stdout??""),n=String(i.stderr??"");throw new y("COMMAND_FAILED","Failed to list iOS apps",{cmd:"xcrun",args:r,exitCode:i.exitCode,stdout:t,stderr:n,deviceId:e.id,hint:sb(t,n)??sy})}let o=await a.readFile(n,"utf8");return l=function(e){let t=e?.result?.apps;if(!Array.isArray(t))return[];let n=[];for(let e of t){if(!e||"object"!=typeof e)continue;let t="string"==typeof e.bundleIdentifier?e.bundleIdentifier.trim():"";if(!t)continue;let r="string"==typeof e.name&&e.name.trim().length>0?e.name.trim():t,a="string"==typeof e.url&&e.url.trim().length>0?e.url.trim():void 0;n.push({bundleId:t,name:r,url:a})}return n}(JSON.parse(o)),d=t,"user-installed"===d?l.filter(e=>!e.bundleId.startsWith("com.apple.")):l}catch(t){if(t instanceof y)throw t;throw new y("COMMAND_FAILED","Failed to parse iOS apps list",{deviceId:e.id,cause:String(t)})}finally{await a.unlink(n).catch(()=>{})}}async function sg(e){let t=o.join(s.tmpdir(),`agent-device-ios-processes-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),n=["devicectl","device","info","processes","--device",e.id,"--json-output",t],r=await ed("xcrun",n,{allowFailure:!0,timeoutMs:su});try{if(0!==r.exitCode){let t=String(r.stdout??""),a=String(r.stderr??"");throw new y("COMMAND_FAILED","Failed to list iOS processes",{cmd:"xcrun",args:n,exitCode:r.exitCode,stdout:t,stderr:a,deviceId:e.id,hint:sb(t,a)??sy})}let i=await a.readFile(t,"utf8");return function(e){let t=e?.result?.runningProcesses;if(!Array.isArray(t))return[];let n=[];for(let e of t){if(!e||"object"!=typeof e)continue;let t="string"==typeof e.executable?e.executable.trim():"",r="number"==typeof e.processIdentifier&&Number.isFinite(e.processIdentifier)?e.processIdentifier:NaN;t&&Number.isFinite(r)&&n.push({executable:t,pid:r})}return n}(JSON.parse(i))}catch(t){if(t instanceof y)throw t;throw new y("COMMAND_FAILED","Failed to parse iOS process list",{deviceId:e.id,cause:String(t)})}finally{await a.unlink(t).catch(()=>{})}}let sy="Ensure the iOS device is unlocked, trusted, and available in Xcode > Devices, then retry.";function sb(e,t){let n=`${e}
|
|
13
|
+
${t}`.toLowerCase();return n.includes("device is busy")&&n.includes("connecting")?"iOS device is still connecting. Keep it unlocked and connected by cable until it is fully available in Xcode Devices, then retry.":n.includes("coredeviceservice")&&n.includes("timed out")?"CoreDevice service timed out. Reconnect the device and retry; if it persists restart Xcode and the iOS device.":null}function sv(e){if(!(e instanceof y)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details??{};if(4!==t.exitCode)return!1;let n=String(t.stderr??"").toLowerCase();return n.includes("fbsopenapplicationserviceerrordomain")&&n.includes("the request to open")}async function sI(e,t){let n=await ed("xcrun",aj(e,["get_app_container",e.id,t]),{allowFailure:!0});if(0!==n.exitCode)return{installed:!1};let r=n.stdout.trim();if(!r)return{installed:!1};let a=await ed("plutil",["-extract","CFBundleExecutable","raw","-o","-",`${r}/Info.plist`],{allowFailure:!0});if(0!==a.exitCode||!a.stdout.trim())return{installed:!0};let i=a.stdout.trim(),o=`${r}/${i}`,s=await ed("otool",["-l",o],{allowFailure:!0});if(0!==s.exitCode)return{installed:!0};let l=s.stdout.toLowerCase();return{installed:!0,simulatorCompatible:l.includes("iossimulator")||l.includes("platform 7")}}function sA(e,t){if("simulator"!==e.kind)throw new y("UNSUPPORTED_OPERATION",`${t} is only supported on iOS simulators`)}async function sx(){await ed("open",["-a","Simulator"],{allowFailure:!0,timeoutMs:sc})}async function sS(e){let t,n;if("simulator"!==e.kind||"Booted"===await s_(e))return;let r=eb.fromTimeoutMs(ss);try{await eC(async({deadline:r})=>{if(r?.isExpired())throw new y("COMMAND_FAILED","iOS simulator boot deadline exceeded",{timeoutMs:ss});let a=Math.max(1e3,r?.remainingMs()??ss),i=await ed("xcrun",aj(e,["boot",e.id]),{allowFailure:!0,timeoutMs:a});t={stdout:String(i.stdout??""),stderr:String(i.stderr??""),exitCode:i.exitCode};let o=`${t.stdout}
|
|
14
|
+
${t.stderr}`.toLowerCase(),s=o.includes("already booted")||o.includes("current state: booted");if(0!==t.exitCode&&!s)throw new y("COMMAND_FAILED","simctl boot failed",{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode});let l=await ed("xcrun",aj(e,["bootstatus",e.id,"-b"]),{allowFailure:!0,timeoutMs:a});if(n={stdout:String(l.stdout??""),stderr:String(l.stderr??""),exitCode:l.exitCode},0!==n.exitCode)throw new y("COMMAND_FAILED","simctl bootstatus failed",{stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode});let d=await s_(e);if("Booted"!==d)throw new y("COMMAND_FAILED","Simulator is still booting",{state:d})},{maxAttempts:3,baseDelayMs:500,maxDelayMs:2e3,jitter:.2,shouldRetry:e=>{let r=ev({error:e,stdout:n?.stdout??t?.stdout,stderr:n?.stderr??t?.stderr,context:{platform:"ios",phase:"boot"}});return"IOS_BOOT_TIMEOUT"!==r&&"CI_RESOURCE_STARVATION_SUSPECTED"!==r}},{deadline:r,phase:"boot",classifyReason:e=>ev({error:e,stdout:n?.stdout??t?.stdout,stderr:n?.stderr??t?.stderr,context:{platform:"ios",phase:"boot"}})})}catch(i){let a=ev({error:i,stdout:n?.stdout??t?.stdout,stderr:n?.stderr??t?.stderr,context:{platform:"ios",phase:"boot"}});throw new y("COMMAND_FAILED","iOS simulator failed to boot",{platform:"ios",deviceId:e.id,timeoutMs:ss,elapsedMs:r.elapsedMs(),reason:a,hint:e_(a),boot:t,bootstatus:n})}await sx()}async function sN(e){let t=aj(e,["shutdown",e.id]),n=await ed("xcrun",t,{allowFailure:!0,timeoutMs:15e3});return{success:0===n.exitCode,exitCode:n.exitCode,stdout:String(n.stdout??""),stderr:String(n.stderr??"")}}async function s_(e){let t="string"==typeof e?e:e.id,n="string"==typeof e?aB(["list","devices","-j"]):aj(e,["list","devices","-j"]),r=await ed("xcrun",n,{allowFailure:!0,timeoutMs:sl});if(0!==r.exitCode)return null;try{let e=JSON.parse(String(r.stdout??""));for(let n of Object.values(e.devices??{})){let e=n.find(e=>e.udid===t);if(e)return e.state}return null}catch{return null}}async function sk(e,t){try{let n=await ed("plutil",["-extract",t,"raw","-o","-",e],{allowFailure:!0});if(0===n.exitCode){let e=String(n.stdout??"").trim();if(e.length>0)return e}}catch{}try{var n,r;let i;return n=await a.readFile(e,"utf8"),r=t,ic(iu(n),(e,t)=>{void 0===i&&e===r&&"string"===t.name&&(i=t.text??void 0)}),i}catch{return}}async function sM(e,t){if("url"===e.kind&&!eW(e.url))throw new y("INVALID_ARGS","iOS install_from_source URL sources are only supported for trusted artifact services such as GitHub Actions and EAS. Use a path source for other hosts.");let n=await eY({source:e,isInstallablePath:(e,t)=>t.isDirectory()&&e.toLowerCase().endsWith(".app")||t.isFile()&&e.toLowerCase().endsWith(".ipa"),installableLabel:"iOS installable (.app or .ipa)",allowArchiveExtraction:"url"!==e.kind||eW(e.url),signal:t?.signal}),r=await sE(n.installablePath,t),a=await sD(r.installPath);return{archivePath:n.archivePath??(n.installablePath.toLowerCase().endsWith(".ipa")?n.installablePath:void 0),installablePath:r.installPath,bundleId:a.bundleId,appName:a.appName,cleanup:async()=>{await r.cleanup(),await n.cleanup()}}}async function sD(e){let t=o.join(e,"Info.plist"),[n,r,a]=await Promise.all([sk(t,"CFBundleIdentifier"),sk(t,"CFBundleDisplayName"),sk(t,"CFBundleName")]);return{bundleId:n,appName:r??a}}async function sE(e,t){if(!e.toLowerCase().endsWith(".ipa"))return{installPath:e,cleanup:async()=>{}};let n=await a.mkdtemp(o.join(s.tmpdir(),"agent-device-ios-ipa-")),r=async()=>{await a.rm(n,{recursive:!0,force:!0})};try{await ed("unzip",["-q",e,"-d",n]);let i=o.join(n,"Payload"),s=(await a.readdir(i,{withFileTypes:!0}).catch(()=>{throw new y("INVALID_ARGS","Invalid IPA: missing Payload directory")})).filter(e=>e.isDirectory()&&e.name.toLowerCase().endsWith(".app")).map(e=>({installPath:o.join(i,e.name),bundleName:e.name.replace(/\.app$/i,"")}));if(1===s.length)return{installPath:s[0].installPath,cleanup:r};if(0===s.length)throw new y("INVALID_ARGS","Invalid IPA: expected at least one .app under Payload, found 0");await sO(s);let l=t?.appIdentifierHint?.trim();if(l){let e=function(e,t){let n=t.toLowerCase(),r=e.filter(e=>e.bundleName.toLowerCase()===n);if(1===r.length)return r[0];if(r.length>1)throw new y("INVALID_ARGS",`Invalid IPA: multiple app bundles matched "${t}" by name. Use a bundle id hint instead.`);if(t.includes(".")){let t=e.filter(e=>e.bundleId?.toLowerCase()===n);if(1===t.length)return t[0]}}(s,l);if(e)return{installPath:e.installPath,cleanup:r};throw new y("INVALID_ARGS",`Invalid IPA: found ${s.length} .app bundles under Payload and none matched "${l}". Available bundles: ${s.map(sC).join(", ")}`)}throw new y("INVALID_ARGS",`Invalid IPA: found ${s.length} .app bundles under Payload. Pass an app identifier or bundle name matching one of: ${s.map(sC).join(", ")}`)}catch(e){throw await r(),e}}async function sO(e){await Promise.all(e.map(async e=>{if(e.bundleId&&e.appName)return;let t=await sD(e.installPath);e.bundleId=e.bundleId??t.bundleId,e.appName=e.appName??t.appName}))}function sC(e){let t=e.bundleId??e.appName;return t?`${e.bundleName}.app (${t})`:`${e.bundleName}.app`}function sR(e,t){return"user-installed"===t?e.filter(e=>!e.bundleId.startsWith("com.apple.")):e}let sP={settings:"com.apple.systempreferences"},sT=/^[a-z0-9-]+(?:\.[a-z0-9-]+)+$/,sL={platform:"macos",deviceId:"host",variant:"all"},s$=eP();function sF(e,t){let n=["-b",e];return t&&n.push(t),n}async function sU(e){for(let t of[o.join(e,"Contents","Info.plist"),o.join(e,"Info.plist")]){let[e,n,r]=await Promise.all([sk(t,"CFBundleIdentifier"),sk(t,"CFBundleDisplayName"),sk(t,"CFBundleName")]);if(e||n||r)return{bundleId:e,appName:n??r}}return{}}async function sG(e){let t=e.trim(),n=sP[t.toLowerCase()];if(n)return n;if(sT.test(t))return t;let r=s$.get(sL,t);if(r)return r;let a=(await sK("all")).filter(e=>e.name.toLowerCase()===t.toLowerCase());if(1===a.length)return s$.set(sL,t,a[0].bundleId);if(a.length>1)throw new y("INVALID_ARGS",`Multiple apps matched "${e}"`,{matches:a});throw new y("APP_NOT_INSTALLED",`No app found matching "${e}"`)}async function sV(e,t,n){let r=n?.url?.trim();if(r){if(!eT(r))throw new y("INVALID_ARGS","open <app> <url> requires a valid URL target");let e=n?.appBundleId??await sG(t);await ed("open",sF(e,r));return}let a=t.trim();if(eT(a))return void await ed("open",[a]);let i=n?.appBundleId??await sG(a);await ed("open",sF(i))}async function sB(e,t){let n=await sG(t),r=await ou(n);if(r.running&&!r.terminated&&!r.forceTerminated)throw new y("COMMAND_FAILED",`Failed to close macOS app ${t}`,{bundleId:n,running:r.running,terminated:r.terminated,forceTerminated:r.forceTerminated})}async function sj(){let e=await ed("pbpaste",[],{allowFailure:!0});if(0!==e.exitCode)throw new y("COMMAND_FAILED","Failed to read macOS clipboard",{stdout:e.stdout,stderr:e.stderr,exitCode:e.exitCode});return e.stdout.replace(/\r\n/g,"\n").replace(/\n$/,"")}async function sq(e){let t=await ed("pbcopy",[],{allowFailure:!0,stdin:e});if(0!==t.exitCode)throw new y("COMMAND_FAILED","Failed to write macOS clipboard",{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode})}async function sX(){let e=await ed("osascript",["-e",'tell application "System Events" to tell appearance preferences to get dark mode'],{allowFailure:!0});if(0!==e.exitCode)throw new y("COMMAND_FAILED","Failed to read macOS appearance",{stdout:e.stdout,stderr:e.stderr,exitCode:e.exitCode});let t=e.stdout.trim().toLowerCase();if("true"===t)return!0;if("false"===t)return!1;throw new y("COMMAND_FAILED",`Unable to determine current macOS appearance from osascript output: ${e.stdout.trim()}`)}async function sH(e){let t=o2(e),n="toggle"===t?!await sX():"dark"===t,r=`tell application "System Events" to tell appearance preferences to set dark mode to ${n?"true":"false"}`,a=await ed("osascript",["-e",r],{allowFailure:!0});if(0!==a.exitCode)throw new y("COMMAND_FAILED","Failed to set macOS appearance",{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode})}async function sK(e="all"){let t=["/Applications","/System/Applications",o.join(s.homedir(),"Applications")],n=new Set;for(let e of t){let t=await a.stat(e).catch(()=>null);if(!t?.isDirectory())continue;let r=await ed("find",[e,"-maxdepth","4","-type","d","-name","*.app"],{allowFailure:!0});if(0===r.exitCode)for(let e of r.stdout.split("\n")){let t=e.trim();t&&n.add(t)}}return sR((await Promise.all(Array.from(n).map(async e=>{let t=await sU(e).catch(()=>({})),n=t.bundleId;return n?{bundleId:n,name:t.appName??o.basename(e,".app")}:null}))).filter(e=>null!==e).sort((e,t)=>e.name.localeCompare(t.name)),e)}let sz=["--time","9:41","--dataNetwork","wifi","--wifiMode","active","--wifiBars","3","--batteryState","charged","--batteryLevel","100"],sY={0:"hide",1:"wifi",6:"3g",7:"4g",8:"lte",9:"lte-a",10:"lte+",11:"5g",12:"5g+",13:"5g-uwb",14:"5g-uc"},sW={1:"searching",2:"failed",3:"active"},sJ={0:"notSupported",1:"searching",2:"failed",3:"active"};function sZ(e,t,n){return ed("xcrun",aj(e,t),n)}async function sQ(e,t){var n,r;let a;await s1(e),t&&await s2(e,(a=[],(n=t).dataNetwork&&a.push("--dataNetwork",n.dataNetwork),n.wifiMode&&a.push("--wifiMode",n.wifiMode),void 0!==n.wifiBars&&("wifi"===n.dataNetwork||n.wifiMode)&&a.push("--wifiBars",n.wifiBars),n.cellularMode&&a.push("--cellularMode",n.cellularMode),void 0!==n.cellularBars&&(n.cellularMode||(r=n.dataNetwork)&&"hide"!==r&&"wifi"!==r||void 0!==n.operatorName)&&a.push("--cellularBars",n.cellularBars),void 0!==n.operatorName&&a.push("--operatorName",n.operatorName),a))}async function s0(e){let t=await sZ(e,["status_bar",e.id,"list"],{allowFailure:!0});if(0!==t.exitCode)throw new y("COMMAND_FAILED","Failed to read simulator status bar overrides",{exitCode:t.exitCode,stdout:t.stdout,stderr:t.stderr});return function(e){let t={};for(let n of e.split("\n").map(e=>e.trim()).filter(e=>e.length>0&&"Current Status Bar Overrides:"!==e&&!/^=+$/.test(e))){let e=/^DataNetworkType:\s+(\d+)$/.exec(n);if(e){let n=Number(e[1]),r=sY[n];if(!r)throw new y("COMMAND_FAILED",`Unsupported simulator data network type: ${n}`);t.dataNetwork=r;continue}let r=/^WiFi Mode:\s+(\d+),\s+WiFi Bars:\s+(\d+)$/.exec(n);if(r){let e=sW[Number(r[1])];e&&(t.wifiMode=e),t.wifiBars=r[2];continue}let a=/^Cell Mode:\s+(\d+),\s+Cell Bars:\s+(\d+)$/.exec(n);if(a){let e=Number(a[1]),n=sJ[e];if(!n)throw new y("COMMAND_FAILED",`Unsupported simulator cellular mode: ${e}`);t.cellularMode=n,t.cellularBars=a[2];continue}let i=/^Operator Name:\s*(.*)$/.exec(n);if(i){t.operatorName=i[1]??"";continue}}return 0===Object.keys(t).length?null:t}(t.stdout)}async function s1(e){await sZ(e,["status_bar",e.id,"clear"])}async function s2(e,t){0!==t.length&&await sZ(e,["status_bar",e.id,"override",...t])}function s3(e,t,n){eH({level:"warn",phase:`ios_screenshot_status_bar_${t}`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,...function(e){if(!(e instanceof y))return{reason:e instanceof Error?e.message:String(e)};let t=e.details??{},n=Array.isArray(t.args)?t.args.filter(e=>"string"==typeof e).join(" "):void 0;return{errorCode:e.code,reason:e.message,timeoutMs:"number"==typeof t.timeoutMs?t.timeoutMs:void 0,exitCode:"number"==typeof t.exitCode?t.exitCode:void 0,stderr:"string"==typeof t.stderr&&t.stderr.trim()?t.stderr:void 0,stdout:"string"==typeof t.stdout&&t.stdout.trim()?t.stdout:void 0,commandArgs:n}}(n)}})}function s5(e,t,n){return ed("xcrun",aj(e,t),n)}let s4={ensureBooted:sS,prepareStatusBarForScreenshot:async function e(e){let t=null,n=!1;try{t=await s0(e),n=!0}catch(t){s3(e,"snapshot_failed",t)}try{await s1(e),await s2(e,sz)}catch(t){s3(e,"prepare_failed",t)}return async()=>{await sQ(e,n?t:null)}},captureWithRetry:s9,runnerFallbackEnabled:sh,captureWithRunner:s7,shouldFallbackToRunner:lo};async function s8(e,t,n,r){if("macos"===e.platform)return void await s7(e,t,n,r);if("simulator"===e.kind)return void await s6(e,t,n,r);try{await sm(["device","screenshot","--device",e.id,t],{action:"capture iOS screenshot",deviceId:e.id});return}catch(t){if(!function(e){if(!(e instanceof y)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details??{},n="string"==typeof t.stdout?t.stdout:"",r="string"==typeof t.stderr?t.stderr:"",a=`${e.message}
|
|
22
15
|
${n}
|
|
23
|
-
${
|
|
16
|
+
${r}`.toLowerCase();return a.includes("unknown option '--device'")||a.includes("unknown subcommand")&&a.includes("screenshot")||a.includes("unrecognized subcommand")&&a.includes("screenshot")}(t))throw t;lr(e,"devicectl_screenshot",t)}await s7(e,t,n,r)}async function s6(e,t,n,r,a=s4){if("simulator"!==e.kind)throw new y("UNSUPPORTED_OPERATION","Simulator screenshot fallback flow supports only iOS simulators");let i="object"==typeof r&&null!==r?r:a;await i.ensureBooted(e);let o=async()=>{};try{o=await i.prepareStatusBarForScreenshot(e)}catch(t){la(e,"prepare_failed",t)}try{try{await i.captureWithRetry(e,t);return}catch(t){if(!i.shouldFallbackToRunner(t))throw t;if(!i.runnerFallbackEnabled){var s,l,d;let n,r;throw s=e,l=t,n=li(l),eH({level:"warn",phase:"ios_screenshot_fallback_skipped",data:{platform:s.platform,deviceKind:s.kind,deviceId:s.id,from:"simctl_screenshot",to:"runner",reason:"Simulator runner fallback is disabled to avoid XCTest automation instability during screenshot capture.",...n}}),r=(d=t)instanceof y?d:new y("COMMAND_FAILED","Failed to capture iOS screenshot: simulator screenshot retries exhausted",void 0,d),new y(r.code,r.message,{...r.details??{},hint:"Restart the simulator and retry. If simctl screenshots keep timing out and you accept the stability tradeoff, set AGENT_DEVICE_IOS_SIMULATOR_SCREENSHOT_RUNNER_FALLBACK=1 to allow XCTest runner fallback."},r)}lr(e,"simctl_screenshot",t)}await i.captureWithRunner(e,t,n,"boolean"==typeof r?r:void 0)}finally{await o().catch(t=>la(e,"restore_failed",t))}}async function s9(e,t){let n=eb.fromTimeoutMs(sp);await eC(async({deadline:n})=>{await s5(e,["io",e.id,"screenshot",t],{timeoutMs:Math.max(1e3,n?.remainingMs()??sp)})},{maxAttempts:5,baseDelayMs:1e3,maxDelayMs:5e3,jitter:.2,shouldRetry:e=>lo(e)},{deadline:n,phase:"ios_simulator_screenshot"})}async function s7(e,t,n,r){let i=(await i4(e,{command:"screenshot",appBundleId:n,fullscreen:r})).message;if(!i)throw new y("COMMAND_FAILED","Failed to capture iOS screenshot: runner returned no file path");"macos"===e.platform?await a.copyFile(i,t):"simulator"===e.kind?await lt(e,i,t):await le(e,i,t)}async function le(e,t,n){let r=eb.fromTimeoutMs(sf),a={exitCode:1,stdout:"",stderr:""};for(let i of iS)if(0===(a=await ed("xcrun",["devicectl","device","copy","from","--device",e.id,"--source",t,"--destination",n,"--domain-type","appDataContainer","--domain-identifier",i],{allowFailure:!0,timeoutMs:ln(r,sf,"runner screenshot copy")})).exitCode)return;let i=a.stderr.trim()||a.stdout.trim()||`devicectl exited with code ${a.exitCode}`;throw new y("COMMAND_FAILED",`Failed to capture iOS screenshot: ${i}`)}async function lt(e,t,n){let r=eb.fromTimeoutMs(sf),i="Unable to locate runner container for simulator screenshot";for(let s of iS){let l=await s5(e,["get_app_container",e.id,s,"data"],{allowFailure:!0,timeoutMs:ln(r,sf,"runner screenshot container lookup")});if(0!==l.exitCode){let e=l.stderr.trim();e&&(i=e);continue}let d=l.stdout.trim();if(!d){i="simctl get_app_container returned empty output";continue}for(let e of function(e,t){let n=o.resolve(e),r=t.trim();if(!r)return[];let a=[],i=new Set,s=e=>{let t=o.normalize(e);i.has(t)||(i.add(t),a.push(t))},l=r.replace(/^\/+/,""),d=l.replace(/\\/g,"/");if(l&&s(o.join(n,l)),o.isAbsolute(r)&&s(o.normalize(r)),d.startsWith("tmp/"))s(o.join(n,d));else{let e=d.lastIndexOf("/tmp/");if(e>=0){let t=d.slice(e+1);s(o.join(n,t))}}let u=o.basename(r);return u&&s(o.join(n,"tmp",u)),a}(d,t))try{await a.copyFile(e,n);return}catch(e){i=e instanceof Error?e.message:String(e)}}throw new y("COMMAND_FAILED",`Failed to capture iOS screenshot: ${i}`)}function ln(e,t,n){let r=e.remainingMs();if(r>0)return r;throw new y("COMMAND_FAILED",`iOS ${n} timed out after ${t}ms`,{timeoutMs:t,step:n})}function lr(e,t,n){let r=li(n);eH({level:"warn",phase:"ios_screenshot_fallback",data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,from:t,to:"runner",...r}})}function la(e,t,n){eH({level:"warn",phase:`ios_screenshot_status_bar_${t}`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,...li(n)}})}function li(e){if(!(e instanceof y))return{reason:e instanceof Error?e.message:String(e)};let t=e.details??{},n=Array.isArray(t.args)?t.args.filter(e=>"string"==typeof e).join(" "):void 0;return{errorCode:e.code,reason:e.message,timeoutMs:"number"==typeof t.timeoutMs?t.timeoutMs:void 0,exitCode:"number"==typeof t.exitCode?t.exitCode:void 0,stderr:"string"==typeof t.stderr&&t.stderr.trim()?t.stderr:void 0,stdout:"string"==typeof t.stdout&&t.stdout.trim()?t.stdout:void 0,commandArgs:n}}function lo(e){if(!(e instanceof y)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details??{},n="string"==typeof t.stdout?t.stdout:"",r="string"==typeof t.stderr?t.stderr:"",a=Array.isArray(t.args)?t.args.filter(e=>"string"==typeof e).join(" "):"",i=`${e.message}
|
|
24
17
|
${n}
|
|
25
|
-
${
|
|
26
|
-
${
|
|
27
|
-
${i}`.toLowerCase()))throw new y("COMMAND_FAILED",`Failed to uninstall iOS app ${n}`,{cmd:"xcrun",args:t,exitCode:
|
|
28
|
-
${
|
|
29
|
-
`,"utf8"),await
|
|
30
|
-
${t}`);if(!n)return null;let
|
|
31
|
-
${
|
|
32
|
-
${n}`.toLowerCase()).includes("unrecognized subcommand")||a.includes("unknown subcommand")||a.includes("not supported")||a.includes("unavailable")||a.includes("biometric")&&a.includes("invalid")}))throw new y("UNSUPPORTED_OPERATION",`${n.label} simulation is not supported on this simulator runtime.`,{deviceId:e.id,action:t,setting:n.settingName,attempts:i});throw new y("COMMAND_FAILED",`Failed to simulate ${n.settingName}.`,{deviceId:e.id,action:t,setting:n.settingName,attempts:i})}async function dW(e,t){await lP(e);let n=0,a=rg.fromTimeoutMs(lb);try{await ry(async({deadline:n})=>{var a;if(n?.isExpired())throw new y("COMMAND_FAILED","App launch deadline exceeded",{timeoutMs:lb});let r=(a=["launch",e.id,t],rj(e,a)),i=await ef("xcrun",r,{allowFailure:!0});if(0!==i.exitCode)throw new y("COMMAND_FAILED",`xcrun exited with code ${i.exitCode}`,{cmd:"xcrun",args:r,stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode})},{maxAttempts:10,baseDelayMs:1e3,maxDelayMs:5e3,jitter:.2,shouldRetry:e=>!!lE(e)&&(n+=1)<3},{deadline:a})}catch(n){if(lE(n)){var r;let a=(r=await lO(e,t)).installed?!1===r.simulatorCompatible?"ARCH_MISMATCH":"PERSISTENT_LAUNCH_FAIL":"APP_NOT_INSTALLED";n.details={...n.details,hint:function(e){switch(e){case"ARCH_MISMATCH":return"The app binary was not built for the simulator platform. Rebuild with a simulator destination or use a physical device.";case"APP_NOT_INSTALLED":return"The app bundle is not installed on this simulator. Run install before open.";case"PERSISTENT_LAUNCH_FAIL":return"The simulator repeatedly refused to launch the app. Inspect crash logs in Console.app or ~/Library/Logs/DiagnosticReports/ and consider reinstalling the app.";default:return"The simulator failed to launch the app. Retry with --debug and inspect diagnostics log for details."}}(a)}}throw n}}async function dX(e,t,n){let a=["device","process","launch","--device",e.id,t];n?.payloadUrl&&a.push("--payload-url",n.payloadUrl),await lN(a,{action:"launch iOS app",deviceId:e.id})}async function dH(e,t,n,a,r,i,o){if("tv"===t.target)return dK(await e(t,{command:"swipe",direction:function(e){switch(e){case"up":return"down";case"down":return"up";case"left":return"right";case"right":return"left";default:return e}}(r),appBundleId:n.appBundleId},a),i);let s=o??await dz(e,t,n,a),l=sA({direction:r,amount:i?.amount,pixels:i?.pixels,referenceWidth:s.referenceWidth,referenceHeight:s.referenceHeight});return dK(await e(t,{command:"drag",x:s.originX+l.x1,y:s.originY+l.y1,x2:s.originX+l.x2,y2:s.originY+l.y2,appBundleId:n.appBundleId},a),{amount:l.amount,pixels:l.pixels,preferProvidedPixels:!0})}async function dz(e,t,n,a){let r=await e(t,{command:"interactionFrame",appBundleId:n.appBundleId},a),i=dY(r.x),o=dY(r.y),s=dY(r.referenceWidth),l=dY(r.referenceHeight);if(void 0===i||void 0===o||void 0===s||void 0===l)throw new y("COMMAND_FAILED","interactionFrame did not return a usable frame");return{originX:i,originY:o,referenceWidth:s,referenceHeight:l}}function dY(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function dK(e,t){var n;let{x1:a,y1:r,x2:i,y2:o}={x1:dY((n=e).x),y1:dY(n.y),x2:dY(n.x2),y2:dY(n.y2)},s=dY(e.referenceWidth),l=dY(e.referenceHeight),d=void 0!==a&&void 0!==i?Math.round(Math.abs(i-a)):void 0,u=void 0!==r&&void 0!==o?Math.round(Math.abs(o-r)):void 0,c=t?.preferProvidedPixels&&void 0!==t.pixels?t.pixels:d&&d>0?d:u&&u>0?u:void 0;return{...void 0!==a?{x1:a}:{},...void 0!==r?{y1:r}:{},...void 0!==i?{x2:i}:{},...void 0!==o?{y2:o}:{},...void 0!==s?{referenceWidth:s}:{},...void 0!==l?{referenceHeight:l}:{},...t?.amount!==void 0?{amount:t.amount}:{},...void 0!==c?{pixels:c}:{}}}function dJ(){return process.env.WAYLAND_DISPLAY||"wayland"===process.env.XDG_SESSION_TYPE?"wayland":"x11"}let dZ=null;async function dQ(){if(dZ)return dZ;let e=dJ();if("wayland"===e){if(await em("ydotool"))return dZ={tool:"ydotool",display:e};throw new y("TOOL_MISSING","ydotool is required for input synthesis on Wayland (xdotool does not work on Wayland). Install it via your package manager.")}if(await em("xdotool"))return dZ={tool:"xdotool",display:e};throw new y("TOOL_MISSING","xdotool is required for input synthesis on X11. Install it via your package manager.")}async function d0(...e){await ef("xdotool",e,{allowFailure:!1,timeoutMs:1e4})}async function d1(...e){await ef("ydotool",e,{allowFailure:!1,timeoutMs:1e4})}async function d2(e,t){let{tool:n}=await dQ();"xdotool"===n?await d0("mousemove","--sync",String(e),String(t)):await d1("mousemove","--absolute","-x",String(e),"-y",String(t))}async function d3(e,t){let{tool:n}=await dQ();"xdotool"===n?await d0("key","--clearmodifiers",e):await d1("key",...t)}async function d4(e,t,n,a){await d2(e,t);let{tool:r}=await dQ();"xdotool"===r?await d0("click",n):await d1("click",a)}async function d5(e,t){await d4(e,t,"1","0xC0")}async function d8(e,t){await d4(e,t,"3","0xC1")}async function d6(e,t){await d4(e,t,"2","0xC2")}async function d9(e,t){let{tool:n}=await dQ();await d2(e,t),"xdotool"===n?await d0("click","--repeat","2","1"):(await d1("click","0xC0"),await d1("click","0xC0"))}async function d7(e,t,n=800){let{tool:a}=await dQ();await d2(e,t),"xdotool"===a?(await d0("mousedown","1"),await eb(n),await d0("mouseup","1")):(await d1("click","--down","0xC0"),await eb(n),await d1("click","--up","0xC0"))}async function ue(e,t){await d5(e,t)}async function ut(e,t,n,a,r=300){let{tool:i}=await dQ();await d2(e,t),"xdotool"===i?(await d0("mousedown","1"),await d0("mousemove","--sync",String(n),String(a)),await eb(r),await d0("mouseup","1")):(await d1("click","--down","0xC0"),await d1("mousemove","--absolute","-x",String(n),"-y",String(a)),await eb(r),await d1("click","--up","0xC0"))}async function un(e,t){let{tool:n}=await dQ(),a=5;if(t?.pixels!=null?a="xdotool"===n?Math.max(1,Math.round(t.pixels/15)):Math.max(1,Math.round(t.pixels/40)):t?.amount!=null&&(a=Math.max(1,Math.round(5*(t.amount/.6)))),"xdotool"===n)await d0("click","--repeat",String(a),"up"===e?"4":"down"===e?"5":"left"===e?"6":"7");else if("up"===e||"down"===e){let t="up"===e?String(-a):String(a);await d1("mousemove","--wheel","-y",t)}else{let t="left"===e?String(-a):String(a);await d1("mousemove","--wheel","-x",t)}}async function ua(e,t=0){let{tool:n}=await dQ();if("xdotool"===n){let n=["type"];t>0&&n.push("--delay",String(t)),n.push("--clearmodifiers","--",e),await d0(...n)}else await d1("type","--",e)}async function ur(e,t,n,a=0){await d5(e,t),await eb(100),await d3("ctrl+a",["29:1","30:1","30:0","29:0"]),await eb(50),await ua(n,a)}function ui(e){let t=null;return{resolve:async function(){if(t)return t;let n="wayland"===dJ()?"wayland":"x11";for(let a of"wayland"===n?e.wayland:e.x11)if(await em(a.command))return t={tool:a.tool,display:n};throw new y("TOOL_MISSING","wayland"===n?e.waylandError:e.x11Error)},resetCache:()=>{t=null}}}let uo=ui({wayland:[{tool:"grim",command:"grim"},{tool:"gnome-screenshot",command:"gnome-screenshot"}],x11:[{tool:"scrot",command:"scrot"},{tool:"import",command:"import"},{tool:"gnome-screenshot",command:"gnome-screenshot"}],waylandError:"grim or gnome-screenshot is required for screenshots on Wayland. Install via your package manager.",x11Error:"scrot, import (ImageMagick), or gnome-screenshot is required for screenshots on X11. Install via your package manager."});async function us(e){let{tool:t}=await uo.resolve();switch(t){case"grim":await ef("grim",[e]);break;case"scrot":await ef("scrot",[e]);break;case"import":await ef("import",["-window","root",e]);break;case"gnome-screenshot":await ef("gnome-screenshot",["-f",e])}}async function ul(e){if(e.includes("://")||e.startsWith("/"))return void await ef("xdg-open",[e]);if(await em(e)){ef(e,[],{allowFailure:!0}).catch(t=>{el({level:"warn",phase:"linux_app_launch",data:{app:e,error:String(t)}})}),await eb(500);return}await ef("xdg-open",[e],{allowFailure:!0})}async function ud(e){await em("wmctrl")?await ef("wmctrl",["-c",e],{allowFailure:!0}):await ef("pkill",["-x",e],{allowFailure:!0})}async function uu(){await d3("alt+Left",["56:1","105:1","105:0","56:0"])}async function uc(){await d3("super+d",["125:1","32:1","32:0","125:0"])}let up=ui({wayland:[{tool:"wl-clipboard",command:"wl-paste"}],x11:[{tool:"xclip",command:"xclip"},{tool:"xsel",command:"xsel"}],waylandError:"wl-paste (wl-clipboard) is required for clipboard access on Wayland. Install via your package manager.",x11Error:"xclip or xsel is required for clipboard access on X11. Install via your package manager."});async function uf(){let{tool:e}=await up.resolve();switch(e){case"wl-clipboard":return(await ef("wl-paste",["--no-newline"],{allowFailure:!0,timeoutMs:5e3})).stdout;case"xclip":return(await ef("xclip",["-selection","clipboard","-o"],{allowFailure:!0,timeoutMs:5e3})).stdout;case"xsel":return(await ef("xsel",["--clipboard","--output"],{allowFailure:!0,timeoutMs:5e3})).stdout}}async function uh(e){let{tool:t}=await up.resolve();switch(t){case"wl-clipboard":await ef("wl-copy",["--",e],{allowFailure:!1,timeoutMs:5e3});break;case"xclip":await ef("xclip",["-selection","clipboard"],{allowFailure:!1,timeoutMs:5e3,stdin:e});break;case"xsel":await ef("xsel",["--clipboard","--input"],{allowFailure:!1,timeoutMs:5e3,stdin:e})}}up.resetCache;let um={"push button":"Button","toggle button":"Button","push button menu":"Button",label:"StaticText",static:"StaticText",caption:"StaticText",text:"TextField",entry:"TextField","password text":"TextField","spin button":"TextField",terminal:"TextArea","document text":"TextArea",paragraph:"TextArea",frame:"Window",window:"Window",dialog:"Dialog",alert:"Alert","file chooser":"Dialog","color chooser":"Dialog","font chooser":"Dialog",panel:"Group",filler:"Group",section:"Group",form:"Group",grouping:"Group","layered pane":"Group","glass pane":"Group","root pane":"Group","option pane":"Group","internal frame":"Group","desktop frame":"Group","block quote":"Group",article:"Group",comment:"Group",landmark:"Group",log:"Group",marquee:"Group",math:"Group",notification:"Group","content deletion":"Group","content insertion":"Group",mark:"Group",suggestion:"Group","scroll pane":"ScrollArea","scroll bar":"ScrollBar","menu bar":"MenuBar",menu:"Menu","popup menu":"Menu","menu item":"MenuItem","check menu item":"MenuItem","radio menu item":"MenuItem","tearoff menu item":"MenuItem","check box":"CheckBox","radio button":"RadioButton",switch:"Switch","combo box":"ComboBox","page tab":"Tab","page tab list":"TabList",table:"Table","tree table":"Table","table cell":"Cell","table row":"Row","table column header":"Cell","table row header":"Cell","column header":"Cell","row header":"Cell",list:"List","list item":"ListItem","list box":"List",tree:"Tree","tree item":"TreeItem","description list":"List","description term":"ListItem","description value":"ListItem","tool bar":"Toolbar","status bar":"StatusBar","info bar":"StatusBar",slider:"Slider","progress bar":"ProgressBar","level bar":"ProgressBar",image:"Image",icon:"Image",animation:"Image",canvas:"Image","drawing area":"Image",video:"Video",audio:"Audio",link:"Link",hyperlink:"Link",separator:"Separator",application:"Application","tool tip":"Tooltip",timer:"Timer",heading:"Heading",footnote:"Footnote","title bar":"TitleBar","date editor":"DateEditor",rating:"Slider"},uw="atspi-dump.py",ug=null;async function uy(e,t={}){let a;if("linux"!==process.platform)throw new y("UNSUPPORTED_PLATFORM","AT-SPI2 bridge is only available on Linux");if(!await em("python3"))throw new y("TOOL_MISSING","python3 is required for AT-SPI2 accessibility snapshots on Linux.");let r=t.maxNodes??1500,i=t.maxDepth??12,s=t.maxApps??24,l=[function(){if(ug)return ug;let e=o.dirname(c(import.meta.url));for(let t=0;t<5;t++){let a=o.join(e,"src","platforms","linux",uw);if(n.existsSync(a))return ug=a,a;if(0===t){let t=o.join(e,uw);if(n.existsSync(t))return ug=t,t}e=o.dirname(e)}throw new y("TOOL_MISSING",`Cannot find ${uw}. Ensure the agent-device package is installed correctly.`)}(),"--surface",e,"--max-nodes",String(r),"--max-depth",String(i),"--max-apps",String(s)],d=await ef("python3",l,{allowFailure:!0,timeoutMs:3e4});if(0!==d.exitCode){let e=d.stderr.trim();if(e.includes("No module named")||e.includes("gi.require_version"))throw new y("TOOL_MISSING","AT-SPI2 Python bindings not found. Install python3-gi and gir1.2-atspi-2.0.",{cause:e});throw new y("COMMAND_FAILED",`AT-SPI2 snapshot failed (exit ${d.exitCode}): ${e||d.stdout}`)}try{a=JSON.parse(d.stdout)}catch{throw new y("COMMAND_FAILED",`AT-SPI2 snapshot returned invalid JSON: ${d.stdout.slice(0,200)}`)}if(a.error)throw new y("COMMAND_FAILED",`AT-SPI2: ${a.error}`);return{nodes:(a.nodes??[]).map(e=>{let t,n;return{index:e.index,type:(n=um[t=e.role.toLowerCase().trim()])||t.split(/[\s_-]+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(""),role:e.role,label:e.label??void 0,value:e.value??void 0,rect:e.rect??void 0,enabled:e.enabled??void 0,selected:e.selected??void 0,hittable:e.hittable??void 0,depth:e.depth,parentIndex:e.parentIndex??void 0,pid:e.pid??void 0,appName:e.appName??void 0,windowTitle:e.windowTitle??void 0}}),truncated:a.truncated,surface:e}}async function ub(e){let t="desktop"===e?"desktop":"frontmost-app"===e||"app"===e?"frontmost-app":("menubar"===e&&el({level:"warn",phase:"linux_snapshot",data:{message:"menubar surface is not supported on Linux, falling back to desktop"}}),"desktop"),n=await uy(t);return{nodes:n.nodes,truncated:n.truncated}}function uv(e){return e?.clickButton??"primary"}function uI(e){return"primary"===e.button?null:"click"!==e.commandLabel?new y("INVALID_ARGS","--button is supported only for click"):"macos"!==e.platform&&"linux"!==e.platform?new y("UNSUPPORTED_OPERATION",`click --button ${e.button} is supported only on macOS and Linux`):"macos"===e.platform&&"middle"===e.button?new y("UNSUPPORTED_OPERATION","click --button middle is not supported by the macOS runner yet"):"number"==typeof e.count||"number"==typeof e.intervalMs||"number"==typeof e.holdMs||"number"==typeof e.jitterPx||!0===e.doubleTap?new y("INVALID_ARGS",`click --button ${e.button} does not support repeat or gesture modifier flags`):null}function uA(e){return"primary"===e?{}:{button:e}}let ux=/^[A-Za-z0-9_.:-]{1,64}$/,uS=[[0,0],[1,0],[0,1],[-1,0],[0,-1],[1,1],[-1,1],[1,-1],[-1,-1]];async function uN(e,t,n){for(let a=0;a<e;a+=1)await n(a),a<e-1&&t>0&&await eb(t)}function u_(e,t){let a,r=t?.subject??"Payload",i=e.trim();if(!i)throw new y("INVALID_ARGS",`${r} cannot be empty`);let o=t?.expandPath?t.expandPath(i,t.cwd):i;try{if(!n.statSync(o).isFile())throw new y("INVALID_ARGS",`${r} path is not a file: ${o}`);return{kind:"file",path:o}}catch(t){if(t instanceof y)throw t;let e=t.code;if("EACCES"===e||"EPERM"===e)throw new y("INVALID_ARGS",`${r} file is not readable: ${o}`);if(e&&"ENOENT"!==e)throw new y("COMMAND_FAILED",`Unable to read ${r} file: ${o}`,{cause:String(t)})}if((a=i.trim()).startsWith("{")&&a.endsWith("}")||a.startsWith("[")&&a.endsWith("]"))return{kind:"inline",text:i};throw new y("INVALID_ARGS",`${r} file not found: ${o}`)}async function uM(e){let t=u_(e,{subject:"Push payload"}),n="inline"===t.kind?t.text:await uk(t.path);try{let e=JSON.parse(n);if(!e||"object"!=typeof e||Array.isArray(e))throw new y("INVALID_ARGS","push payload must be a JSON object");return e}catch(t){if(t instanceof y)throw t;throw new y("INVALID_ARGS",`Invalid push payload JSON: ${e}`)}}async function uk(e){try{return await r.readFile(e,"utf8")}catch(n){let t=n.code;if("ENOENT"===t)throw new y("INVALID_ARGS",`Push payload file not found: ${e}`);if("EISDIR"===t)throw new y("INVALID_ARGS",`Push payload path is not a file: ${e}`);if("EACCES"===t||"EPERM"===t)throw new y("INVALID_ARGS",`Push payload file is not readable: ${e}`);throw new y("COMMAND_FAILED",`Unable to read push payload file: ${e}`,{cause:String(n)})}}function uD(e){if(void 0===e)throw new y("INVALID_ARGS","rotate requires an orientation argument. Use portrait|portrait-upside-down|landscape-left|landscape-right.");switch(e?.trim().toLowerCase()){case"portrait":return"portrait";case"portrait-upside-down":case"upside-down":return"portrait-upside-down";case"landscape-left":case"left":return"landscape-left";case"landscape-right":case"right":return"landscape-right";default:throw new y("INVALID_ARGS",`Invalid rotation: ${e}. Use portrait|portrait-upside-down|landscape-left|landscape-right.`)}}let uE=ev(process.env.AGENT_DEVICE_IOS_DEVICECTL_LIST_TIMEOUT_MS,8e3,500),uO=/^(iphone|ipad|ipod|appletv)/i,uC=/\b(iphone|ipad|ipod)\b/i,uR=/^appletv/i,uP=["apple tv","appletv","tvos"],uT=/^==\s*(.+?)\s*==$/,uL=/^(?<name>.+?)\s+\[(?<id>[^[\]]+)\]\s*$/;function u$(e){return(e??"").trim().toLowerCase()}function uF(e){return u$(e.hardwareProperties?.platform)}function uU(e){return e.includes("tvos")}function uG(e){let t=u$(e);return uP.some(e=>t.includes(e))}function uV(e){return[e.name??"",e.deviceProperties?.name??"",e.deviceProperties?.deviceType??""]}function uB(e){return e.hardwareProperties?.productType??e.deviceProperties?.productType??""}async function uj(e={}){let t,n,a=rU(e.simulatorSetPath),r=e.target;try{t=await ef("xcrun",rB(["list","devices","-j"],{simulatorSetPath:a}))}catch{return null}try{n=JSON.parse(t.stdout)}catch{return null}let i=uq(n,a),o=null,s=null,l=null;for(let e of i)r&&e.target!==r||(e.booted&&(o=o??e),"mobile"===e.target&&(s=s??e),l=l??e);return o??s??l}function uq(e,t){let n=[];for(let[a,r]of Object.entries(e.devices))if(function(e){let t=u$(e);return t.includes("ios")||t.includes("tvos")}(a))for(let e of r)e.isAvailable&&n.push({platform:"ios",id:e.udid,name:e.name,kind:"simulator",target:uU(u$(a))?"tv":"mobile",booted:"Booted"===e.state,...t?{simulatorSetPath:t}:{}});return n}function uW(e,t){let n=new Set(e.map(e=>e.id)),a=[...e];for(let e of t)n.has(e.id)||(n.add(e.id),a.push(e));return a}async function uX(){let e=null;try{e=o.join(s.tmpdir(),`agent-device-devicectl-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);let t=await ef("xcrun",["devicectl","list","devices","--json-output",e],{allowFailure:!0,timeoutMs:uE});if(0!==t.exitCode)return[];let n=await r.readFile(e,"utf8");return function(e){let t=[];for(let n of e.result?.devices??[]){if(!function(e){var t;let n=uF(e);return!!(n.includes("ios")||n.includes("tvos"))||(t=uB(e),!!uO.test(t.trim())||uV(e).some(uG))}(n))continue;let e=n.hardwareProperties?.udid??n.identifier??"",a=n.name??n.deviceProperties?.name??e;e&&t.push({platform:"ios",id:e,name:a,kind:"device",target:function(e){var t;return uU(uF(e))?"tv":(t=uB(e),uR.test(t.trim())||uV(e).some(uG))?"tv":"mobile"}(n),booted:!0})}return t}(JSON.parse(n))}catch{return[]}finally{e&&await r.rm(e,{force:!0}).catch(()=>{})}}async function uH(){try{let e=await ef("xcrun",["xctrace","list","devices"],{allowFailure:!0});if(0!==e.exitCode)return[];return function(e){let t=[],n=null;for(let a of e.split(/\r?\n/)){let e=a.trim();if(!e)continue;let r=uT.exec(e);if(r){n=r[1]?.trim()??null;continue}if("Devices"!==n)continue;let i=uL.exec(e),o=i?.groups?.id?.trim()??"",s=i?.groups?.name?.trim()??"";if(!o||!s)continue;let l=function(e){return uG(e)?"tv":uC.test(e.trim())?"mobile":null}(s);l&&t.push({platform:"ios",id:o,name:s,kind:"device",target:l,booted:!0})}return t}(e.stdout)}catch{return[]}}async function uz(e={}){if("darwin"!==process.platform)throw new y("UNSUPPORTED_PLATFORM","Apple tools are only available on macOS");if(!await em("xcrun"))throw new y("TOOL_MISSING","xcrun not found in PATH");let t=rU(e.simulatorSetPath),n=await ef("xcrun",rB(["list","devices","-j"],{simulatorSetPath:t})),a=[];try{let e=JSON.parse(n.stdout);a=uq(e,t)}catch(e){throw new y("COMMAND_FAILED","Failed to parse simctl devices JSON",void 0,e)}if(a.push({platform:"macos",id:"host-macos-local",name:s.hostname(),kind:"device",target:"desktop",booted:!0}),t)return a;let[r,i]=await Promise.all([uX(),uH()]);return a=uW(a,r),uW(a,i)}async function uY(){return"linux"!==process.platform?[]:[{platform:"linux",id:"local",name:l(),kind:"device",target:"desktop",booted:!0}]}let uK=new u;async function uJ(e,t,n){let a,r=!!(t.udid||t.serial||t.deviceName);try{a=await ri(e,t,n)}catch(e){if(r||!(e instanceof y)||"DEVICE_NOT_FOUND"!==e.code)throw e}if(!r&&(!t.platform||"apple"===t.platform||"ios"===t.platform)&&"desktop"!==t.target&&(!a||"device"===a.kind)){let e=await uj({simulatorSetPath:n.simulatorSetPath,target:t.target});if(e)return e}if(a)return a;throw new y("DEVICE_NOT_FOUND","No devices found",{selector:t})}async function uZ(e){let t=rt(e.platform),n=rr({simulatorSetPath:rU(e.iosSimulatorDeviceSet),platform:t,target:e.target}),a=rV(e.androidDeviceAllowlist),r=function(e){let{flags:t,normalizedPlatform:n,iosSimulatorSetPath:a,androidSerialAllowlist:r}=e;return JSON.stringify({platform:n,target:t.target,device:t.device,udid:t.udid,serial:t.serial,iosSimulatorSetPath:a,androidSerialAllowlist:r?Array.from(r).sort():void 0})}({flags:e,normalizedPlatform:t,iosSimulatorSetPath:n,androidSerialAllowlist:a}),i={platform:t,target:e.target,cacheHit:!1};return await eo("resolve_target_device",async()=>{let o=function(e){let t=uK.getStore(),n=t?.get(e);if(n)return{...n}}(r);if(o)return i.cacheHit=!0,o;let s={platform:t,target:e.target,deviceName:e.device,udid:e.udid,serial:e.serial};if(s.target&&!s.platform)throw new y("INVALID_ARGS","Device target selector requires --platform. Use --platform ios|macos|android|linux|apple with --target mobile|tv|desktop.");if("linux"===s.platform){let e=await uY();return u0(r,await ri(e,s))}if("android"===s.platform){await oy();let e=await o$({serialAllowlist:a});return u0(r,await ri(e,s))}if(s.platform){let e=await uz({simulatorSetPath:n});return u0(r,await uJ(e,s,{simulatorSetPath:n}))}let l=[];try{l.push(...await o$({serialAllowlist:a}))}catch{}try{l.push(...await uz({simulatorSetPath:n}))}catch{}try{l.push(...await uY())}catch{}return u0(r,await ri(l,s,{simulatorSetPath:n}))},i)}async function uQ(e){return uK.getStore()?await e():await uK.run(new Map,e)}function u0(e,t){return uK.getStore()?.set(e,{...t}),t}async function u1(e,t,n,a,i){let s={requestId:i?.requestId,appBundleId:i?.appBundleId,verbose:i?.verbose,logPath:i?.logPath,traceLogPath:i?.traceLogPath},l=function(e,t){switch(e.platform){case"android":return{open:(t,n)=>sn(e,t,n?.activity),openDevice:()=>sl(e),close:t=>sd(e,t),tap:(t,n)=>s$(e,t,n),doubleTap:async(t,n)=>{await s$(e,t,n),await s$(e,t,n)},swipe:(t,n,a,r,i)=>sF(e,t,n,a,r,i),longPress:(t,n,a)=>sj(e,t,n,a),focus:(t,n)=>sX(e,t,n),type:(t,n)=>sq(e,t,n),fill:(t,n,a,r)=>sH(e,t,n,a,r),scroll:(t,n)=>sK(e,t,n),screenshot:t=>lf(e,t),back:t=>sU(e),home:()=>sG(e),rotate:t=>sV(e,t),appSwitcher:()=>sB(e),readClipboard:()=>s8(e),writeClipboard:t=>s6(e,t),setSetting:(t,n,a,r)=>lr(e,t,n,a,r)};case"linux":return{open:e=>ul(e),openDevice:()=>Promise.resolve(),close:e=>ud(e),tap:(e,t)=>d5(e,t),doubleTap:(e,t)=>d9(e,t),swipe:(e,t,n,a,r)=>ut(e,t,n,a,r),longPress:(e,t,n)=>d7(e,t,n),focus:(e,t)=>ue(e,t),type:(e,t)=>ua(e,t),fill:(e,t,n,a)=>ur(e,t,n,a),scroll:(e,t)=>un(e,t),screenshot:e=>us(e),back:()=>uu(),home:()=>uc(),rotate:()=>{throw new y("UNSUPPORTED_OPERATION","rotate not supported on Linux")},appSwitcher:()=>{throw new y("UNSUPPORTED_OPERATION","appSwitcher not yet supported on Linux")},readClipboard:()=>uf(),writeClipboard:e=>uh(e),setSetting:()=>{throw new y("UNSUPPORTED_OPERATION","setSetting not supported on Linux")}};case"ios":case"macos":{let n,{overrides:a,runnerOpts:r}={runnerOpts:n={verbose:t.verbose,logPath:t.logPath,traceLogPath:t.traceLogPath,requestId:t.requestId},overrides:{tap:async(a,r)=>await i5(e,{command:"tap",x:a,y:r,appBundleId:t.appBundleId},n),doubleTap:async(a,r)=>await i5(e,{command:"tapSeries",x:a,y:r,count:1,intervalMs:0,doubleTap:!0,appBundleId:t.appBundleId},n),swipe:async(a,r,i,o,s)=>await i5(e,{command:"drag",x:a,y:r,x2:i,y2:o,durationMs:s,appBundleId:t.appBundleId},n),longPress:async(a,r,i)=>await i5(e,{command:"longPress",x:a,y:r,durationMs:i,appBundleId:t.appBundleId},n),focus:async(a,r)=>await i5(e,{command:"tap",x:a,y:r,appBundleId:t.appBundleId},n),type:async(a,r)=>{await i5(e,{command:"type",text:a,delayMs:r,appBundleId:t.appBundleId},n)},fill:async(a,r,i,o)=>{let s=await i5(e,{command:"tap",x:a,y:r,appBundleId:t.appBundleId},n);return await i5(e,{command:"type",text:i,clearFirst:!0,delayMs:o,appBundleId:t.appBundleId},n),s},scroll:async(a,r)=>await dH(i5,e,t,n,a,r)}};return{open:(t,n)=>dN(e,t,{appBundleId:n?.appBundleId,url:n?.url}),openDevice:()=>d_(e),close:t=>dM(e,t),screenshot:async(t,n)=>{"macos"===e.platform&&n?.surface&&"app"!==n.surface?await ow(t,{surface:n.surface,fullscreen:n.fullscreen}):await ds(e,t,n?.appBundleId,n?.fullscreen)},back:async n=>{await i5(e,{command:"system"===n?"backSystem":"backInApp",appBundleId:t.appBundleId},r)},home:async()=>{await i5(e,{command:"home",appBundleId:t.appBundleId},r)},rotate:async n=>{await i5(e,{command:"rotate",orientation:n,appBundleId:t.appBundleId},r)},appSwitcher:async()=>{await i5(e,{command:"appSwitcher",appBundleId:t.appBundleId},r)},readClipboard:()=>dC(e),writeClipboard:t=>dR(e,t),setSetting:(t,n,a,r)=>dT(e,t,n,a,r),...a}}default:throw new y("UNSUPPORTED_PLATFORM",`Unsupported platform: ${e.platform}`)}}(e,s);return el({level:"debug",phase:"platform_command_prepare",data:{command:t,platform:e.platform,kind:e.kind}}),await eo("platform_command",async()=>{switch(t){case"open":return u2(e,l,n,i);case"close":{let e=n[0];if(!e)return{closed:"session",...ei("Closed session")};return await l.close(e),{app:e,...ei(`Closed: ${e}`)}}case"press":return u3(e,l,n,i,s);case"swipe":return u4(e,l,n,i,s);case"longpress":{let e=Number(n[0]),t=Number(n[1]),a=n[2]?Number(n[2]):void 0;if(Number.isNaN(e)||Number.isNaN(t))throw new y("INVALID_ARGS","longpress requires x y [durationMs]");return await l.longPress(e,t,a),{x:e,y:t,durationMs:a,...ei(`Long pressed (${e}, ${t})`)}}case"focus":{let[e,t]=n.map(Number);if(Number.isNaN(e)||Number.isNaN(t))throw new y("INVALID_ARGS","focus requires x y");return await l.focus(e,t),{x:e,y:t,...ei(`Focused (${e}, ${t})`)}}case"type":{let e=function(e){let t=e[0]?.trim();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(e)throw new y("INVALID_ARGS",`type does not accept a target ref like "${e}"`,{hint:`Use fill ${e} "text" to target that field, or press ${e} then type "text" to append.`});let t=n.join(" ");if(!t)throw new y("INVALID_ARGS","type requires text");let a=nb(i?.delayMs??0,"delay-ms",0,1e4);return await l.type(t,a),{text:t,delayMs:a,...ei(ci("Typed",t))}}case"fill":{let e=Number(n[0]),t=Number(n[1]),a=n.slice(2).join(" ");if(Number.isNaN(e)||Number.isNaN(t)||!a)throw new y("INVALID_ARGS","fill requires x y text");let r=nb(i?.delayMs??0,"delay-ms",0,1e4);return await l.fill(e,t,a,r),{x:e,y:t,text:a,delayMs:r,...ei(ci("Filled",a))}}case"scroll":return u5(l,n,i);case"pinch":return u8(e,n,i,s);case"trigger-app-event":{let{eventName:t,payload:a}=function(e){let t=e[0]?.trim(),n=e[1]?.trim();if(!t)throw new y("INVALID_ARGS","trigger-app-event requires <event> [payloadJson]");if(!ux.test(t))throw new y("INVALID_ARGS",`Invalid trigger-app-event event name: ${t}`,{hint:"Use 1-64 chars: letters, numbers, underscore, dot, colon, or dash."});if(e.length>2)throw new y("INVALID_ARGS","trigger-app-event accepts at most two arguments: <event> [payloadJson]");let a=function(e,t){if(e)try{let n=JSON.parse(e);if(!n||"object"!=typeof n||Array.isArray(n))throw new y("INVALID_ARGS",`trigger-app-event payload for "${t}" must be a JSON object`);let a=JSON.stringify(n);if(Buffer.byteLength(a,"utf8")>8192)throw new y("INVALID_ARGS",`trigger-app-event payload for "${t}" exceeds 8192 bytes`);return n}catch(t){if(t instanceof y)throw t;throw new y("INVALID_ARGS",`Invalid trigger-app-event payload JSON: ${e}`)}}(n,t);return{eventName:t,payload:a}}(n),r=function(e,t,n){var a;let r,i=(r=("ios"===(a=e)?process.env.AGENT_DEVICE_IOS_APP_EVENT_URL_TEMPLATE:"macos"===a?process.env.AGENT_DEVICE_MACOS_APP_EVENT_URL_TEMPLATE:process.env.AGENT_DEVICE_ANDROID_APP_EVENT_URL_TEMPLATE)??process.env.AGENT_DEVICE_APP_EVENT_URL_TEMPLATE,r?.trim()||void 0);if(!i)throw new y("UNSUPPORTED_OPERATION",`No app event URL template configured for ${e}.`,{hint:`Set AGENT_DEVICE_${e.toUpperCase()}_APP_EVENT_URL_TEMPLATE or AGENT_DEVICE_APP_EVENT_URL_TEMPLATE, for example "myapp://agent-device/event?name={event}&payload={payload}".`});let o=n?JSON.stringify(n):"",s=i.replaceAll("{event}",encodeURIComponent(t)).replaceAll("{payload}",encodeURIComponent(o)).replaceAll("{platform}",encodeURIComponent(e));if(s.length>4096)throw new y("INVALID_ARGS","trigger-app-event URL exceeds maximum supported length",{hint:"Reduce payload size or shorten AGENT_DEVICE_*_APP_EVENT_URL_TEMPLATE.",length:s.length,maxLength:4096});return s}(e.platform,t,a);return await l.open(r,{appBundleId:i?.appBundleId}),{event:t,eventUrl:r,transport:"deep-link",...ei(`Triggered app event: ${t}`)}}case"screenshot":{let e=n[0]??a??`./screenshot-${Date.now()}.png`;return await r.mkdir(o.dirname(e),{recursive:!0}),await l.screenshot(e,{appBundleId:i?.appBundleId,fullscreen:i?.screenshotFullscreen,surface:i?.surface}),{path:e,...ei(`Saved screenshot: ${e}`)}}case"back":return await l.back(i?.backMode),{action:"back",mode:i?.backMode??"in-app",...ei("Back")};case"home":return await l.home(),{action:"home",...ei("Home")};case"rotate":{let e=uD(n[0]);return await l.rotate(e),{action:"rotate",orientation:e,...ei(`Rotated to ${e}`)}}case"app-switcher":return await l.appSwitcher(),{action:"app-switcher",...ei("Opened app switcher")};case"clipboard":return u6(l,n);case"keyboard":return u9(e,l,n,i,s);case"settings":return u7(e,l,n,i);case"push":return ce(e,n,i);case"snapshot":return ct(e,n,i,s);case"read":return cn(e,n,i,s);default:throw new y("INVALID_ARGS",`Unknown command: ${t}`)}},{command:t,platform:e.platform})}async function u2(e,t,n,a){let r=n[0],i=n[1];if(n.length>2)throw new y("INVALID_ARGS","open accepts at most two arguments: <app|url> [url]");if(!r)return await t.openDevice(),{app:null,...ei("Opened device")};if(void 0!==i){if("android"===e.platform)throw new y("INVALID_ARGS","open <app> <url> is supported only on Apple platforms");if(ov(r))throw new y("INVALID_ARGS","open <app> <url> requires an app target as the first argument");if(!ov(i))throw new y("INVALID_ARGS","open <app> <url> requires a valid URL target");return await t.open(r,{activity:a?.activity,appBundleId:a?.appBundleId,url:i}),{app:r,url:i,...ei(`Opened: ${r}`)}}return await t.open(r,{activity:a?.activity,appBundleId:a?.appBundleId}),{app:r,...ei(`Opened: ${r}`)}}async function u3(e,t,n,a,r){let i,[o,s]=n.map(Number);if(Number.isNaN(o)||Number.isNaN(s))throw new y("INVALID_ARGS","press requires x y");if("macos"===e.platform&&a?.surface&&"app"!==a.surface){let e=uv(a);if("primary"!==e)throw new y("UNSUPPORTED_OPERATION",`${e} click is not supported on macOS ${a.surface} sessions.`);return await om(o,s,{bundleId:a.appBundleId,surface:a.surface}),{x:o,y:s,...ei(ca({x:o,y:s}))}}let l=uv(a);if("primary"!==l){let t=uI({commandLabel:"click",platform:e.platform,button:l,count:a?.count,intervalMs:a?.intervalMs,holdMs:a?.holdMs,jitterPx:a?.jitterPx,doubleTap:a?.doubleTap});if(t)throw t;return"linux"===e.platform?"secondary"===l?await d8(o,s):await d6(o,s):await i5(e,{command:"mouseClick",x:o,y:s,button:l,appBundleId:a?.appBundleId},{verbose:a?.verbose,logPath:a?.logPath,traceLogPath:a?.traceLogPath,requestId:a?.requestId}),{x:o,y:s,button:l,...ei(ca({x:o,y:s,button:l}))}}let d=nb(a?.count??1,"count",1,200),u=nb(a?.intervalMs??0,"interval-ms",0,1e4),c=nb(a?.holdMs??0,"hold-ms",0,1e4),p=nb(a?.jitterPx??0,"jitter-px",0,100),f=a?.doubleTap===!0;if(f&&c>0)throw new y("INVALID_ARGS","double-tap cannot be combined with hold-ms");if(f&&p>0)throw new y("INVALID_ARGS","double-tap cannot be combined with jitter-px");if(rn(e.platform)&&d>1&&0===c&&0===p){let t=await i5(e,{command:"tapSeries",x:o,y:s,count:d,intervalMs:u,doubleTap:f,appBundleId:a?.appBundleId},{verbose:a?.verbose,logPath:a?.logPath,traceLogPath:a?.traceLogPath,requestId:a?.requestId});return{x:o,y:s,count:d,intervalMs:u,holdMs:c,jitterPx:p,doubleTap:f,timingMode:"runner-series",...t,...ei(ca({x:o,y:s}))}}return await uN(d,u,async e=>{let[n,a]=function(e,t){if(t<=0)return[0,0];let[n,a]=uS[e%uS.length];return[n*t,a*t]}(e,p),r=o+n,l=s+a;if(f){i??=await t.doubleTap(r,l)??void 0;return}c>0?i??=await t.longPress(r,l,c)??void 0:i??=await t.tap(r,l)??void 0}),es({x:o,y:s,count:d,intervalMs:u,holdMs:c,jitterPx:p,doubleTap:f,...i},ca({x:o,y:s}))}async function u4(e,t,n,a,r){let i=Number(n[0]),o=Number(n[1]),s=Number(n[2]),l=Number(n[3]);if([i,o,s,l].some(Number.isNaN))throw new y("INVALID_ARGS","swipe requires x1 y1 x2 y2 [durationMs]");let d=nb(n[4]?Number(n[4]):250,"durationMs",16,1e4),u="ios"===e.platform?Math.min(60,Math.max(16,Math.round(d))):d,c=nb(a?.count??1,"count",1,200),p=nb(a?.pauseMs??0,"pause-ms",0,1e4),f=a?.pattern??"one-way";if("one-way"!==f&&"ping-pong"!==f)throw new y("INVALID_ARGS",`Invalid pattern: ${f}`);if(rn(e.platform)&&c>1){let t=await i5(e,{command:"dragSeries",x:i,y:o,x2:s,y2:l,durationMs:u,count:c,pauseMs:p,pattern:f,appBundleId:a?.appBundleId},{verbose:a?.verbose,logPath:a?.logPath,traceLogPath:a?.traceLogPath,requestId:a?.requestId});return{x1:i,y1:o,x2:s,y2:l,durationMs:d,effectiveDurationMs:u,timingMode:"runner-series",count:c,pauseMs:p,pattern:f,...t,...ei(cr(c,f))}}return await uN(c,p,async e=>{"ping-pong"===f&&e%2==1?await t.swipe(s,l,i,o,u):await t.swipe(i,o,s,l,u)}),es({x1:i,y1:o,x2:s,y2:l,durationMs:d,effectiveDurationMs:u,timingMode:"ios"===e.platform?"safe-normalized":"direct",count:c,pauseMs:p,pattern:f},cr(c,f))}async function u5(e,t,n){let a=t[0],r=t[1]?Number(t[1]):void 0,i=n?.pixels;if(!a)throw new y("INVALID_ARGS","scroll requires direction");if(void 0!==r&&!Number.isFinite(r))throw new y("INVALID_ARGS","scroll amount must be a number");if(void 0!==r&&void 0!==i)throw new y("INVALID_ARGS","scroll accepts either a relative amount or --pixels, not both");let o=function(e){switch(e){case"up":case"down":case"left":case"right":return e;default:throw new y("INVALID_ARGS",`Unknown direction: ${e}`)}}(a),s=await e.scroll(o,{amount:r,pixels:i});return es({direction:o,...void 0!==r?{amount:r}:{},...void 0!==i?{pixels:i}:{},...s},void 0!==i?`Scrolled ${o} by ${i}px`:void 0!==r?`Scrolled ${o} by ${r}`:`Scrolled ${o}`)}async function u8(e,t,n,a){if("android"===e.platform)throw new y("UNSUPPORTED_OPERATION","Android pinch is not supported in current adb backend; requires instrumentation-based backend.");if("macos"===e.platform&&n?.surface&&"app"!==n.surface)throw new y("UNSUPPORTED_OPERATION","pinch is only supported in macOS app sessions. Re-open the target app without --surface desktop|menubar|frontmost-app first.");let r=Number(t[0]),i=t[1]?Number(t[1]):void 0,o=t[2]?Number(t[2]):void 0;if(Number.isNaN(r)||r<=0)throw new y("INVALID_ARGS","pinch requires scale > 0");return await i5(e,{command:"pinch",scale:r,x:i,y:o,appBundleId:n?.appBundleId},{verbose:n?.verbose,logPath:n?.logPath,traceLogPath:n?.traceLogPath,requestId:n?.requestId}),{scale:r,x:i,y:o,...ei(`Pinched to scale ${r}`)}}async function u6(e,t){let n=(t[0]??"").toLowerCase();if("read"!==n&&"write"!==n)throw new y("INVALID_ARGS","clipboard requires a subcommand: read or write");if("read"===n){if(1!==t.length)throw new y("INVALID_ARGS","clipboard read does not accept additional arguments");return{action:n,text:await e.readClipboard()}}if(t.length<2)throw new y("INVALID_ARGS",'clipboard write requires text (use "" to clear clipboard)');let a=t.slice(1).join(" ");return await e.writeClipboard(a),{action:n,textLength:Array.from(a).length,...ei("Clipboard updated")}}async function u9(e,t,n,a,r){let i=(n[0]??"status").toLowerCase();if("status"!==i&&"get"!==i&&"dismiss"!==i)throw new y("INVALID_ARGS","keyboard requires a subcommand: status, get, or dismiss");if(n.length>1)throw new y("INVALID_ARGS","keyboard accepts at most one subcommand argument");if("android"===e.platform){if("dismiss"===i){let t=await s5(e);return{platform:"android",action:"dismiss",attempts:t.attempts,wasVisible:t.wasVisible,dismissed:t.dismissed,visible:t.visible,inputType:t.inputType,type:t.type}}let t=await s4(e);return{platform:"android",action:"status",visible:t.visible,inputType:t.inputType,type:t.type}}if("ios"===e.platform){if("dismiss"!==i)throw new y("UNSUPPORTED_OPERATION","keyboard status/get is currently supported only on Android; use keyboard dismiss on iOS");let t=await i5(e,{command:"keyboardDismiss",appBundleId:a?.appBundleId},r);return{platform:"ios",action:"dismiss",wasVisible:t.wasVisible,dismissed:t.dismissed,visible:t.visible,...ei(t.dismissed?"Keyboard dismissed":"Keyboard already hidden")}}throw new y("UNSUPPORTED_OPERATION","keyboard is supported only on Android and iOS")}async function u7(e,t,n,a){var r;let[i,o,s,l,d]=n,u="permission"===i?{permissionTarget:s,permissionMode:l}:void 0;el({level:"debug",phase:"settings_apply",data:{setting:i,state:o,target:s,mode:l,platform:e.platform}});let c=await t.setSetting(i,o,d??a?.appBundleId,u);return c&&"object"==typeof c?es({setting:i,state:o,...c},("string"==typeof(r=c).message&&r.message.length>0?r.message:void 0)??`Updated setting: ${i}`):{setting:i,state:o,...ei(`Updated setting: ${i}`)}}async function ce(e,t,n){let a=t[0]?.trim(),r=t[1]?.trim();if(!a||!r)throw new y("INVALID_ARGS","push requires <bundle|package> <payload.json|inline-json>");let i=await uM(r);if("ios"===e.platform)return await dP(e,a,i),{platform:"ios",bundleId:a,...ei(`Pushed notification to ${a}`)};let o=await lc(e,a,i);return{platform:"android",package:a,action:o.action,extrasCount:o.extrasCount,...ei(`Pushed notification to ${a}`)}}async function ct(e,t,n,a){if("linux"===e.platform){let e=await eo("snapshot_capture",async()=>await ub(n?.surface),{backend:"linux-atspi"});return{nodes:e.nodes??[],truncated:e.truncated??!1,backend:"linux-atspi"}}if("android"!==e.platform){let t=await eo("snapshot_capture",async()=>await i5(e,{command:"snapshot",appBundleId:n?.appBundleId,interactiveOnly:n?.snapshotInteractiveOnly,compact:n?.snapshotCompact,depth:n?.snapshotDepth,scope:n?.snapshotScope,raw:n?.snapshotRaw},{verbose:n?.verbose,logPath:n?.logPath,traceLogPath:n?.traceLogPath,requestId:n?.requestId}),{backend:"xctest"}),a=t.nodes??[];if(0===a.length&&"simulator"===e.kind)throw new y("COMMAND_FAILED","XCTest snapshot returned 0 nodes on iOS simulator.");return{nodes:a,truncated:t.truncated??!1,backend:"xctest"}}let r=await eo("snapshot_capture",async()=>await s_(e,{interactiveOnly:n?.snapshotInteractiveOnly,compact:n?.snapshotCompact,depth:n?.snapshotDepth,scope:n?.snapshotScope,raw:n?.snapshotRaw}),{backend:"android"});return{nodes:r.nodes??[],truncated:r.truncated??!1,backend:"android",analysis:r.analysis,androidSnapshot:r.androidSnapshot}}async function cn(e,t,n,a){let[r,i]=t.map(Number);if(Number.isNaN(r)||Number.isNaN(i))throw new y("INVALID_ARGS","read requires x y");if("android"===e.platform)return{action:"read",text:await s2(e,r,i)??""};if("macos"===e.platform&&n?.surface&&"app"!==n.surface)return{action:"read",text:(await oh(r,i,{bundleId:n.appBundleId,surface:n.surface})).text};let o=await i5(e,{command:"readText",x:r,y:i,appBundleId:n?.appBundleId},{verbose:n?.verbose,logPath:n?.logPath,traceLogPath:n?.traceLogPath,requestId:n?.requestId});return{action:"read",text:"string"==typeof o.text?o.text:"string"==typeof o.message?o.message:""}}function ca(e){return e.button&&"primary"!==e.button?`Clicked ${e.button} (${e.x}, ${e.y})`:`Tapped (${e.x}, ${e.y})`}function cr(e,t){return e<=1?"Swiped":"ping-pong"===t?`Swiped ${e} times (ping-pong)`:`Swiped ${e} times`}function ci(e,t){return`${e} ${Array.from(t).length} chars`}let co=ev(process.env.AGENT_DEVICE_IOS_DEVICE_READY_TIMEOUT_MS,15e3,1e3),cs=new Map;async function cl(e){var t;let n,a=(n="simulator"===(t=e).kind?t.simulatorSetPath??"":"",JSON.stringify([t.platform,t.kind,t.id,t.target??"",n])),r=cs.get(a);if(void 0!==r){if(r>Date.now())return;cs.delete(a)}if("ios"===e.platform){if("simulator"===e.kind){let{ensureBootedSimulator:t}=await Promise.resolve(eR);await t(e),cd(a);return}if("device"===e.kind){await cu(e.id),cd(a);return}}if("android"===e.platform){let{waitForAndroidBoot:t}=await Promise.resolve(eC);await t(e.id),cd(a)}}function cd(e){cs.set(e,Date.now()+5e3)}async function cu(e){let t=o.join(s.tmpdir(),`agent-device-ready-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),n=Math.max(1,Math.ceil(co/1e3));try{let a=await ef("xcrun",["devicectl","device","info","details","--device",e,"--json-output",t,"--timeout",String(n)],{allowFailure:!0,timeoutMs:co+3e3}),r=String(a.stdout??""),i=String(a.stderr??""),o=await cc(t);if(0===a.exitCode){if(!o.parsed)throw new y("COMMAND_FAILED","iOS device readiness probe failed",{kind:"probe_inconclusive",deviceId:e,stdout:r,stderr:i,hint:"CoreDevice returned success but readiness JSON output was missing or invalid. Retry; if it persists restart Xcode and the iOS device."});let t=o?.tunnelState?.toLowerCase();if("connecting"===t)throw new y("COMMAND_FAILED","iOS device is not ready for automation",{kind:"not_ready",deviceId:e,tunnelState:t,hint:"Device tunnel is still connecting. Keep the device unlocked and connected by cable until it is fully available in Xcode Devices, then retry."});return}throw new y("COMMAND_FAILED","iOS device is not ready for automation",{kind:"not_ready",deviceId:e,stdout:r,stderr:i,exitCode:a.exitCode,tunnelState:o?.tunnelState,hint:cp(r,i)})}catch(t){if(t instanceof y&&"COMMAND_FAILED"===t.code){if("not_ready"===("string"==typeof t.details?.kind?t.details.kind:""))throw t;let n=t.details??{},a=String(n.stdout??""),r=String(n.stderr??""),i=Number(n.timeoutMs??co),o=`CoreDevice did not respond within ${i}ms. Keep the device unlocked and trusted, then retry; if it persists restart Xcode and the iOS device.`;throw new y("COMMAND_FAILED","iOS device readiness probe failed",{deviceId:e,cause:t.message,timeoutMs:i,stdout:a,stderr:r,hint:a||r?cp(a,r):o},t)}throw new y("COMMAND_FAILED","iOS device readiness probe failed",{deviceId:e,hint:"Reconnect the device, keep it unlocked, and retry."},t instanceof Error?t:void 0)}finally{await r.rm(t,{force:!0}).catch(()=>{})}}async function cc(e){try{let t=await r.readFile(e,"utf8"),n=JSON.parse(t),a=function(e){let t=e?.result;if(!t||"object"!=typeof t)return{};let n=t.connectionProperties?.tunnelState,a=t.device?.connectionProperties?.tunnelState,r="string"==typeof n?n:"string"==typeof a?a:void 0;return r?{tunnelState:r}:{}}(n);return{parsed:!0,tunnelState:a.tunnelState}}catch{return{parsed:!1}}}function cp(e,t){let n=lD(e,t);return n||(`${e}
|
|
33
|
-
${t}`.toLowerCase().includes("timed out waiting for all destinations")?"Xcode destination did not become available in time. Keep device unlocked and retry.":lk)}async function cf(e,t,n){let a=e.get(t),r=a?.device??await uZ(n??{});return a||await cl(r),{session:a,device:r}}async function ch(e,t,n){let a=!e&&"ios"===t.platform;try{return await n()}finally{a&&await iJ(t.id)}}function cm(e,t,n,a){t&&e.recordAction(t,{command:n.command,positionals:n.positionals??[],flags:n.flags??{},result:a})}async function cw(e){let{req:t,logPath:n,sessionStore:a,session:r,device:i}=e,o=(t.positionals?.[0]??"get").toLowerCase(),s=r?"frontmost-app"===r.surface?{surface:"frontmost-app"}:{bundleId:r.appBundleId,surface:r.surface}:{};if(!rc("alert",i))return a9("UNSUPPORTED_OPERATION","alert is not supported on this device");if("macos"===i.platform){let e=async()=>await op("wait"===o?"get":o,s);if("wait"===o){let n=a7(t.positionals?.[1])??1e4,i=Date.now();for(;Date.now()-i<n;){try{let n=await e();return cm(a,r,t,n),{ok:!0,data:n}}catch{}await eb(300)}return a9("COMMAND_FAILED","alert wait timed out")}let n="accept"===o||"dismiss"===o?o:"get";if("accept"===n||"dismiss"===n){let e,i=Date.now();for(;Date.now()-i<2e3;){try{let e=await op(n,s);return cm(a,r,t,e),{ok:!0,data:e}}catch(n){e=n;let t=String(n?.message??"").toLowerCase();if(!t.includes("alert not found")&&!t.includes("no alert"))break}await eb(300)}throw cg(e)}let i=await op("get",s);return cm(a,r,t,i),{ok:!0,data:i}}if("wait"===o){let e=a7(t.positionals?.[1])??1e4,o=Date.now();for(;Date.now()-o<e;){try{let e=await i5(i,{command:"alert",action:"get",appBundleId:r?.appBundleId},{verbose:t.flags?.verbose,logPath:n,traceLogPath:r?.trace?.outPath,requestId:t.meta?.requestId});return cm(a,r,t,e),{ok:!0,data:e}}catch{}await eb(300)}return a9("COMMAND_FAILED","alert wait timed out")}let l="accept"===o||"dismiss"===o?o:"get",d={verbose:t.flags?.verbose,logPath:n,traceLogPath:r?.trace?.outPath,requestId:t.meta?.requestId};if("accept"===l||"dismiss"===l){let e,n=Date.now();for(;Date.now()-n<2e3;){try{let e=await i5(i,{command:"alert",action:l,appBundleId:r?.appBundleId},d);return cm(a,r,t,e),{ok:!0,data:e}}catch(n){e=n;let t=String(n?.message??"").toLowerCase();if(!t.includes("alert not found")&&!t.includes("no alert"))break}await eb(300)}throw cg(e)}let u=await i5(i,{command:"alert",action:l,appBundleId:r?.appBundleId},d);return cm(a,r,t,u),{ok:!0,data:u}}function cg(e){if(!(e instanceof y))return e;let t=String(e.message??"").toLowerCase();return t.includes("alert not found")||t.includes("no alert")?new y(e.code,e.message,{...e.details??{},hint:"If the permission sheet is visible in snapshot or screenshot but alert reports no alert, take a scoped snapshot around the visible button label and use press @ref."}):e}function cy(e,t,n,a,r){return{requestId:r??er().requestId,appBundleId:n,activity:t?.activity,verbose:t?.verbose,logPath:e,traceLogPath:a,snapshotInteractiveOnly:t?.snapshotInteractiveOnly,snapshotCompact:t?.snapshotCompact,snapshotDepth:t?.snapshotDepth,snapshotScope:t?.snapshotScope,snapshotRaw:t?.snapshotRaw,screenshotFullscreen:t?.screenshotFullscreen,screenshotMaxSize:t?.screenshotMaxSize,count:t?.count,intervalMs:t?.intervalMs,delayMs:t?.delayMs,holdMs:t?.holdMs,jitterPx:t?.jitterPx,pixels:t?.pixels,doubleTap:t?.doubleTap,clickButton:uv(t),backMode:t?.backMode,pauseMs:t?.pauseMs,pattern:t?.pattern}}async function cb(e){let t,{req:n,logPath:a,sessionStore:r,session:i,device:o,parsed:s}=e,{setting:l,state:d,permissionTarget:u}=s;if(!rc("settings",o))return a9("UNSUPPORTED_OPERATION","settings is not supported on this device");if("macos"===o.platform&&"appearance"!==(t=l.trim().toLowerCase())&&"permission"!==t)return a9("INVALID_ARGS",eW(l));let c=i?.appBundleId,p="permission"===l?[l,d,u??"",n.positionals?.[3]??"",c??""]:[l,d,c??""],f=await u1(o,"settings",p,n.flags?.out,{...cy(a,n.flags,c,i?.trace?.outPath)});return cm(r,i,n,f??{setting:l,state:d}),{ok:!0,data:f??{setting:l,state:d}}}function cv(e,t={}){let n=!0===t.plural?"do":"does";return{resolveInput:async()=>{throw new y("UNSUPPORTED_OPERATION",`${e} ${n} not resolve input artifacts`)},reserveOutput:async()=>{throw new y("UNSUPPORTED_OPERATION",`${e} ${n} not reserve output artifacts`)},createTempFile:async()=>{throw new y("UNSUPPORTED_OPERATION",`${e} ${n} not create temporary files`)}}}let cI=[250,400,600];function cA(e,t,n=e.snapshot){if("android"!==e.device.platform)return;let a=n?.comparisonSafe===!0;e.androidSnapshotFreshness={action:t,markedAt:Date.now(),baselineCount:n?.nodes.length??0,baselineSignatures:a?c_(n?.nodes??[]):void 0,routeComparable:a}}function cx(e){if(!e||"android"!==e.device.platform)return;let t=e.androidSnapshotFreshness;if(t)return Date.now()-t.markedAt>2500?void delete e.androidSnapshotFreshness:t}function cS(e){e&&"android"===e.device.platform&&delete e.androidSnapshotFreshness}function cN(e){return"press"===e||"click"===e||"back"===e||"open"===e}function c_(e){return e.map(e=>[e.depth??0,e.type??"",e.role??"",e.label??"",e.value??"",e.identifier??"",!1===e.enabled?"disabled":"enabled",!0===e.selected?"selected":"unselected",!0===e.hittable?"hittable":"not-hittable"].join("|"))}async function cM(e){let t=cx(e.session);if(t&&"android"===e.device.platform)return await cD(e,t);let n=await ck(e);return cS(e.session),{snapshot:cR(n,cO(e)),analysis:n.analysis,androidSnapshot:n.androidSnapshot}}async function ck(e){let{device:t,session:n,flags:a,outPath:r,logPath:i,snapshotScope:o}=e;if("linux"===t.platform){let e=await ub(n?.surface);return cP({nodes:e.nodes,truncated:e.truncated,backend:"linux-atspi"},{snapshotDepth:a?.snapshotDepth,snapshotInteractiveOnly:a?.snapshotInteractiveOnly,snapshotScope:o})}return"macos"===t.platform&&n?.surface&&"app"!==n.surface?cP(await of(n.surface,{bundleId:"menubar"===n.surface?n.appBundleId:void 0}),{snapshotDepth:a?.snapshotDepth,snapshotInteractiveOnly:a?.snapshotInteractiveOnly,snapshotScope:o}):await u1(t,"snapshot",[],r,{...cy(i,{...a,snapshotScope:o},n?.appBundleId,n?.trace?.outPath)})}async function cD(e,t){let n=await cE(e),a=cC(n,t,e),r=0,i=t.markedAt+1500;for(let o of cI){if(!a)break;let s=i-Date.now();if(s<=0)break;await eb(Math.min(o,s)),n=await cE(e),r+=1,a=cC(n,t,e)}return a||cS(e.session),{snapshot:n.snapshot,analysis:n.data.analysis,androidSnapshot:n.data.androidSnapshot,freshness:r>0||a?{action:t.action,retryCount:r,staleAfterRetries:!!a,reason:a??void 0}:void 0}}async function cE(e){let t=await ck(e);return{data:t,snapshot:cR(t,cO(e))}}function cO(e){return void 0===e.snapshotScope?e.flags:{...e.flags,snapshotScope:e.snapshotScope}}function cC(e,t,n){var a,r;let i=n.flags?.snapshotInteractiveOnly===!0,o=e.data.analysis;if(i&&0===e.snapshot.nodes.length&&o&&o.rawNodeCount>=12)return"empty-interactive";if("ref-refresh"===n.androidFreshnessMode)return null;return(a=t.baselineCount,r=e.snapshot.nodes.length,!(a<12)&&r<=Math.floor(.2*a))?e.snapshot.nodes.some(e=>!0===e.hittable||!!e.label?.trim()||!!e.value?.trim()||!!e.identifier?.trim())?null:"sharp-drop":t.routeComparable&&cN(t.action)&&function(e,t){if(!e||0===e.length)return!1;let n=Math.max(e.length,t.length);if(n<12)return!1;let a=c_(t),r=Math.min(e.length,a.length),i=0;for(let t=0;t<r;t+=1)e[t]===a[t]&&(i+=1);let o=Math.max(0,a.length-e.length),s=Math.max(0,e.length-a.length),l=Math.max(3,Math.floor(.15*n));return i>=Math.floor(.9*n)&&o<=l&&s<=l}(t.baselineSignatures,e.snapshot.nodes)?"stuck-route":null}function cR(e,t){let n=e?.nodes??[],a=function(e){let t=new Map;for(let[n,a]of e.entries())t.set(a.index,n);let n=[],a=[];for(let[r,i]of e.entries()){let e=Math.max(0,i.depth??0);for(;a.length>0&&e<=a[a.length-1].depth;)a.pop();let o="number"==typeof i.parentIndex?t.get(i.parentIndex):void 0,s="number"==typeof o&&o<r?o:a[a.length-1]?.index;n.push({...i,index:r,depth:e,parentIndex:s}),a.push({depth:e,index:r})}return n}(t?.snapshotRaw?n:_(n));return{nodes:q(t?.snapshotScope&&e?.backend!=="macos-helper"?cT(a,t.snapshotScope):a),truncated:e?.truncated,createdAt:Date.now(),backend:e?.backend,comparisonSafe:e?.backend==="android"&&t?.snapshotInteractiveOnly!==!0&&t?.snapshotCompact!==!0&&"number"!=typeof t?.snapshotDepth&&!t?.snapshotScope}}function cP(e,t){var n,a;let r=e.nodes??[];return t.snapshotScope&&(r=cT(r,t.snapshotScope)),t.snapshotInteractiveOnly&&(r=function(e){if(0===e.length)return e;let t=new Map;for(let n of e)t.set(n.index,n);let n=new Set;for(let a of e){if(!function(e){if(e.hittable||e.rect)return!0;let t=`${e.type??""} ${e.role??""} ${e.subrole??""}`.toLowerCase();return t.includes("button")||t.includes("menu")||t.includes("textfield")||t.includes("searchfield")||t.includes("checkbox")||t.includes("radio")||t.includes("switch")}(a))continue;let e=a;for(;e&&!n.has(e.index);)n.add(e.index),e="number"==typeof e.parentIndex?t.get(e.parentIndex):void 0}return 0===n.size?e:cL(e.filter(e=>n.has(e.index)))}(r)),"number"==typeof t.snapshotDepth&&(n=r,a=t.snapshotDepth,r=cL(n.filter(e=>(e.depth??0)<=a))),{...e,nodes:r}}function cT(e,t){let n=C(q(e),t);if(!n)return[];let a=e.findIndex(e=>e.index===n.index);if(-1===a)return[];let r=e[a]?.depth??0,i=[];for(let t=a;t<e.length;t+=1){let n=e[t];if(!n)continue;let o=n.depth??0;if(t>a&&o<=r)break;i.push(n)}return cL(i,r)}function cL(e,t=0){let n=new Map;for(let[t,a]of e.entries())n.set(a.index,t);return e.map((e,a)=>({...e,index:a,depth:Math.max(0,(e.depth??0)-t),parentIndex:"number"==typeof e.parentIndex?n.get(e.parentIndex):void 0}))}function c$(e,t){let n;if(!e||!e.trim().startsWith("@"))return{ok:!0,scope:e};if(!t?.snapshot)return a9("INVALID_ARGS","Ref scope requires an existing snapshot in session.");let a=j(e.trim());if(!a)return a9("INVALID_ARGS",`Invalid ref scope: ${e}`);for(let e of[t.snapshot,...t.snapshotScopeSource?[t.snapshotScopeSource]:[]]){let t=V(e.nodes,a);if(n=t?R(t,e.nodes):void 0)break}return n?{ok:!0,scope:n}:a9("COMMAND_FAILED",`Ref ${e} not found or has no label`)}async function cF(e){let{req:t,sessionName:n,logPath:a,sessionStore:r}=e,{session:i,device:o}=await cf(r,n,t.flags);if(!rc("snapshot",o))return a9("UNSUPPORTED_OPERATION","snapshot is not supported on this device");let s=c$(t.flags?.snapshotScope,i);return s.ok?await ch(i,o,async()=>{let e=cG({req:t,sessionName:n,logPath:a,sessionStore:r,session:i,device:o,snapshotScope:s.scope}),l=await e.capture.snapshot({session:n,interactiveOnly:t.flags?.snapshotInteractiveOnly,compact:t.flags?.snapshotCompact,depth:t.flags?.snapshotDepth,scope:s.scope,raw:t.flags?.snapshotRaw});return cV({req:t,sessionName:n,sessionStore:r,result:{nodes:l.nodes.length,truncated:l.truncated}}),{ok:!0,data:l}}):s}async function cU(e){let{req:t,sessionName:n,logPath:a,sessionStore:r}=e,{session:i,device:o}=await cf(r,n,t.flags);if(!rc("diff",o))return a9("UNSUPPORTED_OPERATION","diff is not supported on this device");let s=c$(t.flags?.snapshotScope,i);return s.ok?await ch(i,o,async()=>{let e=cG({req:t,sessionName:n,logPath:a,sessionStore:r,session:i,device:o,snapshotScope:s.scope}),l=await e.capture.diffSnapshot({session:n,interactiveOnly:t.flags?.snapshotInteractiveOnly,compact:t.flags?.snapshotCompact,depth:t.flags?.snapshotDepth,scope:s.scope,raw:t.flags?.snapshotRaw});return cV({req:t,sessionName:n,sessionStore:r,result:{mode:"snapshot",baselineInitialized:l.baselineInitialized,summary:l.summary}}),{ok:!0,data:l}}):s}function cG(e){let{req:t,sessionName:n,logPath:a,sessionStore:r,session:i,device:o,snapshotScope:s}=e;return a5({backend:function(e){let{req:t,logPath:n,session:a,device:r,snapshotScope:i}=e;return{platform:r.platform,captureSnapshot:async(e,o)=>{let s=await cM({device:r,session:a,flags:t.flags,outPath:o?.outPath??t.flags?.out,logPath:n,snapshotScope:i});return{snapshot:s.snapshot,analysis:s.analysis,androidSnapshot:s.androidSnapshot,freshness:s.freshness,appName:a?.appBundleId?a.appName??a.appBundleId:void 0,appBundleId:a?.appBundleId}}}}({req:t,logPath:a,session:i,device:o,snapshotScope:s}),artifacts:cv("snapshot"),sessions:{get:e=>e===n?function(e){if(e)return{name:e.name,appBundleId:e.appBundleId,appName:e.appName,snapshot:e.snapshot,metadata:{surface:e.surface}}}(r.get(n)):void 0,set:e=>{var a;if(!e.snapshot)throw new y("UNKNOWN","snapshot runtime did not produce session state");let i=r.get(n);r.set(n,function(e){var t,n;let{current:a,sessionName:r,device:i,record:o,refScopedSnapshot:s}=e;if(!o.snapshot)throw new y("UNKNOWN","snapshot runtime did not produce session state");let l=(t=a,n=o,s&&n.snapshot?.nodes.length===0&&t?.snapshot!==void 0),d=l?a.snapshot:o.snapshot,u=function(e){let{session:t,sessionName:n,device:a,snapshot:r,appBundleId:i}=e;return t?{...t,snapshot:r}:{name:n,device:a,createdAt:Date.now(),appBundleId:i,snapshot:r,actions:[]}}({session:a,sessionName:r,device:i,snapshot:d,appBundleId:o.appBundleId});return u.snapshotScopeSource=function(e){let{current:t,keepCurrentSnapshot:n,refScopedSnapshot:a}=e;if(a)return n?t?.snapshotScopeSource:t?.snapshotScopeSource??t?.snapshot}({current:a,keepCurrentSnapshot:l,refScopedSnapshot:s}),o.appName&&(u.appName=o.appName),u}({current:i,sessionName:n,device:o,record:e,refScopedSnapshot:(a=t,a.flags?.snapshotScope?.trim().startsWith("@")===!0)}))}},policy:a6()})}function cV(e){let t=e.sessionStore.get(e.sessionName);t&&e.sessionStore.recordAction(t,{command:e.req.command,positionals:e.req.positionals??[],flags:e.req.flags??{},result:e.result})}async function cB(e){let{device:t,node:n,flags:a,appBundleId:r,traceOutPath:i,surface:o,contextFromFlags:s}=e,l=E(n),d=nv(n.rect);if(!d)return l;try{let e=await u1(t,"read",[String(d.x),String(d.y)],void 0,{...s(a,r,i),surface:o}),u=e&&"object"==typeof e?e:void 0,c="string"==typeof u?.text?u.text:"";if(c.trim())return c;return el({level:"warn",phase:"interaction_read_fallback",data:{reason:"empty_backend_text",nodeRef:n.ref,surface:o,platform:t.platform}}),l}catch(e){return el({level:"warn",phase:"interaction_read_fallback",data:{reason:"backend_read_failed",nodeRef:n.ref,surface:o,platform:t.platform,error:e instanceof Error?e.message:String(e)}}),l}}let cj=[["snapshotDepth","--depth"],["snapshotScope","--scope"],["snapshotRaw","--raw"]];function cq(e,t){let n=function(e){if(!e)return[];let t=[];for(let[n,a]of cj)void 0!==e[n]&&t.push(a);return t}(t);return 0===n.length?null:a9("INVALID_ARGS",`${e} @ref does not support ${n.join(", ")}.`)}function cW(e,t){e.snapshot=t,e.snapshotScopeSource=void 0}async function cX(e,t){let n=await cH(e);if(n)throw new y("COMMAND_FAILED",`press ${t} left ${e.appBundleId} and foregrounded ${n.foregroundPackage}. The tap likely escaped the app.`,n)}async function cH(e){var t;if("android"!==e.device.platform||!e.appBundleId)return null;let n=await se(e.device),a=n.package?.trim();return a&&a!==e.appBundleId&&("com.android.settings"===(t=a)||"com.android.systemui"===t||"com.google.android.permissioncontroller"===t||t.includes("launcher"))?{expectedPackage:e.appBundleId,foregroundPackage:a,activity:n.activity,hint:"com.google.android.permissioncontroller"===a?"Dismiss or allow the permission prompt, then retry the smoke assertion.":"Use screenshot as visual truth, then take a fresh snapshot -i before retrying."}:null}function cz(e){return"COMMAND_FAILED"===e.code&&"string"==typeof e.details?.expectedPackage&&"string"==typeof e.details?.foregroundPackage}function cY(e,t,n,a){let r=e.get(t);r&&e.recordAction(r,{command:n.command,positionals:n.positionals??[],flags:n.flags??{},result:a})}function cK(e){let t=e.target;return t&&"object"==typeof t?"ref"===t.kind&&"string"==typeof t.ref?{kind:"ref",ref:t.ref}:"selector"===t.kind&&"string"==typeof t.selector?{kind:"selector",selector:t.selector}:void 0:void 0}function cJ(e){return e.startsWith("@")?e.slice(1):e}async function cZ(e){var t;let{req:n}=e;if("find"!==n.command)return null;let a=n.positionals??[];if(0===a.length)return a9("INVALID_ARGS","find requires a locator or text");let r=ey(a);if(!r.query)return a9("INVALID_ARGS","find requires a value");if(n.flags?.findFirst&&n.flags?.findLast)return a9("INVALID_ARGS","find accepts only one of --first or --last");let i=r.action;if("exists"!==(t=i)&&"wait"!==t&&"get_text"!==t&&"get_attrs"!==t)return null;let o=await c3(e,{requireSession:!1,capability:"find"});return o.ok?await c8(async()=>{let t=await o.runtime.selectors.find({session:e.sessionName,requestId:n.meta?.requestId,locator:r.locator,query:r.query,action:i,timeoutMs:r.timeoutMs});return cY(e.sessionStore,e.sessionName,n,function(e,t){if("exists"===t)return{found:!0};if("wait"===t)return{found:!0,waitedMs:e.waitedMs};let n="string"==typeof e.ref?e.ref:void 0;return"get_attrs"===t?{ref:n,action:"get attrs"}:{ref:n,action:"get text",text:"string"==typeof e.text?e.text:""}}(t,i)),"found"===t.kind?{found:!0,..."number"==typeof t.waitedMs?{waitedMs:t.waitedMs}:{}}:{..."string"==typeof t.ref?{ref:t.ref}:{},..."string"==typeof t.text?{text:t.text}:{},...t.node&&"object"==typeof t.node?{node:t.node}:{}}}):o.response}async function cQ(e){let{req:t}=e;if("get"!==t.command)return null;let n=t.positionals?.[0];if("text"!==n&&"attrs"!==n)return a9("INVALID_ARGS","get only supports text or attrs");let a=await c3(e,{requireSession:!0,capability:"get"});if(!a.ok)return a.response;let r=function(e){let t=e.positionals?.[1]??"";if(t.startsWith("@"))return{ok:!0,target:{kind:"ref",ref:t,fallbackLabel:e.positionals.length>2?e.positionals.slice(2).join(" ").trim():""}};let n=e.positionals?.slice(1).join(" ").trim()??"";return n?{ok:!0,target:{kind:"selector",selector:n}}:{ok:!1,response:a9("INVALID_ARGS","get requires @ref or selector expression")}}(t);if(!r.ok)return r.response;if("ref"===r.target.kind){let e=cq("get",t.flags);if(e)return e}return await c8(async()=>{let i,o=await a.runtime.selectors.get({session:e.sessionName,requestId:t.meta?.requestId,property:n,target:r.target});return cY(e.sessionStore,e.sessionName,t,function(e,t){let n=Array.isArray(e.selectorChain)?e.selectorChain:void 0,a=cK(e),r=a?.kind==="ref"?cJ(a.ref):void 0,i=a?.kind==="selector"?a.selector:void 0,o={...r?{ref:r}:{},...i?{selector:i}:{},...n?{selectorChain:n}:{}};if("attrs"===t)return o;let s="string"==typeof e.text?e.text:"";return{...o,text:s,refLabel:function(e){let t=e.trim();if(!(!t||t.length>80||/[\r\n]/.test(t)))return t}(s)}}(o,n)),i=cK(o),{...i?.kind==="ref"?{ref:cJ(i.ref)}:{},...i?.kind==="selector"?{selector:i.selector}:{},..."string"==typeof o.text?{text:o.text}:{},...o.node&&"object"==typeof o.node?{node:o.node}:{}}})}async function c0(e){let{req:t}=e;if("is"!==t.command)return null;let n=(t.positionals?.[0]??"").toLowerCase();if(!nt(n))return a9("INVALID_ARGS","is requires predicate: visible|hidden|exists|editable|selected|text");let{split:a}=O(t.positionals??[]);if(!a)return a9("INVALID_ARGS","is requires a selector expression");let r=a.rest.join(" ").trim();if("text"===n&&!r)return a9("INVALID_ARGS","is text requires expected text value");if("text"!==n&&a.rest.length>0)return a9("INVALID_ARGS",`is ${n} does not accept trailing values`);let i=await c3(e,{requireSession:!0,capability:"is"});if(!i.ok)return i.response;let o=await c8(async()=>{let o=await i.runtime.selectors.is({session:e.sessionName,requestId:t.meta?.requestId,predicate:n,selector:a.selectorExpression,expectedText:r});return cY(e.sessionStore,e.sessionName,t,o),function(e){let{selectorChain:t,...n}=e;return n}(o)});return await c6(e,o,`is ${n}`)}async function c1(e){let{req:t,sessionName:n,sessionStore:a}=e,r=re(t.positionals??[]);if(!r)return a9("INVALID_ARGS","wait requires a duration or text");let{session:i,device:o}=await cf(a,n,t.flags);if("sleep"!==r.kind&&!rc("wait",o))return a9("UNSUPPORTED_OPERATION","wait is not supported on this device");let s=async()=>{let s=c2({...e,session:i,device:o}),l=await c8(async()=>{let e=await s.selectors.wait({session:n,requestId:t.meta?.requestId,target:function(e,t){if("sleep"===e.kind)return{kind:"sleep",durationMs:e.durationMs};if("selector"===e.kind)return{kind:"selector",selector:e.selectorExpression,timeoutMs:e.timeoutMs};if("ref"===e.kind){if(!t?.snapshot)throw new y("INVALID_ARGS","Ref wait requires an existing snapshot in session.");return{kind:"ref",ref:e.rawRef,timeoutMs:e.timeoutMs}}if(!e.text)throw new y("INVALID_ARGS","wait requires text");return{kind:"text",text:e.text,timeoutMs:e.timeoutMs}}(r,i)});return cY(a,n,t,e),{waitedMs:e.waitedMs,..."string"==typeof e.text?{text:e.text}:{},..."string"==typeof e.selector?{selector:e.selector}:{}}});return await c6(e,l,"wait")};return"sleep"===r.kind?await s():await ch(i,o,s)}function c2(e){return a5({backend:function(e){let t,{req:n,session:a,device:r,logPath:i,sessionName:o,sessionStore:s}=e,l=0;return{platform:r.platform,captureSnapshot:async(e,d)=>{var u;let c,p={...n.flags,...(u=d,c={},u?.interactiveOnly!==void 0&&(c.snapshotInteractiveOnly=u.interactiveOnly),u?.compact!==void 0&&(c.snapshotCompact=u.compact),u?.scope!==void 0&&(c.snapshotScope=u.scope),u?.depth!==void 0&&(c.snapshotDepth=u.depth),u?.raw!==void 0&&(c.snapshotRaw=u.raw),c)},f=d?.scope??n.flags?.snapshotScope,h=Date.now();if(t&&h-l<750&&!cx(a))return t;let m=await cM({device:r,session:a,flags:p,outPath:n.flags?.out,logPath:i??"",snapshotScope:f});return a&&(cW(a,m.snapshot),s.set(o,a)),l=h,t={snapshot:m.snapshot}},readText:async(t,o)=>({text:await cB({device:r,node:o,flags:n.flags,appBundleId:a?.appBundleId,traceOutPath:a?.trace?.outPath,surface:a?.surface,contextFromFlags:e.contextFromFlags??((e,t,n)=>cy(i??"",e,t,n))})}),findText:async(t,n)=>({found:await c4(e,n)})}}(e),artifacts:cv("selector commands",{plural:!0}),sessions:{get:t=>t===e.sessionName?function(e){if(e)return{name:e.name,appName:e.appName,appBundleId:e.appBundleId,snapshot:e.snapshot,metadata:{surface:e.surface}}}(e.session):void 0,set:t=>{e.session&&t.snapshot&&(cW(e.session,t.snapshot),e.sessionStore.set(e.sessionName,e.session))}},policy:a6()})}async function c3(e,t){let n=e.sessionStore.get(e.sessionName);if(!n&&t.requireSession)return{ok:!1,response:a9("SESSION_NOT_FOUND","No active session. Run open first.")};let a=n?.device??await uZ(e.req.flags??{});return(n||await cl(a),rc(t.capability,a))?{ok:!0,runtime:c2({...e,session:n,device:a})}:{ok:!1,response:a9("UNSUPPORTED_OPERATION",`${t.capability} is not supported on this device`)}}async function c4(e,t){let{device:n,session:a,req:r,logPath:i}=e;if("macos"===n.platform&&a?.surface&&"app"!==a.surface)return!!C((await c5(e)).nodes,t);if(rn(n.platform)){let e=await i5(n,{command:"findText",text:t,appBundleId:a?.appBundleId},{verbose:r.flags?.verbose,logPath:i,traceLogPath:a?.trace?.outPath,requestId:r.meta?.requestId});return e?.found===!0}return!!C((await c5(e)).nodes,t)}async function c5(e){let t=await cM({device:e.device,session:e.session,flags:{...e.req.flags,snapshotInteractiveOnly:!1,snapshotCompact:!1},outPath:e.req.flags?.out,logPath:e.logPath??""});return e.session&&(cW(e.session,t.snapshot),e.sessionStore.set(e.sessionName,e.session)),t.snapshot}async function c8(e){try{return{ok:!0,data:await e()}}catch(t){let e=w(t);return a9(e.code,e.message,e.details)}}async function c6(e,t,n){var a;let r;if(t.ok)return t;let i=e.sessionStore.get(e.sessionName);if(!i)return t;try{r=await cH(i)}catch{return t}return r?a9(t.error.code,`${n} failed because ${"com.google.android.permissioncontroller"===(a=r).foregroundPackage?`Android permission dialog is blocking ${a.expectedPackage}`:`${a.foregroundPackage} is foreground instead of ${a.expectedPackage}`}.`,{...t.error.details??{},...r,blockedBy:"android_foreground_surface",originalMessage:t.error.message}):t}let c9=new Set(["snapshot","diff","wait","alert","settings"]);async function c7(e){let{req:t,sessionName:n,logPath:a,sessionStore:r}=e,i=t.command;if(!c9.has(i))return null;if("snapshot"===i)return await cF({req:t,sessionName:n,logPath:a,sessionStore:r});if("diff"===i)return t.positionals?.[0]!=="snapshot"?a9("INVALID_ARGS","diff currently supports only: diff snapshot"):await cU({req:t,sessionName:n,logPath:a,sessionStore:r});if("wait"===i)return await c1({req:t,sessionName:n,logPath:a,sessionStore:r});if("alert"===i){let{session:e,device:i}=await cf(r,n,t.flags);return await ch(e,i,async()=>await cw({req:t,logPath:a,sessionStore:r,session:e,device:i}))}if("settings"===i){let e,i,o,s=(e=t.positionals?.[0]?.toLowerCase(),i=t.positionals?.[1]?.toLowerCase(),o=t.positionals?.[2]?.toLowerCase(),e&&i&&("permission"!==e||o)?{ok:!0,parsed:{setting:e,state:i,permissionTarget:o}}:a9("INVALID_ARGS",eq));if(!s.ok)return s;let{session:l,device:d}=await cf(r,n,t.flags);return await ch(l,d,async()=>await cb({req:t,logPath:a,sessionStore:r,session:l,device:d,parsed:s.parsed}))}return null}export{lk as IOS_DEVICECTL_DEFAULT_HINT,iS as IOS_RUNNER_CONTAINER_BUNDLE_IDS,ly as IOS_SIMCTL_LIST_TIMEOUT_MS,eX as SESSION_SURFACES,ej as SETTINGS_USAGE_OVERRIDE,iZ as abortAllIosRunnerSessions,og as adbArgs,sB as appSwitcherAndroid,cX as assertAndroidPressStayedInApp,sU as backAndroid,e8 as buildMobileSnapshotPresentation,sA as buildScrollGesturePlan,rB as buildSimctlArgs,rj as buildSimctlArgsForDevice,eY as buildSnapshotDisplayLines,cR as buildSnapshotState,uA as buttonTag,cM as captureSnapshot,ck as captureSnapshotData,oH as classifyAndroidAppTarget,rk as clearRequestCanceled,sd as closeAndroidApp,dM as closeIosApp,cy as context_contextFromFlags,a5 as createAgentDevice,rO as createRequestCanceledError,cv as createUnsupportedArtifactAdapter,tn as decodePng,oq as waitForAndroidBoot,s5 as dismissAndroidKeyboard,u1 as dispatchCommand,cZ as dispatchFindReadOnlyViaRuntime,cQ as dispatchGetViaRuntime,c0 as dispatchIsViaRuntime,e2 as displayNodeLabel,oy as ensureAdb,oj as ensureAndroidEmulatorBooted,cl as ensureDeviceReady,a9 as errorResponse,sH as fillAndroid,uj as findBootableIosSimulator,sX as focusAndroid,oz as formatAndroidInstalledPackageRequiredMessage,eK as formatSnapshotLine,cx as getActiveAndroidSnapshotFreshness,se as getAndroidAppState,s4 as getAndroidKeyboardState,sJ as getAndroidScreenSize,uI as getClickButtonValidationError,rE as getRequestSignal,iz as getRunnerSessionSnapshot,c7 as handleSnapshotCommands,sG as homeAndroid,o7 as inferAndroidAppName,sv as installAndroidApp,sb as installAndroidInstallablePathAndResolvePackageName,dD as installIosApp,dO as installIosInstallablePath,cz as isAndroidEscapeError,rn as isApplePlatform,rc as isCommandSupportedOnDevice,ov as isDeepLinkTarget,rf as isEnvTruthy,cN as isNavigationSensitiveAction,rD as isRequestCanceled,o5 as listAndroidApps,o$ as listAndroidDevices,uz as listAppleDevices,dL as listIosApps,l_ as listIosDeviceApps,lM as listIosDeviceProcesses,a6 as localCommandPolicy,sj as longPressAndroid,cA as markAndroidSnapshotFreshness,rM as markRequestCanceled,ra as matchesPlatformSelector,rt as normalizePlatformSelector,sn as openAndroidApp,sl as openAndroidDevice,dN as openIosApp,d_ as openIosDevice,uD as parseDeviceRotation,rG as parseSerialAllowlist,eH as parseSessionSurface,re as parseWaitArgs,iu as parseXmlDocumentSync,oY as prepareAndroidInstallArtifact,lF as prepareIosInstallArtifact,s$ as pressAndroid,lc as pushAndroidNotification,dP as pushIosNotification,s8 as readAndroidClipboardText,s2 as readAndroidTextAtPoint,l$ as readInfoPlistString,dC as readIosClipboardText,cB as readTextForNode,cq as refSnapshotFlagGuardResponse,r_ as registerRequestAbort,sI as reinstallAndroidApp,dE as reinstallIosApp,o4 as resolveAndroidApp,rV as resolveAndroidSerialAllowlist,rr as resolveAppleSimulatorSetPathForSelector,uv as resolveClickButton,od as resolveFrontmostMacOsApp,dS as resolveIosApp,oI as resolveIosDeviceDeepLinkBundleId,lD as resolveIosDevicectlHint,rU as resolveIosSimulatorDeviceSetPath,u_ as resolvePayloadInput,rN as resolveRequestTrackingId,uZ as resolveTargetDevice,sV as rotateAndroid,i5 as runIosRunnerCommand,op as runMacOsAlertAction,lf as screenshotAndroid,ds as screenshotIos,sK as scrollAndroid,lr as setAndroidSetting,dT as setIosSetting,cW as setSessionSnapshot,lT as shutdownSimulator,lP as ensureBootedSimulator,s_ as snapshotAndroid,iQ as stopAllIosRunnerSessions,iJ as stopIosRunnerSession,sF as swipeAndroid,sq as typeAndroid,io as withKeyedLock,uQ as withResolveTargetDeviceCacheScope,s6 as writeAndroidClipboardText,dR as writeIosClipboardText};
|
|
18
|
+
${r}
|
|
19
|
+
${a}`.toLowerCase();return i.includes("timeout waiting for screen surfaces")||i.includes("nsposixerrordomain")&&i.includes("code=60")&&i.includes("screenshot")||i.includes("timed out")&&i.includes("screenshot")}let ls={settings:"com.apple.Preferences"},ll=eP(),ld=null;function lu(e){return{platform:"ios",deviceId:e.id,variant:e.kind}}function lc(e,t,n){return ed("xcrun",aj(e,t),n)}function lp(e){return e.includes("not installed")||e.includes("not found")||e.includes("no such file")}async function lf(e,t){if("macos"===e.platform)return await sG(t);let n=t.trim();if(n.includes("."))return n;let r=ls[n.toLowerCase()];if(r)return r;let a=lu(e),i=ll.get(a,n);if(i)return i;let o=("simulator"===e.kind?await l_(e):await sw(e,"all")).filter(e=>e.name.toLowerCase()===n.toLowerCase());if(1===o.length)return ll.set(a,n,o[0].bundleId);if(o.length>1)throw new y("INVALID_ARGS",`Multiple apps matched "${t}"`,{matches:o});throw new y("APP_NOT_INSTALLED",`No app found matching "${t}"`)}async function lh(e,t,n){if("macos"===e.platform)return void await sV(e,t,n);let r=n?.url?.trim();if(r){if(!eT(r))throw new y("INVALID_ARGS","open <app> <url> requires a valid URL target");if("simulator"===e.kind){await sS(e),await lc(e,["openurl",e.id,r]);return}let a=eg(n?.appBundleId??await lf(e,t),r);if(!a)throw new y("INVALID_ARGS","Deep link open on iOS devices requires an active app bundle ID. Open the app first, then open the URL.");await lT(e,a,{payloadUrl:r});return}let a=t.trim();if(eT(a)){if("simulator"===e.kind){await sS(e),await lc(e,["openurl",e.id,a]);return}let t=eg(n?.appBundleId,a);if(!t)throw new y("INVALID_ARGS","Deep link open on iOS devices requires an active app bundle ID. Open the app first, then open the URL.");await lT(e,t,{payloadUrl:a});return}let i=n?.appBundleId??await lf(e,t);"simulator"===e.kind?await lP(e,i):await lT(e,i)}async function lm(e){"macos"===e.platform||"simulator"!==e.kind||"Booted"!==await s_(e)&&await sS(e)}async function lw(e,t){if("macos"===e.platform)return void await sB(e,t);let n=await lf(e,t);if("simulator"===e.kind){await sS(e);let t=aj(e,["terminate",e.id,n]),r=await ed("xcrun",t,{allowFailure:!0});if(0!==r.exitCode){if(r.stderr.toLowerCase().includes("found nothing to terminate"))return;throw new y("COMMAND_FAILED",`xcrun exited with code ${r.exitCode}`,{cmd:"xcrun",args:t,stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode})}return}await sm(["device","process","terminate","--device",e.id,n],{action:"terminate iOS app",deviceId:e.id})}async function lg(e,t){return await ll.invalidateWhile(lu(e),async()=>{let n=await lf(e,t);if("simulator"!==e.kind){let t=["devicectl","device","uninstall","app","--device",e.id,n],r=await ed("xcrun",t,{allowFailure:!0,timeoutMs:su});if(0!==r.exitCode){let a=String(r.stdout??""),i=String(r.stderr??"");if(!lp(`${a}
|
|
20
|
+
${i}`.toLowerCase()))throw new y("COMMAND_FAILED",`Failed to uninstall iOS app ${n}`,{cmd:"xcrun",args:t,exitCode:r.exitCode,stdout:a,stderr:i,deviceId:e.id,hint:sb(a,i)??sy})}return{bundleId:n}}await sS(e);let r=await lc(e,["uninstall",e.id,n],{allowFailure:!0});if(0!==r.exitCode&&!lp(`${r.stdout}
|
|
21
|
+
${r.stderr}`.toLowerCase()))throw new y("COMMAND_FAILED",`simctl uninstall failed for ${n}`,{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode});return{bundleId:n}})}async function ly(e,t,n){let r=await sM({kind:"path",path:t},n);try{return await lv(e,r.installablePath),{archivePath:r.archivePath,installablePath:r.installablePath,bundleId:r.bundleId,appName:r.appName,launchTarget:r.bundleId}}finally{await r.cleanup()}}async function lb(e,t,n){return await ll.invalidateWhile(lu(e),async()=>{let{bundleId:r}=await lg(e,t);return await ly(e,n,{appIdentifierHint:t}),{bundleId:r}})}async function lv(e,t){await ll.invalidateWhile(lu(e),async()=>{"simulator"!==e.kind?await sm(["device","install","app","--device",e.id,t],{action:"install iOS app",deviceId:e.id}):(await sS(e),await lc(e,["install",e.id,t]))})}async function lI(e){if("macos"===e.platform)return await sj();sA(e,"clipboard"),await sS(e);let t=await lc(e,["pbpaste",e.id],{allowFailure:!0});if(0!==t.exitCode)throw new y("COMMAND_FAILED","Failed to read iOS simulator clipboard",{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode});return t.stdout.replace(/\r\n/g,"\n").replace(/\n$/,"")}async function lA(e,t){if("macos"===e.platform)return void await sq(t);sA(e,"clipboard"),await sS(e);let n=await lc(e,["pbcopy",e.id],{allowFailure:!0,stdin:t});if(0!==n.exitCode)throw new y("COMMAND_FAILED","Failed to write iOS simulator clipboard",{stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode})}async function lx(e,t,n){sA(e,"push"),await sS(e);let r=await a.mkdtemp(o.join(s.tmpdir(),"agent-device-ios-push-")),i=o.join(r,"payload.apns");try{await a.writeFile(i,`${JSON.stringify(n)}
|
|
22
|
+
`,"utf8"),await lc(e,["push",e.id,t,i])}finally{await a.rm(r,{recursive:!0,force:!0})}}async function lS(e,t,n,r,a){if("macos"===e.platform){let e=t.toLowerCase();if("appearance"===e)return void await sH(n);if("permission"===e){let e=o0(n);if("deny"===e)throw new y("INVALID_ARGS",e7("permission"));let t=function(e){let t=e?.trim().toLowerCase();if("accessibility"===t||"screen-recording"===t||"input-monitoring"===t)return t;throw new y("INVALID_ARGS","Unsupported macOS permission target. Use accessibility|screen-recording|input-monitoring.")}(a?.permissionTarget);return await oc(e,t)}throw new y("INVALID_ARGS",e7(t))}sA(e,"settings"),await sS(e);let i=t.toLowerCase();switch(i){case"wifi":{let t=lk(n);await lc(e,["status_bar",e.id,"override","--wifiMode",t?"active":"failed"]);return}case"airplane":return void(lk(n)?await lc(e,["status_bar",e.id,"override","--dataNetwork","hide","--wifiMode","failed","--wifiBars","0","--cellularMode","failed","--cellularBars","0","--operatorName",""]):await lc(e,["status_bar",e.id,"clear"]));case"location":{let t=lk(n);if(!r)throw new y("INVALID_ARGS","location setting requires an active app in session");await lc(e,["privacy",e.id,t?"grant":"revoke","location",r]);return}case"faceid":case"touchid":{let t=lD[i],r=function(e,t){let n=e.trim().toLowerCase();if("match"===n)return"match";if("nonmatch"===n)return"nonmatch";if("enroll"===n)return"enroll";if("unenroll"===n)return"unenroll";throw new y("INVALID_ARGS",`Invalid ${t} state: ${e}. Use match|nonmatch|enroll|unenroll.`)}(n,i);await lR(e,r,{settingName:i,label:t.label,modalityAliases:t.modalityAliases});return}case"appearance":{let t=await lM(e,n);await lc(e,["ui",e.id,"appearance",t]);return}case"permission":{var o;if(!r)throw new y("INVALID_ARGS","permission setting requires an active app in session");let t="deny"===(o=o0(n))?"revoke":o,i=function(e,t){let n=o1(e);if("photos"!==n&&t?.trim())throw new y("INVALID_ARGS",`Permission mode is only supported for photos. Received: ${t}.`);if("camera"===n)return"camera";if("microphone"===n)return"microphone";if("contacts"===n)return"contacts";if("contacts-limited"===n)return"contacts-limited";if("notifications"===n)return"notifications";if("calendar"===n)return"calendar";if("location"===n)return"location";if("location-always"===n)return"location-always";if("media-library"===n)return"media-library";if("motion"===n)return"motion";if("reminders"===n)return"reminders";if("siri"===n)return"siri";if("photos"===n){let e=t?.trim().toLowerCase();if(!e||"full"===e)return"photos";if("limited"===e)return"photos-add";throw new y("INVALID_ARGS",`Invalid photos mode: ${t}. Use full|limited.`)}throw new y("INVALID_ARGS",`Unsupported permission target: ${e}. Use camera|microphone|photos|contacts|contacts-limited|notifications|calendar|location|location-always|media-library|motion|reminders|siri.`)}(a?.permissionTarget,a?.permissionMode);await lE(e,t,i,r);return}default:throw new y("INVALID_ARGS",`Unsupported setting: ${t}`)}}async function lN(e,t="all"){return"macos"===e.platform?await sK(t):"simulator"===e.kind?sR(await l_(e),t):await sw(e,t)}async function l_(e){let t=(await lc(e,["listapps",e.id],{allowFailure:!0})).stdout.trim();if(!t)return[];let n=null;if(t.startsWith("{"))try{n=JSON.parse(t)}catch{n=null}if(!n&&t.startsWith("{"))try{let e=await ed("plutil",["-convert","json","-o","-","-"],{allowFailure:!0,stdin:t});0===e.exitCode&&e.stdout.trim().startsWith("{")&&(n=JSON.parse(e.stdout))}catch{n=null}return n?Object.entries(n).map(([e,t])=>({bundleId:e,name:t.CFBundleDisplayName??t.CFBundleName??e})):[]}function lk(e){let t=e.toLowerCase();if("on"===t||"true"===t||"1"===t)return!0;if("off"===t||"false"===t||"0"===t)return!1;throw new y("INVALID_ARGS",`Invalid setting state: ${e}`)}async function lM(e,t){let n=o2(t);if("toggle"!==n)return n;let r=await lc(e,["ui",e.id,"appearance"],{allowFailure:!0});if(0!==r.exitCode)throw new y("COMMAND_FAILED","Failed to read current iOS appearance",{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode});let a=function(e,t){let n=/\b(light|dark|unsupported|unknown)\b/i.exec(`${e}
|
|
23
|
+
${t}`);if(!n)return null;let r=n[1].toLowerCase();return"dark"===r?"dark":"light"===r?"light":null}(r.stdout,r.stderr);if(!a)throw new y("COMMAND_FAILED","Unable to determine current iOS appearance for toggle",{stdout:r.stdout,stderr:r.stderr});return"dark"===a?"light":"dark"}let lD={faceid:{label:"Face ID",modalityAliases:["face"]},touchid:{label:"Touch ID",modalityAliases:["finger","touch"]}};async function lE(e,t,n,r){let a=await lC(e);if(!a.has(n))throw new y("UNSUPPORTED_OPERATION",`iOS simctl privacy does not support service "${n}" on this runtime.`,{deviceId:e.id,appBundleId:r,hint:`Supported services: ${Array.from(a).sort().join(", ")}`});let i=["privacy",e.id,t,n,r],o="notifications"===n;if(!("reset"===t&&o))try{await lc(e,i);return}catch(t){if(!(o&&lO(t)))throw t;throw new y("UNSUPPORTED_OPERATION","iOS simulator does not support setting notifications permission via simctl privacy on this runtime.",{deviceId:e.id,appBundleId:r,hint:"Use reset notifications for reprompt behavior, or toggle notifications manually in Settings."})}try{await lc(e,i);return}catch(e){if(!lO(e))throw e}try{await lc(e,["privacy",e.id,"reset","all",r])}catch(t){throw new y("COMMAND_FAILED","iOS simulator blocked direct notifications reset. Fallback reset-all also failed.",{deviceId:e.id,appBundleId:r,hint:"Use reinstall to force a fresh notifications prompt, or reset simulator content and settings."},t instanceof Error?t:void 0)}}function lO(e){if(!(e instanceof y)||"COMMAND_FAILED"!==e.code)return!1;let t=String(e.details?.stderr??"").toLowerCase();return(t.includes("failed to grant access")||t.includes("failed to revoke access")||t.includes("failed to reset access"))&&t.includes("operation not permitted")}async function lC(t){let n=em(t.simulatorSetPath),r=`${process.env.PATH??""}::${n??""}`;if(ld&&e===r)return ld;let a=await lc(t,["privacy","help"],{allowFailure:!0}),i=function(e){let t=new Set,n=!1;for(let r of e.split("\n")){let e=r.trim();if(!e)continue;if("service"===e){n=!0;continue}if(!n)continue;if(e.startsWith("bundle identifier"))break;let a=/^([a-z-]+)\s+-\s+/.exec(e);a&&t.add(a[1])}return t}(`${a.stdout}
|
|
24
|
+
${a.stderr}`);if(0===i.size)throw new y("COMMAND_FAILED","Unable to determine supported simctl privacy services",{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode,hint:"Run `xcrun simctl privacy help` manually to verify available services for this runtime."});return ld=i,e=r,i}async function lR(e,t,n){let r=function(e,t,n){let r=n.length>0?n:["face"];switch(t){case"match":return r.flatMap(t=>[["biometric",e,"match",t],["biometric","match",e,t]]);case"nonmatch":return r.flatMap(t=>[["biometric",e,"nonmatch",t],["biometric",e,"nomatch",t],["biometric","nonmatch",e,t],["biometric","nomatch",e,t]]);case"enroll":return[["biometric",e,"enroll","yes"],["biometric",e,"enroll","1"],["biometric","enroll",e,"yes"],["biometric","enroll",e,"1"]];case"unenroll":return[["biometric",e,"enroll","no"],["biometric",e,"enroll","0"],["biometric","enroll",e,"no"],["biometric","enroll",e,"0"]]}}(e.id,t,n.modalityAliases),a=[];for(let t of r){let n=aj(e,t),r=await ed("xcrun",n,{allowFailure:!0});if(0===r.exitCode)return;a.push({args:n,stderr:r.stderr,stdout:r.stdout,exitCode:r.exitCode})}let i=a.map(e=>({args:e.args.join(" "),exitCode:e.exitCode,stderr:e.stderr.slice(0,400)}));if(a.length>0&&a.every(e=>{var t,n;let r;return t=e.stdout,n=e.stderr,(r=`${t}
|
|
25
|
+
${n}`.toLowerCase()).includes("unrecognized subcommand")||r.includes("unknown subcommand")||r.includes("not supported")||r.includes("unavailable")||r.includes("biometric")&&r.includes("invalid")}))throw new y("UNSUPPORTED_OPERATION",`${n.label} simulation is not supported on this simulator runtime.`,{deviceId:e.id,action:t,setting:n.settingName,attempts:i});throw new y("COMMAND_FAILED",`Failed to simulate ${n.settingName}.`,{deviceId:e.id,action:t,setting:n.settingName,attempts:i})}async function lP(e,t){await sS(e);let n=0,r=eb.fromTimeoutMs(sd);try{await eC(async({deadline:n})=>{var r;if(n?.isExpired())throw new y("COMMAND_FAILED","App launch deadline exceeded",{timeoutMs:sd});let a=(r=["launch",e.id,t],aj(e,r)),i=await ed("xcrun",a,{allowFailure:!0});if(0!==i.exitCode)throw new y("COMMAND_FAILED",`xcrun exited with code ${i.exitCode}`,{cmd:"xcrun",args:a,stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode})},{maxAttempts:10,baseDelayMs:1e3,maxDelayMs:5e3,jitter:.2,shouldRetry:e=>!!sv(e)&&(n+=1)<3},{deadline:r})}catch(n){if(sv(n)){var a;let r=(a=await sI(e,t)).installed?!1===a.simulatorCompatible?"ARCH_MISMATCH":"PERSISTENT_LAUNCH_FAIL":"APP_NOT_INSTALLED";n.details={...n.details,hint:function(e){switch(e){case"ARCH_MISMATCH":return"The app binary was not built for the simulator platform. Rebuild with a simulator destination or use a physical device.";case"APP_NOT_INSTALLED":return"The app bundle is not installed on this simulator. Run install before open.";case"PERSISTENT_LAUNCH_FAIL":return"The simulator repeatedly refused to launch the app. Inspect crash logs in Console.app or ~/Library/Logs/DiagnosticReports/ and consider reinstalling the app.";default:return"The simulator failed to launch the app. Retry with --debug and inspect diagnostics log for details."}}(r)}}throw n}}async function lT(e,t,n){let r=["device","process","launch","--device",e.id,t];n?.payloadUrl&&r.push("--payload-url",n.payloadUrl),await sm(r,{action:"launch iOS app",deviceId:e.id})}async function lL(e,t,n,r,a,i,o){if("tv"===t.target)return lU(await e(t,{command:"swipe",direction:function(e){switch(e){case"up":return"down";case"down":return"up";case"left":return"right";case"right":return"left";default:return e}}(a),appBundleId:n.appBundleId},r),i);let s=o??await l$(e,t,n,r),l=og({direction:a,amount:i?.amount,pixels:i?.pixels,referenceWidth:s.referenceWidth,referenceHeight:s.referenceHeight});return lU(await e(t,{command:"drag",x:s.originX+l.x1,y:s.originY+l.y1,x2:s.originX+l.x2,y2:s.originY+l.y2,appBundleId:n.appBundleId},r),{amount:l.amount,pixels:l.pixels,preferProvidedPixels:!0})}async function l$(e,t,n,r){let a=await e(t,{command:"interactionFrame",appBundleId:n.appBundleId},r),i=lF(a.x),o=lF(a.y),s=lF(a.referenceWidth),l=lF(a.referenceHeight);if(void 0===i||void 0===o||void 0===s||void 0===l)throw new y("COMMAND_FAILED","interactionFrame did not return a usable frame");return{originX:i,originY:o,referenceWidth:s,referenceHeight:l}}function lF(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function lU(e,t){var n;let{x1:r,y1:a,x2:i,y2:o}={x1:lF((n=e).x),y1:lF(n.y),x2:lF(n.x2),y2:lF(n.y2)},s=lF(e.referenceWidth),l=lF(e.referenceHeight),d=void 0!==r&&void 0!==i?Math.round(Math.abs(i-r)):void 0,u=void 0!==a&&void 0!==o?Math.round(Math.abs(o-a)):void 0,c=t?.preferProvidedPixels&&void 0!==t.pixels?t.pixels:d&&d>0?d:u&&u>0?u:void 0;return{...void 0!==r?{x1:r}:{},...void 0!==a?{y1:a}:{},...void 0!==i?{x2:i}:{},...void 0!==o?{y2:o}:{},...void 0!==s?{referenceWidth:s}:{},...void 0!==l?{referenceHeight:l}:{},...t?.amount!==void 0?{amount:t.amount}:{},...void 0!==c?{pixels:c}:{}}}function lG(){return process.env.WAYLAND_DISPLAY||"wayland"===process.env.XDG_SESSION_TYPE?"wayland":"x11"}let lV=null;async function lB(){if(lV)return lV;let e=lG();if("wayland"===e){if(await eu("ydotool"))return lV={tool:"ydotool",display:e};throw new y("TOOL_MISSING","ydotool is required for input synthesis on Wayland (xdotool does not work on Wayland). Install it via your package manager.")}if(await eu("xdotool"))return lV={tool:"xdotool",display:e};throw new y("TOOL_MISSING","xdotool is required for input synthesis on X11. Install it via your package manager.")}async function lj(...e){await ed("xdotool",e,{allowFailure:!1,timeoutMs:1e4})}async function lq(...e){await ed("ydotool",e,{allowFailure:!1,timeoutMs:1e4})}async function lX(e,t){let{tool:n}=await lB();"xdotool"===n?await lj("mousemove","--sync",String(e),String(t)):await lq("mousemove","--absolute","-x",String(e),"-y",String(t))}async function lH(e,t){let{tool:n}=await lB();"xdotool"===n?await lj("key","--clearmodifiers",e):await lq("key",...t)}async function lK(e,t,n,r){await lX(e,t);let{tool:a}=await lB();"xdotool"===a?await lj("click",n):await lq("click",r)}async function lz(e,t){await lK(e,t,"1","0xC0")}async function lY(e,t){await lK(e,t,"3","0xC1")}async function lW(e,t){await lK(e,t,"2","0xC2")}async function lJ(e,t){let{tool:n}=await lB();await lX(e,t),"xdotool"===n?await lj("click","--repeat","2","1"):(await lq("click","0xC0"),await lq("click","0xC0"))}async function lZ(e,t,n=800){let{tool:r}=await lB();await lX(e,t),"xdotool"===r?(await lj("mousedown","1"),await eF(n),await lj("mouseup","1")):(await lq("click","--down","0xC0"),await eF(n),await lq("click","--up","0xC0"))}async function lQ(e,t){await lz(e,t)}async function l0(e,t,n,r,a=300){let{tool:i}=await lB();await lX(e,t),"xdotool"===i?(await lj("mousedown","1"),await lj("mousemove","--sync",String(n),String(r)),await eF(a),await lj("mouseup","1")):(await lq("click","--down","0xC0"),await lq("mousemove","--absolute","-x",String(n),"-y",String(r)),await eF(a),await lq("click","--up","0xC0"))}async function l1(e,t){let{tool:n}=await lB(),r=5;if(t?.pixels!=null?r="xdotool"===n?Math.max(1,Math.round(t.pixels/15)):Math.max(1,Math.round(t.pixels/40)):t?.amount!=null&&(r=Math.max(1,Math.round(5*(t.amount/.6)))),"xdotool"===n)await lj("click","--repeat",String(r),"up"===e?"4":"down"===e?"5":"left"===e?"6":"7");else if("up"===e||"down"===e){let t="up"===e?String(-r):String(r);await lq("mousemove","--wheel","-y",t)}else{let t="left"===e?String(-r):String(r);await lq("mousemove","--wheel","-x",t)}}async function l2(e,t=0){let{tool:n}=await lB();if("xdotool"===n){let n=["type"];t>0&&n.push("--delay",String(t)),n.push("--clearmodifiers","--",e),await lj(...n)}else await lq("type","--",e)}async function l3(e,t,n,r=0){await lz(e,t),await eF(100),await lH("ctrl+a",["29:1","30:1","30:0","29:0"]),await eF(50),await l2(n,r)}function l5(e){let t=null;return{resolve:async function(){if(t)return t;let n="wayland"===lG()?"wayland":"x11";for(let r of"wayland"===n?e.wayland:e.x11)if(await eu(r.command))return t={tool:r.tool,display:n};throw new y("TOOL_MISSING","wayland"===n?e.waylandError:e.x11Error)},resetCache:()=>{t=null}}}let l4=l5({wayland:[{tool:"grim",command:"grim"},{tool:"gnome-screenshot",command:"gnome-screenshot"}],x11:[{tool:"scrot",command:"scrot"},{tool:"import",command:"import"},{tool:"gnome-screenshot",command:"gnome-screenshot"}],waylandError:"grim or gnome-screenshot is required for screenshots on Wayland. Install via your package manager.",x11Error:"scrot, import (ImageMagick), or gnome-screenshot is required for screenshots on X11. Install via your package manager."});async function l8(e){let{tool:t}=await l4.resolve();switch(t){case"grim":await ed("grim",[e]);break;case"scrot":await ed("scrot",[e]);break;case"import":await ed("import",["-window","root",e]);break;case"gnome-screenshot":await ed("gnome-screenshot",["-f",e])}}async function l6(e){if(e.includes("://")||e.startsWith("/"))return void await ed("xdg-open",[e]);if(await eu(e)){ed(e,[],{allowFailure:!0}).catch(t=>{eH({level:"warn",phase:"linux_app_launch",data:{app:e,error:String(t)}})}),await eF(500);return}await ed("xdg-open",[e],{allowFailure:!0})}async function l9(e){await eu("wmctrl")?await ed("wmctrl",["-c",e],{allowFailure:!0}):await ed("pkill",["-x",e],{allowFailure:!0})}async function l7(){await lH("alt+Left",["56:1","105:1","105:0","56:0"])}async function de(){await lH("super+d",["125:1","32:1","32:0","125:0"])}let dt=l5({wayland:[{tool:"wl-clipboard",command:"wl-paste"}],x11:[{tool:"xclip",command:"xclip"},{tool:"xsel",command:"xsel"}],waylandError:"wl-paste (wl-clipboard) is required for clipboard access on Wayland. Install via your package manager.",x11Error:"xclip or xsel is required for clipboard access on X11. Install via your package manager."});async function dn(){let{tool:e}=await dt.resolve();switch(e){case"wl-clipboard":return(await ed("wl-paste",["--no-newline"],{allowFailure:!0,timeoutMs:5e3})).stdout;case"xclip":return(await ed("xclip",["-selection","clipboard","-o"],{allowFailure:!0,timeoutMs:5e3})).stdout;case"xsel":return(await ed("xsel",["--clipboard","--output"],{allowFailure:!0,timeoutMs:5e3})).stdout}}async function dr(e){let{tool:t}=await dt.resolve();switch(t){case"wl-clipboard":await ed("wl-copy",["--",e],{allowFailure:!1,timeoutMs:5e3});break;case"xclip":await ed("xclip",["-selection","clipboard"],{allowFailure:!1,timeoutMs:5e3,stdin:e});break;case"xsel":await ed("xsel",["--clipboard","--input"],{allowFailure:!1,timeoutMs:5e3,stdin:e})}}dt.resetCache;let da={"push button":"Button","toggle button":"Button","push button menu":"Button",label:"StaticText",static:"StaticText",caption:"StaticText",text:"TextField",entry:"TextField","password text":"TextField","spin button":"TextField",terminal:"TextArea","document text":"TextArea",paragraph:"TextArea",frame:"Window",window:"Window",dialog:"Dialog",alert:"Alert","file chooser":"Dialog","color chooser":"Dialog","font chooser":"Dialog",panel:"Group",filler:"Group",section:"Group",form:"Group",grouping:"Group","layered pane":"Group","glass pane":"Group","root pane":"Group","option pane":"Group","internal frame":"Group","desktop frame":"Group","block quote":"Group",article:"Group",comment:"Group",landmark:"Group",log:"Group",marquee:"Group",math:"Group",notification:"Group","content deletion":"Group","content insertion":"Group",mark:"Group",suggestion:"Group","scroll pane":"ScrollArea","scroll bar":"ScrollBar","menu bar":"MenuBar",menu:"Menu","popup menu":"Menu","menu item":"MenuItem","check menu item":"MenuItem","radio menu item":"MenuItem","tearoff menu item":"MenuItem","check box":"CheckBox","radio button":"RadioButton",switch:"Switch","combo box":"ComboBox","page tab":"Tab","page tab list":"TabList",table:"Table","tree table":"Table","table cell":"Cell","table row":"Row","table column header":"Cell","table row header":"Cell","column header":"Cell","row header":"Cell",list:"List","list item":"ListItem","list box":"List",tree:"Tree","tree item":"TreeItem","description list":"List","description term":"ListItem","description value":"ListItem","tool bar":"Toolbar","status bar":"StatusBar","info bar":"StatusBar",slider:"Slider","progress bar":"ProgressBar","level bar":"ProgressBar",image:"Image",icon:"Image",animation:"Image",canvas:"Image","drawing area":"Image",video:"Video",audio:"Audio",link:"Link",hyperlink:"Link",separator:"Separator",application:"Application","tool tip":"Tooltip",timer:"Timer",heading:"Heading",footnote:"Footnote","title bar":"TitleBar","date editor":"DateEditor",rating:"Slider"},di="atspi-dump.py",ds=null;async function dl(e,t={}){let r;if("linux"!==process.platform)throw new y("UNSUPPORTED_PLATFORM","AT-SPI2 bridge is only available on Linux");if(!await eu("python3"))throw new y("TOOL_MISSING","python3 is required for AT-SPI2 accessibility snapshots on Linux.");let a=t.maxNodes??1500,i=t.maxDepth??12,s=t.maxApps??24,l=[function(){if(ds)return ds;let e=o.dirname(c(import.meta.url));for(let t=0;t<5;t++){let r=o.join(e,"src","platforms","linux",di);if(n.existsSync(r))return ds=r,r;if(0===t){let t=o.join(e,di);if(n.existsSync(t))return ds=t,t}e=o.dirname(e)}throw new y("TOOL_MISSING",`Cannot find ${di}. Ensure the agent-device package is installed correctly.`)}(),"--surface",e,"--max-nodes",String(a),"--max-depth",String(i),"--max-apps",String(s)],d=await ed("python3",l,{allowFailure:!0,timeoutMs:3e4});if(0!==d.exitCode){let e=d.stderr.trim();if(e.includes("No module named")||e.includes("gi.require_version"))throw new y("TOOL_MISSING","AT-SPI2 Python bindings not found. Install python3-gi and gir1.2-atspi-2.0.",{cause:e});throw new y("COMMAND_FAILED",`AT-SPI2 snapshot failed (exit ${d.exitCode}): ${e||d.stdout}`)}try{r=JSON.parse(d.stdout)}catch{throw new y("COMMAND_FAILED",`AT-SPI2 snapshot returned invalid JSON: ${d.stdout.slice(0,200)}`)}if(r.error)throw new y("COMMAND_FAILED",`AT-SPI2: ${r.error}`);return{nodes:(r.nodes??[]).map(e=>{let t,n;return{index:e.index,type:(n=da[t=e.role.toLowerCase().trim()])||t.split(/[\s_-]+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(""),role:e.role,label:e.label??void 0,value:e.value??void 0,rect:e.rect??void 0,enabled:e.enabled??void 0,selected:e.selected??void 0,hittable:e.hittable??void 0,depth:e.depth,parentIndex:e.parentIndex??void 0,pid:e.pid??void 0,appName:e.appName??void 0,windowTitle:e.windowTitle??void 0}}),truncated:r.truncated,surface:e}}async function dd(e){let t="desktop"===e?"desktop":"frontmost-app"===e||"app"===e?"frontmost-app":("menubar"===e&&eH({level:"warn",phase:"linux_snapshot",data:{message:"menubar surface is not supported on Linux, falling back to desktop"}}),"desktop"),n=await dl(t);return{nodes:n.nodes,truncated:n.truncated}}function du(e){return e?.clickButton??"primary"}function dc(e){return"primary"===e.button?null:"click"!==e.commandLabel?new y("INVALID_ARGS","--button is supported only for click"):"macos"!==e.platform&&"linux"!==e.platform?new y("UNSUPPORTED_OPERATION",`click --button ${e.button} is supported only on macOS and Linux`):"macos"===e.platform&&"middle"===e.button?new y("UNSUPPORTED_OPERATION","click --button middle is not supported by the macOS runner yet"):"number"==typeof e.count||"number"==typeof e.intervalMs||"number"==typeof e.holdMs||"number"==typeof e.jitterPx||!0===e.doubleTap?new y("INVALID_ARGS",`click --button ${e.button} does not support repeat or gesture modifier flags`):null}function dp(e){return"primary"===e?{}:{button:e}}let df=/^[A-Za-z0-9_.:-]{1,64}$/,dh=[[0,0],[1,0],[0,1],[-1,0],[0,-1],[1,1],[-1,1],[1,-1],[-1,-1]];async function dm(e,t,n){for(let r=0;r<e;r+=1)await n(r),r<e-1&&t>0&&await eF(t)}function dw(e,t){let r,a=t?.subject??"Payload",i=e.trim();if(!i)throw new y("INVALID_ARGS",`${a} cannot be empty`);let o=t?.expandPath?t.expandPath(i,t.cwd):i;try{if(!n.statSync(o).isFile())throw new y("INVALID_ARGS",`${a} path is not a file: ${o}`);return{kind:"file",path:o}}catch(t){if(t instanceof y)throw t;let e=t.code;if("EACCES"===e||"EPERM"===e)throw new y("INVALID_ARGS",`${a} file is not readable: ${o}`);if(e&&"ENOENT"!==e)throw new y("COMMAND_FAILED",`Unable to read ${a} file: ${o}`,{cause:String(t)})}if((r=i.trim()).startsWith("{")&&r.endsWith("}")||r.startsWith("[")&&r.endsWith("]"))return{kind:"inline",text:i};throw new y("INVALID_ARGS",`${a} file not found: ${o}`)}async function dg(e){let t=dw(e,{subject:"Push payload"}),n="inline"===t.kind?t.text:await dy(t.path);try{let e=JSON.parse(n);if(!e||"object"!=typeof e||Array.isArray(e))throw new y("INVALID_ARGS","push payload must be a JSON object");return e}catch(t){if(t instanceof y)throw t;throw new y("INVALID_ARGS",`Invalid push payload JSON: ${e}`)}}async function dy(e){try{return await a.readFile(e,"utf8")}catch(n){let t=n.code;if("ENOENT"===t)throw new y("INVALID_ARGS",`Push payload file not found: ${e}`);if("EISDIR"===t)throw new y("INVALID_ARGS",`Push payload path is not a file: ${e}`);if("EACCES"===t||"EPERM"===t)throw new y("INVALID_ARGS",`Push payload file is not readable: ${e}`);throw new y("COMMAND_FAILED",`Unable to read push payload file: ${e}`,{cause:String(n)})}}function db(e){if(void 0===e)throw new y("INVALID_ARGS","rotate requires an orientation argument. Use portrait|portrait-upside-down|landscape-left|landscape-right.");switch(e?.trim().toLowerCase()){case"portrait":return"portrait";case"portrait-upside-down":case"upside-down":return"portrait-upside-down";case"landscape-left":case"left":return"landscape-left";case"landscape-right":case"right":return"landscape-right";default:throw new y("INVALID_ARGS",`Invalid rotation: ${e}. Use portrait|portrait-upside-down|landscape-left|landscape-right.`)}}let dv=eU(process.env.AGENT_DEVICE_IOS_DEVICECTL_LIST_TIMEOUT_MS,8e3,500),dI=/^(iphone|ipad|ipod|appletv)/i,dA=/\b(iphone|ipad|ipod)\b/i,dx=/^appletv/i,dS=["apple tv","appletv","tvos"],dN=/^==\s*(.+?)\s*==$/,d_=/^(?<name>.+?)\s+\[(?<id>[^[\]]+)\]\s*$/;function dk(e){return(e??"").trim().toLowerCase()}function dM(e){return dk(e.hardwareProperties?.platform)}function dD(e){return e.includes("tvos")}function dE(e){let t=dk(e);return dS.some(e=>t.includes(e))}function dO(e){return[e.name??"",e.deviceProperties?.name??"",e.deviceProperties?.deviceType??""]}function dC(e){return e.hardwareProperties?.productType??e.deviceProperties?.productType??""}async function dR(e={}){let t,n,r=em(e.simulatorSetPath),a=e.target;try{t=await ed("xcrun",aB(["list","devices","-j"],{simulatorSetPath:r}))}catch{return null}try{n=JSON.parse(t.stdout)}catch{return null}let i=dP(n,r),o=null,s=null,l=null;for(let e of i)a&&e.target!==a||(e.booted&&(o=o??e),"mobile"===e.target&&(s=s??e),l=l??e);return o??s??l}function dP(e,t){let n=[];for(let[r,a]of Object.entries(e.devices))if(function(e){let t=dk(e);return t.includes("ios")||t.includes("tvos")}(r))for(let e of a)e.isAvailable&&n.push({platform:"ios",id:e.udid,name:e.name,kind:"simulator",target:dD(dk(r))?"tv":"mobile",booted:"Booted"===e.state,...t?{simulatorSetPath:t}:{}});return n}function dT(e,t){let n=new Set(e.map(e=>e.id)),r=[...e];for(let e of t)n.has(e.id)||(n.add(e.id),r.push(e));return r}async function dL(){let e=null;try{e=o.join(s.tmpdir(),`agent-device-devicectl-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);let t=await ed("xcrun",["devicectl","list","devices","--json-output",e],{allowFailure:!0,timeoutMs:dv});if(0!==t.exitCode)return[];let n=await a.readFile(e,"utf8");return function(e){let t=[];for(let n of e.result?.devices??[]){if(!function(e){var t;let n=dM(e);return!!(n.includes("ios")||n.includes("tvos"))||(t=dC(e),!!dI.test(t.trim())||dO(e).some(dE))}(n))continue;let e=n.hardwareProperties?.udid??n.identifier??"",r=n.name??n.deviceProperties?.name??e;e&&t.push({platform:"ios",id:e,name:r,kind:"device",target:function(e){var t;return dD(dM(e))?"tv":(t=dC(e),dx.test(t.trim())||dO(e).some(dE))?"tv":"mobile"}(n),booted:!0})}return t}(JSON.parse(n))}catch{return[]}finally{e&&await a.rm(e,{force:!0}).catch(()=>{})}}async function d$(){try{let e=await ed("xcrun",["xctrace","list","devices"],{allowFailure:!0});if(0!==e.exitCode)return[];return function(e){let t=[],n=null;for(let r of e.split(/\r?\n/)){let e=r.trim();if(!e)continue;let a=dN.exec(e);if(a){n=a[1]?.trim()??null;continue}if("Devices"!==n)continue;let i=d_.exec(e),o=i?.groups?.id?.trim()??"",s=i?.groups?.name?.trim()??"";if(!o||!s)continue;let l=function(e){return dE(e)?"tv":dA.test(e.trim())?"mobile":null}(s);l&&t.push({platform:"ios",id:o,name:s,kind:"device",target:l,booted:!0})}return t}(e.stdout)}catch{return[]}}async function dF(e={}){if("darwin"!==process.platform)throw new y("UNSUPPORTED_PLATFORM","Apple tools are only available on macOS");if(!await eu("xcrun"))throw new y("TOOL_MISSING","xcrun not found in PATH");let t=em(e.simulatorSetPath),n=await ed("xcrun",aB(["list","devices","-j"],{simulatorSetPath:t})),r=[];try{let e=JSON.parse(n.stdout);r=dP(e,t)}catch(e){throw new y("COMMAND_FAILED","Failed to parse simctl devices JSON",void 0,e)}if(r.push({platform:"macos",id:"host-macos-local",name:s.hostname(),kind:"device",target:"desktop",booted:!0}),t)return r;let[a,i]=await Promise.all([dL(),d$()]);return r=dT(r,a),dT(r,i)}async function dU(){return"linux"!==process.platform?[]:[{platform:"linux",id:"local",name:l(),kind:"device",target:"desktop",booted:!0}]}let dG=new u,dV=new u;async function dB(e,t,n){let r,a=!!(t.udid||t.serial||t.deviceName);try{r=await ax(e,t,n)}catch(e){if(a||!(e instanceof y)||"DEVICE_NOT_FOUND"!==e.code)throw e}if(!a&&(!t.platform||"apple"===t.platform||"ios"===t.platform)&&"desktop"!==t.target&&(!r||"device"===r.kind)){let e=await dR({simulatorSetPath:n.simulatorSetPath,target:t.target});if(e)return e}if(r)return r;throw new y("DEVICE_NOT_FOUND","No devices found",{selector:t})}async function dj(e){let t=ab(e.platform),n=aA({simulatorSetPath:em(e.iosSimulatorDeviceSet),platform:t,target:e.target}),r=eR(e.androidDeviceAllowlist),a=function(e){let{flags:t,normalizedPlatform:n,iosSimulatorSetPath:r,androidSerialAllowlist:a}=e;return JSON.stringify({platform:n,target:t.target,device:t.device,udid:t.udid,serial:t.serial,iosSimulatorSetPath:r,androidSerialAllowlist:a?Array.from(a).sort():void 0})}({flags:e,normalizedPlatform:t,iosSimulatorSetPath:n,androidSerialAllowlist:r}),i={platform:t,target:e.target,cacheHit:!1};return await eq("resolve_target_device",async()=>{let o=function(e){let t=dG.getStore(),n=t?.get(e);if(n)return{...n}}(a);if(o)return i.cacheHit=!0,o;let s={platform:t,target:e.target,deviceName:e.device,udid:e.udid,serial:e.serial};if(s.target&&!s.platform)throw new y("INVALID_ARGS","Device target selector requires --platform. Use --platform ios|macos|android|linux|apple with --target mobile|tv|desktop.");let l=await dK({...s,iosSimulatorSetPath:n,androidSerialAllowlist:r?Array.from(r).sort():void 0});if(l)return dz(a,await ax(l,s,{simulatorSetPath:n}));if("linux"===s.platform){let e=await dU();return dz(a,await ax(e,s))}if("android"===s.platform){await ex();let e=await eE({serialAllowlist:r});return dz(a,await ax(e,s))}if(s.platform){let e=await dF({simulatorSetPath:n});return dz(a,await dB(e,s,{simulatorSetPath:n}))}let d=[];try{d.push(...await eE({serialAllowlist:r}))}catch{}try{d.push(...await dF({simulatorSetPath:n}))}catch{}try{d.push(...await dU())}catch{}return dz(a,await ax(d,s,{simulatorSetPath:n}))},i)}async function dq(e){return dG.getStore()?await e():await dG.run(new Map,e)}async function dX(e,t){return e?await dV.run(e,t):await t()}async function dH(e,t){return await dX(e,async()=>await dq(t))}async function dK(e){let t=dV.getStore();if(!t)return null;let n=await t(e);return null==n?null:n.map(e=>({...e}))}function dz(e,t){return dG.getStore()?.set(e,{...t}),t}async function dY(e,t,n,r,i){let s={requestId:i?.requestId,appBundleId:i?.appBundleId,verbose:i?.verbose,logPath:i?.logPath,traceLogPath:i?.traceLogPath},l=function(e,t){switch(e.platform){case"android":return{open:(t,n)=>eI(e,t,n?.activity),openDevice:()=>ek(e),close:t=>eS(e,t),tap:(t,n)=>oC(e,t,n),doubleTap:async(t,n)=>{await oC(e,t,n),await oC(e,t,n)},swipe:(t,n,r,a,i)=>oR(e,t,n,r,a,i),longPress:(t,n,r)=>oF(e,t,n,r),focus:(t,n)=>oV(e,t,n),type:(t,n)=>oU(e,t,n),fill:(t,n,r,a)=>oB(e,t,n,r,a),scroll:(t,n)=>oX(e,t,n),screenshot:t=>sr(e,t),back:t=>oP(e),home:()=>oT(e),rotate:t=>oL(e,t),appSwitcher:()=>o$(e),readClipboard:()=>e$(e),writeClipboard:t=>eM(e,t),setSetting:(t,n,r,a)=>o5(e,t,n,r,a)};case"linux":return{open:e=>l6(e),openDevice:()=>Promise.resolve(),close:e=>l9(e),tap:(e,t)=>lz(e,t),doubleTap:(e,t)=>lJ(e,t),swipe:(e,t,n,r,a)=>l0(e,t,n,r,a),longPress:(e,t,n)=>lZ(e,t,n),focus:(e,t)=>lQ(e,t),type:(e,t)=>l2(e,t),fill:(e,t,n,r)=>l3(e,t,n,r),scroll:(e,t)=>l1(e,t),screenshot:e=>l8(e),back:()=>l7(),home:()=>de(),rotate:()=>{throw new y("UNSUPPORTED_OPERATION","rotate not supported on Linux")},appSwitcher:()=>{throw new y("UNSUPPORTED_OPERATION","appSwitcher not yet supported on Linux")},readClipboard:()=>dn(),writeClipboard:e=>dr(e),setSetting:()=>{throw new y("UNSUPPORTED_OPERATION","setSetting not supported on Linux")}};case"ios":case"macos":{let n,{overrides:r,runnerOpts:a}={runnerOpts:n={verbose:t.verbose,logPath:t.logPath,traceLogPath:t.traceLogPath,requestId:t.requestId},overrides:{tap:async(r,a)=>await i4(e,{command:"tap",x:r,y:a,appBundleId:t.appBundleId},n),doubleTap:async(r,a)=>await i4(e,{command:"tapSeries",x:r,y:a,count:1,intervalMs:0,doubleTap:!0,appBundleId:t.appBundleId},n),swipe:async(r,a,i,o,s)=>await i4(e,{command:"drag",x:r,y:a,x2:i,y2:o,durationMs:s,appBundleId:t.appBundleId},n),longPress:async(r,a,i)=>await i4(e,{command:"longPress",x:r,y:a,durationMs:i,appBundleId:t.appBundleId},n),focus:async(r,a)=>await i4(e,{command:"tap",x:r,y:a,appBundleId:t.appBundleId},n),type:async(r,a)=>{await i4(e,{command:"type",text:r,delayMs:a,appBundleId:t.appBundleId},n)},fill:async(r,a,i,o)=>{let s=await i4(e,{command:"tap",x:r,y:a,appBundleId:t.appBundleId},n);return await i4(e,{command:"type",text:i,clearFirst:!0,delayMs:o,appBundleId:t.appBundleId},n),s},scroll:async(r,a)=>await lL(i4,e,t,n,r,a)}};return{open:(t,n)=>lh(e,t,{appBundleId:n?.appBundleId,url:n?.url}),openDevice:()=>lm(e),close:t=>lw(e,t),screenshot:async(t,n)=>{"macos"===e.platform&&n?.surface&&"app"!==n.surface?await ow(t,{surface:n.surface,fullscreen:n.fullscreen}):await s8(e,t,n?.appBundleId,n?.fullscreen)},back:async n=>{await i4(e,{command:"system"===n?"backSystem":"backInApp",appBundleId:t.appBundleId},a)},home:async()=>{await i4(e,{command:"home",appBundleId:t.appBundleId},a)},rotate:async n=>{await i4(e,{command:"rotate",orientation:n,appBundleId:t.appBundleId},a)},appSwitcher:async()=>{await i4(e,{command:"appSwitcher",appBundleId:t.appBundleId},a)},readClipboard:()=>lI(e),writeClipboard:t=>lA(e,t),setSetting:(t,n,r,a)=>lS(e,t,n,r,a),...r}}default:throw new y("UNSUPPORTED_PLATFORM",`Unsupported platform: ${e.platform}`)}}(e,s);return eH({level:"debug",phase:"platform_command_prepare",data:{command:t,platform:e.platform,kind:e.kind}}),await eq("platform_command",async()=>{switch(t){case"open":return dW(e,l,n,i);case"close":{let e=n[0];if(!e)return{closed:"session",...ea("Closed session")};return await l.close(e),{app:e,...ea(`Closed: ${e}`)}}case"press":return dJ(e,l,n,i,s);case"swipe":return dZ(e,l,n,i,s);case"longpress":{let e=Number(n[0]),t=Number(n[1]),r=n[2]?Number(n[2]):void 0;if(Number.isNaN(e)||Number.isNaN(t))throw new y("INVALID_ARGS","longpress requires x y [durationMs]");return await l.longPress(e,t,r),{x:e,y:t,durationMs:r,...ea(`Long pressed (${e}, ${t})`)}}case"focus":{let[e,t]=n.map(Number);if(Number.isNaN(e)||Number.isNaN(t))throw new y("INVALID_ARGS","focus requires x y");return await l.focus(e,t),{x:e,y:t,...ea(`Focused (${e}, ${t})`)}}case"type":{let e=function(e){let t=e[0]?.trim();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(e)throw new y("INVALID_ARGS",`type does not accept a target ref like "${e}"`,{hint:`Use fill ${e} "text" to target that field, or press ${e} then type "text" to append.`});let t=n.join(" ");if(!t)throw new y("INVALID_ARGS","type requires text");let r=n$(i?.delayMs??0,"delay-ms",0,1e4);return await l.type(t,r),{text:t,delayMs:r,...ea(d7("Typed",t))}}case"fill":{let e=Number(n[0]),t=Number(n[1]),r=n.slice(2).join(" ");if(Number.isNaN(e)||Number.isNaN(t)||!r)throw new y("INVALID_ARGS","fill requires x y text");let a=n$(i?.delayMs??0,"delay-ms",0,1e4);return await l.fill(e,t,r,a),{x:e,y:t,text:r,delayMs:a,...ea(d7("Filled",r))}}case"scroll":return dQ(l,n,i);case"pinch":return d0(e,n,i,s);case"trigger-app-event":{let{eventName:t,payload:r}=function(e){let t=e[0]?.trim(),n=e[1]?.trim();if(!t)throw new y("INVALID_ARGS","trigger-app-event requires <event> [payloadJson]");if(!df.test(t))throw new y("INVALID_ARGS",`Invalid trigger-app-event event name: ${t}`,{hint:"Use 1-64 chars: letters, numbers, underscore, dot, colon, or dash."});if(e.length>2)throw new y("INVALID_ARGS","trigger-app-event accepts at most two arguments: <event> [payloadJson]");let r=function(e,t){if(e)try{let n=JSON.parse(e);if(!n||"object"!=typeof n||Array.isArray(n))throw new y("INVALID_ARGS",`trigger-app-event payload for "${t}" must be a JSON object`);let r=JSON.stringify(n);if(Buffer.byteLength(r,"utf8")>8192)throw new y("INVALID_ARGS",`trigger-app-event payload for "${t}" exceeds 8192 bytes`);return n}catch(t){if(t instanceof y)throw t;throw new y("INVALID_ARGS",`Invalid trigger-app-event payload JSON: ${e}`)}}(n,t);return{eventName:t,payload:r}}(n),a=function(e,t,n){var r;let a,i=(a=("ios"===(r=e)?process.env.AGENT_DEVICE_IOS_APP_EVENT_URL_TEMPLATE:"macos"===r?process.env.AGENT_DEVICE_MACOS_APP_EVENT_URL_TEMPLATE:process.env.AGENT_DEVICE_ANDROID_APP_EVENT_URL_TEMPLATE)??process.env.AGENT_DEVICE_APP_EVENT_URL_TEMPLATE,a?.trim()||void 0);if(!i)throw new y("UNSUPPORTED_OPERATION",`No app event URL template configured for ${e}.`,{hint:`Set AGENT_DEVICE_${e.toUpperCase()}_APP_EVENT_URL_TEMPLATE or AGENT_DEVICE_APP_EVENT_URL_TEMPLATE, for example "myapp://agent-device/event?name={event}&payload={payload}".`});let o=n?JSON.stringify(n):"",s=i.replaceAll("{event}",encodeURIComponent(t)).replaceAll("{payload}",encodeURIComponent(o)).replaceAll("{platform}",encodeURIComponent(e));if(s.length>4096)throw new y("INVALID_ARGS","trigger-app-event URL exceeds maximum supported length",{hint:"Reduce payload size or shorten AGENT_DEVICE_*_APP_EVENT_URL_TEMPLATE.",length:s.length,maxLength:4096});return s}(e.platform,t,r);return await l.open(a,{appBundleId:i?.appBundleId}),{event:t,eventUrl:a,transport:"deep-link",...ea(`Triggered app event: ${t}`)}}case"screenshot":{let e=n[0]??r??`./screenshot-${Date.now()}.png`;return await a.mkdir(o.dirname(e),{recursive:!0}),await l.screenshot(e,{appBundleId:i?.appBundleId,fullscreen:i?.screenshotFullscreen,surface:i?.surface}),{path:e,...ea(`Saved screenshot: ${e}`)}}case"back":return await l.back(i?.backMode),{action:"back",mode:i?.backMode??"in-app",...ea("Back")};case"home":return await l.home(),{action:"home",...ea("Home")};case"rotate":{let e=db(n[0]);return await l.rotate(e),{action:"rotate",orientation:e,...ea(`Rotated to ${e}`)}}case"app-switcher":return await l.appSwitcher(),{action:"app-switcher",...ea("Opened app switcher")};case"clipboard":return d1(l,n);case"keyboard":return d2(e,l,n,i,s);case"settings":return d3(e,l,n,i);case"push":return d5(e,n,i);case"snapshot":return d4(e,n,i,s);case"read":return d8(e,n,i,s);default:throw new y("INVALID_ARGS",`Unknown command: ${t}`)}},{command:t,platform:e.platform})}async function dW(e,t,n,r){let a=n[0],i=n[1];if(n.length>2)throw new y("INVALID_ARGS","open accepts at most two arguments: <app|url> [url]");if(!a)return await t.openDevice(),{app:null,...ea("Opened device")};if(void 0!==i){if("android"===e.platform)throw new y("INVALID_ARGS","open <app> <url> is supported only on Apple platforms");if(eT(a))throw new y("INVALID_ARGS","open <app> <url> requires an app target as the first argument");if(!eT(i))throw new y("INVALID_ARGS","open <app> <url> requires a valid URL target");return await t.open(a,{activity:r?.activity,appBundleId:r?.appBundleId,url:i}),{app:a,url:i,...ea(`Opened: ${a}`)}}return await t.open(a,{activity:r?.activity,appBundleId:r?.appBundleId}),{app:a,...ea(`Opened: ${a}`)}}async function dJ(e,t,n,r,a){let i,[o,s]=n.map(Number);if(Number.isNaN(o)||Number.isNaN(s))throw new y("INVALID_ARGS","press requires x y");if("macos"===e.platform&&r?.surface&&"app"!==r.surface){let e=du(r);if("primary"!==e)throw new y("UNSUPPORTED_OPERATION",`${e} click is not supported on macOS ${r.surface} sessions.`);return await om(o,s,{bundleId:r.appBundleId,surface:r.surface}),{x:o,y:s,...ea(d6({x:o,y:s}))}}let l=du(r);if("primary"!==l){let t=dc({commandLabel:"click",platform:e.platform,button:l,count:r?.count,intervalMs:r?.intervalMs,holdMs:r?.holdMs,jitterPx:r?.jitterPx,doubleTap:r?.doubleTap});if(t)throw t;return"linux"===e.platform?"secondary"===l?await lY(o,s):await lW(o,s):await i4(e,{command:"mouseClick",x:o,y:s,button:l,appBundleId:r?.appBundleId},{verbose:r?.verbose,logPath:r?.logPath,traceLogPath:r?.traceLogPath,requestId:r?.requestId}),{x:o,y:s,button:l,...ea(d6({x:o,y:s,button:l}))}}let d=n$(r?.count??1,"count",1,200),u=n$(r?.intervalMs??0,"interval-ms",0,1e4),c=n$(r?.holdMs??0,"hold-ms",0,1e4),p=n$(r?.jitterPx??0,"jitter-px",0,100),f=r?.doubleTap===!0;if(f&&c>0)throw new y("INVALID_ARGS","double-tap cannot be combined with hold-ms");if(f&&p>0)throw new y("INVALID_ARGS","double-tap cannot be combined with jitter-px");if(av(e.platform)&&d>1&&0===c&&0===p){let t=await i4(e,{command:"tapSeries",x:o,y:s,count:d,intervalMs:u,doubleTap:f,appBundleId:r?.appBundleId},{verbose:r?.verbose,logPath:r?.logPath,traceLogPath:r?.traceLogPath,requestId:r?.requestId});return{x:o,y:s,count:d,intervalMs:u,holdMs:c,jitterPx:p,doubleTap:f,timingMode:"runner-series",...t,...ea(d6({x:o,y:s}))}}return await dm(d,u,async e=>{let[n,r]=function(e,t){if(t<=0)return[0,0];let[n,r]=dh[e%dh.length];return[n*t,r*t]}(e,p),a=o+n,l=s+r;if(f){i??=await t.doubleTap(a,l)??void 0;return}c>0?i??=await t.longPress(a,l,c)??void 0:i??=await t.tap(a,l)??void 0}),ei({x:o,y:s,count:d,intervalMs:u,holdMs:c,jitterPx:p,doubleTap:f,...i},d6({x:o,y:s}))}async function dZ(e,t,n,r,a){let i=Number(n[0]),o=Number(n[1]),s=Number(n[2]),l=Number(n[3]);if([i,o,s,l].some(Number.isNaN))throw new y("INVALID_ARGS","swipe requires x1 y1 x2 y2 [durationMs]");let d=n$(n[4]?Number(n[4]):250,"durationMs",16,1e4),u="ios"===e.platform?Math.min(60,Math.max(16,Math.round(d))):d,c=n$(r?.count??1,"count",1,200),p=n$(r?.pauseMs??0,"pause-ms",0,1e4),f=r?.pattern??"one-way";if("one-way"!==f&&"ping-pong"!==f)throw new y("INVALID_ARGS",`Invalid pattern: ${f}`);if(av(e.platform)&&c>1){let t=await i4(e,{command:"dragSeries",x:i,y:o,x2:s,y2:l,durationMs:u,count:c,pauseMs:p,pattern:f,appBundleId:r?.appBundleId},{verbose:r?.verbose,logPath:r?.logPath,traceLogPath:r?.traceLogPath,requestId:r?.requestId});return{x1:i,y1:o,x2:s,y2:l,durationMs:d,effectiveDurationMs:u,timingMode:"runner-series",count:c,pauseMs:p,pattern:f,...t,...ea(d9(c,f))}}return await dm(c,p,async e=>{"ping-pong"===f&&e%2==1?await t.swipe(s,l,i,o,u):await t.swipe(i,o,s,l,u)}),ei({x1:i,y1:o,x2:s,y2:l,durationMs:d,effectiveDurationMs:u,timingMode:"ios"===e.platform?"safe-normalized":"direct",count:c,pauseMs:p,pattern:f},d9(c,f))}async function dQ(e,t,n){let r=t[0],a=t[1]?Number(t[1]):void 0,i=n?.pixels;if(!r)throw new y("INVALID_ARGS","scroll requires direction");if(void 0!==a&&!Number.isFinite(a))throw new y("INVALID_ARGS","scroll amount must be a number");if(void 0!==a&&void 0!==i)throw new y("INVALID_ARGS","scroll accepts either a relative amount or --pixels, not both");let o=function(e){switch(e){case"up":case"down":case"left":case"right":return e;default:throw new y("INVALID_ARGS",`Unknown direction: ${e}`)}}(r),s=await e.scroll(o,{amount:a,pixels:i});return ei({direction:o,...void 0!==a?{amount:a}:{},...void 0!==i?{pixels:i}:{},...s},void 0!==i?`Scrolled ${o} by ${i}px`:void 0!==a?`Scrolled ${o} by ${a}`:`Scrolled ${o}`)}async function d0(e,t,n,r){if("android"===e.platform)throw new y("UNSUPPORTED_OPERATION","Android pinch is not supported in current adb backend; requires instrumentation-based backend.");if("macos"===e.platform&&n?.surface&&"app"!==n.surface)throw new y("UNSUPPORTED_OPERATION","pinch is only supported in macOS app sessions. Re-open the target app without --surface desktop|menubar|frontmost-app first.");let a=Number(t[0]),i=t[1]?Number(t[1]):void 0,o=t[2]?Number(t[2]):void 0;if(Number.isNaN(a)||a<=0)throw new y("INVALID_ARGS","pinch requires scale > 0");return await i4(e,{command:"pinch",scale:a,x:i,y:o,appBundleId:n?.appBundleId},{verbose:n?.verbose,logPath:n?.logPath,traceLogPath:n?.traceLogPath,requestId:n?.requestId}),{scale:a,x:i,y:o,...ea(`Pinched to scale ${a}`)}}async function d1(e,t){let n=(t[0]??"").toLowerCase();if("read"!==n&&"write"!==n)throw new y("INVALID_ARGS","clipboard requires a subcommand: read or write");if("read"===n){if(1!==t.length)throw new y("INVALID_ARGS","clipboard read does not accept additional arguments");return{action:n,text:await e.readClipboard()}}if(t.length<2)throw new y("INVALID_ARGS",'clipboard write requires text (use "" to clear clipboard)');let r=t.slice(1).join(" ");return await e.writeClipboard(r),{action:n,textLength:Array.from(r).length,...ea("Clipboard updated")}}async function d2(e,t,n,r,a){let i=(n[0]??"status").toLowerCase();if("status"!==i&&"get"!==i&&"dismiss"!==i)throw new y("INVALID_ARGS","keyboard requires a subcommand: status, get, or dismiss");if(n.length>1)throw new y("INVALID_ARGS","keyboard accepts at most one subcommand argument");if("android"===e.platform){if("dismiss"===i){let t=await ew(e);return{platform:"android",action:"dismiss",attempts:t.attempts,wasVisible:t.wasVisible,dismissed:t.dismissed,visible:t.visible,inputType:t.inputType,type:t.type}}let t=await eD(e);return{platform:"android",action:"status",visible:t.visible,inputType:t.inputType,type:t.type}}if("ios"===e.platform){if("dismiss"!==i)throw new y("UNSUPPORTED_OPERATION","keyboard status/get is currently supported only on Android; use keyboard dismiss on iOS");let t=await i4(e,{command:"keyboardDismiss",appBundleId:r?.appBundleId},a);return{platform:"ios",action:"dismiss",wasVisible:t.wasVisible,dismissed:t.dismissed,visible:t.visible,...ea(t.dismissed?"Keyboard dismissed":"Keyboard already hidden")}}throw new y("UNSUPPORTED_OPERATION","keyboard is supported only on Android and iOS")}async function d3(e,t,n,r){var a;let[i,o,s,l,d]=n,u="permission"===i?{permissionTarget:s,permissionMode:l}:void 0;eH({level:"debug",phase:"settings_apply",data:{setting:i,state:o,target:s,mode:l,platform:e.platform}});let c=await t.setSetting(i,o,d??r?.appBundleId,u);return c&&"object"==typeof c?ei({setting:i,state:o,...c},("string"==typeof(a=c).message&&a.message.length>0?a.message:void 0)??`Updated setting: ${i}`):{setting:i,state:o,...ea(`Updated setting: ${i}`)}}async function d5(e,t,n){let r=t[0]?.trim(),a=t[1]?.trim();if(!r||!a)throw new y("INVALID_ARGS","push requires <bundle|package> <payload.json|inline-json>");let i=await dg(a);if("ios"===e.platform)return await lx(e,r,i),{platform:"ios",bundleId:r,...ea(`Pushed notification to ${r}`)};let o=await st(e,r,i);return{platform:"android",package:r,action:o.action,extrasCount:o.extrasCount,...ea(`Pushed notification to ${r}`)}}async function d4(e,t,n,r){if("linux"===e.platform){let e=await eq("snapshot_capture",async()=>await dd(n?.surface),{backend:"linux-atspi"});return{nodes:e.nodes??[],truncated:e.truncated??!1,backend:"linux-atspi"}}if("android"!==e.platform){let t=await eq("snapshot_capture",async()=>await i4(e,{command:"snapshot",appBundleId:n?.appBundleId,interactiveOnly:n?.snapshotInteractiveOnly,compact:n?.snapshotCompact,depth:n?.snapshotDepth,scope:n?.snapshotScope,raw:n?.snapshotRaw},{verbose:n?.verbose,logPath:n?.logPath,traceLogPath:n?.traceLogPath,requestId:n?.requestId}),{backend:"xctest"}),r=t.nodes??[];if(0===r.length&&"simulator"===e.kind)throw new y("COMMAND_FAILED","XCTest snapshot returned 0 nodes on iOS simulator.");return{nodes:r,truncated:t.truncated??!1,backend:"xctest"}}let a=await eq("snapshot_capture",async()=>await oI(e,{interactiveOnly:n?.snapshotInteractiveOnly,compact:n?.snapshotCompact,depth:n?.snapshotDepth,scope:n?.snapshotScope,raw:n?.snapshotRaw}),{backend:"android"});return{nodes:a.nodes??[],truncated:a.truncated??!1,backend:"android",analysis:a.analysis,androidSnapshot:a.androidSnapshot}}async function d8(e,t,n,r){let[a,i]=t.map(Number);if(Number.isNaN(a)||Number.isNaN(i))throw new y("INVALID_ARGS","read requires x y");if("android"===e.platform)return{action:"read",text:await oJ(e,a,i)??""};if("macos"===e.platform&&n?.surface&&"app"!==n.surface)return{action:"read",text:(await oh(a,i,{bundleId:n.appBundleId,surface:n.surface})).text};let o=await i4(e,{command:"readText",x:a,y:i,appBundleId:n?.appBundleId},{verbose:n?.verbose,logPath:n?.logPath,traceLogPath:n?.traceLogPath,requestId:n?.requestId});return{action:"read",text:"string"==typeof o.text?o.text:"string"==typeof o.message?o.message:""}}function d6(e){return e.button&&"primary"!==e.button?`Clicked ${e.button} (${e.x}, ${e.y})`:`Tapped (${e.x}, ${e.y})`}function d9(e,t){return e<=1?"Swiped":"ping-pong"===t?`Swiped ${e} times (ping-pong)`:`Swiped ${e} times`}function d7(e,t){return`${e} ${Array.from(t).length} chars`}let ue=eU(process.env.AGENT_DEVICE_IOS_DEVICE_READY_TIMEOUT_MS,15e3,1e3),ut=new Map;async function un(e){var t;let n,r=(n="simulator"===(t=e).kind?t.simulatorSetPath??"":"",JSON.stringify([t.platform,t.kind,t.id,t.target??"",n])),a=ut.get(r);if(void 0!==a){if(a>Date.now())return;ut.delete(r)}if("ios"===e.platform){if("simulator"===e.kind){let{ensureBootedSimulator:t}=await Promise.resolve(eJ);await t(e),ur(r);return}if("device"===e.kind){await ua(e.id),ur(r);return}}if("android"===e.platform){let{waitForAndroidBoot:t}=await import("./8809.js");await t(e.id),ur(r)}}function ur(e){ut.set(e,Date.now()+5e3)}async function ua(e){let t=o.join(s.tmpdir(),`agent-device-ready-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),n=Math.max(1,Math.ceil(ue/1e3));try{let r=await ed("xcrun",["devicectl","device","info","details","--device",e,"--json-output",t,"--timeout",String(n)],{allowFailure:!0,timeoutMs:ue+3e3}),a=String(r.stdout??""),i=String(r.stderr??""),o=await ui(t);if(0===r.exitCode){if(!o.parsed)throw new y("COMMAND_FAILED","iOS device readiness probe failed",{kind:"probe_inconclusive",deviceId:e,stdout:a,stderr:i,hint:"CoreDevice returned success but readiness JSON output was missing or invalid. Retry; if it persists restart Xcode and the iOS device."});let t=o?.tunnelState?.toLowerCase();if("connecting"===t)throw new y("COMMAND_FAILED","iOS device is not ready for automation",{kind:"not_ready",deviceId:e,tunnelState:t,hint:"Device tunnel is still connecting. Keep the device unlocked and connected by cable until it is fully available in Xcode Devices, then retry."});return}throw new y("COMMAND_FAILED","iOS device is not ready for automation",{kind:"not_ready",deviceId:e,stdout:a,stderr:i,exitCode:r.exitCode,tunnelState:o?.tunnelState,hint:uo(a,i)})}catch(t){if(t instanceof y&&"COMMAND_FAILED"===t.code){if("not_ready"===("string"==typeof t.details?.kind?t.details.kind:""))throw t;let n=t.details??{},r=String(n.stdout??""),a=String(n.stderr??""),i=Number(n.timeoutMs??ue),o=`CoreDevice did not respond within ${i}ms. Keep the device unlocked and trusted, then retry; if it persists restart Xcode and the iOS device.`;throw new y("COMMAND_FAILED","iOS device readiness probe failed",{deviceId:e,cause:t.message,timeoutMs:i,stdout:r,stderr:a,hint:r||a?uo(r,a):o},t)}throw new y("COMMAND_FAILED","iOS device readiness probe failed",{deviceId:e,hint:"Reconnect the device, keep it unlocked, and retry."},t instanceof Error?t:void 0)}finally{await a.rm(t,{force:!0}).catch(()=>{})}}async function ui(e){try{let t=await a.readFile(e,"utf8"),n=JSON.parse(t),r=function(e){let t=e?.result;if(!t||"object"!=typeof t)return{};let n=t.connectionProperties?.tunnelState,r=t.device?.connectionProperties?.tunnelState,a="string"==typeof n?n:"string"==typeof r?r:void 0;return a?{tunnelState:a}:{}}(n);return{parsed:!0,tunnelState:r.tunnelState}}catch{return{parsed:!1}}}function uo(e,t){let n=sb(e,t);return n||(`${e}
|
|
26
|
+
${t}`.toLowerCase().includes("timed out waiting for all destinations")?"Xcode destination did not become available in time. Keep device unlocked and retry.":sy)}async function us(e,t,n){let r=e.get(t),a=r?.device??await dj(n??{});return r||await un(a),{session:r,device:a}}async function ul(e,t,n){let r=!e&&"ios"===t.platform;try{return await n()}finally{r&&await iJ(t.id)}}function ud(e,t,n,r){t&&e.recordAction(t,{command:n.command,positionals:n.positionals??[],flags:n.flags??{},result:r})}async function uu(e){let{req:t,logPath:n,sessionStore:r,session:a,device:i}=e,o=(t.positionals?.[0]??"get").toLowerCase(),s=a?"frontmost-app"===a.surface?{surface:"frontmost-app"}:{bundleId:a.appBundleId,surface:a.surface}:{};if(!aD("alert",i))return aw("UNSUPPORTED_OPERATION","alert is not supported on this device");if("macos"===i.platform){let e=async()=>await op("wait"===o?"get":o,s);if("wait"===o){let n=ag(t.positionals?.[1])??1e4,i=Date.now();for(;Date.now()-i<n;){try{let n=await e();return ud(r,a,t,n),{ok:!0,data:n}}catch{}await eF(300)}return aw("COMMAND_FAILED","alert wait timed out")}let n="accept"===o||"dismiss"===o?o:"get";if("accept"===n||"dismiss"===n){let e,i=Date.now();for(;Date.now()-i<2e3;){try{let e=await op(n,s);return ud(r,a,t,e),{ok:!0,data:e}}catch(n){e=n;let t=String(n?.message??"").toLowerCase();if(!t.includes("alert not found")&&!t.includes("no alert"))break}await eF(300)}throw uc(e)}let i=await op("get",s);return ud(r,a,t,i),{ok:!0,data:i}}if("wait"===o){let e=ag(t.positionals?.[1])??1e4,o=Date.now();for(;Date.now()-o<e;){try{let e=await i4(i,{command:"alert",action:"get",appBundleId:a?.appBundleId},{verbose:t.flags?.verbose,logPath:n,traceLogPath:a?.trace?.outPath,requestId:t.meta?.requestId});return ud(r,a,t,e),{ok:!0,data:e}}catch{}await eF(300)}return aw("COMMAND_FAILED","alert wait timed out")}let l="accept"===o||"dismiss"===o?o:"get",d={verbose:t.flags?.verbose,logPath:n,traceLogPath:a?.trace?.outPath,requestId:t.meta?.requestId};if("accept"===l||"dismiss"===l){let e,n=Date.now();for(;Date.now()-n<2e3;){try{let e=await i4(i,{command:"alert",action:l,appBundleId:a?.appBundleId},d);return ud(r,a,t,e),{ok:!0,data:e}}catch(n){e=n;let t=String(n?.message??"").toLowerCase();if(!t.includes("alert not found")&&!t.includes("no alert"))break}await eF(300)}throw uc(e)}let u=await i4(i,{command:"alert",action:l,appBundleId:a?.appBundleId},d);return ud(r,a,t,u),{ok:!0,data:u}}function uc(e){if(!(e instanceof y))return e;let t=String(e.message??"").toLowerCase();return t.includes("alert not found")||t.includes("no alert")?new y(e.code,e.message,{...e.details??{},hint:"If the permission sheet is visible in snapshot or screenshot but alert reports no alert, take a scoped snapshot around the visible button label and use press @ref."}):e}function up(e,t,n,r,a){return{requestId:a??eX().requestId,appBundleId:n,activity:t?.activity,verbose:t?.verbose,logPath:e,traceLogPath:r,snapshotInteractiveOnly:t?.snapshotInteractiveOnly,snapshotCompact:t?.snapshotCompact,snapshotDepth:t?.snapshotDepth,snapshotScope:t?.snapshotScope,snapshotRaw:t?.snapshotRaw,screenshotFullscreen:t?.screenshotFullscreen,screenshotMaxSize:t?.screenshotMaxSize,count:t?.count,intervalMs:t?.intervalMs,delayMs:t?.delayMs,holdMs:t?.holdMs,jitterPx:t?.jitterPx,pixels:t?.pixels,doubleTap:t?.doubleTap,clickButton:du(t),backMode:t?.backMode,pauseMs:t?.pauseMs,pattern:t?.pattern}}async function uf(e){let t,{req:n,logPath:r,sessionStore:a,session:i,device:o,parsed:s}=e,{setting:l,state:d,permissionTarget:u}=s;if(!aD("settings",o))return aw("UNSUPPORTED_OPERATION","settings is not supported on this device");if("macos"===o.platform&&"appearance"!==(t=l.trim().toLowerCase())&&"permission"!==t)return aw("INVALID_ARGS",e7(l));let c=i?.appBundleId,p="permission"===l?[l,d,u??"",n.positionals?.[3]??"",c??""]:[l,d,c??""],f=await dY(o,"settings",p,n.flags?.out,{...up(r,n.flags,c,i?.trace?.outPath)});return ud(a,i,n,f??{setting:l,state:d}),{ok:!0,data:f??{setting:l,state:d}}}function uh(e,t={}){let n=!0===t.plural?"do":"does";return{resolveInput:async()=>{throw new y("UNSUPPORTED_OPERATION",`${e} ${n} not resolve input artifacts`)},reserveOutput:async()=>{throw new y("UNSUPPORTED_OPERATION",`${e} ${n} not reserve output artifacts`)},createTempFile:async()=>{throw new y("UNSUPPORTED_OPERATION",`${e} ${n} not create temporary files`)}}}let um=[250,400,600];function uw(e,t,n=e.snapshot){if("android"!==e.device.platform)return;let r=n?.comparisonSafe===!0;e.androidSnapshotFreshness={action:t,markedAt:Date.now(),baselineCount:n?.nodes.length??0,baselineSignatures:r?uv(n?.nodes??[]):void 0,routeComparable:r}}function ug(e){if(!e||"android"!==e.device.platform)return;let t=e.androidSnapshotFreshness;if(t)return Date.now()-t.markedAt>2500?void delete e.androidSnapshotFreshness:t}function uy(e){e&&"android"===e.device.platform&&delete e.androidSnapshotFreshness}function ub(e){return"press"===e||"click"===e||"back"===e||"open"===e}function uv(e){return e.map(e=>[e.depth??0,e.type??"",e.role??"",e.label??"",e.value??"",e.identifier??"",!1===e.enabled?"disabled":"enabled",!0===e.selected?"selected":"unselected",!0===e.hittable?"hittable":"not-hittable"].join("|"))}async function uI(e){let t=ug(e.session);if(t&&"android"===e.device.platform)return await ux(e,t);let n=await uA(e);return uy(e.session),{snapshot:uk(n,uN(e)),analysis:n.analysis,androidSnapshot:n.androidSnapshot}}async function uA(e){let{device:t,session:n,flags:r,outPath:a,logPath:i,snapshotScope:o}=e;if("linux"===t.platform){let e=await dd(n?.surface);return uM({nodes:e.nodes,truncated:e.truncated,backend:"linux-atspi"},{snapshotDepth:r?.snapshotDepth,snapshotInteractiveOnly:r?.snapshotInteractiveOnly,snapshotScope:o})}return"macos"===t.platform&&n?.surface&&"app"!==n.surface?uM(await of(n.surface,{bundleId:"menubar"===n.surface?n.appBundleId:void 0}),{snapshotDepth:r?.snapshotDepth,snapshotInteractiveOnly:r?.snapshotInteractiveOnly,snapshotScope:o}):await dY(t,"snapshot",[],a,{...up(i,{...r,snapshotScope:o},n?.appBundleId,n?.trace?.outPath)})}async function ux(e,t){let n=await uS(e),r=u_(n,t,e),a=0,i=t.markedAt+1500;for(let o of um){if(!r)break;let s=i-Date.now();if(s<=0)break;await eF(Math.min(o,s)),n=await uS(e),a+=1,r=u_(n,t,e)}return r||uy(e.session),{snapshot:n.snapshot,analysis:n.data.analysis,androidSnapshot:n.data.androidSnapshot,freshness:a>0||r?{action:t.action,retryCount:a,staleAfterRetries:!!r,reason:r??void 0}:void 0}}async function uS(e){let t=await uA(e);return{data:t,snapshot:uk(t,uN(e))}}function uN(e){return void 0===e.snapshotScope?e.flags:{...e.flags,snapshotScope:e.snapshotScope}}function u_(e,t,n){var r,a;let i=n.flags?.snapshotInteractiveOnly===!0,o=e.data.analysis;if(i&&0===e.snapshot.nodes.length&&o&&o.rawNodeCount>=12)return"empty-interactive";if("ref-refresh"===n.androidFreshnessMode)return null;return(r=t.baselineCount,a=e.snapshot.nodes.length,!(r<12)&&a<=Math.floor(.2*r))?e.snapshot.nodes.some(e=>!0===e.hittable||!!e.label?.trim()||!!e.value?.trim()||!!e.identifier?.trim())?null:"sharp-drop":t.routeComparable&&ub(t.action)&&function(e,t){if(!e||0===e.length)return!1;let n=Math.max(e.length,t.length);if(n<12)return!1;let r=uv(t),a=Math.min(e.length,r.length),i=0;for(let t=0;t<a;t+=1)e[t]===r[t]&&(i+=1);let o=Math.max(0,r.length-e.length),s=Math.max(0,e.length-r.length),l=Math.max(3,Math.floor(.15*n));return i>=Math.floor(.9*n)&&o<=l&&s<=l}(t.baselineSignatures,e.snapshot.nodes)?"stuck-route":null}function uk(e,t){let n=e?.nodes??[],r=function(e){let t=new Map;for(let[n,r]of e.entries())t.set(r.index,n);let n=[],r=[];for(let[a,i]of e.entries()){let e=Math.max(0,i.depth??0);for(;r.length>0&&e<=r[r.length-1].depth;)r.pop();let o="number"==typeof i.parentIndex?t.get(i.parentIndex):void 0,s="number"==typeof o&&o<a?o:r[r.length-1]?.index;n.push({...i,index:a,depth:e,parentIndex:s}),r.push({depth:e,index:a})}return n}(t?.snapshotRaw?n:_(n));return{nodes:q(t?.snapshotScope&&e?.backend!=="macos-helper"?uD(r,t.snapshotScope):r),truncated:e?.truncated,createdAt:Date.now(),backend:e?.backend,comparisonSafe:e?.backend==="android"&&t?.snapshotInteractiveOnly!==!0&&t?.snapshotCompact!==!0&&"number"!=typeof t?.snapshotDepth&&!t?.snapshotScope}}function uM(e,t){var n,r;let a=e.nodes??[];return t.snapshotScope&&(a=uD(a,t.snapshotScope)),t.snapshotInteractiveOnly&&(a=function(e){if(0===e.length)return e;let t=new Map;for(let n of e)t.set(n.index,n);let n=new Set;for(let r of e){if(!function(e){if(e.hittable||e.rect)return!0;let t=`${e.type??""} ${e.role??""} ${e.subrole??""}`.toLowerCase();return t.includes("button")||t.includes("menu")||t.includes("textfield")||t.includes("searchfield")||t.includes("checkbox")||t.includes("radio")||t.includes("switch")}(r))continue;let e=r;for(;e&&!n.has(e.index);)n.add(e.index),e="number"==typeof e.parentIndex?t.get(e.parentIndex):void 0}return 0===n.size?e:uE(e.filter(e=>n.has(e.index)))}(a)),"number"==typeof t.snapshotDepth&&(n=a,r=t.snapshotDepth,a=uE(n.filter(e=>(e.depth??0)<=r))),{...e,nodes:a}}function uD(e,t){let n=C(q(e),t);if(!n)return[];let r=e.findIndex(e=>e.index===n.index);if(-1===r)return[];let a=e[r]?.depth??0,i=[];for(let t=r;t<e.length;t+=1){let n=e[t];if(!n)continue;let o=n.depth??0;if(t>r&&o<=a)break;i.push(n)}return uE(i,a)}function uE(e,t=0){let n=new Map;for(let[t,r]of e.entries())n.set(r.index,t);return e.map((e,r)=>({...e,index:r,depth:Math.max(0,(e.depth??0)-t),parentIndex:"number"==typeof e.parentIndex?n.get(e.parentIndex):void 0}))}function uO(e,t){let n;if(!e||!e.trim().startsWith("@"))return{ok:!0,scope:e};if(!t?.snapshot)return aw("INVALID_ARGS","Ref scope requires an existing snapshot in session.");let r=j(e.trim());if(!r)return aw("INVALID_ARGS",`Invalid ref scope: ${e}`);for(let e of[t.snapshot,...t.snapshotScopeSource?[t.snapshotScopeSource]:[]]){let t=V(e.nodes,r);if(n=t?R(t,e.nodes):void 0)break}return n?{ok:!0,scope:n}:aw("COMMAND_FAILED",`Ref ${e} not found or has no label`)}async function uC(e){let{req:t,sessionName:n,logPath:r,sessionStore:a}=e,{session:i,device:o}=await us(a,n,t.flags);if(!aD("snapshot",o))return aw("UNSUPPORTED_OPERATION","snapshot is not supported on this device");let s=uO(t.flags?.snapshotScope,i);return s.ok?await ul(i,o,async()=>{let e=uP({req:t,sessionName:n,logPath:r,sessionStore:a,session:i,device:o,snapshotScope:s.scope}),l=await e.capture.snapshot({session:n,interactiveOnly:t.flags?.snapshotInteractiveOnly,compact:t.flags?.snapshotCompact,depth:t.flags?.snapshotDepth,scope:s.scope,raw:t.flags?.snapshotRaw});return uT({req:t,sessionName:n,sessionStore:a,result:{nodes:l.nodes.length,truncated:l.truncated}}),{ok:!0,data:l}}):s}async function uR(e){let{req:t,sessionName:n,logPath:r,sessionStore:a}=e,{session:i,device:o}=await us(a,n,t.flags);if(!aD("diff",o))return aw("UNSUPPORTED_OPERATION","diff is not supported on this device");let s=uO(t.flags?.snapshotScope,i);return s.ok?await ul(i,o,async()=>{let e=uP({req:t,sessionName:n,logPath:r,sessionStore:a,session:i,device:o,snapshotScope:s.scope}),l=await e.capture.diffSnapshot({session:n,interactiveOnly:t.flags?.snapshotInteractiveOnly,compact:t.flags?.snapshotCompact,depth:t.flags?.snapshotDepth,scope:s.scope,raw:t.flags?.snapshotRaw});return uT({req:t,sessionName:n,sessionStore:a,result:{mode:"snapshot",baselineInitialized:l.baselineInitialized,summary:l.summary}}),{ok:!0,data:l}}):s}function uP(e){let{req:t,sessionName:n,logPath:r,sessionStore:a,session:i,device:o,snapshotScope:s}=e;return af({backend:function(e){let{req:t,logPath:n,session:r,device:a,snapshotScope:i}=e;return{platform:a.platform,captureSnapshot:async(e,o)=>{let s=await uI({device:a,session:r,flags:t.flags,outPath:o?.outPath??t.flags?.out,logPath:n,snapshotScope:i});return{snapshot:s.snapshot,analysis:s.analysis,androidSnapshot:s.androidSnapshot,freshness:s.freshness,appName:r?.appBundleId?r.appName??r.appBundleId:void 0,appBundleId:r?.appBundleId}}}}({req:t,logPath:r,session:i,device:o,snapshotScope:s}),artifacts:uh("snapshot"),sessions:{get:e=>e===n?function(e){if(e)return{name:e.name,appBundleId:e.appBundleId,appName:e.appName,snapshot:e.snapshot,metadata:{surface:e.surface}}}(a.get(n)):void 0,set:e=>{var r;if(!e.snapshot)throw new y("UNKNOWN","snapshot runtime did not produce session state");let i=a.get(n);a.set(n,function(e){var t,n;let{current:r,sessionName:a,device:i,record:o,refScopedSnapshot:s}=e;if(!o.snapshot)throw new y("UNKNOWN","snapshot runtime did not produce session state");let l=(t=r,n=o,s&&n.snapshot?.nodes.length===0&&t?.snapshot!==void 0),d=l?r.snapshot:o.snapshot,u=function(e){let{session:t,sessionName:n,device:r,snapshot:a,appBundleId:i}=e;return t?{...t,snapshot:a}:{name:n,device:r,createdAt:Date.now(),appBundleId:i,snapshot:a,actions:[]}}({session:r,sessionName:a,device:i,snapshot:d,appBundleId:o.appBundleId});return u.snapshotScopeSource=function(e){let{current:t,keepCurrentSnapshot:n,refScopedSnapshot:r}=e;if(r)return n?t?.snapshotScopeSource:t?.snapshotScopeSource??t?.snapshot}({current:r,keepCurrentSnapshot:l,refScopedSnapshot:s}),o.appName&&(u.appName=o.appName),u}({current:i,sessionName:n,device:o,record:e,refScopedSnapshot:(r=t,r.flags?.snapshotScope?.trim().startsWith("@")===!0)}))}},policy:am()})}function uT(e){let t=e.sessionStore.get(e.sessionName);t&&e.sessionStore.recordAction(t,{command:e.req.command,positionals:e.req.positionals??[],flags:e.req.flags??{},result:e.result})}async function uL(e){let{device:t,node:n,flags:r,appBundleId:a,traceOutPath:i,surface:o,contextFromFlags:s}=e,l=E(n),d=nF(n.rect);if(!d)return l;try{let e=await dY(t,"read",[String(d.x),String(d.y)],void 0,{...s(r,a,i),surface:o}),u=e&&"object"==typeof e?e:void 0,c="string"==typeof u?.text?u.text:"";if(c.trim())return c;return eH({level:"warn",phase:"interaction_read_fallback",data:{reason:"empty_backend_text",nodeRef:n.ref,surface:o,platform:t.platform}}),l}catch(e){return eH({level:"warn",phase:"interaction_read_fallback",data:{reason:"backend_read_failed",nodeRef:n.ref,surface:o,platform:t.platform,error:e instanceof Error?e.message:String(e)}}),l}}let u$=[["snapshotDepth","--depth"],["snapshotScope","--scope"],["snapshotRaw","--raw"]];function uF(e,t){let n=function(e){if(!e)return[];let t=[];for(let[n,r]of u$)void 0!==e[n]&&t.push(r);return t}(t);return 0===n.length?null:aw("INVALID_ARGS",`${e} @ref does not support ${n.join(", ")}.`)}function uU(e,t){e.snapshot=t,e.snapshotScopeSource=void 0}async function uG(e,t){let n=await uV(e);if(n)throw new y("COMMAND_FAILED",`press ${t} left ${e.appBundleId} and foregrounded ${n.foregroundPackage}. The tap likely escaped the app.`,n)}async function uV(e){var t;if("android"!==e.device.platform||!e.appBundleId)return null;let n=await eO(e.device),r=n.package?.trim();return r&&r!==e.appBundleId&&("com.android.settings"===(t=r)||"com.android.systemui"===t||"com.google.android.permissioncontroller"===t||t.includes("launcher"))?{expectedPackage:e.appBundleId,foregroundPackage:r,activity:n.activity,hint:"com.google.android.permissioncontroller"===r?"Dismiss or allow the permission prompt, then retry the smoke assertion.":"Use screenshot as visual truth, then take a fresh snapshot -i before retrying."}:null}function uB(e){return"COMMAND_FAILED"===e.code&&"string"==typeof e.details?.expectedPackage&&"string"==typeof e.details?.foregroundPackage}function uj(e,t,n,r){let a=e.get(t);a&&e.recordAction(a,{command:n.command,positionals:n.positionals??[],flags:n.flags??{},result:r})}function uq(e){let t=e.target;return t&&"object"==typeof t?"ref"===t.kind&&"string"==typeof t.ref?{kind:"ref",ref:t.ref}:"selector"===t.kind&&"string"==typeof t.selector?{kind:"selector",selector:t.selector}:void 0:void 0}function uX(e){return e.startsWith("@")?e.slice(1):e}async function uH(e){var t;let{req:n}=e;if("find"!==n.command)return null;let r=n.positionals??[];if(0===r.length)return aw("INVALID_ARGS","find requires a locator or text");let a=ef(r);if(!a.query)return aw("INVALID_ARGS","find requires a value");if(n.flags?.findFirst&&n.flags?.findLast)return aw("INVALID_ARGS","find accepts only one of --first or --last");let i=a.action;if("exists"!==(t=i)&&"wait"!==t&&"get_text"!==t&&"get_attrs"!==t)return null;let o=await uJ(e,{requireSession:!1,capability:"find"});return o.ok?await u0(async()=>{let t=await o.runtime.selectors.find({session:e.sessionName,requestId:n.meta?.requestId,locator:a.locator,query:a.query,action:i,timeoutMs:a.timeoutMs});return uj(e.sessionStore,e.sessionName,n,function(e,t){if("exists"===t)return{found:!0};if("wait"===t)return{found:!0,waitedMs:e.waitedMs};let n="string"==typeof e.ref?e.ref:void 0;return"get_attrs"===t?{ref:n,action:"get attrs"}:{ref:n,action:"get text",text:"string"==typeof e.text?e.text:""}}(t,i)),"found"===t.kind?{found:!0,..."number"==typeof t.waitedMs?{waitedMs:t.waitedMs}:{}}:{..."string"==typeof t.ref?{ref:t.ref}:{},..."string"==typeof t.text?{text:t.text}:{},...t.node&&"object"==typeof t.node?{node:t.node}:{}}}):o.response}async function uK(e){let{req:t}=e;if("get"!==t.command)return null;let n=t.positionals?.[0];if("text"!==n&&"attrs"!==n)return aw("INVALID_ARGS","get only supports text or attrs");let r=await uJ(e,{requireSession:!0,capability:"get"});if(!r.ok)return r.response;let a=function(e){let t=e.positionals?.[1]??"";if(t.startsWith("@"))return{ok:!0,target:{kind:"ref",ref:t,fallbackLabel:e.positionals.length>2?e.positionals.slice(2).join(" ").trim():""}};let n=e.positionals?.slice(1).join(" ").trim()??"";return n?{ok:!0,target:{kind:"selector",selector:n}}:{ok:!1,response:aw("INVALID_ARGS","get requires @ref or selector expression")}}(t);if(!a.ok)return a.response;if("ref"===a.target.kind){let e=uF("get",t.flags);if(e)return e}return await u0(async()=>{let i,o=await r.runtime.selectors.get({session:e.sessionName,requestId:t.meta?.requestId,property:n,target:a.target});return uj(e.sessionStore,e.sessionName,t,function(e,t){let n=Array.isArray(e.selectorChain)?e.selectorChain:void 0,r=uq(e),a=r?.kind==="ref"?uX(r.ref):void 0,i=r?.kind==="selector"?r.selector:void 0,o={...a?{ref:a}:{},...i?{selector:i}:{},...n?{selectorChain:n}:{}};if("attrs"===t)return o;let s="string"==typeof e.text?e.text:"";return{...o,text:s,refLabel:function(e){let t=e.trim();if(!(!t||t.length>80||/[\r\n]/.test(t)))return t}(s)}}(o,n)),i=uq(o),{...i?.kind==="ref"?{ref:uX(i.ref)}:{},...i?.kind==="selector"?{selector:i.selector}:{},..."string"==typeof o.text?{text:o.text}:{},...o.node&&"object"==typeof o.node?{node:o.node}:{}}})}async function uz(e){let{req:t}=e;if("is"!==t.command)return null;let n=(t.positionals?.[0]??"").toLowerCase();if(!nb(n))return aw("INVALID_ARGS","is requires predicate: visible|hidden|exists|editable|selected|text");let{split:r}=O(t.positionals??[]);if(!r)return aw("INVALID_ARGS","is requires a selector expression");let a=r.rest.join(" ").trim();if("text"===n&&!a)return aw("INVALID_ARGS","is text requires expected text value");if("text"!==n&&r.rest.length>0)return aw("INVALID_ARGS",`is ${n} does not accept trailing values`);let i=await uJ(e,{requireSession:!0,capability:"is"});if(!i.ok)return i.response;let o=await u0(async()=>{let o=await i.runtime.selectors.is({session:e.sessionName,requestId:t.meta?.requestId,predicate:n,selector:r.selectorExpression,expectedText:a});return uj(e.sessionStore,e.sessionName,t,o),function(e){let{selectorChain:t,...n}=e;return n}(o)});return await u1(e,o,`is ${n}`)}async function uY(e){let{req:t,sessionName:n,sessionStore:r}=e,a=ay(t.positionals??[]);if(!a)return aw("INVALID_ARGS","wait requires a duration or text");let{session:i,device:o}=await us(r,n,t.flags);if("sleep"!==a.kind&&!aD("wait",o))return aw("UNSUPPORTED_OPERATION","wait is not supported on this device");let s=async()=>{let s=uW({...e,session:i,device:o}),l=await u0(async()=>{let e=await s.selectors.wait({session:n,requestId:t.meta?.requestId,target:function(e,t){if("sleep"===e.kind)return{kind:"sleep",durationMs:e.durationMs};if("selector"===e.kind)return{kind:"selector",selector:e.selectorExpression,timeoutMs:e.timeoutMs};if("ref"===e.kind){if(!t?.snapshot)throw new y("INVALID_ARGS","Ref wait requires an existing snapshot in session.");return{kind:"ref",ref:e.rawRef,timeoutMs:e.timeoutMs}}if(!e.text)throw new y("INVALID_ARGS","wait requires text");return{kind:"text",text:e.text,timeoutMs:e.timeoutMs}}(a,i)});return uj(r,n,t,e),{waitedMs:e.waitedMs,..."string"==typeof e.text?{text:e.text}:{},..."string"==typeof e.selector?{selector:e.selector}:{}}});return await u1(e,l,"wait")};return"sleep"===a.kind?await s():await ul(i,o,s)}function uW(e){return af({backend:function(e){let t,{req:n,session:r,device:a,logPath:i,sessionName:o,sessionStore:s}=e,l=0;return{platform:a.platform,captureSnapshot:async(e,d)=>{var u;let c,p={...n.flags,...(u=d,c={},u?.interactiveOnly!==void 0&&(c.snapshotInteractiveOnly=u.interactiveOnly),u?.compact!==void 0&&(c.snapshotCompact=u.compact),u?.scope!==void 0&&(c.snapshotScope=u.scope),u?.depth!==void 0&&(c.snapshotDepth=u.depth),u?.raw!==void 0&&(c.snapshotRaw=u.raw),c)},f=d?.scope??n.flags?.snapshotScope,h=Date.now();if(t&&h-l<750&&!ug(r))return t;let m=await uI({device:a,session:r,flags:p,outPath:n.flags?.out,logPath:i??"",snapshotScope:f});return r&&(uU(r,m.snapshot),s.set(o,r)),l=h,t={snapshot:m.snapshot}},readText:async(t,o)=>({text:await uL({device:a,node:o,flags:n.flags,appBundleId:r?.appBundleId,traceOutPath:r?.trace?.outPath,surface:r?.surface,contextFromFlags:e.contextFromFlags??((e,t,n)=>up(i??"",e,t,n))})}),findText:async(t,n)=>({found:await uZ(e,n)})}}(e),artifacts:uh("selector commands",{plural:!0}),sessions:{get:t=>t===e.sessionName?function(e){if(e)return{name:e.name,appName:e.appName,appBundleId:e.appBundleId,snapshot:e.snapshot,metadata:{surface:e.surface}}}(e.session):void 0,set:t=>{e.session&&t.snapshot&&(uU(e.session,t.snapshot),e.sessionStore.set(e.sessionName,e.session))}},policy:am()})}async function uJ(e,t){let n=e.sessionStore.get(e.sessionName);if(!n&&t.requireSession)return{ok:!1,response:aw("SESSION_NOT_FOUND","No active session. Run open first.")};let r=n?.device??await dj(e.req.flags??{});return(n||await un(r),aD(t.capability,r))?{ok:!0,runtime:uW({...e,session:n,device:r})}:{ok:!1,response:aw("UNSUPPORTED_OPERATION",`${t.capability} is not supported on this device`)}}async function uZ(e,t){let{device:n,session:r,req:a,logPath:i}=e;if("macos"===n.platform&&r?.surface&&"app"!==r.surface)return!!C((await uQ(e)).nodes,t);if(av(n.platform)){let e=await i4(n,{command:"findText",text:t,appBundleId:r?.appBundleId},{verbose:a.flags?.verbose,logPath:i,traceLogPath:r?.trace?.outPath,requestId:a.meta?.requestId});return e?.found===!0}return!!C((await uQ(e)).nodes,t)}async function uQ(e){let t=await uI({device:e.device,session:e.session,flags:{...e.req.flags,snapshotInteractiveOnly:!1,snapshotCompact:!1},outPath:e.req.flags?.out,logPath:e.logPath??""});return e.session&&(uU(e.session,t.snapshot),e.sessionStore.set(e.sessionName,e.session)),t.snapshot}async function u0(e){try{return{ok:!0,data:await e()}}catch(t){let e=w(t);return aw(e.code,e.message,e.details)}}async function u1(e,t,n){var r;let a;if(t.ok)return t;let i=e.sessionStore.get(e.sessionName);if(!i)return t;try{a=await uV(i)}catch{return t}return a?aw(t.error.code,`${n} failed because ${"com.google.android.permissioncontroller"===(r=a).foregroundPackage?`Android permission dialog is blocking ${r.expectedPackage}`:`${r.foregroundPackage} is foreground instead of ${r.expectedPackage}`}.`,{...t.error.details??{},...a,blockedBy:"android_foreground_surface",originalMessage:t.error.message}):t}let u2=new Set(["snapshot","diff","wait","alert","settings"]);async function u3(e){let{req:t,sessionName:n,logPath:r,sessionStore:a}=e,i=t.command;if(!u2.has(i))return null;if("snapshot"===i)return await uC({req:t,sessionName:n,logPath:r,sessionStore:a});if("diff"===i)return t.positionals?.[0]!=="snapshot"?aw("INVALID_ARGS","diff currently supports only: diff snapshot"):await uR({req:t,sessionName:n,logPath:r,sessionStore:a});if("wait"===i)return await uY({req:t,sessionName:n,logPath:r,sessionStore:a});if("alert"===i){let{session:e,device:i}=await us(a,n,t.flags);return await ul(e,i,async()=>await uu({req:t,logPath:r,sessionStore:a,session:e,device:i}))}if("settings"===i){let e,i,o,s=(e=t.positionals?.[0]?.toLowerCase(),i=t.positionals?.[1]?.toLowerCase(),o=t.positionals?.[2]?.toLowerCase(),e&&i&&("permission"!==e||o)?{ok:!0,parsed:{setting:e,state:i,permissionTarget:o}}:aw("INVALID_ARGS",e9));if(!s.ok)return s;let{session:l,device:d}=await us(a,n,t.flags);return await ul(l,d,async()=>await uf({req:t,logPath:r,sessionStore:a,session:l,device:d,parsed:s.parsed}))}return null}export{closeAndroidApp,dismissAndroidKeyboard,ensureAdb,getAndroidAppState,getAndroidKeyboardState,inferAndroidAppName,installAndroidApp,installAndroidInstallablePathAndResolvePackageName,listAndroidApps,openAndroidApp,openAndroidDevice,readAndroidClipboardText,reinstallAndroidApp,resolveAndroidApp,writeAndroidClipboardText}from"./8809.js";export{sy as IOS_DEVICECTL_DEFAULT_HINT,iS as IOS_RUNNER_CONTAINER_BUNDLE_IDS,sl as IOS_SIMCTL_LIST_TIMEOUT_MS,te as SESSION_SURFACES,e6 as SETTINGS_USAGE_OVERRIDE,iZ as abortAllIosRunnerSessions,o$ as appSwitcherAndroid,uG as assertAndroidPressStayedInApp,oP as backAndroid,th as buildMobileSnapshotPresentation,og as buildScrollGesturePlan,aB as buildSimctlArgs,aj as buildSimctlArgsForDevice,tr as buildSnapshotDisplayLines,uk as buildSnapshotState,dp as buttonTag,uI as captureSnapshot,uA as captureSnapshotData,a$ as clearRequestCanceled,lw as closeIosApp,up as context_contextFromFlags,af as createAgentDevice,aG as createRequestCanceledError,uh as createUnsupportedArtifactAdapter,tv as decodePng,dY as dispatchCommand,uH as dispatchFindReadOnlyViaRuntime,uK as dispatchGetViaRuntime,uz as dispatchIsViaRuntime,tu as displayNodeLabel,un as ensureDeviceReady,aw as errorResponse,oB as fillAndroid,dR as findBootableIosSimulator,oV as focusAndroid,ta as formatSnapshotLine,ug as getActiveAndroidSnapshotFreshness,oH as getAndroidScreenSize,dc as getClickButtonValidationError,aU as getRequestSignal,iz as getRunnerSessionSnapshot,u3 as handleSnapshotCommands,oT as homeAndroid,ly as installIosApp,lv as installIosInstallablePath,uB as isAndroidEscapeError,av as isApplePlatform,aD as isCommandSupportedOnDevice,ub as isNavigationSensitiveAction,aF as isRequestCanceled,dF as listAppleDevices,lN as listIosApps,sw as listIosDeviceApps,sg as listIosDeviceProcesses,am as localCommandPolicy,oF as longPressAndroid,uw as markAndroidSnapshotFreshness,aL as markRequestCanceled,aI as matchesPlatformSelector,ab as normalizePlatformSelector,lh as openIosApp,lm as openIosDevice,db as parseDeviceRotation,tt as parseSessionSurface,ay as parseWaitArgs,iu as parseXmlDocumentSync,sM as prepareIosInstallArtifact,oC as pressAndroid,st as pushAndroidNotification,lx as pushIosNotification,oJ as readAndroidTextAtPoint,sk as readInfoPlistString,lI as readIosClipboardText,uL as readTextForNode,uF as refSnapshotFlagGuardResponse,aT as registerRequestAbort,lb as reinstallIosApp,aA as resolveAppleSimulatorSetPathForSelector,du as resolveClickButton,od as resolveFrontmostMacOsApp,lf as resolveIosApp,sb as resolveIosDevicectlHint,dw as resolvePayloadInput,aP as resolveRequestTrackingId,dj as resolveTargetDevice,oL as rotateAndroid,i4 as runIosRunnerCommand,op as runMacOsAlertAction,sr as screenshotAndroid,s8 as screenshotIos,oX as scrollAndroid,o5 as setAndroidSetting,lS as setIosSetting,uU as setSessionSnapshot,sN as shutdownSimulator,sS as ensureBootedSimulator,oI as snapshotAndroid,iQ as stopAllIosRunnerSessions,iJ as stopIosRunnerSession,oR as swipeAndroid,oU as typeAndroid,io as withKeyedLock,dH as withTargetDeviceResolutionScope,lA as writeIosClipboardText};
|