agent-device 0.20.9 → 0.20.10

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.
Files changed (140) hide show
  1. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.9.apk → agent-device-android-ime-helper-0.20.10.apk} +0 -0
  2. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.10.apk.sha256 +1 -0
  3. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.9.manifest.json → agent-device-android-ime-helper-0.20.10.manifest.json} +4 -4
  4. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.9.apk → agent-device-android-snapshot-helper-0.20.10.apk} +0 -0
  5. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.10.apk.sha256 +1 -0
  6. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.9.manifest.json → agent-device-android-snapshot-helper-0.20.10.manifest.json} +6 -6
  7. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +6 -5
  8. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +4 -4
  9. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+FlatSnapshotFiltering.swift +94 -1
  10. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +22 -23
  11. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +3 -23
  12. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Navigation.swift +10 -11
  13. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+PrivateAXPresentation.swift +30 -12
  14. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +8 -5
  15. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +133 -63
  16. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +13 -12
  17. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotPresentation.swift +183 -0
  18. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotPresentationTests.swift +0 -0
  19. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SystemModal.swift +20 -18
  20. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextInputCandidatePolicy.swift +19 -0
  21. package/dist/src/agent-device-client.js +2 -2
  22. package/dist/src/ai-sdk.d.ts +61 -0
  23. package/dist/src/ai-sdk.js +1 -0
  24. package/dist/src/android-adb.d.ts +1 -1
  25. package/dist/src/app-lifecycle.js +1 -1
  26. package/dist/src/app-log-reconnect.js +1 -1
  27. package/dist/src/app-log-runtime.js +3 -3
  28. package/dist/src/app-resolution.js +2 -2
  29. package/dist/src/apps.js +5 -5
  30. package/dist/src/audio-probe.js +1 -1
  31. package/dist/src/boot-diagnostics.js +2 -2
  32. package/dist/src/cli-config.js +1 -1
  33. package/dist/src/cli-help.js +30 -23
  34. package/dist/src/cli-runner.js +1 -1
  35. package/dist/src/cli.js +7 -7
  36. package/dist/src/client-metro.js +1 -1
  37. package/dist/src/client-types.d.ts +1582 -0
  38. package/dist/src/command-tools.js +2 -0
  39. package/dist/src/connection-runtime.js +1 -1
  40. package/dist/src/contracts.d.ts +1 -1
  41. package/dist/src/contracts.js +1 -1
  42. package/dist/src/daemon-shutdown-report.js +1 -1
  43. package/dist/src/daemon.js +1 -1
  44. package/dist/src/debug-symbols.js +1 -1
  45. package/dist/src/device-input-state.js +1 -1
  46. package/dist/src/dispatch.js +1 -1
  47. package/dist/src/find.js +1 -1
  48. package/dist/src/finders.js +1 -1
  49. package/dist/src/generic-settle.js +1 -1
  50. package/dist/src/generic.js +1 -1
  51. package/dist/src/helper-package-install.js +1 -1
  52. package/dist/src/helper.js +1 -1
  53. package/dist/src/ime-lifecycle.js +1 -1
  54. package/dist/src/ime-recovery-marker.js +1 -1
  55. package/dist/src/index.d.ts +2 -1578
  56. package/dist/src/index.js +1 -1
  57. package/dist/src/input-actions.js +1 -1
  58. package/dist/src/input-actions3.js +1 -1
  59. package/dist/src/install-source2.js +1 -1
  60. package/dist/src/interaction-common.js +1 -1
  61. package/dist/src/interaction-runtime.js +1 -1
  62. package/dist/src/interaction-snapshot.js +1 -1
  63. package/dist/src/interaction.js +1 -1
  64. package/dist/src/interaction2.js +1 -1
  65. package/dist/src/interactor.js +2 -2
  66. package/dist/src/interactor2.js +1 -1
  67. package/dist/src/interactors.js +1 -1
  68. package/dist/src/internal/bin.js +2 -2
  69. package/dist/src/internal/daemon.js +4 -4
  70. package/dist/src/internal/png-worker.js +1 -1
  71. package/dist/src/lease-context.js +1 -1
  72. package/dist/src/lease.js +1 -1
  73. package/dist/src/limrun.d.ts +10 -2
  74. package/dist/src/linux.js +1 -1
  75. package/dist/src/location-coordinates.js +1 -1
  76. package/dist/src/{screenshot-geometry.js → mobile-snapshot-semantics.js} +1 -1
  77. package/dist/src/perf.js +1 -1
  78. package/dist/src/platform-runtime-open-target.js +1 -1
  79. package/dist/src/platform-runtime-operation-host.js +4 -4
  80. package/dist/src/platform-runtime.js +1 -1
  81. package/dist/src/platform-runtime2.js +1 -1
  82. package/dist/src/png-resize.js +1 -1
  83. package/dist/src/provider.js +1 -1
  84. package/dist/src/proxy.js +1 -1
  85. package/dist/src/react-native.js +1 -1
  86. package/dist/src/record-runtime.js +1 -1
  87. package/dist/src/registry.js +27 -27
  88. package/dist/src/remote-config2.js +1 -1
  89. package/dist/src/replay.js +2 -2
  90. package/dist/src/reporting.js +5 -5
  91. package/dist/src/runner-client.js +1 -1
  92. package/dist/src/runner-disposal.js +1 -1
  93. package/dist/src/runner-sequence.js +1 -1
  94. package/dist/src/runtime.js +3 -3
  95. package/dist/src/runtime2.js +4 -4
  96. package/dist/src/runtime3.js +1 -1
  97. package/dist/src/runtime4.js +3 -3
  98. package/dist/src/runtime5.js +1 -1
  99. package/dist/src/runtime6.js +1 -1
  100. package/dist/src/runtime7.js +1 -1
  101. package/dist/src/runtime8.js +1 -1
  102. package/dist/src/runtime9.js +1 -1
  103. package/dist/src/screenshot-result.js +4 -4
  104. package/dist/src/screenshot.js +1 -1
  105. package/dist/src/script-source-bundle.js +16 -0
  106. package/dist/src/sdk-android-adb.d.ts +40 -40
  107. package/dist/src/sdk-android-adb.js +4 -4
  108. package/dist/src/sdk-batch-runner.js +3 -3
  109. package/dist/src/sdk-contracts.d.ts +122 -85
  110. package/dist/src/sdk-contracts.js +2 -2
  111. package/dist/src/sdk-finders.d.ts +1 -1
  112. package/dist/src/sdk-finders.js +1 -1
  113. package/dist/src/sdk-selectors.d.ts +89 -77
  114. package/dist/src/sdk-selectors.js +1 -1
  115. package/dist/src/selector-runtime.js +1 -1
  116. package/dist/src/selectors.js +1 -1
  117. package/dist/src/server.js +10 -3
  118. package/dist/src/session-target-evidence.js +1 -1
  119. package/dist/src/session2.js +7 -8
  120. package/dist/src/shared.js +1 -1
  121. package/dist/src/snapshot-runtime.js +1 -1
  122. package/dist/src/snapshot-scope.js +1 -0
  123. package/dist/src/snapshot.js +6 -6
  124. package/dist/src/snapshot2.js +1 -1
  125. package/dist/src/snapshot3.js +1 -1
  126. package/dist/src/src.js +1 -1
  127. package/dist/src/src2.js +1 -1
  128. package/dist/src/src3.js +1 -1
  129. package/dist/src/src4.js +1 -0
  130. package/dist/src/tool-provider2.js +1 -1
  131. package/dist/src/tool-provider3.js +1 -0
  132. package/dist/src/verified-file.js +1 -1
  133. package/dist/src/web.js +1 -1
  134. package/package.json +21 -8
  135. package/server.json +2 -2
  136. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.9.apk.sha256 +0 -1
  137. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.9.apk.sha256 +0 -1
  138. package/dist/src/cancel.js +0 -1
  139. package/dist/src/prepare-kind.js +0 -15
  140. package/dist/src/selector-vocabulary.js +0 -1
