agent-device 0.20.7 → 0.20.9

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 (209) hide show
  1. package/README.md +94 -31
  2. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.7.apk → agent-device-android-ime-helper-0.20.9.apk} +0 -0
  3. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.9.apk.sha256 +1 -0
  4. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.7.manifest.json → agent-device-android-ime-helper-0.20.9.manifest.json} +4 -4
  5. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.7.apk → agent-device-android-snapshot-helper-0.20.9.apk} +0 -0
  6. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.9.apk.sha256 +1 -0
  7. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.7.manifest.json → agent-device-android-snapshot-helper-0.20.9.manifest.json} +6 -6
  8. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.h +3 -0
  9. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.m +13 -7
  10. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +4 -112
  11. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +5 -1
  12. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+FlatSnapshotFiltering.swift +9 -1
  13. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+PrivateAXPresentation.swift +90 -0
  14. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+RecordingTests.swift +4 -0
  15. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +46 -10
  16. package/dist/src/agent-browser-tool.js +1 -1
  17. package/dist/src/agent-device-client.js +2 -2
  18. package/dist/src/android-adb.d.ts +5 -5
  19. package/dist/src/android-adb.js +1 -1
  20. package/dist/src/android.js +1 -1
  21. package/dist/src/app-helpers.js +1 -1
  22. package/dist/src/app-lifecycle.js +6 -7
  23. package/dist/src/app-lifecycle2.js +2 -2
  24. package/dist/src/app-log-reconnect.js +1 -1
  25. package/dist/src/app-log-runtime.js +3 -3
  26. package/dist/src/app-resolution.js +2 -2
  27. package/dist/src/app-state.js +2 -0
  28. package/dist/src/appearance.js +1 -0
  29. package/dist/src/apps.js +5 -5
  30. package/dist/src/artifacts.d.ts +1 -1
  31. package/dist/src/audio-probe.js +1 -1
  32. package/dist/src/backend-snapshot-options.js +1 -0
  33. package/dist/src/boot-diagnostics.js +2 -2
  34. package/dist/src/bounds.js +1 -0
  35. package/dist/src/byte-limit-stream.js +1 -0
  36. package/dist/src/cancel.js +1 -0
  37. package/dist/src/cli-config.js +1 -1
  38. package/dist/src/cli-help.js +25 -20
  39. package/dist/src/cli.js +6 -6
  40. package/dist/src/client-metro.js +1 -1
  41. package/dist/src/command-catalog.js +1 -0
  42. package/dist/src/command-metadata.js +1 -1
  43. package/dist/src/command-schema.js +1 -1
  44. package/dist/src/command-surface.js +1 -1
  45. package/dist/src/config.js +1 -0
  46. package/dist/src/connection-runtime.js +1 -1
  47. package/dist/src/connection.js +3 -3
  48. package/dist/src/contracts.js +1 -1
  49. package/dist/src/debug-symbols.js +1 -1
  50. package/dist/src/device-claim-inspection.js +1 -1
  51. package/dist/src/device-input-state.js +1 -1
  52. package/dist/src/device-ready.js +1 -0
  53. package/dist/src/device2.js +2 -2
  54. package/dist/src/dispatch.js +1 -0
  55. package/dist/src/entities.js +1 -1
  56. package/dist/src/find.js +1 -1
  57. package/dist/src/finders.js +1 -1
  58. package/dist/src/generic-settle.js +1 -1
  59. package/dist/src/generic.js +1 -1
  60. package/dist/src/handler-utils.js +1 -0
  61. package/dist/src/harmonyos.js +1 -1
  62. package/dist/src/hdc.js +1 -0
  63. package/dist/src/helper-package-install.js +1 -0
  64. package/dist/src/helper.js +2 -2
  65. package/dist/src/host-process.js +3 -2
  66. package/dist/src/ime-lifecycle.js +2 -9
  67. package/dist/src/ime-recovery-marker.js +1 -0
  68. package/dist/src/index.d.ts +35 -26
  69. package/dist/src/index.js +1 -1
  70. package/dist/src/input-actions.js +3 -3
  71. package/dist/src/input-actions2.js +1 -1
  72. package/dist/src/input-actions3.js +1 -1
  73. package/dist/src/install-artifact.js +1 -1
  74. package/dist/src/install-artifact2.js +1 -1
  75. package/dist/src/install-source2.js +1 -1
  76. package/dist/src/interaction-common.js +1 -0
  77. package/dist/src/interaction-runtime.js +1 -1
  78. package/dist/src/interaction-snapshot.js +1 -1
  79. package/dist/src/interaction.js +1 -1
  80. package/dist/src/interaction2.js +1 -0
  81. package/dist/src/interactor.js +2 -2
  82. package/dist/src/interactor2.js +1 -1
  83. package/dist/src/interactors.js +1 -0
  84. package/dist/src/internal/bin.js +1 -1
  85. package/dist/src/internal/daemon.js +4 -29
  86. package/dist/src/internal/png-worker.js +1 -1
  87. package/dist/src/inventory.js +1 -1
  88. package/dist/src/inventory2.js +1 -1
  89. package/dist/src/keyed-lock.js +1 -0
  90. package/dist/src/lease-context.js +1 -1
  91. package/dist/src/lease.js +1 -1
  92. package/dist/src/limrun-runtime-dependencies.js +1 -1
  93. package/dist/src/limrun.d.ts +3 -1
  94. package/dist/src/limrun.js +1 -1
  95. package/dist/src/linux.js +1 -1
  96. package/dist/src/location-coordinates.js +1 -0
  97. package/dist/src/logcat.js +1 -1
  98. package/dist/src/manifest.js +1 -1
  99. package/dist/src/observability.js +1 -0
  100. package/dist/src/output-path.js +1 -0
  101. package/dist/src/owner-identity.js +1 -1
  102. package/dist/src/perf.js +4 -0
  103. package/dist/src/physical-device-control.js +1 -1
  104. package/dist/src/platform-runtime-app-log-process.js +1 -1
  105. package/dist/src/platform-runtime-host.js +1 -1
  106. package/dist/src/platform-runtime-open-target.js +1 -0
  107. package/dist/src/platform-runtime-operation-host.js +4 -4
  108. package/dist/src/platform-runtime-runtime-hints.js +2 -0
  109. package/dist/src/platform-runtime-screen-recording-android-host.js +1 -0
  110. package/dist/src/platform-runtime-screen-recording-apple-host.js +1 -0
  111. package/dist/src/platform-runtime-screen-recording-apple-runner-host.js +1 -0
  112. package/dist/src/platform-runtime-screen-recording-apple-runner-transport.js +1 -0
  113. package/dist/src/platform-runtime-screen-recording-apple-simulator-host.js +1 -0
  114. package/dist/src/platform-runtime-screen-recording-apple-transport.js +1 -0
  115. package/dist/src/platform-runtime-screen-recording-finalizer-host.js +1 -0
  116. package/dist/src/platform-runtime-screen-recording-harmony-host.js +1 -0
  117. package/dist/src/platform-runtime-screen-recording-output-host.js +1 -0
  118. package/dist/src/platform-runtime-screen-recording-web-host.js +1 -0
  119. package/dist/src/platform-runtime.js +1 -1
  120. package/dist/src/platform-runtime2.js +1 -0
  121. package/dist/src/plist.js +1 -1
  122. package/dist/src/png-resize.js +1 -0
  123. package/dist/src/png-worker-contract.js +1 -1
  124. package/dist/src/prepare-kind.js +13 -13
  125. package/dist/src/process-lock.js +1 -1
  126. package/dist/src/project-runtime.js +1 -0
  127. package/dist/src/provider-webdriver.js +1 -1
  128. package/dist/src/provider.js +1 -1
  129. package/dist/src/proxy.js +1 -1
  130. package/dist/src/react-native.js +1 -1
  131. package/dist/src/record-runtime.js +1 -0
  132. package/dist/src/record-trace.js +1 -1
  133. package/dist/src/recording-export-quality.js +1 -0
  134. package/dist/src/recording-telemetry.js +1 -0
  135. package/dist/src/registry.js +29 -26
  136. package/dist/src/replay.js +2 -2
  137. package/dist/src/reporting.js +3 -3
  138. package/dist/src/rolldown-runtime.js +1 -0
  139. package/dist/src/runner-client.js +1 -1
  140. package/dist/src/runner-disposal.js +1 -1
  141. package/dist/src/runner-lease.js +1 -1
  142. package/dist/src/runner-sequence.js +1 -1
  143. package/dist/src/runtime-transport.js +1 -1
  144. package/dist/src/runtime.js +3 -3
  145. package/dist/src/runtime2.js +4 -3
  146. package/dist/src/runtime3.js +1 -3
  147. package/dist/src/runtime4.js +3 -1
  148. package/dist/src/runtime5.js +1 -1
  149. package/dist/src/runtime6.js +1 -1
  150. package/dist/src/runtime7.js +1 -1
  151. package/dist/src/runtime8.js +1 -0
  152. package/dist/src/runtime9.js +1 -0
  153. package/dist/src/scoped-provider.js +1 -0
  154. package/dist/src/screenshot-density.js +1 -0
  155. package/dist/src/screenshot-geometry.js +1 -0
  156. package/dist/src/screenshot-result.js +4 -4
  157. package/dist/src/screenshot.js +1 -1
  158. package/dist/src/sdk-android-adb.d.ts +20 -2
  159. package/dist/src/sdk-android-adb.js +4 -4
  160. package/dist/src/sdk-batch-runner.js +3 -3
  161. package/dist/src/sdk-contracts.d.ts +3 -3
  162. package/dist/src/sdk-contracts.js +2 -2
  163. package/dist/src/sdk-device.js +1 -1
  164. package/dist/src/sdk-finders.js +1 -1
  165. package/dist/src/sdk-io.js +1 -1
  166. package/dist/src/sdk-selectors.d.ts +24 -20
  167. package/dist/src/sdk-selectors.js +1 -1
  168. package/dist/src/sdk.js +1 -0
  169. package/dist/src/selector-runtime.js +1 -1
  170. package/dist/src/selectors.d.ts +1 -1
  171. package/dist/src/selectors.js +1 -1
  172. package/dist/src/server.js +2 -2
  173. package/dist/src/session-target-evidence.js +1 -1
  174. package/dist/src/session.js +1 -30
  175. package/dist/src/session2.js +28 -0
  176. package/dist/src/setting-state.js +1 -1
  177. package/dist/src/shared.js +1 -1
  178. package/dist/src/simctl.js +1 -0
  179. package/dist/src/simulator-state.js +1 -0
  180. package/dist/src/simulator.js +1 -1
  181. package/dist/src/snapshot-runtime.js +1 -1
  182. package/dist/src/snapshot-session.js +1 -1
  183. package/dist/src/snapshot.js +8 -1
  184. package/dist/src/snapshot2.js +1 -1
  185. package/dist/src/snapshot3.js +1 -0
  186. package/dist/src/src.js +1 -1
  187. package/dist/src/src2.js +1 -2
  188. package/dist/src/src3.js +2 -1
  189. package/dist/src/string-enum.js +1 -0
  190. package/dist/src/tool-provider.js +3 -3
  191. package/dist/src/tool-provider2.js +1 -1
  192. package/dist/src/update-check.js +1 -1
  193. package/dist/src/verdict.js +1 -0
  194. package/dist/src/verified-file.js +1 -0
  195. package/dist/src/version.js +1 -1
  196. package/dist/src/video.js +23 -0
  197. package/package.json +8 -6
  198. package/server.json +3 -3
  199. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.7.apk.sha256 +0 -1
  200. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.7.apk.sha256 +0 -1
  201. package/dist/src/context.js +0 -1
  202. package/dist/src/interaction-touch-reference-frame.js +0 -1
  203. package/dist/src/notifications.js +0 -1
  204. package/dist/src/platform-runtime-toolchain-host.js +0 -1
  205. package/dist/src/runner-provider.js +0 -1
  206. package/dist/src/text-surface.js +0 -1
  207. package/dist/src/tool-provider3.js +0 -1
  208. package/skills/agent-device/SKILL.md +0 -20
  209. package/skills/dogfood/SKILL.md +0 -27
