agent-device 0.13.3 → 0.14.1
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/README.md +68 -63
- package/android-snapshot-helper/README.md +75 -0
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.14.1.apk +0 -0
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.14.1.apk.sha256 +1 -0
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.14.1.manifest.json +17 -0
- package/dist/src/221.js +4 -0
- package/dist/src/3918.js +29 -29
- package/dist/src/8161.js +3 -3
- package/dist/src/8656.js +1 -1
- package/dist/src/9152.js +1 -1
- package/dist/src/9542.js +2 -2
- package/dist/src/9818.js +1 -1
- package/dist/src/989.js +1 -1
- package/dist/src/android-snapshot-helper.d.ts +182 -0
- package/dist/src/android-snapshot-helper.js +1 -0
- package/dist/src/index.d.ts +19 -0
- package/dist/src/internal/bin.js +413 -69
- package/dist/src/internal/daemon.js +22 -20
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +26 -2
- package/package.json +29 -9
- package/skills/agent-device/SKILL.md +20 -62
- package/skills/dogfood/SKILL.md +9 -168
- package/skills/react-devtools/SKILL.md +15 -31
- package/skills/agent-device/references/bootstrap-install.md +0 -244
- package/skills/agent-device/references/coordinate-system.md +0 -28
- package/skills/agent-device/references/debugging.md +0 -138
- package/skills/agent-device/references/exploration.md +0 -362
- package/skills/agent-device/references/macos-desktop.md +0 -88
- package/skills/agent-device/references/remote-tenancy.md +0 -188
- package/skills/agent-device/references/verification.md +0 -134
- package/skills/dogfood/references/issue-taxonomy.md +0 -83
- package/skills/dogfood/templates/dogfood-report-template.md +0 -52
- package/skills/react-devtools/references/commands.md +0 -91
- package/skills/react-devtools/references/profiling.md +0 -74
package/dist/src/3918.js
CHANGED
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
let e;import{__webpack_require__ as t}from"./rslib-runtime.js";import n,{existsSync as a,promises as r}from"node:fs";import{PNG as i}from"pngjs";import o from"node:path";import s,{hostname as l}from"node:os";import d from"node:net";import{AsyncLocalStorage as u}from"node:async_hooks";import{fileURLToPath as c}from"node:url";import{XMLParser as p}from"fast-xml-parser";import{createHash as f}from"node:crypto";import{asAppError as h,toAppErrorCode as m,AppError as w}from"./9152.js";import{splitSelectorFromArgs as g,trimText as y,extractNodeText as b,tryParseSelectorChain as v,parseSelectorChain as A,isNodeVisible as I,isNodeEditable as x,pruneGroupNodes as N,buildTextPreview as S,findNearestHittableAncestor as _,buildSelectorChainForNode as M,extractNodeReadText as k,splitIsSelectorArgs as D,findNodeByLabel as E,resolveRefLabel as O,describeTextSurface as C,extractReadableText as R,findSelectorChainMatch as P,resolveSelectorChain as T,normalizeType as L,formatSelectorFailure as $,isFillableType as F}from"./940.js";import{findNodeByRef as U,centerOfRect as G,normalizeRef as V,attachRefs as B}from"./4057.js";import{getDiagnosticsMeta as j,successText as q,withDiagnosticTimer as X,withSuccessText as z,emitDiagnostic as W}from"./8161.js";import{runCmdStreaming as H,runCmdDetached as Y,runCmdBackground as K,runCmdSync as J,runCmd as Z,resolveFileOverridePath as Q,whichCmd as ee,resolveExecutableOverridePath as et}from"./9818.js";import{findBestMatchesByLocator as en,parseFindArgs as ea}from"./7556.js";import"./7847.js";import{sleep as er,resolveTimeoutMs as ei,resolveTimeoutSeconds as eo}from"./4829.js";import{isProcessAlive as es,readProcessStartTime as el}from"./8656.js";import{ensureAndroidSdkPathConfigured as ed,resolveAndroidArchivePackageName as eu}from"./7651.js";import{materializeInstallablePath as ec,isTrustedInstallSourceUrl as ep}from"./989.js";import{parseAndroidForegroundApp as ef,parseAndroidLaunchablePackages as eh,parseAndroidUserInstalledPackages as em}from"./9366.js";var ew={};t.r(ew),t.d(ew,{ensureAndroidEmulatorBooted:()=>oS,listAndroidDevices:()=>ob,waitForAndroidBoot:()=>o_});var eg={};t.r(eg),t.d(eg,{TM:()=>ds,ensureBootedSimulator:()=>ly,installIosApp:()=>dd,installIosInstallablePath:()=>dc,listIosApps:()=>dw,L5:()=>dr,IJ:()=>di,TJ:()=>dh,J7:()=>dp,reinstallIosApp:()=>du,resolveIosApp:()=>da,kc:()=>lZ,Cm:()=>dm,ap:()=>df});let ey="<wifi|airplane|location> <on|off>",eb="animations <on|off>",ev="appearance <light|dark|toggle>",eA="faceid <match|nonmatch|enroll|unenroll>",eI="touchid <match|nonmatch|enroll|unenroll>",ex="fingerprint <match|nonmatch>",eN="permission <grant|deny|reset> <camera|microphone|photos|contacts|contacts-limited|notifications|calendar|location|location-always|media-library|motion|reminders|siri> [full|limited]",eS="permission <grant|reset> <accessibility|screen-recording|input-monitoring>",e_=`macOS supports only settings ${ev} and settings ${eS}. wifi|airplane|location|animations remain unsupported on macOS.`,eM=`settings ${ey} | settings ${eb} | settings ${ev} | settings ${eA} | settings ${eI} | settings ${ex} | settings ${eN} | settings ${eS}`,ek=`settings requires ${ey}, ${eb}, ${ev}, ${eA}, ${eI}, ${ex}, ${eN}, or ${eS}`;function eD(e){return`Unsupported macOS setting: ${e}. ${e_}`}let eE=["app","frontmost-app","desktop","menubar"];function eO(e){let t=e?.trim().toLowerCase();if("app"===t||"frontmost-app"===t||"desktop"===t||"menubar"===t)return t;throw new w("INVALID_ARGS",`Invalid surface: ${e}. Use ${eE.join("|")}.`)}function eC(e,t={}){let n=[],a=[];for(let r of e){let e=r.depth??0,i=r.label?.trim()||r.value?.trim()||r.identifier?.trim()||"",o=eT(r.type??"Element");if("group"===o&&!i)continue;for(;n.length>0&&e<=n[n.length-1];)n.pop();let s=n.length;n.push(e),a.push({node:r,depth:s,type:o,text:eR(r,s,!1,o,t)})}return a}function eR(e,t,n,a,r={}){var i,o,s,l,d,u,c,p;let f,h=a??eT(e.type??"Element"),m=C(e,h),w=(i=e,o=h,s=r,l=m,s.summarizeTextSurfaces&&l.shouldSummarize&&function(e,t,n){let a=y(e.label);if(a&&a!==n)return a;let r=y(e.identifier);if(r&&!e$(r)&&r!==n)return r;switch(t){case"text":case"text-view":return"Text view";case"text-field":return"Text field";case"search":return"Search field";default:return""}}(i,o,l.text)||eP(i,o)),g=" ".repeat(t),b=e.ref?`@${e.ref}`:"",v=(d=e,u=h,c=r,p=m,f=[],(!1===d.enabled&&f.push("disabled"),c.summarizeTextSurfaces&&(!0===d.selected&&f.push("selected"),eL(u)&&f.push("editable"),function(e,t){if("scroll-area"===t)return!0;let n=(e.type??"").toLowerCase(),a=`${e.role??""} ${e.subrole??""}`.toLowerCase();return n.includes("scroll")||a.includes("scroll")}(d,u)&&f.push("scrollable"),p.shouldSummarize))?(f.push(`preview:"${S(p.text).replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`),f.push("truncated"),[...new Set(f)]):f).map(e=>` [${e}]`).join(""),A=w?` "${w}"`:"";return n?`${g}${b} [${h}]${v}`.trimEnd():`${g}${b} [${h}]${A}${v}`.trimEnd()}function eP(e,t){var n,a;let r,i=e.label?.trim();if(i&&(n=t,a=i,("scroll-area"===n||"list"===n||"collection"===n||"table"===n)&&(r=a.trim().toLowerCase())&&/^(vertical|horizontal)\s+scroll\s+bar(?:,?\s*\d+\s+pages?)?$/.test(r)))return"";let o=e.value?.trim();if(eL(t)){if(o)return o;if(i)return i}else if(i)return i;if(o)return o;let s=e.identifier?.trim();return!s||e$(s)&&("group"===t||"image"===t||"list"===t||"collection"===t)?"":s}function eT(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 eL(e){return"text-field"===e||"text-view"===e||"search"===e}function e$(e){return/^[\w.]+:id\/[\w.-]+$/i.test(e)}function eF(e){return new Map(e.map(e=>[e.index,e]))}function eU(e){return e.label?.trim()||e.value?.trim()||e.identifier?.trim()||""}function eG(e,t,n){return t>=e.x&&t<=e.x+e.width&&n>=e.y&&n<=e.y+e.height}function eV(e){let t=null,n=-1;for(let a of e){let e=a.width*a.height;e>n&&(t=a,n=e)}return t}function eB(e,t,n,a){return Math.max(e,n)<=Math.min(t,a)}function ej(e){let t=`${e??""}`.toLowerCase();return t.includes("scroll")||t.includes("recyclerview")||t.includes("listview")||t.includes("gridview")||t.includes("collectionview")||"table"===t}function eq(e){return!!ej(e.type)||`${e.role??""} ${e.subrole??""}`.toLowerCase().includes("scroll")}function eX(e){if(0===e.length)return{nodes:e,hiddenCount:0,summaryLines:[]};let{byIndex:t,visibleNodeIndexes:n,offscreenNodes:a,hintedContainers:r}=ez(e),i=0===n.size?e:e.filter(e=>n.has(e.index));return{nodes:i.map(e=>(function(e,t){let n=t.get(e.index);if(!n||0===n.size)return e;let a=!!(!0===e.hiddenContentAbove||n.has("above"))||void 0,r=!!(!0===e.hiddenContentBelow||n.has("below"))||void 0;return{...e,hiddenContentAbove:a,hiddenContentBelow:r}})(e,r.directionsByContainer)),hiddenCount:0===n.size?0:e.length-i.length,summaryLines:function(e,t,n){let a=new Map;for(let r of e){let e=function(e,t,n){if(!e.rect)return null;let a=eH(e,t,n);return a?eY(e.rect,a):null}(r,t,n);if(!e)continue;let i=a.get(e)??[];i.push(r),a.set(e,i)}return["above","below"].flatMap(e=>{let t=a.get(e);if(!t||0===t.length)return[];let n=(function(e){let t=new Set,n=[];for(let a of e){let e=eU(a);!e||t.has(e)||(t.add(e),n.push(e))}return n})(t).slice(0,3).map(e=>`"${e}"`),r=1===t.length?"interactive item":"interactive items",i=n.length>0?`: ${n.join(", ")}`:"";return[`[off-screen ${e}] ${t.length} ${r}${i}`]})}(a.filter(e=>!r.coveredNodeIndexes.has(e.index)&&function(e){if(!0===e.hittable)return!0;let t=(e.type??"").toLowerCase();return t.includes("button")||t.includes("link")||t.includes("textfield")||t.includes("edittext")||t.includes("searchfield")||t.includes("checkbox")||t.includes("radio")||t.includes("switch")||t.includes("menuitem")||!!eU(e)}(e)),e,t)}}function ez(e){let t=eF(e),n=new Set,a=[];for(let r of e){if(eW(r,e,t)){!function(e,t,n){let a=e,r=new Set;for(;a&&!r.has(a.index);)r.add(a.index),t.add(a.index),a="number"==typeof a.parentIndex?n.get(a.parentIndex):void 0}(r,n,t);continue}a.push(r)}let r=function(e,t,n,a){let r=new Map,i=new Set;for(let e of t){if(!e.rect)continue;let t=eK(e,n,a);if(!t?.rect)continue;let o=eY(e.rect,t.rect);if(!o)continue;let s=r.get(t.index)??new Set;s.add(o),r.set(t.index,s),i.add(e.index)}return function(e,t,n,a){for(let r of e){let e=function(e){let t=function(e,t){if(!(e?.trim().toLowerCase()??"").includes("vertical scroll bar"))return null;let n=function(e){if(!e)return null;let t=/^(\d{1,3})%$/.exec(e.trim());if(!t)return null;let n=Number(t[1]);return Number.isFinite(n)?Math.max(0,Math.min(100,n)):null}(t);return null===n?null:n<=1?{above:!1,below:!0}:n>=99?{above:!0,below:!1}:{above:!0,below:!0}}(e.label,e.value);if(!t)return null;let n=new Set;return t.above&&n.add("above"),t.below&&n.add("below"),n.size>0?n:null}(r);if(!e||0===e.size)continue;let i=eK(r,t,n);if(!i)continue;let o=a.get(i.index)??new Set;for(let t of e)o.add(t);a.set(i.index,o)}}(e,n,a,r),{directionsByContainer:r,coveredNodeIndexes:i}}(e,a,n,t);return{byIndex:t,visibleNodeIndexes:n,offscreenNodes:a,hintedContainers:r}}function eW(e,t,n=eF(t)){var a;if(!e.rect)return!0;let r=eH(e,t,n);return!r||(a=e.rect,eB(a.x,a.x+a.width,r.x,r.x+r.width)&&eB(a.y,a.y+a.height,r.y,r.y+r.height))}function eH(e,t,n=eF(t)){let a=function(e,t){let n="number"==typeof e.parentIndex?t.get(e.parentIndex):void 0,a=new Set;for(;n&&!a.has(n.index);){if(a.add(n.index),n.rect&&eq(n))return n.rect;n="number"==typeof n.parentIndex?t.get(n.parentIndex):void 0}return null}(e,n);return a||function(e,t){let n=G(t),a=e.filter(e=>{var t;return!!(t=e.rect)&&Number.isFinite(t.x)&&Number.isFinite(t.y)&&Number.isFinite(t.width)&&Number.isFinite(t.height)}),r=a.filter(e=>{let t=(e.type??"").toLowerCase();return t.includes("application")||t.includes("window")}),i=eV(r.map(e=>e.rect).filter(e=>eG(e,n.x,n.y)));if(i)return i;let o=eV(r.map(e=>e.rect));if(o)return o;let s=eV(a.map(e=>e.rect).filter(e=>eG(e,n.x,n.y)));return s||null}(t,e.rect??{x:0,y:0,width:0,height:0})}function eY(e,t){return e.y+e.height<=t.y?"above":e.y>=t.y+t.height?"below":null}function eK(e,t,n){let a="number"==typeof e.parentIndex?n.get(e.parentIndex):void 0,r=new Set;for(;a&&!r.has(a.index);){if(r.add(a.index),t.has(a.index)&&eq(a))return a;a="number"==typeof a.parentIndex?n.get(a.parentIndex):void 0}return null}let eJ=100,eZ=new Set(["batch","replay"]),eQ=new Set(["command","positionals","flags","runtime"]);function e0(e){let t;try{t=JSON.parse(e)}catch{throw new w("INVALID_ARGS","Batch steps must be valid JSON.")}if(!Array.isArray(t)||0===t.length)throw new w("INVALID_ARGS","Batch steps must be a non-empty JSON array.");return t}function e1(e,t){if(!Array.isArray(e)||0===e.length)throw new w("INVALID_ARGS","batch requires a non-empty batchSteps array.");if(e.length>t)throw new w("INVALID_ARGS",`batch has ${e.length} steps; max allowed is ${t}.`);let n=[];for(let t=0;t<e.length;t+=1){let a=e[t];if(!a||"object"!=typeof a)throw new w("INVALID_ARGS",`Invalid batch step at index ${t}.`);let r=Object.keys(a).filter(e=>!eQ.has(e));if(r.length>0){let e=r.map(e=>`"${e}"`).join(", ");throw new w("INVALID_ARGS",`Batch step ${t+1} has unknown field(s): ${e}. Allowed fields: command, positionals, flags, runtime.`)}let i="string"==typeof a.command?a.command.trim().toLowerCase():"";if(!i)throw new w("INVALID_ARGS",`Batch step ${t+1} requires command.`);if(eZ.has(i))throw new w("INVALID_ARGS",`Batch step ${t+1} cannot run ${i}.`);if(void 0!==a.positionals&&!Array.isArray(a.positionals))throw new w("INVALID_ARGS",`Batch step ${t+1} positionals must be an array.`);let o=a.positionals??[];if(o.some(e=>"string"!=typeof e))throw new w("INVALID_ARGS",`Batch step ${t+1} positionals must contain only strings.`);if(void 0!==a.flags&&("object"!=typeof a.flags||Array.isArray(a.flags)||!a.flags))throw new w("INVALID_ARGS",`Batch step ${t+1} flags must be an object.`);if(void 0!==a.runtime&&("object"!=typeof a.runtime||Array.isArray(a.runtime)||!a.runtime))throw new w("INVALID_ARGS",`Batch step ${t+1} runtime must be an object.`);n.push({command:i,positionals:o,flags:a.flags??{},runtime:a.runtime})}return n}function e2(e,t){try{return i.sync.read(e)}catch(e){throw new w("COMMAND_FAILED",`Failed to decode ${t} as PNG`,{label:t,reason:e instanceof Error?e.message:String(e)})}}async function e3(e,t){if(!Number.isInteger(t)||t<1)throw new w("INVALID_ARGS","Screenshot max size must be a positive integer");let n=e2(await r.readFile(e),"screenshot"),a=Math.max(n.width,n.height);if(a<=t)return;let o=t/a,s=Math.max(1,Math.round(n.width*o)),l=Math.max(1,Math.round(n.height*o)),d=function(e,t,n){let a=new i({width:t,height:n});for(let r=0;r<n;r+=1){let i=r*e.height/n,o=(r+1)*e.height/n;for(let n=0;n<t;n+=1){let s=n*e.width/t,l=(n+1)*e.width/t,d=0,u=0,c=0,p=0,f=0;for(let t=Math.floor(i);t<Math.ceil(o);t+=1){let n=Math.min(t+1,o)-Math.max(t,i);for(let a=Math.floor(s);a<Math.ceil(l);a+=1){let r=n*(Math.min(a+1,l)-Math.max(a,s)),i=(t*e.width+a)*4;d+=(e.data[i]??0)*r,u+=(e.data[i+1]??0)*r,c+=(e.data[i+2]??0)*r,p+=(e.data[i+3]??0)*r,f+=r}}let h=(r*a.width+n)*4;a.data[h]=Math.round(d/f),a.data[h+1]=Math.round(u/f),a.data[h+2]=Math.round(c/f),a.data[h+3]=Math.round(p/f)}}return a}(n,s,l);await r.writeFile(e,i.sync.write(d))}async function e4(e,t,n){if("path"===t.kind&&!e.policy.allowLocalInputPaths)throw new w("INVALID_ARGS",`Local ${n.field??"input"} paths are not allowed by command policy`);try{return await e.artifacts.resolveInput(t,n)}catch(e){throw h(e)}}async function e5(e,t,n){if(t?.kind==="path"&&!e.policy.allowLocalOutputPaths)throw new w("INVALID_ARGS","Local output paths are not allowed by command policy");try{return await e.artifacts.reserveOutput(t,{...n,visibility:n.visibility??"client-visible",requestedClientPath:t?.kind==="downloadableArtifact"?t.clientPath??n.requestedClientPath:n.requestedClientPath})}catch(e){throw h(e)}}async function e8(e,t){try{return await e.artifacts.createTempFile(t)}catch(e){throw h(e)}}let e6=[0,187,255,255];function e9(e,t,n,a){if(t<0||t>=e.width||n<0||n>=e.height)return;let r=(n*e.width+t)*4;e.data[r]=a[0],e.data[r+1]=a[1],e.data[r+2]=a[2],e.data[r+3]=a[3]}function e7(e,t,n){return Math.min(Math.max(e,t),n)}let te={icon:90,toggle:90,chevron:75,separator:45,visual:35,background:10},tt={leading:20,trailing:20,separator:10,unknown:0,background:-30};function tn(e){return"background"!==e.likelyKind}function ta(e,t){return e.width>=.25*t.width||e.height>=.06*t.height}function tr(e,t){let n,a=0;for(let r of t){let t=td(e,r.rect);t<=a||(a=t,n=r)}return n}function ti(e){let t=[];for(let n of[...e].sort((e,t)=>e.rect.y-t.rect.y)){let e=t.find(e=>{var t,a;return t=e.rect,td(t,a=n.rect)>0||Math.abs(tu(t).y-tu(a).y)<=.5*Math.max(t.height,a.height)});if(!e){t.push({rect:n.rect,blocks:[n]});continue}e.blocks.push(n),e.blocks.sort((e,t)=>e.rect.x-t.rect.x),e.rect=function(e){let t=1/0,n=1/0,a=-1/0,r=-1/0;for(let i of e)t=Math.min(t,i.x),n=Math.min(n,i.y),a=Math.max(a,i.x+i.width),r=Math.max(r,i.y+i.height);return{x:t,y:n,width:a-t,height:r-n}}([e.rect,n.rect])}return t}function to(e,t){let n,a=tu(e);for(let e of t){var r,i;let t=Math.sqrt((r=a,i=tu(e.rect),(r.x-i.x)**2+(r.y-i.y)**2));n&&t>=n.distance||(n={block:e,distance:t})}return n}function ts(e){let t=tl(e);return e.differentPixels>=24&&t.width>=3&&t.height>=3}function tl(e){return{x:e.minX,y:e.minY,width:e.maxX-e.minX+1,height:e.maxY-e.minY+1}}function td(e,t){return Math.max(0,Math.min(e.y+e.height,t.y+t.height)-Math.max(e.y,t.y))}function tu(e){return{x:e.x+e.width/2,y:e.y+e.height/2}}function tc(e,t,n){return Math.min(Math.max(e,t),n)}async function tp(e){if(await ee("tesseract"))try{let[t,n]=await Promise.all([th(e.baselinePath),th(e.currentPath)]);if(0!==t.exitCode||0!==n.exitCode)return;let a=tf(t.stdout,e.width,e.height),r=tf(n.stdout,e.width,e.height),i=function(e,t){let n=new Set,a=[];for(let i of e){var r;let e=tA(i.text),o=function(e,t,n,a){let r=null,i=1/0;for(let l=0;l<n.length;l+=1){var o,s;if(a.has(l))continue;let d=n[l];if(tA(d.text)!==t)continue;let u=(o=ty(e.normalizedRect),s=ty(d.normalizedRect),(o.x-s.x)**2+(o.y-s.y)**2);u>=i||(r=l,i=u)}return r}(i,e,t,n);if(null===o)continue;n.add(o);let s=function(e,t){let n={x:t.rect.x-e.rect.x,y:t.rect.y-e.rect.y,width:t.rect.width-e.rect.width,height:t.rect.height-e.rect.height},a=tN(t.rect.width/e.rect.width),r=tN(t.rect.height/e.rect.height),i=Math.abs(a-1)>=.08||Math.abs(r-1)>=.12;return{text:e.text,baselineRect:e.rect,currentRect:t.rect,delta:n,confidence:Math.round(100*Math.min(e.confidence,t.confidence))/100,possibleTextMetricMismatch:i}}(i,t[o]);r=s,(Math.abs(r.delta.x)>=2||Math.abs(r.delta.y)>=2||Math.abs(r.delta.width)>=2||Math.abs(r.delta.height)>=2||r.possibleTextMetricMismatch)&&a.push(s)}return a.sort((e,t)=>tm(t)-tm(e)).slice(0,12)}(a,r),o=function(e){let t=[];for(let n of[...e].sort((e,t)=>e.currentRect.y-t.currentRect.y)){let e=t.find(e=>32>=Math.abs(n.delta.x-tI(e.map(e=>e.delta.x))));e?e.push(n):t.push([n])}return t.filter(e=>e.length>=2).map(tw).filter(e=>e.yRange.max-e.yRange.min<=60).sort((e,t)=>tg(t)-tg(e)).slice(0,4)}(i);if(0===a.length&&0===r.length)return;return{provider:"tesseract",baselineBlocks:a.length,currentBlocks:r.length,baselineBlocksRaw:a,currentBlocksRaw:r,matches:i,...o.length>0?{movementClusters:o}:{}}}catch{return}}function tf(e,t,n){let[a,...r]=e.split(/\r?\n/);if(!a)return[];let i=new Map(a.split(" ").map((e,t)=>[e,t])),o=[];for(let e of r){var s;if(!e.trim())continue;let t=e.split(" "),n=tv(t,i,"level"),a=tb(t,i,"text").trim(),r=tv(t,i,"conf");if(5!==n||(s=a,!/[\p{L}\p{N}]/u.test(s))||r<0)continue;let l=tv(t,i,"left"),d=tv(t,i,"top"),u=tv(t,i,"width"),c=tv(t,i,"height");u<=0||c<=0||o.push({key:[tb(t,i,"page_num"),tb(t,i,"block_num"),tb(t,i,"par_num"),tb(t,i,"line_num")].join(":"),text:a,confidence:r,rect:{x:l,y:d,width:u,height:c}})}let l=new Map;for(let e of o){let t=l.get(e.key);t?t.push(e):l.set(e.key,[e])}return Array.from(l.values()).flatMap(e=>(function(e){let t=[...e].sort((e,t)=>e.rect.x-t.rect.x),n=[],a=[];for(let e of t){let t=a.at(-1);if(!t){a.push(e);continue}if(e.rect.x-(t.rect.x+t.rect.width)>Math.max(48,2.5*Math.max(t.rect.height,e.rect.height))){n.push(a),a=[e];continue}a.push(e)}return a.length>0&&n.push(a),n})(e)).map(e=>(function(e,t,n){if(0===e.length)return null;let a=[...e].sort((e,t)=>e.rect.x-t.rect.x),r=function(e){let t=1/0,n=1/0,a=-1/0,r=-1/0;for(let i of e)t=Math.min(t,i.x),n=Math.min(n,i.y),a=Math.max(a,i.x+i.width),r=Math.max(r,i.y+i.height);return{x:t,y:n,width:a-t,height:r-n}}(a.map(e=>e.rect)),i=Math.round(100*tI(a.map(e=>e.confidence)))/100;return{text:a.map(e=>e.text).join(" "),confidence:i,rect:r,normalizedRect:{x:tx(r.x/t),y:tx(r.y/n),width:tx(r.width/t),height:tx(r.height/n)}}})(e,t,n)).filter(e=>null!==e)}function th(e){return Z("tesseract",[e,"stdout","-l","eng","tsv"],{allowFailure:!0,timeoutMs:1e4})}function tm(e){return Math.abs(e.delta.x)+Math.abs(e.delta.y)+Math.abs(e.delta.width)+Math.abs(e.delta.height)+25*!!e.possibleTextMetricMismatch}function tw(e){let t=e.map(e=>e.delta.x),n=e.map(e=>e.delta.y);return{texts:e.map(e=>e.text),xRange:{min:Math.min(...t),max:Math.max(...t)},yRange:{min:Math.min(...n),max:Math.max(...n)}}}function tg(e){return 2*Math.abs((e.xRange.min+e.xRange.max)/2)+Math.abs((e.yRange.min+e.yRange.max)/2)}function ty(e){return{x:e.x+e.width/2,y:e.y+e.height/2}}function tb(e,t,n){let a=t.get(n);return void 0===a?"":e[a]??""}function tv(e,t,n){let a=Number(tb(e,t,n));return Number.isFinite(a)?a:0}function tA(e){return e.trim().replace(/\s+/g," ").toLowerCase()}function tI(e){return e.reduce((e,t)=>e+t,0)/e.length}function tx(e){return Math.round(100*e*100)/100}function tN(e){return Math.round(1e3*e)/1e3}function tS(e,t,n,a){return{r:Math.round(e/a),g:Math.round(t/a),b:Math.round(n/a)}}function t_(e){return .2126*e.r+.7152*e.g+.0722*e.b}function tM(e){return`#${tk(e.r)}${tk(e.g)}${tk(e.b)}`}function tk(e){return e.toString(16).padStart(2,"0")}function tD(e){return Math.round(100*e*100)/100}let tE=255*Math.sqrt(3);async function tO(e,t,n={}){let a,s,l,d;await tC(e,"Baseline image not found"),await tC(t,"Current screenshot not found");let u=n.outputPath,[c,p]=await Promise.all([r.readFile(e),r.readFile(t)]),f=e2(c,"baseline screenshot"),h=e2(p,"current screenshot");tR(f.width,f.height,"baseline screenshot",n.maxPixels),tR(h.width,h.height,"current screenshot",n.maxPixels);let m=n.threshold??.1;if(f.width!==h.width||f.height!==h.height){let e=f.width*f.height;return await tP(n.outputPath),{match:!1,mismatchPercentage:100,totalPixels:e,differentPixels:e,dimensionMismatch:{expected:{width:f.width,height:f.height},actual:{width:h.width,height:h.height}}}}let w=f.width*f.height,g=m*tE,y=new i({width:f.width,height:f.height}),b=new Uint8Array(w),v=0;for(let e=0,t=0;e<f.data.length;e+=4,t+=1){if(Math.sqrt((f.data[e]-h.data[e])**2+(f.data[e+1]-h.data[e+1])**2+(f.data[e+2]-h.data[e+2])**2)>g){v+=1,b[t]=1;let n=tT(h,e);y.data[e]=tL(n,220,.78),y.data[e+1]=tL(n,0,.78),y.data[e+2]=tL(n,0,.78),y.data[e+3]=255;continue}let n=tT(h,e);y.data[e]=n,y.data[e+1]=n,y.data[e+2]=n,y.data[e+3]=255}let A=v>0?(x=(a=function(e){let{diffMask:t,baseline:n,current:a}=e,{width:r,height:i}=n,o=new Uint8Array(t.length),s=new Int32Array(t.length),l=[];for(let e=0;e<t.length;e+=1){if(1!==t[e]||1===o[e])continue;let d=0,u=0;s[0]=e,u+=1,o[e]=1;let c=e%r,p=Math.floor(e/r),f={minX:c,minY:p,maxX:c,maxY:p,differentPixels:0,baselineRed:0,baselineGreen:0,baselineBlue:0,currentRed:0,currentGreen:0,currentBlue:0};for(;d<u;){let e=s[d];d+=1,function(e,t,n,a,r){let i=t%n,o=Math.floor(t/n),s=4*t;e.minX=Math.min(e.minX,i),e.minY=Math.min(e.minY,o),e.maxX=Math.max(e.maxX,i),e.maxY=Math.max(e.maxY,o),e.differentPixels+=1,e.baselineRed+=a.data[s],e.baselineGreen+=a.data[s+1],e.baselineBlue+=a.data[s+2],e.currentRed+=r.data[s],e.currentGreen+=r.data[s+1],e.currentBlue+=r.data[s+2]}(f,e,r,n,a);let l=e%r,c=Math.floor(e/r);for(let e=-1;e<=1;e+=1){let n=c+e;if(!(n<0)&&!(n>=i))for(let a=-1;a<=1;a+=1){if(0===a&&0===e)continue;let i=l+a;if(i<0||i>=r)continue;let d=n*r+i;1===t[d]&&1!==o[d]&&(o[d]=1,s[u]=d,u+=1)}}}l.push(f)}return l}(I={diffMask:b,baseline:f,current:h,totalPixels:w,differentPixels:v,maxRegions:n.maxRegions})).length<=2e3?function(e){let t=[];for(let r of e.sort((e,t)=>{let n=e.minY-t.minY;return 0!==n?n:e.minX-t.minX})){var n,a;let e=t.find(e=>{var t,n,a;return t=e,n=r,a=12,t.minX-a<=n.maxX&&n.minX-a<=t.maxX&&t.minY-a<=n.maxY&&n.minY-a<=t.maxY});if(!e){t.push({...r});continue}n=e,a=r,n.minX=Math.min(n.minX,a.minX),n.minY=Math.min(n.minY,a.minY),n.maxX=Math.max(n.maxX,a.maxX),n.maxY=Math.max(n.maxY,a.maxY),n.differentPixels+=a.differentPixels,n.baselineRed+=a.baselineRed,n.baselineGreen+=a.baselineGreen,n.baselineBlue+=a.baselineBlue,n.currentRed+=a.currentRed,n.currentGreen+=a.currentGreen,n.currentBlue+=a.currentBlue}return t}(a):a,x.flatMap(e=>{var t,n,a;let r;return(t=e,n=I.baseline.width,a=I.baseline.height,r=t.maxX-t.minX+1,t.maxY-t.minY+1>=Math.max(48,Math.round(.07*a))&&r>=.35*n)?function(e,t,n){var a;let r=function(e,t){let n=[],a=null;for(let r=0;r<e.length;r+=1){if(e[r]<=t){a??=r;continue}null!==a&&(r-a>=6&&n.push([a,r-1]),a=null)}return null!==a&&e.length-a>=6&&n.push([a,e.length-1]),n}((a=function(e,t,n){let a=[];for(let r=e.minY;r<=e.maxY;r+=1){let i=0;for(let a=e.minX;a<=e.maxX;a+=1)1===t[r*n+a]&&(i+=1);a.push(i)}return a}(e,t.diffMask,t.baseline.width)).map((e,t)=>{let n=0,r=0,i=Math.max(0,t-3),o=Math.min(a.length-1,t+3);for(let e=i;e<=o;e+=1)n+=a[e],r+=1;return Math.round(n/r)}),Math.max(1,Math.round((e.maxX-e.minX+1)*.08))),i=function(e,t,n){let a=[],r=e.minY;for(let[i,o]of t){let t=e.minY+Math.round((i+o)/2);t-r+1<n||e.maxY-t<n||(a.push([r,t]),r=t+1)}return a.push([r,e.maxY]),a}(e,r,n);if(i.length<=1)return[e];let o=i.map(([n,a])=>(function(e,t,n,a){let r=null;for(let s=t;s<=n;s+=1)for(let t=e.minX;t<=e.maxX;t+=1){var i,o;let e=s*a.baseline.width+t;1===a.diffMask[e]&&function(e,t,n,a,r,i){let o=4*t;e.minX=Math.min(e.minX,n),e.minY=Math.min(e.minY,a),e.maxX=Math.max(e.maxX,n),e.maxY=Math.max(e.maxY,a),e.differentPixels+=1,e.baselineRed+=r.data[o],e.baselineGreen+=r.data[o+1],e.baselineBlue+=r.data[o+2],e.currentRed+=i.data[o],e.currentGreen+=i.data[o+1],e.currentBlue+=i.data[o+2]}(r??={minX:i=t,minY:o=s,maxX:i,maxY:o,differentPixels:0,baselineRed:0,baselineGreen:0,baselineBlue:0,currentRed:0,currentGreen:0,currentBlue:0},e,t,s,a.baseline,a.current)}return r})(e,n,a,t)).filter(e=>null!==e);return o.length>1?o:[e]}(e,I,Math.max(24,Math.round(.03*I.baseline.height))):[e]})).sort((e,t)=>{let n=t.differentPixels-e.differentPixels;if(0!==n)return n;let a=e.minY-t.minY;return 0!==a?a:e.minX-t.minX}).slice(0,Math.max(0,I.maxRegions??8)).map((e,t)=>{var n,a,r,i,o,s,l,d,u,c,p;let f,h,m,w,g,y,b,v,A,x,N,S,_,M,k,D,E;return n=e,a=t+1,r={width:I.baseline.width,height:I.baseline.height,totalPixels:I.totalPixels,differentPixels:I.differentPixels},y={x:n.minX,y:n.minY,width:n.maxX-n.minX+1,height:n.maxY-n.minY+1},b={x:Math.round(n.minX+y.width/2),y:Math.round(n.minY+y.height/2)},v=tS(n.baselineRed,n.baselineGreen,n.baselineBlue,n.differentPixels),A=tS(n.currentRed,n.currentGreen,n.currentBlue,n.differentPixels),x=y.width*y.height,N=tD(n.differentPixels/x),S=Math.round(t_(v)),_=Math.round(t_(A)),M=(i=y,o=r.width,s=r.height,i.width>=.55*o&&i.height>=.12*s?"large-area":i.width>=2.5*i.height?"horizontal-band":i.height>=2.5*i.width?"vertical-band":"compact"),k=(f=x/r.totalPixels)>=.04?"large":f>=.01?"medium":"small",D=(l=v,d=A,h=t_(l),Math.abs(m=t_(d)-h)>=12?m>0?"brighter":"darker":Math.max(Math.abs(d.r-l.r),Math.abs(d.g-l.g),Math.abs(d.b-l.b))>=12?"color-shift":"mixed"),E=(u=b,c=r.width,p=r.height,w=u.x<c/3?"left":u.x>2*c/3?"right":"center",g=u.y<p/3?"top":u.y>2*p/3?"bottom":"middle","center"===w&&"middle"===g?"center":`${g}-${w}`),{index:a,rect:y,normalizedRect:{x:tD(y.x/r.width),y:tD(y.y/r.height),width:tD(y.width/r.width),height:tD(y.height/r.height)},differentPixels:n.differentPixels,shareOfDiffPercentage:tD(n.differentPixels/r.differentPixels),densityPercentage:N,shape:M,size:k,location:E,averageBaselineColorHex:tM(v),averageCurrentColorHex:tM(A),baselineLuminance:S,currentLuminance:_,dominantChange:D}}):[];if(v>0&&u){var I,x,N;for(let e of A)e.rect.width<4||e.rect.height<4||function(e,t){let n=e7(t.x,0,e.width-1),a=e7(t.y,0,e.height-1),r=e7(t.x+t.width-1,0,e.width-1),i=e7(t.y+t.height-1,0,e.height-1);for(let t=0;t<2;t+=1){for(let o=n;o<=r;o+=1)e9(e,o,a+t,e6),e9(e,o,i-t,e6);for(let o=a;o<=i;o+=1)e9(e,n+t,o,e6),e9(e,r-t,o,e6)}}(y,e.rect);await r.mkdir(o.dirname(u),{recursive:!0}),await r.writeFile(u,i.sync.write(y))}else await tP(n.outputPath);let S=v>0?await tp({baselinePath:e,currentPath:t,width:f.width,height:f.height}):void 0,_=S&&(S.matches.length>0||(S.movementClusters?.length??0)>0)?{provider:S.provider,baselineBlocks:S.baselineBlocks,currentBlocks:S.currentBlocks,matches:S.matches,...S.movementClusters?{movementClusters:S.movementClusters}:{}}:void 0,M=v>0&&S?(s=function(e){let t=[];for(let n of e.sort((e,t)=>e.minY-t.minY||e.minX-t.minX)){let e=t.find(e=>{var t,a,r;return t=e,a=n,r=10,t.minX-r<=a.maxX&&a.minX-r<=t.maxX&&t.minY-r<=a.maxY&&a.minY-r<=t.maxY});if(!e){t.push({...n});continue}e.minX=Math.min(e.minX,n.minX),e.minY=Math.min(e.minY,n.minY),e.maxX=Math.max(e.maxX,n.maxX),e.maxY=Math.max(e.maxY,n.maxY),e.differentPixels+=n.differentPixels}return t}(function(e,t,n){let a=new Uint8Array(e.length),r=new Int32Array(e.length),i=[];for(let o=0;o<e.length;o+=1){if(1!==e[o]||1===a[o])continue;let s=0,l=0;r[0]=o,l+=1,a[o]=1;let d=o%t,u=Math.floor(o/t),c={minX:d,minY:u,maxX:d,maxY:u,differentPixels:0};for(;s<l;){let i=r[s];s+=1;let o=i%t,d=Math.floor(i/t);c.minX=Math.min(c.minX,o),c.minY=Math.min(c.minY,d),c.maxX=Math.max(c.maxX,o),c.maxY=Math.max(c.maxY,d),c.differentPixels+=1;for(let i=-1;i<=1;i+=1){let s=d+i;if(!(s<0)&&!(s>=n))for(let n=-1;n<=1;n+=1){if(0===n&&0===i)continue;let d=o+n;if(d<0||d>=t)continue;let u=s*t+d;1===e[u]&&1!==a[u]&&(a[u]=1,r[l]=u,l+=1)}}}i.push(c)}return i}(function(e,t,n,a){let r=new Uint8Array(e);if(!a)return r;for(let e of[...a.baselineBlocksRaw,...a.currentBlocksRaw]){var i;!function(e,t,n,a){let r=tc(Math.floor(a.x),0,t-1),i=tc(Math.floor(a.y),0,n-1),o=tc(Math.ceil(a.x+a.width),0,t),s=tc(Math.ceil(a.y+a.height),0,n);for(let n=i;n<s;n+=1)for(let a=r;a<o;a+=1)e[n*t+a]=0}(r,t,n,{x:(i=e.rect).x-8,y:i.y-8,width:i.width+16,height:i.height+16})}return r}((N={diffMask:b,width:f.width,height:f.height,regions:A,ocr:S}).diffMask,N.width,N.height,N.ocr),N.width,N.height)),l=ti(N.ocr?.currentBlocksRaw??[]),d=ti(N.ocr?.baselineBlocksRaw??[]),s.filter(ts).map(e=>{var t,n,a,r,i,o,s,u,c,p,f;let h,m,w,g,y,b,v,A,I,x;return t=e,n=N,a=l,r=d,g=function(e,t){let n,a=0;for(let r of t){let t=function(e,t){let n=Math.max(e.x,t.x),a=Math.max(e.y,t.y),r=Math.min(e.x+e.width,t.x+t.width),i=Math.min(e.y+e.height,t.y+t.height);return r<=n||i<=a?0:(r-n)*(i-a)}(e,r.rect);t<=a||(a=t,n=r)}return n?.index}(w=tl(t),n.regions),y=function(e,t,n){let a=tr(e,t);if(a)return to(e,a.blocks);let r=tr(e,n);return r?to(e,r.blocks):void 0}(w,a,r),b=function(e,t,n){if(e.height<=3&&e.width>=.12*n)return"separator";if(!t)return e.width>=.4*n?"background":"unknown";if(e.width>=.4*n)return"background";let a=e.x+e.width/2,r=t.x+t.width/2;return a<r-t.width/2?"leading":a>r+t.width/2?"trailing":e.width>=.35*n?"background":"unknown"}(w,y?.block.rect,n.width),v=(i=w,o=b,s=t.differentPixels,u=n,h=i.width/i.height,m=s/(i.width*i.height),"separator"===o?"separator":"background"===o?"background":"trailing"===o&&h>=1.5&&h<=3.8&&m>=.35?"toggle":"trailing"===o&&i.width<=.06*u.width&&i.height<=.04*u.height?"chevron":"leading"===o&&h>=.55&&h<=1.8?"icon":ta(i,u)?"background":"visual"),A={...g?{regionIndex:g}:{},slot:b,likelyKind:v,rect:w},{...g?{regionIndex:g}:{},slot:b,likelyKind:v,rect:w,...y?{nearestText:y.block.text.trim().replace(/^[^\p{L}\p{N}]+/u,"").replace(/^\p{L}\s+/u,"")}:{},score:(c=A,p=t.differentPixels,f=n,I=ta(c.rect,f)?-35:0,x=20*!!c.regionIndex,te[c.likelyKind]+tt[c.slot]+x+I+Math.min(20,p/200))}}).filter(e=>e.rect.y>=.08*N.height).filter(tn).sort((e,t)=>t.score-e.score).slice(0,Math.max(0,N.maxDeltas??12)).map((e,t)=>{var n;return n=e,{index:t+1,...n.regionIndex?{regionIndex:n.regionIndex}:{},slot:n.slot,likelyKind:n.likelyKind,rect:n.rect,...n.nearestText?{nearestText:n.nearestText}:{}}})):[],k=w>0?Math.round(v/w*1e4)/100:0;return{...v>0&&u?{diffPath:u}:{},...A.length>0?{regions:A}:{},..._?{ocr:_}:{},...M.length>0?{nonTextDeltas:M}:{},totalPixels:w,differentPixels:v,mismatchPercentage:k,match:0===v}}async function tC(e,t){try{await r.access(e)}catch{throw new w("INVALID_ARGS",`${t}: ${e}`)}}function tR(e,t,n,a){if(null==a||a<=0)return;let r=e*t;if(!(r<=a))throw new w("INVALID_ARGS",`${n} is ${r} pixels, which exceeds the configured maxImagePixels limit of ${a}`)}async function tP(e){if(e)try{await r.unlink(e)}catch(e){var t;if(!("object"==typeof(t=e)&&null!==t&&"code"in t&&"ENOENT"===t.code))throw e}}function tT(e,t){return tL(Math.round(.299*e.data[t]+.587*e.data[t+1]+.114*e.data[t+2]),255,.72)}function tL(e,t,n){return Math.round(e*(1-n)+t*n)}function t$(e){return e.width*e.height}function tF(e){return Math.round(100*e*100)/100}async function tU(e,t){let n=await e8(e,{prefix:"agent-device-diff-current",ext:".png"});try{await tV(e,t,n.path,tB(t))}catch(e){throw await n.cleanup(),e}return n}async function tG(e,t,n,a,r){var i,o,s,l;if(!t.overlayRefs)return a;if(a.match||a.dimensionMismatch)return n&&await tq(n),a;let d=(i=t,o=n,i.currentOverlayOut?i.currentOverlayOut:i.out?.kind==="path"?{kind:"path",path:tj(o??i.out.path)}:i.out?.kind==="downloadableArtifact"?{kind:"downloadableArtifact",...i.out.clientPath?{clientPath:tj(i.out.clientPath)}:{},...i.out.fileName?{fileName:tj(i.out.fileName)}:{}}:void 0),u=await e5(e,d,{field:"currentOverlayPath",ext:".png"});try{let n=await tV(e,t,u.path,{overlayRefs:!0,...tB(t)}),i=await u.publish();return i&&r.push(i),{...a,currentOverlayPath:n.path??u.path,...n.overlayRefs?{currentOverlayRefCount:n.overlayRefs.length}:{},...a.regions&&n.overlayRefs?{regions:(s=a.regions,l=n.overlayRefs,s.map(e=>{var t,n;let a,r=(t=e,n=l,a=t$(t.rect),n.map(e=>{var n,r;let i,o,s,l,d=e.overlayRect,u=(n=t.rect,r=d,i=Math.max(n.x,r.x),o=Math.max(n.y,r.y),s=Math.min(n.x+n.width,r.x+r.width),l=Math.min(n.y+n.height,r.y+r.height),s<=i||l<=o?0:(s-i)*(l-o));return u<=0?null:{ref:e.ref,...e.label?{label:e.label}:{},rect:d,overlayCoveragePercentage:tF(u/t$(d)),regionCoveragePercentage:tF(u/a)}}).filter(e=>null!==e).sort((e,t)=>{let n=t.regionCoveragePercentage-e.regionCoveragePercentage;return 0!==n?n:t.overlayCoveragePercentage-e.overlayCoveragePercentage}).slice(0,3).map(e=>({ref:e.ref,...e.label?{label:e.label}:{},rect:e.rect,regionCoveragePercentage:e.regionCoveragePercentage})));return r.length>0?{...e,currentOverlayMatches:r}:e}))}:{}}}catch(e){throw await u.cleanup?.(),e}}async function tV(e,t,n,a={}){if(!e.backend.captureScreenshot)throw new w("UNSUPPORTED_OPERATION","screenshot is not supported by this backend");return await e.backend.captureScreenshot({session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata},n,a)??{}}function tB(e){return e.surface?{surface:e.surface}:{}}function tj(e){let t=o.extname(e),n=t?e.slice(0,-t.length):e;return`${n}.current-overlay${t||".png"}`}async function tq(e){try{await r.unlink(tj(e))}catch(e){var t;if(!("object"==typeof(t=e)&&null!==t&&"code"in t&&"ENOENT"===t.code))throw e}}function tX(e){return"live"===e.kind}function tz(e,t){let n=eT(e.type??"Element"),a=eP(e,n),r=!1===e.enabled?"disabled":"enabled",i=!0===e.selected?"selected":"unselected",o=!0===e.hittable?"hittable":"not-hittable";return[String(t??e.depth??0),n,a,r,i,o].join("|")}function tW(e,t){return t.flatten?e.map(e=>({text:eR(e,0,!1),comparable:tz(e,0)})):eC(e).map(e=>({text:e.text,comparable:tz(e.node,e.depth)}))}function tH(e,t){return e.get(t)??0}function tY(e){return"text"===e||"label"===e||"any"===e}function tK(e,t){return{session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata}}function tJ(e){return e.clock?.now()??Date.now()}async function tZ(e,t){e.clock?await e.clock.sleep(t):await new Promise(e=>setTimeout(e,t))}async function tQ(e,t){var n,a,r,i,o;let s,l,d,u,c,p;if(!e.backend.captureSnapshot)throw new w("UNSUPPORTED_OPERATION","snapshot is not supported by this backend");let f=t.session??"default",h=await e.sessions.get(f),m=await e.backend.captureSnapshot({session:f,requestId:t.requestId,appId:h?.appId,appBundleId:h?.appBundleId,signal:t.signal??e.signal,metadata:t.metadata},{interactiveOnly:t.interactiveOnly,compact:t.compact,depth:t.depth,scope:t.scope,raw:t.raw}),g=(n=m,a=e,n.snapshot?n.snapshot:{nodes:n.nodes??[],truncated:n.truncated,backend:n.backend,createdAt:tJ(a)}),y=tJ(e);return{snapshot:g,result:m,session:h,warnings:(s=[...(r={result:m,snapshot:g,options:t,session:h,capturedAt:g.createdAt??y,runtimeNow:y}).result.warnings??[]],l=!0===r.options.interactiveOnly,d=r.result.analysis,"android"===r.snapshot.backend&&l&&0===r.snapshot.nodes.length&&d&&(d.rawNodeCount??0)>=12&&(s.push(`Interactive snapshot is empty after filtering ${d.rawNodeCount} raw Android nodes. Likely causes: depth too low, transient route change, or collector filtering.`),"number"==typeof r.options.depth&&"number"==typeof d.maxDepth&&d.maxDepth>=r.options.depth+2&&s.push(`Interactive output is empty at depth ${r.options.depth}; retry without -d.`)),c=!!(u=r.session?.snapshot)&&[r.capturedAt,r.runtimeNow].some(e=>{let t=e-u.createdAt;return t>=0&&t<=2e3}),!r.result.freshness&&u&&c&&(i=u.nodes.length,o=r.snapshot.nodes.length,!(i<12)&&o<=Math.floor(.2*i))&&s.push("Recent snapshots dropped sharply in node count, which suggests stale or mid-transition UI. Use screenshot as visual truth, wait briefly, then re-snapshot once."),p=r.result.freshness,p?.staleAfterRetries&&"android"===r.snapshot.backend&&("stuck-route"===p.reason?s.push(`Recent ${p.action} was followed by a nearly identical snapshot after ${p.retryCount} automatic retr${1===p.retryCount?"y":"ies"}. If you expected navigation or submit, the tree may still be stale. Use screenshot as visual truth, wait briefly, then re-snapshot once.`):"sharp-drop"===p.reason&&s.push("Recent snapshots dropped sharply in node count, which suggests stale or mid-transition UI. Use screenshot as visual truth, wait briefly, then re-snapshot once.")),Array.from(new Set(s)))}}function t0(e,t){let n=t.session?.name??e??"default";return{...t.session??{name:n},name:n,snapshot:t.snapshot,appName:t.result.appName??t.session?.appName,appBundleId:t.result.appBundleId??t.session?.appBundleId}}function t1(e){return["visible","hidden","exists","editable","selected","text"].includes(e)}function t2(e){return!!(e&&Number.isFinite(e.x)&&Number.isFinite(e.y)&&Number.isFinite(e.width)&&Number.isFinite(e.height)&&e.width>0&&e.height>0)}async function t3(e,t){let n=t??"default",a=await e.sessions.get(n);if(!a)throw new w("SESSION_NOT_FOUND","No active session. Run open first.");if(!a.snapshot)throw new w("INVALID_ARGS","No snapshot in session. Run snapshot first.");return{sessionName:n,session:a,snapshot:a.snapshot}}async function t4(e,t,n={updateSession:!0}){if(!e.backend.captureSnapshot)throw new w("UNSUPPORTED_OPERATION","snapshot is not supported by this backend");let a=t.session??"default",r=await e.sessions.get(a),i=await e.backend.captureSnapshot(tK(e,t),{interactiveOnly:!1,compact:!1,depth:t.depth,scope:n.scope??t.scope,raw:t.raw}),o=i.snapshot??{nodes:i.nodes??[],truncated:i.truncated,backend:i.backend,createdAt:tJ(e)};return n.updateSession&&r&&await e.sessions.set({...r,snapshot:o}),{sessionName:a,session:r,snapshot:o}}async function t5(e,t,n){if(e.backend.readText){let a=await e.backend.readText(tK(e,{session:t.sessionName}),n);if(a.text.trim())return a.text}return R(n)}let t8=async(e,t)=>{if("ref"===t.target.kind){let n=await t3(e,t.session),a=function(e,t,n){let a=V(t);if(!a)throw new w("INVALID_ARGS",n.invalidRefMessage);let r=U(e,a)??(n.fallbackLabel.length>0?E(e,n.fallbackLabel):null);if(!r)throw new w("COMMAND_FAILED",n.notFoundMessage);return{ref:a,node:r}}(n.snapshot.nodes,t.target.ref,{fallbackLabel:t.target.fallbackLabel??"",invalidRefMessage:"get text requires a ref like @e2",notFoundMessage:`Ref ${t.target.ref} not found`}),r=M(a.node,e.backend.platform,{action:"get"}),i={kind:"ref",ref:`@${a.ref}`};return"attrs"===t.property?{kind:"attrs",target:i,node:a.node,selectorChain:r}:{kind:"text",target:i,text:await t5(e,n,a.node),node:a.node,selectorChain:r}}let n=await nl(e,t,t.session??"default",{selector:t.target.selector,disambiguateAmbiguous:"text"===t.property}),a=M(n.node,e.backend.platform,{action:"get"});if("attrs"===t.property)return{kind:"attrs",target:{kind:"selector",selector:n.selector},node:n.node,selectorChain:a};let r=await t5(e,n.capture,n.node);return{kind:"text",target:{kind:"selector",selector:n.selector},text:r,node:n.node,selectorChain:a}},t6=async(e,t)=>{let n=await t8(e,{...t,property:"text",target:t.target});if("text"!==n.kind)throw new w("COMMAND_FAILED","getText returned non-text result");return n},t9=async(e,t)=>{let n=await t8(e,{...t,property:"attrs",target:t.target});if("attrs"!==n.kind)throw new w("COMMAND_FAILED","getAttrs returned non-attrs result");return n},t7=async(e,t)=>{if(!t1(t.predicate))throw new w("INVALID_ARGS","is requires predicate: visible|hidden|exists|editable|selected|text");if("text"===t.predicate&&!t.expectedText)throw new w("INVALID_ARGS","is text requires expected text value");let n=await t4(e,t,{updateSession:!0}),a=A(t.selector);if("exists"===t.predicate){let r=P(n.snapshot.nodes,a,{platform:e.backend.platform});if(!r)throw new w("COMMAND_FAILED",$(a,[],{unique:!1}));return{predicate:t.predicate,pass:!0,selector:r.selector.raw,matches:r.matches,selectorChain:a.selectors.map(e=>e.raw)}}let r=T(n.snapshot.nodes,a,{platform:e.backend.platform,requireRect:!1,requireUnique:!0,disambiguateAmbiguous:!1});if(!r)throw new w("COMMAND_FAILED",$(a,[],{unique:!0}));let i=function(e){let{predicate:t,node:n,nodes:a,expectedText:r,platform:i}=e,o=b(n),s=x(n,i),l=!0===n.selected,d="text"===t?I(n):function(e,t){if(!0===e.hittable)return!0;if(t2(e.rect))return eW(e,t);if(e.rect)return!1;let n=function(e,t){let n=new Map(t.map(e=>[e.index,e])),a=e,r=new Set;for(;"number"==typeof a.parentIndex&&!r.has(a.index);){r.add(a.index);let e=n.get(a.parentIndex);if(!e)break;if(function(e){let t=L(e.type??"");return!(t.includes("application")||t.includes("window")||t.includes("scrollview")||t.includes("tableview")||t.includes("collectionview"))&&"table"!==t&&"list"!==t&&"listview"!==t&&(!0===e.hittable||t2(e.rect))}(e))return e;a=e}return null}(e,t);return!!n&&(!0===n.hittable||!!t2(n.rect)&&eW(n,t))}(n,a),u=!1;switch(t){case"visible":u=d;break;case"hidden":u=!d;break;case"editable":u=s;break;case"selected":u=l;break;case"text":u=o===(r??"")}let c="text"===t?`expected="${r??""}" actual="${o}"`:`actual=${JSON.stringify({visible:d,editable:s,selected:l})}`;return{pass:u,actualText:o,details:c}}({predicate:t.predicate,node:r.node,nodes:n.snapshot.nodes,expectedText:t.expectedText,platform:e.backend.platform});if(!i.pass)throw new w("COMMAND_FAILED",`is ${t.predicate} failed for selector ${r.selector.raw}: ${i.details}`);return{predicate:t.predicate,pass:!0,selector:r.selector.raw,..."text"===t.predicate?{text:i.actualText}:{},selectorChain:a.selectors.map(e=>e.raw)}},ne=async(e,t)=>await t7(e,{...t,predicate:"visible",selector:t.target.selector}),nt=async(e,t)=>await t7(e,{...t,predicate:"hidden",selector:t.target.selector}),nn=async(e,t)=>{if("sleep"===t.target.kind)return await tZ(e,t.target.durationMs),{kind:"sleep",waitedMs:t.target.durationMs};if("ref"===t.target.kind){let n=await t3(e,t.session),a=V(t.target.ref);if(!a)throw new w("INVALID_ARGS",`Invalid ref: ${t.target.ref}`);let r=U(n.snapshot.nodes,a),i=r?O(r,n.snapshot.nodes):void 0;if(!i)throw new w("COMMAND_FAILED",`Ref ${t.target.ref} not found or has no label`);return await no(e,t,i,t.target.timeoutMs)}if("selector"===t.target.kind)return await ni(e,t,t.target.selector,t.target.timeoutMs);if(!t.target.text)throw new w("INVALID_ARGS","wait requires text");return await no(e,t,t.target.text,t.target.timeoutMs)},na=async(e,t)=>{let n=await nn(e,{...t,target:{kind:"text",text:t.text,timeoutMs:t.timeoutMs}});if("text"!==n.kind)throw new w("COMMAND_FAILED","waitForText returned non-text result");return n};async function nr(e,t,n){let a=t.timeoutMs??1e4,r=tJ(e);for(;tJ(e)-r<a;){if(en((await t4(e,t,{updateSession:!0,scope:tY(n)?t.query:void 0})).snapshot.nodes,n,t.query,{requireRect:!1}).matches[0])return{kind:"found",found:!0,waitedMs:tJ(e)-r};await tZ(e,300)}throw new w("COMMAND_FAILED","find wait timed out")}async function ni(e,t,n,a){let r=a??1e4,i=tJ(e),o=A(n);for(;tJ(e)-i<r;){let n=P((await t4(e,t,{updateSession:!0})).snapshot.nodes,o,{platform:e.backend.platform});if(n)return{kind:"selector",selector:n.selector.raw,waitedMs:tJ(e)-i};await tZ(e,300)}throw new w("COMMAND_FAILED",`wait timed out for selector: ${n}`)}async function no(e,t,n,a){let r=a??1e4,i=tJ(e);for(;tJ(e)-i<r;){if(e.backend.findText?(await e.backend.findText(tK(e,t),n)).found:await ns(e,t,n))return{kind:"text",text:n,waitedMs:tJ(e)-i};await tZ(e,300)}throw new w("COMMAND_FAILED",`wait timed out for text: ${n}`)}async function ns(e,t,n){return!!E((await t4(e,t,{updateSession:!0})).snapshot.nodes,n)}async function nl(e,t,n,a){let r=await t4(e,{...t,session:n},{updateSession:!0}),i=A(a.selector),o=T(r.snapshot.nodes,i,{platform:e.backend.platform,requireRect:!1,requireUnique:!0,disambiguateAmbiguous:a.disambiguateAmbiguous});if(!o)throw new w("COMMAND_FAILED",$(i,[],{unique:!0}));return{capture:r,node:o.node,selector:o.selector.raw,ref:`@${o.node.ref}`}}function nd(e,t,n,a){if(!Number.isFinite(e)||!Number.isInteger(e)||e<n||e>a)throw new w("INVALID_ARGS",`${t} must be an integer between ${n} and ${a}`);return e}function nu(e,t){let n=function(e,t){let n=np(t.rect);if(!n)return null;let a=t,r=new Set;for(;!r.has(a.ref);){r.add(a.ref);let t=e.filter(e=>{if(e.parentIndex!==a.index||!e.hittable)return!1;let t=np(e.rect);return!!t&&nf(t,n)});if(1!==t.length)break;a=t[0]}return a===t?null:a}(e,t);if(n?.rect&&nc(n.rect))return n;let a=_(e,t);return a?.rect&&nc(a.rect)?!function(e,t,n){var a,r,i,o;let s,l,d,u=np(e.rect),c=np(t.rect);if(!u||!c)return!1;let p=function(e,t){let n=G(t),a=e.filter(e=>{let t=(e.type??"").toLowerCase();return t.includes("application")||t.includes("window")}).map(e=>np(e.rect)).filter(e=>null!==e);if(0===a.length)return null;let r=a.filter(e=>eG(e,n.x,n.y));return eV(r.length>0?r:a)}(n,u);return!!p&&(a=c,r=p,s=(i=a,o=r,Math.max(0,Math.min(i.x+i.width,o.x+o.width)-Math.max(i.x,o.x))*Math.max(0,Math.min(i.y+i.height,o.y+o.height)-Math.max(i.y,o.y))),l=a.width*a.height,d=r.width*r.height,!(s<=0)&&!(l<=0)&&!(d<=0)&&!!(s/d>=.9)&&!!(s/l>=.8))&&!nf(u,c)}(t,a,e)?a:t:t}function nc(e){let t=np(e);if(!t)return null;let n=G(t);return Number.isFinite(n.x)&&Number.isFinite(n.y)?n:null}function np(e){if(!e)return null;let t=Number(e.x),n=Number(e.y),a=Number(e.width),r=Number(e.height);return Number.isFinite(t)&&Number.isFinite(n)&&Number.isFinite(a)&&Number.isFinite(r)&&!(a<0)&&!(r<0)?{x:t,y:n,width:a,height:r}:null}function nf(e,t){return .5>=Math.abs(e.x-t.x)&&.5>=Math.abs(e.y-t.y)&&.5>=Math.abs(e.width-t.width)&&.5>=Math.abs(e.height-t.height)}async function nh(e,t,n){if(await nw(e,t,n.action),"point"===t.target.kind)return{kind:"point",point:{x:t.target.x,y:t.target.y}};if("ref"===t.target.kind){let a=await ny(e,t,t.target),r=a.resolved,i=n.promoteToHittableAncestor?nu(a.snapshot.nodes,r.node):r.node;return function(e,t,n,a){let r=e.rect?eH(e,t):null;if(!(!e.rect||!r||eW(e,t)))throw new w("COMMAND_FAILED",`Ref ${n} is off-screen and not safe to ${a}`,{reason:"offscreen_ref",ref:V(n),rect:e.rect,viewport:r,hint:`Use scroll with the direction from the off-screen summary, take a fresh snapshot, then retry ${a} with the new ref or a selector.`})}(i,a.snapshot.nodes,t.target.ref,n.action),{kind:"ref",point:nv(i,`Ref ${t.target.ref} not found or has invalid bounds`),target:{kind:"ref",ref:`@${r.ref}`},node:i,selectorChain:M(i,e.backend.platform,{action:"fill"===n.action?"fill":"click"}),refLabel:O(i,a.snapshot.nodes)}}let a=await nm(e,t,n.requireInteractive),r=A(t.target.selector),i=T(a.snapshot.nodes,r,{platform:e.backend.platform,requireRect:!0,requireUnique:!0,disambiguateAmbiguous:!0});if(!i||!i.node.rect)throw new w("COMMAND_FAILED",$(r,i?.diagnostics??[],{unique:!0}));let o=n.promoteToHittableAncestor?nu(a.snapshot.nodes,i.node):i.node;return{kind:"selector",point:nv(o,`Selector ${i.selector.raw} resolved to invalid bounds`),target:{kind:"selector",selector:i.selector.raw},node:o,selectorChain:M(o,e.backend.platform,{action:"fill"===n.action?"fill":"click"}),refLabel:O(o,a.snapshot.nodes)}}async function nm(e,t,n){if(!e.backend.captureSnapshot)throw new w("UNSUPPORTED_OPERATION","snapshot is not supported by this backend");let a=t.session??"default",r=await e.sessions.get(a);if(!r)throw new w("SESSION_NOT_FOUND","No active session. Run open first.");let i=await e.backend.captureSnapshot(tK(e,t),{interactiveOnly:n,compact:n}),o=i.snapshot??{nodes:i.nodes??[],truncated:i.truncated,backend:i.backend,createdAt:tJ(e)};return await e.sessions.set({...r,snapshot:o}),{snapshot:o}}async function nw(e,t,n){if("macos"!==e.backend.platform)return;let a=await ng(e,t);if(("desktop"===a||"menubar"===a)&&("menubar"!==a||"click"!==n&&"press"!==n))throw new w("UNSUPPORTED_OPERATION",`${n} is not supported on macOS ${a} sessions yet. Open an app session to act, or use the ${a} surface to inspect.`)}async function ng(e,t){let n=await e.sessions.get(t.session??"default");return n?.metadata?.surface}async function ny(e,t,n){let a=t.session??"default",r=await e.sessions.get(a);if(!r)throw new w("SESSION_NOT_FOUND","No active session. Run open first.");if(!r.snapshot)throw new w("INVALID_ARGS","No snapshot in session. Run snapshot first.");let i=n.fallbackLabel??"",o=nb(r.snapshot.nodes,n.ref,{fallbackLabel:i,requireRect:!0});if(o)return{snapshot:r.snapshot,resolved:o};let s=await nm(e,t,!0),l=nb(s.snapshot.nodes,n.ref,{fallbackLabel:i,requireRect:!0});if(!l)throw new w("COMMAND_FAILED",`Ref ${n.ref} not found or has no bounds`);return{...s,resolved:l}}function nb(e,t,n){let a=V(t);if(!a)throw new w("INVALID_ARGS",`Invalid ref: ${t}`);let r=U(e,a);if(nA(r,n.requireRect))return{ref:a,node:r};let i=n.fallbackLabel.length>0?E(e,n.fallbackLabel):null;return nA(i,n.requireRect)?{ref:a,node:i}:null}function nv(e,t){if(!e.rect)throw new w("COMMAND_FAILED",t);let n=G(e.rect);if(!Number.isFinite(n.x)||!Number.isFinite(n.y))throw new w("COMMAND_FAILED",t);return n}function nA(e,t){if(!e)return!1;if(!t)return!0;if(!e.rect)return!1;let{x:n,y:a,width:r,height:i}=e.rect;if(!Number.isFinite(Number(n))||!Number.isFinite(Number(a))||!Number.isFinite(Number(r))||!Number.isFinite(Number(i))||0>Number(r)||0>Number(i))return!1;let o=G(e.rect);return Number.isFinite(o.x)&&Number.isFinite(o.y)}async function nI(e,t){let n=t.target??{kind:"viewport"};return"viewport"===n.kind?(await nw(e,t,"scroll"),{kind:"viewport"}):await nh(e,{...t,target:n},{action:"scroll",requireInteractive:!1,promoteToHittableAncestor:!1})}async function nx(e,t){if(t.from){var n;if("x"in(n=t.from)&&"y"in n)return await nw(e,t,"swipe"),{point:nS(t.from,"from")};let a=await nh(e,{...t,target:t.from},{action:"swipe",requireInteractive:!1,promoteToHittableAncestor:!1});return{point:a.point,target:a}}if(!t.direction)throw new w("INVALID_ARGS","swipe requires from+to or a direction");return await nw(e,t,"swipe"),{point:G(function(e){let t=e.filter(t=>eW(t,e)).map(e=>e.rect).filter(nM),n=t.length>0?t:e.map(e=>e.rect).filter(nM);if(0===n.length)throw new w("COMMAND_FAILED","Cannot infer viewport for directional swipe");let a=Math.min(...n.map(e=>e.x)),r=Math.min(...n.map(e=>e.y));return{x:a,y:r,width:Math.max(...n.map(e=>e.x+e.width))-a,height:Math.max(...n.map(e=>e.y+e.height))-r}}((await nm(e,t,!1)).snapshot.nodes)),target:{kind:"viewport"}}}function nN(e,t){switch(e){case"up":case"down":case"left":case"right":return e;default:throw new w("INVALID_ARGS",`${t} must be up, down, left, or right`)}}function nS(e,t){let n=Number(e.x),a=Number(e.y);if(!Number.isFinite(n)||!Number.isFinite(a))throw new w("INVALID_ARGS",`${t} point requires finite x and y`);return{x:n,y:a}}function n_(e,t){if(!Number.isFinite(e)||e<=0)throw new w("INVALID_ARGS",`${t} must be a positive number`);return e}function nM(e){return!!(e&&e.width>0&&e.height>0)}function nk(e){return e&&"object"==typeof e?e:void 0}async function nD(e,t,n){let a=await nh(e,t,{action:n,requireInteractive:!0,promoteToHittableAncestor:!0});if(!e.backend.tap)throw new w("UNSUPPORTED_OPERATION","tap is not supported by this backend");let r=nE(await e.backend.tap(tK(e,t),a.point,{button:t.button,count:t.count,intervalMs:t.intervalMs,holdMs:t.holdMs,jitterPx:t.jitterPx,doubleTap:t.doubleTap}));return{...a,...r?{backendResult:r}:{}}}function nE(e){return e&&"object"==typeof e?e:void 0}function nO(e){return!!(e&&"object"==typeof e)}function nC(e){return e&&"object"==typeof e?e:void 0}let nR=/^[A-Za-z0-9_.:-]{1,64}$/;function nP(e,t){if(void 0!==e)return nT(e,t)}function nT(e,t){let n=e?.trim();if(!n)throw new w("INVALID_ARGS",`${t} must be a non-empty string`);return n}async function nL(e,t){if(!t||"object"!=typeof t)throw new w("INVALID_ARGS","apps.push requires an input");if("json"===t.kind)return n$(t.payload,"apps.push JSON payload",8192),{backendInput:{kind:"json",payload:t.payload},inputKind:"json"};let n=await e4(e,t,{usage:"apps.push",field:"input"});return{backendInput:{kind:"file",path:n.path},inputKind:"file",...n.cleanup?{cleanup:n.cleanup}:{}}}function n$(e,t,n){if(function(e,t){if(!e||"object"!=typeof e||Array.isArray(e))throw new w("INVALID_ARGS",`${t} must be a JSON object`)}(e,t),Buffer.byteLength(function(e,t){try{let n=JSON.stringify(e);if("string"!=typeof n)throw new w("INVALID_ARGS",`${t} must be JSON-serializable`);return n}catch{throw new w("INVALID_ARGS",`${t} must be JSON-serializable`)}}(e,t),"utf8")>n)throw new w("INVALID_ARGS",`${t} exceeds ${n} bytes`)}function nF(e,t){return{session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata}}function nU(e){return e&&"object"==typeof e?e:void 0}async function nG(e,t,n){let a="reinstall"===n?"reinstallApp":"installApp",r=e.backend[a];if(!r)throw new w("UNSUPPORTED_OPERATION",`admin.${n} is not supported by this backend`);let i="app"in t&&void 0!==t.app?nX(t.app,"app"):void 0;if("installFromSource"!==n&&!i)throw new w("INVALID_ARGS",`admin.${n} requires app`);let o=tK(e,t),s=await nV(e,o,t.source);try{var l,d,u,c,p;let t,a,f,h,m,w,g,y,b=await r.call(e.backend,o,{...i?{app:i}:{},source:s.source});return l=n,d=i,u=s.source,c=b,t=nW(c),a=nz(c,"appName"),f=nz(c,"appId"),h=nz(c,"bundleId"),m=nz(c,"packageName"),w=nz(c,"launchTarget"),g=nz(c,"installablePath"),y=nz(c,"archivePath"),{kind:"reinstall"===l?"appReinstalled":"installFromSource"===l?"appInstalledFromSource":"appInstalled",...d?{app:d}:{},source:u,...f?{appId:f}:{},...a?{appName:a}:{},...h?{bundleId:h}:{},...m?{packageName:m}:{},...w?{launchTarget:w}:{},...g?{installablePath:g}:{},...y?{archivePath:y}:{},...t?{backendResult:t}:{},...q(`${"reinstall"===l?"Reinstalled":"Installed"}: ${a??w??d??(p=u,"path"===p.kind?p.path:"uploadedArtifact"===p.kind?p.id:p.url)}`)}}finally{await s.cleanup?.()}}async function nV(e,t,n){let a=nj(n),r=await nB(e,a);try{let n=e.backend.resolveInstallSource?await e.backend.resolveInstallSource(t,r.source):r.source;return{source:nj(n),...r.cleanup?{cleanup:r.cleanup}:{}}}catch(e){if(r.cleanup)try{await r.cleanup()}catch{}throw e}}async function nB(e,t){if("url"===t.kind)return{source:t};let n=await e4(e,t,{usage:"admin.install",field:"source"});return{source:{kind:"path",path:n.path},...n.cleanup?{cleanup:n.cleanup}:{}}}function nj(e){if(!e||"object"!=typeof e)throw new w("INVALID_ARGS","install source is required");if("path"===e.kind)return{kind:"path",path:nX(e.path,"source.path")};if("uploadedArtifact"===e.kind)return{kind:"uploadedArtifact",id:nX(e.id,"source.id")};if("url"===e.kind){let t=nX(e.url,"source.url");return function(e){let t;try{t=new URL(e)}catch{throw new w("INVALID_ARGS",`Invalid install source URL: ${e}`)}if("http:"!==t.protocol&&"https:"!==t.protocol)throw new w("INVALID_ARGS","Install source URL must use http or https")}(t),{kind:"url",url:t}}throw new w("INVALID_ARGS","install source kind must be path, uploadedArtifact, or url")}function nq(e,t){if(void 0!==e)return nX(e,t)}function nX(e,t){let n=e?.trim();if(!n)throw new w("INVALID_ARGS",`${t} must be a non-empty string`);return n}function nz(e,t){let n=e[t];return"string"==typeof n&&n.length>0?n:void 0}function nW(e){return e&&"object"==typeof e?e:void 0}function nH(e,t){if("start"===e||"stop"===e)return e;throw new w("INVALID_ARGS",`${t} action must be start or stop`)}function nY(e,t,n,a){return{kind:"start"===e?a.startKind:a.stopKind,action:e,...n?{artifact:n}:{},backendResult:t,...q("start"===e?a.startMessage:a.stopMessage)}}let nK=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i,nJ=/\b[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\b/g;function nZ(e){var t,n;let a=!1,r=e;return{value:(t=r=(r=(r=(r=(r=r.replaceAll(/(authorization|token|secret|password|passwd|api[-_]?key)=([^&\s]+)/gi,(e,t)=>(a=!0,`${String(t)}=[REDACTED]`))).replaceAll(/("(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)"\s*:\s*")([^"]*)(")/gi,(e,t,n,r)=>(a=!0,`${String(t)}[REDACTED]${String(r)}`))).replaceAll(/\b(Bearer\s+)([^\s",;]+)/gi,(e,t)=>(a=!0,`${String(t)}[REDACTED]`))).replaceAll(/((?:authorization|cookie|token|secret|password|passwd|api[-_]?key)\s*[:=]\s*)([^\s,;&]+)/gi,(e,t)=>(a=!0,`${String(t)}[REDACTED]`))).replaceAll(nJ,()=>(a=!0,"[REDACTED]")),n=()=>{a=!0},r=/(https?:\/\/|token|secret|password|authorization|cookie|api[-_]?key)/i.test(t)?t.replaceAll(/https?:\/\/[^\s"'<>)]+/gi,e=>{let t=nQ(e);return t?(t.redacted&&n(),t.value):e}):t),redacted:a}}function nQ(e){try{let t=new URL(e),n=function(e){let t=!1;for(let n of Array.from(e.searchParams.keys()))nK.test(n)&&(e.searchParams.set(n,"[REDACTED]"),t=!0);return t}(t);return(t.username||t.password)&&(t.username="REDACTED",t.password="REDACTED",n=!0),{value:t.toString(),redacted:n}}catch{return}}let n0=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i;function n1(e){if(!e)return{redacted:!1};let t=!1,n={};for(let[a,r]of Object.entries(e))if(n0.test(a))n[a]="[REDACTED]",t=!0;else{let e=n5(r,2048);n[a]=e.value??"",t||=e.redacted}return{value:n,redacted:t}}function n2(e){return void 0===e?{redacted:!1}:function(e){try{let t=JSON.parse(e),n=n4(t,nZ);return n8(JSON.stringify(n.value),2048,n.redacted)}catch{return}}(e)??n5(e,2048)}function n3(e){return n4(e,e=>n5(e,2048))}function n4(e,t){if(void 0===e)return{redacted:!1};if("string"==typeof e)return t(e);if(!e||"object"!=typeof e)return{value:e,redacted:!1};if(Array.isArray(e)){let n=!1;return{value:e.map(e=>{let a=n4(e,t);return n||=a.redacted,a.value}),redacted:n}}let n=!1,a={};for(let[r,i]of Object.entries(e)){if(n0.test(r)){a[r]="[REDACTED]",n=!0;continue}let e=n4(i,t);a[r]=e.value,n||=e.redacted}return{value:a,redacted:n}}function n5(e,t){if(void 0===e)return{redacted:!1};let n=nZ(e);return n8(n.value,t,n.redacted)}function n8(e,t,n){if(void 0===e)return{redacted:n};let a=e;return a.length>t&&(a=`${a.slice(0,t)}...[truncated]`,n=!0),{value:a,redacted:n}}async function n6(e,t){let n=tK(e,t),a=t.session?await e.sessions.get(t.session):void 0;return{...n,...t.appId??a?.appId?{appId:t.appId??a?.appId}:{},...t.appBundleId??a?.appBundleId?{appBundleId:t.appBundleId??a?.appBundleId}:{}}}function n9(e,t,n,a){return{...n7(e),...void 0!==e.cursor?{cursor:at(e.cursor,"cursor")}:{},limit:void 0===e.limit?t:nd(e.limit,a,1,n)}}function n7(e){return{...void 0!==e.since?{since:at(e.since,"since")}:{},...void 0!==e.until?{until:at(e.until,"until")}:{}}}function ae(e,t,n=50){if(!Array.isArray(e))throw new w("INVALID_ARGS",`${t} must be an array of strings`);if(e.length>n)throw new w("INVALID_ARGS",`${t} must contain at most ${n} entries`);return e.map((e,n)=>at(e,`${t}[${n}]`))}function at(e,t){let n=e.trim();if(!n)throw new w("INVALID_ARGS",`${t} must be a non-empty string`);return n}let an=async(e,t)=>{let n;if(!e.backend.captureScreenshot)throw new w("UNSUPPORTED_OPERATION","screenshot is not supported by this backend");let a=await e5(e,t.out,{field:"path",ext:".png"});try{await e.backend.captureScreenshot({session:t.session,requestId:t.requestId,appId:t.appId,appBundleId:t.appBundleId,signal:t.signal??e.signal,metadata:t.metadata},a.path,{fullscreen:t.fullscreen,overlayRefs:t.overlayRefs,surface:t.surface}),void 0!==t.maxSize&&await e3(a.path,t.maxSize),n=await a.publish()}catch(e){throw await a.cleanup?.(),e}return{path:a.path,...n?{artifacts:[n]}:{},...q(`Saved screenshot: ${a.path}`)}},aa=async(e,t)=>{let n,a,r;if(!t.baseline)throw new w("INVALID_ARGS","diff screenshot requires a baseline image");let i=function(e){if(null==e||""===e)return .1;let t=Number(e);if(Number.isNaN(t)||t<0||t>1)throw new w("INVALID_ARGS","--threshold must be a number between 0 and 1");return t}(t.threshold),o=t.current??{kind:"live"};if(t.overlayRefs&&!tX(o))throw new w("INVALID_ARGS","diff screenshot <current.png> cannot use --overlay-refs because saved-image comparisons have no live accessibility refs");let s=await e4(e,t.baseline,{usage:"diff screenshot baseline",field:"baseline"}),l=[];try{let d;d=tX(o)?(a=await tU(e,t)).path:(n=await e4(e,o,{usage:"diff screenshot current",field:"current"})).path,r=t.out?await e5(e,t.out,{field:"diffPath",ext:".png"}):void 0;let u=await tO(s.path,d,{threshold:i,outputPath:r?.path,maxPixels:e.policy.maxImagePixels});tX(o)&&(u=await tG(e,t,r?.path,u,l));let c=u.diffPath?await r?.publish():void 0;return c&&l.push(c),u.diffPath||await r?.cleanup?.(),{...u,...l.length>0?{artifacts:l}:{}}}catch(e){throw await r?.cleanup?.(),e}finally{await s.cleanup?.(),await n?.cleanup?.(),await a?.cleanup?.()}},ar=async(e,t)=>{var n;let a,r,i=await tQ(e,t);return await e.sessions.set(t0(t.session,i)),{nodes:i.snapshot.nodes,truncated:i.snapshot.truncated??!1,visibility:function(e){var t;let{nodes:n,backend:a,snapshotRaw:r}=e;if(r||"macos-helper"===(t=a)||"linux-atspi"===t)return{partial:!1,visibleNodeCount:n.length,totalNodeCount:n.length,reasons:[]};let i=eX(n),o=new Set;return i.hiddenCount>0&&o.add("offscreen-nodes"),i.nodes.some(e=>e.hiddenContentAbove)&&o.add("scroll-hidden-above"),i.nodes.some(e=>e.hiddenContentBelow)&&o.add("scroll-hidden-below"),{partial:o.size>0,visibleNodeCount:i.nodes.length,totalNodeCount:n.length,reasons:[...o]}}({nodes:i.snapshot.nodes,backend:i.snapshot.backend,snapshotRaw:t.raw}),...i.warnings.length>0?{warnings:i.warnings}:{},...(a=(n=i).result.appName??n.session?.appName,r=n.result.appBundleId??n.session?.appBundleId,{...a||r?{appName:a??r}:{},...r?{appBundleId:r}:{}})}},ai=async(e,t)=>{let n=await tQ(e,t),a=!0===t.interactiveOnly,r=n.session?.snapshot,i=t0(t.session,n);if(!r){let t=function(e,t={}){return tW(e,t).length}(n.snapshot.nodes,{flatten:a});return await e.sessions.set(i),{mode:"snapshot",baselineInitialized:!0,summary:{additions:0,removals:0,unchanged:t},lines:[],...n.warnings.length>0?{warnings:n.warnings}:{}}}let o=function(e,t,n={}){let a=function(e,t){let n=e.length,a=t.length,r=n+a,i=new Map,o=[];i.set(1,0);for(let s=0;s<=r;s+=1){o.push(new Map(i));for(let r=-s;r<=s;r+=2){let l=r===-s||r!==s&&tH(i,r-1)<tH(i,r+1)?tH(i,r+1):tH(i,r-1)+1,d=l-r;for(;l<n&&d<a&&e[l].comparable===t[d].comparable;)l+=1,d+=1;if(i.set(r,l),l>=n&&d>=a)return function(e,t,n,a,r){let i=[],o=a,s=r;for(let a=e.length-1;a>=0;a-=1){let r=e[a],l=o-s,d=l===-a||l!==a&&tH(r,l-1)<tH(r,l+1)?l+1:l-1,u=tH(r,d),c=u-d;for(;o>u&&s>c;)i.push({kind:"unchanged",text:n[s-1].text}),o-=1,s-=1;if(0===a)break;o===u?(i.push({kind:"added",text:n[c].text}),s=c):(i.push({kind:"removed",text:t[u].text}),o=u)}return i.reverse(),i}(o,e,t,n,a)}}return[]}(tW(e,n),tW(t,n)),r={additions:0,removals:0,unchanged:0};for(let e of a)"added"===e.kind&&(r.additions+=1),"removed"===e.kind&&(r.removals+=1),"unchanged"===e.kind&&(r.unchanged+=1);return{summary:r,lines:a}}(r.nodes,n.snapshot.nodes,{flatten:a});return await e.sessions.set(i),{mode:"snapshot",baselineInitialized:!1,summary:o.summary,lines:o.lines,...n.warnings.length>0?{warnings:n.warnings}:{}}},ao=async(e,t)=>{let n=t.locator??"any";if(!t.query)throw new w("INVALID_ARGS","find requires a value");if("wait"===t.action)return await nr(e,t,n);let a=await t4(e,t,{updateSession:!0,scope:tY(n)?t.query:void 0}),r=en(a.snapshot.nodes,n,t.query,{requireRect:!1}).matches[0];if(!r)throw new w("COMMAND_FAILED","find did not match any element");if("exists"===t.action)return{kind:"found",found:!0};let i=`@${r.ref}`;return"get_attrs"===t.action?{kind:"attrs",ref:i,node:r}:{kind:"text",ref:i,text:await t5(e,a,r),node:r}},as=t8,al=t6,ad=t9,au=t7,ac=ne,ap=nt,af=nn,ah=na,am=async(e,t)=>await nD(e,t,"click"),aw=async(e,t)=>await nD(e,t,"press"),ag=async(e,t)=>{var n;if(!t.text)throw new w("INVALID_ARGS","fill requires text");let a=await nh(e,t,{action:"fill",requireInteractive:!0,promoteToHittableAncestor:!1});if(!e.backend.fill)throw new w("UNSUPPORTED_OPERATION","fill is not supported by this backend");let r=nE(await e.backend.fill(tK(e,t),a.point,t.text,{delayMs:t.delayMs})),i="node"in a?a.node.type??"":"",o=i&&!F(i,e.backend.platform)?`fill target ${n=a,n.target?.kind==="ref"?n.target.ref:n.target?.kind==="selector"?n.target.selector:"point"} resolved to "${i}", attempting fill anyway.`:void 0;return{...a,text:t.text,...o?{warning:o}:{},...r?{backendResult:r}:{}}},ay=async(e,t)=>{let n=t.text;if(!n)throw new w("INVALID_ARGS","type requires text");let a=function(e){let t=e.trim().split(/\s+/,1)[0];if(!t||!t.startsWith("@")||t.length<3)return null;let n=t.slice(1);return/^[A-Za-z_-]*\d[\w-]*$/i.test(n)||/^(?:ref|node|element|el)[\w-]*$/i.test(n)?t:null}(n);if(a)throw new w("INVALID_ARGS",`type does not accept a target ref like "${a}"`,{hint:`Use fill ${a} "text" to target that field, or press ${a} then type "text" to append.`});if(!e.backend.typeText)throw new w("UNSUPPORTED_OPERATION","type is not supported by this backend");let r=nd(t.delayMs??0,"delay-ms",0,1e4),i=nE(await e.backend.typeText(tK(e,t),n,{delayMs:r}));return{kind:"text",text:n,delayMs:r,...i?{backendResult:i}:{},...q(`Typed ${Array.from(n).length} chars`)}},ab=async(e,t)=>{let n=await nh(e,t,{action:"focus",requireInteractive:!0,promoteToHittableAncestor:!1});if(!e.backend.focus)throw new w("UNSUPPORTED_OPERATION","focus is not supported by this backend");let a=nk(await e.backend.focus(tK(e,t),n.point));return{...n,...a?{backendResult:a}:{},...q(`Focused (${n.point.x}, ${n.point.y})`)}},av=async(e,t)=>{let n=await nh(e,t,{action:"longPress",requireInteractive:!0,promoteToHittableAncestor:!0});if(!e.backend.longPress)throw new w("UNSUPPORTED_OPERATION","longPress is not supported by this backend");let a=void 0===t.durationMs?void 0:nd(t.durationMs,"durationMs",0,12e4),r=nk(await e.backend.longPress(tK(e,t),n.point,{durationMs:a}));return{...n,...void 0!==a?{durationMs:a}:{},...r?{backendResult:r}:{},...q(`Long pressed (${n.point.x}, ${n.point.y})`)}},aA=async(e,t)=>{if(!e.backend.swipe)throw new w("UNSUPPORTED_OPERATION","swipe is not supported by this backend");let n=await nx(e,t),a=function(e,t){if(t.to)return{point:nS(t.to,"to")};let n=nN(t.direction,"swipe direction"),a=n_(t.distance??200,"swipe distance");switch(n){case"up":return{point:{x:e.x,y:e.y-a},direction:n,distance:a};case"down":return{point:{x:e.x,y:e.y+a},direction:n,distance:a};case"left":return{point:{x:e.x-a,y:e.y},direction:n,distance:a};case"right":return{point:{x:e.x+a,y:e.y},direction:n,distance:a}}}(n.point,t),r=void 0===t.durationMs?void 0:nd(t.durationMs,"durationMs",16,1e4),i=nk(await e.backend.swipe(tK(e,t),n.point,a.point,{durationMs:r}));return{kind:"swipe",from:n.point,to:a.point,...a.direction?{direction:a.direction}:{},...void 0!==a.distance?{distance:a.distance}:{},...void 0!==r?{durationMs:r}:{},...n.target?{fromTarget:n.target}:{},...i?{backendResult:i}:{},...q("Swiped")}},aI=async(e,t)=>{var n,a;if(!e.backend.scroll)throw new w("UNSUPPORTED_OPERATION","scroll is not supported by this backend");let r=nN(t.direction,"scroll direction"),i=(n=t.amount,a="scroll amount",void 0===n?void 0:n_(n,a)),o=function(e,t){if(void 0!==e){if(!Number.isFinite(e)||!Number.isInteger(e)||e<=0)throw new w("INVALID_ARGS",`${t} must be a positive integer`);return e}}(t.pixels,"scroll pixels");if(void 0!==i&&void 0!==o)throw new w("INVALID_ARGS","scroll accepts either amount or pixels, not both");let s=await nI(e,t),l="viewport"===s.kind?{kind:"viewport"}:{kind:"point",point:s.point},d=nk(await e.backend.scroll(tK(e,t),l,{direction:r,...void 0!==i?{amount:i}:{},...void 0!==o?{pixels:o}:{}}));return{...s,direction:r,...void 0!==i?{amount:i}:{},...void 0!==o?{pixels:o}:{},...d?{backendResult:d}:{},...q(void 0!==o?`Scrolled ${r} by ${o}px`:void 0!==i?`Scrolled ${r} by ${i}`:`Scrolled ${r}`)}},ax=async(e,t)=>{if(!e.backend.pinch)throw new w("UNSUPPORTED_OPERATION","pinch is not supported by this backend");await nw(e,t,"pinch");let n=n_(t.scale,"pinch scale"),a=t.center?await nh(e,{...t,target:t.center},{action:"pinch",requireInteractive:!1,promoteToHittableAncestor:!1}):void 0,r=nk(await e.backend.pinch(tK(e,t),{scale:n,...a?{center:a.point}:{}}));return{kind:"pinch",scale:n,...a?{center:a.point,centerTarget:a}:{},...r?{backendResult:r}:{},...q(`Pinched to scale ${n}`)}},aN=async(e,t={})=>{if(!e.backend.pressBack)throw new w("UNSUPPORTED_OPERATION","system.back is not supported by this backend");let n=t.mode??"in-app";if("in-app"!==n&&"system"!==n)throw new w("INVALID_ARGS","system.back mode must be in-app or system");let a=nC(await e.backend.pressBack(tK(e,t),{mode:n}));return{kind:"systemBack",mode:n,...a?{backendResult:a}:{},...q("Back")}},aS=async(e,t={})=>{if(!e.backend.pressHome)throw new w("UNSUPPORTED_OPERATION","system.home is not supported by this backend");let n=nC(await e.backend.pressHome(tK(e,t)));return{kind:"systemHome",...n?{backendResult:n}:{},...q("Home")}},a_=async(e,t)=>{if(!e.backend.rotate)throw new w("UNSUPPORTED_OPERATION","system.rotate is not supported by this backend");let n=function(e){switch(e){case"portrait":case"portrait-upside-down":case"landscape-left":case"landscape-right":return e;default:throw new w("INVALID_ARGS","system.rotate orientation must be portrait, portrait-upside-down, landscape-left, or landscape-right")}}(t.orientation),a=nC(await e.backend.rotate(tK(e,t),n));return{kind:"systemRotated",orientation:n,...a?{backendResult:a}:{},...q(`Rotated to ${n}`)}},aM=async(e,t={})=>{if(!e.backend.setKeyboard)throw new w("UNSUPPORTED_OPERATION","system.keyboard is not supported by this backend");let n=t.action??"status";if("status"!==n&&"get"!==n&&"dismiss"!==n)throw new w("INVALID_ARGS","system.keyboard action must be status, get, or dismiss");let a=await e.backend.setKeyboard(tK(e,t),{action:n}),r=nC(a);if("dismiss"===n){let e=nO(a)?a.dismissed:void 0;return{kind:"keyboardDismissed",action:n,state:nO(a)?a:{},...r?{backendResult:r}:{},...q(!1===e?"Keyboard already hidden":"Keyboard dismissed")}}return{kind:"keyboardState",action:n,state:nO(a)?a:{},...r?{backendResult:r}:{}}},ak=async(e,t)=>{if("read"===t.action){if(!e.backend.getClipboard)throw new w("UNSUPPORTED_OPERATION","system.clipboard read is not supported by this backend");let n=await e.backend.getClipboard(tK(e,t));return{kind:"clipboardText",action:"read",text:"string"==typeof n?n:n.text}}if("write"!==t.action)throw new w("INVALID_ARGS","system.clipboard action must be read or write");if(!e.backend.setClipboard)throw new w("UNSUPPORTED_OPERATION","system.clipboard write is not supported by this backend");if("string"!=typeof t.text)throw new w("INVALID_ARGS","system.clipboard write requires text");let n=nC(await e.backend.setClipboard(tK(e,t),t.text));return{kind:"clipboardUpdated",action:"write",textLength:Array.from(t.text).length,...n?{backendResult:n}:{},...q("Clipboard updated")}},aD=async(e,t={})=>{if(!e.backend.openSettings)throw new w("UNSUPPORTED_OPERATION","system.settings is not supported by this backend");let n=function(e,t){if(void 0===e)return;let n=e.trim();if(!n)throw new w("INVALID_ARGS",`${t} must be a non-empty string`);return n}(t.target,"target"),a=nC(await e.backend.openSettings(tK(e,t),n));return{kind:"settingsOpened",...n?{target:n}:{},...a?{backendResult:a}:{},...q(n?`Opened settings: ${n}`:"Opened settings")}},aE=async(e,t={})=>{if(!e.backend.handleAlert)throw new w("UNSUPPORTED_OPERATION","system.alert is not supported by this backend");let n=t.action??"get";if("get"!==n&&"accept"!==n&&"dismiss"!==n&&"wait"!==n)throw new w("INVALID_ARGS","system.alert action must be get, accept, dismiss, or wait");let a=void 0===t.timeoutMs?void 0:nd(t.timeoutMs,"timeoutMs",0,12e4),r=await e.backend.handleAlert(tK(e,t),n,{timeoutMs:a});var i=n,o=r;if("get"===i){if("alertStatus"!==o.kind)throw new w("COMMAND_FAILED","system.alert get returned an invalid backend result");return{kind:"alertStatus",action:i,alert:o.alert}}if("wait"===i){if("alertWait"!==o.kind)throw new w("COMMAND_FAILED","system.alert wait returned an invalid backend result");return{kind:"alertWait",action:i,alert:o.alert,...void 0!==o.waitedMs?{waitedMs:o.waitedMs}:{},...void 0!==o.timedOut?{timedOut:o.timedOut}:{},...q(o.alert?"Alert visible":"Alert wait timed out")}}if("alertHandled"!==o.kind)throw new w("COMMAND_FAILED",`system.alert ${i} returned an invalid backend result`);return{kind:"alertHandled",action:i,handled:o.handled,...o.alert?{alert:o.alert}:{},...o.button?{button:o.button}:{},...q(o.handled?`Alert ${i}ed`:"No alert handled")}},aO=async(e,t={})=>{if(!e.backend.openAppSwitcher)throw new w("UNSUPPORTED_OPERATION","system.appSwitcher is not supported by this backend");let n=nC(await e.backend.openAppSwitcher(tK(e,t)));return{kind:"appSwitcherOpened",...n?{backendResult:n}:{},...q("Opened app switcher")}},aC=async(e,t)=>{var n;if(!e.backend.openApp)throw new w("UNSUPPORTED_OPERATION","apps.open is not supported by this backend");let a=function(e){var t;let n=nP(e.app,"app"),a=nP(e.appId,"appId"),r=nP(e.bundleId,"bundleId"),i=nP(e.packageName,"packageName"),o=nP(e.url,"url"),s=nP(e.activity,"activity"),l={...n?{app:n}:{},...a?{appId:a}:{},...r?{bundleId:r}:{},...i?{packageName:i}:{},...o?{url:o}:{},...s?{activity:s}:{}};if(!((t=l).app??t.appId??t.bundleId??t.packageName??t.url??t.activity))throw new w("INVALID_ARGS","apps.open requires app, appId, bundleId, packageName, url, or activity");return l}(t),r=nU(await e.backend.openApp(nF(e,t),a,{relaunch:t.relaunch}));return{kind:"appOpened",target:a,relaunch:!0===t.relaunch,...r?{backendResult:r}:{},...q(`Opened: ${(n=a).app??n.appId??n.bundleId??n.packageName??n.url??n.activity??"app"}`)}},aR=async(e,t={})=>{if(!e.backend.closeApp)throw new w("UNSUPPORTED_OPERATION","apps.close is not supported by this backend");let n=nP(t.app,"app"),a=nU(await e.backend.closeApp(nF(e,t),n));return{kind:"appClosed",...n?{app:n}:{},...a?{backendResult:a}:{},...q(n?`Closed: ${n}`:"Closed app")}},aP=async(e,t={})=>{if(!e.backend.listApps)throw new w("UNSUPPORTED_OPERATION","apps.list is not supported by this backend");return{kind:"appsList",apps:await e.backend.listApps(nF(e,t),t.filter??"all")}},aT=async(e,t)=>{if(!e.backend.getAppState)throw new w("UNSUPPORTED_OPERATION","apps.state is not supported by this backend");let n=nT(t.app,"app"),a=await e.backend.getAppState(nF(e,t),n);return{kind:"appState",app:n,state:a}},aL=async(e,t)=>{if(!e.backend.pushFile)throw new w("UNSUPPORTED_OPERATION","apps.push is not supported by this backend");let n=nT(t.app,"app"),a=await nL(e,t.input);try{let r=await e.backend.pushFile(nF(e,t),a.backendInput,n),i=nU(r);return{kind:"appPushed",app:n,inputKind:a.inputKind,...i?{backendResult:i}:{},...q(`Pushed to ${n}`)}}finally{await a.cleanup?.()}},a$=async(e,t)=>{var n,a;if(!e.backend.triggerAppEvent)throw new w("UNSUPPORTED_OPERATION","apps.triggerEvent is not supported by this backend");let r=function(e){let t=nT(e,"name");if(!nR.test(t))throw new w("INVALID_ARGS",`Invalid apps.triggerEvent name: ${t}`,{hint:"Use 1-64 chars: letters, numbers, underscore, dot, colon, or dash."});return t}(t.name);n=t.payload,a=`apps.triggerEvent payload for "${r}"`,void 0!==n&&n$(n,a,8192);let i=nU(await e.backend.triggerAppEvent(nF(e,t),{name:r,...t.payload?{payload:t.payload}:{}}));return{kind:"appEventTriggered",name:r,...t.payload?{payload:t.payload}:{},...i?{backendResult:i}:{},...q(`Triggered app event: ${r}`)}},aF=async(e,t={})=>{if(!e.backend.listDevices)throw new w("UNSUPPORTED_OPERATION","admin.devices is not supported by this backend");return{kind:"adminDevices",devices:await e.backend.listDevices(tK(e,t),t.filter)}},aU=async(e,t={})=>{if(!e.backend.bootDevice)throw new w("UNSUPPORTED_OPERATION","admin.boot is not supported by this backend");let n=function(e){if(!e)return;let t=nq(e.id,"target.id"),n=nq(e.name,"target.name"),a={...t?{id:t}:{},...n?{name:n}:{},...e.platform?{platform:e.platform}:{},...e.target?{target:e.target}:{},...void 0!==e.headless?{headless:e.headless}:{}};return Object.keys(a).length>0?a:void 0}(t.target),a=nW(await e.backend.bootDevice(tK(e,t),n));return{kind:"deviceBooted",...n?{target:n}:{},...a?{backendResult:a}:{},...q("Booted device")}},aG=async(e,t)=>{if(!e.backend.ensureSimulator)throw new w("UNSUPPORTED_OPERATION","admin.ensureSimulator is not supported by this backend");let n=nX(t.device,"device");return{kind:"simulatorEnsured",...await e.backend.ensureSimulator(tK(e,t),{device:n,...t.runtime?{runtime:nX(t.runtime,"runtime")}:{},...void 0!==t.boot?{boot:t.boot}:{},...void 0!==t.reuseExisting?{reuseExisting:t.reuseExisting}:{}})}},aV=async(e,t)=>await nG(e,t,"install"),aB=async(e,t)=>await nG(e,t,"reinstall"),aj=async(e,t)=>await nG(e,t,"installFromSource"),aq=async(e,t)=>{let n=nH(t.action,"record"),a="start"===n?e.backend.startRecording:e.backend.stopRecording;if(!a)throw new w("UNSUPPORTED_OPERATION",`record ${n} is not supported by this backend`);let r=t.out?await e5(e,t.out,{field:"path",ext:".mp4"}):void 0;try{var i,o,s,l,d;let u,c,p=(i=t,o=r?.path,u=void 0===i.fps?void 0:nd(i.fps,"fps",1,60),c=void 0===i.quality?void 0:nd(i.quality,"quality",5,10),{...o?{outPath:o}:{},...void 0!==u?{fps:u}:{},...void 0!==c?{quality:c}:{},...void 0!==i.hideTouches?{showTouches:!0!==i.hideTouches}:{}}),f=await a.call(e.backend,tK(e,t),p),h=await r?.publish();return s=n,l=f,d=h,{..."string"==typeof l.path?{path:l.path}:{},..."string"==typeof l.telemetryPath?{telemetryPath:l.telemetryPath}:{},..."string"==typeof l.warning?{warning:l.warning}:{},...nY(s,l,d,{startKind:"recordingStarted",stopKind:"recordingStopped",startMessage:"Recording started",stopMessage:"Recording stopped"})}}catch(e){throw await r?.cleanup?.(),e}},aX=async(e,t)=>{let n=nH(t.action,"trace"),a="start"===n?e.backend.startTrace:e.backend.stopTrace;if(!a)throw new w("UNSUPPORTED_OPERATION",`trace ${n} is not supported by this backend`);let r=t.out?await e5(e,t.out,{field:"outPath",ext:".trace"}):void 0;try{var i,o,s;let l={...r?.path?{outPath:r.path}:{}},d=await a.call(e.backend,tK(e,t),l),u=await r?.publish();return i=n,o=d,s=u,{..."string"==typeof o.outPath?{outPath:o.outPath}:{},...nY(i,o,s,{startKind:"traceStarted",stopKind:"traceStopped",startMessage:"Trace started",stopMessage:"Trace stopped"})}}catch(e){throw await r?.cleanup?.(),e}},az=async(e,t={})=>{var n,a;let r;if(!e.backend.readLogs)throw new w("UNSUPPORTED_OPERATION","diagnostics.logs is not supported by this backend");return r=!0===(n=await e.backend.readLogs(await n6(e,t),{...n9(a=t,100,500,"logs limit"),...void 0!==a.levels?{levels:ae(a.levels,"levels")}:{},...void 0!==a.search?{search:at(a.search,"search")}:{},...void 0!==a.source?{source:at(a.source,"source")}:{}})).redacted,{kind:"diagnosticsLogs",entries:n.entries.map(e=>{let t=n5(e.message,4096),n=n3(e.metadata);return r||=t.redacted||n.redacted,{...e.timestamp?{timestamp:e.timestamp}:{},...e.level?{level:e.level}:{},message:t.value??"",...e.source?{source:e.source}:{},...n.value?{metadata:n.value}:{}}}),...n.nextCursor?{nextCursor:n.nextCursor}:{},...n.timeWindow?{timeWindow:n.timeWindow}:{},...n.backend?{backend:n.backend}:{},redacted:r,...n.notes?{notes:n.notes}:{}}},aW=async(e,t={})=>{var n,a,r;let i;if(!e.backend.dumpNetwork)throw new w("UNSUPPORTED_OPERATION","diagnostics.network is not supported by this backend");let o={...n9(r=t,25,200,"network limit"),include:function(e){if(void 0===e)return"summary";if("summary"===e||"headers"===e||"body"===e||"all"===e)return e;throw new w("INVALID_ARGS","network include must be summary, headers, body, or all")}(r.include)};return n=await e.backend.dumpNetwork(await n6(e,t),o),a=o.include??"summary",i=!0===n.redacted,{kind:"diagnosticsNetwork",entries:n.entries.map(e=>{var t;let n=e.url?nQ(t=e.url)??n5(t,2048):void 0,r="headers"===a||"all"===a?n1(e.requestHeaders):void 0,o="headers"===a||"all"===a?n1(e.responseHeaders):void 0,s="body"===a||"all"===a?n2(e.requestBody):void 0,l="body"===a||"all"===a?n2(e.responseBody):void 0,d=n3(e.metadata);return i||=(n?.redacted??!1)||(r?.redacted??!1)||(o?.redacted??!1)||(s?.redacted??!1)||(l?.redacted??!1)||d.redacted,{...e.timestamp?{timestamp:e.timestamp}:{},...e.method?{method:e.method}:{},...n?{url:n.value}:{},...void 0!==e.status?{status:e.status}:{},...void 0!==e.durationMs?{durationMs:e.durationMs}:{},...r?.value?{requestHeaders:r.value}:{},...o?.value?{responseHeaders:o.value}:{},...s?.value!==void 0?{requestBody:s.value}:{},...l?.value!==void 0?{responseBody:l.value}:{},...d.value?{metadata:d.value}:{}}}),...n.nextCursor?{nextCursor:n.nextCursor}:{},...n.timeWindow?{timeWindow:n.timeWindow}:{},...n.backend?{backend:n.backend}:{},redacted:i,...n.notes?{notes:n.notes}:{}}},aH=async(e,t={})=>{var n,a;let r;if(!e.backend.measurePerf)throw new w("UNSUPPORTED_OPERATION","diagnostics.perf is not supported by this backend");return r=!0===(n=await e.backend.measurePerf(await n6(e,t),{...n7(a=t),...void 0!==a.sampleMs?{sampleMs:nd(a.sampleMs,"sampleMs",100,6e4)}:{},...void 0!==a.metrics?{metrics:ae(a.metrics,"metrics",20)}:{}})).redacted,{kind:"diagnosticsPerf",metrics:n.metrics.map(e=>{let t=n5(e.message,4096),n=n3(e.metadata);return r||=t.redacted||n.redacted,{name:e.name,...void 0!==e.value?{value:e.value}:{},...e.unit?{unit:e.unit}:{},...e.status?{status:e.status}:{},...void 0!==t.value?{message:t.value}:{},...n.value?{metadata:n.value}:{}}}),...n.startedAt?{startedAt:n.startedAt}:{},...n.endedAt?{endedAt:n.endedAt}:{},...n.backend?{backend:n.backend}:{},redacted:r,...n.notes?{notes:n.notes}:{}}};function aY(e){let t={backend:e.backend,artifacts:e.artifacts,sessions:e.sessions??function(e=[]){let t=new Map(e.map(e=>[e.name,aK(e)]));return{get:e=>aK(t.get(e)),set:e=>{t.set(e.name,aK(e))},delete:e=>{t.delete(e)},list:()=>Array.from(t.values(),e=>aK(e))}}(),policy:e.policy??function(e={}){return{allowLocalInputPaths:!1,allowLocalOutputPaths:!1,maxImagePixels:2e7,allowNamedBackendCapabilities:[],...e}}(),diagnostics:e.diagnostics,clock:e.clock,signal:e.signal};return{...t,capture:{screenshot:e=>an(t,e),diffScreenshot:e=>aa(t,e),snapshot:e=>ar(t,e),diffSnapshot:e=>ai(t,e)},selectors:{find:e=>ao(t,e),get:e=>as(t,e),getText:(e,n={})=>al(t,{...n,target:e}),getAttrs:(e,n={})=>ad(t,{...n,target:e}),is:e=>au(t,e),isVisible:(e,n={})=>ac(t,{...n,target:e}),isHidden:(e,n={})=>ap(t,{...n,target:e}),wait:e=>af(t,e),waitForText:(e,n={})=>ah(t,{...n,text:e})},interactions:{click:(e,n={})=>am(t,{...n,target:e}),press:(e,n={})=>aw(t,{...n,target:e}),fill:(e,n,a={})=>ag(t,{...a,target:e,text:n}),typeText:(e,n={})=>ay(t,{...n,text:e}),focus:(e,n={})=>ab(t,{...n,target:e}),longPress:(e,n={})=>av(t,{...n,target:e}),swipe:e=>aA(t,e),scroll:e=>aI(t,e),pinch:e=>ax(t,e)},system:{back:e=>aN(t,e),home:e=>aS(t,e),rotate:e=>a_(t,e),keyboard:e=>aM(t,e),clipboard:e=>ak(t,e),settings:e=>aD(t,e),alert:e=>aE(t,e),appSwitcher:e=>aO(t,e)},apps:{open:e=>aC(t,e),close:e=>aR(t,e),list:e=>aP(t,e),state:e=>aT(t,e),push:e=>aL(t,e),triggerEvent:e=>a$(t,e)},admin:{devices:e=>aF(t,e),boot:e=>aU(t,e),ensureSimulator:e=>aG(t,e),install:e=>aV(t,e),reinstall:e=>aB(t,e),installFromSource:e=>aj(t,e)},recording:{record:e=>aq(t,e),trace:e=>aX(t,e)},observability:{logs:e=>az(t,e),network:e=>aW(t,e),perf:e=>aH(t,e)}}}function aK(e){if(e)return{...e,...e.snapshot?{snapshot:structuredClone(e.snapshot)}:{},...e.metadata?{metadata:function(e){try{return structuredClone(e)}catch{return{...e}}}(e.metadata)}:{}}}function aJ(e={}){return{allowLocalInputPaths:!0,allowLocalOutputPaths:!0,maxImagePixels:2e7,allowNamedBackendCapabilities:[],...e}}function aZ(e,t,n){return{ok:!1,error:{code:e,message:t,...n?{details:n}:{}}}}function aQ(e){if(!e)return null;let t=Number(e);return Number.isFinite(t)?t:null}function a0(e){if(0===e.length)return null;let t=aQ(e[0]);if(null!==t)return{kind:"sleep",durationMs:t};if("text"===e[0]){let t=aQ(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=aQ(e[e.length-1]);return{kind:"ref",rawRef:e[0],timeoutMs:t}}let n=aQ(e[e.length-1]),a=g(null!==n?e.slice(0,-1):e.slice());if(a&&0===a.rest.length){let e=v(a.selectorExpression);if(e)return{kind:"selector",selector:e,selectorExpression:a.selectorExpression,timeoutMs:n}}return{kind:"text",text:(null!==n?e.slice(0,-1).join(" "):e.join(" ")).trim(),timeoutMs:n}}function a1(e){return e}function a2(e){return"apple"===e||"ios"===e||"macos"===e}function a3(e,t){return!t||("apple"===t?a2(e):e===t)}function a4(e){let{simulatorSetPath:t,platform:n,target:a}=e;if(t&&"macos"!==n&&"desktop"!==a)return t}async function a5(e,t,n={}){let a=e,r=e=>e.toLowerCase().replace(/_/g," ").replace(/\s+/g," ").trim();if(t.platform&&(a=a.filter(e=>a3(e.platform,t.platform))),t.target&&(a=a.filter(e=>(e.target??"mobile")===t.target)),t.udid){let e=a.find(e=>e.id===t.udid&&a2(e.platform));if(!e)throw new w("DEVICE_NOT_FOUND",`No Apple device with UDID ${t.udid}`);return e}if(t.serial){let e=a.find(e=>e.id===t.serial&&"android"===e.platform);if(!e)throw new w("DEVICE_NOT_FOUND",`No Android device with serial ${t.serial}`);return e}if(t.deviceName){let e=r(t.deviceName),n=a.find(t=>r(t.name)===e);if(!n)throw new w("DEVICE_NOT_FOUND",`No device named ${t.deviceName}`);return n}if(1===a.length)return a[0];if(0===a.length){var i;let e=n.simulatorSetPath;if(e&&(!(i=t.platform)||"apple"===i||"ios"===i))throw new w("DEVICE_NOT_FOUND","No devices found in the scoped simulator set",{simulatorSetPath:e,hint:`The simulator set at "${e}" appears to be empty. Create a simulator first:
|
|
2
|
-
xcrun simctl --set "${e}" create "iPhone 16" com.apple.CoreSimulator.SimDeviceType.iPhone-16 com.apple.CoreSimulator.SimRuntime.iOS-18-0`,selector:t});throw new
|
|
3
|
-
`)}let
|
|
1
|
+
let e;import{__webpack_require__ as t}from"./rslib-runtime.js";import n,{existsSync as a,promises as r}from"node:fs";import{PNG as i}from"pngjs";import o from"node:path";import s,{hostname as l}from"node:os";import d from"node:net";import{AsyncLocalStorage as u}from"node:async_hooks";import{fileURLToPath as c}from"node:url";import{XMLParser as p}from"fast-xml-parser";import{createHash as f}from"node:crypto";import h from"node:fs/promises";import{toAppErrorCode as m,asAppError as w,normalizeError as g,AppError as y}from"./9152.js";import{splitSelectorFromArgs as b,trimText as v,extractNodeText as A,tryParseSelectorChain as I,parseSelectorChain as x,isNodeVisible as S,isNodeEditable as N,pruneGroupNodes as _,buildTextPreview as M,findNearestHittableAncestor as k,buildSelectorChainForNode as D,extractNodeReadText as E,splitIsSelectorArgs as O,findNodeByLabel as C,resolveRefLabel as R,describeTextSurface as P,extractReadableText as T,findSelectorChainMatch as L,resolveSelectorChain as $,normalizeType as F,formatSelectorFailure as U,isFillableType as G}from"./940.js";import{findNodeByRef as V,centerOfRect as B,normalizeRef as j,attachRefs as q}from"./4057.js";import{parseUiHierarchy as W,ensureAndroidSnapshotHelper as X,parseUiHierarchyTree as H,readNodeAttributes as z,captureAndroidSnapshotWithHelper as Y,parseBounds as K,isScrollableNodeLike as J,parseAndroidSnapshotHelperManifest as Z,forgetAndroidSnapshotHelperInstall as Q,isScrollableType as ee,buildUiHierarchySnapshot as et}from"./221.js";import{readVersion as en,findProjectRoot as ea,getDiagnosticsMeta as er,successText as ei,withDiagnosticTimer as eo,withSuccessText as es,emitDiagnostic as el}from"./8161.js";import{runCmdStreaming as ed,runCmdDetached as eu,runCmdBackground as ec,runCmdSync as ep,runCmd as ef,resolveFileOverridePath as eh,whichCmd as em,resolveExecutableOverridePath as ew}from"./9818.js";import{findBestMatchesByLocator as eg,parseFindArgs as ey}from"./7556.js";import"./7847.js";import{sleep as eb,resolveTimeoutMs as ev,resolveTimeoutSeconds as eA}from"./4829.js";import{isProcessGroupAlive as eI,isProcessAlive as ex,readProcessStartTime as eS}from"./8656.js";import{ensureAndroidSdkPathConfigured as eN,resolveAndroidArchivePackageName as e_}from"./7651.js";import{materializeInstallablePath as eM,isTrustedInstallSourceUrl as ek}from"./989.js";import{parseAndroidForegroundApp as eD,parseAndroidLaunchablePackages as eE,parseAndroidUserInstalledPackages as eO}from"./9366.js";var eC={};t.r(eC),t.d(eC,{ensureAndroidEmulatorBooted:()=>oz,listAndroidDevices:()=>oB,waitForAndroidBoot:()=>oY});var eR={};t.r(eR),t.d(eR,{TM:()=>dC,ensureBootedSimulator:()=>lU,installIosApp:()=>dP,installIosInstallablePath:()=>dL,listIosApps:()=>dV,L5:()=>dE,IJ:()=>dO,TJ:()=>dU,J7:()=>d$,reinstallIosApp:()=>dT,resolveIosApp:()=>dD,kc:()=>dp,Cm:()=>dG,ap:()=>dF});let eP="<wifi|airplane|location> <on|off>",eT="animations <on|off>",eL="appearance <light|dark|toggle>",e$="faceid <match|nonmatch|enroll|unenroll>",eF="touchid <match|nonmatch|enroll|unenroll>",eU="fingerprint <match|nonmatch>",eG="permission <grant|deny|reset> <camera|microphone|photos|contacts|contacts-limited|notifications|calendar|location|location-always|media-library|motion|reminders|siri> [full|limited]",eV="permission <grant|reset> <accessibility|screen-recording|input-monitoring>",eB=`macOS supports only settings ${eL} and settings ${eV}. wifi|airplane|location|animations remain unsupported on macOS.`,ej=`settings ${eP} | settings ${eT} | settings ${eL} | settings ${e$} | settings ${eF} | settings ${eU} | settings ${eG} | settings ${eV}`,eq=`settings requires ${eP}, ${eT}, ${eL}, ${e$}, ${eF}, ${eU}, ${eG}, or ${eV}`;function eW(e){return`Unsupported macOS setting: ${e}. ${eB}`}let eX=["app","frontmost-app","desktop","menubar"];function eH(e){let t=e?.trim().toLowerCase();if("app"===t||"frontmost-app"===t||"desktop"===t||"menubar"===t)return t;throw new y("INVALID_ARGS",`Invalid surface: ${e}. Use ${eX.join("|")}.`)}let ez={application:"application",navigationbar:"navigation-bar",tabbar:"tab-bar",button:"button",imagebutton:"button",link:"link",cell:"cell",statictext:"text",checkedtextview:"text",textfield:"text-field",edittext:"text-field",textarea:"text-view",switch:"switch",slider:"slider",image:"image",imageview:"image",webview:"webview",framelayout:"group",linearlayout:"group",relativelayout:"group",constraintlayout:"group",viewgroup:"group",view:"group",listview:"list",recyclerview:"list",collectionview:"collection",searchfield:"search",segmentedcontrol:"segmented-control",group:"group",window:"window",checkbox:"checkbox",radio:"radio",menuitem:"menu-item",toolbar:"toolbar",scrollarea:"scroll-area",scrollview:"scroll-area",nestedscrollview:"scroll-area",table:"table"};function eY(e,t={}){let n=[],a=[];for(let r of e){let e=r.depth??0,i=r.label?.trim()||r.value?.trim()||r.identifier?.trim()||"",o=eZ(r.type??"Element");if("group"===o&&!i)continue;for(;n.length>0&&e<=n[n.length-1];)n.pop();let s=n.length;n.push(e),a.push({node:r,depth:s,type:o,text:eK(r,s,!1,o,t)})}return a}function eK(e,t,n,a,r={}){var i,o,s,l,d,u,c,p;let f,h=a??eZ(e.type??"Element"),m=P(e,h),w=(i=e,o=h,s=r,l=m,s.summarizeTextSurfaces&&l.shouldSummarize&&function(e,t,n){let a=v(e.label);if(a&&a!==n)return a;let r=v(e.identifier);if(r&&!e0(r)&&r!==n)return r;switch(t){case"text":case"text-view":return"Text view";case"text-field":return"Text field";case"search":return"Search field";default:return""}}(i,o,l.text)||eJ(i,o)),g=" ".repeat(t),y=e.ref?`@${e.ref}`:"",b=(d=e,u=h,c=r,p=m,f=[],(!1===d.enabled&&f.push("disabled"),c.summarizeTextSurfaces&&(!0===d.selected&&f.push("selected"),eQ(u)&&f.push("editable"),function(e,t){if("scroll-area"===t)return!0;let n=(e.type??"").toLowerCase(),a=`${e.role??""} ${e.subrole??""}`.toLowerCase();return n.includes("scroll")||a.includes("scroll")}(d,u)&&f.push("scrollable"),p.shouldSummarize))?(f.push(`preview:"${M(p.text).replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`),f.push("truncated"),[...new Set(f)]):f).map(e=>` [${e}]`).join(""),A=w?` "${w}"`:"";return n?`${g}${y} [${h}]${b}`.trimEnd():`${g}${y} [${h}]${A}${b}`.trimEnd()}function eJ(e,t){var n,a;let r,i=e.label?.trim();if(i&&(n=t,a=i,("scroll-area"===n||"list"===n||"collection"===n||"table"===n)&&(r=a.trim().toLowerCase())&&/^(vertical|horizontal)\s+scroll\s+bar(?:,?\s*\d+\s+pages?)?$/.test(r)))return"";let o=e.value?.trim();if(eQ(t)){if(o)return o;if(i)return i}else if(i)return i;if(o)return o;let s=e.identifier?.trim();return!s||e0(s)&&("group"===t||"image"===t||"list"===t||"collection"===t)?"":s}function eZ(e){var t;let n=e.replace(/XCUIElementType/gi,"").toLowerCase(),a=e.includes(".")&&(e.startsWith("android.")||e.startsWith("androidx.")||e.startsWith("com."));return(n.includes(".")&&(n=n.replace(/^android\.widget\./,"").replace(/^android\.view\./,"").replace(/^android\.webkit\./,"").replace(/^androidx\./,"").replace(/^com\.google\.android\./,"").replace(/^com\.android\./,""),a&&n.includes(".")&&(n=n.slice(n.lastIndexOf(".")+1))),"textview"===n)?a?"text":"text-view":(t=n,(Object.prototype.hasOwnProperty.call(ez,t)?ez[t]:void 0)||n||"element")}function eQ(e){return"text-field"===e||"text-view"===e||"search"===e}function e0(e){return/^[\w.]+:id\/[\w.-]+$/i.test(e)}function e1(e){return new Map(e.map(e=>[e.index,e]))}function e2(e){return e.label?.trim()||e.value?.trim()||e.identifier?.trim()||""}function e3(e,t,n){return t>=e.x&&t<=e.x+e.width&&n>=e.y&&n<=e.y+e.height}function e4(e){let t=null,n=-1;for(let a of e){let e=a.width*a.height;e>n&&(t=a,n=e)}return t}function e5(e,t,n,a){return Math.max(e,n)<=Math.min(t,a)}function e8(e){if(0===e.length)return{nodes:e,hiddenCount:0,summaryLines:[]};let{byIndex:t,visibleNodeIndexes:n,offscreenNodes:a,hintedContainers:r}=e6(e),i=0===n.size?e:e.filter(e=>n.has(e.index));return{nodes:i.map(e=>(function(e,t){let n=t.get(e.index);if(!n||0===n.size)return e;let a=!!(!0===e.hiddenContentAbove||n.has("above"))||void 0,r=!!(!0===e.hiddenContentBelow||n.has("below"))||void 0;return{...e,hiddenContentAbove:a,hiddenContentBelow:r}})(e,r.directionsByContainer)),hiddenCount:0===n.size?0:e.length-i.length,summaryLines:function(e,t,n){let a=new Map;for(let r of e){let e=function(e,t,n){if(!e.rect)return null;let a=e7(e,t,n);return a?te(e.rect,a):null}(r,t,n);if(!e)continue;let i=a.get(e)??[];i.push(r),a.set(e,i)}return["above","below"].flatMap(e=>{let t=a.get(e);if(!t||0===t.length)return[];let n=(function(e){let t=new Set,n=[];for(let a of e){let e=e2(a);!e||t.has(e)||(t.add(e),n.push(e))}return n})(t).slice(0,3).map(e=>`"${e}"`),r=1===t.length?"interactive item":"interactive items",i=n.length>0?`: ${n.join(", ")}`:"";return[`[off-screen ${e}] ${t.length} ${r}${i}`]})}(a.filter(e=>!r.coveredNodeIndexes.has(e.index)&&function(e){if(!0===e.hittable)return!0;let t=(e.type??"").toLowerCase();return t.includes("button")||t.includes("link")||t.includes("textfield")||t.includes("edittext")||t.includes("searchfield")||t.includes("checkbox")||t.includes("radio")||t.includes("switch")||t.includes("menuitem")||!!e2(e)}(e)),e,t)}}function e6(e){let t=e1(e),n=new Set,a=[];for(let r of e){if(e9(r,e,t)){!function(e,t,n){let a=e,r=new Set;for(;a&&!r.has(a.index);)r.add(a.index),t.add(a.index),a="number"==typeof a.parentIndex?n.get(a.parentIndex):void 0}(r,n,t);continue}a.push(r)}let r=function(e,t,n,a){let r=new Map,i=new Set;for(let e of t){if(!e.rect)continue;let t=tt(e,n,a);if(!t?.rect)continue;let o=te(e.rect,t.rect);if(!o)continue;let s=r.get(t.index)??new Set;s.add(o),r.set(t.index,s),i.add(e.index)}return function(e,t,n,a){for(let r of e){let e=function(e){let t=function(e,t){if(!(e?.trim().toLowerCase()??"").includes("vertical scroll bar"))return null;let n=function(e){if(!e)return null;let t=/^(\d{1,3})%$/.exec(e.trim());if(!t)return null;let n=Number(t[1]);return Number.isFinite(n)?Math.max(0,Math.min(100,n)):null}(t);return null===n?null:n<=1?{above:!1,below:!0}:n>=99?{above:!0,below:!1}:{above:!0,below:!0}}(e.label,e.value);if(!t)return null;let n=new Set;return t.above&&n.add("above"),t.below&&n.add("below"),n.size>0?n:null}(r);if(!e||0===e.size)continue;let i=tt(r,t,n);if(!i)continue;let o=a.get(i.index)??new Set;for(let t of e)o.add(t);a.set(i.index,o)}}(e,n,a,r),{directionsByContainer:r,coveredNodeIndexes:i}}(e,a,n,t);return{byIndex:t,visibleNodeIndexes:n,offscreenNodes:a,hintedContainers:r}}function e9(e,t,n=e1(t)){var a;if(!e.rect)return!0;let r=e7(e,t,n);return!r||(a=e.rect,e5(a.x,a.x+a.width,r.x,r.x+r.width)&&e5(a.y,a.y+a.height,r.y,r.y+r.height))}function e7(e,t,n=e1(t)){let a=function(e,t){let n="number"==typeof e.parentIndex?t.get(e.parentIndex):void 0,a=new Set;for(;n&&!a.has(n.index);){if(a.add(n.index),n.rect&&J(n))return n.rect;n="number"==typeof n.parentIndex?t.get(n.parentIndex):void 0}return null}(e,n);return a||function(e,t){let n=B(t),a=e.filter(e=>{var t;return!!(t=e.rect)&&Number.isFinite(t.x)&&Number.isFinite(t.y)&&Number.isFinite(t.width)&&Number.isFinite(t.height)}),r=a.filter(e=>{let t=(e.type??"").toLowerCase();return t.includes("application")||t.includes("window")}),i=e4(r.map(e=>e.rect).filter(e=>e3(e,n.x,n.y)));if(i)return i;let o=e4(r.map(e=>e.rect));if(o)return o;let s=e4(a.map(e=>e.rect).filter(e=>e3(e,n.x,n.y)));return s||null}(t,e.rect??{x:0,y:0,width:0,height:0})}function te(e,t){return e.y+e.height<=t.y?"above":e.y>=t.y+t.height?"below":null}function tt(e,t,n){let a="number"==typeof e.parentIndex?n.get(e.parentIndex):void 0,r=new Set;for(;a&&!r.has(a.index);){if(r.add(a.index),t.has(a.index)&&J(a))return a;a="number"==typeof a.parentIndex?n.get(a.parentIndex):void 0}return null}let tn=100,ta=new Set(["batch","replay"]),tr=new Set(["command","positionals","flags","runtime"]);function ti(e){let t;try{t=JSON.parse(e)}catch{throw new y("INVALID_ARGS","Batch steps must be valid JSON.")}if(!Array.isArray(t)||0===t.length)throw new y("INVALID_ARGS","Batch steps must be a non-empty JSON array.");return t}function to(e,t){if(!Array.isArray(e)||0===e.length)throw new y("INVALID_ARGS","batch requires a non-empty batchSteps array.");if(e.length>t)throw new y("INVALID_ARGS",`batch has ${e.length} steps; max allowed is ${t}.`);let n=[];for(let t=0;t<e.length;t+=1){let a=e[t];if(!a||"object"!=typeof a)throw new y("INVALID_ARGS",`Invalid batch step at index ${t}.`);let r=Object.keys(a).filter(e=>!tr.has(e));if(r.length>0){let e=r.map(e=>`"${e}"`).join(", ");throw new y("INVALID_ARGS",`Batch step ${t+1} has unknown field(s): ${e}. Allowed fields: command, positionals, flags, runtime.`)}let i="string"==typeof a.command?a.command.trim().toLowerCase():"";if(!i)throw new y("INVALID_ARGS",`Batch step ${t+1} requires command.`);if(ta.has(i))throw new y("INVALID_ARGS",`Batch step ${t+1} cannot run ${i}.`);if(void 0!==a.positionals&&!Array.isArray(a.positionals))throw new y("INVALID_ARGS",`Batch step ${t+1} positionals must be an array.`);let o=a.positionals??[];if(o.some(e=>"string"!=typeof e))throw new y("INVALID_ARGS",`Batch step ${t+1} positionals must contain only strings.`);if(void 0!==a.flags&&("object"!=typeof a.flags||Array.isArray(a.flags)||!a.flags))throw new y("INVALID_ARGS",`Batch step ${t+1} flags must be an object.`);if(void 0!==a.runtime&&("object"!=typeof a.runtime||Array.isArray(a.runtime)||!a.runtime))throw new y("INVALID_ARGS",`Batch step ${t+1} runtime must be an object.`);n.push({command:i,positionals:o,flags:a.flags??{},runtime:a.runtime})}return n}function ts(e,t){try{return i.sync.read(e)}catch(e){throw new y("COMMAND_FAILED",`Failed to decode ${t} as PNG`,{label:t,reason:e instanceof Error?e.message:String(e)})}}async function tl(e,t){if(!Number.isInteger(t)||t<1)throw new y("INVALID_ARGS","Screenshot max size must be a positive integer");let n=ts(await r.readFile(e),"screenshot"),a=Math.max(n.width,n.height);if(a<=t)return;let o=t/a,s=Math.max(1,Math.round(n.width*o)),l=Math.max(1,Math.round(n.height*o)),d=function(e,t,n){let a=new i({width:t,height:n});for(let r=0;r<n;r+=1){let i=r*e.height/n,o=(r+1)*e.height/n;for(let n=0;n<t;n+=1){let s=n*e.width/t,l=(n+1)*e.width/t,d=0,u=0,c=0,p=0,f=0;for(let t=Math.floor(i);t<Math.ceil(o);t+=1){let n=Math.min(t+1,o)-Math.max(t,i);for(let a=Math.floor(s);a<Math.ceil(l);a+=1){let r=n*(Math.min(a+1,l)-Math.max(a,s)),i=(t*e.width+a)*4;d+=(e.data[i]??0)*r,u+=(e.data[i+1]??0)*r,c+=(e.data[i+2]??0)*r,p+=(e.data[i+3]??0)*r,f+=r}}let h=(r*a.width+n)*4;a.data[h]=Math.round(d/f),a.data[h+1]=Math.round(u/f),a.data[h+2]=Math.round(c/f),a.data[h+3]=Math.round(p/f)}}return a}(n,s,l);await r.writeFile(e,i.sync.write(d))}async function td(e,t,n){if("path"===t.kind&&!e.policy.allowLocalInputPaths)throw new y("INVALID_ARGS",`Local ${n.field??"input"} paths are not allowed by command policy`);try{return await e.artifacts.resolveInput(t,n)}catch(e){throw w(e)}}async function tu(e,t,n){if(t?.kind==="path"&&!e.policy.allowLocalOutputPaths)throw new y("INVALID_ARGS","Local output paths are not allowed by command policy");try{return await e.artifacts.reserveOutput(t,{...n,visibility:n.visibility??"client-visible",requestedClientPath:t?.kind==="downloadableArtifact"?t.clientPath??n.requestedClientPath:n.requestedClientPath})}catch(e){throw w(e)}}async function tc(e,t){try{return await e.artifacts.createTempFile(t)}catch(e){throw w(e)}}let tp=[0,187,255,255];function tf(e,t,n,a){if(t<0||t>=e.width||n<0||n>=e.height)return;let r=(n*e.width+t)*4;e.data[r]=a[0],e.data[r+1]=a[1],e.data[r+2]=a[2],e.data[r+3]=a[3]}function th(e,t,n){return Math.min(Math.max(e,t),n)}let tm={icon:90,toggle:90,chevron:75,separator:45,visual:35,background:10},tw={leading:20,trailing:20,separator:10,unknown:0,background:-30};function tg(e){return"background"!==e.likelyKind}function ty(e,t){return e.width>=.25*t.width||e.height>=.06*t.height}function tb(e,t){let n,a=0;for(let r of t){let t=tS(e,r.rect);t<=a||(a=t,n=r)}return n}function tv(e){let t=[];for(let n of[...e].sort((e,t)=>e.rect.y-t.rect.y)){let e=t.find(e=>{var t,a;return t=e.rect,tS(t,a=n.rect)>0||Math.abs(tN(t).y-tN(a).y)<=.5*Math.max(t.height,a.height)});if(!e){t.push({rect:n.rect,blocks:[n]});continue}e.blocks.push(n),e.blocks.sort((e,t)=>e.rect.x-t.rect.x),e.rect=function(e){let t=1/0,n=1/0,a=-1/0,r=-1/0;for(let i of e)t=Math.min(t,i.x),n=Math.min(n,i.y),a=Math.max(a,i.x+i.width),r=Math.max(r,i.y+i.height);return{x:t,y:n,width:a-t,height:r-n}}([e.rect,n.rect])}return t}function tA(e,t){let n,a=tN(e);for(let e of t){var r,i;let t=Math.sqrt((r=a,i=tN(e.rect),(r.x-i.x)**2+(r.y-i.y)**2));n&&t>=n.distance||(n={block:e,distance:t})}return n}function tI(e){let t=tx(e);return e.differentPixels>=24&&t.width>=3&&t.height>=3}function tx(e){return{x:e.minX,y:e.minY,width:e.maxX-e.minX+1,height:e.maxY-e.minY+1}}function tS(e,t){return Math.max(0,Math.min(e.y+e.height,t.y+t.height)-Math.max(e.y,t.y))}function tN(e){return{x:e.x+e.width/2,y:e.y+e.height/2}}function t_(e,t,n){return Math.min(Math.max(e,t),n)}async function tM(e){if(await em("tesseract"))try{let[t,n]=await Promise.all([tD(e.baselinePath),tD(e.currentPath)]);if(0!==t.exitCode||0!==n.exitCode)return;let a=tk(t.stdout,e.width,e.height),r=tk(n.stdout,e.width,e.height),i=function(e,t){let n=new Set,a=[];for(let i of e){var r;let e=tL(i.text),o=function(e,t,n,a){let r=null,i=1/0;for(let l=0;l<n.length;l+=1){var o,s;if(a.has(l))continue;let d=n[l];if(tL(d.text)!==t)continue;let u=(o=tR(e.normalizedRect),s=tR(d.normalizedRect),(o.x-s.x)**2+(o.y-s.y)**2);u>=i||(r=l,i=u)}return r}(i,e,t,n);if(null===o)continue;n.add(o);let s=function(e,t){let n={x:t.rect.x-e.rect.x,y:t.rect.y-e.rect.y,width:t.rect.width-e.rect.width,height:t.rect.height-e.rect.height},a=tU(t.rect.width/e.rect.width),r=tU(t.rect.height/e.rect.height),i=Math.abs(a-1)>=.08||Math.abs(r-1)>=.12;return{text:e.text,baselineRect:e.rect,currentRect:t.rect,delta:n,confidence:Math.round(100*Math.min(e.confidence,t.confidence))/100,possibleTextMetricMismatch:i}}(i,t[o]);r=s,(Math.abs(r.delta.x)>=2||Math.abs(r.delta.y)>=2||Math.abs(r.delta.width)>=2||Math.abs(r.delta.height)>=2||r.possibleTextMetricMismatch)&&a.push(s)}return a.sort((e,t)=>tE(t)-tE(e)).slice(0,12)}(a,r),o=function(e){let t=[];for(let n of[...e].sort((e,t)=>e.currentRect.y-t.currentRect.y)){let e=t.find(e=>32>=Math.abs(n.delta.x-t$(e.map(e=>e.delta.x))));e?e.push(n):t.push([n])}return t.filter(e=>e.length>=2).map(tO).filter(e=>e.yRange.max-e.yRange.min<=60).sort((e,t)=>tC(t)-tC(e)).slice(0,4)}(i);if(0===a.length&&0===r.length)return;return{provider:"tesseract",baselineBlocks:a.length,currentBlocks:r.length,baselineBlocksRaw:a,currentBlocksRaw:r,matches:i,...o.length>0?{movementClusters:o}:{}}}catch{return}}function tk(e,t,n){let[a,...r]=e.split(/\r?\n/);if(!a)return[];let i=new Map(a.split(" ").map((e,t)=>[e,t])),o=[];for(let e of r){var s;if(!e.trim())continue;let t=e.split(" "),n=tT(t,i,"level"),a=tP(t,i,"text").trim(),r=tT(t,i,"conf");if(5!==n||(s=a,!/[\p{L}\p{N}]/u.test(s))||r<0)continue;let l=tT(t,i,"left"),d=tT(t,i,"top"),u=tT(t,i,"width"),c=tT(t,i,"height");u<=0||c<=0||o.push({key:[tP(t,i,"page_num"),tP(t,i,"block_num"),tP(t,i,"par_num"),tP(t,i,"line_num")].join(":"),text:a,confidence:r,rect:{x:l,y:d,width:u,height:c}})}let l=new Map;for(let e of o){let t=l.get(e.key);t?t.push(e):l.set(e.key,[e])}return Array.from(l.values()).flatMap(e=>(function(e){let t=[...e].sort((e,t)=>e.rect.x-t.rect.x),n=[],a=[];for(let e of t){let t=a.at(-1);if(!t){a.push(e);continue}if(e.rect.x-(t.rect.x+t.rect.width)>Math.max(48,2.5*Math.max(t.rect.height,e.rect.height))){n.push(a),a=[e];continue}a.push(e)}return a.length>0&&n.push(a),n})(e)).map(e=>(function(e,t,n){if(0===e.length)return null;let a=[...e].sort((e,t)=>e.rect.x-t.rect.x),r=function(e){let t=1/0,n=1/0,a=-1/0,r=-1/0;for(let i of e)t=Math.min(t,i.x),n=Math.min(n,i.y),a=Math.max(a,i.x+i.width),r=Math.max(r,i.y+i.height);return{x:t,y:n,width:a-t,height:r-n}}(a.map(e=>e.rect)),i=Math.round(100*t$(a.map(e=>e.confidence)))/100;return{text:a.map(e=>e.text).join(" "),confidence:i,rect:r,normalizedRect:{x:tF(r.x/t),y:tF(r.y/n),width:tF(r.width/t),height:tF(r.height/n)}}})(e,t,n)).filter(e=>null!==e)}function tD(e){return ef("tesseract",[e,"stdout","-l","eng","tsv"],{allowFailure:!0,timeoutMs:1e4})}function tE(e){return Math.abs(e.delta.x)+Math.abs(e.delta.y)+Math.abs(e.delta.width)+Math.abs(e.delta.height)+25*!!e.possibleTextMetricMismatch}function tO(e){let t=e.map(e=>e.delta.x),n=e.map(e=>e.delta.y);return{texts:e.map(e=>e.text),xRange:{min:Math.min(...t),max:Math.max(...t)},yRange:{min:Math.min(...n),max:Math.max(...n)}}}function tC(e){return 2*Math.abs((e.xRange.min+e.xRange.max)/2)+Math.abs((e.yRange.min+e.yRange.max)/2)}function tR(e){return{x:e.x+e.width/2,y:e.y+e.height/2}}function tP(e,t,n){let a=t.get(n);return void 0===a?"":e[a]??""}function tT(e,t,n){let a=Number(tP(e,t,n));return Number.isFinite(a)?a:0}function tL(e){return e.trim().replace(/\s+/g," ").toLowerCase()}function t$(e){return e.reduce((e,t)=>e+t,0)/e.length}function tF(e){return Math.round(100*e*100)/100}function tU(e){return Math.round(1e3*e)/1e3}function tG(e,t,n,a){return{r:Math.round(e/a),g:Math.round(t/a),b:Math.round(n/a)}}function tV(e){return .2126*e.r+.7152*e.g+.0722*e.b}function tB(e){return`#${tj(e.r)}${tj(e.g)}${tj(e.b)}`}function tj(e){return e.toString(16).padStart(2,"0")}function tq(e){return Math.round(100*e*100)/100}let tW=255*Math.sqrt(3);async function tX(e,t,n={}){let a,s,l,d;await tH(e,"Baseline image not found"),await tH(t,"Current screenshot not found");let u=n.outputPath,[c,p]=await Promise.all([r.readFile(e),r.readFile(t)]),f=ts(c,"baseline screenshot"),h=ts(p,"current screenshot");tz(f.width,f.height,"baseline screenshot",n.maxPixels),tz(h.width,h.height,"current screenshot",n.maxPixels);let m=n.threshold??.1;if(f.width!==h.width||f.height!==h.height){let e=f.width*f.height;return await tY(n.outputPath),{match:!1,mismatchPercentage:100,totalPixels:e,differentPixels:e,dimensionMismatch:{expected:{width:f.width,height:f.height},actual:{width:h.width,height:h.height}}}}let w=f.width*f.height,g=m*tW,y=new i({width:f.width,height:f.height}),b=new Uint8Array(w),v=0;for(let e=0,t=0;e<f.data.length;e+=4,t+=1){if(Math.sqrt((f.data[e]-h.data[e])**2+(f.data[e+1]-h.data[e+1])**2+(f.data[e+2]-h.data[e+2])**2)>g){v+=1,b[t]=1;let n=tK(h,e);y.data[e]=tJ(n,220,.78),y.data[e+1]=tJ(n,0,.78),y.data[e+2]=tJ(n,0,.78),y.data[e+3]=255;continue}let n=tK(h,e);y.data[e]=n,y.data[e+1]=n,y.data[e+2]=n,y.data[e+3]=255}let A=v>0?(x=(a=function(e){let{diffMask:t,baseline:n,current:a}=e,{width:r,height:i}=n,o=new Uint8Array(t.length),s=new Int32Array(t.length),l=[];for(let e=0;e<t.length;e+=1){if(1!==t[e]||1===o[e])continue;let d=0,u=0;s[0]=e,u+=1,o[e]=1;let c=e%r,p=Math.floor(e/r),f={minX:c,minY:p,maxX:c,maxY:p,differentPixels:0,baselineRed:0,baselineGreen:0,baselineBlue:0,currentRed:0,currentGreen:0,currentBlue:0};for(;d<u;){let e=s[d];d+=1,function(e,t,n,a,r){let i=t%n,o=Math.floor(t/n),s=4*t;e.minX=Math.min(e.minX,i),e.minY=Math.min(e.minY,o),e.maxX=Math.max(e.maxX,i),e.maxY=Math.max(e.maxY,o),e.differentPixels+=1,e.baselineRed+=a.data[s],e.baselineGreen+=a.data[s+1],e.baselineBlue+=a.data[s+2],e.currentRed+=r.data[s],e.currentGreen+=r.data[s+1],e.currentBlue+=r.data[s+2]}(f,e,r,n,a);let l=e%r,c=Math.floor(e/r);for(let e=-1;e<=1;e+=1){let n=c+e;if(!(n<0)&&!(n>=i))for(let a=-1;a<=1;a+=1){if(0===a&&0===e)continue;let i=l+a;if(i<0||i>=r)continue;let d=n*r+i;1===t[d]&&1!==o[d]&&(o[d]=1,s[u]=d,u+=1)}}}l.push(f)}return l}(I={diffMask:b,baseline:f,current:h,totalPixels:w,differentPixels:v,maxRegions:n.maxRegions})).length<=2e3?function(e){let t=[];for(let r of e.sort((e,t)=>{let n=e.minY-t.minY;return 0!==n?n:e.minX-t.minX})){var n,a;let e=t.find(e=>{var t,n,a;return t=e,n=r,a=12,t.minX-a<=n.maxX&&n.minX-a<=t.maxX&&t.minY-a<=n.maxY&&n.minY-a<=t.maxY});if(!e){t.push({...r});continue}n=e,a=r,n.minX=Math.min(n.minX,a.minX),n.minY=Math.min(n.minY,a.minY),n.maxX=Math.max(n.maxX,a.maxX),n.maxY=Math.max(n.maxY,a.maxY),n.differentPixels+=a.differentPixels,n.baselineRed+=a.baselineRed,n.baselineGreen+=a.baselineGreen,n.baselineBlue+=a.baselineBlue,n.currentRed+=a.currentRed,n.currentGreen+=a.currentGreen,n.currentBlue+=a.currentBlue}return t}(a):a,x.flatMap(e=>{var t,n,a;let r;return(t=e,n=I.baseline.width,a=I.baseline.height,r=t.maxX-t.minX+1,t.maxY-t.minY+1>=Math.max(48,Math.round(.07*a))&&r>=.35*n)?function(e,t,n){var a;let r=function(e,t){let n=[],a=null;for(let r=0;r<e.length;r+=1){if(e[r]<=t){a??=r;continue}null!==a&&(r-a>=6&&n.push([a,r-1]),a=null)}return null!==a&&e.length-a>=6&&n.push([a,e.length-1]),n}((a=function(e,t,n){let a=[];for(let r=e.minY;r<=e.maxY;r+=1){let i=0;for(let a=e.minX;a<=e.maxX;a+=1)1===t[r*n+a]&&(i+=1);a.push(i)}return a}(e,t.diffMask,t.baseline.width)).map((e,t)=>{let n=0,r=0,i=Math.max(0,t-3),o=Math.min(a.length-1,t+3);for(let e=i;e<=o;e+=1)n+=a[e],r+=1;return Math.round(n/r)}),Math.max(1,Math.round((e.maxX-e.minX+1)*.08))),i=function(e,t,n){let a=[],r=e.minY;for(let[i,o]of t){let t=e.minY+Math.round((i+o)/2);t-r+1<n||e.maxY-t<n||(a.push([r,t]),r=t+1)}return a.push([r,e.maxY]),a}(e,r,n);if(i.length<=1)return[e];let o=i.map(([n,a])=>(function(e,t,n,a){let r=null;for(let s=t;s<=n;s+=1)for(let t=e.minX;t<=e.maxX;t+=1){var i,o;let e=s*a.baseline.width+t;1===a.diffMask[e]&&function(e,t,n,a,r,i){let o=4*t;e.minX=Math.min(e.minX,n),e.minY=Math.min(e.minY,a),e.maxX=Math.max(e.maxX,n),e.maxY=Math.max(e.maxY,a),e.differentPixels+=1,e.baselineRed+=r.data[o],e.baselineGreen+=r.data[o+1],e.baselineBlue+=r.data[o+2],e.currentRed+=i.data[o],e.currentGreen+=i.data[o+1],e.currentBlue+=i.data[o+2]}(r??={minX:i=t,minY:o=s,maxX:i,maxY:o,differentPixels:0,baselineRed:0,baselineGreen:0,baselineBlue:0,currentRed:0,currentGreen:0,currentBlue:0},e,t,s,a.baseline,a.current)}return r})(e,n,a,t)).filter(e=>null!==e);return o.length>1?o:[e]}(e,I,Math.max(24,Math.round(.03*I.baseline.height))):[e]})).sort((e,t)=>{let n=t.differentPixels-e.differentPixels;if(0!==n)return n;let a=e.minY-t.minY;return 0!==a?a:e.minX-t.minX}).slice(0,Math.max(0,I.maxRegions??8)).map((e,t)=>{var n,a,r,i,o,s,l,d,u,c,p;let f,h,m,w,g,y,b,v,A,x,S,N,_,M,k,D,E;return n=e,a=t+1,r={width:I.baseline.width,height:I.baseline.height,totalPixels:I.totalPixels,differentPixels:I.differentPixels},y={x:n.minX,y:n.minY,width:n.maxX-n.minX+1,height:n.maxY-n.minY+1},b={x:Math.round(n.minX+y.width/2),y:Math.round(n.minY+y.height/2)},v=tG(n.baselineRed,n.baselineGreen,n.baselineBlue,n.differentPixels),A=tG(n.currentRed,n.currentGreen,n.currentBlue,n.differentPixels),x=y.width*y.height,S=tq(n.differentPixels/x),N=Math.round(tV(v)),_=Math.round(tV(A)),M=(i=y,o=r.width,s=r.height,i.width>=.55*o&&i.height>=.12*s?"large-area":i.width>=2.5*i.height?"horizontal-band":i.height>=2.5*i.width?"vertical-band":"compact"),k=(f=x/r.totalPixels)>=.04?"large":f>=.01?"medium":"small",D=(l=v,d=A,h=tV(l),Math.abs(m=tV(d)-h)>=12?m>0?"brighter":"darker":Math.max(Math.abs(d.r-l.r),Math.abs(d.g-l.g),Math.abs(d.b-l.b))>=12?"color-shift":"mixed"),E=(u=b,c=r.width,p=r.height,w=u.x<c/3?"left":u.x>2*c/3?"right":"center",g=u.y<p/3?"top":u.y>2*p/3?"bottom":"middle","center"===w&&"middle"===g?"center":`${g}-${w}`),{index:a,rect:y,normalizedRect:{x:tq(y.x/r.width),y:tq(y.y/r.height),width:tq(y.width/r.width),height:tq(y.height/r.height)},differentPixels:n.differentPixels,shareOfDiffPercentage:tq(n.differentPixels/r.differentPixels),densityPercentage:S,shape:M,size:k,location:E,averageBaselineColorHex:tB(v),averageCurrentColorHex:tB(A),baselineLuminance:N,currentLuminance:_,dominantChange:D}}):[];if(v>0&&u){var I,x,S;for(let e of A)e.rect.width<4||e.rect.height<4||function(e,t){let n=th(t.x,0,e.width-1),a=th(t.y,0,e.height-1),r=th(t.x+t.width-1,0,e.width-1),i=th(t.y+t.height-1,0,e.height-1);for(let t=0;t<2;t+=1){for(let o=n;o<=r;o+=1)tf(e,o,a+t,tp),tf(e,o,i-t,tp);for(let o=a;o<=i;o+=1)tf(e,n+t,o,tp),tf(e,r-t,o,tp)}}(y,e.rect);await r.mkdir(o.dirname(u),{recursive:!0}),await r.writeFile(u,i.sync.write(y))}else await tY(n.outputPath);let N=v>0?await tM({baselinePath:e,currentPath:t,width:f.width,height:f.height}):void 0,_=N&&(N.matches.length>0||(N.movementClusters?.length??0)>0)?{provider:N.provider,baselineBlocks:N.baselineBlocks,currentBlocks:N.currentBlocks,matches:N.matches,...N.movementClusters?{movementClusters:N.movementClusters}:{}}:void 0,M=v>0&&N?(s=function(e){let t=[];for(let n of e.sort((e,t)=>e.minY-t.minY||e.minX-t.minX)){let e=t.find(e=>{var t,a,r;return t=e,a=n,r=10,t.minX-r<=a.maxX&&a.minX-r<=t.maxX&&t.minY-r<=a.maxY&&a.minY-r<=t.maxY});if(!e){t.push({...n});continue}e.minX=Math.min(e.minX,n.minX),e.minY=Math.min(e.minY,n.minY),e.maxX=Math.max(e.maxX,n.maxX),e.maxY=Math.max(e.maxY,n.maxY),e.differentPixels+=n.differentPixels}return t}(function(e,t,n){let a=new Uint8Array(e.length),r=new Int32Array(e.length),i=[];for(let o=0;o<e.length;o+=1){if(1!==e[o]||1===a[o])continue;let s=0,l=0;r[0]=o,l+=1,a[o]=1;let d=o%t,u=Math.floor(o/t),c={minX:d,minY:u,maxX:d,maxY:u,differentPixels:0};for(;s<l;){let i=r[s];s+=1;let o=i%t,d=Math.floor(i/t);c.minX=Math.min(c.minX,o),c.minY=Math.min(c.minY,d),c.maxX=Math.max(c.maxX,o),c.maxY=Math.max(c.maxY,d),c.differentPixels+=1;for(let i=-1;i<=1;i+=1){let s=d+i;if(!(s<0)&&!(s>=n))for(let n=-1;n<=1;n+=1){if(0===n&&0===i)continue;let d=o+n;if(d<0||d>=t)continue;let u=s*t+d;1===e[u]&&1!==a[u]&&(a[u]=1,r[l]=u,l+=1)}}}i.push(c)}return i}(function(e,t,n,a){let r=new Uint8Array(e);if(!a)return r;for(let e of[...a.baselineBlocksRaw,...a.currentBlocksRaw]){var i;!function(e,t,n,a){let r=t_(Math.floor(a.x),0,t-1),i=t_(Math.floor(a.y),0,n-1),o=t_(Math.ceil(a.x+a.width),0,t),s=t_(Math.ceil(a.y+a.height),0,n);for(let n=i;n<s;n+=1)for(let a=r;a<o;a+=1)e[n*t+a]=0}(r,t,n,{x:(i=e.rect).x-8,y:i.y-8,width:i.width+16,height:i.height+16})}return r}((S={diffMask:b,width:f.width,height:f.height,regions:A,ocr:N}).diffMask,S.width,S.height,S.ocr),S.width,S.height)),l=tv(S.ocr?.currentBlocksRaw??[]),d=tv(S.ocr?.baselineBlocksRaw??[]),s.filter(tI).map(e=>{var t,n,a,r,i,o,s,u,c,p,f;let h,m,w,g,y,b,v,A,I,x;return t=e,n=S,a=l,r=d,g=function(e,t){let n,a=0;for(let r of t){let t=function(e,t){let n=Math.max(e.x,t.x),a=Math.max(e.y,t.y),r=Math.min(e.x+e.width,t.x+t.width),i=Math.min(e.y+e.height,t.y+t.height);return r<=n||i<=a?0:(r-n)*(i-a)}(e,r.rect);t<=a||(a=t,n=r)}return n?.index}(w=tx(t),n.regions),y=function(e,t,n){let a=tb(e,t);if(a)return tA(e,a.blocks);let r=tb(e,n);return r?tA(e,r.blocks):void 0}(w,a,r),b=function(e,t,n){if(e.height<=3&&e.width>=.12*n)return"separator";if(!t)return e.width>=.4*n?"background":"unknown";if(e.width>=.4*n)return"background";let a=e.x+e.width/2,r=t.x+t.width/2;return a<r-t.width/2?"leading":a>r+t.width/2?"trailing":e.width>=.35*n?"background":"unknown"}(w,y?.block.rect,n.width),v=(i=w,o=b,s=t.differentPixels,u=n,h=i.width/i.height,m=s/(i.width*i.height),"separator"===o?"separator":"background"===o?"background":"trailing"===o&&h>=1.5&&h<=3.8&&m>=.35?"toggle":"trailing"===o&&i.width<=.06*u.width&&i.height<=.04*u.height?"chevron":"leading"===o&&h>=.55&&h<=1.8?"icon":ty(i,u)?"background":"visual"),A={...g?{regionIndex:g}:{},slot:b,likelyKind:v,rect:w},{...g?{regionIndex:g}:{},slot:b,likelyKind:v,rect:w,...y?{nearestText:y.block.text.trim().replace(/^[^\p{L}\p{N}]+/u,"").replace(/^\p{L}\s+/u,"")}:{},score:(c=A,p=t.differentPixels,f=n,I=ty(c.rect,f)?-35:0,x=20*!!c.regionIndex,tm[c.likelyKind]+tw[c.slot]+x+I+Math.min(20,p/200))}}).filter(e=>e.rect.y>=.08*S.height).filter(tg).sort((e,t)=>t.score-e.score).slice(0,Math.max(0,S.maxDeltas??12)).map((e,t)=>{var n;return n=e,{index:t+1,...n.regionIndex?{regionIndex:n.regionIndex}:{},slot:n.slot,likelyKind:n.likelyKind,rect:n.rect,...n.nearestText?{nearestText:n.nearestText}:{}}})):[],k=w>0?Math.round(v/w*1e4)/100:0;return{...v>0&&u?{diffPath:u}:{},...A.length>0?{regions:A}:{},..._?{ocr:_}:{},...M.length>0?{nonTextDeltas:M}:{},totalPixels:w,differentPixels:v,mismatchPercentage:k,match:0===v}}async function tH(e,t){try{await r.access(e)}catch{throw new y("INVALID_ARGS",`${t}: ${e}`)}}function tz(e,t,n,a){if(null==a||a<=0)return;let r=e*t;if(!(r<=a))throw new y("INVALID_ARGS",`${n} is ${r} pixels, which exceeds the configured maxImagePixels limit of ${a}`)}async function tY(e){if(e)try{await r.unlink(e)}catch(e){var t;if(!("object"==typeof(t=e)&&null!==t&&"code"in t&&"ENOENT"===t.code))throw e}}function tK(e,t){return tJ(Math.round(.299*e.data[t]+.587*e.data[t+1]+.114*e.data[t+2]),255,.72)}function tJ(e,t,n){return Math.round(e*(1-n)+t*n)}function tZ(e){return e.width*e.height}function tQ(e){return Math.round(100*e*100)/100}async function t0(e,t){let n=await tc(e,{prefix:"agent-device-diff-current",ext:".png"});try{await t2(e,t,n.path,t3(t))}catch(e){throw await n.cleanup(),e}return n}async function t1(e,t,n,a,r){var i,o,s,l;if(!t.overlayRefs)return a;if(a.match||a.dimensionMismatch)return n&&await t5(n),a;let d=(i=t,o=n,i.currentOverlayOut?i.currentOverlayOut:i.out?.kind==="path"?{kind:"path",path:t4(o??i.out.path)}:i.out?.kind==="downloadableArtifact"?{kind:"downloadableArtifact",...i.out.clientPath?{clientPath:t4(i.out.clientPath)}:{},...i.out.fileName?{fileName:t4(i.out.fileName)}:{}}:void 0),u=await tu(e,d,{field:"currentOverlayPath",ext:".png"});try{let n=await t2(e,t,u.path,{overlayRefs:!0,...t3(t)}),i=await u.publish();return i&&r.push(i),{...a,currentOverlayPath:n.path??u.path,...n.overlayRefs?{currentOverlayRefCount:n.overlayRefs.length}:{},...a.regions&&n.overlayRefs?{regions:(s=a.regions,l=n.overlayRefs,s.map(e=>{var t,n;let a,r=(t=e,n=l,a=tZ(t.rect),n.map(e=>{var n,r;let i,o,s,l,d=e.overlayRect,u=(n=t.rect,r=d,i=Math.max(n.x,r.x),o=Math.max(n.y,r.y),s=Math.min(n.x+n.width,r.x+r.width),l=Math.min(n.y+n.height,r.y+r.height),s<=i||l<=o?0:(s-i)*(l-o));return u<=0?null:{ref:e.ref,...e.label?{label:e.label}:{},rect:d,overlayCoveragePercentage:tQ(u/tZ(d)),regionCoveragePercentage:tQ(u/a)}}).filter(e=>null!==e).sort((e,t)=>{let n=t.regionCoveragePercentage-e.regionCoveragePercentage;return 0!==n?n:t.overlayCoveragePercentage-e.overlayCoveragePercentage}).slice(0,3).map(e=>({ref:e.ref,...e.label?{label:e.label}:{},rect:e.rect,regionCoveragePercentage:e.regionCoveragePercentage})));return r.length>0?{...e,currentOverlayMatches:r}:e}))}:{}}}catch(e){throw await u.cleanup?.(),e}}async function t2(e,t,n,a={}){if(!e.backend.captureScreenshot)throw new y("UNSUPPORTED_OPERATION","screenshot is not supported by this backend");return await e.backend.captureScreenshot({session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata},n,a)??{}}function t3(e){return e.surface?{surface:e.surface}:{}}function t4(e){let t=o.extname(e),n=t?e.slice(0,-t.length):e;return`${n}.current-overlay${t||".png"}`}async function t5(e){try{await r.unlink(t4(e))}catch(e){var t;if(!("object"==typeof(t=e)&&null!==t&&"code"in t&&"ENOENT"===t.code))throw e}}function t8(e){return"live"===e.kind}function t6(e,t){let n=eZ(e.type??"Element"),a=eJ(e,n),r=!1===e.enabled?"disabled":"enabled",i=!0===e.selected?"selected":"unselected",o=!0===e.hittable?"hittable":"not-hittable";return[String(t??e.depth??0),n,a,r,i,o].join("|")}function t9(e,t){return t.flatten?e.map(e=>({text:eK(e,0,!1),comparable:t6(e,0)})):eY(e).map(e=>({text:e.text,comparable:t6(e.node,e.depth)}))}function t7(e,t){return e.get(t)??0}function ne(e){return"text"===e||"label"===e||"any"===e}function nt(e,t){return{session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata}}function nn(e){return e.clock?.now()??Date.now()}async function na(e,t){e.clock?await e.clock.sleep(t):await new Promise(e=>setTimeout(e,t))}async function nr(e,t){var n,a,r,i,o;let s,l,d,u,c,p;if(!e.backend.captureSnapshot)throw new y("UNSUPPORTED_OPERATION","snapshot is not supported by this backend");let f=t.session??"default",h=await e.sessions.get(f),m=await e.backend.captureSnapshot({session:f,requestId:t.requestId,appId:h?.appId,appBundleId:h?.appBundleId,signal:t.signal??e.signal,metadata:t.metadata},{interactiveOnly:t.interactiveOnly,compact:t.compact,depth:t.depth,scope:t.scope,raw:t.raw}),w=(n=m,a=e,n.snapshot?n.snapshot:{nodes:n.nodes??[],truncated:n.truncated,backend:n.backend,createdAt:nn(a)}),g=nn(e);return{snapshot:w,result:m,session:h,warnings:(s=[...(r={result:m,snapshot:w,options:t,session:h,capturedAt:w.createdAt??g,runtimeNow:g}).result.warnings??[]],l=!0===r.options.interactiveOnly,d=r.result.analysis,"android"===r.snapshot.backend&&l&&0===r.snapshot.nodes.length&&d&&(d.rawNodeCount??0)>=12&&(s.push(`Interactive snapshot is empty after filtering ${d.rawNodeCount} raw Android nodes. Likely causes: depth too low, transient route change, or collector filtering.`),"number"==typeof r.options.depth&&"number"==typeof d.maxDepth&&d.maxDepth>=r.options.depth+2&&s.push(`Interactive output is empty at depth ${r.options.depth}; retry without -d.`)),c=!!(u=r.session?.snapshot)&&[r.capturedAt,r.runtimeNow].some(e=>{let t=e-u.createdAt;return t>=0&&t<=2e3}),!r.result.freshness&&u&&c&&(i=u.nodes.length,o=r.snapshot.nodes.length,!(i<12)&&o<=Math.floor(.2*i))&&s.push("Recent snapshots dropped sharply in node count, which suggests stale or mid-transition UI. Use screenshot as visual truth, wait briefly, then re-snapshot once."),p=r.result.freshness,p?.staleAfterRetries&&"android"===r.snapshot.backend&&("stuck-route"===p.reason?s.push(`Recent ${p.action} was followed by a nearly identical snapshot after ${p.retryCount} automatic retr${1===p.retryCount?"y":"ies"}. If you expected navigation or submit, the tree may still be stale. Use screenshot as visual truth, wait briefly, then re-snapshot once.`):"sharp-drop"===p.reason&&s.push("Recent snapshots dropped sharply in node count, which suggests stale or mid-transition UI. Use screenshot as visual truth, wait briefly, then re-snapshot once.")),Array.from(new Set(s)))}}function ni(e,t){let n=t.session?.name??e??"default";return{...t.session??{name:n},name:n,snapshot:t.snapshot,appName:t.result.appName??t.session?.appName,appBundleId:t.result.appBundleId??t.session?.appBundleId}}function no(e){return["visible","hidden","exists","editable","selected","text"].includes(e)}function ns(e){return!!(e&&Number.isFinite(e.x)&&Number.isFinite(e.y)&&Number.isFinite(e.width)&&Number.isFinite(e.height)&&e.width>0&&e.height>0)}async function nl(e,t){let n=t??"default",a=await e.sessions.get(n);if(!a)throw new y("SESSION_NOT_FOUND","No active session. Run open first.");if(!a.snapshot)throw new y("INVALID_ARGS","No snapshot in session. Run snapshot first.");return{sessionName:n,session:a,snapshot:a.snapshot}}async function nd(e,t,n={updateSession:!0}){if(!e.backend.captureSnapshot)throw new y("UNSUPPORTED_OPERATION","snapshot is not supported by this backend");let a=t.session??"default",r=await e.sessions.get(a),i=await e.backend.captureSnapshot(nt(e,t),{interactiveOnly:!1,compact:!1,depth:t.depth,scope:n.scope??t.scope,raw:t.raw}),o=i.snapshot??{nodes:i.nodes??[],truncated:i.truncated,backend:i.backend,createdAt:nn(e)};return n.updateSession&&r&&await e.sessions.set({...r,snapshot:o}),{sessionName:a,session:r,snapshot:o}}async function nu(e,t,n){if(e.backend.readText){let a=await e.backend.readText(nt(e,{session:t.sessionName}),n);if(a.text.trim())return a.text}return T(n)}let nc=async(e,t)=>{if("ref"===t.target.kind){let n=await nl(e,t.session),a=function(e,t,n){let a=j(t);if(!a)throw new y("INVALID_ARGS",n.invalidRefMessage);let r=V(e,a)??(n.fallbackLabel.length>0?C(e,n.fallbackLabel):null);if(!r)throw new y("COMMAND_FAILED",n.notFoundMessage);return{ref:a,node:r}}(n.snapshot.nodes,t.target.ref,{fallbackLabel:t.target.fallbackLabel??"",invalidRefMessage:"get text requires a ref like @e2",notFoundMessage:`Ref ${t.target.ref} not found`}),r=D(a.node,e.backend.platform,{action:"get"}),i={kind:"ref",ref:`@${a.ref}`};return"attrs"===t.property?{kind:"attrs",target:i,node:a.node,selectorChain:r}:{kind:"text",target:i,text:await nu(e,n,a.node),node:a.node,selectorChain:r}}let n=await nx(e,t,t.session??"default",{selector:t.target.selector,disambiguateAmbiguous:"text"===t.property}),a=D(n.node,e.backend.platform,{action:"get"});if("attrs"===t.property)return{kind:"attrs",target:{kind:"selector",selector:n.selector},node:n.node,selectorChain:a};let r=await nu(e,n.capture,n.node);return{kind:"text",target:{kind:"selector",selector:n.selector},text:r,node:n.node,selectorChain:a}},np=async(e,t)=>{let n=await nc(e,{...t,property:"text",target:t.target});if("text"!==n.kind)throw new y("COMMAND_FAILED","getText returned non-text result");return n},nf=async(e,t)=>{let n=await nc(e,{...t,property:"attrs",target:t.target});if("attrs"!==n.kind)throw new y("COMMAND_FAILED","getAttrs returned non-attrs result");return n},nh=async(e,t)=>{if(!no(t.predicate))throw new y("INVALID_ARGS","is requires predicate: visible|hidden|exists|editable|selected|text");if("text"===t.predicate&&!t.expectedText)throw new y("INVALID_ARGS","is text requires expected text value");let n=await nd(e,t,{updateSession:!0}),a=x(t.selector);if("exists"===t.predicate){let r=L(n.snapshot.nodes,a,{platform:e.backend.platform});if(!r)throw new y("COMMAND_FAILED",U(a,[],{unique:!1}));return{predicate:t.predicate,pass:!0,selector:r.selector.raw,matches:r.matches,selectorChain:a.selectors.map(e=>e.raw)}}let r=$(n.snapshot.nodes,a,{platform:e.backend.platform,requireRect:!1,requireUnique:!0,disambiguateAmbiguous:!1});if(!r)throw new y("COMMAND_FAILED",U(a,[],{unique:!0}));let i=function(e){let{predicate:t,node:n,nodes:a,expectedText:r,platform:i}=e,o=A(n),s=N(n,i),l=!0===n.selected,d="text"===t?S(n):function(e,t){if(!0===e.hittable)return!0;if(ns(e.rect))return e9(e,t);if(e.rect)return!1;let n=function(e,t){let n=new Map(t.map(e=>[e.index,e])),a=e,r=new Set;for(;"number"==typeof a.parentIndex&&!r.has(a.index);){r.add(a.index);let e=n.get(a.parentIndex);if(!e)break;if(function(e){let t=F(e.type??"");return!(t.includes("application")||t.includes("window")||t.includes("scrollview")||t.includes("tableview")||t.includes("collectionview"))&&"table"!==t&&"list"!==t&&"listview"!==t&&(!0===e.hittable||ns(e.rect))}(e))return e;a=e}return null}(e,t);return!!n&&(!0===n.hittable||!!ns(n.rect)&&e9(n,t))}(n,a),u=!1;switch(t){case"visible":u=d;break;case"hidden":u=!d;break;case"editable":u=s;break;case"selected":u=l;break;case"text":u=o===(r??"")}let c="text"===t?`expected="${r??""}" actual="${o}"`:`actual=${JSON.stringify({visible:d,editable:s,selected:l})}`;return{pass:u,actualText:o,details:c}}({predicate:t.predicate,node:r.node,nodes:n.snapshot.nodes,expectedText:t.expectedText,platform:e.backend.platform});if(!i.pass)throw new y("COMMAND_FAILED",`is ${t.predicate} failed for selector ${r.selector.raw}: ${i.details}`);return{predicate:t.predicate,pass:!0,selector:r.selector.raw,..."text"===t.predicate?{text:i.actualText}:{},selectorChain:a.selectors.map(e=>e.raw)}},nm=async(e,t)=>await nh(e,{...t,predicate:"visible",selector:t.target.selector}),nw=async(e,t)=>await nh(e,{...t,predicate:"hidden",selector:t.target.selector}),ng=async(e,t)=>{if("sleep"===t.target.kind)return await na(e,t.target.durationMs),{kind:"sleep",waitedMs:t.target.durationMs};if("ref"===t.target.kind){let n=await nl(e,t.session),a=j(t.target.ref);if(!a)throw new y("INVALID_ARGS",`Invalid ref: ${t.target.ref}`);let r=V(n.snapshot.nodes,a),i=r?R(r,n.snapshot.nodes):void 0;if(!i)throw new y("COMMAND_FAILED",`Ref ${t.target.ref} not found or has no label`);return await nA(e,t,i,t.target.timeoutMs)}if("selector"===t.target.kind)return await nv(e,t,t.target.selector,t.target.timeoutMs);if(!t.target.text)throw new y("INVALID_ARGS","wait requires text");return await nA(e,t,t.target.text,t.target.timeoutMs)},ny=async(e,t)=>{let n=await ng(e,{...t,target:{kind:"text",text:t.text,timeoutMs:t.timeoutMs}});if("text"!==n.kind)throw new y("COMMAND_FAILED","waitForText returned non-text result");return n};async function nb(e,t,n){let a=t.timeoutMs??1e4,r=nn(e);for(;nn(e)-r<a;){if(eg((await nd(e,t,{updateSession:!0,scope:ne(n)?t.query:void 0})).snapshot.nodes,n,t.query,{requireRect:!1}).matches[0])return{kind:"found",found:!0,waitedMs:nn(e)-r};await na(e,300)}throw new y("COMMAND_FAILED","find wait timed out")}async function nv(e,t,n,a){let r=a??1e4,i=nn(e),o=x(n);for(;nn(e)-i<r;){let n=L((await nd(e,t,{updateSession:!0})).snapshot.nodes,o,{platform:e.backend.platform});if(n)return{kind:"selector",selector:n.selector.raw,waitedMs:nn(e)-i};await na(e,300)}throw new y("COMMAND_FAILED",`wait timed out for selector: ${n}`)}async function nA(e,t,n,a){let r=a??1e4,i=nn(e);for(;nn(e)-i<r;){if(e.backend.findText?(await e.backend.findText(nt(e,t),n)).found:await nI(e,t,n))return{kind:"text",text:n,waitedMs:nn(e)-i};await na(e,300)}throw new y("COMMAND_FAILED",`wait timed out for text: ${n}`)}async function nI(e,t,n){return!!C((await nd(e,t,{updateSession:!0})).snapshot.nodes,n)}async function nx(e,t,n,a){let r=await nd(e,{...t,session:n},{updateSession:!0}),i=x(a.selector),o=$(r.snapshot.nodes,i,{platform:e.backend.platform,requireRect:!1,requireUnique:!0,disambiguateAmbiguous:a.disambiguateAmbiguous});if(!o)throw new y("COMMAND_FAILED",U(i,[],{unique:!0}));return{capture:r,node:o.node,selector:o.selector.raw,ref:`@${o.node.ref}`}}function nS(e,t,n,a){if(!Number.isFinite(e)||!Number.isInteger(e)||e<n||e>a)throw new y("INVALID_ARGS",`${t} must be an integer between ${n} and ${a}`);return e}function nN(e){let t=n_(e);if(!t)return null;let n=B(t);return Number.isFinite(n.x)&&Number.isFinite(n.y)?n:null}function n_(e){if(!e)return null;let t=Number(e.x),n=Number(e.y),a=Number(e.width),r=Number(e.height);return Number.isFinite(t)&&Number.isFinite(n)&&Number.isFinite(a)&&Number.isFinite(r)&&!(a<0)&&!(r<0)?{x:t,y:n,width:a,height:r}:null}function nM(e,t){let n=function(e,t){let n=n_(t.rect);if(!n)return null;let a=t,r=new Set;for(;!r.has(a.ref);){r.add(a.ref);let t=e.filter(e=>{if(e.parentIndex!==a.index||!e.hittable)return!1;let t=n_(e.rect);return!!t&&nk(t,n)});if(1!==t.length)break;a=t[0]}return a===t?null:a}(e,t);if(n?.rect&&nN(n.rect))return n;let a=k(e,t);return a?.rect&&nN(a.rect)?!function(e,t,n){var a,r,i,o;let s,l,d,u=n_(e.rect),c=n_(t.rect);if(!u||!c)return!1;let p=function(e,t){let n=B(t),a=e.filter(e=>{let t=(e.type??"").toLowerCase();return t.includes("application")||t.includes("window")}).map(e=>n_(e.rect)).filter(e=>null!==e);if(0===a.length)return null;let r=a.filter(e=>e3(e,n.x,n.y));return e4(r.length>0?r:a)}(n,u);return!!p&&(a=c,r=p,s=(i=a,o=r,Math.max(0,Math.min(i.x+i.width,o.x+o.width)-Math.max(i.x,o.x))*Math.max(0,Math.min(i.y+i.height,o.y+o.height)-Math.max(i.y,o.y))),l=a.width*a.height,d=r.width*r.height,!(s<=0)&&!(l<=0)&&!(d<=0)&&!!(s/d>=.9)&&!!(s/l>=.8))&&!nk(u,c)}(t,a,e)?a:t:t}function nk(e,t){return .5>=Math.abs(e.x-t.x)&&.5>=Math.abs(e.y-t.y)&&.5>=Math.abs(e.width-t.width)&&.5>=Math.abs(e.height-t.height)}async function nD(e,t,n){if(await nO(e,t,n.action),"point"===t.target.kind)return{kind:"point",point:{x:t.target.x,y:t.target.y}};if("ref"===t.target.kind){let a=await nR(e,t,t.target),r=a.resolved,i=n.promoteToHittableAncestor?nM(a.snapshot.nodes,r.node):r.node;return function(e,t,n,a){let r=e.rect?e7(e,t):null;if(!(!e.rect||!r||e9(e,t)))throw new y("COMMAND_FAILED",`Ref ${n} is off-screen and not safe to ${a}`,{reason:"offscreen_ref",ref:j(n),rect:e.rect,viewport:r,hint:`Use scroll with the direction from the off-screen summary, take a fresh snapshot, then retry ${a} with the new ref or a selector.`})}(i,a.snapshot.nodes,t.target.ref,n.action),{kind:"ref",point:nT(i,`Ref ${t.target.ref} not found or has invalid bounds`),target:{kind:"ref",ref:`@${r.ref}`},node:i,selectorChain:D(i,e.backend.platform,{action:"fill"===n.action?"fill":"click"}),refLabel:R(i,a.snapshot.nodes)}}let a=await nE(e,t,n.requireInteractive),r=x(t.target.selector),i=$(a.snapshot.nodes,r,{platform:e.backend.platform,requireRect:!0,requireUnique:!0,disambiguateAmbiguous:!0});if(!i||!i.node.rect)throw new y("COMMAND_FAILED",U(r,i?.diagnostics??[],{unique:!0}));let o=n.promoteToHittableAncestor?nM(a.snapshot.nodes,i.node):i.node;return{kind:"selector",point:nT(o,`Selector ${i.selector.raw} resolved to invalid bounds`),target:{kind:"selector",selector:i.selector.raw},node:o,selectorChain:D(o,e.backend.platform,{action:"fill"===n.action?"fill":"click"}),refLabel:R(o,a.snapshot.nodes)}}async function nE(e,t,n){if(!e.backend.captureSnapshot)throw new y("UNSUPPORTED_OPERATION","snapshot is not supported by this backend");let a=t.session??"default",r=await e.sessions.get(a);if(!r)throw new y("SESSION_NOT_FOUND","No active session. Run open first.");let i=await e.backend.captureSnapshot(nt(e,t),{interactiveOnly:n,compact:n}),o=i.snapshot??{nodes:i.nodes??[],truncated:i.truncated,backend:i.backend,createdAt:nn(e)};return await e.sessions.set({...r,snapshot:o}),{snapshot:o}}async function nO(e,t,n){if("macos"!==e.backend.platform)return;let a=await nC(e,t);if(("desktop"===a||"menubar"===a)&&("menubar"!==a||"click"!==n&&"press"!==n))throw new y("UNSUPPORTED_OPERATION",`${n} is not supported on macOS ${a} sessions yet. Open an app session to act, or use the ${a} surface to inspect.`)}async function nC(e,t){let n=await e.sessions.get(t.session??"default");return n?.metadata?.surface}async function nR(e,t,n){let a=t.session??"default",r=await e.sessions.get(a);if(!r)throw new y("SESSION_NOT_FOUND","No active session. Run open first.");if(!r.snapshot)throw new y("INVALID_ARGS","No snapshot in session. Run snapshot first.");let i=n.fallbackLabel??"",o=nP(r.snapshot.nodes,n.ref,{fallbackLabel:i,requireRect:!0});if(o)return{snapshot:r.snapshot,resolved:o};let s=await nE(e,t,!0),l=nP(s.snapshot.nodes,n.ref,{fallbackLabel:i,requireRect:!0});if(!l)throw new y("COMMAND_FAILED",`Ref ${n.ref} not found or has no bounds`);return{...s,resolved:l}}function nP(e,t,n){let a=j(t);if(!a)throw new y("INVALID_ARGS",`Invalid ref: ${t}`);let r=V(e,a);if(nL(r,n.requireRect))return{ref:a,node:r};let i=n.fallbackLabel.length>0?C(e,n.fallbackLabel):null;return nL(i,n.requireRect)?{ref:a,node:i}:null}function nT(e,t){if(!e.rect)throw new y("COMMAND_FAILED",t);let n=B(e.rect);if(!Number.isFinite(n.x)||!Number.isFinite(n.y))throw new y("COMMAND_FAILED",t);return n}function nL(e,t){if(!e)return!1;if(!t)return!0;if(!e.rect)return!1;let{x:n,y:a,width:r,height:i}=e.rect;if(!Number.isFinite(Number(n))||!Number.isFinite(Number(a))||!Number.isFinite(Number(r))||!Number.isFinite(Number(i))||0>Number(r)||0>Number(i))return!1;let o=B(e.rect);return Number.isFinite(o.x)&&Number.isFinite(o.y)}async function n$(e,t){let n=t.target??{kind:"viewport"};return"viewport"===n.kind?(await nO(e,t,"scroll"),{kind:"viewport"}):await nD(e,{...t,target:n},{action:"scroll",requireInteractive:!1,promoteToHittableAncestor:!1})}async function nF(e,t){if(t.from){var n;if("x"in(n=t.from)&&"y"in n)return await nO(e,t,"swipe"),{point:nG(t.from,"from")};let a=await nD(e,{...t,target:t.from},{action:"swipe",requireInteractive:!1,promoteToHittableAncestor:!1});return{point:a.point,target:a}}if(!t.direction)throw new y("INVALID_ARGS","swipe requires from+to or a direction");return await nO(e,t,"swipe"),{point:B(function(e){let t=e.filter(t=>e9(t,e)).map(e=>e.rect).filter(nB),n=t.length>0?t:e.map(e=>e.rect).filter(nB);if(0===n.length)throw new y("COMMAND_FAILED","Cannot infer viewport for directional swipe");let a=Math.min(...n.map(e=>e.x)),r=Math.min(...n.map(e=>e.y));return{x:a,y:r,width:Math.max(...n.map(e=>e.x+e.width))-a,height:Math.max(...n.map(e=>e.y+e.height))-r}}((await nE(e,t,!1)).snapshot.nodes)),target:{kind:"viewport"}}}function nU(e,t){switch(e){case"up":case"down":case"left":case"right":return e;default:throw new y("INVALID_ARGS",`${t} must be up, down, left, or right`)}}function nG(e,t){let n=Number(e.x),a=Number(e.y);if(!Number.isFinite(n)||!Number.isFinite(a))throw new y("INVALID_ARGS",`${t} point requires finite x and y`);return{x:n,y:a}}function nV(e,t){if(!Number.isFinite(e)||e<=0)throw new y("INVALID_ARGS",`${t} must be a positive number`);return e}function nB(e){return!!(e&&e.width>0&&e.height>0)}function nj(e){return e&&"object"==typeof e?e:void 0}async function nq(e,t,n){let a=await nD(e,t,{action:n,requireInteractive:!0,promoteToHittableAncestor:!0});if(!e.backend.tap)throw new y("UNSUPPORTED_OPERATION","tap is not supported by this backend");let r=nW(await e.backend.tap(nt(e,t),a.point,{button:t.button,count:t.count,intervalMs:t.intervalMs,holdMs:t.holdMs,jitterPx:t.jitterPx,doubleTap:t.doubleTap}));return{...a,...r?{backendResult:r}:{}}}function nW(e){return e&&"object"==typeof e?e:void 0}function nX(e){return!!(e&&"object"==typeof e)}function nH(e){return e&&"object"==typeof e?e:void 0}let nz=/^[A-Za-z0-9_.:-]{1,64}$/;function nY(e,t){if(void 0!==e)return nK(e,t)}function nK(e,t){let n=e?.trim();if(!n)throw new y("INVALID_ARGS",`${t} must be a non-empty string`);return n}async function nJ(e,t){if(!t||"object"!=typeof t)throw new y("INVALID_ARGS","apps.push requires an input");if("json"===t.kind)return nZ(t.payload,"apps.push JSON payload",8192),{backendInput:{kind:"json",payload:t.payload},inputKind:"json"};let n=await td(e,t,{usage:"apps.push",field:"input"});return{backendInput:{kind:"file",path:n.path},inputKind:"file",...n.cleanup?{cleanup:n.cleanup}:{}}}function nZ(e,t,n){if(function(e,t){if(!e||"object"!=typeof e||Array.isArray(e))throw new y("INVALID_ARGS",`${t} must be a JSON object`)}(e,t),Buffer.byteLength(function(e,t){try{let n=JSON.stringify(e);if("string"!=typeof n)throw new y("INVALID_ARGS",`${t} must be JSON-serializable`);return n}catch{throw new y("INVALID_ARGS",`${t} must be JSON-serializable`)}}(e,t),"utf8")>n)throw new y("INVALID_ARGS",`${t} exceeds ${n} bytes`)}function nQ(e,t){return{session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata}}function n0(e){return e&&"object"==typeof e?e:void 0}async function n1(e,t,n){let a="reinstall"===n?"reinstallApp":"installApp",r=e.backend[a];if(!r)throw new y("UNSUPPORTED_OPERATION",`admin.${n} is not supported by this backend`);let i="app"in t&&void 0!==t.app?n8(t.app,"app"):void 0;if("installFromSource"!==n&&!i)throw new y("INVALID_ARGS",`admin.${n} requires app`);let o=nt(e,t),s=await n2(e,o,t.source);try{var l,d,u,c,p;let t,a,f,h,m,w,g,y,b=await r.call(e.backend,o,{...i?{app:i}:{},source:s.source});return l=n,d=i,u=s.source,c=b,t=n9(c),a=n6(c,"appName"),f=n6(c,"appId"),h=n6(c,"bundleId"),m=n6(c,"packageName"),w=n6(c,"launchTarget"),g=n6(c,"installablePath"),y=n6(c,"archivePath"),{kind:"reinstall"===l?"appReinstalled":"installFromSource"===l?"appInstalledFromSource":"appInstalled",...d?{app:d}:{},source:u,...f?{appId:f}:{},...a?{appName:a}:{},...h?{bundleId:h}:{},...m?{packageName:m}:{},...w?{launchTarget:w}:{},...g?{installablePath:g}:{},...y?{archivePath:y}:{},...t?{backendResult:t}:{},...ei(`${"reinstall"===l?"Reinstalled":"Installed"}: ${a??w??d??(p=u,"path"===p.kind?p.path:"uploadedArtifact"===p.kind?p.id:p.url)}`)}}finally{await s.cleanup?.()}}async function n2(e,t,n){let a=n4(n),r=await n3(e,a);try{let n=e.backend.resolveInstallSource?await e.backend.resolveInstallSource(t,r.source):r.source;return{source:n4(n),...r.cleanup?{cleanup:r.cleanup}:{}}}catch(e){if(r.cleanup)try{await r.cleanup()}catch{}throw e}}async function n3(e,t){if("url"===t.kind)return{source:t};let n=await td(e,t,{usage:"admin.install",field:"source"});return{source:{kind:"path",path:n.path},...n.cleanup?{cleanup:n.cleanup}:{}}}function n4(e){if(!e||"object"!=typeof e)throw new y("INVALID_ARGS","install source is required");if("path"===e.kind)return{kind:"path",path:n8(e.path,"source.path")};if("uploadedArtifact"===e.kind)return{kind:"uploadedArtifact",id:n8(e.id,"source.id")};if("url"===e.kind){let t=n8(e.url,"source.url");return function(e){let t;try{t=new URL(e)}catch{throw new y("INVALID_ARGS",`Invalid install source URL: ${e}`)}if("http:"!==t.protocol&&"https:"!==t.protocol)throw new y("INVALID_ARGS","Install source URL must use http or https")}(t),{kind:"url",url:t}}throw new y("INVALID_ARGS","install source kind must be path, uploadedArtifact, or url")}function n5(e,t){if(void 0!==e)return n8(e,t)}function n8(e,t){let n=e?.trim();if(!n)throw new y("INVALID_ARGS",`${t} must be a non-empty string`);return n}function n6(e,t){let n=e[t];return"string"==typeof n&&n.length>0?n:void 0}function n9(e){return e&&"object"==typeof e?e:void 0}function n7(e,t){if("start"===e||"stop"===e)return e;throw new y("INVALID_ARGS",`${t} action must be start or stop`)}function ae(e,t,n,a){return{kind:"start"===e?a.startKind:a.stopKind,action:e,...n?{artifact:n}:{},backendResult:t,...ei("start"===e?a.startMessage:a.stopMessage)}}let at=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i,an=/\b[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\b/g;function aa(e){var t,n;let a=!1,r=e;return{value:(t=r=(r=(r=(r=(r=r.replaceAll(/(authorization|token|secret|password|passwd|api[-_]?key)=([^&\s]+)/gi,(e,t)=>(a=!0,`${String(t)}=[REDACTED]`))).replaceAll(/("(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)"\s*:\s*")([^"]*)(")/gi,(e,t,n,r)=>(a=!0,`${String(t)}[REDACTED]${String(r)}`))).replaceAll(/\b(Bearer\s+)([^\s",;]+)/gi,(e,t)=>(a=!0,`${String(t)}[REDACTED]`))).replaceAll(/((?:authorization|cookie|token|secret|password|passwd|api[-_]?key)\s*[:=]\s*)([^\s,;&]+)/gi,(e,t)=>(a=!0,`${String(t)}[REDACTED]`))).replaceAll(an,()=>(a=!0,"[REDACTED]")),n=()=>{a=!0},r=/(https?:\/\/|token|secret|password|authorization|cookie|api[-_]?key)/i.test(t)?t.replaceAll(/https?:\/\/[^\s"'<>)]+/gi,e=>{let t=ar(e);return t?(t.redacted&&n(),t.value):e}):t),redacted:a}}function ar(e){try{let t=new URL(e),n=function(e){let t=!1;for(let n of Array.from(e.searchParams.keys()))at.test(n)&&(e.searchParams.set(n,"[REDACTED]"),t=!0);return t}(t);return(t.username||t.password)&&(t.username="REDACTED",t.password="REDACTED",n=!0),{value:t.toString(),redacted:n}}catch{return}}let ai=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i;function ao(e){if(!e)return{redacted:!1};let t=!1,n={};for(let[a,r]of Object.entries(e))if(ai.test(a))n[a]="[REDACTED]",t=!0;else{let e=au(r,2048);n[a]=e.value??"",t||=e.redacted}return{value:n,redacted:t}}function as(e){return void 0===e?{redacted:!1}:function(e){try{let t=JSON.parse(e),n=ad(t,aa);return ac(JSON.stringify(n.value),2048,n.redacted)}catch{return}}(e)??au(e,2048)}function al(e){return ad(e,e=>au(e,2048))}function ad(e,t){if(void 0===e)return{redacted:!1};if("string"==typeof e)return t(e);if(!e||"object"!=typeof e)return{value:e,redacted:!1};if(Array.isArray(e)){let n=!1;return{value:e.map(e=>{let a=ad(e,t);return n||=a.redacted,a.value}),redacted:n}}let n=!1,a={};for(let[r,i]of Object.entries(e)){if(ai.test(r)){a[r]="[REDACTED]",n=!0;continue}let e=ad(i,t);a[r]=e.value,n||=e.redacted}return{value:a,redacted:n}}function au(e,t){if(void 0===e)return{redacted:!1};let n=aa(e);return ac(n.value,t,n.redacted)}function ac(e,t,n){if(void 0===e)return{redacted:n};let a=e;return a.length>t&&(a=`${a.slice(0,t)}...[truncated]`,n=!0),{value:a,redacted:n}}async function ap(e,t){let n=nt(e,t),a=t.session?await e.sessions.get(t.session):void 0;return{...n,...t.appId??a?.appId?{appId:t.appId??a?.appId}:{},...t.appBundleId??a?.appBundleId?{appBundleId:t.appBundleId??a?.appBundleId}:{}}}function af(e,t,n,a){return{...ah(e),...void 0!==e.cursor?{cursor:aw(e.cursor,"cursor")}:{},limit:void 0===e.limit?t:nS(e.limit,a,1,n)}}function ah(e){return{...void 0!==e.since?{since:aw(e.since,"since")}:{},...void 0!==e.until?{until:aw(e.until,"until")}:{}}}function am(e,t,n=50){if(!Array.isArray(e))throw new y("INVALID_ARGS",`${t} must be an array of strings`);if(e.length>n)throw new y("INVALID_ARGS",`${t} must contain at most ${n} entries`);return e.map((e,n)=>aw(e,`${t}[${n}]`))}function aw(e,t){let n=e.trim();if(!n)throw new y("INVALID_ARGS",`${t} must be a non-empty string`);return n}let ag=async(e,t)=>{let n;if(!e.backend.captureScreenshot)throw new y("UNSUPPORTED_OPERATION","screenshot is not supported by this backend");let a=await tu(e,t.out,{field:"path",ext:".png"});try{await e.backend.captureScreenshot({session:t.session,requestId:t.requestId,appId:t.appId,appBundleId:t.appBundleId,signal:t.signal??e.signal,metadata:t.metadata},a.path,{fullscreen:t.fullscreen,overlayRefs:t.overlayRefs,surface:t.surface}),void 0!==t.maxSize&&await tl(a.path,t.maxSize),n=await a.publish()}catch(e){throw await a.cleanup?.(),e}return{path:a.path,...n?{artifacts:[n]}:{},...ei(`Saved screenshot: ${a.path}`)}},ay=async(e,t)=>{let n,a,r;if(!t.baseline)throw new y("INVALID_ARGS","diff screenshot requires a baseline image");let i=function(e){if(null==e||""===e)return .1;let t=Number(e);if(Number.isNaN(t)||t<0||t>1)throw new y("INVALID_ARGS","--threshold must be a number between 0 and 1");return t}(t.threshold),o=t.current??{kind:"live"};if(t.overlayRefs&&!t8(o))throw new y("INVALID_ARGS","diff screenshot <current.png> cannot use --overlay-refs because saved-image comparisons have no live accessibility refs");let s=await td(e,t.baseline,{usage:"diff screenshot baseline",field:"baseline"}),l=[];try{let d;d=t8(o)?(a=await t0(e,t)).path:(n=await td(e,o,{usage:"diff screenshot current",field:"current"})).path,r=t.out?await tu(e,t.out,{field:"diffPath",ext:".png"}):void 0;let u=await tX(s.path,d,{threshold:i,outputPath:r?.path,maxPixels:e.policy.maxImagePixels});t8(o)&&(u=await t1(e,t,r?.path,u,l));let c=u.diffPath?await r?.publish():void 0;return c&&l.push(c),u.diffPath||await r?.cleanup?.(),{...u,...l.length>0?{artifacts:l}:{}}}catch(e){throw await r?.cleanup?.(),e}finally{await s.cleanup?.(),await n?.cleanup?.(),await a?.cleanup?.()}},ab=async(e,t)=>{var n;let a,r,i=await nr(e,t);return await e.sessions.set(ni(t.session,i)),{nodes:i.snapshot.nodes,truncated:i.snapshot.truncated??!1,visibility:function(e){var t;let{nodes:n,backend:a,snapshotRaw:r}=e;if(r||"macos-helper"===(t=a)||"linux-atspi"===t)return{partial:!1,visibleNodeCount:n.length,totalNodeCount:n.length,reasons:[]};let i=e8(n),o=new Set;return i.hiddenCount>0&&o.add("offscreen-nodes"),i.nodes.some(e=>e.hiddenContentAbove)&&o.add("scroll-hidden-above"),i.nodes.some(e=>e.hiddenContentBelow)&&o.add("scroll-hidden-below"),{partial:o.size>0,visibleNodeCount:i.nodes.length,totalNodeCount:n.length,reasons:[...o]}}({nodes:i.snapshot.nodes,backend:i.snapshot.backend,snapshotRaw:t.raw}),...i.result.androidSnapshot?{androidSnapshot:i.result.androidSnapshot}:{},...i.warnings.length>0?{warnings:i.warnings}:{},...(a=(n=i).result.appName??n.session?.appName,r=n.result.appBundleId??n.session?.appBundleId,{...a||r?{appName:a??r}:{},...r?{appBundleId:r}:{}})}},av=async(e,t)=>{let n=await nr(e,t),a=!0===t.interactiveOnly,r=n.session?.snapshot,i=ni(t.session,n);if(!r){let t=function(e,t={}){return t9(e,t).length}(n.snapshot.nodes,{flatten:a});return await e.sessions.set(i),{mode:"snapshot",baselineInitialized:!0,summary:{additions:0,removals:0,unchanged:t},lines:[],...n.warnings.length>0?{warnings:n.warnings}:{}}}let o=function(e,t,n={}){let a=function(e,t){let n=e.length,a=t.length,r=n+a,i=new Map,o=[];i.set(1,0);for(let s=0;s<=r;s+=1){o.push(new Map(i));for(let r=-s;r<=s;r+=2){let l=r===-s||r!==s&&t7(i,r-1)<t7(i,r+1)?t7(i,r+1):t7(i,r-1)+1,d=l-r;for(;l<n&&d<a&&e[l].comparable===t[d].comparable;)l+=1,d+=1;if(i.set(r,l),l>=n&&d>=a)return function(e,t,n,a,r){let i=[],o=a,s=r;for(let a=e.length-1;a>=0;a-=1){let r=e[a],l=o-s,d=l===-a||l!==a&&t7(r,l-1)<t7(r,l+1)?l+1:l-1,u=t7(r,d),c=u-d;for(;o>u&&s>c;)i.push({kind:"unchanged",text:n[s-1].text}),o-=1,s-=1;if(0===a)break;o===u?(i.push({kind:"added",text:n[c].text}),s=c):(i.push({kind:"removed",text:t[u].text}),o=u)}return i.reverse(),i}(o,e,t,n,a)}}return[]}(t9(e,n),t9(t,n)),r={additions:0,removals:0,unchanged:0};for(let e of a)"added"===e.kind&&(r.additions+=1),"removed"===e.kind&&(r.removals+=1),"unchanged"===e.kind&&(r.unchanged+=1);return{summary:r,lines:a}}(r.nodes,n.snapshot.nodes,{flatten:a});return await e.sessions.set(i),{mode:"snapshot",baselineInitialized:!1,summary:o.summary,lines:o.lines,...n.warnings.length>0?{warnings:n.warnings}:{}}},aA=async(e,t)=>{let n=t.locator??"any";if(!t.query)throw new y("INVALID_ARGS","find requires a value");if("wait"===t.action)return await nb(e,t,n);let a=await nd(e,t,{updateSession:!0,scope:ne(n)?t.query:void 0}),r=eg(a.snapshot.nodes,n,t.query,{requireRect:!1}).matches[0];if(!r)throw new y("COMMAND_FAILED","find did not match any element");if("exists"===t.action)return{kind:"found",found:!0};let i=`@${r.ref}`;return"get_attrs"===t.action?{kind:"attrs",ref:i,node:r}:{kind:"text",ref:i,text:await nu(e,a,r),node:r}},aI=nc,ax=np,aS=nf,aN=nh,a_=nm,aM=nw,ak=ng,aD=ny,aE=async(e,t)=>await nq(e,t,"click"),aO=async(e,t)=>await nq(e,t,"press"),aC=async(e,t)=>{var n;if(!t.text)throw new y("INVALID_ARGS","fill requires text");let a=await nD(e,t,{action:"fill",requireInteractive:!0,promoteToHittableAncestor:!1});if(!e.backend.fill)throw new y("UNSUPPORTED_OPERATION","fill is not supported by this backend");let r=nW(await e.backend.fill(nt(e,t),a.point,t.text,{delayMs:t.delayMs})),i="node"in a?a.node.type??"":"",o=i&&!G(i,e.backend.platform)?`fill target ${n=a,n.target?.kind==="ref"?n.target.ref:n.target?.kind==="selector"?n.target.selector:"point"} resolved to "${i}", attempting fill anyway.`:void 0;return{...a,text:t.text,...o?{warning:o}:{},...r?{backendResult:r}:{}}},aR=async(e,t)=>{let n=t.text;if(!n)throw new y("INVALID_ARGS","type requires text");let a=function(e){let t=e.trim().split(/\s+/,1)[0];if(!t||!t.startsWith("@")||t.length<3)return null;let n=t.slice(1);return/^[A-Za-z_-]*\d[\w-]*$/i.test(n)||/^(?:ref|node|element|el)[\w-]*$/i.test(n)?t:null}(n);if(a)throw new y("INVALID_ARGS",`type does not accept a target ref like "${a}"`,{hint:`Use fill ${a} "text" to target that field, or press ${a} then type "text" to append.`});if(!e.backend.typeText)throw new y("UNSUPPORTED_OPERATION","type is not supported by this backend");let r=nS(t.delayMs??0,"delay-ms",0,1e4),i=nW(await e.backend.typeText(nt(e,t),n,{delayMs:r}));return{kind:"text",text:n,delayMs:r,...i?{backendResult:i}:{},...ei(`Typed ${Array.from(n).length} chars`)}},aP=async(e,t)=>{let n=await nD(e,t,{action:"focus",requireInteractive:!0,promoteToHittableAncestor:!1});if(!e.backend.focus)throw new y("UNSUPPORTED_OPERATION","focus is not supported by this backend");let a=nj(await e.backend.focus(nt(e,t),n.point));return{...n,...a?{backendResult:a}:{},...ei(`Focused (${n.point.x}, ${n.point.y})`)}},aT=async(e,t)=>{let n=await nD(e,t,{action:"longPress",requireInteractive:!0,promoteToHittableAncestor:!0});if(!e.backend.longPress)throw new y("UNSUPPORTED_OPERATION","longPress is not supported by this backend");let a=void 0===t.durationMs?void 0:nS(t.durationMs,"durationMs",0,12e4),r=nj(await e.backend.longPress(nt(e,t),n.point,{durationMs:a}));return{...n,...void 0!==a?{durationMs:a}:{},...r?{backendResult:r}:{},...ei(`Long pressed (${n.point.x}, ${n.point.y})`)}},aL=async(e,t)=>{if(!e.backend.swipe)throw new y("UNSUPPORTED_OPERATION","swipe is not supported by this backend");let n=await nF(e,t),a=function(e,t){if(t.to)return{point:nG(t.to,"to")};let n=nU(t.direction,"swipe direction"),a=nV(t.distance??200,"swipe distance");switch(n){case"up":return{point:{x:e.x,y:e.y-a},direction:n,distance:a};case"down":return{point:{x:e.x,y:e.y+a},direction:n,distance:a};case"left":return{point:{x:e.x-a,y:e.y},direction:n,distance:a};case"right":return{point:{x:e.x+a,y:e.y},direction:n,distance:a}}}(n.point,t),r=void 0===t.durationMs?void 0:nS(t.durationMs,"durationMs",16,1e4),i=nj(await e.backend.swipe(nt(e,t),n.point,a.point,{durationMs:r}));return{kind:"swipe",from:n.point,to:a.point,...a.direction?{direction:a.direction}:{},...void 0!==a.distance?{distance:a.distance}:{},...void 0!==r?{durationMs:r}:{},...n.target?{fromTarget:n.target}:{},...i?{backendResult:i}:{},...ei("Swiped")}},a$=async(e,t)=>{var n,a;if(!e.backend.scroll)throw new y("UNSUPPORTED_OPERATION","scroll is not supported by this backend");let r=nU(t.direction,"scroll direction"),i=(n=t.amount,a="scroll amount",void 0===n?void 0:nV(n,a)),o=function(e,t){if(void 0!==e){if(!Number.isFinite(e)||!Number.isInteger(e)||e<=0)throw new y("INVALID_ARGS",`${t} must be a positive integer`);return e}}(t.pixels,"scroll pixels");if(void 0!==i&&void 0!==o)throw new y("INVALID_ARGS","scroll accepts either amount or pixels, not both");let s=await n$(e,t),l="viewport"===s.kind?{kind:"viewport"}:{kind:"point",point:s.point},d=nj(await e.backend.scroll(nt(e,t),l,{direction:r,...void 0!==i?{amount:i}:{},...void 0!==o?{pixels:o}:{}}));return{...s,direction:r,...void 0!==i?{amount:i}:{},...void 0!==o?{pixels:o}:{},...d?{backendResult:d}:{},...ei(void 0!==o?`Scrolled ${r} by ${o}px`:void 0!==i?`Scrolled ${r} by ${i}`:`Scrolled ${r}`)}},aF=async(e,t)=>{if(!e.backend.pinch)throw new y("UNSUPPORTED_OPERATION","pinch is not supported by this backend");await nO(e,t,"pinch");let n=nV(t.scale,"pinch scale"),a=t.center?await nD(e,{...t,target:t.center},{action:"pinch",requireInteractive:!1,promoteToHittableAncestor:!1}):void 0,r=nj(await e.backend.pinch(nt(e,t),{scale:n,...a?{center:a.point}:{}}));return{kind:"pinch",scale:n,...a?{center:a.point,centerTarget:a}:{},...r?{backendResult:r}:{},...ei(`Pinched to scale ${n}`)}},aU=async(e,t={})=>{if(!e.backend.pressBack)throw new y("UNSUPPORTED_OPERATION","system.back is not supported by this backend");let n=t.mode??"in-app";if("in-app"!==n&&"system"!==n)throw new y("INVALID_ARGS","system.back mode must be in-app or system");let a=nH(await e.backend.pressBack(nt(e,t),{mode:n}));return{kind:"systemBack",mode:n,...a?{backendResult:a}:{},...ei("Back")}},aG=async(e,t={})=>{if(!e.backend.pressHome)throw new y("UNSUPPORTED_OPERATION","system.home is not supported by this backend");let n=nH(await e.backend.pressHome(nt(e,t)));return{kind:"systemHome",...n?{backendResult:n}:{},...ei("Home")}},aV=async(e,t)=>{if(!e.backend.rotate)throw new y("UNSUPPORTED_OPERATION","system.rotate is not supported by this backend");let n=function(e){switch(e){case"portrait":case"portrait-upside-down":case"landscape-left":case"landscape-right":return e;default:throw new y("INVALID_ARGS","system.rotate orientation must be portrait, portrait-upside-down, landscape-left, or landscape-right")}}(t.orientation),a=nH(await e.backend.rotate(nt(e,t),n));return{kind:"systemRotated",orientation:n,...a?{backendResult:a}:{},...ei(`Rotated to ${n}`)}},aB=async(e,t={})=>{if(!e.backend.setKeyboard)throw new y("UNSUPPORTED_OPERATION","system.keyboard is not supported by this backend");let n=t.action??"status";if("status"!==n&&"get"!==n&&"dismiss"!==n)throw new y("INVALID_ARGS","system.keyboard action must be status, get, or dismiss");let a=await e.backend.setKeyboard(nt(e,t),{action:n}),r=nH(a);if("dismiss"===n){let e=nX(a)?a.dismissed:void 0;return{kind:"keyboardDismissed",action:n,state:nX(a)?a:{},...r?{backendResult:r}:{},...ei(!1===e?"Keyboard already hidden":"Keyboard dismissed")}}return{kind:"keyboardState",action:n,state:nX(a)?a:{},...r?{backendResult:r}:{}}},aj=async(e,t)=>{if("read"===t.action){if(!e.backend.getClipboard)throw new y("UNSUPPORTED_OPERATION","system.clipboard read is not supported by this backend");let n=await e.backend.getClipboard(nt(e,t));return{kind:"clipboardText",action:"read",text:"string"==typeof n?n:n.text}}if("write"!==t.action)throw new y("INVALID_ARGS","system.clipboard action must be read or write");if(!e.backend.setClipboard)throw new y("UNSUPPORTED_OPERATION","system.clipboard write is not supported by this backend");if("string"!=typeof t.text)throw new y("INVALID_ARGS","system.clipboard write requires text");let n=nH(await e.backend.setClipboard(nt(e,t),t.text));return{kind:"clipboardUpdated",action:"write",textLength:Array.from(t.text).length,...n?{backendResult:n}:{},...ei("Clipboard updated")}},aq=async(e,t={})=>{if(!e.backend.openSettings)throw new y("UNSUPPORTED_OPERATION","system.settings is not supported by this backend");let n=function(e,t){if(void 0===e)return;let n=e.trim();if(!n)throw new y("INVALID_ARGS",`${t} must be a non-empty string`);return n}(t.target,"target"),a=nH(await e.backend.openSettings(nt(e,t),n));return{kind:"settingsOpened",...n?{target:n}:{},...a?{backendResult:a}:{},...ei(n?`Opened settings: ${n}`:"Opened settings")}},aW=async(e,t={})=>{if(!e.backend.handleAlert)throw new y("UNSUPPORTED_OPERATION","system.alert is not supported by this backend");let n=t.action??"get";if("get"!==n&&"accept"!==n&&"dismiss"!==n&&"wait"!==n)throw new y("INVALID_ARGS","system.alert action must be get, accept, dismiss, or wait");let a=void 0===t.timeoutMs?void 0:nS(t.timeoutMs,"timeoutMs",0,12e4),r=await e.backend.handleAlert(nt(e,t),n,{timeoutMs:a});var i=n,o=r;if("get"===i){if("alertStatus"!==o.kind)throw new y("COMMAND_FAILED","system.alert get returned an invalid backend result");return{kind:"alertStatus",action:i,alert:o.alert}}if("wait"===i){if("alertWait"!==o.kind)throw new y("COMMAND_FAILED","system.alert wait returned an invalid backend result");return{kind:"alertWait",action:i,alert:o.alert,...void 0!==o.waitedMs?{waitedMs:o.waitedMs}:{},...void 0!==o.timedOut?{timedOut:o.timedOut}:{},...ei(o.alert?"Alert visible":"Alert wait timed out")}}if("alertHandled"!==o.kind)throw new y("COMMAND_FAILED",`system.alert ${i} returned an invalid backend result`);return{kind:"alertHandled",action:i,handled:o.handled,...o.alert?{alert:o.alert}:{},...o.button?{button:o.button}:{},...ei(o.handled?`Alert ${i}ed`:"No alert handled")}},aX=async(e,t={})=>{if(!e.backend.openAppSwitcher)throw new y("UNSUPPORTED_OPERATION","system.appSwitcher is not supported by this backend");let n=nH(await e.backend.openAppSwitcher(nt(e,t)));return{kind:"appSwitcherOpened",...n?{backendResult:n}:{},...ei("Opened app switcher")}},aH=async(e,t)=>{var n;if(!e.backend.openApp)throw new y("UNSUPPORTED_OPERATION","apps.open is not supported by this backend");let a=function(e){var t;let n=nY(e.app,"app"),a=nY(e.appId,"appId"),r=nY(e.bundleId,"bundleId"),i=nY(e.packageName,"packageName"),o=nY(e.url,"url"),s=nY(e.activity,"activity"),l={...n?{app:n}:{},...a?{appId:a}:{},...r?{bundleId:r}:{},...i?{packageName:i}:{},...o?{url:o}:{},...s?{activity:s}:{}};if(!((t=l).app??t.appId??t.bundleId??t.packageName??t.url??t.activity))throw new y("INVALID_ARGS","apps.open requires app, appId, bundleId, packageName, url, or activity");return l}(t),r=n0(await e.backend.openApp(nQ(e,t),a,{relaunch:t.relaunch}));return{kind:"appOpened",target:a,relaunch:!0===t.relaunch,...r?{backendResult:r}:{},...ei(`Opened: ${(n=a).app??n.appId??n.bundleId??n.packageName??n.url??n.activity??"app"}`)}},az=async(e,t={})=>{if(!e.backend.closeApp)throw new y("UNSUPPORTED_OPERATION","apps.close is not supported by this backend");let n=nY(t.app,"app"),a=n0(await e.backend.closeApp(nQ(e,t),n));return{kind:"appClosed",...n?{app:n}:{},...a?{backendResult:a}:{},...ei(n?`Closed: ${n}`:"Closed app")}},aY=async(e,t={})=>{if(!e.backend.listApps)throw new y("UNSUPPORTED_OPERATION","apps.list is not supported by this backend");return{kind:"appsList",apps:await e.backend.listApps(nQ(e,t),t.filter??"all")}},aK=async(e,t)=>{if(!e.backend.getAppState)throw new y("UNSUPPORTED_OPERATION","apps.state is not supported by this backend");let n=nK(t.app,"app"),a=await e.backend.getAppState(nQ(e,t),n);return{kind:"appState",app:n,state:a}},aJ=async(e,t)=>{if(!e.backend.pushFile)throw new y("UNSUPPORTED_OPERATION","apps.push is not supported by this backend");let n=nK(t.app,"app"),a=await nJ(e,t.input);try{let r=await e.backend.pushFile(nQ(e,t),a.backendInput,n),i=n0(r);return{kind:"appPushed",app:n,inputKind:a.inputKind,...i?{backendResult:i}:{},...ei(`Pushed to ${n}`)}}finally{await a.cleanup?.()}},aZ=async(e,t)=>{var n,a;if(!e.backend.triggerAppEvent)throw new y("UNSUPPORTED_OPERATION","apps.triggerEvent is not supported by this backend");let r=function(e){let t=nK(e,"name");if(!nz.test(t))throw new y("INVALID_ARGS",`Invalid apps.triggerEvent name: ${t}`,{hint:"Use 1-64 chars: letters, numbers, underscore, dot, colon, or dash."});return t}(t.name);n=t.payload,a=`apps.triggerEvent payload for "${r}"`,void 0!==n&&nZ(n,a,8192);let i=n0(await e.backend.triggerAppEvent(nQ(e,t),{name:r,...t.payload?{payload:t.payload}:{}}));return{kind:"appEventTriggered",name:r,...t.payload?{payload:t.payload}:{},...i?{backendResult:i}:{},...ei(`Triggered app event: ${r}`)}},aQ=async(e,t={})=>{if(!e.backend.listDevices)throw new y("UNSUPPORTED_OPERATION","admin.devices is not supported by this backend");return{kind:"adminDevices",devices:await e.backend.listDevices(nt(e,t),t.filter)}},a0=async(e,t={})=>{if(!e.backend.bootDevice)throw new y("UNSUPPORTED_OPERATION","admin.boot is not supported by this backend");let n=function(e){if(!e)return;let t=n5(e.id,"target.id"),n=n5(e.name,"target.name"),a={...t?{id:t}:{},...n?{name:n}:{},...e.platform?{platform:e.platform}:{},...e.target?{target:e.target}:{},...void 0!==e.headless?{headless:e.headless}:{}};return Object.keys(a).length>0?a:void 0}(t.target),a=n9(await e.backend.bootDevice(nt(e,t),n));return{kind:"deviceBooted",...n?{target:n}:{},...a?{backendResult:a}:{},...ei("Booted device")}},a1=async(e,t)=>{if(!e.backend.ensureSimulator)throw new y("UNSUPPORTED_OPERATION","admin.ensureSimulator is not supported by this backend");let n=n8(t.device,"device");return{kind:"simulatorEnsured",...await e.backend.ensureSimulator(nt(e,t),{device:n,...t.runtime?{runtime:n8(t.runtime,"runtime")}:{},...void 0!==t.boot?{boot:t.boot}:{},...void 0!==t.reuseExisting?{reuseExisting:t.reuseExisting}:{}})}},a2=async(e,t)=>await n1(e,t,"install"),a3=async(e,t)=>await n1(e,t,"reinstall"),a4=async(e,t)=>await n1(e,t,"installFromSource"),a5=async(e,t)=>{let n=n7(t.action,"record"),a="start"===n?e.backend.startRecording:e.backend.stopRecording;if(!a)throw new y("UNSUPPORTED_OPERATION",`record ${n} is not supported by this backend`);let r=t.out?await tu(e,t.out,{field:"path",ext:".mp4"}):void 0;try{var i,o,s,l,d;let u,c,p=(i=t,o=r?.path,u=void 0===i.fps?void 0:nS(i.fps,"fps",1,60),c=void 0===i.quality?void 0:nS(i.quality,"quality",5,10),{...o?{outPath:o}:{},...void 0!==u?{fps:u}:{},...void 0!==c?{quality:c}:{},...void 0!==i.hideTouches?{showTouches:!0!==i.hideTouches}:{}}),f=await a.call(e.backend,nt(e,t),p),h=await r?.publish();return s=n,l=f,d=h,{..."string"==typeof l.path?{path:l.path}:{},..."string"==typeof l.telemetryPath?{telemetryPath:l.telemetryPath}:{},..."string"==typeof l.warning?{warning:l.warning}:{},...ae(s,l,d,{startKind:"recordingStarted",stopKind:"recordingStopped",startMessage:"Recording started",stopMessage:"Recording stopped"})}}catch(e){throw await r?.cleanup?.(),e}},a8=async(e,t)=>{let n=n7(t.action,"trace"),a="start"===n?e.backend.startTrace:e.backend.stopTrace;if(!a)throw new y("UNSUPPORTED_OPERATION",`trace ${n} is not supported by this backend`);let r=t.out?await tu(e,t.out,{field:"outPath",ext:".trace"}):void 0;try{var i,o,s;let l={...r?.path?{outPath:r.path}:{}},d=await a.call(e.backend,nt(e,t),l),u=await r?.publish();return i=n,o=d,s=u,{..."string"==typeof o.outPath?{outPath:o.outPath}:{},...ae(i,o,s,{startKind:"traceStarted",stopKind:"traceStopped",startMessage:"Trace started",stopMessage:"Trace stopped"})}}catch(e){throw await r?.cleanup?.(),e}},a6=async(e,t={})=>{var n,a;let r;if(!e.backend.readLogs)throw new y("UNSUPPORTED_OPERATION","diagnostics.logs is not supported by this backend");return r=!0===(n=await e.backend.readLogs(await ap(e,t),{...af(a=t,100,500,"logs limit"),...void 0!==a.levels?{levels:am(a.levels,"levels")}:{},...void 0!==a.search?{search:aw(a.search,"search")}:{},...void 0!==a.source?{source:aw(a.source,"source")}:{}})).redacted,{kind:"diagnosticsLogs",entries:n.entries.map(e=>{let t=au(e.message,4096),n=al(e.metadata);return r||=t.redacted||n.redacted,{...e.timestamp?{timestamp:e.timestamp}:{},...e.level?{level:e.level}:{},message:t.value??"",...e.source?{source:e.source}:{},...n.value?{metadata:n.value}:{}}}),...n.nextCursor?{nextCursor:n.nextCursor}:{},...n.timeWindow?{timeWindow:n.timeWindow}:{},...n.backend?{backend:n.backend}:{},redacted:r,...n.notes?{notes:n.notes}:{}}},a9=async(e,t={})=>{var n,a,r;let i;if(!e.backend.dumpNetwork)throw new y("UNSUPPORTED_OPERATION","diagnostics.network is not supported by this backend");let o={...af(r=t,25,200,"network limit"),include:function(e){if(void 0===e)return"summary";if("summary"===e||"headers"===e||"body"===e||"all"===e)return e;throw new y("INVALID_ARGS","network include must be summary, headers, body, or all")}(r.include)};return n=await e.backend.dumpNetwork(await ap(e,t),o),a=o.include??"summary",i=!0===n.redacted,{kind:"diagnosticsNetwork",entries:n.entries.map(e=>{var t;let n=e.url?ar(t=e.url)??au(t,2048):void 0,r="headers"===a||"all"===a?ao(e.requestHeaders):void 0,o="headers"===a||"all"===a?ao(e.responseHeaders):void 0,s="body"===a||"all"===a?as(e.requestBody):void 0,l="body"===a||"all"===a?as(e.responseBody):void 0,d=al(e.metadata);return i||=(n?.redacted??!1)||(r?.redacted??!1)||(o?.redacted??!1)||(s?.redacted??!1)||(l?.redacted??!1)||d.redacted,{...e.timestamp?{timestamp:e.timestamp}:{},...e.method?{method:e.method}:{},...n?{url:n.value}:{},...void 0!==e.status?{status:e.status}:{},...void 0!==e.durationMs?{durationMs:e.durationMs}:{},...r?.value?{requestHeaders:r.value}:{},...o?.value?{responseHeaders:o.value}:{},...s?.value!==void 0?{requestBody:s.value}:{},...l?.value!==void 0?{responseBody:l.value}:{},...d.value?{metadata:d.value}:{}}}),...n.nextCursor?{nextCursor:n.nextCursor}:{},...n.timeWindow?{timeWindow:n.timeWindow}:{},...n.backend?{backend:n.backend}:{},redacted:i,...n.notes?{notes:n.notes}:{}}},a7=async(e,t={})=>{var n,a;let r;if(!e.backend.measurePerf)throw new y("UNSUPPORTED_OPERATION","diagnostics.perf is not supported by this backend");return r=!0===(n=await e.backend.measurePerf(await ap(e,t),{...ah(a=t),...void 0!==a.sampleMs?{sampleMs:nS(a.sampleMs,"sampleMs",100,6e4)}:{},...void 0!==a.metrics?{metrics:am(a.metrics,"metrics",20)}:{}})).redacted,{kind:"diagnosticsPerf",metrics:n.metrics.map(e=>{let t=au(e.message,4096),n=al(e.metadata);return r||=t.redacted||n.redacted,{name:e.name,...void 0!==e.value?{value:e.value}:{},...e.unit?{unit:e.unit}:{},...e.status?{status:e.status}:{},...void 0!==t.value?{message:t.value}:{},...n.value?{metadata:n.value}:{}}}),...n.startedAt?{startedAt:n.startedAt}:{},...n.endedAt?{endedAt:n.endedAt}:{},...n.backend?{backend:n.backend}:{},redacted:r,...n.notes?{notes:n.notes}:{}}};function re(e){let t={backend:e.backend,artifacts:e.artifacts,sessions:e.sessions??function(e=[]){let t=new Map(e.map(e=>[e.name,rt(e)]));return{get:e=>rt(t.get(e)),set:e=>{t.set(e.name,rt(e))},delete:e=>{t.delete(e)},list:()=>Array.from(t.values(),e=>rt(e))}}(),policy:e.policy??function(e={}){return{allowLocalInputPaths:!1,allowLocalOutputPaths:!1,maxImagePixels:2e7,allowNamedBackendCapabilities:[],...e}}(),diagnostics:e.diagnostics,clock:e.clock,signal:e.signal};return{...t,capture:{screenshot:e=>ag(t,e),diffScreenshot:e=>ay(t,e),snapshot:e=>ab(t,e),diffSnapshot:e=>av(t,e)},selectors:{find:e=>aA(t,e),get:e=>aI(t,e),getText:(e,n={})=>ax(t,{...n,target:e}),getAttrs:(e,n={})=>aS(t,{...n,target:e}),is:e=>aN(t,e),isVisible:(e,n={})=>a_(t,{...n,target:e}),isHidden:(e,n={})=>aM(t,{...n,target:e}),wait:e=>ak(t,e),waitForText:(e,n={})=>aD(t,{...n,text:e})},interactions:{click:(e,n={})=>aE(t,{...n,target:e}),press:(e,n={})=>aO(t,{...n,target:e}),fill:(e,n,a={})=>aC(t,{...a,target:e,text:n}),typeText:(e,n={})=>aR(t,{...n,text:e}),focus:(e,n={})=>aP(t,{...n,target:e}),longPress:(e,n={})=>aT(t,{...n,target:e}),swipe:e=>aL(t,e),scroll:e=>a$(t,e),pinch:e=>aF(t,e)},system:{back:e=>aU(t,e),home:e=>aG(t,e),rotate:e=>aV(t,e),keyboard:e=>aB(t,e),clipboard:e=>aj(t,e),settings:e=>aq(t,e),alert:e=>aW(t,e),appSwitcher:e=>aX(t,e)},apps:{open:e=>aH(t,e),close:e=>az(t,e),list:e=>aY(t,e),state:e=>aK(t,e),push:e=>aJ(t,e),triggerEvent:e=>aZ(t,e)},admin:{devices:e=>aQ(t,e),boot:e=>a0(t,e),ensureSimulator:e=>a1(t,e),install:e=>a2(t,e),reinstall:e=>a3(t,e),installFromSource:e=>a4(t,e)},recording:{record:e=>a5(t,e),trace:e=>a8(t,e)},observability:{logs:e=>a6(t,e),network:e=>a9(t,e),perf:e=>a7(t,e)}}}function rt(e){if(e)return{...e,...e.snapshot?{snapshot:structuredClone(e.snapshot)}:{},...e.metadata?{metadata:function(e){try{return structuredClone(e)}catch{return{...e}}}(e.metadata)}:{}}}function rn(e={}){return{allowLocalInputPaths:!0,allowLocalOutputPaths:!0,maxImagePixels:2e7,allowNamedBackendCapabilities:[],...e}}function ra(e,t,n){return{ok:!1,error:{code:e,message:t,...n?{details:n}:{}}}}function rr(e){if(!e)return null;let t=Number(e);return Number.isFinite(t)?t:null}function ri(e){if(0===e.length)return null;let t=rr(e[0]);if(null!==t)return{kind:"sleep",durationMs:t};if("text"===e[0]){let t=rr(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=rr(e[e.length-1]);return{kind:"ref",rawRef:e[0],timeoutMs:t}}let n=rr(e[e.length-1]),a=b(null!==n?e.slice(0,-1):e.slice());if(a&&0===a.rest.length){let e=I(a.selectorExpression);if(e)return{kind:"selector",selector:e,selectorExpression:a.selectorExpression,timeoutMs:n}}return{kind:"text",text:(null!==n?e.slice(0,-1).join(" "):e.join(" ")).trim(),timeoutMs:n}}function ro(e){return e}function rs(e){return"apple"===e||"ios"===e||"macos"===e}function rl(e,t){return!t||("apple"===t?rs(e):e===t)}function rd(e){let{simulatorSetPath:t,platform:n,target:a}=e;if(t&&"macos"!==n&&"desktop"!==a)return t}async function ru(e,t,n={}){let a=e,r=e=>e.toLowerCase().replace(/_/g," ").replace(/\s+/g," ").trim();if(t.platform&&(a=a.filter(e=>rl(e.platform,t.platform))),t.target&&(a=a.filter(e=>(e.target??"mobile")===t.target)),t.udid){let e=a.find(e=>e.id===t.udid&&rs(e.platform));if(!e)throw new y("DEVICE_NOT_FOUND",`No Apple device with UDID ${t.udid}`);return e}if(t.serial){let e=a.find(e=>e.id===t.serial&&"android"===e.platform);if(!e)throw new y("DEVICE_NOT_FOUND",`No Android device with serial ${t.serial}`);return e}if(t.deviceName){let e=r(t.deviceName),n=a.find(t=>r(t.name)===e);if(!n)throw new y("DEVICE_NOT_FOUND",`No device named ${t.deviceName}`);return n}if(1===a.length)return a[0];if(0===a.length){var i;let e=n.simulatorSetPath;if(e&&(!(i=t.platform)||"apple"===i||"ios"===i))throw new y("DEVICE_NOT_FOUND","No devices found in the scoped simulator set",{simulatorSetPath:e,hint:`The simulator set at "${e}" appears to be empty. Create a simulator first:
|
|
2
|
+
xcrun simctl --set "${e}" create "iPhone 16" com.apple.CoreSimulator.SimDeviceType.iPhone-16 com.apple.CoreSimulator.SimRuntime.iOS-18-0`,selector:t});throw new y("DEVICE_NOT_FOUND","No devices found",{selector:t})}let o=a.filter(e=>"device"!==e.kind);o.length>0&&(a=o);let s=a.filter(e=>e.booted);return 1===s.length?s[0]:s[0]??a[0]}let rc=e=>"macos"!==e.platform,rp=e=>"macos"===e.platform||"simulator"===e.kind,rf={device:!0},rh={},rm={alert:{apple:{simulator:!0,device:!0},android:{},linux:rh,supports:rp},pinch:{apple:{simulator:!0,device:!0},android:{},linux:rh,supports:rp},"app-switcher":{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rh,supports:rc},apps:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rh},back:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rf},boot:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rh,supports:rc},click:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rf},clipboard:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rf,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:rh,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:rf},fill:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rf},diff:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rf},find:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rf},focus:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rf},get:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rf},is:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rf},home:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rf,supports:rc},logs:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rh},network:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rh},longpress:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rf},open:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rf},perf:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rh},install:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rh,supports:rc},"install-from-source":{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rh,supports:rc},reinstall:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rh,supports:rc},press:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rf},push:{apple:{simulator:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rh,supports:rc},record:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rh},rotate:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rh,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:rf},scroll:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rf},swipe:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rf},settings:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rh,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:rf},"trigger-app-event":{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rh},type:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rf},wait:{apple:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0},linux:rf}};function rw(e,t){let n=rm[e];if(!n)return!0;let a=rs(t.platform)?n.apple:"linux"===t.platform?n.linux:n.android;return!!a&&(!n.supports||!!n.supports(t))&&!0===a[t.kind??"unknown"]}let rg=ry(process.env.AGENT_DEVICE_RETRY_LOGS);function ry(e){return["1","true","yes","on"].includes((e??"").trim().toLowerCase())}let rb=2e4,rv=12e4,rA=1e4;class rI{startedAtMs;expiresAtMs;constructor(e,t){this.startedAtMs=e,this.expiresAtMs=e+Math.max(0,t)}static fromTimeoutMs(e,t=Date.now()){return new rI(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 rx(e,t={},n={}){let a,r={maxAttempts:t.maxAttempts??3,baseDelayMs:t.baseDelayMs??200,maxDelayMs:t.maxDelayMs??2e3,jitter:t.jitter??.2,shouldRetry:t.shouldRetry};for(let t=1;t<=r.maxAttempts;t+=1){if(n.signal?.aborted)throw new y("COMMAND_FAILED","request canceled",{reason:"request_canceled"});if(n.deadline?.isExpired()&&t>1)break;try{let a=await e({attempt:t,maxAttempts:r.maxAttempts,deadline:n.deadline});return n.onEvent?.({phase:n.phase,event:"succeeded",attempt:t,maxAttempts:r.maxAttempts,elapsedMs:n.deadline?.elapsedMs(),remainingMs:n.deadline?.remainingMs()}),rN({phase:n.phase,event:"succeeded",attempt:t,maxAttempts:r.maxAttempts,elapsedMs:n.deadline?.elapsedMs(),remainingMs:n.deadline?.remainingMs()}),a}catch(d){a=d;let e=n.classifyReason?.(d),i={phase:n.phase,event:"attempt_failed",attempt:t,maxAttempts:r.maxAttempts,elapsedMs:n.deadline?.elapsedMs(),remainingMs:n.deadline?.remainingMs(),reason:e};if(n.onEvent?.(i),rN(i),t>=r.maxAttempts||r.shouldRetry&&!r.shouldRetry(d,t))break;let o=function(e,t,n,a){let r=Math.min(t,e*2**(a-1));return Math.max(0,r+r*n*(2*Math.random()-1))}(r.baseDelayMs,r.maxDelayMs,r.jitter,t),s=n.deadline?Math.min(o,n.deadline.remainingMs()):o;if(s<=0)break;let l={phase:n.phase,event:"retry_scheduled",attempt:t,maxAttempts:r.maxAttempts,delayMs:s,elapsedMs:n.deadline?.elapsedMs(),remainingMs:n.deadline?.remainingMs(),reason:e};n.onEvent?.(l),rN(l),await function(e,t){return new Promise(n=>{if(t?.aborted)return void n();let a=!1,r=()=>{a||(a=!0,t&&t.removeEventListener("abort",o),n())},i=setTimeout(r,e);function o(){clearTimeout(i),r()}t&&t.addEventListener("abort",o,{once:!0})})}(s,n.signal)}}let i={phase:n.phase,event:"exhausted",attempt:r.maxAttempts,maxAttempts:r.maxAttempts,elapsedMs:n.deadline?.elapsedMs(),remainingMs:n.deadline?.remainingMs(),reason:n.classifyReason?.(a)};if(n.onEvent?.(i),rN(i),a)throw a;throw new y("COMMAND_FAILED","retry failed")}async function rS(e,t={}){return rx(()=>e(),{maxAttempts:t.attempts,baseDelayMs:t.baseDelayMs,maxDelayMs:t.maxDelayMs,jitter:t.jitter,shouldRetry:t.shouldRetry})}function rN(e){el({level:"attempt_failed"===e.event||"exhausted"===e.event?"warn":"debug",phase:"retry",data:{...e}}),rg&&process.stderr.write(`[agent-device][retry] ${JSON.stringify(e)}
|
|
3
|
+
`)}let r_=new Set,rM=new Map,rk="request_canceled",rD="request canceled";function rE(e,t){if("string"==typeof e&&e.length>0)return e;let n=("string"==typeof t?t:"number"==typeof t&&Number.isFinite(t)?String(t):"generated").trim().replace(/[^a-zA-Z0-9_-]/g,"_").slice(0,32)||"generated",a=Math.random().toString(36).slice(2,10);return`req:${n}:${process.pid}:${Date.now()}:${a}`}function rO(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++}}(rM);let t=new AbortController;rM.set(e,t),r_.has(e)&&t.abort()}function rC(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++}}(r_),r_.add(e),rM.get(e)?.abort())}function rR(e){e&&(r_.delete(e),rM.delete(e))}function rP(e){return!!e&&r_.has(e)}function rT(e){if(e)return rM.get(e)?.signal}function rL(){return new y("COMMAND_FAILED",rD,{reason:rk})}function r$(e){return e instanceof y&&"COMMAND_FAILED"===e.code&&(e.details?.reason===rk||e.message===rD)}function rF(e){let t=e.error?w(e.error):null,n=e.context?.platform,a=e.context?.phase;if(t?.code==="TOOL_MISSING")return"android"===n?"ADB_TRANSPORT_UNAVAILABLE":"IOS_TOOL_MISSING";let r=t?.details??{},i="string"==typeof r.message?r.message:void 0,o="string"==typeof r.stdout?r.stdout:void 0,s="string"==typeof r.stderr?r.stderr:void 0,l=r.boot&&"object"==typeof r.boot?r.boot:null,d=r.bootstatus&&"object"==typeof r.bootstatus?r.bootstatus:null,u=[e.message,t?.message,e.stdout,e.stderr,i,o,s,"string"==typeof l?.stdout?l.stdout:void 0,"string"==typeof l?.stderr?l.stderr:void 0,"string"==typeof d?.stdout?d.stdout:void 0,"string"==typeof d?.stderr?d.stderr:void 0].filter(Boolean).join("\n").toLowerCase();return"ios"===n&&(u.includes("runner did not accept connection")||"connect"===a&&(u.includes("timed out")||u.includes("timeout")||u.includes("econnrefused")||u.includes("connection refused")||u.includes("fetch failed")||u.includes("socket hang up")))?"IOS_RUNNER_CONNECT_TIMEOUT":"ios"===n&&"boot"===a&&(u.includes("timed out")||u.includes("timeout"))?"IOS_BOOT_TIMEOUT":"android"===n&&"boot"===a&&(u.includes("timed out")||u.includes("timeout"))?"ANDROID_BOOT_TIMEOUT":u.includes("resource temporarily unavailable")||u.includes("killed: 9")||u.includes("cannot allocate memory")||u.includes("system is low on memory")?"CI_RESOURCE_STARVATION_SUSPECTED":"android"===n&&(u.includes("device not found")||u.includes("no devices")||u.includes("device offline")||u.includes("offline")||u.includes("unauthorized")||u.includes("not authorized")||u.includes("unable to locate device")||u.includes("invalid device"))?"ADB_TRANSPORT_UNAVAILABLE":t?.code==="COMMAND_FAILED"||u.length>0?"BOOT_COMMAND_FAILED":"UNKNOWN"}function rU(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 rG=["AGENT_DEVICE_IOS_SIMULATOR_DEVICE_SET","IOS_SIMULATOR_DEVICE_SET"],rV=["AGENT_DEVICE_ANDROID_DEVICE_ALLOWLIST","ANDROID_DEVICE_ALLOWLIST"];function rB(e){return e?.trim()||void 0}function rj(e,t){for(let n of e){let e=rB(t[n]);if(e)return e}}function rq(e,t=process.env){return rB(e)??rj(rG,t)}function rW(e){return new Set(e.split(/[\s,]+/).map(e=>e.trim()).filter(Boolean))}function rX(e,t=process.env){let n=rB(e)??rj(rV,t);if(n)return rW(n)}function rH(e,t={}){let n=rq(t.simulatorSetPath);return n?["simctl","--set",n,...e]:["simctl",...e]}function rz(e,t){return"ios"!==e.platform||"simulator"!==e.kind?["simctl",...t]:rH(t,{simulatorSetPath:e.simulatorSetPath})}function rY(e){return!(e instanceof y)||"COMMAND_FAILED"!==e.code||!String(e.message??"").toLowerCase().includes("xcodebuild exited early")}function rK(e){let{port:t,endpoints:n,logPath:a,lastError:r}=e,i="Runner did not accept connection";return new y("COMMAND_FAILED",i,{port:t,endpoints:n,logPath:a,lastError:r?String(r):void 0,reason:rF({error:r,message:i,context:{platform:"ios",phase:"connect"}}),hint:rU("IOS_RUNNER_CONNECT_TIMEOUT")})}async function rJ(e){var t,n;let a,{session:r,port:i,logPath:o}=e,s=await r.testPromise,l="Runner did not accept connection (xcodebuild exited early)",d=rF({message:l,stdout:s.stdout,stderr:s.stderr,context:{platform:"ios",phase:"connect"}});return new y("COMMAND_FAILED",l,{port:i,logPath:o,xcodebuild:{exitCode:s.exitCode,stdout:s.stdout,stderr:s.stderr},reason:d,hint:(t=s.stdout,n=s.stderr,(a=`${l}
|
|
4
4
|
${t}
|
|
5
|
-
${n}`.toLowerCase()).includes("device is busy")&&a.includes("connecting")?"Target iOS device is still connecting. Keep it unlocked, wait for device trust/connection to settle, then retry.":rN("IOS_RUNNER_CONNECT_TIMEOUT"))})}function r$(e){if(rb(e))throw rA()}let rF=ei(process.env.AGENT_DEVICE_RUNNER_STARTUP_TIMEOUT_MS,45e3,5e3),rU=ei(process.env.AGENT_DEVICE_RUNNER_COMMAND_TIMEOUT_MS,45e3,1e3),rG=ei(process.env.AGENT_DEVICE_RUNNER_CONNECT_ATTEMPT_INTERVAL_MS,250,50),rV=ei(process.env.AGENT_DEVICE_RUNNER_CONNECT_RETRY_BASE_DELAY_MS,300,10),rB=ei(process.env.AGENT_DEVICE_RUNNER_CONNECT_RETRY_MAX_DELAY_MS,2e3,10),rj=ei(process.env.AGENT_DEVICE_RUNNER_CONNECT_REQUEST_TIMEOUT_MS,2e4,250),rq=ei(process.env.AGENT_DEVICE_IOS_DEVICE_INFO_TIMEOUT_MS,1e4,500),rX=eo(process.env.AGENT_DEVICE_RUNNER_DESTINATION_TIMEOUT_SECONDS,20,5);async function rz(e,t,n,a,r=rF,i,o){let s=rs.fromTimeoutMs(r),l=await rW(e,t,s.remainingMs()),d=null,u=Math.max(1,Math.ceil(r/rG));try{return await rl(async({deadline:s})=>{if(s?.isExpired())throw new w("COMMAND_FAILED","Runner connection deadline exceeded",{port:t,timeoutMs:r});if(i&&null!==i.child.exitCode&&void 0!==i.child.exitCode)throw await rL({session:i,port:t,logPath:a});for(let a of("device"===e.kind&&(l=await rW(e,t,s?.remainingMs())),l))try{let e=s?.remainingMs()??r;if(e<=0)throw new w("COMMAND_FAILED","Runner connection deadline exceeded",{port:t,timeoutMs:r});return await rH(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)},Math.min(rj,e),o)}catch(e){if(o?.aborted||rI(e))throw rA();d=e}throw new w("COMMAND_FAILED","Runner endpoint probe failed",{port:t,endpoints:l,lastError:d?String(d):void 0})},{maxAttempts:u,baseDelayMs:rV,maxDelayMs:rB,jitter:.2,shouldRetry:rP},{deadline:s,phase:"ios_runner_connect",signal:o})}catch(e){if(o?.aborted||rI(e))throw rA();d||(d=e)}if(o?.aborted)throw rA();if("simulator"===e.kind){let r=s.remainingMs();if(r<=0)throw rT({port:t,endpoints:l,logPath:a,lastError:d});let i=await rK(e,t,n,r);return new Response(i.body,{status:i.status})}throw rT({port:t,endpoints:l,logPath:a,lastError:d})}async function rW(e,t,n){let a=[`http://127.0.0.1:${t}/command`];if("device"!==e.kind)return a;let r=await rY(e.id,n);return r&&a.unshift(`http://[${r}]:${t}/command`),a}async function rH(e,t,n,a){let r,i=new AbortController,o=setTimeout(()=>i.abort(),n);a&&(a.aborted?(clearTimeout(o),i.abort()):(r=()=>i.abort(),a.addEventListener("abort",r,{once:!0})));try{return await fetch(e,{...t,signal:i.signal})}finally{clearTimeout(o),r&&a&&a.removeEventListener("abort",r)}}async function rY(e,t){if("number"==typeof t&&t<=0)return null;let a="number"==typeof t?Math.max(1,Math.min(rq,t)):rq,r=o.join(s.tmpdir(),`agent-device-devicectl-info-${process.pid}-${Date.now()}.json`);try{let t=Math.max(1,Math.ceil(a/1e3)),i=await Z("xcrun",["devicectl","device","info","details","--device",e,"--json-output",r,"--timeout",String(t)],{allowFailure:!0,timeoutMs:a});if(0!==i.exitCode||!n.existsSync(r))return null;let o=JSON.parse(n.readFileSync(r,"utf8"));if(o.info?.outcome&&"success"!==o.info.outcome)return null;let s=(o.result?.connectionProperties?.tunnelIPAddress??o.result?.device?.connectionProperties?.tunnelIPAddress)?.trim();return s&&s.length>0?s:null}catch{return null}finally{rQ(r)}}async function rK(e,t,n,a){let r=JSON.stringify(n),i=rR(e,["spawn",e.id,"/usr/bin/curl","-s","-X","POST","-H","Content-Type: application/json","--data",r,`http://127.0.0.1:${t}/command`]),o=await Z("xcrun",i,{allowFailure:!0,timeoutMs:a}),s=o.stdout;if(0!==o.exitCode){let e=rx({message:"Runner did not accept connection (simctl spawn)",stdout:o.stdout,stderr:o.stderr,context:{platform:"ios",phase:"connect"}});throw new w("COMMAND_FAILED","Runner did not accept connection (simctl spawn)",{port:t,stdout:o.stdout,stderr:o.stderr,exitCode:o.exitCode,reason:e,hint:rN(e)})}return{status:200,body:s}}async function rJ(){return await new Promise((e,t)=>{let n=d.createServer();n.listen(0,"127.0.0.1",()=>{let a=n.address();if("object"==typeof a&&a?.port){let t=a.port;n.close(()=>e(t))}else n.close(()=>t(new w("COMMAND_FAILED","Failed to allocate port")))}),n.on("error",t)})}function rZ(e,t,a,r){t&&n.appendFile(t,e,()=>{}),a&&n.appendFile(a,e,()=>{}),r&&process.stderr.write(e)}function rQ(e){try{n.existsSync(e)&&n.unlinkSync(e)}catch{}}let r0=new u;async function r1(e,t,n){let a=r0.getStore()??[];if(a.some(n=>n.locks===e&&n.key===t))return await n();let r=(e.get(t)??Promise.resolve()).catch(()=>{}).then(()=>r0.run([...a,{locks:e,key:t}],n));return e.set(t,r),r.finally(()=>{e.get(t)===r&&e.delete(t)})}let r2=new Set(["RUNNER_PRODUCT_MISSING","RUNNER_PRODUCT_REPAIR_FAILED"]);async function r3(e,t,a){if("macos"!==e.platform)return;if(0===t.length)throw new w("COMMAND_FAILED","Missing macOS runner product",{reason:"RUNNER_PRODUCT_MISSING",xctestrunPath:a});let r=Array.from(new Set(t)).sort((e,t)=>t.length-e.length);for(let e of r)if(!n.existsSync(e))throw new w("COMMAND_FAILED","Missing macOS runner product",{reason:"RUNNER_PRODUCT_MISSING",productPath:e,xctestrunPath:a});for(let e of r)if(0!==J("codesign",["--verify","--deep","--strict",e],{allowFailure:!0}).exitCode){await Z("codesign",["--remove-signature",e],{allowFailure:!0});try{await Z("codesign",["--force","--sign","-",e])}catch(n){let t=n instanceof w?n:new w("COMMAND_FAILED",String(n));throw new w("COMMAND_FAILED","Failed to repair macOS runner product signature",{reason:"RUNNER_PRODUCT_REPAIR_FAILED",productPath:e,xctestrunPath:a,error:t.message,details:t.details})}}}let r4=null;function r5(e){return function e(t){if(!Array.isArray(t))return[];let n=[];for(let a of t)if(!(!a||"object"!=typeof a||Array.isArray(a)))for(let[t,r]of Object.entries(a))":@"!==t&&"#text"!==t&&n.push({name:t,attributes:function(e){if(!e||"object"!=typeof e||Array.isArray(e))return{};let t={};for(let[n,a]of Object.entries(e))"string"==typeof a&&(t[n]=a);return t}(a[":@"]),text:r6(r)??r6(a["#text"]),children:e(r)});return n}((r4??=new p({ignoreAttributes:!1,attributeNamePrefix:"",preserveOrder:!0,trimValues:!0,parseTagValue:!1})).parse(e))}function r8(e,t){for(let n of e){if("dict"===n.name)for(let e=0;e<n.children.length-1;e+=1){let a=n.children[e],r=n.children[e+1];a?.name==="key"&&a.text&&r&&t(a.text,r)}r8(n.children,t)}}function r6(e){if("string"==typeof e){let t=e.trim();return t.length>0?t:null}if(!Array.isArray(e))return null;let t=e.map(e=>{if(!e||"object"!=typeof e||Array.isArray(e))return null;let t=e["#text"];return"string"==typeof t?t.trim():null}).filter(e=>null!==e&&e.length>0).join("").trim();return t.length>0?t:null}let r9="XCTestDevices",r7=".agent-device-backup",ie=".agent-device-xctestdevices-backup-",it=o.join(s.homedir(),".agent-device","ios-runner"),ia=new Set(["ProductPaths","DependentProductPaths","TestHostPath","TestBundlePath","UITargetAppPath"]),ir=new Map,ii=new Set;function io(e){return e?.trim()??""}function is(e=process.env){return io(e.AGENT_DEVICE_IOS_BUNDLE_ID)||io(e.AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID)||"com.callstack.agentdevice.runner"}function il(e=process.env){let t=io(e.AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID);return t||`${is(e)}.uitests`}let id=function(e=process.env){let t=is(e),n=il(e);return Array.from(new Set([io(e.AGENT_DEVICE_IOS_RUNNER_CONTAINER_BUNDLE_ID),`${n}.xctrunner`,t].filter(e=>e.length>0)))}(process.env);function iu(e=s.homedir()){return o.join(e,"Library","Developer","XCTestDevices")}async function ic(e,t={}){if("ios"!==e.platform||"simulator"!==e.kind)return null;let a=rD(e.simulatorSetPath);if(!a)return null;let r=o.resolve(a),i=o.resolve(t.xctestDeviceSetPath??iu()),l=o.resolve(t.backupPath??function(e=iu()){return`${e}${r7}`}(i)),d=o.resolve(t.lockDirPath??function(e=s.homedir()){return o.join(e,".agent-device","xctest-device-set.lock")}()),u=t.ownerStartTime??el(process.pid),c=await im({lockDirPath:d,owner:{pid:t.ownerPid??process.pid,startTime:u,acquiredAtMs:t.nowMs??Date.now()}});try{if(ip({xctestDeviceSetPath:i,backupPath:l}),function(e,t){if(o.resolve(e)===o.resolve(t))return!0;try{return n.realpathSync.native(e)===n.realpathSync.native(t)}catch{return!1}}(r,i))return await c(),null;n.mkdirSync(r,{recursive:!0}),n.existsSync(i)&&n.renameSync(i,l),function(e){let{requestedSetPath:t,xctestDeviceSetPath:a}=e,r=o.dirname(a),i=o.join(r,`${r9}.agent-device-link-${process.pid}-${Date.now()}`);n.mkdirSync(r,{recursive:!0});try{n.symlinkSync(t,i,"dir"),n.renameSync(i,a)}catch(e){throw n.existsSync(i)&&ih(i),e}}({requestedSetPath:r,xctestDeviceSetPath:i})}catch(e){throw ip({xctestDeviceSetPath:i,backupPath:l}),await c(),new w("COMMAND_FAILED","Failed to redirect XCTest device set path",{requestedSetPath:r,xctestDeviceSetPath:i,backupPath:l,error:String(e)})}let p=!1;return{release:async()=>{if(!p){p=!0;try{ip({xctestDeviceSetPath:i,backupPath:l})}finally{await c()}}}}}function ip(e){let{xctestDeviceSetPath:t,backupPath:a}=e,r=[a,...function(e){let t=o.dirname(e),a=o.basename(e).replace(r7,""),r=a===r9?ie:`${a}${ie}`;try{return n.readdirSync(t).filter(e=>e.startsWith(r)).sort().map(e=>o.join(t,e))}catch{return[]}}(a)],i=r.find(e=>n.existsSync(e)),s=n.existsSync(t)&&n.lstatSync(t).isSymbolicLink();if(i){if(s&&ih(t),n.existsSync(t))if(!s)return void W({level:"warn",phase:"ios_runner_xctest_device_set_restore_collision",data:{xctestDeviceSetPath:t,activeBackupPath:i}});else i!==a?n.rmSync(i,{recursive:!0,force:!0}):n.rmSync(a,{recursive:!0,force:!0});else n.mkdirSync(o.dirname(t),{recursive:!0}),n.renameSync(i,t);for(let e of r)e!==i&&n.existsSync(e)&&n.rmSync(e,{recursive:!0,force:!0});return}s&&(W({level:"warn",phase:"ios_runner_xctest_device_set_orphaned_symlink",data:{xctestDeviceSetPath:t}}),ih(t))}function ih(e){!n.existsSync(e)||n.lstatSync(e).isSymbolicLink()&&n.unlinkSync(e)}async function im(e){let{lockDirPath:t,owner:a}=e,r=o.join(t,"owner.json"),i=Date.now()+3e4;for(n.mkdirSync(o.dirname(t),{recursive:!0});Date.now()<i;)try{n.mkdirSync(t),function(e,t){let a=`${e}.${process.pid}.${Date.now()}.tmp`;n.writeFileSync(a,JSON.stringify(t),"utf8"),n.renameSync(a,e)}(r,a);let e=!1;return async()=>{e||(e=!0,n.rmSync(t,{recursive:!0,force:!0}))}}catch(e){if("EEXIST"!==e.code)throw e;if(function(e,t){let a=null;try{a=n.statSync(e)}catch{return!0}let r=function(e){try{return JSON.parse(n.readFileSync(e,"utf8"))}catch{return null}}(t);if(r){var i;return!(Number.isInteger((i=r).pid)&&!(i.pid<=0)&&es(i.pid)&&(!i.startTime||el(i.pid)===i.startTime))&&(n.rmSync(e,{recursive:!0,force:!0}),!0)}return!(Date.now()-a.mtimeMs<5e3)&&(n.rmSync(e,{recursive:!0,force:!0}),!0)}(t,r))continue;await er(100)}throw new w("COMMAND_FAILED","Timed out waiting for XCTest device set lock",{lockDirPath:t})}async function iw(e,t){var a;let r,i=(a=e,(r=process.env.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim())?o.resolve(r):"macos"===a.platform?o.join(it,"derived","macos"):"simulator"===a.kind?o.join(it,"derived"):o.join(it,"derived",a.kind)),s=function(){let e=o.dirname(c(import.meta.url)),t=e;for(let e=0;e<6;e+=1){let e=o.join(t,"package.json");if(n.existsSync(e))return t;t=o.dirname(t)}return e}();return await r1(ir,i,async()=>{ra(process.env.AGENT_DEVICE_IOS_CLEAN_DERIVED)&&(ik("clean","forced_clean",{derived:i}),iM(i),ig(i));let a=function(e){let t=e.findXctestrun(e.derived);if(!t)return{reason:"missing_xctestrun",xctestrunPath:null};let n=e.resolveExistingXctestrunProductPaths(t);return n?e.xctestrunReferencesProjectRoot(t,e.projectRoot)?{reason:"reuse_ready",xctestrunPath:t,productPaths:n}:{reason:"project_root_mismatch",xctestrunPath:t,productPaths:n}:{reason:"missing_products",xctestrunPath:t,productPaths:[]}}({derived:i,projectRoot:s,findXctestrun:t=>ib(t,e),xctestrunReferencesProjectRoot:iA,resolveExistingXctestrunProductPaths:iD});if("reuse_ready"!==a.reason&&ik("rebuild",a.reason,{derived:i,xctestrunPath:a.xctestrunPath}),"reuse_ready"===a.reason)try{return await r3(e,a.productPaths,a.xctestrunPath),ik("reuse","reuse_ready",{derived:i,xctestrunPath:a.xctestrunPath}),a.xctestrunPath}catch(e){if(!function(e){if(!(e instanceof w))return!1;let t=e.details&&"object"==typeof e.details?e.details.reason:void 0;return"string"==typeof t&&r2.has(t)}(e))throw e;ik("rebuild","repair_failed",{derived:i,xctestrunPath:a.xctestrunPath})}a.xctestrunPath&&(iM(i),ig(i));let r=o.join(s,"ios-runner","AgentDeviceRunner","AgentDeviceRunner.xcodeproj");if(!n.existsSync(r))throw new w("COMMAND_FAILED","iOS runner project not found",{projectPath:r});await ix(e,r,i,t);let l=ib(i,e);if(!l)throw new w("COMMAND_FAILED","Failed to locate .xctestrun after build");let d=iD(l);if(!d)throw new w("COMMAND_FAILED","Runner build is missing expected products",{xctestrunPath:l});return await r3(e,d,l),ik("build","built_new",{derived:i,xctestrunPath:l}),l})}function ig(e){try{if(!n.existsSync(e))return;if("derived"!==o.basename(e))return void n.rmSync(e,{recursive:!0,force:!0});for(let a of n.readdirSync(e,{withFileTypes:!0})){var t;t=a.name,iy.has(t)&&n.rmSync(o.join(e,a.name),{recursive:!0,force:!0})}}catch{}}let iy=new Set(["Build","BuildCache.noindex","Index.noindex","Logs","ModuleCache.noindex","SDKStatCaches.noindex","SourcePackages","TextBasedInstallAPI","info.plist"]);function ib(e,t){if(!n.existsSync(e))return null;let a=[],r=[e];for(;r.length>0;){let e=r.pop();for(let t of n.readdirSync(e,{withFileTypes:!0})){let i=o.join(e,t.name);if(t.isDirectory()){r.push(i);continue}if(t.isFile()&&t.name.endsWith(".xctestrun"))try{let e=n.statSync(i);a.push({path:i,mtimeMs:e.mtimeMs})}catch{}}}return 0===a.length?null:(a.sort((e,n)=>{if(t){let a=iv(n.path,t)-iv(e.path,t);if(0!==a)return a}return n.mtimeMs-e.mtimeMs||e.path.localeCompare(n.path)}),a[0]?.path??null)}function iv(e,t){var n;let a=0,r=e.toLowerCase();o.basename(r).startsWith("agentdevicerunner.env.")&&(a-=1e3),r.includes(`${o.sep}macos${o.sep}`)&&(a-=5e3);let i="macos"===(n=t).platform?{preferred:["macos"],disallowed:["iphoneos","iphonesimulator","appletvos","appletvsimulator"]}:"tv"===n.target?"simulator"===n.kind?{preferred:["appletvsimulator"],disallowed:["appletvos","iphoneos","iphonesimulator","macos"]}:{preferred:["appletvos"],disallowed:["appletvsimulator","iphoneos","iphonesimulator","macos"]}:"simulator"===n.kind?{preferred:["iphonesimulator"],disallowed:["iphoneos","appletvos","appletvsimulator","macos"]}:{preferred:["iphoneos"],disallowed:["iphonesimulator","appletvos","appletvsimulator","macos"]};return i.preferred.length>0&&(i.preferred.some(e=>r.includes(e))?a+=2e3:a-=500),i.disallowed.some(e=>r.includes(e))&&(a-=2500),a}function iA(e,t){try{let a=n.readFileSync(e,"utf8"),r=new Set([t]);try{r.add(n.realpathSync(t))}catch{}for(let e of r)if(a.includes(e))return!0;return!1}catch{return!1}}async function iI(e,t,a){let r,i=o.dirname(e),s=a.replace(/[^a-zA-Z0-9._-]/g,"_"),l=o.join(i,`AgentDeviceRunner.env.${s}.json`),d=o.join(i,`AgentDeviceRunner.env.${s}.xctestrun`),u=await Z("plutil",["-convert","json","-o","-",e],{allowFailure:!0});if(0!==u.exitCode||!u.stdout.trim())throw new w("COMMAND_FAILED","Failed to read xctestrun plist",{xctestrunPath:e,stderr:u.stderr});try{let e=JSON.parse(u.stdout);if(!e||"object"!=typeof e||Array.isArray(e))throw Error("Root must be an object");r=e}catch(t){throw new w("COMMAND_FAILED","Failed to parse xctestrun JSON",{xctestrunPath:e,error:String(t)})}let c=e=>{e.EnvironmentVariables={...e.EnvironmentVariables??{},...t},e.UITestEnvironmentVariables={...e.UITestEnvironmentVariables??{},...t},e.UITargetAppEnvironmentVariables={...e.UITargetAppEnvironmentVariables??{},...t},e.TestingEnvironmentVariables={...e.TestingEnvironmentVariables??{},...t}},p=r.TestConfigurations;if(Array.isArray(p))for(let e of p){if(!e||"object"!=typeof e)continue;let t=e.TestTargets;if(Array.isArray(t))for(let e of t)e&&"object"==typeof e&&c(e)}for(let[e,t]of Object.entries(r))t&&"object"==typeof t&&!Array.isArray(t)&&t.TestBundlePath&&(c(t),r[e]=t);n.writeFileSync(l,JSON.stringify(r,null,2));let f=await Z("plutil",["-convert","xml1","-o",d,l],{allowFailure:!0});if(0!==f.exitCode)throw new w("COMMAND_FAILED","Failed to write xctestrun plist",{tmpXctestrunPath:d,stderr:f.stderr});return{xctestrunPath:d,jsonPath:l}}async function ix(e,t,n,a){let r=function(e=process.env){let t=is(e),n=il(e);return[`AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID=${t}`,`AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID=${n}`]}(process.env),i=function(e=process.env,t=!1,n="ios"){if("macos"===n)return["CODE_SIGNING_ALLOWED=NO","CODE_SIGNING_REQUIRED=NO","CODE_SIGN_IDENTITY=","DEVELOPMENT_TEAM="];if(!t)return[];let a=e.AGENT_DEVICE_IOS_TEAM_ID?.trim()||"",r=e.AGENT_DEVICE_IOS_SIGNING_IDENTITY?.trim()||"",i=e.AGENT_DEVICE_IOS_PROVISIONING_PROFILE?.trim()||"",o=["CODE_SIGN_STYLE=Automatic"];return a&&o.push(`DEVELOPMENT_TEAM=${a}`),r&&o.push(`CODE_SIGN_IDENTITY=${r}`),i&&o.push(`PROVISIONING_PROFILE_SPECIFIER=${i}`),o}(process.env,"device"===e.kind,e.platform),o="device"===e.kind?["-allowProvisioningUpdates"]:[],s=await ic(e);try{var l;let s;await H("xcodebuild",["build-for-testing","-project",t,"-scheme","AgentDeviceRunner","-parallel-testing-enabled","NO",i_(e),"1","-destination",(l=e,s=iN(l),"macOS"===s?`platform=macOS,arch=${iS()}`:"simulator"===l.kind?`platform=${s} Simulator,id=${l.id}`:`generic/platform=${s}`),"-derivedDataPath",n,"COMPILER_INDEX_STORE_ENABLE=NO","ENABLE_CODE_COVERAGE=NO",...r,...o,...i],{detached:!0,onSpawn:e=>{ii.add(e),e.on("close",()=>{ii.delete(e)})},onStdoutChunk:e=>{rZ(e,a.logPath,a.traceLogPath,a.verbose)},onStderrChunk:e=>{rZ(e,a.logPath,a.traceLogPath,a.verbose)}})}catch(i){let e,t,n=i instanceof w?i:new w("COMMAND_FAILED",String(i)),r=(e=n.details?JSON.stringify(n.details):"",(t=`${n.message}
|
|
6
|
-
${e}`.toLowerCase()).includes("failed registering bundle identifier")||t.includes("app identifier")&&t.includes("not available")?"Set AGENT_DEVICE_IOS_BUNDLE_ID to a unique reverse-DNS value (for example, com.yourname.agentdevice.runner), then retry.":t.includes("requires a development team")?"Configure signing in Xcode or set AGENT_DEVICE_IOS_TEAM_ID for physical-device runs.":t.includes("no profiles for")||t.includes("provisioning profile")?"Install/select a valid iOS provisioning profile, or set AGENT_DEVICE_IOS_PROVISIONING_PROFILE.":t.includes("code signing")?"Enable Automatic Signing in Xcode or provide AGENT_DEVICE_IOS_TEAM_ID and optional AGENT_DEVICE_IOS_SIGNING_IDENTITY.":void 0);throw new
|
|
7
|
-
${n.stderr}`.toLowerCase();if(!e.includes("not installed")&&!e.includes("found nothing")&&!e.includes("no such file")&&!e.includes("invalid device")&&!e.includes("could not find"))continue}}}function
|
|
8
|
-
`,"utf8"),a}async function
|
|
9
|
-
${t}`.toLowerCase();return n.includes("no shell command implementation")||n.includes("unknown command")}function
|
|
10
|
-
${e.stderr}`}function od(e,t){return["-s",e,...t]}function ou(e){return e.startsWith("emulator-")}function oc(e){return e.toLowerCase().replace(/_/g," ").replace(/\s+/g," ").trim()}async function op(e,t=ro){return Z("adb",od(e,["shell","getprop","sys.boot_completed"]),{allowFailure:!0,timeoutMs:t})}async function of(e,t){let n=t.replace(/_/g," ").trim();if(!ou(e))return n||e;let a=await om(e);return a?a.replace(/_/g," "):n||e}async function oh(e,t,n){try{return await n("adb",od(e,t),{allowFailure:!0,timeoutMs:1e4})}catch(e){var a;if("COMMAND_FAILED"===(a=h(e)).code&&"number"==typeof a.details?.timeoutMs)return;throw e}}async function om(e,t=Z){for(let n of["ro.boot.qemu.avd_name","persist.sys.avd_name"]){let a=await oh(e,["shell","getprop",n],t);if(!a)continue;let r=a.stdout.trim();if(0===a.exitCode&&r.length>0)return r}let n=await oh(e,["emu","avd","name"],t);if(!n)return;let a=function(e){let t=e.split("\n").map(e=>e.trim()).filter(e=>e.length>0);if(0!==t.length)return"OK"===t.at(-1)&&t.pop(),t.join("\n").trim()||void 0}(n.stdout);if(0===n.exitCode&&a)return a}async function ow(e,t){let n=ol(await Z("adb",od(e,["shell","cmd","package","has-feature",t]),{allowFailure:!0,timeoutMs:ro})).toLowerCase();return!!n.includes("true")||!n.includes("false")&&null}async function og(e){return(await Promise.all(os.map(async t=>await ow(e,t)))).some(e=>!0===e)}async function oy(e){var t;let n;return"tv"===((n=ol(await Z("adb",od(e,["shell","getprop","ro.build.characteristics"]),{allowFailure:!0,timeoutMs:ro})).toLowerCase()).includes("tv")||n.includes("leanback")?"tv":null)||await og(e)?"tv":(t=ol(await Z("adb",od(e,["shell","pm","list","features"]),{allowFailure:!0,timeoutMs:ro})),/feature:android\.(software\.leanback(_only)?|hardware\.type\.television)\b/i.test(t))?"tv":"mobile"}async function ob(e={}){if(await ed(),!await ee("adb"))throw new w("TOOL_MISSING","adb not found in PATH");let t=e.serialAllowlist??rO(void 0),n=(await ov()).filter(e=>!t||t.has(e.serial));return await Promise.all(n.map(async({serial:e,rawModel:t})=>{let[n,a,r]=await Promise.all([of(e,t),oN(e),oy(e)]);return{platform:"android",id:e,name:n,kind:ou(e)?"emulator":"device",target:r,booted:a}}))}async function ov(){return(await Z("adb",["devices","-l"],{timeoutMs:ro})).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 oA(){let e=await Z("emulator",["-list-avds"],{allowFailure:!0,timeoutMs:ro});if(0!==e.exitCode)throw new w("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 oI(e){let t=Date.now();for(;Date.now()-t<e.timeoutMs;){try{let t=await ox(e.avdName,e.serial);if(t)return{platform:"android",id:t,name:e.avdName,kind:"emulator",target:"mobile",booted:!1}}catch{}await er(1e3)}throw new w("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 ox(e,t){let n=oc(e);for(let e of(await ov()).filter(e=>(!t||e.serial===t)&&ou(e.serial)))if(oc(e.rawModel)===n||oc(await of(e.serial,e.rawModel))===n)return e.serial}async function oN(e){try{let t=await op(e);return"1"===t.stdout.trim()}catch{return!1}}async function oS(e){var t,n;let a;await ed();let r=e.avdName.trim();if(!r)throw new w("INVALID_ARGS","Android emulator boot requires a non-empty AVD name.");let i=e.timeoutMs??12e4;if(!await ee("adb"))throw new w("TOOL_MISSING","adb not found in PATH");if(!await ee("emulator"))throw new w("TOOL_MISSING","emulator not found in PATH");let o=await oA(),s=function(e,t){let n=e.find(e=>e===t);if(n)return n;let a=oc(t);return e.find(e=>oc(e)===a)}(o,r);if(!s)throw new w("DEVICE_NOT_FOUND",`No Android emulator AVD named ${e.avdName}`,{requestedAvdName:r,availableAvds:o,hint:"Run `emulator -list-avds` and pass an existing AVD name to --device."});let l=Date.now(),d=(t=await ob(),n=e.serial,a=oc(s),t.find(e=>"android"===e.platform&&"emulator"===e.kind&&(!n||e.id===n)&&oc(e.name)===a));if(!d){let t=["-avd",s];e.headless&&t.push("-no-window","-no-audio"),Y("emulator",t)}let u=d??await oI({avdName:s,serial:e.serial,timeoutMs:i}),c=Math.max(1e3,i-(Date.now()-l));await o_(u.id,c);let p=(await ob()).find(e=>e.id===u.id);return p?{...p,name:s,booted:!0}:{...u,name:s,booted:!0}}async function o_(e,t=6e4){let n,a=rs.fromTimeoutMs(t),r=Math.max(1,Math.ceil(t/1e3)),i=!1;try{await rl(async({deadline:r})=>{if(r?.isExpired())throw i=!0,new w("COMMAND_FAILED","Android boot deadline exceeded",{serial:e,timeoutMs:t,elapsedMs:a.elapsedMs(),message:"timeout"});let o=Math.max(1e3,r?.remainingMs()??t),s=await op(e,Math.min(o,ro));if(n=s,"1"!==s.stdout.trim())throw new w("COMMAND_FAILED","Android device is still booting",{serial:e,stdout:s.stdout,stderr:s.stderr,exitCode:s.exitCode})},{maxAttempts:r,baseDelayMs:1e3,maxDelayMs:1e3,jitter:0,shouldRetry:e=>{let t=rx({error:e,stdout:n?.stdout,stderr:n?.stderr,context:{platform:"android",phase:"boot"}});return"ADB_TRANSPORT_UNAVAILABLE"!==t&&"ANDROID_BOOT_TIMEOUT"!==t}},{deadline:a,phase:"boot",classifyReason:e=>rx({error:e,stdout:n?.stdout,stderr:n?.stderr,context:{platform:"android",phase:"boot"}})})}catch(c){let r=h(c),o=n?.stdout,s=n?.stderr,l=n?.exitCode,d=rx({error:c,stdout:o,stderr:s,context:{platform:"android",phase:"boot"}});"BOOT_COMMAND_FAILED"===d&&"Android device is still booting"===r.message&&(d="ANDROID_BOOT_TIMEOUT");let u={serial:e,timeoutMs:t,elapsedMs:a.elapsedMs(),reason:d,hint:rN(d),stdout:o,stderr:s,exitCode:l};if(i||"ANDROID_BOOT_TIMEOUT"===d)throw new w("COMMAND_FAILED","Android device did not finish booting in time",u);if("TOOL_MISSING"===r.code)throw new w("TOOL_MISSING",r.message,{...u,...r.details??{}});if("ADB_TRANSPORT_UNAVAILABLE"===d)throw new w("COMMAND_FAILED",r.message,{...u,...r.details??{}});throw new w(r.code,r.message,{...u,...r.details??{}},r.cause)}}let oM=/\.(?:apk|aab)$/i,ok=/^[A-Za-z_][\w]*(\.[A-Za-z_][\w]*)+$/;function oD(e){var t,n;let a=e.trim();return 0===a.length?"other":oM.test(a)?a.includes("/")||a.includes("\\")||a.startsWith(".")||a.startsWith("~")||(t=a,!ok.test(t))?"binary":"package":(n=a,ok.test(n))?"package":"other"}function oE(e){return`Android runtime hints require an installed package name, not "${e}". Install or reinstall the app first, then relaunch by package.`}async function oO(e,t){let n="url"===e.kind&&ep(e.url),a=await ec({source:e,isInstallablePath:(e,t)=>{var n;let a;return t.isFile()&&(n=e,".apk"===(a=o.extname(n).toLowerCase())||".aab"===a)},installableLabel:"Android installable (.apk or .aab)",allowArchiveExtraction:"url"!==e.kind||n,signal:t?.signal}),r=t?.resolveIdentity===!1?{}:await oC(a.installablePath);return{archivePath:a.archivePath,installablePath:a.installablePath,packageName:r.packageName,cleanup:a.cleanup}}async function oC(e){let t=o.extname(e).toLowerCase();return".apk"!==t&&".aab"!==t?{}:{packageName:await eu(e)}}let oR={settings:{type:"intent",value:"android.settings.SETTINGS"}},oP="android.intent.category.LAUNCHER",oT="android.intent.category.LEANBACK_LAUNCHER",oL="android.intent.category.DEFAULT",o$="Run agent-device apps --platform android to discover the installed package name, then retry open with that exact package.";async function oF(e,t){let n=t.trim();if("package"===oD(n))return{type:"package",value:n};let a=oR[n.toLowerCase()];if(a)return a;let r=(await Z("adb",on(e,["shell","pm","list","packages"]))).stdout.split("\n").map(e=>e.replace("package:","").trim()).filter(Boolean).filter(e=>e.toLowerCase().includes(n.toLowerCase()));if(1===r.length)return{type:"package",value:r[0]};if(r.length>1)throw new w("INVALID_ARGS",`Multiple packages matched "${t}"`,{matches:r,hint:"Run agent-device apps --platform android to see the exact installed package names before retrying open."});throw new w("APP_NOT_INSTALLED",`No package found matching "${t}"`,{hint:o$})}async function oU(e,t="all"){let n=await oG(e);return("user-installed"===t?(await oB(e)).filter(e=>n.has(e)):Array.from(n)).sort((e,t)=>e.localeCompare(t)).map(e=>({package:e,name:oj(e)}))}async function oG(e){let t=new Set;for(let n of oV(e,{includeFallbackWhenUnknown:!0})){let a=await Z("adb",on(e,["shell","cmd","package","query-activities","--brief","-a","android.intent.action.MAIN","-c",n]),{allowFailure:!0});if(0===a.exitCode&&0!==a.stdout.trim().length)for(let e of eh(a.stdout))t.add(e)}return t}function oV(e,t={}){return"tv"===e.target?[oT]:"mobile"===e.target?[oP]:t.includeFallbackWhenUnknown?[oP,oT]:[oP]}async function oB(e){return em((await Z("adb",on(e,["shell","pm","list","packages","-3"]))).stdout)}function oj(e){let t=new Set(["com","android","google","app","apps","service","services","mobile","client"]),n=e.split(".").flatMap(e=>e.split(/[_-]+/)).map(e=>e.trim().toLowerCase()).filter(e=>e.length>0),a=n[n.length-1]??e;for(let e=n.length-1;e>=0;e-=1){let r=n[e];if(!t.has(r)){a=r;break}}return a.split(/[^a-z0-9]+/i).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(" ")}async function oq(e){let t=await oX(e,[["shell","dumpsys","window","windows"],["shell","dumpsys","window"]]);if(t)return t;let n=await oX(e,[["shell","dumpsys","activity","activities"],["shell","dumpsys","activity"]]);return n||{}}async function oX(e,t){for(let n of t){let t=ef((await Z("adb",on(e,n),{allowFailure:!0})).stdout??"");if(t)return t}return null}async function oz(e,t,n){var a,r;let i;e.booted||await o_(e.id);let o=t.trim();if(oi(o)){if(n)throw new w("INVALID_ARGS","Activity override is not supported when opening a deep link URL");await Z("adb",on(e,["shell","am","start","-W","-a","android.intent.action.VIEW","-d",o]));return}let s=await oF(e,t),l=oV(e)[0]??oP;if("intent"===s.type){if(n)throw new w("INVALID_ARGS","Activity override requires a package name, not an intent");await Z("adb",on(e,["shell","am","start","-W","-a",s.value]));return}if(n){let t=n.includes("/")?n:`${s.value}/${n.startsWith(".")?n:`.${n}`}`;try{await Z("adb",on(e,["shell","am","start","-W","-a","android.intent.action.MAIN","-c",oL,"-c",l,"-n",t]))}catch(t){throw await oY(e,s.value,t),t}return}let d=await Z("adb",on(e,["shell","am","start","-W","-a","android.intent.action.MAIN","-c",oL,"-c",l,"-p",s.value]),{allowFailure:!0});if(0===d.exitCode&&(a=d.stdout,r=d.stderr,i=`${a}
|
|
11
|
-
${r}`,!/Error:.*(?:Activity not started|unable to resolve Intent)/i.test(i)))return;let u=await
|
|
12
|
-
${n.stderr}`;return!!(0===n.exitCode&&/\bpackage:/i.test(a))||(
|
|
13
|
-
${String(n.details?.stderr??"")}`:"")||!await
|
|
14
|
-
${a.stderr}`.toLowerCase();if(!e.includes("unknown package")&&!e.includes("not installed"))throw new w("COMMAND_FAILED",`adb uninstall failed for ${n.value}`,{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode})}return{package:n.value}}let o1=null;async function o2(){let e=`${process.env.PATH??""}::${process.env.AGENT_DEVICE_BUNDLETOOL_JAR??""}`;if(o1?.key===e)return o1.invocation;if(await ee("bundletool")){let t={cmd:"bundletool",prefixArgs:[]};return o1={key:e,invocation:t},t}let t=await Q(process.env.AGENT_DEVICE_BUNDLETOOL_JAR,"AGENT_DEVICE_BUNDLETOOL_JAR");if(!t)throw new w("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 o1={key:e,invocation:n},n}async function o3(e){let t=await o2();await Z(t.cmd,[...t.prefixArgs,...e])}async function o4(e,t){let n,a=await r.mkdtemp(o.join(s.tmpdir(),"agent-device-aab-")),i=o.join(a,"bundle.apks"),l=(n=process.env.AGENT_DEVICE_ANDROID_BUNDLETOOL_MODE?.trim())&&n.length>0?n:"universal";try{await o3(["build-apks","--bundle",t,"--output",i,"--mode",l]),await o3(["install-apks","--apks",i,"--device-id",e.id])}finally{await r.rm(a,{recursive:!0,force:!0})}}async function o5(e,t){".aab"===o.extname(t).toLowerCase()?await o4(e,t):await Z("adb",on(e,["install","-r",t]))}async function o8(e){return new Set((await Z("adb",on(e,["shell","pm","list","packages"]))).stdout.split("\n").map(e=>e.replace("package:","").trim()).filter(Boolean))}async function o6(e,t){let n=Array.from(await o8(e)).filter(e=>!t.has(e));if(1===n.length)return n[0]}async function o9(e,t){e.booted||await o_(e.id),await o5(e,t)}async function o7(e,t,n){let a=n?void 0:await o8(e);return await o9(e,t),n??(a?await o6(e,a):void 0)}async function se(e,t){e.booted||await o_(e.id);let n=await oO({kind:"path",path:t});try{let t=await o7(e,n.installablePath,n.packageName),a=t?oj(t):void 0;return{archivePath:n.archivePath,installablePath:n.installablePath,packageName:t,appName:a,launchTarget:t}}finally{await n.cleanup()}}async function st(e,t,n){e.booted||await o_(e.id);let{package:a}=await o0(e,t),r=await oO({kind:"path",path:n},{resolveIdentity:!1});try{return await o9(e,r.installablePath),{package:a}}finally{await r.cleanup()}}function sn(e){let t=e.direction,n="up"===t||"down"===t?e.referenceHeight:e.referenceWidth,a=function(e){if(void 0===e)return .6;if(!Number.isFinite(e)||e<=0)throw new w("INVALID_ARGS","scroll amount must be a positive number");return e}(e.amount),r=void 0!==e.pixels?function(e){if(!Number.isFinite(e)||e<=0)throw new w("INVALID_ARGS","scroll pixels must be a positive integer");return Math.max(1,Math.round(e))}(e.pixels):Math.round(n*a),i=Math.max(1,Math.round(.05*n)),o=Math.max(1,Math.min(r,Math.max(1,n-2*i))),s=Math.round(o/2),l=Math.round(e.referenceWidth/2),d=Math.round(e.referenceHeight/2),u=(n,a,r,i)=>({direction:t,x1:n,y1:a,x2:r,y2:i,referenceWidth:e.referenceWidth,referenceHeight:e.referenceHeight,amount:e.amount,pixels:o});switch(t){case"up":return u(l,d-s,l,d+s);case"down":return u(l,d+s,l,d-s);case"left":return u(l-s,d,l+s,d);case"right":return u(l+s,d,l-s,d)}}function sa(e,t,n){let a=function(e){let t=0,n=0,a=[...e.children];for(;a.length>0;){let e=a.pop();t+=1,n=Math.max(n,e.depth),a.push(...e.children)}return{rawNodeCount:t,maxDepth:n}}(e),r=[],i=[],o=!1,s=n.depth??1/0,l=n.scope?function(e,t){let n=t.toLowerCase(),a=[...e.children],r=0;for(;r<a.length;){let e=a[r++],t=e.label?.toLowerCase()??"",i=e.value?.toLowerCase()??"",o=e.identifier?.toLowerCase()??"";if(t.includes(n)||i.includes(n)||o.includes(n))return e;a.push(...e.children)}return null}(e,n.scope):null,d=l?[l]:e.children,u=new Map,c=e=>{let t=u.get(e);if(void 0!==t)return t;for(let t of e.children)if(t.hittable||c(t))return u.set(e,!0),!0;return u.set(e,!1),!1},p=(e,a,l,d=!1,u=!1)=>{var f,h,m,w,g,y;let b,v,A,I,x,N,S,_;if(r.length>=t){o=!0;return}if(a>s)return;let M=!!n.raw||(f=e,h=n,m=d,w=c(e),g=u,v=sl(f.type),A=!!(f.label&&f.label.trim().length>0),I=!!(f.identifier&&f.identifier.trim().length>0),x=A&&!sd(f.label??""),N=I&&!sd(f.identifier??""),S=(b=(y=v).split(".").pop()??y).includes("layout")||"viewgroup"===b||"view"===b,_="imageview"===v||"imagebutton"===v,h.interactiveOnly?!!(f.hittable||ej(v)&&w)||!!(x||N)&&!_&&(!S||!!g)&&(m||w||g):h.compact?x||N||!!f.hittable:!S&&!_||!!f.hittable||!!x||!!N&&!!w||w),k=l;M&&(k=r.length,i.push(e),r.push({index:k,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:a,parentIndex:l,...e.hiddenContentAbove?{hiddenContentAbove:!0}:{},...e.hiddenContentBelow?{hiddenContentBelow:!0}:{}}));let D=d||!!e.hittable,E=u||function(e){if(!e)return!1;let t=sl(e);return t.includes("recyclerview")||t.includes("listview")||t.includes("gridview")}(e.type);for(let t of e.children)if(p(t,a+1,k,D,E),o)return};for(let e of d)if(p(e,0,void 0,!1,!1),o)break;return o?{nodes:r,sourceNodes:i,truncated:o,analysis:a}:{nodes:r,sourceNodes:i,analysis:a}}function sr(e){let t=function(e){let t=new Map,n=e.indexOf(" "),a=e.lastIndexOf(">");if(n<0||a<=n)return t;let r=/([^\s=/>]+)\s*=\s*(["'])([\s\S]*?)\2/y,i=n;for(;i<a;){for(;i<a;){let t=e[i];if(" "!==t&&"\n"!==t&&"\r"!==t&&" "!==t)break;i+=1}if(i>=a)break;let n=e[i];if("/"===n||">"===n)break;r.lastIndex=i;let o=r.exec(e);if(!o)break;t.set(o[1],o[3]),i=r.lastIndex}return t}(e),n=e=>{let n=si(t,e);if(null!==n)return"true"===n};return{text:si(t,"text"),desc:si(t,"content-desc"),resourceId:si(t,"resource-id"),className:si(t,"class"),bounds:si(t,"bounds"),clickable:n("clickable"),enabled:n("enabled"),focusable:n("focusable"),focused:n("focused")}}function si(e,t){return e.get(t)??null}function so(e){if(!e)return;let t=/\[(\d+),(\d+)\]\[(\d+),(\d+)\]/.exec(e);if(!t)return;let n=Number(t[1]),a=Number(t[2]);return{x:n,y:a,width:Math.max(0,Number(t[3])-n),height:Math.max(0,Number(t[4])-a)}}function ss(e){let t={type:null,label:null,value:null,identifier:null,depth:-1,children:[]},n=[t],a=/<node\b[^>]*>|<\/node>/g,r=a.exec(e);for(;r;){let t=r[0];if(t.startsWith("</node")){n.length>1&&n.pop(),r=a.exec(e);continue}let i=sr(t),o=so(i.bounds),s=n[n.length-1],l={type:i.className,label:i.text||i.desc,value:i.text,identifier:i.resourceId,rect:o,enabled:i.enabled,hittable:i.clickable??i.focusable,depth:s.depth+1,parentIndex:void 0,children:[]};s.children.push(l),t.endsWith("/>")||n.push(l),r=a.exec(e)}return t}function sl(e){return e?e.toLowerCase():""}function sd(e){let t=e.trim();return!!t&&/^[\w.]+:id\/[\w.-]+$/i.test(t)}function su(e){if(0===e.length)return null;let t=[...e].sort((e,t)=>e-t);return t[Math.floor(t.length/2)]??null}function sc(e,t){let n=Math.max(24,Math.round(.2*Math.min(e.size,t.size))),a=Math.max(48,Math.round(.15*Math.min(e.crossSize,t.crossSize)));return Math.abs(e.size-t.size)<=n&&Math.abs(e.crossSize-t.crossSize)<=a}function sp(e,t){return{start:e.y-t.y,size:e.height,crossSize:e.width}}async function sf(e,t={}){let n=await sm(e);if(!t.interactiveOnly){let a=function(e,t){let{sourceNodes:n,...a}=sa(ss(e),800,t);return a}(n,t);return function(e,t){for(let[n,a]of e){let e=t[n];e&&(a.hiddenContentAbove&&(e.hiddenContentAbove=!0),a.hiddenContentBelow&&(e.hiddenContentBelow=!0))}}(await sh(e,a.nodes),a.nodes),a}let a=ss(n),r=sa(a,800,{...t,interactiveOnly:!1}),i=sa(a,800,t),o=await sh(e,r.nodes);sv(o,r,i),0===o.size&&sv(function(e){if(0===e.length)return new Map;let{hintedContainers:t}=ez(e);var n=t.directionsByContainer;let a=new Map;for(let[e,t]of n){let n={};t.has("above")&&(n.hiddenContentAbove=!0),t.has("below")&&(n.hiddenContentBelow=!0),(n.hiddenContentAbove||n.hiddenContentBelow)&&a.set(e,n)}return a}(B(r.nodes)),r,i);let{sourceNodes:s,...l}=i;return l}async function sh(e,t){if(!t.some(e=>ej(e.type)))return new Map;let n=await sb(e);return n?function(e,t){let n=function(e){let t={className:"root",rect:{x:0,y:0,width:0,height:0},children:[]},n=[{indent:-1,node:t}],a=/^(\s*)([\w.$]+)\{[^}]* (-?\d+),(-?\d+)-(-?\d+),(-?\d+) #/;for(let t of e.split("\n")){let e=a.exec(t);if(!e)continue;let r=e[1].length,i=Number(e[3]),o=Number(e[4]),s=Number(e[5]),l=Number(e[6]),d={className:e[2],rect:{x:i,y:o,width:Math.max(0,s-i),height:Math.max(0,l-o)},children:[]};for(;n.length>1&&r<=n[n.length-1].indent;)n.pop();n[n.length-1].node.children.push(d),n.push({indent:r,node:d})}return t.children.length>0?t:null}(t);if(!n)return new Map;let a=function(e){let t=[],n=[e];for(;n.length>0;){let e=n.pop();if(ej(e.className)){let n=function(e){let t=e.children[0];if(!t)return null;let n=Math.max(t.rect.height,...t.children.map(e=>e.rect.y+e.rect.height)),a=t.children.filter(e=>e.rect.height>0).map(t=>sp(t.rect,e.rect)).sort((e,t)=>e.start-t.start);return 0===a.length?null:{rect:e.rect,contentExtent:n,contentBlocks:a}}(e);n&&t.push(n)}n.push(...e.children)}return t}(n);if(0===a.length)return new Map;let r=new Map;for(let t of e){if(!t.rect||!ej(t.type))continue;let n=function(e,t){let n=null,a=1/0;for(let r of t){let t=Math.abs(r.rect.width-e.width)+Math.abs(r.rect.height-e.height);if(t>32)continue;let i=4*t+(Math.abs(r.rect.x-e.x)+Math.abs(r.rect.y-e.y));i<a&&(n=r,a=i)}return n}(t.rect,a);if(!n)continue;let i=function(e,t){let n=function(e,t){let n=t,a=new Set;for(;!a.has(n.index);){var r,i;a.add(n.index);let o=e.filter(e=>e.parentIndex===n.index&&e.rect);if(1!==o.length)return n;let s=o[0];if(r=s.rect,i=t.rect,r.x!==i.x||r.y!==i.y||r.width!==i.width||r.height!==i.height)return n;n=s}return t}(e,t);return e.filter(e=>e.parentIndex===n.index&&e.rect).map(e=>e.rect).filter(e=>e.height>0).sort((e,t)=>e.y-t.y).map(e=>sp(e,t.rect))}(e,t),o=function(e){let{viewportRect:t,visibleBlocks:n,nativeScrollView:a}=e;if(0===n.length||0===a.contentBlocks.length)return null;let r=function(e){if(0===e.contentBlocks.length)return null;let t=e.contentBlocks[0],n=e.contentBlocks[e.contentBlocks.length-1];if(!t||!n)return null;let a=su(e.contentBlocks.map(e=>e.size))??e.rect.height,r=Math.max(48,Math.round(.5*a)),i=Math.max(24,Math.round(.25*a)),o=t.start>=r,s=e.contentExtent-(n.start+n.size)>=i;return o||s?{above:o,below:s}:null}(a),i=function(e,t){let n=new Map;for(let a of e)for(let e of t){if(!sc(a,e))continue;let t=a.start-e.start,r=8*Math.round(t/8),i=n.get(r)??[];i.push(t),n.set(r,i)}let a=null;for(let e of n.values())(!a||e.length>a.length)&&(a=e);if(!a||a.length<2)return null;let r=[...a].sort((e,t)=>e-t);return r[Math.floor(r.length/2)]??null}(a.contentBlocks,n)??function(e){let{nativeBlocks:t,visibleBlocks:n,viewportExtent:a,contentExtent:r}=e,i=[],o=[];for(let e of t)for(let t of n){if(!sc(e,t))continue;let n=e.start-t.start;16>=Math.abs(n)&&i.push(n),16>=Math.abs(n+a-r)&&o.push(n)}return o.length>0?su(o):i.length>0?su(i):null}({nativeBlocks:a.contentBlocks,visibleBlocks:n,viewportExtent:t.height,contentExtent:a.contentExtent});if(null===i)return r;let o=t.height;return{above:(r?.above??!1)||i>16,below:(r?.below??!1)||i+o<a.contentExtent-16}}({viewportRect:t.rect,visibleBlocks:i,nativeScrollView:n});if(!o)continue;let s={};o.above&&(s.hiddenContentAbove=!0),o.below&&(s.hiddenContentBelow=!0),(s.hiddenContentAbove||s.hiddenContentBelow)&&r.set(t.index,s)}return r}(t,n):new Map}async function sm(e){try{return await rd(()=>sw(e),{shouldRetry:sy})}catch(e){if(function(e){if(!(e instanceof w)||"COMMAND_FAILED"!==e.code||"number"!=typeof e.details?.timeoutMs)return!1;let t=e.details?.cmd,n=e.details?.args,a=Array.isArray(n)?n.map(String):"string"==typeof n?n.split(/\s+/):[];return"adb"===t&&a.includes("uiautomator")&&a.includes("dump")}(e)){let t="If the app has looping animations, use screenshot as visual truth, try settings animations off, then retry snapshot. Stock Android UIAutomator may still time out on app-owned infinite animations.";throw new w("COMMAND_FAILED",`Android UI hierarchy dump timed out while waiting for the UI to become idle. ${t}`,{...e.details??{},hint:t},e)}throw e}}async function sw(e){var t,n,a;let r,i,o=await Z("adb",on(e,["exec-out","uiautomator","dump","/dev/tty"]),{allowFailure:!0,timeoutMs:8e3}),s=sg(o.stdout,o.stderr);if(s)return s;let l="/sdcard/window_dump.xml",d=await Z("adb",on(e,["shell","uiautomator","dump",l]),{allowFailure:!0,timeoutMs:8e3}),u=(t=l,n=d.stdout,a=d.stderr,r=`${n}
|
|
15
|
-
${a}`,i=/dumped to:\s*(\S+)/i.exec(r),i?.[1]??t),c=await
|
|
16
|
-
${t}`,a=n.indexOf("<?xml"),r=a>=0?a:n.indexOf("<hierarchy");if(r<0)return null;let i=n.lastIndexOf("</hierarchy>");if(i<0||i<r)return null;let o=n.slice(r,i+12).trim();return o.length>0?o:null}function
|
|
17
|
-
${t.stderr}`.trim();return n.length>0?n:null}catch{return null}}function sv(e,t,n){if(0===e.size)return;let a=new Map;for(let[e,t]of n.sourceNodes.entries()){let r=n.nodes[e];r&&a.set(t,r)}for(let[n,r]of e){let e=t.sourceNodes[n];if(!e)continue;let i=a.get(e);i&&(r.hiddenContentAbove&&(i.hiddenContentAbove=!0),r.hiddenContentBelow&&(i.hiddenContentBelow=!0))}}async function sA(e,t,n){await Z("adb",on(e,["shell","input","tap",String(t),String(n)]))}async function sI(e,t,n,a,r,i=250){await Z("adb",on(e,["shell","input","swipe",String(t),String(n),String(a),String(r),String(i)]))}async function sx(e){await Z("adb",on(e,["shell","input","keyevent","4"]))}async function sN(e){await Z("adb",on(e,["shell","input","keyevent","3"]))}async function sS(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 w("INVALID_ARGS",`Unsupported Android rotation: ${e}`)}}(t);await Z("adb",on(e,["shell","settings","put","system","accelerometer_rotation","0"])),await Z("adb",on(e,["shell","settings","put","system","user_rotation",n]))}async function s_(e){await Z("adb",on(e,["shell","input","keyevent","187"]))}async function sM(e,t,n,a=800){await Z("adb",on(e,["shell","input","swipe",String(t),String(n),String(t),String(n),String(a)]))}async function sk(e,t,n=0){n>0&&Array.from(t).length>1?await sL(e,t,1,n):await sD(e,t)}async function sD(e,t){let n=s$(t);if(!n||"ok"!==await sF(e,t))try{let n=t.replace(/ /g,"%s");await Z("adb",on(e,["shell","input","text",n]))}catch(e){if(n&&function(e){if(!(e instanceof w)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details?.stderr,n=("string"==typeof t?t:"").toLowerCase();return!!(n.includes("exception occurred while executing 'text'")||n.includes("nullpointerexception")&&n.includes("inputshellcommand.sendtext"))}(e))throw new w("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 sE(e,t,n){await sA(e,t,n)}async function sO(e,t,n,a,r=0){let i=Array.from(a).length,o=s$(a),s=[{strategy:"input_text",clearPadding:12,minClear:8,maxClear:48}];!o&&r<=0&&s.push({strategy:"clipboard_paste",clearPadding:12,minClear:8,maxClear:48}),(!o||r>0)&&s.push({strategy:"chunked_input",clearPadding:24,minClear:16,maxClear:96});let l=null;for(let o of s){var d,u;await sE(e,t,n);let s=(d=i+o.clearPadding,u=o.minClear,Math.max(u,Math.min(o.maxClear,d)));if(await sU(e,s),"input_text"===o.strategy)await sk(e,a,r);else if("clipboard_paste"===o.strategy){if("ok"!==await sF(e,a))continue}else await sL(e,a,1,r>0?r:15);let c=await sC(e,t,n,a);if(l=c.actual,c.ok)return}throw new w("COMMAND_FAILED","Android fill verification failed",{expected:a,actual:l??null})}async function sC(e,t,n,a){let r=null;for(let i of[0,150,350])if(i>0&&await er(i),function(e,t){if(e===t)return!0;let n=sR(e),a=sR(t);return!!n&&!!a&&(!!(n===a||n.includes(a))||a.includes(n)&&n.length>=Math.max(4,Math.floor(.8*a.length)))}(r=await sG(e,t,n),a))return{ok:!0,actual:r};return{ok:!1,actual:r}}function sR(e){return(e??"").replace(/\s+/g," ").trim()}async function sP(e,t,n){let a=await sT(e),r=sn({direction:t,amount:n?.amount,pixels:n?.pixels,referenceWidth:a.width,referenceHeight:a.height});return await Z("adb",on(e,["shell","input","swipe",String(r.x1),String(r.y1),String(r.x2),String(r.y2),"300"])),r}async function sT(e){let t=(await Z("adb",on(e,["shell","wm","size"]))).stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(!t)throw new w("COMMAND_FAILED","Unable to read screen size");return{width:Number(t[1]),height:Number(t[2])}}async function sL(e,t,n,a){let r=Math.max(1,Math.floor(n)),i=Array.from(t);for(let t=0;t<i.length;t+=r){let n=i.slice(t,t+r).join("");await sD(e,n),a>0&&t+r<i.length&&await er(a)}}function s$(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 sF(e,t){let n=await Z("adb",on(e,["shell","cmd","clipboard","set","text",t]),{allowFailure:!0});return 0!==n.exitCode?"failed":or(n.stdout,n.stderr)?"unsupported":0===(await Z("adb",on(e,["shell","input","keyevent","KEYCODE_PASTE"]),{allowFailure:!0})).exitCode||0===(await Z("adb",on(e,["shell","input","keyevent","279"]),{allowFailure:!0})).exitCode?"ok":"failed"}async function sU(e,t){let n=Math.max(0,t);await Z("adb",on(e,["shell","input","keyevent","KEYCODE_MOVE_END"]),{allowFailure:!0});for(let t=0;t<n;t+=24){let a=Math.min(24,n-t);await Z("adb",on(e,["shell","input","keyevent",...Array(a).fill("KEYCODE_DEL")]),{allowFailure:!0})}}async function sG(e,t,n){let a,r=await sm(e),i=/<node\b[^>]*>/g,o=null,s=null,l=null;for(;null!==(a=i.exec(r));){let e=sr(a[0]),r=so(e.bounds);if(!r)continue;let i=e.className??"",d=(e.text??"").replace(/"/g,'"').replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">").replace(/&/g,"&"),u=e.focused??!1;if(!d)continue;let c=Math.max(1,r.width*r.height),p=t>=r.x&&t<=r.x+r.width&&n>=r.y&&n<=r.y+r.height;if(u&&sV(i)){(!o||c<=o.area)&&(o={text:d,area:c});continue}if(p&&sV(i)){(!s||c<=s.area)&&(s={text:d,area:c});continue}p&&(!l||c<=l.area)&&(l={text:d,area:c})}return o?.text??s?.text??l?.text??null}function sV(e){let t=e.toLowerCase();return t.includes("edittext")||t.includes("textfield")}async function sB(e){let t=await Z("adb",on(e,["shell","dumpsys","input_method"]),{allowFailure:!0});if(0!==t.exitCode)throw new w("COMMAND_FAILED","Failed to query Android keyboard state",{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode});return function(e){let t=function(e){let t=new Map;for(let n of e.matchAll(/\b(mInputShown|mIsInputViewShown|isInputViewShown)=([a-zA-Z]+)\b/g)){let e=n[1],a=n[2]?.toLowerCase();e&&("true"===a||"false"===a)&&t.set(e,"true"===a)}if(0===t.size)return null;for(let e of t.values())if(e)return!0;return!1}(e),n=t??!1;if(null===t){let t=e.match(/\bmImeWindowVis=0x([0-9a-fA-F]+)\b/);if(t?.[1]){let e=Number.parseInt(t[1],16);Number.isNaN(e)||(n=(1&e)!=0)}}let a=Array.from(e.matchAll(/\binputType=0x([0-9a-fA-F]+)\b/gi)),r=a.length>0?a[a.length-1]?.[1]:void 0,i=r?`0x${r.toLowerCase()}`:void 0;return{visible:n,inputType:i,type:i?function(e){let t=Number.parseInt(e.replace(/^0x/i,""),16);if(Number.isNaN(t))return"unknown";let n=15&t;if(2===n)return"number";if(3===n)return"phone";if(4===n)return"datetime";if(1!==n)return"unknown";let a=4080&t;return 32===a||208===a?"email":128===a||224===a||144===a?"password":"text"}(i):void 0}}(t.stdout)}async function sj(e){let t=await sB(e),n=t,a=0;for(;n.visible&&a<2;)await Z("adb",on(e,["shell","input","keyevent","111"])),a+=1,await er(120),n=await sB(e);if(t.visible&&n.visible)throw new w("UNSUPPORTED_OPERATION","Android keyboard dismiss is unavailable for the current IME without back navigation.",{attempts:a,inputType:n.inputType,type:n.type});return{attempts:a,wasVisible:t.visible,dismissed:t.visible&&!n.visible,visible:n.visible,inputType:n.inputType,type:n.type}}async function sq(e){let t,n;return(n=(t=(await sz(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 sX(e,t){await sz(e,["shell","cmd","clipboard","set","text",t],"write")}async function sz(e,t,n){let a=await Z("adb",on(e,t),{allowFailure:!0});if(or(a.stdout,a.stderr))throw new w("UNSUPPORTED_OPERATION",`Android shell clipboard ${n} is not supported on this device.`);if(0!==a.exitCode)throw new w("COMMAND_FAILED",`Failed to ${n} Android clipboard text`,{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});return a.stdout}let sW=["camera","microphone","photos","contacts","contacts-limited","notifications","calendar","location","location-always","media-library","motion","reminders","siri"];function sH(e){let t=e.trim().toLowerCase();if("grant"===t)return"grant";if("deny"===t)return"deny";if("reset"===t)return"reset";throw new w("INVALID_ARGS",`Invalid permission action: ${e}. Use grant|deny|reset.`)}function sY(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 w("INVALID_ARGS",`permission setting requires a target: ${sW.join("|")}`)}function sK(e){let t=e.trim().toLowerCase();if("light"===t)return"light";if("dark"===t)return"dark";if("toggle"===t)return"toggle";throw new w("INVALID_ARGS",`Invalid appearance state: ${e}. Use light|dark|toggle.`)}let sJ=["window_animation_scale","transition_animation_scale","animator_duration_scale"];async function sZ(e,t,n,a,r){switch(t.toLowerCase()){case"wifi":{let t=s0(n);await Z("adb",on(e,["shell","svc","wifi",t?"enable":"disable"]));return}case"airplane":{let t=s0(n);await Z("adb",on(e,["shell","settings","put","global","airplane_mode_on",t?"1":"0"])),await Z("adb",on(e,["shell","am","broadcast","-a","android.intent.action.AIRPLANE_MODE","--ez","state",t?"true":"false"]));return}case"location":{let t=s0(n);await Z("adb",on(e,["shell","settings","put","secure","location_mode",t?"3":"0"]));return}case"animations":{let t=s0(n)?"1":"0";for(let n of sJ)await Z("adb",on(e,["shell","settings","put","global",n,t]));return{scale:t,keys:[...sJ]}}case"appearance":{let t=await s1(e,n);await Z("adb",on(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 w("INVALID_ARGS",`Invalid fingerprint state: ${e}. Use match|nonmatch.`)}(n);await sQ(e,t);return}case"permission":{if(!a)throw new w("INVALID_ARGS","permission setting requires an active app in session");let t=sH(n),i=function(e,t){let n=sY(e);if(t?.trim())throw new w("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 w("INVALID_ARGS",`Unsupported permission target on Android: ${e}. Use camera|microphone|photos|contacts|notifications.`)}(r?.permissionTarget,r?.permissionMode);if("notifications"===i.kind)return void await s3(e,a,t,i);let o="grant"===t?"grant":"revoke";if("photos"===i.type)return void await s2(e,a,o);await Z("adb",on(e,["shell","pm",o,a,i.value]));return}default:throw new w("INVALID_ARGS",`Unsupported setting: ${t}`)}}async function sQ(e,t){var n;let a,r,i=(n=e,r=[["shell","cmd","fingerprint","touch",a="match"===t?"1":"9999"],["shell","cmd","fingerprint","finger",a]],"emulator"===n.kind&&r.push(["emu","finger","touch",a]),r),o=[];for(let t of i){let n=await Z("adb",on(e,t),{allowFailure:!0});if(0===n.exitCode)return;o.push({args:t,stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode})}let s=o.map(e=>({args:e.args.join(" "),exitCode:e.exitCode,stderr:e.stderr.slice(0,400)}));if(o.length>0&&o.every(e=>{var t,n;let a;return t=e.stdout,n=e.stderr,(a=`${t}
|
|
18
|
-
${n}`.toLowerCase()).includes("unknown command")||a.includes("can't find service: fingerprint")||a.includes("service fingerprint was not found")||a.includes("fingerprint cmd unavailable")||a.includes("emu command is not supported")||a.includes("emulator console is not running")||a.includes("fingerprint")&&a.includes("not found")}))throw new
|
|
19
|
-
${t}`);if(!n)return null;let a=n[1].toLowerCase();return"yes"===a?"dark":"no"===a?"light":"auto"===a?"auto":null}(a.stdout,a.stderr);if(!r)throw new
|
|
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
|
|
21
|
-
${t.stderr}`.toLowerCase(),s=o.includes("already booted")||o.includes("current state: booted");if(0!==t.exitCode&&!s)throw new w("COMMAND_FAILED","simctl boot failed",{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode});let l=await Z("xcrun",rR(e,["bootstatus",e.id,"-b"]),{allowFailure:!0,timeoutMs:r});if(n={stdout:String(l.stdout??""),stderr:String(l.stderr??""),exitCode:l.exitCode},0!==n.exitCode)throw new w("COMMAND_FAILED","simctl bootstatus failed",{stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode});let d=await lv(e);if("Booted"!==d)throw new w("COMMAND_FAILED","Simulator is still booting",{state:d})},{maxAttempts:3,baseDelayMs:500,maxDelayMs:2e3,jitter:.2,shouldRetry:e=>{let a=rx({error:e,stdout:n?.stdout??t?.stdout,stderr:n?.stderr??t?.stderr,context:{platform:"ios",phase:"boot"}});return"IOS_BOOT_TIMEOUT"!==a&&"CI_RESOURCE_STARVATION_SUSPECTED"!==a}},{deadline:a,phase:"boot",classifyReason:e=>rx({error:e,stdout:n?.stdout??t?.stdout,stderr:n?.stderr??t?.stderr,context:{platform:"ios",phase:"boot"}})})}catch(i){let r=rx({error:i,stdout:n?.stdout??t?.stdout,stderr:n?.stderr??t?.stderr,context:{platform:"ios",phase:"boot"}});throw new w("COMMAND_FAILED","iOS simulator failed to boot",{platform:"ios",deviceId:e.id,timeoutMs:lt,elapsedMs:a.elapsedMs(),reason:r,hint:rN(r),boot:t,bootstatus:n})}await lg()}async function lb(e){let t=rR(e,["shutdown",e.id]),n=await Z("xcrun",t,{allowFailure:!0,timeoutMs:15e3});return{success:0===n.exitCode,exitCode:n.exitCode,stdout:String(n.stdout??""),stderr:String(n.stderr??"")}}async function lv(e){let t="string"==typeof e?e:e.id,n="string"==typeof e?rC(["list","devices","-j"]):rR(e,["list","devices","-j"]),a=await Z("xcrun",n,{allowFailure:!0,timeoutMs:ln});if(0!==a.exitCode)return null;try{let e=JSON.parse(String(a.stdout??""));for(let n of Object.values(e.devices??{})){let e=n.find(e=>e.udid===t);if(e)return e.state}return null}catch{return null}}async function lA(e,t){try{let n=await Z("plutil",["-extract",t,"raw","-o","-",e],{allowFailure:!0});if(0===n.exitCode){let e=String(n.stdout??"").trim();if(e.length>0)return e}}catch{}try{var n,a;let i;return n=await r.readFile(e,"utf8"),a=t,r8(r5(n),(e,t)=>{void 0===i&&e===a&&"string"===t.name&&(i=t.text??void 0)}),i}catch{return}}async function lI(e,t){if("url"===e.kind&&!ep(e.url))throw new w("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 ec({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||ep(e.url),signal:t?.signal}),a=await lN(n.installablePath,t),r=await lx(a.installPath);return{archivePath:n.archivePath??(n.installablePath.toLowerCase().endsWith(".ipa")?n.installablePath:void 0),installablePath:a.installPath,bundleId:r.bundleId,appName:r.appName,cleanup:async()=>{await a.cleanup(),await n.cleanup()}}}async function lx(e){let t=o.join(e,"Info.plist"),[n,a,r]=await Promise.all([lA(t,"CFBundleIdentifier"),lA(t,"CFBundleDisplayName"),lA(t,"CFBundleName")]);return{bundleId:n,appName:a??r}}async function lN(e,t){if(!e.toLowerCase().endsWith(".ipa"))return{installPath:e,cleanup:async()=>{}};let n=await r.mkdtemp(o.join(s.tmpdir(),"agent-device-ios-ipa-")),a=async()=>{await r.rm(n,{recursive:!0,force:!0})};try{await Z("unzip",["-q",e,"-d",n]);let i=o.join(n,"Payload"),s=(await r.readdir(i,{withFileTypes:!0}).catch(()=>{throw new w("INVALID_ARGS","Invalid IPA: missing Payload directory")})).filter(e=>e.isDirectory()&&e.name.toLowerCase().endsWith(".app")).map(e=>({installPath:o.join(i,e.name),bundleName:e.name.replace(/\.app$/i,"")}));if(1===s.length)return{installPath:s[0].installPath,cleanup:a};if(0===s.length)throw new w("INVALID_ARGS","Invalid IPA: expected at least one .app under Payload, found 0");await lS(s);let l=t?.appIdentifierHint?.trim();if(l){let e=function(e,t){let n=t.toLowerCase(),a=e.filter(e=>e.bundleName.toLowerCase()===n);if(1===a.length)return a[0];if(a.length>1)throw new w("INVALID_ARGS",`Invalid IPA: multiple app bundles matched "${t}" by name. Use a bundle id hint instead.`);if(t.includes(".")){let t=e.filter(e=>e.bundleId?.toLowerCase()===n);if(1===t.length)return t[0]}}(s,l);if(e)return{installPath:e.installPath,cleanup:a};throw new w("INVALID_ARGS",`Invalid IPA: found ${s.length} .app bundles under Payload and none matched "${l}". Available bundles: ${s.map(l_).join(", ")}`)}throw new w("INVALID_ARGS",`Invalid IPA: found ${s.length} .app bundles under Payload. Pass an app identifier or bundle name matching one of: ${s.map(l_).join(", ")}`)}catch(e){throw await a(),e}}async function lS(e){await Promise.all(e.map(async e=>{if(e.bundleId&&e.appName)return;let t=await lx(e.installPath);e.bundleId=e.bundleId??t.bundleId,e.appName=e.appName??t.appName}))}function l_(e){let t=e.bundleId??e.appName;return t?`${e.bundleName}.app (${t})`:`${e.bundleName}.app`}function lM(e,t){return"user-installed"===t?e.filter(e=>!e.bundleId.startsWith("com.apple.")):e}let lk={settings:"com.apple.systempreferences"},lD=/^[a-z0-9-]+(?:\.[a-z0-9-]+)+$/;function lE(e,t){let n=["-b",e];return t&&n.push(t),n}async function lO(e){for(let t of[o.join(e,"Contents","Info.plist"),o.join(e,"Info.plist")]){let[e,n,a]=await Promise.all([lA(t,"CFBundleIdentifier"),lA(t,"CFBundleDisplayName"),lA(t,"CFBundleName")]);if(e||n||a)return{bundleId:e,appName:n??a}}return{}}async function lC(e){let t=e.trim(),n=lk[t.toLowerCase()];if(n)return n;if(lD.test(t))return t;let a=(await lU("all")).filter(e=>e.name.toLowerCase()===t.toLowerCase());if(1===a.length)return a[0].bundleId;if(a.length>1)throw new w("INVALID_ARGS",`Multiple apps matched "${e}"`,{matches:a});throw new w("APP_NOT_INSTALLED",`No app found matching "${e}"`)}async function lR(e,t,n){let a=n?.url?.trim();if(a){if(!oi(a))throw new w("INVALID_ARGS","open <app> <url> requires a valid URL target");let e=n?.appBundleId??await lC(t);await Z("open",lE(e,a));return}let r=t.trim();if(oi(r))return void await Z("open",[r]);let i=n?.appBundleId??await lC(r);await Z("open",lE(i))}async function lP(e,t){let n=await lC(t),a=await i5(n);if(a.running&&!a.terminated&&!a.forceTerminated)throw new w("COMMAND_FAILED",`Failed to close macOS app ${t}`,{bundleId:n,running:a.running,terminated:a.terminated,forceTerminated:a.forceTerminated})}async function lT(){let e=await Z("pbpaste",[],{allowFailure:!0});if(0!==e.exitCode)throw new w("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 lL(e){let t=await Z("pbcopy",[],{allowFailure:!0,stdin:e});if(0!==t.exitCode)throw new w("COMMAND_FAILED","Failed to write macOS clipboard",{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode})}async function l$(){let e=await Z("osascript",["-e",'tell application "System Events" to tell appearance preferences to get dark mode'],{allowFailure:!0});if(0!==e.exitCode)throw new w("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 w("COMMAND_FAILED",`Unable to determine current macOS appearance from osascript output: ${e.stdout.trim()}`)}async function lF(e){let t=sK(e),n="toggle"===t?!await l$():"dark"===t,a=`tell application "System Events" to tell appearance preferences to set dark mode to ${n?"true":"false"}`,r=await Z("osascript",["-e",a],{allowFailure:!0});if(0!==r.exitCode)throw new w("COMMAND_FAILED","Failed to set macOS appearance",{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode})}async function lU(e="all"){let t=["/Applications","/System/Applications",o.join(s.homedir(),"Applications")],n=new Set;for(let e of t){let t=await r.stat(e).catch(()=>null);if(!t?.isDirectory())continue;let a=await Z("find",[e,"-maxdepth","4","-type","d","-name","*.app"],{allowFailure:!0});if(0===a.exitCode)for(let e of a.stdout.split("\n")){let t=e.trim();t&&n.add(t)}}return lM((await Promise.all(Array.from(n).map(async e=>{let t=await lO(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 lG=["--time","9:41","--dataNetwork","wifi","--wifiMode","active","--wifiBars","3","--batteryState","charged","--batteryLevel","100"],lV={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"},lB={1:"searching",2:"failed",3:"active"},lj={0:"notSupported",1:"searching",2:"failed",3:"active"};function lq(e,t,n){return Z("xcrun",rR(e,t),n)}async function lX(e,t){var n,a;let r;await lW(e),t&&await lH(e,(r=[],(n=t).dataNetwork&&r.push("--dataNetwork",n.dataNetwork),n.wifiMode&&r.push("--wifiMode",n.wifiMode),void 0!==n.wifiBars&&("wifi"===n.dataNetwork||n.wifiMode)&&r.push("--wifiBars",n.wifiBars),n.cellularMode&&r.push("--cellularMode",n.cellularMode),void 0!==n.cellularBars&&(n.cellularMode||(a=n.dataNetwork)&&"hide"!==a&&"wifi"!==a||void 0!==n.operatorName)&&r.push("--cellularBars",n.cellularBars),void 0!==n.operatorName&&r.push("--operatorName",n.operatorName),r))}async function lz(e){let t=await lq(e,["status_bar",e.id,"list"],{allowFailure:!0});if(0!==t.exitCode)throw new w("COMMAND_FAILED","Failed to read simulator status bar overrides",{exitCode:t.exitCode,stdout:t.stdout,stderr:t.stderr});return function(e){let t={};for(let n of e.split("\n").map(e=>e.trim()).filter(e=>e.length>0&&"Current Status Bar Overrides:"!==e&&!/^=+$/.test(e))){let e=/^DataNetworkType:\s+(\d+)$/.exec(n);if(e){let n=Number(e[1]),a=lV[n];if(!a)throw new w("COMMAND_FAILED",`Unsupported simulator data network type: ${n}`);t.dataNetwork=a;continue}let a=/^WiFi Mode:\s+(\d+),\s+WiFi Bars:\s+(\d+)$/.exec(n);if(a){let e=lB[Number(a[1])];e&&(t.wifiMode=e),t.wifiBars=a[2];continue}let r=/^Cell Mode:\s+(\d+),\s+Cell Bars:\s+(\d+)$/.exec(n);if(r){let e=Number(r[1]),n=lj[e];if(!n)throw new w("COMMAND_FAILED",`Unsupported simulator cellular mode: ${e}`);t.cellularMode=n,t.cellularBars=r[2];continue}let i=/^Operator Name:\s*(.*)$/.exec(n);if(i){t.operatorName=i[1]??"";continue}}return 0===Object.keys(t).length?null:t}(t.stdout)}async function lW(e){await lq(e,["status_bar",e.id,"clear"])}async function lH(e,t){0!==t.length&&await lq(e,["status_bar",e.id,"override",...t])}function lY(e,t,n){W({level:"warn",phase:`ios_screenshot_status_bar_${t}`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,...function(e){if(!(e instanceof w))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 lK(e,t,n){return Z("xcrun",rR(e,t),n)}let lJ={ensureBooted:ly,prepareStatusBarForScreenshot:async function e(e){let t=null,n=!1;try{t=await lz(e),n=!0}catch(t){lY(e,"snapshot_failed",t)}try{await lW(e),await lH(e,lG)}catch(t){lY(e,"prepare_failed",t)}return async()=>{await lX(e,n?t:null)}},captureWithRetry:l0,runnerFallbackEnabled:ll,captureWithRunner:l1,shouldFallbackToRunner:l9};async function lZ(e,t,n,a){if("macos"===e.platform)return void await l1(e,t,n,a);if("simulator"===e.kind)return void await lQ(e,t,n,a);try{await ld(["device","screenshot","--device",e.id,t],{action:"capture iOS screenshot",deviceId:e.id});return}catch(t){if(!function(e){if(!(e instanceof w)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details??{},n="string"==typeof t.stdout?t.stdout:"",a="string"==typeof t.stderr?t.stderr:"",r=`${e.message}
|
|
5
|
+
${n}`.toLowerCase()).includes("device is busy")&&a.includes("connecting")?"Target iOS device is still connecting. Keep it unlocked, wait for device trust/connection to settle, then retry.":rU("IOS_RUNNER_CONNECT_TIMEOUT"))})}function rZ(e){if(rP(e))throw rL()}let rQ=ev(process.env.AGENT_DEVICE_RUNNER_STARTUP_TIMEOUT_MS,45e3,5e3),r0=ev(process.env.AGENT_DEVICE_RUNNER_COMMAND_TIMEOUT_MS,45e3,1e3),r1=ev(process.env.AGENT_DEVICE_RUNNER_CONNECT_ATTEMPT_INTERVAL_MS,250,50),r2=ev(process.env.AGENT_DEVICE_RUNNER_CONNECT_RETRY_BASE_DELAY_MS,300,10),r3=ev(process.env.AGENT_DEVICE_RUNNER_CONNECT_RETRY_MAX_DELAY_MS,2e3,10),r4=ev(process.env.AGENT_DEVICE_RUNNER_CONNECT_REQUEST_TIMEOUT_MS,2e4,250),r5=ev(process.env.AGENT_DEVICE_IOS_DEVICE_INFO_TIMEOUT_MS,1e4,500),r8=eA(process.env.AGENT_DEVICE_RUNNER_DESTINATION_TIMEOUT_SECONDS,20,5),r6=new Map;async function r9(e,t,n,a,r=rQ,i,o){let s,l=rI.fromTimeoutMs(r),d=async(n,a=!1)=>{var r,i,o;let l,d=await ie({device:e,timeoutBudgetMs:n,forceRefresh:a,requestTunnelIp:s,setRequestTunnelIp:e=>{s=e}});return{endpoints:(r=e,i=t,o=d.ip,l=[`http://127.0.0.1:${i}/command`],"device"!==r.kind||o&&l.unshift(`http://[${o}]:${i}/command`),l),cached:d.sharedCacheHit}},{endpoints:u}=await d(l.remainingMs()),c=null,p=Math.max(1,Math.ceil(r/r1));try{return await rx(async({deadline:s})=>{if(s?.isExpired())throw new y("COMMAND_FAILED","Runner connection deadline exceeded",{port:t,timeoutMs:r});if(i&&null!==i.child.exitCode&&void 0!==i.child.exitCode)throw await rJ({session:i,port:t,logPath:a});let l=!1;if("device"===e.kind){let e=await d(s?.remainingMs());u=e.endpoints,l=e.cached}let p=l?u[0]:null,f=await r7(u,{command:n,port:t,timeoutMs:r,signal:o,attemptDeadline:s,onError:(t,n)=>{var a;c=n,"device"===e.kind&&t===p&&(a=e.id,r6.delete(a))}});if(f)return f;if("device"===e.kind&&l){var h;h=e.id,r6.delete(h),u=(await d(s?.remainingMs(),!0)).endpoints;let a=await r7(u,{command:n,port:t,timeoutMs:r,signal:o,attemptDeadline:s,onError:(e,t)=>{c=t}});if(a)return a}if(o?.aborted)throw rL();throw new y("COMMAND_FAILED","Runner endpoint probe failed",{port:t,endpoints:u,lastError:c?String(c):void 0})},{maxAttempts:p,baseDelayMs:r2,maxDelayMs:r3,jitter:.2,shouldRetry:rY},{deadline:l,phase:"ios_runner_connect",signal:o})}catch(e){if(o?.aborted||r$(e))throw rL();c||(c=e)}if(o?.aborted)throw rL();if("simulator"===e.kind){let r=l.remainingMs();if(r<=0)throw rK({port:t,endpoints:u,logPath:a,lastError:c});let i=await ir(e,t,n,r,o);return new Response(i.body,{status:i.status})}throw rK({port:t,endpoints:u,logPath:a,lastError:c})}async function r7(e,t){let{command:n,port:a,timeoutMs:r,signal:i,attemptDeadline:o,onError:s}=t;for(let t of e)try{let e=o?.remainingMs()??r;if(e<=0)throw new y("COMMAND_FAILED","Runner connection deadline exceeded",{port:a,timeoutMs:r});return await it(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)},Math.min(r4,e),i)}catch(e){if(i?.aborted||r$(e))throw rL();s(t,e)}return null}async function ie(e){var t,n,a;let{device:r,timeoutBudgetMs:i,forceRefresh:o,requestTunnelIp:s,setRequestTunnelIp:l}=e;if("device"!==r.kind)return{ip:null,sharedCacheHit:!1};if(!o){let e,n=(t=r.id,(e=r6.get(t))?e.expiresAt<=Date.now()?(r6.delete(t),null):e.ip:null);if(n)return{ip:n,sharedCacheHit:!0};if(void 0!==s)return{ip:s,sharedCacheHit:!1}}let d=await ia(r.id,i);return l(d),d&&(n=r.id,a=d,r6.set(n,{ip:a,expiresAt:Date.now()+3e4})),{ip:d,sharedCacheHit:!1}}async function it(e,t,n,a){let r=AbortSignal.timeout(n),i=a?AbortSignal.any([a,r]):r;return await fetch(e,{...t,signal:i})}async function ia(e,t){if("number"==typeof t&&t<=0)return null;let a="number"==typeof t?Math.max(1,Math.min(r5,t)):r5,r=o.join(s.tmpdir(),`agent-device-devicectl-info-${process.pid}-${Date.now()}.json`);try{let t=Math.max(1,Math.ceil(a/1e3)),i=await ef("xcrun",["devicectl","device","info","details","--device",e,"--json-output",r,"--timeout",String(t)],{allowFailure:!0,timeoutMs:a});if(0!==i.exitCode||!n.existsSync(r))return null;let o=JSON.parse(n.readFileSync(r,"utf8"));if(o.info?.outcome&&"success"!==o.info.outcome)return null;let s=(o.result?.connectionProperties?.tunnelIPAddress??o.result?.device?.connectionProperties?.tunnelIPAddress)?.trim();return s&&s.length>0?s:null}catch{return null}finally{id(r)}}async function ir(e,t,n,a,r){let i=JSON.stringify(n),o=rz(e,["spawn",e.id,"/usr/bin/curl","-s","-X","POST","-H","Content-Type: application/json","--data",i,`http://127.0.0.1:${t}/command`]),s=await ef("xcrun",o,{allowFailure:!0,timeoutMs:a,signal:r}),l=s.stdout;if(0!==s.exitCode){let e=rF({message:"Runner did not accept connection (simctl spawn)",stdout:s.stdout,stderr:s.stderr,context:{platform:"ios",phase:"connect"}});throw new y("COMMAND_FAILED","Runner did not accept connection (simctl spawn)",{port:t,stdout:s.stdout,stderr:s.stderr,exitCode:s.exitCode,reason:e,hint:rU(e)})}return{status:200,body:l}}async function ii(){return await new Promise((e,t)=>{let n=d.createServer();n.listen(0,"127.0.0.1",()=>{let a=n.address();if("object"==typeof a&&a?.port){let t=a.port;n.close(()=>e(t))}else n.close(()=>t(new y("COMMAND_FAILED","Failed to allocate port")))}),n.on("error",t)})}function io(e,t,n,a){t&&il(t,e),n&&il(n,e),a&&process.stderr.write(e)}let is=new Map;function il(e,t){let a=(is.get(e)??Promise.resolve()).catch(()=>{}).then(()=>n.promises.appendFile(e,t)).catch(()=>{}).finally(()=>{is.get(e)===a&&is.delete(e)});is.set(e,a)}function id(e){try{n.existsSync(e)&&n.unlinkSync(e)}catch{}}let iu=new u;async function ic(e,t,n){let a=iu.getStore()??[];if(a.some(n=>n.locks===e&&n.key===t))return await n();let r=(e.get(t)??Promise.resolve()).catch(()=>{}).then(()=>iu.run([...a,{locks:e,key:t}],n));return e.set(t,r),r.finally(()=>{e.get(t)===r&&e.delete(t)})}let ip=new Set(["RUNNER_PRODUCT_MISSING","RUNNER_PRODUCT_REPAIR_FAILED"]);async function ih(e,t,a){if("macos"!==e.platform)return;if(0===t.length)throw new y("COMMAND_FAILED","Missing macOS runner product",{reason:"RUNNER_PRODUCT_MISSING",xctestrunPath:a});let r=Array.from(new Set(t)).sort((e,t)=>t.length-e.length);for(let e of r)if(!n.existsSync(e))throw new y("COMMAND_FAILED","Missing macOS runner product",{reason:"RUNNER_PRODUCT_MISSING",productPath:e,xctestrunPath:a});for(let e of r)if(0!==ep("codesign",["--verify","--deep","--strict",e],{allowFailure:!0}).exitCode){await ef("codesign",["--remove-signature",e],{allowFailure:!0});try{await ef("codesign",["--force","--sign","-",e])}catch(n){let t=n instanceof y?n:new y("COMMAND_FAILED",String(n));throw new y("COMMAND_FAILED","Failed to repair macOS runner product signature",{reason:"RUNNER_PRODUCT_REPAIR_FAILED",productPath:e,xctestrunPath:a,error:t.message,details:t.details})}}}let im=null;function iw(e){return function e(t){if(!Array.isArray(t))return[];let n=[];for(let a of t)if(!(!a||"object"!=typeof a||Array.isArray(a)))for(let[t,r]of Object.entries(a))":@"!==t&&"#text"!==t&&n.push({name:t,attributes:function(e){if(!e||"object"!=typeof e||Array.isArray(e))return{};let t={};for(let[n,a]of Object.entries(e))"string"==typeof a&&(t[n]=a);return t}(a[":@"]),text:iy(r)??iy(a["#text"]),children:e(r)});return n}((im??=new p({ignoreAttributes:!1,attributeNamePrefix:"",preserveOrder:!0,trimValues:!0,parseTagValue:!1})).parse(e))}function ig(e,t){for(let n of e){if("dict"===n.name)for(let e=0;e<n.children.length-1;e+=1){let a=n.children[e],r=n.children[e+1];a?.name==="key"&&a.text&&r&&t(a.text,r)}ig(n.children,t)}}function iy(e){if("string"==typeof e){let t=e.trim();return t.length>0?t:null}if(!Array.isArray(e))return null;let t=e.map(e=>{if(!e||"object"!=typeof e||Array.isArray(e))return null;let t=e["#text"];return"string"==typeof t?t.trim():null}).filter(e=>null!==e&&e.length>0).join("").trim();return t.length>0?t:null}let ib="XCTestDevices",iv=".agent-device-backup",iA=".agent-device-xctestdevices-backup-",iI=o.join(s.homedir(),".agent-device","ios-runner"),ix=new Set(["ProductPaths","DependentProductPaths","TestHostPath","TestBundlePath","UITargetAppPath"]),iS=new Map,iN=new Set;function i_(e){return e?.trim()??""}function iM(e=process.env){return i_(e.AGENT_DEVICE_IOS_BUNDLE_ID)||i_(e.AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID)||"com.callstack.agentdevice.runner"}function ik(e=process.env){let t=i_(e.AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID);return t||`${iM(e)}.uitests`}let iD=function(e=process.env){let t=iM(e),n=ik(e);return Array.from(new Set([i_(e.AGENT_DEVICE_IOS_RUNNER_CONTAINER_BUNDLE_ID),`${n}.xctrunner`,t].filter(e=>e.length>0)))}(process.env);function iE(e=s.homedir()){return o.join(e,"Library","Developer","XCTestDevices")}async function iO(e,t={}){if("ios"!==e.platform||"simulator"!==e.kind)return null;let a=rq(e.simulatorSetPath);if(!a)return null;let r=o.resolve(a),i=o.resolve(t.xctestDeviceSetPath??iE()),l=o.resolve(t.backupPath??function(e=iE()){return`${e}${iv}`}(i)),d=o.resolve(t.lockDirPath??function(e=s.homedir()){return o.join(e,".agent-device","xctest-device-set.lock")}()),u=t.ownerStartTime??eS(process.pid),c=await iP({lockDirPath:d,owner:{pid:t.ownerPid??process.pid,startTime:u,acquiredAtMs:t.nowMs??Date.now()}});try{if(iC({xctestDeviceSetPath:i,backupPath:l}),function(e,t){if(o.resolve(e)===o.resolve(t))return!0;try{return n.realpathSync.native(e)===n.realpathSync.native(t)}catch{return!1}}(r,i))return await c(),null;n.mkdirSync(r,{recursive:!0}),n.existsSync(i)&&n.renameSync(i,l),function(e){let{requestedSetPath:t,xctestDeviceSetPath:a}=e,r=o.dirname(a),i=o.join(r,`${ib}.agent-device-link-${process.pid}-${Date.now()}`);n.mkdirSync(r,{recursive:!0});try{n.symlinkSync(t,i,"dir"),n.renameSync(i,a)}catch(e){throw n.existsSync(i)&&iR(i),e}}({requestedSetPath:r,xctestDeviceSetPath:i})}catch(e){throw iC({xctestDeviceSetPath:i,backupPath:l}),await c(),new y("COMMAND_FAILED","Failed to redirect XCTest device set path",{requestedSetPath:r,xctestDeviceSetPath:i,backupPath:l,error:String(e)})}let p=!1;return{release:async()=>{if(!p){p=!0;try{iC({xctestDeviceSetPath:i,backupPath:l})}finally{await c()}}}}}function iC(e){let{xctestDeviceSetPath:t,backupPath:a}=e,r=[a,...function(e){let t=o.dirname(e),a=o.basename(e).replace(iv,""),r=a===ib?iA:`${a}${iA}`;try{return n.readdirSync(t).filter(e=>e.startsWith(r)).sort().map(e=>o.join(t,e))}catch{return[]}}(a)],i=r.find(e=>n.existsSync(e)),s=n.existsSync(t)&&n.lstatSync(t).isSymbolicLink();if(i){if(s&&iR(t),n.existsSync(t))if(!s)return void el({level:"warn",phase:"ios_runner_xctest_device_set_restore_collision",data:{xctestDeviceSetPath:t,activeBackupPath:i}});else i!==a?n.rmSync(i,{recursive:!0,force:!0}):n.rmSync(a,{recursive:!0,force:!0});else n.mkdirSync(o.dirname(t),{recursive:!0}),n.renameSync(i,t);for(let e of r)e!==i&&n.existsSync(e)&&n.rmSync(e,{recursive:!0,force:!0});return}s&&(el({level:"warn",phase:"ios_runner_xctest_device_set_orphaned_symlink",data:{xctestDeviceSetPath:t}}),iR(t))}function iR(e){!n.existsSync(e)||n.lstatSync(e).isSymbolicLink()&&n.unlinkSync(e)}async function iP(e){let{lockDirPath:t,owner:a}=e,r=o.join(t,"owner.json"),i=Date.now()+3e4;for(n.mkdirSync(o.dirname(t),{recursive:!0});Date.now()<i;)try{n.mkdirSync(t),function(e,t){let a=`${e}.${process.pid}.${Date.now()}.tmp`;n.writeFileSync(a,JSON.stringify(t),"utf8"),n.renameSync(a,e)}(r,a);let e=!1;return async()=>{e||(e=!0,n.rmSync(t,{recursive:!0,force:!0}))}}catch(e){if("EEXIST"!==e.code)throw e;if(function(e,t){let a=null;try{a=n.statSync(e)}catch{return!0}let r=function(e){try{return JSON.parse(n.readFileSync(e,"utf8"))}catch{return null}}(t);if(r){var i;return!(Number.isInteger((i=r).pid)&&!(i.pid<=0)&&ex(i.pid)&&(!i.startTime||eS(i.pid)===i.startTime))&&(n.rmSync(e,{recursive:!0,force:!0}),!0)}return!(Date.now()-a.mtimeMs<5e3)&&(n.rmSync(e,{recursive:!0,force:!0}),!0)}(t,r))continue;await eb(100)}throw new y("COMMAND_FAILED","Timed out waiting for XCTest device set lock",{lockDirPath:t})}async function iT(e,t){var a;let r,i=(a=e,(r=process.env.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim())?o.resolve(r):"macos"===a.platform?o.join(iI,"derived","macos"):"simulator"===a.kind?o.join(iI,"derived"):o.join(iI,"derived",a.kind)),s=function(){let e=o.dirname(c(import.meta.url)),t=e;for(let e=0;e<6;e+=1){let e=o.join(t,"package.json");if(n.existsSync(e))return t;t=o.dirname(t)}return e}();return await ic(iS,i,async()=>{ry(process.env.AGENT_DEVICE_IOS_CLEAN_DERIVED)&&(iH("clean","forced_clean",{derived:i}),iX(i),iL(i));let a=function(e){let t=e.findXctestrun(e.derived);if(!t)return{reason:"missing_xctestrun",xctestrunPath:null};let n=e.resolveExistingXctestrunProductPaths(t);return n?e.xctestrunReferencesProjectRoot(t,e.projectRoot)?{reason:"reuse_ready",xctestrunPath:t,productPaths:n}:{reason:"project_root_mismatch",xctestrunPath:t,productPaths:n}:{reason:"missing_products",xctestrunPath:t,productPaths:[]}}({derived:i,projectRoot:s,findXctestrun:t=>iF(t,e),xctestrunReferencesProjectRoot:iG,resolveExistingXctestrunProductPaths:iz});if("reuse_ready"!==a.reason&&iH("rebuild",a.reason,{derived:i,xctestrunPath:a.xctestrunPath}),"reuse_ready"===a.reason)try{return await ih(e,a.productPaths,a.xctestrunPath),iH("reuse","reuse_ready",{derived:i,xctestrunPath:a.xctestrunPath}),a.xctestrunPath}catch(e){if(!function(e){if(!(e instanceof y))return!1;let t=e.details&&"object"==typeof e.details?e.details.reason:void 0;return"string"==typeof t&&ip.has(t)}(e))throw e;iH("rebuild","repair_failed",{derived:i,xctestrunPath:a.xctestrunPath})}a.xctestrunPath&&(iX(i),iL(i));let r=o.join(s,"ios-runner","AgentDeviceRunner","AgentDeviceRunner.xcodeproj");if(!n.existsSync(r))throw new y("COMMAND_FAILED","iOS runner project not found",{projectPath:r});await iB(e,r,i,t);let l=iF(i,e);if(!l)throw new y("COMMAND_FAILED","Failed to locate .xctestrun after build");let d=iz(l);if(!d)throw new y("COMMAND_FAILED","Runner build is missing expected products",{xctestrunPath:l});return await ih(e,d,l),iH("build","built_new",{derived:i,xctestrunPath:l}),l})}function iL(e){try{if(!n.existsSync(e))return;if("derived"!==o.basename(e))return void n.rmSync(e,{recursive:!0,force:!0});for(let a of n.readdirSync(e,{withFileTypes:!0})){var t;t=a.name,i$.has(t)&&n.rmSync(o.join(e,a.name),{recursive:!0,force:!0})}}catch{}}let i$=new Set(["Build","BuildCache.noindex","Index.noindex","Logs","ModuleCache.noindex","SDKStatCaches.noindex","SourcePackages","TextBasedInstallAPI","info.plist"]);function iF(e,t){if(!n.existsSync(e))return null;let a=[],r=[e];for(;r.length>0;){let e=r.pop();for(let t of n.readdirSync(e,{withFileTypes:!0})){let i=o.join(e,t.name);if(t.isDirectory()){r.push(i);continue}if(t.isFile()&&t.name.endsWith(".xctestrun"))try{let e=n.statSync(i);a.push({path:i,mtimeMs:e.mtimeMs})}catch{}}}return 0===a.length?null:(a.sort((e,n)=>{if(t){let a=iU(n.path,t)-iU(e.path,t);if(0!==a)return a}return n.mtimeMs-e.mtimeMs||e.path.localeCompare(n.path)}),a[0]?.path??null)}function iU(e,t){var n;let a=0,r=e.toLowerCase();o.basename(r).startsWith("agentdevicerunner.env.")&&(a-=1e3),r.includes(`${o.sep}macos${o.sep}`)&&(a-=5e3);let i="macos"===(n=t).platform?{preferred:["macos"],disallowed:["iphoneos","iphonesimulator","appletvos","appletvsimulator"]}:"tv"===n.target?"simulator"===n.kind?{preferred:["appletvsimulator"],disallowed:["appletvos","iphoneos","iphonesimulator","macos"]}:{preferred:["appletvos"],disallowed:["appletvsimulator","iphoneos","iphonesimulator","macos"]}:"simulator"===n.kind?{preferred:["iphonesimulator"],disallowed:["iphoneos","appletvos","appletvsimulator","macos"]}:{preferred:["iphoneos"],disallowed:["iphonesimulator","appletvos","appletvsimulator","macos"]};return i.preferred.length>0&&(i.preferred.some(e=>r.includes(e))?a+=2e3:a-=500),i.disallowed.some(e=>r.includes(e))&&(a-=2500),a}function iG(e,t){try{let a=n.readFileSync(e,"utf8"),r=new Set([t]);try{r.add(n.realpathSync(t))}catch{}for(let e of r)if(a.includes(e))return!0;return!1}catch{return!1}}async function iV(e,t,a){let r,i=o.dirname(e),s=a.replace(/[^a-zA-Z0-9._-]/g,"_"),l=o.join(i,`AgentDeviceRunner.env.${s}.json`),d=o.join(i,`AgentDeviceRunner.env.${s}.xctestrun`),u=await ef("plutil",["-convert","json","-o","-",e],{allowFailure:!0});if(0!==u.exitCode||!u.stdout.trim())throw new y("COMMAND_FAILED","Failed to read xctestrun plist",{xctestrunPath:e,stderr:u.stderr});try{let e=JSON.parse(u.stdout);if(!e||"object"!=typeof e||Array.isArray(e))throw Error("Root must be an object");r=e}catch(t){throw new y("COMMAND_FAILED","Failed to parse xctestrun JSON",{xctestrunPath:e,error:String(t)})}let c=e=>{e.EnvironmentVariables={...e.EnvironmentVariables??{},...t},e.UITestEnvironmentVariables={...e.UITestEnvironmentVariables??{},...t},e.UITargetAppEnvironmentVariables={...e.UITargetAppEnvironmentVariables??{},...t},e.TestingEnvironmentVariables={...e.TestingEnvironmentVariables??{},...t}},p=r.TestConfigurations;if(Array.isArray(p))for(let e of p){if(!e||"object"!=typeof e)continue;let t=e.TestTargets;if(Array.isArray(t))for(let e of t)e&&"object"==typeof e&&c(e)}for(let[e,t]of Object.entries(r))t&&"object"==typeof t&&!Array.isArray(t)&&t.TestBundlePath&&(c(t),r[e]=t);n.writeFileSync(l,JSON.stringify(r,null,2));let f=await ef("plutil",["-convert","xml1","-o",d,l],{allowFailure:!0});if(0!==f.exitCode)throw new y("COMMAND_FAILED","Failed to write xctestrun plist",{tmpXctestrunPath:d,stderr:f.stderr});return{xctestrunPath:d,jsonPath:l}}async function iB(e,t,n,a){let r=function(e=process.env){let t=iM(e),n=ik(e);return[`AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID=${t}`,`AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID=${n}`]}(process.env),i=function(e=process.env,t=!1,n="ios"){if("macos"===n)return["CODE_SIGNING_ALLOWED=NO","CODE_SIGNING_REQUIRED=NO","CODE_SIGN_IDENTITY=","DEVELOPMENT_TEAM="];if(!t)return[];let a=e.AGENT_DEVICE_IOS_TEAM_ID?.trim()||"",r=e.AGENT_DEVICE_IOS_SIGNING_IDENTITY?.trim()||"",i=e.AGENT_DEVICE_IOS_PROVISIONING_PROFILE?.trim()||"",o=["CODE_SIGN_STYLE=Automatic"];return a&&o.push(`DEVELOPMENT_TEAM=${a}`),r&&o.push(`CODE_SIGN_IDENTITY=${r}`),i&&o.push(`PROVISIONING_PROFILE_SPECIFIER=${i}`),o}(process.env,"device"===e.kind,e.platform),o="device"===e.kind?["-allowProvisioningUpdates"]:[],s=await iO(e);try{var l;let s;await ed("xcodebuild",["build-for-testing","-project",t,"-scheme","AgentDeviceRunner","-parallel-testing-enabled","NO",iW(e),"1","-destination",(l=e,s=ij(l),"macOS"===s?`platform=macOS,arch=${iq()}`:"simulator"===l.kind?`platform=${s} Simulator,id=${l.id}`:`generic/platform=${s}`),"-derivedDataPath",n,"COMPILER_INDEX_STORE_ENABLE=NO","ENABLE_CODE_COVERAGE=NO",...r,...o,...i],{detached:!0,onSpawn:e=>{iN.add(e),e.on("close",()=>{iN.delete(e)})},onStdoutChunk:e=>{io(e,a.logPath,a.traceLogPath,a.verbose)},onStderrChunk:e=>{io(e,a.logPath,a.traceLogPath,a.verbose)}})}catch(i){let e,t,n=i instanceof y?i:new y("COMMAND_FAILED",String(i)),r=(e=n.details?JSON.stringify(n.details):"",(t=`${n.message}
|
|
6
|
+
${e}`.toLowerCase()).includes("failed registering bundle identifier")||t.includes("app identifier")&&t.includes("not available")?"Set AGENT_DEVICE_IOS_BUNDLE_ID to a unique reverse-DNS value (for example, com.yourname.agentdevice.runner), then retry.":t.includes("requires a development team")?"Configure signing in Xcode or set AGENT_DEVICE_IOS_TEAM_ID for physical-device runs.":t.includes("no profiles for")||t.includes("provisioning profile")?"Install/select a valid iOS provisioning profile, or set AGENT_DEVICE_IOS_PROVISIONING_PROFILE.":t.includes("code signing")?"Enable Automatic Signing in Xcode or provide AGENT_DEVICE_IOS_TEAM_ID and optional AGENT_DEVICE_IOS_SIGNING_IDENTITY.":void 0);throw new y("COMMAND_FAILED","xcodebuild build-for-testing failed",{error:n.message,details:n.details,logPath:a.logPath,hint:r})}finally{await s?.release()}}function ij(e){var t;if("ios"!==e.platform&&"macos"!==e.platform)throw new y("UNSUPPORTED_PLATFORM",`Unsupported platform for iOS runner: ${e.platform}`);return"macos"===e.platform?"macOS":"macos"===(t=e.target)||"desktop"===t?"macOS":"tv"===t?"tvOS":"iOS"}function iq(){return"arm64"===process.arch?"arm64":"x86_64"}function iW(e){return"macos"===e.platform||"device"===e.kind?"-maximum-concurrent-test-device-destinations":"-maximum-concurrent-test-simulator-destinations"}function iX(e,t=process.env){if(t.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim()&&!function(e=process.env){return ry(e.AGENT_DEVICE_IOS_ALLOW_OVERRIDE_DERIVED_CLEAN)}(t))throw new y("COMMAND_FAILED","Refusing to clean AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH automatically",{derivedPath:e,hint:"Unset AGENT_DEVICE_IOS_CLEAN_DERIVED, or set AGENT_DEVICE_IOS_ALLOW_OVERRIDE_DERIVED_CLEAN=1 if you trust this path."})}function iH(e,t,n){el({level:"rebuild"===e?"warn":"info",phase:"runner_xctestrun_cache",data:{action:e,reason:t,...n}})}function iz(e){let t=function(e){let t=function(e){try{let t=ep("plutil",["-convert","json","-o","-",e],{allowFailure:!0});if(0!==t.exitCode||!t.stdout.trim())return null;return JSON.parse(t.stdout)}catch{return null}}(e);if(t){var a,r,i=t;let e=new Set,n=t=>{if(t&&"object"==typeof t)for(let n of function(e){let t=new Set(["ProductPaths","DependentProductPaths","TestHostPath","TestBundlePath","UITargetAppPath"]),n=new Set;for(let[a,r]of Object.entries(e))if(t.has(a)){if("string"==typeof r){n.add(r);continue}if(Array.isArray(r))for(let e of r)"string"==typeof e&&n.add(e)}return Array.from(n)}(t))e.add(n)};n(i);let o=i.TestConfigurations;if(Array.isArray(o))for(let e of o){if(!e||"object"!=typeof e)continue;let t=e.TestTargets;if(Array.isArray(t))for(let e of t)n(e)}for(let e of Object.values(i))e&&"object"==typeof e&&"TestBundlePath"in e&&n(e);return Array.from(e)}if("darwin"===process.platform)return null;try{let t;return a=n.readFileSync(e,"utf8"),r=iw(a),t=new Set,ig(r,(e,n)=>{if(ix.has(e)){if("string"===n.name&&n.text)return void t.add(n.text);if("array"===n.name)for(let e of n.children)"string"===e.name&&e.text&&t.add(e.text)}}),Array.from(t)}catch{return null}}(e);if(!t||0===t.length)return null;let a=o.dirname(e),r=new Set,i=new Set,s=[];for(let e of t){if(e.startsWith("__TESTROOT__/")){let t=e.slice(13),s=o.join(a,t);if(!n.existsSync(s))return null;r.add(s);let l=function(e){let t=/\.app(?:\/|$)/.exec(e);return t&&void 0!==t.index?e.slice(0,t.index+4):null}(t);l&&i.add(o.join(a,l));continue}e.startsWith("__TESTHOST__/")&&s.push(e.slice(13))}for(let e of s){let t=Array.from(i).find(t=>n.existsSync(o.join(t,e)));if(!t)return null;r.add(o.join(t,e))}return Array.from(r)}let iY=new Map,iK=new Map;async function iJ(e,t){return await ic(iK,e.id,async()=>{var n;let a,r,i=iY.get(e.id);if(i){if(i5(i.child.pid))return i;await i1(e.id,i)}await ("simulator"!==(n=e).kind?Promise.resolve():i6(n)),await iZ(e);let o=await iT(e,t),s=await ii(),{xctestrunPath:l,jsonPath:d}=await iV(o,{AGENT_DEVICE_RUNNER_PORT:String(s)},`session-${e.id}-${s}`),u=await iO(e);try{let t;({child:a,wait:r}=ec("xcodebuild",["test-without-building","-only-testing","AgentDeviceRunnerUITests/RunnerTests/testCommand","-parallel-testing-enabled","NO","-test-timeouts-enabled","NO","-collect-test-diagnostics","never",iW(e),"1","-destination-timeout",String(r8),"-xctestrun",l,"-destination",(t=ij(e),"macOS"===t?`platform=macOS,arch=${iq()}`:"simulator"===e.kind?`platform=${t} Simulator,id=${e.id}`:`platform=${t},id=${e.id}`)],{allowFailure:!0,env:{...process.env,AGENT_DEVICE_RUNNER_PORT:String(s)},detached:!0}))}catch(e){throw await u?.release(),e}a.stdout?.on("data",e=>{io(e,t.logPath,t.traceLogPath,t.verbose)}),a.stderr?.on("data",e=>{io(e,t.logPath,t.traceLogPath,t.verbose)});let c={sessionId:`${e.id}:${s}:${Date.now()}`,device:e,deviceId:e.id,port:s,xctestrunPath:l,jsonPath:d,testPromise:r,child:a,ready:!1,simulatorSetRedirect:u??void 0};return iY.set(e.id,c),c})}async function iZ(e){if("simulator"===e.kind)for(let t of iD){let n=await ef("xcrun",rz(e,["uninstall",e.id,t]),{allowFailure:!0});if(0!==n.exitCode){let e=`${n.stdout}
|
|
7
|
+
${n.stderr}`.toLowerCase();if(!e.includes("not installed")&&!e.includes("found nothing")&&!e.includes("no such file")&&!e.includes("invalid device")&&!e.includes("could not find"))continue}}}function iQ(e){let t=iY.get(e);return t?{sessionId:t.sessionId,alive:i5(t.child.pid)}:null}async function i0(e){await ic(iK,e.deviceId,async()=>{await i1(e.deviceId,e)})}async function i1(e,t){let n=t??iY.get(e);if(n){var a;try{await r9(n.device,n.port,{command:"shutdown"},void 0,15e3)}catch{await i8(n.child.pid,"SIGTERM")}try{await Promise.race([n.testPromise,new Promise(e=>setTimeout(e,1e4))])}catch{}(a=n.child.pid)&&(i5(a)||eI(a))&&await i8(n.child.pid,"SIGKILL"),id(n.xctestrunPath),id(n.jsonPath),await n.simulatorSetRedirect?.release(),iY.get(e)===n&&iY.delete(e)}}async function i2(e){await ic(iK,e,async()=>{await i1(e)})}async function i3(){let e=Array.from(iY.values()),t=Array.from(iN);await Promise.allSettled(e.map(async e=>{await i8(e.child.pid,"SIGINT")})),await Promise.allSettled(t.map(async e=>{await i8(e.pid,"SIGINT")})),await Promise.allSettled(e.map(async e=>{await i8(e.child.pid,"SIGTERM")})),await Promise.allSettled(t.map(async e=>{await i8(e.pid,"SIGTERM")})),await Promise.allSettled(e.map(async e=>{await i8(e.child.pid,"SIGKILL")})),await Promise.allSettled(t.map(async e=>{await i8(e.pid,"SIGKILL"),iN.delete(e)})),await Promise.allSettled(e.map(async e=>{await e.simulatorSetRedirect?.release()}))}async function i4(){await i3();let e=Array.from(iY.keys());await Promise.allSettled(e.map(async e=>{await i2(e)}));let t=Array.from(iN);await Promise.allSettled(t.map(async e=>{try{await i8(e.pid,"SIGTERM"),await i8(e.pid,"SIGKILL")}finally{iN.delete(e)}}))}function i5(e){return!!e&&ex(e)}async function i8(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 ef("pkill",[`-${n}`,"-P",String(e)],{allowFailure:!0})}catch{}}async function i6(e){await ef("xcrun",rz(e,["bootstatus",e.id,"-b"]),{timeoutMs:rQ})}async function i9(e,t,n,a,r,i){let o=await r9(e,t.port,n,a,r,t,i);return await i7(o,t,a)}async function i7(e,t,n){let a,r=await e.text();try{let e=JSON.parse(r);a=e&&"object"==typeof e?e:{}}catch{throw new y("COMMAND_FAILED","Invalid runner response",{text:r})}if(!a.ok){let e=a.error?.code;throw new y("string"==typeof e&&e.trim().length>0?m(e):"COMMAND_FAILED",("string"==typeof a.error?.message?a.error.message:void 0)??"Runner error",{runner:a,xcodebuild:{exitCode:1,stdout:"",stderr:""},logPath:n})}return(t.ready=!0,a.data&&"object"==typeof a.data&&!Array.isArray(a.data))?a.data:{}}async function oe(e,t,n={}){var a;if("ios"!==e.platform&&"macos"!==e.platform)throw new y("UNSUPPORTED_PLATFORM",`Unsupported platform for iOS runner: ${e.platform}`);if("simulator"!==e.kind&&"device"!==e.kind)throw new y("UNSUPPORTED_OPERATION",`Unsupported iOS device kind for runner: ${e.kind}`);return(rZ(n.requestId),"interactionFrame"===(a=t.command)||"snapshot"===a||"screenshot"===a||"findText"===a||"readText"===a||"alert"===a||"uptime"===a)?rS(()=>(rZ(n.requestId),ot(e,t,n)),{shouldRetry:e=>{rZ(n.requestId);if(!(e instanceof y)||"COMMAND_FAILED"!==e.code)return!1;let t=`${e.message??""}`.toLowerCase();return!(t.includes("xcodebuild exited early")||t.includes("device is busy")&&t.includes("connecting"))&&!!(t.includes("runner did not accept connection")||t.includes("fetch failed")||t.includes("econnrefused")||t.includes("socket hang up"))}}):ot(e,t,n)}async function ot(e,t,n={}){let a;rZ(n.requestId);let r=rT(n.requestId);try{let i=(a=await iJ(e,n)).ready?r0:rQ;return await i9(e,a,t,n.logPath,i,r)}catch(o){let i=o instanceof y?o:new y("COMMAND_FAILED",String(o));if("COMMAND_FAILED"===i.code&&"string"==typeof i.message&&i.message.includes("Runner did not accept connection")&&rY(i)&&a?.ready){rZ(n.requestId),a?await i0(a):await i2(e.id),a=await iJ(e,n);let i=await r9(a.device,a.port,t,n.logPath,rQ,void 0,r);return await i7(i,a,n.logPath)}throw o}}let on="agent-device-macos-helper",oa="AGENT_DEVICE_MACOS_HELPER_BIN",or=o.join(s.homedir(),".agent-device","macos-helper","current"),oi=o.join(or,"manifest.json"),oo=/^[A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)+$/;function os(e){let t=e.trim();if(!oo.test(t))throw new y("INVALID_ARGS","macOS bundle id must use reverse-DNS form like com.example.App",{bundleId:e});return t}function ol(){return function(e){let t=o.dirname(e);for(;;){let e=o.join(t,"macos-helper");if(a(o.join(e,"Package.swift")))return e;let n=o.dirname(t);if(n===t)break;t=n}throw new y("COMMAND_FAILED","Unable to locate macOS helper package root",{modulePath:e})}(c(import.meta.url))}async function od(e){let t=await r.readdir(e,{withFileTypes:!0});return(await Promise.all(t.map(async t=>{let n=o.join(e,t.name);return t.isDirectory()?".build"===t.name?[]:await od(n):t.isFile()&&(t.name.endsWith(".swift")||"Package.swift"===t.name)?[n]:[]}))).flat().sort()}async function ou(e){let t=await od(e),n=f("sha256");for(let a of t)n.update(o.relative(e,a)),n.update("\0"),n.update(await r.readFile(a)),n.update("\0");let a=await ef("swift",["--version"],{allowFailure:!0,cwd:e,timeoutMs:1e4});return n.update("swift-version"),n.update("\0"),n.update(a.stdout||a.stderr||`exit:${a.exitCode}`),n.update("\0"),n.digest("hex")}async function oc(){try{let e=JSON.parse(await r.readFile(oi,"utf8"));return"string"==typeof e.fingerprint?e.fingerprint:null}catch{return null}}async function op(){let e=await ew(process.env[oa],oa);if(e)return e;let t=ol(),n=await ou(t),a=o.join(or,on);try{if(await oc()===n)return await r.access(a),a}catch{}let i=o.join(ol(),".build","release",on);process.stderr.write("agent-device: building macOS helper (first run or helper update)\n"),await ef("swift",["build","-c","release","--package-path",t],{cwd:t,timeoutMs:12e4}),await r.mkdir(or,{recursive:!0});let s=`${a}.tmp`;return await r.copyFile(i,s),await r.rename(s,a),await r.chmod(a,493),await r.writeFile(oi,`${JSON.stringify({fingerprint:n},null,2)}
|
|
8
|
+
`,"utf8"),a}async function of(e){let t=process.env[oa]?.trim();if("darwin"!==process.platform&&!t)throw new y("UNSUPPORTED_PLATFORM","macOS helper is only available on macOS");let n=await op(),a=await ef(n,e,{allowFailure:!0,timeoutMs:3e4}),r=a.stdout.trim(),i=null;if(r)try{i=JSON.parse(r)}catch{i=null}if(0===a.exitCode&&i?.ok)return i.data;throw new y("COMMAND_FAILED",i&&!i.ok?i.error?.message??`macOS helper exited with code ${a.exitCode}`:r||a.stderr.trim()||`macOS helper exited with code ${a.exitCode}`,{helperPath:n,args:e,stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode,...i&&!i.ok?i.error?.details:{}})}async function oh(){return await of(["app","frontmost"])}async function om(e){return await of(["app","quit","--bundle-id",os(e)])}async function ow(e,t){return await of(["permission",e,t])}async function og(e,t={}){let n=["alert",e];return t.bundleId&&n.push("--bundle-id",os(t.bundleId)),t.surface&&n.push("--surface",t.surface),await of(n)}async function oy(e,t={}){let n=["snapshot","--surface",e];return t.bundleId&&n.push("--bundle-id",os(t.bundleId)),await of(n)}async function ob(e,t,n={}){let a=["read","--x",String(e),"--y",String(t)];return n.bundleId&&a.push("--bundle-id",os(n.bundleId)),n.surface&&a.push("--surface",n.surface),await of(a)}async function ov(e,t,n={}){let a=["press","--x",String(e),"--y",String(t)];return n.bundleId&&a.push("--bundle-id",os(n.bundleId)),n.surface&&a.push("--surface",n.surface),await of(a)}async function oA(e,t={}){let n=["screenshot","--out",e];return t.surface&&n.push("--surface",t.surface),t.fullscreen&&n.push("--fullscreen"),await of(n)}function oI(e,t){return["-s",e.id,...t]}async function ox(){if(await eN(),!await em("adb"))throw new y("TOOL_MISSING","adb not found in PATH")}function oS(e,t){let n=`${e}
|
|
9
|
+
${t}`.toLowerCase();return n.includes("no shell command implementation")||n.includes("unknown command")}function oN(e){let t=e.trim();if(!t||/\s/.test(t))return!1;let n=/^([A-Za-z][A-Za-z0-9+.-]*):(.+)$/.exec(t);if(!n)return!1;let a=n[1]?.toLowerCase(),r=n[2]??"";return"http"!==a&&"https"!==a&&"ws"!==a&&"wss"!==a&&"ftp"!==a&&"ftps"!==a||r.startsWith("//")}function o_(e,t){let n,a=e?.trim();return a?a:"http"===(n=t.trim().split(":")[0]?.toLowerCase())||"https"===n?"com.apple.mobilesafari":void 0}function oM(e={}){let t=e.ttlMs??3e4,n=e.nowMs??Date.now,a=new Map,r=e=>{var t;let n=[(t=e).platform,t.deviceId,""].join("\0");for(let e of a.keys())e.startsWith(n)&&a.delete(e)};return{get(e,t){let r=ok(e,t),i=a.get(r);if(i)return i.expiresAtMs<=n()?void a.delete(r):i.value},set:(e,r,i)=>(a.set(ok(e,r),{value:i,expiresAtMs:n()+t}),i),clear(e){r(e)},async invalidateWhile(e,t){r(e);try{return await t()}finally{r(e)}}}}function ok(e,t){return[e.platform,e.deviceId,e.variant??"",t.trim().toLowerCase()].join("\0")}let oD=["android.software.leanback","android.software.leanback_only","android.hardware.type.television"];async function oE(e,t,n){let a=Array(e.length),r=0,i=Math.min(t,e.length);return await Promise.all(Array.from({length:i},async()=>{for(;r<e.length;){let t=r;r+=1,a[t]=await n(e[t])}})),a}function oO(e){return`${e.stdout}
|
|
10
|
+
${e.stderr}`}function oC(e,t){return["-s",e,...t]}function oR(e){return e.startsWith("emulator-")}function oP(e){return e.toLowerCase().replace(/_/g," ").replace(/\s+/g," ").trim()}async function oT(e,t=rA){return ef("adb",oC(e,["shell","getprop","sys.boot_completed"]),{allowFailure:!0,timeoutMs:t})}async function oL(e,t){let n=t.replace(/_/g," ").trim();if(!oR(e))return n||e;let a=await oF(e);return a?a.replace(/_/g," "):n||e}async function o$(e,t,n){try{return await n("adb",oC(e,t),{allowFailure:!0,timeoutMs:1e4})}catch(e){var a;if("COMMAND_FAILED"===(a=w(e)).code&&"number"==typeof a.details?.timeoutMs)return;throw e}}async function oF(e,t=ef){for(let n of["ro.boot.qemu.avd_name","persist.sys.avd_name"]){let a=await o$(e,["shell","getprop",n],t);if(!a)continue;let r=a.stdout.trim();if(0===a.exitCode&&r.length>0)return r}let n=await o$(e,["emu","avd","name"],t);if(!n)return;let a=function(e){let t=e.split("\n").map(e=>e.trim()).filter(e=>e.length>0);if(0!==t.length)return"OK"===t.at(-1)&&t.pop(),t.join("\n").trim()||void 0}(n.stdout);if(0===n.exitCode&&a)return a}async function oU(e,t){let n=oO(await ef("adb",oC(e,["shell","cmd","package","has-feature",t]),{allowFailure:!0,timeoutMs:rA})).toLowerCase();return!!n.includes("true")||!n.includes("false")&&null}async function oG(e){return(await oE(oD,2,async t=>await oU(e,t))).some(e=>!0===e)}async function oV(e){var t;let n;return"tv"===((n=oO(await ef("adb",oC(e,["shell","getprop","ro.build.characteristics"]),{allowFailure:!0,timeoutMs:rA})).toLowerCase()).includes("tv")||n.includes("leanback")?"tv":null)||await oG(e)?"tv":(t=oO(await ef("adb",oC(e,["shell","pm","list","features"]),{allowFailure:!0,timeoutMs:rA})),/feature:android\.(software\.leanback(_only)?|hardware\.type\.television)\b/i.test(t))?"tv":"mobile"}async function oB(e={}){if(await eN(),!await em("adb"))throw new y("TOOL_MISSING","adb not found in PATH");let t=e.serialAllowlist??rX(void 0),n=(await oj()).filter(e=>!t||t.has(e.serial));return await oE(n,3,async({serial:e,rawModel:t})=>{let[n,a,r]=await Promise.all([oL(e,t),oH(e),oV(e)]);return{platform:"android",id:e,name:n,kind:oR(e)?"emulator":"device",target:r,booted:a}})}async function oj(){return(await ef("adb",["devices","-l"],{timeoutMs:rA})).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 oq(){let e=await ef("emulator",["-list-avds"],{allowFailure:!0,timeoutMs:rA});if(0!==e.exitCode)throw new y("COMMAND_FAILED","Failed to list Android emulator AVDs",{stdout:e.stdout,stderr:e.stderr,exitCode:e.exitCode,hint:"Verify Android emulator tooling is installed and available in PATH."});return e.stdout.split("\n").map(e=>e.trim()).filter(e=>e.length>0)}async function oW(e){let t=Date.now();for(;Date.now()-t<e.timeoutMs;){try{let t=await oX(e.avdName,e.serial);if(t)return{platform:"android",id:t,name:e.avdName,kind:"emulator",target:"mobile",booted:!1}}catch{}await eb(1e3)}throw new y("COMMAND_FAILED","Android emulator did not appear in time",{avdName:e.avdName,serial:e.serial,timeoutMs:e.timeoutMs,hint:"Check emulator logs and verify the AVD can start from command line."})}async function oX(e,t){let n=oP(e);for(let e of(await oj()).filter(e=>(!t||e.serial===t)&&oR(e.serial)))if(oP(e.rawModel)===n||oP(await oL(e.serial,e.rawModel))===n)return e.serial}async function oH(e){try{let t=await oT(e);return"1"===t.stdout.trim()}catch{return!1}}async function oz(e){var t,n;let a;await eN();let r=e.avdName.trim();if(!r)throw new y("INVALID_ARGS","Android emulator boot requires a non-empty AVD name.");let i=e.timeoutMs??12e4;if(!await em("adb"))throw new y("TOOL_MISSING","adb not found in PATH");if(!await em("emulator"))throw new y("TOOL_MISSING","emulator not found in PATH");let o=await oq(),s=function(e,t){let n=e.find(e=>e===t);if(n)return n;let a=oP(t);return e.find(e=>oP(e)===a)}(o,r);if(!s)throw new y("DEVICE_NOT_FOUND",`No Android emulator AVD named ${e.avdName}`,{requestedAvdName:r,availableAvds:o,hint:"Run `emulator -list-avds` and pass an existing AVD name to --device."});let l=Date.now(),d=(t=await oB(),n=e.serial,a=oP(s),t.find(e=>"android"===e.platform&&"emulator"===e.kind&&(!n||e.id===n)&&oP(e.name)===a));if(!d){let t=["-avd",s];e.headless&&t.push("-no-window","-no-audio"),eu("emulator",t)}let u=d??await oW({avdName:s,serial:e.serial,timeoutMs:i}),c=Math.max(1e3,i-(Date.now()-l));await oY(u.id,c);let p=(await oB()).find(e=>e.id===u.id);return p?{...p,name:s,booted:!0}:{...u,name:s,booted:!0}}async function oY(e,t=6e4){let n,a=rI.fromTimeoutMs(t),r=Math.max(1,Math.ceil(t/1e3)),i=!1;try{await rx(async({deadline:r})=>{if(r?.isExpired())throw i=!0,new y("COMMAND_FAILED","Android boot deadline exceeded",{serial:e,timeoutMs:t,elapsedMs:a.elapsedMs(),message:"timeout"});let o=Math.max(1e3,r?.remainingMs()??t),s=await oT(e,Math.min(o,rA));if(n=s,"1"!==s.stdout.trim())throw new y("COMMAND_FAILED","Android device is still booting",{serial:e,stdout:s.stdout,stderr:s.stderr,exitCode:s.exitCode})},{maxAttempts:r,baseDelayMs:1e3,maxDelayMs:1e3,jitter:0,shouldRetry:e=>{let t=rF({error:e,stdout:n?.stdout,stderr:n?.stderr,context:{platform:"android",phase:"boot"}});return"ADB_TRANSPORT_UNAVAILABLE"!==t&&"ANDROID_BOOT_TIMEOUT"!==t}},{deadline:a,phase:"boot",classifyReason:e=>rF({error:e,stdout:n?.stdout,stderr:n?.stderr,context:{platform:"android",phase:"boot"}})})}catch(c){let r=w(c),o=n?.stdout,s=n?.stderr,l=n?.exitCode,d=rF({error:c,stdout:o,stderr:s,context:{platform:"android",phase:"boot"}});"BOOT_COMMAND_FAILED"===d&&"Android device is still booting"===r.message&&(d="ANDROID_BOOT_TIMEOUT");let u={serial:e,timeoutMs:t,elapsedMs:a.elapsedMs(),reason:d,hint:rU(d),stdout:o,stderr:s,exitCode:l};if(i||"ANDROID_BOOT_TIMEOUT"===d)throw new y("COMMAND_FAILED","Android device did not finish booting in time",u);if("TOOL_MISSING"===r.code)throw new y("TOOL_MISSING",r.message,{...u,...r.details??{}});if("ADB_TRANSPORT_UNAVAILABLE"===d)throw new y("COMMAND_FAILED",r.message,{...u,...r.details??{}});throw new y(r.code,r.message,{...u,...r.details??{}},r.cause)}}let oK=/\.(?:apk|aab)$/i,oJ=/^[A-Za-z_][\w]*(\.[A-Za-z_][\w]*)+$/;function oZ(e){var t,n;let a=e.trim();return 0===a.length?"other":oK.test(a)?a.includes("/")||a.includes("\\")||a.startsWith(".")||a.startsWith("~")||(t=a,!oJ.test(t))?"binary":"package":(n=a,oJ.test(n))?"package":"other"}function oQ(e){return`Android runtime hints require an installed package name, not "${e}". Install or reinstall the app first, then relaunch by package.`}async function o0(e,t){let n="url"===e.kind&&ek(e.url),a=await eM({source:e,isInstallablePath:(e,t)=>{var n;let a;return t.isFile()&&(n=e,".apk"===(a=o.extname(n).toLowerCase())||".aab"===a)},installableLabel:"Android installable (.apk or .aab)",allowArchiveExtraction:"url"!==e.kind||n,signal:t?.signal}),r=t?.resolveIdentity===!1?{}:await o1(a.installablePath);return{archivePath:a.archivePath,installablePath:a.installablePath,packageName:r.packageName,cleanup:a.cleanup}}async function o1(e){let t=o.extname(e).toLowerCase();return".apk"!==t&&".aab"!==t?{}:{packageName:await e_(e)}}let o2={settings:{type:"intent",value:"android.settings.SETTINGS"}},o3="android.intent.category.LAUNCHER",o4="android.intent.category.LEANBACK_LAUNCHER",o5="android.intent.category.DEFAULT",o8="Run agent-device apps --platform android to discover the installed package name, then retry open with that exact package.",o6=oM();function o9(e){return{platform:"android",deviceId:e.id,variant:e.target??""}}async function o7(e,t){let n=t.trim();if("package"===oZ(n))return{type:"package",value:n};let a=o2[n.toLowerCase()];if(a)return a;let r=o9(e),i=o6.get(r,n);if(i)return i;let o=(await ef("adb",oI(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===o.length)return o6.set(r,n,{type:"package",value:o[0]});if(o.length>1)throw new y("INVALID_ARGS",`Multiple packages matched "${t}"`,{matches:o,hint:"Run agent-device apps --platform android to see the exact installed package names before retrying open."});throw new y("APP_NOT_INSTALLED",`No package found matching "${t}"`,{hint:o8})}async function se(e,t="all"){let n=await st(e);return("user-installed"===t?(await sa(e)).filter(e=>n.has(e)):Array.from(n)).sort((e,t)=>e.localeCompare(t)).map(e=>({package:e,name:sr(e)}))}async function st(e){let t=new Set;for(let n of sn(e,{includeFallbackWhenUnknown:!0})){let a=await ef("adb",oI(e,["shell","cmd","package","query-activities","--brief","-a","android.intent.action.MAIN","-c",n]),{allowFailure:!0});if(0===a.exitCode&&0!==a.stdout.trim().length)for(let e of eE(a.stdout))t.add(e)}return t}function sn(e,t={}){return"tv"===e.target?[o4]:"mobile"===e.target?[o3]:t.includeFallbackWhenUnknown?[o3,o4]:[o3]}async function sa(e){return eO((await ef("adb",oI(e,["shell","pm","list","packages","-3"]))).stdout)}function sr(e){let t=new Set(["com","android","google","app","apps","service","services","mobile","client"]),n=e.split(".").flatMap(e=>e.split(/[_-]+/)).map(e=>e.trim().toLowerCase()).filter(e=>e.length>0),a=n[n.length-1]??e;for(let e=n.length-1;e>=0;e-=1){let r=n[e];if(!t.has(r)){a=r;break}}return a.split(/[^a-z0-9]+/i).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(" ")}async function si(e){let t=await so(e,[["shell","dumpsys","window","windows"],["shell","dumpsys","window"]]);if(t)return t;let n=await so(e,[["shell","dumpsys","activity","activities"],["shell","dumpsys","activity"]]);return n||{}}async function so(e,t){for(let n of t){let t=eD((await ef("adb",oI(e,n),{allowFailure:!0})).stdout??"");if(t)return t}return null}async function ss(e,t,n){var a,r;let i;e.booted||await oY(e.id);let o=t.trim();if(oN(o)){if(n)throw new y("INVALID_ARGS","Activity override is not supported when opening a deep link URL");await ef("adb",oI(e,["shell","am","start","-W","-a","android.intent.action.VIEW","-d",o]));return}let s=await o7(e,t),l=sn(e)[0]??o3;if("intent"===s.type){if(n)throw new y("INVALID_ARGS","Activity override requires a package name, not an intent");await ef("adb",oI(e,["shell","am","start","-W","-a",s.value]));return}if(n){let t=n.includes("/")?n:`${s.value}/${n.startsWith(".")?n:`.${n}`}`;try{await ef("adb",oI(e,["shell","am","start","-W","-a","android.intent.action.MAIN","-c",o5,"-c",l,"-n",t]))}catch(t){throw await su(e,s.value,t),t}return}let d=await ef("adb",oI(e,["shell","am","start","-W","-a","android.intent.action.MAIN","-c",o5,"-c",l,"-p",s.value]),{allowFailure:!0});if(0===d.exitCode&&(a=d.stdout,r=d.stderr,i=`${a}
|
|
11
|
+
${r}`,!/Error:.*(?:Activity not started|unable to resolve Intent)/i.test(i)))return;let u=await sp(e,s.value);if(!u){if(!await sd(e,s.value))throw sl(s.value);throw new y("COMMAND_FAILED",`Failed to launch ${s.value}`,{stdout:d.stdout,stderr:d.stderr})}await ef("adb",oI(e,["shell","am","start","-W","-a","android.intent.action.MAIN","-c",o5,"-c",l,"-n",u]))}function sl(e){return new y("APP_NOT_INSTALLED",`No package found matching "${e}"`,{package:e,hint:o8})}async function sd(e,t){let n=await ef("adb",oI(e,["shell","pm","path",t]),{allowFailure:!0}),a=`${n.stdout}
|
|
12
|
+
${n.stderr}`;return!!(0===n.exitCode&&/\bpackage:/i.test(a))||(sc(a),!1)}async function su(e,t,n){if(sc(n instanceof y?`${String(n.details?.stdout??"")}
|
|
13
|
+
${String(n.details?.stderr??"")}`:"")||!await sd(e,t))throw sl(t)}function sc(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 sp(e,t){for(let n of Array.from(new Set(sn(e,{includeFallbackWhenUnknown:!0})))){let a=await ef("adb",oI(e,["shell","cmd","package","resolve-activity","--brief","-a","android.intent.action.MAIN","-c",n,t]),{allowFailure:!0});if(0!==a.exitCode)continue;let r=function(e){let t=e.split("\n").map(e=>e.trim()).filter(Boolean);for(let e=t.length-1;e>=0;e-=1){let n=t[e];if(n.includes("/"))return n.split(/\s+/)[0]}return null}(a.stdout);if(r)return r}return null}async function sf(e){e.booted||await oY(e.id)}async function sh(e,t){if("settings"===t.trim().toLowerCase())return void await ef("adb",oI(e,["shell","am","force-stop","com.android.settings"]));let n=await o7(e,t);if("intent"===n.type)throw new y("INVALID_ARGS","Close requires a package name, not an intent");await ef("adb",oI(e,["shell","am","force-stop",n.value]))}async function sm(e,t){let n=await o7(e,t);if("intent"===n.type)throw new y("INVALID_ARGS","App uninstall requires a package name, not an intent");let a=await ef("adb",oI(e,["uninstall",n.value]),{allowFailure:!0});if(0!==a.exitCode){let e=`${a.stdout}
|
|
14
|
+
${a.stderr}`.toLowerCase();if(!e.includes("unknown package")&&!e.includes("not installed"))throw new y("COMMAND_FAILED",`adb uninstall failed for ${n.value}`,{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode})}return{package:n.value}}let sw=null;async function sg(){let e=`${process.env.PATH??""}::${process.env.AGENT_DEVICE_BUNDLETOOL_JAR??""}`;if(sw?.key===e)return sw.invocation;if(await em("bundletool")){let t={cmd:"bundletool",prefixArgs:[]};return sw={key:e,invocation:t},t}let t=await eh(process.env.AGENT_DEVICE_BUNDLETOOL_JAR,"AGENT_DEVICE_BUNDLETOOL_JAR");if(!t)throw new y("TOOL_MISSING","bundletool not found in PATH. Install bundletool or set AGENT_DEVICE_BUNDLETOOL_JAR to a bundletool-all.jar path.");let n={cmd:"java",prefixArgs:["-jar",t]};return sw={key:e,invocation:n},n}async function sy(e){let t=await sg();await ef(t.cmd,[...t.prefixArgs,...e])}async function sb(e,t){let n,a=await r.mkdtemp(o.join(s.tmpdir(),"agent-device-aab-")),i=o.join(a,"bundle.apks"),l=(n=process.env.AGENT_DEVICE_ANDROID_BUNDLETOOL_MODE?.trim())&&n.length>0?n:"universal";try{await sy(["build-apks","--bundle",t,"--output",i,"--mode",l]),await sy(["install-apks","--apks",i,"--device-id",e.id])}finally{await r.rm(a,{recursive:!0,force:!0})}}async function sv(e,t){".aab"===o.extname(t).toLowerCase()?await sb(e,t):await ef("adb",oI(e,["install","-r",t]))}async function sA(e){return new Set((await ef("adb",oI(e,["shell","pm","list","packages"]))).stdout.split("\n").map(e=>e.replace("package:","").trim()).filter(Boolean))}async function sI(e,t){let n=Array.from(await sA(e)).filter(e=>!t.has(e));if(1===n.length)return n[0]}async function sx(e,t){await o6.invalidateWhile(o9(e),async()=>{e.booted||await oY(e.id),await sv(e,t)})}async function sS(e,t,n){let a=n?void 0:await sA(e);return await sx(e,t),n??(a?await sI(e,a):void 0)}async function sN(e,t){e.booted||await oY(e.id);let n=await o0({kind:"path",path:t});try{let t=await sS(e,n.installablePath,n.packageName),a=t?sr(t):void 0;return{archivePath:n.archivePath,installablePath:n.installablePath,packageName:t,appName:a,launchTarget:t}}finally{await n.cleanup()}}async function s_(e,t,n){return await o6.invalidateWhile(o9(e),async()=>{e.booted||await oY(e.id);let{package:a}=await sm(e,t),r=await o0({kind:"path",path:n},{resolveIdentity:!1});try{await sx(e,r.installablePath)}finally{await r.cleanup()}return{package:a}})}function sM(e){let t=e.direction,n="up"===t||"down"===t?e.referenceHeight:e.referenceWidth,a=function(e){if(void 0===e)return .6;if(!Number.isFinite(e)||e<=0)throw new y("INVALID_ARGS","scroll amount must be a positive number");return e}(e.amount),r=void 0!==e.pixels?function(e){if(!Number.isFinite(e)||e<=0)throw new y("INVALID_ARGS","scroll pixels must be a positive integer");return Math.max(1,Math.round(e))}(e.pixels):Math.round(n*a),i=Math.max(1,Math.round(.05*n)),o=Math.max(1,Math.min(r,Math.max(1,n-2*i))),s=Math.round(o/2),l=Math.round(e.referenceWidth/2),d=Math.round(e.referenceHeight/2),u=(n,a,r,i)=>({direction:t,x1:n,y1:a,x2:r,y2:i,referenceWidth:e.referenceWidth,referenceHeight:e.referenceHeight,amount:e.amount,pixels:o});switch(t){case"up":return u(l,d-s,l,d+s);case"down":return u(l,d+s,l,d-s);case"left":return u(l-s,d,l+s,d);case"right":return u(l+s,d,l-s,d)}}function sk(e){if(0===e.length)return null;let t=[...e].sort((e,t)=>e-t);return t[Math.floor(t.length/2)]??null}function sD(e,t){let n=Math.max(24,Math.round(.2*Math.min(e.size,t.size))),a=Math.max(48,Math.round(.15*Math.min(e.crossSize,t.crossSize)));return Math.abs(e.size-t.size)<=n&&Math.abs(e.crossSize-t.crossSize)<=a}function sE(e,t){return{start:e.y-t.y,size:e.height,crossSize:e.width}}async function sO(e,t={}){let n=await sC(e,t),a=n.xml;if(!t.interactiveOnly){let r=W(a,800,t);return function(e,t){for(let[n,a]of e){let e=t[n];e&&(a.hiddenContentAbove&&(e.hiddenContentAbove=!0),a.hiddenContentBelow&&(e.hiddenContentBelow=!0))}}(await sT(e,r.nodes),r.nodes),{...r,androidSnapshot:n.metadata}}let r=H(a),i=et(r,800,{...t,interactiveOnly:!1}),o=et(r,800,t),s=await sT(e,i.nodes);sV(s,i,o),0===s.size&&sV(function(e){if(0===e.length)return new Map;let{hintedContainers:t}=e6(e);var n=t.directionsByContainer;let a=new Map;for(let[e,t]of n){let n={};t.has("above")&&(n.hiddenContentAbove=!0),t.has("below")&&(n.hiddenContentBelow=!0),(n.hiddenContentAbove||n.hiddenContentBelow)&&a.set(e,n)}return a}(q(i.nodes)),i,o);let{sourceNodes:l,...d}=o;return{...d,androidSnapshot:n.metadata}}async function sC(e,t){let n=await sR(t.helperArtifact);if(n.artifact){var a,r;let i=(a=e,`${a.platform}:${a.id}`);try{let a=t.helperAdb??(r=e,async(e,t)=>await ef("adb",oI(r,e),t)),o=await X({adb:a,artifact:n.artifact,deviceKey:i,installPolicy:t.helperInstallPolicy,timeoutMs:3e4}),s=await Y({adb:a,packageName:n.artifact.manifest.packageName,instrumentationRunner:n.artifact.manifest.instrumentationRunner,waitForIdleTimeoutMs:500,timeoutMs:8e3,commandTimeoutMs:13e3});return{xml:s.xml,metadata:{backend:"android-helper",helperVersion:n.artifact.manifest.version,helperApiVersion:s.metadata.helperApiVersion,installReason:o.reason,waitForIdleTimeoutMs:s.metadata.waitForIdleTimeoutMs,timeoutMs:s.metadata.timeoutMs,maxDepth:s.metadata.maxDepth,maxNodes:s.metadata.maxNodes,rootPresent:s.metadata.rootPresent,captureMode:s.metadata.captureMode,windowCount:s.metadata.windowCount,nodeCount:s.metadata.nodeCount,helperTruncated:s.metadata.truncated,elapsedMs:s.metadata.elapsedMs}}}catch(t){return Q({deviceKey:i,packageName:n.artifact.manifest.packageName,versionCode:n.artifact.manifest.versionCode}),await sP(e,g(t).message)}}return await sP(e,n.fallbackReason)}async function sR(e){if(e)return{artifact:e};let t=en(),n=o.join(ea(),"android-snapshot-helper","dist"),a=o.join(n,`agent-device-android-snapshot-helper-${t}.manifest.json`);try{await h.access(a)}catch{return{}}try{let e=Z(JSON.parse(await h.readFile(a,"utf8"))),t=o.join(n,e.assetName??`agent-device-android-snapshot-helper-${e.version}.apk`);return await h.access(t),{artifact:{apkPath:t,manifest:e}}}catch(e){return{fallbackReason:g(e).message}}}async function sP(e,t){return{xml:await sL(e),metadata:{backend:"uiautomator-dump",...t?{fallbackReason:t}:{}}}}async function sT(e,t){if(!t.some(e=>ee(e.type)))return new Map;let n=await sG(e);return n?function(e,t){let n=function(e){let t={className:"root",rect:{x:0,y:0,width:0,height:0},children:[]},n=[{indent:-1,node:t}],a=/^(\s*)([\w.$]+)\{[^}]* (-?\d+),(-?\d+)-(-?\d+),(-?\d+) #/;for(let t of e.split("\n")){let e=a.exec(t);if(!e)continue;let r=e[1].length,i=Number(e[3]),o=Number(e[4]),s=Number(e[5]),l=Number(e[6]),d={className:e[2],rect:{x:i,y:o,width:Math.max(0,s-i),height:Math.max(0,l-o)},children:[]};for(;n.length>1&&r<=n[n.length-1].indent;)n.pop();n[n.length-1].node.children.push(d),n.push({indent:r,node:d})}return t.children.length>0?t:null}(t);if(!n)return new Map;let a=function(e){let t=[],n=[e];for(;n.length>0;){let e=n.pop();if(ee(e.className)){let n=function(e){let t=e.children[0];if(!t)return null;let n=Math.max(t.rect.height,...t.children.map(e=>e.rect.y+e.rect.height)),a=t.children.filter(e=>e.rect.height>0).map(t=>sE(t.rect,e.rect)).sort((e,t)=>e.start-t.start);return 0===a.length?null:{rect:e.rect,contentExtent:n,contentBlocks:a}}(e);n&&t.push(n)}n.push(...e.children)}return t}(n);if(0===a.length)return new Map;let r=new Map;for(let t of e){if(!t.rect||!ee(t.type))continue;let n=function(e,t){let n=null,a=1/0;for(let r of t){let t=Math.abs(r.rect.width-e.width)+Math.abs(r.rect.height-e.height);if(t>32)continue;let i=4*t+(Math.abs(r.rect.x-e.x)+Math.abs(r.rect.y-e.y));i<a&&(n=r,a=i)}return n}(t.rect,a);if(!n)continue;let i=function(e,t){let n=function(e,t){let n=t,a=new Set;for(;!a.has(n.index);){var r,i;a.add(n.index);let o=e.filter(e=>e.parentIndex===n.index&&e.rect);if(1!==o.length)return n;let s=o[0];if(r=s.rect,i=t.rect,r.x!==i.x||r.y!==i.y||r.width!==i.width||r.height!==i.height)return n;n=s}return t}(e,t);return e.filter(e=>e.parentIndex===n.index&&e.rect).map(e=>e.rect).filter(e=>e.height>0).sort((e,t)=>e.y-t.y).map(e=>sE(e,t.rect))}(e,t),o=function(e){let{viewportRect:t,visibleBlocks:n,nativeScrollView:a}=e;if(0===n.length||0===a.contentBlocks.length)return null;let r=function(e){if(0===e.contentBlocks.length)return null;let t=e.contentBlocks[0],n=e.contentBlocks[e.contentBlocks.length-1];if(!t||!n)return null;let a=sk(e.contentBlocks.map(e=>e.size))??e.rect.height,r=Math.max(48,Math.round(.5*a)),i=Math.max(24,Math.round(.25*a)),o=t.start>=r,s=e.contentExtent-(n.start+n.size)>=i;return o||s?{above:o,below:s}:null}(a),i=function(e,t){let n=new Map;for(let a of e)for(let e of t){if(!sD(a,e))continue;let t=a.start-e.start,r=8*Math.round(t/8),i=n.get(r)??[];i.push(t),n.set(r,i)}let a=null;for(let e of n.values())(!a||e.length>a.length)&&(a=e);if(!a||a.length<2)return null;let r=[...a].sort((e,t)=>e-t);return r[Math.floor(r.length/2)]??null}(a.contentBlocks,n)??function(e){let{nativeBlocks:t,visibleBlocks:n,viewportExtent:a,contentExtent:r}=e,i=[],o=[];for(let e of t)for(let t of n){if(!sD(e,t))continue;let n=e.start-t.start;16>=Math.abs(n)&&i.push(n),16>=Math.abs(n+a-r)&&o.push(n)}return o.length>0?sk(o):i.length>0?sk(i):null}({nativeBlocks:a.contentBlocks,visibleBlocks:n,viewportExtent:t.height,contentExtent:a.contentExtent});if(null===i)return r;let o=t.height;return{above:(r?.above??!1)||i>16,below:(r?.below??!1)||i+o<a.contentExtent-16}}({viewportRect:t.rect,visibleBlocks:i,nativeScrollView:n});if(!o)continue;let s={};o.above&&(s.hiddenContentAbove=!0),o.below&&(s.hiddenContentBelow=!0),(s.hiddenContentAbove||s.hiddenContentBelow)&&r.set(t.index,s)}return r}(t,n):new Map}async function sL(e){try{return await rS(()=>s$(e),{shouldRetry:sU})}catch(e){if(function(e){if(!(e instanceof y)||"COMMAND_FAILED"!==e.code||"number"!=typeof e.details?.timeoutMs)return!1;let t=e.details?.cmd,n=e.details?.args,a=Array.isArray(n)?n.map(String):"string"==typeof n?n.split(/\s+/):[];return"adb"===t&&a.includes("uiautomator")&&a.includes("dump")}(e)){let t="If the app has looping animations, use screenshot as visual truth, try settings animations off, then retry snapshot. Stock Android UIAutomator may still time out on app-owned infinite animations.";throw new y("COMMAND_FAILED",`Android UI hierarchy dump timed out while waiting for the UI to become idle. ${t}`,{...e.details??{},hint:t},e)}throw e}}async function s$(e){var t,n,a;let r,i,o=await ef("adb",oI(e,["exec-out","uiautomator","dump","/dev/tty"]),{allowFailure:!0,timeoutMs:8e3}),s=sF(o.stdout,o.stderr);if(s)return s;let l="/sdcard/window_dump.xml",d=await ef("adb",oI(e,["shell","uiautomator","dump",l]),{allowFailure:!0,timeoutMs:8e3}),u=(t=l,n=d.stdout,a=d.stderr,r=`${n}
|
|
15
|
+
${a}`,i=/dumped to:\s*(\S+)/i.exec(r),i?.[1]??t),c=await ef("adb",oI(e,["shell","cat",u])),p=sF(c.stdout,c.stderr);if(!p)throw new y("COMMAND_FAILED","uiautomator dump did not return XML",{stdout:c.stdout,stderr:c.stderr});return p}function sF(e,t){let n=`${e}
|
|
16
|
+
${t}`,a=n.indexOf("<?xml"),r=a>=0?a:n.indexOf("<hierarchy");if(r<0)return null;let i=n.lastIndexOf("</hierarchy>");if(i<0||i<r)return null;let o=n.slice(r,i+12).trim();return o.length>0?o:null}function sU(e){if(!(e instanceof y)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details?.stderr,n=("string"==typeof t?t:"").toLowerCase();return!!(n.includes("device offline")||n.includes("device not found")||n.includes("transport error")||n.includes("connection reset")||n.includes("broken pipe")||n.includes("timed out")||n.includes("no such file or directory"))}async function sG(e){try{let t=await ef("adb",oI(e,["shell","dumpsys","activity","top"]),{allowFailure:!0,timeoutMs:8e3}),n=`${t.stdout}
|
|
17
|
+
${t.stderr}`.trim();return n.length>0?n:null}catch{return null}}function sV(e,t,n){if(0===e.size)return;let a=new Map;for(let[e,t]of n.sourceNodes.entries()){let r=n.nodes[e];r&&a.set(t,r)}for(let[n,r]of e){let e=t.sourceNodes[n];if(!e)continue;let i=a.get(e);i&&(r.hiddenContentAbove&&(i.hiddenContentAbove=!0),r.hiddenContentBelow&&(i.hiddenContentBelow=!0))}}async function sB(e,t,n){await ef("adb",oI(e,["shell","input","tap",String(t),String(n)]))}async function sj(e,t,n,a,r,i=250){await ef("adb",oI(e,["shell","input","swipe",String(t),String(n),String(a),String(r),String(i)]))}async function sq(e){await ef("adb",oI(e,["shell","input","keyevent","4"]))}async function sW(e){await ef("adb",oI(e,["shell","input","keyevent","3"]))}async function sX(e,t){let n=function(e){switch(e){case"portrait":return"0";case"landscape-left":return"1";case"portrait-upside-down":return"2";case"landscape-right":return"3";default:throw new y("INVALID_ARGS",`Unsupported Android rotation: ${e}`)}}(t);await ef("adb",oI(e,["shell","settings","put","system","accelerometer_rotation","0"])),await ef("adb",oI(e,["shell","settings","put","system","user_rotation",n]))}async function sH(e){await ef("adb",oI(e,["shell","input","keyevent","187"]))}async function sz(e,t,n,a=800){await ef("adb",oI(e,["shell","input","swipe",String(t),String(n),String(t),String(n),String(a)]))}async function sY(e,t,n=0){n>0&&Array.from(t).length>1?await s3(e,t,1,n):await sK(e,t)}async function sK(e,t){let n=s4(t);if(!n||"ok"!==await s5(e,t))try{let n=t.replace(/ /g,"%s");await ef("adb",oI(e,["shell","input","text",n]))}catch(e){if(n&&function(e){if(!(e instanceof y)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details?.stderr,n=("string"==typeof t?t:"").toLowerCase();return!!(n.includes("exception occurred while executing 'text'")||n.includes("nullpointerexception")&&n.includes("inputshellcommand.sendtext"))}(e))throw new y("COMMAND_FAILED","Non-ASCII text input is not supported on this Android shell. Install an ADB keyboard IME or use ASCII input.",{textPreview:t.slice(0,32)},e instanceof Error?e:void 0);throw e}}async function sJ(e,t,n){await sB(e,t,n)}async function sZ(e,t,n,a,r=0){let i=Array.from(a).length,o=s4(a),s=[{strategy:"input_text",clearPadding:12,minClear:8,maxClear:48}];!o&&r<=0&&s.push({strategy:"clipboard_paste",clearPadding:12,minClear:8,maxClear:48}),(!o||r>0)&&s.push({strategy:"chunked_input",clearPadding:24,minClear:16,maxClear:96});let l=null;for(let o of s){var d,u;await sJ(e,t,n);let s=(d=i+o.clearPadding,u=o.minClear,Math.max(u,Math.min(o.maxClear,d)));if(await s8(e,s),"input_text"===o.strategy)await sY(e,a,r);else if("clipboard_paste"===o.strategy){if("ok"!==await s5(e,a))continue}else await s3(e,a,1,r>0?r:15);let c=await sQ(e,t,n,a);if(l=c.actual,c.ok)return}throw new y("COMMAND_FAILED","Android fill verification failed",{expected:a,actual:l??null})}async function sQ(e,t,n,a){let r=null;for(let i of[0,150,350])if(i>0&&await eb(i),function(e,t){if(e===t)return!0;let n=s0(e),a=s0(t);return!!n&&!!a&&(!!(n===a||n.includes(a))||a.includes(n)&&n.length>=Math.max(4,Math.floor(.8*a.length)))}(r=await s6(e,t,n),a))return{ok:!0,actual:r};return{ok:!1,actual:r}}function s0(e){return(e??"").replace(/\s+/g," ").trim()}async function s1(e,t,n){let a=await s2(e),r=sM({direction:t,amount:n?.amount,pixels:n?.pixels,referenceWidth:a.width,referenceHeight:a.height});return await ef("adb",oI(e,["shell","input","swipe",String(r.x1),String(r.y1),String(r.x2),String(r.y2),"300"])),r}async function s2(e){let t=(await ef("adb",oI(e,["shell","wm","size"]))).stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(!t)throw new y("COMMAND_FAILED","Unable to read screen size");return{width:Number(t[1]),height:Number(t[2])}}async function s3(e,t,n,a){let r=Math.max(1,Math.floor(n)),i=Array.from(t);for(let t=0;t<i.length;t+=r){let n=i.slice(t,t+r).join("");await sK(e,n),a>0&&t+r<i.length&&await eb(a)}}function s4(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 s5(e,t){let n=await ef("adb",oI(e,["shell","cmd","clipboard","set","text",t]),{allowFailure:!0});return 0!==n.exitCode?"failed":oS(n.stdout,n.stderr)?"unsupported":0===(await ef("adb",oI(e,["shell","input","keyevent","KEYCODE_PASTE"]),{allowFailure:!0})).exitCode||0===(await ef("adb",oI(e,["shell","input","keyevent","279"]),{allowFailure:!0})).exitCode?"ok":"failed"}async function s8(e,t){let n=Math.max(0,t);await ef("adb",oI(e,["shell","input","keyevent","KEYCODE_MOVE_END"]),{allowFailure:!0});for(let t=0;t<n;t+=24){let a=Math.min(24,n-t);await ef("adb",oI(e,["shell","input","keyevent",...Array(a).fill("KEYCODE_DEL")]),{allowFailure:!0})}}async function s6(e,t,n){let a,r=await sL(e),i=/<node\b[^>]*>/g,o=null,s=null,l=null;for(;null!==(a=i.exec(r));){let e=z(a[0]),r=K(e.bounds);if(!r)continue;let i=e.className??"",d=(e.text??"").replace(/"/g,'"').replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">").replace(/&/g,"&"),u=e.focused??!1;if(!d)continue;let c=Math.max(1,r.width*r.height),p=t>=r.x&&t<=r.x+r.width&&n>=r.y&&n<=r.y+r.height;if(u&&s9(i)){(!o||c<=o.area)&&(o={text:d,area:c});continue}if(p&&s9(i)){(!s||c<=s.area)&&(s={text:d,area:c});continue}p&&(!l||c<=l.area)&&(l={text:d,area:c})}return o?.text??s?.text??l?.text??null}function s9(e){let t=e.toLowerCase();return t.includes("edittext")||t.includes("textfield")}async function s7(e){let t=await ef("adb",oI(e,["shell","dumpsys","input_method"]),{allowFailure:!0});if(0!==t.exitCode)throw new y("COMMAND_FAILED","Failed to query Android keyboard state",{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode});return function(e){let t=function(e){let t=new Map;for(let n of e.matchAll(/\b(mInputShown|mIsInputViewShown|isInputViewShown)=([a-zA-Z]+)\b/g)){let e=n[1],a=n[2]?.toLowerCase();e&&("true"===a||"false"===a)&&t.set(e,"true"===a)}if(0===t.size)return null;for(let e of t.values())if(e)return!0;return!1}(e),n=t??!1;if(null===t){let t=e.match(/\bmImeWindowVis=0x([0-9a-fA-F]+)\b/);if(t?.[1]){let e=Number.parseInt(t[1],16);Number.isNaN(e)||(n=(1&e)!=0)}}let a=Array.from(e.matchAll(/\binputType=0x([0-9a-fA-F]+)\b/gi)),r=a.length>0?a[a.length-1]?.[1]:void 0,i=r?`0x${r.toLowerCase()}`:void 0;return{visible:n,inputType:i,type:i?function(e){let t=Number.parseInt(e.replace(/^0x/i,""),16);if(Number.isNaN(t))return"unknown";let n=15&t;if(2===n)return"number";if(3===n)return"phone";if(4===n)return"datetime";if(1!==n)return"unknown";let a=4080&t;return 32===a||208===a?"email":128===a||224===a||144===a?"password":"text"}(i):void 0}}(t.stdout)}async function le(e){let t=await s7(e),n=t,a=0;for(;n.visible&&a<2;)await ef("adb",oI(e,["shell","input","keyevent","111"])),a+=1,await eb(120),n=await s7(e);if(t.visible&&n.visible)throw new y("UNSUPPORTED_OPERATION","Android keyboard dismiss is unavailable for the current IME without back navigation.",{attempts:a,inputType:n.inputType,type:n.type});return{attempts:a,wasVisible:t.visible,dismissed:t.visible&&!n.visible,visible:n.visible,inputType:n.inputType,type:n.type}}async function lt(e){let t,n;return(n=(t=(await la(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 ln(e,t){await la(e,["shell","cmd","clipboard","set","text",t],"write")}async function la(e,t,n){let a=await ef("adb",oI(e,t),{allowFailure:!0});if(oS(a.stdout,a.stderr))throw new y("UNSUPPORTED_OPERATION",`Android shell clipboard ${n} is not supported on this device.`);if(0!==a.exitCode)throw new y("COMMAND_FAILED",`Failed to ${n} Android clipboard text`,{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});return a.stdout}let lr=["camera","microphone","photos","contacts","contacts-limited","notifications","calendar","location","location-always","media-library","motion","reminders","siri"];function li(e){let t=e.trim().toLowerCase();if("grant"===t)return"grant";if("deny"===t)return"deny";if("reset"===t)return"reset";throw new y("INVALID_ARGS",`Invalid permission action: ${e}. Use grant|deny|reset.`)}function lo(e){let t=e?.trim().toLowerCase();if("camera"===t||"microphone"===t||"photos"===t||"contacts"===t||"contacts-limited"===t||"notifications"===t||"calendar"===t||"location"===t||"location-always"===t||"media-library"===t||"motion"===t||"reminders"===t||"siri"===t)return t;throw new y("INVALID_ARGS",`permission setting requires a target: ${lr.join("|")}`)}function ls(e){let t=e.trim().toLowerCase();if("light"===t)return"light";if("dark"===t)return"dark";if("toggle"===t)return"toggle";throw new y("INVALID_ARGS",`Invalid appearance state: ${e}. Use light|dark|toggle.`)}let ll=["window_animation_scale","transition_animation_scale","animator_duration_scale"];async function ld(e,t,n,a,r){switch(t.toLowerCase()){case"wifi":{let t=lc(n);await ef("adb",oI(e,["shell","svc","wifi",t?"enable":"disable"]));return}case"airplane":{let t=lc(n);await ef("adb",oI(e,["shell","settings","put","global","airplane_mode_on",t?"1":"0"])),await ef("adb",oI(e,["shell","am","broadcast","-a","android.intent.action.AIRPLANE_MODE","--ez","state",t?"true":"false"]));return}case"location":{let t=lc(n);await ef("adb",oI(e,["shell","settings","put","secure","location_mode",t?"3":"0"]));return}case"animations":{let t=lc(n)?"1":"0";for(let n of ll)await ef("adb",oI(e,["shell","settings","put","global",n,t]));return{scale:t,keys:[...ll]}}case"appearance":{let t=await lp(e,n);await ef("adb",oI(e,["shell","cmd","uimode","night","dark"===t?"yes":"no"]));return}case"fingerprint":{let t=function(e){let t=e.trim().toLowerCase();if("match"===t)return"match";if("nonmatch"===t)return"nonmatch";throw new y("INVALID_ARGS",`Invalid fingerprint state: ${e}. Use match|nonmatch.`)}(n);await lu(e,t);return}case"permission":{if(!a)throw new y("INVALID_ARGS","permission setting requires an active app in session");let t=li(n),i=function(e,t){let n=lo(e);if(t?.trim())throw new y("INVALID_ARGS",`Permission mode is only supported for photos. Received: ${t}.`);if("camera"===n)return{kind:"pm",value:"android.permission.CAMERA",type:"camera"};if("microphone"===n)return{kind:"pm",value:"android.permission.RECORD_AUDIO",type:"microphone"};if("photos"===n)return{kind:"pm",value:"android.permission.READ_MEDIA_IMAGES",type:"photos"};if("contacts"===n)return{kind:"pm",value:"android.permission.READ_CONTACTS",type:"contacts"};if("notifications"===n)return{kind:"notifications",appOps:"POST_NOTIFICATION",permission:"android.permission.POST_NOTIFICATIONS"};throw new y("INVALID_ARGS",`Unsupported permission target on Android: ${e}. Use camera|microphone|photos|contacts|notifications.`)}(r?.permissionTarget,r?.permissionMode);if("notifications"===i.kind)return void await lh(e,a,t,i);let o="grant"===t?"grant":"revoke";if("photos"===i.type)return void await lf(e,a,o);await ef("adb",oI(e,["shell","pm",o,a,i.value]));return}default:throw new y("INVALID_ARGS",`Unsupported setting: ${t}`)}}async function lu(e,t){var n;let a,r,i=(n=e,r=[["shell","cmd","fingerprint","touch",a="match"===t?"1":"9999"],["shell","cmd","fingerprint","finger",a]],"emulator"===n.kind&&r.push(["emu","finger","touch",a]),r),o=[];for(let t of i){let n=await ef("adb",oI(e,t),{allowFailure:!0});if(0===n.exitCode)return;o.push({args:t,stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode})}let s=o.map(e=>({args:e.args.join(" "),exitCode:e.exitCode,stderr:e.stderr.slice(0,400)}));if(o.length>0&&o.every(e=>{var t,n;let a;return t=e.stdout,n=e.stderr,(a=`${t}
|
|
18
|
+
${n}`.toLowerCase()).includes("unknown command")||a.includes("can't find service: fingerprint")||a.includes("service fingerprint was not found")||a.includes("fingerprint cmd unavailable")||a.includes("emu command is not supported")||a.includes("emulator console is not running")||a.includes("fingerprint")&&a.includes("not found")}))throw new y("UNSUPPORTED_OPERATION","Android fingerprint simulation is not supported on this target/runtime.",{deviceId:e.id,action:t,hint:"Use an Android emulator with biometric support, or a device/runtime that exposes cmd fingerprint.",attempts:s});throw new y("COMMAND_FAILED","Failed to simulate Android fingerprint.",{deviceId:e.id,action:t,attempts:s})}function lc(e){let t=e.toLowerCase();if("on"===t||"true"===t||"1"===t)return!0;if("off"===t||"false"===t||"0"===t)return!1;throw new y("INVALID_ARGS",`Invalid setting state: ${e}`)}async function lp(e,t){let n=ls(t);if("toggle"!==n)return n;let a=await ef("adb",oI(e,["shell","cmd","uimode","night"]),{allowFailure:!0});if(0!==a.exitCode)throw new y("COMMAND_FAILED","Failed to read current Android appearance",{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});let r=function(e,t){let n=/night mode:\s*(yes|no|auto)\b/i.exec(`${e}
|
|
19
|
+
${t}`);if(!n)return null;let a=n[1].toLowerCase();return"yes"===a?"dark":"no"===a?"light":"auto"===a?"auto":null}(a.stdout,a.stderr);if(!r)throw new y("COMMAND_FAILED","Unable to determine current Android appearance for toggle",{stdout:a.stdout,stderr:a.stderr});return"auto"===r?"dark":"dark"===r?"light":"dark"}async function lf(e,t,n){let a=await lm(e),r=[];for(let i of null!==a&&a>=33?["android.permission.READ_MEDIA_IMAGES","android.permission.READ_EXTERNAL_STORAGE"]:["android.permission.READ_EXTERNAL_STORAGE","android.permission.READ_MEDIA_IMAGES"]){let a=await ef("adb",oI(e,["shell","pm",n,t,i]),{allowFailure:!0});if(0===a.exitCode)return;r.push({permission:i,stderr:a.stderr,exitCode:a.exitCode})}throw new y("COMMAND_FAILED",`Failed to ${n} Android photos permission`,{appPackage:t,sdkInt:a,attempts:r})}async function lh(e,t,n,a){"grant"===n?await ef("adb",oI(e,["shell","pm","grant",t,a.permission]),{allowFailure:!0}):(await ef("adb",oI(e,["shell","pm","revoke",t,a.permission]),{allowFailure:!0}),"reset"===n&&(await ef("adb",oI(e,["shell","pm","clear-permission-flags",t,a.permission,"user-set"]),{allowFailure:!0}),await ef("adb",oI(e,["shell","pm","clear-permission-flags",t,a.permission,"user-fixed"]),{allowFailure:!0}))),await ef("adb",oI(e,["shell","appops","set",t,a.appOps,"grant"===n?"allow":"deny"===n?"deny":"default"]))}async function lm(e){let t=await ef("adb",oI(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 lw(e,t,n){let a="string"==typeof n.action&&n.action.trim()?n.action.trim():`${t}.TEST_PUSH`,r=["shell","am","broadcast","-a",a,"-p",t],i="string"==typeof n.receiver?n.receiver.trim():"";i&&r.push("-n",i);let o=n.extras;if(void 0!==o&&("object"!=typeof o||null===o||Array.isArray(o)))throw new y("INVALID_ARGS","Android push payload extras must be an object");let s=0;for(let[e,t]of Object.entries(o??{}))e&&(function(e,t,n){if("string"==typeof n)return e.push("--es",t,n);if("boolean"==typeof n)return e.push("--ez",t,n?"true":"false");if("number"==typeof n&&Number.isFinite(n))return Number.isInteger(n)?e.push("--ei",t,String(n)):e.push("--ef",t,String(n));throw new y("INVALID_ARGS",`Unsupported Android broadcast extra type for "${t}". Use string, boolean, or number.`)}(r,e,t),s+=1);return await ef("adb",oI(e,r)),{action:a,extrasCount:s}}let lg=Buffer.from([137,80,78,71,13,10,26,10]);async function ly(e,t){await lb(e);try{await eb(1e3),await lA(e,t)}finally{await lv(e).catch(()=>{})}}async function lb(e){let t=t=>ef("adb",oI(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 lv(e){await ef("adb",oI(e,["shell","am broadcast -a com.android.systemui.demo -e command exit"]),{allowFailure:!0})}async function lA(e,t){let n=await ef("adb",oI(e,["exec-out","screencap","-p"]),{binaryStdout:!0});if(!n.stdoutBuffer)throw new y("COMMAND_FAILED","Failed to capture screenshot");let a=n.stdoutBuffer.indexOf(lg);if(a<0)throw new y("COMMAND_FAILED","Screenshot data does not contain a valid PNG header");let i=function(e,t){let n=t+lg.length;for(;n+8<=e.length;){let t=e.readUInt32BE(n),a=n+4,r=e.toString("ascii",a,a+4),i=n+12+t;if(i>e.length)break;if("IEND"===r)return i;n=i}return null}(n.stdoutBuffer,a);if(!i)throw new y("COMMAND_FAILED","Screenshot data does not contain a complete PNG payload");await r.writeFile(t,n.stdoutBuffer.subarray(a,i))}let lI=ev(process.env.AGENT_DEVICE_IOS_BOOT_TIMEOUT_MS,rv,5e3),lx=ev(process.env.AGENT_DEVICE_IOS_SIMCTL_LIST_TIMEOUT_MS,rb,1e3),lS=ev(process.env.AGENT_DEVICE_IOS_APP_LAUNCH_TIMEOUT_MS,3e4,5e3),lN=ev(process.env.AGENT_DEVICE_IOS_DEVICECTL_TIMEOUT_MS,2e4,1e3),l_=ev(process.env.AGENT_DEVICE_IOS_SIMULATOR_FOCUS_TIMEOUT_MS,1e4,1e3),lM=ev(process.env.AGENT_DEVICE_IOS_SIMULATOR_SCREENSHOT_TIMEOUT_MS,2e4,1e3),lk=ev(process.env.AGENT_DEVICE_IOS_RUNNER_SCREENSHOT_COPY_TIMEOUT_MS,2e4,1e3),lD=ry(process.env.AGENT_DEVICE_IOS_SIMULATOR_SCREENSHOT_RUNNER_FALLBACK);async function lE(e,t){let n=["devicectl",...e],a=await ef("xcrun",n,{allowFailure:!0,timeoutMs:lN});if(0===a.exitCode)return;let r=String(a.stdout??""),i=String(a.stderr??"");throw new y("COMMAND_FAILED",`Failed to ${t.action}`,{cmd:"xcrun",args:n,exitCode:a.exitCode,stdout:r,stderr:i,deviceId:t.deviceId,hint:lP(r,i)??lR})}async function lO(e,t){let n=o.join(s.tmpdir(),`agent-device-ios-apps-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),a=["devicectl","device","info","apps","--device",e.id,"--include-all-apps","--json-output",n],i=await ef("xcrun",a,{allowFailure:!0,timeoutMs:lN});try{var l,d;if(0!==i.exitCode){let t=String(i.stdout??""),n=String(i.stderr??"");throw new y("COMMAND_FAILED","Failed to list iOS apps",{cmd:"xcrun",args:a,exitCode:i.exitCode,stdout:t,stderr:n,deviceId:e.id,hint:lP(t,n)??lR})}let o=await r.readFile(n,"utf8");return l=function(e){let t=e?.result?.apps;if(!Array.isArray(t))return[];let n=[];for(let e of t){if(!e||"object"!=typeof e)continue;let t="string"==typeof e.bundleIdentifier?e.bundleIdentifier.trim():"";if(!t)continue;let a="string"==typeof e.name&&e.name.trim().length>0?e.name.trim():t,r="string"==typeof e.url&&e.url.trim().length>0?e.url.trim():void 0;n.push({bundleId:t,name:a,url:r})}return n}(JSON.parse(o)),d=t,"user-installed"===d?l.filter(e=>!e.bundleId.startsWith("com.apple.")):l}catch(t){if(t instanceof y)throw t;throw new y("COMMAND_FAILED","Failed to parse iOS apps list",{deviceId:e.id,cause:String(t)})}finally{await r.unlink(n).catch(()=>{})}}async function lC(e){let t=o.join(s.tmpdir(),`agent-device-ios-processes-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),n=["devicectl","device","info","processes","--device",e.id,"--json-output",t],a=await ef("xcrun",n,{allowFailure:!0,timeoutMs:lN});try{if(0!==a.exitCode){let t=String(a.stdout??""),r=String(a.stderr??"");throw new y("COMMAND_FAILED","Failed to list iOS processes",{cmd:"xcrun",args:n,exitCode:a.exitCode,stdout:t,stderr:r,deviceId:e.id,hint:lP(t,r)??lR})}let i=await r.readFile(t,"utf8");return function(e){let t=e?.result?.runningProcesses;if(!Array.isArray(t))return[];let n=[];for(let e of t){if(!e||"object"!=typeof e)continue;let t="string"==typeof e.executable?e.executable.trim():"",a="number"==typeof e.processIdentifier&&Number.isFinite(e.processIdentifier)?e.processIdentifier:NaN;t&&Number.isFinite(a)&&n.push({executable:t,pid:a})}return n}(JSON.parse(i))}catch(t){if(t instanceof y)throw t;throw new y("COMMAND_FAILED","Failed to parse iOS process list",{deviceId:e.id,cause:String(t)})}finally{await r.unlink(t).catch(()=>{})}}let lR="Ensure the iOS device is unlocked, trusted, and available in Xcode > Devices, then retry.";function lP(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 lT(e){if(!(e instanceof y)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details??{};if(4!==t.exitCode)return!1;let n=String(t.stderr??"").toLowerCase();return n.includes("fbsopenapplicationserviceerrordomain")&&n.includes("the request to open")}async function lL(e,t){let n=await ef("xcrun",rz(e,["get_app_container",e.id,t]),{allowFailure:!0});if(0!==n.exitCode)return{installed:!1};let a=n.stdout.trim();if(!a)return{installed:!1};let r=await ef("plutil",["-extract","CFBundleExecutable","raw","-o","-",`${a}/Info.plist`],{allowFailure:!0});if(0!==r.exitCode||!r.stdout.trim())return{installed:!0};let i=r.stdout.trim(),o=`${a}/${i}`,s=await ef("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 l$(e,t){if("simulator"!==e.kind)throw new y("UNSUPPORTED_OPERATION",`${t} is only supported on iOS simulators`)}async function lF(){await ef("open",["-a","Simulator"],{allowFailure:!0,timeoutMs:l_})}async function lU(e){let t,n;if("simulator"!==e.kind||"Booted"===await lV(e))return;let a=rI.fromTimeoutMs(lI);try{await rx(async({deadline:a})=>{if(a?.isExpired())throw new y("COMMAND_FAILED","iOS simulator boot deadline exceeded",{timeoutMs:lI});let r=Math.max(1e3,a?.remainingMs()??lI),i=await ef("xcrun",rz(e,["boot",e.id]),{allowFailure:!0,timeoutMs:r});t={stdout:String(i.stdout??""),stderr:String(i.stderr??""),exitCode:i.exitCode};let o=`${t.stdout}
|
|
21
|
+
${t.stderr}`.toLowerCase(),s=o.includes("already booted")||o.includes("current state: booted");if(0!==t.exitCode&&!s)throw new y("COMMAND_FAILED","simctl boot failed",{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode});let l=await ef("xcrun",rz(e,["bootstatus",e.id,"-b"]),{allowFailure:!0,timeoutMs:r});if(n={stdout:String(l.stdout??""),stderr:String(l.stderr??""),exitCode:l.exitCode},0!==n.exitCode)throw new y("COMMAND_FAILED","simctl bootstatus failed",{stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode});let d=await lV(e);if("Booted"!==d)throw new y("COMMAND_FAILED","Simulator is still booting",{state:d})},{maxAttempts:3,baseDelayMs:500,maxDelayMs:2e3,jitter:.2,shouldRetry:e=>{let a=rF({error:e,stdout:n?.stdout??t?.stdout,stderr:n?.stderr??t?.stderr,context:{platform:"ios",phase:"boot"}});return"IOS_BOOT_TIMEOUT"!==a&&"CI_RESOURCE_STARVATION_SUSPECTED"!==a}},{deadline:a,phase:"boot",classifyReason:e=>rF({error:e,stdout:n?.stdout??t?.stdout,stderr:n?.stderr??t?.stderr,context:{platform:"ios",phase:"boot"}})})}catch(i){let r=rF({error:i,stdout:n?.stdout??t?.stdout,stderr:n?.stderr??t?.stderr,context:{platform:"ios",phase:"boot"}});throw new y("COMMAND_FAILED","iOS simulator failed to boot",{platform:"ios",deviceId:e.id,timeoutMs:lI,elapsedMs:a.elapsedMs(),reason:r,hint:rU(r),boot:t,bootstatus:n})}await lF()}async function lG(e){let t=rz(e,["shutdown",e.id]),n=await ef("xcrun",t,{allowFailure:!0,timeoutMs:15e3});return{success:0===n.exitCode,exitCode:n.exitCode,stdout:String(n.stdout??""),stderr:String(n.stderr??"")}}async function lV(e){let t="string"==typeof e?e:e.id,n="string"==typeof e?rH(["list","devices","-j"]):rz(e,["list","devices","-j"]),a=await ef("xcrun",n,{allowFailure:!0,timeoutMs:lx});if(0!==a.exitCode)return null;try{let e=JSON.parse(String(a.stdout??""));for(let n of Object.values(e.devices??{})){let e=n.find(e=>e.udid===t);if(e)return e.state}return null}catch{return null}}async function lB(e,t){try{let n=await ef("plutil",["-extract",t,"raw","-o","-",e],{allowFailure:!0});if(0===n.exitCode){let e=String(n.stdout??"").trim();if(e.length>0)return e}}catch{}try{var n,a;let i;return n=await r.readFile(e,"utf8"),a=t,ig(iw(n),(e,t)=>{void 0===i&&e===a&&"string"===t.name&&(i=t.text??void 0)}),i}catch{return}}async function lj(e,t){if("url"===e.kind&&!ek(e.url))throw new y("INVALID_ARGS","iOS install_from_source URL sources are only supported for trusted artifact services such as GitHub Actions and EAS. Use a path source for other hosts.");let n=await eM({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||ek(e.url),signal:t?.signal}),a=await lW(n.installablePath,t),r=await lq(a.installPath);return{archivePath:n.archivePath??(n.installablePath.toLowerCase().endsWith(".ipa")?n.installablePath:void 0),installablePath:a.installPath,bundleId:r.bundleId,appName:r.appName,cleanup:async()=>{await a.cleanup(),await n.cleanup()}}}async function lq(e){let t=o.join(e,"Info.plist"),[n,a,r]=await Promise.all([lB(t,"CFBundleIdentifier"),lB(t,"CFBundleDisplayName"),lB(t,"CFBundleName")]);return{bundleId:n,appName:a??r}}async function lW(e,t){if(!e.toLowerCase().endsWith(".ipa"))return{installPath:e,cleanup:async()=>{}};let n=await r.mkdtemp(o.join(s.tmpdir(),"agent-device-ios-ipa-")),a=async()=>{await r.rm(n,{recursive:!0,force:!0})};try{await ef("unzip",["-q",e,"-d",n]);let i=o.join(n,"Payload"),s=(await r.readdir(i,{withFileTypes:!0}).catch(()=>{throw new y("INVALID_ARGS","Invalid IPA: missing Payload directory")})).filter(e=>e.isDirectory()&&e.name.toLowerCase().endsWith(".app")).map(e=>({installPath:o.join(i,e.name),bundleName:e.name.replace(/\.app$/i,"")}));if(1===s.length)return{installPath:s[0].installPath,cleanup:a};if(0===s.length)throw new y("INVALID_ARGS","Invalid IPA: expected at least one .app under Payload, found 0");await lX(s);let l=t?.appIdentifierHint?.trim();if(l){let e=function(e,t){let n=t.toLowerCase(),a=e.filter(e=>e.bundleName.toLowerCase()===n);if(1===a.length)return a[0];if(a.length>1)throw new y("INVALID_ARGS",`Invalid IPA: multiple app bundles matched "${t}" by name. Use a bundle id hint instead.`);if(t.includes(".")){let t=e.filter(e=>e.bundleId?.toLowerCase()===n);if(1===t.length)return t[0]}}(s,l);if(e)return{installPath:e.installPath,cleanup:a};throw new y("INVALID_ARGS",`Invalid IPA: found ${s.length} .app bundles under Payload and none matched "${l}". Available bundles: ${s.map(lH).join(", ")}`)}throw new y("INVALID_ARGS",`Invalid IPA: found ${s.length} .app bundles under Payload. Pass an app identifier or bundle name matching one of: ${s.map(lH).join(", ")}`)}catch(e){throw await a(),e}}async function lX(e){await Promise.all(e.map(async e=>{if(e.bundleId&&e.appName)return;let t=await lq(e.installPath);e.bundleId=e.bundleId??t.bundleId,e.appName=e.appName??t.appName}))}function lH(e){let t=e.bundleId??e.appName;return t?`${e.bundleName}.app (${t})`:`${e.bundleName}.app`}function lz(e,t){return"user-installed"===t?e.filter(e=>!e.bundleId.startsWith("com.apple.")):e}let lY={settings:"com.apple.systempreferences"},lK=/^[a-z0-9-]+(?:\.[a-z0-9-]+)+$/,lJ={platform:"macos",deviceId:"host",variant:"all"},lZ=oM();function lQ(e,t){let n=["-b",e];return t&&n.push(t),n}async function l0(e){for(let t of[o.join(e,"Contents","Info.plist"),o.join(e,"Info.plist")]){let[e,n,a]=await Promise.all([lB(t,"CFBundleIdentifier"),lB(t,"CFBundleDisplayName"),lB(t,"CFBundleName")]);if(e||n||a)return{bundleId:e,appName:n??a}}return{}}async function l1(e){let t=e.trim(),n=lY[t.toLowerCase()];if(n)return n;if(lK.test(t))return t;let a=lZ.get(lJ,t);if(a)return a;let r=(await l9("all")).filter(e=>e.name.toLowerCase()===t.toLowerCase());if(1===r.length)return lZ.set(lJ,t,r[0].bundleId);if(r.length>1)throw new y("INVALID_ARGS",`Multiple apps matched "${e}"`,{matches:r});throw new y("APP_NOT_INSTALLED",`No app found matching "${e}"`)}async function l2(e,t,n){let a=n?.url?.trim();if(a){if(!oN(a))throw new y("INVALID_ARGS","open <app> <url> requires a valid URL target");let e=n?.appBundleId??await l1(t);await ef("open",lQ(e,a));return}let r=t.trim();if(oN(r))return void await ef("open",[r]);let i=n?.appBundleId??await l1(r);await ef("open",lQ(i))}async function l3(e,t){let n=await l1(t),a=await om(n);if(a.running&&!a.terminated&&!a.forceTerminated)throw new y("COMMAND_FAILED",`Failed to close macOS app ${t}`,{bundleId:n,running:a.running,terminated:a.terminated,forceTerminated:a.forceTerminated})}async function l4(){let e=await ef("pbpaste",[],{allowFailure:!0});if(0!==e.exitCode)throw new y("COMMAND_FAILED","Failed to read macOS clipboard",{stdout:e.stdout,stderr:e.stderr,exitCode:e.exitCode});return e.stdout.replace(/\r\n/g,"\n").replace(/\n$/,"")}async function l5(e){let t=await ef("pbcopy",[],{allowFailure:!0,stdin:e});if(0!==t.exitCode)throw new y("COMMAND_FAILED","Failed to write macOS clipboard",{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode})}async function l8(){let e=await ef("osascript",["-e",'tell application "System Events" to tell appearance preferences to get dark mode'],{allowFailure:!0});if(0!==e.exitCode)throw new y("COMMAND_FAILED","Failed to read macOS appearance",{stdout:e.stdout,stderr:e.stderr,exitCode:e.exitCode});let t=e.stdout.trim().toLowerCase();if("true"===t)return!0;if("false"===t)return!1;throw new y("COMMAND_FAILED",`Unable to determine current macOS appearance from osascript output: ${e.stdout.trim()}`)}async function l6(e){let t=ls(e),n="toggle"===t?!await l8():"dark"===t,a=`tell application "System Events" to tell appearance preferences to set dark mode to ${n?"true":"false"}`,r=await ef("osascript",["-e",a],{allowFailure:!0});if(0!==r.exitCode)throw new y("COMMAND_FAILED","Failed to set macOS appearance",{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode})}async function l9(e="all"){let t=["/Applications","/System/Applications",o.join(s.homedir(),"Applications")],n=new Set;for(let e of t){let t=await r.stat(e).catch(()=>null);if(!t?.isDirectory())continue;let a=await ef("find",[e,"-maxdepth","4","-type","d","-name","*.app"],{allowFailure:!0});if(0===a.exitCode)for(let e of a.stdout.split("\n")){let t=e.trim();t&&n.add(t)}}return lz((await Promise.all(Array.from(n).map(async e=>{let t=await l0(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 l7=["--time","9:41","--dataNetwork","wifi","--wifiMode","active","--wifiBars","3","--batteryState","charged","--batteryLevel","100"],de={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"},dt={1:"searching",2:"failed",3:"active"},dn={0:"notSupported",1:"searching",2:"failed",3:"active"};function da(e,t,n){return ef("xcrun",rz(e,t),n)}async function dr(e,t){var n,a;let r;await ds(e),t&&await dl(e,(r=[],(n=t).dataNetwork&&r.push("--dataNetwork",n.dataNetwork),n.wifiMode&&r.push("--wifiMode",n.wifiMode),void 0!==n.wifiBars&&("wifi"===n.dataNetwork||n.wifiMode)&&r.push("--wifiBars",n.wifiBars),n.cellularMode&&r.push("--cellularMode",n.cellularMode),void 0!==n.cellularBars&&(n.cellularMode||(a=n.dataNetwork)&&"hide"!==a&&"wifi"!==a||void 0!==n.operatorName)&&r.push("--cellularBars",n.cellularBars),void 0!==n.operatorName&&r.push("--operatorName",n.operatorName),r))}async function di(e){let t=await da(e,["status_bar",e.id,"list"],{allowFailure:!0});if(0!==t.exitCode)throw new y("COMMAND_FAILED","Failed to read simulator status bar overrides",{exitCode:t.exitCode,stdout:t.stdout,stderr:t.stderr});return function(e){let t={};for(let n of e.split("\n").map(e=>e.trim()).filter(e=>e.length>0&&"Current Status Bar Overrides:"!==e&&!/^=+$/.test(e))){let e=/^DataNetworkType:\s+(\d+)$/.exec(n);if(e){let n=Number(e[1]),a=de[n];if(!a)throw new y("COMMAND_FAILED",`Unsupported simulator data network type: ${n}`);t.dataNetwork=a;continue}let a=/^WiFi Mode:\s+(\d+),\s+WiFi Bars:\s+(\d+)$/.exec(n);if(a){let e=dt[Number(a[1])];e&&(t.wifiMode=e),t.wifiBars=a[2];continue}let r=/^Cell Mode:\s+(\d+),\s+Cell Bars:\s+(\d+)$/.exec(n);if(r){let e=Number(r[1]),n=dn[e];if(!n)throw new y("COMMAND_FAILED",`Unsupported simulator cellular mode: ${e}`);t.cellularMode=n,t.cellularBars=r[2];continue}let i=/^Operator Name:\s*(.*)$/.exec(n);if(i){t.operatorName=i[1]??"";continue}}return 0===Object.keys(t).length?null:t}(t.stdout)}async function ds(e){await da(e,["status_bar",e.id,"clear"])}async function dl(e,t){0!==t.length&&await da(e,["status_bar",e.id,"override",...t])}function dd(e,t,n){el({level:"warn",phase:`ios_screenshot_status_bar_${t}`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,...function(e){if(!(e instanceof y))return{reason:e instanceof Error?e.message:String(e)};let t=e.details??{},n=Array.isArray(t.args)?t.args.filter(e=>"string"==typeof e).join(" "):void 0;return{errorCode:e.code,reason:e.message,timeoutMs:"number"==typeof t.timeoutMs?t.timeoutMs:void 0,exitCode:"number"==typeof t.exitCode?t.exitCode:void 0,stderr:"string"==typeof t.stderr&&t.stderr.trim()?t.stderr:void 0,stdout:"string"==typeof t.stdout&&t.stdout.trim()?t.stdout:void 0,commandArgs:n}}(n)}})}function du(e,t,n){return ef("xcrun",rz(e,t),n)}let dc={ensureBooted:lU,prepareStatusBarForScreenshot:async function e(e){let t=null,n=!1;try{t=await di(e),n=!0}catch(t){dd(e,"snapshot_failed",t)}try{await ds(e),await dl(e,l7)}catch(t){dd(e,"prepare_failed",t)}return async()=>{await dr(e,n?t:null)}},captureWithRetry:dh,runnerFallbackEnabled:lD,captureWithRunner:dm,shouldFallbackToRunner:dI};async function dp(e,t,n,a){if("macos"===e.platform)return void await dm(e,t,n,a);if("simulator"===e.kind)return void await df(e,t,n,a);try{await lE(["device","screenshot","--device",e.id,t],{action:"capture iOS screenshot",deviceId:e.id});return}catch(t){if(!function(e){if(!(e instanceof y)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details??{},n="string"==typeof t.stdout?t.stdout:"",a="string"==typeof t.stderr?t.stderr:"",r=`${e.message}
|
|
22
22
|
${n}
|
|
23
|
-
${a}`.toLowerCase();return r.includes("unknown option '--device'")||r.includes("unknown subcommand")&&r.includes("screenshot")||r.includes("unrecognized subcommand")&&r.includes("screenshot")}(t))throw t;
|
|
23
|
+
${a}`.toLowerCase();return r.includes("unknown option '--device'")||r.includes("unknown subcommand")&&r.includes("screenshot")||r.includes("unrecognized subcommand")&&r.includes("screenshot")}(t))throw t;db(e,"devicectl_screenshot",t)}await dm(e,t,n,a)}async function df(e,t,n,a,r=dc){if("simulator"!==e.kind)throw new y("UNSUPPORTED_OPERATION","Simulator screenshot fallback flow supports only iOS simulators");let i="object"==typeof a&&null!==a?a:r;await i.ensureBooted(e);let o=async()=>{};try{o=await i.prepareStatusBarForScreenshot(e)}catch(t){dv(e,"prepare_failed",t)}try{try{await i.captureWithRetry(e,t);return}catch(t){if(!i.shouldFallbackToRunner(t))throw t;if(!i.runnerFallbackEnabled){var s,l,d;let n,a;throw s=e,l=t,n=dA(l),el({level:"warn",phase:"ios_screenshot_fallback_skipped",data:{platform:s.platform,deviceKind:s.kind,deviceId:s.id,from:"simctl_screenshot",to:"runner",reason:"Simulator runner fallback is disabled to avoid XCTest automation instability during screenshot capture.",...n}}),a=(d=t)instanceof y?d:new y("COMMAND_FAILED","Failed to capture iOS screenshot: simulator screenshot retries exhausted",void 0,d),new y(a.code,a.message,{...a.details??{},hint:"Restart the simulator and retry. If simctl screenshots keep timing out and you accept the stability tradeoff, set AGENT_DEVICE_IOS_SIMULATOR_SCREENSHOT_RUNNER_FALLBACK=1 to allow XCTest runner fallback."},a)}db(e,"simctl_screenshot",t)}await i.captureWithRunner(e,t,n,"boolean"==typeof a?a:void 0)}finally{await o().catch(t=>dv(e,"restore_failed",t))}}async function dh(e,t){let n=rI.fromTimeoutMs(lM);await rx(async({deadline:n})=>{await du(e,["io",e.id,"screenshot",t],{timeoutMs:Math.max(1e3,n?.remainingMs()??lM)})},{maxAttempts:5,baseDelayMs:1e3,maxDelayMs:5e3,jitter:.2,shouldRetry:e=>dI(e)},{deadline:n,phase:"ios_simulator_screenshot"})}async function dm(e,t,n,a){let i=(await oe(e,{command:"screenshot",appBundleId:n,fullscreen:a})).message;if(!i)throw new y("COMMAND_FAILED","Failed to capture iOS screenshot: runner returned no file path");"macos"===e.platform?await r.copyFile(i,t):"simulator"===e.kind?await dg(e,i,t):await dw(e,i,t)}async function dw(e,t,n){let a=rI.fromTimeoutMs(lk),r={exitCode:1,stdout:"",stderr:""};for(let i of iD)if(0===(r=await ef("xcrun",["devicectl","device","copy","from","--device",e.id,"--source",t,"--destination",n,"--domain-type","appDataContainer","--domain-identifier",i],{allowFailure:!0,timeoutMs:dy(a,lk,"runner screenshot copy")})).exitCode)return;let i=r.stderr.trim()||r.stdout.trim()||`devicectl exited with code ${r.exitCode}`;throw new y("COMMAND_FAILED",`Failed to capture iOS screenshot: ${i}`)}async function dg(e,t,n){let a=rI.fromTimeoutMs(lk),i="Unable to locate runner container for simulator screenshot";for(let s of iD){let l=await du(e,["get_app_container",e.id,s,"data"],{allowFailure:!0,timeoutMs:dy(a,lk,"runner screenshot container lookup")});if(0!==l.exitCode){let e=l.stderr.trim();e&&(i=e);continue}let d=l.stdout.trim();if(!d){i="simctl get_app_container returned empty output";continue}for(let e of function(e,t){let n=o.resolve(e),a=t.trim();if(!a)return[];let r=[],i=new Set,s=e=>{let t=o.normalize(e);i.has(t)||(i.add(t),r.push(t))},l=a.replace(/^\/+/,""),d=l.replace(/\\/g,"/");if(l&&s(o.join(n,l)),o.isAbsolute(a)&&s(o.normalize(a)),d.startsWith("tmp/"))s(o.join(n,d));else{let e=d.lastIndexOf("/tmp/");if(e>=0){let t=d.slice(e+1);s(o.join(n,t))}}let u=o.basename(a);return u&&s(o.join(n,"tmp",u)),r}(d,t))try{await r.copyFile(e,n);return}catch(e){i=e instanceof Error?e.message:String(e)}}throw new y("COMMAND_FAILED",`Failed to capture iOS screenshot: ${i}`)}function dy(e,t,n){let a=e.remainingMs();if(a>0)return a;throw new y("COMMAND_FAILED",`iOS ${n} timed out after ${t}ms`,{timeoutMs:t,step:n})}function db(e,t,n){let a=dA(n);el({level:"warn",phase:"ios_screenshot_fallback",data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,from:t,to:"runner",...a}})}function dv(e,t,n){el({level:"warn",phase:`ios_screenshot_status_bar_${t}`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,...dA(n)}})}function dA(e){if(!(e instanceof y))return{reason:e instanceof Error?e.message:String(e)};let t=e.details??{},n=Array.isArray(t.args)?t.args.filter(e=>"string"==typeof e).join(" "):void 0;return{errorCode:e.code,reason:e.message,timeoutMs:"number"==typeof t.timeoutMs?t.timeoutMs:void 0,exitCode:"number"==typeof t.exitCode?t.exitCode:void 0,stderr:"string"==typeof t.stderr&&t.stderr.trim()?t.stderr:void 0,stdout:"string"==typeof t.stdout&&t.stdout.trim()?t.stdout:void 0,commandArgs:n}}function dI(e){if(!(e instanceof y)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details??{},n="string"==typeof t.stdout?t.stdout:"",a="string"==typeof t.stderr?t.stderr:"",r=Array.isArray(t.args)?t.args.filter(e=>"string"==typeof e).join(" "):"",i=`${e.message}
|
|
24
24
|
${n}
|
|
25
25
|
${a}
|
|
26
|
-
${r}`.toLowerCase();return i.includes("timeout waiting for screen surfaces")||i.includes("nsposixerrordomain")&&i.includes("code=60")&&i.includes("screenshot")||i.includes("timed out")&&i.includes("screenshot")}let
|
|
27
|
-
${i}`.toLowerCase()))throw new
|
|
28
|
-
${a.stderr}`.toLowerCase()))throw new
|
|
29
|
-
`,"utf8"),await
|
|
30
|
-
${t}`);if(!n)return null;let a=n[1].toLowerCase();return"dark"===a?"dark":"light"===a?"light":null}(a.stdout,a.stderr);if(!r)throw new
|
|
31
|
-
${r.stderr}`);if(0===i.size)throw new
|
|
32
|
-
${n}`.toLowerCase()).includes("unrecognized subcommand")||a.includes("unknown subcommand")||a.includes("not supported")||a.includes("unavailable")||a.includes("biometric")&&a.includes("invalid")}))throw new w("UNSUPPORTED_OPERATION",`${n.label} simulation is not supported on this simulator runtime.`,{deviceId:e.id,action:t,setting:n.settingName,attempts:i});throw new w("COMMAND_FAILED",`Failed to simulate ${n.settingName}.`,{deviceId:e.id,action:t,setting:n.settingName,attempts:i})}async function dS(e,t){await ly(e);let n=0,a=rs.fromTimeoutMs(la);try{await rl(async({deadline:n})=>{var a;if(n?.isExpired())throw new w("COMMAND_FAILED","App launch deadline exceeded",{timeoutMs:la});let r=(a=["launch",e.id,t],rR(e,a)),i=await Z("xcrun",r,{allowFailure:!0});if(0!==i.exitCode)throw new w("COMMAND_FAILED",`xcrun exited with code ${i.exitCode}`,{cmd:"xcrun",args:r,stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode})},{maxAttempts:10,baseDelayMs:1e3,maxDelayMs:5e3,jitter:.2,shouldRetry:e=>!!lh(e)&&(n+=1)<3},{deadline:a})}catch(n){if(lh(n)){var r;let a=(r=await lm(e,t)).installed?!1===r.simulatorCompatible?"ARCH_MISMATCH":"PERSISTENT_LAUNCH_FAIL":"APP_NOT_INSTALLED";n.details={...n.details,hint:function(e){switch(e){case"ARCH_MISMATCH":return"The app binary was not built for the simulator platform. Rebuild with a simulator destination or use a physical device.";case"APP_NOT_INSTALLED":return"The app bundle is not installed on this simulator. Run install before open.";case"PERSISTENT_LAUNCH_FAIL":return"The simulator repeatedly refused to launch the app. Inspect crash logs in Console.app or ~/Library/Logs/DiagnosticReports/ and consider reinstalling the app.";default:return"The simulator failed to launch the app. Retry with --debug and inspect diagnostics log for details."}}(a)}}throw n}}async function d_(e,t,n){let a=["device","process","launch","--device",e.id,t];n?.payloadUrl&&a.push("--payload-url",n.payloadUrl),await ld(a,{action:"launch iOS app",deviceId:e.id})}async function dM(e,t,n,a,r,i,o){if("tv"===t.target)return dE(await e(t,{command:"swipe",direction:function(e){switch(e){case"up":return"down";case"down":return"up";case"left":return"right";case"right":return"left";default:return e}}(r),appBundleId:n.appBundleId},a),i);let s=o??await dk(e,t,n,a),l=sn({direction:r,amount:i?.amount,pixels:i?.pixels,referenceWidth:s.referenceWidth,referenceHeight:s.referenceHeight});return dE(await e(t,{command:"drag",x:s.originX+l.x1,y:s.originY+l.y1,x2:s.originX+l.x2,y2:s.originY+l.y2,appBundleId:n.appBundleId},a),{amount:l.amount,pixels:l.pixels,preferProvidedPixels:!0})}async function dk(e,t,n,a){let r=await e(t,{command:"interactionFrame",appBundleId:n.appBundleId},a),i=dD(r.x),o=dD(r.y),s=dD(r.referenceWidth),l=dD(r.referenceHeight);if(void 0===i||void 0===o||void 0===s||void 0===l)throw new w("COMMAND_FAILED","interactionFrame did not return a usable frame");return{originX:i,originY:o,referenceWidth:s,referenceHeight:l}}function dD(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function dE(e,t){var n;let{x1:a,y1:r,x2:i,y2:o}={x1:dD((n=e).x),y1:dD(n.y),x2:dD(n.x2),y2:dD(n.y2)},s=dD(e.referenceWidth),l=dD(e.referenceHeight),d=void 0!==a&&void 0!==i?Math.round(Math.abs(i-a)):void 0,u=void 0!==r&&void 0!==o?Math.round(Math.abs(o-r)):void 0,c=t?.preferProvidedPixels&&void 0!==t.pixels?t.pixels:d&&d>0?d:u&&u>0?u:void 0;return{...void 0!==a?{x1:a}:{},...void 0!==r?{y1:r}:{},...void 0!==i?{x2:i}:{},...void 0!==o?{y2:o}:{},...void 0!==s?{referenceWidth:s}:{},...void 0!==l?{referenceHeight:l}:{},...t?.amount!==void 0?{amount:t.amount}:{},...void 0!==c?{pixels:c}:{}}}function dO(){return process.env.WAYLAND_DISPLAY||"wayland"===process.env.XDG_SESSION_TYPE?"wayland":"x11"}let dC=null;async function dR(){if(dC)return dC;let e=dO();if("wayland"===e){if(await ee("ydotool"))return dC={tool:"ydotool",display:e};throw new w("TOOL_MISSING","ydotool is required for input synthesis on Wayland (xdotool does not work on Wayland). Install it via your package manager.")}if(await ee("xdotool"))return dC={tool:"xdotool",display:e};throw new w("TOOL_MISSING","xdotool is required for input synthesis on X11. Install it via your package manager.")}async function dP(...e){await Z("xdotool",e,{allowFailure:!1,timeoutMs:1e4})}async function dT(...e){await Z("ydotool",e,{allowFailure:!1,timeoutMs:1e4})}async function dL(e,t){let{tool:n}=await dR();"xdotool"===n?await dP("mousemove","--sync",String(e),String(t)):await dT("mousemove","--absolute","-x",String(e),"-y",String(t))}async function d$(e,t){let{tool:n}=await dR();"xdotool"===n?await dP("key","--clearmodifiers",e):await dT("key",...t)}async function dF(e,t,n,a){await dL(e,t);let{tool:r}=await dR();"xdotool"===r?await dP("click",n):await dT("click",a)}async function dU(e,t){await dF(e,t,"1","0xC0")}async function dG(e,t){await dF(e,t,"3","0xC1")}async function dV(e,t){await dF(e,t,"2","0xC2")}async function dB(e,t){let{tool:n}=await dR();await dL(e,t),"xdotool"===n?await dP("click","--repeat","2","1"):(await dT("click","0xC0"),await dT("click","0xC0"))}async function dj(e,t,n=800){let{tool:a}=await dR();await dL(e,t),"xdotool"===a?(await dP("mousedown","1"),await er(n),await dP("mouseup","1")):(await dT("click","--down","0xC0"),await er(n),await dT("click","--up","0xC0"))}async function dq(e,t){await dU(e,t)}async function dX(e,t,n,a,r=300){let{tool:i}=await dR();await dL(e,t),"xdotool"===i?(await dP("mousedown","1"),await dP("mousemove","--sync",String(n),String(a)),await er(r),await dP("mouseup","1")):(await dT("click","--down","0xC0"),await dT("mousemove","--absolute","-x",String(n),"-y",String(a)),await er(r),await dT("click","--up","0xC0"))}async function dz(e,t){let{tool:n}=await dR(),a=5;if(t?.pixels!=null?a="xdotool"===n?Math.max(1,Math.round(t.pixels/15)):Math.max(1,Math.round(t.pixels/40)):t?.amount!=null&&(a=Math.max(1,Math.round(5*(t.amount/.6)))),"xdotool"===n)await dP("click","--repeat",String(a),"up"===e?"4":"down"===e?"5":"left"===e?"6":"7");else if("up"===e||"down"===e){let t="up"===e?String(-a):String(a);await dT("mousemove","--wheel","-y",t)}else{let t="left"===e?String(-a):String(a);await dT("mousemove","--wheel","-x",t)}}async function dW(e,t=0){let{tool:n}=await dR();if("xdotool"===n){let n=["type"];t>0&&n.push("--delay",String(t)),n.push("--clearmodifiers","--",e),await dP(...n)}else await dT("type","--",e)}async function dH(e,t,n,a=0){await dU(e,t),await er(100),await d$("ctrl+a",["29:1","30:1","30:0","29:0"]),await er(50),await dW(n,a)}function dY(e){let t=null;return{resolve:async function(){if(t)return t;let n="wayland"===dO()?"wayland":"x11";for(let a of"wayland"===n?e.wayland:e.x11)if(await ee(a.command))return t={tool:a.tool,display:n};throw new w("TOOL_MISSING","wayland"===n?e.waylandError:e.x11Error)},resetCache:()=>{t=null}}}let dK=dY({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 dJ(e){let{tool:t}=await dK.resolve();switch(t){case"grim":await Z("grim",[e]);break;case"scrot":await Z("scrot",[e]);break;case"import":await Z("import",["-window","root",e]);break;case"gnome-screenshot":await Z("gnome-screenshot",["-f",e])}}async function dZ(e){if(e.includes("://")||e.startsWith("/"))return void await Z("xdg-open",[e]);if(await ee(e)){Z(e,[],{allowFailure:!0}).catch(t=>{W({level:"warn",phase:"linux_app_launch",data:{app:e,error:String(t)}})}),await er(500);return}await Z("xdg-open",[e],{allowFailure:!0})}async function dQ(e){await ee("wmctrl")?await Z("wmctrl",["-c",e],{allowFailure:!0}):await Z("pkill",["-x",e],{allowFailure:!0})}async function d0(){await d$("alt+Left",["56:1","105:1","105:0","56:0"])}async function d1(){await d$("super+d",["125:1","32:1","32:0","125:0"])}let d2=dY({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 d3(){let{tool:e}=await d2.resolve();switch(e){case"wl-clipboard":return(await Z("wl-paste",["--no-newline"],{allowFailure:!0,timeoutMs:5e3})).stdout;case"xclip":return(await Z("xclip",["-selection","clipboard","-o"],{allowFailure:!0,timeoutMs:5e3})).stdout;case"xsel":return(await Z("xsel",["--clipboard","--output"],{allowFailure:!0,timeoutMs:5e3})).stdout}}async function d4(e){let{tool:t}=await d2.resolve();switch(t){case"wl-clipboard":await Z("wl-copy",["--",e],{allowFailure:!1,timeoutMs:5e3});break;case"xclip":await Z("xclip",["-selection","clipboard"],{allowFailure:!1,timeoutMs:5e3,stdin:e});break;case"xsel":await Z("xsel",["--clipboard","--input"],{allowFailure:!1,timeoutMs:5e3,stdin:e})}}d2.resetCache;let d5={"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"},d8="atspi-dump.py",d6=null;async function d9(e,t={}){let a;if("linux"!==process.platform)throw new w("UNSUPPORTED_PLATFORM","AT-SPI2 bridge is only available on Linux");if(!await ee("python3"))throw new w("TOOL_MISSING","python3 is required for AT-SPI2 accessibility snapshots on Linux.");let r=t.maxNodes??1500,i=t.maxDepth??12,s=t.maxApps??24,l=[function(){if(d6)return d6;let e=o.dirname(c(import.meta.url));for(let t=0;t<5;t++){let a=o.join(e,"src","platforms","linux",d8);if(n.existsSync(a))return d6=a,a;if(0===t){let t=o.join(e,d8);if(n.existsSync(t))return d6=t,t}e=o.dirname(e)}throw new w("TOOL_MISSING",`Cannot find ${d8}. Ensure the agent-device package is installed correctly.`)}(),"--surface",e,"--max-nodes",String(r),"--max-depth",String(i),"--max-apps",String(s)],d=await Z("python3",l,{allowFailure:!0,timeoutMs:3e4});if(0!==d.exitCode){let e=d.stderr.trim();if(e.includes("No module named")||e.includes("gi.require_version"))throw new w("TOOL_MISSING","AT-SPI2 Python bindings not found. Install python3-gi and gir1.2-atspi-2.0.",{cause:e});throw new w("COMMAND_FAILED",`AT-SPI2 snapshot failed (exit ${d.exitCode}): ${e||d.stdout}`)}try{a=JSON.parse(d.stdout)}catch{throw new w("COMMAND_FAILED",`AT-SPI2 snapshot returned invalid JSON: ${d.stdout.slice(0,200)}`)}if(a.error)throw new w("COMMAND_FAILED",`AT-SPI2: ${a.error}`);return{nodes:(a.nodes??[]).map(e=>{let t,n;return{index:e.index,type:(n=d5[t=e.role.toLowerCase().trim()])||t.split(/[\s_-]+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(""),role:e.role,label:e.label??void 0,value:e.value??void 0,rect:e.rect??void 0,enabled:e.enabled??void 0,selected:e.selected??void 0,hittable:e.hittable??void 0,depth:e.depth,parentIndex:e.parentIndex??void 0,pid:e.pid??void 0,appName:e.appName??void 0,windowTitle:e.windowTitle??void 0}}),truncated:a.truncated,surface:e}}async function d7(e){let t="desktop"===e?"desktop":"frontmost-app"===e||"app"===e?"frontmost-app":("menubar"===e&&W({level:"warn",phase:"linux_snapshot",data:{message:"menubar surface is not supported on Linux, falling back to desktop"}}),"desktop"),n=await d9(t);return{nodes:n.nodes,truncated:n.truncated}}function ue(e){return e?.clickButton??"primary"}function ut(e){return"primary"===e.button?null:"click"!==e.commandLabel?new w("INVALID_ARGS","--button is supported only for click"):"macos"!==e.platform&&"linux"!==e.platform?new w("UNSUPPORTED_OPERATION",`click --button ${e.button} is supported only on macOS and Linux`):"macos"===e.platform&&"middle"===e.button?new w("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 w("INVALID_ARGS",`click --button ${e.button} does not support repeat or gesture modifier flags`):null}function un(e){return"primary"===e?{}:{button:e}}let ua=/^[A-Za-z0-9_.:-]{1,64}$/,ur=[[0,0],[1,0],[0,1],[-1,0],[0,-1],[1,1],[-1,1],[1,-1],[-1,-1]];async function ui(e,t,n){for(let a=0;a<e;a+=1)await n(a),a<e-1&&t>0&&await er(t)}function uo(e,t){let a,r=t?.subject??"Payload",i=e.trim();if(!i)throw new w("INVALID_ARGS",`${r} cannot be empty`);let o=t?.expandPath?t.expandPath(i,t.cwd):i;try{if(!n.statSync(o).isFile())throw new w("INVALID_ARGS",`${r} path is not a file: ${o}`);return{kind:"file",path:o}}catch(t){if(t instanceof w)throw t;let e=t.code;if("EACCES"===e||"EPERM"===e)throw new w("INVALID_ARGS",`${r} file is not readable: ${o}`);if(e&&"ENOENT"!==e)throw new w("COMMAND_FAILED",`Unable to read ${r} file: ${o}`,{cause:String(t)})}if((a=i.trim()).startsWith("{")&&a.endsWith("}")||a.startsWith("[")&&a.endsWith("]"))return{kind:"inline",text:i};throw new w("INVALID_ARGS",`${r} file not found: ${o}`)}async function us(e){let t=uo(e,{subject:"Push payload"}),n="inline"===t.kind?t.text:await ul(t.path);try{let e=JSON.parse(n);if(!e||"object"!=typeof e||Array.isArray(e))throw new w("INVALID_ARGS","push payload must be a JSON object");return e}catch(t){if(t instanceof w)throw t;throw new w("INVALID_ARGS",`Invalid push payload JSON: ${e}`)}}async function ul(e){try{return await r.readFile(e,"utf8")}catch(n){let t=n.code;if("ENOENT"===t)throw new w("INVALID_ARGS",`Push payload file not found: ${e}`);if("EISDIR"===t)throw new w("INVALID_ARGS",`Push payload path is not a file: ${e}`);if("EACCES"===t||"EPERM"===t)throw new w("INVALID_ARGS",`Push payload file is not readable: ${e}`);throw new w("COMMAND_FAILED",`Unable to read push payload file: ${e}`,{cause:String(n)})}}function ud(e){if(void 0===e)throw new w("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 w("INVALID_ARGS",`Invalid rotation: ${e}. Use portrait|portrait-upside-down|landscape-left|landscape-right.`)}}let uu=ei(process.env.AGENT_DEVICE_IOS_DEVICECTL_LIST_TIMEOUT_MS,8e3,500),uc=/^(iphone|ipad|ipod|appletv)/i,up=/\b(iphone|ipad|ipod)\b/i,uf=/^appletv/i,uh=["apple tv","appletv","tvos"],um=/^==\s*(.+?)\s*==$/,uw=/^(?<name>.+?)\s+\[(?<id>[^[\]]+)\]\s*$/;function ug(e){return(e??"").trim().toLowerCase()}function uy(e){return ug(e.hardwareProperties?.platform)}function ub(e){return e.includes("tvos")}function uv(e){let t=ug(e);return uh.some(e=>t.includes(e))}function uA(e){return[e.name??"",e.deviceProperties?.name??"",e.deviceProperties?.deviceType??""]}function uI(e){return e.hardwareProperties?.productType??e.deviceProperties?.productType??""}async function ux(e={}){let t,n,a=rD(e.simulatorSetPath),r=e.target;try{t=await Z("xcrun",rC(["list","devices","-j"],{simulatorSetPath:a}))}catch{return null}try{n=JSON.parse(t.stdout)}catch{return null}let i=uN(n,a),o=null,s=null,l=null;for(let e of i)r&&e.target!==r||(e.booted&&(o=o??e),"mobile"===e.target&&(s=s??e),l=l??e);return o??s??l}function uN(e,t){let n=[];for(let[a,r]of Object.entries(e.devices))if(function(e){let t=ug(e);return t.includes("ios")||t.includes("tvos")}(a))for(let e of r)e.isAvailable&&n.push({platform:"ios",id:e.udid,name:e.name,kind:"simulator",target:ub(ug(a))?"tv":"mobile",booted:"Booted"===e.state,...t?{simulatorSetPath:t}:{}});return n}function uS(e,t){let n=new Set(e.map(e=>e.id)),a=[...e];for(let e of t)n.has(e.id)||(n.add(e.id),a.push(e));return a}async function u_(){let e=null;try{e=o.join(s.tmpdir(),`agent-device-devicectl-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);let t=await Z("xcrun",["devicectl","list","devices","--json-output",e],{allowFailure:!0,timeoutMs:uu});if(0!==t.exitCode)return[];let n=await r.readFile(e,"utf8");return function(e){let t=[];for(let n of e.result?.devices??[]){if(!function(e){var t;let n=uy(e);return!!(n.includes("ios")||n.includes("tvos"))||(t=uI(e),!!uc.test(t.trim())||uA(e).some(uv))}(n))continue;let e=n.hardwareProperties?.udid??n.identifier??"",a=n.name??n.deviceProperties?.name??e;e&&t.push({platform:"ios",id:e,name:a,kind:"device",target:function(e){var t;return ub(uy(e))?"tv":(t=uI(e),uf.test(t.trim())||uA(e).some(uv))?"tv":"mobile"}(n),booted:!0})}return t}(JSON.parse(n))}catch{return[]}finally{e&&await r.rm(e,{force:!0}).catch(()=>{})}}async function uM(){try{let e=await Z("xcrun",["xctrace","list","devices"],{allowFailure:!0});if(0!==e.exitCode)return[];return function(e){let t=[],n=null;for(let a of e.split(/\r?\n/)){let e=a.trim();if(!e)continue;let r=um.exec(e);if(r){n=r[1]?.trim()??null;continue}if("Devices"!==n)continue;let i=uw.exec(e),o=i?.groups?.id?.trim()??"",s=i?.groups?.name?.trim()??"";if(!o||!s)continue;let l=function(e){return uv(e)?"tv":up.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 uk(e={}){if("darwin"!==process.platform)throw new w("UNSUPPORTED_PLATFORM","Apple tools are only available on macOS");if(!await ee("xcrun"))throw new w("TOOL_MISSING","xcrun not found in PATH");let t=rD(e.simulatorSetPath),n=await Z("xcrun",rC(["list","devices","-j"],{simulatorSetPath:t})),a=[];try{let e=JSON.parse(n.stdout);a=uN(e,t)}catch(e){throw new w("COMMAND_FAILED","Failed to parse simctl devices JSON",void 0,e)}if(a.push({platform:"macos",id:"host-macos-local",name:s.hostname(),kind:"device",target:"desktop",booted:!0}),t)return a;let[r,i]=await Promise.all([u_(),uM()]);return a=uS(a,r),uS(a,i)}async function uD(){return"linux"!==process.platform?[]:[{platform:"linux",id:"local",name:l(),kind:"device",target:"desktop",booted:!0}]}async function uE(e,t,n){let a,r=!!(t.udid||t.serial||t.deviceName);try{a=await a5(e,t,n)}catch(e){if(r||!(e instanceof w)||"DEVICE_NOT_FOUND"!==e.code)throw e}if(!r&&(!t.platform||"apple"===t.platform||"ios"===t.platform)&&"desktop"!==t.target&&(!a||"device"===a.kind)){let e=await ux({simulatorSetPath:n.simulatorSetPath,target:t.target});if(e)return e}if(a)return a;throw new w("DEVICE_NOT_FOUND","No devices found",{selector:t})}async function uO(e){let t=a1(e.platform),n=a4({simulatorSetPath:rD(e.iosSimulatorDeviceSet),platform:t,target:e.target}),a=rO(e.androidDeviceAllowlist);return await X("resolve_target_device",async()=>{let r={platform:t,target:e.target,deviceName:e.device,udid:e.udid,serial:e.serial};if(r.target&&!r.platform)throw new w("INVALID_ARGS","Device target selector requires --platform. Use --platform ios|macos|android|linux|apple with --target mobile|tv|desktop.");if("linux"===r.platform){let e=await uD();return await a5(e,r)}if("android"===r.platform){await oa();let e=await ob({serialAllowlist:a});return await a5(e,r)}if(r.platform){let e=await uk({simulatorSetPath:n});return await uE(e,r,{simulatorSetPath:n})}let i=[];try{i.push(...await ob({serialAllowlist:a}))}catch{}try{i.push(...await uk({simulatorSetPath:n}))}catch{}try{i.push(...await uD())}catch{}return await a5(i,r,{simulatorSetPath:n})},{platform:t,target:e.target})}async function uC(e,t,n,a,i){let s={requestId:i?.requestId,appBundleId:i?.appBundleId,verbose:i?.verbose,logPath:i?.logPath,traceLogPath:i?.traceLogPath},l=function(e,t){switch(e.platform){case"android":return{open:(t,n)=>oz(e,t,n?.activity),openDevice:()=>oZ(e),close:t=>oQ(e,t),tap:(t,n)=>sA(e,t,n),doubleTap:async(t,n)=>{await sA(e,t,n),await sA(e,t,n)},swipe:(t,n,a,r,i)=>sI(e,t,n,a,r,i),longPress:(t,n,a)=>sM(e,t,n,a),focus:(t,n)=>sE(e,t,n),type:(t,n)=>sk(e,t,n),fill:(t,n,a,r)=>sO(e,t,n,a,r),scroll:(t,n)=>sP(e,t,n),screenshot:t=>s6(e,t),back:t=>sx(e),home:()=>sN(e),rotate:t=>sS(e,t),appSwitcher:()=>s_(e),readClipboard:()=>sq(e),writeClipboard:t=>sX(e,t),setSetting:(t,n,a,r)=>sZ(e,t,n,a,r)};case"linux":return{open:e=>dZ(e),openDevice:()=>Promise.resolve(),close:e=>dQ(e),tap:(e,t)=>dU(e,t),doubleTap:(e,t)=>dB(e,t),swipe:(e,t,n,a,r)=>dX(e,t,n,a,r),longPress:(e,t,n)=>dj(e,t,n),focus:(e,t)=>dq(e,t),type:(e,t)=>dW(e,t),fill:(e,t,n,a)=>dH(e,t,n,a),scroll:(e,t)=>dz(e,t),screenshot:e=>dJ(e),back:()=>d0(),home:()=>d1(),rotate:()=>{throw new w("UNSUPPORTED_OPERATION","rotate not supported on Linux")},appSwitcher:()=>{throw new w("UNSUPPORTED_OPERATION","appSwitcher not yet supported on Linux")},readClipboard:()=>d3(),writeClipboard:e=>d4(e),setSetting:()=>{throw new w("UNSUPPORTED_OPERATION","setSetting not supported on Linux")}};case"ios":case"macos":{let n,{overrides:a,runnerOpts:r}={runnerOpts:n={verbose:t.verbose,logPath:t.logPath,traceLogPath:t.traceLogPath,requestId:t.requestId},overrides:{tap:async(a,r)=>await iq(e,{command:"tap",x:a,y:r,appBundleId:t.appBundleId},n),doubleTap:async(a,r)=>await iq(e,{command:"tapSeries",x:a,y:r,count:1,intervalMs:0,doubleTap:!0,appBundleId:t.appBundleId},n),swipe:async(a,r,i,o,s)=>await iq(e,{command:"drag",x:a,y:r,x2:i,y2:o,durationMs:s,appBundleId:t.appBundleId},n),longPress:async(a,r,i)=>await iq(e,{command:"longPress",x:a,y:r,durationMs:i,appBundleId:t.appBundleId},n),focus:async(a,r)=>await iq(e,{command:"tap",x:a,y:r,appBundleId:t.appBundleId},n),type:async(a,r)=>{await iq(e,{command:"type",text:a,delayMs:r,appBundleId:t.appBundleId},n)},fill:async(a,r,i,o)=>{let s=await iq(e,{command:"tap",x:a,y:r,appBundleId:t.appBundleId},n);return await iq(e,{command:"type",text:i,clearFirst:!0,delayMs:o,appBundleId:t.appBundleId},n),s},scroll:async(a,r)=>await dM(iq,e,t,n,a,r)}};return{open:(t,n)=>dr(e,t,{appBundleId:n?.appBundleId,url:n?.url}),openDevice:()=>di(e),close:t=>ds(e,t),screenshot:async(t,n)=>{"macos"===e.platform&&n?.surface&&"app"!==n.surface?await ot(t,{surface:n.surface,fullscreen:n.fullscreen}):await lZ(e,t,n?.appBundleId,n?.fullscreen)},back:async n=>{await iq(e,{command:"system"===n?"backSystem":"backInApp",appBundleId:t.appBundleId},r)},home:async()=>{await iq(e,{command:"home",appBundleId:t.appBundleId},r)},rotate:async n=>{await iq(e,{command:"rotate",orientation:n,appBundleId:t.appBundleId},r)},appSwitcher:async()=>{await iq(e,{command:"appSwitcher",appBundleId:t.appBundleId},r)},readClipboard:()=>dp(e),writeClipboard:t=>df(e,t),setSetting:(t,n,a,r)=>dm(e,t,n,a,r),...a}}default:throw new w("UNSUPPORTED_PLATFORM",`Unsupported platform: ${e.platform}`)}}(e,s);return W({level:"debug",phase:"platform_command_prepare",data:{command:t,platform:e.platform,kind:e.kind}}),await X("platform_command",async()=>{switch(t){case"open":return uR(e,l,n,i);case"close":{let e=n[0];if(!e)return{closed:"session",...q("Closed session")};return await l.close(e),{app:e,...q(`Closed: ${e}`)}}case"press":return uP(e,l,n,i,s);case"swipe":return uT(e,l,n,i,s);case"longpress":{let e=Number(n[0]),t=Number(n[1]),a=n[2]?Number(n[2]):void 0;if(Number.isNaN(e)||Number.isNaN(t))throw new w("INVALID_ARGS","longpress requires x y [durationMs]");return await l.longPress(e,t,a),{x:e,y:t,durationMs:a,...q(`Long pressed (${e}, ${t})`)}}case"focus":{let[e,t]=n.map(Number);if(Number.isNaN(e)||Number.isNaN(t))throw new w("INVALID_ARGS","focus requires x y");return await l.focus(e,t),{x:e,y:t,...q(`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 w("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 w("INVALID_ARGS","type requires text");let a=nd(i?.delayMs??0,"delay-ms",0,1e4);return await l.type(t,a),{text:t,delayMs:a,...q(uz("Typed",t))}}case"fill":{let e=Number(n[0]),t=Number(n[1]),a=n.slice(2).join(" ");if(Number.isNaN(e)||Number.isNaN(t)||!a)throw new w("INVALID_ARGS","fill requires x y text");let r=nd(i?.delayMs??0,"delay-ms",0,1e4);return await l.fill(e,t,a,r),{x:e,y:t,text:a,delayMs:r,...q(uz("Filled",a))}}case"scroll":return uL(l,n,i);case"pinch":return u$(e,n,i,s);case"trigger-app-event":{let{eventName:t,payload:a}=function(e){let t=e[0]?.trim(),n=e[1]?.trim();if(!t)throw new w("INVALID_ARGS","trigger-app-event requires <event> [payloadJson]");if(!ua.test(t))throw new w("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 w("INVALID_ARGS","trigger-app-event accepts at most two arguments: <event> [payloadJson]");let a=function(e,t){if(e)try{let n=JSON.parse(e);if(!n||"object"!=typeof n||Array.isArray(n))throw new w("INVALID_ARGS",`trigger-app-event payload for "${t}" must be a JSON object`);let a=JSON.stringify(n);if(Buffer.byteLength(a,"utf8")>8192)throw new w("INVALID_ARGS",`trigger-app-event payload for "${t}" exceeds 8192 bytes`);return n}catch(t){if(t instanceof w)throw t;throw new w("INVALID_ARGS",`Invalid trigger-app-event payload JSON: ${e}`)}}(n,t);return{eventName:t,payload:a}}(n),r=function(e,t,n){var a;let r,i=(r=("ios"===(a=e)?process.env.AGENT_DEVICE_IOS_APP_EVENT_URL_TEMPLATE:"macos"===a?process.env.AGENT_DEVICE_MACOS_APP_EVENT_URL_TEMPLATE:process.env.AGENT_DEVICE_ANDROID_APP_EVENT_URL_TEMPLATE)??process.env.AGENT_DEVICE_APP_EVENT_URL_TEMPLATE,r?.trim()||void 0);if(!i)throw new w("UNSUPPORTED_OPERATION",`No app event URL template configured for ${e}.`,{hint:`Set AGENT_DEVICE_${e.toUpperCase()}_APP_EVENT_URL_TEMPLATE or AGENT_DEVICE_APP_EVENT_URL_TEMPLATE, for example "myapp://agent-device/event?name={event}&payload={payload}".`});let o=n?JSON.stringify(n):"",s=i.replaceAll("{event}",encodeURIComponent(t)).replaceAll("{payload}",encodeURIComponent(o)).replaceAll("{platform}",encodeURIComponent(e));if(s.length>4096)throw new w("INVALID_ARGS","trigger-app-event URL exceeds maximum supported length",{hint:"Reduce payload size or shorten AGENT_DEVICE_*_APP_EVENT_URL_TEMPLATE.",length:s.length,maxLength:4096});return s}(e.platform,t,a);return await l.open(r,{appBundleId:i?.appBundleId}),{event:t,eventUrl:r,transport:"deep-link",...q(`Triggered app event: ${t}`)}}case"screenshot":{let e=n[0]??a??`./screenshot-${Date.now()}.png`;return await r.mkdir(o.dirname(e),{recursive:!0}),await l.screenshot(e,{appBundleId:i?.appBundleId,fullscreen:i?.screenshotFullscreen,surface:i?.surface}),{path:e,...q(`Saved screenshot: ${e}`)}}case"back":return await l.back(i?.backMode),{action:"back",mode:i?.backMode??"in-app",...q("Back")};case"home":return await l.home(),{action:"home",...q("Home")};case"rotate":{let e=ud(n[0]);return await l.rotate(e),{action:"rotate",orientation:e,...q(`Rotated to ${e}`)}}case"app-switcher":return await l.appSwitcher(),{action:"app-switcher",...q("Opened app switcher")};case"clipboard":return uF(l,n);case"keyboard":return uU(e,l,n,i,s);case"settings":return uG(e,l,n,i);case"push":return uV(e,n,i);case"snapshot":return uB(e,n,i,s);case"read":return uj(e,n,i,s);default:throw new w("INVALID_ARGS",`Unknown command: ${t}`)}},{command:t,platform:e.platform})}async function uR(e,t,n,a){let r=n[0],i=n[1];if(n.length>2)throw new w("INVALID_ARGS","open accepts at most two arguments: <app|url> [url]");if(!r)return await t.openDevice(),{app:null,...q("Opened device")};if(void 0!==i){if("android"===e.platform)throw new w("INVALID_ARGS","open <app> <url> is supported only on Apple platforms");if(oi(r))throw new w("INVALID_ARGS","open <app> <url> requires an app target as the first argument");if(!oi(i))throw new w("INVALID_ARGS","open <app> <url> requires a valid URL target");return await t.open(r,{activity:a?.activity,appBundleId:a?.appBundleId,url:i}),{app:r,url:i,...q(`Opened: ${r}`)}}return await t.open(r,{activity:a?.activity,appBundleId:a?.appBundleId}),{app:r,...q(`Opened: ${r}`)}}async function uP(e,t,n,a,r){let i,[o,s]=n.map(Number);if(Number.isNaN(o)||Number.isNaN(s))throw new w("INVALID_ARGS","press requires x y");if("macos"===e.platform&&a?.surface&&"app"!==a.surface){let e=ue(a);if("primary"!==e)throw new w("UNSUPPORTED_OPERATION",`${e} click is not supported on macOS ${a.surface} sessions.`);return await oe(o,s,{bundleId:a.appBundleId,surface:a.surface}),{x:o,y:s,...q(uq({x:o,y:s}))}}let l=ue(a);if("primary"!==l){let t=ut({commandLabel:"click",platform:e.platform,button:l,count:a?.count,intervalMs:a?.intervalMs,holdMs:a?.holdMs,jitterPx:a?.jitterPx,doubleTap:a?.doubleTap});if(t)throw t;return"linux"===e.platform?"secondary"===l?await dG(o,s):await dV(o,s):await iq(e,{command:"mouseClick",x:o,y:s,button:l,appBundleId:a?.appBundleId},{verbose:a?.verbose,logPath:a?.logPath,traceLogPath:a?.traceLogPath,requestId:a?.requestId}),{x:o,y:s,button:l,...q(uq({x:o,y:s,button:l}))}}let d=nd(a?.count??1,"count",1,200),u=nd(a?.intervalMs??0,"interval-ms",0,1e4),c=nd(a?.holdMs??0,"hold-ms",0,1e4),p=nd(a?.jitterPx??0,"jitter-px",0,100),f=a?.doubleTap===!0;if(f&&c>0)throw new w("INVALID_ARGS","double-tap cannot be combined with hold-ms");if(f&&p>0)throw new w("INVALID_ARGS","double-tap cannot be combined with jitter-px");if(a2(e.platform)&&d>1&&0===c&&0===p){let t=await iq(e,{command:"tapSeries",x:o,y:s,count:d,intervalMs:u,doubleTap:f,appBundleId:a?.appBundleId},{verbose:a?.verbose,logPath:a?.logPath,traceLogPath:a?.traceLogPath,requestId:a?.requestId});return{x:o,y:s,count:d,intervalMs:u,holdMs:c,jitterPx:p,doubleTap:f,timingMode:"runner-series",...t,...q(uq({x:o,y:s}))}}return await ui(d,u,async e=>{let[n,a]=function(e,t){if(t<=0)return[0,0];let[n,a]=ur[e%ur.length];return[n*t,a*t]}(e,p),r=o+n,l=s+a;if(f){i??=await t.doubleTap(r,l)??void 0;return}c>0?i??=await t.longPress(r,l,c)??void 0:i??=await t.tap(r,l)??void 0}),z({x:o,y:s,count:d,intervalMs:u,holdMs:c,jitterPx:p,doubleTap:f,...i},uq({x:o,y:s}))}async function uT(e,t,n,a,r){let i=Number(n[0]),o=Number(n[1]),s=Number(n[2]),l=Number(n[3]);if([i,o,s,l].some(Number.isNaN))throw new w("INVALID_ARGS","swipe requires x1 y1 x2 y2 [durationMs]");let d=nd(n[4]?Number(n[4]):250,"durationMs",16,1e4),u="ios"===e.platform?Math.min(60,Math.max(16,Math.round(d))):d,c=nd(a?.count??1,"count",1,200),p=nd(a?.pauseMs??0,"pause-ms",0,1e4),f=a?.pattern??"one-way";if("one-way"!==f&&"ping-pong"!==f)throw new w("INVALID_ARGS",`Invalid pattern: ${f}`);if(a2(e.platform)&&c>1){let t=await iq(e,{command:"dragSeries",x:i,y:o,x2:s,y2:l,durationMs:u,count:c,pauseMs:p,pattern:f,appBundleId:a?.appBundleId},{verbose:a?.verbose,logPath:a?.logPath,traceLogPath:a?.traceLogPath,requestId:a?.requestId});return{x1:i,y1:o,x2:s,y2:l,durationMs:d,effectiveDurationMs:u,timingMode:"runner-series",count:c,pauseMs:p,pattern:f,...t,...q(uX(c,f))}}return await ui(c,p,async e=>{"ping-pong"===f&&e%2==1?await t.swipe(s,l,i,o,u):await t.swipe(i,o,s,l,u)}),z({x1:i,y1:o,x2:s,y2:l,durationMs:d,effectiveDurationMs:u,timingMode:"ios"===e.platform?"safe-normalized":"direct",count:c,pauseMs:p,pattern:f},uX(c,f))}async function uL(e,t,n){let a=t[0],r=t[1]?Number(t[1]):void 0,i=n?.pixels;if(!a)throw new w("INVALID_ARGS","scroll requires direction");if(void 0!==r&&!Number.isFinite(r))throw new w("INVALID_ARGS","scroll amount must be a number");if(void 0!==r&&void 0!==i)throw new w("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 w("INVALID_ARGS",`Unknown direction: ${e}`)}}(a),s=await e.scroll(o,{amount:r,pixels:i});return z({direction:o,...void 0!==r?{amount:r}:{},...void 0!==i?{pixels:i}:{},...s},void 0!==i?`Scrolled ${o} by ${i}px`:void 0!==r?`Scrolled ${o} by ${r}`:`Scrolled ${o}`)}async function u$(e,t,n,a){if("android"===e.platform)throw new w("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 w("UNSUPPORTED_OPERATION","pinch is only supported in macOS app sessions. Re-open the target app without --surface desktop|menubar|frontmost-app first.");let r=Number(t[0]),i=t[1]?Number(t[1]):void 0,o=t[2]?Number(t[2]):void 0;if(Number.isNaN(r)||r<=0)throw new w("INVALID_ARGS","pinch requires scale > 0");return await iq(e,{command:"pinch",scale:r,x:i,y:o,appBundleId:n?.appBundleId},{verbose:n?.verbose,logPath:n?.logPath,traceLogPath:n?.traceLogPath,requestId:n?.requestId}),{scale:r,x:i,y:o,...q(`Pinched to scale ${r}`)}}async function uF(e,t){let n=(t[0]??"").toLowerCase();if("read"!==n&&"write"!==n)throw new w("INVALID_ARGS","clipboard requires a subcommand: read or write");if("read"===n){if(1!==t.length)throw new w("INVALID_ARGS","clipboard read does not accept additional arguments");return{action:n,text:await e.readClipboard()}}if(t.length<2)throw new w("INVALID_ARGS",'clipboard write requires text (use "" to clear clipboard)');let a=t.slice(1).join(" ");return await e.writeClipboard(a),{action:n,textLength:Array.from(a).length,...q("Clipboard updated")}}async function uU(e,t,n,a,r){let i=(n[0]??"status").toLowerCase();if("status"!==i&&"get"!==i&&"dismiss"!==i)throw new w("INVALID_ARGS","keyboard requires a subcommand: status, get, or dismiss");if(n.length>1)throw new w("INVALID_ARGS","keyboard accepts at most one subcommand argument");if("android"===e.platform){if("dismiss"===i){let t=await sj(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 sB(e);return{platform:"android",action:"status",visible:t.visible,inputType:t.inputType,type:t.type}}if("ios"===e.platform){if("dismiss"!==i)throw new w("UNSUPPORTED_OPERATION","keyboard status/get is currently supported only on Android; use keyboard dismiss on iOS");let t=await iq(e,{command:"keyboardDismiss",appBundleId:a?.appBundleId},r);return{platform:"ios",action:"dismiss",wasVisible:t.wasVisible,dismissed:t.dismissed,visible:t.visible,...q(t.dismissed?"Keyboard dismissed":"Keyboard already hidden")}}throw new w("UNSUPPORTED_OPERATION","keyboard is supported only on Android and iOS")}async function uG(e,t,n,a){var r;let[i,o,s,l,d]=n,u="permission"===i?{permissionTarget:s,permissionMode:l}:void 0;W({level:"debug",phase:"settings_apply",data:{setting:i,state:o,target:s,mode:l,platform:e.platform}});let c=await t.setSetting(i,o,d??a?.appBundleId,u);return c&&"object"==typeof c?z({setting:i,state:o,...c},("string"==typeof(r=c).message&&r.message.length>0?r.message:void 0)??`Updated setting: ${i}`):{setting:i,state:o,...q(`Updated setting: ${i}`)}}async function uV(e,t,n){let a=t[0]?.trim(),r=t[1]?.trim();if(!a||!r)throw new w("INVALID_ARGS","push requires <bundle|package> <payload.json|inline-json>");let i=await us(r);if("ios"===e.platform)return await dh(e,a,i),{platform:"ios",bundleId:a,...q(`Pushed notification to ${a}`)};let o=await s5(e,a,i);return{platform:"android",package:a,action:o.action,extrasCount:o.extrasCount,...q(`Pushed notification to ${a}`)}}async function uB(e,t,n,a){if("linux"===e.platform){let e=await X("snapshot_capture",async()=>await d7(n?.surface),{backend:"linux-atspi"});return{nodes:e.nodes??[],truncated:e.truncated??!1,backend:"linux-atspi"}}if("android"!==e.platform){let t=await X("snapshot_capture",async()=>await iq(e,{command:"snapshot",appBundleId:n?.appBundleId,interactiveOnly:n?.snapshotInteractiveOnly,compact:n?.snapshotCompact,depth:n?.snapshotDepth,scope:n?.snapshotScope,raw:n?.snapshotRaw},{verbose:n?.verbose,logPath:n?.logPath,traceLogPath:n?.traceLogPath,requestId:n?.requestId}),{backend:"xctest"}),a=t.nodes??[];if(0===a.length&&"simulator"===e.kind)throw new w("COMMAND_FAILED","XCTest snapshot returned 0 nodes on iOS simulator.");return{nodes:a,truncated:t.truncated??!1,backend:"xctest"}}let r=await X("snapshot_capture",async()=>await sf(e,{interactiveOnly:n?.snapshotInteractiveOnly,compact:n?.snapshotCompact,depth:n?.snapshotDepth,scope:n?.snapshotScope,raw:n?.snapshotRaw}),{backend:"android"});return{nodes:r.nodes??[],truncated:r.truncated??!1,backend:"android",analysis:r.analysis}}async function uj(e,t,n,a){let[r,i]=t.map(Number);if(Number.isNaN(r)||Number.isNaN(i))throw new w("INVALID_ARGS","read requires x y");if("android"===e.platform)return{action:"read",text:await sG(e,r,i)??""};if("macos"===e.platform&&n?.surface&&"app"!==n.surface)return{action:"read",text:(await i7(r,i,{bundleId:n.appBundleId,surface:n.surface})).text};let o=await iq(e,{command:"readText",x:r,y:i,appBundleId:n?.appBundleId},{verbose:n?.verbose,logPath:n?.logPath,traceLogPath:n?.traceLogPath,requestId:n?.requestId});return{action:"read",text:"string"==typeof o.text?o.text:"string"==typeof o.message?o.message:""}}function uq(e){return e.button&&"primary"!==e.button?`Clicked ${e.button} (${e.x}, ${e.y})`:`Tapped (${e.x}, ${e.y})`}function uX(e,t){return e<=1?"Swiped":"ping-pong"===t?`Swiped ${e} times (ping-pong)`:`Swiped ${e} times`}function uz(e,t){return`${e} ${Array.from(t).length} chars`}let uW=ei(process.env.AGENT_DEVICE_IOS_DEVICE_READY_TIMEOUT_MS,15e3,1e3);async function uH(e){if("ios"===e.platform){if("simulator"===e.kind){let{ensureBootedSimulator:t}=await Promise.resolve(eg);await t(e);return}if("device"===e.kind)return void await uY(e.id)}if("android"===e.platform){let{waitForAndroidBoot:t}=await Promise.resolve(ew);await t(e.id)}}async function uY(e){let t=o.join(s.tmpdir(),`agent-device-ready-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),n=Math.max(1,Math.ceil(uW/1e3));try{let a=await Z("xcrun",["devicectl","device","info","details","--device",e,"--json-output",t,"--timeout",String(n)],{allowFailure:!0,timeoutMs:uW+3e3}),r=String(a.stdout??""),i=String(a.stderr??""),o=await uK(t);if(0===a.exitCode){if(!o.parsed)throw new w("COMMAND_FAILED","iOS device readiness probe failed",{kind:"probe_inconclusive",deviceId:e,stdout:r,stderr:i,hint:"CoreDevice returned success but readiness JSON output was missing or invalid. Retry; if it persists restart Xcode and the iOS device."});let t=o?.tunnelState?.toLowerCase();if("connecting"===t)throw new w("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 w("COMMAND_FAILED","iOS device is not ready for automation",{kind:"not_ready",deviceId:e,stdout:r,stderr:i,exitCode:a.exitCode,tunnelState:o?.tunnelState,hint:uJ(r,i)})}catch(t){if(t instanceof w&&"COMMAND_FAILED"===t.code){if("not_ready"===("string"==typeof t.details?.kind?t.details.kind:""))throw t;let n=t.details??{},a=String(n.stdout??""),r=String(n.stderr??""),i=Number(n.timeoutMs??uW),o=`CoreDevice did not respond within ${i}ms. Keep the device unlocked and trusted, then retry; if it persists restart Xcode and the iOS device.`;throw new w("COMMAND_FAILED","iOS device readiness probe failed",{deviceId:e,cause:t.message,timeoutMs:i,stdout:a,stderr:r,hint:a||r?uJ(a,r):o},t)}throw new w("COMMAND_FAILED","iOS device readiness probe failed",{deviceId:e,hint:"Reconnect the device, keep it unlocked, and retry."},t instanceof Error?t:void 0)}finally{await r.rm(t,{force:!0}).catch(()=>{})}}async function uK(e){try{let t=await r.readFile(e,"utf8"),n=JSON.parse(t),a=function(e){let t=e?.result;if(!t||"object"!=typeof t)return{};let n=t.connectionProperties?.tunnelState,a=t.device?.connectionProperties?.tunnelState,r="string"==typeof n?n:"string"==typeof a?a:void 0;return r?{tunnelState:r}:{}}(n);return{parsed:!0,tunnelState:a.tunnelState}}catch{return{parsed:!1}}}function uJ(e,t){let n=lf(e,t);return n||(`${e}
|
|
33
|
-
${t}`.toLowerCase().includes("timed out waiting for all destinations")?"Xcode destination did not become available in time. Keep device unlocked and retry.":lp)}async function uZ(e,t,n){let a=e.get(t),r=a?.device??await uO(n??{});return a||await uH(r),{session:a,device:r}}async function uQ(e,t,n){let a=!e&&"ios"===t.platform;try{return await n()}finally{a&&await i$(t.id)}}function u0(e,t,n,a){t&&e.recordAction(t,{command:n.command,positionals:n.positionals??[],flags:n.flags??{},result:a})}async function u1(e){let{req:t,logPath:n,sessionStore:a,session:r,device:i}=e,o=(t.positionals?.[0]??"get").toLowerCase(),s=r?"frontmost-app"===r.surface?{surface:"frontmost-app"}:{bundleId:r.appBundleId,surface:r.surface}:{};if(!rt("alert",i))return aZ("UNSUPPORTED_OPERATION","alert is not supported on this device");if("macos"===i.platform){let e=async()=>await i6("wait"===o?"get":o,s);if("wait"===o){let n=aQ(t.positionals?.[1])??1e4,i=Date.now();for(;Date.now()-i<n;){try{let n=await e();return u0(a,r,t,n),{ok:!0,data:n}}catch{}await er(300)}return aZ("COMMAND_FAILED","alert wait timed out")}let n="accept"===o||"dismiss"===o?o:"get";if("accept"===n||"dismiss"===n){let e,i=Date.now();for(;Date.now()-i<2e3;){try{let e=await i6(n,s);return u0(a,r,t,e),{ok:!0,data:e}}catch(n){e=n;let t=String(n?.message??"").toLowerCase();if(!t.includes("alert not found")&&!t.includes("no alert"))break}await er(300)}throw u2(e)}let i=await i6("get",s);return u0(a,r,t,i),{ok:!0,data:i}}if("wait"===o){let e=aQ(t.positionals?.[1])??1e4,o=Date.now();for(;Date.now()-o<e;){try{let e=await iq(i,{command:"alert",action:"get",appBundleId:r?.appBundleId},{verbose:t.flags?.verbose,logPath:n,traceLogPath:r?.trace?.outPath,requestId:t.meta?.requestId});return u0(a,r,t,e),{ok:!0,data:e}}catch{}await er(300)}return aZ("COMMAND_FAILED","alert wait timed out")}let l="accept"===o||"dismiss"===o?o:"get",d={verbose:t.flags?.verbose,logPath:n,traceLogPath:r?.trace?.outPath,requestId:t.meta?.requestId};if("accept"===l||"dismiss"===l){let e,n=Date.now();for(;Date.now()-n<2e3;){try{let e=await iq(i,{command:"alert",action:l,appBundleId:r?.appBundleId},d);return u0(a,r,t,e),{ok:!0,data:e}}catch(n){e=n;let t=String(n?.message??"").toLowerCase();if(!t.includes("alert not found")&&!t.includes("no alert"))break}await er(300)}throw u2(e)}let u=await iq(i,{command:"alert",action:l,appBundleId:r?.appBundleId},d);return u0(a,r,t,u),{ok:!0,data:u}}function u2(e){if(!(e instanceof w))return e;let t=String(e.message??"").toLowerCase();return t.includes("alert not found")||t.includes("no alert")?new w(e.code,e.message,{...e.details??{},hint:"If the permission sheet is visible in snapshot or screenshot but alert reports no alert, take a scoped snapshot around the visible button label and use press @ref."}):e}function u3(e,t,n,a,r){return{requestId:r??j().requestId,appBundleId:n,activity:t?.activity,verbose:t?.verbose,logPath:e,traceLogPath:a,snapshotInteractiveOnly:t?.snapshotInteractiveOnly,snapshotCompact:t?.snapshotCompact,snapshotDepth:t?.snapshotDepth,snapshotScope:t?.snapshotScope,snapshotRaw:t?.snapshotRaw,screenshotFullscreen:t?.screenshotFullscreen,screenshotMaxSize:t?.screenshotMaxSize,count:t?.count,intervalMs:t?.intervalMs,delayMs:t?.delayMs,holdMs:t?.holdMs,jitterPx:t?.jitterPx,pixels:t?.pixels,doubleTap:t?.doubleTap,clickButton:ue(t),backMode:t?.backMode,pauseMs:t?.pauseMs,pattern:t?.pattern}}async function u4(e){let t,{req:n,logPath:a,sessionStore:r,session:i,device:o,parsed:s}=e,{setting:l,state:d,permissionTarget:u}=s;if(!rt("settings",o))return aZ("UNSUPPORTED_OPERATION","settings is not supported on this device");if("macos"===o.platform&&"appearance"!==(t=l.trim().toLowerCase())&&"permission"!==t)return aZ("INVALID_ARGS",eD(l));let c=i?.appBundleId,p="permission"===l?[l,d,u??"",n.positionals?.[3]??"",c??""]:[l,d,c??""],f=await uC(o,"settings",p,n.flags?.out,{...u3(a,n.flags,c,i?.trace?.outPath)});return u0(r,i,n,f??{setting:l,state:d}),{ok:!0,data:f??{setting:l,state:d}}}function u5(e,t={}){let n=!0===t.plural?"do":"does";return{resolveInput:async()=>{throw new w("UNSUPPORTED_OPERATION",`${e} ${n} not resolve input artifacts`)},reserveOutput:async()=>{throw new w("UNSUPPORTED_OPERATION",`${e} ${n} not reserve output artifacts`)},createTempFile:async()=>{throw new w("UNSUPPORTED_OPERATION",`${e} ${n} not create temporary files`)}}}let u8=[250,400,600];function u6(e,t,n=e.snapshot){if("android"!==e.device.platform)return;let a=n?.comparisonSafe===!0;e.androidSnapshotFreshness={action:t,markedAt:Date.now(),baselineCount:n?.nodes.length??0,baselineSignatures:a?ct(n?.nodes??[]):void 0,routeComparable:a}}function u9(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 u7(e){e&&"android"===e.device.platform&&delete e.androidSnapshotFreshness}function ce(e){return"press"===e||"click"===e||"back"===e||"open"===e}function ct(e){return e.map(e=>[e.depth??0,e.type??"",e.role??"",e.label??"",e.value??"",e.identifier??"",!1===e.enabled?"disabled":"enabled",!0===e.selected?"selected":"unselected",!0===e.hittable?"hittable":"not-hittable"].join("|"))}async function cn(e){let t=u9(e.session);if(t&&"android"===e.device.platform)return await cr(e,t);let n=await ca(e);return u7(e.session),{snapshot:cs(n,e.flags),analysis:n.analysis}}async function ca(e){let{device:t,session:n,flags:a,outPath:r,logPath:i,snapshotScope:o}=e;if("linux"===t.platform){let e=await d7(n?.surface);return cl({nodes:e.nodes,truncated:e.truncated,backend:"linux-atspi"},{snapshotDepth:a?.snapshotDepth,snapshotInteractiveOnly:a?.snapshotInteractiveOnly,snapshotScope:o})}return"macos"===t.platform&&n?.surface&&"app"!==n.surface?cl(await i9(n.surface,{bundleId:"menubar"===n.surface?n.appBundleId:void 0}),{snapshotDepth:a?.snapshotDepth,snapshotInteractiveOnly:a?.snapshotInteractiveOnly,snapshotScope:o}):await uC(t,"snapshot",[],r,{...u3(i,{...a,snapshotScope:o},n?.appBundleId,n?.trace?.outPath)})}async function cr(e,t){let n=await ci(e),a=co(n,t,e),r=0,i=t.markedAt+1500;for(let o of u8){if(!a)break;let s=i-Date.now();if(s<=0)break;await er(Math.min(o,s)),n=await ci(e),r+=1,a=co(n,t,e)}return a||u7(e.session),{snapshot:n.snapshot,analysis:n.data.analysis,freshness:r>0||a?{action:t.action,retryCount:r,staleAfterRetries:!!a,reason:a??void 0}:void 0}}async function ci(e){let t=await ca(e);return{data:t,snapshot:cs(t,e.flags)}}function co(e,t,n){var a,r;let i=n.flags?.snapshotInteractiveOnly===!0,o=e.data.analysis;if(i&&0===e.snapshot.nodes.length&&o&&o.rawNodeCount>=12)return"empty-interactive";if("ref-refresh"===n.androidFreshnessMode)return null;return(a=t.baselineCount,r=e.snapshot.nodes.length,!(a<12)&&r<=Math.floor(.2*a))?e.snapshot.nodes.some(e=>!0===e.hittable||!!e.label?.trim()||!!e.value?.trim()||!!e.identifier?.trim())?null:"sharp-drop":t.routeComparable&&ce(t.action)&&function(e,t){if(!e||0===e.length)return!1;let n=Math.max(e.length,t.length);if(n<12)return!1;let a=ct(t),r=Math.min(e.length,a.length),i=0;for(let t=0;t<r;t+=1)e[t]===a[t]&&(i+=1);let o=Math.max(0,a.length-e.length),s=Math.max(0,e.length-a.length),l=Math.max(3,Math.floor(.15*n));return i>=Math.floor(.9*n)&&o<=l&&s<=l}(t.baselineSignatures,e.snapshot.nodes)?"stuck-route":null}function cs(e,t){let n=e?.nodes??[],a=function(e){let t=new Map;for(let[n,a]of e.entries())t.set(a.index,n);let n=[],a=[];for(let[r,i]of e.entries()){let e=Math.max(0,i.depth??0);for(;a.length>0&&e<=a[a.length-1].depth;)a.pop();let o="number"==typeof i.parentIndex?t.get(i.parentIndex):void 0,s="number"==typeof o&&o<r?o:a[a.length-1]?.index;n.push({...i,index:r,depth:e,parentIndex:s}),a.push({depth:e,index:r})}return n}(t?.snapshotRaw?n:N(n));return{nodes:B(t?.snapshotScope&&e?.backend!=="macos-helper"?cd(a,t.snapshotScope):a),truncated:e?.truncated,createdAt:Date.now(),backend:e?.backend,comparisonSafe:e?.backend==="android"&&t?.snapshotInteractiveOnly!==!0&&t?.snapshotCompact!==!0&&"number"!=typeof t?.snapshotDepth&&!t?.snapshotScope}}function cl(e,t){var n,a;let r=e.nodes??[];return t.snapshotScope&&(r=cd(r,t.snapshotScope)),t.snapshotInteractiveOnly&&(r=function(e){if(0===e.length)return e;let t=new Map;for(let n of e)t.set(n.index,n);let n=new Set;for(let a of e){if(!function(e){if(e.hittable||e.rect)return!0;let t=`${e.type??""} ${e.role??""} ${e.subrole??""}`.toLowerCase();return t.includes("button")||t.includes("menu")||t.includes("textfield")||t.includes("searchfield")||t.includes("checkbox")||t.includes("radio")||t.includes("switch")}(a))continue;let e=a;for(;e&&!n.has(e.index);)n.add(e.index),e="number"==typeof e.parentIndex?t.get(e.parentIndex):void 0}return 0===n.size?e:cu(e.filter(e=>n.has(e.index)))}(r)),"number"==typeof t.snapshotDepth&&(n=r,a=t.snapshotDepth,r=cu(n.filter(e=>(e.depth??0)<=a))),{...e,nodes:r}}function cd(e,t){let n=E(B(e),t);if(!n)return[];let a=e.findIndex(e=>e.index===n.index);if(-1===a)return[];let r=e[a]?.depth??0,i=[];for(let t=a;t<e.length;t+=1){let n=e[t];if(!n)continue;let o=n.depth??0;if(t>a&&o<=r)break;i.push(n)}return cu(i,r)}function cu(e,t=0){let n=new Map;for(let[t,a]of e.entries())n.set(a.index,t);return e.map((e,a)=>({...e,index:a,depth:Math.max(0,(e.depth??0)-t),parentIndex:"number"==typeof e.parentIndex?n.get(e.parentIndex):void 0}))}function cc(e,t){if(!e||!e.trim().startsWith("@"))return{ok:!0,scope:e};if(!t?.snapshot)return aZ("INVALID_ARGS","Ref scope requires an existing snapshot in session.");let n=V(e.trim());if(!n)return aZ("INVALID_ARGS",`Invalid ref scope: ${e}`);let a=U(t.snapshot.nodes,n),r=a?O(a,t.snapshot.nodes):void 0;return r?{ok:!0,scope:r}:aZ("COMMAND_FAILED",`Ref ${e} not found or has no label`)}async function cp(e){let{req:t,sessionName:n,logPath:a,sessionStore:r}=e,{session:i,device:o}=await uZ(r,n,t.flags);if(!rt("snapshot",o))return aZ("UNSUPPORTED_OPERATION","snapshot is not supported on this device");let s=cc(t.flags?.snapshotScope,i);return s.ok?await uQ(i,o,async()=>{let e=ch({req:t,sessionName:n,logPath:a,sessionStore:r,session:i,device:o,snapshotScope:s.scope}),l=await e.capture.snapshot({session:n,interactiveOnly:t.flags?.snapshotInteractiveOnly,compact:t.flags?.snapshotCompact,depth:t.flags?.snapshotDepth,scope:s.scope,raw:t.flags?.snapshotRaw});return cm({req:t,sessionName:n,sessionStore:r,result:{nodes:l.nodes.length,truncated:l.truncated}}),{ok:!0,data:l}}):s}async function cf(e){let{req:t,sessionName:n,logPath:a,sessionStore:r}=e,{session:i,device:o}=await uZ(r,n,t.flags);if(!rt("diff",o))return aZ("UNSUPPORTED_OPERATION","diff is not supported on this device");let s=cc(t.flags?.snapshotScope,i);return s.ok?await uQ(i,o,async()=>{let e=ch({req:t,sessionName:n,logPath:a,sessionStore:r,session:i,device:o,snapshotScope:s.scope}),l=await e.capture.diffSnapshot({session:n,interactiveOnly:t.flags?.snapshotInteractiveOnly,compact:t.flags?.snapshotCompact,depth:t.flags?.snapshotDepth,scope:s.scope,raw:t.flags?.snapshotRaw});return cm({req:t,sessionName:n,sessionStore:r,result:{mode:"snapshot",baselineInitialized:l.baselineInitialized,summary:l.summary}}),{ok:!0,data:l}}):s}function ch(e){let{req:t,sessionName:n,logPath:a,sessionStore:r,session:i,device:o,snapshotScope:s}=e;return aY({backend:function(e){let{req:t,logPath:n,session:a,device:r,snapshotScope:i}=e;return{platform:r.platform,captureSnapshot:async(e,o)=>{let s=await cn({device:r,session:a,flags:t.flags,outPath:o?.outPath??t.flags?.out,logPath:n,snapshotScope:i});return{snapshot:s.snapshot,analysis:s.analysis,freshness:s.freshness,appName:a?.appBundleId?a.appName??a.appBundleId:void 0,appBundleId:a?.appBundleId}}}}({req:t,logPath:a,session:i,device:o,snapshotScope:s}),artifacts:u5("snapshot"),sessions:{get:e=>e===n?function(e){if(e)return{name:e.name,appBundleId:e.appBundleId,appName:e.appName,snapshot:e.snapshot,metadata:{surface:e.surface}}}(r.get(n)):void 0,set:e=>{if(!e.snapshot)throw new w("UNKNOWN","snapshot runtime did not produce session state");let t=function(e){let{session:t,sessionName:n,device:a,snapshot:r,appBundleId:i}=e;return t?{...t,snapshot:r}:{name:n,device:a,createdAt:Date.now(),appBundleId:i,snapshot:r,actions:[]}}({session:r.get(n),sessionName:n,device:o,snapshot:e.snapshot,appBundleId:e.appBundleId});e.appName&&(t.appName=e.appName),r.set(n,t)}},policy:aJ()})}function cm(e){let t=e.sessionStore.get(e.sessionName);t&&e.sessionStore.recordAction(t,{command:e.req.command,positionals:e.req.positionals??[],flags:e.req.flags??{},result:e.result})}function cw(e){if(e.length<2)return null;let t=Number(e[0]),n=Number(e[1]);return Number.isFinite(t)&&Number.isFinite(n)?{x:t,y:n}:null}async function cg(e){let{device:t,node:n,flags:a,appBundleId:r,traceOutPath:i,surface:o,contextFromFlags:s}=e,l=k(n),d=function(e){let t=function(e){if(!e)return null;let t=Number(e.x),n=Number(e.y),a=Number(e.width),r=Number(e.height);return Number.isFinite(t)&&Number.isFinite(n)&&Number.isFinite(a)&&Number.isFinite(r)&&!(a<0)&&!(r<0)?{x:t,y:n,width:a,height:r}:null}(e);if(!t)return null;let n=G(t);return Number.isFinite(n.x)&&Number.isFinite(n.y)?n:null}(n.rect);if(!d)return l;try{let e=await uC(t,"read",[String(d.x),String(d.y)],void 0,{...s(a,r,i),surface:o}),u=e&&"object"==typeof e?e:void 0,c="string"==typeof u?.text?u.text:"";if(c.trim())return c;return W({level:"warn",phase:"interaction_read_fallback",data:{reason:"empty_backend_text",nodeRef:n.ref,surface:o,platform:t.platform}}),l}catch(e){return W({level:"warn",phase:"interaction_read_fallback",data:{reason:"backend_read_failed",nodeRef:n.ref,surface:o,platform:t.platform,error:e instanceof Error?e.message:String(e)}}),l}}let cy=[["snapshotDepth","--depth"],["snapshotScope","--scope"],["snapshotRaw","--raw"]];function cb(e,t){let n=function(e){if(!e)return[];let t=[];for(let[n,a]of cy)void 0!==e[n]&&t.push(a);return t}(t);return 0===n.length?null:aZ("INVALID_ARGS",`${e} @ref does not support ${n.join(", ")}.`)}async function cv(e,t){let n=await cA(e);if(n)throw new w("COMMAND_FAILED",`press ${t} left ${e.appBundleId} and foregrounded ${n.foregroundPackage}. The tap likely escaped the app.`,n)}async function cA(e){var t;if("android"!==e.device.platform||!e.appBundleId)return null;let n=await oq(e.device),a=n.package?.trim();return a&&a!==e.appBundleId&&("com.android.settings"===(t=a)||"com.android.systemui"===t||"com.google.android.permissioncontroller"===t||t.includes("launcher"))?{expectedPackage:e.appBundleId,foregroundPackage:a,activity:n.activity,hint:"com.google.android.permissioncontroller"===a?"Dismiss or allow the permission prompt, then retry the smoke assertion.":"Use screenshot as visual truth, then take a fresh snapshot -i before retrying."}:null}function cI(e){return"COMMAND_FAILED"===e.code&&"string"==typeof e.details?.expectedPackage&&"string"==typeof e.details?.foregroundPackage}function cx(e,t,n,a){let r=e.get(t);r&&e.recordAction(r,{command:n.command,positionals:n.positionals??[],flags:n.flags??{},result:a})}function cN(e){let t=e.target;return t&&"object"==typeof t?"ref"===t.kind&&"string"==typeof t.ref?{kind:"ref",ref:t.ref}:"selector"===t.kind&&"string"==typeof t.selector?{kind:"selector",selector:t.selector}:void 0:void 0}function cS(e){return e.startsWith("@")?e.slice(1):e}async function c_(e){var t;let{req:n}=e;if("find"!==n.command)return null;let a=n.positionals??[];if(0===a.length)return aZ("INVALID_ARGS","find requires a locator or text");let r=ea(a);if(!r.query)return aZ("INVALID_ARGS","find requires a value");if(n.flags?.findFirst&&n.flags?.findLast)return aZ("INVALID_ARGS","find accepts only one of --first or --last");let i=r.action;if("exists"!==(t=i)&&"wait"!==t&&"get_text"!==t&&"get_attrs"!==t)return null;let o=await cO(e,{requireSession:!1,capability:"find"});return o.ok?await cP(async()=>{let t=await o.runtime.selectors.find({session:e.sessionName,requestId:n.meta?.requestId,locator:r.locator,query:r.query,action:i,timeoutMs:r.timeoutMs});return cx(e.sessionStore,e.sessionName,n,function(e,t){if("exists"===t)return{found:!0};if("wait"===t)return{found:!0,waitedMs:e.waitedMs};let n="string"==typeof e.ref?e.ref:void 0;return"get_attrs"===t?{ref:n,action:"get attrs"}:{ref:n,action:"get text",text:"string"==typeof e.text?e.text:""}}(t,i)),"found"===t.kind?{found:!0,..."number"==typeof t.waitedMs?{waitedMs:t.waitedMs}:{}}:{..."string"==typeof t.ref?{ref:t.ref}:{},..."string"==typeof t.text?{text:t.text}:{},...t.node&&"object"==typeof t.node?{node:t.node}:{}}}):o.response}async function cM(e){let{req:t}=e;if("get"!==t.command)return null;let n=t.positionals?.[0];if("text"!==n&&"attrs"!==n)return aZ("INVALID_ARGS","get only supports text or attrs");let a=await cO(e,{requireSession:!0,capability:"get"});if(!a.ok)return a.response;let r=function(e){let t=e.positionals?.[1]??"";if(t.startsWith("@"))return{ok:!0,target:{kind:"ref",ref:t,fallbackLabel:e.positionals.length>2?e.positionals.slice(2).join(" ").trim():""}};let n=e.positionals?.slice(1).join(" ").trim()??"";return n?{ok:!0,target:{kind:"selector",selector:n}}:{ok:!1,response:aZ("INVALID_ARGS","get requires @ref or selector expression")}}(t);if(!r.ok)return r.response;if("ref"===r.target.kind){let e=cb("get",t.flags);if(e)return e}return await cP(async()=>{let i,o=await a.runtime.selectors.get({session:e.sessionName,requestId:t.meta?.requestId,property:n,target:r.target});return cx(e.sessionStore,e.sessionName,t,function(e,t){let n=Array.isArray(e.selectorChain)?e.selectorChain:void 0,a=cN(e),r=a?.kind==="ref"?cS(a.ref):void 0,i=a?.kind==="selector"?a.selector:void 0,o={...r?{ref:r}:{},...i?{selector:i}:{},...n?{selectorChain:n}:{}};if("attrs"===t)return o;let s="string"==typeof e.text?e.text:"";return{...o,text:s,refLabel:function(e){let t=e.trim();if(!(!t||t.length>80||/[\r\n]/.test(t)))return t}(s)}}(o,n)),i=cN(o),{...i?.kind==="ref"?{ref:cS(i.ref)}:{},...i?.kind==="selector"?{selector:i.selector}:{},..."string"==typeof o.text?{text:o.text}:{},...o.node&&"object"==typeof o.node?{node:o.node}:{}}})}async function ck(e){let{req:t}=e;if("is"!==t.command)return null;let n=(t.positionals?.[0]??"").toLowerCase();if(!t1(n))return aZ("INVALID_ARGS","is requires predicate: visible|hidden|exists|editable|selected|text");let{split:a}=D(t.positionals??[]);if(!a)return aZ("INVALID_ARGS","is requires a selector expression");let r=a.rest.join(" ").trim();if("text"===n&&!r)return aZ("INVALID_ARGS","is text requires expected text value");if("text"!==n&&a.rest.length>0)return aZ("INVALID_ARGS",`is ${n} does not accept trailing values`);let i=await cO(e,{requireSession:!0,capability:"is"});if(!i.ok)return i.response;let o=await cP(async()=>{let o=await i.runtime.selectors.is({session:e.sessionName,requestId:t.meta?.requestId,predicate:n,selector:a.selectorExpression,expectedText:r});return cx(e.sessionStore,e.sessionName,t,o),function(e){let{selectorChain:t,...n}=e;return n}(o)});return await cT(e,o,`is ${n}`)}async function cD(e){let{req:t,sessionName:n,sessionStore:a}=e,r=a0(t.positionals??[]);if(!r)return aZ("INVALID_ARGS","wait requires a duration or text");let{session:i,device:o}=await uZ(a,n,t.flags);if("sleep"!==r.kind&&!rt("wait",o))return aZ("UNSUPPORTED_OPERATION","wait is not supported on this device");let s=async()=>{let s=cE({...e,session:i,device:o}),l=await cP(async()=>{let e=await s.selectors.wait({session:n,requestId:t.meta?.requestId,target:function(e,t){if("sleep"===e.kind)return{kind:"sleep",durationMs:e.durationMs};if("selector"===e.kind)return{kind:"selector",selector:e.selectorExpression,timeoutMs:e.timeoutMs};if("ref"===e.kind){if(!t?.snapshot)throw new w("INVALID_ARGS","Ref wait requires an existing snapshot in session.");return{kind:"ref",ref:e.rawRef,timeoutMs:e.timeoutMs}}if(!e.text)throw new w("INVALID_ARGS","wait requires text");return{kind:"text",text:e.text,timeoutMs:e.timeoutMs}}(r,i)});return cx(a,n,t,e),{waitedMs:e.waitedMs,..."string"==typeof e.text?{text:e.text}:{},..."string"==typeof e.selector?{selector:e.selector}:{}}});return await cT(e,l,"wait")};return"sleep"===r.kind?await s():await uQ(i,o,s)}function cE(e){return aY({backend:function(e){let t,{req:n,session:a,device:r,logPath:i,sessionName:o,sessionStore:s}=e,l=0;return{platform:r.platform,captureSnapshot:async(e,d)=>{var u;let c,p={...n.flags,...(u=d,c={},u?.interactiveOnly!==void 0&&(c.snapshotInteractiveOnly=u.interactiveOnly),u?.compact!==void 0&&(c.snapshotCompact=u.compact),u?.scope!==void 0&&(c.snapshotScope=u.scope),u?.depth!==void 0&&(c.snapshotDepth=u.depth),u?.raw!==void 0&&(c.snapshotRaw=u.raw),c)},f=d?.scope??n.flags?.snapshotScope,h=Date.now();if(t&&h-l<750&&!u9(a))return t;let m=await cn({device:r,session:a,flags:p,outPath:n.flags?.out,logPath:i??"",snapshotScope:f});return a&&(a.snapshot=m.snapshot,s.set(o,a)),l=h,t={snapshot:m.snapshot}},readText:async(t,o)=>({text:await cg({device:r,node:o,flags:n.flags,appBundleId:a?.appBundleId,traceOutPath:a?.trace?.outPath,surface:a?.surface,contextFromFlags:e.contextFromFlags??((e,t,n)=>u3(i??"",e,t,n))})}),findText:async(t,n)=>({found:await cC(e,n)})}}(e),artifacts:u5("selector commands",{plural:!0}),sessions:{get:t=>t===e.sessionName?function(e){if(e)return{name:e.name,appName:e.appName,appBundleId:e.appBundleId,snapshot:e.snapshot,metadata:{surface:e.surface}}}(e.session):void 0,set:t=>{e.session&&t.snapshot&&(e.session.snapshot=t.snapshot,e.sessionStore.set(e.sessionName,e.session))}},policy:aJ()})}async function cO(e,t){let n=e.sessionStore.get(e.sessionName);if(!n&&t.requireSession)return{ok:!1,response:aZ("SESSION_NOT_FOUND","No active session. Run open first.")};let a=n?.device??await uO(e.req.flags??{});return(n||await uH(a),rt(t.capability,a))?{ok:!0,runtime:cE({...e,session:n,device:a})}:{ok:!1,response:aZ("UNSUPPORTED_OPERATION",`${t.capability} is not supported on this device`)}}async function cC(e,t){let{device:n,session:a,req:r,logPath:i}=e;if("macos"===n.platform&&a?.surface&&"app"!==a.surface)return!!E((await cR(e)).nodes,t);if(a2(n.platform)){let e=await iq(n,{command:"findText",text:t,appBundleId:a?.appBundleId},{verbose:r.flags?.verbose,logPath:i,traceLogPath:a?.trace?.outPath,requestId:r.meta?.requestId});return e?.found===!0}return!!E((await cR(e)).nodes,t)}async function cR(e){let t=await cn({device:e.device,session:e.session,flags:{...e.req.flags,snapshotInteractiveOnly:!1,snapshotCompact:!1},outPath:e.req.flags?.out,logPath:e.logPath??""});return e.session&&(e.session.snapshot=t.snapshot,e.sessionStore.set(e.sessionName,e.session)),t.snapshot}async function cP(e){try{return{ok:!0,data:await e()}}catch(t){let e=h(t);return aZ(e.code,e.message,e.details)}}async function cT(e,t,n){var a;let r;if(t.ok)return t;let i=e.sessionStore.get(e.sessionName);if(!i)return t;try{r=await cA(i)}catch{return t}return r?aZ(t.error.code,`${n} failed because ${"com.google.android.permissioncontroller"===(a=r).foregroundPackage?`Android permission dialog is blocking ${a.expectedPackage}`:`${a.foregroundPackage} is foreground instead of ${a.expectedPackage}`}.`,{...t.error.details??{},...r,blockedBy:"android_foreground_surface",originalMessage:t.error.message}):t}let cL=new Set(["snapshot","diff","wait","alert","settings"]);async function c$(e){let{req:t,sessionName:n,logPath:a,sessionStore:r}=e,i=t.command;if(!cL.has(i))return null;if("snapshot"===i)return await cp({req:t,sessionName:n,logPath:a,sessionStore:r});if("diff"===i)return t.positionals?.[0]!=="snapshot"?aZ("INVALID_ARGS","diff currently supports only: diff snapshot"):await cf({req:t,sessionName:n,logPath:a,sessionStore:r});if("wait"===i)return await cD({req:t,sessionName:n,logPath:a,sessionStore:r});if("alert"===i){let{session:e,device:i}=await uZ(r,n,t.flags);return await uQ(e,i,async()=>await u1({req:t,logPath:a,sessionStore:r,session:e,device:i}))}if("settings"===i){let e,i,o,s=(e=t.positionals?.[0]?.toLowerCase(),i=t.positionals?.[1]?.toLowerCase(),o=t.positionals?.[2]?.toLowerCase(),e&&i&&("permission"!==e||o)?{ok:!0,parsed:{setting:e,state:i,permissionTarget:o}}:aZ("INVALID_ARGS",ek));if(!s.ok)return s;let{session:l,device:d}=await uZ(r,n,t.flags);return await uQ(l,d,async()=>await u4({req:t,logPath:a,sessionStore:r,session:l,device:d,parsed:s.parsed}))}return null}export{eJ as DEFAULT_BATCH_MAX_STEPS,lp as IOS_DEVICECTL_DEFAULT_HINT,id as IOS_RUNNER_CONTAINER_BUNDLE_IDS,ln as IOS_SIMCTL_LIST_TIMEOUT_MS,eE as SESSION_SURFACES,eM as SETTINGS_USAGE_OVERRIDE,iF as abortAllIosRunnerSessions,on as adbArgs,s_ as appSwitcherAndroid,cv as assertAndroidPressStayedInApp,sx as backAndroid,eX as buildMobileSnapshotPresentation,sn as buildScrollGesturePlan,rC as buildSimctlArgs,rR as buildSimctlArgsForDevice,eC as buildSnapshotDisplayLines,cs as buildSnapshotState,un as buttonTag,cn as captureSnapshot,ca as captureSnapshotData,oD as classifyAndroidAppTarget,ry as clearRequestCanceled,oQ as closeAndroidApp,ds as closeIosApp,u3 as context_contextFromFlags,aY as createAgentDevice,rA as createRequestCanceledError,u5 as createUnsupportedArtifactAdapter,e2 as decodePng,o_ as waitForAndroidBoot,sj as dismissAndroidKeyboard,uC as dispatchCommand,c_ as dispatchFindReadOnlyViaRuntime,cM as dispatchGetViaRuntime,ck as dispatchIsViaRuntime,eU as displayNodeLabel,oa as ensureAdb,oS as ensureAndroidEmulatorBooted,uH as ensureDeviceReady,sO as fillAndroid,ux as findBootableIosSimulator,sE as focusAndroid,oE as formatAndroidInstalledPackageRequiredMessage,eR as formatSnapshotLine,u9 as getActiveAndroidSnapshotFreshness,oq as getAndroidAppState,sB as getAndroidKeyboardState,sT as getAndroidScreenSize,ut as getClickButtonValidationError,rv as getRequestSignal,iP as getRunnerSessionSnapshot,c$ as handleSnapshotCommands,sN as homeAndroid,oj as inferAndroidAppName,se as installAndroidApp,o7 as installAndroidInstallablePathAndResolvePackageName,dd as installIosApp,dc as installIosInstallablePath,cI as isAndroidEscapeError,a2 as isApplePlatform,rt as isCommandSupportedOnDevice,oi as isDeepLinkTarget,ra as isEnvTruthy,ce as isNavigationSensitiveAction,rb as isRequestCanceled,oU as listAndroidApps,ob as listAndroidDevices,uk as listAppleDevices,dw as listIosApps,lu as listIosDeviceApps,lc as listIosDeviceProcesses,aJ as localCommandPolicy,sM as longPressAndroid,u6 as markAndroidSnapshotFreshness,rg as markRequestCanceled,a3 as matchesPlatformSelector,a1 as normalizePlatformSelector,oz as openAndroidApp,oZ as openAndroidDevice,dr as openIosApp,di as openIosDevice,e0 as parseBatchStepsJson,cw as parseCoordinateTarget,ud as parseDeviceRotation,rE as parseSerialAllowlist,eO as parseSessionSurface,a0 as parseWaitArgs,r5 as parseXmlDocumentSync,oO as prepareAndroidInstallArtifact,lI as prepareIosInstallArtifact,sA as pressAndroid,s5 as pushAndroidNotification,dh as pushIosNotification,sq as readAndroidClipboardText,sG as readAndroidTextAtPoint,lA as readInfoPlistString,dp as readIosClipboardText,cg as readTextForNode,cb as refSnapshotFlagGuardResponse,rw as registerRequestAbort,st as reinstallAndroidApp,du as reinstallIosApp,oF as resolveAndroidApp,rO as resolveAndroidSerialAllowlist,a4 as resolveAppleSimulatorSetPathForSelector,ue as resolveClickButton,i4 as resolveFrontmostMacOsApp,da as resolveIosApp,oo as resolveIosDeviceDeepLinkBundleId,lf as resolveIosDevicectlHint,rD as resolveIosSimulatorDeviceSetPath,uo as resolvePayloadInput,rm as resolveRequestTrackingId,uO as resolveTargetDevice,aZ as response_errorResponse,sS as rotateAndroid,iq as runIosRunnerCommand,i6 as runMacOsAlertAction,s6 as screenshotAndroid,lZ as screenshotIos,sP as scrollAndroid,sZ as setAndroidSetting,dm as setIosSetting,lb as shutdownSimulator,ly as ensureBootedSimulator,sf as snapshotAndroid,iU as stopAllIosRunnerSessions,i$ as stopIosRunnerSession,sI as swipeAndroid,sk as typeAndroid,e1 as validateAndNormalizeBatchSteps,r1 as withKeyedLock,sX as writeAndroidClipboardText,df as writeIosClipboardText};
|
|
26
|
+
${r}`.toLowerCase();return i.includes("timeout waiting for screen surfaces")||i.includes("nsposixerrordomain")&&i.includes("code=60")&&i.includes("screenshot")||i.includes("timed out")&&i.includes("screenshot")}let dx={settings:"com.apple.Preferences"},dS=oM(),dN=null;function d_(e){return{platform:"ios",deviceId:e.id,variant:e.kind}}function dM(e,t,n){return ef("xcrun",rz(e,t),n)}function dk(e){return e.includes("not installed")||e.includes("not found")||e.includes("no such file")}async function dD(e,t){if("macos"===e.platform)return await l1(t);let n=t.trim();if(n.includes("."))return n;let a=dx[n.toLowerCase()];if(a)return a;let r=d_(e),i=dS.get(r,n);if(i)return i;let o=("simulator"===e.kind?await dB(e):await lO(e,"all")).filter(e=>e.name.toLowerCase()===n.toLowerCase());if(1===o.length)return dS.set(r,n,o[0].bundleId);if(o.length>1)throw new y("INVALID_ARGS",`Multiple apps matched "${t}"`,{matches:o});throw new y("APP_NOT_INSTALLED",`No app found matching "${t}"`)}async function dE(e,t,n){if("macos"===e.platform)return void await l2(e,t,n);let a=n?.url?.trim();if(a){if(!oN(a))throw new y("INVALID_ARGS","open <app> <url> requires a valid URL target");if("simulator"===e.kind){await lU(e),await dM(e,["openurl",e.id,a]);return}let r=o_(n?.appBundleId??await dD(e,t),a);if(!r)throw new y("INVALID_ARGS","Deep link open on iOS devices requires an active app bundle ID. Open the app first, then open the URL.");await dJ(e,r,{payloadUrl:a});return}let r=t.trim();if(oN(r)){if("simulator"===e.kind){await lU(e),await dM(e,["openurl",e.id,r]);return}let t=o_(n?.appBundleId,r);if(!t)throw new y("INVALID_ARGS","Deep link open on iOS devices requires an active app bundle ID. Open the app first, then open the URL.");await dJ(e,t,{payloadUrl:r});return}let i=n?.appBundleId??await dD(e,t);"simulator"===e.kind?await dK(e,i):await dJ(e,i)}async function dO(e){"macos"===e.platform||"simulator"!==e.kind||"Booted"!==await lV(e)&&await lU(e)}async function dC(e,t){if("macos"===e.platform)return void await l3(e,t);let n=await dD(e,t);if("simulator"===e.kind){await lU(e);let t=rz(e,["terminate",e.id,n]),a=await ef("xcrun",t,{allowFailure:!0});if(0!==a.exitCode){if(a.stderr.toLowerCase().includes("found nothing to terminate"))return;throw new y("COMMAND_FAILED",`xcrun exited with code ${a.exitCode}`,{cmd:"xcrun",args:t,stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode})}return}await lE(["device","process","terminate","--device",e.id,n],{action:"terminate iOS app",deviceId:e.id})}async function dR(e,t){return await dS.invalidateWhile(d_(e),async()=>{let n=await dD(e,t);if("simulator"!==e.kind){let t=["devicectl","device","uninstall","app","--device",e.id,n],a=await ef("xcrun",t,{allowFailure:!0,timeoutMs:lN});if(0!==a.exitCode){let r=String(a.stdout??""),i=String(a.stderr??"");if(!dk(`${r}
|
|
27
|
+
${i}`.toLowerCase()))throw new y("COMMAND_FAILED",`Failed to uninstall iOS app ${n}`,{cmd:"xcrun",args:t,exitCode:a.exitCode,stdout:r,stderr:i,deviceId:e.id,hint:lP(r,i)??lR})}return{bundleId:n}}await lU(e);let a=await dM(e,["uninstall",e.id,n],{allowFailure:!0});if(0!==a.exitCode&&!dk(`${a.stdout}
|
|
28
|
+
${a.stderr}`.toLowerCase()))throw new y("COMMAND_FAILED",`simctl uninstall failed for ${n}`,{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});return{bundleId:n}})}async function dP(e,t,n){let a=await lj({kind:"path",path:t},n);try{return await dL(e,a.installablePath),{archivePath:a.archivePath,installablePath:a.installablePath,bundleId:a.bundleId,appName:a.appName,launchTarget:a.bundleId}}finally{await a.cleanup()}}async function dT(e,t,n){return await dS.invalidateWhile(d_(e),async()=>{let{bundleId:a}=await dR(e,t);return await dP(e,n,{appIdentifierHint:t}),{bundleId:a}})}async function dL(e,t){await dS.invalidateWhile(d_(e),async()=>{"simulator"!==e.kind?await lE(["device","install","app","--device",e.id,t],{action:"install iOS app",deviceId:e.id}):(await lU(e),await dM(e,["install",e.id,t]))})}async function d$(e){if("macos"===e.platform)return await l4();l$(e,"clipboard"),await lU(e);let t=await dM(e,["pbpaste",e.id],{allowFailure:!0});if(0!==t.exitCode)throw new y("COMMAND_FAILED","Failed to read iOS simulator clipboard",{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode});return t.stdout.replace(/\r\n/g,"\n").replace(/\n$/,"")}async function dF(e,t){if("macos"===e.platform)return void await l5(t);l$(e,"clipboard"),await lU(e);let n=await dM(e,["pbcopy",e.id],{allowFailure:!0,stdin:t});if(0!==n.exitCode)throw new y("COMMAND_FAILED","Failed to write iOS simulator clipboard",{stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode})}async function dU(e,t,n){l$(e,"push"),await lU(e);let a=await r.mkdtemp(o.join(s.tmpdir(),"agent-device-ios-push-")),i=o.join(a,"payload.apns");try{await r.writeFile(i,`${JSON.stringify(n)}
|
|
29
|
+
`,"utf8"),await dM(e,["push",e.id,t,i])}finally{await r.rm(a,{recursive:!0,force:!0})}}async function dG(e,t,n,a,r){if("macos"===e.platform){let e=t.toLowerCase();if("appearance"===e)return void await l6(n);if("permission"===e){let e=li(n);if("deny"===e)throw new y("INVALID_ARGS",eW("permission"));let t=function(e){let t=e?.trim().toLowerCase();if("accessibility"===t||"screen-recording"===t||"input-monitoring"===t)return t;throw new y("INVALID_ARGS","Unsupported macOS permission target. Use accessibility|screen-recording|input-monitoring.")}(r?.permissionTarget);return await ow(e,t)}throw new y("INVALID_ARGS",eW(t))}l$(e,"settings"),await lU(e);let i=t.toLowerCase();switch(i){case"wifi":{let t=dj(n);await dM(e,["status_bar",e.id,"override","--wifiMode",t?"active":"failed"]);return}case"airplane":return void(dj(n)?await dM(e,["status_bar",e.id,"override","--dataNetwork","hide","--wifiMode","failed","--wifiBars","0","--cellularMode","failed","--cellularBars","0","--operatorName",""]):await dM(e,["status_bar",e.id,"clear"]));case"location":{let t=dj(n);if(!a)throw new y("INVALID_ARGS","location setting requires an active app in session");await dM(e,["privacy",e.id,t?"grant":"revoke","location",a]);return}case"faceid":case"touchid":{let t=dW[i],a=function(e,t){let n=e.trim().toLowerCase();if("match"===n)return"match";if("nonmatch"===n)return"nonmatch";if("enroll"===n)return"enroll";if("unenroll"===n)return"unenroll";throw new y("INVALID_ARGS",`Invalid ${t} state: ${e}. Use match|nonmatch|enroll|unenroll.`)}(n,i);await dY(e,a,{settingName:i,label:t.label,modalityAliases:t.modalityAliases});return}case"appearance":{let t=await dq(e,n);await dM(e,["ui",e.id,"appearance",t]);return}case"permission":{var o;if(!a)throw new y("INVALID_ARGS","permission setting requires an active app in session");let t="deny"===(o=li(n))?"revoke":o,i=function(e,t){let n=lo(e);if("photos"!==n&&t?.trim())throw new y("INVALID_ARGS",`Permission mode is only supported for photos. Received: ${t}.`);if("camera"===n)return"camera";if("microphone"===n)return"microphone";if("contacts"===n)return"contacts";if("contacts-limited"===n)return"contacts-limited";if("notifications"===n)return"notifications";if("calendar"===n)return"calendar";if("location"===n)return"location";if("location-always"===n)return"location-always";if("media-library"===n)return"media-library";if("motion"===n)return"motion";if("reminders"===n)return"reminders";if("siri"===n)return"siri";if("photos"===n){let e=t?.trim().toLowerCase();if(!e||"full"===e)return"photos";if("limited"===e)return"photos-add";throw new y("INVALID_ARGS",`Invalid photos mode: ${t}. Use full|limited.`)}throw new y("INVALID_ARGS",`Unsupported permission target: ${e}. Use camera|microphone|photos|contacts|contacts-limited|notifications|calendar|location|location-always|media-library|motion|reminders|siri.`)}(r?.permissionTarget,r?.permissionMode);await dX(e,t,i,a);return}default:throw new y("INVALID_ARGS",`Unsupported setting: ${t}`)}}async function dV(e,t="all"){return"macos"===e.platform?await l9(t):"simulator"===e.kind?lz(await dB(e),t):await lO(e,t)}async function dB(e){let t=(await dM(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 ef("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 dj(e){let t=e.toLowerCase();if("on"===t||"true"===t||"1"===t)return!0;if("off"===t||"false"===t||"0"===t)return!1;throw new y("INVALID_ARGS",`Invalid setting state: ${e}`)}async function dq(e,t){let n=ls(t);if("toggle"!==n)return n;let a=await dM(e,["ui",e.id,"appearance"],{allowFailure:!0});if(0!==a.exitCode)throw new y("COMMAND_FAILED","Failed to read current iOS appearance",{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});let r=function(e,t){let n=/\b(light|dark|unsupported|unknown)\b/i.exec(`${e}
|
|
30
|
+
${t}`);if(!n)return null;let a=n[1].toLowerCase();return"dark"===a?"dark":"light"===a?"light":null}(a.stdout,a.stderr);if(!r)throw new y("COMMAND_FAILED","Unable to determine current iOS appearance for toggle",{stdout:a.stdout,stderr:a.stderr});return"dark"===r?"light":"dark"}let dW={faceid:{label:"Face ID",modalityAliases:["face"]},touchid:{label:"Touch ID",modalityAliases:["finger","touch"]}};async function dX(e,t,n,a){let r=await dz(e);if(!r.has(n))throw new y("UNSUPPORTED_OPERATION",`iOS simctl privacy does not support service "${n}" on this runtime.`,{deviceId:e.id,appBundleId:a,hint:`Supported services: ${Array.from(r).sort().join(", ")}`});let i=["privacy",e.id,t,n,a],o="notifications"===n;if(!("reset"===t&&o))try{await dM(e,i);return}catch(t){if(!(o&&dH(t)))throw t;throw new y("UNSUPPORTED_OPERATION","iOS simulator does not support setting notifications permission via simctl privacy on this runtime.",{deviceId:e.id,appBundleId:a,hint:"Use reset notifications for reprompt behavior, or toggle notifications manually in Settings."})}try{await dM(e,i);return}catch(e){if(!dH(e))throw e}try{await dM(e,["privacy",e.id,"reset","all",a])}catch(t){throw new y("COMMAND_FAILED","iOS simulator blocked direct notifications reset. Fallback reset-all also failed.",{deviceId:e.id,appBundleId:a,hint:"Use reinstall to force a fresh notifications prompt, or reset simulator content and settings."},t instanceof Error?t:void 0)}}function dH(e){if(!(e instanceof y)||"COMMAND_FAILED"!==e.code)return!1;let t=String(e.details?.stderr??"").toLowerCase();return(t.includes("failed to grant access")||t.includes("failed to revoke access")||t.includes("failed to reset access"))&&t.includes("operation not permitted")}async function dz(t){let n=rq(t.simulatorSetPath),a=`${process.env.PATH??""}::${n??""}`;if(dN&&e===a)return dN;let r=await dM(t,["privacy","help"],{allowFailure:!0}),i=function(e){let t=new Set,n=!1;for(let a of e.split("\n")){let e=a.trim();if(!e)continue;if("service"===e){n=!0;continue}if(!n)continue;if(e.startsWith("bundle identifier"))break;let r=/^([a-z-]+)\s+-\s+/.exec(e);r&&t.add(r[1])}return t}(`${r.stdout}
|
|
31
|
+
${r.stderr}`);if(0===i.size)throw new y("COMMAND_FAILED","Unable to determine supported simctl privacy services",{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode,hint:"Run `xcrun simctl privacy help` manually to verify available services for this runtime."});return dN=i,e=a,i}async function dY(e,t,n){let a=function(e,t,n){let a=n.length>0?n:["face"];switch(t){case"match":return a.flatMap(t=>[["biometric",e,"match",t],["biometric","match",e,t]]);case"nonmatch":return a.flatMap(t=>[["biometric",e,"nonmatch",t],["biometric",e,"nomatch",t],["biometric","nonmatch",e,t],["biometric","nomatch",e,t]]);case"enroll":return[["biometric",e,"enroll","yes"],["biometric",e,"enroll","1"],["biometric","enroll",e,"yes"],["biometric","enroll",e,"1"]];case"unenroll":return[["biometric",e,"enroll","no"],["biometric",e,"enroll","0"],["biometric","enroll",e,"no"],["biometric","enroll",e,"0"]]}}(e.id,t,n.modalityAliases),r=[];for(let t of a){let n=rz(e,t),a=await ef("xcrun",n,{allowFailure:!0});if(0===a.exitCode)return;r.push({args:n,stderr:a.stderr,stdout:a.stdout,exitCode:a.exitCode})}let i=r.map(e=>({args:e.args.join(" "),exitCode:e.exitCode,stderr:e.stderr.slice(0,400)}));if(r.length>0&&r.every(e=>{var t,n;let a;return t=e.stdout,n=e.stderr,(a=`${t}
|
|
32
|
+
${n}`.toLowerCase()).includes("unrecognized subcommand")||a.includes("unknown subcommand")||a.includes("not supported")||a.includes("unavailable")||a.includes("biometric")&&a.includes("invalid")}))throw new y("UNSUPPORTED_OPERATION",`${n.label} simulation is not supported on this simulator runtime.`,{deviceId:e.id,action:t,setting:n.settingName,attempts:i});throw new y("COMMAND_FAILED",`Failed to simulate ${n.settingName}.`,{deviceId:e.id,action:t,setting:n.settingName,attempts:i})}async function dK(e,t){await lU(e);let n=0,a=rI.fromTimeoutMs(lS);try{await rx(async({deadline:n})=>{var a;if(n?.isExpired())throw new y("COMMAND_FAILED","App launch deadline exceeded",{timeoutMs:lS});let r=(a=["launch",e.id,t],rz(e,a)),i=await ef("xcrun",r,{allowFailure:!0});if(0!==i.exitCode)throw new y("COMMAND_FAILED",`xcrun exited with code ${i.exitCode}`,{cmd:"xcrun",args:r,stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode})},{maxAttempts:10,baseDelayMs:1e3,maxDelayMs:5e3,jitter:.2,shouldRetry:e=>!!lT(e)&&(n+=1)<3},{deadline:a})}catch(n){if(lT(n)){var r;let a=(r=await lL(e,t)).installed?!1===r.simulatorCompatible?"ARCH_MISMATCH":"PERSISTENT_LAUNCH_FAIL":"APP_NOT_INSTALLED";n.details={...n.details,hint:function(e){switch(e){case"ARCH_MISMATCH":return"The app binary was not built for the simulator platform. Rebuild with a simulator destination or use a physical device.";case"APP_NOT_INSTALLED":return"The app bundle is not installed on this simulator. Run install before open.";case"PERSISTENT_LAUNCH_FAIL":return"The simulator repeatedly refused to launch the app. Inspect crash logs in Console.app or ~/Library/Logs/DiagnosticReports/ and consider reinstalling the app.";default:return"The simulator failed to launch the app. Retry with --debug and inspect diagnostics log for details."}}(a)}}throw n}}async function dJ(e,t,n){let a=["device","process","launch","--device",e.id,t];n?.payloadUrl&&a.push("--payload-url",n.payloadUrl),await lE(a,{action:"launch iOS app",deviceId:e.id})}async function dZ(e,t,n,a,r,i,o){if("tv"===t.target)return d1(await e(t,{command:"swipe",direction:function(e){switch(e){case"up":return"down";case"down":return"up";case"left":return"right";case"right":return"left";default:return e}}(r),appBundleId:n.appBundleId},a),i);let s=o??await dQ(e,t,n,a),l=sM({direction:r,amount:i?.amount,pixels:i?.pixels,referenceWidth:s.referenceWidth,referenceHeight:s.referenceHeight});return d1(await e(t,{command:"drag",x:s.originX+l.x1,y:s.originY+l.y1,x2:s.originX+l.x2,y2:s.originY+l.y2,appBundleId:n.appBundleId},a),{amount:l.amount,pixels:l.pixels,preferProvidedPixels:!0})}async function dQ(e,t,n,a){let r=await e(t,{command:"interactionFrame",appBundleId:n.appBundleId},a),i=d0(r.x),o=d0(r.y),s=d0(r.referenceWidth),l=d0(r.referenceHeight);if(void 0===i||void 0===o||void 0===s||void 0===l)throw new y("COMMAND_FAILED","interactionFrame did not return a usable frame");return{originX:i,originY:o,referenceWidth:s,referenceHeight:l}}function d0(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function d1(e,t){var n;let{x1:a,y1:r,x2:i,y2:o}={x1:d0((n=e).x),y1:d0(n.y),x2:d0(n.x2),y2:d0(n.y2)},s=d0(e.referenceWidth),l=d0(e.referenceHeight),d=void 0!==a&&void 0!==i?Math.round(Math.abs(i-a)):void 0,u=void 0!==r&&void 0!==o?Math.round(Math.abs(o-r)):void 0,c=t?.preferProvidedPixels&&void 0!==t.pixels?t.pixels:d&&d>0?d:u&&u>0?u:void 0;return{...void 0!==a?{x1:a}:{},...void 0!==r?{y1:r}:{},...void 0!==i?{x2:i}:{},...void 0!==o?{y2:o}:{},...void 0!==s?{referenceWidth:s}:{},...void 0!==l?{referenceHeight:l}:{},...t?.amount!==void 0?{amount:t.amount}:{},...void 0!==c?{pixels:c}:{}}}function d2(){return process.env.WAYLAND_DISPLAY||"wayland"===process.env.XDG_SESSION_TYPE?"wayland":"x11"}let d3=null;async function d4(){if(d3)return d3;let e=d2();if("wayland"===e){if(await em("ydotool"))return d3={tool:"ydotool",display:e};throw new y("TOOL_MISSING","ydotool is required for input synthesis on Wayland (xdotool does not work on Wayland). Install it via your package manager.")}if(await em("xdotool"))return d3={tool:"xdotool",display:e};throw new y("TOOL_MISSING","xdotool is required for input synthesis on X11. Install it via your package manager.")}async function d5(...e){await ef("xdotool",e,{allowFailure:!1,timeoutMs:1e4})}async function d8(...e){await ef("ydotool",e,{allowFailure:!1,timeoutMs:1e4})}async function d6(e,t){let{tool:n}=await d4();"xdotool"===n?await d5("mousemove","--sync",String(e),String(t)):await d8("mousemove","--absolute","-x",String(e),"-y",String(t))}async function d9(e,t){let{tool:n}=await d4();"xdotool"===n?await d5("key","--clearmodifiers",e):await d8("key",...t)}async function d7(e,t,n,a){await d6(e,t);let{tool:r}=await d4();"xdotool"===r?await d5("click",n):await d8("click",a)}async function ue(e,t){await d7(e,t,"1","0xC0")}async function ut(e,t){await d7(e,t,"3","0xC1")}async function un(e,t){await d7(e,t,"2","0xC2")}async function ua(e,t){let{tool:n}=await d4();await d6(e,t),"xdotool"===n?await d5("click","--repeat","2","1"):(await d8("click","0xC0"),await d8("click","0xC0"))}async function ur(e,t,n=800){let{tool:a}=await d4();await d6(e,t),"xdotool"===a?(await d5("mousedown","1"),await eb(n),await d5("mouseup","1")):(await d8("click","--down","0xC0"),await eb(n),await d8("click","--up","0xC0"))}async function ui(e,t){await ue(e,t)}async function uo(e,t,n,a,r=300){let{tool:i}=await d4();await d6(e,t),"xdotool"===i?(await d5("mousedown","1"),await d5("mousemove","--sync",String(n),String(a)),await eb(r),await d5("mouseup","1")):(await d8("click","--down","0xC0"),await d8("mousemove","--absolute","-x",String(n),"-y",String(a)),await eb(r),await d8("click","--up","0xC0"))}async function us(e,t){let{tool:n}=await d4(),a=5;if(t?.pixels!=null?a="xdotool"===n?Math.max(1,Math.round(t.pixels/15)):Math.max(1,Math.round(t.pixels/40)):t?.amount!=null&&(a=Math.max(1,Math.round(5*(t.amount/.6)))),"xdotool"===n)await d5("click","--repeat",String(a),"up"===e?"4":"down"===e?"5":"left"===e?"6":"7");else if("up"===e||"down"===e){let t="up"===e?String(-a):String(a);await d8("mousemove","--wheel","-y",t)}else{let t="left"===e?String(-a):String(a);await d8("mousemove","--wheel","-x",t)}}async function ul(e,t=0){let{tool:n}=await d4();if("xdotool"===n){let n=["type"];t>0&&n.push("--delay",String(t)),n.push("--clearmodifiers","--",e),await d5(...n)}else await d8("type","--",e)}async function ud(e,t,n,a=0){await ue(e,t),await eb(100),await d9("ctrl+a",["29:1","30:1","30:0","29:0"]),await eb(50),await ul(n,a)}function uu(e){let t=null;return{resolve:async function(){if(t)return t;let n="wayland"===d2()?"wayland":"x11";for(let a of"wayland"===n?e.wayland:e.x11)if(await em(a.command))return t={tool:a.tool,display:n};throw new y("TOOL_MISSING","wayland"===n?e.waylandError:e.x11Error)},resetCache:()=>{t=null}}}let uc=uu({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 up(e){let{tool:t}=await uc.resolve();switch(t){case"grim":await ef("grim",[e]);break;case"scrot":await ef("scrot",[e]);break;case"import":await ef("import",["-window","root",e]);break;case"gnome-screenshot":await ef("gnome-screenshot",["-f",e])}}async function uf(e){if(e.includes("://")||e.startsWith("/"))return void await ef("xdg-open",[e]);if(await em(e)){ef(e,[],{allowFailure:!0}).catch(t=>{el({level:"warn",phase:"linux_app_launch",data:{app:e,error:String(t)}})}),await eb(500);return}await ef("xdg-open",[e],{allowFailure:!0})}async function uh(e){await em("wmctrl")?await ef("wmctrl",["-c",e],{allowFailure:!0}):await ef("pkill",["-x",e],{allowFailure:!0})}async function um(){await d9("alt+Left",["56:1","105:1","105:0","56:0"])}async function uw(){await d9("super+d",["125:1","32:1","32:0","125:0"])}let ug=uu({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 uy(){let{tool:e}=await ug.resolve();switch(e){case"wl-clipboard":return(await ef("wl-paste",["--no-newline"],{allowFailure:!0,timeoutMs:5e3})).stdout;case"xclip":return(await ef("xclip",["-selection","clipboard","-o"],{allowFailure:!0,timeoutMs:5e3})).stdout;case"xsel":return(await ef("xsel",["--clipboard","--output"],{allowFailure:!0,timeoutMs:5e3})).stdout}}async function ub(e){let{tool:t}=await ug.resolve();switch(t){case"wl-clipboard":await ef("wl-copy",["--",e],{allowFailure:!1,timeoutMs:5e3});break;case"xclip":await ef("xclip",["-selection","clipboard"],{allowFailure:!1,timeoutMs:5e3,stdin:e});break;case"xsel":await ef("xsel",["--clipboard","--input"],{allowFailure:!1,timeoutMs:5e3,stdin:e})}}ug.resetCache;let uv={"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"},uA="atspi-dump.py",uI=null;async function ux(e,t={}){let a;if("linux"!==process.platform)throw new y("UNSUPPORTED_PLATFORM","AT-SPI2 bridge is only available on Linux");if(!await em("python3"))throw new y("TOOL_MISSING","python3 is required for AT-SPI2 accessibility snapshots on Linux.");let r=t.maxNodes??1500,i=t.maxDepth??12,s=t.maxApps??24,l=[function(){if(uI)return uI;let e=o.dirname(c(import.meta.url));for(let t=0;t<5;t++){let a=o.join(e,"src","platforms","linux",uA);if(n.existsSync(a))return uI=a,a;if(0===t){let t=o.join(e,uA);if(n.existsSync(t))return uI=t,t}e=o.dirname(e)}throw new y("TOOL_MISSING",`Cannot find ${uA}. Ensure the agent-device package is installed correctly.`)}(),"--surface",e,"--max-nodes",String(r),"--max-depth",String(i),"--max-apps",String(s)],d=await ef("python3",l,{allowFailure:!0,timeoutMs:3e4});if(0!==d.exitCode){let e=d.stderr.trim();if(e.includes("No module named")||e.includes("gi.require_version"))throw new y("TOOL_MISSING","AT-SPI2 Python bindings not found. Install python3-gi and gir1.2-atspi-2.0.",{cause:e});throw new y("COMMAND_FAILED",`AT-SPI2 snapshot failed (exit ${d.exitCode}): ${e||d.stdout}`)}try{a=JSON.parse(d.stdout)}catch{throw new y("COMMAND_FAILED",`AT-SPI2 snapshot returned invalid JSON: ${d.stdout.slice(0,200)}`)}if(a.error)throw new y("COMMAND_FAILED",`AT-SPI2: ${a.error}`);return{nodes:(a.nodes??[]).map(e=>{let t,n;return{index:e.index,type:(n=uv[t=e.role.toLowerCase().trim()])||t.split(/[\s_-]+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(""),role:e.role,label:e.label??void 0,value:e.value??void 0,rect:e.rect??void 0,enabled:e.enabled??void 0,selected:e.selected??void 0,hittable:e.hittable??void 0,depth:e.depth,parentIndex:e.parentIndex??void 0,pid:e.pid??void 0,appName:e.appName??void 0,windowTitle:e.windowTitle??void 0}}),truncated:a.truncated,surface:e}}async function uS(e){let t="desktop"===e?"desktop":"frontmost-app"===e||"app"===e?"frontmost-app":("menubar"===e&&el({level:"warn",phase:"linux_snapshot",data:{message:"menubar surface is not supported on Linux, falling back to desktop"}}),"desktop"),n=await ux(t);return{nodes:n.nodes,truncated:n.truncated}}function uN(e){return e?.clickButton??"primary"}function u_(e){return"primary"===e.button?null:"click"!==e.commandLabel?new y("INVALID_ARGS","--button is supported only for click"):"macos"!==e.platform&&"linux"!==e.platform?new y("UNSUPPORTED_OPERATION",`click --button ${e.button} is supported only on macOS and Linux`):"macos"===e.platform&&"middle"===e.button?new y("UNSUPPORTED_OPERATION","click --button middle is not supported by the macOS runner yet"):"number"==typeof e.count||"number"==typeof e.intervalMs||"number"==typeof e.holdMs||"number"==typeof e.jitterPx||!0===e.doubleTap?new y("INVALID_ARGS",`click --button ${e.button} does not support repeat or gesture modifier flags`):null}function uM(e){return"primary"===e?{}:{button:e}}let uk=/^[A-Za-z0-9_.:-]{1,64}$/,uD=[[0,0],[1,0],[0,1],[-1,0],[0,-1],[1,1],[-1,1],[1,-1],[-1,-1]];async function uE(e,t,n){for(let a=0;a<e;a+=1)await n(a),a<e-1&&t>0&&await eb(t)}function uO(e,t){let a,r=t?.subject??"Payload",i=e.trim();if(!i)throw new y("INVALID_ARGS",`${r} cannot be empty`);let o=t?.expandPath?t.expandPath(i,t.cwd):i;try{if(!n.statSync(o).isFile())throw new y("INVALID_ARGS",`${r} path is not a file: ${o}`);return{kind:"file",path:o}}catch(t){if(t instanceof y)throw t;let e=t.code;if("EACCES"===e||"EPERM"===e)throw new y("INVALID_ARGS",`${r} file is not readable: ${o}`);if(e&&"ENOENT"!==e)throw new y("COMMAND_FAILED",`Unable to read ${r} file: ${o}`,{cause:String(t)})}if((a=i.trim()).startsWith("{")&&a.endsWith("}")||a.startsWith("[")&&a.endsWith("]"))return{kind:"inline",text:i};throw new y("INVALID_ARGS",`${r} file not found: ${o}`)}async function uC(e){let t=uO(e,{subject:"Push payload"}),n="inline"===t.kind?t.text:await uR(t.path);try{let e=JSON.parse(n);if(!e||"object"!=typeof e||Array.isArray(e))throw new y("INVALID_ARGS","push payload must be a JSON object");return e}catch(t){if(t instanceof y)throw t;throw new y("INVALID_ARGS",`Invalid push payload JSON: ${e}`)}}async function uR(e){try{return await r.readFile(e,"utf8")}catch(n){let t=n.code;if("ENOENT"===t)throw new y("INVALID_ARGS",`Push payload file not found: ${e}`);if("EISDIR"===t)throw new y("INVALID_ARGS",`Push payload path is not a file: ${e}`);if("EACCES"===t||"EPERM"===t)throw new y("INVALID_ARGS",`Push payload file is not readable: ${e}`);throw new y("COMMAND_FAILED",`Unable to read push payload file: ${e}`,{cause:String(n)})}}function uP(e){if(void 0===e)throw new y("INVALID_ARGS","rotate requires an orientation argument. Use portrait|portrait-upside-down|landscape-left|landscape-right.");switch(e?.trim().toLowerCase()){case"portrait":return"portrait";case"portrait-upside-down":case"upside-down":return"portrait-upside-down";case"landscape-left":case"left":return"landscape-left";case"landscape-right":case"right":return"landscape-right";default:throw new y("INVALID_ARGS",`Invalid rotation: ${e}. Use portrait|portrait-upside-down|landscape-left|landscape-right.`)}}let uT=ev(process.env.AGENT_DEVICE_IOS_DEVICECTL_LIST_TIMEOUT_MS,8e3,500),uL=/^(iphone|ipad|ipod|appletv)/i,u$=/\b(iphone|ipad|ipod)\b/i,uF=/^appletv/i,uU=["apple tv","appletv","tvos"],uG=/^==\s*(.+?)\s*==$/,uV=/^(?<name>.+?)\s+\[(?<id>[^[\]]+)\]\s*$/;function uB(e){return(e??"").trim().toLowerCase()}function uj(e){return uB(e.hardwareProperties?.platform)}function uq(e){return e.includes("tvos")}function uW(e){let t=uB(e);return uU.some(e=>t.includes(e))}function uX(e){return[e.name??"",e.deviceProperties?.name??"",e.deviceProperties?.deviceType??""]}function uH(e){return e.hardwareProperties?.productType??e.deviceProperties?.productType??""}async function uz(e={}){let t,n,a=rq(e.simulatorSetPath),r=e.target;try{t=await ef("xcrun",rH(["list","devices","-j"],{simulatorSetPath:a}))}catch{return null}try{n=JSON.parse(t.stdout)}catch{return null}let i=uY(n,a),o=null,s=null,l=null;for(let e of i)r&&e.target!==r||(e.booted&&(o=o??e),"mobile"===e.target&&(s=s??e),l=l??e);return o??s??l}function uY(e,t){let n=[];for(let[a,r]of Object.entries(e.devices))if(function(e){let t=uB(e);return t.includes("ios")||t.includes("tvos")}(a))for(let e of r)e.isAvailable&&n.push({platform:"ios",id:e.udid,name:e.name,kind:"simulator",target:uq(uB(a))?"tv":"mobile",booted:"Booted"===e.state,...t?{simulatorSetPath:t}:{}});return n}function uK(e,t){let n=new Set(e.map(e=>e.id)),a=[...e];for(let e of t)n.has(e.id)||(n.add(e.id),a.push(e));return a}async function uJ(){let e=null;try{e=o.join(s.tmpdir(),`agent-device-devicectl-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);let t=await ef("xcrun",["devicectl","list","devices","--json-output",e],{allowFailure:!0,timeoutMs:uT});if(0!==t.exitCode)return[];let n=await r.readFile(e,"utf8");return function(e){let t=[];for(let n of e.result?.devices??[]){if(!function(e){var t;let n=uj(e);return!!(n.includes("ios")||n.includes("tvos"))||(t=uH(e),!!uL.test(t.trim())||uX(e).some(uW))}(n))continue;let e=n.hardwareProperties?.udid??n.identifier??"",a=n.name??n.deviceProperties?.name??e;e&&t.push({platform:"ios",id:e,name:a,kind:"device",target:function(e){var t;return uq(uj(e))?"tv":(t=uH(e),uF.test(t.trim())||uX(e).some(uW))?"tv":"mobile"}(n),booted:!0})}return t}(JSON.parse(n))}catch{return[]}finally{e&&await r.rm(e,{force:!0}).catch(()=>{})}}async function uZ(){try{let e=await ef("xcrun",["xctrace","list","devices"],{allowFailure:!0});if(0!==e.exitCode)return[];return function(e){let t=[],n=null;for(let a of e.split(/\r?\n/)){let e=a.trim();if(!e)continue;let r=uG.exec(e);if(r){n=r[1]?.trim()??null;continue}if("Devices"!==n)continue;let i=uV.exec(e),o=i?.groups?.id?.trim()??"",s=i?.groups?.name?.trim()??"";if(!o||!s)continue;let l=function(e){return uW(e)?"tv":u$.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 uQ(e={}){if("darwin"!==process.platform)throw new y("UNSUPPORTED_PLATFORM","Apple tools are only available on macOS");if(!await em("xcrun"))throw new y("TOOL_MISSING","xcrun not found in PATH");let t=rq(e.simulatorSetPath),n=await ef("xcrun",rH(["list","devices","-j"],{simulatorSetPath:t})),a=[];try{let e=JSON.parse(n.stdout);a=uY(e,t)}catch(e){throw new y("COMMAND_FAILED","Failed to parse simctl devices JSON",void 0,e)}if(a.push({platform:"macos",id:"host-macos-local",name:s.hostname(),kind:"device",target:"desktop",booted:!0}),t)return a;let[r,i]=await Promise.all([uJ(),uZ()]);return a=uK(a,r),uK(a,i)}async function u0(){return"linux"!==process.platform?[]:[{platform:"linux",id:"local",name:l(),kind:"device",target:"desktop",booted:!0}]}let u1=new u;async function u2(e,t,n){let a,r=!!(t.udid||t.serial||t.deviceName);try{a=await ru(e,t,n)}catch(e){if(r||!(e instanceof y)||"DEVICE_NOT_FOUND"!==e.code)throw e}if(!r&&(!t.platform||"apple"===t.platform||"ios"===t.platform)&&"desktop"!==t.target&&(!a||"device"===a.kind)){let e=await uz({simulatorSetPath:n.simulatorSetPath,target:t.target});if(e)return e}if(a)return a;throw new y("DEVICE_NOT_FOUND","No devices found",{selector:t})}async function u3(e){let t=ro(e.platform),n=rd({simulatorSetPath:rq(e.iosSimulatorDeviceSet),platform:t,target:e.target}),a=rX(e.androidDeviceAllowlist),r=function(e){let{flags:t,normalizedPlatform:n,iosSimulatorSetPath:a,androidSerialAllowlist:r}=e;return JSON.stringify({platform:n,target:t.target,device:t.device,udid:t.udid,serial:t.serial,iosSimulatorSetPath:a,androidSerialAllowlist:r?Array.from(r).sort():void 0})}({flags:e,normalizedPlatform:t,iosSimulatorSetPath:n,androidSerialAllowlist:a}),i={platform:t,target:e.target,cacheHit:!1};return await eo("resolve_target_device",async()=>{let o=function(e){let t=u1.getStore(),n=t?.get(e);if(n)return{...n}}(r);if(o)return i.cacheHit=!0,o;let s={platform:t,target:e.target,deviceName:e.device,udid:e.udid,serial:e.serial};if(s.target&&!s.platform)throw new y("INVALID_ARGS","Device target selector requires --platform. Use --platform ios|macos|android|linux|apple with --target mobile|tv|desktop.");if("linux"===s.platform){let e=await u0();return u5(r,await ru(e,s))}if("android"===s.platform){await ox();let e=await oB({serialAllowlist:a});return u5(r,await ru(e,s))}if(s.platform){let e=await uQ({simulatorSetPath:n});return u5(r,await u2(e,s,{simulatorSetPath:n}))}let l=[];try{l.push(...await oB({serialAllowlist:a}))}catch{}try{l.push(...await uQ({simulatorSetPath:n}))}catch{}try{l.push(...await u0())}catch{}return u5(r,await ru(l,s,{simulatorSetPath:n}))},i)}async function u4(e){return u1.getStore()?await e():await u1.run(new Map,e)}function u5(e,t){return u1.getStore()?.set(e,{...t}),t}async function u8(e,t,n,a,i){let s={requestId:i?.requestId,appBundleId:i?.appBundleId,verbose:i?.verbose,logPath:i?.logPath,traceLogPath:i?.traceLogPath},l=function(e,t){switch(e.platform){case"android":return{open:(t,n)=>ss(e,t,n?.activity),openDevice:()=>sf(e),close:t=>sh(e,t),tap:(t,n)=>sB(e,t,n),doubleTap:async(t,n)=>{await sB(e,t,n),await sB(e,t,n)},swipe:(t,n,a,r,i)=>sj(e,t,n,a,r,i),longPress:(t,n,a)=>sz(e,t,n,a),focus:(t,n)=>sJ(e,t,n),type:(t,n)=>sY(e,t,n),fill:(t,n,a,r)=>sZ(e,t,n,a,r),scroll:(t,n)=>s1(e,t,n),screenshot:t=>ly(e,t),back:t=>sq(e),home:()=>sW(e),rotate:t=>sX(e,t),appSwitcher:()=>sH(e),readClipboard:()=>lt(e),writeClipboard:t=>ln(e,t),setSetting:(t,n,a,r)=>ld(e,t,n,a,r)};case"linux":return{open:e=>uf(e),openDevice:()=>Promise.resolve(),close:e=>uh(e),tap:(e,t)=>ue(e,t),doubleTap:(e,t)=>ua(e,t),swipe:(e,t,n,a,r)=>uo(e,t,n,a,r),longPress:(e,t,n)=>ur(e,t,n),focus:(e,t)=>ui(e,t),type:(e,t)=>ul(e,t),fill:(e,t,n,a)=>ud(e,t,n,a),scroll:(e,t)=>us(e,t),screenshot:e=>up(e),back:()=>um(),home:()=>uw(),rotate:()=>{throw new y("UNSUPPORTED_OPERATION","rotate not supported on Linux")},appSwitcher:()=>{throw new y("UNSUPPORTED_OPERATION","appSwitcher not yet supported on Linux")},readClipboard:()=>uy(),writeClipboard:e=>ub(e),setSetting:()=>{throw new y("UNSUPPORTED_OPERATION","setSetting not supported on Linux")}};case"ios":case"macos":{let n,{overrides:a,runnerOpts:r}={runnerOpts:n={verbose:t.verbose,logPath:t.logPath,traceLogPath:t.traceLogPath,requestId:t.requestId},overrides:{tap:async(a,r)=>await oe(e,{command:"tap",x:a,y:r,appBundleId:t.appBundleId},n),doubleTap:async(a,r)=>await oe(e,{command:"tapSeries",x:a,y:r,count:1,intervalMs:0,doubleTap:!0,appBundleId:t.appBundleId},n),swipe:async(a,r,i,o,s)=>await oe(e,{command:"drag",x:a,y:r,x2:i,y2:o,durationMs:s,appBundleId:t.appBundleId},n),longPress:async(a,r,i)=>await oe(e,{command:"longPress",x:a,y:r,durationMs:i,appBundleId:t.appBundleId},n),focus:async(a,r)=>await oe(e,{command:"tap",x:a,y:r,appBundleId:t.appBundleId},n),type:async(a,r)=>{await oe(e,{command:"type",text:a,delayMs:r,appBundleId:t.appBundleId},n)},fill:async(a,r,i,o)=>{let s=await oe(e,{command:"tap",x:a,y:r,appBundleId:t.appBundleId},n);return await oe(e,{command:"type",text:i,clearFirst:!0,delayMs:o,appBundleId:t.appBundleId},n),s},scroll:async(a,r)=>await dZ(oe,e,t,n,a,r)}};return{open:(t,n)=>dE(e,t,{appBundleId:n?.appBundleId,url:n?.url}),openDevice:()=>dO(e),close:t=>dC(e,t),screenshot:async(t,n)=>{"macos"===e.platform&&n?.surface&&"app"!==n.surface?await oA(t,{surface:n.surface,fullscreen:n.fullscreen}):await dp(e,t,n?.appBundleId,n?.fullscreen)},back:async n=>{await oe(e,{command:"system"===n?"backSystem":"backInApp",appBundleId:t.appBundleId},r)},home:async()=>{await oe(e,{command:"home",appBundleId:t.appBundleId},r)},rotate:async n=>{await oe(e,{command:"rotate",orientation:n,appBundleId:t.appBundleId},r)},appSwitcher:async()=>{await oe(e,{command:"appSwitcher",appBundleId:t.appBundleId},r)},readClipboard:()=>d$(e),writeClipboard:t=>dF(e,t),setSetting:(t,n,a,r)=>dG(e,t,n,a,r),...a}}default:throw new y("UNSUPPORTED_PLATFORM",`Unsupported platform: ${e.platform}`)}}(e,s);return el({level:"debug",phase:"platform_command_prepare",data:{command:t,platform:e.platform,kind:e.kind}}),await eo("platform_command",async()=>{switch(t){case"open":return u6(e,l,n,i);case"close":{let e=n[0];if(!e)return{closed:"session",...ei("Closed session")};return await l.close(e),{app:e,...ei(`Closed: ${e}`)}}case"press":return u9(e,l,n,i,s);case"swipe":return u7(e,l,n,i,s);case"longpress":{let e=Number(n[0]),t=Number(n[1]),a=n[2]?Number(n[2]):void 0;if(Number.isNaN(e)||Number.isNaN(t))throw new y("INVALID_ARGS","longpress requires x y [durationMs]");return await l.longPress(e,t,a),{x:e,y:t,durationMs:a,...ei(`Long pressed (${e}, ${t})`)}}case"focus":{let[e,t]=n.map(Number);if(Number.isNaN(e)||Number.isNaN(t))throw new y("INVALID_ARGS","focus requires x y");return await l.focus(e,t),{x:e,y:t,...ei(`Focused (${e}, ${t})`)}}case"type":{let e=function(e){let t=e[0]?.trim();if(!t||!t.startsWith("@")||t.length<3)return null;let n=t.slice(1);return/^[A-Za-z_-]*\d[\w-]*$/i.test(n)||/^(?:ref|node|element|el)[\w-]*$/i.test(n)?t:null}(n);if(e)throw new y("INVALID_ARGS",`type does not accept a target ref like "${e}"`,{hint:`Use fill ${e} "text" to target that field, or press ${e} then type "text" to append.`});let t=n.join(" ");if(!t)throw new y("INVALID_ARGS","type requires text");let a=nS(i?.delayMs??0,"delay-ms",0,1e4);return await l.type(t,a),{text:t,delayMs:a,...ei(cu("Typed",t))}}case"fill":{let e=Number(n[0]),t=Number(n[1]),a=n.slice(2).join(" ");if(Number.isNaN(e)||Number.isNaN(t)||!a)throw new y("INVALID_ARGS","fill requires x y text");let r=nS(i?.delayMs??0,"delay-ms",0,1e4);return await l.fill(e,t,a,r),{x:e,y:t,text:a,delayMs:r,...ei(cu("Filled",a))}}case"scroll":return ce(l,n,i);case"pinch":return ct(e,n,i,s);case"trigger-app-event":{let{eventName:t,payload:a}=function(e){let t=e[0]?.trim(),n=e[1]?.trim();if(!t)throw new y("INVALID_ARGS","trigger-app-event requires <event> [payloadJson]");if(!uk.test(t))throw new y("INVALID_ARGS",`Invalid trigger-app-event event name: ${t}`,{hint:"Use 1-64 chars: letters, numbers, underscore, dot, colon, or dash."});if(e.length>2)throw new y("INVALID_ARGS","trigger-app-event accepts at most two arguments: <event> [payloadJson]");let a=function(e,t){if(e)try{let n=JSON.parse(e);if(!n||"object"!=typeof n||Array.isArray(n))throw new y("INVALID_ARGS",`trigger-app-event payload for "${t}" must be a JSON object`);let a=JSON.stringify(n);if(Buffer.byteLength(a,"utf8")>8192)throw new y("INVALID_ARGS",`trigger-app-event payload for "${t}" exceeds 8192 bytes`);return n}catch(t){if(t instanceof y)throw t;throw new y("INVALID_ARGS",`Invalid trigger-app-event payload JSON: ${e}`)}}(n,t);return{eventName:t,payload:a}}(n),r=function(e,t,n){var a;let r,i=(r=("ios"===(a=e)?process.env.AGENT_DEVICE_IOS_APP_EVENT_URL_TEMPLATE:"macos"===a?process.env.AGENT_DEVICE_MACOS_APP_EVENT_URL_TEMPLATE:process.env.AGENT_DEVICE_ANDROID_APP_EVENT_URL_TEMPLATE)??process.env.AGENT_DEVICE_APP_EVENT_URL_TEMPLATE,r?.trim()||void 0);if(!i)throw new y("UNSUPPORTED_OPERATION",`No app event URL template configured for ${e}.`,{hint:`Set AGENT_DEVICE_${e.toUpperCase()}_APP_EVENT_URL_TEMPLATE or AGENT_DEVICE_APP_EVENT_URL_TEMPLATE, for example "myapp://agent-device/event?name={event}&payload={payload}".`});let o=n?JSON.stringify(n):"",s=i.replaceAll("{event}",encodeURIComponent(t)).replaceAll("{payload}",encodeURIComponent(o)).replaceAll("{platform}",encodeURIComponent(e));if(s.length>4096)throw new y("INVALID_ARGS","trigger-app-event URL exceeds maximum supported length",{hint:"Reduce payload size or shorten AGENT_DEVICE_*_APP_EVENT_URL_TEMPLATE.",length:s.length,maxLength:4096});return s}(e.platform,t,a);return await l.open(r,{appBundleId:i?.appBundleId}),{event:t,eventUrl:r,transport:"deep-link",...ei(`Triggered app event: ${t}`)}}case"screenshot":{let e=n[0]??a??`./screenshot-${Date.now()}.png`;return await r.mkdir(o.dirname(e),{recursive:!0}),await l.screenshot(e,{appBundleId:i?.appBundleId,fullscreen:i?.screenshotFullscreen,surface:i?.surface}),{path:e,...ei(`Saved screenshot: ${e}`)}}case"back":return await l.back(i?.backMode),{action:"back",mode:i?.backMode??"in-app",...ei("Back")};case"home":return await l.home(),{action:"home",...ei("Home")};case"rotate":{let e=uP(n[0]);return await l.rotate(e),{action:"rotate",orientation:e,...ei(`Rotated to ${e}`)}}case"app-switcher":return await l.appSwitcher(),{action:"app-switcher",...ei("Opened app switcher")};case"clipboard":return cn(l,n);case"keyboard":return ca(e,l,n,i,s);case"settings":return cr(e,l,n,i);case"push":return ci(e,n,i);case"snapshot":return co(e,n,i,s);case"read":return cs(e,n,i,s);default:throw new y("INVALID_ARGS",`Unknown command: ${t}`)}},{command:t,platform:e.platform})}async function u6(e,t,n,a){let r=n[0],i=n[1];if(n.length>2)throw new y("INVALID_ARGS","open accepts at most two arguments: <app|url> [url]");if(!r)return await t.openDevice(),{app:null,...ei("Opened device")};if(void 0!==i){if("android"===e.platform)throw new y("INVALID_ARGS","open <app> <url> is supported only on Apple platforms");if(oN(r))throw new y("INVALID_ARGS","open <app> <url> requires an app target as the first argument");if(!oN(i))throw new y("INVALID_ARGS","open <app> <url> requires a valid URL target");return await t.open(r,{activity:a?.activity,appBundleId:a?.appBundleId,url:i}),{app:r,url:i,...ei(`Opened: ${r}`)}}return await t.open(r,{activity:a?.activity,appBundleId:a?.appBundleId}),{app:r,...ei(`Opened: ${r}`)}}async function u9(e,t,n,a,r){let i,[o,s]=n.map(Number);if(Number.isNaN(o)||Number.isNaN(s))throw new y("INVALID_ARGS","press requires x y");if("macos"===e.platform&&a?.surface&&"app"!==a.surface){let e=uN(a);if("primary"!==e)throw new y("UNSUPPORTED_OPERATION",`${e} click is not supported on macOS ${a.surface} sessions.`);return await ov(o,s,{bundleId:a.appBundleId,surface:a.surface}),{x:o,y:s,...ei(cl({x:o,y:s}))}}let l=uN(a);if("primary"!==l){let t=u_({commandLabel:"click",platform:e.platform,button:l,count:a?.count,intervalMs:a?.intervalMs,holdMs:a?.holdMs,jitterPx:a?.jitterPx,doubleTap:a?.doubleTap});if(t)throw t;return"linux"===e.platform?"secondary"===l?await ut(o,s):await un(o,s):await oe(e,{command:"mouseClick",x:o,y:s,button:l,appBundleId:a?.appBundleId},{verbose:a?.verbose,logPath:a?.logPath,traceLogPath:a?.traceLogPath,requestId:a?.requestId}),{x:o,y:s,button:l,...ei(cl({x:o,y:s,button:l}))}}let d=nS(a?.count??1,"count",1,200),u=nS(a?.intervalMs??0,"interval-ms",0,1e4),c=nS(a?.holdMs??0,"hold-ms",0,1e4),p=nS(a?.jitterPx??0,"jitter-px",0,100),f=a?.doubleTap===!0;if(f&&c>0)throw new y("INVALID_ARGS","double-tap cannot be combined with hold-ms");if(f&&p>0)throw new y("INVALID_ARGS","double-tap cannot be combined with jitter-px");if(rs(e.platform)&&d>1&&0===c&&0===p){let t=await oe(e,{command:"tapSeries",x:o,y:s,count:d,intervalMs:u,doubleTap:f,appBundleId:a?.appBundleId},{verbose:a?.verbose,logPath:a?.logPath,traceLogPath:a?.traceLogPath,requestId:a?.requestId});return{x:o,y:s,count:d,intervalMs:u,holdMs:c,jitterPx:p,doubleTap:f,timingMode:"runner-series",...t,...ei(cl({x:o,y:s}))}}return await uE(d,u,async e=>{let[n,a]=function(e,t){if(t<=0)return[0,0];let[n,a]=uD[e%uD.length];return[n*t,a*t]}(e,p),r=o+n,l=s+a;if(f){i??=await t.doubleTap(r,l)??void 0;return}c>0?i??=await t.longPress(r,l,c)??void 0:i??=await t.tap(r,l)??void 0}),es({x:o,y:s,count:d,intervalMs:u,holdMs:c,jitterPx:p,doubleTap:f,...i},cl({x:o,y:s}))}async function u7(e,t,n,a,r){let i=Number(n[0]),o=Number(n[1]),s=Number(n[2]),l=Number(n[3]);if([i,o,s,l].some(Number.isNaN))throw new y("INVALID_ARGS","swipe requires x1 y1 x2 y2 [durationMs]");let d=nS(n[4]?Number(n[4]):250,"durationMs",16,1e4),u="ios"===e.platform?Math.min(60,Math.max(16,Math.round(d))):d,c=nS(a?.count??1,"count",1,200),p=nS(a?.pauseMs??0,"pause-ms",0,1e4),f=a?.pattern??"one-way";if("one-way"!==f&&"ping-pong"!==f)throw new y("INVALID_ARGS",`Invalid pattern: ${f}`);if(rs(e.platform)&&c>1){let t=await oe(e,{command:"dragSeries",x:i,y:o,x2:s,y2:l,durationMs:u,count:c,pauseMs:p,pattern:f,appBundleId:a?.appBundleId},{verbose:a?.verbose,logPath:a?.logPath,traceLogPath:a?.traceLogPath,requestId:a?.requestId});return{x1:i,y1:o,x2:s,y2:l,durationMs:d,effectiveDurationMs:u,timingMode:"runner-series",count:c,pauseMs:p,pattern:f,...t,...ei(cd(c,f))}}return await uE(c,p,async e=>{"ping-pong"===f&&e%2==1?await t.swipe(s,l,i,o,u):await t.swipe(i,o,s,l,u)}),es({x1:i,y1:o,x2:s,y2:l,durationMs:d,effectiveDurationMs:u,timingMode:"ios"===e.platform?"safe-normalized":"direct",count:c,pauseMs:p,pattern:f},cd(c,f))}async function ce(e,t,n){let a=t[0],r=t[1]?Number(t[1]):void 0,i=n?.pixels;if(!a)throw new y("INVALID_ARGS","scroll requires direction");if(void 0!==r&&!Number.isFinite(r))throw new y("INVALID_ARGS","scroll amount must be a number");if(void 0!==r&&void 0!==i)throw new y("INVALID_ARGS","scroll accepts either a relative amount or --pixels, not both");let o=function(e){switch(e){case"up":case"down":case"left":case"right":return e;default:throw new y("INVALID_ARGS",`Unknown direction: ${e}`)}}(a),s=await e.scroll(o,{amount:r,pixels:i});return es({direction:o,...void 0!==r?{amount:r}:{},...void 0!==i?{pixels:i}:{},...s},void 0!==i?`Scrolled ${o} by ${i}px`:void 0!==r?`Scrolled ${o} by ${r}`:`Scrolled ${o}`)}async function ct(e,t,n,a){if("android"===e.platform)throw new y("UNSUPPORTED_OPERATION","Android pinch is not supported in current adb backend; requires instrumentation-based backend.");if("macos"===e.platform&&n?.surface&&"app"!==n.surface)throw new y("UNSUPPORTED_OPERATION","pinch is only supported in macOS app sessions. Re-open the target app without --surface desktop|menubar|frontmost-app first.");let r=Number(t[0]),i=t[1]?Number(t[1]):void 0,o=t[2]?Number(t[2]):void 0;if(Number.isNaN(r)||r<=0)throw new y("INVALID_ARGS","pinch requires scale > 0");return await oe(e,{command:"pinch",scale:r,x:i,y:o,appBundleId:n?.appBundleId},{verbose:n?.verbose,logPath:n?.logPath,traceLogPath:n?.traceLogPath,requestId:n?.requestId}),{scale:r,x:i,y:o,...ei(`Pinched to scale ${r}`)}}async function cn(e,t){let n=(t[0]??"").toLowerCase();if("read"!==n&&"write"!==n)throw new y("INVALID_ARGS","clipboard requires a subcommand: read or write");if("read"===n){if(1!==t.length)throw new y("INVALID_ARGS","clipboard read does not accept additional arguments");return{action:n,text:await e.readClipboard()}}if(t.length<2)throw new y("INVALID_ARGS",'clipboard write requires text (use "" to clear clipboard)');let a=t.slice(1).join(" ");return await e.writeClipboard(a),{action:n,textLength:Array.from(a).length,...ei("Clipboard updated")}}async function ca(e,t,n,a,r){let i=(n[0]??"status").toLowerCase();if("status"!==i&&"get"!==i&&"dismiss"!==i)throw new y("INVALID_ARGS","keyboard requires a subcommand: status, get, or dismiss");if(n.length>1)throw new y("INVALID_ARGS","keyboard accepts at most one subcommand argument");if("android"===e.platform){if("dismiss"===i){let t=await le(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 s7(e);return{platform:"android",action:"status",visible:t.visible,inputType:t.inputType,type:t.type}}if("ios"===e.platform){if("dismiss"!==i)throw new y("UNSUPPORTED_OPERATION","keyboard status/get is currently supported only on Android; use keyboard dismiss on iOS");let t=await oe(e,{command:"keyboardDismiss",appBundleId:a?.appBundleId},r);return{platform:"ios",action:"dismiss",wasVisible:t.wasVisible,dismissed:t.dismissed,visible:t.visible,...ei(t.dismissed?"Keyboard dismissed":"Keyboard already hidden")}}throw new y("UNSUPPORTED_OPERATION","keyboard is supported only on Android and iOS")}async function cr(e,t,n,a){var r;let[i,o,s,l,d]=n,u="permission"===i?{permissionTarget:s,permissionMode:l}:void 0;el({level:"debug",phase:"settings_apply",data:{setting:i,state:o,target:s,mode:l,platform:e.platform}});let c=await t.setSetting(i,o,d??a?.appBundleId,u);return c&&"object"==typeof c?es({setting:i,state:o,...c},("string"==typeof(r=c).message&&r.message.length>0?r.message:void 0)??`Updated setting: ${i}`):{setting:i,state:o,...ei(`Updated setting: ${i}`)}}async function ci(e,t,n){let a=t[0]?.trim(),r=t[1]?.trim();if(!a||!r)throw new y("INVALID_ARGS","push requires <bundle|package> <payload.json|inline-json>");let i=await uC(r);if("ios"===e.platform)return await dU(e,a,i),{platform:"ios",bundleId:a,...ei(`Pushed notification to ${a}`)};let o=await lw(e,a,i);return{platform:"android",package:a,action:o.action,extrasCount:o.extrasCount,...ei(`Pushed notification to ${a}`)}}async function co(e,t,n,a){if("linux"===e.platform){let e=await eo("snapshot_capture",async()=>await uS(n?.surface),{backend:"linux-atspi"});return{nodes:e.nodes??[],truncated:e.truncated??!1,backend:"linux-atspi"}}if("android"!==e.platform){let t=await eo("snapshot_capture",async()=>await oe(e,{command:"snapshot",appBundleId:n?.appBundleId,interactiveOnly:n?.snapshotInteractiveOnly,compact:n?.snapshotCompact,depth:n?.snapshotDepth,scope:n?.snapshotScope,raw:n?.snapshotRaw},{verbose:n?.verbose,logPath:n?.logPath,traceLogPath:n?.traceLogPath,requestId:n?.requestId}),{backend:"xctest"}),a=t.nodes??[];if(0===a.length&&"simulator"===e.kind)throw new y("COMMAND_FAILED","XCTest snapshot returned 0 nodes on iOS simulator.");return{nodes:a,truncated:t.truncated??!1,backend:"xctest"}}let r=await eo("snapshot_capture",async()=>await sO(e,{interactiveOnly:n?.snapshotInteractiveOnly,compact:n?.snapshotCompact,depth:n?.snapshotDepth,scope:n?.snapshotScope,raw:n?.snapshotRaw}),{backend:"android"});return{nodes:r.nodes??[],truncated:r.truncated??!1,backend:"android",analysis:r.analysis,androidSnapshot:r.androidSnapshot}}async function cs(e,t,n,a){let[r,i]=t.map(Number);if(Number.isNaN(r)||Number.isNaN(i))throw new y("INVALID_ARGS","read requires x y");if("android"===e.platform)return{action:"read",text:await s6(e,r,i)??""};if("macos"===e.platform&&n?.surface&&"app"!==n.surface)return{action:"read",text:(await ob(r,i,{bundleId:n.appBundleId,surface:n.surface})).text};let o=await oe(e,{command:"readText",x:r,y:i,appBundleId:n?.appBundleId},{verbose:n?.verbose,logPath:n?.logPath,traceLogPath:n?.traceLogPath,requestId:n?.requestId});return{action:"read",text:"string"==typeof o.text?o.text:"string"==typeof o.message?o.message:""}}function cl(e){return e.button&&"primary"!==e.button?`Clicked ${e.button} (${e.x}, ${e.y})`:`Tapped (${e.x}, ${e.y})`}function cd(e,t){return e<=1?"Swiped":"ping-pong"===t?`Swiped ${e} times (ping-pong)`:`Swiped ${e} times`}function cu(e,t){return`${e} ${Array.from(t).length} chars`}let cc=ev(process.env.AGENT_DEVICE_IOS_DEVICE_READY_TIMEOUT_MS,15e3,1e3),cp=new Map;async function cf(e){var t;let n,a=(n="simulator"===(t=e).kind?t.simulatorSetPath??"":"",JSON.stringify([t.platform,t.kind,t.id,t.target??"",n])),r=cp.get(a);if(void 0!==r){if(r>Date.now())return;cp.delete(a)}if("ios"===e.platform){if("simulator"===e.kind){let{ensureBootedSimulator:t}=await Promise.resolve(eR);await t(e),ch(a);return}if("device"===e.kind){await cm(e.id),ch(a);return}}if("android"===e.platform){let{waitForAndroidBoot:t}=await Promise.resolve(eC);await t(e.id),ch(a)}}function ch(e){cp.set(e,Date.now()+5e3)}async function cm(e){let t=o.join(s.tmpdir(),`agent-device-ready-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),n=Math.max(1,Math.ceil(cc/1e3));try{let a=await ef("xcrun",["devicectl","device","info","details","--device",e,"--json-output",t,"--timeout",String(n)],{allowFailure:!0,timeoutMs:cc+3e3}),r=String(a.stdout??""),i=String(a.stderr??""),o=await cw(t);if(0===a.exitCode){if(!o.parsed)throw new y("COMMAND_FAILED","iOS device readiness probe failed",{kind:"probe_inconclusive",deviceId:e,stdout:r,stderr:i,hint:"CoreDevice returned success but readiness JSON output was missing or invalid. Retry; if it persists restart Xcode and the iOS device."});let t=o?.tunnelState?.toLowerCase();if("connecting"===t)throw new y("COMMAND_FAILED","iOS device is not ready for automation",{kind:"not_ready",deviceId:e,tunnelState:t,hint:"Device tunnel is still connecting. Keep the device unlocked and connected by cable until it is fully available in Xcode Devices, then retry."});return}throw new y("COMMAND_FAILED","iOS device is not ready for automation",{kind:"not_ready",deviceId:e,stdout:r,stderr:i,exitCode:a.exitCode,tunnelState:o?.tunnelState,hint:cg(r,i)})}catch(t){if(t instanceof y&&"COMMAND_FAILED"===t.code){if("not_ready"===("string"==typeof t.details?.kind?t.details.kind:""))throw t;let n=t.details??{},a=String(n.stdout??""),r=String(n.stderr??""),i=Number(n.timeoutMs??cc),o=`CoreDevice did not respond within ${i}ms. Keep the device unlocked and trusted, then retry; if it persists restart Xcode and the iOS device.`;throw new y("COMMAND_FAILED","iOS device readiness probe failed",{deviceId:e,cause:t.message,timeoutMs:i,stdout:a,stderr:r,hint:a||r?cg(a,r):o},t)}throw new y("COMMAND_FAILED","iOS device readiness probe failed",{deviceId:e,hint:"Reconnect the device, keep it unlocked, and retry."},t instanceof Error?t:void 0)}finally{await r.rm(t,{force:!0}).catch(()=>{})}}async function cw(e){try{let t=await r.readFile(e,"utf8"),n=JSON.parse(t),a=function(e){let t=e?.result;if(!t||"object"!=typeof t)return{};let n=t.connectionProperties?.tunnelState,a=t.device?.connectionProperties?.tunnelState,r="string"==typeof n?n:"string"==typeof a?a:void 0;return r?{tunnelState:r}:{}}(n);return{parsed:!0,tunnelState:a.tunnelState}}catch{return{parsed:!1}}}function cg(e,t){let n=lP(e,t);return n||(`${e}
|
|
33
|
+
${t}`.toLowerCase().includes("timed out waiting for all destinations")?"Xcode destination did not become available in time. Keep device unlocked and retry.":lR)}async function cy(e,t,n){let a=e.get(t),r=a?.device??await u3(n??{});return a||await cf(r),{session:a,device:r}}async function cb(e,t,n){let a=!e&&"ios"===t.platform;try{return await n()}finally{a&&await i2(t.id)}}function cv(e,t,n,a){t&&e.recordAction(t,{command:n.command,positionals:n.positionals??[],flags:n.flags??{},result:a})}async function cA(e){let{req:t,logPath:n,sessionStore:a,session:r,device:i}=e,o=(t.positionals?.[0]??"get").toLowerCase(),s=r?"frontmost-app"===r.surface?{surface:"frontmost-app"}:{bundleId:r.appBundleId,surface:r.surface}:{};if(!rw("alert",i))return ra("UNSUPPORTED_OPERATION","alert is not supported on this device");if("macos"===i.platform){let e=async()=>await og("wait"===o?"get":o,s);if("wait"===o){let n=rr(t.positionals?.[1])??1e4,i=Date.now();for(;Date.now()-i<n;){try{let n=await e();return cv(a,r,t,n),{ok:!0,data:n}}catch{}await eb(300)}return ra("COMMAND_FAILED","alert wait timed out")}let n="accept"===o||"dismiss"===o?o:"get";if("accept"===n||"dismiss"===n){let e,i=Date.now();for(;Date.now()-i<2e3;){try{let e=await og(n,s);return cv(a,r,t,e),{ok:!0,data:e}}catch(n){e=n;let t=String(n?.message??"").toLowerCase();if(!t.includes("alert not found")&&!t.includes("no alert"))break}await eb(300)}throw cI(e)}let i=await og("get",s);return cv(a,r,t,i),{ok:!0,data:i}}if("wait"===o){let e=rr(t.positionals?.[1])??1e4,o=Date.now();for(;Date.now()-o<e;){try{let e=await oe(i,{command:"alert",action:"get",appBundleId:r?.appBundleId},{verbose:t.flags?.verbose,logPath:n,traceLogPath:r?.trace?.outPath,requestId:t.meta?.requestId});return cv(a,r,t,e),{ok:!0,data:e}}catch{}await eb(300)}return ra("COMMAND_FAILED","alert wait timed out")}let l="accept"===o||"dismiss"===o?o:"get",d={verbose:t.flags?.verbose,logPath:n,traceLogPath:r?.trace?.outPath,requestId:t.meta?.requestId};if("accept"===l||"dismiss"===l){let e,n=Date.now();for(;Date.now()-n<2e3;){try{let e=await oe(i,{command:"alert",action:l,appBundleId:r?.appBundleId},d);return cv(a,r,t,e),{ok:!0,data:e}}catch(n){e=n;let t=String(n?.message??"").toLowerCase();if(!t.includes("alert not found")&&!t.includes("no alert"))break}await eb(300)}throw cI(e)}let u=await oe(i,{command:"alert",action:l,appBundleId:r?.appBundleId},d);return cv(a,r,t,u),{ok:!0,data:u}}function cI(e){if(!(e instanceof y))return e;let t=String(e.message??"").toLowerCase();return t.includes("alert not found")||t.includes("no alert")?new y(e.code,e.message,{...e.details??{},hint:"If the permission sheet is visible in snapshot or screenshot but alert reports no alert, take a scoped snapshot around the visible button label and use press @ref."}):e}function cx(e,t,n,a,r){return{requestId:r??er().requestId,appBundleId:n,activity:t?.activity,verbose:t?.verbose,logPath:e,traceLogPath:a,snapshotInteractiveOnly:t?.snapshotInteractiveOnly,snapshotCompact:t?.snapshotCompact,snapshotDepth:t?.snapshotDepth,snapshotScope:t?.snapshotScope,snapshotRaw:t?.snapshotRaw,screenshotFullscreen:t?.screenshotFullscreen,screenshotMaxSize:t?.screenshotMaxSize,count:t?.count,intervalMs:t?.intervalMs,delayMs:t?.delayMs,holdMs:t?.holdMs,jitterPx:t?.jitterPx,pixels:t?.pixels,doubleTap:t?.doubleTap,clickButton:uN(t),backMode:t?.backMode,pauseMs:t?.pauseMs,pattern:t?.pattern}}async function cS(e){let t,{req:n,logPath:a,sessionStore:r,session:i,device:o,parsed:s}=e,{setting:l,state:d,permissionTarget:u}=s;if(!rw("settings",o))return ra("UNSUPPORTED_OPERATION","settings is not supported on this device");if("macos"===o.platform&&"appearance"!==(t=l.trim().toLowerCase())&&"permission"!==t)return ra("INVALID_ARGS",eW(l));let c=i?.appBundleId,p="permission"===l?[l,d,u??"",n.positionals?.[3]??"",c??""]:[l,d,c??""],f=await u8(o,"settings",p,n.flags?.out,{...cx(a,n.flags,c,i?.trace?.outPath)});return cv(r,i,n,f??{setting:l,state:d}),{ok:!0,data:f??{setting:l,state:d}}}function cN(e,t={}){let n=!0===t.plural?"do":"does";return{resolveInput:async()=>{throw new y("UNSUPPORTED_OPERATION",`${e} ${n} not resolve input artifacts`)},reserveOutput:async()=>{throw new y("UNSUPPORTED_OPERATION",`${e} ${n} not reserve output artifacts`)},createTempFile:async()=>{throw new y("UNSUPPORTED_OPERATION",`${e} ${n} not create temporary files`)}}}let c_=[250,400,600];function cM(e,t,n=e.snapshot){if("android"!==e.device.platform)return;let a=n?.comparisonSafe===!0;e.androidSnapshotFreshness={action:t,markedAt:Date.now(),baselineCount:n?.nodes.length??0,baselineSignatures:a?cO(n?.nodes??[]):void 0,routeComparable:a}}function ck(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 cD(e){e&&"android"===e.device.platform&&delete e.androidSnapshotFreshness}function cE(e){return"press"===e||"click"===e||"back"===e||"open"===e}function cO(e){return e.map(e=>[e.depth??0,e.type??"",e.role??"",e.label??"",e.value??"",e.identifier??"",!1===e.enabled?"disabled":"enabled",!0===e.selected?"selected":"unselected",!0===e.hittable?"hittable":"not-hittable"].join("|"))}async function cC(e){let t=ck(e.session);if(t&&"android"===e.device.platform)return await cP(e,t);let n=await cR(e);return cD(e.session),{snapshot:cF(n,cL(e)),analysis:n.analysis,androidSnapshot:n.androidSnapshot}}async function cR(e){let{device:t,session:n,flags:a,outPath:r,logPath:i,snapshotScope:o}=e;if("linux"===t.platform){let e=await uS(n?.surface);return cU({nodes:e.nodes,truncated:e.truncated,backend:"linux-atspi"},{snapshotDepth:a?.snapshotDepth,snapshotInteractiveOnly:a?.snapshotInteractiveOnly,snapshotScope:o})}return"macos"===t.platform&&n?.surface&&"app"!==n.surface?cU(await oy(n.surface,{bundleId:"menubar"===n.surface?n.appBundleId:void 0}),{snapshotDepth:a?.snapshotDepth,snapshotInteractiveOnly:a?.snapshotInteractiveOnly,snapshotScope:o}):await u8(t,"snapshot",[],r,{...cx(i,{...a,snapshotScope:o},n?.appBundleId,n?.trace?.outPath)})}async function cP(e,t){let n=await cT(e),a=c$(n,t,e),r=0,i=t.markedAt+1500;for(let o of c_){if(!a)break;let s=i-Date.now();if(s<=0)break;await eb(Math.min(o,s)),n=await cT(e),r+=1,a=c$(n,t,e)}return a||cD(e.session),{snapshot:n.snapshot,analysis:n.data.analysis,androidSnapshot:n.data.androidSnapshot,freshness:r>0||a?{action:t.action,retryCount:r,staleAfterRetries:!!a,reason:a??void 0}:void 0}}async function cT(e){let t=await cR(e);return{data:t,snapshot:cF(t,cL(e))}}function cL(e){return void 0===e.snapshotScope?e.flags:{...e.flags,snapshotScope:e.snapshotScope}}function c$(e,t,n){var a,r;let i=n.flags?.snapshotInteractiveOnly===!0,o=e.data.analysis;if(i&&0===e.snapshot.nodes.length&&o&&o.rawNodeCount>=12)return"empty-interactive";if("ref-refresh"===n.androidFreshnessMode)return null;return(a=t.baselineCount,r=e.snapshot.nodes.length,!(a<12)&&r<=Math.floor(.2*a))?e.snapshot.nodes.some(e=>!0===e.hittable||!!e.label?.trim()||!!e.value?.trim()||!!e.identifier?.trim())?null:"sharp-drop":t.routeComparable&&cE(t.action)&&function(e,t){if(!e||0===e.length)return!1;let n=Math.max(e.length,t.length);if(n<12)return!1;let a=cO(t),r=Math.min(e.length,a.length),i=0;for(let t=0;t<r;t+=1)e[t]===a[t]&&(i+=1);let o=Math.max(0,a.length-e.length),s=Math.max(0,e.length-a.length),l=Math.max(3,Math.floor(.15*n));return i>=Math.floor(.9*n)&&o<=l&&s<=l}(t.baselineSignatures,e.snapshot.nodes)?"stuck-route":null}function cF(e,t){let n=e?.nodes??[],a=function(e){let t=new Map;for(let[n,a]of e.entries())t.set(a.index,n);let n=[],a=[];for(let[r,i]of e.entries()){let e=Math.max(0,i.depth??0);for(;a.length>0&&e<=a[a.length-1].depth;)a.pop();let o="number"==typeof i.parentIndex?t.get(i.parentIndex):void 0,s="number"==typeof o&&o<r?o:a[a.length-1]?.index;n.push({...i,index:r,depth:e,parentIndex:s}),a.push({depth:e,index:r})}return n}(t?.snapshotRaw?n:_(n));return{nodes:q(t?.snapshotScope&&e?.backend!=="macos-helper"?cG(a,t.snapshotScope):a),truncated:e?.truncated,createdAt:Date.now(),backend:e?.backend,comparisonSafe:e?.backend==="android"&&t?.snapshotInteractiveOnly!==!0&&t?.snapshotCompact!==!0&&"number"!=typeof t?.snapshotDepth&&!t?.snapshotScope}}function cU(e,t){var n,a;let r=e.nodes??[];return t.snapshotScope&&(r=cG(r,t.snapshotScope)),t.snapshotInteractiveOnly&&(r=function(e){if(0===e.length)return e;let t=new Map;for(let n of e)t.set(n.index,n);let n=new Set;for(let a of e){if(!function(e){if(e.hittable||e.rect)return!0;let t=`${e.type??""} ${e.role??""} ${e.subrole??""}`.toLowerCase();return t.includes("button")||t.includes("menu")||t.includes("textfield")||t.includes("searchfield")||t.includes("checkbox")||t.includes("radio")||t.includes("switch")}(a))continue;let e=a;for(;e&&!n.has(e.index);)n.add(e.index),e="number"==typeof e.parentIndex?t.get(e.parentIndex):void 0}return 0===n.size?e:cV(e.filter(e=>n.has(e.index)))}(r)),"number"==typeof t.snapshotDepth&&(n=r,a=t.snapshotDepth,r=cV(n.filter(e=>(e.depth??0)<=a))),{...e,nodes:r}}function cG(e,t){let n=C(q(e),t);if(!n)return[];let a=e.findIndex(e=>e.index===n.index);if(-1===a)return[];let r=e[a]?.depth??0,i=[];for(let t=a;t<e.length;t+=1){let n=e[t];if(!n)continue;let o=n.depth??0;if(t>a&&o<=r)break;i.push(n)}return cV(i,r)}function cV(e,t=0){let n=new Map;for(let[t,a]of e.entries())n.set(a.index,t);return e.map((e,a)=>({...e,index:a,depth:Math.max(0,(e.depth??0)-t),parentIndex:"number"==typeof e.parentIndex?n.get(e.parentIndex):void 0}))}function cB(e,t){let n;if(!e||!e.trim().startsWith("@"))return{ok:!0,scope:e};if(!t?.snapshot)return ra("INVALID_ARGS","Ref scope requires an existing snapshot in session.");let a=j(e.trim());if(!a)return ra("INVALID_ARGS",`Invalid ref scope: ${e}`);for(let e of[t.snapshot,...t.snapshotScopeSource?[t.snapshotScopeSource]:[]]){let t=V(e.nodes,a);if(n=t?R(t,e.nodes):void 0)break}return n?{ok:!0,scope:n}:ra("COMMAND_FAILED",`Ref ${e} not found or has no label`)}async function cj(e){let{req:t,sessionName:n,logPath:a,sessionStore:r}=e,{session:i,device:o}=await cy(r,n,t.flags);if(!rw("snapshot",o))return ra("UNSUPPORTED_OPERATION","snapshot is not supported on this device");let s=cB(t.flags?.snapshotScope,i);return s.ok?await cb(i,o,async()=>{let e=cW({req:t,sessionName:n,logPath:a,sessionStore:r,session:i,device:o,snapshotScope:s.scope}),l=await e.capture.snapshot({session:n,interactiveOnly:t.flags?.snapshotInteractiveOnly,compact:t.flags?.snapshotCompact,depth:t.flags?.snapshotDepth,scope:s.scope,raw:t.flags?.snapshotRaw});return cX({req:t,sessionName:n,sessionStore:r,result:{nodes:l.nodes.length,truncated:l.truncated}}),{ok:!0,data:l}}):s}async function cq(e){let{req:t,sessionName:n,logPath:a,sessionStore:r}=e,{session:i,device:o}=await cy(r,n,t.flags);if(!rw("diff",o))return ra("UNSUPPORTED_OPERATION","diff is not supported on this device");let s=cB(t.flags?.snapshotScope,i);return s.ok?await cb(i,o,async()=>{let e=cW({req:t,sessionName:n,logPath:a,sessionStore:r,session:i,device:o,snapshotScope:s.scope}),l=await e.capture.diffSnapshot({session:n,interactiveOnly:t.flags?.snapshotInteractiveOnly,compact:t.flags?.snapshotCompact,depth:t.flags?.snapshotDepth,scope:s.scope,raw:t.flags?.snapshotRaw});return cX({req:t,sessionName:n,sessionStore:r,result:{mode:"snapshot",baselineInitialized:l.baselineInitialized,summary:l.summary}}),{ok:!0,data:l}}):s}function cW(e){let{req:t,sessionName:n,logPath:a,sessionStore:r,session:i,device:o,snapshotScope:s}=e;return re({backend:function(e){let{req:t,logPath:n,session:a,device:r,snapshotScope:i}=e;return{platform:r.platform,captureSnapshot:async(e,o)=>{let s=await cC({device:r,session:a,flags:t.flags,outPath:o?.outPath??t.flags?.out,logPath:n,snapshotScope:i});return{snapshot:s.snapshot,analysis:s.analysis,androidSnapshot:s.androidSnapshot,freshness:s.freshness,appName:a?.appBundleId?a.appName??a.appBundleId:void 0,appBundleId:a?.appBundleId}}}}({req:t,logPath:a,session:i,device:o,snapshotScope:s}),artifacts:cN("snapshot"),sessions:{get:e=>e===n?function(e){if(e)return{name:e.name,appBundleId:e.appBundleId,appName:e.appName,snapshot:e.snapshot,metadata:{surface:e.surface}}}(r.get(n)):void 0,set:e=>{var a;if(!e.snapshot)throw new y("UNKNOWN","snapshot runtime did not produce session state");let i=r.get(n);r.set(n,function(e){var t,n;let{current:a,sessionName:r,device:i,record:o,refScopedSnapshot:s}=e;if(!o.snapshot)throw new y("UNKNOWN","snapshot runtime did not produce session state");let l=(t=a,n=o,s&&n.snapshot?.nodes.length===0&&t?.snapshot!==void 0),d=l?a.snapshot:o.snapshot,u=function(e){let{session:t,sessionName:n,device:a,snapshot:r,appBundleId:i}=e;return t?{...t,snapshot:r}:{name:n,device:a,createdAt:Date.now(),appBundleId:i,snapshot:r,actions:[]}}({session:a,sessionName:r,device:i,snapshot:d,appBundleId:o.appBundleId});return u.snapshotScopeSource=function(e){let{current:t,keepCurrentSnapshot:n,refScopedSnapshot:a}=e;if(a)return n?t?.snapshotScopeSource:t?.snapshotScopeSource??t?.snapshot}({current:a,keepCurrentSnapshot:l,refScopedSnapshot:s}),o.appName&&(u.appName=o.appName),u}({current:i,sessionName:n,device:o,record:e,refScopedSnapshot:(a=t,a.flags?.snapshotScope?.trim().startsWith("@")===!0)}))}},policy:rn()})}function cX(e){let t=e.sessionStore.get(e.sessionName);t&&e.sessionStore.recordAction(t,{command:e.req.command,positionals:e.req.positionals??[],flags:e.req.flags??{},result:e.result})}async function cH(e){let{device:t,node:n,flags:a,appBundleId:r,traceOutPath:i,surface:o,contextFromFlags:s}=e,l=E(n),d=nN(n.rect);if(!d)return l;try{let e=await u8(t,"read",[String(d.x),String(d.y)],void 0,{...s(a,r,i),surface:o}),u=e&&"object"==typeof e?e:void 0,c="string"==typeof u?.text?u.text:"";if(c.trim())return c;return el({level:"warn",phase:"interaction_read_fallback",data:{reason:"empty_backend_text",nodeRef:n.ref,surface:o,platform:t.platform}}),l}catch(e){return el({level:"warn",phase:"interaction_read_fallback",data:{reason:"backend_read_failed",nodeRef:n.ref,surface:o,platform:t.platform,error:e instanceof Error?e.message:String(e)}}),l}}let cz=[["snapshotDepth","--depth"],["snapshotScope","--scope"],["snapshotRaw","--raw"]];function cY(e,t){let n=function(e){if(!e)return[];let t=[];for(let[n,a]of cz)void 0!==e[n]&&t.push(a);return t}(t);return 0===n.length?null:ra("INVALID_ARGS",`${e} @ref does not support ${n.join(", ")}.`)}function cK(e,t){e.snapshot=t,e.snapshotScopeSource=void 0}async function cJ(e,t){let n=await cZ(e);if(n)throw new y("COMMAND_FAILED",`press ${t} left ${e.appBundleId} and foregrounded ${n.foregroundPackage}. The tap likely escaped the app.`,n)}async function cZ(e){var t;if("android"!==e.device.platform||!e.appBundleId)return null;let n=await si(e.device),a=n.package?.trim();return a&&a!==e.appBundleId&&("com.android.settings"===(t=a)||"com.android.systemui"===t||"com.google.android.permissioncontroller"===t||t.includes("launcher"))?{expectedPackage:e.appBundleId,foregroundPackage:a,activity:n.activity,hint:"com.google.android.permissioncontroller"===a?"Dismiss or allow the permission prompt, then retry the smoke assertion.":"Use screenshot as visual truth, then take a fresh snapshot -i before retrying."}:null}function cQ(e){return"COMMAND_FAILED"===e.code&&"string"==typeof e.details?.expectedPackage&&"string"==typeof e.details?.foregroundPackage}function c0(e,t,n,a){let r=e.get(t);r&&e.recordAction(r,{command:n.command,positionals:n.positionals??[],flags:n.flags??{},result:a})}function c1(e){let t=e.target;return t&&"object"==typeof t?"ref"===t.kind&&"string"==typeof t.ref?{kind:"ref",ref:t.ref}:"selector"===t.kind&&"string"==typeof t.selector?{kind:"selector",selector:t.selector}:void 0:void 0}function c2(e){return e.startsWith("@")?e.slice(1):e}async function c3(e){var t;let{req:n}=e;if("find"!==n.command)return null;let a=n.positionals??[];if(0===a.length)return ra("INVALID_ARGS","find requires a locator or text");let r=ey(a);if(!r.query)return ra("INVALID_ARGS","find requires a value");if(n.flags?.findFirst&&n.flags?.findLast)return ra("INVALID_ARGS","find accepts only one of --first or --last");let i=r.action;if("exists"!==(t=i)&&"wait"!==t&&"get_text"!==t&&"get_attrs"!==t)return null;let o=await c9(e,{requireSession:!1,capability:"find"});return o.ok?await pt(async()=>{let t=await o.runtime.selectors.find({session:e.sessionName,requestId:n.meta?.requestId,locator:r.locator,query:r.query,action:i,timeoutMs:r.timeoutMs});return c0(e.sessionStore,e.sessionName,n,function(e,t){if("exists"===t)return{found:!0};if("wait"===t)return{found:!0,waitedMs:e.waitedMs};let n="string"==typeof e.ref?e.ref:void 0;return"get_attrs"===t?{ref:n,action:"get attrs"}:{ref:n,action:"get text",text:"string"==typeof e.text?e.text:""}}(t,i)),"found"===t.kind?{found:!0,..."number"==typeof t.waitedMs?{waitedMs:t.waitedMs}:{}}:{..."string"==typeof t.ref?{ref:t.ref}:{},..."string"==typeof t.text?{text:t.text}:{},...t.node&&"object"==typeof t.node?{node:t.node}:{}}}):o.response}async function c4(e){let{req:t}=e;if("get"!==t.command)return null;let n=t.positionals?.[0];if("text"!==n&&"attrs"!==n)return ra("INVALID_ARGS","get only supports text or attrs");let a=await c9(e,{requireSession:!0,capability:"get"});if(!a.ok)return a.response;let r=function(e){let t=e.positionals?.[1]??"";if(t.startsWith("@"))return{ok:!0,target:{kind:"ref",ref:t,fallbackLabel:e.positionals.length>2?e.positionals.slice(2).join(" ").trim():""}};let n=e.positionals?.slice(1).join(" ").trim()??"";return n?{ok:!0,target:{kind:"selector",selector:n}}:{ok:!1,response:ra("INVALID_ARGS","get requires @ref or selector expression")}}(t);if(!r.ok)return r.response;if("ref"===r.target.kind){let e=cY("get",t.flags);if(e)return e}return await pt(async()=>{let i,o=await a.runtime.selectors.get({session:e.sessionName,requestId:t.meta?.requestId,property:n,target:r.target});return c0(e.sessionStore,e.sessionName,t,function(e,t){let n=Array.isArray(e.selectorChain)?e.selectorChain:void 0,a=c1(e),r=a?.kind==="ref"?c2(a.ref):void 0,i=a?.kind==="selector"?a.selector:void 0,o={...r?{ref:r}:{},...i?{selector:i}:{},...n?{selectorChain:n}:{}};if("attrs"===t)return o;let s="string"==typeof e.text?e.text:"";return{...o,text:s,refLabel:function(e){let t=e.trim();if(!(!t||t.length>80||/[\r\n]/.test(t)))return t}(s)}}(o,n)),i=c1(o),{...i?.kind==="ref"?{ref:c2(i.ref)}:{},...i?.kind==="selector"?{selector:i.selector}:{},..."string"==typeof o.text?{text:o.text}:{},...o.node&&"object"==typeof o.node?{node:o.node}:{}}})}async function c5(e){let{req:t}=e;if("is"!==t.command)return null;let n=(t.positionals?.[0]??"").toLowerCase();if(!no(n))return ra("INVALID_ARGS","is requires predicate: visible|hidden|exists|editable|selected|text");let{split:a}=O(t.positionals??[]);if(!a)return ra("INVALID_ARGS","is requires a selector expression");let r=a.rest.join(" ").trim();if("text"===n&&!r)return ra("INVALID_ARGS","is text requires expected text value");if("text"!==n&&a.rest.length>0)return ra("INVALID_ARGS",`is ${n} does not accept trailing values`);let i=await c9(e,{requireSession:!0,capability:"is"});if(!i.ok)return i.response;let o=await pt(async()=>{let o=await i.runtime.selectors.is({session:e.sessionName,requestId:t.meta?.requestId,predicate:n,selector:a.selectorExpression,expectedText:r});return c0(e.sessionStore,e.sessionName,t,o),function(e){let{selectorChain:t,...n}=e;return n}(o)});return await pn(e,o,`is ${n}`)}async function c8(e){let{req:t,sessionName:n,sessionStore:a}=e,r=ri(t.positionals??[]);if(!r)return ra("INVALID_ARGS","wait requires a duration or text");let{session:i,device:o}=await cy(a,n,t.flags);if("sleep"!==r.kind&&!rw("wait",o))return ra("UNSUPPORTED_OPERATION","wait is not supported on this device");let s=async()=>{let s=c6({...e,session:i,device:o}),l=await pt(async()=>{let e=await s.selectors.wait({session:n,requestId:t.meta?.requestId,target:function(e,t){if("sleep"===e.kind)return{kind:"sleep",durationMs:e.durationMs};if("selector"===e.kind)return{kind:"selector",selector:e.selectorExpression,timeoutMs:e.timeoutMs};if("ref"===e.kind){if(!t?.snapshot)throw new y("INVALID_ARGS","Ref wait requires an existing snapshot in session.");return{kind:"ref",ref:e.rawRef,timeoutMs:e.timeoutMs}}if(!e.text)throw new y("INVALID_ARGS","wait requires text");return{kind:"text",text:e.text,timeoutMs:e.timeoutMs}}(r,i)});return c0(a,n,t,e),{waitedMs:e.waitedMs,..."string"==typeof e.text?{text:e.text}:{},..."string"==typeof e.selector?{selector:e.selector}:{}}});return await pn(e,l,"wait")};return"sleep"===r.kind?await s():await cb(i,o,s)}function c6(e){return re({backend:function(e){let t,{req:n,session:a,device:r,logPath:i,sessionName:o,sessionStore:s}=e,l=0;return{platform:r.platform,captureSnapshot:async(e,d)=>{var u;let c,p={...n.flags,...(u=d,c={},u?.interactiveOnly!==void 0&&(c.snapshotInteractiveOnly=u.interactiveOnly),u?.compact!==void 0&&(c.snapshotCompact=u.compact),u?.scope!==void 0&&(c.snapshotScope=u.scope),u?.depth!==void 0&&(c.snapshotDepth=u.depth),u?.raw!==void 0&&(c.snapshotRaw=u.raw),c)},f=d?.scope??n.flags?.snapshotScope,h=Date.now();if(t&&h-l<750&&!ck(a))return t;let m=await cC({device:r,session:a,flags:p,outPath:n.flags?.out,logPath:i??"",snapshotScope:f});return a&&(cK(a,m.snapshot),s.set(o,a)),l=h,t={snapshot:m.snapshot}},readText:async(t,o)=>({text:await cH({device:r,node:o,flags:n.flags,appBundleId:a?.appBundleId,traceOutPath:a?.trace?.outPath,surface:a?.surface,contextFromFlags:e.contextFromFlags??((e,t,n)=>cx(i??"",e,t,n))})}),findText:async(t,n)=>({found:await c7(e,n)})}}(e),artifacts:cN("selector commands",{plural:!0}),sessions:{get:t=>t===e.sessionName?function(e){if(e)return{name:e.name,appName:e.appName,appBundleId:e.appBundleId,snapshot:e.snapshot,metadata:{surface:e.surface}}}(e.session):void 0,set:t=>{e.session&&t.snapshot&&(cK(e.session,t.snapshot),e.sessionStore.set(e.sessionName,e.session))}},policy:rn()})}async function c9(e,t){let n=e.sessionStore.get(e.sessionName);if(!n&&t.requireSession)return{ok:!1,response:ra("SESSION_NOT_FOUND","No active session. Run open first.")};let a=n?.device??await u3(e.req.flags??{});return(n||await cf(a),rw(t.capability,a))?{ok:!0,runtime:c6({...e,session:n,device:a})}:{ok:!1,response:ra("UNSUPPORTED_OPERATION",`${t.capability} is not supported on this device`)}}async function c7(e,t){let{device:n,session:a,req:r,logPath:i}=e;if("macos"===n.platform&&a?.surface&&"app"!==a.surface)return!!C((await pe(e)).nodes,t);if(rs(n.platform)){let e=await oe(n,{command:"findText",text:t,appBundleId:a?.appBundleId},{verbose:r.flags?.verbose,logPath:i,traceLogPath:a?.trace?.outPath,requestId:r.meta?.requestId});return e?.found===!0}return!!C((await pe(e)).nodes,t)}async function pe(e){let t=await cC({device:e.device,session:e.session,flags:{...e.req.flags,snapshotInteractiveOnly:!1,snapshotCompact:!1},outPath:e.req.flags?.out,logPath:e.logPath??""});return e.session&&(cK(e.session,t.snapshot),e.sessionStore.set(e.sessionName,e.session)),t.snapshot}async function pt(e){try{return{ok:!0,data:await e()}}catch(t){let e=w(t);return ra(e.code,e.message,e.details)}}async function pn(e,t,n){var a;let r;if(t.ok)return t;let i=e.sessionStore.get(e.sessionName);if(!i)return t;try{r=await cZ(i)}catch{return t}return r?ra(t.error.code,`${n} failed because ${"com.google.android.permissioncontroller"===(a=r).foregroundPackage?`Android permission dialog is blocking ${a.expectedPackage}`:`${a.foregroundPackage} is foreground instead of ${a.expectedPackage}`}.`,{...t.error.details??{},...r,blockedBy:"android_foreground_surface",originalMessage:t.error.message}):t}let pa=new Set(["snapshot","diff","wait","alert","settings"]);async function pr(e){let{req:t,sessionName:n,logPath:a,sessionStore:r}=e,i=t.command;if(!pa.has(i))return null;if("snapshot"===i)return await cj({req:t,sessionName:n,logPath:a,sessionStore:r});if("diff"===i)return t.positionals?.[0]!=="snapshot"?ra("INVALID_ARGS","diff currently supports only: diff snapshot"):await cq({req:t,sessionName:n,logPath:a,sessionStore:r});if("wait"===i)return await c8({req:t,sessionName:n,logPath:a,sessionStore:r});if("alert"===i){let{session:e,device:i}=await cy(r,n,t.flags);return await cb(e,i,async()=>await cA({req:t,logPath:a,sessionStore:r,session:e,device:i}))}if("settings"===i){let e,i,o,s=(e=t.positionals?.[0]?.toLowerCase(),i=t.positionals?.[1]?.toLowerCase(),o=t.positionals?.[2]?.toLowerCase(),e&&i&&("permission"!==e||o)?{ok:!0,parsed:{setting:e,state:i,permissionTarget:o}}:ra("INVALID_ARGS",eq));if(!s.ok)return s;let{session:l,device:d}=await cy(r,n,t.flags);return await cb(l,d,async()=>await cS({req:t,logPath:a,sessionStore:r,session:l,device:d,parsed:s.parsed}))}return null}export{tn as DEFAULT_BATCH_MAX_STEPS,lR as IOS_DEVICECTL_DEFAULT_HINT,iD as IOS_RUNNER_CONTAINER_BUNDLE_IDS,lx as IOS_SIMCTL_LIST_TIMEOUT_MS,eX as SESSION_SURFACES,ej as SETTINGS_USAGE_OVERRIDE,i3 as abortAllIosRunnerSessions,oI as adbArgs,sH as appSwitcherAndroid,cJ as assertAndroidPressStayedInApp,sq as backAndroid,e8 as buildMobileSnapshotPresentation,sM as buildScrollGesturePlan,rH as buildSimctlArgs,rz as buildSimctlArgsForDevice,eY as buildSnapshotDisplayLines,cF as buildSnapshotState,uM as buttonTag,cC as captureSnapshot,cR as captureSnapshotData,oZ as classifyAndroidAppTarget,rR as clearRequestCanceled,sh as closeAndroidApp,dC as closeIosApp,cx as context_contextFromFlags,re as createAgentDevice,rL as createRequestCanceledError,cN as createUnsupportedArtifactAdapter,ts as decodePng,oY as waitForAndroidBoot,le as dismissAndroidKeyboard,u8 as dispatchCommand,c3 as dispatchFindReadOnlyViaRuntime,c4 as dispatchGetViaRuntime,c5 as dispatchIsViaRuntime,e2 as displayNodeLabel,ox as ensureAdb,oz as ensureAndroidEmulatorBooted,cf as ensureDeviceReady,ra as errorResponse,sZ as fillAndroid,uz as findBootableIosSimulator,sJ as focusAndroid,oQ as formatAndroidInstalledPackageRequiredMessage,eK as formatSnapshotLine,ck as getActiveAndroidSnapshotFreshness,si as getAndroidAppState,s7 as getAndroidKeyboardState,s2 as getAndroidScreenSize,u_ as getClickButtonValidationError,rT as getRequestSignal,iQ as getRunnerSessionSnapshot,pr as handleSnapshotCommands,sW as homeAndroid,sr as inferAndroidAppName,sN as installAndroidApp,sS as installAndroidInstallablePathAndResolvePackageName,dP as installIosApp,dL as installIosInstallablePath,cQ as isAndroidEscapeError,rs as isApplePlatform,rw as isCommandSupportedOnDevice,oN as isDeepLinkTarget,ry as isEnvTruthy,cE as isNavigationSensitiveAction,rP as isRequestCanceled,se as listAndroidApps,oB as listAndroidDevices,uQ as listAppleDevices,dV as listIosApps,lO as listIosDeviceApps,lC as listIosDeviceProcesses,rn as localCommandPolicy,sz as longPressAndroid,cM as markAndroidSnapshotFreshness,rC as markRequestCanceled,rl as matchesPlatformSelector,ro as normalizePlatformSelector,ss as openAndroidApp,sf as openAndroidDevice,dE as openIosApp,dO as openIosDevice,ti as parseBatchStepsJson,uP as parseDeviceRotation,rW as parseSerialAllowlist,eH as parseSessionSurface,ri as parseWaitArgs,iw as parseXmlDocumentSync,o0 as prepareAndroidInstallArtifact,lj as prepareIosInstallArtifact,sB as pressAndroid,lw as pushAndroidNotification,dU as pushIosNotification,lt as readAndroidClipboardText,s6 as readAndroidTextAtPoint,lB as readInfoPlistString,d$ as readIosClipboardText,cH as readTextForNode,cY as refSnapshotFlagGuardResponse,rO as registerRequestAbort,s_ as reinstallAndroidApp,dT as reinstallIosApp,o7 as resolveAndroidApp,rX as resolveAndroidSerialAllowlist,rd as resolveAppleSimulatorSetPathForSelector,uN as resolveClickButton,oh as resolveFrontmostMacOsApp,dD as resolveIosApp,o_ as resolveIosDeviceDeepLinkBundleId,lP as resolveIosDevicectlHint,rq as resolveIosSimulatorDeviceSetPath,uO as resolvePayloadInput,rE as resolveRequestTrackingId,u3 as resolveTargetDevice,sX as rotateAndroid,oe as runIosRunnerCommand,og as runMacOsAlertAction,ly as screenshotAndroid,dp as screenshotIos,s1 as scrollAndroid,ld as setAndroidSetting,dG as setIosSetting,cK as setSessionSnapshot,lG as shutdownSimulator,lU as ensureBootedSimulator,sO as snapshotAndroid,i4 as stopAllIosRunnerSessions,i2 as stopIosRunnerSession,sj as swipeAndroid,sY as typeAndroid,to as validateAndNormalizeBatchSteps,ic as withKeyedLock,u4 as withResolveTargetDeviceCacheScope,ln as writeAndroidClipboardText,dF as writeIosClipboardText};
|