@@ -1,3 +1,3 @@
1
- import{n as e}from"./rolldown-runtime.js";import{_ as t,d as n,g as r,l as i,p as a,u as o,v as s}from"./sdk-contracts.js";import{g as c,k as l,m as u}from"./location-coordinates.js";import{Bn as d,Dn as f,Ft as p,Gn as m,Kn as ee,Tr as te,_n as ne,an as re,bn as ie,cn as ae,pn as oe,pr as se,qn as ce,qt as le,un as ue,vn as de}from"./sdk-batch-runner.js";import{B as fe,C as pe,D as me,E as he,F as ge,H as _e,I as ve,K as ye,L as be,M as h,N as g,O as xe,P as Se,R as Ce,T as we,U as Te,V as Ee,Vt as _,W as v,_ as De,b as Oe,ct as y,d as ke,et as b,f as Ae,g as je,h as Me,it as x,j as Ne,k as Pe,m as Fe,nt as Ie,p as Le,rt as S,tt as C,u as Re,v as ze,w as Be,y as Ve,z as He}from"./prepare-kind.js";import{r as Ue}from"./recording-export-quality.js";import{_ as We,i as Ge,t as w}from"./interaction.js";import{A as Ke}from"./screenshot-result.js";import{n as qe,r as Je,t as Ye}from"./screenshot-geometry.js";import{t as Xe}from"./verdict.js";import{f as Ze,p as Qe}from"./device.js";import{a as $e}from"./png-worker-contract.js";import{a as et,i as tt,n as nt,o as rt}from"./png-resize.js";import it from"node:path";import{promises as T}from"node:fs";const at=/\b(logbox|redbox|reload js|copy stack|component stack|call stack|runtime error|open debugger to view warnings)\b/,ot=[/\b[\w.$<>/-]+\.(?:tsx?|jsx?):\d+(?::\d+)?\b/,/\b[\w.$<>/-]+\.(?:tsx?|jsx?)\s+\(\d+:\d+\)/],st=[/^!,\s+/,/^(warn|warning|error):\s+/,/\b(?:possible\s+)?unhandled (?:promise )?rejection\b/],ct=[`open debugger to view warnings`,`getsnapshot should be cached to avoid an infinite loop`,`unique "key" prop`,`unique 'key' prop`,`virtualizedlists should never be nested`,`failed prop type`],lt=new Set([`x`,`×`,`✕`,`✖`,`⨯`]);function ut(e){if(dt(e).detected)return[`Hint: React Native warning/error overlay detected. It overlays part of the app and should be handled before interacting.`,`Run: agent-device react-native dismiss-overlay`,`The command verifies the overlay is gone. Run agent-device snapshot -i afterward only when you need fresh refs for the next action.`].join(`
2
- `)}function dt(e){let t=mt(e),n=t.detected?ht(t):null;return{detected:t.detected,dismissNodes:t.dismissNodes,minimizeNodes:t.minimizeNodes,collapsedNodes:t.collapsedNodes,primaryAction:n}}function ft(e){return St(e.label?.trim())&&Mt(e.rect)}function pt(e,t){let n=e.label?.trim();return!n||!ft(e)?!1:t.some(e=>e.label?.trim()===n&&Nt(e))}function mt(e){let t=e.map(gt).join(`
3
- `).toLowerCase(),n=E(e,wt),r=E(e,Ot),i=E(e,St,At),a=E(e,Ct),o=vt(t),s=yt(t);return{dismissNodes:n,minimizeNodes:r,collapsedNodes:i,detected:xt({text:t,hasReactNativeStackFrame:o,hasOverlayControl:bt(t,n,r),hasControllessRedBoxText:s,collapsedNodes:i,openDebuggerWarningNodes:a})}}function ht(e){let t=Pt(e.dismissNodes);if(t)return Lt(t,Rt(t));let n=zt(e.collapsedNodes.filter(jt));return n?.rect?{action:`close-collapsed-banner`,point:Wt(n),rect:n.rect,ref:n.ref,label:D(n)}:null}function gt(e){return[e.label,e.value,e.identifier,e.type,e.role].filter(Boolean).join(` `)}function _t(e){return at.test(e)}function vt(e){return ot.some(t=>t.test(e))}function yt(e){return/\buncaught\b/.test(e)&&/unable to download asset/.test(e)}function bt(e,t,n){return t.length>0||n.length>0||/\b(reload js|copy stack)\b/.test(e)}function xt(e){return e.collapsedNodes.length>0||e.openDebuggerWarningNodes.length>0||e.hasControllessRedBoxText||e.hasOverlayControl&&(_t(e.text)||e.hasReactNativeStackFrame)}function St(e){let t=e?.trim().toLowerCase();return t?ct.some(e=>t.includes(e))||st.some(e=>e.test(t)):!1}function Ct(e){return e.includes(`open debugger to view warnings`)||/^!,\s+open debugger\b/.test(e)}function wt(e){return Tt(e)||Et(e)||Dt(e)}function Tt(e){return/^dismiss(?:\s*\([^)]*\))?$/i.test(e)}function Et(e){return/^close(?:\s*\([^)]*\))?$/i.test(e)}function Dt(e){return lt.has(e)}function Ot(e){return/^minimi[sz]e(?:\b|\s|\()/i.test(e)}function kt(e){return/^!,\s+/.test(e)}function At(e){return!e.rect||e.rect.height<=180}function jt(e){let t=D(e)?.trim().toLowerCase()??``;return(Ct(t)||kt(t))&&Nt(e)}function Mt(e){return e?e.x<=1&&e.y<=1&&e.width>=300&&e.height>=600:!1}function Nt(e){return e.rect?e.rect.width>=120&&e.rect.height>=36&&e.rect.height<=180:!1}function E(e,t,n=()=>!0){let r=[];for(let i of e)i.ref&&n(i)&&[i.label,i.value,i.identifier].map(e=>e?.trim().toLowerCase()).filter(e=>!!e).some(e=>t(e))&&r.push(i);return r}function Pt(e){return Bt(e,It)}function Ft(e){let t=[e.type,e.role,e.subrole].join(` `).toLowerCase();return/\b(button|menuitem|link)\b/.test(t)}function It(e){return[Ht(Ft(e)),Ht(e.hittable),-(e.rect?te(e.rect):1/0)]}function Lt(e,t){if(!e.rect)throw Error(`React Native overlay target node must have rect`);return{action:t,point:o(e.rect),rect:e.rect,ref:e.ref,label:D(e)}}function Rt(e){let t=D(e)?.trim().toLowerCase();return t&&Tt(t)?`dismiss`:`close`}function zt(e){return Bt(e,Vt)}function Bt(e,t){let n=e.filter(e=>e.rect);return n.length===0?null:n.sort((e,n)=>Ut(t(n),t(e)))[0]??null}function Vt(e){return[Ht(e.hittable),e.rect?.width??0,e.rect?.y??0]}function Ht(e){return+(e===!0)}function Ut(e,t){for(let n=0;n<e.length;n+=1){let r=e[n]-t[n];if(r!==0)return r}return 0}function Wt(e){if(!e.rect)throw Error(`Collapsed React Native warning node must have rect`);let t=Math.min(e.rect.height,52),n=Math.min(36,Math.max(18,t*.45));return{x:Math.round(Gt(e.rect.x+e.rect.width-n,e.rect.x+1,e.rect.x+e.rect.width-1)),y:Math.round(e.rect.y+t/2)}}function Gt(e,t,n){return Math.min(n,Math.max(t,e))}function D(e){return e.label??e.value??e.identifier}function Kt(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}const O=[0,187,255,255];function qt(e,t){for(let n of t)n.rect.width<4||n.rect.height<4||Jt(e,n.rect)}function Jt(e,t){let n=Yt(t);if(n==null)return;let r=A(n.x,0,e.width-1),i=A(n.y,0,e.height-1),a=A(n.right,0,e.width-1),o=A(n.bottom,0,e.height-1);for(let t=0;t<2;t+=1){for(let n=r;n<=a;n+=1)k(e,n,i+t,O),k(e,n,o-t,O);for(let n=i;n<=o;n+=1)k(e,r+t,n,O),k(e,a-t,n,O)}}function Yt(e){let t=e.x+e.width-1,n=e.y+e.height-1;return[e.x,e.y,e.width,e.height,t,n].every(Number.isFinite)?{x:e.x,y:e.y,right:t,bottom:n}:null}function k(e,t,n,r){if(t<0||t>=e.width||n<0||n>=e.height)return;let i=(n*e.width+t)*4;e.data[i]=r[0],e.data[i+1]=r[1],e.data[i+2]=r[2],e.data[i+3]=r[3]}function A(e,t,n){return Number.isFinite(e)?Math.min(Math.max(e,t),n):t}const Xt=[{x:-1,y:-1},{x:0,y:-1},{x:1,y:-1},{x:-1,y:0},{x:1,y:0},{x:-1,y:1},{x:0,y:1},{x:1,y:1}];function Zt(e){let{mask:t,width:n,height:r,hooks:i}=e,a=new Uint8Array(t.length),o=new Int32Array(t.length),s=[];for(let e=0;e<t.length;e+=1){if(!en(t,a,e))continue;let c=0,l=$t(o,a,0,e),u=i.create(e);for(;c<l;){let e=o[c];c+=1,i.visit(u,e),l=Qt({mask:t,visited:a,queue:o,queueEnd:l,width:n,height:r,pixelIndex:e})}s.push(u)}return s}function Qt(e){let{mask:t,visited:n,queue:r,width:i,height:a,pixelIndex:o}=e,s=o%i,c=Math.floor(o/i),l=e.queueEnd;for(let e of Xt){let o=s+e.x,u=c+e.y;if(!tn(o,u,i,a))continue;let d=u*i+o;en(t,n,d)&&(l=$t(r,n,l,d))}return l}function $t(e,t,n,r){return t[r]=1,e[n]=r,n+1}function en(e,t,n){return e[n]===1&&t[n]!==1}function tn(e,t,n,r){return e>=0&&e<n&&t>=0&&t<r}function nn(e,t){return e.flatMap(e=>rn(e,t.baseline.width,t.baseline.height)?an(e,t,dn(t.baseline.height)):[e])}function rn(e,t,n){let r=e.maxX-e.minX+1;return e.maxY-e.minY+1>=un(n)&&r>=t*.35}function an(e,t,n){let r=ln(e,cn(sn(on(e,t.diffMask,t.baseline.width)),Math.max(1,Math.round((e.maxX-e.minX+1)*.08))),n);if(r.length<=1)return[e];let i=r.map(([n,r])=>fn(e,n,r,t)).filter(e=>e!==null);return i.length>1?i:[e]}function on(e,t,n){let r=[];for(let i=e.minY;i<=e.maxY;i+=1){let a=0;for(let r=e.minX;r<=e.maxX;r+=1)t[i*n+r]===1&&(a+=1);r.push(a)}return r}function sn(e){return e.map((t,n)=>{let r=0,i=0,a=Math.max(0,n-3),o=Math.min(e.length-1,n+3);for(let t=a;t<=o;t+=1)r+=e[t],i+=1;return Math.round(r/i)})}function cn(e,t){let n=[],r=null;for(let i=0;i<e.length;i+=1){if(e[i]<=t){r??=i;continue}r!==null&&(i-r>=6&&n.push([r,i-1]),r=null)}return r!==null&&e.length-r>=6&&n.push([r,e.length-1]),n}function ln(e,t,n){let r=[],i=e.minY;for(let[a,o]of t){let t=e.minY+Math.round((a+o)/2);t-i+1<n||e.maxY-t<n||(r.push([i,t]),i=t+1)}return r.push([i,e.maxY]),r}function un(e){return Math.max(48,Math.round(e*.07))}function dn(e){return Math.max(24,Math.round(e*.03))}function fn(e,t,n,r){let i=null;for(let a=t;a<=n;a+=1)for(let t=e.minX;t<=e.maxX;t+=1){let e=a*r.baseline.width+t;r.diffMask[e]===1&&(i??=pn(t,a),mn(i,e,t,a,r.baseline,r.current))}return i}function pn(e,t){return{minX:e,minY:t,maxX:e,maxY:t,differentPixels:0,baselineRed:0,baselineGreen:0,baselineBlue:0,currentRed:0,currentGreen:0,currentBlue:0}}function mn(e,t,n,r,i,a){let o=t*4;e.minX=Math.min(e.minX,n),e.minY=Math.min(e.minY,r),e.maxX=Math.max(e.maxX,n),e.maxY=Math.max(e.maxY,r),e.differentPixels+=1,e.baselineRed+=i.data[o],e.baselineGreen+=i.data[o+1],e.baselineBlue+=i.data[o+2],e.currentRed+=a.data[o],e.currentGreen+=a.data[o+1],e.currentBlue+=a.data[o+2]}const hn=2.5;function gn(e){let t=_n(e);return nn(t.length<=2e3?bn(t,12):t,e).sort((e,t)=>{let n=t.differentPixels-e.differentPixels;if(n!==0)return n;let r=e.minY-t.minY;return r===0?e.minX-t.minX:r}).slice(0,8).map((t,n)=>Cn(t,n+1,{width:e.baseline.width,height:e.baseline.height,totalPixels:e.totalPixels,differentPixels:e.differentPixels}))}function _n(e){let{diffMask:t,baseline:n,current:r}=e,{width:i,height:a}=n;return Zt({mask:t,width:i,height:a,hooks:{create:e=>vn(e,i),visit:(e,t)=>yn(e,t,i,n,r)}})}function vn(e,t){let n=e%t,r=Math.floor(e/t);return{minX:n,minY:r,maxX:n,maxY:r,differentPixels:0,baselineRed:0,baselineGreen:0,baselineBlue:0,currentRed:0,currentGreen:0,currentBlue:0}}function yn(e,t,n,r,i){let a=t%n,o=Math.floor(t/n),s=t*4;e.minX=Math.min(e.minX,a),e.minY=Math.min(e.minY,o),e.maxX=Math.max(e.maxX,a),e.maxY=Math.max(e.maxY,o),e.differentPixels+=1,e.baselineRed+=r.data[s],e.baselineGreen+=r.data[s+1],e.baselineBlue+=r.data[s+2],e.currentRed+=i.data[s],e.currentGreen+=i.data[s+1],e.currentBlue+=i.data[s+2]}function bn(e,t){let n=[];for(let r of e.sort((e,t)=>{let n=e.minY-t.minY;return n===0?e.minX-t.minX:n})){let e=n.find(e=>xn(e,r,t));if(!e){n.push({...r});continue}Sn(e,r)}return n}function xn(e,t,n){return e.minX-n<=t.maxX&&t.minX-n<=e.maxX&&e.minY-n<=t.maxY&&t.minY-n<=e.maxY}function Sn(e,t){e.minX=Math.min(e.minX,t.minX),e.minY=Math.min(e.minY,t.minY),e.maxX=Math.max(e.maxX,t.maxX),e.maxY=Math.max(e.maxY,t.maxY),e.differentPixels+=t.differentPixels,e.baselineRed+=t.baselineRed,e.baselineGreen+=t.baselineGreen,e.baselineBlue+=t.baselineBlue,e.currentRed+=t.currentRed,e.currentGreen+=t.currentGreen,e.currentBlue+=t.currentBlue}function Cn(e,t,n){let r={x:e.minX,y:e.minY,width:e.maxX-e.minX+1,height:e.maxY-e.minY+1},i={x:Math.round(e.minX+r.width/2),y:Math.round(e.minY+r.height/2)},a=wn(e.baselineRed,e.baselineGreen,e.baselineBlue,e.differentPixels),o=wn(e.currentRed,e.currentGreen,e.currentBlue,e.differentPixels),s=r.width*r.height;return{index:t,rect:r,normalizedRect:qe({x:N(r.x/n.width),y:N(r.y/n.height),width:N(r.width/n.width),height:N(r.height/n.height)}),differentPixels:e.differentPixels,shareOfDiffPercentage:N(e.differentPixels/n.differentPixels),densityPercentage:N(e.differentPixels/s),shape:Dn(r,n.width,n.height),size:On(s,n.totalPixels),location:Tn(i,n.width,n.height),averageBaselineColorHex:kn(a),averageCurrentColorHex:kn(o),baselineLuminance:Math.round(j(a)),currentLuminance:Math.round(j(o)),dominantChange:En(a,o)}}function wn(e,t,n,r){return{r:Math.round(e/r),g:Math.round(t/r),b:Math.round(n/r)}}function Tn(e,t,n){let r=e.x<t/3?`left`:e.x>t*2/3?`right`:`center`,i=e.y<n/3?`top`:e.y>n*2/3?`bottom`:`middle`;return r===`center`&&i===`middle`?`center`:`${i}-${r}`}function En(e,t){let n=j(t)-j(e);return Math.abs(n)>=12?n>0?`brighter`:`darker`:Math.max(Math.abs(t.r-e.r),Math.abs(t.g-e.g),Math.abs(t.b-e.b))>=12?`color-shift`:`mixed`}function Dn(e,t,n){return e.width>=t*.55&&e.height>=n*.12?`large-area`:e.width>=e.height*hn?`horizontal-band`:e.height>=e.width*hn?`vertical-band`:`compact`}function On(e,t){let n=e/t;return n>=.04?`large`:n>=.01?`medium`:`small`}function j(e){return e.r*.2126+e.g*.7152+e.b*.0722}function kn(e){return`#${M(e.r)}${M(e.g)}${M(e.b)}`}function M(e){return e.toString(16).padStart(2,`0`)}function N(e){return Math.round(e*100*100)/100}const An=255*Math.sqrt(3);async function jn(e,t,n={}){await Mn(e,`Baseline image not found`),await Mn(t,`Current screenshot not found`);let r=n.outputPath,[i,a]=await Promise.all([T.readFile(e),T.readFile(t)]),[o,s]=await Promise.all([et(i,`baseline screenshot`),et(a,`current screenshot`)]);Nn(o.width,o.height,`baseline screenshot`,n.maxPixels),Nn(s.width,s.height,`current screenshot`,n.maxPixels);let c=n.threshold??.1;if(o.width!==s.width||o.height!==s.height){let e=o.width*o.height;return await Pn(n.outputPath),{match:!1,mismatchPercentage:100,totalPixels:e,differentPixels:e,dimensionMismatch:{expected:{width:o.width,height:o.height},actual:{width:s.width,height:s.height}}}}let l=o.width*o.height,u=c*An,{diffData:d,diffMask:f,differentPixels:p}=await tt({baselineData:o.data,currentData:s.data,width:o.width,height:o.height,maxColorDistance:u}),m=p>0?gn({diffMask:f,baseline:o,current:s,totalPixels:l,differentPixels:p}):[];if(p>0&&r){let e=new $e.PNG({width:o.width,height:o.height});e.data=d,qt(e,m),await T.mkdir(it.dirname(r),{recursive:!0}),await T.writeFile(r,await rt(e))}else await Pn(n.outputPath);let ee=l>0?Math.round(p/l*100*100)/100:0;return{...p>0&&r?{diffPath:r}:{},...m.length>0?{regions:m}:{},totalPixels:l,differentPixels:p,mismatchPercentage:ee,match:p===0}}async function Mn(e,n){try{await T.access(e)}catch{throw new t(`INVALID_ARGS`,`${n}: ${e}`)}}function Nn(e,n,r,i){if(i==null||i<=0)return;let a=e*n;if(!(a<=i))throw new t(`INVALID_ARGS`,`${r} is ${a} pixels, which exceeds the configured maxImagePixels limit of ${i}`)}async function Pn(e){if(e)try{await T.unlink(e)}catch(e){if(!Fn(e,`ENOENT`))throw e}}function Fn(e,t){return typeof e==`object`&&!!e&&`code`in e&&e.code===t}function In(e,t){return e.map(e=>{let n=Ln(e,t);return n.length>0?{...e,currentOverlayMatches:n}:e})}function Ln(e,t){let n=Rn(e.rect);return t.map(t=>{let r=t.overlayRect,i=Ye(e.rect,r);return i<=0?null:{ref:t.ref,...t.label?{label:t.label}:{},rect:r,overlayCoveragePercentage:zn(i/Rn(r)),regionCoveragePercentage:zn(i/n)}}).filter(e=>e!==null).sort((e,t)=>{let n=t.regionCoveragePercentage-e.regionCoveragePercentage;return n===0?t.overlayCoveragePercentage-e.overlayCoveragePercentage:n}).slice(0,3).map(e=>({ref:e.ref,...e.label?{label:e.label}:{},rect:e.rect,regionCoveragePercentage:e.regionCoveragePercentage}))}function Rn(e){return e.width*e.height}function zn(e){return Math.round(e*100*100)/100}async function P(e,n,r){if(n.kind===`path`&&!e.policy.allowLocalInputPaths)throw new t(`INVALID_ARGS`,`Local ${r.field??`input`} paths are not allowed by command policy`);try{return await e.artifacts.resolveInput(n,r)}catch(e){throw s(e)}}async function F(e,n,r){if(n?.kind===`path`&&!e.policy.allowLocalOutputPaths)throw new t(`INVALID_ARGS`,`Local output paths are not allowed by command policy`);try{return await e.artifacts.reserveOutput(n,{...r,visibility:r.visibility??`client-visible`,requestedClientPath:n?.kind===`downloadableArtifact`?n.clientPath??r.requestedClientPath:r.requestedClientPath})}catch(e){throw s(e)}}async function Bn(e,t){try{return await e.artifacts.createTempFile(t)}catch(e){throw s(e)}}const Vn=async(e,n)=>{if(!n.baseline)throw new t(`INVALID_ARGS`,`diff screenshot requires a baseline image`);let r=Hn(n.threshold),i=n.current??{kind:`live`};if(n.overlayRefs&&!L(i))throw new t(`INVALID_ARGS`,`diff screenshot <current.png> cannot use --overlay-refs because saved-image comparisons have no live accessibility refs`);let a=await P(e,n.baseline,{usage:`diff screenshot baseline`,field:`baseline`}),o,s,c,l=[];try{let t;L(i)?(s=await Un(e,n),t=s.path):(o=await P(e,i,{usage:`diff screenshot current`,field:`current`}),t=o.path),c=n.out?await F(e,n.out,{field:`diffPath`,ext:`.png`,artifactType:`screenshot-diff`}):void 0;let u=await jn(a.path,t,{threshold:r,outputPath:c?.path,maxPixels:e.policy.maxImagePixels});L(i)&&(u=await Wn(e,n,c?.path,u,l));let d=u.diffPath?await c?.publish():void 0;return d&&l.push(d),u.diffPath||await c?.cleanup?.(),{...u,...l.length>0?{artifacts:l}:{}}}catch(e){throw await c?.cleanup?.(),e}finally{await a.cleanup?.(),await o?.cleanup?.(),await s?.cleanup?.()}};function Hn(e){if(e==null||e===``)return .1;let n=Number(e);if(Number.isNaN(n)||n<0||n>1)throw new t(`INVALID_ARGS`,`--threshold must be a number between 0 and 1`);return n}async function Un(e,t){let n=await Bn(e,{prefix:`agent-device-diff-current`,ext:`.png`});try{await Gn(e,t,n.path,Kn(t))}catch(e){throw await n.cleanup(),e}return n}async function Wn(e,t,n,r,i){if(!t.overlayRefs)return r;if(r.match||r.dimensionMismatch)return n&&await Jn(n),r;let a=await F(e,qn(t,n),{field:`currentOverlayPath`,ext:`.png`,artifactType:`screenshot`});try{let n=await Gn(e,t,a.path,{overlayRefs:!0,...Kn(t)}),o=await a.publish();return o&&i.push(o),{...r,currentOverlayPath:n.path??a.path,...n.overlayRefs?{currentOverlayRefCount:n.overlayRefs.length}:{},...r.regions&&n.overlayRefs?{regions:In(r.regions,n.overlayRefs)}:{}}}catch(e){throw await a.cleanup?.(),e}}async function Gn(e,n,r,i={}){if(!e.backend.captureScreenshot)throw new t(`UNSUPPORTED_OPERATION`,`screenshot is not supported by this backend`);return await e.backend.captureScreenshot({session:n.session,requestId:n.requestId,signal:n.signal??e.signal,metadata:n.metadata},r,i)??{}}function Kn(e){return{normalizeStatusBar:e.normalizeStatusBar??!0,...e.surface?{surface:e.surface}:{}}}function qn(e,t){if(e.currentOverlayOut)return e.currentOverlayOut;if(e.out?.kind===`path`)return{kind:`path`,path:I(t??e.out.path)};if(e.out?.kind===`downloadableArtifact`)return{kind:`downloadableArtifact`,...e.out.clientPath?{clientPath:I(e.out.clientPath)}:{},...e.out.fileName?{fileName:I(e.out.fileName)}:{}}}function I(e){let t=it.extname(e);return`${t?e.slice(0,-t.length):e}.current-overlay${t||`.png`}`}async function Jn(e){try{await T.unlink(I(e))}catch(e){if(!Yn(e,`ENOENT`))throw e}}function L(e){return e.kind===`live`}function Yn(e,t){return typeof e==`object`&&!!e&&`code`in e&&e.code===t}const Xn=async(e,n)=>{if(!e.backend.captureScreenshot)throw new t(`UNSUPPORTED_OPERATION`,`screenshot is not supported by this backend`);l(n);let r=await F(e,n.out,{field:`path`,ext:`.png`,artifactType:`screenshot`}),i;try{await e.backend.captureScreenshot({session:n.session,requestId:n.requestId,appId:n.appId,appBundleId:n.appBundleId,signal:n.signal??e.signal,metadata:n.metadata},r.path,{fullscreen:n.fullscreen,overlayRefs:n.overlayRefs,pixelDensity:n.pixelDensity,stabilize:n.stabilize,normalizeStatusBar:n.normalizeStatusBar,surface:n.surface}),n.scale!==void 0&&await nt(r.path,n.scale),i=await r.publish()}catch(e){throw await r.cleanup?.(),e}return{path:r.path,...i?{artifacts:[i]}:{},..._(`Saved screenshot: ${r.path}`)}};function Zn(e,t){return[...er(e),...Qn(e),...nr(e),...rr(e,t)]}function Qn(e){let t=e.customActions;if(!t)return[];let n=[];return t.blocked?n.push(`Custom actions were not read: an earlier accessibility read is still hung, so this capture skipped the read pass instead of queueing behind it. No element’s actions list is authoritative here. Reads resume once that call returns.`):t.read<t.candidates&&n.push(`Custom actions were read for ${t.read} of ${t.candidates} merged elements, on-screen ones first; the remaining ${t.candidates-t.read} were not read, so an absent actions list on those is not evidence that they have none. Scroll them into view and re-run to read them.`),t.truncated>0&&n.push(`${t.truncated} element(s) published more custom actions than are shown; those lists are clipped to the first 8 names, and long names are shortened.`),n}function $n(e){return`Detected an overly complex or slow accessibility tree. Fell back to the ${e} snapshot backend. It is OK to continue; use --json to inspect snapshotQuality.reason if you need recovery details.`}function er(e){return e.state===`recovered`?e.reasonCode===`deferred`||e.reasonCode===`requested-backend`?[]:[$n(e.backend)]:e.state===`sparse`?[`No snapshot backend could read this screen`+(e.reason?` (${e.reason})`:``)+`. Its refs and selectors are invalid. Use screenshot as visual truth and coordinate taps; retry snapshot after navigating.`,...tr(e)]:[]}function tr(e){return e.reasonCode===`sparse-tree`?[`This screen publishes no accessibility content at all; assistive technologies see the same empty tree, so it is worth flagging as an app accessibility bug rather than only an automation limitation.`]:[]}function nr(e){return e.effectiveDepth===void 0?[]:[`Some deeper accessibility nodes were omitted; this tree is capped at depth ${e.effectiveDepth}. Re-run with --depth ${e.effectiveDepth} --scope <container> only if you need deeper content.`]}function rr(e,t){let n=[];for(let r of e.collapsedLeafIndexes??[]){let e=t.find(e=>e.index===r);if(!e)continue;let i=e.identifier?` (${e.identifier})`:``;n.push(`@${e.ref} [${e.type??`element`}]${i} merges many labels into a single accessibility element. The app likely marks a container as accessible, which hides every descendant from assistive tech and automation — the children cannot be addressed individually. Fix the app's accessibility (mark the rows, not the container); until then use screenshot as visual truth and coordinate taps.`)}return n}function ir(e){let{nodes:t,backend:n,snapshotRaw:i}=e;if(i||!r(n))return{partial:!1,visibleNodeCount:t.length,totalNodeCount:t.length,reasons:[]};let a=Je(t),o=new Set;return a.hiddenCount>0&&o.add(`offscreen-nodes`),a.nodes.some(e=>e.hiddenContentAbove)&&o.add(`scroll-hidden-above`),a.nodes.some(e=>e.hiddenContentBelow)&&o.add(`scroll-hidden-below`),{partial:o.size>0,visibleNodeCount:a.nodes.length,totalNodeCount:t.length,reasons:[...o]}}const ar=`A system surface (notification shade, quick settings, or another system overlay) covers the app, so this snapshot shows that surface. Interact with it or dismiss it (press back or swipe up) to reach app content.`;function or(e){return e?.systemSurfaceOnly===!0?ar:void 0}function sr(e,t){return e.presentationKey?e:{...e,presentationKey:i(t)}}function cr(e){let{previous:t,current:n,options:r,identity:i}=e;if(r.forceFull===!0||r.raw===!0||!t||t.comparisonSafe===!1||n.comparisonSafe===!1||!lr(t,n,i)||!t.presentationKey||t.presentationKey!==n.presentationKey||!ur(t,n))return;let a=r.scope?.trim();return{ageMs:Math.max(0,n.createdAt-t.createdAt),nodeCount:n.nodes.length,...r.interactiveOnly===!0?{interactiveOnly:!0}:{},...a?{scope:a}:{}}}function lr(e,t,n){return!(e.backend&&t.backend&&e.backend!==t.backend||n?.previousAppBundleId&&n.currentAppBundleId&&n.previousAppBundleId!==n.currentAppBundleId)}function ur(e,t){return e.truncated===t.truncated?JSON.stringify(dr(e.nodes))===JSON.stringify(dr(t.nodes)):!1}function dr(e){return e.map(e=>({index:e.index,depth:e.depth,parentIndex:e.parentIndex,type:e.type,role:e.role,subrole:e.subrole,label:e.label,value:e.value,identifier:e.identifier,enabled:e.enabled,selected:e.selected,focused:e.focused,hittable:e.hittable,rect:e.rect,bundleId:e.bundleId,appName:e.appName,windowTitle:e.windowTitle,surface:e.surface,hiddenContentAbove:e.hiddenContentAbove,hiddenContentBelow:e.hiddenContentBelow,interactionBlocked:e.interactionBlocked,presentationHints:e.presentationHints,actions:e.actions}))}const fr=async(e,t)=>{let n=await mr(e,t),r=cr({previous:n.session?.snapshot,current:n.snapshot,options:t,identity:{previousAppBundleId:n.session?.appBundleId,currentAppBundleId:n.result.appBundleId??n.session?.appBundleId}});return await e.sessions.set(gr(t.session,n)),{nodes:n.snapshot.nodes,truncated:n.snapshot.truncated??!1,visibility:ir({nodes:n.snapshot.nodes,backend:n.snapshot.backend,snapshotRaw:t.raw}),...u({...n.annotations,warnings:n.warnings}),...r?{unchanged:r}:{},...n.result.snapshotDiagnostics?{snapshotDiagnostics:n.result.snapshotDiagnostics}:{},..._r(n)}},pr=async(e,t)=>{let n=await mr(e,t),r=t.interactiveOnly===!0,i=n.session?.snapshot,a=gr(t.session,n);if(!i){let t=Be(n.snapshot.nodes,{flatten:r});return await e.sessions.set(a),{mode:`snapshot`,baselineInitialized:!0,summary:{additions:0,removals:0,unchanged:t},lines:[],...n.warnings.length>0?{warnings:n.warnings}:{}}}let o=pe(i.nodes,n.snapshot.nodes,{flatten:r});return await e.sessions.set(a),{mode:`snapshot`,baselineInitialized:!1,summary:o.summary,lines:o.lines,...n.warnings.length>0?{warnings:n.warnings}:{}}};async function mr(e,n){if(!e.backend.captureSnapshot)throw new t(`UNSUPPORTED_OPERATION`,`snapshot is not supported by this backend`);let r=n.session??`default`,i=await e.sessions.get(r),a=await e.backend.captureSnapshot({session:r,requestId:n.requestId,appId:i?.appId,appBundleId:i?.appBundleId,signal:n.signal??e.signal,metadata:n.metadata},{interactiveOnly:n.interactiveOnly,depth:n.depth,scope:n.scope,raw:n.raw,customActions:n.customActions}),o=sr(hr(a,e),n),s=c(a),l=Ie(e);return{snapshot:o,result:a,session:i,annotations:s,warnings:vr({result:a,annotations:s,snapshot:o,options:n,session:i,capturedAt:o.createdAt??l,runtimeNow:l})}}function hr(e,t){return e.snapshot?e.snapshot:{nodes:e.nodes??[],truncated:e.truncated,backend:e.backend,createdAt:Ie(t)}}function gr(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 _r(e){let t=e.result.appName??e.session?.appName,n=e.result.appBundleId??e.session?.appBundleId;return{...t||n?{appName:t??n}:{},...n?{appBundleId:n}:{}}}function vr(e){let t=[...e.annotations.warnings??[]];e.annotations.quality&&t.push(...Zn(e.annotations.quality,e.snapshot.nodes)),t.push(...Sr(e)),e.annotations.quality||(t.push(...br(e)),t.push(...xr(e.snapshot.nodes)));let n=ut(e.snapshot.nodes);n&&t.push(n);let r=yr(e.annotations);r&&t.push(r);let i=Cr(e);return i&&t.push(i),t.push(...Dr(e.annotations.freshness,e.snapshot.backend)),Array.from(new Set(t))}function yr(e){if(e.androidSnapshot?.systemSurfaceOnly===!0)return ar}function br(e){return e.snapshot.backend!==`xctest`||e.options.interactiveOnly!==!0||e.snapshot.nodes.length!==1||e.snapshot.nodes[0]?.type!==`Application`?[]:[`iOS interactive snapshot exposed only the application root. XCTest accessibility queries can fail to enumerate some simulator UI trees even when screenshots and direct gestures still work. Use screenshot as visual truth, try a scoped/full snapshot for diagnostics, and prefer direct selectors when known.`]}function xr(e){let t=new Set(e.map(e=>e.parentIndex).filter(e=>e!==void 0));return e.filter(e=>t.has(e.index)||(e.type?.toLowerCase()??``).includes(`text`)?!1:(e.label??``).split(`, `).length>10).map(e=>{let t=(e.label??``).split(`, `).length,n=e.identifier?` (${e.identifier})`:``;return`@${e.ref} [${e.type??`element`}]${n} merges ~${t} labels into a single accessibility element. The app likely marks a container as accessible, which hides every descendant from assistive tech and automation — the children cannot be addressed individually. Fix the app's accessibility (mark the rows, not the container); until then use screenshot as visual truth and coordinate taps.`})}function Sr(e){let t=e.annotations.analysis;if(e.snapshot.backend!==`android`||e.options.interactiveOnly!==!0||e.snapshot.nodes.length>0||!t||(t.rawNodeCount??0)<12)return[];let n=[`Interactive snapshot is empty after filtering ${t.rawNodeCount} raw Android nodes. Likely causes: the app content is not accessibility-visible yet, a transient route change, or depth/filter options hid the target.`];return typeof e.options.depth==`number`&&typeof t.maxDepth==`number`&&t.maxDepth>=e.options.depth+2&&n.push(`Interactive output is empty at depth ${e.options.depth}; retry without -d.`),n}function Cr(e){let t=e.session?.snapshot;if(!e.annotations.freshness&&t&&wr(t,e.snapshot)&&Tr(t,e.capturedAt,e.runtimeNow)&&Or(t.nodes.length,e.snapshot.nodes.length))return Er}function wr(e,t){return e.presentationKey===void 0||t.presentationKey===void 0?!0:e.presentationKey===t.presentationKey}function Tr(e,t,n){return[t,n].some(t=>{let n=t-e.createdAt;return n>=0&&n<=2e3})}const Er=`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.`;function Dr(e,t){return!e?.staleAfterRetries||t!==`android`?[]:e.reason===`stuck-route`?[`Recent ${e.action} was followed by a nearly identical snapshot after ${e.retryCount} automatic retr${e.retryCount===1?`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.`]:e.reason===`sharp-drop`?[Er]:[]}function Or(e,t){return e<12?!1:t<=Math.floor(e*.2)}const kr={screenshot:Xn,diffScreenshot:Vn,snapshot:fr,diffSnapshot:pr},Ar=new WeakMap;function jr(e,t){Nr(e)&&Ar.set(e,t)}function Mr(e){return Nr(e)?Ar.get(e):void 0}function Nr(e){return typeof e==`object`&&!!e||typeof e==`function`}const Pr=async(e,t)=>await Rr(e,t,`press`),Fr=async(e,t)=>await Rr(e,t,`click`),Ir=async(e,n)=>{if(!n.text)throw new t(`INVALID_ARGS`,`fill requires text`);let r=je(n),i=r.needsPreActionBaseline?null:await Vr(e,n);if(i)return i;let a=await Pe(e,n,{action:`fill`,requireInteractive:!0,pipeline:y.resolvedTarget,captureEvidenceBaseline:r.needsPreActionBaseline,expectedResolvedTarget:n.expectedResolvedTarget,preresolvedTarget:n.preresolvedTarget});if(!e.backend.fill)throw new t(`UNSUPPORTED_OPERATION`,`fill is not supported by this backend`);let o=zr(a),s=`node`in a?a.node?.type??``:``,c=s!==``&&se(s,e.backend.platform),l=n.allowNonHittableCoordinateFallback===!0&&`node`in a&&a.node?.hittable===!1,u=C(await e.backend.fill(S(e,n),o,n.text,{delayMs:n.delayMs,allowNonHittableCoordinateFallback:l})),d=s&&!c?`fill target ${Ur(a)} resolved to "${s}", attempting fill anyway.`:void 0;return await Me(e,n,a,{...a,text:n.text,...d?{warning:d}:{},...u?{backendResult:u}:{}},r)},Lr=async(e,n)=>{let r=n.text;if(!r)throw new t(`INVALID_ARGS`,`type requires text`);let i=Wr(r);if(i)throw new t(`INVALID_ARGS`,`type does not accept a target ref like "${i}"`,{hint:`Use fill ${i} "text" to target that field, or press ${i} then type "text" to append.`});if(!e.backend.typeText)throw new t(`UNSUPPORTED_OPERATION`,`type is not supported by this backend`);let a=x(n.delayMs??0,`delay-ms`,0,1e4),o=C(await e.backend.typeText(S(e,n),r,{delayMs:a}));return{kind:`text`,text:r,delayMs:a,...o?{backendResult:o}:{},..._(`Typed ${Array.from(r).length} chars`)}};async function Rr(e,n,r){let i=je(n),a=i.needsPreActionBaseline?null:await Br(e,n,r);if(a)return a;let o=await Pe(e,n,{action:r,requireInteractive:!0,pipeline:y.promotedTarget,captureEvidenceBaseline:i.needsPreActionBaseline,expectedResolvedTarget:n.expectedResolvedTarget,preresolvedTarget:n.preresolvedTarget});if(!e.backend.tap)throw new t(`UNSUPPORTED_OPERATION`,`tap is not supported by this backend`);let s=zr(o),c;try{c=await e.backend.tap(S(e,n),s,{button:n.button,count:n.count,intervalMs:n.intervalMs,holdMs:n.holdMs,jitterPx:n.jitterPx,doubleTap:n.doubleTap})}catch(e){throw jr(e,o),e}let l=C(c);return await Me(e,n,o,{...o,...l?{backendResult:l}:{}},i)}function zr(e){if(!e.point)throw new t(`COMMAND_FAILED`,`Interaction target resolved without coordinates`);return e.point}async function Br(e,t,n){if(n!==`click`||t.target.kind!==`ref`||!e.backend.tapTarget||Hr(t)||t.expectedResolvedTarget)return null;let r=await xe(e,t,t.target,n),i=C(await e.backend.tapTarget(S(e,t),{kind:`ref`,ref:t.target.ref,...t.target.fallbackLabel?{fallbackLabel:t.target.fallbackLabel}:{}}));return{kind:`ref`,target:{kind:`ref`,ref:t.target.ref},resolution:we,...r,...i?{backendResult:i}:{}}}async function Vr(e,t){if(t.target.kind!==`ref`||!e.backend.fillTarget||t.expectedResolvedTarget)return null;let n=await xe(e,t,t.target,`fill`),r=C(await e.backend.fillTarget(S(e,t),{kind:`ref`,ref:t.target.ref,...t.target.fallbackLabel?{fallbackLabel:t.target.fallbackLabel}:{}},t.text,{delayMs:t.delayMs}));return{kind:`ref`,target:{kind:`ref`,ref:t.target.ref},text:t.text,resolution:we,...n,...r?{backendResult:r}:{}}}function Hr(e){return e.count!==void 0||e.intervalMs!==void 0||e.holdMs!==void 0||e.jitterPx!==void 0||e.doubleTap!==void 0||e.button!==void 0&&e.button!==`primary`}function Ur(e){return e.target?.kind===`ref`?e.target.ref:e.target?.kind===`selector`?e.target.selector:`point`}function Wr(e){return Kt(e)}function R(e){return{includeRects:e===`visible`||e===`hidden`,interactiveOnly:!1}}const Gr=y.wait.poll.defaultTimeoutMs;function z(e,t,n,r){let i=ye(r),a=n??i.defaultTimeoutMs,o=V(e),s=Yr(),c=()=>Math.max(0,a-(V(e)-o));return{capture:async n=>{let r=!1,i=await Oe(e,t,c(),async e=>await s.attempt(async()=>{let t=await n(e);return r=!0,t}));return i.timedOut?{timedOut:!0,deadline:s.readableCaptures()===0?`capture-stalled`:`capture-truncated`}:(r&&s.recordReadableCapture(),i)},hasTimeRemaining:()=>c()>0,failureEvidence:()=>({timeoutMs:a,readableCaptures:s.readableCaptures(),waitedMs:V(e)-o}),rethrowIfNeverReadable:s.rethrowIfNeverReadable,sleepUntilNextPoll:async()=>await Xr(e,t,Math.min(i.intervalMs,c())),timeoutMs:a,waitedMs:()=>V(e)-o}}function Kr(e,n){return new t(`COMMAND_FAILED`,e,{reason:w.captureStalled,captureStalled:!0,...n,retriable:!0,hint:`No readable snapshot capture completed before the wait timeout. Retry, or use screenshot to inspect the current surface.`})}function qr(e,n){return new t(`COMMAND_FAILED`,e,{reason:w.deadlineExceeded,captureTruncated:!0,...n})}function Jr(e,n){return new t(`COMMAND_FAILED`,e,{reason:w.targetAbsent,...n})}function B(e,t,n){let r=t.failureEvidence();return n===`capture-stalled`?Kr(e,r):n===`capture-truncated`?qr(e,r):(t.rethrowIfNeverReadable(),r.readableCaptures===0?Kr(e,r):Jr(e,r))}function Yr(){let e=0,t;return{attempt:async e=>{try{return await e()}catch(e){if(!p(e))throw e;t=e;return}},recordReadableCapture:()=>{e+=1},readableCaptures:()=>e,rethrowIfNeverReadable:()=>{if(e===0&&t!==void 0)throw t}}}function V(e){return e.clock?.now()??Date.now()}async function Xr(e,t,n){let r=[t.signal,e.signal].filter(e=>e!==void 0);for(let e of r)e.throwIfAborted();if(n<=0)return!1;if(e.clock){await e.clock.sleep(n);for(let e of r)e.throwIfAborted();return!0}return await new Promise((e,t)=>{let i=r.length>0?AbortSignal.any(r):void 0,a=()=>i?.removeEventListener(`abort`,s),o=setTimeout(()=>{a(),e()},n),s=()=>{clearTimeout(o),a(),t(i?.reason)};i?.addEventListener(`abort`,s,{once:!0}),o.unref()}),!0}function Zr(e){if(e.kind===`ambiguous`||e.kind===`target`)return{selector:e.selector,selectorIndex:e.selectorIndex,matchedNodes:e.matchedNodes}}function Qr(e){let r=async(r,i)=>{if(i.target.kind===`sleep`)return await Xr(r,i,i.target.durationMs),{kind:`sleep`,waitedMs:i.target.durationMs};if(i.target.kind===`ref`){let o=await e.requireSnapshot(r,i.session),s=a(i.target.ref);if(!s)throw new t(`INVALID_ARGS`,`Invalid ref: ${i.target.ref}`);let c=n(o.snapshot.nodes,s),l=c?He(c,o.snapshot.nodes):void 0;if(!l)throw new t(`COMMAND_FAILED`,`Ref ${i.target.ref} not found or has no label`);return await ti(e,r,i,l,i.target.timeoutMs)}if(i.target.kind===`selector`)return await $r(e,r,i,i.target.selector,i.target.timeoutMs,i.target.recordedLandmark);if(i.target.kind===`stable`)return await ri(e,r,i,i.target.quietMs,i.target.timeoutMs);let o=m(i.target.text);if(!o.ok)throw new t(o.code,o.message);return await ti(e,r,i,i.target.text,i.target.timeoutMs)};return{waitCommand:r,waitForTextCommand:async(e,n)=>{let i=await r(e,{...n,target:{kind:`text`,text:n.text,timeoutMs:n.timeoutMs}});if(i.kind!==`text`)throw new t(`COMMAND_FAILED`,`waitForText returned non-text result`);return i}}}async function $r(e,n,r,i,a,o){let s=z(n,r,a,y.wait),c=R(),l,u;for(;s.hasTimeRemaining();){let t=await s.capture(async t=>await e.captureSnapshot(n,{...r,signal:t},{updateSession:!0,includeHiddenContentHints:!1,...c}));if(t.timedOut){u=t.deadline;break}let a=t.value;if(a){let e=a.snapshot.nodes,t=Zr(await v(y.wait,e,i,{platform:n.backend.platform}));if(t){let n=ei(e,t,o);if(n.kind===`satisfied`)return{kind:`selector`,selector:t.selector,waitedMs:s.waitedMs(),node:n.node,preActionNodes:e};l=n.evidence}}await s.sleepUntilNextPoll()}throw u!==`capture-stalled`&&l?new t(`COMMAND_FAILED`,`wait matched selector ${i} but no candidate carried the recorded landmark identity`,{reason:Ne,...l}):B(`wait timed out for selector: ${i}`,s,u)}function ei(e,t,n){let r=t.matchedNodes[0];if(!n)return{kind:`satisfied`,node:r};let i=Ee(e),a=_e(t.matchedNodes,i,ie(n),n.ancestry)[0];return a?{kind:`satisfied`,node:a}:{kind:`identity-mismatch`,evidence:{matchCount:t.matchedNodes.length,observed:f(r),observedAncestry:fe(r,i,Math.max(n.ancestry.length,1)).chain}}}async function ti(e,t,n,r,i){let a=z(t,n,i,y.wait),o;for(;a.hasTimeRemaining();){let i=await a.capture(async i=>t.backend.findText?(await t.backend.findText(ii(t,{...n,signal:i}),r)).found:await ni(e,t,{...n,signal:i},r));if(i.timedOut){o=i.deadline;break}if(i.value)return{kind:`text`,text:r,waitedMs:a.waitedMs()};await a.sleepUntilNextPoll()}throw B(`wait timed out for text: ${r}`,a,o)}async function ni(e,t,n,r){return!!Ce((await e.captureSnapshot(t,n,{updateSession:!0,includeHiddenContentHints:!1})).snapshot.nodes,r)}async function ri(e,n,r,i,a){let o=a??Gr,s=i??e.stable.defaultQuietMs,c=await e.stable.capture(n,r,{quietMs:s,timeoutMs:o});if(!c.settled)throw new t(`COMMAND_FAILED`,`wait timed out waiting for a stable UI`,{reason:w.stableTimeout,...c.stalled?{captureStalled:!0}:{},quietMs:s,timeoutMs:o,captures:c.captures,nodeCount:c.nodeCount,...c.stalled?{hint:`A snapshot capture stalled past the wait timeout, so no settle verdict is available. The UI may still be readable: retry, or use screenshot to inspect the surface.`}:{}});return{kind:`stable`,waitedMs:c.waitedMs,captures:c.captures,nodeCount:c.nodeCount,...c.nodeCount<e.stable.tinyTreeNodeCount?{hint:e.stable.tinyTreeHint}:{}}}function ii(e,t){return{session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata}}const ai=Qr({captureSnapshot:h,requireSnapshot:Se,stable:{defaultQuietMs:500,tinyTreeHint:ze,tinyTreeNodeCount:5,capture:Ve}}),oi=ai.waitCommand,si=ai.waitForTextCommand,ci=async(e,n)=>{let r=n.locator??`any`;if(!n.query)throw new t(`INVALID_ARGS`,ue);if(n.action===`wait`)return await pi(e,n,r);if(n.action===`list`)return await mi(e,n,r);let{capture:i,match:a}=await hi(e,n,r);if(!a)throw new t(`COMMAND_FAILED`,`find did not match any element`);if(n.action===`exists`)return{kind:`found`,found:!0};let o=`@${a.ref}`;return n.action===`get_attrs`?{kind:`attrs`,ref:o,node:a}:{kind:`text`,ref:o,text:await g(e,i,a),node:a}},H=async(e,t)=>{if(t.target.kind===`ref`){let n=await Se(e,t.session),r=ge(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`});he(r.node,n.snapshot.nodes,t.expectedResolvedTarget,`get`);let i=de(r.node,e.backend.platform,{action:`get`,nodes:n.snapshot.nodes}),a={kind:`ref`,ref:`@${r.ref}`},o=n.snapshot.nodes;return t.property===`attrs`?{kind:`attrs`,target:a,node:r.node,selectorChain:i,preActionNodes:o}:{kind:`text`,target:a,text:await g(e,n,r.node),node:r.node,selectorChain:i,preActionNodes:o}}let n=await gi(e,t,t.session??`default`,{selector:t.target.selector,policy:t.property===`text`?y.readText:y.readUnique,hooks:{onResolved:(e,n)=>he(e,n,t.expectedResolvedTarget,`get`)}}),r=de(n.node,e.backend.platform,{action:`get`,nodes:n.capture.snapshot.nodes});if(t.property===`attrs`)return{kind:`attrs`,target:{kind:`selector`,selector:n.selector},node:n.node,selectorChain:r,preActionNodes:n.capture.snapshot.nodes};let i=await g(e,n.capture,n.node);return{kind:`text`,target:{kind:`selector`,selector:n.selector},text:i,node:n.node,selectorChain:r,preActionNodes:n.capture.snapshot.nodes}},li=async(e,n)=>{let r=await H(e,{...n,property:`text`,target:n.target});if(r.kind!==`text`)throw new t(`COMMAND_FAILED`,`getText returned non-text result`);return r},ui=async(e,n)=>{let r=await H(e,{...n,property:`attrs`,target:n.target});if(r.kind!==`attrs`)throw new t(`COMMAND_FAILED`,`getAttrs returned non-attrs result`);return r},U=async(e,n)=>{let r=ee(n.predicate);if(!r.ok)throw new t(r.code,r.message,{hint:r.hint});let i=r.predicate;if(i===`text`&&!n.expectedText)throw new t(`INVALID_ARGS`,d);let a=n.selector,o=await h(e,n,{updateSession:!0,...R(i)});if(i===`exists`){let n=await v(y.readAny,o.snapshot.nodes,a,{platform:e.backend.platform});if(n.kind!==`target`)throw new t(`COMMAND_FAILED`,re(a,[],{unique:!1}),{hint:ae([])});return{predicate:i,pass:!0,selector:n.selector,matches:n.matches,selectorChain:le(a)}}let s=await v(y.readUnique,o.snapshot.nodes,a,{platform:e.backend.platform},{onResolved:(e,t)=>he(e,t,n.expectedResolvedTarget,`is`)});if(s.kind!==`target`)throw new t(`COMMAND_FAILED`,re(a,[],{unique:!0}),{command:`is`,reason:`selector_not_found`,predicate:i,selector:a,hint:ae([])});let c=s,l=ce({predicate:i,node:c.node,nodes:o.snapshot.nodes,expectedText:n.expectedText,platform:e.backend.platform});if(!l.pass)throw new t(`COMMAND_FAILED`,`is ${i} failed for selector ${c.selector}: ${l.details}`,{command:`is`,reason:`predicate_failed`,predicate:i,selector:c.selector,predicateDetails:l.details});return{predicate:i,pass:!0,selector:c.selector,...i===`text`?{text:l.actualText}:{},selectorChain:le(a),node:c.node,preActionNodes:o.snapshot.nodes}},di=async(e,t)=>await U(e,{...t,predicate:`visible`,selector:t.target.selector}),fi=async(e,t)=>await U(e,{...t,predicate:`hidden`,selector:t.target.selector});async function pi(e,t,n){let r=z(e,t,t.timeoutMs,y.findWait),i;for(;r.hasTimeRemaining();){let a=await r.capture(async r=>await hi(e,{...t,signal:r},n,{includeHiddenContentHints:!1}));if(a.timedOut){i=a.deadline;break}if(a.value?.match)return{kind:`found`,found:!0,waitedMs:r.waitedMs()};await r.sleepUntilNextPoll()}throw B(`find wait timed out`,r,i)}async function mi(e,t,n){let r=ne(n,t.query),i=await h(e,t,{updateSession:!0,...R()});if(Xe(i.snapshot.snapshotQuality))throw be(i.snapshot.snapshotQuality);return{kind:`list`,matches:(r?Te(y.readList,i.snapshot.nodes,r,{platform:e.backend.platform}).list?.matchedNodes??[]:oe(i.snapshot.nodes,n,t.query,{}).matches).map(e=>({ref:`@${e.ref}`,node:e}))}}async function hi(e,t,n,r){let i=ne(n,t.query),a=await h(e,t,{updateSession:!0,scope:ve(e.backend.platform,n,t.query,i),includeHiddenContentHints:r?.includeHiddenContentHints,...R()});if(Xe(a.snapshot.snapshotQuality))throw be(a.snapshot.snapshotQuality);if(i){let t=await v(y.readAny,a.snapshot.nodes,i,{platform:e.backend.platform});return{capture:a,match:t.kind===`target`?t.node:void 0}}return{capture:a,match:oe(a.snapshot.nodes,n,t.query,{requireRect:!1}).matches[0]}}async function gi(e,n,r,i){let a=await h(e,{...n,session:r},{updateSession:!0,...R()}),o=await v(i.policy,a.snapshot.nodes,i.selector,{platform:e.backend.platform},i.hooks);if(o.kind!==`target`)throw new t(`COMMAND_FAILED`,re(i.selector,[],{unique:!0}),{hint:ae([])});return{capture:a,node:o.node,selector:o.selector,ref:`@${o.node.ref}`}}const _i=async(e,n)=>{if(!e.backend.performGesture)throw new t(`UNSUPPORTED_OPERATION`,`gesture is not supported by this backend`);await me(e,n,n.gesture.intent);let r=await Le(e,n),i=We(n.gesture,r,e.backend.platform),a=C(await e.backend.performGesture(S(e,n),i)),o=yi(i.pointers,0),s=yi(i.pointers,-1);return{kind:n.gesture.intent,durationMs:i.durationMs,pointerCount:i.topology===`single`?1:2,from:o,to:s,...a?{backendResult:a}:{},..._(bi(n.gesture,o,s))}},vi=async(e,t)=>{let n=t.gesture;return n.intent===`drag`?await Re(e,{...t,gesture:n}):await _i(e,{...t,gesture:n})};function yi(e,n){let r=e.map(e=>n===0?e.samples[0]?.point:e.samples.at(-1)?.point);if(r.some(e=>e===void 0))throw new t(`COMMAND_FAILED`,`Gesture plan did not contain endpoint samples.`);let i=r;return{x:i.reduce((e,t)=>e+t.x,0)/i.length,y:i.reduce((e,t)=>e+t.y,0)/i.length}}function bi(e,t,n){switch(e.intent){case`pan`:{let r=`preset`in e?t:e.origin,i=`preset`in e?{x:n.x-t.x,y:n.y-t.y}:e.delta;return`Panned (${r.x}, ${r.y}) by (${i.x}, ${i.y})`}case`fling`:return`direction`in e?`Flung ${e.direction}`:`Flung`;case`pinch`:return`Pinched to scale ${e.scale}`;case`rotate`:return`Rotated gesture ${e.degrees} degrees`;case`transform`:return`Requested transform gesture by (${e.delta.x}, ${e.delta.y}), scale ${e.scale}, rotate ${e.degrees} degrees`}}const W={find:ci,get:H,getText:li,getAttrs:ui,is:U,isVisible:di,isHidden:fi,wait:oi,waitForText:si},G={click:Fr,press:Pr,fill:Ir,typeText:Lr,focus:ke,longPress:Ae,scroll:Fe,gesture:vi,settleObservation:De};function xi(e){return{find:t=>W.find(e,t),get:t=>W.get(e,t),getText:(t,n={})=>W.getText(e,{...n,target:t}),getAttrs:(t,n={})=>W.getAttrs(e,{...n,target:t}),is:t=>W.is(e,t),isVisible:(t,n={})=>W.isVisible(e,{...n,target:t}),isHidden:(t,n={})=>W.isHidden(e,{...n,target:t}),wait:t=>W.wait(e,t),waitForText:(t,n={})=>W.waitForText(e,{...n,text:t})}}function Si(e){return{click:(t,n={})=>G.click(e,{...n,target:t}),press:(t,n={})=>G.press(e,{...n,target:t}),fill:(t,n,r={})=>G.fill(e,{...r,target:t,text:n}),typeText:(t,n={})=>G.typeText(e,{...n,text:t}),focus:(t,n={})=>G.focus(e,{...n,target:t}),longPress:(t,n={})=>G.longPress(e,{...n,target:t}),scroll:t=>G.scroll(e,t),gesture:t=>G.gesture(e,t),settleObservation:t=>G.settleObservation(e,t)}}function K(e,t){if(e!==void 0)return q(e,t)}function q(e,n){let r=e?.trim();if(!r)throw new t(`INVALID_ARGS`,`${n} must be a non-empty string`);return r}const Ci=async(e,n={})=>{if(!e.backend.listDevices)throw new t(`UNSUPPORTED_OPERATION`,`admin.devices is not supported by this backend`);return{kind:`adminDevices`,devices:await e.backend.listDevices(S(e,n),n.filter)}},wi=async(e,n={})=>{if(!e.backend.bootDevice)throw new t(`UNSUPPORTED_OPERATION`,`admin.boot is not supported by this backend`);let r=Pi(n.target),i=C(await e.backend.bootDevice(S(e,n),r));return{kind:`deviceBooted`,...r?{target:r}:{},...i?{backendResult:i}:{},..._(`Booted device`)}},Ti=async(e,n={})=>{if(!e.backend.shutdownDevice)throw new t(`UNSUPPORTED_OPERATION`,`admin.shutdown is not supported by this backend`);let r=Pi(n.target),i=C(await e.backend.shutdownDevice(S(e,n),r));return{kind:`deviceShutdown`,...r?{target:r}:{},...i?{backendResult:i}:{},..._(`Shutdown device`)}},Ei=async(e,t)=>await ki(e,t,`install`),Di=async(e,t)=>await ki(e,t,`reinstall`),Oi=async(e,t)=>await ki(e,t,`installFromSource`);async function ki(e,n,r){let i=r===`reinstall`?`reinstallApp`:`installApp`,a=e.backend[i];if(!a)throw new t(`UNSUPPORTED_OPERATION`,`admin.${r} is not supported by this backend`);let o=`app`in n&&n.app!==void 0?q(n.app,`app`):void 0;if(r!==`installFromSource`&&!o)throw new t(`INVALID_ARGS`,`admin.${r} requires app`);let s=S(e,n),c=await Ai(e,s,n.source);try{let t=await a.call(e.backend,s,{...o?{app:o}:{},source:c.source});return Fi(r,o,c.source,t)}finally{await c.cleanup?.()}}async function Ai(e,t,n){let r=await ji(e,Mi(n));try{return{source:Mi(e.backend.resolveInstallSource?await e.backend.resolveInstallSource(t,r.source):r.source),...r.cleanup?{cleanup:r.cleanup}:{}}}catch(e){if(r.cleanup)try{await r.cleanup()}catch{}throw e}}async function ji(e,t){if(t.kind===`url`)return{source:t};let n=await P(e,t,{usage:`admin.install`,field:`source`});return{source:{kind:`path`,path:n.path},...n.cleanup?{cleanup:n.cleanup}:{}}}function Mi(e){if(!e||typeof e!=`object`)throw new t(`INVALID_ARGS`,`install source is required`);if(e.kind===`path`)return{kind:`path`,path:q(e.path,`source.path`)};if(e.kind===`uploadedArtifact`)return{kind:`uploadedArtifact`,id:q(e.id,`source.id`)};if(e.kind===`url`){let t=q(e.url,`source.url`);return Ni(t),{kind:`url`,url:t}}throw new t(`INVALID_ARGS`,`install source kind must be path, uploadedArtifact, or url`)}function Ni(e){let n;try{n=new URL(e)}catch{throw new t(`INVALID_ARGS`,`Invalid install source URL: ${e}`)}if(n.protocol!==`http:`&&n.protocol!==`https:`)throw new t(`INVALID_ARGS`,`Install source URL must use http or https`)}function Pi(e){if(!e)return;let t=K(e.id,`target.id`),n=K(e.name,`target.name`),r={...t?{id:t}:{},...n?{name:n}:{},...e.platform?{platform:e.platform}:{},...e.target?{target:e.target}:{},...e.headless===void 0?{}:{headless:e.headless}};return Object.keys(r).length>0?r:void 0}function Fi(e,t,n,r){let i=C(r),a=e===`reinstall`?`appReinstalled`:e===`installFromSource`?`appInstalledFromSource`:`appInstalled`,o=J(r,`appName`),s=J(r,`appId`),c=J(r,`bundleId`),l=J(r,`packageName`),u=J(r,`launchTarget`),d=J(r,`installablePath`),f=J(r,`archivePath`);return{kind:a,...t?{app:t}:{},source:n,...s?{appId:s}:{},...o?{appName:o}:{},...c?{bundleId:c}:{},...l?{packageName:l}:{},...u?{launchTarget:u}:{},...d?{installablePath:d}:{},...f?{archivePath:f}:{},...i?{backendResult:i}:{},..._(`${e===`reinstall`?`Reinstalled`:`Installed`}: ${o??u??t??Ii(n)}`)}}function J(e,t){let n=e[t];return typeof n==`string`&&n.length>0?n:void 0}function Ii(e){return e.kind===`path`?e.path:e.kind===`uploadedArtifact`?e.id:e.url}const Li=/^[A-Za-z0-9_.:-]{1,64}$/,Ri=async(e,n)=>{if(!e.backend.openApp)throw new t(`UNSUPPORTED_OPERATION`,`apps.open is not supported by this backend`);let r=Wi(n),i=C(await e.backend.openApp(Y(e,n),r,{launchArgs:n.launchArgs,relaunch:n.relaunch}));return{kind:`appOpened`,target:r,relaunch:n.relaunch===!0,...i?{backendResult:i}:{},..._(`Opened: ${Ki(r)}`)}},zi=async(e,n={})=>{if(!e.backend.closeApp)throw new t(`UNSUPPORTED_OPERATION`,`apps.close is not supported by this backend`);let r=K(n.app,`app`),i=C(await e.backend.closeApp(Y(e,n),r));return{kind:`appClosed`,...r?{app:r}:{},...i?{backendResult:i}:{},..._(r?`Closed: ${r}`:`Closed app`)}},Bi=async(e,n={})=>{if(!e.backend.listApps)throw new t(`UNSUPPORTED_OPERATION`,`apps.list is not supported by this backend`);return{kind:`appsList`,apps:await e.backend.listApps(Y(e,n),Ze(n.filter))}},Vi=async(e,n)=>{if(!e.backend.getAppState)throw new t(`UNSUPPORTED_OPERATION`,`apps.state is not supported by this backend`);let r=q(n.app,`app`);return{kind:`appState`,app:r,state:await e.backend.getAppState(Y(e,n),r)}},Hi=async(e,n)=>{if(!e.backend.pushFile)throw new t(`UNSUPPORTED_OPERATION`,`apps.push is not supported by this backend`);let r=q(n.app,`app`),i=await qi(e,n.input);try{let t=C(await e.backend.pushFile(Y(e,n),i.backendInput,r));return{kind:`appPushed`,app:r,inputKind:i.inputKind,...t?{backendResult:t}:{},..._(`Pushed to ${r}`)}}finally{await i.cleanup?.()}},Ui=async(e,n)=>{if(!e.backend.triggerAppEvent)throw new t(`UNSUPPORTED_OPERATION`,`apps.triggerEvent is not supported by this backend`);let r=Ji(n.name);Yi(n.payload,`apps.triggerEvent payload for "${r}"`);let i=C(await e.backend.triggerAppEvent(Y(e,n),{name:r,...n.payload?{payload:n.payload}:{}}));return{kind:`appEventTriggered`,name:r,...n.payload?{payload:n.payload}:{},...i?{backendResult:i}:{},..._(`Triggered app event: ${r}`)}};function Wi(e){let n=K(e.app,`app`),r=K(e.appId,`appId`),i=K(e.bundleId,`bundleId`),a=K(e.packageName,`packageName`),o=K(e.url,`url`),s=K(e.activity,`activity`),c={...n?{app:n}:{},...r?{appId:r}:{},...i?{bundleId:i}:{},...a?{packageName:a}:{},...o?{url:o}:{},...s?{activity:s}:{}};if(!Gi(c))throw new t(`INVALID_ARGS`,`apps.open requires app, appId, bundleId, packageName, url, or activity`);return c}function Gi(e){return!!(e.app??e.appId??e.bundleId??e.packageName??e.url??e.activity)}function Ki(e){return e.app??e.appId??e.bundleId??e.packageName??e.url??e.activity??`app`}async function qi(e,n){if(!n||typeof n!=`object`)throw new t(`INVALID_ARGS`,`apps.push requires an input`);if(n.kind===`json`)return Xi(n.payload,`apps.push JSON payload`,8192),{backendInput:{kind:`json`,payload:n.payload},inputKind:`json`};let r=await P(e,n,{usage:`apps.push`,field:`input`});return{backendInput:{kind:`file`,path:r.path},inputKind:`file`,...r.cleanup?{cleanup:r.cleanup}:{}}}function Ji(e){let n=q(e,`name`);if(!Li.test(n))throw new t(`INVALID_ARGS`,`Invalid apps.triggerEvent name: ${n}`,{hint:`Use 1-64 chars: letters, numbers, underscore, dot, colon, or dash.`});return n}function Yi(e,t){e!==void 0&&Xi(e,t,8192)}function Xi(e,n,r){if(Zi(e,n),Buffer.byteLength(Qi(e,n),`utf8`)>r)throw new t(`INVALID_ARGS`,`${n} exceeds ${r} bytes`)}function Zi(e,n){if(!e||typeof e!=`object`||Array.isArray(e))throw new t(`INVALID_ARGS`,`${n} must be a JSON object`)}function Qi(e,n){try{let r=JSON.stringify(e);if(typeof r!=`string`)throw new t(`INVALID_ARGS`,`${n} must be JSON-serializable`);return r}catch{throw new t(`INVALID_ARGS`,`${n} must be JSON-serializable`)}}function Y(e,t){return{session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata}}const $i={open:Ri,close:zi,list:Bi,state:Vi,push:Hi,triggerEvent:Ui},ea={devices:Ci,boot:wi,shutdown:Ti,install:Ei,reinstall:Di,installFromSource:Oi};function ta(e){return{...b($i,e),list:(t={})=>$i.list(e,{...t,filter:Qe(t.filter)})}}const na=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i,ra=/\b[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\b/g;function ia(e){let t=!1,n=e;return n=n.replaceAll(/(authorization|token|secret|password|passwd|api[-_]?key)=([^&\s]+)/gi,(e,n)=>(t=!0,`${String(n)}=[REDACTED]`)),n=n.replaceAll(/("(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)"\s*:\s*")([^"]*)(")/gi,(e,n,r,i)=>(t=!0,`${String(n)}[REDACTED]${String(i)}`)),n=n.replaceAll(/\b(Bearer\s+)([^\s",;]+)/gi,(e,n)=>(t=!0,`${String(n)}[REDACTED]`)),n=n.replaceAll(/((?:authorization|cookie|token|secret|password|passwd|api[-_]?key)\s*[:=]\s*)([^\s,;&]+)/gi,(e,n)=>(t=!0,`${String(n)}[REDACTED]`)),n=n.replaceAll(ra,()=>(t=!0,`[REDACTED]`)),n=oa(n,()=>{t=!0}),{value:n,redacted:t}}function aa(e){try{let t=new URL(e),n=sa(t);return(t.username||t.password)&&(t.username=`REDACTED`,t.password=`REDACTED`,n=!0),{value:t.toString(),redacted:n}}catch{return}}function oa(e,t){return/(https?:\/\/|token|secret|password|authorization|cookie|api[-_]?key)/i.test(e)?e.replaceAll(/https?:\/\/[^\s"'<>)]+/gi,e=>{let n=aa(e);return n?(n.redacted&&t(),n.value):e}):e}function sa(e){let t=!1;for(let n of Array.from(e.searchParams.keys()))na.test(n)&&(e.searchParams.set(n,`[REDACTED]`),t=!0);return t}const X=2048,ca=4096,la=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i;function ua(e){let t=e.redacted===!0;return{kind:`diagnosticsLogs`,entries:e.entries.map(e=>{let n=Q(e.message,ca),r=_a(e.metadata);return t||=n.redacted||r.redacted,{...e.timestamp?{timestamp:e.timestamp}:{},...e.level?{level:e.level}:{},message:n.value??``,...e.source?{source:e.source}:{},...r.value?{metadata:r.value}:{}}}),...e.nextCursor?{nextCursor:e.nextCursor}:{},...e.timeWindow?{timeWindow:e.timeWindow}:{},...e.backend?{backend:e.backend}:{},redacted:t,...e.notes?{notes:e.notes}:{}}}function da(e,t){let n=e.redacted===!0;return{kind:`diagnosticsNetwork`,entries:e.entries.map(e=>{let r=e.url?ma(e.url):void 0,i=t===`headers`||t===`all`?pa(e.requestHeaders):void 0,a=t===`headers`||t===`all`?pa(e.responseHeaders):void 0,o=t===`body`||t===`all`?ha(e.requestBody):void 0,s=t===`body`||t===`all`?ha(e.responseBody):void 0,c=_a(e.metadata);return n||=(r?.redacted??!1)||(i?.redacted??!1)||(a?.redacted??!1)||(o?.redacted??!1)||(s?.redacted??!1)||c.redacted,{...e.timestamp?{timestamp:e.timestamp}:{},...e.method?{method:e.method}:{},...r?{url:r.value}:{},...e.status===void 0?{}:{status:e.status},...e.durationMs===void 0?{}:{durationMs:e.durationMs},...i?.value?{requestHeaders:i.value}:{},...a?.value?{responseHeaders:a.value}:{},...o?.value===void 0?{}:{requestBody:o.value},...s?.value===void 0?{}:{responseBody:s.value},...c.value?{metadata:c.value}:{}}}),...e.nextCursor?{nextCursor:e.nextCursor}:{},...e.timeWindow?{timeWindow:e.timeWindow}:{},...e.backend?{backend:e.backend}:{},redacted:n,...e.notes?{notes:e.notes}:{}}}function fa(e){let t=e.redacted===!0;return{kind:`diagnosticsPerf`,metrics:e.metrics.map(e=>{let n=Q(e.message,ca),r=_a(e.metadata);return t||=n.redacted||r.redacted,{name:e.name,...e.value===void 0?{}:{value:e.value},...e.unit?{unit:e.unit}:{},...e.status?{status:e.status}:{},...n.value===void 0?{}:{message:n.value},...r.value?{metadata:r.value}:{}}}),...e.startedAt?{startedAt:e.startedAt}:{},...e.endedAt?{endedAt:e.endedAt}:{},...e.backend?{backend:e.backend}:{},redacted:t,...e.notes?{notes:e.notes}:{}}}function pa(e){if(!e)return{redacted:!1};let t=!1,n={};for(let[r,i]of Object.entries(e))if(la.test(r))n[r]=`[REDACTED]`,t=!0;else{let e=Q(i,X);n[r]=e.value??``,t||=e.redacted}return{value:n,redacted:t}}function ma(e){return aa(e)??Q(e,X)}function ha(e){return e===void 0?{redacted:!1}:ga(e)??Q(e,X)}function ga(e){try{let t=Z(JSON.parse(e),ia);return va(JSON.stringify(t.value),X,t.redacted)}catch{return}}function _a(e){return Z(e,e=>Q(e,X))}function Z(e,t){if(e===void 0)return{redacted:!1};if(typeof e==`string`)return t(e);if(!e||typeof e!=`object`)return{value:e,redacted:!1};if(Array.isArray(e)){let n=!1;return{value:e.map(e=>{let r=Z(e,t);return n||=r.redacted,r.value}),redacted:n}}let n=!1,r={};for(let[i,a]of Object.entries(e)){if(la.test(i)){r[i]=`[REDACTED]`,n=!0;continue}let e=Z(a,t);r[i]=e.value,n||=e.redacted}return{value:r,redacted:n}}function Q(e,t){if(e===void 0)return{redacted:!1};let n=ia(e);return va(n.value,t,n.redacted)}function va(e,t,n){if(e===void 0)return{redacted:n};let r=e;return r.length>t&&(r=`${r.slice(0,t)}...[truncated]`,n=!0),{value:r,redacted:n}}const ya=async(e,n={})=>{if(!e.backend.readLogs)throw new t(`UNSUPPORTED_OPERATION`,`diagnostics.logs is not supported by this backend`);return ua(await e.backend.readLogs(await Sa(e,n),Ca(n)))},ba=async(e,n={})=>{if(!e.backend.dumpNetwork)throw new t(`UNSUPPORTED_OPERATION`,`diagnostics.network is not supported by this backend`);let r=wa(n);return da(await e.backend.dumpNetwork(await Sa(e,n),r),r.include??`summary`)},xa=async(e,n={})=>{if(!e.backend.measurePerf)throw new t(`UNSUPPORTED_OPERATION`,`diagnostics.perf is not supported by this backend`);return fa(await e.backend.measurePerf(await Sa(e,n),Ta(n)))};async function Sa(e,t){let n=S(e,t),r=t.session?await e.sessions.get(t.session):void 0;return{...n,...t.appId??r?.appId?{appId:t.appId??r?.appId}:{},...t.appBundleId??r?.appBundleId?{appBundleId:t.appBundleId??r?.appBundleId}:{}}}function Ca(e){return{...Ea(e,100,500,`logs limit`),...e.levels===void 0?{}:{levels:ka(e.levels,`levels`)},...e.search===void 0?{}:{search:q(e.search,`search`)},...e.source===void 0?{}:{source:q(e.source,`source`)}}}function wa(e){return{...Ea(e,25,200,`network limit`),include:Oa(e.include)}}function Ta(e){return{...Da(e),...e.sampleMs===void 0?{}:{sampleMs:x(e.sampleMs,`sampleMs`,100,6e4)},...e.metrics===void 0?{}:{metrics:ka(e.metrics,`metrics`,20)}}}function Ea(e,t,n,r){return{...Da(e),...e.cursor===void 0?{}:{cursor:q(e.cursor,`cursor`)},limit:e.limit===void 0?t:x(e.limit,r,1,n)}}function Da(e){return{...e.since===void 0?{}:{since:q(e.since,`since`)},...e.until===void 0?{}:{until:q(e.until,`until`)}}}function Oa(e){if(e===void 0)return`summary`;if(e===`summary`||e===`headers`||e===`body`||e===`all`)return e;throw new t(`INVALID_ARGS`,`network include must be summary, headers, body, or all`)}function ka(e,n,r=50){if(!Array.isArray(e))throw new t(`INVALID_ARGS`,`${n} must be an array of strings`);if(e.length>r)throw new t(`INVALID_ARGS`,`${n} must contain at most ${r} entries`);return e.map((e,t)=>q(e,`${n}[${t}]`))}const Aa={logs:ya,network:ba,perf:xa},ja=async(e,n)=>{let r=Ia(n.action,`record`),i=r===`start`?e.backend.startRecording:e.backend.stopRecording;if(!i)throw new t(`UNSUPPORTED_OPERATION`,`record ${r} is not supported by this backend`);let a=n.out?await F(e,n.out,{field:`path`,ext:`.mp4`,artifactType:`screen-recording`}):void 0;try{let t=Na(n,a?.path);return La(r,await i.call(e.backend,S(e,n),t),await a?.publish())}catch(e){throw await a?.cleanup?.(),e}},Ma=async(e,n)=>{let r=Ia(n.action,`trace`),i=r===`start`?e.backend.startTrace:e.backend.stopTrace;if(!i)throw new t(`UNSUPPORTED_OPERATION`,`trace ${r} is not supported by this backend`);let a=n.out?await F(e,n.out,{field:`outPath`,ext:`.trace`,artifactType:`trace-log`}):void 0;try{let t={...a?.path?{outPath:a.path}:{}};return Ra(r,await i.call(e.backend,S(e,n),t),await a?.publish())}catch(e){throw await a?.cleanup?.(),e}};function Na(e,t){let n={};t&&(n.outPath=t);let r=Pa(e.fps);r!==void 0&&(n.fps=r);let i=Fa(e.quality);return i!==void 0&&(n.quality=i),e.hideTouches!==void 0&&(n.showTouches=e.hideTouches!==!0),n}function Pa(e){return e===void 0?void 0:x(e,`fps`,1,60)}function Fa(e){if(e===void 0)return;let n=Ue(e);if(n===void 0)throw new t(`INVALID_ARGS`,`quality must be one of: medium, high (legacy numeric values 5-10 are accepted)`);return n}function Ia(e,n){if(e===`start`||e===`stop`)return e;throw new t(`INVALID_ARGS`,`${n} action must be start or stop`)}function La(e,t,n){return{...typeof t.path==`string`?{path:t.path}:{},...typeof t.telemetryPath==`string`?{telemetryPath:t.telemetryPath}:{},...typeof t.warning==`string`?{warning:t.warning}:{},...za(e,t,n,{startKind:`recordingStarted`,stopKind:`recordingStopped`,startMessage:`Recording started`,stopMessage:`Recording stopped`})}}function Ra(e,t,n){return{...typeof t.outPath==`string`?{outPath:t.outPath}:{},...za(e,t,n,{startKind:`traceStarted`,stopKind:`traceStopped`,startMessage:`Trace started`,stopMessage:`Trace stopped`})}}function za(e,t,n,r){return{kind:e===`start`?r.startKind:r.stopKind,action:e,...n?{artifact:n}:{},backendResult:t,..._(e===`start`?r.startMessage:r.stopMessage)}}const Ba={record:ja,trace:Ma},Va=async(e,n={})=>{if(!e.backend.pressBack)throw new t(`UNSUPPORTED_OPERATION`,`system.back is not supported by this backend`);let r=n.mode??`in-app`;if(r!==`in-app`&&r!==`system`)throw new t(`INVALID_ARGS`,`system.back mode must be in-app or system`);let i=C(await e.backend.pressBack(S(e,n),{mode:r}));return{kind:`systemBack`,mode:r,...i?{backendResult:i}:{},..._(`Back`)}},Ha=async(e,n={})=>{if(!e.backend.pressHome)throw new t(`UNSUPPORTED_OPERATION`,`system.home is not supported by this backend`);let r=C(await e.backend.pressHome(S(e,n)));return{kind:`systemHome`,...r?{backendResult:r}:{},..._(`Home`)}},Ua=async(e,n)=>{if(!e.backend.pressTvRemote)throw new t(`UNSUPPORTED_OPERATION`,`system.tvRemote is not supported by this backend`);let r=Ge(n.button),i=n.durationMs===void 0?void 0:x(n.durationMs,`durationMs`,0,1e4),a=C(await e.backend.pressTvRemote(S(e,n),{button:r,...i===void 0?{}:{durationMs:i}}));return{kind:`tvRemotePressed`,button:r,...i===void 0?{}:{durationMs:i},...a?{backendResult:a}:{},..._(`Pressed TV remote ${r}`)}},Wa=async(e,n)=>{if(!e.backend.setOrientation)throw new t(`UNSUPPORTED_OPERATION`,`system.orientation is not supported by this backend`);let r=Xa(n.orientation),i=C(await e.backend.setOrientation(S(e,n),r));return{kind:`systemOrientationSet`,orientation:r,...i?{backendResult:i}:{},..._(`Rotated to ${r}`)}},Ga=async(e,n={})=>{if(!e.backend.setKeyboard)throw new t(`UNSUPPORTED_OPERATION`,`system.keyboard is not supported by this backend`);let r=n.action??`status`;if(!Ke(r))throw new t(`INVALID_ARGS`,`system.keyboard action must be status, get, dismiss, enter, or return`);let i=await e.backend.setKeyboard(S(e,n),{action:r}),a=C(i),o=ao(i)?i:{};return r===`enter`||r===`return`?Qa(o,a):r===`dismiss`?$a(r,o,a):to(r,o,a)},Ka=async(e,n)=>{if(n.action===`read`){if(!e.backend.getClipboard)throw new t(`UNSUPPORTED_OPERATION`,`system.clipboard read is not supported by this backend`);let r=await e.backend.getClipboard(S(e,n));return{kind:`clipboardText`,action:`read`,text:typeof r==`string`?r:r.text}}if(n.action!==`write`)throw new t(`INVALID_ARGS`,`system.clipboard action must be read or write`);if(!e.backend.setClipboard)throw new t(`UNSUPPORTED_OPERATION`,`system.clipboard write is not supported by this backend`);if(typeof n.text!=`string`)throw new t(`INVALID_ARGS`,`system.clipboard write requires text`);let r=C(await e.backend.setClipboard(S(e,n),n.text));return{kind:`clipboardUpdated`,action:`write`,textLength:Array.from(n.text).length,...r?{backendResult:r}:{},..._(`Clipboard updated`)}},qa=async(e,n={})=>{if(!e.backend.openSettings)throw new t(`UNSUPPORTED_OPERATION`,`system.settings is not supported by this backend`);let r=K(n.target,`target`),i=C(await e.backend.openSettings(S(e,n),r));return{kind:`settingsOpened`,...r?{target:r}:{},...i?{backendResult:i}:{},..._(r?`Opened settings: ${r}`:`Opened settings`)}},Ja=async(e,n={})=>{if(!e.backend.handleAlert)throw new t(`UNSUPPORTED_OPERATION`,`system.alert is not supported by this backend`);let r=n.action??`get`;if(r!==`get`&&r!==`accept`&&r!==`dismiss`&&r!==`wait`)throw new t(`INVALID_ARGS`,`system.alert action must be get, accept, dismiss, or wait`);let i=n.timeoutMs===void 0?void 0:x(n.timeoutMs,`timeoutMs`,0,12e4);return Za(r,await e.backend.handleAlert(S(e,n),r,{timeoutMs:i}))},Ya=async(e,n={})=>{if(!e.backend.openAppSwitcher)throw new t(`UNSUPPORTED_OPERATION`,`system.appSwitcher is not supported by this backend`);let r=C(await e.backend.openAppSwitcher(S(e,n)));return{kind:`appSwitcherOpened`,...r?{backendResult:r}:{},..._(`Opened app switcher`)}};function Xa(e){switch(e){case`portrait`:case`portrait-upside-down`:case`landscape-left`:case`landscape-right`:return e;default:throw new t(`INVALID_ARGS`,`system.orientation must be portrait, portrait-upside-down, landscape-left, or landscape-right`)}}function Za(e,t){return e===`get`?no(t):e===`wait`?ro(t):io(e,t)}function Qa(e,t){return{kind:`keyboardEnterPressed`,action:`enter`,state:e,...t?{backendResult:t}:{},..._(`Keyboard enter pressed`)}}function $a(e,t,n){return{kind:`keyboardDismissed`,action:e,state:t,...n?{backendResult:n}:{},..._(eo(t))}}function eo(e){return e.dismissed===!1?`Keyboard already hidden`:e.mechanism===`dismissKey`?`Keyboard dismissed via its dismiss key`:`Keyboard dismissed`}function to(e,t,n){return{kind:`keyboardState`,action:e,state:t,...n?{backendResult:n}:{}}}function no(e){if(e.kind!==`alertStatus`)throw new t(`COMMAND_FAILED`,`system.alert get returned an invalid backend result`);return{kind:`alertStatus`,action:`get`,alert:e.alert}}function ro(e){if(e.kind!==`alertWait`)throw new t(`COMMAND_FAILED`,`system.alert wait returned an invalid backend result`);return{kind:`alertWait`,action:`wait`,alert:e.alert,...e.waitedMs===void 0?{}:{waitedMs:e.waitedMs},...e.timedOut===void 0?{}:{timedOut:e.timedOut},..._(e.alert?`Alert visible`:`Alert wait timed out`)}}function io(e,n){if(n.kind!==`alertHandled`)throw new t(`COMMAND_FAILED`,`system.alert ${e} returned an invalid backend result`);return{kind:`alertHandled`,action:e,handled:n.handled,...n.alert?{alert:n.alert}:{},...n.button?{button:n.button}:{},..._(n.handled?`Alert ${e}ed`:`No alert handled`)}}function ao(e){return!!(e&&typeof e==`object`)}const oo={back:Va,home:Ha,orientation:Wa,keyboard:Ga,clipboard:Ka,settings:qa,alert:Ja,appSwitcher:Ya,tvRemote:Ua};function so(e){return{capture:b(kr,e),selectors:xi(e),interactions:Si(e),system:b(oo,e),apps:ta(e),admin:b(ea,e),recording:b(Ba,e),observability:b(Aa,e)}}var co=e({createAgentDevice:()=>lo,createMemorySessionStore:()=>uo,localCommandPolicy:()=>po,restrictedCommandPolicy:()=>mo});function lo(e){let t={backend:e.backend,artifacts:e.artifacts,sessions:e.sessions??uo(),policy:e.policy??mo(),diagnostics:e.diagnostics,clock:e.clock,signal:e.signal};return{...t,...so(t)}}function uo(e=[]){let t=new Map(e.map(e=>[e.name,$(e)]));return{get:e=>$(t.get(e)),set:e=>{t.set(e.name,$(e))},delete:e=>{t.delete(e)},list:()=>Array.from(t.values(),e=>$(e))}}function $(e){if(e)return{...e,...e.snapshot?{snapshot:structuredClone(e.snapshot)}:{},...e.metadata?{metadata:fo(e.metadata)}:{}}}function fo(e){try{return structuredClone(e)}catch{return{...e}}}function po(e={}){return{allowLocalInputPaths:!0,allowLocalOutputPaths:!0,maxImagePixels:2e7,...e}}function mo(e={}){return{allowLocalInputPaths:!1,allowLocalOutputPaths:!1,maxImagePixels:2e7,...e}}export{or as a,dt as c,Tt as d,Ot as f,Mr as i,ft as l,po as n,$n as o,co as r,Kt as s,lo as t,pt as u};
1
+ import{n as e}from"./rolldown-runtime.js";import{_ as t,d as n,g as r,l as i,p as a,u as o,v as s}from"./sdk-contracts.js";import{g as c,k as l,m as u}from"./location-coordinates.js";import{$n as d,En as f,Fn as p,Jn as m,Nr as ee,On as te,Tn as ne,Vt as re,er as ie,gn as h,pn as g,tn as ae,tr as oe,vn as se,xn as ce,xr as le}from"./sdk-batch-runner.js";import{A as ue,B as de,C as fe,D as pe,E as me,F as he,G as ge,H as _e,J as ve,K as ye,L as be,M as xe,N as Se,P as Ce,Q as we,R as _,S as Te,T as Ee,U as De,V as Oe,W as ke,X as v,Y as Ae,_ as je,b as Me,ct as y,dt as b,ft as x,g as Ne,gt as S,j as Pe,lt as C,nt as Fe,q as Ie,tt as Le,ut as Re,v as ze,w as Be,x as Ve,y as He,yn as w,z as Ue}from"./script-source-bundle.js";import{r as We}from"./recording-export-quality.js";import{_ as Ge,i as Ke,t as T}from"./interaction.js";import{M as qe}from"./screenshot-result.js";import{t as Je}from"./mobile-snapshot-semantics.js";import{t as Ye}from"./verdict.js";import{f as Xe,p as Ze}from"./device.js";import{a as Qe}from"./png-worker-contract.js";import{a as $e,i as et,n as tt,o as nt}from"./png-resize.js";import rt from"node:path";import{promises as E}from"node:fs";const it=/\b(logbox|redbox|reload js|copy stack|component stack|call stack|runtime error|open debugger to view warnings)\b/,at=[/\b[\w.$<>/-]+\.(?:tsx?|jsx?):\d+(?::\d+)?\b/,/\b[\w.$<>/-]+\.(?:tsx?|jsx?)\s+\(\d+:\d+\)/],ot=[/^!,\s+/,/^(warn|warning|error):\s+/,/\b(?:possible\s+)?unhandled (?:promise )?rejection\b/],st=[`open debugger to view warnings`,`getsnapshot should be cached to avoid an infinite loop`,`unique "key" prop`,`unique 'key' prop`,`virtualizedlists should never be nested`,`failed prop type`],ct=new Set([`x`,`×`,`✕`,`✖`,`⨯`]);function lt(e){if(ut(e).detected)return[`Hint: React Native warning/error overlay detected. It overlays part of the app and should be handled before interacting.`,`Run: agent-device react-native dismiss-overlay`,`The command verifies the overlay is gone. Run agent-device snapshot -i afterward only when you need fresh refs for the next action.`].join(`
2
+ `)}function ut(e){let t=pt(e),n=t.detected?mt(t):null;return{detected:t.detected,dismissNodes:t.dismissNodes,minimizeNodes:t.minimizeNodes,collapsedNodes:t.collapsedNodes,primaryAction:n}}function dt(e){return xt(e.label?.trim())&&At(e.rect)}function ft(e,t){let n=e.label?.trim();return!n||!dt(e)?!1:t.some(e=>e.label?.trim()===n&&jt(e))}function pt(e){let t=e.map(ht).join(`
3
+ `).toLowerCase(),n=O(e,Ct),r=O(e,Et),i=O(e,xt,Ot),a=O(e,St),o=_t(t),s=vt(t);return{dismissNodes:n,minimizeNodes:r,collapsedNodes:i,detected:bt({text:t,hasReactNativeStackFrame:o,hasOverlayControl:yt(t,n,r),hasControllessRedBoxText:s,collapsedNodes:i,openDebuggerWarningNodes:a})}}function mt(e){let t=Mt(e.dismissNodes);if(t)return Ft(t,It(t));let n=Lt(e.collapsedNodes.filter(kt));return n?.rect?{action:`close-collapsed-banner`,point:Ht(n),rect:n.rect,ref:n.ref,label:k(n)}:null}function ht(e){return[e.label,e.value,e.identifier,e.type,e.role].filter(Boolean).join(` `)}function gt(e){return it.test(e)}function _t(e){return at.some(t=>t.test(e))}function vt(e){return/\buncaught\b/.test(e)&&/unable to download asset/.test(e)}function yt(e,t,n){return t.length>0||n.length>0||/\b(reload js|copy stack)\b/.test(e)}function bt(e){return e.collapsedNodes.length>0||e.openDebuggerWarningNodes.length>0||e.hasControllessRedBoxText||e.hasOverlayControl&&(gt(e.text)||e.hasReactNativeStackFrame)}function xt(e){let t=e?.trim().toLowerCase();return t?st.some(e=>t.includes(e))||ot.some(e=>e.test(t)):!1}function St(e){return e.includes(`open debugger to view warnings`)||/^!,\s+open debugger\b/.test(e)}function Ct(e){return D(e)||wt(e)||Tt(e)}function D(e){return/^dismiss(?:\s*\([^)]*\))?$/i.test(e)}function wt(e){return/^close(?:\s*\([^)]*\))?$/i.test(e)}function Tt(e){return ct.has(e)}function Et(e){return/^minimi[sz]e(?:\b|\s|\()/i.test(e)}function Dt(e){return/^!,\s+/.test(e)}function Ot(e){return!e.rect||e.rect.height<=180}function kt(e){let t=k(e)?.trim().toLowerCase()??``;return(St(t)||Dt(t))&&jt(e)}function At(e){return e?e.x<=1&&e.y<=1&&e.width>=300&&e.height>=600:!1}function jt(e){return e.rect?e.rect.width>=120&&e.rect.height>=36&&e.rect.height<=180:!1}function O(e,t,n=()=>!0){let r=[];for(let i of e)i.ref&&n(i)&&[i.label,i.value,i.identifier].map(e=>e?.trim().toLowerCase()).filter(e=>!!e).some(e=>t(e))&&r.push(i);return r}function Mt(e){return Rt(e,Pt)}function Nt(e){let t=[e.type,e.role,e.subrole].join(` `).toLowerCase();return/\b(button|menuitem|link)\b/.test(t)}function Pt(e){return[Bt(Nt(e)),Bt(e.hittable),-(e.rect?ee(e.rect):1/0)]}function Ft(e,t){if(!e.rect)throw Error(`React Native overlay target node must have rect`);return{action:t,point:o(e.rect),rect:e.rect,ref:e.ref,label:k(e)}}function It(e){let t=k(e)?.trim().toLowerCase();return t&&D(t)?`dismiss`:`close`}function Lt(e){return Rt(e,zt)}function Rt(e,t){let n=e.filter(e=>e.rect);return n.length===0?null:n.sort((e,n)=>Vt(t(n),t(e)))[0]??null}function zt(e){return[Bt(e.hittable),e.rect?.width??0,e.rect?.y??0]}function Bt(e){return+(e===!0)}function Vt(e,t){for(let n=0;n<e.length;n+=1){let r=e[n]-t[n];if(r!==0)return r}return 0}function Ht(e){if(!e.rect)throw Error(`Collapsed React Native warning node must have rect`);let t=Math.min(e.rect.height,52),n=Math.min(36,Math.max(18,t*.45));return{x:Math.round(Ut(e.rect.x+e.rect.width-n,e.rect.x+1,e.rect.x+e.rect.width-1)),y:Math.round(e.rect.y+t/2)}}function Ut(e,t,n){return Math.min(n,Math.max(t,e))}function k(e){return e.label??e.value??e.identifier}function Wt(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}const A=[0,187,255,255];function Gt(e,t){for(let n of t)n.rect.width<4||n.rect.height<4||Kt(e,n.rect)}function Kt(e,t){let n=qt(t);if(n==null)return;let r=M(n.x,0,e.width-1),i=M(n.y,0,e.height-1),a=M(n.right,0,e.width-1),o=M(n.bottom,0,e.height-1);for(let t=0;t<2;t+=1){for(let n=r;n<=a;n+=1)j(e,n,i+t,A),j(e,n,o-t,A);for(let n=i;n<=o;n+=1)j(e,r+t,n,A),j(e,a-t,n,A)}}function qt(e){let t=e.x+e.width-1,n=e.y+e.height-1;return[e.x,e.y,e.width,e.height,t,n].every(Number.isFinite)?{x:e.x,y:e.y,right:t,bottom:n}:null}function j(e,t,n,r){if(t<0||t>=e.width||n<0||n>=e.height)return;let i=(n*e.width+t)*4;e.data[i]=r[0],e.data[i+1]=r[1],e.data[i+2]=r[2],e.data[i+3]=r[3]}function M(e,t,n){return Number.isFinite(e)?Math.min(Math.max(e,t),n):t}const Jt=[{x:-1,y:-1},{x:0,y:-1},{x:1,y:-1},{x:-1,y:0},{x:1,y:0},{x:-1,y:1},{x:0,y:1},{x:1,y:1}];function Yt(e){let{mask:t,width:n,height:r,hooks:i}=e,a=new Uint8Array(t.length),o=new Int32Array(t.length),s=[];for(let e=0;e<t.length;e+=1){if(!Qt(t,a,e))continue;let c=0,l=Zt(o,a,0,e),u=i.create(e);for(;c<l;){let e=o[c];c+=1,i.visit(u,e),l=Xt({mask:t,visited:a,queue:o,queueEnd:l,width:n,height:r,pixelIndex:e})}s.push(u)}return s}function Xt(e){let{mask:t,visited:n,queue:r,width:i,height:a,pixelIndex:o}=e,s=o%i,c=Math.floor(o/i),l=e.queueEnd;for(let e of Jt){let o=s+e.x,u=c+e.y;if(!$t(o,u,i,a))continue;let d=u*i+o;Qt(t,n,d)&&(l=Zt(r,n,l,d))}return l}function Zt(e,t,n,r){return t[r]=1,e[n]=r,n+1}function Qt(e,t,n){return e[n]===1&&t[n]!==1}function $t(e,t,n,r){return e>=0&&e<n&&t>=0&&t<r}function en(e,t){return e.flatMap(e=>tn(e,t.baseline.width,t.baseline.height)?nn(e,t,ln(t.baseline.height)):[e])}function tn(e,t,n){let r=e.maxX-e.minX+1;return e.maxY-e.minY+1>=cn(n)&&r>=t*.35}function nn(e,t,n){let r=sn(e,on(an(rn(e,t.diffMask,t.baseline.width)),Math.max(1,Math.round((e.maxX-e.minX+1)*.08))),n);if(r.length<=1)return[e];let i=r.map(([n,r])=>un(e,n,r,t)).filter(e=>e!==null);return i.length>1?i:[e]}function rn(e,t,n){let r=[];for(let i=e.minY;i<=e.maxY;i+=1){let a=0;for(let r=e.minX;r<=e.maxX;r+=1)t[i*n+r]===1&&(a+=1);r.push(a)}return r}function an(e){return e.map((t,n)=>{let r=0,i=0,a=Math.max(0,n-3),o=Math.min(e.length-1,n+3);for(let t=a;t<=o;t+=1)r+=e[t],i+=1;return Math.round(r/i)})}function on(e,t){let n=[],r=null;for(let i=0;i<e.length;i+=1){if(e[i]<=t){r??=i;continue}r!==null&&(i-r>=6&&n.push([r,i-1]),r=null)}return r!==null&&e.length-r>=6&&n.push([r,e.length-1]),n}function sn(e,t,n){let r=[],i=e.minY;for(let[a,o]of t){let t=e.minY+Math.round((a+o)/2);t-i+1<n||e.maxY-t<n||(r.push([i,t]),i=t+1)}return r.push([i,e.maxY]),r}function cn(e){return Math.max(48,Math.round(e*.07))}function ln(e){return Math.max(24,Math.round(e*.03))}function un(e,t,n,r){let i=null;for(let a=t;a<=n;a+=1)for(let t=e.minX;t<=e.maxX;t+=1){let e=a*r.baseline.width+t;r.diffMask[e]===1&&(i??=dn(t,a),fn(i,e,t,a,r.baseline,r.current))}return i}function dn(e,t){return{minX:e,minY:t,maxX:e,maxY:t,differentPixels:0,baselineRed:0,baselineGreen:0,baselineBlue:0,currentRed:0,currentGreen:0,currentBlue:0}}function fn(e,t,n,r,i,a){let o=t*4;e.minX=Math.min(e.minX,n),e.minY=Math.min(e.minY,r),e.maxX=Math.max(e.maxX,n),e.maxY=Math.max(e.maxY,r),e.differentPixels+=1,e.baselineRed+=i.data[o],e.baselineGreen+=i.data[o+1],e.baselineBlue+=i.data[o+2],e.currentRed+=a.data[o],e.currentGreen+=a.data[o+1],e.currentBlue+=a.data[o+2]}const pn=2.5;function mn(e){let t=hn(e);return en(t.length<=2e3?vn(t,12):t,e).sort((e,t)=>{let n=t.differentPixels-e.differentPixels;if(n!==0)return n;let r=e.minY-t.minY;return r===0?e.minX-t.minX:r}).slice(0,8).map((t,n)=>xn(t,n+1,{width:e.baseline.width,height:e.baseline.height,totalPixels:e.totalPixels,differentPixels:e.differentPixels}))}function hn(e){let{diffMask:t,baseline:n,current:r}=e,{width:i,height:a}=n;return Yt({mask:t,width:i,height:a,hooks:{create:e=>gn(e,i),visit:(e,t)=>_n(e,t,i,n,r)}})}function gn(e,t){let n=e%t,r=Math.floor(e/t);return{minX:n,minY:r,maxX:n,maxY:r,differentPixels:0,baselineRed:0,baselineGreen:0,baselineBlue:0,currentRed:0,currentGreen:0,currentBlue:0}}function _n(e,t,n,r,i){let a=t%n,o=Math.floor(t/n),s=t*4;e.minX=Math.min(e.minX,a),e.minY=Math.min(e.minY,o),e.maxX=Math.max(e.maxX,a),e.maxY=Math.max(e.maxY,o),e.differentPixels+=1,e.baselineRed+=r.data[s],e.baselineGreen+=r.data[s+1],e.baselineBlue+=r.data[s+2],e.currentRed+=i.data[s],e.currentGreen+=i.data[s+1],e.currentBlue+=i.data[s+2]}function vn(e,t){let n=[];for(let r of e.sort((e,t)=>{let n=e.minY-t.minY;return n===0?e.minX-t.minX:n})){let e=n.find(e=>yn(e,r,t));if(!e){n.push({...r});continue}bn(e,r)}return n}function yn(e,t,n){return e.minX-n<=t.maxX&&t.minX-n<=e.maxX&&e.minY-n<=t.maxY&&t.minY-n<=e.maxY}function bn(e,t){e.minX=Math.min(e.minX,t.minX),e.minY=Math.min(e.minY,t.minY),e.maxX=Math.max(e.maxX,t.maxX),e.maxY=Math.max(e.maxY,t.maxY),e.differentPixels+=t.differentPixels,e.baselineRed+=t.baselineRed,e.baselineGreen+=t.baselineGreen,e.baselineBlue+=t.baselineBlue,e.currentRed+=t.currentRed,e.currentGreen+=t.currentGreen,e.currentBlue+=t.currentBlue}function xn(e,t,n){let r={x:e.minX,y:e.minY,width:e.maxX-e.minX+1,height:e.maxY-e.minY+1},i={x:Math.round(e.minX+r.width/2),y:Math.round(e.minY+r.height/2)},a=Sn(e.baselineRed,e.baselineGreen,e.baselineBlue,e.differentPixels),o=Sn(e.currentRed,e.currentGreen,e.currentBlue,e.differentPixels),s=r.width*r.height;return{index:t,rect:r,normalizedRect:Fe({x:F(r.x/n.width),y:F(r.y/n.height),width:F(r.width/n.width),height:F(r.height/n.height)}),differentPixels:e.differentPixels,shareOfDiffPercentage:F(e.differentPixels/n.differentPixels),densityPercentage:F(e.differentPixels/s),shape:Tn(r,n.width,n.height),size:En(s,n.totalPixels),location:Cn(i,n.width,n.height),averageBaselineColorHex:Dn(a),averageCurrentColorHex:Dn(o),baselineLuminance:Math.round(N(a)),currentLuminance:Math.round(N(o)),dominantChange:wn(a,o)}}function Sn(e,t,n,r){return{r:Math.round(e/r),g:Math.round(t/r),b:Math.round(n/r)}}function Cn(e,t,n){let r=e.x<t/3?`left`:e.x>t*2/3?`right`:`center`,i=e.y<n/3?`top`:e.y>n*2/3?`bottom`:`middle`;return r===`center`&&i===`middle`?`center`:`${i}-${r}`}function wn(e,t){let n=N(t)-N(e);return Math.abs(n)>=12?n>0?`brighter`:`darker`:Math.max(Math.abs(t.r-e.r),Math.abs(t.g-e.g),Math.abs(t.b-e.b))>=12?`color-shift`:`mixed`}function Tn(e,t,n){return e.width>=t*.55&&e.height>=n*.12?`large-area`:e.width>=e.height*pn?`horizontal-band`:e.height>=e.width*pn?`vertical-band`:`compact`}function En(e,t){let n=e/t;return n>=.04?`large`:n>=.01?`medium`:`small`}function N(e){return e.r*.2126+e.g*.7152+e.b*.0722}function Dn(e){return`#${P(e.r)}${P(e.g)}${P(e.b)}`}function P(e){return e.toString(16).padStart(2,`0`)}function F(e){return Math.round(e*100*100)/100}const On=255*Math.sqrt(3);async function kn(e,t,n={}){await An(e,`Baseline image not found`),await An(t,`Current screenshot not found`);let r=n.outputPath,[i,a]=await Promise.all([E.readFile(e),E.readFile(t)]),[o,s]=await Promise.all([$e(i,`baseline screenshot`),$e(a,`current screenshot`)]);jn(o.width,o.height,`baseline screenshot`,n.maxPixels),jn(s.width,s.height,`current screenshot`,n.maxPixels);let c=n.threshold??.1;if(o.width!==s.width||o.height!==s.height){let e=o.width*o.height;return await Mn(n.outputPath),{match:!1,mismatchPercentage:100,totalPixels:e,differentPixels:e,dimensionMismatch:{expected:{width:o.width,height:o.height},actual:{width:s.width,height:s.height}}}}let l=o.width*o.height,u=c*On,{diffData:d,diffMask:f,differentPixels:p}=await et({baselineData:o.data,currentData:s.data,width:o.width,height:o.height,maxColorDistance:u}),m=p>0?mn({diffMask:f,baseline:o,current:s,totalPixels:l,differentPixels:p}):[];if(p>0&&r){let e=new Qe.PNG({width:o.width,height:o.height});e.data=d,Gt(e,m),await E.mkdir(rt.dirname(r),{recursive:!0}),await E.writeFile(r,await nt(e))}else await Mn(n.outputPath);let ee=l>0?Math.round(p/l*100*100)/100:0;return{...p>0&&r?{diffPath:r}:{},...m.length>0?{regions:m}:{},totalPixels:l,differentPixels:p,mismatchPercentage:ee,match:p===0}}async function An(e,n){try{await E.access(e)}catch{throw new t(`INVALID_ARGS`,`${n}: ${e}`)}}function jn(e,n,r,i){if(i==null||i<=0)return;let a=e*n;if(!(a<=i))throw new t(`INVALID_ARGS`,`${r} is ${a} pixels, which exceeds the configured maxImagePixels limit of ${i}`)}async function Mn(e){if(e)try{await E.unlink(e)}catch(e){if(!Nn(e,`ENOENT`))throw e}}function Nn(e,t){return typeof e==`object`&&!!e&&`code`in e&&e.code===t}function Pn(e,t){return e.map(e=>{let n=Fn(e,t);return n.length>0?{...e,currentOverlayMatches:n}:e})}function Fn(e,t){let n=In(e.rect);return t.map(t=>{let r=t.overlayRect,i=Le(e.rect,r);return i<=0?null:{ref:t.ref,...t.label?{label:t.label}:{},rect:r,overlayCoveragePercentage:Ln(i/In(r)),regionCoveragePercentage:Ln(i/n)}}).filter(e=>e!==null).sort((e,t)=>{let n=t.regionCoveragePercentage-e.regionCoveragePercentage;return n===0?t.overlayCoveragePercentage-e.overlayCoveragePercentage:n}).slice(0,3).map(e=>({ref:e.ref,...e.label?{label:e.label}:{},rect:e.rect,regionCoveragePercentage:e.regionCoveragePercentage}))}function In(e){return e.width*e.height}function Ln(e){return Math.round(e*100*100)/100}async function I(e,n,r){if(n.kind===`path`&&!e.policy.allowLocalInputPaths)throw new t(`INVALID_ARGS`,`Local ${r.field??`input`} paths are not allowed by command policy`);try{return await e.artifacts.resolveInput(n,r)}catch(e){throw s(e)}}async function L(e,n,r){if(n?.kind===`path`&&!e.policy.allowLocalOutputPaths)throw new t(`INVALID_ARGS`,`Local output paths are not allowed by command policy`);try{return await e.artifacts.reserveOutput(n,{...r,visibility:r.visibility??`client-visible`,requestedClientPath:n?.kind===`downloadableArtifact`?n.clientPath??r.requestedClientPath:r.requestedClientPath})}catch(e){throw s(e)}}async function Rn(e,t){try{return await e.artifacts.createTempFile(t)}catch(e){throw s(e)}}const zn=async(e,n)=>{if(!n.baseline)throw new t(`INVALID_ARGS`,`diff screenshot requires a baseline image`);let r=Bn(n.threshold),i=n.current??{kind:`live`};if(n.overlayRefs&&!qn(i))throw new t(`INVALID_ARGS`,`diff screenshot <current.png> cannot use --overlay-refs because saved-image comparisons have no live accessibility refs`);let a=await I(e,n.baseline,{usage:`diff screenshot baseline`,field:`baseline`}),o,s,c,l=[];try{let t;qn(i)?(s=await Vn(e,n),t=s.path):(o=await I(e,i,{usage:`diff screenshot current`,field:`current`}),t=o.path),c=n.out?await L(e,n.out,{field:`diffPath`,ext:`.png`,artifactType:`screenshot-diff`}):void 0;let u=await kn(a.path,t,{threshold:r,outputPath:c?.path,maxPixels:e.policy.maxImagePixels});qn(i)&&(u=await Hn(e,n,c?.path,u,l));let d=u.diffPath?await c?.publish():void 0;return d&&l.push(d),u.diffPath||await c?.cleanup?.(),{...u,...l.length>0?{artifacts:l}:{}}}catch(e){throw await c?.cleanup?.(),e}finally{await a.cleanup?.(),await o?.cleanup?.(),await s?.cleanup?.()}};function Bn(e){if(e==null||e===``)return .1;let n=Number(e);if(Number.isNaN(n)||n<0||n>1)throw new t(`INVALID_ARGS`,`--threshold must be a number between 0 and 1`);return n}async function Vn(e,t){let n=await Rn(e,{prefix:`agent-device-diff-current`,ext:`.png`});try{await Un(e,t,n.path,Wn(t))}catch(e){throw await n.cleanup(),e}return n}async function Hn(e,t,n,r,i){if(!t.overlayRefs)return r;if(r.match||r.dimensionMismatch)return n&&await Kn(n),r;let a=await L(e,Gn(t,n),{field:`currentOverlayPath`,ext:`.png`,artifactType:`screenshot`});try{let n=await Un(e,t,a.path,{overlayRefs:!0,...Wn(t)}),o=await a.publish();return o&&i.push(o),{...r,currentOverlayPath:n.path??a.path,...n.overlayRefs?{currentOverlayRefCount:n.overlayRefs.length}:{},...r.regions&&n.overlayRefs?{regions:Pn(r.regions,n.overlayRefs)}:{}}}catch(e){throw await a.cleanup?.(),e}}async function Un(e,n,r,i={}){if(!e.backend.captureScreenshot)throw new t(`UNSUPPORTED_OPERATION`,`screenshot is not supported by this backend`);return await e.backend.captureScreenshot({session:n.session,requestId:n.requestId,signal:n.signal??e.signal,metadata:n.metadata},r,i)??{}}function Wn(e){return{normalizeStatusBar:e.normalizeStatusBar??!0,...e.surface?{surface:e.surface}:{}}}function Gn(e,t){if(e.currentOverlayOut)return e.currentOverlayOut;if(e.out?.kind===`path`)return{kind:`path`,path:R(t??e.out.path)};if(e.out?.kind===`downloadableArtifact`)return{kind:`downloadableArtifact`,...e.out.clientPath?{clientPath:R(e.out.clientPath)}:{},...e.out.fileName?{fileName:R(e.out.fileName)}:{}}}function R(e){let t=rt.extname(e);return`${t?e.slice(0,-t.length):e}.current-overlay${t||`.png`}`}async function Kn(e){try{await E.unlink(R(e))}catch(e){if(!Jn(e,`ENOENT`))throw e}}function qn(e){return e.kind===`live`}function Jn(e,t){return typeof e==`object`&&!!e&&`code`in e&&e.code===t}const Yn=async(e,n)=>{if(!e.backend.captureScreenshot)throw new t(`UNSUPPORTED_OPERATION`,`screenshot is not supported by this backend`);l(n);let r=await L(e,n.out,{field:`path`,ext:`.png`,artifactType:`screenshot`}),i;try{await e.backend.captureScreenshot({session:n.session,requestId:n.requestId,appId:n.appId,appBundleId:n.appBundleId,signal:n.signal??e.signal,metadata:n.metadata},r.path,{fullscreen:n.fullscreen,overlayRefs:n.overlayRefs,pixelDensity:n.pixelDensity,stabilize:n.stabilize,normalizeStatusBar:n.normalizeStatusBar,surface:n.surface}),n.scale!==void 0&&await tt(r.path,n.scale),i=await r.publish()}catch(e){throw await r.cleanup?.(),e}return{path:r.path,...i?{artifacts:[i]}:{},...w(`Saved screenshot: ${r.path}`)}};function Xn(e,t){return[...$n(e),...Zn(e),...tr(e),...nr(e,t)]}function Zn(e){let t=e.customActions;if(!t)return[];let n=[];return t.blocked?n.push(`Custom actions were not read: an earlier accessibility read is still hung, so this capture skipped the read pass instead of queueing behind it. No element’s actions list is authoritative here. Reads resume once that call returns.`):t.read<t.candidates&&n.push(`Custom actions were read for ${t.read} of ${t.candidates} merged elements, on-screen ones first; the remaining ${t.candidates-t.read} were not read, so an absent actions list on those is not evidence that they have none. Scroll them into view and re-run to read them.`),t.truncated>0&&n.push(`${t.truncated} element(s) published more custom actions than are shown; those lists are clipped to the first 8 names, and long names are shortened.`),n}function Qn(e){return`Detected an overly complex or slow accessibility tree. Fell back to the ${e} snapshot backend. It is OK to continue; use --json to inspect snapshotQuality.reason if you need recovery details.`}function $n(e){return e.state===`recovered`?e.reasonCode===`deferred`||e.reasonCode===`requested-backend`?[]:[Qn(e.backend)]:e.state===`sparse`?[`No snapshot backend could read this screen`+(e.reason?` (${e.reason})`:``)+`. Its refs and selectors are invalid. Use screenshot as visual truth and coordinate taps; retry snapshot after navigating.`,...er(e)]:[]}function er(e){return e.reasonCode===`sparse-tree`?[`This screen publishes no accessibility content at all; assistive technologies see the same empty tree, so it is worth flagging as an app accessibility bug rather than only an automation limitation.`]:[]}function tr(e){return e.effectiveDepth===void 0?[]:[`Some deeper accessibility nodes were omitted; this tree is capped at depth ${e.effectiveDepth}. Re-run with --depth ${e.effectiveDepth} --scope <container> only if you need deeper content.`]}function nr(e,t){let n=[];for(let r of e.collapsedLeafIndexes??[]){let e=t.find(e=>e.index===r);if(!e)continue;let i=e.identifier?` (${e.identifier})`:``;n.push(`@${e.ref} [${e.type??`element`}]${i} merges many labels into a single accessibility element. The app likely marks a container as accessible, which hides every descendant from assistive tech and automation — the children cannot be addressed individually. Fix the app's accessibility (mark the rows, not the container); until then use screenshot as visual truth and coordinate taps.`)}return n}function rr(e){let{nodes:t,backend:n,snapshotRaw:i}=e;if(i||!r(n))return{partial:!1,visibleNodeCount:t.length,totalNodeCount:t.length,reasons:[]};let a=Je(t),o=new Set;return a.hiddenCount>0&&o.add(`offscreen-nodes`),a.nodes.some(e=>e.hiddenContentAbove)&&o.add(`scroll-hidden-above`),a.nodes.some(e=>e.hiddenContentBelow)&&o.add(`scroll-hidden-below`),{partial:o.size>0,visibleNodeCount:a.nodes.length,totalNodeCount:t.length,reasons:[...o]}}const ir=`A system surface (notification shade, quick settings, or another system overlay) covers the app, so this snapshot shows that surface. Interact with it or dismiss it (press back or swipe up) to reach app content.`;function ar(e){return e?.systemSurfaceOnly===!0?ir:void 0}function or(e,t){return e.presentationKey?e:{...e,presentationKey:i(t)}}function sr(e){let{previous:t,current:n,options:r,identity:i}=e;if(r.forceFull===!0||r.raw===!0||!t||t.comparisonSafe===!1||n.comparisonSafe===!1||!cr(t,n,i)||!t.presentationKey||t.presentationKey!==n.presentationKey||!lr(t,n))return;let a=r.scope?.trim();return{ageMs:Math.max(0,n.createdAt-t.createdAt),nodeCount:n.nodes.length,...r.interactiveOnly===!0?{interactiveOnly:!0}:{},...a?{scope:a}:{}}}function cr(e,t,n){return!(e.backend&&t.backend&&e.backend!==t.backend||n?.previousAppBundleId&&n.currentAppBundleId&&n.previousAppBundleId!==n.currentAppBundleId)}function lr(e,t){return e.truncated===t.truncated?JSON.stringify(ur(e.nodes))===JSON.stringify(ur(t.nodes)):!1}function ur(e){return e.map(e=>({index:e.index,depth:e.depth,parentIndex:e.parentIndex,type:e.type,role:e.role,subrole:e.subrole,label:e.label,value:e.value,identifier:e.identifier,enabled:e.enabled,selected:e.selected,focused:e.focused,hittable:e.hittable,rect:e.rect,bundleId:e.bundleId,appName:e.appName,windowTitle:e.windowTitle,surface:e.surface,hiddenContentAbove:e.hiddenContentAbove,hiddenContentBelow:e.hiddenContentBelow,interactionBlocked:e.interactionBlocked,presentationHints:e.presentationHints,actions:e.actions}))}const dr=async(e,t)=>{let n=await pr(e,t),r=sr({previous:n.session?.snapshot,current:n.snapshot,options:t,identity:{previousAppBundleId:n.session?.appBundleId,currentAppBundleId:n.result.appBundleId??n.session?.appBundleId}});return await e.sessions.set(hr(t.session,n)),{nodes:n.snapshot.nodes,truncated:n.snapshot.truncated??!1,visibility:rr({nodes:n.snapshot.nodes,backend:n.snapshot.backend,snapshotRaw:t.raw}),...u({...n.annotations,warnings:n.warnings}),...r?{unchanged:r}:{},...n.result.snapshotDiagnostics?{snapshotDiagnostics:n.result.snapshotDiagnostics}:{},...gr(n)}},fr=async(e,t)=>{let n=await pr(e,t),r=t.interactiveOnly===!0,i=n.session?.snapshot,a=hr(t.session,n);if(!i){let t=Pe(n.snapshot.nodes,{flatten:r});return await e.sessions.set(a),{mode:`snapshot`,baselineInitialized:!0,summary:{additions:0,removals:0,unchanged:t},lines:[],...n.warnings.length>0?{warnings:n.warnings}:{}}}let o=ue(i.nodes,n.snapshot.nodes,{flatten:r});return await e.sessions.set(a),{mode:`snapshot`,baselineInitialized:!1,summary:o.summary,lines:o.lines,...n.warnings.length>0?{warnings:n.warnings}:{}}};async function pr(e,n){if(!e.backend.captureSnapshot)throw new t(`UNSUPPORTED_OPERATION`,`snapshot is not supported by this backend`);let r=n.session??`default`,i=await e.sessions.get(r),a=await e.backend.captureSnapshot({session:r,requestId:n.requestId,appId:i?.appId,appBundleId:i?.appBundleId,signal:n.signal??e.signal,metadata:n.metadata},{interactiveOnly:n.interactiveOnly,depth:n.depth,scope:n.scope,raw:n.raw,customActions:n.customActions}),o=or(mr(a,e),n),s=c(a),l=Re(e);return{snapshot:o,result:a,session:i,annotations:s,warnings:_r({result:a,annotations:s,snapshot:o,options:n,session:i,capturedAt:o.createdAt??l,runtimeNow:l})}}function mr(e,t){return e.snapshot?e.snapshot:{nodes:e.nodes??[],truncated:e.truncated,backend:e.backend,createdAt:Re(t)}}function hr(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 gr(e){let t=e.result.appName??e.session?.appName,n=e.result.appBundleId??e.session?.appBundleId;return{...t||n?{appName:t??n}:{},...n?{appBundleId:n}:{}}}function _r(e){let t=[...e.annotations.warnings??[]];e.annotations.quality&&t.push(...Xn(e.annotations.quality,e.snapshot.nodes)),t.push(...xr(e)),e.annotations.quality||(t.push(...yr(e)),t.push(...br(e.snapshot.nodes)));let n=lt(e.snapshot.nodes);n&&t.push(n);let r=vr(e.annotations);r&&t.push(r);let i=Sr(e);return i&&t.push(i),t.push(...Er(e.annotations.freshness,e.snapshot.backend)),Array.from(new Set(t))}function vr(e){if(e.androidSnapshot?.systemSurfaceOnly===!0)return ir}function yr(e){return e.snapshot.backend!==`xctest`||e.options.interactiveOnly!==!0||e.snapshot.nodes.length!==1||e.snapshot.nodes[0]?.type!==`Application`?[]:[`iOS interactive snapshot exposed only the application root. XCTest accessibility queries can fail to enumerate some simulator UI trees even when screenshots and direct gestures still work. Use screenshot as visual truth, try a scoped/full snapshot for diagnostics, and prefer direct selectors when known.`]}function br(e){let t=new Set(e.map(e=>e.parentIndex).filter(e=>e!==void 0));return e.filter(e=>t.has(e.index)||(e.type?.toLowerCase()??``).includes(`text`)?!1:(e.label??``).split(`, `).length>10).map(e=>{let t=(e.label??``).split(`, `).length,n=e.identifier?` (${e.identifier})`:``;return`@${e.ref} [${e.type??`element`}]${n} merges ~${t} labels into a single accessibility element. The app likely marks a container as accessible, which hides every descendant from assistive tech and automation — the children cannot be addressed individually. Fix the app's accessibility (mark the rows, not the container); until then use screenshot as visual truth and coordinate taps.`})}function xr(e){let t=e.annotations.analysis;if(e.snapshot.backend!==`android`||e.options.interactiveOnly!==!0||e.snapshot.nodes.length>0||!t||(t.rawNodeCount??0)<12)return[];let n=[`Interactive snapshot is empty after filtering ${t.rawNodeCount} raw Android nodes. Likely causes: the app content is not accessibility-visible yet, a transient route change, or depth/filter options hid the target.`];return typeof e.options.depth==`number`&&typeof t.maxDepth==`number`&&t.maxDepth>=e.options.depth+2&&n.push(`Interactive output is empty at depth ${e.options.depth}; retry without -d.`),n}function Sr(e){let t=e.session?.snapshot;if(!e.annotations.freshness&&t&&Cr(t,e.snapshot)&&wr(t,e.capturedAt,e.runtimeNow)&&Dr(t.nodes.length,e.snapshot.nodes.length))return Tr}function Cr(e,t){return e.presentationKey===void 0||t.presentationKey===void 0?!0:e.presentationKey===t.presentationKey}function wr(e,t,n){return[t,n].some(t=>{let n=t-e.createdAt;return n>=0&&n<=2e3})}const Tr=`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.`;function Er(e,t){return!e?.staleAfterRetries||t!==`android`?[]:e.reason===`stuck-route`?[`Recent ${e.action} was followed by a nearly identical snapshot after ${e.retryCount} automatic retr${e.retryCount===1?`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.`]:e.reason===`sharp-drop`?[Tr]:[]}function Dr(e,t){return e<12?!1:t<=Math.floor(e*.2)}const Or={screenshot:Yn,diffScreenshot:zn,snapshot:dr,diffSnapshot:fr},kr=new WeakMap;function Ar(e,t){Mr(e)&&kr.set(e,t)}function jr(e){return Mr(e)?kr.get(e):void 0}function Mr(e){return typeof e==`object`&&!!e||typeof e==`function`}const Nr=async(e,t)=>await Lr(e,t,`press`),Pr=async(e,t)=>await Lr(e,t,`click`),Fr=async(e,n)=>{if(!n.text)throw new t(`INVALID_ARGS`,`fill requires text`);let r=fe(n),i=r.needsPreActionBaseline?null:await Br(e,n);if(i)return i;let a=await he(e,n,{action:`fill`,requireInteractive:!0,pipeline:S.resolvedTarget,captureEvidenceBaseline:r.needsPreActionBaseline,expectedResolvedTarget:n.expectedResolvedTarget,preresolvedTarget:n.preresolvedTarget});if(!e.backend.fill)throw new t(`UNSUPPORTED_OPERATION`,`fill is not supported by this backend`);let o=Rr(a),s=`node`in a?a.node?.type??``:``,c=s!==``&&le(s,e.backend.platform),l=n.allowNonHittableCoordinateFallback===!0&&`node`in a&&a.node?.hittable===!1,u=C(await e.backend.fill(b(e,n),o,n.text,{delayMs:n.delayMs,allowNonHittableCoordinateFallback:l})),d=s&&!c?`fill target ${Hr(a)} resolved to "${s}", attempting fill anyway.`:void 0;return await Te(e,n,a,{...a,text:n.text,...d?{warning:d}:{},...u?{backendResult:u}:{}},r)},Ir=async(e,n)=>{let r=n.text;if(!r)throw new t(`INVALID_ARGS`,`type requires text`);let i=Ur(r);if(i)throw new t(`INVALID_ARGS`,`type does not accept a target ref like "${i}"`,{hint:`Use fill ${i} "text" to target that field, or press ${i} then type "text" to append.`});if(!e.backend.typeText)throw new t(`UNSUPPORTED_OPERATION`,`type is not supported by this backend`);let a=x(n.delayMs??0,`delay-ms`,0,1e4),o=C(await e.backend.typeText(b(e,n),r,{delayMs:a}));return{kind:`text`,text:r,delayMs:a,...o?{backendResult:o}:{},...w(`Typed ${Array.from(r).length} chars`)}};async function Lr(e,n,r){let i=fe(n),a=i.needsPreActionBaseline?null:await zr(e,n,r);if(a)return a;let o=await he(e,n,{action:r,requireInteractive:!0,pipeline:S.promotedTarget,captureEvidenceBaseline:i.needsPreActionBaseline,expectedResolvedTarget:n.expectedResolvedTarget,preresolvedTarget:n.preresolvedTarget});if(!e.backend.tap)throw new t(`UNSUPPORTED_OPERATION`,`tap is not supported by this backend`);let s=Rr(o),c;try{c=await e.backend.tap(b(e,n),s,{button:n.button,count:n.count,intervalMs:n.intervalMs,holdMs:n.holdMs,jitterPx:n.jitterPx,doubleTap:n.doubleTap})}catch(e){throw Ar(e,o),e}let l=C(c);return await Te(e,n,o,{...o,...l?{backendResult:l}:{}},i)}function Rr(e){if(!e.point)throw new t(`COMMAND_FAILED`,`Interaction target resolved without coordinates`);return e.point}async function zr(e,t,n){if(n!==`click`||t.target.kind!==`ref`||!e.backend.tapTarget||Vr(t)||t.expectedResolvedTarget)return null;let{tapTarget:r}=e.backend;return await Ce(e,t,t.target,n,async(e,t)=>await r(e,t))}async function Br(e,t){if(t.target.kind!==`ref`||!e.backend.fillTarget||t.expectedResolvedTarget)return null;let{fillTarget:n}=e.backend;return{...await Ce(e,t,t.target,`fill`,async(e,r)=>await n(e,r,t.text,{delayMs:t.delayMs})),text:t.text}}function Vr(e){return e.count!==void 0||e.intervalMs!==void 0||e.holdMs!==void 0||e.jitterPx!==void 0||e.doubleTap!==void 0||e.button!==void 0&&e.button!==`primary`}function Hr(e){return e.target?.kind===`ref`?e.target.ref:e.target?.kind===`selector`?e.target.selector:`point`}function Ur(e){return Wt(e)}function z(e){return{includeRects:e===`visible`||e===`hidden`,interactiveOnly:!1}}const Wr=S.wait.poll.defaultTimeoutMs;function B(e,t,n,r){let i=we(r),a=n??i.defaultTimeoutMs,o=V(e),s=Yr(),c=()=>Math.max(0,a-(V(e)-o));return{capture:async n=>{let r=!1,i=await pe(e,t,c(),async e=>await s.attempt(async()=>{let t=await n(e);return r=!0,t}));return i.timedOut?{timedOut:!0,deadline:s.readableCaptures()===0?`capture-stalled`:`capture-truncated`}:(r&&s.recordReadableCapture(),i)},hasTimeRemaining:()=>c()>0,failureEvidence:()=>({timeoutMs:a,readableCaptures:s.readableCaptures(),waitedMs:V(e)-o}),rethrowIfNeverReadable:s.rethrowIfNeverReadable,sleepUntilNextPoll:async()=>await Xr(e,t,Math.min(i.intervalMs,c())),timeoutMs:a,waitedMs:()=>V(e)-o}}function Gr(e,n){return new t(`COMMAND_FAILED`,e,{reason:T.captureStalled,captureStalled:!0,...n,retriable:!0,hint:`No readable snapshot capture completed before the wait timeout. Retry, or use screenshot to inspect the current surface.`})}function Kr(e,n){return new t(`COMMAND_FAILED`,e,{reason:T.deadlineExceeded,captureTruncated:!0,...n})}function qr(e,n){return new t(`COMMAND_FAILED`,e,{reason:T.targetAbsent,...n})}function Jr(e,t,n){let r=t.failureEvidence();return n===`capture-stalled`?Gr(e,r):n===`capture-truncated`?Kr(e,r):(t.rethrowIfNeverReadable(),r.readableCaptures===0?Gr(e,r):qr(e,r))}function Yr(){let e=0,t;return{attempt:async e=>{try{return await e()}catch(e){if(!re(e))throw e;t=e;return}},recordReadableCapture:()=>{e+=1},readableCaptures:()=>e,rethrowIfNeverReadable:()=>{if(e===0&&t!==void 0)throw t}}}function V(e){return e.clock?.now()??Date.now()}async function Xr(e,t,n){let r=[t.signal,e.signal].filter(e=>e!==void 0);for(let e of r)e.throwIfAborted();if(n<=0)return!1;if(e.clock){await e.clock.sleep(n);for(let e of r)e.throwIfAborted();return!0}return await new Promise((e,t)=>{let i=r.length>0?AbortSignal.any(r):void 0,a=()=>i?.removeEventListener(`abort`,s),o=setTimeout(()=>{a(),e()},n),s=()=>{clearTimeout(o),a(),t(i?.reason)};i?.addEventListener(`abort`,s,{once:!0}),o.unref()}),!0}function Zr(e){if(e.kind===`ambiguous`||e.kind===`target`)return{selector:e.selector,selectorIndex:e.selectorIndex,matchedNodes:e.matchedNodes}}function Qr(e){let r=async(r,i)=>{if(i.target.kind===`sleep`)return await Xr(r,i,i.target.durationMs),{kind:`sleep`,waitedMs:i.target.durationMs};if(i.target.kind===`ref`){let o=await e.requireSnapshot(r,i.session),s=a(i.target.ref);if(!s)throw new t(`INVALID_ARGS`,`Invalid ref: ${i.target.ref}`);let c=n(o.snapshot.nodes,s),l=c?ke(c,o.snapshot.nodes):void 0;if(!l)throw new t(`COMMAND_FAILED`,`Ref ${i.target.ref} not found or has no label`);return await ti(e,r,i,l,i.target.timeoutMs)}if(i.target.kind===`selector`)return await $r(e,r,i,i.target.selector,i.target.timeoutMs,i.target.recordedLandmark);if(i.target.kind===`stable`)return await ri(e,r,i,i.target.quietMs,i.target.timeoutMs);let o=d(i.target.text);if(!o.ok)throw new t(o.code,o.message);return await ti(e,r,i,i.target.text,i.target.timeoutMs)};return{waitCommand:r,waitForTextCommand:async(e,n)=>{let i=await r(e,{...n,target:{kind:`text`,text:n.text,timeoutMs:n.timeoutMs}});if(i.kind!==`text`)throw new t(`COMMAND_FAILED`,`waitForText returned non-text result`);return i}}}async function $r(e,n,r,i,a,o){let s=B(n,r,a,S.wait),c=z(),l,u;for(;s.hasTimeRemaining();){let t=await s.capture(async t=>await e.captureSnapshot(n,{...r,signal:t},{updateSession:!0,includeHiddenContentHints:!1,...c}));if(t.timedOut){u=t.deadline;break}let a=t.value;if(a){let e=a.snapshot.nodes,t=Zr(await v(S.wait,e,i,{platform:n.backend.platform}));if(t){let n=ei(e,t,o);if(n.kind===`satisfied`)return{kind:`selector`,selector:t.selector,waitedMs:s.waitedMs(),node:n.node,preActionNodes:e};l=n.evidence}}await s.sleepUntilNextPoll()}throw u!==`capture-stalled`&&l?new t(`COMMAND_FAILED`,`wait matched selector ${i} but no candidate carried the recorded landmark identity`,{reason:be,...l}):Jr(`wait timed out for selector: ${i}`,s,u)}function ei(e,t,n){let r=t.matchedNodes[0];if(!n)return{kind:`satisfied`,node:r};let i=Ie(e),a=ve(t.matchedNodes,i,te(n),n.ancestry)[0];return a?{kind:`satisfied`,node:a}:{kind:`identity-mismatch`,evidence:{matchCount:t.matchedNodes.length,observed:p(r),observedAncestry:ye(r,i,Math.max(n.ancestry.length,1)).chain}}}async function ti(e,t,n,r,i){let a=B(t,n,i,S.wait),o;for(;a.hasTimeRemaining();){let i=await a.capture(async i=>t.backend.findText?(await t.backend.findText(ii(t,{...n,signal:i}),r)).found:await ni(e,t,{...n,signal:i},r));if(i.timedOut){o=i.deadline;break}if(i.value)return{kind:`text`,text:r,waitedMs:a.waitedMs()};await a.sleepUntilNextPoll()}throw Jr(`wait timed out for text: ${r}`,a,o)}async function ni(e,t,n,r){return!!ge((await e.captureSnapshot(t,n,{updateSession:!0,includeHiddenContentHints:!1})).snapshot.nodes,r)}async function ri(e,n,r,i,a){let o=a??Wr,s=i??e.stable.defaultQuietMs,c=await e.stable.capture(n,r,{quietMs:s,timeoutMs:o});if(!c.settled)throw new t(`COMMAND_FAILED`,`wait timed out waiting for a stable UI`,{reason:T.stableTimeout,...c.stalled?{captureStalled:!0}:{},quietMs:s,timeoutMs:o,captures:c.captures,nodeCount:c.nodeCount,...c.stalled?{hint:`A snapshot capture stalled past the wait timeout, so no settle verdict is available. The UI may still be readable: retry, or use screenshot to inspect the surface.`}:{}});return{kind:`stable`,waitedMs:c.waitedMs,captures:c.captures,nodeCount:c.nodeCount,...c.nodeCount<e.stable.tinyTreeNodeCount?{hint:e.stable.tinyTreeHint}:{}}}function ii(e,t){return{session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata}}const ai=Qr({captureSnapshot:_,requireSnapshot:de,stable:{defaultQuietMs:500,tinyTreeHint:Ee,tinyTreeNodeCount:5,capture:me}}),oi=ai.waitCommand,si=ai.waitForTextCommand,ci=async(e,n)=>{let r=n.locator??`any`;if(!n.query)throw new t(`INVALID_ARGS`,se);if(n.action===`wait`)return await mi(e,n,r);if(n.action===`list`)return await hi(e,n,r);let{capture:i,match:a}=await gi(e,n,r);if(!a)throw new t(`COMMAND_FAILED`,`find did not match any element`);if(n.action===`exists`)return{kind:`found`,found:!0};let o=`@${a.ref}`;return n.action===`get_attrs`?{kind:`attrs`,ref:o,node:a}:{kind:`text`,ref:o,text:await Ue(e,i,a),node:a}},H=async(e,t)=>{if(t.target.kind===`ref`){let n=await de(e,t.session),r=Oe(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`});xe(r.node,n.snapshot.nodes,t.expectedResolvedTarget,`get`);let i=f(r.node,e.backend.platform,{action:`get`,nodes:n.snapshot.nodes}),a={kind:`ref`,ref:`@${r.ref}`},o=n.snapshot.nodes;return t.property===`attrs`?{kind:`attrs`,target:a,node:r.node,selectorChain:i,preActionNodes:o}:{kind:`text`,target:a,text:await Ue(e,n,r.node),node:r.node,selectorChain:i,preActionNodes:o}}let n=await _i(e,t,t.session??`default`,{selector:t.target.selector,policy:t.property===`text`?S.readText:S.readUnique,hooks:{onResolved:(e,n)=>xe(e,n,t.expectedResolvedTarget,`get`)}}),r=f(n.node,e.backend.platform,{action:`get`,nodes:n.capture.snapshot.nodes});if(t.property===`attrs`)return{kind:`attrs`,target:{kind:`selector`,selector:n.selector},node:n.node,selectorChain:r,preActionNodes:n.capture.snapshot.nodes};let i=await Ue(e,n.capture,n.node);return{kind:`text`,target:{kind:`selector`,selector:n.selector},text:i,node:n.node,selectorChain:r,preActionNodes:n.capture.snapshot.nodes}},li=async(e,n)=>{let r=await H(e,{...n,property:`text`,target:n.target});if(r.kind!==`text`)throw new t(`COMMAND_FAILED`,`getText returned non-text result`);return r},ui=async(e,n)=>{let r=await H(e,{...n,property:`attrs`,target:n.target});if(r.kind!==`attrs`)throw new t(`COMMAND_FAILED`,`getAttrs returned non-attrs result`);return r},di=async(e,n)=>{let r=ie(n.predicate);if(!r.ok)throw new t(r.code,r.message,{hint:r.hint});let i=r.predicate;if(i===`text`&&!n.expectedText)throw new t(`INVALID_ARGS`,m);let a=n.selector,o=await _(e,n,{updateSession:!0,...z(i)});if(i===`exists`){let n=await v(S.readAny,o.snapshot.nodes,a,{platform:e.backend.platform});if(n.kind!==`target`)throw new t(`COMMAND_FAILED`,g(a,[],{unique:!1}),{hint:h([])});return{predicate:i,pass:!0,selector:n.selector,matches:n.matches,selectorChain:ae(a)}}let s=await v(S.readUnique,o.snapshot.nodes,a,{platform:e.backend.platform},{onResolved:(e,t)=>xe(e,t,n.expectedResolvedTarget,`is`)});if(s.kind!==`target`)throw new t(`COMMAND_FAILED`,g(a,[],{unique:!0}),{command:`is`,reason:`selector_not_found`,predicate:i,selector:a,hint:h([])});let c=s,l=oe({predicate:i,node:c.node,nodes:o.snapshot.nodes,expectedText:n.expectedText,platform:e.backend.platform});if(!l.pass)throw new t(`COMMAND_FAILED`,`is ${i} failed for selector ${c.selector}: ${l.details}`,{command:`is`,reason:`predicate_failed`,predicate:i,selector:c.selector,predicateDetails:l.details});return{predicate:i,pass:!0,selector:c.selector,...i===`text`?{text:l.actualText}:{},selectorChain:ae(a),node:c.node,preActionNodes:o.snapshot.nodes}},fi=async(e,t)=>await di(e,{...t,predicate:`visible`,selector:t.target.selector}),pi=async(e,t)=>await di(e,{...t,predicate:`hidden`,selector:t.target.selector});async function mi(e,t,n){let r=B(e,t,t.timeoutMs,S.findWait),i;for(;r.hasTimeRemaining();){let a=await r.capture(async r=>await gi(e,{...t,signal:r},n,{includeHiddenContentHints:!1}));if(a.timedOut){i=a.deadline;break}if(a.value?.match)return{kind:`found`,found:!0,waitedMs:r.waitedMs()};await r.sleepUntilNextPoll()}throw Jr(`find wait timed out`,r,i)}async function hi(e,t,n){let r=ne(n,t.query),i=await _(e,t,{updateSession:!0,...z()});if(Ye(i.snapshot.snapshotQuality))throw De(i.snapshot.snapshotQuality);return{kind:`list`,matches:(r?Ae(S.readList,i.snapshot.nodes,r,{platform:e.backend.platform}).list?.matchedNodes??[]:ce(i.snapshot.nodes,n,t.query,{}).matches).map(e=>({ref:`@${e.ref}`,node:e}))}}async function gi(e,t,n,r){let i=ne(n,t.query),a=await _(e,t,{updateSession:!0,scope:_e(e.backend.platform,n,t.query,i),includeHiddenContentHints:r?.includeHiddenContentHints,...z()});if(Ye(a.snapshot.snapshotQuality))throw De(a.snapshot.snapshotQuality);if(i){let t=await v(S.readAny,a.snapshot.nodes,i,{platform:e.backend.platform});return{capture:a,match:t.kind===`target`?t.node:void 0}}return{capture:a,match:ce(a.snapshot.nodes,n,t.query,{requireRect:!1}).matches[0]}}async function _i(e,n,r,i){let a=await _(e,{...n,session:r},{updateSession:!0,...z()}),o=await v(i.policy,a.snapshot.nodes,i.selector,{platform:e.backend.platform},i.hooks);if(o.kind!==`target`)throw new t(`COMMAND_FAILED`,g(i.selector,[],{unique:!0}),{hint:h([])});return{capture:a,node:o.node,selector:o.selector,ref:`@${o.node.ref}`}}const vi=async(e,n)=>{if(!e.backend.performGesture)throw new t(`UNSUPPORTED_OPERATION`,`gesture is not supported by this backend`);await Se(e,n,n.gesture.intent);let r=await Me(e,n),i=Ge(n.gesture,r,e.backend.platform),a=C(await e.backend.performGesture(b(e,n),i)),o=bi(i.pointers,0),s=bi(i.pointers,-1);return{kind:n.gesture.intent,durationMs:i.durationMs,pointerCount:i.topology===`single`?1:2,from:o,to:s,...a?{backendResult:a}:{},...w(xi(n.gesture,o,s))}},yi=async(e,t)=>{let n=t.gesture;return n.intent===`drag`?await Ne(e,{...t,gesture:n}):await vi(e,{...t,gesture:n})};function bi(e,n){let r=e.map(e=>n===0?e.samples[0]?.point:e.samples.at(-1)?.point);if(r.some(e=>e===void 0))throw new t(`COMMAND_FAILED`,`Gesture plan did not contain endpoint samples.`);let i=r;return{x:i.reduce((e,t)=>e+t.x,0)/i.length,y:i.reduce((e,t)=>e+t.y,0)/i.length}}function xi(e,t,n){switch(e.intent){case`pan`:{let r=`preset`in e?t:e.origin,i=`preset`in e?{x:n.x-t.x,y:n.y-t.y}:e.delta;return`Panned (${r.x}, ${r.y}) by (${i.x}, ${i.y})`}case`fling`:return`direction`in e?`Flung ${e.direction}`:`Flung`;case`pinch`:return`Pinched to scale ${e.scale}`;case`rotate`:return`Rotated gesture ${e.degrees} degrees`;case`transform`:return`Requested transform gesture by (${e.delta.x}, ${e.delta.y}), scale ${e.scale}, rotate ${e.degrees} degrees`}}const U={find:ci,get:H,getText:li,getAttrs:ui,is:di,isVisible:fi,isHidden:pi,wait:oi,waitForText:si},W={click:Pr,press:Nr,fill:Fr,typeText:Ir,focus:je,longPress:He,hover:ze,scroll:Ve,gesture:yi,settleObservation:Be};function Si(e){return{find:t=>U.find(e,t),get:t=>U.get(e,t),getText:(t,n={})=>U.getText(e,{...n,target:t}),getAttrs:(t,n={})=>U.getAttrs(e,{...n,target:t}),is:t=>U.is(e,t),isVisible:(t,n={})=>U.isVisible(e,{...n,target:t}),isHidden:(t,n={})=>U.isHidden(e,{...n,target:t}),wait:t=>U.wait(e,t),waitForText:(t,n={})=>U.waitForText(e,{...n,text:t})}}function Ci(e){return{click:(t,n={})=>W.click(e,{...n,target:t}),press:(t,n={})=>W.press(e,{...n,target:t}),fill:(t,n,r={})=>W.fill(e,{...r,target:t,text:n}),typeText:(t,n={})=>W.typeText(e,{...n,text:t}),focus:(t,n={})=>W.focus(e,{...n,target:t}),longPress:(t,n={})=>W.longPress(e,{...n,target:t}),hover:(t,n={})=>W.hover(e,{...n,target:t}),scroll:t=>W.scroll(e,t),gesture:t=>W.gesture(e,t),settleObservation:t=>W.settleObservation(e,t)}}function G(e,t){if(e!==void 0)return K(e,t)}function K(e,n){let r=e?.trim();if(!r)throw new t(`INVALID_ARGS`,`${n} must be a non-empty string`);return r}const wi=async(e,n={})=>{if(!e.backend.listDevices)throw new t(`UNSUPPORTED_OPERATION`,`admin.devices is not supported by this backend`);return{kind:`adminDevices`,devices:await e.backend.listDevices(b(e,n),n.filter)}},Ti=async(e,n={})=>{if(!e.backend.bootDevice)throw new t(`UNSUPPORTED_OPERATION`,`admin.boot is not supported by this backend`);let r=Pi(n.target),i=C(await e.backend.bootDevice(b(e,n),r));return{kind:`deviceBooted`,...r?{target:r}:{},...i?{backendResult:i}:{},...w(`Booted device`)}},Ei=async(e,n={})=>{if(!e.backend.shutdownDevice)throw new t(`UNSUPPORTED_OPERATION`,`admin.shutdown is not supported by this backend`);let r=Pi(n.target),i=C(await e.backend.shutdownDevice(b(e,n),r));return{kind:`deviceShutdown`,...r?{target:r}:{},...i?{backendResult:i}:{},...w(`Shutdown device`)}},Di=async(e,t)=>await q(e,t,`install`),Oi=async(e,t)=>await q(e,t,`reinstall`),ki=async(e,t)=>await q(e,t,`installFromSource`);async function q(e,n,r){let i=r===`reinstall`?`reinstallApp`:`installApp`,a=e.backend[i];if(!a)throw new t(`UNSUPPORTED_OPERATION`,`admin.${r} is not supported by this backend`);let o=`app`in n&&n.app!==void 0?K(n.app,`app`):void 0;if(r!==`installFromSource`&&!o)throw new t(`INVALID_ARGS`,`admin.${r} requires app`);let s=b(e,n),c=await Ai(e,s,n.source);try{let t=await a.call(e.backend,s,{...o?{app:o}:{},source:c.source});return Fi(r,o,c.source,t)}finally{await c.cleanup?.()}}async function Ai(e,t,n){let r=await ji(e,Mi(n));try{return{source:Mi(e.backend.resolveInstallSource?await e.backend.resolveInstallSource(t,r.source):r.source),...r.cleanup?{cleanup:r.cleanup}:{}}}catch(e){if(r.cleanup)try{await r.cleanup()}catch{}throw e}}async function ji(e,t){if(t.kind===`url`)return{source:t};let n=await I(e,t,{usage:`admin.install`,field:`source`});return{source:{kind:`path`,path:n.path},...n.cleanup?{cleanup:n.cleanup}:{}}}function Mi(e){if(!e||typeof e!=`object`)throw new t(`INVALID_ARGS`,`install source is required`);if(e.kind===`path`)return{kind:`path`,path:K(e.path,`source.path`)};if(e.kind===`uploadedArtifact`)return{kind:`uploadedArtifact`,id:K(e.id,`source.id`)};if(e.kind===`url`){let t=K(e.url,`source.url`);return Ni(t),{kind:`url`,url:t}}throw new t(`INVALID_ARGS`,`install source kind must be path, uploadedArtifact, or url`)}function Ni(e){let n;try{n=new URL(e)}catch{throw new t(`INVALID_ARGS`,`Invalid install source URL: ${e}`)}if(n.protocol!==`http:`&&n.protocol!==`https:`)throw new t(`INVALID_ARGS`,`Install source URL must use http or https`)}function Pi(e){if(!e)return;let t=G(e.id,`target.id`),n=G(e.name,`target.name`),r={...t?{id:t}:{},...n?{name:n}:{},...e.platform?{platform:e.platform}:{},...e.target?{target:e.target}:{},...e.headless===void 0?{}:{headless:e.headless}};return Object.keys(r).length>0?r:void 0}function Fi(e,t,n,r){let i=C(r),a=e===`reinstall`?`appReinstalled`:e===`installFromSource`?`appInstalledFromSource`:`appInstalled`,o=J(r,`appName`),s=J(r,`appId`),c=J(r,`bundleId`),l=J(r,`packageName`),u=J(r,`launchTarget`),d=J(r,`installablePath`),f=J(r,`archivePath`);return{kind:a,...t?{app:t}:{},source:n,...s?{appId:s}:{},...o?{appName:o}:{},...c?{bundleId:c}:{},...l?{packageName:l}:{},...u?{launchTarget:u}:{},...d?{installablePath:d}:{},...f?{archivePath:f}:{},...i?{backendResult:i}:{},...w(`${e===`reinstall`?`Reinstalled`:`Installed`}: ${o??u??t??Ii(n)}`)}}function J(e,t){let n=e[t];return typeof n==`string`&&n.length>0?n:void 0}function Ii(e){return e.kind===`path`?e.path:e.kind===`uploadedArtifact`?e.id:e.url}const Li=/^[A-Za-z0-9_.:-]{1,64}$/,Ri=async(e,n)=>{if(!e.backend.openApp)throw new t(`UNSUPPORTED_OPERATION`,`apps.open is not supported by this backend`);let r=Wi(n),i=C(await e.backend.openApp(Y(e,n),r,{launchArgs:n.launchArgs,relaunch:n.relaunch}));return{kind:`appOpened`,target:r,relaunch:n.relaunch===!0,...i?{backendResult:i}:{},...w(`Opened: ${Ki(r)}`)}},zi=async(e,n={})=>{if(!e.backend.closeApp)throw new t(`UNSUPPORTED_OPERATION`,`apps.close is not supported by this backend`);let r=G(n.app,`app`),i=C(await e.backend.closeApp(Y(e,n),r));return{kind:`appClosed`,...r?{app:r}:{},...i?{backendResult:i}:{},...w(r?`Closed: ${r}`:`Closed app`)}},Bi=async(e,n={})=>{if(!e.backend.listApps)throw new t(`UNSUPPORTED_OPERATION`,`apps.list is not supported by this backend`);return{kind:`appsList`,apps:await e.backend.listApps(Y(e,n),Xe(n.filter))}},Vi=async(e,n)=>{if(!e.backend.getAppState)throw new t(`UNSUPPORTED_OPERATION`,`apps.state is not supported by this backend`);let r=K(n.app,`app`);return{kind:`appState`,app:r,state:await e.backend.getAppState(Y(e,n),r)}},Hi=async(e,n)=>{if(!e.backend.pushFile)throw new t(`UNSUPPORTED_OPERATION`,`apps.push is not supported by this backend`);let r=K(n.app,`app`),i=await qi(e,n.input);try{let t=C(await e.backend.pushFile(Y(e,n),i.backendInput,r));return{kind:`appPushed`,app:r,inputKind:i.inputKind,...t?{backendResult:t}:{},...w(`Pushed to ${r}`)}}finally{await i.cleanup?.()}},Ui=async(e,n)=>{if(!e.backend.triggerAppEvent)throw new t(`UNSUPPORTED_OPERATION`,`apps.triggerEvent is not supported by this backend`);let r=Ji(n.name);Yi(n.payload,`apps.triggerEvent payload for "${r}"`);let i=C(await e.backend.triggerAppEvent(Y(e,n),{name:r,...n.payload?{payload:n.payload}:{}}));return{kind:`appEventTriggered`,name:r,...n.payload?{payload:n.payload}:{},...i?{backendResult:i}:{},...w(`Triggered app event: ${r}`)}};function Wi(e){let n=G(e.app,`app`),r=G(e.appId,`appId`),i=G(e.bundleId,`bundleId`),a=G(e.packageName,`packageName`),o=G(e.url,`url`),s=G(e.activity,`activity`),c={...n?{app:n}:{},...r?{appId:r}:{},...i?{bundleId:i}:{},...a?{packageName:a}:{},...o?{url:o}:{},...s?{activity:s}:{}};if(!Gi(c))throw new t(`INVALID_ARGS`,`apps.open requires app, appId, bundleId, packageName, url, or activity`);return c}function Gi(e){return!!(e.app??e.appId??e.bundleId??e.packageName??e.url??e.activity)}function Ki(e){return e.app??e.appId??e.bundleId??e.packageName??e.url??e.activity??`app`}async function qi(e,n){if(!n||typeof n!=`object`)throw new t(`INVALID_ARGS`,`apps.push requires an input`);if(n.kind===`json`)return Xi(n.payload,`apps.push JSON payload`,8192),{backendInput:{kind:`json`,payload:n.payload},inputKind:`json`};let r=await I(e,n,{usage:`apps.push`,field:`input`});return{backendInput:{kind:`file`,path:r.path},inputKind:`file`,...r.cleanup?{cleanup:r.cleanup}:{}}}function Ji(e){let n=K(e,`name`);if(!Li.test(n))throw new t(`INVALID_ARGS`,`Invalid apps.triggerEvent name: ${n}`,{hint:`Use 1-64 chars: letters, numbers, underscore, dot, colon, or dash.`});return n}function Yi(e,t){e!==void 0&&Xi(e,t,8192)}function Xi(e,n,r){if(Zi(e,n),Buffer.byteLength(Qi(e,n),`utf8`)>r)throw new t(`INVALID_ARGS`,`${n} exceeds ${r} bytes`)}function Zi(e,n){if(!e||typeof e!=`object`||Array.isArray(e))throw new t(`INVALID_ARGS`,`${n} must be a JSON object`)}function Qi(e,n){try{let r=JSON.stringify(e);if(typeof r!=`string`)throw new t(`INVALID_ARGS`,`${n} must be JSON-serializable`);return r}catch{throw new t(`INVALID_ARGS`,`${n} must be JSON-serializable`)}}function Y(e,t){return{session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata}}const $i={open:Ri,close:zi,list:Bi,state:Vi,push:Hi,triggerEvent:Ui},ea={devices:wi,boot:Ti,shutdown:Ei,install:Di,reinstall:Oi,installFromSource:ki};function ta(e){return{...y($i,e),list:(t={})=>$i.list(e,{...t,filter:Ze(t.filter)})}}const na=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i,ra=/\b[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\b/g;function ia(e){let t=!1,n=e;return n=n.replaceAll(/(authorization|token|secret|password|passwd|api[-_]?key)=([^&\s]+)/gi,(e,n)=>(t=!0,`${String(n)}=[REDACTED]`)),n=n.replaceAll(/("(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)"\s*:\s*")([^"]*)(")/gi,(e,n,r,i)=>(t=!0,`${String(n)}[REDACTED]${String(i)}`)),n=n.replaceAll(/\b(Bearer\s+)([^\s",;]+)/gi,(e,n)=>(t=!0,`${String(n)}[REDACTED]`)),n=n.replaceAll(/((?:authorization|cookie|token|secret|password|passwd|api[-_]?key)\s*[:=]\s*)([^\s,;&]+)/gi,(e,n)=>(t=!0,`${String(n)}[REDACTED]`)),n=n.replaceAll(ra,()=>(t=!0,`[REDACTED]`)),n=oa(n,()=>{t=!0}),{value:n,redacted:t}}function aa(e){try{let t=new URL(e),n=sa(t);return(t.username||t.password)&&(t.username=`REDACTED`,t.password=`REDACTED`,n=!0),{value:t.toString(),redacted:n}}catch{return}}function oa(e,t){return/(https?:\/\/|token|secret|password|authorization|cookie|api[-_]?key)/i.test(e)?e.replaceAll(/https?:\/\/[^\s"'<>)]+/gi,e=>{let n=aa(e);return n?(n.redacted&&t(),n.value):e}):e}function sa(e){let t=!1;for(let n of Array.from(e.searchParams.keys()))na.test(n)&&(e.searchParams.set(n,`[REDACTED]`),t=!0);return t}const X=2048,ca=4096,la=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i;function ua(e){let t=e.redacted===!0;return{kind:`diagnosticsLogs`,entries:e.entries.map(e=>{let n=Q(e.message,ca),r=_a(e.metadata);return t||=n.redacted||r.redacted,{...e.timestamp?{timestamp:e.timestamp}:{},...e.level?{level:e.level}:{},message:n.value??``,...e.source?{source:e.source}:{},...r.value?{metadata:r.value}:{}}}),...e.nextCursor?{nextCursor:e.nextCursor}:{},...e.timeWindow?{timeWindow:e.timeWindow}:{},...e.backend?{backend:e.backend}:{},redacted:t,...e.notes?{notes:e.notes}:{}}}function da(e,t){let n=e.redacted===!0;return{kind:`diagnosticsNetwork`,entries:e.entries.map(e=>{let r=e.url?ma(e.url):void 0,i=t===`headers`||t===`all`?pa(e.requestHeaders):void 0,a=t===`headers`||t===`all`?pa(e.responseHeaders):void 0,o=t===`body`||t===`all`?ha(e.requestBody):void 0,s=t===`body`||t===`all`?ha(e.responseBody):void 0,c=_a(e.metadata);return n||=(r?.redacted??!1)||(i?.redacted??!1)||(a?.redacted??!1)||(o?.redacted??!1)||(s?.redacted??!1)||c.redacted,{...e.timestamp?{timestamp:e.timestamp}:{},...e.method?{method:e.method}:{},...r?{url:r.value}:{},...e.status===void 0?{}:{status:e.status},...e.durationMs===void 0?{}:{durationMs:e.durationMs},...i?.value?{requestHeaders:i.value}:{},...a?.value?{responseHeaders:a.value}:{},...o?.value===void 0?{}:{requestBody:o.value},...s?.value===void 0?{}:{responseBody:s.value},...c.value?{metadata:c.value}:{}}}),...e.nextCursor?{nextCursor:e.nextCursor}:{},...e.timeWindow?{timeWindow:e.timeWindow}:{},...e.backend?{backend:e.backend}:{},redacted:n,...e.notes?{notes:e.notes}:{}}}function fa(e){let t=e.redacted===!0;return{kind:`diagnosticsPerf`,metrics:e.metrics.map(e=>{let n=Q(e.message,ca),r=_a(e.metadata);return t||=n.redacted||r.redacted,{name:e.name,...e.value===void 0?{}:{value:e.value},...e.unit?{unit:e.unit}:{},...e.status?{status:e.status}:{},...n.value===void 0?{}:{message:n.value},...r.value?{metadata:r.value}:{}}}),...e.startedAt?{startedAt:e.startedAt}:{},...e.endedAt?{endedAt:e.endedAt}:{},...e.backend?{backend:e.backend}:{},redacted:t,...e.notes?{notes:e.notes}:{}}}function pa(e){if(!e)return{redacted:!1};let t=!1,n={};for(let[r,i]of Object.entries(e))if(la.test(r))n[r]=`[REDACTED]`,t=!0;else{let e=Q(i,X);n[r]=e.value??``,t||=e.redacted}return{value:n,redacted:t}}function ma(e){return aa(e)??Q(e,X)}function ha(e){return e===void 0?{redacted:!1}:ga(e)??Q(e,X)}function ga(e){try{let t=Z(JSON.parse(e),ia);return va(JSON.stringify(t.value),X,t.redacted)}catch{return}}function _a(e){return Z(e,e=>Q(e,X))}function Z(e,t){if(e===void 0)return{redacted:!1};if(typeof e==`string`)return t(e);if(!e||typeof e!=`object`)return{value:e,redacted:!1};if(Array.isArray(e)){let n=!1;return{value:e.map(e=>{let r=Z(e,t);return n||=r.redacted,r.value}),redacted:n}}let n=!1,r={};for(let[i,a]of Object.entries(e)){if(la.test(i)){r[i]=`[REDACTED]`,n=!0;continue}let e=Z(a,t);r[i]=e.value,n||=e.redacted}return{value:r,redacted:n}}function Q(e,t){if(e===void 0)return{redacted:!1};let n=ia(e);return va(n.value,t,n.redacted)}function va(e,t,n){if(e===void 0)return{redacted:n};let r=e;return r.length>t&&(r=`${r.slice(0,t)}...[truncated]`,n=!0),{value:r,redacted:n}}const ya=async(e,n={})=>{if(!e.backend.readLogs)throw new t(`UNSUPPORTED_OPERATION`,`diagnostics.logs is not supported by this backend`);return ua(await e.backend.readLogs(await Sa(e,n),Ca(n)))},ba=async(e,n={})=>{if(!e.backend.dumpNetwork)throw new t(`UNSUPPORTED_OPERATION`,`diagnostics.network is not supported by this backend`);let r=wa(n);return da(await e.backend.dumpNetwork(await Sa(e,n),r),r.include??`summary`)},xa=async(e,n={})=>{if(!e.backend.measurePerf)throw new t(`UNSUPPORTED_OPERATION`,`diagnostics.perf is not supported by this backend`);return fa(await e.backend.measurePerf(await Sa(e,n),Ta(n)))};async function Sa(e,t){let n=b(e,t),r=t.session?await e.sessions.get(t.session):void 0;return{...n,...t.appId??r?.appId?{appId:t.appId??r?.appId}:{},...t.appBundleId??r?.appBundleId?{appBundleId:t.appBundleId??r?.appBundleId}:{}}}function Ca(e){return{...Ea(e,100,500,`logs limit`),...e.levels===void 0?{}:{levels:ka(e.levels,`levels`)},...e.search===void 0?{}:{search:K(e.search,`search`)},...e.source===void 0?{}:{source:K(e.source,`source`)}}}function wa(e){return{...Ea(e,25,200,`network limit`),include:Oa(e.include)}}function Ta(e){return{...Da(e),...e.sampleMs===void 0?{}:{sampleMs:x(e.sampleMs,`sampleMs`,100,6e4)},...e.metrics===void 0?{}:{metrics:ka(e.metrics,`metrics`,20)}}}function Ea(e,t,n,r){return{...Da(e),...e.cursor===void 0?{}:{cursor:K(e.cursor,`cursor`)},limit:e.limit===void 0?t:x(e.limit,r,1,n)}}function Da(e){return{...e.since===void 0?{}:{since:K(e.since,`since`)},...e.until===void 0?{}:{until:K(e.until,`until`)}}}function Oa(e){if(e===void 0)return`summary`;if(e===`summary`||e===`headers`||e===`body`||e===`all`)return e;throw new t(`INVALID_ARGS`,`network include must be summary, headers, body, or all`)}function ka(e,n,r=50){if(!Array.isArray(e))throw new t(`INVALID_ARGS`,`${n} must be an array of strings`);if(e.length>r)throw new t(`INVALID_ARGS`,`${n} must contain at most ${r} entries`);return e.map((e,t)=>K(e,`${n}[${t}]`))}const Aa={logs:ya,network:ba,perf:xa},ja=async(e,n)=>{let r=Ia(n.action,`record`),i=r===`start`?e.backend.startRecording:e.backend.stopRecording;if(!i)throw new t(`UNSUPPORTED_OPERATION`,`record ${r} is not supported by this backend`);let a=n.out?await L(e,n.out,{field:`path`,ext:`.mp4`,artifactType:`screen-recording`}):void 0;try{let t=Na(n,a?.path);return La(r,await i.call(e.backend,b(e,n),t),await a?.publish())}catch(e){throw await a?.cleanup?.(),e}},Ma=async(e,n)=>{let r=Ia(n.action,`trace`),i=r===`start`?e.backend.startTrace:e.backend.stopTrace;if(!i)throw new t(`UNSUPPORTED_OPERATION`,`trace ${r} is not supported by this backend`);let a=n.out?await L(e,n.out,{field:`outPath`,ext:`.trace`,artifactType:`trace-log`}):void 0;try{let t={...a?.path?{outPath:a.path}:{}};return Ra(r,await i.call(e.backend,b(e,n),t),await a?.publish())}catch(e){throw await a?.cleanup?.(),e}};function Na(e,t){let n={};t&&(n.outPath=t);let r=Pa(e.fps);r!==void 0&&(n.fps=r);let i=Fa(e.quality);return i!==void 0&&(n.quality=i),e.hideTouches!==void 0&&(n.showTouches=e.hideTouches!==!0),n}function Pa(e){return e===void 0?void 0:x(e,`fps`,1,60)}function Fa(e){if(e===void 0)return;let n=We(e);if(n===void 0)throw new t(`INVALID_ARGS`,`quality must be one of: medium, high (legacy numeric values 5-10 are accepted)`);return n}function Ia(e,n){if(e===`start`||e===`stop`)return e;throw new t(`INVALID_ARGS`,`${n} action must be start or stop`)}function La(e,t,n){return{...typeof t.path==`string`?{path:t.path}:{},...typeof t.telemetryPath==`string`?{telemetryPath:t.telemetryPath}:{},...typeof t.warning==`string`?{warning:t.warning}:{},...za(e,t,n,{startKind:`recordingStarted`,stopKind:`recordingStopped`,startMessage:`Recording started`,stopMessage:`Recording stopped`})}}function Ra(e,t,n){return{...typeof t.outPath==`string`?{outPath:t.outPath}:{},...za(e,t,n,{startKind:`traceStarted`,stopKind:`traceStopped`,startMessage:`Trace started`,stopMessage:`Trace stopped`})}}function za(e,t,n,r){return{kind:e===`start`?r.startKind:r.stopKind,action:e,...n?{artifact:n}:{},backendResult:t,...w(e===`start`?r.startMessage:r.stopMessage)}}const Ba={record:ja,trace:Ma},Va=async(e,n={})=>{if(!e.backend.pressBack)throw new t(`UNSUPPORTED_OPERATION`,`system.back is not supported by this backend`);let r=n.mode??`in-app`;if(r!==`in-app`&&r!==`system`)throw new t(`INVALID_ARGS`,`system.back mode must be in-app or system`);let i=C(await e.backend.pressBack(b(e,n),{mode:r}));return{kind:`systemBack`,mode:r,...i?{backendResult:i}:{},...w(`Back`)}},Ha=async(e,n={})=>{if(!e.backend.pressHome)throw new t(`UNSUPPORTED_OPERATION`,`system.home is not supported by this backend`);let r=C(await e.backend.pressHome(b(e,n)));return{kind:`systemHome`,...r?{backendResult:r}:{},...w(`Home`)}},Ua=async(e,n)=>{if(!e.backend.pressTvRemote)throw new t(`UNSUPPORTED_OPERATION`,`system.tvRemote is not supported by this backend`);let r=Ke(n.button),i=n.durationMs===void 0?void 0:x(n.durationMs,`durationMs`,0,1e4),a=C(await e.backend.pressTvRemote(b(e,n),{button:r,...i===void 0?{}:{durationMs:i}}));return{kind:`tvRemotePressed`,button:r,...i===void 0?{}:{durationMs:i},...a?{backendResult:a}:{},...w(`Pressed TV remote ${r}`)}},Wa=async(e,n)=>{if(!e.backend.setOrientation)throw new t(`UNSUPPORTED_OPERATION`,`system.orientation is not supported by this backend`);let r=Xa(n.orientation),i=C(await e.backend.setOrientation(b(e,n),r));return{kind:`systemOrientationSet`,orientation:r,...i?{backendResult:i}:{},...w(`Rotated to ${r}`)}},Ga=async(e,n={})=>{if(!e.backend.setKeyboard)throw new t(`UNSUPPORTED_OPERATION`,`system.keyboard is not supported by this backend`);let r=n.action??`status`;if(!qe(r))throw new t(`INVALID_ARGS`,`system.keyboard action must be status, get, dismiss, enter, or return`);let i=await e.backend.setKeyboard(b(e,n),{action:r}),a=C(i),o=ao(i)?i:{};return r===`enter`||r===`return`?Qa(o,a):r===`dismiss`?$a(r,o,a):to(r,o,a)},Ka=async(e,n)=>{if(n.action===`read`){if(!e.backend.getClipboard)throw new t(`UNSUPPORTED_OPERATION`,`system.clipboard read is not supported by this backend`);let r=await e.backend.getClipboard(b(e,n));return{kind:`clipboardText`,action:`read`,text:typeof r==`string`?r:r.text}}if(n.action!==`write`)throw new t(`INVALID_ARGS`,`system.clipboard action must be read or write`);if(!e.backend.setClipboard)throw new t(`UNSUPPORTED_OPERATION`,`system.clipboard write is not supported by this backend`);if(typeof n.text!=`string`)throw new t(`INVALID_ARGS`,`system.clipboard write requires text`);let r=C(await e.backend.setClipboard(b(e,n),n.text));return{kind:`clipboardUpdated`,action:`write`,textLength:Array.from(n.text).length,...r?{backendResult:r}:{},...w(`Clipboard updated`)}},qa=async(e,n={})=>{if(!e.backend.openSettings)throw new t(`UNSUPPORTED_OPERATION`,`system.settings is not supported by this backend`);let r=G(n.target,`target`),i=C(await e.backend.openSettings(b(e,n),r));return{kind:`settingsOpened`,...r?{target:r}:{},...i?{backendResult:i}:{},...w(r?`Opened settings: ${r}`:`Opened settings`)}},Ja=async(e,n={})=>{if(!e.backend.handleAlert)throw new t(`UNSUPPORTED_OPERATION`,`system.alert is not supported by this backend`);let r=n.action??`get`;if(r!==`get`&&r!==`accept`&&r!==`dismiss`&&r!==`wait`)throw new t(`INVALID_ARGS`,`system.alert action must be get, accept, dismiss, or wait`);let i=n.timeoutMs===void 0?void 0:x(n.timeoutMs,`timeoutMs`,0,12e4);return Za(r,await e.backend.handleAlert(b(e,n),r,{timeoutMs:i}))},Ya=async(e,n={})=>{if(!e.backend.openAppSwitcher)throw new t(`UNSUPPORTED_OPERATION`,`system.appSwitcher is not supported by this backend`);let r=C(await e.backend.openAppSwitcher(b(e,n)));return{kind:`appSwitcherOpened`,...r?{backendResult:r}:{},...w(`Opened app switcher`)}};function Xa(e){switch(e){case`portrait`:case`portrait-upside-down`:case`landscape-left`:case`landscape-right`:return e;default:throw new t(`INVALID_ARGS`,`system.orientation must be portrait, portrait-upside-down, landscape-left, or landscape-right`)}}function Za(e,t){return e===`get`?no(t):e===`wait`?ro(t):io(e,t)}function Qa(e,t){return{kind:`keyboardEnterPressed`,action:`enter`,state:e,...t?{backendResult:t}:{},...w(`Keyboard enter pressed`)}}function $a(e,t,n){return{kind:`keyboardDismissed`,action:e,state:t,...n?{backendResult:n}:{},...w(eo(t))}}function eo(e){return e.dismissed===!1?`Keyboard already hidden`:e.mechanism===`dismissKey`?`Keyboard dismissed via its dismiss key`:`Keyboard dismissed`}function to(e,t,n){return{kind:`keyboardState`,action:e,state:t,...n?{backendResult:n}:{}}}function no(e){if(e.kind!==`alertStatus`)throw new t(`COMMAND_FAILED`,`system.alert get returned an invalid backend result`);return{kind:`alertStatus`,action:`get`,alert:e.alert}}function ro(e){if(e.kind!==`alertWait`)throw new t(`COMMAND_FAILED`,`system.alert wait returned an invalid backend result`);return{kind:`alertWait`,action:`wait`,alert:e.alert,...e.waitedMs===void 0?{}:{waitedMs:e.waitedMs},...e.timedOut===void 0?{}:{timedOut:e.timedOut},...w(e.alert?`Alert visible`:`Alert wait timed out`)}}function io(e,n){if(n.kind!==`alertHandled`)throw new t(`COMMAND_FAILED`,`system.alert ${e} returned an invalid backend result`);return{kind:`alertHandled`,action:e,handled:n.handled,...n.alert?{alert:n.alert}:{},...n.button?{button:n.button}:{},...w(n.handled?`Alert ${e}ed`:`No alert handled`)}}function ao(e){return!!(e&&typeof e==`object`)}const oo={back:Va,home:Ha,orientation:Wa,keyboard:Ga,clipboard:Ka,settings:qa,alert:Ja,appSwitcher:Ya,tvRemote:Ua};function so(e){return{capture:y(Or,e),selectors:Si(e),interactions:Ci(e),system:y(oo,e),apps:ta(e),admin:y(ea,e),recording:y(Ba,e),observability:y(Aa,e)}}var co=e({createAgentDevice:()=>lo,createMemorySessionStore:()=>uo,localCommandPolicy:()=>po,restrictedCommandPolicy:()=>mo});function lo(e){let t={backend:e.backend,artifacts:e.artifacts,sessions:e.sessions??uo(),policy:e.policy??mo(),diagnostics:e.diagnostics,clock:e.clock,signal:e.signal};return{...t,...so(t)}}function uo(e=[]){let t=new Map(e.map(e=>[e.name,$(e)]));return{get:e=>$(t.get(e)),set:e=>{t.set(e.name,$(e))},delete:e=>{t.delete(e)},list:()=>Array.from(t.values(),e=>$(e))}}function $(e){if(e)return{...e,...e.snapshot?{snapshot:structuredClone(e.snapshot)}:{},...e.metadata?{metadata:fo(e.metadata)}:{}}}function fo(e){try{return structuredClone(e)}catch{return{...e}}}function po(e={}){return{allowLocalInputPaths:!0,allowLocalOutputPaths:!0,maxImagePixels:2e7,...e}}function mo(e={}){return{allowLocalInputPaths:!1,allowLocalOutputPaths:!1,maxImagePixels:2e7,...e}}export{ar as a,ut as c,D as d,Et as f,jr as i,dt as l,po as n,Qn as o,co as r,Wt as s,lo as t,ft as u};
@@ -1,5 +1,5 @@
1
- import{_ as e}from"./sdk-contracts.js";import{H as t,U as n,V as r,at as i,bt as a,dt as o,et as s,ot as c,st as l,tt as u,z as d}from"./sdk-batch-runner.js";import{C as ee}from"./sdk-device.js";import{a as f,i as p,n as m,o as h,p as g,r as _,t as v,v as te,x as y}from"./src3.js";import{readAndroidAppState as b}from"./app-state.js";import x from"node:path";function S(t){if(!/^[a-zA-Z0-9._:-]+$/.test(t))throw new e(`INVALID_ARGS`,`Invalid Android package name for logs: ${t}`)}const C=Object.freeze({resourceKind:u,version:1,encode:e=>({...e}),decode:e=>e.transport!==`android-logcat-local`&&e.transport!==`android-logcat-transport-composed`||!re(e.outputPath)||!re(e.pidPath)?{status:`invalid`,message:`Invalid Android app-log descriptor`}:{status:`decoded`,descriptor:Object.freeze({transport:e.transport,outputPath:e.outputPath,pidPath:e.pidPath})}});function ne(e){let t=C.decode(e.descriptor);if(t.status!==`decoded`)throw TypeError(t.message);return te({resourceKind:u,sessionId:e.sessionId,device:{id:e.device.id,family:`android`,kind:e.device.kind,...e.device.target===void 0?{}:{target:e.device.target}},owner:e.owner,fence:e.fence,lifecycle:`open`,descriptor:y(C,t.descriptor)})}function re(e){return typeof e==`string`&&e.trim().length>0}function ie(e){return f(e,{family:`android`,backend:`android`,label:`Android`,codec:C,startUnavailableHint:`The selected Android transport cannot start a background adb logcat stream.`,cleanupFailureMessage:`Android app-log cleanup did not settle every owned resource`,doctor:async({host:e,device:t,signal:n},r)=>await ae(e,t.id,r,n),validateStart:({input:e})=>S(e.appBundleId),process:async({host:e,device:t,input:n})=>({resolvePid:async r=>await h(e,oe(t.id,n.appBundleId),r),command:e=>({kind:`android-adb`,serial:t.id,args:[`logcat`,`-v`,`time`,`--pid`,e],options:{allowFailure:!0}})}),descriptor:({artifacts:e,transport:t})=>({transport:t.mode===`transport-composed`?`android-logcat-transport-composed`:`android-logcat-local`,...e}),envelope:({input:e,device:t,owner:n,descriptor:r})=>ne({sessionId:e.sessionId,device:t,owner:n,fence:e.fence,descriptor:r})})}async function ae(e,t,n,r){let i={};return i.adbAvailable=await p(async()=>_(await e.commands.run({executable:`adb`,args:[`-s`,t,`shell`,`echo`,`ok`],allowFailure:!0,timeoutMs:1e3},r)),r),n&&(i.androidPidVisible=await p(async()=>!!await h(e,oe(t,n),r),r)),{backend:`android`,checks:i,notes:n?[]:[`No app bundle is tracked in this session. Run open <app> first for app-scoped logs.`]}}function oe(e,t){return{executable:`adb`,args:[`-s`,e,`shell`,`pidof`,t],allowFailure:!0,timeoutMs:5e3}}async function se(e,t,n,r){let i=await e.appLogs.readRecent(n.sessionId,n.maxScanLines),a=m(i.text,{...n,path:i.path,exists:i.exists,lineNumberOffset:i.skippedLines,backend:`android`}),o=[],s=await le(e,t,n,r);if(s&&n.appBundleId){S(n.appBundleId);let c=await de(e,t,n.appBundleId,r);if(c){let e=m(c.text,{...n,path:`${i.path} (adb logcat recovery)`,exists:!0,backend:`android`});e.entries.length>0&&(a=v(e,a,n.maxEntries),o.push(s.reason===`stale-active`?`Session app log stream was still bound to prior Android PID ${s.trackedPid}. Recovered recent Android HTTP entries from adb logcat for PID set ${c.pids.join(`, `)}.`:`Session app log stream was inactive. Recovered recent Android HTTP entries from adb logcat for PID set ${c.pids.join(`, `)}.`))}}return n.appLogSnapshot?n.appLogSnapshot.state!==`active`&&o.length===0&&o.push(`Session app log stream is inactive. Run logs clear --restart, reproduce the request window again, then rerun network dump.`):o.push(`Capture uses the session app log file. For fresh traffic, run logs clear --restart before reproducing requests.`),a.entries.length===0&&o.push(`No HTTP(s) entries were found in recent session app logs.`),Object.freeze({source:`app-log`,backend:`android`,dump:a,notes:Object.freeze(o)})}async function ce(e,t,n){n.throwIfAborted();try{let r=await e.commands.run(t,n);return n.throwIfAborted(),r}catch{n.throwIfAborted();return}}async function le(e,t,n,r){if(!n.appBundleId||n.appLogSnapshot?.state===void 0)return;if(n.appLogSnapshot.state!==`active`)return{reason:`inactive`};let i=ue(await e.appLogs.readProcessMarker(n.sessionId));if(!i)return;let a=await fe(e,t.id,n.appBundleId,r);if(!(!a||a===i))return{reason:`stale-active`,trackedPid:i}}function ue(e){if(e.status===`decoded`)return/(?:^|\s)--pid\s+(\d+)(?:\s|$)/.exec(e.marker.command)?.[1]}async function de(e,t,n,r){let i=await fe(e,t.id,n,r),a=await ce(e,{executable:`adb`,args:[`-s`,t.id,`logcat`,`-d`,`-v`,`time`,`-t`,`4000`],allowFailure:!0,timeoutMs:3e3},r);if(!a||a.exitCode!==0||!a.stdout.trim())return;let o=pe(a.stdout,n,i);if(o.length===0)return;let s=new Set(o),c=a.stdout.split(`
1
+ import{_ as e}from"./sdk-contracts.js";import{Et as t,G as n,U as r,V as i,W as a,dt as o,ft as s,gt as c,lt as l,nt as u,rt as d,st as f,ut as p}from"./sdk-batch-runner.js";import{C as ee}from"./sdk-device.js";import{a as m,i as h,n as g,o as _,p as te,r as ne,t as re,v,x as ie}from"./src3.js";import{readAndroidAppState as ae}from"./app-state.js";import y from"node:path";function b(t){if(!/^[a-zA-Z0-9._:-]+$/.test(t))throw new e(`INVALID_ARGS`,`Invalid Android package name for logs: ${t}`)}const x=Object.freeze({resourceKind:d,version:1,encode:e=>({...e}),decode:e=>e.transport!==`android-logcat-local`&&e.transport!==`android-logcat-transport-composed`||!se(e.outputPath)||!se(e.pidPath)?{status:`invalid`,message:`Invalid Android app-log descriptor`}:{status:`decoded`,descriptor:Object.freeze({transport:e.transport,outputPath:e.outputPath,pidPath:e.pidPath})}});function oe(e){let t=x.decode(e.descriptor);if(t.status!==`decoded`)throw TypeError(t.message);return v({resourceKind:d,sessionId:e.sessionId,device:{id:e.device.id,family:`android`,kind:e.device.kind,...e.device.target===void 0?{}:{target:e.device.target}},owner:e.owner,fence:e.fence,lifecycle:`open`,descriptor:ie(x,t.descriptor)})}function se(e){return typeof e==`string`&&e.trim().length>0}function ce(e){return m(e,{family:`android`,backend:`android`,label:`Android`,codec:x,startUnavailableHint:`The selected Android transport cannot start a background adb logcat stream.`,cleanupFailureMessage:`Android app-log cleanup did not settle every owned resource`,doctor:async({host:e,device:t,signal:n},r)=>await le(e,t.id,r,n),validateStart:({input:e})=>b(e.appBundleId),process:async({host:e,device:t,input:n})=>({resolvePid:async r=>await _(e,ue(t.id,n.appBundleId),r),command:e=>({kind:`android-adb`,serial:t.id,args:[`logcat`,`-v`,`time`,`--pid`,e],options:{allowFailure:!0}})}),descriptor:({artifacts:e,transport:t})=>({transport:t.mode===`transport-composed`?`android-logcat-transport-composed`:`android-logcat-local`,...e}),envelope:({input:e,device:t,owner:n,descriptor:r})=>oe({sessionId:e.sessionId,device:t,owner:n,fence:e.fence,descriptor:r})})}async function le(e,t,n,r){let i={};return i.adbAvailable=await h(async()=>ne(await e.commands.run({executable:`adb`,args:[`-s`,t,`shell`,`echo`,`ok`],allowFailure:!0,timeoutMs:1e3},r)),r),n&&(i.androidPidVisible=await h(async()=>!!await _(e,ue(t,n),r),r)),{backend:`android`,checks:i,notes:n?[]:[`No app bundle is tracked in this session. Run open <app> first for app-scoped logs.`]}}function ue(e,t){return{executable:`adb`,args:[`-s`,e,`shell`,`pidof`,t],allowFailure:!0,timeoutMs:5e3}}async function de(e,t,n,r){let i=await e.appLogs.readRecent(n.sessionId,n.maxScanLines),a=g(i.text,{...n,path:i.path,exists:i.exists,lineNumberOffset:i.skippedLines,backend:`android`}),o=[],s=await pe(e,t,n,r);if(s&&n.appBundleId){b(n.appBundleId);let c=await he(e,t,n.appBundleId,r);if(c){let e=g(c.text,{...n,path:`${i.path} (adb logcat recovery)`,exists:!0,backend:`android`});e.entries.length>0&&(a=re(e,a,n.maxEntries),o.push(s.reason===`stale-active`?`Session app log stream was still bound to prior Android PID ${s.trackedPid}. Recovered recent Android HTTP entries from adb logcat for PID set ${c.pids.join(`, `)}.`:`Session app log stream was inactive. Recovered recent Android HTTP entries from adb logcat for PID set ${c.pids.join(`, `)}.`))}}return n.appLogSnapshot?n.appLogSnapshot.state!==`active`&&o.length===0&&o.push(`Session app log stream is inactive. Run logs clear --restart, reproduce the request window again, then rerun network dump.`):o.push(`Capture uses the session app log file. For fresh traffic, run logs clear --restart before reproducing requests.`),a.entries.length===0&&o.push(`No HTTP(s) entries were found in recent session app logs.`),Object.freeze({source:`app-log`,backend:`android`,dump:a,notes:Object.freeze(o)})}async function fe(e,t,n){n.throwIfAborted();try{let r=await e.commands.run(t,n);return n.throwIfAborted(),r}catch{n.throwIfAborted();return}}async function pe(e,t,n,r){if(!n.appBundleId||n.appLogSnapshot?.state===void 0)return;if(n.appLogSnapshot.state!==`active`)return{reason:`inactive`};let i=me(await e.appLogs.readProcessMarker(n.sessionId));if(!i)return;let a=await S(e,t.id,n.appBundleId,r);if(!(!a||a===i))return{reason:`stale-active`,trackedPid:i}}function me(e){if(e.status===`decoded`)return/(?:^|\s)--pid\s+(\d+)(?:\s|$)/.exec(e.marker.command)?.[1]}async function he(e,t,n,r){let i=await S(e,t.id,n,r),a=await fe(e,{executable:`adb`,args:[`-s`,t.id,`logcat`,`-d`,`-v`,`time`,`-t`,`4000`],allowFailure:!0,timeoutMs:3e3},r);if(!a||a.exitCode!==0||!a.stdout.trim())return;let o=ge(a.stdout,n,i);if(o.length===0)return;let s=new Set(o),c=a.stdout.split(`
2
2
  `).filter(e=>{if(!e.trim())return!1;if(e.includes(n))return!0;let t=/\(\s*(\d+)\)\s*:/.exec(e)?.[1];return!!(t&&s.has(t))}).join(`
3
- `);return c.trim()?{text:c,pids:o}:void 0}async function fe(e,t,n,r){let i=await ce(e,{executable:`adb`,args:[`-s`,t,`shell`,`pidof`,n],allowFailure:!0},r);if(!i)return;let a=i.stdout.trim().split(/\s+/)[0];return a&&/^\d+$/.test(a)?a:void 0}function pe(e,t,n){let r=new Set(n?[n]:[]),i=t.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`),a=[RegExp(`\\bStart proc\\s+(\\d+):${i}(?:\\b|/)`,`i`),RegExp(`\\b(\\d+):${i}(?:\\b|/)`,`i`),RegExp(`${i}.*?\\bpid\\s*[=:]?\\s*(\\d+)\\b`,`i`),RegExp(`\\bpid\\s*[=:]?\\s*(\\d+)\\b.*${i}`,`i`)];for(let n of e.split(`
4
- `))if(n.includes(t))for(let e of a){let t=e.exec(n)?.[1];t&&/^\d+$/.test(t)&&r.add(t)}return Object.freeze([...r])}const me=/^(?:\/sdcard|\/data\/local\/tmp)\/agent-device-recording-\d{1,20}\.mp4$/,he=/^(?:\/sdcard|\/data\/local\/tmp)\/agent-device-recording-active\.json$/;function ge(e){return ye(e)&&be(e)&&xe(e)}function _e(e){if(!w(e))return!1;let t=e;return Se(t)&&Ce(t)&&we(t)&&Te(t)&&(t.completion===void 0||je(t))}function ve(e,t){return Me(e,t)&&Ne(e,t.outputPath,t.clientOutputPath)}function ye(e){return e.backend===`adb-screenrecord`&&typeof e.manifestPath==`string`&&he.test(e.manifestPath)&&typeof e.outputPath==`string`}function be(e){return(e.clientOutputPath===void 0||typeof e.clientOutputPath==`string`)&&T(e.scope)&&typeof e.showTouches==`boolean`&&typeof e.recordOnlySession==`boolean`}function xe(e){return E(e.transportMode)&&Pe(e.exportQuality)&&D(e.activeSessionApp)}function Se(e){return e.version===1&&e.resourceKind===`screen-recording`&&typeof e.fenceToken==`string`&&Number.isInteger(e.fenceGeneration)&&typeof e.sessionId==`string`&&typeof e.deviceId==`string`&&Number.isFinite(e.startedAt)}function Ce(e){return typeof e.outputPath==`string`&&(e.clientOutputPath===void 0||typeof e.clientOutputPath==`string`)&&T(e.scope)&&typeof e.showTouches==`boolean`&&typeof e.recordOnlySession==`boolean`}function we(e){return D(e.activeSessionApp)&&Pe(e.exportQuality)&&E(e.transportMode)&&(e.pendingRemotePath===void 0||Fe(e.pendingRemotePath))}function Te(e){return Array.isArray(e.chunks)&&e.chunks.every(Ee)&&(e.chunks.length>0||e.pendingRemotePath!==void 0)&&(e.completion===void 0||De(e.completion))}function Ee(e,t){if(!w(e))return!1;let n=e;return n.index===t+1&&Fe(n.remotePath)&&O(n.remotePid)&&O(n.remoteStartTime)}function De(e){if(!w(e))return!1;let t=e;return Oe(t)&&ke(t)&&(t.chunks===void 0||t.chunks.every(Ae))}function Oe(e){return typeof e.backend==`string`&&typeof e.outPath==`string`&&(e.clientOutPath===void 0||typeof e.clientOutPath==`string`)&&Number.isFinite(e.startedAt)&&Number.isFinite(e.completedAt)}function ke(e){return T(e.scope)&&typeof e.showTouches==`boolean`&&typeof e.recordOnlySession==`boolean`&&D(e.activeSessionApp)}function Ae(e,t){return e.index===t+1&&typeof e.path==`string`&&(e.clientOutPath===void 0||typeof e.clientOutPath==`string`)}function je(e){let t=e.completion;return t!==void 0&&Me(t,e)&&t.startedAt===e.startedAt&&Ne(t,e.outputPath,e.clientOutputPath,e.chunks.length)}function Me(e,t){return e.backend===`adb screenrecord`&&e.outPath===t.outputPath&&e.clientOutPath===t.clientOutputPath&&e.scope===t.scope&&e.showTouches===t.showTouches&&e.recordOnlySession===t.recordOnlySession&&Ie(e.activeSessionApp,t.activeSessionApp)}function Ne(e,t,n,r=e.chunks===void 0?1:e.chunks.length){return r===1?e.chunks===void 0:e.chunks?.length===r&&e.chunks.every((e,r)=>e.path===k(t,r+1)&&e.clientOutPath===(n===void 0?void 0:k(n,r+1)))}function w(e){return typeof e==`object`&&!!e}function T(e){return e===`app`||e===`device`||e===`system`}function E(e){return e===`local`||e===`transport-composed`}function Pe(e){return e===void 0||e===`medium`||e===`high`}function D(e){return e===void 0||w(e)&&typeof e.bundleId==`string`&&(e.name===void 0||typeof e.name==`string`)}function Fe(e){return typeof e==`string`&&me.test(e)}function O(e){return typeof e==`string`&&/^\d+$/.test(e)}function Ie(e,t){return JSON.stringify(e)===JSON.stringify(t)}function k(e,t){if(t===1)return e;let n=e.lastIndexOf(`.`),r=n>e.lastIndexOf(`/`)?e.slice(0,n):e,i=n>e.lastIndexOf(`/`)?e.slice(n):`.mp4`;return`${r}.part-${String(t).padStart(3,`0`)}${i}`}const A=Object.freeze({resourceKind:s,version:1,encode:e=>({...e}),decode:e=>ge(e)?{status:`decoded`,descriptor:Object.freeze({backend:`adb-screenrecord`,manifestPath:e.manifestPath,outputPath:e.outputPath,...e.clientOutputPath===void 0?{}:{clientOutputPath:e.clientOutputPath},scope:e.scope,showTouches:e.showTouches,recordOnlySession:e.recordOnlySession,transportMode:e.transportMode,...e.activeSessionApp===void 0?{}:{activeSessionApp:e.activeSessionApp},...e.exportQuality===void 0?{}:{exportQuality:e.exportQuality}})}:{status:`invalid`,message:`Invalid Android screen-recording descriptor`}});function j(e,t,n,r,i,a=`local`){return Object.freeze({version:1,resourceKind:`screen-recording`,fenceToken:t.fence.token,fenceGeneration:t.fence.generation,sessionId:t.sessionId,deviceId:e.id,startedAt:n,outputPath:t.outputPath,...t.clientOutputPath===void 0?{}:{clientOutputPath:t.clientOutputPath},scope:t.scope,showTouches:t.showTouches,recordOnlySession:t.recordOnlySession,...t.activeSessionApp===void 0?{}:{activeSessionApp:t.activeSessionApp},...t.exportQuality===void 0?{}:{exportQuality:t.exportQuality},chunks:r,...i===void 0?{}:{pendingRemotePath:i},transportMode:a})}function Le(e,t){return Object.freeze({...e,completion:t})}function M(e){try{let t=e&&JSON.parse(e);return _e(t)?t:void 0}catch{return}}function Re(e,t,n){return e.deviceId===t.id&&e.deviceId===n.device.id&&e.fenceToken===n.fence.token&&e.fenceGeneration===n.fence.generation&&e.sessionId===n.sessionId}function ze(e,t){return e.outputPath===t.outputPath&&e.clientOutputPath===t.clientOutputPath&&e.scope===t.scope&&e.showTouches===t.showTouches&&e.recordOnlySession===t.recordOnlySession&&JSON.stringify(e.activeSessionApp)===JSON.stringify(t.activeSessionApp)&&e.exportQuality===t.exportQuality&&e.transportMode===t.transportMode&&(e.completion===void 0||ve(e.completion,t))}const Be=1e4,Ve=1e3;var N=class extends Error{constructor(e){super(`Android screenrecord launch rollback could not be confirmed`,{cause:e})}};function P(e,t=Date.now()){return[...new Set(e?[e,`/sdcard`,`/data/local/tmp`]:[`/sdcard`,`/data/local/tmp`])].map(e=>`${e}/agent-device-recording-${t}.mp4`)}async function He(e,t,n,r){let i;try{if(i=(await e.start({remotePath:t,quality:n.exportQuality??`medium`},r)).process,!/^\d+$/.test(i.pid)||!/^\d+$/.test(i.startTime)||i.remotePath!==t)throw Error(`Android screenrecord returned an invalid process identity`);if(!await Ke(e,t,i,r))throw Error(`Android screenrecord did not begin producing frames`);return{index:1,remotePath:t,remotePid:i.pid,remoteStartTime:i.startTime}}catch(t){throw i&&Ue(i)&&!await qe(e,i)?new N(t):r?.aborted?r.reason:t}}function Ue(e){return/^\d+$/.test(e.pid)&&/^\d+$/.test(e.startTime)&&e.remotePath.length>0}async function F(e,t){let n=!1,r;for(let i of[...t].reverse())try{n=await R(e,i)||n}catch(e){r??=e}if(r)throw r;return n}async function We(e,t){for(let n of t){let t;for(let r=0;r<3;r+=1){let i=await e.size(n.remotePath);if(typeof i==`number`&&i>0&&i===t)break;if(t=typeof i==`number`&&i>0?i:void 0,r===2)throw Error(`Android recording artifact is not stable: ${n.remotePath}`);await new Promise(e=>setTimeout(e,250))}}}async function Ge(e,t,n,r){let i=[];for(let[a,o]of t.entries()){let t=a===0?n:B(n,a+1);await Je(e,o.remotePath,t);let s=a===0||r===void 0?r:B(r,a+1);i.push({index:a+1,path:t,...s===void 0?{}:{clientOutPath:s}})}return Object.freeze(i)}async function I(e,t){let n;for(let r of t)try{if(!await e.remove(r.remotePath))throw Error(`failed to remove Android recording artifact: ${r.remotePath}`)}catch(e){n??=e}if(n)throw n}async function L(e,t){try{await F(e,t)}finally{await I(e,t)}}async function Ke(e,t,n,r){for(let i=0;i<3;i+=1){if(r?.throwIfAborted(),await e.exists(t,r)===!0)return!0;if(await e.inspect(n,r)!==`owned-alive`)return!1;i<2&&await new Promise(e=>setTimeout(e,250))}return!0}async function qe(e,t){try{let n=await e.stop(t,{force:!0});return(n===`stopped`||n===`already-missing`)&&await e.remove(t.remotePath)}catch{return!1}}async function R(e,t){if(!t)return!1;let n={pid:t.remotePid,remotePath:t.remotePath,startTime:t.remoteStartTime},r=await e.stop(n);if(r===`already-missing`)return!0;if(r===`ownership-lost`)throw Error(`Android screenrecord ownership could not be confirmed for pid ${t.remotePid}`);if(await Ye(e,n))return!1;let i=await e.stop(n,{force:!0});if(i===`stopped`||i===`already-missing`)return!1;throw Error(`failed to stop Android screenrecord pid ${t.remotePid}`)}async function Je(e,t,n){for(let r=0;r<3;r+=1){let i=await e.pullPlayable({remotePath:t,outputPath:n});if(i.exitCode===0&&i.playable)return;r+1<3&&await z(1e3)}throw Error(`failed to retrieve playable Android recording`)}async function Ye(e,t){for(let n=0;n<=Be;n+=Ve){let r=await e.inspect(t);if(r===`missing`)return!0;if(r===`ownership-lost`)throw Error(`Android screenrecord ownership could not be confirmed for pid ${t.pid}`);n<Be&&await z(Ve)}return!1}function z(e){return new Promise(t=>setTimeout(t,e))}function B(e,t){let n=x.parse(e);return x.join(n.dir,`${n.name}.part-${String(t).padStart(3,`0`)}${n.ext||`.mp4`}`)}async function Xe(e){let{transport:t,device:n,input:r,startedAt:i,signal:a,prepareOutput:o}=e;await $e(t,n),await o();let s;for(let e of P(void 0)){let o=t.manifestPathFor(e);await H(t,o,j(n,r,i,[],e,t.mode),a);let c;try{c=await He(t,e,r,a)}catch(e){if(a.aborted)throw await Ze(t,o,e),a.reason;await ot(t,o,e),s=e;continue}try{await H(t,o,j(n,r,i,[c],void 0,t.mode),a)}catch(e){throw await Qe(t,o,c),e}return{chunk:c,manifestPath:o}}throw s??Error(`Android screenrecord did not begin producing frames`)}async function Ze(e,t,n){n instanceof N||await U(e,t).catch(()=>{})}async function Qe(e,t,n){try{await L(e,[n])}catch{return}await U(e,t).catch(()=>{})}async function $e(e,t){let n=(await et(e)).flatMap(n=>tt(n,t,e.mode));for(let t of n)await at(e,t.evidence,t.manifestPath)}async function et(e){return await Promise.all(P(void 0).map(async t=>{let n=e.manifestPathFor(t);return{manifestPath:n,read:await e.readManifest(n)}}))}function tt(e,t,n){if(e.read.status===`missing`)return[];if(e.read.status!==`read`)throw rt();let r=M(e.read.contents);if(!nt(r,t,n))throw it();return[{manifestPath:e.manifestPath,evidence:r}]}function nt(e,t,n){return e!==void 0&&e.completion!==void 0&&e.pendingRemotePath===void 0&&e.deviceId===t.id&&e.transportMode===n}function rt(){return Error(`Android screenrecord native recovery evidence is unavailable`)}function it(){return Error(`Android screenrecord native recovery evidence already exists`)}async function at(e,t,n){for(let n of t.chunks)if(await e.inspect({pid:n.remotePid,remotePath:n.remotePath,startTime:n.remoteStartTime})!==`missing`)throw Error(`Android screenrecord completed evidence cannot be safely retired`);if(await I(e,t.chunks),await U(e,n),(await e.readManifest(n)).status!==`missing`)throw Error(`Android screenrecord completed evidence removal could not be confirmed`)}async function V(e){let{transport:t,device:n,input:r,startedAt:i,chunks:a,manifestPath:o,preferredDir:s}=e,c;for(let e of P(s)){await H(t,o,j(n,r,i,a,e,t.mode));try{return await He(t,e,r)}catch(e){if(e instanceof N)throw e;try{await H(t,o,j(n,r,i,a,void 0,t.mode))}catch{throw new N(e)}c=e}}throw c??Error(`failed to start next Android recording chunk`)}async function ot(e,t,n){if(n instanceof N)throw n;try{await U(e,t)}catch{throw new N(n)}}async function H(e,t,n,r){await e.writeManifest({manifestPath:t,contents:JSON.stringify(n)},r)}async function U(e,t){if(!await e.removeManifest(t))throw Error(`failed to remove Android recording manifest: ${t}`)}function st(e,t){return Object.freeze({backend:`adb screenrecord`,outPath:e.outputPath,...e.clientOutputPath?{clientOutPath:e.clientOutputPath}:{},startedAt:t,scope:e.scope,showTouches:e.showTouches,recordOnlySession:e.recordOnlySession,...e.activeSessionApp?{activeSessionApp:e.activeSessionApp}:{},...e.exportQuality?{exportQuality:e.exportQuality}:{},gestureEvents:[]})}async function ct(e,t,n,r,i=!1){let a=n.length>1,o=await e.screenRecording.finalize.complete({outputPath:t.outPath,showTouches:a?!1:t.showTouches,gestureEvents:t.gestureEvents,exportQuality:t.exportQuality??`medium`,targetLabel:r}),s=[...i?[`Android adb screenrecord stopped before record stop, likely after reaching the 180s platform limit. The MP4 may be truncated; final interactions after the limit are not in the video.`]:[],...a?[`Android adb screenrecord is capped at 180s, so this recording was split into multiple MP4 chunks.`]:[]];return{status:`completed`,result:{backend:t.backend,outPath:t.outPath,...t.clientOutPath?{clientOutPath:t.clientOutPath}:{},startedAt:t.startedAt,completedAt:Date.now(),scope:t.scope,showTouches:t.showTouches,recordOnlySession:t.recordOnlySession,...t.activeSessionApp?{activeSessionApp:t.activeSessionApp}:{},...a?{chunks:n}:{},...s.length?{warning:s.join(` `)}:{},...o,...a&&t.showTouches&&t.gestureEvents.length>0?{overlayWarning:`touch overlay burn-in is skipped for chunked Android recordings; returning raw chunks plus gesture telemetry`}:{}}}}function lt(e){return{status:`cleanup-pending`,reason:`transport-failed`,message:e instanceof Error?e.message:String(e)}}async function ut(e){let t=await F(e.transport,e.evidence.chunks)||e.reachedLimit===!0;await We(e.transport,e.evidence.chunks);let n=await Ge(e.transport,e.evidence.chunks,e.recording.outPath,e.recording.clientOutPath),r=await ct(e.host,e.recording,n,`Android recording`,t);return await H(e.transport,e.manifestPath,Le(e.evidence,r.result)),await I(e.transport,e.evidence.chunks),r}async function dt(e,t,n){try{let r=t.pendingRemotePath,i=r===void 0?[]:(await e.findRunning(r)).map(e=>({index:t.chunks.length+1,remotePath:r,remotePid:e.pid,remoteStartTime:e.startTime}));if(await F(e,[...t.chunks,...i]),await I(e,t.chunks),r!==void 0&&!await e.remove(r))throw Error(`failed to remove Android recording artifact: ${r}`);return await U(e,n),{status:`cleaned`}}catch(e){return lt(e)}}async function ft(e){let{transport:t,device:n,envelope:r,descriptor:i}=e;if(i.transportMode!==t.mode)return{status:`transport-unavailable`};let a=await t.readManifest(i.manifestPath);if(a.status===`unavailable`)return{status:`transport-unavailable`};let o=a.status===`read`?M(a.contents):void 0;return o&&Re(o,n,r)&&ze(o,i)?{status:`matched`,evidence:o}:{status:`ownership-lost`}}async function pt(e){let t=await e.transport.readManifest(e.manifestPath);if(t.status!==`read`)return;let n=M(t.contents);return n&&mt(n,e)?n:void 0}function mt(e,t){return e.deviceId===t.deviceId&&e.sessionId===t.sessionId&&e.fenceToken===t.fence.token&&e.fenceGeneration===t.fence.generation}async function ht(e){let{host:t,transport:n,device:r,input:i}=e,a=A.decode(i.envelope.descriptor.body);if(a.status!==`decoded`)return W(`descriptor-invalid`);let o=await ft({transport:n,device:r,envelope:i.envelope,descriptor:a.descriptor});return o.status===`matched`?await _t({host:t,transport:n,device:r,input:i,descriptor:a.descriptor,evidence:o.evidence}):W(o.status===`transport-unavailable`?`transport-not-reattachable`:`ownership-fence-lost`)}async function gt(e){let t=A.decode(e.input.envelope.descriptor.body);if(t.status!==`decoded`)return{status:`cleanup-pending`,reason:`manual-recovery-required`};let n=await ft({transport:e.transport,device:e.device,envelope:e.input.envelope,descriptor:t.descriptor});return n.status===`matched`?await dt(e.transport,n.evidence,t.descriptor.manifestPath):n.status===`transport-unavailable`?{status:`cleanup-pending`,reason:`owner-unavailable`}:{status:`cleanup-pending`,reason:`ownership-fence-lost`}}async function _t(e){let{host:t,transport:n,device:r,input:i,descriptor:a,evidence:o}=e;if(o.completion!==void 0&&await vt(n,o))return{status:`completed`,result:o.completion};if(o.completion!==void 0)return W(`ownership-fence-lost`,`Android recording completed evidence still names a live or unverifiable recorder.`);if(o.pendingRemotePath!==void 0)return W(`transport-not-reattachable`,`Android recording launch was interrupted before its process identity was committed.`);let s=o.chunks.at(-1);if(!s)return{status:`missing`};let c=await n.inspect({pid:s.remotePid,remotePath:s.remotePath,startTime:s.remoteStartTime});if(c!==`owned-alive`&&await n.exists(s.remotePath)!==!0)return W(`transport-not-reattachable`,`Android recording process ended before its artifact could be recovered.`);let l=yt(i.envelope.sessionId,i.envelope.fence,a),u=!1;return{status:`active`,handle:g(st(l,o.startedAt),{finish:async e=>{let r=await ut({host:t,transport:n,evidence:o,manifestPath:a.manifestPath,recording:e,reachedLimit:c===`missing`});return u=!0,r},forceCleanup:async()=>u?{status:`cleaned`}:await gt({transport:n,device:r,input:i})})}}async function vt(e,t){try{for(let n of t.chunks)if(await e.inspect({pid:n.remotePid,remotePath:n.remotePath,startTime:n.remoteStartTime})!==`missing`)return!1;return!0}catch{return!1}}function yt(e,t,n){return{sessionId:e,outputPath:n.outputPath,...n.clientOutputPath===void 0?{}:{clientOutputPath:n.clientOutputPath},scope:n.scope,showTouches:n.showTouches,hideTouchesRequested:!1,recordOnlySession:n.recordOnlySession,...n.activeSessionApp===void 0?{}:{activeSessionApp:n.activeSessionApp},...n.exportQuality===void 0?{}:{exportQuality:n.exportQuality},fence:t}}function W(e,t){return{status:`unreattachable`,reason:e,...t===void 0?{}:{message:t}}}async function bt(e){let{host:t,device:n,owner:r,signal:i}=e,a=await t.screenRecording.android.resolve(n);return Object.freeze({screenRecordingStart:async e=>await xt({host:t,transport:a,device:n,owner:r,input:e,signal:i}),screenRecordingReattach:async e=>await ht({host:t,transport:a,device:n,input:e}),screenRecordingCleanup:async e=>await gt({transport:a,device:n,input:e})})}async function xt(e){let{host:t,transport:n,device:r,owner:i,input:a,signal:c}=e;c.throwIfAborted();let l=Date.now(),u=await Xe({transport:n,device:r,input:a,startedAt:l,signal:c,prepareOutput:async()=>await t.screenRecording.outputs.prepare(a.outputPath)}),d=u.manifestPath,f=[u.chunk],p,m,h,_=!1,v=()=>{p=setTimeout(()=>{m=b().catch(e=>{h=e})},17e4),p.unref?.()},b=async()=>{let e=f.at(-1);if(!e)throw Error(`Android recording has no active chunk`);let t=!1,i;try{i=await V({transport:n,device:r,input:a,startedAt:l,chunks:f,manifestPath:d,preferredDir:x.posix.dirname(e.remotePath)})}catch(o){await R(n,e),t=!0;try{i=await V({transport:n,device:r,input:a,startedAt:l,chunks:f,manifestPath:d,preferredDir:x.posix.dirname(e.remotePath)})}catch(e){throw e instanceof Error?e:o}}let o=[...f,{...i,index:f.length+1}];try{await H(n,d,j(r,a,l,o,void 0,n.mode))}catch(o){if(await L(n,[i]).catch(()=>{}),t)await H(n,d,j(r,a,l,f,i.remotePath,n.mode)).catch(()=>{});else try{await H(n,d,j(r,a,l,f,void 0,n.mode))}catch{await R(n,e).catch(()=>{}),await H(n,d,j(r,a,l,f,i.remotePath,n.mode)).catch(()=>{})}throw o}f=o,t||await R(n,e),v()};v();let S=g(st(a,l),{finish:async e=>{if(p&&clearTimeout(p),await m,h)throw h;let i=await ut({host:t,transport:n,evidence:j(r,a,l,f,void 0,n.mode),manifestPath:d,recording:e});return _=!0,i},forceCleanup:async()=>{if(p&&clearTimeout(p),_)return{status:`cleaned`};try{await m}catch(e){h=e}let e=await pt({transport:n,deviceId:r.id,sessionId:a.sessionId,fence:a.fence,manifestPath:d});return e?await dt(n,e,d):{status:`cleanup-pending`,reason:`ownership-fence-lost`}}});return Object.freeze({pendingHandle:new o(S),envelope:te({resourceKind:s,sessionId:a.sessionId,device:ee(r),owner:i,fence:a.fence,lifecycle:`open`,descriptor:y(A,{backend:`adb-screenrecord`,manifestPath:d,outputPath:a.outputPath,...a.clientOutputPath===void 0?{}:{clientOutputPath:a.clientOutputPath},scope:a.scope,showTouches:a.showTouches,recordOnlySession:a.recordOnlySession,...a.activeSessionApp===void 0?{}:{activeSessionApp:a.activeSessionApp},...a.exportQuality===void 0?{}:{exportQuality:a.exportQuality},transportMode:n.mode})})})}const G=12e4,St=1e3;async function K(e,t,n,r){return r.throwIfAborted(),t.kind===`emulator`&&(t.booted!==!0||!q(t))?await Ct(e,t,n,r):(t.booted!==!0&&await Dt(e,t.id,G,r),{...t,booted:!0})}async function Ct(e,t,n,r){await wt(e);let i=Ot(n),a=Tt(await e.deviceReadiness.androidEmulator.discover(i,r),t.name,n.serial),o=q(a)?a:void 0,s=o?void 0:e.deviceReadiness.androidEmulator.launch(a.name,n.headless);try{let t=o??await Et(e,a.name,i,n.serial,r);return await Dt(e,t.id,G,r),{...(await e.deviceReadiness.androidEmulator.discover(i,r)).find(e=>e.id===t.id)??t,name:a.name,booted:!0}}catch(t){throw s!==void 0&&r.aborted&&await e.deviceReadiness.androidEmulator.terminate(s),r.throwIfAborted(),t}}async function wt(t){if(await t.toolchains.prepare(`android`),!await t.commands.which(`adb`))throw new e(`TOOL_MISSING`,`adb not found in PATH`);if(!await t.commands.which(`emulator`))throw new e(`TOOL_MISSING`,`emulator not found in PATH`)}function Tt(t,n,r){let i=kt(t,n,r);if(i)return i;throw new e(`DEVICE_NOT_FOUND`,`No Android emulator AVD named ${n}`,{requestedAvdName:n,availableAvds:t.map(e=>e.name),hint:"Run `emulator -list-avds` and pass an existing AVD name to --device."})}async function Et(t,n,r,i,a){let o=t.clock.now()+G;for(;t.clock.now()<o;){let e=kt(await t.deviceReadiness.androidEmulator.discover(r,a),n,i);if(e&&q(e))return e;await t.clock.sleep(St,a)}throw new e(`COMMAND_FAILED`,`Android emulator did not appear in time`,{avdName:n,serial:i,timeoutMs:G})}async function Dt(t,n,r,i){let a=t.clock.now()+r;for(;t.clock.now()<a;){if((await t.commands.run({executable:`adb`,args:[`-s`,n,`shell`,`getprop`,`sys.boot_completed`],allowFailure:!0,timeoutMs:Math.min(1e4,Math.max(1e3,a-t.clock.now()))},i)).stdout.trim()===`1`)return;await t.clock.sleep(St,i)}throw new e(`COMMAND_FAILED`,`Android device failed to finish booting`,{serial:n,timeoutMs:r,reason:`ANDROID_BOOT_TIMEOUT`})}function Ot(e){return{platform:`android`,kind:`emulator`,...e.serial?{serial:e.serial}:{},...e.androidSerialAllowlist?{androidSerialAllowlist:[...e.androidSerialAllowlist]}:{}}}function kt(e,t,n){let r=At(t);return e.find(e=>e.platform===`android`&&e.kind===`emulator`&&At(e.name)===r&&(!n||!q(e)||e.id===n))}function q(e){return e.id.startsWith(`emulator-`)}function At(e){return e.toLowerCase().replace(/_/g,` `).replace(/\s+/g,` `).trim()}function jt(e){let{host:n,device:r,signal:i}=e,a=d({device:r,signal:i,resolveInteractor:n.localInteractors.resolve});return Object.freeze({resolveOpenTarget:async e=>await n.androidApplications.resolveOpenTarget(r,e),prepareApplicationOpen:async e=>{await K(n,r,{headless:!1},i)},openApplication:async e=>await Mt(n,a,e),applyRuntimeHints:async e=>await n.androidApplications.applyRuntimeHints(r,e),clearRuntimeHints:async e=>await n.androidApplications.clearRuntimeHints(r,e),closeApplication:async e=>{e.ensureReady&&await K(n,r,{headless:!1},i),await t({device:r,interactor:await a.resolveInteractor(e.execution,e.appBundleId),positionals:e.positionals})},finalizeApplicationClose:async e=>{await n.androidApplications.restoreTestIme(r,{stateDir:e.stateDir});let t=e.shutdownTarget&&r.kind===`emulator`?await n.deviceShutdown.android.shutdownTarget(r,i):void 0;return t===void 0?{}:{shutdown:t}},prepareAppleRunner:Nt,configureProviderPortReverse:Nt})}async function Mt(i,a,o){let s={};if(o.relaunch&&o.target){let e=Date.now();await t({device:a.device,interactor:await a.resolveInteractor(o.execution,o.appBundleId),positionals:[o.appBundleId??o.target]}),s.relaunchCloseDurationMs=J(e)}if(l(o.runtimeHints)){if(!o.applyRuntimeHints)throw new e(`COMMAND_FAILED`,`Runtime hint operation was not admitted for this open.`,{reason:`runtime-hints-operation-missing`});let t=Date.now();await o.applyRuntimeHints({appId:o.appBundleId,values:o.runtimeHints}),s.runtimeHintsDurationMs=J(t)}let c=Date.now();await n({device:a.device,interactor:await a.resolveInteractor(o.execution,o.appBundleId),positionals:o.positionals,appBundleId:o.appBundleId,execution:o.execution}),s.openDispatchDurationMs=J(c),o.enableTestIme&&await i.androidApplications.activateTestIme(a.device,{stateDir:o.stateDir});let u=r(o);if(u){let e=Date.now();await n({device:a.device,interactor:await a.resolveInteractor({...o.execution,clearAppState:void 0,launchConsole:void 0,launchArgs:void 0},o.appBundleId),positionals:[u],appBundleId:o.appBundleId,execution:{...o.execution,clearAppState:void 0,launchConsole:void 0,launchArgs:void 0}}),s.launchUrlDurationMs=J(e)}else s.launchUrlDurationMs=0;let d=await i.androidApplications.inferOpenedAppBundleId(a.device,o.target,o.appBundleId);return d&&await i.androidApplications.resetFramePerfStats(a.device,d),s.postOpenSettleDurationMs=0,{appBundleId:d,timing:s}}function J(e){return Math.max(0,Date.now()-e)}async function Nt(){throw new e(`UNSUPPORTED_OPERATION`,`This lifecycle operation is unavailable for Android.`)}async function Y(e,t,n,r,i){let a=r?void 0:await Rt(e,t,i);if(x.extname(n).toLowerCase()===`.aab`?await Lt(e,t,n,i):Z(await e.androidTools.installPackage(t,n,{replace:!0},i),`adb install failed`),r)return r;let o=[...await Rt(e,t,i)].filter(e=>!a?.has(e));return o.length===1?o[0]:void 0}async function Pt(e,t,n,r){let i=await X(e,t,[`uninstall`,n],r);if(i.exitCode===0)return;let a=`${i.stdout}\n${i.stderr}`.toLowerCase();a.includes(`unknown package`)||a.includes(`not installed`)||Z(i,`adb uninstall failed for ${n}`)}async function Ft(t,n,r,i){let a=r.payload,o=typeof a.action==`string`&&a.action.trim()?a.action.trim():`${r.appId}.TEST_PUSH`,s=[`shell`,`am`,`broadcast`,`-a`,o,`-p`,r.appId];typeof a.receiver==`string`&&a.receiver.trim()&&s.push(`-n`,a.receiver.trim());let c=a.extras??{};if(typeof c!=`object`||!c||Array.isArray(c))throw new e(`INVALID_ARGS`,`Android push payload extras must be an object`);let l=0;for(let[e,t]of Object.entries(c))e&&(zt(s,e,t),l+=1);return Z(await X(t,n,s,i),`adb push broadcast failed`),{action:o,extrasCount:l}}function It(e){let t=new Set([`com`,`android`,`google`,`app`,`apps`,`service`,`services`,`mobile`,`client`]),n=e.split(/[._-]+/).map(e=>e.trim().toLowerCase()).filter(Boolean),r=[...n].reverse().find(e=>!t.has(e))??n.at(-1)??e;return r.charAt(0).toUpperCase()+r.slice(1)}async function Lt(t,n,r,i){if(await t.androidTools.installBundle(n,r,`universal`,i))return;let a=await t.commands.which(`bundletool`),o=t.androidDeployment.bundletoolJar;if(!a&&!o)throw new e(`TOOL_MISSING`,`bundletool not found in PATH. Install bundletool or set AGENT_DEVICE_BUNDLETOOL_JAR.`);let s=a?`bundletool`:`java`,c=a?[]:[`-jar`,o],l=await t.temporaryFiles.create({prefix:`agent-device-aab-`,suffix:`.apks`}),u=l.path;try{Z(await t.commands.run({executable:s,args:[...c,`build-apks`,`--bundle`,r,`--output`,u,`--mode`,`universal`]},i),`bundletool build-apks failed`),Z(await t.commands.run({executable:s,args:[...c,`install-apks`,`--apks`,u,`--device-id`,n.id]},i),`bundletool install-apks failed`)}finally{await l[Symbol.asyncDispose]()}}async function Rt(e,t,n){let r=await X(e,t,[`shell`,`pm`,`list`,`packages`],n);return Z(r,`adb package inventory failed`),new Set(r.stdout.split(`
5
- `).map(e=>e.replace(`package:`,``).trim()).filter(Boolean))}function zt(t,n,r){if(typeof r==`string`)t.push(`--es`,n,r);else if(typeof r==`boolean`)t.push(`--ez`,n,String(r));else if(typeof r==`number`&&Number.isFinite(r))t.push(Number.isInteger(r)?`--ei`:`--ef`,n,String(r));else throw new e(`INVALID_ARGS`,`Unsupported Android broadcast extra type for "${n}". Use string, boolean, or number.`)}async function X(e,t,n,r,i=15e3){return await e.androidTools.runAdb(t,n,{timeoutMs:i,allowFailure:!0},r)}function Z(t,n){if(t.exitCode!==0)throw new e(`COMMAND_FAILED`,n,{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode})}const Bt=Object.freeze({available:!0});function Vt(e){let t=Gt(e);return Object.freeze({deployApp:t,materializeAppSource:t,deployMaterializedApp:t,sendPushNotification:t})}function Ht(e){let{host:t,device:n,signal:r}=e;return Vt(n).deployApp.available?Object.freeze({deployApp:async e=>await Ut(t,n,e,r),materializeAppSource:async e=>await t.androidDeployment.prepareArtifact(e,{signal:r}),deployMaterializedApp:async e=>await Wt(t,n,e,r),sendPushNotification:async e=>await Ft(t,n,e,r)}):Object.freeze({})}async function Ut(e,t,n,r){if(n.replaceExisting)return await e.androidDeployment.withInvalidatedAppResolutionCache(t,async()=>{t.booted!==!0&&await K(e,t,{headless:!1},r);let i=await e.androidDeployment.resolveAppPackage(t,n.app);await Pt(e,t,i,r);let a=await e.androidDeployment.prepareArtifact({source:{kind:`path`,path:n.appPath}},{resolveIdentity:!1,signal:r});try{return await Y(e,t,a.installablePath,void 0,r),{packageName:i,launchTarget:i}}finally{await a.cleanup()}});t.booted!==!0&&await K(e,t,{headless:!1},r);let i=await e.androidDeployment.prepareArtifact({source:{kind:`path`,path:n.appPath}},{resolveIdentity:!0,signal:r});try{let n=await Y(e,t,i.installablePath,i.packageName,r);return n?{packageName:n,appName:It(n),launchTarget:n}:{}}finally{await i.cleanup()}}async function Wt(t,n,r,i){let a=await Y(t,n,r.artifact.installablePath,r.artifact.packageName,i);if(!a)throw new e(`COMMAND_FAILED`,`Installed Android app identity could not be resolved from the artifact or device state`);return{packageName:a,appName:It(a),launchTarget:a}}function Gt(e){return e.kind===`emulator`||e.kind===`device`?Bt:Object.freeze({available:!1,reason:`unsupported-device-kind`})}const Q=a(`android`),$=Object.freeze({available:!0}),Kt=Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`Headless boot is supported only for Android emulators.`}),qt=Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`Android appstate is supported only for Android emulators and devices.`}),Jt=Object.freeze({available:!1,reason:`unsupported-platform-leaf`,hint:`Apple runner preparation is supported only for Apple targets.`}),Yt=Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`open is supported only for Android emulators and devices.`}),Xt=Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`close is supported only for Android emulators and devices.`}),Zt=Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`Runtime hints are supported only for Android emulators and devices.`}),Qt=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Port reverse is supported only by an owning provider runtime.`}),$t=Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`shutdown is supported only for Apple simulators and Android emulators.`});function en(e){let t=tn(e),n=nn(e),r=rn(e);return i({resolveOpenTarget:t,prepareApplicationOpen:t,openApplication:t,applyRuntimeHints:r,clearRuntimeHints:r,closeApplication:n,finalizeApplicationClose:n,prepareAppleRunner:Jt,configureProviderPortReverse:Qt})}function tn(e){return e.kind===`emulator`||e.kind===`device`?$:Yt}function nn(e){return e.kind===`emulator`||e.kind===`device`?$:Xt}function rn(e){return e.kind===`emulator`||e.kind===`device`?$:Zt}function an(e){let t=ie(e),n=async e=>{let n=await t.inspectFacts(e),r=Vt(e);return Object.freeze({device:n.device,operations:{...n.operations,...r,appState:e.kind===`simulator`?qt:$,networkDump:$,screenRecordingStart:$,screenRecordingReattach:$,screenRecordingCleanup:$,ensureReady:$,bootTarget:$,bootTargetHeadless:e.kind===`emulator`?$:Kt,listApps:$,...en(e),shutdownTarget:e.kind===`emulator`?$:$t}})};return Object.freeze({owner:Q,ownsDevice:e=>e.platform===`android`,inspectFacts:n,bind:async r=>{let i=await t.bind(r),a=await n(r.device),o=await bt({host:e,device:r.device,owner:Q,signal:r.scope.signal});return Object.freeze({device:i.device,owner:Q,facts:a,operations:Object.freeze({...i.operations,...Ht({host:e,device:r.device,signal:r.scope.signal}),...a.operations.appState.available?{appState:async()=>await b(e.appState.android,r.device,r.scope.signal)}:{},networkDump:async t=>await se(e,r.device,t,r.scope.signal),...o,ensureReady:async t=>await K(e,r.device,{...t,headless:!1},r.scope.signal),bootTarget:async t=>await K(e,r.device,{...t,headless:!1},r.scope.signal),...a.operations.bootTargetHeadless.available?{bootTargetHeadless:async t=>await K(e,r.device,{...t,headless:!0},r.scope.signal)}:{},listApps:async t=>await e.appInventory.android.listApps(t.device,t.filter,r.scope.signal),...c(jt({host:e,device:r.device,signal:r.scope.signal}),a.operations),...a.operations.shutdownTarget.available?{shutdownTarget:async()=>await e.deviceShutdown.android.shutdownTarget(r.device,r.scope.signal)}:{}}),[Symbol.asyncDispose]:async()=>await i[Symbol.asyncDispose]()})},shutdown:async()=>await t.shutdown()})}export{an as createAndroidPlatformRuntime};
3
+ `);return c.trim()?{text:c,pids:o}:void 0}async function S(e,t,n,r){let i=await fe(e,{executable:`adb`,args:[`-s`,t,`shell`,`pidof`,n],allowFailure:!0},r);if(!i)return;let a=i.stdout.trim().split(/\s+/)[0];return a&&/^\d+$/.test(a)?a:void 0}function ge(e,t,n){let r=new Set(n?[n]:[]),i=t.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`),a=[RegExp(`\\bStart proc\\s+(\\d+):${i}(?:\\b|/)`,`i`),RegExp(`\\b(\\d+):${i}(?:\\b|/)`,`i`),RegExp(`${i}.*?\\bpid\\s*[=:]?\\s*(\\d+)\\b`,`i`),RegExp(`\\bpid\\s*[=:]?\\s*(\\d+)\\b.*${i}`,`i`)];for(let n of e.split(`
4
+ `))if(n.includes(t))for(let e of a){let t=e.exec(n)?.[1];t&&/^\d+$/.test(t)&&r.add(t)}return Object.freeze([...r])}const _e=/^(?:\/sdcard|\/data\/local\/tmp)\/agent-device-recording-\d{1,20}\.mp4$/,ve=/^(?:\/sdcard|\/data\/local\/tmp)\/agent-device-recording-active\.json$/;function ye(e){return Se(e)&&Ce(e)&&we(e)}function be(e){if(!T(e))return!1;let t=e;return Te(t)&&Ee(t)&&De(t)&&Oe(t)&&(t.completion===void 0||Pe(t))}function xe(e,t){return C(e,t)&&w(e,t.outputPath,t.clientOutputPath)}function Se(e){return e.backend===`adb-screenrecord`&&typeof e.manifestPath==`string`&&ve.test(e.manifestPath)&&typeof e.outputPath==`string`}function Ce(e){return(e.clientOutputPath===void 0||typeof e.clientOutputPath==`string`)&&E(e.scope)&&typeof e.showTouches==`boolean`&&typeof e.recordOnlySession==`boolean`}function we(e){return Fe(e.transportMode)&&Ie(e.exportQuality)&&D(e.activeSessionApp)}function Te(e){return e.version===1&&e.resourceKind===`screen-recording`&&typeof e.fenceToken==`string`&&Number.isInteger(e.fenceGeneration)&&typeof e.sessionId==`string`&&typeof e.deviceId==`string`&&Number.isFinite(e.startedAt)}function Ee(e){return typeof e.outputPath==`string`&&(e.clientOutputPath===void 0||typeof e.clientOutputPath==`string`)&&E(e.scope)&&typeof e.showTouches==`boolean`&&typeof e.recordOnlySession==`boolean`}function De(e){return D(e.activeSessionApp)&&Ie(e.exportQuality)&&Fe(e.transportMode)&&(e.pendingRemotePath===void 0||Le(e.pendingRemotePath))}function Oe(e){return Array.isArray(e.chunks)&&e.chunks.every(ke)&&(e.chunks.length>0||e.pendingRemotePath!==void 0)&&(e.completion===void 0||Ae(e.completion))}function ke(e,t){if(!T(e))return!1;let n=e;return n.index===t+1&&Le(n.remotePath)&&Re(n.remotePid)&&Re(n.remoteStartTime)}function Ae(e){if(!T(e))return!1;let t=e;return je(t)&&Me(t)&&(t.chunks===void 0||t.chunks.every(Ne))}function je(e){return typeof e.backend==`string`&&typeof e.outPath==`string`&&(e.clientOutPath===void 0||typeof e.clientOutPath==`string`)&&Number.isFinite(e.startedAt)&&Number.isFinite(e.completedAt)}function Me(e){return E(e.scope)&&typeof e.showTouches==`boolean`&&typeof e.recordOnlySession==`boolean`&&D(e.activeSessionApp)}function Ne(e,t){return e.index===t+1&&typeof e.path==`string`&&(e.clientOutPath===void 0||typeof e.clientOutPath==`string`)}function Pe(e){let t=e.completion;return t!==void 0&&C(t,e)&&t.startedAt===e.startedAt&&w(t,e.outputPath,e.clientOutputPath,e.chunks.length)}function C(e,t){return e.backend===`adb screenrecord`&&e.outPath===t.outputPath&&e.clientOutPath===t.clientOutputPath&&e.scope===t.scope&&e.showTouches===t.showTouches&&e.recordOnlySession===t.recordOnlySession&&ze(e.activeSessionApp,t.activeSessionApp)}function w(e,t,n,r=e.chunks===void 0?1:e.chunks.length){return r===1?e.chunks===void 0:e.chunks?.length===r&&e.chunks.every((e,r)=>e.path===Be(t,r+1)&&e.clientOutPath===(n===void 0?void 0:Be(n,r+1)))}function T(e){return typeof e==`object`&&!!e}function E(e){return e===`app`||e===`device`||e===`system`}function Fe(e){return e===`local`||e===`transport-composed`}function Ie(e){return e===void 0||e===`medium`||e===`high`}function D(e){return e===void 0||T(e)&&typeof e.bundleId==`string`&&(e.name===void 0||typeof e.name==`string`)}function Le(e){return typeof e==`string`&&_e.test(e)}function Re(e){return typeof e==`string`&&/^\d+$/.test(e)}function ze(e,t){return JSON.stringify(e)===JSON.stringify(t)}function Be(e,t){if(t===1)return e;let n=e.lastIndexOf(`.`),r=n>e.lastIndexOf(`/`)?e.slice(0,n):e,i=n>e.lastIndexOf(`/`)?e.slice(n):`.mp4`;return`${r}.part-${String(t).padStart(3,`0`)}${i}`}const O=Object.freeze({resourceKind:u,version:1,encode:e=>({...e}),decode:e=>ye(e)?{status:`decoded`,descriptor:Object.freeze({backend:`adb-screenrecord`,manifestPath:e.manifestPath,outputPath:e.outputPath,...e.clientOutputPath===void 0?{}:{clientOutputPath:e.clientOutputPath},scope:e.scope,showTouches:e.showTouches,recordOnlySession:e.recordOnlySession,transportMode:e.transportMode,...e.activeSessionApp===void 0?{}:{activeSessionApp:e.activeSessionApp},...e.exportQuality===void 0?{}:{exportQuality:e.exportQuality}})}:{status:`invalid`,message:`Invalid Android screen-recording descriptor`}});function k(e,t,n,r,i,a=`local`){return Object.freeze({version:1,resourceKind:`screen-recording`,fenceToken:t.fence.token,fenceGeneration:t.fence.generation,sessionId:t.sessionId,deviceId:e.id,startedAt:n,outputPath:t.outputPath,...t.clientOutputPath===void 0?{}:{clientOutputPath:t.clientOutputPath},scope:t.scope,showTouches:t.showTouches,recordOnlySession:t.recordOnlySession,...t.activeSessionApp===void 0?{}:{activeSessionApp:t.activeSessionApp},...t.exportQuality===void 0?{}:{exportQuality:t.exportQuality},chunks:r,...i===void 0?{}:{pendingRemotePath:i},transportMode:a})}function Ve(e,t){return Object.freeze({...e,completion:t})}function A(e){try{let t=e&&JSON.parse(e);return be(t)?t:void 0}catch{return}}function He(e,t,n){return e.deviceId===t.id&&e.deviceId===n.device.id&&e.fenceToken===n.fence.token&&e.fenceGeneration===n.fence.generation&&e.sessionId===n.sessionId}function Ue(e,t){return e.outputPath===t.outputPath&&e.clientOutputPath===t.clientOutputPath&&e.scope===t.scope&&e.showTouches===t.showTouches&&e.recordOnlySession===t.recordOnlySession&&JSON.stringify(e.activeSessionApp)===JSON.stringify(t.activeSessionApp)&&e.exportQuality===t.exportQuality&&e.transportMode===t.transportMode&&(e.completion===void 0||xe(e.completion,t))}const We=1e4,Ge=1e3;var j=class extends Error{constructor(e){super(`Android screenrecord launch rollback could not be confirmed`,{cause:e})}};function M(e,t=Date.now()){return[...new Set(e?[e,`/sdcard`,`/data/local/tmp`]:[`/sdcard`,`/data/local/tmp`])].map(e=>`${e}/agent-device-recording-${t}.mp4`)}async function N(e,t,n,r){let i;try{if(i=(await e.start({remotePath:t,quality:n.exportQuality??`medium`},r)).process,!/^\d+$/.test(i.pid)||!/^\d+$/.test(i.startTime)||i.remotePath!==t)throw Error(`Android screenrecord returned an invalid process identity`);if(!await Ye(e,t,i,r))throw Error(`Android screenrecord did not begin producing frames`);return{index:1,remotePath:t,remotePid:i.pid,remoteStartTime:i.startTime}}catch(t){throw i&&Ke(i)&&!await Xe(e,i)?new j(t):r?.aborted?r.reason:t}}function Ke(e){return/^\d+$/.test(e.pid)&&/^\d+$/.test(e.startTime)&&e.remotePath.length>0}async function P(e,t){let n=!1,r;for(let i of[...t].reverse())try{n=await L(e,i)||n}catch(e){r??=e}if(r)throw r;return n}async function qe(e,t){for(let n of t){let t;for(let r=0;r<3;r+=1){let i=await e.size(n.remotePath);if(typeof i==`number`&&i>0&&i===t)break;if(t=typeof i==`number`&&i>0?i:void 0,r===2)throw Error(`Android recording artifact is not stable: ${n.remotePath}`);await new Promise(e=>setTimeout(e,250))}}}async function Je(e,t,n,r){let i=[];for(let[a,o]of t.entries()){let t=a===0?n:z(n,a+1);await Ze(e,o.remotePath,t);let s=a===0||r===void 0?r:z(r,a+1);i.push({index:a+1,path:t,...s===void 0?{}:{clientOutPath:s}})}return Object.freeze(i)}async function F(e,t){let n;for(let r of t)try{if(!await e.remove(r.remotePath))throw Error(`failed to remove Android recording artifact: ${r.remotePath}`)}catch(e){n??=e}if(n)throw n}async function I(e,t){try{await P(e,t)}finally{await F(e,t)}}async function Ye(e,t,n,r){for(let i=0;i<3;i+=1){if(r?.throwIfAborted(),await e.exists(t,r)===!0)return!0;if(await e.inspect(n,r)!==`owned-alive`)return!1;i<2&&await new Promise(e=>setTimeout(e,250))}return!0}async function Xe(e,t){try{let n=await e.stop(t,{force:!0});return(n===`stopped`||n===`already-missing`)&&await e.remove(t.remotePath)}catch{return!1}}async function L(e,t){if(!t)return!1;let n={pid:t.remotePid,remotePath:t.remotePath,startTime:t.remoteStartTime},r=await e.stop(n);if(r===`already-missing`)return!0;if(r===`ownership-lost`)throw Error(`Android screenrecord ownership could not be confirmed for pid ${t.remotePid}`);if(await Qe(e,n))return!1;let i=await e.stop(n,{force:!0});if(i===`stopped`||i===`already-missing`)return!1;throw Error(`failed to stop Android screenrecord pid ${t.remotePid}`)}async function Ze(e,t,n){for(let r=0;r<3;r+=1){let i=await e.pullPlayable({remotePath:t,outputPath:n});if(i.exitCode===0&&i.playable)return;r+1<3&&await R(1e3)}throw Error(`failed to retrieve playable Android recording`)}async function Qe(e,t){for(let n=0;n<=We;n+=Ge){let r=await e.inspect(t);if(r===`missing`)return!0;if(r===`ownership-lost`)throw Error(`Android screenrecord ownership could not be confirmed for pid ${t.pid}`);n<We&&await R(Ge)}return!1}function R(e){return new Promise(t=>setTimeout(t,e))}function z(e,t){let n=y.parse(e);return y.join(n.dir,`${n.name}.part-${String(t).padStart(3,`0`)}${n.ext||`.mp4`}`)}async function $e(e){let{transport:t,device:n,input:r,startedAt:i,signal:a,prepareOutput:o}=e;await nt(t,n),await o();let s;for(let e of M(void 0)){let o=t.manifestPathFor(e);await V(t,o,k(n,r,i,[],e,t.mode),a);let c;try{c=await N(t,e,r,a)}catch(e){if(a.aborted)throw await et(t,o,e),a.reason;await lt(t,o,e),s=e;continue}try{await V(t,o,k(n,r,i,[c],void 0,t.mode),a)}catch(e){throw await tt(t,o,c),e}return{chunk:c,manifestPath:o}}throw s??Error(`Android screenrecord did not begin producing frames`)}async function et(e,t,n){n instanceof j||await H(e,t).catch(()=>{})}async function tt(e,t,n){try{await I(e,[n])}catch{return}await H(e,t).catch(()=>{})}async function nt(e,t){let n=(await rt(e)).flatMap(n=>it(n,t,e.mode));for(let t of n)await ct(e,t.evidence,t.manifestPath)}async function rt(e){return await Promise.all(M(void 0).map(async t=>{let n=e.manifestPathFor(t);return{manifestPath:n,read:await e.readManifest(n)}}))}function it(e,t,n){if(e.read.status===`missing`)return[];if(e.read.status!==`read`)throw ot();let r=A(e.read.contents);if(!at(r,t,n))throw st();return[{manifestPath:e.manifestPath,evidence:r}]}function at(e,t,n){return e!==void 0&&e.completion!==void 0&&e.pendingRemotePath===void 0&&e.deviceId===t.id&&e.transportMode===n}function ot(){return Error(`Android screenrecord native recovery evidence is unavailable`)}function st(){return Error(`Android screenrecord native recovery evidence already exists`)}async function ct(e,t,n){for(let n of t.chunks)if(await e.inspect({pid:n.remotePid,remotePath:n.remotePath,startTime:n.remoteStartTime})!==`missing`)throw Error(`Android screenrecord completed evidence cannot be safely retired`);if(await F(e,t.chunks),await H(e,n),(await e.readManifest(n)).status!==`missing`)throw Error(`Android screenrecord completed evidence removal could not be confirmed`)}async function B(e){let{transport:t,device:n,input:r,startedAt:i,chunks:a,manifestPath:o,preferredDir:s}=e,c;for(let e of M(s)){await V(t,o,k(n,r,i,a,e,t.mode));try{return await N(t,e,r)}catch(e){if(e instanceof j)throw e;try{await V(t,o,k(n,r,i,a,void 0,t.mode))}catch{throw new j(e)}c=e}}throw c??Error(`failed to start next Android recording chunk`)}async function lt(e,t,n){if(n instanceof j)throw n;try{await H(e,t)}catch{throw new j(n)}}async function V(e,t,n,r){await e.writeManifest({manifestPath:t,contents:JSON.stringify(n)},r)}async function H(e,t){if(!await e.removeManifest(t))throw Error(`failed to remove Android recording manifest: ${t}`)}function ut(e,t){return Object.freeze({backend:`adb screenrecord`,outPath:e.outputPath,...e.clientOutputPath?{clientOutPath:e.clientOutputPath}:{},startedAt:t,scope:e.scope,showTouches:e.showTouches,recordOnlySession:e.recordOnlySession,...e.activeSessionApp?{activeSessionApp:e.activeSessionApp}:{},...e.exportQuality?{exportQuality:e.exportQuality}:{},gestureEvents:[]})}async function dt(e,t,n,r,i=!1){let a=n.length>1,o=await e.screenRecording.finalize.complete({outputPath:t.outPath,showTouches:a?!1:t.showTouches,gestureEvents:t.gestureEvents,exportQuality:t.exportQuality??`medium`,targetLabel:r}),s=[...i?[`Android adb screenrecord stopped before record stop, likely after reaching the 180s platform limit. The MP4 may be truncated; final interactions after the limit are not in the video.`]:[],...a?[`Android adb screenrecord is capped at 180s, so this recording was split into multiple MP4 chunks.`]:[]];return{status:`completed`,result:{backend:t.backend,outPath:t.outPath,...t.clientOutPath?{clientOutPath:t.clientOutPath}:{},startedAt:t.startedAt,completedAt:Date.now(),scope:t.scope,showTouches:t.showTouches,recordOnlySession:t.recordOnlySession,...t.activeSessionApp?{activeSessionApp:t.activeSessionApp}:{},...a?{chunks:n}:{},...s.length?{warning:s.join(` `)}:{},...o,...a&&t.showTouches&&t.gestureEvents.length>0?{overlayWarning:`touch overlay burn-in is skipped for chunked Android recordings; returning raw chunks plus gesture telemetry`}:{}}}}function ft(e){return{status:`cleanup-pending`,reason:`transport-failed`,message:e instanceof Error?e.message:String(e)}}async function pt(e){let t=await P(e.transport,e.evidence.chunks)||e.reachedLimit===!0;await qe(e.transport,e.evidence.chunks);let n=await Je(e.transport,e.evidence.chunks,e.recording.outPath,e.recording.clientOutPath),r=await dt(e.host,e.recording,n,`Android recording`,t);return await V(e.transport,e.manifestPath,Ve(e.evidence,r.result)),await F(e.transport,e.evidence.chunks),r}async function mt(e,t,n){try{let r=t.pendingRemotePath,i=r===void 0?[]:(await e.findRunning(r)).map(e=>({index:t.chunks.length+1,remotePath:r,remotePid:e.pid,remoteStartTime:e.startTime}));if(await P(e,[...t.chunks,...i]),await F(e,t.chunks),r!==void 0&&!await e.remove(r))throw Error(`failed to remove Android recording artifact: ${r}`);return await H(e,n),{status:`cleaned`}}catch(e){return ft(e)}}async function ht(e){let{transport:t,device:n,envelope:r,descriptor:i}=e;if(i.transportMode!==t.mode)return{status:`transport-unavailable`};let a=await t.readManifest(i.manifestPath);if(a.status===`unavailable`)return{status:`transport-unavailable`};let o=a.status===`read`?A(a.contents):void 0;return o&&He(o,n,r)&&Ue(o,i)?{status:`matched`,evidence:o}:{status:`ownership-lost`}}async function gt(e){let t=await e.transport.readManifest(e.manifestPath);if(t.status!==`read`)return;let n=A(t.contents);return n&&_t(n,e)?n:void 0}function _t(e,t){return e.deviceId===t.deviceId&&e.sessionId===t.sessionId&&e.fenceToken===t.fence.token&&e.fenceGeneration===t.fence.generation}async function vt(e){let{host:t,transport:n,device:r,input:i}=e,a=O.decode(i.envelope.descriptor.body);if(a.status!==`decoded`)return U(`descriptor-invalid`);let o=await ht({transport:n,device:r,envelope:i.envelope,descriptor:a.descriptor});return o.status===`matched`?await bt({host:t,transport:n,device:r,input:i,descriptor:a.descriptor,evidence:o.evidence}):U(o.status===`transport-unavailable`?`transport-not-reattachable`:`ownership-fence-lost`)}async function yt(e){let t=O.decode(e.input.envelope.descriptor.body);if(t.status!==`decoded`)return{status:`cleanup-pending`,reason:`manual-recovery-required`};let n=await ht({transport:e.transport,device:e.device,envelope:e.input.envelope,descriptor:t.descriptor});return n.status===`matched`?await mt(e.transport,n.evidence,t.descriptor.manifestPath):n.status===`transport-unavailable`?{status:`cleanup-pending`,reason:`owner-unavailable`}:{status:`cleanup-pending`,reason:`ownership-fence-lost`}}async function bt(e){let{host:t,transport:n,device:r,input:i,descriptor:a,evidence:o}=e;if(o.completion!==void 0&&await xt(n,o))return{status:`completed`,result:o.completion};if(o.completion!==void 0)return U(`ownership-fence-lost`,`Android recording completed evidence still names a live or unverifiable recorder.`);if(o.pendingRemotePath!==void 0)return U(`transport-not-reattachable`,`Android recording launch was interrupted before its process identity was committed.`);let s=o.chunks.at(-1);if(!s)return{status:`missing`};let c=await n.inspect({pid:s.remotePid,remotePath:s.remotePath,startTime:s.remoteStartTime});if(c!==`owned-alive`&&await n.exists(s.remotePath)!==!0)return U(`transport-not-reattachable`,`Android recording process ended before its artifact could be recovered.`);let l=St(i.envelope.sessionId,i.envelope.fence,a),u=!1;return{status:`active`,handle:te(ut(l,o.startedAt),{finish:async e=>{let r=await pt({host:t,transport:n,evidence:o,manifestPath:a.manifestPath,recording:e,reachedLimit:c===`missing`});return u=!0,r},forceCleanup:async()=>u?{status:`cleaned`}:await yt({transport:n,device:r,input:i})})}}async function xt(e,t){try{for(let n of t.chunks)if(await e.inspect({pid:n.remotePid,remotePath:n.remotePath,startTime:n.remoteStartTime})!==`missing`)return!1;return!0}catch{return!1}}function St(e,t,n){return{sessionId:e,outputPath:n.outputPath,...n.clientOutputPath===void 0?{}:{clientOutputPath:n.clientOutputPath},scope:n.scope,showTouches:n.showTouches,hideTouchesRequested:!1,recordOnlySession:n.recordOnlySession,...n.activeSessionApp===void 0?{}:{activeSessionApp:n.activeSessionApp},...n.exportQuality===void 0?{}:{exportQuality:n.exportQuality},fence:t}}function U(e,t){return{status:`unreattachable`,reason:e,...t===void 0?{}:{message:t}}}async function Ct(e){let{host:t,device:n,owner:r,signal:i}=e,a=await t.screenRecording.android.resolve(n);return Object.freeze({screenRecordingStart:async e=>await wt({host:t,transport:a,device:n,owner:r,input:e,signal:i}),screenRecordingReattach:async e=>await vt({host:t,transport:a,device:n,input:e}),screenRecordingCleanup:async e=>await yt({transport:a,device:n,input:e})})}async function wt(e){let{host:t,transport:n,device:r,owner:i,input:a,signal:o}=e;o.throwIfAborted();let s=Date.now(),l=await $e({transport:n,device:r,input:a,startedAt:s,signal:o,prepareOutput:async()=>await t.screenRecording.outputs.prepare(a.outputPath)}),d=l.manifestPath,f=[l.chunk],p,m,h,g=!1,_=()=>{p=setTimeout(()=>{m=ne().catch(e=>{h=e})},17e4),p.unref?.()},ne=async()=>{let e=f.at(-1);if(!e)throw Error(`Android recording has no active chunk`);let t=!1,i;try{i=await B({transport:n,device:r,input:a,startedAt:s,chunks:f,manifestPath:d,preferredDir:y.posix.dirname(e.remotePath)})}catch(o){await L(n,e),t=!0;try{i=await B({transport:n,device:r,input:a,startedAt:s,chunks:f,manifestPath:d,preferredDir:y.posix.dirname(e.remotePath)})}catch(e){throw e instanceof Error?e:o}}let o=[...f,{...i,index:f.length+1}];try{await V(n,d,k(r,a,s,o,void 0,n.mode))}catch(o){if(await I(n,[i]).catch(()=>{}),t)await V(n,d,k(r,a,s,f,i.remotePath,n.mode)).catch(()=>{});else try{await V(n,d,k(r,a,s,f,void 0,n.mode))}catch{await L(n,e).catch(()=>{}),await V(n,d,k(r,a,s,f,i.remotePath,n.mode)).catch(()=>{})}throw o}f=o,t||await L(n,e),_()};_();let re=te(ut(a,s),{finish:async e=>{if(p&&clearTimeout(p),await m,h)throw h;let i=await pt({host:t,transport:n,evidence:k(r,a,s,f,void 0,n.mode),manifestPath:d,recording:e});return g=!0,i},forceCleanup:async()=>{if(p&&clearTimeout(p),g)return{status:`cleaned`};try{await m}catch(e){h=e}let e=await gt({transport:n,deviceId:r.id,sessionId:a.sessionId,fence:a.fence,manifestPath:d});return e?await mt(n,e,d):{status:`cleanup-pending`,reason:`ownership-fence-lost`}}});return Object.freeze({pendingHandle:new c(re),envelope:v({resourceKind:u,sessionId:a.sessionId,device:ee(r),owner:i,fence:a.fence,lifecycle:`open`,descriptor:ie(O,{backend:`adb-screenrecord`,manifestPath:d,outputPath:a.outputPath,...a.clientOutputPath===void 0?{}:{clientOutputPath:a.clientOutputPath},scope:a.scope,showTouches:a.showTouches,recordOnlySession:a.recordOnlySession,...a.activeSessionApp===void 0?{}:{activeSessionApp:a.activeSessionApp},...a.exportQuality===void 0?{}:{exportQuality:a.exportQuality},transportMode:n.mode})})})}const W=12e4,Tt=1e3;async function G(e,t,n,r){return r.throwIfAborted(),t.kind===`emulator`&&(t.booted!==!0||!K(t))?await Et(e,t,n,r):(t.booted!==!0&&await At(e,t.id,W,r),{...t,booted:!0})}async function Et(e,t,n,r){await Dt(e);let i=jt(n),a=Ot(await e.deviceReadiness.androidEmulator.discover(i,r),t.name,n.serial),o=K(a)?a:void 0,s=o?void 0:e.deviceReadiness.androidEmulator.launch(a.name,n.headless);try{let t=o??await kt(e,a.name,i,n.serial,r);return await At(e,t.id,W,r),{...(await e.deviceReadiness.androidEmulator.discover(i,r)).find(e=>e.id===t.id)??t,name:a.name,booted:!0}}catch(t){throw s!==void 0&&r.aborted&&await e.deviceReadiness.androidEmulator.terminate(s),r.throwIfAborted(),t}}async function Dt(t){if(await t.toolchains.prepare(`android`),!await t.commands.which(`adb`))throw new e(`TOOL_MISSING`,`adb not found in PATH`);if(!await t.commands.which(`emulator`))throw new e(`TOOL_MISSING`,`emulator not found in PATH`)}function Ot(t,n,r){let i=Mt(t,n,r);if(i)return i;throw new e(`DEVICE_NOT_FOUND`,`No Android emulator AVD named ${n}`,{requestedAvdName:n,availableAvds:t.map(e=>e.name),hint:"Run `emulator -list-avds` and pass an existing AVD name to --device."})}async function kt(t,n,r,i,a){let o=t.clock.now()+W;for(;t.clock.now()<o;){let e=Mt(await t.deviceReadiness.androidEmulator.discover(r,a),n,i);if(e&&K(e))return e;await t.clock.sleep(Tt,a)}throw new e(`COMMAND_FAILED`,`Android emulator did not appear in time`,{avdName:n,serial:i,timeoutMs:W})}async function At(t,n,r,i){let a=t.clock.now()+r;for(;t.clock.now()<a;){if((await t.commands.run({executable:`adb`,args:[`-s`,n,`shell`,`getprop`,`sys.boot_completed`],allowFailure:!0,timeoutMs:Math.min(1e4,Math.max(1e3,a-t.clock.now()))},i)).stdout.trim()===`1`)return;await t.clock.sleep(Tt,i)}throw new e(`COMMAND_FAILED`,`Android device failed to finish booting`,{serial:n,timeoutMs:r,reason:`ANDROID_BOOT_TIMEOUT`})}function jt(e){return{platform:`android`,kind:`emulator`,...e.serial?{serial:e.serial}:{},...e.androidSerialAllowlist?{androidSerialAllowlist:[...e.androidSerialAllowlist]}:{}}}function Mt(e,t,n){let r=q(t);return e.find(e=>e.platform===`android`&&e.kind===`emulator`&&q(e.name)===r&&(!n||!K(e)||e.id===n))}function K(e){return e.id.startsWith(`emulator-`)}function q(e){return e.toLowerCase().replace(/_/g,` `).replace(/\s+/g,` `).trim()}function Nt(e){let{host:t,device:n,signal:r}=e,o=i({device:n,signal:r,resolveInteractor:t.localInteractors.resolve});return Object.freeze({resolveOpenTarget:async e=>await t.androidApplications.resolveOpenTarget(n,e),prepareApplicationOpen:async e=>{await G(t,n,{headless:!1},r)},openApplication:async e=>await Pt(t,o,e),applyRuntimeHints:async e=>await t.androidApplications.applyRuntimeHints(n,e),clearRuntimeHints:async e=>await t.androidApplications.clearRuntimeHints(n,e),closeApplication:async e=>{e.ensureReady&&await G(t,n,{headless:!1},r),await a({device:n,interactor:await o.resolveInteractor(e.execution,e.appBundleId),positionals:e.positionals})},finalizeApplicationClose:async e=>{await t.androidApplications.restoreTestIme(n,{stateDir:e.stateDir});let i=e.shutdownTarget&&n.kind===`emulator`?await t.deviceShutdown.android.shutdownTarget(n,r):void 0;return i===void 0?{}:{shutdown:i}},prepareAppleRunner:Ft,configureProviderPortReverse:Ft})}async function Pt(t,i,o){let c={};if(o.relaunch&&o.target){let e=Date.now();await a({device:i.device,interactor:await i.resolveInteractor(o.execution,o.appBundleId),positionals:[o.appBundleId??o.target]}),c.relaunchCloseDurationMs=J(e)}if(s(o.runtimeHints)){if(!o.applyRuntimeHints)throw new e(`COMMAND_FAILED`,`Runtime hint operation was not admitted for this open.`,{reason:`runtime-hints-operation-missing`});let t=Date.now();await o.applyRuntimeHints({appId:o.appBundleId,values:o.runtimeHints}),c.runtimeHintsDurationMs=J(t)}let l=Date.now();await n({device:i.device,interactor:await i.resolveInteractor(o.execution,o.appBundleId),positionals:o.positionals,appBundleId:o.appBundleId,execution:o.execution}),c.openDispatchDurationMs=J(l),o.enableTestIme&&await t.androidApplications.activateTestIme(i.device,{stateDir:o.stateDir});let u=r(o);if(u){let e=Date.now();await n({device:i.device,interactor:await i.resolveInteractor({...o.execution,clearAppState:void 0,launchConsole:void 0,launchArgs:void 0},o.appBundleId),positionals:[u],appBundleId:o.appBundleId,execution:{...o.execution,clearAppState:void 0,launchConsole:void 0,launchArgs:void 0}}),c.launchUrlDurationMs=J(e)}else c.launchUrlDurationMs=0;let d=await t.androidApplications.inferOpenedAppBundleId(i.device,o.target,o.appBundleId);return d&&await t.androidApplications.resetFramePerfStats(i.device,d),c.postOpenSettleDurationMs=0,{appBundleId:d,timing:c}}function J(e){return Math.max(0,Date.now()-e)}async function Ft(){throw new e(`UNSUPPORTED_OPERATION`,`This lifecycle operation is unavailable for Android.`)}async function Y(e,t,n,r,i){let a=r?void 0:await Bt(e,t,i);if(y.extname(n).toLowerCase()===`.aab`?await zt(e,t,n,i):Z(await e.androidTools.installPackage(t,n,{replace:!0},i),`adb install failed`),r)return r;let o=[...await Bt(e,t,i)].filter(e=>!a?.has(e));return o.length===1?o[0]:void 0}async function It(e,t,n,r){let i=await X(e,t,[`uninstall`,n],r);if(i.exitCode===0)return;let a=`${i.stdout}\n${i.stderr}`.toLowerCase();a.includes(`unknown package`)||a.includes(`not installed`)||Z(i,`adb uninstall failed for ${n}`)}async function Lt(t,n,r,i){let a=r.payload,o=typeof a.action==`string`&&a.action.trim()?a.action.trim():`${r.appId}.TEST_PUSH`,s=[`shell`,`am`,`broadcast`,`-a`,o,`-p`,r.appId];typeof a.receiver==`string`&&a.receiver.trim()&&s.push(`-n`,a.receiver.trim());let c=a.extras??{};if(typeof c!=`object`||!c||Array.isArray(c))throw new e(`INVALID_ARGS`,`Android push payload extras must be an object`);let l=0;for(let[e,t]of Object.entries(c))e&&(Vt(s,e,t),l+=1);return Z(await X(t,n,s,i),`adb push broadcast failed`),{action:o,extrasCount:l}}function Rt(e){let t=new Set([`com`,`android`,`google`,`app`,`apps`,`service`,`services`,`mobile`,`client`]),n=e.split(/[._-]+/).map(e=>e.trim().toLowerCase()).filter(Boolean),r=[...n].reverse().find(e=>!t.has(e))??n.at(-1)??e;return r.charAt(0).toUpperCase()+r.slice(1)}async function zt(t,n,r,i){if(await t.androidTools.installBundle(n,r,`universal`,i))return;let a=await t.commands.which(`bundletool`),o=t.androidDeployment.bundletoolJar;if(!a&&!o)throw new e(`TOOL_MISSING`,`bundletool not found in PATH. Install bundletool or set AGENT_DEVICE_BUNDLETOOL_JAR.`);let s=a?`bundletool`:`java`,c=a?[]:[`-jar`,o],l=await t.temporaryFiles.create({prefix:`agent-device-aab-`,suffix:`.apks`}),u=l.path;try{Z(await t.commands.run({executable:s,args:[...c,`build-apks`,`--bundle`,r,`--output`,u,`--mode`,`universal`]},i),`bundletool build-apks failed`),Z(await t.commands.run({executable:s,args:[...c,`install-apks`,`--apks`,u,`--device-id`,n.id]},i),`bundletool install-apks failed`)}finally{await l[Symbol.asyncDispose]()}}async function Bt(e,t,n){let r=await X(e,t,[`shell`,`pm`,`list`,`packages`],n);return Z(r,`adb package inventory failed`),new Set(r.stdout.split(`
5
+ `).map(e=>e.replace(`package:`,``).trim()).filter(Boolean))}function Vt(t,n,r){if(typeof r==`string`)t.push(`--es`,n,r);else if(typeof r==`boolean`)t.push(`--ez`,n,String(r));else if(typeof r==`number`&&Number.isFinite(r))t.push(Number.isInteger(r)?`--ei`:`--ef`,n,String(r));else throw new e(`INVALID_ARGS`,`Unsupported Android broadcast extra type for "${n}". Use string, boolean, or number.`)}async function X(e,t,n,r,i=15e3){return await e.androidTools.runAdb(t,n,{timeoutMs:i,allowFailure:!0},r)}function Z(t,n){if(t.exitCode!==0)throw new e(`COMMAND_FAILED`,n,{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode})}const Ht=Object.freeze({available:!0});function Ut(e){let t=qt(e);return Object.freeze({deployApp:t,materializeAppSource:t,deployMaterializedApp:t,sendPushNotification:t})}function Wt(e){let{host:t,device:n,signal:r}=e;return Ut(n).deployApp.available?Object.freeze({deployApp:async e=>await Gt(t,n,e,r),materializeAppSource:async e=>await t.androidDeployment.prepareArtifact(e,{signal:r}),deployMaterializedApp:async e=>await Kt(t,n,e,r),sendPushNotification:async e=>await Lt(t,n,e,r)}):Object.freeze({})}async function Gt(e,t,n,r){if(n.replaceExisting)return await e.androidDeployment.withInvalidatedAppResolutionCache(t,async()=>{t.booted!==!0&&await G(e,t,{headless:!1},r);let i=await e.androidDeployment.resolveAppPackage(t,n.app);await It(e,t,i,r);let a=await e.androidDeployment.prepareArtifact({source:{kind:`path`,path:n.appPath}},{resolveIdentity:!1,signal:r});try{return await Y(e,t,a.installablePath,void 0,r),{packageName:i,launchTarget:i}}finally{await a.cleanup()}});t.booted!==!0&&await G(e,t,{headless:!1},r);let i=await e.androidDeployment.prepareArtifact({source:{kind:`path`,path:n.appPath}},{resolveIdentity:!0,signal:r});try{let n=await Y(e,t,i.installablePath,i.packageName,r);return n?{packageName:n,appName:Rt(n),launchTarget:n}:{}}finally{await i.cleanup()}}async function Kt(t,n,r,i){let a=await Y(t,n,r.artifact.installablePath,r.artifact.packageName,i);if(!a)throw new e(`COMMAND_FAILED`,`Installed Android app identity could not be resolved from the artifact or device state`);return{packageName:a,appName:Rt(a),launchTarget:a}}function qt(e){return e.kind===`emulator`||e.kind===`device`?Ht:Object.freeze({available:!1,reason:`unsupported-device-kind`})}const Q=t(`android`),$=Object.freeze({available:!0}),Jt=Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`Headless boot is supported only for Android emulators.`}),Yt=Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`Android appstate is supported only for Android emulators and devices.`}),Xt=Object.freeze({available:!1,reason:`unsupported-platform-leaf`,hint:`Apple runner preparation is supported only for Apple targets.`}),Zt=Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`open is supported only for Android emulators and devices.`}),Qt=Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`close is supported only for Android emulators and devices.`}),$t=Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`Runtime hints are supported only for Android emulators and devices.`}),en=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Port reverse is supported only by an owning provider runtime.`}),tn=Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`shutdown is supported only for Apple simulators and Android emulators.`}),nn=Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`snapshot is supported only for Android emulators and devices.`}),rn=Object.freeze({available:!1,reason:`unsupported-platform-leaf`,hint:`Re-run without --actions, or target an iOS simulator.`});function an(e){let t=on(e),n=sn(e),r=cn(e);return p({resolveOpenTarget:t,prepareApplicationOpen:t,openApplication:t,applyRuntimeHints:r,clearRuntimeHints:r,closeApplication:n,finalizeApplicationClose:n,prepareAppleRunner:Xt,configureProviderPortReverse:en})}function on(e){return e.kind===`emulator`||e.kind===`device`?$:Zt}function sn(e){return e.kind===`emulator`||e.kind===`device`?$:Qt}function cn(e){return e.kind===`emulator`||e.kind===`device`?$:$t}function ln(e){let t=ce(e),n=async e=>{let n=await t.inspectFacts(e),r=Ut(e);return Object.freeze({device:n.device,operations:{...n.operations,...r,appState:e.kind===`simulator`?Yt:$,networkDump:$,screenRecordingStart:$,screenRecordingReattach:$,screenRecordingCleanup:$,...l({capture:e.kind===`simulator`?nn:$,customActions:rn,withoutActiveApp:e.kind===`simulator`?nn:$}),ensureReady:$,bootTarget:$,bootTargetHeadless:e.kind===`emulator`?$:Jt,listApps:$,...an(e),shutdownTarget:e.kind===`emulator`?$:tn}})};return Object.freeze({owner:Q,ownsDevice:e=>e.platform===`android`,inspectFacts:n,bind:async r=>{let i=await t.bind(r),a=await n(r.device),s=await Ct({host:e,device:r.device,owner:Q,signal:r.scope.signal});return Object.freeze({device:i.device,owner:Q,facts:a,operations:Object.freeze({...i.operations,...Wt({host:e,device:r.device,signal:r.scope.signal}),...a.operations.appState.available?{appState:async()=>await ae(e.appState.android,r.device,r.scope.signal)}:{},networkDump:async t=>await de(e,r.device,t,r.scope.signal),...s,...a.operations.captureSnapshot.available?f({device:r.device,signal:r.scope.signal,resolveInteractor:e.localInteractors.resolve}):{},ensureReady:async t=>await G(e,r.device,{...t,headless:!1},r.scope.signal),bootTarget:async t=>await G(e,r.device,{...t,headless:!1},r.scope.signal),...a.operations.bootTargetHeadless.available?{bootTargetHeadless:async t=>await G(e,r.device,{...t,headless:!0},r.scope.signal)}:{},listApps:async t=>await e.appInventory.android.listApps(t.device,t.filter,r.scope.signal),...o(Nt({host:e,device:r.device,signal:r.scope.signal}),a.operations),...a.operations.shutdownTarget.available?{shutdownTarget:async()=>await e.deviceShutdown.android.shutdownTarget(r.device,r.scope.signal)}:{}}),[Symbol.asyncDispose]:async()=>await i[Symbol.asyncDispose]()})},shutdown:async()=>await t.shutdown()})}export{ln as createAndroidPlatformRuntime};
@@ -1 +1 @@
1
- import{C as e}from"./sdk-contracts.js";function t(e){return Object.freeze({canShutdownTarget:n,shutdownTarget:async(t,n)=>await r(e.commands,t,n)})}function n(e){return e.platform===`android`&&e.kind===`emulator`}async function r(t,n,r){if(n.booted===!1)return i();r.throwIfAborted();try{let e=await t.run({executable:`adb`,args:[`-s`,n.id,`emu`,`kill`],allowFailure:!0,timeoutMs:15e3},r);r.throwIfAborted();let i=e.exitCode??-1;return{success:i===0,exitCode:i,stdout:e.stdout,stderr:e.stderr}}catch(t){r.throwIfAborted();let n=e(t);return{success:!1,exitCode:-1,stdout:``,stderr:n.message,error:n}}}function i(){return{success:!0,exitCode:0,stdout:``,stderr:``}}export{t as createAndroidShutdownRuntime};
1
+ import{E as e}from"./sdk-contracts.js";function t(e){return Object.freeze({canShutdownTarget:n,shutdownTarget:async(t,n)=>await r(e.commands,t,n)})}function n(e){return e.platform===`android`&&e.kind===`emulator`}async function r(t,n,r){if(n.booted===!1)return i();r.throwIfAborted();try{let e=await t.run({executable:`adb`,args:[`-s`,n.id,`emu`,`kill`],allowFailure:!0,timeoutMs:15e3},r);r.throwIfAborted();let i=e.exitCode??-1;return{success:i===0,exitCode:i,stdout:e.stdout,stderr:e.stderr}}catch(t){r.throwIfAborted();let n=e(t);return{success:!1,exitCode:-1,stdout:``,stderr:n.message,error:n}}}function i(){return{success:!0,exitCode:0,stdout:``,stderr:``}}export{t as createAndroidShutdownRuntime};