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