@@ -1,3 +1,3 @@
1
- import{a as e,i as t,n,o as r,r as i,t as a}from"./png-worker-contract.js";import{T as o,_ as s,d as c,g as l,l as u,p as d,u as f,v as p}from"./sdk-contracts.js";import{L as m,Lt as h,Ot as ee,St as te,a as ne,i as re,r as ie,w as ae,wt as oe,x as g}from"./version.js";import{An as se,In as ce,St as le,Wt as ue,Xt as de,Yt as fe,Zt as pe,an as me,cn as he,ct as ge,fn as _e,ft as ve,gt as ye,ht as _,jt as be,ot as xe,pt as Se,rn as Ce,tn as we,ut as Te,wt as Ee}from"./sdk-batch-runner.js";import{$ as De,A as Oe,B as ke,D as Ae,E as je,F as Me,I as Ne,L as Pe,M as Fe,N as v,O as Ie,P as Le,Q as Re,R as ze,T as Be,U as Ve,X as He,_ as Ue,b as We,ct as Ge,d as Ke,et as qe,f as Je,g as Ye,gn as y,h as Xe,k as Ze,lt as b,m as Qe,ot as x,p as $e,rn as et,st as S,tt,u as nt,ut as C,v as rt,w as it,y as at,z as ot}from"./prepare-kind.js";import{A as st}from"./screenshot-result.js";import{f as ct,p as lt}from"./device.js";import{A as ut}from"./sdk-android-adb.js";import w from"node:path";import dt,{promises as T}from"node:fs";import{fileURLToPath as ft}from"node:url";import{Worker as pt}from"node:worker_threads";const mt=/\b(logbox|redbox|reload js|copy stack|component stack|call stack|runtime error|open debugger to view warnings)\b/,ht=[/\b[\w.$<>/-]+\.(?:tsx?|jsx?):\d+(?::\d+)?\b/,/\b[\w.$<>/-]+\.(?:tsx?|jsx?)\s+\(\d+:\d+\)/],gt=[/^!,\s+/,/^(warn|warning|error):\s+/,/\b(?:possible\s+)?unhandled (?:promise )?rejection\b/],_t=[`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`],vt=new Set([`x`,`×`,`✕`,`✖`,`⨯`]);function yt(e){if(bt(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 bt(e){let t=Ct(e),n=t.detected?wt(t):null;return{detected:t.detected,dismissNodes:t.dismissNodes,minimizeNodes:t.minimizeNodes,collapsedNodes:t.collapsedNodes,primaryAction:n}}function xt(e){return jt(e.label?.trim())&&Vt(e.rect)}function St(e,t){let n=e.label?.trim();return!n||!xt(e)?!1:t.some(e=>e.label?.trim()===n&&Ht(e))}function Ct(e){let t=e.map(Tt).join(`
3
- `).toLowerCase(),n=E(e,Nt),r=E(e,Lt),i=E(e,jt,zt),a=E(e,Mt),o=Dt(t),s=Ot(t);return{dismissNodes:n,minimizeNodes:r,collapsedNodes:i,detected:At({text:t,hasReactNativeStackFrame:o,hasOverlayControl:kt(t,n,r),hasControllessRedBoxText:s,collapsedNodes:i,openDebuggerWarningNodes:a})}}function wt(e){let t=Ut(e.dismissNodes);if(t)return Kt(t,qt(t));let n=Jt(e.collapsedNodes.filter(Bt));return n?.rect?{action:`close-collapsed-banner`,point:$t(n),rect:n.rect,ref:n.ref,label:D(n)}:null}function Tt(e){return[e.label,e.value,e.identifier,e.type,e.role].filter(Boolean).join(` `)}function Et(e){return mt.test(e)}function Dt(e){return ht.some(t=>t.test(e))}function Ot(e){return/\buncaught\b/.test(e)&&/unable to download asset/.test(e)}function kt(e,t,n){return t.length>0||n.length>0||/\b(reload js|copy stack)\b/.test(e)}function At(e){return e.collapsedNodes.length>0||e.openDebuggerWarningNodes.length>0||e.hasControllessRedBoxText||e.hasOverlayControl&&(Et(e.text)||e.hasReactNativeStackFrame)}function jt(e){let t=e?.trim().toLowerCase();return t?_t.some(e=>t.includes(e))||gt.some(e=>e.test(t)):!1}function Mt(e){return e.includes(`open debugger to view warnings`)||/^!,\s+open debugger\b/.test(e)}function Nt(e){return Pt(e)||Ft(e)||It(e)}function Pt(e){return/^dismiss(?:\s*\([^)]*\))?$/i.test(e)}function Ft(e){return/^close(?:\s*\([^)]*\))?$/i.test(e)}function It(e){return vt.has(e)}function Lt(e){return/^minimi[sz]e(?:\b|\s|\()/i.test(e)}function Rt(e){return/^!,\s+/.test(e)}function zt(e){return!e.rect||e.rect.height<=180}function Bt(e){let t=D(e)?.trim().toLowerCase()??``;return(Mt(t)||Rt(t))&&Ht(e)}function Vt(e){return e?e.x<=1&&e.y<=1&&e.width>=300&&e.height>=600:!1}function Ht(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 Ut(e){return Yt(e,Gt)}function Wt(e){let t=[e.type,e.role,e.subrole].join(` `).toLowerCase();return/\b(button|menuitem|link)\b/.test(t)}function Gt(e){return[Zt(Wt(e)),Zt(e.hittable),-(e.rect?ce(e.rect):1/0)]}function Kt(e,t){if(!e.rect)throw Error(`React Native overlay target node must have rect`);return{action:t,point:f(e.rect),rect:e.rect,ref:e.ref,label:D(e)}}function qt(e){let t=D(e)?.trim().toLowerCase();return t&&Pt(t)?`dismiss`:`close`}function Jt(e){return Yt(e,Xt)}function Yt(e,t){let n=e.filter(e=>e.rect);return n.length===0?null:n.sort((e,n)=>Qt(t(n),t(e)))[0]??null}function Xt(e){return[Zt(e.hittable),e.rect?.width??0,e.rect?.y??0]}function Zt(e){return+(e===!0)}function Qt(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 $t(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(en(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 en(e,t,n){return Math.min(n,Math.max(t,e))}function D(e){return e.label??e.value??e.identifier}function tn(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}function nn(e,t){try{let n=ft(e),r=w.extname(n)||`.js`;return[w.join(w.dirname(n),`${t}${r}`),w.join(w.dirname(n),`internal`,`${t}${r}`)].find(e=>dt.existsSync(e))??null}catch{return null}}var O=class extends Error{};let k=null,rn=!1,an=!1,on=0;const A=new Map;function sn(e){rn=!0,!an&&(an=!0,ut({level:`warn`,phase:`png_worker_unavailable`,data:{reason:e}}),process.emitWarning(`PNG worker unavailable, falling back to in-process PNG processing: ${e}`))}function cn(e){let t=A.get(e.id);t&&(A.delete(e.id),dn(),e.ok?t.resolve(e.result):t.reject(new s(o(e.error.code),e.error.message,e.error.details)))}function ln(e,t){k===e&&(sn(t.message),k=null,e.terminate().catch(()=>{}),un(new O(`PNG worker failed: ${t.message}`)))}function un(e){let t=[...A.values()];A.clear();for(let n of t)n.reject(e)}function dn(){k&&(A.size>0?k.ref():k.unref())}function fn(){if(rn)return null;if(k)return k;let e=nn(import.meta.url,`png-worker`);if(!e)return sn(`worker entry module not found next to the current module`),null;try{let t=new pt(e,{execArgv:e.endsWith(`.ts`)?[`--experimental-strip-types`]:[]});return t.on(`message`,cn),t.on(`error`,e=>{ln(t,e)}),t.on(`exit`,e=>{ln(t,Error(`PNG worker exited with code ${e}`))}),t.unref(),k=t,t}catch(e){return sn(`failed to spawn worker: ${e instanceof Error?e.message:String(e)}`),null}}function pn(e){let t=fn();if(!t)return Promise.reject(new O(`PNG worker is unavailable`));on+=1;let n=on;return new Promise((r,i)=>{A.set(n,{resolve:r,reject:i}),dn();try{t.postMessage({...e,id:n})}catch(e){A.delete(n),dn(),i(new O(`failed to post job to PNG worker: ${e instanceof Error?e.message:String(e)}`))}})}async function j(e,t){try{return await pn(e)}catch(e){if(e instanceof O)return t();throw e}}function mn(){fn()}async function hn(){let e=k;k=null,un(new O(`PNG worker terminated`)),e&&await e.terminate()}async function M(n,r){let i=await j({kind:`decode`,png:n,label:r},()=>{let e=t(n,r);return{kind:`decode`,width:e.width,height:e.height,data:e.data}}),o=new e.PNG({width:i.width,height:i.height});return o.data=a(i.data),o}async function N(t){return a((await j({kind:`encode`,width:t.width,height:t.height,data:t.data},()=>({kind:`encode`,png:e.PNG.sync.write(t)}))).png)}async function gn(e,r,i){let{kind:a,...o}=await j({kind:`rgb-difference`,firstPng:e,secondPng:r,label:i},()=>({kind:`rgb-difference`,...n(t(e,i),t(r,i))}));return o}async function _n(e){let{kind:t,...n}=await j({kind:`diff-pixels`,...e},()=>({kind:`diff-pixels`,...i(e)}));return{...n,diffData:a(n.diffData)}}const P=[0,187,255,255];function vn(e,t){for(let n of t)n.rect.width<4||n.rect.height<4||yn(e,n.rect)}function yn(e,t){let n=bn(t);if(n==null)return;let r=I(n.x,0,e.width-1),i=I(n.y,0,e.height-1),a=I(n.right,0,e.width-1),o=I(n.bottom,0,e.height-1);for(let t=0;t<2;t+=1){for(let n=r;n<=a;n+=1)F(e,n,i+t,P),F(e,n,o-t,P);for(let n=i;n<=o;n+=1)F(e,r+t,n,P),F(e,a-t,n,P)}}function bn(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 F(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 I(e,t,n){return Number.isFinite(e)?Math.min(Math.max(e,t),n):t}const xn=[{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 Sn(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(!Tn(t,a,e))continue;let c=0,l=wn(o,a,0,e),u=i.create(e);for(;c<l;){let e=o[c];c+=1,i.visit(u,e),l=Cn({mask:t,visited:a,queue:o,queueEnd:l,width:n,height:r,pixelIndex:e})}s.push(u)}return s}function Cn(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 xn){let o=s+e.x,u=c+e.y;if(!En(o,u,i,a))continue;let d=u*i+o;Tn(t,n,d)&&(l=wn(r,n,l,d))}return l}function wn(e,t,n,r){return t[r]=1,e[n]=r,n+1}function Tn(e,t,n){return e[n]===1&&t[n]!==1}function En(e,t,n,r){return e>=0&&e<n&&t>=0&&t<r}function Dn(e,t){return e.flatMap(e=>On(e,t.baseline.width,t.baseline.height)?kn(e,t,Fn(t.baseline.height)):[e])}function On(e,t,n){let r=e.maxX-e.minX+1;return e.maxY-e.minY+1>=Pn(n)&&r>=t*.35}function kn(e,t,n){let r=Nn(e,Mn(jn(An(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])=>In(e,n,r,t)).filter(e=>e!==null);return i.length>1?i:[e]}function An(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 jn(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 Mn(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 Nn(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 Pn(e){return Math.max(48,Math.round(e*.07))}function Fn(e){return Math.max(24,Math.round(e*.03))}function In(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??=Ln(t,a),Rn(i,e,t,a,r.baseline,r.current))}return i}function Ln(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 Rn(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 zn=2.5;function Bn(e){let t=Vn(e);return Dn(t.length<=2e3?Wn(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)=>qn(t,n+1,{width:e.baseline.width,height:e.baseline.height,totalPixels:e.totalPixels,differentPixels:e.differentPixels}))}function Vn(e){let{diffMask:t,baseline:n,current:r}=e,{width:i,height:a}=n;return Sn({mask:t,width:i,height:a,hooks:{create:e=>Hn(e,i),visit:(e,t)=>Un(e,t,i,n,r)}})}function Hn(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 Un(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 Wn(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=>Gn(e,r,t));if(!e){n.push({...r});continue}Kn(e,r)}return n}function Gn(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 Kn(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 qn(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=Jn(e.baselineRed,e.baselineGreen,e.baselineBlue,e.differentPixels),o=Jn(e.currentRed,e.currentGreen,e.currentBlue,e.differentPixels),s=r.width*r.height;return{index:t,rect:r,normalizedRect:re({x:R(r.x/n.width),y:R(r.y/n.height),width:R(r.width/n.width),height:R(r.height/n.height)}),differentPixels:e.differentPixels,shareOfDiffPercentage:R(e.differentPixels/n.differentPixels),densityPercentage:R(e.differentPixels/s),shape:Zn(r,n.width,n.height),size:Qn(s,n.totalPixels),location:Yn(i,n.width,n.height),averageBaselineColorHex:$n(a),averageCurrentColorHex:$n(o),baselineLuminance:Math.round(L(a)),currentLuminance:Math.round(L(o)),dominantChange:Xn(a,o)}}function Jn(e,t,n,r){return{r:Math.round(e/r),g:Math.round(t/r),b:Math.round(n/r)}}function Yn(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 Xn(e,t){let n=L(t)-L(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 Zn(e,t,n){return e.width>=t*.55&&e.height>=n*.12?`large-area`:e.width>=e.height*zn?`horizontal-band`:e.height>=e.width*zn?`vertical-band`:`compact`}function Qn(e,t){let n=e/t;return n>=.04?`large`:n>=.01?`medium`:`small`}function L(e){return e.r*.2126+e.g*.7152+e.b*.0722}function $n(e){return`#${er(e.r)}${er(e.g)}${er(e.b)}`}function er(e){return e.toString(16).padStart(2,`0`)}function R(e){return Math.round(e*100*100)/100}const tr=255*Math.sqrt(3);async function nr(t,n,r={}){await rr(t,`Baseline image not found`),await rr(n,`Current screenshot not found`);let i=r.outputPath,[a,o]=await Promise.all([T.readFile(t),T.readFile(n)]),[s,c]=await Promise.all([M(a,`baseline screenshot`),M(o,`current screenshot`)]);ir(s.width,s.height,`baseline screenshot`,r.maxPixels),ir(c.width,c.height,`current screenshot`,r.maxPixels);let l=r.threshold??.1;if(s.width!==c.width||s.height!==c.height){let e=s.width*s.height;return await ar(r.outputPath),{match:!1,mismatchPercentage:100,totalPixels:e,differentPixels:e,dimensionMismatch:{expected:{width:s.width,height:s.height},actual:{width:c.width,height:c.height}}}}let u=s.width*s.height,d=l*tr,{diffData:f,diffMask:p,differentPixels:m}=await _n({baselineData:s.data,currentData:c.data,width:s.width,height:s.height,maxColorDistance:d}),h=m>0?Bn({diffMask:p,baseline:s,current:c,totalPixels:u,differentPixels:m}):[];if(m>0&&i){let t=new e.PNG({width:s.width,height:s.height});t.data=f,vn(t,h),await T.mkdir(w.dirname(i),{recursive:!0}),await T.writeFile(i,await N(t))}else await ar(r.outputPath);let ee=u>0?Math.round(m/u*100*100)/100:0;return{...m>0&&i?{diffPath:i}:{},...h.length>0?{regions:h}:{},totalPixels:u,differentPixels:m,mismatchPercentage:ee,match:m===0}}async function rr(e,t){try{await T.access(e)}catch{throw new s(`INVALID_ARGS`,`${t}: ${e}`)}}function ir(e,t,n,r){if(r==null||r<=0)return;let i=e*t;if(!(i<=r))throw new s(`INVALID_ARGS`,`${n} is ${i} pixels, which exceeds the configured maxImagePixels limit of ${r}`)}async function ar(e){if(e)try{await T.unlink(e)}catch(e){if(!or(e,`ENOENT`))throw e}}function or(e,t){return typeof e==`object`&&!!e&&`code`in e&&e.code===t}function sr(e,t){return e.map(e=>{let n=cr(e,t);return n.length>0?{...e,currentOverlayMatches:n}:e})}function cr(e,t){let n=lr(e.rect);return t.map(t=>{let r=t.overlayRect,i=ie(e.rect,r);return i<=0?null:{ref:t.ref,...t.label?{label:t.label}:{},rect:r,overlayCoveragePercentage:ur(i/lr(r)),regionCoveragePercentage:ur(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 lr(e){return e.width*e.height}function ur(e){return Math.round(e*100*100)/100}async function z(e,t,n){if(t.kind===`path`&&!e.policy.allowLocalInputPaths)throw new s(`INVALID_ARGS`,`Local ${n.field??`input`} paths are not allowed by command policy`);try{return await e.artifacts.resolveInput(t,n)}catch(e){throw p(e)}}async function B(e,t,n){if(t?.kind===`path`&&!e.policy.allowLocalOutputPaths)throw new s(`INVALID_ARGS`,`Local output paths are not allowed by command policy`);try{return await e.artifacts.reserveOutput(t,{...n,visibility:n.visibility??`client-visible`,requestedClientPath:t?.kind===`downloadableArtifact`?t.clientPath??n.requestedClientPath:n.requestedClientPath})}catch(e){throw p(e)}}async function dr(e,t){try{return await e.artifacts.createTempFile(t)}catch(e){throw p(e)}}const fr=async(e,t)=>{if(!t.baseline)throw new s(`INVALID_ARGS`,`diff screenshot requires a baseline image`);let n=pr(t.threshold),r=t.current??{kind:`live`};if(t.overlayRefs&&!br(r))throw new s(`INVALID_ARGS`,`diff screenshot <current.png> cannot use --overlay-refs because saved-image comparisons have no live accessibility refs`);let i=await z(e,t.baseline,{usage:`diff screenshot baseline`,field:`baseline`}),a,o,c,l=[];try{let s;br(r)?(o=await mr(e,t),s=o.path):(a=await z(e,r,{usage:`diff screenshot current`,field:`current`}),s=a.path),c=t.out?await B(e,t.out,{field:`diffPath`,ext:`.png`,artifactType:`screenshot-diff`}):void 0;let u=await nr(i.path,s,{threshold:n,outputPath:c?.path,maxPixels:e.policy.maxImagePixels});br(r)&&(u=await hr(e,t,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 i.cleanup?.(),await a?.cleanup?.(),await o?.cleanup?.()}};function pr(e){if(e==null||e===``)return .1;let t=Number(e);if(Number.isNaN(t)||t<0||t>1)throw new s(`INVALID_ARGS`,`--threshold must be a number between 0 and 1`);return t}async function mr(e,t){let n=await dr(e,{prefix:`agent-device-diff-current`,ext:`.png`});try{await gr(e,t,n.path,_r(t))}catch(e){throw await n.cleanup(),e}return n}async function hr(e,t,n,r,i){if(!t.overlayRefs)return r;if(r.match||r.dimensionMismatch)return n&&await yr(n),r;let a=await B(e,vr(t,n),{field:`currentOverlayPath`,ext:`.png`,artifactType:`screenshot`});try{let n=await gr(e,t,a.path,{overlayRefs:!0,..._r(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:sr(r.regions,n.overlayRefs)}:{}}}catch(e){throw await a.cleanup?.(),e}}async function gr(e,t,n,r={}){if(!e.backend.captureScreenshot)throw new s(`UNSUPPORTED_OPERATION`,`screenshot is not supported by this backend`);return await e.backend.captureScreenshot({session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata},n,r)??{}}function _r(e){return{normalizeStatusBar:e.normalizeStatusBar??!0,...e.surface?{surface:e.surface}:{}}}function vr(e,t){if(e.currentOverlayOut)return e.currentOverlayOut;if(e.out?.kind===`path`)return{kind:`path`,path:V(t??e.out.path)};if(e.out?.kind===`downloadableArtifact`)return{kind:`downloadableArtifact`,...e.out.clientPath?{clientPath:V(e.out.clientPath)}:{},...e.out.fileName?{fileName:V(e.out.fileName)}:{}}}function V(e){let t=w.extname(e);return`${t?e.slice(0,-t.length):e}.current-overlay${t||`.png`}`}async function yr(e){try{await T.unlink(V(e))}catch(e){if(!xr(e,`ENOENT`))throw e}}function br(e){return e.kind===`live`}function xr(e,t){return typeof e==`object`&&!!e&&`code`in e&&e.code===t}async function Sr(e,t){let{min:n,max:r}=ee;if(!Number.isFinite(t)||t<n||t>r)throw new s(`INVALID_ARGS`,`Screenshot scale must be between ${n} and ${r}`);if(t===1)return;let i=await M(await T.readFile(e),`screenshot`),a=Math.max(1,Math.round(i.width*t)),o=Math.max(1,Math.round(i.height*t));await T.writeFile(e,await N(wr(i,a,o)))}async function Cr(e,t,n){if(!Number.isInteger(t)||t<1||!Number.isInteger(n)||n<1)throw new s(`INVALID_ARGS`,`Screenshot resize dimensions must be positive integers`);let r=await M(await T.readFile(e),`screenshot`);r.width===t&&r.height===n||await T.writeFile(e,await N(wr(r,t,n)))}function wr(t,n,r){let i=new e.PNG({width:n,height:r});for(let e=0;e<r;e+=1){let a=e*t.height/r,o=(e+1)*t.height/r;for(let r=0;r<n;r+=1){let s=r*t.width/n,c=(r+1)*t.width/n,l=0,u=0,d=0,f=0,p=0;for(let e=Math.floor(a);e<Math.ceil(o);e+=1){let n=Math.min(e+1,o)-Math.max(e,a);for(let r=Math.floor(s);r<Math.ceil(c);r+=1){let i=n*(Math.min(r+1,c)-Math.max(r,s)),a=(e*t.width+r)*4;l+=(t.data[a]??0)*i,u+=(t.data[a+1]??0)*i,d+=(t.data[a+2]??0)*i,f+=(t.data[a+3]??0)*i,p+=i}}let m=(e*i.width+r)*4;i.data[m]=Math.round(l/p),i.data[m+1]=Math.round(u/p),i.data[m+2]=Math.round(d/p),i.data[m+3]=Math.round(f/p)}}return i}const Tr=async(e,t)=>{if(!e.backend.captureScreenshot)throw new s(`UNSUPPORTED_OPERATION`,`screenshot is not supported by this backend`);h(t);let n=await B(e,t.out,{field:`path`,ext:`.png`,artifactType:`screenshot`}),r;try{await e.backend.captureScreenshot({session:t.session,requestId:t.requestId,appId:t.appId,appBundleId:t.appBundleId,signal:t.signal??e.signal,metadata:t.metadata},n.path,{fullscreen:t.fullscreen,overlayRefs:t.overlayRefs,pixelDensity:t.pixelDensity,stabilize:t.stabilize,normalizeStatusBar:t.normalizeStatusBar,surface:t.surface}),t.scale!==void 0&&await Sr(n.path,t.scale),r=await n.publish()}catch(e){throw await n.cleanup?.(),e}return{path:n.path,...r?{artifacts:[r]}:{},...y(`Saved screenshot: ${n.path}`)}};function Er(e){let{nodes:t,backend:n,snapshotRaw:r}=e;if(r||!l(n))return{partial:!1,visibleNodeCount:t.length,totalNodeCount:t.length,reasons:[]};let i=ne(t),a=new Set;return i.hiddenCount>0&&a.add(`offscreen-nodes`),i.nodes.some(e=>e.hiddenContentAbove)&&a.add(`scroll-hidden-above`),i.nodes.some(e=>e.hiddenContentBelow)&&a.add(`scroll-hidden-below`),{partial:a.size>0,visibleNodeCount:i.nodes.length,totalNodeCount:t.length,reasons:[...a]}}const Dr=`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?Dr:void 0}function kr(e,t){return e.presentationKey?e:{...e,presentationKey:u(t)}}function Ar(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||!jr(t,n,i)||!t.presentationKey||t.presentationKey!==n.presentationKey||!Mr(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 jr(e,t,n){return!(e.backend&&t.backend&&e.backend!==t.backend||n?.previousAppBundleId&&n.currentAppBundleId&&n.previousAppBundleId!==n.currentAppBundleId)}function Mr(e,t){return e.truncated===t.truncated?JSON.stringify(Nr(e.nodes))===JSON.stringify(Nr(t.nodes)):!1}function Nr(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 Pr=async(e,t)=>{let n=await Ir(e,t),r=Ar({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(Rr(t.session,n)),{nodes:n.snapshot.nodes,truncated:n.snapshot.truncated??!1,visibility:Er({nodes:n.snapshot.nodes,backend:n.snapshot.backend,snapshotRaw:t.raw}),...te({...n.annotations,warnings:n.warnings}),...r?{unchanged:r}:{},...n.result.snapshotDiagnostics?{snapshotDiagnostics:n.result.snapshotDiagnostics}:{},...zr(n)}},Fr=async(e,t)=>{let n=await Ir(e,t),r=t.interactiveOnly===!0,i=n.session?.snapshot,a=Rr(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=it(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 Ir(e,t){if(!e.backend.captureSnapshot)throw new s(`UNSUPPORTED_OPERATION`,`snapshot is not supported by this backend`);let n=t.session??`default`,r=await e.sessions.get(n),i=await e.backend.captureSnapshot({session:n,requestId:t.requestId,appId:r?.appId,appBundleId:r?.appBundleId,signal:t.signal??e.signal,metadata:t.metadata},{interactiveOnly:t.interactiveOnly,depth:t.depth,scope:t.scope,raw:t.raw,customActions:t.customActions}),a=kr(Lr(i,e),t),o=oe(i),c=Ge(e);return{snapshot:a,result:i,session:r,annotations:o,warnings:Br({result:i,annotations:o,snapshot:a,options:t,session:r,capturedAt:a.createdAt??c,runtimeNow:c})}}function Lr(e,t){return e.snapshot?e.snapshot:{nodes:e.nodes??[],truncated:e.truncated,backend:e.backend,createdAt:Ge(t)}}function Rr(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 zr(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 Br(e){let t=[...e.annotations.warnings??[]];e.annotations.quality&&t.push(...Ve(e.annotations.quality,e.snapshot.nodes)),t.push(...Wr(e)),e.annotations.quality||(t.push(...Hr(e)),t.push(...Ur(e.snapshot.nodes)));let n=yt(e.snapshot.nodes);n&&t.push(n);let r=Vr(e.annotations);r&&t.push(r);let i=Gr(e);return i&&t.push(i),t.push(...Yr(e.annotations.freshness,e.snapshot.backend)),Array.from(new Set(t))}function Vr(e){if(e.androidSnapshot?.systemSurfaceOnly===!0)return Dr}function Hr(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 Ur(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 Wr(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 Gr(e){let t=e.session?.snapshot;if(!e.annotations.freshness&&t&&Kr(t,e.snapshot)&&qr(t,e.capturedAt,e.runtimeNow)&&Xr(t.nodes.length,e.snapshot.nodes.length))return Jr}function Kr(e,t){return e.presentationKey===void 0||t.presentationKey===void 0?!0:e.presentationKey===t.presentationKey}function qr(e,t,n){return[t,n].some(t=>{let n=t-e.createdAt;return n>=0&&n<=2e3})}const Jr=`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 Yr(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`?[Jr]:[]}function Xr(e,t){return e<12?!1:t<=Math.floor(e*.2)}const Zr={screenshot:Tr,diffScreenshot:fr,snapshot:Pr,diffSnapshot:Fr},Qr=new WeakMap;function $r(e,t){ti(e)&&Qr.set(e,t)}function ei(e){return ti(e)?Qr.get(e):void 0}function ti(e){return typeof e==`object`&&!!e||typeof e==`function`}const ni=async(e,t)=>await oi(e,t,`press`),ri=async(e,t)=>await oi(e,t,`click`),ii=async(e,t)=>{if(!t.text)throw new s(`INVALID_ARGS`,`fill requires text`);let n=Ye(t),r=n.needsPreActionBaseline?null:await li(e,t);if(r)return r;let i=await Oe(e,t,{action:`fill`,requireInteractive:!0,promoteToHittableAncestor:!1,captureEvidenceBaseline:n.needsPreActionBaseline,expectedResolvedTarget:t.expectedResolvedTarget,preresolvedTarget:t.preresolvedTarget});if(!e.backend.fill)throw new s(`UNSUPPORTED_OPERATION`,`fill is not supported by this backend`);let a=si(i),o=`node`in i?i.node?.type??``:``,c=o!==``&&se(o,e.backend.platform),l=t.allowNonHittableCoordinateFallback===!0&&`node`in i&&i.node?.hittable===!1,u=S(await e.backend.fill(b(e,t),a,t.text,{delayMs:t.delayMs,allowNonHittableCoordinateFallback:l})),d=o&&!c?`fill target ${di(i)} resolved to "${o}", attempting fill anyway.`:void 0;return await Xe(e,t,i,{...i,text:t.text,...d?{warning:d}:{},...u?{backendResult:u}:{}},n)},ai=async(e,t)=>{let n=t.text;if(!n)throw new s(`INVALID_ARGS`,`type requires text`);let r=fi(n);if(r)throw new s(`INVALID_ARGS`,`type does not accept a target ref like "${r}"`,{hint:`Use fill ${r} "text" to target that field, or press ${r} then type "text" to append.`});if(!e.backend.typeText)throw new s(`UNSUPPORTED_OPERATION`,`type is not supported by this backend`);let i=C(t.delayMs??0,`delay-ms`,0,1e4),a=S(await e.backend.typeText(b(e,t),n,{delayMs:i}));return{kind:`text`,text:n,delayMs:i,...a?{backendResult:a}:{},...y(`Typed ${Array.from(n).length} chars`)}};async function oi(e,t,n){let r=Ye(t),i=r.needsPreActionBaseline?null:await ci(e,t,n);if(i)return i;let a=await Oe(e,t,{action:n,requireInteractive:!0,promoteToHittableAncestor:!0,captureEvidenceBaseline:r.needsPreActionBaseline,expectedResolvedTarget:t.expectedResolvedTarget,preresolvedTarget:t.preresolvedTarget});if(!e.backend.tap)throw new s(`UNSUPPORTED_OPERATION`,`tap is not supported by this backend`);let o=si(a),c;try{c=await e.backend.tap(b(e,t),o,{button:t.button,count:t.count,intervalMs:t.intervalMs,holdMs:t.holdMs,jitterPx:t.jitterPx,doubleTap:t.doubleTap})}catch(e){throw $r(e,a),e}let l=S(c);return await Xe(e,t,a,{...a,...l?{backendResult:l}:{}},r)}function si(e){if(!e.point)throw new s(`COMMAND_FAILED`,`Interaction target resolved without coordinates`);return e.point}async function ci(e,t,n){if(n!==`click`||t.target.kind!==`ref`||!e.backend.tapTarget||ui(t)||t.expectedResolvedTarget)return null;let r=await Ze(e,t,t.target,n),i=S(await e.backend.tapTarget(b(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:je,...r,...i?{backendResult:i}:{}}}async function li(e,t){if(t.target.kind!==`ref`||!e.backend.fillTarget||t.expectedResolvedTarget)return null;let n=await Ze(e,t,t.target,`fill`),r=S(await e.backend.fillTarget(b(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:je,...n,...r?{backendResult:r}:{}}}function ui(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 di(e){return e.target?.kind===`ref`?e.target.ref:e.target?.kind===`selector`?e.target.selector:`point`}function fi(e){return tn(e)}function H(e){return{includeRects:e===`visible`||e===`hidden`,interactiveOnly:!1}}function pi(e,t,n){let r=n??1e4,i=U(e),a=vi(),o=()=>Math.max(0,r-(U(e)-i));return{capture:async n=>{let r=!1,i=await We(e,t,o(),async e=>await a.attempt(async()=>{let t=await n(e);return r=!0,t}));return i.timedOut?{timedOut:!0,deadline:a.readableCaptures()===0?`capture-stalled`:`capture-truncated`}:(r&&a.recordReadableCapture(),i)},hasTimeRemaining:()=>o()>0,failureEvidence:()=>({timeoutMs:r,readableCaptures:a.readableCaptures(),waitedMs:U(e)-i}),rethrowIfNeverReadable:a.rethrowIfNeverReadable,sleepUntilNextPoll:async()=>await yi(e,t,Math.min(300,o())),timeoutMs:r,waitedMs:()=>U(e)-i}}function mi(e,t){return new s(`COMMAND_FAILED`,e,{reason:g.captureStalled,captureStalled:!0,...t,retriable:!0,hint:`No readable snapshot capture completed before the wait timeout. Retry, or use screenshot to inspect the current surface.`})}function hi(e,t){return new s(`COMMAND_FAILED`,e,{reason:g.deadlineExceeded,captureTruncated:!0,...t})}function gi(e,t){return new s(`COMMAND_FAILED`,e,{reason:g.targetAbsent,...t})}function _i(e,t,n){let r=t.failureEvidence();return n===`capture-stalled`?mi(e,r):n===`capture-truncated`?hi(e,r):(t.rethrowIfNeverReadable(),r.readableCaptures===0?mi(e,r):gi(e,r))}function vi(){let e=0,t;return{attempt:async e=>{try{return await e()}catch(e){if(!ke(e))throw e;t=e;return}},recordReadableCapture:()=>{e+=1},readableCaptures:()=>e,rethrowIfNeverReadable:()=>{if(e===0&&t!==void 0)throw t}}}function U(e){return e.clock?.now()??Date.now()}async function yi(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 bi(e){if(e.kind===`ambiguous`)return{selector:e.selector,selectorIndex:e.selectorIndex,matchedNodes:e.matchedNodes};if(e.kind===`resolved`)return{selector:e.resolution.selector,selectorIndex:e.resolution.selectorIndex,matchedNodes:e.matchedNodes}}function xi(e){let t=async(t,n)=>{if(n.target.kind===`sleep`)return await Oi(t,n.target.durationMs),{kind:`sleep`,waitedMs:n.target.durationMs};if(n.target.kind===`ref`){let r=await e.requireSnapshot(t,n.session),i=d(n.target.ref);if(!i)throw new s(`INVALID_ARGS`,`Invalid ref: ${n.target.ref}`);let a=c(r.snapshot.nodes,i),o=a?Re(a,r.snapshot.nodes):void 0;if(!o)throw new s(`COMMAND_FAILED`,`Ref ${n.target.ref} not found or has no label`);return await wi(e,t,n,o,n.target.timeoutMs)}if(n.target.kind===`selector`)return await Si(e,t,n,n.target.selector,n.target.timeoutMs,n.target.recordedLandmark);if(n.target.kind===`stable`)return await Ei(e,t,n,n.target.quietMs,n.target.timeoutMs);let r=fe(n.target.text);if(!r.ok)throw new s(r.code,r.message);return await wi(e,t,n,n.target.text,n.target.timeoutMs)};return{waitCommand:t,waitForTextCommand:async(e,n)=>{let r=await t(e,{...n,target:{kind:`text`,text:n.text,timeoutMs:n.timeoutMs}});if(r.kind!==`text`)throw new s(`COMMAND_FAILED`,`waitForText returned non-text result`);return r}}}async function Si(e,t,n,r,i,a){let o=pi(t,n,i),c=H(),l,u;for(;o.hasTimeRemaining();){let i=await o.capture(async r=>await e.captureSnapshot(t,{...n,signal:r},{updateSession:!0,includeHiddenContentHints:!1,...c}));if(i.timedOut){u=i.deadline;break}let s=i.value;if(s){let e=s.snapshot.nodes,n=bi(Se(e,r,_.wait,{platform:t.backend.platform}));if(n){let t=Ci(e,n,a);if(t.kind===`satisfied`)return{kind:`selector`,selector:n.selector,waitedMs:o.waitedMs(),node:t.node,preActionNodes:e};l=t.evidence}}await o.sleepUntilNextPoll()}throw u!==`capture-stalled`&&l?new s(`COMMAND_FAILED`,`wait matched selector ${r} but no candidate carried the recorded landmark identity`,{reason:Fe,...l}):_i(`wait timed out for selector: ${r}`,o,u)}function Ci(e,t,n){let r=t.matchedNodes[0];if(!n)return{kind:`satisfied`,node:r};let i=qe(e),a=tt(t.matchedNodes,i,Ee(n),n.ancestry)[0];return a?{kind:`satisfied`,node:a}:{kind:`identity-mismatch`,evidence:{matchCount:t.matchedNodes.length,observed:be(r),observedAncestry:De(r,i,Math.max(n.ancestry.length,1)).chain}}}async function wi(e,t,n,r,i){let a=pi(t,n,i),o;for(;a.hasTimeRemaining();){let i=await a.capture(async i=>t.backend.findText?(await t.backend.findText(Di(t,{...n,signal:i}),r)).found:await Ti(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 _i(`wait timed out for text: ${r}`,a,o)}async function Ti(e,t,n,r){return!!He((await e.captureSnapshot(t,n,{updateSession:!0,includeHiddenContentHints:!1})).snapshot.nodes,r)}async function Ei(e,t,n,r,i){let a=i??1e4,o=r??e.stable.defaultQuietMs,c=await e.stable.capture(t,n,{quietMs:o,timeoutMs:a});if(!c.settled)throw new s(`COMMAND_FAILED`,`wait timed out waiting for a stable UI`,{reason:g.stableTimeout,...c.stalled?{captureStalled:!0}:{},quietMs:o,timeoutMs:a,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 Di(e,t){return{session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata}}async function Oi(e,t){e.clock?await e.clock.sleep(t):await new Promise(e=>setTimeout(e,t))}const ki=xi({captureSnapshot:v,requireSnapshot:Me,stable:{defaultQuietMs:500,tinyTreeHint:rt,tinyTreeNodeCount:5,capture:at}}),Ai=ki.waitCommand,ji=ki.waitForTextCommand,Mi=async(e,t)=>{let n=t.locator??`any`;if(!t.query)throw new s(`INVALID_ARGS`,me);if(t.action===`wait`)return await zi(e,t,n);if(t.action===`list`)return await Bi(e,t,n);let{capture:r,match:i}=await Vi(e,t,n);if(!i)throw new s(`COMMAND_FAILED`,`find did not match any element`);if(t.action===`exists`)return{kind:`found`,found:!0};let a=`@${i.ref}`;return t.action===`get_attrs`?{kind:`attrs`,ref:a,node:i}:{kind:`text`,ref:a,text:await Le(e,r,i),node:i}},Ni=async(e,t)=>{if(t.target.kind===`ref`){let n=await Me(e,t.session),r=Ne(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`});Ae(r.node,n.snapshot.nodes,t.expectedResolvedTarget,`get`);let i=le(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 Le(e,n,r.node),node:r.node,selectorChain:i,preActionNodes:o}}let n=await Hi(e,t,t.session??`default`,{selector:t.target.selector,policy:t.property===`text`?_.readText:_.readUnique});Ae(n.node,n.capture.snapshot.nodes,t.expectedResolvedTarget,`get`);let r=le(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 Le(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}},Pi=async(e,t)=>{let n=await Ni(e,{...t,property:`text`,target:t.target});if(n.kind!==`text`)throw new s(`COMMAND_FAILED`,`getText returned non-text result`);return n},Fi=async(e,t)=>{let n=await Ni(e,{...t,property:`attrs`,target:t.target});if(n.kind!==`attrs`)throw new s(`COMMAND_FAILED`,`getAttrs returned non-attrs result`);return n},Ii=async(e,t)=>{let n=de(t.predicate);if(!n.ok)throw new s(n.code,n.message,{hint:n.hint});let r=n.predicate;if(r===`text`&&!t.expectedText)throw new s(`INVALID_ARGS`,ue);let i=t.selector,a=await v(e,t,{updateSession:!0,...H(r)});if(r===`exists`){let t=xe(a.snapshot.nodes,i,{platform:e.backend.platform});if(!t)throw new s(`COMMAND_FAILED`,we(i,[],{unique:!1}),{hint:Ce([])});return{predicate:r,pass:!0,selector:t.selector,matches:t.matches,selectorChain:Te(i)}}let o=ve(a.snapshot.nodes,i,{platform:e.backend.platform,...ye(_.readUnique)});if(!o)throw new s(`COMMAND_FAILED`,we(i,[],{unique:!0}),{command:`is`,reason:`selector_not_found`,predicate:r,selector:i,hint:Ce([])});Ae(o.node,a.snapshot.nodes,t.expectedResolvedTarget,`is`);let c=pe({predicate:r,node:o.node,nodes:a.snapshot.nodes,expectedText:t.expectedText,platform:e.backend.platform});if(!c.pass)throw new s(`COMMAND_FAILED`,`is ${r} failed for selector ${o.selector}: ${c.details}`,{command:`is`,reason:`predicate_failed`,predicate:r,selector:o.selector,predicateDetails:c.details});return{predicate:r,pass:!0,selector:o.selector,...r===`text`?{text:c.actualText}:{},selectorChain:Te(i),node:o.node,preActionNodes:a.snapshot.nodes}},Li=async(e,t)=>await Ii(e,{...t,predicate:`visible`,selector:t.target.selector}),Ri=async(e,t)=>await Ii(e,{...t,predicate:`hidden`,selector:t.target.selector});async function zi(e,t,n){let r=pi(e,t,t.timeoutMs),i;for(;r.hasTimeRemaining();){let a=await r.capture(async r=>await Vi(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 _i(`find wait timed out`,r,i)}async function Bi(e,t,n){let r=_e(n,t.query),i=await v(e,t,{updateSession:!0,...H()});if(ot(i.snapshot.snapshotQuality))throw ze(i.snapshot.snapshotQuality);return{kind:`list`,matches:(r?ge(i.snapshot.nodes,r,{platform:e.backend.platform})?.matchedNodes??[]:he(i.snapshot.nodes,n,t.query,{}).matches).map(e=>({ref:`@${e.ref}`,node:e}))}}async function Vi(e,t,n,r){let i=_e(n,t.query),a=await v(e,t,{updateSession:!0,scope:Pe(e.backend.platform,n,t.query,i),includeHiddenContentHints:r?.includeHiddenContentHints,...H()});if(ot(a.snapshot.snapshotQuality))throw ze(a.snapshot.snapshotQuality);return i?{capture:a,match:ve(a.snapshot.nodes,i,{platform:e.backend.platform,...ye(_.readAny)})?.node}:{capture:a,match:he(a.snapshot.nodes,n,t.query,{requireRect:!1}).matches[0]}}async function Hi(e,t,n,r){let i=await v(e,{...t,session:n},{updateSession:!0,...H()}),a=ve(i.snapshot.nodes,r.selector,{platform:e.backend.platform,...ye(r.policy)});if(!a)throw new s(`COMMAND_FAILED`,we(r.selector,[],{unique:!0}),{hint:Ce([])});return{capture:i,node:a.node,selector:a.selector,ref:`@${a.node.ref}`}}const Ui=async(e,t)=>{if(!e.backend.performGesture)throw new s(`UNSUPPORTED_OPERATION`,`gesture is not supported by this backend`);await Ie(e,t,t.gesture.intent);let n=await $e(e,t),r=m(t.gesture,n,e.backend.platform),i=S(await e.backend.performGesture(b(e,t),r)),a=Gi(r.pointers,0),o=Gi(r.pointers,-1);return{kind:t.gesture.intent,durationMs:r.durationMs,pointerCount:r.topology===`single`?1:2,from:a,to:o,...i?{backendResult:i}:{},...y(Ki(t.gesture,a,o))}},Wi=async(e,t)=>{let n=t.gesture;return n.intent===`drag`?await nt(e,{...t,gesture:n}):await Ui(e,{...t,gesture:n})};function Gi(e,t){let n=e.map(e=>t===0?e.samples[0]?.point:e.samples.at(-1)?.point);if(n.some(e=>e===void 0))throw new s(`COMMAND_FAILED`,`Gesture plan did not contain endpoint samples.`);let r=n;return{x:r.reduce((e,t)=>e+t.x,0)/r.length,y:r.reduce((e,t)=>e+t.y,0)/r.length}}function Ki(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:Mi,get:Ni,getText:Pi,getAttrs:Fi,is:Ii,isVisible:Li,isHidden:Ri,wait:Ai,waitForText:ji},G={click:ri,press:ni,fill:ii,typeText:ai,focus:Ke,longPress:Je,scroll:Qe,gesture:Wi,settleObservation:Ue};function qi(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 Ji(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,t){let n=e?.trim();if(!n)throw new s(`INVALID_ARGS`,`${t} must be a non-empty string`);return n}const Yi=async(e,t={})=>{if(!e.backend.listDevices)throw new s(`UNSUPPORTED_OPERATION`,`admin.devices is not supported by this backend`);return{kind:`adminDevices`,devices:await e.backend.listDevices(b(e,t),t.filter)}},Xi=async(e,t={})=>{if(!e.backend.bootDevice)throw new s(`UNSUPPORTED_OPERATION`,`admin.boot is not supported by this backend`);let n=oa(t.target),r=S(await e.backend.bootDevice(b(e,t),n));return{kind:`deviceBooted`,...n?{target:n}:{},...r?{backendResult:r}:{},...y(`Booted device`)}},Zi=async(e,t={})=>{if(!e.backend.shutdownDevice)throw new s(`UNSUPPORTED_OPERATION`,`admin.shutdown is not supported by this backend`);let n=oa(t.target),r=S(await e.backend.shutdownDevice(b(e,t),n));return{kind:`deviceShutdown`,...n?{target:n}:{},...r?{backendResult:r}:{},...y(`Shutdown device`)}},Qi=async(e,t)=>await ta(e,t,`install`),$i=async(e,t)=>await ta(e,t,`reinstall`),ea=async(e,t)=>await ta(e,t,`installFromSource`);async function ta(e,t,n){let r=n===`reinstall`?`reinstallApp`:`installApp`,i=e.backend[r];if(!i)throw new s(`UNSUPPORTED_OPERATION`,`admin.${n} is not supported by this backend`);let a=`app`in t&&t.app!==void 0?q(t.app,`app`):void 0;if(n!==`installFromSource`&&!a)throw new s(`INVALID_ARGS`,`admin.${n} requires app`);let o=b(e,t),c=await na(e,o,t.source);try{let t=await i.call(e.backend,o,{...a?{app:a}:{},source:c.source});return sa(n,a,c.source,t)}finally{await c.cleanup?.()}}async function na(e,t,n){let r=await ra(e,ia(n));try{return{source:ia(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 ra(e,t){if(t.kind===`url`)return{source:t};let n=await z(e,t,{usage:`admin.install`,field:`source`});return{source:{kind:`path`,path:n.path},...n.cleanup?{cleanup:n.cleanup}:{}}}function ia(e){if(!e||typeof e!=`object`)throw new s(`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 aa(t),{kind:`url`,url:t}}throw new s(`INVALID_ARGS`,`install source kind must be path, uploadedArtifact, or url`)}function aa(e){let t;try{t=new URL(e)}catch{throw new s(`INVALID_ARGS`,`Invalid install source URL: ${e}`)}if(t.protocol!==`http:`&&t.protocol!==`https:`)throw new s(`INVALID_ARGS`,`Install source URL must use http or https`)}function oa(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 sa(e,t,n,r){let i=S(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}:{},...y(`${e===`reinstall`?`Reinstalled`:`Installed`}: ${o??u??t??ca(n)}`)}}function J(e,t){let n=e[t];return typeof n==`string`&&n.length>0?n:void 0}function ca(e){return e.kind===`path`?e.path:e.kind===`uploadedArtifact`?e.id:e.url}const la=/^[A-Za-z0-9_.:-]{1,64}$/,ua=async(e,t)=>{if(!e.backend.openApp)throw new s(`UNSUPPORTED_OPERATION`,`apps.open is not supported by this backend`);let n=ga(t),r=S(await e.backend.openApp(Y(e,t),n,{launchArgs:t.launchArgs,relaunch:t.relaunch}));return{kind:`appOpened`,target:n,relaunch:t.relaunch===!0,...r?{backendResult:r}:{},...y(`Opened: ${va(n)}`)}},da=async(e,t={})=>{if(!e.backend.closeApp)throw new s(`UNSUPPORTED_OPERATION`,`apps.close is not supported by this backend`);let n=K(t.app,`app`),r=S(await e.backend.closeApp(Y(e,t),n));return{kind:`appClosed`,...n?{app:n}:{},...r?{backendResult:r}:{},...y(n?`Closed: ${n}`:`Closed app`)}},fa=async(e,t={})=>{if(!e.backend.listApps)throw new s(`UNSUPPORTED_OPERATION`,`apps.list is not supported by this backend`);return{kind:`appsList`,apps:await e.backend.listApps(Y(e,t),ct(t.filter))}},pa=async(e,t)=>{if(!e.backend.getAppState)throw new s(`UNSUPPORTED_OPERATION`,`apps.state is not supported by this backend`);let n=q(t.app,`app`);return{kind:`appState`,app:n,state:await e.backend.getAppState(Y(e,t),n)}},ma=async(e,t)=>{if(!e.backend.pushFile)throw new s(`UNSUPPORTED_OPERATION`,`apps.push is not supported by this backend`);let n=q(t.app,`app`),r=await ya(e,t.input);try{let i=S(await e.backend.pushFile(Y(e,t),r.backendInput,n));return{kind:`appPushed`,app:n,inputKind:r.inputKind,...i?{backendResult:i}:{},...y(`Pushed to ${n}`)}}finally{await r.cleanup?.()}},ha=async(e,t)=>{if(!e.backend.triggerAppEvent)throw new s(`UNSUPPORTED_OPERATION`,`apps.triggerEvent is not supported by this backend`);let n=ba(t.name);xa(t.payload,`apps.triggerEvent payload for "${n}"`);let r=S(await e.backend.triggerAppEvent(Y(e,t),{name:n,...t.payload?{payload:t.payload}:{}}));return{kind:`appEventTriggered`,name:n,...t.payload?{payload:t.payload}:{},...r?{backendResult:r}:{},...y(`Triggered app event: ${n}`)}};function ga(e){let t=K(e.app,`app`),n=K(e.appId,`appId`),r=K(e.bundleId,`bundleId`),i=K(e.packageName,`packageName`),a=K(e.url,`url`),o=K(e.activity,`activity`),c={...t?{app:t}:{},...n?{appId:n}:{},...r?{bundleId:r}:{},...i?{packageName:i}:{},...a?{url:a}:{},...o?{activity:o}:{}};if(!_a(c))throw new s(`INVALID_ARGS`,`apps.open requires app, appId, bundleId, packageName, url, or activity`);return c}function _a(e){return!!(e.app??e.appId??e.bundleId??e.packageName??e.url??e.activity)}function va(e){return e.app??e.appId??e.bundleId??e.packageName??e.url??e.activity??`app`}async function ya(e,t){if(!t||typeof t!=`object`)throw new s(`INVALID_ARGS`,`apps.push requires an input`);if(t.kind===`json`)return Sa(t.payload,`apps.push JSON payload`,8192),{backendInput:{kind:`json`,payload:t.payload},inputKind:`json`};let n=await z(e,t,{usage:`apps.push`,field:`input`});return{backendInput:{kind:`file`,path:n.path},inputKind:`file`,...n.cleanup?{cleanup:n.cleanup}:{}}}function ba(e){let t=q(e,`name`);if(!la.test(t))throw new s(`INVALID_ARGS`,`Invalid apps.triggerEvent name: ${t}`,{hint:`Use 1-64 chars: letters, numbers, underscore, dot, colon, or dash.`});return t}function xa(e,t){e!==void 0&&Sa(e,t,8192)}function Sa(e,t,n){if(Ca(e,t),Buffer.byteLength(wa(e,t),`utf8`)>n)throw new s(`INVALID_ARGS`,`${t} exceeds ${n} bytes`)}function Ca(e,t){if(!e||typeof e!=`object`||Array.isArray(e))throw new s(`INVALID_ARGS`,`${t} must be a JSON object`)}function wa(e,t){try{let n=JSON.stringify(e);if(typeof n!=`string`)throw new s(`INVALID_ARGS`,`${t} must be JSON-serializable`);return n}catch{throw new s(`INVALID_ARGS`,`${t} must be JSON-serializable`)}}function Y(e,t){return{session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata}}const Ta={open:ua,close:da,list:fa,state:pa,push:ma,triggerEvent:ha},Ea={devices:Yi,boot:Xi,shutdown:Zi,install:Qi,reinstall:$i,installFromSource:ea};function Da(e){return{...x(Ta,e),list:(t={})=>Ta.list(e,{...t,filter:lt(t.filter)})}}const Oa=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i,ka=/\b[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\b/g;function Aa(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(ka,()=>(t=!0,`[REDACTED]`)),n=Ma(n,()=>{t=!0}),{value:n,redacted:t}}function ja(e){try{let t=new URL(e),n=Na(t);return(t.username||t.password)&&(t.username=`REDACTED`,t.password=`REDACTED`,n=!0),{value:t.toString(),redacted:n}}catch{return}}function Ma(e,t){return/(https?:\/\/|token|secret|password|authorization|cookie|api[-_]?key)/i.test(e)?e.replaceAll(/https?:\/\/[^\s"'<>)]+/gi,e=>{let n=ja(e);return n?(n.redacted&&t(),n.value):e}):e}function Na(e){let t=!1;for(let n of Array.from(e.searchParams.keys()))Oa.test(n)&&(e.searchParams.set(n,`[REDACTED]`),t=!0);return t}const X=2048,Pa=4096,Fa=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i;function Ia(e){let t=e.redacted===!0;return{kind:`diagnosticsLogs`,entries:e.entries.map(e=>{let n=Q(e.message,Pa),r=Ua(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 La(e,t){let n=e.redacted===!0;return{kind:`diagnosticsNetwork`,entries:e.entries.map(e=>{let r=e.url?Ba(e.url):void 0,i=t===`headers`||t===`all`?za(e.requestHeaders):void 0,a=t===`headers`||t===`all`?za(e.responseHeaders):void 0,o=t===`body`||t===`all`?Va(e.requestBody):void 0,s=t===`body`||t===`all`?Va(e.responseBody):void 0,c=Ua(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 Ra(e){let t=e.redacted===!0;return{kind:`diagnosticsPerf`,metrics:e.metrics.map(e=>{let n=Q(e.message,Pa),r=Ua(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 za(e){if(!e)return{redacted:!1};let t=!1,n={};for(let[r,i]of Object.entries(e))if(Fa.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 Ba(e){return ja(e)??Q(e,X)}function Va(e){return e===void 0?{redacted:!1}:Ha(e)??Q(e,X)}function Ha(e){try{let t=Z(JSON.parse(e),Aa);return Wa(JSON.stringify(t.value),X,t.redacted)}catch{return}}function Ua(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(Fa.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=Aa(e);return Wa(n.value,t,n.redacted)}function Wa(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 Ga=async(e,t={})=>{if(!e.backend.readLogs)throw new s(`UNSUPPORTED_OPERATION`,`diagnostics.logs is not supported by this backend`);return Ia(await e.backend.readLogs(await Ja(e,t),Ya(t)))},Ka=async(e,t={})=>{if(!e.backend.dumpNetwork)throw new s(`UNSUPPORTED_OPERATION`,`diagnostics.network is not supported by this backend`);let n=Xa(t);return La(await e.backend.dumpNetwork(await Ja(e,t),n),n.include??`summary`)},qa=async(e,t={})=>{if(!e.backend.measurePerf)throw new s(`UNSUPPORTED_OPERATION`,`diagnostics.perf is not supported by this backend`);return Ra(await e.backend.measurePerf(await Ja(e,t),Za(t)))};async function Ja(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 Ya(e){return{...Qa(e,100,500,`logs limit`),...e.levels===void 0?{}:{levels:to(e.levels,`levels`)},...e.search===void 0?{}:{search:q(e.search,`search`)},...e.source===void 0?{}:{source:q(e.source,`source`)}}}function Xa(e){return{...Qa(e,25,200,`network limit`),include:eo(e.include)}}function Za(e){return{...$a(e),...e.sampleMs===void 0?{}:{sampleMs:C(e.sampleMs,`sampleMs`,100,6e4)},...e.metrics===void 0?{}:{metrics:to(e.metrics,`metrics`,20)}}}function Qa(e,t,n,r){return{...$a(e),...e.cursor===void 0?{}:{cursor:q(e.cursor,`cursor`)},limit:e.limit===void 0?t:C(e.limit,r,1,n)}}function $a(e){return{...e.since===void 0?{}:{since:q(e.since,`since`)},...e.until===void 0?{}:{until:q(e.until,`until`)}}}function eo(e){if(e===void 0)return`summary`;if(e===`summary`||e===`headers`||e===`body`||e===`all`)return e;throw new s(`INVALID_ARGS`,`network include must be summary, headers, body, or all`)}function to(e,t,n=50){if(!Array.isArray(e))throw new s(`INVALID_ARGS`,`${t} must be an array of strings`);if(e.length>n)throw new s(`INVALID_ARGS`,`${t} must contain at most ${n} entries`);return e.map((e,n)=>q(e,`${t}[${n}]`))}const no={logs:Ga,network:Ka,perf:qa},ro=async(e,t)=>{let n=co(t.action,`record`),r=n===`start`?e.backend.startRecording:e.backend.stopRecording;if(!r)throw new s(`UNSUPPORTED_OPERATION`,`record ${n} is not supported by this backend`);let i=t.out?await B(e,t.out,{field:`path`,ext:`.mp4`,artifactType:`screen-recording`}):void 0;try{let a=ao(t,i?.path);return lo(n,await r.call(e.backend,b(e,t),a),await i?.publish())}catch(e){throw await i?.cleanup?.(),e}},io=async(e,t)=>{let n=co(t.action,`trace`),r=n===`start`?e.backend.startTrace:e.backend.stopTrace;if(!r)throw new s(`UNSUPPORTED_OPERATION`,`trace ${n} is not supported by this backend`);let i=t.out?await B(e,t.out,{field:`outPath`,ext:`.trace`,artifactType:`trace-log`}):void 0;try{let a={...i?.path?{outPath:i.path}:{}};return uo(n,await r.call(e.backend,b(e,t),a),await i?.publish())}catch(e){throw await i?.cleanup?.(),e}};function ao(e,t){let n={};t&&(n.outPath=t);let r=oo(e.fps);r!==void 0&&(n.fps=r);let i=so(e.quality);return i!==void 0&&(n.quality=i),e.hideTouches!==void 0&&(n.showTouches=e.hideTouches!==!0),n}function oo(e){return e===void 0?void 0:C(e,`fps`,1,60)}function so(e){if(e===void 0)return;let t=et(e);if(t===void 0)throw new s(`INVALID_ARGS`,`quality must be one of: medium, high (legacy numeric values 5-10 are accepted)`);return t}function co(e,t){if(e===`start`||e===`stop`)return e;throw new s(`INVALID_ARGS`,`${t} action must be start or stop`)}function lo(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}:{},...fo(e,t,n,{startKind:`recordingStarted`,stopKind:`recordingStopped`,startMessage:`Recording started`,stopMessage:`Recording stopped`})}}function uo(e,t,n){return{...typeof t.outPath==`string`?{outPath:t.outPath}:{},...fo(e,t,n,{startKind:`traceStarted`,stopKind:`traceStopped`,startMessage:`Trace started`,stopMessage:`Trace stopped`})}}function fo(e,t,n,r){return{kind:e===`start`?r.startKind:r.stopKind,action:e,...n?{artifact:n}:{},backendResult:t,...y(e===`start`?r.startMessage:r.stopMessage)}}const po={record:ro,trace:io},mo=async(e,t={})=>{if(!e.backend.pressBack)throw new s(`UNSUPPORTED_OPERATION`,`system.back is not supported by this backend`);let n=t.mode??`in-app`;if(n!==`in-app`&&n!==`system`)throw new s(`INVALID_ARGS`,`system.back mode must be in-app or system`);let r=S(await e.backend.pressBack(b(e,t),{mode:n}));return{kind:`systemBack`,mode:n,...r?{backendResult:r}:{},...y(`Back`)}},ho=async(e,t={})=>{if(!e.backend.pressHome)throw new s(`UNSUPPORTED_OPERATION`,`system.home is not supported by this backend`);let n=S(await e.backend.pressHome(b(e,t)));return{kind:`systemHome`,...n?{backendResult:n}:{},...y(`Home`)}},go=async(e,t)=>{if(!e.backend.pressTvRemote)throw new s(`UNSUPPORTED_OPERATION`,`system.tvRemote is not supported by this backend`);let n=ae(t.button),r=t.durationMs===void 0?void 0:C(t.durationMs,`durationMs`,0,1e4),i=S(await e.backend.pressTvRemote(b(e,t),{button:n,...r===void 0?{}:{durationMs:r}}));return{kind:`tvRemotePressed`,button:n,...r===void 0?{}:{durationMs:r},...i?{backendResult:i}:{},...y(`Pressed TV remote ${n}`)}},_o=async(e,t)=>{if(!e.backend.setOrientation)throw new s(`UNSUPPORTED_OPERATION`,`system.orientation is not supported by this backend`);let n=Co(t.orientation),r=S(await e.backend.setOrientation(b(e,t),n));return{kind:`systemOrientationSet`,orientation:n,...r?{backendResult:r}:{},...y(`Rotated to ${n}`)}},vo=async(e,t={})=>{if(!e.backend.setKeyboard)throw new s(`UNSUPPORTED_OPERATION`,`system.keyboard is not supported by this backend`);let n=t.action??`status`;if(!st(n))throw new s(`INVALID_ARGS`,`system.keyboard action must be status, get, dismiss, enter, or return`);let r=await e.backend.setKeyboard(b(e,t),{action:n}),i=S(r),a=Mo(r)?r:{};return n===`enter`||n===`return`?To(a,i):n===`dismiss`?Eo(n,a,i):Oo(n,a,i)},yo=async(e,t)=>{if(t.action===`read`){if(!e.backend.getClipboard)throw new s(`UNSUPPORTED_OPERATION`,`system.clipboard read is not supported by this backend`);let n=await e.backend.getClipboard(b(e,t));return{kind:`clipboardText`,action:`read`,text:typeof n==`string`?n:n.text}}if(t.action!==`write`)throw new s(`INVALID_ARGS`,`system.clipboard action must be read or write`);if(!e.backend.setClipboard)throw new s(`UNSUPPORTED_OPERATION`,`system.clipboard write is not supported by this backend`);if(typeof t.text!=`string`)throw new s(`INVALID_ARGS`,`system.clipboard write requires text`);let n=S(await e.backend.setClipboard(b(e,t),t.text));return{kind:`clipboardUpdated`,action:`write`,textLength:Array.from(t.text).length,...n?{backendResult:n}:{},...y(`Clipboard updated`)}},bo=async(e,t={})=>{if(!e.backend.openSettings)throw new s(`UNSUPPORTED_OPERATION`,`system.settings is not supported by this backend`);let n=K(t.target,`target`),r=S(await e.backend.openSettings(b(e,t),n));return{kind:`settingsOpened`,...n?{target:n}:{},...r?{backendResult:r}:{},...y(n?`Opened settings: ${n}`:`Opened settings`)}},xo=async(e,t={})=>{if(!e.backend.handleAlert)throw new s(`UNSUPPORTED_OPERATION`,`system.alert is not supported by this backend`);let n=t.action??`get`;if(n!==`get`&&n!==`accept`&&n!==`dismiss`&&n!==`wait`)throw new s(`INVALID_ARGS`,`system.alert action must be get, accept, dismiss, or wait`);let r=t.timeoutMs===void 0?void 0:C(t.timeoutMs,`timeoutMs`,0,12e4);return wo(n,await e.backend.handleAlert(b(e,t),n,{timeoutMs:r}))},So=async(e,t={})=>{if(!e.backend.openAppSwitcher)throw new s(`UNSUPPORTED_OPERATION`,`system.appSwitcher is not supported by this backend`);let n=S(await e.backend.openAppSwitcher(b(e,t)));return{kind:`appSwitcherOpened`,...n?{backendResult:n}:{},...y(`Opened app switcher`)}};function Co(e){switch(e){case`portrait`:case`portrait-upside-down`:case`landscape-left`:case`landscape-right`:return e;default:throw new s(`INVALID_ARGS`,`system.orientation must be portrait, portrait-upside-down, landscape-left, or landscape-right`)}}function wo(e,t){return e===`get`?ko(t):e===`wait`?Ao(t):jo(e,t)}function To(e,t){return{kind:`keyboardEnterPressed`,action:`enter`,state:e,...t?{backendResult:t}:{},...y(`Keyboard enter pressed`)}}function Eo(e,t,n){return{kind:`keyboardDismissed`,action:e,state:t,...n?{backendResult:n}:{},...y(Do(t))}}function Do(e){return e.dismissed===!1?`Keyboard already hidden`:e.mechanism===`dismissKey`?`Keyboard dismissed via its dismiss key`:`Keyboard dismissed`}function Oo(e,t,n){return{kind:`keyboardState`,action:e,state:t,...n?{backendResult:n}:{}}}function ko(e){if(e.kind!==`alertStatus`)throw new s(`COMMAND_FAILED`,`system.alert get returned an invalid backend result`);return{kind:`alertStatus`,action:`get`,alert:e.alert}}function Ao(e){if(e.kind!==`alertWait`)throw new s(`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},...y(e.alert?`Alert visible`:`Alert wait timed out`)}}function jo(e,t){if(t.kind!==`alertHandled`)throw new s(`COMMAND_FAILED`,`system.alert ${e} returned an invalid backend result`);return{kind:`alertHandled`,action:e,handled:t.handled,...t.alert?{alert:t.alert}:{},...t.button?{button:t.button}:{},...y(t.handled?`Alert ${e}ed`:`No alert handled`)}}function Mo(e){return!!(e&&typeof e==`object`)}const No={back:mo,home:ho,orientation:_o,keyboard:vo,clipboard:yo,settings:bo,alert:xo,appSwitcher:So,tvRemote:go};function Po(e){return{capture:x(Zr,e),selectors:qi(e),interactions:Ji(e),system:x(No,e),apps:Da(e),admin:x(Ea,e),recording:x(po,e),observability:x(no,e)}}var Fo=r({createAgentDevice:()=>Io,createMemorySessionStore:()=>Lo,localCommandPolicy:()=>zo,restrictedCommandPolicy:()=>Bo});function Io(e){let t={backend:e.backend,artifacts:e.artifacts,sessions:e.sessions??Lo(),policy:e.policy??Bo(),diagnostics:e.diagnostics,clock:e.clock,signal:e.signal};return{...t,...Po(t)}}function Lo(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:Ro(e.metadata)}:{}}}function Ro(e){try{return structuredClone(e)}catch{return{...e}}}function zo(e={}){return{allowLocalInputPaths:!0,allowLocalOutputPaths:!0,maxImagePixels:2e7,...e}}function Bo(e={}){return{allowLocalInputPaths:!1,allowLocalOutputPaths:!1,maxImagePixels:2e7,...e}}export{Lt as _,Or as a,M as c,hn as d,tn as f,Pt as g,St as h,ei as i,N as l,xt as m,zo as n,Cr as o,bt as p,Fo as r,gn as s,Io as t,mn 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{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,4 +1,5 @@
1
- import{_ as e}from"./sdk-contracts.js";import{N as t,j as n}from"./sdk-batch-runner.js";import{_ as r,a as i,c as a,n as o,o as s,s as c,t as l,y as u}from"./src2.js";function d(t){if(!/^[a-zA-Z0-9._:-]+$/.test(t))throw new e(`INVALID_ARGS`,`Invalid Android package name for logs: ${t}`)}const f=Object.freeze({resourceKind:n,version:1,encode:e=>({...e}),decode:e=>e.transport!==`android-logcat-local`&&e.transport!==`android-logcat-transport-composed`||!m(e.outputPath)||!m(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 p(e){let t=f.decode(e.descriptor);if(t.status!==`decoded`)throw TypeError(t.message);return r({resourceKind:n,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:u(f,t.descriptor)})}function m(e){return typeof e==`string`&&e.trim().length>0}function h(e){return c(e,{family:`android`,backend:`android`,label:`Android`,codec:f,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 g(e,t.id,r,n),validateStart:({input:e})=>d(e.appBundleId),process:async({host:e,device:t,input:n})=>({resolvePid:async r=>await a(e,_(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})=>p({sessionId:e.sessionId,device:t,owner:n,fence:e.fence,descriptor:r})})}async function g(e,t,n,r){let o={};return o.adbAvailable=await s(async()=>i(await e.commands.run({executable:`adb`,args:[`-s`,t,`shell`,`echo`,`ok`],allowFailure:!0,timeoutMs:1e3},r)),r),n&&(o.androidPidVisible=await s(async()=>!!await a(e,_(t,n),r),r)),{backend:`android`,checks:o,notes:n?[]:[`No app bundle is tracked in this session. Run open <app> first for app-scoped logs.`]}}function _(e,t){return{executable:`adb`,args:[`-s`,e,`shell`,`pidof`,t],allowFailure:!0,timeoutMs:5e3}}async function v(e,t,n,r){let i=await e.appLogs.readRecent(n.sessionId,n.maxScanLines),a=o(i.text,{...n,path:i.path,exists:i.exists,lineNumberOffset:i.skippedLines,backend:`android`}),s=[],c=await b(e,t,n,r);if(c&&n.appBundleId){d(n.appBundleId);let u=await S(e,t,n.appBundleId,r);if(u){let e=o(u.text,{...n,path:`${i.path} (adb logcat recovery)`,exists:!0,backend:`android`});e.entries.length>0&&(a=l(e,a,n.maxEntries),s.push(c.reason===`stale-active`?`Session app log stream was still bound to prior Android PID ${c.trackedPid}. Recovered recent Android HTTP entries from adb logcat for PID set ${u.pids.join(`, `)}.`:`Session app log stream was inactive. Recovered recent Android HTTP entries from adb logcat for PID set ${u.pids.join(`, `)}.`))}}return n.appLogSnapshot?n.appLogSnapshot.state!==`active`&&s.length===0&&s.push(`Session app log stream is inactive. Run logs clear --restart, reproduce the request window again, then rerun network dump.`):s.push(`Capture uses the session app log file. For fresh traffic, run logs clear --restart before reproducing requests.`),a.entries.length===0&&s.push(`No HTTP(s) entries were found in recent session app logs.`),Object.freeze({source:`app-log`,backend:`android`,dump:a,notes:Object.freeze(s)})}async function y(e,t,n){n.throwIfAborted();try{let r=await e.commands.run(t,n);return n.throwIfAborted(),r}catch{n.throwIfAborted();return}}async function b(e,t,n,r){if(!n.appBundleId||n.appLogSnapshot?.state===void 0)return;if(n.appLogSnapshot.state!==`active`)return{reason:`inactive`};let i=x(await e.appLogs.readProcessMarker(n.sessionId));if(!i)return;let a=await C(e,t.id,n.appBundleId,r);if(!(!a||a===i))return{reason:`stale-active`,trackedPid:i}}function x(e){if(e.status===`decoded`)return/(?:^|\s)--pid\s+(\d+)(?:\s|$)/.exec(e.marker.command)?.[1]}async function S(e,t,n,r){let i=await C(e,t.id,n,r),a=await y(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=w(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{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(`
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 C(e,t,n,r){let i=await y(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 w(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 T=t(`android`),E=Object.freeze({available:!0});function D(e){let t=h(e);return Object.freeze({owner:T,ownsDevice:e=>e.platform===`android`,bind:async n=>{let r=await t.bind(n);return Object.freeze({device:r.device,owner:T,facts:Object.freeze({device:r.facts.device,operations:{...r.facts.operations,networkDump:E}}),operations:Object.freeze({...r.operations,networkDump:async t=>await v(e,n.device,t,n.scope.signal)}),[Symbol.asyncDispose]:async()=>await r[Symbol.asyncDispose]()})},shutdown:async()=>await t.shutdown()})}export{D as createAndroidPlatformRuntime};
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};
@@ -1,3 +1 @@
1
- import{_ as e}from"./sdk-contracts.js";import{N as t,R as n,j as r,z as i}from"./sdk-batch-runner.js";import{c as a,l as o}from"./sdk-device.js";import{_ as s,a as c,d as l,f as u,h as d,l as f,m as p,n as m,o as h,p as g,t as _,u as v,y}from"./src2.js";import b from"node:path";const x=`This command requires a CoreDevice-backed physical iOS device. The selected XCTest backend supports open, close, interactions, snapshots, and screenshots.`;function S(e){return o(e)?`macos`:e.kind===`device`?`ios-device`:`ios-simulator`}const C=Object.freeze({resourceKind:r,version:1,encode:e=>({...e}),decode:e=>!T(e.transport)||!E(e.backend)||!k(e.outputPath)||!D(e.pidPath)||!ee(e.transport,e.backend)?w():{status:`decoded`,descriptor:Object.freeze({transport:e.transport,backend:e.backend,outputPath:e.outputPath,...e.pidPath===void 0?{}:{pidPath:e.pidPath}})}});function w(){return{status:`invalid`,message:`Invalid Apple app-log descriptor`}}function T(e){return e===`apple-log-stream`||e===`coredevice-console`}function E(e){return e===`ios-simulator`||e===`ios-device`||e===`macos`}function ee(e,t){return e===`coredevice-console`?t===`ios-device`:t!==`ios-device`}function D(e){return e===void 0||k(e)}function O(e){if(!e.device.appleOs)throw TypeError(`Apple app-log persistence requires an explicit appleOs identity`);return s({resourceKind:r,sessionId:e.sessionId,device:{id:e.device.id,family:`apple`,appleOs:e.device.appleOs,kind:e.device.kind,...e.device.target===void 0?{}:{target:e.device.target},...e.device.iosPhysicalDeviceBackend===void 0?{}:{iosPhysicalDeviceBackend:e.device.iosPhysicalDeviceBackend}},owner:e.owner,fence:e.fence,lifecycle:`open`,descriptor:y(C,e.descriptor)})}function k(e){return typeof e==`string`&&e.trim().length>0}const A={message:`iOS physical-device app console capture is not supported by the installed devicectl.`,hint:`This devicectl does not expose process launch --console. Markers can still be written to app.log, but app output is not being captured. Use an iOS simulator for agent-device app logs or inspect physical-device logs in Console.app/Xcode until this Xcode toolchain exposes scriptable console capture.`},j={message:`Could not verify iOS physical-device app console capture support.`,hint:`Retry logs clear --restart. If the probe keeps failing, run logs doctor and inspect the request diagnostics for the devicectl help command.`};async function M(e,t){try{let n=await e.appleTools.run({tool:`devicectl`,args:[`device`,`process`,`launch`,`--help`],allowFailure:!0,timeoutMs:5e3},t),r=n.stderr.trim()||void 0;if(n.exitCode!==0)return{supported:!1,reason:`probe-failed`,stderr:r};let i=`${n.stdout}\n${n.stderr}`;return/\bUSAGE:\s+devicectl device process launch\b/i.test(i)&&/--console\b/.test(i)&&/--terminate-existing\b/.test(i)?{supported:!0,...r?{stderr:r}:{}}:{supported:!1,reason:`unsupported`,...r?{stderr:r}:{}}}catch(e){if(t?.aborted)throw t.reason;return{supported:!1,reason:`probe-failed`,...e instanceof Error?{stderr:e.message}:{}}}}async function N(e,t,n,r){let i={},a=n?[]:[`No app bundle is tracked in this session. Run open <app> first for app-scoped logs.`];if(o(t))i.logAvailable=!!await e.commands.which(`log`);else if(t.kind===`simulator`)i.simctlAvailable=await h(async()=>c(await e.appleTools.run({tool:`simctl`,args:[`help`],allowFailure:!0},r)),r);else if(t.iosPhysicalDeviceBackend===`xctest`)i.devicectlAvailable=!1,i.devicectlConsoleCapture=!1,a.push(x);else{i.devicectlAvailable=await h(async()=>c(await e.appleTools.run({tool:`devicectl`,args:[`--version`],allowFailure:!0},r)),r);let t=await M(e,r);if(i.devicectlConsoleCapture=t.supported,!t.supported){let e=t.reason===`unsupported`?A:j;a.push(`${e.message} ${e.hint}`)}}return{backend:S(t),checks:i,notes:a}}function P(e,t){let n=L(e),r=[`subsystem == "${n}"`,`subsystem CONTAINS "${n}"`,`processImagePath ENDSWITH[c] "/${n}"`,`senderImagePath ENDSWITH[c] "/${n}"`];if(t){let e=L(t);r.push(`process == "${e}"`,`processImagePath ENDSWITH[c] "/${e}"`,`senderImagePath ENDSWITH[c] "/${e}"`,`processImagePath CONTAINS[c] "/${e}.app/"`,`senderImagePath CONTAINS[c] "/${e}.app/"`)}return r.join(` OR `)}function F(e){return[...e.simulatorSetPath?[`simctl`,`--set`,e.simulatorSetPath]:[`simctl`],`spawn`,e.deviceId,`log`,`stream`,`--style`,`compact`,`--level`,`info`,`--predicate`,P(e.appBundleId,e.executableName)]}function I(e,t){return[`devicectl`,`device`,`process`,`launch`,`--device`,e,`--console`,`--terminate-existing`,t]}function L(e){return e.replaceAll(`\\`,`\\\\`).replaceAll(`"`,`\\"`)}async function R(e,t,n,r,a){z(t),v(e,n);let o=S(t),s=await V(e,t,n.appBundleId,a),c=new i,l=!1;try{let i=await e.outputs.openAppend(n.outputPath);c.defer(async()=>{l||await i[Symbol.asyncDispose]()}),a?.throwIfAborted();let u=await B(e,t,s,i,n.pidPath,a);c.defer(async()=>{l||await u[Symbol.asyncDispose]()});let f=te(e,u,i,o,n.outputPath),p={transport:o===`ios-device`?`coredevice-console`:`apple-log-stream`,backend:o,outputPath:n.outputPath,...n.pidPath===void 0?{}:{pidPath:n.pidPath}},m=d(f,O({sessionId:n.sessionId,device:t,owner:r,fence:n.fence,descriptor:p}));return l=!0,m}finally{await c[Symbol.asyncDispose]()}}function z(t){if(t.appleOs===`watchos`)throw new e(`UNSUPPORTED_PLATFORM`,`watchOS app logs are not supported`);if(a(t)&&t.kind===`device`&&t.iosPhysicalDeviceBackend===`xctest`)throw new e(`UNSUPPORTED_OPERATION`,x,{hint:x})}async function B(t,n,r,i,o,s){if(a(n)&&n.kind===`device`){let n=await M(t,s);if(!n.supported){let t=n.reason===`unsupported`?A:j;throw new e(n.reason===`unsupported`?`UNSUPPORTED_OPERATION`:`COMMAND_FAILED`,t.message,{backend:`ios-device`,hint:t.hint,stderr:n.stderr})}}return s?.throwIfAborted(),await t.processes.start({command:{kind:`host`,request:r},output:i,...o?{markerPath:o}:{}})}async function V(e,t,n,r){if(o(t))return{executable:`log`,args:[`stream`,`--style`,`compact`,`--predicate`,P(n)],allowFailure:!0};if(t.kind===`device`)return{executable:`xcrun`,args:I(t.id,n),allowFailure:!0};let i=await H(e,t,n,r);return{executable:`xcrun`,args:F({deviceId:t.id,appBundleId:n,executableName:i,simulatorSetPath:t.simulatorSetPath}),allowFailure:!0}}async function H(e,t,n,r){let i=t.simulatorSetPath?[`--set`,t.simulatorSetPath]:[],a=await e.appleTools.run({tool:`simctl`,args:[...i,`get_app_container`,t.id,n,`app`],allowFailure:!0,timeoutMs:4e3},r),o=a.exitCode===0?a.stdout.trim():``;if(!o)return;let s=await e.commands.run({executable:`plutil`,args:[`-extract`,`CFBundleExecutable`,`raw`,`-o`,`-`,b.join(o,`Info.plist`)],allowFailure:!0,timeoutMs:4e3},r);return s.exitCode===0&&s.stdout.trim()||void 0}function te(e,t,n,r,i){let a=e.clock.now(),o=`active`;t.wait.then(e=>{o=e.exitCode===0?`ended`:`failed`},()=>{o=`failed`});let s;return g({inspect:()=>({backend:r,state:o,startedAt:a}),finish:async()=>s??=(async()=>(await U([async()=>await t.terminate(),async()=>await t.wait.then(()=>void 0),async()=>await t[Symbol.asyncDispose](),async()=>await n[Symbol.asyncDispose]()])).length>0?(o=`failed`,{status:`cleanup-pending`,reason:`transport-failed`,message:`Apple app-log cleanup did not settle every owned resource`}):(o=`ended`,{status:`completed`,result:{backend:r,outputPath:i,completedAt:e.clock.now()}}))()})}async function U(e){let t=[];for(let n of e)try{await n()}catch(e){t.push(e)}return t}const W=t(`apple`),G=Object.freeze({available:!0});function K(t){return Object.freeze({owner:W,ownsDevice:e=>e.platform===`apple`,bind:async r=>{if(r.intent.kind===`exact-owner`&&!n(r.intent.owner,W))throw new e(`UNSUPPORTED_OPERATION`,`Apple app-log owner identity does not match`);return q(t,r.device,r.scope.signal)},shutdown:async()=>void 0})}function q(t,n,r){if(n.platform!==`apple`)throw new e(`UNSUPPORTED_PLATFORM`,`Apple app-log owner cannot bind ${n.platform}`);let i=p({codec:C,reattach:async(e,r)=>e.backend!==S(n)||!f(t,r.sessionId,e)?{status:`unreattachable`,reason:`descriptor-invalid`,message:`Apple app-log descriptor does not match the bound device or owning session`}:await u(t,e.pidPath),cleanup:async(e,r)=>e.backend===S(n)&&f(t,r.sessionId,e)?await l(t,e.pidPath):{status:`cleanup-pending`,reason:`ownership-fence-lost`,message:`Apple app-log descriptor does not match the bound device or owning session`}}),a=Object.freeze({appLogInspect:async()=>({backend:S(n)}),appLogDoctor:async({appBundleId:e})=>await N(t,n,e,r),appLogStart:async e=>await R(t,n,e,W,r),...i});return Object.freeze({device:n,owner:W,facts:J(n),operations:a,[Symbol.asyncDispose]:async()=>void 0})}function J(e){if(e.appleOs===`watchos`)return Y(e);let t=a(e)&&e.kind===`device`&&e.iosPhysicalDeviceBackend===`xctest`?{available:!1,reason:`unsupported-device-backend`,hint:x}:G;return Object.freeze({device:{family:`apple`,appleOs:e.appleOs,kind:e.kind,...e.target===void 0?{}:{target:e.target},...e.iosPhysicalDeviceBackend===void 0?{}:{iosPhysicalDeviceBackend:e.iosPhysicalDeviceBackend},providerMode:`local`},operations:{appLogInspect:t,appLogDoctor:t,appLogStart:t,appLogReattach:G,appLogCleanup:G}})}function Y(e){let t=Object.freeze({available:!1,reason:`unsupported-platform-leaf`,hint:`watchOS app logs are not supported.`});return Object.freeze({device:{family:`apple`,appleOs:`watchos`,kind:e.kind,...e.target===void 0?{}:{target:e.target},providerMode:`local`},operations:{appLogInspect:t,appLogDoctor:t,appLogStart:t,appLogReattach:t,appLogCleanup:t}})}async function X(e,t,n,r){let i=S(t),a=await e.appLogs.readRecent(n.sessionId,n.maxScanLines),o=m(a.text,{...n,path:a.path,exists:a.exists,lineNumberOffset:a.skippedLines,backend:i}),s=[];if(Z(t,n,o)){let i=await Q(e,t,n,a.path,r);i&&(i.dump.entries.length>0?(o=_(i.dump,o,n.maxEntries),s.push(`Recovered ${i.dump.entries.length} iOS simulator HTTP entr${i.dump.entries.length===1?`y`:`ies`} from simctl log show (${i.lineCount} app log lines scanned).`)):i.lineCount>0&&s.push(`Recovered ${i.lineCount} recent iOS simulator app log lines from simctl log show, but none looked like HTTP traffic. This app may not emit request URLs, status, or timing into Unified Logging for this repro window.`))}return re(s,t,n),o.entries.length===0&&s.push(ie(t)),Object.freeze({source:`app-log`,backend:i,dump:o,notes:Object.freeze(s)})}function Z(e,t,n){return a(e)&&e.kind===`simulator`&&!!t.appBundleId&&n.entries.length===0}async function Q(e,t,n,r,i){let a=[...t.simulatorSetPath?[`--set`,t.simulatorSetPath]:[],`spawn`,t.id,`log`,`show`,`--style`,`compact`,`--info`,`--predicate`,ne(n.appBundleId)],o=n.appLogSnapshot?.startedAt;a.push(...typeof o==`number`&&Number.isFinite(o)&&o>0?[`--start`,`@${Math.floor(o/1e3)}`]:[`--last`,`5m`]);let s=await e.appleTools.run({tool:`simctl`,args:a,allowFailure:!0,timeoutMs:4e3},i);if(s.exitCode!==0||!s.stdout.trim())return;let c=s.stdout.split(`
2
- `).map(e=>e.trimEnd()).filter(e=>e.trim()&&!e.trim().startsWith(`Timestamp Ty Process[PID:TID]`));if(c.length!==0)return{dump:m(`${c.join(`
3
- `)}\n`,{...n,path:`${r} (simctl log show recovery)`,exists:!0,backend:`ios-simulator`}),lineCount:c.length}}function ne(e){let t=e.replaceAll(`\\`,`\\\\`).replaceAll(`"`,`\\"`);return[`subsystem == "${t}"`,`subsystem CONTAINS "${t}"`,`processImagePath ENDSWITH[c] "/${t}"`,`senderImagePath ENDSWITH[c] "/${t}"`].join(` OR `)}function re(e,t,n){n.appLogSnapshot?n.appLogSnapshot.state!==`active`&&e.length===0&&e.push(a(t)&&t.kind===`simulator`?`Session app log stream is inactive. The iOS simulator recovery path scanned recent simctl log history, but a fresh logs clear --restart window is still the most reliable repro loop.`:`Session app log stream is inactive. Run logs clear --restart, reproduce the request window again, then rerun network dump.`):e.push(`Capture uses the session app log file. For fresh traffic, run logs clear --restart before reproducing requests.`)}function ie(e){return a(e)&&e.kind===`simulator`?`No HTTP(s) entries were found in recent iOS simulator app logs. If the app only emits non-HTTP diagnostics, inspect logs path or add app-side URLSession/network logging for per-request timing and payload details.`:a(e)?`No HTTP(s) entries were found in recent iOS device app logs. iOS network dump only sees what the app emits into Unified Logging for this process.`:`No HTTP(s) entries were found in recent session app logs.`}const $=t(`apple`),ae=Object.freeze({available:!0});function oe(e){let t=K(e);return Object.freeze({owner:$,ownsDevice:e=>e.platform===`apple`,bind:async n=>{let r=await t.bind(n);return Object.freeze({device:r.device,owner:$,facts:Object.freeze({device:r.facts.device,operations:{...r.facts.operations,networkDump:ae}}),operations:Object.freeze({...r.operations,networkDump:async t=>await X(e,n.device,t,n.scope.signal)}),[Symbol.asyncDispose]:async()=>await r[Symbol.asyncDispose]()})},shutdown:async()=>await t.shutdown()})}export{oe as createApplePlatformRuntime};
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 +1,3 @@
1
- import{_ as e}from"./sdk-contracts.js";import{N as t,j as n}from"./sdk-batch-runner.js";import{_ as r,c as i,s as a,y as o}from"./src2.js";const s=Object.freeze({resourceKind:n,version:1,encode:e=>({...e}),decode:e=>e.transport!==`harmony-hilog`||!l(e.outputPath)||!l(e.pidPath)?{status:`invalid`,message:`Invalid HarmonyOS app-log descriptor`}:{status:`decoded`,descriptor:Object.freeze({transport:`harmony-hilog`,outputPath:e.outputPath,pidPath:e.pidPath})}});function c(e){return r({resourceKind:n,sessionId:e.sessionId,device:{id:e.device.id,family:`harmonyos`,kind:e.device.kind,...e.device.target===void 0?{}:{target:e.device.target}},owner:e.owner,fence:e.fence,lifecycle:`open`,descriptor:o(s,e.descriptor)})}function l(e){return typeof e==`string`&&e.trim().length>0}function u(e){return a(e,{family:`harmonyos`,backend:`harmonyos`,label:`HarmonyOS`,codec:s,startUnavailableHint:`The selected HarmonyOS transport cannot start a background hilog stream.`,cleanupFailureMessage:`HarmonyOS app-log cleanup did not settle every owned resource`,doctor:async(e,t)=>({backend:`harmonyos`,checks:{},notes:t?[]:[`No app bundle is tracked in this session. Run open <app> first for app-scoped logs.`]}),process:async({host:e,device:t,input:n,signal:r})=>{let a=await d(e,r);return{resolvePid:async r=>await i(e,{executable:a,args:[`-t`,t.id,`shell`,`pidof`,n.appBundleId],allowFailure:!0,timeoutMs:5e3},r),command:e=>({kind:`host`,request:{executable:a,args:[`-t`,t.id,`shell`,`hilog`,`-P`,e],allowFailure:!0}})}},descriptor:({artifacts:e})=>({transport:`harmony-hilog`,...e}),envelope:({input:e,device:t,owner:n,descriptor:r})=>c({sessionId:e.sessionId,device:t,owner:n,fence:e.fence,descriptor:r})})}async function d(t,n){n.throwIfAborted(),await f(async()=>await t.toolchains.prepare(`harmonyos`),n),n.throwIfAborted();let r=await f(async()=>await t.commands.which(`hdc`),n);if(n.throwIfAborted(),!r)throw new e(`TOOL_MISSING`,`hdc not found in PATH`,{hint:`Install HarmonyOS Command Line Tools, then add its sdk/default/openharmony/toolchains directory to PATH.`});return r}async function f(e,t){try{return await e()}catch(e){throw t.throwIfAborted(),e}}const p=t(`harmonyos`),m=Object.freeze({available:!1,reason:`unsupported-platform-leaf`});function h(e){let t=u(e);return Object.freeze({owner:p,ownsDevice:e=>e.platform===`harmonyos`,bind:async e=>{let n=await t.bind(e);return Object.freeze({device:n.device,owner:p,facts:Object.freeze({device:n.facts.device,operations:{...n.facts.operations,networkDump:m}}),operations:n.operations,[Symbol.asyncDispose]:async()=>await n[Symbol.asyncDispose]()})},shutdown:async()=>await t.shutdown()})}export{h as createHarmonyPlatformRuntime};
1
+ import{_ as e,v as t}from"./sdk-contracts.js";import{H as n,K as r,U as i,at as a,bt as o,dt as s,et as c,ot as l,st as u,tt as d,ut as f,wt as p,z as ee}from"./sdk-batch-runner.js";import{C as te,c as m,l as h,s as g,x as _}from"./sdk-device.js";import{c as ne,f as re,g as ie,h as ae,i as oe,l as se,m as ce,n as le,p as ue,r as v,s as y,t as de,u as fe,v as b,x}from"./src3.js";import{n as S,t as pe}from"./simulator-state.js";import me from"node:path";const C=`This command requires a CoreDevice-backed physical iOS device. The selected XCTest backend supports open, close, interactions, snapshots, and screenshots.`;function w(e){return h(e)?`macos`:e.kind===`device`?`ios-device`:`ios-simulator`}const T=Object.freeze({resourceKind:d,version:1,encode:e=>({...e}),decode:e=>!ge(e.transport)||!_e(e.backend)||!E(e.outputPath)||!ye(e.pidPath)||!ve(e.transport,e.backend)?he():{status:`decoded`,descriptor:Object.freeze({transport:e.transport,backend:e.backend,outputPath:e.outputPath,...e.pidPath===void 0?{}:{pidPath:e.pidPath}})}});function he(){return{status:`invalid`,message:`Invalid Apple app-log descriptor`}}function ge(e){return e===`apple-log-stream`||e===`coredevice-console`}function _e(e){return e===`ios-simulator`||e===`ios-device`||e===`macos`}function ve(e,t){return e===`coredevice-console`?t===`ios-device`:t!==`ios-device`}function ye(e){return e===void 0||E(e)}function be(e){if(!e.device.appleOs)throw TypeError(`Apple app-log persistence requires an explicit appleOs identity`);return b({resourceKind:d,sessionId:e.sessionId,device:{id:e.device.id,family:`apple`,appleOs:e.device.appleOs,kind:e.device.kind,...e.device.target===void 0?{}:{target:e.device.target},...e.device.iosPhysicalDeviceBackend===void 0?{}:{iosPhysicalDeviceBackend:e.device.iosPhysicalDeviceBackend}},owner:e.owner,fence:e.fence,lifecycle:`open`,descriptor:x(T,e.descriptor)})}function E(e){return typeof e==`string`&&e.trim().length>0}const D={message:`iOS physical-device app console capture is not supported by the installed devicectl.`,hint:`This devicectl does not expose process launch --console. Markers can still be written to app.log, but app output is not being captured. Use an iOS simulator for agent-device app logs or inspect physical-device logs in Console.app/Xcode until this Xcode toolchain exposes scriptable console capture.`},xe={message:`Could not verify iOS physical-device app console capture support.`,hint:`Retry logs clear --restart. If the probe keeps failing, run logs doctor and inspect the request diagnostics for the devicectl help command.`};async function Se(e,t){try{let n=await e.appleTools.run({tool:`devicectl`,args:[`device`,`process`,`launch`,`--help`],allowFailure:!0,timeoutMs:5e3},t),r=n.stderr.trim()||void 0;if(n.exitCode!==0)return{supported:!1,reason:`probe-failed`,stderr:r};let i=`${n.stdout}\n${n.stderr}`;return/\bUSAGE:\s+devicectl device process launch\b/i.test(i)&&/--console\b/.test(i)&&/--terminate-existing\b/.test(i)?{supported:!0,...r?{stderr:r}:{}}:{supported:!1,reason:`unsupported`,...r?{stderr:r}:{}}}catch(e){if(t?.aborted)throw t.reason;return{supported:!1,reason:`probe-failed`,...e instanceof Error?{stderr:e.message}:{}}}}async function Ce(e,t,n,r){let i={},a=n?[]:[`No app bundle is tracked in this session. Run open <app> first for app-scoped logs.`];if(h(t))i.logAvailable=!!await e.commands.which(`log`);else if(t.kind===`simulator`)i.simctlAvailable=await oe(async()=>v(await e.appleTools.run({tool:`simctl`,args:[`help`],allowFailure:!0},r)),r);else if(t.iosPhysicalDeviceBackend===`xctest`)i.devicectlAvailable=!1,i.devicectlConsoleCapture=!1,a.push(C);else{i.devicectlAvailable=await oe(async()=>v(await e.appleTools.run({tool:`devicectl`,args:[`--version`],allowFailure:!0},r)),r);let t=await Se(e,r);if(i.devicectlConsoleCapture=t.supported,!t.supported){let e=t.reason===`unsupported`?D:xe;a.push(`${e.message} ${e.hint}`)}}return{backend:w(t),checks:i,notes:a}}function we(e,t){let n=O(e),r=[`subsystem == "${n}"`,`subsystem CONTAINS "${n}"`,`processImagePath ENDSWITH[c] "/${n}"`,`senderImagePath ENDSWITH[c] "/${n}"`];if(t){let e=O(t);r.push(`process == "${e}"`,`processImagePath ENDSWITH[c] "/${e}"`,`senderImagePath ENDSWITH[c] "/${e}"`,`processImagePath CONTAINS[c] "/${e}.app/"`,`senderImagePath CONTAINS[c] "/${e}.app/"`)}return r.join(` OR `)}function Te(e){return[...e.simulatorSetPath?[`simctl`,`--set`,e.simulatorSetPath]:[`simctl`],`spawn`,e.deviceId,`log`,`stream`,`--style`,`compact`,`--level`,`info`,`--predicate`,we(e.appBundleId,e.executableName)]}function Ee(e,t){return[`devicectl`,`device`,`process`,`launch`,`--device`,e,`--console`,`--terminate-existing`,t]}function O(e){return e.replaceAll(`\\`,`\\\\`).replaceAll(`"`,`\\"`)}async function De(e,t,n,r,i){Oe(t),ne(e,n);let a=w(t),o=await Ae(e,t,n.appBundleId,i),s=new f,c=!1;try{let l=await e.outputs.openAppend(n.outputPath);s.defer(async()=>{c||await l[Symbol.asyncDispose]()}),i?.throwIfAborted();let u=await ke(e,t,o,l,n.pidPath,i);s.defer(async()=>{c||await u[Symbol.asyncDispose]()});let d=Me(e,u,l,a,n.outputPath),f={transport:a===`ios-device`?`coredevice-console`:`apple-log-stream`,backend:a,outputPath:n.outputPath,...n.pidPath===void 0?{}:{pidPath:n.pidPath}},p=ie(d,be({sessionId:n.sessionId,device:t,owner:r,fence:n.fence,descriptor:f}));return c=!0,p}finally{await s[Symbol.asyncDispose]()}}function Oe(t){if(t.appleOs===`watchos`)throw new e(`UNSUPPORTED_PLATFORM`,`watchOS app logs are not supported`);if(m(t)&&t.kind===`device`&&t.iosPhysicalDeviceBackend===`xctest`)throw new e(`UNSUPPORTED_OPERATION`,C,{hint:C})}async function ke(t,n,r,i,a,o){if(m(n)&&n.kind===`device`){let n=await Se(t,o);if(!n.supported){let t=n.reason===`unsupported`?D:xe;throw new e(n.reason===`unsupported`?`UNSUPPORTED_OPERATION`:`COMMAND_FAILED`,t.message,{backend:`ios-device`,hint:t.hint,stderr:n.stderr})}}return o?.throwIfAborted(),await t.processes.start({command:{kind:`host`,request:r},output:i,...a?{markerPath:a}:{}})}async function Ae(e,t,n,r){if(h(t))return{executable:`log`,args:[`stream`,`--style`,`compact`,`--predicate`,we(n)],allowFailure:!0};if(t.kind===`device`)return{executable:`xcrun`,args:Ee(t.id,n),allowFailure:!0};let i=await je(e,t,n,r);return{executable:`xcrun`,args:Te({deviceId:t.id,appBundleId:n,executableName:i,simulatorSetPath:t.simulatorSetPath}),allowFailure:!0}}async function je(e,t,n,r){let i=t.simulatorSetPath?[`--set`,t.simulatorSetPath]:[],a=await e.appleTools.run({tool:`simctl`,args:[...i,`get_app_container`,t.id,n,`app`],allowFailure:!0,timeoutMs:4e3},r),o=a.exitCode===0?a.stdout.trim():``;if(!o)return;let s=await e.commands.run({executable:`plutil`,args:[`-extract`,`CFBundleExecutable`,`raw`,`-o`,`-`,me.join(o,`Info.plist`)],allowFailure:!0,timeoutMs:4e3},r);return s.exitCode===0&&s.stdout.trim()||void 0}function Me(e,t,n,r,i){let a=e.clock.now(),o=`active`;t.wait.then(e=>{o=e.exitCode===0?`ended`:`failed`},()=>{o=`failed`});let s;return ce({inspect:()=>({backend:r,state:o,startedAt:a}),finish:async()=>s??=(async()=>(await Ne([async()=>await t.terminate(),async()=>await t.wait.then(()=>void 0),async()=>await t[Symbol.asyncDispose](),async()=>await n[Symbol.asyncDispose]()])).length>0?(o=`failed`,{status:`cleanup-pending`,reason:`transport-failed`,message:`Apple app-log cleanup did not settle every owned resource`}):(o=`ended`,{status:`completed`,result:{backend:r,outputPath:i,completedAt:e.clock.now()}}))()})}async function Ne(e){let t=[];for(let n of e)try{await n()}catch(e){t.push(e)}return t}const k=o(`apple`),A=Object.freeze({available:!0});function Pe(t){return Object.freeze({owner:k,ownsDevice:e=>e.platform===`apple`,inspectFacts:async e=>j(e),bind:async n=>{if(n.intent.kind===`exact-owner`&&!p(n.intent.owner,k))throw new e(`UNSUPPORTED_OPERATION`,`Apple app-log owner identity does not match`);return Fe(t,n.device,n.scope.signal)},shutdown:async()=>void 0})}function Fe(t,n,r){if(n.platform!==`apple`)throw new e(`UNSUPPORTED_PLATFORM`,`Apple app-log owner cannot bind ${n.platform}`);let i=ae({codec:T,reattach:async(e,r)=>e.backend!==w(n)||!y(t,r.sessionId,e)?{status:`unreattachable`,reason:`descriptor-invalid`,message:`Apple app-log descriptor does not match the bound device or owning session`}:await fe(t,e.pidPath),cleanup:async(e,r)=>e.backend===w(n)&&y(t,r.sessionId,e)?await se(t,e.pidPath):{status:`cleanup-pending`,reason:`ownership-fence-lost`,message:`Apple app-log descriptor does not match the bound device or owning session`}}),a=Object.freeze({appLogInspect:async()=>({backend:w(n)}),appLogDoctor:async({appBundleId:e})=>await Ce(t,n,e,r),appLogStart:async e=>await De(t,n,e,k,r),...i});return Object.freeze({device:n,owner:k,facts:j(n),operations:a,[Symbol.asyncDispose]:async()=>void 0})}function j(e){if(e.appleOs===`watchos`)return Ie(e);let t=m(e)&&e.kind===`device`&&e.iosPhysicalDeviceBackend===`xctest`?{available:!1,reason:`unsupported-device-backend`,hint:C}:A;return Object.freeze({device:{family:`apple`,appleOs:e.appleOs,kind:e.kind,...e.target===void 0?{}:{target:e.target},...e.iosPhysicalDeviceBackend===void 0?{}:{iosPhysicalDeviceBackend:e.iosPhysicalDeviceBackend},providerMode:`local`},operations:{appLogInspect:t,appLogDoctor:t,appLogStart:t,appLogReattach:A,appLogCleanup:A}})}function Ie(e){let t=Object.freeze({available:!1,reason:`unsupported-platform-leaf`,hint:`watchOS app logs are not supported.`});return Object.freeze({device:{family:`apple`,appleOs:`watchos`,kind:e.kind,...e.target===void 0?{}:{target:e.target},providerMode:`local`},operations:{appLogInspect:t,appLogDoctor:t,appLogStart:t,appLogReattach:t,appLogCleanup:t}})}async function Le(e,t,n,r){let i=w(t),a=await e.appLogs.readRecent(n.sessionId,n.maxScanLines),o=le(a.text,{...n,path:a.path,exists:a.exists,lineNumberOffset:a.skippedLines,backend:i}),s=[];if(Re(t,n,o)){let i=await ze(e,t,n,a.path,r);i&&(i.dump.entries.length>0?(o=de(i.dump,o,n.maxEntries),s.push(`Recovered ${i.dump.entries.length} iOS simulator HTTP entr${i.dump.entries.length===1?`y`:`ies`} from simctl log show (${i.lineCount} app log lines scanned).`)):i.lineCount>0&&s.push(`Recovered ${i.lineCount} recent iOS simulator app log lines from simctl log show, but none looked like HTTP traffic. This app may not emit request URLs, status, or timing into Unified Logging for this repro window.`))}return Ve(s,t,n),o.entries.length===0&&s.push(He(t)),Object.freeze({source:`app-log`,backend:i,dump:o,notes:Object.freeze(s)})}function Re(e,t,n){return m(e)&&e.kind===`simulator`&&!!t.appBundleId&&n.entries.length===0}async function ze(e,t,n,r,i){let a=[...t.simulatorSetPath?[`--set`,t.simulatorSetPath]:[],`spawn`,t.id,`log`,`show`,`--style`,`compact`,`--info`,`--predicate`,Be(n.appBundleId)],o=n.appLogSnapshot?.startedAt;a.push(...typeof o==`number`&&Number.isFinite(o)&&o>0?[`--start`,`@${Math.floor(o/1e3)}`]:[`--last`,`5m`]);let s=await e.appleTools.run({tool:`simctl`,args:a,allowFailure:!0,timeoutMs:4e3},i);if(s.exitCode!==0||!s.stdout.trim())return;let c=s.stdout.split(`
2
+ `).map(e=>e.trimEnd()).filter(e=>e.trim()&&!e.trim().startsWith(`Timestamp Ty Process[PID:TID]`));if(c.length!==0)return{dump:le(`${c.join(`
3
+ `)}\n`,{...n,path:`${r} (simctl log show recovery)`,exists:!0,backend:`ios-simulator`}),lineCount:c.length}}function Be(e){let t=e.replaceAll(`\\`,`\\\\`).replaceAll(`"`,`\\"`);return[`subsystem == "${t}"`,`subsystem CONTAINS "${t}"`,`processImagePath ENDSWITH[c] "/${t}"`,`senderImagePath ENDSWITH[c] "/${t}"`].join(` OR `)}function Ve(e,t,n){n.appLogSnapshot?n.appLogSnapshot.state!==`active`&&e.length===0&&e.push(m(t)&&t.kind===`simulator`?`Session app log stream is inactive. The iOS simulator recovery path scanned recent simctl log history, but a fresh logs clear --restart window is still the most reliable repro loop.`:`Session app log stream is inactive. Run logs clear --restart, reproduce the request window again, then rerun network dump.`):e.push(`Capture uses the session app log file. For fresh traffic, run logs clear --restart before reproducing requests.`)}function He(e){return m(e)&&e.kind===`simulator`?`No HTTP(s) entries were found in recent iOS simulator app logs. If the app only emits non-HTTP diagnostics, inspect logs path or add app-side URLSession/network logging for per-request timing and payload details.`:m(e)?`No HTTP(s) entries were found in recent iOS device app logs. iOS network dump only sees what the app emits into Unified Logging for this process.`:`No HTTP(s) entries were found in recent session app logs.`}async function M(e,n,r){if(n.invalidatedReason&&!n.showTouches)throw Error(`recording invalidated: ${n.invalidatedReason}`);let i;try{i=await e.screenRecording.finalize.complete({outputPath:n.outPath,showTouches:n.invalidatedReason?!1:n.showTouches,gestureEvents:n.gestureEvents,exportQuality:n.exportQuality??`medium`,...n.runnerStartedAtUptimeMs!==void 0&&n.targetAppReadyUptimeMs!==void 0?{trimStartMs:Math.max(0,n.targetAppReadyUptimeMs-n.runnerStartedAtUptimeMs)}:{},targetLabel:r})}catch(e){throw t(e,`COMMAND_FAILED`)}return re(n,{...i,...n.invalidatedReason?{overlayWarning:`overlay unavailable: ${n.invalidatedReason}`}:{}})}const N=Object.freeze({resourceKind:c,version:1,encode:e=>e.backend===`simctl`?{backend:e.backend,outputPath:e.outputPath,processes:e.processes.map(e=>({...e}))}:{backend:e.backend,outputPath:e.outputPath,appBundleId:e.appBundleId,runnerSessionId:e.runnerSessionId,runnerAuthority:e.runnerAuthority,...e.remotePath===void 0?{}:{remotePath:e.remotePath}},decode:e=>Je(e)});function Ue(e){let{device:t,owner:n,input:r,descriptor:i}=e;return b({resourceKind:c,sessionId:r.sessionId,device:te(t),owner:n,fence:r.fence,lifecycle:`open`,descriptor:x(N,i)})}async function We(e,t,n){let r=N.decode(n);return r.status!==`decoded`||!I(t,r.descriptor)?{status:`cleanup-pending`,reason:`manual-recovery-required`}:r.descriptor.backend===`simctl`?await Ge(e,r.descriptor.processes):await Ke(e,t,r.descriptor)}async function Ge(e,t){let n=await Promise.all(t.map(async t=>await e.screenRecording.apple.inspectProcess(t)));if(n.includes(`ownership-lost`))return{status:`cleanup-pending`,reason:`ownership-fence-lost`};if(n.every(e=>e===`missing`))return{status:`already-missing`};let r=await Promise.all(t.flatMap((t,r)=>n[r]===`owned-alive`?[e.screenRecording.apple.terminateProcess(t)]:[]));return r.includes(`ownership-lost`)?{status:`cleanup-pending`,reason:`ownership-fence-lost`}:r.every(e=>e===`already-missing`)?{status:`already-missing`}:{status:`cleaned`}}async function Ke(e,t,n){try{let r=await e.screenRecording.apple.inspectRunner(t,n.runnerSessionId,n.runnerAuthority);return r===`missing`?{status:`already-missing`}:r===`ownership-lost`?{status:`cleanup-pending`,reason:`ownership-fence-lost`}:(await e.screenRecording.apple.runRunner(t,{kind:`stop`,appBundleId:n.appBundleId,runnerSessionId:n.runnerSessionId,runnerAuthority:n.runnerAuthority}),{status:`cleaned`})}catch(e){return{status:`cleanup-pending`,reason:`transport-failed`,message:e instanceof Error?e.message:`Apple recording cleanup failed`}}}async function qe(e,t,n){let r=N.decode(n);if(r.status!==`decoded`)return{status:`unreattachable`,reason:`descriptor-invalid`,message:r.message};if(!I(t,r.descriptor))return{status:`unreattachable`,reason:`descriptor-invalid`,message:`Apple screen-recording descriptor does not match the bound device.`};let i=r.descriptor.backend===`simctl`?await Promise.all(r.descriptor.processes.map(async t=>await e.screenRecording.apple.inspectProcess(t))):[await e.screenRecording.apple.inspectRunner(t,r.descriptor.runnerSessionId,r.descriptor.runnerAuthority)];return i.every(e=>e===`missing`)?{status:`missing`}:{status:`unreattachable`,reason:`transport-not-reattachable`,message:i.includes(`ownership-lost`)?`Apple recording ownership no longer matches the durable descriptor.`:`Apple screen recordings require exact cleanup after daemon restart.`}}function Je(e){return typeof e.outputPath!=`string`||e.outputPath.length===0?L():e.backend===`simctl`?Ye(e,e.outputPath):e.backend===`runner`?Xe(e,e.outputPath):L()}function Ye(e,t){let n=$e(e.processes);return n?{status:`decoded`,descriptor:Object.freeze({backend:`simctl`,outputPath:t,processes:n})}:L()}function Xe(e,t){return!P(e.appBundleId)||!P(e.runnerSessionId)||!Ze(e.runnerAuthority)||!Qe(e.remotePath)?L():{status:`decoded`,descriptor:Object.freeze({backend:`runner`,outputPath:t,appBundleId:e.appBundleId,runnerSessionId:e.runnerSessionId,runnerAuthority:e.runnerAuthority,...e.remotePath===void 0?{}:{remotePath:e.remotePath}})}}function P(e){return typeof e==`string`&&e.length>0}function Ze(e){return e===`local-lease`||e===`scoped-provider`}function Qe(e){return e===void 0||F(e)}function F(e){return typeof e==`string`&&/^tmp\/agent-device-recording-\d+\.mp4$/.test(e)}function I(e,t){return e.kind===`simulator`?t.backend===`simctl`:t.backend===`runner`?e.appleOs===`macos`?t.remotePath===void 0:m(e)?t.remotePath!==void 0&&F(t.remotePath):t.remotePath===void 0:!1}function $e(e){if(!Array.isArray(e)||e.length===0)return;let t=e.filter(e=>typeof e==`object`&&!!e&&Number.isInteger(e.pid)&&(e.pid??0)>0&&typeof e.startTime==`string`&&e.startTime.length>0&&typeof e.command==`string`&&e.command.length>0);return t.length===e.length?Object.freeze([...t]):void 0}function L(){return{status:`invalid`,message:`Invalid Apple screen-recording descriptor`}}async function et(e,t,n){if(e.kind!==`simulator`||t.scope!==`app`)return;let r=t.activeSessionApp?.bundleId;if(!r)throw TypeError(`App-scoped recording requires an active app session; open the app under test before recording.`);if(await n(r))throw TypeError(`App-scoped recording requires a real application session; open the app under test before recording.`)}function tt(e){return e.appleOs===`watchos`?V(`unsupported-platform-leaf`,`watchOS recording is not supported.`):m(e)&&e.kind===`device`&&e.iosPhysicalDeviceBackend===`xctest`?V(`unsupported-device-backend`,`This command requires a CoreDevice-backed physical iOS device. The selected XCTest backend supports open, close, interactions, snapshots, and screenshots.`):Object.freeze({available:!0})}function nt(e){let{host:t,device:n,owner:r,signal:i}=e;return Object.freeze({screenRecordingStart:async e=>await rt({host:t,device:n,owner:r,input:e,signal:i}),screenRecordingReattach:async e=>await qe(t,n,e.envelope.descriptor.body),screenRecordingCleanup:async e=>await We(t,n,e.envelope.descriptor.body)})}async function rt(e){return e.signal.throwIfAborted(),e.device.kind===`simulator`?await it(e):await at(e)}async function it(e){let{host:t,device:n,owner:r,input:i,signal:a}=e;await et(n,i,t.screenRecording.apple.isRunnerBundleId);let o=i.activeSessionApp?await t.screenRecording.apple.captureClockAnchor(n,i.activeSessionApp.bundleId,a):void 0;await t.screenRecording.outputs.prepare(i.outputPath);let s=await t.screenRecording.apple.startSimulator(n,i.outputPath,a),c=s.markers;if(!c||c.length===0)throw await R(s).catch(()=>{}),Error(`simctl recordVideo did not expose durable process identity`);try{a.throwIfAborted()}catch(e){throw await R(s).catch(()=>{}),e}return z({device:n,owner:r,input:i,descriptor:{backend:`simctl`,outputPath:i.outputPath,processes:c},snapshot:B(i,`simctl recordVideo`,{},o),finish:async e=>{await s.terminate();let n=await s.wait;if(n.exitCode!==0)throw Error(`simctl recordVideo exited with code ${n.exitCode}`);return await M(t,e,`iOS recording`)},cleanup:async()=>await ct(s)})}async function at(e){let{host:t,device:n,owner:r,input:i,signal:a}=e,o=i.activeSessionApp?.bundleId;if(!o)throw TypeError(`Apple runner recording requires an active app session identity`);await t.screenRecording.outputs.prepare(i.outputPath);let s=await t.screenRecording.apple.runRunner(n,{kind:`start`,appBundleId:o,outputPath:i.outputPath,...i.fps===void 0?{}:{fps:i.fps}},a);if(!s.runnerSessionId||!s.runnerAuthority)throw Error(`Apple runner recording did not expose durable session ownership`);let c={runnerSessionId:s.runnerSessionId,runnerAuthority:s.runnerAuthority},l,u=()=>l??=ot(()=>t.screenRecording.apple.runRunner(n,{kind:`stop`,appBundleId:o,...c}).then(()=>void 0));if(!st(n,s.remotePath))throw await u().catch(()=>{}),Error(`Apple runner recording did not expose coherent durable media ownership`);try{a.throwIfAborted()}catch(e){throw await u().catch(()=>{}),e}return z({device:n,owner:r,input:i,descriptor:{backend:`runner`,outputPath:i.outputPath,appBundleId:o,...c,...s.remotePath===void 0?{}:{remotePath:s.remotePath}},snapshot:B(i,`runner AVAssetWriter`,s),finish:async e=>(await u(),s.remotePath!==void 0&&await t.screenRecording.apple.retrieveRunnerRecording(n,s.remotePath,e.outPath),await M(t,e,n.appleOs===`macos`?`macOS recording`:`iOS recording`)),cleanup:async()=>(await u(),{status:`cleaned`})})}async function ot(e){try{return await e()}catch(e){throw t(e,`COMMAND_FAILED`)}}function st(e,t){return e.appleOs===`macos`||!m(e)?t===void 0:t!==void 0&&/^tmp\/agent-device-recording-\d+\.mp4$/.test(t)}async function R(e){return await e.terminate(),await e.wait}async function ct(e){try{return await R(e),{status:`cleaned`}}catch(e){return{status:`cleanup-pending`,reason:`transport-failed`,message:e instanceof Error?e.message:`Apple simulator cleanup failed`}}}function z(e){let{device:t,owner:n,input:r,descriptor:i,snapshot:a,finish:o,cleanup:c}=e,l=ue(a,{finish:o,forceCleanup:c});return Object.freeze({pendingHandle:new s(l),envelope:Ue({device:t,owner:n,input:r,descriptor:i})})}function B(e,t,n={},r){let i=Date.now();return Object.freeze({backend:t,outPath:e.outputPath,...e.clientOutputPath===void 0?{}:{clientOutPath:e.clientOutputPath},startedAt:i,scope:e.scope,showTouches:e.showTouches,recordOnlySession:e.recordOnlySession,...e.activeSessionApp===void 0?{}:{activeSessionApp:e.activeSessionApp},...e.exportQuality===void 0?{}:{exportQuality:e.exportQuality},gestureEvents:[],...r===void 0?{}:{gestureClockOriginAtMs:r.wallClockAtMs,gestureClockOriginUptimeMs:r.uptimeMs},...n.recorderStartUptimeMs===void 0?{}:{gestureClockOriginAtMs:i,gestureClockOriginUptimeMs:n.recorderStartUptimeMs,runnerStartedAtUptimeMs:n.recorderStartUptimeMs},...n.targetAppReadyUptimeMs===void 0?{}:{targetAppReadyUptimeMs:n.targetAppReadyUptimeMs},...n.runnerSessionId===void 0?{}:{runnerSessionId:n.runnerSessionId}})}function V(e,t){return Object.freeze({available:!1,reason:e,hint:t})}const H=12e4;async function U(e,t,n,r={}){return n.throwIfAborted(),h(t)?{...t,booted:!0}:t.kind===`device`?(await e.deviceReadiness.applePhysical.ensureConnected(t,n),{...t,booted:!0}):t.kind===`simulator`?(await W(e,t,n)!==`Booted`&&(r.onColdBootStart?.(),e.deviceReadiness.appleAutomation.keepHot(t),await lt(e,t,n),await ut(e,n)),e.deviceReadiness.appleAutomation.keepHot(t),e.deviceReadiness.appleAutomation.markBooted(t),{...t,booted:!0}):{...t,booted:!0}}async function lt(t,n,r){let i=!1;try{let a=await t.appleTools.run({tool:`simctl`,args:S(n,[`boot`,n.id]),allowFailure:!0,timeoutMs:H},r),o=`${a.stdout}\n${a.stderr}`.toLowerCase(),s=o.includes(`already booted`)||o.includes(`current state: booted`);if(a.exitCode!==0&&!s)throw new e(`COMMAND_FAILED`,`simctl boot failed`,{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});i=!s;let c=await t.appleTools.run({tool:`simctl`,args:S(n,[`bootstatus`,n.id,`-b`]),allowFailure:!0,timeoutMs:H},r);if(c.exitCode!==0)throw new e(`COMMAND_FAILED`,`simctl bootstatus failed`,{stdout:c.stdout,stderr:c.stderr,exitCode:c.exitCode});if(await W(t,n,r)!==`Booted`)throw new e(`COMMAND_FAILED`,`Simulator is still booting`,{deviceId:n.id})}catch(e){throw i&&r.aborted&&dt(t,n),r.throwIfAborted(),e}}async function W(e,t,n){return await pe(e.appleTools,t,n,15e3)}async function ut(e,t){await e.commands.run({executable:`open`,args:[`-a`,`Simulator`],allowFailure:!0,timeoutMs:1e4},t)}function dt(e,t){e.appleTools.run({tool:`simctl`,args:S(t,[`shutdown`,t.id]),allowFailure:!0}).catch(()=>{})}function ft(e){let t=ee({device:e.device,signal:e.signal,resolveInteractor:e.host.localInteractors.resolve});return Object.freeze({resolveOpenTarget:async t=>await e.host.appleApplications.resolveOpenTarget(e.device,t),prepareApplicationOpen:async t=>{await U(e.host,e.device,e.signal,{onColdBootStart:t.prewarmRunnerOnColdBoot?()=>{e.host.appleApplications.prewarmRunnerCache(e.device,t.execution,e.signal).catch(()=>{})}:void 0})},openApplication:async n=>await pt(e.host,t,n),applyRuntimeHints:async t=>await e.host.appleApplications.applyRuntimeHints(e.device,t),clearRuntimeHints:async t=>await e.host.appleApplications.clearRuntimeHints(e.device,t),closeApplication:async n=>await Ct(e.host,t,n),finalizeApplicationClose:async t=>await wt(e.host,e.device,e.signal,t),prepareAppleRunner:async t=>await Tt(e.host,e.device,e.signal,t),configureProviderPortReverse:kt})}async function pt(e,t,n){let r={},i=G(t.device),a=Et(e,t,n,r),o=m(t.device)&&n.surface===`app`&&n.positionals.length>0&&!!n.appBundleId;i&&o&&!n.prewarmRunnerBeforeOpen&&a.schedule(),await mt(e,t,n,i,r),await ht(n,r),await gt(a,o,n.prewarmRunnerBeforeOpen);let s=a.wasAwaited();return await _t(t,n,i,r),await yt(a,o,n.relaunch),await bt(e,t,n,i,s),await xt(e,t,i,r),{appBundleId:n.appBundleId,timing:r}}async function mt(e,t,r,i,a){if(!St(r,i)||!r.target)return;let o=Date.now();g(t.device.platform)&&!i&&await e.appleApplications.stopRunnerSession(t.device.id),await n({device:t.device,interactor:await t.resolveInteractor(r.execution,r.appBundleId),positionals:[r.appBundleId??r.target]}),i&&await e.clock.sleep(300,t.signal),a.relaunchCloseDurationMs=K(o)}async function ht(t,n){if(!u(t.runtimeHints))return;if(!t.applyRuntimeHints)throw new e(`COMMAND_FAILED`,`Runtime hint operation was not admitted for this open.`,{reason:`runtime-hints-operation-missing`});let r=Date.now();await t.applyRuntimeHints({appId:t.appBundleId,values:t.runtimeHints}),n.runtimeHintsDurationMs=K(r)}async function gt(e,t,n){!t||!n||(e.schedule(!0),await e.wait())}async function _t(e,t,n,r){let a=Dt(t,n),o=Date.now();await i({device:e.device,interactor:await e.resolveInteractor(t.execution,t.appBundleId),positionals:a.positionals,appBundleId:t.appBundleId,execution:t.execution,...n&&t.relaunch&&!t.execution.clearAppState?{terminateRunningApp:!0}:{}}),r.openDispatchDurationMs=K(o),await vt(e,t,a.followUpUrl,r)}async function vt(e,t,n,r){if(!n){r.launchUrlDurationMs=0;return}let a={...t.execution,clearAppState:void 0,launchConsole:void 0,launchArgs:void 0},o=Date.now();await i({device:e.device,interactor:await e.resolveInteractor(a,t.appBundleId),positionals:[n],appBundleId:t.appBundleId,execution:a}),r.launchUrlDurationMs=K(o)}async function yt(e,t,n){t&&!e.wasScheduled()&&e.schedule(),n?await e.wait():e.recordUnawaited()}async function bt(e,t,n,r,i){!r||!n.relaunch&&!i||await e.appleApplications.notifyRunnerAppRelaunched(t.device,n.execution,t.signal)}async function xt(e,t,n,r){let i=Date.now();n&&await e.clock.sleep(300,t.signal),r.postOpenSettleDurationMs=K(i)}function St(e,t){return!!(e.relaunch&&e.target)&&!(t&&!e.execution.clearAppState)}async function Ct(e,t,r){r.ensureReady&&await U(e,t.device,t.signal),g(t.device.platform)&&!G(t.device)&&await e.appleApplications.stopRunnerSession(t.device.id),await n({device:t.device,interactor:await t.resolveInteractor(r.execution,r.appBundleId),positionals:r.positionals}),G(t.device)&&await e.clock.sleep(300,t.signal)}async function wt(e,t,n,r){r.daemonShutdown?await e.appleApplications.dismissCloseAlerts(t,r).catch(()=>{}):r.retainRunner?(e.appleApplications.scheduleRunnerIdleStop(t.id),await e.appleApplications.dismissCloseAlerts(t,r).catch(()=>{})):(await e.appleApplications.stopRunnerSession(t.id),await e.appleApplications.dismissCloseAlerts(t,r).catch(()=>{}));let i=r.shutdownTarget&&G(t)?await e.deviceShutdown.apple.shutdownTarget(t,n):void 0;return i===void 0?{}:{shutdown:i}}async function Tt(e,t,n,r){return await U(e,t,n),await e.appleApplications.prepareRunner(t,r,n)}function Et(e,t,n,r){let i,a=!1;return{schedule:(a=!1)=>{i||=(r.runnerPrewarmKind=`session`,r.runnerPrewarmScheduled=!0,e.appleApplications.prewarmRunnerSession(t.device,n.execution,t.signal,a))},wait:async()=>{if(!i||a)return;a=!0;let e=Date.now();await i,r.runnerPrewarmWaited=!0,r.runnerPrewarmDurationMs=K(e)},wasAwaited:()=>a,wasScheduled:()=>i!==void 0,recordUnawaited:()=>{i&&!a&&(r.runnerPrewarmWaited=!1)}}}function Dt(e,t){let n=e.runtimeLaunchUrl?.trim(),i=e.positionals.length===1?e.positionals[0]?.trim():void 0;return!n||!i||r(i)?{positionals:e.positionals}:t&&!Ot(e)?{positionals:[i,n]}:{positionals:e.positionals,followUpUrl:n}}function Ot(e){return e.execution.clearAppState===!0||!!e.execution.launchConsole?.trim()||!!e.execution.launchArgs?.length}function G(e){return m(e)&&e.kind===`simulator`}function K(e){return Math.max(0,Date.now()-e)}async function kt(){throw new e(`UNSUPPORTED_OPERATION`,`This lifecycle operation is unavailable for Apple.`)}const q=Object.freeze({available:!0}),At=Object.freeze({available:!1,reason:`unsupported-device-backend`,hint:`This command requires a CoreDevice-backed physical iOS device. The selected XCTest backend supports open, close, interactions, snapshots, and screenshots.`}),jt=Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`Push notifications are supported on Apple simulators only.`}),J=Object.freeze({available:!1,reason:`unsupported-platform-leaf`}),Mt=Object.freeze({available:!1,reason:`unsupported-device-kind`});function Y(e){let t=Bt(e);return Object.freeze({deployApp:t,materializeAppSource:t,deployMaterializedApp:t,sendPushNotification:Vt(e)})}function Nt(e){let{host:t,device:n,signal:r}=e,i=Y(n);return Object.freeze({...i.deployApp.available?{deployApp:async e=>await Pt(t,n,e,r),materializeAppSource:async e=>await t.appleDeployment.prepareArtifact(e,{signal:r}),deployMaterializedApp:async e=>await Ft(t,n,e,r)}:{},...i.sendPushNotification.available?{sendPushNotification:async e=>(await Rt(t,n,e,r),{})}:{}})}async function Pt(e,t,n,r){if(n.replaceExisting)return await e.appleDeployment.withInvalidatedAppResolutionCache(t,async()=>{let i=await e.appleDeployment.resolveAppBundleId(t,n.app);await Lt(e,t,i,r);let a=await e.appleDeployment.prepareArtifact({source:{kind:`path`,path:n.appPath}},{appIdentifierHint:n.app,signal:r});try{return await It(e,t,a.installablePath,r),{bundleId:i,launchTarget:i}}finally{await a.cleanup()}});let i=await e.appleDeployment.prepareArtifact({source:{kind:`path`,path:n.appPath}},{appIdentifierHint:n.app,signal:r});try{return await Ft(e,t,{artifact:i},r)}finally{await i.cleanup()}}async function Ft(e,t,n,r){return await It(e,t,n.artifact.installablePath,r),{...n.artifact.bundleId?{bundleId:n.artifact.bundleId}:{},...n.artifact.appName?{appName:n.artifact.appName}:{},...n.artifact.bundleId?{launchTarget:n.artifact.bundleId}:{}}}async function It(e,t,n,r){await U(e,t,r),X(await e.appleTools.run(t.kind===`simulator`?{tool:`simctl`,args:S(t,[`install`,t.id,n])}:{tool:`devicectl`,args:[`device`,`install`,`app`,`--device`,t.id,n],timeoutMs:12e4},r),`Apple app install failed`)}async function Lt(e,t,n,r){await U(e,t,r);let i=await e.appleTools.run(t.kind===`simulator`?{tool:`simctl`,args:S(t,[`uninstall`,t.id,n]),allowFailure:!0}:{tool:`devicectl`,args:[`device`,`uninstall`,`app`,`--device`,t.id,n],allowFailure:!0},r);i.exitCode===0||zt(`${i.stdout}\n${i.stderr}`)||X(i,`Apple app uninstall failed for ${n}`)}async function Rt(t,n,r,i){if(n.kind!==`simulator`)throw new e(`UNSUPPORTED_OPERATION`,`Apple push notifications require a simulator`);await U(t,n,i);let a=await t.temporaryFiles.create({prefix:`agent-device-ios-push-`,suffix:`.apns`});try{await a.writeText(`${JSON.stringify(r.payload)}\n`),X(await t.appleTools.run({tool:`simctl`,args:S(n,[`push`,n.id,r.appId,a.path])},i),`Apple push notification failed`)}finally{await a[Symbol.asyncDispose]()}}function zt(e){let t=e.toLowerCase();return t.includes(`not installed`)||t.includes(`not found`)||t.includes(`no such file`)}function X(t,n){if(t.exitCode!==0)throw new e(`COMMAND_FAILED`,n,{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode})}function Bt(e){return Ht(e)?e.kind!==`simulator`&&e.kind!==`device`?Mt:e.kind===`device`&&e.iosPhysicalDeviceBackend===`xctest`?At:q:J}function Vt(e){return Ht(e)?e.kind===`simulator`?q:jt:J}function Ht(e){return m(e)&&e.appleOs!==`watchos`}const Z=o(`apple`),Q=Object.freeze({available:!0}),$=Object.freeze({available:!1,reason:`unsupported-platform-leaf`}),Ut=Object.freeze({available:!1,reason:`unsupported-platform-leaf`,hint:`Apple appstate reads the active session state; a sessionless runtime foreground probe is unavailable.`}),Wt=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Headless boot is supported only for local Android emulators.`}),Gt=Object.freeze({available:!1,reason:`unsupported-platform-leaf`,hint:`watchOS open is not supported because XCUITest cannot drive watchOS UI.`}),Kt=Object.freeze({available:!1,reason:`unsupported-platform-leaf`,hint:`watchOS runner preparation is not supported because XCUITest cannot drive watchOS UI.`}),qt=Object.freeze({available:!1,reason:`unsupported-platform-leaf`,hint:`watchOS close is not supported because XCUITest cannot drive watchOS UI.`}),Jt=Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`Runtime hints are supported only for local iOS-family simulators and Android devices.`}),Yt=Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`open is supported only for Apple simulators and devices.`}),Xt=Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`prepare is supported only for Apple simulators and devices.`}),Zt=Object.freeze({available:!1,reason:`unsupported-device-kind`,hint:`close is supported only for Apple simulators 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){return!m(e)||e.appleOs===`watchos`?$:e.kind===`simulator`?Q:$t}function tn(e){let t=nn(e),n=rn(e),r=an(e),i=on(e);return a({resolveOpenTarget:t,prepareApplicationOpen:t,openApplication:t,applyRuntimeHints:i,clearRuntimeHints:i,closeApplication:r,finalizeApplicationClose:r,prepareAppleRunner:n,configureProviderPortReverse:Qt})}function nn(e){return _(e)===`watchos`?Gt:e.kind===`simulator`||e.kind===`device`?Q:Yt}function rn(e){return _(e)===`watchos`?Kt:e.kind===`simulator`||e.kind===`device`?Q:Xt}function an(e){return _(e)===`watchos`?qt:e.kind===`simulator`||e.kind===`device`?Q:Zt}function on(e){return _(e)!==`watchos`&&m(e)&&e.kind===`simulator`?Q:Jt}function sn(e){return e.appleOs===`watchos`?Object.freeze({available:!1,reason:`unsupported-platform-leaf`,hint:`watchOS app inventory is not supported.`}):e.kind===`device`&&e.iosPhysicalDeviceBackend===`xctest`?Object.freeze({available:!1,reason:`unsupported-device-backend`,hint:`App inventory is available only on CoreDevice-backed physical iOS devices.`}):Q}function cn(e){let t=Pe(e),n=async n=>{let r=await t.inspectFacts(n),i=Y(n),a=tt(n),o=a.available?await e.screenRecording.apple.availability(n):void 0,s=a.available&&o?.available===!1?Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:o.hint}):a,c=n.appleOs===`watchos`?$:Q,l=h(n)||n.appleOs===`watchos`?$:Q,u=sn(n);return Object.freeze({device:r.device,operations:{...r.operations,...i,appState:Ut,networkDump:Q,screenRecordingStart:s,screenRecordingReattach:s,screenRecordingCleanup:s,ensureReady:c,bootTarget:l,bootTargetHeadless:Wt,listApps:u,...tn(n),shutdownTarget:en(n)}})};return Object.freeze({owner:Z,ownsDevice:e=>e.platform===`apple`,inspectFacts:n,bind:async r=>{let i=await t.bind(r),a=await n(r.device),o=a.operations.screenRecordingStart;return Object.freeze({device:i.device,owner:Z,facts:a,operations:Object.freeze({...i.operations,...Nt({host:e,device:r.device,signal:r.scope.signal}),networkDump:async t=>await Le(e,r.device,t,r.scope.signal),...o.available?nt({host:e,device:r.device,owner:Z,signal:r.scope.signal}):{},...a.operations.ensureReady.available?{ensureReady:async()=>await U(e,r.device,r.scope.signal)}:{},...a.operations.bootTarget.available?{bootTarget:async()=>await U(e,r.device,r.scope.signal)}:{},...a.operations.listApps.available?{listApps:async t=>await e.appInventory.apple.listApps(t.device,t.filter,r.scope.signal)}:{},...l(ft({host:e,device:r.device,signal:r.scope.signal}),a.operations),...a.operations.shutdownTarget.available?{shutdownTarget:async()=>await e.deviceShutdown.apple.shutdownTarget(r.device,r.scope.signal)}:{}}),[Symbol.asyncDispose]:async()=>await i[Symbol.asyncDispose]()})},shutdown:async()=>await t.shutdown()})}export{cn as createApplePlatformRuntime};