agent-device 0.11.15 → 0.12.0

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/760.js DELETED
@@ -1,33 +0,0 @@
1
- let e,t;import{__webpack_require__ as n}from"./1~rslib-runtime.js";import r,{existsSync as i,promises as a}from"node:fs";import o from"node:path";import{fileURLToPath as s}from"node:url";import l,{hostname as u}from"node:os";import d,{createHash as c}from"node:crypto";import{PNG as p}from"pngjs";import f from"node:dns/promises";import m from"node:net";import h from"node:fs/promises";import{TextDecoder as w}from"node:util";import{XMLParser as g}from"fast-xml-parser";import{AsyncLocalStorage as y}from"node:async_hooks";import{runCmdStreaming as I,asAppError as v,AppError as b,runCmdBackground as A,runCmdDetached as S,getDiagnosticsMeta as x,runCmd as _,runCmdSync as N,withDiagnosticTimer as E,whichCmd as D,emitDiagnostic as M}from"./818.js";var C={};n.r(C),n.d(C,{ensureAndroidEmulatorBooted:()=>nR,listAndroidDevices:()=>nM,waitForAndroidBoot:()=>nP});var O={};n.r(O),n.d(O,{TM:()=>sv,ensureBootedSimulator:()=>i0,installIosApp:()=>sA,installIosInstallablePath:()=>sx,listIosApps:()=>sM,L5:()=>sy,IJ:()=>sI,TJ:()=>sE,J7:()=>s_,reinstallIosApp:()=>sS,resolveIosApp:()=>sg,kc:()=>sn,Cm:()=>sD,ap:()=>sN});let L="<wifi|airplane|location> <on|off>",T="appearance <light|dark|toggle>",k="faceid <match|nonmatch|enroll|unenroll>",R="touchid <match|nonmatch|enroll|unenroll>",P="fingerprint <match|nonmatch>",$="permission <grant|deny|reset> <camera|microphone|photos|contacts|contacts-limited|notifications|calendar|location|location-always|media-library|motion|reminders|siri> [full|limited]",F="permission <grant|reset> <accessibility|screen-recording|input-monitoring>",U=`macOS supports only settings ${T} and settings ${F}. wifi|airplane|location remain unsupported on macOS.`,V=`settings ${L} | settings ${T} | settings ${k} | settings ${R} | settings ${P} | settings ${$} | settings ${F}`,G=`settings requires ${L}, ${T}, ${k}, ${R}, ${P}, ${$}, or ${F}`;function B(e){return`Unsupported macOS setting: ${e}. ${U}`}let j=["app","frontmost-app","desktop","menubar"];function q(e){let t=e?.trim().toLowerCase();if("app"===t||"frontmost-app"===t||"desktop"===t||"menubar"===t)return t;throw new b("INVALID_ARGS",`Invalid surface: ${e}. Use ${j.join("|")}.`)}function W(e){var t;let n,r=z(e.label),i=z(e.value),a=z(e.identifier),o=(t=a)&&!/^[\w.]+:id\/[\w.-]+$/i.test(t)&&!/^_?NS:\d+$/i.test(t)?a:"";return(n=H(e.type??"")).includes("textfield")||n.includes("securetextfield")||n.includes("searchfield")||n.includes("edittext")||n.includes("textview")||n.includes("textarea")?i||r||o:r||i||o}function z(e){return"string"==typeof e?e.trim():""}function H(e){let t=e.trim().replace(/XCUIElementType/gi,"").replace(/^AX/,"").toLowerCase(),n=Math.max(t.lastIndexOf("."),t.lastIndexOf("/"));return -1!==n&&(t=t.slice(n+1)),t}function J(e,t={}){let n=[],r=[];for(let i of e){let e=i.depth??0,a=i.label?.trim()||i.value?.trim()||i.identifier?.trim()||"",o=Y(i.type??"Element");if("group"===o&&!a)continue;for(;n.length>0&&e<=n[n.length-1];)n.pop();let s=n.length;n.push(e),r.push({node:i,depth:s,type:o,text:X(i,s,!1,o,t)})}return r}function X(e,t,n,r,i={}){var a,o,s,l,u;let d,c,p=r??Y(e.type??"Element"),f=(d=W(e),{text:d,isLargeSurface:c=function(e,t){if("text-view"===t||"text-field"===t||"search"===t)return!0;let n=H(e.type??""),r=`${e.role??""} ${e.subrole??""}`.toLowerCase();return n.includes("textview")||n.includes("textarea")||n.includes("textfield")||n.includes("securetextfield")||n.includes("searchfield")||n.includes("edittext")||r.includes("text area")||r.includes("text field")}(e,p),shouldSummarize:c&&!!(a=d)&&(a.length>80||/[\r\n]/.test(a))}),m=(o=e,s=p,l=i,u=f,l.summarizeTextSurfaces&&u.shouldSummarize&&function(e,t,n){let r=z(e.label);if(r&&r!==n)return r;let i=z(e.identifier);if(i&&!Q(i)&&i!==n)return i;switch(t){case"text":case"text-view":return"Text view";case"text-field":return"Text field";case"search":return"Search field";default:return""}}(o,s,u.text)||K(o,s)),h=" ".repeat(t),w=e.ref?`@${e.ref}`:"",g=(function(e,t,n,r){let i,a=[];if(!1===e.enabled&&a.push("disabled"),!n.summarizeTextSurfaces||(!0===e.selected&&a.push("selected"),Z(t)&&a.push("editable"),function(e,t){if("scroll-area"===t)return!0;let n=(e.type??"").toLowerCase(),r=`${e.role??""} ${e.subrole??""}`.toLowerCase();return n.includes("scroll")||r.includes("scroll")}(e,t)&&a.push("scrollable"),!r.shouldSummarize))return a;return a.push(`preview:"${((i=r.text.replace(/\s+/g," ").trim()).length<=48?i:`${i.slice(0,45)}...`).replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`),a.push("truncated"),[...new Set(a)]})(e,p,i,f).map(e=>` [${e}]`).join(""),y=m?` "${m}"`:"";return n?`${h}${w} [${p}]${g}`.trimEnd():`${h}${w} [${p}]${y}${g}`.trimEnd()}function K(e,t){var n,r;let i,a=e.label?.trim();if(a&&(n=t,r=a,("scroll-area"===n||"list"===n||"collection"===n||"table"===n)&&(i=r.trim().toLowerCase())&&/^(vertical|horizontal)\s+scroll\s+bar(?:,?\s*\d+\s+pages?)?$/.test(i)))return"";let o=e.value?.trim();if(Z(t)){if(o)return o;if(a)return a}else if(a)return a;if(o)return o;let s=e.identifier?.trim();return!s||Q(s)&&("group"===t||"image"===t||"list"===t||"collection"===t)?"":s}function Y(e){let t=e.replace(/XCUIElementType/gi,"").toLowerCase(),n=e.includes(".")&&(e.startsWith("android.")||e.startsWith("androidx.")||e.startsWith("com."));switch(t.includes(".")&&(t=t.replace(/^android\.widget\./,"").replace(/^android\.view\./,"").replace(/^android\.webkit\./,"").replace(/^androidx\./,"").replace(/^com\.google\.android\./,"").replace(/^com\.android\./,""),n&&t.includes(".")&&(t=t.slice(t.lastIndexOf(".")+1))),t){case"application":return"application";case"navigationbar":return"navigation-bar";case"tabbar":return"tab-bar";case"button":case"imagebutton":return"button";case"link":return"link";case"cell":return"cell";case"statictext":case"checkedtextview":return"text";case"textfield":case"edittext":return"text-field";case"textview":return n?"text":"text-view";case"textarea":return"text-view";case"switch":return"switch";case"slider":return"slider";case"image":case"imageview":return"image";case"webview":return"webview";case"framelayout":case"linearlayout":case"relativelayout":case"constraintlayout":case"viewgroup":case"view":case"group":return"group";case"listview":case"recyclerview":return"list";case"collectionview":return"collection";case"searchfield":return"search";case"segmentedcontrol":return"segmented-control";case"window":return"window";case"checkbox":return"checkbox";case"radio":return"radio";case"menuitem":return"menu-item";case"toolbar":return"toolbar";case"scrollarea":case"scrollview":case"nestedscrollview":return"scroll-area";case"table":return"table";default:return t||"element"}}function Z(e){return"text-field"===e||"text-view"===e||"search"===e}function Q(e){return/^[\w.]+:id\/[\w.-]+$/i.test(e)}function ee(e){return new Map(e.map(e=>[e.index,e]))}function et(e){return e.label?.trim()||e.value?.trim()||e.identifier?.trim()||""}function en(e){return e.map((e,t)=>({...e,ref:`e${t+1}`}))}function er(e){let t=e.trim();return t.startsWith("@")?t.slice(1)||null:t.startsWith("e")?t:null}function ei(e,t){return e.find(e=>e.ref===t)??null}function ea(e){return{x:Math.round(e.x+e.width/2),y:Math.round(e.y+e.height/2)}}function eo(e,t){let n=ea(t),r=e.filter(e=>{var t;return!!(t=e.rect)&&Number.isFinite(t.x)&&Number.isFinite(t.y)&&Number.isFinite(t.width)&&Number.isFinite(t.height)}),i=r.filter(e=>{let t=(e.type??"").toLowerCase();return t.includes("application")||t.includes("window")}),a=eu(i.map(e=>e.rect).filter(e=>el(e,n.x,n.y)));if(a)return a;let o=eu(i.map(e=>e.rect));if(o)return o;let s=eu(r.map(e=>e.rect).filter(e=>el(e,n.x,n.y)));return s||null}function es(e,t){let n=Math.max(1,t.height),r=t.y,i=t.y+n,a=r+.25*n,o=i-.25*n,s=e.y+e.height/2;return s<a?Math.ceil(a-s):s>o?Math.ceil(s-o):0}function el(e,t,n){return t>=e.x&&t<=e.x+e.width&&n>=e.y&&n<=e.y+e.height}function eu(e){let t=null,n=-1;for(let r of e){let e=r.width*r.height;e>n&&(t=r,n=e)}return t}function ed(e,t,n,r){return Math.max(e,n)<=Math.min(t,r)}function ec(e){let t=`${e??""}`.toLowerCase();return t.includes("scroll")||t.includes("recyclerview")||t.includes("listview")||t.includes("gridview")||t.includes("collectionview")||"table"===t}function ep(e){return!!ec(e.type)||`${e.role??""} ${e.subrole??""}`.toLowerCase().includes("scroll")}function ef(e){if(0===e.length)return{nodes:e,hiddenCount:0,summaryLines:[]};let t=ee(e),n=new Set,r=[];for(let i of e){if(em(i,e,t)){!function(e,t,n){let r=e,i=new Set;for(;r&&!i.has(r.index);)i.add(r.index),t.add(r.index),r="number"==typeof r.parentIndex?n.get(r.parentIndex):void 0}(i,n,t);continue}r.push(i)}let i=function(e,t,n,r){let i=new Map,a=new Set;for(let e of t){if(!e.rect)continue;let t=eg(e,n,r);if(!t?.rect)continue;let o=ew(e.rect,t.rect);if(!o)continue;let s=i.get(t.index)??new Set;s.add(o),i.set(t.index,s),a.add(e.index)}return function(e,t,n,r){for(let i 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}(i);if(!e||0===e.size)continue;let a=eg(i,t,n);if(!a)continue;let o=r.get(a.index)??new Set;for(let t of e)o.add(t);r.set(a.index,o)}}(e,n,r,i),{directionsByContainer:i,coveredNodeIndexes:a}}(e,r,n,t),a=0===n.size?e:e.filter(e=>n.has(e.index));return{nodes:a.map(e=>(function(e,t){let n=t.get(e.index);if(!n||0===n.size)return e;let r=!!(!0===e.hiddenContentAbove||n.has("above"))||void 0,i=!!(!0===e.hiddenContentBelow||n.has("below"))||void 0;return{...e,hiddenContentAbove:r,hiddenContentBelow:i}})(e,i.directionsByContainer)),hiddenCount:0===n.size?0:e.length-a.length,summaryLines:function(e,t,n){let r=new Map;for(let i of e){let e=function(e,t,n){if(!e.rect)return null;let r=eh(e,t,n);return r?ew(e.rect,r):null}(i,t,n);if(!e)continue;let a=r.get(e)??[];a.push(i),r.set(e,a)}return["above","below"].flatMap(e=>{let t=r.get(e);if(!t||0===t.length)return[];let n=(function(e){let t=new Set,n=[];for(let r of e){let e=et(r);!e||t.has(e)||(t.add(e),n.push(e))}return n})(t).slice(0,3).map(e=>`"${e}"`),i=1===t.length?"interactive item":"interactive items",a=n.length>0?`: ${n.join(", ")}`:"";return[`[off-screen ${e}] ${t.length} ${i}${a}`]})}(r.filter(e=>!i.coveredNodeIndexes.has(e.index)&&function(e){if(!0===e.hittable)return!0;let t=(e.type??"").toLowerCase();return t.includes("button")||t.includes("link")||t.includes("textfield")||t.includes("edittext")||t.includes("searchfield")||t.includes("checkbox")||t.includes("radio")||t.includes("switch")||t.includes("menuitem")||!!et(e)}(e)),e,t)}}function em(e,t,n=ee(t)){var r;if(!e.rect)return!0;let i=eh(e,t,n);return!i||(r=e.rect,ed(r.x,r.x+r.width,i.x,i.x+i.width)&&ed(r.y,r.y+r.height,i.y,i.y+i.height))}function eh(e,t,n=ee(t)){let r=function(e,t){let n="number"==typeof e.parentIndex?t.get(e.parentIndex):void 0,r=new Set;for(;n&&!r.has(n.index);){if(r.add(n.index),n.rect&&ep(n))return n.rect;n="number"==typeof n.parentIndex?t.get(n.parentIndex):void 0}return null}(e,n);return r||eo(t,e.rect??{x:0,y:0,width:0,height:0})}function ew(e,t){return e.y+e.height<=t.y?"above":e.y>=t.y+t.height?"below":null}function eg(e,t,n){let r="number"==typeof e.parentIndex?n.get(e.parentIndex):void 0,i=new Set;for(;r&&!i.has(r.index);){if(i.add(r.index),t.has(r.index)&&ep(r))return r;r="number"==typeof r.parentIndex?n.get(r.parentIndex):void 0}return null}function ey(){try{let e=eI();return JSON.parse(r.readFileSync(o.join(e,"package.json"),"utf8")).version??"0.0.0"}catch{return"0.0.0"}}function eI(){let e=o.dirname(s(import.meta.url)),t=e;for(let e=0;e<6;e+=1){let e=o.join(t,"package.json");if(r.existsSync(e))return t;t=o.dirname(t)}return e}let ev=[/(^|[/\s"'=])dist\/src\/daemon\.js($|[\s"'])/,/(^|[/\s"'=])src\/daemon\.ts($|[\s"'])/];function eb(e){if(!Number.isInteger(e)||e<=0)return!1;try{return process.kill(e,0),!0}catch(e){return"EPERM"===e.code}}function eA(e){if(!Number.isInteger(e)||e<=0)return null;try{let t=N("ps",["-p",String(e),"-o","lstart="],{allowFailure:!0,timeoutMs:1e3});if(0!==t.exitCode)return null;let n=t.stdout.trim();return n.length>0?n:null}catch{return null}}function eS(e){if(!Number.isInteger(e)||e<=0)return null;try{let t=N("ps",["-p",String(e),"-o","command="],{allowFailure:!0,timeoutMs:1e3});if(0!==t.exitCode)return null;let n=t.stdout.trim();return n.length>0?n:null}catch{return null}}function ex(e,t){let n;if(!eb(e))return!1;if(t){let n=eA(e);if(!n||n!==t)return!1}let r=eS(e);return!!r&&!!(n=r.toLowerCase().replaceAll("\\","/")).includes("agent-device")&&ev.some(e=>e.test(n))}function e_(e,t){try{return process.kill(e,t),!0}catch(t){let e=t.code;if("ESRCH"===e||"EPERM"===e)return!1;throw t}}async function eN(e,t){if(!eb(e))return!0;let n=Date.now();for(;Date.now()-n<t;)if(await new Promise(e=>setTimeout(e,50)),!eb(e))return!0;return!eb(e)}async function eE(e,t){!ex(e,t.expectedStartTime)||!e_(e,"SIGTERM")||await eN(e,t.termTimeoutMs)||e_(e,"SIGKILL")&&await eN(e,t.killTimeoutMs)}function eD(e){return e?.HOME?.trim()||l.homedir()}function eM(e,t={}){return"~"===e?eD(t.env):e.startsWith("~/")?o.join(eD(t.env),e.slice(2)):e}function eC(e,t={}){let n=eM(e,t);return o.isAbsolute(n)?n:o.resolve(t.cwd??process.cwd(),n)}function eO(e){let t,n=(t=(e??"").trim())?eC(t):o.join(eM("~"),".agent-device");return{baseDir:n,infoPath:o.join(n,"daemon.json"),lockPath:o.join(n,"daemon.lock"),logPath:o.join(n,"daemon.log"),sessionsDir:o.join(n,"sessions")}}function eL(e){let t=(e??"").trim().toLowerCase();return"http"===t?"http":"dual"===t?"dual":"socket"}function eT(e){let t=(e??"").trim().toLowerCase();return"auto"===t?"auto":"socket"===t?"socket":"http"===t?"http":"auto"}function ek(e){return"tenant"===(e??"").trim().toLowerCase()?"tenant":"none"}function eR(e){if(!e)return;let t=e.trim();if(t&&/^[a-zA-Z0-9._-]{1,128}$/.test(t))return t}let eP=/(?:^|[^\w$.])(?:import|export)\s+(?:type\s+)?(?:[^'"`]*?\s+from\s+)?['"]([^'"]+)['"]/gm,e$=/import\(\s*['"]([^'"]+)['"]\s*\)/gm,eF=[".ts",".tsx",".js",".jsx",".mjs",".cjs"];function eU(){let e=process.argv[1];return e?eV(e):"unknown"}function eV(e,t=eI()){try{let n=o.resolve(t),i=[o.resolve(e)],a=new Set,s=[];for(;i.length>0;){let e=i.pop();if(!e||a.has(e))continue;a.add(e);let t=r.statSync(e);if(!t.isFile())continue;let l=o.relative(n,e)||e;s.push(`${l}:${t.size}:${Math.trunc(t.mtimeMs)}`);let u=r.readFileSync(e,"utf8");for(let t of function(e){let t=new Set;return eG(e,eP,t),eG(e,e$,t),[...t]}(u)){let n=function(e,t){let n=o.resolve(o.dirname(e),t),r=eB(n);if(r)return r;for(let e of eF){let t=eB(`${n}${e}`);if(t)return t}for(let e of eF){let t=eB(o.join(n,`index${e}`));if(t)return t}return null}(e,t);n&&i.push(n)}}let l=s.sort().join("|"),u=d.createHash("sha1").update(l).digest("hex");return`graph:${s.length}:${u}`}catch{return"unknown"}}function eG(e,t,n){t.lastIndex=0;let r=null;for(;null!==(r=t.exec(e));){let e=r[1]?.trim();e?.startsWith(".")&&n.add(e)}}function eB(e){try{return r.statSync(e).isFile()?e:null}catch{return null}}let ej=100,eq=new Set(["batch","replay"]),eW=new Set(["command","positionals","flags","runtime"]);function ez(e){let t;try{t=JSON.parse(e)}catch{throw new b("INVALID_ARGS","Batch steps must be valid JSON.")}if(!Array.isArray(t)||0===t.length)throw new b("INVALID_ARGS","Batch steps must be a non-empty JSON array.");return t}function eH(e,t){if(!Array.isArray(e)||0===e.length)throw new b("INVALID_ARGS","batch requires a non-empty batchSteps array.");if(e.length>t)throw new b("INVALID_ARGS",`batch has ${e.length} steps; max allowed is ${t}.`);let n=[];for(let t=0;t<e.length;t+=1){let r=e[t];if(!r||"object"!=typeof r)throw new b("INVALID_ARGS",`Invalid batch step at index ${t}.`);let i=Object.keys(r).filter(e=>!eW.has(e));if(i.length>0){let e=i.map(e=>`"${e}"`).join(", ");throw new b("INVALID_ARGS",`Batch step ${t+1} has unknown field(s): ${e}. Allowed fields: command, positionals, flags, runtime.`)}let a="string"==typeof r.command?r.command.trim().toLowerCase():"";if(!a)throw new b("INVALID_ARGS",`Batch step ${t+1} requires command.`);if(eq.has(a))throw new b("INVALID_ARGS",`Batch step ${t+1} cannot run ${a}.`);if(void 0!==r.positionals&&!Array.isArray(r.positionals))throw new b("INVALID_ARGS",`Batch step ${t+1} positionals must be an array.`);let o=r.positionals??[];if(o.some(e=>"string"!=typeof e))throw new b("INVALID_ARGS",`Batch step ${t+1} positionals must contain only strings.`);if(void 0!==r.flags&&("object"!=typeof r.flags||Array.isArray(r.flags)||!r.flags))throw new b("INVALID_ARGS",`Batch step ${t+1} flags must be an object.`);if(void 0!==r.runtime&&("object"!=typeof r.runtime||Array.isArray(r.runtime)||!r.runtime))throw new b("INVALID_ARGS",`Batch step ${t+1} runtime must be an object.`);n.push({command:a,positionals:o,flags:r.flags??{},runtime:r.runtime})}return n}let eJ=new Set(["id","role","text","label","value","appname","windowtitle"]),eX=new Set(["visible","hidden","editable","selected","enabled","hittable"]),eK=new Set([...eJ,...eX]);function eY(e){let t=e.trim();if(!t)throw new b("INVALID_ARGS","Selector expression cannot be empty");let n=function(e){let t=[],n="",r=null;for(let i=0;i<e.length;i+=1){let a=e[i];if(('"'===a||"'"===a)&&!e4(e,i)){r=e2(r,a),n+=a;continue}if(!r&&"|"===a&&"|"===e[i+1]){let r=n.trim();if(!r)throw new b("INVALID_ARGS",`Invalid selector fallback expression: ${e}`);t.push(r),n="",i+=1;continue}n+=a}let i=n.trim();if(!i)throw new b("INVALID_ARGS",`Invalid selector fallback expression: ${e}`);return t.push(i),t}(t);if(0===n.length)throw new b("INVALID_ARGS","Selector expression cannot be empty");return{raw:t,selectors:n.map(e=>(function(e){let t=e.trim();if(!t)throw new b("INVALID_ARGS","Selector segment cannot be empty");let n=function(e){let t=[],n="",r=null;for(let i=0;i<e.length;i+=1){let a=e[i];if(('"'===a||"'"===a)&&!e4(e,i)){r=e2(r,a),n+=a;continue}if(!r&&/\s/.test(a)){n.trim()&&t.push(n.trim()),n="";continue}n+=a}if(r)throw new b("INVALID_ARGS",`Unclosed quote in selector: ${e}`);return n.trim()&&t.push(n.trim()),t}(t);if(0===n.length)throw new b("INVALID_ARGS",`Invalid selector segment: ${e}`);return{raw:t,terms:n.map(e1)}})(e))}}function eZ(e){try{return eY(e)}catch{return null}}function eQ(e,t={}){if(0===e.length)return null;let n=t.preferTrailingValue??!1,r=0,i=[];for(;r<e.length&&function(e){let t=e.trim();if(!t)return!1;if("||"===t)return!0;let n=t.indexOf("=");if(-1!==n){let e=t.slice(0,n).trim().toLowerCase();return eK.has(e)}return eK.has(t.toLowerCase())}(e[r]);){r+=1;let t=e.slice(0,r).join(" ").trim();t&&eZ(t)&&i.push(r)}if(0===i.length)return null;let a=i[i.length-1];if(n){for(let t=i.length-1;t>=0;t-=1)if(i[t]<e.length){a=i[t];break}}let o=e.slice(0,a).join(" ").trim();return o?{selectorExpression:o,rest:e.slice(a)}:null}function e0(e){let t=e[0]??"",n=eQ(e.slice(1),{preferTrailingValue:"text"===t});return{predicate:t,split:n}}function e1(e){let t=e.trim();if(!t)throw new b("INVALID_ARGS","Empty selector term");let n=t.indexOf("=");if(-1===n){let n=t.toLowerCase();if(!eX.has(n))throw new b("INVALID_ARGS",`Invalid selector term "${e}", expected key=value`);return{key:n,value:!0}}let r=t.slice(0,n).trim().toLowerCase(),i=t.slice(n+1).trim();if(!eK.has(r))throw new b("INVALID_ARGS",`Unknown selector key: ${r}`);if(!i)throw new b("INVALID_ARGS",`Missing selector value for key: ${r}`);if(eX.has(r)){let e,t="true"===(e=e3(i).toLowerCase())||"false"!==e&&null;if(null===t)throw new b("INVALID_ARGS",`Invalid boolean value for ${r}: ${i}`);return{key:r,value:t}}return{key:r,value:e3(i)}}function e2(e,t){return e?e===t?null:e:t}function e3(e){let t=e.trim();return t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'")?t.slice(1,-1).replace(/\\(["'])/g,"$1"):t}function e4(e,t){let n=0;for(let r=t-1;r>=0&&"\\"===e[r];r-=1)n+=1;return n%2==1}function e5(e,t){let n=t.toLowerCase();return e.find(e=>{let t=(e.label??"").toLowerCase(),r=(e.value??"").toLowerCase(),i=(e.identifier??"").toLowerCase();return t.includes(n)||r.includes(n)||i.includes(n)})??null}function e8(e,t){let n=[e.label,e.value,e.identifier].map(e=>"string"==typeof e?e.trim():"").find(e=>e&&e.length>0);return n&&e6(n)?n:function(e,t){if(!e.rect)return;let n=e.rect.y+e.rect.height/2,r=null;for(let e of t){if(!e.rect)continue;let t=[e.label,e.value,e.identifier].map(e=>"string"==typeof e?e.trim():"").find(e=>e&&e.length>0);if(!t||!e6(t))continue;let i=Math.abs(e.rect.y+e.rect.height/2-n);(!r||i<r.distance)&&(r={label:t,distance:i})}return r?.label}(e,t)??(n&&e6(n)?n:void 0)}function e6(e){let t=e.trim();return!(!t||/^(true|false)$/i.test(t)||/^\d+$/.test(t))}function e9(e){let t=[],n=[];for(let r of e){let e=r.depth??0;for(;t.length>0&&e<=t[t.length-1];)t.pop();let i=e7(r.type??""),a=[r.label,r.value,r.identifier].map(e=>"string"==typeof e?e.trim():"").find(e=>e&&e.length>0),o=!!a&&e6(a);if(("group"===i||"ioscontentgroup"===i)&&!o){t.push(e);continue}let s=Math.max(0,e-t.length);n.push({...r,depth:s})}return n}function e7(e){let t=e.trim().replace(/XCUIElementType/gi,"");t.startsWith("AX")&&(t=t.slice(2));let n=Math.max((t=t.toLowerCase()).lastIndexOf("."),t.lastIndexOf("/"));return -1!==n&&(t=t.slice(n+1)),t}function te(e,t){let n=e7(e);return!n||("android"===t?n.includes("edittext")||n.includes("autocompletetextview"):n.includes("textfield")||n.includes("securetextfield")||n.includes("searchfield")||n.includes("textview")||n.includes("textarea")||"search"===n)}function tt(e,t){if(t.hittable)return t;let n=t,r=new Set;for(;void 0!==n.parentIndex&&!r.has(n.ref);){r.add(n.ref);let t=e[n.parentIndex];if(!t)break;if(t.hittable)return t;n=t}return null}function tn(e){return[e.label,e.value,e.identifier].map(e=>"string"==typeof e?e.trim():"").filter(e=>e.length>0)[0]??""}function tr(e){return W(e)}function ti(e,t,n,r={}){let i=to(n);if(!i)return{matches:[],score:0};let a=0,o=[];for(let n of e){if(r.requireRect&&!n.rect)continue;let e=function(e,t,n){switch(t){case"role":return function(e,t){let n=function(e){let t=e.trim();return t?t=(t.split(".").pop()??t).replace(/XCUIElementType/gi,"").toLowerCase():""}(e??"");return n?n===t?2:+!!n.includes(t):0}(e.type,n);case"label":return ta(e.label,n);case"value":return ta(e.value,n);case"id":return ta(e.identifier,n);default:return Math.max(ta(e.label,n),ta(e.value,n),ta(e.identifier,n))}}(n,t,i);if(!(e<=0)){if(e>a){a=e,o.length=0,o.push(n);continue}e===a&&o.push(n)}}return{matches:o,score:a}}function ta(e,t){let n=to(e??"");return n?n===t?2:+!!n.includes(t):0}function to(e){return e.trim().toLowerCase().replace(/\s+/g," ")}function ts(e,t,n){return t.terms.every(t=>(function(e,t,n){switch(t.key){case"id":return td(e.identifier,String(t.value));case"role":return td(e7(e.type??""),String(t.value));case"label":return td(e.label,String(t.value));case"value":return td(e.value,String(t.value));case"text":return td(tn(e),String(t.value));case"appname":return td(e.appName,String(t.value));case"windowtitle":return td(e.windowTitle,String(t.value));case"visible":return tl(e)===!!t.value;case"hidden":return!tl(e)==!!t.value;case"editable":return tu(e,n)===!!t.value;case"selected":return!0===e.selected==!!t.value;case"enabled":return!1!==e.enabled==!!t.value;case"hittable":return!0===e.hittable==!!t.value;default:return!1}})(e,t,n))}function tl(e){return!0===e.hittable||!!e.rect&&e.rect.width>0&&e.rect.height>0}function tu(e,t){return te(e.type??"",t)&&!1!==e.enabled}function td(e,t){return to(e??"")===to(t)}function tc(e,t,n){let r=n.requireRect??!1,i=n.requireUnique??!0,a=[];for(let o=0;o<t.selectors.length;o+=1){let s=t.selectors[o],l=function(e,t,n,r){let i=0,a=null,o=null,s=!1;for(let l of e){if(r&&!l.rect||!ts(l,t,n))continue;if(i+=1,a??=l,!o){o=l;continue}let e=function(e,t){let n=e.depth??0,r=t.depth??0;if(n!==r)return n>r?1:-1;let i=tm(e),a=tm(t);return i!==a?i<a?1:-1:0}(l,o);e>0?(o=l,s=!1):0===e&&(s=!0)}return{count:i,firstNode:a,disambiguated:s?null:o}}(e,s,n.platform,r);if(a.push({selector:s.raw,matches:l.count}),0!==l.count&&l.firstNode){if(i&&1!==l.count){if(!n.disambiguateAmbiguous||!l.disambiguated)continue;return{node:l.disambiguated,selector:s,selectorIndex:o,matches:l.count,diagnostics:a}}return{node:l.firstNode,selector:s,selectorIndex:o,matches:l.count,diagnostics:a}}}return null}function tp(e,t,n){let r=n.requireRect??!1,i=[];for(let a=0;a<t.selectors.length;a+=1){let o=t.selectors[a],s=function(e,t,n,r){let i=0;for(let a of e)(!r||a.rect)&&ts(a,t,n)&&(i+=1);return i}(e,o,n.platform,r);if(i.push({selector:o.raw,matches:s}),s>0)return{selectorIndex:a,selector:o,matches:s,diagnostics:i}}return null}function tf(e,t,n){if(0===t.length)return`Selector did not match: ${e.raw}`;let r=t.map(e=>`${e.selector} -> ${e.matches}`).join(", ");return n.unique??!0?`Selector did not resolve uniquely (${r})`:`Selector did not match (${r})`}function tm(e){return e.rect?e.rect.width*e.rect.height:1/0}function th(e){let t=e.result?.text;if("string"==typeof t&&t.trim().length>0)return t;let n=e.positionals??[];return 0===n.length?"":n[0].startsWith("@")?n.length>=3?n.slice(2).join(" ").trim():n.slice(1).join(" ").trim():!(n.length>=3)||Number.isNaN(Number(n[0]))||Number.isNaN(Number(n[1]))?n.slice(1).join(" ").trim():n.slice(2).join(" ").trim()}function tw(e){let t=new Set,n=[];for(let r of e)t.has(r)||(t.add(r),n.push(r));return n}function tg(e,t,n={}){let r=[],i=e7(e.type??""),a=tI(e.identifier),o=tI(e.label),s=tI(e.value),l=tI(tn(e)),u="fill"===n.action;a&&r.push(`id=${ty(a)}`),i&&o&&r.push(u?`role=${ty(i)} label=${ty(o)} editable=true`:`role=${ty(i)} label=${ty(o)}`),o&&r.push(u?`label=${ty(o)} editable=true`:`label=${ty(o)}`),s&&r.push(u?`value=${ty(s)} editable=true`:`value=${ty(s)}`),l&&l!==o&&l!==s&&r.push(u?`text=${ty(l)} editable=true`:`text=${ty(l)}`),i&&u&&!r.some(e=>e.includes("editable=true"))&&r.push(`role=${ty(i)} editable=true`);let d=tw(r);return 0===d.length&&i&&d.push(u?`role=${ty(i)} editable=true`:`role=${ty(i)}`),0===d.length&&tl(e)&&d.push("visible=true"),d}function ty(e){return JSON.stringify(e)}function tI(e){if(!e)return null;let t=e.trim();return t||null}function tv(e){return e?{message:e}:{}}function tb(e,t){return t?{...e,message:t}:e}function tA(e){return"string"==typeof e?.message&&e.message.length>0?e.message:null}function tS(e){let t=e.appId??e.bundleId??e.packageName;return{session:e.session,appId:t,appBundleId:e.bundleId,package:e.packageName}}function tx(e,t,n){return{deviceId:t,deviceName:n,..."android"===e?{serial:t}:"ios"===e?{udid:t}:{}}}function t_(e,t={}){let n=t.includeAndroidSerial??!0;return{platform:e.platform,target:e.target,device:e.name,id:e.id,..."ios"===e.platform?{device_udid:e.ios?.udid??e.id,ios_simulator_device_set:e.ios?.simulatorSetPath??null}:{},..."android"===e.platform&&n?{serial:e.android?.serial??e.id}:{}}}function tN(e){return{name:e.name,...t_(e.device,{includeAndroidSerial:!1}),createdAt:e.createdAt}}function tE(e){return{platform:e.platform,id:e.id,name:e.name,kind:e.kind,target:e.target,..."boolean"==typeof e.booted?{booted:e.booted}:{}}}function tD(e){let t=e.created?"Created":"Reused",n=e.booted?" (booted)":"";return tb({udid:e.udid,device:e.device,runtime:e.runtime,ios_simulator_device_set:e.iosSimulatorDeviceSet??null,created:e.created,booted:e.booted},`${t}: ${e.device} ${e.udid}${n}`)}function tM(e){return e.bundleId??e.package??e.app}function tC(e){return tb({app:e.app,appPath:e.appPath,platform:e.platform,...e.appId?{appId:e.appId}:{},...e.bundleId?{bundleId:e.bundleId}:{},...e.package?{package:e.package}:{}},`Installed: ${tM(e)}`)}function tO(e){return e.appName??e.bundleId??e.packageName??e.launchTarget}function tL(e){return tb({launchTarget:e.launchTarget,...e.appName?{appName:e.appName}:{},...e.appId?{appId:e.appId}:{},...e.bundleId?{bundleId:e.bundleId}:{},...e.packageName?{package:e.packageName}:{},...e.installablePath?{installablePath:e.installablePath}:{},...e.archivePath?{archivePath:e.archivePath}:{},...e.materializationId?{materializationId:e.materializationId}:{},...e.materializationExpiresAt?{materializationExpiresAt:e.materializationExpiresAt}:{}},`Installed: ${tO(e)}`)}function tT(e){let t=e.appName??e.appBundleId??e.session;return tb({session:e.session,...e.appName?{appName:e.appName}:{},...e.appBundleId?{appBundleId:e.appBundleId}:{},...e.startup?{startup:e.startup}:{},...e.runtime?{runtime:e.runtime}:{},...e.device?t_(e.device):{}},t?`Opened: ${t}`:"Opened")}function tk(e){return{session:e.session,...e.shutdown?{shutdown:e.shutdown}:{},...tv(e.session?`Closed: ${e.session}`:"Closed")}}function tR(e){return{nodes:e.nodes,truncated:e.truncated,...e.appName?{appName:e.appName}:{},...e.appBundleId?{appBundleId:e.appBundleId}:{},...e.visibility?{visibility:e.visibility}:{},...e.warnings&&e.warnings.length>0?{warnings:e.warnings}:{}}}function tP(e,t){try{return p.sync.read(e)}catch(e){throw new b("COMMAND_FAILED",`Failed to decode ${t} as PNG`,{label:t,reason:e instanceof Error?e.message:String(e)})}}function t$(e){return e}function tF(e){return"apple"===e||"ios"===e||"macos"===e}function tU(e,t){return!t||("apple"===t?tF(e):e===t)}function tV(e){let{simulatorSetPath:t,platform:n,target:r}=e;if(t&&"macos"!==n&&"desktop"!==r)return t}async function tG(e,t,n={}){let r=e,i=e=>e.toLowerCase().replace(/_/g," ").replace(/\s+/g," ").trim();if(t.platform&&(r=r.filter(e=>tU(e.platform,t.platform))),t.target&&(r=r.filter(e=>(e.target??"mobile")===t.target)),t.udid){let e=r.find(e=>e.id===t.udid&&tF(e.platform));if(!e)throw new b("DEVICE_NOT_FOUND",`No Apple device with UDID ${t.udid}`);return e}if(t.serial){let e=r.find(e=>e.id===t.serial&&"android"===e.platform);if(!e)throw new b("DEVICE_NOT_FOUND",`No Android device with serial ${t.serial}`);return e}if(t.deviceName){let e=i(t.deviceName),n=r.find(t=>i(t.name)===e);if(!n)throw new b("DEVICE_NOT_FOUND",`No device named ${t.deviceName}`);return n}if(1===r.length)return r[0];if(0===r.length){var a;let e=n.simulatorSetPath;if(e&&(!(a=t.platform)||"apple"===a||"ios"===a))throw new b("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 b("DEVICE_NOT_FOUND","No devices found",{selector:t})}let o=r.filter(e=>"device"!==e.kind);o.length>0&&(r=o);let s=r.filter(e=>e.booted);return 1===s.length?s[0]:s[0]??r[0]}let tB=e=>"macos"!==e.platform,tj=e=>"macos"===e.platform||"simulator"===e.kind,tq={device:!0},tW={},tz={alert:{apple:{simulator:!0,device:!0},android:{},linux:tW,supports:tj},pinch:{apple:{simulator:!0,device:!0},android:{},linux:tW,supports:tj},"app-switcher":{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:tW,supports:tB},apps:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:tW},back:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:tq},boot:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:tW,supports:tB},click:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:tq},clipboard:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:tq,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:tW,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:tq},fill:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:tq},diff:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:tq},find:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:tq},focus:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:tq},get:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:tq},is:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:tq},home:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:tq,supports:tB},logs:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:tW},network:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:tW},longpress:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:tq},open:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:tq},perf:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:tW},install:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:tW,supports:tB},"install-from-source":{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:tW,supports:tB},reinstall:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:tW,supports:tB},press:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:tq},push:{apple:{simulator:!0},android:{emulator:!0,device:!0,unknown:!0},linux:tW,supports:tB},record:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:tW},rotate:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:tW,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:tq},scroll:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:tq},scrollintoview:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:tW},swipe:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:tq},settings:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:tW,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:tq},"trigger-app-event":{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:tW},type:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:tq},wait:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:tq}};function tH(e,t){let n=tz[e];if(!n)return!0;let r=tF(t.platform)?n.apple:"linux"===t.platform?n.linux:n.android;return!!r&&(!n.supports||!!n.supports(t))&&!0===r[t.kind??"unknown"]}function tJ(e,t){let n=Y(e.type??"Element"),r=K(e,n),i=!1===e.enabled?"disabled":"enabled",a=!0===e.selected?"selected":"unselected",o=!0===e.hittable?"hittable":"not-hittable";return[String(t??e.depth??0),n,r,i,a,o].join("|")}function tX(e,t){return t.flatten?e.map(e=>({text:X(e,0,!1),comparable:tJ(e,0)})):J(e).map(e=>({text:e.text,comparable:tJ(e.node,e.depth)}))}function tK(e,t){return e.get(t)??0}function tY(e,t,n){return{ok:!1,error:{code:e,message:t,...n?{details:n}:{}}}}let tZ=["emulator","platform-tools",o.join("cmdline-tools","latest","bin"),o.join("cmdline-tools","tools","bin")];function tQ(e){let t=new Set,n=[];for(let r of e){let e=r.trim();!e||t.has(e)||(t.add(e),n.push(e))}return n}function t0(e=process.env){let t=e.ANDROID_SDK_ROOT?.trim(),n=e.ANDROID_HOME?.trim(),r=e.HOME?.trim()||l.homedir();return tQ([t??"",n??"",r?o.join(r,"Android","Sdk"):""])}async function t1(e){try{return await a.access(e,a.constants.X_OK),!0}catch{return!1}}async function t2(e=process.env){let t,n=[];for(let r of t0(e)){let e=[];for(let t of tZ){let n=o.join(r,t);await t1(n)&&e.push(n)}0!==e.length&&(t||(t=r),n.push(...e))}if(t&&(e.ANDROID_SDK_ROOT=e.ANDROID_SDK_ROOT?.trim()||t,e.ANDROID_HOME=e.ANDROID_HOME?.trim()||t),0===n.length)return;let r=(e.PATH??"").split(o.delimiter).map(e=>e.trim()).filter(e=>e.length>0);e.PATH=tQ([...n,...r]).join(o.delimiter)}function t3(e,t){return["-s",e.id,...t]}async function t4(){if(await t2(),!await D("adb"))throw new b("TOOL_MISSING","adb not found in PATH")}function t5(e,t){let n=`${e}
3
- ${t}`.toLowerCase();return n.includes("no shell command implementation")||n.includes("unknown command")}async function t8(e){await new Promise(t=>setTimeout(t,e))}function t6(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 r=n[1]?.toLowerCase(),i=n[2]??"";return"http"!==r&&"https"!==r&&"ws"!==r&&"wss"!==r&&"ftp"!==r&&"ftps"!==r||i.startsWith("//")}function t9(e,t){let n,r=e?.trim();return r?r:"http"===(n=t.trim().split(":")[0]?.toLowerCase())||"https"===n?"com.apple.mobilesafari":void 0}let t7=ne(process.env.AGENT_DEVICE_RETRY_LOGS);function ne(e){return["1","true","yes","on"].includes((e??"").trim().toLowerCase())}let nt=2e4,nn=12e4,nr=1e4;class ni{startedAtMs;expiresAtMs;constructor(e,t){this.startedAtMs=e,this.expiresAtMs=e+Math.max(0,t)}static fromTimeoutMs(e,t=Date.now()){return new ni(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 na(e,t={},n={}){let r,i={maxAttempts:t.maxAttempts??3,baseDelayMs:t.baseDelayMs??200,maxDelayMs:t.maxDelayMs??2e3,jitter:t.jitter??.2,shouldRetry:t.shouldRetry};for(let t=1;t<=i.maxAttempts;t+=1){if(n.signal?.aborted)throw new b("COMMAND_FAILED","request canceled",{reason:"request_canceled"});if(n.deadline?.isExpired()&&t>1)break;try{let r=await e({attempt:t,maxAttempts:i.maxAttempts,deadline:n.deadline});return n.onEvent?.({phase:n.phase,event:"succeeded",attempt:t,maxAttempts:i.maxAttempts,elapsedMs:n.deadline?.elapsedMs(),remainingMs:n.deadline?.remainingMs()}),ns({phase:n.phase,event:"succeeded",attempt:t,maxAttempts:i.maxAttempts,elapsedMs:n.deadline?.elapsedMs(),remainingMs:n.deadline?.remainingMs()}),r}catch(u){r=u;let e=n.classifyReason?.(u),a={phase:n.phase,event:"attempt_failed",attempt:t,maxAttempts:i.maxAttempts,elapsedMs:n.deadline?.elapsedMs(),remainingMs:n.deadline?.remainingMs(),reason:e};if(n.onEvent?.(a),ns(a),t>=i.maxAttempts||i.shouldRetry&&!i.shouldRetry(u,t))break;let o=function(e,t,n,r){let i=Math.min(t,e*2**(r-1));return Math.max(0,i+i*n*(2*Math.random()-1))}(i.baseDelayMs,i.maxDelayMs,i.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:i.maxAttempts,delayMs:s,elapsedMs:n.deadline?.elapsedMs(),remainingMs:n.deadline?.remainingMs(),reason:e};n.onEvent?.(l),ns(l),await function(e,t){return new Promise(n=>{if(t?.aborted)return void n();let r=!1,i=()=>{r||(r=!0,t&&t.removeEventListener("abort",o),n())},a=setTimeout(i,e);function o(){clearTimeout(a),i()}t&&t.addEventListener("abort",o,{once:!0})})}(s,n.signal)}}let a={phase:n.phase,event:"exhausted",attempt:i.maxAttempts,maxAttempts:i.maxAttempts,elapsedMs:n.deadline?.elapsedMs(),remainingMs:n.deadline?.remainingMs(),reason:n.classifyReason?.(r)};if(n.onEvent?.(a),ns(a),r)throw r;throw new b("COMMAND_FAILED","retry failed")}async function no(e,t={}){return na(()=>e(),{maxAttempts:t.attempts,baseDelayMs:t.baseDelayMs,maxDelayMs:t.maxDelayMs,jitter:t.jitter,shouldRetry:t.shouldRetry})}function ns(e){M({level:"attempt_failed"===e.event||"exhausted"===e.event?"warn":"debug",phase:"retry",data:{...e}}),t7&&process.stderr.write(`[agent-device][retry] ${JSON.stringify(e)}
4
- `)}let nl=["AGENT_DEVICE_IOS_SIMULATOR_DEVICE_SET","IOS_SIMULATOR_DEVICE_SET"],nu=["AGENT_DEVICE_ANDROID_DEVICE_ALLOWLIST","ANDROID_DEVICE_ALLOWLIST"];function nd(e){return e?.trim()||void 0}function nc(e,t){for(let n of e){let e=nd(t[n]);if(e)return e}}function np(e,t=process.env){return nd(e)??nc(nl,t)}function nf(e){return new Set(e.split(/[\s,]+/).map(e=>e.trim()).filter(Boolean))}function nm(e,t=process.env){let n=nd(e)??nc(nu,t);if(n)return nf(n)}function nh(e){let t=e.error?v(e.error):null,n=e.context?.platform,r=e.context?.phase;if(t?.code==="TOOL_MISSING")return"android"===n?"ADB_TRANSPORT_UNAVAILABLE":"IOS_TOOL_MISSING";let i=t?.details??{},a="string"==typeof i.message?i.message:void 0,o="string"==typeof i.stdout?i.stdout:void 0,s="string"==typeof i.stderr?i.stderr:void 0,l=i.boot&&"object"==typeof i.boot?i.boot:null,u=i.bootstatus&&"object"==typeof i.bootstatus?i.bootstatus:null,d=[e.message,t?.message,e.stdout,e.stderr,a,o,s,"string"==typeof l?.stdout?l.stdout:void 0,"string"==typeof l?.stderr?l.stderr:void 0,"string"==typeof u?.stdout?u.stdout:void 0,"string"==typeof u?.stderr?u.stderr:void 0].filter(Boolean).join("\n").toLowerCase();return"ios"===n&&(d.includes("runner did not accept connection")||"connect"===r&&(d.includes("timed out")||d.includes("timeout")||d.includes("econnrefused")||d.includes("connection refused")||d.includes("fetch failed")||d.includes("socket hang up")))?"IOS_RUNNER_CONNECT_TIMEOUT":"ios"===n&&"boot"===r&&(d.includes("timed out")||d.includes("timeout"))?"IOS_BOOT_TIMEOUT":"android"===n&&"boot"===r&&(d.includes("timed out")||d.includes("timeout"))?"ANDROID_BOOT_TIMEOUT":d.includes("resource temporarily unavailable")||d.includes("killed: 9")||d.includes("cannot allocate memory")||d.includes("system is low on memory")?"CI_RESOURCE_STARVATION_SUSPECTED":"android"===n&&(d.includes("device not found")||d.includes("no devices")||d.includes("device offline")||d.includes("offline")||d.includes("unauthorized")||d.includes("not authorized")||d.includes("unable to locate device")||d.includes("invalid device"))?"ADB_TRANSPORT_UNAVAILABLE":t?.code==="COMMAND_FAILED"||d.length>0?"BOOT_COMMAND_FAILED":"UNKNOWN"}function nw(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 ng=["android.software.leanback","android.software.leanback_only","android.hardware.type.television"];function ny(e){return`${e.stdout}
5
- ${e.stderr}`}function nI(e,t){return["-s",e,...t]}function nv(e){return e.startsWith("emulator-")}function nb(e){return e.toLowerCase().replace(/_/g," ").replace(/\s+/g," ").trim()}async function nA(e,t=nr){return _("adb",nI(e,["shell","getprop","sys.boot_completed"]),{allowFailure:!0,timeoutMs:t})}async function nS(e,t){let n=t.replace(/_/g," ").trim();if(!nv(e))return n||e;let r=await n_(e);return r?r.replace(/_/g," "):n||e}async function nx(e,t,n){try{return await n("adb",nI(e,t),{allowFailure:!0,timeoutMs:1e4})}catch(e){var r;if("COMMAND_FAILED"===(r=v(e)).code&&"number"==typeof r.details?.timeoutMs)return;throw e}}async function n_(e,t=_){for(let n of["ro.boot.qemu.avd_name","persist.sys.avd_name"]){let r=await nx(e,["shell","getprop",n],t);if(!r)continue;let i=r.stdout.trim();if(0===r.exitCode&&i.length>0)return i}let n=await nx(e,["emu","avd","name"],t);if(!n)return;let r=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&&r)return r}async function nN(e,t){let n=ny(await _("adb",nI(e,["shell","cmd","package","has-feature",t]),{allowFailure:!0,timeoutMs:nr})).toLowerCase();return!!n.includes("true")||!n.includes("false")&&null}async function nE(e){return(await Promise.all(ng.map(async t=>await nN(e,t)))).some(e=>!0===e)}async function nD(e){var t;let n;return"tv"===((n=ny(await _("adb",nI(e,["shell","getprop","ro.build.characteristics"]),{allowFailure:!0,timeoutMs:nr})).toLowerCase()).includes("tv")||n.includes("leanback")?"tv":null)||await nE(e)?"tv":(t=ny(await _("adb",nI(e,["shell","pm","list","features"]),{allowFailure:!0,timeoutMs:nr})),/feature:android\.(software\.leanback(_only)?|hardware\.type\.television)\b/i.test(t))?"tv":"mobile"}async function nM(e={}){if(await t2(),!await D("adb"))throw new b("TOOL_MISSING","adb not found in PATH");let t=e.serialAllowlist??nm(void 0),n=(await nC()).filter(e=>!t||t.has(e.serial));return await Promise.all(n.map(async({serial:e,rawModel:t})=>{let[n,r,i]=await Promise.all([nS(e,t),nk(e),nD(e)]);return{platform:"android",id:e,name:n,kind:nv(e)?"emulator":"device",target:i,booted:r}}))}async function nC(){return(await _("adb",["devices","-l"],{timeoutMs:nr})).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 nO(){let e=await _("emulator",["-list-avds"],{allowFailure:!0,timeoutMs:nr});if(0!==e.exitCode)throw new b("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 nL(e){let t=Date.now();for(;Date.now()-t<e.timeoutMs;){try{let t=await nT(e.avdName,e.serial);if(t)return{platform:"android",id:t,name:e.avdName,kind:"emulator",target:"mobile",booted:!1}}catch{}await new Promise(e=>setTimeout(e,1e3))}throw new b("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 nT(e,t){let n=nb(e);for(let e of(await nC()).filter(e=>(!t||e.serial===t)&&nv(e.serial)))if(nb(e.rawModel)===n||nb(await nS(e.serial,e.rawModel))===n)return e.serial}async function nk(e){try{let t=await nA(e);return"1"===t.stdout.trim()}catch{return!1}}async function nR(e){var t,n;let r;await t2();let i=e.avdName.trim();if(!i)throw new b("INVALID_ARGS","Android emulator boot requires a non-empty AVD name.");let a=e.timeoutMs??12e4;if(!await D("adb"))throw new b("TOOL_MISSING","adb not found in PATH");if(!await D("emulator"))throw new b("TOOL_MISSING","emulator not found in PATH");let o=await nO(),s=function(e,t){let n=e.find(e=>e===t);if(n)return n;let r=nb(t);return e.find(e=>nb(e)===r)}(o,i);if(!s)throw new b("DEVICE_NOT_FOUND",`No Android emulator AVD named ${e.avdName}`,{requestedAvdName:i,availableAvds:o,hint:"Run `emulator -list-avds` and pass an existing AVD name to --device."});let l=Date.now(),u=(t=await nM(),n=e.serial,r=nb(s),t.find(e=>"android"===e.platform&&"emulator"===e.kind&&(!n||e.id===n)&&nb(e.name)===r));if(!u){let t=["-avd",s];e.headless&&t.push("-no-window","-no-audio"),S("emulator",t)}let d=u??await nL({avdName:s,serial:e.serial,timeoutMs:a}),c=Math.max(1e3,a-(Date.now()-l));await nP(d.id,c);let p=(await nM()).find(e=>e.id===d.id);return p?{...p,name:s,booted:!0}:{...d,name:s,booted:!0}}async function nP(e,t=6e4){let n,r=ni.fromTimeoutMs(t),i=Math.max(1,Math.ceil(t/1e3)),a=!1;try{await na(async({deadline:i})=>{if(i?.isExpired())throw a=!0,new b("COMMAND_FAILED","Android boot deadline exceeded",{serial:e,timeoutMs:t,elapsedMs:r.elapsedMs(),message:"timeout"});let o=Math.max(1e3,i?.remainingMs()??t),s=await nA(e,Math.min(o,nr));if(n=s,"1"!==s.stdout.trim())throw new b("COMMAND_FAILED","Android device is still booting",{serial:e,stdout:s.stdout,stderr:s.stderr,exitCode:s.exitCode})},{maxAttempts:i,baseDelayMs:1e3,maxDelayMs:1e3,jitter:0,shouldRetry:e=>{let t=nh({error:e,stdout:n?.stdout,stderr:n?.stderr,context:{platform:"android",phase:"boot"}});return"ADB_TRANSPORT_UNAVAILABLE"!==t&&"ANDROID_BOOT_TIMEOUT"!==t}},{deadline:r,phase:"boot",classifyReason:e=>nh({error:e,stdout:n?.stdout,stderr:n?.stderr,context:{platform:"android",phase:"boot"}})})}catch(c){let i=v(c),o=n?.stdout,s=n?.stderr,l=n?.exitCode,u=nh({error:c,stdout:o,stderr:s,context:{platform:"android",phase:"boot"}});"BOOT_COMMAND_FAILED"===u&&"Android device is still booting"===i.message&&(u="ANDROID_BOOT_TIMEOUT");let d={serial:e,timeoutMs:t,elapsedMs:r.elapsedMs(),reason:u,hint:nw(u),stdout:o,stderr:s,exitCode:l};if(a||"ANDROID_BOOT_TIMEOUT"===u)throw new b("COMMAND_FAILED","Android device did not finish booting in time",d);if("TOOL_MISSING"===i.code)throw new b("TOOL_MISSING",i.message,{...d,...i.details??{}});if("ADB_TRANSPORT_UNAVAILABLE"===u)throw new b("COMMAND_FAILED",i.message,{...d,...i.details??{}});throw new b(i.code,i.message,{...d,...i.details??{}},i.cause)}}let n$=/\.(?:apk|aab)$/i,nF=/^[A-Za-z_][\w]*(\.[A-Za-z_][\w]*)+$/;function nU(e){var t,n;let r=e.trim();return 0===r.length?"other":n$.test(r)?r.includes("/")||r.includes("\\")||r.startsWith(".")||r.startsWith("~")||(t=r,!nF.test(t))?"binary":"package":(n=r,nF.test(n))?"package":"other"}function nV(e){return`Android runtime hints require an installed package name, not "${e}". Install or reinstall the app first, then relaunch by package.`}function nG(e,t,n){if(!e)return t;let r=Number(e);return Number.isFinite(r)?Math.max(n,Math.floor(r)):t}let nB=[".zip",".tar",".tar.gz",".tgz"],nj=nG(process.env.AGENT_DEVICE_SOURCE_DOWNLOAD_TIMEOUT_MS,12e4,1e3),nq=["1","true","yes","on"];async function nW(e){let t=[];try{let n=await nz(e.source,{signal:e.signal,downloadTimeoutMs:e.downloadTimeoutMs});t.push(n.cleanup);let r=await nY(n.localPath,{archivePath:void 0,isInstallablePath:e.isInstallablePath,installableLabel:e.installableLabel,allowArchiveExtraction:!1!==e.allowArchiveExtraction,registerCleanup:e=>{t.push(e)}});return{archivePath:r.archivePath,installablePath:r.installablePath,cleanup:async()=>{await n1(t)}}}catch(e){throw await n1(t),e}}async function nz(e,t){if("path"===e.kind)return{localPath:eM(e.path),cleanup:async()=>{}};let n=await a.mkdtemp(o.join(l.tmpdir(),"agent-device-source-"));try{return{localPath:await nH(n,e.url,e.headers,t),cleanup:async()=>{await a.rm(n,{recursive:!0,force:!0})}}}catch(e){throw await a.rm(n,{recursive:!0,force:!0}),e}}async function nH(e,t,n,r){let i;try{i=new URL(t)}catch{throw new b("INVALID_ARGS",`Invalid source URL: ${t}`)}await nJ(i);let s=r?.signal;if(s?.aborted)throw new b("COMMAND_FAILED","request canceled",{reason:"request_canceled"});let l=new AbortController,u=()=>{l.abort(s?.reason)};s?.addEventListener("abort",u,{once:!0});let d=r?.downloadTimeoutMs??nj,c=setTimeout(()=>{l.abort(Error("download timeout"))},d);try{let t=await fetch(i,{headers:n,redirect:"follow",signal:l.signal});if(!t.ok)throw new b("COMMAND_FAILED",`Failed to download app source: ${t.status} ${t.statusText}`,{status:t.status,statusText:t.statusText,url:i.toString()});let r=function(e,t){let n=e.headers.get("content-disposition"),r=n?.match(/filename\*?=(?:UTF-8'')?"?([^";]+)"?/i),i=r?.[1]?.trim();if(i)return o.basename(i);let a=o.basename(t.pathname);return a||"downloaded-artifact.bin"}(t,i),s=o.join(e,r),u=t.body;if(!u)throw new b("COMMAND_FAILED","Download response body was empty",{url:i.toString()});let d=await a.open(s,"w");try{for await(let e of u)await d.write(e)}finally{await d.close()}return s}catch(e){if(s?.aborted)throw new b("COMMAND_FAILED","request canceled",{reason:"request_canceled"},e);if(l.signal.aborted)throw new b("COMMAND_FAILED",`App source download timed out after ${d}ms`,{timeoutMs:d,url:i.toString()},e);throw e}finally{s?.removeEventListener("abort",u),clearTimeout(c)}}async function nJ(e){if("http:"!==e.protocol&&"https:"!==e.protocol)throw new b("INVALID_ARGS",`Unsupported source URL protocol: ${e.protocol}`);if(!nq.includes((process.env.AGENT_DEVICE_ALLOW_PRIVATE_SOURCE_URLS??"").toLowerCase())){var t;if(!(t=e.hostname.toLowerCase())||"localhost"===t||t.endsWith(".localhost")||nK(t))throw new b("INVALID_ARGS",`Source URL host is not allowed: ${e.hostname}`,{hint:"Use a public artifact URL, or set AGENT_DEVICE_ALLOW_PRIVATE_SOURCE_URLS=1 for trusted private-network daemons."});if((await f.lookup(e.hostname,{all:!0,verbatim:!0}).catch(()=>[])).some(e=>nK(e.address)))throw new b("INVALID_ARGS",`Source URL host resolved to a private or loopback address: ${e.hostname}`,{hint:"Use a public artifact URL, or set AGENT_DEVICE_ALLOW_PRIVATE_SOURCE_URLS=1 for trusted private-network daemons."})}}function nX(e){var t,n,r,i;let a=e instanceof URL?e:new URL(e),o=a.hostname.toLowerCase();if(!o)return!1;let s=a.pathname;return t=o,n=s,("api.github.com"===t?/^\/repos\/[^/]+\/[^/]+\/actions\/artifacts\/\d+\/zip$/i.test(n):"github.com"===t&&/^\/[^/]+\/[^/]+\/(?:actions\/runs\/\d+\/artifacts\/\d+|suites\/\d+\/artifacts\/\d+)$/i.test(n))||(r=o,i=s,("expo.dev"===r||!!r.endsWith(".expo.dev"))&&/^\/(?:artifacts\/eas\/|accounts\/[^/]+\/projects\/[^/]+\/builds\/)/i.test(i))}function nK(e){let t,n=m.isIP(e);return 4===n?function(e){let t=e.split(".").map(e=>Number.parseInt(e,10));if(4!==t.length||t.some(e=>Number.isNaN(e)||e<0||e>255))return!1;let[n,r]=t;return 10===n||127===n||169===n&&254===r||172===n&&!!(r>=16)&&!!(r<=31)||192===n&&168===r}(e):6===n&&!!("::1"===(t=e.toLowerCase())||t.startsWith("fc")||t.startsWith("fd")||t.startsWith("fe80:"))}async function nY(e,t){let n=await a.stat(e).catch(()=>null);if(!n)throw new b("INVALID_ARGS",`App source not found: ${e}`);if(t.isInstallablePath(e,n))return{archivePath:t.archivePath,installablePath:e};if(n.isFile()&&n0(e)){if(!t.allowArchiveExtraction)throw new b("INVALID_ARGS",`URL sources must point directly to a ${t.installableLabel}; archive extraction is not allowed`,{path:e});let n=await nQ(e);return t.registerCleanup(n.cleanup),await nY(n.outputPath,{...t,archivePath:t.archivePath??e})}if(n.isDirectory()){let n=await nZ(e,t.isInstallablePath);if(1===n.length)return{archivePath:t.archivePath,installablePath:n[0]};if(n.length>1)throw new b("INVALID_ARGS",`Found multiple ${t.installableLabel} candidates under ${e}`,{matches:n});let r=await nZ(e,(e,t)=>t.isFile()&&n0(e));if(1===r.length){if(!t.allowArchiveExtraction)throw new b("INVALID_ARGS",`URL sources must point directly to a ${t.installableLabel}; nested archives are not allowed`,{path:r[0]});let e=await nQ(r[0]);return t.registerCleanup(e.cleanup),await nY(e.outputPath,{...t,archivePath:t.archivePath??r[0]})}if(r.length>1)throw new b("INVALID_ARGS",`Found multiple nested archives under ${e}; expected one ${t.installableLabel} source`,{matches:r})}throw new b("INVALID_ARGS",`Expected ${t.installableLabel} source, but got ${e}`)}async function nZ(e,t){let n=[],r=[{path:e,depth:0}];for(;r.length>0;){let e=r.shift();if(!e)continue;let i=await a.readdir(e.path,{withFileTypes:!0});for(let a of(i.sort((e,t)=>e.name.localeCompare(t.name)),i)){let i=o.join(e.path,a.name);if(t(i,a)){n.push(i);continue}a.isDirectory()&&e.depth<5&&r.push({path:i,depth:e.depth+1})}}return n}async function nQ(e){let t=await a.mkdtemp(o.join(l.tmpdir(),"agent-device-archive-"));try{return e.toLowerCase().endsWith(".zip")?await _("ditto",["-x","-k",e,t]):e.toLowerCase().endsWith(".tar.gz")||e.toLowerCase().endsWith(".tgz")?await _("tar",["-xzf",e,"-C",t]):await _("tar",["-xf",e,"-C",t]),{outputPath:t,cleanup:async()=>{await a.rm(t,{recursive:!0,force:!0})}}}catch(e){throw await a.rm(t,{recursive:!0,force:!0}),e}}function n0(e){let t=e.toLowerCase();return nB.some(e=>t.endsWith(e))}async function n1(e){for(let t=e.length-1;t>=0;t-=1)await e[t]()}let n2=new w("utf-16le");async function n3(e){for(let n of["AndroidManifest.xml","base/manifest/AndroidManifest.xml"]){var t;let r=await n4(e,n);if(!r)continue;let i=(t=r).subarray(0,Math.min(t.length,128)).toString("utf8").trimStart().startsWith("<")?function(e){let t=e.match(/<manifest\b[^>]*\bpackage\s*=\s*["']([^"']+)["']/i);return t?.[1]}(t.toString("utf8")):function(e){let t;if(!(e.length<8)&&3===e.readUInt16LE(0))for(let n=e.readUInt16LE(2);n+8<=e.length;){let r=e.readUInt16LE(n),i=e.readUInt16LE(n+2),a=e.readUInt32LE(n+4);if(a<=0||n+a>e.length)break;if(1===r)t=function(e){if(e.length<28)return[];let t=e.readUInt32LE(8),n=e.readUInt32LE(16),r=e.readUInt32LE(20),i=(256&n)!=0,a=[];for(let n=0;n<t;n+=1){let t=28+4*n;if(t+4>e.length)break;let o=r+e.readUInt32LE(t);a.push(i?function(e,t){let[,n]=n5(e,t),[r,i]=n5(e,t+n),a=t+n+i;return e.subarray(a,a+r).toString("utf8")}(e,o):function(e,t){let[n,r]=function(e,t){let n=e.readUInt16LE(t);return(32768&n)==0?[n,2]:[(32767&n)<<16|e.readUInt16LE(t+2),4]}(e,t),i=t+r;return n2.decode(e.subarray(i,i+2*n))}(e,o))}return a}(e.subarray(n,n+a));else if(258===r&&t){let r=function(e,t,n,r){if(n<36||t+n>e.length||"manifest"!==r[e.readUInt32LE(t+20)])return;let i=e.readUInt16LE(t+24),a=e.readUInt16LE(t+26),o=e.readUInt16LE(t+28),s=t+i;for(let t=0;t<o;t+=1){let n=s+t*a;if(n+20>e.length)break;if("package"!==r[e.readUInt32LE(n+4)])continue;let i=e.readUInt32LE(n+8);if(0xffffffff!==i)return r[i];let o=e.readUInt8(n+15),l=e.readUInt32LE(n+16);if(3===o)return r[l];break}}(e,n,i,t);if(r)return r}n+=a}}(t);if(i)return i}return await n8(e)}async function n4(e,t){try{let n=await _("unzip",["-p",e,t],{allowFailure:!0,binaryStdout:!0});if(0!==n.exitCode||!n.stdoutBuffer||0===n.stdoutBuffer.length)return;return n.stdoutBuffer}catch{return}}function n5(e,t){let n=e.readUInt8(t);return(128&n)==0?[n,1]:[(127&n)<<8|e.readUInt8(t+1),2]}async function n8(e){let t=await n6();if(!t)return;let n=await _(t,["dump","badging",e],{allowFailure:!0});if(0!==n.exitCode)return;let r=n.stdout.match(/package:\s+name='([^']+)'/);return r?.[1]}async function n6(){if(void 0!==e)return e??void 0;try{for(let t of t0()){let n=o.join(t,"build-tools");try{for(let t of(await h.readdir(n)).sort((e,t)=>t.localeCompare(e,void 0,{numeric:!0}))){let r=o.join(n,t,"aapt");try{return await h.access(r),e=r,r}catch{}}}catch{}}}catch{}e=null}async function n9(e,t){let n="url"===e.kind&&nX(e.url),r=await nW({source:e,isInstallablePath:(e,t)=>{var n;let r;return t.isFile()&&(n=e,".apk"===(r=o.extname(n).toLowerCase())||".aab"===r)},installableLabel:"Android installable (.apk or .aab)",allowArchiveExtraction:"url"!==e.kind||n,signal:t?.signal}),i=t?.resolveIdentity===!1?{}:await n7(r.installablePath);return{archivePath:r.archivePath,installablePath:r.installablePath,packageName:i.packageName,cleanup:r.cleanup}}async function n7(e){let t=o.extname(e).toLowerCase();return".apk"!==t&&".aab"!==t?{}:{packageName:await n3(e)}}let re={settings:{type:"intent",value:"android.settings.SETTINGS"}},rt="android.intent.category.LAUNCHER",rn="android.intent.category.LEANBACK_LAUNCHER",rr="android.intent.category.DEFAULT",ri="Run agent-device apps --platform android to discover the installed package name, then retry open with that exact package.";async function ra(e,t){let n=t.trim();if("package"===nU(n))return{type:"package",value:n};let r=re[n.toLowerCase()];if(r)return r;let i=(await _("adb",t3(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===i.length)return{type:"package",value:i[0]};if(i.length>1)throw new b("INVALID_ARGS",`Multiple packages matched "${t}"`,{matches:i,hint:"Run agent-device apps --platform android to see the exact installed package names before retrying open."});throw new b("APP_NOT_INSTALLED",`No package found matching "${t}"`,{hint:ri})}async function ro(e,t="all"){let n=await rs(e);return("user-installed"===t?(await ru(e)).filter(e=>n.has(e)):Array.from(n)).sort((e,t)=>e.localeCompare(t)).map(e=>({package:e,name:rd(e)}))}async function rs(e){let t=new Set;for(let n of rl(e,{includeFallbackWhenUnknown:!0})){let r=await _("adb",t3(e,["shell","cmd","package","query-activities","--brief","-a","android.intent.action.MAIN","-c",n]),{allowFailure:!0});if(0===r.exitCode&&0!==r.stdout.trim().length)for(let e of r.stdout.split("\n")){let n=e.trim();if(!n)continue;let r=n.split(/\s+/)[0],i=r.includes("/")?r.split("/")[0]:r;i&&t.add(i)}}return t}function rl(e,t={}){return"tv"===e.target?[rn]:"mobile"===e.target?[rt]:t.includeFallbackWhenUnknown?[rt,rn]:[rt]}async function ru(e){return(await _("adb",t3(e,["shell","pm","list","packages","-3"]))).stdout.split("\n").map(e=>e.replace("package:","").trim()).filter(Boolean)}function rd(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),r=n[n.length-1]??e;for(let e=n.length-1;e>=0;e-=1){let i=n[e];if(!t.has(i)){r=i;break}}return r.split(/[^a-z0-9]+/i).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(" ")}async function rc(e){let t=await rp(e,[["shell","dumpsys","window","windows"],["shell","dumpsys","window"]]);if(t)return t;let n=await rp(e,[["shell","dumpsys","activity","activities"],["shell","dumpsys","activity"]]);return n||{}}async function rp(e,t){for(let n of t){let t=function(e){for(let t of[/mCurrentFocus=Window\{[^}]*\s([\w.]+)\/([\w.$]+)/,/mFocusedApp=AppWindowToken\{[^}]*\s([\w.]+)\/([\w.$]+)/,/mResumedActivity:.*?\s([\w.]+)\/([\w.$]+)/,/ResumedActivity:.*?\s([\w.]+)\/([\w.$]+)/]){let n=t.exec(e);if(n)return{package:n[1],activity:n[2]}}return null}((await _("adb",t3(e,n),{allowFailure:!0})).stdout??"");if(t)return t}return null}async function rf(e,t,n){var r,i;let a;e.booted||await nP(e.id);let o=t.trim();if(t6(o)){if(n)throw new b("INVALID_ARGS","Activity override is not supported when opening a deep link URL");await _("adb",t3(e,["shell","am","start","-W","-a","android.intent.action.VIEW","-d",o]));return}let s=await ra(e,t),l=rl(e)[0]??rt;if("intent"===s.type){if(n)throw new b("INVALID_ARGS","Activity override requires a package name, not an intent");await _("adb",t3(e,["shell","am","start","-W","-a",s.value]));return}if(n){let t=n.includes("/")?n:`${s.value}/${n.startsWith(".")?n:`.${n}`}`;try{await _("adb",t3(e,["shell","am","start","-W","-a","android.intent.action.MAIN","-c",rr,"-c",l,"-n",t]))}catch(t){throw await rw(e,s.value,t),t}return}let u=await _("adb",t3(e,["shell","am","start","-W","-a","android.intent.action.MAIN","-c",rr,"-c",l,"-p",s.value]),{allowFailure:!0});if(0===u.exitCode&&(r=u.stdout,i=u.stderr,a=`${r}
6
- ${i}`,!/Error:.*(?:Activity not started|unable to resolve Intent)/i.test(a)))return;let d=await ry(e,s.value);if(!d){if(!await rh(e,s.value))throw rm(s.value);throw new b("COMMAND_FAILED",`Failed to launch ${s.value}`,{stdout:u.stdout,stderr:u.stderr})}await _("adb",t3(e,["shell","am","start","-W","-a","android.intent.action.MAIN","-c",rr,"-c",l,"-n",d]))}function rm(e){return new b("APP_NOT_INSTALLED",`No package found matching "${e}"`,{package:e,hint:ri})}async function rh(e,t){let n=await _("adb",t3(e,["shell","pm","path",t]),{allowFailure:!0}),r=`${n.stdout}
7
- ${n.stderr}`;return!!(0===n.exitCode&&/\bpackage:/i.test(r))||(rg(r),!1)}async function rw(e,t,n){if(rg(n instanceof b?`${String(n.details?.stdout??"")}
8
- ${String(n.details?.stderr??"")}`:"")||!await rh(e,t))throw rm(t)}function rg(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 ry(e,t){for(let n of Array.from(new Set(rl(e,{includeFallbackWhenUnknown:!0})))){let r=await _("adb",t3(e,["shell","cmd","package","resolve-activity","--brief","-a","android.intent.action.MAIN","-c",n,t]),{allowFailure:!0});if(0!==r.exitCode)continue;let i=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}(r.stdout);if(i)return i}return null}async function rI(e){e.booted||await nP(e.id)}async function rv(e,t){if("settings"===t.trim().toLowerCase())return void await _("adb",t3(e,["shell","am","force-stop","com.android.settings"]));let n=await ra(e,t);if("intent"===n.type)throw new b("INVALID_ARGS","Close requires a package name, not an intent");await _("adb",t3(e,["shell","am","force-stop",n.value]))}async function rb(e,t){let n=await ra(e,t);if("intent"===n.type)throw new b("INVALID_ARGS","App uninstall requires a package name, not an intent");let r=await _("adb",t3(e,["uninstall",n.value]),{allowFailure:!0});if(0!==r.exitCode){let e=`${r.stdout}
9
- ${r.stderr}`.toLowerCase();if(!e.includes("unknown package")&&!e.includes("not installed"))throw new b("COMMAND_FAILED",`adb uninstall failed for ${n.value}`,{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode})}return{package:n.value}}let rA=null;async function rS(){let e=`${process.env.PATH??""}::${process.env.AGENT_DEVICE_BUNDLETOOL_JAR??""}`;if(rA?.key===e)return rA.invocation;if(await D("bundletool")){let t={cmd:"bundletool",prefixArgs:[]};return rA={key:e,invocation:t},t}let t=process.env.AGENT_DEVICE_BUNDLETOOL_JAR?.trim();if(!t)throw new b("TOOL_MISSING","bundletool not found in PATH. Install bundletool or set AGENT_DEVICE_BUNDLETOOL_JAR to a bundletool-all.jar path.");try{await a.access(t)}catch{throw new b("TOOL_MISSING",`AGENT_DEVICE_BUNDLETOOL_JAR points to a missing file: ${t}`)}let n={cmd:"java",prefixArgs:["-jar",t]};return rA={key:e,invocation:n},n}async function rx(e){let t=await rS();await _(t.cmd,[...t.prefixArgs,...e])}async function r_(e,t){let n,r=await a.mkdtemp(o.join(l.tmpdir(),"agent-device-aab-")),i=o.join(r,"bundle.apks"),s=(n=process.env.AGENT_DEVICE_ANDROID_BUNDLETOOL_MODE?.trim())&&n.length>0?n:"universal";try{await rx(["build-apks","--bundle",t,"--output",i,"--mode",s]),await rx(["install-apks","--apks",i,"--device-id",e.id])}finally{await a.rm(r,{recursive:!0,force:!0})}}async function rN(e,t){".aab"===o.extname(t).toLowerCase()?await r_(e,t):await _("adb",t3(e,["install","-r",t]))}async function rE(e){return new Set((await _("adb",t3(e,["shell","pm","list","packages"]))).stdout.split("\n").map(e=>e.replace("package:","").trim()).filter(Boolean))}async function rD(e,t){let n=Array.from(await rE(e)).filter(e=>!t.has(e));if(1===n.length)return n[0]}async function rM(e,t){e.booted||await nP(e.id),await rN(e,t)}async function rC(e,t,n){let r=n?void 0:await rE(e);return await rM(e,t),n??(r?await rD(e,r):void 0)}async function rO(e,t){e.booted||await nP(e.id);let n=await n9({kind:"path",path:t});try{let t=await rC(e,n.installablePath,n.packageName),r=t?rd(t):void 0;return{archivePath:n.archivePath,installablePath:n.installablePath,packageName:t,appName:r,launchTarget:t}}finally{await n.cleanup()}}async function rL(e,t,n){e.booted||await nP(e.id);let{package:r}=await rb(e,t),i=await n9({kind:"path",path:n},{resolveIdentity:!1});try{return await rM(e,i.installablePath),{package:r}}finally{await i.cleanup()}}function rT(e){let t=e.direction,n="up"===t||"down"===t?e.referenceHeight:e.referenceWidth,r=function(e){if(void 0===e)return .6;if(!Number.isFinite(e)||e<=0)throw new b("INVALID_ARGS","scroll amount must be a positive number");return e}(e.amount),i=void 0!==e.pixels?function(e){if(!Number.isFinite(e)||e<=0)throw new b("INVALID_ARGS","scroll pixels must be a positive integer");return Math.max(1,Math.round(e))}(e.pixels):Math.round(n*r),a=Math.max(1,Math.round(.05*n)),o=Math.max(1,Math.min(i,Math.max(1,n-2*a))),s=Math.round(o/2),l=Math.round(e.referenceWidth/2),u=Math.round(e.referenceHeight/2),d=(n,r,i,a)=>({direction:t,x1:n,y1:r,x2:i,y2:a,referenceWidth:e.referenceWidth,referenceHeight:e.referenceHeight,amount:e.amount,pixels:o});switch(t){case"up":return d(l,u-s,l,u+s);case"down":return d(l,u+s,l,u-s);case"left":return d(l-s,u,l+s,u);case"right":return d(l+s,u,l-s,u)}}function rk(e,t){let n=t.toLowerCase(),r=/<node[^>]+>/g,i=r.exec(e);for(;i;){let t=r$(i[0]),a=(rF(t,"text")??"").toLowerCase(),o=(rF(t,"content-desc")??"").toLowerCase();if(a.includes(n)||o.includes(n)){let e=rU(rF(t,"bounds"));if(e)return{x:Math.floor(e.x+e.width/2),y:Math.floor(e.y+e.height/2)};return{x:0,y:0}}i=r.exec(e)}return null}function rR(e,t,n){let r=function(e){let t=0,n=0,r=[...e.children];for(;r.length>0;){let e=r.pop();t+=1,n=Math.max(n,e.depth),r.push(...e.children)}return{rawNodeCount:t,maxDepth:n}}(e),i=[],a=[],o=!1,s=n.depth??1/0,l=n.scope?function(e,t){let n=t.toLowerCase(),r=[...e.children],i=0;for(;i<r.length;){let e=r[i++],t=e.label?.toLowerCase()??"",a=e.value?.toLowerCase()??"",o=e.identifier?.toLowerCase()??"";if(t.includes(n)||a.includes(n)||o.includes(n))return e;r.push(...e.children)}return null}(e,n.scope):null,u=l?[l]:e.children,d=new Map,c=e=>{let t=d.get(e);if(void 0!==t)return t;for(let t of e.children)if(t.hittable||c(t))return d.set(e,!0),!0;return d.set(e,!1),!1},p=(e,r,l,u=!1,d=!1)=>{if(i.length>=t){o=!0;return}if(r>s)return;let f=!!n.raw||function(e,t,n,r,i){var a;let o,s=rG(e.type),l=!!(e.label&&e.label.trim().length>0),u=!!(e.identifier&&e.identifier.trim().length>0),d=l&&!rB(e.label??""),c=u&&!rB(e.identifier??""),p=(o=(a=s).split(".").pop()??a).includes("layout")||"viewgroup"===o||"view"===o,f="imageview"===s||"imagebutton"===s;if(t.interactiveOnly)return!!(e.hittable||ec(s)&&r)||!!(d||c)&&!f&&(!p||!!i)&&(n||r||i);return t.compact?d||c||!!e.hittable:!p&&!f||!!e.hittable||!!d||!!c&&!!r||r}(e,n,u,c(e),d),m=l;f&&(m=i.length,a.push(e),i.push({index:m,type:e.type??void 0,label:e.label??void 0,value:e.value??void 0,identifier:e.identifier??void 0,rect:e.rect,enabled:e.enabled,hittable:e.hittable,depth:r,parentIndex:l,...e.hiddenContentAbove?{hiddenContentAbove:!0}:{},...e.hiddenContentBelow?{hiddenContentBelow:!0}:{}}));let h=u||!!e.hittable,w=d||function(e){if(!e)return!1;let t=rG(e);return t.includes("recyclerview")||t.includes("listview")||t.includes("gridview")}(e.type);for(let t of e.children)if(p(t,r+1,m,h,w),o)return};for(let e of u)if(p(e,0,void 0,!1,!1),o)break;return o?{nodes:i,sourceNodes:a,truncated:o,analysis:r}:{nodes:i,sourceNodes:a,analysis:r}}function rP(e){let t=r$(e),n=e=>{let n=rF(t,e);if(null!==n)return"true"===n};return{text:rF(t,"text"),desc:rF(t,"content-desc"),resourceId:rF(t,"resource-id"),className:rF(t,"class"),bounds:rF(t,"bounds"),clickable:n("clickable"),enabled:n("enabled"),focusable:n("focusable"),focused:n("focused")}}function r$(e){let t=new Map,n=e.indexOf(" "),r=e.lastIndexOf(">");if(n<0||r<=n)return t;let i=/([^\s=/>]+)\s*=\s*(["'])([\s\S]*?)\2/y,a=n;for(;a<r;){for(;a<r;){let t=e[a];if(" "!==t&&"\n"!==t&&"\r"!==t&&" "!==t)break;a+=1}if(a>=r)break;let n=e[a];if("/"===n||">"===n)break;i.lastIndex=a;let o=i.exec(e);if(!o)break;t.set(o[1],o[3]),a=i.lastIndex}return t}function rF(e,t){return e.get(t)??null}function rU(e){if(!e)return;let t=/\[(\d+),(\d+)\]\[(\d+),(\d+)\]/.exec(e);if(!t)return;let n=Number(t[1]),r=Number(t[2]);return{x:n,y:r,width:Math.max(0,Number(t[3])-n),height:Math.max(0,Number(t[4])-r)}}function rV(e){let t={type:null,label:null,value:null,identifier:null,depth:-1,children:[]},n=[t],r=/<node\b[^>]*>|<\/node>/g,i=r.exec(e);for(;i;){let t=i[0];if(t.startsWith("</node")){n.length>1&&n.pop(),i=r.exec(e);continue}let a=rP(t),o=rU(a.bounds),s=n[n.length-1],l={type:a.className,label:a.text||a.desc,value:a.text,identifier:a.resourceId,rect:o,enabled:a.enabled,hittable:a.clickable??a.focusable,depth:s.depth+1,parentIndex:void 0,children:[]};s.children.push(l),t.endsWith("/>")||n.push(l),i=r.exec(e)}return t}function rG(e){return e?e.toLowerCase():""}function rB(e){let t=e.trim();return!!t&&/^[\w.]+:id\/[\w.-]+$/i.test(t)}function rj(e){if(0===e.length)return null;let t=[...e].sort((e,t)=>e-t);return t[Math.floor(t.length/2)]??null}function rq(e,t){let n=Math.max(24,Math.round(.2*Math.min(e.size,t.size))),r=Math.max(48,Math.round(.15*Math.min(e.crossSize,t.crossSize)));return Math.abs(e.size-t.size)<=n&&Math.abs(e.crossSize-t.crossSize)<=r}function rW(e,t){return{start:e.y-t.y,size:e.height,crossSize:e.width}}async function rz(e,t={}){let n=await rJ(e);if(!t.interactiveOnly){let r=function(e,t){let{sourceNodes:n,...r}=rR(rV(e),800,t);return r}(n,t);return await rH(e,r.nodes),r}let r=rV(n),i=rR(r,800,{...t,interactiveOnly:!1});await rH(e,i.nodes),function(e){if(0===e.length||e.some(e=>e.hiddenContentAbove||e.hiddenContentBelow))return;let t=new Map(ef(en(e)).nodes.filter(e=>e.hiddenContentAbove||e.hiddenContentBelow).map(e=>[e.index,e]));for(let n of e){let e=t.get(n.index);e&&(e.hiddenContentAbove&&(n.hiddenContentAbove=!0),e.hiddenContentBelow&&(n.hiddenContentBelow=!0))}}(i.nodes),function(e){for(let[t,n]of e.sourceNodes.entries()){let r=e.nodes[t];r&&(r.hiddenContentAbove&&(n.hiddenContentAbove=!0),r.hiddenContentBelow&&(n.hiddenContentBelow=!0))}}(i);let{sourceNodes:a,...o}=rR(r,800,t);return o}async function rH(e,t){if(!t.some(e=>ec(e.type)))return;let n=await rZ(e);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}],r=/^(\s*)([\w.$]+)\{[^}]* (-?\d+),(-?\d+)-(-?\d+),(-?\d+) #/;for(let t of e.split("\n")){let e=r.exec(t);if(!e)continue;let i=e[1].length,a=Number(e[3]),o=Number(e[4]),s=Number(e[5]),l=Number(e[6]),u={className:e[2],rect:{x:a,y:o,width:Math.max(0,s-a),height:Math.max(0,l-o)},children:[]};for(;n.length>1&&i<=n[n.length-1].indent;)n.pop();n[n.length-1].node.children.push(u),n.push({indent:i,node:u})}return t.children.length>0?t:null}(t);if(!n)return;let r=function(e){let t=[],n=[e];for(;n.length>0;){let e=n.pop();if(ec(e.className)){let n=function(e){let t=e.children[0];if(!t)return null;let n=Math.max(t.rect.height,...t.children.map(e=>e.rect.y+e.rect.height)),r=t.children.filter(e=>e.rect.height>0).map(t=>rW(t.rect,e.rect)).sort((e,t)=>e.start-t.start);return 0===r.length?null:{rect:e.rect,contentExtent:n,contentBlocks:r}}(e);n&&t.push(n)}n.push(...e.children)}return t}(n);if(0!==r.length)for(let t of e){if(!t.rect||!ec(t.type))continue;let n=function(e,t){let n=null,r=1/0;for(let i of t){let t=Math.abs(i.rect.width-e.width)+Math.abs(i.rect.height-e.height);if(t>32)continue;let a=4*t+(Math.abs(i.rect.x-e.x)+Math.abs(i.rect.y-e.y));a<r&&(n=i,r=a)}return n}(t.rect,r);if(!n)continue;let i=function(e,t){let n=function(e,t){let n=t,r=new Set;for(;!r.has(n.index);){var i,a;r.add(n.index);let o=e.filter(e=>e.parentIndex===n.index&&e.rect);if(1!==o.length)return n;let s=o[0];if(i=s.rect,a=t.rect,i.x!==a.x||i.y!==a.y||i.width!==a.width||i.height!==a.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=>rW(e,t.rect))}(e,t),a=function(e){let{viewportRect:t,visibleBlocks:n,nativeScrollView:r}=e;if(0===n.length||0===r.contentBlocks.length)return null;let i=function(e){if(0===e.contentBlocks.length)return null;let t=e.contentBlocks[0],n=e.contentBlocks[e.contentBlocks.length-1];if(!t||!n)return null;let r=rj(e.contentBlocks.map(e=>e.size))??e.rect.height,i=Math.max(48,Math.round(.5*r)),a=Math.max(24,Math.round(.25*r)),o=t.start>=i,s=e.contentExtent-(n.start+n.size)>=a;return o||s?{above:o,below:s}:null}(r),a=function(e,t){let n=new Map;for(let r of e)for(let e of t){if(!rq(r,e))continue;let t=r.start-e.start,i=8*Math.round(t/8),a=n.get(i)??[];a.push(t),n.set(i,a)}let r=null;for(let e of n.values())(!r||e.length>r.length)&&(r=e);if(!r||r.length<2)return null;let i=[...r].sort((e,t)=>e-t);return i[Math.floor(i.length/2)]??null}(r.contentBlocks,n)??function(e){let{nativeBlocks:t,visibleBlocks:n,viewportExtent:r,contentExtent:i}=e,a=[],o=[];for(let e of t)for(let t of n){if(!rq(e,t))continue;let n=e.start-t.start;16>=Math.abs(n)&&a.push(n),16>=Math.abs(n+r-i)&&o.push(n)}return o.length>0?rj(o):a.length>0?rj(a):null}({nativeBlocks:r.contentBlocks,visibleBlocks:n,viewportExtent:t.height,contentExtent:r.contentExtent});if(null===a)return i;let o=t.height;return{above:(i?.above??!1)||a>16,below:(i?.below??!1)||a+o<r.contentExtent-16}}({viewportRect:t.rect,visibleBlocks:i,nativeScrollView:n});a&&(a.above&&(t.hiddenContentAbove=!0),a.below&&(t.hiddenContentBelow=!0))}}(t,n)}async function rJ(e){return no(()=>rX(e),{shouldRetry:rY})}async function rX(e){var t,n,r;let i,a,o=await _("adb",t3(e,["exec-out","uiautomator","dump","/dev/tty"]),{allowFailure:!0}),s=rK(o.stdout,o.stderr);if(s)return s;let l="/sdcard/window_dump.xml",u=await _("adb",t3(e,["shell","uiautomator","dump",l]),{allowFailure:!0}),d=(t=l,n=u.stdout,r=u.stderr,i=`${n}
10
- ${r}`,a=/dumped to:\s*(\S+)/i.exec(i),a?.[1]??t),c=await _("adb",t3(e,["shell","cat",d])),p=rK(c.stdout,c.stderr);if(!p)throw new b("COMMAND_FAILED","uiautomator dump did not return XML",{stdout:c.stdout,stderr:c.stderr});return p}function rK(e,t){let n=`${e}
11
- ${t}`,r=n.indexOf("<?xml"),i=r>=0?r:n.indexOf("<hierarchy");if(i<0)return null;let a=n.lastIndexOf("</hierarchy>");if(a<0||a<i)return null;let o=n.slice(i,a+12).trim();return o.length>0?o:null}function rY(e){if(!(e instanceof b)||"COMMAND_FAILED"!==e.code)return!1;let t=`${e.details?.stderr??""}`.toLowerCase();return!!(t.includes("device offline")||t.includes("device not found")||t.includes("transport error")||t.includes("connection reset")||t.includes("broken pipe")||t.includes("timed out")||t.includes("no such file or directory"))}async function rZ(e){try{let t=await _("adb",t3(e,["shell","dumpsys","activity","top"]),{allowFailure:!0,timeoutMs:8e3}),n=`${t.stdout}
12
- ${t.stderr}`.trim();return n.length>0?n:null}catch{return null}}async function rQ(e,t,n){await _("adb",t3(e,["shell","input","tap",String(t),String(n)]))}async function r0(e,t,n,r,i,a=250){await _("adb",t3(e,["shell","input","swipe",String(t),String(n),String(r),String(i),String(a)]))}async function r1(e){await _("adb",t3(e,["shell","input","keyevent","4"]))}async function r2(e){await _("adb",t3(e,["shell","input","keyevent","3"]))}async function r3(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 b("INVALID_ARGS",`Unsupported Android rotation: ${e}`)}}(t);await _("adb",t3(e,["shell","settings","put","system","accelerometer_rotation","0"])),await _("adb",t3(e,["shell","settings","put","system","user_rotation",n]))}async function r4(e){await _("adb",t3(e,["shell","input","keyevent","187"]))}async function r5(e,t,n,r=800){await _("adb",t3(e,["shell","input","swipe",String(t),String(n),String(t),String(n),String(r)]))}async function r8(e,t,n=0){n>0&&Array.from(t).length>1?await io(e,t,1,n):await r6(e,t)}async function r6(e,t){let n=is(t);if(!n||"ok"!==await il(e,t))try{let n=t.replace(/ /g,"%s");await _("adb",t3(e,["shell","input","text",n]))}catch(e){if(n&&function(e){if(!(e instanceof b)||"COMMAND_FAILED"!==e.code)return!1;let t=String(e.details?.stderr??"").toLowerCase();return!!(t.includes("exception occurred while executing 'text'")||t.includes("nullpointerexception")&&t.includes("inputshellcommand.sendtext"))}(e))throw new b("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 r9(e,t,n){await rQ(e,t,n)}async function r7(e,t,n,r,i=0){let a=Array.from(r).length,o=is(r),s=[{strategy:"input_text",clearPadding:12,minClear:8,maxClear:48}];!o&&i<=0&&s.push({strategy:"clipboard_paste",clearPadding:12,minClear:8,maxClear:48}),(!o||i>0)&&s.push({strategy:"chunked_input",clearPadding:24,minClear:16,maxClear:96});let l=null;for(let o of s){var u,d;await r9(e,t,n);let s=(u=a+o.clearPadding,d=o.minClear,Math.max(d,Math.min(o.maxClear,u)));if(await iu(e,s),"input_text"===o.strategy)await r8(e,r,i);else if("clipboard_paste"===o.strategy){if("ok"!==await il(e,r))continue}else await io(e,r,1,i>0?i:15);let c=await ie(e,t,n,r);if(l=c.actual,c.ok)return}throw new b("COMMAND_FAILED","Android fill verification failed",{expected:r,actual:l??null})}async function ie(e,t,n,r){let i=null;for(let a of[0,150,350])if(a>0&&await t8(a),function(e,t){if(e===t)return!0;let n=it(e),r=it(t);return!!n&&!!r&&(!!(n===r||n.includes(r))||r.includes(n)&&n.length>=Math.max(4,Math.floor(.8*r.length)))}(i=await id(e,t,n),r))return{ok:!0,actual:i};return{ok:!1,actual:i}}function it(e){return(e??"").replace(/\s+/g," ").trim()}async function ir(e,t,n){let r=await ia(e),i=rT({direction:t,amount:n?.amount,pixels:n?.pixels,referenceWidth:r.width,referenceHeight:r.height});return await _("adb",t3(e,["shell","input","swipe",String(i.x1),String(i.y1),String(i.x2),String(i.y2),"300"])),i}async function ii(e,t,n){let r=n?.maxScrolls??8,i="";try{i=await rJ(e)}catch(t){let e=t instanceof Error?t.message:String(t);throw new b("UNSUPPORTED_OPERATION",`uiautomator dump failed: ${e}`)}if(rk(i,t))return{attempts:0};for(let n=1;n<=r;n+=1){await ir(e,"down",{amount:.5});let r="";try{r=await rJ(e)}catch(t){let e=t instanceof Error?t.message:String(t);throw new b("UNSUPPORTED_OPERATION",`uiautomator dump failed: ${e}`)}if(rk(r,t))return{attempts:n};if(r===i)throw new b("COMMAND_FAILED",`scrollintoview could not find text: ${t}`,{reason:"not_found",attempts:n,stalled:!0});i=r}throw new b("COMMAND_FAILED",`scrollintoview could not find text: ${t}`,{reason:"not_found",attempts:r})}async function ia(e){let t=(await _("adb",t3(e,["shell","wm","size"]))).stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(!t)throw new b("COMMAND_FAILED","Unable to read screen size");return{width:Number(t[1]),height:Number(t[2])}}async function io(e,t,n,r){let i=Math.max(1,Math.floor(n)),a=Array.from(t);for(let t=0;t<a.length;t+=i){let n=a.slice(t,t+i).join("");await r6(e,n),r>0&&t+i<a.length&&await t8(r)}}function is(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 il(e,t){let n=await _("adb",t3(e,["shell","cmd","clipboard","set","text",t]),{allowFailure:!0});return 0!==n.exitCode?"failed":t5(n.stdout,n.stderr)?"unsupported":0===(await _("adb",t3(e,["shell","input","keyevent","KEYCODE_PASTE"]),{allowFailure:!0})).exitCode||0===(await _("adb",t3(e,["shell","input","keyevent","279"]),{allowFailure:!0})).exitCode?"ok":"failed"}async function iu(e,t){let n=Math.max(0,t);await _("adb",t3(e,["shell","input","keyevent","KEYCODE_MOVE_END"]),{allowFailure:!0});for(let t=0;t<n;t+=24){let r=Math.min(24,n-t);await _("adb",t3(e,["shell","input","keyevent",...Array(r).fill("KEYCODE_DEL")]),{allowFailure:!0})}}async function id(e,t,n){let r,i=await rJ(e),a=/<node\b[^>]*>/g,o=null,s=null,l=null;for(;null!==(r=a.exec(i));){let e=rP(r[0]),i=rU(e.bounds);if(!i)continue;let a=e.className??"",u=(e.text??"").replace(/&quot;/g,'"').replace(/&apos;/g,"'").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&amp;/g,"&"),d=e.focused??!1;if(!u)continue;let c=Math.max(1,i.width*i.height),p=t>=i.x&&t<=i.x+i.width&&n>=i.y&&n<=i.y+i.height;if(d&&ic(a)){(!o||c<=o.area)&&(o={text:u,area:c});continue}if(p&&ic(a)){(!s||c<=s.area)&&(s={text:u,area:c});continue}p&&(!l||c<=l.area)&&(l={text:u,area:c})}return o?.text??s?.text??l?.text??null}function ic(e){let t=e.toLowerCase();return t.includes("edittext")||t.includes("textfield")}async function ip(e){let t=await _("adb",t3(e,["shell","dumpsys","input_method"]),{allowFailure:!0});if(0!==t.exitCode)throw new b("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],r=n[2]?.toLowerCase();e&&("true"===r||"false"===r)&&t.set(e,"true"===r)}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 r=Array.from(e.matchAll(/\binputType=0x([0-9a-fA-F]+)\b/gi)),i=r.length>0?r[r.length-1]?.[1]:void 0,a=i?`0x${i.toLowerCase()}`:void 0;return{visible:n,inputType:a,type:a?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 r=4080&t;return 32===r||208===r?"email":128===r||224===r||144===r?"password":"text"}(a):void 0}}(t.stdout)}async function im(e){let t=await ip(e),n=t,r=0;for(;n.visible&&r<2;)await _("adb",t3(e,["shell","input","keyevent","111"])),r+=1,await t8(120),n=await ip(e);if(t.visible&&n.visible)throw new b("UNSUPPORTED_OPERATION","Android keyboard dismiss is unavailable for the current IME without back navigation.",{attempts:r,inputType:n.inputType,type:n.type});return{attempts:r,wasVisible:t.visible,dismissed:t.visible&&!n.visible,visible:n.visible,inputType:n.inputType,type:n.type}}async function ih(e){let t,n;return(n=(t=(await ig(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 iw(e,t){await ig(e,["shell","cmd","clipboard","set","text",t],"write")}async function ig(e,t,n){let r=await _("adb",t3(e,t),{allowFailure:!0});if(t5(r.stdout,r.stderr))throw new b("UNSUPPORTED_OPERATION",`Android shell clipboard ${n} is not supported on this device.`);if(0!==r.exitCode)throw new b("COMMAND_FAILED",`Failed to ${n} Android clipboard text`,{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode});return r.stdout}let iy=["camera","microphone","photos","contacts","contacts-limited","notifications","calendar","location","location-always","media-library","motion","reminders","siri"];function iI(e){let t=e.trim().toLowerCase();if("grant"===t)return"grant";if("deny"===t)return"deny";if("reset"===t)return"reset";throw new b("INVALID_ARGS",`Invalid permission action: ${e}. Use grant|deny|reset.`)}function iv(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 b("INVALID_ARGS",`permission setting requires a target: ${iy.join("|")}`)}function ib(e){let t=e.trim().toLowerCase();if("light"===t)return"light";if("dark"===t)return"dark";if("toggle"===t)return"toggle";throw new b("INVALID_ARGS",`Invalid appearance state: ${e}. Use light|dark|toggle.`)}async function iA(e,t,n,r,i){switch(t.toLowerCase()){case"wifi":{let t=ix(n);await _("adb",t3(e,["shell","svc","wifi",t?"enable":"disable"]));return}case"airplane":{let t=ix(n);await _("adb",t3(e,["shell","settings","put","global","airplane_mode_on",t?"1":"0"])),await _("adb",t3(e,["shell","am","broadcast","-a","android.intent.action.AIRPLANE_MODE","--ez","state",t?"true":"false"]));return}case"location":{let t=ix(n);await _("adb",t3(e,["shell","settings","put","secure","location_mode",t?"3":"0"]));return}case"appearance":{let t=await i_(e,n);await _("adb",t3(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 b("INVALID_ARGS",`Invalid fingerprint state: ${e}. Use match|nonmatch.`)}(n);await iS(e,t);return}case"permission":{if(!r)throw new b("INVALID_ARGS","permission setting requires an active app in session");let t=iI(n),a=function(e,t){let n=iv(e);if(t?.trim())throw new b("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 b("INVALID_ARGS",`Unsupported permission target on Android: ${e}. Use camera|microphone|photos|contacts|notifications.`)}(i?.permissionTarget,i?.permissionMode);if("notifications"===a.kind)return void await iE(e,r,t,a);let o="grant"===t?"grant":"revoke";if("photos"===a.type)return void await iN(e,r,o);await _("adb",t3(e,["shell","pm",o,r,a.value]));return}default:throw new b("INVALID_ARGS",`Unsupported setting: ${t}`)}}async function iS(e,t){var n;let r,i,a=(n=e,i=[["shell","cmd","fingerprint","touch",r="match"===t?"1":"9999"],["shell","cmd","fingerprint","finger",r]],"emulator"===n.kind&&i.push(["emu","finger","touch",r]),i),o=[];for(let t of a){let n=await _("adb",t3(e,t),{allowFailure:!0});if(0===n.exitCode)return;o.push({args:t,stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode})}let s=o.map(e=>({args:e.args.join(" "),exitCode:e.exitCode,stderr:e.stderr.slice(0,400)}));if(o.length>0&&o.every(e=>{var t,n;let r;return t=e.stdout,n=e.stderr,(r=`${t}
13
- ${n}`.toLowerCase()).includes("unknown command")||r.includes("can't find service: fingerprint")||r.includes("service fingerprint was not found")||r.includes("fingerprint cmd unavailable")||r.includes("emu command is not supported")||r.includes("emulator console is not running")||r.includes("fingerprint")&&r.includes("not found")}))throw new b("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 b("COMMAND_FAILED","Failed to simulate Android fingerprint.",{deviceId:e.id,action:t,attempts:s})}function ix(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 b("INVALID_ARGS",`Invalid setting state: ${e}`)}async function i_(e,t){let n=ib(t);if("toggle"!==n)return n;let r=await _("adb",t3(e,["shell","cmd","uimode","night"]),{allowFailure:!0});if(0!==r.exitCode)throw new b("COMMAND_FAILED","Failed to read current Android appearance",{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode});let i=function(e,t){let n=/night mode:\s*(yes|no|auto)\b/i.exec(`${e}
14
- ${t}`);if(!n)return null;let r=n[1].toLowerCase();return"yes"===r?"dark":"no"===r?"light":"auto"===r?"auto":null}(r.stdout,r.stderr);if(!i)throw new b("COMMAND_FAILED","Unable to determine current Android appearance for toggle",{stdout:r.stdout,stderr:r.stderr});return"auto"===i?"dark":"dark"===i?"light":"dark"}async function iN(e,t,n){let r=await iD(e),i=[];for(let a of null!==r&&r>=33?["android.permission.READ_MEDIA_IMAGES","android.permission.READ_EXTERNAL_STORAGE"]:["android.permission.READ_EXTERNAL_STORAGE","android.permission.READ_MEDIA_IMAGES"]){let r=await _("adb",t3(e,["shell","pm",n,t,a]),{allowFailure:!0});if(0===r.exitCode)return;i.push({permission:a,stderr:r.stderr,exitCode:r.exitCode})}throw new b("COMMAND_FAILED",`Failed to ${n} Android photos permission`,{appPackage:t,sdkInt:r,attempts:i})}async function iE(e,t,n,r){"grant"===n?await _("adb",t3(e,["shell","pm","grant",t,r.permission]),{allowFailure:!0}):(await _("adb",t3(e,["shell","pm","revoke",t,r.permission]),{allowFailure:!0}),"reset"===n&&(await _("adb",t3(e,["shell","pm","clear-permission-flags",t,r.permission,"user-set"]),{allowFailure:!0}),await _("adb",t3(e,["shell","pm","clear-permission-flags",t,r.permission,"user-fixed"]),{allowFailure:!0}))),await _("adb",t3(e,["shell","appops","set",t,r.appOps,"grant"===n?"allow":"deny"===n?"deny":"default"]))}async function iD(e){let t=await _("adb",t3(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 iM(e,t,n){let r="string"==typeof n.action&&n.action.trim()?n.action.trim():`${t}.TEST_PUSH`,i=["shell","am","broadcast","-a",r,"-p",t],a="string"==typeof n.receiver?n.receiver.trim():"";a&&i.push("-n",a);let o=n.extras;if(void 0!==o&&("object"!=typeof o||null===o||Array.isArray(o)))throw new b("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 b("INVALID_ARGS",`Unsupported Android broadcast extra type for "${t}". Use string, boolean, or number.`)}(i,e,t),s+=1);return await _("adb",t3(e,i)),{action:r,extrasCount:s}}let iC=Buffer.from([137,80,78,71,13,10,26,10]);async function iO(e,t){await iL(e);try{await t8(1e3),await ik(e,t)}finally{await iT(e).catch(()=>{})}}async function iL(e){let t=t=>_("adb",t3(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 iT(e){await _("adb",t3(e,["shell","am broadcast -a com.android.systemui.demo -e command exit"]),{allowFailure:!0})}async function ik(e,t){let n=await _("adb",t3(e,["exec-out","screencap","-p"]),{binaryStdout:!0});if(!n.stdoutBuffer)throw new b("COMMAND_FAILED","Failed to capture screenshot");let r=n.stdoutBuffer.indexOf(iC);if(r<0)throw new b("COMMAND_FAILED","Screenshot data does not contain a valid PNG header");let i=function(e,t){let n=t+iC.length;for(;n+8<=e.length;){let t=e.readUInt32BE(n),r=n+4,i=e.toString("ascii",r,r+4),a=n+12+t;if(a>e.length)break;if("IEND"===i)return a;n=a}return null}(n.stdoutBuffer,r);if(!i)throw new b("COMMAND_FAILED","Screenshot data does not contain a complete PNG payload");await a.writeFile(t,n.stdoutBuffer.subarray(r,i))}let iR=nG(process.env.AGENT_DEVICE_IOS_BOOT_TIMEOUT_MS,nn,5e3),iP=nG(process.env.AGENT_DEVICE_IOS_SIMCTL_LIST_TIMEOUT_MS,nt,1e3),i$=nG(process.env.AGENT_DEVICE_IOS_APP_LAUNCH_TIMEOUT_MS,3e4,5e3),iF=nG(process.env.AGENT_DEVICE_IOS_DEVICECTL_TIMEOUT_MS,2e4,1e3),iU=nG(process.env.AGENT_DEVICE_IOS_SIMULATOR_FOCUS_TIMEOUT_MS,1e4,1e3),iV=nG(process.env.AGENT_DEVICE_IOS_SIMULATOR_SCREENSHOT_TIMEOUT_MS,2e4,1e3),iG=nG(process.env.AGENT_DEVICE_IOS_RUNNER_SCREENSHOT_COPY_TIMEOUT_MS,2e4,1e3),iB=ne(process.env.AGENT_DEVICE_IOS_SIMULATOR_SCREENSHOT_RUNNER_FALLBACK);async function ij(e,t){let n=["devicectl",...e],r=await _("xcrun",n,{allowFailure:!0,timeoutMs:iF});if(0===r.exitCode)return;let i=String(r.stdout??""),a=String(r.stderr??"");throw new b("COMMAND_FAILED",`Failed to ${t.action}`,{cmd:"xcrun",args:n,exitCode:r.exitCode,stdout:i,stderr:a,deviceId:t.deviceId,hint:iH(i,a)??iz})}async function iq(e,t){let n=o.join(l.tmpdir(),`agent-device-ios-apps-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),r=["devicectl","device","info","apps","--device",e.id,"--include-all-apps","--json-output",n],i=await _("xcrun",r,{allowFailure:!0,timeoutMs:iF});try{var s,u;if(0!==i.exitCode){let t=String(i.stdout??""),n=String(i.stderr??"");throw new b("COMMAND_FAILED","Failed to list iOS apps",{cmd:"xcrun",args:r,exitCode:i.exitCode,stdout:t,stderr:n,deviceId:e.id,hint:iH(t,n)??iz})}let o=await a.readFile(n,"utf8");return s=function(e){let t=e?.result?.apps;if(!Array.isArray(t))return[];let n=[];for(let e of t){if(!e||"object"!=typeof e)continue;let t="string"==typeof e.bundleIdentifier?e.bundleIdentifier.trim():"";if(!t)continue;let r="string"==typeof e.name&&e.name.trim().length>0?e.name.trim():t,i="string"==typeof e.url&&e.url.trim().length>0?e.url.trim():void 0;n.push({bundleId:t,name:r,url:i})}return n}(JSON.parse(o)),u=t,"user-installed"===u?s.filter(e=>!e.bundleId.startsWith("com.apple.")):s}catch(t){if(t instanceof b)throw t;throw new b("COMMAND_FAILED","Failed to parse iOS apps list",{deviceId:e.id,cause:String(t)})}finally{await a.unlink(n).catch(()=>{})}}async function iW(e){let t=o.join(l.tmpdir(),`agent-device-ios-processes-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),n=["devicectl","device","info","processes","--device",e.id,"--json-output",t],r=await _("xcrun",n,{allowFailure:!0,timeoutMs:iF});try{if(0!==r.exitCode){let t=String(r.stdout??""),i=String(r.stderr??"");throw new b("COMMAND_FAILED","Failed to list iOS processes",{cmd:"xcrun",args:n,exitCode:r.exitCode,stdout:t,stderr:i,deviceId:e.id,hint:iH(t,i)??iz})}let i=await a.readFile(t,"utf8");return function(e){let t=e?.result?.runningProcesses;if(!Array.isArray(t))return[];let n=[];for(let e of t){if(!e||"object"!=typeof e)continue;let t="string"==typeof e.executable?e.executable.trim():"",r="number"==typeof e.processIdentifier&&Number.isFinite(e.processIdentifier)?e.processIdentifier:NaN;t&&Number.isFinite(r)&&n.push({executable:t,pid:r})}return n}(JSON.parse(i))}catch(t){if(t instanceof b)throw t;throw new b("COMMAND_FAILED","Failed to parse iOS process list",{deviceId:e.id,cause:String(t)})}finally{await a.unlink(t).catch(()=>{})}}let iz="Ensure the iOS device is unlocked, trusted, and available in Xcode > Devices, then retry.";function iH(e,t){let n=`${e}
15
- ${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 iJ(e,t={}){let n=np(t.simulatorSetPath);return n?["simctl","--set",n,...e]:["simctl",...e]}function iX(e,t){return"ios"!==e.platform||"simulator"!==e.kind?["simctl",...t]:iJ(t,{simulatorSetPath:e.simulatorSetPath})}function iK(e){if(!(e instanceof b)||"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 iY(e,t){let n=await _("xcrun",iX(e,["get_app_container",e.id,t]),{allowFailure:!0});if(0!==n.exitCode)return{installed:!1};let r=n.stdout.trim();if(!r)return{installed:!1};let i=await _("plutil",["-extract","CFBundleExecutable","raw","-o","-",`${r}/Info.plist`],{allowFailure:!0});if(0!==i.exitCode||!i.stdout.trim())return{installed:!0};let a=i.stdout.trim(),o=`${r}/${a}`,s=await _("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 iZ(e,t){if("simulator"!==e.kind)throw new b("UNSUPPORTED_OPERATION",`${t} is only supported on iOS simulators`)}async function iQ(){await _("open",["-a","Simulator"],{allowFailure:!0,timeoutMs:iU})}async function i0(e){let t,n;if("simulator"!==e.kind||"Booted"===await i2(e))return;let r=ni.fromTimeoutMs(iR);try{await na(async({deadline:r})=>{if(r?.isExpired())throw new b("COMMAND_FAILED","iOS simulator boot deadline exceeded",{timeoutMs:iR});let i=Math.max(1e3,r?.remainingMs()??iR),a=await _("xcrun",iX(e,["boot",e.id]),{allowFailure:!0,timeoutMs:i});t={stdout:String(a.stdout??""),stderr:String(a.stderr??""),exitCode:a.exitCode};let o=`${t.stdout}
16
- ${t.stderr}`.toLowerCase(),s=o.includes("already booted")||o.includes("current state: booted");if(0!==t.exitCode&&!s)throw new b("COMMAND_FAILED","simctl boot failed",{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode});let l=await _("xcrun",iX(e,["bootstatus",e.id,"-b"]),{allowFailure:!0,timeoutMs:i});if(n={stdout:String(l.stdout??""),stderr:String(l.stderr??""),exitCode:l.exitCode},0!==n.exitCode)throw new b("COMMAND_FAILED","simctl bootstatus failed",{stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode});let u=await i2(e);if("Booted"!==u)throw new b("COMMAND_FAILED","Simulator is still booting",{state:u})},{maxAttempts:3,baseDelayMs:500,maxDelayMs:2e3,jitter:.2,shouldRetry:e=>{let r=nh({error:e,stdout:n?.stdout??t?.stdout,stderr:n?.stderr??t?.stderr,context:{platform:"ios",phase:"boot"}});return"IOS_BOOT_TIMEOUT"!==r&&"CI_RESOURCE_STARVATION_SUSPECTED"!==r}},{deadline:r,phase:"boot",classifyReason:e=>nh({error:e,stdout:n?.stdout??t?.stdout,stderr:n?.stderr??t?.stderr,context:{platform:"ios",phase:"boot"}})})}catch(a){let i=nh({error:a,stdout:n?.stdout??t?.stdout,stderr:n?.stderr??t?.stderr,context:{platform:"ios",phase:"boot"}});throw new b("COMMAND_FAILED","iOS simulator failed to boot",{platform:"ios",deviceId:e.id,timeoutMs:iR,elapsedMs:r.elapsedMs(),reason:i,hint:nw(i),boot:t,bootstatus:n})}await iQ()}async function i1(e){let t=iX(e,["shutdown",e.id]),n=await _("xcrun",t,{allowFailure:!0,timeoutMs:15e3});return{success:0===n.exitCode,exitCode:n.exitCode,stdout:String(n.stdout??""),stderr:String(n.stderr??"")}}async function i2(e){let t="string"==typeof e?e:e.id,n="string"==typeof e?iJ(["list","devices","-j"]):iX(e,["list","devices","-j"]),r=await _("xcrun",n,{allowFailure:!0,timeoutMs:iP});if(0!==r.exitCode)return null;try{let e=JSON.parse(String(r.stdout??""));for(let n of Object.values(e.devices??{})){let e=n.find(e=>e.udid===t);if(e)return e.state}return null}catch{return null}}let i3=null;function i4(e){return function e(t){if(!Array.isArray(t))return[];let n=[];for(let r of t)if(!(!r||"object"!=typeof r||Array.isArray(r)))for(let[t,i]of Object.entries(r))":@"!==t&&"#text"!==t&&n.push({name:t,attributes:function(e){if(!e||"object"!=typeof e||Array.isArray(e))return{};let t={};for(let[n,r]of Object.entries(e))"string"==typeof r&&(t[n]=r);return t}(r[":@"]),text:i8(i)??i8(r["#text"]),children:e(i)});return n}((i3??=new g({ignoreAttributes:!1,attributeNamePrefix:"",preserveOrder:!0,trimValues:!0,parseTagValue:!1})).parse(e))}function i5(e,t){for(let n of e){if("dict"===n.name)for(let e=0;e<n.children.length-1;e+=1){let r=n.children[e],i=n.children[e+1];r?.name==="key"&&r.text&&i&&t(r.text,i)}i5(n.children,t)}}function i8(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}async function i6(e,t){try{let n=await _("plutil",["-extract",t,"raw","-o","-",e],{allowFailure:!0});if(0===n.exitCode){let e=String(n.stdout??"").trim();if(e.length>0)return e}}catch{}try{var n,r;let i;return n=await a.readFile(e,"utf8"),r=t,i5(i4(n),(e,t)=>{void 0===i&&e===r&&"string"===t.name&&(i=t.text??void 0)}),i}catch{return}}async function i9(e,t){if("url"===e.kind&&!nX(e.url))throw new b("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 nW({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||nX(e.url),signal:t?.signal}),r=await ae(n.installablePath,t),i=await i7(r.installPath);return{archivePath:n.archivePath??(n.installablePath.toLowerCase().endsWith(".ipa")?n.installablePath:void 0),installablePath:r.installPath,bundleId:i.bundleId,appName:i.appName,cleanup:async()=>{await r.cleanup(),await n.cleanup()}}}async function i7(e){let t=o.join(e,"Info.plist"),[n,r,i]=await Promise.all([i6(t,"CFBundleIdentifier"),i6(t,"CFBundleDisplayName"),i6(t,"CFBundleName")]);return{bundleId:n,appName:r??i}}async function ae(e,t){if(!e.toLowerCase().endsWith(".ipa"))return{installPath:e,cleanup:async()=>{}};let n=await a.mkdtemp(o.join(l.tmpdir(),"agent-device-ios-ipa-")),r=async()=>{await a.rm(n,{recursive:!0,force:!0})};try{await _("ditto",["-x","-k",e,n]);let i=o.join(n,"Payload"),s=(await a.readdir(i,{withFileTypes:!0}).catch(()=>{throw new b("INVALID_ARGS","Invalid IPA: missing Payload directory")})).filter(e=>e.isDirectory()&&e.name.toLowerCase().endsWith(".app")).map(e=>({installPath:o.join(i,e.name),bundleName:e.name.replace(/\.app$/i,"")}));if(1===s.length)return{installPath:s[0].installPath,cleanup:r};if(0===s.length)throw new b("INVALID_ARGS","Invalid IPA: expected at least one .app under Payload, found 0");await at(s);let l=t?.appIdentifierHint?.trim();if(l){let e=function(e,t){let n=t.toLowerCase(),r=e.filter(e=>e.bundleName.toLowerCase()===n);if(1===r.length)return r[0];if(r.length>1)throw new b("INVALID_ARGS",`Invalid IPA: multiple app bundles matched "${t}" by name. Use a bundle id hint instead.`);if(t.includes(".")){let t=e.filter(e=>e.bundleId?.toLowerCase()===n);if(1===t.length)return t[0]}}(s,l);if(e)return{installPath:e.installPath,cleanup:r};throw new b("INVALID_ARGS",`Invalid IPA: found ${s.length} .app bundles under Payload and none matched "${l}". Available bundles: ${s.map(an).join(", ")}`)}throw new b("INVALID_ARGS",`Invalid IPA: found ${s.length} .app bundles under Payload. Pass an app identifier or bundle name matching one of: ${s.map(an).join(", ")}`)}catch(e){throw await r(),e}}async function at(e){await Promise.all(e.map(async e=>{if(e.bundleId&&e.appName)return;let t=await i7(e.installPath);e.bundleId=e.bundleId??t.bundleId,e.appName=e.appName??t.appName}))}function an(e){let t=e.bundleId??e.appName;return t?`${e.bundleName}.app (${t})`:`${e.bundleName}.app`}function ar(e,t){return"user-installed"===t?e.filter(e=>!e.bundleId.startsWith("com.apple.")):e}let ai="agent-device-macos-helper",aa="AGENT_DEVICE_MACOS_HELPER_BIN",ao=o.join(l.homedir(),".agent-device","macos-helper","current"),as=o.join(ao,"manifest.json"),al=/^[A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)+$/;function au(e){let t=e.trim();if(!al.test(t))throw new b("INVALID_ARGS","macOS bundle id must use reverse-DNS form like com.example.App",{bundleId:e});return t}function ad(){return function(e){let t=o.dirname(e);for(;;){let e=o.join(t,"macos-helper");if(i(o.join(e,"Package.swift")))return e;let n=o.dirname(t);if(n===t)break;t=n}throw new b("COMMAND_FAILED","Unable to locate macOS helper package root",{modulePath:e})}(s(import.meta.url))}async function ac(e){let t=await a.readdir(e,{withFileTypes:!0});return(await Promise.all(t.map(async t=>{let n=o.join(e,t.name);return t.isDirectory()?".build"===t.name?[]:await ac(n):t.isFile()&&(t.name.endsWith(".swift")||"Package.swift"===t.name)?[n]:[]}))).flat().sort()}async function ap(e){let t=await ac(e),n=c("sha256");for(let r of t)n.update(o.relative(e,r)),n.update("\0"),n.update(await a.readFile(r)),n.update("\0");let r=await _("swift",["--version"],{allowFailure:!0,cwd:e,timeoutMs:1e4});return n.update("swift-version"),n.update("\0"),n.update(r.stdout||r.stderr||`exit:${r.exitCode}`),n.update("\0"),n.digest("hex")}async function af(){try{let e=JSON.parse(await a.readFile(as,"utf8"));return"string"==typeof e.fingerprint?e.fingerprint:null}catch{return null}}async function am(){let e=process.env[aa]?.trim();if(e)return e;let t=ad(),n=await ap(t),r=o.join(ao,ai);try{if(await af()===n)return await a.access(r),r}catch{}let i=o.join(ad(),".build","release",ai);process.stderr.write("agent-device: building macOS helper (first run or helper update)\n"),await _("swift",["build","-c","release","--package-path",t],{cwd:t,timeoutMs:12e4}),await a.mkdir(ao,{recursive:!0});let s=`${r}.tmp`;return await a.copyFile(i,s),await a.rename(s,r),await a.chmod(r,493),await a.writeFile(as,`${JSON.stringify({fingerprint:n},null,2)}
17
- `,"utf8"),r}async function ah(e){let t=process.env[aa]?.trim();if("darwin"!==process.platform&&!t)throw new b("UNSUPPORTED_PLATFORM","macOS helper is only available on macOS");let n=await am(),r=await _(n,e,{allowFailure:!0,timeoutMs:3e4}),i=r.stdout.trim(),a=null;if(i)try{a=JSON.parse(i)}catch{a=null}if(0===r.exitCode&&a?.ok)return a.data;throw new b("COMMAND_FAILED",a&&!a.ok?a.error?.message??`macOS helper exited with code ${r.exitCode}`:i||r.stderr.trim()||`macOS helper exited with code ${r.exitCode}`,{helperPath:n,args:e,stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode,...a&&!a.ok?a.error?.details:{}})}async function aw(){return await ah(["app","frontmost"])}async function ag(e){return await ah(["app","quit","--bundle-id",au(e)])}async function ay(e,t){return await ah(["permission",e,t])}async function aI(e,t={}){let n=["alert",e];return t.bundleId&&n.push("--bundle-id",au(t.bundleId)),t.surface&&n.push("--surface",t.surface),await ah(n)}async function av(e,t={}){let n=["snapshot","--surface",e];return t.bundleId&&n.push("--bundle-id",au(t.bundleId)),await ah(n)}async function ab(e,t,n={}){let r=["read","--x",String(e),"--y",String(t)];return n.bundleId&&r.push("--bundle-id",au(n.bundleId)),n.surface&&r.push("--surface",n.surface),await ah(r)}async function aA(e,t,n={}){let r=["press","--x",String(e),"--y",String(t)];return n.bundleId&&r.push("--bundle-id",au(n.bundleId)),n.surface&&r.push("--surface",n.surface),await ah(r)}async function aS(e,t={}){let n=["screenshot","--out",e];return t.surface&&n.push("--surface",t.surface),t.fullscreen&&n.push("--fullscreen"),await ah(n)}let ax={settings:"com.apple.systempreferences"},a_=/^[a-z0-9-]+(?:\.[a-z0-9-]+)+$/;function aN(e,t){let n=["-b",e];return t&&n.push(t),n}async function aE(e){for(let t of[o.join(e,"Contents","Info.plist"),o.join(e,"Info.plist")]){let[e,n,r]=await Promise.all([i6(t,"CFBundleIdentifier"),i6(t,"CFBundleDisplayName"),i6(t,"CFBundleName")]);if(e||n||r)return{bundleId:e,appName:n??r}}return{}}async function aD(e){let t=e.trim(),n=ax[t.toLowerCase()];if(n)return n;if(a_.test(t))return t;let r=(await aR("all")).filter(e=>e.name.toLowerCase()===t.toLowerCase());if(1===r.length)return r[0].bundleId;if(r.length>1)throw new b("INVALID_ARGS",`Multiple apps matched "${e}"`,{matches:r});throw new b("APP_NOT_INSTALLED",`No app found matching "${e}"`)}async function aM(e,t,n){let r=n?.url?.trim();if(r){if(!t6(r))throw new b("INVALID_ARGS","open <app> <url> requires a valid URL target");let e=n?.appBundleId??await aD(t);await _("open",aN(e,r));return}let i=t.trim();if(t6(i))return void await _("open",[i]);let a=n?.appBundleId??await aD(i);await _("open",aN(a))}async function aC(e,t){let n=await aD(t),r=await ag(n);if(r.running&&!r.terminated&&!r.forceTerminated)throw new b("COMMAND_FAILED",`Failed to close macOS app ${t}`,{bundleId:n,running:r.running,terminated:r.terminated,forceTerminated:r.forceTerminated})}async function aO(){let e=await _("pbpaste",[],{allowFailure:!0});if(0!==e.exitCode)throw new b("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 aL(e){let t=await _("pbcopy",[],{allowFailure:!0,stdin:e});if(0!==t.exitCode)throw new b("COMMAND_FAILED","Failed to write macOS clipboard",{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode})}async function aT(){let e=await _("osascript",["-e",'tell application "System Events" to tell appearance preferences to get dark mode'],{allowFailure:!0});if(0!==e.exitCode)throw new b("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 b("COMMAND_FAILED",`Unable to determine current macOS appearance from osascript output: ${e.stdout.trim()}`)}async function ak(e){let t=ib(e),n="toggle"===t?!await aT():"dark"===t,r=`tell application "System Events" to tell appearance preferences to set dark mode to ${n?"true":"false"}`,i=await _("osascript",["-e",r],{allowFailure:!0});if(0!==i.exitCode)throw new b("COMMAND_FAILED","Failed to set macOS appearance",{stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode})}async function aR(e="all"){let t=["/Applications","/System/Applications",o.join(l.homedir(),"Applications")],n=new Set;for(let e of t){let t=await a.stat(e).catch(()=>null);if(!t?.isDirectory())continue;let r=await _("find",[e,"-maxdepth","4","-type","d","-name","*.app"],{allowFailure:!0});if(0===r.exitCode)for(let e of r.stdout.split("\n")){let t=e.trim();t&&n.add(t)}}return ar((await Promise.all(Array.from(n).map(async e=>{let t=await aE(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 aP=new Set,a$=new Map,aF="request_canceled",aU="request canceled";function aV(e,t){if("string"==typeof e&&e.length>0)return e;let n=("string"==typeof t?t:"number"==typeof t&&Number.isFinite(t)?String(t):"generated").trim().replace(/[^a-zA-Z0-9_-]/g,"_").slice(0,32)||"generated",r=Math.random().toString(36).slice(2,10);return`req:${n}:${process.pid}:${Date.now()}:${r}`}function aG(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++}}(a$);let t=new AbortController;a$.set(e,t),aP.has(e)&&t.abort()}function aB(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++}}(aP),aP.add(e),a$.get(e)?.abort())}function aj(e){e&&(aP.delete(e),a$.delete(e))}function aq(e){return!!e&&aP.has(e)}function aW(e){if(e)return a$.get(e)?.signal}function az(){return new b("COMMAND_FAILED",aU,{reason:aF})}function aH(e){return e instanceof b&&"COMMAND_FAILED"===e.code&&(e.details?.reason===aF||e.message===aU)}function aJ(e){return!(e instanceof b)||"COMMAND_FAILED"!==e.code||!String(e.message??"").toLowerCase().includes("xcodebuild exited early")}function aX(e){let{port:t,endpoints:n,logPath:r,lastError:i}=e,a="Runner did not accept connection";return new b("COMMAND_FAILED",a,{port:t,endpoints:n,logPath:r,lastError:i?String(i):void 0,reason:nh({error:i,message:a,context:{platform:"ios",phase:"connect"}}),hint:nw("IOS_RUNNER_CONNECT_TIMEOUT")})}async function aK(e){var t,n;let r,{session:i,port:a,logPath:o}=e,s=await i.testPromise,l="Runner did not accept connection (xcodebuild exited early)",u=nh({message:l,stdout:s.stdout,stderr:s.stderr,context:{platform:"ios",phase:"connect"}});return new b("COMMAND_FAILED",l,{port:a,logPath:o,xcodebuild:{exitCode:s.exitCode,stdout:s.stdout,stderr:s.stderr},reason:u,hint:(t=s.stdout,n=s.stderr,(r=`${l}
18
- ${t}
19
- ${n}`.toLowerCase()).includes("device is busy")&&r.includes("connecting")?"Target iOS device is still connecting. Keep it unlocked, wait for device trust/connection to settle, then retry.":nw("IOS_RUNNER_CONNECT_TIMEOUT"))})}function aY(e){if(aq(e))throw az()}let aZ=nG(process.env.AGENT_DEVICE_RUNNER_STARTUP_TIMEOUT_MS,45e3,5e3),aQ=nG(process.env.AGENT_DEVICE_RUNNER_COMMAND_TIMEOUT_MS,45e3,1e3),a0=nG(process.env.AGENT_DEVICE_RUNNER_CONNECT_ATTEMPT_INTERVAL_MS,250,50),a1=nG(process.env.AGENT_DEVICE_RUNNER_CONNECT_RETRY_BASE_DELAY_MS,300,10),a2=nG(process.env.AGENT_DEVICE_RUNNER_CONNECT_RETRY_MAX_DELAY_MS,2e3,10),a3=nG(process.env.AGENT_DEVICE_RUNNER_CONNECT_REQUEST_TIMEOUT_MS,2e4,250),a4=nG(process.env.AGENT_DEVICE_IOS_DEVICE_INFO_TIMEOUT_MS,1e4,500),a5=nG(process.env.AGENT_DEVICE_RUNNER_DESTINATION_TIMEOUT_SECONDS,20,5);async function a8(e,t,n,r,i=aZ,a,o){let s=ni.fromTimeoutMs(i),l=await a6(e,t,s.remainingMs()),u=null,d=Math.max(1,Math.ceil(i/a0));try{return await na(async({deadline:s})=>{if(s?.isExpired())throw new b("COMMAND_FAILED","Runner connection deadline exceeded",{port:t,timeoutMs:i});if(a&&null!==a.child.exitCode&&void 0!==a.child.exitCode)throw await aK({session:a,port:t,logPath:r});for(let r of("device"===e.kind&&(l=await a6(e,t,s?.remainingMs())),l))try{let e=s?.remainingMs()??i;if(e<=0)throw new b("COMMAND_FAILED","Runner connection deadline exceeded",{port:t,timeoutMs:i});return await a9(r,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)},Math.min(a3,e),o)}catch(e){if(o?.aborted||aH(e))throw az();u=e}throw new b("COMMAND_FAILED","Runner endpoint probe failed",{port:t,endpoints:l,lastError:u?String(u):void 0})},{maxAttempts:d,baseDelayMs:a1,maxDelayMs:a2,jitter:.2,shouldRetry:aJ},{deadline:s,phase:"ios_runner_connect",signal:o})}catch(e){if(o?.aborted||aH(e))throw az();u||(u=e)}if(o?.aborted)throw az();if("simulator"===e.kind){let i=s.remainingMs();if(i<=0)throw aX({port:t,endpoints:l,logPath:r,lastError:u});let a=await oe(e,t,n,i);return new Response(a.body,{status:a.status})}throw aX({port:t,endpoints:l,logPath:r,lastError:u})}async function a6(e,t,n){let r=[`http://127.0.0.1:${t}/command`];if("device"!==e.kind)return r;let i=await a7(e.id,n);return i&&r.unshift(`http://[${i}]:${t}/command`),r}async function a9(e,t,n,r){let i,a=new AbortController,o=setTimeout(()=>a.abort(),n);r&&(r.aborted?(clearTimeout(o),a.abort()):(i=()=>a.abort(),r.addEventListener("abort",i,{once:!0})));try{return await fetch(e,{...t,signal:a.signal})}finally{clearTimeout(o),i&&r&&r.removeEventListener("abort",i)}}async function a7(e,t){if("number"==typeof t&&t<=0)return null;let n="number"==typeof t?Math.max(1,Math.min(a4,t)):a4,i=o.join(l.tmpdir(),`agent-device-devicectl-info-${process.pid}-${Date.now()}.json`);try{let t=Math.max(1,Math.ceil(n/1e3)),a=await _("xcrun",["devicectl","device","info","details","--device",e,"--json-output",i,"--timeout",String(t)],{allowFailure:!0,timeoutMs:n});if(0!==a.exitCode||!r.existsSync(i))return null;let o=JSON.parse(r.readFileSync(i,"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{or(i)}}async function oe(e,t,n,r){let i=JSON.stringify(n),a=iX(e,["spawn",e.id,"/usr/bin/curl","-s","-X","POST","-H","Content-Type: application/json","--data",i,`http://127.0.0.1:${t}/command`]),o=await _("xcrun",a,{allowFailure:!0,timeoutMs:r}),s=o.stdout;if(0!==o.exitCode){let e=nh({message:"Runner did not accept connection (simctl spawn)",stdout:o.stdout,stderr:o.stderr,context:{platform:"ios",phase:"connect"}});throw new b("COMMAND_FAILED","Runner did not accept connection (simctl spawn)",{port:t,stdout:o.stdout,stderr:o.stderr,exitCode:o.exitCode,reason:e,hint:nw(e)})}return{status:200,body:s}}async function ot(){return await new Promise((e,t)=>{let n=m.createServer();n.listen(0,"127.0.0.1",()=>{let r=n.address();if("object"==typeof r&&r?.port){let t=r.port;n.close(()=>e(t))}else n.close(()=>t(new b("COMMAND_FAILED","Failed to allocate port")))}),n.on("error",t)})}function on(e,t,n,i){t&&r.appendFile(t,e,()=>{}),n&&r.appendFile(n,e,()=>{}),i&&process.stderr.write(e)}function or(e){try{r.existsSync(e)&&r.unlinkSync(e)}catch{}}let oi=new y;async function oa(e,t,n){let r=oi.getStore()??[];if(r.some(n=>n.locks===e&&n.key===t))return await n();let i=(e.get(t)??Promise.resolve()).catch(()=>{}).then(()=>oi.run([...r,{locks:e,key:t}],n));return e.set(t,i),i.finally(()=>{e.get(t)===i&&e.delete(t)})}let oo=new Set(["RUNNER_PRODUCT_MISSING","RUNNER_PRODUCT_REPAIR_FAILED"]);async function os(e,t,n){if("macos"!==e.platform)return;if(0===t.length)throw new b("COMMAND_FAILED","Missing macOS runner product",{reason:"RUNNER_PRODUCT_MISSING",xctestrunPath:n});let i=Array.from(new Set(t)).sort((e,t)=>t.length-e.length);for(let e of i)if(!r.existsSync(e))throw new b("COMMAND_FAILED","Missing macOS runner product",{reason:"RUNNER_PRODUCT_MISSING",productPath:e,xctestrunPath:n});for(let e of i)if(0!==N("codesign",["--verify","--deep","--strict",e],{allowFailure:!0}).exitCode){await _("codesign",["--remove-signature",e],{allowFailure:!0});try{await _("codesign",["--force","--sign","-",e])}catch(r){let t=r instanceof b?r:new b("COMMAND_FAILED",String(r));throw new b("COMMAND_FAILED","Failed to repair macOS runner product signature",{reason:"RUNNER_PRODUCT_REPAIR_FAILED",productPath:e,xctestrunPath:n,error:t.message,details:t.details})}}}let ol="XCTestDevices",ou=".agent-device-backup",od=".agent-device-xctestdevices-backup-",oc=o.join(l.homedir(),".agent-device","ios-runner"),op=new Set(["ProductPaths","DependentProductPaths","TestHostPath","TestBundlePath","UITargetAppPath"]),of=new Map,om=new Set;function oh(e){return e?.trim()??""}function ow(e=process.env){return oh(e.AGENT_DEVICE_IOS_BUNDLE_ID)||oh(e.AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID)||"com.callstack.agentdevice.runner"}function og(e=process.env){let t=oh(e.AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID);return t||`${ow(e)}.uitests`}let oy=function(e=process.env){let t=ow(e),n=og(e);return Array.from(new Set([oh(e.AGENT_DEVICE_IOS_RUNNER_CONTAINER_BUNDLE_ID),`${n}.xctrunner`,t].filter(e=>e.length>0)))}(process.env);function oI(e=l.homedir()){return o.join(e,"Library","Developer","XCTestDevices")}async function ov(e,t={}){if("ios"!==e.platform||"simulator"!==e.kind)return null;let n=np(e.simulatorSetPath);if(!n)return null;let i=o.resolve(n),a=o.resolve(t.xctestDeviceSetPath??oI()),s=o.resolve(t.backupPath??function(e=oI()){return`${e}${ou}`}(a)),u=o.resolve(t.lockDirPath??function(e=l.homedir()){return o.join(e,".agent-device","xctest-device-set.lock")}()),d=t.ownerStartTime??eA(process.pid),c=await oS({lockDirPath:u,owner:{pid:t.ownerPid??process.pid,startTime:d,acquiredAtMs:t.nowMs??Date.now()}});try{if(ob({xctestDeviceSetPath:a,backupPath:s}),function(e,t){if(o.resolve(e)===o.resolve(t))return!0;try{return r.realpathSync.native(e)===r.realpathSync.native(t)}catch{return!1}}(i,a))return await c(),null;r.mkdirSync(i,{recursive:!0}),r.existsSync(a)&&r.renameSync(a,s),function(e){let{requestedSetPath:t,xctestDeviceSetPath:n}=e,i=o.dirname(n),a=o.join(i,`${ol}.agent-device-link-${process.pid}-${Date.now()}`);r.mkdirSync(i,{recursive:!0});try{r.symlinkSync(t,a,"dir"),r.renameSync(a,n)}catch(e){throw r.existsSync(a)&&oA(a),e}}({requestedSetPath:i,xctestDeviceSetPath:a})}catch(e){throw ob({xctestDeviceSetPath:a,backupPath:s}),await c(),new b("COMMAND_FAILED","Failed to redirect XCTest device set path",{requestedSetPath:i,xctestDeviceSetPath:a,backupPath:s,error:String(e)})}let p=!1;return{release:async()=>{if(!p){p=!0;try{ob({xctestDeviceSetPath:a,backupPath:s})}finally{await c()}}}}}function ob(e){let{xctestDeviceSetPath:t,backupPath:n}=e,i=[n,...function(e){let t=o.dirname(e),n=o.basename(e).replace(ou,""),i=n===ol?od:`${n}${od}`;try{return r.readdirSync(t).filter(e=>e.startsWith(i)).sort().map(e=>o.join(t,e))}catch{return[]}}(n)],a=i.find(e=>r.existsSync(e)),s=r.existsSync(t)&&r.lstatSync(t).isSymbolicLink();if(a){if(s&&oA(t),r.existsSync(t))if(!s)return void M({level:"warn",phase:"ios_runner_xctest_device_set_restore_collision",data:{xctestDeviceSetPath:t,activeBackupPath:a}});else a!==n?r.rmSync(a,{recursive:!0,force:!0}):r.rmSync(n,{recursive:!0,force:!0});else r.mkdirSync(o.dirname(t),{recursive:!0}),r.renameSync(a,t);for(let e of i)e!==a&&r.existsSync(e)&&r.rmSync(e,{recursive:!0,force:!0});return}s&&(M({level:"warn",phase:"ios_runner_xctest_device_set_orphaned_symlink",data:{xctestDeviceSetPath:t}}),oA(t))}function oA(e){!r.existsSync(e)||r.lstatSync(e).isSymbolicLink()&&r.unlinkSync(e)}async function oS(e){let{lockDirPath:t,owner:n}=e,i=o.join(t,"owner.json"),a=Date.now()+3e4;for(r.mkdirSync(o.dirname(t),{recursive:!0});Date.now()<a;)try{r.mkdirSync(t),function(e,t){let n=`${e}.${process.pid}.${Date.now()}.tmp`;r.writeFileSync(n,JSON.stringify(t),"utf8"),r.renameSync(n,e)}(i,n);let e=!1;return async()=>{e||(e=!0,r.rmSync(t,{recursive:!0,force:!0}))}}catch(e){if("EEXIST"!==e.code)throw e;if(function(e,t){let n=null;try{n=r.statSync(e)}catch{return!0}let i=function(e){try{return JSON.parse(r.readFileSync(e,"utf8"))}catch{return null}}(t);if(i){var a;return!(Number.isInteger((a=i).pid)&&!(a.pid<=0)&&eb(a.pid)&&(!a.startTime||eA(a.pid)===a.startTime))&&(r.rmSync(e,{recursive:!0,force:!0}),!0)}return!(Date.now()-n.mtimeMs<5e3)&&(r.rmSync(e,{recursive:!0,force:!0}),!0)}(t,i))continue;await new Promise(e=>setTimeout(e,100))}throw new b("COMMAND_FAILED","Timed out waiting for XCTest device set lock",{lockDirPath:t})}async function ox(e,t){var n;let i,a=(n=e,(i=process.env.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim())?o.resolve(i):"macos"===n.platform?o.join(oc,"derived","macos"):"simulator"===n.kind?o.join(oc,"derived"):o.join(oc,"derived",n.kind)),l=function(){let e=o.dirname(s(import.meta.url)),t=e;for(let e=0;e<6;e+=1){let e=o.join(t,"package.json");if(r.existsSync(e))return t;t=o.dirname(t)}return e}();return await oa(of,a,async()=>{ne(process.env.AGENT_DEVICE_IOS_CLEAN_DERIVED)&&(oP("clean","forced_clean",{derived:a}),oR(a),o_(a));let n=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:a,projectRoot:l,findXctestrun:t=>oE(t,e),xctestrunReferencesProjectRoot:oM,resolveExistingXctestrunProductPaths:o$});if("reuse_ready"!==n.reason&&oP("rebuild",n.reason,{derived:a,xctestrunPath:n.xctestrunPath}),"reuse_ready"===n.reason)try{return await os(e,n.productPaths,n.xctestrunPath),oP("reuse","reuse_ready",{derived:a,xctestrunPath:n.xctestrunPath}),n.xctestrunPath}catch(e){if(!function(e){if(!(e instanceof b))return!1;let t=e.details&&"object"==typeof e.details?e.details.reason:void 0;return"string"==typeof t&&oo.has(t)}(e))throw e;oP("rebuild","repair_failed",{derived:a,xctestrunPath:n.xctestrunPath})}n.xctestrunPath&&(oR(a),o_(a));let i=o.join(l,"ios-runner","AgentDeviceRunner","AgentDeviceRunner.xcodeproj");if(!r.existsSync(i))throw new b("COMMAND_FAILED","iOS runner project not found",{projectPath:i});await oO(e,i,a,t);let s=oE(a,e);if(!s)throw new b("COMMAND_FAILED","Failed to locate .xctestrun after build");let u=o$(s);if(!u)throw new b("COMMAND_FAILED","Runner build is missing expected products",{xctestrunPath:s});return await os(e,u,s),oP("build","built_new",{derived:a,xctestrunPath:s}),s})}function o_(e){try{if(!r.existsSync(e))return;if("derived"!==o.basename(e))return void r.rmSync(e,{recursive:!0,force:!0});for(let n of r.readdirSync(e,{withFileTypes:!0})){var t;t=n.name,oN.has(t)&&r.rmSync(o.join(e,n.name),{recursive:!0,force:!0})}}catch{}}let oN=new Set(["Build","BuildCache.noindex","Index.noindex","Logs","ModuleCache.noindex","SDKStatCaches.noindex","SourcePackages","TextBasedInstallAPI","info.plist"]);function oE(e,t){if(!r.existsSync(e))return null;let n=[],i=[e];for(;i.length>0;){let e=i.pop();for(let t of r.readdirSync(e,{withFileTypes:!0})){let a=o.join(e,t.name);if(t.isDirectory()){i.push(a);continue}if(t.isFile()&&t.name.endsWith(".xctestrun"))try{let e=r.statSync(a);n.push({path:a,mtimeMs:e.mtimeMs})}catch{}}}return 0===n.length?null:(n.sort((e,n)=>{if(t){let r=oD(n.path,t)-oD(e.path,t);if(0!==r)return r}return n.mtimeMs-e.mtimeMs||e.path.localeCompare(n.path)}),n[0]?.path??null)}function oD(e,t){var n;let r=0,i=e.toLowerCase();o.basename(i).startsWith("agentdevicerunner.env.")&&(r-=1e3),i.includes(`${o.sep}macos${o.sep}`)&&(r-=5e3);let a="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 a.preferred.length>0&&(a.preferred.some(e=>i.includes(e))?r+=2e3:r-=500),a.disallowed.some(e=>i.includes(e))&&(r-=2500),r}function oM(e,t){try{let n=r.readFileSync(e,"utf8"),i=new Set([t]);try{i.add(r.realpathSync(t))}catch{}for(let e of i)if(n.includes(e))return!0;return!1}catch{return!1}}async function oC(e,t,n){let i,a=o.dirname(e),s=n.replace(/[^a-zA-Z0-9._-]/g,"_"),l=o.join(a,`AgentDeviceRunner.env.${s}.json`),u=o.join(a,`AgentDeviceRunner.env.${s}.xctestrun`),d=await _("plutil",["-convert","json","-o","-",e],{allowFailure:!0});if(0!==d.exitCode||!d.stdout.trim())throw new b("COMMAND_FAILED","Failed to read xctestrun plist",{xctestrunPath:e,stderr:d.stderr});try{i=JSON.parse(d.stdout)}catch(t){throw new b("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=i.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(i))t&&"object"==typeof t&&t.TestBundlePath&&(c(t),i[e]=t);r.writeFileSync(l,JSON.stringify(i,null,2));let f=await _("plutil",["-convert","xml1","-o",u,l],{allowFailure:!0});if(0!==f.exitCode)throw new b("COMMAND_FAILED","Failed to write xctestrun plist",{tmpXctestrunPath:u,stderr:f.stderr});return{xctestrunPath:u,jsonPath:l}}async function oO(e,t,n,r){let i=function(e=process.env){let t=ow(e),n=og(e);return[`AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID=${t}`,`AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID=${n}`]}(process.env),a=function(e=process.env,t=!1,n="ios"){if("macos"===n)return["CODE_SIGNING_ALLOWED=NO","CODE_SIGNING_REQUIRED=NO","CODE_SIGN_IDENTITY=","DEVELOPMENT_TEAM="];if(!t)return[];let r=e.AGENT_DEVICE_IOS_TEAM_ID?.trim()||"",i=e.AGENT_DEVICE_IOS_SIGNING_IDENTITY?.trim()||"",a=e.AGENT_DEVICE_IOS_PROVISIONING_PROFILE?.trim()||"",o=["CODE_SIGN_STYLE=Automatic"];return r&&o.push(`DEVELOPMENT_TEAM=${r}`),i&&o.push(`CODE_SIGN_IDENTITY=${i}`),a&&o.push(`PROVISIONING_PROFILE_SPECIFIER=${a}`),o}(process.env,"device"===e.kind,e.platform),o="device"===e.kind?["-allowProvisioningUpdates"]:[],s=await ov(e);try{var l;let s;await I("xcodebuild",["build-for-testing","-project",t,"-scheme","AgentDeviceRunner","-parallel-testing-enabled","NO",ok(e),"1","-destination",(l=e,s=oL(l),"macOS"===s?`platform=macOS,arch=${oT()}`:"simulator"===l.kind?`platform=${s} Simulator,id=${l.id}`:`generic/platform=${s}`),"-derivedDataPath",n,"COMPILER_INDEX_STORE_ENABLE=NO","ENABLE_CODE_COVERAGE=NO",...i,...o,...a],{detached:!0,onSpawn:e=>{om.add(e),e.on("close",()=>{om.delete(e)})},onStdoutChunk:e=>{on(e,r.logPath,r.traceLogPath,r.verbose)},onStderrChunk:e=>{on(e,r.logPath,r.traceLogPath,r.verbose)}})}catch(a){let e,t,n=a instanceof b?a:new b("COMMAND_FAILED",String(a)),i=(e=n.details?JSON.stringify(n.details):"",(t=`${n.message}
20
- ${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 b("COMMAND_FAILED","xcodebuild build-for-testing failed",{error:n.message,details:n.details,logPath:r.logPath,hint:i})}finally{await s?.release()}}function oL(e){var t;if("ios"!==e.platform&&"macos"!==e.platform)throw new b("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 oT(){return"arm64"===process.arch?"arm64":"x86_64"}function ok(e){return"macos"===e.platform||"device"===e.kind?"-maximum-concurrent-test-device-destinations":"-maximum-concurrent-test-simulator-destinations"}function oR(e,t=process.env){if(t.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim()&&!function(e=process.env){return ne(e.AGENT_DEVICE_IOS_ALLOW_OVERRIDE_DERIVED_CLEAN)}(t))throw new b("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 oP(e,t,n){M({level:"rebuild"===e?"warn":"info",phase:"runner_xctestrun_cache",data:{action:e,reason:t,...n}})}function o$(e){let t=function(e){let t=function(e){try{let t=N("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 n,i,a=t;let e=new Set,r=t=>{if(t&&"object"==typeof t)for(let n of function(e){let t=new Set(["ProductPaths","DependentProductPaths","TestHostPath","TestBundlePath","UITargetAppPath"]),n=new Set;for(let[r,i]of Object.entries(e))if(t.has(r)){if("string"==typeof i){n.add(i);continue}if(Array.isArray(i))for(let e of i)"string"==typeof e&&n.add(e)}return Array.from(n)}(t))e.add(n)};r(a);let o=a.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)r(e)}for(let e of Object.values(a))e&&"object"==typeof e&&"TestBundlePath"in e&&r(e);return Array.from(e)}if("darwin"===process.platform)return null;try{let t;return n=r.readFileSync(e,"utf8"),i=i4(n),t=new Set,i5(i,(e,n)=>{if(op.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 n=o.dirname(e),i=new Set,a=new Set,s=[];for(let e of t){if(e.startsWith("__TESTROOT__/")){let t=e.slice(13),s=o.join(n,t);if(!r.existsSync(s))return null;i.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&&a.add(o.join(n,l));continue}e.startsWith("__TESTHOST__/")&&s.push(e.slice(13))}for(let e of s){let t=Array.from(a).find(t=>r.existsSync(o.join(t,e)));if(!t)return null;i.add(o.join(t,e))}return Array.from(i)}let oF=new Map,oU=new Map;async function oV(e,t){return await oa(oU,e.id,async()=>{var n;let r,i,a=oF.get(e.id);if(a){if(function(e){return!!e&&eb(e)}(a.child.pid))return a;await oq(e.id,a)}await ("simulator"!==(n=e).kind?Promise.resolve():oX(n)),await oG(e);let o=await ox(e,t),s=await ot(),{xctestrunPath:l,jsonPath:u}=await oC(o,{AGENT_DEVICE_RUNNER_PORT:String(s)},`session-${e.id}-${s}`),d=await ov(e);try{let t;({child:r,wait:i}=A("xcodebuild",["test-without-building","-only-testing","AgentDeviceRunnerUITests/RunnerTests/testCommand","-parallel-testing-enabled","NO","-test-timeouts-enabled","NO","-collect-test-diagnostics","never",ok(e),"1","-destination-timeout",String(a5),"-xctestrun",l,"-destination",(t=oL(e),"macOS"===t?`platform=macOS,arch=${oT()}`:"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 d?.release(),e}r.stdout?.on("data",e=>{on(e,t.logPath,t.traceLogPath,t.verbose)}),r.stderr?.on("data",e=>{on(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:u,testPromise:i,child:r,ready:!1,simulatorSetRedirect:d??void 0};return oF.set(e.id,c),c})}async function oG(e){if("simulator"===e.kind)for(let t of oy){let n=await _("xcrun",iX(e,["uninstall",e.id,t]),{allowFailure:!0});if(0!==n.exitCode){let e=`${n.stdout}
21
- ${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 oB(e){let t=oF.get(e);return t?{sessionId:t.sessionId,alive:function(e){return!!e&&eb(e)}(t.child.pid)}:null}async function oj(e){await oa(oU,e.deviceId,async()=>{await oq(e.deviceId,e)})}async function oq(e,t){let n=t??oF.get(e);if(n){try{await a8(n.device,n.port,{command:"shutdown"},void 0,15e3)}catch{await oJ(n.child.pid,"SIGTERM")}try{await Promise.race([n.testPromise,new Promise(e=>setTimeout(e,1e4))])}catch{}await oJ(n.child.pid,"SIGKILL"),or(n.xctestrunPath),or(n.jsonPath),await n.simulatorSetRedirect?.release(),oF.get(e)===n&&oF.delete(e)}}async function oW(e){await oa(oU,e,async()=>{await oq(e)})}async function oz(){let e=Array.from(oF.values()),t=Array.from(om);await Promise.allSettled(e.map(async e=>{await oJ(e.child.pid,"SIGINT")})),await Promise.allSettled(t.map(async e=>{await oJ(e.pid,"SIGINT")})),await Promise.allSettled(e.map(async e=>{await oJ(e.child.pid,"SIGTERM")})),await Promise.allSettled(t.map(async e=>{await oJ(e.pid,"SIGTERM")})),await Promise.allSettled(e.map(async e=>{await oJ(e.child.pid,"SIGKILL")})),await Promise.allSettled(t.map(async e=>{await oJ(e.pid,"SIGKILL"),om.delete(e)})),await Promise.allSettled(e.map(async e=>{await e.simulatorSetRedirect?.release()}))}async function oH(){await oz();let e=Array.from(oF.keys());await Promise.allSettled(e.map(async e=>{await oW(e)}));let t=Array.from(om);await Promise.allSettled(t.map(async e=>{try{await oJ(e.pid,"SIGTERM"),await oJ(e.pid,"SIGKILL")}finally{om.delete(e)}}))}async function oJ(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 _("pkill",[`-${n}`,"-P",String(e)],{allowFailure:!0})}catch{}}async function oX(e){await _("xcrun",iX(e,["bootstatus",e.id,"-b"]),{timeoutMs:aZ})}async function oK(e,t,n,r,i,a){let o=await a8(e,t.port,n,r,i,t,a);return await oY(o,t,r)}async function oY(e,t,n){let r=await e.text(),i={};try{i=JSON.parse(r)}catch{throw new b("COMMAND_FAILED","Invalid runner response",{text:r})}if(!i.ok)throw new b("string"==typeof i.error?.code&&i.error.code.trim().length>0?i.error.code:"COMMAND_FAILED",i.error?.message??"Runner error",{runner:i,xcodebuild:{exitCode:1,stdout:"",stderr:""},logPath:n});return t.ready=!0,i.data??{}}async function oZ(e,t,n={}){var r;if("ios"!==e.platform&&"macos"!==e.platform)throw new b("UNSUPPORTED_PLATFORM",`Unsupported platform for iOS runner: ${e.platform}`);if("simulator"!==e.kind&&"device"!==e.kind)throw new b("UNSUPPORTED_OPERATION",`Unsupported iOS device kind for runner: ${e.kind}`);return(aY(n.requestId),"interactionFrame"===(r=t.command)||"snapshot"===r||"screenshot"===r||"findText"===r||"readText"===r||"alert"===r||"uptime"===r)?no(()=>(aY(n.requestId),oQ(e,t,n)),{shouldRetry:e=>{aY(n.requestId);if(!(e instanceof b)||"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"))}}):oQ(e,t,n)}async function oQ(e,t,n={}){let r;aY(n.requestId);let i=aW(n.requestId);try{let a=(r=await oV(e,n)).ready?aQ:aZ;return await oK(e,r,t,n.logPath,a,i)}catch(o){let a=o instanceof b?o:new b("COMMAND_FAILED",String(o));if("COMMAND_FAILED"===a.code&&"string"==typeof a.message&&a.message.includes("Runner did not accept connection")&&aJ(a)&&r?.ready){aY(n.requestId),r?await oj(r):await oW(e.id),r=await oV(e,n);let a=await a8(r.device,r.port,t,n.logPath,aZ,void 0,i);return await oY(a,r,n.logPath)}throw o}}let o0=["--time","9:41","--dataNetwork","wifi","--wifiMode","active","--wifiBars","3","--batteryState","charged","--batteryLevel","100"],o1={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"},o2={1:"searching",2:"failed",3:"active"},o3={0:"notSupported",1:"searching",2:"failed",3:"active"};function o4(e,t,n){return _("xcrun",iX(e,t),n)}async function o5(e,t){var n,r;let i;await o6(e),t&&await o9(e,(i=[],(n=t).dataNetwork&&i.push("--dataNetwork",n.dataNetwork),n.wifiMode&&i.push("--wifiMode",n.wifiMode),void 0!==n.wifiBars&&("wifi"===n.dataNetwork||n.wifiMode)&&i.push("--wifiBars",n.wifiBars),n.cellularMode&&i.push("--cellularMode",n.cellularMode),void 0!==n.cellularBars&&(n.cellularMode||(r=n.dataNetwork)&&"hide"!==r&&"wifi"!==r||void 0!==n.operatorName)&&i.push("--cellularBars",n.cellularBars),void 0!==n.operatorName&&i.push("--operatorName",n.operatorName),i))}async function o8(e){let t=await o4(e,["status_bar",e.id,"list"],{allowFailure:!0});if(0!==t.exitCode)throw new b("COMMAND_FAILED","Failed to read simulator status bar overrides",{exitCode:t.exitCode,stdout:t.stdout,stderr:t.stderr});return function(e){let t={};for(let n of e.split("\n").map(e=>e.trim()).filter(e=>e.length>0&&"Current Status Bar Overrides:"!==e&&!/^=+$/.test(e))){let e=/^DataNetworkType:\s+(\d+)$/.exec(n);if(e){let n=Number(e[1]),r=o1[n];if(!r)throw new b("COMMAND_FAILED",`Unsupported simulator data network type: ${n}`);t.dataNetwork=r;continue}let r=/^WiFi Mode:\s+(\d+),\s+WiFi Bars:\s+(\d+)$/.exec(n);if(r){let e=o2[Number(r[1])];e&&(t.wifiMode=e),t.wifiBars=r[2];continue}let i=/^Cell Mode:\s+(\d+),\s+Cell Bars:\s+(\d+)$/.exec(n);if(i){let e=Number(i[1]),n=o3[e];if(!n)throw new b("COMMAND_FAILED",`Unsupported simulator cellular mode: ${e}`);t.cellularMode=n,t.cellularBars=i[2];continue}let a=/^Operator Name:\s*(.*)$/.exec(n);if(a){t.operatorName=a[1]??"";continue}}return 0===Object.keys(t).length?null:t}(t.stdout)}async function o6(e){await o4(e,["status_bar",e.id,"clear"])}async function o9(e,t){0!==t.length&&await o4(e,["status_bar",e.id,"override",...t])}function o7(e,t,n){M({level:"warn",phase:`ios_screenshot_status_bar_${t}`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,...function(e){if(!(e instanceof b))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 se(e,t,n){return _("xcrun",iX(e,t),n)}let st={ensureBooted:i0,prepareStatusBarForScreenshot:async function e(e){let t=null,n=!1;try{t=await o8(e),n=!0}catch(t){o7(e,"snapshot_failed",t)}try{await o6(e),await o9(e,o0)}catch(t){o7(e,"prepare_failed",t)}return async()=>{await o5(e,n?t:null)}},captureWithRetry:si,runnerFallbackEnabled:iB,captureWithRunner:sa,shouldFallbackToRunner:sp};async function sn(e,t,n,r){if("macos"===e.platform)return void await sa(e,t,n,r);if("simulator"===e.kind)return void await sr(e,t,n,r);try{await ij(["device","screenshot","--device",e.id,t],{action:"capture iOS screenshot",deviceId:e.id});return}catch(t){if(!function(e){if(!(e instanceof b)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details??{},n="string"==typeof t.stdout?t.stdout:"",r="string"==typeof t.stderr?t.stderr:"",i=`${e.message}
22
- ${n}
23
- ${r}`.toLowerCase();return i.includes("unknown option '--device'")||i.includes("unknown subcommand")&&i.includes("screenshot")||i.includes("unrecognized subcommand")&&i.includes("screenshot")}(t))throw t;su(e,"devicectl_screenshot",t)}await sa(e,t,n,r)}async function sr(e,t,n,r,i=st){if("simulator"!==e.kind)throw new b("UNSUPPORTED_OPERATION","Simulator screenshot fallback flow supports only iOS simulators");let a="object"==typeof r&&null!==r?r:i;await a.ensureBooted(e);let o=async()=>{};try{o=await a.prepareStatusBarForScreenshot(e)}catch(t){sd(e,"prepare_failed",t)}try{try{await a.captureWithRetry(e,t);return}catch(t){if(!a.shouldFallbackToRunner(t))throw t;if(!a.runnerFallbackEnabled){var s,l,u;let n,r;throw s=e,l=t,n=sc(l),M({level:"warn",phase:"ios_screenshot_fallback_skipped",data:{platform:s.platform,deviceKind:s.kind,deviceId:s.id,from:"simctl_screenshot",to:"runner",reason:"Simulator runner fallback is disabled to avoid XCTest automation instability during screenshot capture.",...n}}),r=(u=t)instanceof b?u:new b("COMMAND_FAILED","Failed to capture iOS screenshot: simulator screenshot retries exhausted",void 0,u),new b(r.code,r.message,{...r.details??{},hint:"Restart the simulator and retry. If simctl screenshots keep timing out and you accept the stability tradeoff, set AGENT_DEVICE_IOS_SIMULATOR_SCREENSHOT_RUNNER_FALLBACK=1 to allow XCTest runner fallback."},r)}su(e,"simctl_screenshot",t)}await a.captureWithRunner(e,t,n,"boolean"==typeof r?r:void 0)}finally{await o().catch(t=>sd(e,"restore_failed",t))}}async function si(e,t){let n=ni.fromTimeoutMs(iV);await na(async({deadline:n})=>{await se(e,["io",e.id,"screenshot",t],{timeoutMs:Math.max(1e3,n?.remainingMs()??iV)})},{maxAttempts:5,baseDelayMs:1e3,maxDelayMs:5e3,jitter:.2,shouldRetry:e=>sp(e)},{deadline:n,phase:"ios_simulator_screenshot"})}async function sa(e,t,n,r){let i=(await oZ(e,{command:"screenshot",appBundleId:n,fullscreen:r})).message;if(!i)throw new b("COMMAND_FAILED","Failed to capture iOS screenshot: runner returned no file path");"macos"===e.platform?await a.copyFile(i,t):"simulator"===e.kind?await ss(e,i,t):await so(e,i,t)}async function so(e,t,n){let r=ni.fromTimeoutMs(iG),i={exitCode:1,stdout:"",stderr:""};for(let a of oy)if(0===(i=await _("xcrun",["devicectl","device","copy","from","--device",e.id,"--source",t,"--destination",n,"--domain-type","appDataContainer","--domain-identifier",a],{allowFailure:!0,timeoutMs:sl(r,iG,"runner screenshot copy")})).exitCode)return;let a=i.stderr.trim()||i.stdout.trim()||`devicectl exited with code ${i.exitCode}`;throw new b("COMMAND_FAILED",`Failed to capture iOS screenshot: ${a}`)}async function ss(e,t,n){let r=ni.fromTimeoutMs(iG),i="Unable to locate runner container for simulator screenshot";for(let s of oy){let l=await se(e,["get_app_container",e.id,s,"data"],{allowFailure:!0,timeoutMs:sl(r,iG,"runner screenshot container lookup")});if(0!==l.exitCode){let e=l.stderr.trim();e&&(i=e);continue}let u=l.stdout.trim();if(!u){i="simctl get_app_container returned empty output";continue}for(let e of function(e,t){let n=o.resolve(e),r=t.trim();if(!r)return[];let i=[],a=new Set,s=e=>{let t=o.normalize(e);a.has(t)||(a.add(t),i.push(t))},l=r.replace(/^\/+/,""),u=l.replace(/\\/g,"/");if(l&&s(o.join(n,l)),o.isAbsolute(r)&&s(o.normalize(r)),u.startsWith("tmp/"))s(o.join(n,u));else{let e=u.lastIndexOf("/tmp/");if(e>=0){let t=u.slice(e+1);s(o.join(n,t))}}let d=o.basename(r);return d&&s(o.join(n,"tmp",d)),i}(u,t))try{await a.copyFile(e,n);return}catch(e){i=e instanceof Error?e.message:String(e)}}throw new b("COMMAND_FAILED",`Failed to capture iOS screenshot: ${i}`)}function sl(e,t,n){let r=e.remainingMs();if(r>0)return r;throw new b("COMMAND_FAILED",`iOS ${n} timed out after ${t}ms`,{timeoutMs:t,step:n})}function su(e,t,n){let r=sc(n);M({level:"warn",phase:"ios_screenshot_fallback",data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,from:t,to:"runner",...r}})}function sd(e,t,n){M({level:"warn",phase:`ios_screenshot_status_bar_${t}`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,...sc(n)}})}function sc(e){if(!(e instanceof b))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 sp(e){if(!(e instanceof b)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details??{},n="string"==typeof t.stdout?t.stdout:"",r="string"==typeof t.stderr?t.stderr:"",i=Array.isArray(t.args)?t.args.filter(e=>"string"==typeof e).join(" "):"",a=`${e.message}
24
- ${n}
25
- ${r}
26
- ${i}`.toLowerCase();return a.includes("timeout waiting for screen surfaces")||a.includes("nsposixerrordomain")&&a.includes("code=60")&&a.includes("screenshot")||a.includes("timed out")&&a.includes("screenshot")}let sf={settings:"com.apple.Preferences"},sm=null;function sh(e,t,n){return _("xcrun",iX(e,t),n)}function sw(e){return e.includes("not installed")||e.includes("not found")||e.includes("no such file")}async function sg(e,t){if("macos"===e.platform)return await aD(t);let n=t.trim();if(n.includes("."))return n;let r=sf[n.toLowerCase()];if(r)return r;let i=("simulator"===e.kind?await sC(e):await iq(e,"all")).filter(e=>e.name.toLowerCase()===n.toLowerCase());if(1===i.length)return i[0].bundleId;if(i.length>1)throw new b("INVALID_ARGS",`Multiple apps matched "${t}"`,{matches:i});throw new b("APP_NOT_INSTALLED",`No app found matching "${t}"`)}async function sy(e,t,n){if("macos"===e.platform)return void await aM(e,t,n);let r=n?.url?.trim();if(r){if(!t6(r))throw new b("INVALID_ARGS","open <app> <url> requires a valid URL target");if("simulator"===e.kind){await i0(e),await sh(e,["openurl",e.id,r]);return}let i=t9(n?.appBundleId??await sg(e,t),r);if(!i)throw new b("INVALID_ARGS","Deep link open on iOS devices requires an active app bundle ID. Open the app first, then open the URL.");await sU(e,i,{payloadUrl:r});return}let i=t.trim();if(t6(i)){if("simulator"===e.kind){await i0(e),await sh(e,["openurl",e.id,i]);return}let t=t9(n?.appBundleId,i);if(!t)throw new b("INVALID_ARGS","Deep link open on iOS devices requires an active app bundle ID. Open the app first, then open the URL.");await sU(e,t,{payloadUrl:i});return}let a=n?.appBundleId??await sg(e,t);"simulator"===e.kind?await sF(e,a):await sU(e,a)}async function sI(e){"macos"===e.platform||"simulator"!==e.kind||"Booted"!==await i2(e)&&await i0(e)}async function sv(e,t){if("macos"===e.platform)return void await aC(e,t);let n=await sg(e,t);if("simulator"===e.kind){await i0(e);let t=iX(e,["terminate",e.id,n]),r=await _("xcrun",t,{allowFailure:!0});if(0!==r.exitCode){if(r.stderr.toLowerCase().includes("found nothing to terminate"))return;throw new b("COMMAND_FAILED",`xcrun exited with code ${r.exitCode}`,{cmd:"xcrun",args:t,stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode})}return}await ij(["device","process","terminate","--device",e.id,n],{action:"terminate iOS app",deviceId:e.id})}async function sb(e,t){let n=await sg(e,t);if("simulator"!==e.kind){let t=["devicectl","device","uninstall","app","--device",e.id,n],r=await _("xcrun",t,{allowFailure:!0,timeoutMs:iF});if(0!==r.exitCode){let i=String(r.stdout??""),a=String(r.stderr??"");if(!sw(`${i}
27
- ${a}`.toLowerCase()))throw new b("COMMAND_FAILED",`Failed to uninstall iOS app ${n}`,{cmd:"xcrun",args:t,exitCode:r.exitCode,stdout:i,stderr:a,deviceId:e.id,hint:iH(i,a)??iz})}return{bundleId:n}}await i0(e);let r=await sh(e,["uninstall",e.id,n],{allowFailure:!0});if(0!==r.exitCode&&!sw(`${r.stdout}
28
- ${r.stderr}`.toLowerCase()))throw new b("COMMAND_FAILED",`simctl uninstall failed for ${n}`,{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode});return{bundleId:n}}async function sA(e,t,n){let r=await i9({kind:"path",path:t},n);try{return await sx(e,r.installablePath),{archivePath:r.archivePath,installablePath:r.installablePath,bundleId:r.bundleId,appName:r.appName,launchTarget:r.bundleId}}finally{await r.cleanup()}}async function sS(e,t,n){let{bundleId:r}=await sb(e,t);return await sA(e,n,{appIdentifierHint:t}),{bundleId:r}}async function sx(e,t){"simulator"!==e.kind?await ij(["device","install","app","--device",e.id,t],{action:"install iOS app",deviceId:e.id}):(await i0(e),await sh(e,["install",e.id,t]))}async function s_(e){if("macos"===e.platform)return await aO();iZ(e,"clipboard"),await i0(e);let t=await sh(e,["pbpaste",e.id],{allowFailure:!0});if(0!==t.exitCode)throw new b("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 sN(e,t){if("macos"===e.platform)return void await aL(t);iZ(e,"clipboard"),await i0(e);let n=await sh(e,["pbcopy",e.id],{allowFailure:!0,stdin:t});if(0!==n.exitCode)throw new b("COMMAND_FAILED","Failed to write iOS simulator clipboard",{stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode})}async function sE(e,t,n){iZ(e,"push"),await i0(e);let r=await a.mkdtemp(o.join(l.tmpdir(),"agent-device-ios-push-")),i=o.join(r,"payload.apns");try{await a.writeFile(i,`${JSON.stringify(n)}
29
- `,"utf8"),await sh(e,["push",e.id,t,i])}finally{await a.rm(r,{recursive:!0,force:!0})}}async function sD(e,t,n,r,i){if("macos"===e.platform){let e=t.toLowerCase();if("appearance"===e)return void await ak(n);if("permission"===e){let e=iI(n);if("deny"===e)throw new b("INVALID_ARGS",B("permission"));let t=function(e){let t=e?.trim().toLowerCase();if("accessibility"===t||"screen-recording"===t||"input-monitoring"===t)return t;throw new b("INVALID_ARGS","Unsupported macOS permission target. Use accessibility|screen-recording|input-monitoring.")}(i?.permissionTarget);return await ay(e,t)}throw new b("INVALID_ARGS",B(t))}iZ(e,"settings"),await i0(e);let a=t.toLowerCase();switch(a){case"wifi":{let t=sO(n);await sh(e,["status_bar",e.id,"override","--wifiMode",t?"active":"failed"]);return}case"airplane":return void(sO(n)?await sh(e,["status_bar",e.id,"override","--dataNetwork","hide","--wifiMode","failed","--wifiBars","0","--cellularMode","failed","--cellularBars","0","--operatorName",""]):await sh(e,["status_bar",e.id,"clear"]));case"location":{let t=sO(n);if(!r)throw new b("INVALID_ARGS","location setting requires an active app in session");await sh(e,["privacy",e.id,t?"grant":"revoke","location",r]);return}case"faceid":case"touchid":{let t=sT[a],r=function(e,t){let n=e.trim().toLowerCase();if("match"===n)return"match";if("nonmatch"===n)return"nonmatch";if("enroll"===n)return"enroll";if("unenroll"===n)return"unenroll";throw new b("INVALID_ARGS",`Invalid ${t} state: ${e}. Use match|nonmatch|enroll|unenroll.`)}(n,a);await s$(e,r,{settingName:a,label:t.label,modalityAliases:t.modalityAliases});return}case"appearance":{let t=await sL(e,n);await sh(e,["ui",e.id,"appearance",t]);return}case"permission":{var o;if(!r)throw new b("INVALID_ARGS","permission setting requires an active app in session");let t="deny"===(o=iI(n))?"revoke":o,a=function(e,t){let n=iv(e);if("photos"!==n&&t?.trim())throw new b("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 b("INVALID_ARGS",`Invalid photos mode: ${t}. Use full|limited.`)}throw new b("INVALID_ARGS",`Unsupported permission target: ${e}. Use camera|microphone|photos|contacts|contacts-limited|notifications|calendar|location|location-always|media-library|motion|reminders|siri.`)}(i?.permissionTarget,i?.permissionMode);await sk(e,t,a,r);return}default:throw new b("INVALID_ARGS",`Unsupported setting: ${t}`)}}async function sM(e,t="all"){return"macos"===e.platform?await aR(t):"simulator"===e.kind?ar(await sC(e),t):await iq(e,t)}async function sC(e){let t=(await sh(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 _("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 sO(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 b("INVALID_ARGS",`Invalid setting state: ${e}`)}async function sL(e,t){let n=ib(t);if("toggle"!==n)return n;let r=await sh(e,["ui",e.id,"appearance"],{allowFailure:!0});if(0!==r.exitCode)throw new b("COMMAND_FAILED","Failed to read current iOS appearance",{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode});let i=function(e,t){let n=/\b(light|dark|unsupported|unknown)\b/i.exec(`${e}
30
- ${t}`);if(!n)return null;let r=n[1].toLowerCase();return"dark"===r?"dark":"light"===r?"light":null}(r.stdout,r.stderr);if(!i)throw new b("COMMAND_FAILED","Unable to determine current iOS appearance for toggle",{stdout:r.stdout,stderr:r.stderr});return"dark"===i?"light":"dark"}let sT={faceid:{label:"Face ID",modalityAliases:["face"]},touchid:{label:"Touch ID",modalityAliases:["finger","touch"]}};async function sk(e,t,n,r){let i=await sP(e);if(!i.has(n))throw new b("UNSUPPORTED_OPERATION",`iOS simctl privacy does not support service "${n}" on this runtime.`,{deviceId:e.id,appBundleId:r,hint:`Supported services: ${Array.from(i).sort().join(", ")}`});let a=["privacy",e.id,t,n,r],o="notifications"===n;if(!("reset"===t&&o))try{await sh(e,a);return}catch(t){if(!(o&&sR(t)))throw t;throw new b("UNSUPPORTED_OPERATION","iOS simulator does not support setting notifications permission via simctl privacy on this runtime.",{deviceId:e.id,appBundleId:r,hint:"Use reset notifications for reprompt behavior, or toggle notifications manually in Settings."})}try{await sh(e,a);return}catch(e){if(!sR(e))throw e}try{await sh(e,["privacy",e.id,"reset","all",r])}catch(t){throw new b("COMMAND_FAILED","iOS simulator blocked direct notifications reset. Fallback reset-all also failed.",{deviceId:e.id,appBundleId:r,hint:"Use reinstall to force a fresh notifications prompt, or reset simulator content and settings."},t instanceof Error?t:void 0)}}function sR(e){if(!(e instanceof b)||"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 sP(e){let n=np(e.simulatorSetPath),r=`${process.env.PATH??""}::${n??""}`;if(sm&&t===r)return sm;let i=await sh(e,["privacy","help"],{allowFailure:!0}),a=function(e){let t=new Set,n=!1;for(let r of e.split("\n")){let e=r.trim();if(!e)continue;if("service"===e){n=!0;continue}if(!n)continue;if(e.startsWith("bundle identifier"))break;let i=/^([a-z-]+)\s+-\s+/.exec(e);i&&t.add(i[1])}return t}(`${i.stdout}
31
- ${i.stderr}`);if(0===a.size)throw new b("COMMAND_FAILED","Unable to determine supported simctl privacy services",{stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode,hint:"Run `xcrun simctl privacy help` manually to verify available services for this runtime."});return sm=a,t=r,a}async function s$(e,t,n){let r=function(e,t,n){let r=n.length>0?n:["face"];switch(t){case"match":return r.flatMap(t=>[["biometric",e,"match",t],["biometric","match",e,t]]);case"nonmatch":return r.flatMap(t=>[["biometric",e,"nonmatch",t],["biometric",e,"nomatch",t],["biometric","nonmatch",e,t],["biometric","nomatch",e,t]]);case"enroll":return[["biometric",e,"enroll","yes"],["biometric",e,"enroll","1"],["biometric","enroll",e,"yes"],["biometric","enroll",e,"1"]];case"unenroll":return[["biometric",e,"enroll","no"],["biometric",e,"enroll","0"],["biometric","enroll",e,"no"],["biometric","enroll",e,"0"]]}}(e.id,t,n.modalityAliases),i=[];for(let t of r){let n=iX(e,t),r=await _("xcrun",n,{allowFailure:!0});if(0===r.exitCode)return;i.push({args:n,stderr:r.stderr,stdout:r.stdout,exitCode:r.exitCode})}let a=i.map(e=>({args:e.args.join(" "),exitCode:e.exitCode,stderr:e.stderr.slice(0,400)}));if(i.length>0&&i.every(e=>{var t,n;let r;return t=e.stdout,n=e.stderr,(r=`${t}
32
- ${n}`.toLowerCase()).includes("unrecognized subcommand")||r.includes("unknown subcommand")||r.includes("not supported")||r.includes("unavailable")||r.includes("biometric")&&r.includes("invalid")}))throw new b("UNSUPPORTED_OPERATION",`${n.label} simulation is not supported on this simulator runtime.`,{deviceId:e.id,action:t,setting:n.settingName,attempts:a});throw new b("COMMAND_FAILED",`Failed to simulate ${n.settingName}.`,{deviceId:e.id,action:t,setting:n.settingName,attempts:a})}async function sF(e,t){await i0(e);let n=0,r=ni.fromTimeoutMs(i$);try{await na(async({deadline:n})=>{var r;if(n?.isExpired())throw new b("COMMAND_FAILED","App launch deadline exceeded",{timeoutMs:i$});let i=(r=["launch",e.id,t],iX(e,r)),a=await _("xcrun",i,{allowFailure:!0});if(0!==a.exitCode)throw new b("COMMAND_FAILED",`xcrun exited with code ${a.exitCode}`,{cmd:"xcrun",args:i,stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode})},{maxAttempts:10,baseDelayMs:1e3,maxDelayMs:5e3,jitter:.2,shouldRetry:e=>!!iK(e)&&(n+=1)<3},{deadline:r})}catch(n){if(iK(n)){var i;let r=(i=await iY(e,t)).installed?!1===i.simulatorCompatible?"ARCH_MISMATCH":"PERSISTENT_LAUNCH_FAIL":"APP_NOT_INSTALLED";n.details={...n.details,hint:function(e){switch(e){case"ARCH_MISMATCH":return"The app binary was not built for the simulator platform. Rebuild with a simulator destination or use a physical device.";case"APP_NOT_INSTALLED":return"The app bundle is not installed on this simulator. Run install before open.";case"PERSISTENT_LAUNCH_FAIL":return"The simulator repeatedly refused to launch the app. Inspect crash logs in Console.app or ~/Library/Logs/DiagnosticReports/ and consider reinstalling the app.";default:return"The simulator failed to launch the app. Retry with --debug and inspect diagnostics log for details."}}(r)}}throw n}}async function sU(e,t,n){let r=["device","process","launch","--device",e.id,t];n?.payloadUrl&&r.push("--payload-url",n.payloadUrl),await ij(r,{action:"launch iOS app",deviceId:e.id})}async function sV(e,t,n,r){let i=r?.maxScrolls??48,a=await e({command:"findText",text:n});if(a?.found)return{attempts:0};let o=sG(await e({command:"snapshot",interactiveOnly:!0,compact:!0}));for(let r=1;r<=i;r+=1){t(),await e({command:"swipe",direction:"up"}),await new Promise(e=>setTimeout(e,80));let i=await e({command:"findText",text:n});if(i?.found)return{attempts:r};let a=sG(await e({command:"snapshot",interactiveOnly:!0,compact:!0}));if(a===o)throw new b("COMMAND_FAILED",`scrollintoview could not find text: ${n}`,{reason:"not_found",attempts:r,stalled:!0});o=a}throw new b("COMMAND_FAILED",`scrollintoview could not find text: ${n}`,{reason:"not_found",attempts:i})}function sG(e){let t=e.nodes;return JSON.stringify(Array.isArray(t)?t:e)}async function sB(e,t,n,r,i,a,o){if("tv"===t.target)return sW(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}}(i),appBundleId:n.appBundleId},r),a);let s=o??await sj(e,t,n,r),l=rT({direction:i,amount:a?.amount,pixels:a?.pixels,referenceWidth:s.referenceWidth,referenceHeight:s.referenceHeight});return sW(await e(t,{command:"drag",x:s.originX+l.x1,y:s.originY+l.y1,x2:s.originX+l.x2,y2:s.originY+l.y2,appBundleId:n.appBundleId},r),{amount:l.amount,pixels:l.pixels,preferProvidedPixels:!0})}async function sj(e,t,n,r){let i=await e(t,{command:"interactionFrame",appBundleId:n.appBundleId},r),a=sq(i.x),o=sq(i.y),s=sq(i.referenceWidth),l=sq(i.referenceHeight);if(void 0===a||void 0===o||void 0===s||void 0===l)throw new b("COMMAND_FAILED","interactionFrame did not return a usable frame");return{originX:a,originY:o,referenceWidth:s,referenceHeight:l}}function sq(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function sW(e,t){var n;let{x1:r,y1:i,x2:a,y2:o}={x1:sq((n=e).x),y1:sq(n.y),x2:sq(n.x2),y2:sq(n.y2)},s=sq(e.referenceWidth),l=sq(e.referenceHeight),u=void 0!==r&&void 0!==a?Math.round(Math.abs(a-r)):void 0,d=void 0!==i&&void 0!==o?Math.round(Math.abs(o-i)):void 0,c=t?.preferProvidedPixels&&void 0!==t.pixels?t.pixels:u&&u>0?u:d&&d>0?d:void 0;return{...void 0!==r?{x1:r}:{},...void 0!==i?{y1:i}:{},...void 0!==a?{x2:a}:{},...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 sz(){return process.env.WAYLAND_DISPLAY||"wayland"===process.env.XDG_SESSION_TYPE?"wayland":"x11"}let sH=null;async function sJ(){if(sH)return sH;let e=sz();if("wayland"===e){if(await D("ydotool"))return sH={tool:"ydotool",display:e};throw new b("TOOL_MISSING","ydotool is required for input synthesis on Wayland (xdotool does not work on Wayland). Install it via your package manager.")}if(await D("xdotool"))return sH={tool:"xdotool",display:e};throw new b("TOOL_MISSING","xdotool is required for input synthesis on X11. Install it via your package manager.")}async function sX(...e){await _("xdotool",e,{allowFailure:!1,timeoutMs:1e4})}async function sK(...e){await _("ydotool",e,{allowFailure:!1,timeoutMs:1e4})}async function sY(e,t){let{tool:n}=await sJ();"xdotool"===n?await sX("mousemove","--sync",String(e),String(t)):await sK("mousemove","--absolute","-x",String(e),"-y",String(t))}async function sZ(e,t){let{tool:n}=await sJ();"xdotool"===n?await sX("key","--clearmodifiers",e):await sK("key",...t)}async function sQ(e,t,n,r){await sY(e,t);let{tool:i}=await sJ();"xdotool"===i?await sX("click",n):await sK("click",r)}async function s0(e,t){await sQ(e,t,"1","0xC0")}async function s1(e,t){await sQ(e,t,"3","0xC1")}async function s2(e,t){await sQ(e,t,"2","0xC2")}async function s3(e,t){let{tool:n}=await sJ();await sY(e,t),"xdotool"===n?await sX("click","--repeat","2","1"):(await sK("click","0xC0"),await sK("click","0xC0"))}async function s4(e,t,n=800){let{tool:r}=await sJ();await sY(e,t),"xdotool"===r?(await sX("mousedown","1"),await le(n),await sX("mouseup","1")):(await sK("click","--down","0xC0"),await le(n),await sK("click","--up","0xC0"))}async function s5(e,t){await s0(e,t)}async function s8(e,t,n,r,i=300){let{tool:a}=await sJ();await sY(e,t),"xdotool"===a?(await sX("mousedown","1"),await sX("mousemove","--sync",String(n),String(r)),await le(i),await sX("mouseup","1")):(await sK("click","--down","0xC0"),await sK("mousemove","--absolute","-x",String(n),"-y",String(r)),await le(i),await sK("click","--up","0xC0"))}async function s6(e,t){let{tool:n}=await sJ(),r=5;if(t?.pixels!=null?r="xdotool"===n?Math.max(1,Math.round(t.pixels/15)):Math.max(1,Math.round(t.pixels/40)):t?.amount!=null&&(r=Math.max(1,Math.round(5*(t.amount/.6)))),"xdotool"===n)await sX("click","--repeat",String(r),"up"===e?"4":"down"===e?"5":"left"===e?"6":"7");else if("up"===e||"down"===e){let t="up"===e?String(-r):String(r);await sK("mousemove","--wheel","-y",t)}else{let t="left"===e?String(-r):String(r);await sK("mousemove","--wheel","-x",t)}}async function s9(e,t=0){let{tool:n}=await sJ();if("xdotool"===n){let n=["type"];t>0&&n.push("--delay",String(t)),n.push("--clearmodifiers","--",e),await sX(...n)}else await sK("type","--",e)}async function s7(e,t,n,r=0){await s0(e,t),await le(100),await sZ("ctrl+a",["29:1","30:1","30:0","29:0"]),await le(50),await s9(n,r)}function le(e){return new Promise(t=>setTimeout(t,e))}function lt(e){let t=null;return{resolve:async function(){if(t)return t;let n="wayland"===sz()?"wayland":"x11";for(let r of"wayland"===n?e.wayland:e.x11)if(await D(r.command))return t={tool:r.tool,display:n};throw new b("TOOL_MISSING","wayland"===n?e.waylandError:e.x11Error)},resetCache:()=>{t=null}}}let ln=lt({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 lr(e){let{tool:t}=await ln.resolve();switch(t){case"grim":await _("grim",[e]);break;case"scrot":await _("scrot",[e]);break;case"import":await _("import",["-window","root",e]);break;case"gnome-screenshot":await _("gnome-screenshot",["-f",e])}}async function li(e){if(e.includes("://")||e.startsWith("/"))return void await _("xdg-open",[e]);if(await D(e)){_(e,[],{allowFailure:!0}).catch(t=>{M({level:"warn",phase:"linux_app_launch",data:{app:e,error:String(t)}})}),await new Promise(e=>setTimeout(e,500));return}await _("xdg-open",[e],{allowFailure:!0})}async function la(e){await D("wmctrl")?await _("wmctrl",["-c",e],{allowFailure:!0}):await _("pkill",["-x",e],{allowFailure:!0})}async function lo(){await sZ("alt+Left",["56:1","105:1","105:0","56:0"])}async function ls(){await sZ("super+d",["125:1","32:1","32:0","125:0"])}let ll=lt({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 lu(){let{tool:e}=await ll.resolve();switch(e){case"wl-clipboard":return(await _("wl-paste",["--no-newline"],{allowFailure:!0,timeoutMs:5e3})).stdout;case"xclip":return(await _("xclip",["-selection","clipboard","-o"],{allowFailure:!0,timeoutMs:5e3})).stdout;case"xsel":return(await _("xsel",["--clipboard","--output"],{allowFailure:!0,timeoutMs:5e3})).stdout}}async function ld(e){let{tool:t}=await ll.resolve();switch(t){case"wl-clipboard":await _("wl-copy",["--",e],{allowFailure:!1,timeoutMs:5e3});break;case"xclip":await _("xclip",["-selection","clipboard"],{allowFailure:!1,timeoutMs:5e3,stdin:e});break;case"xsel":await _("xsel",["--clipboard","--input"],{allowFailure:!1,timeoutMs:5e3,stdin:e})}}async function lc(){return"linux"!==process.platform?[]:[{platform:"linux",id:"local",name:u(),kind:"device",target:"desktop",booted:!0}]}ll.resetCache;let lp={"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"},lf="atspi-dump.py",lm=null;async function lh(e,t={}){let n;if("linux"!==process.platform)throw new b("UNSUPPORTED_PLATFORM","AT-SPI2 bridge is only available on Linux");if(!await D("python3"))throw new b("TOOL_MISSING","python3 is required for AT-SPI2 accessibility snapshots on Linux.");let i=t.maxNodes??1500,a=t.maxDepth??12,l=t.maxApps??24,u=[function(){if(lm)return lm;let e=o.dirname(s(import.meta.url));for(let t=0;t<5;t++){let n=o.join(e,"src","platforms","linux",lf);if(r.existsSync(n))return lm=n,n;if(0===t){let t=o.join(e,lf);if(r.existsSync(t))return lm=t,t}e=o.dirname(e)}throw new b("TOOL_MISSING",`Cannot find ${lf}. Ensure the agent-device package is installed correctly.`)}(),"--surface",e,"--max-nodes",String(i),"--max-depth",String(a),"--max-apps",String(l)],d=await _("python3",u,{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 b("TOOL_MISSING","AT-SPI2 Python bindings not found. Install python3-gi and gir1.2-atspi-2.0.",{cause:e});throw new b("COMMAND_FAILED",`AT-SPI2 snapshot failed (exit ${d.exitCode}): ${e||d.stdout}`)}try{n=JSON.parse(d.stdout)}catch{throw new b("COMMAND_FAILED",`AT-SPI2 snapshot returned invalid JSON: ${d.stdout.slice(0,200)}`)}if(n.error)throw new b("COMMAND_FAILED",`AT-SPI2: ${n.error}`);return{nodes:(n.nodes??[]).map(e=>{let t,n;return{index:e.index,type:(n=lp[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:n.truncated,surface:e}}async function lw(e){let t="desktop"===e?"desktop":"frontmost-app"===e||"app"===e?"frontmost-app":("menubar"===e&&M({level:"warn",phase:"linux_snapshot",data:{message:"menubar surface is not supported on Linux, falling back to desktop"}}),"desktop"),n=await lh(t);return{nodes:n.nodes,truncated:n.truncated}}function lg(e){return e?.clickButton??"primary"}function ly(e){return"primary"===e.button?null:"click"!==e.commandLabel?new b("INVALID_ARGS","--button is supported only for click"):"macos"!==e.platform&&"linux"!==e.platform?new b("UNSUPPORTED_OPERATION",`click --button ${e.button} is supported only on macOS and Linux`):"macos"===e.platform&&"middle"===e.button?new b("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 b("INVALID_ARGS",`click --button ${e.button} does not support repeat or gesture modifier flags`):null}function lI(e){return"primary"===e?{}:{button:e}}let lv=/^[A-Za-z0-9_.:-]{1,64}$/,lb=[[0,0],[1,0],[0,1],[-1,0],[0,-1],[1,1],[-1,1],[1,-1],[-1,-1]];function lA(e,t,n,r){if(!Number.isFinite(e)||!Number.isInteger(e)||e<n||e>r)throw new b("INVALID_ARGS",`${t} must be an integer between ${n} and ${r}`);return e}async function lS(e,t,n){for(let r=0;r<e;r+=1)await n(r),r<e-1&&t>0&&await lx(t)}async function lx(e){await new Promise(t=>setTimeout(t,e))}function l_(e,t){let n,i=t?.subject??"Payload",a=e.trim();if(!a)throw new b("INVALID_ARGS",`${i} cannot be empty`);let o=t?.expandPath?t.expandPath(a,t.cwd):a;try{if(!r.statSync(o).isFile())throw new b("INVALID_ARGS",`${i} path is not a file: ${o}`);return{kind:"file",path:o}}catch(t){if(t instanceof b)throw t;let e=t.code;if("EACCES"===e||"EPERM"===e)throw new b("INVALID_ARGS",`${i} file is not readable: ${o}`);if(e&&"ENOENT"!==e)throw new b("COMMAND_FAILED",`Unable to read ${i} file: ${o}`,{cause:String(t)})}if((n=a.trim()).startsWith("{")&&n.endsWith("}")||n.startsWith("[")&&n.endsWith("]"))return{kind:"inline",text:a};throw new b("INVALID_ARGS",`${i} file not found: ${o}`)}async function lN(e){let t=l_(e,{subject:"Push payload"}),n="inline"===t.kind?t.text:await lE(t.path);try{let e=JSON.parse(n);if(!e||"object"!=typeof e||Array.isArray(e))throw new b("INVALID_ARGS","push payload must be a JSON object");return e}catch(t){if(t instanceof b)throw t;throw new b("INVALID_ARGS",`Invalid push payload JSON: ${e}`)}}async function lE(e){try{return await a.readFile(e,"utf8")}catch(n){let t=n.code;if("ENOENT"===t)throw new b("INVALID_ARGS",`Push payload file not found: ${e}`);if("EISDIR"===t)throw new b("INVALID_ARGS",`Push payload path is not a file: ${e}`);if("EACCES"===t||"EPERM"===t)throw new b("INVALID_ARGS",`Push payload file is not readable: ${e}`);throw new b("COMMAND_FAILED",`Unable to read push payload file: ${e}`,{cause:String(n)})}}function lD(e){if(void 0===e)throw new b("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 b("INVALID_ARGS",`Invalid rotation: ${e}. Use portrait|portrait-upside-down|landscape-left|landscape-right.`)}}let lM=nG(process.env.AGENT_DEVICE_IOS_DEVICECTL_LIST_TIMEOUT_MS,8e3,500),lC=/^(iphone|ipad|ipod|appletv)/i,lO=/\b(iphone|ipad|ipod)\b/i,lL=/^appletv/i,lT=["apple tv","appletv","tvos"],lk=/^==\s*(.+?)\s*==$/,lR=/^(?<name>.+?)\s+\[(?<id>[^[\]]+)\]\s*$/;function lP(e){return(e??"").trim().toLowerCase()}function l$(e){return lP(e.hardwareProperties?.platform)}function lF(e){return e.includes("tvos")}function lU(e){let t=lP(e);return lT.some(e=>t.includes(e))}function lV(e){return[e.name??"",e.deviceProperties?.name??"",e.deviceProperties?.deviceType??""]}function lG(e){return e.hardwareProperties?.productType??e.deviceProperties?.productType??""}async function lB(e={}){let t,n,r=np(e.simulatorSetPath),i=e.target;try{t=await _("xcrun",iJ(["list","devices","-j"],{simulatorSetPath:r}))}catch{return null}try{n=JSON.parse(t.stdout)}catch{return null}let a=lj(n,r),o=null,s=null,l=null;for(let e of a)i&&e.target!==i||(e.booted&&(o=o??e),"mobile"===e.target&&(s=s??e),l=l??e);return o??s??l}function lj(e,t){let n=[];for(let[r,i]of Object.entries(e.devices))if(function(e){let t=lP(e);return t.includes("ios")||t.includes("tvos")}(r))for(let e of i)e.isAvailable&&n.push({platform:"ios",id:e.udid,name:e.name,kind:"simulator",target:lF(lP(r))?"tv":"mobile",booted:"Booted"===e.state,...t?{simulatorSetPath:t}:{}});return n}function lq(e,t){let n=new Set(e.map(e=>e.id)),r=[...e];for(let e of t)n.has(e.id)||(n.add(e.id),r.push(e));return r}async function lW(){let e=null;try{e=o.join(l.tmpdir(),`agent-device-devicectl-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);let t=await _("xcrun",["devicectl","list","devices","--json-output",e],{allowFailure:!0,timeoutMs:lM});if(0!==t.exitCode)return[];let n=await a.readFile(e,"utf8");return function(e){let t=[];for(let n of e.result?.devices??[]){if(!function(e){var t;let n=l$(e);return!!(n.includes("ios")||n.includes("tvos"))||(t=lG(e),!!lC.test(t.trim())||lV(e).some(lU))}(n))continue;let e=n.hardwareProperties?.udid??n.identifier??"",r=n.name??n.deviceProperties?.name??e;e&&t.push({platform:"ios",id:e,name:r,kind:"device",target:function(e){var t;return lF(l$(e))?"tv":(t=lG(e),lL.test(t.trim())||lV(e).some(lU))?"tv":"mobile"}(n),booted:!0})}return t}(JSON.parse(n))}catch{return[]}finally{e&&await a.rm(e,{force:!0}).catch(()=>{})}}async function lz(){try{let e=await _("xcrun",["xctrace","list","devices"],{allowFailure:!0});if(0!==e.exitCode)return[];return function(e){let t=[],n=null;for(let r of e.split(/\r?\n/)){let e=r.trim();if(!e)continue;let i=lk.exec(e);if(i){n=i[1]?.trim()??null;continue}if("Devices"!==n)continue;let a=lR.exec(e),o=a?.groups?.id?.trim()??"",s=a?.groups?.name?.trim()??"";if(!o||!s)continue;let l=function(e){return lU(e)?"tv":lO.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 lH(e={}){if("darwin"!==process.platform)throw new b("UNSUPPORTED_PLATFORM","Apple tools are only available on macOS");if(!await D("xcrun"))throw new b("TOOL_MISSING","xcrun not found in PATH");let t=np(e.simulatorSetPath),n=await _("xcrun",iJ(["list","devices","-j"],{simulatorSetPath:t})),r=[];try{let e=JSON.parse(n.stdout);r=lj(e,t)}catch(e){throw new b("COMMAND_FAILED","Failed to parse simctl devices JSON",void 0,e)}if(r.push({platform:"macos",id:"host-macos-local",name:l.hostname(),kind:"device",target:"desktop",booted:!0}),t)return r;let[i,a]=await Promise.all([lW(),lz()]);return r=lq(r,i),lq(r,a)}async function lJ(e,t,n){let r,i=!!(t.udid||t.serial||t.deviceName);try{r=await tG(e,t,n)}catch(e){if(i||!(e instanceof b)||"DEVICE_NOT_FOUND"!==e.code)throw e}if(!i&&(!t.platform||"apple"===t.platform||"ios"===t.platform)&&"desktop"!==t.target&&(!r||"device"===r.kind)){let e=await lB({simulatorSetPath:n.simulatorSetPath,target:t.target});if(e)return e}if(r)return r;throw new b("DEVICE_NOT_FOUND","No devices found",{selector:t})}async function lX(e){let t=t$(e.platform),n=tV({simulatorSetPath:np(e.iosSimulatorDeviceSet),platform:t,target:e.target}),r=nm(e.androidDeviceAllowlist);return await E("resolve_target_device",async()=>{let i={platform:t,target:e.target,deviceName:e.device,udid:e.udid,serial:e.serial};if(i.target&&!i.platform)throw new b("INVALID_ARGS","Device target selector requires --platform. Use --platform ios|macos|android|linux|apple with --target mobile|tv|desktop.");if("linux"===i.platform){let e=await lc();return await tG(e,i)}if("android"===i.platform){await t4();let e=await nM({serialAllowlist:r});return await tG(e,i)}if(i.platform){let e=await lH({simulatorSetPath:n});return await lJ(e,i,{simulatorSetPath:n})}let a=[];try{a.push(...await nM({serialAllowlist:r}))}catch{}try{a.push(...await lH({simulatorSetPath:n}))}catch{}try{a.push(...await lc())}catch{}return await tG(a,i,{simulatorSetPath:n})},{platform:t,target:e.target})}async function lK(e,t,n,r,i){let s={requestId:i?.requestId,appBundleId:i?.appBundleId,verbose:i?.verbose,logPath:i?.logPath,traceLogPath:i?.traceLogPath},l=function(e,t){switch(e.platform){case"android":return{open:(t,n)=>rf(e,t,n?.activity),openDevice:()=>rI(e),close:t=>rv(e,t),tap:(t,n)=>rQ(e,t,n),doubleTap:async(t,n)=>{await rQ(e,t,n),await rQ(e,t,n)},swipe:(t,n,r,i,a)=>r0(e,t,n,r,i,a),longPress:(t,n,r)=>r5(e,t,n,r),focus:(t,n)=>r9(e,t,n),type:(t,n)=>r8(e,t,n),fill:(t,n,r,i)=>r7(e,t,n,r,i),scroll:(t,n)=>ir(e,t,n),scrollIntoView:(t,n)=>ii(e,t,n),screenshot:t=>iO(e,t),back:t=>r1(e),home:()=>r2(e),rotate:t=>r3(e,t),appSwitcher:()=>r4(e),readClipboard:()=>ih(e),writeClipboard:t=>iw(e,t),setSetting:(t,n,r,i)=>iA(e,t,n,r,i)};case"linux":return{open:e=>li(e),openDevice:()=>Promise.resolve(),close:e=>la(e),tap:(e,t)=>s0(e,t),doubleTap:(e,t)=>s3(e,t),swipe:(e,t,n,r,i)=>s8(e,t,n,r,i),longPress:(e,t,n)=>s4(e,t,n),focus:(e,t)=>s5(e,t),type:(e,t)=>s9(e,t),fill:(e,t,n,r)=>s7(e,t,n,r),scroll:(e,t)=>s6(e,t),scrollIntoView:()=>{throw new b("UNSUPPORTED_OPERATION","scrollIntoView not yet supported on Linux")},screenshot:e=>lr(e),back:()=>lo(),home:()=>ls(),rotate:()=>{throw new b("UNSUPPORTED_OPERATION","rotate not supported on Linux")},appSwitcher:()=>{throw new b("UNSUPPORTED_OPERATION","appSwitcher not yet supported on Linux")},readClipboard:()=>lu(),writeClipboard:e=>ld(e),setSetting:()=>{throw new b("UNSUPPORTED_OPERATION","setSetting not supported on Linux")}};case"ios":case"macos":{let n,r,{overrides:i,runnerOpts:a}=(n={verbose:t.verbose,logPath:t.logPath,traceLogPath:t.traceLogPath,requestId:t.requestId},r=()=>{if(aq(t.requestId))throw az()},{runnerOpts:n,overrides:{tap:async(r,i)=>await oZ(e,{command:"tap",x:r,y:i,appBundleId:t.appBundleId},n),doubleTap:async(r,i)=>await oZ(e,{command:"tapSeries",x:r,y:i,count:1,intervalMs:0,doubleTap:!0,appBundleId:t.appBundleId},n),swipe:async(r,i,a,o,s)=>await oZ(e,{command:"drag",x:r,y:i,x2:a,y2:o,durationMs:s,appBundleId:t.appBundleId},n),longPress:async(r,i,a)=>await oZ(e,{command:"longPress",x:r,y:i,durationMs:a,appBundleId:t.appBundleId},n),focus:async(r,i)=>await oZ(e,{command:"tap",x:r,y:i,appBundleId:t.appBundleId},n),type:async(r,i)=>{await oZ(e,{command:"type",text:r,delayMs:i,appBundleId:t.appBundleId},n)},fill:async(r,i,a,o)=>{let s=await oZ(e,{command:"tap",x:r,y:i,appBundleId:t.appBundleId},n);return await oZ(e,{command:"type",text:a,clearFirst:!0,delayMs:o,appBundleId:t.appBundleId},n),s},scroll:async(r,i)=>await sB(oZ,e,t,n,r,i),scrollIntoView:async(i,a)=>await sV(r=>oZ(e,{...r,appBundleId:t.appBundleId},n),r,i,a)}});return{open:(t,n)=>sy(e,t,{appBundleId:n?.appBundleId,url:n?.url}),openDevice:()=>sI(e),close:t=>sv(e,t),screenshot:async(t,n)=>{"macos"===e.platform&&n?.surface&&"app"!==n.surface?await aS(t,{surface:n.surface,fullscreen:n.fullscreen}):await sn(e,t,n?.appBundleId,n?.fullscreen)},back:async n=>{await oZ(e,{command:"system"===n?"backSystem":"backInApp",appBundleId:t.appBundleId},a)},home:async()=>{await oZ(e,{command:"home",appBundleId:t.appBundleId},a)},rotate:async n=>{await oZ(e,{command:"rotate",orientation:n,appBundleId:t.appBundleId},a)},appSwitcher:async()=>{await oZ(e,{command:"appSwitcher",appBundleId:t.appBundleId},a)},readClipboard:()=>s_(e),writeClipboard:t=>sN(e,t),setSetting:(t,n,r,i)=>sD(e,t,n,r,i),...i}}default:throw new b("UNSUPPORTED_PLATFORM",`Unsupported platform: ${e.platform}`)}}(e,s);return M({level:"debug",phase:"platform_command_prepare",data:{command:t,platform:e.platform,kind:e.kind}}),await E("platform_command",async()=>{switch(t){case"open":return lY(e,l,n,i);case"close":{let e=n[0];if(!e)return{closed:"session",...tv("Closed session")};return await l.close(e),{app:e,...tv(`Closed: ${e}`)}}case"press":return lZ(e,l,n,i,s);case"swipe":return lQ(e,l,n,i,s);case"longpress":{let e=Number(n[0]),t=Number(n[1]),r=n[2]?Number(n[2]):void 0;if(Number.isNaN(e)||Number.isNaN(t))throw new b("INVALID_ARGS","longpress requires x y [durationMs]");return await l.longPress(e,t,r),{x:e,y:t,durationMs:r,...tv(`Long pressed (${e}, ${t})`)}}case"focus":{let[e,t]=n.map(Number);if(Number.isNaN(e)||Number.isNaN(t))throw new b("INVALID_ARGS","focus requires x y");return await l.focus(e,t),{x:e,y:t,...tv(`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 b("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 b("INVALID_ARGS","type requires text");let r=lA(i?.delayMs??0,"delay-ms",0,1e4);return await l.type(t,r),{text:t,delayMs:r,...tv(ue("Typed",t))}}case"fill":{let e=Number(n[0]),t=Number(n[1]),r=n.slice(2).join(" ");if(Number.isNaN(e)||Number.isNaN(t)||!r)throw new b("INVALID_ARGS","fill requires x y text");let a=lA(i?.delayMs??0,"delay-ms",0,1e4);return await l.fill(e,t,r,a),{x:e,y:t,text:r,delayMs:a,...tv(ue("Filled",r))}}case"scroll":return l0(l,n,i);case"scrollintoview":{let e=n.join(" ").trim();if(!e)throw new b("INVALID_ARGS","scrollintoview requires text");let t=await l.scrollIntoView(e,{maxScrolls:i?.maxScrolls});if("number"==typeof t?.attempts)return{text:e,attempts:t.attempts,...tv(`Scrolled into view: ${e}`)};return{text:e,...tv(`Scrolled into view: ${e}`)}}case"pinch":return l1(e,n,i,s);case"trigger-app-event":{let{eventName:t,payload:r}=function(e){let t=e[0]?.trim(),n=e[1]?.trim();if(!t)throw new b("INVALID_ARGS","trigger-app-event requires <event> [payloadJson]");if(!lv.test(t))throw new b("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 b("INVALID_ARGS","trigger-app-event accepts at most two arguments: <event> [payloadJson]");let r=function(e,t){if(e)try{let n=JSON.parse(e);if(!n||"object"!=typeof n||Array.isArray(n))throw new b("INVALID_ARGS",`trigger-app-event payload for "${t}" must be a JSON object`);let r=JSON.stringify(n);if(Buffer.byteLength(r,"utf8")>8192)throw new b("INVALID_ARGS",`trigger-app-event payload for "${t}" exceeds 8192 bytes`);return n}catch(t){if(t instanceof b)throw t;throw new b("INVALID_ARGS",`Invalid trigger-app-event payload JSON: ${e}`)}}(n,t);return{eventName:t,payload:r}}(n),a=function(e,t,n){var r;let i,a=(i=("ios"===(r=e)?process.env.AGENT_DEVICE_IOS_APP_EVENT_URL_TEMPLATE:"macos"===r?process.env.AGENT_DEVICE_MACOS_APP_EVENT_URL_TEMPLATE:process.env.AGENT_DEVICE_ANDROID_APP_EVENT_URL_TEMPLATE)??process.env.AGENT_DEVICE_APP_EVENT_URL_TEMPLATE,i?.trim()||void 0);if(!a)throw new b("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=a.replaceAll("{event}",encodeURIComponent(t)).replaceAll("{payload}",encodeURIComponent(o)).replaceAll("{platform}",encodeURIComponent(e));if(s.length>4096)throw new b("INVALID_ARGS","trigger-app-event URL exceeds maximum supported length",{hint:"Reduce payload size or shorten AGENT_DEVICE_*_APP_EVENT_URL_TEMPLATE.",length:s.length,maxLength:4096});return s}(e.platform,t,r);return await l.open(a,{appBundleId:i?.appBundleId}),{event:t,eventUrl:a,transport:"deep-link",...tv(`Triggered app event: ${t}`)}}case"screenshot":{let e=n[0]??r??`./screenshot-${Date.now()}.png`;return await a.mkdir(o.dirname(e),{recursive:!0}),await l.screenshot(e,{appBundleId:i?.appBundleId,fullscreen:i?.screenshotFullscreen,surface:i?.surface}),{path:e,...tv(`Saved screenshot: ${e}`)}}case"back":return await l.back(i?.backMode),{action:"back",mode:i?.backMode??"in-app",...tv("Back")};case"home":return await l.home(),{action:"home",...tv("Home")};case"rotate":{let e=lD(n[0]);return await l.rotate(e),{action:"rotate",orientation:e,...tv(`Rotated to ${e}`)}}case"app-switcher":return await l.appSwitcher(),{action:"app-switcher",...tv("Opened app switcher")};case"clipboard":return l2(l,n);case"keyboard":return l3(e,l,n,i,s);case"settings":return l4(e,l,n,i);case"push":return l5(e,n,i);case"snapshot":return l8(e,n,i,s);case"read":return l6(e,n,i,s);default:throw new b("INVALID_ARGS",`Unknown command: ${t}`)}},{command:t,platform:e.platform})}async function lY(e,t,n,r){let i=n[0],a=n[1];if(n.length>2)throw new b("INVALID_ARGS","open accepts at most two arguments: <app|url> [url]");if(!i)return await t.openDevice(),{app:null,...tv("Opened device")};if(void 0!==a){if("android"===e.platform)throw new b("INVALID_ARGS","open <app> <url> is supported only on Apple platforms");if(t6(i))throw new b("INVALID_ARGS","open <app> <url> requires an app target as the first argument");if(!t6(a))throw new b("INVALID_ARGS","open <app> <url> requires a valid URL target");return await t.open(i,{activity:r?.activity,appBundleId:r?.appBundleId,url:a}),{app:i,url:a,...tv(`Opened: ${i}`)}}return await t.open(i,{activity:r?.activity,appBundleId:r?.appBundleId}),{app:i,...tv(`Opened: ${i}`)}}async function lZ(e,t,n,r,i){let a,[o,s]=n.map(Number);if(Number.isNaN(o)||Number.isNaN(s))throw new b("INVALID_ARGS","press requires x y");if("macos"===e.platform&&r?.surface&&"app"!==r.surface){let e=lg(r);if("primary"!==e)throw new b("UNSUPPORTED_OPERATION",`${e} click is not supported on macOS ${r.surface} sessions.`);return await aA(o,s,{bundleId:r.appBundleId,surface:r.surface}),{x:o,y:s,...tv(l9({x:o,y:s}))}}let l=lg(r);if("primary"!==l){let t=ly({commandLabel:"click",platform:e.platform,button:l,count:r?.count,intervalMs:r?.intervalMs,holdMs:r?.holdMs,jitterPx:r?.jitterPx,doubleTap:r?.doubleTap});if(t)throw t;return"linux"===e.platform?"secondary"===l?await s1(o,s):await s2(o,s):await oZ(e,{command:"mouseClick",x:o,y:s,button:l,appBundleId:r?.appBundleId},{verbose:r?.verbose,logPath:r?.logPath,traceLogPath:r?.traceLogPath,requestId:r?.requestId}),{x:o,y:s,button:l,...tv(l9({x:o,y:s,button:l}))}}let u=lA(r?.count??1,"count",1,200),d=lA(r?.intervalMs??0,"interval-ms",0,1e4),c=lA(r?.holdMs??0,"hold-ms",0,1e4),p=lA(r?.jitterPx??0,"jitter-px",0,100),f=r?.doubleTap===!0;if(f&&c>0)throw new b("INVALID_ARGS","double-tap cannot be combined with hold-ms");if(f&&p>0)throw new b("INVALID_ARGS","double-tap cannot be combined with jitter-px");if(("ios"===e.platform||"macos"===e.platform)&&u>1&&0===c&&0===p){let t=await oZ(e,{command:"tapSeries",x:o,y:s,count:u,intervalMs:d,doubleTap:f,appBundleId:r?.appBundleId},{verbose:r?.verbose,logPath:r?.logPath,traceLogPath:r?.traceLogPath,requestId:r?.requestId});return{x:o,y:s,count:u,intervalMs:d,holdMs:c,jitterPx:p,doubleTap:f,timingMode:"runner-series",...t,...tv(l9({x:o,y:s}))}}return await lS(u,d,async e=>{let[n,r]=function(e,t){if(t<=0)return[0,0];let[n,r]=lb[e%lb.length];return[n*t,r*t]}(e,p),i=o+n,l=s+r;if(f){a??=await t.doubleTap(i,l)??void 0;return}c>0?a??=await t.longPress(i,l,c)??void 0:a??=await t.tap(i,l)??void 0}),tb({x:o,y:s,count:u,intervalMs:d,holdMs:c,jitterPx:p,doubleTap:f,...a},l9({x:o,y:s}))}async function lQ(e,t,n,r,i){let a=Number(n[0]),o=Number(n[1]),s=Number(n[2]),l=Number(n[3]);if([a,o,s,l].some(Number.isNaN))throw new b("INVALID_ARGS","swipe requires x1 y1 x2 y2 [durationMs]");let u=lA(n[4]?Number(n[4]):250,"durationMs",16,1e4),d="ios"===e.platform?Math.min(60,Math.max(16,Math.round(u))):u,c=lA(r?.count??1,"count",1,200),p=lA(r?.pauseMs??0,"pause-ms",0,1e4),f=r?.pattern??"one-way";if("one-way"!==f&&"ping-pong"!==f)throw new b("INVALID_ARGS",`Invalid pattern: ${f}`);if(("ios"===e.platform||"macos"===e.platform)&&c>1){let t=await oZ(e,{command:"dragSeries",x:a,y:o,x2:s,y2:l,durationMs:d,count:c,pauseMs:p,pattern:f,appBundleId:r?.appBundleId},{verbose:r?.verbose,logPath:r?.logPath,traceLogPath:r?.traceLogPath,requestId:r?.requestId});return{x1:a,y1:o,x2:s,y2:l,durationMs:u,effectiveDurationMs:d,timingMode:"runner-series",count:c,pauseMs:p,pattern:f,...t,...tv(l7(c,f))}}return await lS(c,p,async e=>{"ping-pong"===f&&e%2==1?await t.swipe(s,l,a,o,d):await t.swipe(a,o,s,l,d)}),tb({x1:a,y1:o,x2:s,y2:l,durationMs:u,effectiveDurationMs:d,timingMode:"ios"===e.platform?"safe-normalized":"direct",count:c,pauseMs:p,pattern:f},l7(c,f))}async function l0(e,t,n){let r=t[0],i=t[1]?Number(t[1]):void 0,a=n?.pixels;if(!r)throw new b("INVALID_ARGS","scroll requires direction");if(void 0!==i&&!Number.isFinite(i))throw new b("INVALID_ARGS","scroll amount must be a number");if(void 0!==i&&void 0!==a)throw new b("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 b("INVALID_ARGS",`Unknown direction: ${e}`)}}(r),s=await e.scroll(o,{amount:i,pixels:a});return tb({direction:o,...void 0!==i?{amount:i}:{},...void 0!==a?{pixels:a}:{},...s},void 0!==a?`Scrolled ${o} by ${a}px`:void 0!==i?`Scrolled ${o} by ${i}`:`Scrolled ${o}`)}async function l1(e,t,n,r){if("android"===e.platform)throw new b("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 b("UNSUPPORTED_OPERATION","pinch is only supported in macOS app sessions. Re-open the target app without --surface desktop|menubar|frontmost-app first.");let i=Number(t[0]),a=t[1]?Number(t[1]):void 0,o=t[2]?Number(t[2]):void 0;if(Number.isNaN(i)||i<=0)throw new b("INVALID_ARGS","pinch requires scale > 0");return await oZ(e,{command:"pinch",scale:i,x:a,y:o,appBundleId:n?.appBundleId},{verbose:n?.verbose,logPath:n?.logPath,traceLogPath:n?.traceLogPath,requestId:n?.requestId}),{scale:i,x:a,y:o,...tv(`Pinched to scale ${i}`)}}async function l2(e,t){let n=(t[0]??"").toLowerCase();if("read"!==n&&"write"!==n)throw new b("INVALID_ARGS","clipboard requires a subcommand: read or write");if("read"===n){if(1!==t.length)throw new b("INVALID_ARGS","clipboard read does not accept additional arguments");return{action:n,text:await e.readClipboard()}}if(t.length<2)throw new b("INVALID_ARGS",'clipboard write requires text (use "" to clear clipboard)');let r=t.slice(1).join(" ");return await e.writeClipboard(r),{action:n,textLength:Array.from(r).length,...tv("Clipboard updated")}}async function l3(e,t,n,r,i){let a=(n[0]??"status").toLowerCase();if("status"!==a&&"get"!==a&&"dismiss"!==a)throw new b("INVALID_ARGS","keyboard requires a subcommand: status, get, or dismiss");if(n.length>1)throw new b("INVALID_ARGS","keyboard accepts at most one subcommand argument");if("android"===e.platform){if("dismiss"===a){let t=await im(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 ip(e);return{platform:"android",action:"status",visible:t.visible,inputType:t.inputType,type:t.type}}if("ios"===e.platform){if("dismiss"!==a)throw new b("UNSUPPORTED_OPERATION","keyboard status/get is currently supported only on Android; use keyboard dismiss on iOS");let t=await oZ(e,{command:"keyboardDismiss",appBundleId:r?.appBundleId},i);return{platform:"ios",action:"dismiss",wasVisible:t.wasVisible,dismissed:t.dismissed,visible:t.visible,...tv(t.dismissed?"Keyboard dismissed":"Keyboard already hidden")}}throw new b("UNSUPPORTED_OPERATION","keyboard is supported only on Android and iOS")}async function l4(e,t,n,r){var i;let[a,o,s,l,u]=n,d="permission"===a?{permissionTarget:s,permissionMode:l}:void 0;M({level:"debug",phase:"settings_apply",data:{setting:a,state:o,target:s,mode:l,platform:e.platform}});let c=await t.setSetting(a,o,u??r?.appBundleId,d);return c&&"object"==typeof c?tb({setting:a,state:o,...c},("string"==typeof(i=c).message&&i.message.length>0?i.message:void 0)??`Updated setting: ${a}`):{setting:a,state:o,...tv(`Updated setting: ${a}`)}}async function l5(e,t,n){let r=t[0]?.trim(),i=t[1]?.trim();if(!r||!i)throw new b("INVALID_ARGS","push requires <bundle|package> <payload.json|inline-json>");let a=await lN(i);if("ios"===e.platform)return await sE(e,r,a),{platform:"ios",bundleId:r,...tv(`Pushed notification to ${r}`)};let o=await iM(e,r,a);return{platform:"android",package:r,action:o.action,extrasCount:o.extrasCount,...tv(`Pushed notification to ${r}`)}}async function l8(e,t,n,r){if("linux"===e.platform){let e=await E("snapshot_capture",async()=>await lw(n?.surface),{backend:"linux-atspi"});return{nodes:e.nodes??[],truncated:e.truncated??!1,backend:"linux-atspi"}}if("android"!==e.platform){let t=await E("snapshot_capture",async()=>await oZ(e,{command:"snapshot",appBundleId:n?.appBundleId,interactiveOnly:n?.snapshotInteractiveOnly,compact:n?.snapshotCompact,depth:n?.snapshotDepth,scope:n?.snapshotScope,raw:n?.snapshotRaw},{verbose:n?.verbose,logPath:n?.logPath,traceLogPath:n?.traceLogPath,requestId:n?.requestId}),{backend:"xctest"}),r=t.nodes??[];if(0===r.length&&"simulator"===e.kind)throw new b("COMMAND_FAILED","XCTest snapshot returned 0 nodes on iOS simulator.");return{nodes:r,truncated:t.truncated??!1,backend:"xctest"}}let i=await E("snapshot_capture",async()=>await rz(e,{interactiveOnly:n?.snapshotInteractiveOnly,compact:n?.snapshotCompact,depth:n?.snapshotDepth,scope:n?.snapshotScope,raw:n?.snapshotRaw}),{backend:"android"});return{nodes:i.nodes??[],truncated:i.truncated??!1,backend:"android",analysis:i.analysis}}async function l6(e,t,n,r){let[i,a]=t.map(Number);if(Number.isNaN(i)||Number.isNaN(a))throw new b("INVALID_ARGS","read requires x y");if("android"===e.platform)return{action:"read",text:await id(e,i,a)??""};if("macos"===e.platform&&n?.surface&&"app"!==n.surface)return{action:"read",text:(await ab(i,a,{bundleId:n.appBundleId,surface:n.surface})).text};let o=await oZ(e,{command:"readText",x:i,y:a,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 l9(e){return e.button&&"primary"!==e.button?`Clicked ${e.button} (${e.x}, ${e.y})`:`Tapped (${e.x}, ${e.y})`}function l7(e,t){return e<=1?"Swiped":"ping-pong"===t?`Swiped ${e} times (ping-pong)`:`Swiped ${e} times`}function ue(e,t){return`${e} ${Array.from(t).length} chars`}let ut=[250,400];function un(e,t,n=e.snapshot){if("android"!==e.device.platform)return;let r=n?.comparisonSafe===!0;e.androidSnapshotFreshness={action:t,markedAt:Date.now(),baselineCount:n?.nodes.length??0,baselineSignatures:r?uo(n?.nodes??[]):void 0,routeComparable:r}}function ur(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 ui(e){e&&"android"===e.device.platform&&delete e.androidSnapshotFreshness}function ua(e){return"press"===e||"click"===e||"back"===e||"open"===e}function uo(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("|"))}function us(e,t){return!(e<12)&&t<=Math.floor(.2*e)}function ul(e,t,n,r,i){return{requestId:i??x().requestId,appBundleId:n,activity:t?.activity,verbose:t?.verbose,logPath:e,traceLogPath:r,snapshotInteractiveOnly:t?.snapshotInteractiveOnly,snapshotCompact:t?.snapshotCompact,snapshotDepth:t?.snapshotDepth,snapshotScope:t?.snapshotScope,snapshotRaw:t?.snapshotRaw,screenshotFullscreen:t?.screenshotFullscreen,count:t?.count,intervalMs:t?.intervalMs,delayMs:t?.delayMs,holdMs:t?.holdMs,jitterPx:t?.jitterPx,pixels:t?.pixels,doubleTap:t?.doubleTap,clickButton:lg(t),backMode:t?.backMode,pauseMs:t?.pauseMs,pattern:t?.pattern,maxScrolls:t?.maxScrolls}}async function uu(e){let t=ur(e.session);if(t&&"android"===e.device.platform)return await uc(e,t);let n=await ud(e);return ui(e.session),{snapshot:um(n,e.flags),analysis:n.analysis}}async function ud(e){let{device:t,session:n,flags:r,outPath:i,logPath:a,snapshotScope:o}=e;if("linux"===t.platform){let e=await lw(n?.surface);return uh({nodes:e.nodes,truncated:e.truncated,backend:"linux-atspi"},{snapshotDepth:r?.snapshotDepth,snapshotInteractiveOnly:r?.snapshotInteractiveOnly,snapshotScope:o})}return"macos"===t.platform&&n?.surface&&"app"!==n.surface?uh(await av(n.surface,{bundleId:"menubar"===n.surface?n.appBundleId:void 0}),{snapshotDepth:r?.snapshotDepth,snapshotInteractiveOnly:r?.snapshotInteractiveOnly,snapshotScope:o}):await lK(t,"snapshot",[],i,{...ul(a,{...r,snapshotScope:o},n?.appBundleId,n?.trace?.outPath)})}async function uc(e,t){let n=await up(e),r=uf(n,t,e.flags),i=0;for(let a of ut){if(!r)break;await new Promise(e=>setTimeout(e,a)),n=await up(e),i+=1,r=uf(n,t,e.flags)}return r||ui(e.session),{snapshot:n.snapshot,analysis:n.data.analysis,freshness:i>0||r?{action:t.action,retryCount:i,staleAfterRetries:!!r,reason:r??void 0}:void 0}}async function up(e){let t=await ud(e);return{data:t,snapshot:um(t,e.flags)}}function uf(e,t,n){let r=n?.snapshotInteractiveOnly===!0,i=e.data.analysis;return r&&0===e.snapshot.nodes.length&&i&&i.rawNodeCount>=12?"empty-interactive":us(t.baselineCount,e.snapshot.nodes.length)?e.snapshot.nodes.some(e=>!0===e.hittable||!!e.label?.trim()||!!e.value?.trim()||!!e.identifier?.trim())?null:"sharp-drop":t.routeComparable&&ua(t.action)&&function(e,t){if(!e||0===e.length)return!1;let n=Math.max(e.length,t.length);if(n<12)return!1;let r=uo(t),i=Math.min(e.length,r.length),a=0;for(let t=0;t<i;t+=1)e[t]===r[t]&&(a+=1);let o=Math.max(0,r.length-e.length),s=Math.max(0,e.length-r.length),l=Math.max(3,Math.floor(.15*n));return a>=Math.floor(.9*n)&&o<=l&&s<=l}(t.baselineSignatures,e.snapshot.nodes)?"stuck-route":null}function um(e,t){let n=e?.nodes??[],r=function(e){let t=new Map;for(let[n,r]of e.entries())t.set(r.index,n);let n=[],r=[];for(let[i,a]of e.entries()){let e=Math.max(0,a.depth??0);for(;r.length>0&&e<=r[r.length-1].depth;)r.pop();let o="number"==typeof a.parentIndex?t.get(a.parentIndex):void 0,s="number"==typeof o&&o<i?o:r[r.length-1]?.index;n.push({...a,index:i,depth:e,parentIndex:s}),r.push({depth:e,index:i})}return n}(t?.snapshotRaw?n:e9(n));return{nodes:en(t?.snapshotScope&&e?.backend!=="macos-helper"?uw(r,t.snapshotScope):r),truncated:e?.truncated,createdAt:Date.now(),backend:e?.backend,comparisonSafe:e?.backend==="android"&&t?.snapshotInteractiveOnly!==!0&&t?.snapshotCompact!==!0&&"number"!=typeof t?.snapshotDepth&&!t?.snapshotScope}}function uh(e,t){var n,r;let i=e.nodes??[];return t.snapshotScope&&(i=uw(i,t.snapshotScope)),t.snapshotInteractiveOnly&&(i=function(e){if(0===e.length)return e;let t=new Map;for(let n of e)t.set(n.index,n);let n=new Set;for(let r of e){if(!function(e){if(e.hittable||e.rect)return!0;let t=`${e.type??""} ${e.role??""} ${e.subrole??""}`.toLowerCase();return t.includes("button")||t.includes("menu")||t.includes("textfield")||t.includes("searchfield")||t.includes("checkbox")||t.includes("radio")||t.includes("switch")}(r))continue;let e=r;for(;e&&!n.has(e.index);)n.add(e.index),e="number"==typeof e.parentIndex?t.get(e.parentIndex):void 0}return 0===n.size?e:ug(e.filter(e=>n.has(e.index)))}(i)),"number"==typeof t.snapshotDepth&&(n=i,r=t.snapshotDepth,i=ug(n.filter(e=>(e.depth??0)<=r))),{...e,nodes:i}}function uw(e,t){let n=e5(en(e),t);if(!n)return[];let r=e.findIndex(e=>e.index===n.index);if(-1===r)return[];let i=e[r]?.depth??0,a=[];for(let t=r;t<e.length;t+=1){let n=e[t];if(!n)continue;let o=n.depth??0;if(t>r&&o<=i)break;a.push(n)}return ug(a,i)}function ug(e,t=0){let n=new Map;for(let[t,r]of e.entries())n.set(r.index,t);return e.map((e,r)=>({...e,index:r,depth:Math.max(0,(e.depth??0)-t),parentIndex:"number"==typeof e.parentIndex?n.get(e.parentIndex):void 0}))}function uy(e,t){if(!e||!e.trim().startsWith("@"))return{ok:!0,scope:e};if(!t?.snapshot)return tY("INVALID_ARGS","Ref scope requires an existing snapshot in session.");let n=er(e.trim());if(!n)return tY("INVALID_ARGS",`Invalid ref scope: ${e}`);let r=ei(t.snapshot.nodes,n),i=r?e8(r,t.snapshot.nodes):void 0;return i?{ok:!0,scope:i}:tY("COMMAND_FAILED",`Ref ${e} not found or has no label`)}let uI=nG(process.env.AGENT_DEVICE_IOS_DEVICE_READY_TIMEOUT_MS,15e3,1e3);async function uv(e){if("ios"===e.platform){if("simulator"===e.kind){let{ensureBootedSimulator:t}=await Promise.resolve(O);await t(e);return}if("device"===e.kind)return void await ub(e.id)}if("android"===e.platform){let{waitForAndroidBoot:t}=await Promise.resolve(C);await t(e.id)}}async function ub(e){let t=o.join(l.tmpdir(),`agent-device-ready-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),n=Math.max(1,Math.ceil(uI/1e3));try{let r=await _("xcrun",["devicectl","device","info","details","--device",e,"--json-output",t,"--timeout",String(n)],{allowFailure:!0,timeoutMs:uI+3e3}),i=String(r.stdout??""),a=String(r.stderr??""),o=await uA(t);if(0===r.exitCode){if(!o.parsed)throw new b("COMMAND_FAILED","iOS device readiness probe failed",{kind:"probe_inconclusive",deviceId:e,stdout:i,stderr:a,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 b("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 b("COMMAND_FAILED","iOS device is not ready for automation",{kind:"not_ready",deviceId:e,stdout:i,stderr:a,exitCode:r.exitCode,tunnelState:o?.tunnelState,hint:uS(i,a)})}catch(t){if(t instanceof b&&"COMMAND_FAILED"===t.code){if("not_ready"===("string"==typeof t.details?.kind?t.details.kind:""))throw t;let n=t.details??{},r=String(n.stdout??""),i=String(n.stderr??""),a=Number(n.timeoutMs??uI),o=`CoreDevice did not respond within ${a}ms. Keep the device unlocked and trusted, then retry; if it persists restart Xcode and the iOS device.`;throw new b("COMMAND_FAILED","iOS device readiness probe failed",{deviceId:e,cause:t.message,timeoutMs:a,stdout:r,stderr:i,hint:r||i?uS(r,i):o},t)}throw new b("COMMAND_FAILED","iOS device readiness probe failed",{deviceId:e,hint:"Reconnect the device, keep it unlocked, and retry."},t instanceof Error?t:void 0)}finally{await a.rm(t,{force:!0}).catch(()=>{})}}async function uA(e){try{let t=await a.readFile(e,"utf8"),n=JSON.parse(t),r=function(e){let t=e?.result;if(!t||"object"!=typeof t)return{};let n=t.connectionProperties?.tunnelState,r=t.device?.connectionProperties?.tunnelState,i="string"==typeof n?n:"string"==typeof r?r:void 0;return i?{tunnelState:i}:{}}(n);return{parsed:!0,tunnelState:r.tunnelState}}catch{return{parsed:!1}}}function uS(e,t){let n=iH(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.":iz)}async function ux(e,t,n){let r=e.get(t),i=r?.device??await lX(n??{});return r||await uv(i),{session:r,device:i}}async function u_(e,t,n){let r=!e&&"ios"===t.platform;try{return await n()}finally{r&&await oW(t.id)}}function uN(e,t,n,r){t&&e.recordAction(t,{command:n.command,positionals:n.positionals??[],flags:n.flags??{},result:r})}function uE(e){let{session:t,sessionName:n,device:r,snapshot:i,appBundleId:a}=e;return t?{...t,snapshot:i}:{name:n,device:r,createdAt:Date.now(),appBundleId:a,snapshot:i,actions:[]}}function uD(e){if(!e)return null;let t=Number(e);return Number.isFinite(t)?t:null}function uM(e){if(0===e.length)return null;let t=uD(e[0]);if(null!==t)return{kind:"sleep",durationMs:t};if("text"===e[0]){let t=uD(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=uD(e[e.length-1]);return{kind:"ref",rawRef:e[0],timeoutMs:t}}let n=uD(e[e.length-1]),r=eQ(null!==n?e.slice(0,-1):e.slice());if(r&&0===r.rest.length){let e=eZ(r.selectorExpression);if(e)return{kind:"selector",selector:e,selectorExpression:r.selectorExpression,timeoutMs:n}}return{kind:"text",text:(null!==n?e.slice(0,-1).join(" "):e.join(" ")).trim(),timeoutMs:n}}async function uC(e){let{parsed:t,req:n,sessionName:r,logPath:i,sessionStore:a,session:o,device:s}=e;if("sleep"===t.kind)return await new Promise(e=>setTimeout(e,t.durationMs)),uN(a,o,n,{waitedMs:t.durationMs}),{ok:!0,data:{waitedMs:t.durationMs}};if(!tH("wait",s))return tY("UNSUPPORTED_OPERATION","wait is not supported on this device");if("selector"===t.kind)return await uO({device:s,logPath:i,parsed:t,req:n,session:o,sessionName:r,sessionStore:a});let l=function(e,t){if("ref"===e.kind){if(!t?.snapshot)return tY("INVALID_ARGS","Ref wait requires an existing snapshot in session.");let n=er(e.rawRef);if(!n)return tY("INVALID_ARGS",`Invalid ref: ${e.rawRef}`);let r=ei(t.snapshot.nodes,n),i=r?e8(r,t.snapshot.nodes):void 0;return i?{ok:!0,text:i,timeoutMs:e.timeoutMs}:tY("COMMAND_FAILED",`Ref ${e.rawRef} not found or has no label`)}return e.text?{ok:!0,text:e.text,timeoutMs:e.timeoutMs}:tY("INVALID_ARGS","wait requires text")}(t,o);return l.ok?await uL({device:s,logPath:i,req:n,session:o,sessionStore:a,text:l.text,timeoutMs:l.timeoutMs}):l}async function uO(e){let{device:t,logPath:n,parsed:r,req:i,session:a,sessionName:o,sessionStore:s}=e,l=r.timeoutMs??1e4,u=Date.now();for(;Date.now()-u<l;){let e=tp((await uT({device:t,logPath:n,req:i,session:a,sessionName:o,sessionStore:s})).nodes,r.selector,{platform:t.platform});if(e)return uk(s,a,i,{selector:e.selector.raw,waitedMs:Date.now()-u});await new Promise(e=>setTimeout(e,300))}return tY("COMMAND_FAILED",`wait timed out for selector: ${r.selectorExpression}`)}async function uL(e){let{device:t,logPath:n,req:r,session:i,sessionStore:a,text:o,timeoutMs:s}=e,l=s??1e4,u=Date.now();for(;Date.now()-u<l;){if("macos"===t.platform&&i?.surface&&"app"!==i.surface){if(e5((await uT({device:t,logPath:n,req:r,session:i,sessionName:i?.name??r.session??"default",sessionStore:a})).nodes,o))return uk(a,i,r,{text:o,waitedMs:Date.now()-u})}else if(tF(t.platform)){let e=await oZ(t,{command:"findText",text:o,appBundleId:i?.appBundleId},{verbose:r.flags?.verbose,logPath:n,traceLogPath:i?.trace?.outPath,requestId:r.meta?.requestId});if(e?.found)return uN(a,i,r,{text:o,waitedMs:Date.now()-u}),{ok:!0,data:{text:o,waitedMs:Date.now()-u}}}else if("android"===t.platform&&e5((await uT({device:t,logPath:n,req:r,session:i,sessionName:i?.name??r.session??"default",sessionStore:a})).nodes,o))return uN(a,i,r,{text:o,waitedMs:Date.now()-u}),{ok:!0,data:{text:o,waitedMs:Date.now()-u}};await new Promise(e=>setTimeout(e,300))}return tY("COMMAND_FAILED",`wait timed out for text: ${o}`)}async function uT(e){let{device:t,logPath:n,req:r,session:i,sessionName:a,sessionStore:o}=e,{snapshot:s}=await uu({device:t,session:i,flags:{...r.flags,snapshotInteractiveOnly:!1,snapshotCompact:!1},outPath:r.flags?.out,logPath:n});return i&&(i.snapshot=s,o.set(a,i)),s}function uk(e,t,n,r){return uN(e,t,n,r),{ok:!0,data:r}}async function uR(e){let{req:t,logPath:n,sessionStore:r,session:i,device:a}=e,o=(t.positionals?.[0]??"get").toLowerCase(),s=i?"frontmost-app"===i.surface?{surface:"frontmost-app"}:{bundleId:i.appBundleId,surface:i.surface}:{};if(!tH("alert",a))return tY("UNSUPPORTED_OPERATION","alert is not supported on this device");if("macos"===a.platform){let e=async()=>await aI("wait"===o?"get":o,s);if("wait"===o){let n=uD(t.positionals?.[1])??1e4,a=Date.now();for(;Date.now()-a<n;){try{let n=await e();return uN(r,i,t,n),{ok:!0,data:n}}catch{}await new Promise(e=>setTimeout(e,300))}return tY("COMMAND_FAILED","alert wait timed out")}let n="accept"===o||"dismiss"===o?o:"get";if("accept"===n||"dismiss"===n){let e,a=Date.now();for(;Date.now()-a<2e3;){try{let e=await aI(n,s);return uN(r,i,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 new Promise(e=>setTimeout(e,300))}throw uP(e)}let a=await aI("get",s);return uN(r,i,t,a),{ok:!0,data:a}}if("wait"===o){let e=uD(t.positionals?.[1])??1e4,o=Date.now();for(;Date.now()-o<e;){try{let e=await oZ(a,{command:"alert",action:"get",appBundleId:i?.appBundleId},{verbose:t.flags?.verbose,logPath:n,traceLogPath:i?.trace?.outPath,requestId:t.meta?.requestId});return uN(r,i,t,e),{ok:!0,data:e}}catch{}await new Promise(e=>setTimeout(e,300))}return tY("COMMAND_FAILED","alert wait timed out")}let l="accept"===o||"dismiss"===o?o:"get",u={verbose:t.flags?.verbose,logPath:n,traceLogPath:i?.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 oZ(a,{command:"alert",action:l,appBundleId:i?.appBundleId},u);return uN(r,i,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 new Promise(e=>setTimeout(e,300))}throw uP(e)}let d=await oZ(a,{command:"alert",action:l,appBundleId:i?.appBundleId},u);return uN(r,i,t,d),{ok:!0,data:d}}function uP(e){if(!(e instanceof b))return e;let t=String(e.message??"").toLowerCase();return t.includes("alert not found")||t.includes("no alert")?new b(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}async function u$(e){let t,{req:n,logPath:r,sessionStore:i,session:a,device:o,parsed:s}=e,{setting:l,state:u,permissionTarget:d}=s;if(!tH("settings",o))return tY("UNSUPPORTED_OPERATION","settings is not supported on this device");if("macos"===o.platform&&"appearance"!==(t=l.trim().toLowerCase())&&"permission"!==t)return tY("INVALID_ARGS",B(l));let c=a?.appBundleId,p="permission"===l?[l,u,d??"",n.positionals?.[3]??"",c??""]:[l,u,c??""],f=await lK(o,"settings",p,n.flags?.out,{...ul(r,n.flags,c,a?.trace?.outPath)});return uN(i,a,n,f??{setting:l,state:u}),{ok:!0,data:f??{setting:l,state:u}}}let uF=new Set(["snapshot","diff","wait","alert","settings"]);async function uU(e){let{req:t,sessionName:n,logPath:r,sessionStore:i}=e,a=t.command;if(!uF.has(a))return null;if("snapshot"===a){let{session:e,device:a}=await ux(i,n,t.flags);if(!tH("snapshot",a))return tY("UNSUPPORTED_OPERATION","snapshot is not supported on this device");let o=uy(t.flags?.snapshotScope,e);return o.ok?await u_(e,a,async()=>{let s=await uu({device:a,session:e,flags:t.flags,outPath:t.flags?.out,logPath:r,snapshotScope:o.scope}),l=uV({capture:s,flags:t.flags,session:e}),u=function(e){var t;let{nodes:n,backend:r,snapshotRaw:i}=e;if(i||"macos-helper"===(t=r)||"linux-atspi"===t)return{partial:!1,visibleNodeCount:n.length,totalNodeCount:n.length,reasons:[]};let a=ef(n),o=new Set;return a.hiddenCount>0&&o.add("offscreen-nodes"),a.nodes.some(e=>e.hiddenContentAbove)&&o.add("scroll-hidden-above"),a.nodes.some(e=>e.hiddenContentBelow)&&o.add("scroll-hidden-below"),{partial:o.size>0,visibleNodeCount:a.nodes.length,totalNodeCount:n.length,reasons:[...o]}}({nodes:s.snapshot.nodes,backend:s.snapshot.backend,snapshotRaw:t.flags?.snapshotRaw}),d=uE({session:e,sessionName:n,device:a,snapshot:s.snapshot,appBundleId:e?.appBundleId});return uN(i,d,t,{nodes:s.snapshot.nodes.length,truncated:s.snapshot.truncated??!1}),i.set(n,d),{ok:!0,data:{nodes:s.snapshot.nodes,truncated:s.snapshot.truncated??!1,visibility:u,...l.length>0?{warnings:l}:{},appName:d.appBundleId?d.appName??d.appBundleId:void 0,appBundleId:d.appBundleId}}}):o}if("diff"===a)return t.positionals?.[0]!=="snapshot"?tY("INVALID_ARGS","diff currently supports only: diff snapshot"):await uG({req:t,sessionName:n,logPath:r,sessionStore:i});if("wait"===a){let{session:e,device:a}=await ux(i,n,t.flags),o=uM(t.positionals??[]);if(!o)return tY("INVALID_ARGS","wait requires a duration or text");let s=()=>uC({parsed:o,req:t,sessionName:n,logPath:r,sessionStore:i,session:e,device:a});return"sleep"===o.kind?await s():await u_(e,a,s)}if("alert"===a){let{session:e,device:a}=await ux(i,n,t.flags);return await u_(e,a,async()=>await uR({req:t,logPath:r,sessionStore:i,session:e,device:a}))}if("settings"===a){let e,a,o,s=(e=t.positionals?.[0]?.toLowerCase(),a=t.positionals?.[1]?.toLowerCase(),o=t.positionals?.[2]?.toLowerCase(),e&&a&&("permission"!==e||o)?{ok:!0,parsed:{setting:e,state:a,permissionTarget:o}}:tY("INVALID_ARGS",G));if(!s.ok)return s;let{session:l,device:u}=await ux(i,n,t.flags);return await u_(l,u,async()=>await u$({req:t,logPath:r,sessionStore:i,session:l,device:u,parsed:s.parsed}))}return null}function uV(e){let{capture:t,flags:n,session:r}=e,i=[],a=t.analysis,o=n?.snapshotInteractiveOnly===!0;"android"===t.snapshot.backend&&o&&0===t.snapshot.nodes.length&&a&&a.rawNodeCount>=12&&(i.push(`Interactive snapshot is empty after filtering ${a.rawNodeCount} raw Android nodes. Likely causes: depth too low, transient route change, or collector filtering.`),"number"==typeof n?.snapshotDepth&&a.maxDepth>=n.snapshotDepth+2&&i.push(`Interactive output is empty at depth ${n.snapshotDepth}; retry without -d.`));let s=r?.snapshot;return!t.freshness&&s&&Date.now()-s.createdAt<=2e3&&us(s.nodes.length,t.snapshot.nodes.length)&&i.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."),t.freshness?.staleAfterRetries&&"android"===t.snapshot.backend&&("stuck-route"===t.freshness.reason?i.push(`Recent ${t.freshness.action} was followed by a nearly identical snapshot after ${t.freshness.retryCount} automatic retr${1===t.freshness.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"===t.freshness.reason&&i.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.")),tw(i)}async function uG(e){let{req:t,sessionName:n,logPath:r,sessionStore:i}=e,{session:a,device:o}=await ux(i,n,t.flags);if(!tH("diff",o))return tY("UNSUPPORTED_OPERATION","diff is not supported on this device");let s=uy(t.flags?.snapshotScope,a);if(!s.ok)return s;let l=t.flags?.snapshotInteractiveOnly===!0;return await u_(a,o,async()=>{let e=await uu({device:o,session:a,flags:t.flags,outPath:t.flags?.out,logPath:r,snapshotScope:s.scope}),u=e.snapshot,d=uV({capture:e,flags:t.flags,session:a});if(!a?.snapshot){let e=function(e,t={}){return tX(e,t).length}(u.nodes,{flatten:l}),r=uE({session:a,sessionName:n,device:o,snapshot:u,appBundleId:a?.appBundleId});return uN(i,r,t,{mode:"snapshot",baselineInitialized:!0,summary:{additions:0,removals:0,unchanged:e}}),i.set(n,r),{ok:!0,data:{mode:"snapshot",baselineInitialized:!0,summary:{additions:0,removals:0,unchanged:e},lines:[],...d.length>0?{warnings:d}:{}}}}let c=function(e,t,n={}){let r=function(e,t){let n=e.length,r=t.length,i=n+r,a=new Map,o=[];a.set(1,0);for(let s=0;s<=i;s+=1){o.push(new Map(a));for(let i=-s;i<=s;i+=2){let l=i===-s||i!==s&&tK(a,i-1)<tK(a,i+1)?tK(a,i+1):tK(a,i-1)+1,u=l-i;for(;l<n&&u<r&&e[l].comparable===t[u].comparable;)l+=1,u+=1;if(a.set(i,l),l>=n&&u>=r)return function(e,t,n,r,i){let a=[],o=r,s=i;for(let r=e.length-1;r>=0;r-=1){let i=e[r],l=o-s,u=l===-r||l!==r&&tK(i,l-1)<tK(i,l+1)?l+1:l-1,d=tK(i,u),c=d-u;for(;o>d&&s>c;)a.push({kind:"unchanged",text:n[s-1].text}),o-=1,s-=1;if(0===r)break;o===d?(a.push({kind:"added",text:n[c].text}),s=c):(a.push({kind:"removed",text:t[d].text}),o=d)}return a.reverse(),a}(o,e,t,n,r)}}return[]}(tX(e,n),tX(t,n)),i={additions:0,removals:0,unchanged:0};for(let e of r)"added"===e.kind&&(i.additions+=1),"removed"===e.kind&&(i.removals+=1),"unchanged"===e.kind&&(i.unchanged+=1);return{summary:i,lines:r}}(a.snapshot.nodes,u.nodes,{flatten:l}),p={...a,snapshot:u};return uN(i,p,t,{mode:"snapshot",baselineInitialized:!1,summary:c.summary}),i.set(n,p),{ok:!0,data:{mode:"snapshot",baselineInitialized:!1,summary:c.summary,lines:c.lines,...d.length>0?{warnings:d}:{}}}})}export{ej as DEFAULT_BATCH_MAX_STEPS,iz as IOS_DEVICECTL_DEFAULT_HINT,oy as IOS_RUNNER_CONTAINER_BUNDLE_IDS,iP as IOS_SIMCTL_LIST_TIMEOUT_MS,j as SESSION_SURFACES,V as SETTINGS_USAGE_OVERRIDE,oz as abortAllIosRunnerSessions,t3 as adbArgs,r4 as appSwitcherAndroid,en as attachRefs,r1 as backAndroid,tS as buildAppIdentifiers,tx as buildDeviceIdentifiers,ef as buildMobileSnapshotPresentation,rT as buildScrollGesturePlan,tg as buildSelectorChainForNode,iJ as buildSimctlArgs,iX as buildSimctlArgsForDevice,J as buildSnapshotDisplayLines,um as buildSnapshotState,lI as buttonTag,uu as captureSnapshot,ud as captureSnapshotData,ea as centerOfRect,nU as classifyAndroidAppTarget,aj as clearRequestCanceled,rv as closeAndroidApp,sv as closeIosApp,eV as computeDaemonCodeSignature,ul as contextFromFlags,az as createRequestCanceledError,tP as decodePng,nP as waitForAndroidBoot,im as dismissAndroidKeyboard,lK as dispatchCommand,et as displayNodeLabel,es as distanceFromSafeViewportBand,t4 as ensureAdb,nR as ensureAndroidEmulatorBooted,uv as ensureDeviceReady,tY as errorResponse,eM as expandUserHomePath,tr as extractNodeReadText,tn as extractNodeText,r7 as fillAndroid,ti as findBestMatchesByLocator,lB as findBootableIosSimulator,tt as findNearestHittableAncestor,e5 as findNodeByLabel,ei as findNodeByRef,eI as findProjectRoot,tp as findSelectorChainMatch,r9 as focusAndroid,nV as formatAndroidInstalledPackageRequiredMessage,tf as formatSelectorFailure,X as formatSnapshotLine,ur as getActiveAndroidSnapshotFreshness,rc as getAndroidAppState,ip as getAndroidKeyboardState,ia as getAndroidScreenSize,ly as getClickButtonValidationError,aW as getRequestSignal,oB as getRunnerSessionSnapshot,uU as handleSnapshotCommands,r2 as homeAndroid,rd as inferAndroidAppName,th as inferFillText,rO as installAndroidApp,rC as installAndroidInstallablePathAndResolvePackageName,sA as installIosApp,sx as installIosInstallablePath,ex as isAgentDeviceDaemonProcess,tF as isApplePlatform,tH as isCommandSupportedOnDevice,t6 as isDeepLinkTarget,ne as isEnvTruthy,te as isFillableType,ua as isNavigationSensitiveAction,tu as isNodeEditable,tl as isNodeVisible,em as isNodeVisibleInEffectiveViewport,eb as isProcessAlive,aq as isRequestCanceled,ro as listAndroidApps,nM as listAndroidDevices,lH as listAppleDevices,sM as listIosApps,iq as listIosDeviceApps,iW as listIosDeviceProcesses,r5 as longPressAndroid,un as markAndroidSnapshotFreshness,aB as markRequestCanceled,tU as matchesPlatformSelector,t$ as normalizePlatformSelector,er as normalizeRef,eR as normalizeTenantId,e7 as normalizeType,rf as openAndroidApp,rI as openAndroidDevice,sy as openIosApp,sI as openIosDevice,ez as parseBatchStepsJson,lD as parseDeviceRotation,eY as parseSelectorChain,nf as parseSerialAllowlist,q as parseSessionSurface,uD as parseTimeout,uM as parseWaitArgs,i4 as parseXmlDocumentSync,eu as pickLargestRect,n9 as prepareAndroidInstallArtifact,i9 as prepareIosInstallArtifact,rQ as pressAndroid,e9 as pruneGroupNodes,iM as pushAndroidNotification,sE as pushIosNotification,ih as readAndroidClipboardText,id as readAndroidTextAtPoint,tA as readCommandMessage,i6 as readInfoPlistString,s_ as readIosClipboardText,eS as readProcessCommand,eA as readProcessStartTime,ey as readVersion,el as rect_visibility_containsPoint,aG as registerRequestAbort,rL as reinstallAndroidApp,sS as reinstallIosApp,ra as resolveAndroidApp,nm as resolveAndroidSerialAllowlist,tV as resolveAppleSimulatorSetPathForSelector,lg as resolveClickButton,eU as resolveDaemonCodeSignature,eO as resolveDaemonPaths,eL as resolveDaemonServerMode,eT as resolveDaemonTransportPreference,tM as resolveDeployResultTarget,eh as resolveEffectiveViewportRect,aw as resolveFrontmostMacOsApp,tO as resolveInstallFromSourceResultTarget,sg as resolveIosApp,t9 as resolveIosDeviceDeepLinkBundleId,iH as resolveIosDevicectlHint,np as resolveIosSimulatorDeviceSetPath,l_ as resolvePayloadInput,e8 as resolveRefLabel,aV as resolveRequestTrackingId,tc as resolveSelectorChain,ek as resolveSessionIsolationMode,lX as resolveTargetDevice,nG as resolveTimeoutMs,eC as resolveUserPath,eo as resolveViewportRect,r3 as rotateAndroid,oZ as runIosRunnerCommand,aI as runMacOsAlertAction,iO as screenshotAndroid,sn as screenshotIos,ir as scrollAndroid,ii as scrollIntoViewAndroid,tk as serializeCloseResult,tC as serializeDeployResult,tE as serializeDevice,tD as serializeEnsureSimulatorResult,tL as serializeInstallFromSourceResult,tT as serializeOpenResult,tN as serializeSessionListEntry,tR as serializeSnapshotResult,iA as setAndroidSetting,sD as setIosSetting,i1 as shutdownSimulator,i0 as ensureBootedSimulator,rz as snapshotAndroid,e0 as splitIsSelectorArgs,eQ as splitSelectorFromArgs,oH as stopAllIosRunnerSessions,oW as stopIosRunnerSession,eE as stopProcessForTakeover,tv as successText,r0 as swipeAndroid,eZ as tryParseSelectorChain,r8 as typeAndroid,tw as uniqueStrings,eH as validateAndNormalizeBatchSteps,eN as waitForProcessExit,oa as withKeyedLock,tb as withSuccessText,iw as writeAndroidClipboardText,sN as writeIosClipboardText};