agent-device 0.21.23 → 0.21.25

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 (435) hide show
  1. package/README.md +6 -6
  2. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.23.apk → agent-device-android-ime-helper-0.21.25.apk} +0 -0
  3. package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.25.apk.sha256 +1 -0
  4. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.23.manifest.json → agent-device-android-ime-helper-0.21.25.manifest.json} +4 -4
  5. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.25.apk +0 -0
  6. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.25.apk.sha256 +1 -0
  7. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.25.manifest.json +16 -0
  8. package/apple/macos-helper/Sources/AgentDeviceMacOSHelper/SnapshotTraversal.swift +12 -6
  9. package/apple/macos-helper/Tests/AgentDeviceMacOSHelperTests/RectResponseTests.swift +21 -0
  10. package/apple/snapshot-bridge/README.md +9 -7
  11. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +159 -4
  12. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerHttpRequestFraming.swift +139 -0
  13. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerListenerPeer.swift +41 -0
  14. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerListenerToken.swift +25 -0
  15. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandDispatch.swift +56 -0
  16. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +14 -5
  17. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Environment.swift +18 -11
  18. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +8 -0
  19. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +12 -0
  20. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Navigation.swift +25 -1
  21. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCaptureTarget.swift +1 -1
  22. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotExecution.swift +29 -5
  23. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedTextEntry.swift +0 -3
  24. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +35 -13
  25. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryConfirmation.swift +59 -26
  26. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryFocus.swift +19 -5
  27. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextTyping.swift +50 -106
  28. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Transport.swift +142 -54
  29. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TypeExecution.swift +4 -1
  30. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +21 -19
  31. package/dist/src/absence-observation-errors.js +1 -0
  32. package/dist/src/adapter.js +1 -1
  33. package/dist/src/adb-executor.js +2 -2
  34. package/dist/src/adb-failure.js +2 -2
  35. package/dist/src/adb.js +1 -1
  36. package/dist/src/agent-browser-lifecycle.js +1 -1
  37. package/dist/src/agent-browser-process-record.js +1 -1
  38. package/dist/src/agent-browser-provider.js +1 -1
  39. package/dist/src/agent-browser-tool.js +1 -1
  40. package/dist/src/agent-device-client.js +2 -2
  41. package/dist/src/alert.js +1 -1
  42. package/dist/src/android-adb.d.ts +3 -2
  43. package/dist/src/android-adb.js +1 -1
  44. package/dist/src/android-input-ownership.js +1 -1
  45. package/dist/src/android-system-surface-disclosure.js +1 -0
  46. package/dist/src/android-text-entry.js +1 -0
  47. package/dist/src/android.js +1 -1
  48. package/dist/src/app-backend.js +1 -1
  49. package/dist/src/app-helpers.js +1 -1
  50. package/dist/src/app-inventory.d.ts +4 -0
  51. package/dist/src/app-launch.js +1 -1
  52. package/dist/src/app-lifecycle.js +4 -3
  53. package/dist/src/app-lifecycle2.js +2 -2
  54. package/dist/src/app-log-files.js +1 -1
  55. package/dist/src/app-log-reconnect.js +1 -1
  56. package/dist/src/app-log-runtime2.js +3 -3
  57. package/dist/src/app-resolution-facade.js +1 -1
  58. package/dist/src/app-resolution.js +2 -2
  59. package/dist/src/app-state-runtime.d.ts +15 -0
  60. package/dist/src/apple-runner-platform.js +1 -1
  61. package/dist/src/application-lifecycle-interaction.js +1 -1
  62. package/dist/src/artifact-download.js +1 -1
  63. package/dist/src/auth.js +1 -1
  64. package/dist/src/aws-device-farm-connection.js +1 -0
  65. package/dist/src/back-mode.js +1 -1
  66. package/dist/src/backend-snapshot-options.js +1 -1
  67. package/dist/src/boot-diagnostics.js +1 -1
  68. package/dist/src/browserstack-connection.js +1 -0
  69. package/dist/src/capture-disclosure.js +1 -0
  70. package/dist/src/cli-config.js +1 -1
  71. package/dist/src/cli-help.js +36 -17
  72. package/dist/src/cli-output.js +1 -1
  73. package/dist/src/cli-runner.js +3 -1
  74. package/dist/src/cli.js +3 -4
  75. package/dist/src/client-companion-tunnel.js +1 -0
  76. package/dist/src/client-metro.js +1 -1
  77. package/dist/src/client-types.d.ts +15 -7
  78. package/dist/src/cloud-artifacts.d.ts +3 -2
  79. package/dist/src/code-signature-cache.js +1 -1
  80. package/dist/src/code-signature.js +1 -1
  81. package/dist/src/command-metadata.js +73 -1
  82. package/dist/src/command-policy.js +1 -0
  83. package/dist/src/command-schema.js +3 -3
  84. package/dist/src/command-surface.js +1 -1
  85. package/dist/src/command-tools.js +2 -2
  86. package/dist/src/connection-runtime.js +1 -1
  87. package/dist/src/connection-verification.js +1 -0
  88. package/dist/src/connection.js +5 -5
  89. package/dist/src/contracts.d.ts +1 -1
  90. package/dist/src/contracts.js +1 -1
  91. package/dist/src/daemon-client-lease-beat.js +1 -1
  92. package/dist/src/daemon-client-lifecycle.js +1 -1
  93. package/dist/src/daemon-client-liveness-probe.js +1 -1
  94. package/dist/src/daemon-policy-file.js +1 -1
  95. package/dist/src/daemon-registration-owner.js +1 -1
  96. package/dist/src/daemon-registration.js +1 -1
  97. package/dist/src/daemon-resolution.js +3 -1
  98. package/dist/src/debug-symbols-facade.js +1 -1
  99. package/dist/src/device-claim-inspection.js +1 -1
  100. package/dist/src/device-input-state.d.ts +6 -17
  101. package/dist/src/device-inventory-context.js +1 -1
  102. package/dist/src/device-readiness-runtime.js +1 -1
  103. package/dist/src/device-release.js +1 -1
  104. package/dist/src/device-selection-resolver.js +1 -1
  105. package/dist/src/device-shell.js +1 -1
  106. package/dist/src/device.js +3 -1
  107. package/dist/src/devicectl.js +1 -1
  108. package/dist/src/diagnostics.js +1 -1
  109. package/dist/src/doctor-facade.js +1 -1
  110. package/dist/src/durable-capture-resource.js +1 -1
  111. package/dist/src/durable-resource.js +1 -1
  112. package/dist/src/engine-eval-script.js +1 -1
  113. package/dist/src/error.js +1 -1
  114. package/dist/src/exec.js +1 -1
  115. package/dist/src/expo-dev-client-launch.js +1 -0
  116. package/dist/src/file.js +3 -1
  117. package/dist/src/find.js +1 -1
  118. package/dist/src/finders.js +1 -1
  119. package/dist/src/generic-settle.js +1 -1
  120. package/dist/src/generic.js +1 -1
  121. package/dist/src/gesture-admission.js +1 -1
  122. package/dist/src/gesture-plan-types.d.ts +2 -5
  123. package/dist/src/gesture-plan.js +1 -1
  124. package/dist/src/gesture-runtime.js +1 -1
  125. package/dist/src/harmonyos.js +1 -1
  126. package/dist/src/hdc.js +1 -1
  127. package/dist/src/helper.js +2 -2
  128. package/dist/src/human-control.js +1 -1
  129. package/dist/src/ime-rebind.js +1 -1
  130. package/dist/src/ime-state.js +1 -1
  131. package/dist/src/index.d.ts +4 -4
  132. package/dist/src/index.js +1 -1
  133. package/dist/src/input-actions.js +1 -1
  134. package/dist/src/input-actions2.js +2 -2
  135. package/dist/src/install-source-network-transport.js +1 -1
  136. package/dist/src/install-source2.js +1 -1
  137. package/dist/src/interaction-error.js +1 -0
  138. package/dist/src/interaction-positionals.js +1 -1
  139. package/dist/src/interaction.js +1 -1
  140. package/dist/src/interaction2.js +1 -1
  141. package/dist/src/interactor-operation-catalog.js +1 -1
  142. package/dist/src/interactor.js +5 -5
  143. package/dist/src/interactor2.js +1 -1
  144. package/dist/src/interactors.js +1 -1
  145. package/dist/src/internal/bin.js +1 -1
  146. package/dist/src/internal/daemon.js +5 -1
  147. package/dist/src/internal/png-worker.js +1 -1
  148. package/dist/src/inventory.js +2 -2
  149. package/dist/src/inventory2.js +1 -1
  150. package/dist/src/inventory6.js +1 -1
  151. package/dist/src/io.d.ts +2 -2
  152. package/dist/src/ios-client.js +1 -1
  153. package/dist/src/ios-settings.js +1 -1
  154. package/dist/src/ios-snapshot-acquisition.js +1 -1
  155. package/dist/src/ios-snapshot-adapter.js +1 -1
  156. package/dist/src/ios-snapshot-engine.js +1 -1
  157. package/dist/src/ios-snapshot-runtime.js +1 -1
  158. package/dist/src/keyed-lock.js +1 -1
  159. package/dist/src/launch-confirmation.js +1 -1
  160. package/dist/src/lease.js +1 -1
  161. package/dist/src/limrun-runtime-dependencies.js +1 -1
  162. package/dist/src/limrun.d.ts +5 -564
  163. package/dist/src/limrun.js +1 -1
  164. package/dist/src/linux.js +1 -1
  165. package/dist/src/load.js +1 -1
  166. package/dist/src/local-interactor-operation-set.js +1 -1
  167. package/dist/src/log-stream.js +9 -9
  168. package/dist/src/mechanics.js +16 -16
  169. package/dist/src/metro.js +1 -1
  170. package/dist/src/metro2.js +1 -1
  171. package/dist/src/mobile-snapshot-semantics.js +1 -1
  172. package/dist/src/observability.js +1 -1
  173. package/dist/src/observation.js +1 -2
  174. package/dist/src/open-target-resolution.js +1 -1
  175. package/dist/src/output-path.js +1 -1
  176. package/dist/src/overlay.js +1 -3
  177. package/dist/src/perf-facade.js +1 -1
  178. package/dist/src/perf-runtime-operation-builder.js +1 -1
  179. package/dist/src/perf-runtime.js +1 -1
  180. package/dist/src/perf-target.js +1 -1
  181. package/dist/src/physical-device-control.js +1 -1
  182. package/dist/src/platform-request-scope.js +1 -1
  183. package/dist/src/platform-runtime-android-adb-host.js +1 -1
  184. package/dist/src/platform-runtime-app-log-android-transport.js +1 -1
  185. package/dist/src/platform-runtime-apple-resources.js +1 -0
  186. package/dist/src/platform-runtime-claim-recovery.js +1 -0
  187. package/dist/src/platform-runtime-daemon-services.js +1 -0
  188. package/dist/src/platform-runtime-host.js +1 -1
  189. package/dist/src/platform-runtime-network-web-transport.js +1 -1
  190. package/dist/src/platform-runtime-open-target.js +1 -1
  191. package/dist/src/platform-runtime-operation-host.js +4 -4
  192. package/dist/src/platform-runtime-runtime-hints.js +2 -2
  193. package/dist/src/platform-runtime-screen-recording-android-host.js +1 -1
  194. package/dist/src/platform-runtime-screen-recording-apple-runner-transport.js +1 -1
  195. package/dist/src/platform-runtime-screen-recording-apple-simulator-host.js +1 -1
  196. package/dist/src/platform-runtime-screen-recording-finalizer-host.js +1 -1
  197. package/dist/src/platform-runtime-screen-recording-harmony-host.js +1 -1
  198. package/dist/src/platform-runtime-screen-recording-web-host.js +1 -1
  199. package/dist/src/platform-runtime-unavailable.js +1 -1
  200. package/dist/src/platform-runtime.js +1 -1
  201. package/dist/src/platform-runtime2.js +1 -1
  202. package/dist/src/plugin.js +1 -0
  203. package/dist/src/plugins/webdriver.d.ts +111 -0
  204. package/dist/src/plugins/webdriver.js +1 -0
  205. package/dist/src/plugins.d.ts +2 -1
  206. package/dist/src/plugins2.js +1 -1
  207. package/dist/src/png-crop-bytes.js +1 -1
  208. package/dist/src/png-resize.js +1 -0
  209. package/dist/src/png-worker-client.js +1 -1
  210. package/dist/src/png-worker-contract.js +1 -1
  211. package/dist/src/process-entry.js +1 -1
  212. package/dist/src/process-exit.js +1 -1
  213. package/dist/src/process.js +1 -1
  214. package/dist/src/provider-credential-fingerprint.js +1 -1
  215. package/dist/src/provider-device-admission.js +1 -1
  216. package/dist/src/provider-device-runtime.d.ts +556 -0
  217. package/dist/src/provider-policy.js +1 -0
  218. package/dist/src/provider-profile-fields.js +1 -1
  219. package/dist/src/provider-webdriver.js +1 -2
  220. package/dist/src/proxy.js +2 -2
  221. package/dist/src/quality-warnings.js +1 -1
  222. package/dist/src/react-devtools.js +2 -0
  223. package/dist/src/react-native-overlay2.js +3 -0
  224. package/dist/src/react-native.js +1 -1
  225. package/dist/src/record-runtime.js +1 -1
  226. package/dist/src/record-trace.js +1 -1
  227. package/dist/src/recording.js +2 -2
  228. package/dist/src/register-builtins.js +1 -1
  229. package/dist/src/remote-bridge.js +1 -0
  230. package/dist/src/remote-config-core.js +1 -0
  231. package/dist/src/remote-config.js +1 -1
  232. package/dist/src/remote-config2.js +1 -1
  233. package/dist/src/replay-backend-registry.js +1 -0
  234. package/dist/src/replay-divergence.js +1 -1
  235. package/dist/src/replay-maestro-backend.js +117 -0
  236. package/dist/src/replay-script-selection.js +1 -0
  237. package/dist/src/replay.js +1 -3
  238. package/dist/src/replay2.js +1 -0
  239. package/dist/src/reporting.js +3 -3
  240. package/dist/src/request-cancel.js +1 -1
  241. package/dist/src/request-providers.js +1 -1
  242. package/dist/src/request-runtime-binding.js +1 -1
  243. package/dist/src/result-serialization.js +1 -1
  244. package/dist/src/retry.js +1 -1
  245. package/dist/src/retry2.js +1 -0
  246. package/dist/src/runner-artifact-manifest.js +1 -1
  247. package/dist/src/runner-cache-retention.js +1 -0
  248. package/dist/src/runner-cache-trim.js +1 -0
  249. package/dist/src/runner-client.js +1 -1
  250. package/dist/src/runner-dev-tools-security.js +1 -1
  251. package/dist/src/runner-device-readiness.js +1 -1
  252. package/dist/src/runner-device-set.js +1 -0
  253. package/dist/src/runner-error-classification.js +3 -3
  254. package/dist/src/runner-exchange.js +1 -1
  255. package/dist/src/runner-lease.js +1 -0
  256. package/dist/src/runner-operations-facade.js +1 -1
  257. package/dist/src/runner-retention.js +1 -0
  258. package/dist/src/runner-start-budget.js +1 -1
  259. package/dist/src/runner-startup-transport.js +1 -0
  260. package/dist/src/runner-toolchain-probe.js +2 -0
  261. package/dist/src/runner.js +2 -1
  262. package/dist/src/runtime-command-surface.js +1 -0
  263. package/dist/src/runtime-deployment.js +1 -0
  264. package/dist/src/runtime-factory.js +1 -0
  265. package/dist/src/runtime-session.js +1 -0
  266. package/dist/src/runtime-transport-hints.js +1 -1
  267. package/dist/src/runtime.js +2 -1
  268. package/dist/src/runtime10.js +2 -2
  269. package/dist/src/runtime2.js +4 -4
  270. package/dist/src/runtime3.js +1 -1
  271. package/dist/src/runtime4.js +5 -5
  272. package/dist/src/runtime5.js +1 -1
  273. package/dist/src/runtime6.js +1 -1
  274. package/dist/src/runtime7.js +1 -1
  275. package/dist/src/runtime8.js +1 -1
  276. package/dist/src/runtime9.js +1 -1
  277. package/dist/src/screen-recording-transport.js +1 -1
  278. package/dist/src/screenshot-density.js +1 -1
  279. package/dist/src/screenshot-image.js +1 -1
  280. package/dist/src/screenshot-runtime.js +1 -1
  281. package/dist/src/screenshot3.js +5 -5
  282. package/dist/src/sdk-batch-runner.js +2 -2
  283. package/dist/src/sdk-batch.js +2 -2
  284. package/dist/src/sdk-contracts.d.ts +20 -29
  285. package/dist/src/sdk-contracts.js +2 -2
  286. package/dist/src/sdk-device.js +1 -1
  287. package/dist/src/sdk-finders.d.ts +1 -1
  288. package/dist/src/sdk-finders.js +1 -1
  289. package/dist/src/sdk-io.d.ts +4 -2
  290. package/dist/src/sdk-remote-config.d.ts +4 -0
  291. package/dist/src/sdk-remote-config.js +1 -1
  292. package/dist/src/sdk-selectors.d.ts +5 -6
  293. package/dist/src/sdk-selectors.js +1 -1
  294. package/dist/src/selection.js +0 -0
  295. package/dist/src/selector-pipeline-policy.js +1 -1
  296. package/dist/src/selector-runtime.js +1 -1
  297. package/dist/src/selectors.js +1 -1
  298. package/dist/src/server.js +2 -2
  299. package/dist/src/session-allocation.js +1 -1
  300. package/dist/src/session-replay-runtime-failure-response.js +1 -0
  301. package/dist/src/session-runtime-admission.js +1 -1
  302. package/dist/src/session.js +1 -1
  303. package/dist/src/session2.js +5 -5
  304. package/dist/src/settings.js +1 -1
  305. package/dist/src/settings2.js +1 -1
  306. package/dist/src/simctl-settings.js +1 -1
  307. package/dist/src/simctl.js +1 -1
  308. package/dist/src/simulator-boot.js +1 -1
  309. package/dist/src/simulator-state.js +1 -1
  310. package/dist/src/simulator.js +1 -1
  311. package/dist/src/snapshot-capture-annotations.js +1 -1
  312. package/dist/src/snapshot-chrome.js +1 -0
  313. package/dist/src/snapshot-desktop-projection.js +1 -1
  314. package/dist/src/snapshot-evidence.js +1 -0
  315. package/dist/src/snapshot-node-lookup.js +1 -0
  316. package/dist/src/snapshot-occlusion.js +1 -0
  317. package/dist/src/snapshot-quality-verdict.js +1 -0
  318. package/dist/src/snapshot-runtime-binding.js +1 -1
  319. package/dist/src/snapshot-runtime.js +1 -1
  320. package/dist/src/snapshot-state.js +1 -1
  321. package/dist/src/snapshot.js +1 -1
  322. package/dist/src/snapshot2.js +1 -1
  323. package/dist/src/snapshot3.js +1 -1
  324. package/dist/src/src.js +5 -1
  325. package/dist/src/src2.js +1 -1
  326. package/dist/src/src3.js +2 -1
  327. package/dist/src/store.js +1 -1
  328. package/dist/src/surface-snapshot2.js +1 -1
  329. package/dist/src/target-evidence-tree.js +1 -0
  330. package/dist/src/target-evidence.js +1 -1
  331. package/dist/src/text-entry-focus.js +1 -1
  332. package/dist/src/tool-provider2.js +1 -1
  333. package/dist/src/touch-runtime.js +1 -1
  334. package/dist/src/touch-runtime2.js +1 -1
  335. package/dist/src/tree.js +1 -1
  336. package/dist/src/tv-remote.js +1 -1
  337. package/dist/src/type-text-runtime.js +1 -1
  338. package/dist/src/undici.js +8 -8
  339. package/dist/src/update-check.js +1 -1
  340. package/dist/src/vars.js +1 -1
  341. package/dist/src/version.js +1 -1
  342. package/dist/src/video.js +2 -2
  343. package/dist/src/wait.js +1 -0
  344. package/dist/src/web.js +1 -1
  345. package/dist/src/web2.js +1 -1
  346. package/package.json +22 -19
  347. package/server.json +2 -2
  348. package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.23.apk.sha256 +0 -1
  349. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.23.apk +0 -0
  350. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.23.apk.sha256 +0 -1
  351. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.23.manifest.json +0 -16
  352. package/dist/src/adb-transport.js +0 -1
  353. package/dist/src/alert-runtime.js +0 -1
  354. package/dist/src/app-deployment-resolution.js +0 -2
  355. package/dist/src/app-inventory-contract.js +0 -1
  356. package/dist/src/app-log-session-resource.js +0 -1
  357. package/dist/src/application-lifecycle-runtime.js +0 -1
  358. package/dist/src/auth-session.js +0 -1
  359. package/dist/src/cache.js +0 -1
  360. package/dist/src/capabilities.js +0 -1
  361. package/dist/src/capture.js +0 -1
  362. package/dist/src/catalog.js +0 -1
  363. package/dist/src/click-button.js +0 -1
  364. package/dist/src/client-metro-companion.js +0 -1
  365. package/dist/src/client-options.js +0 -3
  366. package/dist/src/compatibility-policy.js +0 -1
  367. package/dist/src/daemon-artifacts.js +0 -1
  368. package/dist/src/daemon-client-transport.js +0 -1
  369. package/dist/src/daemon-http.js +0 -1
  370. package/dist/src/device-claim-rule.js +0 -1
  371. package/dist/src/device-rotation.js +0 -1
  372. package/dist/src/device-session.js +0 -3
  373. package/dist/src/device2.js +0 -1
  374. package/dist/src/device3.js +0 -3
  375. package/dist/src/dispatch-resolve.js +0 -4
  376. package/dist/src/format.js +0 -1
  377. package/dist/src/gesture-plan-types.js +0 -1
  378. package/dist/src/host.js +0 -1
  379. package/dist/src/human-control-contract.js +0 -1
  380. package/dist/src/interaction-ref-policy.js +0 -1
  381. package/dist/src/interactor-operation-binding.js +0 -1
  382. package/dist/src/keyboard-actions.js +0 -1
  383. package/dist/src/lease-context.js +0 -1
  384. package/dist/src/lease-registry-scope.js +0 -1
  385. package/dist/src/lease-scope.js +0 -1
  386. package/dist/src/managed-device-scope.js +0 -1
  387. package/dist/src/observe-until.js +0 -1
  388. package/dist/src/output-common.js +0 -5
  389. package/dist/src/owner-identity.js +0 -3
  390. package/dist/src/path-resolution.js +0 -1
  391. package/dist/src/perf-runtime-plan.js +0 -1
  392. package/dist/src/platform-runtime-app-log-process.js +0 -1
  393. package/dist/src/platform-runtime-managed-owner.js +0 -1
  394. package/dist/src/platform-runtime-screen-recording-process-host.js +0 -1
  395. package/dist/src/png.js +0 -1
  396. package/dist/src/prepare-kind.js +0 -1
  397. package/dist/src/provider-device-runtimes.js +0 -1
  398. package/dist/src/provider-session-ownership.js +0 -2
  399. package/dist/src/providers.js +0 -1
  400. package/dist/src/registry.js +0 -68
  401. package/dist/src/request-admission.js +0 -1
  402. package/dist/src/request-cancellation.js +0 -1
  403. package/dist/src/request-progress-protocol.js +0 -1
  404. package/dist/src/runner-cache-metadata.js +0 -3
  405. package/dist/src/runner-disposal.js +0 -1
  406. package/dist/src/runner-session-types.js +0 -1
  407. package/dist/src/runtime-admission.js +0 -1
  408. package/dist/src/screen-recording-admission-ledger.js +0 -1
  409. package/dist/src/screen-recording-resource-recovery.js +0 -1
  410. package/dist/src/screenshot-result.js +0 -1
  411. package/dist/src/script.js +0 -1
  412. package/dist/src/scroll-command.js +0 -1
  413. package/dist/src/scroll-gesture.js +0 -1
  414. package/dist/src/scroll-indicator.js +0 -1
  415. package/dist/src/session-artifact-paths.js +0 -1
  416. package/dist/src/session-paths.js +0 -1
  417. package/dist/src/session-repair-tombstone.js +0 -1
  418. package/dist/src/session-routing.js +0 -1
  419. package/dist/src/session-snapshot.js +0 -1
  420. package/dist/src/snapshot4.js +0 -1
  421. package/dist/src/src4.js +0 -1
  422. package/dist/src/src5.js +0 -1
  423. package/dist/src/src6.js +0 -1
  424. package/dist/src/src7.js +0 -2
  425. package/dist/src/src8.js +0 -115
  426. package/dist/src/string-enum.js +0 -1
  427. package/dist/src/success-text.js +0 -1
  428. package/dist/src/timeouts.js +0 -1
  429. package/dist/src/touch-reference-frame.js +0 -1
  430. package/dist/src/transport.js +0 -3
  431. package/dist/src/ttl-memo.js +0 -1
  432. package/dist/src/verified-file.js +0 -1
  433. package/dist/src/viewport.js +0 -1
  434. package/dist/src/window-state.js +0 -1
  435. /package/dist/src/{doctor-output.js → doctor-lines.js} +0 -0
@@ -1,19 +1,19 @@
1
- import{r as e}from"./rolldown-runtime.js";import{$ as t,B as n,F as r,J as i,P as a,b as o,rt as s,tt as c,v as l,z as u}from"./sdk-contracts.js";import"./capture.js";import{k as d,p as f}from"./sdk-batch-runner.js";import{a as p,d as m,i as ee,l as te,o as ne,r as re,t as ie,u as ae}from"./android-input-ownership.js";import{c as h,r as g}from"./diagnostics.js";import"./diagnostics2.js";import{Hr as oe,Kr as se,Ur as ce,Wr as le,Yr as ue,Zr as de,ni as fe,qr as pe,ti as me}from"./sdk-batch.js";import{_ as he,d as ge,p as _e}from"./scroll-gesture.js";import{r as ve}from"./success-text.js";import{n as ye}from"./alert-contract.js";import{T as be,_ as xe,b as Se,d as Ce,v as we,x as Te,y as Ee}from"./settings.js";import{n as De}from"./location-coordinates.js";import{r as Oe}from"./mobile-snapshot-semantics.js";import"./device.js";import{n as ke,s as Ae}from"./device-rotation.js";import{c as je,g as Me,l as Ne,o as Pe,r as Fe}from"./exec.js";import{t as _}from"./timeouts.js";import{i as Ie}from"./tv-remote.js";import"./command.js";import{a as Le,r as Re}from"./version.js";import"./retry.js";import{r as ze}from"./install-source2.js";import{_ as Be,a as v,c as Ve,d as y,f as He,g as b,h as x,i as Ue,l as We,n as Ge,o as S,p as Ke,r as qe,s as Je,t as Ye,u as Xe,v as Ze}from"./adb-executor.js";import{a as C,n as Qe,o as w}from"./device-shell.js";import{c as $e,h as et,i as tt,o as nt,r as rt,u as it}from"./adb-transport.js";import{c as at,i as ot,l as st,n as T,o as ct,s as lt}from"./adb-failure.js";import{a as ut,i as dt,n as ft,o as E}from"./adb.js";import{i as pt,n as mt,r as ht}from"./gesture-plan.js";import{C as gt,S as _t,T as vt,_ as yt,a as bt,b as xt,c as St,d as Ct,f as wt,g as Tt,h as Et,i as Dt,l as Ot,n as kt,o as At,p as jt,r as Mt,s as Nt,t as D,u as O,v as k,w as Pt,x as Ft,y as It}from"./ime-state.js";import{n as Lt}from"./android-snapshot-quality.js";import{a as Rt,c as zt,i as Bt,l as Vt,n as Ht,o as Ut,r as Wt,s as Gt,u as Kt}from"./app-lifecycle.js";import{a as qt,i as Jt,n as Yt,o as Xt,r as Zt,t as Qt}from"./app-deployment-resolution.js";import{a as $t,i as en,n as tn,o as nn,t as rn}from"./app-parsers.js";import{i as an,n as on,r as sn,t as cn}from"./window-state.js";import{i as ln,r as un}from"./toolchain-probe.js";import{n as dn,r as fn}from"./android-system-chrome.js";import{t as pn}from"./bounds.js";import{t as mn}from"./entities.js";import{n as hn}from"./startup-recovery-fence.js";import{n as gn}from"./numeric.js";import A from"node:path";import _n from"node:net";import{TextDecoder as vn}from"node:util";const yn=new Map;async function bn(e){let t=yn.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=Sn(n).includes(`shell_v2`);return yn.set(e.deviceKey,r),r}function xn(){yn.clear()}function Sn(e){return e.split(`
2
- `).map(e=>e.trim()).filter(Boolean)}const Cn=new Set([`com.android.permissioncontroller`,`com.google.android.permissioncontroller`,`com.google.android.packageinstaller`,`com.android.packageinstaller`]);function wn(e){return Cn.has(e)}const Tn=new Set([`android`,`com.android.systemui`]),En=/^android:id\/(?:alertTitle|message|button[123]|parentPanel|buttonPanel|contentPanel)$/i,Dn=/^android:id\/button[123]$/i,On=/(?:^|:)id\/permission_/i,kn=/\b(?:is(?:n't| not) responding|keeps stopping|has stopped|close app|app info)\b/i,An=/^(?:ok|allow|allow all|while using the app|only this time|yes|continue|save|confirm|turn on|open settings)$/i,jn=/^(?:cancel|deny|don.t allow|don’t allow|not now|no|dismiss|close|close app|later|skip)$/i;function Mn(e){if(e!==null){if(Dn.test(e))return`button`;if(En.test(e))return`content`}}function Nn(e){let t=In(e.filter(Pn)),n=t.nodes;if(n.length===0)return null;let r=Vn(n),i=n.filter(e=>j(e)&&!Zn(e)),a=Wn(i),o=Gn(i,a);if(!a&&!o&&r.length===0)return null;let s=Qn(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 Pn(e){return!te(e)}function Fn(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 In(e){let t=e.filter(e=>Yn(e));if(t.length)return{nodes:t,source:`permission`};let n=Bn(e);return n.length?{nodes:n,source:`system-dialog`}:{nodes:Ln(e),source:`native-dialog`}}function Ln(e){let t=e.filter(e=>Rn(e.type??``)),n=e.filter(e=>En.test(e.identifier??``)),r=t.length?[...t,...n]:zn(n);if(r.length===0)return[];let i=Kn(e,r);return i===void 0?r:Jn(e,i)}function Rn(e){let t=Math.max(e.lastIndexOf(`.`),e.lastIndexOf(`$`));return e.slice(t+1).toLowerCase().endsWith(`dialog`)}function zn(e){let t=e.some(e=>Dn.test(e.identifier??``)),n=e.some(e=>!Dn.test(e.identifier??``));return t&&n?e:[]}function Bn(e){let t=e.filter(e=>Xn(e));if(t.length===0)return[];let n=Kn(e,t);return n===void 0?t:Jn(e,n).filter(e=>e.bundleId&&Tn.has(e.bundleId))}function Vn(e){let t=new Set,n=[];for(let r of e){let e=j(r);if(!e||!r.rect||!Zn(r))continue;let i=e.trim().toLowerCase();if(!i||t.has(i))continue;t.add(i);let a=o(r.rect);n.push({label:e,x:a.x,y:a.y,role:Hn(r,e)})}return n}function Hn(e,t){return Un(e.identifier??``)||(An.test(t.trim())?`accept`:jn.test(t.trim())?`dismiss`:`neutral`)}function Un(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 Wn(e){return j(e.find(e=>/(?:^|:)id\/(?:alertTitle|permission_message)$/i.test(e.identifier??``)))||j(e[0])}function Gn(e,t){let n=e.map(e=>j(e)).filter(e=>e&&e!==t);return n.length?[...new Set(n)].join(`
3
- `):void 0}function Kn(e,t){let n=t[0];if(!n)return;let r=qn(e,n.index);for(let n of t.slice(1)){let t=new Set(qn(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 qn(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 Jn(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 Yn(e){let t=e.bundleId??``;return Cn.has(t)||On.test(e.identifier??``)}function Xn(e){let t=e.bundleId??``;return Tn.has(t)&&kn.test(j(e))}function Zn(e){let t=e.type??``,n=e.identifier??``;return!!(e.hittable||/\bbutton\b/i.test(t)||Dn.test(n)||/(?:^|:)id\/permission_(?:allow|deny)/i.test(n))}function j(e){return e?[e.label,e.value].filter(e=>typeof e==`string`&&e.trim().length>0)[0]?.trim()??``:``}function Qn(e){return e.find(e=>e.bundleId)?.bundleId}function $n(e){let t={status:[],results:[],currentStatus:null,currentResult:null};for(let n of e.split(/\r?\n/))er(n,t);return tr(t),{status:t.status,results:t.results}}function er(e,t){if(e.startsWith(`INSTRUMENTATION_STATUS: `)){t.currentStatus??={},ir(e.slice(24),t.currentStatus);return}if(e.startsWith(`INSTRUMENTATION_STATUS_CODE: `)){nr(t);return}if(e.startsWith(`INSTRUMENTATION_RESULT: `)){t.currentResult??={},ir(e.slice(24),t.currentResult);return}e.startsWith(`INSTRUMENTATION_CODE: `)&&rr(t)}function tr(e){nr(e),rr(e)}function nr(e){e.currentStatus&&=(e.status.push(e.currentStatus),null)}function rr(e){e.currentResult&&=(e.results.push(e.currentResult),null)}function ir(e,t){let n=e.indexOf(`=`);n<0||(t[e.slice(0,n)]=e.slice(n+1))}function M(e){if(e===void 0)return;let t=Number(e);return Number.isFinite(t)?t:void 0}function ar(e){if(e===void 0)return;if(e===``)return[];let t=e.split(`,`);return t.every(e=>/^\d+$/.test(e))?t.map(Number):void 0}function or(e){if(e===`true`)return!0;if(e===`false`)return!1}function sr(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 a(`COMMAND_FAILED`,`Android helper returned an invalid gesture viewport`);return e}const cr=1e4;async function lr(e,t){try{return await Ye(e,t)}catch(e){throw ct(e)}}async function ur(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 _r(a,o,u);let f=await dr({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 lr(a,{provider:n,replace:!0,allowFailure:!0,timeoutMs:l});if(p.exitCode!==0)throw T(`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 dr(e){let{adb:t,adbProvider:n,packageName:r,versionCode:i,sha256:a,signal:o}=e,s=await mr(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 hr(t,n,r,o);return{installedVersionCode:s,installedSha256:e,reason:e===a?`current`:`mismatched`}}catch{return o?.throwIfAborted(),{installedVersionCode:s,reason:`unverifiable`}}}async function fr(e){let t=b().files,n=Le(),r=A.join(Re(),`android`,e.helperDirName,`dist`),o=A.join(r,e.manifestFileName(n));try{let n=e.parseManifest(JSON.parse(await t.readText(o))),i=A.join(r,n.assetName);return await t.access(i),{apkPath:i,manifest:n}}catch(t){throw new a(`UNSUPPORTED_OPERATION`,e.unavailableMessage,{manifestPath:o,error:i(t).message},t)}}function pr(e){return async t=>await ur({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 mr(e,t,n){let r=await y(e,[`cmd`,`package`,`list`,`packages`,`--show-versioncode`,t],{allowFailure:!0,timeoutMs:5e3,signal:n});if(r.exitCode!==0)return;let i=RegExp(`package:${yr(t)}(?:\\s|$).*versionCode:(\\d+)`).exec(`${r.stdout}\n${r.stderr}`);return i?Number(i[1]):void 0}async function hr(e,t,n,r){let i=await y(e,[`pm`,`path`,n],{allowFailure:!0,timeoutMs:cr,signal:r}),o=gr(`${i.stdout}\n${i.stderr}`);if(i.exitCode!==0||!o)throw new a(`COMMAND_FAILED`,`Could not resolve installed Android helper APK`);let s=b().files,c=await s.makeTempDirectory(`agent-device-helper-`),l=A.join(c,`base.apk`);try{let e=await Ge(o,l,{provider:t,allowFailure:!0,timeoutMs:cr,signal:r});if(e.exitCode!==0)throw T(`Could not read installed Android helper APK`,e,{packageName:n,remotePath:o});return await vr(l)}finally{await s.remove(c,{recursive:!0,force:!0})}}function gr(e){return e.split(/\r?\n/).map(e=>e.startsWith(`package:`)?e.slice(8).trim():``).find(e=>e.endsWith(`/base.apk`))}async function _r(e,t,n){let r=await vr(e);if(r!==t)throw new a(`COMMAND_FAILED`,`${n} APK checksum mismatch`,{apkPath:e,expectedSha256:t,actualSha256:r})}async function vr(e){let t=b().files;return t.sha256(await t.readBytes(e))}function yr(e){return e.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`)}const br=`android-snapshot-helper-v1`,xr=`uiautomator-xml`,Sr=5e3,Cr=3e4;function wr(e){if(!e||typeof e!=`object`||Array.isArray(e))throw new a(`INVALID_ARGS`,`Android snapshot helper manifest must be an object.`);let t=e;return{name:Er(t.name,`name`,`android-snapshot-helper`),version:N(t.version,`version`),releaseTag:Or(t.releaseTag),assetName:Or(t.assetName),apkUrl:kr(t.apkUrl,`apkUrl`),sha256:Dr(t.sha256),checksumName:Or(t.checksumName),packageName:N(t.packageName,`packageName`),versionCode:Tr(t.versionCode,`versionCode`),instrumentationRunner:N(t.instrumentationRunner,`instrumentationRunner`),minSdk:Tr(t.minSdk,`minSdk`),targetSdk:t.targetSdk===void 0?void 0:Tr(t.targetSdk,`targetSdk`),outputFormat:Er(t.outputFormat,`outputFormat`,xr),statusProtocol:Er(t.statusProtocol,`statusProtocol`,br)}}function Tr(e,t){return Pt(e,t,`snapshot helper`)}function Er(e,t,n){return vt(e,t,n,`snapshot helper`)}function Dr(e){let t=N(e,`sha256`).trim().toLowerCase();if(t.length!==64||!Ar(t))throw new a(`INVALID_ARGS`,`Android snapshot helper manifest sha256 must be a 64-character hex string.`);return t}function N(e,t){if(typeof e!=`string`||e.trim().length===0)throw new a(`INVALID_ARGS`,`Android snapshot helper manifest ${t} is required.`);return e}function Or(e){return typeof e==`string`&&e.trim().length>0?e:void 0}function kr(e,t){return e===null?null:N(e,t)}function Ar(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 P=new Map;function jr(e){let t=`${e.deviceKey}\0${e.packageName}\0${e.versionCode}\0`;for(let e of P.keys())e.startsWith(t)&&Lr(e)}const Mr=`android-snapshot-helper-not-current`;function Nr(e){return r(e).details?.reason===Mr}function Pr(){P.clear()}function Fr(e,t,n,r){return e?`${e}\0${t}\0${n}\0${r}`:void 0}function Ir(e,t){if(!e)return;let[n,r]=e.split(`\0`),i=`${n}\0${r}\0`;for(let t of P.keys())t!==e&&t.startsWith(i)&&P.delete(t);P.set(e,t)}function Lr(e){e&&P.delete(e)}async function Rr(e){let{adb:t,artifact:n}=e,r=e.installPolicy??`missing-or-outdated`,i=n.manifest.packageName,o=n.manifest.versionCode,s=n.manifest.sha256;if(r===`never`)return{packageName:i,versionCode:o,installed:!1,reason:`skipped`};let c=Fr(e.deviceKey,i,o,s),l=c?P.get(c):void 0;if(c&&r!==`always`&&l!==void 0)return{packageName:i,versionCode:o,installedVersionCode:l,installedSha256:s,installed:!1,reason:`current`};await _r(n.apkPath,s,`Android snapshot helper`);let u=r===`always`?{installedVersionCode:await Vr(t,i,e.timeoutMs,e.signal),reason:`forced`}:await dr({adb:t,adbProvider:Br(e.adbProvider,t),packageName:i,versionCode:o,sha256:s,signal:e.signal}),{installedVersionCode:d}=u,f=`installedSha256`in u?u.installedSha256:void 0,p=u.reason;if(p===`current`){if(d===void 0)throw Error(`Expected installed versionCode for current Android snapshot helper`);return Ir(c,d),{packageName:i,versionCode:o,installedVersionCode:d,installedSha256:f,installed:!1,reason:p}}if(r===`current-only`)throw new a(`COMMAND_FAILED`,`Android snapshot helper is not installed at the current version`,{reason:Mr,packageName:i,versionCode:o,installedVersionCode:d});let m;try{m=await Hr(t,e.adbProvider??t,n.apkPath,{packageName:i,timeoutMs:e.timeoutMs,signal:e.signal})}catch(e){throw Lr(c),zr(e,{packageName:i,versionCode:o})}if(m.exitCode!==0)throw Lr(c),zr(T(`Failed to install Android snapshot helper`,m,{packageName:i,versionCode:o}));return Ir(c,o),{packageName:i,versionCode:o,installedVersionCode:d,installedSha256:f,installed:!0,reason:p}}function zr(e,t){let n=r(e,`COMMAND_FAILED`);return n.details={...t,...n.details,androidSnapshotHelperInstallFailure:!0},n}function Br(e,t){return e?typeof e==`function`?{exec:e}:e:{exec:t}}async function Vr(e,t,n,r){let i=await y(e,[`cmd`,`package`,`list`,`packages`,`--show-versioncode`,t],{allowFailure:!0,timeoutMs:n,signal:r});if(i.exitCode===0)return Ur(`${i.stdout}\n${i.stderr}`,t)}async function Hr(e,t,n,r){let i=async()=>await lr(n,{allowFailure:!0,provider:t,replace:!0,timeoutMs:r.timeoutMs,signal:r.signal}),a=await i();if(a.exitCode===0||!Wr(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 Ur(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 Wr(e){return`${e.stdout}\n${e.stderr}`.includes(`INSTALL_FAILED_UPDATE_INCOMPATIBLE`)}function Gr(e){return e.errorType===`java.util.concurrent.TimeoutException`?`accessibility-timeout`:void 0}function Kr(e){return e===137?`accessibility-timeout`:void 0}function qr(e){return e?{androidCaptureFailureReason:e}:{}}function F(e,t,n,r){if(r instanceof a){let i=r.details??{};return new a(r.code,r.message,{...i,action:e,package:n,tool:t,hint:typeof i.hint==`string`?i.hint:Xr(t,i)},r)}return new a(`COMMAND_FAILED`,`Failed to ${e} Android ${t} for ${n}`,{action:e,package:n,tool:t,hint:Jr(t)},r)}function Jr(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 Yr(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 Xr(e,t){let n=(typeof t.stderr==`string`?t.stderr:``).toLowerCase();return e===`simpleperf`?Zr(n):$r(n)?`Use a device image that permits perfetto trace capture for shell, keep the app running, then retry perf trace start.`:Jr(e)}function Zr(e){return Qr(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.`:Jr(`simpleperf`)}function Qr(e){return e.includes(`permission denied`)||e.includes(`not profileable`)||e.includes(`profileable`)}function $r(e){return e.includes(`permission denied`)||e.includes(`not allowed`)}const ei=`adb-shell-simpleperf`,ti=`adb-shell-perfetto`,I=15e3,L=3e4,ni=`/data/local/tmp`;async function ri(e,t){try{let n=await y(e,[`pidof`,t],{allowFailure:!0,timeoutMs:I}),r=ai(n.stdout);if(n.exitCode===0&&r)return r}catch{}throw new a(`COMMAND_FAILED`,`No active Android app process found for ${t}`,{package:t,hint:`Run open <app> for this session again, wait for the app UI to appear, then retry perf.`})}async function ii(e,t,n){let r=await y(e,[C(`command -v ${w(t)} || which ${w(t)}`)],{allowFailure:!0,timeoutMs:I});if(!(r.exitCode===0&&r.stdout.trim()))throw new a(`UNSUPPORTED_OPERATION`,`Android device does not expose ${t}`,{package:n,tool:t,hint:Yr(t)})}function ai(e){return e.trim().split(/\s+/).find(e=>/^\d+$/.test(e))}const oi=2e3,si=`android_snapshot_helper_runtime_occupied`,R=new Map;function ci(e){return`${e.platform}:${e.id}`}async function li(e){await Si({adb:e.adb,packageName:e.packageName}),await di({deviceKey:e.deviceKey,packageName:e.packageName,adb:e.adb,cause:e.cause})}async function ui(e){let t=R.get(e.deviceKey);if(!t)return;await Si({adb:e.adb,packageName:t.packageName,timeoutMs:5e3,...e.signal?{signal:e.signal}:{}}),e.signal?.throwIfAborted();let n=await mi({adb:e.adb,packageName:t.packageName});if(n===`occupied`&&(await _(250),n=await mi({adb:e.adb,packageName:t.packageName})),n===`occupied`)throw pi({deviceKey:e.deviceKey,packageName:t.packageName,cause:t.cause});n!==`unknown`&&R.delete(e.deviceKey)}async function di(e){let t=e.release??await mi({adb:e.adb,packageName:e.packageName});if(t===`released`)return R.delete(e.deviceKey),t;let n=e.cause instanceof Error?e.cause.message:String(e.cause);return R.set(e.deviceKey,{packageName:e.packageName,cause:n}),g({level:`warn`,phase:`android_snapshot_helper_retirement_pending`,data:{deviceKey:e.deviceKey,packageName:e.packageName,release:t}}),t}function fi(e){return e instanceof a&&e.details?.reason===si}function pi(e){let t=e.cause instanceof Error?e.cause.message:String(e.cause);return new a(`COMMAND_FAILED`,`Android automation helper is still holding device automation ownership`,{reason:si,deviceKey:e.deviceKey,packageName:e.packageName,cause:t,hint:`Retry after the helper process exits, or restart the device if Android keeps reporting the helper as running.`})}async function mi(e){try{let t=await y(e.adb,[`pidof`,e.packageName,C(`|| echo AGENT_DEVICE_NO_HELPER`)],{allowFailure:!0,timeoutMs:oi}),n=t.stdout.trim();return ai(n)?`occupied`:n===`AGENT_DEVICE_NO_HELPER`&&t.stderr.trim().length===0?`released`:`unknown`}catch{return`unknown`}}async function hi(e){let t=AbortSignal.timeout(e.timeoutMs);return await Promise.all([...e.forceStopRuntime?[Si({adb:e.adb,packageName:e.packageName,timeoutMs:e.timeoutMs,signal:t})]:[],Ci({...e,signal:t})]),{timedOut:t.aborted}}function gi(e){let t=_i(e);return{ended:t?Promise.resolve():new Promise(t=>{e.once(`close`,()=>t()),e.once(`exit`,()=>t())}),hasEnded:()=>_i(e),completedCleanly:()=>!t&&e.exitCode===0&&e.signalCode==null}}function _i(e){return e.exitCode!=null||e.signalCode!=null}async function vi(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 yi(e){if(e.processExit.hasEnded())return!0;try{e.process.kill(`SIGTERM`)}catch{}return await vi(e.processExit.ended,e.timeoutMs)}function bi(e){R.delete(e)}function xi(){R.clear()}async function Si(e){await y(e.adb,[`am`,`force-stop`,e.packageName],{allowFailure:!0,timeoutMs:e.timeoutMs??2e3,...e.signal?{signal:e.signal}:{}}).catch(()=>{})}async function Ci(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 wi(e){let t=Ei(e),n=e.deviceKey??`android:default`;await ui({deviceKey:n,adb:e.adb,signal:e.signal});let r;try{r=await e.adb(Di(t),{allowFailure:!0,timeoutMs:t.commandTimeoutMs,signal:e.signal})}catch(r){throw e.signal?.aborted?(await li({deviceKey:n,packageName:t.packageName,adb:e.adb,cause:r}),e.signal.throwIfAborted(),r):r}e.signal?.aborted&&(await li({deviceKey:n,packageName:t.packageName,adb:e.adb,cause:e.signal.reason}),e.signal.throwIfAborted());let{output:i,cleanupDone:o}=await Oi(e,t,r);if(t.outputPath&&!o&&await Fi(e.adb,t.outputPath),r.exitCode!==0)throw new a(`COMMAND_FAILED`,`Android snapshot helper failed`,Fe(r,{helper:i.metadata}));return i}function Ti(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:Sr,commandTimeoutMs:Cr,...e.signal?{signal:e.signal}:{}}}function Ei(e){let t=z(e.timeoutMs,8e3),n=z(e.packageName,`com.callstack.agentdevice.snapshothelper`);return{waitForIdleTimeoutMs:z(e.waitForIdleTimeoutMs,500),waitForIdleQuietMs:z(e.waitForIdleQuietMs,100),timeoutMs:t,commandTimeoutMs:z(e.commandTimeoutMs,t+5e3),maxDepth:z(e.maxDepth,128),maxNodes:z(e.maxNodes,5e3),packageName:n,runner:z(e.instrumentationRunner,`${n}/.SnapshotInstrumentation`),...e.outputPath?{outputPath:e.outputPath}:{},...e.emitChunks===void 0?{}:{emitChunks:e.emitChunks}}}function z(e,t){return e===void 0?t:e}function Di(e,t={}){return Qe(`adb`,`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)],...t.sessionPort===void 0?[]:[`-e`,`sessionPort`,t.sessionPort],e.runner])}async function Oi(e,t,n){try{return{output:Ii(`${n.stdout}\n${n.stderr}`),cleanupDone:!1}}catch(r){return await ki(e,t,n,r)}}async function ki(e,t,n,r){let i=r instanceof a&&r.details?.helper?r:void 0;if(i&&n.exitCode!==0)throw i;let o=await Ai(e,t,n);if(o)return{output:o,cleanupDone:!0};throw i||new a(`COMMAND_FAILED`,n.exitCode===0?`Android snapshot helper output could not be parsed`:`Android snapshot helper failed before returning parseable output`,{stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode,...qr(Kr(n.exitCode))},r)}async function Ai(e,t,n){if(!(n.exitCode!==0||!t.outputPath))return await Mi(e.adb,t.outputPath,Pi(`${n.stdout}\n${n.stderr}`)??ji(t))}function ji(e){return{outputFormat:xr,waitForIdleTimeoutMs:e.waitForIdleTimeoutMs,waitForIdleQuietMs:e.waitForIdleQuietMs,timeoutMs:e.timeoutMs,maxDepth:e.maxDepth,maxNodes:e.maxNodes,transport:`instrumentation`}}async function Mi(e,t,n){let r;try{r=await y(e,Ni(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 Ni(e){return[`sh`,`-c`,`cat "$1"; status=$?; rm -f "$1"; exit "$status"`,`agent-device-snapshot-helper-output`,e]}function Pi(e){try{return Wi(Ri($n(e).results))}catch{return null}}async function Fi(e,t){try{await y(e,[`rm`,`-f`,t],{allowFailure:!0,timeoutMs:5e3})}catch{}}function Ii(e){let t=$n(e),n=Ri(t.results);return{xml:Bi(Li(t.status),n),metadata:{...Wi(n),transport:`instrumentation`}}}function Li(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:B(n.chunkIndex),count:B(n.chunkCount),payloadBase64:e})}return t}function Ri(e){let t=e.find(e=>e.agentDeviceProtocol===br);if(!t)throw new a(`COMMAND_FAILED`,`Android snapshot helper did not return a final result`);if(t.ok!==`true`)throw new a(`COMMAND_FAILED`,zi(t),{errorType:t.errorType,helper:t,...qr(Gr(t))});return t}function zi(e){return e.message&&e.message!==`null`?e.message:e.errorType||`Android snapshot helper returned an error`}function Bi(e,t){if(e.length===0)throw new a(`COMMAND_FAILED`,`Android snapshot helper did not return XML chunks`,{helper:t});let n=Vi(e),r=Buffer.concat(Ui(Hi(e,n),n)).toString(`utf8`);if(!r.includes(`<hierarchy`)||!r.includes(`</hierarchy>`))throw new a(`COMMAND_FAILED`,`Android snapshot helper output did not contain XML`,{xml:r});return r}function Vi(e){let t=e[0]?.count??e.length;if(t<1||e.length!==t||e.some(e=>e.count!==t))throw new a(`COMMAND_FAILED`,`Android snapshot helper returned incomplete XML chunks`,{expectedChunks:t,actualChunks:e.length});return t}function Hi(e,t){let n=new Map;for(let r of e){if(r.index===void 0||r.index<0||r.index>=t)throw new a(`COMMAND_FAILED`,`Android snapshot helper returned invalid chunk index`,{chunkIndex:r.index,expectedChunks:t});if(n.has(r.index))throw new a(`COMMAND_FAILED`,`Android snapshot helper returned duplicate XML chunks`,{chunkIndex:r.index});n.set(r.index,r.payloadBase64)}return n}function Ui(e,t){let n=[];for(let r=0;r<t;r+=1){let i=e.get(r);if(i===void 0)throw new a(`COMMAND_FAILED`,`Android snapshot helper returned incomplete XML chunks`,{missingChunkIndex:r,expectedChunks:t});n.push(Buffer.from(i,`base64`))}return n}function Wi(e){return{helperApiVersion:e.helperApiVersion,outputFormat:xr,waitForIdleTimeoutMs:B(e.waitForIdleTimeoutMs),waitForIdleQuietMs:B(e.waitForIdleQuietMs),timeoutMs:B(e.timeoutMs),maxDepth:B(e.maxDepth),maxNodes:B(e.maxNodes),rootPresent:Ki(e.rootPresent),captureMode:Gi(e.captureMode),windowCount:B(e.windowCount),missingRootWindowTypes:ar(e.missingRootWindowTypes),nodeCount:B(e.nodeCount),truncated:Ki(e.truncated),elapsedMs:B(e.elapsedMs),pixelDensity:B(e.pixelDensity),displayWidth:B(e.displayWidth),displayHeight:B(e.displayHeight)}}function Gi(e){return e===`interactive-windows`||e===`active-window`?e:void 0}const B=M,Ki=or;function qi(){return new Promise((e,t)=>{let n=_n.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 Ji(e,t,n,r){return new Promise((i,o)=>{let s=_n.connect({host:`127.0.0.1`,port:e}),c=[],l=setTimeout(()=>{u(),s.destroy(),o(new a(`COMMAND_FAILED`,`Android snapshot helper session request timed out`,{command:t,timeoutMs:n,port:e}))},n),u=()=>{clearTimeout(l),r?.removeEventListener(`abort`,d)},d=()=>{u(),s.destroy(),o(r?.reason??new DOMException(`The operation was aborted`,`AbortError`))};if(r?.addEventListener(`abort`,d,{once:!0}),r?.aborted){d();return}s.on(`connect`,()=>s.write(`${t}\n`)),s.on(`data`,e=>c.push(Buffer.from(e))),s.on(`error`,e=>{u(),o(e)}),s.on(`close`,()=>{u(),i(Buffer.concat(c).toString(`utf8`))})})}async function Yi(e){let t=`snapshot-${Date.now()}-${Math.random().toString(16).slice(2)}`;return ta(await Ji(e.port,`snapshot ${t}`,Xi(e),e.signal),t)}function Xi(e){return Math.min(e.commandTimeoutMs,Math.max(e.timeoutMs+3e3,3e3))}function Zi(e,t,n){return new Promise((r,i)=>{let o=``,s=setTimeout(()=>{n?.removeEventListener(`abort`,l),i(new a(`COMMAND_FAILED`,`Android snapshot helper session did not become ready`,{output:o,timeoutMs:t,reason:`android_snapshot_helper_session_ready_timeout`}))},t),c=e=>{o+=e.toString(),o.includes(`agentDeviceProtocol=android-snapshot-helper-v1`)&&o.includes(`sessionReady=true`)&&(clearTimeout(s),n?.removeEventListener(`abort`,l),r())},l=()=>{clearTimeout(s),i(n?.reason??new DOMException(`The operation was aborted`,`AbortError`))};if(n?.addEventListener(`abort`,l,{once:!0}),n?.aborted){l();return}e.stdout?.on(`data`,c),e.stderr?.on(`data`,c),e.once(`exit`,(e,t)=>{clearTimeout(s),n?.removeEventListener(`abort`,l),i(new a(`COMMAND_FAILED`,`Android snapshot helper session exited before ready`,{output:o,exitCode:e,signal:t,reason:`android_snapshot_helper_session_exited_before_ready`}))}),e.on(`error`,e=>{clearTimeout(s),n?.removeEventListener(`abort`,l),i(e)})})}function Qi(e){let t=e.indexOf(`
1
+ import{r as e}from"./rolldown-runtime.js";import{B as t,I as n,P as r,V as i,Y as a,b as o,et as s,it as c,nt as l,v as u}from"./sdk-contracts.js";import{H as d,i as f,l as p,m,rt as ee,st as te,tt as ne}from"./tv-remote.js";import{k as re,p as ie}from"./sdk-batch-runner.js";import{a as ae,c as oe,i as se,o as ce,r as le,s as ue,t as de}from"./android-input-ownership.js";import{c as h,r as g}from"./diagnostics.js";import"./diagnostics2.js";import{Gr as fe,Hr as pe,Jr as me,Kr as he,Ur as ge,Vr as _e,Xr as ve,ei as ye,ti as be}from"./sdk-batch.js";import{n as xe}from"./alert-contract.js";import{D as Se,S as Ce,b as we,c as Te,f as Ee,v as De,w as Oe,x as ke,y as Ae}from"./settings.js";import{n as je}from"./location-coordinates.js";import{r as Me}from"./mobile-snapshot-semantics.js";import{c as Ne,g as Pe,l as Fe,o as Ie,r as Le}from"./exec.js";import{i as _}from"./retry.js";import"./command.js";import{a as Re,r as ze}from"./version.js";import"./retry2.js";import{r as Be}from"./install-source2.js";import{C as Ve,S as v,_ as He,a as y,c as Ue,d as b,f as We,g as Ge,h as Ke,i as qe,l as Je,m as Ye,n as Xe,o as x,p as Ze,r as Qe,s as $e,t as et,u as tt,v as nt,w as rt,x as S,y as it}from"./adb-executor.js";import{n as at,o as C,s as w}from"./device-shell.js";import{c as ot,i as st,l as ct,n as T,o as lt,s as ut}from"./adb-failure.js";import{a as dt,i as ft,n as pt,o as E}from"./adb.js";import{r as mt}from"./snapshot-occlusion.js";import{i as ht,n as gt,r as _t}from"./gesture-plan.js";import{_ as vt,a as yt,b as bt,c as xt,d as St,f as Ct,g as wt,h as Tt,i as Et,l as Dt,m as Ot,n as kt,o as At,p as D,r as jt,s as Mt,t as O,u as Nt,v as Pt,y as Ft}from"./ime-state.js";import{n as It}from"./android-snapshot-quality.js";import{_ as Lt,a as Rt,b as zt,c as Bt,d as Vt,f as Ht,g as Ut,h as Wt,i as Gt,l as Kt,m as qt,o as Jt,p as Yt,r as Xt,s as Zt,t as Qt,u as $t,v as en,x as tn,y as nn}from"./app-lifecycle.js";import{a as rn,i as an,n as on,o as sn,t as cn}from"./app-parsers.js";import{i as ln,r as un}from"./toolchain-probe.js";import{n as dn,r as fn}from"./android-system-chrome.js";import{t as pn}from"./bounds.js";import{t as mn}from"./entities.js";import{n as hn}from"./startup-recovery-fence.js";import{n as gn}from"./numeric.js";import k from"node:path";import _n from"node:net";import{TextDecoder as vn}from"node:util";const yn=new Map;async function bn(e){let t=yn.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=Sn(n).includes(`shell_v2`);return yn.set(e.deviceKey,r),r}function xn(){yn.clear()}function Sn(e){return e.split(`
2
+ `).map(e=>e.trim()).filter(Boolean)}const Cn=new Set([`com.android.permissioncontroller`,`com.google.android.permissioncontroller`,`com.google.android.packageinstaller`,`com.android.packageinstaller`]);function wn(e){return Cn.has(e)}const Tn=new Set([`android`,`com.android.systemui`]),En=/^android:id\/(?:alertTitle|message|button[123]|parentPanel|buttonPanel|contentPanel)$/i,Dn=/^android:id\/button[123]$/i,On=/(?:^|:)id\/permission_/i,kn=/\b(?:is(?:n't| not) responding|keeps stopping|has stopped|close app|app info)\b/i,An=/^(?:ok|allow|allow all|while using the app|only this time|yes|continue|save|confirm|turn on|open settings)$/i,jn=/^(?:cancel|deny|don.t allow|don’t allow|not now|no|dismiss|close|close app|later|skip)$/i;function Mn(e){if(e!==null){if(Dn.test(e))return`button`;if(En.test(e))return`content`}}function Nn(e){let t=In(e.filter(Pn)),n=t.nodes;if(n.length===0)return null;let r=Vn(n),i=n.filter(e=>A(e)&&!Zn(e)),a=Wn(i),o=Gn(i,a);if(!a&&!o&&r.length===0)return null;let s=Qn(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 Pn(e){return!mt(e)}function Fn(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 In(e){let t=e.filter(e=>Yn(e));if(t.length)return{nodes:t,source:`permission`};let n=Bn(e);return n.length?{nodes:n,source:`system-dialog`}:{nodes:Ln(e),source:`native-dialog`}}function Ln(e){let t=e.filter(e=>Rn(e.type??``)),n=e.filter(e=>En.test(e.identifier??``)),r=t.length?[...t,...n]:zn(n);if(r.length===0)return[];let i=Kn(e,r);return i===void 0?r:Jn(e,i)}function Rn(e){let t=Math.max(e.lastIndexOf(`.`),e.lastIndexOf(`$`));return e.slice(t+1).toLowerCase().endsWith(`dialog`)}function zn(e){let t=e.some(e=>Dn.test(e.identifier??``)),n=e.some(e=>!Dn.test(e.identifier??``));return t&&n?e:[]}function Bn(e){let t=e.filter(e=>Xn(e));if(t.length===0)return[];let n=Kn(e,t);return n===void 0?t:Jn(e,n).filter(e=>e.bundleId&&Tn.has(e.bundleId))}function Vn(e){let t=new Set,n=[];for(let r of e){let e=A(r);if(!e||!r.rect||!Zn(r))continue;let i=e.trim().toLowerCase();if(!i||t.has(i))continue;t.add(i);let a=o(r.rect);n.push({label:e,x:a.x,y:a.y,role:Hn(r,e)})}return n}function Hn(e,t){return Un(e.identifier??``)||(An.test(t.trim())?`accept`:jn.test(t.trim())?`dismiss`:`neutral`)}function Un(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 Wn(e){return A(e.find(e=>/(?:^|:)id\/(?:alertTitle|permission_message)$/i.test(e.identifier??``)))||A(e[0])}function Gn(e,t){let n=e.map(e=>A(e)).filter(e=>e&&e!==t);return n.length?[...new Set(n)].join(`
3
+ `):void 0}function Kn(e,t){let n=t[0];if(!n)return;let r=qn(e,n.index);for(let n of t.slice(1)){let t=new Set(qn(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 qn(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 Jn(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 Yn(e){let t=e.bundleId??``;return Cn.has(t)||On.test(e.identifier??``)}function Xn(e){let t=e.bundleId??``;return Tn.has(t)&&kn.test(A(e))}function Zn(e){let t=e.type??``,n=e.identifier??``;return!!(e.hittable||/\bbutton\b/i.test(t)||Dn.test(n)||/(?:^|:)id\/permission_(?:allow|deny)/i.test(n))}function A(e){return e?[e.label,e.value].filter(e=>typeof e==`string`&&e.trim().length>0)[0]?.trim()??``:``}function Qn(e){return e.find(e=>e.bundleId)?.bundleId}function $n(e){let t={status:[],results:[],currentStatus:null,currentResult:null};for(let n of e.split(/\r?\n/))er(n,t);return tr(t),{status:t.status,results:t.results}}function er(e,t){if(e.startsWith(`INSTRUMENTATION_STATUS: `)){t.currentStatus??={},ir(e.slice(24),t.currentStatus);return}if(e.startsWith(`INSTRUMENTATION_STATUS_CODE: `)){nr(t);return}if(e.startsWith(`INSTRUMENTATION_RESULT: `)){t.currentResult??={},ir(e.slice(24),t.currentResult);return}e.startsWith(`INSTRUMENTATION_CODE: `)&&rr(t)}function tr(e){nr(e),rr(e)}function nr(e){e.currentStatus&&=(e.status.push(e.currentStatus),null)}function rr(e){e.currentResult&&=(e.results.push(e.currentResult),null)}function ir(e,t){let n=e.indexOf(`=`);n<0||(t[e.slice(0,n)]=e.slice(n+1))}function j(e){if(e===void 0)return;let t=Number(e);return Number.isFinite(t)?t:void 0}function ar(e){if(e===void 0)return;if(e===``)return[];let t=e.split(`,`);return t.every(e=>/^\d+$/.test(e))?t.map(Number):void 0}function or(e){if(e===`true`)return!0;if(e===`false`)return!1}function sr(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 r(`COMMAND_FAILED`,`Android helper returned an invalid gesture viewport`);return e}const cr=1e4;async function lr(e,t){try{return await et(e,t)}catch(e){throw lt(e)}}async function ur(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 _r(a,o,u);let f=await dr({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 lr(a,{provider:n,replace:!0,allowFailure:!0,timeoutMs:l});if(p.exitCode!==0)throw T(`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 dr(e){let{adb:t,adbProvider:n,packageName:r,versionCode:i,sha256:a,signal:o}=e,s=await mr(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 hr(t,n,r,o);return{installedVersionCode:s,installedSha256:e,reason:e===a?`current`:`mismatched`}}catch{return o?.throwIfAborted(),{installedVersionCode:s,reason:`unverifiable`}}}async function fr(e){let t=v().files,n=Re(),i=k.join(ze(),`android`,e.helperDirName,`dist`),o=k.join(i,e.manifestFileName(n));try{let n=e.parseManifest(JSON.parse(await t.readText(o))),r=k.join(i,n.assetName);return await t.access(r),{apkPath:r,manifest:n}}catch(t){throw new r(`UNSUPPORTED_OPERATION`,e.unavailableMessage,{manifestPath:o,error:a(t).message},t)}}function pr(e){return async t=>await ur({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 mr(e,t,n){let r=await b(e,[`cmd`,`package`,`list`,`packages`,`--show-versioncode`,t],{allowFailure:!0,timeoutMs:5e3,signal:n});if(r.exitCode!==0)return;let i=RegExp(`package:${yr(t)}(?:\\s|$).*versionCode:(\\d+)`).exec(`${r.stdout}\n${r.stderr}`);return i?Number(i[1]):void 0}async function hr(e,t,n,i){let a=await b(e,[`pm`,`path`,n],{allowFailure:!0,timeoutMs:cr,signal:i}),o=gr(`${a.stdout}\n${a.stderr}`);if(a.exitCode!==0||!o)throw new r(`COMMAND_FAILED`,`Could not resolve installed Android helper APK`);let s=v().files,c=await s.makeTempDirectory(`agent-device-helper-`),l=k.join(c,`base.apk`);try{let e=await Xe(o,l,{provider:t,allowFailure:!0,timeoutMs:cr,signal:i});if(e.exitCode!==0)throw T(`Could not read installed Android helper APK`,e,{packageName:n,remotePath:o});return await vr(l)}finally{await s.remove(c,{recursive:!0,force:!0})}}function gr(e){return e.split(/\r?\n/).map(e=>e.startsWith(`package:`)?e.slice(8).trim():``).find(e=>e.endsWith(`/base.apk`))}async function _r(e,t,n){let i=await vr(e);if(i!==t)throw new r(`COMMAND_FAILED`,`${n} APK checksum mismatch`,{apkPath:e,expectedSha256:t,actualSha256:i})}async function vr(e){let t=v().files;return t.sha256(await t.readBytes(e))}function yr(e){return e.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`)}const br=`android-snapshot-helper-v1`,xr=`uiautomator-xml`,Sr=5e3,Cr=3e4;function wr(e){if(!e||typeof e!=`object`||Array.isArray(e))throw new r(`INVALID_ARGS`,`Android snapshot helper manifest must be an object.`);let t=e;return{name:Er(t.name,`name`,`android-snapshot-helper`),version:M(t.version,`version`),releaseTag:Or(t.releaseTag),assetName:Or(t.assetName),apkUrl:kr(t.apkUrl,`apkUrl`),sha256:Dr(t.sha256),checksumName:Or(t.checksumName),packageName:M(t.packageName,`packageName`),versionCode:Tr(t.versionCode,`versionCode`),instrumentationRunner:M(t.instrumentationRunner,`instrumentationRunner`),minSdk:Tr(t.minSdk,`minSdk`),targetSdk:t.targetSdk===void 0?void 0:Tr(t.targetSdk,`targetSdk`),outputFormat:Er(t.outputFormat,`outputFormat`,xr),statusProtocol:Er(t.statusProtocol,`statusProtocol`,br)}}function Tr(e,t){return Ft(e,t,`snapshot helper`)}function Er(e,t,n){return bt(e,t,n,`snapshot helper`)}function Dr(e){let t=M(e,`sha256`).trim().toLowerCase();if(t.length!==64||!Ar(t))throw new r(`INVALID_ARGS`,`Android snapshot helper manifest sha256 must be a 64-character hex string.`);return t}function M(e,t){if(typeof e!=`string`||e.trim().length===0)throw new r(`INVALID_ARGS`,`Android snapshot helper manifest ${t} is required.`);return e}function Or(e){return typeof e==`string`&&e.trim().length>0?e:void 0}function kr(e,t){return e===null?null:M(e,t)}function Ar(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 N=new Map;function jr(e){let t=`${e.deviceKey}\0${e.packageName}\0${e.versionCode}\0`;for(let e of N.keys())e.startsWith(t)&&Lr(e)}const Mr=`android-snapshot-helper-not-current`;function Nr(e){return n(e).details?.reason===Mr}function Pr(){N.clear()}function Fr(e,t,n,r){return e?`${e}\0${t}\0${n}\0${r}`:void 0}function Ir(e,t){if(!e)return;let[n,r]=e.split(`\0`),i=`${n}\0${r}\0`;for(let t of N.keys())t!==e&&t.startsWith(i)&&N.delete(t);N.set(e,t)}function Lr(e){e&&N.delete(e)}async function Rr(e){let{adb:t,artifact:n}=e,i=e.installPolicy??`missing-or-outdated`,a=n.manifest.packageName,o=n.manifest.versionCode,s=n.manifest.sha256;if(i===`never`)return{packageName:a,versionCode:o,installed:!1,reason:`skipped`};let c=Fr(e.deviceKey,a,o,s),l=c?N.get(c):void 0;if(c&&i!==`always`&&l!==void 0)return{packageName:a,versionCode:o,installedVersionCode:l,installedSha256:s,installed:!1,reason:`current`};await _r(n.apkPath,s,`Android snapshot helper`);let u=i===`always`?{installedVersionCode:await Vr(t,a,e.timeoutMs,e.signal),reason:`forced`}:await dr({adb:t,adbProvider:Br(e.adbProvider,t),packageName:a,versionCode:o,sha256:s,signal:e.signal}),{installedVersionCode:d}=u,f=`installedSha256`in u?u.installedSha256:void 0,p=u.reason;if(p===`current`){if(d===void 0)throw Error(`Expected installed versionCode for current Android snapshot helper`);return Ir(c,d),{packageName:a,versionCode:o,installedVersionCode:d,installedSha256:f,installed:!1,reason:p}}if(i===`current-only`)throw new r(`COMMAND_FAILED`,`Android snapshot helper is not installed at the current version`,{reason:Mr,packageName:a,versionCode:o,installedVersionCode:d});let m;try{m=await Hr(t,e.adbProvider??t,n.apkPath,{packageName:a,timeoutMs:e.timeoutMs,signal:e.signal})}catch(e){throw Lr(c),zr(e,{packageName:a,versionCode:o})}if(m.exitCode!==0)throw Lr(c),zr(T(`Failed to install Android snapshot helper`,m,{packageName:a,versionCode:o}));return Ir(c,o),{packageName:a,versionCode:o,installedVersionCode:d,installedSha256:f,installed:!0,reason:p}}function zr(e,t){let r=n(e,`COMMAND_FAILED`);return r.details={...t,...r.details,androidSnapshotHelperInstallFailure:!0},r}function Br(e,t){return e?typeof e==`function`?{exec:e}:e:{exec:t}}async function Vr(e,t,n,r){let i=await b(e,[`cmd`,`package`,`list`,`packages`,`--show-versioncode`,t],{allowFailure:!0,timeoutMs:n,signal:r});if(i.exitCode===0)return Ur(`${i.stdout}\n${i.stderr}`,t)}async function Hr(e,t,n,r){let i=async()=>await lr(n,{allowFailure:!0,provider:t,replace:!0,timeoutMs:r.timeoutMs,signal:r.signal}),a=await i();if(a.exitCode===0||!Wr(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 Ur(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 Wr(e){return`${e.stdout}\n${e.stderr}`.includes(`INSTALL_FAILED_UPDATE_INCOMPATIBLE`)}function Gr(e){return e.errorType===`java.util.concurrent.TimeoutException`?`accessibility-timeout`:void 0}function Kr(e){return e===137?`accessibility-timeout`:void 0}function qr(e){return e?{androidCaptureFailureReason:e}:{}}function P(e,t,n,i){if(i instanceof r){let a=i.details??{};return new r(i.code,i.message,{...a,action:e,package:n,tool:t,hint:typeof a.hint==`string`?a.hint:Xr(t,a)},i)}return new r(`COMMAND_FAILED`,`Failed to ${e} Android ${t} for ${n}`,{action:e,package:n,tool:t,hint:Jr(t)},i)}function Jr(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 Yr(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 Xr(e,t){let n=(typeof t.stderr==`string`?t.stderr:``).toLowerCase();return e===`simpleperf`?Zr(n):$r(n)?`Use a device image that permits perfetto trace capture for shell, keep the app running, then retry perf trace start.`:Jr(e)}function Zr(e){return Qr(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.`:Jr(`simpleperf`)}function Qr(e){return e.includes(`permission denied`)||e.includes(`not profileable`)||e.includes(`profileable`)}function $r(e){return e.includes(`permission denied`)||e.includes(`not allowed`)}const ei=`adb-shell-simpleperf`,ti=`adb-shell-perfetto`,ni=15e3,F=3e4,ri=`/data/local/tmp`;async function ii(e,t){try{let n=await b(e,[`pidof`,t],{allowFailure:!0,timeoutMs:ni}),r=oi(n.stdout);if(n.exitCode===0&&r)return r}catch{}throw new r(`COMMAND_FAILED`,`No active Android app process found for ${t}`,{package:t,hint:`Run open <app> for this session again, wait for the app UI to appear, then retry perf.`})}async function ai(e,t,n){let i=await b(e,[C(`command -v ${w(t)} || which ${w(t)}`)],{allowFailure:!0,timeoutMs:ni});if(!(i.exitCode===0&&i.stdout.trim()))throw new r(`UNSUPPORTED_OPERATION`,`Android device does not expose ${t}`,{package:n,tool:t,hint:Yr(t)})}function oi(e){return e.trim().split(/\s+/).find(e=>/^\d+$/.test(e))}const si=2e3,ci=`android_snapshot_helper_runtime_occupied`,I=new Map;function li(e){return`${e.platform}:${e.id}`}async function ui(e){await Ci({adb:e.adb,packageName:e.packageName}),await fi({deviceKey:e.deviceKey,packageName:e.packageName,adb:e.adb,cause:e.cause})}async function di(e){let t=I.get(e.deviceKey);if(!t)return;await Ci({adb:e.adb,packageName:t.packageName,timeoutMs:5e3,...e.signal?{signal:e.signal}:{}}),e.signal?.throwIfAborted();let n=await hi({adb:e.adb,packageName:t.packageName});if(n===`occupied`&&(await _(250),n=await hi({adb:e.adb,packageName:t.packageName})),n===`occupied`)throw mi({deviceKey:e.deviceKey,packageName:t.packageName,cause:t.cause});n!==`unknown`&&I.delete(e.deviceKey)}async function fi(e){let t=e.release??await hi({adb:e.adb,packageName:e.packageName});if(t===`released`)return I.delete(e.deviceKey),t;let n=e.cause instanceof Error?e.cause.message:String(e.cause);return I.set(e.deviceKey,{packageName:e.packageName,cause:n}),g({level:`warn`,phase:`android_snapshot_helper_retirement_pending`,data:{deviceKey:e.deviceKey,packageName:e.packageName,release:t}}),t}function pi(e){return e instanceof r&&e.details?.reason===ci}function mi(e){let t=e.cause instanceof Error?e.cause.message:String(e.cause);return new r(`COMMAND_FAILED`,`Android automation helper is still holding device automation ownership`,{reason:ci,deviceKey:e.deviceKey,packageName:e.packageName,cause:t,hint:`Retry after the helper process exits, or restart the device if Android keeps reporting the helper as running.`})}async function hi(e){try{let t=await b(e.adb,[`pidof`,e.packageName,C(`|| echo AGENT_DEVICE_NO_HELPER`)],{allowFailure:!0,timeoutMs:si}),n=t.stdout.trim();return oi(n)?`occupied`:n===`AGENT_DEVICE_NO_HELPER`&&t.stderr.trim().length===0?`released`:`unknown`}catch{return`unknown`}}async function gi(e){let t=AbortSignal.timeout(e.timeoutMs);return await Promise.all([...e.forceStopRuntime?[Ci({adb:e.adb,packageName:e.packageName,timeoutMs:e.timeoutMs,signal:t})]:[],wi({...e,signal:t})]),{timedOut:t.aborted}}function _i(e){let t=vi(e);return{ended:t?Promise.resolve():new Promise(t=>{e.once(`close`,()=>t()),e.once(`exit`,()=>t())}),hasEnded:()=>vi(e),completedCleanly:()=>!t&&e.exitCode===0&&e.signalCode==null}}function vi(e){return e.exitCode!=null||e.signalCode!=null}async function yi(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 bi(e){if(e.processExit.hasEnded())return!0;try{e.process.kill(`SIGTERM`)}catch{}return await yi(e.processExit.ended,e.timeoutMs)}function xi(e){I.delete(e)}function Si(){I.clear()}async function Ci(e){await b(e.adb,[`am`,`force-stop`,e.packageName],{allowFailure:!0,timeoutMs:e.timeoutMs??2e3,...e.signal?{signal:e.signal}:{}}).catch(()=>{})}async function wi(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 Ti(e){let t=Di(e),n=e.deviceKey??`android:default`;await di({deviceKey:n,adb:e.adb,signal:e.signal});let i;try{i=await e.adb(Oi(t),{allowFailure:!0,timeoutMs:t.commandTimeoutMs,signal:e.signal})}catch(r){throw e.signal?.aborted?(await ui({deviceKey:n,packageName:t.packageName,adb:e.adb,cause:r}),e.signal.throwIfAborted(),r):r}e.signal?.aborted&&(await ui({deviceKey:n,packageName:t.packageName,adb:e.adb,cause:e.signal.reason}),e.signal.throwIfAborted());let a=ki(i);if(i.exitCode!==0)throw new r(`COMMAND_FAILED`,`Android snapshot helper failed`,Le(i,{helper:a.metadata}));return a}function Ei(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:Sr,commandTimeoutMs:Cr,...e.signal?{signal:e.signal}:{}}}function Di(e){let t=L(e.timeoutMs,8e3),n=L(e.packageName,`com.callstack.agentdevice.snapshothelper`);return{waitForIdleTimeoutMs:L(e.waitForIdleTimeoutMs,500),waitForIdleQuietMs:L(e.waitForIdleQuietMs,100),timeoutMs:t,commandTimeoutMs:L(e.commandTimeoutMs,t+5e3),maxDepth:L(e.maxDepth,128),maxNodes:L(e.maxNodes,5e3),packageName:n,runner:L(e.instrumentationRunner,`${n}/.SnapshotInstrumentation`),...e.emitChunks===void 0?{}:{emitChunks:e.emitChunks}}}function L(e,t){return e===void 0?t:e}function Oi(e,t={}){return at(`adb`,`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.emitChunks===void 0?[]:[`-e`,`emitChunks`,String(e.emitChunks)],...t.sessionPort===void 0?[]:[`-e`,`sessionPort`,t.sessionPort],e.runner])}function ki(e){try{return Ai(`${e.stdout}\n${e.stderr}`)}catch(t){throw(t instanceof r&&t.details?.helper?t:void 0)||new r(`COMMAND_FAILED`,e.exitCode===0?`Android snapshot helper output could not be parsed`:`Android snapshot helper failed before returning parseable output`,{stdout:e.stdout,stderr:e.stderr,exitCode:e.exitCode,...qr(Kr(e.exitCode))},t)}}function Ai(e){let t=$n(e),n=Mi(t.results);return{xml:Pi(ji(t.status),n),metadata:{...Ri(n),transport:`instrumentation`}}}function ji(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:R(n.chunkIndex),count:R(n.chunkCount),payloadBase64:e})}return t}function Mi(e){let t=e.find(e=>e.agentDeviceProtocol===br);if(!t)throw new r(`COMMAND_FAILED`,`Android snapshot helper did not return a final result`);if(t.ok!==`true`)throw new r(`COMMAND_FAILED`,Ni(t),{errorType:t.errorType,helper:t,...qr(Gr(t))});return t}function Ni(e){return e.message&&e.message!==`null`?e.message:e.errorType||`Android snapshot helper returned an error`}function Pi(e,t){if(e.length===0)throw new r(`COMMAND_FAILED`,`Android snapshot helper did not return XML chunks`,{helper:t});let n=Fi(e),i=Buffer.concat(Li(Ii(e,n),n)).toString(`utf8`);if(!i.includes(`<hierarchy`)||!i.includes(`</hierarchy>`))throw new r(`COMMAND_FAILED`,`Android snapshot helper output did not contain XML`,{xml:i});return i}function Fi(e){let t=e[0]?.count??e.length;if(t<1||e.length!==t||e.some(e=>e.count!==t))throw new r(`COMMAND_FAILED`,`Android snapshot helper returned incomplete XML chunks`,{expectedChunks:t,actualChunks:e.length});return t}function Ii(e,t){let n=new Map;for(let i of e){if(i.index===void 0||i.index<0||i.index>=t)throw new r(`COMMAND_FAILED`,`Android snapshot helper returned invalid chunk index`,{chunkIndex:i.index,expectedChunks:t});if(n.has(i.index))throw new r(`COMMAND_FAILED`,`Android snapshot helper returned duplicate XML chunks`,{chunkIndex:i.index});n.set(i.index,i.payloadBase64)}return n}function Li(e,t){let n=[];for(let i=0;i<t;i+=1){let a=e.get(i);if(a===void 0)throw new r(`COMMAND_FAILED`,`Android snapshot helper returned incomplete XML chunks`,{missingChunkIndex:i,expectedChunks:t});n.push(Buffer.from(a,`base64`))}return n}function Ri(e){return{helperApiVersion:e.helperApiVersion,outputFormat:xr,waitForIdleTimeoutMs:R(e.waitForIdleTimeoutMs),waitForIdleQuietMs:R(e.waitForIdleQuietMs),timeoutMs:R(e.timeoutMs),maxDepth:R(e.maxDepth),maxNodes:R(e.maxNodes),rootPresent:Bi(e.rootPresent),captureMode:zi(e.captureMode),windowCount:R(e.windowCount),missingRootWindowTypes:ar(e.missingRootWindowTypes),nodeCount:R(e.nodeCount),truncated:Bi(e.truncated),elapsedMs:R(e.elapsedMs),pixelDensity:R(e.pixelDensity),displayWidth:R(e.displayWidth),displayHeight:R(e.displayHeight)}}function zi(e){return e===`interactive-windows`||e===`active-window`?e:void 0}const R=j,Bi=or;function Vi(){return new Promise((e,t)=>{let n=_n.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 Hi(e,t,n,i){return new Promise((a,o)=>{let s=_n.connect({host:`127.0.0.1`,port:e}),c=[],l=setTimeout(()=>{u(),s.destroy(),o(new r(`COMMAND_FAILED`,`Android snapshot helper session request timed out`,{command:t,timeoutMs:n,port:e}))},n),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(`${t}\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 Ui(e){let t=`snapshot-${Date.now()}-${Math.random().toString(16).slice(2)}`;return Yi(await Hi(e.port,`snapshot ${t}`,Wi(e),e.signal),t)}function Wi(e){return Math.min(e.commandTimeoutMs,Math.max(e.timeoutMs+3e3,3e3))}function Gi(e,t,n){return new Promise((i,a)=>{let o=``,s=setTimeout(()=>{n?.removeEventListener(`abort`,l),a(new r(`COMMAND_FAILED`,`Android snapshot helper session did not become ready`,{output:o,timeoutMs:t,reason:`android_snapshot_helper_session_ready_timeout`}))},t),c=e=>{o+=e.toString(),o.includes(`agentDeviceProtocol=android-snapshot-helper-v1`)&&o.includes(`sessionReady=true`)&&(clearTimeout(s),n?.removeEventListener(`abort`,l),i())},l=()=>{clearTimeout(s),a(n?.reason??new DOMException(`The operation was aborted`,`AbortError`))};if(n?.addEventListener(`abort`,l,{once:!0}),n?.aborted){l();return}e.stdout?.on(`data`,c),e.stderr?.on(`data`,c),e.once(`exit`,(e,t)=>{clearTimeout(s),n?.removeEventListener(`abort`,l),a(new r(`COMMAND_FAILED`,`Android snapshot helper session exited before ready`,{output:o,exitCode:e,signal:t,reason:`android_snapshot_helper_session_exited_before_ready`}))}),e.on(`error`,e=>{clearTimeout(s),n?.removeEventListener(`abort`,l),a(e)})})}function Ki(e){let t=e.indexOf(`
5
5
 
6
- `);return ia(e.slice(0,t<0?e.length:t))}function $i(e,t){if(e.agentDeviceProtocol!==`android-snapshot-helper-v1`)throw new a(`COMMAND_FAILED`,`Android automation helper session returned wrong protocol`,{headers:e});if(e.requestId!==t)throw new a(`COMMAND_FAILED`,`Android automation helper session returned stale output`,{headers:e,requestId:t})}function ea(e,t){let n=Qi(e);return n.agentDeviceProtocol===`android-snapshot-helper-v1`&&n.requestId===t&&n.ok===`true`}function ta(e,t){let n=e.indexOf(`
6
+ `);return Qi(e.slice(0,t<0?e.length:t))}function qi(e,t){if(e.agentDeviceProtocol!==`android-snapshot-helper-v1`)throw new r(`COMMAND_FAILED`,`Android automation helper session returned wrong protocol`,{headers:e});if(e.requestId!==t)throw new r(`COMMAND_FAILED`,`Android automation helper session returned stale output`,{headers:e,requestId:t})}function Ji(e,t){let n=Ki(e);return n.agentDeviceProtocol===`android-snapshot-helper-v1`&&n.requestId===t&&n.ok===`true`}function Yi(e,t){let n=e.indexOf(`
7
7
 
8
- `);if(n<0)throw new a(`COMMAND_FAILED`,`Android snapshot helper session returned malformed output`,{response:e});let r=ia(e.slice(0,n)),i=e.slice(n+2);return na(r,t),ra(r,i),{xml:i,metadata:aa(r)}}function na(e,t){if(e.agentDeviceProtocol!==`android-snapshot-helper-v1`)throw new a(`COMMAND_FAILED`,`Android snapshot helper session returned wrong protocol`,{headers:e});if(e.outputFormat!==`uiautomator-xml`)throw new a(`COMMAND_FAILED`,`Android snapshot helper session returned wrong output format`,{headers:e});if(e.requestId!==t)throw new a(`COMMAND_FAILED`,`Android snapshot helper session returned stale output`,{headers:e,requestId:t});if(e.ok!==`true`)throw new a(`COMMAND_FAILED`,e.message||e.errorType||`Android snapshot helper session returned an error`,{helper:e,...qr(Gr(e))})}function ra(e,t){let n=M(e.byteLength);if(n!==void 0&&Buffer.byteLength(t,`utf8`)!==n)throw new a(`COMMAND_FAILED`,`Android snapshot helper session returned truncated XML`,{headers:e,actualByteLength:Buffer.byteLength(t,`utf8`)});if(!t.includes(`<hierarchy`)||!t.includes(`</hierarchy>`))throw new a(`COMMAND_FAILED`,`Android snapshot helper session did not return XML`,{headers:e,xml:t})}function ia(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 aa(e){return{helperApiVersion:e.helperApiVersion,outputFormat:xr,waitForIdleTimeoutMs:M(e.waitForIdleTimeoutMs),waitForIdleQuietMs:M(e.waitForIdleQuietMs),timeoutMs:M(e.timeoutMs),maxDepth:M(e.maxDepth),maxNodes:M(e.maxNodes),rootPresent:or(e.rootPresent),captureMode:e.captureMode===`interactive-windows`||e.captureMode===`active-window`?e.captureMode:void 0,windowCount:M(e.windowCount),missingRootWindowTypes:ar(e.missingRootWindowTypes),nodeCount:M(e.nodeCount),truncated:or(e.truncated),elapsedMs:M(e.elapsedMs),pixelDensity:M(e.pixelDensity),displayWidth:M(e.displayWidth),displayHeight:M(e.displayHeight)}}const oa=5e3,V=new Map,H=new Map;async function sa(e){return await ca(e)!==void 0}async function ca(e){let t=e.deviceKey??`android:default`;if(await ui({deviceKey:t,adb:e.adb,signal:e.signal}),!xa()||!e.adbProvider?.spawn)return;let n=Ei(e),r=ya(n),i=await ua({deviceKey:t,identity:va(t,r,e),options:e,resolved:r,startBudgetMs:ba(n.commandTimeoutMs)});return i?{session:i,resolved:r,deviceKey:t}:void 0}function la(e){return V.get(e)}async function ua(e){if(!pa(e.identity))return await da(e.deviceKey,e.identity),V.get(e.deviceKey)??await fa(e)}async function da(e,t){let n=V.get(e);!n||ga(n,t)||await U(e,{force:_i(n.process)})}async function fa(e){let t=Date.now();try{return await _a(e)}catch(n){e.options.signal?.throwIfAborted(),H.set(e.identity,Date.now()+ma(Date.now()-t)),g({level:`warn`,phase:`android_snapshot_helper_session_start_failed`,data:{deviceKey:e.deviceKey,reason:n instanceof a?n.details?.reason:void 0,detail:n instanceof Error?n.message:String(n)}});return}}function pa(e){let t=H.get(e);return t===void 0?!1:t>Date.now()||(H.delete(e),!1)}function ma(e){return Math.min(Math.max(e,1e4),6e4)}async function ha(e){await U(e.deviceKey,{force:!0,signal:e.signal,cause:e.cause}),!e.signal?.aborted&&H.set(e.identity,Date.now()+e.fallbackBudgetMs+ma(e.failedAfterMs))}function ga(e,t){return e.identity===t&&!_i(e.process)}async function _a(e){let t=await qi();await e.options.adb([`forward`,`tcp:${t}`,`tcp:${t}`],{allowFailure:!1,timeoutMs:oa,signal:e.options.signal});let n=Di({...e.resolved,outputPath:void 0,emitChunks:!1},{sessionPort:t}),r=e.options.adbProvider.spawn(n,{allowFailure:!0,captureOutput:!1}),i={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:t,adb:e.options.adb,process:r,startedAtMs:Date.now(),capturedCount:0};try{return await Zi(r,e.startBudgetMs,e.options.signal),V.set(e.deviceKey,i),H.delete(e.identity),bi(e.deviceKey),g({phase:`android_snapshot_helper_session_ready`,data:{deviceKey:e.deviceKey,port:t,packageName:e.resolved.packageName,runner:e.resolved.runner}}),i}catch(t){let n=gi(r);try{r.kill(`SIGTERM`)}catch{}throw await Promise.all([vi(n.ended,250),hi({adb:i.adb,process:i.process,port:i.port,packageName:i.helper.packageName,timeoutMs:oi,forceStopRuntime:!0})]),await di({deviceKey:e.deviceKey,packageName:i.helper.packageName,adb:i.adb,cause:t}),t}}function va(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 ya(e){let t=Math.min(e.timeoutMs,2e3);return{...e,timeoutMs:t,commandTimeoutMs:Math.min(e.commandTimeoutMs,t+3e3)}}function ba(e){return Math.min(e,Math.max(Math.floor(e/2),5e3))}function xa(){let e=b().environment.AGENT_DEVICE_ANDROID_SNAPSHOT_HELPER_SESSION;return e===void 0||!/^(0|false|no|off)$/i.test(e)}async function U(e,t={}){let n=V.get(e);if(!n)return!1;V.delete(e);let r=gi(n.process),i=t.force===!0||t.signal?.aborted===!0,a=await Sa(n,r,i,t.signal),o=r.hasEnded(),s=a.acknowledged&&a.exited,c=s&&await bn({adb:n.adb,deviceKey:e,signal:t.signal}),l=i?t.signal?.aborted===!0?250:oi:oa,u=i?250:2e3,[d,f]=await Promise.all([yi({process:n.process,processExit:r,timeoutMs:u}),hi({adb:n.adb,process:n.process,port:n.port,packageName:n.helper.packageName,timeoutMs:l,forceStopRuntime:t.resetRuntime===!0||!c})]),p=await di({deviceKey:e,packageName:n.helper.packageName,adb:n.adb,cause:t.cause,...c?{release:`released`}:{}});return g({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 Sa(e,t,n,r){if(n)return{acknowledged:!1,exited:!1};let i=`quit-${Date.now()}`;try{let n=ea(await Ji(e.port,`quit ${i}`,1e3,r),i);return{acknowledged:n,exited:n&&await vi(t.ended,11e3,r)&&t.completedCleanly()}}catch{return{acknowledged:!1,exited:!1}}}async function Ca(e){await U(ci(e))}async function wa(){try{await Promise.allSettled([...V.keys()].map(async e=>{await U(e)}))}finally{V.clear(),H.clear(),xi(),xn()}}async function Ta(e){let t=await ca(e);if(t)return await Ea({session:t.session,deviceKey:t.deviceKey,options:e,resolved:t.resolved})}async function Ea(e){let{session:t,deviceKey:n,options:r,resolved:i}=e,a=Date.now();try{let e=t.capturedCount>0,n=await Yi({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 ha({deviceKey:n,identity:t.identity,failedAfterMs:Date.now()-a,fallbackBudgetMs:Ei(r).commandTimeoutMs,signal:r.signal,cause:e}),r.signal?.throwIfAborted(),g({level:`warn`,phase:`android_snapshot_helper_session_fallback`,data:{deviceKey:n,reason:e instanceof Error?e.message:String(e),uiAutomationConnectionTimeout:Lt(e)===`accessibility-timeout`}});return}}function W(e,t){return e!==`gesture`||!(t instanceof a)?t:u(t,st(t)?`no`:`unknown`)}async function Da(e){let t=la(e.deviceKey);if(!t)return;if(!Oa(t.helper,e.helper)){g({level:`warn`,phase:`android_snapshot_helper_session_touch_identity_mismatch`,data:{deviceKey:e.deviceKey,sessionHelper:t.helper,requestedHelper:e.helper}}),await U(e.deviceKey);return}let n=`${e.action}-${Date.now()}-${Math.random().toString(16).slice(2)}`,r=e.payloadBase64?`${e.action} ${n} ${e.payloadBase64}`:`${e.action} ${n}`,i;try{i=Qi(await Ji(t.port,r,e.timeoutMs)),$i(i,n)}catch(t){throw await U(e.deviceKey),W(e.action,t)}if(i.ok!==`true`)throw W(e.action,new a(`COMMAND_FAILED`,i.message||i.errorType||`Android automation helper ${e.action} failed`,{errorType:i.errorType,helper:i}));return i}function Oa(e,t){return e.packageName===t.packageName&&e.runner===t.runner&&ka(e.helperVersion,t.helperVersion)&&ka(e.helperVersionCode,t.helperVersionCode)&&ka(e.sha256,t.sha256)}function ka(e,t){return e===void 0||t===void 0||e===t}const Aa=`android-touch-plan-v1`,ja=45e3,Ma=`ANDROID_TOUCH_HELPER_NO_FINAL_RESULT`,Na=`ANDROID_TOUCH_HELPER_REPORTED_FAILURE`;async function Pa(e,t){let n=await La(e),r=za(t),i=Math.max(45e3,r.durationMs+15e3),a=Buffer.from(JSON.stringify({protocol:Aa,...r})).toString(`base64`),o=await h(`android_touch_helper_gesture`,async()=>{let e=await Da({deviceKey:n.deviceKey,action:`gesture`,helper:Ia(n.artifact),payloadBase64:a,timeoutMs:i});return e?{...Ua(e),helperTransport:`persistent-session`}:{...await Va({adb:n.adb,runner:n.artifact.manifest.instrumentationRunner,action:`gesture`,extraArgs:[`-e`,`payloadBase64`,a],timeoutMs:i,readResult:Ua}),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 Fa(e,t={}){let n=await La(e);t.helperSessionScope===`daemon-session`&&await sa(Ti({adb:n.adb,adbProvider:n.adbProvider,artifact:n.artifact,deviceKey:n.deviceKey}));try{let e=await Da({deviceKey:n.deviceKey,action:`viewport`,helper:Ia(n.artifact),timeoutMs:ja});if(e)return Wa(e)}catch(e){await U(n.deviceKey),g({level:`warn`,phase:`android_touch_helper_viewport_session_fallback`,data:{reason:e instanceof Error?e.message:String(e)}})}return await Va({adb:n.adb,runner:n.artifact.manifest.instrumentationRunner,action:`viewport`,extraArgs:[],timeoutMs:ja,readResult:Wa})}function Ia(e){return{packageName:e.manifest.packageName,runner:e.manifest.instrumentationRunner,helperVersion:e.manifest.version,helperVersionCode:e.manifest.versionCode,sha256:e.manifest.sha256}}async function La(e){let t=S(e),n=t.snapshotHelperArtifact??await Ra(),r=ci(e);await ui({deviceKey:r,adb:t.exec});let i=await h(`android_touch_helper_install`,async()=>await Rr({adb:t.exec,adbProvider:t,artifact:n,deviceKey:r,timeoutMs:3e4}),{packageName:n.manifest.packageName,versionCode:n.manifest.versionCode});return g({phase:`android_touch_helper_install_decision`,data:i}),i.installed&&await U(r),{adb:t.exec,adbProvider:t,artifact:n,install:i,deviceKey:r}}async function Ra(){return await fr({helperDirName:`snapshot-helper`,manifestFileName:e=>`agent-device-android-snapshot-helper-${e}.manifest.json`,parseManifest:e=>{let t=wr(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 za(e){return{kind:e.topology===`single`?`swipe`:`transform`,durationMs:e.durationMs,pointers:e.pointers.map(Ba)}}function Ba(e){return{pointerId:e.pointerId,samples:e.samples.map(({offsetMs:e,point:t})=>({offsetMs:e,x:t.x,y:t.y}))}}async function Va(e){let t=await y(e.adb,[`am`,`instrument`,`-w`,`-e`,`mode`,e.action,...e.extraArgs,e.runner],{allowFailure:!0,timeoutMs:e.timeoutMs}),n;try{n=Ha(`${t.stdout}\n${t.stderr}`)}catch(n){if(n instanceof a){if(n.code===Na)throw W(e.action,new a(`COMMAND_FAILED`,n.message,n.details,n));if(n.code!==Ma)throw n}let r=new a(`COMMAND_FAILED`,t.exitCode===0?`Android automation helper output could not be parsed`:`Android automation helper failed before returning parseable output`,Fe(t),n);throw W(e.action,t.exitCode===0?r:ot(r))}if(t.exitCode!==0)throw W(e.action,ot(new a(`COMMAND_FAILED`,`Android automation helper failed`,Fe(t,{helper:n}))));return e.readResult(n)}function Ha(e){let t=$n(e).results.find(e=>e.agentDeviceProtocol===br);if(!t)throw new a(Ma,`Android automation helper did not return a final result`);if(t.ok!==`true`)throw new a(Na,t.message&&t.message!==`null`?t.message:t.errorType||`Android automation helper returned an error`,{errorType:t.errorType,helper:t});return t}function Ua(e){return{helperKind:e.kind,helperApiVersion:e.helperApiVersion,injectedEvents:M(e.injectedEvents),elapsedMs:M(e.elapsedMs)}}function Wa(e){let t=M(e.x),n=M(e.y),r=M(e.width),i=M(e.height);if(t===void 0||n===void 0||r===void 0||i===void 0)throw new a(`COMMAND_FAILED`,`Android helper returned an invalid gesture viewport`);let o=Ga(e);return{viewport:sr({x:t,y:n,width:r,height:i}),...o?{keyboard:o}:{}}}function Ga(e){let t=M(e.keyboardX),n=M(e.keyboardY),r=M(e.keyboardWidth),i=M(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 Ka(e){if(e.topology===`two`||e.intent===`longPress`)return e;let{releaseBehavior:t,...n}=e,[{pointerId:r,samples:i}]=n.pointers,a=[...new Set([...pt(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:ht(n.point,r.point,t===`controlled`?qa(s,a):s)}}),c=[s[0],s[1],s[2],...s.slice(3)];return{...n,pointers:[{pointerId:r,samples:c}]}}function qa(e,t){let n=Math.min(16/t,.5);return e<n?e**2/n:1-(1-e)**2/(1-n)}async function Ja(e,t){let n=Ka(t),r=Ve(e);if(r){let e=n.intent===`longPress`?{...n,viewport:sr(await r.gestureViewport())}:n;return{backend:`provider-native-touch`,...await r.touch(e)??{}}}return await Pa(e,n)}async function Ya(e,t={}){return(await Xa(e,t)).viewport}async function Xa(e,t={}){let n=Ve(e);return n?{viewport:sr(await n.gestureViewport())}:await Fa(e,t)}async function G(e,t,n){try{await E(e,[`input`,`tap`,t,n])}catch(e){throw at(e)}}async function Za(e,t,r){await G(e,t,r);try{await G(e,t,r)}catch(e){throw n(e,1)}}async function Qa(e,t,n){let r=Ie(t);await E(e,[`input`,...n&&n>0?[`keyevent`,`--longpress`]:[`keyevent`],r])}async function $a(e){await E(e,[`input`,`keyevent`,`4`])}async function eo(e){await E(e,[`input`,`keyevent`,`3`])}async function to(e){await E(e,[`input`,`keyevent`,`ENTER`])}async function no(e,t){let n=ho(t);await E(e,[`settings`,`put`,`system`,`accelerometer_rotation`,`0`]),await E(e,[`settings`,`put`,`system`,`user_rotation`,n]),await io(e,t,n)}const ro=15e3;async function io(e,t,n){let r=Date.now()+ro,i=await ao(e,t,r);for(;i!==void 0&&i!==n&&Date.now()<r;)await _(Math.min(500,oo(r))),i=await ao(e,t,r);if(i!==void 0&&i!==n)throw new a(`COMMAND_FAILED`,`orientation ${t} did not take effect: the display still reports rotation ${i} after ${ro}ms`,{requestedRotation:Number(n),observedRotation:Number(i),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 ao(e,t,n){try{return(await so(e,{timeoutMs:oo(n)}))[0]}catch(e){throw new a(`COMMAND_FAILED`,`orientation ${t} 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 oo(e){return Math.max(1,e-Date.now())}async function so(e,t){let n=await E(e,[`dumpsys`,`display`],{...t,allowFailure:!0});if(n.exitCode!==0)throw T(`adb shell dumpsys display exited with code ${n.exitCode}`,n);return[...n.stdout.matchAll(/mCurrentOrientation=(\d)/g)].map(e=>e[1])}async function co(e,t){try{let n=await so(e,t);return n.length===1?Ae(Number(n[0])):void 0}catch{return}}async function lo(e){await E(e,[`input`,`keyevent`,`187`])}async function uo(e,t,n,r=800){let i={x:t,y:n};return await Ja(e,{topology:`single`,intent:`longPress`,durationMs:r,pointers:[{pointerId:0,samples:[{offsetMs:0,point:i},{offsetMs:r,point:i}]}]})}async function fo(e,t,n){await G(e,t,n)}async function po(e,t,n){let{viewport:r,keyboard:i}=await Xa(e,{helperSessionScope:n?.helperSessionScope}),a=mo(t,r,i),o=ge({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 Ja(e,{...mt({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 mo(e,t,n){if(n===void 0)return{viewport:t,evidence:{}};let r=_e(t,n);if(r.kind===`occluded`)throw he(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 ho(e){let t=ke[e];if(t===void 0)throw new a(`INVALID_ARGS`,`Unsupported Android rotation: ${e}`);return String(t)}async function go(e){let t=(await E(e,[`wm`,`size`])).stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(!t)throw new a(`COMMAND_FAILED`,`Unable to read screen size`);return{width:Number(t[1]),height:Number(t[2])}}async function _o(e,t,n){return t===`wait`?await vo(n.captureNodes,n.timeoutMs??1e4):t===`get`?wo((await Co(n.captureNodes))?.alert??null):await yo(e,t,n.captureNodes)}async function vo(e,t){let n=Date.now(),r=await So(e,t);if(!r)throw new a(`COMMAND_FAILED`,`alert wait timed out`);return{kind:`alertWait`,platform:`android`,action:`wait`,alert:r.alert,waitedMs:Date.now()-n,...ve(`Alert visible`)}}async function yo(e,t,n){let r=await So(n,ye);if(!r)throw new a(`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 i=Fn(r.buttons,t);if(i)return await G(e,i.x,i.y),await bo(r.alert,t,n),To(t,r.alert,i.label,{x:i.x,y:i.y});if(t===`dismiss`)return await $a(e),await bo(r.alert,t,n),To(t,r.alert,`Back`);throw new a(`COMMAND_FAILED`,`alert accept found an alert but no accept button`,{alert:r.alert,hint:`Inspect alert get --json for visible buttons, then use press by visible label/ref if needed.`})}async function bo(e,t,n){let r=Date.now();for(;;){let i=await Co(n);if(!i||!xo(i.alert,e))return;if(Date.now()-r>=2e3)throw new a(`COMMAND_FAILED`,`alert ${t} 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 _(300)}}function xo(e,t){return e.title===t.title&&e.buttons.join(`\0`)===t.buttons.join(`\0`)}async function So(e,t){let n=Date.now();for(;Date.now()-n<t;){let t=await Co(e);if(t)return t;await _(300)}return null}async function Co(e){return Nn(await h(`snapshot_capture`,e,{backend:`android`,purpose:`alert`}))}function wo(e){return{kind:`alertStatus`,platform:`android`,action:`get`,alert:e,...ve(e?`Alert visible`:`No alert visible`)}}function To(e,t,n,r){return{kind:`alertHandled`,platform:`android`,action:e,handled:!0,alert:t,button:n,...r?{coordinates:r}:{},...ve(`Alert ${e}ed`)}}const Eo=`android.intent.category.LAUNCHER`,Do=`android.intent.category.DEFAULT`;async function Oo(e,t){await y(e,[`am`,`force-stop`,t])}async function ko(e,t,n=[Eo]){for(let r of n){let n=await y(e,[`cmd`,`package`,`resolve-activity`,`--brief`,`-a`,`android.intent.action.MAIN`,`-c`,r,t],{allowFailure:!0});if(n.exitCode!==0)continue;let i=Ut(n.stdout);if(i)return i}return null}async function Ao(e,t,n={}){let r=n.category??Eo;if(n.activity){await y(e,[`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,Do,`-c`,r,`-n`,jo(t,n.activity)]);return}let i=await y(e,[`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,Do,`-c`,r,`-p`,t],{allowFailure:!0});if(i.exitCode===0&&!Wt(i.stdout,i.stderr))return;let o=await ko(e,t,[r]);if(!o)throw new a(`COMMAND_FAILED`,`Failed to resolve Android launch component for ${t}`,{stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode});await y(e,[`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,Do,`-c`,r,`-n`,o])}function jo(e,t){return t.includes(`/`)?t:`${e}/${t.startsWith(`.`)?t:`.${t}`}`}let Mo=null;function No(e){return`${e.PATH??``}::${e.AGENT_DEVICE_BUNDLETOOL_JAR??``}`}async function Po(e){let t=No(e);if(Mo?.key===t)return Mo.invocation;if(await Me(`bundletool`)){let e={cmd:`bundletool`,prefixArgs:[]};return Mo={key:t,invocation:e},e}let n=await je(e.AGENT_DEVICE_BUNDLETOOL_JAR,`AGENT_DEVICE_BUNDLETOOL_JAR`);if(!n)throw new a(`TOOL_MISSING`,`bundletool not found in PATH. Install bundletool or set AGENT_DEVICE_BUNDLETOOL_JAR to a bundletool-all.jar path.`);let r={cmd:`java`,prefixArgs:[`-jar`,n]};return Mo={key:t,invocation:r},r}async function Fo(e,t,n){let r=await Po(n);await Ne(r.cmd,[...r.prefixArgs,...e],{signal:t})}function Io(e){return A.extname(e).toLowerCase()===`.aab`}async function Lo(e,t,n={}){let r=S(e),i=`universal`;if(r.installBundle){await r.installBundle(t,{mode:i,signal:n.signal});return}let a=b().files,o=await a.makeTempDirectory(`agent-device-aab-`),s=A.join(o,`bundle.apks`);try{await Fo([`build-apks`,`--bundle`,t,`--output`,s,`--mode`,i],n.signal,n.environment??b().environment),await Fo([`install-apks`,`--apks`,s,`--device-id`,e.id],n.signal,n.environment??b().environment)}finally{await a.remove(o,{recursive:!0,force:!0})}}async function Ro(e,t,n={}){if(Io(t)){await Lo(e,t,n);return}await Ye(t,{device:e,replace:!0,signal:n.signal})}async function zo(e,t,n={}){await Jt(e,async()=>{e.booted||await zt(e.id,void 0,n.signal),await Ro(e,t,n)})}const Bo=[`mInputShown`,`mIsInputViewShown`,`isInputViewShown`,`mDecorViewVisible`,`mWindowVisible`,`mInShowWindow`],Vo=new Map([[2,`number`],[3,`phone`],[4,`datetime`]]),Ho=new Set([32,208]),Uo=new Set([128,224,144]);async function Wo(e){return await K(v(e))}async function K(e){let t=await y(e,[`dumpsys`,`input_method`],{allowFailure:!0});if(t.exitCode!==0)throw T(`Failed to query Android keyboard state`,t);return qo(t.stdout)}async function Go(e){return await Ko(v(e))}async function Ko(e){let t=await K(e),r=t,i=0;try{for(;r.visible&&i<2;)await y(e,[`input`,`keyevent`,`111`]),i+=1,await _(120),r=await K(e)}catch(e){throw n(e,i)}if(t.visible&&r.visible)throw new a(`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:t.visible,dismissed:t.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 qo(e){let t=Qo(e)??Jo(e),n=Yo(e),r=Xo(e,/\bpackageName=([A-Za-z0-9_.]+)\b/g),i=Xo(e,/\b(?:resourceId|resource-id)=([^\s,}]+)/g),a=ne(e),o=ie(r,i,a);return Zo(r,i,a),{visible:t??!1,inputType:n,type:n?ns(n):void 0,inputMethodPackage:a,focusedPackage:r,focusedResourceId:i,inputOwner:o}}function Jo(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 Yo(e){let t=Xo(e,/\binputType=0x([0-9a-fA-F]+)\b/gi);return t?`0x${t.toLowerCase()}`:void 0}function Xo(e,t){let n;for(let r of e.matchAll(t))n=r[1];return n}function Zo(e,t,n){n||!ee(e)&&!p(t)||g({level:`warn`,phase:`android_input_ownership_fallback`,data:{focusedPackage:e,focusedResourceId:t}})}function Qo(e){return es($o(e,Bo))}function $o(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 es(e){if(e.size===0)return null;let t=ts(e,[`mWindowVisible`,`mDecorViewVisible`,`mInShowWindow`]);if(t!==void 0)return t;let n=e.get(`mInputShown`);return n===void 0?ts(e,[`mIsInputViewShown`,`isInputViewShown`])??null:n}function ts(e,t){for(let n of t){let t=e.get(n);if(t!==void 0)return t}}function ns(e){let t=Number.parseInt(e.replace(/^0x/i,``),16);if(Number.isNaN(t))return`unknown`;let n=t&15,r=Vo.get(n);if(r)return r;if(n!==1)return`unknown`;let i=t&4080;return Ho.has(i)?`email`:Uo.has(i)?`password`:`text`}async function rs(e){return await is(v(e))}async function is(e){return cs(await ss(e,[`cmd`,`clipboard`,`get`,`text`],`read`))}async function as(e,t){await os(v(e),t)}async function os(e,t){await ss(e,[`cmd`,`clipboard`,`set`,`text`,t],`write`)}async function ss(e,t,n){let{androidClipboardShellCommandUnavailableError:r,classifyAndroidClipboardShellResponse:i}=await import(`./clipboard-shell-response.js`),a=await y(e,t,{allowFailure:!0}),o=i(a);if(o===`no-shell-command`)throw r(n);if(o===`call-failed`)throw T(`Failed to ${n} Android clipboard text`,a);return a.stdout}function cs(e){let t=e.replaceAll(`\r
8
+ `);if(n<0)throw new r(`COMMAND_FAILED`,`Android snapshot helper session returned malformed output`,{response:e});let i=Qi(e.slice(0,n)),a=e.slice(n+2);return Xi(i,t),Zi(i,a),{xml:a,metadata:$i(i)}}function Xi(e,t){if(e.agentDeviceProtocol!==`android-snapshot-helper-v1`)throw new r(`COMMAND_FAILED`,`Android snapshot helper session returned wrong protocol`,{headers:e});if(e.outputFormat!==`uiautomator-xml`)throw new r(`COMMAND_FAILED`,`Android snapshot helper session returned wrong output format`,{headers:e});if(e.requestId!==t)throw new r(`COMMAND_FAILED`,`Android snapshot helper session returned stale output`,{headers:e,requestId:t});if(e.ok!==`true`)throw new r(`COMMAND_FAILED`,e.message||e.errorType||`Android snapshot helper session returned an error`,{helper:e,...qr(Gr(e))})}function Zi(e,t){let n=j(e.byteLength);if(n!==void 0&&Buffer.byteLength(t,`utf8`)!==n)throw new r(`COMMAND_FAILED`,`Android snapshot helper session returned truncated XML`,{headers:e,actualByteLength:Buffer.byteLength(t,`utf8`)});if(!t.includes(`<hierarchy`)||!t.includes(`</hierarchy>`))throw new r(`COMMAND_FAILED`,`Android snapshot helper session did not return XML`,{headers:e,xml:t})}function Qi(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 $i(e){return{helperApiVersion:e.helperApiVersion,outputFormat:xr,waitForIdleTimeoutMs:j(e.waitForIdleTimeoutMs),waitForIdleQuietMs:j(e.waitForIdleQuietMs),timeoutMs:j(e.timeoutMs),maxDepth:j(e.maxDepth),maxNodes:j(e.maxNodes),rootPresent:or(e.rootPresent),captureMode:e.captureMode===`interactive-windows`||e.captureMode===`active-window`?e.captureMode:void 0,windowCount:j(e.windowCount),missingRootWindowTypes:ar(e.missingRootWindowTypes),nodeCount:j(e.nodeCount),truncated:or(e.truncated),elapsedMs:j(e.elapsedMs),pixelDensity:j(e.pixelDensity),displayWidth:j(e.displayWidth),displayHeight:j(e.displayHeight)}}const ea=5e3,z=new Map,B=new Map;async function ta(e){return await na(e)!==void 0}async function na(e){let t=e.deviceKey??`android:default`;if(await di({deviceKey:t,adb:e.adb,signal:e.signal}),!ha()||!e.adbProvider?.spawn)return;let n=Di(e),r=pa(n),i=await ia({deviceKey:t,identity:fa(t,r,e),options:e,resolved:r,startBudgetMs:ma(n.commandTimeoutMs)});return i?{session:i,resolved:r,deviceKey:t}:void 0}function ra(e){return z.get(e)}async function ia(e){if(!sa(e.identity))return await aa(e.deviceKey,e.identity),z.get(e.deviceKey)??await oa(e)}async function aa(e,t){let n=z.get(e);!n||ua(n,t)||await V(e,{force:vi(n.process)})}async function oa(e){let t=Date.now();try{return await da(e)}catch(n){e.options.signal?.throwIfAborted(),B.set(e.identity,Date.now()+ca(Date.now()-t)),g({level:`warn`,phase:`android_snapshot_helper_session_start_failed`,data:{deviceKey:e.deviceKey,reason:n instanceof r?n.details?.reason:void 0,detail:n instanceof Error?n.message:String(n)}});return}}function sa(e){let t=B.get(e);return t===void 0?!1:t>Date.now()||(B.delete(e),!1)}function ca(e){return Math.min(Math.max(e,1e4),6e4)}async function la(e){await V(e.deviceKey,{force:!0,signal:e.signal,cause:e.cause}),!e.signal?.aborted&&B.set(e.identity,Date.now()+e.fallbackBudgetMs+ca(e.failedAfterMs))}function ua(e,t){return e.identity===t&&!vi(e.process)}async function da(e){let t=await Vi();await e.options.adb([`forward`,`tcp:${t}`,`tcp:${t}`],{allowFailure:!1,timeoutMs:ea,signal:e.options.signal});let n=Oi({...e.resolved,emitChunks:!1},{sessionPort:t}),r=e.options.adbProvider.spawn(n,{allowFailure:!0,captureOutput:!1}),i={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:t,adb:e.options.adb,process:r,startedAtMs:Date.now(),capturedCount:0};try{return await Gi(r,e.startBudgetMs,e.options.signal),z.set(e.deviceKey,i),B.delete(e.identity),xi(e.deviceKey),g({phase:`android_snapshot_helper_session_ready`,data:{deviceKey:e.deviceKey,port:t,packageName:e.resolved.packageName,runner:e.resolved.runner}}),i}catch(t){let n=_i(r);try{r.kill(`SIGTERM`)}catch{}throw await Promise.all([yi(n.ended,250),gi({adb:i.adb,process:i.process,port:i.port,packageName:i.helper.packageName,timeoutMs:si,forceStopRuntime:!0})]),await fi({deviceKey:e.deviceKey,packageName:i.helper.packageName,adb:i.adb,cause:t}),t}}function fa(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 pa(e){let t=Math.min(e.timeoutMs,2e3);return{...e,timeoutMs:t,commandTimeoutMs:Math.min(e.commandTimeoutMs,t+3e3)}}function ma(e){return Math.min(e,Math.max(Math.floor(e/2),5e3))}function ha(){let e=v().environment.AGENT_DEVICE_ANDROID_SNAPSHOT_HELPER_SESSION;return e===void 0||!/^(0|false|no|off)$/i.test(e)}async function V(e,t={}){let n=z.get(e);if(!n)return!1;z.delete(e);let r=_i(n.process),i=t.force===!0||t.signal?.aborted===!0,a=await ga(n,r,i,t.signal),o=r.hasEnded(),s=a.acknowledged&&a.exited,c=s&&await bn({adb:n.adb,deviceKey:e,signal:t.signal}),l=i?t.signal?.aborted===!0?250:si:ea,u=i?250:2e3,[d,f]=await Promise.all([bi({process:n.process,processExit:r,timeoutMs:u}),gi({adb:n.adb,process:n.process,port:n.port,packageName:n.helper.packageName,timeoutMs:l,forceStopRuntime:t.resetRuntime===!0||!c})]),p=await fi({deviceKey:e,packageName:n.helper.packageName,adb:n.adb,cause:t.cause,...c?{release:`released`}:{}});return g({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 ga(e,t,n,r){if(n)return{acknowledged:!1,exited:!1};let i=`quit-${Date.now()}`;try{let n=Ji(await Hi(e.port,`quit ${i}`,1e3,r),i);return{acknowledged:n,exited:n&&await yi(t.ended,11e3,r)&&t.completedCleanly()}}catch{return{acknowledged:!1,exited:!1}}}async function _a(e){await V(li(e))}async function va(){try{await Promise.allSettled([...z.keys()].map(async e=>{await V(e)}))}finally{z.clear(),B.clear(),Si(),xn()}}async function ya(e){let t=await na(e);if(t)return await ba({session:t.session,deviceKey:t.deviceKey,options:e,resolved:t.resolved})}async function ba(e){let{session:t,deviceKey:n,options:r,resolved:i}=e,a=Date.now();try{let e=t.capturedCount>0,n=await Ui({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 la({deviceKey:n,identity:t.identity,failedAfterMs:Date.now()-a,fallbackBudgetMs:Di(r).commandTimeoutMs,signal:r.signal,cause:e}),r.signal?.throwIfAborted(),g({level:`warn`,phase:`android_snapshot_helper_session_fallback`,data:{deviceKey:n,reason:e instanceof Error?e.message:String(e),uiAutomationConnectionTimeout:It(e)===`accessibility-timeout`}});return}}function H(e,n){return e!==`gesture`||!(n instanceof r)?n:t(n,ct(n)?`no`:`unknown`)}async function xa(e){let t=ra(e.deviceKey);if(!t)return;if(!Sa(t.helper,e.helper)){g({level:`warn`,phase:`android_snapshot_helper_session_touch_identity_mismatch`,data:{deviceKey:e.deviceKey,sessionHelper:t.helper,requestedHelper:e.helper}}),await V(e.deviceKey);return}let n=`${e.action}-${Date.now()}-${Math.random().toString(16).slice(2)}`,i=e.payloadBase64?`${e.action} ${n} ${e.payloadBase64}`:`${e.action} ${n}`,a;try{a=Ki(await Hi(t.port,i,e.timeoutMs)),qi(a,n)}catch(t){throw await V(e.deviceKey),H(e.action,t)}if(a.ok!==`true`)throw H(e.action,new r(`COMMAND_FAILED`,a.message||a.errorType||`Android automation helper ${e.action} failed`,{errorType:a.errorType,helper:a}));return a}function Sa(e,t){return e.packageName===t.packageName&&e.runner===t.runner&&Ca(e.helperVersion,t.helperVersion)&&Ca(e.helperVersionCode,t.helperVersionCode)&&Ca(e.sha256,t.sha256)}function Ca(e,t){return e===void 0||t===void 0||e===t}const wa=`android-touch-plan-v1`,Ta=45e3,Ea=`ANDROID_TOUCH_HELPER_NO_FINAL_RESULT`,Da=`ANDROID_TOUCH_HELPER_REPORTED_FAILURE`;async function Oa(e,t){let n=await ja(e),r=Na(t),i=Math.max(45e3,r.durationMs+15e3),a=Buffer.from(JSON.stringify({protocol:wa,...r})).toString(`base64`),o=await h(`android_touch_helper_gesture`,async()=>{let e=await xa({deviceKey:n.deviceKey,action:`gesture`,helper:Aa(n.artifact),payloadBase64:a,timeoutMs:i});return e?{...La(e),helperTransport:`persistent-session`}:{...await Fa({adb:n.adb,runner:n.artifact.manifest.instrumentationRunner,action:`gesture`,extraArgs:[`-e`,`payloadBase64`,a],timeoutMs:i,readResult:La}),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 ka(e,t={}){let n=await ja(e);t.helperSessionScope===`daemon-session`&&await ta(Ei({adb:n.adb,adbProvider:n.adbProvider,artifact:n.artifact,deviceKey:n.deviceKey}));try{let e=await xa({deviceKey:n.deviceKey,action:`viewport`,helper:Aa(n.artifact),timeoutMs:Ta});if(e)return Ra(e)}catch(e){await V(n.deviceKey),g({level:`warn`,phase:`android_touch_helper_viewport_session_fallback`,data:{reason:e instanceof Error?e.message:String(e)}})}return await Fa({adb:n.adb,runner:n.artifact.manifest.instrumentationRunner,action:`viewport`,extraArgs:[],timeoutMs:Ta,readResult:Ra})}function Aa(e){return{packageName:e.manifest.packageName,runner:e.manifest.instrumentationRunner,helperVersion:e.manifest.version,helperVersionCode:e.manifest.versionCode,sha256:e.manifest.sha256}}async function ja(e){let t=x(e),n=t.snapshotHelperArtifact??await Ma(),r=li(e);await di({deviceKey:r,adb:t.exec});let i=await h(`android_touch_helper_install`,async()=>await Rr({adb:t.exec,adbProvider:t,artifact:n,deviceKey:r,timeoutMs:3e4}),{packageName:n.manifest.packageName,versionCode:n.manifest.versionCode});return g({phase:`android_touch_helper_install_decision`,data:i}),i.installed&&await V(r),{adb:t.exec,adbProvider:t,artifact:n,install:i,deviceKey:r}}async function Ma(){return await fr({helperDirName:`snapshot-helper`,manifestFileName:e=>`agent-device-android-snapshot-helper-${e}.manifest.json`,parseManifest:e=>{let t=wr(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 Na(e){return{kind:e.topology===`single`?`swipe`:`transform`,durationMs:e.durationMs,pointers:e.pointers.map(Pa)}}function Pa(e){return{pointerId:e.pointerId,samples:e.samples.map(({offsetMs:e,point:t})=>({offsetMs:e,x:t.x,y:t.y}))}}async function Fa(e){let t=await b(e.adb,[`am`,`instrument`,`-w`,`-e`,`mode`,e.action,...e.extraArgs,e.runner],{allowFailure:!0,timeoutMs:e.timeoutMs}),n;try{n=Ia(`${t.stdout}\n${t.stderr}`)}catch(n){if(n instanceof r){if(n.code===Da)throw H(e.action,new r(`COMMAND_FAILED`,n.message,n.details,n));if(n.code!==Ea)throw n}let i=new r(`COMMAND_FAILED`,t.exitCode===0?`Android automation helper output could not be parsed`:`Android automation helper failed before returning parseable output`,Le(t),n);throw H(e.action,t.exitCode===0?i:st(i))}if(t.exitCode!==0)throw H(e.action,st(new r(`COMMAND_FAILED`,`Android automation helper failed`,Le(t,{helper:n}))));return e.readResult(n)}function Ia(e){let t=$n(e).results.find(e=>e.agentDeviceProtocol===br);if(!t)throw new r(Ea,`Android automation helper did not return a final result`);if(t.ok!==`true`)throw new r(Da,t.message&&t.message!==`null`?t.message:t.errorType||`Android automation helper returned an error`,{errorType:t.errorType,helper:t});return t}function La(e){return{helperKind:e.kind,helperApiVersion:e.helperApiVersion,injectedEvents:j(e.injectedEvents),elapsedMs:j(e.elapsedMs)}}function Ra(e){let t=j(e.x),n=j(e.y),i=j(e.width),a=j(e.height);if(t===void 0||n===void 0||i===void 0||a===void 0)throw new r(`COMMAND_FAILED`,`Android helper returned an invalid gesture viewport`);let o=za(e);return{viewport:sr({x:t,y:n,width:i,height:a}),...o?{keyboard:o}:{}}}function za(e){let t=j(e.keyboardX),n=j(e.keyboardY),r=j(e.keyboardWidth),i=j(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 Ba(e){if(e.topology===`two`||e.intent===`longPress`)return e;let{releaseBehavior:t,...n}=e,[{pointerId:r,samples:i}]=n.pointers,a=[...new Set([...ht(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:_t(n.point,r.point,t===`controlled`?Va(s,a):s)}}),c=[s[0],s[1],s[2],...s.slice(3)];return{...n,pointers:[{pointerId:r,samples:c}]}}function Va(e,t){let n=Math.min(16/t,.5);return e<n?e**2/n:1-(1-e)**2/(1-n)}async function Ha(e,t){let n=Ba(t),r=Ue(e);if(r){let e=n.intent===`longPress`?{...n,viewport:sr(await r.gestureViewport())}:n;return{backend:`provider-native-touch`,...await r.touch(e)??{}}}return await Oa(e,n)}async function Ua(e,t={}){return(await Wa(e,t)).viewport}async function Wa(e,t={}){let n=Ue(e);return n?{viewport:sr(await n.gestureViewport())}:await ka(e,t)}async function U(e,t,n){try{await E(e,[`input`,`tap`,t,n])}catch(e){throw ot(e)}}async function Ga(e,t,n){await U(e,t,n);try{await U(e,t,n)}catch(e){throw i(e,1)}}async function Ka(e,t,n){let r=f(t);await E(e,[`input`,...n&&n>0?[`keyevent`,`--longpress`]:[`keyevent`],r])}async function qa(e){await E(e,[`input`,`keyevent`,`4`])}async function Ja(e){await E(e,[`input`,`keyevent`,`3`])}async function Ya(e){await E(e,[`input`,`keyevent`,`ENTER`])}async function Xa(e,t){let n=co(t);await E(e,[`settings`,`put`,`system`,`accelerometer_rotation`,`0`]),await E(e,[`settings`,`put`,`system`,`user_rotation`,n]),await Qa(e,t,n)}const Za=15e3;async function Qa(e,t,n){let i=Date.now()+Za,a=await $a(e,t,i);for(;a!==void 0&&a!==n&&Date.now()<i;)await _(Math.min(500,eo(i))),a=await $a(e,t,i);if(a!==void 0&&a!==n)throw new r(`COMMAND_FAILED`,`orientation ${t} did not take effect: the display still reports rotation ${a} after ${Za}ms`,{requestedRotation:Number(n),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 $a(e,t,n){try{return(await to(e,{timeoutMs:eo(n)}))[0]}catch(e){throw new r(`COMMAND_FAILED`,`orientation ${t} 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 eo(e){return Math.max(1,e-Date.now())}async function to(e,t){let n=await E(e,[`dumpsys`,`display`],{...t,allowFailure:!0});if(n.exitCode!==0)throw T(`adb shell dumpsys display exited with code ${n.exitCode}`,n);return[...n.stdout.matchAll(/mCurrentOrientation=(\d)/g)].map(e=>e[1])}async function no(e,t){try{let n=await to(e,t);return n.length===1?m(Number(n[0])):void 0}catch{return}}async function ro(e){await E(e,[`input`,`keyevent`,`187`])}async function io(e,t,n,r=800){let i={x:t,y:n};return await Ha(e,{topology:`single`,intent:`longPress`,durationMs:r,pointers:[{pointerId:0,samples:[{offsetMs:0,point:i},{offsetMs:r,point:i}]}]})}async function ao(e,t,n){await U(e,t,n)}async function oo(e,t,n){let{viewport:r,keyboard:i}=await Wa(e,{helperSessionScope:n?.helperSessionScope}),a=so(t,r,i),o=ne({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 Ha(e,{...gt({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 so(e,t,n){if(n===void 0)return{viewport:t,evidence:{}};let r=ee(t,n);if(r.kind===`occluded`)throw te(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 co(e){let t=p[e];if(t===void 0)throw new r(`INVALID_ARGS`,`Unsupported Android rotation: ${e}`);return String(t)}async function lo(e){let t=(await E(e,[`wm`,`size`])).stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(!t)throw new r(`COMMAND_FAILED`,`Unable to read screen size`);return{width:Number(t[1]),height:Number(t[2])}}async function uo(e,t,n){return t===`wait`?await fo(n.captureNodes,n.timeoutMs??1e4):t===`get`?vo((await _o(n.captureNodes))?.alert??null):await po(e,t,n.captureNodes)}async function fo(e,t){let n=Date.now(),i=await go(e,t);if(!i)throw new r(`COMMAND_FAILED`,`alert wait timed out`);return{kind:`alertWait`,platform:`android`,action:`wait`,alert:i.alert,waitedMs:Date.now()-n,...d(`Alert visible`)}}async function po(e,t,n){let i=await go(n,xe);if(!i)throw new r(`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=Fn(i.buttons,t);if(a)return await U(e,a.x,a.y),await mo(i.alert,t,n),yo(t,i.alert,a.label,{x:a.x,y:a.y});if(t===`dismiss`)return await qa(e),await mo(i.alert,t,n),yo(t,i.alert,`Back`);throw new r(`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 mo(e,t,n){let i=Date.now();for(;;){let a=await _o(n);if(!a||!ho(a.alert,e))return;if(Date.now()-i>=2e3)throw new r(`COMMAND_FAILED`,`alert ${t} 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 _(300)}}function ho(e,t){return e.title===t.title&&e.buttons.join(`\0`)===t.buttons.join(`\0`)}async function go(e,t){let n=Date.now();for(;Date.now()-n<t;){let t=await _o(e);if(t)return t;await _(300)}return null}async function _o(e){return Nn(await h(`snapshot_capture`,e,{backend:`android`,purpose:`alert`}))}function vo(e){return{kind:`alertStatus`,platform:`android`,action:`get`,alert:e,...d(e?`Alert visible`:`No alert visible`)}}function yo(e,t,n,r){return{kind:`alertHandled`,platform:`android`,action:e,handled:!0,alert:t,button:n,...r?{coordinates:r}:{},...d(`Alert ${e}ed`)}}const bo=`android.intent.category.LAUNCHER`,xo=`android.intent.category.DEFAULT`;async function So(e,t){await b(e,[`am`,`force-stop`,t])}async function Co(e,t,n=[bo]){for(let r of n){let n=await b(e,[`cmd`,`package`,`resolve-activity`,`--brief`,`-a`,`android.intent.action.MAIN`,`-c`,r,t],{allowFailure:!0});if(n.exitCode!==0)continue;let i=Zt(n.stdout);if(i)return i}return null}async function wo(e,t,n={}){let i=n.category??bo;if(n.activity!==void 0){await b(e,[`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,xo,`-c`,i,`-n`,Qt(t,n.activity)]);return}let a=await b(e,[`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,xo,`-c`,i,`-p`,t],{allowFailure:!0});if(a.exitCode===0&&!Gt(a.stdout,a.stderr))return;let o=await Co(e,t,[i]);if(!o)throw new r(`COMMAND_FAILED`,`Failed to resolve Android launch component for ${t}`,{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});await b(e,[`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,xo,`-c`,i,`-n`,o])}let To=null;function Eo(e){return`${e.PATH??``}::${e.AGENT_DEVICE_BUNDLETOOL_JAR??``}`}async function Do(e){let t=Eo(e);if(To?.key===t)return To.invocation;if(await Pe(`bundletool`)){let e={cmd:`bundletool`,prefixArgs:[]};return To={key:t,invocation:e},e}let n=await Ne(e.AGENT_DEVICE_BUNDLETOOL_JAR,`AGENT_DEVICE_BUNDLETOOL_JAR`);if(!n)throw new r(`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`,n]};return To={key:t,invocation:i},i}async function Oo(e,t,n){let r=await Do(n);await Fe(r.cmd,[...r.prefixArgs,...e],{signal:t})}function ko(e){return k.extname(e).toLowerCase()===`.aab`}async function Ao(e,t,n={}){let r=x(e),i=`universal`;if(r.installBundle){await r.installBundle(t,{mode:i,signal:n.signal});return}let a=v().files,o=await a.makeTempDirectory(`agent-device-aab-`),s=k.join(o,`bundle.apks`);try{await Oo([`build-apks`,`--bundle`,t,`--output`,s,`--mode`,i],n.signal,n.environment??v().environment),await Oo([`install-apks`,`--apks`,s,`--device-id`,e.id],n.signal,n.environment??v().environment)}finally{await a.remove(o,{recursive:!0,force:!0})}}async function jo(e,t,n={}){if(ko(t)){await Ao(e,t,n);return}await et(t,{device:e,replace:!0,signal:n.signal})}async function Mo(e,t,n={}){await Wt(e,async()=>{e.booted||await nn(e.id,void 0,n.signal),await jo(e,t,n)})}const No=[`mInputShown`,`mIsInputViewShown`,`isInputViewShown`,`mDecorViewVisible`,`mWindowVisible`,`mInShowWindow`],Po=new Map([[2,`number`],[3,`phone`],[4,`datetime`]]),Fo=new Set([32,208]),Io=new Set([128,224,144]);async function Lo(e){return await W(y(e))}async function W(e){let t=await b(e,[`dumpsys`,`input_method`],{allowFailure:!0});if(t.exitCode!==0)throw T(`Failed to query Android keyboard state`,t);return Bo(t.stdout)}async function Ro(e){return await zo(y(e))}async function zo(e){let t=await W(e),n=t,a=0;try{for(;n.visible&&a<2;)await b(e,[`input`,`keyevent`,`111`]),a+=1,await _(120),n=await W(e)}catch(e){throw i(e,a)}if(t.visible&&n.visible)throw new r(`UNSUPPORTED_OPERATION`,`Android keyboard dismiss is unavailable for the current IME without back navigation.`,{attempts:a,inputType:n.inputType,type:n.type,inputMethodPackage:n.inputMethodPackage,focusedPackage:n.focusedPackage,focusedResourceId:n.focusedResourceId,inputOwner:n.inputOwner});return{attempts:a,wasVisible:t.visible,dismissed:t.visible&&!n.visible,visible:n.visible,inputType:n.inputType,type:n.type,inputMethodPackage:n.inputMethodPackage,focusedPackage:n.focusedPackage,focusedResourceId:n.focusedResourceId,inputOwner:n.inputOwner}}function Bo(e){let t=Go(e)??Vo(e),n=Ho(e),r=Uo(e,/\bpackageName=([A-Za-z0-9_.]+)\b/g),i=Uo(e,/\b(?:resourceId|resource-id)=([^\s,}]+)/g),a=ce(e),o=de(r,i,a);return Wo(r,i,a),{visible:t??!1,inputType:n,type:n?Yo(n):void 0,inputMethodPackage:a,focusedPackage:r,focusedResourceId:i,inputOwner:o}}function Vo(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 Ho(e){let t=Uo(e,/\binputType=0x([0-9a-fA-F]+)\b/gi);return t?`0x${t.toLowerCase()}`:void 0}function Uo(e,t){let n;for(let r of e.matchAll(t))n=r[1];return n}function Wo(e,t,n){n||!se(e)&&!ae(t)||g({level:`warn`,phase:`android_input_ownership_fallback`,data:{focusedPackage:e,focusedResourceId:t}})}function Go(e){return qo(Ko(e,No))}function Ko(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 qo(e){if(e.size===0)return null;let t=Jo(e,[`mWindowVisible`,`mDecorViewVisible`,`mInShowWindow`]);if(t!==void 0)return t;let n=e.get(`mInputShown`);return n===void 0?Jo(e,[`mIsInputViewShown`,`isInputViewShown`])??null:n}function Jo(e,t){for(let n of t){let t=e.get(n);if(t!==void 0)return t}}function Yo(e){let t=Number.parseInt(e.replace(/^0x/i,``),16);if(Number.isNaN(t))return`unknown`;let n=t&15,r=Po.get(n);if(r)return r;if(n!==1)return`unknown`;let i=t&4080;return Fo.has(i)?`email`:Io.has(i)?`password`:`text`}async function Xo(e){return await Zo(y(e))}async function Zo(e){return ts(await es(e,[`cmd`,`clipboard`,`get`,`text`],`read`))}async function Qo(e,t){await $o(y(e),t)}async function $o(e,t){await es(e,[`cmd`,`clipboard`,`set`,`text`,t],`write`)}async function es(e,t,n){let{androidClipboardShellCommandUnavailableError:r,classifyAndroidClipboardShellResponse:i}=await import(`./clipboard-shell-response.js`),a=await b(e,t,{allowFailure:!0}),o=i(a);if(o===`no-shell-command`)throw r(n);if(o===`call-failed`)throw T(`Failed to ${n} Android clipboard text`,a);return a.stdout}function ts(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}async function ls(e,t){return await At(t.stateDir,e.id,async()=>{let n=k(e);if(!D.has(n))return{restored:!1,reason:`no-record`};D.delete(n);let r=await ds(v(e),e);return us(r.reason)&&await b().imeRecoveryMarkers.clear(t.stateDir,e.id),r})}function us(e){return e===`ok`||e===`helper-not-active`||e===`no-record`}async function ds(e,t){let n=t.id;if(D.has(k(t)))return{restored:!1,reason:`owned-by-live-session`};let r=await Ct(e);if(r.kind===`unreadable`)return x({level:`warn`,phase:`android_test_ime_restore_record_unreadable`,data:{device:n}}),{restored:!1,reason:`record-unreadable`};if(r.kind===`absent`)return{restored:!1,reason:`no-record`};let{previousIme:i}=r,a=await O(e);if(a!==`com.callstack.agentdevice.imehelper/.TestInputMethodService`&&!r.rebindDisplaced)return x({level:`debug`,phase:`android_test_ime_restore_skipped`,data:{device:n,currentIme:a,previousIme:i}}),{restored:!1,previousIme:i,reason:`helper-not-active`};await y(e,[`ime`,`set`,i],{allowFailure:!0,timeoutMs:1e4});let o=await O(e);return o===i?(await St(e).catch(()=>{}),await Ot(e).catch(()=>{}),x({phase:`android_test_ime_restored`,data:{device:n,previousIme:i}}),{restored:!0,previousIme:i,reason:`ok`}):(x({level:`warn`,phase:`android_test_ime_restore_failed`,data:{device:n,previousIme:i,afterIme:o}}),{restored:!1,previousIme:i,reason:`set-failed`})}async function fs(e){let t=b().imeRecoveryMarkers,n=await t.read(e.stateDir);if(n.length===0)return;let r;try{r=new Set(await e.listSerials())}catch(e){x({level:`debug`,phase:`android_test_ime_startup_scan_failed`,data:{error:i(e).message}});return}for(let a of n){if(!r.has(a))continue;let n={platform:`android`,id:a,name:a,kind:a.startsWith(`emulator-`)?`emulator`:`device`,booted:!0};try{await At(e.stateDir,a,async()=>{let r=await ds(v(n),n);r.restored&&x({level:`warn`,phase:`android_test_ime_orphan_restored`,data:{device:a,previousIme:r.previousIme}}),us(r.reason)&&await t.clear(e.stateDir,a)})}catch(e){x({level:`debug`,phase:`android_test_ime_orphan_restore_failed`,data:{device:a,error:i(e).message}})}}}async function ps(){b();try{return(await Be(it([`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 ms=2e3;async function hs(e,t,n=b().files){let r=e.ANDROID_HOME||e.ANDROID_SDK_ROOT,i=await Ms(r,n),a=await un(`adb`,[`version`]),o=a===void 0?void 0:ln(a);if(!a||!o)return js(r,i);let s=t===`win32`?void 0:Es(a);return s?Ds({windowsAdb:s,sdkRoot:r,versionLine:o}):Os({license:i,sdkRoot:r,versionLine:o})}async function gs(e,t){if(e.platform!==`android`)return[];let n=v(e,t.transportOverrides.androidAdb),r=[];return t.shouldProbeMetro&&r.push(await Ss(n,e.id,t.metroPort)),r.push(await _s(n,e)),r}async function _s(e,t){try{let n=await O(e),r=Mt(t);return n===await vs()&&!r?await ys(e,t,n):bs(t,n,r)}catch(e){return xs(e)}}async function vs(){try{return(await Ft()).manifest.serviceComponent}catch{return}}async function ys(e,t,n){let r=(await y(e,[`settings`,`get`,`secure`,Nt.previousIme],{allowFailure:!0,timeoutMs:ms})).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 bs(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 xs(e){let t=i(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 Ss(e,t,n){try{let r=await e([`reverse`,`--list`],{allowFailure:!0,timeoutMs:ms}),i=`tcp:${n} tcp:${n}`,a=r.stdout.includes(i);return{id:`android-reverse`,status:a?`pass`:`warn`,summary:a?`Android adb reverse exists for Metro port ${n}.`:`Android adb reverse is missing for Metro port ${n}.`,command:a?void 0:`adb -s ${t} reverse tcp:${n} tcp:${n}`,evidence:{stdout:r.stdout.trim()}}}catch(e){let t=i(e);return{id:`android-reverse`,status:`warn`,summary:`Could not inspect Android adb reverse mappings.`,hint:t.message,evidence:{code:t.code}}}}function Cs(e){return/^Installed as (.+)$/m.exec(e)?.[1]?.trim()}function ws(e){return/^(?:[A-Za-z]:[\\/]|\\\\)/.test(e)}function Ts(e){return/^Running on Windows\b/m.test(e)}function Es(e){let t=Cs(e);if(t&&ws(t))return{detectedVia:`installed-as-path`,adbPath:t};if(Ts(e))return{detectedVia:`running-on-line`,adbPath:void 0}}function Ds(e){let{adbPath:t,detectedVia:n}=e.windowsAdb;return{id:`toolchain`,status:`fail`,summary:`Android toolchain: adb on PATH${t?` (${t})`:``} is a Windows binary, which cannot use this host's file paths.`,hint:`adb must be a native binary for this host: install this host's Android platform-tools, put them first on PATH, and point ANDROID_HOME at an SDK on this host's filesystem. Under WSL that means a Linux SDK, not one under /mnt/<drive>.`,evidence:{reason:`android_adb_windows_binary_on_posix_host`,detectedVia:n,adbPath:t??null,adbVersion:e.versionLine,androidHome:e.sdkRoot??null}}}function Os(e){return{id:`toolchain`,status:ks(e),summary:e.versionLine?`Android toolchain: ${e.versionLine}; ${As(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 ks(e){return e.versionLine&&e.sdkRoot&&e.license!==`missing`?`pass`:`info`}function As(e){return e?`ANDROID_HOME/ANDROID_SDK_ROOT set`:`ANDROID_HOME unset`}function js(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 Ms(e,t){if(!e)return`unknown`;try{return await t.access(A.join(e,`licenses`,`android-sdk-license`)),`accepted`}catch{return`missing`}}function Ns(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:Fs(t.targetInput),actualInput:Fs(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 q(e){return e?e.password?!0:Ps(e.text):!1}function Ps(e){return e?Array.from(e).every(Is):!1}function Fs(e){if(!e)return null;let t=q(e);return{...e,text:t?null:e.text,...t?{textRedacted:!0}:{}}}function Is(e){return e===`•`||e===`*`||e===`●`}function Ls(e){return e.masked===!0||q(e.targetInput)||q(e.actualInput)}const Rs=new WeakMap;function zs(e,t){return t&&Rs.set(e,t),e}function Bs(e){return Rs.get(e)}function Vs(e){return e.clickable}function Hs(e){return e.focusable||e.focused===!0}function J(e){return Vs(e)||Hs(e)}function Us(e){let t=e.trim();return t?/^[\w.]+:id\/[\w.-]+$/i.test(t):!1}function Ws(e,t){return{raw:e,...t?{effectiveRect:t}:{}}}function Gs(e,t,n){if(!e)return;let r=Js(e);return t&&(r=qs(r,t)),n&&(r=qs(r,n)),r}function Ks(e){return{...e.raw,...e.effectiveRect?{rect:e.effectiveRect}:{rect:void 0},hittable:e.raw.hittable===!0&&ue(e.effectiveRect)?!0:void 0}}function qs(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 Js(e){return{x:e.x,y:e.y,width:Math.max(0,e.width),height:Math.max(0,e.height)}}function Ys(e,t){let n=new Set;return Xs(e,n,t),Qs(e,n,t),n}function Xs(e,t,n){for(let r of e.children){if(n?.check(`work`),r.visibleToUser===!1){t.add(r);continue}Xs(r,t,n)}}function Zs(e,t,n){return n?.check(`work`),e.children.filter(e=>!t.has(e)&&e.visibleToUser!==!1)}function Qs(e,t,n){let r=Zs(e,t,n).filter(ec);if(r.length<2)return;let i=r.filter(e=>tc(e)&&nc(e));if(i.length===0)return;let a=$s(i);for(let r of Zs(e,t,n))n?.check(`work`),tc(r)&&(nc(r)&&(a===void 0||r.windowLayer===a)||t.add(r))}function $s(e){let t=e.map(e=>e.windowLayer).filter(e=>e!==void 0);return t.length>0?Math.max(...t):void 0}function ec(e){return e.windowIndex!==void 0||e.windowType!==void 0}function tc(e){return e.windowType===1}function nc(e){return e.windowActive===!0||e.windowFocused===!0}function rc(e,t,n,r,i){let a=new Set(e.sourceNodes),o=ac(t,i),s=ic(o,n,oc(o,a,i),i);if(!s)return{nodes:[],sourceNodes:[]};let c=new Set(ac([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:le(d.map(t=>e.nodes[t]),u),sourceNodes:d.map(t=>e.sourceNodes[t])}}function ic(e,t,n,r){for(let i of e)if(r.check(`work`),oe(i,t)&&n.has(i))return i;return null}function ac(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 oc(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 sc(e,t,n,r,i){if(e.visibleToUser===!1)return!1;let a=cc(e);return t.interactiveOnly?lc(e,a,n,r,i):a.isStructural||a.isVisual?fc(e,a,r):!0}function cc(e){let t=mc(e.type),n=!!(e.label&&e.label.trim().length>0),r=!!(e.identifier&&e.identifier.trim().length>0);return{type:t,hasMeaningfulText:n&&!Us(e.label??``),hasMeaningfulId:r&&!Us(e.identifier??``),isStructural:hc(t),isVisual:t===`imageview`||t===`imagebutton`}}function lc(e,t,n,r,i){return dc(e)?!1:J(e)||se(t.type)&&r?!0:uc(t,n,r,i)}function uc(e,t,n,r){return!e.hasMeaningfulText&&!e.hasMeaningfulId||e.isVisual||e.isStructural&&!r&&!t?!1:t||n||r}function dc(e){return!!(e.rect&&(e.rect.width<=0||e.rect.height<=0))}function fc(e,t,n){return J(e)||t.hasMeaningfulText||t.hasMeaningfulId?!0:n}function pc(e){if(!e)return!1;let t=mc(e);return t.includes(`recyclerview`)||t.includes(`listview`)||t.includes(`gridview`)}function mc(e){return e?e.toLowerCase():``}function hc(e){let t=e.split(`.`).pop()??e;return t.includes(`layout`)||t===`viewgroup`||t===`view`}function gc(e,t,n,r){return{...Ws(e,t),...n?{clipsDescendants:!0}:{},...r?{windowRect:r}:{}}}const _c=`ANDROID_SNAPSHOT_PRESENTATION_FAILED`;var Y=class extends Error{code=_c;qualityReasonCode=`presentation-failed`;details;analysis;constructor(e,t,n){super(e),this.name=`AndroidSnapshotPresentationFailure`,this.details=t,this.analysis=n}};function vc(e){return e instanceof Y?e.code===_c:!!(e&&typeof e==`object`&&e.code===_c)}var yc=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()+wc()}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 Y(`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 Y(`Android snapshot presentation exceeded its cooperative deadline`,{phase:`deadline`,workUnits:this.workUnits,deadlineAtMs:this.deadlineAtMs,maxWorkUnits:t})}};function bc(e,t){return new yc(e??{},t)}function xc(e,t,n){let r=new Map;for(let i of e){n.check(`regular-invariant`);let e=Sc(i,r,t),a=i.effectiveRect;if(!a||!ue(a)){if(Ks(i).hittable===!0)throw new Y(`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&&!Cc(a,e))throw new Y(`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 Sc(e,t,n){let r=e.raw.parentIndex;return r===void 0?e.windowRect??n:t.get(r)??e.windowRect??n}function Cc(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 wc(){return 250}function Tc(e,t,n){let r=n.depth??1/0,i=ce(n.scope),a=Uc(e),o=bc(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=Ic(e,o),s.hidden=n.raw?new Set:Ys(e,o);for(let t of e.children)if(Dc(s,t,0),s.truncated)break;n.raw||xc(s.presentationNodes,s.viewport,o);let t=s.nodes,a=new Map(s.sourceNodes.map((e,t)=>[e,t])),{nodes:c,sourceNodes:l}=i?rc(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:Ec(s.sourceNodes)},analysis:s.analysis};return s.truncated?{...u,truncated:!0}:u}catch(e){throw vc(e)&&(e.analysis??=s.analysis),e}}function Ec(e){let t=new Map,n=new Map;for(let[r,i]of e.entries()){let e=Bs(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 Dc(e,t,n,r,i=!1,a=!1,o=!1,s,c){if(e.presentationBudget.check(`work`),Oc(e,t,n))return;let l=t.windowRect??s??e.viewport,u=kc(e,t,c,l),d=Ac(e,t,r,i,a,o,u,l),f=i||J(t),p=a||pc(t.type),m=jc(e,t,u,c);Mc(e,t,n,d,f,p,o||fn(t.identifier),l,m)}function Oc(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 kc(e,t,n,r){return e.options.raw?t.rect:Gs(t.rect,r,n)}function Ac(e,t,n,r,i,a,o,s){return!e.options.raw&&!sc(t,e.options,r,zc(e,t),i)?n:Nc(e,t,n,a||fn(t.identifier),o,s)}function jc(e,t,n,r){return e.options.raw||!Lc(t)?r:n}function Mc(e,t,n,r,i,a,o,s,c){for(let l of t.children)if(Dc(e,l,n+1,r,i,a,o,s,c),e.truncated)return}function Nc(e,t,n,r,i,a){let o=e.nodes.length;return e.sourceNodes.push(t),Fc(e,t,Pc(e,t,n,r),i,a),o}function Pc(e,t,n,r){return{index:e.nodes.length,type:t.type??void 0,label:t.label??void 0,value:t.value??void 0,...t.passiveFacts,identifier:t.identifier??void 0,bundleId:t.packageName??void 0,rect:t.rect,focused:t.focused,visibleToUser:t.visibleToUser,hittable:J(t)||void 0,depth:Rc(e.nodes,n),parentIndex:n,...Bc(t,e.hidden),...r?{systemChrome:!0}:{}}}function Fc(e,t,n,r,i){let a=gc(n,r,!e.options.raw&&Lc(t),i);e.presentationNodes.push(a),e.nodes.push(e.options.raw?a.raw:Ks(a))}function Ic(e,t){let n=[],r=[...e.children];for(;r.length>0;){t.check(`work`);let e=r.pop();ue(e.windowRect)&&n.push(e.windowRect),r.push(...e.children)}return de(n)??void 0}function Lc(e){return e.scrollable===!0&&se(e.type)}function Rc(e,t){return t===void 0?0:(e[t]?.depth??-1)+1}function zc(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&&(J(n)||zc(e,n)))return e.interactiveDescendantMemo.set(t,!0),!0;return e.interactiveDescendantMemo.set(t,!1),!1}function Bc(e,t){return Vc(e,t)?{...e.canScrollBackward?{hiddenContentAbove:!0}:{},...e.canScrollForward?{hiddenContentBelow:!0}:{}}:{}}function Vc(e,t){if(!e.scrollable||!se(e.type)||`${e.type??``}`.toLowerCase().includes(`horizontalscrollview`))return!1;let n=Hc(e,t);return!(n&&n.horizontal>n.vertical&&n.horizontal>16)}function Hc(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 Uc(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 Wc(){let e=[],t=()=>e.at(-1)===!0;return{open(n,r){let i=t()||fn(n);return r||e.push(i),i},close(){e.pop()}}}function*Gc(e){let t=/<node\b[^>]*>|<\/node>/g,n=Wc(),r=t.exec(e);for(;r;){let i=r[0];if(i.startsWith(`</node`))n.close();else{let e=Kc(i);yield n.open(e.resourceId,i.endsWith(`/>`))?{...e,systemChrome:!0}:e}r=t.exec(e)}}function Kc(e){let t=qc(e),n=pn(t.bounds);return{...t,...n?{rect:n}:{}}}function qc(e){let t=Jc(e),n=e=>nl(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=pn(n(t));return r===void 0?{}:{[e]:r}},s=(e,t)=>{let r=n(t);return r===null||r===``?{}:{[e]:r}},c=(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`),...c(`editable`,`editable`),...a(`selectionStart`,`selection-start`),...a(`selectionEnd`,`selection-end`),...c(`hintShowing`,`hint-showing`),...s(`hint`,`hint`),...c(`visibleToUser`,`visible-to-user`),...c(`selected`,`selected`),...c(`heading`,`heading`),...s(`roleDescription`,`role-description`),...c(`checked`,`checked`),...a(`drawingOrder`,`drawing-order`),...c(`scrollable`,`scrollable`),...c(`canScrollForward`,`can-scroll-forward`),...c(`canScrollBackward`,`can-scroll-backward`),...a(`windowIndex`,`window-index`),...a(`windowType`,`window-type`),...a(`windowLayer`,`window-layer`),...c(`windowActive`,`window-active`),...c(`windowFocused`,`window-focused`),...o(`windowRect`,`window-bounds`),...c(`windowRegionRect`,`window-region-rect`)}}function Jc(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=Yc(e,i,r);if(!n)break;t.set(n.name,n.value),i=n.nextCursor}return t}function Yc(e,t,n){if(t=Zc(e,t,n),t>=n||Qc(e[t]))return;let r=t;t=Xc(e,t,n);let i=e.slice(r,t);if(t=Zc(e,t,n),!i||e[t]!==`=`)return;t=Zc(e,t+1,n);let a=e[t];if(!$c(a))return;let o=t+1,s=e.indexOf(a,o);if(!(s<0||s>=n))return{name:i,value:mn(e.slice(o,s)),nextCursor:s+1}}function Xc(e,t,n){for(;t<n&&!tl(e[t]??``);)t+=1;return t}function Zc(e,t,n){for(;t<n&&el(e[t]??``);)t+=1;return t}function Qc(e){return e===`/`||e===`>`}function $c(e){return e===`"`||e===`'`}function el(e){return e===` `||e===`
12
- `||e===`\r`||e===` `}function tl(e){return e===`=`||e===`/`||e===`>`||el(e)}function nl(e,t){return e.get(t)??null}function rl(e){let t={type:null,label:null,value:null,passiveFacts:{},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=Kc(t),o=n.at(-1),s=il(a,o.depth+1,o);o.children.push(s),t.endsWith(`/>`)||n.push(s),i=r.exec(e)}return t}function il(e,t,n){let r=e.text||e.desc;return zs({type:e.className,label:r,value:e.text,passiveFacts:{contentDescription:e.desc&&e.desc!==r?e.desc:void 0,enabled:e.enabled,selected:e.selected,heading:e.heading,roleDescription:e.roleDescription,checked:e.checked,editable:e.editable,password:e.password,hintShowing:e.hintShowing,placeholder:e.hint,selectionStart:e.selectionStart,selectionEnd:e.selectionEnd},identifier:e.resourceId,packageName:e.packageName,rect:e.rect,focused:e.focused,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,windowRegionRect:e.windowRegionRect,depth:t,parentIndex:void 0,children:[]},e.drawingOrder===void 0?void 0:{parent:n,order:e.drawingOrder})}function al(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 ol=new Set([`android`,`com.android.systemui`]);function sl(e,t,n={}){if(t.backend!==`android-helper`)return{outcome:`ok`};let r=vl(e,n.foregroundAppPackage);return ul(r,t)?cl(r,t,`empty-helper-output`,`Android snapshot helper returned no accessibility nodes`):gl(r)?{outcome:`ok`}:ll(r)?{outcome:`system-surface-only`}:dl(r)?{outcome:`ok`}:fl(r)?cl(r,t,`content-poor-app-window`,`Android snapshot helper returned insufficient foreground app content`):pl(r)||ml(r,t)?cl(r,t,`content-poor-app-window`,`Android snapshot helper returned insufficient application window content`):hl(r)?cl(r,t,`system-window-only`,`Android snapshot helper returned only non-application windows`):{outcome:`ok`}}function cl(e,t,n,r){return{outcome:`unusable`,decision:_l(e,t,n,r)}}function ll(e){return e.windowRootCount>0&&e.applicationWindowRootCount===0&&e.activeSystemSurfaceMeaningfulNodeCount>=3}function ul(e,t){return e.nodeCount===0||t.nodeCount===0||t.rootPresent===!1}function dl(e){return fl(e)&&e.inputMethodMeaningfulNodeCount>=2}function fl(e){let t=e.foregroundAppMeaningfulNodeCount;return t===void 0?!1:t===0?e.applicationMeaningfulNodeCount<2:t<2&&e.meaningfulNodeCount>t}function pl(e){return e.foregroundAppMeaningfulNodeCount===void 0&&e.applicationWindowRootCount>0&&e.applicationMeaningfulNodeCount<2}function ml(e,t){return e.foregroundAppMeaningfulNodeCount===void 0&&e.windowRootCount===0&&(t.windowCount??0)>1&&e.nonSystemMeaningfulNodeCount<2}function hl(e){return e.windowRootCount>0&&e.applicationWindowRootCount===0||e.windowRootCount===0&&e.nodeCount>0&&e.systemUiNodeCount===e.nodeCount}function gl(e){return e.hasAlertButtonIdentifier&&e.hasAlertContentIdentifier}function _l(e,t,n,r){return{reason:n,failureReason:r,diagnostics:Ml(e,t)}}function vl(e,t){let n=yl(t);for(let t of Gc(e))bl(n,t);return Dl(n)}function yl(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 bl(e,t){e.nodeCount+=1,jl(t.packageName)&&(e.systemUiNodeCount+=1),t.visibleToUser!==!1&&xl(e,t.resourceId),Sl(e,t),Cl(e,t)}function xl(e,t){let n=Mn(t);n===`button`&&(e.hasAlertButtonIdentifier=!0),n===`content`&&(e.hasAlertContentIdentifier=!0)}function Sl(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 Cl(e,t){Ol(t)&&(e.meaningfulNodeCount+=1,wl(e,t),El(e,t))}function wl(e,t){e.currentWindowType===1&&!Al(t.packageName)&&(e.applicationMeaningfulNodeCount+=1),Tl(e)&&!dn(t)&&(e.activeSystemSurfaceMeaningfulNodeCount+=1)}function Tl(e){return e.currentWindowType!==void 0&&e.currentWindowType!==1&&e.currentWindowActiveOrFocused===!0}function El(e,t){Al(t.packageName)||(e.nonSystemMeaningfulNodeCount+=1),re({packageName:t.packageName,resourceId:t.resourceId})&&(e.inputMethodMeaningfulNodeCount+=1),e.foregroundAppPackage!==void 0&&t.packageName===e.foregroundAppPackage&&(e.foregroundAppMeaningfulNodeCount=(e.foregroundAppMeaningfulNodeCount??0)+1)}function Dl(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 Ol(e){return e.visibleToUser===!1?!1:kl(e.text)||kl(e.desc)||kl(e.resourceId)}function kl(e){return e!==null&&e.trim()!==``}function Al(e){return e===null||ol.has(e)}function jl(e){return e!==null&&ol.has(e)}function Ml(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 Nl(e){let t=await U(e.deviceKey,{resetRuntime:!0,signal:e.signal,cause:e.cause});e.signal?.throwIfAborted(),t||await Pl(e.adb,e.packageName)}async function Pl(e,t){await Si({adb:e,packageName:t}),await _(150),g({level:`debug`,phase:`android_snapshot_helper_runtime_reset`,data:{packageName:t}})}const Fl=Symbol(`androidSnapshotCaptureEvidence`);function Il(e,t){return Object.defineProperty(e,Fl,{value:t}),e}function Ll(e){return me({x:0,y:0,width:e.displayWidth??NaN,height:e.displayHeight??NaN})}function Rl(e){let t={...e,backend:`android`,producer:`android-uiautomator`},n=e[Fl];return ae(t,n.clickability),n.occlusionContext&&m(t,n.occlusionContext),t}async function zl(e,t={}){let n=S(e,t.helperAdb).exec;return(await ql(e,t,n)).xml}async function Bl(e,t={}){let n=S(e,t.helperAdb).exec,r=await ql(e,t,n),i=Ll(r.helperMetadata),a=r.xml,o=rl(a),s=Ul(r.metadata,o),c=vu(o,r.metadata),l={...t,androidPresentation:{...t.androidPresentation,deadlineAtMs:t.androidPresentation?.deadlineAtMs??Date.now()+250}};try{let e=Tc(o,void 0,l),n=Hl(e.truncated,r.metadata);t.interactiveOnly&&t.includeHiddenContentHints!==!1&&Kl({options:l,tree:o,xml:a,interactiveSnapshot:e});let{sourceNodes:u,occlusionContext:d,...f}=e;return Il({...f,...Gl(n),androidSnapshot:s,quality:{state:`healthy`,backend:`android-helper`},keyboard:c,...i?{viewport:i}:{}},{clickability:al(e),occlusionContext:d})}catch(e){if(!vc(e))throw e;return Vl({failure:e,androidSnapshot:s,keyboard:c,...i?{viewport:i}:{}})}}function Vl(e){return Il({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},keyboard:e.keyboard,...e.viewport?{viewport:e.viewport}:{}},{clickability:{kind:`exact`,provider:`android-helper`,clickableByNodeIndex:new Map}})}function Hl(e,t){return e===!0||t.helperTruncated===!0||e}function Ul(e,t){return Wl(t)===!1?{...e,occlusionScanUnavailable:!0}:e}function Wl(e){let t=[...e.children];if(t.length!==0){for(;t.length>0;){let e=t.pop();if(Bs(e)!==void 0)return!0;t.push(...e.children)}return!1}}function Gl(e){return e===!0?{truncated:!0}:{}}function Kl(e){if(gu(e.interactiveSnapshot.nodes).size>0||hu(e.xml))return;let t=Tc(e.tree,void 0,{...e.options,interactiveOnly:!1});_u(Oe(l(t.nodes)),t,e.interactiveSnapshot)}async function ql(e,t,n){let r=S(e,t.helperAdb),i=await h(`android_snapshot_helper_artifact_resolution`,async()=>await pu(t.helperArtifact??r.snapshotHelperArtifact));if(i.artifact)return await Jl(e,t,n,i.artifact);throw g({level:`error`,phase:`android_snapshot_helper_unavailable`,data:{reason:i.errorReason??`artifact_not_found`}}),mu(i.errorReason)}async function Jl(e,t,n,r){let i=ci(e),a=Zl(t,i);try{return await Yl({options:t,adb:n,adbProvider:S(e,t.helperAdb),artifact:r,helperDeviceKey:i})}finally{a&&await U(i)}}async function Yl(e){let{options:t}=e,n=Xl(t),r=async(n,r)=>await iu({contentRecovery:n,attempts:r,helperDeviceKey:e.helperDeviceKey,artifact:e.artifact,adb:e.adb,signal:t.signal,retireHelper:t.transient===void 0}),i;for(let a=0;;a+=1){if(i&&(await ru(t.signal),Date.now()>=n))return await r(i,a);let o=await nu({...e,attempt:a,previousContentReason:i?.reason});if(o.outcome===`captured`)return o.capture;if(a+1>=3||Date.now()>=n)return await r(o.decision,a+1);i=o.decision}}function Xl(e){return Math.min(Date.now()+1e4,e.transient?.settleBy??1/0)}function Zl(e,t){return e.transient?la(t)===void 0:e.helperSessionScope!==`daemon-session`}function Ql(e){return e.transient?`current-only`:e.helperInstallPolicy??`missing-or-outdated`}async function $l(e,t,n,r,i){let a=await h(`android_snapshot_helper_install`,async()=>await Rr({adb:t,adbProvider:n,artifact:r,deviceKey:i,installPolicy:Ql(e),timeoutMs:3e4,signal:e.signal}),{packageName:r.manifest.packageName,versionCode:r.manifest.versionCode,installPolicy:Ql(e)});return g({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 eu(e){let{signal:t,adb:n,adbProvider:r,artifact:a,helperDeviceKey:o}=e,s=Ti({adb:n,adbProvider:r,artifact:a,deviceKey:o,signal:t});try{let e=await h(`android_snapshot_helper_session_capture`,async()=>await Ta(s),{packageName:a.manifest.packageName,version:a.manifest.version,timeoutMs:Sr});if(e)return e}catch(e){if(t?.throwIfAborted(),fi(e))throw e;g({level:`warn`,phase:`android_snapshot_helper_session_fallback`,data:{reason:i(e).message}}),await Pl(n,a.manifest.packageName)}return await h(`android_snapshot_helper_capture`,async()=>await wi(s),{packageName:a.manifest.packageName,version:a.manifest.version,timeoutMs:Sr,commandTimeoutMs:Cr})}function tu(e,t,n){return{xml:e.xml,helperMetadata:e.metadata,metadata:{backend:`android-helper`,pixelDensity:e.metadata.pixelDensity,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,missingRootWindowTypes:e.metadata.missingRootWindowTypes,nodeCount:e.metadata.nodeCount,helperTruncated:e.metadata.truncated,elapsedMs:e.metadata.elapsedMs}}}async function nu(e){let{options:t,adb:n,adbProvider:r,artifact:i,helperDeviceKey:a,attempt:o}=e,s;try{let e=await $l(t,n,r,i,a);e.installed&&await U(a),s=tu(await eu({signal:t.signal,adb:n,adbProvider:r,artifact:i,helperDeviceKey:a}),i,e.reason)}catch(e){if(t.signal?.throwIfAborted(),Nr(e))throw e;return{outcome:`captured`,capture:await ou({error:e,helperDeviceKey:a,artifact:i,adb:n})}}let c=sl(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&&g({phase:`android_snapshot_helper_content_recaptured`,data:{attempts:o+1,recoveredFromReason:e.previousContentReason}}),{outcome:`captured`,capture:{xml:s.xml,helperMetadata:s.helperMetadata,metadata:l?{...s.metadata,systemSurfaceOnly:!0}:s.metadata}}}async function ru(e){e?.throwIfAborted(),await _(250),e?.throwIfAborted()}async function iu(e){throw g({level:`error`,phase:`android_snapshot_helper_content_invalid`,data:{reason:e.contentRecovery.reason,failureReason:e.contentRecovery.failureReason,attempts:e.attempts,...e.contentRecovery.diagnostics}}),e.retireHelper&&await Nl({adb:e.adb,deviceKey:e.helperDeviceKey,packageName:e.artifact.manifest.packageName,signal:e.signal,cause:e.contentRecovery.failureReason}),au(e.contentRecovery,e.attempts)}function au(e,t){return new a(`COMMAND_FAILED`,e.failureReason,{...e.diagnostics,androidSnapshotHelperFailureReason:e.reason,attempts:t,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 ou(e){let t=su(e.error);throw g({level:`error`,phase:`android_snapshot_helper_failed`,data:{reason:t}}),await U(e.helperDeviceKey),await Pl(e.adb,e.artifact.manifest.packageName),jr({deviceKey:e.helperDeviceKey,packageName:e.artifact.manifest.packageName,versionCode:e.artifact.manifest.versionCode}),cu(e.error,t)}function su(e){let t=i(e),n=fu(t.details?.helper);if(n&&n!==t.message)return`${t.message}: ${n}`;if(n)return n;let r=(typeof t.details?.stderr==`string`?t.details.stderr.trim():``).split(/\r?\n/).find(e=>e.trim());return r?`${t.message}: ${r}`:t.message}function cu(e,t){let n=i(e),r=lu(n);return new a(s(n.code),`Android snapshot helper failed: ${t}`,{...n.details,...du(n),androidSnapshotHelperFailureReason:t,...r?{androidCaptureFailureReason:r}:{},hint:uu(n,r)},e)}function lu(e){return Lt(e)}function uu(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 du(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 fu(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 pu(e){if(e)return{artifact:e};let t=Le(),n=A.join(Re(),`android`,`snapshot-helper`,`dist`),r=A.join(n,`agent-device-android-snapshot-helper-${t}.manifest.json`);try{await b().files.access(r)}catch{return{}}try{let e=wr(JSON.parse(await b().files.readText(r))),t=A.join(n,e.assetName??`agent-device-android-snapshot-helper-${e.version}.apk`);return await b().files.access(t),{artifact:{apkPath:t,manifest:e}}}catch(e){return{errorReason:i(e).message}}}function mu(e){let t=e??`the bundled helper artifact was not found`;return new a(`COMMAND_FAILED`,`Android snapshot helper is unavailable: ${t}`,{androidSnapshotHelperFailureReason:t,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 hu(e){return e.includes(` can-scroll-forward=`)||e.includes(` can-scroll-backward=`)}function gu(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 _u(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))}}function vu(e,t){let n=e.children,r=n.filter(e=>e.windowType===2),i=[];for(let{windowRect:e,windowRegionRect:t}of r){if(t===!1)return{kind:`unmeasurable`,reason:`window-region-not-rectangular`};if(ue(e))i.push(e);else if(!yu(e))return{kind:`unmeasurable`,reason:`window-bounds-unavailable`}}return t.missingRootWindowTypes?.includes(2)?{kind:`unmeasurable`,reason:`window-root-unavailable`}:i.length>0?{kind:`visible`,frame:fe(i)}:t.captureMode!==`interactive-windows`||n.some(e=>e.windowType===void 0)?{kind:`unmeasurable`,reason:`window-list-unavailable`}:t.helperTruncated===!0?{kind:`unmeasurable`,reason:`capture-truncated`}:{kind:`absent`}}function yu(e){return!e||![e.x,e.y,e.width,e.height].every(Number.isFinite)?!1:e.width===0||e.height===0}const bu=Object.freeze({now:()=>Date.now(),sleep:_});async function xu(e,t,n,r,i={},a=bu){let o=await Vu(e),s=a.now()+1500,c=null;for(;;){let l=await ju(e,t,n,r,o,i);if(l.reason===`ime_capture`)return l;let u=s-a.now();if(l.ok&&c?.ok||u<=0)return l;c=l,await a.sleep(Math.min(150,u))}}async function Su(e,t,n,r={}){return Ou(await zl(e,r),t,n)}async function Cu(e,t,n,r){let i=await Vu(e);return Mu(await zl(e,r),t,n,i).targetInput}async function wu(e,t,n,r={}){try{return await Cu(e,t,n,r)}catch(e){return g({level:`warn`,phase:`android_fill_pre_action_target_capture_failed`,data:{error:e instanceof Error?e.message:String(e)}}),null}}function X(e,t,n){if(n?.ok)return;let r=n?Eu(e,t,n):null;if(r)return r;throw u(new a(`COMMAND_FAILED`,ku(n),Au(e,n)),`unknown`)}function Tu(e,t){if(e.ok)return!1;let n=e.actualInput;return n&&(n.hintShowing===!0||n.text===null)?!0:t?.text!=null&&e.actual===t.text}function Eu(e,t,n){let r=n.targetInput,i=n.actualInput;if(e.length===0||n.reason===`ime_capture`||Tu(n,t)||!t||!r||!i||q(t)||q(r)||q(i)||!qu(t,r)||!qu(t,i))return null;let a=Ju(t);return g({level:`warn`,phase:`android_fill_verification_unconfirmed`,data:{target:a}}),{verification:`unconfirmed`,requested:e,before:t.text,after:n.actual,target:a}}function Du(e,t,n,r,i={}){let a=Mu(e,t,n,i);return Nu(a)?{ok:!1,actual:a.actualInput?.text??null,reason:`ime_capture`,targetInput:a.targetInput,actualInput:a.actualInput}:Pu(a,r)??Fu(a,r)}function Ou(e,t,n){return Mu(e,t,n).targetInput?.text??null}function ku(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 Au(e,t){let n=Ns(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 ju(e,t,n,r,i,a){return Du(await zl(e,a),t,n,r,i)}function Mu(e,t,n,r={}){let i={focusedEdit:null,editAtPoint:null,anyAtPoint:null};for(let a of Gc(e)){let e=Bu(a,r);e&&Hu(i,e,t,n)}return Wu(i)}function Nu(e){let{targetInput:t,actualInput:n}=e;return!t||!n||n===t?!1:n.inputMethodOwned&&!t.inputMethodOwned}function Pu(e,t){let n=e.actualInput;if(!n||!Ku(n))return null;let r=n.text??null,i=Array.from(Iu(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 Fu(e,t){let n=e.actualInput;return{ok:n!==null&&Lu(Iu(n),t),actual:n?.text??null,reason:`text_mismatch`,targetInput:e.targetInput,actualInput:n}}function Iu(e){return e.hintShowing?``:e.text??``}function Lu(e,t){if(e===t)return!0;if(t.length===0)return!1;let n=Ru(e),r=Ru(t);return!n||!r?!1:!!(n===r||zu(n,r))}function Ru(e){return e.replaceAll(/\s+/g,` `).trim()}function zu(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 Bu(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:re({packageName:e.packageName,resourceId:e.resourceId,activeInputMethodPackage:t.activeInputMethodPackage}),area:r,editText:Gu(e.className??``),hintShowing:e.hintShowing===!0,placeholder:e.hint??null}}async function Vu(e){try{return{activeInputMethodPackage:(await Wo(e)).inputMethodPackage}}catch(e){return g({level:`warn`,phase:`android_fill_verification_input_method_probe_failed`,data:{error:e instanceof Error?e.message:String(e)}}),{}}}function Hu(e,t,n,r){let i=pe(t.rect,n,r);if(i&&t.editText&&(e.editAtPoint=Uu(e.editAtPoint,t)),t.focused&&t.editText){e.focusedEdit=Uu(e.focusedEdit,t);return}i&&t.text&&(e.anyAtPoint=Uu(e.anyAtPoint,t))}function Uu(e,t){return e&&e.area<t.area?e:t}function Wu(e){let t=e.editAtPoint??e.anyAtPoint;return{targetInput:t,actualInput:(e.focusedEdit?.text?e.focusedEdit:null)??t}}function Gu(e){let t=e.toLowerCase();return t.includes(`edittext`)||t.includes(`textfield`)}function Ku(e){return q(e)}function qu(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 Ju(e){return{resourceId:e.resourceId,className:e.className,packageName:e.packageName,rect:e.rect}}async function Yu(e,t){return await hn(t.stateDir),await At(t.stateDir,e.id,async()=>await Zu(e,t))}function Xu(e){let t=r(e).details?.hint;return{outcome:`helper-unavailable`,reason:i(e).message,...typeof t==`string`?{hint:t}:{}}}async function Zu(e,t){let n=b().imeRecoveryMarkers,r=v(e),i=S(e),a=k(e),o;try{o=await _t(i),await yt({adb:r,adbProvider:i,artifact:o,deviceKey:a})}catch(e){return Xu(e)}let{manifest:s}=o,c=await O(r);if(c===s.serviceComponent)return await Qu(e,s,t.stateDir);let l=await Ct(r);if(l.kind===`unreadable`)return x({level:`warn`,phase:`android_test_ime_record_unreadable`,data:{device:e.id}}),{outcome:`settled`,activated:!1,alreadyActive:!1,persistFailed:!0,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName};let{previousIme:u,priorPersistedIme:d}=$u(l,c);if(!await jt(r,u))return await wt(r,d,e.id),x({level:`warn`,phase:`android_test_ime_persist_failed`,data:{device:e.id,previousIme:u}}),{outcome:`settled`,activated:!1,alreadyActive:!1,persistFailed:!0,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName};let f=(await n.read(t.stateDir)).includes(e.id);if(!await n.write(t.stateDir,e.id))return await wt(r,d,e.id),x({level:`warn`,phase:`android_test_ime_marker_persist_failed`,data:{device:e.id,previousIme:u}}),{outcome:`settled`,activated:!1,alreadyActive:!1,persistFailed:!0,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName};await y(r,[`ime`,`enable`,s.serviceComponent],{allowFailure:!0,timeoutMs:1e4});let p=await y(r,[`ime`,`set`,s.serviceComponent],{allowFailure:!0,timeoutMs:1e4}),m=await O(r);if(m!==s.serviceComponent)return D.delete(a),await wt(r,d,e.id),f||await n.clear(t.stateDir,e.id),x({level:`warn`,phase:`android_test_ime_activate_failed`,data:{device:e.id,activeIme:m,stderr:p.stderr.trim()}}),{outcome:`settled`,activated:!1,alreadyActive:!1,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName};let ee={stateDir:t.stateDir,rebindUnconfirmed:l.rebindDisplaced};return D.set(a,ee),l.rebindDisplaced&&(ee.rebindUnconfirmed=!await Ot(r)),x({phase:`android_test_ime_activated`,data:{device:e.id,previousIme:u}}),{outcome:`settled`,activated:!0,alreadyActive:!1,previousIme:u,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName}}async function Qu(e,t,n){let r=v(e),i=k(e),a=await b().imeRecoveryMarkers.write(n,e.id),o=await Ct(r);if(a){let e=o.kind===`unreadable`||o.rebindDisplaced;D.set(i,{stateDir:n,rebindUnconfirmed:e})}let s=o.kind===`owned`?o.previousIme:void 0;return{outcome:`settled`,activated:!1,alreadyActive:!0,...a?{}:{persistFailed:!0},previousIme:s,helperServiceComponent:t.serviceComponent,helperPackageName:t.packageName}}function $u(e,t){return e.kind===`absent`?{previousIme:t,priorPersistedIme:void 0}:{previousIme:e.rebindDisplaced?e.previousIme:t,priorPersistedIme:e.previousIme}}function ed(e){return A.join(e,`android-test-ime-pending`)}function td(e,t){return A.join(ed(e),encodeURIComponent(t))}async function nd(e,t){let n=b().files,r,a=!1;try{let i=ed(e);if(r=td(e,t),await n.ensureDirectory(i),(await ad(r))?.serial===t)return!0;let o={version:1,serial:t};if(await n.writeAtomicText(r,`${JSON.stringify(o)}\n`,384),a=!0,(await ad(r))?.serial!==t)throw Error(`Android test IME marker read-back did not match the requested device.`);return!0}catch(o){return a&&r&&await n.remove(r,{force:!0}).catch(()=>{}),g({level:`debug`,phase:`android_test_ime_marker_write_failed`,data:{stateDir:e,serial:t,error:i(o).message}}),!1}}async function rd(e,t){await b().files.remove(td(e,t),{force:!0}).catch(()=>{})}async function id(e){let t=b().files,n;try{n=await t.readDirectory(ed(e))}catch{return[]}let r=[];for(let t of n)try{let n=A.join(ed(e),t),i=await ad(n);i&&td(e,i.serial)===n&&r.push(i.serial)}catch{}return[...new Set(r)].sort()}async function ad(e){try{return od(await b().files.readText(e))}catch{return}}function od(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 sd=new vn(`utf-16le`);let cd;async function ld(e,t){for(let n of[`AndroidManifest.xml`,`base/manifest/AndroidManifest.xml`]){let r=await ud(e,n,t);if(!r)continue;let i=dd(r);if(i)return i}return await Od(e,t)}async function ud(e,t,n){try{let r=await Ne(`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 dd(e){return e.subarray(0,Math.min(e.length,128)).toString(`utf8`).trimStart().startsWith(`<`)?fd(e.toString(`utf8`)):pd(e)}function fd(e){return e.match(/<manifest\b[^>]*\bpackage\s*=\s*["']([^"']+)["']/i)?.[1]}function pd(e){let t=gd(e);if(!t)return;let n;for(let r=t.treeHeaderSize;r+8<=t.dataEnd;){let i=md(e,r,t.dataEnd);if(!i)return;if(i.type===1){if(n=Sd(e.subarray(r,r+i.chunkSize)),!n)return}else if(n){let t=hd(e,i,r,n);if(t)return t}r+=i.chunkSize}}function md(e,t,n){let r=e.readUInt16LE(t),i=e.readUInt16LE(t+2),a=e.readUInt32LE(t+4);if(!(!_d(i,a)||t+a>n))return{type:r,headerSize:i,chunkSize:a}}function hd(e,t,n,r){if(t.type===258)return vd(e,n,n+t.chunkSize,t.headerSize,r)}function gd(e){if(e.length<8||e.readUInt16LE(0)!==3)return;let t=e.readUInt16LE(2),n=e.readUInt32LE(4);if(!(!_d(t,n)||n>e.length))return{treeHeaderSize:t,dataEnd:n}}function _d(e,t){return e>=8&&e%4==0&&t%4==0&&e<=t}function vd(e,t,n,r,i){if(r<16)return;let a=t+r;if(a+20>n||i[e.readUInt32LE(a+4)]!==`manifest`)return;let o=yd(e,a,n);return o?bd(e,i,o):void 0}function yd(e,t,n){let r=e.readUInt16LE(t+8),i=e.readUInt16LE(t+10),a=e.readUInt16LE(t+12);if(!(i<20||r<20)&&!(r+i*a>n-t))return{firstOffset:t+r,stride:i,count:a}}function bd(e,t,n){for(let r=0;r<n.count;r+=1){let i=n.firstOffset+r*n.stride;if(t[e.readUInt32LE(i+4)]===`package`)return xd(e,t,i)}}function xd(e,t,n){let r=e.readUInt32LE(n+8);if(r!==4294967295)return t[r];let i=e.readUInt8(n+15),a=e.readUInt32LE(n+16);return i===3?t[a]:void 0}function Sd(e){let t=e.readUInt16LE(2),n=e.readUInt32LE(4);if(!_d(t,n)||t<28||n>e.length)return;let r=e.readUInt32LE(8),i=e.readUInt32LE(16),a=e.readUInt32LE(20),o=!!(i&256),s=t;if(s+r*4>n||a<s+r*4||a>=n)return;let c=[];for(let t=0;t<r;t+=1){let n=a+e.readUInt32LE(s+t*4);c.push(o?Cd(e,n):wd(e,n))}return c}function Cd(e,t){let n=Ed(e,t);if(!n)return;let r=Ed(e,t+n.bytes);if(!r)return;let i=t+n.bytes+r.bytes;return Td(e,i,r.value)?e.subarray(i,i+r.value).toString(`utf8`):void 0}function wd(e,t){let n=Dd(e,t);if(!n)return;let r=t+n.bytes;return Td(e,r,n.value*2)?sd.decode(e.subarray(r,r+n.value*2)):void 0}function Td(e,t,n){return Number.isSafeInteger(t)&&Number.isSafeInteger(n)&&t+n<=e.length}function Ed(e,t){if(t+1>e.length)return;let n=e.readUInt8(t);if(!(n&128))return{value:n,bytes:1};if(!(t+2>e.length))return{value:(n&127)<<8|e.readUInt8(t+1),bytes:2}}function Dd(e,t){if(t+2>e.length)return;let n=e.readUInt16LE(t);if(!(n&32768))return{value:n,bytes:2};if(!(t+4>e.length))return{value:(n&32767)<<16|e.readUInt16LE(t+2),bytes:4}}async function Od(e,t){t?.throwIfAborted();let n=await kd();if(!n)return;let r=await Ne(n,[`dump`,`badging`,e],{allowFailure:!0,signal:t});if(r.exitCode===0)return r.stdout.match(/package:\s+name='([^']+)'/)?.[1]}async function kd(){if(cd!==void 0)return cd??void 0;try{let e=b().files,{hostPlatform:t}=await import(`./process.js`).then(e=>e.t);for(let n of Kt(void 0,t())){let t=A.join(n,`build-tools`);try{let n=(await e.readDirectory(t)).sort((e,t)=>t.localeCompare(e,void 0,{numeric:!0}));for(let r of n){let n=A.join(t,r,`aapt`);if(A.isAbsolute(n)&&await e.isExecutable(n))return cd=n,n}}catch{}}}catch{}cd=null}async function Ad(e,t){let n=await ze({source:e,isInstallablePath:(e,t)=>t.isFile()&&jd(e),installableLabel:`Android installable (.apk or .aab)`,signal:t?.signal});try{let e=t?.resolveIdentity===!1?{}:await Md(n.installablePath,t?.signal);return{archivePath:n.archivePath,installablePath:n.installablePath,packageName:e.packageName,cleanup:n.cleanup}}catch(e){throw await n.cleanup(),e}}function jd(e){let t=A.extname(e).toLowerCase();return t===`.apk`||t===`.aab`}async function Md(e,t){let n=A.extname(e).toLowerCase();return n!==`.apk`&&n!==`.aab`?{}:{packageName:await ld(e,t)}}async function Nd(e,t,n,r={}){let i=typeof n.action==`string`&&n.action.trim()?n.action.trim():`${t}.TEST_PUSH`,o=[`am`,`broadcast`,`-a`,i,`-p`,t],s=typeof n.receiver==`string`?n.receiver.trim():``;s&&o.push(`-n`,s);let c=n.extras;if(c!==void 0&&(typeof c!=`object`||!c||Array.isArray(c)))throw new a(`INVALID_ARGS`,`Android push payload extras must be an object`);let l=c??{},u=0;for(let[e,t]of Object.entries(l))e&&(Pd(o,e,t),u+=1);return await E(e,o,{signal:r.signal}),{action:i,extrasCount:u}}function Pd(e,t,n){if(typeof n==`string`){e.push(`--es`,t,n);return}if(typeof n==`boolean`){e.push(`--ez`,t,n?`true`:`false`);return}if(typeof n==`number`&&Number.isFinite(n)){if(Number.isInteger(n)){e.push(`--ei`,t,String(n));return}e.push(`--ef`,t,String(n));return}throw new a(`INVALID_ARGS`,`Unsupported Android broadcast extra type for "${t}". Use string, boolean, or number.`)}function Z(e){let t=e.replaceAll(`,`,``).match(/^-?\d+(?:\.\d+)?/);if(!t)return null;let n=Number(t[0]);return Number.isFinite(n)?n:null}function Fd(e){let t=Bd(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 Vd(n)}function Id(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 Ld(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=>zd({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 Rd(e){return Math.round(e*10)/10}function zd(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:Rd(Math.max(...t.map(e=>e.durationNs))/1e6)}}function Bd(e){return[...new Set(e.filter(e=>Number.isFinite(e)))].sort((e,t)=>e-t)}function Vd(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 Hd(e,t,n){Ud(e,t);let r=$d(e),i=Yd(e),a=Gd(i,r,t),o=Date.parse(n),s=tf({frames:i,measuredAtMs:o,summary:r}),c=Id({frames:i,frameDeadlineNs:a,summaryDroppedFrameCount:r?.droppedFrameCount}),l=r?.sampleWindowMs??s.sampleWindowMs??of(i),u=Kd(r,i,c),d=Jd({droppedFrames:c,timing:s,measuredAtMs:o,summary:r});return{...u,sampleWindowMs:l,...qd(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 Ud(e,t){if(/no process found for:/i.test(e))throw new a(`COMMAND_FAILED`,`Android gfxinfo did not find a running process for ${t}`,{metric:`fps`,package:t,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 Wd(e){throw new a(`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 Gd(e,t,n){let r=Fd(e);if(!t&&e.length===0&&Wd(n),t||r!==void 0)return r;throw new a(`COMMAND_FAILED`,`Failed to infer Android frame deadline from framestats output for ${n}`,{metric:`fps`,package:n,hint:`Retry perf after a longer interaction window so consecutive Android frame timestamps are available.`})}function Kd(e,t,n){let r=e?.totalFrameCount??t.length,i=e?.droppedFrameCount??n.length;return{totalFrameCount:r,droppedFrameCount:i,droppedFramePercent:e?.droppedFramePercent??(r>0?gn(i/r*100):0)}}function qd(e){return{frameDeadlineMs:e===void 0?void 0:Rd(e/1e6),refreshRateHz:e===void 0?void 0:Rd(1e9/e)}}function Jd(e){let{droppedFrames:t,timing:n,measuredAtMs:r,summary:i}=e;if(t.length===0)return;let a=Ld({frames:t,windowStartNs:n.windowStartNs,measuredAtMs:r,uptimeMs:i?.uptimeMs});return a.length>0?a:void 0}function Yd(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(Xd(i)){n=new Map(i.map((e,t)=>[e,t]));continue}let a=Zd(i,n);a&&t.push(a)}return t.sort((e,t)=>e.intendedVsyncNs-t.intendedVsyncNs)}function Xd(e){return e.includes(`IntendedVsync`)&&e.includes(`FrameCompleted`)}function Zd(e,t){if(!t||e.length<t.size)return;let n=Qd(e,t,`Flags`),r=Qd(e,t,`IntendedVsync`),i=Qd(e,t,`FrameCompleted`);if(!(n!==0||r===null||i===null||r<=0||i<=r))return{intendedVsyncNs:r,frameCompletedNs:i,durationNs:i-r}}function Qd(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 $d(e){let t=e.split(/\nProfile data in ms:\n/i)[0]??``,n=sf(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=Z(i)??void 0,s=Number(a);if(o===void 0||!Number.isFinite(s)||n<0)return;let c=sf(t,`Uptime`),l=sf(t,`Stats since`);return{droppedFramePercent:gn(s),droppedFrameCount:o,totalFrameCount:n,sampleWindowMs:ef({uptimeMs:c,statsSinceNs:l}),uptimeMs:c,statsSinceNs:l}}function ef(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 tf(e){let{frames:t,measuredAtMs:n,summary:r}=e,i=nf(t),a=r?.statsSinceNs,o=a??i.firstFrameNs,s=rf(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:af({deviceBootWallClockMs:l,measuredAtMs:n,summaryStartNs:a,lastFrameNs:i.lastFrameNs}),timestampSource:`estimated-from-device-uptime`}}function nf(e){return e.length===0?{}:{firstFrameNs:Math.min(...e.map(e=>e.intendedVsyncNs)),lastFrameNs:Math.max(...e.map(e=>e.frameCompletedNs))}}function rf(e,t){if(e!==void 0&&t!==void 0)return Math.max(0,Math.round((t-e)/1e6))}function af(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 of(e){if(e.length===0)return;let t=nf(e);return rf(t.firstFrameNs,t.lastFrameNs)}function sf(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:Z(i)??void 0}async function cf(e,t,n={}){let r=v(e,n.adb);try{let i=Hd((await y(r,[`dumpsys`,`gfxinfo`,t,`framestats`],{timeoutMs:15e3})).stdout,t,new Date().toISOString());return await lf(e,t,n),i}catch(e){throw uf(t,e)}}async function lf(e,t,n={}){let r=v(e,n.adb);try{await y(r,[`dumpsys`,`gfxinfo`,t,`reset`],{allowFailure:!0,timeoutMs:3e3})}catch{}}function uf(e,t){return t instanceof a?new a(t.code,t.message,{...t.details??{},metric:`fps`,package:e},t):new a(`COMMAND_FAILED`,`Failed to sample Android fps for ${e}`,{metric:`fps`,package:e},t)}async function df(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 ff(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 ff(e,t,n){try{let r=await cf(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 pf(e,t,n){let r=v(e,n.adb);await yf(r,t),await Sf(r,t),await xf(r,t,n.files);let i=await vf(t.outPath,n.files);await gf(r,t.remotePath);let a=Date.now(),o=Math.max(0,a-t.startedAt),s=await df(e,t,i,o,{adb:r});return{...t,action:`stop`,platform:`android`,state:`stopped`,stoppedAt:a,durationMs:o,sizeBytes:i,method:t.kind===`simpleperf`?ei:ti,artifact:{path:t.outPath,sizeBytes:i},summary:s,message:`Stopped Android ${t.kind} ${t.type} for ${t.packageName}`}}async function mf(e,t,n={}){let r=v(e,n.adb);try{t.state===`running`&&(await yf(r,t),await Sf(r,t).catch(()=>{}))}finally{await gf(r,t.remotePath)}}function hf(e,t,n=ni){return`${n}/agent-device-${e.replaceAll(/[^A-Za-z0-9_.-]/g,`_`)}-${Date.now()}-${t}`}async function gf(e,t){try{await y(e,[`rm`,`-f`,t],{allowFailure:!0,timeoutMs:I})}catch{}}async function _f(e,t,n=b().files){await n.ensureDirectory(A.dirname(e)),await n.writeBytes(e,Buffer.from(`${JSON.stringify(t,null,2)}\n`))}async function vf(e,t=b().files){try{return(await t.stat(e)).size}catch(t){throw new a(`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.`},t)}}async function yf(e,t){try{await y(e,[C(bf(t.profilerPid))],{timeoutMs:L})}catch(e){throw F(`stop`,t.kind,t.packageName,e)}}function bf(e){return[`pid=${w(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 xf(e,t,n){await(n??b().files).ensureDirectory(A.dirname(t.outPath));try{await e([`pull`,t.remotePath,t.outPath],{timeoutMs:L})}catch(e){throw new a(`COMMAND_FAILED`,`Failed to pull Android ${t.kind} artifact for ${t.packageName}`,{package:t.packageName,tool:t.kind,remotePath:t.remotePath,outPath:t.outPath,hint:`Check that the profiling command ran long enough to create an artifact, then retry stop with the same session.`},e)}}async function Sf(e,t){let n;for(let r=0;r<12;r+=1){let r=await Cf(e,t.remotePath);if(r!==void 0&&r>0&&r===n)return;n=r,await _(250)}throw new a(`COMMAND_FAILED`,`Android ${t.kind} artifact is not ready to pull`,{package:t.packageName,tool:t.kind,remotePath:t.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 Cf(e,t){let n=w(t),r=await y(e,[C(`if [ -f ${n} ]; then stat -c %s ${n} 2>/dev/null || wc -c < ${n}; fi`)],{allowFailure:!0,timeoutMs:I});if(r.exitCode!==0)return;let i=Number(r.stdout.trim().split(/\s+/)[0]);return Number.isFinite(i)?i:void 0}async function wf(e,t,n,r={}){let i=v(e,r.adb),a=await ri(i,t);await ii(i,`perfetto`,t);let o=hf(t,`app.perfetto-trace`,`/data/misc/perfetto-traces`),s;try{await lf(e,t,{adb:i}),s=await Ef(i,o,t)}catch(e){throw await gf(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:ti,message:`Started Android Perfetto trace for ${t}`}}async function Tf(e,t,n,r={}){return await pf(e,{...t,outPath:n},r)}async function Ef(e,t,n){try{let r=ai((await y(e,[`perfetto`,`--background-wait`,`-o`,t,`-t`,`3600s`,`sched`,`freq`,`idle`,`am`,`wm`,`gfx`,`view`,`binder_driver`,`hal`,`dalvik`],{timeoutMs:L})).stdout);if(r)return r;throw new a(`COMMAND_FAILED`,`Android perfetto did not return a profiler pid`,{package:n,tool:`perfetto`,hint:`Retry perf trace start. If perfetto exits immediately, verify the device permits trace capture.`})}catch(e){throw F(`start`,`perfetto`,n,e)}}function Df(e){let t=[];for(let n of d(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:gn(r),command:a[0],dso:a[1],symbol:a.slice(2).join(` `)||void 0}),t.length>=50)break}return t}async function Of(e,t,n,r={}){let i=v(e,r.adb),a=await ri(i,t);await ii(i,`simpleperf`,t);let o=hf(t,`cpu.perf.data`),s;try{s=await jf(i,a,o,t)}catch(e){throw await gf(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:ei,message:`Started Android Simpleperf CPU profile for ${t}`}}async function kf(e,t,n,r={}){return await pf(e,{...t,outPath:n},r)}async function Af(e,t,n,r={}){let i=v(e,r.adb);await ii(i,`simpleperf`,t.packageName);let a=await Pf(i,t),o=new Date().toISOString(),s=Df(a.stdout),c=s.slice(0,10).map(e=>({symbol:e.symbol??`<unknown>`,binary:e.dso,selfSamplePercent:e.percentage}));await _f(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 vf(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:ei,message:`Wrote Android Simpleperf report for ${t.packageName}`}}async function jf(e,t,n,r){try{let i=ai((await y(e,[C(Mf(t,n))],{timeoutMs:L})).stdout);if(i)return i;throw new a(`COMMAND_FAILED`,`Android simpleperf did not return a profiler pid`,{package:r,tool:`simpleperf`,hint:`Retry perf. If simpleperf exits immediately, verify the app is profileable and the device permits native profiling.`})}catch(e){throw F(`start`,`simpleperf`,r,e)}}function Mf(e,t){return Nf([`simpleperf`,`record`,`-e`,`cpu-clock:u`,`-p`,e,`-o`,t,`--duration`,`3600`],`simpleperf`)}function Nf(e,t){let n=e.map(w).join(` `),r=`${ni}/agent-device-${t}-${Date.now()}.err`;return[`err=${w(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 Pf(e,t){try{return await y(e,[`simpleperf`,`report`,`-i`,t.remotePath,`--stdio`,`--sort`,`comm,dso,symbol`],{timeoutMs:L})}catch(e){throw F(`report`,`simpleperf`,t.packageName,e)}}const Ff=15e3,If=12e4;async function Lf(e,t,n={}){let r=v(e,n.adb);try{return Vf((await y(r,[`dumpsys`,`meminfo`,t],{timeoutMs:Ff})).stdout,t,new Date().toISOString())}catch(e){throw Yf(`memory`,t,e)}}async function Rf(e,t,n,r={}){let i=v(e,r.adb),o=r.files??b().files,s=await Hf(i,t),c=Uf(t);await o.ensureDirectory(A.dirname(n));let l=await zf(o,n);try{Pe(await y(i,[`am`,`dumpheap`,t,c],{allowFailure:!0,timeoutMs:If}),`Failed to capture Android heap dump for ${t}`,e=>({kind:`android-hprof`,package:t,pid:s,remotePath:c,hint:Wf(e.stdout,e.stderr)}));let e=await i([`pull`,c,n],{allowFailure:!0,timeoutMs:If});if(e.exitCode!==0)throw await Bf(o,n,l),T(`Failed to pull Android heap dump for ${t}`,e,{kind:`android-hprof`,package:t,pid:s,remotePath:c,path:n,hint:`Verify the daemon can write the requested --out path and retry. The heap dump stays on-device only until cleanup runs.`});let r=await o.stat(n).catch(()=>null);if(!r?.isFile||r.size<=0)throw await Bf(o,n,l),new a(`COMMAND_FAILED`,`Android heap dump artifact is missing or empty`,{kind:`android-hprof`,package:t,pid:s,path:n,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:n,sizeBytes:r.size,measuredAt:new Date().toISOString(),method:`adb-shell-am-dumpheap`,packageName:t,pid:s,remotePath:c}}finally{await y(i,[`rm`,`-f`,c],{allowFailure:!0,timeoutMs:Ff}).catch(()=>{})}}async function zf(e,t){return await e.stat(t).then(e=>e.isFile).catch(()=>!1)}async function Bf(e,t,n){n||await e.remove(t,{force:!0}).catch(()=>{})}function Vf(e,t,n){if(/no process found for:/i.test(e))throw new a(`COMMAND_FAILED`,`Android meminfo did not find a running process for ${t}`,{metric:`memory`,package:t,hint:`Run open <app> for this session again to ensure the Android app is active, then retry perf.`});let r=Xf(e,`TOTAL PSS`)??Zf(e);if(r===void 0)throw new a(`COMMAND_FAILED`,`Failed to parse Android meminfo output for ${t}`,{metric:`memory`,package:t,hint:`Retry perf after reopening the app session. If the problem persists, capture adb shell dumpsys meminfo output for debugging.`});return{totalPssKb:r,totalRssKb:Xf(e,`TOTAL RSS`),measuredAt:n,method:`adb-shell-dumpsys-meminfo`,topConsumers:Gf(e)}}async function Hf(e,t){let n=await y(e,[`pidof`,t],{allowFailure:!0,timeoutMs:Ff}),r=n.stdout.trim().split(/\s+/).map(Number).find(e=>Number.isInteger(e)&&e>0);if(n.exitCode===0&&r!==void 0)return r;throw new a(`COMMAND_FAILED`,`No running Android process found for ${t}`,{kind:`android-hprof`,package:t,stdout:n.stdout,stderr:n.stderr,hint:`Run open <app> for this session again to ensure the Android app is active, then retry perf memory snapshot.`})}function Uf(e){return`/data/local/tmp/agent-device-${e.replaceAll(/[^a-zA-Z0-9._-]/g,`_`)}-${Date.now()}.hprof`}function Wf(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 Gf(e){let t=e.split(`
14
- `).flatMap(e=>Kf(e)??[]).sort((e,t)=>t.pssKb-e.pssKb).slice(0,5);return t.length>0?t:void 0}function Kf(e){let t=e.trim();if(qf(t))return;let n=t.match(/^(.+?)\s+([0-9][0-9,]*(?:\(\d+\))?)(?:\s|$)/);if(n)return Jf(n[1],n[2])}function qf(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 Jf(e,t){let n=e?.trim(),r=t?Z(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 Yf(e,t,n){return n instanceof a?new a(n.code,n.message,{...n.details??{},metric:e,package:t},n):new a(`COMMAND_FAILED`,`Failed to sample Android ${e} for ${t}`,{metric:e,package:t},n)}function Xf(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:Z(i)??void 0}function Zf(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=>Z(e)!==null);return n?Z(n)??void 0:void 0}}async function Qf(e,t,n){let r=await E(e,[`dumpsys`,`package`,t],{allowFailure:!0});return r.exitCode===0?cp(r.stdout,n):{requested:void 0,grants:void 0}}async function $f(e){let t=await E(e,[`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 ep=/^\s*User (\d+):/,tp=/^\s*runtime permissions:\s*$/,np=/^\s*([\w.]+): granted=(true|false)\b/,rp=/^\s*Package \[.+?\]/,ip=/^\s*requested permissions:\s*$/,ap=/^\s*([A-Za-z][\w.]*)/;function op(e){return e.split(`
16
- `).filter(e=>e.trim().length>0).map(e=>({text:e,indent:e.length-e.trimStart().length}))}function sp(e,t){let n=Q(Q(Q(op(e),e=>e.indent===0&&e.text.trim()===`Packages:`),e=>ep.exec(e.text)?.[1]===String(t)),e=>tp.test(e.text));if(!n)return;let r=new Map;for(let{text:e}of n){let t=np.exec(e);t&&r.set(t[1],t[2]===`true`?`granted`:`not_granted`)}return r}function Q(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 cp(e,t){return{requested:lp(e),grants:sp(e,t)}}function lp(e){let t=Q(Q(Q(op(e),e=>e.indent===0&&e.text.trim()===`Packages:`),e=>rp.test(e.text)),e=>ip.test(e.text));if(!t)return;let n=[];for(let{text:e}of t){let t=ap.exec(e)?.[1];t&&t.includes(`.`)&&!n.includes(t)&&n.push(t)}return n}function up(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.`}const dp=[`all`,`camera`,`microphone`,`photos`,`contacts`,`notifications`,`calendar`,`location`,`media-library`],fp={calendar:[`android.permission.WRITE_CALENDAR`,`android.permission.READ_CALENDAR`],camera:[`android.permission.CAMERA`],contacts:[`android.permission.READ_CONTACTS`,`android.permission.WRITE_CONTACTS`],location:[`android.permission.ACCESS_FINE_LOCATION`,`android.permission.ACCESS_COARSE_LOCATION`],"media-library":[`android.permission.WRITE_EXTERNAL_STORAGE`,`android.permission.READ_EXTERNAL_STORAGE`,`android.permission.READ_MEDIA_AUDIO`,`android.permission.READ_MEDIA_IMAGES`,`android.permission.READ_MEDIA_VIDEO`],microphone:[`android.permission.RECORD_AUDIO`]};async function pp(e){let t=await $f(e);if(t!==void 0)return t;throw new a(`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 mp(e,t,n,r){let i=we(n),a=Fp(r?.permissionTarget,r?.permissionMode),o=await pp(e),s=[`--user`,String(o)];if(a.kind===`all`)return await _p(e,t,i,o,s);if(i===`grant`){let n=await Np(e,t,a,o,s);return gp(hp(a),n)}if(a.kind===`pm`)return await Rp(e,t,i,a,o,s);let{grants:c}=await Qf(e,t,o),l=await Pp(e,t,i,a,s),{priorGrantState:u,warnings:d}=Bp(t,l,l.map(e=>c?.get(e)??`unknown`));return gp(a.kind,l,{priorGrantState:u,warnings:d})}function hp(e){return e.kind===`pm`?e.name:e.kind}function gp(e,t,n){return{permission:e,permissions:[...t],...n?{priorGrantState:n.priorGrantState,...n.warnings.length>0?{warnings:n.warnings}:{}}:{}}}async function _p(e,t,n,r,i){let{requested:o,grants:s}=await Qf(e,t,r);if(o===void 0)throw new a(`COMMAND_FAILED`,`Could not read declared permissions for ${t}, so no permission was changed.`,{appPackage:t});let c=n===`grant`?void 0:s,l=[],u=[];for(let r of wp(o))await vp({device:e,appPackage:t,action:n,userArgs:i,grants:c,applied:l,warnings:u},r);return{permission:`all`,permissions:l,...u.length>0?{warnings:u}:{}}}async function vp(e,t){return t.kind===`notification`?await yp(e):t.kind===`photos`?await bp(e):await xp(e,t.value)}async function yp(e){let{device:t,appPackage:n,action:r,userArgs:i}=e;await Hp(t,n,r,{appOps:`POST_NOTIFICATION`,permission:`android.permission.POST_NOTIFICATIONS`},i),Sp(e,`android.permission.POST_NOTIFICATIONS`)}async function bp(e){let{device:t,appPackage:n,action:r,userArgs:i,warnings:a}=e,o=await kp(t,n,r===`grant`?`grant`:`revoke`,i);if(o===void 0){a.push(`Skipped Android photos permission for ${n}: device refused both media candidates.`);return}await Cp(e,o)}async function xp(e,t){let{device:n,appPackage:r,action:i,userArgs:a,warnings:o}=e,s=await Op(n,i===`grant`?`grant`:`revoke`,a,r,t);if(s.kind===`skipped`){o.push(`Skipped ${t} for ${r}: ${s.detail}`);return}await Cp(e,t)}function Sp(e,t){let{appPackage:n,action:r,grants:i,applied:a,warnings:o}=e;a.push(t),r!==`grant`&&Tp(o,i,n,t)}async function Cp(e,t){Sp(e,t),e.action===`reset`&&await Up(e.device,e.appPackage,t,e.userArgs)}function wp(e){let t=[],n=!1;for(let r of e)r===`android.permission.POST_NOTIFICATIONS`?t.push({kind:`notification`}):r===`android.permission.READ_MEDIA_IMAGES`||r===`android.permission.READ_EXTERNAL_STORAGE`?n||(n=!0,t.push({kind:`photos`})):t.push({kind:`pm`,value:r});return t}function Tp(e,t,n,r){let i=up(n,r,t?.get(r)??`unknown`);i&&e.push(i)}const Ep=[[/not a changeable permission/,`not-changeable`],[/has not requested permission/,`not-requested`],[/is not a runtime permission/,`not-runtime-permission`],[/unknown permission/,`unknown-permission`],[/managed by role/,`role-managed`]];function Dp(e){let t=e.toLowerCase();return Ep.find(([e])=>e.test(t))?.[1]}async function Op(e,t,n,r,i){let a=await E(e,[`pm`,t,...n,r,i],{allowFailure:!0});if(a.exitCode===0)return{kind:`applied`};let o=Dp(a.stderr);if(o)return{kind:`skipped`,reason:o,detail:Mp(a.stderr)};throw T(`Failed to ${t} Android permission ${i} for ${r}`,a,{appPackage:r,permission:i})}async function kp(e,t,n,r){try{return await Vp(e,t,n,r)}catch(e){if(Ap(e))return;throw e}}function Ap(e){if(!(e instanceof a)||e.code!==`COMMAND_FAILED`)return!1;let t=e.details?.attempts;return jp(t)&&t.length>0&&t.every(e=>e.reason!==void 0)}function jp(e){return Array.isArray(e)&&e.every(e=>typeof e==`object`&&!!e&&typeof e.permission==`string`&&typeof e.detail==`string`)}function Mp(e){let t=e.split(`
17
- `).map(e=>e.trim()).filter(e=>e.length>0),n=t[0]??`unknown device error`;return(n.endsWith(`:`)&&t[1]?`${n} ${t[1]}`:n).slice(0,200)}async function Np(e,t,n,r,i){if(n.kind===`notifications`)return await Hp(e,t,`grant`,n,i),[n.permission];if(n.kind===`photos`)return[await Vp(e,t,`grant`,i)];if(n.kind===`pm`){let a=[...await Ip(e,t,n.values,r)];for(let n of a)await E(e,[`pm`,`grant`,...i,t,n]);return a}throw n.kind===`all`?Error(`Unhandled Android permission target: all is resolved by the caller.`):Error(`Unhandled Android permission target: ${JSON.stringify(n)}`)}async function Pp(e,t,n,r,i){if(r.kind===`notifications`)return await Hp(e,t,n,r,i),[r.permission];if(r.kind===`photos`){let r=await Vp(e,t,`revoke`,i);return n===`reset`&&await Up(e,t,r,i),[r]}throw r.kind===`pm`?Error(`Unhandled Android permission target: pm is resolved by the caller.`):r.kind===`all`?Error(`Unhandled Android permission target: all is resolved by the caller.`):Error(`Unhandled Android permission target: ${JSON.stringify(r)}`)}function Fp(e,t){let n=Ee(e);if(t?.trim())throw new a(`INVALID_ARGS`,`Android does not support permission modes. Received: ${t}.`);if(n===`all`)return{kind:`all`};if(n===`photos`)return{kind:`photos`};if(n===`notifications`)return{kind:`notifications`,appOps:`POST_NOTIFICATION`,permission:`android.permission.POST_NOTIFICATIONS`};let r=n in fp?fp[n]:void 0;if(r)return{kind:`pm`,name:n,values:r};throw new a(`INVALID_ARGS`,`Unsupported permission target on Android: ${e}. Use ${dp.join(`|`)}.`,{hint:`Android custom permission ids are attempted through all, not individually.`})}async function Ip(e,t,n,r){let{requested:i}=await Qf(e,t,r);return Lp(i,n,t)}function Lp(e,t,n){if(e===void 0)return t;let r=t.filter(t=>e.includes(t));if(r.length===0)throw new a(`COMMAND_FAILED`,`Package ${n} has not requested permission ${t.join(`, `)}, so no permission was changed.`,{appPackage:n,permissions:t});return r}async function Rp(e,t,n,r,i,a){let{requested:o,grants:s}=await Qf(e,t,i),c=Lp(o,r.values,t);await zp(e,t,c,n,a);let{priorGrantState:l,warnings:u}=Bp(t,c,c.map(e=>s?.get(e)??`unknown`));return gp(r.name,c,{priorGrantState:l,warnings:u})}async function zp(e,t,n,r,i){for(let r of n)await E(e,[`pm`,`revoke`,...i,t,r]);if(r===`reset`)for(let r of n)await Up(e,t,r,i)}function Bp(e,t,n){return{priorGrantState:n.includes(`granted`)?`granted`:n.includes(`unknown`)?`unknown`:`not_granted`,warnings:t.flatMap((t,r)=>{let i=up(e,t,n[r]);return i?[i]:[]})}}async function Vp(e,t,n,r){let i=await Wp(e),o=i!==null&&i>=33?[`android.permission.READ_MEDIA_IMAGES`,`android.permission.READ_EXTERNAL_STORAGE`]:[`android.permission.READ_EXTERNAL_STORAGE`,`android.permission.READ_MEDIA_IMAGES`],s=[];for(let i of o){let a=await E(e,[`pm`,n,...r,t,i],{allowFailure:!0});if(a.exitCode===0)return i;s.push({permission:i,reason:Dp(a.stderr),detail:Mp(a.stderr)})}throw new a(`COMMAND_FAILED`,`Failed to ${n} Android photos permission`,{appPackage:t,sdkInt:i,attempts:s})}async function Hp(e,t,n,r,i){let a=n===`grant`?`allow`:n===`deny`?`deny`:`default`;n===`grant`?await E(e,[`pm`,`grant`,...i,t,r.permission],{allowFailure:!0}):(await E(e,[`pm`,`revoke`,...i,t,r.permission],{allowFailure:!0}),n===`reset`&&await Up(e,t,r.permission,i)),await E(e,[`appops`,`set`,...i,t,r.appOps,a])}async function Up(e,t,n,r){for(let i of[`user-set`,`user-fixed`])await E(e,[`pm`,`clear-permission-flags`,...r,t,n,i],{allowFailure:!0})}async function Wp(e){let t=await E(e,[`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}const Gp=[`cmd`,`connectivity`,`airplane-mode`];async function Kp(e,t){let n=t?`enabled`:`disabled`;await qp(e),await E(e,[...Gp,t?`enable`:`disable`]);let r=await Jp(e);if(r!==n)throw new a(`COMMAND_FAILED`,`Android airplane mode reads ${r} after requesting ${n}.`,{deviceId:e.id,requested:n,airplaneMode:r});return{airplaneMode:r}}async function qp(e){let{state:t,result:n}=await Yp(e);if(!t)throw n.exitCode!==0&&ft(n.stdout,n.stderr)?new a(`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:n.stdout,stderr:n.stderr,exitCode:n.exitCode}):T(`Failed to read Android airplane mode`,n,{deviceId:e.id})}async function Jp(e){let{state:t,result:n}=await Yp(e);if(t)return t;throw T(`Failed to read Android airplane mode after changing it`,n,{deviceId:e.id})}async function Yp(e){let t=await E(e,[...Gp],{allowFailure:!0});return{state:t.exitCode===0?Xp(t.stdout):void 0,result:t}}function Xp(e){let t=e.trim().toLowerCase();if(t===`enabled`)return`enabled`;if(t===`disabled`)return`disabled`}const Zp=[`window_animation_scale`,`transition_animation_scale`,`animator_duration_scale`],Qp={"extra-small":`0.82`,small:`0.88`,medium:`0.94`,large:`1.0`,"extra-large":`1.12`,"extra-extra-large":`1.24`,"extra-extra-extra-large":`1.35`,"accessibility-medium":`1.5`,"accessibility-large":`1.75`,"accessibility-extra-large":`2.0`,"accessibility-extra-extra-large":`2.5`,"accessibility-extra-extra-extra-large":`3.2`},$p=Qp.large;async function em(e,n,r,i,o){switch(n.toLowerCase()){case`wifi`:{let t=Se(r);await E(e,[`svc`,`wifi`,t?`enable`:`disable`]);return}case`airplane`:return await Kp(e,Se(r));case`location`:{if(r.toLowerCase()===`set`){if(e.kind!==`emulator`)throw new a(`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:t,longitude:n}=De(o);return await dt(e,[`emu`,`geo`,`fix`,String(n),String(t)]),{latitude:t,longitude:n}}let t=Se(r)?`3`:`0`;await E(e,[`settings`,`put`,`secure`,`location_mode`,t]);return}case`animations`:{let t=Se(r)?`1`:`0`;for(let n of Zp)await E(e,[`settings`,`put`,`global`,n,t]);return{scale:t,keys:[...Zp]}}case`appearance`:{let t=await um(e,r);await E(e,[`cmd`,`uimode`,`night`,t===`dark`?`yes`:`no`]);return}case`clear-app-state`:{if(r.toLowerCase()!==`clear`)throw new a(`INVALID_ARGS`,`settings clear-app-state only supports clear.`);if(!i)throw new a(`INVALID_ARGS`,`settings clear-app-state requires an app id or an active app session.`,t());let n=await Zt(e,i);if(n.type===`intent`)throw new a(`INVALID_ARGS`,`settings clear-app-state requires a package name, not an intent.`);await E(e,[`am`,`force-stop`,n.value],{allowFailure:!0});let o=await E(e,[`pm`,`clear`,n.value],{allowFailure:!0});if(o.exitCode!==0||!/\bSuccess\b/i.test(o.stdout))throw new a(`COMMAND_FAILED`,`Failed to clear Android app data for ${n.value}`,{package:n.value,stdout:o.stdout,stderr:o.stderr,exitCode:o.exitCode});return{package:n.value,cleared:!0}}case`fingerprint`:await sm(e,om(r));return;case`permission`:if(!i)throw new a(`INVALID_ARGS`,`permission setting requires an active app in session`,t());return await mp(e,i,r,o);case`text-size`:return await rm(e,r);default:throw new a(`INVALID_ARGS`,`Unsupported setting: ${n}`)}}const tm={"text-size":im};async function nm(e,t){return await tm[t](e)}async function rm(e,t){let n=Te(t),r=Qp[n];return await E(e,[`settings`,`put`,`system`,`font_scale`,r]),be(n,r)}async function im(e){let t=(await E(e,[`settings`,`get`,`system`,`font_scale`])).stdout.trim(),n=t===`null`?$p:t,r=/^(\d+(\.\d+)?)$/.test(n)?Number(n):NaN;if(!Number.isFinite(r)||r<=0)throw new a(`COMMAND_FAILED`,`Android reported an unusable font scale: ${t||`(empty)`}`,{deviceId:e.id,fontScale:t,hint:"Run `adb shell settings get system font_scale` to see what the device holds."});return be(am(r),n)}function am(e){let t=Ce[0],n=1/0;for(let r of Ce){let i=Math.abs(Number.parseFloat(Qp[r])-e);i>=n||(t=r,n=i)}return t}function om(e){let t=e.trim().toLowerCase();if(t===`match`)return`match`;if(t===`nonmatch`)return`nonmatch`;throw new a(`INVALID_ARGS`,`Invalid fingerprint state: ${e}. Use match|nonmatch.`)}async function sm(e,t){let n=cm(e,t),r=[];for(let t of n){let n=await dt(e,t,{allowFailure:!0});if(n.exitCode===0)return;r.push({args:t,stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode})}let i=c(r);throw r.length>0&&r.every(e=>lm(e.stdout,e.stderr))?new a(`UNSUPPORTED_OPERATION`,`Android fingerprint simulation is not supported on this target/runtime.`,{deviceId:e.id,action:t,hint:`Use an Android emulator with biometric support, or a device/runtime that exposes cmd fingerprint.`,attempts:i}):new a(`COMMAND_FAILED`,`Failed to simulate Android fingerprint.`,{deviceId:e.id,action:t,attempts:i})}function cm(e,t){let n=t===`match`?`1`:`9999`,r=[Qe(`adb`,`shell`,[`cmd`,`fingerprint`,`touch`,n]),Qe(`adb`,`shell`,[`cmd`,`fingerprint`,`finger`,n])];return e.kind===`emulator`&&r.push([`emu`,`finger`,`touch`,n]),r}function lm(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 um(e,t){let n=xe(t);if(n!==`toggle`)return n;let r=await E(e,[`cmd`,`uimode`,`night`],{allowFailure:!0});if(r.exitCode!==0)throw T(`Failed to read current Android appearance`,r);let i=dm(r.stdout,r.stderr);if(!i)throw new a(`COMMAND_FAILED`,`Unable to determine current Android appearance for toggle`,{stdout:r.stdout,stderr:r.stderr});return i===`auto`?`dark`:i===`dark`?`light`:`dark`}function dm(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 fm=Buffer.from([137,80,78,71,13,10,26,10]);async function pm(e,t,n={}){if(n.stabilize===!1)return await gm(e,t);await mm(e);try{return await _(1e3),await gm(e,t)}finally{await hm(e).catch(()=>{})}}async function mm(e){let t=t=>E(e,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 hm(e){await E(e,[`am`,`broadcast`,`-a`,`com.android.systemui.demo`,`-e`,`command`,`exit`],{allowFailure:!0})}async function gm(e,t){let n=new AbortController,r=co(e,{timeoutMs:2e3,signal:n.signal});try{await vm(e,t);let n=await _m(r,250);return n?{displayRotation:n}:{}}finally{n.abort()}}async function _m(e,t){let n;try{return await Promise.race([e,new Promise(e=>{n=setTimeout(()=>e(void 0),t)})])}finally{clearTimeout(n)}}async function vm(e,t){let n=await ut(e,[`screencap`,`-p`],{binaryStdout:!0});if(!n.stdoutBuffer)throw new a(`COMMAND_FAILED`,`Failed to capture screenshot`);let r=n.stdoutBuffer.indexOf(fm);if(r<0)throw new a(`COMMAND_FAILED`,`Screenshot data does not contain a valid PNG header`);let i=ym(n.stdoutBuffer,r);if(!i)throw new a(`COMMAND_FAILED`,`Screenshot data does not contain a complete PNG payload`);await b().files.writeBytes(t,n.stdoutBuffer.subarray(r,i))}function ym(e,t){let n=t+fm.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 bm(e,t,n=0){let r=Je(e);if(r){await r({action:`type`,text:t,delayMs:n}),$(`type`,`provider-native`,t);return}let i=await Tm(e,`type`,t);if(i.backend===`test-ime`){await Dm(e,i.packageName,t,n);return}if(n>0&&Array.from(t).length>1){await km(e,{action:`type`,text:t,chunkSize:1,delayMs:n});return}await km(e,{action:`type`,text:t,chunkSize:8,delayMs:0})}async function xm(e,t,r,i,a=0,o={}){let s=await wu(e,t,r,o),c=Je(e);if(c)return await c({action:`fill`,target:{x:t,y:r},text:i,delayMs:a}),$(`fill`,`provider-native`,i),X(i,s,await xu(e,t,r,i,o));let l=null,u=0;try{for(let n of Sm(a)){await fo(e,t,r),u+=1;let a=await Tm(e,`fill`,i);if(a.backend===`test-ime`)return X(i,s,await Om(e,a.packageName,t,r,i,s,o));let c=await Cm(e,{x:t,y:r,text:i,beforeTarget:s,attempt:n},o);if(l=c,c.ok)return;if(c.reason===`ime_capture`)return X(i,s,c);let d=Eu(i,s,c);if(d)return d}}catch(e){throw n(e,u)}return X(i,s,l)}function Sm(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 Cm(e,t,n){let{x:r,y:i,text:a,beforeTarget:o,attempt:s}=t;return await Pm(e,wm(a,o,s)),await km(e,{action:`fill`,text:a,chunkSize:s.chunkSize,delayMs:s.inputDelayMs}),xu(e,r,i,a,n)}function wm(e,t,n){let r=Array.from(e).length;return Um(r>0?r+n.clearPadding:t?.text?Array.from(t.text).length+n.clearPadding:n.maxClear,n.minClear,n.maxClear)}async function Tm(e,t,n){let r=kt(e);if(r)return r.rebindUnconfirmed&&await Em(e),{backend:`test-ime`,packageName:(await _t(S(e))).manifest.packageName};let i=await Fm(e,t),a=i?.inputMethodPackage;return It(a)?{backend:`test-ime`,packageName:a}:(Lm(n),Im(i,t),{backend:`adb-shell`})}async function Em(e){let{rebindAndroidTestIme:t}=await import(`./ime-rebind.js`),n=await t(e);if(n.kind!==`confirmed`)throw new a(`COMMAND_FAILED`,`Could not confirm the Android test IME rebind on ${e.name??e.id}.`,{reason:`android_test_ime_rebind_unconfirmed`,rebindCause:n.kind===`not-owned`?`not-owned`:n.cause,deviceId:e.id,hint:`Close and reopen the session to restore the keyboard and reactivate the test IME.`})}async function Dm(e,t,n,r){let i=v(e);await jm(e,Am(n,r>0?1:1/0,r),{delayMs:r,sendChunk:async e=>await gt(i,t,e)}),$(`type`,`test-ime`,n)}async function Om(e,t,r,i,a,o,s){let c=v(e),l=0,u=async()=>(await Tt(c,t),l+=1,a&&(await gt(c,t,a),l+=1),await xu(e,r,i,a,s)),d=async()=>{let t=await u();return t.ok||Eu(a,o,t)?t:(Tu(t,o)&&await Em(e),await fo(e,r,i),l+=1,await u())},f;try{f=await d()}catch(e){throw n(e,l)}return $(`fill`,`test-ime`,a),f}async function km(e,t){await jm(e,Am(t.text,t.chunkSize,t.delayMs),{delayMs:t.delayMs,sendChunk:async t=>{try{await Nm(e,t)}catch(e){throw at(e)}}}),$(t.action,`adb-shell`,t.text)}function Am(e,t,n){let r=e.split(`
18
- `);return r.flatMap((e,i)=>{let a=Hm(e,t),o=i+1===r.length,s=a.map((e,t)=>({kind:`chunk`,text:e,pauseAfter:n>0&&!(o&&t+1===a.length)}));return o?s:[...s,{kind:`enter`}]})}async function jm(e,t,r){let i=0;try{for(let n of t){if(n.kind===`enter`){await Mm(e),i+=1;continue}n.text&&(await r.sendChunk(n.text),i+=1),n.pauseAfter&&await _(r.delayMs)}}catch(e){throw n(e,i)}}async function Mm(e){try{await E(e,[`input`,`keyevent`,`ENTER`])}catch(e){throw at(e)}}async function Nm(e,t){try{await E(e,[`input`,`text`,zm(t)])}catch(e){throw Bm(e)?Vm(t,e):e}}async function Pm(e,t){let r=Math.max(0,t),i=0;try{await E(e,[`input`,`keyevent`,`KEYCODE_MOVE_END`],{allowFailure:!0}),i+=1;for(let t=0;t<r;t+=24){let n=Math.min(24,r-t);await E(e,[`input`,`keyevent`,...Array(n).fill(`KEYCODE_DEL`)],{allowFailure:!0}),i+=1}}catch(e){throw n(e,i)}}async function Fm(e,t){try{return await Wo(e)}catch(e){return g({level:`warn`,phase:`android_input_ownership_probe_failed`,data:{action:t,error:e instanceof Error?e.message:String(e)}}),null}}function Im(e,t){if(!(!e||e.inputOwner!==`ime`))throw new a(`COMMAND_FAILED`,`KEYBOARD_OVERLAY_BLOCKING: Android text input is blocked because the focused input belongs to the active keyboard/IME.`,{failureReason:`ime_capture`,action:t,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 Lm(e){if(!Rm(e))throw Vm(e)}function Rm(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 zm(e){return e.replaceAll(` `,`%s`)}function Bm(e){if(!(e instanceof a)||e.code!==`COMMAND_FAILED`)return!1;let t=e.details?.stderr,n=(typeof t==`string`?t:``).toLowerCase();return!!(n.includes(`exception occurred while executing 'text'`)||n.includes(`nullpointerexception`)&&n.includes(`inputshellcommand.sendtext`))}function Vm(e,t){return new a(`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.`,{backend:`adb-shell`,reason:f,textLength:Array.from(e).length,textPreview:e.slice(0,32),hint:"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)."},t instanceof Error?t:void 0)}function Hm(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){g({phase:`android_text_injection`,data:{action:e,backend:t,textLength:Array.from(n).length}})}function Um(e,t,n){return Math.max(t,Math.min(n,e))}var Wm=e({ANDROID_FOCUSED_WINDOW_MARKER:()=>rn,ANDROID_FOCUS_MARKERS:()=>tn,ANDROID_IME_HELPER_SERVICE_COMPONENT:()=>Et,ANDROID_SNAPSHOT_PRESENTATION_DEFAULT_DEADLINE_MS:()=>250,ANDROID_TEST_IME_SETTINGS_KEYS:()=>Nt,ANDROID_TOUCH_PLAN_PROTOCOL:()=>Aa,AndroidSnapshotPresentationFailure:()=>Y,activateAndroidTestIme:()=>Yu,androidAdbForwardsDeviceExitStatus:()=>bn,androidAdbHostTarget:()=>rt,androidAdbInvocation:()=>tt,androidAdbResultError:()=>T,androidAdbSerialTarget:()=>nt,androidAppsDiscoveryHint:()=>Qt,androidCaptureFailureReasonDetail:()=>qr,androidCaptureFailureReasonFromExitCode:()=>Kr,androidCaptureFailureReasonFromHelperResult:()=>Gr,androidClipboardShellSupportForResult:()=>Km,androidDeviceChecks:()=>gs,androidFillFailureDetails:()=>Au,androidFillFailureMessage:()=>ku,androidRevokedPermissionWarning:()=>up,androidSnapshotPublicationInput:()=>Rl,androidToolchainCheck:()=>hs,androidUiNodes:()=>Gc,annotateAndroidNativePerfError:()=>F,appSwitcherAndroid:()=>lo,attachAdbFailureHint:()=>ot,backAndroid:()=>$a,buildAndroidFillUnconfirmedVerification:()=>Eu,buildAndroidNativeToolUnavailableHint:()=>Yr,buildAndroidSnapshotClickabilityEvidence:()=>al,buildAndroidSnapshotHelperArgs:()=>Di,buildAndroidSnapshotHelperCaptureOptions:()=>Ti,buildUiHierarchySnapshot:()=>Tc,captureAndroidHeapSnapshot:()=>Rf,captureAndroidLogcatWithAdb:()=>qm,captureAndroidSnapshotWithHelper:()=>wi,captureAndroidSnapshotWithHelperSession:()=>Ta,classifyAdbFailure:()=>lt,classifyAndroidAlertIdentifier:()=>Mn,classifyAndroidAppTarget:()=>qt,classifyAndroidHelperContent:()=>sl,cleanupAndroidNativePerfSession:()=>mf,clearAndroidImeHelperText:()=>Tt,clearAndroidTestImeRecoveryMarker:()=>rd,closeAndroidApp:()=>Ht,completeAndroidFillVerification:()=>X,createAndroidPortReverseManager:()=>Ke,createAndroidSnapshotCapture:()=>Il,createAndroidSnapshotPresentationBudget:()=>bc,createAndroidSnapshotPresentationNode:()=>gc,createAndroidWindowDumpReader:()=>cn,createDeviceAdbExecutor:()=>qe,createLocalAndroidAdbProvider:()=>Ue,dismissAndroidKeyboard:()=>Go,dismissAndroidKeyboardWithAdb:()=>Ko,doubleTapAndroid:()=>Za,ensureAndroidEmulatorBooted:()=>Gt,ensureAndroidImeHelper:()=>yt,ensureAndroidSdkPathConfigured:()=>Vt,ensureAndroidSnapshotHelper:()=>Rr,executeAndroidTouchHelperPlan:()=>Pa,executeAndroidTouchPlan:()=>Ja,fillAndroid:()=>xm,findAndroidAlertCandidate:()=>Nn,focusAndroid:()=>fo,forceStopAndroidAppWithAdb:()=>Oo,forgetAndroidSnapshotHelperInstall:()=>jr,formatAndroidInstalledPackageRequiredMessage:()=>Xt,getAndroidAppState:()=>on,getAndroidBlockingDialogObservation:()=>sn,getAndroidImeHelperDeviceKey:()=>k,getAndroidKeyboardState:()=>Wo,getAndroidKeyboardStatusWithAdb:()=>K,getAndroidScreenSize:()=>go,handleAndroidAlert:()=>_o,homeAndroid:()=>eo,inferAndroidAppName:()=>Yt,inferAndroidPackageAfterOpen:()=>Ym,inspectInstalledAndroidHelper:()=>dr,installAndroidAdbPackage:()=>Ye,installAndroidInstallablePath:()=>zo,isAmStartError:()=>Wt,isAndroidImeHelperPackage:()=>It,isAndroidPermissionPackage:()=>wn,isAndroidSnapshotPresentationFailure:()=>vc,isAndroidTestImeActive:()=>Mt,listAndroidAdbSerialsQuick:()=>ps,listAndroidAppsWithAdb:()=>Gm,longPressAndroid:()=>uo,lowerAndroidAdbInvocation:()=>$e,lowerAndroidTouchPlan:()=>Ka,makeEnsureAndroidHelperInstalled:()=>pr,normalizeAndroidTouchHelperGestureRequest:()=>za,openAndroidApp:()=>Bt,openAndroidAppWithAdb:()=>Ao,openAndroidDevice:()=>Rt,parseAndroidAdbArgv:()=>it,parseAndroidHelperManifest:()=>wr,parseAndroidLaunchComponent:()=>Ut,parseAndroidLaunchablePackages:()=>en,parseAndroidSnapshotHelperManifest:()=>wr,parseAndroidSnapshotHelperOutput:()=>Ii,parseAndroidUserInstalledPackages:()=>$t,parseInstrumentationRecords:()=>$n,parseUiHierarchyTree:()=>rl,prepareAndroidInstallArtifact:()=>Ad,pressAndroid:()=>G,pressAndroidEnter:()=>to,pressAndroidTvRemote:()=>Qa,pullAndroidAdbFile:()=>Ge,pushAndroidNotification:()=>Nd,readAndroidBlockingDialogFocus:()=>nn,readAndroidClipboardText:()=>rs,readAndroidClipboardWithAdb:()=>is,readAndroidDefaultInputMethod:()=>O,readAndroidFillTargetBeforeMutation:()=>wu,readAndroidGestureViewport:()=>Ya,readAndroidHelperManifestInteger:()=>Pt,readAndroidHelperManifestLiteral:()=>vt,readAndroidSetting:()=>nm,readAndroidTestImeRecoveryMarkers:()=>id,readAndroidTextAtPoint:()=>Su,readAndroidTextAtPointInHierarchy:()=>Ou,readAndroidTouchHelperFinalRecord:()=>Ha,readAndroidTouchHelperViewportReading:()=>Fa,readInstrumentationResultBoolean:()=>or,readInstrumentationResultNumber:()=>M,resetAndroidAdbShellProtocolProbes:()=>xn,resetAndroidFramePerfStats:()=>lf,resetAndroidImeHelperInstallCache:()=>xt,resetAndroidSnapshotHelperInstallCache:()=>Pr,resetAndroidSnapshotHelperRuntime:()=>Pl,resetAndroidSnapshotHelperSessions:()=>wa,resetAndroidTestImeActivationCacheForTests:()=>Dt,resetAndroidWindowDumpFocusMemoForTests:()=>an,resolveAndroidAdbExecutor:()=>v,resolveAndroidAdbProvider:()=>S,resolveAndroidApp:()=>Zt,resolveAndroidArchivePackageName:()=>ld,resolveAndroidHelperArtifact:()=>fr,resolveAndroidImeHelperArtifact:()=>Ft,resolveAndroidPackageForOpen:()=>Jm,resolveAndroidSnapshotHelperCaptureOptions:()=>Ei,resolveAndroidTextInjector:()=>Je,resolveAndroidTouchProvider:()=>Ve,resolveScopedAndroidAdbBackgroundTransport:()=>We,restoreAndroidTestIme:()=>ls,restoreOrphanedAndroidTestImeOnDaemonStartup:()=>fs,retireAndroidSnapshotHelperAfterContentFailure:()=>Nl,runAdbExecOut:()=>Xe,runAdbShell:()=>y,runAndroidAdb:()=>dt,runAndroidExecOut:()=>ut,runAndroidHostAdb:()=>Be,runAndroidShell:()=>E,runAndroidSnapshotHelperSessionTouchCommand:()=>Da,sampleAndroidFramePerf:()=>cf,sampleAndroidMemoryPerf:()=>Lf,screenshotAndroid:()=>pm,scrollAndroid:()=>po,selectAndroidImeHelperArtifact:()=>_t,sendAndroidImeHelperText:()=>gt,serializeAndroidAdbInvocation:()=>et,setAndroidOrientation:()=>no,setAndroidPermission:()=>mp,setAndroidSetting:()=>em,setAndroidTestImeActiveForTests:()=>bt,sleep:()=>_,snapshotAndroid:()=>Bl,startAndroidPerfettoTrace:()=>wf,startAndroidSimpleperfProfile:()=>Of,stopAndroidPerfettoTrace:()=>Tf,stopAndroidSimpleperfProfile:()=>kf,stopAndroidSnapshotHelperSession:()=>U,stopAndroidSnapshotHelperSessionForDevice:()=>Ca,typeAndroid:()=>bm,validateAndroidGestureViewport:()=>sr,validateAndroidRegularPresentation:()=>xc,verifyAndroidFilledText:()=>xu,verifyAndroidFilledTextInHierarchy:()=>Du,verifyAndroidHelperApkChecksum:()=>_r,waitForAndroidBoot:()=>zt,withAndroidAdbProvider:()=>He,withAndroidAppResolutionCacheInvalidated:()=>Jt,withAndroidHostAdbTransport:()=>Ze,writeAndroidClipboardText:()=>as,writeAndroidClipboardWithAdb:()=>os,writeAndroidSimpleperfReport:()=>Af,writeAndroidTestImeRecoveryMarker:()=>nd});async function Gm(...e){let{listAndroidAppsWithAdb:t}=await import(`./app-helpers.js`);return await t(...e)}async function Km(...e){let{androidClipboardShellSupportForResult:t}=await import(`./clipboard-shell-response.js`);return t(...e)}async function qm(...e){let{captureAndroidLogcatWithAdb:t}=await import(`./logcat.js`);return await t(...e)}async function Jm(...e){let{resolveAndroidPackageForOpen:t}=await import(`./open-target-resolution.js`);return await t(...e)}async function Ym(...e){let{inferAndroidPackageAfterOpen:t}=await import(`./open-target-resolution.js`);return await t(...e)}export{Qa as A,$a as C,uo as D,eo as E,no as M,Ja as N,G as O,Ya as P,lo as S,fo as T,as as _,bm as a,Ao as b,em as c,Go as d,Ko as f,is as g,rs as h,xm as i,po as j,to as k,Bl as l,K as m,Gm as n,pm as o,Wo as p,Wm as r,nm as s,qm as t,Rl as u,os as v,Za as w,_o as x,Oo as y};
10
+ `).replace(/\n$/,``),n=t.match(/^clipboard text:\s*(.*)$/i);return n?n[1]??``:t.trim().toLowerCase()===`null`?``:t}const G=`agent_device_ime_helper_previous_ime`,K=`agent_device_ime_helper_rebind_displaced`,q=`secure`,ns=`default_input_method`,rs={previousIme:G,rebindDisplaced:K,defaultInputMethod:ns};async function J(e){let t=await b(e,[`settings`,`get`,q,ns],{allowFailure:!0,timeoutMs:5e3});return ps(t.exitCode===0?t.stdout:``)}async function is(e){return await fs(e,G)||void 0}async function as(e,t){return(await b(e,[`settings`,`put`,q,G,t],{allowFailure:!0,timeoutMs:5e3})).exitCode===0&&await is(e)===t}async function os(e){await b(e,[`settings`,`delete`,q,G],{allowFailure:!0,timeoutMs:5e3})}async function ss(e){let t=await fs(e,G),n=await fs(e,K);if(t===void 0||n===void 0)return{kind:`unreadable`};let r=n===`1`;return t?{kind:`owned`,previousIme:t,rebindDisplaced:r}:{kind:`absent`,rebindDisplaced:r}}async function cs(e){return(await b(e,[`settings`,`put`,q,K,`1`],{allowFailure:!0,timeoutMs:5e3})).exitCode===0&&await fs(e,K)===`1`}async function ls(e){return await b(e,[`settings`,`delete`,q,K],{allowFailure:!0,timeoutMs:5e3}),await fs(e,K)===``}async function us(e,t,n){try{(t?await as(e,t):await ds(e))||S({level:`warn`,phase:`android_test_ime_record_rollback_failed`,data:{device:n,hadPriorRecord:t!==void 0}})}catch(e){S({level:`warn`,phase:`android_test_ime_record_rollback_failed`,data:{device:n,hadPriorRecord:t!==void 0,error:a(e).message}})}}async function ds(e){return await os(e),await is(e)===void 0}async function fs(e,t){let n=await b(e,[`settings`,`get`,q,t],{allowFailure:!0,timeoutMs:5e3});return n.exitCode===0?ps(n.stdout):void 0}function ps(e){let t=e.trim();return!t||t===`null`?``:t}function ms(e,t){return _s(e)?t!==`aborted`:e===`not-activated-here`&&t===`covered-confirmed`}async function hs(e,t){return await Dt(t.stateDir,e.id,async()=>{let n=await gs(e),r=t.shutdownTarget===!0?await kt(e.id,t.signal):`idle`;return ms(n.reason,r)&&await v().imeRecoveryMarkers.clear(t.stateDir,e.id),n})}async function gs(e){let t=D(e);return O.has(t)?(O.delete(t),await vs(y(e),e)):{restored:!1,reason:`not-activated-here`}}function _s(e){return e===`ok`||e===`helper-not-active`||e===`no-record`}async function vs(e,t){let n=t.id;if(O.has(D(t)))return{restored:!1,reason:`owned-by-live-session`};let r=await ss(e);if(r.kind===`unreadable`)return S({level:`warn`,phase:`android_test_ime_restore_record_unreadable`,data:{device:n}}),{restored:!1,reason:`record-unreadable`};if(r.kind===`absent`)return{restored:!1,reason:`no-record`};let{previousIme:i}=r,a=await J(e);if(a!==`com.callstack.agentdevice.imehelper/.TestInputMethodService`&&!r.rebindDisplaced)return S({level:`debug`,phase:`android_test_ime_restore_skipped`,data:{device:n,currentIme:a,previousIme:i}}),{restored:!1,previousIme:i,reason:`helper-not-active`};let o=jt(t.id),s=!1;try{await b(e,[`ime`,`set`,i],{allowFailure:!0,timeoutMs:1e4});let t=await J(e);return t===i?(s=!0,await os(e).catch(()=>{}),await ls(e).catch(()=>{}),S({phase:`android_test_ime_restored`,data:{device:n,previousIme:i}}),{restored:!0,previousIme:i,reason:`ok`}):(S({level:`warn`,phase:`android_test_ime_restore_failed`,data:{device:n,previousIme:i,afterIme:t}}),{restored:!1,previousIme:i,reason:`set-failed`})}finally{t.kind===`emulator`&&At(t.id,s),o()}}async function ys(e){let t=v().imeRecoveryMarkers,n=await t.read(e.stateDir);if(n.length===0)return;let r;try{r=new Set(await e.listSerials())}catch(e){S({level:`debug`,phase:`android_test_ime_startup_scan_failed`,data:{error:a(e).message}});return}for(let i of n){if(!r.has(i))continue;let n={platform:`android`,id:i,name:i,kind:i.startsWith(`emulator-`)?`emulator`:`device`,booted:!0};try{await Dt(e.stateDir,i,async()=>{let r=await vs(y(n),n);r.restored&&S({level:`warn`,phase:`android_test_ime_orphan_restored`,data:{device:i,previousIme:r.previousIme}}),ms(r.reason,`idle`)&&await t.clear(e.stateDir,i)})}catch(e){S({level:`debug`,phase:`android_test_ime_orphan_restore_failed`,data:{device:i,error:a(e).message}})}}}async function bs(){v();try{return(await Ve(nt([`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 xs=2e3;async function Ss(e,t,n=v().files){let r=e.ANDROID_HOME||e.ANDROID_SDK_ROOT,i=await zs(r,n),a=await un(`adb`,[`version`]),o=a===void 0?void 0:ln(a);if(!a||!o)return Rs(r,i);let s=t===`win32`?void 0:Ns(a);return s?Ps({windowsAdb:s,sdkRoot:r,versionLine:o}):Fs({license:i,sdkRoot:r,versionLine:o})}async function Cs(e,t){if(e.platform!==`android`)return[];let n=y(e,t.transportOverrides.androidAdb),r=[];return t.shouldProbeMetro&&r.push(await ks(n,e.id,t.metroPort)),r.push(await ws(n,e)),r}async function ws(e,t){try{let n=await J(e),r=yt(t);return n===await Ts()&&!r?await Es(e,t,n):Ds(t,n,r)}catch(e){return Os(e)}}async function Ts(){try{return(await wt()).manifest.serviceComponent}catch{return}}async function Es(e,t,n){let r=(await b(e,[`settings`,`get`,`secure`,rs.previousIme],{allowFailure:!0,timeoutMs:xs})).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 Ds(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 Os(e){let t=a(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 ks(e,t,n){try{let r=await e([`reverse`,`--list`],{allowFailure:!0,timeoutMs:xs}),i=`tcp:${n} tcp:${n}`,a=r.stdout.includes(i);return{id:`android-reverse`,status:a?`pass`:`warn`,summary:a?`Android adb reverse exists for Metro port ${n}.`:`Android adb reverse is missing for Metro port ${n}.`,command:a?void 0:`adb -s ${t} reverse tcp:${n} tcp:${n}`,evidence:{stdout:r.stdout.trim()}}}catch(e){let t=a(e);return{id:`android-reverse`,status:`warn`,summary:`Could not inspect Android adb reverse mappings.`,hint:t.message,evidence:{code:t.code}}}}function As(e){return/^Installed as (.+)$/m.exec(e)?.[1]?.trim()}function js(e){return/^(?:[A-Za-z]:[\\/]|\\\\)/.test(e)}function Ms(e){return/^Running on Windows\b/m.test(e)}function Ns(e){let t=As(e);if(t&&js(t))return{detectedVia:`installed-as-path`,adbPath:t};if(Ms(e))return{detectedVia:`running-on-line`,adbPath:void 0}}function Ps(e){let{adbPath:t,detectedVia:n}=e.windowsAdb;return{id:`toolchain`,status:`fail`,summary:`Android toolchain: adb on PATH${t?` (${t})`:``} is a Windows binary, which cannot use this host's file paths.`,hint:`adb must be a native binary for this host: install this host's Android platform-tools, put them first on PATH, and point ANDROID_HOME at an SDK on this host's filesystem. Under WSL that means a Linux SDK, not one under /mnt/<drive>.`,evidence:{reason:`android_adb_windows_binary_on_posix_host`,detectedVia:n,adbPath:t??null,adbVersion:e.versionLine,androidHome:e.sdkRoot??null}}}function Fs(e){return{id:`toolchain`,status:Is(e),summary:e.versionLine?`Android toolchain: ${e.versionLine}; ${Ls(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 Is(e){return e.versionLine&&e.sdkRoot&&e.license!==`missing`?`pass`:`info`}function Ls(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 zs(e,t){if(!e)return`unknown`;try{return await t.access(k.join(e,`licenses`,`android-sdk-license`)),`accepted`}catch{return`missing`}}function Bs(e,t){if(!t)return{expected:e,actual:null,failureReason:`text_mismatch`,targetInput:null,actualInput:null};let n=Ws(t),r={failureReason:t.reason??`text_mismatch`,targetInput:Hs(t.targetInput),actualInput:Hs(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 Y(e){return e?e.password?!0:Vs(e.text):!1}function Vs(e){return e?Array.from(e).every(Us):!1}function Hs(e){if(!e)return null;let t=Y(e);return{...e,text:t?null:e.text,...t?{textRedacted:!0}:{}}}function Us(e){return e===`•`||e===`*`||e===`●`}function Ws(e){return e.masked===!0||Y(e.targetInput)||Y(e.actualInput)}const Gs=new WeakMap;function Ks(e,t){return t&&Gs.set(e,t),e}function qs(e){return Gs.get(e)}function Js(e){return e.clickable}function Ys(e){return e.focusable||e.focused===!0}function Xs(e){return Js(e)||Ys(e)}function Zs(e){let t=e.trim();return t?/^[\w.]+:id\/[\w.-]+$/i.test(t):!1}function Qs(e,t){return{raw:e,...t?{effectiveRect:t}:{}}}function $s(e,t,n){if(!e)return;let r=nc(e);return t&&(r=tc(r,t)),n&&(r=tc(r,n)),r}function ec(e){return{...e.raw,...e.effectiveRect?{rect:e.effectiveRect}:{rect:void 0},hittable:e.raw.hittable===!0&&me(e.effectiveRect)?!0:void 0}}function tc(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 nc(e){return{x:e.x,y:e.y,width:Math.max(0,e.width),height:Math.max(0,e.height)}}function rc(e,t){let n=new Set;return ic(e,n,t),oc(e,n,t),n}function ic(e,t,n){for(let r of e.children){if(n?.check(`work`),r.visibleToUser===!1){t.add(r);continue}ic(r,t,n)}}function ac(e,t,n){return n?.check(`work`),e.children.filter(e=>!t.has(e)&&e.visibleToUser!==!1)}function oc(e,t,n){let r=ac(e,t,n).filter(cc);if(r.length<2)return;let i=r.filter(e=>lc(e)&&uc(e));if(i.length===0)return;let a=sc(i);for(let r of ac(e,t,n))n?.check(`work`),lc(r)&&(uc(r)&&(a===void 0||r.windowLayer===a)||t.add(r))}function sc(e){let t=e.map(e=>e.windowLayer).filter(e=>e!==void 0);return t.length>0?Math.max(...t):void 0}function cc(e){return e.windowIndex!==void 0||e.windowType!==void 0}function lc(e){return e.windowType===1}function uc(e){return e.windowActive===!0||e.windowFocused===!0}function dc(e,t,n,r,i){let a=new Set(e.sourceNodes),o=pc(t,i),s=fc(o,n,mc(o,a,i),i);if(!s)return{nodes:[],sourceNodes:[]};let c=new Set(pc([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:ge(d.map(t=>e.nodes[t]),u),sourceNodes:d.map(t=>e.sourceNodes[t])}}function fc(e,t,n,r){for(let i of e)if(r.check(`work`),_e(i,t)&&n.has(i))return i;return null}function pc(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 mc(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 hc(e,t,n,r,i){if(e.visibleToUser===!1)return!1;let a=gc(e);return t.interactiveOnly?_c(e,a,n,r,i):a.isStructural||a.isVisual?bc(e,a,r):!0}function gc(e){let t=Sc(e.type),n=!!(e.label&&e.label.trim().length>0),r=!!(e.identifier&&e.identifier.trim().length>0);return{type:t,hasMeaningfulText:n&&!Zs(e.label??``),hasMeaningfulId:r&&!Zs(e.identifier??``),isStructural:Cc(t),isVisual:t===`imageview`||t===`imagebutton`}}function _c(e,t,n,r,i){return yc(e)?!1:Xs(e)||fe(t.type)&&r?!0:vc(t,n,r,i)}function vc(e,t,n,r){return!e.hasMeaningfulText&&!e.hasMeaningfulId||e.isVisual||e.isStructural&&!r&&!t?!1:t||n||r}function yc(e){return!!(e.rect&&(e.rect.width<=0||e.rect.height<=0))}function bc(e,t,n){return Xs(e)||t.hasMeaningfulText||t.hasMeaningfulId?!0:n}function xc(e){if(!e)return!1;let t=Sc(e);return t.includes(`recyclerview`)||t.includes(`listview`)||t.includes(`gridview`)}function Sc(e){return e?e.toLowerCase():``}function Cc(e){let t=e.split(`.`).pop()??e;return t.includes(`layout`)||t===`viewgroup`||t===`view`}function wc(e,t,n,r){return{...Qs(e,t),...n?{clipsDescendants:!0}:{},...r?{windowRect:r}:{}}}const Tc=`ANDROID_SNAPSHOT_PRESENTATION_FAILED`;var X=class extends Error{code=Tc;qualityReasonCode=`presentation-failed`;details;analysis;constructor(e,t,n){super(e),this.name=`AndroidSnapshotPresentationFailure`,this.details=t,this.analysis=n}};function Ec(e){return e instanceof X?e.code===Tc:!!(e&&typeof e==`object`&&e.code===Tc)}var Dc=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()+Mc()}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 Oc(e,t){return new Dc(e??{},t)}function kc(e,t,n){let r=new Map;for(let i of e){n.check(`regular-invariant`);let e=Ac(i,r,t),a=i.effectiveRect;if(!a||!me(a)){if(ec(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&&!jc(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 Ac(e,t,n){let r=e.raw.parentIndex;return r===void 0?e.windowRect??n:t.get(r)??e.windowRect??n}function jc(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 Mc(){return 250}function Nc(e,t,n){let r=n.depth??1/0,i=pe(n.scope),a=Zc(e),o=Oc(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=Wc(e,o),s.hidden=n.raw?new Set:rc(e,o);for(let t of e.children)if(Fc(s,t,0),s.truncated)break;n.raw||kc(s.presentationNodes,s.viewport,o);let t=s.nodes,a=new Map(s.sourceNodes.map((e,t)=>[e,t])),{nodes:c,sourceNodes:l}=i?dc(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:Pc(s.sourceNodes)},analysis:s.analysis};return s.truncated?{...u,truncated:!0}:u}catch(e){throw Ec(e)&&(e.analysis??=s.analysis),e}}function Pc(e){let t=new Map,n=new Map;for(let[r,i]of e.entries()){let e=qs(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 Fc(e,t,n,r,i=!1,a=!1,o=!1,s,c){if(e.presentationBudget.check(`work`),Ic(e,t,n))return;let l=t.windowRect??s??e.viewport,u=Lc(e,t,c,l),d=Rc(e,t,r,i,a,o,u,l),f=i||Xs(t),p=a||xc(t.type),m=zc(e,t,u,c);Bc(e,t,n,d,f,p,o||fn(t.identifier),l,m)}function Ic(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 Lc(e,t,n,r){return e.options.raw?t.rect:$s(t.rect,r,n)}function Rc(e,t,n,r,i,a,o,s){return!e.options.raw&&!hc(t,e.options,r,qc(e,t),i)?n:Vc(e,t,n,a||fn(t.identifier),o,s)}function zc(e,t,n,r){return e.options.raw||!Gc(t)?r:n}function Bc(e,t,n,r,i,a,o,s,c){for(let l of t.children)if(Fc(e,l,n+1,r,i,a,o,s,c),e.truncated)return}function Vc(e,t,n,r,i,a){let o=e.nodes.length;return e.sourceNodes.push(t),Uc(e,t,Hc(e,t,n,r),i,a),o}function Hc(e,t,n,r){return{index:e.nodes.length,type:t.type??void 0,label:t.label??void 0,value:t.value??void 0,...t.passiveFacts,identifier:t.identifier??void 0,bundleId:t.packageName??void 0,rect:t.rect,focused:t.focused,visibleToUser:t.visibleToUser,hittable:Xs(t)||void 0,depth:Kc(e.nodes,n),parentIndex:n,...Jc(t,e.hidden),...r?{systemChrome:!0}:{}}}function Uc(e,t,n,r,i){let a=wc(n,r,!e.options.raw&&Gc(t),i);e.presentationNodes.push(a),e.nodes.push(e.options.raw?a.raw:ec(a))}function Wc(e,t){let n=[],r=[...e.children];for(;r.length>0;){t.check(`work`);let e=r.pop();me(e.windowRect)&&n.push(e.windowRect),r.push(...e.children)}return ve(n)??void 0}function Gc(e){return e.scrollable===!0&&fe(e.type)}function Kc(e,t){return t===void 0?0:(e[t]?.depth??-1)+1}function qc(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&&(Xs(n)||qc(e,n)))return e.interactiveDescendantMemo.set(t,!0),!0;return e.interactiveDescendantMemo.set(t,!1),!1}function Jc(e,t){return Yc(e,t)?{...e.canScrollBackward?{hiddenContentAbove:!0}:{},...e.canScrollForward?{hiddenContentBelow:!0}:{}}:{}}function Yc(e,t){if(!e.scrollable||!fe(e.type)||`${e.type??``}`.toLowerCase().includes(`horizontalscrollview`))return!1;let n=Xc(e,t);return!(n&&n.horizontal>n.vertical&&n.horizontal>16)}function Xc(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 Zc(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 Qc(){let e=[],t=()=>e.at(-1)===!0;return{open(n,r){let i=t()||fn(n);return r||e.push(i),i},close(){e.pop()}}}function*$c(e){let t=/<node\b[^>]*>|<\/node>/g,n=Qc(),r=t.exec(e);for(;r;){let i=r[0];if(i.startsWith(`</node`))n.close();else{let e=el(i);yield n.open(e.resourceId,i.endsWith(`/>`))?{...e,systemChrome:!0}:e}r=t.exec(e)}}function el(e){let t=tl(e),n=pn(t.bounds);return{...t,...n?{rect:n}:{}}}function tl(e){let t=nl(e),n=e=>ul(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=pn(n(t));return r===void 0?{}:{[e]:r}},s=(e,t)=>{let r=n(t);return r===null||r===``?{}:{[e]:r}},c=(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`),...c(`editable`,`editable`),...a(`selectionStart`,`selection-start`),...a(`selectionEnd`,`selection-end`),...c(`hintShowing`,`hint-showing`),...s(`hint`,`hint`),...c(`visibleToUser`,`visible-to-user`),...c(`selected`,`selected`),...c(`heading`,`heading`),...s(`roleDescription`,`role-description`),...c(`checked`,`checked`),...a(`drawingOrder`,`drawing-order`),...c(`scrollable`,`scrollable`),...c(`canScrollForward`,`can-scroll-forward`),...c(`canScrollBackward`,`can-scroll-backward`),...a(`windowIndex`,`window-index`),...a(`windowType`,`window-type`),...a(`windowLayer`,`window-layer`),...c(`windowActive`,`window-active`),...c(`windowFocused`,`window-focused`),...o(`windowRect`,`window-bounds`),...c(`windowRegionRect`,`window-region-rect`)}}function nl(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=rl(e,i,r);if(!n)break;t.set(n.name,n.value),i=n.nextCursor}return t}function rl(e,t,n){if(t=al(e,t,n),t>=n||ol(e[t]))return;let r=t;t=il(e,t,n);let i=e.slice(r,t);if(t=al(e,t,n),!i||e[t]!==`=`)return;t=al(e,t+1,n);let a=e[t];if(!sl(a))return;let o=t+1,s=e.indexOf(a,o);if(!(s<0||s>=n))return{name:i,value:mn(e.slice(o,s)),nextCursor:s+1}}function il(e,t,n){for(;t<n&&!ll(e[t]??``);)t+=1;return t}function al(e,t,n){for(;t<n&&cl(e[t]??``);)t+=1;return t}function ol(e){return e===`/`||e===`>`}function sl(e){return e===`"`||e===`'`}function cl(e){return e===` `||e===`
12
+ `||e===`\r`||e===` `}function ll(e){return e===`=`||e===`/`||e===`>`||cl(e)}function ul(e,t){return e.get(t)??null}function dl(e){let t={type:null,label:null,value:null,passiveFacts:{},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=el(t),o=n.at(-1),s=fl(a,o.depth+1,o);o.children.push(s),t.endsWith(`/>`)||n.push(s),i=r.exec(e)}return t}function fl(e,t,n){let r=e.text||e.desc;return Ks({type:e.className,label:r,value:e.text,passiveFacts:{contentDescription:e.desc&&e.desc!==r?e.desc:void 0,enabled:e.enabled,selected:e.selected,heading:e.heading,roleDescription:e.roleDescription,checked:e.checked,editable:e.editable,password:e.password,hintShowing:e.hintShowing,placeholder:e.hint,selectionStart:e.selectionStart,selectionEnd:e.selectionEnd},identifier:e.resourceId,packageName:e.packageName,rect:e.rect,focused:e.focused,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,windowRegionRect:e.windowRegionRect,depth:t,parentIndex:void 0,children:[]},e.drawingOrder===void 0?void 0:{parent:n,order:e.drawingOrder})}function pl(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 ml=new Set([`android`,`com.android.systemui`]);function hl(e,t,n={}){if(t.backend!==`android-helper`)return{outcome:`ok`};let r=El(e,n.foregroundAppPackage);return vl(r,t)?gl(r,t,`empty-helper-output`,`Android snapshot helper returned no accessibility nodes`):wl(r)?{outcome:`ok`}:_l(r)?{outcome:`system-surface-only`}:yl(r)?{outcome:`ok`}:bl(r)?gl(r,t,`content-poor-app-window`,`Android snapshot helper returned insufficient foreground app content`):xl(r)||Sl(r,t)?gl(r,t,`content-poor-app-window`,`Android snapshot helper returned insufficient application window content`):Cl(r)?gl(r,t,`system-window-only`,`Android snapshot helper returned only non-application windows`):{outcome:`ok`}}function gl(e,t,n,r){return{outcome:`unusable`,decision:Tl(e,t,n,r)}}function _l(e){return e.windowRootCount>0&&e.applicationWindowRootCount===0&&e.activeSystemSurfaceMeaningfulNodeCount>=3}function vl(e,t){return e.nodeCount===0||t.nodeCount===0||t.rootPresent===!1}function yl(e){return bl(e)&&e.inputMethodMeaningfulNodeCount>=2}function bl(e){let t=e.foregroundAppMeaningfulNodeCount;return t===void 0?!1:t===0?e.applicationMeaningfulNodeCount<2:t<2&&e.meaningfulNodeCount>t}function xl(e){return e.foregroundAppMeaningfulNodeCount===void 0&&e.applicationWindowRootCount>0&&e.applicationMeaningfulNodeCount<2}function Sl(e,t){return e.foregroundAppMeaningfulNodeCount===void 0&&e.windowRootCount===0&&(t.windowCount??0)>1&&e.nonSystemMeaningfulNodeCount<2}function Cl(e){return e.windowRootCount>0&&e.applicationWindowRootCount===0||e.windowRootCount===0&&e.nodeCount>0&&e.systemUiNodeCount===e.nodeCount}function wl(e){return e.hasAlertButtonIdentifier&&e.hasAlertContentIdentifier}function Tl(e,t,n,r){return{reason:n,failureReason:r,diagnostics:Bl(e,t)}}function El(e,t){let n=Dl(t);for(let t of $c(e))Ol(n,t);return Fl(n)}function Dl(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 Ol(e,t){e.nodeCount+=1,zl(t.packageName)&&(e.systemUiNodeCount+=1),t.visibleToUser!==!1&&kl(e,t.resourceId),Al(e,t),jl(e,t)}function kl(e,t){let n=Mn(t);n===`button`&&(e.hasAlertButtonIdentifier=!0),n===`content`&&(e.hasAlertContentIdentifier=!0)}function Al(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 jl(e,t){Il(t)&&(e.meaningfulNodeCount+=1,Ml(e,t),Pl(e,t))}function Ml(e,t){e.currentWindowType===1&&!Rl(t.packageName)&&(e.applicationMeaningfulNodeCount+=1),Nl(e)&&!dn(t)&&(e.activeSystemSurfaceMeaningfulNodeCount+=1)}function Nl(e){return e.currentWindowType!==void 0&&e.currentWindowType!==1&&e.currentWindowActiveOrFocused===!0}function Pl(e,t){Rl(t.packageName)||(e.nonSystemMeaningfulNodeCount+=1),le({packageName:t.packageName,resourceId:t.resourceId})&&(e.inputMethodMeaningfulNodeCount+=1),e.foregroundAppPackage!==void 0&&t.packageName===e.foregroundAppPackage&&(e.foregroundAppMeaningfulNodeCount=(e.foregroundAppMeaningfulNodeCount??0)+1)}function Fl(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 Il(e){return e.visibleToUser===!1?!1:Ll(e.text)||Ll(e.desc)||Ll(e.resourceId)}function Ll(e){return e!==null&&e.trim()!==``}function Rl(e){return e===null||ml.has(e)}function zl(e){return e!==null&&ml.has(e)}function Bl(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 Vl(e){let t=await V(e.deviceKey,{resetRuntime:!0,signal:e.signal,cause:e.cause});e.signal?.throwIfAborted(),t||await Hl(e.adb,e.packageName)}async function Hl(e,t){await Ci({adb:e,packageName:t}),await _(150),g({level:`debug`,phase:`android_snapshot_helper_runtime_reset`,data:{packageName:t}})}const Ul=Symbol(`androidSnapshotCaptureEvidence`);function Wl(e,t){return Object.defineProperty(e,Ul,{value:t}),e}function Gl(e){return ye({x:0,y:0,width:e.displayWidth??NaN,height:e.displayHeight??NaN})}function Kl(e){let t={...e,backend:`android`,producer:`android-uiautomator`},n=e[Ul];return ue(t,n.clickability),n.occlusionContext&&oe(t,n.occlusionContext),t}async function ql(e,t={}){let n=x(e,t.helperAdb).exec;return(await tu(e,t,n)).xml}async function Jl(e,t={}){let n=x(e,t.helperAdb).exec,r=await tu(e,t,n),i=Gl(r.helperMetadata),a=r.xml,o=dl(a),s=Zl(r.metadata,o),c=Eu(o,r.metadata),l={...t,androidPresentation:{...t.androidPresentation,deadlineAtMs:t.androidPresentation?.deadlineAtMs??Date.now()+250}};try{let e=Nc(o,void 0,l),n=Xl(e.truncated,r.metadata);t.interactiveOnly&&t.includeHiddenContentHints!==!1&&eu({options:l,tree:o,xml:a,interactiveSnapshot:e});let{sourceNodes:u,occlusionContext:d,...f}=e;return Wl({...f,...$l(n),androidSnapshot:s,quality:{state:`healthy`,backend:`android-helper`},keyboard:c,...i?{viewport:i}:{}},{clickability:pl(e),occlusionContext:d})}catch(e){if(!Ec(e))throw e;return Yl({failure:e,androidSnapshot:s,keyboard:c,...i?{viewport:i}:{}})}}function Yl(e){return Wl({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},keyboard:e.keyboard,...e.viewport?{viewport:e.viewport}:{}},{clickability:{kind:`exact`,provider:`android-helper`,clickableByNodeIndex:new Map}})}function Xl(e,t){return e===!0||t.helperTruncated===!0||e}function Zl(e,t){return Ql(t)===!1?{...e,occlusionScanUnavailable:!0}:e}function Ql(e){let t=[...e.children];if(t.length!==0){for(;t.length>0;){let e=t.pop();if(qs(e)!==void 0)return!0;t.push(...e.children)}return!1}}function $l(e){return e===!0?{truncated:!0}:{}}function eu(e){if(wu(e.interactiveSnapshot.nodes).size>0||Cu(e.xml))return;let t=Nc(e.tree,void 0,{...e.options,interactiveOnly:!1});Tu(Me(u(t.nodes)),t,e.interactiveSnapshot)}async function tu(e,t,n){let r=x(e,t.helperAdb),i=await h(`android_snapshot_helper_artifact_resolution`,async()=>await xu(t.helperArtifact??r.snapshotHelperArtifact));if(i.artifact)return await nu(e,t,n,i.artifact);throw g({level:`error`,phase:`android_snapshot_helper_unavailable`,data:{reason:i.errorReason??`artifact_not_found`}}),Su(i.errorReason)}async function nu(e,t,n,r){let i=li(e),a=au(t,i);try{return await ru({options:t,adb:n,adbProvider:x(e,t.helperAdb),artifact:r,helperDeviceKey:i})}finally{a&&await V(i)}}async function ru(e){let{options:t}=e,n=iu(t),r=async(n,r)=>await fu({contentRecovery:n,attempts:r,helperDeviceKey:e.helperDeviceKey,artifact:e.artifact,adb:e.adb,signal:t.signal,retireHelper:t.transient===void 0}),i;for(let a=0;;a+=1){if(i&&(await du(t.signal),Date.now()>=n))return await r(i,a);let o=await uu({...e,attempt:a,previousContentReason:i?.reason});if(o.outcome===`captured`)return o.capture;if(a+1>=3||Date.now()>=n)return await r(o.decision,a+1);i=o.decision}}function iu(e){return Math.min(Date.now()+1e4,e.transient?.settleBy??1/0)}function au(e,t){return e.transient?ra(t)===void 0:e.helperSessionScope!==`daemon-session`}function ou(e){return e.transient?`current-only`:e.helperInstallPolicy??`missing-or-outdated`}async function su(e,t,n,r,i){let a=await h(`android_snapshot_helper_install`,async()=>await Rr({adb:t,adbProvider:n,artifact:r,deviceKey:i,installPolicy:ou(e),timeoutMs:3e4,signal:e.signal}),{packageName:r.manifest.packageName,versionCode:r.manifest.versionCode,installPolicy:ou(e)});return g({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 cu(e){let{signal:t,adb:n,adbProvider:r,artifact:i,helperDeviceKey:o}=e,s=Ei({adb:n,adbProvider:r,artifact:i,deviceKey:o,signal:t});try{let e=await h(`android_snapshot_helper_session_capture`,async()=>await ya(s),{packageName:i.manifest.packageName,version:i.manifest.version,timeoutMs:Sr});if(e)return e}catch(e){if(t?.throwIfAborted(),pi(e))throw e;g({level:`warn`,phase:`android_snapshot_helper_session_fallback`,data:{reason:a(e).message}}),await Hl(n,i.manifest.packageName)}return await h(`android_snapshot_helper_capture`,async()=>await Ti(s),{packageName:i.manifest.packageName,version:i.manifest.version,timeoutMs:Sr,commandTimeoutMs:Cr})}function lu(e,t,n){return{xml:e.xml,helperMetadata:e.metadata,metadata:{backend:`android-helper`,pixelDensity:e.metadata.pixelDensity,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,missingRootWindowTypes:e.metadata.missingRootWindowTypes,nodeCount:e.metadata.nodeCount,helperTruncated:e.metadata.truncated,elapsedMs:e.metadata.elapsedMs}}}async function uu(e){let{options:t,adb:n,adbProvider:r,artifact:i,helperDeviceKey:a,attempt:o}=e,s;try{let e=await su(t,n,r,i,a);e.installed&&await V(a),s=lu(await cu({signal:t.signal,adb:n,adbProvider:r,artifact:i,helperDeviceKey:a}),i,e.reason)}catch(e){if(t.signal?.throwIfAborted(),Nr(e))throw e;return{outcome:`captured`,capture:await mu({error:e,helperDeviceKey:a,artifact:i,adb:n})}}let c=hl(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&&g({phase:`android_snapshot_helper_content_recaptured`,data:{attempts:o+1,recoveredFromReason:e.previousContentReason}}),{outcome:`captured`,capture:{xml:s.xml,helperMetadata:s.helperMetadata,metadata:l?{...s.metadata,systemSurfaceOnly:!0}:s.metadata}}}async function du(e){e?.throwIfAborted(),await _(250),e?.throwIfAborted()}async function fu(e){throw g({level:`error`,phase:`android_snapshot_helper_content_invalid`,data:{reason:e.contentRecovery.reason,failureReason:e.contentRecovery.failureReason,attempts:e.attempts,...e.contentRecovery.diagnostics}}),e.retireHelper&&await Vl({adb:e.adb,deviceKey:e.helperDeviceKey,packageName:e.artifact.manifest.packageName,signal:e.signal,cause:e.contentRecovery.failureReason}),pu(e.contentRecovery,e.attempts)}function pu(e,t){return new r(`COMMAND_FAILED`,e.failureReason,{...e.diagnostics,androidSnapshotHelperFailureReason:e.reason,attempts:t,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 mu(e){let t=hu(e.error);throw g({level:`error`,phase:`android_snapshot_helper_failed`,data:{reason:t}}),await V(e.helperDeviceKey),await Hl(e.adb,e.artifact.manifest.packageName),jr({deviceKey:e.helperDeviceKey,packageName:e.artifact.manifest.packageName,versionCode:e.artifact.manifest.versionCode}),gu(e.error,t)}function hu(e){let t=a(e),n=bu(t.details?.helper);if(n&&n!==t.message)return`${t.message}: ${n}`;if(n)return n;let r=(typeof t.details?.stderr==`string`?t.details.stderr.trim():``).split(/\r?\n/).find(e=>e.trim());return r?`${t.message}: ${r}`:t.message}function gu(e,t){let n=a(e),i=_u(n);return new r(c(n.code),`Android snapshot helper failed: ${t}`,{...n.details,...yu(n),androidSnapshotHelperFailureReason:t,...i?{androidCaptureFailureReason:i}:{},hint:vu(n,i)},e)}function _u(e){return It(e)}function vu(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 yu(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 bu(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 xu(e){if(e)return{artifact:e};let t=Re(),n=k.join(ze(),`android`,`snapshot-helper`,`dist`),r=k.join(n,`agent-device-android-snapshot-helper-${t}.manifest.json`);try{await v().files.access(r)}catch{return{}}try{let e=wr(JSON.parse(await v().files.readText(r))),t=k.join(n,e.assetName??`agent-device-android-snapshot-helper-${e.version}.apk`);return await v().files.access(t),{artifact:{apkPath:t,manifest:e}}}catch(e){return{errorReason:a(e).message}}}function Su(e){let t=e??`the bundled helper artifact was not found`;return new r(`COMMAND_FAILED`,`Android snapshot helper is unavailable: ${t}`,{androidSnapshotHelperFailureReason:t,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 Cu(e){return e.includes(` can-scroll-forward=`)||e.includes(` can-scroll-backward=`)}function wu(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 Tu(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))}}function Eu(e,t){let n=e.children,r=n.filter(e=>e.windowType===2),i=[];for(let{windowRect:e,windowRegionRect:t}of r){if(t===!1)return{kind:`unmeasurable`,reason:`window-region-not-rectangular`};if(me(e))i.push(e);else if(!Du(e))return{kind:`unmeasurable`,reason:`window-bounds-unavailable`}}return t.missingRootWindowTypes?.includes(2)?{kind:`unmeasurable`,reason:`window-root-unavailable`}:i.length>0?{kind:`visible`,frame:be(i)}:t.captureMode!==`interactive-windows`||n.some(e=>e.windowType===void 0)?{kind:`unmeasurable`,reason:`window-list-unavailable`}:t.helperTruncated===!0?{kind:`unmeasurable`,reason:`capture-truncated`}:{kind:`absent`}}function Du(e){return!e||![e.x,e.y,e.width,e.height].every(Number.isFinite)?!1:e.width===0||e.height===0}const Ou=Object.freeze({now:()=>Date.now(),sleep:_});async function ku(e,t,n,r,i={},a=Ou){let o=await Xu(e),s=a.now()+1500,c=null;for(;;){let l=await Bu(e,t,n,r,o,i);if(l.reason===`ime_capture`)return l;let u=s-a.now();if(l.ok&&c?.ok||u<=0)return l;c=l,await a.sleep(Math.min(150,u))}}async function Au(e,t,n,r={}){return Lu(await ql(e,r),t,n)}async function ju(e,t,n,r){let i=await Xu(e);return Vu(await ql(e,r),t,n,i).targetInput}async function Mu(e,t,n,r={}){try{return await ju(e,t,n,r)}catch(e){return g({level:`warn`,phase:`android_fill_pre_action_target_capture_failed`,data:{error:e instanceof Error?e.message:String(e)}}),null}}function Nu(e,n,i){if(i?.ok)return;let a=i?Fu(e,n,i):null;if(a)return a;throw t(new r(`COMMAND_FAILED`,Ru(i),zu(e,i)),`unknown`)}function Pu(e,t){if(e.ok)return!1;let n=e.actualInput;return n&&(n.hintShowing===!0||n.text===null)?!0:t?.text!=null&&e.actual===t.text}function Fu(e,t,n){let r=n.targetInput,i=n.actualInput;if(e.length===0||n.reason===`ime_capture`||Pu(n,t)||!t||!r||!i||Y(t)||Y(r)||Y(i)||!nd(t,r)||!nd(t,i))return null;let a=rd(t);return g({level:`warn`,phase:`android_fill_verification_unconfirmed`,data:{target:a}}),{verification:`unconfirmed`,requested:e,before:t.text,after:n.actual,target:a}}function Iu(e,t,n,r,i={}){let a=Vu(e,t,n,i);return Hu(a)?{ok:!1,actual:a.actualInput?.text??null,reason:`ime_capture`,targetInput:a.targetInput,actualInput:a.actualInput}:Uu(a,r)??Wu(a,r)}function Lu(e,t,n){return Vu(e,t,n).targetInput?.text??null}function Ru(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 zu(e,t){let n=Bs(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 Bu(e,t,n,r,i,a){return Iu(await ql(e,a),t,n,r,i)}function Vu(e,t,n,r={}){let i={focusedEdit:null,editAtPoint:null,anyAtPoint:null};for(let a of $c(e)){let e=Yu(a,r);e&&Zu(i,e,t,n)}return $u(i)}function Hu(e){let{targetInput:t,actualInput:n}=e;return!t||!n||n===t?!1:n.inputMethodOwned&&!t.inputMethodOwned}function Uu(e,t){let n=e.actualInput;if(!n||!td(n))return null;let r=n.text??null,i=Array.from(Gu(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 Wu(e,t){let n=e.actualInput;return{ok:n!==null&&Ku(Gu(n),t),actual:n?.text??null,reason:`text_mismatch`,targetInput:e.targetInput,actualInput:n}}function Gu(e){return e.hintShowing?``:e.text??``}function Ku(e,t){if(e===t)return!0;if(t.length===0)return!1;let n=qu(e),r=qu(t);return!n||!r?!1:!!(n===r||Ju(n,r))}function qu(e){return e.replaceAll(/\s+/g,` `).trim()}function Ju(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 Yu(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:le({packageName:e.packageName,resourceId:e.resourceId,activeInputMethodPackage:t.activeInputMethodPackage}),area:r,editText:ed(e.className??``),hintShowing:e.hintShowing===!0,placeholder:e.hint??null}}async function Xu(e){try{return{activeInputMethodPackage:(await Lo(e)).inputMethodPackage}}catch(e){return g({level:`warn`,phase:`android_fill_verification_input_method_probe_failed`,data:{error:e instanceof Error?e.message:String(e)}}),{}}}function Zu(e,t,n,r){let i=he(t.rect,n,r);if(i&&t.editText&&(e.editAtPoint=Qu(e.editAtPoint,t)),t.focused&&t.editText){e.focusedEdit=Qu(e.focusedEdit,t);return}i&&t.text&&(e.anyAtPoint=Qu(e.anyAtPoint,t))}function Qu(e,t){return e&&e.area<t.area?e:t}function $u(e){let t=e.editAtPoint??e.anyAtPoint;return{targetInput:t,actualInput:(e.focusedEdit?.text?e.focusedEdit:null)??t}}function ed(e){let t=e.toLowerCase();return t.includes(`edittext`)||t.includes(`textfield`)}function td(e){return Y(e)}function nd(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 rd(e){return{resourceId:e.resourceId,className:e.className,packageName:e.packageName,rect:e.rect}}async function id(e,t){return await hn(t.stateDir),await Dt(t.stateDir,e.id,async()=>await od(e,t))}function ad(e){let t=n(e).details?.hint;return{outcome:`helper-unavailable`,reason:a(e).message,...typeof t==`string`?{hint:t}:{}}}async function od(e,t){let n=v().imeRecoveryMarkers,r=y(e),i=x(e),a=D(e),o;try{o=await vt(i),await Ct({adb:r,adbProvider:i,artifact:o,deviceKey:a})}catch(e){return ad(e)}let{manifest:s}=o,c=await J(r);if(c===s.serviceComponent)return await sd(e,s,t.stateDir);let l=await ss(r);if(l.kind===`unreadable`)return S({level:`warn`,phase:`android_test_ime_record_unreadable`,data:{device:e.id}}),{outcome:`settled`,activated:!1,alreadyActive:!1,persistFailed:!0,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName};let{previousIme:u,priorPersistedIme:d}=cd(l,c);if(!await as(r,u))return await us(r,d,e.id),S({level:`warn`,phase:`android_test_ime_persist_failed`,data:{device:e.id,previousIme:u}}),{outcome:`settled`,activated:!1,alreadyActive:!1,persistFailed:!0,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName};let f=(await n.read(t.stateDir)).includes(e.id);if(!await n.write(t.stateDir,e.id))return await us(r,d,e.id),S({level:`warn`,phase:`android_test_ime_marker_persist_failed`,data:{device:e.id,previousIme:u}}),{outcome:`settled`,activated:!1,alreadyActive:!1,persistFailed:!0,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName};await b(r,[`ime`,`enable`,s.serviceComponent],{allowFailure:!0,timeoutMs:1e4});let p=await b(r,[`ime`,`set`,s.serviceComponent],{allowFailure:!0,timeoutMs:1e4}),m=await J(r);if(m!==s.serviceComponent)return O.delete(a),await us(r,d,e.id),f||await n.clear(t.stateDir,e.id),S({level:`warn`,phase:`android_test_ime_activate_failed`,data:{device:e.id,activeIme:m,stderr:p.stderr.trim()}}),{outcome:`settled`,activated:!1,alreadyActive:!1,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName};let ee={stateDir:t.stateDir,rebindUnconfirmed:l.rebindDisplaced};return O.set(a,ee),l.rebindDisplaced&&(ee.rebindUnconfirmed=!await ls(r)),S({phase:`android_test_ime_activated`,data:{device:e.id,previousIme:u}}),{outcome:`settled`,activated:!0,alreadyActive:!1,previousIme:u,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName}}async function sd(e,t,n){let r=y(e),i=D(e),a=await v().imeRecoveryMarkers.write(n,e.id),o=await ss(r);if(a){let e=o.kind===`unreadable`||o.rebindDisplaced;O.set(i,{stateDir:n,rebindUnconfirmed:e})}let s=o.kind===`owned`?o.previousIme:void 0;return{outcome:`settled`,activated:!1,alreadyActive:!0,...a?{}:{persistFailed:!0},previousIme:s,helperServiceComponent:t.serviceComponent,helperPackageName:t.packageName}}function cd(e,t){return e.kind===`absent`?{previousIme:t,priorPersistedIme:void 0}:{previousIme:e.rebindDisplaced?e.previousIme:t,priorPersistedIme:e.previousIme}}function ld(e){return k.join(e,`android-test-ime-pending`)}function ud(e,t){return k.join(ld(e),encodeURIComponent(t))}async function dd(e,t){let n=v().files,r,i=!1;try{let a=ld(e);if(r=ud(e,t),await n.ensureDirectory(a),(await md(r))?.serial===t)return!0;let o={version:1,serial:t};if(await n.writeAtomicText(r,`${JSON.stringify(o)}\n`,384),i=!0,(await md(r))?.serial!==t)throw Error(`Android test IME marker read-back did not match the requested device.`);return!0}catch(o){return i&&r&&await n.remove(r,{force:!0}).catch(()=>{}),g({level:`debug`,phase:`android_test_ime_marker_write_failed`,data:{stateDir:e,serial:t,error:a(o).message}}),!1}}async function fd(e,t){await v().files.remove(ud(e,t),{force:!0}).catch(()=>{})}async function pd(e){let t=v().files,n;try{n=await t.readDirectory(ld(e))}catch{return[]}let r=[];for(let t of n)try{let n=k.join(ld(e),t),i=await md(n);i&&ud(e,i.serial)===n&&r.push(i.serial)}catch{}return[...new Set(r)].sort()}async function md(e){try{return hd(await v().files.readText(e))}catch{return}}function hd(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 gd=new vn(`utf-16le`);let _d;async function vd(e,t){for(let n of[`AndroidManifest.xml`,`base/manifest/AndroidManifest.xml`]){let r=await yd(e,n,t);if(!r)continue;let i=bd(r);if(i)return i}return await Ld(e,t)}async function yd(e,t,n){try{let r=await Fe(`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 bd(e){return e.subarray(0,Math.min(e.length,128)).toString(`utf8`).trimStart().startsWith(`<`)?xd(e.toString(`utf8`)):Sd(e)}function xd(e){return e.match(/<manifest\b[^>]*\bpackage\s*=\s*["']([^"']+)["']/i)?.[1]}function Sd(e){let t=Td(e);if(!t)return;let n;for(let r=t.treeHeaderSize;r+8<=t.dataEnd;){let i=Cd(e,r,t.dataEnd);if(!i)return;if(i.type===1){if(n=jd(e.subarray(r,r+i.chunkSize)),!n)return}else if(n){let t=wd(e,i,r,n);if(t)return t}r+=i.chunkSize}}function Cd(e,t,n){let r=e.readUInt16LE(t),i=e.readUInt16LE(t+2),a=e.readUInt32LE(t+4);if(!(!Ed(i,a)||t+a>n))return{type:r,headerSize:i,chunkSize:a}}function wd(e,t,n,r){if(t.type===258)return Dd(e,n,n+t.chunkSize,t.headerSize,r)}function Td(e){if(e.length<8||e.readUInt16LE(0)!==3)return;let t=e.readUInt16LE(2),n=e.readUInt32LE(4);if(!(!Ed(t,n)||n>e.length))return{treeHeaderSize:t,dataEnd:n}}function Ed(e,t){return e>=8&&e%4==0&&t%4==0&&e<=t}function Dd(e,t,n,r,i){if(r<16)return;let a=t+r;if(a+20>n||i[e.readUInt32LE(a+4)]!==`manifest`)return;let o=Od(e,a,n);return o?kd(e,i,o):void 0}function Od(e,t,n){let r=e.readUInt16LE(t+8),i=e.readUInt16LE(t+10),a=e.readUInt16LE(t+12);if(!(i<20||r<20)&&!(r+i*a>n-t))return{firstOffset:t+r,stride:i,count:a}}function kd(e,t,n){for(let r=0;r<n.count;r+=1){let i=n.firstOffset+r*n.stride;if(t[e.readUInt32LE(i+4)]===`package`)return Ad(e,t,i)}}function Ad(e,t,n){let r=e.readUInt32LE(n+8);if(r!==4294967295)return t[r];let i=e.readUInt8(n+15),a=e.readUInt32LE(n+16);return i===3?t[a]:void 0}function jd(e){let t=e.readUInt16LE(2),n=e.readUInt32LE(4);if(!Ed(t,n)||t<28||n>e.length)return;let r=e.readUInt32LE(8),i=e.readUInt32LE(16),a=e.readUInt32LE(20),o=!!(i&256),s=t;if(s+r*4>n||a<s+r*4||a>=n)return;let c=[];for(let t=0;t<r;t+=1){let n=a+e.readUInt32LE(s+t*4);c.push(o?Md(e,n):Nd(e,n))}return c}function Md(e,t){let n=Fd(e,t);if(!n)return;let r=Fd(e,t+n.bytes);if(!r)return;let i=t+n.bytes+r.bytes;return Pd(e,i,r.value)?e.subarray(i,i+r.value).toString(`utf8`):void 0}function Nd(e,t){let n=Id(e,t);if(!n)return;let r=t+n.bytes;return Pd(e,r,n.value*2)?gd.decode(e.subarray(r,r+n.value*2)):void 0}function Pd(e,t,n){return Number.isSafeInteger(t)&&Number.isSafeInteger(n)&&t+n<=e.length}function Fd(e,t){if(t+1>e.length)return;let n=e.readUInt8(t);if(!(n&128))return{value:n,bytes:1};if(!(t+2>e.length))return{value:(n&127)<<8|e.readUInt8(t+1),bytes:2}}function Id(e,t){if(t+2>e.length)return;let n=e.readUInt16LE(t);if(!(n&32768))return{value:n,bytes:2};if(!(t+4>e.length))return{value:(n&32767)<<16|e.readUInt16LE(t+2),bytes:4}}async function Ld(e,t){t?.throwIfAborted();let n=await Rd();if(!n)return;let r=await Fe(n,[`dump`,`badging`,e],{allowFailure:!0,signal:t});if(r.exitCode===0)return r.stdout.match(/package:\s+name='([^']+)'/)?.[1]}async function Rd(){if(_d!==void 0)return _d??void 0;try{let e=v().files,{hostPlatform:t}=await import(`./process.js`).then(e=>e.t);for(let n of tn(void 0,t())){let t=k.join(n,`build-tools`);try{let n=(await e.readDirectory(t)).sort((e,t)=>t.localeCompare(e,void 0,{numeric:!0}));for(let r of n){let n=k.join(t,r,`aapt`);if(k.isAbsolute(n)&&await e.isExecutable(n))return _d=n,n}}catch{}}}catch{}_d=null}async function zd(e,t){let n=await Be({source:e,isInstallablePath:(e,t)=>t.isFile()&&Bd(e),installableLabel:`Android installable (.apk or .aab)`,signal:t?.signal});try{let e=t?.resolveIdentity===!1?{}:await Vd(n.installablePath,t?.signal);return{archivePath:n.archivePath,installablePath:n.installablePath,packageName:e.packageName,cleanup:n.cleanup}}catch(e){throw await n.cleanup(),e}}function Bd(e){let t=k.extname(e).toLowerCase();return t===`.apk`||t===`.aab`}async function Vd(e,t){let n=k.extname(e).toLowerCase();return n!==`.apk`&&n!==`.aab`?{}:{packageName:await vd(e,t)}}async function Hd(e,t,n,i={}){let a=typeof n.action==`string`&&n.action.trim()?n.action.trim():`${t}.TEST_PUSH`,o=[`am`,`broadcast`,`-a`,a,`-p`,t],s=typeof n.receiver==`string`?n.receiver.trim():``;s&&o.push(`-n`,s);let c=n.extras;if(c!==void 0&&(typeof c!=`object`||!c||Array.isArray(c)))throw new r(`INVALID_ARGS`,`Android push payload extras must be an object`);let l=c??{},u=0;for(let[e,t]of Object.entries(l))e&&(Ud(o,e,t),u+=1);return await E(e,o,{signal:i.signal}),{action:a,extrasCount:u}}function Ud(e,t,n){if(typeof n==`string`){e.push(`--es`,t,n);return}if(typeof n==`boolean`){e.push(`--ez`,t,n?`true`:`false`);return}if(typeof n==`number`&&Number.isFinite(n)){if(Number.isInteger(n)){e.push(`--ei`,t,String(n));return}e.push(`--ef`,t,String(n));return}throw new r(`INVALID_ARGS`,`Unsupported Android broadcast extra type for "${t}". Use string, boolean, or number.`)}function Z(e){let t=e.replaceAll(`,`,``).match(/^-?\d+(?:\.\d+)?/);if(!t)return null;let n=Number(t[0]);return Number.isFinite(n)?n:null}function Wd(e){let t=Yd(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 Xd(n)}function Gd(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 Kd(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=>Jd({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 qd(e){return Math.round(e*10)/10}function Jd(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:qd(Math.max(...t.map(e=>e.durationNs))/1e6)}}function Yd(e){return[...new Set(e.filter(e=>Number.isFinite(e)))].sort((e,t)=>e-t)}function Xd(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 Zd(e,t,n){Qd(e,t);let r=lf(e),i=af(e),a=ef(i,r,t),o=Date.parse(n),s=df({frames:i,measuredAtMs:o,summary:r}),c=Gd({frames:i,frameDeadlineNs:a,summaryDroppedFrameCount:r?.droppedFrameCount}),l=r?.sampleWindowMs??s.sampleWindowMs??hf(i),u=tf(r,i,c),d=rf({droppedFrames:c,timing:s,measuredAtMs:o,summary:r});return{...u,sampleWindowMs:l,...nf(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 Qd(e,t){if(/no process found for:/i.test(e))throw new r(`COMMAND_FAILED`,`Android gfxinfo did not find a running process for ${t}`,{metric:`fps`,package:t,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 $d(e){throw new r(`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 ef(e,t,n){let i=Wd(e);if(!t&&e.length===0&&$d(n),t||i!==void 0)return i;throw new r(`COMMAND_FAILED`,`Failed to infer Android frame deadline from framestats output for ${n}`,{metric:`fps`,package:n,hint:`Retry perf after a longer interaction window so consecutive Android frame timestamps are available.`})}function tf(e,t,n){let r=e?.totalFrameCount??t.length,i=e?.droppedFrameCount??n.length;return{totalFrameCount:r,droppedFrameCount:i,droppedFramePercent:e?.droppedFramePercent??(r>0?gn(i/r*100):0)}}function nf(e){return{frameDeadlineMs:e===void 0?void 0:qd(e/1e6),refreshRateHz:e===void 0?void 0:qd(1e9/e)}}function rf(e){let{droppedFrames:t,timing:n,measuredAtMs:r,summary:i}=e;if(t.length===0)return;let a=Kd({frames:t,windowStartNs:n.windowStartNs,measuredAtMs:r,uptimeMs:i?.uptimeMs});return a.length>0?a:void 0}function af(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(of(i)){n=new Map(i.map((e,t)=>[e,t]));continue}let a=sf(i,n);a&&t.push(a)}return t.sort((e,t)=>e.intendedVsyncNs-t.intendedVsyncNs)}function of(e){return e.includes(`IntendedVsync`)&&e.includes(`FrameCompleted`)}function sf(e,t){if(!t||e.length<t.size)return;let n=cf(e,t,`Flags`),r=cf(e,t,`IntendedVsync`),i=cf(e,t,`FrameCompleted`);if(!(n!==0||r===null||i===null||r<=0||i<=r))return{intendedVsyncNs:r,frameCompletedNs:i,durationNs:i-r}}function cf(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 lf(e){let t=e.split(/\nProfile data in ms:\n/i)[0]??``,n=gf(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=Z(i)??void 0,s=Number(a);if(o===void 0||!Number.isFinite(s)||n<0)return;let c=gf(t,`Uptime`),l=gf(t,`Stats since`);return{droppedFramePercent:gn(s),droppedFrameCount:o,totalFrameCount:n,sampleWindowMs:uf({uptimeMs:c,statsSinceNs:l}),uptimeMs:c,statsSinceNs:l}}function uf(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 df(e){let{frames:t,measuredAtMs:n,summary:r}=e,i=ff(t),a=r?.statsSinceNs,o=a??i.firstFrameNs,s=pf(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:mf({deviceBootWallClockMs:l,measuredAtMs:n,summaryStartNs:a,lastFrameNs:i.lastFrameNs}),timestampSource:`estimated-from-device-uptime`}}function ff(e){return e.length===0?{}:{firstFrameNs:Math.min(...e.map(e=>e.intendedVsyncNs)),lastFrameNs:Math.max(...e.map(e=>e.frameCompletedNs))}}function pf(e,t){if(e!==void 0&&t!==void 0)return Math.max(0,Math.round((t-e)/1e6))}function mf(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 hf(e){if(e.length===0)return;let t=ff(e);return pf(t.firstFrameNs,t.lastFrameNs)}function gf(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:Z(i)??void 0}async function _f(e,t,n={}){let r=y(e,n.adb);try{let i=Zd((await b(r,[`dumpsys`,`gfxinfo`,t,`framestats`],{timeoutMs:15e3})).stdout,t,new Date().toISOString());return await vf(e,t,n),i}catch(e){throw yf(t,e)}}async function vf(e,t,n={}){let r=y(e,n.adb);try{await b(r,[`dumpsys`,`gfxinfo`,t,`reset`],{allowFailure:!0,timeoutMs:3e3})}catch{}}function yf(e,t){return t instanceof r?new r(t.code,t.message,{...t.details??{},metric:`fps`,package:e},t):new r(`COMMAND_FAILED`,`Failed to sample Android fps for ${e}`,{metric:`fps`,package:e},t)}async function bf(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 xf(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 xf(e,t,n){try{let r=await _f(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 Sf(e,t,n){let r=y(e,n.adb);await Of(r,t),await jf(r,t),await Af(r,t,n.files);let i=await Df(t.outPath,n.files);await Tf(r,t.remotePath);let a=Date.now(),o=Math.max(0,a-t.startedAt),s=await bf(e,t,i,o,{adb:r});return{...t,action:`stop`,platform:`android`,state:`stopped`,stoppedAt:a,durationMs:o,sizeBytes:i,method:t.kind===`simpleperf`?ei:ti,artifact:{path:t.outPath,sizeBytes:i},summary:s,message:`Stopped Android ${t.kind} ${t.type} for ${t.packageName}`}}async function Cf(e,t,n={}){let r=y(e,n.adb);try{t.state===`running`&&(await Of(r,t),await jf(r,t).catch(()=>{}))}finally{await Tf(r,t.remotePath)}}function wf(e,t,n=ri){return`${n}/agent-device-${e.replaceAll(/[^A-Za-z0-9_.-]/g,`_`)}-${Date.now()}-${t}`}async function Tf(e,t){try{await b(e,[`rm`,`-f`,t],{allowFailure:!0,timeoutMs:ni})}catch{}}async function Ef(e,t,n=v().files){await n.ensureDirectory(k.dirname(e)),await n.writeBytes(e,Buffer.from(`${JSON.stringify(t,null,2)}\n`))}async function Df(e,t=v().files){try{return(await t.stat(e)).size}catch(t){throw new r(`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.`},t)}}async function Of(e,t){try{await b(e,[C(kf(t.profilerPid))],{timeoutMs:F})}catch(e){throw P(`stop`,t.kind,t.packageName,e)}}function kf(e){return[`pid=${w(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 Af(e,t,n){await(n??v().files).ensureDirectory(k.dirname(t.outPath));try{await e([`pull`,t.remotePath,t.outPath],{timeoutMs:F})}catch(e){throw new r(`COMMAND_FAILED`,`Failed to pull Android ${t.kind} artifact for ${t.packageName}`,{package:t.packageName,tool:t.kind,remotePath:t.remotePath,outPath:t.outPath,hint:`Check that the profiling command ran long enough to create an artifact, then retry stop with the same session.`},e)}}async function jf(e,t){let n;for(let r=0;r<12;r+=1){let r=await Mf(e,t.remotePath);if(r!==void 0&&r>0&&r===n)return;n=r,await _(250)}throw new r(`COMMAND_FAILED`,`Android ${t.kind} artifact is not ready to pull`,{package:t.packageName,tool:t.kind,remotePath:t.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 Mf(e,t){let n=w(t),r=await b(e,[C(`if [ -f ${n} ]; then stat -c %s ${n} 2>/dev/null || wc -c < ${n}; fi`)],{allowFailure:!0,timeoutMs:ni});if(r.exitCode!==0)return;let i=Number(r.stdout.trim().split(/\s+/)[0]);return Number.isFinite(i)?i:void 0}async function Nf(e,t,n,r={}){let i=y(e,r.adb),a=await ii(i,t);await ai(i,`perfetto`,t);let o=wf(t,`app.perfetto-trace`,`/data/misc/perfetto-traces`),s;try{await vf(e,t,{adb:i}),s=await Ff(i,o,t)}catch(e){throw await Tf(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:ti,message:`Started Android Perfetto trace for ${t}`}}async function Pf(e,t,n,r={}){return await Sf(e,{...t,outPath:n},r)}async function Ff(e,t,n){try{let i=oi((await b(e,[`perfetto`,`--background-wait`,`-o`,t,`-t`,`3600s`,`sched`,`freq`,`idle`,`am`,`wm`,`gfx`,`view`,`binder_driver`,`hal`,`dalvik`],{timeoutMs:F})).stdout);if(i)return i;throw new r(`COMMAND_FAILED`,`Android perfetto did not return a profiler pid`,{package:n,tool:`perfetto`,hint:`Retry perf trace start. If perfetto exits immediately, verify the device permits trace capture.`})}catch(e){throw P(`start`,`perfetto`,n,e)}}function If(e){let t=[];for(let n of re(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:gn(r),command:a[0],dso:a[1],symbol:a.slice(2).join(` `)||void 0}),t.length>=50)break}return t}async function Lf(e,t,n,r={}){let i=y(e,r.adb),a=await ii(i,t);await ai(i,`simpleperf`,t);let o=wf(t,`cpu.perf.data`),s;try{s=await Bf(i,a,o,t)}catch(e){throw await Tf(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:ei,message:`Started Android Simpleperf CPU profile for ${t}`}}async function Rf(e,t,n,r={}){return await Sf(e,{...t,outPath:n},r)}async function zf(e,t,n,r={}){let i=y(e,r.adb);await ai(i,`simpleperf`,t.packageName);let a=await Uf(i,t),o=new Date().toISOString(),s=If(a.stdout),c=s.slice(0,10).map(e=>({symbol:e.symbol??`<unknown>`,binary:e.dso,selfSamplePercent:e.percentage}));await Ef(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 Df(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:ei,message:`Wrote Android Simpleperf report for ${t.packageName}`}}async function Bf(e,t,n,i){try{let a=oi((await b(e,[C(Vf(t,n))],{timeoutMs:F})).stdout);if(a)return a;throw new r(`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 P(`start`,`simpleperf`,i,e)}}function Vf(e,t){return Hf([`simpleperf`,`record`,`-e`,`cpu-clock:u`,`-p`,e,`-o`,t,`--duration`,`3600`],`simpleperf`)}function Hf(e,t){let n=e.map(w).join(` `),r=`${ri}/agent-device-${t}-${Date.now()}.err`;return[`err=${w(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 Uf(e,t){try{return await b(e,[`simpleperf`,`report`,`-i`,t.remotePath,`--stdio`,`--sort`,`comm,dso,symbol`],{timeoutMs:F})}catch(e){throw P(`report`,`simpleperf`,t.packageName,e)}}const Wf=15e3,Gf=12e4;async function Kf(e,t,n={}){let r=y(e,n.adb);try{return Xf((await b(r,[`dumpsys`,`meminfo`,t],{timeoutMs:Wf})).stdout,t,new Date().toISOString())}catch(e){throw ip(`memory`,t,e)}}async function qf(e,t,n,i={}){let a=y(e,i.adb),o=i.files??v().files,s=await Zf(a,t),c=Qf(t);await o.ensureDirectory(k.dirname(n));let l=await Jf(o,n);try{Ie(await b(a,[`am`,`dumpheap`,t,c],{allowFailure:!0,timeoutMs:Gf}),`Failed to capture Android heap dump for ${t}`,e=>({kind:`android-hprof`,package:t,pid:s,remotePath:c,hint:$f(e.stdout,e.stderr)}));let e=await a([`pull`,c,n],{allowFailure:!0,timeoutMs:Gf});if(e.exitCode!==0)throw await Yf(o,n,l),T(`Failed to pull Android heap dump for ${t}`,e,{kind:`android-hprof`,package:t,pid:s,remotePath:c,path:n,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(n).catch(()=>null);if(!i?.isFile||i.size<=0)throw await Yf(o,n,l),new r(`COMMAND_FAILED`,`Android heap dump artifact is missing or empty`,{kind:`android-hprof`,package:t,pid:s,path:n,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:n,sizeBytes:i.size,measuredAt:new Date().toISOString(),method:`adb-shell-am-dumpheap`,packageName:t,pid:s,remotePath:c}}finally{await b(a,[`rm`,`-f`,c],{allowFailure:!0,timeoutMs:Wf}).catch(()=>{})}}async function Jf(e,t){return await e.stat(t).then(e=>e.isFile).catch(()=>!1)}async function Yf(e,t,n){n||await e.remove(t,{force:!0}).catch(()=>{})}function Xf(e,t,n){if(/no process found for:/i.test(e))throw new r(`COMMAND_FAILED`,`Android meminfo did not find a running process for ${t}`,{metric:`memory`,package:t,hint:`Run open <app> for this session again to ensure the Android app is active, then retry perf.`});let i=ap(e,`TOTAL PSS`)??op(e);if(i===void 0)throw new r(`COMMAND_FAILED`,`Failed to parse Android meminfo output for ${t}`,{metric:`memory`,package:t,hint:`Retry perf after reopening the app session. If the problem persists, capture adb shell dumpsys meminfo output for debugging.`});return{totalPssKb:i,totalRssKb:ap(e,`TOTAL RSS`),measuredAt:n,method:`adb-shell-dumpsys-meminfo`,topConsumers:ep(e)}}async function Zf(e,t){let n=await b(e,[`pidof`,t],{allowFailure:!0,timeoutMs:Wf}),i=n.stdout.trim().split(/\s+/).map(Number).find(e=>Number.isInteger(e)&&e>0);if(n.exitCode===0&&i!==void 0)return i;throw new r(`COMMAND_FAILED`,`No running Android process found for ${t}`,{kind:`android-hprof`,package:t,stdout:n.stdout,stderr:n.stderr,hint:`Run open <app> for this session again to ensure the Android app is active, then retry perf memory snapshot.`})}function Qf(e){return`/data/local/tmp/agent-device-${e.replaceAll(/[^a-zA-Z0-9._-]/g,`_`)}-${Date.now()}.hprof`}function $f(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 ep(e){let t=e.split(`
14
+ `).flatMap(e=>tp(e)??[]).sort((e,t)=>t.pssKb-e.pssKb).slice(0,5);return t.length>0?t:void 0}function tp(e){let t=e.trim();if(np(t))return;let n=t.match(/^(.+?)\s+([0-9][0-9,]*(?:\(\d+\))?)(?:\s|$)/);if(n)return rp(n[1],n[2])}function np(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 rp(e,t){let n=e?.trim(),r=t?Z(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 ip(e,t,n){return n instanceof r?new r(n.code,n.message,{...n.details??{},metric:e,package:t},n):new r(`COMMAND_FAILED`,`Failed to sample Android ${e} for ${t}`,{metric:e,package:t},n)}function ap(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:Z(i)??void 0}function op(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=>Z(e)!==null);return n?Z(n)??void 0:void 0}}async function sp(e,t,n){let r=await E(e,[`dumpsys`,`package`,t],{allowFailure:!0});return r.exitCode===0?_p(r.stdout,n):{requested:void 0,grants:void 0}}async function cp(e){let t=await E(e,[`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 lp=/^\s*User (\d+):/,up=/^\s*runtime permissions:\s*$/,dp=/^\s*([\w.]+): granted=(true|false)\b/,fp=/^\s*Package \[.+?\]/,pp=/^\s*requested permissions:\s*$/,mp=/^\s*([A-Za-z][\w.]*)/;function hp(e){return e.split(`
16
+ `).filter(e=>e.trim().length>0).map(e=>({text:e,indent:e.length-e.trimStart().length}))}function gp(e,t){let n=Q(Q(Q(hp(e),e=>e.indent===0&&e.text.trim()===`Packages:`),e=>lp.exec(e.text)?.[1]===String(t)),e=>up.test(e.text));if(!n)return;let r=new Map;for(let{text:e}of n){let t=dp.exec(e);t&&r.set(t[1],t[2]===`true`?`granted`:`not_granted`)}return r}function Q(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 _p(e,t){return{requested:vp(e),grants:gp(e,t)}}function vp(e){let t=Q(Q(Q(hp(e),e=>e.indent===0&&e.text.trim()===`Packages:`),e=>fp.test(e.text)),e=>pp.test(e.text));if(!t)return;let n=[];for(let{text:e}of t){let t=mp.exec(e)?.[1];t&&t.includes(`.`)&&!n.includes(t)&&n.push(t)}return n}function yp(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.`}const bp=[`all`,`camera`,`microphone`,`photos`,`contacts`,`notifications`,`calendar`,`location`,`media-library`],xp={calendar:[`android.permission.WRITE_CALENDAR`,`android.permission.READ_CALENDAR`],camera:[`android.permission.CAMERA`],contacts:[`android.permission.READ_CONTACTS`,`android.permission.WRITE_CONTACTS`],location:[`android.permission.ACCESS_FINE_LOCATION`,`android.permission.ACCESS_COARSE_LOCATION`],"media-library":[`android.permission.WRITE_EXTERNAL_STORAGE`,`android.permission.READ_EXTERNAL_STORAGE`,`android.permission.READ_MEDIA_AUDIO`,`android.permission.READ_MEDIA_IMAGES`,`android.permission.READ_MEDIA_VIDEO`],microphone:[`android.permission.RECORD_AUDIO`]};async function Sp(e){let t=await cp(e);if(t!==void 0)return t;throw new r(`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.`})}function Cp(e,t){return{action:Ae(e),target:Gp(t?.permissionTarget,t?.permissionMode)}}async function wp(e,t,{action:n,target:r},i){let a=[`--user`,String(i)];if(r.kind===`all`)return await Dp(e,t,n,i,a);if(n===`grant`){let n=await Up(e,t,r,i,a);return Ep(Tp(r),n)}if(r.kind===`pm`)return await Jp(e,t,n,r,i,a);let{grants:o}=await sp(e,t,i),s=await Wp(e,t,n,r,a),{priorGrantState:c,warnings:l}=Xp(t,s,s.map(e=>o?.get(e)??`unknown`));return Ep(r.kind,s,{priorGrantState:c,warnings:l})}function Tp(e){return e.kind===`pm`?e.name:e.kind}function Ep(e,t,n){return{permission:e,permissions:[...t],...n?{priorGrantState:n.priorGrantState,...n.warnings.length>0?{warnings:n.warnings}:{}}:{}}}async function Dp(e,t,n,i,a){let{requested:o,grants:s}=await sp(e,t,i);if(o===void 0)throw new r(`COMMAND_FAILED`,`Could not read declared permissions for ${t}, so no permission was changed.`,{appPackage:t});let c=n===`grant`?void 0:s,l=[],u=[];for(let r of Pp(o))await Op({device:e,appPackage:t,action:n,userArgs:a,grants:c,applied:l,warnings:u},r);return{permission:`all`,permissions:l,...u.length>0?{warnings:u}:{}}}async function Op(e,t){return t.kind===`notification`?await kp(e):t.kind===`photos`?await Ap(e):await jp(e,t.value)}async function kp(e){let{device:t,appPackage:n,action:r,userArgs:i}=e;await Qp(t,n,r,{appOps:`POST_NOTIFICATION`,permission:`android.permission.POST_NOTIFICATIONS`},i),Mp(e,`android.permission.POST_NOTIFICATIONS`)}async function Ap(e){let{device:t,appPackage:n,action:r,userArgs:i,warnings:a}=e,o=await zp(t,n,r===`grant`?`grant`:`revoke`,i);if(o===void 0){a.push(`Skipped Android photos permission for ${n}: device refused both media candidates.`);return}await Np(e,o)}async function jp(e,t){let{device:n,appPackage:r,action:i,userArgs:a,warnings:o}=e,s=await Rp(n,i===`grant`?`grant`:`revoke`,a,r,t);if(s.kind===`skipped`){o.push(`Skipped ${t} for ${r}: ${s.detail}`);return}await Np(e,t)}function Mp(e,t){let{appPackage:n,action:r,grants:i,applied:a,warnings:o}=e;a.push(t),r!==`grant`&&Fp(o,i,n,t)}async function Np(e,t){Mp(e,t),e.action===`reset`&&await $p(e.device,e.appPackage,t,e.userArgs)}function Pp(e){let t=[],n=!1;for(let r of e)r===`android.permission.POST_NOTIFICATIONS`?t.push({kind:`notification`}):r===`android.permission.READ_MEDIA_IMAGES`||r===`android.permission.READ_EXTERNAL_STORAGE`?n||(n=!0,t.push({kind:`photos`})):t.push({kind:`pm`,value:r});return t}function Fp(e,t,n,r){let i=yp(n,r,t?.get(r)??`unknown`);i&&e.push(i)}const Ip=[[/not a changeable permission/,`not-changeable`],[/has not requested permission/,`not-requested`],[/is not a runtime permission/,`not-runtime-permission`],[/unknown permission/,`unknown-permission`],[/managed by role/,`role-managed`]];function Lp(e){let t=e.toLowerCase();return Ip.find(([e])=>e.test(t))?.[1]}async function Rp(e,t,n,r,i){let a=await E(e,[`pm`,t,...n,r,i],{allowFailure:!0});if(a.exitCode===0)return{kind:`applied`};let o=Lp(a.stderr);if(o)return{kind:`skipped`,reason:o,detail:Hp(a.stderr)};throw T(`Failed to ${t} Android permission ${i} for ${r}`,a,{appPackage:r,permission:i})}async function zp(e,t,n,r){try{return await Zp(e,t,n,r)}catch(e){if(Bp(e))return;throw e}}function Bp(e){if(!(e instanceof r)||e.code!==`COMMAND_FAILED`)return!1;let t=e.details?.attempts;return Vp(t)&&t.length>0&&t.every(e=>e.reason!==void 0)}function Vp(e){return Array.isArray(e)&&e.every(e=>typeof e==`object`&&!!e&&typeof e.permission==`string`&&typeof e.detail==`string`)}function Hp(e){let t=e.split(`
17
+ `).map(e=>e.trim()).filter(e=>e.length>0),n=t[0]??`unknown device error`;return(n.endsWith(`:`)&&t[1]?`${n} ${t[1]}`:n).slice(0,200)}async function Up(e,t,n,r,i){if(n.kind===`notifications`)return await Qp(e,t,`grant`,n,i),[n.permission];if(n.kind===`photos`)return[await Zp(e,t,`grant`,i)];if(n.kind===`pm`){let a=[...await Kp(e,t,n.values,r)];for(let n of a)await E(e,[`pm`,`grant`,...i,t,n]);return a}throw n.kind===`all`?Error(`Unhandled Android permission target: all is resolved by the caller.`):Error(`Unhandled Android permission target: ${JSON.stringify(n)}`)}async function Wp(e,t,n,r,i){if(r.kind===`notifications`)return await Qp(e,t,n,r,i),[r.permission];if(r.kind===`photos`){let r=await Zp(e,t,`revoke`,i);return n===`reset`&&await $p(e,t,r,i),[r]}throw r.kind===`pm`?Error(`Unhandled Android permission target: pm is resolved by the caller.`):r.kind===`all`?Error(`Unhandled Android permission target: all is resolved by the caller.`):Error(`Unhandled Android permission target: ${JSON.stringify(r)}`)}function Gp(e,t){let n=we(e);if(t?.trim())throw new r(`INVALID_ARGS`,`Android does not support permission modes. Received: ${t}.`);if(n===`all`)return{kind:`all`};if(n===`photos`)return{kind:`photos`};if(n===`notifications`)return{kind:`notifications`,appOps:`POST_NOTIFICATION`,permission:`android.permission.POST_NOTIFICATIONS`};let i=n in xp?xp[n]:void 0;if(i)return{kind:`pm`,name:n,values:i};throw new r(`INVALID_ARGS`,`Unsupported permission target on Android: ${e}. Use ${bp.join(`|`)}.`,{hint:`Android custom permission ids are attempted through all, not individually.`})}async function Kp(e,t,n,r){let{requested:i}=await sp(e,t,r);return qp(i,n,t)}function qp(e,t,n){if(e===void 0)return t;let i=t.filter(t=>e.includes(t));if(i.length===0)throw new r(`COMMAND_FAILED`,`Package ${n} has not requested permission ${t.join(`, `)}, so no permission was changed.`,{appPackage:n,permissions:t});return i}async function Jp(e,t,n,r,i,a){let{requested:o,grants:s}=await sp(e,t,i),c=qp(o,r.values,t);await Yp(e,t,c,n,a);let{priorGrantState:l,warnings:u}=Xp(t,c,c.map(e=>s?.get(e)??`unknown`));return Ep(r.name,c,{priorGrantState:l,warnings:u})}async function Yp(e,t,n,r,i){for(let r of n)await E(e,[`pm`,`revoke`,...i,t,r]);if(r===`reset`)for(let r of n)await $p(e,t,r,i)}function Xp(e,t,n){return{priorGrantState:n.includes(`granted`)?`granted`:n.includes(`unknown`)?`unknown`:`not_granted`,warnings:t.flatMap((t,r)=>{let i=yp(e,t,n[r]);return i?[i]:[]})}}async function Zp(e,t,n,i){let a=await em(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 r of o){let a=await E(e,[`pm`,n,...i,t,r],{allowFailure:!0});if(a.exitCode===0)return r;s.push({permission:r,reason:Lp(a.stderr),detail:Hp(a.stderr)})}throw new r(`COMMAND_FAILED`,`Failed to ${n} Android photos permission`,{appPackage:t,sdkInt:a,attempts:s})}async function Qp(e,t,n,r,i){let a=n===`grant`?`allow`:n===`deny`?`deny`:`default`;n===`grant`?await E(e,[`pm`,`grant`,...i,t,r.permission],{allowFailure:!0}):(await E(e,[`pm`,`revoke`,...i,t,r.permission],{allowFailure:!0}),n===`reset`&&await $p(e,t,r.permission,i)),await E(e,[`appops`,`set`,...i,t,r.appOps,a])}async function $p(e,t,n,r){for(let i of[`user-set`,`user-fixed`])await E(e,[`pm`,`clear-permission-flags`,...r,t,n,i],{allowFailure:!0})}async function em(e){let t=await E(e,[`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}const tm=[`cmd`,`connectivity`,`airplane-mode`];async function nm(e,t){let n=t?`enabled`:`disabled`;await rm(e),await E(e,[...tm,t?`enable`:`disable`]);let i=await im(e);if(i!==n)throw new r(`COMMAND_FAILED`,`Android airplane mode reads ${i} after requesting ${n}.`,{deviceId:e.id,requested:n,airplaneMode:i});return{airplaneMode:i}}async function rm(e){let{state:t,result:n}=await am(e);if(!t)throw n.exitCode!==0&&pt(n.stdout,n.stderr)?new r(`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:n.stdout,stderr:n.stderr,exitCode:n.exitCode}):T(`Failed to read Android airplane mode`,n,{deviceId:e.id})}async function im(e){let{state:t,result:n}=await am(e);if(t)return t;throw T(`Failed to read Android airplane mode after changing it`,n,{deviceId:e.id})}async function am(e){let t=await E(e,[...tm],{allowFailure:!0});return{state:t.exitCode===0?om(t.stdout):void 0,result:t}}function om(e){let t=e.trim().toLowerCase();if(t===`enabled`)return`enabled`;if(t===`disabled`)return`disabled`}const sm=[`window_animation_scale`,`transition_animation_scale`,`animator_duration_scale`],cm={"extra-small":`0.82`,small:`0.88`,medium:`0.94`,large:`1.0`,"extra-large":`1.12`,"extra-extra-large":`1.24`,"extra-extra-extra-large":`1.35`,"accessibility-medium":`1.5`,"accessibility-large":`1.75`,"accessibility-extra-large":`2.0`,"accessibility-extra-extra-large":`2.5`,"accessibility-extra-extra-extra-large":`3.2`},lm=cm.large;async function um(e,t,n,i,a){let o=t.toLowerCase();switch(o){case`wifi`:{let t=ke(n);await E(e,[`svc`,`wifi`,t?`enable`:`disable`]);return}case`airplane`:return await nm(e,ke(n));case`location`:{if(n.toLowerCase()===`set`){if(e.kind!==`emulator`)throw new r(`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:t,longitude:n}=je(a);return await ft(e,[`emu`,`geo`,`fix`,String(n),String(t)]),{latitude:t,longitude:n}}let t=ke(n)?`3`:`0`;await E(e,[`settings`,`put`,`secure`,`location_mode`,t]);return}case`animations`:{let t=ke(n)?`1`:`0`;for(let n of sm)await E(e,[`settings`,`put`,`global`,n,t]);return{scale:t,keys:[...sm]}}case`appearance`:{let t=await xm(e,n);await E(e,[`cmd`,`uimode`,`night`,t===`dark`?`yes`:`no`]);return}case`clear-app-state`:{if(n.toLowerCase()!==`clear`)throw new r(`INVALID_ARGS`,`settings clear-app-state only supports clear.`);if(!i)throw new r(`INVALID_ARGS`,`settings clear-app-state requires an app id or an active app session.`,s());let t=await dm(e,o,i);await E(e,[`am`,`force-stop`,t],{allowFailure:!0});let a=await E(e,[`pm`,`clear`,t],{allowFailure:!0});if(a.exitCode!==0||!/\bSuccess\b/i.test(a.stdout))throw new r(`COMMAND_FAILED`,`Failed to clear Android app data for ${t}`,{package:t,stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});return{package:t,cleared:!0}}case`fingerprint`:await vm(e,_m(n));return;case`permission`:{if(!i)throw new r(`INVALID_ARGS`,`permission setting requires an active app in session`,s());let t=Cp(n,a),c=await Sp(e);return await wp(e,await dm(e,o,i,c),t,c)}case`text-size`:return await mm(e,n);default:throw new r(`INVALID_ARGS`,`Unsupported setting: ${t}`)}}async function dm(e,t,n,i){let a=await Oe(n,t=>qt(e,t,{installedOnly:!0,userId:i}));if(a.type===`intent`)throw new r(`INVALID_ARGS`,`settings ${t} requires a package name, not an intent.`,{reason:Te,dispatched:`no`,app:n,hint:`Run apps --all for the exact package name, then retry with it in --app.`});return a.value}const fm={"text-size":hm};async function pm(e,t){return await fm[t](e)}async function mm(e,t){let n=Ce(t),r=cm[n];return await E(e,[`settings`,`put`,`system`,`font_scale`,r]),Se(n,r)}async function hm(e){let t=(await E(e,[`settings`,`get`,`system`,`font_scale`])).stdout.trim(),n=t===`null`?lm:t,i=/^(\d+(\.\d+)?)$/.test(n)?Number(n):NaN;if(!Number.isFinite(i)||i<=0)throw new r(`COMMAND_FAILED`,`Android reported an unusable font scale: ${t||`(empty)`}`,{deviceId:e.id,fontScale:t,hint:"Run `adb shell settings get system font_scale` to see what the device holds."});return Se(gm(i),n)}function gm(e){let t=Ee[0],n=1/0;for(let r of Ee){let i=Math.abs(Number.parseFloat(cm[r])-e);i>=n||(t=r,n=i)}return t}function _m(e){let t=e.trim().toLowerCase();if(t===`match`)return`match`;if(t===`nonmatch`)return`nonmatch`;throw new r(`INVALID_ARGS`,`Invalid fingerprint state: ${e}. Use match|nonmatch.`)}async function vm(e,t){let n=ym(e,t),i=[];for(let t of n){let n=await ft(e,t,{allowFailure:!0});if(n.exitCode===0)return;i.push({args:t,stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode})}let a=l(i);throw i.length>0&&i.every(e=>bm(e.stdout,e.stderr))?new r(`UNSUPPORTED_OPERATION`,`Android fingerprint simulation is not supported on this target/runtime.`,{deviceId:e.id,action:t,hint:`Use an Android emulator with biometric support, or a device/runtime that exposes cmd fingerprint.`,attempts:a}):new r(`COMMAND_FAILED`,`Failed to simulate Android fingerprint.`,{deviceId:e.id,action:t,attempts:a})}function ym(e,t){let n=t===`match`?`1`:`9999`,r=[at(`adb`,`shell`,[`cmd`,`fingerprint`,`touch`,n]),at(`adb`,`shell`,[`cmd`,`fingerprint`,`finger`,n])];return e.kind===`emulator`&&r.push([`emu`,`finger`,`touch`,n]),r}function bm(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 xm(e,t){let n=De(t);if(n!==`toggle`)return n;let i=await E(e,[`cmd`,`uimode`,`night`],{allowFailure:!0});if(i.exitCode!==0)throw T(`Failed to read current Android appearance`,i);let a=Sm(i.stdout,i.stderr);if(!a)throw new r(`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 Sm(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 Cm=Buffer.from([137,80,78,71,13,10,26,10]);async function wm(e,t,n={}){if(n.stabilize===!1)return await Dm(e,t);await Tm(e);try{return await _(1e3),await Dm(e,t)}finally{await Em(e).catch(()=>{})}}async function Tm(e){let t=t=>E(e,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 Em(e){await E(e,[`am`,`broadcast`,`-a`,`com.android.systemui.demo`,`-e`,`command`,`exit`],{allowFailure:!0})}async function Dm(e,t){let n=new AbortController,r=no(e,{timeoutMs:2e3,signal:n.signal});try{await km(e,t);let n=await Om(r,250);return n?{displayRotation:n}:{}}finally{n.abort()}}async function Om(e,t){let n;try{return await Promise.race([e,new Promise(e=>{n=setTimeout(()=>e(void 0),t)})])}finally{clearTimeout(n)}}async function km(e,t){let n=await dt(e,[`screencap`,`-p`],{binaryStdout:!0});if(!n.stdoutBuffer)throw new r(`COMMAND_FAILED`,`Failed to capture screenshot`);let i=n.stdoutBuffer.indexOf(Cm);if(i<0)throw new r(`COMMAND_FAILED`,`Screenshot data does not contain a valid PNG header`);let a=Am(n.stdoutBuffer,i);if(!a)throw new r(`COMMAND_FAILED`,`Screenshot data does not contain a complete PNG payload`);await v().files.writeBytes(t,n.stdoutBuffer.subarray(i,a))}function Am(e,t){let n=t+Cm.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 jm(e,t,n=0){let r=$e(e);if(r){await r({action:`type`,text:t,delayMs:n}),$(`type`,`provider-native`,t);return}let i=await Im(e,`type`,t);if(i.backend===`test-ime`){await Rm(e,i.packageName,t,n);return}if(n>0&&Array.from(t).length>1){await Bm(e,{action:`type`,text:t,chunkSize:1,delayMs:n});return}await Bm(e,{action:`type`,text:t,chunkSize:8,delayMs:0})}async function Mm(e,t,n,r,a=0,o={}){let s=await Mu(e,t,n,o),c=$e(e);if(c)return await c({action:`fill`,target:{x:t,y:n},text:r,delayMs:a}),$(`fill`,`provider-native`,r),Nu(r,s,await ku(e,t,n,r,o));let l=null,u=0;try{for(let i of Nm(a)){await ao(e,t,n),u+=1;let a=await Im(e,`fill`,r);if(a.backend===`test-ime`)return Nu(r,s,await zm(e,a.packageName,t,n,r,s,o));let c=await Pm(e,{x:t,y:n,text:r,beforeTarget:s,attempt:i},o);if(l=c,c.ok)return;if(c.reason===`ime_capture`)return Nu(r,s,c);let d=Fu(r,s,c);if(d)return d}}catch(e){throw i(e,u)}return Nu(r,s,l)}function Nm(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 Pm(e,t,n){let{x:r,y:i,text:a,beforeTarget:o,attempt:s}=t;return await Gm(e,Fm(a,o,s)),await Bm(e,{action:`fill`,text:a,chunkSize:s.chunkSize,delayMs:s.inputDelayMs}),ku(e,r,i,a,n)}function Fm(e,t,n){let r=Array.from(e).length;return eh(r>0?r+n.clearPadding:t?.text?Array.from(t.text).length+n.clearPadding:n.maxClear,n.minClear,n.maxClear)}async function Im(e,t,n){let r=Et(e);if(r)return r.rebindUnconfirmed&&await Lm(e),{backend:`test-ime`,packageName:(await vt(x(e))).manifest.packageName};let i=await Km(e,t),a=i?.inputMethodPackage;return Ot(a)?{backend:`test-ime`,packageName:a}:(Jm(n),qm(i,t),{backend:`adb-shell`})}async function Lm(e){let{rebindAndroidTestIme:t}=await import(`./ime-rebind.js`),n=await t(e);if(n.kind!==`confirmed`)throw new r(`COMMAND_FAILED`,`Could not confirm the Android test IME rebind on ${e.name??e.id}.`,{reason:`android_test_ime_rebind_unconfirmed`,rebindCause:n.kind===`not-owned`?`not-owned`:n.cause,deviceId:e.id,hint:`Close and reopen the session to restore the keyboard and reactivate the test IME.`})}async function Rm(e,t,n,r){let i=y(e);await Hm(e,Vm(n,r>0?1:1/0,r),{delayMs:r,sendChunk:async e=>await Pt(i,t,e)}),$(`type`,`test-ime`,n)}async function zm(e,t,n,r,a,o,s){let c=y(e),l=0,u=async()=>(await St(c,t),l+=1,a&&(await Pt(c,t,a),l+=1),await ku(e,n,r,a,s)),d=async()=>{let t=await u();return t.ok||Fu(a,o,t)?t:(Pu(t,o)&&await Lm(e),await ao(e,n,r),l+=1,await u())},f;try{f=await d()}catch(e){throw i(e,l)}return $(`fill`,`test-ime`,a),f}async function Bm(e,t){await Hm(e,Vm(t.text,t.chunkSize,t.delayMs),{delayMs:t.delayMs,sendChunk:async t=>{try{await Wm(e,t)}catch(e){throw ot(e)}}}),$(t.action,`adb-shell`,t.text)}function Vm(e,t,n){let r=e.split(`
18
+ `);return r.flatMap((e,i)=>{let a=$m(e,t),o=i+1===r.length,s=a.map((e,t)=>({kind:`chunk`,text:e,pauseAfter:n>0&&!(o&&t+1===a.length)}));return o?s:[...s,{kind:`enter`}]})}async function Hm(e,t,n){let r=0;try{for(let i of t){if(i.kind===`enter`){await Um(e),r+=1;continue}i.text&&(await n.sendChunk(i.text),r+=1),i.pauseAfter&&await _(n.delayMs)}}catch(e){throw i(e,r)}}async function Um(e){try{await E(e,[`input`,`keyevent`,`ENTER`])}catch(e){throw ot(e)}}async function Wm(e,t){try{await E(e,[`input`,`text`,Xm(t)])}catch(e){throw Zm(e)?Qm(t,e):e}}async function Gm(e,t){let n=Math.max(0,t),r=0;try{await E(e,[`input`,`keyevent`,`KEYCODE_MOVE_END`],{allowFailure:!0}),r+=1;for(let t=0;t<n;t+=24){let i=Math.min(24,n-t);await E(e,[`input`,`keyevent`,...Array(i).fill(`KEYCODE_DEL`)],{allowFailure:!0}),r+=1}}catch(e){throw i(e,r)}}async function Km(e,t){try{return await Lo(e)}catch(e){return g({level:`warn`,phase:`android_input_ownership_probe_failed`,data:{action:t,error:e instanceof Error?e.message:String(e)}}),null}}function qm(e,t){if(!(!e||e.inputOwner!==`ime`))throw new r(`COMMAND_FAILED`,`KEYBOARD_OVERLAY_BLOCKING: Android text input is blocked because the focused input belongs to the active keyboard/IME.`,{failureReason:`ime_capture`,action:t,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 Jm(e){if(!Ym(e))throw Qm(e)}function Ym(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 Xm(e){return e.replaceAll(` `,`%s`)}function Zm(e){if(!(e instanceof r)||e.code!==`COMMAND_FAILED`)return!1;let t=e.details?.stderr,n=(typeof t==`string`?t:``).toLowerCase();return!!(n.includes(`exception occurred while executing 'text'`)||n.includes(`nullpointerexception`)&&n.includes(`inputshellcommand.sendtext`))}function Qm(e,t){return new r(`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.`,{backend:`adb-shell`,reason:ie,textLength:Array.from(e).length,textPreview:e.slice(0,32),hint:"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)."},t instanceof Error?t:void 0)}function $m(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){g({phase:`android_text_injection`,data:{action:e,backend:t,textLength:Array.from(n).length}})}function eh(e,t,n){return Math.max(t,Math.min(n,e))}var th=e({ANDROID_FOCUSED_WINDOW_MARKER:()=>cn,ANDROID_FOCUS_MARKERS:()=>on,ANDROID_IME_HELPER_SERVICE_COMPONENT:()=>Nt,ANDROID_SNAPSHOT_PRESENTATION_DEFAULT_DEADLINE_MS:()=>250,ANDROID_TEST_IME_SETTINGS_KEYS:()=>rs,ANDROID_TOUCH_PLAN_PROTOCOL:()=>wa,AndroidSnapshotPresentationFailure:()=>X,activateAndroidTestIme:()=>id,androidAdbForwardsDeviceExitStatus:()=>bn,androidAdbHostTarget:()=>Ye,androidAdbInvocation:()=>Ke,androidAdbResultError:()=>T,androidAdbSerialTarget:()=>Ge,androidAppsDiscoveryHint:()=>Ht,androidCaptureFailureReasonDetail:()=>qr,androidCaptureFailureReasonFromExitCode:()=>Kr,androidCaptureFailureReasonFromHelperResult:()=>Gr,androidClipboardShellSupportForResult:()=>rh,androidDeviceChecks:()=>Cs,androidFillFailureDetails:()=>zu,androidFillFailureMessage:()=>Ru,androidRevokedPermissionWarning:()=>yp,androidSnapshotPublicationInput:()=>Kl,androidToolchainCheck:()=>Ss,androidUiNodes:()=>$c,annotateAndroidNativePerfError:()=>P,appSwitcherAndroid:()=>ro,attachAdbFailureHint:()=>st,backAndroid:()=>qa,buildAndroidFillUnconfirmedVerification:()=>Fu,buildAndroidNativeToolUnavailableHint:()=>Yr,buildAndroidSnapshotClickabilityEvidence:()=>pl,buildAndroidSnapshotHelperArgs:()=>Oi,buildAndroidSnapshotHelperCaptureOptions:()=>Ei,buildUiHierarchySnapshot:()=>Nc,captureAndroidHeapSnapshot:()=>qf,captureAndroidLogcatWithAdb:()=>ih,captureAndroidSnapshotWithHelper:()=>Ti,captureAndroidSnapshotWithHelperSession:()=>ya,classifyAdbFailure:()=>ut,classifyAndroidAlertIdentifier:()=>Mn,classifyAndroidAppTarget:()=>Ut,classifyAndroidHelperContent:()=>hl,cleanupAndroidNativePerfSession:()=>Cf,clearAndroidImeHelperText:()=>St,clearAndroidTestImeRecoveryMarker:()=>fd,closeAndroidApp:()=>Xt,completeAndroidFillVerification:()=>Nu,createAndroidPortReverseManager:()=>Ze,createAndroidSnapshotCapture:()=>Wl,createAndroidSnapshotPresentationBudget:()=>Oc,createAndroidSnapshotPresentationNode:()=>wc,createAndroidWindowDumpReader:()=>Bt,createDeviceAdbExecutor:()=>Qe,createLocalAndroidAdbProvider:()=>qe,dismissAndroidKeyboard:()=>Ro,dismissAndroidKeyboardWithAdb:()=>zo,doubleTapAndroid:()=>Ga,ensureAndroidEmulatorBooted:()=>en,ensureAndroidImeHelper:()=>Ct,ensureAndroidSdkPathConfigured:()=>zt,ensureAndroidSnapshotHelper:()=>Rr,executeAndroidTouchHelperPlan:()=>Oa,executeAndroidTouchPlan:()=>Ha,fillAndroid:()=>Mm,findAndroidAlertCandidate:()=>Nn,focusAndroid:()=>ao,forceStopAndroidAppWithAdb:()=>So,forgetAndroidSnapshotHelperInstall:()=>jr,formatAndroidInstalledPackageRequiredMessage:()=>Lt,getAndroidAppState:()=>Kt,getAndroidBlockingDialogObservation:()=>$t,getAndroidImeHelperDeviceKey:()=>D,getAndroidKeyboardState:()=>Lo,getAndroidKeyboardStatusWithAdb:()=>W,getAndroidScreenSize:()=>lo,handleAndroidAlert:()=>uo,homeAndroid:()=>Ja,inferAndroidAppName:()=>Yt,inferAndroidPackageAfterOpen:()=>oh,inspectInstalledAndroidHelper:()=>dr,installAndroidAdbPackage:()=>et,installAndroidInstallablePath:()=>Mo,isAmStartError:()=>Gt,isAndroidImeHelperPackage:()=>Ot,isAndroidPermissionPackage:()=>wn,isAndroidSnapshotPresentationFailure:()=>Ec,isAndroidTestImeActive:()=>yt,listAndroidAdbSerialsQuick:()=>bs,listAndroidAppsWithAdb:()=>nh,longPressAndroid:()=>io,lowerAndroidAdbInvocation:()=>He,lowerAndroidTouchPlan:()=>Ba,makeEnsureAndroidHelperInstalled:()=>pr,normalizeAndroidTouchHelperGestureRequest:()=>Na,openAndroidApp:()=>Rt,openAndroidAppWithAdb:()=>wo,openAndroidDevice:()=>Jt,parseAndroidAdbArgv:()=>nt,parseAndroidHelperManifest:()=>wr,parseAndroidLaunchComponent:()=>Zt,parseAndroidLaunchablePackages:()=>an,parseAndroidSnapshotHelperManifest:()=>wr,parseAndroidSnapshotHelperOutput:()=>Ai,parseAndroidUserInstalledPackages:()=>rn,parseInstrumentationRecords:()=>$n,parseUiHierarchyTree:()=>dl,prepareAndroidInstallArtifact:()=>zd,pressAndroid:()=>U,pressAndroidEnter:()=>Ya,pressAndroidTvRemote:()=>Ka,pullAndroidAdbFile:()=>Xe,pushAndroidNotification:()=>Hd,readAndroidBlockingDialogFocus:()=>sn,readAndroidClipboardText:()=>Xo,readAndroidClipboardWithAdb:()=>Zo,readAndroidDefaultInputMethod:()=>J,readAndroidFillTargetBeforeMutation:()=>Mu,readAndroidGestureViewport:()=>Ua,readAndroidHelperManifestInteger:()=>Ft,readAndroidHelperManifestLiteral:()=>bt,readAndroidSetting:()=>pm,readAndroidTestImeRecoveryMarkers:()=>pd,readAndroidTextAtPoint:()=>Au,readAndroidTextAtPointInHierarchy:()=>Lu,readAndroidTouchHelperFinalRecord:()=>Ia,readAndroidTouchHelperViewportReading:()=>ka,readInstrumentationResultBoolean:()=>or,readInstrumentationResultNumber:()=>j,resetAndroidAdbShellProtocolProbes:()=>xn,resetAndroidFramePerfStats:()=>vf,resetAndroidImeHelperInstallCache:()=>Tt,resetAndroidSnapshotHelperInstallCache:()=>Pr,resetAndroidSnapshotHelperRuntime:()=>Hl,resetAndroidSnapshotHelperSessions:()=>va,resetAndroidTestImeActivationCacheForTests:()=>Mt,resetAndroidWindowDumpFocusMemoForTests:()=>Vt,resolveAndroidAdbExecutor:()=>y,resolveAndroidAdbProvider:()=>x,resolveAndroidApp:()=>qt,resolveAndroidArchivePackageName:()=>vd,resolveAndroidHelperArtifact:()=>fr,resolveAndroidImeHelperArtifact:()=>wt,resolveAndroidPackageForOpen:()=>ah,resolveAndroidSnapshotHelperCaptureOptions:()=>Di,resolveAndroidTextInjector:()=>$e,resolveAndroidTouchProvider:()=>Ue,resolveScopedAndroidAdbBackgroundTransport:()=>Je,restoreAndroidTestIme:()=>hs,restoreOrphanedAndroidTestImeOnDaemonStartup:()=>ys,retireAndroidSnapshotHelperAfterContentFailure:()=>Vl,runAdbExecOut:()=>tt,runAdbShell:()=>b,runAndroidAdb:()=>ft,runAndroidExecOut:()=>dt,runAndroidHostAdb:()=>Ve,runAndroidShell:()=>E,runAndroidSnapshotHelperSessionTouchCommand:()=>xa,sampleAndroidFramePerf:()=>_f,sampleAndroidMemoryPerf:()=>Kf,screenshotAndroid:()=>wm,scrollAndroid:()=>oo,selectAndroidImeHelperArtifact:()=>vt,sendAndroidImeHelperText:()=>Pt,serializeAndroidAdbInvocation:()=>it,setAndroidOrientation:()=>Xa,setAndroidPermission:()=>wp,setAndroidSetting:()=>um,setAndroidTestImeActiveForTests:()=>xt,sleep:()=>_,snapshotAndroid:()=>Jl,startAndroidPerfettoTrace:()=>Nf,startAndroidSimpleperfProfile:()=>Lf,stopAndroidPerfettoTrace:()=>Pf,stopAndroidSimpleperfProfile:()=>Rf,stopAndroidSnapshotHelperSession:()=>V,stopAndroidSnapshotHelperSessionForDevice:()=>_a,typeAndroid:()=>jm,validateAndroidGestureViewport:()=>sr,validateAndroidRegularPresentation:()=>kc,verifyAndroidFilledText:()=>ku,verifyAndroidFilledTextInHierarchy:()=>Iu,verifyAndroidHelperApkChecksum:()=>_r,waitForAndroidBoot:()=>nn,withAndroidAdbProvider:()=>We,withAndroidAppResolutionCacheInvalidated:()=>Wt,withAndroidHostAdbTransport:()=>rt,writeAndroidClipboardText:()=>Qo,writeAndroidClipboardWithAdb:()=>$o,writeAndroidSimpleperfReport:()=>zf,writeAndroidTestImeRecoveryMarker:()=>dd});async function nh(...e){let{listAndroidAppsWithAdb:t}=await import(`./app-helpers.js`);return await t(...e)}async function rh(...e){let{androidClipboardShellSupportForResult:t}=await import(`./clipboard-shell-response.js`);return t(...e)}async function ih(...e){let{captureAndroidLogcatWithAdb:t}=await import(`./logcat.js`);return await t(...e)}async function ah(...e){let{resolveAndroidPackageForOpen:t}=await import(`./open-target-resolution.js`);return await t(...e)}async function oh(...e){let{inferAndroidPackageAfterOpen:t}=await import(`./open-target-resolution.js`);return await t(...e)}export{io as A,wo as C,Ga as D,qa as E,Xa as F,Ha as I,Ua as L,Ya as M,Ka as N,ao as O,oo as P,So as S,ro as T,W as _,jm as a,Qo as b,um as c,ls as d,J as f,Lo as g,zo as h,Mm as i,U as j,Ja as k,Jl as l,Ro as m,nh as n,wm as o,cs as p,th as r,pm as s,ih as t,Kl as u,Xo as v,uo as w,$o as x,Zo as y};