agent-device 0.21.3 → 0.21.4

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 (131) hide show
  1. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.3.apk → agent-device-android-ime-helper-0.21.4.apk} +0 -0
  2. package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.4.apk.sha256 +1 -0
  3. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.3.manifest.json → agent-device-android-ime-helper-0.21.4.manifest.json} +4 -4
  4. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.3.apk → agent-device-android-snapshot-helper-0.21.4.apk} +0 -0
  5. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.4.apk.sha256 +1 -0
  6. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.4.manifest.json +16 -0
  7. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +39 -0
  8. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSystemSurfaceHostPolicy.swift +9 -1
  9. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +2 -1
  10. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +10 -1
  11. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +26 -124
  12. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +46 -0
  13. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +36 -4
  14. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+MainThreadWork.swift +229 -0
  15. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +15 -0
  16. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +4 -40
  17. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +6 -40
  18. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Transport.swift +30 -9
  19. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +22 -6
  20. package/dist/src/adapter.js +1 -1
  21. package/dist/src/adb-executor.js +2 -2
  22. package/dist/src/adb-failure.js +1 -1
  23. package/dist/src/agent-browser-process-record.js +1 -1
  24. package/dist/src/agent-device-client.js +2 -2
  25. package/dist/src/api.js +3 -11
  26. package/dist/src/app-launch.js +1 -1
  27. package/dist/src/app-lifecycle.js +1 -1
  28. package/dist/src/app-log-reconnect.js +1 -1
  29. package/dist/src/archive.js +2 -2
  30. package/dist/src/cli-help.js +2 -2
  31. package/dist/src/cli.js +4 -4
  32. package/dist/src/client-metro-companion.js +1 -1
  33. package/dist/src/client-metro.js +1 -1
  34. package/dist/src/client-types.d.ts +69 -4
  35. package/dist/src/code-signature-cache.js +1 -1
  36. package/dist/src/command-tools.js +2 -2
  37. package/dist/src/command.js +1 -1
  38. package/dist/src/connection-runtime.js +1 -1
  39. package/dist/src/contracts.js +1 -1
  40. package/dist/src/daemon-client-lifecycle.js +1 -1
  41. package/dist/src/daemon-shutdown-report.js +1 -1
  42. package/dist/src/device-claim-rule.js +1 -1
  43. package/dist/src/device-input-state.d.ts +10 -8
  44. package/dist/src/device-inventory-context.js +1 -1
  45. package/dist/src/device-session.js +1 -1
  46. package/dist/src/diagnostics.js +1 -1
  47. package/dist/src/error.js +2 -2
  48. package/dist/src/exec.js +1 -1
  49. package/dist/src/file.js +1 -1
  50. package/dist/src/find.js +1 -1
  51. package/dist/src/gesture-runtime.js +1 -1
  52. package/dist/src/helper.js +1 -1
  53. package/dist/src/index.js +1 -1
  54. package/dist/src/install-source-network-transport.js +1 -1
  55. package/dist/src/interaction2.js +1 -1
  56. package/dist/src/interactor.js +4 -4
  57. package/dist/src/internal/bin.js +1 -1
  58. package/dist/src/internal/daemon.js +2 -2
  59. package/dist/src/internal/png-worker.js +1 -1
  60. package/dist/src/ios-client.js +121 -7
  61. package/dist/src/ios-snapshot-adapter.js +1 -1
  62. package/dist/src/ios-system-surface.js +1 -1
  63. package/dist/src/limrun-delta-sync-omitted.js +1 -0
  64. package/dist/src/limrun.d.ts +0 -1598
  65. package/dist/src/location-coordinates.js +1 -1
  66. package/dist/src/mechanics.js +16 -16
  67. package/dist/src/output-common.js +2 -0
  68. package/dist/src/owner-identity.js +1 -1
  69. package/dist/src/perf-runtime-operation-builder.js +1 -1
  70. package/dist/src/perf-runtime-plan.js +1 -1
  71. package/dist/src/platform-runtime-android-adb-host.js +1 -1
  72. package/dist/src/platform-runtime-app-log-android-transport.js +1 -1
  73. package/dist/src/platform-runtime-app-log-process.js +1 -1
  74. package/dist/src/platform-runtime-host.js +1 -1
  75. package/dist/src/platform-runtime-operation-host.js +2 -2
  76. package/dist/src/platform-runtime-screen-recording-android-host.js +1 -1
  77. package/dist/src/platform-runtime-screen-recording-finalizer-host.js +1 -1
  78. package/dist/src/platform-runtime-screen-recording-output-host.js +1 -1
  79. package/dist/src/platform-runtime-screen-recording-process-host.js +1 -1
  80. package/dist/src/process.js +1 -1
  81. package/dist/src/proxy.js +1 -1
  82. package/dist/src/quality-warnings.js +1 -1
  83. package/dist/src/react-native.js +1 -1
  84. package/dist/src/record-runtime.js +1 -1
  85. package/dist/src/recording-stop-observation.js +1 -0
  86. package/dist/src/registry.js +35 -36
  87. package/dist/src/replay-divergence.js +1 -1
  88. package/dist/src/reporting.js +11 -9
  89. package/dist/src/result-serialization.js +1 -1
  90. package/dist/src/runner-cache-metadata.js +1 -1
  91. package/dist/src/runner-client.js +1 -1
  92. package/dist/src/runner-disposal.js +1 -1
  93. package/dist/src/runner-operations-facade.js +1 -1
  94. package/dist/src/runner.js +1 -1
  95. package/dist/src/runtime.js +3 -3
  96. package/dist/src/runtime10.js +1 -1
  97. package/dist/src/runtime2.js +4 -4
  98. package/dist/src/runtime3.js +1 -1
  99. package/dist/src/runtime4.js +4 -4
  100. package/dist/src/runtime5.js +1 -1
  101. package/dist/src/runtime6.js +1 -1
  102. package/dist/src/runtime9.js +1 -1
  103. package/dist/src/screen-recording-completion.js +1 -1
  104. package/dist/src/screen-recording-resource-recovery.js +1 -1
  105. package/dist/src/screenshot-result.js +1 -1
  106. package/dist/src/sdk-contracts.js +2 -2
  107. package/dist/src/sdk-selectors.d.ts +36 -24
  108. package/dist/src/selector-runtime.js +1 -1
  109. package/dist/src/session-observation.js +1 -1
  110. package/dist/src/session-snapshot.js +1 -1
  111. package/dist/src/session-store.js +2 -2
  112. package/dist/src/session2.js +5 -5
  113. package/dist/src/snapshot-runtime.js +1 -1
  114. package/dist/src/snapshot.js +1 -1
  115. package/dist/src/snapshot4.js +1 -1
  116. package/dist/src/stop-sequence.js +1 -0
  117. package/dist/src/success-text.js +1 -1
  118. package/dist/src/text-entry-focus.js +1 -0
  119. package/dist/src/tool-provider.js +1 -1
  120. package/dist/src/tool-provider2.js +1 -1
  121. package/dist/src/tool-provider3.js +1 -1
  122. package/dist/src/type-text-runtime.js +1 -1
  123. package/dist/src/video.js +2 -2
  124. package/dist/src/yauzl.js +1 -0
  125. package/package.json +2 -2
  126. package/server.json +2 -2
  127. package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.3.apk.sha256 +0 -1
  128. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.3.apk.sha256 +0 -1
  129. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.3.manifest.json +0 -17
  130. package/dist/src/audio-probe-support.js +0 -1
  131. package/dist/src/screen-recording-live-handle.js +0 -1
@@ -1,19 +1,19 @@
1
- import{r as e}from"./rolldown-runtime.js";import{C as t,M as n,R as r,d as i,p as a,w as o}from"./sdk-contracts.js";import"./capture.js";import{E as s}from"./sdk-batch-runner.js";import{a as c,d as l,i as u,l as d,o as f,r as p,t as ee,u as te}from"./android-input-ownership.js";import{Lr as ne,Rr as re,Vr as ie,zr as ae}from"./sdk-batch.js";import{i as oe,n as se,r as ce}from"./snapshot-scope.js";import{_ as le,d as ue,p as de}from"./scroll-gesture.js";import{n as fe}from"./success-text.js";import{n as pe}from"./alert-contract.js";import{c as me,n as he,s as ge}from"./location-coordinates.js";import{r as _e}from"./mobile-snapshot-semantics.js";import"./device.js";import{n as ve}from"./device-rotation.js";import{c as m,r as h}from"./diagnostics.js";import{a as ye,c as be,m as xe,n as Se,s as Ce}from"./exec.js";import{t as g}from"./timeouts.js";import{i as we}from"./tv-remote.js";import"./diagnostics2.js";import{n as _,r as Te}from"./command.js";import"./retry.js";import{n as Ee,r as De}from"./version.js";import{n as Oe,r as ke}from"./install-source2.js";import{a as Ae,i as je,n as v,r as y}from"./adb-host.js";import{i as Me,n as b,o as Ne}from"./adb-failure.js";import{a as x,c as Pe,d as Fe,i as Ie,l as Le,n as Re,o as S,r as ze,s as Be,t as Ve,u as He}from"./adb-executor.js";import{n as Ue,r as C}from"./adb.js";import{i as We,n as Ge,r as Ke}from"./gesture-plan.js";import{n as qe,r as Je,s as Ye}from"./android-system-chrome.js";import{a as Xe,c as Ze,i as Qe,l as $e,n as et,o as tt,r as nt,s as rt,u as it}from"./app-lifecycle.js";import{a as at,i as ot,n as st,o as ct,r as lt,t as ut}from"./app-deployment-resolution.js";import{a as dt,i as ft,n as pt,o as mt,t as ht}from"./app-parsers.js";import{i as gt,n as _t,r as vt,t as yt}from"./window-state.js";import{n as bt}from"./toolchain-probe.js";import{t as xt}from"./keyed-lock.js";import{t as St}from"./bounds.js";import{t as Ct}from"./entities.js";import{n as wt}from"./startup-recovery-fence.js";import{n as Tt}from"./numeric.js";import w from"node:path";import Et from"node:net";import{TextDecoder as Dt}from"node:util";const Ot=new Map;async function kt(e){let t=Ot.get(e.deviceKey);if(t!==void 0)return t;let n;try{let t=await e.adb([`features`],{allowFailure:!0,timeoutMs:2e3,...e.signal?{signal:e.signal}:{}});if(t.exitCode!==0)return!1;n=t.stdout}catch{return!1}let r=jt(n).includes(`shell_v2`);return Ot.set(e.deviceKey,r),r}function At(){Ot.clear()}function jt(e){return e.split(`
2
- `).map(e=>e.trim()).filter(Boolean)}const Mt=new Set([`com.android.permissioncontroller`,`com.google.android.permissioncontroller`,`com.google.android.packageinstaller`,`com.android.packageinstaller`]);function Nt(e){return Mt.has(e)}const Pt=new Set([`android`,`com.android.systemui`]),Ft=/^android:id\/(?:alertTitle|message|button[123]|parentPanel|buttonPanel|contentPanel)$/i,T=/^android:id\/button[123]$/i,It=/(?:^|:)id\/permission_/i,Lt=/\b(?:is(?:n't| not) responding|keeps stopping|has stopped|close app|app info)\b/i,Rt=/^(?:ok|allow|allow all|while using the app|only this time|yes|continue|save|confirm|turn on|open settings)$/i,zt=/^(?:cancel|deny|don.t allow|don’t allow|not now|no|dismiss|close|close app|later|skip)$/i;function Bt(e){if(e!==null){if(T.test(e))return`button`;if(Ft.test(e))return`content`}}function Vt(e){let t=Wt(e.filter(Ht)),n=t.nodes;if(n.length===0)return null;let r=Yt(n),i=n.filter(e=>E(e)&&!on(e)),a=Qt(i),o=$t(i,a);if(!a&&!o&&r.length===0)return null;let s=sn(n);return{alert:{...a?{title:a}:{},...o?{message:o}:{},buttons:r.map(e=>e.label),platform:`android`,source:t.source,...s?{packageName:s}:{}},buttons:r}}function Ht(e){return!d(e)}function Ut(e,t){let n=t===`accept`?`accept`:`dismiss`;return e.find(e=>e.role===n)||(t===`dismiss`?e.find(e=>e.role===`neutral`)??null:e.length===1?e[0]??null:null)}function Wt(e){let t=e.filter(e=>rn(e));if(t.length)return{nodes:t,source:`permission`};let n=Jt(e);return n.length?{nodes:n,source:`system-dialog`}:{nodes:Gt(e),source:`native-dialog`}}function Gt(e){let t=e.filter(e=>Kt(e.type??``)),n=e.filter(e=>Ft.test(e.identifier??``)),r=t.length?[...t,...n]:qt(n);if(r.length===0)return[];let i=en(e,r);return i===void 0?r:nn(e,i)}function Kt(e){let t=Math.max(e.lastIndexOf(`.`),e.lastIndexOf(`$`));return e.slice(t+1).toLowerCase().endsWith(`dialog`)}function qt(e){let t=e.some(e=>T.test(e.identifier??``)),n=e.some(e=>!T.test(e.identifier??``));return t&&n?e:[]}function Jt(e){let t=e.filter(e=>an(e));if(t.length===0)return[];let n=en(e,t);return n===void 0?t:nn(e,n).filter(e=>e.bundleId&&Pt.has(e.bundleId))}function Yt(e){let t=new Set,n=[];for(let r of e){let e=E(r);if(!e||!r.rect||!on(r))continue;let i=e.trim().toLowerCase();if(!i||t.has(i))continue;t.add(i);let o=a(r.rect);n.push({label:e,x:o.x,y:o.y,role:Xt(r,e)})}return n}function Xt(e,t){return Zt(e.identifier??``)||(Rt.test(t.trim())?`accept`:zt.test(t.trim())?`dismiss`:`neutral`)}function Zt(e){return/(?:^|:)id\/button1$/i.test(e)?`accept`:/(?:^|:)id\/button2$/i.test(e)?`dismiss`:/(?:^|:)id\/button3$/i.test(e)?`neutral`:/(?:^|:)id\/permission_allow/i.test(e)?`accept`:/(?:^|:)id\/permission_deny/i.test(e)?`dismiss`:null}function Qt(e){return E(e.find(e=>/(?:^|:)id\/(?:alertTitle|permission_message)$/i.test(e.identifier??``)))||E(e[0])}function $t(e,t){let n=e.map(e=>E(e)).filter(e=>e&&e!==t);return n.length?[...new Set(n)].join(`
3
- `):void 0}function en(e,t){let n=t[0];if(!n)return;let r=tn(e,n.index);for(let n of t.slice(1)){let t=new Set(tn(e,n.index));for(let e=r.length-1;e>=0;--e)t.has(r[e])||r.splice(e,1)}return r.at(-1)}function tn(e,t){let n=new Map(e.map(e=>[e.index,e])),r=[],i=n.get(t);for(;i;)r.push(i.index),i=i.parentIndex===void 0?void 0:n.get(i.parentIndex);return r.reverse()}function nn(e,t){let n=new Map;for(let t of e){if(t.parentIndex===void 0)continue;let e=n.get(t.parentIndex)??[];e.push(t),n.set(t.parentIndex,e)}let r=new Set([t]),i=[t];for(let e of i)for(let t of n.get(e)??[])r.has(t.index)||(r.add(t.index),i.push(t.index));return e.filter(e=>r.has(e.index))}function rn(e){let t=e.bundleId??``;return Mt.has(t)||It.test(e.identifier??``)}function an(e){let t=e.bundleId??``;return Pt.has(t)&&Lt.test(E(e))}function on(e){let t=e.type??``,n=e.identifier??``;return!!(e.hittable||/\bbutton\b/i.test(t)||T.test(n)||/(?:^|:)id\/permission_(?:allow|deny)/i.test(n))}function E(e){return e?[e.label,e.value].filter(e=>typeof e==`string`&&e.trim().length>0)[0]?.trim()??``:``}function sn(e){return e.find(e=>e.bundleId)?.bundleId}function cn(e,n,r){if(typeof e!=`number`||!Number.isInteger(e))throw new t(`INVALID_ARGS`,`Android ${r} manifest ${n} must be an integer.`);return e}function D(e,n,r,i){if(e!==r)throw new t(`INVALID_ARGS`,`Android ${i} manifest ${n} must be "${r}".`);return r}function ln(e,n,r){if(typeof e!=`string`||e.length===0)throw new t(`INVALID_ARGS`,`Android ${r} manifest ${n} is required.`);return e}function un(e,n){let r=ln(e,`sha256`,n).trim().toLowerCase();if(r.length!==64||!/^[0-9a-f]+$/.test(r))throw new t(`INVALID_ARGS`,`Android ${n} manifest sha256 must be a 64-character hex string.`);return r}function dn(e){let t={status:[],results:[],currentStatus:null,currentResult:null};for(let n of e.split(/\r?\n/))fn(n,t);return pn(t),{status:t.status,results:t.results}}function fn(e,t){if(e.startsWith(`INSTRUMENTATION_STATUS: `)){t.currentStatus??={},gn(e.slice(24),t.currentStatus);return}if(e.startsWith(`INSTRUMENTATION_STATUS_CODE: `)){mn(t);return}if(e.startsWith(`INSTRUMENTATION_RESULT: `)){t.currentResult??={},gn(e.slice(24),t.currentResult);return}e.startsWith(`INSTRUMENTATION_CODE: `)&&hn(t)}function pn(e){mn(e),hn(e)}function mn(e){e.currentStatus&&=(e.status.push(e.currentStatus),null)}function hn(e){e.currentResult&&=(e.results.push(e.currentResult),null)}function gn(e,t){let n=e.indexOf(`=`);n<0||(t[e.slice(0,n)]=e.slice(n+1))}function O(e){if(e===void 0)return;let t=Number(e);return Number.isFinite(t)?t:void 0}function _n(e){if(e===`true`)return!0;if(e===`false`)return!1}function vn(e){if(!Number.isFinite(e.x)||!Number.isFinite(e.y)||!Number.isFinite(e.width)||!Number.isFinite(e.height)||e.width<=0||e.height<=0)throw new t(`COMMAND_FAILED`,`Android helper returned an invalid gesture viewport`);return e}const yn=1e4;async function bn(e){let{adb:t,adbProvider:n,packageName:r,versionCode:i,apkPath:a,sha256:o,cache:s,deviceKey:c,installTimeoutMs:l,helperLabel:u}=e,d=`${c}\0${r}\0${i}\0${o}`;if(s.has(d))return{packageName:r,versionCode:i,installedSha256:o,installed:!1,reason:`current`};await Dn(a,o,u);let f=await xn({adb:t,adbProvider:n,packageName:r,versionCode:i,sha256:o});if(f.reason===`current`)return s.add(d),{packageName:r,versionCode:i,...f,installed:!1};let p=await Ve(a,{provider:n,replace:!0,allowFailure:!0,timeoutMs:l});if(p.exitCode!==0)throw b(`Failed to install ${u}`,p,{packageName:r,versionCode:i,reason:f.reason});return s.add(d),{packageName:r,versionCode:i,...f,installed:!0}}async function xn(e){let{adb:t,adbProvider:n,packageName:r,versionCode:i,sha256:a,signal:o}=e,s=await wn(t,r,o);if(s===void 0)return{reason:`missing`};if(s<i)return{installedVersionCode:s,reason:`outdated`};if(s>i)return{installedVersionCode:s,reason:`current`};try{let e=await Tn(t,n,r,o);return{installedVersionCode:s,installedSha256:e,reason:e===a?`current`:`mismatched`}}catch{return o?.throwIfAborted(),{installedVersionCode:s,reason:`unverifiable`}}}async function Sn(e){let r=y().files,i=De(),a=w.join(Ee(),`android`,e.helperDirName,`dist`),o=w.join(a,e.manifestFileName(i));try{let t=e.parseManifest(JSON.parse(await r.readText(o))),n=w.join(a,t.assetName);return await r.access(n),{apkPath:n,manifest:t}}catch(r){throw new t(`UNSUPPORTED_OPERATION`,e.unavailableMessage,{manifestPath:o,error:n(r).message},r)}}function Cn(e){return async t=>await bn({adb:t.adb,adbProvider:t.adbProvider,packageName:t.artifact.manifest.packageName,versionCode:t.artifact.manifest.versionCode,apkPath:t.artifact.apkPath,sha256:t.artifact.manifest.sha256,cache:e.cache,deviceKey:t.deviceKey,installTimeoutMs:e.installTimeoutMs,helperLabel:e.helperLabel})}async function wn(e,t,n){let r=await e([`shell`,`cmd`,`package`,`list`,`packages`,`--show-versioncode`,t],{allowFailure:!0,timeoutMs:5e3,signal:n});if(r.exitCode!==0)return;let i=RegExp(`package:${kn(t)}(?:\\s|$).*versionCode:(\\d+)`).exec(`${r.stdout}\n${r.stderr}`);return i?Number(i[1]):void 0}async function Tn(e,n,r,i){let a=await e([`shell`,`pm`,`path`,r],{allowFailure:!0,timeoutMs:yn,signal:i}),o=En(`${a.stdout}\n${a.stderr}`);if(a.exitCode!==0||!o)throw new t(`COMMAND_FAILED`,`Could not resolve installed Android helper APK`);let s=y().files,c=await s.makeTempDirectory(`agent-device-helper-`),l=w.join(c,`base.apk`);try{let e=await Re(o,l,{provider:n,allowFailure:!0,timeoutMs:yn,signal:i});if(e.exitCode!==0)throw b(`Could not read installed Android helper APK`,e,{packageName:r,remotePath:o});return await On(l)}finally{await s.remove(c,{recursive:!0,force:!0})}}function En(e){return e.split(/\r?\n/).map(e=>e.startsWith(`package:`)?e.slice(8).trim():``).find(e=>e.endsWith(`/base.apk`))}async function Dn(e,n,r){let i=await On(e);if(i!==n)throw new t(`COMMAND_FAILED`,`${r} APK checksum mismatch`,{apkPath:e,expectedSha256:n,actualSha256:i})}async function On(e){let t=y().files;return t.sha256(await t.readBytes(e))}function kn(e){return e.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`)}const An=`android-snapshot-helper-v1`,k=`uiautomator-xml`,jn=5e3,Mn=3e4,Nn={"-r":`replace`,"-t":`allowTestPackages`,"-d":`allowDowngrade`,"-g":`grantPermissions`};function A(e){if(!e||typeof e!=`object`||Array.isArray(e))throw new t(`INVALID_ARGS`,`Android snapshot helper manifest must be an object.`);let n=e;return{name:Fn(n.name,`name`,`android-snapshot-helper`),version:j(n.version,`version`),releaseTag:Bn(n.releaseTag),assetName:Bn(n.assetName),apkUrl:Vn(n.apkUrl,`apkUrl`),sha256:zn(n.sha256),checksumName:Bn(n.checksumName),packageName:j(n.packageName,`packageName`),versionCode:Pn(n.versionCode,`versionCode`),instrumentationRunner:j(n.instrumentationRunner,`instrumentationRunner`),minSdk:Pn(n.minSdk,`minSdk`),targetSdk:n.targetSdk===void 0?void 0:Pn(n.targetSdk,`targetSdk`),outputFormat:Fn(n.outputFormat,`outputFormat`,k),statusProtocol:Fn(n.statusProtocol,`statusProtocol`,An),installArgs:Ln(n.installArgs)}}function Pn(e,t){return cn(e,t,`snapshot helper`)}function Fn(e,t,n){return D(e,t,n,`snapshot helper`)}function In(e){return Rn(Ln(e.installArgs))}function Ln(e){let n=Hn(e,`installArgs`);if(n[0]!==`install`)throw new t(`INVALID_ARGS`,`Android snapshot helper manifest installArgs must start with "install".`);if(n.some(e=>e.includes(`\0`)))throw new t(`INVALID_ARGS`,`Android snapshot helper manifest installArgs must not contain null bytes.`);let r=n.slice(1).find(e=>!Un(e));if(r)throw new t(`INVALID_ARGS`,`Android snapshot helper manifest installArgs contains unsupported install flag "${r}".`);return n}function Rn(e){let n={};for(let r of e.slice(1)){let e=Wn(r);if(!e)throw new t(`INVALID_ARGS`,`Android snapshot helper manifest installArgs contains unsupported install flag "${r}".`);n[e]=!0}return n}function zn(e){let n=j(e,`sha256`).trim().toLowerCase();if(n.length!==64||!Gn(n))throw new t(`INVALID_ARGS`,`Android snapshot helper manifest sha256 must be a 64-character hex string.`);return n}function j(e,n){if(typeof e!=`string`||e.trim().length===0)throw new t(`INVALID_ARGS`,`Android snapshot helper manifest ${n} is required.`);return e}function Bn(e){return typeof e==`string`&&e.trim().length>0?e:void 0}function Vn(e,t){return e===null?null:j(e,t)}function Hn(e,n){if(!Array.isArray(e)||!e.every(e=>typeof e==`string`))throw new t(`INVALID_ARGS`,`Android snapshot helper manifest ${n} must be a string array.`);return e}function Un(e){return Wn(e)!==void 0}function Wn(e){if(Object.hasOwn(Nn,e))return Nn[e]}function Gn(e){for(let t of e){let e=t.charCodeAt(0);if(!(e>=48&&e<=57)&&!(e>=97&&e<=102))return!1}return!0}const M=new Map;function Kn(e){let t=`${e.deviceKey}\0${e.packageName}\0${e.versionCode}\0`;for(let e of M.keys())e.startsWith(t)&&Xn(e)}function qn(){M.clear()}function Jn(e,t,n,r){return e?`${e}\0${t}\0${n}\0${r}`:void 0}function Yn(e,t){if(!e)return;let[n,r]=e.split(`\0`),i=`${n}\0${r}\0`;for(let t of M.keys())t!==e&&t.startsWith(i)&&M.delete(t);M.set(e,t)}function Xn(e){e&&M.delete(e)}async function Zn(e){let{adb:t,artifact:n}=e,r=e.installPolicy??`missing-or-outdated`,i=n.manifest.packageName,a=n.manifest.versionCode,o=n.manifest.sha256;if(r===`never`)return{packageName:i,versionCode:a,installed:!1,reason:`skipped`};let s=Jn(e.deviceKey,i,a,o),c=s?M.get(s):void 0;if(s&&r!==`always`&&c!==void 0)return{packageName:i,versionCode:a,installedVersionCode:c,installedSha256:o,installed:!1,reason:`current`};await Dn(n.apkPath,o,`Android snapshot helper`);let l=r===`always`?{installedVersionCode:await er(t,i,e.timeoutMs,e.signal),reason:`forced`}:await xn({adb:t,adbProvider:$n(e.adbProvider,t),packageName:i,versionCode:a,sha256:o,signal:e.signal}),{installedVersionCode:u}=l,d=`installedSha256`in l?l.installedSha256:void 0,f=l.reason;if(f===`current`){if(u===void 0)throw Error(`Expected installed versionCode for current Android snapshot helper`);return Yn(s,u),{packageName:i,versionCode:a,installedVersionCode:u,installedSha256:d,installed:!1,reason:f}}let p;try{p=await tr(t,e.adbProvider??t,n.apkPath,In(n.manifest),{packageName:i,timeoutMs:e.timeoutMs,signal:e.signal})}catch(e){throw Xn(s),Qn(e,{packageName:i,versionCode:a})}if(p.exitCode!==0)throw Xn(s),Qn(b(`Failed to install Android snapshot helper`,p,{packageName:i,versionCode:a}));return Yn(s,a),{packageName:i,versionCode:a,installedVersionCode:u,installedSha256:d,installed:!0,reason:f}}function Qn(e,t){let n=o(e,`COMMAND_FAILED`);return n.details={...t,...n.details,androidSnapshotHelperInstallFailure:!0},n}function $n(e,t){return e?typeof e==`function`?{exec:e}:e:{exec:t}}async function er(e,t,n,r){let i=await e([`shell`,`cmd`,`package`,`list`,`packages`,`--show-versioncode`,t],{allowFailure:!0,timeoutMs:n,signal:r});if(i.exitCode===0)return nr(`${i.stdout}\n${i.stderr}`,t)}async function tr(e,t,n,r,i){let a=async()=>await Ve(n,{allowFailure:!0,provider:t,...r,timeoutMs:i.timeoutMs,signal:i.signal}),o=await a();if(o.exitCode===0||!rr(o))return o;let s=await e([`uninstall`,i.packageName],{allowFailure:!0,timeoutMs:i.timeoutMs,signal:i.signal}),c=await a();return c.exitCode===0?c:{...c,stderr:[c.stderr,s.stderr?`Previous uninstall stderr after INSTALL_FAILED_UPDATE_INCOMPATIBLE: ${s.stderr}`:``].filter(Boolean).join(`
4
- `)}}function nr(e,t){let n=`package:${t}`;for(let t of e.split(/\r?\n/)){if(!t.startsWith(n)||t.length>n.length&&!/\s/.test(t[n.length]??``))continue;let e=/(?:^|\s)versionCode:(\d+)(?:\s|$)/.exec(t);if(e)return Number(e[1])}}function rr(e){return`${e.stdout}\n${e.stderr}`.includes(`INSTALL_FAILED_UPDATE_INCOMPATIBLE`)}function ir(e){return e.errorType===`java.util.concurrent.TimeoutException`?`accessibility-timeout`:void 0}function ar(e){return e===137?`accessibility-timeout`:void 0}function or(e){return e?{androidCaptureFailureReason:e}:{}}function sr(){return new Promise((e,t)=>{let n=Et.createServer();n.unref(),n.on(`error`,t),n.listen(0,`127.0.0.1`,()=>{let r=n.address();if(!r||typeof r==`string`){n.close(()=>t(Error(`Failed to allocate a local TCP port`)));return}let i=r.port;n.close(()=>e(i))})})}function cr(e,n,r,i){return new Promise((a,o)=>{let s=Et.connect({host:`127.0.0.1`,port:e}),c=[],l=setTimeout(()=>{u(),s.destroy(),o(new t(`COMMAND_FAILED`,`Android snapshot helper session request timed out`,{command:n,timeoutMs:r,port:e}))},r),u=()=>{clearTimeout(l),i?.removeEventListener(`abort`,d)},d=()=>{u(),s.destroy(),o(i?.reason??new DOMException(`The operation was aborted`,`AbortError`))};if(i?.addEventListener(`abort`,d,{once:!0}),i?.aborted){d();return}s.on(`connect`,()=>s.write(`${n}\n`)),s.on(`data`,e=>c.push(Buffer.from(e))),s.on(`error`,e=>{u(),o(e)}),s.on(`close`,()=>{u(),a(Buffer.concat(c).toString(`utf8`))})})}async function lr(e){let t=`snapshot-${Date.now()}-${Math.random().toString(16).slice(2)}`;return hr(await cr(e.port,`snapshot ${t}`,ur(e),e.signal),t)}function ur(e){return Math.min(e.commandTimeoutMs,Math.max(e.timeoutMs+3e3,3e3))}function dr(e,n,r){return new Promise((i,a)=>{let o=``,s=setTimeout(()=>{r?.removeEventListener(`abort`,l),a(new t(`COMMAND_FAILED`,`Android snapshot helper session did not become ready`,{output:o,timeoutMs:n}))},n),c=e=>{o+=e.toString(),o.includes(`agentDeviceProtocol=android-snapshot-helper-v1`)&&o.includes(`sessionReady=true`)&&(clearTimeout(s),r?.removeEventListener(`abort`,l),i())},l=()=>{clearTimeout(s),a(r?.reason??new DOMException(`The operation was aborted`,`AbortError`))};if(r?.addEventListener(`abort`,l,{once:!0}),r?.aborted){l();return}e.stdout?.on(`data`,c),e.stderr?.on(`data`,c),e.once(`exit`,(e,n)=>{clearTimeout(s),r?.removeEventListener(`abort`,l),a(new t(`COMMAND_FAILED`,`Android snapshot helper session exited before ready`,{output:o,exitCode:e,signal:n}))}),e.on(`error`,e=>{clearTimeout(s),r?.removeEventListener(`abort`,l),a(e)})})}function fr(e){let t=e.indexOf(`
1
+ import{r as e}from"./rolldown-runtime.js";import{C as t,N as n,d as r,p as i,w as a,z as o}from"./sdk-contracts.js";import"./capture.js";import{E as s}from"./sdk-batch-runner.js";import{a as c,d as l,i as u,l as d,o as f,r as p,t as ee,u as te}from"./android-input-ownership.js";import{Lr as ne,Rr as re,Vr as ie,zr as ae}from"./sdk-batch.js";import{i as oe,n as se,r as ce}from"./snapshot-scope.js";import{_ as le,d as ue,p as de}from"./scroll-gesture.js";import{r as fe}from"./success-text.js";import{n as pe}from"./alert-contract.js";import{f as me,n as he,p as ge}from"./location-coordinates.js";import{r as _e}from"./mobile-snapshot-semantics.js";import"./device.js";import{n as ve}from"./device-rotation.js";import{c as m,r as h}from"./diagnostics.js";import{a as ye,c as be,h as xe,n as Se,s as Ce}from"./exec.js";import{t as g}from"./timeouts.js";import{i as we}from"./tv-remote.js";import"./diagnostics2.js";import{n as _,r as Te}from"./command.js";import"./retry.js";import{n as Ee,r as De}from"./version.js";import{n as Oe,r as ke}from"./install-source2.js";import{a as Ae,i as je,n as v,r as y}from"./adb-host.js";import{i as Me,n as b,o as Ne,s as Pe}from"./adb-failure.js";import{a as x,c as Fe,d as Ie,i as Le,l as Re,n as ze,o as S,r as Be,s as Ve,t as He,u as Ue}from"./adb-executor.js";import{n as We,r as C}from"./adb.js";import{i as Ge,n as Ke,r as qe}from"./gesture-plan.js";import{n as Je,r as Ye,s as Xe}from"./android-system-chrome.js";import{a as Ze,c as Qe,i as $e,l as et,n as tt,o as nt,r as rt,s as it,u as at}from"./app-lifecycle.js";import{a as ot,i as st,n as ct,o as lt,r as ut,t as dt}from"./app-deployment-resolution.js";import{a as ft,i as pt,n as mt,o as ht,t as gt}from"./app-parsers.js";import{i as _t,n as vt,r as yt,t as bt}from"./window-state.js";import{n as xt}from"./toolchain-probe.js";import{t as St}from"./keyed-lock.js";import{t as Ct}from"./bounds.js";import{t as wt}from"./entities.js";import{n as Tt}from"./startup-recovery-fence.js";import{n as Et}from"./numeric.js";import w from"node:path";import Dt from"node:net";import{TextDecoder as Ot}from"node:util";const kt=new Map;async function At(e){let t=kt.get(e.deviceKey);if(t!==void 0)return t;let n;try{let t=await e.adb([`features`],{allowFailure:!0,timeoutMs:2e3,...e.signal?{signal:e.signal}:{}});if(t.exitCode!==0)return!1;n=t.stdout}catch{return!1}let r=Mt(n).includes(`shell_v2`);return kt.set(e.deviceKey,r),r}function jt(){kt.clear()}function Mt(e){return e.split(`
2
+ `).map(e=>e.trim()).filter(Boolean)}const Nt=new Set([`com.android.permissioncontroller`,`com.google.android.permissioncontroller`,`com.google.android.packageinstaller`,`com.android.packageinstaller`]);function Pt(e){return Nt.has(e)}const Ft=new Set([`android`,`com.android.systemui`]),It=/^android:id\/(?:alertTitle|message|button[123]|parentPanel|buttonPanel|contentPanel)$/i,Lt=/^android:id\/button[123]$/i,Rt=/(?:^|:)id\/permission_/i,zt=/\b(?:is(?:n't| not) responding|keeps stopping|has stopped|close app|app info)\b/i,Bt=/^(?:ok|allow|allow all|while using the app|only this time|yes|continue|save|confirm|turn on|open settings)$/i,Vt=/^(?:cancel|deny|don.t allow|don’t allow|not now|no|dismiss|close|close app|later|skip)$/i;function Ht(e){if(e!==null){if(Lt.test(e))return`button`;if(It.test(e))return`content`}}function Ut(e){let t=Kt(e.filter(Wt)),n=t.nodes;if(n.length===0)return null;let r=Zt(n),i=n.filter(e=>T(e)&&!cn(e)),a=en(i),o=tn(i,a);if(!a&&!o&&r.length===0)return null;let s=ln(n);return{alert:{...a?{title:a}:{},...o?{message:o}:{},buttons:r.map(e=>e.label),platform:`android`,source:t.source,...s?{packageName:s}:{}},buttons:r}}function Wt(e){return!d(e)}function Gt(e,t){let n=t===`accept`?`accept`:`dismiss`;return e.find(e=>e.role===n)||(t===`dismiss`?e.find(e=>e.role===`neutral`)??null:e.length===1?e[0]??null:null)}function Kt(e){let t=e.filter(e=>on(e));if(t.length)return{nodes:t,source:`permission`};let n=Xt(e);return n.length?{nodes:n,source:`system-dialog`}:{nodes:qt(e),source:`native-dialog`}}function qt(e){let t=e.filter(e=>Jt(e.type??``)),n=e.filter(e=>It.test(e.identifier??``)),r=t.length?[...t,...n]:Yt(n);if(r.length===0)return[];let i=nn(e,r);return i===void 0?r:an(e,i)}function Jt(e){let t=Math.max(e.lastIndexOf(`.`),e.lastIndexOf(`$`));return e.slice(t+1).toLowerCase().endsWith(`dialog`)}function Yt(e){let t=e.some(e=>Lt.test(e.identifier??``)),n=e.some(e=>!Lt.test(e.identifier??``));return t&&n?e:[]}function Xt(e){let t=e.filter(e=>sn(e));if(t.length===0)return[];let n=nn(e,t);return n===void 0?t:an(e,n).filter(e=>e.bundleId&&Ft.has(e.bundleId))}function Zt(e){let t=new Set,n=[];for(let r of e){let e=T(r);if(!e||!r.rect||!cn(r))continue;let a=e.trim().toLowerCase();if(!a||t.has(a))continue;t.add(a);let o=i(r.rect);n.push({label:e,x:o.x,y:o.y,role:Qt(r,e)})}return n}function Qt(e,t){return $t(e.identifier??``)||(Bt.test(t.trim())?`accept`:Vt.test(t.trim())?`dismiss`:`neutral`)}function $t(e){return/(?:^|:)id\/button1$/i.test(e)?`accept`:/(?:^|:)id\/button2$/i.test(e)?`dismiss`:/(?:^|:)id\/button3$/i.test(e)?`neutral`:/(?:^|:)id\/permission_allow/i.test(e)?`accept`:/(?:^|:)id\/permission_deny/i.test(e)?`dismiss`:null}function en(e){return T(e.find(e=>/(?:^|:)id\/(?:alertTitle|permission_message)$/i.test(e.identifier??``)))||T(e[0])}function tn(e,t){let n=e.map(e=>T(e)).filter(e=>e&&e!==t);return n.length?[...new Set(n)].join(`
3
+ `):void 0}function nn(e,t){let n=t[0];if(!n)return;let r=rn(e,n.index);for(let n of t.slice(1)){let t=new Set(rn(e,n.index));for(let e=r.length-1;e>=0;--e)t.has(r[e])||r.splice(e,1)}return r.at(-1)}function rn(e,t){let n=new Map(e.map(e=>[e.index,e])),r=[],i=n.get(t);for(;i;)r.push(i.index),i=i.parentIndex===void 0?void 0:n.get(i.parentIndex);return r.reverse()}function an(e,t){let n=new Map;for(let t of e){if(t.parentIndex===void 0)continue;let e=n.get(t.parentIndex)??[];e.push(t),n.set(t.parentIndex,e)}let r=new Set([t]),i=[t];for(let e of i)for(let t of n.get(e)??[])r.has(t.index)||(r.add(t.index),i.push(t.index));return e.filter(e=>r.has(e.index))}function on(e){let t=e.bundleId??``;return Nt.has(t)||Rt.test(e.identifier??``)}function sn(e){let t=e.bundleId??``;return Ft.has(t)&&zt.test(T(e))}function cn(e){let t=e.type??``,n=e.identifier??``;return!!(e.hittable||/\bbutton\b/i.test(t)||Lt.test(n)||/(?:^|:)id\/permission_(?:allow|deny)/i.test(n))}function T(e){return e?[e.label,e.value].filter(e=>typeof e==`string`&&e.trim().length>0)[0]?.trim()??``:``}function ln(e){return e.find(e=>e.bundleId)?.bundleId}function un(e,n,r){if(typeof e!=`number`||!Number.isInteger(e))throw new t(`INVALID_ARGS`,`Android ${r} manifest ${n} must be an integer.`);return e}function E(e,n,r,i){if(e!==r)throw new t(`INVALID_ARGS`,`Android ${i} manifest ${n} must be "${r}".`);return r}function dn(e,n,r){if(typeof e!=`string`||e.length===0)throw new t(`INVALID_ARGS`,`Android ${r} manifest ${n} is required.`);return e}function fn(e,n){let r=dn(e,`sha256`,n).trim().toLowerCase();if(r.length!==64||!/^[0-9a-f]+$/.test(r))throw new t(`INVALID_ARGS`,`Android ${n} manifest sha256 must be a 64-character hex string.`);return r}function pn(e){let t={status:[],results:[],currentStatus:null,currentResult:null};for(let n of e.split(/\r?\n/))mn(n,t);return hn(t),{status:t.status,results:t.results}}function mn(e,t){if(e.startsWith(`INSTRUMENTATION_STATUS: `)){t.currentStatus??={},vn(e.slice(24),t.currentStatus);return}if(e.startsWith(`INSTRUMENTATION_STATUS_CODE: `)){gn(t);return}if(e.startsWith(`INSTRUMENTATION_RESULT: `)){t.currentResult??={},vn(e.slice(24),t.currentResult);return}e.startsWith(`INSTRUMENTATION_CODE: `)&&_n(t)}function hn(e){gn(e),_n(e)}function gn(e){e.currentStatus&&=(e.status.push(e.currentStatus),null)}function _n(e){e.currentResult&&=(e.results.push(e.currentResult),null)}function vn(e,t){let n=e.indexOf(`=`);n<0||(t[e.slice(0,n)]=e.slice(n+1))}function D(e){if(e===void 0)return;let t=Number(e);return Number.isFinite(t)?t:void 0}function yn(e){if(e===`true`)return!0;if(e===`false`)return!1}function O(e){if(!Number.isFinite(e.x)||!Number.isFinite(e.y)||!Number.isFinite(e.width)||!Number.isFinite(e.height)||e.width<=0||e.height<=0)throw new t(`COMMAND_FAILED`,`Android helper returned an invalid gesture viewport`);return e}const bn=1e4;async function xn(e,t){try{return await He(e,t)}catch(e){throw Ne(e)}}async function Sn(e){let{adb:t,adbProvider:n,packageName:r,versionCode:i,apkPath:a,sha256:o,cache:s,deviceKey:c,installTimeoutMs:l,helperLabel:u}=e,d=`${c}\0${r}\0${i}\0${o}`;if(s.has(d))return{packageName:r,versionCode:i,installedSha256:o,installed:!1,reason:`current`};await kn(a,o,u);let f=await Cn({adb:t,adbProvider:n,packageName:r,versionCode:i,sha256:o});if(f.reason===`current`)return s.add(d),{packageName:r,versionCode:i,...f,installed:!1};let p=await xn(a,{provider:n,replace:!0,allowFailure:!0,timeoutMs:l});if(p.exitCode!==0)throw b(`Failed to install ${u}`,p,{packageName:r,versionCode:i,reason:f.reason});return s.add(d),{packageName:r,versionCode:i,...f,installed:!0}}async function Cn(e){let{adb:t,adbProvider:n,packageName:r,versionCode:i,sha256:a,signal:o}=e,s=await En(t,r,o);if(s===void 0)return{reason:`missing`};if(s<i)return{installedVersionCode:s,reason:`outdated`};if(s>i)return{installedVersionCode:s,reason:`current`};try{let e=await Dn(t,n,r,o);return{installedVersionCode:s,installedSha256:e,reason:e===a?`current`:`mismatched`}}catch{return o?.throwIfAborted(),{installedVersionCode:s,reason:`unverifiable`}}}async function wn(e){let r=y().files,i=De(),a=w.join(Ee(),`android`,e.helperDirName,`dist`),o=w.join(a,e.manifestFileName(i));try{let t=e.parseManifest(JSON.parse(await r.readText(o))),n=w.join(a,t.assetName);return await r.access(n),{apkPath:n,manifest:t}}catch(r){throw new t(`UNSUPPORTED_OPERATION`,e.unavailableMessage,{manifestPath:o,error:n(r).message},r)}}function Tn(e){return async t=>await Sn({adb:t.adb,adbProvider:t.adbProvider,packageName:t.artifact.manifest.packageName,versionCode:t.artifact.manifest.versionCode,apkPath:t.artifact.apkPath,sha256:t.artifact.manifest.sha256,cache:e.cache,deviceKey:t.deviceKey,installTimeoutMs:e.installTimeoutMs,helperLabel:e.helperLabel})}async function En(e,t,n){let r=await e([`shell`,`cmd`,`package`,`list`,`packages`,`--show-versioncode`,t],{allowFailure:!0,timeoutMs:5e3,signal:n});if(r.exitCode!==0)return;let i=RegExp(`package:${jn(t)}(?:\\s|$).*versionCode:(\\d+)`).exec(`${r.stdout}\n${r.stderr}`);return i?Number(i[1]):void 0}async function Dn(e,n,r,i){let a=await e([`shell`,`pm`,`path`,r],{allowFailure:!0,timeoutMs:bn,signal:i}),o=On(`${a.stdout}\n${a.stderr}`);if(a.exitCode!==0||!o)throw new t(`COMMAND_FAILED`,`Could not resolve installed Android helper APK`);let s=y().files,c=await s.makeTempDirectory(`agent-device-helper-`),l=w.join(c,`base.apk`);try{let e=await ze(o,l,{provider:n,allowFailure:!0,timeoutMs:bn,signal:i});if(e.exitCode!==0)throw b(`Could not read installed Android helper APK`,e,{packageName:r,remotePath:o});return await An(l)}finally{await s.remove(c,{recursive:!0,force:!0})}}function On(e){return e.split(/\r?\n/).map(e=>e.startsWith(`package:`)?e.slice(8).trim():``).find(e=>e.endsWith(`/base.apk`))}async function kn(e,n,r){let i=await An(e);if(i!==n)throw new t(`COMMAND_FAILED`,`${r} APK checksum mismatch`,{apkPath:e,expectedSha256:n,actualSha256:i})}async function An(e){let t=y().files;return t.sha256(await t.readBytes(e))}function jn(e){return e.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`)}const Mn=`android-snapshot-helper-v1`,Nn=`uiautomator-xml`,Pn=5e3,Fn=3e4;function In(e){if(!e||typeof e!=`object`||Array.isArray(e))throw new t(`INVALID_ARGS`,`Android snapshot helper manifest must be an object.`);let n=e;return{name:Rn(n.name,`name`,`android-snapshot-helper`),version:k(n.version,`version`),releaseTag:Bn(n.releaseTag),assetName:Bn(n.assetName),apkUrl:Vn(n.apkUrl,`apkUrl`),sha256:zn(n.sha256),checksumName:Bn(n.checksumName),packageName:k(n.packageName,`packageName`),versionCode:Ln(n.versionCode,`versionCode`),instrumentationRunner:k(n.instrumentationRunner,`instrumentationRunner`),minSdk:Ln(n.minSdk,`minSdk`),targetSdk:n.targetSdk===void 0?void 0:Ln(n.targetSdk,`targetSdk`),outputFormat:Rn(n.outputFormat,`outputFormat`,Nn),statusProtocol:Rn(n.statusProtocol,`statusProtocol`,Mn)}}function Ln(e,t){return un(e,t,`snapshot helper`)}function Rn(e,t,n){return E(e,t,n,`snapshot helper`)}function zn(e){let n=k(e,`sha256`).trim().toLowerCase();if(n.length!==64||!Hn(n))throw new t(`INVALID_ARGS`,`Android snapshot helper manifest sha256 must be a 64-character hex string.`);return n}function k(e,n){if(typeof e!=`string`||e.trim().length===0)throw new t(`INVALID_ARGS`,`Android snapshot helper manifest ${n} is required.`);return e}function Bn(e){return typeof e==`string`&&e.trim().length>0?e:void 0}function Vn(e,t){return e===null?null:k(e,t)}function Hn(e){for(let t of e){let e=t.charCodeAt(0);if(!(e>=48&&e<=57)&&!(e>=97&&e<=102))return!1}return!0}const A=new Map;function Un(e){let t=`${e.deviceKey}\0${e.packageName}\0${e.versionCode}\0`;for(let e of A.keys())e.startsWith(t)&&qn(e)}function Wn(){A.clear()}function Gn(e,t,n,r){return e?`${e}\0${t}\0${n}\0${r}`:void 0}function Kn(e,t){if(!e)return;let[n,r]=e.split(`\0`),i=`${n}\0${r}\0`;for(let t of A.keys())t!==e&&t.startsWith(i)&&A.delete(t);A.set(e,t)}function qn(e){e&&A.delete(e)}async function Jn(e){let{adb:t,artifact:n}=e,r=e.installPolicy??`missing-or-outdated`,i=n.manifest.packageName,a=n.manifest.versionCode,o=n.manifest.sha256;if(r===`never`)return{packageName:i,versionCode:a,installed:!1,reason:`skipped`};let s=Gn(e.deviceKey,i,a,o),c=s?A.get(s):void 0;if(s&&r!==`always`&&c!==void 0)return{packageName:i,versionCode:a,installedVersionCode:c,installedSha256:o,installed:!1,reason:`current`};await kn(n.apkPath,o,`Android snapshot helper`);let l=r===`always`?{installedVersionCode:await Zn(t,i,e.timeoutMs,e.signal),reason:`forced`}:await Cn({adb:t,adbProvider:Xn(e.adbProvider,t),packageName:i,versionCode:a,sha256:o,signal:e.signal}),{installedVersionCode:u}=l,d=`installedSha256`in l?l.installedSha256:void 0,f=l.reason;if(f===`current`){if(u===void 0)throw Error(`Expected installed versionCode for current Android snapshot helper`);return Kn(s,u),{packageName:i,versionCode:a,installedVersionCode:u,installedSha256:d,installed:!1,reason:f}}let p;try{p=await Qn(t,e.adbProvider??t,n.apkPath,{packageName:i,timeoutMs:e.timeoutMs,signal:e.signal})}catch(e){throw qn(s),Yn(e,{packageName:i,versionCode:a})}if(p.exitCode!==0)throw qn(s),Yn(b(`Failed to install Android snapshot helper`,p,{packageName:i,versionCode:a}));return Kn(s,a),{packageName:i,versionCode:a,installedVersionCode:u,installedSha256:d,installed:!0,reason:f}}function Yn(e,t){let n=a(e,`COMMAND_FAILED`);return n.details={...t,...n.details,androidSnapshotHelperInstallFailure:!0},n}function Xn(e,t){return e?typeof e==`function`?{exec:e}:e:{exec:t}}async function Zn(e,t,n,r){let i=await e([`shell`,`cmd`,`package`,`list`,`packages`,`--show-versioncode`,t],{allowFailure:!0,timeoutMs:n,signal:r});if(i.exitCode===0)return $n(`${i.stdout}\n${i.stderr}`,t)}async function Qn(e,t,n,r){let i=async()=>await xn(n,{allowFailure:!0,provider:t,replace:!0,timeoutMs:r.timeoutMs,signal:r.signal}),a=await i();if(a.exitCode===0||!er(a))return a;let o=await e([`uninstall`,r.packageName],{allowFailure:!0,timeoutMs:r.timeoutMs,signal:r.signal}),s=await i();return s.exitCode===0?s:{...s,stderr:[s.stderr,o.stderr?`Previous uninstall stderr after INSTALL_FAILED_UPDATE_INCOMPATIBLE: ${o.stderr}`:``].filter(Boolean).join(`
4
+ `)}}function $n(e,t){let n=`package:${t}`;for(let t of e.split(/\r?\n/)){if(!t.startsWith(n)||t.length>n.length&&!/\s/.test(t[n.length]??``))continue;let e=/(?:^|\s)versionCode:(\d+)(?:\s|$)/.exec(t);if(e)return Number(e[1])}}function er(e){return`${e.stdout}\n${e.stderr}`.includes(`INSTALL_FAILED_UPDATE_INCOMPATIBLE`)}function tr(e){return e.errorType===`java.util.concurrent.TimeoutException`?`accessibility-timeout`:void 0}function nr(e){return e===137?`accessibility-timeout`:void 0}function j(e){return e?{androidCaptureFailureReason:e}:{}}function rr(){return new Promise((e,t)=>{let n=Dt.createServer();n.unref(),n.on(`error`,t),n.listen(0,`127.0.0.1`,()=>{let r=n.address();if(!r||typeof r==`string`){n.close(()=>t(Error(`Failed to allocate a local TCP port`)));return}let i=r.port;n.close(()=>e(i))})})}function ir(e,n,r,i){return new Promise((a,o)=>{let s=Dt.connect({host:`127.0.0.1`,port:e}),c=[],l=setTimeout(()=>{u(),s.destroy(),o(new t(`COMMAND_FAILED`,`Android snapshot helper session request timed out`,{command:n,timeoutMs:r,port:e}))},r),u=()=>{clearTimeout(l),i?.removeEventListener(`abort`,d)},d=()=>{u(),s.destroy(),o(i?.reason??new DOMException(`The operation was aborted`,`AbortError`))};if(i?.addEventListener(`abort`,d,{once:!0}),i?.aborted){d();return}s.on(`connect`,()=>s.write(`${n}\n`)),s.on(`data`,e=>c.push(Buffer.from(e))),s.on(`error`,e=>{u(),o(e)}),s.on(`close`,()=>{u(),a(Buffer.concat(c).toString(`utf8`))})})}async function ar(e){let t=`snapshot-${Date.now()}-${Math.random().toString(16).slice(2)}`;return dr(await ir(e.port,`snapshot ${t}`,or(e),e.signal),t)}function or(e){return Math.min(e.commandTimeoutMs,Math.max(e.timeoutMs+3e3,3e3))}function sr(e,n,r){return new Promise((i,a)=>{let o=``,s=setTimeout(()=>{r?.removeEventListener(`abort`,l),a(new t(`COMMAND_FAILED`,`Android snapshot helper session did not become ready`,{output:o,timeoutMs:n,reason:`android_snapshot_helper_session_ready_timeout`}))},n),c=e=>{o+=e.toString(),o.includes(`agentDeviceProtocol=android-snapshot-helper-v1`)&&o.includes(`sessionReady=true`)&&(clearTimeout(s),r?.removeEventListener(`abort`,l),i())},l=()=>{clearTimeout(s),a(r?.reason??new DOMException(`The operation was aborted`,`AbortError`))};if(r?.addEventListener(`abort`,l,{once:!0}),r?.aborted){l();return}e.stdout?.on(`data`,c),e.stderr?.on(`data`,c),e.once(`exit`,(e,n)=>{clearTimeout(s),r?.removeEventListener(`abort`,l),a(new t(`COMMAND_FAILED`,`Android snapshot helper session exited before ready`,{output:o,exitCode:e,signal:n,reason:`android_snapshot_helper_session_exited_before_ready`}))}),e.on(`error`,e=>{clearTimeout(s),r?.removeEventListener(`abort`,l),a(e)})})}function cr(e){let t=e.indexOf(`
5
5
 
6
- `);return vr(e.slice(0,t<0?e.length:t))}function pr(e,n){if(e.agentDeviceProtocol!==`android-snapshot-helper-v1`)throw new t(`COMMAND_FAILED`,`Android automation helper session returned wrong protocol`,{headers:e});if(e.requestId!==n)throw new t(`COMMAND_FAILED`,`Android automation helper session returned stale output`,{headers:e,requestId:n})}function mr(e,t){let n=fr(e);return n.agentDeviceProtocol===`android-snapshot-helper-v1`&&n.requestId===t&&n.ok===`true`}function hr(e,n){let r=e.indexOf(`
6
+ `);return mr(e.slice(0,t<0?e.length:t))}function lr(e,n){if(e.agentDeviceProtocol!==`android-snapshot-helper-v1`)throw new t(`COMMAND_FAILED`,`Android automation helper session returned wrong protocol`,{headers:e});if(e.requestId!==n)throw new t(`COMMAND_FAILED`,`Android automation helper session returned stale output`,{headers:e,requestId:n})}function ur(e,t){let n=cr(e);return n.agentDeviceProtocol===`android-snapshot-helper-v1`&&n.requestId===t&&n.ok===`true`}function dr(e,n){let r=e.indexOf(`
7
7
 
8
- `);if(r<0)throw new t(`COMMAND_FAILED`,`Android snapshot helper session returned malformed output`,{response:e});let i=vr(e.slice(0,r)),a=e.slice(r+2);return gr(i,n),_r(i,a),{xml:a,metadata:yr(i)}}function gr(e,n){if(e.agentDeviceProtocol!==`android-snapshot-helper-v1`)throw new t(`COMMAND_FAILED`,`Android snapshot helper session returned wrong protocol`,{headers:e});if(e.outputFormat!==`uiautomator-xml`)throw new t(`COMMAND_FAILED`,`Android snapshot helper session returned wrong output format`,{headers:e});if(e.requestId!==n)throw new t(`COMMAND_FAILED`,`Android snapshot helper session returned stale output`,{headers:e,requestId:n});if(e.ok!==`true`)throw new t(`COMMAND_FAILED`,e.message||e.errorType||`Android snapshot helper session returned an error`,{helper:e,...or(ir(e))})}function _r(e,n){let r=O(e.byteLength);if(r!==void 0&&Buffer.byteLength(n,`utf8`)!==r)throw new t(`COMMAND_FAILED`,`Android snapshot helper session returned truncated XML`,{headers:e,actualByteLength:Buffer.byteLength(n,`utf8`)});if(!n.includes(`<hierarchy`)||!n.includes(`</hierarchy>`))throw new t(`COMMAND_FAILED`,`Android snapshot helper session did not return XML`,{headers:e,xml:n})}function vr(e){let t={};for(let n of e.split(/\r?\n/)){let e=n.indexOf(`=`);e<0||(t[n.slice(0,e)]=n.slice(e+1))}return t}function yr(e){return{helperApiVersion:e.helperApiVersion,outputFormat:k,waitForIdleTimeoutMs:O(e.waitForIdleTimeoutMs),waitForIdleQuietMs:O(e.waitForIdleQuietMs),timeoutMs:O(e.timeoutMs),maxDepth:O(e.maxDepth),maxNodes:O(e.maxNodes),rootPresent:_n(e.rootPresent),captureMode:e.captureMode===`interactive-windows`||e.captureMode===`active-window`?e.captureMode:void 0,windowCount:O(e.windowCount),nodeCount:O(e.nodeCount),truncated:_n(e.truncated),elapsedMs:O(e.elapsedMs)}}const br=2e3,xr=`android_snapshot_helper_retirement_unconfirmed`,Sr=new Map;function Cr(e){return`${e.platform}:${e.id}`}async function wr(e){await Nr({adb:e.adb,packageName:e.packageName,timeoutMs:2e3})||N(e)}async function Tr(e){let t=Sr.get(e.deviceKey);if(t){try{let n=await e.adb([`shell`,`am`,`force-stop`,t.packageName],{allowFailure:!0,timeoutMs:5e3,signal:e.signal});if(e.signal?.throwIfAborted(),n.exitCode===0){Sr.delete(e.deviceKey);return}}catch{e.signal?.throwIfAborted()}N({deviceKey:e.deviceKey,packageName:t.packageName,cause:t.cause})}}function N(e){let n=e.cause instanceof Error?e.cause.message:String(e.cause);throw Sr.set(e.deviceKey,{packageName:e.packageName,cause:n}),new t(`COMMAND_FAILED`,`Android snapshot helper could not confirm release of device automation ownership`,{reason:xr,deviceKey:e.deviceKey,cause:n,hint:`Retry after the helper process exits, or restart the device if Android still reports automation as busy.`})}function Er(e){return e instanceof t&&e.details?.reason===xr}async function Dr(e){let t=AbortSignal.timeout(e.timeoutMs),[n]=await Promise.allSettled([e.forceStopRuntime?Nr({adb:e.adb,packageName:e.packageName,timeoutMs:e.timeoutMs,signal:t}):Promise.resolve(!1),Pr({...e,signal:t})]);return{timedOut:t.aborted,runtimeForceStopped:n?.status===`fulfilled`&&n.value}}function Or(e){let t=kr(e);return{ended:t?Promise.resolve():new Promise(t=>{e.once(`close`,()=>t()),e.once(`exit`,()=>t())}),hasEnded:()=>kr(e),completedCleanly:()=>!t&&e.exitCode===0&&e.signalCode==null}}function kr(e){return e.exitCode!=null||e.signalCode!=null}async function Ar(e,t,n){let r,i,a=await Promise.race([e.then(()=>!0),new Promise(e=>{r=setTimeout(()=>e(!1),t)}),...n?[new Promise(e=>{i=()=>e(!1),n.addEventListener(`abort`,i,{once:!0}),n.aborted&&i()})]:[]]);return r&&clearTimeout(r),i&&n?.removeEventListener(`abort`,i),a}async function jr(e){if(e.processExit.hasEnded())return!0;try{e.process.kill(`SIGTERM`)}catch{}return await Ar(e.processExit.ended,e.timeoutMs)}function Mr(){Sr.clear()}async function Nr(e){let t=e.signal??AbortSignal.timeout(e.timeoutMs);try{return(await e.adb([`shell`,`am`,`force-stop`,e.packageName],{allowFailure:!0,timeoutMs:e.timeoutMs,signal:t})).exitCode===0}catch{return!1}}async function Pr(e){e.process.stdin?.end(),e.process.stdout?.destroy(),e.process.stderr?.destroy(),await e.adb([`forward`,`--remove`,`tcp:${e.port}`],{allowFailure:!0,timeoutMs:e.timeoutMs,signal:e.signal})}async function Fr(e){let n=Lr(e),r=e.deviceKey??`android:default`;await Tr({deviceKey:r,adb:e.adb,signal:e.signal});let i;try{i=await e.adb(Rr(n),{allowFailure:!0,timeoutMs:n.commandTimeoutMs,signal:e.signal})}catch(t){throw e.signal?.aborted?(await wr({deviceKey:r,packageName:n.packageName,adb:e.adb,cause:t}),e.signal.throwIfAborted(),t):t}e.signal?.aborted&&(await wr({deviceKey:r,packageName:n.packageName,adb:e.adb,cause:e.signal.reason}),e.signal.throwIfAborted());let{output:a,cleanupDone:o}=await zr(e,n,i);if(n.outputPath&&!o&&await Kr(e.adb,n.outputPath),i.exitCode!==0)throw new t(`COMMAND_FAILED`,`Android snapshot helper failed`,Se(i,{helper:a.metadata}));return a}function Ir(e){return{adb:e.adb,adbProvider:e.adbProvider,deviceKey:e.deviceKey,helperVersion:e.artifact.manifest.version,helperVersionCode:e.artifact.manifest.versionCode,helperSha256:e.artifact.manifest.sha256,packageName:e.artifact.manifest.packageName,instrumentationRunner:e.artifact.manifest.instrumentationRunner,waitForIdleTimeoutMs:500,timeoutMs:jn,commandTimeoutMs:Mn,...e.signal?{signal:e.signal}:{}}}function Lr(e){let t=P(e.timeoutMs,8e3),n=P(e.packageName,`com.callstack.agentdevice.snapshothelper`);return{waitForIdleTimeoutMs:P(e.waitForIdleTimeoutMs,500),waitForIdleQuietMs:P(e.waitForIdleQuietMs,100),timeoutMs:t,commandTimeoutMs:P(e.commandTimeoutMs,t+5e3),maxDepth:P(e.maxDepth,128),maxNodes:P(e.maxNodes,5e3),packageName:n,runner:P(e.instrumentationRunner,`${n}/.SnapshotInstrumentation`),...e.outputPath?{outputPath:e.outputPath}:{},...e.emitChunks===void 0?{}:{emitChunks:e.emitChunks}}}function P(e,t){return e===void 0?t:e}function Rr(e){return[`shell`,`am`,`instrument`,`-w`,`-e`,`waitForIdleTimeoutMs`,String(e.waitForIdleTimeoutMs),`-e`,`waitForIdleQuietMs`,String(e.waitForIdleQuietMs),`-e`,`timeoutMs`,String(e.timeoutMs),`-e`,`maxDepth`,String(e.maxDepth),`-e`,`maxNodes`,String(e.maxNodes),...e.outputPath?[`-e`,`outputPath`,e.outputPath]:[],...e.emitChunks===void 0?[]:[`-e`,`emitChunks`,String(e.emitChunks)],e.runner]}async function zr(e,t,n){try{return{output:qr(`${n.stdout}\n${n.stderr}`),cleanupDone:!1}}catch(r){return await Br(e,t,n,r)}}async function Br(e,n,r,i){if(i instanceof t&&r.exitCode!==0&&i.details?.helper)throw i;let a=await Vr(e,n,r);if(a)return{output:a,cleanupDone:!0};throw new t(`COMMAND_FAILED`,r.exitCode===0?`Android snapshot helper output could not be parsed`:`Android snapshot helper failed before returning parseable output`,{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode,...or(ar(r.exitCode))},i)}async function Vr(e,t,n){if(!(n.exitCode!==0||!t.outputPath))return await Ur(e.adb,t.outputPath,Gr(`${n.stdout}\n${n.stderr}`)??Hr(t))}function Hr(e){return{outputFormat:k,waitForIdleTimeoutMs:e.waitForIdleTimeoutMs,waitForIdleQuietMs:e.waitForIdleQuietMs,timeoutMs:e.timeoutMs,maxDepth:e.maxDepth,maxNodes:e.maxNodes,transport:`instrumentation`}}async function Ur(e,t,n){let r;try{r=await e(Wr(t),{allowFailure:!0,timeoutMs:5e3})}catch{return}if(r.exitCode!==0)return;let i=r.stdout.trim();if(!(!i.includes(`<hierarchy`)||!i.includes(`</hierarchy>`)))return{xml:i,metadata:n}}function Wr(e){return[`shell`,`sh`,`-c`,`cat "$1"; status=$?; rm -f "$1"; exit "$status"`,`agent-device-snapshot-helper-output`,e]}function Gr(e){try{return ti(Yr(dn(e).results))}catch{return null}}async function Kr(e,t){try{await e([`shell`,`rm`,`-f`,t],{allowFailure:!0,timeoutMs:5e3})}catch{}}function qr(e){let t=dn(e),n=Yr(t.results);return{xml:Zr(Jr(t.status),n),metadata:{...ti(n),transport:`instrumentation`}}}function Jr(e){let t=[];for(let n of e){if(n.agentDeviceProtocol!==`android-snapshot-helper-v1`||n.outputFormat!==`uiautomator-xml`)continue;let{payloadBase64:e}=n;e!==void 0&&t.push({index:F(n.chunkIndex),count:F(n.chunkCount),payloadBase64:e})}return t}function Yr(e){let n=e.find(e=>e.agentDeviceProtocol===An);if(!n)throw new t(`COMMAND_FAILED`,`Android snapshot helper did not return a final result`);if(n.ok!==`true`)throw new t(`COMMAND_FAILED`,Xr(n),{errorType:n.errorType,helper:n,...or(ir(n))});return n}function Xr(e){return e.message&&e.message!==`null`?e.message:e.errorType||`Android snapshot helper returned an error`}function Zr(e,n){if(e.length===0)throw new t(`COMMAND_FAILED`,`Android snapshot helper did not return XML chunks`,{helper:n});let r=Qr(e),i=Buffer.concat(ei($r(e,r),r)).toString(`utf8`);if(!i.includes(`<hierarchy`)||!i.includes(`</hierarchy>`))throw new t(`COMMAND_FAILED`,`Android snapshot helper output did not contain XML`,{xml:i});return i}function Qr(e){let n=e[0]?.count??e.length;if(n<1||e.length!==n||e.some(e=>e.count!==n))throw new t(`COMMAND_FAILED`,`Android snapshot helper returned incomplete XML chunks`,{expectedChunks:n,actualChunks:e.length});return n}function $r(e,n){let r=new Map;for(let i of e){if(i.index===void 0||i.index<0||i.index>=n)throw new t(`COMMAND_FAILED`,`Android snapshot helper returned invalid chunk index`,{chunkIndex:i.index,expectedChunks:n});if(r.has(i.index))throw new t(`COMMAND_FAILED`,`Android snapshot helper returned duplicate XML chunks`,{chunkIndex:i.index});r.set(i.index,i.payloadBase64)}return r}function ei(e,n){let r=[];for(let i=0;i<n;i+=1){let a=e.get(i);if(a===void 0)throw new t(`COMMAND_FAILED`,`Android snapshot helper returned incomplete XML chunks`,{missingChunkIndex:i,expectedChunks:n});r.push(Buffer.from(a,`base64`))}return r}function ti(e){return{helperApiVersion:e.helperApiVersion,outputFormat:k,waitForIdleTimeoutMs:F(e.waitForIdleTimeoutMs),waitForIdleQuietMs:F(e.waitForIdleQuietMs),timeoutMs:F(e.timeoutMs),maxDepth:F(e.maxDepth),maxNodes:F(e.maxNodes),rootPresent:ri(e.rootPresent),captureMode:ni(e.captureMode),windowCount:F(e.windowCount),nodeCount:F(e.nodeCount),truncated:ri(e.truncated),elapsedMs:F(e.elapsedMs)}}function ni(e){return e===`interactive-windows`||e===`active-window`?e:void 0}const F=O,ri=_n,ii=5e3,I=new Map,ai=new Map;async function oi(e){return await si(e)!==void 0}async function si(e){let t=e.deviceKey??`android:default`;if(await Tr({deviceKey:t,adb:e.adb,signal:e.signal}),!pi()||!e.adbProvider?.spawn)return;let n=fi(Lr(e)),r=await li({deviceKey:t,identity:di(t,n,e),options:e,resolved:n});return r?{session:r,resolved:n,deviceKey:t}:void 0}function ci(e){return I.get(e)}async function li(e){let{deviceKey:t,identity:n,options:r,resolved:i}=e;if(ai.get(t)===n)return;let a=I.get(t);if(a&&a.identity!==n&&(await L(t),a=void 0),!a)try{a=await ui({deviceKey:t,identity:n,options:r,resolved:i})}catch(e){if(r.signal?.throwIfAborted(),ai.set(t,n),h({level:`warn`,phase:`android_snapshot_helper_session_disabled`,data:{deviceKey:t,reason:e instanceof Error?e.message:String(e)}}),Er(e))throw e;return}return a}async function ui(e){let n=await sr();await e.options.adb([`forward`,`tcp:${n}`,`tcp:${n}`],{allowFailure:!1,timeoutMs:ii,signal:e.options.signal});let r=Rr({...e.resolved,outputPath:void 0,emitChunks:!1}),i=r.at(-1);if(!i)throw new t(`INVALID_ARGS`,`Android snapshot helper runner was not resolved`);let a=[...r.slice(0,-1),`-e`,`sessionPort`,String(n),i],o=e.options.adbProvider.spawn(a,{allowFailure:!0,captureOutput:!1}),s={identity:e.identity,deviceKey:e.deviceKey,helper:{packageName:e.resolved.packageName,runner:e.resolved.runner,helperVersion:e.options.helperVersion,helperVersionCode:e.options.helperVersionCode,sha256:e.options.helperSha256},port:n,adb:e.options.adb,process:o,startedAtMs:Date.now(),capturedCount:0};try{return await dr(o,1e4,e.options.signal),I.set(e.deviceKey,s),h({phase:`android_snapshot_helper_session_ready`,data:{deviceKey:e.deviceKey,port:n,packageName:e.resolved.packageName,runner:e.resolved.runner}}),s}catch(t){let n=Or(o);try{o.kill(`SIGTERM`)}catch{}let[,r]=await Promise.all([Ar(n.ended,250),Dr({adb:s.adb,process:s.process,port:s.port,packageName:s.helper.packageName,timeoutMs:br,forceStopRuntime:!0})]);throw r.runtimeForceStopped||N({deviceKey:e.deviceKey,packageName:s.helper.packageName,cause:t}),t}}function di(e,t,n){return JSON.stringify({deviceKey:e,packageName:t.packageName,runner:t.runner,helperVersion:n.helperVersion,helperVersionCode:n.helperVersionCode,helperSha256:n.helperSha256,waitForIdleTimeoutMs:t.waitForIdleTimeoutMs,waitForIdleQuietMs:t.waitForIdleQuietMs,timeoutMs:t.timeoutMs,maxDepth:t.maxDepth,maxNodes:t.maxNodes})}function fi(e){let t=Math.min(e.timeoutMs,2e3);return{...e,timeoutMs:t,commandTimeoutMs:Math.min(e.commandTimeoutMs,t+3e3)}}function pi(){let e=y().environment.AGENT_DEVICE_ANDROID_SNAPSHOT_HELPER_SESSION;return e===void 0||!/^(0|false|no|off)$/i.test(e)}async function L(e,t={}){let n=I.get(e);if(!n)return!1;I.delete(e);let r=Or(n.process),i=t.force===!0||t.signal?.aborted===!0,a=await mi(n,r,i,t.signal),o=r.hasEnded(),s=a.acknowledged&&a.exited,c=s&&await kt({adb:n.adb,deviceKey:e,signal:t.signal}),l=i?t.signal?.aborted===!0?250:br:ii,u=i?250:2e3,[d,f]=await Promise.all([jr({process:n.process,processExit:r,timeoutMs:u}),Dr({adb:n.adb,process:n.process,port:n.port,packageName:n.helper.packageName,timeoutMs:l,forceStopRuntime:t.resetRuntime===!0||!c})]);return h({phase:`android_snapshot_helper_session_stop`,data:{deviceKey:e,port:n.port,capturedCount:n.capturedCount,lifetimeMs:Date.now()-n.startedAtMs,quitAcknowledged:a.acknowledged,quitExitObserved:s,runtimeReleaseConfirmed:c,forceKilled:!o&&d,forced:i||t.signal?.aborted===!0,runtimeForceStopped:f.runtimeForceStopped,externalCleanupTimedOut:f.timedOut}}),!c&&!f.runtimeForceStopped&&N({deviceKey:e,packageName:n.helper.packageName,cause:t.cause}),!0}async function mi(e,t,n,r){if(n)return{acknowledged:!1,exited:!1};let i=`quit-${Date.now()}`;try{let n=mr(await cr(e.port,`quit ${i}`,1e3,r),i);return{acknowledged:n,exited:n&&await Ar(t.ended,11e3,r)&&t.completedCleanly()}}catch{return{acknowledged:!1,exited:!1}}}async function hi(e){await L(Cr(e))}async function gi(){let e=await Promise.allSettled([...I.keys()].map(e=>L(e)));ai.clear();let t=e.filter(e=>e.status===`rejected`).map(e=>e.reason);if(t.length>0)throw AggregateError(t,`Failed to retire every Android snapshot helper session`);Mr(),At()}async function _i(e){let t=await si(e);if(t)return await vi({session:t.session,deviceKey:t.deviceKey,options:e,resolved:t.resolved})}async function vi(e){let{session:t,deviceKey:n,options:r,resolved:i}=e;try{let e=t.capturedCount>0,n=await lr({port:t.port,timeoutMs:i.timeoutMs,commandTimeoutMs:i.commandTimeoutMs,signal:r.signal});return t.capturedCount+=1,{xml:n.xml,metadata:{...n.metadata,transport:`persistent-session`,sessionReused:e}}}catch(e){await L(n,{force:!0,signal:r.signal,cause:e}),r.signal?.throwIfAborted(),h({level:`warn`,phase:`android_snapshot_helper_session_fallback`,data:{deviceKey:n,reason:e instanceof Error?e.message:String(e),uiAutomationConnectionTimeout:Ye(e)===`accessibility-timeout`}});return}}async function yi(e){let n=ci(e.deviceKey);if(!n)return;if(!bi(n.helper,e.helper)){h({level:`warn`,phase:`android_snapshot_helper_session_touch_identity_mismatch`,data:{deviceKey:e.deviceKey,sessionHelper:n.helper,requestedHelper:e.helper}}),await L(e.deviceKey);return}let r=`${e.action}-${Date.now()}-${Math.random().toString(16).slice(2)}`,i=e.payloadBase64?`${e.action} ${r} ${e.payloadBase64}`:`${e.action} ${r}`,a;try{a=fr(await cr(n.port,i,e.timeoutMs)),pr(a,r)}catch(t){throw await L(e.deviceKey),t}if(a.ok!==`true`)throw new t(`COMMAND_FAILED`,a.message||a.errorType||`Android automation helper ${e.action} failed`,{errorType:a.errorType,helper:a});return a}function bi(e,t){return e.packageName===t.packageName&&e.runner===t.runner&&xi(e.helperVersion,t.helperVersion)&&xi(e.helperVersionCode,t.helperVersionCode)&&xi(e.sha256,t.sha256)}function xi(e,t){return e===void 0||t===void 0||e===t}const Si=`android-touch-plan-v1`,Ci=45e3,wi=`ANDROID_TOUCH_HELPER_NO_FINAL_RESULT`,Ti=`ANDROID_TOUCH_HELPER_REPORTED_FAILURE`;async function Ei(e,t){let n=await ki(e),r=ji(t),i=Math.max(45e3,r.durationMs+15e3),a=Buffer.from(JSON.stringify({protocol:Si,...r})).toString(`base64`),o=await m(`android_touch_helper_gesture`,async()=>{let e=await yi({deviceKey:n.deviceKey,action:`gesture`,helper:Oi(n.artifact),payloadBase64:a,timeoutMs:i});return e?{...Fi(e),helperTransport:`persistent-session`}:{...await Ni({adb:n.adb,runner:n.artifact.manifest.instrumentationRunner,extraArgs:[`-e`,`mode`,`gesture`,`-e`,`payloadBase64`,a],timeoutMs:i,readResult:Fi}),helperTransport:`instrumentation`}},{packageName:n.artifact.manifest.packageName,version:n.artifact.manifest.version});return{backend:`android-helper`,helperVersion:n.artifact.manifest.version,installReason:n.install.reason,...o}}async function Di(e,t={}){let n=await ki(e);t.helperSessionScope===`daemon-session`&&await oi(Ir({adb:n.adb,adbProvider:n.adbProvider,artifact:n.artifact,deviceKey:n.deviceKey}));try{let e=await yi({deviceKey:n.deviceKey,action:`viewport`,helper:Oi(n.artifact),timeoutMs:Ci});if(e)return Ii(e)}catch(e){await L(n.deviceKey),h({level:`warn`,phase:`android_touch_helper_viewport_session_fallback`,data:{reason:e instanceof Error?e.message:String(e)}})}return await Ni({adb:n.adb,runner:n.artifact.manifest.instrumentationRunner,extraArgs:[`-e`,`mode`,`viewport`],timeoutMs:Ci,readResult:Ii})}function Oi(e){return{packageName:e.manifest.packageName,runner:e.manifest.instrumentationRunner,helperVersion:e.manifest.version,helperVersionCode:e.manifest.versionCode,sha256:e.manifest.sha256}}async function ki(e){let t=S(e),n=t.snapshotHelperArtifact??await Ai(),r=Cr(e);await Tr({deviceKey:r,adb:t.exec});let i=await m(`android_touch_helper_install`,async()=>await Zn({adb:t.exec,adbProvider:t,artifact:n,deviceKey:r,timeoutMs:3e4}),{packageName:n.manifest.packageName,versionCode:n.manifest.versionCode});return h({phase:`android_touch_helper_install_decision`,data:i}),i.installed&&await L(r),{adb:t.exec,adbProvider:t,artifact:n,install:i,deviceKey:r}}async function Ai(){return await Sn({helperDirName:`snapshot-helper`,manifestFileName:e=>`agent-device-android-snapshot-helper-${e}.manifest.json`,parseManifest:e=>{let t=A(e);return{...t,assetName:t.assetName??`agent-device-android-snapshot-helper-${t.version}.apk`}},unavailableMessage:`Android touch gestures require the bundled Android automation helper artifact, but it was not found or could not be read`})}function ji(e){return{kind:e.topology===`single`?`swipe`:`transform`,durationMs:e.durationMs,pointers:e.pointers.map(Mi)}}function Mi(e){return{pointerId:e.pointerId,samples:e.samples.map(({offsetMs:e,point:t})=>({offsetMs:e,x:t.x,y:t.y}))}}async function Ni(e){let n=await e.adb([`shell`,`am`,`instrument`,`-w`,...e.extraArgs,e.runner],{allowFailure:!0,timeoutMs:e.timeoutMs}),r;try{r=Pi(`${n.stdout}\n${n.stderr}`)}catch(e){if(e instanceof t){if(e.code===Ti)throw new t(`COMMAND_FAILED`,e.message,e.details,e);if(e.code!==wi)throw e}throw new t(`COMMAND_FAILED`,n.exitCode===0?`Android automation helper output could not be parsed`:`Android automation helper failed before returning parseable output`,Se(n),e)}if(n.exitCode!==0)throw new t(`COMMAND_FAILED`,`Android automation helper failed`,Se(n,{helper:r}));return e.readResult(r)}function Pi(e){let n=dn(e).results.find(e=>e.agentDeviceProtocol===An);if(!n)throw new t(wi,`Android automation helper did not return a final result`);if(n.ok!==`true`)throw new t(Ti,n.message&&n.message!==`null`?n.message:n.errorType||`Android automation helper returned an error`,{errorType:n.errorType,helper:n});return n}function Fi(e){return{helperKind:e.kind,helperApiVersion:e.helperApiVersion,injectedEvents:O(e.injectedEvents),elapsedMs:O(e.elapsedMs)}}function Ii(e){let n=O(e.x),r=O(e.y),i=O(e.width),a=O(e.height);if(n===void 0||r===void 0||i===void 0||a===void 0)throw new t(`COMMAND_FAILED`,`Android helper returned an invalid gesture viewport`);let o=Li(e);return{viewport:vn({x:n,y:r,width:i,height:a}),...o?{keyboard:o}:{}}}function Li(e){let t=O(e.keyboardX),n=O(e.keyboardY),r=O(e.keyboardWidth),i=O(e.keyboardHeight);if(t!==void 0&&n!==void 0&&r!==void 0&&i!==void 0)return{x:t,y:n,width:r,height:i}}function Ri(e){if(e.topology===`two`||e.intent===`longPress`)return e;let{releaseBehavior:t,...n}=e,[{pointerId:r,samples:i}]=n.pointers,a=[...new Set([...We(e.durationMs,`android`),...i.map(({offsetMs:e})=>e)])].sort((e,t)=>e-t),o=0,s=a.map(e=>{for(;o<i.length-2&&e>i[o+1].offsetMs;)o+=1;let n=i[o],r=i[o+1],a=r.offsetMs-n.offsetMs,s=(e-n.offsetMs)/a;return{offsetMs:e,point:e===r.offsetMs||a===0?r.point:Ke(n.point,r.point,t===`controlled`?zi(s,a):s)}}),c=[s[0],s[1],s[2],...s.slice(3)];return{...n,pointers:[{pointerId:r,samples:c}]}}function zi(e,t){let n=Math.min(16/t,.5);return e<n?e**2/n:1-(1-e)**2/(1-n)}async function Bi(e,t){let n=Ri(t),r=Pe(e);if(r){let e=n.intent===`longPress`?{...n,viewport:vn(await r.gestureViewport())}:n;return{backend:`provider-native-touch`,...await r.touch(e)??{}}}return await Ei(e,n)}async function Vi(e,t={}){return(await Hi(e,t)).viewport}async function Hi(e,t={}){let n=Pe(e);return n?{viewport:vn(await n.gestureViewport())}:await Di(e,t)}async function Ui(e,t,n){await C(e,[`shell`,`input`,`tap`,String(t),String(n)])}async function Wi(e,t,n){let r=we(t);await C(e,[`shell`,`input`,...n&&n>0?[`keyevent`,`--longpress`]:[`keyevent`],r])}async function Gi(e){await C(e,[`shell`,`input`,`keyevent`,`4`])}async function Ki(e){await C(e,[`shell`,`input`,`keyevent`,`3`])}async function qi(e){await C(e,[`shell`,`input`,`keyevent`,`ENTER`])}async function Ji(e,t){let n=ia(t);await C(e,[`shell`,`settings`,`put`,`system`,`accelerometer_rotation`,`0`]),await C(e,[`shell`,`settings`,`put`,`system`,`user_rotation`,n]),await Xi(e,t,n)}const Yi=15e3;async function Xi(e,n,r){let i=Date.now()+Yi,a=await Zi(e,n,i);for(;a!==void 0&&a!==r&&Date.now()<i;)await g(Math.min(500,Qi(i))),a=await Zi(e,n,i);if(a!==void 0&&a!==r)throw new t(`COMMAND_FAILED`,`orientation ${n} did not take effect: the display still reports rotation ${a} after ${Yi}ms`,{requestedRotation:Number(r),observedRotation:Number(a),hint:"The foreground app may pin its orientation, or the device may ignore user_rotation. Check `adb shell dumpsys display | grep mCurrentOrientation` and the app manifest."})}async function Zi(e,n,r){try{let t=await C(e,[`shell`,`dumpsys`,`display`],{timeoutMs:Qi(r)});return/mCurrentOrientation=(\d)/.exec(t.stdout)?.[1]}catch(e){throw new t(`COMMAND_FAILED`,`orientation ${n} could not confirm the display rotation: ${e instanceof Error?e.message:String(e)}`,{hint:"The device did not answer `dumpsys display` within the orientation budget."})}}function Qi(e){return Math.max(1,e-Date.now())}async function $i(e){await C(e,[`shell`,`input`,`keyevent`,`187`])}async function ea(e,t,n,r=800){let i={x:t,y:n};return await Bi(e,{topology:`single`,intent:`longPress`,durationMs:r,pointers:[{pointerId:0,samples:[{offsetMs:0,point:i},{offsetMs:r,point:i}]}]})}async function ta(e,t,n){await Ui(e,t,n)}async function na(e,t,n){let{viewport:r,keyboard:i}=await Hi(e,{helperSessionScope:n?.helperSessionScope}),a=ra(t,r,i),o=ue({direction:t,amount:n?.amount,pixels:n?.pixels,referenceWidth:a.viewport.width,referenceHeight:a.viewport.height}),s={...o,referenceWidth:a.viewport.x+a.viewport.width,referenceHeight:a.viewport.y+a.viewport.height,x1:a.viewport.x+o.x1,y1:a.viewport.y+o.y1,x2:a.viewport.x+o.x2,y2:a.viewport.y+o.y2},c=Math.max(n?.durationMs??300,16),l=await Bi(e,{...Ge({intent:`pan`,origin:{x:s.x1,y:s.y1},delta:{x:s.x2-s.x1,y:s.y2-s.y1},durationMs:c},a.viewport,`android`),releaseBehavior:n?.releaseBehavior??`controlled`});return{...s,...a.evidence,...n?.durationMs===void 0?{}:{durationMs:c},...l}}function ra(e,t,n){if(n===void 0)return{viewport:t,evidence:{}};let r=de(t,n);if(r.kind===`occluded`)throw le(e,{keyboardMinY:r.keyboardMinY,visibleHeight:r.visibleHeight,viewportHeight:t.height});return r.kind===`avoided`?{viewport:r.viewport,evidence:{keyboardAvoided:!0,keyboardMinY:r.keyboardMinY}}:{viewport:t,evidence:{}}}function ia(e){let n=ve[e];if(n===void 0)throw new t(`INVALID_ARGS`,`Unsupported Android rotation: ${e}`);return String(n)}async function aa(e){let n=(await C(e,[`shell`,`wm`,`size`])).stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(!n)throw new t(`COMMAND_FAILED`,`Unable to read screen size`);return{width:Number(n[1]),height:Number(n[2])}}async function oa(e,t,n){return t===`wait`?await sa(n.captureNodes,n.timeoutMs??1e4):t===`get`?pa((await fa(n.captureNodes))?.alert??null):await ca(e,t,n.captureNodes)}async function sa(e,n){let r=Date.now(),i=await da(e,n);if(!i)throw new t(`COMMAND_FAILED`,`alert wait timed out`);return{kind:`alertWait`,platform:`android`,action:`wait`,alert:i.alert,waitedMs:Date.now()-r,...fe(`Alert visible`)}}async function ca(e,n,r){let i=await da(r,pe);if(!i)throw new t(`COMMAND_FAILED`,`alert not found`,{hint:`If a sheet is visible in snapshot but alert reports no alert, it is likely app-owned UI. Use snapshot -i and press the visible label/ref.`});let a=Ut(i.buttons,n);if(a)return await Ui(e,a.x,a.y),await la(i.alert,n,r),ma(n,i.alert,a.label,{x:a.x,y:a.y});if(n===`dismiss`)return await Gi(e),await la(i.alert,n,r),ma(n,i.alert,`Back`);throw new t(`COMMAND_FAILED`,`alert accept found an alert but no accept button`,{alert:i.alert,hint:`Inspect alert get --json for visible buttons, then use press by visible label/ref if needed.`})}async function la(e,n,r){let i=Date.now();for(;;){let a=await fa(r);if(!a||!ua(a.alert,e))return;if(Date.now()-i>=2e3)throw new t(`COMMAND_FAILED`,`alert ${n} did not dismiss the visible alert`,{alert:e,hint:`The alert button was pressed but the dialog is still visible. Inspect alert get --json, then press the visible button by label/ref or retry.`});await g(300)}}function ua(e,t){return e.title===t.title&&e.buttons.join(`\0`)===t.buttons.join(`\0`)}async function da(e,t){let n=Date.now();for(;Date.now()-n<t;){let t=await fa(e);if(t)return t;await g(300)}return null}async function fa(e){return Vt(await m(`snapshot_capture`,e,{backend:`android`,purpose:`alert`}))}function pa(e){return{kind:`alertStatus`,platform:`android`,action:`get`,alert:e,...fe(e?`Alert visible`:`No alert visible`)}}function ma(e,t,n,r){return{kind:`alertHandled`,platform:`android`,action:e,handled:!0,alert:t,button:n,...r?{coordinates:r}:{},...fe(`Alert ${e}ed`)}}const ha=`android.intent.category.LAUNCHER`,ga=`android.intent.category.DEFAULT`;async function _a(e,t){await e([`shell`,`am`,`force-stop`,t])}async function va(e,t,n=[ha]){for(let r of n){let n=await e([`shell`,`cmd`,`package`,`resolve-activity`,`--brief`,`-a`,`android.intent.action.MAIN`,`-c`,r,t],{allowFailure:!0});if(n.exitCode!==0)continue;let i=tt(n.stdout);if(i)return i}return null}async function ya(e,n,r={}){let i=r.category??ha;if(r.activity){await e([`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,ga,`-c`,i,`-n`,ba(n,r.activity)]);return}let a=await e([`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,ga,`-c`,i,`-p`,n],{allowFailure:!0});if(a.exitCode===0&&!nt(a.stdout,a.stderr))return;let o=await va(e,n,[i]);if(!o)throw new t(`COMMAND_FAILED`,`Failed to resolve Android launch component for ${n}`,{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});await e([`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,ga,`-c`,i,`-n`,o])}function ba(e,t){return t.includes(`/`)?t:`${e}/${t.startsWith(`.`)?t:`.${t}`}`}let xa=null;function Sa(e){return`${e.PATH??``}::${e.AGENT_DEVICE_BUNDLETOOL_JAR??``}`}async function Ca(e){let n=Sa(e);if(xa?.key===n)return xa.invocation;if(await xe(`bundletool`)){let e={cmd:`bundletool`,prefixArgs:[]};return xa={key:n,invocation:e},e}let r=await Ce(e.AGENT_DEVICE_BUNDLETOOL_JAR,`AGENT_DEVICE_BUNDLETOOL_JAR`);if(!r)throw new t(`TOOL_MISSING`,`bundletool not found in PATH. Install bundletool or set AGENT_DEVICE_BUNDLETOOL_JAR to a bundletool-all.jar path.`);let i={cmd:`java`,prefixArgs:[`-jar`,r]};return xa={key:n,invocation:i},i}async function wa(e,t,n){let r=await Ca(n);await be(r.cmd,[...r.prefixArgs,...e],{signal:t})}function Ta(e){return w.extname(e).toLowerCase()===`.aab`}async function Ea(e,t,n={}){let r=S(e),i=`universal`;if(r.installBundle){await r.installBundle(t,{mode:i,signal:n.signal});return}let a=y().files,o=await a.makeTempDirectory(`agent-device-aab-`),s=w.join(o,`bundle.apks`);try{await wa([`build-apks`,`--bundle`,t,`--output`,s,`--mode`,i],n.signal,n.environment??y().environment),await wa([`install-apks`,`--apks`,s,`--device-id`,e.id],n.signal,n.environment??y().environment)}finally{await a.remove(o,{recursive:!0,force:!0})}}async function Da(e,t,n={}){if(Ta(t)){await Ea(e,t,n);return}await Ve(t,{device:e,replace:!0,signal:n.signal})}async function Oa(e,t,n={}){await ot(e,async()=>{e.booted||await Ze(e.id,void 0,n.signal),await Da(e,t,n)})}const ka=[`mInputShown`,`mIsInputViewShown`,`isInputViewShown`,`mDecorViewVisible`,`mWindowVisible`,`mInShowWindow`],Aa=new Map([[2,`number`],[3,`phone`],[4,`datetime`]]),ja=new Set([32,208]),Ma=new Set([128,224,144]);async function Na(e){return await R(x(e))}async function R(e){let t=await e([`shell`,`dumpsys`,`input_method`],{allowFailure:!0});if(t.exitCode!==0)throw b(`Failed to query Android keyboard state`,t);return Ia(t.stdout)}async function Pa(e){return await Fa(x(e))}async function Fa(e){let n=await R(e),r=n,i=0;for(;r.visible&&i<2;)await e([`shell`,`input`,`keyevent`,`111`]),i+=1,await g(120),r=await R(e);if(n.visible&&r.visible)throw new t(`UNSUPPORTED_OPERATION`,`Android keyboard dismiss is unavailable for the current IME without back navigation.`,{attempts:i,inputType:r.inputType,type:r.type,inputMethodPackage:r.inputMethodPackage,focusedPackage:r.focusedPackage,focusedResourceId:r.focusedResourceId,inputOwner:r.inputOwner});return{attempts:i,wasVisible:n.visible,dismissed:n.visible&&!r.visible,visible:r.visible,inputType:r.inputType,type:r.type,inputMethodPackage:r.inputMethodPackage,focusedPackage:r.focusedPackage,focusedResourceId:r.focusedResourceId,inputOwner:r.inputOwner}}function Ia(e){let t=Va(e)??La(e),n=Ra(e),r=za(e,/\bpackageName=([A-Za-z0-9_.]+)\b/g),i=za(e,/\b(?:resourceId|resource-id)=([^\s,}]+)/g),a=f(e),o=ee(r,i,a);return Ba(r,i,a),{visible:t??!1,inputType:n,type:n?Ga(n):void 0,inputMethodPackage:a,focusedPackage:r,focusedResourceId:i,inputOwner:o}}function La(e){let t=e.match(/\bmImeWindowVis=0x([0-9a-fA-F]+)\b/)?.[1];if(!t)return null;let n=Number.parseInt(t,16);return Number.isNaN(n)?null:!!(n&1)}function Ra(e){let t=za(e,/\binputType=0x([0-9a-fA-F]+)\b/gi);return t?`0x${t.toLowerCase()}`:void 0}function za(e,t){let n;for(let r of e.matchAll(t))n=r[1];return n}function Ba(e,t,n){n||!u(e)&&!c(t)||h({level:`warn`,phase:`android_input_ownership_fallback`,data:{focusedPackage:e,focusedResourceId:t}})}function Va(e){return Ua(Ha(e,ka))}function Ha(e,t){let n=new Map,r=RegExp(`\\b(${t.join(`|`)})=([a-zA-Z]+)\\b`,`g`);for(let t of e.matchAll(r)){let e=t[1],r=t[2]?.toLowerCase();!e||r!==`true`&&r!==`false`||n.set(e,r===`true`)}return n}function Ua(e){if(e.size===0)return null;let t=Wa(e,[`mWindowVisible`,`mDecorViewVisible`,`mInShowWindow`]);if(t!==void 0)return t;let n=e.get(`mInputShown`);return n===void 0?Wa(e,[`mIsInputViewShown`,`isInputViewShown`])??null:n}function Wa(e,t){for(let n of t){let t=e.get(n);if(t!==void 0)return t}}function Ga(e){let t=Number.parseInt(e.replace(/^0x/i,``),16);if(Number.isNaN(t))return`unknown`;let n=t&15,r=Aa.get(n);if(r)return r;if(n!==1)return`unknown`;let i=t&4080;return ja.has(i)?`email`:Ma.has(i)?`password`:`text`}async function Ka(e){return await qa(x(e))}async function qa(e){return Za(await Xa(e,[`shell`,`cmd`,`clipboard`,`get`,`text`],`read`))}async function Ja(e,t){await Ya(x(e),t)}async function Ya(e,t){await Xa(e,[`shell`,`cmd`,`clipboard`,`set`,`text`,Te(t)],`write`)}async function Xa(e,n,r){let i=await e(n,{allowFailure:!0});if(i.exitCode===0)return i.stdout;throw Ue(i.stdout,i.stderr)?new t(`UNSUPPORTED_OPERATION`,`Android shell clipboard ${r} is not supported on this device.`):b(`Failed to ${r} Android clipboard text`,i)}function Za(e){let t=e.replaceAll(`\r
8
+ `);if(r<0)throw new t(`COMMAND_FAILED`,`Android snapshot helper session returned malformed output`,{response:e});let i=mr(e.slice(0,r)),a=e.slice(r+2);return fr(i,n),pr(i,a),{xml:a,metadata:hr(i)}}function fr(e,n){if(e.agentDeviceProtocol!==`android-snapshot-helper-v1`)throw new t(`COMMAND_FAILED`,`Android snapshot helper session returned wrong protocol`,{headers:e});if(e.outputFormat!==`uiautomator-xml`)throw new t(`COMMAND_FAILED`,`Android snapshot helper session returned wrong output format`,{headers:e});if(e.requestId!==n)throw new t(`COMMAND_FAILED`,`Android snapshot helper session returned stale output`,{headers:e,requestId:n});if(e.ok!==`true`)throw new t(`COMMAND_FAILED`,e.message||e.errorType||`Android snapshot helper session returned an error`,{helper:e,...j(tr(e))})}function pr(e,n){let r=D(e.byteLength);if(r!==void 0&&Buffer.byteLength(n,`utf8`)!==r)throw new t(`COMMAND_FAILED`,`Android snapshot helper session returned truncated XML`,{headers:e,actualByteLength:Buffer.byteLength(n,`utf8`)});if(!n.includes(`<hierarchy`)||!n.includes(`</hierarchy>`))throw new t(`COMMAND_FAILED`,`Android snapshot helper session did not return XML`,{headers:e,xml:n})}function mr(e){let t={};for(let n of e.split(/\r?\n/)){let e=n.indexOf(`=`);e<0||(t[n.slice(0,e)]=n.slice(e+1))}return t}function hr(e){return{helperApiVersion:e.helperApiVersion,outputFormat:Nn,waitForIdleTimeoutMs:D(e.waitForIdleTimeoutMs),waitForIdleQuietMs:D(e.waitForIdleQuietMs),timeoutMs:D(e.timeoutMs),maxDepth:D(e.maxDepth),maxNodes:D(e.maxNodes),rootPresent:yn(e.rootPresent),captureMode:e.captureMode===`interactive-windows`||e.captureMode===`active-window`?e.captureMode:void 0,windowCount:D(e.windowCount),nodeCount:D(e.nodeCount),truncated:yn(e.truncated),elapsedMs:D(e.elapsedMs)}}function M(e,n,r,i){if(i instanceof t){let a=i.details??{};return new t(i.code,i.message,{...a,action:e,package:r,tool:n,hint:typeof a.hint==`string`?a.hint:vr(n,a)},i)}return new t(`COMMAND_FAILED`,`Failed to ${e} Android ${n} for ${r}`,{action:e,package:r,tool:n,hint:gr(n)},i)}function gr(e){return e===`simpleperf`?`Verify simpleperf is available, the app process is running, and the app/device permits native CPU profiling.`:`Verify perfetto is available, the app process is running, and the device permits trace capture.`}function _r(e){return e===`simpleperf`?`Use an emulator/system image with simpleperf available, or install the Android NDK simpleperf binary for this device.`:`Use Android 10+ or a system image that exposes the perfetto command-line binary.`}function vr(e,t){let n=(typeof t.stderr==`string`?t.stderr:``).toLowerCase();return e===`simpleperf`?yr(n):xr(n)?`Use a device image that permits perfetto trace capture for shell, keep the app running, then retry perf trace start.`:gr(e)}function yr(e){return br(e)?`Use a debuggable/profileable Android app or a device image that permits simpleperf for the target process, then retry perf cpu profile start.`:e.includes(`not supported`)||e.includes(`failed to open perf event`)?`This device image does not expose the requested simpleperf event for the app process. Try a different emulator/system image or a profileable app.`:gr(`simpleperf`)}function br(e){return e.includes(`permission denied`)||e.includes(`not profileable`)||e.includes(`profileable`)}function xr(e){return e.includes(`permission denied`)||e.includes(`not allowed`)}const Sr=`adb-shell-simpleperf`,Cr=`adb-shell-perfetto`,wr=15e3,N=3e4,Tr=`/data/local/tmp`;async function Er(e,n){try{let t=await e([`shell`,`pidof`,n],{allowFailure:!0,timeoutMs:wr}),r=Or(t.stdout);if(t.exitCode===0&&r)return r}catch{}throw new t(`COMMAND_FAILED`,`No active Android app process found for ${n}`,{package:n,hint:`Run open <app> for this session again, wait for the app UI to appear, then retry perf.`})}async function Dr(e,n,r){let i=await e([`shell`,`command -v ${n} || which ${n}`],{allowFailure:!0,timeoutMs:wr});if(!(i.exitCode===0&&i.stdout.trim()))throw new t(`UNSUPPORTED_OPERATION`,`Android device does not expose ${n}`,{package:r,tool:n,hint:_r(n)})}function Or(e){return e.trim().split(/\s+/).find(e=>/^\d+$/.test(e))}const kr=2e3,Ar=`android_snapshot_helper_runtime_occupied`,P=new Map;function jr(e){return`${e.platform}:${e.id}`}async function Mr(e){await F({adb:e.adb,packageName:e.packageName}),await Pr({deviceKey:e.deviceKey,packageName:e.packageName,adb:e.adb,cause:e.cause})}async function Nr(e){let t=P.get(e.deviceKey);if(!t)return;await F({adb:e.adb,packageName:t.packageName,timeoutMs:5e3,...e.signal?{signal:e.signal}:{}}),e.signal?.throwIfAborted();let n=await Lr({adb:e.adb,packageName:t.packageName});if(n===`occupied`&&(await g(250),n=await Lr({adb:e.adb,packageName:t.packageName})),n===`occupied`)throw Ir({deviceKey:e.deviceKey,packageName:t.packageName,cause:t.cause});n!==`unknown`&&P.delete(e.deviceKey)}async function Pr(e){let t=e.release??await Lr({adb:e.adb,packageName:e.packageName});if(t===`released`)return P.delete(e.deviceKey),t;let n=e.cause instanceof Error?e.cause.message:String(e.cause);return P.set(e.deviceKey,{packageName:e.packageName,cause:n}),h({level:`warn`,phase:`android_snapshot_helper_retirement_pending`,data:{deviceKey:e.deviceKey,packageName:e.packageName,release:t}}),t}function Fr(e){return e instanceof t&&e.details?.reason===Ar}function Ir(e){let n=e.cause instanceof Error?e.cause.message:String(e.cause);return new t(`COMMAND_FAILED`,`Android automation helper is still holding device automation ownership`,{reason:Ar,deviceKey:e.deviceKey,packageName:e.packageName,cause:n,hint:`Retry after the helper process exits, or restart the device if Android keeps reporting the helper as running.`})}async function Lr(e){try{let t=await e.adb([`shell`,`pidof`,e.packageName,`||`,`echo`,`AGENT_DEVICE_NO_HELPER`],{allowFailure:!0,timeoutMs:kr}),n=t.stdout.trim();return Or(n)?`occupied`:n===`AGENT_DEVICE_NO_HELPER`&&t.stderr.trim().length===0?`released`:`unknown`}catch{return`unknown`}}async function Rr(e){let t=AbortSignal.timeout(e.timeoutMs);return await Promise.all([...e.forceStopRuntime?[F({adb:e.adb,packageName:e.packageName,timeoutMs:e.timeoutMs,signal:t})]:[],Gr({...e,signal:t})]),{timedOut:t.aborted}}function zr(e){let t=Br(e);return{ended:t?Promise.resolve():new Promise(t=>{e.once(`close`,()=>t()),e.once(`exit`,()=>t())}),hasEnded:()=>Br(e),completedCleanly:()=>!t&&e.exitCode===0&&e.signalCode==null}}function Br(e){return e.exitCode!=null||e.signalCode!=null}async function Vr(e,t,n){let r,i,a=await Promise.race([e.then(()=>!0),new Promise(e=>{r=setTimeout(()=>e(!1),t)}),...n?[new Promise(e=>{i=()=>e(!1),n.addEventListener(`abort`,i,{once:!0}),n.aborted&&i()})]:[]]);return r&&clearTimeout(r),i&&n?.removeEventListener(`abort`,i),a}async function Hr(e){if(e.processExit.hasEnded())return!0;try{e.process.kill(`SIGTERM`)}catch{}return await Vr(e.processExit.ended,e.timeoutMs)}function Ur(e){P.delete(e)}function Wr(){P.clear()}async function F(e){await e.adb([`shell`,`am`,`force-stop`,e.packageName],{allowFailure:!0,timeoutMs:e.timeoutMs??2e3,...e.signal?{signal:e.signal}:{}}).catch(()=>{})}async function Gr(e){e.process.stdin?.end(),e.process.stdout?.destroy(),e.process.stderr?.destroy(),await e.adb([`forward`,`--remove`,`tcp:${e.port}`],{allowFailure:!0,timeoutMs:e.timeoutMs,signal:e.signal})}async function Kr(e){let n=Jr(e),r=e.deviceKey??`android:default`;await Nr({deviceKey:r,adb:e.adb,signal:e.signal});let i;try{i=await e.adb(Yr(n),{allowFailure:!0,timeoutMs:n.commandTimeoutMs,signal:e.signal})}catch(t){throw e.signal?.aborted?(await Mr({deviceKey:r,packageName:n.packageName,adb:e.adb,cause:t}),e.signal.throwIfAborted(),t):t}e.signal?.aborted&&(await Mr({deviceKey:r,packageName:n.packageName,adb:e.adb,cause:e.signal.reason}),e.signal.throwIfAborted());let{output:a,cleanupDone:o}=await Xr(e,n,i);if(n.outputPath&&!o&&await ri(e.adb,n.outputPath),i.exitCode!==0)throw new t(`COMMAND_FAILED`,`Android snapshot helper failed`,Se(i,{helper:a.metadata}));return a}function qr(e){return{adb:e.adb,adbProvider:e.adbProvider,deviceKey:e.deviceKey,helperVersion:e.artifact.manifest.version,helperVersionCode:e.artifact.manifest.versionCode,helperSha256:e.artifact.manifest.sha256,packageName:e.artifact.manifest.packageName,instrumentationRunner:e.artifact.manifest.instrumentationRunner,waitForIdleTimeoutMs:500,timeoutMs:Pn,commandTimeoutMs:Fn,...e.signal?{signal:e.signal}:{}}}function Jr(e){let t=I(e.timeoutMs,8e3),n=I(e.packageName,`com.callstack.agentdevice.snapshothelper`);return{waitForIdleTimeoutMs:I(e.waitForIdleTimeoutMs,500),waitForIdleQuietMs:I(e.waitForIdleQuietMs,100),timeoutMs:t,commandTimeoutMs:I(e.commandTimeoutMs,t+5e3),maxDepth:I(e.maxDepth,128),maxNodes:I(e.maxNodes,5e3),packageName:n,runner:I(e.instrumentationRunner,`${n}/.SnapshotInstrumentation`),...e.outputPath?{outputPath:e.outputPath}:{},...e.emitChunks===void 0?{}:{emitChunks:e.emitChunks}}}function I(e,t){return e===void 0?t:e}function Yr(e){return[`shell`,`am`,`instrument`,`-w`,`-e`,`waitForIdleTimeoutMs`,String(e.waitForIdleTimeoutMs),`-e`,`waitForIdleQuietMs`,String(e.waitForIdleQuietMs),`-e`,`timeoutMs`,String(e.timeoutMs),`-e`,`maxDepth`,String(e.maxDepth),`-e`,`maxNodes`,String(e.maxNodes),...e.outputPath?[`-e`,`outputPath`,e.outputPath]:[],...e.emitChunks===void 0?[]:[`-e`,`emitChunks`,String(e.emitChunks)],e.runner]}async function Xr(e,t,n){try{return{output:ii(`${n.stdout}\n${n.stderr}`),cleanupDone:!1}}catch(r){return await Zr(e,t,n,r)}}async function Zr(e,n,r,i){if(i instanceof t&&r.exitCode!==0&&i.details?.helper)throw i;let a=await Qr(e,n,r);if(a)return{output:a,cleanupDone:!0};throw new t(`COMMAND_FAILED`,r.exitCode===0?`Android snapshot helper output could not be parsed`:`Android snapshot helper failed before returning parseable output`,{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode,...j(nr(r.exitCode))},i)}async function Qr(e,t,n){if(!(n.exitCode!==0||!t.outputPath))return await ei(e.adb,t.outputPath,ni(`${n.stdout}\n${n.stderr}`)??$r(t))}function $r(e){return{outputFormat:Nn,waitForIdleTimeoutMs:e.waitForIdleTimeoutMs,waitForIdleQuietMs:e.waitForIdleQuietMs,timeoutMs:e.timeoutMs,maxDepth:e.maxDepth,maxNodes:e.maxNodes,transport:`instrumentation`}}async function ei(e,t,n){let r;try{r=await e(ti(t),{allowFailure:!0,timeoutMs:5e3})}catch{return}if(r.exitCode!==0)return;let i=r.stdout.trim();if(!(!i.includes(`<hierarchy`)||!i.includes(`</hierarchy>`)))return{xml:i,metadata:n}}function ti(e){return[`shell`,`sh`,`-c`,`cat "$1"; status=$?; rm -f "$1"; exit "$status"`,`agent-device-snapshot-helper-output`,e]}function ni(e){try{return fi(oi(pn(e).results))}catch{return null}}async function ri(e,t){try{await e([`shell`,`rm`,`-f`,t],{allowFailure:!0,timeoutMs:5e3})}catch{}}function ii(e){let t=pn(e),n=oi(t.results);return{xml:ci(ai(t.status),n),metadata:{...fi(n),transport:`instrumentation`}}}function ai(e){let t=[];for(let n of e){if(n.agentDeviceProtocol!==`android-snapshot-helper-v1`||n.outputFormat!==`uiautomator-xml`)continue;let{payloadBase64:e}=n;e!==void 0&&t.push({index:L(n.chunkIndex),count:L(n.chunkCount),payloadBase64:e})}return t}function oi(e){let n=e.find(e=>e.agentDeviceProtocol===Mn);if(!n)throw new t(`COMMAND_FAILED`,`Android snapshot helper did not return a final result`);if(n.ok!==`true`)throw new t(`COMMAND_FAILED`,si(n),{errorType:n.errorType,helper:n,...j(tr(n))});return n}function si(e){return e.message&&e.message!==`null`?e.message:e.errorType||`Android snapshot helper returned an error`}function ci(e,n){if(e.length===0)throw new t(`COMMAND_FAILED`,`Android snapshot helper did not return XML chunks`,{helper:n});let r=li(e),i=Buffer.concat(di(ui(e,r),r)).toString(`utf8`);if(!i.includes(`<hierarchy`)||!i.includes(`</hierarchy>`))throw new t(`COMMAND_FAILED`,`Android snapshot helper output did not contain XML`,{xml:i});return i}function li(e){let n=e[0]?.count??e.length;if(n<1||e.length!==n||e.some(e=>e.count!==n))throw new t(`COMMAND_FAILED`,`Android snapshot helper returned incomplete XML chunks`,{expectedChunks:n,actualChunks:e.length});return n}function ui(e,n){let r=new Map;for(let i of e){if(i.index===void 0||i.index<0||i.index>=n)throw new t(`COMMAND_FAILED`,`Android snapshot helper returned invalid chunk index`,{chunkIndex:i.index,expectedChunks:n});if(r.has(i.index))throw new t(`COMMAND_FAILED`,`Android snapshot helper returned duplicate XML chunks`,{chunkIndex:i.index});r.set(i.index,i.payloadBase64)}return r}function di(e,n){let r=[];for(let i=0;i<n;i+=1){let a=e.get(i);if(a===void 0)throw new t(`COMMAND_FAILED`,`Android snapshot helper returned incomplete XML chunks`,{missingChunkIndex:i,expectedChunks:n});r.push(Buffer.from(a,`base64`))}return r}function fi(e){return{helperApiVersion:e.helperApiVersion,outputFormat:Nn,waitForIdleTimeoutMs:L(e.waitForIdleTimeoutMs),waitForIdleQuietMs:L(e.waitForIdleQuietMs),timeoutMs:L(e.timeoutMs),maxDepth:L(e.maxDepth),maxNodes:L(e.maxNodes),rootPresent:mi(e.rootPresent),captureMode:pi(e.captureMode),windowCount:L(e.windowCount),nodeCount:L(e.nodeCount),truncated:mi(e.truncated),elapsedMs:L(e.elapsedMs)}}function pi(e){return e===`interactive-windows`||e===`active-window`?e:void 0}const L=D,mi=yn,hi=5e3,R=new Map,z=new Map;async function gi(e){return await _i(e)!==void 0}async function _i(e){let t=e.deviceKey??`android:default`;if(await Nr({deviceKey:t,adb:e.adb,signal:e.signal}),!ki()||!e.adbProvider?.spawn)return;let n=Jr(e),r=Di(n),i=await yi({deviceKey:t,identity:Ei(t,r,e),options:e,resolved:r,startBudgetMs:Oi(n.commandTimeoutMs)});return i?{session:i,resolved:r,deviceKey:t}:void 0}function vi(e){return R.get(e)}async function yi(e){if(!Si(e.identity))return await bi(e.deviceKey,e.identity),R.get(e.deviceKey)??await xi(e)}async function bi(e,t){let n=R.get(e);!n||wi(n,t)||await B(e,{force:Br(n.process)})}async function xi(e){let n=Date.now();try{return await Ti(e)}catch(r){e.options.signal?.throwIfAborted(),z.set(e.identity,Date.now()+Ci(Date.now()-n)),h({level:`warn`,phase:`android_snapshot_helper_session_start_failed`,data:{deviceKey:e.deviceKey,reason:r instanceof t?r.details?.reason:void 0,detail:r instanceof Error?r.message:String(r)}});return}}function Si(e){let t=z.get(e);return t===void 0?!1:t>Date.now()||(z.delete(e),!1)}function Ci(e){return Math.min(Math.max(e,1e4),6e4)}function wi(e,t){return e.identity===t&&!Br(e.process)}async function Ti(e){let n=await rr();await e.options.adb([`forward`,`tcp:${n}`,`tcp:${n}`],{allowFailure:!1,timeoutMs:hi,signal:e.options.signal});let r=Yr({...e.resolved,outputPath:void 0,emitChunks:!1}),i=r.at(-1);if(!i)throw new t(`INVALID_ARGS`,`Android snapshot helper runner was not resolved`);let a=[...r.slice(0,-1),`-e`,`sessionPort`,String(n),i],o=e.options.adbProvider.spawn(a,{allowFailure:!0,captureOutput:!1}),s={identity:e.identity,deviceKey:e.deviceKey,helper:{packageName:e.resolved.packageName,runner:e.resolved.runner,helperVersion:e.options.helperVersion,helperVersionCode:e.options.helperVersionCode,sha256:e.options.helperSha256},port:n,adb:e.options.adb,process:o,startedAtMs:Date.now(),capturedCount:0};try{return await sr(o,e.startBudgetMs,e.options.signal),R.set(e.deviceKey,s),z.delete(e.identity),Ur(e.deviceKey),h({phase:`android_snapshot_helper_session_ready`,data:{deviceKey:e.deviceKey,port:n,packageName:e.resolved.packageName,runner:e.resolved.runner}}),s}catch(t){let n=zr(o);try{o.kill(`SIGTERM`)}catch{}throw await Promise.all([Vr(n.ended,250),Rr({adb:s.adb,process:s.process,port:s.port,packageName:s.helper.packageName,timeoutMs:kr,forceStopRuntime:!0})]),await Pr({deviceKey:e.deviceKey,packageName:s.helper.packageName,adb:s.adb,cause:t}),t}}function Ei(e,t,n){return JSON.stringify({deviceKey:e,packageName:t.packageName,runner:t.runner,helperVersion:n.helperVersion,helperVersionCode:n.helperVersionCode,helperSha256:n.helperSha256,waitForIdleTimeoutMs:t.waitForIdleTimeoutMs,waitForIdleQuietMs:t.waitForIdleQuietMs,timeoutMs:t.timeoutMs,maxDepth:t.maxDepth,maxNodes:t.maxNodes})}function Di(e){let t=Math.min(e.timeoutMs,2e3);return{...e,timeoutMs:t,commandTimeoutMs:Math.min(e.commandTimeoutMs,t+3e3)}}function Oi(e){return Math.min(e,Math.max(Math.floor(e/2),5e3))}function ki(){let e=y().environment.AGENT_DEVICE_ANDROID_SNAPSHOT_HELPER_SESSION;return e===void 0||!/^(0|false|no|off)$/i.test(e)}async function B(e,t={}){let n=R.get(e);if(!n)return!1;R.delete(e);let r=zr(n.process),i=t.force===!0||t.signal?.aborted===!0,a=await Ai(n,r,i,t.signal),o=r.hasEnded(),s=a.acknowledged&&a.exited,c=s&&await At({adb:n.adb,deviceKey:e,signal:t.signal}),l=i?t.signal?.aborted===!0?250:kr:hi,u=i?250:2e3,[d,f]=await Promise.all([Hr({process:n.process,processExit:r,timeoutMs:u}),Rr({adb:n.adb,process:n.process,port:n.port,packageName:n.helper.packageName,timeoutMs:l,forceStopRuntime:t.resetRuntime===!0||!c})]),p=await Pr({deviceKey:e,packageName:n.helper.packageName,adb:n.adb,cause:t.cause,...c?{release:`released`}:{}});return h({phase:`android_snapshot_helper_session_stop`,data:{deviceKey:e,port:n.port,capturedCount:n.capturedCount,lifetimeMs:Date.now()-n.startedAtMs,quitAcknowledged:a.acknowledged,quitExitObserved:s,releaseProvenByQuit:c,release:p,forceKilled:!o&&d,forced:i||t.signal?.aborted===!0,externalCleanupTimedOut:f.timedOut}}),!0}async function Ai(e,t,n,r){if(n)return{acknowledged:!1,exited:!1};let i=`quit-${Date.now()}`;try{let n=ur(await ir(e.port,`quit ${i}`,1e3,r),i);return{acknowledged:n,exited:n&&await Vr(t.ended,11e3,r)&&t.completedCleanly()}}catch{return{acknowledged:!1,exited:!1}}}async function ji(e){await B(jr(e))}async function Mi(){try{await Promise.allSettled([...R.keys()].map(async e=>{await B(e)}))}finally{R.clear(),z.clear(),Wr(),jt()}}async function Ni(e){let t=await _i(e);if(t)return await Pi({session:t.session,deviceKey:t.deviceKey,options:e,resolved:t.resolved})}async function Pi(e){let{session:t,deviceKey:n,options:r,resolved:i}=e;try{let e=t.capturedCount>0,n=await ar({port:t.port,timeoutMs:i.timeoutMs,commandTimeoutMs:i.commandTimeoutMs,signal:r.signal});return t.capturedCount+=1,{xml:n.xml,metadata:{...n.metadata,transport:`persistent-session`,sessionReused:e}}}catch(e){await B(n,{force:!0,signal:r.signal,cause:e}),r.signal?.throwIfAborted(),h({level:`warn`,phase:`android_snapshot_helper_session_fallback`,data:{deviceKey:n,reason:e instanceof Error?e.message:String(e),uiAutomationConnectionTimeout:Xe(e)===`accessibility-timeout`}});return}}async function Fi(e){let n=vi(e.deviceKey);if(!n)return;if(!Ii(n.helper,e.helper)){h({level:`warn`,phase:`android_snapshot_helper_session_touch_identity_mismatch`,data:{deviceKey:e.deviceKey,sessionHelper:n.helper,requestedHelper:e.helper}}),await B(e.deviceKey);return}let r=`${e.action}-${Date.now()}-${Math.random().toString(16).slice(2)}`,i=e.payloadBase64?`${e.action} ${r} ${e.payloadBase64}`:`${e.action} ${r}`,a;try{a=cr(await ir(n.port,i,e.timeoutMs)),lr(a,r)}catch(t){throw await B(e.deviceKey),t}if(a.ok!==`true`)throw new t(`COMMAND_FAILED`,a.message||a.errorType||`Android automation helper ${e.action} failed`,{errorType:a.errorType,helper:a});return a}function Ii(e,t){return e.packageName===t.packageName&&e.runner===t.runner&&Li(e.helperVersion,t.helperVersion)&&Li(e.helperVersionCode,t.helperVersionCode)&&Li(e.sha256,t.sha256)}function Li(e,t){return e===void 0||t===void 0||e===t}const Ri=`android-touch-plan-v1`,zi=45e3,Bi=`ANDROID_TOUCH_HELPER_NO_FINAL_RESULT`,Vi=`ANDROID_TOUCH_HELPER_REPORTED_FAILURE`;async function Hi(e,t){let n=await Gi(e),r=qi(t),i=Math.max(45e3,r.durationMs+15e3),a=Buffer.from(JSON.stringify({protocol:Ri,...r})).toString(`base64`),o=await m(`android_touch_helper_gesture`,async()=>{let e=await Fi({deviceKey:n.deviceKey,action:`gesture`,helper:Wi(n.artifact),payloadBase64:a,timeoutMs:i});return e?{...Zi(e),helperTransport:`persistent-session`}:{...await Yi({adb:n.adb,runner:n.artifact.manifest.instrumentationRunner,extraArgs:[`-e`,`mode`,`gesture`,`-e`,`payloadBase64`,a],timeoutMs:i,readResult:Zi}),helperTransport:`instrumentation`}},{packageName:n.artifact.manifest.packageName,version:n.artifact.manifest.version});return{backend:`android-helper`,helperVersion:n.artifact.manifest.version,installReason:n.install.reason,...o}}async function Ui(e,t={}){let n=await Gi(e);t.helperSessionScope===`daemon-session`&&await gi(qr({adb:n.adb,adbProvider:n.adbProvider,artifact:n.artifact,deviceKey:n.deviceKey}));try{let e=await Fi({deviceKey:n.deviceKey,action:`viewport`,helper:Wi(n.artifact),timeoutMs:zi});if(e)return Qi(e)}catch(e){await B(n.deviceKey),h({level:`warn`,phase:`android_touch_helper_viewport_session_fallback`,data:{reason:e instanceof Error?e.message:String(e)}})}return await Yi({adb:n.adb,runner:n.artifact.manifest.instrumentationRunner,extraArgs:[`-e`,`mode`,`viewport`],timeoutMs:zi,readResult:Qi})}function Wi(e){return{packageName:e.manifest.packageName,runner:e.manifest.instrumentationRunner,helperVersion:e.manifest.version,helperVersionCode:e.manifest.versionCode,sha256:e.manifest.sha256}}async function Gi(e){let t=S(e),n=t.snapshotHelperArtifact??await Ki(),r=jr(e);await Nr({deviceKey:r,adb:t.exec});let i=await m(`android_touch_helper_install`,async()=>await Jn({adb:t.exec,adbProvider:t,artifact:n,deviceKey:r,timeoutMs:3e4}),{packageName:n.manifest.packageName,versionCode:n.manifest.versionCode});return h({phase:`android_touch_helper_install_decision`,data:i}),i.installed&&await B(r),{adb:t.exec,adbProvider:t,artifact:n,install:i,deviceKey:r}}async function Ki(){return await wn({helperDirName:`snapshot-helper`,manifestFileName:e=>`agent-device-android-snapshot-helper-${e}.manifest.json`,parseManifest:e=>{let t=In(e);return{...t,assetName:t.assetName??`agent-device-android-snapshot-helper-${t.version}.apk`}},unavailableMessage:`Android touch gestures require the bundled Android automation helper artifact, but it was not found or could not be read`})}function qi(e){return{kind:e.topology===`single`?`swipe`:`transform`,durationMs:e.durationMs,pointers:e.pointers.map(Ji)}}function Ji(e){return{pointerId:e.pointerId,samples:e.samples.map(({offsetMs:e,point:t})=>({offsetMs:e,x:t.x,y:t.y}))}}async function Yi(e){let n=await e.adb([`shell`,`am`,`instrument`,`-w`,...e.extraArgs,e.runner],{allowFailure:!0,timeoutMs:e.timeoutMs}),r;try{r=Xi(`${n.stdout}\n${n.stderr}`)}catch(e){if(e instanceof t){if(e.code===Vi)throw new t(`COMMAND_FAILED`,e.message,e.details,e);if(e.code!==Bi)throw e}throw new t(`COMMAND_FAILED`,n.exitCode===0?`Android automation helper output could not be parsed`:`Android automation helper failed before returning parseable output`,Se(n),e)}if(n.exitCode!==0)throw new t(`COMMAND_FAILED`,`Android automation helper failed`,Se(n,{helper:r}));return e.readResult(r)}function Xi(e){let n=pn(e).results.find(e=>e.agentDeviceProtocol===Mn);if(!n)throw new t(Bi,`Android automation helper did not return a final result`);if(n.ok!==`true`)throw new t(Vi,n.message&&n.message!==`null`?n.message:n.errorType||`Android automation helper returned an error`,{errorType:n.errorType,helper:n});return n}function Zi(e){return{helperKind:e.kind,helperApiVersion:e.helperApiVersion,injectedEvents:D(e.injectedEvents),elapsedMs:D(e.elapsedMs)}}function Qi(e){let n=D(e.x),r=D(e.y),i=D(e.width),a=D(e.height);if(n===void 0||r===void 0||i===void 0||a===void 0)throw new t(`COMMAND_FAILED`,`Android helper returned an invalid gesture viewport`);let o=$i(e);return{viewport:O({x:n,y:r,width:i,height:a}),...o?{keyboard:o}:{}}}function $i(e){let t=D(e.keyboardX),n=D(e.keyboardY),r=D(e.keyboardWidth),i=D(e.keyboardHeight);if(t!==void 0&&n!==void 0&&r!==void 0&&i!==void 0)return{x:t,y:n,width:r,height:i}}function ea(e){if(e.topology===`two`||e.intent===`longPress`)return e;let{releaseBehavior:t,...n}=e,[{pointerId:r,samples:i}]=n.pointers,a=[...new Set([...Ge(e.durationMs,`android`),...i.map(({offsetMs:e})=>e)])].sort((e,t)=>e-t),o=0,s=a.map(e=>{for(;o<i.length-2&&e>i[o+1].offsetMs;)o+=1;let n=i[o],r=i[o+1],a=r.offsetMs-n.offsetMs,s=(e-n.offsetMs)/a;return{offsetMs:e,point:e===r.offsetMs||a===0?r.point:qe(n.point,r.point,t===`controlled`?ta(s,a):s)}}),c=[s[0],s[1],s[2],...s.slice(3)];return{...n,pointers:[{pointerId:r,samples:c}]}}function ta(e,t){let n=Math.min(16/t,.5);return e<n?e**2/n:1-(1-e)**2/(1-n)}async function na(e,t){let n=ea(t),r=Fe(e);if(r){let e=n.intent===`longPress`?{...n,viewport:O(await r.gestureViewport())}:n;return{backend:`provider-native-touch`,...await r.touch(e)??{}}}return await Hi(e,n)}async function ra(e,t={}){return(await ia(e,t)).viewport}async function ia(e,t={}){let n=Fe(e);return n?{viewport:O(await n.gestureViewport())}:await Ui(e,t)}async function aa(e,t,n){await C(e,[`shell`,`input`,`tap`,String(t),String(n)])}async function oa(e,t,n){let r=we(t);await C(e,[`shell`,`input`,...n&&n>0?[`keyevent`,`--longpress`]:[`keyevent`],r])}async function sa(e){await C(e,[`shell`,`input`,`keyevent`,`4`])}async function ca(e){await C(e,[`shell`,`input`,`keyevent`,`3`])}async function la(e){await C(e,[`shell`,`input`,`keyevent`,`ENTER`])}async function ua(e,t){let n=ba(t);await C(e,[`shell`,`settings`,`put`,`system`,`accelerometer_rotation`,`0`]),await C(e,[`shell`,`settings`,`put`,`system`,`user_rotation`,n]),await fa(e,t,n)}const da=15e3;async function fa(e,n,r){let i=Date.now()+da,a=await pa(e,n,i);for(;a!==void 0&&a!==r&&Date.now()<i;)await g(Math.min(500,ma(i))),a=await pa(e,n,i);if(a!==void 0&&a!==r)throw new t(`COMMAND_FAILED`,`orientation ${n} did not take effect: the display still reports rotation ${a} after ${da}ms`,{requestedRotation:Number(r),observedRotation:Number(a),hint:"The foreground app may pin its orientation, or the device may ignore user_rotation. Check `adb shell dumpsys display | grep mCurrentOrientation` and the app manifest."})}async function pa(e,n,r){try{let t=await C(e,[`shell`,`dumpsys`,`display`],{timeoutMs:ma(r)});return/mCurrentOrientation=(\d)/.exec(t.stdout)?.[1]}catch(e){throw new t(`COMMAND_FAILED`,`orientation ${n} could not confirm the display rotation: ${e instanceof Error?e.message:String(e)}`,{hint:"The device did not answer `dumpsys display` within the orientation budget."})}}function ma(e){return Math.max(1,e-Date.now())}async function ha(e){await C(e,[`shell`,`input`,`keyevent`,`187`])}async function ga(e,t,n,r=800){let i={x:t,y:n};return await na(e,{topology:`single`,intent:`longPress`,durationMs:r,pointers:[{pointerId:0,samples:[{offsetMs:0,point:i},{offsetMs:r,point:i}]}]})}async function _a(e,t,n){await aa(e,t,n)}async function va(e,t,n){let{viewport:r,keyboard:i}=await ia(e,{helperSessionScope:n?.helperSessionScope}),a=ya(t,r,i),o=ue({direction:t,amount:n?.amount,pixels:n?.pixels,referenceWidth:a.viewport.width,referenceHeight:a.viewport.height}),s={...o,referenceWidth:a.viewport.x+a.viewport.width,referenceHeight:a.viewport.y+a.viewport.height,x1:a.viewport.x+o.x1,y1:a.viewport.y+o.y1,x2:a.viewport.x+o.x2,y2:a.viewport.y+o.y2},c=Math.max(n?.durationMs??300,16),l=await na(e,{...Ke({intent:`pan`,origin:{x:s.x1,y:s.y1},delta:{x:s.x2-s.x1,y:s.y2-s.y1},durationMs:c},a.viewport,`android`),releaseBehavior:n?.releaseBehavior??`controlled`});return{...s,...a.evidence,...n?.durationMs===void 0?{}:{durationMs:c},...l}}function ya(e,t,n){if(n===void 0)return{viewport:t,evidence:{}};let r=de(t,n);if(r.kind===`occluded`)throw le(e,{keyboardMinY:r.keyboardMinY,visibleHeight:r.visibleHeight,viewportHeight:t.height});return r.kind===`avoided`?{viewport:r.viewport,evidence:{keyboardAvoided:!0,keyboardMinY:r.keyboardMinY}}:{viewport:t,evidence:{}}}function ba(e){let n=ve[e];if(n===void 0)throw new t(`INVALID_ARGS`,`Unsupported Android rotation: ${e}`);return String(n)}async function xa(e){let n=(await C(e,[`shell`,`wm`,`size`])).stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(!n)throw new t(`COMMAND_FAILED`,`Unable to read screen size`);return{width:Number(n[1]),height:Number(n[2])}}async function Sa(e,t,n){return t===`wait`?await Ca(n.captureNodes,n.timeoutMs??1e4):t===`get`?ka((await Oa(n.captureNodes))?.alert??null):await wa(e,t,n.captureNodes)}async function Ca(e,n){let r=Date.now(),i=await Da(e,n);if(!i)throw new t(`COMMAND_FAILED`,`alert wait timed out`);return{kind:`alertWait`,platform:`android`,action:`wait`,alert:i.alert,waitedMs:Date.now()-r,...fe(`Alert visible`)}}async function wa(e,n,r){let i=await Da(r,pe);if(!i)throw new t(`COMMAND_FAILED`,`alert not found`,{hint:`If a sheet is visible in snapshot but alert reports no alert, it is likely app-owned UI. Use snapshot -i and press the visible label/ref.`});let a=Gt(i.buttons,n);if(a)return await aa(e,a.x,a.y),await Ta(i.alert,n,r),Aa(n,i.alert,a.label,{x:a.x,y:a.y});if(n===`dismiss`)return await sa(e),await Ta(i.alert,n,r),Aa(n,i.alert,`Back`);throw new t(`COMMAND_FAILED`,`alert accept found an alert but no accept button`,{alert:i.alert,hint:`Inspect alert get --json for visible buttons, then use press by visible label/ref if needed.`})}async function Ta(e,n,r){let i=Date.now();for(;;){let a=await Oa(r);if(!a||!Ea(a.alert,e))return;if(Date.now()-i>=2e3)throw new t(`COMMAND_FAILED`,`alert ${n} did not dismiss the visible alert`,{alert:e,hint:`The alert button was pressed but the dialog is still visible. Inspect alert get --json, then press the visible button by label/ref or retry.`});await g(300)}}function Ea(e,t){return e.title===t.title&&e.buttons.join(`\0`)===t.buttons.join(`\0`)}async function Da(e,t){let n=Date.now();for(;Date.now()-n<t;){let t=await Oa(e);if(t)return t;await g(300)}return null}async function Oa(e){return Ut(await m(`snapshot_capture`,e,{backend:`android`,purpose:`alert`}))}function ka(e){return{kind:`alertStatus`,platform:`android`,action:`get`,alert:e,...fe(e?`Alert visible`:`No alert visible`)}}function Aa(e,t,n,r){return{kind:`alertHandled`,platform:`android`,action:e,handled:!0,alert:t,button:n,...r?{coordinates:r}:{},...fe(`Alert ${e}ed`)}}const ja=`android.intent.category.LAUNCHER`,Ma=`android.intent.category.DEFAULT`;async function Na(e,t){await e([`shell`,`am`,`force-stop`,t])}async function Pa(e,t,n=[ja]){for(let r of n){let n=await e([`shell`,`cmd`,`package`,`resolve-activity`,`--brief`,`-a`,`android.intent.action.MAIN`,`-c`,r,t],{allowFailure:!0});if(n.exitCode!==0)continue;let i=nt(n.stdout);if(i)return i}return null}async function Fa(e,n,r={}){let i=r.category??ja;if(r.activity){await e([`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,Ma,`-c`,i,`-n`,Ia(n,r.activity)]);return}let a=await e([`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,Ma,`-c`,i,`-p`,n],{allowFailure:!0});if(a.exitCode===0&&!rt(a.stdout,a.stderr))return;let o=await Pa(e,n,[i]);if(!o)throw new t(`COMMAND_FAILED`,`Failed to resolve Android launch component for ${n}`,{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});await e([`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,Ma,`-c`,i,`-n`,o])}function Ia(e,t){return t.includes(`/`)?t:`${e}/${t.startsWith(`.`)?t:`.${t}`}`}let La=null;function Ra(e){return`${e.PATH??``}::${e.AGENT_DEVICE_BUNDLETOOL_JAR??``}`}async function za(e){let n=Ra(e);if(La?.key===n)return La.invocation;if(await xe(`bundletool`)){let e={cmd:`bundletool`,prefixArgs:[]};return La={key:n,invocation:e},e}let r=await Ce(e.AGENT_DEVICE_BUNDLETOOL_JAR,`AGENT_DEVICE_BUNDLETOOL_JAR`);if(!r)throw new t(`TOOL_MISSING`,`bundletool not found in PATH. Install bundletool or set AGENT_DEVICE_BUNDLETOOL_JAR to a bundletool-all.jar path.`);let i={cmd:`java`,prefixArgs:[`-jar`,r]};return La={key:n,invocation:i},i}async function Ba(e,t,n){let r=await za(n);await be(r.cmd,[...r.prefixArgs,...e],{signal:t})}function Va(e){return w.extname(e).toLowerCase()===`.aab`}async function Ha(e,t,n={}){let r=S(e),i=`universal`;if(r.installBundle){await r.installBundle(t,{mode:i,signal:n.signal});return}let a=y().files,o=await a.makeTempDirectory(`agent-device-aab-`),s=w.join(o,`bundle.apks`);try{await Ba([`build-apks`,`--bundle`,t,`--output`,s,`--mode`,i],n.signal,n.environment??y().environment),await Ba([`install-apks`,`--apks`,s,`--device-id`,e.id],n.signal,n.environment??y().environment)}finally{await a.remove(o,{recursive:!0,force:!0})}}async function Ua(e,t,n={}){if(Va(t)){await Ha(e,t,n);return}await He(t,{device:e,replace:!0,signal:n.signal})}async function Wa(e,t,n={}){await st(e,async()=>{e.booted||await Qe(e.id,void 0,n.signal),await Ua(e,t,n)})}const Ga=[`mInputShown`,`mIsInputViewShown`,`isInputViewShown`,`mDecorViewVisible`,`mWindowVisible`,`mInShowWindow`],Ka=new Map([[2,`number`],[3,`phone`],[4,`datetime`]]),qa=new Set([32,208]),Ja=new Set([128,224,144]);async function V(e){return await H(x(e))}async function H(e){let t=await e([`shell`,`dumpsys`,`input_method`],{allowFailure:!0});if(t.exitCode!==0)throw b(`Failed to query Android keyboard state`,t);return Za(t.stdout)}async function Ya(e){return await Xa(x(e))}async function Xa(e){let n=await H(e),r=n,i=0;for(;r.visible&&i<2;)await e([`shell`,`input`,`keyevent`,`111`]),i+=1,await g(120),r=await H(e);if(n.visible&&r.visible)throw new t(`UNSUPPORTED_OPERATION`,`Android keyboard dismiss is unavailable for the current IME without back navigation.`,{attempts:i,inputType:r.inputType,type:r.type,inputMethodPackage:r.inputMethodPackage,focusedPackage:r.focusedPackage,focusedResourceId:r.focusedResourceId,inputOwner:r.inputOwner});return{attempts:i,wasVisible:n.visible,dismissed:n.visible&&!r.visible,visible:r.visible,inputType:r.inputType,type:r.type,inputMethodPackage:r.inputMethodPackage,focusedPackage:r.focusedPackage,focusedResourceId:r.focusedResourceId,inputOwner:r.inputOwner}}function Za(e){let t=no(e)??Qa(e),n=$a(e),r=eo(e,/\bpackageName=([A-Za-z0-9_.]+)\b/g),i=eo(e,/\b(?:resourceId|resource-id)=([^\s,}]+)/g),a=f(e),o=ee(r,i,a);return to(r,i,a),{visible:t??!1,inputType:n,type:n?oo(n):void 0,inputMethodPackage:a,focusedPackage:r,focusedResourceId:i,inputOwner:o}}function Qa(e){let t=e.match(/\bmImeWindowVis=0x([0-9a-fA-F]+)\b/)?.[1];if(!t)return null;let n=Number.parseInt(t,16);return Number.isNaN(n)?null:!!(n&1)}function $a(e){let t=eo(e,/\binputType=0x([0-9a-fA-F]+)\b/gi);return t?`0x${t.toLowerCase()}`:void 0}function eo(e,t){let n;for(let r of e.matchAll(t))n=r[1];return n}function to(e,t,n){n||!u(e)&&!c(t)||h({level:`warn`,phase:`android_input_ownership_fallback`,data:{focusedPackage:e,focusedResourceId:t}})}function no(e){return io(ro(e,Ga))}function ro(e,t){let n=new Map,r=RegExp(`\\b(${t.join(`|`)})=([a-zA-Z]+)\\b`,`g`);for(let t of e.matchAll(r)){let e=t[1],r=t[2]?.toLowerCase();!e||r!==`true`&&r!==`false`||n.set(e,r===`true`)}return n}function io(e){if(e.size===0)return null;let t=ao(e,[`mWindowVisible`,`mDecorViewVisible`,`mInShowWindow`]);if(t!==void 0)return t;let n=e.get(`mInputShown`);return n===void 0?ao(e,[`mIsInputViewShown`,`isInputViewShown`])??null:n}function ao(e,t){for(let n of t){let t=e.get(n);if(t!==void 0)return t}}function oo(e){let t=Number.parseInt(e.replace(/^0x/i,``),16);if(Number.isNaN(t))return`unknown`;let n=t&15,r=Ka.get(n);if(r)return r;if(n!==1)return`unknown`;let i=t&4080;return qa.has(i)?`email`:Ja.has(i)?`password`:`text`}async function so(e){return await co(x(e))}async function co(e){return po(await fo(e,[`shell`,`cmd`,`clipboard`,`get`,`text`],`read`))}async function lo(e,t){await uo(x(e),t)}async function uo(e,t){await fo(e,[`shell`,`cmd`,`clipboard`,`set`,`text`,Te(t)],`write`)}async function fo(e,n,r){let i=await e(n,{allowFailure:!0});if(i.exitCode===0)return i.stdout;throw We(i.stdout,i.stderr)?new t(`UNSUPPORTED_OPERATION`,`Android shell clipboard ${r} is not supported on this device.`):b(`Failed to ${r} Android clipboard text`,i)}function po(e){let t=e.replaceAll(`\r
9
9
  `,`
10
- `).replace(/\n$/,``),n=t.match(/^clipboard text:\s*(.*)$/i);return n?n[1]??``:t.trim().toLowerCase()===`null`?``:t}const Qa=`com.callstack.agentdevice.imehelper`,$a=`android-ime-helper-v1`;async function eo(e){return e.imeHelperArtifact??await to()}async function to(){return await y().resolveHelperArtifact({helperDirName:`ime-helper`,manifestFileName:e=>`agent-device-android-ime-helper-${e}.manifest.json`,parseManifest:no,unavailableMessage:`Android test IME text entry requires the bundled Android IME helper artifact, but it was not found or could not be read`})}const z=`IME helper`;function no(e){if(!e||typeof e!=`object`||Array.isArray(e))throw new t(`INVALID_ARGS`,`Android IME helper manifest must be an object.`);let n=e;return{name:D(n.name,`name`,`android-ime-helper`,z),version:ln(n.version,`version`,z),assetName:ln(n.assetName,`assetName`,z),sha256:un(n.sha256,z),packageName:D(n.packageName,`packageName`,Qa,z),versionCode:cn(n.versionCode,`versionCode`,z),serviceComponent:D(n.serviceComponent,`serviceComponent`,`com.callstack.agentdevice.imehelper/.TestInputMethodService`,z),broadcastProtocol:D(n.broadcastProtocol,`broadcastProtocol`,$a,z)}}const ro=new Set;async function io(e){return await y().ensureHelperInstalled({cache:ro,installTimeoutMs:3e4,helperLabel:`Android IME helper`},e)}function ao(){ro.clear()}function B(e){return`${e.platform}:${e.id}`}function oo(e){return e===Qa}async function so(e,t,n){await lo(e,t,`com.callstack.agentdevice.imehelper.ACTION_INPUT_TEXT_B64`,{text:Buffer.from(n,`utf8`).toString(`base64`)})}async function co(e,t){await lo(e,t,`com.callstack.agentdevice.imehelper.ACTION_CLEAR_TEXT`,{})}async function lo(e,t,n,r){let i=[`shell`,`am`,`broadcast`,`-p`,t,`-a`,n];i.push(`--es`,`protocol`,$a);for(let[e,t]of Object.entries(r))i.push(`--es`,e,t);let a=await e(i,{allowFailure:!0,timeoutMs:1e4});if(a.exitCode!==0)throw b(`Android IME helper broadcast failed`,a,{action:n,packageName:t})}const V=`agent_device_ime_helper_previous_ime`,H=`secure`,uo=`default_input_method`,fo={previousIme:V,defaultInputMethod:uo};async function U(e){let t=await e([`shell`,`settings`,`get`,H,uo],{allowFailure:!0,timeoutMs:5e3});return _o(t.exitCode===0?t.stdout:``)}async function W(e){let t=await e([`shell`,`settings`,`get`,H,V],{allowFailure:!0,timeoutMs:5e3});return _o(t.exitCode===0?t.stdout:``)||void 0}async function po(e,t){return(await e([`shell`,`settings`,`put`,H,V,t],{allowFailure:!0,timeoutMs:5e3})).exitCode===0&&await W(e)===t}async function mo(e){await e([`shell`,`settings`,`delete`,H,V],{allowFailure:!0,timeoutMs:5e3})}async function ho(e,t,r){try{(t?await po(e,t):await go(e))||v({level:`warn`,phase:`android_test_ime_record_rollback_failed`,data:{device:r,hadPriorRecord:t!==void 0}})}catch(e){v({level:`warn`,phase:`android_test_ime_record_rollback_failed`,data:{device:r,hadPriorRecord:t!==void 0,error:n(e).message}})}}async function go(e){return await mo(e),await W(e)===void 0}function _o(e){let t=e.trim();return!t||t===`null`?``:t}const G=new Set,vo=new Map;function yo(e){return G.has(B(e))}function bo(e,t,n){return xt(vo,`${e}:${t}`,n)}function xo(){G.clear()}function So(e,t){let n=B(e);t?G.add(n):G.delete(n)}async function Co(e,t){return await bo(t.stateDir,e.id,async()=>{let n=B(e);if(!G.has(n))return{restored:!1,reason:`no-record`};G.delete(n);let r=await To(x(e),e);return wo(r.reason)&&await y().imeRecoveryMarkers.clear(t.stateDir,e.id),r})}function wo(e){return e===`ok`||e===`helper-not-active`||e===`no-record`}async function To(e,t){let n=t.id;if(G.has(B(t)))return{restored:!1,reason:`owned-by-live-session`};let r=await W(e);if(!r)return{restored:!1,reason:`no-record`};let i=await U(e);if(i!==`com.callstack.agentdevice.imehelper/.TestInputMethodService`)return v({level:`debug`,phase:`android_test_ime_restore_skipped`,data:{device:n,currentIme:i,previousIme:r}}),{restored:!1,previousIme:r,reason:`helper-not-active`};await e([`shell`,`ime`,`set`,r],{allowFailure:!0,timeoutMs:1e4});let a=await U(e);return a===r?(await mo(e).catch(()=>{}),v({phase:`android_test_ime_restored`,data:{device:n,previousIme:r}}),{restored:!0,previousIme:r,reason:`ok`}):(v({level:`warn`,phase:`android_test_ime_restore_failed`,data:{device:n,previousIme:r,afterIme:a}}),{restored:!1,previousIme:r,reason:`set-failed`})}async function Eo(e){let t=y().imeRecoveryMarkers,r=await t.read(e.stateDir);if(r.length===0)return;let i;try{i=new Set(await e.listSerials())}catch(e){v({level:`debug`,phase:`android_test_ime_startup_scan_failed`,data:{error:n(e).message}});return}for(let a of r){if(!i.has(a))continue;let r={platform:`android`,id:a,name:a,kind:a.startsWith(`emulator-`)?`emulator`:`device`,booted:!0};try{await bo(e.stateDir,a,async()=>{let n=await To(x(r),r);n.restored&&v({level:`warn`,phase:`android_test_ime_orphan_restored`,data:{device:a,previousIme:n.previousIme}}),wo(n.reason)&&await t.clear(e.stateDir,a)})}catch(e){v({level:`debug`,phase:`android_test_ime_orphan_restore_failed`,data:{device:a,error:n(e).message}})}}}async function Do(){y();try{return(await je([`devices`],{timeoutMs:5e3})).stdout.split(`
11
- `).map(e=>e.trim()).filter(e=>e.length>0&&!e.startsWith(`List of devices`)).map(e=>e.split(/\s+/)).filter(e=>e[1]===`device`).map(e=>e[0])}catch{return[]}}const Oo=2e3;async function ko(e=y().environment,t=y().files){let n=e.ANDROID_HOME||e.ANDROID_SDK_ROOT,r=await Vo(n,t),i=await bt(`adb`,[`version`]);return i?Lo({license:r,sdkRoot:n,versionLine:i}):Bo(n,r)}async function Ao(e,t){if(e.platform!==`android`)return[];let n=x(e,t.transportOverrides.androidAdb),r=[];return t.shouldProbeMetro&&r.push(await Io(n,e.id,t.metroPort)),r.push(await jo(n,e)),r}async function jo(e,t){try{let n=await U(e),r=yo(t);return n===await Mo()&&!r?await No(e,t,n):Po(t,n,r)}catch(e){return Fo(e)}}async function Mo(){try{return(await to()).manifest.serviceComponent}catch{return}}async function No(e,t,n){let r=(await e([`shell`,`settings`,`get`,`secure`,fo.previousIme],{allowFailure:!0,timeoutMs:Oo})).stdout.trim(),i=r&&r!==`null`?r:void 0;return{id:`android-test-ime`,status:`fail`,summary:`Android test IME helper is the active input method on ${t.id}, but no active session owns it -- likely left over from a crashed session.`,hint:`A stuck test IME leaves the real keyboard unavailable on this device until restored.`,command:i?`adb -s ${t.id} shell ime set ${i}`:`adb -s ${t.id} shell ime list -s`,evidence:{currentIme:n,previousIme:i}}}function Po(e,t,n){return{id:`android-test-ime`,status:`pass`,summary:n?`Android test IME helper is active for this session on ${e.id}.`:`Android test IME helper is not active on ${e.id}; the device's normal IME is in use.`,evidence:{currentIme:t}}}function Fo(e){let t=n(e);return{id:`android-test-ime`,status:`warn`,summary:`Could not inspect the Android test IME helper state.`,hint:t.message,evidence:{code:t.code}}}async function Io(e,t,r){try{let n=await e([`reverse`,`--list`],{allowFailure:!0,timeoutMs:Oo}),i=`tcp:${r} tcp:${r}`,a=n.stdout.includes(i);return{id:`android-reverse`,status:a?`pass`:`warn`,summary:a?`Android adb reverse exists for Metro port ${r}.`:`Android adb reverse is missing for Metro port ${r}.`,command:a?void 0:`adb -s ${t} reverse tcp:${r} tcp:${r}`,evidence:{stdout:n.stdout.trim()}}}catch(e){let t=n(e);return{id:`android-reverse`,status:`warn`,summary:`Could not inspect Android adb reverse mappings.`,hint:t.message,evidence:{code:t.code}}}}function Lo(e){return{id:`toolchain`,status:Ro(e),summary:e.versionLine?`Android toolchain: ${e.versionLine}; ${zo(e.sdkRoot)}.`:`Android toolchain: adb is present but version check failed.`,hint:e.license===`missing`?`Accept Android SDK licenses before installing/building apps.`:void 0,command:e.license===`missing`?`sdkmanager --licenses`:void 0,evidence:{adbVersion:e.versionLine??null,androidHome:e.sdkRoot??null,license:e.license}}}function Ro(e){return e.versionLine&&e.sdkRoot&&e.license!==`missing`?`pass`:`info`}function zo(e){return e?`ANDROID_HOME/ANDROID_SDK_ROOT set`:`ANDROID_HOME unset`}function Bo(e,t){return{id:`toolchain`,status:`info`,summary:`Android toolchain: adb not found on PATH.`,hint:`Install Android platform-tools or add adb to PATH.`,evidence:{androidHome:e??null,license:t}}}async function Vo(e,t){if(!e)return`unknown`;try{return await t.access(w.join(e,`licenses`,`android-sdk-license`)),`accepted`}catch{return`missing`}}function Ho(e,t){if(!t)return{expected:e,actual:null,failureReason:`text_mismatch`,targetInput:null,actualInput:null};let n=Ko(t),r={failureReason:t.reason??`text_mismatch`,targetInput:Wo(t.targetInput),actualInput:Wo(t.actualInput)};return n?{...r,expectedLength:Array.from(e).length,actual:null,masked:!0,actualLength:Array.from(t.actual??``).length}:{...r,expected:e,actual:t.actual}}function K(e){return e?e.password?!0:Uo(e.text):!1}function Uo(e){return e?Array.from(e).every(Go):!1}function Wo(e){if(!e)return null;let t=K(e);return{...e,text:t?null:e.text,...t?{textRedacted:!0}:{}}}function Go(e){return e===`•`||e===`*`||e===`●`}function Ko(e){return e.masked===!0||K(e.targetInput)||K(e.actualInput)}const qo=new WeakMap;function Jo(e,t){return t&&qo.set(e,t),e}function Yo(e){return qo.get(e)}function Xo(e){return e.clickable}function Zo(e){return e.focusable||e.focused===!0}function q(e){return Xo(e)||Zo(e)}function Qo(e){let t=e.trim();return t?/^[\w.]+:id\/[\w.-]+$/i.test(t):!1}function $o(e,t){return{raw:e,...t?{effectiveRect:t}:{}}}function es(e,t,n){if(!e)return;let r=rs(e);return t&&(r=ns(r,t)),n&&(r=ns(r,n)),r}function ts(e){return{...e.raw,...e.effectiveRect?{rect:e.effectiveRect}:{rect:void 0},hittable:e.raw.hittable===!0&&ae(e.effectiveRect)?!0:void 0}}function ns(e,t){let n=Math.max(e.x,t.x),r=Math.max(e.y,t.y),i=Math.min(e.x+e.width,t.x+t.width),a=Math.min(e.y+e.height,t.y+t.height),o=i>n&&a>r;return{x:o?n:e.x,y:o?r:e.y,width:o?i-n:0,height:o?a-r:0}}function rs(e){return{x:e.x,y:e.y,width:Math.max(0,e.width),height:Math.max(0,e.height)}}function is(e,t){let n=new Set;return as(e,n,t),ss(e,n,t),n}function as(e,t,n){for(let r of e.children){if(n?.check(`work`),r.visibleToUser===!1){t.add(r);continue}as(r,t,n)}}function os(e,t,n){return n?.check(`work`),e.children.filter(e=>!t.has(e)&&e.visibleToUser!==!1)}function ss(e,t,n){let r=os(e,t,n).filter(ls);if(r.length<2)return;let i=r.filter(e=>us(e)&&ds(e));if(i.length===0)return;let a=cs(i);for(let r of os(e,t,n))n?.check(`work`),us(r)&&(ds(r)&&(a===void 0||r.windowLayer===a)||t.add(r))}function cs(e){let t=e.map(e=>e.windowLayer).filter(e=>e!==void 0);return t.length>0?Math.max(...t):void 0}function ls(e){return e.windowIndex!==void 0||e.windowType!==void 0}function us(e){return e.windowType===1}function ds(e){return e.windowActive===!0||e.windowFocused===!0}function fs(e,t,n,r,i){let a=new Set(e.sourceNodes),o=ms(t,i),s=ps(o,n,hs(o,a,i),i);if(!s)return{nodes:[],sourceNodes:[]};let c=new Set(ms([s],i)),l=[];for(let[t,n]of e.sourceNodes.entries())i.check(`work`),c.has(n)&&l.push(t);if(l.length===0)return{nodes:[],sourceNodes:[]};let u=1/0;for(let t of l)i.check(`work`),u=Math.min(u,e.nodes[t]?.depth??0);let d=[];for(let t of l)i.check(`work`),(e.nodes[t]?.depth??0)-u<=r&&d.push(t);return i.consume(d.length),{nodes:oe(d.map(t=>e.nodes[t]),u),sourceNodes:d.map(t=>e.sourceNodes[t])}}function ps(e,t,n,r){for(let i of e)if(r.check(`work`),se(i,t)&&n.has(i))return i;return null}function ms(e,t){let n=[],r=[...e].reverse();for(;r.length>0;){t.check(`work`);let e=r.pop();n.push(e);for(let n=e.children.length-1;n>=0;--n)t.check(`work`),r.push(e.children[n])}return n}function hs(e,t,n){let r=new Set;for(let i=e.length-1;i>=0;--i){n.check(`work`);let a=e[i];if(t.has(a)){r.add(a);continue}for(let e of a.children)if(n.check(`work`),r.has(e)){r.add(a);break}}return r}function gs(e,t,n,r,i){if(e.visibleToUser===!1)return!1;let a=_s(e);return t.interactiveOnly?vs(e,a,n,r,i):a.isStructural||a.isVisual?xs(e,a,r):!0}function _s(e){let t=Cs(e.type),n=!!(e.label&&e.label.trim().length>0),r=!!(e.identifier&&e.identifier.trim().length>0);return{type:t,hasMeaningfulText:n&&!Qo(e.label??``),hasMeaningfulId:r&&!Qo(e.identifier??``),isStructural:ws(t),isVisual:t===`imageview`||t===`imagebutton`}}function vs(e,t,n,r,i){return bs(e)?!1:q(e)||ne(t.type)&&r?!0:ys(t,n,r,i)}function ys(e,t,n,r){return!e.hasMeaningfulText&&!e.hasMeaningfulId||e.isVisual||e.isStructural&&!r&&!t?!1:t||n||r}function bs(e){return!!(e.rect&&(e.rect.width<=0||e.rect.height<=0))}function xs(e,t,n){return q(e)||t.hasMeaningfulText||t.hasMeaningfulId?!0:n}function Ss(e){if(!e)return!1;let t=Cs(e);return t.includes(`recyclerview`)||t.includes(`listview`)||t.includes(`gridview`)}function Cs(e){return e?e.toLowerCase():``}function ws(e){let t=e.split(`.`).pop()??e;return t.includes(`layout`)||t===`viewgroup`||t===`view`}function Ts(e,t,n,r){return{...$o(e,t),...n?{clipsDescendants:!0}:{},...r?{windowRect:r}:{}}}const Es=`ANDROID_SNAPSHOT_PRESENTATION_FAILED`;var J=class extends Error{code=Es;qualityReasonCode=`presentation-failed`;details;analysis;constructor(e,t,n){super(e),this.name=`AndroidSnapshotPresentationFailure`,this.details=t,this.analysis=n}};function Ds(e){return e instanceof J?e.code===Es:!!(e&&typeof e==`object`&&e.code===Es)}var Os=class{workUnits=0;options;defaultMaxWorkUnits;deadlineAtMs;constructor(e,t){this.options=e,this.defaultMaxWorkUnits=t;let n=e.now??Date.now;this.deadlineAtMs=e.deadlineAtMs??n()+Ns()}get workUnitCount(){return this.workUnits}check(e){this.consume(1)}consume(e){this.workUnits+=e;let t=this.options.maxWorkUnits??this.defaultMaxWorkUnits;if(this.workUnits>t)throw new J(`Android snapshot presentation exceeded its linear work budget`,{phase:`complexity`,workUnits:this.workUnits,maxWorkUnits:t});if((this.options.now??Date.now)()>=this.deadlineAtMs)throw new J(`Android snapshot presentation exceeded its cooperative deadline`,{phase:`deadline`,workUnits:this.workUnits,deadlineAtMs:this.deadlineAtMs,maxWorkUnits:t})}};function ks(e,t){return new Os(e??{},t)}function As(e,t,n){let r=new Map;for(let i of e){n.check(`regular-invariant`);let e=js(i,r,t),a=i.effectiveRect;if(!a||!ae(a)){if(ts(i).hittable===!0)throw new J(`Android regular snapshot node ${i.raw.index} with degenerate effective geometry was marked hittable`,{phase:`regular-invariant`,workUnits:n.workUnitCount,nodeIndex:i.raw.index,frame:a});r.set(i.raw.index,e);continue}if(e&&!Ms(a,e))throw new J(`Android regular snapshot node ${i.raw.index} escaped its cumulative clip`,{phase:`regular-invariant`,workUnits:n.workUnitCount,nodeIndex:i.raw.index,frame:a,clip:e});r.set(i.raw.index,i.clipsDescendants?a:e)}}function js(e,t,n){let r=e.raw.parentIndex;return r===void 0?e.windowRect??n:t.get(r)??e.windowRect??n}function Ms(e,t){let n=1e-4;return e.x>=t.x-n&&e.y>=t.y-n&&e.x+e.width<=t.x+t.width+n&&e.y+e.height<=t.y+t.height+n}function Ns(){return 250}function Ps(e,t,n){let r=n.depth??1/0,i=ce(n.scope),a=Qs(e),o=ks(n.androidPresentation,Math.max(1024,a.rawNodeCount*128)),s={nodes:[],sourceNodes:[],...t===void 0?{}:{maxNodes:t},maxDepth:i?1/0:r,options:n,analysis:a,interactiveDescendantMemo:new Map,hidden:new Set,presentationBudget:o,presentationNodes:[],truncated:!1};try{o.check(`work`),s.viewport=Gs(e,o),s.hidden=n.raw?new Set:is(e,o);for(let t of e.children)if(Is(s,t,0),s.truncated)break;n.raw||As(s.presentationNodes,s.viewport,o);let t=s.nodes,a=new Map(s.sourceNodes.map((e,t)=>[e,t])),{nodes:c,sourceNodes:l}=i?fs(s,e.children,i,r,o):s,u={nodes:c,sourceNodes:l,occlusionContext:{nodes:t,sourceIndexByNodeIndex:new Map(l.flatMap((e,t)=>{let n=a.get(e),r=c[t]?.index;return n===void 0||r===void 0?[]:[[r,n]]})),androidSiblingOrderByNodeIndex:Fs(s.sourceNodes)},analysis:s.analysis};return s.truncated?{...u,truncated:!0}:u}catch(e){throw Ds(e)&&(e.analysis??=s.analysis),e}}function Fs(e){let t=new Map,n=new Map;for(let[r,i]of e.entries()){let e=Yo(i);if(!e)continue;let a=t.get(e.parent);a===void 0&&(a=t.size,t.set(e.parent,a)),n.set(r,{group:a,order:e.order})}return n}function Is(e,t,n,r,i=!1,a=!1,o=!1,s,c){if(e.presentationBudget.check(`work`),Ls(e,t,n))return;let l=t.windowRect??s??e.viewport,u=Rs(e,t,c,l),d=zs(e,t,r,i,a,o,u,l),f=i||q(t),p=a||Ss(t.type),ee=Bs(e,t,u,c);Vs(e,t,n,d,f,p,o||Je(t.identifier),l,ee)}function Ls(e,t,n){return e.maxNodes!==void 0&&e.nodes.length>=e.maxNodes?(e.truncated=!0,!0):n>e.maxDepth||e.hidden.has(t)}function Rs(e,t,n,r){return e.options.raw?t.rect:es(t.rect,r,n)}function zs(e,t,n,r,i,a,o,s){return!e.options.raw&&!gs(t,e.options,r,Js(e,t),i)?n:Hs(e,t,n,a||Je(t.identifier),o,s)}function Bs(e,t,n,r){return e.options.raw||!Ks(t)?r:n}function Vs(e,t,n,r,i,a,o,s,c){for(let l of t.children)if(Is(e,l,n+1,r,i,a,o,s,c),e.truncated)return}function Hs(e,t,n,r,i,a){let o=e.nodes.length;return e.sourceNodes.push(t),Ws(e,t,Us(e,t,n,r),i,a),o}function Us(e,t,n,r){return{index:e.nodes.length,type:t.type??void 0,label:t.label??void 0,value:t.value??void 0,identifier:t.identifier??void 0,bundleId:t.packageName??void 0,rect:t.rect,enabled:t.enabled,focused:t.focused,selected:t.selected,editable:t.editable,password:t.password,hintShowing:t.hintShowing,selectionStart:t.selectionStart,selectionEnd:t.selectionEnd,visibleToUser:t.visibleToUser,hittable:q(t)||void 0,depth:qs(e.nodes,n),parentIndex:n,...Ys(t,e.hidden),...r?{systemChrome:!0}:{}}}function Ws(e,t,n,r,i){let a=Ts(n,r,!e.options.raw&&Ks(t),i);e.presentationNodes.push(a),e.nodes.push(e.options.raw?a.raw:ts(a))}function Gs(e,t){let n=[],r=[...e.children];for(;r.length>0;){t.check(`work`);let e=r.pop();ae(e.windowRect)&&n.push(e.windowRect),r.push(...e.children)}return ie(n)??void 0}function Ks(e){return e.scrollable===!0&&ne(e.type)}function qs(e,t){return t===void 0?0:(e[t]?.depth??-1)+1}function Js(e,t){let n=e.interactiveDescendantMemo.get(t);if(n!==void 0)return n;for(let n of t.children)if(!e.hidden.has(n)&&n.visibleToUser!==!1&&(q(n)||Js(e,n)))return e.interactiveDescendantMemo.set(t,!0),!0;return e.interactiveDescendantMemo.set(t,!1),!1}function Ys(e,t){return Xs(e,t)?{...e.canScrollBackward?{hiddenContentAbove:!0}:{},...e.canScrollForward?{hiddenContentBelow:!0}:{}}:{}}function Xs(e,t){if(!e.scrollable||!ne(e.type)||`${e.type??``}`.toLowerCase().includes(`horizontalscrollview`))return!1;let n=Zs(e,t);return!(n&&n.horizontal>n.vertical&&n.horizontal>16)}function Zs(e,t){let n=e.children.filter(e=>!t.has(e)&&e.visibleToUser!==!1);if(!e.rect||n.length===0)return null;let r=n.map(e=>e.rect).filter(e=>e!==void 0);if(r.length===0)return null;let i=Math.min(...r.map(e=>e.x)),a=Math.max(...r.map(e=>e.x+e.width)),o=Math.min(...r.map(e=>e.y)),s=Math.max(...r.map(e=>e.y+e.height));return{horizontal:Math.max(0,a-i-e.rect.width),vertical:Math.max(0,s-o-e.rect.height)}}function Qs(e){let t=0,n=0,r=[...e.children];for(;r.length>0;){let e=r.pop();t+=1,n=Math.max(n,e.depth),r.push(...e.children)}return{rawNodeCount:t,maxDepth:n}}function $s(){let e=[],t=()=>e.at(-1)===!0;return{open(n,r){let i=t()||Je(n);return r||e.push(i),i},close(){e.pop()}}}function*ec(e){let t=/<node\b[^>]*>|<\/node>/g,n=$s(),r=t.exec(e);for(;r;){let i=r[0];if(i.startsWith(`</node`))n.close();else{let e=tc(i);yield n.open(e.resourceId,i.endsWith(`/>`))?{...e,systemChrome:!0}:e}r=t.exec(e)}}function tc(e){let t=nc(e),n=St(t.bounds);return{...t,...n?{rect:n}:{}}}function nc(e){let t=rc(e),n=e=>dc(t,e),r=e=>{let t=n(e);if(t!==null)return t===`true`},i=e=>{let t=n(e);if(t===null||t.trim()===``)return;let r=Number(t);return Number.isFinite(r)?r:void 0},a=(e,t)=>{let n=i(t);return n===void 0?{}:{[e]:n}},o=(e,t)=>{let r=St(n(t));return r===void 0?{}:{[e]:r}},s=(e,t)=>{let n=r(t);return n===void 0?{}:{[e]:n}};return{text:n(`text`),desc:n(`content-desc`),resourceId:n(`resource-id`),packageName:n(`package`),className:n(`class`),bounds:n(`bounds`),clickable:r(`clickable`),enabled:r(`enabled`),focusable:r(`focusable`),focused:r(`focused`),password:r(`password`),...s(`editable`,`editable`),...a(`selectionStart`,`selection-start`),...a(`selectionEnd`,`selection-end`),...s(`hintShowing`,`hint-showing`),...s(`visibleToUser`,`visible-to-user`),...s(`selected`,`selected`),...a(`drawingOrder`,`drawing-order`),...s(`scrollable`,`scrollable`),...s(`canScrollForward`,`can-scroll-forward`),...s(`canScrollBackward`,`can-scroll-backward`),...a(`windowIndex`,`window-index`),...a(`windowType`,`window-type`),...a(`windowLayer`,`window-layer`),...s(`windowActive`,`window-active`),...s(`windowFocused`,`window-focused`),...o(`windowRect`,`window-bounds`)}}function rc(e){let t=new Map,n=e.indexOf(` `),r=e.lastIndexOf(`>`);if(n<0||r<=n)return t;let i=n;for(;i<r;){let n=ic(e,i,r);if(!n)break;t.set(n.name,n.value),i=n.nextCursor}return t}function ic(e,t,n){if(t=oc(e,t,n),t>=n||sc(e[t]))return;let r=t;t=ac(e,t,n);let i=e.slice(r,t);if(t=oc(e,t,n),!i||e[t]!==`=`)return;t=oc(e,t+1,n);let a=e[t];if(!cc(a))return;let o=t+1,s=e.indexOf(a,o);if(!(s<0||s>=n))return{name:i,value:Ct(e.slice(o,s)),nextCursor:s+1}}function ac(e,t,n){for(;t<n&&!uc(e[t]??``);)t+=1;return t}function oc(e,t,n){for(;t<n&&lc(e[t]??``);)t+=1;return t}function sc(e){return e===`/`||e===`>`}function cc(e){return e===`"`||e===`'`}function lc(e){return e===` `||e===`
12
- `||e===`\r`||e===` `}function uc(e){return e===`=`||e===`/`||e===`>`||lc(e)}function dc(e,t){return e.get(t)??null}function fc(e){let t={type:null,label:null,value:null,identifier:null,packageName:null,clickable:!1,focusable:!1,depth:-1,children:[]},n=[t],r=/<node\b[^>]*>|<\/node>/g,i=r.exec(e);for(;i;){let t=i[0];if(t.startsWith(`</node`)){n.length>1&&n.pop(),i=r.exec(e);continue}let a=tc(t),o=n.at(-1),s=pc(a,o.depth+1,o);o.children.push(s),t.endsWith(`/>`)||n.push(s),i=r.exec(e)}return t}function pc(e,t,n){return Jo({type:e.className,label:e.text||e.desc,value:e.text,identifier:e.resourceId,packageName:e.packageName,rect:e.rect,enabled:e.enabled,focused:e.focused,selected:e.selected,editable:e.editable,password:e.password,hintShowing:e.hintShowing,selectionStart:e.selectionStart,selectionEnd:e.selectionEnd,visibleToUser:e.visibleToUser,clickable:e.clickable===!0,focusable:e.focusable===!0,scrollable:e.scrollable,canScrollForward:e.canScrollForward,canScrollBackward:e.canScrollBackward,windowIndex:e.windowIndex,windowType:e.windowType,windowLayer:e.windowLayer,windowActive:e.windowActive,windowFocused:e.windowFocused,windowRect:e.windowRect,depth:t,parentIndex:void 0,children:[]},e.drawingOrder===void 0?void 0:{parent:n,order:e.drawingOrder})}function mc(e){let t=new Map;return e.nodes.forEach((n,r)=>{t.set(n.index,e.sourceNodes[r]?.clickable)}),{kind:`exact`,provider:`android-helper`,clickableByNodeIndex:t}}const hc=new Set([`android`,`com.android.systemui`]);function gc(e,t,n={}){if(t.backend!==`android-helper`)return{outcome:`ok`};let r=Dc(e,n.foregroundAppPackage);return yc(r,t)?_c(r,t,`empty-helper-output`,`Android snapshot helper returned no accessibility nodes`):Tc(r)?{outcome:`ok`}:vc(r)?{outcome:`system-surface-only`}:bc(r)?{outcome:`ok`}:xc(r)?_c(r,t,`content-poor-app-window`,`Android snapshot helper returned insufficient foreground app content`):Sc(r)||Cc(r,t)?_c(r,t,`content-poor-app-window`,`Android snapshot helper returned insufficient application window content`):wc(r)?_c(r,t,`system-window-only`,`Android snapshot helper returned only non-application windows`):{outcome:`ok`}}function _c(e,t,n,r){return{outcome:`unusable`,decision:Ec(e,t,n,r)}}function vc(e){return e.windowRootCount>0&&e.applicationWindowRootCount===0&&e.activeSystemSurfaceMeaningfulNodeCount>=3}function yc(e,t){return e.nodeCount===0||t.nodeCount===0||t.rootPresent===!1}function bc(e){return xc(e)&&e.inputMethodMeaningfulNodeCount>=2}function xc(e){let t=e.foregroundAppMeaningfulNodeCount;return t===void 0?!1:t===0?e.applicationMeaningfulNodeCount<2:t<2&&e.meaningfulNodeCount>t}function Sc(e){return e.foregroundAppMeaningfulNodeCount===void 0&&e.applicationWindowRootCount>0&&e.applicationMeaningfulNodeCount<2}function Cc(e,t){return e.foregroundAppMeaningfulNodeCount===void 0&&e.windowRootCount===0&&(t.windowCount??0)>1&&e.nonSystemMeaningfulNodeCount<2}function wc(e){return e.windowRootCount>0&&e.applicationWindowRootCount===0||e.windowRootCount===0&&e.nodeCount>0&&e.systemUiNodeCount===e.nodeCount}function Tc(e){return e.hasAlertButtonIdentifier&&e.hasAlertContentIdentifier}function Ec(e,t,n,r){return{reason:n,failureReason:r,diagnostics:Vc(e,t)}}function Dc(e,t){let n=Oc(t);for(let t of ec(e))kc(n,t);return Ic(n)}function Oc(e){return{nodeCount:0,systemUiNodeCount:0,windowRootCount:0,applicationWindowRootCount:0,activeSystemSurfaceMeaningfulNodeCount:0,meaningfulNodeCount:0,applicationMeaningfulNodeCount:0,nonSystemMeaningfulNodeCount:0,inputMethodMeaningfulNodeCount:0,hasAlertButtonIdentifier:!1,hasAlertContentIdentifier:!1,...e===void 0?{}:{foregroundAppPackage:e,foregroundAppMeaningfulNodeCount:0},windowTypes:new Set}}function kc(e,t){e.nodeCount+=1,Bc(t.packageName)&&(e.systemUiNodeCount+=1),t.visibleToUser!==!1&&Ac(e,t.resourceId),jc(e,t),Mc(e,t)}function Ac(e,t){let n=Bt(t);n===`button`&&(e.hasAlertButtonIdentifier=!0),n===`content`&&(e.hasAlertContentIdentifier=!0)}function jc(e,t){t.windowType!==void 0&&(e.currentWindowType=t.windowType,e.currentWindowActiveOrFocused=t.windowActive===!0||t.windowFocused===!0,e.windowRootCount+=1,e.windowTypes.add(t.windowType),t.windowType===1&&(e.applicationWindowRootCount+=1))}function Mc(e,t){Lc(t)&&(e.meaningfulNodeCount+=1,Nc(e,t),Fc(e,t))}function Nc(e,t){e.currentWindowType===1&&!zc(t.packageName)&&(e.applicationMeaningfulNodeCount+=1),Pc(e)&&!qe(t)&&(e.activeSystemSurfaceMeaningfulNodeCount+=1)}function Pc(e){return e.currentWindowType!==void 0&&e.currentWindowType!==1&&e.currentWindowActiveOrFocused===!0}function Fc(e,t){zc(t.packageName)||(e.nonSystemMeaningfulNodeCount+=1),p({packageName:t.packageName,resourceId:t.resourceId})&&(e.inputMethodMeaningfulNodeCount+=1),e.foregroundAppPackage!==void 0&&t.packageName===e.foregroundAppPackage&&(e.foregroundAppMeaningfulNodeCount=(e.foregroundAppMeaningfulNodeCount??0)+1)}function Ic(e){return{nodeCount:e.nodeCount,systemUiNodeCount:e.systemUiNodeCount,windowRootCount:e.windowRootCount,applicationWindowRootCount:e.applicationWindowRootCount,activeSystemSurfaceMeaningfulNodeCount:e.activeSystemSurfaceMeaningfulNodeCount,meaningfulNodeCount:e.meaningfulNodeCount,applicationMeaningfulNodeCount:e.applicationMeaningfulNodeCount,nonSystemMeaningfulNodeCount:e.nonSystemMeaningfulNodeCount,inputMethodMeaningfulNodeCount:e.inputMethodMeaningfulNodeCount,hasAlertButtonIdentifier:e.hasAlertButtonIdentifier,hasAlertContentIdentifier:e.hasAlertContentIdentifier,...e.foregroundAppPackage===void 0?{}:{foregroundAppPackage:e.foregroundAppPackage,foregroundAppMeaningfulNodeCount:e.foregroundAppMeaningfulNodeCount??0},windowTypes:[...e.windowTypes].sort((e,t)=>e-t).slice(0,8)}}function Lc(e){return e.visibleToUser===!1?!1:Rc(e.text)||Rc(e.desc)||Rc(e.resourceId)}function Rc(e){return e!==null&&e.trim()!==``}function zc(e){return e===null||hc.has(e)}function Bc(e){return e!==null&&hc.has(e)}function Vc(e,t){return{helperNodeCount:e.nodeCount,helperSystemUiNodeCount:e.systemUiNodeCount,helperWindowRootCount:e.windowRootCount,helperApplicationWindowRootCount:e.applicationWindowRootCount,helperMeaningfulNodeCount:e.meaningfulNodeCount,helperApplicationMeaningfulNodeCount:e.applicationMeaningfulNodeCount,helperNonSystemMeaningfulNodeCount:e.nonSystemMeaningfulNodeCount,helperInputMethodMeaningfulNodeCount:e.inputMethodMeaningfulNodeCount,...e.foregroundAppPackage===void 0?{}:{helperForegroundAppPackage:e.foregroundAppPackage,helperForegroundAppMeaningfulNodeCount:e.foregroundAppMeaningfulNodeCount,helperForegroundAppMeaningfulNodeThreshold:2},helperWindowTypes:e.windowTypes,...t.captureMode?{helperCaptureMode:t.captureMode}:{}}}async function Hc(e){let t=await L(e.deviceKey,{resetRuntime:!0,signal:e.signal,cause:e.cause});e.signal?.throwIfAborted(),t||await Uc(e.adb,e.packageName)}async function Uc(e,t){try{await e([`shell`,`am`,`force-stop`,t],{allowFailure:!0,timeoutMs:2e3}),await g(150),h({level:`debug`,phase:`android_snapshot_helper_runtime_reset`,data:{packageName:t}})}catch(e){h({level:`warn`,phase:`android_snapshot_helper_runtime_reset_failed`,data:{packageName:t,error:n(e).message}})}}const Wc=Symbol(`androidSnapshotCaptureEvidence`);function Gc(e,t){return Object.defineProperty(e,Wc,{value:t}),e}function Kc(e){let t={...e,backend:`android`,producer:`android-uiautomator`},n=e[Wc];return te(t,n.clickability),n.occlusionContext&&l(t,n.occlusionContext),t}async function qc(e,t={}){let n=S(e,t.helperAdb).exec;return(await tl(e,t,n)).xml}async function Jc(e,t={}){let n=S(e,t.helperAdb).exec,r=await tl(e,t,n),i=r.xml,a=fc(i),o=Zc(r.metadata,a),s={...t,androidPresentation:{...t.androidPresentation,deadlineAtMs:t.androidPresentation?.deadlineAtMs??Date.now()+250}};try{let e=Ps(a,void 0,s),n=Xc(e.truncated,r.metadata);t.interactiveOnly&&t.includeHiddenContentHints!==!1&&el({options:s,tree:a,xml:i,interactiveSnapshot:e});let{sourceNodes:c,occlusionContext:l,...u}=e;return Gc({...u,...$c(n),androidSnapshot:o,quality:{state:`healthy`,backend:`android-helper`}},{clickability:mc(e),occlusionContext:l})}catch(e){if(!Ds(e))throw e;return Yc({failure:e,androidSnapshot:o})}}function Yc(e){return Gc({nodes:[],truncated:!0,analysis:e.failure.analysis??{rawNodeCount:0,maxDepth:0},androidSnapshot:{...e.androidSnapshot,presentationFailure:{phase:e.failure.details.phase,workUnits:e.failure.details.workUnits,...e.failure.details.maxWorkUnits===void 0?{}:{maxWorkUnits:e.failure.details.maxWorkUnits}}},quality:{state:`sparse`,backend:`android-helper`,reason:e.failure.message,reasonCode:e.failure.qualityReasonCode}},{clickability:{kind:`exact`,provider:`android-helper`,clickableByNodeIndex:new Map}})}function Xc(e,t){return e===!0||t.helperTruncated===!0||e}function Zc(e,t){return Qc(t)===!1?{...e,occlusionScanUnavailable:!0}:e}function Qc(e){let t=[...e.children];if(t.length!==0){for(;t.length>0;){let e=t.pop();if(Yo(e)!==void 0)return!0;t.push(...e.children)}return!1}}function $c(e){return e===!0?{truncated:!0}:{}}function el(e){if(yl(e.interactiveSnapshot.nodes).size>0||vl(e.xml))return;let t=Ps(e.tree,void 0,{...e.options,interactiveOnly:!1});bl(_e(i(t.nodes)),t,e.interactiveSnapshot)}async function tl(e,t,n){let r=S(e,t.helperAdb),i=await m(`android_snapshot_helper_artifact_resolution`,async()=>await gl(t.helperArtifact??r.snapshotHelperArtifact));if(i.artifact)return await nl(e,t,n,i.artifact);throw h({level:`error`,phase:`android_snapshot_helper_unavailable`,data:{reason:i.errorReason??`artifact_not_found`}}),_l(i.errorReason)}async function nl(e,t,n,r){let i=Cr(e),a=S(e,t.helperAdb),o=t.helperSessionScope!==`daemon-session`;try{let e;for(let o=0;;o+=1){o>0&&await sl(t.signal);let s=await ol({options:t,adb:n,adbProvider:a,artifact:r,helperDeviceKey:i,attempt:o,previousContentReason:e});if(s.outcome===`captured`)return s.capture;if(o+1>=3)return await cl({contentRecovery:s.decision,attempts:o+1,helperDeviceKey:i,artifact:r,adb:n,signal:t.signal});e=s.decision.reason}}finally{o&&await L(i)}}async function rl(e,t,n,r,i){let a=await m(`android_snapshot_helper_install`,async()=>await Zn({adb:t,adbProvider:n,artifact:r,deviceKey:i,installPolicy:e.helperInstallPolicy,timeoutMs:3e4,signal:e.signal}),{packageName:r.manifest.packageName,versionCode:r.manifest.versionCode,installPolicy:e.helperInstallPolicy??`missing-or-outdated`});return h({phase:`android_snapshot_helper_install_decision`,data:{packageName:a.packageName,versionCode:a.versionCode,installedVersionCode:a.installedVersionCode,artifactSha256:r.manifest.sha256,installedSha256:a.installedSha256,installed:a.installed,reason:a.reason}}),a}async function il(e){let{signal:t,adb:r,adbProvider:i,artifact:a,helperDeviceKey:o}=e,s=Ir({adb:r,adbProvider:i,artifact:a,deviceKey:o,signal:t});try{let e=await m(`android_snapshot_helper_session_capture`,async()=>await _i(s),{packageName:a.manifest.packageName,version:a.manifest.version,timeoutMs:jn});if(e)return e}catch(e){if(t?.throwIfAborted(),Er(e))throw e;h({level:`warn`,phase:`android_snapshot_helper_session_fallback`,data:{reason:n(e).message}}),await Uc(r,a.manifest.packageName)}return await m(`android_snapshot_helper_capture`,async()=>await Fr(s),{packageName:a.manifest.packageName,version:a.manifest.version,timeoutMs:jn,commandTimeoutMs:Mn})}function al(e,t,n){return{xml:e.xml,metadata:{backend:`android-helper`,helperVersion:t.manifest.version,helperApiVersion:e.metadata.helperApiVersion,helperTransport:e.metadata.transport,helperSessionReused:e.metadata.sessionReused,installReason:n,waitForIdleTimeoutMs:e.metadata.waitForIdleTimeoutMs,waitForIdleQuietMs:e.metadata.waitForIdleQuietMs,timeoutMs:e.metadata.timeoutMs,maxDepth:e.metadata.maxDepth,maxNodes:e.metadata.maxNodes,rootPresent:e.metadata.rootPresent,captureMode:e.metadata.captureMode,windowCount:e.metadata.windowCount,nodeCount:e.metadata.nodeCount,helperTruncated:e.metadata.truncated,elapsedMs:e.metadata.elapsedMs}}}async function ol(e){let{options:t,adb:n,adbProvider:r,artifact:i,helperDeviceKey:a,attempt:o}=e,s;try{let e=await rl(t,n,r,i,a);e.installed&&await L(a),s=al(await il({signal:t.signal,adb:n,adbProvider:r,artifact:i,helperDeviceKey:a}),i,e.reason)}catch(e){return t.signal?.throwIfAborted(),{outcome:`captured`,capture:await ll({error:e,helperDeviceKey:a,artifact:i,adb:n})}}let c=gc(s.xml,s.metadata,{foregroundAppPackage:t.appBundleId});return c.outcome===`system-surface-only`?(h({phase:`android_snapshot_helper_system_surface`,data:{foregroundAppPackage:t.appBundleId}}),{outcome:`captured`,capture:{xml:s.xml,metadata:{...s.metadata,systemSurfaceOnly:!0}}}):c.outcome===`ok`?(o>0&&h({phase:`android_snapshot_helper_content_recaptured`,data:{attempts:o+1,recoveredFromReason:e.previousContentReason}}),{outcome:`captured`,capture:s}):{outcome:`unusable`,decision:c.decision}}async function sl(e){e?.throwIfAborted(),await g(250),e?.throwIfAborted()}async function cl(e){throw h({level:`error`,phase:`android_snapshot_helper_content_invalid`,data:{reason:e.contentRecovery.reason,failureReason:e.contentRecovery.failureReason,attempts:e.attempts,...e.contentRecovery.diagnostics}}),await Hc({adb:e.adb,deviceKey:e.helperDeviceKey,packageName:e.artifact.manifest.packageName,signal:e.signal,cause:e.contentRecovery.failureReason}),new t(`COMMAND_FAILED`,e.contentRecovery.failureReason,{...e.contentRecovery.diagnostics,androidSnapshotHelperFailureReason:e.contentRecovery.reason,attempts:e.attempts,retriable:!0,hint:`Retry after the app UI stabilizes. If this persists, capture a screenshot and report the helper diagnostics; agent-device does not substitute a second snapshot engine.`})}async function ll(e){let t=ul(e.error);throw h({level:`error`,phase:`android_snapshot_helper_failed`,data:{reason:t}}),await L(e.helperDeviceKey),await Uc(e.adb,e.artifact.manifest.packageName),Kn({deviceKey:e.helperDeviceKey,packageName:e.artifact.manifest.packageName,versionCode:e.artifact.manifest.versionCode}),dl(e.error,t)}function ul(e){let t=n(e),r=hl(t.details?.helper);if(r&&r!==t.message)return`${t.message}: ${r}`;if(r)return r;let i=(typeof t.details?.stderr==`string`?t.details.stderr.trim():``).split(/\r?\n/).find(e=>e.trim());return i?`${t.message}: ${i}`:t.message}function dl(e,i){let a=n(e),o=fl(a);return new t(r(a.code),`Android snapshot helper failed: ${i}`,{...a.details,...ml(a),androidSnapshotHelperFailureReason:i,...o?{androidCaptureFailureReason:o}:{},hint:pl(a,o)},e)}function fl(e){return Ye(e)}function pl(e,t){return t===`accessibility-timeout`?`Android accessibility snapshots can be blocked by busy or continuously changing app UI. Use screenshot as visual truth after this timeout and report the busy UI if it persists.`:e.details?.androidSnapshotHelperInstallFailure===!0?[e.hint,`This is a device-side install failure (adb rejection or OEM policy) — the helper artifact itself is present, this is not a missing/unbuilt build.`].filter(Boolean).join(` `):e.hint??`Retry once. If the helper still fails, run agent-device doctor and report the diagnostic log; agent-device does not substitute a second snapshot engine.`}function ml(e){let t={};return e.diagnosticId!==void 0&&(t.diagnosticId=e.diagnosticId),e.logPath!==void 0&&(t.logPath=e.logPath),e.retriable!==void 0&&(t.retriable=e.retriable),e.supportedOn!==void 0&&(t.supportedOn=e.supportedOn),t}function hl(e){if(!e||typeof e!=`object`||!(`message`in e))return;let t=String(e.message).trim();return t&&t!==`null`?t:void 0}async function gl(e){if(e)return{artifact:e};let t=De(),r=w.join(Ee(),`android`,`snapshot-helper`,`dist`),i=w.join(r,`agent-device-android-snapshot-helper-${t}.manifest.json`);try{await y().files.access(i)}catch{return{}}try{let e=A(JSON.parse(await y().files.readText(i))),t=w.join(r,e.assetName??`agent-device-android-snapshot-helper-${e.version}.apk`);return await y().files.access(t),{artifact:{apkPath:t,manifest:e}}}catch(e){return{errorReason:n(e).message}}}function _l(e){let n=e??`the bundled helper artifact was not found`;return new t(`COMMAND_FAILED`,`Android snapshot helper is unavailable: ${n}`,{androidSnapshotHelperFailureReason:n,hint:"Run `pnpm build:android` to build the helper dist for a source checkout — the runtime needs android/snapshot-helper/dist/agent-device-android-snapshot-helper-<version>.manifest.json and the .apk it references. Packaged installs ship these via the prepack script; if they are missing from a packaged install, reinstall agent-device."})}function vl(e){return e.includes(` can-scroll-forward=`)||e.includes(` can-scroll-backward=`)}function yl(e){let t=new Map;for(let n of e){let e={};n.hiddenContentAbove&&(e.hiddenContentAbove=!0),n.hiddenContentBelow&&(e.hiddenContentBelow=!0),(e.hiddenContentAbove||e.hiddenContentBelow)&&t.set(n.index,e)}return t}function bl(e,t,n){if(e.size===0)return;let r=new Map;for(let[e,t]of n.sourceNodes.entries()){let i=n.nodes[e];i&&r.set(t,i)}for(let[n,i]of e){let e=t.sourceNodes[n];if(!e)continue;let a=r.get(e);a&&(i.hiddenContentAbove&&(a.hiddenContentAbove=!0),i.hiddenContentBelow&&(a.hiddenContentBelow=!0))}}async function xl(e,t,n,r,i={}){let a=[0,150,350],o=null,s=null,c=await Bl(e);for(let l of a){l>0&&await g(l);let a=await Al(e,t,n,r,c,i);if(o=a,a.reason===`ime_capture`)return a;s=a.ok?a:null}return s??o??{ok:!1,actual:null,reason:`text_mismatch`,targetInput:null,actualInput:null}}async function Sl(e,t,n,r={}){return Dl(await qc(e,r),t,n)}async function Cl(e,t,n,r){let i=await Bl(e);return jl(await qc(e,r),t,n,i).targetInput}async function wl(e,t,n,r={}){try{return await Cl(e,t,n,r)}catch(e){return h({level:`warn`,phase:`android_fill_pre_action_target_capture_failed`,data:{error:e instanceof Error?e.message:String(e)}}),null}}function Y(e,n,r){if(r?.ok)return;let i=r?Tl(e,n,r):null;if(i)return i;throw new t(`COMMAND_FAILED`,Ol(r),kl(e,r))}function Tl(e,t,n){let r=n.targetInput,i=n.actualInput;if(e.length===0||n.reason===`ime_capture`||!t||!r||!i||K(t)||K(r)||K(i)||!Kl(t,r)||!Kl(t,i)||t.text===n.actual)return null;let a=ql(t);return h({level:`warn`,phase:`android_fill_verification_unconfirmed`,data:{target:a}}),{verification:`unconfirmed`,requested:e,before:t.text,after:n.actual,target:a}}function El(e,t,n,r,i={}){let a=jl(e,t,n,i);return Ml(a)?{ok:!1,actual:a.actualInput?.text??null,reason:`ime_capture`,targetInput:a.targetInput,actualInput:a.actualInput}:Nl(a,r)??Pl(a,r)}function Dl(e,t,n){return jl(e,t,n).targetInput?.text??null}function Ol(e){return e?.reason===`ime_capture`?`Android fill input was captured by the active keyboard instead of the app field`:e?.reason===`masked_unverified`?`Android fill verification could not confirm masked text value`:`Android fill verification failed`}function kl(e,t){let n=Ho(e,t);return t?.reason===`ime_capture`&&(n.hint=`The focused input belongs to the Android keyboard/IME, not the app field. Disable handwriting/stylus input or switch to a standard IME, then retry fill.`),n}async function Al(e,t,n,r,i,a){return El(await qc(e,a),t,n,r,i)}function jl(e,t,n,r={}){let i={focusedEdit:null,editAtPoint:null,anyAtPoint:null};for(let a of ec(e)){let e=zl(a,r);e&&Vl(i,e,t,n)}return Ul(i)}function Ml(e){let{targetInput:t,actualInput:n}=e;return!t||!n||n===t?!1:n.inputMethodOwned&&!t.inputMethodOwned}function Nl(e,t){let n=e.actualInput;if(!n||!Gl(n))return null;let r=n.text??null,i=Array.from(Fl(n)).length,a=Array.from(t).length,o=a===0?i===0:i>0&&i===a;return{ok:o,actual:r,reason:o?void 0:`masked_unverified`,masked:!0,targetInput:e.targetInput,actualInput:n}}function Pl(e,t){let n=e.actualInput;return{ok:n!==null&&Il(Fl(n),t),actual:n?.text??null,reason:`text_mismatch`,targetInput:e.targetInput,actualInput:n}}function Fl(e){return e.hintShowing?``:e.text??``}function Il(e,t){if(e===t)return!0;if(t.length===0)return!1;let n=Ll(e),r=Ll(t);return!n||!r?!1:!!(n===r||Rl(n,r))}function Ll(e){return e.replaceAll(/\s+/g,` `).trim()}function Rl(e,t){if(e.length!==t.length||e.length===0||e.slice(1)!==t.slice(1))return!1;let n=e[0],r=t[0];return!n||!r?!1:r.toLowerCase()===r&&n===r.toUpperCase()}function zl(e,t){if(!e.rect)return null;let n=e.text??``,r=Math.max(1,e.rect.width*e.rect.height);return{text:n||null,className:e.className,resourceId:e.resourceId,packageName:e.packageName,rect:e.rect,focused:e.focused??!1,password:e.password===!0,inputMethodOwned:p({packageName:e.packageName,resourceId:e.resourceId,activeInputMethodPackage:t.activeInputMethodPackage}),area:r,editText:Wl(e.className??``),hintShowing:e.hintShowing===!0}}async function Bl(e){try{return{activeInputMethodPackage:(await Na(e)).inputMethodPackage}}catch(e){return h({level:`warn`,phase:`android_fill_verification_input_method_probe_failed`,data:{error:e instanceof Error?e.message:String(e)}}),{}}}function Vl(e,t,n,r){let i=re(t.rect,n,r);if(i&&t.editText&&(e.editAtPoint=Hl(e.editAtPoint,t)),t.focused&&t.editText){e.focusedEdit=Hl(e.focusedEdit,t);return}i&&t.text&&(e.anyAtPoint=Hl(e.anyAtPoint,t))}function Hl(e,t){return e&&e.area<t.area?e:t}function Ul(e){let t=e.editAtPoint??e.anyAtPoint;return{targetInput:t,actualInput:(e.focusedEdit?.text?e.focusedEdit:null)??t}}function Wl(e){let t=e.toLowerCase();return t.includes(`edittext`)||t.includes(`textfield`)}function Gl(e){return K(e)}function Kl(e,t){return e.resourceId||t.resourceId?e.resourceId===t.resourceId&&e.packageName===t.packageName:e.className===t.className&&e.packageName===t.packageName&&e.rect.x===t.rect.x&&e.rect.y===t.rect.y&&e.rect.width===t.rect.width&&e.rect.height===t.rect.height}function ql(e){return{resourceId:e.resourceId,className:e.className,packageName:e.packageName,rect:e.rect}}async function Jl(e,t){return await wt(t.stateDir),await bo(t.stateDir,e.id,async()=>await Yl(e,t))}async function Yl(e,t){let r=y().imeRecoveryMarkers,i=x(e),a=S(e),o=B(e),s;try{s=await eo(a),await io({adb:i,adbProvider:a,artifact:s,deviceKey:o})}catch(e){return{outcome:`helper-unavailable`,reason:n(e).message}}let{manifest:c}=s,l=await U(i);if(l===c.serviceComponent){let n=await r.write(t.stateDir,e.id),a=await W(i);return n&&G.add(o),{outcome:`settled`,activated:!1,alreadyActive:!0,...n?{}:{persistFailed:!0},previousIme:a,helperServiceComponent:c.serviceComponent,helperPackageName:c.packageName}}let u=await W(i);if(!await po(i,l))return await ho(i,u,e.id),v({level:`warn`,phase:`android_test_ime_persist_failed`,data:{device:e.id,previousIme:l}}),{outcome:`settled`,activated:!1,alreadyActive:!1,persistFailed:!0,helperServiceComponent:c.serviceComponent,helperPackageName:c.packageName};let d=(await r.read(t.stateDir)).includes(e.id);if(!await r.write(t.stateDir,e.id))return await ho(i,u,e.id),v({level:`warn`,phase:`android_test_ime_marker_persist_failed`,data:{device:e.id,previousIme:l}}),{outcome:`settled`,activated:!1,alreadyActive:!1,persistFailed:!0,helperServiceComponent:c.serviceComponent,helperPackageName:c.packageName};await i([`shell`,`ime`,`enable`,c.serviceComponent],{allowFailure:!0,timeoutMs:1e4});let f=await i([`shell`,`ime`,`set`,c.serviceComponent],{allowFailure:!0,timeoutMs:1e4}),p=await U(i);return p===c.serviceComponent?(G.add(o),v({phase:`android_test_ime_activated`,data:{device:e.id,previousIme:l}}),{outcome:`settled`,activated:!0,alreadyActive:!1,previousIme:l,helperServiceComponent:c.serviceComponent,helperPackageName:c.packageName}):(G.delete(o),await ho(i,u,e.id),d||await r.clear(t.stateDir,e.id),v({level:`warn`,phase:`android_test_ime_activate_failed`,data:{device:e.id,activeIme:p,stderr:f.stderr.trim()}}),{outcome:`settled`,activated:!1,alreadyActive:!1,helperServiceComponent:c.serviceComponent,helperPackageName:c.packageName})}function Xl(e){return w.join(e,`android-test-ime-pending`)}function Zl(e,t){return w.join(Xl(e),encodeURIComponent(t))}async function Ql(e,t){let r=y().files,i,a=!1;try{let n=Xl(e);if(i=Zl(e,t),await r.ensureDirectory(n),(await tu(i))?.serial===t)return!0;let o={version:1,serial:t};if(await r.writeAtomicText(i,`${JSON.stringify(o)}\n`,384),a=!0,(await tu(i))?.serial!==t)throw Error(`Android test IME marker read-back did not match the requested device.`);return!0}catch(o){return a&&i&&await r.remove(i,{force:!0}).catch(()=>{}),h({level:`debug`,phase:`android_test_ime_marker_write_failed`,data:{stateDir:e,serial:t,error:n(o).message}}),!1}}async function $l(e,t){await y().files.remove(Zl(e,t),{force:!0}).catch(()=>{})}async function eu(e){let t=y().files,n;try{n=await t.readDirectory(Xl(e))}catch{return[]}let r=[];for(let t of n)try{let n=w.join(Xl(e),t),i=await tu(n);i&&Zl(e,i.serial)===n&&r.push(i.serial)}catch{}return[...new Set(r)].sort()}async function tu(e){try{return nu(await y().files.readText(e))}catch{return}}function nu(e){try{let t=JSON.parse(e);if(!t||typeof t!=`object`||Array.isArray(t))return;let n=t;return n.version===1&&typeof n.serial==`string`&&n.serial.length>0?{version:1,serial:n.serial}:void 0}catch{return}}const ru=new Dt(`utf-16le`);let iu;async function au(e,t){for(let n of[`AndroidManifest.xml`,`base/manifest/AndroidManifest.xml`]){let r=await ou(e,n,t);if(!r)continue;let i=su(r);if(i)return i}return await gu(e,t)}async function ou(e,t,n){try{let r=await be(`unzip`,[`-p`,e,t],{allowFailure:!0,binaryStdout:!0,signal:n});return r.exitCode!==0||!r.stdoutBuffer||r.stdoutBuffer.length===0?void 0:r.stdoutBuffer}catch{n?.throwIfAborted();return}}function su(e){return e.subarray(0,Math.min(e.length,128)).toString(`utf8`).trimStart().startsWith(`<`)?cu(e.toString(`utf8`)):lu(e)}function cu(e){return e.match(/<manifest\b[^>]*\bpackage\s*=\s*["']([^"']+)["']/i)?.[1]}function lu(e){if(e.length<8||e.readUInt16LE(0)!==3)return;let t;for(let n=e.readUInt16LE(2);n+8<=e.length;){let r=e.readUInt16LE(n),i=e.readUInt16LE(n+2),a=e.readUInt32LE(n+4);if(a<=0||n+a>e.length)return;if(r===1)t=du(e.subarray(n,n+a));else if(r===258&&t){let r=uu(e,n,i,t);if(r)return r}n+=a}}function uu(e,t,n,r){if(n<36||t+n>e.length||r[e.readUInt32LE(t+20)]!==`manifest`)return;let i=e.readUInt16LE(t+24),a=e.readUInt16LE(t+26),o=e.readUInt16LE(t+28),s=t+i;for(let t=0;t<o;t+=1){let n=s+t*a;if(n+20>e.length)return;if(r[e.readUInt32LE(n+4)]!==`package`)continue;let i=e.readUInt32LE(n+8);if(i!==4294967295)return r[i];let o=e.readUInt8(n+15),c=e.readUInt32LE(n+16);return o===3?r[c]:void 0}}function du(e){if(e.length<28)return[];let t=e.readUInt32LE(8),n=e.readUInt32LE(16),r=e.readUInt32LE(20),i=!!(n&256),a=[];for(let n=0;n<t;n+=1){let t=28+n*4;if(t+4>e.length)return a;let o=r+e.readUInt32LE(t);a.push(i?fu(e,o):pu(e,o))}return a}function fu(e,t){let[,n]=mu(e,t),[r,i]=mu(e,t+n),a=t+n+i;return e.subarray(a,a+r).toString(`utf8`)}function pu(e,t){let[n,r]=hu(e,t),i=t+r;return ru.decode(e.subarray(i,i+n*2))}function mu(e,t){let n=e.readUInt8(t);if(!(n&128))return[n,1];let r=e.readUInt8(t+1);return[(n&127)<<8|r,2]}function hu(e,t){let n=e.readUInt16LE(t);if(!(n&32768))return[n,2];let r=e.readUInt16LE(t+2);return[(n&32767)<<16|r,4]}async function gu(e,t){t?.throwIfAborted();let n=await _u();if(!n)return;let r=await be(n,[`dump`,`badging`,e],{allowFailure:!0,signal:t});if(r.exitCode===0)return r.stdout.match(/package:\s+name='([^']+)'/)?.[1]}async function _u(){if(iu!==void 0)return iu??void 0;try{let e=y().files;for(let t of it()){let n=w.join(t,`build-tools`);try{let t=(await e.readDirectory(n)).sort((e,t)=>t.localeCompare(e,void 0,{numeric:!0}));for(let r of t){let t=w.join(n,r,`aapt`);if(w.isAbsolute(t)&&await e.isExecutable(t))return iu=t,t}}catch{}}}catch{}iu=null}async function vu(e,t){let n=e.kind===`url`&&Oe(e.url),r=await ke({source:e,isInstallablePath:(e,t)=>t.isFile()&&yu(e),installableLabel:`Android installable (.apk or .aab)`,allowArchiveExtraction:e.kind!==`url`||n,signal:t?.signal});try{let e=t?.resolveIdentity===!1?{}:await bu(r.installablePath,t?.signal);return{archivePath:r.archivePath,installablePath:r.installablePath,packageName:e.packageName,cleanup:r.cleanup}}catch(e){throw await r.cleanup(),e}}function yu(e){let t=w.extname(e).toLowerCase();return t===`.apk`||t===`.aab`}async function bu(e,t){let n=w.extname(e).toLowerCase();return n!==`.apk`&&n!==`.aab`?{}:{packageName:await au(e,t)}}async function xu(e,n,r,i={}){let a=typeof r.action==`string`&&r.action.trim()?r.action.trim():`${n}.TEST_PUSH`,o=[`shell`,`am`,`broadcast`,`-a`,a,`-p`,n],s=typeof r.receiver==`string`?r.receiver.trim():``;s&&o.push(`-n`,s);let c=r.extras;if(c!==void 0&&(typeof c!=`object`||!c||Array.isArray(c)))throw new t(`INVALID_ARGS`,`Android push payload extras must be an object`);let l=c??{},u=0;for(let[e,t]of Object.entries(l))e&&(Su(o,e,t),u+=1);return await C(e,o,{signal:i.signal}),{action:a,extrasCount:u}}function Su(e,n,r){if(typeof r==`string`){e.push(`--es`,n,r);return}if(typeof r==`boolean`){e.push(`--ez`,n,r?`true`:`false`);return}if(typeof r==`number`&&Number.isFinite(r)){if(Number.isInteger(r)){e.push(`--ei`,n,String(r));return}e.push(`--ef`,n,String(r));return}throw new t(`INVALID_ARGS`,`Unsupported Android broadcast extra type for "${n}". Use string, boolean, or number.`)}function X(e){let t=e.replaceAll(`,`,``).match(/^-?\d+(?:\.\d+)?/);if(!t)return null;let n=Number(t[0]);return Number.isFinite(n)?n:null}function Cu(e){let t=Ou(e.map(e=>e.intendedVsyncNs)),n=[];for(let e=1;e<t.length;e+=1){let r=t[e]-t[e-1];r>=4e6&&r<=5e7&&n.push(r)}if(n.length!==0)return ku(n)}function wu(e){let{frames:t,frameDeadlineNs:n,summaryDroppedFrameCount:r}=e;return r===void 0?n===void 0?[]:t.filter(e=>e.durationNs>n):r<=0?[]:[...t].sort((e,t)=>t.durationNs-e.durationNs).slice(0,r).sort((e,t)=>e.intendedVsyncNs-t.intendedVsyncNs)}function Tu(e){let{frames:t,windowStartNs:n,measuredAtMs:r,uptimeMs:i}=e;if(t.length===0||n===void 0)return[];let a=[],o=[];for(let e of t){let t=o.at(-1);if(!t||e.intendedVsyncNs-t.frameCompletedNs<=5e8){o.push(e);continue}a.push(o),o=[e]}return o.length>0&&a.push(o),a.map(e=>Du({frames:e,windowStartNs:n,measuredAtMs:r,uptimeMs:i})).sort((e,t)=>t.missedDeadlineFrameCount-e.missedDeadlineFrameCount||t.worstFrameMs-e.worstFrameMs).slice(0,3).sort((e,t)=>e.startOffsetMs-t.startOffsetMs)}function Eu(e){return Math.round(e*10)/10}function Du(e){let{frames:t,windowStartNs:n,measuredAtMs:r,uptimeMs:i}=e,a=Math.min(...t.map(e=>e.intendedVsyncNs)),o=Math.max(...t.map(e=>e.frameCompletedNs)),s=Math.max(0,Math.round((a-n)/1e6)),c=Math.max(s,Math.round((o-n)/1e6)),l=i!==void 0&&Number.isFinite(r)?r-i:void 0;return{startOffsetMs:s,endOffsetMs:c,startAt:l===void 0?void 0:new Date(l+a/1e6).toISOString(),endAt:l===void 0?void 0:new Date(l+o/1e6).toISOString(),missedDeadlineFrameCount:t.length,worstFrameMs:Eu(Math.max(...t.map(e=>e.durationNs))/1e6)}}function Ou(e){return[...new Set(e.filter(e=>Number.isFinite(e)))].sort((e,t)=>e-t)}function ku(e){let t=[...e].sort((e,t)=>e-t),n=Math.floor(t.length/2);return t.length%2==1?t[n]:(t[n-1]+t[n])/2}function Au(e,t,n){ju(e,t);let r=Vu(e),i=Lu(e),a=Nu(i,r,t),o=Date.parse(n),s=Uu({frames:i,measuredAtMs:o,summary:r}),c=wu({frames:i,frameDeadlineNs:a,summaryDroppedFrameCount:r?.droppedFrameCount}),l=r?.sampleWindowMs??s.sampleWindowMs??qu(i),u=Pu(r,i,c),d=Iu({droppedFrames:c,timing:s,measuredAtMs:o,summary:r});return{...u,sampleWindowMs:l,...Fu(a),windowStartedAt:s.windowStartedAt,windowEndedAt:s.windowEndedAt,timestampSource:s.timestampSource,measuredAt:n,method:`adb-shell-dumpsys-gfxinfo-framestats`,source:r?`android-gfxinfo-summary`:`framestats-rows`,worstWindows:d&&d.length>0?d:void 0}}function ju(e,n){if(/no process found for:/i.test(e))throw new t(`COMMAND_FAILED`,`Android gfxinfo did not find a running process for ${n}`,{metric:`fps`,package:n,hint:`Run open <app> for this session again to ensure the Android app is active, then retry perf after the interaction you want to inspect.`})}function Mu(e){throw new t(`COMMAND_FAILED`,`Failed to parse Android framestats output for ${e}`,{metric:`fps`,package:e,hint:`Retry perf after exercising the app screen. If the problem persists, capture adb shell dumpsys gfxinfo <package> framestats output for debugging.`})}function Nu(e,n,r){let i=Cu(e);if(!n&&e.length===0&&Mu(r),n||i!==void 0)return i;throw new t(`COMMAND_FAILED`,`Failed to infer Android frame deadline from framestats output for ${r}`,{metric:`fps`,package:r,hint:`Retry perf after a longer interaction window so consecutive Android frame timestamps are available.`})}function Pu(e,t,n){let r=e?.totalFrameCount??t.length,i=e?.droppedFrameCount??n.length;return{totalFrameCount:r,droppedFrameCount:i,droppedFramePercent:e?.droppedFramePercent??(r>0?Tt(i/r*100):0)}}function Fu(e){return{frameDeadlineMs:e===void 0?void 0:Eu(e/1e6),refreshRateHz:e===void 0?void 0:Eu(1e9/e)}}function Iu(e){let{droppedFrames:t,timing:n,measuredAtMs:r,summary:i}=e;if(t.length===0)return;let a=Tu({frames:t,windowStartNs:n.windowStartNs,measuredAtMs:r,uptimeMs:i?.uptimeMs});return a.length>0?a:void 0}function Lu(e){let t=[],n=null;for(let r of e.split(`
13
- `)){let e=r.trim();if(e.length===0||e===`---PROFILEDATA---`)continue;let i=e.split(`,`).map(e=>e.trim());if(Ru(i)){n=new Map(i.map((e,t)=>[e,t]));continue}let a=zu(i,n);a&&t.push(a)}return t.sort((e,t)=>e.intendedVsyncNs-t.intendedVsyncNs)}function Ru(e){return e.includes(`IntendedVsync`)&&e.includes(`FrameCompleted`)}function zu(e,t){if(!t||e.length<t.size)return;let n=Bu(e,t,`Flags`),r=Bu(e,t,`IntendedVsync`),i=Bu(e,t,`FrameCompleted`);if(!(n!==0||r===null||i===null||r<=0||i<=r))return{intendedVsyncNs:r,frameCompletedNs:i,durationNs:i-r}}function Bu(e,t,n){let r=t.get(n);if(r===void 0)return null;let i=Number(e[r]);return Number.isFinite(i)?i:null}function Vu(e){let t=e.split(/\nProfile data in ms:\n/i)[0]??``,n=Ju(t,`Total frames rendered`),r=t.match(/^\s*Janky frames:\s*([0-9][0-9,]*)\s*\(([0-9.]+)%\)/im);if(n===void 0||!r)return;let i=r[1],a=r[2];if(i===void 0||a===void 0)return;let o=X(i)??void 0,s=Number(a);if(o===void 0||!Number.isFinite(s)||n<0)return;let c=Ju(t,`Uptime`),l=Ju(t,`Stats since`);return{droppedFramePercent:Tt(s),droppedFrameCount:o,totalFrameCount:n,sampleWindowMs:Hu({uptimeMs:c,statsSinceNs:l}),uptimeMs:c,statsSinceNs:l}}function Hu(e){let{uptimeMs:t,statsSinceNs:n}=e;if(t===void 0||n===void 0)return;let r=t-Math.round(n/1e6);return r>=0?r:void 0}function Uu(e){let{frames:t,measuredAtMs:n,summary:r}=e,i=Wu(t),a=r?.statsSinceNs,o=a??i.firstFrameNs,s=Gu(o,i.lastFrameNs),c=r?.sampleWindowMs??s;if(!Number.isFinite(n)||r?.uptimeMs===void 0||o===void 0)return{sampleWindowMs:c,windowStartNs:o};let l=n-r.uptimeMs;return{sampleWindowMs:c,windowStartNs:o,windowStartedAt:new Date(l+o/1e6).toISOString(),windowEndedAt:Ku({deviceBootWallClockMs:l,measuredAtMs:n,summaryStartNs:a,lastFrameNs:i.lastFrameNs}),timestampSource:`estimated-from-device-uptime`}}function Wu(e){return e.length===0?{}:{firstFrameNs:Math.min(...e.map(e=>e.intendedVsyncNs)),lastFrameNs:Math.max(...e.map(e=>e.frameCompletedNs))}}function Gu(e,t){if(e!==void 0&&t!==void 0)return Math.max(0,Math.round((t-e)/1e6))}function Ku(e){let{deviceBootWallClockMs:t,measuredAtMs:n,summaryStartNs:r,lastFrameNs:i}=e;return r===void 0?i===void 0?void 0:new Date(t+i/1e6).toISOString():new Date(n).toISOString()}function qu(e){if(e.length===0)return;let t=Wu(e);return Gu(t.firstFrameNs,t.lastFrameNs)}function Ju(e,t){let n=t.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`),r=e.match(RegExp(`^\\s*${n}:\\s*([0-9][0-9,]*)`,`im`));if(!r)return;let i=r[1];return i===void 0?void 0:X(i)??void 0}async function Yu(e,t,n={}){let r=x(e,n.adb);try{let i=Au((await r([`shell`,`dumpsys`,`gfxinfo`,t,`framestats`],{timeoutMs:15e3})).stdout,t,new Date().toISOString());return await Xu(e,t,n),i}catch(e){throw Zu(t,e)}}async function Xu(e,t,n={}){let r=x(e,n.adb);try{await r([`shell`,`dumpsys`,`gfxinfo`,t,`reset`],{allowFailure:!0,timeoutMs:3e3})}catch{}}function Zu(e,n){return n instanceof t?new t(n.code,n.message,{...n.details??{},metric:`fps`,package:e},n):new t(`COMMAND_FAILED`,`Failed to sample Android fps for ${e}`,{metric:`fps`,package:e},n)}function Z(e,n,r,i){if(i instanceof t){let a=i.details??{};return new t(i.code,i.message,{...a,action:e,package:r,tool:n,hint:typeof a.hint==`string`?a.hint:ed(n,a)},i)}return new t(`COMMAND_FAILED`,`Failed to ${e} Android ${n} for ${r}`,{action:e,package:r,tool:n,hint:Qu(n)},i)}function Qu(e){return e===`simpleperf`?`Verify simpleperf is available, the app process is running, and the app/device permits native CPU profiling.`:`Verify perfetto is available, the app process is running, and the device permits trace capture.`}function $u(e){return e===`simpleperf`?`Use an emulator/system image with simpleperf available, or install the Android NDK simpleperf binary for this device.`:`Use Android 10+ or a system image that exposes the perfetto command-line binary.`}function ed(e,t){let n=(typeof t.stderr==`string`?t.stderr:``).toLowerCase();return e===`simpleperf`?td(n):rd(n)?`Use a device image that permits perfetto trace capture for shell, keep the app running, then retry perf trace start.`:Qu(e)}function td(e){return nd(e)?`Use a debuggable/profileable Android app or a device image that permits simpleperf for the target process, then retry perf cpu profile start.`:e.includes(`not supported`)||e.includes(`failed to open perf event`)?`This device image does not expose the requested simpleperf event for the app process. Try a different emulator/system image or a profileable app.`:Qu(`simpleperf`)}function nd(e){return e.includes(`permission denied`)||e.includes(`not profileable`)||e.includes(`profileable`)}function rd(e){return e.includes(`permission denied`)||e.includes(`not allowed`)}async function id(e,t,n,r,i){return{capture:{durationMs:r,packageName:t.packageName,appPid:t.appPid,artifactPath:t.outPath,sizeBytes:n},frameHealth:t.kind===`perfetto`?await ad(e,t.packageName,i):void 0,notes:[t.kind===`perfetto`?`Frame health is sampled from Android gfxinfo around the trace window; open the Perfetto artifact for timeline root cause.`:`Open the Simpleperf report artifact for symbol-level CPU attribution.`]}}async function ad(e,t,n){try{let r=await Yu(e,t,n);return{available:!0,droppedFramePercent:r.droppedFramePercent,droppedFrameCount:r.droppedFrameCount,totalFrameCount:r.totalFrameCount,method:r.method,worstWindows:r.worstWindows?.slice(0,3).map(e=>({startOffsetMs:e.startOffsetMs,endOffsetMs:e.endOffsetMs,missedDeadlineFrameCount:e.missedDeadlineFrameCount,worstFrameMs:e.worstFrameMs}))}}catch(e){return{available:!1,reason:e instanceof Error?e.message:`Android frame health was not available`}}}const od=`adb-shell-simpleperf`,sd=`adb-shell-perfetto`,cd=15e3,Q=3e4,ld=`/data/local/tmp`;async function ud(e,t,n){let r=x(e,n.adb);await gd(r,t),await yd(r,t),await vd(r,t,n.files);let i=await hd(t.outPath,n.files);await pd(r,t.remotePath);let a=Date.now(),o=Math.max(0,a-t.startedAt),s=await id(e,t,i,o,{adb:r});return{...t,action:`stop`,platform:`android`,state:`stopped`,stoppedAt:a,durationMs:o,sizeBytes:i,method:t.kind===`simpleperf`?od:sd,artifact:{path:t.outPath,sizeBytes:i},summary:s,message:`Stopped Android ${t.kind} ${t.type} for ${t.packageName}`}}async function dd(e,t,n={}){let r=x(e,n.adb);try{t.state===`running`&&(await gd(r,t),await yd(r,t).catch(()=>{}))}finally{await pd(r,t.remotePath)}}function fd(e,t,n=ld){return`${n}/agent-device-${e.replaceAll(/[^A-Za-z0-9_.-]/g,`_`)}-${Date.now()}-${t}`}async function pd(e,t){try{await e([`shell`,`rm -f ${_(t)}`],{allowFailure:!0,timeoutMs:cd})}catch{}}async function md(e,t,n=y().files){await n.ensureDirectory(w.dirname(e)),await n.writeBytes(e,Buffer.from(`${JSON.stringify(t,null,2)}\n`))}async function hd(e,n=y().files){try{return(await n.stat(e)).size}catch(n){throw new t(`COMMAND_FAILED`,`Profiler artifact was not written: ${e}`,{outPath:e,hint:`Retry the profiling command and check daemon logs if the artifact path is still missing.`},n)}}async function gd(e,t){try{await e([`shell`,_d(t.profilerPid)],{timeoutMs:Q})}catch(e){throw Z(`stop`,t.kind,t.packageName,e)}}function _d(e){return[`pid=${_(e)}`,`kill -INT "$pid" 2>/dev/null || true`,`for i in 1 2 3 4 5 6 7 8 9 10; do kill -0 "$pid" 2>/dev/null || exit 0; sleep 0.2; done`,`kill -TERM "$pid" 2>/dev/null || true`,`for i in 1 2 3 4 5 6 7 8 9 10; do kill -0 "$pid" 2>/dev/null || exit 0; sleep 0.2; done`,`echo "profiler process did not stop after SIGTERM" >&2`,`exit 1`].join(`; `)}async function vd(e,n,r){await(r??y().files).ensureDirectory(w.dirname(n.outPath));try{await e([`pull`,n.remotePath,n.outPath],{timeoutMs:Q})}catch(e){throw new t(`COMMAND_FAILED`,`Failed to pull Android ${n.kind} artifact for ${n.packageName}`,{package:n.packageName,tool:n.kind,remotePath:n.remotePath,outPath:n.outPath,hint:`Check that the profiling command ran long enough to create an artifact, then retry stop with the same session.`},e)}}async function yd(e,n){let r;for(let t=0;t<12;t+=1){let t=await bd(e,n.remotePath);if(t!==void 0&&t>0&&t===r)return;r=t,await g(250)}throw new t(`COMMAND_FAILED`,`Android ${n.kind} artifact is not ready to pull`,{package:n.packageName,tool:n.kind,remotePath:n.remotePath,hint:`The profiler stopped, but the remote artifact was missing, empty, or still changing. Retry stop with the same session or inspect the device-side artifact.`})}async function bd(e,t){let n=_(t),r=await e([`shell`,`if [ -f ${n} ]; then stat -c %s ${n} 2>/dev/null || wc -c < ${n}; fi`],{allowFailure:!0,timeoutMs:cd});if(r.exitCode!==0)return;let i=Number(r.stdout.trim().split(/\s+/)[0]);return Number.isFinite(i)?i:void 0}async function xd(e,n){try{let t=await e([`shell`,`pidof`,n],{allowFailure:!0,timeoutMs:cd}),r=Cd(t.stdout);if(t.exitCode===0&&r)return r}catch{}throw new t(`COMMAND_FAILED`,`No active Android app process found for ${n}`,{package:n,hint:`Run open <app> for this session again, wait for the app UI to appear, then retry perf.`})}async function Sd(e,n,r){let i=await e([`shell`,`command -v ${n} || which ${n}`],{allowFailure:!0,timeoutMs:cd});if(!(i.exitCode===0&&i.stdout.trim()))throw new t(`UNSUPPORTED_OPERATION`,`Android device does not expose ${n}`,{package:r,tool:n,hint:$u(n)})}function Cd(e){return e.trim().split(/\s+/).find(e=>/^\d+$/.test(e))}async function wd(e,t,n,r={}){let i=x(e,r.adb),a=await xd(i,t);await Sd(i,`perfetto`,t);let o=fd(t,`app.perfetto-trace`,`/data/misc/perfetto-traces`),s;try{await Xu(e,t,{adb:i}),s=await Ed(i,o,t)}catch(e){throw await pd(i,o),e}return{type:`trace`,kind:`perfetto`,packageName:t,appPid:a,profilerPid:s,remotePath:o,outPath:n,startedAt:Date.now(),state:`running`,action:`start`,platform:`android`,method:sd,message:`Started Android Perfetto trace for ${t}`}}async function Td(e,t,n,r={}){return await ud(e,{...t,outPath:n},r)}async function Ed(e,n,r){try{let i=Cd((await e([`shell`,`perfetto`,`--background-wait`,`-o`,n,`-t`,`3600s`,`sched`,`freq`,`idle`,`am`,`wm`,`gfx`,`view`,`binder_driver`,`hal`,`dalvik`],{timeoutMs:Q})).stdout);if(i)return i;throw new t(`COMMAND_FAILED`,`Android perfetto did not return a profiler pid`,{package:r,tool:`perfetto`,hint:`Retry perf trace start. If perfetto exits immediately, verify the device permits trace capture.`})}catch(e){throw Z(`start`,`perfetto`,r,e)}}function Dd(e){let t=[];for(let n of s(e)){let e=n.match(/^([0-9]+(?:\.[0-9]+)?)%\s+(.+)$/);if(!e)continue;let r=Number(e[1]),i=e[2]?.trim();if(!Number.isFinite(r)||!i)continue;let a=i.split(/\s{2,}/).filter(Boolean);if(t.push({percentage:Tt(r),command:a[0],dso:a[1],symbol:a.slice(2).join(` `)||void 0}),t.length>=50)break}return t}async function Od(e,t,n,r={}){let i=x(e,r.adb),a=await xd(i,t);await Sd(i,`simpleperf`,t);let o=fd(t,`cpu.perf.data`),s;try{s=await jd(i,a,o,t)}catch(e){throw await pd(i,o),e}return{type:`cpu-profile`,kind:`simpleperf`,packageName:t,appPid:a,profilerPid:s,remotePath:o,outPath:n,startedAt:Date.now(),state:`running`,action:`start`,platform:`android`,method:od,message:`Started Android Simpleperf CPU profile for ${t}`}}async function kd(e,t,n,r={}){return await ud(e,{...t,outPath:n},r)}async function Ad(e,t,n,r={}){let i=x(e,r.adb);await Sd(i,`simpleperf`,t.packageName);let a=await Pd(i,t),o=new Date().toISOString(),s=Dd(a.stdout),c=s.slice(0,10).map(e=>({symbol:e.symbol??`<unknown>`,binary:e.dso,selfSamplePercent:e.percentage}));await md(n,{kind:`simpleperf-report`,generatedAt:o,packageName:t.packageName,appPid:t.appPid,sourceProfilePath:t.outPath,sourceRemotePath:t.remotePath,entryCount:s.length,summary:{topFunctions:c},entries:s},r.files);let l=await hd(n,r.files);return{action:`report`,platform:`android`,type:`cpu-profile-report`,kind:`simpleperf`,packageName:t.packageName,appPid:t.appPid,sourceProfilePath:t.outPath,outPath:n,sizeBytes:l,generatedAt:o,entryCount:s.length,summary:{topFunctions:c},method:od,message:`Wrote Android Simpleperf report for ${t.packageName}`}}async function jd(e,n,r,i){try{let a=Cd((await e([`shell`,Md(n,r)],{timeoutMs:Q})).stdout);if(a)return a;throw new t(`COMMAND_FAILED`,`Android simpleperf did not return a profiler pid`,{package:i,tool:`simpleperf`,hint:`Retry perf. If simpleperf exits immediately, verify the app is profileable and the device permits native profiling.`})}catch(e){throw Z(`start`,`simpleperf`,i,e)}}function Md(e,t){return Nd([`simpleperf`,`record`,`-e`,`cpu-clock:u`,`-p`,e,`-o`,t,`--duration`,`3600`],`simpleperf`)}function Nd(e,t){let n=e.map(_).join(` `),r=`${ld}/agent-device-${t}-${Date.now()}.err`;return[`err=${_(r)}`,`(${n}) >/dev/null 2>"$err" & pid=$!`,`sleep 1`,`if kill -0 "$pid" 2>/dev/null; then rm -f "$err"; echo "$pid"; exit 0; fi`,`cat "$err" >&2`,`rm -f "$err"`,`exit 1`].join(`; `)}async function Pd(e,t){try{return await e([`shell`,`simpleperf`,`report`,`-i`,t.remotePath,`--stdio`,`--sort`,`comm,dso,symbol`],{timeoutMs:Q})}catch(e){throw Z(`report`,`simpleperf`,t.packageName,e)}}const Fd=15e3,Id=12e4;async function Ld(e,t,n={}){let r=x(e,n.adb);try{return Vd((await r([`shell`,`dumpsys`,`meminfo`,t],{timeoutMs:Fd})).stdout,t,new Date().toISOString())}catch(e){throw Yd(`memory`,t,e)}}async function Rd(e,n,r,i={}){let a=x(e,i.adb),o=i.files??y().files,s=await Hd(a,n),c=Ud(n);await o.ensureDirectory(w.dirname(r));let l=await zd(o,r);try{ye(await a([`shell`,`am`,`dumpheap`,n,c],{allowFailure:!0,timeoutMs:Id}),`Failed to capture Android heap dump for ${n}`,e=>({kind:`android-hprof`,package:n,pid:s,remotePath:c,hint:Wd(e.stdout,e.stderr)}));let e=await a([`pull`,c,r],{allowFailure:!0,timeoutMs:Id});if(e.exitCode!==0)throw await Bd(o,r,l),b(`Failed to pull Android heap dump for ${n}`,e,{kind:`android-hprof`,package:n,pid:s,remotePath:c,path:r,hint:`Verify the daemon can write the requested --out path and retry. The heap dump stays on-device only until cleanup runs.`});let i=await o.stat(r).catch(()=>null);if(!i?.isFile||i.size<=0)throw await Bd(o,r,l),new t(`COMMAND_FAILED`,`Android heap dump artifact is missing or empty`,{kind:`android-hprof`,package:n,pid:s,path:r,remotePath:c,hint:`Retry with a writable --out path. If the file is still empty, inspect adb pull output with --debug.`});return{available:!0,kind:`android-hprof`,path:r,sizeBytes:i.size,measuredAt:new Date().toISOString(),method:`adb-shell-am-dumpheap`,packageName:n,pid:s,remotePath:c}}finally{await a([`shell`,`rm`,`-f`,c],{allowFailure:!0,timeoutMs:Fd}).catch(()=>{})}}async function zd(e,t){return await e.stat(t).then(e=>e.isFile).catch(()=>!1)}async function Bd(e,t,n){n||await e.remove(t,{force:!0}).catch(()=>{})}function Vd(e,n,r){if(/no process found for:/i.test(e))throw new t(`COMMAND_FAILED`,`Android meminfo did not find a running process for ${n}`,{metric:`memory`,package:n,hint:`Run open <app> for this session again to ensure the Android app is active, then retry perf.`});let i=Xd(e,`TOTAL PSS`)??Zd(e);if(i===void 0)throw new t(`COMMAND_FAILED`,`Failed to parse Android meminfo output for ${n}`,{metric:`memory`,package:n,hint:`Retry perf after reopening the app session. If the problem persists, capture adb shell dumpsys meminfo output for debugging.`});return{totalPssKb:i,totalRssKb:Xd(e,`TOTAL RSS`),measuredAt:r,method:`adb-shell-dumpsys-meminfo`,topConsumers:Gd(e)}}async function Hd(e,n){let r=await e([`shell`,`pidof`,n],{allowFailure:!0,timeoutMs:Fd}),i=r.stdout.trim().split(/\s+/).map(Number).find(e=>Number.isInteger(e)&&e>0);if(r.exitCode===0&&i!==void 0)return i;throw new t(`COMMAND_FAILED`,`No running Android process found for ${n}`,{kind:`android-hprof`,package:n,stdout:r.stdout,stderr:r.stderr,hint:`Run open <app> for this session again to ensure the Android app is active, then retry perf memory snapshot.`})}function Ud(e){return`/data/local/tmp/agent-device-${e.replaceAll(/[^a-zA-Z0-9._-]/g,`_`)}-${Date.now()}.hprof`}function Wd(e,t){let n=`${e}\n${t}`.toLowerCase();return n.includes(`profileable`)||n.includes(`debuggable`)||n.includes(`not allowed`)?`Android heap dumps require a debuggable/profileable app process on many devices. Use a debug/profileable build, reopen the app, then retry.`:n.includes(`permission`)||n.includes(`denied`)?`The device denied heap dump access. Use a debug/profileable build or a device image that permits app heap dumping.`:`Reopen the app to refresh the process, then retry perf memory snapshot. If it still fails, run with --debug and inspect adb am dumpheap output.`}function Gd(e){let t=e.split(`
14
- `).flatMap(e=>Kd(e)??[]).sort((e,t)=>t.pssKb-e.pssKb).slice(0,5);return t.length>0?t:void 0}function Kd(e){let t=e.trim();if(qd(t))return;let n=t.match(/^(.+?)\s+([0-9][0-9,]*(?:\(\d+\))?)(?:\s|$)/);if(n)return Jd(n[1],n[2])}function qd(e){if(!e||e.startsWith(`**`)||e.startsWith(`-`)||e.includes(`:`))return!0;let t=/^\S.+\s+\d/.test(e);return/^(pss|total|native|dalvik|unknown|app summary\b)/i.test(e)&&!t}function Jd(e,t){let n=e?.trim(),r=t?X(t):null;if(!(!n||n===`TOTAL`||r===null||r<=0)&&!/^(pss|private|shared|heap|size|alloc|free)$/i.test(n))return{name:n,pssKb:r}}function Yd(e,n,r){return r instanceof t?new t(r.code,r.message,{...r.details??{},metric:e,package:n},r):new t(`COMMAND_FAILED`,`Failed to sample Android ${e} for ${n}`,{metric:e,package:n},r)}function Xd(e,t){let n=t.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`),r=e.match(RegExp(`${n}:\\s*([0-9][0-9,]*)`,`i`));if(!r)return;let i=r[1];return i===void 0?void 0:X(i)??void 0}function Zd(e){for(let t of e.split(`
15
- `)){let e=t.trim();if(!/^TOTAL\b(?!\s+PSS:)/.test(e))continue;let n=e.split(/\s+/).slice(1).find(e=>X(e)!==null);return n?X(n)??void 0:void 0}}async function Qd(e,t,n){let r=await C(e,[`shell`,`dumpsys`,`package`,t],{allowFailure:!0});if(r.exitCode===0)return rf(r.stdout,n)}async function $d(e){let t=await C(e,[`shell`,`am`,`get-current-user`],{allowFailure:!0});if(t.exitCode!==0)return;let n=Number.parseInt(t.stdout.trim(),10);return Number.isInteger(n)&&n>=0?n:void 0}const ef=/^\s*User (\d+):/,tf=/^\s*runtime permissions:\s*$/,nf=/^\s*([\w.]+): granted=(true|false)\b/;function rf(e,t){let n=af(af(af(e.split(`
16
- `).filter(e=>e.trim().length>0).map(e=>({text:e,indent:e.length-e.trimStart().length})),e=>e.indent===0&&e.text.trim()===`Packages:`),e=>ef.exec(e.text)?.[1]===String(t)),e=>tf.test(e.text));if(!n)return;let r=new Map;for(let{text:e}of n){let t=nf.exec(e);t&&r.set(t[1],t[2]===`true`?`granted`:`not_granted`)}return r}function af(e,t){if(!e)return;let n=e.findIndex(e=>t(e));if(n<0)return;let r=e.slice(n+1),i=r.findIndex(t=>t.indent<=e[n].indent);return i<0?r:r.slice(0,i)}function of(e,t,n){if(n!==`not_granted`)return`${n===`granted`?`${t} was granted before this revoke, and Android kills an app when a granted permission is revoked: if ${e} was running it is no longer.`:`Whether ${t} was granted before this revoke could not be read (adb did not report the acting user's runtime permission state), and Android kills an app when a granted permission is revoked: ${e} may no longer be running.`} Relaunch it with open ${e} --relaunch before the next interaction.`}async function sf(e){let n=await $d(e);if(n!==void 0)return n;throw new t(`COMMAND_FAILED`,`Could not determine which Android user the session runs as, so no permission was changed.`,{deviceId:e.id,hint:`Check adb -s ${e.id} shell am get-current-user — if the device is still booting, retry once it reports a user. agent-device refuses to change permissions it cannot scope, because pm would silently apply them to user 0.`})}async function cf(e,t,n,r){let i=ge(n),a=df(r?.permissionTarget,r?.permissionMode),o=await sf(e),s=[`--user`,String(o)];if(i===`grant`){await lf(e,t,a,s);return}let c=await Qd(e,t,o),l=await uf(e,t,i,a,s),u=c?.get(l)??`unknown`,d=of(t,l,u);return{permission:l,priorGrantState:u,...d?{warnings:[d]}:{}}}async function lf(e,t,n,r){n.kind===`notifications`?await pf(e,t,`grant`,n,r):n.type===`photos`?await ff(e,t,`grant`,r):await C(e,[`shell`,`pm`,`grant`,...r,t,n.value])}async function uf(e,t,n,r,i){if(r.kind===`notifications`)return await pf(e,t,n,r,i),r.permission;let a;return r.type===`photos`?a=await ff(e,t,`revoke`,i):(a=r.value,await C(e,[`shell`,`pm`,`revoke`,...i,t,a])),n===`reset`&&await mf(e,t,a,i),a}function df(e,n){let r=me(e);if(n?.trim())throw new t(`INVALID_ARGS`,`Permission mode is only supported for photos. Received: ${n}.`);if(r===`camera`)return{kind:`pm`,value:`android.permission.CAMERA`,type:`camera`};if(r===`microphone`)return{kind:`pm`,value:`android.permission.RECORD_AUDIO`,type:`microphone`};if(r===`photos`)return{kind:`pm`,value:`android.permission.READ_MEDIA_IMAGES`,type:`photos`};if(r===`contacts`)return{kind:`pm`,value:`android.permission.READ_CONTACTS`,type:`contacts`};if(r===`notifications`)return{kind:`notifications`,appOps:`POST_NOTIFICATION`,permission:`android.permission.POST_NOTIFICATIONS`};throw new t(`INVALID_ARGS`,`Unsupported permission target on Android: ${e}. Use camera|microphone|photos|contacts|notifications.`)}async function ff(e,n,r,i){let a=await hf(e),o=a!==null&&a>=33?[`android.permission.READ_MEDIA_IMAGES`,`android.permission.READ_EXTERNAL_STORAGE`]:[`android.permission.READ_EXTERNAL_STORAGE`,`android.permission.READ_MEDIA_IMAGES`],s=[];for(let t of o){let a=await C(e,[`shell`,`pm`,r,...i,n,t],{allowFailure:!0});if(a.exitCode===0)return t;s.push({permission:t,stderr:a.stderr,exitCode:a.exitCode})}throw new t(`COMMAND_FAILED`,`Failed to ${r} Android photos permission`,{appPackage:n,sdkInt:a,attempts:s})}async function pf(e,t,n,r,i){let a=n===`grant`?`allow`:n===`deny`?`deny`:`default`;n===`grant`?await C(e,[`shell`,`pm`,`grant`,...i,t,r.permission],{allowFailure:!0}):(await C(e,[`shell`,`pm`,`revoke`,...i,t,r.permission],{allowFailure:!0}),n===`reset`&&await mf(e,t,r.permission,i)),await C(e,[`shell`,`appops`,`set`,...i,t,r.appOps,a])}async function mf(e,t,n,r){for(let i of[`user-set`,`user-fixed`])await C(e,[`shell`,`pm`,`clear-permission-flags`,...r,t,n,i],{allowFailure:!0})}async function hf(e){let t=await C(e,[`shell`,`getprop`,`ro.build.version.sdk`],{allowFailure:!0});if(t.exitCode!==0)return null;let n=Number.parseInt(t.stdout.trim(),10);return!Number.isFinite(n)||n<=0?null:n}function gf(e){let n=e.trim().toLowerCase();if(n===`light`)return`light`;if(n===`dark`)return`dark`;if(n===`toggle`)return`toggle`;throw new t(`INVALID_ARGS`,`Invalid appearance state: ${e}. Use light|dark|toggle.`)}function _f(e){let n=e.toLowerCase();if(n===`on`||n===`true`||n===`1`)return!0;if(n===`off`||n===`false`||n===`0`)return!1;throw new t(`INVALID_ARGS`,`Invalid setting state: ${e}`)}function vf(e){return e.map(e=>({args:e.args.join(` `),exitCode:e.exitCode,stderr:e.stderr.slice(0,400)}))}const yf=[`shell`,`cmd`,`connectivity`,`airplane-mode`];async function bf(e,n){let r=n?`enabled`:`disabled`;await xf(e),await C(e,[...yf,n?`enable`:`disable`]);let i=await Sf(e);if(i!==r)throw new t(`COMMAND_FAILED`,`Android airplane mode reads ${i} after requesting ${r}.`,{deviceId:e.id,requested:r,airplaneMode:i});return{airplaneMode:i}}async function xf(e){let{state:n,result:r}=await Cf(e);if(!n)throw r.exitCode!==0&&Ue(r.stdout,r.stderr)?new t(`UNSUPPORTED_OPERATION`,`The connectivity service on this Android build has no airplane-mode command, so nothing was changed.`,{deviceId:e.id,hint:`settings airplane needs cmd connectivity airplane-mode, which requires Android 11 (API 30) or newer. Use a newer device or emulator image.`,stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode}):b(`Failed to read Android airplane mode`,r,{deviceId:e.id})}async function Sf(e){let{state:t,result:n}=await Cf(e);if(t)return t;throw b(`Failed to read Android airplane mode after changing it`,n,{deviceId:e.id})}async function Cf(e){let t=await C(e,[...yf],{allowFailure:!0});return{state:t.exitCode===0?wf(t.stdout):void 0,result:t}}function wf(e){let t=e.trim().toLowerCase();if(t===`enabled`)return`enabled`;if(t===`disabled`)return`disabled`}const Tf=[`window_animation_scale`,`transition_animation_scale`,`animator_duration_scale`];async function Ef(e,n,r,i,a){switch(n.toLowerCase()){case`wifi`:{let t=_f(r);await C(e,[`shell`,`svc`,`wifi`,t?`enable`:`disable`]);return}case`airplane`:return await bf(e,_f(r));case`location`:{if(r.toLowerCase()===`set`){if(e.kind!==`emulator`)throw new t(`UNSUPPORTED_OPERATION`,`Android precise location coordinates are supported only on emulators.`,{deviceId:e.id,hint:`Use an Android emulator for adb emu geo fix, or configure location through device/provider tooling.`});let{latitude:n,longitude:r}=he(a);return await C(e,[`emu`,`geo`,`fix`,String(r),String(n)]),{latitude:n,longitude:r}}let n=_f(r)?`3`:`0`;await C(e,[`shell`,`settings`,`put`,`secure`,`location_mode`,n]);return}case`animations`:{let t=_f(r)?`1`:`0`;for(let n of Tf)await C(e,[`shell`,`settings`,`put`,`global`,n,t]);return{scale:t,keys:[...Tf]}}case`appearance`:{let t=await jf(e,r);await C(e,[`shell`,`cmd`,`uimode`,`night`,t===`dark`?`yes`:`no`]);return}case`clear-app-state`:{if(r.toLowerCase()!==`clear`)throw new t(`INVALID_ARGS`,`settings clear-app-state only supports clear.`);if(!i)throw new t(`INVALID_ARGS`,`settings clear-app-state requires an app id or an active app session.`);let n=await lt(e,i);if(n.type===`intent`)throw new t(`INVALID_ARGS`,`settings clear-app-state requires a package name, not an intent.`);await C(e,[`shell`,`am`,`force-stop`,n.value],{allowFailure:!0});let a=await C(e,[`shell`,`pm`,`clear`,n.value],{allowFailure:!0});if(a.exitCode!==0||!/\bSuccess\b/i.test(a.stdout))throw new t(`COMMAND_FAILED`,`Failed to clear Android app data for ${n.value}`,{package:n.value,stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});return{package:n.value,cleared:!0}}case`fingerprint`:await Of(e,Df(r));return;case`permission`:if(!i)throw new t(`INVALID_ARGS`,`permission setting requires an active app in session`);return await cf(e,i,r,a);default:throw new t(`INVALID_ARGS`,`Unsupported setting: ${n}`)}}function Df(e){let n=e.trim().toLowerCase();if(n===`match`)return`match`;if(n===`nonmatch`)return`nonmatch`;throw new t(`INVALID_ARGS`,`Invalid fingerprint state: ${e}. Use match|nonmatch.`)}async function Of(e,n){let r=kf(e,n),i=[];for(let t of r){let n=await C(e,t,{allowFailure:!0});if(n.exitCode===0)return;i.push({args:t,stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode})}let a=vf(i);throw i.length>0&&i.every(e=>Af(e.stdout,e.stderr))?new t(`UNSUPPORTED_OPERATION`,`Android fingerprint simulation is not supported on this target/runtime.`,{deviceId:e.id,action:n,hint:`Use an Android emulator with biometric support, or a device/runtime that exposes cmd fingerprint.`,attempts:a}):new t(`COMMAND_FAILED`,`Failed to simulate Android fingerprint.`,{deviceId:e.id,action:n,attempts:a})}function kf(e,t){let n=t===`match`?`1`:`9999`,r=[[`shell`,`cmd`,`fingerprint`,`touch`,n],[`shell`,`cmd`,`fingerprint`,`finger`,n]];return e.kind===`emulator`&&r.push([`emu`,`finger`,`touch`,n]),r}function Af(e,t){let n=`${e}\n${t}`.toLowerCase();return n.includes(`unknown command`)||n.includes(`can't find service: fingerprint`)||n.includes(`service fingerprint was not found`)||n.includes(`fingerprint cmd unavailable`)||n.includes(`emu command is not supported`)||n.includes(`emulator console is not running`)||n.includes(`fingerprint`)&&n.includes(`not found`)}async function jf(e,n){let r=gf(n);if(r!==`toggle`)return r;let i=await C(e,[`shell`,`cmd`,`uimode`,`night`],{allowFailure:!0});if(i.exitCode!==0)throw b(`Failed to read current Android appearance`,i);let a=Mf(i.stdout,i.stderr);if(!a)throw new t(`COMMAND_FAILED`,`Unable to determine current Android appearance for toggle`,{stdout:i.stdout,stderr:i.stderr});return a===`auto`?`dark`:a===`dark`?`light`:`dark`}function Mf(e,t){let n=/night mode:\s*(yes|no|auto)\b/i.exec(`${e}\n${t}`);if(!n)return null;let r=n[1]?.toLowerCase();return r===`yes`?`dark`:r===`no`?`light`:r===`auto`?`auto`:null}const Nf=Buffer.from([137,80,78,71,13,10,26,10]);async function Pf(e,t,n={}){if(n.stabilize===!1){await Lf(e,t);return}await Ff(e);try{await g(1e3),await Lf(e,t)}finally{await If(e).catch(()=>{})}}async function Ff(e){let t=t=>C(e,[`shell`,t],{allowFailure:!0});await t(`settings put global sysui_demo_allowed 1`);let n=e=>t(`am broadcast -a com.android.systemui.demo -e command ${e}`);await n(`clock -e hhmm 0941`),await n(`notifications -e visible false`)}async function If(e){await C(e,[`shell`,`am broadcast -a com.android.systemui.demo -e command exit`],{allowFailure:!0})}async function Lf(e,n){let r=await C(e,[`exec-out`,`screencap`,`-p`],{binaryStdout:!0});if(!r.stdoutBuffer)throw new t(`COMMAND_FAILED`,`Failed to capture screenshot`);let i=r.stdoutBuffer.indexOf(Nf);if(i<0)throw new t(`COMMAND_FAILED`,`Screenshot data does not contain a valid PNG header`);let a=Rf(r.stdoutBuffer,i);if(!a)throw new t(`COMMAND_FAILED`,`Screenshot data does not contain a complete PNG payload`);await y().files.writeBytes(n,r.stdoutBuffer.subarray(i,a))}function Rf(e,t){let n=t+Nf.length;for(;n+8<=e.length;){let t=e.readUInt32BE(n),r=n+4,i=e.toString(`ascii`,r,r+4),a=n+12+t;if(a>e.length)return null;if(i===`IEND`)return a;n=a}return null}async function zf(e,t,n=0){let r=Be(e);if(r){await r({action:`type`,text:t,delayMs:n}),$(`type`,`provider-native`,t);return}let i=await Wf(e,`type`,t);if(i.backend===`test-ime`){await Gf(e,i.packageName,t,n);return}if(n>0&&Array.from(t).length>1){await qf(e,{action:`type`,text:t,chunkSize:1,delayMs:n});return}await qf(e,{action:`type`,text:t,chunkSize:8,delayMs:0})}async function Bf(e,t,n,r,i=0,a={}){let o=await wl(e,t,n,a),s=Be(e);if(s)return await s({action:`fill`,target:{x:t,y:n},text:r,delayMs:i}),$(`fill`,`provider-native`,r),Y(r,o,await xl(e,t,n,r,a));let c=null;for(let s of Vf(i)){await ta(e,t,n);let i=await Wf(e,`fill`,r);if(i.backend===`test-ime`)return Y(r,o,await Kf(e,i.packageName,t,n,r,o,a));let l=await Hf(e,{x:t,y:n,text:r,beforeTarget:o,attempt:s},a);if(c=l,l.ok)return;if(l.reason===`ime_capture`)return Y(r,o,l);let u=Tl(r,o,l);if(u)return u}return Y(r,o,c)}function Vf(e){return[{clearPadding:12,minClear:8,maxClear:48,chunkSize:e>0?1:8,inputDelayMs:e},{clearPadding:24,minClear:16,maxClear:96,chunkSize:e>0?1:4,inputDelayMs:e>0?e:15}]}async function Hf(e,t,n){let{x:r,y:i,text:a,beforeTarget:o,attempt:s}=t;return await Yf(e,Uf(a,o,s)),await qf(e,{action:`fill`,text:a,chunkSize:s.chunkSize,delayMs:s.inputDelayMs}),xl(e,r,i,a,n)}function Uf(e,t,n){let r=Array.from(e).length;return ip(r>0?r+n.clearPadding:t?.text?Array.from(t.text).length+n.clearPadding:n.maxClear,n.minClear,n.maxClear)}async function Wf(e,t,n){if(yo(e))return{backend:`test-ime`,packageName:(await eo(S(e))).manifest.packageName};let r=await Xf(e,t),i=r?.inputMethodPackage;return oo(i)?{backend:`test-ime`,packageName:i}:(Qf(n),Zf(r,t),{backend:`adb-shell`})}async function Gf(e,t,n,r){let i=x(e),a=n.split(`
17
- `);for(let[n,o]of a.entries()){let s=r>0?rp(o,1):[o];for(let[e,o]of s.entries())o&&await so(i,t,o),r>0&&(e+1<s.length||n+1<a.length)&&await g(r);n+1<a.length&&await C(e,[`shell`,`input`,`keyevent`,`ENTER`])}$(`type`,`test-ime`,n)}async function Kf(e,t,n,r,i,a,o){let s=x(e),c=null;for(let l=0;l<2;l+=1){l>0&&await ta(e,n,r),await co(s,t),i&&await so(s,t,i);let u=await xl(e,n,r,i,o);if(c=u,u.ok||Tl(i,a,u))break}return $(`fill`,`test-ime`,i),c}async function qf(e,t){let n=t.text.split(`
18
- `);for(let[r,i]of n.entries()){let a=rp(i,t.chunkSize);for(let[i,o]of a.entries())await Jf(e,o),t.delayMs>0&&(i+1<a.length||r+1<n.length)&&await g(t.delayMs);r+1<n.length&&await C(e,[`shell`,`input`,`keyevent`,`ENTER`])}$(t.action,`adb-shell`,t.text)}async function Jf(e,t){if(t)try{await C(e,[`shell`,`input`,`text`,Te(ep(t))])}catch(e){throw tp(e)?np(t,e):e}}async function Yf(e,t){let n=Math.max(0,t);await C(e,[`shell`,`input`,`keyevent`,`KEYCODE_MOVE_END`],{allowFailure:!0});for(let t=0;t<n;t+=24){let r=Math.min(24,n-t);await C(e,[`shell`,`input`,`keyevent`,...Array(r).fill(`KEYCODE_DEL`)],{allowFailure:!0})}}async function Xf(e,t){try{return await Na(e)}catch(e){return h({level:`warn`,phase:`android_input_ownership_probe_failed`,data:{action:t,error:e instanceof Error?e.message:String(e)}}),null}}function Zf(e,n){if(!(!e||e.inputOwner!==`ime`))throw new t(`COMMAND_FAILED`,`KEYBOARD_OVERLAY_BLOCKING: Android text input is blocked because the focused input belongs to the active keyboard/IME.`,{failureReason:`ime_capture`,action:n,inputOwner:e.inputOwner,inputType:e.inputType,type:e.type,inputMethodPackage:e.inputMethodPackage,focusedPackage:e.focusedPackage,focusedResourceId:e.focusedResourceId,nextAction:`Focused input appears to be owned by the keyboard/IME; dismiss or change the IME before retrying text entry.`})}function Qf(e){if(!$f(e))throw np(e)}function $f(e){for(let t of e){let e=t.codePointAt(0);if(e!==void 0&&t!==`
19
- `&&(e<32||e>126))return!1}return!0}function ep(e){return e.replaceAll(` `,`%s`)}function tp(e){if(!(e instanceof t)||e.code!==`COMMAND_FAILED`)return!1;let n=e.details?.stderr,r=(typeof n==`string`?n:``).toLowerCase();return!!(r.includes(`exception occurred while executing 'text'`)||r.includes(`nullpointerexception`)&&r.includes(`inputshellcommand.sendtext`))}function np(e,n){return new t(`COMMAND_FAILED`,"Android text input requires provider-native text injection or the bundled test IME helper for non-ASCII/control characters; the adb-shell fallback supports ASCII text only. On emulators the test IME activates automatically; on real devices pass `open --test-ime` to enable it (see `agent-device doctor` for the current IME state).",{backend:`adb-shell`,textLength:Array.from(e).length,textPreview:e.slice(0,32)},n instanceof Error?n:void 0)}function rp(e,t){let n=Math.max(1,Math.floor(t)),r=[],i=Array.from(e);for(let e=0;e<i.length;e+=n)r.push(i.slice(e,e+n).join(``));return r.length>0?r:[``]}function $(e,t,n){h({phase:`android_text_injection`,data:{action:e,backend:t,textLength:Array.from(n).length}})}function ip(e,t,n){return Math.max(t,Math.min(n,e))}var ap=e({ANDROID_FOCUSED_WINDOW_MARKER:()=>ht,ANDROID_FOCUS_MARKERS:()=>pt,ANDROID_IME_HELPER_SERVICE_COMPONENT:()=>`com.callstack.agentdevice.imehelper/.TestInputMethodService`,ANDROID_SNAPSHOT_PRESENTATION_DEFAULT_DEADLINE_MS:()=>250,ANDROID_TEST_IME_SETTINGS_KEYS:()=>fo,ANDROID_TOUCH_PLAN_PROTOCOL:()=>Si,AndroidSnapshotPresentationFailure:()=>J,activateAndroidTestIme:()=>Jl,androidAdbForwardsDeviceExitStatus:()=>kt,androidAdbResultError:()=>b,androidAppsDiscoveryHint:()=>ut,androidCaptureFailureReasonDetail:()=>or,androidCaptureFailureReasonFromExitCode:()=>ar,androidCaptureFailureReasonFromHelperResult:()=>ir,androidDeviceChecks:()=>Ao,androidFillFailureDetails:()=>kl,androidFillFailureMessage:()=>Ol,androidRevokedPermissionWarning:()=>of,androidSnapshotPublicationInput:()=>Kc,androidToolchainCheck:()=>ko,androidUiNodes:()=>ec,annotateAndroidNativePerfError:()=>Z,appSwitcherAndroid:()=>$i,attachAdbFailureHint:()=>Me,backAndroid:()=>Gi,buildAndroidFillUnconfirmedVerification:()=>Tl,buildAndroidNativeToolUnavailableHint:()=>$u,buildAndroidSnapshotClickabilityEvidence:()=>mc,buildAndroidSnapshotHelperArgs:()=>Rr,buildAndroidSnapshotHelperCaptureOptions:()=>Ir,buildUiHierarchySnapshot:()=>Ps,captureAndroidHeapSnapshot:()=>Rd,captureAndroidLogcatWithAdb:()=>sp,captureAndroidSnapshotWithHelper:()=>Fr,captureAndroidSnapshotWithHelperSession:()=>_i,classifyAdbFailure:()=>Ne,classifyAndroidAlertIdentifier:()=>Bt,classifyAndroidAppTarget:()=>at,classifyAndroidHelperContent:()=>gc,cleanupAndroidNativePerfSession:()=>dd,clearAndroidImeHelperText:()=>co,clearAndroidTestImeRecoveryMarker:()=>$l,closeAndroidApp:()=>et,completeAndroidFillVerification:()=>Y,createAndroidPortReverseManager:()=>Fe,createAndroidSnapshotCapture:()=>Gc,createAndroidSnapshotPresentationBudget:()=>ks,createAndroidSnapshotPresentationNode:()=>Ts,createAndroidWindowDumpReader:()=>yt,createDeviceAdbExecutor:()=>ze,createLocalAndroidAdbProvider:()=>Ie,dismissAndroidKeyboard:()=>Pa,dismissAndroidKeyboardWithAdb:()=>Fa,ensureAndroidEmulatorBooted:()=>rt,ensureAndroidImeHelper:()=>io,ensureAndroidSdkPathConfigured:()=>$e,ensureAndroidSnapshotHelper:()=>Zn,executeAndroidTouchHelperPlan:()=>Ei,executeAndroidTouchPlan:()=>Bi,fillAndroid:()=>Bf,findAndroidAlertCandidate:()=>Vt,focusAndroid:()=>ta,forceStopAndroidAppWithAdb:()=>_a,forgetAndroidSnapshotHelperInstall:()=>Kn,formatAndroidInstalledPackageRequiredMessage:()=>ct,getAndroidAppState:()=>_t,getAndroidBlockingDialogObservation:()=>vt,getAndroidImeHelperDeviceKey:()=>B,getAndroidKeyboardState:()=>Na,getAndroidKeyboardStatusWithAdb:()=>R,getAndroidScreenSize:()=>aa,getAndroidSnapshotHelperSessionDeviceKey:()=>Cr,handleAndroidAlert:()=>oa,homeAndroid:()=>Ki,inferAndroidAppName:()=>st,inferAndroidPackageAfterOpen:()=>lp,inspectInstalledAndroidHelper:()=>xn,installAndroidAdbPackage:()=>Ve,installAndroidInstallablePath:()=>Oa,isAmStartError:()=>nt,isAndroidImeHelperPackage:()=>oo,isAndroidPermissionPackage:()=>Nt,isAndroidShellCommandUnsupported:()=>Ue,isAndroidSnapshotHelperRetirementUnconfirmedError:()=>Er,isAndroidSnapshotPresentationFailure:()=>Ds,isAndroidTestImeActive:()=>yo,listAndroidAdbSerialsQuick:()=>Do,listAndroidAppsWithAdb:()=>op,longPressAndroid:()=>ea,lowerAndroidTouchPlan:()=>Ri,makeEnsureAndroidHelperInstalled:()=>Cn,normalizeAndroidTouchHelperGestureRequest:()=>ji,openAndroidApp:()=>Qe,openAndroidAppWithAdb:()=>ya,openAndroidDevice:()=>Xe,parseAndroidHelperManifest:()=>A,parseAndroidLaunchComponent:()=>tt,parseAndroidLaunchablePackages:()=>ft,parseAndroidSnapshotHelperManifest:()=>A,parseAndroidSnapshotHelperOutput:()=>qr,parseAndroidUserInstalledPackages:()=>dt,parseInstrumentationRecords:()=>dn,parseUiHierarchyTree:()=>fc,prepareAndroidInstallArtifact:()=>vu,pressAndroid:()=>Ui,pressAndroidEnter:()=>qi,pressAndroidTvRemote:()=>Wi,pullAndroidAdbFile:()=>Re,pushAndroidNotification:()=>xu,readAndroidBlockingDialogFocus:()=>mt,readAndroidClipboardText:()=>Ka,readAndroidClipboardWithAdb:()=>qa,readAndroidDefaultInputMethod:()=>U,readAndroidFillTargetBeforeMutation:()=>wl,readAndroidGestureViewport:()=>Vi,readAndroidHelperManifestInteger:()=>cn,readAndroidHelperManifestLiteral:()=>D,readAndroidSnapshotHelperInstallOptions:()=>In,readAndroidTestImeRecoveryMarkers:()=>eu,readAndroidTextAtPoint:()=>Sl,readAndroidTextAtPointInHierarchy:()=>Dl,readAndroidTouchHelperFinalRecord:()=>Pi,readAndroidTouchHelperViewportReading:()=>Di,readInstrumentationResultBoolean:()=>_n,readInstrumentationResultNumber:()=>O,resetAndroidAdbShellProtocolProbes:()=>At,resetAndroidFramePerfStats:()=>Xu,resetAndroidImeHelperInstallCache:()=>ao,resetAndroidSnapshotHelperInstallCache:()=>qn,resetAndroidSnapshotHelperRuntime:()=>Uc,resetAndroidSnapshotHelperSessions:()=>gi,resetAndroidTestImeActivationCacheForTests:()=>xo,resetAndroidWindowDumpFocusMemoForTests:()=>gt,resolveAndroidAdbExecutor:()=>x,resolveAndroidAdbProvider:()=>S,resolveAndroidApp:()=>lt,resolveAndroidArchivePackageName:()=>au,resolveAndroidHelperArtifact:()=>Sn,resolveAndroidImeHelperArtifact:()=>to,resolveAndroidPackageForOpen:()=>cp,resolveAndroidSnapshotHelperCaptureOptions:()=>Lr,resolveAndroidTextInjector:()=>Be,resolveAndroidTouchProvider:()=>Pe,resolveScopedAndroidAdbBackgroundTransport:()=>Le,restoreAndroidTestIme:()=>Co,restoreOrphanedAndroidTestImeOnDaemonStartup:()=>Eo,retireAndroidSnapshotHelperAfterContentFailure:()=>Hc,runAndroidAdb:()=>C,runAndroidHostAdb:()=>je,runAndroidSnapshotHelperSessionTouchCommand:()=>yi,sampleAndroidFramePerf:()=>Yu,sampleAndroidMemoryPerf:()=>Ld,screenshotAndroid:()=>Pf,scrollAndroid:()=>na,selectAndroidImeHelperArtifact:()=>eo,sendAndroidImeHelperText:()=>so,setAndroidOrientation:()=>Ji,setAndroidPermission:()=>cf,setAndroidSetting:()=>Ef,setAndroidTestImeActiveForTests:()=>So,sleep:()=>g,snapshotAndroid:()=>Jc,startAndroidPerfettoTrace:()=>wd,startAndroidSimpleperfProfile:()=>Od,stopAndroidPerfettoTrace:()=>Td,stopAndroidSimpleperfProfile:()=>kd,stopAndroidSnapshotHelperSession:()=>L,stopAndroidSnapshotHelperSessionForDevice:()=>hi,typeAndroid:()=>zf,validateAndroidGestureViewport:()=>vn,validateAndroidRegularPresentation:()=>As,verifyAndroidFilledText:()=>xl,verifyAndroidFilledTextInHierarchy:()=>El,verifyAndroidHelperApkChecksum:()=>Dn,waitForAndroidBoot:()=>Ze,withAndroidAdbProvider:()=>He,withAndroidAppResolutionCacheInvalidated:()=>ot,withAndroidHostAdbTransport:()=>Ae,writeAndroidClipboardText:()=>Ja,writeAndroidClipboardWithAdb:()=>Ya,writeAndroidSimpleperfReport:()=>Ad,writeAndroidTestImeRecoveryMarker:()=>Ql});async function op(...e){let{listAndroidAppsWithAdb:t}=await import(`./app-helpers.js`);return await t(...e)}async function sp(...e){let{captureAndroidLogcatWithAdb:t}=await import(`./logcat.js`);return await t(...e)}async function cp(...e){let{resolveAndroidPackageForOpen:t}=await import(`./open-target-resolution.js`);return await t(...e)}async function lp(...e){let{inferAndroidPackageAfterOpen:t}=await import(`./open-target-resolution.js`);return await t(...e)}export{Ji as A,ta as C,qi as D,Ui as E,Vi as M,Wi as O,Gi as S,ea as T,Ya as _,zf as a,oa as b,Jc as c,Fa as d,Na as f,Ja as g,qa as h,Bf as i,Bi as j,na as k,Kc as l,Ka as m,op as n,Pf as o,R as p,ap as r,Ef as s,sp as t,Pa as u,_a as v,Ki as w,$i as x,ya as y};
10
+ `).replace(/\n$/,``),n=t.match(/^clipboard text:\s*(.*)$/i);return n?n[1]??``:t.trim().toLowerCase()===`null`?``:t}const mo=`com.callstack.agentdevice.imehelper`,ho=`android-ime-helper-v1`;async function go(e){return e.imeHelperArtifact??await _o()}async function _o(){return await y().resolveHelperArtifact({helperDirName:`ime-helper`,manifestFileName:e=>`agent-device-android-ime-helper-${e}.manifest.json`,parseManifest:vo,unavailableMessage:`Android test IME text entry requires the bundled Android IME helper artifact, but it was not found or could not be read`})}const U=`IME helper`;function vo(e){if(!e||typeof e!=`object`||Array.isArray(e))throw new t(`INVALID_ARGS`,`Android IME helper manifest must be an object.`);let n=e;return{name:E(n.name,`name`,`android-ime-helper`,U),version:dn(n.version,`version`,U),assetName:dn(n.assetName,`assetName`,U),sha256:fn(n.sha256,U),packageName:E(n.packageName,`packageName`,mo,U),versionCode:un(n.versionCode,`versionCode`,U),serviceComponent:E(n.serviceComponent,`serviceComponent`,`com.callstack.agentdevice.imehelper/.TestInputMethodService`,U),broadcastProtocol:E(n.broadcastProtocol,`broadcastProtocol`,ho,U)}}const yo=new Set;async function bo(e){return await y().ensureHelperInstalled({cache:yo,installTimeoutMs:3e4,helperLabel:`Android IME helper`},e)}function xo(){yo.clear()}function W(e){return`${e.platform}:${e.id}`}function So(e){return e===mo}async function Co(e,t,n){await To(e,t,`com.callstack.agentdevice.imehelper.ACTION_INPUT_TEXT_B64`,{text:Buffer.from(n,`utf8`).toString(`base64`)})}async function wo(e,t){await To(e,t,`com.callstack.agentdevice.imehelper.ACTION_CLEAR_TEXT`,{})}async function To(e,t,n,r){let i=[`shell`,`am`,`broadcast`,`-p`,t,`-a`,n];i.push(`--es`,`protocol`,ho);for(let[e,t]of Object.entries(r))i.push(`--es`,e,t);let a=await e(i,{allowFailure:!0,timeoutMs:1e4});if(a.exitCode!==0)throw b(`Android IME helper broadcast failed`,a,{action:n,packageName:t})}const Eo=`agent_device_ime_helper_previous_ime`,Do=`secure`,Oo=`default_input_method`,ko={previousIme:Eo,defaultInputMethod:Oo};async function G(e){let t=await e([`shell`,`settings`,`get`,Do,Oo],{allowFailure:!0,timeoutMs:5e3});return Po(t.exitCode===0?t.stdout:``)}async function K(e){let t=await e([`shell`,`settings`,`get`,Do,Eo],{allowFailure:!0,timeoutMs:5e3});return Po(t.exitCode===0?t.stdout:``)||void 0}async function Ao(e,t){return(await e([`shell`,`settings`,`put`,Do,Eo,t],{allowFailure:!0,timeoutMs:5e3})).exitCode===0&&await K(e)===t}async function jo(e){await e([`shell`,`settings`,`delete`,Do,Eo],{allowFailure:!0,timeoutMs:5e3})}async function Mo(e,t,r){try{(t?await Ao(e,t):await No(e))||v({level:`warn`,phase:`android_test_ime_record_rollback_failed`,data:{device:r,hadPriorRecord:t!==void 0}})}catch(e){v({level:`warn`,phase:`android_test_ime_record_rollback_failed`,data:{device:r,hadPriorRecord:t!==void 0,error:n(e).message}})}}async function No(e){return await jo(e),await K(e)===void 0}function Po(e){let t=e.trim();return!t||t===`null`?``:t}const q=new Set,Fo=new Map;function Io(e){return q.has(W(e))}function Lo(e,t,n){return St(Fo,`${e}:${t}`,n)}function Ro(){q.clear()}function zo(e,t){let n=W(e);t?q.add(n):q.delete(n)}async function Bo(e,t){return await Lo(t.stateDir,e.id,async()=>{let n=W(e);if(!q.has(n))return{restored:!1,reason:`no-record`};q.delete(n);let r=await Ho(x(e),e);return Vo(r.reason)&&await y().imeRecoveryMarkers.clear(t.stateDir,e.id),r})}function Vo(e){return e===`ok`||e===`helper-not-active`||e===`no-record`}async function Ho(e,t){let n=t.id;if(q.has(W(t)))return{restored:!1,reason:`owned-by-live-session`};let r=await K(e);if(!r)return{restored:!1,reason:`no-record`};let i=await G(e);if(i!==`com.callstack.agentdevice.imehelper/.TestInputMethodService`)return v({level:`debug`,phase:`android_test_ime_restore_skipped`,data:{device:n,currentIme:i,previousIme:r}}),{restored:!1,previousIme:r,reason:`helper-not-active`};await e([`shell`,`ime`,`set`,r],{allowFailure:!0,timeoutMs:1e4});let a=await G(e);return a===r?(await jo(e).catch(()=>{}),v({phase:`android_test_ime_restored`,data:{device:n,previousIme:r}}),{restored:!0,previousIme:r,reason:`ok`}):(v({level:`warn`,phase:`android_test_ime_restore_failed`,data:{device:n,previousIme:r,afterIme:a}}),{restored:!1,previousIme:r,reason:`set-failed`})}async function Uo(e){let t=y().imeRecoveryMarkers,r=await t.read(e.stateDir);if(r.length===0)return;let i;try{i=new Set(await e.listSerials())}catch(e){v({level:`debug`,phase:`android_test_ime_startup_scan_failed`,data:{error:n(e).message}});return}for(let a of r){if(!i.has(a))continue;let r={platform:`android`,id:a,name:a,kind:a.startsWith(`emulator-`)?`emulator`:`device`,booted:!0};try{await Lo(e.stateDir,a,async()=>{let n=await Ho(x(r),r);n.restored&&v({level:`warn`,phase:`android_test_ime_orphan_restored`,data:{device:a,previousIme:n.previousIme}}),Vo(n.reason)&&await t.clear(e.stateDir,a)})}catch(e){v({level:`debug`,phase:`android_test_ime_orphan_restore_failed`,data:{device:a,error:n(e).message}})}}}async function Wo(){y();try{return(await je([`devices`],{timeoutMs:5e3})).stdout.split(`
11
+ `).map(e=>e.trim()).filter(e=>e.length>0&&!e.startsWith(`List of devices`)).map(e=>e.split(/\s+/)).filter(e=>e[1]===`device`).map(e=>e[0])}catch{return[]}}const Go=2e3;async function Ko(e=y().environment,t=y().files){let n=e.ANDROID_HOME||e.ANDROID_SDK_ROOT,r=await is(n,t),i=await xt(`adb`,[`version`]);return i?es({license:r,sdkRoot:n,versionLine:i}):rs(n,r)}async function qo(e,t){if(e.platform!==`android`)return[];let n=x(e,t.transportOverrides.androidAdb),r=[];return t.shouldProbeMetro&&r.push(await $o(n,e.id,t.metroPort)),r.push(await Jo(n,e)),r}async function Jo(e,t){try{let n=await G(e),r=Io(t);return n===await Yo()&&!r?await Xo(e,t,n):Zo(t,n,r)}catch(e){return Qo(e)}}async function Yo(){try{return(await _o()).manifest.serviceComponent}catch{return}}async function Xo(e,t,n){let r=(await e([`shell`,`settings`,`get`,`secure`,ko.previousIme],{allowFailure:!0,timeoutMs:Go})).stdout.trim(),i=r&&r!==`null`?r:void 0;return{id:`android-test-ime`,status:`fail`,summary:`Android test IME helper is the active input method on ${t.id}, but no active session owns it -- likely left over from a crashed session.`,hint:`A stuck test IME leaves the real keyboard unavailable on this device until restored.`,command:i?`adb -s ${t.id} shell ime set ${i}`:`adb -s ${t.id} shell ime list -s`,evidence:{currentIme:n,previousIme:i}}}function Zo(e,t,n){return{id:`android-test-ime`,status:`pass`,summary:n?`Android test IME helper is active for this session on ${e.id}.`:`Android test IME helper is not active on ${e.id}; the device's normal IME is in use.`,evidence:{currentIme:t}}}function Qo(e){let t=n(e);return{id:`android-test-ime`,status:`warn`,summary:`Could not inspect the Android test IME helper state.`,hint:t.message,evidence:{code:t.code}}}async function $o(e,t,r){try{let n=await e([`reverse`,`--list`],{allowFailure:!0,timeoutMs:Go}),i=`tcp:${r} tcp:${r}`,a=n.stdout.includes(i);return{id:`android-reverse`,status:a?`pass`:`warn`,summary:a?`Android adb reverse exists for Metro port ${r}.`:`Android adb reverse is missing for Metro port ${r}.`,command:a?void 0:`adb -s ${t} reverse tcp:${r} tcp:${r}`,evidence:{stdout:n.stdout.trim()}}}catch(e){let t=n(e);return{id:`android-reverse`,status:`warn`,summary:`Could not inspect Android adb reverse mappings.`,hint:t.message,evidence:{code:t.code}}}}function es(e){return{id:`toolchain`,status:ts(e),summary:e.versionLine?`Android toolchain: ${e.versionLine}; ${ns(e.sdkRoot)}.`:`Android toolchain: adb is present but version check failed.`,hint:e.license===`missing`?`Accept Android SDK licenses before installing/building apps.`:void 0,command:e.license===`missing`?`sdkmanager --licenses`:void 0,evidence:{adbVersion:e.versionLine??null,androidHome:e.sdkRoot??null,license:e.license}}}function ts(e){return e.versionLine&&e.sdkRoot&&e.license!==`missing`?`pass`:`info`}function ns(e){return e?`ANDROID_HOME/ANDROID_SDK_ROOT set`:`ANDROID_HOME unset`}function rs(e,t){return{id:`toolchain`,status:`info`,summary:`Android toolchain: adb not found on PATH.`,hint:`Install Android platform-tools or add adb to PATH.`,evidence:{androidHome:e??null,license:t}}}async function is(e,t){if(!e)return`unknown`;try{return await t.access(w.join(e,`licenses`,`android-sdk-license`)),`accepted`}catch{return`missing`}}function as(e,t){if(!t)return{expected:e,actual:null,failureReason:`text_mismatch`,targetInput:null,actualInput:null};let n=ls(t),r={failureReason:t.reason??`text_mismatch`,targetInput:ss(t.targetInput),actualInput:ss(t.actualInput)};return n?{...r,expectedLength:Array.from(e).length,actual:null,masked:!0,actualLength:Array.from(t.actual??``).length}:{...r,expected:e,actual:t.actual}}function J(e){return e?e.password?!0:os(e.text):!1}function os(e){return e?Array.from(e).every(cs):!1}function ss(e){if(!e)return null;let t=J(e);return{...e,text:t?null:e.text,...t?{textRedacted:!0}:{}}}function cs(e){return e===`•`||e===`*`||e===`●`}function ls(e){return e.masked===!0||J(e.targetInput)||J(e.actualInput)}const us=new WeakMap;function ds(e,t){return t&&us.set(e,t),e}function fs(e){return us.get(e)}function ps(e){return e.clickable}function ms(e){return e.focusable||e.focused===!0}function Y(e){return ps(e)||ms(e)}function hs(e){let t=e.trim();return t?/^[\w.]+:id\/[\w.-]+$/i.test(t):!1}function gs(e,t){return{raw:e,...t?{effectiveRect:t}:{}}}function _s(e,t,n){if(!e)return;let r=bs(e);return t&&(r=ys(r,t)),n&&(r=ys(r,n)),r}function vs(e){return{...e.raw,...e.effectiveRect?{rect:e.effectiveRect}:{rect:void 0},hittable:e.raw.hittable===!0&&ae(e.effectiveRect)?!0:void 0}}function ys(e,t){let n=Math.max(e.x,t.x),r=Math.max(e.y,t.y),i=Math.min(e.x+e.width,t.x+t.width),a=Math.min(e.y+e.height,t.y+t.height),o=i>n&&a>r;return{x:o?n:e.x,y:o?r:e.y,width:o?i-n:0,height:o?a-r:0}}function bs(e){return{x:e.x,y:e.y,width:Math.max(0,e.width),height:Math.max(0,e.height)}}function xs(e,t){let n=new Set;return Ss(e,n,t),ws(e,n,t),n}function Ss(e,t,n){for(let r of e.children){if(n?.check(`work`),r.visibleToUser===!1){t.add(r);continue}Ss(r,t,n)}}function Cs(e,t,n){return n?.check(`work`),e.children.filter(e=>!t.has(e)&&e.visibleToUser!==!1)}function ws(e,t,n){let r=Cs(e,t,n).filter(Es);if(r.length<2)return;let i=r.filter(e=>Ds(e)&&Os(e));if(i.length===0)return;let a=Ts(i);for(let r of Cs(e,t,n))n?.check(`work`),Ds(r)&&(Os(r)&&(a===void 0||r.windowLayer===a)||t.add(r))}function Ts(e){let t=e.map(e=>e.windowLayer).filter(e=>e!==void 0);return t.length>0?Math.max(...t):void 0}function Es(e){return e.windowIndex!==void 0||e.windowType!==void 0}function Ds(e){return e.windowType===1}function Os(e){return e.windowActive===!0||e.windowFocused===!0}function ks(e,t,n,r,i){let a=new Set(e.sourceNodes),o=js(t,i),s=As(o,n,Ms(o,a,i),i);if(!s)return{nodes:[],sourceNodes:[]};let c=new Set(js([s],i)),l=[];for(let[t,n]of e.sourceNodes.entries())i.check(`work`),c.has(n)&&l.push(t);if(l.length===0)return{nodes:[],sourceNodes:[]};let u=1/0;for(let t of l)i.check(`work`),u=Math.min(u,e.nodes[t]?.depth??0);let d=[];for(let t of l)i.check(`work`),(e.nodes[t]?.depth??0)-u<=r&&d.push(t);return i.consume(d.length),{nodes:oe(d.map(t=>e.nodes[t]),u),sourceNodes:d.map(t=>e.sourceNodes[t])}}function As(e,t,n,r){for(let i of e)if(r.check(`work`),se(i,t)&&n.has(i))return i;return null}function js(e,t){let n=[],r=[...e].reverse();for(;r.length>0;){t.check(`work`);let e=r.pop();n.push(e);for(let n=e.children.length-1;n>=0;--n)t.check(`work`),r.push(e.children[n])}return n}function Ms(e,t,n){let r=new Set;for(let i=e.length-1;i>=0;--i){n.check(`work`);let a=e[i];if(t.has(a)){r.add(a);continue}for(let e of a.children)if(n.check(`work`),r.has(e)){r.add(a);break}}return r}function Ns(e,t,n,r,i){if(e.visibleToUser===!1)return!1;let a=Ps(e);return t.interactiveOnly?Fs(e,a,n,r,i):a.isStructural||a.isVisual?Rs(e,a,r):!0}function Ps(e){let t=Bs(e.type),n=!!(e.label&&e.label.trim().length>0),r=!!(e.identifier&&e.identifier.trim().length>0);return{type:t,hasMeaningfulText:n&&!hs(e.label??``),hasMeaningfulId:r&&!hs(e.identifier??``),isStructural:Vs(t),isVisual:t===`imageview`||t===`imagebutton`}}function Fs(e,t,n,r,i){return Ls(e)?!1:Y(e)||ne(t.type)&&r?!0:Is(t,n,r,i)}function Is(e,t,n,r){return!e.hasMeaningfulText&&!e.hasMeaningfulId||e.isVisual||e.isStructural&&!r&&!t?!1:t||n||r}function Ls(e){return!!(e.rect&&(e.rect.width<=0||e.rect.height<=0))}function Rs(e,t,n){return Y(e)||t.hasMeaningfulText||t.hasMeaningfulId?!0:n}function zs(e){if(!e)return!1;let t=Bs(e);return t.includes(`recyclerview`)||t.includes(`listview`)||t.includes(`gridview`)}function Bs(e){return e?e.toLowerCase():``}function Vs(e){let t=e.split(`.`).pop()??e;return t.includes(`layout`)||t===`viewgroup`||t===`view`}function Hs(e,t,n,r){return{...gs(e,t),...n?{clipsDescendants:!0}:{},...r?{windowRect:r}:{}}}const Us=`ANDROID_SNAPSHOT_PRESENTATION_FAILED`;var X=class extends Error{code=Us;qualityReasonCode=`presentation-failed`;details;analysis;constructor(e,t,n){super(e),this.name=`AndroidSnapshotPresentationFailure`,this.details=t,this.analysis=n}};function Ws(e){return e instanceof X?e.code===Us:!!(e&&typeof e==`object`&&e.code===Us)}var Gs=class{workUnits=0;options;defaultMaxWorkUnits;deadlineAtMs;constructor(e,t){this.options=e,this.defaultMaxWorkUnits=t;let n=e.now??Date.now;this.deadlineAtMs=e.deadlineAtMs??n()+Xs()}get workUnitCount(){return this.workUnits}check(e){this.consume(1)}consume(e){this.workUnits+=e;let t=this.options.maxWorkUnits??this.defaultMaxWorkUnits;if(this.workUnits>t)throw new X(`Android snapshot presentation exceeded its linear work budget`,{phase:`complexity`,workUnits:this.workUnits,maxWorkUnits:t});if((this.options.now??Date.now)()>=this.deadlineAtMs)throw new X(`Android snapshot presentation exceeded its cooperative deadline`,{phase:`deadline`,workUnits:this.workUnits,deadlineAtMs:this.deadlineAtMs,maxWorkUnits:t})}};function Ks(e,t){return new Gs(e??{},t)}function qs(e,t,n){let r=new Map;for(let i of e){n.check(`regular-invariant`);let e=Js(i,r,t),a=i.effectiveRect;if(!a||!ae(a)){if(vs(i).hittable===!0)throw new X(`Android regular snapshot node ${i.raw.index} with degenerate effective geometry was marked hittable`,{phase:`regular-invariant`,workUnits:n.workUnitCount,nodeIndex:i.raw.index,frame:a});r.set(i.raw.index,e);continue}if(e&&!Ys(a,e))throw new X(`Android regular snapshot node ${i.raw.index} escaped its cumulative clip`,{phase:`regular-invariant`,workUnits:n.workUnitCount,nodeIndex:i.raw.index,frame:a,clip:e});r.set(i.raw.index,i.clipsDescendants?a:e)}}function Js(e,t,n){let r=e.raw.parentIndex;return r===void 0?e.windowRect??n:t.get(r)??e.windowRect??n}function Ys(e,t){let n=1e-4;return e.x>=t.x-n&&e.y>=t.y-n&&e.x+e.width<=t.x+t.width+n&&e.y+e.height<=t.y+t.height+n}function Xs(){return 250}function Zs(e,t,n){let r=n.depth??1/0,i=ce(n.scope),a=hc(e),o=Ks(n.androidPresentation,Math.max(1024,a.rawNodeCount*128)),s={nodes:[],sourceNodes:[],...t===void 0?{}:{maxNodes:t},maxDepth:i?1/0:r,options:n,analysis:a,interactiveDescendantMemo:new Map,hidden:new Set,presentationBudget:o,presentationNodes:[],truncated:!1};try{o.check(`work`),s.viewport=cc(e,o),s.hidden=n.raw?new Set:xs(e,o);for(let t of e.children)if($s(s,t,0),s.truncated)break;n.raw||qs(s.presentationNodes,s.viewport,o);let t=s.nodes,a=new Map(s.sourceNodes.map((e,t)=>[e,t])),{nodes:c,sourceNodes:l}=i?ks(s,e.children,i,r,o):s,u={nodes:c,sourceNodes:l,occlusionContext:{nodes:t,sourceIndexByNodeIndex:new Map(l.flatMap((e,t)=>{let n=a.get(e),r=c[t]?.index;return n===void 0||r===void 0?[]:[[r,n]]})),androidSiblingOrderByNodeIndex:Qs(s.sourceNodes)},analysis:s.analysis};return s.truncated?{...u,truncated:!0}:u}catch(e){throw Ws(e)&&(e.analysis??=s.analysis),e}}function Qs(e){let t=new Map,n=new Map;for(let[r,i]of e.entries()){let e=fs(i);if(!e)continue;let a=t.get(e.parent);a===void 0&&(a=t.size,t.set(e.parent,a)),n.set(r,{group:a,order:e.order})}return n}function $s(e,t,n,r,i=!1,a=!1,o=!1,s,c){if(e.presentationBudget.check(`work`),ec(e,t,n))return;let l=t.windowRect??s??e.viewport,u=tc(e,t,c,l),d=nc(e,t,r,i,a,o,u,l),f=i||Y(t),p=a||zs(t.type),ee=rc(e,t,u,c);ic(e,t,n,d,f,p,o||Ye(t.identifier),l,ee)}function ec(e,t,n){return e.maxNodes!==void 0&&e.nodes.length>=e.maxNodes?(e.truncated=!0,!0):n>e.maxDepth||e.hidden.has(t)}function tc(e,t,n,r){return e.options.raw?t.rect:_s(t.rect,r,n)}function nc(e,t,n,r,i,a,o,s){return!e.options.raw&&!Ns(t,e.options,r,dc(e,t),i)?n:ac(e,t,n,a||Ye(t.identifier),o,s)}function rc(e,t,n,r){return e.options.raw||!lc(t)?r:n}function ic(e,t,n,r,i,a,o,s,c){for(let l of t.children)if($s(e,l,n+1,r,i,a,o,s,c),e.truncated)return}function ac(e,t,n,r,i,a){let o=e.nodes.length;return e.sourceNodes.push(t),sc(e,t,oc(e,t,n,r),i,a),o}function oc(e,t,n,r){return{index:e.nodes.length,type:t.type??void 0,label:t.label??void 0,value:t.value??void 0,identifier:t.identifier??void 0,bundleId:t.packageName??void 0,rect:t.rect,enabled:t.enabled,focused:t.focused,selected:t.selected,editable:t.editable,password:t.password,hintShowing:t.hintShowing,selectionStart:t.selectionStart,selectionEnd:t.selectionEnd,visibleToUser:t.visibleToUser,hittable:Y(t)||void 0,depth:uc(e.nodes,n),parentIndex:n,...fc(t,e.hidden),...r?{systemChrome:!0}:{}}}function sc(e,t,n,r,i){let a=Hs(n,r,!e.options.raw&&lc(t),i);e.presentationNodes.push(a),e.nodes.push(e.options.raw?a.raw:vs(a))}function cc(e,t){let n=[],r=[...e.children];for(;r.length>0;){t.check(`work`);let e=r.pop();ae(e.windowRect)&&n.push(e.windowRect),r.push(...e.children)}return ie(n)??void 0}function lc(e){return e.scrollable===!0&&ne(e.type)}function uc(e,t){return t===void 0?0:(e[t]?.depth??-1)+1}function dc(e,t){let n=e.interactiveDescendantMemo.get(t);if(n!==void 0)return n;for(let n of t.children)if(!e.hidden.has(n)&&n.visibleToUser!==!1&&(Y(n)||dc(e,n)))return e.interactiveDescendantMemo.set(t,!0),!0;return e.interactiveDescendantMemo.set(t,!1),!1}function fc(e,t){return pc(e,t)?{...e.canScrollBackward?{hiddenContentAbove:!0}:{},...e.canScrollForward?{hiddenContentBelow:!0}:{}}:{}}function pc(e,t){if(!e.scrollable||!ne(e.type)||`${e.type??``}`.toLowerCase().includes(`horizontalscrollview`))return!1;let n=mc(e,t);return!(n&&n.horizontal>n.vertical&&n.horizontal>16)}function mc(e,t){let n=e.children.filter(e=>!t.has(e)&&e.visibleToUser!==!1);if(!e.rect||n.length===0)return null;let r=n.map(e=>e.rect).filter(e=>e!==void 0);if(r.length===0)return null;let i=Math.min(...r.map(e=>e.x)),a=Math.max(...r.map(e=>e.x+e.width)),o=Math.min(...r.map(e=>e.y)),s=Math.max(...r.map(e=>e.y+e.height));return{horizontal:Math.max(0,a-i-e.rect.width),vertical:Math.max(0,s-o-e.rect.height)}}function hc(e){let t=0,n=0,r=[...e.children];for(;r.length>0;){let e=r.pop();t+=1,n=Math.max(n,e.depth),r.push(...e.children)}return{rawNodeCount:t,maxDepth:n}}function gc(){let e=[],t=()=>e.at(-1)===!0;return{open(n,r){let i=t()||Ye(n);return r||e.push(i),i},close(){e.pop()}}}function*_c(e){let t=/<node\b[^>]*>|<\/node>/g,n=gc(),r=t.exec(e);for(;r;){let i=r[0];if(i.startsWith(`</node`))n.close();else{let e=vc(i);yield n.open(e.resourceId,i.endsWith(`/>`))?{...e,systemChrome:!0}:e}r=t.exec(e)}}function vc(e){let t=yc(e),n=Ct(t.bounds);return{...t,...n?{rect:n}:{}}}function yc(e){let t=bc(e),n=e=>Oc(t,e),r=e=>{let t=n(e);if(t!==null)return t===`true`},i=e=>{let t=n(e);if(t===null||t.trim()===``)return;let r=Number(t);return Number.isFinite(r)?r:void 0},a=(e,t)=>{let n=i(t);return n===void 0?{}:{[e]:n}},o=(e,t)=>{let r=Ct(n(t));return r===void 0?{}:{[e]:r}},s=(e,t)=>{let n=r(t);return n===void 0?{}:{[e]:n}};return{text:n(`text`),desc:n(`content-desc`),resourceId:n(`resource-id`),packageName:n(`package`),className:n(`class`),bounds:n(`bounds`),clickable:r(`clickable`),enabled:r(`enabled`),focusable:r(`focusable`),focused:r(`focused`),password:r(`password`),...s(`editable`,`editable`),...a(`selectionStart`,`selection-start`),...a(`selectionEnd`,`selection-end`),...s(`hintShowing`,`hint-showing`),...s(`visibleToUser`,`visible-to-user`),...s(`selected`,`selected`),...a(`drawingOrder`,`drawing-order`),...s(`scrollable`,`scrollable`),...s(`canScrollForward`,`can-scroll-forward`),...s(`canScrollBackward`,`can-scroll-backward`),...a(`windowIndex`,`window-index`),...a(`windowType`,`window-type`),...a(`windowLayer`,`window-layer`),...s(`windowActive`,`window-active`),...s(`windowFocused`,`window-focused`),...o(`windowRect`,`window-bounds`)}}function bc(e){let t=new Map,n=e.indexOf(` `),r=e.lastIndexOf(`>`);if(n<0||r<=n)return t;let i=n;for(;i<r;){let n=xc(e,i,r);if(!n)break;t.set(n.name,n.value),i=n.nextCursor}return t}function xc(e,t,n){if(t=Cc(e,t,n),t>=n||wc(e[t]))return;let r=t;t=Sc(e,t,n);let i=e.slice(r,t);if(t=Cc(e,t,n),!i||e[t]!==`=`)return;t=Cc(e,t+1,n);let a=e[t];if(!Tc(a))return;let o=t+1,s=e.indexOf(a,o);if(!(s<0||s>=n))return{name:i,value:wt(e.slice(o,s)),nextCursor:s+1}}function Sc(e,t,n){for(;t<n&&!Dc(e[t]??``);)t+=1;return t}function Cc(e,t,n){for(;t<n&&Ec(e[t]??``);)t+=1;return t}function wc(e){return e===`/`||e===`>`}function Tc(e){return e===`"`||e===`'`}function Ec(e){return e===` `||e===`
12
+ `||e===`\r`||e===` `}function Dc(e){return e===`=`||e===`/`||e===`>`||Ec(e)}function Oc(e,t){return e.get(t)??null}function kc(e){let t={type:null,label:null,value:null,identifier:null,packageName:null,clickable:!1,focusable:!1,depth:-1,children:[]},n=[t],r=/<node\b[^>]*>|<\/node>/g,i=r.exec(e);for(;i;){let t=i[0];if(t.startsWith(`</node`)){n.length>1&&n.pop(),i=r.exec(e);continue}let a=vc(t),o=n.at(-1),s=Ac(a,o.depth+1,o);o.children.push(s),t.endsWith(`/>`)||n.push(s),i=r.exec(e)}return t}function Ac(e,t,n){return ds({type:e.className,label:e.text||e.desc,value:e.text,identifier:e.resourceId,packageName:e.packageName,rect:e.rect,enabled:e.enabled,focused:e.focused,selected:e.selected,editable:e.editable,password:e.password,hintShowing:e.hintShowing,selectionStart:e.selectionStart,selectionEnd:e.selectionEnd,visibleToUser:e.visibleToUser,clickable:e.clickable===!0,focusable:e.focusable===!0,scrollable:e.scrollable,canScrollForward:e.canScrollForward,canScrollBackward:e.canScrollBackward,windowIndex:e.windowIndex,windowType:e.windowType,windowLayer:e.windowLayer,windowActive:e.windowActive,windowFocused:e.windowFocused,windowRect:e.windowRect,depth:t,parentIndex:void 0,children:[]},e.drawingOrder===void 0?void 0:{parent:n,order:e.drawingOrder})}function jc(e){let t=new Map;return e.nodes.forEach((n,r)=>{t.set(n.index,e.sourceNodes[r]?.clickable)}),{kind:`exact`,provider:`android-helper`,clickableByNodeIndex:t}}const Mc=new Set([`android`,`com.android.systemui`]);function Nc(e,t,n={}){if(t.backend!==`android-helper`)return{outcome:`ok`};let r=Wc(e,n.foregroundAppPackage);return Ic(r,t)?Pc(r,t,`empty-helper-output`,`Android snapshot helper returned no accessibility nodes`):Hc(r)?{outcome:`ok`}:Fc(r)?{outcome:`system-surface-only`}:Lc(r)?{outcome:`ok`}:Rc(r)?Pc(r,t,`content-poor-app-window`,`Android snapshot helper returned insufficient foreground app content`):zc(r)||Bc(r,t)?Pc(r,t,`content-poor-app-window`,`Android snapshot helper returned insufficient application window content`):Vc(r)?Pc(r,t,`system-window-only`,`Android snapshot helper returned only non-application windows`):{outcome:`ok`}}function Pc(e,t,n,r){return{outcome:`unusable`,decision:Uc(e,t,n,r)}}function Fc(e){return e.windowRootCount>0&&e.applicationWindowRootCount===0&&e.activeSystemSurfaceMeaningfulNodeCount>=3}function Ic(e,t){return e.nodeCount===0||t.nodeCount===0||t.rootPresent===!1}function Lc(e){return Rc(e)&&e.inputMethodMeaningfulNodeCount>=2}function Rc(e){let t=e.foregroundAppMeaningfulNodeCount;return t===void 0?!1:t===0?e.applicationMeaningfulNodeCount<2:t<2&&e.meaningfulNodeCount>t}function zc(e){return e.foregroundAppMeaningfulNodeCount===void 0&&e.applicationWindowRootCount>0&&e.applicationMeaningfulNodeCount<2}function Bc(e,t){return e.foregroundAppMeaningfulNodeCount===void 0&&e.windowRootCount===0&&(t.windowCount??0)>1&&e.nonSystemMeaningfulNodeCount<2}function Vc(e){return e.windowRootCount>0&&e.applicationWindowRootCount===0||e.windowRootCount===0&&e.nodeCount>0&&e.systemUiNodeCount===e.nodeCount}function Hc(e){return e.hasAlertButtonIdentifier&&e.hasAlertContentIdentifier}function Uc(e,t,n,r){return{reason:n,failureReason:r,diagnostics:il(e,t)}}function Wc(e,t){let n=Gc(t);for(let t of _c(e))Kc(n,t);return $c(n)}function Gc(e){return{nodeCount:0,systemUiNodeCount:0,windowRootCount:0,applicationWindowRootCount:0,activeSystemSurfaceMeaningfulNodeCount:0,meaningfulNodeCount:0,applicationMeaningfulNodeCount:0,nonSystemMeaningfulNodeCount:0,inputMethodMeaningfulNodeCount:0,hasAlertButtonIdentifier:!1,hasAlertContentIdentifier:!1,...e===void 0?{}:{foregroundAppPackage:e,foregroundAppMeaningfulNodeCount:0},windowTypes:new Set}}function Kc(e,t){e.nodeCount+=1,rl(t.packageName)&&(e.systemUiNodeCount+=1),t.visibleToUser!==!1&&qc(e,t.resourceId),Jc(e,t),Yc(e,t)}function qc(e,t){let n=Ht(t);n===`button`&&(e.hasAlertButtonIdentifier=!0),n===`content`&&(e.hasAlertContentIdentifier=!0)}function Jc(e,t){t.windowType!==void 0&&(e.currentWindowType=t.windowType,e.currentWindowActiveOrFocused=t.windowActive===!0||t.windowFocused===!0,e.windowRootCount+=1,e.windowTypes.add(t.windowType),t.windowType===1&&(e.applicationWindowRootCount+=1))}function Yc(e,t){el(t)&&(e.meaningfulNodeCount+=1,Xc(e,t),Qc(e,t))}function Xc(e,t){e.currentWindowType===1&&!nl(t.packageName)&&(e.applicationMeaningfulNodeCount+=1),Zc(e)&&!Je(t)&&(e.activeSystemSurfaceMeaningfulNodeCount+=1)}function Zc(e){return e.currentWindowType!==void 0&&e.currentWindowType!==1&&e.currentWindowActiveOrFocused===!0}function Qc(e,t){nl(t.packageName)||(e.nonSystemMeaningfulNodeCount+=1),p({packageName:t.packageName,resourceId:t.resourceId})&&(e.inputMethodMeaningfulNodeCount+=1),e.foregroundAppPackage!==void 0&&t.packageName===e.foregroundAppPackage&&(e.foregroundAppMeaningfulNodeCount=(e.foregroundAppMeaningfulNodeCount??0)+1)}function $c(e){return{nodeCount:e.nodeCount,systemUiNodeCount:e.systemUiNodeCount,windowRootCount:e.windowRootCount,applicationWindowRootCount:e.applicationWindowRootCount,activeSystemSurfaceMeaningfulNodeCount:e.activeSystemSurfaceMeaningfulNodeCount,meaningfulNodeCount:e.meaningfulNodeCount,applicationMeaningfulNodeCount:e.applicationMeaningfulNodeCount,nonSystemMeaningfulNodeCount:e.nonSystemMeaningfulNodeCount,inputMethodMeaningfulNodeCount:e.inputMethodMeaningfulNodeCount,hasAlertButtonIdentifier:e.hasAlertButtonIdentifier,hasAlertContentIdentifier:e.hasAlertContentIdentifier,...e.foregroundAppPackage===void 0?{}:{foregroundAppPackage:e.foregroundAppPackage,foregroundAppMeaningfulNodeCount:e.foregroundAppMeaningfulNodeCount??0},windowTypes:[...e.windowTypes].sort((e,t)=>e-t).slice(0,8)}}function el(e){return e.visibleToUser===!1?!1:tl(e.text)||tl(e.desc)||tl(e.resourceId)}function tl(e){return e!==null&&e.trim()!==``}function nl(e){return e===null||Mc.has(e)}function rl(e){return e!==null&&Mc.has(e)}function il(e,t){return{helperNodeCount:e.nodeCount,helperSystemUiNodeCount:e.systemUiNodeCount,helperWindowRootCount:e.windowRootCount,helperApplicationWindowRootCount:e.applicationWindowRootCount,helperMeaningfulNodeCount:e.meaningfulNodeCount,helperApplicationMeaningfulNodeCount:e.applicationMeaningfulNodeCount,helperNonSystemMeaningfulNodeCount:e.nonSystemMeaningfulNodeCount,helperInputMethodMeaningfulNodeCount:e.inputMethodMeaningfulNodeCount,...e.foregroundAppPackage===void 0?{}:{helperForegroundAppPackage:e.foregroundAppPackage,helperForegroundAppMeaningfulNodeCount:e.foregroundAppMeaningfulNodeCount,helperForegroundAppMeaningfulNodeThreshold:2},helperWindowTypes:e.windowTypes,...t.captureMode?{helperCaptureMode:t.captureMode}:{}}}async function al(e){let t=await B(e.deviceKey,{resetRuntime:!0,signal:e.signal,cause:e.cause});e.signal?.throwIfAborted(),t||await ol(e.adb,e.packageName)}async function ol(e,t){await F({adb:e,packageName:t}),await g(150),h({level:`debug`,phase:`android_snapshot_helper_runtime_reset`,data:{packageName:t}})}const sl=Symbol(`androidSnapshotCaptureEvidence`);function cl(e,t){return Object.defineProperty(e,sl,{value:t}),e}function ll(e){let t={...e,backend:`android`,producer:`android-uiautomator`},n=e[sl];return te(t,n.clickability),n.occlusionContext&&l(t,n.occlusionContext),t}async function ul(e,t={}){let n=S(e,t.helperAdb).exec;return(await vl(e,t,n)).xml}async function dl(e,t={}){let n=S(e,t.helperAdb).exec,r=await vl(e,t,n),i=r.xml,a=kc(i),o=ml(r.metadata,a),s={...t,androidPresentation:{...t.androidPresentation,deadlineAtMs:t.androidPresentation?.deadlineAtMs??Date.now()+250}};try{let e=Zs(a,void 0,s),n=pl(e.truncated,r.metadata);t.interactiveOnly&&t.includeHiddenContentHints!==!1&&_l({options:s,tree:a,xml:i,interactiveSnapshot:e});let{sourceNodes:c,occlusionContext:l,...u}=e;return cl({...u,...gl(n),androidSnapshot:o,quality:{state:`healthy`,backend:`android-helper`}},{clickability:jc(e),occlusionContext:l})}catch(e){if(!Ws(e))throw e;return fl({failure:e,androidSnapshot:o})}}function fl(e){return cl({nodes:[],truncated:!0,analysis:e.failure.analysis??{rawNodeCount:0,maxDepth:0},androidSnapshot:{...e.androidSnapshot,presentationFailure:{phase:e.failure.details.phase,workUnits:e.failure.details.workUnits,...e.failure.details.maxWorkUnits===void 0?{}:{maxWorkUnits:e.failure.details.maxWorkUnits}}},quality:{state:`sparse`,backend:`android-helper`,reason:e.failure.message,reasonCode:e.failure.qualityReasonCode}},{clickability:{kind:`exact`,provider:`android-helper`,clickableByNodeIndex:new Map}})}function pl(e,t){return e===!0||t.helperTruncated===!0||e}function ml(e,t){return hl(t)===!1?{...e,occlusionScanUnavailable:!0}:e}function hl(e){let t=[...e.children];if(t.length!==0){for(;t.length>0;){let e=t.pop();if(fs(e)!==void 0)return!0;t.push(...e.children)}return!1}}function gl(e){return e===!0?{truncated:!0}:{}}function _l(e){if(Il(e.interactiveSnapshot.nodes).size>0||Fl(e.xml))return;let t=Zs(e.tree,void 0,{...e.options,interactiveOnly:!1});Ll(_e(r(t.nodes)),t,e.interactiveSnapshot)}async function vl(e,t,n){let r=S(e,t.helperAdb),i=await m(`android_snapshot_helper_artifact_resolution`,async()=>await Nl(t.helperArtifact??r.snapshotHelperArtifact));if(i.artifact)return await yl(e,t,n,i.artifact);throw h({level:`error`,phase:`android_snapshot_helper_unavailable`,data:{reason:i.errorReason??`artifact_not_found`}}),Pl(i.errorReason)}async function yl(e,t,n,r){let i=jr(e),a=S(e,t.helperAdb),o=t.helperSessionScope!==`daemon-session`;try{let e;for(let o=0;;o+=1){o>0&&await wl(t.signal);let s=await Cl({options:t,adb:n,adbProvider:a,artifact:r,helperDeviceKey:i,attempt:o,previousContentReason:e});if(s.outcome===`captured`)return s.capture;if(o+1>=3)return await Tl({contentRecovery:s.decision,attempts:o+1,helperDeviceKey:i,artifact:r,adb:n,signal:t.signal});e=s.decision.reason}}finally{o&&await B(i)}}async function bl(e,t,n,r,i){let a=await m(`android_snapshot_helper_install`,async()=>await Jn({adb:t,adbProvider:n,artifact:r,deviceKey:i,installPolicy:e.helperInstallPolicy,timeoutMs:3e4,signal:e.signal}),{packageName:r.manifest.packageName,versionCode:r.manifest.versionCode,installPolicy:e.helperInstallPolicy??`missing-or-outdated`});return h({phase:`android_snapshot_helper_install_decision`,data:{packageName:a.packageName,versionCode:a.versionCode,installedVersionCode:a.installedVersionCode,artifactSha256:r.manifest.sha256,installedSha256:a.installedSha256,installed:a.installed,reason:a.reason}}),a}async function xl(e){let{signal:t,adb:r,adbProvider:i,artifact:a,helperDeviceKey:o}=e,s=qr({adb:r,adbProvider:i,artifact:a,deviceKey:o,signal:t});try{let e=await m(`android_snapshot_helper_session_capture`,async()=>await Ni(s),{packageName:a.manifest.packageName,version:a.manifest.version,timeoutMs:Pn});if(e)return e}catch(e){if(t?.throwIfAborted(),Fr(e))throw e;h({level:`warn`,phase:`android_snapshot_helper_session_fallback`,data:{reason:n(e).message}}),await ol(r,a.manifest.packageName)}return await m(`android_snapshot_helper_capture`,async()=>await Kr(s),{packageName:a.manifest.packageName,version:a.manifest.version,timeoutMs:Pn,commandTimeoutMs:Fn})}function Sl(e,t,n){return{xml:e.xml,metadata:{backend:`android-helper`,helperVersion:t.manifest.version,helperApiVersion:e.metadata.helperApiVersion,helperTransport:e.metadata.transport,helperSessionReused:e.metadata.sessionReused,installReason:n,waitForIdleTimeoutMs:e.metadata.waitForIdleTimeoutMs,waitForIdleQuietMs:e.metadata.waitForIdleQuietMs,timeoutMs:e.metadata.timeoutMs,maxDepth:e.metadata.maxDepth,maxNodes:e.metadata.maxNodes,rootPresent:e.metadata.rootPresent,captureMode:e.metadata.captureMode,windowCount:e.metadata.windowCount,nodeCount:e.metadata.nodeCount,helperTruncated:e.metadata.truncated,elapsedMs:e.metadata.elapsedMs}}}async function Cl(e){let{options:t,adb:n,adbProvider:r,artifact:i,helperDeviceKey:a,attempt:o}=e,s;try{let e=await bl(t,n,r,i,a);e.installed&&await B(a),s=Sl(await xl({signal:t.signal,adb:n,adbProvider:r,artifact:i,helperDeviceKey:a}),i,e.reason)}catch(e){return t.signal?.throwIfAborted(),{outcome:`captured`,capture:await El({error:e,helperDeviceKey:a,artifact:i,adb:n})}}let c=Nc(s.xml,s.metadata,{foregroundAppPackage:t.appBundleId});if(c.outcome===`unusable`)return{outcome:`unusable`,decision:c.decision};let l=c.outcome===`system-surface-only`;return!l&&o>0&&h({phase:`android_snapshot_helper_content_recaptured`,data:{attempts:o+1,recoveredFromReason:e.previousContentReason}}),{outcome:`captured`,capture:{xml:s.xml,metadata:l?{...s.metadata,systemSurfaceOnly:!0}:s.metadata}}}async function wl(e){e?.throwIfAborted(),await g(250),e?.throwIfAborted()}async function Tl(e){throw h({level:`error`,phase:`android_snapshot_helper_content_invalid`,data:{reason:e.contentRecovery.reason,failureReason:e.contentRecovery.failureReason,attempts:e.attempts,...e.contentRecovery.diagnostics}}),await al({adb:e.adb,deviceKey:e.helperDeviceKey,packageName:e.artifact.manifest.packageName,signal:e.signal,cause:e.contentRecovery.failureReason}),new t(`COMMAND_FAILED`,e.contentRecovery.failureReason,{...e.contentRecovery.diagnostics,androidSnapshotHelperFailureReason:e.contentRecovery.reason,attempts:e.attempts,retriable:!0,hint:`Retry after the app UI stabilizes. If this persists, capture a screenshot and report the helper diagnostics; agent-device does not substitute a second snapshot engine.`})}async function El(e){let t=Dl(e.error);throw h({level:`error`,phase:`android_snapshot_helper_failed`,data:{reason:t}}),await B(e.helperDeviceKey),await ol(e.adb,e.artifact.manifest.packageName),Un({deviceKey:e.helperDeviceKey,packageName:e.artifact.manifest.packageName,versionCode:e.artifact.manifest.versionCode}),Ol(e.error,t)}function Dl(e){let t=n(e),r=Ml(t.details?.helper);if(r&&r!==t.message)return`${t.message}: ${r}`;if(r)return r;let i=(typeof t.details?.stderr==`string`?t.details.stderr.trim():``).split(/\r?\n/).find(e=>e.trim());return i?`${t.message}: ${i}`:t.message}function Ol(e,r){let i=n(e),a=kl(i);return new t(o(i.code),`Android snapshot helper failed: ${r}`,{...i.details,...jl(i),androidSnapshotHelperFailureReason:r,...a?{androidCaptureFailureReason:a}:{},hint:Al(i,a)},e)}function kl(e){return Xe(e)}function Al(e,t){return t===`accessibility-timeout`?`Android accessibility snapshots can be blocked by busy or continuously changing app UI. Use screenshot as visual truth after this timeout and report the busy UI if it persists.`:e.details?.androidSnapshotHelperInstallFailure===!0?[e.hint,`This is a device-side install failure (adb rejection or OEM policy) — the helper artifact itself is present, this is not a missing/unbuilt build.`].filter(Boolean).join(` `):e.hint??`Retry once. If the helper still fails, run agent-device doctor and report the diagnostic log; agent-device does not substitute a second snapshot engine.`}function jl(e){let t={};return e.diagnosticId!==void 0&&(t.diagnosticId=e.diagnosticId),e.logPath!==void 0&&(t.logPath=e.logPath),e.retriable!==void 0&&(t.retriable=e.retriable),e.supportedOn!==void 0&&(t.supportedOn=e.supportedOn),t}function Ml(e){if(!e||typeof e!=`object`||!(`message`in e))return;let t=String(e.message).trim();return t&&t!==`null`?t:void 0}async function Nl(e){if(e)return{artifact:e};let t=De(),r=w.join(Ee(),`android`,`snapshot-helper`,`dist`),i=w.join(r,`agent-device-android-snapshot-helper-${t}.manifest.json`);try{await y().files.access(i)}catch{return{}}try{let e=In(JSON.parse(await y().files.readText(i))),t=w.join(r,e.assetName??`agent-device-android-snapshot-helper-${e.version}.apk`);return await y().files.access(t),{artifact:{apkPath:t,manifest:e}}}catch(e){return{errorReason:n(e).message}}}function Pl(e){let n=e??`the bundled helper artifact was not found`;return new t(`COMMAND_FAILED`,`Android snapshot helper is unavailable: ${n}`,{androidSnapshotHelperFailureReason:n,hint:"Run `pnpm build:android` to build the helper dist for a source checkout — the runtime needs android/snapshot-helper/dist/agent-device-android-snapshot-helper-<version>.manifest.json and the .apk it references. Packaged installs ship these via the prepack script; if they are missing from a packaged install, reinstall agent-device."})}function Fl(e){return e.includes(` can-scroll-forward=`)||e.includes(` can-scroll-backward=`)}function Il(e){let t=new Map;for(let n of e){let e={};n.hiddenContentAbove&&(e.hiddenContentAbove=!0),n.hiddenContentBelow&&(e.hiddenContentBelow=!0),(e.hiddenContentAbove||e.hiddenContentBelow)&&t.set(n.index,e)}return t}function Ll(e,t,n){if(e.size===0)return;let r=new Map;for(let[e,t]of n.sourceNodes.entries()){let i=n.nodes[e];i&&r.set(t,i)}for(let[n,i]of e){let e=t.sourceNodes[n];if(!e)continue;let a=r.get(e);a&&(i.hiddenContentAbove&&(a.hiddenContentAbove=!0),i.hiddenContentBelow&&(a.hiddenContentBelow=!0))}}async function Rl(e,t,n,r,i={}){let a=[0,150,350],o=null,s=null,c=await ru(e);for(let l of a){l>0&&await g(l);let a=await ql(e,t,n,r,c,i);if(o=a,a.reason===`ime_capture`)return a;s=a.ok?a:null}return s??o??{ok:!1,actual:null,reason:`text_mismatch`,targetInput:null,actualInput:null}}async function zl(e,t,n,r={}){return Wl(await ul(e,r),t,n)}async function Bl(e,t,n,r){let i=await ru(e);return Jl(await ul(e,r),t,n,i).targetInput}async function Vl(e,t,n,r={}){try{return await Bl(e,t,n,r)}catch(e){return h({level:`warn`,phase:`android_fill_pre_action_target_capture_failed`,data:{error:e instanceof Error?e.message:String(e)}}),null}}function Z(e,n,r){if(r?.ok)return;let i=r?Hl(e,n,r):null;if(i)return i;throw new t(`COMMAND_FAILED`,Gl(r),Kl(e,r))}function Hl(e,t,n){let r=n.targetInput,i=n.actualInput;if(e.length===0||n.reason===`ime_capture`||!t||!r||!i||J(t)||J(r)||J(i)||!lu(t,r)||!lu(t,i)||t.text===n.actual)return null;let a=uu(t);return h({level:`warn`,phase:`android_fill_verification_unconfirmed`,data:{target:a}}),{verification:`unconfirmed`,requested:e,before:t.text,after:n.actual,target:a}}function Ul(e,t,n,r,i={}){let a=Jl(e,t,n,i);return Yl(a)?{ok:!1,actual:a.actualInput?.text??null,reason:`ime_capture`,targetInput:a.targetInput,actualInput:a.actualInput}:Xl(a,r)??Zl(a,r)}function Wl(e,t,n){return Jl(e,t,n).targetInput?.text??null}function Gl(e){return e?.reason===`ime_capture`?`Android fill input was captured by the active keyboard instead of the app field`:e?.reason===`masked_unverified`?`Android fill verification could not confirm masked text value`:`Android fill verification failed`}function Kl(e,t){let n=as(e,t);return t?.reason===`ime_capture`&&(n.hint=`The focused input belongs to the Android keyboard/IME, not the app field. Disable handwriting/stylus input or switch to a standard IME, then retry fill.`),n}async function ql(e,t,n,r,i,a){return Ul(await ul(e,a),t,n,r,i)}function Jl(e,t,n,r={}){let i={focusedEdit:null,editAtPoint:null,anyAtPoint:null};for(let a of _c(e)){let e=nu(a,r);e&&iu(i,e,t,n)}return ou(i)}function Yl(e){let{targetInput:t,actualInput:n}=e;return!t||!n||n===t?!1:n.inputMethodOwned&&!t.inputMethodOwned}function Xl(e,t){let n=e.actualInput;if(!n||!cu(n))return null;let r=n.text??null,i=Array.from(Ql(n)).length,a=Array.from(t).length,o=a===0?i===0:i>0&&i===a;return{ok:o,actual:r,reason:o?void 0:`masked_unverified`,masked:!0,targetInput:e.targetInput,actualInput:n}}function Zl(e,t){let n=e.actualInput;return{ok:n!==null&&$l(Ql(n),t),actual:n?.text??null,reason:`text_mismatch`,targetInput:e.targetInput,actualInput:n}}function Ql(e){return e.hintShowing?``:e.text??``}function $l(e,t){if(e===t)return!0;if(t.length===0)return!1;let n=eu(e),r=eu(t);return!n||!r?!1:!!(n===r||tu(n,r))}function eu(e){return e.replaceAll(/\s+/g,` `).trim()}function tu(e,t){if(e.length!==t.length||e.length===0||e.slice(1)!==t.slice(1))return!1;let n=e[0],r=t[0];return!n||!r?!1:r.toLowerCase()===r&&n===r.toUpperCase()}function nu(e,t){if(!e.rect)return null;let n=e.text??``,r=Math.max(1,e.rect.width*e.rect.height);return{text:n||null,className:e.className,resourceId:e.resourceId,packageName:e.packageName,rect:e.rect,focused:e.focused??!1,password:e.password===!0,inputMethodOwned:p({packageName:e.packageName,resourceId:e.resourceId,activeInputMethodPackage:t.activeInputMethodPackage}),area:r,editText:su(e.className??``),hintShowing:e.hintShowing===!0}}async function ru(e){try{return{activeInputMethodPackage:(await V(e)).inputMethodPackage}}catch(e){return h({level:`warn`,phase:`android_fill_verification_input_method_probe_failed`,data:{error:e instanceof Error?e.message:String(e)}}),{}}}function iu(e,t,n,r){let i=re(t.rect,n,r);if(i&&t.editText&&(e.editAtPoint=au(e.editAtPoint,t)),t.focused&&t.editText){e.focusedEdit=au(e.focusedEdit,t);return}i&&t.text&&(e.anyAtPoint=au(e.anyAtPoint,t))}function au(e,t){return e&&e.area<t.area?e:t}function ou(e){let t=e.editAtPoint??e.anyAtPoint;return{targetInput:t,actualInput:(e.focusedEdit?.text?e.focusedEdit:null)??t}}function su(e){let t=e.toLowerCase();return t.includes(`edittext`)||t.includes(`textfield`)}function cu(e){return J(e)}function lu(e,t){return e.resourceId||t.resourceId?e.resourceId===t.resourceId&&e.packageName===t.packageName:e.className===t.className&&e.packageName===t.packageName&&e.rect.x===t.rect.x&&e.rect.y===t.rect.y&&e.rect.width===t.rect.width&&e.rect.height===t.rect.height}function uu(e){return{resourceId:e.resourceId,className:e.className,packageName:e.packageName,rect:e.rect}}async function du(e,t){return await Tt(t.stateDir),await Lo(t.stateDir,e.id,async()=>await pu(e,t))}function fu(e){let t=a(e).details?.hint;return{outcome:`helper-unavailable`,reason:n(e).message,...typeof t==`string`?{hint:t}:{}}}async function pu(e,t){let n=y().imeRecoveryMarkers,r=x(e),i=S(e),a=W(e),o;try{o=await go(i),await bo({adb:r,adbProvider:i,artifact:o,deviceKey:a})}catch(e){return fu(e)}let{manifest:s}=o,c=await G(r);if(c===s.serviceComponent){let i=await n.write(t.stateDir,e.id),o=await K(r);return i&&q.add(a),{outcome:`settled`,activated:!1,alreadyActive:!0,...i?{}:{persistFailed:!0},previousIme:o,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName}}let l=await K(r);if(!await Ao(r,c))return await Mo(r,l,e.id),v({level:`warn`,phase:`android_test_ime_persist_failed`,data:{device:e.id,previousIme:c}}),{outcome:`settled`,activated:!1,alreadyActive:!1,persistFailed:!0,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName};let u=(await n.read(t.stateDir)).includes(e.id);if(!await n.write(t.stateDir,e.id))return await Mo(r,l,e.id),v({level:`warn`,phase:`android_test_ime_marker_persist_failed`,data:{device:e.id,previousIme:c}}),{outcome:`settled`,activated:!1,alreadyActive:!1,persistFailed:!0,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName};await r([`shell`,`ime`,`enable`,s.serviceComponent],{allowFailure:!0,timeoutMs:1e4});let d=await r([`shell`,`ime`,`set`,s.serviceComponent],{allowFailure:!0,timeoutMs:1e4}),f=await G(r);return f===s.serviceComponent?(q.add(a),v({phase:`android_test_ime_activated`,data:{device:e.id,previousIme:c}}),{outcome:`settled`,activated:!0,alreadyActive:!1,previousIme:c,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName}):(q.delete(a),await Mo(r,l,e.id),u||await n.clear(t.stateDir,e.id),v({level:`warn`,phase:`android_test_ime_activate_failed`,data:{device:e.id,activeIme:f,stderr:d.stderr.trim()}}),{outcome:`settled`,activated:!1,alreadyActive:!1,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName})}function mu(e){return w.join(e,`android-test-ime-pending`)}function hu(e,t){return w.join(mu(e),encodeURIComponent(t))}async function gu(e,t){let r=y().files,i,a=!1;try{let n=mu(e);if(i=hu(e,t),await r.ensureDirectory(n),(await yu(i))?.serial===t)return!0;let o={version:1,serial:t};if(await r.writeAtomicText(i,`${JSON.stringify(o)}\n`,384),a=!0,(await yu(i))?.serial!==t)throw Error(`Android test IME marker read-back did not match the requested device.`);return!0}catch(o){return a&&i&&await r.remove(i,{force:!0}).catch(()=>{}),h({level:`debug`,phase:`android_test_ime_marker_write_failed`,data:{stateDir:e,serial:t,error:n(o).message}}),!1}}async function _u(e,t){await y().files.remove(hu(e,t),{force:!0}).catch(()=>{})}async function vu(e){let t=y().files,n;try{n=await t.readDirectory(mu(e))}catch{return[]}let r=[];for(let t of n)try{let n=w.join(mu(e),t),i=await yu(n);i&&hu(e,i.serial)===n&&r.push(i.serial)}catch{}return[...new Set(r)].sort()}async function yu(e){try{return bu(await y().files.readText(e))}catch{return}}function bu(e){try{let t=JSON.parse(e);if(!t||typeof t!=`object`||Array.isArray(t))return;let n=t;return n.version===1&&typeof n.serial==`string`&&n.serial.length>0?{version:1,serial:n.serial}:void 0}catch{return}}const xu=new Ot(`utf-16le`);let Su;async function Cu(e,t){for(let n of[`AndroidManifest.xml`,`base/manifest/AndroidManifest.xml`]){let r=await wu(e,n,t);if(!r)continue;let i=Tu(r);if(i)return i}return await Pu(e,t)}async function wu(e,t,n){try{let r=await be(`unzip`,[`-p`,e,t],{allowFailure:!0,binaryStdout:!0,signal:n});return r.exitCode!==0||!r.stdoutBuffer||r.stdoutBuffer.length===0?void 0:r.stdoutBuffer}catch{n?.throwIfAborted();return}}function Tu(e){return e.subarray(0,Math.min(e.length,128)).toString(`utf8`).trimStart().startsWith(`<`)?Eu(e.toString(`utf8`)):Du(e)}function Eu(e){return e.match(/<manifest\b[^>]*\bpackage\s*=\s*["']([^"']+)["']/i)?.[1]}function Du(e){if(e.length<8||e.readUInt16LE(0)!==3)return;let t;for(let n=e.readUInt16LE(2);n+8<=e.length;){let r=e.readUInt16LE(n),i=e.readUInt16LE(n+2),a=e.readUInt32LE(n+4);if(a<=0||n+a>e.length)return;if(r===1)t=ku(e.subarray(n,n+a));else if(r===258&&t){let r=Ou(e,n,i,t);if(r)return r}n+=a}}function Ou(e,t,n,r){if(n<36||t+n>e.length||r[e.readUInt32LE(t+20)]!==`manifest`)return;let i=e.readUInt16LE(t+24),a=e.readUInt16LE(t+26),o=e.readUInt16LE(t+28),s=t+i;for(let t=0;t<o;t+=1){let n=s+t*a;if(n+20>e.length)return;if(r[e.readUInt32LE(n+4)]!==`package`)continue;let i=e.readUInt32LE(n+8);if(i!==4294967295)return r[i];let o=e.readUInt8(n+15),c=e.readUInt32LE(n+16);return o===3?r[c]:void 0}}function ku(e){if(e.length<28)return[];let t=e.readUInt32LE(8),n=e.readUInt32LE(16),r=e.readUInt32LE(20),i=!!(n&256),a=[];for(let n=0;n<t;n+=1){let t=28+n*4;if(t+4>e.length)return a;let o=r+e.readUInt32LE(t);a.push(i?Au(e,o):ju(e,o))}return a}function Au(e,t){let[,n]=Mu(e,t),[r,i]=Mu(e,t+n),a=t+n+i;return e.subarray(a,a+r).toString(`utf8`)}function ju(e,t){let[n,r]=Nu(e,t),i=t+r;return xu.decode(e.subarray(i,i+n*2))}function Mu(e,t){let n=e.readUInt8(t);if(!(n&128))return[n,1];let r=e.readUInt8(t+1);return[(n&127)<<8|r,2]}function Nu(e,t){let n=e.readUInt16LE(t);if(!(n&32768))return[n,2];let r=e.readUInt16LE(t+2);return[(n&32767)<<16|r,4]}async function Pu(e,t){t?.throwIfAborted();let n=await Fu();if(!n)return;let r=await be(n,[`dump`,`badging`,e],{allowFailure:!0,signal:t});if(r.exitCode===0)return r.stdout.match(/package:\s+name='([^']+)'/)?.[1]}async function Fu(){if(Su!==void 0)return Su??void 0;try{let e=y().files;for(let t of at()){let n=w.join(t,`build-tools`);try{let t=(await e.readDirectory(n)).sort((e,t)=>t.localeCompare(e,void 0,{numeric:!0}));for(let r of t){let t=w.join(n,r,`aapt`);if(w.isAbsolute(t)&&await e.isExecutable(t))return Su=t,t}}catch{}}}catch{}Su=null}async function Iu(e,t){let n=e.kind===`url`&&Oe(e.url),r=await ke({source:e,isInstallablePath:(e,t)=>t.isFile()&&Lu(e),installableLabel:`Android installable (.apk or .aab)`,allowArchiveExtraction:e.kind!==`url`||n,signal:t?.signal});try{let e=t?.resolveIdentity===!1?{}:await Ru(r.installablePath,t?.signal);return{archivePath:r.archivePath,installablePath:r.installablePath,packageName:e.packageName,cleanup:r.cleanup}}catch(e){throw await r.cleanup(),e}}function Lu(e){let t=w.extname(e).toLowerCase();return t===`.apk`||t===`.aab`}async function Ru(e,t){let n=w.extname(e).toLowerCase();return n!==`.apk`&&n!==`.aab`?{}:{packageName:await Cu(e,t)}}async function zu(e,n,r,i={}){let a=typeof r.action==`string`&&r.action.trim()?r.action.trim():`${n}.TEST_PUSH`,o=[`shell`,`am`,`broadcast`,`-a`,a,`-p`,n],s=typeof r.receiver==`string`?r.receiver.trim():``;s&&o.push(`-n`,s);let c=r.extras;if(c!==void 0&&(typeof c!=`object`||!c||Array.isArray(c)))throw new t(`INVALID_ARGS`,`Android push payload extras must be an object`);let l=c??{},u=0;for(let[e,t]of Object.entries(l))e&&(Bu(o,e,t),u+=1);return await C(e,o,{signal:i.signal}),{action:a,extrasCount:u}}function Bu(e,n,r){if(typeof r==`string`){e.push(`--es`,n,r);return}if(typeof r==`boolean`){e.push(`--ez`,n,r?`true`:`false`);return}if(typeof r==`number`&&Number.isFinite(r)){if(Number.isInteger(r)){e.push(`--ei`,n,String(r));return}e.push(`--ef`,n,String(r));return}throw new t(`INVALID_ARGS`,`Unsupported Android broadcast extra type for "${n}". Use string, boolean, or number.`)}function Q(e){let t=e.replaceAll(`,`,``).match(/^-?\d+(?:\.\d+)?/);if(!t)return null;let n=Number(t[0]);return Number.isFinite(n)?n:null}function Vu(e){let t=Ku(e.map(e=>e.intendedVsyncNs)),n=[];for(let e=1;e<t.length;e+=1){let r=t[e]-t[e-1];r>=4e6&&r<=5e7&&n.push(r)}if(n.length!==0)return qu(n)}function Hu(e){let{frames:t,frameDeadlineNs:n,summaryDroppedFrameCount:r}=e;return r===void 0?n===void 0?[]:t.filter(e=>e.durationNs>n):r<=0?[]:[...t].sort((e,t)=>t.durationNs-e.durationNs).slice(0,r).sort((e,t)=>e.intendedVsyncNs-t.intendedVsyncNs)}function Uu(e){let{frames:t,windowStartNs:n,measuredAtMs:r,uptimeMs:i}=e;if(t.length===0||n===void 0)return[];let a=[],o=[];for(let e of t){let t=o.at(-1);if(!t||e.intendedVsyncNs-t.frameCompletedNs<=5e8){o.push(e);continue}a.push(o),o=[e]}return o.length>0&&a.push(o),a.map(e=>Gu({frames:e,windowStartNs:n,measuredAtMs:r,uptimeMs:i})).sort((e,t)=>t.missedDeadlineFrameCount-e.missedDeadlineFrameCount||t.worstFrameMs-e.worstFrameMs).slice(0,3).sort((e,t)=>e.startOffsetMs-t.startOffsetMs)}function Wu(e){return Math.round(e*10)/10}function Gu(e){let{frames:t,windowStartNs:n,measuredAtMs:r,uptimeMs:i}=e,a=Math.min(...t.map(e=>e.intendedVsyncNs)),o=Math.max(...t.map(e=>e.frameCompletedNs)),s=Math.max(0,Math.round((a-n)/1e6)),c=Math.max(s,Math.round((o-n)/1e6)),l=i!==void 0&&Number.isFinite(r)?r-i:void 0;return{startOffsetMs:s,endOffsetMs:c,startAt:l===void 0?void 0:new Date(l+a/1e6).toISOString(),endAt:l===void 0?void 0:new Date(l+o/1e6).toISOString(),missedDeadlineFrameCount:t.length,worstFrameMs:Wu(Math.max(...t.map(e=>e.durationNs))/1e6)}}function Ku(e){return[...new Set(e.filter(e=>Number.isFinite(e)))].sort((e,t)=>e-t)}function qu(e){let t=[...e].sort((e,t)=>e-t),n=Math.floor(t.length/2);return t.length%2==1?t[n]:(t[n-1]+t[n])/2}function Ju(e,t,n){Yu(e,t);let r=ad(e),i=td(e),a=Zu(i,r,t),o=Date.parse(n),s=sd({frames:i,measuredAtMs:o,summary:r}),c=Hu({frames:i,frameDeadlineNs:a,summaryDroppedFrameCount:r?.droppedFrameCount}),l=r?.sampleWindowMs??s.sampleWindowMs??dd(i),u=Qu(r,i,c),d=ed({droppedFrames:c,timing:s,measuredAtMs:o,summary:r});return{...u,sampleWindowMs:l,...$u(a),windowStartedAt:s.windowStartedAt,windowEndedAt:s.windowEndedAt,timestampSource:s.timestampSource,measuredAt:n,method:`adb-shell-dumpsys-gfxinfo-framestats`,source:r?`android-gfxinfo-summary`:`framestats-rows`,worstWindows:d&&d.length>0?d:void 0}}function Yu(e,n){if(/no process found for:/i.test(e))throw new t(`COMMAND_FAILED`,`Android gfxinfo did not find a running process for ${n}`,{metric:`fps`,package:n,hint:`Run open <app> for this session again to ensure the Android app is active, then retry perf after the interaction you want to inspect.`})}function Xu(e){throw new t(`COMMAND_FAILED`,`Failed to parse Android framestats output for ${e}`,{metric:`fps`,package:e,hint:`Retry perf after exercising the app screen. If the problem persists, capture adb shell dumpsys gfxinfo <package> framestats output for debugging.`})}function Zu(e,n,r){let i=Vu(e);if(!n&&e.length===0&&Xu(r),n||i!==void 0)return i;throw new t(`COMMAND_FAILED`,`Failed to infer Android frame deadline from framestats output for ${r}`,{metric:`fps`,package:r,hint:`Retry perf after a longer interaction window so consecutive Android frame timestamps are available.`})}function Qu(e,t,n){let r=e?.totalFrameCount??t.length,i=e?.droppedFrameCount??n.length;return{totalFrameCount:r,droppedFrameCount:i,droppedFramePercent:e?.droppedFramePercent??(r>0?Et(i/r*100):0)}}function $u(e){return{frameDeadlineMs:e===void 0?void 0:Wu(e/1e6),refreshRateHz:e===void 0?void 0:Wu(1e9/e)}}function ed(e){let{droppedFrames:t,timing:n,measuredAtMs:r,summary:i}=e;if(t.length===0)return;let a=Uu({frames:t,windowStartNs:n.windowStartNs,measuredAtMs:r,uptimeMs:i?.uptimeMs});return a.length>0?a:void 0}function td(e){let t=[],n=null;for(let r of e.split(`
13
+ `)){let e=r.trim();if(e.length===0||e===`---PROFILEDATA---`)continue;let i=e.split(`,`).map(e=>e.trim());if(nd(i)){n=new Map(i.map((e,t)=>[e,t]));continue}let a=rd(i,n);a&&t.push(a)}return t.sort((e,t)=>e.intendedVsyncNs-t.intendedVsyncNs)}function nd(e){return e.includes(`IntendedVsync`)&&e.includes(`FrameCompleted`)}function rd(e,t){if(!t||e.length<t.size)return;let n=id(e,t,`Flags`),r=id(e,t,`IntendedVsync`),i=id(e,t,`FrameCompleted`);if(!(n!==0||r===null||i===null||r<=0||i<=r))return{intendedVsyncNs:r,frameCompletedNs:i,durationNs:i-r}}function id(e,t,n){let r=t.get(n);if(r===void 0)return null;let i=Number(e[r]);return Number.isFinite(i)?i:null}function ad(e){let t=e.split(/\nProfile data in ms:\n/i)[0]??``,n=fd(t,`Total frames rendered`),r=t.match(/^\s*Janky frames:\s*([0-9][0-9,]*)\s*\(([0-9.]+)%\)/im);if(n===void 0||!r)return;let i=r[1],a=r[2];if(i===void 0||a===void 0)return;let o=Q(i)??void 0,s=Number(a);if(o===void 0||!Number.isFinite(s)||n<0)return;let c=fd(t,`Uptime`),l=fd(t,`Stats since`);return{droppedFramePercent:Et(s),droppedFrameCount:o,totalFrameCount:n,sampleWindowMs:od({uptimeMs:c,statsSinceNs:l}),uptimeMs:c,statsSinceNs:l}}function od(e){let{uptimeMs:t,statsSinceNs:n}=e;if(t===void 0||n===void 0)return;let r=t-Math.round(n/1e6);return r>=0?r:void 0}function sd(e){let{frames:t,measuredAtMs:n,summary:r}=e,i=cd(t),a=r?.statsSinceNs,o=a??i.firstFrameNs,s=ld(o,i.lastFrameNs),c=r?.sampleWindowMs??s;if(!Number.isFinite(n)||r?.uptimeMs===void 0||o===void 0)return{sampleWindowMs:c,windowStartNs:o};let l=n-r.uptimeMs;return{sampleWindowMs:c,windowStartNs:o,windowStartedAt:new Date(l+o/1e6).toISOString(),windowEndedAt:ud({deviceBootWallClockMs:l,measuredAtMs:n,summaryStartNs:a,lastFrameNs:i.lastFrameNs}),timestampSource:`estimated-from-device-uptime`}}function cd(e){return e.length===0?{}:{firstFrameNs:Math.min(...e.map(e=>e.intendedVsyncNs)),lastFrameNs:Math.max(...e.map(e=>e.frameCompletedNs))}}function ld(e,t){if(e!==void 0&&t!==void 0)return Math.max(0,Math.round((t-e)/1e6))}function ud(e){let{deviceBootWallClockMs:t,measuredAtMs:n,summaryStartNs:r,lastFrameNs:i}=e;return r===void 0?i===void 0?void 0:new Date(t+i/1e6).toISOString():new Date(n).toISOString()}function dd(e){if(e.length===0)return;let t=cd(e);return ld(t.firstFrameNs,t.lastFrameNs)}function fd(e,t){let n=t.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`),r=e.match(RegExp(`^\\s*${n}:\\s*([0-9][0-9,]*)`,`im`));if(!r)return;let i=r[1];return i===void 0?void 0:Q(i)??void 0}async function pd(e,t,n={}){let r=x(e,n.adb);try{let i=Ju((await r([`shell`,`dumpsys`,`gfxinfo`,t,`framestats`],{timeoutMs:15e3})).stdout,t,new Date().toISOString());return await md(e,t,n),i}catch(e){throw hd(t,e)}}async function md(e,t,n={}){let r=x(e,n.adb);try{await r([`shell`,`dumpsys`,`gfxinfo`,t,`reset`],{allowFailure:!0,timeoutMs:3e3})}catch{}}function hd(e,n){return n instanceof t?new t(n.code,n.message,{...n.details??{},metric:`fps`,package:e},n):new t(`COMMAND_FAILED`,`Failed to sample Android fps for ${e}`,{metric:`fps`,package:e},n)}async function gd(e,t,n,r,i){return{capture:{durationMs:r,packageName:t.packageName,appPid:t.appPid,artifactPath:t.outPath,sizeBytes:n},frameHealth:t.kind===`perfetto`?await _d(e,t.packageName,i):void 0,notes:[t.kind===`perfetto`?`Frame health is sampled from Android gfxinfo around the trace window; open the Perfetto artifact for timeline root cause.`:`Open the Simpleperf report artifact for symbol-level CPU attribution.`]}}async function _d(e,t,n){try{let r=await pd(e,t,n);return{available:!0,droppedFramePercent:r.droppedFramePercent,droppedFrameCount:r.droppedFrameCount,totalFrameCount:r.totalFrameCount,method:r.method,worstWindows:r.worstWindows?.slice(0,3).map(e=>({startOffsetMs:e.startOffsetMs,endOffsetMs:e.endOffsetMs,missedDeadlineFrameCount:e.missedDeadlineFrameCount,worstFrameMs:e.worstFrameMs}))}}catch(e){return{available:!1,reason:e instanceof Error?e.message:`Android frame health was not available`}}}async function vd(e,t,n){let r=x(e,n.adb);await wd(r,t),await Dd(r,t),await Ed(r,t,n.files);let i=await Cd(t.outPath,n.files);await xd(r,t.remotePath);let a=Date.now(),o=Math.max(0,a-t.startedAt),s=await gd(e,t,i,o,{adb:r});return{...t,action:`stop`,platform:`android`,state:`stopped`,stoppedAt:a,durationMs:o,sizeBytes:i,method:t.kind===`simpleperf`?Sr:Cr,artifact:{path:t.outPath,sizeBytes:i},summary:s,message:`Stopped Android ${t.kind} ${t.type} for ${t.packageName}`}}async function yd(e,t,n={}){let r=x(e,n.adb);try{t.state===`running`&&(await wd(r,t),await Dd(r,t).catch(()=>{}))}finally{await xd(r,t.remotePath)}}function bd(e,t,n=Tr){return`${n}/agent-device-${e.replaceAll(/[^A-Za-z0-9_.-]/g,`_`)}-${Date.now()}-${t}`}async function xd(e,t){try{await e([`shell`,`rm -f ${_(t)}`],{allowFailure:!0,timeoutMs:wr})}catch{}}async function Sd(e,t,n=y().files){await n.ensureDirectory(w.dirname(e)),await n.writeBytes(e,Buffer.from(`${JSON.stringify(t,null,2)}\n`))}async function Cd(e,n=y().files){try{return(await n.stat(e)).size}catch(n){throw new t(`COMMAND_FAILED`,`Profiler artifact was not written: ${e}`,{outPath:e,hint:`Retry the profiling command and check daemon logs if the artifact path is still missing.`},n)}}async function wd(e,t){try{await e([`shell`,Td(t.profilerPid)],{timeoutMs:N})}catch(e){throw M(`stop`,t.kind,t.packageName,e)}}function Td(e){return[`pid=${_(e)}`,`kill -INT "$pid" 2>/dev/null || true`,`for i in 1 2 3 4 5 6 7 8 9 10; do kill -0 "$pid" 2>/dev/null || exit 0; sleep 0.2; done`,`kill -TERM "$pid" 2>/dev/null || true`,`for i in 1 2 3 4 5 6 7 8 9 10; do kill -0 "$pid" 2>/dev/null || exit 0; sleep 0.2; done`,`echo "profiler process did not stop after SIGTERM" >&2`,`exit 1`].join(`; `)}async function Ed(e,n,r){await(r??y().files).ensureDirectory(w.dirname(n.outPath));try{await e([`pull`,n.remotePath,n.outPath],{timeoutMs:N})}catch(e){throw new t(`COMMAND_FAILED`,`Failed to pull Android ${n.kind} artifact for ${n.packageName}`,{package:n.packageName,tool:n.kind,remotePath:n.remotePath,outPath:n.outPath,hint:`Check that the profiling command ran long enough to create an artifact, then retry stop with the same session.`},e)}}async function Dd(e,n){let r;for(let t=0;t<12;t+=1){let t=await Od(e,n.remotePath);if(t!==void 0&&t>0&&t===r)return;r=t,await g(250)}throw new t(`COMMAND_FAILED`,`Android ${n.kind} artifact is not ready to pull`,{package:n.packageName,tool:n.kind,remotePath:n.remotePath,hint:`The profiler stopped, but the remote artifact was missing, empty, or still changing. Retry stop with the same session or inspect the device-side artifact.`})}async function Od(e,t){let n=_(t),r=await e([`shell`,`if [ -f ${n} ]; then stat -c %s ${n} 2>/dev/null || wc -c < ${n}; fi`],{allowFailure:!0,timeoutMs:wr});if(r.exitCode!==0)return;let i=Number(r.stdout.trim().split(/\s+/)[0]);return Number.isFinite(i)?i:void 0}async function kd(e,t,n,r={}){let i=x(e,r.adb),a=await Er(i,t);await Dr(i,`perfetto`,t);let o=bd(t,`app.perfetto-trace`,`/data/misc/perfetto-traces`),s;try{await md(e,t,{adb:i}),s=await jd(i,o,t)}catch(e){throw await xd(i,o),e}return{type:`trace`,kind:`perfetto`,packageName:t,appPid:a,profilerPid:s,remotePath:o,outPath:n,startedAt:Date.now(),state:`running`,action:`start`,platform:`android`,method:Cr,message:`Started Android Perfetto trace for ${t}`}}async function Ad(e,t,n,r={}){return await vd(e,{...t,outPath:n},r)}async function jd(e,n,r){try{let i=Or((await e([`shell`,`perfetto`,`--background-wait`,`-o`,n,`-t`,`3600s`,`sched`,`freq`,`idle`,`am`,`wm`,`gfx`,`view`,`binder_driver`,`hal`,`dalvik`],{timeoutMs:N})).stdout);if(i)return i;throw new t(`COMMAND_FAILED`,`Android perfetto did not return a profiler pid`,{package:r,tool:`perfetto`,hint:`Retry perf trace start. If perfetto exits immediately, verify the device permits trace capture.`})}catch(e){throw M(`start`,`perfetto`,r,e)}}function Md(e){let t=[];for(let n of s(e)){let e=n.match(/^([0-9]+(?:\.[0-9]+)?)%\s+(.+)$/);if(!e)continue;let r=Number(e[1]),i=e[2]?.trim();if(!Number.isFinite(r)||!i)continue;let a=i.split(/\s{2,}/).filter(Boolean);if(t.push({percentage:Et(r),command:a[0],dso:a[1],symbol:a.slice(2).join(` `)||void 0}),t.length>=50)break}return t}async function Nd(e,t,n,r={}){let i=x(e,r.adb),a=await Er(i,t);await Dr(i,`simpleperf`,t);let o=bd(t,`cpu.perf.data`),s;try{s=await Id(i,a,o,t)}catch(e){throw await xd(i,o),e}return{type:`cpu-profile`,kind:`simpleperf`,packageName:t,appPid:a,profilerPid:s,remotePath:o,outPath:n,startedAt:Date.now(),state:`running`,action:`start`,platform:`android`,method:Sr,message:`Started Android Simpleperf CPU profile for ${t}`}}async function Pd(e,t,n,r={}){return await vd(e,{...t,outPath:n},r)}async function Fd(e,t,n,r={}){let i=x(e,r.adb);await Dr(i,`simpleperf`,t.packageName);let a=await zd(i,t),o=new Date().toISOString(),s=Md(a.stdout),c=s.slice(0,10).map(e=>({symbol:e.symbol??`<unknown>`,binary:e.dso,selfSamplePercent:e.percentage}));await Sd(n,{kind:`simpleperf-report`,generatedAt:o,packageName:t.packageName,appPid:t.appPid,sourceProfilePath:t.outPath,sourceRemotePath:t.remotePath,entryCount:s.length,summary:{topFunctions:c},entries:s},r.files);let l=await Cd(n,r.files);return{action:`report`,platform:`android`,type:`cpu-profile-report`,kind:`simpleperf`,packageName:t.packageName,appPid:t.appPid,sourceProfilePath:t.outPath,outPath:n,sizeBytes:l,generatedAt:o,entryCount:s.length,summary:{topFunctions:c},method:Sr,message:`Wrote Android Simpleperf report for ${t.packageName}`}}async function Id(e,n,r,i){try{let a=Or((await e([`shell`,Ld(n,r)],{timeoutMs:N})).stdout);if(a)return a;throw new t(`COMMAND_FAILED`,`Android simpleperf did not return a profiler pid`,{package:i,tool:`simpleperf`,hint:`Retry perf. If simpleperf exits immediately, verify the app is profileable and the device permits native profiling.`})}catch(e){throw M(`start`,`simpleperf`,i,e)}}function Ld(e,t){return Rd([`simpleperf`,`record`,`-e`,`cpu-clock:u`,`-p`,e,`-o`,t,`--duration`,`3600`],`simpleperf`)}function Rd(e,t){let n=e.map(_).join(` `),r=`${Tr}/agent-device-${t}-${Date.now()}.err`;return[`err=${_(r)}`,`(${n}) >/dev/null 2>"$err" & pid=$!`,`sleep 1`,`if kill -0 "$pid" 2>/dev/null; then rm -f "$err"; echo "$pid"; exit 0; fi`,`cat "$err" >&2`,`rm -f "$err"`,`exit 1`].join(`; `)}async function zd(e,t){try{return await e([`shell`,`simpleperf`,`report`,`-i`,t.remotePath,`--stdio`,`--sort`,`comm,dso,symbol`],{timeoutMs:N})}catch(e){throw M(`report`,`simpleperf`,t.packageName,e)}}const Bd=15e3,Vd=12e4;async function Hd(e,t,n={}){let r=x(e,n.adb);try{return Kd((await r([`shell`,`dumpsys`,`meminfo`,t],{timeoutMs:Bd})).stdout,t,new Date().toISOString())}catch(e){throw ef(`memory`,t,e)}}async function Ud(e,n,r,i={}){let a=x(e,i.adb),o=i.files??y().files,s=await qd(a,n),c=Jd(n);await o.ensureDirectory(w.dirname(r));let l=await Wd(o,r);try{ye(await a([`shell`,`am`,`dumpheap`,n,c],{allowFailure:!0,timeoutMs:Vd}),`Failed to capture Android heap dump for ${n}`,e=>({kind:`android-hprof`,package:n,pid:s,remotePath:c,hint:Yd(e.stdout,e.stderr)}));let e=await a([`pull`,c,r],{allowFailure:!0,timeoutMs:Vd});if(e.exitCode!==0)throw await Gd(o,r,l),b(`Failed to pull Android heap dump for ${n}`,e,{kind:`android-hprof`,package:n,pid:s,remotePath:c,path:r,hint:`Verify the daemon can write the requested --out path and retry. The heap dump stays on-device only until cleanup runs.`});let i=await o.stat(r).catch(()=>null);if(!i?.isFile||i.size<=0)throw await Gd(o,r,l),new t(`COMMAND_FAILED`,`Android heap dump artifact is missing or empty`,{kind:`android-hprof`,package:n,pid:s,path:r,remotePath:c,hint:`Retry with a writable --out path. If the file is still empty, inspect adb pull output with --debug.`});return{available:!0,kind:`android-hprof`,path:r,sizeBytes:i.size,measuredAt:new Date().toISOString(),method:`adb-shell-am-dumpheap`,packageName:n,pid:s,remotePath:c}}finally{await a([`shell`,`rm`,`-f`,c],{allowFailure:!0,timeoutMs:Bd}).catch(()=>{})}}async function Wd(e,t){return await e.stat(t).then(e=>e.isFile).catch(()=>!1)}async function Gd(e,t,n){n||await e.remove(t,{force:!0}).catch(()=>{})}function Kd(e,n,r){if(/no process found for:/i.test(e))throw new t(`COMMAND_FAILED`,`Android meminfo did not find a running process for ${n}`,{metric:`memory`,package:n,hint:`Run open <app> for this session again to ensure the Android app is active, then retry perf.`});let i=tf(e,`TOTAL PSS`)??nf(e);if(i===void 0)throw new t(`COMMAND_FAILED`,`Failed to parse Android meminfo output for ${n}`,{metric:`memory`,package:n,hint:`Retry perf after reopening the app session. If the problem persists, capture adb shell dumpsys meminfo output for debugging.`});return{totalPssKb:i,totalRssKb:tf(e,`TOTAL RSS`),measuredAt:r,method:`adb-shell-dumpsys-meminfo`,topConsumers:Xd(e)}}async function qd(e,n){let r=await e([`shell`,`pidof`,n],{allowFailure:!0,timeoutMs:Bd}),i=r.stdout.trim().split(/\s+/).map(Number).find(e=>Number.isInteger(e)&&e>0);if(r.exitCode===0&&i!==void 0)return i;throw new t(`COMMAND_FAILED`,`No running Android process found for ${n}`,{kind:`android-hprof`,package:n,stdout:r.stdout,stderr:r.stderr,hint:`Run open <app> for this session again to ensure the Android app is active, then retry perf memory snapshot.`})}function Jd(e){return`/data/local/tmp/agent-device-${e.replaceAll(/[^a-zA-Z0-9._-]/g,`_`)}-${Date.now()}.hprof`}function Yd(e,t){let n=`${e}\n${t}`.toLowerCase();return n.includes(`profileable`)||n.includes(`debuggable`)||n.includes(`not allowed`)?`Android heap dumps require a debuggable/profileable app process on many devices. Use a debug/profileable build, reopen the app, then retry.`:n.includes(`permission`)||n.includes(`denied`)?`The device denied heap dump access. Use a debug/profileable build or a device image that permits app heap dumping.`:`Reopen the app to refresh the process, then retry perf memory snapshot. If it still fails, run with --debug and inspect adb am dumpheap output.`}function Xd(e){let t=e.split(`
14
+ `).flatMap(e=>Zd(e)??[]).sort((e,t)=>t.pssKb-e.pssKb).slice(0,5);return t.length>0?t:void 0}function Zd(e){let t=e.trim();if(Qd(t))return;let n=t.match(/^(.+?)\s+([0-9][0-9,]*(?:\(\d+\))?)(?:\s|$)/);if(n)return $d(n[1],n[2])}function Qd(e){if(!e||e.startsWith(`**`)||e.startsWith(`-`)||e.includes(`:`))return!0;let t=/^\S.+\s+\d/.test(e);return/^(pss|total|native|dalvik|unknown|app summary\b)/i.test(e)&&!t}function $d(e,t){let n=e?.trim(),r=t?Q(t):null;if(!(!n||n===`TOTAL`||r===null||r<=0)&&!/^(pss|private|shared|heap|size|alloc|free)$/i.test(n))return{name:n,pssKb:r}}function ef(e,n,r){return r instanceof t?new t(r.code,r.message,{...r.details??{},metric:e,package:n},r):new t(`COMMAND_FAILED`,`Failed to sample Android ${e} for ${n}`,{metric:e,package:n},r)}function tf(e,t){let n=t.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`),r=e.match(RegExp(`${n}:\\s*([0-9][0-9,]*)`,`i`));if(!r)return;let i=r[1];return i===void 0?void 0:Q(i)??void 0}function nf(e){for(let t of e.split(`
15
+ `)){let e=t.trim();if(!/^TOTAL\b(?!\s+PSS:)/.test(e))continue;let n=e.split(/\s+/).slice(1).find(e=>Q(e)!==null);return n?Q(n)??void 0:void 0}}async function rf(e,t,n){let r=await C(e,[`shell`,`dumpsys`,`package`,t],{allowFailure:!0});if(r.exitCode===0)return lf(r.stdout,n)}async function af(e){let t=await C(e,[`shell`,`am`,`get-current-user`],{allowFailure:!0});if(t.exitCode!==0)return;let n=Number.parseInt(t.stdout.trim(),10);return Number.isInteger(n)&&n>=0?n:void 0}const of=/^\s*User (\d+):/,sf=/^\s*runtime permissions:\s*$/,cf=/^\s*([\w.]+): granted=(true|false)\b/;function lf(e,t){let n=uf(uf(uf(e.split(`
16
+ `).filter(e=>e.trim().length>0).map(e=>({text:e,indent:e.length-e.trimStart().length})),e=>e.indent===0&&e.text.trim()===`Packages:`),e=>of.exec(e.text)?.[1]===String(t)),e=>sf.test(e.text));if(!n)return;let r=new Map;for(let{text:e}of n){let t=cf.exec(e);t&&r.set(t[1],t[2]===`true`?`granted`:`not_granted`)}return r}function uf(e,t){if(!e)return;let n=e.findIndex(e=>t(e));if(n<0)return;let r=e.slice(n+1),i=r.findIndex(t=>t.indent<=e[n].indent);return i<0?r:r.slice(0,i)}function df(e,t,n){if(n!==`not_granted`)return`${n===`granted`?`${t} was granted before this revoke, and Android kills an app when a granted permission is revoked: if ${e} was running it is no longer.`:`Whether ${t} was granted before this revoke could not be read (adb did not report the acting user's runtime permission state), and Android kills an app when a granted permission is revoked: ${e} may no longer be running.`} Relaunch it with open ${e} --relaunch before the next interaction.`}async function ff(e){let n=await af(e);if(n!==void 0)return n;throw new t(`COMMAND_FAILED`,`Could not determine which Android user the session runs as, so no permission was changed.`,{deviceId:e.id,hint:`Check adb -s ${e.id} shell am get-current-user — if the device is still booting, retry once it reports a user. agent-device refuses to change permissions it cannot scope, because pm would silently apply them to user 0.`})}async function pf(e,t,n,r){let i=me(n),a=gf(r?.permissionTarget,r?.permissionMode),o=await ff(e),s=[`--user`,String(o)];if(i===`grant`){await mf(e,t,a,s);return}let c=await rf(e,t,o),l=await hf(e,t,i,a,s),u=c?.get(l)??`unknown`,d=df(t,l,u);return{permission:l,priorGrantState:u,...d?{warnings:[d]}:{}}}async function mf(e,t,n,r){n.kind===`notifications`?await vf(e,t,`grant`,n,r):n.type===`photos`?await _f(e,t,`grant`,r):await C(e,[`shell`,`pm`,`grant`,...r,t,n.value])}async function hf(e,t,n,r,i){if(r.kind===`notifications`)return await vf(e,t,n,r,i),r.permission;let a;return r.type===`photos`?a=await _f(e,t,`revoke`,i):(a=r.value,await C(e,[`shell`,`pm`,`revoke`,...i,t,a])),n===`reset`&&await yf(e,t,a,i),a}function gf(e,n){let r=ge(e);if(n?.trim())throw new t(`INVALID_ARGS`,`Permission mode is only supported for photos. Received: ${n}.`);if(r===`camera`)return{kind:`pm`,value:`android.permission.CAMERA`,type:`camera`};if(r===`microphone`)return{kind:`pm`,value:`android.permission.RECORD_AUDIO`,type:`microphone`};if(r===`photos`)return{kind:`pm`,value:`android.permission.READ_MEDIA_IMAGES`,type:`photos`};if(r===`contacts`)return{kind:`pm`,value:`android.permission.READ_CONTACTS`,type:`contacts`};if(r===`notifications`)return{kind:`notifications`,appOps:`POST_NOTIFICATION`,permission:`android.permission.POST_NOTIFICATIONS`};throw new t(`INVALID_ARGS`,`Unsupported permission target on Android: ${e}. Use camera|microphone|photos|contacts|notifications.`)}async function _f(e,n,r,i){let a=await bf(e),o=a!==null&&a>=33?[`android.permission.READ_MEDIA_IMAGES`,`android.permission.READ_EXTERNAL_STORAGE`]:[`android.permission.READ_EXTERNAL_STORAGE`,`android.permission.READ_MEDIA_IMAGES`],s=[];for(let t of o){let a=await C(e,[`shell`,`pm`,r,...i,n,t],{allowFailure:!0});if(a.exitCode===0)return t;s.push({permission:t,stderr:a.stderr,exitCode:a.exitCode})}throw new t(`COMMAND_FAILED`,`Failed to ${r} Android photos permission`,{appPackage:n,sdkInt:a,attempts:s})}async function vf(e,t,n,r,i){let a=n===`grant`?`allow`:n===`deny`?`deny`:`default`;n===`grant`?await C(e,[`shell`,`pm`,`grant`,...i,t,r.permission],{allowFailure:!0}):(await C(e,[`shell`,`pm`,`revoke`,...i,t,r.permission],{allowFailure:!0}),n===`reset`&&await yf(e,t,r.permission,i)),await C(e,[`shell`,`appops`,`set`,...i,t,r.appOps,a])}async function yf(e,t,n,r){for(let i of[`user-set`,`user-fixed`])await C(e,[`shell`,`pm`,`clear-permission-flags`,...r,t,n,i],{allowFailure:!0})}async function bf(e){let t=await C(e,[`shell`,`getprop`,`ro.build.version.sdk`],{allowFailure:!0});if(t.exitCode!==0)return null;let n=Number.parseInt(t.stdout.trim(),10);return!Number.isFinite(n)||n<=0?null:n}function xf(e){let n=e.trim().toLowerCase();if(n===`light`)return`light`;if(n===`dark`)return`dark`;if(n===`toggle`)return`toggle`;throw new t(`INVALID_ARGS`,`Invalid appearance state: ${e}. Use light|dark|toggle.`)}function Sf(e){let n=e.toLowerCase();if(n===`on`||n===`true`||n===`1`)return!0;if(n===`off`||n===`false`||n===`0`)return!1;throw new t(`INVALID_ARGS`,`Invalid setting state: ${e}`)}function Cf(e){return e.map(e=>({args:e.args.join(` `),exitCode:e.exitCode,stderr:e.stderr.slice(0,400)}))}const wf=[`shell`,`cmd`,`connectivity`,`airplane-mode`];async function Tf(e,n){let r=n?`enabled`:`disabled`;await Ef(e),await C(e,[...wf,n?`enable`:`disable`]);let i=await Df(e);if(i!==r)throw new t(`COMMAND_FAILED`,`Android airplane mode reads ${i} after requesting ${r}.`,{deviceId:e.id,requested:r,airplaneMode:i});return{airplaneMode:i}}async function Ef(e){let{state:n,result:r}=await Of(e);if(!n)throw r.exitCode!==0&&We(r.stdout,r.stderr)?new t(`UNSUPPORTED_OPERATION`,`The connectivity service on this Android build has no airplane-mode command, so nothing was changed.`,{deviceId:e.id,hint:`settings airplane needs cmd connectivity airplane-mode, which requires Android 11 (API 30) or newer. Use a newer device or emulator image.`,stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode}):b(`Failed to read Android airplane mode`,r,{deviceId:e.id})}async function Df(e){let{state:t,result:n}=await Of(e);if(t)return t;throw b(`Failed to read Android airplane mode after changing it`,n,{deviceId:e.id})}async function Of(e){let t=await C(e,[...wf],{allowFailure:!0});return{state:t.exitCode===0?kf(t.stdout):void 0,result:t}}function kf(e){let t=e.trim().toLowerCase();if(t===`enabled`)return`enabled`;if(t===`disabled`)return`disabled`}const Af=[`window_animation_scale`,`transition_animation_scale`,`animator_duration_scale`];async function jf(e,n,r,i,a){switch(n.toLowerCase()){case`wifi`:{let t=Sf(r);await C(e,[`shell`,`svc`,`wifi`,t?`enable`:`disable`]);return}case`airplane`:return await Tf(e,Sf(r));case`location`:{if(r.toLowerCase()===`set`){if(e.kind!==`emulator`)throw new t(`UNSUPPORTED_OPERATION`,`Android precise location coordinates are supported only on emulators.`,{deviceId:e.id,hint:`Use an Android emulator for adb emu geo fix, or configure location through device/provider tooling.`});let{latitude:n,longitude:r}=he(a);return await C(e,[`emu`,`geo`,`fix`,String(r),String(n)]),{latitude:n,longitude:r}}let n=Sf(r)?`3`:`0`;await C(e,[`shell`,`settings`,`put`,`secure`,`location_mode`,n]);return}case`animations`:{let t=Sf(r)?`1`:`0`;for(let n of Af)await C(e,[`shell`,`settings`,`put`,`global`,n,t]);return{scale:t,keys:[...Af]}}case`appearance`:{let t=await If(e,r);await C(e,[`shell`,`cmd`,`uimode`,`night`,t===`dark`?`yes`:`no`]);return}case`clear-app-state`:{if(r.toLowerCase()!==`clear`)throw new t(`INVALID_ARGS`,`settings clear-app-state only supports clear.`);if(!i)throw new t(`INVALID_ARGS`,`settings clear-app-state requires an app id or an active app session.`);let n=await ut(e,i);if(n.type===`intent`)throw new t(`INVALID_ARGS`,`settings clear-app-state requires a package name, not an intent.`);await C(e,[`shell`,`am`,`force-stop`,n.value],{allowFailure:!0});let a=await C(e,[`shell`,`pm`,`clear`,n.value],{allowFailure:!0});if(a.exitCode!==0||!/\bSuccess\b/i.test(a.stdout))throw new t(`COMMAND_FAILED`,`Failed to clear Android app data for ${n.value}`,{package:n.value,stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});return{package:n.value,cleared:!0}}case`fingerprint`:await Nf(e,Mf(r));return;case`permission`:if(!i)throw new t(`INVALID_ARGS`,`permission setting requires an active app in session`);return await pf(e,i,r,a);default:throw new t(`INVALID_ARGS`,`Unsupported setting: ${n}`)}}function Mf(e){let n=e.trim().toLowerCase();if(n===`match`)return`match`;if(n===`nonmatch`)return`nonmatch`;throw new t(`INVALID_ARGS`,`Invalid fingerprint state: ${e}. Use match|nonmatch.`)}async function Nf(e,n){let r=Pf(e,n),i=[];for(let t of r){let n=await C(e,t,{allowFailure:!0});if(n.exitCode===0)return;i.push({args:t,stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode})}let a=Cf(i);throw i.length>0&&i.every(e=>Ff(e.stdout,e.stderr))?new t(`UNSUPPORTED_OPERATION`,`Android fingerprint simulation is not supported on this target/runtime.`,{deviceId:e.id,action:n,hint:`Use an Android emulator with biometric support, or a device/runtime that exposes cmd fingerprint.`,attempts:a}):new t(`COMMAND_FAILED`,`Failed to simulate Android fingerprint.`,{deviceId:e.id,action:n,attempts:a})}function Pf(e,t){let n=t===`match`?`1`:`9999`,r=[[`shell`,`cmd`,`fingerprint`,`touch`,n],[`shell`,`cmd`,`fingerprint`,`finger`,n]];return e.kind===`emulator`&&r.push([`emu`,`finger`,`touch`,n]),r}function Ff(e,t){let n=`${e}\n${t}`.toLowerCase();return n.includes(`unknown command`)||n.includes(`can't find service: fingerprint`)||n.includes(`service fingerprint was not found`)||n.includes(`fingerprint cmd unavailable`)||n.includes(`emu command is not supported`)||n.includes(`emulator console is not running`)||n.includes(`fingerprint`)&&n.includes(`not found`)}async function If(e,n){let r=xf(n);if(r!==`toggle`)return r;let i=await C(e,[`shell`,`cmd`,`uimode`,`night`],{allowFailure:!0});if(i.exitCode!==0)throw b(`Failed to read current Android appearance`,i);let a=Lf(i.stdout,i.stderr);if(!a)throw new t(`COMMAND_FAILED`,`Unable to determine current Android appearance for toggle`,{stdout:i.stdout,stderr:i.stderr});return a===`auto`?`dark`:a===`dark`?`light`:`dark`}function Lf(e,t){let n=/night mode:\s*(yes|no|auto)\b/i.exec(`${e}\n${t}`);if(!n)return null;let r=n[1]?.toLowerCase();return r===`yes`?`dark`:r===`no`?`light`:r===`auto`?`auto`:null}const Rf=Buffer.from([137,80,78,71,13,10,26,10]);async function zf(e,t,n={}){if(n.stabilize===!1){await Hf(e,t);return}await Bf(e);try{await g(1e3),await Hf(e,t)}finally{await Vf(e).catch(()=>{})}}async function Bf(e){let t=t=>C(e,[`shell`,t],{allowFailure:!0});await t(`settings put global sysui_demo_allowed 1`);let n=e=>t(`am broadcast -a com.android.systemui.demo -e command ${e}`);await n(`clock -e hhmm 0941`),await n(`notifications -e visible false`)}async function Vf(e){await C(e,[`shell`,`am broadcast -a com.android.systemui.demo -e command exit`],{allowFailure:!0})}async function Hf(e,n){let r=await C(e,[`exec-out`,`screencap`,`-p`],{binaryStdout:!0});if(!r.stdoutBuffer)throw new t(`COMMAND_FAILED`,`Failed to capture screenshot`);let i=r.stdoutBuffer.indexOf(Rf);if(i<0)throw new t(`COMMAND_FAILED`,`Screenshot data does not contain a valid PNG header`);let a=Uf(r.stdoutBuffer,i);if(!a)throw new t(`COMMAND_FAILED`,`Screenshot data does not contain a complete PNG payload`);await y().files.writeBytes(n,r.stdoutBuffer.subarray(i,a))}function Uf(e,t){let n=t+Rf.length;for(;n+8<=e.length;){let t=e.readUInt32BE(n),r=n+4,i=e.toString(`ascii`,r,r+4),a=n+12+t;if(a>e.length)return null;if(i===`IEND`)return a;n=a}return null}async function Wf(e,t,n=0){let r=Ve(e);if(r){await r({action:`type`,text:t,delayMs:n}),$(`type`,`provider-native`,t);return}let i=await Yf(e,`type`,t);if(i.backend===`test-ime`){await Xf(e,i.packageName,t,n);return}if(n>0&&Array.from(t).length>1){await Qf(e,{action:`type`,text:t,chunkSize:1,delayMs:n});return}await Qf(e,{action:`type`,text:t,chunkSize:8,delayMs:0})}async function Gf(e,t,n,r,i=0,a={}){let o=await Vl(e,t,n,a),s=Ve(e);if(s)return await s({action:`fill`,target:{x:t,y:n},text:r,delayMs:i}),$(`fill`,`provider-native`,r),Z(r,o,await Rl(e,t,n,r,a));let c=null;for(let s of Kf(i)){await _a(e,t,n);let i=await Yf(e,`fill`,r);if(i.backend===`test-ime`)return Z(r,o,await Zf(e,i.packageName,t,n,r,o,a));let l=await qf(e,{x:t,y:n,text:r,beforeTarget:o,attempt:s},a);if(c=l,l.ok)return;if(l.reason===`ime_capture`)return Z(r,o,l);let u=Hl(r,o,l);if(u)return u}return Z(r,o,c)}function Kf(e){return[{clearPadding:12,minClear:8,maxClear:48,chunkSize:e>0?1:8,inputDelayMs:e},{clearPadding:24,minClear:16,maxClear:96,chunkSize:e>0?1:4,inputDelayMs:e>0?e:15}]}async function qf(e,t,n){let{x:r,y:i,text:a,beforeTarget:o,attempt:s}=t;return await ep(e,Jf(a,o,s)),await Qf(e,{action:`fill`,text:a,chunkSize:s.chunkSize,delayMs:s.inputDelayMs}),Rl(e,r,i,a,n)}function Jf(e,t,n){let r=Array.from(e).length;return lp(r>0?r+n.clearPadding:t?.text?Array.from(t.text).length+n.clearPadding:n.maxClear,n.minClear,n.maxClear)}async function Yf(e,t,n){if(Io(e))return{backend:`test-ime`,packageName:(await go(S(e))).manifest.packageName};let r=await tp(e,t),i=r?.inputMethodPackage;return So(i)?{backend:`test-ime`,packageName:i}:(rp(n),np(r,t),{backend:`adb-shell`})}async function Xf(e,t,n,r){let i=x(e),a=n.split(`
17
+ `);for(let[n,o]of a.entries()){let s=r>0?cp(o,1):[o];for(let[e,o]of s.entries())o&&await Co(i,t,o),r>0&&(e+1<s.length||n+1<a.length)&&await g(r);n+1<a.length&&await C(e,[`shell`,`input`,`keyevent`,`ENTER`])}$(`type`,`test-ime`,n)}async function Zf(e,t,n,r,i,a,o){let s=x(e),c=null;for(let l=0;l<2;l+=1){l>0&&await _a(e,n,r),await wo(s,t),i&&await Co(s,t,i);let u=await Rl(e,n,r,i,o);if(c=u,u.ok||Hl(i,a,u))break}return $(`fill`,`test-ime`,i),c}async function Qf(e,t){let n=t.text.split(`
18
+ `);for(let[r,i]of n.entries()){let a=cp(i,t.chunkSize);for(let[i,o]of a.entries())await $f(e,o),t.delayMs>0&&(i+1<a.length||r+1<n.length)&&await g(t.delayMs);r+1<n.length&&await C(e,[`shell`,`input`,`keyevent`,`ENTER`])}$(t.action,`adb-shell`,t.text)}async function $f(e,t){if(t)try{await C(e,[`shell`,`input`,`text`,Te(ap(t))])}catch(e){throw op(e)?sp(t,e):e}}async function ep(e,t){let n=Math.max(0,t);await C(e,[`shell`,`input`,`keyevent`,`KEYCODE_MOVE_END`],{allowFailure:!0});for(let t=0;t<n;t+=24){let r=Math.min(24,n-t);await C(e,[`shell`,`input`,`keyevent`,...Array(r).fill(`KEYCODE_DEL`)],{allowFailure:!0})}}async function tp(e,t){try{return await V(e)}catch(e){return h({level:`warn`,phase:`android_input_ownership_probe_failed`,data:{action:t,error:e instanceof Error?e.message:String(e)}}),null}}function np(e,n){if(!(!e||e.inputOwner!==`ime`))throw new t(`COMMAND_FAILED`,`KEYBOARD_OVERLAY_BLOCKING: Android text input is blocked because the focused input belongs to the active keyboard/IME.`,{failureReason:`ime_capture`,action:n,inputOwner:e.inputOwner,inputType:e.inputType,type:e.type,inputMethodPackage:e.inputMethodPackage,focusedPackage:e.focusedPackage,focusedResourceId:e.focusedResourceId,nextAction:`Focused input appears to be owned by the keyboard/IME; dismiss or change the IME before retrying text entry.`})}function rp(e){if(!ip(e))throw sp(e)}function ip(e){for(let t of e){let e=t.codePointAt(0);if(e!==void 0&&t!==`
19
+ `&&(e<32||e>126))return!1}return!0}function ap(e){return e.replaceAll(` `,`%s`)}function op(e){if(!(e instanceof t)||e.code!==`COMMAND_FAILED`)return!1;let n=e.details?.stderr,r=(typeof n==`string`?n:``).toLowerCase();return!!(r.includes(`exception occurred while executing 'text'`)||r.includes(`nullpointerexception`)&&r.includes(`inputshellcommand.sendtext`))}function sp(e,n){return new t(`COMMAND_FAILED`,"Android text input requires provider-native text injection or the bundled test IME helper for non-ASCII/control characters; the adb-shell fallback supports ASCII text only. On emulators the test IME activates automatically; on real devices pass `open --test-ime` to enable it (see `agent-device doctor` for the current IME state).",{backend:`adb-shell`,textLength:Array.from(e).length,textPreview:e.slice(0,32)},n instanceof Error?n:void 0)}function cp(e,t){let n=Math.max(1,Math.floor(t)),r=[],i=Array.from(e);for(let e=0;e<i.length;e+=n)r.push(i.slice(e,e+n).join(``));return r.length>0?r:[``]}function $(e,t,n){h({phase:`android_text_injection`,data:{action:e,backend:t,textLength:Array.from(n).length}})}function lp(e,t,n){return Math.max(t,Math.min(n,e))}var up=e({ANDROID_FOCUSED_WINDOW_MARKER:()=>gt,ANDROID_FOCUS_MARKERS:()=>mt,ANDROID_IME_HELPER_SERVICE_COMPONENT:()=>`com.callstack.agentdevice.imehelper/.TestInputMethodService`,ANDROID_SNAPSHOT_PRESENTATION_DEFAULT_DEADLINE_MS:()=>250,ANDROID_TEST_IME_SETTINGS_KEYS:()=>ko,ANDROID_TOUCH_PLAN_PROTOCOL:()=>Ri,AndroidSnapshotPresentationFailure:()=>X,activateAndroidTestIme:()=>du,androidAdbForwardsDeviceExitStatus:()=>At,androidAdbResultError:()=>b,androidAppsDiscoveryHint:()=>dt,androidCaptureFailureReasonDetail:()=>j,androidCaptureFailureReasonFromExitCode:()=>nr,androidCaptureFailureReasonFromHelperResult:()=>tr,androidDeviceChecks:()=>qo,androidFillFailureDetails:()=>Kl,androidFillFailureMessage:()=>Gl,androidRevokedPermissionWarning:()=>df,androidSnapshotPublicationInput:()=>ll,androidToolchainCheck:()=>Ko,androidUiNodes:()=>_c,annotateAndroidNativePerfError:()=>M,appSwitcherAndroid:()=>ha,attachAdbFailureHint:()=>Me,backAndroid:()=>sa,buildAndroidFillUnconfirmedVerification:()=>Hl,buildAndroidNativeToolUnavailableHint:()=>_r,buildAndroidSnapshotClickabilityEvidence:()=>jc,buildAndroidSnapshotHelperArgs:()=>Yr,buildAndroidSnapshotHelperCaptureOptions:()=>qr,buildUiHierarchySnapshot:()=>Zs,captureAndroidHeapSnapshot:()=>Ud,captureAndroidLogcatWithAdb:()=>fp,captureAndroidSnapshotWithHelper:()=>Kr,captureAndroidSnapshotWithHelperSession:()=>Ni,classifyAdbFailure:()=>Pe,classifyAndroidAlertIdentifier:()=>Ht,classifyAndroidAppTarget:()=>ot,classifyAndroidHelperContent:()=>Nc,cleanupAndroidNativePerfSession:()=>yd,clearAndroidImeHelperText:()=>wo,clearAndroidTestImeRecoveryMarker:()=>_u,closeAndroidApp:()=>tt,completeAndroidFillVerification:()=>Z,createAndroidPortReverseManager:()=>Ie,createAndroidSnapshotCapture:()=>cl,createAndroidSnapshotPresentationBudget:()=>Ks,createAndroidSnapshotPresentationNode:()=>Hs,createAndroidWindowDumpReader:()=>bt,createDeviceAdbExecutor:()=>Be,createLocalAndroidAdbProvider:()=>Le,dismissAndroidKeyboard:()=>Ya,dismissAndroidKeyboardWithAdb:()=>Xa,ensureAndroidEmulatorBooted:()=>it,ensureAndroidImeHelper:()=>bo,ensureAndroidSdkPathConfigured:()=>et,ensureAndroidSnapshotHelper:()=>Jn,executeAndroidTouchHelperPlan:()=>Hi,executeAndroidTouchPlan:()=>na,fillAndroid:()=>Gf,findAndroidAlertCandidate:()=>Ut,focusAndroid:()=>_a,forceStopAndroidAppWithAdb:()=>Na,forgetAndroidSnapshotHelperInstall:()=>Un,formatAndroidInstalledPackageRequiredMessage:()=>lt,getAndroidAppState:()=>vt,getAndroidBlockingDialogObservation:()=>yt,getAndroidImeHelperDeviceKey:()=>W,getAndroidKeyboardState:()=>V,getAndroidKeyboardStatusWithAdb:()=>H,getAndroidScreenSize:()=>xa,handleAndroidAlert:()=>Sa,homeAndroid:()=>ca,inferAndroidAppName:()=>ct,inferAndroidPackageAfterOpen:()=>mp,inspectInstalledAndroidHelper:()=>Cn,installAndroidAdbPackage:()=>He,installAndroidInstallablePath:()=>Wa,isAmStartError:()=>rt,isAndroidImeHelperPackage:()=>So,isAndroidPermissionPackage:()=>Pt,isAndroidShellCommandUnsupported:()=>We,isAndroidSnapshotPresentationFailure:()=>Ws,isAndroidTestImeActive:()=>Io,listAndroidAdbSerialsQuick:()=>Wo,listAndroidAppsWithAdb:()=>dp,longPressAndroid:()=>ga,lowerAndroidTouchPlan:()=>ea,makeEnsureAndroidHelperInstalled:()=>Tn,normalizeAndroidTouchHelperGestureRequest:()=>qi,openAndroidApp:()=>$e,openAndroidAppWithAdb:()=>Fa,openAndroidDevice:()=>Ze,parseAndroidHelperManifest:()=>In,parseAndroidLaunchComponent:()=>nt,parseAndroidLaunchablePackages:()=>pt,parseAndroidSnapshotHelperManifest:()=>In,parseAndroidSnapshotHelperOutput:()=>ii,parseAndroidUserInstalledPackages:()=>ft,parseInstrumentationRecords:()=>pn,parseUiHierarchyTree:()=>kc,prepareAndroidInstallArtifact:()=>Iu,pressAndroid:()=>aa,pressAndroidEnter:()=>la,pressAndroidTvRemote:()=>oa,pullAndroidAdbFile:()=>ze,pushAndroidNotification:()=>zu,readAndroidBlockingDialogFocus:()=>ht,readAndroidClipboardText:()=>so,readAndroidClipboardWithAdb:()=>co,readAndroidDefaultInputMethod:()=>G,readAndroidFillTargetBeforeMutation:()=>Vl,readAndroidGestureViewport:()=>ra,readAndroidHelperManifestInteger:()=>un,readAndroidHelperManifestLiteral:()=>E,readAndroidTestImeRecoveryMarkers:()=>vu,readAndroidTextAtPoint:()=>zl,readAndroidTextAtPointInHierarchy:()=>Wl,readAndroidTouchHelperFinalRecord:()=>Xi,readAndroidTouchHelperViewportReading:()=>Ui,readInstrumentationResultBoolean:()=>yn,readInstrumentationResultNumber:()=>D,resetAndroidAdbShellProtocolProbes:()=>jt,resetAndroidFramePerfStats:()=>md,resetAndroidImeHelperInstallCache:()=>xo,resetAndroidSnapshotHelperInstallCache:()=>Wn,resetAndroidSnapshotHelperRuntime:()=>ol,resetAndroidSnapshotHelperSessions:()=>Mi,resetAndroidTestImeActivationCacheForTests:()=>Ro,resetAndroidWindowDumpFocusMemoForTests:()=>_t,resolveAndroidAdbExecutor:()=>x,resolveAndroidAdbProvider:()=>S,resolveAndroidApp:()=>ut,resolveAndroidArchivePackageName:()=>Cu,resolveAndroidHelperArtifact:()=>wn,resolveAndroidImeHelperArtifact:()=>_o,resolveAndroidPackageForOpen:()=>pp,resolveAndroidSnapshotHelperCaptureOptions:()=>Jr,resolveAndroidTextInjector:()=>Ve,resolveAndroidTouchProvider:()=>Fe,resolveScopedAndroidAdbBackgroundTransport:()=>Re,restoreAndroidTestIme:()=>Bo,restoreOrphanedAndroidTestImeOnDaemonStartup:()=>Uo,retireAndroidSnapshotHelperAfterContentFailure:()=>al,runAndroidAdb:()=>C,runAndroidHostAdb:()=>je,runAndroidSnapshotHelperSessionTouchCommand:()=>Fi,sampleAndroidFramePerf:()=>pd,sampleAndroidMemoryPerf:()=>Hd,screenshotAndroid:()=>zf,scrollAndroid:()=>va,selectAndroidImeHelperArtifact:()=>go,sendAndroidImeHelperText:()=>Co,setAndroidOrientation:()=>ua,setAndroidPermission:()=>pf,setAndroidSetting:()=>jf,setAndroidTestImeActiveForTests:()=>zo,sleep:()=>g,snapshotAndroid:()=>dl,startAndroidPerfettoTrace:()=>kd,startAndroidSimpleperfProfile:()=>Nd,stopAndroidPerfettoTrace:()=>Ad,stopAndroidSimpleperfProfile:()=>Pd,stopAndroidSnapshotHelperSession:()=>B,stopAndroidSnapshotHelperSessionForDevice:()=>ji,typeAndroid:()=>Wf,validateAndroidGestureViewport:()=>O,validateAndroidRegularPresentation:()=>qs,verifyAndroidFilledText:()=>Rl,verifyAndroidFilledTextInHierarchy:()=>Ul,verifyAndroidHelperApkChecksum:()=>kn,waitForAndroidBoot:()=>Qe,withAndroidAdbProvider:()=>Ue,withAndroidAppResolutionCacheInvalidated:()=>st,withAndroidHostAdbTransport:()=>Ae,writeAndroidClipboardText:()=>lo,writeAndroidClipboardWithAdb:()=>uo,writeAndroidSimpleperfReport:()=>Fd,writeAndroidTestImeRecoveryMarker:()=>gu});async function dp(...e){let{listAndroidAppsWithAdb:t}=await import(`./app-helpers.js`);return await t(...e)}async function fp(...e){let{captureAndroidLogcatWithAdb:t}=await import(`./logcat.js`);return await t(...e)}async function pp(...e){let{resolveAndroidPackageForOpen:t}=await import(`./open-target-resolution.js`);return await t(...e)}async function mp(...e){let{inferAndroidPackageAfterOpen:t}=await import(`./open-target-resolution.js`);return await t(...e)}export{ua as A,_a as C,la as D,aa as E,ra as M,oa as O,sa as S,ga as T,uo as _,Wf as a,Sa as b,dl as c,Xa as d,V as f,lo as g,co as h,Gf as i,na as j,va as k,ll as l,so as m,dp as n,zf as o,H as p,up as r,jf as s,fp as t,Ya as u,Na as v,ca as w,ha as x,Fa as y};