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.
@@ -0,0 +1,38 @@
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{URL as s,fileURLToPath as l}from"node:url";import{AsyncLocalStorage as u}from"node:async_hooks";import d,{createHash as c}from"node:crypto";import p,{hostname as f}from"node:os";import{PNG as m}from"pngjs";import h from"node:dns/promises";import w from"node:net";import g from"node:fs/promises";import{TextDecoder as y}from"node:util";import{XMLParser as v}from"fast-xml-parser";import{resolveExecutableOverridePath as I,isExecutablePath as b,runCmdStreaming as A,asAppError as S,runCmdDetached as x,runCmdBackground as _,AppError as N,runCmd as D,runCmdSync as E,resolveFileOverridePath as C,whichCmd as M,redactDiagnosticData as O}from"./818.js";var L={};n.r(L),n.d(L,{ensureAndroidEmulatorBooted:()=>rd,listAndroidDevices:()=>ri,waitForAndroidBoot:()=>rc});var T={};n.r(T),n.d(T,{TM:()=>sY,ensureBootedSimulator:()=>ab,installIosApp:()=>sQ,installIosInstallablePath:()=>s1,listIosApps:()=>s8,L5:()=>sX,IJ:()=>sK,TJ:()=>s4,J7:()=>s2,reinstallIosApp:()=>s0,resolveIosApp:()=>sJ,kc:()=>sT,Cm:()=>s5,ap:()=>s3});let k="<wifi|airplane|location> <on|off>",R="appearance <light|dark|toggle>",P="faceid <match|nonmatch|enroll|unenroll>",$="touchid <match|nonmatch|enroll|unenroll>",F="fingerprint <match|nonmatch>",U="permission <grant|deny|reset> <camera|microphone|photos|contacts|contacts-limited|notifications|calendar|location|location-always|media-library|motion|reminders|siri> [full|limited]",G="permission <grant|reset> <accessibility|screen-recording|input-monitoring>",V=`macOS supports only settings ${R} and settings ${G}. wifi|airplane|location remain unsupported on macOS.`,B=`settings ${k} | settings ${R} | settings ${P} | settings ${$} | settings ${F} | settings ${U} | settings ${G}`,j=`settings requires ${k}, ${R}, ${P}, ${$}, ${F}, ${U}, or ${G}`;function q(e){return`Unsupported macOS setting: ${e}. ${V}`}let W=["app","frontmost-app","desktop","menubar"];function z(e){let t=e?.trim().toLowerCase();if("app"===t||"frontmost-app"===t||"desktop"===t||"menubar"===t)return t;throw new N("INVALID_ARGS",`Invalid surface: ${e}. Use ${W.join("|")}.`)}function H(e){var t;let n,r=J(e.label),i=J(e.value),a=J(e.identifier),o=(t=a)&&!/^[\w.]+:id\/[\w.-]+$/i.test(t)&&!/^_?NS:\d+$/i.test(t)?a:"";return(n=X(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 J(e){return"string"==typeof e?e.trim():""}function X(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 K(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=Q(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:Y(i,s,!1,o,t)})}return r}function Y(e,t,n,r,i={}){var a,o,s,l,u;let d,c,p=r??Q(e.type??"Element"),f=(d=H(e),{text:d,isLargeSurface:c=function(e,t){if("text-view"===t||"text-field"===t||"search"===t)return!0;let n=X(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=J(e.label);if(r&&r!==n)return r;let i=J(e.identifier);if(i&&!et(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)||Z(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"),ee(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 Z(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(ee(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||et(s)&&("group"===t||"image"===t||"list"===t||"collection"===t)?"":s}function Q(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 ee(e){return"text-field"===e||"text-view"===e||"search"===e}function et(e){return/^[\w.]+:id\/[\w.-]+$/i.test(e)}function en(e){return new Map(e.map(e=>[e.index,e]))}function er(e){return e.label?.trim()||e.value?.trim()||e.identifier?.trim()||""}function ei(e){return e.map((e,t)=>({...e,ref:`e${t+1}`}))}function ea(e){let t=e.trim();return t.startsWith("@")?t.slice(1)||null:t.startsWith("e")?t:null}function eo(e,t){return e.find(e=>e.ref===t)??null}function es(e){return{x:Math.round(e.x+e.width/2),y:Math.round(e.y+e.height/2)}}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=en(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=er(r);!e||t.has(e)||(t.add(e),n.push(e))}return n})(t).slice(0,3).map(e=>`"${e}"`),i=1===t.length?"interactive item":"interactive items",a=n.length>0?`: ${n.join(", ")}`:"";return[`[off-screen ${e}] ${t.length} ${i}${a}`]})}(r.filter(e=>!i.coveredNodeIndexes.has(e.index)&&function(e){if(!0===e.hittable)return!0;let t=(e.type??"").toLowerCase();return t.includes("button")||t.includes("link")||t.includes("textfield")||t.includes("edittext")||t.includes("searchfield")||t.includes("checkbox")||t.includes("radio")||t.includes("switch")||t.includes("menuitem")||!!er(e)}(e)),e,t)}}function em(e,t,n=en(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=en(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||function(e,t){let n=es(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}(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=ev();return JSON.parse(r.readFileSync(o.join(e,"package.json"),"utf8")).version??"0.0.0"}catch{return"0.0.0"}}function ev(){let e=o.dirname(l(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 eI=new u;function eb(){return d.randomBytes(8).toString("hex")}async function eA(e,t){let n={...e,diagnosticId:`${Date.now().toString(36)}-${d.randomBytes(4).toString("hex")}`,events:[]};return await eI.run(n,t)}function eS(){let e=eI.getStore();return e?{diagnosticId:e.diagnosticId,requestId:e.requestId,session:e.session,command:e.command,debug:e.debug}:{}}function ex(e){let t=eI.getStore();if(!t)return;let n={ts:new Date().toISOString(),level:e.level??"info",phase:e.phase,session:t.session,requestId:t.requestId,command:t.command,durationMs:e.durationMs,data:e.data?O(e.data):void 0};if(t.events.push(n),!t.debug)return;let i=`[agent-device][diag] ${JSON.stringify(n)}
2
+ `;try{t.logPath&&r.appendFile(t.logPath,i,()=>{}),t.traceLogPath&&r.appendFile(t.traceLogPath,i,()=>{}),t.logPath||t.traceLogPath||process.stderr.write(i)}catch{}}async function e_(e,t,n){let r=Date.now();try{let i=await t();return ex({level:"info",phase:e,durationMs:Date.now()-r,data:n}),i}catch(t){throw ex({level:"error",phase:e,durationMs:Date.now()-r,data:{...n??{},error:t instanceof Error?t.message:String(t)}}),t}}function eN(e={}){let t=eI.getStore();if(!t||!e.force&&!t.debug||0===t.events.length)return null;try{let e=(t.session??"default").replace(/[^a-zA-Z0-9._-]/g,"_"),n=new Date().toISOString().slice(0,10),i=o.join(p.homedir(),".agent-device","logs",e,n);r.mkdirSync(i,{recursive:!0});let a=new Date().toISOString().replace(/[:.]/g,"-"),s=o.join(i,`${a}-${t.diagnosticId}.ndjson`),l=t.events.map(e=>JSON.stringify(O(e)));return r.writeFileSync(s,`${l.join("\n")}
3
+ `),t.events=[],s}catch{return null}}let eD=[/(^|[/\s"'=])dist\/src\/daemon\.js($|[\s"'])/,/(^|[/\s"'=])src\/daemon\.ts($|[\s"'])/];function eE(e){if(!Number.isInteger(e)||e<=0)return!1;try{return process.kill(e,0),!0}catch(e){return"EPERM"===e.code}}function eC(e){if(!Number.isInteger(e)||e<=0)return null;try{let t=E("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 eM(e){if(!Number.isInteger(e)||e<=0)return null;try{let t=E("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 eO(e,t){let n;if(!eE(e))return!1;if(t){let n=eC(e);if(!n||n!==t)return!1}let r=eM(e);return!!r&&!!(n=r.toLowerCase().replaceAll("\\","/")).includes("agent-device")&&eD.some(e=>e.test(n))}function eL(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 eT(e,t){if(!eE(e))return!0;let n=Date.now();for(;Date.now()-n<t;)if(await new Promise(e=>setTimeout(e,50)),!eE(e))return!0;return!eE(e)}async function ek(e,t){!eO(e,t.expectedStartTime)||!eL(e,"SIGTERM")||await eT(e,t.termTimeoutMs)||eL(e,"SIGKILL")&&await eT(e,t.killTimeoutMs)}function eR(e){return e?.HOME?.trim()||p.homedir()}function eP(e,t={}){return"~"===e?eR(t.env):e.startsWith("~/")?o.join(eR(t.env),e.slice(2)):e}function e$(e,t={}){let n=eP(e,t);return o.isAbsolute(n)?n:o.resolve(t.cwd??process.cwd(),n)}function eF(e){let t,n=(t=(e??"").trim())?e$(t):o.join(eP("~"),".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 eU(e){let t=(e??"").trim().toLowerCase();return"http"===t?"http":"dual"===t?"dual":"socket"}function eG(e){let t=(e??"").trim().toLowerCase();return"auto"===t?"auto":"socket"===t?"socket":"http"===t?"http":"auto"}function eV(e){return"tenant"===(e??"").trim().toLowerCase()?"tenant":"none"}function eB(e){if(!e)return;let t=e.trim();if(t&&/^[a-zA-Z0-9._-]{1,128}$/.test(t))return t}let ej=/(?:^|[^\w$.])(?:import|export)\s+(?:type\s+)?(?:[^'"`]*?\s+from\s+)?['"]([^'"]+)['"]/gm,eq=/import\(\s*['"]([^'"]+)['"]\s*\)/gm,eW=[".ts",".tsx",".js",".jsx",".mjs",".cjs"];function ez(){let e=process.argv[1];return e?eH(e):"unknown"}function eH(e,t=ev()){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 eJ(e,ej,t),eJ(e,eq,t),[...t]}(u)){let n=function(e,t){let n=o.resolve(o.dirname(e),t),r=eX(n);if(r)return r;for(let e of eW){let t=eX(`${n}${e}`);if(t)return t}for(let e of eW){let t=eX(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 eJ(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 eX(e){try{return r.statSync(e).isFile()?e:null}catch{return null}}let eK=100,eY=new Set(["batch","replay"]),eZ=new Set(["command","positionals","flags","runtime"]);function eQ(e){let t;try{t=JSON.parse(e)}catch{throw new N("INVALID_ARGS","Batch steps must be valid JSON.")}if(!Array.isArray(t)||0===t.length)throw new N("INVALID_ARGS","Batch steps must be a non-empty JSON array.");return t}function e0(e,t){if(!Array.isArray(e)||0===e.length)throw new N("INVALID_ARGS","batch requires a non-empty batchSteps array.");if(e.length>t)throw new N("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 N("INVALID_ARGS",`Invalid batch step at index ${t}.`);let i=Object.keys(r).filter(e=>!eZ.has(e));if(i.length>0){let e=i.map(e=>`"${e}"`).join(", ");throw new N("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 N("INVALID_ARGS",`Batch step ${t+1} requires command.`);if(eY.has(a))throw new N("INVALID_ARGS",`Batch step ${t+1} cannot run ${a}.`);if(void 0!==r.positionals&&!Array.isArray(r.positionals))throw new N("INVALID_ARGS",`Batch step ${t+1} positionals must be an array.`);let o=r.positionals??[];if(o.some(e=>"string"!=typeof e))throw new N("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 N("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 N("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 e1=new Set(["id","role","text","label","value","appname","windowtitle"]),e2=new Set(["visible","hidden","editable","selected","enabled","hittable"]),e3=new Set([...e1,...e2]);function e4(e){let t=e.trim();if(!t)throw new N("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)&&!tt(e,i)){r=e7(r,a),n+=a;continue}if(!r&&"|"===a&&"|"===e[i+1]){let r=n.trim();if(!r)throw new N("INVALID_ARGS",`Invalid selector fallback expression: ${e}`);t.push(r),n="",i+=1;continue}n+=a}let i=n.trim();if(!i)throw new N("INVALID_ARGS",`Invalid selector fallback expression: ${e}`);return t.push(i),t}(t);if(0===n.length)throw new N("INVALID_ARGS","Selector expression cannot be empty");return{raw:t,selectors:n.map(e=>(function(e){let t=e.trim();if(!t)throw new N("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)&&!tt(e,i)){r=e7(r,a),n+=a;continue}if(!r&&/\s/.test(a)){n.trim()&&t.push(n.trim()),n="";continue}n+=a}if(r)throw new N("INVALID_ARGS",`Unclosed quote in selector: ${e}`);return n.trim()&&t.push(n.trim()),t}(t);if(0===n.length)throw new N("INVALID_ARGS",`Invalid selector segment: ${e}`);return{raw:t,terms:n.map(e9)}})(e))}}function e5(e){try{return e4(e)}catch{return null}}function e8(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 e3.has(e)}return e3.has(t.toLowerCase())}(e[r]);){r+=1;let t=e.slice(0,r).join(" ").trim();t&&e5(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 e6(e){let t=e[0]??"",n=e8(e.slice(1),{preferTrailingValue:"text"===t});return{predicate:t,split:n}}function e9(e){let t=e.trim();if(!t)throw new N("INVALID_ARGS","Empty selector term");let n=t.indexOf("=");if(-1===n){let n=t.toLowerCase();if(!e2.has(n))throw new N("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(!e3.has(r))throw new N("INVALID_ARGS",`Unknown selector key: ${r}`);if(!i)throw new N("INVALID_ARGS",`Missing selector value for key: ${r}`);if(e2.has(r)){let e,t="true"===(e=te(i).toLowerCase())||"false"!==e&&null;if(null===t)throw new N("INVALID_ARGS",`Invalid boolean value for ${r}: ${i}`);return{key:r,value:t}}return{key:r,value:te(i)}}function e7(e,t){return e?e===t?null:e:t}function te(e){let t=e.trim();return t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'")?t.slice(1,-1).replace(/\\(["'])/g,"$1"):t}function tt(e,t){let n=0;for(let r=t-1;r>=0&&"\\"===e[r];r-=1)n+=1;return n%2==1}function tn(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 tr(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&&ti(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||!ti(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&&ti(n)?n:void 0)}function ti(e){let t=e.trim();return!(!t||/^(true|false)$/i.test(t)||/^\d+$/.test(t))}function ta(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=to(r.type??""),a=[r.label,r.value,r.identifier].map(e=>"string"==typeof e?e.trim():"").find(e=>e&&e.length>0),o=!!a&&ti(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 to(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 ts(e,t){let n=to(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 tl(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 tu(e){return[e.label,e.value,e.identifier].map(e=>"string"==typeof e?e.trim():"").filter(e=>e.length>0)[0]??""}function td(e){return H(e)}function tc(e,t,n,r={}){let i=tf(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 tp(e.label,n);case"value":return tp(e.value,n);case"id":return tp(e.identifier,n);default:return Math.max(tp(e.label,n),tp(e.value,n),tp(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 tp(e,t){let n=tf(e??"");return n?n===t?2:+!!n.includes(t):0}function tf(e){return e.trim().toLowerCase().replace(/\s+/g," ")}function tm(e){let t="any",n=0;["text","label","value","role","id"].includes(e[0])&&(t=e[0],n=1);let r=e[n]??"",i=e.slice(n+1);if(0===i.length)return{locator:t,query:r,action:"click"};let a=i[0].toLowerCase();if("get"===a){let e=i[1]?.toLowerCase();if("text"===e)return{locator:t,query:r,action:"get_text"};if("attrs"===e)return{locator:t,query:r,action:"get_attrs"};throw new N("INVALID_ARGS","find get only supports text or attrs")}if("wait"===a)return{locator:t,query:r,action:"wait",timeoutMs:function(e){if(!e)return null;let t=Number(e);return Number.isFinite(t)?t:null}(i[1])??void 0};if("exists"===a)return{locator:t,query:r,action:"exists"};if("click"===a)return{locator:t,query:r,action:"click"};if("focus"===a)return{locator:t,query:r,action:"focus"};if("fill"===a)return{locator:t,query:r,action:"fill",value:i.slice(1).join(" ")};if("type"===a)return{locator:t,query:r,action:"type",value:i.slice(1).join(" ")};throw new N("INVALID_ARGS",`Unsupported find action: ${i[0]}`)}function th(e,t,n){return t.terms.every(t=>(function(e,t,n){switch(t.key){case"id":return ty(e.identifier,String(t.value));case"role":return ty(to(e.type??""),String(t.value));case"label":return ty(e.label,String(t.value));case"value":return ty(e.value,String(t.value));case"text":return ty(tu(e),String(t.value));case"appname":return ty(e.appName,String(t.value));case"windowtitle":return ty(e.windowTitle,String(t.value));case"visible":return tw(e)===!!t.value;case"hidden":return!tw(e)==!!t.value;case"editable":return tg(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 tw(e){return!0===e.hittable||!!e.rect&&e.rect.width>0&&e.rect.height>0}function tg(e,t){return ts(e.type??"",t)&&!1!==e.enabled}function ty(e,t){return tf(e??"")===tf(t)}function tv(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||!th(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=tA(e),a=tA(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 tI(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)&&th(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 tb(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 tA(e){return e.rect?e.rect.width*e.rect.height:1/0}function tS(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 tx(e){let t=new Set,n=[];for(let r of e)t.has(r)||(t.add(r),n.push(r));return n}function t_(e,t,n={}){let r=[],i=to(e.type??""),a=tD(e.identifier),o=tD(e.label),s=tD(e.value),l=tD(tu(e)),u="fill"===n.action;a&&r.push(`id=${tN(a)}`),i&&o&&r.push(u?`role=${tN(i)} label=${tN(o)} editable=true`:`role=${tN(i)} label=${tN(o)}`),o&&r.push(u?`label=${tN(o)} editable=true`:`label=${tN(o)}`),s&&r.push(u?`value=${tN(s)} editable=true`:`value=${tN(s)}`),l&&l!==o&&l!==s&&r.push(u?`text=${tN(l)} editable=true`:`text=${tN(l)}`),i&&u&&!r.some(e=>e.includes("editable=true"))&&r.push(`role=${tN(i)} editable=true`);let d=tx(r);return 0===d.length&&i&&d.push(u?`role=${tN(i)} editable=true`:`role=${tN(i)}`),0===d.length&&tw(e)&&d.push("visible=true"),d}function tN(e){return JSON.stringify(e)}function tD(e){if(!e)return null;let t=e.trim();return t||null}function tE(e){return e?{message:e}:{}}function tC(e,t){return t?{...e,message:t}:e}function tM(e){return"string"==typeof e?.message&&e.message.length>0?e.message:null}function tO(e){let t=e.appId??e.bundleId??e.packageName;return{session:e.session,appId:t,appBundleId:e.bundleId,package:e.packageName}}function tL(e,t,n){return{deviceId:t,deviceName:n,..."android"===e?{serial:t}:"ios"===e?{udid:t}:{}}}function tT(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 tk(e){return{name:e.name,...tT(e.device,{includeAndroidSerial:!1}),createdAt:e.createdAt}}function tR(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 tP(e){let t=e.created?"Created":"Reused",n=e.booted?" (booted)":"";return tC({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 t$(e){return e.bundleId??e.package??e.app}function tF(e){return tC({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: ${t$(e)}`)}function tU(e){return e.appName??e.bundleId??e.packageName??e.launchTarget}function tG(e){return tC({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: ${tU(e)}`)}function tV(e){let t=e.appName??e.appBundleId??e.session;return tC({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?tT(e.device):{}},t?`Opened: ${t}`:"Opened")}function tB(e){return{session:e.session,...e.shutdown?{shutdown:e.shutdown}:{},...tE(e.session?`Closed: ${e.session}`:"Closed")}}function tj(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}:{}}}let tq=["emulator","platform-tools",o.join("cmdline-tools","latest","bin"),o.join("cmdline-tools","tools","bin")];function tW(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 tz(e=process.env){let t=e.ANDROID_SDK_ROOT?.trim(),n=e.ANDROID_HOME?.trim(),r=e.HOME?.trim()||p.homedir();return tW([t??"",n??"",r?o.join(r,"Android","Sdk"):""])}async function tH(e){try{return await a.access(e,a.constants.X_OK),!0}catch{return!1}}async function tJ(e=process.env){let t,n=[];for(let r of tz(e)){let e=[];for(let t of tq){let n=o.join(r,t);await tH(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=tW([...n,...r]).join(o.delimiter)}function tX(e,t){return["-s",e.id,...t]}async function tK(){if(await tJ(),!await M("adb"))throw new N("TOOL_MISSING","adb not found in PATH")}function tY(e,t){let n=`${e}
4
+ ${t}`.toLowerCase();return n.includes("no shell command implementation")||n.includes("unknown command")}async function tZ(e){await new Promise(t=>setTimeout(t,e))}let tQ=/\.(?:apk|aab)$/i,t0=/^[A-Za-z_][\w]*(\.[A-Za-z_][\w]*)+$/;function t1(e){var t,n;let r=e.trim();return 0===r.length?"other":tQ.test(r)?r.includes("/")||r.includes("\\")||r.startsWith(".")||r.startsWith("~")||(t=r,!t0.test(t))?"binary":"package":(n=r,t0.test(n))?"package":"other"}function t2(e){return`Android runtime hints require an installed package name, not "${e}". Install or reinstall the app first, then relaunch by package.`}let t3=["AGENT_DEVICE_IOS_SIMULATOR_DEVICE_SET","IOS_SIMULATOR_DEVICE_SET"],t4=["AGENT_DEVICE_ANDROID_DEVICE_ALLOWLIST","ANDROID_DEVICE_ALLOWLIST"];function t5(e){return e?.trim()||void 0}function t8(e,t){for(let n of e){let e=t5(t[n]);if(e)return e}}function t6(e,t=process.env){return t5(e)??t8(t3,t)}function t9(e){return new Set(e.split(/[\s,]+/).map(e=>e.trim()).filter(Boolean))}function t7(e,t=process.env){let n=t5(e)??t8(t4,t);if(n)return t9(n)}function ne(e,t={}){let n=t6(t.simulatorSetPath);return n?["simctl","--set",n,...e]:["simctl",...e]}function nt(e,t){return"ios"!==e.platform||"simulator"!==e.kind?["simctl",...t]:ne(t,{simulatorSetPath:e.simulatorSetPath})}let nn="shared_prefs/ReactNativeDevPrefs.xml",nr="debug_http_host",ni="dev_server_https",na="RCT_jsLocation",no="RCT_packager_scheme",ns="React Native runtime hints require adb run-as access to the app sandbox. Verify the app is debuggable and the selected package/device are correct.",nl='<?xml version="1.0" encoding="utf-8" standalone="yes" ?>\n<map>\n</map>\n';function nu(e){return void 0!==nd(e)}function nd(e){if(!e)return;let t=nA(e.metroHost),n=nx(e.metroPort),r="http",i=nA(e.bundleUrl);if(i){var a;let e;try{e=new s(i)}catch(e){throw new N("INVALID_ARGS",`Invalid runtime bundle URL: ${i}`,{},e)}("http:"===e.protocol||"https:"===e.protocol)&&(t??=nA(e.hostname),n??=nx(e.port.length>0?Number(e.port):"https:"===(a=e.protocol)?443:"http:"===a?80:void 0),r="https:"===e.protocol?"https":"http")}if(t&&n)return{host:t,port:n,scheme:r}}async function nc(e){let{device:t,appId:n,runtime:r}=e;if(!n)return;let i=nd(r);if(i){if("android"===t.platform)return void await nf(t,n,i);"ios"===t.platform&&"simulator"===t.kind&&await ng(t,n,i)}}async function np(e){let{device:t,appId:n}=e;if(n){if("android"===t.platform)return void await nm(t,n);"ios"===t.platform&&"simulator"===t.kind&&await ny(t,n)}}async function nf(e,t,n){var r,i,a,o,s,l;let u,d;nS(t);let c=(r=await nh(e,t),i=nr,a=`${n.host}:${n.port}`,u=` <string name="${n_(i)}">${n_(a)}</string>`,nI(nb(r,i),u));o=c,s=ni,l="https"===n.scheme,d=` <boolean name="${n_(s)}" value="${l?"true":"false"}" />`,c=nI(nb(o,s),d),await nw(e,t,c)}async function nm(e,t){nS(t);let n=await nh(e,t),r=nb(n,nr),i=nb(r,ni);i!==n&&await nw(e,t,i)}async function nh(e,t){let n=await D("adb",tX(e,["shell","run-as",t,"cat",nn]),{allowFailure:!0});return 0!==n.exitCode?nl:nv(n.stdout)}async function nw(e,t,n){let r=tX(e,["shell","run-as",t,"id"]),i=await D("adb",r,{allowFailure:!0});if(0!==i.exitCode){let e=nN(i.stdout,i.stderr);throw new N("COMMAND_FAILED",e?`Failed to access Android app sandbox for ${t}`:`Failed to probe Android app sandbox for ${t}`,{package:t,cmd:"adb",args:r,stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode,hint:e?ns:"adb shell run-as probe failed. Check adb connectivity and that the device is reachable. Inspect stderr/details for more information."})}try{await D("adb",tX(e,["shell","run-as",t,"mkdir","-p","shared_prefs"])),await D("adb",tX(e,["shell","run-as",t,"tee",nn]),{stdin:n.trimEnd()})}catch(r){let e=S(r);if("TOOL_MISSING"===e.code)throw e;let n=nN("string"==typeof e.details?.stdout?e.details.stdout:"","string"==typeof e.details?.stderr?e.details.stderr:"");throw new N("COMMAND_FAILED",n?`Failed to access Android app sandbox for ${t}`:`Failed to write Android runtime hints for ${t}`,{...e.details??{},package:t,cmd:"adb",phase:"write-runtime-hints",hint:n?ns:"adb run-as succeeded, but writing ReactNativeDevPrefs.xml failed. Inspect stderr/details for the failing shell command."},e)}}async function ng(e,t,n){await D("xcrun",nt(e,["spawn",e.id,"defaults","write",t,na,"-string",`${n.host}:${n.port}`])),await D("xcrun",nt(e,["spawn",e.id,"defaults","write",t,no,"-string",n.scheme]))}async function ny(e,t){await D("xcrun",nt(e,["spawn",e.id,"defaults","delete",t,na]),{allowFailure:!0}),await D("xcrun",nt(e,["spawn",e.id,"defaults","delete",t,no]),{allowFailure:!0})}function nv(e){let t=e.trim();return t.includes("<map")&&t.includes("</map>")?`${t}
5
+ `:nl}function nI(e,t){return nv(e).replace("</map>",`${t}
6
+ </map>`)}function nb(e,t){let n=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return nv(e).replace(RegExp(`^\\s*<string name="${n}">[\\s\\S]*?<\\/string>\\n?`,"m"),"").replace(RegExp(`^\\s*<boolean name="${n}" value="(?:true|false)"\\s*\\/?>\\n?`,"m"),"")}function nA(e){let t=e?.trim();return t&&t.length>0?t:void 0}function nS(e){if("binary"!==t1(e))return;let t=t2(e);throw new N("INVALID_ARGS",t,{package:e,hint:t})}function nx(e){if(Number.isInteger(e)&&!(e<=0)&&!(e>65535))return e}function n_(e){return e.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&apos;")}function nN(e,t){let n=`${e}
7
+ ${t}`.toLowerCase();return["run-as: package not debuggable","run-as: permission denied","run-as: package is unknown","run-as: unknown package","is unknown","is not an application","could not set capabilities"].some(e=>n.includes(e))}function nD(e,t){try{return m.sync.read(e)}catch(e){throw new N("COMMAND_FAILED",`Failed to decode ${t} as PNG`,{label:t,reason:e instanceof Error?e.message:String(e)})}}function nE(e){return e}function nC(e){return"apple"===e||"ios"===e||"macos"===e}function nM(e,t){return!t||("apple"===t?nC(e):e===t)}function nO(e){let{simulatorSetPath:t,platform:n,target:r}=e;if(t&&"macos"!==n&&"desktop"!==r)return t}async function nL(e,t,n={}){let r=e,i=e=>e.toLowerCase().replace(/_/g," ").replace(/\s+/g," ").trim();if(t.platform&&(r=r.filter(e=>nM(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&&nC(e.platform));if(!e)throw new N("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 N("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 N("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 N("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:
8
+ xcrun simctl --set "${e}" create "iPhone 16" com.apple.CoreSimulator.SimDeviceType.iPhone-16 com.apple.CoreSimulator.SimRuntime.iOS-18-0`,selector:t});throw new N("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 nT=e=>"macos"!==e.platform,nk=e=>"macos"===e.platform||"simulator"===e.kind,nR={device:!0},nP={},n$={alert:{apple:{simulator:!0,device:!0},android:{},linux:nP,supports:nk},pinch:{apple:{simulator:!0,device:!0},android:{},linux:nP,supports:nk},"app-switcher":{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:nP,supports:nT},apps:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:nP},back:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:nR},boot:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:nP,supports:nT},click:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:nR},clipboard:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:nR,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:nP,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:nR},fill:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:nR},diff:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:nR},find:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:nR},focus:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:nR},get:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:nR},is:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:nR},home:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:nR,supports:nT},logs:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:nP},network:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:nP},longpress:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:nR},open:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:nR},perf:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:nP},install:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:nP,supports:nT},"install-from-source":{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:nP,supports:nT},reinstall:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:nP,supports:nT},press:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:nR},push:{apple:{simulator:!0},android:{emulator:!0,device:!0,unknown:!0},linux:nP,supports:nT},record:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:nP},rotate:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:nP,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:nR},scroll:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:nR},swipe:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:nR},settings:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:nP,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:nR},"trigger-app-event":{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:nP},type:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:nR},wait:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:nR}};function nF(e,t){let n=n$[e];if(!n)return!0;let r=nC(t.platform)?n.apple:"linux"===t.platform?n.linux:n.android;return!!r&&(!n.supports||!!n.supports(t))&&!0===r[t.kind??"unknown"]}function nU(e,t){let n=Q(e.type??"Element"),r=Z(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 nG(e,t){return t.flatten?e.map(e=>({text:Y(e,0,!1),comparable:nU(e,0)})):K(e).map(e=>({text:e.text,comparable:nU(e.node,e.depth)}))}function nV(e,t){return e.get(t)??0}function nB(e,t,n){return{ok:!1,error:{code:e,message:t,...n?{details:n}:{}}}}function nj(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 nq(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 nW=nz(process.env.AGENT_DEVICE_RETRY_LOGS);function nz(e){return["1","true","yes","on"].includes((e??"").trim().toLowerCase())}let nH=2e4,nJ=12e4,nX=1e4;class nK{startedAtMs;expiresAtMs;constructor(e,t){this.startedAtMs=e,this.expiresAtMs=e+Math.max(0,t)}static fromTimeoutMs(e,t=Date.now()){return new nK(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 nY(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 N("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()}),nQ({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),nQ(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),nQ(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),nQ(a),r)throw r;throw new N("COMMAND_FAILED","retry failed")}async function nZ(e,t={}){return nY(()=>e(),{maxAttempts:t.attempts,baseDelayMs:t.baseDelayMs,maxDelayMs:t.maxDelayMs,jitter:t.jitter,shouldRetry:t.shouldRetry})}function nQ(e){ex({level:"attempt_failed"===e.event||"exhausted"===e.event?"warn":"debug",phase:"retry",data:{...e}}),nW&&process.stderr.write(`[agent-device][retry] ${JSON.stringify(e)}
9
+ `)}function n0(e){let t=e.error?S(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 n1(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 n2=["android.software.leanback","android.software.leanback_only","android.hardware.type.television"];function n3(e){return`${e.stdout}
10
+ ${e.stderr}`}function n4(e,t){return["-s",e,...t]}function n5(e){return e.startsWith("emulator-")}function n8(e){return e.toLowerCase().replace(/_/g," ").replace(/\s+/g," ").trim()}async function n6(e,t=nX){return D("adb",n4(e,["shell","getprop","sys.boot_completed"]),{allowFailure:!0,timeoutMs:t})}async function n9(e,t){let n=t.replace(/_/g," ").trim();if(!n5(e))return n||e;let r=await re(e);return r?r.replace(/_/g," "):n||e}async function n7(e,t,n){try{return await n("adb",n4(e,t),{allowFailure:!0,timeoutMs:1e4})}catch(e){var r;if("COMMAND_FAILED"===(r=S(e)).code&&"number"==typeof r.details?.timeoutMs)return;throw e}}async function re(e,t=D){for(let n of["ro.boot.qemu.avd_name","persist.sys.avd_name"]){let r=await n7(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 n7(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 rt(e,t){let n=n3(await D("adb",n4(e,["shell","cmd","package","has-feature",t]),{allowFailure:!0,timeoutMs:nX})).toLowerCase();return!!n.includes("true")||!n.includes("false")&&null}async function rn(e){return(await Promise.all(n2.map(async t=>await rt(e,t)))).some(e=>!0===e)}async function rr(e){var t;let n;return"tv"===((n=n3(await D("adb",n4(e,["shell","getprop","ro.build.characteristics"]),{allowFailure:!0,timeoutMs:nX})).toLowerCase()).includes("tv")||n.includes("leanback")?"tv":null)||await rn(e)?"tv":(t=n3(await D("adb",n4(e,["shell","pm","list","features"]),{allowFailure:!0,timeoutMs:nX})),/feature:android\.(software\.leanback(_only)?|hardware\.type\.television)\b/i.test(t))?"tv":"mobile"}async function ri(e={}){if(await tJ(),!await M("adb"))throw new N("TOOL_MISSING","adb not found in PATH");let t=e.serialAllowlist??t7(void 0),n=(await ra()).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([n9(e,t),ru(e),rr(e)]);return{platform:"android",id:e,name:n,kind:n5(e)?"emulator":"device",target:i,booted:r}}))}async function ra(){return(await D("adb",["devices","-l"],{timeoutMs:nX})).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 ro(){let e=await D("emulator",["-list-avds"],{allowFailure:!0,timeoutMs:nX});if(0!==e.exitCode)throw new N("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 rs(e){let t=Date.now();for(;Date.now()-t<e.timeoutMs;){try{let t=await rl(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 N("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 rl(e,t){let n=n8(e);for(let e of(await ra()).filter(e=>(!t||e.serial===t)&&n5(e.serial)))if(n8(e.rawModel)===n||n8(await n9(e.serial,e.rawModel))===n)return e.serial}async function ru(e){try{let t=await n6(e);return"1"===t.stdout.trim()}catch{return!1}}async function rd(e){var t,n;let r;await tJ();let i=e.avdName.trim();if(!i)throw new N("INVALID_ARGS","Android emulator boot requires a non-empty AVD name.");let a=e.timeoutMs??12e4;if(!await M("adb"))throw new N("TOOL_MISSING","adb not found in PATH");if(!await M("emulator"))throw new N("TOOL_MISSING","emulator not found in PATH");let o=await ro(),s=function(e,t){let n=e.find(e=>e===t);if(n)return n;let r=n8(t);return e.find(e=>n8(e)===r)}(o,i);if(!s)throw new N("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 ri(),n=e.serial,r=n8(s),t.find(e=>"android"===e.platform&&"emulator"===e.kind&&(!n||e.id===n)&&n8(e.name)===r));if(!u){let t=["-avd",s];e.headless&&t.push("-no-window","-no-audio"),x("emulator",t)}let d=u??await rs({avdName:s,serial:e.serial,timeoutMs:a}),c=Math.max(1e3,a-(Date.now()-l));await rc(d.id,c);let p=(await ri()).find(e=>e.id===d.id);return p?{...p,name:s,booted:!0}:{...d,name:s,booted:!0}}async function rc(e,t=6e4){let n,r=nK.fromTimeoutMs(t),i=Math.max(1,Math.ceil(t/1e3)),a=!1;try{await nY(async({deadline:i})=>{if(i?.isExpired())throw a=!0,new N("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 n6(e,Math.min(o,nX));if(n=s,"1"!==s.stdout.trim())throw new N("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=n0({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=>n0({error:e,stdout:n?.stdout,stderr:n?.stderr,context:{platform:"android",phase:"boot"}})})}catch(c){let i=S(c),o=n?.stdout,s=n?.stderr,l=n?.exitCode,u=n0({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:n1(u),stdout:o,stderr:s,exitCode:l};if(a||"ANDROID_BOOT_TIMEOUT"===u)throw new N("COMMAND_FAILED","Android device did not finish booting in time",d);if("TOOL_MISSING"===i.code)throw new N("TOOL_MISSING",i.message,{...d,...i.details??{}});if("ADB_TRANSPORT_UNAVAILABLE"===u)throw new N("COMMAND_FAILED",i.message,{...d,...i.details??{}});throw new N(i.code,i.message,{...d,...i.details??{}},i.cause)}}function rp(e,t,n){if(!e)return t;let r=Number(e);return Number.isFinite(r)?Math.max(n,Math.floor(r)):t}let rf=[".zip",".tar",".tar.gz",".tgz"];Object.freeze([...rf]);let rm=rp(process.env.AGENT_DEVICE_SOURCE_DOWNLOAD_TIMEOUT_MS,12e4,1e3),rh=["1","true","yes","on"];async function rw(e){let t=[];try{let n=await rg(e.source,{signal:e.signal,downloadTimeoutMs:e.downloadTimeoutMs});t.push(n.cleanup);let r=await rA(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 rD(t)}}}catch(e){throw await rD(t),e}}async function rg(e,t){if("path"===e.kind)return{localPath:eP(e.path),cleanup:async()=>{}};let n=await a.mkdtemp(o.join(p.tmpdir(),"agent-device-source-"));try{return{localPath:await ry(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 ry(e,t,n,r){let i;try{i=new URL(t)}catch{throw new N("INVALID_ARGS",`Invalid source URL: ${t}`)}await rv(i);let s=r?.signal;if(s?.aborted)throw new N("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??rm,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 N("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 N("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 N("COMMAND_FAILED","request canceled",{reason:"request_canceled"},e);if(l.signal.aborted)throw new N("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 rv(e){if("http:"!==e.protocol&&"https:"!==e.protocol)throw new N("INVALID_ARGS",`Unsupported source URL protocol: ${e.protocol}`);if(!rh.includes((process.env.AGENT_DEVICE_ALLOW_PRIVATE_SOURCE_URLS??"").toLowerCase())){var t;if(!(t=e.hostname.toLowerCase())||"localhost"===t||t.endsWith(".localhost")||rb(t))throw new N("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 h.lookup(e.hostname,{all:!0,verbatim:!0}).catch(()=>[])).some(e=>rb(e.address)))throw new N("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 rI(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 rb(e){let t,n=w.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 rA(e,t){let n=await a.stat(e).catch(()=>null);if(!n)throw new N("INVALID_ARGS",`App source not found: ${e}`);if(t.isInstallablePath(e,n))return{archivePath:t.archivePath,installablePath:e};if(n.isFile()&&rN(e)){if(!t.allowArchiveExtraction)throw new N("INVALID_ARGS",`URL sources must point directly to a ${t.installableLabel}; archive extraction is not allowed`,{path:e});let n=await rx(e);return t.registerCleanup(n.cleanup),await rA(n.outputPath,{...t,archivePath:t.archivePath??e})}if(n.isDirectory()){let n=await rS(e,t.isInstallablePath);if(1===n.length)return{archivePath:t.archivePath,installablePath:n[0]};if(n.length>1)throw new N("INVALID_ARGS",`Found multiple ${t.installableLabel} candidates under ${e}`,{matches:n});let r=await rS(e,(e,t)=>t.isFile()&&rN(e));if(1===r.length){if(!t.allowArchiveExtraction)throw new N("INVALID_ARGS",`URL sources must point directly to a ${t.installableLabel}; nested archives are not allowed`,{path:r[0]});let e=await rx(r[0]);return t.registerCleanup(e.cleanup),await rA(e.outputPath,{...t,archivePath:t.archivePath??r[0]})}if(r.length>1)throw new N("INVALID_ARGS",`Found multiple nested archives under ${e}; expected one ${t.installableLabel} source`,{matches:r})}throw new N("INVALID_ARGS",`Expected ${t.installableLabel} source, but got ${e}`)}async function rS(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 rx(e){let t=await a.mkdtemp(o.join(p.tmpdir(),"agent-device-archive-"));try{return e.toLowerCase().endsWith(".zip")?await r_(e,t):e.toLowerCase().endsWith(".tar.gz")||e.toLowerCase().endsWith(".tgz")?await D("tar",["-xzf",e,"-C",t]):await D("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}}async function r_(e,t){await D("unzip",["-q",e,"-d",t])}function rN(e){let t=e.toLowerCase();return rf.some(e=>t.endsWith(e))}async function rD(e){for(let t=e.length-1;t>=0;t-=1)await e[t]()}let rE=new y("utf-16le");async function rC(e){for(let n of["AndroidManifest.xml","base/manifest/AndroidManifest.xml"]){var t;let r=await rM(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]=rO(e,t),[r,i]=rO(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 rE.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 rL(e)}async function rM(e,t){try{let n=await D("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 rO(e,t){let n=e.readUInt8(t);return(128&n)==0?[n,1]:[(127&n)<<8|e.readUInt8(t+1),2]}async function rL(e){let t=await rT();if(!t)return;let n=await D(t,["dump","badging",e],{allowFailure:!0});if(0!==n.exitCode)return;let r=n.stdout.match(/package:\s+name='([^']+)'/);return r?.[1]}async function rT(){if(void 0!==e)return e??void 0;try{for(let t of tz()){let n=o.join(t,"build-tools");try{for(let t of(await g.readdir(n)).sort((e,t)=>t.localeCompare(e,void 0,{numeric:!0}))){let r=o.join(n,t,"aapt");if(o.isAbsolute(r)&&await b(r))return e=r,r}}catch{}}}catch{}e=null}async function rk(e,t){let n="url"===e.kind&&rI(e.url),r=await rw({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 rR(r.installablePath);return{archivePath:r.archivePath,installablePath:r.installablePath,packageName:i.packageName,cleanup:r.cleanup}}async function rR(e){let t=o.extname(e).toLowerCase();return".apk"!==t&&".aab"!==t?{}:{packageName:await rC(e)}}let rP={settings:{type:"intent",value:"android.settings.SETTINGS"}},r$="android.intent.category.LAUNCHER",rF="android.intent.category.LEANBACK_LAUNCHER",rU="android.intent.category.DEFAULT",rG="Run agent-device apps --platform android to discover the installed package name, then retry open with that exact package.";async function rV(e,t){let n=t.trim();if("package"===t1(n))return{type:"package",value:n};let r=rP[n.toLowerCase()];if(r)return r;let i=(await D("adb",tX(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 N("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 N("APP_NOT_INSTALLED",`No package found matching "${t}"`,{hint:rG})}async function rB(e,t="all"){let n=await rj(e);return("user-installed"===t?(await rW(e)).filter(e=>n.has(e)):Array.from(n)).sort((e,t)=>e.localeCompare(t)).map(e=>({package:e,name:rz(e)}))}async function rj(e){let t=new Set;for(let n of rq(e,{includeFallbackWhenUnknown:!0})){let r=await D("adb",tX(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 rq(e,t={}){return"tv"===e.target?[rF]:"mobile"===e.target?[r$]:t.includeFallbackWhenUnknown?[r$,rF]:[r$]}async function rW(e){return(await D("adb",tX(e,["shell","pm","list","packages","-3"]))).stdout.split("\n").map(e=>e.replace("package:","").trim()).filter(Boolean)}function rz(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 rH(e){let t=await rJ(e,[["shell","dumpsys","window","windows"],["shell","dumpsys","window"]]);if(t)return t;let n=await rJ(e,[["shell","dumpsys","activity","activities"],["shell","dumpsys","activity"]]);return n||{}}async function rJ(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 D("adb",tX(e,n),{allowFailure:!0})).stdout??"");if(t)return t}return null}async function rX(e,t,n){var r,i;let a;e.booted||await rc(e.id);let o=t.trim();if(nj(o)){if(n)throw new N("INVALID_ARGS","Activity override is not supported when opening a deep link URL");await D("adb",tX(e,["shell","am","start","-W","-a","android.intent.action.VIEW","-d",o]));return}let s=await rV(e,t),l=rq(e)[0]??r$;if("intent"===s.type){if(n)throw new N("INVALID_ARGS","Activity override requires a package name, not an intent");await D("adb",tX(e,["shell","am","start","-W","-a",s.value]));return}if(n){let t=n.includes("/")?n:`${s.value}/${n.startsWith(".")?n:`.${n}`}`;try{await D("adb",tX(e,["shell","am","start","-W","-a","android.intent.action.MAIN","-c",rU,"-c",l,"-n",t]))}catch(t){throw await rZ(e,s.value,t),t}return}let u=await D("adb",tX(e,["shell","am","start","-W","-a","android.intent.action.MAIN","-c",rU,"-c",l,"-p",s.value]),{allowFailure:!0});if(0===u.exitCode&&(r=u.stdout,i=u.stderr,a=`${r}
11
+ ${i}`,!/Error:.*(?:Activity not started|unable to resolve Intent)/i.test(a)))return;let d=await r0(e,s.value);if(!d){if(!await rY(e,s.value))throw rK(s.value);throw new N("COMMAND_FAILED",`Failed to launch ${s.value}`,{stdout:u.stdout,stderr:u.stderr})}await D("adb",tX(e,["shell","am","start","-W","-a","android.intent.action.MAIN","-c",rU,"-c",l,"-n",d]))}function rK(e){return new N("APP_NOT_INSTALLED",`No package found matching "${e}"`,{package:e,hint:rG})}async function rY(e,t){let n=await D("adb",tX(e,["shell","pm","path",t]),{allowFailure:!0}),r=`${n.stdout}
12
+ ${n.stderr}`;return!!(0===n.exitCode&&/\bpackage:/i.test(r))||(rQ(r),!1)}async function rZ(e,t,n){if(rQ(n instanceof N?`${String(n.details?.stdout??"")}
13
+ ${String(n.details?.stderr??"")}`:"")||!await rY(e,t))throw rK(t)}function rQ(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 r0(e,t){for(let n of Array.from(new Set(rq(e,{includeFallbackWhenUnknown:!0})))){let r=await D("adb",tX(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 r1(e){e.booted||await rc(e.id)}async function r2(e,t){if("settings"===t.trim().toLowerCase())return void await D("adb",tX(e,["shell","am","force-stop","com.android.settings"]));let n=await rV(e,t);if("intent"===n.type)throw new N("INVALID_ARGS","Close requires a package name, not an intent");await D("adb",tX(e,["shell","am","force-stop",n.value]))}async function r3(e,t){let n=await rV(e,t);if("intent"===n.type)throw new N("INVALID_ARGS","App uninstall requires a package name, not an intent");let r=await D("adb",tX(e,["uninstall",n.value]),{allowFailure:!0});if(0!==r.exitCode){let e=`${r.stdout}
14
+ ${r.stderr}`.toLowerCase();if(!e.includes("unknown package")&&!e.includes("not installed"))throw new N("COMMAND_FAILED",`adb uninstall failed for ${n.value}`,{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode})}return{package:n.value}}let r4=null;async function r5(){let e=`${process.env.PATH??""}::${process.env.AGENT_DEVICE_BUNDLETOOL_JAR??""}`;if(r4?.key===e)return r4.invocation;if(await M("bundletool")){let t={cmd:"bundletool",prefixArgs:[]};return r4={key:e,invocation:t},t}let t=await C(process.env.AGENT_DEVICE_BUNDLETOOL_JAR,"AGENT_DEVICE_BUNDLETOOL_JAR");if(!t)throw new N("TOOL_MISSING","bundletool not found in PATH. Install bundletool or set AGENT_DEVICE_BUNDLETOOL_JAR to a bundletool-all.jar path.");let n={cmd:"java",prefixArgs:["-jar",t]};return r4={key:e,invocation:n},n}async function r8(e){let t=await r5();await D(t.cmd,[...t.prefixArgs,...e])}async function r6(e,t){let n,r=await a.mkdtemp(o.join(p.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 r8(["build-apks","--bundle",t,"--output",i,"--mode",s]),await r8(["install-apks","--apks",i,"--device-id",e.id])}finally{await a.rm(r,{recursive:!0,force:!0})}}async function r9(e,t){".aab"===o.extname(t).toLowerCase()?await r6(e,t):await D("adb",tX(e,["install","-r",t]))}async function r7(e){return new Set((await D("adb",tX(e,["shell","pm","list","packages"]))).stdout.split("\n").map(e=>e.replace("package:","").trim()).filter(Boolean))}async function ie(e,t){let n=Array.from(await r7(e)).filter(e=>!t.has(e));if(1===n.length)return n[0]}async function it(e,t){e.booted||await rc(e.id),await r9(e,t)}async function ir(e,t,n){let r=n?void 0:await r7(e);return await it(e,t),n??(r?await ie(e,r):void 0)}async function ii(e,t){e.booted||await rc(e.id);let n=await rk({kind:"path",path:t});try{let t=await ir(e,n.installablePath,n.packageName),r=t?rz(t):void 0;return{archivePath:n.archivePath,installablePath:n.installablePath,packageName:t,appName:r,launchTarget:t}}finally{await n.cleanup()}}async function ia(e,t,n){e.booted||await rc(e.id);let{package:r}=await r3(e,t),i=await rk({kind:"path",path:n},{resolveIdentity:!1});try{return await it(e,i.installablePath),{package:r}}finally{await i.cleanup()}}function io(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 N("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 N("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 is(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=ip(e.type),l=!!(e.label&&e.label.trim().length>0),u=!!(e.identifier&&e.identifier.trim().length>0),d=l&&!im(e.label??""),c=u&&!im(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=ip(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 il(e){let t=function(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}(e),n=e=>{let n=iu(t,e);if(null!==n)return"true"===n};return{text:iu(t,"text"),desc:iu(t,"content-desc"),resourceId:iu(t,"resource-id"),className:iu(t,"class"),bounds:iu(t,"bounds"),clickable:n("clickable"),enabled:n("enabled"),focusable:n("focusable"),focused:n("focused")}}function iu(e,t){return e.get(t)??null}function id(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 ic(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=il(t),o=id(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 ip(e){return e?e.toLowerCase():""}function im(e){let t=e.trim();return!!t&&/^[\w.]+:id\/[\w.-]+$/i.test(t)}function ih(e){if(0===e.length)return null;let t=[...e].sort((e,t)=>e-t);return t[Math.floor(t.length/2)]??null}function iw(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 ig(e,t){return{start:e.y-t.y,size:e.height,crossSize:e.width}}async function iy(e,t={}){let n=await iI(e);if(!t.interactiveOnly){let r=function(e,t){let{sourceNodes:n,...r}=is(ic(e),800,t);return r}(n,t);return await iv(e,r.nodes),r}let r=ic(n),i=is(r,800,{...t,interactiveOnly:!1});await iv(e,i.nodes),function(e){if(0===e.length||e.some(e=>e.hiddenContentAbove||e.hiddenContentBelow))return;let t=new Map(ef(ei(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}=is(r,800,t);return o}async function iv(e,t){if(!t.some(e=>ec(e.type)))return;let n=await ix(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=>ig(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=>ig(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=ih(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(!iw(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(!iw(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?ih(o):a.length>0?ih(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 iI(e){return nZ(()=>ib(e),{shouldRetry:iS})}async function ib(e){var t,n,r;let i,a,o=await D("adb",tX(e,["exec-out","uiautomator","dump","/dev/tty"]),{allowFailure:!0}),s=iA(o.stdout,o.stderr);if(s)return s;let l="/sdcard/window_dump.xml",u=await D("adb",tX(e,["shell","uiautomator","dump",l]),{allowFailure:!0}),d=(t=l,n=u.stdout,r=u.stderr,i=`${n}
15
+ ${r}`,a=/dumped to:\s*(\S+)/i.exec(i),a?.[1]??t),c=await D("adb",tX(e,["shell","cat",d])),p=iA(c.stdout,c.stderr);if(!p)throw new N("COMMAND_FAILED","uiautomator dump did not return XML",{stdout:c.stdout,stderr:c.stderr});return p}function iA(e,t){let n=`${e}
16
+ ${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 iS(e){if(!(e instanceof N)||"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 ix(e){try{let t=await D("adb",tX(e,["shell","dumpsys","activity","top"]),{allowFailure:!0,timeoutMs:8e3}),n=`${t.stdout}
17
+ ${t.stderr}`.trim();return n.length>0?n:null}catch{return null}}async function i_(e,t,n){await D("adb",tX(e,["shell","input","tap",String(t),String(n)]))}async function iN(e,t,n,r,i,a=250){await D("adb",tX(e,["shell","input","swipe",String(t),String(n),String(r),String(i),String(a)]))}async function iD(e){await D("adb",tX(e,["shell","input","keyevent","4"]))}async function iE(e){await D("adb",tX(e,["shell","input","keyevent","3"]))}async function iC(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 N("INVALID_ARGS",`Unsupported Android rotation: ${e}`)}}(t);await D("adb",tX(e,["shell","settings","put","system","accelerometer_rotation","0"])),await D("adb",tX(e,["shell","settings","put","system","user_rotation",n]))}async function iM(e){await D("adb",tX(e,["shell","input","keyevent","187"]))}async function iO(e,t,n,r=800){await D("adb",tX(e,["shell","input","swipe",String(t),String(n),String(t),String(n),String(r)]))}async function iL(e,t,n=0){n>0&&Array.from(t).length>1?await iG(e,t,1,n):await iT(e,t)}async function iT(e,t){let n=iV(t);if(!n||"ok"!==await iB(e,t))try{let n=t.replace(/ /g,"%s");await D("adb",tX(e,["shell","input","text",n]))}catch(e){if(n&&function(e){if(!(e instanceof N)||"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 N("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 ik(e,t,n){await i_(e,t,n)}async function iR(e,t,n,r,i=0){let a=Array.from(r).length,o=iV(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 ik(e,t,n);let s=(u=a+o.clearPadding,d=o.minClear,Math.max(d,Math.min(o.maxClear,u)));if(await ij(e,s),"input_text"===o.strategy)await iL(e,r,i);else if("clipboard_paste"===o.strategy){if("ok"!==await iB(e,r))continue}else await iG(e,r,1,i>0?i:15);let c=await iP(e,t,n,r);if(l=c.actual,c.ok)return}throw new N("COMMAND_FAILED","Android fill verification failed",{expected:r,actual:l??null})}async function iP(e,t,n,r){let i=null;for(let a of[0,150,350])if(a>0&&await tZ(a),function(e,t){if(e===t)return!0;let n=i$(e),r=i$(t);return!!n&&!!r&&(!!(n===r||n.includes(r))||r.includes(n)&&n.length>=Math.max(4,Math.floor(.8*r.length)))}(i=await iq(e,t,n),r))return{ok:!0,actual:i};return{ok:!1,actual:i}}function i$(e){return(e??"").replace(/\s+/g," ").trim()}async function iF(e,t,n){let r=await iU(e),i=io({direction:t,amount:n?.amount,pixels:n?.pixels,referenceWidth:r.width,referenceHeight:r.height});return await D("adb",tX(e,["shell","input","swipe",String(i.x1),String(i.y1),String(i.x2),String(i.y2),"300"])),i}async function iU(e){let t=(await D("adb",tX(e,["shell","wm","size"]))).stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(!t)throw new N("COMMAND_FAILED","Unable to read screen size");return{width:Number(t[1]),height:Number(t[2])}}async function iG(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 iT(e,n),r>0&&t+i<a.length&&await tZ(r)}}function iV(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 iB(e,t){let n=await D("adb",tX(e,["shell","cmd","clipboard","set","text",t]),{allowFailure:!0});return 0!==n.exitCode?"failed":tY(n.stdout,n.stderr)?"unsupported":0===(await D("adb",tX(e,["shell","input","keyevent","KEYCODE_PASTE"]),{allowFailure:!0})).exitCode||0===(await D("adb",tX(e,["shell","input","keyevent","279"]),{allowFailure:!0})).exitCode?"ok":"failed"}async function ij(e,t){let n=Math.max(0,t);await D("adb",tX(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 D("adb",tX(e,["shell","input","keyevent",...Array(r).fill("KEYCODE_DEL")]),{allowFailure:!0})}}async function iq(e,t,n){let r,i=await iI(e),a=/<node\b[^>]*>/g,o=null,s=null,l=null;for(;null!==(r=a.exec(i));){let e=il(r[0]),i=id(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&&iW(a)){(!o||c<=o.area)&&(o={text:u,area:c});continue}if(p&&iW(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 iW(e){let t=e.toLowerCase();return t.includes("edittext")||t.includes("textfield")}async function iz(e){let t=await D("adb",tX(e,["shell","dumpsys","input_method"]),{allowFailure:!0});if(0!==t.exitCode)throw new N("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 iH(e){let t=await iz(e),n=t,r=0;for(;n.visible&&r<2;)await D("adb",tX(e,["shell","input","keyevent","111"])),r+=1,await tZ(120),n=await iz(e);if(t.visible&&n.visible)throw new N("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 iJ(e){let t,n;return(n=(t=(await iK(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 iX(e,t){await iK(e,["shell","cmd","clipboard","set","text",t],"write")}async function iK(e,t,n){let r=await D("adb",tX(e,t),{allowFailure:!0});if(tY(r.stdout,r.stderr))throw new N("UNSUPPORTED_OPERATION",`Android shell clipboard ${n} is not supported on this device.`);if(0!==r.exitCode)throw new N("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 iZ(e){let t=e.trim().toLowerCase();if("grant"===t)return"grant";if("deny"===t)return"deny";if("reset"===t)return"reset";throw new N("INVALID_ARGS",`Invalid permission action: ${e}. Use grant|deny|reset.`)}function iQ(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 N("INVALID_ARGS",`permission setting requires a target: ${iY.join("|")}`)}function i0(e){let t=e.trim().toLowerCase();if("light"===t)return"light";if("dark"===t)return"dark";if("toggle"===t)return"toggle";throw new N("INVALID_ARGS",`Invalid appearance state: ${e}. Use light|dark|toggle.`)}async function i1(e,t,n,r,i){switch(t.toLowerCase()){case"wifi":{let t=i3(n);await D("adb",tX(e,["shell","svc","wifi",t?"enable":"disable"]));return}case"airplane":{let t=i3(n);await D("adb",tX(e,["shell","settings","put","global","airplane_mode_on",t?"1":"0"])),await D("adb",tX(e,["shell","am","broadcast","-a","android.intent.action.AIRPLANE_MODE","--ez","state",t?"true":"false"]));return}case"location":{let t=i3(n);await D("adb",tX(e,["shell","settings","put","secure","location_mode",t?"3":"0"]));return}case"appearance":{let t=await i4(e,n);await D("adb",tX(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 N("INVALID_ARGS",`Invalid fingerprint state: ${e}. Use match|nonmatch.`)}(n);await i2(e,t);return}case"permission":{if(!r)throw new N("INVALID_ARGS","permission setting requires an active app in session");let t=iZ(n),a=function(e,t){let n=iQ(e);if(t?.trim())throw new N("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 N("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 i8(e,r,t,a);let o="grant"===t?"grant":"revoke";if("photos"===a.type)return void await i5(e,r,o);await D("adb",tX(e,["shell","pm",o,r,a.value]));return}default:throw new N("INVALID_ARGS",`Unsupported setting: ${t}`)}}async function i2(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 D("adb",tX(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}
18
+ ${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 N("UNSUPPORTED_OPERATION","Android fingerprint simulation is not supported on this target/runtime.",{deviceId:e.id,action:t,hint:"Use an Android emulator with biometric support, or a device/runtime that exposes cmd fingerprint.",attempts:s});throw new N("COMMAND_FAILED","Failed to simulate Android fingerprint.",{deviceId:e.id,action:t,attempts:s})}function i3(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 N("INVALID_ARGS",`Invalid setting state: ${e}`)}async function i4(e,t){let n=i0(t);if("toggle"!==n)return n;let r=await D("adb",tX(e,["shell","cmd","uimode","night"]),{allowFailure:!0});if(0!==r.exitCode)throw new N("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}
19
+ ${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 N("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 i5(e,t,n){let r=await i6(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 D("adb",tX(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 N("COMMAND_FAILED",`Failed to ${n} Android photos permission`,{appPackage:t,sdkInt:r,attempts:i})}async function i8(e,t,n,r){"grant"===n?await D("adb",tX(e,["shell","pm","grant",t,r.permission]),{allowFailure:!0}):(await D("adb",tX(e,["shell","pm","revoke",t,r.permission]),{allowFailure:!0}),"reset"===n&&(await D("adb",tX(e,["shell","pm","clear-permission-flags",t,r.permission,"user-set"]),{allowFailure:!0}),await D("adb",tX(e,["shell","pm","clear-permission-flags",t,r.permission,"user-fixed"]),{allowFailure:!0}))),await D("adb",tX(e,["shell","appops","set",t,r.appOps,"grant"===n?"allow":"deny"===n?"deny":"default"]))}async function i6(e){let t=await D("adb",tX(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 i9(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 N("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 N("INVALID_ARGS",`Unsupported Android broadcast extra type for "${t}". Use string, boolean, or number.`)}(i,e,t),s+=1);return await D("adb",tX(e,i)),{action:r,extrasCount:s}}let i7=Buffer.from([137,80,78,71,13,10,26,10]);async function ae(e,t){await at(e);try{await tZ(1e3),await ar(e,t)}finally{await an(e).catch(()=>{})}}async function at(e){let t=t=>D("adb",tX(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 an(e){await D("adb",tX(e,["shell","am broadcast -a com.android.systemui.demo -e command exit"]),{allowFailure:!0})}async function ar(e,t){let n=await D("adb",tX(e,["exec-out","screencap","-p"]),{binaryStdout:!0});if(!n.stdoutBuffer)throw new N("COMMAND_FAILED","Failed to capture screenshot");let r=n.stdoutBuffer.indexOf(i7);if(r<0)throw new N("COMMAND_FAILED","Screenshot data does not contain a valid PNG header");let i=function(e,t){let n=t+i7.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 N("COMMAND_FAILED","Screenshot data does not contain a complete PNG payload");await a.writeFile(t,n.stdoutBuffer.subarray(r,i))}let ai=rp(process.env.AGENT_DEVICE_IOS_BOOT_TIMEOUT_MS,nJ,5e3),aa=rp(process.env.AGENT_DEVICE_IOS_SIMCTL_LIST_TIMEOUT_MS,nH,1e3),ao=rp(process.env.AGENT_DEVICE_IOS_APP_LAUNCH_TIMEOUT_MS,3e4,5e3),as=rp(process.env.AGENT_DEVICE_IOS_DEVICECTL_TIMEOUT_MS,2e4,1e3),al=rp(process.env.AGENT_DEVICE_IOS_SIMULATOR_FOCUS_TIMEOUT_MS,1e4,1e3),au=rp(process.env.AGENT_DEVICE_IOS_SIMULATOR_SCREENSHOT_TIMEOUT_MS,2e4,1e3),ad=rp(process.env.AGENT_DEVICE_IOS_RUNNER_SCREENSHOT_COPY_TIMEOUT_MS,2e4,1e3),ac=nz(process.env.AGENT_DEVICE_IOS_SIMULATOR_SCREENSHOT_RUNNER_FALLBACK);async function ap(e,t){let n=["devicectl",...e],r=await D("xcrun",n,{allowFailure:!0,timeoutMs:as});if(0===r.exitCode)return;let i=String(r.stdout??""),a=String(r.stderr??"");throw new N("COMMAND_FAILED",`Failed to ${t.action}`,{cmd:"xcrun",args:n,exitCode:r.exitCode,stdout:i,stderr:a,deviceId:t.deviceId,hint:aw(i,a)??ah})}async function af(e,t){let n=o.join(p.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 D("xcrun",r,{allowFailure:!0,timeoutMs:as});try{var s,l;if(0!==i.exitCode){let t=String(i.stdout??""),n=String(i.stderr??"");throw new N("COMMAND_FAILED","Failed to list iOS apps",{cmd:"xcrun",args:r,exitCode:i.exitCode,stdout:t,stderr:n,deviceId:e.id,hint:aw(t,n)??ah})}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)),l=t,"user-installed"===l?s.filter(e=>!e.bundleId.startsWith("com.apple.")):s}catch(t){if(t instanceof N)throw t;throw new N("COMMAND_FAILED","Failed to parse iOS apps list",{deviceId:e.id,cause:String(t)})}finally{await a.unlink(n).catch(()=>{})}}async function am(e){let t=o.join(p.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 D("xcrun",n,{allowFailure:!0,timeoutMs:as});try{if(0!==r.exitCode){let t=String(r.stdout??""),i=String(r.stderr??"");throw new N("COMMAND_FAILED","Failed to list iOS processes",{cmd:"xcrun",args:n,exitCode:r.exitCode,stdout:t,stderr:i,deviceId:e.id,hint:aw(t,i)??ah})}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 N)throw t;throw new N("COMMAND_FAILED","Failed to parse iOS process list",{deviceId:e.id,cause:String(t)})}finally{await a.unlink(t).catch(()=>{})}}let ah="Ensure the iOS device is unlocked, trusted, and available in Xcode > Devices, then retry.";function aw(e,t){let n=`${e}
20
+ ${t}`.toLowerCase();return n.includes("device is busy")&&n.includes("connecting")?"iOS device is still connecting. Keep it unlocked and connected by cable until it is fully available in Xcode Devices, then retry.":n.includes("coredeviceservice")&&n.includes("timed out")?"CoreDevice service timed out. Reconnect the device and retry; if it persists restart Xcode and the iOS device.":null}function ag(e){if(!(e instanceof N)||"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 ay(e,t){let n=await D("xcrun",nt(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 D("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 D("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 av(e,t){if("simulator"!==e.kind)throw new N("UNSUPPORTED_OPERATION",`${t} is only supported on iOS simulators`)}async function aI(){await D("open",["-a","Simulator"],{allowFailure:!0,timeoutMs:al})}async function ab(e){let t,n;if("simulator"!==e.kind||"Booted"===await aS(e))return;let r=nK.fromTimeoutMs(ai);try{await nY(async({deadline:r})=>{if(r?.isExpired())throw new N("COMMAND_FAILED","iOS simulator boot deadline exceeded",{timeoutMs:ai});let i=Math.max(1e3,r?.remainingMs()??ai),a=await D("xcrun",nt(e,["boot",e.id]),{allowFailure:!0,timeoutMs:i});t={stdout:String(a.stdout??""),stderr:String(a.stderr??""),exitCode:a.exitCode};let o=`${t.stdout}
21
+ ${t.stderr}`.toLowerCase(),s=o.includes("already booted")||o.includes("current state: booted");if(0!==t.exitCode&&!s)throw new N("COMMAND_FAILED","simctl boot failed",{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode});let l=await D("xcrun",nt(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 N("COMMAND_FAILED","simctl bootstatus failed",{stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode});let u=await aS(e);if("Booted"!==u)throw new N("COMMAND_FAILED","Simulator is still booting",{state:u})},{maxAttempts:3,baseDelayMs:500,maxDelayMs:2e3,jitter:.2,shouldRetry:e=>{let r=n0({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=>n0({error:e,stdout:n?.stdout??t?.stdout,stderr:n?.stderr??t?.stderr,context:{platform:"ios",phase:"boot"}})})}catch(a){let i=n0({error:a,stdout:n?.stdout??t?.stdout,stderr:n?.stderr??t?.stderr,context:{platform:"ios",phase:"boot"}});throw new N("COMMAND_FAILED","iOS simulator failed to boot",{platform:"ios",deviceId:e.id,timeoutMs:ai,elapsedMs:r.elapsedMs(),reason:i,hint:n1(i),boot:t,bootstatus:n})}await aI()}async function aA(e){let t=nt(e,["shutdown",e.id]),n=await D("xcrun",t,{allowFailure:!0,timeoutMs:15e3});return{success:0===n.exitCode,exitCode:n.exitCode,stdout:String(n.stdout??""),stderr:String(n.stderr??"")}}async function aS(e){let t="string"==typeof e?e:e.id,n="string"==typeof e?ne(["list","devices","-j"]):nt(e,["list","devices","-j"]),r=await D("xcrun",n,{allowFailure:!0,timeoutMs:aa});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 ax=null;function a_(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:aD(i)??aD(r["#text"]),children:e(i)});return n}((ax??=new v({ignoreAttributes:!1,attributeNamePrefix:"",preserveOrder:!0,trimValues:!0,parseTagValue:!1})).parse(e))}function aN(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)}aN(n.children,t)}}function aD(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 aE(e,t){try{let n=await D("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,aN(a_(n),(e,t)=>{void 0===i&&e===r&&"string"===t.name&&(i=t.text??void 0)}),i}catch{return}}async function aC(e,t){if("url"===e.kind&&!rI(e.url))throw new N("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 rw({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||rI(e.url),signal:t?.signal}),r=await aO(n.installablePath,t),i=await aM(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 aM(e){let t=o.join(e,"Info.plist"),[n,r,i]=await Promise.all([aE(t,"CFBundleIdentifier"),aE(t,"CFBundleDisplayName"),aE(t,"CFBundleName")]);return{bundleId:n,appName:r??i}}async function aO(e,t){if(!e.toLowerCase().endsWith(".ipa"))return{installPath:e,cleanup:async()=>{}};let n=await a.mkdtemp(o.join(p.tmpdir(),"agent-device-ios-ipa-")),r=async()=>{await a.rm(n,{recursive:!0,force:!0})};try{await D("unzip",["-q",e,"-d",n]);let i=o.join(n,"Payload"),s=(await a.readdir(i,{withFileTypes:!0}).catch(()=>{throw new N("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 N("INVALID_ARGS","Invalid IPA: expected at least one .app under Payload, found 0");await aL(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 N("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 N("INVALID_ARGS",`Invalid IPA: found ${s.length} .app bundles under Payload and none matched "${l}". Available bundles: ${s.map(aT).join(", ")}`)}throw new N("INVALID_ARGS",`Invalid IPA: found ${s.length} .app bundles under Payload. Pass an app identifier or bundle name matching one of: ${s.map(aT).join(", ")}`)}catch(e){throw await r(),e}}async function aL(e){await Promise.all(e.map(async e=>{if(e.bundleId&&e.appName)return;let t=await aM(e.installPath);e.bundleId=e.bundleId??t.bundleId,e.appName=e.appName??t.appName}))}function aT(e){let t=e.bundleId??e.appName;return t?`${e.bundleName}.app (${t})`:`${e.bundleName}.app`}function ak(e,t){return"user-installed"===t?e.filter(e=>!e.bundleId.startsWith("com.apple.")):e}let aR="agent-device-macos-helper",aP="AGENT_DEVICE_MACOS_HELPER_BIN",a$=o.join(p.homedir(),".agent-device","macos-helper","current"),aF=o.join(a$,"manifest.json"),aU=/^[A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)+$/;function aG(e){let t=e.trim();if(!aU.test(t))throw new N("INVALID_ARGS","macOS bundle id must use reverse-DNS form like com.example.App",{bundleId:e});return t}function aV(){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 N("COMMAND_FAILED","Unable to locate macOS helper package root",{modulePath:e})}(l(import.meta.url))}async function aB(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 aB(n):t.isFile()&&(t.name.endsWith(".swift")||"Package.swift"===t.name)?[n]:[]}))).flat().sort()}async function aj(e){let t=await aB(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 D("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 aq(){try{let e=JSON.parse(await a.readFile(aF,"utf8"));return"string"==typeof e.fingerprint?e.fingerprint:null}catch{return null}}async function aW(){let e=await I(process.env[aP],aP);if(e)return e;let t=aV(),n=await aj(t),r=o.join(a$,aR);try{if(await aq()===n)return await a.access(r),r}catch{}let i=o.join(aV(),".build","release",aR);process.stderr.write("agent-device: building macOS helper (first run or helper update)\n"),await D("swift",["build","-c","release","--package-path",t],{cwd:t,timeoutMs:12e4}),await a.mkdir(a$,{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(aF,`${JSON.stringify({fingerprint:n},null,2)}
22
+ `,"utf8"),r}async function az(e){let t=process.env[aP]?.trim();if("darwin"!==process.platform&&!t)throw new N("UNSUPPORTED_PLATFORM","macOS helper is only available on macOS");let n=await aW(),r=await D(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 N("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 aH(){return await az(["app","frontmost"])}async function aJ(e){return await az(["app","quit","--bundle-id",aG(e)])}async function aX(e,t){return await az(["permission",e,t])}async function aK(e,t={}){let n=["alert",e];return t.bundleId&&n.push("--bundle-id",aG(t.bundleId)),t.surface&&n.push("--surface",t.surface),await az(n)}async function aY(e,t={}){let n=["snapshot","--surface",e];return t.bundleId&&n.push("--bundle-id",aG(t.bundleId)),await az(n)}async function aZ(e,t,n={}){let r=["read","--x",String(e),"--y",String(t)];return n.bundleId&&r.push("--bundle-id",aG(n.bundleId)),n.surface&&r.push("--surface",n.surface),await az(r)}async function aQ(e,t,n={}){let r=["press","--x",String(e),"--y",String(t)];return n.bundleId&&r.push("--bundle-id",aG(n.bundleId)),n.surface&&r.push("--surface",n.surface),await az(r)}async function a0(e,t={}){let n=["screenshot","--out",e];return t.surface&&n.push("--surface",t.surface),t.fullscreen&&n.push("--fullscreen"),await az(n)}let a1={settings:"com.apple.systempreferences"},a2=/^[a-z0-9-]+(?:\.[a-z0-9-]+)+$/;function a3(e,t){let n=["-b",e];return t&&n.push(t),n}async function a4(e){for(let t of[o.join(e,"Contents","Info.plist"),o.join(e,"Info.plist")]){let[e,n,r]=await Promise.all([aE(t,"CFBundleIdentifier"),aE(t,"CFBundleDisplayName"),aE(t,"CFBundleName")]);if(e||n||r)return{bundleId:e,appName:n??r}}return{}}async function a5(e){let t=e.trim(),n=a1[t.toLowerCase()];if(n)return n;if(a2.test(t))return t;let r=(await on("all")).filter(e=>e.name.toLowerCase()===t.toLowerCase());if(1===r.length)return r[0].bundleId;if(r.length>1)throw new N("INVALID_ARGS",`Multiple apps matched "${e}"`,{matches:r});throw new N("APP_NOT_INSTALLED",`No app found matching "${e}"`)}async function a8(e,t,n){let r=n?.url?.trim();if(r){if(!nj(r))throw new N("INVALID_ARGS","open <app> <url> requires a valid URL target");let e=n?.appBundleId??await a5(t);await D("open",a3(e,r));return}let i=t.trim();if(nj(i))return void await D("open",[i]);let a=n?.appBundleId??await a5(i);await D("open",a3(a))}async function a6(e,t){let n=await a5(t),r=await aJ(n);if(r.running&&!r.terminated&&!r.forceTerminated)throw new N("COMMAND_FAILED",`Failed to close macOS app ${t}`,{bundleId:n,running:r.running,terminated:r.terminated,forceTerminated:r.forceTerminated})}async function a9(){let e=await D("pbpaste",[],{allowFailure:!0});if(0!==e.exitCode)throw new N("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 a7(e){let t=await D("pbcopy",[],{allowFailure:!0,stdin:e});if(0!==t.exitCode)throw new N("COMMAND_FAILED","Failed to write macOS clipboard",{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode})}async function oe(){let e=await D("osascript",["-e",'tell application "System Events" to tell appearance preferences to get dark mode'],{allowFailure:!0});if(0!==e.exitCode)throw new N("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 N("COMMAND_FAILED",`Unable to determine current macOS appearance from osascript output: ${e.stdout.trim()}`)}async function ot(e){let t=i0(e),n="toggle"===t?!await oe():"dark"===t,r=`tell application "System Events" to tell appearance preferences to set dark mode to ${n?"true":"false"}`,i=await D("osascript",["-e",r],{allowFailure:!0});if(0!==i.exitCode)throw new N("COMMAND_FAILED","Failed to set macOS appearance",{stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode})}async function on(e="all"){let t=["/Applications","/System/Applications",o.join(p.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 D("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 ak((await Promise.all(Array.from(n).map(async e=>{let t=await a4(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 or=new Set,oi=new Map,oa="request_canceled",oo="request canceled";function os(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 ol(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++}}(oi);let t=new AbortController;oi.set(e,t),or.has(e)&&t.abort()}function ou(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++}}(or),or.add(e),oi.get(e)?.abort())}function od(e){e&&(or.delete(e),oi.delete(e))}function oc(e){return!!e&&or.has(e)}function op(e){if(e)return oi.get(e)?.signal}function of(){return new N("COMMAND_FAILED",oo,{reason:oa})}function om(e){return e instanceof N&&"COMMAND_FAILED"===e.code&&(e.details?.reason===oa||e.message===oo)}function oh(e){return!(e instanceof N)||"COMMAND_FAILED"!==e.code||!String(e.message??"").toLowerCase().includes("xcodebuild exited early")}function ow(e){let{port:t,endpoints:n,logPath:r,lastError:i}=e,a="Runner did not accept connection";return new N("COMMAND_FAILED",a,{port:t,endpoints:n,logPath:r,lastError:i?String(i):void 0,reason:n0({error:i,message:a,context:{platform:"ios",phase:"connect"}}),hint:n1("IOS_RUNNER_CONNECT_TIMEOUT")})}async function og(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=n0({message:l,stdout:s.stdout,stderr:s.stderr,context:{platform:"ios",phase:"connect"}});return new N("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}
23
+ ${t}
24
+ ${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.":n1("IOS_RUNNER_CONNECT_TIMEOUT"))})}function oy(e){if(oc(e))throw of()}let ov=rp(process.env.AGENT_DEVICE_RUNNER_STARTUP_TIMEOUT_MS,45e3,5e3),oI=rp(process.env.AGENT_DEVICE_RUNNER_COMMAND_TIMEOUT_MS,45e3,1e3),ob=rp(process.env.AGENT_DEVICE_RUNNER_CONNECT_ATTEMPT_INTERVAL_MS,250,50),oA=rp(process.env.AGENT_DEVICE_RUNNER_CONNECT_RETRY_BASE_DELAY_MS,300,10),oS=rp(process.env.AGENT_DEVICE_RUNNER_CONNECT_RETRY_MAX_DELAY_MS,2e3,10),ox=rp(process.env.AGENT_DEVICE_RUNNER_CONNECT_REQUEST_TIMEOUT_MS,2e4,250),o_=rp(process.env.AGENT_DEVICE_IOS_DEVICE_INFO_TIMEOUT_MS,1e4,500),oN=rp(process.env.AGENT_DEVICE_RUNNER_DESTINATION_TIMEOUT_SECONDS,20,5);async function oD(e,t,n,r,i=ov,a,o){let s=nK.fromTimeoutMs(i),l=await oE(e,t,s.remainingMs()),u=null,d=Math.max(1,Math.ceil(i/ob));try{return await nY(async({deadline:s})=>{if(s?.isExpired())throw new N("COMMAND_FAILED","Runner connection deadline exceeded",{port:t,timeoutMs:i});if(a&&null!==a.child.exitCode&&void 0!==a.child.exitCode)throw await og({session:a,port:t,logPath:r});for(let r of("device"===e.kind&&(l=await oE(e,t,s?.remainingMs())),l))try{let e=s?.remainingMs()??i;if(e<=0)throw new N("COMMAND_FAILED","Runner connection deadline exceeded",{port:t,timeoutMs:i});return await oC(r,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)},Math.min(ox,e),o)}catch(e){if(o?.aborted||om(e))throw of();u=e}throw new N("COMMAND_FAILED","Runner endpoint probe failed",{port:t,endpoints:l,lastError:u?String(u):void 0})},{maxAttempts:d,baseDelayMs:oA,maxDelayMs:oS,jitter:.2,shouldRetry:oh},{deadline:s,phase:"ios_runner_connect",signal:o})}catch(e){if(o?.aborted||om(e))throw of();u||(u=e)}if(o?.aborted)throw of();if("simulator"===e.kind){let i=s.remainingMs();if(i<=0)throw ow({port:t,endpoints:l,logPath:r,lastError:u});let a=await oO(e,t,n,i);return new Response(a.body,{status:a.status})}throw ow({port:t,endpoints:l,logPath:r,lastError:u})}async function oE(e,t,n){let r=[`http://127.0.0.1:${t}/command`];if("device"!==e.kind)return r;let i=await oM(e.id,n);return i&&r.unshift(`http://[${i}]:${t}/command`),r}async function oC(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 oM(e,t){if("number"==typeof t&&t<=0)return null;let n="number"==typeof t?Math.max(1,Math.min(o_,t)):o_,i=o.join(p.tmpdir(),`agent-device-devicectl-info-${process.pid}-${Date.now()}.json`);try{let t=Math.max(1,Math.ceil(n/1e3)),a=await D("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{ok(i)}}async function oO(e,t,n,r){let i=JSON.stringify(n),a=nt(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 D("xcrun",a,{allowFailure:!0,timeoutMs:r}),s=o.stdout;if(0!==o.exitCode){let e=n0({message:"Runner did not accept connection (simctl spawn)",stdout:o.stdout,stderr:o.stderr,context:{platform:"ios",phase:"connect"}});throw new N("COMMAND_FAILED","Runner did not accept connection (simctl spawn)",{port:t,stdout:o.stdout,stderr:o.stderr,exitCode:o.exitCode,reason:e,hint:n1(e)})}return{status:200,body:s}}async function oL(){return await new Promise((e,t)=>{let n=w.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 N("COMMAND_FAILED","Failed to allocate port")))}),n.on("error",t)})}function oT(e,t,n,i){t&&r.appendFile(t,e,()=>{}),n&&r.appendFile(n,e,()=>{}),i&&process.stderr.write(e)}function ok(e){try{r.existsSync(e)&&r.unlinkSync(e)}catch{}}let oR=new u;async function oP(e,t,n){let r=oR.getStore()??[];if(r.some(n=>n.locks===e&&n.key===t))return await n();let i=(e.get(t)??Promise.resolve()).catch(()=>{}).then(()=>oR.run([...r,{locks:e,key:t}],n));return e.set(t,i),i.finally(()=>{e.get(t)===i&&e.delete(t)})}let o$=new Set(["RUNNER_PRODUCT_MISSING","RUNNER_PRODUCT_REPAIR_FAILED"]);async function oF(e,t,n){if("macos"!==e.platform)return;if(0===t.length)throw new N("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 N("COMMAND_FAILED","Missing macOS runner product",{reason:"RUNNER_PRODUCT_MISSING",productPath:e,xctestrunPath:n});for(let e of i)if(0!==E("codesign",["--verify","--deep","--strict",e],{allowFailure:!0}).exitCode){await D("codesign",["--remove-signature",e],{allowFailure:!0});try{await D("codesign",["--force","--sign","-",e])}catch(r){let t=r instanceof N?r:new N("COMMAND_FAILED",String(r));throw new N("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 oU="XCTestDevices",oG=".agent-device-backup",oV=".agent-device-xctestdevices-backup-",oB=o.join(p.homedir(),".agent-device","ios-runner"),oj=new Set(["ProductPaths","DependentProductPaths","TestHostPath","TestBundlePath","UITargetAppPath"]),oq=new Map,oW=new Set;function oz(e){return e?.trim()??""}function oH(e=process.env){return oz(e.AGENT_DEVICE_IOS_BUNDLE_ID)||oz(e.AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID)||"com.callstack.agentdevice.runner"}function oJ(e=process.env){let t=oz(e.AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID);return t||`${oH(e)}.uitests`}let oX=function(e=process.env){let t=oH(e),n=oJ(e);return Array.from(new Set([oz(e.AGENT_DEVICE_IOS_RUNNER_CONTAINER_BUNDLE_ID),`${n}.xctrunner`,t].filter(e=>e.length>0)))}(process.env);function oK(e=p.homedir()){return o.join(e,"Library","Developer","XCTestDevices")}async function oY(e,t={}){if("ios"!==e.platform||"simulator"!==e.kind)return null;let n=t6(e.simulatorSetPath);if(!n)return null;let i=o.resolve(n),a=o.resolve(t.xctestDeviceSetPath??oK()),s=o.resolve(t.backupPath??function(e=oK()){return`${e}${oG}`}(a)),l=o.resolve(t.lockDirPath??function(e=p.homedir()){return o.join(e,".agent-device","xctest-device-set.lock")}()),u=t.ownerStartTime??eC(process.pid),d=await o0({lockDirPath:l,owner:{pid:t.ownerPid??process.pid,startTime:u,acquiredAtMs:t.nowMs??Date.now()}});try{if(oZ({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 d(),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,`${oU}.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)&&oQ(a),e}}({requestedSetPath:i,xctestDeviceSetPath:a})}catch(e){throw oZ({xctestDeviceSetPath:a,backupPath:s}),await d(),new N("COMMAND_FAILED","Failed to redirect XCTest device set path",{requestedSetPath:i,xctestDeviceSetPath:a,backupPath:s,error:String(e)})}let c=!1;return{release:async()=>{if(!c){c=!0;try{oZ({xctestDeviceSetPath:a,backupPath:s})}finally{await d()}}}}}function oZ(e){let{xctestDeviceSetPath:t,backupPath:n}=e,i=[n,...function(e){let t=o.dirname(e),n=o.basename(e).replace(oG,""),i=n===oU?oV:`${n}${oV}`;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&&oQ(t),r.existsSync(t))if(!s)return void ex({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&&(ex({level:"warn",phase:"ios_runner_xctest_device_set_orphaned_symlink",data:{xctestDeviceSetPath:t}}),oQ(t))}function oQ(e){!r.existsSync(e)||r.lstatSync(e).isSymbolicLink()&&r.unlinkSync(e)}async function o0(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)&&eE(a.pid)&&(!a.startTime||eC(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 N("COMMAND_FAILED","Timed out waiting for XCTest device set lock",{lockDirPath:t})}async function o1(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(oB,"derived","macos"):"simulator"===n.kind?o.join(oB,"derived"):o.join(oB,"derived",n.kind)),s=function(){let e=o.dirname(l(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 oP(oq,a,async()=>{nz(process.env.AGENT_DEVICE_IOS_CLEAN_DERIVED)&&(sr("clean","forced_clean",{derived:a}),sn(a),o2(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:s,findXctestrun:t=>o4(t,e),xctestrunReferencesProjectRoot:o8,resolveExistingXctestrunProductPaths:si});if("reuse_ready"!==n.reason&&sr("rebuild",n.reason,{derived:a,xctestrunPath:n.xctestrunPath}),"reuse_ready"===n.reason)try{return await oF(e,n.productPaths,n.xctestrunPath),sr("reuse","reuse_ready",{derived:a,xctestrunPath:n.xctestrunPath}),n.xctestrunPath}catch(e){if(!function(e){if(!(e instanceof N))return!1;let t=e.details&&"object"==typeof e.details?e.details.reason:void 0;return"string"==typeof t&&o$.has(t)}(e))throw e;sr("rebuild","repair_failed",{derived:a,xctestrunPath:n.xctestrunPath})}n.xctestrunPath&&(sn(a),o2(a));let i=o.join(s,"ios-runner","AgentDeviceRunner","AgentDeviceRunner.xcodeproj");if(!r.existsSync(i))throw new N("COMMAND_FAILED","iOS runner project not found",{projectPath:i});await o9(e,i,a,t);let l=o4(a,e);if(!l)throw new N("COMMAND_FAILED","Failed to locate .xctestrun after build");let u=si(l);if(!u)throw new N("COMMAND_FAILED","Runner build is missing expected products",{xctestrunPath:l});return await oF(e,u,l),sr("build","built_new",{derived:a,xctestrunPath:l}),l})}function o2(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,o3.has(t)&&r.rmSync(o.join(e,n.name),{recursive:!0,force:!0})}}catch{}}let o3=new Set(["Build","BuildCache.noindex","Index.noindex","Logs","ModuleCache.noindex","SDKStatCaches.noindex","SourcePackages","TextBasedInstallAPI","info.plist"]);function o4(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=o5(n.path,t)-o5(e.path,t);if(0!==r)return r}return n.mtimeMs-e.mtimeMs||e.path.localeCompare(n.path)}),n[0]?.path??null)}function o5(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 o8(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 o6(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 D("plutil",["-convert","json","-o","-",e],{allowFailure:!0});if(0!==d.exitCode||!d.stdout.trim())throw new N("COMMAND_FAILED","Failed to read xctestrun plist",{xctestrunPath:e,stderr:d.stderr});try{i=JSON.parse(d.stdout)}catch(t){throw new N("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 D("plutil",["-convert","xml1","-o",u,l],{allowFailure:!0});if(0!==f.exitCode)throw new N("COMMAND_FAILED","Failed to write xctestrun plist",{tmpXctestrunPath:u,stderr:f.stderr});return{xctestrunPath:u,jsonPath:l}}async function o9(e,t,n,r){let i=function(e=process.env){let t=oH(e),n=oJ(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 oY(e);try{var l;let s;await A("xcodebuild",["build-for-testing","-project",t,"-scheme","AgentDeviceRunner","-parallel-testing-enabled","NO",st(e),"1","-destination",(l=e,s=o7(l),"macOS"===s?`platform=macOS,arch=${se()}`:"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=>{oW.add(e),e.on("close",()=>{oW.delete(e)})},onStdoutChunk:e=>{oT(e,r.logPath,r.traceLogPath,r.verbose)},onStderrChunk:e=>{oT(e,r.logPath,r.traceLogPath,r.verbose)}})}catch(a){let e,t,n=a instanceof N?a:new N("COMMAND_FAILED",String(a)),i=(e=n.details?JSON.stringify(n.details):"",(t=`${n.message}
25
+ ${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 N("COMMAND_FAILED","xcodebuild build-for-testing failed",{error:n.message,details:n.details,logPath:r.logPath,hint:i})}finally{await s?.release()}}function o7(e){var t;if("ios"!==e.platform&&"macos"!==e.platform)throw new N("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 se(){return"arm64"===process.arch?"arm64":"x86_64"}function st(e){return"macos"===e.platform||"device"===e.kind?"-maximum-concurrent-test-device-destinations":"-maximum-concurrent-test-simulator-destinations"}function sn(e,t=process.env){if(t.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim()&&!function(e=process.env){return nz(e.AGENT_DEVICE_IOS_ALLOW_OVERRIDE_DERIVED_CLEAN)}(t))throw new N("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 sr(e,t,n){ex({level:"rebuild"===e?"warn":"info",phase:"runner_xctestrun_cache",data:{action:e,reason:t,...n}})}function si(e){let t=function(e){let t=function(e){try{let t=E("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=a_(n),t=new Set,aN(i,(e,n)=>{if(oj.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 sa=new Map,so=new Map;async function ss(e,t){return await oP(so,e.id,async()=>{var n;let r,i,a=sa.get(e.id);if(a){if(function(e){return!!e&&eE(e)}(a.child.pid))return a;await sc(e.id,a)}await ("simulator"!==(n=e).kind?Promise.resolve():sw(n)),await sl(e);let o=await o1(e,t),s=await oL(),{xctestrunPath:l,jsonPath:u}=await o6(o,{AGENT_DEVICE_RUNNER_PORT:String(s)},`session-${e.id}-${s}`),d=await oY(e);try{let t;({child:r,wait:i}=_("xcodebuild",["test-without-building","-only-testing","AgentDeviceRunnerUITests/RunnerTests/testCommand","-parallel-testing-enabled","NO","-test-timeouts-enabled","NO","-collect-test-diagnostics","never",st(e),"1","-destination-timeout",String(oN),"-xctestrun",l,"-destination",(t=o7(e),"macOS"===t?`platform=macOS,arch=${se()}`:"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=>{oT(e,t.logPath,t.traceLogPath,t.verbose)}),r.stderr?.on("data",e=>{oT(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 sa.set(e.id,c),c})}async function sl(e){if("simulator"===e.kind)for(let t of oX){let n=await D("xcrun",nt(e,["uninstall",e.id,t]),{allowFailure:!0});if(0!==n.exitCode){let e=`${n.stdout}
26
+ ${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 su(e){let t=sa.get(e);return t?{sessionId:t.sessionId,alive:function(e){return!!e&&eE(e)}(t.child.pid)}:null}async function sd(e){await oP(so,e.deviceId,async()=>{await sc(e.deviceId,e)})}async function sc(e,t){let n=t??sa.get(e);if(n){try{await oD(n.device,n.port,{command:"shutdown"},void 0,15e3)}catch{await sh(n.child.pid,"SIGTERM")}try{await Promise.race([n.testPromise,new Promise(e=>setTimeout(e,1e4))])}catch{}await sh(n.child.pid,"SIGKILL"),ok(n.xctestrunPath),ok(n.jsonPath),await n.simulatorSetRedirect?.release(),sa.get(e)===n&&sa.delete(e)}}async function sp(e){await oP(so,e,async()=>{await sc(e)})}async function sf(){let e=Array.from(sa.values()),t=Array.from(oW);await Promise.allSettled(e.map(async e=>{await sh(e.child.pid,"SIGINT")})),await Promise.allSettled(t.map(async e=>{await sh(e.pid,"SIGINT")})),await Promise.allSettled(e.map(async e=>{await sh(e.child.pid,"SIGTERM")})),await Promise.allSettled(t.map(async e=>{await sh(e.pid,"SIGTERM")})),await Promise.allSettled(e.map(async e=>{await sh(e.child.pid,"SIGKILL")})),await Promise.allSettled(t.map(async e=>{await sh(e.pid,"SIGKILL"),oW.delete(e)})),await Promise.allSettled(e.map(async e=>{await e.simulatorSetRedirect?.release()}))}async function sm(){await sf();let e=Array.from(sa.keys());await Promise.allSettled(e.map(async e=>{await sp(e)}));let t=Array.from(oW);await Promise.allSettled(t.map(async e=>{try{await sh(e.pid,"SIGTERM"),await sh(e.pid,"SIGKILL")}finally{oW.delete(e)}}))}async function sh(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 D("pkill",[`-${n}`,"-P",String(e)],{allowFailure:!0})}catch{}}async function sw(e){await D("xcrun",nt(e,["bootstatus",e.id,"-b"]),{timeoutMs:ov})}async function sg(e,t,n,r,i,a){let o=await oD(e,t.port,n,r,i,t,a);return await sy(o,t,r)}async function sy(e,t,n){let r=await e.text(),i={};try{i=JSON.parse(r)}catch{throw new N("COMMAND_FAILED","Invalid runner response",{text:r})}if(!i.ok)throw new N("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 sv(e,t,n={}){var r;if("ios"!==e.platform&&"macos"!==e.platform)throw new N("UNSUPPORTED_PLATFORM",`Unsupported platform for iOS runner: ${e.platform}`);if("simulator"!==e.kind&&"device"!==e.kind)throw new N("UNSUPPORTED_OPERATION",`Unsupported iOS device kind for runner: ${e.kind}`);return(oy(n.requestId),"interactionFrame"===(r=t.command)||"snapshot"===r||"screenshot"===r||"findText"===r||"readText"===r||"alert"===r||"uptime"===r)?nZ(()=>(oy(n.requestId),sI(e,t,n)),{shouldRetry:e=>{oy(n.requestId);if(!(e instanceof N)||"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"))}}):sI(e,t,n)}async function sI(e,t,n={}){let r;oy(n.requestId);let i=op(n.requestId);try{let a=(r=await ss(e,n)).ready?oI:ov;return await sg(e,r,t,n.logPath,a,i)}catch(o){let a=o instanceof N?o:new N("COMMAND_FAILED",String(o));if("COMMAND_FAILED"===a.code&&"string"==typeof a.message&&a.message.includes("Runner did not accept connection")&&oh(a)&&r?.ready){oy(n.requestId),r?await sd(r):await sp(e.id),r=await ss(e,n);let a=await oD(r.device,r.port,t,n.logPath,ov,void 0,i);return await sy(a,r,n.logPath)}throw o}}let sb=["--time","9:41","--dataNetwork","wifi","--wifiMode","active","--wifiBars","3","--batteryState","charged","--batteryLevel","100"],sA={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"},sS={1:"searching",2:"failed",3:"active"},sx={0:"notSupported",1:"searching",2:"failed",3:"active"};function s_(e,t,n){return D("xcrun",nt(e,t),n)}async function sN(e,t){var n,r;let i;await sE(e),t&&await sC(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 sD(e){let t=await s_(e,["status_bar",e.id,"list"],{allowFailure:!0});if(0!==t.exitCode)throw new N("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=sA[n];if(!r)throw new N("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=sS[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=sx[e];if(!n)throw new N("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 sE(e){await s_(e,["status_bar",e.id,"clear"])}async function sC(e,t){0!==t.length&&await s_(e,["status_bar",e.id,"override",...t])}function sM(e,t,n){ex({level:"warn",phase:`ios_screenshot_status_bar_${t}`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,...function(e){if(!(e instanceof N))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 sO(e,t,n){return D("xcrun",nt(e,t),n)}let sL={ensureBooted:ab,prepareStatusBarForScreenshot:async function e(e){let t=null,n=!1;try{t=await sD(e),n=!0}catch(t){sM(e,"snapshot_failed",t)}try{await sE(e),await sC(e,sb)}catch(t){sM(e,"prepare_failed",t)}return async()=>{await sN(e,n?t:null)}},captureWithRetry:sR,runnerFallbackEnabled:ac,captureWithRunner:sP,shouldFallbackToRunner:sj};async function sT(e,t,n,r){if("macos"===e.platform)return void await sP(e,t,n,r);if("simulator"===e.kind)return void await sk(e,t,n,r);try{await ap(["device","screenshot","--device",e.id,t],{action:"capture iOS screenshot",deviceId:e.id});return}catch(t){if(!function(e){if(!(e instanceof N)||"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}
27
+ ${n}
28
+ ${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;sG(e,"devicectl_screenshot",t)}await sP(e,t,n,r)}async function sk(e,t,n,r,i=sL){if("simulator"!==e.kind)throw new N("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){sV(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=sB(l),ex({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 N?u:new N("COMMAND_FAILED","Failed to capture iOS screenshot: simulator screenshot retries exhausted",void 0,u),new N(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)}sG(e,"simctl_screenshot",t)}await a.captureWithRunner(e,t,n,"boolean"==typeof r?r:void 0)}finally{await o().catch(t=>sV(e,"restore_failed",t))}}async function sR(e,t){let n=nK.fromTimeoutMs(au);await nY(async({deadline:n})=>{await sO(e,["io",e.id,"screenshot",t],{timeoutMs:Math.max(1e3,n?.remainingMs()??au)})},{maxAttempts:5,baseDelayMs:1e3,maxDelayMs:5e3,jitter:.2,shouldRetry:e=>sj(e)},{deadline:n,phase:"ios_simulator_screenshot"})}async function sP(e,t,n,r){let i=(await sv(e,{command:"screenshot",appBundleId:n,fullscreen:r})).message;if(!i)throw new N("COMMAND_FAILED","Failed to capture iOS screenshot: runner returned no file path");"macos"===e.platform?await a.copyFile(i,t):"simulator"===e.kind?await sF(e,i,t):await s$(e,i,t)}async function s$(e,t,n){let r=nK.fromTimeoutMs(ad),i={exitCode:1,stdout:"",stderr:""};for(let a of oX)if(0===(i=await D("xcrun",["devicectl","device","copy","from","--device",e.id,"--source",t,"--destination",n,"--domain-type","appDataContainer","--domain-identifier",a],{allowFailure:!0,timeoutMs:sU(r,ad,"runner screenshot copy")})).exitCode)return;let a=i.stderr.trim()||i.stdout.trim()||`devicectl exited with code ${i.exitCode}`;throw new N("COMMAND_FAILED",`Failed to capture iOS screenshot: ${a}`)}async function sF(e,t,n){let r=nK.fromTimeoutMs(ad),i="Unable to locate runner container for simulator screenshot";for(let s of oX){let l=await sO(e,["get_app_container",e.id,s,"data"],{allowFailure:!0,timeoutMs:sU(r,ad,"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 N("COMMAND_FAILED",`Failed to capture iOS screenshot: ${i}`)}function sU(e,t,n){let r=e.remainingMs();if(r>0)return r;throw new N("COMMAND_FAILED",`iOS ${n} timed out after ${t}ms`,{timeoutMs:t,step:n})}function sG(e,t,n){let r=sB(n);ex({level:"warn",phase:"ios_screenshot_fallback",data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,from:t,to:"runner",...r}})}function sV(e,t,n){ex({level:"warn",phase:`ios_screenshot_status_bar_${t}`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,...sB(n)}})}function sB(e){if(!(e instanceof N))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 sj(e){if(!(e instanceof N)||"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}
29
+ ${n}
30
+ ${r}
31
+ ${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 sq={settings:"com.apple.Preferences"},sW=null;function sz(e,t,n){return D("xcrun",nt(e,t),n)}function sH(e){return e.includes("not installed")||e.includes("not found")||e.includes("no such file")}async function sJ(e,t){if("macos"===e.platform)return await a5(t);let n=t.trim();if(n.includes("."))return n;let r=sq[n.toLowerCase()];if(r)return r;let i=("simulator"===e.kind?await s6(e):await af(e,"all")).filter(e=>e.name.toLowerCase()===n.toLowerCase());if(1===i.length)return i[0].bundleId;if(i.length>1)throw new N("INVALID_ARGS",`Multiple apps matched "${t}"`,{matches:i});throw new N("APP_NOT_INSTALLED",`No app found matching "${t}"`)}async function sX(e,t,n){if("macos"===e.platform)return void await a8(e,t,n);let r=n?.url?.trim();if(r){if(!nj(r))throw new N("INVALID_ARGS","open <app> <url> requires a valid URL target");if("simulator"===e.kind){await ab(e),await sz(e,["openurl",e.id,r]);return}let i=nq(n?.appBundleId??await sJ(e,t),r);if(!i)throw new N("INVALID_ARGS","Deep link open on iOS devices requires an active app bundle ID. Open the app first, then open the URL.");await lo(e,i,{payloadUrl:r});return}let i=t.trim();if(nj(i)){if("simulator"===e.kind){await ab(e),await sz(e,["openurl",e.id,i]);return}let t=nq(n?.appBundleId,i);if(!t)throw new N("INVALID_ARGS","Deep link open on iOS devices requires an active app bundle ID. Open the app first, then open the URL.");await lo(e,t,{payloadUrl:i});return}let a=n?.appBundleId??await sJ(e,t);"simulator"===e.kind?await la(e,a):await lo(e,a)}async function sK(e){"macos"===e.platform||"simulator"!==e.kind||"Booted"!==await aS(e)&&await ab(e)}async function sY(e,t){if("macos"===e.platform)return void await a6(e,t);let n=await sJ(e,t);if("simulator"===e.kind){await ab(e);let t=nt(e,["terminate",e.id,n]),r=await D("xcrun",t,{allowFailure:!0});if(0!==r.exitCode){if(r.stderr.toLowerCase().includes("found nothing to terminate"))return;throw new N("COMMAND_FAILED",`xcrun exited with code ${r.exitCode}`,{cmd:"xcrun",args:t,stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode})}return}await ap(["device","process","terminate","--device",e.id,n],{action:"terminate iOS app",deviceId:e.id})}async function sZ(e,t){let n=await sJ(e,t);if("simulator"!==e.kind){let t=["devicectl","device","uninstall","app","--device",e.id,n],r=await D("xcrun",t,{allowFailure:!0,timeoutMs:as});if(0!==r.exitCode){let i=String(r.stdout??""),a=String(r.stderr??"");if(!sH(`${i}
32
+ ${a}`.toLowerCase()))throw new N("COMMAND_FAILED",`Failed to uninstall iOS app ${n}`,{cmd:"xcrun",args:t,exitCode:r.exitCode,stdout:i,stderr:a,deviceId:e.id,hint:aw(i,a)??ah})}return{bundleId:n}}await ab(e);let r=await sz(e,["uninstall",e.id,n],{allowFailure:!0});if(0!==r.exitCode&&!sH(`${r.stdout}
33
+ ${r.stderr}`.toLowerCase()))throw new N("COMMAND_FAILED",`simctl uninstall failed for ${n}`,{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode});return{bundleId:n}}async function sQ(e,t,n){let r=await aC({kind:"path",path:t},n);try{return await s1(e,r.installablePath),{archivePath:r.archivePath,installablePath:r.installablePath,bundleId:r.bundleId,appName:r.appName,launchTarget:r.bundleId}}finally{await r.cleanup()}}async function s0(e,t,n){let{bundleId:r}=await sZ(e,t);return await sQ(e,n,{appIdentifierHint:t}),{bundleId:r}}async function s1(e,t){"simulator"!==e.kind?await ap(["device","install","app","--device",e.id,t],{action:"install iOS app",deviceId:e.id}):(await ab(e),await sz(e,["install",e.id,t]))}async function s2(e){if("macos"===e.platform)return await a9();av(e,"clipboard"),await ab(e);let t=await sz(e,["pbpaste",e.id],{allowFailure:!0});if(0!==t.exitCode)throw new N("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 s3(e,t){if("macos"===e.platform)return void await a7(t);av(e,"clipboard"),await ab(e);let n=await sz(e,["pbcopy",e.id],{allowFailure:!0,stdin:t});if(0!==n.exitCode)throw new N("COMMAND_FAILED","Failed to write iOS simulator clipboard",{stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode})}async function s4(e,t,n){av(e,"push"),await ab(e);let r=await a.mkdtemp(o.join(p.tmpdir(),"agent-device-ios-push-")),i=o.join(r,"payload.apns");try{await a.writeFile(i,`${JSON.stringify(n)}
34
+ `,"utf8"),await sz(e,["push",e.id,t,i])}finally{await a.rm(r,{recursive:!0,force:!0})}}async function s5(e,t,n,r,i){if("macos"===e.platform){let e=t.toLowerCase();if("appearance"===e)return void await ot(n);if("permission"===e){let e=iZ(n);if("deny"===e)throw new N("INVALID_ARGS",q("permission"));let t=function(e){let t=e?.trim().toLowerCase();if("accessibility"===t||"screen-recording"===t||"input-monitoring"===t)return t;throw new N("INVALID_ARGS","Unsupported macOS permission target. Use accessibility|screen-recording|input-monitoring.")}(i?.permissionTarget);return await aX(e,t)}throw new N("INVALID_ARGS",q(t))}av(e,"settings"),await ab(e);let a=t.toLowerCase();switch(a){case"wifi":{let t=s9(n);await sz(e,["status_bar",e.id,"override","--wifiMode",t?"active":"failed"]);return}case"airplane":return void(s9(n)?await sz(e,["status_bar",e.id,"override","--dataNetwork","hide","--wifiMode","failed","--wifiBars","0","--cellularMode","failed","--cellularBars","0","--operatorName",""]):await sz(e,["status_bar",e.id,"clear"]));case"location":{let t=s9(n);if(!r)throw new N("INVALID_ARGS","location setting requires an active app in session");await sz(e,["privacy",e.id,t?"grant":"revoke","location",r]);return}case"faceid":case"touchid":{let t=le[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 N("INVALID_ARGS",`Invalid ${t} state: ${e}. Use match|nonmatch|enroll|unenroll.`)}(n,a);await li(e,r,{settingName:a,label:t.label,modalityAliases:t.modalityAliases});return}case"appearance":{let t=await s7(e,n);await sz(e,["ui",e.id,"appearance",t]);return}case"permission":{var o;if(!r)throw new N("INVALID_ARGS","permission setting requires an active app in session");let t="deny"===(o=iZ(n))?"revoke":o,a=function(e,t){let n=iQ(e);if("photos"!==n&&t?.trim())throw new N("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 N("INVALID_ARGS",`Invalid photos mode: ${t}. Use full|limited.`)}throw new N("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 lt(e,t,a,r);return}default:throw new N("INVALID_ARGS",`Unsupported setting: ${t}`)}}async function s8(e,t="all"){return"macos"===e.platform?await on(t):"simulator"===e.kind?ak(await s6(e),t):await af(e,t)}async function s6(e){let t=(await sz(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 D("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 s9(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 N("INVALID_ARGS",`Invalid setting state: ${e}`)}async function s7(e,t){let n=i0(t);if("toggle"!==n)return n;let r=await sz(e,["ui",e.id,"appearance"],{allowFailure:!0});if(0!==r.exitCode)throw new N("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}
35
+ ${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 N("COMMAND_FAILED","Unable to determine current iOS appearance for toggle",{stdout:r.stdout,stderr:r.stderr});return"dark"===i?"light":"dark"}let le={faceid:{label:"Face ID",modalityAliases:["face"]},touchid:{label:"Touch ID",modalityAliases:["finger","touch"]}};async function lt(e,t,n,r){let i=await lr(e);if(!i.has(n))throw new N("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 sz(e,a);return}catch(t){if(!(o&&ln(t)))throw t;throw new N("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 sz(e,a);return}catch(e){if(!ln(e))throw e}try{await sz(e,["privacy",e.id,"reset","all",r])}catch(t){throw new N("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 ln(e){if(!(e instanceof N)||"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 lr(e){let n=t6(e.simulatorSetPath),r=`${process.env.PATH??""}::${n??""}`;if(sW&&t===r)return sW;let i=await sz(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}
36
+ ${i.stderr}`);if(0===a.size)throw new N("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 sW=a,t=r,a}async function li(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=nt(e,t),r=await D("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}
37
+ ${n}`.toLowerCase()).includes("unrecognized subcommand")||r.includes("unknown subcommand")||r.includes("not supported")||r.includes("unavailable")||r.includes("biometric")&&r.includes("invalid")}))throw new N("UNSUPPORTED_OPERATION",`${n.label} simulation is not supported on this simulator runtime.`,{deviceId:e.id,action:t,setting:n.settingName,attempts:a});throw new N("COMMAND_FAILED",`Failed to simulate ${n.settingName}.`,{deviceId:e.id,action:t,setting:n.settingName,attempts:a})}async function la(e,t){await ab(e);let n=0,r=nK.fromTimeoutMs(ao);try{await nY(async({deadline:n})=>{var r;if(n?.isExpired())throw new N("COMMAND_FAILED","App launch deadline exceeded",{timeoutMs:ao});let i=(r=["launch",e.id,t],nt(e,r)),a=await D("xcrun",i,{allowFailure:!0});if(0!==a.exitCode)throw new N("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=>!!ag(e)&&(n+=1)<3},{deadline:r})}catch(n){if(ag(n)){var i;let r=(i=await ay(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 lo(e,t,n){let r=["device","process","launch","--device",e.id,t];n?.payloadUrl&&r.push("--payload-url",n.payloadUrl),await ap(r,{action:"launch iOS app",deviceId:e.id})}async function ls(e,t,n,r,i,a,o){if("tv"===t.target)return ld(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 ll(e,t,n,r),l=io({direction:i,amount:a?.amount,pixels:a?.pixels,referenceWidth:s.referenceWidth,referenceHeight:s.referenceHeight});return ld(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 ll(e,t,n,r){let i=await e(t,{command:"interactionFrame",appBundleId:n.appBundleId},r),a=lu(i.x),o=lu(i.y),s=lu(i.referenceWidth),l=lu(i.referenceHeight);if(void 0===a||void 0===o||void 0===s||void 0===l)throw new N("COMMAND_FAILED","interactionFrame did not return a usable frame");return{originX:a,originY:o,referenceWidth:s,referenceHeight:l}}function lu(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function ld(e,t){var n;let{x1:r,y1:i,x2:a,y2:o}={x1:lu((n=e).x),y1:lu(n.y),x2:lu(n.x2),y2:lu(n.y2)},s=lu(e.referenceWidth),l=lu(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 lc(){return process.env.WAYLAND_DISPLAY||"wayland"===process.env.XDG_SESSION_TYPE?"wayland":"x11"}let lp=null;async function lf(){if(lp)return lp;let e=lc();if("wayland"===e){if(await M("ydotool"))return lp={tool:"ydotool",display:e};throw new N("TOOL_MISSING","ydotool is required for input synthesis on Wayland (xdotool does not work on Wayland). Install it via your package manager.")}if(await M("xdotool"))return lp={tool:"xdotool",display:e};throw new N("TOOL_MISSING","xdotool is required for input synthesis on X11. Install it via your package manager.")}async function lm(...e){await D("xdotool",e,{allowFailure:!1,timeoutMs:1e4})}async function lh(...e){await D("ydotool",e,{allowFailure:!1,timeoutMs:1e4})}async function lw(e,t){let{tool:n}=await lf();"xdotool"===n?await lm("mousemove","--sync",String(e),String(t)):await lh("mousemove","--absolute","-x",String(e),"-y",String(t))}async function lg(e,t){let{tool:n}=await lf();"xdotool"===n?await lm("key","--clearmodifiers",e):await lh("key",...t)}async function ly(e,t,n,r){await lw(e,t);let{tool:i}=await lf();"xdotool"===i?await lm("click",n):await lh("click",r)}async function lv(e,t){await ly(e,t,"1","0xC0")}async function lI(e,t){await ly(e,t,"3","0xC1")}async function lb(e,t){await ly(e,t,"2","0xC2")}async function lA(e,t){let{tool:n}=await lf();await lw(e,t),"xdotool"===n?await lm("click","--repeat","2","1"):(await lh("click","0xC0"),await lh("click","0xC0"))}async function lS(e,t,n=800){let{tool:r}=await lf();await lw(e,t),"xdotool"===r?(await lm("mousedown","1"),await lC(n),await lm("mouseup","1")):(await lh("click","--down","0xC0"),await lC(n),await lh("click","--up","0xC0"))}async function lx(e,t){await lv(e,t)}async function l_(e,t,n,r,i=300){let{tool:a}=await lf();await lw(e,t),"xdotool"===a?(await lm("mousedown","1"),await lm("mousemove","--sync",String(n),String(r)),await lC(i),await lm("mouseup","1")):(await lh("click","--down","0xC0"),await lh("mousemove","--absolute","-x",String(n),"-y",String(r)),await lC(i),await lh("click","--up","0xC0"))}async function lN(e,t){let{tool:n}=await lf(),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 lm("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 lh("mousemove","--wheel","-y",t)}else{let t="left"===e?String(-r):String(r);await lh("mousemove","--wheel","-x",t)}}async function lD(e,t=0){let{tool:n}=await lf();if("xdotool"===n){let n=["type"];t>0&&n.push("--delay",String(t)),n.push("--clearmodifiers","--",e),await lm(...n)}else await lh("type","--",e)}async function lE(e,t,n,r=0){await lv(e,t),await lC(100),await lg("ctrl+a",["29:1","30:1","30:0","29:0"]),await lC(50),await lD(n,r)}function lC(e){return new Promise(t=>setTimeout(t,e))}function lM(e){let t=null;return{resolve:async function(){if(t)return t;let n="wayland"===lc()?"wayland":"x11";for(let r of"wayland"===n?e.wayland:e.x11)if(await M(r.command))return t={tool:r.tool,display:n};throw new N("TOOL_MISSING","wayland"===n?e.waylandError:e.x11Error)},resetCache:()=>{t=null}}}let lO=lM({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 lL(e){let{tool:t}=await lO.resolve();switch(t){case"grim":await D("grim",[e]);break;case"scrot":await D("scrot",[e]);break;case"import":await D("import",["-window","root",e]);break;case"gnome-screenshot":await D("gnome-screenshot",["-f",e])}}async function lT(e){if(e.includes("://")||e.startsWith("/"))return void await D("xdg-open",[e]);if(await M(e)){D(e,[],{allowFailure:!0}).catch(t=>{ex({level:"warn",phase:"linux_app_launch",data:{app:e,error:String(t)}})}),await new Promise(e=>setTimeout(e,500));return}await D("xdg-open",[e],{allowFailure:!0})}async function lk(e){await M("wmctrl")?await D("wmctrl",["-c",e],{allowFailure:!0}):await D("pkill",["-x",e],{allowFailure:!0})}async function lR(){await lg("alt+Left",["56:1","105:1","105:0","56:0"])}async function lP(){await lg("super+d",["125:1","32:1","32:0","125:0"])}let l$=lM({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 lF(){let{tool:e}=await l$.resolve();switch(e){case"wl-clipboard":return(await D("wl-paste",["--no-newline"],{allowFailure:!0,timeoutMs:5e3})).stdout;case"xclip":return(await D("xclip",["-selection","clipboard","-o"],{allowFailure:!0,timeoutMs:5e3})).stdout;case"xsel":return(await D("xsel",["--clipboard","--output"],{allowFailure:!0,timeoutMs:5e3})).stdout}}async function lU(e){let{tool:t}=await l$.resolve();switch(t){case"wl-clipboard":await D("wl-copy",["--",e],{allowFailure:!1,timeoutMs:5e3});break;case"xclip":await D("xclip",["-selection","clipboard"],{allowFailure:!1,timeoutMs:5e3,stdin:e});break;case"xsel":await D("xsel",["--clipboard","--input"],{allowFailure:!1,timeoutMs:5e3,stdin:e})}}async function lG(){return"linux"!==process.platform?[]:[{platform:"linux",id:"local",name:f(),kind:"device",target:"desktop",booted:!0}]}l$.resetCache;let lV={"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"},lB="atspi-dump.py",lj=null;async function lq(e,t={}){let n;if("linux"!==process.platform)throw new N("UNSUPPORTED_PLATFORM","AT-SPI2 bridge is only available on Linux");if(!await M("python3"))throw new N("TOOL_MISSING","python3 is required for AT-SPI2 accessibility snapshots on Linux.");let i=t.maxNodes??1500,a=t.maxDepth??12,s=t.maxApps??24,u=[function(){if(lj)return lj;let e=o.dirname(l(import.meta.url));for(let t=0;t<5;t++){let n=o.join(e,"src","platforms","linux",lB);if(r.existsSync(n))return lj=n,n;if(0===t){let t=o.join(e,lB);if(r.existsSync(t))return lj=t,t}e=o.dirname(e)}throw new N("TOOL_MISSING",`Cannot find ${lB}. Ensure the agent-device package is installed correctly.`)}(),"--surface",e,"--max-nodes",String(i),"--max-depth",String(a),"--max-apps",String(s)],d=await D("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 N("TOOL_MISSING","AT-SPI2 Python bindings not found. Install python3-gi and gir1.2-atspi-2.0.",{cause:e});throw new N("COMMAND_FAILED",`AT-SPI2 snapshot failed (exit ${d.exitCode}): ${e||d.stdout}`)}try{n=JSON.parse(d.stdout)}catch{throw new N("COMMAND_FAILED",`AT-SPI2 snapshot returned invalid JSON: ${d.stdout.slice(0,200)}`)}if(n.error)throw new N("COMMAND_FAILED",`AT-SPI2: ${n.error}`);return{nodes:(n.nodes??[]).map(e=>{let t,n;return{index:e.index,type:(n=lV[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&&ex({level:"warn",phase:"linux_snapshot",data:{message:"menubar surface is not supported on Linux, falling back to desktop"}}),"desktop"),n=await lq(t);return{nodes:n.nodes,truncated:n.truncated}}function lz(e){return e?.clickButton??"primary"}function lH(e){return"primary"===e.button?null:"click"!==e.commandLabel?new N("INVALID_ARGS","--button is supported only for click"):"macos"!==e.platform&&"linux"!==e.platform?new N("UNSUPPORTED_OPERATION",`click --button ${e.button} is supported only on macOS and Linux`):"macos"===e.platform&&"middle"===e.button?new N("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 N("INVALID_ARGS",`click --button ${e.button} does not support repeat or gesture modifier flags`):null}function lJ(e){return"primary"===e?{}:{button:e}}let lX=/^[A-Za-z0-9_.:-]{1,64}$/,lK=[[0,0],[1,0],[0,1],[-1,0],[0,-1],[1,1],[-1,1],[1,-1],[-1,-1]];function lY(e,t,n,r){if(!Number.isFinite(e)||!Number.isInteger(e)||e<n||e>r)throw new N("INVALID_ARGS",`${t} must be an integer between ${n} and ${r}`);return e}async function lZ(e,t,n){for(let r=0;r<e;r+=1)await n(r),r<e-1&&t>0&&await lQ(t)}async function lQ(e){await new Promise(t=>setTimeout(t,e))}function l0(e,t){let n,i=t?.subject??"Payload",a=e.trim();if(!a)throw new N("INVALID_ARGS",`${i} cannot be empty`);let o=t?.expandPath?t.expandPath(a,t.cwd):a;try{if(!r.statSync(o).isFile())throw new N("INVALID_ARGS",`${i} path is not a file: ${o}`);return{kind:"file",path:o}}catch(t){if(t instanceof N)throw t;let e=t.code;if("EACCES"===e||"EPERM"===e)throw new N("INVALID_ARGS",`${i} file is not readable: ${o}`);if(e&&"ENOENT"!==e)throw new N("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 N("INVALID_ARGS",`${i} file not found: ${o}`)}async function l1(e){let t=l0(e,{subject:"Push payload"}),n="inline"===t.kind?t.text:await l2(t.path);try{let e=JSON.parse(n);if(!e||"object"!=typeof e||Array.isArray(e))throw new N("INVALID_ARGS","push payload must be a JSON object");return e}catch(t){if(t instanceof N)throw t;throw new N("INVALID_ARGS",`Invalid push payload JSON: ${e}`)}}async function l2(e){try{return await a.readFile(e,"utf8")}catch(n){let t=n.code;if("ENOENT"===t)throw new N("INVALID_ARGS",`Push payload file not found: ${e}`);if("EISDIR"===t)throw new N("INVALID_ARGS",`Push payload path is not a file: ${e}`);if("EACCES"===t||"EPERM"===t)throw new N("INVALID_ARGS",`Push payload file is not readable: ${e}`);throw new N("COMMAND_FAILED",`Unable to read push payload file: ${e}`,{cause:String(n)})}}function l3(e){if(void 0===e)throw new N("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 N("INVALID_ARGS",`Invalid rotation: ${e}. Use portrait|portrait-upside-down|landscape-left|landscape-right.`)}}let l4=rp(process.env.AGENT_DEVICE_IOS_DEVICECTL_LIST_TIMEOUT_MS,8e3,500),l5=/^(iphone|ipad|ipod|appletv)/i,l8=/\b(iphone|ipad|ipod)\b/i,l6=/^appletv/i,l9=["apple tv","appletv","tvos"],l7=/^==\s*(.+?)\s*==$/,ue=/^(?<name>.+?)\s+\[(?<id>[^[\]]+)\]\s*$/;function ut(e){return(e??"").trim().toLowerCase()}function un(e){return ut(e.hardwareProperties?.platform)}function ur(e){return e.includes("tvos")}function ui(e){let t=ut(e);return l9.some(e=>t.includes(e))}function ua(e){return[e.name??"",e.deviceProperties?.name??"",e.deviceProperties?.deviceType??""]}function uo(e){return e.hardwareProperties?.productType??e.deviceProperties?.productType??""}async function us(e={}){let t,n,r=t6(e.simulatorSetPath),i=e.target;try{t=await D("xcrun",ne(["list","devices","-j"],{simulatorSetPath:r}))}catch{return null}try{n=JSON.parse(t.stdout)}catch{return null}let a=ul(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 ul(e,t){let n=[];for(let[r,i]of Object.entries(e.devices))if(function(e){let t=ut(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:ur(ut(r))?"tv":"mobile",booted:"Booted"===e.state,...t?{simulatorSetPath:t}:{}});return n}function uu(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 ud(){let e=null;try{e=o.join(p.tmpdir(),`agent-device-devicectl-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);let t=await D("xcrun",["devicectl","list","devices","--json-output",e],{allowFailure:!0,timeoutMs:l4});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=un(e);return!!(n.includes("ios")||n.includes("tvos"))||(t=uo(e),!!l5.test(t.trim())||ua(e).some(ui))}(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 ur(un(e))?"tv":(t=uo(e),l6.test(t.trim())||ua(e).some(ui))?"tv":"mobile"}(n),booted:!0})}return t}(JSON.parse(n))}catch{return[]}finally{e&&await a.rm(e,{force:!0}).catch(()=>{})}}async function uc(){try{let e=await D("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=l7.exec(e);if(i){n=i[1]?.trim()??null;continue}if("Devices"!==n)continue;let a=ue.exec(e),o=a?.groups?.id?.trim()??"",s=a?.groups?.name?.trim()??"";if(!o||!s)continue;let l=function(e){return ui(e)?"tv":l8.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 up(e={}){if("darwin"!==process.platform)throw new N("UNSUPPORTED_PLATFORM","Apple tools are only available on macOS");if(!await M("xcrun"))throw new N("TOOL_MISSING","xcrun not found in PATH");let t=t6(e.simulatorSetPath),n=await D("xcrun",ne(["list","devices","-j"],{simulatorSetPath:t})),r=[];try{let e=JSON.parse(n.stdout);r=ul(e,t)}catch(e){throw new N("COMMAND_FAILED","Failed to parse simctl devices JSON",void 0,e)}if(r.push({platform:"macos",id:"host-macos-local",name:p.hostname(),kind:"device",target:"desktop",booted:!0}),t)return r;let[i,a]=await Promise.all([ud(),uc()]);return r=uu(r,i),uu(r,a)}async function uf(e,t,n){let r,i=!!(t.udid||t.serial||t.deviceName);try{r=await nL(e,t,n)}catch(e){if(i||!(e instanceof N)||"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 us({simulatorSetPath:n.simulatorSetPath,target:t.target});if(e)return e}if(r)return r;throw new N("DEVICE_NOT_FOUND","No devices found",{selector:t})}async function um(e){let t=nE(e.platform),n=nO({simulatorSetPath:t6(e.iosSimulatorDeviceSet),platform:t,target:e.target}),r=t7(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 N("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 lG();return await nL(e,i)}if("android"===i.platform){await tK();let e=await ri({serialAllowlist:r});return await nL(e,i)}if(i.platform){let e=await up({simulatorSetPath:n});return await uf(e,i,{simulatorSetPath:n})}let a=[];try{a.push(...await ri({serialAllowlist:r}))}catch{}try{a.push(...await up({simulatorSetPath:n}))}catch{}try{a.push(...await lG())}catch{}return await nL(a,i,{simulatorSetPath:n})},{platform:t,target:e.target})}async function uh(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)=>rX(e,t,n?.activity),openDevice:()=>r1(e),close:t=>r2(e,t),tap:(t,n)=>i_(e,t,n),doubleTap:async(t,n)=>{await i_(e,t,n),await i_(e,t,n)},swipe:(t,n,r,i,a)=>iN(e,t,n,r,i,a),longPress:(t,n,r)=>iO(e,t,n,r),focus:(t,n)=>ik(e,t,n),type:(t,n)=>iL(e,t,n),fill:(t,n,r,i)=>iR(e,t,n,r,i),scroll:(t,n)=>iF(e,t,n),screenshot:t=>ae(e,t),back:t=>iD(e),home:()=>iE(e),rotate:t=>iC(e,t),appSwitcher:()=>iM(e),readClipboard:()=>iJ(e),writeClipboard:t=>iX(e,t),setSetting:(t,n,r,i)=>i1(e,t,n,r,i)};case"linux":return{open:e=>lT(e),openDevice:()=>Promise.resolve(),close:e=>lk(e),tap:(e,t)=>lv(e,t),doubleTap:(e,t)=>lA(e,t),swipe:(e,t,n,r,i)=>l_(e,t,n,r,i),longPress:(e,t,n)=>lS(e,t,n),focus:(e,t)=>lx(e,t),type:(e,t)=>lD(e,t),fill:(e,t,n,r)=>lE(e,t,n,r),scroll:(e,t)=>lN(e,t),screenshot:e=>lL(e),back:()=>lR(),home:()=>lP(),rotate:()=>{throw new N("UNSUPPORTED_OPERATION","rotate not supported on Linux")},appSwitcher:()=>{throw new N("UNSUPPORTED_OPERATION","appSwitcher not yet supported on Linux")},readClipboard:()=>lF(),writeClipboard:e=>lU(e),setSetting:()=>{throw new N("UNSUPPORTED_OPERATION","setSetting not supported on Linux")}};case"ios":case"macos":{let n,{overrides:r,runnerOpts:i}={runnerOpts:n={verbose:t.verbose,logPath:t.logPath,traceLogPath:t.traceLogPath,requestId:t.requestId},overrides:{tap:async(r,i)=>await sv(e,{command:"tap",x:r,y:i,appBundleId:t.appBundleId},n),doubleTap:async(r,i)=>await sv(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 sv(e,{command:"drag",x:r,y:i,x2:a,y2:o,durationMs:s,appBundleId:t.appBundleId},n),longPress:async(r,i,a)=>await sv(e,{command:"longPress",x:r,y:i,durationMs:a,appBundleId:t.appBundleId},n),focus:async(r,i)=>await sv(e,{command:"tap",x:r,y:i,appBundleId:t.appBundleId},n),type:async(r,i)=>{await sv(e,{command:"type",text:r,delayMs:i,appBundleId:t.appBundleId},n)},fill:async(r,i,a,o)=>{let s=await sv(e,{command:"tap",x:r,y:i,appBundleId:t.appBundleId},n);return await sv(e,{command:"type",text:a,clearFirst:!0,delayMs:o,appBundleId:t.appBundleId},n),s},scroll:async(r,i)=>await ls(sv,e,t,n,r,i)}};return{open:(t,n)=>sX(e,t,{appBundleId:n?.appBundleId,url:n?.url}),openDevice:()=>sK(e),close:t=>sY(e,t),screenshot:async(t,n)=>{"macos"===e.platform&&n?.surface&&"app"!==n.surface?await a0(t,{surface:n.surface,fullscreen:n.fullscreen}):await sT(e,t,n?.appBundleId,n?.fullscreen)},back:async n=>{await sv(e,{command:"system"===n?"backSystem":"backInApp",appBundleId:t.appBundleId},i)},home:async()=>{await sv(e,{command:"home",appBundleId:t.appBundleId},i)},rotate:async n=>{await sv(e,{command:"rotate",orientation:n,appBundleId:t.appBundleId},i)},appSwitcher:async()=>{await sv(e,{command:"appSwitcher",appBundleId:t.appBundleId},i)},readClipboard:()=>s2(e),writeClipboard:t=>s3(e,t),setSetting:(t,n,r,i)=>s5(e,t,n,r,i),...r}}default:throw new N("UNSUPPORTED_PLATFORM",`Unsupported platform: ${e.platform}`)}}(e,s);return ex({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 uw(e,l,n,i);case"close":{let e=n[0];if(!e)return{closed:"session",...tE("Closed session")};return await l.close(e),{app:e,...tE(`Closed: ${e}`)}}case"press":return ug(e,l,n,i,s);case"swipe":return uy(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 N("INVALID_ARGS","longpress requires x y [durationMs]");return await l.longPress(e,t,r),{x:e,y:t,durationMs:r,...tE(`Long pressed (${e}, ${t})`)}}case"focus":{let[e,t]=n.map(Number);if(Number.isNaN(e)||Number.isNaN(t))throw new N("INVALID_ARGS","focus requires x y");return await l.focus(e,t),{x:e,y:t,...tE(`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 N("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 N("INVALID_ARGS","type requires text");let r=lY(i?.delayMs??0,"delay-ms",0,1e4);return await l.type(t,r),{text:t,delayMs:r,...tE(uC("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 N("INVALID_ARGS","fill requires x y text");let a=lY(i?.delayMs??0,"delay-ms",0,1e4);return await l.fill(e,t,r,a),{x:e,y:t,text:r,delayMs:a,...tE(uC("Filled",r))}}case"scroll":return uv(l,n,i);case"pinch":return uI(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 N("INVALID_ARGS","trigger-app-event requires <event> [payloadJson]");if(!lX.test(t))throw new N("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 N("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 N("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 N("INVALID_ARGS",`trigger-app-event payload for "${t}" exceeds 8192 bytes`);return n}catch(t){if(t instanceof N)throw t;throw new N("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 N("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 N("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",...tE(`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,...tE(`Saved screenshot: ${e}`)}}case"back":return await l.back(i?.backMode),{action:"back",mode:i?.backMode??"in-app",...tE("Back")};case"home":return await l.home(),{action:"home",...tE("Home")};case"rotate":{let e=l3(n[0]);return await l.rotate(e),{action:"rotate",orientation:e,...tE(`Rotated to ${e}`)}}case"app-switcher":return await l.appSwitcher(),{action:"app-switcher",...tE("Opened app switcher")};case"clipboard":return ub(l,n);case"keyboard":return uA(e,l,n,i,s);case"settings":return uS(e,l,n,i);case"push":return ux(e,n,i);case"snapshot":return u_(e,n,i,s);case"read":return uN(e,n,i,s);default:throw new N("INVALID_ARGS",`Unknown command: ${t}`)}},{command:t,platform:e.platform})}async function uw(e,t,n,r){let i=n[0],a=n[1];if(n.length>2)throw new N("INVALID_ARGS","open accepts at most two arguments: <app|url> [url]");if(!i)return await t.openDevice(),{app:null,...tE("Opened device")};if(void 0!==a){if("android"===e.platform)throw new N("INVALID_ARGS","open <app> <url> is supported only on Apple platforms");if(nj(i))throw new N("INVALID_ARGS","open <app> <url> requires an app target as the first argument");if(!nj(a))throw new N("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,...tE(`Opened: ${i}`)}}return await t.open(i,{activity:r?.activity,appBundleId:r?.appBundleId}),{app:i,...tE(`Opened: ${i}`)}}async function ug(e,t,n,r,i){let a,[o,s]=n.map(Number);if(Number.isNaN(o)||Number.isNaN(s))throw new N("INVALID_ARGS","press requires x y");if("macos"===e.platform&&r?.surface&&"app"!==r.surface){let e=lz(r);if("primary"!==e)throw new N("UNSUPPORTED_OPERATION",`${e} click is not supported on macOS ${r.surface} sessions.`);return await aQ(o,s,{bundleId:r.appBundleId,surface:r.surface}),{x:o,y:s,...tE(uD({x:o,y:s}))}}let l=lz(r);if("primary"!==l){let t=lH({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 lI(o,s):await lb(o,s):await sv(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,...tE(uD({x:o,y:s,button:l}))}}let u=lY(r?.count??1,"count",1,200),d=lY(r?.intervalMs??0,"interval-ms",0,1e4),c=lY(r?.holdMs??0,"hold-ms",0,1e4),p=lY(r?.jitterPx??0,"jitter-px",0,100),f=r?.doubleTap===!0;if(f&&c>0)throw new N("INVALID_ARGS","double-tap cannot be combined with hold-ms");if(f&&p>0)throw new N("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 sv(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,...tE(uD({x:o,y:s}))}}return await lZ(u,d,async e=>{let[n,r]=function(e,t){if(t<=0)return[0,0];let[n,r]=lK[e%lK.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}),tC({x:o,y:s,count:u,intervalMs:d,holdMs:c,jitterPx:p,doubleTap:f,...a},uD({x:o,y:s}))}async function uy(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 N("INVALID_ARGS","swipe requires x1 y1 x2 y2 [durationMs]");let u=lY(n[4]?Number(n[4]):250,"durationMs",16,1e4),d="ios"===e.platform?Math.min(60,Math.max(16,Math.round(u))):u,c=lY(r?.count??1,"count",1,200),p=lY(r?.pauseMs??0,"pause-ms",0,1e4),f=r?.pattern??"one-way";if("one-way"!==f&&"ping-pong"!==f)throw new N("INVALID_ARGS",`Invalid pattern: ${f}`);if(("ios"===e.platform||"macos"===e.platform)&&c>1){let t=await sv(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,...tE(uE(c,f))}}return await lZ(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)}),tC({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},uE(c,f))}async function uv(e,t,n){let r=t[0],i=t[1]?Number(t[1]):void 0,a=n?.pixels;if(!r)throw new N("INVALID_ARGS","scroll requires direction");if(void 0!==i&&!Number.isFinite(i))throw new N("INVALID_ARGS","scroll amount must be a number");if(void 0!==i&&void 0!==a)throw new N("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 N("INVALID_ARGS",`Unknown direction: ${e}`)}}(r),s=await e.scroll(o,{amount:i,pixels:a});return tC({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 uI(e,t,n,r){if("android"===e.platform)throw new N("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 N("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 N("INVALID_ARGS","pinch requires scale > 0");return await sv(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,...tE(`Pinched to scale ${i}`)}}async function ub(e,t){let n=(t[0]??"").toLowerCase();if("read"!==n&&"write"!==n)throw new N("INVALID_ARGS","clipboard requires a subcommand: read or write");if("read"===n){if(1!==t.length)throw new N("INVALID_ARGS","clipboard read does not accept additional arguments");return{action:n,text:await e.readClipboard()}}if(t.length<2)throw new N("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,...tE("Clipboard updated")}}async function uA(e,t,n,r,i){let a=(n[0]??"status").toLowerCase();if("status"!==a&&"get"!==a&&"dismiss"!==a)throw new N("INVALID_ARGS","keyboard requires a subcommand: status, get, or dismiss");if(n.length>1)throw new N("INVALID_ARGS","keyboard accepts at most one subcommand argument");if("android"===e.platform){if("dismiss"===a){let t=await iH(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 iz(e);return{platform:"android",action:"status",visible:t.visible,inputType:t.inputType,type:t.type}}if("ios"===e.platform){if("dismiss"!==a)throw new N("UNSUPPORTED_OPERATION","keyboard status/get is currently supported only on Android; use keyboard dismiss on iOS");let t=await sv(e,{command:"keyboardDismiss",appBundleId:r?.appBundleId},i);return{platform:"ios",action:"dismiss",wasVisible:t.wasVisible,dismissed:t.dismissed,visible:t.visible,...tE(t.dismissed?"Keyboard dismissed":"Keyboard already hidden")}}throw new N("UNSUPPORTED_OPERATION","keyboard is supported only on Android and iOS")}async function uS(e,t,n,r){var i;let[a,o,s,l,u]=n,d="permission"===a?{permissionTarget:s,permissionMode:l}:void 0;ex({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?tC({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,...tE(`Updated setting: ${a}`)}}async function ux(e,t,n){let r=t[0]?.trim(),i=t[1]?.trim();if(!r||!i)throw new N("INVALID_ARGS","push requires <bundle|package> <payload.json|inline-json>");let a=await l1(i);if("ios"===e.platform)return await s4(e,r,a),{platform:"ios",bundleId:r,...tE(`Pushed notification to ${r}`)};let o=await i9(e,r,a);return{platform:"android",package:r,action:o.action,extrasCount:o.extrasCount,...tE(`Pushed notification to ${r}`)}}async function u_(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 sv(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 N("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 iy(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 uN(e,t,n,r){let[i,a]=t.map(Number);if(Number.isNaN(i)||Number.isNaN(a))throw new N("INVALID_ARGS","read requires x y");if("android"===e.platform)return{action:"read",text:await iq(e,i,a)??""};if("macos"===e.platform&&n?.surface&&"app"!==n.surface)return{action:"read",text:(await aZ(i,a,{bundleId:n.appBundleId,surface:n.surface})).text};let o=await sv(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 uD(e){return e.button&&"primary"!==e.button?`Clicked ${e.button} (${e.x}, ${e.y})`:`Tapped (${e.x}, ${e.y})`}function uE(e,t){return e<=1?"Swiped":"ping-pong"===t?`Swiped ${e} times (ping-pong)`:`Swiped ${e} times`}function uC(e,t){return`${e} ${Array.from(t).length} chars`}let uM=[250,400];function uO(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?uR(n?.nodes??[]):void 0,routeComparable:r}}function uL(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 uT(e){e&&"android"===e.device.platform&&delete e.androidSnapshotFreshness}function uk(e){return"press"===e||"click"===e||"back"===e||"open"===e}function uR(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 uP(e,t){return!(e<12)&&t<=Math.floor(.2*e)}function u$(e,t,n,r,i){return{requestId:i??eS().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:lz(t),backMode:t?.backMode,pauseMs:t?.pauseMs,pattern:t?.pattern}}async function uF(e){let t=uL(e.session);if(t&&"android"===e.device.platform)return await uG(e,t);let n=await uU(e);return uT(e.session),{snapshot:uj(n,e.flags),analysis:n.analysis}}async function uU(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 uq({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?uq(await aY(n.surface,{bundleId:"menubar"===n.surface?n.appBundleId:void 0}),{snapshotDepth:r?.snapshotDepth,snapshotInteractiveOnly:r?.snapshotInteractiveOnly,snapshotScope:o}):await uh(t,"snapshot",[],i,{...u$(a,{...r,snapshotScope:o},n?.appBundleId,n?.trace?.outPath)})}async function uG(e,t){let n=await uV(e),r=uB(n,t,e.flags),i=0;for(let a of uM){if(!r)break;await new Promise(e=>setTimeout(e,a)),n=await uV(e),i+=1,r=uB(n,t,e.flags)}return r||uT(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 uV(e){let t=await uU(e);return{data:t,snapshot:uj(t,e.flags)}}function uB(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":uP(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&&uk(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=uR(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 uj(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:ta(n));return{nodes:ei(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 uq(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:uz(e.filter(e=>n.has(e.index)))}(i)),"number"==typeof t.snapshotDepth&&(n=i,r=t.snapshotDepth,i=uz(n.filter(e=>(e.depth??0)<=r))),{...e,nodes:i}}function uW(e,t){let n=tn(ei(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 uz(a,i)}function uz(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 uH(e,t){if(!e||!e.trim().startsWith("@"))return{ok:!0,scope:e};if(!t?.snapshot)return nB("INVALID_ARGS","Ref scope requires an existing snapshot in session.");let n=ea(e.trim());if(!n)return nB("INVALID_ARGS",`Invalid ref scope: ${e}`);let r=eo(t.snapshot.nodes,n),i=r?tr(r,t.snapshot.nodes):void 0;return i?{ok:!0,scope:i}:nB("COMMAND_FAILED",`Ref ${e} not found or has no label`)}let uJ=rp(process.env.AGENT_DEVICE_IOS_DEVICE_READY_TIMEOUT_MS,15e3,1e3);async function uX(e){if("ios"===e.platform){if("simulator"===e.kind){let{ensureBootedSimulator:t}=await Promise.resolve(T);await t(e);return}if("device"===e.kind)return void await uK(e.id)}if("android"===e.platform){let{waitForAndroidBoot:t}=await Promise.resolve(L);await t(e.id)}}async function uK(e){let t=o.join(p.tmpdir(),`agent-device-ready-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),n=Math.max(1,Math.ceil(uJ/1e3));try{let r=await D("xcrun",["devicectl","device","info","details","--device",e,"--json-output",t,"--timeout",String(n)],{allowFailure:!0,timeoutMs:uJ+3e3}),i=String(r.stdout??""),a=String(r.stderr??""),o=await uY(t);if(0===r.exitCode){if(!o.parsed)throw new N("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 N("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 N("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:uZ(i,a)})}catch(t){if(t instanceof N&&"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??uJ),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 N("COMMAND_FAILED","iOS device readiness probe failed",{deviceId:e,cause:t.message,timeoutMs:a,stdout:r,stderr:i,hint:r||i?uZ(r,i):o},t)}throw new N("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 uY(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 uZ(e,t){let n=aw(e,t);return n||(`${e}
38
+ ${t}`.toLowerCase().includes("timed out waiting for all destinations")?"Xcode destination did not become available in time. Keep device unlocked and retry.":ah)}async function uQ(e,t,n){let r=e.get(t),i=r?.device??await um(n??{});return r||await uX(i),{session:r,device:i}}async function u0(e,t,n){let r=!e&&"ios"===t.platform;try{return await n()}finally{r&&await sp(t.id)}}function u1(e,t,n,r){t&&e.recordAction(t,{command:n.command,positionals:n.positionals??[],flags:n.flags??{},result:r})}function u2(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 u3(e){if(!e)return null;let t=Number(e);return Number.isFinite(t)?t:null}function u4(e){if(0===e.length)return null;let t=u3(e[0]);if(null!==t)return{kind:"sleep",durationMs:t};if("text"===e[0]){let t=u3(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=u3(e[e.length-1]);return{kind:"ref",rawRef:e[0],timeoutMs:t}}let n=u3(e[e.length-1]),r=e8(null!==n?e.slice(0,-1):e.slice());if(r&&0===r.rest.length){let e=e5(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 u5(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)),u1(a,o,n,{waitedMs:t.durationMs}),{ok:!0,data:{waitedMs:t.durationMs}};if(!nF("wait",s))return nB("UNSUPPORTED_OPERATION","wait is not supported on this device");if("selector"===t.kind)return await u8({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 nB("INVALID_ARGS","Ref wait requires an existing snapshot in session.");let n=ea(e.rawRef);if(!n)return nB("INVALID_ARGS",`Invalid ref: ${e.rawRef}`);let r=eo(t.snapshot.nodes,n),i=r?tr(r,t.snapshot.nodes):void 0;return i?{ok:!0,text:i,timeoutMs:e.timeoutMs}:nB("COMMAND_FAILED",`Ref ${e.rawRef} not found or has no label`)}return e.text?{ok:!0,text:e.text,timeoutMs:e.timeoutMs}:nB("INVALID_ARGS","wait requires text")}(t,o);return l.ok?await u6({device:s,logPath:i,req:n,session:o,sessionStore:a,text:l.text,timeoutMs:l.timeoutMs}):l}async function u8(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=tI((await u9({device:t,logPath:n,req:i,session:a,sessionName:o,sessionStore:s})).nodes,r.selector,{platform:t.platform});if(e)return u7(s,a,i,{selector:e.selector.raw,waitedMs:Date.now()-u});await new Promise(e=>setTimeout(e,300))}return nB("COMMAND_FAILED",`wait timed out for selector: ${r.selectorExpression}`)}async function u6(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(tn((await u9({device:t,logPath:n,req:r,session:i,sessionName:i?.name??r.session??"default",sessionStore:a})).nodes,o))return u7(a,i,r,{text:o,waitedMs:Date.now()-u})}else if(nC(t.platform)){let e=await sv(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 u1(a,i,r,{text:o,waitedMs:Date.now()-u}),{ok:!0,data:{text:o,waitedMs:Date.now()-u}}}else if("android"===t.platform&&tn((await u9({device:t,logPath:n,req:r,session:i,sessionName:i?.name??r.session??"default",sessionStore:a})).nodes,o))return u1(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 nB("COMMAND_FAILED",`wait timed out for text: ${o}`)}async function u9(e){let{device:t,logPath:n,req:r,session:i,sessionName:a,sessionStore:o}=e,{snapshot:s}=await uF({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 u7(e,t,n,r){return u1(e,t,n,r),{ok:!0,data:r}}async function de(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(!nF("alert",a))return nB("UNSUPPORTED_OPERATION","alert is not supported on this device");if("macos"===a.platform){let e=async()=>await aK("wait"===o?"get":o,s);if("wait"===o){let n=u3(t.positionals?.[1])??1e4,a=Date.now();for(;Date.now()-a<n;){try{let n=await e();return u1(r,i,t,n),{ok:!0,data:n}}catch{}await new Promise(e=>setTimeout(e,300))}return nB("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 aK(n,s);return u1(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 dt(e)}let a=await aK("get",s);return u1(r,i,t,a),{ok:!0,data:a}}if("wait"===o){let e=u3(t.positionals?.[1])??1e4,o=Date.now();for(;Date.now()-o<e;){try{let e=await sv(a,{command:"alert",action:"get",appBundleId:i?.appBundleId},{verbose:t.flags?.verbose,logPath:n,traceLogPath:i?.trace?.outPath,requestId:t.meta?.requestId});return u1(r,i,t,e),{ok:!0,data:e}}catch{}await new Promise(e=>setTimeout(e,300))}return nB("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 sv(a,{command:"alert",action:l,appBundleId:i?.appBundleId},u);return u1(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 dt(e)}let d=await sv(a,{command:"alert",action:l,appBundleId:i?.appBundleId},u);return u1(r,i,t,d),{ok:!0,data:d}}function dt(e){if(!(e instanceof N))return e;let t=String(e.message??"").toLowerCase();return t.includes("alert not found")||t.includes("no alert")?new N(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 dn(e){let t,{req:n,logPath:r,sessionStore:i,session:a,device:o,parsed:s}=e,{setting:l,state:u,permissionTarget:d}=s;if(!nF("settings",o))return nB("UNSUPPORTED_OPERATION","settings is not supported on this device");if("macos"===o.platform&&"appearance"!==(t=l.trim().toLowerCase())&&"permission"!==t)return nB("INVALID_ARGS",q(l));let c=a?.appBundleId,p="permission"===l?[l,u,d??"",n.positionals?.[3]??"",c??""]:[l,u,c??""],f=await uh(o,"settings",p,n.flags?.out,{...u$(r,n.flags,c,a?.trace?.outPath)});return u1(i,a,n,f??{setting:l,state:u}),{ok:!0,data:f??{setting:l,state:u}}}let dr=new Set(["snapshot","diff","wait","alert","settings"]);async function di(e){let{req:t,sessionName:n,logPath:r,sessionStore:i}=e,a=t.command;if(!dr.has(a))return null;if("snapshot"===a){let{session:e,device:a}=await uQ(i,n,t.flags);if(!nF("snapshot",a))return nB("UNSUPPORTED_OPERATION","snapshot is not supported on this device");let o=uH(t.flags?.snapshotScope,e);return o.ok?await u0(e,a,async()=>{let s=await uF({device:a,session:e,flags:t.flags,outPath:t.flags?.out,logPath:r,snapshotScope:o.scope}),l=da({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=u2({session:e,sessionName:n,device:a,snapshot:s.snapshot,appBundleId:e?.appBundleId});return u1(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"?nB("INVALID_ARGS","diff currently supports only: diff snapshot"):await ds({req:t,sessionName:n,logPath:r,sessionStore:i});if("wait"===a){let{session:e,device:a}=await uQ(i,n,t.flags),o=u4(t.positionals??[]);if(!o)return nB("INVALID_ARGS","wait requires a duration or text");let s=()=>u5({parsed:o,req:t,sessionName:n,logPath:r,sessionStore:i,session:e,device:a});return"sleep"===o.kind?await s():await u0(e,a,s)}if("alert"===a){let{session:e,device:a}=await uQ(i,n,t.flags);return await u0(e,a,async()=>await de({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}}:nB("INVALID_ARGS",j));if(!s.ok)return s;let{session:l,device:u}=await uQ(i,n,t.flags);return await u0(l,u,async()=>await dn({req:t,logPath:r,sessionStore:i,session:l,device:u,parsed:s.parsed}))}return null}function da(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&&uP(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.")),tx(i)}async function ds(e){let{req:t,sessionName:n,logPath:r,sessionStore:i}=e,{session:a,device:o}=await uQ(i,n,t.flags);if(!nF("diff",o))return nB("UNSUPPORTED_OPERATION","diff is not supported on this device");let s=uH(t.flags?.snapshotScope,a);if(!s.ok)return s;let l=t.flags?.snapshotInteractiveOnly===!0;return await u0(a,o,async()=>{let e=await uF({device:o,session:a,flags:t.flags,outPath:t.flags?.out,logPath:r,snapshotScope:s.scope}),u=e.snapshot,d=da({capture:e,flags:t.flags,session:a});if(!a?.snapshot){let e=function(e,t={}){return nG(e,t).length}(u.nodes,{flatten:l}),r=u2({session:a,sessionName:n,device:o,snapshot:u,appBundleId:a?.appBundleId});return u1(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&&nV(a,i-1)<nV(a,i+1)?nV(a,i+1):nV(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&&nV(i,l-1)<nV(i,l+1)?l+1:l-1,d=nV(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[]}(nG(e,n),nG(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 u1(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{eK as DEFAULT_BATCH_MAX_STEPS,ah as IOS_DEVICECTL_DEFAULT_HINT,oX as IOS_RUNNER_CONTAINER_BUNDLE_IDS,aa as IOS_SIMCTL_LIST_TIMEOUT_MS,W as SESSION_SURFACES,B as SETTINGS_USAGE_OVERRIDE,sf as abortAllIosRunnerSessions,tX as adbArgs,iM as appSwitcherAndroid,nc as applyRuntimeHintsToApp,ei as attachRefs,iD as backAndroid,tO as buildAppIdentifiers,tL as buildDeviceIdentifiers,ef as buildMobileSnapshotPresentation,io as buildScrollGesturePlan,t_ as buildSelectorChainForNode,ne as buildSimctlArgs,nt as buildSimctlArgsForDevice,K as buildSnapshotDisplayLines,uj as buildSnapshotState,lJ as buttonTag,uF as captureSnapshot,uU as captureSnapshotData,es as centerOfRect,t1 as classifyAndroidAppTarget,od as clearRequestCanceled,np as clearRuntimeHintsFromApp,r2 as closeAndroidApp,sY as closeIosApp,eH as computeDaemonCodeSignature,u$ as contextFromFlags,of as createRequestCanceledError,eb as createRequestId,nD as decodePng,rc as waitForAndroidBoot,iH as dismissAndroidKeyboard,uh as dispatchCommand,er as displayNodeLabel,ex as emitDiagnostic,tK as ensureAdb,rd as ensureAndroidEmulatorBooted,uX as ensureDeviceReady,nB as errorResponse,eP as expandUserHomePath,td as extractNodeReadText,tu as extractNodeText,iR as fillAndroid,tc as findBestMatchesByLocator,us as findBootableIosSimulator,tl as findNearestHittableAncestor,tn as findNodeByLabel,eo as findNodeByRef,ev as findProjectRoot,tI as findSelectorChainMatch,eN as flushDiagnosticsToSessionFile,ik as focusAndroid,t2 as formatAndroidInstalledPackageRequiredMessage,tb as formatSelectorFailure,Y as formatSnapshotLine,uL as getActiveAndroidSnapshotFreshness,rH as getAndroidAppState,iz as getAndroidKeyboardState,iU as getAndroidScreenSize,lH as getClickButtonValidationError,eS as getDiagnosticsMeta,op as getRequestSignal,su as getRunnerSessionSnapshot,di as handleSnapshotCommands,nu as hasRuntimeTransportHints,iE as homeAndroid,rz as inferAndroidAppName,tS as inferFillText,ii as installAndroidApp,ir as installAndroidInstallablePathAndResolvePackageName,sQ as installIosApp,s1 as installIosInstallablePath,eO as isAgentDeviceDaemonProcess,nC as isApplePlatform,nF as isCommandSupportedOnDevice,nj as isDeepLinkTarget,nz as isEnvTruthy,ts as isFillableType,uk as isNavigationSensitiveAction,tg as isNodeEditable,tw as isNodeVisible,em as isNodeVisibleInEffectiveViewport,eE as isProcessAlive,oc as isRequestCanceled,rB as listAndroidApps,ri as listAndroidDevices,up as listAppleDevices,s8 as listIosApps,af as listIosDeviceApps,am as listIosDeviceProcesses,iO as longPressAndroid,uO as markAndroidSnapshotFreshness,ou as markRequestCanceled,nM as matchesPlatformSelector,nE as normalizePlatformSelector,ea as normalizeRef,eB as normalizeTenantId,to as normalizeType,rX as openAndroidApp,r1 as openAndroidDevice,sX as openIosApp,sK as openIosDevice,eQ as parseBatchStepsJson,l3 as parseDeviceRotation,tm as parseFindArgs,e4 as parseSelectorChain,t9 as parseSerialAllowlist,z as parseSessionSurface,u4 as parseWaitArgs,a_ as parseXmlDocumentSync,eu as pickLargestRect,rk as prepareAndroidInstallArtifact,aC as prepareIosInstallArtifact,i_ as pressAndroid,ta as pruneGroupNodes,i9 as pushAndroidNotification,s4 as pushIosNotification,iJ as readAndroidClipboardText,iq as readAndroidTextAtPoint,tM as readCommandMessage,aE as readInfoPlistString,s2 as readIosClipboardText,eM as readProcessCommand,eC as readProcessStartTime,ey as readVersion,el as rect_visibility_containsPoint,ol as registerRequestAbort,ia as reinstallAndroidApp,s0 as reinstallIosApp,rV as resolveAndroidApp,t7 as resolveAndroidSerialAllowlist,nO as resolveAppleSimulatorSetPathForSelector,lz as resolveClickButton,ez as resolveDaemonCodeSignature,eF as resolveDaemonPaths,eU as resolveDaemonServerMode,eG as resolveDaemonTransportPreference,t$ as resolveDeployResultTarget,eh as resolveEffectiveViewportRect,aH as resolveFrontmostMacOsApp,tU as resolveInstallFromSourceResultTarget,sJ as resolveIosApp,nq as resolveIosDeviceDeepLinkBundleId,aw as resolveIosDevicectlHint,t6 as resolveIosSimulatorDeviceSetPath,l0 as resolvePayloadInput,tr as resolveRefLabel,os as resolveRequestTrackingId,tv as resolveSelectorChain,eV as resolveSessionIsolationMode,um as resolveTargetDevice,rp as resolveTimeoutMs,e$ as resolveUserPath,iC as rotateAndroid,sv as runIosRunnerCommand,aK as runMacOsAlertAction,ae as screenshotAndroid,sT as screenshotIos,iF as scrollAndroid,tB as serializeCloseResult,tF as serializeDeployResult,tR as serializeDevice,tP as serializeEnsureSimulatorResult,tG as serializeInstallFromSourceResult,tV as serializeOpenResult,tk as serializeSessionListEntry,tj as serializeSnapshotResult,i1 as setAndroidSetting,s5 as setIosSetting,aA as shutdownSimulator,ab as ensureBootedSimulator,iy as snapshotAndroid,e6 as splitIsSelectorArgs,e8 as splitSelectorFromArgs,sm as stopAllIosRunnerSessions,sp as stopIosRunnerSession,ek as stopProcessForTakeover,tE as successText,iN as swipeAndroid,e5 as tryParseSelectorChain,iL as typeAndroid,tx as uniqueStrings,e0 as validateAndNormalizeBatchSteps,eT as waitForProcessExit,e_ as withDiagnosticTimer,eA as withDiagnosticsScope,oP as withKeyedLock,tC as withSuccessText,iX as writeAndroidClipboardText,s3 as writeIosClipboardText};