agent-device 0.14.0 → 0.14.2

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/dist/src/3918.js DELETED
@@ -1,33 +0,0 @@
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 A,tryParseSelectorChain as I,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 X,ensureAndroidSnapshotHelper as z,parseUiHierarchyTree as W,readNodeAttributes as H,captureAndroidSnapshotWithHelper as Y,parseBounds as K,isScrollableNodeLike as J,parseAndroidSnapshotHelperManifest as Z,isScrollableType as Q,buildUiHierarchySnapshot as ee}from"./221.js";import{readVersion as et,findProjectRoot as en,getDiagnosticsMeta as ea,successText as er,withDiagnosticTimer as ei,withSuccessText as eo,emitDiagnostic as es}from"./8161.js";import{runCmdStreaming as el,runCmdDetached as ed,runCmdBackground as eu,runCmdSync as ec,runCmd as ep,resolveFileOverridePath as ef,whichCmd as eh,resolveExecutableOverridePath as em}from"./9818.js";import{findBestMatchesByLocator as ew,parseFindArgs as eg}from"./7556.js";import"./7847.js";import{sleep as ey,resolveTimeoutMs as eb,resolveTimeoutSeconds as ev}from"./4829.js";import{isProcessAlive as eA,readProcessStartTime as eI}from"./8656.js";import{ensureAndroidSdkPathConfigured as ex,resolveAndroidArchivePackageName as eS}from"./7651.js";import{materializeInstallablePath as eN,isTrustedInstallSourceUrl as e_}from"./989.js";import{parseAndroidForegroundApp as eM,parseAndroidLaunchablePackages as ek,parseAndroidUserInstalledPackages as eD}from"./9366.js";var eE={};t.r(eE),t.d(eE,{ensureAndroidEmulatorBooted:()=>oV,listAndroidDevices:()=>oT,waitForAndroidBoot:()=>oB});var eO={};t.r(eO),t.d(eO,{TM:()=>db,ensureBootedSimulator:()=>lE,installIosApp:()=>dA,installIosInstallablePath:()=>dx,listIosApps:()=>dk,L5:()=>dg,IJ:()=>dy,TJ:()=>d_,J7:()=>dS,reinstallIosApp:()=>dI,resolveIosApp:()=>dw,kc:()=>de,Cm:()=>dM,ap:()=>dN});let eC="<wifi|airplane|location> <on|off>",eR="animations <on|off>",eP="appearance <light|dark|toggle>",eT="faceid <match|nonmatch|enroll|unenroll>",eL="touchid <match|nonmatch|enroll|unenroll>",e$="fingerprint <match|nonmatch>",eF="permission <grant|deny|reset> <camera|microphone|photos|contacts|contacts-limited|notifications|calendar|location|location-always|media-library|motion|reminders|siri> [full|limited]",eU="permission <grant|reset> <accessibility|screen-recording|input-monitoring>",eG=`macOS supports only settings ${eP} and settings ${eU}. wifi|airplane|location|animations remain unsupported on macOS.`,eV=`settings ${eC} | settings ${eR} | settings ${eP} | settings ${eT} | settings ${eL} | settings ${e$} | settings ${eF} | settings ${eU}`,eB=`settings requires ${eC}, ${eR}, ${eP}, ${eT}, ${eL}, ${e$}, ${eF}, or ${eU}`;function ej(e){return`Unsupported macOS setting: ${e}. ${eG}`}let eq=["app","frontmost-app","desktop","menubar"];function eX(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 ${eq.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 eW(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=eK(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:eH(r,s,!1,o,t)})}return a}function eH(e,t,n,a,r={}){var i,o,s,l,d,u,c,p;let f,h=a??eK(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&&!eZ(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)||eY(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"),eJ(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(""),A=w?` "${w}"`:"";return n?`${g}${y} [${h}]${b}`.trimEnd():`${g}${y} [${h}]${A}${b}`.trimEnd()}function eY(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(eJ(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||eZ(s)&&("group"===t||"image"===t||"list"===t||"collection"===t)?"":s}function eK(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 eJ(e){return"text-field"===e||"text-view"===e||"search"===e}function eZ(e){return/^[\w.]+:id\/[\w.-]+$/i.test(e)}function eQ(e){return new Map(e.map(e=>[e.index,e]))}function e0(e){return e.label?.trim()||e.value?.trim()||e.identifier?.trim()||""}function e1(e,t,n){return t>=e.x&&t<=e.x+e.width&&n>=e.y&&n<=e.y+e.height}function e2(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 e3(e,t,n,a){return Math.max(e,n)<=Math.min(t,a)}function e4(e){if(0===e.length)return{nodes:e,hiddenCount:0,summaryLines:[]};let{byIndex:t,visibleNodeIndexes:n,offscreenNodes:a,hintedContainers:r}=e5(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=e6(e,t,n);return a?e9(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=e0(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")||!!e0(e)}(e)),e,t)}}function e5(e){let t=eQ(e),n=new Set,a=[];for(let r of e){if(e8(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=e7(e,n,a);if(!t?.rect)continue;let o=e9(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=e7(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 e8(e,t,n=eQ(t)){var a;if(!e.rect)return!0;let r=e6(e,t,n);return!r||(a=e.rect,e3(a.x,a.x+a.width,r.x,r.x+r.width)&&e3(a.y,a.y+a.height,r.y,r.y+r.height))}function e6(e,t,n=eQ(t)){let a=function(e,t){let n="number"==typeof e.parentIndex?t.get(e.parentIndex):void 0,a=new Set;for(;n&&!a.has(n.index);){if(a.add(n.index),n.rect&&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=e2(r.map(e=>e.rect).filter(e=>e1(e,n.x,n.y)));if(i)return i;let o=e2(r.map(e=>e.rect));if(o)return o;let s=e2(a.map(e=>e.rect).filter(e=>e1(e,n.x,n.y)));return s||null}(t,e.rect??{x:0,y:0,width:0,height:0})}function e9(e,t){return e.y+e.height<=t.y?"above":e.y>=t.y+t.height?"below":null}function e7(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}let te=100,tt=new Set(["batch","replay"]),tn=new Set(["command","positionals","flags","runtime"]);function ta(e){let t;try{t=JSON.parse(e)}catch{throw new y("INVALID_ARGS","Batch steps must be valid JSON.")}if(!Array.isArray(t)||0===t.length)throw new y("INVALID_ARGS","Batch steps must be a non-empty JSON array.");return t}function tr(e,t){if(!Array.isArray(e)||0===e.length)throw new y("INVALID_ARGS","batch requires a non-empty batchSteps array.");if(e.length>t)throw new y("INVALID_ARGS",`batch has ${e.length} steps; max allowed is ${t}.`);let n=[];for(let t=0;t<e.length;t+=1){let a=e[t];if(!a||"object"!=typeof a)throw new y("INVALID_ARGS",`Invalid batch step at index ${t}.`);let r=Object.keys(a).filter(e=>!tn.has(e));if(r.length>0){let e=r.map(e=>`"${e}"`).join(", ");throw new y("INVALID_ARGS",`Batch step ${t+1} has unknown field(s): ${e}. Allowed fields: command, positionals, flags, runtime.`)}let i="string"==typeof a.command?a.command.trim().toLowerCase():"";if(!i)throw new y("INVALID_ARGS",`Batch step ${t+1} requires command.`);if(tt.has(i))throw new y("INVALID_ARGS",`Batch step ${t+1} cannot run ${i}.`);if(void 0!==a.positionals&&!Array.isArray(a.positionals))throw new y("INVALID_ARGS",`Batch step ${t+1} positionals must be an array.`);let o=a.positionals??[];if(o.some(e=>"string"!=typeof e))throw new y("INVALID_ARGS",`Batch step ${t+1} positionals must contain only strings.`);if(void 0!==a.flags&&("object"!=typeof a.flags||Array.isArray(a.flags)||!a.flags))throw new y("INVALID_ARGS",`Batch step ${t+1} flags must be an object.`);if(void 0!==a.runtime&&("object"!=typeof a.runtime||Array.isArray(a.runtime)||!a.runtime))throw new y("INVALID_ARGS",`Batch step ${t+1} runtime must be an object.`);n.push({command:i,positionals:o,flags:a.flags??{},runtime:a.runtime})}return n}function ti(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 to(e,t){if(!Number.isInteger(t)||t<1)throw new y("INVALID_ARGS","Screenshot max size must be a positive integer");let n=ti(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 ts(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 tl(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 td(e,t){try{return await e.artifacts.createTempFile(t)}catch(e){throw w(e)}}let tu=[0,187,255,255];function tc(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 tp(e,t,n){return Math.min(Math.max(e,t),n)}let tf={icon:90,toggle:90,chevron:75,separator:45,visual:35,background:10},th={leading:20,trailing:20,separator:10,unknown:0,background:-30};function tm(e){return"background"!==e.likelyKind}function tw(e,t){return e.width>=.25*t.width||e.height>=.06*t.height}function tg(e,t){let n,a=0;for(let r of t){let t=tI(e,r.rect);t<=a||(a=t,n=r)}return n}function ty(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,tI(t,a=n.rect)>0||Math.abs(tx(t).y-tx(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 tb(e,t){let n,a=tx(e);for(let e of t){var r,i;let t=Math.sqrt((r=a,i=tx(e.rect),(r.x-i.x)**2+(r.y-i.y)**2));n&&t>=n.distance||(n={block:e,distance:t})}return n}function tv(e){let t=tA(e);return e.differentPixels>=24&&t.width>=3&&t.height>=3}function tA(e){return{x:e.minX,y:e.minY,width:e.maxX-e.minX+1,height:e.maxY-e.minY+1}}function tI(e,t){return Math.max(0,Math.min(e.y+e.height,t.y+t.height)-Math.max(e.y,t.y))}function tx(e){return{x:e.x+e.width/2,y:e.y+e.height/2}}function tS(e,t,n){return Math.min(Math.max(e,t),n)}async function tN(e){if(await eh("tesseract"))try{let[t,n]=await Promise.all([tM(e.baselinePath),tM(e.currentPath)]);if(0!==t.exitCode||0!==n.exitCode)return;let a=t_(t.stdout,e.width,e.height),r=t_(n.stdout,e.width,e.height),i=function(e,t){let n=new Set,a=[];for(let i of e){var r;let e=tP(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(tP(d.text)!==t)continue;let u=(o=tO(e.normalizedRect),s=tO(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=t$(t.rect.width/e.rect.width),r=t$(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)=>tk(t)-tk(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-tT(e.map(e=>e.delta.x))));e?e.push(n):t.push([n])}return t.filter(e=>e.length>=2).map(tD).filter(e=>e.yRange.max-e.yRange.min<=60).sort((e,t)=>tE(t)-tE(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 t_(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=tR(t,i,"level"),a=tC(t,i,"text").trim(),r=tR(t,i,"conf");if(5!==n||(s=a,!/[\p{L}\p{N}]/u.test(s))||r<0)continue;let l=tR(t,i,"left"),d=tR(t,i,"top"),u=tR(t,i,"width"),c=tR(t,i,"height");u<=0||c<=0||o.push({key:[tC(t,i,"page_num"),tC(t,i,"block_num"),tC(t,i,"par_num"),tC(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*tT(a.map(e=>e.confidence)))/100;return{text:a.map(e=>e.text).join(" "),confidence:i,rect:r,normalizedRect:{x:tL(r.x/t),y:tL(r.y/n),width:tL(r.width/t),height:tL(r.height/n)}}})(e,t,n)).filter(e=>null!==e)}function tM(e){return ep("tesseract",[e,"stdout","-l","eng","tsv"],{allowFailure:!0,timeoutMs:1e4})}function tk(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 tD(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 tE(e){return 2*Math.abs((e.xRange.min+e.xRange.max)/2)+Math.abs((e.yRange.min+e.yRange.max)/2)}function tO(e){return{x:e.x+e.width/2,y:e.y+e.height/2}}function tC(e,t,n){let a=t.get(n);return void 0===a?"":e[a]??""}function tR(e,t,n){let a=Number(tC(e,t,n));return Number.isFinite(a)?a:0}function tP(e){return e.trim().replace(/\s+/g," ").toLowerCase()}function tT(e){return e.reduce((e,t)=>e+t,0)/e.length}function tL(e){return Math.round(100*e*100)/100}function t$(e){return Math.round(1e3*e)/1e3}function tF(e,t,n,a){return{r:Math.round(e/a),g:Math.round(t/a),b:Math.round(n/a)}}function tU(e){return .2126*e.r+.7152*e.g+.0722*e.b}function tG(e){return`#${tV(e.r)}${tV(e.g)}${tV(e.b)}`}function tV(e){return e.toString(16).padStart(2,"0")}function tB(e){return Math.round(100*e*100)/100}let tj=255*Math.sqrt(3);async function tq(e,t,n={}){let a,s,l,d;await tX(e,"Baseline image not found"),await tX(t,"Current screenshot not found");let u=n.outputPath,[c,p]=await Promise.all([r.readFile(e),r.readFile(t)]),f=ti(c,"baseline screenshot"),h=ti(p,"current screenshot");tz(f.width,f.height,"baseline screenshot",n.maxPixels),tz(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 tW(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*tj,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=tH(h,e);y.data[e]=tY(n,220,.78),y.data[e+1]=tY(n,0,.78),y.data[e+2]=tY(n,0,.78),y.data[e+3]=255;continue}let n=tH(h,e);y.data[e]=n,y.data[e+1]=n,y.data[e+2]=n,y.data[e+3]=255}let A=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}(I={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=I.baseline.width,a=I.baseline.height,r=t.maxX-t.minX+1,t.maxY-t.minY+1>=Math.max(48,Math.round(.07*a))&&r>=.35*n)?function(e,t,n){var a;let r=function(e,t){let n=[],a=null;for(let r=0;r<e.length;r+=1){if(e[r]<=t){a??=r;continue}null!==a&&(r-a>=6&&n.push([a,r-1]),a=null)}return null!==a&&e.length-a>=6&&n.push([a,e.length-1]),n}((a=function(e,t,n){let a=[];for(let r=e.minY;r<=e.maxY;r+=1){let i=0;for(let a=e.minX;a<=e.maxX;a+=1)1===t[r*n+a]&&(i+=1);a.push(i)}return a}(e,t.diffMask,t.baseline.width)).map((e,t)=>{let n=0,r=0,i=Math.max(0,t-3),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,I,Math.max(24,Math.round(.03*I.baseline.height))):[e]})).sort((e,t)=>{let n=t.differentPixels-e.differentPixels;if(0!==n)return n;let a=e.minY-t.minY;return 0!==a?a:e.minX-t.minX}).slice(0,Math.max(0,I.maxRegions??8)).map((e,t)=>{var n,a,r,i,o,s,l,d,u,c,p;let f,h,m,w,g,y,b,v,A,x,S,N,_,M,k,D,E;return n=e,a=t+1,r={width:I.baseline.width,height:I.baseline.height,totalPixels:I.totalPixels,differentPixels:I.differentPixels},y={x:n.minX,y:n.minY,width:n.maxX-n.minX+1,height:n.maxY-n.minY+1},b={x:Math.round(n.minX+y.width/2),y:Math.round(n.minY+y.height/2)},v=tF(n.baselineRed,n.baselineGreen,n.baselineBlue,n.differentPixels),A=tF(n.currentRed,n.currentGreen,n.currentBlue,n.differentPixels),x=y.width*y.height,S=tB(n.differentPixels/x),N=Math.round(tU(v)),_=Math.round(tU(A)),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=A,h=tU(l),Math.abs(m=tU(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:tB(y.x/r.width),y:tB(y.y/r.height),width:tB(y.width/r.width),height:tB(y.height/r.height)},differentPixels:n.differentPixels,shareOfDiffPercentage:tB(n.differentPixels/r.differentPixels),densityPercentage:S,shape:M,size:k,location:E,averageBaselineColorHex:tG(v),averageCurrentColorHex:tG(A),baselineLuminance:N,currentLuminance:_,dominantChange:D}}):[];if(v>0&&u){var I,x,S;for(let e of A)e.rect.width<4||e.rect.height<4||function(e,t){let n=tp(t.x,0,e.width-1),a=tp(t.y,0,e.height-1),r=tp(t.x+t.width-1,0,e.width-1),i=tp(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)tc(e,o,a+t,tu),tc(e,o,i-t,tu);for(let o=a;o<=i;o+=1)tc(e,n+t,o,tu),tc(e,r-t,o,tu)}}(y,e.rect);await r.mkdir(o.dirname(u),{recursive:!0}),await r.writeFile(u,i.sync.write(y))}else await tW(n.outputPath);let N=v>0?await tN({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=tS(Math.floor(a.x),0,t-1),i=tS(Math.floor(a.y),0,n-1),o=tS(Math.ceil(a.x+a.width),0,t),s=tS(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:A,ocr:N}).diffMask,S.width,S.height,S.ocr),S.width,S.height)),l=ty(S.ocr?.currentBlocksRaw??[]),d=ty(S.ocr?.baselineBlocksRaw??[]),s.filter(tv).map(e=>{var t,n,a,r,i,o,s,u,c,p,f;let h,m,w,g,y,b,v,A,I,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=tA(t),n.regions),y=function(e,t,n){let a=tg(e,t);if(a)return tb(e,a.blocks);let r=tg(e,n);return r?tb(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":tw(i,u)?"background":"visual"),A={...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=A,p=t.differentPixels,f=n,I=tw(c.rect,f)?-35:0,x=20*!!c.regionIndex,tf[c.likelyKind]+th[c.slot]+x+I+Math.min(20,p/200))}}).filter(e=>e.rect.y>=.08*S.height).filter(tm).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}:{},...A.length>0?{regions:A}:{},..._?{ocr:_}:{},...M.length>0?{nonTextDeltas:M}:{},totalPixels:w,differentPixels:v,mismatchPercentage:k,match:0===v}}async function tX(e,t){try{await r.access(e)}catch{throw new y("INVALID_ARGS",`${t}: ${e}`)}}function tz(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 tW(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 tH(e,t){return tY(Math.round(.299*e.data[t]+.587*e.data[t+1]+.114*e.data[t+2]),255,.72)}function tY(e,t,n){return Math.round(e*(1-n)+t*n)}function tK(e){return e.width*e.height}function tJ(e){return Math.round(100*e*100)/100}async function tZ(e,t){let n=await td(e,{prefix:"agent-device-diff-current",ext:".png"});try{await t0(e,t,n.path,t1(t))}catch(e){throw await n.cleanup(),e}return n}async function tQ(e,t,n,a,r){var i,o,s,l;if(!t.overlayRefs)return a;if(a.match||a.dimensionMismatch)return n&&await t3(n),a;let d=(i=t,o=n,i.currentOverlayOut?i.currentOverlayOut:i.out?.kind==="path"?{kind:"path",path:t2(o??i.out.path)}:i.out?.kind==="downloadableArtifact"?{kind:"downloadableArtifact",...i.out.clientPath?{clientPath:t2(i.out.clientPath)}:{},...i.out.fileName?{fileName:t2(i.out.fileName)}:{}}:void 0),u=await tl(e,d,{field:"currentOverlayPath",ext:".png"});try{let n=await t0(e,t,u.path,{overlayRefs:!0,...t1(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=tK(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:tJ(u/tK(d)),regionCoveragePercentage:tJ(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 t0(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 t1(e){return e.surface?{surface:e.surface}:{}}function t2(e){let t=o.extname(e),n=t?e.slice(0,-t.length):e;return`${n}.current-overlay${t||".png"}`}async function t3(e){try{await r.unlink(t2(e))}catch(e){var t;if(!("object"==typeof(t=e)&&null!==t&&"code"in t&&"ENOENT"===t.code))throw e}}function t4(e){return"live"===e.kind}function t5(e,t){let n=eK(e.type??"Element"),a=eY(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 t8(e,t){return t.flatten?e.map(e=>({text:eH(e,0,!1),comparable:t5(e,0)})):eW(e).map(e=>({text:e.text,comparable:t5(e.node,e.depth)}))}function t6(e,t){return e.get(t)??0}function t9(e){return"text"===e||"label"===e||"any"===e}function t7(e,t){return{session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata}}function ne(e){return e.clock?.now()??Date.now()}async function nt(e,t){e.clock?await e.clock.sleep(t):await new Promise(e=>setTimeout(e,t))}async function nn(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:ne(a)}),g=ne(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 na(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 nr(e){return["visible","hidden","exists","editable","selected","text"].includes(e)}function ni(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 no(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 ns(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(t7(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:ne(e)};return n.updateSession&&r&&await e.sessions.set({...r,snapshot:o}),{sessionName:a,session:r,snapshot:o}}async function nl(e,t,n){if(e.backend.readText){let a=await e.backend.readText(t7(e,{session:t.sessionName}),n);if(a.text.trim())return a.text}return T(n)}let nd=async(e,t)=>{if("ref"===t.target.kind){let n=await no(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 nl(e,n,a.node),node:a.node,selectorChain:r}}let n=await nA(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 nl(e,n.capture,n.node);return{kind:"text",target:{kind:"selector",selector:n.selector},text:r,node:n.node,selectorChain:a}},nu=async(e,t)=>{let n=await nd(e,{...t,property:"text",target:t.target});if("text"!==n.kind)throw new y("COMMAND_FAILED","getText returned non-text result");return n},nc=async(e,t)=>{let n=await nd(e,{...t,property:"attrs",target:t.target});if("attrs"!==n.kind)throw new y("COMMAND_FAILED","getAttrs returned non-attrs result");return n},np=async(e,t)=>{if(!nr(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 ns(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=A(n),s=N(n,i),l=!0===n.selected,d="text"===t?S(n):function(e,t){if(!0===e.hittable)return!0;if(ni(e.rect))return e8(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||ni(e.rect))}(e))return e;a=e}return null}(e,t);return!!n&&(!0===n.hittable||!!ni(n.rect)&&e8(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)}},nf=async(e,t)=>await np(e,{...t,predicate:"visible",selector:t.target.selector}),nh=async(e,t)=>await np(e,{...t,predicate:"hidden",selector:t.target.selector}),nm=async(e,t)=>{if("sleep"===t.target.kind)return await nt(e,t.target.durationMs),{kind:"sleep",waitedMs:t.target.durationMs};if("ref"===t.target.kind){let n=await no(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 nb(e,t,i,t.target.timeoutMs)}if("selector"===t.target.kind)return await ny(e,t,t.target.selector,t.target.timeoutMs);if(!t.target.text)throw new y("INVALID_ARGS","wait requires text");return await nb(e,t,t.target.text,t.target.timeoutMs)},nw=async(e,t)=>{let n=await nm(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 ng(e,t,n){let a=t.timeoutMs??1e4,r=ne(e);for(;ne(e)-r<a;){if(ew((await ns(e,t,{updateSession:!0,scope:t9(n)?t.query:void 0})).snapshot.nodes,n,t.query,{requireRect:!1}).matches[0])return{kind:"found",found:!0,waitedMs:ne(e)-r};await nt(e,300)}throw new y("COMMAND_FAILED","find wait timed out")}async function ny(e,t,n,a){let r=a??1e4,i=ne(e),o=x(n);for(;ne(e)-i<r;){let n=L((await ns(e,t,{updateSession:!0})).snapshot.nodes,o,{platform:e.backend.platform});if(n)return{kind:"selector",selector:n.selector.raw,waitedMs:ne(e)-i};await nt(e,300)}throw new y("COMMAND_FAILED",`wait timed out for selector: ${n}`)}async function nb(e,t,n,a){let r=a??1e4,i=ne(e);for(;ne(e)-i<r;){if(e.backend.findText?(await e.backend.findText(t7(e,t),n)).found:await nv(e,t,n))return{kind:"text",text:n,waitedMs:ne(e)-i};await nt(e,300)}throw new y("COMMAND_FAILED",`wait timed out for text: ${n}`)}async function nv(e,t,n){return!!C((await ns(e,t,{updateSession:!0})).snapshot.nodes,n)}async function nA(e,t,n,a){let r=await ns(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 nI(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 nx(e){let t=nS(e);if(!t)return null;let n=B(t);return Number.isFinite(n.x)&&Number.isFinite(n.y)?n:null}function nS(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 nN(e,t){let n=function(e,t){let n=nS(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=nS(e.rect);return!!t&&n_(t,n)});if(1!==t.length)break;a=t[0]}return a===t?null:a}(e,t);if(n?.rect&&nx(n.rect))return n;let a=k(e,t);return a?.rect&&nx(a.rect)?!function(e,t,n){var a,r,i,o;let s,l,d,u=nS(e.rect),c=nS(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=>nS(e.rect)).filter(e=>null!==e);if(0===a.length)return null;let r=a.filter(e=>e1(e,n.x,n.y));return e2(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))&&!n_(u,c)}(t,a,e)?a:t:t}function n_(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 nM(e,t,n){if(await nD(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 nO(e,t,t.target),r=a.resolved,i=n.promoteToHittableAncestor?nN(a.snapshot.nodes,r.node):r.node;return function(e,t,n,a){let r=e.rect?e6(e,t):null;if(!(!e.rect||!r||e8(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:nR(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 nk(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?nN(a.snapshot.nodes,i.node):i.node;return{kind:"selector",point:nR(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 nk(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(t7(e,t),{interactiveOnly:n,compact:n}),o=i.snapshot??{nodes:i.nodes??[],truncated:i.truncated,backend:i.backend,createdAt:ne(e)};return await e.sessions.set({...r,snapshot:o}),{snapshot:o}}async function nD(e,t,n){if("macos"!==e.backend.platform)return;let a=await nE(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 nE(e,t){let n=await e.sessions.get(t.session??"default");return n?.metadata?.surface}async function nO(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=nC(r.snapshot.nodes,n.ref,{fallbackLabel:i,requireRect:!0});if(o)return{snapshot:r.snapshot,resolved:o};let s=await nk(e,t,!0),l=nC(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 nC(e,t,n){let a=j(t);if(!a)throw new y("INVALID_ARGS",`Invalid ref: ${t}`);let r=V(e,a);if(nP(r,n.requireRect))return{ref:a,node:r};let i=n.fallbackLabel.length>0?C(e,n.fallbackLabel):null;return nP(i,n.requireRect)?{ref:a,node:i}:null}function nR(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 nP(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 nT(e,t){let n=t.target??{kind:"viewport"};return"viewport"===n.kind?(await nD(e,t,"scroll"),{kind:"viewport"}):await nM(e,{...t,target:n},{action:"scroll",requireInteractive:!1,promoteToHittableAncestor:!1})}async function nL(e,t){if(t.from){var n;if("x"in(n=t.from)&&"y"in n)return await nD(e,t,"swipe"),{point:nF(t.from,"from")};let a=await nM(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 nD(e,t,"swipe"),{point:B(function(e){let t=e.filter(t=>e8(t,e)).map(e=>e.rect).filter(nG),n=t.length>0?t:e.map(e=>e.rect).filter(nG);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 nk(e,t,!1)).snapshot.nodes)),target:{kind:"viewport"}}}function n$(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 nF(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 nU(e,t){if(!Number.isFinite(e)||e<=0)throw new y("INVALID_ARGS",`${t} must be a positive number`);return e}function nG(e){return!!(e&&e.width>0&&e.height>0)}function nV(e){return e&&"object"==typeof e?e:void 0}async function nB(e,t,n){let a=await nM(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=nj(await e.backend.tap(t7(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 nj(e){return e&&"object"==typeof e?e:void 0}function nq(e){return!!(e&&"object"==typeof e)}function nX(e){return e&&"object"==typeof e?e:void 0}let nz=/^[A-Za-z0-9_.:-]{1,64}$/;function nW(e,t){if(void 0!==e)return nH(e,t)}function nH(e,t){let n=e?.trim();if(!n)throw new y("INVALID_ARGS",`${t} must be a non-empty string`);return n}async function nY(e,t){if(!t||"object"!=typeof t)throw new y("INVALID_ARGS","apps.push requires an input");if("json"===t.kind)return nK(t.payload,"apps.push JSON payload",8192),{backendInput:{kind:"json",payload:t.payload},inputKind:"json"};let n=await ts(e,t,{usage:"apps.push",field:"input"});return{backendInput:{kind:"file",path:n.path},inputKind:"file",...n.cleanup?{cleanup:n.cleanup}:{}}}function nK(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 nJ(e,t){return{session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata}}function nZ(e){return e&&"object"==typeof e?e:void 0}async function nQ(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?n4(t.app,"app"):void 0;if("installFromSource"!==n&&!i)throw new y("INVALID_ARGS",`admin.${n} requires app`);let o=t7(e,t),s=await n0(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=n8(c),a=n5(c,"appName"),f=n5(c,"appId"),h=n5(c,"bundleId"),m=n5(c,"packageName"),w=n5(c,"launchTarget"),g=n5(c,"installablePath"),y=n5(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}:{},...er(`${"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 n0(e,t,n){let a=n2(n),r=await n1(e,a);try{let n=e.backend.resolveInstallSource?await e.backend.resolveInstallSource(t,r.source):r.source;return{source:n2(n),...r.cleanup?{cleanup:r.cleanup}:{}}}catch(e){if(r.cleanup)try{await r.cleanup()}catch{}throw e}}async function n1(e,t){if("url"===t.kind)return{source:t};let n=await ts(e,t,{usage:"admin.install",field:"source"});return{source:{kind:"path",path:n.path},...n.cleanup?{cleanup:n.cleanup}:{}}}function n2(e){if(!e||"object"!=typeof e)throw new y("INVALID_ARGS","install source is required");if("path"===e.kind)return{kind:"path",path:n4(e.path,"source.path")};if("uploadedArtifact"===e.kind)return{kind:"uploadedArtifact",id:n4(e.id,"source.id")};if("url"===e.kind){let t=n4(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 n3(e,t){if(void 0!==e)return n4(e,t)}function n4(e,t){let n=e?.trim();if(!n)throw new y("INVALID_ARGS",`${t} must be a non-empty string`);return n}function n5(e,t){let n=e[t];return"string"==typeof n&&n.length>0?n:void 0}function n8(e){return e&&"object"==typeof e?e:void 0}function n6(e,t){if("start"===e||"stop"===e)return e;throw new y("INVALID_ARGS",`${t} action must be start or stop`)}function n9(e,t,n,a){return{kind:"start"===e?a.startKind:a.stopKind,action:e,...n?{artifact:n}:{},backendResult:t,...er("start"===e?a.startMessage:a.stopMessage)}}let n7=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i,ae=/\b[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\b/g;function at(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(ae,()=>(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=an(e);return t?(t.redacted&&n(),t.value):e}):t),redacted:a}}function an(e){try{let t=new URL(e),n=function(e){let t=!1;for(let n of Array.from(e.searchParams.keys()))n7.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 aa=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i;function ar(e){if(!e)return{redacted:!1};let t=!1,n={};for(let[a,r]of Object.entries(e))if(aa.test(a))n[a]="[REDACTED]",t=!0;else{let e=al(r,2048);n[a]=e.value??"",t||=e.redacted}return{value:n,redacted:t}}function ai(e){return void 0===e?{redacted:!1}:function(e){try{let t=JSON.parse(e),n=as(t,at);return ad(JSON.stringify(n.value),2048,n.redacted)}catch{return}}(e)??al(e,2048)}function ao(e){return as(e,e=>al(e,2048))}function as(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=as(e,t);return n||=a.redacted,a.value}),redacted:n}}let n=!1,a={};for(let[r,i]of Object.entries(e)){if(aa.test(r)){a[r]="[REDACTED]",n=!0;continue}let e=as(i,t);a[r]=e.value,n||=e.redacted}return{value:a,redacted:n}}function al(e,t){if(void 0===e)return{redacted:!1};let n=at(e);return ad(n.value,t,n.redacted)}function ad(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 au(e,t){let n=t7(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 ac(e,t,n,a){return{...ap(e),...void 0!==e.cursor?{cursor:ah(e.cursor,"cursor")}:{},limit:void 0===e.limit?t:nI(e.limit,a,1,n)}}function ap(e){return{...void 0!==e.since?{since:ah(e.since,"since")}:{},...void 0!==e.until?{until:ah(e.until,"until")}:{}}}function af(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)=>ah(e,`${t}[${n}]`))}function ah(e,t){let n=e.trim();if(!n)throw new y("INVALID_ARGS",`${t} must be a non-empty string`);return n}let am=async(e,t)=>{let n;if(!e.backend.captureScreenshot)throw new y("UNSUPPORTED_OPERATION","screenshot is not supported by this backend");let a=await tl(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 to(a.path,t.maxSize),n=await a.publish()}catch(e){throw await a.cleanup?.(),e}return{path:a.path,...n?{artifacts:[n]}:{},...er(`Saved screenshot: ${a.path}`)}},aw=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&&!t4(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 ts(e,t.baseline,{usage:"diff screenshot baseline",field:"baseline"}),l=[];try{let d;d=t4(o)?(a=await tZ(e,t)).path:(n=await ts(e,o,{usage:"diff screenshot current",field:"current"})).path,r=t.out?await tl(e,t.out,{field:"diffPath",ext:".png"}):void 0;let u=await tq(s.path,d,{threshold:i,outputPath:r?.path,maxPixels:e.policy.maxImagePixels});t4(o)&&(u=await tQ(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?.()}},ag=async(e,t)=>{var n;let a,r,i=await nn(e,t);return await e.sessions.set(na(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=e4(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}:{}})}},ay=async(e,t)=>{let n=await nn(e,t),a=!0===t.interactiveOnly,r=n.session?.snapshot,i=na(t.session,n);if(!r){let t=function(e,t={}){return t8(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&&t6(i,r-1)<t6(i,r+1)?t6(i,r+1):t6(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&&t6(r,l-1)<t6(r,l+1)?l+1:l-1,u=t6(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[]}(t8(e,n),t8(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}:{}}},ab=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 ng(e,t,n);let a=await ns(e,t,{updateSession:!0,scope:t9(n)?t.query:void 0}),r=ew(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 nl(e,a,r),node:r}},av=nd,aA=nu,aI=nc,ax=np,aS=nf,aN=nh,a_=nm,aM=nw,ak=async(e,t)=>await nB(e,t,"click"),aD=async(e,t)=>await nB(e,t,"press"),aE=async(e,t)=>{var n;if(!t.text)throw new y("INVALID_ARGS","fill requires text");let a=await nM(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=nj(await e.backend.fill(t7(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}:{}}},aO=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=nI(t.delayMs??0,"delay-ms",0,1e4),i=nj(await e.backend.typeText(t7(e,t),n,{delayMs:r}));return{kind:"text",text:n,delayMs:r,...i?{backendResult:i}:{},...er(`Typed ${Array.from(n).length} chars`)}},aC=async(e,t)=>{let n=await nM(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=nV(await e.backend.focus(t7(e,t),n.point));return{...n,...a?{backendResult:a}:{},...er(`Focused (${n.point.x}, ${n.point.y})`)}},aR=async(e,t)=>{let n=await nM(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:nI(t.durationMs,"durationMs",0,12e4),r=nV(await e.backend.longPress(t7(e,t),n.point,{durationMs:a}));return{...n,...void 0!==a?{durationMs:a}:{},...r?{backendResult:r}:{},...er(`Long pressed (${n.point.x}, ${n.point.y})`)}},aP=async(e,t)=>{if(!e.backend.swipe)throw new y("UNSUPPORTED_OPERATION","swipe is not supported by this backend");let n=await nL(e,t),a=function(e,t){if(t.to)return{point:nF(t.to,"to")};let n=n$(t.direction,"swipe direction"),a=nU(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:nI(t.durationMs,"durationMs",16,1e4),i=nV(await e.backend.swipe(t7(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}:{},...er("Swiped")}},aT=async(e,t)=>{var n,a;if(!e.backend.scroll)throw new y("UNSUPPORTED_OPERATION","scroll is not supported by this backend");let r=n$(t.direction,"scroll direction"),i=(n=t.amount,a="scroll amount",void 0===n?void 0:nU(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 nT(e,t),l="viewport"===s.kind?{kind:"viewport"}:{kind:"point",point:s.point},d=nV(await e.backend.scroll(t7(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}:{},...er(void 0!==o?`Scrolled ${r} by ${o}px`:void 0!==i?`Scrolled ${r} by ${i}`:`Scrolled ${r}`)}},aL=async(e,t)=>{if(!e.backend.pinch)throw new y("UNSUPPORTED_OPERATION","pinch is not supported by this backend");await nD(e,t,"pinch");let n=nU(t.scale,"pinch scale"),a=t.center?await nM(e,{...t,target:t.center},{action:"pinch",requireInteractive:!1,promoteToHittableAncestor:!1}):void 0,r=nV(await e.backend.pinch(t7(e,t),{scale:n,...a?{center:a.point}:{}}));return{kind:"pinch",scale:n,...a?{center:a.point,centerTarget:a}:{},...r?{backendResult:r}:{},...er(`Pinched to scale ${n}`)}},a$=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=nX(await e.backend.pressBack(t7(e,t),{mode:n}));return{kind:"systemBack",mode:n,...a?{backendResult:a}:{},...er("Back")}},aF=async(e,t={})=>{if(!e.backend.pressHome)throw new y("UNSUPPORTED_OPERATION","system.home is not supported by this backend");let n=nX(await e.backend.pressHome(t7(e,t)));return{kind:"systemHome",...n?{backendResult:n}:{},...er("Home")}},aU=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=nX(await e.backend.rotate(t7(e,t),n));return{kind:"systemRotated",orientation:n,...a?{backendResult:a}:{},...er(`Rotated to ${n}`)}},aG=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(t7(e,t),{action:n}),r=nX(a);if("dismiss"===n){let e=nq(a)?a.dismissed:void 0;return{kind:"keyboardDismissed",action:n,state:nq(a)?a:{},...r?{backendResult:r}:{},...er(!1===e?"Keyboard already hidden":"Keyboard dismissed")}}return{kind:"keyboardState",action:n,state:nq(a)?a:{},...r?{backendResult:r}:{}}},aV=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(t7(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=nX(await e.backend.setClipboard(t7(e,t),t.text));return{kind:"clipboardUpdated",action:"write",textLength:Array.from(t.text).length,...n?{backendResult:n}:{},...er("Clipboard updated")}},aB=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=nX(await e.backend.openSettings(t7(e,t),n));return{kind:"settingsOpened",...n?{target:n}:{},...a?{backendResult:a}:{},...er(n?`Opened settings: ${n}`:"Opened settings")}},aj=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:nI(t.timeoutMs,"timeoutMs",0,12e4),r=await e.backend.handleAlert(t7(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}:{},...er(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}:{},...er(o.handled?`Alert ${i}ed`:"No alert handled")}},aq=async(e,t={})=>{if(!e.backend.openAppSwitcher)throw new y("UNSUPPORTED_OPERATION","system.appSwitcher is not supported by this backend");let n=nX(await e.backend.openAppSwitcher(t7(e,t)));return{kind:"appSwitcherOpened",...n?{backendResult:n}:{},...er("Opened app switcher")}},aX=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=nW(e.app,"app"),a=nW(e.appId,"appId"),r=nW(e.bundleId,"bundleId"),i=nW(e.packageName,"packageName"),o=nW(e.url,"url"),s=nW(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=nZ(await e.backend.openApp(nJ(e,t),a,{relaunch:t.relaunch}));return{kind:"appOpened",target:a,relaunch:!0===t.relaunch,...r?{backendResult:r}:{},...er(`Opened: ${(n=a).app??n.appId??n.bundleId??n.packageName??n.url??n.activity??"app"}`)}},az=async(e,t={})=>{if(!e.backend.closeApp)throw new y("UNSUPPORTED_OPERATION","apps.close is not supported by this backend");let n=nW(t.app,"app"),a=nZ(await e.backend.closeApp(nJ(e,t),n));return{kind:"appClosed",...n?{app:n}:{},...a?{backendResult:a}:{},...er(n?`Closed: ${n}`:"Closed app")}},aW=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(nJ(e,t),t.filter??"all")}},aH=async(e,t)=>{if(!e.backend.getAppState)throw new y("UNSUPPORTED_OPERATION","apps.state is not supported by this backend");let n=nH(t.app,"app"),a=await e.backend.getAppState(nJ(e,t),n);return{kind:"appState",app:n,state:a}},aY=async(e,t)=>{if(!e.backend.pushFile)throw new y("UNSUPPORTED_OPERATION","apps.push is not supported by this backend");let n=nH(t.app,"app"),a=await nY(e,t.input);try{let r=await e.backend.pushFile(nJ(e,t),a.backendInput,n),i=nZ(r);return{kind:"appPushed",app:n,inputKind:a.inputKind,...i?{backendResult:i}:{},...er(`Pushed to ${n}`)}}finally{await a.cleanup?.()}},aK=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=nH(e,"name");if(!nz.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&&nK(n,a,8192);let i=nZ(await e.backend.triggerAppEvent(nJ(e,t),{name:r,...t.payload?{payload:t.payload}:{}}));return{kind:"appEventTriggered",name:r,...t.payload?{payload:t.payload}:{},...i?{backendResult:i}:{},...er(`Triggered app event: ${r}`)}},aJ=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(t7(e,t),t.filter)}},aZ=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=n3(e.id,"target.id"),n=n3(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=n8(await e.backend.bootDevice(t7(e,t),n));return{kind:"deviceBooted",...n?{target:n}:{},...a?{backendResult:a}:{},...er("Booted device")}},aQ=async(e,t)=>{if(!e.backend.ensureSimulator)throw new y("UNSUPPORTED_OPERATION","admin.ensureSimulator is not supported by this backend");let n=n4(t.device,"device");return{kind:"simulatorEnsured",...await e.backend.ensureSimulator(t7(e,t),{device:n,...t.runtime?{runtime:n4(t.runtime,"runtime")}:{},...void 0!==t.boot?{boot:t.boot}:{},...void 0!==t.reuseExisting?{reuseExisting:t.reuseExisting}:{}})}},a0=async(e,t)=>await nQ(e,t,"install"),a1=async(e,t)=>await nQ(e,t,"reinstall"),a2=async(e,t)=>await nQ(e,t,"installFromSource"),a3=async(e,t)=>{let n=n6(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 tl(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:nI(i.fps,"fps",1,60),c=void 0===i.quality?void 0:nI(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,t7(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}:{},...n9(s,l,d,{startKind:"recordingStarted",stopKind:"recordingStopped",startMessage:"Recording started",stopMessage:"Recording stopped"})}}catch(e){throw await r?.cleanup?.(),e}},a4=async(e,t)=>{let n=n6(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 tl(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,t7(e,t),l),u=await r?.publish();return i=n,o=d,s=u,{..."string"==typeof o.outPath?{outPath:o.outPath}:{},...n9(i,o,s,{startKind:"traceStarted",stopKind:"traceStopped",startMessage:"Trace started",stopMessage:"Trace stopped"})}}catch(e){throw await r?.cleanup?.(),e}},a5=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 au(e,t),{...ac(a=t,100,500,"logs limit"),...void 0!==a.levels?{levels:af(a.levels,"levels")}:{},...void 0!==a.search?{search:ah(a.search,"search")}:{},...void 0!==a.source?{source:ah(a.source,"source")}:{}})).redacted,{kind:"diagnosticsLogs",entries:n.entries.map(e=>{let t=al(e.message,4096),n=ao(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}:{}}},a8=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={...ac(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 au(e,t),o),a=o.include??"summary",i=!0===n.redacted,{kind:"diagnosticsNetwork",entries:n.entries.map(e=>{var t;let n=e.url?an(t=e.url)??al(t,2048):void 0,r="headers"===a||"all"===a?ar(e.requestHeaders):void 0,o="headers"===a||"all"===a?ar(e.responseHeaders):void 0,s="body"===a||"all"===a?ai(e.requestBody):void 0,l="body"===a||"all"===a?ai(e.responseBody):void 0,d=ao(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}:{}}},a6=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 au(e,t),{...ap(a=t),...void 0!==a.sampleMs?{sampleMs:nI(a.sampleMs,"sampleMs",100,6e4)}:{},...void 0!==a.metrics?{metrics:af(a.metrics,"metrics",20)}:{}})).redacted,{kind:"diagnosticsPerf",metrics:n.metrics.map(e=>{let t=al(e.message,4096),n=ao(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 a9(e){let t={backend:e.backend,artifacts:e.artifacts,sessions:e.sessions??function(e=[]){let t=new Map(e.map(e=>[e.name,a7(e)]));return{get:e=>a7(t.get(e)),set:e=>{t.set(e.name,a7(e))},delete:e=>{t.delete(e)},list:()=>Array.from(t.values(),e=>a7(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=>am(t,e),diffScreenshot:e=>aw(t,e),snapshot:e=>ag(t,e),diffSnapshot:e=>ay(t,e)},selectors:{find:e=>ab(t,e),get:e=>av(t,e),getText:(e,n={})=>aA(t,{...n,target:e}),getAttrs:(e,n={})=>aI(t,{...n,target:e}),is:e=>ax(t,e),isVisible:(e,n={})=>aS(t,{...n,target:e}),isHidden:(e,n={})=>aN(t,{...n,target:e}),wait:e=>a_(t,e),waitForText:(e,n={})=>aM(t,{...n,text:e})},interactions:{click:(e,n={})=>ak(t,{...n,target:e}),press:(e,n={})=>aD(t,{...n,target:e}),fill:(e,n,a={})=>aE(t,{...a,target:e,text:n}),typeText:(e,n={})=>aO(t,{...n,text:e}),focus:(e,n={})=>aC(t,{...n,target:e}),longPress:(e,n={})=>aR(t,{...n,target:e}),swipe:e=>aP(t,e),scroll:e=>aT(t,e),pinch:e=>aL(t,e)},system:{back:e=>a$(t,e),home:e=>aF(t,e),rotate:e=>aU(t,e),keyboard:e=>aG(t,e),clipboard:e=>aV(t,e),settings:e=>aB(t,e),alert:e=>aj(t,e),appSwitcher:e=>aq(t,e)},apps:{open:e=>aX(t,e),close:e=>az(t,e),list:e=>aW(t,e),state:e=>aH(t,e),push:e=>aY(t,e),triggerEvent:e=>aK(t,e)},admin:{devices:e=>aJ(t,e),boot:e=>aZ(t,e),ensureSimulator:e=>aQ(t,e),install:e=>a0(t,e),reinstall:e=>a1(t,e),installFromSource:e=>a2(t,e)},recording:{record:e=>a3(t,e),trace:e=>a4(t,e)},observability:{logs:e=>a5(t,e),network:e=>a8(t,e),perf:e=>a6(t,e)}}}function a7(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 re(e={}){return{allowLocalInputPaths:!0,allowLocalOutputPaths:!0,maxImagePixels:2e7,allowNamedBackendCapabilities:[],...e}}function rt(e,t,n){return{ok:!1,error:{code:e,message:t,...n?{details:n}:{}}}}function rn(e){if(!e)return null;let t=Number(e);return Number.isFinite(t)?t:null}function ra(e){if(0===e.length)return null;let t=rn(e[0]);if(null!==t)return{kind:"sleep",durationMs:t};if("text"===e[0]){let t=rn(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=rn(e[e.length-1]);return{kind:"ref",rawRef:e[0],timeoutMs:t}}let n=rn(e[e.length-1]),a=b(null!==n?e.slice(0,-1):e.slice());if(a&&0===a.rest.length){let e=I(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 rr(e){return e}function ri(e){return"apple"===e||"ios"===e||"macos"===e}function ro(e,t){return!t||("apple"===t?ri(e):e===t)}function rs(e){let{simulatorSetPath:t,platform:n,target:a}=e;if(t&&"macos"!==n&&"desktop"!==a)return t}async function rl(e,t,n={}){let a=e,r=e=>e.toLowerCase().replace(/_/g," ").replace(/\s+/g," ").trim();if(t.platform&&(a=a.filter(e=>ro(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&&ri(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=a.filter(e=>"device"!==e.kind);o.length>0&&(a=o);let s=a.filter(e=>e.booted);return 1===s.length?s[0]:s[0]??a[0]}let rd=e=>"macos"!==e.platform,ru=e=>"macos"===e.platform||"simulator"===e.kind,rc={device:!0},rp={},rf={alert:{apple:{simulator:!0,device:!0},android:{},linux:rp,supports:ru},pinch:{apple:{simulator:!0,device:!0},android:{},linux:rp,supports:ru},"app-switcher":{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rp,supports:rd},apps:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rp},back:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rc},boot:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rp,supports:rd},click:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rc},clipboard:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rc,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:rp,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:rc},fill:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rc},diff:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rc},find:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rc},focus:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rc},get:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rc},is:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rc},home:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rc,supports:rd},logs:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rp},network:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rp},longpress:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rc},open:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rc},perf:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rp},install:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rp,supports:rd},"install-from-source":{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rp,supports:rd},reinstall:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rp,supports:rd},press:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rc},push:{apple:{simulator:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rp,supports:rd},record:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rp},rotate:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rp,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:rc},scroll:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rc},swipe:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rc},settings:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rp,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:rc},"trigger-app-event":{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rp},type:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rc},wait:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rc}};function rh(e,t){let n=rf[e];if(!n)return!0;let a=ri(t.platform)?n.apple:"linux"===t.platform?n.linux:n.android;return!!a&&(!n.supports||!!n.supports(t))&&!0===a[t.kind??"unknown"]}let rm=rw(process.env.AGENT_DEVICE_RETRY_LOGS);function rw(e){return["1","true","yes","on"].includes((e??"").trim().toLowerCase())}let rg=2e4,ry=12e4,rb=1e4;class rv{startedAtMs;expiresAtMs;constructor(e,t){this.startedAtMs=e,this.expiresAtMs=e+Math.max(0,t)}static fromTimeoutMs(e,t=Date.now()){return new rv(t,e)}remainingMs(e=Date.now()){return Math.max(0,this.expiresAtMs-e)}elapsedMs(e=Date.now()){return Math.max(0,e-this.startedAtMs)}isExpired(e=Date.now()){return 0>=this.remainingMs(e)}}async function rA(e,t={},n={}){let a,r={maxAttempts:t.maxAttempts??3,baseDelayMs:t.baseDelayMs??200,maxDelayMs:t.maxDelayMs??2e3,jitter:t.jitter??.2,shouldRetry:t.shouldRetry};for(let t=1;t<=r.maxAttempts;t+=1){if(n.signal?.aborted)throw new y("COMMAND_FAILED","request canceled",{reason:"request_canceled"});if(n.deadline?.isExpired()&&t>1)break;try{let a=await e({attempt:t,maxAttempts:r.maxAttempts,deadline:n.deadline});return n.onEvent?.({phase:n.phase,event:"succeeded",attempt:t,maxAttempts:r.maxAttempts,elapsedMs:n.deadline?.elapsedMs(),remainingMs:n.deadline?.remainingMs()}),rx({phase:n.phase,event:"succeeded",attempt:t,maxAttempts:r.maxAttempts,elapsedMs:n.deadline?.elapsedMs(),remainingMs:n.deadline?.remainingMs()}),a}catch(d){a=d;let e=n.classifyReason?.(d),i={phase:n.phase,event:"attempt_failed",attempt:t,maxAttempts:r.maxAttempts,elapsedMs:n.deadline?.elapsedMs(),remainingMs:n.deadline?.remainingMs(),reason:e};if(n.onEvent?.(i),rx(i),t>=r.maxAttempts||r.shouldRetry&&!r.shouldRetry(d,t))break;let o=function(e,t,n,a){let r=Math.min(t,e*2**(a-1));return Math.max(0,r+r*n*(2*Math.random()-1))}(r.baseDelayMs,r.maxDelayMs,r.jitter,t),s=n.deadline?Math.min(o,n.deadline.remainingMs()):o;if(s<=0)break;let l={phase:n.phase,event:"retry_scheduled",attempt:t,maxAttempts:r.maxAttempts,delayMs:s,elapsedMs:n.deadline?.elapsedMs(),remainingMs:n.deadline?.remainingMs(),reason:e};n.onEvent?.(l),rx(l),await function(e,t){return new Promise(n=>{if(t?.aborted)return void n();let a=!1,r=()=>{a||(a=!0,t&&t.removeEventListener("abort",o),n())},i=setTimeout(r,e);function o(){clearTimeout(i),r()}t&&t.addEventListener("abort",o,{once:!0})})}(s,n.signal)}}let i={phase:n.phase,event:"exhausted",attempt:r.maxAttempts,maxAttempts:r.maxAttempts,elapsedMs:n.deadline?.elapsedMs(),remainingMs:n.deadline?.remainingMs(),reason:n.classifyReason?.(a)};if(n.onEvent?.(i),rx(i),a)throw a;throw new y("COMMAND_FAILED","retry failed")}async function rI(e,t={}){return rA(()=>e(),{maxAttempts:t.attempts,baseDelayMs:t.baseDelayMs,maxDelayMs:t.maxDelayMs,jitter:t.jitter,shouldRetry:t.shouldRetry})}function rx(e){es({level:"attempt_failed"===e.event||"exhausted"===e.event?"warn":"debug",phase:"retry",data:{...e}}),rm&&process.stderr.write(`[agent-device][retry] ${JSON.stringify(e)}
3
- `)}let rS=new Set,rN=new Map,r_="request_canceled",rM="request canceled";function rk(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 rD(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++}}(rN);let t=new AbortController;rN.set(e,t),rS.has(e)&&t.abort()}function rE(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++}}(rS),rS.add(e),rN.get(e)?.abort())}function rO(e){e&&(rS.delete(e),rN.delete(e))}function rC(e){return!!e&&rS.has(e)}function rR(e){if(e)return rN.get(e)?.signal}function rP(){return new y("COMMAND_FAILED",rM,{reason:r_})}function rT(e){return e instanceof y&&"COMMAND_FAILED"===e.code&&(e.details?.reason===r_||e.message===rM)}function rL(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 r$(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 rF=["AGENT_DEVICE_IOS_SIMULATOR_DEVICE_SET","IOS_SIMULATOR_DEVICE_SET"],rU=["AGENT_DEVICE_ANDROID_DEVICE_ALLOWLIST","ANDROID_DEVICE_ALLOWLIST"];function rG(e){return e?.trim()||void 0}function rV(e,t){for(let n of e){let e=rG(t[n]);if(e)return e}}function rB(e,t=process.env){return rG(e)??rV(rF,t)}function rj(e){return new Set(e.split(/[\s,]+/).map(e=>e.trim()).filter(Boolean))}function rq(e,t=process.env){let n=rG(e)??rV(rU,t);if(n)return rj(n)}function rX(e,t={}){let n=rB(t.simulatorSetPath);return n?["simctl","--set",n,...e]:["simctl",...e]}function rz(e,t){return"ios"!==e.platform||"simulator"!==e.kind?["simctl",...t]:rX(t,{simulatorSetPath:e.simulatorSetPath})}function rW(e){return!(e instanceof y)||"COMMAND_FAILED"!==e.code||!String(e.message??"").toLowerCase().includes("xcodebuild exited early")}function rH(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:rL({error:r,message:i,context:{platform:"ios",phase:"connect"}}),hint:r$("IOS_RUNNER_CONNECT_TIMEOUT")})}async function rY(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=rL({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}
4
- ${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.":r$("IOS_RUNNER_CONNECT_TIMEOUT"))})}function rK(e){if(rC(e))throw rP()}let rJ=eb(process.env.AGENT_DEVICE_RUNNER_STARTUP_TIMEOUT_MS,45e3,5e3),rZ=eb(process.env.AGENT_DEVICE_RUNNER_COMMAND_TIMEOUT_MS,45e3,1e3),rQ=eb(process.env.AGENT_DEVICE_RUNNER_CONNECT_ATTEMPT_INTERVAL_MS,250,50),r0=eb(process.env.AGENT_DEVICE_RUNNER_CONNECT_RETRY_BASE_DELAY_MS,300,10),r1=eb(process.env.AGENT_DEVICE_RUNNER_CONNECT_RETRY_MAX_DELAY_MS,2e3,10),r2=eb(process.env.AGENT_DEVICE_RUNNER_CONNECT_REQUEST_TIMEOUT_MS,2e4,250),r3=eb(process.env.AGENT_DEVICE_IOS_DEVICE_INFO_TIMEOUT_MS,1e4,500),r4=ev(process.env.AGENT_DEVICE_RUNNER_DESTINATION_TIMEOUT_SECONDS,20,5);async function r5(e,t,n,a,r=rJ,i,o){let s,l=rv.fromTimeoutMs(r),d=async n=>("device"===e.kind&&void 0===s&&(s=await r9(e.id,n)??void 0),r8(e,t,s??null)),u=await d(l.remainingMs()),c=null,p=Math.max(1,Math.ceil(r/rQ));try{return await rA(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 rY({session:i,port:t,logPath:a});for(let a of("device"===e.kind&&(u=await d(s?.remainingMs())),u))try{let e=s?.remainingMs()??r;if(e<=0)throw new y("COMMAND_FAILED","Runner connection deadline exceeded",{port:t,timeoutMs:r});return await r6(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)},Math.min(r2,e),o)}catch(e){if(o?.aborted||rT(e))throw rP();c=e}throw new y("COMMAND_FAILED","Runner endpoint probe failed",{port:t,endpoints:u,lastError:c?String(c):void 0})},{maxAttempts:p,baseDelayMs:r0,maxDelayMs:r1,jitter:.2,shouldRetry:rW},{deadline:l,phase:"ios_runner_connect",signal:o})}catch(e){if(o?.aborted||rT(e))throw rP();c||(c=e)}if(o?.aborted)throw rP();if("simulator"===e.kind){let r=l.remainingMs();if(r<=0)throw rH({port:t,endpoints:u,logPath:a,lastError:c});let i=await r7(e,t,n,r,o);return new Response(i.body,{status:i.status})}throw rH({port:t,endpoints:u,logPath:a,lastError:c})}async function r8(e,t,n){let a=[`http://127.0.0.1:${t}/command`];return"device"!==e.kind||n&&a.unshift(`http://[${n}]:${t}/command`),a}async function r6(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 r9(e,t){if("number"==typeof t&&t<=0)return null;let a="number"==typeof t?Math.max(1,Math.min(r3,t)):r3,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 ep("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{ii(r)}}async function r7(e,t,n,a,r){let i=JSON.stringify(n),o=rz(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 ep("xcrun",o,{allowFailure:!0,timeoutMs:a,signal:r}),l=s.stdout;if(0!==s.exitCode){let e=rL({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:r$(e)})}return{status:200,body:l}}async function ie(){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 it(e,t,n,a){t&&ir(t,e),n&&ir(n,e),a&&process.stderr.write(e)}let ia=new Map;function ir(e,t){let a=(ia.get(e)??Promise.resolve()).catch(()=>{}).then(()=>n.promises.appendFile(e,t)).catch(()=>{}).finally(()=>{ia.get(e)===a&&ia.delete(e)});ia.set(e,a)}function ii(e){try{n.existsSync(e)&&n.unlinkSync(e)}catch{}}let io=new u;async function is(e,t,n){let a=io.getStore()??[];if(a.some(n=>n.locks===e&&n.key===t))return await n();let r=(e.get(t)??Promise.resolve()).catch(()=>{}).then(()=>io.run([...a,{locks:e,key:t}],n));return e.set(t,r),r.finally(()=>{e.get(t)===r&&e.delete(t)})}let il=new Set(["RUNNER_PRODUCT_MISSING","RUNNER_PRODUCT_REPAIR_FAILED"]);async function id(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!==ec("codesign",["--verify","--deep","--strict",e],{allowFailure:!0}).exitCode){await ep("codesign",["--remove-signature",e],{allowFailure:!0});try{await ep("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 iu=null;function ic(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:ih(r)??ih(a["#text"]),children:e(r)});return n}((iu??=new p({ignoreAttributes:!1,attributeNamePrefix:"",preserveOrder:!0,trimValues:!0,parseTagValue:!1})).parse(e))}function ip(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)}ip(n.children,t)}}function ih(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 im="XCTestDevices",iw=".agent-device-backup",ig=".agent-device-xctestdevices-backup-",iy=o.join(s.homedir(),".agent-device","ios-runner"),ib=new Set(["ProductPaths","DependentProductPaths","TestHostPath","TestBundlePath","UITargetAppPath"]),iv=new Map,iA=new Set;function iI(e){return e?.trim()??""}function ix(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 iS(e=process.env){let t=iI(e.AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID);return t||`${ix(e)}.uitests`}let iN=function(e=process.env){let t=ix(e),n=iS(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 i_(e=s.homedir()){return o.join(e,"Library","Developer","XCTestDevices")}async function iM(e,t={}){if("ios"!==e.platform||"simulator"!==e.kind)return null;let a=rB(e.simulatorSetPath);if(!a)return null;let r=o.resolve(a),i=o.resolve(t.xctestDeviceSetPath??i_()),l=o.resolve(t.backupPath??function(e=i_()){return`${e}${iw}`}(i)),d=o.resolve(t.lockDirPath??function(e=s.homedir()){return o.join(e,".agent-device","xctest-device-set.lock")}()),u=t.ownerStartTime??eI(process.pid),c=await iE({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}}(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,`${im}.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)&&iD(i),e}}({requestedSetPath:r,xctestDeviceSetPath:i})}catch(e){throw ik({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{ik({xctestDeviceSetPath:i,backupPath:l})}finally{await c()}}}}}function ik(e){let{xctestDeviceSetPath:t,backupPath:a}=e,r=[a,...function(e){let t=o.dirname(e),a=o.basename(e).replace(iw,""),r=a===im?ig:`${a}${ig}`;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&&iD(t),n.existsSync(t))if(!s)return void es({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&&(es({level:"warn",phase:"ios_runner_xctest_device_set_orphaned_symlink",data:{xctestDeviceSetPath:t}}),iD(t))}function iD(e){!n.existsSync(e)||n.lstatSync(e).isSymbolicLink()&&n.unlinkSync(e)}async function iE(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)&&eA(i.pid)&&(!i.startTime||eI(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 ey(100)}throw new y("COMMAND_FAILED","Timed out waiting for XCTest device set lock",{lockDirPath:t})}async function iO(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(iy,"derived","macos"):"simulator"===a.kind?o.join(iy,"derived"):o.join(iy,"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 is(iv,i,async()=>{rw(process.env.AGENT_DEVICE_IOS_CLEAN_DERIVED)&&(ij("clean","forced_clean",{derived:i}),iB(i),iC(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=>iP(t,e),xctestrunReferencesProjectRoot:iL,resolveExistingXctestrunProductPaths:iq});if("reuse_ready"!==a.reason&&ij("rebuild",a.reason,{derived:i,xctestrunPath:a.xctestrunPath}),"reuse_ready"===a.reason)try{return await id(e,a.productPaths,a.xctestrunPath),ij("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&&il.has(t)}(e))throw e;ij("rebuild","repair_failed",{derived:i,xctestrunPath:a.xctestrunPath})}a.xctestrunPath&&(iB(i),iC(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 iF(e,r,i,t);let l=iP(i,e);if(!l)throw new y("COMMAND_FAILED","Failed to locate .xctestrun after build");let d=iq(l);if(!d)throw new y("COMMAND_FAILED","Runner build is missing expected products",{xctestrunPath:l});return await id(e,d,l),ij("build","built_new",{derived:i,xctestrunPath:l}),l})}function iC(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,iR.has(t)&&n.rmSync(o.join(e,a.name),{recursive:!0,force:!0})}}catch{}}let iR=new Set(["Build","BuildCache.noindex","Index.noindex","Logs","ModuleCache.noindex","SDKStatCaches.noindex","SourcePackages","TextBasedInstallAPI","info.plist"]);function iP(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=iT(n.path,t)-iT(e.path,t);if(0!==a)return a}return n.mtimeMs-e.mtimeMs||e.path.localeCompare(n.path)}),a[0]?.path??null)}function iT(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 iL(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 i$(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 ep("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 ep("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 iF(e,t,n,a){let r=function(e=process.env){let t=ix(e),n=iS(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 iM(e);try{var l;let s;await el("xcodebuild",["build-for-testing","-project",t,"-scheme","AgentDeviceRunner","-parallel-testing-enabled","NO",iV(e),"1","-destination",(l=e,s=iU(l),"macOS"===s?`platform=macOS,arch=${iG()}`:"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=>{iA.add(e),e.on("close",()=>{iA.delete(e)})},onStdoutChunk:e=>{it(e,a.logPath,a.traceLogPath,a.verbose)},onStderrChunk:e=>{it(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:a.logPath,hint:r})}finally{await s?.release()}}function iU(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 iG(){return"arm64"===process.arch?"arm64":"x86_64"}function iV(e){return"macos"===e.platform||"device"===e.kind?"-maximum-concurrent-test-device-destinations":"-maximum-concurrent-test-simulator-destinations"}function iB(e,t=process.env){if(t.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim()&&!function(e=process.env){return rw(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 ij(e,t,n){es({level:"rebuild"===e?"warn":"info",phase:"runner_xctestrun_cache",data:{action:e,reason:t,...n}})}function iq(e){let t=function(e){let t=function(e){try{let t=ec("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 a,r,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[a,r]of Object.entries(e))if(t.has(a)){if("string"==typeof r){n.add(r);continue}if(Array.isArray(r))for(let e of r)"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 a=n.readFileSync(e,"utf8"),r=ic(a),t=new Set,ip(r,(e,n)=>{if(ib.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 a=o.dirname(e),r=new Set,i=new Set,s=[];for(let e of t){if(e.startsWith("__TESTROOT__/")){let t=e.slice(13),s=o.join(a,t);if(!n.existsSync(s))return null;r.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(a,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;r.add(o.join(t,e))}return Array.from(r)}let iX=new Map,iz=new Map;async function iW(e,t){return await is(iz,e.id,async()=>{var n;let a,r,i=iX.get(e.id);if(i){if(function(e){return!!e&&eA(e)}(i.child.pid))return i;await iJ(e.id,i)}await ("simulator"!==(n=e).kind?Promise.resolve():i2(n)),await iH(e);let o=await iO(e,t),s=await ie(),{xctestrunPath:l,jsonPath:d}=await i$(o,{AGENT_DEVICE_RUNNER_PORT:String(s)},`session-${e.id}-${s}`),u=await iM(e);try{let t;({child:a,wait:r}=eu("xcodebuild",["test-without-building","-only-testing","AgentDeviceRunnerUITests/RunnerTests/testCommand","-parallel-testing-enabled","NO","-test-timeouts-enabled","NO","-collect-test-diagnostics","never",iV(e),"1","-destination-timeout",String(r4),"-xctestrun",l,"-destination",(t=iU(e),"macOS"===t?`platform=macOS,arch=${iG()}`:"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}a.stdout?.on("data",e=>{it(e,t.logPath,t.traceLogPath,t.verbose)}),a.stderr?.on("data",e=>{it(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:r,child:a,ready:!1,simulatorSetRedirect:u??void 0};return iX.set(e.id,c),c})}async function iH(e){if("simulator"===e.kind)for(let t of iN){let n=await ep("xcrun",rz(e,["uninstall",e.id,t]),{allowFailure:!0});if(0!==n.exitCode){let e=`${n.stdout}
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 iY(e){let t=iX.get(e);return t?{sessionId:t.sessionId,alive:function(e){return!!e&&eA(e)}(t.child.pid)}:null}async function iK(e){await is(iz,e.deviceId,async()=>{await iJ(e.deviceId,e)})}async function iJ(e,t){let n=t??iX.get(e);if(n){try{await r5(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{}await i1(n.child.pid,"SIGKILL"),ii(n.xctestrunPath),ii(n.jsonPath),await n.simulatorSetRedirect?.release(),iX.get(e)===n&&iX.delete(e)}}async function iZ(e){await is(iz,e,async()=>{await iJ(e)})}async function iQ(){let e=Array.from(iX.values()),t=Array.from(iA);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"),iA.delete(e)})),await Promise.allSettled(e.map(async e=>{await e.simulatorSetRedirect?.release()}))}async function i0(){await iQ();let e=Array.from(iX.keys());await Promise.allSettled(e.map(async e=>{await iZ(e)}));let t=Array.from(iA);await Promise.allSettled(t.map(async e=>{try{await i1(e.pid,"SIGTERM"),await i1(e.pid,"SIGKILL")}finally{iA.delete(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 ep("pkill",[`-${n}`,"-P",String(e)],{allowFailure:!0})}catch{}}async function i2(e){await ep("xcrun",rz(e,["bootstatus",e.id,"-b"]),{timeoutMs:rJ})}async function i3(e,t,n,a,r,i){let o=await r5(e,t.port,n,a,r,t,i);return await i4(o,t,a)}async function i4(e,t,n){let a,r=await e.text();try{let e=JSON.parse(r);a=e&&"object"==typeof e?e:{}}catch{throw new y("COMMAND_FAILED","Invalid runner response",{text:r})}if(!a.ok){let e=a.error?.code;throw new y("string"==typeof e&&e.trim().length>0?m(e):"COMMAND_FAILED",("string"==typeof a.error?.message?a.error.message:void 0)??"Runner error",{runner:a,xcodebuild:{exitCode:1,stdout:"",stderr:""},logPath:n})}return(t.ready=!0,a.data&&"object"==typeof a.data&&!Array.isArray(a.data))?a.data:{}}async function i5(e,t,n={}){var a;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(rK(n.requestId),"interactionFrame"===(a=t.command)||"snapshot"===a||"screenshot"===a||"findText"===a||"readText"===a||"alert"===a||"uptime"===a)?rI(()=>(rK(n.requestId),i8(e,t,n)),{shouldRetry:e=>{rK(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 a;rK(n.requestId);let r=rR(n.requestId);try{let i=(a=await iW(e,n)).ready?rZ:rJ;return await i3(e,a,t,n.logPath,i,r)}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")&&rW(i)&&a?.ready){rK(n.requestId),a?await iK(a):await iZ(e.id),a=await iW(e,n);let i=await r5(a.device,a.port,t,n.logPath,rJ,void 0,r);return await i4(i,a,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 oa(){return function(e){let t=o.dirname(e);for(;;){let e=o.join(t,"macos-helper");if(a(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 or(e){let t=await r.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 or(n):t.isFile()&&(t.name.endsWith(".swift")||"Package.swift"===t.name)?[n]:[]}))).flat().sort()}async function oi(e){let t=await or(e),n=f("sha256");for(let a of t)n.update(o.relative(e,a)),n.update("\0"),n.update(await r.readFile(a)),n.update("\0");let a=await ep("swift",["--version"],{allowFailure:!0,cwd:e,timeoutMs:1e4});return n.update("swift-version"),n.update("\0"),n.update(a.stdout||a.stderr||`exit:${a.exitCode}`),n.update("\0"),n.digest("hex")}async function oo(){try{let e=JSON.parse(await r.readFile(oe,"utf8"));return"string"==typeof e.fingerprint?e.fingerprint:null}catch{return null}}async function os(){let e=await em(process.env[i9],i9);if(e)return e;let t=oa(),n=await oi(t),a=o.join(i7,i6);try{if(await oo()===n)return await r.access(a),a}catch{}let i=o.join(oa(),".build","release",i6);process.stderr.write("agent-device: building macOS helper (first run or helper update)\n"),await ep("swift",["build","-c","release","--package-path",t],{cwd:t,timeoutMs:12e4}),await r.mkdir(i7,{recursive:!0});let s=`${a}.tmp`;return await r.copyFile(i,s),await r.rename(s,a),await r.chmod(a,493),await r.writeFile(oe,`${JSON.stringify({fingerprint:n},null,2)}
8
- `,"utf8"),a}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(),a=await ep(n,e,{allowFailure:!0,timeoutMs:3e4}),r=a.stdout.trim(),i=null;if(r)try{i=JSON.parse(r)}catch{i=null}if(0===a.exitCode&&i?.ok)return i.data;throw new y("COMMAND_FAILED",i&&!i.ok?i.error?.message??`macOS helper exited with code ${a.exitCode}`:r||a.stderr.trim()||`macOS helper exited with code ${a.exitCode}`,{helperPath:n,args:e,stdout:a.stdout,stderr:a.stderr,exitCode:a.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 a=["read","--x",String(e),"--y",String(t)];return n.bundleId&&a.push("--bundle-id",on(n.bundleId)),n.surface&&a.push("--surface",n.surface),await ol(a)}async function om(e,t,n={}){let a=["press","--x",String(e),"--y",String(t)];return n.bundleId&&a.push("--bundle-id",on(n.bundleId)),n.surface&&a.push("--surface",n.surface),await ol(a)}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,t){return["-s",e.id,...t]}async function oy(){if(await ex(),!await eh("adb"))throw new y("TOOL_MISSING","adb not found in PATH")}function ob(e,t){let n=`${e}
9
- ${t}`.toLowerCase();return n.includes("no shell command implementation")||n.includes("unknown command")}function ov(e){let t=e.trim();if(!t||/\s/.test(t))return!1;let n=/^([A-Za-z][A-Za-z0-9+.-]*):(.+)$/.exec(t);if(!n)return!1;let a=n[1]?.toLowerCase(),r=n[2]??"";return"http"!==a&&"https"!==a&&"ws"!==a&&"wss"!==a&&"ftp"!==a&&"ftps"!==a||r.startsWith("//")}function oA(e,t){let n,a=e?.trim();return a?a:"http"===(n=t.trim().split(":")[0]?.toLowerCase())||"https"===n?"com.apple.mobilesafari":void 0}let oI=["android.software.leanback","android.software.leanback_only","android.hardware.type.television"];async function ox(e,t,n){let a=Array(e.length),r=0,i=Math.min(t,e.length);return await Promise.all(Array.from({length:i},async()=>{for(;r<e.length;){let t=r;r+=1,a[t]=await n(e[t])}})),a}function oS(e){return`${e.stdout}
10
- ${e.stderr}`}function oN(e,t){return["-s",e,...t]}function o_(e){return e.startsWith("emulator-")}function oM(e){return e.toLowerCase().replace(/_/g," ").replace(/\s+/g," ").trim()}async function ok(e,t=rb){return ep("adb",oN(e,["shell","getprop","sys.boot_completed"]),{allowFailure:!0,timeoutMs:t})}async function oD(e,t){let n=t.replace(/_/g," ").trim();if(!o_(e))return n||e;let a=await oO(e);return a?a.replace(/_/g," "):n||e}async function oE(e,t,n){try{return await n("adb",oN(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 oO(e,t=ep){for(let n of["ro.boot.qemu.avd_name","persist.sys.avd_name"]){let a=await oE(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 oE(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 oC(e,t){let n=oS(await ep("adb",oN(e,["shell","cmd","package","has-feature",t]),{allowFailure:!0,timeoutMs:rb})).toLowerCase();return!!n.includes("true")||!n.includes("false")&&null}async function oR(e){return(await ox(oI,2,async t=>await oC(e,t))).some(e=>!0===e)}async function oP(e){var t;let n;return"tv"===((n=oS(await ep("adb",oN(e,["shell","getprop","ro.build.characteristics"]),{allowFailure:!0,timeoutMs:rb})).toLowerCase()).includes("tv")||n.includes("leanback")?"tv":null)||await oR(e)?"tv":(t=oS(await ep("adb",oN(e,["shell","pm","list","features"]),{allowFailure:!0,timeoutMs:rb})),/feature:android\.(software\.leanback(_only)?|hardware\.type\.television)\b/i.test(t))?"tv":"mobile"}async function oT(e={}){if(await ex(),!await eh("adb"))throw new y("TOOL_MISSING","adb not found in PATH");let t=e.serialAllowlist??rq(void 0),n=(await oL()).filter(e=>!t||t.has(e.serial));return await ox(n,3,async({serial:e,rawModel:t})=>{let[n,a,r]=await Promise.all([oD(e,t),oG(e),oP(e)]);return{platform:"android",id:e,name:n,kind:o_(e)?"emulator":"device",target:r,booted:a}})}async function oL(){return(await ep("adb",["devices","-l"],{timeoutMs:rb})).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 o$(){let e=await ep("emulator",["-list-avds"],{allowFailure:!0,timeoutMs:rb});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 oF(e){let t=Date.now();for(;Date.now()-t<e.timeoutMs;){try{let t=await oU(e.avdName,e.serial);if(t)return{platform:"android",id:t,name:e.avdName,kind:"emulator",target:"mobile",booted:!1}}catch{}await ey(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 oU(e,t){let n=oM(e);for(let e of(await oL()).filter(e=>(!t||e.serial===t)&&o_(e.serial)))if(oM(e.rawModel)===n||oM(await oD(e.serial,e.rawModel))===n)return e.serial}async function oG(e){try{let t=await ok(e);return"1"===t.stdout.trim()}catch{return!1}}async function oV(e){var t,n;let a;await ex();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 eh("adb"))throw new y("TOOL_MISSING","adb not found in PATH");if(!await eh("emulator"))throw new y("TOOL_MISSING","emulator not found in PATH");let o=await o$(),s=function(e,t){let n=e.find(e=>e===t);if(n)return n;let a=oM(t);return e.find(e=>oM(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 oT(),n=e.serial,a=oM(s),t.find(e=>"android"===e.platform&&"emulator"===e.kind&&(!n||e.id===n)&&oM(e.name)===a));if(!d){let t=["-avd",s];e.headless&&t.push("-no-window","-no-audio"),ed("emulator",t)}let u=d??await oF({avdName:s,serial:e.serial,timeoutMs:i}),c=Math.max(1e3,i-(Date.now()-l));await oB(u.id,c);let p=(await oT()).find(e=>e.id===u.id);return p?{...p,name:s,booted:!0}:{...u,name:s,booted:!0}}async function oB(e,t=6e4){let n,a=rv.fromTimeoutMs(t),r=Math.max(1,Math.ceil(t/1e3)),i=!1;try{await rA(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 ok(e,Math.min(o,rb));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=rL({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=>rL({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=rL({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:r$(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 oj=/\.(?:apk|aab)$/i,oq=/^[A-Za-z_][\w]*(\.[A-Za-z_][\w]*)+$/;function oX(e){var t,n;let a=e.trim();return 0===a.length?"other":oj.test(a)?a.includes("/")||a.includes("\\")||a.startsWith(".")||a.startsWith("~")||(t=a,!oq.test(t))?"binary":"package":(n=a,oq.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 oW(e,t){let n="url"===e.kind&&e_(e.url),a=await eN({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 oH(a.installablePath);return{archivePath:a.archivePath,installablePath:a.installablePath,packageName:r.packageName,cleanup:a.cleanup}}async function oH(e){let t=o.extname(e).toLowerCase();return".apk"!==t&&".aab"!==t?{}:{packageName:await eS(e)}}let oY={settings:{type:"intent",value:"android.settings.SETTINGS"}},oK="android.intent.category.LAUNCHER",oJ="android.intent.category.LEANBACK_LAUNCHER",oZ="android.intent.category.DEFAULT",oQ="Run agent-device apps --platform android to discover the installed package name, then retry open with that exact package.";async function o0(e,t){let n=t.trim();if("package"===oX(n))return{type:"package",value:n};let a=oY[n.toLowerCase()];if(a)return a;let r=(await ep("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===r.length)return{type:"package",value:r[0]};if(r.length>1)throw new y("INVALID_ARGS",`Multiple packages matched "${t}"`,{matches:r,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:oQ})}async function o1(e,t="all"){let n=await o2(e);return("user-installed"===t?(await o4(e)).filter(e=>n.has(e)):Array.from(n)).sort((e,t)=>e.localeCompare(t)).map(e=>({package:e,name:o5(e)}))}async function o2(e){let t=new Set;for(let n of o3(e,{includeFallbackWhenUnknown:!0})){let a=await ep("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 ek(a.stdout))t.add(e)}return t}function o3(e,t={}){return"tv"===e.target?[oJ]:"mobile"===e.target?[oK]:t.includeFallbackWhenUnknown?[oK,oJ]:[oK]}async function o4(e){return eD((await ep("adb",og(e,["shell","pm","list","packages","-3"]))).stdout)}function o5(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 o8(e){let t=await o6(e,[["shell","dumpsys","window","windows"],["shell","dumpsys","window"]]);if(t)return t;let n=await o6(e,[["shell","dumpsys","activity","activities"],["shell","dumpsys","activity"]]);return n||{}}async function o6(e,t){for(let n of t){let t=eM((await ep("adb",og(e,n),{allowFailure:!0})).stdout??"");if(t)return t}return null}async function o9(e,t,n){var a,r;let i;e.booted||await oB(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 ep("adb",og(e,["shell","am","start","-W","-a","android.intent.action.VIEW","-d",o]));return}let s=await o0(e,t),l=o3(e)[0]??oK;if("intent"===s.type){if(n)throw new y("INVALID_ARGS","Activity override requires a package name, not an intent");await ep("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 ep("adb",og(e,["shell","am","start","-W","-a","android.intent.action.MAIN","-c",oZ,"-c",l,"-n",t]))}catch(t){throw await st(e,s.value,t),t}return}let d=await ep("adb",og(e,["shell","am","start","-W","-a","android.intent.action.MAIN","-c",oZ,"-c",l,"-p",s.value]),{allowFailure:!0});if(0===d.exitCode&&(a=d.stdout,r=d.stderr,i=`${a}
11
- ${r}`,!/Error:.*(?:Activity not started|unable to resolve Intent)/i.test(i)))return;let u=await sa(e,s.value);if(!u){if(!await se(e,s.value))throw o7(s.value);throw new y("COMMAND_FAILED",`Failed to launch ${s.value}`,{stdout:d.stdout,stderr:d.stderr})}await ep("adb",og(e,["shell","am","start","-W","-a","android.intent.action.MAIN","-c",oZ,"-c",l,"-n",u]))}function o7(e){return new y("APP_NOT_INSTALLED",`No package found matching "${e}"`,{package:e,hint:oQ})}async function se(e,t){let n=await ep("adb",og(e,["shell","pm","path",t]),{allowFailure:!0}),a=`${n.stdout}
12
- ${n.stderr}`;return!!(0===n.exitCode&&/\bpackage:/i.test(a))||(sn(a),!1)}async function st(e,t,n){if(sn(n instanceof y?`${String(n.details?.stdout??"")}
13
- ${String(n.details?.stderr??"")}`:"")||!await se(e,t))throw o7(t)}function sn(e){return/\bunknown package\b/i.test(e)||/\bpackage .* (?:was|is) not found\b/i.test(e)||/\bpackage .* does not exist\b/i.test(e)||/\bcould not find package\b/i.test(e)}async function sa(e,t){for(let n of Array.from(new Set(o3(e,{includeFallbackWhenUnknown:!0})))){let a=await ep("adb",og(e,["shell","cmd","package","resolve-activity","--brief","-a","android.intent.action.MAIN","-c",n,t]),{allowFailure:!0});if(0!==a.exitCode)continue;let r=function(e){let t=e.split("\n").map(e=>e.trim()).filter(Boolean);for(let e=t.length-1;e>=0;e-=1){let n=t[e];if(n.includes("/"))return n.split(/\s+/)[0]}return null}(a.stdout);if(r)return r}return null}async function sr(e){e.booted||await oB(e.id)}async function si(e,t){if("settings"===t.trim().toLowerCase())return void await ep("adb",og(e,["shell","am","force-stop","com.android.settings"]));let n=await o0(e,t);if("intent"===n.type)throw new y("INVALID_ARGS","Close requires a package name, not an intent");await ep("adb",og(e,["shell","am","force-stop",n.value]))}async function so(e,t){let n=await o0(e,t);if("intent"===n.type)throw new y("INVALID_ARGS","App uninstall requires a package name, not an intent");let a=await ep("adb",og(e,["uninstall",n.value]),{allowFailure:!0});if(0!==a.exitCode){let e=`${a.stdout}
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 ss=null;async function sl(){let e=`${process.env.PATH??""}::${process.env.AGENT_DEVICE_BUNDLETOOL_JAR??""}`;if(ss?.key===e)return ss.invocation;if(await eh("bundletool")){let t={cmd:"bundletool",prefixArgs:[]};return ss={key:e,invocation:t},t}let t=await ef(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 ss={key:e,invocation:n},n}async function sd(e){let t=await sl();await ep(t.cmd,[...t.prefixArgs,...e])}async function su(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 sd(["build-apks","--bundle",t,"--output",i,"--mode",l]),await sd(["install-apks","--apks",i,"--device-id",e.id])}finally{await r.rm(a,{recursive:!0,force:!0})}}async function sc(e,t){".aab"===o.extname(t).toLowerCase()?await su(e,t):await ep("adb",og(e,["install","-r",t]))}async function sp(e){return new Set((await ep("adb",og(e,["shell","pm","list","packages"]))).stdout.split("\n").map(e=>e.replace("package:","").trim()).filter(Boolean))}async function sf(e,t){let n=Array.from(await sp(e)).filter(e=>!t.has(e));if(1===n.length)return n[0]}async function sh(e,t){e.booted||await oB(e.id),await sc(e,t)}async function sm(e,t,n){let a=n?void 0:await sp(e);return await sh(e,t),n??(a?await sf(e,a):void 0)}async function sw(e,t){e.booted||await oB(e.id);let n=await oW({kind:"path",path:t});try{let t=await sm(e,n.installablePath,n.packageName),a=t?o5(t):void 0;return{archivePath:n.archivePath,installablePath:n.installablePath,packageName:t,appName:a,launchTarget:t}}finally{await n.cleanup()}}async function sg(e,t,n){e.booted||await oB(e.id);let{package:a}=await so(e,t),r=await oW({kind:"path",path:n},{resolveIdentity:!1});try{return await sh(e,r.installablePath),{package:a}}finally{await r.cleanup()}}function sy(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 sb(e){if(0===e.length)return null;let t=[...e].sort((e,t)=>e-t);return t[Math.floor(t.length/2)]??null}function sv(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 sA(e,t){return{start:e.y-t.y,size:e.height,crossSize:e.width}}async function sI(e,t={}){let n=await sx(e,t),a=n.xml;if(!t.interactiveOnly){let r=X(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 s_(e,r.nodes),r.nodes),{...r,androidSnapshot:n.metadata}}let r=W(a),i=ee(r,800,{...t,interactiveOnly:!1}),o=ee(r,800,t),s=await s_(e,i.nodes);sC(s,i,o),0===s.size&&sC(function(e){if(0===e.length)return new Map;let{hintedContainers:t}=e5(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 sx(e,t){let n=await sS(t.helperArtifact);if(n.artifact)try{var a;let r=t.helperAdb??(a=e,async(e,t)=>await ep("adb",og(a,e),t)),i=await z({adb:r,artifact:n.artifact,installPolicy:t.helperInstallPolicy,timeoutMs:3e4}),o=await Y({adb:r,packageName:n.artifact.manifest.packageName,instrumentationRunner:n.artifact.manifest.instrumentationRunner,waitForIdleTimeoutMs:500,timeoutMs:8e3,commandTimeoutMs:13e3});return{xml:o.xml,metadata:{backend:"android-helper",helperVersion:n.artifact.manifest.version,helperApiVersion:o.metadata.helperApiVersion,installReason:i.reason,waitForIdleTimeoutMs:o.metadata.waitForIdleTimeoutMs,timeoutMs:o.metadata.timeoutMs,maxDepth:o.metadata.maxDepth,maxNodes:o.metadata.maxNodes,rootPresent:o.metadata.rootPresent,captureMode:o.metadata.captureMode,windowCount:o.metadata.windowCount,nodeCount:o.metadata.nodeCount,helperTruncated:o.metadata.truncated,elapsedMs:o.metadata.elapsedMs}}}catch(t){return await sN(e,g(t).message)}return await sN(e,n.fallbackReason)}async function sS(e){if(e)return{artifact:e};let t=et(),n=o.join(en(),"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 sN(e,t){return{xml:await sM(e),metadata:{backend:"uiautomator-dump",...t?{fallbackReason:t}:{}}}}async function s_(e,t){if(!t.some(e=>Q(e.type)))return new Map;let n=await sO(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(Q(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=>sA(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||!Q(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=>sA(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=sb(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(!sv(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(!sv(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?sb(o):i.length>0?sb(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 sM(e){try{return await rI(()=>sk(e),{shouldRetry:sE})}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 sk(e){var t,n,a;let r,i,o=await ep("adb",og(e,["exec-out","uiautomator","dump","/dev/tty"]),{allowFailure:!0,timeoutMs:8e3}),s=sD(o.stdout,o.stderr);if(s)return s;let l="/sdcard/window_dump.xml",d=await ep("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 ep("adb",og(e,["shell","cat",u])),p=sD(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 sD(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 sE(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 sO(e){try{let t=await ep("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 sC(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 sR(e,t,n){await ep("adb",og(e,["shell","input","tap",String(t),String(n)]))}async function sP(e,t,n,a,r,i=250){await ep("adb",og(e,["shell","input","swipe",String(t),String(n),String(a),String(r),String(i)]))}async function sT(e){await ep("adb",og(e,["shell","input","keyevent","4"]))}async function sL(e){await ep("adb",og(e,["shell","input","keyevent","3"]))}async function s$(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 ep("adb",og(e,["shell","settings","put","system","accelerometer_rotation","0"])),await ep("adb",og(e,["shell","settings","put","system","user_rotation",n]))}async function sF(e){await ep("adb",og(e,["shell","input","keyevent","187"]))}async function sU(e,t,n,a=800){await ep("adb",og(e,["shell","input","swipe",String(t),String(n),String(t),String(n),String(a)]))}async function sG(e,t,n=0){n>0&&Array.from(t).length>1?await sH(e,t,1,n):await sV(e,t)}async function sV(e,t){let n=sY(t);if(!n||"ok"!==await sK(e,t))try{let n=t.replace(/ /g,"%s");await ep("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 sB(e,t,n){await sR(e,t,n)}async function sj(e,t,n,a,r=0){let i=Array.from(a).length,o=sY(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 sB(e,t,n);let s=(d=i+o.clearPadding,u=o.minClear,Math.max(u,Math.min(o.maxClear,d)));if(await sJ(e,s),"input_text"===o.strategy)await sG(e,a,r);else if("clipboard_paste"===o.strategy){if("ok"!==await sK(e,a))continue}else await sH(e,a,1,r>0?r:15);let c=await sq(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 sq(e,t,n,a){let r=null;for(let i of[0,150,350])if(i>0&&await ey(i),function(e,t){if(e===t)return!0;let n=sX(e),a=sX(t);return!!n&&!!a&&(!!(n===a||n.includes(a))||a.includes(n)&&n.length>=Math.max(4,Math.floor(.8*a.length)))}(r=await sZ(e,t,n),a))return{ok:!0,actual:r};return{ok:!1,actual:r}}function sX(e){return(e??"").replace(/\s+/g," ").trim()}async function sz(e,t,n){let a=await sW(e),r=sy({direction:t,amount:n?.amount,pixels:n?.pixels,referenceWidth:a.width,referenceHeight:a.height});return await ep("adb",og(e,["shell","input","swipe",String(r.x1),String(r.y1),String(r.x2),String(r.y2),"300"])),r}async function sW(e){let t=(await ep("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 sH(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 sV(e,n),a>0&&t+r<i.length&&await ey(a)}}function sY(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 sK(e,t){let n=await ep("adb",og(e,["shell","cmd","clipboard","set","text",t]),{allowFailure:!0});return 0!==n.exitCode?"failed":ob(n.stdout,n.stderr)?"unsupported":0===(await ep("adb",og(e,["shell","input","keyevent","KEYCODE_PASTE"]),{allowFailure:!0})).exitCode||0===(await ep("adb",og(e,["shell","input","keyevent","279"]),{allowFailure:!0})).exitCode?"ok":"failed"}async function sJ(e,t){let n=Math.max(0,t);await ep("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 ep("adb",og(e,["shell","input","keyevent",...Array(a).fill("KEYCODE_DEL")]),{allowFailure:!0})}}async function sZ(e,t,n){let a,r=await sM(e),i=/<node\b[^>]*>/g,o=null,s=null,l=null;for(;null!==(a=i.exec(r));){let e=H(a[0]),r=K(e.bounds);if(!r)continue;let i=e.className??"",d=(e.text??"").replace(/&quot;/g,'"').replace(/&apos;/g,"'").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&amp;/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&&sQ(i)){(!o||c<=o.area)&&(o={text:d,area:c});continue}if(p&&sQ(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 sQ(e){let t=e.toLowerCase();return t.includes("edittext")||t.includes("textfield")}async function s0(e){let t=await ep("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 s1(e){let t=await s0(e),n=t,a=0;for(;n.visible&&a<2;)await ep("adb",og(e,["shell","input","keyevent","111"])),a+=1,await ey(120),n=await s0(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 s2(e){let t,n;return(n=(t=(await s4(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 s3(e,t){await s4(e,["shell","cmd","clipboard","set","text",t],"write")}async function s4(e,t,n){let a=await ep("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 s5=["camera","microphone","photos","contacts","contacts-limited","notifications","calendar","location","location-always","media-library","motion","reminders","siri"];function s8(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 s6(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: ${s5.join("|")}`)}function s9(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 s7=["window_animation_scale","transition_animation_scale","animator_duration_scale"];async function le(e,t,n,a,r){switch(t.toLowerCase()){case"wifi":{let t=ln(n);await ep("adb",og(e,["shell","svc","wifi",t?"enable":"disable"]));return}case"airplane":{let t=ln(n);await ep("adb",og(e,["shell","settings","put","global","airplane_mode_on",t?"1":"0"])),await ep("adb",og(e,["shell","am","broadcast","-a","android.intent.action.AIRPLANE_MODE","--ez","state",t?"true":"false"]));return}case"location":{let t=ln(n);await ep("adb",og(e,["shell","settings","put","secure","location_mode",t?"3":"0"]));return}case"animations":{let t=ln(n)?"1":"0";for(let n of s7)await ep("adb",og(e,["shell","settings","put","global",n,t]));return{scale:t,keys:[...s7]}}case"appearance":{let t=await la(e,n);await ep("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 lt(e,t);return}case"permission":{if(!a)throw new y("INVALID_ARGS","permission setting requires an active app in session");let t=s8(n),i=function(e,t){let n=s6(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 li(e,a,t,i);let o="grant"===t?"grant":"revoke";if("photos"===i.type)return void await lr(e,a,o);await ep("adb",og(e,["shell","pm",o,a,i.value]));return}default:throw new y("INVALID_ARGS",`Unsupported setting: ${t}`)}}async function lt(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 ep("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 ln(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 la(e,t){let n=s9(t);if("toggle"!==n)return n;let a=await ep("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 lr(e,t,n){let a=await lo(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 ep("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 li(e,t,n,a){"grant"===n?await ep("adb",og(e,["shell","pm","grant",t,a.permission]),{allowFailure:!0}):(await ep("adb",og(e,["shell","pm","revoke",t,a.permission]),{allowFailure:!0}),"reset"===n&&(await ep("adb",og(e,["shell","pm","clear-permission-flags",t,a.permission,"user-set"]),{allowFailure:!0}),await ep("adb",og(e,["shell","pm","clear-permission-flags",t,a.permission,"user-fixed"]),{allowFailure:!0}))),await ep("adb",og(e,["shell","appops","set",t,a.appOps,"grant"===n?"allow":"deny"===n?"deny":"default"]))}async function lo(e){let t=await ep("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 ls(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 ep("adb",og(e,r)),{action:a,extrasCount:s}}let ll=Buffer.from([137,80,78,71,13,10,26,10]);async function ld(e,t){await lu(e);try{await ey(1e3),await lp(e,t)}finally{await lc(e).catch(()=>{})}}async function lu(e){let t=t=>ep("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 lc(e){await ep("adb",og(e,["shell","am broadcast -a com.android.systemui.demo -e command exit"]),{allowFailure:!0})}async function lp(e,t){let n=await ep("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(ll);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+ll.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 lf=eb(process.env.AGENT_DEVICE_IOS_BOOT_TIMEOUT_MS,ry,5e3),lh=eb(process.env.AGENT_DEVICE_IOS_SIMCTL_LIST_TIMEOUT_MS,rg,1e3),lm=eb(process.env.AGENT_DEVICE_IOS_APP_LAUNCH_TIMEOUT_MS,3e4,5e3),lw=eb(process.env.AGENT_DEVICE_IOS_DEVICECTL_TIMEOUT_MS,2e4,1e3),lg=eb(process.env.AGENT_DEVICE_IOS_SIMULATOR_FOCUS_TIMEOUT_MS,1e4,1e3),ly=eb(process.env.AGENT_DEVICE_IOS_SIMULATOR_SCREENSHOT_TIMEOUT_MS,2e4,1e3),lb=eb(process.env.AGENT_DEVICE_IOS_RUNNER_SCREENSHOT_COPY_TIMEOUT_MS,2e4,1e3),lv=rw(process.env.AGENT_DEVICE_IOS_SIMULATOR_SCREENSHOT_RUNNER_FALLBACK);async function lA(e,t){let n=["devicectl",...e],a=await ep("xcrun",n,{allowFailure:!0,timeoutMs:lw});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:lN(r,i)??lS})}async function lI(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 ep("xcrun",a,{allowFailure:!0,timeoutMs:lw});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:lN(t,n)??lS})}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 lx(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 ep("xcrun",n,{allowFailure:!0,timeoutMs:lw});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:lN(t,r)??lS})}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 lS="Ensure the iOS device is unlocked, trusted, and available in Xcode > Devices, then retry.";function lN(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 l_(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 lM(e,t){let n=await ep("xcrun",rz(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 ep("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 ep("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 lk(e,t){if("simulator"!==e.kind)throw new y("UNSUPPORTED_OPERATION",`${t} is only supported on iOS simulators`)}async function lD(){await ep("open",["-a","Simulator"],{allowFailure:!0,timeoutMs:lg})}async function lE(e){let t,n;if("simulator"!==e.kind||"Booted"===await lC(e))return;let a=rv.fromTimeoutMs(lf);try{await rA(async({deadline:a})=>{if(a?.isExpired())throw new y("COMMAND_FAILED","iOS simulator boot deadline exceeded",{timeoutMs:lf});let r=Math.max(1e3,a?.remainingMs()??lf),i=await ep("xcrun",rz(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 ep("xcrun",rz(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 lC(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=rL({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=>rL({error:e,stdout:n?.stdout??t?.stdout,stderr:n?.stderr??t?.stderr,context:{platform:"ios",phase:"boot"}})})}catch(i){let r=rL({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:lf,elapsedMs:a.elapsedMs(),reason:r,hint:r$(r),boot:t,bootstatus:n})}await lD()}async function lO(e){let t=rz(e,["shutdown",e.id]),n=await ep("xcrun",t,{allowFailure:!0,timeoutMs:15e3});return{success:0===n.exitCode,exitCode:n.exitCode,stdout:String(n.stdout??""),stderr:String(n.stderr??"")}}async function lC(e){let t="string"==typeof e?e:e.id,n="string"==typeof e?rX(["list","devices","-j"]):rz(e,["list","devices","-j"]),a=await ep("xcrun",n,{allowFailure:!0,timeoutMs:lh});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 lR(e,t){try{let n=await ep("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,ip(ic(n),(e,t)=>{void 0===i&&e===a&&"string"===t.name&&(i=t.text??void 0)}),i}catch{return}}async function lP(e,t){if("url"===e.kind&&!e_(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 eN({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||e_(e.url),signal:t?.signal}),a=await lL(n.installablePath,t),r=await lT(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 lT(e){let t=o.join(e,"Info.plist"),[n,a,r]=await Promise.all([lR(t,"CFBundleIdentifier"),lR(t,"CFBundleDisplayName"),lR(t,"CFBundleName")]);return{bundleId:n,appName:a??r}}async function lL(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 ep("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 l$(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(lF).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(lF).join(", ")}`)}catch(e){throw await a(),e}}async function l$(e){await Promise.all(e.map(async e=>{if(e.bundleId&&e.appName)return;let t=await lT(e.installPath);e.bundleId=e.bundleId??t.bundleId,e.appName=e.appName??t.appName}))}function lF(e){let t=e.bundleId??e.appName;return t?`${e.bundleName}.app (${t})`:`${e.bundleName}.app`}function lU(e,t){return"user-installed"===t?e.filter(e=>!e.bundleId.startsWith("com.apple.")):e}let lG={settings:"com.apple.systempreferences"},lV=/^[a-z0-9-]+(?:\.[a-z0-9-]+)+$/;function lB(e,t){let n=["-b",e];return t&&n.push(t),n}async function lj(e){for(let t of[o.join(e,"Contents","Info.plist"),o.join(e,"Info.plist")]){let[e,n,a]=await Promise.all([lR(t,"CFBundleIdentifier"),lR(t,"CFBundleDisplayName"),lR(t,"CFBundleName")]);if(e||n||a)return{bundleId:e,appName:n??a}}return{}}async function lq(e){let t=e.trim(),n=lG[t.toLowerCase()];if(n)return n;if(lV.test(t))return t;let a=(await lJ("all")).filter(e=>e.name.toLowerCase()===t.toLowerCase());if(1===a.length)return 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 lX(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 lq(t);await ep("open",lB(e,a));return}let r=t.trim();if(ov(r))return void await ep("open",[r]);let i=n?.appBundleId??await lq(r);await ep("open",lB(i))}async function lz(e,t){let n=await lq(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 lW(){let e=await ep("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 lH(e){let t=await ep("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 lY(){let e=await ep("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 lK(e){let t=s9(e),n="toggle"===t?!await lY():"dark"===t,a=`tell application "System Events" to tell appearance preferences to set dark mode to ${n?"true":"false"}`,r=await ep("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 lJ(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 ep("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 lU((await Promise.all(Array.from(n).map(async e=>{let t=await lj(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 lZ=["--time","9:41","--dataNetwork","wifi","--wifiMode","active","--wifiBars","3","--batteryState","charged","--batteryLevel","100"],lQ={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"},l0={1:"searching",2:"failed",3:"active"},l1={0:"notSupported",1:"searching",2:"failed",3:"active"};function l2(e,t,n){return ep("xcrun",rz(e,t),n)}async function l3(e,t){var n,a;let r;await l5(e),t&&await l8(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 l4(e){let t=await l2(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=lQ[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=l0[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=l1[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 l5(e){await l2(e,["status_bar",e.id,"clear"])}async function l8(e,t){0!==t.length&&await l2(e,["status_bar",e.id,"override",...t])}function l6(e,t,n){es({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 l9(e,t,n){return ep("xcrun",rz(e,t),n)}let l7={ensureBooted:lE,prepareStatusBarForScreenshot:async function e(e){let t=null,n=!1;try{t=await l4(e),n=!0}catch(t){l6(e,"snapshot_failed",t)}try{await l5(e),await l8(e,lZ)}catch(t){l6(e,"prepare_failed",t)}return async()=>{await l3(e,n?t:null)}},captureWithRetry:dn,runnerFallbackEnabled:lv,captureWithRunner:da,shouldFallbackToRunner:dc};async function de(e,t,n,a){if("macos"===e.platform)return void await da(e,t,n,a);if("simulator"===e.kind)return void await dt(e,t,n,a);try{await lA(["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}
22
- ${n}
23
- ${a}`.toLowerCase();return r.includes("unknown option '--device'")||r.includes("unknown subcommand")&&r.includes("screenshot")||r.includes("unrecognized subcommand")&&r.includes("screenshot")}(t))throw t;dl(e,"devicectl_screenshot",t)}await da(e,t,n,a)}async function dt(e,t,n,a,r=l7){if("simulator"!==e.kind)throw new y("UNSUPPORTED_OPERATION","Simulator screenshot fallback flow supports only iOS simulators");let i="object"==typeof a&&null!==a?a:r;await i.ensureBooted(e);let o=async()=>{};try{o=await i.prepareStatusBarForScreenshot(e)}catch(t){dd(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,a;throw s=e,l=t,n=du(l),es({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}}),a=(d=t)instanceof y?d:new y("COMMAND_FAILED","Failed to capture iOS screenshot: simulator screenshot retries exhausted",void 0,d),new y(a.code,a.message,{...a.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."},a)}dl(e,"simctl_screenshot",t)}await i.captureWithRunner(e,t,n,"boolean"==typeof a?a:void 0)}finally{await o().catch(t=>dd(e,"restore_failed",t))}}async function dn(e,t){let n=rv.fromTimeoutMs(ly);await rA(async({deadline:n})=>{await l9(e,["io",e.id,"screenshot",t],{timeoutMs:Math.max(1e3,n?.remainingMs()??ly)})},{maxAttempts:5,baseDelayMs:1e3,maxDelayMs:5e3,jitter:.2,shouldRetry:e=>dc(e)},{deadline:n,phase:"ios_simulator_screenshot"})}async function da(e,t,n,a){let i=(await i5(e,{command:"screenshot",appBundleId:n,fullscreen:a})).message;if(!i)throw new y("COMMAND_FAILED","Failed to capture iOS screenshot: runner returned no file path");"macos"===e.platform?await r.copyFile(i,t):"simulator"===e.kind?await di(e,i,t):await dr(e,i,t)}async function dr(e,t,n){let a=rv.fromTimeoutMs(lb),r={exitCode:1,stdout:"",stderr:""};for(let i of iN)if(0===(r=await ep("xcrun",["devicectl","device","copy","from","--device",e.id,"--source",t,"--destination",n,"--domain-type","appDataContainer","--domain-identifier",i],{allowFailure:!0,timeoutMs:ds(a,lb,"runner screenshot copy")})).exitCode)return;let i=r.stderr.trim()||r.stdout.trim()||`devicectl exited with code ${r.exitCode}`;throw new y("COMMAND_FAILED",`Failed to capture iOS screenshot: ${i}`)}async function di(e,t,n){let a=rv.fromTimeoutMs(lb),i="Unable to locate runner container for simulator screenshot";for(let s of iN){let l=await l9(e,["get_app_container",e.id,s,"data"],{allowFailure:!0,timeoutMs:ds(a,lb,"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),a=t.trim();if(!a)return[];let r=[],i=new Set,s=e=>{let t=o.normalize(e);i.has(t)||(i.add(t),r.push(t))},l=a.replace(/^\/+/,""),d=l.replace(/\\/g,"/");if(l&&s(o.join(n,l)),o.isAbsolute(a)&&s(o.normalize(a)),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(a);return u&&s(o.join(n,"tmp",u)),r}(d,t))try{await r.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 ds(e,t,n){let a=e.remainingMs();if(a>0)return a;throw new y("COMMAND_FAILED",`iOS ${n} timed out after ${t}ms`,{timeoutMs:t,step:n})}function dl(e,t,n){let a=du(n);es({level:"warn",phase:"ios_screenshot_fallback",data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,from:t,to:"runner",...a}})}function dd(e,t,n){es({level:"warn",phase:`ios_screenshot_status_bar_${t}`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,...du(n)}})}function du(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 dc(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=Array.isArray(t.args)?t.args.filter(e=>"string"==typeof e).join(" "):"",i=`${e.message}
24
- ${n}
25
- ${a}
26
- ${r}`.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 dp={settings:"com.apple.Preferences"},df=null;function dh(e,t,n){return ep("xcrun",rz(e,t),n)}function dm(e){return e.includes("not installed")||e.includes("not found")||e.includes("no such file")}async function dw(e,t){if("macos"===e.platform)return await lq(t);let n=t.trim();if(n.includes("."))return n;let a=dp[n.toLowerCase()];if(a)return a;let r=("simulator"===e.kind?await dD(e):await lI(e,"all")).filter(e=>e.name.toLowerCase()===n.toLowerCase());if(1===r.length)return r[0].bundleId;if(r.length>1)throw new y("INVALID_ARGS",`Multiple apps matched "${t}"`,{matches:r});throw new y("APP_NOT_INSTALLED",`No app found matching "${t}"`)}async function dg(e,t,n){if("macos"===e.platform)return void await lX(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");if("simulator"===e.kind){await lE(e),await dh(e,["openurl",e.id,a]);return}let r=oA(n?.appBundleId??await dw(e,t),a);if(!r)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 dF(e,r,{payloadUrl:a});return}let r=t.trim();if(ov(r)){if("simulator"===e.kind){await lE(e),await dh(e,["openurl",e.id,r]);return}let t=oA(n?.appBundleId,r);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 dF(e,t,{payloadUrl:r});return}let i=n?.appBundleId??await dw(e,t);"simulator"===e.kind?await d$(e,i):await dF(e,i)}async function dy(e){"macos"===e.platform||"simulator"!==e.kind||"Booted"!==await lC(e)&&await lE(e)}async function db(e,t){if("macos"===e.platform)return void await lz(e,t);let n=await dw(e,t);if("simulator"===e.kind){await lE(e);let t=rz(e,["terminate",e.id,n]),a=await ep("xcrun",t,{allowFailure:!0});if(0!==a.exitCode){if(a.stderr.toLowerCase().includes("found nothing to terminate"))return;throw new y("COMMAND_FAILED",`xcrun exited with code ${a.exitCode}`,{cmd:"xcrun",args:t,stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode})}return}await lA(["device","process","terminate","--device",e.id,n],{action:"terminate iOS app",deviceId:e.id})}async function dv(e,t){let n=await dw(e,t);if("simulator"!==e.kind){let t=["devicectl","device","uninstall","app","--device",e.id,n],a=await ep("xcrun",t,{allowFailure:!0,timeoutMs:lw});if(0!==a.exitCode){let r=String(a.stdout??""),i=String(a.stderr??"");if(!dm(`${r}
27
- ${i}`.toLowerCase()))throw new y("COMMAND_FAILED",`Failed to uninstall iOS app ${n}`,{cmd:"xcrun",args:t,exitCode:a.exitCode,stdout:r,stderr:i,deviceId:e.id,hint:lN(r,i)??lS})}return{bundleId:n}}await lE(e);let a=await dh(e,["uninstall",e.id,n],{allowFailure:!0});if(0!==a.exitCode&&!dm(`${a.stdout}
28
- ${a.stderr}`.toLowerCase()))throw new y("COMMAND_FAILED",`simctl uninstall failed for ${n}`,{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});return{bundleId:n}}async function dA(e,t,n){let a=await lP({kind:"path",path:t},n);try{return await dx(e,a.installablePath),{archivePath:a.archivePath,installablePath:a.installablePath,bundleId:a.bundleId,appName:a.appName,launchTarget:a.bundleId}}finally{await a.cleanup()}}async function dI(e,t,n){let{bundleId:a}=await dv(e,t);return await dA(e,n,{appIdentifierHint:t}),{bundleId:a}}async function dx(e,t){"simulator"!==e.kind?await lA(["device","install","app","--device",e.id,t],{action:"install iOS app",deviceId:e.id}):(await lE(e),await dh(e,["install",e.id,t]))}async function dS(e){if("macos"===e.platform)return await lW();lk(e,"clipboard"),await lE(e);let t=await dh(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 dN(e,t){if("macos"===e.platform)return void await lH(t);lk(e,"clipboard"),await lE(e);let n=await dh(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 d_(e,t,n){lk(e,"push"),await lE(e);let a=await r.mkdtemp(o.join(s.tmpdir(),"agent-device-ios-push-")),i=o.join(a,"payload.apns");try{await r.writeFile(i,`${JSON.stringify(n)}
29
- `,"utf8"),await dh(e,["push",e.id,t,i])}finally{await r.rm(a,{recursive:!0,force:!0})}}async function dM(e,t,n,a,r){if("macos"===e.platform){let e=t.toLowerCase();if("appearance"===e)return void await lK(n);if("permission"===e){let e=s8(n);if("deny"===e)throw new y("INVALID_ARGS",ej("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.")}(r?.permissionTarget);return await oc(e,t)}throw new y("INVALID_ARGS",ej(t))}lk(e,"settings"),await lE(e);let i=t.toLowerCase();switch(i){case"wifi":{let t=dE(n);await dh(e,["status_bar",e.id,"override","--wifiMode",t?"active":"failed"]);return}case"airplane":return void(dE(n)?await dh(e,["status_bar",e.id,"override","--dataNetwork","hide","--wifiMode","failed","--wifiBars","0","--cellularMode","failed","--cellularBars","0","--operatorName",""]):await dh(e,["status_bar",e.id,"clear"]));case"location":{let t=dE(n);if(!a)throw new y("INVALID_ARGS","location setting requires an active app in session");await dh(e,["privacy",e.id,t?"grant":"revoke","location",a]);return}case"faceid":case"touchid":{let t=dC[i],a=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 dL(e,a,{settingName:i,label:t.label,modalityAliases:t.modalityAliases});return}case"appearance":{let t=await dO(e,n);await dh(e,["ui",e.id,"appearance",t]);return}case"permission":{var o;if(!a)throw new y("INVALID_ARGS","permission setting requires an active app in session");let t="deny"===(o=s8(n))?"revoke":o,i=function(e,t){let n=s6(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.`)}(r?.permissionTarget,r?.permissionMode);await dR(e,t,i,a);return}default:throw new y("INVALID_ARGS",`Unsupported setting: ${t}`)}}async function dk(e,t="all"){return"macos"===e.platform?await lJ(t):"simulator"===e.kind?lU(await dD(e),t):await lI(e,t)}async function dD(e){let t=(await dh(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 ep("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 dE(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 dO(e,t){let n=s9(t);if("toggle"!==n)return n;let a=await dh(e,["ui",e.id,"appearance"],{allowFailure:!0});if(0!==a.exitCode)throw new y("COMMAND_FAILED","Failed to read current iOS appearance",{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});let r=function(e,t){let n=/\b(light|dark|unsupported|unknown)\b/i.exec(`${e}
30
- ${t}`);if(!n)return null;let a=n[1].toLowerCase();return"dark"===a?"dark":"light"===a?"light":null}(a.stdout,a.stderr);if(!r)throw new y("COMMAND_FAILED","Unable to determine current iOS appearance for toggle",{stdout:a.stdout,stderr:a.stderr});return"dark"===r?"light":"dark"}let dC={faceid:{label:"Face ID",modalityAliases:["face"]},touchid:{label:"Touch ID",modalityAliases:["finger","touch"]}};async function dR(e,t,n,a){let r=await dT(e);if(!r.has(n))throw new y("UNSUPPORTED_OPERATION",`iOS simctl privacy does not support service "${n}" on this runtime.`,{deviceId:e.id,appBundleId:a,hint:`Supported services: ${Array.from(r).sort().join(", ")}`});let i=["privacy",e.id,t,n,a],o="notifications"===n;if(!("reset"===t&&o))try{await dh(e,i);return}catch(t){if(!(o&&dP(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:a,hint:"Use reset notifications for reprompt behavior, or toggle notifications manually in Settings."})}try{await dh(e,i);return}catch(e){if(!dP(e))throw e}try{await dh(e,["privacy",e.id,"reset","all",a])}catch(t){throw new y("COMMAND_FAILED","iOS simulator blocked direct notifications reset. Fallback reset-all also failed.",{deviceId:e.id,appBundleId:a,hint:"Use reinstall to force a fresh notifications prompt, or reset simulator content and settings."},t instanceof Error?t:void 0)}}function dP(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 dT(t){let n=rB(t.simulatorSetPath),a=`${process.env.PATH??""}::${n??""}`;if(df&&e===a)return df;let r=await dh(t,["privacy","help"],{allowFailure:!0}),i=function(e){let t=new Set,n=!1;for(let a of e.split("\n")){let e=a.trim();if(!e)continue;if("service"===e){n=!0;continue}if(!n)continue;if(e.startsWith("bundle identifier"))break;let r=/^([a-z-]+)\s+-\s+/.exec(e);r&&t.add(r[1])}return t}(`${r.stdout}
31
- ${r.stderr}`);if(0===i.size)throw new y("COMMAND_FAILED","Unable to determine supported simctl privacy services",{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode,hint:"Run `xcrun simctl privacy help` manually to verify available services for this runtime."});return df=i,e=a,i}async function dL(e,t,n){let a=function(e,t,n){let a=n.length>0?n:["face"];switch(t){case"match":return a.flatMap(t=>[["biometric",e,"match",t],["biometric","match",e,t]]);case"nonmatch":return a.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),r=[];for(let t of a){let n=rz(e,t),a=await ep("xcrun",n,{allowFailure:!0});if(0===a.exitCode)return;r.push({args:n,stderr:a.stderr,stdout:a.stdout,exitCode:a.exitCode})}let i=r.map(e=>({args:e.args.join(" "),exitCode:e.exitCode,stderr:e.stderr.slice(0,400)}));if(r.length>0&&r.every(e=>{var t,n;let a;return t=e.stdout,n=e.stderr,(a=`${t}
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 d$(e,t){await lE(e);let n=0,a=rv.fromTimeoutMs(lm);try{await rA(async({deadline:n})=>{var a;if(n?.isExpired())throw new y("COMMAND_FAILED","App launch deadline exceeded",{timeoutMs:lm});let r=(a=["launch",e.id,t],rz(e,a)),i=await ep("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=>!!l_(e)&&(n+=1)<3},{deadline:a})}catch(n){if(l_(n)){var r;let a=(r=await lM(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 dF(e,t,n){let a=["device","process","launch","--device",e.id,t];n?.payloadUrl&&a.push("--payload-url",n.payloadUrl),await lA(a,{action:"launch iOS app",deviceId:e.id})}async function dU(e,t,n,a,r,i,o){if("tv"===t.target)return dB(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 dG(e,t,n,a),l=sy({direction:r,amount:i?.amount,pixels:i?.pixels,referenceWidth:s.referenceWidth,referenceHeight:s.referenceHeight});return dB(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 dG(e,t,n,a){let r=await e(t,{command:"interactionFrame",appBundleId:n.appBundleId},a),i=dV(r.x),o=dV(r.y),s=dV(r.referenceWidth),l=dV(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 dV(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function dB(e,t){var n;let{x1:a,y1:r,x2:i,y2:o}={x1:dV((n=e).x),y1:dV(n.y),x2:dV(n.x2),y2:dV(n.y2)},s=dV(e.referenceWidth),l=dV(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 dq=null;async function dX(){if(dq)return dq;let e=dj();if("wayland"===e){if(await eh("ydotool"))return dq={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 eh("xdotool"))return dq={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 dz(...e){await ep("xdotool",e,{allowFailure:!1,timeoutMs:1e4})}async function dW(...e){await ep("ydotool",e,{allowFailure:!1,timeoutMs:1e4})}async function dH(e,t){let{tool:n}=await dX();"xdotool"===n?await dz("mousemove","--sync",String(e),String(t)):await dW("mousemove","--absolute","-x",String(e),"-y",String(t))}async function dY(e,t){let{tool:n}=await dX();"xdotool"===n?await dz("key","--clearmodifiers",e):await dW("key",...t)}async function dK(e,t,n,a){await dH(e,t);let{tool:r}=await dX();"xdotool"===r?await dz("click",n):await dW("click",a)}async function dJ(e,t){await dK(e,t,"1","0xC0")}async function dZ(e,t){await dK(e,t,"3","0xC1")}async function dQ(e,t){await dK(e,t,"2","0xC2")}async function d0(e,t){let{tool:n}=await dX();await dH(e,t),"xdotool"===n?await dz("click","--repeat","2","1"):(await dW("click","0xC0"),await dW("click","0xC0"))}async function d1(e,t,n=800){let{tool:a}=await dX();await dH(e,t),"xdotool"===a?(await dz("mousedown","1"),await ey(n),await dz("mouseup","1")):(await dW("click","--down","0xC0"),await ey(n),await dW("click","--up","0xC0"))}async function d2(e,t){await dJ(e,t)}async function d3(e,t,n,a,r=300){let{tool:i}=await dX();await dH(e,t),"xdotool"===i?(await dz("mousedown","1"),await dz("mousemove","--sync",String(n),String(a)),await ey(r),await dz("mouseup","1")):(await dW("click","--down","0xC0"),await dW("mousemove","--absolute","-x",String(n),"-y",String(a)),await ey(r),await dW("click","--up","0xC0"))}async function d4(e,t){let{tool:n}=await dX(),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 dz("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 dW("mousemove","--wheel","-y",t)}else{let t="left"===e?String(-a):String(a);await dW("mousemove","--wheel","-x",t)}}async function d5(e,t=0){let{tool:n}=await dX();if("xdotool"===n){let n=["type"];t>0&&n.push("--delay",String(t)),n.push("--clearmodifiers","--",e),await dz(...n)}else await dW("type","--",e)}async function d8(e,t,n,a=0){await dJ(e,t),await ey(100),await dY("ctrl+a",["29:1","30:1","30:0","29:0"]),await ey(50),await d5(n,a)}function d6(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 eh(a.command))return t={tool:a.tool,display:n};throw new y("TOOL_MISSING","wayland"===n?e.waylandError:e.x11Error)},resetCache:()=>{t=null}}}let d9=d6({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 d7(e){let{tool:t}=await d9.resolve();switch(t){case"grim":await ep("grim",[e]);break;case"scrot":await ep("scrot",[e]);break;case"import":await ep("import",["-window","root",e]);break;case"gnome-screenshot":await ep("gnome-screenshot",["-f",e])}}async function ue(e){if(e.includes("://")||e.startsWith("/"))return void await ep("xdg-open",[e]);if(await eh(e)){ep(e,[],{allowFailure:!0}).catch(t=>{es({level:"warn",phase:"linux_app_launch",data:{app:e,error:String(t)}})}),await ey(500);return}await ep("xdg-open",[e],{allowFailure:!0})}async function ut(e){await eh("wmctrl")?await ep("wmctrl",["-c",e],{allowFailure:!0}):await ep("pkill",["-x",e],{allowFailure:!0})}async function un(){await dY("alt+Left",["56:1","105:1","105:0","56:0"])}async function ua(){await dY("super+d",["125:1","32:1","32:0","125:0"])}let ur=d6({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 ui(){let{tool:e}=await ur.resolve();switch(e){case"wl-clipboard":return(await ep("wl-paste",["--no-newline"],{allowFailure:!0,timeoutMs:5e3})).stdout;case"xclip":return(await ep("xclip",["-selection","clipboard","-o"],{allowFailure:!0,timeoutMs:5e3})).stdout;case"xsel":return(await ep("xsel",["--clipboard","--output"],{allowFailure:!0,timeoutMs:5e3})).stdout}}async function uo(e){let{tool:t}=await ur.resolve();switch(t){case"wl-clipboard":await ep("wl-copy",["--",e],{allowFailure:!1,timeoutMs:5e3});break;case"xclip":await ep("xclip",["-selection","clipboard"],{allowFailure:!1,timeoutMs:5e3,stdin:e});break;case"xsel":await ep("xsel",["--clipboard","--input"],{allowFailure:!1,timeoutMs:5e3,stdin:e})}}ur.resetCache;let us={"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"},ul="atspi-dump.py",ud=null;async function uu(e,t={}){let a;if("linux"!==process.platform)throw new y("UNSUPPORTED_PLATFORM","AT-SPI2 bridge is only available on Linux");if(!await eh("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(ud)return ud;let e=o.dirname(c(import.meta.url));for(let t=0;t<5;t++){let a=o.join(e,"src","platforms","linux",ul);if(n.existsSync(a))return ud=a,a;if(0===t){let t=o.join(e,ul);if(n.existsSync(t))return ud=t,t}e=o.dirname(e)}throw new y("TOOL_MISSING",`Cannot find ${ul}. Ensure the agent-device package is installed correctly.`)}(),"--surface",e,"--max-nodes",String(r),"--max-depth",String(i),"--max-apps",String(s)],d=await ep("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=us[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 uc(e){let t="desktop"===e?"desktop":"frontmost-app"===e||"app"===e?"frontmost-app":("menubar"===e&&es({level:"warn",phase:"linux_snapshot",data:{message:"menubar surface is not supported on Linux, falling back to desktop"}}),"desktop"),n=await uu(t);return{nodes:n.nodes,truncated:n.truncated}}function up(e){return e?.clickButton??"primary"}function uf(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 uh(e){return"primary"===e?{}:{button:e}}let um=/^[A-Za-z0-9_.:-]{1,64}$/,uw=[[0,0],[1,0],[0,1],[-1,0],[0,-1],[1,1],[-1,1],[1,-1],[-1,-1]];async function ug(e,t,n){for(let a=0;a<e;a+=1)await n(a),a<e-1&&t>0&&await ey(t)}function uy(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 ub(e){let t=uy(e,{subject:"Push payload"}),n="inline"===t.kind?t.text:await uv(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 uv(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 uA(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 uI=eb(process.env.AGENT_DEVICE_IOS_DEVICECTL_LIST_TIMEOUT_MS,8e3,500),ux=/^(iphone|ipad|ipod|appletv)/i,uS=/\b(iphone|ipad|ipod)\b/i,uN=/^appletv/i,u_=["apple tv","appletv","tvos"],uM=/^==\s*(.+?)\s*==$/,uk=/^(?<name>.+?)\s+\[(?<id>[^[\]]+)\]\s*$/;function uD(e){return(e??"").trim().toLowerCase()}function uE(e){return uD(e.hardwareProperties?.platform)}function uO(e){return e.includes("tvos")}function uC(e){let t=uD(e);return u_.some(e=>t.includes(e))}function uR(e){return[e.name??"",e.deviceProperties?.name??"",e.deviceProperties?.deviceType??""]}function uP(e){return e.hardwareProperties?.productType??e.deviceProperties?.productType??""}async function uT(e={}){let t,n,a=rB(e.simulatorSetPath),r=e.target;try{t=await ep("xcrun",rX(["list","devices","-j"],{simulatorSetPath:a}))}catch{return null}try{n=JSON.parse(t.stdout)}catch{return null}let i=uL(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 uL(e,t){let n=[];for(let[a,r]of Object.entries(e.devices))if(function(e){let t=uD(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:uO(uD(a))?"tv":"mobile",booted:"Booted"===e.state,...t?{simulatorSetPath:t}:{}});return n}function u$(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 uF(){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 ep("xcrun",["devicectl","list","devices","--json-output",e],{allowFailure:!0,timeoutMs:uI});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=uE(e);return!!(n.includes("ios")||n.includes("tvos"))||(t=uP(e),!!ux.test(t.trim())||uR(e).some(uC))}(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 uO(uE(e))?"tv":(t=uP(e),uN.test(t.trim())||uR(e).some(uC))?"tv":"mobile"}(n),booted:!0})}return t}(JSON.parse(n))}catch{return[]}finally{e&&await r.rm(e,{force:!0}).catch(()=>{})}}async function uU(){try{let e=await ep("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=uM.exec(e);if(r){n=r[1]?.trim()??null;continue}if("Devices"!==n)continue;let i=uk.exec(e),o=i?.groups?.id?.trim()??"",s=i?.groups?.name?.trim()??"";if(!o||!s)continue;let l=function(e){return uC(e)?"tv":uS.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 uG(e={}){if("darwin"!==process.platform)throw new y("UNSUPPORTED_PLATFORM","Apple tools are only available on macOS");if(!await eh("xcrun"))throw new y("TOOL_MISSING","xcrun not found in PATH");let t=rB(e.simulatorSetPath),n=await ep("xcrun",rX(["list","devices","-j"],{simulatorSetPath:t})),a=[];try{let e=JSON.parse(n.stdout);a=uL(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([uF(),uU()]);return a=u$(a,r),u$(a,i)}async function uV(){return"linux"!==process.platform?[]:[{platform:"linux",id:"local",name:l(),kind:"device",target:"desktop",booted:!0}]}async function uB(e,t,n){let a,r=!!(t.udid||t.serial||t.deviceName);try{a=await rl(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 uT({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 uj(e){let t=rr(e.platform),n=rs({simulatorSetPath:rB(e.iosSimulatorDeviceSet),platform:t,target:e.target}),a=rq(e.androidDeviceAllowlist);return await ei("resolve_target_device",async()=>{let r={platform:t,target:e.target,deviceName:e.device,udid:e.udid,serial:e.serial};if(r.target&&!r.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"===r.platform){let e=await uV();return await rl(e,r)}if("android"===r.platform){await oy();let e=await oT({serialAllowlist:a});return await rl(e,r)}if(r.platform){let e=await uG({simulatorSetPath:n});return await uB(e,r,{simulatorSetPath:n})}let i=[];try{i.push(...await oT({serialAllowlist:a}))}catch{}try{i.push(...await uG({simulatorSetPath:n}))}catch{}try{i.push(...await uV())}catch{}return await rl(i,r,{simulatorSetPath:n})},{platform:t,target:e.target})}async function uq(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)=>o9(e,t,n?.activity),openDevice:()=>sr(e),close:t=>si(e,t),tap:(t,n)=>sR(e,t,n),doubleTap:async(t,n)=>{await sR(e,t,n),await sR(e,t,n)},swipe:(t,n,a,r,i)=>sP(e,t,n,a,r,i),longPress:(t,n,a)=>sU(e,t,n,a),focus:(t,n)=>sB(e,t,n),type:(t,n)=>sG(e,t,n),fill:(t,n,a,r)=>sj(e,t,n,a,r),scroll:(t,n)=>sz(e,t,n),screenshot:t=>ld(e,t),back:t=>sT(e),home:()=>sL(e),rotate:t=>s$(e,t),appSwitcher:()=>sF(e),readClipboard:()=>s2(e),writeClipboard:t=>s3(e,t),setSetting:(t,n,a,r)=>le(e,t,n,a,r)};case"linux":return{open:e=>ue(e),openDevice:()=>Promise.resolve(),close:e=>ut(e),tap:(e,t)=>dJ(e,t),doubleTap:(e,t)=>d0(e,t),swipe:(e,t,n,a,r)=>d3(e,t,n,a,r),longPress:(e,t,n)=>d1(e,t,n),focus:(e,t)=>d2(e,t),type:(e,t)=>d5(e,t),fill:(e,t,n,a)=>d8(e,t,n,a),scroll:(e,t)=>d4(e,t),screenshot:e=>d7(e),back:()=>un(),home:()=>ua(),rotate:()=>{throw new y("UNSUPPORTED_OPERATION","rotate not supported on Linux")},appSwitcher:()=>{throw new y("UNSUPPORTED_OPERATION","appSwitcher not yet supported on Linux")},readClipboard:()=>ui(),writeClipboard:e=>uo(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 dU(i5,e,t,n,a,r)}};return{open:(t,n)=>dg(e,t,{appBundleId:n?.appBundleId,url:n?.url}),openDevice:()=>dy(e),close:t=>db(e,t),screenshot:async(t,n)=>{"macos"===e.platform&&n?.surface&&"app"!==n.surface?await ow(t,{surface:n.surface,fullscreen:n.fullscreen}):await de(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:()=>dS(e),writeClipboard:t=>dN(e,t),setSetting:(t,n,a,r)=>dM(e,t,n,a,r),...a}}default:throw new y("UNSUPPORTED_PLATFORM",`Unsupported platform: ${e.platform}`)}}(e,s);return es({level:"debug",phase:"platform_command_prepare",data:{command:t,platform:e.platform,kind:e.kind}}),await ei("platform_command",async()=>{switch(t){case"open":return uX(e,l,n,i);case"close":{let e=n[0];if(!e)return{closed:"session",...er("Closed session")};return await l.close(e),{app:e,...er(`Closed: ${e}`)}}case"press":return uz(e,l,n,i,s);case"swipe":return uW(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,...er(`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,...er(`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=nI(i?.delayMs??0,"delay-ms",0,1e4);return await l.type(t,a),{text:t,delayMs:a,...er(u4("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=nI(i?.delayMs??0,"delay-ms",0,1e4);return await l.fill(e,t,a,r),{x:e,y:t,text:a,delayMs:r,...er(u4("Filled",a))}}case"scroll":return uH(l,n,i);case"pinch":return uY(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(!um.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",...er(`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,...er(`Saved screenshot: ${e}`)}}case"back":return await l.back(i?.backMode),{action:"back",mode:i?.backMode??"in-app",...er("Back")};case"home":return await l.home(),{action:"home",...er("Home")};case"rotate":{let e=uA(n[0]);return await l.rotate(e),{action:"rotate",orientation:e,...er(`Rotated to ${e}`)}}case"app-switcher":return await l.appSwitcher(),{action:"app-switcher",...er("Opened app switcher")};case"clipboard":return uK(l,n);case"keyboard":return uJ(e,l,n,i,s);case"settings":return uZ(e,l,n,i);case"push":return uQ(e,n,i);case"snapshot":return u0(e,n,i,s);case"read":return u1(e,n,i,s);default:throw new y("INVALID_ARGS",`Unknown command: ${t}`)}},{command:t,platform:e.platform})}async function uX(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,...er("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,...er(`Opened: ${r}`)}}return await t.open(r,{activity:a?.activity,appBundleId:a?.appBundleId}),{app:r,...er(`Opened: ${r}`)}}async function uz(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=up(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,...er(u2({x:o,y:s}))}}let l=up(a);if("primary"!==l){let t=uf({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 dZ(o,s):await dQ(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,...er(u2({x:o,y:s,button:l}))}}let d=nI(a?.count??1,"count",1,200),u=nI(a?.intervalMs??0,"interval-ms",0,1e4),c=nI(a?.holdMs??0,"hold-ms",0,1e4),p=nI(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(ri(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,...er(u2({x:o,y:s}))}}return await ug(d,u,async e=>{let[n,a]=function(e,t){if(t<=0)return[0,0];let[n,a]=uw[e%uw.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}),eo({x:o,y:s,count:d,intervalMs:u,holdMs:c,jitterPx:p,doubleTap:f,...i},u2({x:o,y:s}))}async function uW(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=nI(n[4]?Number(n[4]):250,"durationMs",16,1e4),u="ios"===e.platform?Math.min(60,Math.max(16,Math.round(d))):d,c=nI(a?.count??1,"count",1,200),p=nI(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(ri(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,...er(u3(c,f))}}return await ug(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)}),eo({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},u3(c,f))}async function uH(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 eo({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 uY(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,...er(`Pinched to scale ${r}`)}}async function uK(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,...er("Clipboard updated")}}async function uJ(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 s1(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 s0(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,...er(t.dismissed?"Keyboard dismissed":"Keyboard already hidden")}}throw new y("UNSUPPORTED_OPERATION","keyboard is supported only on Android and iOS")}async function uZ(e,t,n,a){var r;let[i,o,s,l,d]=n,u="permission"===i?{permissionTarget:s,permissionMode:l}:void 0;es({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?eo({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,...er(`Updated setting: ${i}`)}}async function uQ(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 ub(r);if("ios"===e.platform)return await d_(e,a,i),{platform:"ios",bundleId:a,...er(`Pushed notification to ${a}`)};let o=await ls(e,a,i);return{platform:"android",package:a,action:o.action,extrasCount:o.extrasCount,...er(`Pushed notification to ${a}`)}}async function u0(e,t,n,a){if("linux"===e.platform){let e=await ei("snapshot_capture",async()=>await uc(n?.surface),{backend:"linux-atspi"});return{nodes:e.nodes??[],truncated:e.truncated??!1,backend:"linux-atspi"}}if("android"!==e.platform){let t=await ei("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 ei("snapshot_capture",async()=>await sI(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 u1(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 sZ(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 u2(e){return e.button&&"primary"!==e.button?`Clicked ${e.button} (${e.x}, ${e.y})`:`Tapped (${e.x}, ${e.y})`}function u3(e,t){return e<=1?"Swiped":"ping-pong"===t?`Swiped ${e} times (ping-pong)`:`Swiped ${e} times`}function u4(e,t){return`${e} ${Array.from(t).length} chars`}let u5=eb(process.env.AGENT_DEVICE_IOS_DEVICE_READY_TIMEOUT_MS,15e3,1e3);async function u8(e){if("ios"===e.platform){if("simulator"===e.kind){let{ensureBootedSimulator:t}=await Promise.resolve(eO);await t(e);return}if("device"===e.kind)return void await u6(e.id)}if("android"===e.platform){let{waitForAndroidBoot:t}=await Promise.resolve(eE);await t(e.id)}}async function u6(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(u5/1e3));try{let a=await ep("xcrun",["devicectl","device","info","details","--device",e,"--json-output",t,"--timeout",String(n)],{allowFailure:!0,timeoutMs:u5+3e3}),r=String(a.stdout??""),i=String(a.stderr??""),o=await u9(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:u7(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??u5),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?u7(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 u9(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 u7(e,t){let n=lN(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.":lS)}async function ce(e,t,n){let a=e.get(t),r=a?.device??await uj(n??{});return a||await u8(r),{session:a,device:r}}async function ct(e,t,n){let a=!e&&"ios"===t.platform;try{return await n()}finally{a&&await iZ(t.id)}}function cn(e,t,n,a){t&&e.recordAction(t,{command:n.command,positionals:n.positionals??[],flags:n.flags??{},result:a})}async function ca(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(!rh("alert",i))return rt("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=rn(t.positionals?.[1])??1e4,i=Date.now();for(;Date.now()-i<n;){try{let n=await e();return cn(a,r,t,n),{ok:!0,data:n}}catch{}await ey(300)}return rt("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 cn(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 ey(300)}throw cr(e)}let i=await op("get",s);return cn(a,r,t,i),{ok:!0,data:i}}if("wait"===o){let e=rn(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 cn(a,r,t,e),{ok:!0,data:e}}catch{}await ey(300)}return rt("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 cn(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 ey(300)}throw cr(e)}let u=await i5(i,{command:"alert",action:l,appBundleId:r?.appBundleId},d);return cn(a,r,t,u),{ok:!0,data:u}}function cr(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 ci(e,t,n,a,r){return{requestId:r??ea().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:up(t),backMode:t?.backMode,pauseMs:t?.pauseMs,pattern:t?.pattern}}async function co(e){let t,{req:n,logPath:a,sessionStore:r,session:i,device:o,parsed:s}=e,{setting:l,state:d,permissionTarget:u}=s;if(!rh("settings",o))return rt("UNSUPPORTED_OPERATION","settings is not supported on this device");if("macos"===o.platform&&"appearance"!==(t=l.trim().toLowerCase())&&"permission"!==t)return rt("INVALID_ARGS",ej(l));let c=i?.appBundleId,p="permission"===l?[l,d,u??"",n.positionals?.[3]??"",c??""]:[l,d,c??""],f=await uq(o,"settings",p,n.flags?.out,{...ci(a,n.flags,c,i?.trace?.outPath)});return cn(r,i,n,f??{setting:l,state:d}),{ok:!0,data:f??{setting:l,state:d}}}function cs(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 cl=[250,400,600];function cd(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?cf(n?.nodes??[]):void 0,routeComparable:a}}function cu(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 cc(e){e&&"android"===e.device.platform&&delete e.androidSnapshotFreshness}function cp(e){return"press"===e||"click"===e||"back"===e||"open"===e}function cf(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 ch(e){let t=cu(e.session);if(t&&"android"===e.device.platform)return await cw(e,t);let n=await cm(e);return cc(e.session),{snapshot:cv(n,cy(e)),analysis:n.analysis,androidSnapshot:n.androidSnapshot}}async function cm(e){let{device:t,session:n,flags:a,outPath:r,logPath:i,snapshotScope:o}=e;if("linux"===t.platform){let e=await uc(n?.surface);return cA({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?cA(await of(n.surface,{bundleId:"menubar"===n.surface?n.appBundleId:void 0}),{snapshotDepth:a?.snapshotDepth,snapshotInteractiveOnly:a?.snapshotInteractiveOnly,snapshotScope:o}):await uq(t,"snapshot",[],r,{...ci(i,{...a,snapshotScope:o},n?.appBundleId,n?.trace?.outPath)})}async function cw(e,t){let n=await cg(e),a=cb(n,t,e),r=0,i=t.markedAt+1500;for(let o of cl){if(!a)break;let s=i-Date.now();if(s<=0)break;await ey(Math.min(o,s)),n=await cg(e),r+=1,a=cb(n,t,e)}return a||cc(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 cg(e){let t=await cm(e);return{data:t,snapshot:cv(t,cy(e))}}function cy(e){return void 0===e.snapshotScope?e.flags:{...e.flags,snapshotScope:e.snapshotScope}}function cb(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&&cp(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=cf(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 cv(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"?cI(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 cA(e,t){var n,a;let r=e.nodes??[];return t.snapshotScope&&(r=cI(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:cx(e.filter(e=>n.has(e.index)))}(r)),"number"==typeof t.snapshotDepth&&(n=r,a=t.snapshotDepth,r=cx(n.filter(e=>(e.depth??0)<=a))),{...e,nodes:r}}function cI(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 cx(i,r)}function cx(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 cS(e,t){let n;if(!e||!e.trim().startsWith("@"))return{ok:!0,scope:e};if(!t?.snapshot)return rt("INVALID_ARGS","Ref scope requires an existing snapshot in session.");let a=j(e.trim());if(!a)return rt("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}:rt("COMMAND_FAILED",`Ref ${e} not found or has no label`)}async function cN(e){let{req:t,sessionName:n,logPath:a,sessionStore:r}=e,{session:i,device:o}=await ce(r,n,t.flags);if(!rh("snapshot",o))return rt("UNSUPPORTED_OPERATION","snapshot is not supported on this device");let s=cS(t.flags?.snapshotScope,i);return s.ok?await ct(i,o,async()=>{let e=cM({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 ck({req:t,sessionName:n,sessionStore:r,result:{nodes:l.nodes.length,truncated:l.truncated}}),{ok:!0,data:l}}):s}async function c_(e){let{req:t,sessionName:n,logPath:a,sessionStore:r}=e,{session:i,device:o}=await ce(r,n,t.flags);if(!rh("diff",o))return rt("UNSUPPORTED_OPERATION","diff is not supported on this device");let s=cS(t.flags?.snapshotScope,i);return s.ok?await ct(i,o,async()=>{let e=cM({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 ck({req:t,sessionName:n,sessionStore:r,result:{mode:"snapshot",baselineInitialized:l.baselineInitialized,summary:l.summary}}),{ok:!0,data:l}}):s}function cM(e){let{req:t,sessionName:n,logPath:a,sessionStore:r,session:i,device:o,snapshotScope:s}=e;return a9({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 ch({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:cs("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:re()})}function ck(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 cD(e){let{device:t,node:n,flags:a,appBundleId:r,traceOutPath:i,surface:o,contextFromFlags:s}=e,l=E(n),d=nx(n.rect);if(!d)return l;try{let e=await uq(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 es({level:"warn",phase:"interaction_read_fallback",data:{reason:"empty_backend_text",nodeRef:n.ref,surface:o,platform:t.platform}}),l}catch(e){return es({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 cE=[["snapshotDepth","--depth"],["snapshotScope","--scope"],["snapshotRaw","--raw"]];function cO(e,t){let n=function(e){if(!e)return[];let t=[];for(let[n,a]of cE)void 0!==e[n]&&t.push(a);return t}(t);return 0===n.length?null:rt("INVALID_ARGS",`${e} @ref does not support ${n.join(", ")}.`)}function cC(e,t){e.snapshot=t,e.snapshotScopeSource=void 0}async function cR(e,t){let n=await cP(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 cP(e){var t;if("android"!==e.device.platform||!e.appBundleId)return null;let n=await o8(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 cT(e){return"COMMAND_FAILED"===e.code&&"string"==typeof e.details?.expectedPackage&&"string"==typeof e.details?.foregroundPackage}function cL(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 c$(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 cF(e){return e.startsWith("@")?e.slice(1):e}async function cU(e){var t;let{req:n}=e;if("find"!==n.command)return null;let a=n.positionals??[];if(0===a.length)return rt("INVALID_ARGS","find requires a locator or text");let r=eg(a);if(!r.query)return rt("INVALID_ARGS","find requires a value");if(n.flags?.findFirst&&n.flags?.findLast)return rt("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 cq(e,{requireSession:!1,capability:"find"});return o.ok?await cW(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 cL(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 cG(e){let{req:t}=e;if("get"!==t.command)return null;let n=t.positionals?.[0];if("text"!==n&&"attrs"!==n)return rt("INVALID_ARGS","get only supports text or attrs");let a=await cq(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:rt("INVALID_ARGS","get requires @ref or selector expression")}}(t);if(!r.ok)return r.response;if("ref"===r.target.kind){let e=cO("get",t.flags);if(e)return e}return await cW(async()=>{let i,o=await a.runtime.selectors.get({session:e.sessionName,requestId:t.meta?.requestId,property:n,target:r.target});return cL(e.sessionStore,e.sessionName,t,function(e,t){let n=Array.isArray(e.selectorChain)?e.selectorChain:void 0,a=c$(e),r=a?.kind==="ref"?cF(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=c$(o),{...i?.kind==="ref"?{ref:cF(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 cV(e){let{req:t}=e;if("is"!==t.command)return null;let n=(t.positionals?.[0]??"").toLowerCase();if(!nr(n))return rt("INVALID_ARGS","is requires predicate: visible|hidden|exists|editable|selected|text");let{split:a}=O(t.positionals??[]);if(!a)return rt("INVALID_ARGS","is requires a selector expression");let r=a.rest.join(" ").trim();if("text"===n&&!r)return rt("INVALID_ARGS","is text requires expected text value");if("text"!==n&&a.rest.length>0)return rt("INVALID_ARGS",`is ${n} does not accept trailing values`);let i=await cq(e,{requireSession:!0,capability:"is"});if(!i.ok)return i.response;let o=await cW(async()=>{let o=await i.runtime.selectors.is({session:e.sessionName,requestId:t.meta?.requestId,predicate:n,selector:a.selectorExpression,expectedText:r});return cL(e.sessionStore,e.sessionName,t,o),function(e){let{selectorChain:t,...n}=e;return n}(o)});return await cH(e,o,`is ${n}`)}async function cB(e){let{req:t,sessionName:n,sessionStore:a}=e,r=ra(t.positionals??[]);if(!r)return rt("INVALID_ARGS","wait requires a duration or text");let{session:i,device:o}=await ce(a,n,t.flags);if("sleep"!==r.kind&&!rh("wait",o))return rt("UNSUPPORTED_OPERATION","wait is not supported on this device");let s=async()=>{let s=cj({...e,session:i,device:o}),l=await cW(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 cL(a,n,t,e),{waitedMs:e.waitedMs,..."string"==typeof e.text?{text:e.text}:{},..."string"==typeof e.selector?{selector:e.selector}:{}}});return await cH(e,l,"wait")};return"sleep"===r.kind?await s():await ct(i,o,s)}function cj(e){return a9({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&&!cu(a))return t;let m=await ch({device:r,session:a,flags:p,outPath:n.flags?.out,logPath:i??"",snapshotScope:f});return a&&(cC(a,m.snapshot),s.set(o,a)),l=h,t={snapshot:m.snapshot}},readText:async(t,o)=>({text:await cD({device:r,node:o,flags:n.flags,appBundleId:a?.appBundleId,traceOutPath:a?.trace?.outPath,surface:a?.surface,contextFromFlags:e.contextFromFlags??((e,t,n)=>ci(i??"",e,t,n))})}),findText:async(t,n)=>({found:await cX(e,n)})}}(e),artifacts:cs("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&&(cC(e.session,t.snapshot),e.sessionStore.set(e.sessionName,e.session))}},policy:re()})}async function cq(e,t){let n=e.sessionStore.get(e.sessionName);if(!n&&t.requireSession)return{ok:!1,response:rt("SESSION_NOT_FOUND","No active session. Run open first.")};let a=n?.device??await uj(e.req.flags??{});return(n||await u8(a),rh(t.capability,a))?{ok:!0,runtime:cj({...e,session:n,device:a})}:{ok:!1,response:rt("UNSUPPORTED_OPERATION",`${t.capability} is not supported on this device`)}}async function cX(e,t){let{device:n,session:a,req:r,logPath:i}=e;if("macos"===n.platform&&a?.surface&&"app"!==a.surface)return!!C((await cz(e)).nodes,t);if(ri(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 cz(e)).nodes,t)}async function cz(e){let t=await ch({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&&(cC(e.session,t.snapshot),e.sessionStore.set(e.sessionName,e.session)),t.snapshot}async function cW(e){try{return{ok:!0,data:await e()}}catch(t){let e=w(t);return rt(e.code,e.message,e.details)}}async function cH(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 cP(i)}catch{return t}return r?rt(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 cY=new Set(["snapshot","diff","wait","alert","settings"]);async function cK(e){let{req:t,sessionName:n,logPath:a,sessionStore:r}=e,i=t.command;if(!cY.has(i))return null;if("snapshot"===i)return await cN({req:t,sessionName:n,logPath:a,sessionStore:r});if("diff"===i)return t.positionals?.[0]!=="snapshot"?rt("INVALID_ARGS","diff currently supports only: diff snapshot"):await c_({req:t,sessionName:n,logPath:a,sessionStore:r});if("wait"===i)return await cB({req:t,sessionName:n,logPath:a,sessionStore:r});if("alert"===i){let{session:e,device:i}=await ce(r,n,t.flags);return await ct(e,i,async()=>await ca({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}}:rt("INVALID_ARGS",eB));if(!s.ok)return s;let{session:l,device:d}=await ce(r,n,t.flags);return await ct(l,d,async()=>await co({req:t,logPath:a,sessionStore:r,session:l,device:d,parsed:s.parsed}))}return null}export{te as DEFAULT_BATCH_MAX_STEPS,lS as IOS_DEVICECTL_DEFAULT_HINT,iN as IOS_RUNNER_CONTAINER_BUNDLE_IDS,lh as IOS_SIMCTL_LIST_TIMEOUT_MS,eq as SESSION_SURFACES,eV as SETTINGS_USAGE_OVERRIDE,iQ as abortAllIosRunnerSessions,og as adbArgs,sF as appSwitcherAndroid,cR as assertAndroidPressStayedInApp,sT as backAndroid,e4 as buildMobileSnapshotPresentation,sy as buildScrollGesturePlan,rX as buildSimctlArgs,rz as buildSimctlArgsForDevice,eW as buildSnapshotDisplayLines,cv as buildSnapshotState,uh as buttonTag,ch as captureSnapshot,cm as captureSnapshotData,oX as classifyAndroidAppTarget,rO as clearRequestCanceled,si as closeAndroidApp,db as closeIosApp,ci as context_contextFromFlags,a9 as createAgentDevice,rP as createRequestCanceledError,cs as createUnsupportedArtifactAdapter,ti as decodePng,oB as waitForAndroidBoot,s1 as dismissAndroidKeyboard,uq as dispatchCommand,cU as dispatchFindReadOnlyViaRuntime,cG as dispatchGetViaRuntime,cV as dispatchIsViaRuntime,e0 as displayNodeLabel,oy as ensureAdb,oV as ensureAndroidEmulatorBooted,u8 as ensureDeviceReady,rt as errorResponse,sj as fillAndroid,uT as findBootableIosSimulator,sB as focusAndroid,oz as formatAndroidInstalledPackageRequiredMessage,eH as formatSnapshotLine,cu as getActiveAndroidSnapshotFreshness,o8 as getAndroidAppState,s0 as getAndroidKeyboardState,sW as getAndroidScreenSize,uf as getClickButtonValidationError,rR as getRequestSignal,iY as getRunnerSessionSnapshot,cK as handleSnapshotCommands,sL as homeAndroid,o5 as inferAndroidAppName,sw as installAndroidApp,sm as installAndroidInstallablePathAndResolvePackageName,dA as installIosApp,dx as installIosInstallablePath,cT as isAndroidEscapeError,ri as isApplePlatform,rh as isCommandSupportedOnDevice,ov as isDeepLinkTarget,rw as isEnvTruthy,cp as isNavigationSensitiveAction,rC as isRequestCanceled,o1 as listAndroidApps,oT as listAndroidDevices,uG as listAppleDevices,dk as listIosApps,lI as listIosDeviceApps,lx as listIosDeviceProcesses,re as localCommandPolicy,sU as longPressAndroid,cd as markAndroidSnapshotFreshness,rE as markRequestCanceled,ro as matchesPlatformSelector,rr as normalizePlatformSelector,o9 as openAndroidApp,sr as openAndroidDevice,dg as openIosApp,dy as openIosDevice,ta as parseBatchStepsJson,uA as parseDeviceRotation,rj as parseSerialAllowlist,eX as parseSessionSurface,ra as parseWaitArgs,ic as parseXmlDocumentSync,oW as prepareAndroidInstallArtifact,lP as prepareIosInstallArtifact,sR as pressAndroid,ls as pushAndroidNotification,d_ as pushIosNotification,s2 as readAndroidClipboardText,sZ as readAndroidTextAtPoint,lR as readInfoPlistString,dS as readIosClipboardText,cD as readTextForNode,cO as refSnapshotFlagGuardResponse,rD as registerRequestAbort,sg as reinstallAndroidApp,dI as reinstallIosApp,o0 as resolveAndroidApp,rq as resolveAndroidSerialAllowlist,rs as resolveAppleSimulatorSetPathForSelector,up as resolveClickButton,od as resolveFrontmostMacOsApp,dw as resolveIosApp,oA as resolveIosDeviceDeepLinkBundleId,lN as resolveIosDevicectlHint,rB as resolveIosSimulatorDeviceSetPath,uy as resolvePayloadInput,rk as resolveRequestTrackingId,uj as resolveTargetDevice,s$ as rotateAndroid,i5 as runIosRunnerCommand,op as runMacOsAlertAction,ld as screenshotAndroid,de as screenshotIos,sz as scrollAndroid,le as setAndroidSetting,dM as setIosSetting,cC as setSessionSnapshot,lO as shutdownSimulator,lE as ensureBootedSimulator,sI as snapshotAndroid,i0 as stopAllIosRunnerSessions,iZ as stopIosRunnerSession,sP as swipeAndroid,sG as typeAndroid,tr as validateAndNormalizeBatchSteps,is as withKeyedLock,s3 as writeAndroidClipboardText,dN as writeIosClipboardText};