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