agent-device 0.21.6 → 0.21.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.6.apk → agent-device-android-ime-helper-0.21.8.apk} +0 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.8.apk.sha256 +1 -0
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.6.manifest.json → agent-device-android-ime-helper-0.21.8.manifest.json} +4 -4
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.6.apk → agent-device-android-snapshot-helper-0.21.8.apk} +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.8.apk.sha256 +1 -0
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.6.manifest.json → agent-device-android-snapshot-helper-0.21.8.manifest.json} +6 -6
- package/apple/macos-helper/Package.swift +16 -1
- package/apple/macos-helper/Sources/AgentDeviceMacOSDeviceHub/DeviceHubPose.swift +47 -0
- package/apple/macos-helper/Sources/AgentDeviceMacOSHelper/DeviceHubPose.swift +320 -0
- package/apple/macos-helper/Sources/AgentDeviceMacOSHelper/main.swift +66 -13
- package/apple/macos-helper/Sources/AgentDeviceMacOSInput/MouseClickDelivery.swift +116 -0
- package/apple/macos-helper/Sources/AgentDeviceMacOSInput/MouseClickSchedule.swift +61 -0
- package/apple/macos-helper/Tests/AgentDeviceMacOSDeviceHubTests/DeviceHubPoseTests.swift +30 -0
- package/apple/macos-helper/Tests/AgentDeviceMacOSInputTests/MouseClickScheduleTests.swift +58 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.h +4 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.m +20 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerScrollViewportPolicy.swift +1 -2
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +25 -12
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +56 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +1 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +36 -108
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Keyboard.swift +241 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +29 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +46 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+PrivateAXPresentation.swift +85 -26
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +134 -117
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotBackendCapabilities.swift +1 -3
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +25 -4
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SystemModal.swift +1 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +3 -0
- package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotCoordinateSpace.swift +197 -0
- package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotModels.swift +30 -4
- package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentation.swift +0 -81
- package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentationInvariant.swift +1 -9
- package/dist/src/absence-observation-errors.js +1 -1
- package/dist/src/adapter.js +1 -1
- package/dist/src/adb-executor.js +2 -2
- package/dist/src/adb-failure.js +1 -1
- package/dist/src/adb-transport.js +1 -1
- package/dist/src/adb.js +1 -1
- package/dist/src/agent-browser-lifecycle.js +1 -1
- package/dist/src/agent-browser-process-record.js +1 -1
- package/dist/src/agent-browser-provider.js +1 -1
- package/dist/src/agent-browser-tool.js +1 -1
- package/dist/src/agent-device-client.js +2 -2
- package/dist/src/ai-sdk.js +1 -1
- package/dist/src/alert-runtime.js +1 -1
- package/dist/src/android-adb.d.ts +29 -2
- package/dist/src/android-adb.js +1 -1
- package/dist/src/android-input-ownership.js +1 -1
- package/dist/src/android.js +1 -1
- package/dist/src/app-catalog.js +1 -1
- package/dist/src/app-deployment-resolution.js +1 -1
- package/dist/src/app-helpers.js +1 -1
- package/dist/src/app-inventory.js +1 -1
- package/dist/src/app-launch.js +2 -2
- package/dist/src/app-lifecycle.js +2 -2
- package/dist/src/app-lifecycle2.js +2 -2
- package/dist/src/app-log-files.js +1 -1
- package/dist/src/app-log-runtime2.js +3 -3
- package/dist/src/app-resolution.js +2 -2
- package/dist/src/app-state.js +1 -1
- package/dist/src/apple-runner-platform.js +1 -1
- package/dist/src/application-lifecycle-interaction.js +1 -1
- package/dist/src/archive.js +1 -1
- package/dist/src/artifact-download.js +1 -1
- package/dist/src/auth-session.js +1 -1
- package/dist/src/auth.js +1 -1
- package/dist/src/back-mode.js +1 -1
- package/dist/src/backend-snapshot-options.js +1 -1
- package/dist/src/boot-diagnostics.js +1 -1
- package/dist/src/capture-disclosure.js +1 -0
- package/dist/src/capture.js +1 -1
- package/dist/src/cli-config.js +1 -1
- package/dist/src/cli-help.js +18 -2
- package/dist/src/cli-output.js +1 -1
- package/dist/src/cli.js +4 -4
- package/dist/src/click-button.js +1 -1
- package/dist/src/client-metro.js +1 -1
- package/dist/src/client-types.d.ts +65 -3
- package/dist/src/clipboard-shell-response.js +1 -0
- package/dist/src/command-schema.js +1 -1
- package/dist/src/command-tools.js +4 -2
- package/dist/src/command.js +1 -1
- package/dist/src/config.js +1 -1
- package/dist/src/connection-runtime.js +1 -1
- package/dist/src/connection.js +1 -1
- package/dist/src/contracts.d.ts +1 -1
- package/dist/src/contracts.js +1 -1
- package/dist/src/daemon-client-lifecycle.js +1 -1
- package/dist/src/daemon.js +1 -1
- package/dist/src/debug-symbols-facade.js +1 -1
- package/dist/src/device-boot.js +1 -1
- package/dist/src/device-claim-inspection.js +1 -1
- package/dist/src/device-claim-rule.js +2 -1
- package/dist/src/device-input-state.d.ts +5 -5
- package/dist/src/device-inventory-context.js +1 -1
- package/dist/src/device-rotation.js +1 -1
- package/dist/src/device-selection-resolver.js +1 -1
- package/dist/src/device-session.js +1 -1
- package/dist/src/device-shell.js +1 -0
- package/dist/src/device.js +1 -1
- package/dist/src/device2.js +1 -1
- package/dist/src/devicectl.js +1 -0
- package/dist/src/diagnostics.js +1 -1
- package/dist/src/dispatch-resolve.js +1 -1
- package/dist/src/display-inventory.js +1 -0
- package/dist/src/doctor-facade.js +1 -1
- package/dist/src/doctor2.js +1 -1
- package/dist/src/durable-resource.js +1 -1
- package/dist/src/engine-eval-script.js +1 -1
- package/dist/src/error.js +1 -1
- package/dist/src/exec.js +1 -1
- package/dist/src/file.js +1 -1
- package/dist/src/find.js +1 -1
- package/dist/src/finders.js +1 -1
- package/dist/src/format.js +2 -1
- package/dist/src/generic.js +1 -1
- package/dist/src/gesture-admission.js +1 -1
- package/dist/src/gesture-plan.js +1 -1
- package/dist/src/gesture-runtime.js +1 -1
- package/dist/src/harmonyos.js +1 -1
- package/dist/src/hdc.js +1 -1
- package/dist/src/helper.js +2 -2
- package/dist/src/host.js +1 -0
- package/dist/src/human-control-contract.js +1 -1
- package/dist/src/human-control.js +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/input-actions.js +1 -1
- package/dist/src/input-actions2.js +1 -1
- package/dist/src/install-artifact-facade.js +1 -1
- package/dist/src/install-source-network-transport.js +1 -1
- package/dist/src/install-source2.js +1 -1
- package/dist/src/interaction-positionals.js +1 -1
- package/dist/src/interaction-ref-policy.js +1 -1
- package/dist/src/interaction.js +1 -1
- package/dist/src/interaction2.js +1 -1
- package/dist/src/interactor-operation-binding.js +1 -0
- package/dist/src/interactor-operation-catalog.js +1 -1
- package/dist/src/interactor.js +4 -5
- package/dist/src/interactor2.js +1 -1
- package/dist/src/interactors.js +1 -1
- package/dist/src/internal/bin.js +1 -1
- package/dist/src/internal/daemon.js +2 -2
- package/dist/src/internal/png-worker.d.ts +9 -1
- package/dist/src/internal/png-worker.js +1 -1
- package/dist/src/internal/run-script-http-child.js +1 -1
- package/dist/src/inventory.js +4 -4
- package/dist/src/inventory2.js +1 -1
- package/dist/src/inventory3.js +2 -2
- package/dist/src/inventory5.js +1 -1
- package/dist/src/ios-snapshot-acquisition.js +1 -1
- package/dist/src/ios-snapshot-runtime.js +1 -1
- package/dist/src/ios-target-activation.js +1 -0
- package/dist/src/lease-context.js +1 -1
- package/dist/src/lease-scope.js +1 -1
- package/dist/src/lease.js +1 -1
- package/dist/src/limrun-download-file.js +1 -0
- package/dist/src/limrun-runtime-dependencies.js +1 -1
- package/dist/src/limrun.d.ts +10 -4
- package/dist/src/linux.js +1 -1
- package/dist/src/local-interactor-operation-set.js +1 -1
- package/dist/src/location-coordinates.js +1 -1
- package/dist/src/macos-facade.js +1 -1
- package/dist/src/managed-device-scope.js +1 -1
- package/dist/src/mechanics.js +17 -16
- package/dist/src/mobile-snapshot-semantics.js +1 -1
- package/dist/src/multitouch-support.js +1 -1
- package/dist/src/observation.js +2 -2
- package/dist/src/output-common.js +5 -2
- package/dist/src/parameterized-recorded-fill.js +1 -1
- package/dist/src/perf-facade.js +2 -2
- package/dist/src/perf-runtime-operation-builder.js +1 -1
- package/dist/src/perf-runtime-plan.js +1 -1
- package/dist/src/perf.js +1 -1
- package/dist/src/physical-device-control.js +1 -1
- package/dist/src/platform-request-scope.js +1 -1
- package/dist/src/platform-runtime-android-adb-host.js +1 -1
- package/dist/src/platform-runtime-host.js +1 -1
- package/dist/src/platform-runtime-managed-owner.js +1 -1
- package/dist/src/platform-runtime-open-target.js +1 -1
- package/dist/src/platform-runtime-operation-host.js +4 -4
- package/dist/src/platform-runtime-runtime-hints.js +2 -2
- package/dist/src/platform-runtime-screen-recording-android-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-apple-runner-transport.js +1 -1
- package/dist/src/platform-runtime-screen-recording-apple-simulator-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-apple-transport.js +1 -1
- package/dist/src/platform-runtime-screen-recording-finalizer-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-harmony-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-process-host.js +1 -1
- package/dist/src/platform-runtime-unavailable.js +1 -1
- package/dist/src/platform-runtime.js +1 -1
- package/dist/src/platform-runtime2.js +1 -1
- package/dist/src/png-crop-bytes.js +1 -1
- package/dist/src/png-worker-client.js +1 -0
- package/dist/src/png.js +1 -1
- package/dist/src/prepare-kind.js +1 -1
- package/dist/src/provider-session-ownership.js +1 -1
- package/dist/src/provider-webdriver.js +1 -1
- package/dist/src/proxy.js +1 -1
- package/dist/src/quality-warnings.js +1 -1
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-runtime.js +1 -1
- package/dist/src/record-trace.js +1 -1
- package/dist/src/rect-center.js +1 -1
- package/dist/src/register-builtins.js +1 -1
- package/dist/src/registry.js +35 -35
- package/dist/src/remote-config2.js +1 -1
- package/dist/src/replay-divergence.js +1 -1
- package/dist/src/replay.js +1 -1
- package/dist/src/reporting.js +1 -1
- package/dist/src/request-admission.js +1 -1
- package/dist/src/request-cancel.js +1 -1
- package/dist/src/request-runtime-binding.js +1 -1
- package/dist/src/result-serialization.js +1 -1
- package/dist/src/retry.js +1 -1
- package/dist/src/runner-cache-metadata.js +2 -2
- package/dist/src/runner-client.js +1 -1
- package/dist/src/runner-contract.js +3 -0
- package/dist/src/runner-dev-tools-security.js +1 -0
- package/dist/src/runner-device-readiness.js +1 -0
- package/dist/src/runner-disposal.js +1 -1
- package/dist/src/runner-operations-facade.js +1 -1
- package/dist/src/runner-presentation.js +1 -1
- package/dist/src/runner.js +1 -1
- package/dist/src/runtime-transport-hints.js +1 -1
- package/dist/src/runtime.js +3 -3
- package/dist/src/runtime10.js +1 -1
- package/dist/src/runtime2.js +4 -4
- package/dist/src/runtime3.js +1 -1
- package/dist/src/runtime4.js +5 -5
- package/dist/src/runtime5.js +1 -1
- package/dist/src/runtime6.js +1 -1
- package/dist/src/runtime7.js +1 -1
- package/dist/src/runtime8.js +1 -1
- package/dist/src/runtime9.js +1 -1
- package/dist/src/screen-recording-admission-ledger.js +1 -0
- package/dist/src/screen-recording-completion.js +1 -1
- package/dist/src/screen-recording-options.js +1 -1
- package/dist/src/screen-recording-resource-recovery.js +1 -1
- package/dist/src/screen-recording-transport.js +1 -0
- package/dist/src/screenshot-density.js +1 -1
- package/dist/src/screenshot-image.js +1 -0
- package/dist/src/screenshot-runtime.js +1 -1
- package/dist/src/screenshot.js +1 -1
- package/dist/src/screenshot3.js +1 -1
- package/dist/src/script.js +1 -1
- package/dist/src/scroll-command.js +1 -1
- package/dist/src/scroll-gesture.js +1 -1
- package/dist/src/sdk-batch-runner.js +2 -2
- package/dist/src/sdk-batch.js +2 -2
- package/dist/src/sdk-contracts.d.ts +76 -1
- package/dist/src/sdk-contracts.js +2 -2
- package/dist/src/sdk-device.js +1 -1
- package/dist/src/sdk-finders.d.ts +1 -1
- package/dist/src/sdk-finders.js +1 -1
- package/dist/src/sdk-io.js +1 -1
- package/dist/src/sdk-remote-config.js +1 -1
- package/dist/src/sdk-selectors.d.ts +29 -3
- package/dist/src/sdk-selectors.js +1 -1
- package/dist/src/selection.js +0 -0
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/selectors.js +1 -1
- package/dist/src/semantic-index.js +1 -1
- package/dist/src/server.js +1 -1
- package/dist/src/session-allocation.js +1 -1
- package/dist/src/session-observation.js +1 -1
- package/dist/src/session-routing.js +1 -1
- package/dist/src/session-runtime-admission.js +1 -1
- package/dist/src/session-snapshot.js +1 -1
- package/dist/src/session-store.js +3 -3
- package/dist/src/session2.js +4 -5
- package/dist/src/settings.js +1 -1
- package/dist/src/simctl-facade.js +1 -1
- package/dist/src/simctl.js +1 -1
- package/dist/src/simulator-boot.js +1 -1
- package/dist/src/simulator-facade.js +1 -1
- package/dist/src/simulator.js +1 -1
- package/dist/src/snapshot-capture-annotations.js +1 -1
- package/dist/src/snapshot-diagnostics.js +1 -1
- package/dist/src/snapshot-quality-backend-capabilities.js +1 -1
- package/dist/src/snapshot-runtime-binding.js +1 -1
- package/dist/src/snapshot-runtime.js +1 -1
- package/dist/src/snapshot-state.js +1 -1
- package/dist/src/snapshot.js +1 -1
- package/dist/src/snapshot2.js +1 -1
- package/dist/src/snapshot3.js +1 -1
- package/dist/src/snapshot4.js +1 -1
- package/dist/src/src.js +1 -1
- package/dist/src/src4.js +1 -1
- package/dist/src/src7.js +1 -1
- package/dist/src/src8.js +2 -2
- package/dist/src/stop-sequence.js +1 -1
- package/dist/src/string-enum.js +1 -1
- package/dist/src/takeover.js +1 -1
- package/dist/src/text-entry-focus.js +1 -1
- package/dist/src/tool-provider.js +1 -1
- package/dist/src/tool-provider2.js +1 -1
- package/dist/src/touch-runtime.js +1 -1
- package/dist/src/transport.js +1 -1
- package/dist/src/tree.js +1 -1
- package/dist/src/tv-remote.js +1 -1
- package/dist/src/type-text-runtime.js +1 -1
- package/dist/src/verified-file.js +1 -1
- package/dist/src/video.js +1 -1
- package/dist/src/viewport.js +1 -1
- package/dist/src/web.js +1 -1
- package/dist/src/web2.js +1 -1
- package/dist/src/webdriver-source.js +1 -1
- package/dist/src/window-state.js +1 -1
- package/package.json +4 -1
- package/server.json +2 -2
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.6.apk.sha256 +0 -1
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.6.apk.sha256 +0 -1
- package/dist/src/session-target-evidence.js +0 -1
- package/dist/src/vars.js +0 -2
package/dist/src/mechanics.js
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime.js";import{
|
|
2
|
-
`).map(e=>e.trim()).filter(Boolean)}const
|
|
3
|
-
`):void 0}function ln(e,t){let n=t[0];if(!n)return;let r=un(e,n.index);for(let n of t.slice(1)){let t=new Set(un(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 un(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 dn(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 fn(e){let t=e.bundleId??``;return zt.has(t)||Wt.test(e.identifier??``)}function pn(e){let t=e.bundleId??``;return Vt.has(t)&&Gt.test(T(e))}function mn(e){let t=e.type??``,n=e.identifier??``;return!!(e.hittable||/\bbutton\b/i.test(t)||Ut.test(n)||/(?:^|:)id\/permission_(?:allow|deny)/i.test(n))}function T(e){return e?[e.label,e.value].filter(e=>typeof e==`string`&&e.trim().length>0)[0]?.trim()??``:``}function hn(e){return e.find(e=>e.bundleId)?.bundleId}function gn(e,n,r){if(typeof e!=`number`||!Number.isInteger(e))throw new t(`INVALID_ARGS`,`Android ${r} manifest ${n} must be an integer.`);return e}function E(e,n,r,i){if(e!==r)throw new t(`INVALID_ARGS`,`Android ${i} manifest ${n} must be "${r}".`);return r}function _n(e,n,r){if(typeof e!=`string`||e.length===0)throw new t(`INVALID_ARGS`,`Android ${r} manifest ${n} is required.`);return e}function vn(e,n){let r=_n(e,`sha256`,n).trim().toLowerCase();if(r.length!==64||!/^[0-9a-f]+$/.test(r))throw new t(`INVALID_ARGS`,`Android ${n} manifest sha256 must be a 64-character hex string.`);return r}function yn(e){let t={status:[],results:[],currentStatus:null,currentResult:null};for(let n of e.split(/\r?\n/))bn(n,t);return xn(t),{status:t.status,results:t.results}}function bn(e,t){if(e.startsWith(`INSTRUMENTATION_STATUS: `)){t.currentStatus??={},wn(e.slice(24),t.currentStatus);return}if(e.startsWith(`INSTRUMENTATION_STATUS_CODE: `)){Sn(t);return}if(e.startsWith(`INSTRUMENTATION_RESULT: `)){t.currentResult??={},wn(e.slice(24),t.currentResult);return}e.startsWith(`INSTRUMENTATION_CODE: `)&&Cn(t)}function xn(e){Sn(e),Cn(e)}function Sn(e){e.currentStatus&&=(e.status.push(e.currentStatus),null)}function Cn(e){e.currentResult&&=(e.results.push(e.currentResult),null)}function wn(e,t){let n=e.indexOf(`=`);n<0||(t[e.slice(0,n)]=e.slice(n+1))}function D(e){if(e===void 0)return;let t=Number(e);return Number.isFinite(t)?t:void 0}function O(e){if(e===`true`)return!0;if(e===`false`)return!1}function k(e){if(!Number.isFinite(e.x)||!Number.isFinite(e.y)||!Number.isFinite(e.width)||!Number.isFinite(e.height)||e.width<=0||e.height<=0)throw new t(`COMMAND_FAILED`,`Android helper returned an invalid gesture viewport`);return e}const Tn=1e4;async function En(e,t){try{return await ze(e,t)}catch(e){throw Je(e)}}async function Dn(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 Pn(a,o,u);let f=await On({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 En(a,{provider:n,replace:!0,allowFailure:!0,timeoutMs:l});if(p.exitCode!==0)throw S(`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 On(e){let{adb:t,adbProvider:n,packageName:r,versionCode:i,sha256:a,signal:o}=e,s=await jn(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 Mn(t,n,r,o);return{installedVersionCode:s,installedSha256:e,reason:e===a?`current`:`mismatched`}}catch{return o?.throwIfAborted(),{installedVersionCode:s,reason:`unverifiable`}}}async function kn(e){let r=y().files,i=De(),a=w.join(Ee(),`android`,e.helperDirName,`dist`),o=w.join(a,e.manifestFileName(i));try{let t=e.parseManifest(JSON.parse(await r.readText(o))),n=w.join(a,t.assetName);return await r.access(n),{apkPath:n,manifest:t}}catch(r){throw new t(`UNSUPPORTED_OPERATION`,e.unavailableMessage,{manifestPath:o,error:n(r).message},r)}}function An(e){return async t=>await Dn({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 jn(e,t,n){let r=await e([`shell`,`cmd`,`package`,`list`,`packages`,`--show-versioncode`,t],{allowFailure:!0,timeoutMs:5e3,signal:n});if(r.exitCode!==0)return;let i=RegExp(`package:${In(t)}(?:\\s|$).*versionCode:(\\d+)`).exec(`${r.stdout}\n${r.stderr}`);return i?Number(i[1]):void 0}async function Mn(e,n,r,i){let a=await e([`shell`,`pm`,`path`,r],{allowFailure:!0,timeoutMs:Tn,signal:i}),o=Nn(`${a.stdout}\n${a.stderr}`);if(a.exitCode!==0||!o)throw new t(`COMMAND_FAILED`,`Could not resolve installed Android helper APK`);let s=y().files,c=await s.makeTempDirectory(`agent-device-helper-`),l=w.join(c,`base.apk`);try{let e=await Ie(o,l,{provider:n,allowFailure:!0,timeoutMs:Tn,signal:i});if(e.exitCode!==0)throw S(`Could not read installed Android helper APK`,e,{packageName:r,remotePath:o});return await Fn(l)}finally{await s.remove(c,{recursive:!0,force:!0})}}function Nn(e){return e.split(/\r?\n/).map(e=>e.startsWith(`package:`)?e.slice(8).trim():``).find(e=>e.endsWith(`/base.apk`))}async function Pn(e,n,r){let i=await Fn(e);if(i!==n)throw new t(`COMMAND_FAILED`,`${r} APK checksum mismatch`,{apkPath:e,expectedSha256:n,actualSha256:i})}async function Fn(e){let t=y().files;return t.sha256(await t.readBytes(e))}function In(e){return e.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`)}const Ln=`android-snapshot-helper-v1`,Rn=`uiautomator-xml`,zn=5e3,Bn=3e4;function Vn(e){if(!e||typeof e!=`object`||Array.isArray(e))throw new t(`INVALID_ARGS`,`Android snapshot helper manifest must be an object.`);let n=e;return{name:Un(n.name,`name`,`android-snapshot-helper`),version:A(n.version,`version`),releaseTag:Gn(n.releaseTag),assetName:Gn(n.assetName),apkUrl:Kn(n.apkUrl,`apkUrl`),sha256:Wn(n.sha256),checksumName:Gn(n.checksumName),packageName:A(n.packageName,`packageName`),versionCode:Hn(n.versionCode,`versionCode`),instrumentationRunner:A(n.instrumentationRunner,`instrumentationRunner`),minSdk:Hn(n.minSdk,`minSdk`),targetSdk:n.targetSdk===void 0?void 0:Hn(n.targetSdk,`targetSdk`),outputFormat:Un(n.outputFormat,`outputFormat`,Rn),statusProtocol:Un(n.statusProtocol,`statusProtocol`,Ln)}}function Hn(e,t){return gn(e,t,`snapshot helper`)}function Un(e,t,n){return E(e,t,n,`snapshot helper`)}function Wn(e){let n=A(e,`sha256`).trim().toLowerCase();if(n.length!==64||!qn(n))throw new t(`INVALID_ARGS`,`Android snapshot helper manifest sha256 must be a 64-character hex string.`);return n}function A(e,n){if(typeof e!=`string`||e.trim().length===0)throw new t(`INVALID_ARGS`,`Android snapshot helper manifest ${n} is required.`);return e}function Gn(e){return typeof e==`string`&&e.trim().length>0?e:void 0}function Kn(e,t){return e===null?null:A(e,t)}function qn(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 j=new Map;function Jn(e){let t=`${e.deviceKey}\0${e.packageName}\0${e.versionCode}\0`;for(let e of j.keys())e.startsWith(t)&&Qn(e)}function Yn(){j.clear()}function Xn(e,t,n,r){return e?`${e}\0${t}\0${n}\0${r}`:void 0}function Zn(e,t){if(!e)return;let[n,r]=e.split(`\0`),i=`${n}\0${r}\0`;for(let t of j.keys())t!==e&&t.startsWith(i)&&j.delete(t);j.set(e,t)}function Qn(e){e&&j.delete(e)}async function $n(e){let{adb:t,artifact:n}=e,r=e.installPolicy??`missing-or-outdated`,i=n.manifest.packageName,a=n.manifest.versionCode,o=n.manifest.sha256;if(r===`never`)return{packageName:i,versionCode:a,installed:!1,reason:`skipped`};let s=Xn(e.deviceKey,i,a,o),c=s?j.get(s):void 0;if(s&&r!==`always`&&c!==void 0)return{packageName:i,versionCode:a,installedVersionCode:c,installedSha256:o,installed:!1,reason:`current`};await Pn(n.apkPath,o,`Android snapshot helper`);let l=r===`always`?{installedVersionCode:await nr(t,i,e.timeoutMs,e.signal),reason:`forced`}:await On({adb:t,adbProvider:tr(e.adbProvider,t),packageName:i,versionCode:a,sha256:o,signal:e.signal}),{installedVersionCode:u}=l,d=`installedSha256`in l?l.installedSha256:void 0,f=l.reason;if(f===`current`){if(u===void 0)throw Error(`Expected installed versionCode for current Android snapshot helper`);return Zn(s,u),{packageName:i,versionCode:a,installedVersionCode:u,installedSha256:d,installed:!1,reason:f}}let p;try{p=await rr(t,e.adbProvider??t,n.apkPath,{packageName:i,timeoutMs:e.timeoutMs,signal:e.signal})}catch(e){throw Qn(s),er(e,{packageName:i,versionCode:a})}if(p.exitCode!==0)throw Qn(s),er(S(`Failed to install Android snapshot helper`,p,{packageName:i,versionCode:a}));return Zn(s,a),{packageName:i,versionCode:a,installedVersionCode:u,installedSha256:d,installed:!0,reason:f}}function er(e,t){let n=a(e,`COMMAND_FAILED`);return n.details={...t,...n.details,androidSnapshotHelperInstallFailure:!0},n}function tr(e,t){return e?typeof e==`function`?{exec:e}:e:{exec:t}}async function nr(e,t,n,r){let i=await e([`shell`,`cmd`,`package`,`list`,`packages`,`--show-versioncode`,t],{allowFailure:!0,timeoutMs:n,signal:r});if(i.exitCode===0)return ir(`${i.stdout}\n${i.stderr}`,t)}async function rr(e,t,n,r){let i=async()=>await En(n,{allowFailure:!0,provider:t,replace:!0,timeoutMs:r.timeoutMs,signal:r.signal}),a=await i();if(a.exitCode===0||!ar(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
|
|
1
|
+
import{r as e}from"./rolldown-runtime.js";import{D as t,L as n,O as r,U as i,g as a,m as o}from"./sdk-contracts.js";import"./capture.js";import{D as s}from"./sdk-batch-runner.js";import{a as c,d as l,i as u,l as d,o as f,r as p,t as ee,u as te}from"./android-input-ownership.js";import{Br as ne,Ur as re,Vr as ie,zr as ae}from"./sdk-batch.js";import{i as oe,n as se,r as ce}from"./snapshot-scope.js";import{_ as le,d as ue,p as de}from"./scroll-gesture.js";import{r as fe}from"./success-text.js";import{n as pe}from"./alert-contract.js";import{f as me,n as he,p as ge}from"./location-coordinates.js";import{r as _e}from"./mobile-snapshot-semantics.js";import"./device.js";import{n as ve}from"./device-rotation.js";import{c as m,r as h}from"./diagnostics.js";import{a as ye,c as be,h as xe,n as Se,s as Ce}from"./exec.js";import{t as g}from"./timeouts.js";import{i as we}from"./tv-remote.js";import"./diagnostics2.js";import"./command.js";import{a as _,n as Te,o as v}from"./device-shell.js";import"./retry.js";import{n as Ee,r as De}from"./version.js";import{n as Oe,r as ke}from"./install-source2.js";import{_ as Ae,a as y,c as je,d as b,f as Me,g as x,h as S,i as Ne,l as Pe,n as Fe,o as C,p as Ie,r as Le,s as Re,t as ze,u as Be,v as Ve}from"./adb-executor.js";import{c as He,h as Ue,i as We,o as Ge,r as Ke,u as qe}from"./adb-transport.js";import{i as Je,n as w,o as Ye,s as Xe}from"./adb-failure.js";import{a as Ze,i as Qe,n as $e,o as T}from"./adb.js";import{i as et,n as tt,r as nt}from"./gesture-plan.js";import{n as rt,r as it,s as at}from"./android-system-chrome.js";import{a as ot,c as st,i as ct,l as lt,n as ut,o as dt,r as ft,s as pt,u as mt}from"./app-lifecycle.js";import{a as ht,i as gt,n as _t,o as vt,r as yt,t as bt}from"./app-deployment-resolution.js";import{a as xt,i as St,n as Ct,o as wt,t as Tt}from"./app-parsers.js";import{i as Et,n as Dt,r as Ot,t as kt}from"./window-state.js";import{n as At}from"./toolchain-probe.js";import{t as jt}from"./keyed-lock.js";import{t as Mt}from"./bounds.js";import{t as Nt}from"./entities.js";import{n as Pt}from"./startup-recovery-fence.js";import{n as Ft}from"./numeric.js";import E from"node:path";import It from"node:net";import{TextDecoder as Lt}from"node:util";const Rt=new Map;async function zt(e){let t=Rt.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=Vt(n).includes(`shell_v2`);return Rt.set(e.deviceKey,r),r}function Bt(){Rt.clear()}function Vt(e){return e.split(`
|
|
2
|
+
`).map(e=>e.trim()).filter(Boolean)}const Ht=new Set([`com.android.permissioncontroller`,`com.google.android.permissioncontroller`,`com.google.android.packageinstaller`,`com.android.packageinstaller`]);function Ut(e){return Ht.has(e)}const Wt=new Set([`android`,`com.android.systemui`]),Gt=/^android:id\/(?:alertTitle|message|button[123]|parentPanel|buttonPanel|contentPanel)$/i,Kt=/^android:id\/button[123]$/i,qt=/(?:^|:)id\/permission_/i,Jt=/\b(?:is(?:n't| not) responding|keeps stopping|has stopped|close app|app info)\b/i,Yt=/^(?:ok|allow|allow all|while using the app|only this time|yes|continue|save|confirm|turn on|open settings)$/i,Xt=/^(?:cancel|deny|don.t allow|don’t allow|not now|no|dismiss|close|close app|later|skip)$/i;function Zt(e){if(e!==null){if(Kt.test(e))return`button`;if(Gt.test(e))return`content`}}function Qt(e){let t=tn(e.filter($t)),n=t.nodes;if(n.length===0)return null;let r=sn(n),i=n.filter(e=>D(e)&&!_n(e)),a=un(i),o=dn(i,a);if(!a&&!o&&r.length===0)return null;let s=vn(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 $t(e){return!d(e)}function en(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 tn(e){let t=e.filter(e=>hn(e));if(t.length)return{nodes:t,source:`permission`};let n=on(e);return n.length?{nodes:n,source:`system-dialog`}:{nodes:nn(e),source:`native-dialog`}}function nn(e){let t=e.filter(e=>rn(e.type??``)),n=e.filter(e=>Gt.test(e.identifier??``)),r=t.length?[...t,...n]:an(n);if(r.length===0)return[];let i=fn(e,r);return i===void 0?r:mn(e,i)}function rn(e){let t=Math.max(e.lastIndexOf(`.`),e.lastIndexOf(`$`));return e.slice(t+1).toLowerCase().endsWith(`dialog`)}function an(e){let t=e.some(e=>Kt.test(e.identifier??``)),n=e.some(e=>!Kt.test(e.identifier??``));return t&&n?e:[]}function on(e){let t=e.filter(e=>gn(e));if(t.length===0)return[];let n=fn(e,t);return n===void 0?t:mn(e,n).filter(e=>e.bundleId&&Wt.has(e.bundleId))}function sn(e){let t=new Set,n=[];for(let r of e){let e=D(r);if(!e||!r.rect||!_n(r))continue;let i=e.trim().toLowerCase();if(!i||t.has(i))continue;t.add(i);let o=a(r.rect);n.push({label:e,x:o.x,y:o.y,role:cn(r,e)})}return n}function cn(e,t){return ln(e.identifier??``)||(Yt.test(t.trim())?`accept`:Xt.test(t.trim())?`dismiss`:`neutral`)}function ln(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 un(e){return D(e.find(e=>/(?:^|:)id\/(?:alertTitle|permission_message)$/i.test(e.identifier??``)))||D(e[0])}function dn(e,t){let n=e.map(e=>D(e)).filter(e=>e&&e!==t);return n.length?[...new Set(n)].join(`
|
|
3
|
+
`):void 0}function fn(e,t){let n=t[0];if(!n)return;let r=pn(e,n.index);for(let n of t.slice(1)){let t=new Set(pn(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 pn(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 mn(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 hn(e){let t=e.bundleId??``;return Ht.has(t)||qt.test(e.identifier??``)}function gn(e){let t=e.bundleId??``;return Wt.has(t)&&Jt.test(D(e))}function _n(e){let t=e.type??``,n=e.identifier??``;return!!(e.hittable||/\bbutton\b/i.test(t)||Kt.test(n)||/(?:^|:)id\/permission_(?:allow|deny)/i.test(n))}function D(e){return e?[e.label,e.value].filter(e=>typeof e==`string`&&e.trim().length>0)[0]?.trim()??``:``}function vn(e){return e.find(e=>e.bundleId)?.bundleId}function yn(e,n,r){if(typeof e!=`number`||!Number.isInteger(e))throw new t(`INVALID_ARGS`,`Android ${r} manifest ${n} must be an integer.`);return e}function O(e,n,r,i){if(e!==r)throw new t(`INVALID_ARGS`,`Android ${i} manifest ${n} must be "${r}".`);return r}function bn(e,n,r){if(typeof e!=`string`||e.length===0)throw new t(`INVALID_ARGS`,`Android ${r} manifest ${n} is required.`);return e}function xn(e,n){let r=bn(e,`sha256`,n).trim().toLowerCase();if(r.length!==64||!/^[0-9a-f]+$/.test(r))throw new t(`INVALID_ARGS`,`Android ${n} manifest sha256 must be a 64-character hex string.`);return r}function Sn(e){let t={status:[],results:[],currentStatus:null,currentResult:null};for(let n of e.split(/\r?\n/))Cn(n,t);return wn(t),{status:t.status,results:t.results}}function Cn(e,t){if(e.startsWith(`INSTRUMENTATION_STATUS: `)){t.currentStatus??={},Dn(e.slice(24),t.currentStatus);return}if(e.startsWith(`INSTRUMENTATION_STATUS_CODE: `)){Tn(t);return}if(e.startsWith(`INSTRUMENTATION_RESULT: `)){t.currentResult??={},Dn(e.slice(24),t.currentResult);return}e.startsWith(`INSTRUMENTATION_CODE: `)&&En(t)}function wn(e){Tn(e),En(e)}function Tn(e){e.currentStatus&&=(e.status.push(e.currentStatus),null)}function En(e){e.currentResult&&=(e.results.push(e.currentResult),null)}function Dn(e,t){let n=e.indexOf(`=`);n<0||(t[e.slice(0,n)]=e.slice(n+1))}function k(e){if(e===void 0)return;let t=Number(e);return Number.isFinite(t)?t:void 0}function On(e){if(e===`true`)return!0;if(e===`false`)return!1}function kn(e){if(!Number.isFinite(e.x)||!Number.isFinite(e.y)||!Number.isFinite(e.width)||!Number.isFinite(e.height)||e.width<=0||e.height<=0)throw new t(`COMMAND_FAILED`,`Android helper returned an invalid gesture viewport`);return e}const An=1e4;async function jn(e,t){try{return await ze(e,t)}catch(e){throw Ye(e)}}async function Mn(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 zn(a,o,u);let f=await Nn({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 jn(a,{provider:n,replace:!0,allowFailure:!0,timeoutMs:l});if(p.exitCode!==0)throw w(`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 Nn(e){let{adb:t,adbProvider:n,packageName:r,versionCode:i,sha256:a,signal:o}=e,s=await In(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 Ln(t,n,r,o);return{installedVersionCode:s,installedSha256:e,reason:e===a?`current`:`mismatched`}}catch{return o?.throwIfAborted(),{installedVersionCode:s,reason:`unverifiable`}}}async function Pn(e){let r=x().files,i=De(),a=E.join(Ee(),`android`,e.helperDirName,`dist`),o=E.join(a,e.manifestFileName(i));try{let t=e.parseManifest(JSON.parse(await r.readText(o))),n=E.join(a,t.assetName);return await r.access(n),{apkPath:n,manifest:t}}catch(r){throw new t(`UNSUPPORTED_OPERATION`,e.unavailableMessage,{manifestPath:o,error:n(r).message},r)}}function Fn(e){return async t=>await Mn({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 In(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:${Vn(t)}(?:\\s|$).*versionCode:(\\d+)`).exec(`${r.stdout}\n${r.stderr}`);return i?Number(i[1]):void 0}async function Ln(e,n,r,i){let a=await b(e,[`pm`,`path`,r],{allowFailure:!0,timeoutMs:An,signal:i}),o=Rn(`${a.stdout}\n${a.stderr}`);if(a.exitCode!==0||!o)throw new t(`COMMAND_FAILED`,`Could not resolve installed Android helper APK`);let s=x().files,c=await s.makeTempDirectory(`agent-device-helper-`),l=E.join(c,`base.apk`);try{let e=await Fe(o,l,{provider:n,allowFailure:!0,timeoutMs:An,signal:i});if(e.exitCode!==0)throw w(`Could not read installed Android helper APK`,e,{packageName:r,remotePath:o});return await Bn(l)}finally{await s.remove(c,{recursive:!0,force:!0})}}function Rn(e){return e.split(/\r?\n/).map(e=>e.startsWith(`package:`)?e.slice(8).trim():``).find(e=>e.endsWith(`/base.apk`))}async function zn(e,n,r){let i=await Bn(e);if(i!==n)throw new t(`COMMAND_FAILED`,`${r} APK checksum mismatch`,{apkPath:e,expectedSha256:n,actualSha256:i})}async function Bn(e){let t=x().files;return t.sha256(await t.readBytes(e))}function Vn(e){return e.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`)}const Hn=`android-snapshot-helper-v1`,Un=`uiautomator-xml`,Wn=5e3,Gn=3e4;function Kn(e){if(!e||typeof e!=`object`||Array.isArray(e))throw new t(`INVALID_ARGS`,`Android snapshot helper manifest must be an object.`);let n=e;return{name:Jn(n.name,`name`,`android-snapshot-helper`),version:A(n.version,`version`),releaseTag:Xn(n.releaseTag),assetName:Xn(n.assetName),apkUrl:Zn(n.apkUrl,`apkUrl`),sha256:Yn(n.sha256),checksumName:Xn(n.checksumName),packageName:A(n.packageName,`packageName`),versionCode:qn(n.versionCode,`versionCode`),instrumentationRunner:A(n.instrumentationRunner,`instrumentationRunner`),minSdk:qn(n.minSdk,`minSdk`),targetSdk:n.targetSdk===void 0?void 0:qn(n.targetSdk,`targetSdk`),outputFormat:Jn(n.outputFormat,`outputFormat`,Un),statusProtocol:Jn(n.statusProtocol,`statusProtocol`,Hn)}}function qn(e,t){return yn(e,t,`snapshot helper`)}function Jn(e,t,n){return O(e,t,n,`snapshot helper`)}function Yn(e){let n=A(e,`sha256`).trim().toLowerCase();if(n.length!==64||!Qn(n))throw new t(`INVALID_ARGS`,`Android snapshot helper manifest sha256 must be a 64-character hex string.`);return n}function A(e,n){if(typeof e!=`string`||e.trim().length===0)throw new t(`INVALID_ARGS`,`Android snapshot helper manifest ${n} is required.`);return e}function Xn(e){return typeof e==`string`&&e.trim().length>0?e:void 0}function Zn(e,t){return e===null?null:A(e,t)}function Qn(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 j=new Map;function $n(e){let t=`${e.deviceKey}\0${e.packageName}\0${e.versionCode}\0`;for(let e of j.keys())e.startsWith(t)&&rr(e)}function er(){j.clear()}function tr(e,t,n,r){return e?`${e}\0${t}\0${n}\0${r}`:void 0}function nr(e,t){if(!e)return;let[n,r]=e.split(`\0`),i=`${n}\0${r}\0`;for(let t of j.keys())t!==e&&t.startsWith(i)&&j.delete(t);j.set(e,t)}function rr(e){e&&j.delete(e)}async function ir(e){let{adb:t,artifact:n}=e,r=e.installPolicy??`missing-or-outdated`,i=n.manifest.packageName,a=n.manifest.versionCode,o=n.manifest.sha256;if(r===`never`)return{packageName:i,versionCode:a,installed:!1,reason:`skipped`};let s=tr(e.deviceKey,i,a,o),c=s?j.get(s):void 0;if(s&&r!==`always`&&c!==void 0)return{packageName:i,versionCode:a,installedVersionCode:c,installedSha256:o,installed:!1,reason:`current`};await zn(n.apkPath,o,`Android snapshot helper`);let l=r===`always`?{installedVersionCode:await sr(t,i,e.timeoutMs,e.signal),reason:`forced`}:await Nn({adb:t,adbProvider:or(e.adbProvider,t),packageName:i,versionCode:a,sha256:o,signal:e.signal}),{installedVersionCode:u}=l,d=`installedSha256`in l?l.installedSha256:void 0,f=l.reason;if(f===`current`){if(u===void 0)throw Error(`Expected installed versionCode for current Android snapshot helper`);return nr(s,u),{packageName:i,versionCode:a,installedVersionCode:u,installedSha256:d,installed:!1,reason:f}}let p;try{p=await cr(t,e.adbProvider??t,n.apkPath,{packageName:i,timeoutMs:e.timeoutMs,signal:e.signal})}catch(e){throw rr(s),ar(e,{packageName:i,versionCode:a})}if(p.exitCode!==0)throw rr(s),ar(w(`Failed to install Android snapshot helper`,p,{packageName:i,versionCode:a}));return nr(s,a),{packageName:i,versionCode:a,installedVersionCode:u,installedSha256:d,installed:!0,reason:f}}function ar(e,t){let n=r(e,`COMMAND_FAILED`);return n.details={...t,...n.details,androidSnapshotHelperInstallFailure:!0},n}function or(e,t){return e?typeof e==`function`?{exec:e}:e:{exec:t}}async function sr(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 lr(`${i.stdout}\n${i.stderr}`,t)}async function cr(e,t,n,r){let i=async()=>await jn(n,{allowFailure:!0,provider:t,replace:!0,timeoutMs:r.timeoutMs,signal:r.signal}),a=await i();if(a.exitCode===0||!ur(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 lr(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 ur(e){return`${e.stdout}\n${e.stderr}`.includes(`INSTALL_FAILED_UPDATE_INCOMPATIBLE`)}function dr(e){return e.errorType===`java.util.concurrent.TimeoutException`?`accessibility-timeout`:void 0}function fr(e){return e===137?`accessibility-timeout`:void 0}function pr(e){return e?{androidCaptureFailureReason:e}:{}}function mr(){return new Promise((e,t)=>{let n=It.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 hr(e,n,r,i){return new Promise((a,o)=>{let s=It.connect({host:`127.0.0.1`,port:e}),c=[],l=setTimeout(()=>{u(),s.destroy(),o(new t(`COMMAND_FAILED`,`Android snapshot helper session request timed out`,{command:n,timeoutMs:r,port:e}))},r),u=()=>{clearTimeout(l),i?.removeEventListener(`abort`,d)},d=()=>{u(),s.destroy(),o(i?.reason??new DOMException(`The operation was aborted`,`AbortError`))};if(i?.addEventListener(`abort`,d,{once:!0}),i?.aborted){d();return}s.on(`connect`,()=>s.write(`${n}\n`)),s.on(`data`,e=>c.push(Buffer.from(e))),s.on(`error`,e=>{u(),o(e)}),s.on(`close`,()=>{u(),a(Buffer.concat(c).toString(`utf8`))})})}async function gr(e){let t=`snapshot-${Date.now()}-${Math.random().toString(16).slice(2)}`;return Sr(await hr(e.port,`snapshot ${t}`,_r(e),e.signal),t)}function _r(e){return Math.min(e.commandTimeoutMs,Math.max(e.timeoutMs+3e3,3e3))}function vr(e,n,r){return new Promise((i,a)=>{let o=``,s=setTimeout(()=>{r?.removeEventListener(`abort`,l),a(new t(`COMMAND_FAILED`,`Android snapshot helper session did not become ready`,{output:o,timeoutMs:n,reason:`android_snapshot_helper_session_ready_timeout`}))},n),c=e=>{o+=e.toString(),o.includes(`agentDeviceProtocol=android-snapshot-helper-v1`)&&o.includes(`sessionReady=true`)&&(clearTimeout(s),r?.removeEventListener(`abort`,l),i())},l=()=>{clearTimeout(s),a(r?.reason??new DOMException(`The operation was aborted`,`AbortError`))};if(r?.addEventListener(`abort`,l,{once:!0}),r?.aborted){l();return}e.stdout?.on(`data`,c),e.stderr?.on(`data`,c),e.once(`exit`,(e,n)=>{clearTimeout(s),r?.removeEventListener(`abort`,l),a(new t(`COMMAND_FAILED`,`Android snapshot helper session exited before ready`,{output:o,exitCode:e,signal:n,reason:`android_snapshot_helper_session_exited_before_ready`}))}),e.on(`error`,e=>{clearTimeout(s),r?.removeEventListener(`abort`,l),a(e)})})}function yr(e){let t=e.indexOf(`
|
|
5
5
|
|
|
6
|
-
`);return
|
|
6
|
+
`);return Tr(e.slice(0,t<0?e.length:t))}function br(e,n){if(e.agentDeviceProtocol!==`android-snapshot-helper-v1`)throw new t(`COMMAND_FAILED`,`Android automation helper session returned wrong protocol`,{headers:e});if(e.requestId!==n)throw new t(`COMMAND_FAILED`,`Android automation helper session returned stale output`,{headers:e,requestId:n})}function xr(e,t){let n=yr(e);return n.agentDeviceProtocol===`android-snapshot-helper-v1`&&n.requestId===t&&n.ok===`true`}function Sr(e,n){let r=e.indexOf(`
|
|
7
7
|
|
|
8
|
-
`);if(r<0)throw new t(`COMMAND_FAILED`,`Android snapshot helper session returned malformed output`,{response:e});let i=br(e.slice(0,r)),a=e.slice(r+2);return vr(i,n),yr(i,a),{xml:a,metadata:xr(i)}}function vr(e,n){if(e.agentDeviceProtocol!==`android-snapshot-helper-v1`)throw new t(`COMMAND_FAILED`,`Android snapshot helper session returned wrong protocol`,{headers:e});if(e.outputFormat!==`uiautomator-xml`)throw new t(`COMMAND_FAILED`,`Android snapshot helper session returned wrong output format`,{headers:e});if(e.requestId!==n)throw new t(`COMMAND_FAILED`,`Android snapshot helper session returned stale output`,{headers:e,requestId:n});if(e.ok!==`true`)throw new t(`COMMAND_FAILED`,e.message||e.errorType||`Android snapshot helper session returned an error`,{helper:e,...cr(or(e))})}function yr(e,n){let r=D(e.byteLength);if(r!==void 0&&Buffer.byteLength(n,`utf8`)!==r)throw new t(`COMMAND_FAILED`,`Android snapshot helper session returned truncated XML`,{headers:e,actualByteLength:Buffer.byteLength(n,`utf8`)});if(!n.includes(`<hierarchy`)||!n.includes(`</hierarchy>`))throw new t(`COMMAND_FAILED`,`Android snapshot helper session did not return XML`,{headers:e,xml:n})}function br(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 xr(e){return{helperApiVersion:e.helperApiVersion,outputFormat:Rn,waitForIdleTimeoutMs:D(e.waitForIdleTimeoutMs),waitForIdleQuietMs:D(e.waitForIdleQuietMs),timeoutMs:D(e.timeoutMs),maxDepth:D(e.maxDepth),maxNodes:D(e.maxNodes),rootPresent:O(e.rootPresent),captureMode:e.captureMode===`interactive-windows`||e.captureMode===`active-window`?e.captureMode:void 0,windowCount:D(e.windowCount),nodeCount:D(e.nodeCount),truncated:O(e.truncated),elapsedMs:D(e.elapsedMs)}}function M(e,n,r,i){if(i instanceof t){let a=i.details??{};return new t(i.code,i.message,{...a,action:e,package:r,tool:n,hint:typeof a.hint==`string`?a.hint:wr(n,a)},i)}return new t(`COMMAND_FAILED`,`Failed to ${e} Android ${n} for ${r}`,{action:e,package:r,tool:n,hint:Sr(n)},i)}function Sr(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 Cr(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 wr(e,t){let n=(typeof t.stderr==`string`?t.stderr:``).toLowerCase();return e===`simpleperf`?Tr(n):Dr(n)?`Use a device image that permits perfetto trace capture for shell, keep the app running, then retry perf trace start.`:Sr(e)}function Tr(e){return Er(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.`:Sr(`simpleperf`)}function Er(e){return e.includes(`permission denied`)||e.includes(`not profileable`)||e.includes(`profileable`)}function Dr(e){return e.includes(`permission denied`)||e.includes(`not allowed`)}const Or=`adb-shell-simpleperf`,kr=`adb-shell-perfetto`,Ar=15e3,N=3e4,jr=`/data/local/tmp`;async function Mr(e,n){try{let t=await e([`shell`,`pidof`,n],{allowFailure:!0,timeoutMs:Ar}),r=P(t.stdout);if(t.exitCode===0&&r)return r}catch{}throw new t(`COMMAND_FAILED`,`No active Android app process found for ${n}`,{package:n,hint:`Run open <app> for this session again, wait for the app UI to appear, then retry perf.`})}async function Nr(e,n,r){let i=await e([`shell`,`command -v ${n} || which ${n}`],{allowFailure:!0,timeoutMs:Ar});if(!(i.exitCode===0&&i.stdout.trim()))throw new t(`UNSUPPORTED_OPERATION`,`Android device does not expose ${n}`,{package:r,tool:n,hint:Cr(n)})}function P(e){return e.trim().split(/\s+/).find(e=>/^\d+$/.test(e))}const Pr=2e3,Fr=`android_snapshot_helper_runtime_occupied`,F=new Map;function Ir(e){return`${e.platform}:${e.id}`}async function Lr(e){await Xr({adb:e.adb,packageName:e.packageName}),await zr({deviceKey:e.deviceKey,packageName:e.packageName,adb:e.adb,cause:e.cause})}async function Rr(e){let t=F.get(e.deviceKey);if(!t)return;await Xr({adb:e.adb,packageName:t.packageName,timeoutMs:5e3,...e.signal?{signal:e.signal}:{}}),e.signal?.throwIfAborted();let n=await Hr({adb:e.adb,packageName:t.packageName});if(n===`occupied`&&(await g(250),n=await Hr({adb:e.adb,packageName:t.packageName})),n===`occupied`)throw Vr({deviceKey:e.deviceKey,packageName:t.packageName,cause:t.cause});n!==`unknown`&&F.delete(e.deviceKey)}async function zr(e){let t=e.release??await Hr({adb:e.adb,packageName:e.packageName});if(t===`released`)return F.delete(e.deviceKey),t;let n=e.cause instanceof Error?e.cause.message:String(e.cause);return F.set(e.deviceKey,{packageName:e.packageName,cause:n}),h({level:`warn`,phase:`android_snapshot_helper_retirement_pending`,data:{deviceKey:e.deviceKey,packageName:e.packageName,release:t}}),t}function Br(e){return e instanceof t&&e.details?.reason===Fr}function Vr(e){let n=e.cause instanceof Error?e.cause.message:String(e.cause);return new t(`COMMAND_FAILED`,`Android automation helper is still holding device automation ownership`,{reason:Fr,deviceKey:e.deviceKey,packageName:e.packageName,cause:n,hint:`Retry after the helper process exits, or restart the device if Android keeps reporting the helper as running.`})}async function Hr(e){try{let t=await e.adb([`shell`,`pidof`,e.packageName,`||`,`echo`,`AGENT_DEVICE_NO_HELPER`],{allowFailure:!0,timeoutMs:Pr}),n=t.stdout.trim();return P(n)?`occupied`:n===`AGENT_DEVICE_NO_HELPER`&&t.stderr.trim().length===0?`released`:`unknown`}catch{return`unknown`}}async function Ur(e){let t=AbortSignal.timeout(e.timeoutMs);return await Promise.all([...e.forceStopRuntime?[Xr({adb:e.adb,packageName:e.packageName,timeoutMs:e.timeoutMs,signal:t})]:[],Zr({...e,signal:t})]),{timedOut:t.aborted}}function Wr(e){let t=Gr(e);return{ended:t?Promise.resolve():new Promise(t=>{e.once(`close`,()=>t()),e.once(`exit`,()=>t())}),hasEnded:()=>Gr(e),completedCleanly:()=>!t&&e.exitCode===0&&e.signalCode==null}}function Gr(e){return e.exitCode!=null||e.signalCode!=null}async function Kr(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 qr(e){if(e.processExit.hasEnded())return!0;try{e.process.kill(`SIGTERM`)}catch{}return await Kr(e.processExit.ended,e.timeoutMs)}function Jr(e){F.delete(e)}function Yr(){F.clear()}async function Xr(e){await e.adb([`shell`,`am`,`force-stop`,e.packageName],{allowFailure:!0,timeoutMs:e.timeoutMs??2e3,...e.signal?{signal:e.signal}:{}}).catch(()=>{})}async function Zr(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 Qr(e){let n=ei(e),r=e.deviceKey??`android:default`;await Rr({deviceKey:r,adb:e.adb,signal:e.signal});let i;try{i=await e.adb(ti(n),{allowFailure:!0,timeoutMs:n.commandTimeoutMs,signal:e.signal})}catch(t){throw e.signal?.aborted?(await Lr({deviceKey:r,packageName:n.packageName,adb:e.adb,cause:t}),e.signal.throwIfAborted(),t):t}e.signal?.aborted&&(await Lr({deviceKey:r,packageName:n.packageName,adb:e.adb,cause:e.signal.reason}),e.signal.throwIfAborted());let{output:a,cleanupDone:o}=await ni(e,n,i);if(n.outputPath&&!o&&await li(e.adb,n.outputPath),i.exitCode!==0)throw new t(`COMMAND_FAILED`,`Android snapshot helper failed`,Se(i,{helper:a.metadata}));return a}function $r(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:zn,commandTimeoutMs:Bn,...e.signal?{signal:e.signal}:{}}}function ei(e){let t=I(e.timeoutMs,8e3),n=I(e.packageName,`com.callstack.agentdevice.snapshothelper`);return{waitForIdleTimeoutMs:I(e.waitForIdleTimeoutMs,500),waitForIdleQuietMs:I(e.waitForIdleQuietMs,100),timeoutMs:t,commandTimeoutMs:I(e.commandTimeoutMs,t+5e3),maxDepth:I(e.maxDepth,128),maxNodes:I(e.maxNodes,5e3),packageName:n,runner:I(e.instrumentationRunner,`${n}/.SnapshotInstrumentation`),...e.outputPath?{outputPath:e.outputPath}:{},...e.emitChunks===void 0?{}:{emitChunks:e.emitChunks}}}function I(e,t){return e===void 0?t:e}function ti(e){return[`shell`,`am`,`instrument`,`-w`,`-e`,`waitForIdleTimeoutMs`,String(e.waitForIdleTimeoutMs),`-e`,`waitForIdleQuietMs`,String(e.waitForIdleQuietMs),`-e`,`timeoutMs`,String(e.timeoutMs),`-e`,`maxDepth`,String(e.maxDepth),`-e`,`maxNodes`,String(e.maxNodes),...e.outputPath?[`-e`,`outputPath`,e.outputPath]:[],...e.emitChunks===void 0?[]:[`-e`,`emitChunks`,String(e.emitChunks)],e.runner]}async function ni(e,t,n){try{return{output:ui(`${n.stdout}\n${n.stderr}`),cleanupDone:!1}}catch(r){return await ri(e,t,n,r)}}async function ri(e,n,r,i){if(i instanceof t&&r.exitCode!==0&&i.details?.helper)throw i;let a=await ii(e,n,r);if(a)return{output:a,cleanupDone:!0};throw new t(`COMMAND_FAILED`,r.exitCode===0?`Android snapshot helper output could not be parsed`:`Android snapshot helper failed before returning parseable output`,{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode,...cr(sr(r.exitCode))},i)}async function ii(e,t,n){if(!(n.exitCode!==0||!t.outputPath))return await oi(e.adb,t.outputPath,ci(`${n.stdout}\n${n.stderr}`)??ai(t))}function ai(e){return{outputFormat:Rn,waitForIdleTimeoutMs:e.waitForIdleTimeoutMs,waitForIdleQuietMs:e.waitForIdleQuietMs,timeoutMs:e.timeoutMs,maxDepth:e.maxDepth,maxNodes:e.maxNodes,transport:`instrumentation`}}async function oi(e,t,n){let r;try{r=await e(si(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 si(e){return[`shell`,`sh`,`-c`,`cat "$1"; status=$?; rm -f "$1"; exit "$status"`,`agent-device-snapshot-helper-output`,e]}function ci(e){try{return vi(fi(yn(e).results))}catch{return null}}async function li(e,t){try{await e([`shell`,`rm`,`-f`,t],{allowFailure:!0,timeoutMs:5e3})}catch{}}function ui(e){let t=yn(e),n=fi(t.results);return{xml:mi(di(t.status),n),metadata:{...vi(n),transport:`instrumentation`}}}function di(e){let t=[];for(let n of e){if(n.agentDeviceProtocol!==`android-snapshot-helper-v1`||n.outputFormat!==`uiautomator-xml`)continue;let{payloadBase64:e}=n;e!==void 0&&t.push({index:L(n.chunkIndex),count:L(n.chunkCount),payloadBase64:e})}return t}function fi(e){let n=e.find(e=>e.agentDeviceProtocol===Ln);if(!n)throw new t(`COMMAND_FAILED`,`Android snapshot helper did not return a final result`);if(n.ok!==`true`)throw new t(`COMMAND_FAILED`,pi(n),{errorType:n.errorType,helper:n,...cr(or(n))});return n}function pi(e){return e.message&&e.message!==`null`?e.message:e.errorType||`Android snapshot helper returned an error`}function mi(e,n){if(e.length===0)throw new t(`COMMAND_FAILED`,`Android snapshot helper did not return XML chunks`,{helper:n});let r=hi(e),i=Buffer.concat(_i(gi(e,r),r)).toString(`utf8`);if(!i.includes(`<hierarchy`)||!i.includes(`</hierarchy>`))throw new t(`COMMAND_FAILED`,`Android snapshot helper output did not contain XML`,{xml:i});return i}function hi(e){let n=e[0]?.count??e.length;if(n<1||e.length!==n||e.some(e=>e.count!==n))throw new t(`COMMAND_FAILED`,`Android snapshot helper returned incomplete XML chunks`,{expectedChunks:n,actualChunks:e.length});return n}function gi(e,n){let r=new Map;for(let i of e){if(i.index===void 0||i.index<0||i.index>=n)throw new t(`COMMAND_FAILED`,`Android snapshot helper returned invalid chunk index`,{chunkIndex:i.index,expectedChunks:n});if(r.has(i.index))throw new t(`COMMAND_FAILED`,`Android snapshot helper returned duplicate XML chunks`,{chunkIndex:i.index});r.set(i.index,i.payloadBase64)}return r}function _i(e,n){let r=[];for(let i=0;i<n;i+=1){let a=e.get(i);if(a===void 0)throw new t(`COMMAND_FAILED`,`Android snapshot helper returned incomplete XML chunks`,{missingChunkIndex:i,expectedChunks:n});r.push(Buffer.from(a,`base64`))}return r}function vi(e){return{helperApiVersion:e.helperApiVersion,outputFormat:Rn,waitForIdleTimeoutMs:L(e.waitForIdleTimeoutMs),waitForIdleQuietMs:L(e.waitForIdleQuietMs),timeoutMs:L(e.timeoutMs),maxDepth:L(e.maxDepth),maxNodes:L(e.maxNodes),rootPresent:bi(e.rootPresent),captureMode:yi(e.captureMode),windowCount:L(e.windowCount),nodeCount:L(e.nodeCount),truncated:bi(e.truncated),elapsedMs:L(e.elapsedMs)}}function yi(e){return e===`interactive-windows`||e===`active-window`?e:void 0}const L=D,bi=O,xi=5e3,R=new Map,z=new Map;async function Si(e){return await Ci(e)!==void 0}async function Ci(e){let t=e.deviceKey??`android:default`;if(await Rr({deviceKey:t,adb:e.adb,signal:e.signal}),!Fi()||!e.adbProvider?.spawn)return;let n=ei(e),r=Ni(n),i=await Ti({deviceKey:t,identity:Mi(t,r,e),options:e,resolved:r,startBudgetMs:Pi(n.commandTimeoutMs)});return i?{session:i,resolved:r,deviceKey:t}:void 0}function wi(e){return R.get(e)}async function Ti(e){if(!Oi(e.identity))return await Ei(e.deviceKey,e.identity),R.get(e.deviceKey)??await Di(e)}async function Ei(e,t){let n=R.get(e);!n||Ai(n,t)||await B(e,{force:Gr(n.process)})}async function Di(e){let n=Date.now();try{return await ji(e)}catch(r){e.options.signal?.throwIfAborted(),z.set(e.identity,Date.now()+ki(Date.now()-n)),h({level:`warn`,phase:`android_snapshot_helper_session_start_failed`,data:{deviceKey:e.deviceKey,reason:r instanceof t?r.details?.reason:void 0,detail:r instanceof Error?r.message:String(r)}});return}}function Oi(e){let t=z.get(e);return t===void 0?!1:t>Date.now()||(z.delete(e),!1)}function ki(e){return Math.min(Math.max(e,1e4),6e4)}function Ai(e,t){return e.identity===t&&!Gr(e.process)}async function ji(e){let n=await lr();await e.options.adb([`forward`,`tcp:${n}`,`tcp:${n}`],{allowFailure:!1,timeoutMs:xi,signal:e.options.signal});let r=ti({...e.resolved,outputPath:void 0,emitChunks:!1}),i=r.at(-1);if(!i)throw new t(`INVALID_ARGS`,`Android snapshot helper runner was not resolved`);let a=[...r.slice(0,-1),`-e`,`sessionPort`,String(n),i],o=e.options.adbProvider.spawn(a,{allowFailure:!0,captureOutput:!1}),s={identity:e.identity,deviceKey:e.deviceKey,helper:{packageName:e.resolved.packageName,runner:e.resolved.runner,helperVersion:e.options.helperVersion,helperVersionCode:e.options.helperVersionCode,sha256:e.options.helperSha256},port:n,adb:e.options.adb,process:o,startedAtMs:Date.now(),capturedCount:0};try{return await pr(o,e.startBudgetMs,e.options.signal),R.set(e.deviceKey,s),z.delete(e.identity),Jr(e.deviceKey),h({phase:`android_snapshot_helper_session_ready`,data:{deviceKey:e.deviceKey,port:n,packageName:e.resolved.packageName,runner:e.resolved.runner}}),s}catch(t){let n=Wr(o);try{o.kill(`SIGTERM`)}catch{}throw await Promise.all([Kr(n.ended,250),Ur({adb:s.adb,process:s.process,port:s.port,packageName:s.helper.packageName,timeoutMs:Pr,forceStopRuntime:!0})]),await zr({deviceKey:e.deviceKey,packageName:s.helper.packageName,adb:s.adb,cause:t}),t}}function Mi(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 Ni(e){let t=Math.min(e.timeoutMs,2e3);return{...e,timeoutMs:t,commandTimeoutMs:Math.min(e.commandTimeoutMs,t+3e3)}}function Pi(e){return Math.min(e,Math.max(Math.floor(e/2),5e3))}function Fi(){let e=y().environment.AGENT_DEVICE_ANDROID_SNAPSHOT_HELPER_SESSION;return e===void 0||!/^(0|false|no|off)$/i.test(e)}async function B(e,t={}){let n=R.get(e);if(!n)return!1;R.delete(e);let r=Wr(n.process),i=t.force===!0||t.signal?.aborted===!0,a=await Ii(n,r,i,t.signal),o=r.hasEnded(),s=a.acknowledged&&a.exited,c=s&&await It({adb:n.adb,deviceKey:e,signal:t.signal}),l=i?t.signal?.aborted===!0?250:Pr:xi,u=i?250:2e3,[d,f]=await Promise.all([qr({process:n.process,processExit:r,timeoutMs:u}),Ur({adb:n.adb,process:n.process,port:n.port,packageName:n.helper.packageName,timeoutMs:l,forceStopRuntime:t.resetRuntime===!0||!c})]),p=await zr({deviceKey:e,packageName:n.helper.packageName,adb:n.adb,cause:t.cause,...c?{release:`released`}:{}});return h({phase:`android_snapshot_helper_session_stop`,data:{deviceKey:e,port:n.port,capturedCount:n.capturedCount,lifetimeMs:Date.now()-n.startedAtMs,quitAcknowledged:a.acknowledged,quitExitObserved:s,releaseProvenByQuit:c,release:p,forceKilled:!o&&d,forced:i||t.signal?.aborted===!0,externalCleanupTimedOut:f.timedOut}}),!0}async function Ii(e,t,n,r){if(n)return{acknowledged:!1,exited:!1};let i=`quit-${Date.now()}`;try{let n=gr(await ur(e.port,`quit ${i}`,1e3,r),i);return{acknowledged:n,exited:n&&await Kr(t.ended,11e3,r)&&t.completedCleanly()}}catch{return{acknowledged:!1,exited:!1}}}async function Li(e){await B(Ir(e))}async function Ri(){try{await Promise.allSettled([...R.keys()].map(async e=>{await B(e)}))}finally{R.clear(),z.clear(),Yr(),Lt()}}async function zi(e){let t=await Ci(e);if(t)return await Bi({session:t.session,deviceKey:t.deviceKey,options:e,resolved:t.resolved})}async function Bi(e){let{session:t,deviceKey:n,options:r,resolved:i}=e;try{let e=t.capturedCount>0,n=await dr({port:t.port,timeoutMs:i.timeoutMs,commandTimeoutMs:i.commandTimeoutMs,signal:r.signal});return t.capturedCount+=1,{xml:n.xml,metadata:{...n.metadata,transport:`persistent-session`,sessionReused:e}}}catch(e){await B(n,{force:!0,signal:r.signal,cause:e}),r.signal?.throwIfAborted(),h({level:`warn`,phase:`android_snapshot_helper_session_fallback`,data:{deviceKey:n,reason:e instanceof Error?e.message:String(e),uiAutomationConnectionTimeout:nt(e)===`accessibility-timeout`}});return}}async function Vi(e){let n=wi(e.deviceKey);if(!n)return;if(!Hi(n.helper,e.helper)){h({level:`warn`,phase:`android_snapshot_helper_session_touch_identity_mismatch`,data:{deviceKey:e.deviceKey,sessionHelper:n.helper,requestedHelper:e.helper}}),await B(e.deviceKey);return}let r=`${e.action}-${Date.now()}-${Math.random().toString(16).slice(2)}`,i=e.payloadBase64?`${e.action} ${r} ${e.payloadBase64}`:`${e.action} ${r}`,a;try{a=mr(await ur(n.port,i,e.timeoutMs)),hr(a,r)}catch(t){throw await B(e.deviceKey),t}if(a.ok!==`true`)throw new t(`COMMAND_FAILED`,a.message||a.errorType||`Android automation helper ${e.action} failed`,{errorType:a.errorType,helper:a});return a}function Hi(e,t){return e.packageName===t.packageName&&e.runner===t.runner&&Ui(e.helperVersion,t.helperVersion)&&Ui(e.helperVersionCode,t.helperVersionCode)&&Ui(e.sha256,t.sha256)}function Ui(e,t){return e===void 0||t===void 0||e===t}const Wi=`android-touch-plan-v1`,Gi=45e3,Ki=`ANDROID_TOUCH_HELPER_NO_FINAL_RESULT`,qi=`ANDROID_TOUCH_HELPER_REPORTED_FAILURE`;async function Ji(e,t){let n=await Zi(e),r=$i(t),i=Math.max(45e3,r.durationMs+15e3),a=Buffer.from(JSON.stringify({protocol:Wi,...r})).toString(`base64`),o=await m(`android_touch_helper_gesture`,async()=>{let e=await Vi({deviceKey:n.deviceKey,action:`gesture`,helper:Xi(n.artifact),payloadBase64:a,timeoutMs:i});return e?{...ra(e),helperTransport:`persistent-session`}:{...await ta({adb:n.adb,runner:n.artifact.manifest.instrumentationRunner,extraArgs:[`-e`,`mode`,`gesture`,`-e`,`payloadBase64`,a],timeoutMs:i,readResult:ra}),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 Yi(e,t={}){let n=await Zi(e);t.helperSessionScope===`daemon-session`&&await Si($r({adb:n.adb,adbProvider:n.adbProvider,artifact:n.artifact,deviceKey:n.deviceKey}));try{let e=await Vi({deviceKey:n.deviceKey,action:`viewport`,helper:Xi(n.artifact),timeoutMs:Gi});if(e)return ia(e)}catch(e){await B(n.deviceKey),h({level:`warn`,phase:`android_touch_helper_viewport_session_fallback`,data:{reason:e instanceof Error?e.message:String(e)}})}return await ta({adb:n.adb,runner:n.artifact.manifest.instrumentationRunner,extraArgs:[`-e`,`mode`,`viewport`],timeoutMs:Gi,readResult:ia})}function Xi(e){return{packageName:e.manifest.packageName,runner:e.manifest.instrumentationRunner,helperVersion:e.manifest.version,helperVersionCode:e.manifest.versionCode,sha256:e.manifest.sha256}}async function Zi(e){let t=b(e),n=t.snapshotHelperArtifact??await Qi(),r=Ir(e);await Rr({deviceKey:r,adb:t.exec});let i=await m(`android_touch_helper_install`,async()=>await $n({adb:t.exec,adbProvider:t,artifact:n,deviceKey:r,timeoutMs:3e4}),{packageName:n.manifest.packageName,versionCode:n.manifest.versionCode});return h({phase:`android_touch_helper_install_decision`,data:i}),i.installed&&await B(r),{adb:t.exec,adbProvider:t,artifact:n,install:i,deviceKey:r}}async function Qi(){return await kn({helperDirName:`snapshot-helper`,manifestFileName:e=>`agent-device-android-snapshot-helper-${e}.manifest.json`,parseManifest:e=>{let t=Vn(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 $i(e){return{kind:e.topology===`single`?`swipe`:`transform`,durationMs:e.durationMs,pointers:e.pointers.map(ea)}}function ea(e){return{pointerId:e.pointerId,samples:e.samples.map(({offsetMs:e,point:t})=>({offsetMs:e,x:t.x,y:t.y}))}}async function ta(e){let n=await e.adb([`shell`,`am`,`instrument`,`-w`,...e.extraArgs,e.runner],{allowFailure:!0,timeoutMs:e.timeoutMs}),r;try{r=na(`${n.stdout}\n${n.stderr}`)}catch(e){if(e instanceof t){if(e.code===qi)throw new t(`COMMAND_FAILED`,e.message,e.details,e);if(e.code!==Ki)throw e}throw new t(`COMMAND_FAILED`,n.exitCode===0?`Android automation helper output could not be parsed`:`Android automation helper failed before returning parseable output`,Se(n),e)}if(n.exitCode!==0)throw new t(`COMMAND_FAILED`,`Android automation helper failed`,Se(n,{helper:r}));return e.readResult(r)}function na(e){let n=yn(e).results.find(e=>e.agentDeviceProtocol===Ln);if(!n)throw new t(Ki,`Android automation helper did not return a final result`);if(n.ok!==`true`)throw new t(qi,n.message&&n.message!==`null`?n.message:n.errorType||`Android automation helper returned an error`,{errorType:n.errorType,helper:n});return n}function ra(e){return{helperKind:e.kind,helperApiVersion:e.helperApiVersion,injectedEvents:D(e.injectedEvents),elapsedMs:D(e.elapsedMs)}}function ia(e){let n=D(e.x),r=D(e.y),i=D(e.width),a=D(e.height);if(n===void 0||r===void 0||i===void 0||a===void 0)throw new t(`COMMAND_FAILED`,`Android helper returned an invalid gesture viewport`);let o=aa(e);return{viewport:k({x:n,y:r,width:i,height:a}),...o?{keyboard:o}:{}}}function aa(e){let t=D(e.keyboardX),n=D(e.keyboardY),r=D(e.keyboardWidth),i=D(e.keyboardHeight);if(t!==void 0&&n!==void 0&&r!==void 0&&i!==void 0)return{x:t,y:n,width:r,height:i}}function oa(e){if(e.topology===`two`||e.intent===`longPress`)return e;let{releaseBehavior:t,...n}=e,[{pointerId:r,samples:i}]=n.pointers,a=[...new Set([...Ze(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:$e(n.point,r.point,t===`controlled`?sa(s,a):s)}}),c=[s[0],s[1],s[2],...s.slice(3)];return{...n,pointers:[{pointerId:r,samples:c}]}}function sa(e,t){let n=Math.min(16/t,.5);return e<n?e**2/n:1-(1-e)**2/(1-n)}async function ca(e,t){let n=oa(t),r=Ae(e);if(r){let e=n.intent===`longPress`?{...n,viewport:k(await r.gestureViewport())}:n;return{backend:`provider-native-touch`,...await r.touch(e)??{}}}return await Ji(e,n)}async function la(e,t={}){return(await ua(e,t)).viewport}async function ua(e,t={}){let n=Ae(e);return n?{viewport:k(await n.gestureViewport())}:await Yi(e,t)}async function da(e,t,n){await C(e,[`shell`,`input`,`tap`,String(t),String(n)])}async function fa(e,t,n){let r=we(t);await C(e,[`shell`,`input`,...n&&n>0?[`keyevent`,`--longpress`]:[`keyevent`],r])}async function pa(e){await C(e,[`shell`,`input`,`keyevent`,`4`])}async function ma(e){await C(e,[`shell`,`input`,`keyevent`,`3`])}async function ha(e){await C(e,[`shell`,`input`,`keyevent`,`ENTER`])}async function ga(e,t){let n=Ea(t);await C(e,[`shell`,`settings`,`put`,`system`,`accelerometer_rotation`,`0`]),await C(e,[`shell`,`settings`,`put`,`system`,`user_rotation`,n]),await va(e,t,n)}const _a=15e3;async function va(e,n,r){let i=Date.now()+_a,a=await ya(e,n,i);for(;a!==void 0&&a!==r&&Date.now()<i;)await g(Math.min(500,ba(i))),a=await ya(e,n,i);if(a!==void 0&&a!==r)throw new t(`COMMAND_FAILED`,`orientation ${n} did not take effect: the display still reports rotation ${a} after ${_a}ms`,{requestedRotation:Number(r),observedRotation:Number(a),hint:"The foreground app may pin its orientation, or the device may ignore user_rotation. Check `adb shell dumpsys display | grep mCurrentOrientation` and the app manifest."})}async function ya(e,n,r){try{let t=await C(e,[`shell`,`dumpsys`,`display`],{timeoutMs:ba(r)});return/mCurrentOrientation=(\d)/.exec(t.stdout)?.[1]}catch(e){throw new t(`COMMAND_FAILED`,`orientation ${n} could not confirm the display rotation: ${e instanceof Error?e.message:String(e)}`,{hint:"The device did not answer `dumpsys display` within the orientation budget."})}}function ba(e){return Math.max(1,e-Date.now())}async function xa(e){await C(e,[`shell`,`input`,`keyevent`,`187`])}async function Sa(e,t,n,r=800){let i={x:t,y:n};return await ca(e,{topology:`single`,intent:`longPress`,durationMs:r,pointers:[{pointerId:0,samples:[{offsetMs:0,point:i},{offsetMs:r,point:i}]}]})}async function Ca(e,t,n){await da(e,t,n)}async function wa(e,t,n){let{viewport:r,keyboard:i}=await ua(e,{helperSessionScope:n?.helperSessionScope}),a=Ta(t,r,i),o=ue({direction:t,amount:n?.amount,pixels:n?.pixels,referenceWidth:a.viewport.width,referenceHeight:a.viewport.height}),s={...o,referenceWidth:a.viewport.x+a.viewport.width,referenceHeight:a.viewport.y+a.viewport.height,x1:a.viewport.x+o.x1,y1:a.viewport.y+o.y1,x2:a.viewport.x+o.x2,y2:a.viewport.y+o.y2},c=Math.max(n?.durationMs??300,16),l=await ca(e,{...Qe({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 Ta(e,t,n){if(n===void 0)return{viewport:t,evidence:{}};let r=de(t,n);if(r.kind===`occluded`)throw le(e,{keyboardMinY:r.keyboardMinY,visibleHeight:r.visibleHeight,viewportHeight:t.height});return r.kind===`avoided`?{viewport:r.viewport,evidence:{keyboardAvoided:!0,keyboardMinY:r.keyboardMinY}}:{viewport:t,evidence:{}}}function Ea(e){let n=ve[e];if(n===void 0)throw new t(`INVALID_ARGS`,`Unsupported Android rotation: ${e}`);return String(n)}async function Da(e){let n=(await C(e,[`shell`,`wm`,`size`])).stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(!n)throw new t(`COMMAND_FAILED`,`Unable to read screen size`);return{width:Number(n[1]),height:Number(n[2])}}async function Oa(e,t,n){return t===`wait`?await ka(n.captureNodes,n.timeoutMs??1e4):t===`get`?Fa((await Pa(n.captureNodes))?.alert??null):await Aa(e,t,n.captureNodes)}async function ka(e,n){let r=Date.now(),i=await Na(e,n);if(!i)throw new t(`COMMAND_FAILED`,`alert wait timed out`);return{kind:`alertWait`,platform:`android`,action:`wait`,alert:i.alert,waitedMs:Date.now()-r,...fe(`Alert visible`)}}async function Aa(e,n,r){let i=await Na(r,pe);if(!i)throw new t(`COMMAND_FAILED`,`alert not found`,{hint:`If a sheet is visible in snapshot but alert reports no alert, it is likely app-owned UI. Use snapshot -i and press the visible label/ref.`});let a=Zt(i.buttons,n);if(a)return await da(e,a.x,a.y),await ja(i.alert,n,r),Ia(n,i.alert,a.label,{x:a.x,y:a.y});if(n===`dismiss`)return await pa(e),await ja(i.alert,n,r),Ia(n,i.alert,`Back`);throw new t(`COMMAND_FAILED`,`alert accept found an alert but no accept button`,{alert:i.alert,hint:`Inspect alert get --json for visible buttons, then use press by visible label/ref if needed.`})}async function ja(e,n,r){let i=Date.now();for(;;){let a=await Pa(r);if(!a||!Ma(a.alert,e))return;if(Date.now()-i>=2e3)throw new t(`COMMAND_FAILED`,`alert ${n} did not dismiss the visible alert`,{alert:e,hint:`The alert button was pressed but the dialog is still visible. Inspect alert get --json, then press the visible button by label/ref or retry.`});await g(300)}}function Ma(e,t){return e.title===t.title&&e.buttons.join(`\0`)===t.buttons.join(`\0`)}async function Na(e,t){let n=Date.now();for(;Date.now()-n<t;){let t=await Pa(e);if(t)return t;await g(300)}return null}async function Pa(e){return Yt(await m(`snapshot_capture`,e,{backend:`android`,purpose:`alert`}))}function Fa(e){return{kind:`alertStatus`,platform:`android`,action:`get`,alert:e,...fe(e?`Alert visible`:`No alert visible`)}}function Ia(e,t,n,r){return{kind:`alertHandled`,platform:`android`,action:e,handled:!0,alert:t,button:n,...r?{coordinates:r}:{},...fe(`Alert ${e}ed`)}}const La=`android.intent.category.LAUNCHER`,Ra=`android.intent.category.DEFAULT`;async function za(e,t){await e([`shell`,`am`,`force-stop`,t])}async function Ba(e,t,n=[La]){for(let r of n){let n=await e([`shell`,`cmd`,`package`,`resolve-activity`,`--brief`,`-a`,`android.intent.action.MAIN`,`-c`,r,t],{allowFailure:!0});if(n.exitCode!==0)continue;let i=ct(n.stdout);if(i)return i}return null}async function Va(e,n,r={}){let i=r.category??La;if(r.activity){await e([`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,Ra,`-c`,i,`-n`,Ha(n,r.activity)]);return}let a=await e([`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,Ra,`-c`,i,`-p`,n],{allowFailure:!0});if(a.exitCode===0&&!lt(a.stdout,a.stderr))return;let o=await Ba(e,n,[i]);if(!o)throw new t(`COMMAND_FAILED`,`Failed to resolve Android launch component for ${n}`,{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});await e([`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,Ra,`-c`,i,`-n`,o])}function Ha(e,t){return t.includes(`/`)?t:`${e}/${t.startsWith(`.`)?t:`.${t}`}`}let Ua=null;function Wa(e){return`${e.PATH??``}::${e.AGENT_DEVICE_BUNDLETOOL_JAR??``}`}async function Ga(e){let n=Wa(e);if(Ua?.key===n)return Ua.invocation;if(await xe(`bundletool`)){let e={cmd:`bundletool`,prefixArgs:[]};return Ua={key:n,invocation:e},e}let r=await Ce(e.AGENT_DEVICE_BUNDLETOOL_JAR,`AGENT_DEVICE_BUNDLETOOL_JAR`);if(!r)throw new t(`TOOL_MISSING`,`bundletool not found in PATH. Install bundletool or set AGENT_DEVICE_BUNDLETOOL_JAR to a bundletool-all.jar path.`);let i={cmd:`java`,prefixArgs:[`-jar`,r]};return Ua={key:n,invocation:i},i}async function Ka(e,t,n){let r=await Ga(n);await be(r.cmd,[...r.prefixArgs,...e],{signal:t})}function qa(e){return w.extname(e).toLowerCase()===`.aab`}async function Ja(e,t,n={}){let r=b(e),i=`universal`;if(r.installBundle){await r.installBundle(t,{mode:i,signal:n.signal});return}let a=y().files,o=await a.makeTempDirectory(`agent-device-aab-`),s=w.join(o,`bundle.apks`);try{await Ka([`build-apks`,`--bundle`,t,`--output`,s,`--mode`,i],n.signal,n.environment??y().environment),await Ka([`install-apks`,`--apks`,s,`--device-id`,e.id],n.signal,n.environment??y().environment)}finally{await a.remove(o,{recursive:!0,force:!0})}}async function Ya(e,t,n={}){if(qa(t)){await Ja(e,t,n);return}await ze(t,{device:e,replace:!0,signal:n.signal})}async function Xa(e,t,n={}){await pt(e,async()=>{e.booted||await it(e.id,void 0,n.signal),await Ya(e,t,n)})}const Za=[`mInputShown`,`mIsInputViewShown`,`isInputViewShown`,`mDecorViewVisible`,`mWindowVisible`,`mInShowWindow`],Qa=new Map([[2,`number`],[3,`phone`],[4,`datetime`]]),$a=new Set([32,208]),eo=new Set([128,224,144]);async function V(e){return await H(v(e))}async function H(e){let t=await e([`shell`,`dumpsys`,`input_method`],{allowFailure:!0});if(t.exitCode!==0)throw S(`Failed to query Android keyboard state`,t);return ro(t.stdout)}async function to(e){return await no(v(e))}async function no(e){let n=await H(e),r=n,i=0;for(;r.visible&&i<2;)await e([`shell`,`input`,`keyevent`,`111`]),i+=1,await g(120),r=await H(e);if(n.visible&&r.visible)throw new t(`UNSUPPORTED_OPERATION`,`Android keyboard dismiss is unavailable for the current IME without back navigation.`,{attempts:i,inputType:r.inputType,type:r.type,inputMethodPackage:r.inputMethodPackage,focusedPackage:r.focusedPackage,focusedResourceId:r.focusedResourceId,inputOwner:r.inputOwner});return{attempts:i,wasVisible:n.visible,dismissed:n.visible&&!r.visible,visible:r.visible,inputType:r.inputType,type:r.type,inputMethodPackage:r.inputMethodPackage,focusedPackage:r.focusedPackage,focusedResourceId:r.focusedResourceId,inputOwner:r.inputOwner}}function ro(e){let t=co(e)??io(e),n=ao(e),r=oo(e,/\bpackageName=([A-Za-z0-9_.]+)\b/g),i=oo(e,/\b(?:resourceId|resource-id)=([^\s,}]+)/g),a=f(e),o=ee(r,i,a);return so(r,i,a),{visible:t??!1,inputType:n,type:n?po(n):void 0,inputMethodPackage:a,focusedPackage:r,focusedResourceId:i,inputOwner:o}}function io(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 ao(e){let t=oo(e,/\binputType=0x([0-9a-fA-F]+)\b/gi);return t?`0x${t.toLowerCase()}`:void 0}function oo(e,t){let n;for(let r of e.matchAll(t))n=r[1];return n}function so(e,t,n){n||!u(e)&&!c(t)||h({level:`warn`,phase:`android_input_ownership_fallback`,data:{focusedPackage:e,focusedResourceId:t}})}function co(e){return uo(lo(e,Za))}function lo(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 uo(e){if(e.size===0)return null;let t=fo(e,[`mWindowVisible`,`mDecorViewVisible`,`mInShowWindow`]);if(t!==void 0)return t;let n=e.get(`mInputShown`);return n===void 0?fo(e,[`mIsInputViewShown`,`isInputViewShown`])??null:n}function fo(e,t){for(let n of t){let t=e.get(n);if(t!==void 0)return t}}function po(e){let t=Number.parseInt(e.replace(/^0x/i,``),16);if(Number.isNaN(t))return`unknown`;let n=t&15,r=Qa.get(n);if(r)return r;if(n!==1)return`unknown`;let i=t&4080;return $a.has(i)?`email`:eo.has(i)?`password`:`text`}async function mo(e){return await ho(v(e))}async function ho(e){return yo(await vo(e,[`shell`,`cmd`,`clipboard`,`get`,`text`],`read`))}async function go(e,t){await _o(v(e),t)}async function _o(e,t){await vo(e,[`shell`,`cmd`,`clipboard`,`set`,`text`,Te(t)],`write`)}async function vo(e,n,r){let i=await e(n,{allowFailure:!0});if(i.exitCode===0)return i.stdout;throw Xe(i.stdout,i.stderr)?new t(`UNSUPPORTED_OPERATION`,`Android shell clipboard ${r} is not supported on this device.`):S(`Failed to ${r} Android clipboard text`,i)}function yo(e){let t=e.replaceAll(`\r
|
|
8
|
+
`);if(r<0)throw new t(`COMMAND_FAILED`,`Android snapshot helper session returned malformed output`,{response:e});let i=Tr(e.slice(0,r)),a=e.slice(r+2);return Cr(i,n),wr(i,a),{xml:a,metadata:Er(i)}}function Cr(e,n){if(e.agentDeviceProtocol!==`android-snapshot-helper-v1`)throw new t(`COMMAND_FAILED`,`Android snapshot helper session returned wrong protocol`,{headers:e});if(e.outputFormat!==`uiautomator-xml`)throw new t(`COMMAND_FAILED`,`Android snapshot helper session returned wrong output format`,{headers:e});if(e.requestId!==n)throw new t(`COMMAND_FAILED`,`Android snapshot helper session returned stale output`,{headers:e,requestId:n});if(e.ok!==`true`)throw new t(`COMMAND_FAILED`,e.message||e.errorType||`Android snapshot helper session returned an error`,{helper:e,...pr(dr(e))})}function wr(e,n){let r=k(e.byteLength);if(r!==void 0&&Buffer.byteLength(n,`utf8`)!==r)throw new t(`COMMAND_FAILED`,`Android snapshot helper session returned truncated XML`,{headers:e,actualByteLength:Buffer.byteLength(n,`utf8`)});if(!n.includes(`<hierarchy`)||!n.includes(`</hierarchy>`))throw new t(`COMMAND_FAILED`,`Android snapshot helper session did not return XML`,{headers:e,xml:n})}function Tr(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 Er(e){return{helperApiVersion:e.helperApiVersion,outputFormat:Un,waitForIdleTimeoutMs:k(e.waitForIdleTimeoutMs),waitForIdleQuietMs:k(e.waitForIdleQuietMs),timeoutMs:k(e.timeoutMs),maxDepth:k(e.maxDepth),maxNodes:k(e.maxNodes),rootPresent:On(e.rootPresent),captureMode:e.captureMode===`interactive-windows`||e.captureMode===`active-window`?e.captureMode:void 0,windowCount:k(e.windowCount),nodeCount:k(e.nodeCount),truncated:On(e.truncated),elapsedMs:k(e.elapsedMs)}}function M(e,n,r,i){if(i instanceof t){let a=i.details??{};return new t(i.code,i.message,{...a,action:e,package:r,tool:n,hint:typeof a.hint==`string`?a.hint:kr(n,a)},i)}return new t(`COMMAND_FAILED`,`Failed to ${e} Android ${n} for ${r}`,{action:e,package:r,tool:n,hint:Dr(n)},i)}function Dr(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 Or(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 kr(e,t){let n=(typeof t.stderr==`string`?t.stderr:``).toLowerCase();return e===`simpleperf`?Ar(n):Mr(n)?`Use a device image that permits perfetto trace capture for shell, keep the app running, then retry perf trace start.`:Dr(e)}function Ar(e){return jr(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.`:Dr(`simpleperf`)}function jr(e){return e.includes(`permission denied`)||e.includes(`not profileable`)||e.includes(`profileable`)}function Mr(e){return e.includes(`permission denied`)||e.includes(`not allowed`)}const Nr=`adb-shell-simpleperf`,Pr=`adb-shell-perfetto`,Fr=15e3,N=3e4,Ir=`/data/local/tmp`;async function Lr(e,n){try{let t=await b(e,[`pidof`,n],{allowFailure:!0,timeoutMs:Fr}),r=zr(t.stdout);if(t.exitCode===0&&r)return r}catch{}throw new t(`COMMAND_FAILED`,`No active Android app process found for ${n}`,{package:n,hint:`Run open <app> for this session again, wait for the app UI to appear, then retry perf.`})}async function Rr(e,n,r){let i=await b(e,[_(`command -v ${v(n)} || which ${v(n)}`)],{allowFailure:!0,timeoutMs:Fr});if(!(i.exitCode===0&&i.stdout.trim()))throw new t(`UNSUPPORTED_OPERATION`,`Android device does not expose ${n}`,{package:r,tool:n,hint:Or(n)})}function zr(e){return e.trim().split(/\s+/).find(e=>/^\d+$/.test(e))}const Br=2e3,Vr=`android_snapshot_helper_runtime_occupied`,P=new Map;function Hr(e){return`${e.platform}:${e.id}`}async function Ur(e){await ni({adb:e.adb,packageName:e.packageName}),await Gr({deviceKey:e.deviceKey,packageName:e.packageName,adb:e.adb,cause:e.cause})}async function Wr(e){let t=P.get(e.deviceKey);if(!t)return;await ni({adb:e.adb,packageName:t.packageName,timeoutMs:5e3,...e.signal?{signal:e.signal}:{}}),e.signal?.throwIfAborted();let n=await Jr({adb:e.adb,packageName:t.packageName});if(n===`occupied`&&(await g(250),n=await Jr({adb:e.adb,packageName:t.packageName})),n===`occupied`)throw qr({deviceKey:e.deviceKey,packageName:t.packageName,cause:t.cause});n!==`unknown`&&P.delete(e.deviceKey)}async function Gr(e){let t=e.release??await Jr({adb:e.adb,packageName:e.packageName});if(t===`released`)return P.delete(e.deviceKey),t;let n=e.cause instanceof Error?e.cause.message:String(e.cause);return P.set(e.deviceKey,{packageName:e.packageName,cause:n}),h({level:`warn`,phase:`android_snapshot_helper_retirement_pending`,data:{deviceKey:e.deviceKey,packageName:e.packageName,release:t}}),t}function Kr(e){return e instanceof t&&e.details?.reason===Vr}function qr(e){let n=e.cause instanceof Error?e.cause.message:String(e.cause);return new t(`COMMAND_FAILED`,`Android automation helper is still holding device automation ownership`,{reason:Vr,deviceKey:e.deviceKey,packageName:e.packageName,cause:n,hint:`Retry after the helper process exits, or restart the device if Android keeps reporting the helper as running.`})}async function Jr(e){try{let t=await b(e.adb,[`pidof`,e.packageName,_(`|| echo AGENT_DEVICE_NO_HELPER`)],{allowFailure:!0,timeoutMs:Br}),n=t.stdout.trim();return zr(n)?`occupied`:n===`AGENT_DEVICE_NO_HELPER`&&t.stderr.trim().length===0?`released`:`unknown`}catch{return`unknown`}}async function Yr(e){let t=AbortSignal.timeout(e.timeoutMs);return await Promise.all([...e.forceStopRuntime?[ni({adb:e.adb,packageName:e.packageName,timeoutMs:e.timeoutMs,signal:t})]:[],ri({...e,signal:t})]),{timedOut:t.aborted}}function Xr(e){let t=Zr(e);return{ended:t?Promise.resolve():new Promise(t=>{e.once(`close`,()=>t()),e.once(`exit`,()=>t())}),hasEnded:()=>Zr(e),completedCleanly:()=>!t&&e.exitCode===0&&e.signalCode==null}}function Zr(e){return e.exitCode!=null||e.signalCode!=null}async function Qr(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 $r(e){if(e.processExit.hasEnded())return!0;try{e.process.kill(`SIGTERM`)}catch{}return await Qr(e.processExit.ended,e.timeoutMs)}function ei(e){P.delete(e)}function ti(){P.clear()}async function ni(e){await b(e.adb,[`am`,`force-stop`,e.packageName],{allowFailure:!0,timeoutMs:e.timeoutMs??2e3,...e.signal?{signal:e.signal}:{}}).catch(()=>{})}async function ri(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 ii(e){let n=oi(e),r=e.deviceKey??`android:default`;await Wr({deviceKey:r,adb:e.adb,signal:e.signal});let i;try{i=await e.adb(si(n),{allowFailure:!0,timeoutMs:n.commandTimeoutMs,signal:e.signal})}catch(t){throw e.signal?.aborted?(await Ur({deviceKey:r,packageName:n.packageName,adb:e.adb,cause:t}),e.signal.throwIfAborted(),t):t}e.signal?.aborted&&(await Ur({deviceKey:r,packageName:n.packageName,adb:e.adb,cause:e.signal.reason}),e.signal.throwIfAborted());let{output:a,cleanupDone:o}=await ci(e,n,i);if(n.outputPath&&!o&&await hi(e.adb,n.outputPath),i.exitCode!==0)throw new t(`COMMAND_FAILED`,`Android snapshot helper failed`,Se(i,{helper:a.metadata}));return a}function ai(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:Wn,commandTimeoutMs:Gn,...e.signal?{signal:e.signal}:{}}}function oi(e){let t=F(e.timeoutMs,8e3),n=F(e.packageName,`com.callstack.agentdevice.snapshothelper`);return{waitForIdleTimeoutMs:F(e.waitForIdleTimeoutMs,500),waitForIdleQuietMs:F(e.waitForIdleQuietMs,100),timeoutMs:t,commandTimeoutMs:F(e.commandTimeoutMs,t+5e3),maxDepth:F(e.maxDepth,128),maxNodes:F(e.maxNodes,5e3),packageName:n,runner:F(e.instrumentationRunner,`${n}/.SnapshotInstrumentation`),...e.outputPath?{outputPath:e.outputPath}:{},...e.emitChunks===void 0?{}:{emitChunks:e.emitChunks}}}function F(e,t){return e===void 0?t:e}function si(e,t={}){return Te(`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 ci(e,t,n){try{return{output:gi(`${n.stdout}\n${n.stderr}`),cleanupDone:!1}}catch(r){return await li(e,t,n,r)}}async function li(e,n,r,i){if(i instanceof t&&r.exitCode!==0&&i.details?.helper)throw i;let a=await ui(e,n,r);if(a)return{output:a,cleanupDone:!0};throw new t(`COMMAND_FAILED`,r.exitCode===0?`Android snapshot helper output could not be parsed`:`Android snapshot helper failed before returning parseable output`,{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode,...pr(fr(r.exitCode))},i)}async function ui(e,t,n){if(!(n.exitCode!==0||!t.outputPath))return await fi(e.adb,t.outputPath,mi(`${n.stdout}\n${n.stderr}`)??di(t))}function di(e){return{outputFormat:Un,waitForIdleTimeoutMs:e.waitForIdleTimeoutMs,waitForIdleQuietMs:e.waitForIdleQuietMs,timeoutMs:e.timeoutMs,maxDepth:e.maxDepth,maxNodes:e.maxNodes,transport:`instrumentation`}}async function fi(e,t,n){let r;try{r=await b(e,pi(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 pi(e){return[`sh`,`-c`,`cat "$1"; status=$?; rm -f "$1"; exit "$status"`,`agent-device-snapshot-helper-output`,e]}function mi(e){try{return wi(vi(Sn(e).results))}catch{return null}}async function hi(e,t){try{await b(e,[`rm`,`-f`,t],{allowFailure:!0,timeoutMs:5e3})}catch{}}function gi(e){let t=Sn(e),n=vi(t.results);return{xml:bi(_i(t.status),n),metadata:{...wi(n),transport:`instrumentation`}}}function _i(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:I(n.chunkIndex),count:I(n.chunkCount),payloadBase64:e})}return t}function vi(e){let n=e.find(e=>e.agentDeviceProtocol===Hn);if(!n)throw new t(`COMMAND_FAILED`,`Android snapshot helper did not return a final result`);if(n.ok!==`true`)throw new t(`COMMAND_FAILED`,yi(n),{errorType:n.errorType,helper:n,...pr(dr(n))});return n}function yi(e){return e.message&&e.message!==`null`?e.message:e.errorType||`Android snapshot helper returned an error`}function bi(e,n){if(e.length===0)throw new t(`COMMAND_FAILED`,`Android snapshot helper did not return XML chunks`,{helper:n});let r=xi(e),i=Buffer.concat(Ci(Si(e,r),r)).toString(`utf8`);if(!i.includes(`<hierarchy`)||!i.includes(`</hierarchy>`))throw new t(`COMMAND_FAILED`,`Android snapshot helper output did not contain XML`,{xml:i});return i}function xi(e){let n=e[0]?.count??e.length;if(n<1||e.length!==n||e.some(e=>e.count!==n))throw new t(`COMMAND_FAILED`,`Android snapshot helper returned incomplete XML chunks`,{expectedChunks:n,actualChunks:e.length});return n}function Si(e,n){let r=new Map;for(let i of e){if(i.index===void 0||i.index<0||i.index>=n)throw new t(`COMMAND_FAILED`,`Android snapshot helper returned invalid chunk index`,{chunkIndex:i.index,expectedChunks:n});if(r.has(i.index))throw new t(`COMMAND_FAILED`,`Android snapshot helper returned duplicate XML chunks`,{chunkIndex:i.index});r.set(i.index,i.payloadBase64)}return r}function Ci(e,n){let r=[];for(let i=0;i<n;i+=1){let a=e.get(i);if(a===void 0)throw new t(`COMMAND_FAILED`,`Android snapshot helper returned incomplete XML chunks`,{missingChunkIndex:i,expectedChunks:n});r.push(Buffer.from(a,`base64`))}return r}function wi(e){return{helperApiVersion:e.helperApiVersion,outputFormat:Un,waitForIdleTimeoutMs:I(e.waitForIdleTimeoutMs),waitForIdleQuietMs:I(e.waitForIdleQuietMs),timeoutMs:I(e.timeoutMs),maxDepth:I(e.maxDepth),maxNodes:I(e.maxNodes),rootPresent:Ei(e.rootPresent),captureMode:Ti(e.captureMode),windowCount:I(e.windowCount),nodeCount:I(e.nodeCount),truncated:Ei(e.truncated),elapsedMs:I(e.elapsedMs)}}function Ti(e){return e===`interactive-windows`||e===`active-window`?e:void 0}const I=k,Ei=On,Di=5e3,L=new Map,R=new Map;async function Oi(e){return await ki(e)!==void 0}async function ki(e){let t=e.deviceKey??`android:default`;if(await Wr({deviceKey:t,adb:e.adb,signal:e.signal}),!Vi()||!e.adbProvider?.spawn)return;let n=oi(e),r=zi(n),i=await ji({deviceKey:t,identity:Ri(t,r,e),options:e,resolved:r,startBudgetMs:Bi(n.commandTimeoutMs)});return i?{session:i,resolved:r,deviceKey:t}:void 0}function Ai(e){return L.get(e)}async function ji(e){if(!Pi(e.identity))return await Mi(e.deviceKey,e.identity),L.get(e.deviceKey)??await Ni(e)}async function Mi(e,t){let n=L.get(e);!n||Ii(n,t)||await z(e,{force:Zr(n.process)})}async function Ni(e){let n=Date.now();try{return await Li(e)}catch(r){e.options.signal?.throwIfAborted(),R.set(e.identity,Date.now()+Fi(Date.now()-n)),h({level:`warn`,phase:`android_snapshot_helper_session_start_failed`,data:{deviceKey:e.deviceKey,reason:r instanceof t?r.details?.reason:void 0,detail:r instanceof Error?r.message:String(r)}});return}}function Pi(e){let t=R.get(e);return t===void 0?!1:t>Date.now()||(R.delete(e),!1)}function Fi(e){return Math.min(Math.max(e,1e4),6e4)}function Ii(e,t){return e.identity===t&&!Zr(e.process)}async function Li(e){let t=await mr();await e.options.adb([`forward`,`tcp:${t}`,`tcp:${t}`],{allowFailure:!1,timeoutMs:Di,signal:e.options.signal});let n=si({...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 vr(r,e.startBudgetMs,e.options.signal),L.set(e.deviceKey,i),R.delete(e.identity),ei(e.deviceKey),h({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=Xr(r);try{r.kill(`SIGTERM`)}catch{}throw await Promise.all([Qr(n.ended,250),Yr({adb:i.adb,process:i.process,port:i.port,packageName:i.helper.packageName,timeoutMs:Br,forceStopRuntime:!0})]),await Gr({deviceKey:e.deviceKey,packageName:i.helper.packageName,adb:i.adb,cause:t}),t}}function Ri(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 zi(e){let t=Math.min(e.timeoutMs,2e3);return{...e,timeoutMs:t,commandTimeoutMs:Math.min(e.commandTimeoutMs,t+3e3)}}function Bi(e){return Math.min(e,Math.max(Math.floor(e/2),5e3))}function Vi(){let e=x().environment.AGENT_DEVICE_ANDROID_SNAPSHOT_HELPER_SESSION;return e===void 0||!/^(0|false|no|off)$/i.test(e)}async function z(e,t={}){let n=L.get(e);if(!n)return!1;L.delete(e);let r=Xr(n.process),i=t.force===!0||t.signal?.aborted===!0,a=await Hi(n,r,i,t.signal),o=r.hasEnded(),s=a.acknowledged&&a.exited,c=s&&await zt({adb:n.adb,deviceKey:e,signal:t.signal}),l=i?t.signal?.aborted===!0?250:Br:Di,u=i?250:2e3,[d,f]=await Promise.all([$r({process:n.process,processExit:r,timeoutMs:u}),Yr({adb:n.adb,process:n.process,port:n.port,packageName:n.helper.packageName,timeoutMs:l,forceStopRuntime:t.resetRuntime===!0||!c})]),p=await Gr({deviceKey:e,packageName:n.helper.packageName,adb:n.adb,cause:t.cause,...c?{release:`released`}:{}});return h({phase:`android_snapshot_helper_session_stop`,data:{deviceKey:e,port:n.port,capturedCount:n.capturedCount,lifetimeMs:Date.now()-n.startedAtMs,quitAcknowledged:a.acknowledged,quitExitObserved:s,releaseProvenByQuit:c,release:p,forceKilled:!o&&d,forced:i||t.signal?.aborted===!0,externalCleanupTimedOut:f.timedOut}}),!0}async function Hi(e,t,n,r){if(n)return{acknowledged:!1,exited:!1};let i=`quit-${Date.now()}`;try{let n=xr(await hr(e.port,`quit ${i}`,1e3,r),i);return{acknowledged:n,exited:n&&await Qr(t.ended,11e3,r)&&t.completedCleanly()}}catch{return{acknowledged:!1,exited:!1}}}async function Ui(e){await z(Hr(e))}async function Wi(){try{await Promise.allSettled([...L.keys()].map(async e=>{await z(e)}))}finally{L.clear(),R.clear(),ti(),Bt()}}async function Gi(e){let t=await ki(e);if(t)return await Ki({session:t.session,deviceKey:t.deviceKey,options:e,resolved:t.resolved})}async function Ki(e){let{session:t,deviceKey:n,options:r,resolved:i}=e;try{let e=t.capturedCount>0,n=await gr({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 z(n,{force:!0,signal:r.signal,cause:e}),r.signal?.throwIfAborted(),h({level:`warn`,phase:`android_snapshot_helper_session_fallback`,data:{deviceKey:n,reason:e instanceof Error?e.message:String(e),uiAutomationConnectionTimeout:at(e)===`accessibility-timeout`}});return}}async function qi(e){let n=Ai(e.deviceKey);if(!n)return;if(!Ji(n.helper,e.helper)){h({level:`warn`,phase:`android_snapshot_helper_session_touch_identity_mismatch`,data:{deviceKey:e.deviceKey,sessionHelper:n.helper,requestedHelper:e.helper}}),await z(e.deviceKey);return}let r=`${e.action}-${Date.now()}-${Math.random().toString(16).slice(2)}`,i=e.payloadBase64?`${e.action} ${r} ${e.payloadBase64}`:`${e.action} ${r}`,a;try{a=yr(await hr(n.port,i,e.timeoutMs)),br(a,r)}catch(t){throw await z(e.deviceKey),t}if(a.ok!==`true`)throw new t(`COMMAND_FAILED`,a.message||a.errorType||`Android automation helper ${e.action} failed`,{errorType:a.errorType,helper:a});return a}function Ji(e,t){return e.packageName===t.packageName&&e.runner===t.runner&&Yi(e.helperVersion,t.helperVersion)&&Yi(e.helperVersionCode,t.helperVersionCode)&&Yi(e.sha256,t.sha256)}function Yi(e,t){return e===void 0||t===void 0||e===t}const Xi=`android-touch-plan-v1`,Zi=45e3,Qi=`ANDROID_TOUCH_HELPER_NO_FINAL_RESULT`,$i=`ANDROID_TOUCH_HELPER_REPORTED_FAILURE`;async function ea(e,t){let n=await ra(e),r=aa(t),i=Math.max(45e3,r.durationMs+15e3),a=Buffer.from(JSON.stringify({protocol:Xi,...r})).toString(`base64`),o=await m(`android_touch_helper_gesture`,async()=>{let e=await qi({deviceKey:n.deviceKey,action:`gesture`,helper:na(n.artifact),payloadBase64:a,timeoutMs:i});return e?{...la(e),helperTransport:`persistent-session`}:{...await sa({adb:n.adb,runner:n.artifact.manifest.instrumentationRunner,extraArgs:[`-e`,`mode`,`gesture`,`-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 ta(e,t={}){let n=await ra(e);t.helperSessionScope===`daemon-session`&&await Oi(ai({adb:n.adb,adbProvider:n.adbProvider,artifact:n.artifact,deviceKey:n.deviceKey}));try{let e=await qi({deviceKey:n.deviceKey,action:`viewport`,helper:na(n.artifact),timeoutMs:Zi});if(e)return ua(e)}catch(e){await z(n.deviceKey),h({level:`warn`,phase:`android_touch_helper_viewport_session_fallback`,data:{reason:e instanceof Error?e.message:String(e)}})}return await sa({adb:n.adb,runner:n.artifact.manifest.instrumentationRunner,extraArgs:[`-e`,`mode`,`viewport`],timeoutMs:Zi,readResult:ua})}function na(e){return{packageName:e.manifest.packageName,runner:e.manifest.instrumentationRunner,helperVersion:e.manifest.version,helperVersionCode:e.manifest.versionCode,sha256:e.manifest.sha256}}async function ra(e){let t=C(e),n=t.snapshotHelperArtifact??await ia(),r=Hr(e);await Wr({deviceKey:r,adb:t.exec});let i=await m(`android_touch_helper_install`,async()=>await ir({adb:t.exec,adbProvider:t,artifact:n,deviceKey:r,timeoutMs:3e4}),{packageName:n.manifest.packageName,versionCode:n.manifest.versionCode});return h({phase:`android_touch_helper_install_decision`,data:i}),i.installed&&await z(r),{adb:t.exec,adbProvider:t,artifact:n,install:i,deviceKey:r}}async function ia(){return await Pn({helperDirName:`snapshot-helper`,manifestFileName:e=>`agent-device-android-snapshot-helper-${e}.manifest.json`,parseManifest:e=>{let t=Kn(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 aa(e){return{kind:e.topology===`single`?`swipe`:`transform`,durationMs:e.durationMs,pointers:e.pointers.map(oa)}}function oa(e){return{pointerId:e.pointerId,samples:e.samples.map(({offsetMs:e,point:t})=>({offsetMs:e,x:t.x,y:t.y}))}}async function sa(e){let n=await b(e.adb,[`am`,`instrument`,`-w`,...e.extraArgs,e.runner],{allowFailure:!0,timeoutMs:e.timeoutMs}),r;try{r=ca(`${n.stdout}\n${n.stderr}`)}catch(e){if(e instanceof t){if(e.code===$i)throw new t(`COMMAND_FAILED`,e.message,e.details,e);if(e.code!==Qi)throw e}throw new t(`COMMAND_FAILED`,n.exitCode===0?`Android automation helper output could not be parsed`:`Android automation helper failed before returning parseable output`,Se(n),e)}if(n.exitCode!==0)throw new t(`COMMAND_FAILED`,`Android automation helper failed`,Se(n,{helper:r}));return e.readResult(r)}function ca(e){let n=Sn(e).results.find(e=>e.agentDeviceProtocol===Hn);if(!n)throw new t(Qi,`Android automation helper did not return a final result`);if(n.ok!==`true`)throw new t($i,n.message&&n.message!==`null`?n.message:n.errorType||`Android automation helper returned an error`,{errorType:n.errorType,helper:n});return n}function la(e){return{helperKind:e.kind,helperApiVersion:e.helperApiVersion,injectedEvents:k(e.injectedEvents),elapsedMs:k(e.elapsedMs)}}function ua(e){let n=k(e.x),r=k(e.y),i=k(e.width),a=k(e.height);if(n===void 0||r===void 0||i===void 0||a===void 0)throw new t(`COMMAND_FAILED`,`Android helper returned an invalid gesture viewport`);let o=da(e);return{viewport:kn({x:n,y:r,width:i,height:a}),...o?{keyboard:o}:{}}}function da(e){let t=k(e.keyboardX),n=k(e.keyboardY),r=k(e.keyboardWidth),i=k(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 fa(e){if(e.topology===`two`||e.intent===`longPress`)return e;let{releaseBehavior:t,...n}=e,[{pointerId:r,samples:i}]=n.pointers,a=[...new Set([...et(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:nt(n.point,r.point,t===`controlled`?pa(s,a):s)}}),c=[s[0],s[1],s[2],...s.slice(3)];return{...n,pointers:[{pointerId:r,samples:c}]}}function pa(e,t){let n=Math.min(16/t,.5);return e<n?e**2/n:1-(1-e)**2/(1-n)}async function B(e,t){let n=fa(t),r=je(e);if(r){let e=n.intent===`longPress`?{...n,viewport:kn(await r.gestureViewport())}:n;return{backend:`provider-native-touch`,...await r.touch(e)??{}}}return await ea(e,n)}async function ma(e,t={}){return(await ha(e,t)).viewport}async function ha(e,t={}){let n=je(e);return n?{viewport:kn(await n.gestureViewport())}:await ta(e,t)}async function ga(e,t,n){await T(e,[`input`,`tap`,t,n])}async function _a(e,t,n){let r=we(t);await T(e,[`input`,...n&&n>0?[`keyevent`,`--longpress`]:[`keyevent`],r])}async function va(e){await T(e,[`input`,`keyevent`,`4`])}async function ya(e){await T(e,[`input`,`keyevent`,`3`])}async function ba(e){await T(e,[`input`,`keyevent`,`ENTER`])}async function xa(e,t){let n=ja(t);await T(e,[`settings`,`put`,`system`,`accelerometer_rotation`,`0`]),await T(e,[`settings`,`put`,`system`,`user_rotation`,n]),await Ca(e,t,n)}const Sa=15e3;async function Ca(e,n,r){let i=Date.now()+Sa,a=await wa(e,n,i);for(;a!==void 0&&a!==r&&Date.now()<i;)await g(Math.min(500,Ta(i))),a=await wa(e,n,i);if(a!==void 0&&a!==r)throw new t(`COMMAND_FAILED`,`orientation ${n} did not take effect: the display still reports rotation ${a} after ${Sa}ms`,{requestedRotation:Number(r),observedRotation:Number(a),hint:"The foreground app may pin its orientation, or the device may ignore user_rotation. Check `adb shell dumpsys display | grep mCurrentOrientation` and the app manifest."})}async function wa(e,n,r){try{let t=await T(e,[`dumpsys`,`display`],{timeoutMs:Ta(r)});return/mCurrentOrientation=(\d)/.exec(t.stdout)?.[1]}catch(e){throw new t(`COMMAND_FAILED`,`orientation ${n} could not confirm the display rotation: ${e instanceof Error?e.message:String(e)}`,{hint:"The device did not answer `dumpsys display` within the orientation budget."})}}function Ta(e){return Math.max(1,e-Date.now())}async function Ea(e){await T(e,[`input`,`keyevent`,`187`])}async function Da(e,t,n,r=800){let i={x:t,y:n};return await B(e,{topology:`single`,intent:`longPress`,durationMs:r,pointers:[{pointerId:0,samples:[{offsetMs:0,point:i},{offsetMs:r,point:i}]}]})}async function Oa(e,t,n){await ga(e,t,n)}async function ka(e,t,n){let{viewport:r,keyboard:i}=await ha(e,{helperSessionScope:n?.helperSessionScope}),a=Aa(t,r,i),o=ue({direction:t,amount:n?.amount,pixels:n?.pixels,referenceWidth:a.viewport.width,referenceHeight:a.viewport.height}),s={...o,referenceWidth:a.viewport.x+a.viewport.width,referenceHeight:a.viewport.y+a.viewport.height,x1:a.viewport.x+o.x1,y1:a.viewport.y+o.y1,x2:a.viewport.x+o.x2,y2:a.viewport.y+o.y2},c=Math.max(n?.durationMs??300,16),l=await B(e,{...tt({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 Aa(e,t,n){if(n===void 0)return{viewport:t,evidence:{}};let r=de(t,n);if(r.kind===`occluded`)throw le(e,{keyboardMinY:r.keyboardMinY,visibleHeight:r.visibleHeight,viewportHeight:t.height});return r.kind===`avoided`?{viewport:r.viewport,evidence:{keyboardAvoided:!0,keyboardMinY:r.keyboardMinY}}:{viewport:t,evidence:{}}}function ja(e){let n=ve[e];if(n===void 0)throw new t(`INVALID_ARGS`,`Unsupported Android rotation: ${e}`);return String(n)}async function Ma(e){let n=(await T(e,[`wm`,`size`])).stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(!n)throw new t(`COMMAND_FAILED`,`Unable to read screen size`);return{width:Number(n[1]),height:Number(n[2])}}async function Na(e,t,n){return t===`wait`?await Pa(n.captureNodes,n.timeoutMs??1e4):t===`get`?Ba((await za(n.captureNodes))?.alert??null):await Fa(e,t,n.captureNodes)}async function Pa(e,n){let r=Date.now(),i=await Ra(e,n);if(!i)throw new t(`COMMAND_FAILED`,`alert wait timed out`);return{kind:`alertWait`,platform:`android`,action:`wait`,alert:i.alert,waitedMs:Date.now()-r,...fe(`Alert visible`)}}async function Fa(e,n,r){let i=await Ra(r,pe);if(!i)throw new t(`COMMAND_FAILED`,`alert not found`,{hint:`If a sheet is visible in snapshot but alert reports no alert, it is likely app-owned UI. Use snapshot -i and press the visible label/ref.`});let a=en(i.buttons,n);if(a)return await ga(e,a.x,a.y),await Ia(i.alert,n,r),Va(n,i.alert,a.label,{x:a.x,y:a.y});if(n===`dismiss`)return await va(e),await Ia(i.alert,n,r),Va(n,i.alert,`Back`);throw new t(`COMMAND_FAILED`,`alert accept found an alert but no accept button`,{alert:i.alert,hint:`Inspect alert get --json for visible buttons, then use press by visible label/ref if needed.`})}async function Ia(e,n,r){let i=Date.now();for(;;){let a=await za(r);if(!a||!La(a.alert,e))return;if(Date.now()-i>=2e3)throw new t(`COMMAND_FAILED`,`alert ${n} did not dismiss the visible alert`,{alert:e,hint:`The alert button was pressed but the dialog is still visible. Inspect alert get --json, then press the visible button by label/ref or retry.`});await g(300)}}function La(e,t){return e.title===t.title&&e.buttons.join(`\0`)===t.buttons.join(`\0`)}async function Ra(e,t){let n=Date.now();for(;Date.now()-n<t;){let t=await za(e);if(t)return t;await g(300)}return null}async function za(e){return Qt(await m(`snapshot_capture`,e,{backend:`android`,purpose:`alert`}))}function Ba(e){return{kind:`alertStatus`,platform:`android`,action:`get`,alert:e,...fe(e?`Alert visible`:`No alert visible`)}}function Va(e,t,n,r){return{kind:`alertHandled`,platform:`android`,action:e,handled:!0,alert:t,button:n,...r?{coordinates:r}:{},...fe(`Alert ${e}ed`)}}const Ha=`android.intent.category.LAUNCHER`,Ua=`android.intent.category.DEFAULT`;async function Wa(e,t){await b(e,[`am`,`force-stop`,t])}async function Ga(e,t,n=[Ha]){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=dt(n.stdout);if(i)return i}return null}async function Ka(e,n,r={}){let i=r.category??Ha;if(r.activity){await b(e,[`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,Ua,`-c`,i,`-n`,qa(n,r.activity)]);return}let a=await b(e,[`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,Ua,`-c`,i,`-p`,n],{allowFailure:!0});if(a.exitCode===0&&!ft(a.stdout,a.stderr))return;let o=await Ga(e,n,[i]);if(!o)throw new t(`COMMAND_FAILED`,`Failed to resolve Android launch component for ${n}`,{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});await b(e,[`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,Ua,`-c`,i,`-n`,o])}function qa(e,t){return t.includes(`/`)?t:`${e}/${t.startsWith(`.`)?t:`.${t}`}`}let Ja=null;function Ya(e){return`${e.PATH??``}::${e.AGENT_DEVICE_BUNDLETOOL_JAR??``}`}async function Xa(e){let n=Ya(e);if(Ja?.key===n)return Ja.invocation;if(await xe(`bundletool`)){let e={cmd:`bundletool`,prefixArgs:[]};return Ja={key:n,invocation:e},e}let r=await Ce(e.AGENT_DEVICE_BUNDLETOOL_JAR,`AGENT_DEVICE_BUNDLETOOL_JAR`);if(!r)throw new t(`TOOL_MISSING`,`bundletool not found in PATH. Install bundletool or set AGENT_DEVICE_BUNDLETOOL_JAR to a bundletool-all.jar path.`);let i={cmd:`java`,prefixArgs:[`-jar`,r]};return Ja={key:n,invocation:i},i}async function Za(e,t,n){let r=await Xa(n);await be(r.cmd,[...r.prefixArgs,...e],{signal:t})}function Qa(e){return E.extname(e).toLowerCase()===`.aab`}async function $a(e,t,n={}){let r=C(e),i=`universal`;if(r.installBundle){await r.installBundle(t,{mode:i,signal:n.signal});return}let a=x().files,o=await a.makeTempDirectory(`agent-device-aab-`),s=E.join(o,`bundle.apks`);try{await Za([`build-apks`,`--bundle`,t,`--output`,s,`--mode`,i],n.signal,n.environment??x().environment),await Za([`install-apks`,`--apks`,s,`--device-id`,e.id],n.signal,n.environment??x().environment)}finally{await a.remove(o,{recursive:!0,force:!0})}}async function eo(e,t,n={}){if(Qa(t)){await $a(e,t,n);return}await ze(t,{device:e,replace:!0,signal:n.signal})}async function to(e,t,n={}){await gt(e,async()=>{e.booted||await st(e.id,void 0,n.signal),await eo(e,t,n)})}const no=[`mInputShown`,`mIsInputViewShown`,`isInputViewShown`,`mDecorViewVisible`,`mWindowVisible`,`mInShowWindow`],ro=new Map([[2,`number`],[3,`phone`],[4,`datetime`]]),io=new Set([32,208]),ao=new Set([128,224,144]);async function oo(e){return await V(y(e))}async function V(e){let t=await b(e,[`dumpsys`,`input_method`],{allowFailure:!0});if(t.exitCode!==0)throw w(`Failed to query Android keyboard state`,t);return lo(t.stdout)}async function so(e){return await co(y(e))}async function co(e){let n=await V(e),r=n,i=0;for(;r.visible&&i<2;)await b(e,[`input`,`keyevent`,`111`]),i+=1,await g(120),r=await V(e);if(n.visible&&r.visible)throw new t(`UNSUPPORTED_OPERATION`,`Android keyboard dismiss is unavailable for the current IME without back navigation.`,{attempts:i,inputType:r.inputType,type:r.type,inputMethodPackage:r.inputMethodPackage,focusedPackage:r.focusedPackage,focusedResourceId:r.focusedResourceId,inputOwner:r.inputOwner});return{attempts:i,wasVisible:n.visible,dismissed:n.visible&&!r.visible,visible:r.visible,inputType:r.inputType,type:r.type,inputMethodPackage:r.inputMethodPackage,focusedPackage:r.focusedPackage,focusedResourceId:r.focusedResourceId,inputOwner:r.inputOwner}}function lo(e){let t=ho(e)??uo(e),n=fo(e),r=po(e,/\bpackageName=([A-Za-z0-9_.]+)\b/g),i=po(e,/\b(?:resourceId|resource-id)=([^\s,}]+)/g),a=f(e),o=ee(r,i,a);return mo(r,i,a),{visible:t??!1,inputType:n,type:n?yo(n):void 0,inputMethodPackage:a,focusedPackage:r,focusedResourceId:i,inputOwner:o}}function uo(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 fo(e){let t=po(e,/\binputType=0x([0-9a-fA-F]+)\b/gi);return t?`0x${t.toLowerCase()}`:void 0}function po(e,t){let n;for(let r of e.matchAll(t))n=r[1];return n}function mo(e,t,n){n||!u(e)&&!c(t)||h({level:`warn`,phase:`android_input_ownership_fallback`,data:{focusedPackage:e,focusedResourceId:t}})}function ho(e){return _o(go(e,no))}function go(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 _o(e){if(e.size===0)return null;let t=vo(e,[`mWindowVisible`,`mDecorViewVisible`,`mInShowWindow`]);if(t!==void 0)return t;let n=e.get(`mInputShown`);return n===void 0?vo(e,[`mIsInputViewShown`,`isInputViewShown`])??null:n}function vo(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=ro.get(n);if(r)return r;if(n!==1)return`unknown`;let i=t&4080;return io.has(i)?`email`:ao.has(i)?`password`:`text`}async function bo(e){return await xo(y(e))}async function xo(e){return To(await wo(e,[`cmd`,`clipboard`,`get`,`text`],`read`))}async function So(e,t){await Co(y(e),t)}async function Co(e,t){await wo(e,[`cmd`,`clipboard`,`set`,`text`,t],`write`)}async function wo(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 w(`Failed to ${n} Android clipboard text`,a);return a.stdout}function To(e){let t=e.replaceAll(`\r
|
|
9
9
|
`,`
|
|
10
|
-
`).replace(/\n$/,``),n=t.match(/^clipboard text:\s*(.*)$/i);return n?n[1]??``:t.trim().toLowerCase()===`null`?``:t}const
|
|
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 Zo=2e3;async function Qo(e=y().environment,t=y().files){let n=e.ANDROID_HOME||e.ANDROID_SDK_ROOT,r=await us(n,t),i=await Dt(`adb`,[`version`]);return i?os({license:r,sdkRoot:n,versionLine:i}):ls(n,r)}async function $o(e,t){if(e.platform!==`android`)return[];let n=v(e,t.transportOverrides.androidAdb),r=[];return t.shouldProbeMetro&&r.push(await as(n,e.id,t.metroPort)),r.push(await es(n,e)),r}async function es(e,t){try{let n=await G(e),r=Ho(t);return n===await ts()&&!r?await ns(e,t,n):rs(t,n,r)}catch(e){return is(e)}}async function ts(){try{return(await Co()).manifest.serviceComponent}catch{return}}async function ns(e,t,n){let r=(await e([`shell`,`settings`,`get`,`secure`,Fo.previousIme],{allowFailure:!0,timeoutMs:Zo})).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 rs(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 is(e){let t=n(e);return{id:`android-test-ime`,status:`warn`,summary:`Could not inspect the Android test IME helper state.`,hint:t.message,evidence:{code:t.code}}}async function as(e,t,r){try{let n=await e([`reverse`,`--list`],{allowFailure:!0,timeoutMs:Zo}),i=`tcp:${r} tcp:${r}`,a=n.stdout.includes(i);return{id:`android-reverse`,status:a?`pass`:`warn`,summary:a?`Android adb reverse exists for Metro port ${r}.`:`Android adb reverse is missing for Metro port ${r}.`,command:a?void 0:`adb -s ${t} reverse tcp:${r} tcp:${r}`,evidence:{stdout:n.stdout.trim()}}}catch(e){let t=n(e);return{id:`android-reverse`,status:`warn`,summary:`Could not inspect Android adb reverse mappings.`,hint:t.message,evidence:{code:t.code}}}}function os(e){return{id:`toolchain`,status:ss(e),summary:e.versionLine?`Android toolchain: ${e.versionLine}; ${cs(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 ss(e){return e.versionLine&&e.sdkRoot&&e.license!==`missing`?`pass`:`info`}function cs(e){return e?`ANDROID_HOME/ANDROID_SDK_ROOT set`:`ANDROID_HOME unset`}function ls(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 us(e,t){if(!e)return`unknown`;try{return await t.access(w.join(e,`licenses`,`android-sdk-license`)),`accepted`}catch{return`missing`}}function ds(e,t){if(!t)return{expected:e,actual:null,failureReason:`text_mismatch`,targetInput:null,actualInput:null};let n=hs(t),r={failureReason:t.reason??`text_mismatch`,targetInput:ps(t.targetInput),actualInput:ps(t.actualInput)};return n?{...r,expectedLength:Array.from(e).length,actual:null,masked:!0,actualLength:Array.from(t.actual??``).length}:{...r,expected:e,actual:t.actual}}function J(e){return e?e.password?!0:fs(e.text):!1}function fs(e){return e?Array.from(e).every(ms):!1}function ps(e){if(!e)return null;let t=J(e);return{...e,text:t?null:e.text,...t?{textRedacted:!0}:{}}}function ms(e){return e===`•`||e===`*`||e===`●`}function hs(e){return e.masked===!0||J(e.targetInput)||J(e.actualInput)}const gs=new WeakMap;function _s(e,t){return t&&gs.set(e,t),e}function vs(e){return gs.get(e)}function ys(e){return e.clickable}function bs(e){return e.focusable||e.focused===!0}function Y(e){return ys(e)||bs(e)}function xs(e){let t=e.trim();return t?/^[\w.]+:id\/[\w.-]+$/i.test(t):!1}function Ss(e,t){return{raw:e,...t?{effectiveRect:t}:{}}}function Cs(e,t,n){if(!e)return;let r=Es(e);return t&&(r=Ts(r,t)),n&&(r=Ts(r,n)),r}function ws(e){return{...e.raw,...e.effectiveRect?{rect:e.effectiveRect}:{rect:void 0},hittable:e.raw.hittable===!0&&ae(e.effectiveRect)?!0:void 0}}function Ts(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 Es(e){return{x:e.x,y:e.y,width:Math.max(0,e.width),height:Math.max(0,e.height)}}function Ds(e,t){let n=new Set;return Os(e,n,t),As(e,n,t),n}function Os(e,t,n){for(let r of e.children){if(n?.check(`work`),r.visibleToUser===!1){t.add(r);continue}Os(r,t,n)}}function ks(e,t,n){return n?.check(`work`),e.children.filter(e=>!t.has(e)&&e.visibleToUser!==!1)}function As(e,t,n){let r=ks(e,t,n).filter(Ms);if(r.length<2)return;let i=r.filter(e=>Ns(e)&&Ps(e));if(i.length===0)return;let a=js(i);for(let r of ks(e,t,n))n?.check(`work`),Ns(r)&&(Ps(r)&&(a===void 0||r.windowLayer===a)||t.add(r))}function js(e){let t=e.map(e=>e.windowLayer).filter(e=>e!==void 0);return t.length>0?Math.max(...t):void 0}function Ms(e){return e.windowIndex!==void 0||e.windowType!==void 0}function Ns(e){return e.windowType===1}function Ps(e){return e.windowActive===!0||e.windowFocused===!0}function Fs(e,t,n,r,i){let a=new Set(e.sourceNodes),o=Ls(t,i),s=Is(o,n,Rs(o,a,i),i);if(!s)return{nodes:[],sourceNodes:[]};let c=new Set(Ls([s],i)),l=[];for(let[t,n]of e.sourceNodes.entries())i.check(`work`),c.has(n)&&l.push(t);if(l.length===0)return{nodes:[],sourceNodes:[]};let u=1/0;for(let t of l)i.check(`work`),u=Math.min(u,e.nodes[t]?.depth??0);let d=[];for(let t of l)i.check(`work`),(e.nodes[t]?.depth??0)-u<=r&&d.push(t);return i.consume(d.length),{nodes:oe(d.map(t=>e.nodes[t]),u),sourceNodes:d.map(t=>e.sourceNodes[t])}}function Is(e,t,n,r){for(let i of e)if(r.check(`work`),se(i,t)&&n.has(i))return i;return null}function Ls(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 Rs(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 zs(e,t,n,r,i){if(e.visibleToUser===!1)return!1;let a=Bs(e);return t.interactiveOnly?Vs(e,a,n,r,i):a.isStructural||a.isVisual?Ws(e,a,r):!0}function Bs(e){let t=Ks(e.type),n=!!(e.label&&e.label.trim().length>0),r=!!(e.identifier&&e.identifier.trim().length>0);return{type:t,hasMeaningfulText:n&&!xs(e.label??``),hasMeaningfulId:r&&!xs(e.identifier??``),isStructural:qs(t),isVisual:t===`imageview`||t===`imagebutton`}}function Vs(e,t,n,r,i){return Us(e)?!1:Y(e)||ne(t.type)&&r?!0:Hs(t,n,r,i)}function Hs(e,t,n,r){return!e.hasMeaningfulText&&!e.hasMeaningfulId||e.isVisual||e.isStructural&&!r&&!t?!1:t||n||r}function Us(e){return!!(e.rect&&(e.rect.width<=0||e.rect.height<=0))}function Ws(e,t,n){return Y(e)||t.hasMeaningfulText||t.hasMeaningfulId?!0:n}function Gs(e){if(!e)return!1;let t=Ks(e);return t.includes(`recyclerview`)||t.includes(`listview`)||t.includes(`gridview`)}function Ks(e){return e?e.toLowerCase():``}function qs(e){let t=e.split(`.`).pop()??e;return t.includes(`layout`)||t===`viewgroup`||t===`view`}function Js(e,t,n,r){return{...Ss(e,t),...n?{clipsDescendants:!0}:{},...r?{windowRect:r}:{}}}const Ys=`ANDROID_SNAPSHOT_PRESENTATION_FAILED`;var X=class extends Error{code=Ys;qualityReasonCode=`presentation-failed`;details;analysis;constructor(e,t,n){super(e),this.name=`AndroidSnapshotPresentationFailure`,this.details=t,this.analysis=n}};function Xs(e){return e instanceof X?e.code===Ys:!!(e&&typeof e==`object`&&e.code===Ys)}var Zs=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()+nc()}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 Qs(e,t){return new Zs(e??{},t)}function $s(e,t,n){let r=new Map;for(let i of e){n.check(`regular-invariant`);let e=ec(i,r,t),a=i.effectiveRect;if(!a||!ae(a)){if(ws(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&&!tc(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 ec(e,t,n){let r=e.raw.parentIndex;return r===void 0?e.windowRect??n:t.get(r)??e.windowRect??n}function tc(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 nc(){return 250}function rc(e,t,n){let r=n.depth??1/0,i=ce(n.scope),a=xc(e),o=Qs(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=mc(e,o),s.hidden=n.raw?new Set:Ds(e,o);for(let t of e.children)if(ac(s,t,0),s.truncated)break;n.raw||$s(s.presentationNodes,s.viewport,o);let t=s.nodes,a=new Map(s.sourceNodes.map((e,t)=>[e,t])),{nodes:c,sourceNodes:l}=i?Fs(s,e.children,i,r,o):s,u={nodes:c,sourceNodes:l,occlusionContext:{nodes:t,sourceIndexByNodeIndex:new Map(l.flatMap((e,t)=>{let n=a.get(e),r=c[t]?.index;return n===void 0||r===void 0?[]:[[r,n]]})),androidSiblingOrderByNodeIndex:ic(s.sourceNodes)},analysis:s.analysis};return s.truncated?{...u,truncated:!0}:u}catch(e){throw Xs(e)&&(e.analysis??=s.analysis),e}}function ic(e){let t=new Map,n=new Map;for(let[r,i]of e.entries()){let e=vs(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 ac(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=sc(e,t,c,l),d=cc(e,t,r,i,a,o,u,l),f=i||Y(t),p=a||Gs(t.type),ee=lc(e,t,u,c);uc(e,t,n,d,f,p,o||tt(t.identifier),l,ee)}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 sc(e,t,n,r){return e.options.raw?t.rect:Cs(t.rect,r,n)}function cc(e,t,n,r,i,a,o,s){return!e.options.raw&&!zs(t,e.options,r,_c(e,t),i)?n:dc(e,t,n,a||tt(t.identifier),o,s)}function lc(e,t,n,r){return e.options.raw||!hc(t)?r:n}function uc(e,t,n,r,i,a,o,s,c){for(let l of t.children)if(ac(e,l,n+1,r,i,a,o,s,c),e.truncated)return}function dc(e,t,n,r,i,a){let o=e.nodes.length;return e.sourceNodes.push(t),pc(e,t,fc(e,t,n,r),i,a),o}function fc(e,t,n,r){return{index:e.nodes.length,type:t.type??void 0,label:t.label??void 0,value:t.value??void 0,identifier:t.identifier??void 0,bundleId:t.packageName??void 0,rect:t.rect,enabled:t.enabled,focused:t.focused,selected:t.selected,editable:t.editable,password:t.password,hintShowing:t.hintShowing,selectionStart:t.selectionStart,selectionEnd:t.selectionEnd,visibleToUser:t.visibleToUser,hittable:Y(t)||void 0,depth:gc(e.nodes,n),parentIndex:n,...vc(t,e.hidden),...r?{systemChrome:!0}:{}}}function pc(e,t,n,r,i){let a=Js(n,r,!e.options.raw&&hc(t),i);e.presentationNodes.push(a),e.nodes.push(e.options.raw?a.raw:ws(a))}function mc(e,t){let n=[],r=[...e.children];for(;r.length>0;){t.check(`work`);let e=r.pop();ae(e.windowRect)&&n.push(e.windowRect),r.push(...e.children)}return ie(n)??void 0}function hc(e){return e.scrollable===!0&&ne(e.type)}function gc(e,t){return t===void 0?0:(e[t]?.depth??-1)+1}function _c(e,t){let n=e.interactiveDescendantMemo.get(t);if(n!==void 0)return n;for(let n of t.children)if(!e.hidden.has(n)&&n.visibleToUser!==!1&&(Y(n)||_c(e,n)))return e.interactiveDescendantMemo.set(t,!0),!0;return e.interactiveDescendantMemo.set(t,!1),!1}function vc(e,t){return yc(e,t)?{...e.canScrollBackward?{hiddenContentAbove:!0}:{},...e.canScrollForward?{hiddenContentBelow:!0}:{}}:{}}function yc(e,t){if(!e.scrollable||!ne(e.type)||`${e.type??``}`.toLowerCase().includes(`horizontalscrollview`))return!1;let n=bc(e,t);return!(n&&n.horizontal>n.vertical&&n.horizontal>16)}function bc(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 xc(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 Sc(){let e=[],t=()=>e.at(-1)===!0;return{open(n,r){let i=t()||tt(n);return r||e.push(i),i},close(){e.pop()}}}function*Cc(e){let t=/<node\b[^>]*>|<\/node>/g,n=Sc(),r=t.exec(e);for(;r;){let i=r[0];if(i.startsWith(`</node`))n.close();else{let e=wc(i);yield n.open(e.resourceId,i.endsWith(`/>`))?{...e,systemChrome:!0}:e}r=t.exec(e)}}function wc(e){let t=Tc(e),n=kt(t.bounds);return{...t,...n?{rect:n}:{}}}function Tc(e){let t=Ec(e),n=e=>Pc(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=kt(n(t));return r===void 0?{}:{[e]:r}},s=(e,t)=>{let n=r(t);return n===void 0?{}:{[e]:n}};return{text:n(`text`),desc:n(`content-desc`),resourceId:n(`resource-id`),packageName:n(`package`),className:n(`class`),bounds:n(`bounds`),clickable:r(`clickable`),enabled:r(`enabled`),focusable:r(`focusable`),focused:r(`focused`),password:r(`password`),...s(`editable`,`editable`),...a(`selectionStart`,`selection-start`),...a(`selectionEnd`,`selection-end`),...s(`hintShowing`,`hint-showing`),...s(`visibleToUser`,`visible-to-user`),...s(`selected`,`selected`),...a(`drawingOrder`,`drawing-order`),...s(`scrollable`,`scrollable`),...s(`canScrollForward`,`can-scroll-forward`),...s(`canScrollBackward`,`can-scroll-backward`),...a(`windowIndex`,`window-index`),...a(`windowType`,`window-type`),...a(`windowLayer`,`window-layer`),...s(`windowActive`,`window-active`),...s(`windowFocused`,`window-focused`),...o(`windowRect`,`window-bounds`)}}function Ec(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=Dc(e,i,r);if(!n)break;t.set(n.name,n.value),i=n.nextCursor}return t}function Dc(e,t,n){if(t=kc(e,t,n),t>=n||Ac(e[t]))return;let r=t;t=Oc(e,t,n);let i=e.slice(r,t);if(t=kc(e,t,n),!i||e[t]!==`=`)return;t=kc(e,t+1,n);let a=e[t];if(!jc(a))return;let o=t+1,s=e.indexOf(a,o);if(!(s<0||s>=n))return{name:i,value:At(e.slice(o,s)),nextCursor:s+1}}function Oc(e,t,n){for(;t<n&&!Nc(e[t]??``);)t+=1;return t}function kc(e,t,n){for(;t<n&&Mc(e[t]??``);)t+=1;return t}function Ac(e){return e===`/`||e===`>`}function jc(e){return e===`"`||e===`'`}function Mc(e){return e===` `||e===`
|
|
12
|
-
`||e===`\r`||e===` `}function Nc(e){return e===`=`||e===`/`||e===`>`||Mc(e)}function Pc(e,t){return e.get(t)??null}function Fc(e){let t={type:null,label:null,value:null,identifier:null,packageName:null,clickable:!1,focusable:!1,depth:-1,children:[]},n=[t],r=/<node\b[^>]*>|<\/node>/g,i=r.exec(e);for(;i;){let t=i[0];if(t.startsWith(`</node`)){n.length>1&&n.pop(),i=r.exec(e);continue}let a=wc(t),o=n.at(-1),s=Ic(a,o.depth+1,o);o.children.push(s),t.endsWith(`/>`)||n.push(s),i=r.exec(e)}return t}function Ic(e,t,n){return _s({type:e.className,label:e.text||e.desc,value:e.text,identifier:e.resourceId,packageName:e.packageName,rect:e.rect,enabled:e.enabled,focused:e.focused,selected:e.selected,editable:e.editable,password:e.password,hintShowing:e.hintShowing,selectionStart:e.selectionStart,selectionEnd:e.selectionEnd,visibleToUser:e.visibleToUser,clickable:e.clickable===!0,focusable:e.focusable===!0,scrollable:e.scrollable,canScrollForward:e.canScrollForward,canScrollBackward:e.canScrollBackward,windowIndex:e.windowIndex,windowType:e.windowType,windowLayer:e.windowLayer,windowActive:e.windowActive,windowFocused:e.windowFocused,windowRect:e.windowRect,depth:t,parentIndex:void 0,children:[]},e.drawingOrder===void 0?void 0:{parent:n,order:e.drawingOrder})}function Lc(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 Rc=new Set([`android`,`com.android.systemui`]);function zc(e,t,n={}){if(t.backend!==`android-helper`)return{outcome:`ok`};let r=Xc(e,n.foregroundAppPackage);return Hc(r,t)?Bc(r,t,`empty-helper-output`,`Android snapshot helper returned no accessibility nodes`):Jc(r)?{outcome:`ok`}:Vc(r)?{outcome:`system-surface-only`}:Uc(r)?{outcome:`ok`}:Wc(r)?Bc(r,t,`content-poor-app-window`,`Android snapshot helper returned insufficient foreground app content`):Gc(r)||Kc(r,t)?Bc(r,t,`content-poor-app-window`,`Android snapshot helper returned insufficient application window content`):qc(r)?Bc(r,t,`system-window-only`,`Android snapshot helper returned only non-application windows`):{outcome:`ok`}}function Bc(e,t,n,r){return{outcome:`unusable`,decision:Yc(e,t,n,r)}}function Vc(e){return e.windowRootCount>0&&e.applicationWindowRootCount===0&&e.activeSystemSurfaceMeaningfulNodeCount>=3}function Hc(e,t){return e.nodeCount===0||t.nodeCount===0||t.rootPresent===!1}function Uc(e){return Wc(e)&&e.inputMethodMeaningfulNodeCount>=2}function Wc(e){let t=e.foregroundAppMeaningfulNodeCount;return t===void 0?!1:t===0?e.applicationMeaningfulNodeCount<2:t<2&&e.meaningfulNodeCount>t}function Gc(e){return e.foregroundAppMeaningfulNodeCount===void 0&&e.applicationWindowRootCount>0&&e.applicationMeaningfulNodeCount<2}function Kc(e,t){return e.foregroundAppMeaningfulNodeCount===void 0&&e.windowRootCount===0&&(t.windowCount??0)>1&&e.nonSystemMeaningfulNodeCount<2}function qc(e){return e.windowRootCount>0&&e.applicationWindowRootCount===0||e.windowRootCount===0&&e.nodeCount>0&&e.systemUiNodeCount===e.nodeCount}function Jc(e){return e.hasAlertButtonIdentifier&&e.hasAlertContentIdentifier}function Yc(e,t,n,r){return{reason:n,failureReason:r,diagnostics:ul(e,t)}}function Xc(e,t){let n=Zc(t);for(let t of Cc(e))Qc(n,t);return al(n)}function Zc(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 Qc(e,t){e.nodeCount+=1,ll(t.packageName)&&(e.systemUiNodeCount+=1),t.visibleToUser!==!1&&$c(e,t.resourceId),el(e,t),tl(e,t)}function $c(e,t){let n=Jt(t);n===`button`&&(e.hasAlertButtonIdentifier=!0),n===`content`&&(e.hasAlertContentIdentifier=!0)}function el(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 tl(e,t){ol(t)&&(e.meaningfulNodeCount+=1,nl(e,t),il(e,t))}function nl(e,t){e.currentWindowType===1&&!cl(t.packageName)&&(e.applicationMeaningfulNodeCount+=1),rl(e)&&!et(t)&&(e.activeSystemSurfaceMeaningfulNodeCount+=1)}function rl(e){return e.currentWindowType!==void 0&&e.currentWindowType!==1&&e.currentWindowActiveOrFocused===!0}function il(e,t){cl(t.packageName)||(e.nonSystemMeaningfulNodeCount+=1),p({packageName:t.packageName,resourceId:t.resourceId})&&(e.inputMethodMeaningfulNodeCount+=1),e.foregroundAppPackage!==void 0&&t.packageName===e.foregroundAppPackage&&(e.foregroundAppMeaningfulNodeCount=(e.foregroundAppMeaningfulNodeCount??0)+1)}function al(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:sl(e.text)||sl(e.desc)||sl(e.resourceId)}function sl(e){return e!==null&&e.trim()!==``}function cl(e){return e===null||Rc.has(e)}function ll(e){return e!==null&&Rc.has(e)}function ul(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 dl(e){let t=await B(e.deviceKey,{resetRuntime:!0,signal:e.signal,cause:e.cause});e.signal?.throwIfAborted(),t||await fl(e.adb,e.packageName)}async function fl(e,t){await Xr({adb:e,packageName:t}),await g(150),h({level:`debug`,phase:`android_snapshot_helper_runtime_reset`,data:{packageName:t}})}const pl=Symbol(`androidSnapshotCaptureEvidence`);function ml(e,t){return Object.defineProperty(e,pl,{value:t}),e}function hl(e){let t={...e,backend:`android`,producer:`android-uiautomator`},n=e[pl];return te(t,n.clickability),n.occlusionContext&&l(t,n.occlusionContext),t}async function gl(e,t={}){let n=b(e,t.helperAdb).exec;return(await wl(e,t,n)).xml}async function _l(e,t={}){let n=b(e,t.helperAdb).exec,r=await wl(e,t,n),i=r.xml,a=Fc(i),o=bl(r.metadata,a),s={...t,androidPresentation:{...t.androidPresentation,deadlineAtMs:t.androidPresentation?.deadlineAtMs??Date.now()+250}};try{let e=rc(a,void 0,s),n=yl(e.truncated,r.metadata);t.interactiveOnly&&t.includeHiddenContentHints!==!1&&Cl({options:s,tree:a,xml:i,interactiveSnapshot:e});let{sourceNodes:c,occlusionContext:l,...u}=e;return ml({...u,...Sl(n),androidSnapshot:o,quality:{state:`healthy`,backend:`android-helper`}},{clickability:Lc(e),occlusionContext:l})}catch(e){if(!Xs(e))throw e;return vl({failure:e,androidSnapshot:o})}}function vl(e){return ml({nodes:[],truncated:!0,analysis:e.failure.analysis??{rawNodeCount:0,maxDepth:0},androidSnapshot:{...e.androidSnapshot,presentationFailure:{phase:e.failure.details.phase,workUnits:e.failure.details.workUnits,...e.failure.details.maxWorkUnits===void 0?{}:{maxWorkUnits:e.failure.details.maxWorkUnits}}},quality:{state:`sparse`,backend:`android-helper`,reason:e.failure.message,reasonCode:e.failure.qualityReasonCode}},{clickability:{kind:`exact`,provider:`android-helper`,clickableByNodeIndex:new Map}})}function yl(e,t){return e===!0||t.helperTruncated===!0||e}function bl(e,t){return xl(t)===!1?{...e,occlusionScanUnavailable:!0}:e}function xl(e){let t=[...e.children];if(t.length!==0){for(;t.length>0;){let e=t.pop();if(vs(e)!==void 0)return!0;t.push(...e.children)}return!1}}function Sl(e){return e===!0?{truncated:!0}:{}}function Cl(e){if(Hl(e.interactiveSnapshot.nodes).size>0||Vl(e.xml))return;let t=rc(e.tree,void 0,{...e.options,interactiveOnly:!1});Ul(_e(r(t.nodes)),t,e.interactiveSnapshot)}async function wl(e,t,n){let r=b(e,t.helperAdb),i=await m(`android_snapshot_helper_artifact_resolution`,async()=>await zl(t.helperArtifact??r.snapshotHelperArtifact));if(i.artifact)return await Tl(e,t,n,i.artifact);throw h({level:`error`,phase:`android_snapshot_helper_unavailable`,data:{reason:i.errorReason??`artifact_not_found`}}),Bl(i.errorReason)}async function Tl(e,t,n,r){let i=Ir(e),a=b(e,t.helperAdb),o=t.helperSessionScope!==`daemon-session`;try{let e;for(let o=0;;o+=1){o>0&&await Al(t.signal);let s=await kl({options:t,adb:n,adbProvider:a,artifact:r,helperDeviceKey:i,attempt:o,previousContentReason:e});if(s.outcome===`captured`)return s.capture;if(o+1>=3)return await jl({contentRecovery:s.decision,attempts:o+1,helperDeviceKey:i,artifact:r,adb:n,signal:t.signal});e=s.decision.reason}}finally{o&&await B(i)}}async function El(e,t,n,r,i){let a=await m(`android_snapshot_helper_install`,async()=>await $n({adb:t,adbProvider:n,artifact:r,deviceKey:i,installPolicy:e.helperInstallPolicy,timeoutMs:3e4,signal:e.signal}),{packageName:r.manifest.packageName,versionCode:r.manifest.versionCode,installPolicy:e.helperInstallPolicy??`missing-or-outdated`});return h({phase:`android_snapshot_helper_install_decision`,data:{packageName:a.packageName,versionCode:a.versionCode,installedVersionCode:a.installedVersionCode,artifactSha256:r.manifest.sha256,installedSha256:a.installedSha256,installed:a.installed,reason:a.reason}}),a}async function Dl(e){let{signal:t,adb:r,adbProvider:i,artifact:a,helperDeviceKey:o}=e,s=$r({adb:r,adbProvider:i,artifact:a,deviceKey:o,signal:t});try{let e=await m(`android_snapshot_helper_session_capture`,async()=>await zi(s),{packageName:a.manifest.packageName,version:a.manifest.version,timeoutMs:zn});if(e)return e}catch(e){if(t?.throwIfAborted(),Br(e))throw e;h({level:`warn`,phase:`android_snapshot_helper_session_fallback`,data:{reason:n(e).message}}),await fl(r,a.manifest.packageName)}return await m(`android_snapshot_helper_capture`,async()=>await Qr(s),{packageName:a.manifest.packageName,version:a.manifest.version,timeoutMs:zn,commandTimeoutMs:Bn})}function Ol(e,t,n){return{xml:e.xml,metadata:{backend:`android-helper`,helperVersion:t.manifest.version,helperApiVersion:e.metadata.helperApiVersion,helperTransport:e.metadata.transport,helperSessionReused:e.metadata.sessionReused,installReason:n,waitForIdleTimeoutMs:e.metadata.waitForIdleTimeoutMs,waitForIdleQuietMs:e.metadata.waitForIdleQuietMs,timeoutMs:e.metadata.timeoutMs,maxDepth:e.metadata.maxDepth,maxNodes:e.metadata.maxNodes,rootPresent:e.metadata.rootPresent,captureMode:e.metadata.captureMode,windowCount:e.metadata.windowCount,nodeCount:e.metadata.nodeCount,helperTruncated:e.metadata.truncated,elapsedMs:e.metadata.elapsedMs}}}async function kl(e){let{options:t,adb:n,adbProvider:r,artifact:i,helperDeviceKey:a,attempt:o}=e,s;try{let e=await El(t,n,r,i,a);e.installed&&await B(a),s=Ol(await Dl({signal:t.signal,adb:n,adbProvider:r,artifact:i,helperDeviceKey:a}),i,e.reason)}catch(e){return t.signal?.throwIfAborted(),{outcome:`captured`,capture:await Ml({error:e,helperDeviceKey:a,artifact:i,adb:n})}}let c=zc(s.xml,s.metadata,{foregroundAppPackage:t.appBundleId});if(c.outcome===`unusable`)return{outcome:`unusable`,decision:c.decision};let l=c.outcome===`system-surface-only`;return!l&&o>0&&h({phase:`android_snapshot_helper_content_recaptured`,data:{attempts:o+1,recoveredFromReason:e.previousContentReason}}),{outcome:`captured`,capture:{xml:s.xml,metadata:l?{...s.metadata,systemSurfaceOnly:!0}:s.metadata}}}async function Al(e){e?.throwIfAborted(),await g(250),e?.throwIfAborted()}async function jl(e){throw h({level:`error`,phase:`android_snapshot_helper_content_invalid`,data:{reason:e.contentRecovery.reason,failureReason:e.contentRecovery.failureReason,attempts:e.attempts,...e.contentRecovery.diagnostics}}),await dl({adb:e.adb,deviceKey:e.helperDeviceKey,packageName:e.artifact.manifest.packageName,signal:e.signal,cause:e.contentRecovery.failureReason}),new t(`COMMAND_FAILED`,e.contentRecovery.failureReason,{...e.contentRecovery.diagnostics,androidSnapshotHelperFailureReason:e.contentRecovery.reason,attempts:e.attempts,retriable:!0,hint:`Retry after the app UI stabilizes. If this persists, capture a screenshot and report the helper diagnostics; agent-device does not substitute a second snapshot engine.`})}async function Ml(e){let t=Nl(e.error);throw h({level:`error`,phase:`android_snapshot_helper_failed`,data:{reason:t}}),await B(e.helperDeviceKey),await fl(e.adb,e.artifact.manifest.packageName),Jn({deviceKey:e.helperDeviceKey,packageName:e.artifact.manifest.packageName,versionCode:e.artifact.manifest.versionCode}),Pl(e.error,t)}function Nl(e){let t=n(e),r=Rl(t.details?.helper);if(r&&r!==t.message)return`${t.message}: ${r}`;if(r)return r;let i=(typeof t.details?.stderr==`string`?t.details.stderr.trim():``).split(/\r?\n/).find(e=>e.trim());return i?`${t.message}: ${i}`:t.message}function Pl(e,r){let i=n(e),a=Fl(i);return new t(o(i.code),`Android snapshot helper failed: ${r}`,{...i.details,...Ll(i),androidSnapshotHelperFailureReason:r,...a?{androidCaptureFailureReason:a}:{},hint:Il(i,a)},e)}function Fl(e){return nt(e)}function Il(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 Ll(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 Rl(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 zl(e){if(e)return{artifact:e};let t=De(),r=w.join(Ee(),`android`,`snapshot-helper`,`dist`),i=w.join(r,`agent-device-android-snapshot-helper-${t}.manifest.json`);try{await y().files.access(i)}catch{return{}}try{let e=Vn(JSON.parse(await y().files.readText(i))),t=w.join(r,e.assetName??`agent-device-android-snapshot-helper-${e.version}.apk`);return await y().files.access(t),{artifact:{apkPath:t,manifest:e}}}catch(e){return{errorReason:n(e).message}}}function Bl(e){let n=e??`the bundled helper artifact was not found`;return new t(`COMMAND_FAILED`,`Android snapshot helper is unavailable: ${n}`,{androidSnapshotHelperFailureReason:n,hint:"Run `pnpm build:android` to build the helper dist for a source checkout — the runtime needs android/snapshot-helper/dist/agent-device-android-snapshot-helper-<version>.manifest.json and the .apk it references. Packaged installs ship these via the prepack script; if they are missing from a packaged install, reinstall agent-device."})}function Vl(e){return e.includes(` can-scroll-forward=`)||e.includes(` can-scroll-backward=`)}function Hl(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 Ul(e,t,n){if(e.size===0)return;let r=new Map;for(let[e,t]of n.sourceNodes.entries()){let i=n.nodes[e];i&&r.set(t,i)}for(let[n,i]of e){let e=t.sourceNodes[n];if(!e)continue;let a=r.get(e);a&&(i.hiddenContentAbove&&(a.hiddenContentAbove=!0),i.hiddenContentBelow&&(a.hiddenContentBelow=!0))}}async function Wl(e,t,n,r,i={}){let a=[0,150,350],o=null,s=null,c=await lu(e);for(let l of a){l>0&&await g(l);let a=await $l(e,t,n,r,c,i);if(o=a,a.reason===`ime_capture`)return a;s=a.ok?a:null}return s??o??{ok:!1,actual:null,reason:`text_mismatch`,targetInput:null,actualInput:null}}async function Gl(e,t,n,r={}){return Xl(await gl(e,r),t,n)}async function Kl(e,t,n,r){let i=await lu(e);return eu(await gl(e,r),t,n,i).targetInput}async function ql(e,t,n,r={}){try{return await Kl(e,t,n,r)}catch(e){return h({level:`warn`,phase:`android_fill_pre_action_target_capture_failed`,data:{error:e instanceof Error?e.message:String(e)}}),null}}function Z(e,n,r){if(r?.ok)return;let i=r?Jl(e,n,r):null;if(i)return i;throw new t(`COMMAND_FAILED`,Zl(r),Ql(e,r))}function Jl(e,t,n){let r=n.targetInput,i=n.actualInput;if(e.length===0||n.reason===`ime_capture`||!t||!r||!i||J(t)||J(r)||J(i)||!hu(t,r)||!hu(t,i)||t.text===n.actual)return null;let a=gu(t);return h({level:`warn`,phase:`android_fill_verification_unconfirmed`,data:{target:a}}),{verification:`unconfirmed`,requested:e,before:t.text,after:n.actual,target:a}}function Yl(e,t,n,r,i={}){let a=eu(e,t,n,i);return tu(a)?{ok:!1,actual:a.actualInput?.text??null,reason:`ime_capture`,targetInput:a.targetInput,actualInput:a.actualInput}:nu(a,r)??ru(a,r)}function Xl(e,t,n){return eu(e,t,n).targetInput?.text??null}function Zl(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 Ql(e,t){let n=ds(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 $l(e,t,n,r,i,a){return Yl(await gl(e,a),t,n,r,i)}function eu(e,t,n,r={}){let i={focusedEdit:null,editAtPoint:null,anyAtPoint:null};for(let a of Cc(e)){let e=cu(a,r);e&&uu(i,e,t,n)}return fu(i)}function tu(e){let{targetInput:t,actualInput:n}=e;return!t||!n||n===t?!1:n.inputMethodOwned&&!t.inputMethodOwned}function nu(e,t){let n=e.actualInput;if(!n||!mu(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 ru(e,t){let n=e.actualInput;return{ok:n!==null&&au(iu(n),t),actual:n?.text??null,reason:`text_mismatch`,targetInput:e.targetInput,actualInput:n}}function iu(e){return e.hintShowing?``:e.text??``}function au(e,t){if(e===t)return!0;if(t.length===0)return!1;let n=ou(e),r=ou(t);return!n||!r?!1:!!(n===r||su(n,r))}function ou(e){return e.replaceAll(/\s+/g,` `).trim()}function su(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 cu(e,t){if(!e.rect)return null;let n=e.text??``,r=Math.max(1,e.rect.width*e.rect.height);return{text:n||null,className:e.className,resourceId:e.resourceId,packageName:e.packageName,rect:e.rect,focused:e.focused??!1,password:e.password===!0,inputMethodOwned:p({packageName:e.packageName,resourceId:e.resourceId,activeInputMethodPackage:t.activeInputMethodPackage}),area:r,editText:pu(e.className??``),hintShowing:e.hintShowing===!0}}async function lu(e){try{return{activeInputMethodPackage:(await V(e)).inputMethodPackage}}catch(e){return h({level:`warn`,phase:`android_fill_verification_input_method_probe_failed`,data:{error:e instanceof Error?e.message:String(e)}}),{}}}function uu(e,t,n,r){let i=re(t.rect,n,r);if(i&&t.editText&&(e.editAtPoint=du(e.editAtPoint,t)),t.focused&&t.editText){e.focusedEdit=du(e.focusedEdit,t);return}i&&t.text&&(e.anyAtPoint=du(e.anyAtPoint,t))}function du(e,t){return e&&e.area<t.area?e:t}function fu(e){let t=e.editAtPoint??e.anyAtPoint;return{targetInput:t,actualInput:(e.focusedEdit?.text?e.focusedEdit:null)??t}}function pu(e){let t=e.toLowerCase();return t.includes(`edittext`)||t.includes(`textfield`)}function mu(e){return J(e)}function hu(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 gu(e){return{resourceId:e.resourceId,className:e.className,packageName:e.packageName,rect:e.rect}}async function _u(e,t){return await jt(t.stateDir),await Uo(t.stateDir,e.id,async()=>await yu(e,t))}function vu(e){let t=a(e).details?.hint;return{outcome:`helper-unavailable`,reason:n(e).message,...typeof t==`string`?{hint:t}:{}}}async function yu(e,t){let n=y().imeRecoveryMarkers,r=v(e),i=b(e),a=W(e),o;try{o=await So(i),await Eo({adb:r,adbProvider:i,artifact:o,deviceKey:a})}catch(e){return vu(e)}let{manifest:s}=o,c=await G(r);if(c===s.serviceComponent){let i=await n.write(t.stateDir,e.id),o=await K(r);return i&&q.add(a),{outcome:`settled`,activated:!1,alreadyActive:!0,...i?{}:{persistFailed:!0},previousIme:o,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName}}let l=await K(r);if(!await Io(r,c))return await Ro(r,l,e.id),x({level:`warn`,phase:`android_test_ime_persist_failed`,data:{device:e.id,previousIme:c}}),{outcome:`settled`,activated:!1,alreadyActive:!1,persistFailed:!0,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName};let u=(await n.read(t.stateDir)).includes(e.id);if(!await n.write(t.stateDir,e.id))return await Ro(r,l,e.id),x({level:`warn`,phase:`android_test_ime_marker_persist_failed`,data:{device:e.id,previousIme:c}}),{outcome:`settled`,activated:!1,alreadyActive:!1,persistFailed:!0,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName};await r([`shell`,`ime`,`enable`,s.serviceComponent],{allowFailure:!0,timeoutMs:1e4});let d=await r([`shell`,`ime`,`set`,s.serviceComponent],{allowFailure:!0,timeoutMs:1e4}),f=await G(r);return f===s.serviceComponent?(q.add(a),x({phase:`android_test_ime_activated`,data:{device:e.id,previousIme:c}}),{outcome:`settled`,activated:!0,alreadyActive:!1,previousIme:c,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName}):(q.delete(a),await Ro(r,l,e.id),u||await n.clear(t.stateDir,e.id),x({level:`warn`,phase:`android_test_ime_activate_failed`,data:{device:e.id,activeIme:f,stderr:d.stderr.trim()}}),{outcome:`settled`,activated:!1,alreadyActive:!1,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName})}function bu(e){return w.join(e,`android-test-ime-pending`)}function xu(e,t){return w.join(bu(e),encodeURIComponent(t))}async function Su(e,t){let r=y().files,i,a=!1;try{let n=bu(e);if(i=xu(e,t),await r.ensureDirectory(n),(await Tu(i))?.serial===t)return!0;let o={version:1,serial:t};if(await r.writeAtomicText(i,`${JSON.stringify(o)}\n`,384),a=!0,(await Tu(i))?.serial!==t)throw Error(`Android test IME marker read-back did not match the requested device.`);return!0}catch(o){return a&&i&&await r.remove(i,{force:!0}).catch(()=>{}),h({level:`debug`,phase:`android_test_ime_marker_write_failed`,data:{stateDir:e,serial:t,error:n(o).message}}),!1}}async function Cu(e,t){await y().files.remove(xu(e,t),{force:!0}).catch(()=>{})}async function wu(e){let t=y().files,n;try{n=await t.readDirectory(bu(e))}catch{return[]}let r=[];for(let t of n)try{let n=w.join(bu(e),t),i=await Tu(n);i&&xu(e,i.serial)===n&&r.push(i.serial)}catch{}return[...new Set(r)].sort()}async function Tu(e){try{return Eu(await y().files.readText(e))}catch{return}}function Eu(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 Du=new Pt(`utf-16le`);let Ou;async function ku(e,t){for(let n of[`AndroidManifest.xml`,`base/manifest/AndroidManifest.xml`]){let r=await Au(e,n,t);if(!r)continue;let i=ju(r);if(i)return i}return await Bu(e,t)}async function Au(e,t,n){try{let r=await be(`unzip`,[`-p`,e,t],{allowFailure:!0,binaryStdout:!0,signal:n});return r.exitCode!==0||!r.stdoutBuffer||r.stdoutBuffer.length===0?void 0:r.stdoutBuffer}catch{n?.throwIfAborted();return}}function ju(e){return e.subarray(0,Math.min(e.length,128)).toString(`utf8`).trimStart().startsWith(`<`)?Mu(e.toString(`utf8`)):Nu(e)}function Mu(e){return e.match(/<manifest\b[^>]*\bpackage\s*=\s*["']([^"']+)["']/i)?.[1]}function Nu(e){if(e.length<8||e.readUInt16LE(0)!==3)return;let t;for(let n=e.readUInt16LE(2);n+8<=e.length;){let r=e.readUInt16LE(n),i=e.readUInt16LE(n+2),a=e.readUInt32LE(n+4);if(a<=0||n+a>e.length)return;if(r===1)t=Fu(e.subarray(n,n+a));else if(r===258&&t){let r=Pu(e,n,i,t);if(r)return r}n+=a}}function Pu(e,t,n,r){if(n<36||t+n>e.length||r[e.readUInt32LE(t+20)]!==`manifest`)return;let i=e.readUInt16LE(t+24),a=e.readUInt16LE(t+26),o=e.readUInt16LE(t+28),s=t+i;for(let t=0;t<o;t+=1){let n=s+t*a;if(n+20>e.length)return;if(r[e.readUInt32LE(n+4)]!==`package`)continue;let i=e.readUInt32LE(n+8);if(i!==4294967295)return r[i];let o=e.readUInt8(n+15),c=e.readUInt32LE(n+16);return o===3?r[c]:void 0}}function Fu(e){if(e.length<28)return[];let t=e.readUInt32LE(8),n=e.readUInt32LE(16),r=e.readUInt32LE(20),i=!!(n&256),a=[];for(let n=0;n<t;n+=1){let t=28+n*4;if(t+4>e.length)return a;let o=r+e.readUInt32LE(t);a.push(i?Iu(e,o):Lu(e,o))}return a}function Iu(e,t){let[,n]=Ru(e,t),[r,i]=Ru(e,t+n),a=t+n+i;return e.subarray(a,a+r).toString(`utf8`)}function Lu(e,t){let[n,r]=zu(e,t),i=t+r;return Du.decode(e.subarray(i,i+n*2))}function Ru(e,t){let n=e.readUInt8(t);if(!(n&128))return[n,1];let r=e.readUInt8(t+1);return[(n&127)<<8|r,2]}function zu(e,t){let n=e.readUInt16LE(t);if(!(n&32768))return[n,2];let r=e.readUInt16LE(t+2);return[(n&32767)<<16|r,4]}async function Bu(e,t){t?.throwIfAborted();let n=await Vu();if(!n)return;let r=await be(n,[`dump`,`badging`,e],{allowFailure:!0,signal:t});if(r.exitCode===0)return r.stdout.match(/package:\s+name='([^']+)'/)?.[1]}async function Vu(){if(Ou!==void 0)return Ou??void 0;try{let e=y().files;for(let t of dt()){let n=w.join(t,`build-tools`);try{let t=(await e.readDirectory(n)).sort((e,t)=>t.localeCompare(e,void 0,{numeric:!0}));for(let r of t){let t=w.join(n,r,`aapt`);if(w.isAbsolute(t)&&await e.isExecutable(t))return Ou=t,t}}catch{}}}catch{}Ou=null}async function Hu(e,t){let n=e.kind===`url`&&Oe(e.url),r=await ke({source:e,isInstallablePath:(e,t)=>t.isFile()&&Uu(e),installableLabel:`Android installable (.apk or .aab)`,allowArchiveExtraction:e.kind!==`url`||n,signal:t?.signal});try{let e=t?.resolveIdentity===!1?{}:await Wu(r.installablePath,t?.signal);return{archivePath:r.archivePath,installablePath:r.installablePath,packageName:e.packageName,cleanup:r.cleanup}}catch(e){throw await r.cleanup(),e}}function Uu(e){let t=w.extname(e).toLowerCase();return t===`.apk`||t===`.aab`}async function Wu(e,t){let n=w.extname(e).toLowerCase();return n!==`.apk`&&n!==`.aab`?{}:{packageName:await ku(e,t)}}async function Gu(e,n,r,i={}){let a=typeof r.action==`string`&&r.action.trim()?r.action.trim():`${n}.TEST_PUSH`,o=[`shell`,`am`,`broadcast`,`-a`,a,`-p`,n],s=typeof r.receiver==`string`?r.receiver.trim():``;s&&o.push(`-n`,s);let c=r.extras;if(c!==void 0&&(typeof c!=`object`||!c||Array.isArray(c)))throw new t(`INVALID_ARGS`,`Android push payload extras must be an object`);let l=c??{},u=0;for(let[e,t]of Object.entries(l))e&&(Ku(o,e,t),u+=1);return await C(e,o,{signal:i.signal}),{action:a,extrasCount:u}}function Ku(e,n,r){if(typeof r==`string`){e.push(`--es`,n,r);return}if(typeof r==`boolean`){e.push(`--ez`,n,r?`true`:`false`);return}if(typeof r==`number`&&Number.isFinite(r)){if(Number.isInteger(r)){e.push(`--ei`,n,String(r));return}e.push(`--ef`,n,String(r));return}throw new t(`INVALID_ARGS`,`Unsupported Android broadcast extra type for "${n}". Use string, boolean, or number.`)}function Q(e){let t=e.replaceAll(`,`,``).match(/^-?\d+(?:\.\d+)?/);if(!t)return null;let n=Number(t[0]);return Number.isFinite(n)?n:null}function qu(e){let t=Qu(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 $u(n)}function Ju(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 Yu(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=>Zu({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 Xu(e){return Math.round(e*10)/10}function Zu(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:Xu(Math.max(...t.map(e=>e.durationNs))/1e6)}}function Qu(e){return[...new Set(e.filter(e=>Number.isFinite(e)))].sort((e,t)=>e-t)}function $u(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 ed(e,t,n){td(e,t);let r=dd(e),i=sd(e),a=rd(i,r,t),o=Date.parse(n),s=pd({frames:i,measuredAtMs:o,summary:r}),c=Ju({frames:i,frameDeadlineNs:a,summaryDroppedFrameCount:r?.droppedFrameCount}),l=r?.sampleWindowMs??s.sampleWindowMs??_d(i),u=id(r,i,c),d=od({droppedFrames:c,timing:s,measuredAtMs:o,summary:r});return{...u,sampleWindowMs:l,...ad(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 td(e,n){if(/no process found for:/i.test(e))throw new t(`COMMAND_FAILED`,`Android gfxinfo did not find a running process for ${n}`,{metric:`fps`,package:n,hint:`Run open <app> for this session again to ensure the Android app is active, then retry perf after the interaction you want to inspect.`})}function nd(e){throw new t(`COMMAND_FAILED`,`Failed to parse Android framestats output for ${e}`,{metric:`fps`,package:e,hint:`Retry perf after exercising the app screen. If the problem persists, capture adb shell dumpsys gfxinfo <package> framestats output for debugging.`})}function rd(e,n,r){let i=qu(e);if(!n&&e.length===0&&nd(r),n||i!==void 0)return i;throw new t(`COMMAND_FAILED`,`Failed to infer Android frame deadline from framestats output for ${r}`,{metric:`fps`,package:r,hint:`Retry perf after a longer interaction window so consecutive Android frame timestamps are available.`})}function id(e,t,n){let r=e?.totalFrameCount??t.length,i=e?.droppedFrameCount??n.length;return{totalFrameCount:r,droppedFrameCount:i,droppedFramePercent:e?.droppedFramePercent??(r>0?Mt(i/r*100):0)}}function ad(e){return{frameDeadlineMs:e===void 0?void 0:Xu(e/1e6),refreshRateHz:e===void 0?void 0:Xu(1e9/e)}}function od(e){let{droppedFrames:t,timing:n,measuredAtMs:r,summary:i}=e;if(t.length===0)return;let a=Yu({frames:t,windowStartNs:n.windowStartNs,measuredAtMs:r,uptimeMs:i?.uptimeMs});return a.length>0?a:void 0}function sd(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(cd(i)){n=new Map(i.map((e,t)=>[e,t]));continue}let a=ld(i,n);a&&t.push(a)}return t.sort((e,t)=>e.intendedVsyncNs-t.intendedVsyncNs)}function cd(e){return e.includes(`IntendedVsync`)&&e.includes(`FrameCompleted`)}function ld(e,t){if(!t||e.length<t.size)return;let n=ud(e,t,`Flags`),r=ud(e,t,`IntendedVsync`),i=ud(e,t,`FrameCompleted`);if(!(n!==0||r===null||i===null||r<=0||i<=r))return{intendedVsyncNs:r,frameCompletedNs:i,durationNs:i-r}}function ud(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 dd(e){let t=e.split(/\nProfile data in ms:\n/i)[0]??``,n=vd(t,`Total frames rendered`),r=t.match(/^\s*Janky frames:\s*([0-9][0-9,]*)\s*\(([0-9.]+)%\)/im);if(n===void 0||!r)return;let i=r[1],a=r[2];if(i===void 0||a===void 0)return;let o=Q(i)??void 0,s=Number(a);if(o===void 0||!Number.isFinite(s)||n<0)return;let c=vd(t,`Uptime`),l=vd(t,`Stats since`);return{droppedFramePercent:Mt(s),droppedFrameCount:o,totalFrameCount:n,sampleWindowMs:fd({uptimeMs:c,statsSinceNs:l}),uptimeMs:c,statsSinceNs:l}}function fd(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 pd(e){let{frames:t,measuredAtMs:n,summary:r}=e,i=md(t),a=r?.statsSinceNs,o=a??i.firstFrameNs,s=hd(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:gd({deviceBootWallClockMs:l,measuredAtMs:n,summaryStartNs:a,lastFrameNs:i.lastFrameNs}),timestampSource:`estimated-from-device-uptime`}}function md(e){return e.length===0?{}:{firstFrameNs:Math.min(...e.map(e=>e.intendedVsyncNs)),lastFrameNs:Math.max(...e.map(e=>e.frameCompletedNs))}}function hd(e,t){if(e!==void 0&&t!==void 0)return Math.max(0,Math.round((t-e)/1e6))}function gd(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 _d(e){if(e.length===0)return;let t=md(e);return hd(t.firstFrameNs,t.lastFrameNs)}function vd(e,t){let n=t.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`),r=e.match(RegExp(`^\\s*${n}:\\s*([0-9][0-9,]*)`,`im`));if(!r)return;let i=r[1];return i===void 0?void 0:Q(i)??void 0}async function yd(e,t,n={}){let r=v(e,n.adb);try{let i=ed((await r([`shell`,`dumpsys`,`gfxinfo`,t,`framestats`],{timeoutMs:15e3})).stdout,t,new Date().toISOString());return await bd(e,t,n),i}catch(e){throw xd(t,e)}}async function bd(e,t,n={}){let r=v(e,n.adb);try{await r([`shell`,`dumpsys`,`gfxinfo`,t,`reset`],{allowFailure:!0,timeoutMs:3e3})}catch{}}function xd(e,n){return n instanceof t?new t(n.code,n.message,{...n.details??{},metric:`fps`,package:e},n):new t(`COMMAND_FAILED`,`Failed to sample Android fps for ${e}`,{metric:`fps`,package:e},n)}async function Sd(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 Cd(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 Cd(e,t,n){try{let r=await yd(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 wd(e,t,n){let r=v(e,n.adb);await Ad(r,t),await Nd(r,t),await Md(r,t,n.files);let i=await kd(t.outPath,n.files);await Dd(r,t.remotePath);let a=Date.now(),o=Math.max(0,a-t.startedAt),s=await Sd(e,t,i,o,{adb:r});return{...t,action:`stop`,platform:`android`,state:`stopped`,stoppedAt:a,durationMs:o,sizeBytes:i,method:t.kind===`simpleperf`?Or:kr,artifact:{path:t.outPath,sizeBytes:i},summary:s,message:`Stopped Android ${t.kind} ${t.type} for ${t.packageName}`}}async function Td(e,t,n={}){let r=v(e,n.adb);try{t.state===`running`&&(await Ad(r,t),await Nd(r,t).catch(()=>{}))}finally{await Dd(r,t.remotePath)}}function Ed(e,t,n=jr){return`${n}/agent-device-${e.replaceAll(/[^A-Za-z0-9_.-]/g,`_`)}-${Date.now()}-${t}`}async function Dd(e,t){try{await e([`shell`,`rm -f ${_(t)}`],{allowFailure:!0,timeoutMs:Ar})}catch{}}async function Od(e,t,n=y().files){await n.ensureDirectory(w.dirname(e)),await n.writeBytes(e,Buffer.from(`${JSON.stringify(t,null,2)}\n`))}async function kd(e,n=y().files){try{return(await n.stat(e)).size}catch(n){throw new t(`COMMAND_FAILED`,`Profiler artifact was not written: ${e}`,{outPath:e,hint:`Retry the profiling command and check daemon logs if the artifact path is still missing.`},n)}}async function Ad(e,t){try{await e([`shell`,jd(t.profilerPid)],{timeoutMs:N})}catch(e){throw M(`stop`,t.kind,t.packageName,e)}}function jd(e){return[`pid=${_(e)}`,`kill -INT "$pid" 2>/dev/null || true`,`for i in 1 2 3 4 5 6 7 8 9 10; do kill -0 "$pid" 2>/dev/null || exit 0; sleep 0.2; done`,`kill -TERM "$pid" 2>/dev/null || true`,`for i in 1 2 3 4 5 6 7 8 9 10; do kill -0 "$pid" 2>/dev/null || exit 0; sleep 0.2; done`,`echo "profiler process did not stop after SIGTERM" >&2`,`exit 1`].join(`; `)}async function Md(e,n,r){await(r??y().files).ensureDirectory(w.dirname(n.outPath));try{await e([`pull`,n.remotePath,n.outPath],{timeoutMs:N})}catch(e){throw new t(`COMMAND_FAILED`,`Failed to pull Android ${n.kind} artifact for ${n.packageName}`,{package:n.packageName,tool:n.kind,remotePath:n.remotePath,outPath:n.outPath,hint:`Check that the profiling command ran long enough to create an artifact, then retry stop with the same session.`},e)}}async function Nd(e,n){let r;for(let t=0;t<12;t+=1){let t=await Pd(e,n.remotePath);if(t!==void 0&&t>0&&t===r)return;r=t,await g(250)}throw new t(`COMMAND_FAILED`,`Android ${n.kind} artifact is not ready to pull`,{package:n.packageName,tool:n.kind,remotePath:n.remotePath,hint:`The profiler stopped, but the remote artifact was missing, empty, or still changing. Retry stop with the same session or inspect the device-side artifact.`})}async function Pd(e,t){let n=_(t),r=await e([`shell`,`if [ -f ${n} ]; then stat -c %s ${n} 2>/dev/null || wc -c < ${n}; fi`],{allowFailure:!0,timeoutMs:Ar});if(r.exitCode!==0)return;let i=Number(r.stdout.trim().split(/\s+/)[0]);return Number.isFinite(i)?i:void 0}async function Fd(e,t,n,r={}){let i=v(e,r.adb),a=await Mr(i,t);await Nr(i,`perfetto`,t);let o=Ed(t,`app.perfetto-trace`,`/data/misc/perfetto-traces`),s;try{await bd(e,t,{adb:i}),s=await Ld(i,o,t)}catch(e){throw await Dd(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:kr,message:`Started Android Perfetto trace for ${t}`}}async function Id(e,t,n,r={}){return await wd(e,{...t,outPath:n},r)}async function Ld(e,n,r){try{let i=P((await e([`shell`,`perfetto`,`--background-wait`,`-o`,n,`-t`,`3600s`,`sched`,`freq`,`idle`,`am`,`wm`,`gfx`,`view`,`binder_driver`,`hal`,`dalvik`],{timeoutMs:N})).stdout);if(i)return i;throw new t(`COMMAND_FAILED`,`Android perfetto did not return a profiler pid`,{package:r,tool:`perfetto`,hint:`Retry perf trace start. If perfetto exits immediately, verify the device permits trace capture.`})}catch(e){throw M(`start`,`perfetto`,r,e)}}function Rd(e){let t=[];for(let n of s(e)){let e=n.match(/^([0-9]+(?:\.[0-9]+)?)%\s+(.+)$/);if(!e)continue;let r=Number(e[1]),i=e[2]?.trim();if(!Number.isFinite(r)||!i)continue;let a=i.split(/\s{2,}/).filter(Boolean);if(t.push({percentage:Mt(r),command:a[0],dso:a[1],symbol:a.slice(2).join(` `)||void 0}),t.length>=50)break}return t}async function zd(e,t,n,r={}){let i=v(e,r.adb),a=await Mr(i,t);await Nr(i,`simpleperf`,t);let o=Ed(t,`cpu.perf.data`),s;try{s=await Hd(i,a,o,t)}catch(e){throw await Dd(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:Or,message:`Started Android Simpleperf CPU profile for ${t}`}}async function Bd(e,t,n,r={}){return await wd(e,{...t,outPath:n},r)}async function Vd(e,t,n,r={}){let i=v(e,r.adb);await Nr(i,`simpleperf`,t.packageName);let a=await Gd(i,t),o=new Date().toISOString(),s=Rd(a.stdout),c=s.slice(0,10).map(e=>({symbol:e.symbol??`<unknown>`,binary:e.dso,selfSamplePercent:e.percentage}));await Od(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 kd(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:Or,message:`Wrote Android Simpleperf report for ${t.packageName}`}}async function Hd(e,n,r,i){try{let a=P((await e([`shell`,Ud(n,r)],{timeoutMs:N})).stdout);if(a)return a;throw new t(`COMMAND_FAILED`,`Android simpleperf did not return a profiler pid`,{package:i,tool:`simpleperf`,hint:`Retry perf. If simpleperf exits immediately, verify the app is profileable and the device permits native profiling.`})}catch(e){throw M(`start`,`simpleperf`,i,e)}}function Ud(e,t){return Wd([`simpleperf`,`record`,`-e`,`cpu-clock:u`,`-p`,e,`-o`,t,`--duration`,`3600`],`simpleperf`)}function Wd(e,t){let n=e.map(_).join(` `),r=`${jr}/agent-device-${t}-${Date.now()}.err`;return[`err=${_(r)}`,`(${n}) >/dev/null 2>"$err" & pid=$!`,`sleep 1`,`if kill -0 "$pid" 2>/dev/null; then rm -f "$err"; echo "$pid"; exit 0; fi`,`cat "$err" >&2`,`rm -f "$err"`,`exit 1`].join(`; `)}async function Gd(e,t){try{return await e([`shell`,`simpleperf`,`report`,`-i`,t.remotePath,`--stdio`,`--sort`,`comm,dso,symbol`],{timeoutMs:N})}catch(e){throw M(`report`,`simpleperf`,t.packageName,e)}}const Kd=15e3,qd=12e4;async function Jd(e,t,n={}){let r=v(e,n.adb);try{return Qd((await r([`shell`,`dumpsys`,`meminfo`,t],{timeoutMs:Kd})).stdout,t,new Date().toISOString())}catch(e){throw sf(`memory`,t,e)}}async function Yd(e,n,r,i={}){let a=v(e,i.adb),o=i.files??y().files,s=await $d(a,n),c=ef(n);await o.ensureDirectory(w.dirname(r));let l=await Xd(o,r);try{ye(await a([`shell`,`am`,`dumpheap`,n,c],{allowFailure:!0,timeoutMs:qd}),`Failed to capture Android heap dump for ${n}`,e=>({kind:`android-hprof`,package:n,pid:s,remotePath:c,hint:tf(e.stdout,e.stderr)}));let e=await a([`pull`,c,r],{allowFailure:!0,timeoutMs:qd});if(e.exitCode!==0)throw await Zd(o,r,l),S(`Failed to pull Android heap dump for ${n}`,e,{kind:`android-hprof`,package:n,pid:s,remotePath:c,path:r,hint:`Verify the daemon can write the requested --out path and retry. The heap dump stays on-device only until cleanup runs.`});let i=await o.stat(r).catch(()=>null);if(!i?.isFile||i.size<=0)throw await Zd(o,r,l),new t(`COMMAND_FAILED`,`Android heap dump artifact is missing or empty`,{kind:`android-hprof`,package:n,pid:s,path:r,remotePath:c,hint:`Retry with a writable --out path. If the file is still empty, inspect adb pull output with --debug.`});return{available:!0,kind:`android-hprof`,path:r,sizeBytes:i.size,measuredAt:new Date().toISOString(),method:`adb-shell-am-dumpheap`,packageName:n,pid:s,remotePath:c}}finally{await a([`shell`,`rm`,`-f`,c],{allowFailure:!0,timeoutMs:Kd}).catch(()=>{})}}async function Xd(e,t){return await e.stat(t).then(e=>e.isFile).catch(()=>!1)}async function Zd(e,t,n){n||await e.remove(t,{force:!0}).catch(()=>{})}function Qd(e,n,r){if(/no process found for:/i.test(e))throw new t(`COMMAND_FAILED`,`Android meminfo did not find a running process for ${n}`,{metric:`memory`,package:n,hint:`Run open <app> for this session again to ensure the Android app is active, then retry perf.`});let i=cf(e,`TOTAL PSS`)??lf(e);if(i===void 0)throw new t(`COMMAND_FAILED`,`Failed to parse Android meminfo output for ${n}`,{metric:`memory`,package:n,hint:`Retry perf after reopening the app session. If the problem persists, capture adb shell dumpsys meminfo output for debugging.`});return{totalPssKb:i,totalRssKb:cf(e,`TOTAL RSS`),measuredAt:r,method:`adb-shell-dumpsys-meminfo`,topConsumers:nf(e)}}async function $d(e,n){let r=await e([`shell`,`pidof`,n],{allowFailure:!0,timeoutMs:Kd}),i=r.stdout.trim().split(/\s+/).map(Number).find(e=>Number.isInteger(e)&&e>0);if(r.exitCode===0&&i!==void 0)return i;throw new t(`COMMAND_FAILED`,`No running Android process found for ${n}`,{kind:`android-hprof`,package:n,stdout:r.stdout,stderr:r.stderr,hint:`Run open <app> for this session again to ensure the Android app is active, then retry perf memory snapshot.`})}function ef(e){return`/data/local/tmp/agent-device-${e.replaceAll(/[^a-zA-Z0-9._-]/g,`_`)}-${Date.now()}.hprof`}function tf(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 nf(e){let t=e.split(`
|
|
14
|
-
`).flatMap(e=>
|
|
15
|
-
`)){let e=t.trim();if(!/^TOTAL\b(?!\s+PSS:)/.test(e))continue;let n=e.split(/\s+/).slice(1).find(e=>
|
|
16
|
-
`).filter(e=>e.trim().length>0).map(e=>({text:e,indent:e.length-e.trimStart().length})),e=>e.indent===0&&e.text.trim()===`Packages:`),e=>ff.exec(e.text)?.[1]===String(t)),e=>pf.test(e.text));if(!n)return;let r=new Map;for(let{text:e}of n){let t=mf.exec(e);t&&r.set(t[1],t[2]===`true`?`granted`:`not_granted`)}return r}function gf(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 _f(e,t,n){if(n!==`not_granted`)return`${n===`granted`?`${t} was granted before this revoke, and Android kills an app when a granted permission is revoked: if ${e} was running it is no longer.`:`Whether ${t} was granted before this revoke could not be read (adb did not report the acting user's runtime permission state), and Android kills an app when a granted permission is revoked: ${e} may no longer be running.`} Relaunch it with open ${e} --relaunch before the next interaction.`}async function vf(e){let n=await df(e);if(n!==void 0)return n;throw new t(`COMMAND_FAILED`,`Could not determine which Android user the session runs as, so no permission was changed.`,{deviceId:e.id,hint:`Check adb -s ${e.id} shell am get-current-user — if the device is still booting, retry once it reports a user. agent-device refuses to change permissions it cannot scope, because pm would silently apply them to user 0.`})}async function yf(e,t,n,r){let i=me(n),a=Sf(r?.permissionTarget,r?.permissionMode),o=await vf(e),s=[`--user`,String(o)];if(i===`grant`){await bf(e,t,a,s);return}let c=await uf(e,t,o),l=await xf(e,t,i,a,s),u=c?.get(l)??`unknown`,d=_f(t,l,u);return{permission:l,priorGrantState:u,...d?{warnings:[d]}:{}}}async function bf(e,t,n,r){n.kind===`notifications`?await wf(e,t,`grant`,n,r):n.type===`photos`?await Cf(e,t,`grant`,r):await C(e,[`shell`,`pm`,`grant`,...r,t,n.value])}async function xf(e,t,n,r,i){if(r.kind===`notifications`)return await wf(e,t,n,r,i),r.permission;let a;return r.type===`photos`?a=await Cf(e,t,`revoke`,i):(a=r.value,await C(e,[`shell`,`pm`,`revoke`,...i,t,a])),n===`reset`&&await Tf(e,t,a,i),a}function Sf(e,n){let r=ge(e);if(n?.trim())throw new t(`INVALID_ARGS`,`Permission mode is only supported for photos. Received: ${n}.`);if(r===`camera`)return{kind:`pm`,value:`android.permission.CAMERA`,type:`camera`};if(r===`microphone`)return{kind:`pm`,value:`android.permission.RECORD_AUDIO`,type:`microphone`};if(r===`photos`)return{kind:`pm`,value:`android.permission.READ_MEDIA_IMAGES`,type:`photos`};if(r===`contacts`)return{kind:`pm`,value:`android.permission.READ_CONTACTS`,type:`contacts`};if(r===`notifications`)return{kind:`notifications`,appOps:`POST_NOTIFICATION`,permission:`android.permission.POST_NOTIFICATIONS`};throw new t(`INVALID_ARGS`,`Unsupported permission target on Android: ${e}. Use camera|microphone|photos|contacts|notifications.`)}async function Cf(e,n,r,i){let a=await Ef(e),o=a!==null&&a>=33?[`android.permission.READ_MEDIA_IMAGES`,`android.permission.READ_EXTERNAL_STORAGE`]:[`android.permission.READ_EXTERNAL_STORAGE`,`android.permission.READ_MEDIA_IMAGES`],s=[];for(let t of o){let a=await C(e,[`shell`,`pm`,r,...i,n,t],{allowFailure:!0});if(a.exitCode===0)return t;s.push({permission:t,stderr:a.stderr,exitCode:a.exitCode})}throw new t(`COMMAND_FAILED`,`Failed to ${r} Android photos permission`,{appPackage:n,sdkInt:a,attempts:s})}async function wf(e,t,n,r,i){let a=n===`grant`?`allow`:n===`deny`?`deny`:`default`;n===`grant`?await C(e,[`shell`,`pm`,`grant`,...i,t,r.permission],{allowFailure:!0}):(await C(e,[`shell`,`pm`,`revoke`,...i,t,r.permission],{allowFailure:!0}),n===`reset`&&await Tf(e,t,r.permission,i)),await C(e,[`shell`,`appops`,`set`,...i,t,r.appOps,a])}async function Tf(e,t,n,r){for(let i of[`user-set`,`user-fixed`])await C(e,[`shell`,`pm`,`clear-permission-flags`,...r,t,n,i],{allowFailure:!0})}async function Ef(e){let t=await C(e,[`shell`,`getprop`,`ro.build.version.sdk`],{allowFailure:!0});if(t.exitCode!==0)return null;let n=Number.parseInt(t.stdout.trim(),10);return!Number.isFinite(n)||n<=0?null:n}function Df(e){let n=e.trim().toLowerCase();if(n===`light`)return`light`;if(n===`dark`)return`dark`;if(n===`toggle`)return`toggle`;throw new t(`INVALID_ARGS`,`Invalid appearance state: ${e}. Use light|dark|toggle.`)}function Of(e){let n=e.toLowerCase();if(n===`on`||n===`true`||n===`1`)return!0;if(n===`off`||n===`false`||n===`0`)return!1;throw new t(`INVALID_ARGS`,`Invalid setting state: ${e}`)}function kf(e){return e.map(e=>({args:e.args.join(` `),exitCode:e.exitCode,stderr:e.stderr.slice(0,400)}))}const Af=[`shell`,`cmd`,`connectivity`,`airplane-mode`];async function jf(e,n){let r=n?`enabled`:`disabled`;await Mf(e),await C(e,[...Af,n?`enable`:`disable`]);let i=await Nf(e);if(i!==r)throw new t(`COMMAND_FAILED`,`Android airplane mode reads ${i} after requesting ${r}.`,{deviceId:e.id,requested:r,airplaneMode:i});return{airplaneMode:i}}async function Mf(e){let{state:n,result:r}=await Pf(e);if(!n)throw r.exitCode!==0&&Xe(r.stdout,r.stderr)?new t(`UNSUPPORTED_OPERATION`,`The connectivity service on this Android build has no airplane-mode command, so nothing was changed.`,{deviceId:e.id,hint:`settings airplane needs cmd connectivity airplane-mode, which requires Android 11 (API 30) or newer. Use a newer device or emulator image.`,stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode}):S(`Failed to read Android airplane mode`,r,{deviceId:e.id})}async function Nf(e){let{state:t,result:n}=await Pf(e);if(t)return t;throw S(`Failed to read Android airplane mode after changing it`,n,{deviceId:e.id})}async function Pf(e){let t=await C(e,[...Af],{allowFailure:!0});return{state:t.exitCode===0?Ff(t.stdout):void 0,result:t}}function Ff(e){let t=e.trim().toLowerCase();if(t===`enabled`)return`enabled`;if(t===`disabled`)return`disabled`}const If=[`window_animation_scale`,`transition_animation_scale`,`animator_duration_scale`];async function Lf(e,n,r,i,a){switch(n.toLowerCase()){case`wifi`:{let t=Of(r);await C(e,[`shell`,`svc`,`wifi`,t?`enable`:`disable`]);return}case`airplane`:return await jf(e,Of(r));case`location`:{if(r.toLowerCase()===`set`){if(e.kind!==`emulator`)throw new t(`UNSUPPORTED_OPERATION`,`Android precise location coordinates are supported only on emulators.`,{deviceId:e.id,hint:`Use an Android emulator for adb emu geo fix, or configure location through device/provider tooling.`});let{latitude:n,longitude:r}=he(a);return await C(e,[`emu`,`geo`,`fix`,String(r),String(n)]),{latitude:n,longitude:r}}let n=Of(r)?`3`:`0`;await C(e,[`shell`,`settings`,`put`,`secure`,`location_mode`,n]);return}case`animations`:{let t=Of(r)?`1`:`0`;for(let n of If)await C(e,[`shell`,`settings`,`put`,`global`,n,t]);return{scale:t,keys:[...If]}}case`appearance`:{let t=await Hf(e,r);await C(e,[`shell`,`cmd`,`uimode`,`night`,t===`dark`?`yes`:`no`]);return}case`clear-app-state`:{if(r.toLowerCase()!==`clear`)throw new t(`INVALID_ARGS`,`settings clear-app-state only supports clear.`);if(!i)throw new t(`INVALID_ARGS`,`settings clear-app-state requires an app id or an active app session.`);let n=await gt(e,i);if(n.type===`intent`)throw new t(`INVALID_ARGS`,`settings clear-app-state requires a package name, not an intent.`);await C(e,[`shell`,`am`,`force-stop`,n.value],{allowFailure:!0});let a=await C(e,[`shell`,`pm`,`clear`,n.value],{allowFailure:!0});if(a.exitCode!==0||!/\bSuccess\b/i.test(a.stdout))throw new t(`COMMAND_FAILED`,`Failed to clear Android app data for ${n.value}`,{package:n.value,stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});return{package:n.value,cleared:!0}}case`fingerprint`:await zf(e,Rf(r));return;case`permission`:if(!i)throw new t(`INVALID_ARGS`,`permission setting requires an active app in session`);return await yf(e,i,r,a);default:throw new t(`INVALID_ARGS`,`Unsupported setting: ${n}`)}}function Rf(e){let n=e.trim().toLowerCase();if(n===`match`)return`match`;if(n===`nonmatch`)return`nonmatch`;throw new t(`INVALID_ARGS`,`Invalid fingerprint state: ${e}. Use match|nonmatch.`)}async function zf(e,n){let r=Bf(e,n),i=[];for(let t of r){let n=await C(e,t,{allowFailure:!0});if(n.exitCode===0)return;i.push({args:t,stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode})}let a=kf(i);throw i.length>0&&i.every(e=>Vf(e.stdout,e.stderr))?new t(`UNSUPPORTED_OPERATION`,`Android fingerprint simulation is not supported on this target/runtime.`,{deviceId:e.id,action:n,hint:`Use an Android emulator with biometric support, or a device/runtime that exposes cmd fingerprint.`,attempts:a}):new t(`COMMAND_FAILED`,`Failed to simulate Android fingerprint.`,{deviceId:e.id,action:n,attempts:a})}function Bf(e,t){let n=t===`match`?`1`:`9999`,r=[[`shell`,`cmd`,`fingerprint`,`touch`,n],[`shell`,`cmd`,`fingerprint`,`finger`,n]];return e.kind===`emulator`&&r.push([`emu`,`finger`,`touch`,n]),r}function Vf(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 Hf(e,n){let r=Df(n);if(r!==`toggle`)return r;let i=await C(e,[`shell`,`cmd`,`uimode`,`night`],{allowFailure:!0});if(i.exitCode!==0)throw S(`Failed to read current Android appearance`,i);let a=Uf(i.stdout,i.stderr);if(!a)throw new t(`COMMAND_FAILED`,`Unable to determine current Android appearance for toggle`,{stdout:i.stdout,stderr:i.stderr});return a===`auto`?`dark`:a===`dark`?`light`:`dark`}function Uf(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 Wf=Buffer.from([137,80,78,71,13,10,26,10]);async function Gf(e,t,n={}){if(n.stabilize===!1){await Jf(e,t);return}await Kf(e);try{await g(1e3),await Jf(e,t)}finally{await qf(e).catch(()=>{})}}async function Kf(e){let t=t=>C(e,[`shell`,t],{allowFailure:!0});await t(`settings put global sysui_demo_allowed 1`);let n=e=>t(`am broadcast -a com.android.systemui.demo -e command ${e}`);await n(`clock -e hhmm 0941`),await n(`notifications -e visible false`)}async function qf(e){await C(e,[`shell`,`am broadcast -a com.android.systemui.demo -e command exit`],{allowFailure:!0})}async function Jf(e,n){let r=await C(e,[`exec-out`,`screencap`,`-p`],{binaryStdout:!0});if(!r.stdoutBuffer)throw new t(`COMMAND_FAILED`,`Failed to capture screenshot`);let i=r.stdoutBuffer.indexOf(Wf);if(i<0)throw new t(`COMMAND_FAILED`,`Screenshot data does not contain a valid PNG header`);let a=Yf(r.stdoutBuffer,i);if(!a)throw new t(`COMMAND_FAILED`,`Screenshot data does not contain a complete PNG payload`);await y().files.writeBytes(n,r.stdoutBuffer.subarray(i,a))}function Yf(e,t){let n=t+Wf.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 Xf(e,t,n=0){let r=Re(e);if(r){await r({action:`type`,text:t,delayMs:n}),$(`type`,`provider-native`,t);return}let i=await tp(e,`type`,t);if(i.backend===`test-ime`){await np(e,i.packageName,t,n);return}if(n>0&&Array.from(t).length>1){await ip(e,{action:`type`,text:t,chunkSize:1,delayMs:n});return}await ip(e,{action:`type`,text:t,chunkSize:8,delayMs:0})}async function Zf(e,t,n,r,i=0,a={}){let o=await ql(e,t,n,a),s=Re(e);if(s)return await s({action:`fill`,target:{x:t,y:n},text:r,delayMs:i}),$(`fill`,`provider-native`,r),Z(r,o,await Wl(e,t,n,r,a));let c=null;for(let s of Qf(i)){await Ca(e,t,n);let i=await tp(e,`fill`,r);if(i.backend===`test-ime`)return Z(r,o,await rp(e,i.packageName,t,n,r,o,a));let l=await $f(e,{x:t,y:n,text:r,beforeTarget:o,attempt:s},a);if(c=l,l.ok)return;if(l.reason===`ime_capture`)return Z(r,o,l);let u=Jl(r,o,l);if(u)return u}return Z(r,o,c)}function Qf(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 $f(e,t,n){let{x:r,y:i,text:a,beforeTarget:o,attempt:s}=t;return await op(e,ep(a,o,s)),await ip(e,{action:`fill`,text:a,chunkSize:s.chunkSize,delayMs:s.inputDelayMs}),Wl(e,r,i,a,n)}function ep(e,t,n){let r=Array.from(e).length;return hp(r>0?r+n.clearPadding:t?.text?Array.from(t.text).length+n.clearPadding:n.maxClear,n.minClear,n.maxClear)}async function tp(e,t,n){if(Ho(e))return{backend:`test-ime`,packageName:(await So(b(e))).manifest.packageName};let r=await sp(e,t),i=r?.inputMethodPackage;return Oo(i)?{backend:`test-ime`,packageName:i}:(lp(n),cp(r,t),{backend:`adb-shell`})}async function np(e,t,n,r){let i=v(e),a=n.split(`
|
|
17
|
-
`);for(let[n,o]of a.entries()){let s=r>0?mp(o,1):[o];for(let[e,o]of s.entries())o&&await ko(i,t,o),r>0&&(e+1<s.length||n+1<a.length)&&await g(r);n+1<a.length&&await C(e,[`shell`,`input`,`keyevent`,`ENTER`])}$(`type`,`test-ime`,n)}async function rp(e,t,n,r,i,a,o){let s=v(e),c=null;for(let l=0;l<2;l+=1){l>0&&await Ca(e,n,r),await Ao(s,t),i&&await ko(s,t,i);let u=await Wl(e,n,r,i,o);if(c=u,u.ok||Jl(i,a,u))break}return $(`fill`,`test-ime`,i),c}async function ip(e,t){let n=t.text.split(`
|
|
18
|
-
`);for(let[
|
|
19
|
-
|
|
10
|
+
`).replace(/\n$/,``),n=t.match(/^clipboard text:\s*(.*)$/i);return n?n[1]??``:t.trim().toLowerCase()===`null`?``:t}const Eo=`com.callstack.agentdevice.imehelper`,Do=`android-ime-helper-v1`;async function Oo(e){return e.imeHelperArtifact??await ko()}async function ko(){return await x().resolveHelperArtifact({helperDirName:`ime-helper`,manifestFileName:e=>`agent-device-android-ime-helper-${e}.manifest.json`,parseManifest:Ao,unavailableMessage:`Android test IME text entry requires the bundled Android IME helper artifact, but it was not found or could not be read`})}const H=`IME helper`;function Ao(e){if(!e||typeof e!=`object`||Array.isArray(e))throw new t(`INVALID_ARGS`,`Android IME helper manifest must be an object.`);let n=e;return{name:O(n.name,`name`,`android-ime-helper`,H),version:bn(n.version,`version`,H),assetName:bn(n.assetName,`assetName`,H),sha256:xn(n.sha256,H),packageName:O(n.packageName,`packageName`,Eo,H),versionCode:yn(n.versionCode,`versionCode`,H),serviceComponent:O(n.serviceComponent,`serviceComponent`,`com.callstack.agentdevice.imehelper/.TestInputMethodService`,H),broadcastProtocol:O(n.broadcastProtocol,`broadcastProtocol`,Do,H)}}const jo=new Set;async function Mo(e){return await x().ensureHelperInstalled({cache:jo,installTimeoutMs:3e4,helperLabel:`Android IME helper`},e)}function No(){jo.clear()}function U(e){return`${e.platform}:${e.id}`}function Po(e){return e===Eo}async function Fo(e,t,n){await Lo(e,t,`com.callstack.agentdevice.imehelper.ACTION_INPUT_TEXT_B64`,{text:Buffer.from(n,`utf8`).toString(`base64`)})}async function Io(e,t){await Lo(e,t,`com.callstack.agentdevice.imehelper.ACTION_CLEAR_TEXT`,{})}async function Lo(e,t,n,r){let i=[`am`,`broadcast`,`-p`,t,`-a`,n];i.push(`--es`,`protocol`,Do);for(let[e,t]of Object.entries(r))i.push(`--es`,e,t);let a=await b(e,i,{allowFailure:!0,timeoutMs:1e4});if(a.exitCode!==0)throw w(`Android IME helper broadcast failed`,a,{action:n,packageName:t})}const Ro=`agent_device_ime_helper_previous_ime`,zo=`secure`,Bo=`default_input_method`,Vo={previousIme:Ro,defaultInputMethod:Bo};async function W(e){let t=await b(e,[`settings`,`get`,zo,Bo],{allowFailure:!0,timeoutMs:5e3});return Ko(t.exitCode===0?t.stdout:``)}async function G(e){let t=await b(e,[`settings`,`get`,zo,Ro],{allowFailure:!0,timeoutMs:5e3});return Ko(t.exitCode===0?t.stdout:``)||void 0}async function Ho(e,t){return(await b(e,[`settings`,`put`,zo,Ro,t],{allowFailure:!0,timeoutMs:5e3})).exitCode===0&&await G(e)===t}async function Uo(e){await b(e,[`settings`,`delete`,zo,Ro],{allowFailure:!0,timeoutMs:5e3})}async function Wo(e,t,r){try{(t?await Ho(e,t):await Go(e))||S({level:`warn`,phase:`android_test_ime_record_rollback_failed`,data:{device:r,hadPriorRecord:t!==void 0}})}catch(e){S({level:`warn`,phase:`android_test_ime_record_rollback_failed`,data:{device:r,hadPriorRecord:t!==void 0,error:n(e).message}})}}async function Go(e){return await Uo(e),await G(e)===void 0}function Ko(e){let t=e.trim();return!t||t===`null`?``:t}const K=new Set,qo=new Map;function Jo(e){return K.has(U(e))}function Yo(e,t,n){return jt(qo,`${e}:${t}`,n)}function Xo(){K.clear()}function Zo(e,t){let n=U(e);t?K.add(n):K.delete(n)}async function Qo(e,t){return await Yo(t.stateDir,e.id,async()=>{let n=U(e);if(!K.has(n))return{restored:!1,reason:`no-record`};K.delete(n);let r=await es(y(e),e);return $o(r.reason)&&await x().imeRecoveryMarkers.clear(t.stateDir,e.id),r})}function $o(e){return e===`ok`||e===`helper-not-active`||e===`no-record`}async function es(e,t){let n=t.id;if(K.has(U(t)))return{restored:!1,reason:`owned-by-live-session`};let r=await G(e);if(!r)return{restored:!1,reason:`no-record`};let i=await W(e);if(i!==`com.callstack.agentdevice.imehelper/.TestInputMethodService`)return S({level:`debug`,phase:`android_test_ime_restore_skipped`,data:{device:n,currentIme:i,previousIme:r}}),{restored:!1,previousIme:r,reason:`helper-not-active`};await b(e,[`ime`,`set`,r],{allowFailure:!0,timeoutMs:1e4});let a=await W(e);return a===r?(await Uo(e).catch(()=>{}),S({phase:`android_test_ime_restored`,data:{device:n,previousIme:r}}),{restored:!0,previousIme:r,reason:`ok`}):(S({level:`warn`,phase:`android_test_ime_restore_failed`,data:{device:n,previousIme:r,afterIme:a}}),{restored:!1,previousIme:r,reason:`set-failed`})}async function ts(e){let t=x().imeRecoveryMarkers,r=await t.read(e.stateDir);if(r.length===0)return;let i;try{i=new Set(await e.listSerials())}catch(e){S({level:`debug`,phase:`android_test_ime_startup_scan_failed`,data:{error:n(e).message}});return}for(let a of r){if(!i.has(a))continue;let r={platform:`android`,id:a,name:a,kind:a.startsWith(`emulator-`)?`emulator`:`device`,booted:!0};try{await Yo(e.stateDir,a,async()=>{let n=await es(y(r),r);n.restored&&S({level:`warn`,phase:`android_test_ime_orphan_restored`,data:{device:a,previousIme:n.previousIme}}),$o(n.reason)&&await t.clear(e.stateDir,a)})}catch(e){S({level:`debug`,phase:`android_test_ime_orphan_restore_failed`,data:{device:a,error:n(e).message}})}}}async function ns(){x();try{return(await Ae(qe([`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 rs=2e3;async function is(e=x().environment,t=x().files){let n=e.ANDROID_HOME||e.ANDROID_SDK_ROOT,r=await gs(n,t),i=await At(`adb`,[`version`]);return i?fs({license:r,sdkRoot:n,versionLine:i}):hs(n,r)}async function as(e,t){if(e.platform!==`android`)return[];let n=y(e,t.transportOverrides.androidAdb),r=[];return t.shouldProbeMetro&&r.push(await ds(n,e.id,t.metroPort)),r.push(await os(n,e)),r}async function os(e,t){try{let n=await W(e),r=Jo(t);return n===await ss()&&!r?await cs(e,t,n):ls(t,n,r)}catch(e){return us(e)}}async function ss(){try{return(await ko()).manifest.serviceComponent}catch{return}}async function cs(e,t,n){let r=(await b(e,[`settings`,`get`,`secure`,Vo.previousIme],{allowFailure:!0,timeoutMs:rs})).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 ls(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 us(e){let t=n(e);return{id:`android-test-ime`,status:`warn`,summary:`Could not inspect the Android test IME helper state.`,hint:t.message,evidence:{code:t.code}}}async function ds(e,t,r){try{let n=await e([`reverse`,`--list`],{allowFailure:!0,timeoutMs:rs}),i=`tcp:${r} tcp:${r}`,a=n.stdout.includes(i);return{id:`android-reverse`,status:a?`pass`:`warn`,summary:a?`Android adb reverse exists for Metro port ${r}.`:`Android adb reverse is missing for Metro port ${r}.`,command:a?void 0:`adb -s ${t} reverse tcp:${r} tcp:${r}`,evidence:{stdout:n.stdout.trim()}}}catch(e){let t=n(e);return{id:`android-reverse`,status:`warn`,summary:`Could not inspect Android adb reverse mappings.`,hint:t.message,evidence:{code:t.code}}}}function fs(e){return{id:`toolchain`,status:ps(e),summary:e.versionLine?`Android toolchain: ${e.versionLine}; ${ms(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 ps(e){return e.versionLine&&e.sdkRoot&&e.license!==`missing`?`pass`:`info`}function ms(e){return e?`ANDROID_HOME/ANDROID_SDK_ROOT set`:`ANDROID_HOME unset`}function hs(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 gs(e,t){if(!e)return`unknown`;try{return await t.access(E.join(e,`licenses`,`android-sdk-license`)),`accepted`}catch{return`missing`}}function _s(e,t){if(!t)return{expected:e,actual:null,failureReason:`text_mismatch`,targetInput:null,actualInput:null};let n=xs(t),r={failureReason:t.reason??`text_mismatch`,targetInput:ys(t.targetInput),actualInput:ys(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:vs(e.text):!1}function vs(e){return e?Array.from(e).every(bs):!1}function ys(e){if(!e)return null;let t=q(e);return{...e,text:t?null:e.text,...t?{textRedacted:!0}:{}}}function bs(e){return e===`•`||e===`*`||e===`●`}function xs(e){return e.masked===!0||q(e.targetInput)||q(e.actualInput)}const Ss=new WeakMap;function Cs(e,t){return t&&Ss.set(e,t),e}function ws(e){return Ss.get(e)}function Ts(e){return e.clickable}function Es(e){return e.focusable||e.focused===!0}function J(e){return Ts(e)||Es(e)}function Ds(e){let t=e.trim();return t?/^[\w.]+:id\/[\w.-]+$/i.test(t):!1}function Os(e,t){return{raw:e,...t?{effectiveRect:t}:{}}}function ks(e,t,n){if(!e)return;let r=Ms(e);return t&&(r=js(r,t)),n&&(r=js(r,n)),r}function As(e){return{...e.raw,...e.effectiveRect?{rect:e.effectiveRect}:{rect:void 0},hittable:e.raw.hittable===!0&&ie(e.effectiveRect)?!0:void 0}}function js(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 Ms(e){return{x:e.x,y:e.y,width:Math.max(0,e.width),height:Math.max(0,e.height)}}function Ns(e,t){let n=new Set;return Ps(e,n,t),Is(e,n,t),n}function Ps(e,t,n){for(let r of e.children){if(n?.check(`work`),r.visibleToUser===!1){t.add(r);continue}Ps(r,t,n)}}function Fs(e,t,n){return n?.check(`work`),e.children.filter(e=>!t.has(e)&&e.visibleToUser!==!1)}function Is(e,t,n){let r=Fs(e,t,n).filter(Rs);if(r.length<2)return;let i=r.filter(e=>zs(e)&&Bs(e));if(i.length===0)return;let a=Ls(i);for(let r of Fs(e,t,n))n?.check(`work`),zs(r)&&(Bs(r)&&(a===void 0||r.windowLayer===a)||t.add(r))}function Ls(e){let t=e.map(e=>e.windowLayer).filter(e=>e!==void 0);return t.length>0?Math.max(...t):void 0}function Rs(e){return e.windowIndex!==void 0||e.windowType!==void 0}function zs(e){return e.windowType===1}function Bs(e){return e.windowActive===!0||e.windowFocused===!0}function Vs(e,t,n,r,i){let a=new Set(e.sourceNodes),o=Us(t,i),s=Hs(o,n,Ws(o,a,i),i);if(!s)return{nodes:[],sourceNodes:[]};let c=new Set(Us([s],i)),l=[];for(let[t,n]of e.sourceNodes.entries())i.check(`work`),c.has(n)&&l.push(t);if(l.length===0)return{nodes:[],sourceNodes:[]};let u=1/0;for(let t of l)i.check(`work`),u=Math.min(u,e.nodes[t]?.depth??0);let d=[];for(let t of l)i.check(`work`),(e.nodes[t]?.depth??0)-u<=r&&d.push(t);return i.consume(d.length),{nodes:oe(d.map(t=>e.nodes[t]),u),sourceNodes:d.map(t=>e.sourceNodes[t])}}function Hs(e,t,n,r){for(let i of e)if(r.check(`work`),se(i,t)&&n.has(i))return i;return null}function Us(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 Ws(e,t,n){let r=new Set;for(let i=e.length-1;i>=0;--i){n.check(`work`);let a=e[i];if(t.has(a)){r.add(a);continue}for(let e of a.children)if(n.check(`work`),r.has(e)){r.add(a);break}}return r}function Gs(e,t,n,r,i){if(e.visibleToUser===!1)return!1;let a=Ks(e);return t.interactiveOnly?qs(e,a,n,r,i):a.isStructural||a.isVisual?Xs(e,a,r):!0}function Ks(e){let t=Qs(e.type),n=!!(e.label&&e.label.trim().length>0),r=!!(e.identifier&&e.identifier.trim().length>0);return{type:t,hasMeaningfulText:n&&!Ds(e.label??``),hasMeaningfulId:r&&!Ds(e.identifier??``),isStructural:$s(t),isVisual:t===`imageview`||t===`imagebutton`}}function qs(e,t,n,r,i){return Ys(e)?!1:J(e)||ae(t.type)&&r?!0:Js(t,n,r,i)}function Js(e,t,n,r){return!e.hasMeaningfulText&&!e.hasMeaningfulId||e.isVisual||e.isStructural&&!r&&!t?!1:t||n||r}function Ys(e){return!!(e.rect&&(e.rect.width<=0||e.rect.height<=0))}function Xs(e,t,n){return J(e)||t.hasMeaningfulText||t.hasMeaningfulId?!0:n}function Zs(e){if(!e)return!1;let t=Qs(e);return t.includes(`recyclerview`)||t.includes(`listview`)||t.includes(`gridview`)}function Qs(e){return e?e.toLowerCase():``}function $s(e){let t=e.split(`.`).pop()??e;return t.includes(`layout`)||t===`viewgroup`||t===`view`}function ec(e,t,n,r){return{...Os(e,t),...n?{clipsDescendants:!0}:{},...r?{windowRect:r}:{}}}const tc=`ANDROID_SNAPSHOT_PRESENTATION_FAILED`;var Y=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 nc(e){return e instanceof Y?e.code===tc:!!(e&&typeof e==`object`&&e.code===tc)}var rc=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()+cc()}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 ic(e,t){return new rc(e??{},t)}function ac(e,t,n){let r=new Map;for(let i of e){n.check(`regular-invariant`);let e=oc(i,r,t),a=i.effectiveRect;if(!a||!ie(a)){if(As(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&&!sc(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 oc(e,t,n){let r=e.raw.parentIndex;return r===void 0?e.windowRect??n:t.get(r)??e.windowRect??n}function sc(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 cc(){return 250}function lc(e,t,n){let r=n.depth??1/0,i=ce(n.scope),a=Dc(e),o=ic(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=bc(e,o),s.hidden=n.raw?new Set:Ns(e,o);for(let t of e.children)if(dc(s,t,0),s.truncated)break;n.raw||ac(s.presentationNodes,s.viewport,o);let t=s.nodes,a=new Map(s.sourceNodes.map((e,t)=>[e,t])),{nodes:c,sourceNodes:l}=i?Vs(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:uc(s.sourceNodes)},analysis:s.analysis};return s.truncated?{...u,truncated:!0}:u}catch(e){throw nc(e)&&(e.analysis??=s.analysis),e}}function uc(e){let t=new Map,n=new Map;for(let[r,i]of e.entries()){let e=ws(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`),fc(e,t,n))return;let l=t.windowRect??s??e.viewport,u=pc(e,t,c,l),d=mc(e,t,r,i,a,o,u,l),f=i||J(t),p=a||Zs(t.type),ee=hc(e,t,u,c);gc(e,t,n,d,f,p,o||it(t.identifier),l,ee)}function fc(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 pc(e,t,n,r){return e.options.raw?t.rect:ks(t.rect,r,n)}function mc(e,t,n,r,i,a,o,s){return!e.options.raw&&!Gs(t,e.options,r,Cc(e,t),i)?n:_c(e,t,n,a||it(t.identifier),o,s)}function hc(e,t,n,r){return e.options.raw||!xc(t)?r:n}function gc(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 _c(e,t,n,r,i,a){let o=e.nodes.length;return e.sourceNodes.push(t),yc(e,t,vc(e,t,n,r),i,a),o}function vc(e,t,n,r){return{index:e.nodes.length,type:t.type??void 0,label:t.label??void 0,value:t.value??void 0,identifier:t.identifier??void 0,bundleId:t.packageName??void 0,rect:t.rect,enabled:t.enabled,focused:t.focused,selected:t.selected,editable:t.editable,password:t.password,hintShowing:t.hintShowing,selectionStart:t.selectionStart,selectionEnd:t.selectionEnd,visibleToUser:t.visibleToUser,hittable:J(t)||void 0,depth:Sc(e.nodes,n),parentIndex:n,...wc(t,e.hidden),...r?{systemChrome:!0}:{}}}function yc(e,t,n,r,i){let a=ec(n,r,!e.options.raw&&xc(t),i);e.presentationNodes.push(a),e.nodes.push(e.options.raw?a.raw:As(a))}function bc(e,t){let n=[],r=[...e.children];for(;r.length>0;){t.check(`work`);let e=r.pop();ie(e.windowRect)&&n.push(e.windowRect),r.push(...e.children)}return re(n)??void 0}function xc(e){return e.scrollable===!0&&ae(e.type)}function Sc(e,t){return t===void 0?0:(e[t]?.depth??-1)+1}function Cc(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)||Cc(e,n)))return e.interactiveDescendantMemo.set(t,!0),!0;return e.interactiveDescendantMemo.set(t,!1),!1}function wc(e,t){return Tc(e,t)?{...e.canScrollBackward?{hiddenContentAbove:!0}:{},...e.canScrollForward?{hiddenContentBelow:!0}:{}}:{}}function Tc(e,t){if(!e.scrollable||!ae(e.type)||`${e.type??``}`.toLowerCase().includes(`horizontalscrollview`))return!1;let n=Ec(e,t);return!(n&&n.horizontal>n.vertical&&n.horizontal>16)}function Ec(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 Dc(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 Oc(){let e=[],t=()=>e.at(-1)===!0;return{open(n,r){let i=t()||it(n);return r||e.push(i),i},close(){e.pop()}}}function*kc(e){let t=/<node\b[^>]*>|<\/node>/g,n=Oc(),r=t.exec(e);for(;r;){let i=r[0];if(i.startsWith(`</node`))n.close();else{let e=Ac(i);yield n.open(e.resourceId,i.endsWith(`/>`))?{...e,systemChrome:!0}:e}r=t.exec(e)}}function Ac(e){let t=jc(e),n=Mt(t.bounds);return{...t,...n?{rect:n}:{}}}function jc(e){let t=Mc(e),n=e=>Bc(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=Mt(n(t));return r===void 0?{}:{[e]:r}},s=(e,t)=>{let n=r(t);return n===void 0?{}:{[e]:n}};return{text:n(`text`),desc:n(`content-desc`),resourceId:n(`resource-id`),packageName:n(`package`),className:n(`class`),bounds:n(`bounds`),clickable:r(`clickable`),enabled:r(`enabled`),focusable:r(`focusable`),focused:r(`focused`),password:r(`password`),...s(`editable`,`editable`),...a(`selectionStart`,`selection-start`),...a(`selectionEnd`,`selection-end`),...s(`hintShowing`,`hint-showing`),...s(`visibleToUser`,`visible-to-user`),...s(`selected`,`selected`),...a(`drawingOrder`,`drawing-order`),...s(`scrollable`,`scrollable`),...s(`canScrollForward`,`can-scroll-forward`),...s(`canScrollBackward`,`can-scroll-backward`),...a(`windowIndex`,`window-index`),...a(`windowType`,`window-type`),...a(`windowLayer`,`window-layer`),...s(`windowActive`,`window-active`),...s(`windowFocused`,`window-focused`),...o(`windowRect`,`window-bounds`)}}function Mc(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=Nc(e,i,r);if(!n)break;t.set(n.name,n.value),i=n.nextCursor}return t}function Nc(e,t,n){if(t=Fc(e,t,n),t>=n||Ic(e[t]))return;let r=t;t=Pc(e,t,n);let i=e.slice(r,t);if(t=Fc(e,t,n),!i||e[t]!==`=`)return;t=Fc(e,t+1,n);let a=e[t];if(!Lc(a))return;let o=t+1,s=e.indexOf(a,o);if(!(s<0||s>=n))return{name:i,value:Nt(e.slice(o,s)),nextCursor:s+1}}function Pc(e,t,n){for(;t<n&&!zc(e[t]??``);)t+=1;return t}function Fc(e,t,n){for(;t<n&&Rc(e[t]??``);)t+=1;return t}function Ic(e){return e===`/`||e===`>`}function Lc(e){return e===`"`||e===`'`}function Rc(e){return e===` `||e===`
|
|
12
|
+
`||e===`\r`||e===` `}function zc(e){return e===`=`||e===`/`||e===`>`||Rc(e)}function Bc(e,t){return e.get(t)??null}function Vc(e){let t={type:null,label:null,value:null,identifier:null,packageName:null,clickable:!1,focusable:!1,depth:-1,children:[]},n=[t],r=/<node\b[^>]*>|<\/node>/g,i=r.exec(e);for(;i;){let t=i[0];if(t.startsWith(`</node`)){n.length>1&&n.pop(),i=r.exec(e);continue}let a=Ac(t),o=n.at(-1),s=Hc(a,o.depth+1,o);o.children.push(s),t.endsWith(`/>`)||n.push(s),i=r.exec(e)}return t}function Hc(e,t,n){return Cs({type:e.className,label:e.text||e.desc,value:e.text,identifier:e.resourceId,packageName:e.packageName,rect:e.rect,enabled:e.enabled,focused:e.focused,selected:e.selected,editable:e.editable,password:e.password,hintShowing:e.hintShowing,selectionStart:e.selectionStart,selectionEnd:e.selectionEnd,visibleToUser:e.visibleToUser,clickable:e.clickable===!0,focusable:e.focusable===!0,scrollable:e.scrollable,canScrollForward:e.canScrollForward,canScrollBackward:e.canScrollBackward,windowIndex:e.windowIndex,windowType:e.windowType,windowLayer:e.windowLayer,windowActive:e.windowActive,windowFocused:e.windowFocused,windowRect:e.windowRect,depth:t,parentIndex:void 0,children:[]},e.drawingOrder===void 0?void 0:{parent:n,order:e.drawingOrder})}function Uc(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 Wc=new Set([`android`,`com.android.systemui`]);function Gc(e,t,n={}){if(t.backend!==`android-helper`)return{outcome:`ok`};let r=nl(e,n.foregroundAppPackage);return Jc(r,t)?Kc(r,t,`empty-helper-output`,`Android snapshot helper returned no accessibility nodes`):el(r)?{outcome:`ok`}:qc(r)?{outcome:`system-surface-only`}:Yc(r)?{outcome:`ok`}:Xc(r)?Kc(r,t,`content-poor-app-window`,`Android snapshot helper returned insufficient foreground app content`):Zc(r)||Qc(r,t)?Kc(r,t,`content-poor-app-window`,`Android snapshot helper returned insufficient application window content`):$c(r)?Kc(r,t,`system-window-only`,`Android snapshot helper returned only non-application windows`):{outcome:`ok`}}function Kc(e,t,n,r){return{outcome:`unusable`,decision:tl(e,t,n,r)}}function qc(e){return e.windowRootCount>0&&e.applicationWindowRootCount===0&&e.activeSystemSurfaceMeaningfulNodeCount>=3}function Jc(e,t){return e.nodeCount===0||t.nodeCount===0||t.rootPresent===!1}function Yc(e){return Xc(e)&&e.inputMethodMeaningfulNodeCount>=2}function Xc(e){let t=e.foregroundAppMeaningfulNodeCount;return t===void 0?!1:t===0?e.applicationMeaningfulNodeCount<2:t<2&&e.meaningfulNodeCount>t}function Zc(e){return e.foregroundAppMeaningfulNodeCount===void 0&&e.applicationWindowRootCount>0&&e.applicationMeaningfulNodeCount<2}function Qc(e,t){return e.foregroundAppMeaningfulNodeCount===void 0&&e.windowRootCount===0&&(t.windowCount??0)>1&&e.nonSystemMeaningfulNodeCount<2}function $c(e){return e.windowRootCount>0&&e.applicationWindowRootCount===0||e.windowRootCount===0&&e.nodeCount>0&&e.systemUiNodeCount===e.nodeCount}function el(e){return e.hasAlertButtonIdentifier&&e.hasAlertContentIdentifier}function tl(e,t,n,r){return{reason:n,failureReason:r,diagnostics:gl(e,t)}}function nl(e,t){let n=rl(t);for(let t of kc(e))il(n,t);return dl(n)}function rl(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 il(e,t){e.nodeCount+=1,hl(t.packageName)&&(e.systemUiNodeCount+=1),t.visibleToUser!==!1&&al(e,t.resourceId),ol(e,t),sl(e,t)}function al(e,t){let n=Zt(t);n===`button`&&(e.hasAlertButtonIdentifier=!0),n===`content`&&(e.hasAlertContentIdentifier=!0)}function ol(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 sl(e,t){fl(t)&&(e.meaningfulNodeCount+=1,cl(e,t),ul(e,t))}function cl(e,t){e.currentWindowType===1&&!ml(t.packageName)&&(e.applicationMeaningfulNodeCount+=1),ll(e)&&!rt(t)&&(e.activeSystemSurfaceMeaningfulNodeCount+=1)}function ll(e){return e.currentWindowType!==void 0&&e.currentWindowType!==1&&e.currentWindowActiveOrFocused===!0}function ul(e,t){ml(t.packageName)||(e.nonSystemMeaningfulNodeCount+=1),p({packageName:t.packageName,resourceId:t.resourceId})&&(e.inputMethodMeaningfulNodeCount+=1),e.foregroundAppPackage!==void 0&&t.packageName===e.foregroundAppPackage&&(e.foregroundAppMeaningfulNodeCount=(e.foregroundAppMeaningfulNodeCount??0)+1)}function 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 fl(e){return e.visibleToUser===!1?!1:pl(e.text)||pl(e.desc)||pl(e.resourceId)}function pl(e){return e!==null&&e.trim()!==``}function ml(e){return e===null||Wc.has(e)}function hl(e){return e!==null&&Wc.has(e)}function gl(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 _l(e){let t=await z(e.deviceKey,{resetRuntime:!0,signal:e.signal,cause:e.cause});e.signal?.throwIfAborted(),t||await vl(e.adb,e.packageName)}async function vl(e,t){await ni({adb:e,packageName:t}),await g(150),h({level:`debug`,phase:`android_snapshot_helper_runtime_reset`,data:{packageName:t}})}const yl=Symbol(`androidSnapshotCaptureEvidence`);function bl(e,t){return Object.defineProperty(e,yl,{value:t}),e}function xl(e){let t={...e,backend:`android`,producer:`android-uiautomator`},n=e[yl];return te(t,n.clickability),n.occlusionContext&&l(t,n.occlusionContext),t}async function Sl(e,t={}){let n=C(e,t.helperAdb).exec;return(await Al(e,t,n)).xml}async function Cl(e,t={}){let n=C(e,t.helperAdb).exec,r=await Al(e,t,n),i=r.xml,a=Vc(i),o=El(r.metadata,a),s={...t,androidPresentation:{...t.androidPresentation,deadlineAtMs:t.androidPresentation?.deadlineAtMs??Date.now()+250}};try{let e=lc(a,void 0,s),n=Tl(e.truncated,r.metadata);t.interactiveOnly&&t.includeHiddenContentHints!==!1&&kl({options:s,tree:a,xml:i,interactiveSnapshot:e});let{sourceNodes:c,occlusionContext:l,...u}=e;return bl({...u,...Ol(n),androidSnapshot:o,quality:{state:`healthy`,backend:`android-helper`}},{clickability:Uc(e),occlusionContext:l})}catch(e){if(!nc(e))throw e;return wl({failure:e,androidSnapshot:o})}}function wl(e){return bl({nodes:[],truncated:!0,analysis:e.failure.analysis??{rawNodeCount:0,maxDepth:0},androidSnapshot:{...e.androidSnapshot,presentationFailure:{phase:e.failure.details.phase,workUnits:e.failure.details.workUnits,...e.failure.details.maxWorkUnits===void 0?{}:{maxWorkUnits:e.failure.details.maxWorkUnits}}},quality:{state:`sparse`,backend:`android-helper`,reason:e.failure.message,reasonCode:e.failure.qualityReasonCode}},{clickability:{kind:`exact`,provider:`android-helper`,clickableByNodeIndex:new Map}})}function Tl(e,t){return e===!0||t.helperTruncated===!0||e}function El(e,t){return Dl(t)===!1?{...e,occlusionScanUnavailable:!0}:e}function Dl(e){let t=[...e.children];if(t.length!==0){for(;t.length>0;){let e=t.pop();if(ws(e)!==void 0)return!0;t.push(...e.children)}return!1}}function Ol(e){return e===!0?{truncated:!0}:{}}function kl(e){if(Jl(e.interactiveSnapshot.nodes).size>0||ql(e.xml))return;let t=lc(e.tree,void 0,{...e.options,interactiveOnly:!1});Yl(_e(o(t.nodes)),t,e.interactiveSnapshot)}async function Al(e,t,n){let r=C(e,t.helperAdb),i=await m(`android_snapshot_helper_artifact_resolution`,async()=>await Gl(t.helperArtifact??r.snapshotHelperArtifact));if(i.artifact)return await jl(e,t,n,i.artifact);throw h({level:`error`,phase:`android_snapshot_helper_unavailable`,data:{reason:i.errorReason??`artifact_not_found`}}),Kl(i.errorReason)}async function jl(e,t,n,r){let i=Hr(e),a=C(e,t.helperAdb),o=t.helperSessionScope!==`daemon-session`;try{let e;for(let o=0;;o+=1){o>0&&await Il(t.signal);let s=await Fl({options:t,adb:n,adbProvider:a,artifact:r,helperDeviceKey:i,attempt:o,previousContentReason:e});if(s.outcome===`captured`)return s.capture;if(o+1>=3)return await Ll({contentRecovery:s.decision,attempts:o+1,helperDeviceKey:i,artifact:r,adb:n,signal:t.signal});e=s.decision.reason}}finally{o&&await z(i)}}async function Ml(e,t,n,r,i){let a=await m(`android_snapshot_helper_install`,async()=>await ir({adb:t,adbProvider:n,artifact:r,deviceKey:i,installPolicy:e.helperInstallPolicy,timeoutMs:3e4,signal:e.signal}),{packageName:r.manifest.packageName,versionCode:r.manifest.versionCode,installPolicy:e.helperInstallPolicy??`missing-or-outdated`});return h({phase:`android_snapshot_helper_install_decision`,data:{packageName:a.packageName,versionCode:a.versionCode,installedVersionCode:a.installedVersionCode,artifactSha256:r.manifest.sha256,installedSha256:a.installedSha256,installed:a.installed,reason:a.reason}}),a}async function Nl(e){let{signal:t,adb:r,adbProvider:i,artifact:a,helperDeviceKey:o}=e,s=ai({adb:r,adbProvider:i,artifact:a,deviceKey:o,signal:t});try{let e=await m(`android_snapshot_helper_session_capture`,async()=>await Gi(s),{packageName:a.manifest.packageName,version:a.manifest.version,timeoutMs:Wn});if(e)return e}catch(e){if(t?.throwIfAborted(),Kr(e))throw e;h({level:`warn`,phase:`android_snapshot_helper_session_fallback`,data:{reason:n(e).message}}),await vl(r,a.manifest.packageName)}return await m(`android_snapshot_helper_capture`,async()=>await ii(s),{packageName:a.manifest.packageName,version:a.manifest.version,timeoutMs:Wn,commandTimeoutMs:Gn})}function Pl(e,t,n){return{xml:e.xml,metadata:{backend:`android-helper`,helperVersion:t.manifest.version,helperApiVersion:e.metadata.helperApiVersion,helperTransport:e.metadata.transport,helperSessionReused:e.metadata.sessionReused,installReason:n,waitForIdleTimeoutMs:e.metadata.waitForIdleTimeoutMs,waitForIdleQuietMs:e.metadata.waitForIdleQuietMs,timeoutMs:e.metadata.timeoutMs,maxDepth:e.metadata.maxDepth,maxNodes:e.metadata.maxNodes,rootPresent:e.metadata.rootPresent,captureMode:e.metadata.captureMode,windowCount:e.metadata.windowCount,nodeCount:e.metadata.nodeCount,helperTruncated:e.metadata.truncated,elapsedMs:e.metadata.elapsedMs}}}async function Fl(e){let{options:t,adb:n,adbProvider:r,artifact:i,helperDeviceKey:a,attempt:o}=e,s;try{let e=await Ml(t,n,r,i,a);e.installed&&await z(a),s=Pl(await Nl({signal:t.signal,adb:n,adbProvider:r,artifact:i,helperDeviceKey:a}),i,e.reason)}catch(e){return t.signal?.throwIfAborted(),{outcome:`captured`,capture:await Rl({error:e,helperDeviceKey:a,artifact:i,adb:n})}}let c=Gc(s.xml,s.metadata,{foregroundAppPackage:t.appBundleId});if(c.outcome===`unusable`)return{outcome:`unusable`,decision:c.decision};let l=c.outcome===`system-surface-only`;return!l&&o>0&&h({phase:`android_snapshot_helper_content_recaptured`,data:{attempts:o+1,recoveredFromReason:e.previousContentReason}}),{outcome:`captured`,capture:{xml:s.xml,metadata:l?{...s.metadata,systemSurfaceOnly:!0}:s.metadata}}}async function Il(e){e?.throwIfAborted(),await g(250),e?.throwIfAborted()}async function Ll(e){throw h({level:`error`,phase:`android_snapshot_helper_content_invalid`,data:{reason:e.contentRecovery.reason,failureReason:e.contentRecovery.failureReason,attempts:e.attempts,...e.contentRecovery.diagnostics}}),await _l({adb:e.adb,deviceKey:e.helperDeviceKey,packageName:e.artifact.manifest.packageName,signal:e.signal,cause:e.contentRecovery.failureReason}),new t(`COMMAND_FAILED`,e.contentRecovery.failureReason,{...e.contentRecovery.diagnostics,androidSnapshotHelperFailureReason:e.contentRecovery.reason,attempts:e.attempts,retriable:!0,hint:`Retry after the app UI stabilizes. If this persists, capture a screenshot and report the helper diagnostics; agent-device does not substitute a second snapshot engine.`})}async function Rl(e){let t=zl(e.error);throw h({level:`error`,phase:`android_snapshot_helper_failed`,data:{reason:t}}),await z(e.helperDeviceKey),await vl(e.adb,e.artifact.manifest.packageName),$n({deviceKey:e.helperDeviceKey,packageName:e.artifact.manifest.packageName,versionCode:e.artifact.manifest.versionCode}),Bl(e.error,t)}function zl(e){let t=n(e),r=Wl(t.details?.helper);if(r&&r!==t.message)return`${t.message}: ${r}`;if(r)return r;let i=(typeof t.details?.stderr==`string`?t.details.stderr.trim():``).split(/\r?\n/).find(e=>e.trim());return i?`${t.message}: ${i}`:t.message}function Bl(e,r){let a=n(e),o=Vl(a);return new t(i(a.code),`Android snapshot helper failed: ${r}`,{...a.details,...Ul(a),androidSnapshotHelperFailureReason:r,...o?{androidCaptureFailureReason:o}:{},hint:Hl(a,o)},e)}function Vl(e){return at(e)}function Hl(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 Ul(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 Wl(e){if(!e||typeof e!=`object`||!(`message`in e))return;let t=String(e.message).trim();return t&&t!==`null`?t:void 0}async function Gl(e){if(e)return{artifact:e};let t=De(),r=E.join(Ee(),`android`,`snapshot-helper`,`dist`),i=E.join(r,`agent-device-android-snapshot-helper-${t}.manifest.json`);try{await x().files.access(i)}catch{return{}}try{let e=Kn(JSON.parse(await x().files.readText(i))),t=E.join(r,e.assetName??`agent-device-android-snapshot-helper-${e.version}.apk`);return await x().files.access(t),{artifact:{apkPath:t,manifest:e}}}catch(e){return{errorReason:n(e).message}}}function Kl(e){let n=e??`the bundled helper artifact was not found`;return new t(`COMMAND_FAILED`,`Android snapshot helper is unavailable: ${n}`,{androidSnapshotHelperFailureReason:n,hint:"Run `pnpm build:android` to build the helper dist for a source checkout — the runtime needs android/snapshot-helper/dist/agent-device-android-snapshot-helper-<version>.manifest.json and the .apk it references. Packaged installs ship these via the prepack script; if they are missing from a packaged install, reinstall agent-device."})}function ql(e){return e.includes(` can-scroll-forward=`)||e.includes(` can-scroll-backward=`)}function Jl(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 Yl(e,t,n){if(e.size===0)return;let r=new Map;for(let[e,t]of n.sourceNodes.entries()){let i=n.nodes[e];i&&r.set(t,i)}for(let[n,i]of e){let e=t.sourceNodes[n];if(!e)continue;let a=r.get(e);a&&(i.hiddenContentAbove&&(a.hiddenContentAbove=!0),i.hiddenContentBelow&&(a.hiddenContentBelow=!0))}}async function Xl(e,t,n,r,i={}){let a=[0,150,350],o=null,s=null,c=await hu(e);for(let l of a){l>0&&await g(l);let a=await au(e,t,n,r,c,i);if(o=a,a.reason===`ime_capture`)return a;s=a.ok?a:null}return s??o??{ok:!1,actual:null,reason:`text_mismatch`,targetInput:null,actualInput:null}}async function Zl(e,t,n,r={}){return nu(await Sl(e,r),t,n)}async function Ql(e,t,n,r){let i=await hu(e);return ou(await Sl(e,r),t,n,i).targetInput}async function $l(e,t,n,r={}){try{return await Ql(e,t,n,r)}catch(e){return h({level:`warn`,phase:`android_fill_pre_action_target_capture_failed`,data:{error:e instanceof Error?e.message:String(e)}}),null}}function X(e,n,r){if(r?.ok)return;let i=r?eu(e,n,r):null;if(i)return i;throw new t(`COMMAND_FAILED`,ru(r),iu(e,r))}function eu(e,t,n){let r=n.targetInput,i=n.actualInput;if(e.length===0||n.reason===`ime_capture`||!t||!r||!i||q(t)||q(r)||q(i)||!xu(t,r)||!xu(t,i)||t.text===n.actual)return null;let a=Su(t);return h({level:`warn`,phase:`android_fill_verification_unconfirmed`,data:{target:a}}),{verification:`unconfirmed`,requested:e,before:t.text,after:n.actual,target:a}}function tu(e,t,n,r,i={}){let a=ou(e,t,n,i);return su(a)?{ok:!1,actual:a.actualInput?.text??null,reason:`ime_capture`,targetInput:a.targetInput,actualInput:a.actualInput}:cu(a,r)??lu(a,r)}function nu(e,t,n){return ou(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 iu(e,t){let n=_s(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 au(e,t,n,r,i,a){return tu(await Sl(e,a),t,n,r,i)}function ou(e,t,n,r={}){let i={focusedEdit:null,editAtPoint:null,anyAtPoint:null};for(let a of kc(e)){let e=mu(a,r);e&&gu(i,e,t,n)}return vu(i)}function su(e){let{targetInput:t,actualInput:n}=e;return!t||!n||n===t?!1:n.inputMethodOwned&&!t.inputMethodOwned}function cu(e,t){let n=e.actualInput;if(!n||!bu(n))return null;let r=n.text??null,i=Array.from(uu(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 lu(e,t){let n=e.actualInput;return{ok:n!==null&&du(uu(n),t),actual:n?.text??null,reason:`text_mismatch`,targetInput:e.targetInput,actualInput:n}}function uu(e){return e.hintShowing?``:e.text??``}function du(e,t){if(e===t)return!0;if(t.length===0)return!1;let n=fu(e),r=fu(t);return!n||!r?!1:!!(n===r||pu(n,r))}function fu(e){return e.replaceAll(/\s+/g,` `).trim()}function pu(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 mu(e,t){if(!e.rect)return null;let n=e.text??``,r=Math.max(1,e.rect.width*e.rect.height);return{text:n||null,className:e.className,resourceId:e.resourceId,packageName:e.packageName,rect:e.rect,focused:e.focused??!1,password:e.password===!0,inputMethodOwned:p({packageName:e.packageName,resourceId:e.resourceId,activeInputMethodPackage:t.activeInputMethodPackage}),area:r,editText:yu(e.className??``),hintShowing:e.hintShowing===!0}}async function hu(e){try{return{activeInputMethodPackage:(await oo(e)).inputMethodPackage}}catch(e){return h({level:`warn`,phase:`android_fill_verification_input_method_probe_failed`,data:{error:e instanceof Error?e.message:String(e)}}),{}}}function gu(e,t,n,r){let i=ne(t.rect,n,r);if(i&&t.editText&&(e.editAtPoint=_u(e.editAtPoint,t)),t.focused&&t.editText){e.focusedEdit=_u(e.focusedEdit,t);return}i&&t.text&&(e.anyAtPoint=_u(e.anyAtPoint,t))}function _u(e,t){return e&&e.area<t.area?e:t}function vu(e){let t=e.editAtPoint??e.anyAtPoint;return{targetInput:t,actualInput:(e.focusedEdit?.text?e.focusedEdit:null)??t}}function yu(e){let t=e.toLowerCase();return t.includes(`edittext`)||t.includes(`textfield`)}function bu(e){return q(e)}function xu(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 Su(e){return{resourceId:e.resourceId,className:e.className,packageName:e.packageName,rect:e.rect}}async function Cu(e,t){return await Pt(t.stateDir),await Yo(t.stateDir,e.id,async()=>await Tu(e,t))}function wu(e){let t=r(e).details?.hint;return{outcome:`helper-unavailable`,reason:n(e).message,...typeof t==`string`?{hint:t}:{}}}async function Tu(e,t){let n=x().imeRecoveryMarkers,r=y(e),i=C(e),a=U(e),o;try{o=await Oo(i),await Mo({adb:r,adbProvider:i,artifact:o,deviceKey:a})}catch(e){return wu(e)}let{manifest:s}=o,c=await W(r);if(c===s.serviceComponent){let i=await n.write(t.stateDir,e.id),o=await G(r);return i&&K.add(a),{outcome:`settled`,activated:!1,alreadyActive:!0,...i?{}:{persistFailed:!0},previousIme:o,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName}}let l=await G(r);if(!await Ho(r,c))return await Wo(r,l,e.id),S({level:`warn`,phase:`android_test_ime_persist_failed`,data:{device:e.id,previousIme:c}}),{outcome:`settled`,activated:!1,alreadyActive:!1,persistFailed:!0,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName};let u=(await n.read(t.stateDir)).includes(e.id);if(!await n.write(t.stateDir,e.id))return await Wo(r,l,e.id),S({level:`warn`,phase:`android_test_ime_marker_persist_failed`,data:{device:e.id,previousIme:c}}),{outcome:`settled`,activated:!1,alreadyActive:!1,persistFailed:!0,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName};await b(r,[`ime`,`enable`,s.serviceComponent],{allowFailure:!0,timeoutMs:1e4});let d=await b(r,[`ime`,`set`,s.serviceComponent],{allowFailure:!0,timeoutMs:1e4}),f=await W(r);return f===s.serviceComponent?(K.add(a),S({phase:`android_test_ime_activated`,data:{device:e.id,previousIme:c}}),{outcome:`settled`,activated:!0,alreadyActive:!1,previousIme:c,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName}):(K.delete(a),await Wo(r,l,e.id),u||await n.clear(t.stateDir,e.id),S({level:`warn`,phase:`android_test_ime_activate_failed`,data:{device:e.id,activeIme:f,stderr:d.stderr.trim()}}),{outcome:`settled`,activated:!1,alreadyActive:!1,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName})}function Eu(e){return E.join(e,`android-test-ime-pending`)}function Du(e,t){return E.join(Eu(e),encodeURIComponent(t))}async function Ou(e,t){let r=x().files,i,a=!1;try{let n=Eu(e);if(i=Du(e,t),await r.ensureDirectory(n),(await ju(i))?.serial===t)return!0;let o={version:1,serial:t};if(await r.writeAtomicText(i,`${JSON.stringify(o)}\n`,384),a=!0,(await ju(i))?.serial!==t)throw Error(`Android test IME marker read-back did not match the requested device.`);return!0}catch(o){return a&&i&&await r.remove(i,{force:!0}).catch(()=>{}),h({level:`debug`,phase:`android_test_ime_marker_write_failed`,data:{stateDir:e,serial:t,error:n(o).message}}),!1}}async function ku(e,t){await x().files.remove(Du(e,t),{force:!0}).catch(()=>{})}async function Au(e){let t=x().files,n;try{n=await t.readDirectory(Eu(e))}catch{return[]}let r=[];for(let t of n)try{let n=E.join(Eu(e),t),i=await ju(n);i&&Du(e,i.serial)===n&&r.push(i.serial)}catch{}return[...new Set(r)].sort()}async function ju(e){try{return Mu(await x().files.readText(e))}catch{return}}function Mu(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 Nu=new Lt(`utf-16le`);let Pu;async function Fu(e,t){for(let n of[`AndroidManifest.xml`,`base/manifest/AndroidManifest.xml`]){let r=await Iu(e,n,t);if(!r)continue;let i=Lu(r);if(i)return i}return await Ku(e,t)}async function Iu(e,t,n){try{let r=await be(`unzip`,[`-p`,e,t],{allowFailure:!0,binaryStdout:!0,signal:n});return r.exitCode!==0||!r.stdoutBuffer||r.stdoutBuffer.length===0?void 0:r.stdoutBuffer}catch{n?.throwIfAborted();return}}function Lu(e){return e.subarray(0,Math.min(e.length,128)).toString(`utf8`).trimStart().startsWith(`<`)?Ru(e.toString(`utf8`)):zu(e)}function Ru(e){return e.match(/<manifest\b[^>]*\bpackage\s*=\s*["']([^"']+)["']/i)?.[1]}function zu(e){if(e.length<8||e.readUInt16LE(0)!==3)return;let t;for(let n=e.readUInt16LE(2);n+8<=e.length;){let r=e.readUInt16LE(n),i=e.readUInt16LE(n+2),a=e.readUInt32LE(n+4);if(a<=0||n+a>e.length)return;if(r===1)t=Vu(e.subarray(n,n+a));else if(r===258&&t){let r=Bu(e,n,i,t);if(r)return r}n+=a}}function Bu(e,t,n,r){if(n<36||t+n>e.length||r[e.readUInt32LE(t+20)]!==`manifest`)return;let i=e.readUInt16LE(t+24),a=e.readUInt16LE(t+26),o=e.readUInt16LE(t+28),s=t+i;for(let t=0;t<o;t+=1){let n=s+t*a;if(n+20>e.length)return;if(r[e.readUInt32LE(n+4)]!==`package`)continue;let i=e.readUInt32LE(n+8);if(i!==4294967295)return r[i];let o=e.readUInt8(n+15),c=e.readUInt32LE(n+16);return o===3?r[c]:void 0}}function Vu(e){if(e.length<28)return[];let t=e.readUInt32LE(8),n=e.readUInt32LE(16),r=e.readUInt32LE(20),i=!!(n&256),a=[];for(let n=0;n<t;n+=1){let t=28+n*4;if(t+4>e.length)return a;let o=r+e.readUInt32LE(t);a.push(i?Hu(e,o):Uu(e,o))}return a}function Hu(e,t){let[,n]=Wu(e,t),[r,i]=Wu(e,t+n),a=t+n+i;return e.subarray(a,a+r).toString(`utf8`)}function Uu(e,t){let[n,r]=Gu(e,t),i=t+r;return Nu.decode(e.subarray(i,i+n*2))}function Wu(e,t){let n=e.readUInt8(t);if(!(n&128))return[n,1];let r=e.readUInt8(t+1);return[(n&127)<<8|r,2]}function Gu(e,t){let n=e.readUInt16LE(t);if(!(n&32768))return[n,2];let r=e.readUInt16LE(t+2);return[(n&32767)<<16|r,4]}async function Ku(e,t){t?.throwIfAborted();let n=await qu();if(!n)return;let r=await be(n,[`dump`,`badging`,e],{allowFailure:!0,signal:t});if(r.exitCode===0)return r.stdout.match(/package:\s+name='([^']+)'/)?.[1]}async function qu(){if(Pu!==void 0)return Pu??void 0;try{let e=x().files;for(let t of mt()){let n=E.join(t,`build-tools`);try{let t=(await e.readDirectory(n)).sort((e,t)=>t.localeCompare(e,void 0,{numeric:!0}));for(let r of t){let t=E.join(n,r,`aapt`);if(E.isAbsolute(t)&&await e.isExecutable(t))return Pu=t,t}}catch{}}}catch{}Pu=null}async function Ju(e,t){let n=e.kind===`url`&&Oe(e.url),r=await ke({source:e,isInstallablePath:(e,t)=>t.isFile()&&Yu(e),installableLabel:`Android installable (.apk or .aab)`,allowArchiveExtraction:e.kind!==`url`||n,signal:t?.signal});try{let e=t?.resolveIdentity===!1?{}:await Xu(r.installablePath,t?.signal);return{archivePath:r.archivePath,installablePath:r.installablePath,packageName:e.packageName,cleanup:r.cleanup}}catch(e){throw await r.cleanup(),e}}function Yu(e){let t=E.extname(e).toLowerCase();return t===`.apk`||t===`.aab`}async function Xu(e,t){let n=E.extname(e).toLowerCase();return n!==`.apk`&&n!==`.aab`?{}:{packageName:await Fu(e,t)}}async function Zu(e,n,r,i={}){let a=typeof r.action==`string`&&r.action.trim()?r.action.trim():`${n}.TEST_PUSH`,o=[`am`,`broadcast`,`-a`,a,`-p`,n],s=typeof r.receiver==`string`?r.receiver.trim():``;s&&o.push(`-n`,s);let c=r.extras;if(c!==void 0&&(typeof c!=`object`||!c||Array.isArray(c)))throw new t(`INVALID_ARGS`,`Android push payload extras must be an object`);let l=c??{},u=0;for(let[e,t]of Object.entries(l))e&&(Qu(o,e,t),u+=1);return await T(e,o,{signal:i.signal}),{action:a,extrasCount:u}}function Qu(e,n,r){if(typeof r==`string`){e.push(`--es`,n,r);return}if(typeof r==`boolean`){e.push(`--ez`,n,r?`true`:`false`);return}if(typeof r==`number`&&Number.isFinite(r)){if(Number.isInteger(r)){e.push(`--ei`,n,String(r));return}e.push(`--ef`,n,String(r));return}throw new t(`INVALID_ARGS`,`Unsupported Android broadcast extra type for "${n}". Use string, boolean, or number.`)}function 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 $u(e){let t=id(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 ad(n)}function ed(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 td(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=>rd({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 nd(e){return Math.round(e*10)/10}function rd(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:nd(Math.max(...t.map(e=>e.durationNs))/1e6)}}function id(e){return[...new Set(e.filter(e=>Number.isFinite(e)))].sort((e,t)=>e-t)}function ad(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 od(e,t,n){sd(e,t);let r=_d(e),i=pd(e),a=ld(i,r,t),o=Date.parse(n),s=yd({frames:i,measuredAtMs:o,summary:r}),c=ed({frames:i,frameDeadlineNs:a,summaryDroppedFrameCount:r?.droppedFrameCount}),l=r?.sampleWindowMs??s.sampleWindowMs??Cd(i),u=ud(r,i,c),d=fd({droppedFrames:c,timing:s,measuredAtMs:o,summary:r});return{...u,sampleWindowMs:l,...dd(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 sd(e,n){if(/no process found for:/i.test(e))throw new t(`COMMAND_FAILED`,`Android gfxinfo did not find a running process for ${n}`,{metric:`fps`,package:n,hint:`Run open <app> for this session again to ensure the Android app is active, then retry perf after the interaction you want to inspect.`})}function cd(e){throw new t(`COMMAND_FAILED`,`Failed to parse Android framestats output for ${e}`,{metric:`fps`,package:e,hint:`Retry perf after exercising the app screen. If the problem persists, capture adb shell dumpsys gfxinfo <package> framestats output for debugging.`})}function ld(e,n,r){let i=$u(e);if(!n&&e.length===0&&cd(r),n||i!==void 0)return i;throw new t(`COMMAND_FAILED`,`Failed to infer Android frame deadline from framestats output for ${r}`,{metric:`fps`,package:r,hint:`Retry perf after a longer interaction window so consecutive Android frame timestamps are available.`})}function ud(e,t,n){let r=e?.totalFrameCount??t.length,i=e?.droppedFrameCount??n.length;return{totalFrameCount:r,droppedFrameCount:i,droppedFramePercent:e?.droppedFramePercent??(r>0?Ft(i/r*100):0)}}function dd(e){return{frameDeadlineMs:e===void 0?void 0:nd(e/1e6),refreshRateHz:e===void 0?void 0:nd(1e9/e)}}function fd(e){let{droppedFrames:t,timing:n,measuredAtMs:r,summary:i}=e;if(t.length===0)return;let a=td({frames:t,windowStartNs:n.windowStartNs,measuredAtMs:r,uptimeMs:i?.uptimeMs});return a.length>0?a:void 0}function pd(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(md(i)){n=new Map(i.map((e,t)=>[e,t]));continue}let a=hd(i,n);a&&t.push(a)}return t.sort((e,t)=>e.intendedVsyncNs-t.intendedVsyncNs)}function md(e){return e.includes(`IntendedVsync`)&&e.includes(`FrameCompleted`)}function hd(e,t){if(!t||e.length<t.size)return;let n=gd(e,t,`Flags`),r=gd(e,t,`IntendedVsync`),i=gd(e,t,`FrameCompleted`);if(!(n!==0||r===null||i===null||r<=0||i<=r))return{intendedVsyncNs:r,frameCompletedNs:i,durationNs:i-r}}function gd(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=wd(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=wd(t,`Uptime`),l=wd(t,`Stats since`);return{droppedFramePercent:Ft(s),droppedFrameCount:o,totalFrameCount:n,sampleWindowMs:vd({uptimeMs:c,statsSinceNs:l}),uptimeMs:c,statsSinceNs:l}}function vd(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 yd(e){let{frames:t,measuredAtMs:n,summary:r}=e,i=bd(t),a=r?.statsSinceNs,o=a??i.firstFrameNs,s=xd(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:Sd({deviceBootWallClockMs:l,measuredAtMs:n,summaryStartNs:a,lastFrameNs:i.lastFrameNs}),timestampSource:`estimated-from-device-uptime`}}function bd(e){return e.length===0?{}:{firstFrameNs:Math.min(...e.map(e=>e.intendedVsyncNs)),lastFrameNs:Math.max(...e.map(e=>e.frameCompletedNs))}}function xd(e,t){if(e!==void 0&&t!==void 0)return Math.max(0,Math.round((t-e)/1e6))}function Sd(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 Cd(e){if(e.length===0)return;let t=bd(e);return xd(t.firstFrameNs,t.lastFrameNs)}function wd(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 Td(e,t,n={}){let r=y(e,n.adb);try{let i=od((await b(r,[`dumpsys`,`gfxinfo`,t,`framestats`],{timeoutMs:15e3})).stdout,t,new Date().toISOString());return await Ed(e,t,n),i}catch(e){throw Dd(t,e)}}async function Ed(e,t,n={}){let r=y(e,n.adb);try{await b(r,[`dumpsys`,`gfxinfo`,t,`reset`],{allowFailure:!0,timeoutMs:3e3})}catch{}}function Dd(e,n){return n instanceof t?new t(n.code,n.message,{...n.details??{},metric:`fps`,package:e},n):new t(`COMMAND_FAILED`,`Failed to sample Android fps for ${e}`,{metric:`fps`,package:e},n)}async function Od(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 kd(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 kd(e,t,n){try{let r=await Td(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 Ad(e,t,n){let r=y(e,n.adb);await Id(r,t),await zd(r,t),await Rd(r,t,n.files);let i=await Fd(t.outPath,n.files);await Nd(r,t.remotePath);let a=Date.now(),o=Math.max(0,a-t.startedAt),s=await Od(e,t,i,o,{adb:r});return{...t,action:`stop`,platform:`android`,state:`stopped`,stoppedAt:a,durationMs:o,sizeBytes:i,method:t.kind===`simpleperf`?Nr:Pr,artifact:{path:t.outPath,sizeBytes:i},summary:s,message:`Stopped Android ${t.kind} ${t.type} for ${t.packageName}`}}async function jd(e,t,n={}){let r=y(e,n.adb);try{t.state===`running`&&(await Id(r,t),await zd(r,t).catch(()=>{}))}finally{await Nd(r,t.remotePath)}}function Md(e,t,n=Ir){return`${n}/agent-device-${e.replaceAll(/[^A-Za-z0-9_.-]/g,`_`)}-${Date.now()}-${t}`}async function Nd(e,t){try{await b(e,[`rm`,`-f`,t],{allowFailure:!0,timeoutMs:Fr})}catch{}}async function Pd(e,t,n=x().files){await n.ensureDirectory(E.dirname(e)),await n.writeBytes(e,Buffer.from(`${JSON.stringify(t,null,2)}\n`))}async function Fd(e,n=x().files){try{return(await n.stat(e)).size}catch(n){throw new t(`COMMAND_FAILED`,`Profiler artifact was not written: ${e}`,{outPath:e,hint:`Retry the profiling command and check daemon logs if the artifact path is still missing.`},n)}}async function Id(e,t){try{await b(e,[_(Ld(t.profilerPid))],{timeoutMs:N})}catch(e){throw M(`stop`,t.kind,t.packageName,e)}}function Ld(e){return[`pid=${v(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 Rd(e,n,r){await(r??x().files).ensureDirectory(E.dirname(n.outPath));try{await e([`pull`,n.remotePath,n.outPath],{timeoutMs:N})}catch(e){throw new t(`COMMAND_FAILED`,`Failed to pull Android ${n.kind} artifact for ${n.packageName}`,{package:n.packageName,tool:n.kind,remotePath:n.remotePath,outPath:n.outPath,hint:`Check that the profiling command ran long enough to create an artifact, then retry stop with the same session.`},e)}}async function zd(e,n){let r;for(let t=0;t<12;t+=1){let t=await Bd(e,n.remotePath);if(t!==void 0&&t>0&&t===r)return;r=t,await g(250)}throw new t(`COMMAND_FAILED`,`Android ${n.kind} artifact is not ready to pull`,{package:n.packageName,tool:n.kind,remotePath:n.remotePath,hint:`The profiler stopped, but the remote artifact was missing, empty, or still changing. Retry stop with the same session or inspect the device-side artifact.`})}async function Bd(e,t){let n=v(t),r=await b(e,[_(`if [ -f ${n} ]; then stat -c %s ${n} 2>/dev/null || wc -c < ${n}; fi`)],{allowFailure:!0,timeoutMs:Fr});if(r.exitCode!==0)return;let i=Number(r.stdout.trim().split(/\s+/)[0]);return Number.isFinite(i)?i:void 0}async function Vd(e,t,n,r={}){let i=y(e,r.adb),a=await Lr(i,t);await Rr(i,`perfetto`,t);let o=Md(t,`app.perfetto-trace`,`/data/misc/perfetto-traces`),s;try{await Ed(e,t,{adb:i}),s=await Ud(i,o,t)}catch(e){throw await Nd(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:Pr,message:`Started Android Perfetto trace for ${t}`}}async function Hd(e,t,n,r={}){return await Ad(e,{...t,outPath:n},r)}async function Ud(e,n,r){try{let i=zr((await b(e,[`perfetto`,`--background-wait`,`-o`,n,`-t`,`3600s`,`sched`,`freq`,`idle`,`am`,`wm`,`gfx`,`view`,`binder_driver`,`hal`,`dalvik`],{timeoutMs:N})).stdout);if(i)return i;throw new t(`COMMAND_FAILED`,`Android perfetto did not return a profiler pid`,{package:r,tool:`perfetto`,hint:`Retry perf trace start. If perfetto exits immediately, verify the device permits trace capture.`})}catch(e){throw M(`start`,`perfetto`,r,e)}}function Wd(e){let t=[];for(let n of s(e)){let e=n.match(/^([0-9]+(?:\.[0-9]+)?)%\s+(.+)$/);if(!e)continue;let r=Number(e[1]),i=e[2]?.trim();if(!Number.isFinite(r)||!i)continue;let a=i.split(/\s{2,}/).filter(Boolean);if(t.push({percentage:Ft(r),command:a[0],dso:a[1],symbol:a.slice(2).join(` `)||void 0}),t.length>=50)break}return t}async function Gd(e,t,n,r={}){let i=y(e,r.adb),a=await Lr(i,t);await Rr(i,`simpleperf`,t);let o=Md(t,`cpu.perf.data`),s;try{s=await Jd(i,a,o,t)}catch(e){throw await Nd(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:Nr,message:`Started Android Simpleperf CPU profile for ${t}`}}async function Kd(e,t,n,r={}){return await Ad(e,{...t,outPath:n},r)}async function qd(e,t,n,r={}){let i=y(e,r.adb);await Rr(i,`simpleperf`,t.packageName);let a=await Zd(i,t),o=new Date().toISOString(),s=Wd(a.stdout),c=s.slice(0,10).map(e=>({symbol:e.symbol??`<unknown>`,binary:e.dso,selfSamplePercent:e.percentage}));await Pd(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 Fd(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:Nr,message:`Wrote Android Simpleperf report for ${t.packageName}`}}async function Jd(e,n,r,i){try{let a=zr((await b(e,[_(Yd(n,r))],{timeoutMs:N})).stdout);if(a)return a;throw new t(`COMMAND_FAILED`,`Android simpleperf did not return a profiler pid`,{package:i,tool:`simpleperf`,hint:`Retry perf. If simpleperf exits immediately, verify the app is profileable and the device permits native profiling.`})}catch(e){throw M(`start`,`simpleperf`,i,e)}}function Yd(e,t){return Xd([`simpleperf`,`record`,`-e`,`cpu-clock:u`,`-p`,e,`-o`,t,`--duration`,`3600`],`simpleperf`)}function Xd(e,t){let n=e.map(v).join(` `),r=`${Ir}/agent-device-${t}-${Date.now()}.err`;return[`err=${v(r)}`,`(${n}) >/dev/null 2>"$err" & pid=$!`,`sleep 1`,`if kill -0 "$pid" 2>/dev/null; then rm -f "$err"; echo "$pid"; exit 0; fi`,`cat "$err" >&2`,`rm -f "$err"`,`exit 1`].join(`; `)}async function Zd(e,t){try{return await b(e,[`simpleperf`,`report`,`-i`,t.remotePath,`--stdio`,`--sort`,`comm,dso,symbol`],{timeoutMs:N})}catch(e){throw M(`report`,`simpleperf`,t.packageName,e)}}const Qd=15e3,$d=12e4;async function ef(e,t,n={}){let r=y(e,n.adb);try{return af((await b(r,[`dumpsys`,`meminfo`,t],{timeoutMs:Qd})).stdout,t,new Date().toISOString())}catch(e){throw pf(`memory`,t,e)}}async function tf(e,n,r,i={}){let a=y(e,i.adb),o=i.files??x().files,s=await of(a,n),c=sf(n);await o.ensureDirectory(E.dirname(r));let l=await nf(o,r);try{ye(await b(a,[`am`,`dumpheap`,n,c],{allowFailure:!0,timeoutMs:$d}),`Failed to capture Android heap dump for ${n}`,e=>({kind:`android-hprof`,package:n,pid:s,remotePath:c,hint:cf(e.stdout,e.stderr)}));let e=await a([`pull`,c,r],{allowFailure:!0,timeoutMs:$d});if(e.exitCode!==0)throw await rf(o,r,l),w(`Failed to pull Android heap dump for ${n}`,e,{kind:`android-hprof`,package:n,pid:s,remotePath:c,path:r,hint:`Verify the daemon can write the requested --out path and retry. The heap dump stays on-device only until cleanup runs.`});let i=await o.stat(r).catch(()=>null);if(!i?.isFile||i.size<=0)throw await rf(o,r,l),new t(`COMMAND_FAILED`,`Android heap dump artifact is missing or empty`,{kind:`android-hprof`,package:n,pid:s,path:r,remotePath:c,hint:`Retry with a writable --out path. If the file is still empty, inspect adb pull output with --debug.`});return{available:!0,kind:`android-hprof`,path:r,sizeBytes:i.size,measuredAt:new Date().toISOString(),method:`adb-shell-am-dumpheap`,packageName:n,pid:s,remotePath:c}}finally{await b(a,[`rm`,`-f`,c],{allowFailure:!0,timeoutMs:Qd}).catch(()=>{})}}async function nf(e,t){return await e.stat(t).then(e=>e.isFile).catch(()=>!1)}async function rf(e,t,n){n||await e.remove(t,{force:!0}).catch(()=>{})}function af(e,n,r){if(/no process found for:/i.test(e))throw new t(`COMMAND_FAILED`,`Android meminfo did not find a running process for ${n}`,{metric:`memory`,package:n,hint:`Run open <app> for this session again to ensure the Android app is active, then retry perf.`});let i=mf(e,`TOTAL PSS`)??hf(e);if(i===void 0)throw new t(`COMMAND_FAILED`,`Failed to parse Android meminfo output for ${n}`,{metric:`memory`,package:n,hint:`Retry perf after reopening the app session. If the problem persists, capture adb shell dumpsys meminfo output for debugging.`});return{totalPssKb:i,totalRssKb:mf(e,`TOTAL RSS`),measuredAt:r,method:`adb-shell-dumpsys-meminfo`,topConsumers:lf(e)}}async function of(e,n){let r=await b(e,[`pidof`,n],{allowFailure:!0,timeoutMs:Qd}),i=r.stdout.trim().split(/\s+/).map(Number).find(e=>Number.isInteger(e)&&e>0);if(r.exitCode===0&&i!==void 0)return i;throw new t(`COMMAND_FAILED`,`No running Android process found for ${n}`,{kind:`android-hprof`,package:n,stdout:r.stdout,stderr:r.stderr,hint:`Run open <app> for this session again to ensure the Android app is active, then retry perf memory snapshot.`})}function sf(e){return`/data/local/tmp/agent-device-${e.replaceAll(/[^a-zA-Z0-9._-]/g,`_`)}-${Date.now()}.hprof`}function cf(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 lf(e){let t=e.split(`
|
|
14
|
+
`).flatMap(e=>uf(e)??[]).sort((e,t)=>t.pssKb-e.pssKb).slice(0,5);return t.length>0?t:void 0}function uf(e){let t=e.trim();if(df(t))return;let n=t.match(/^(.+?)\s+([0-9][0-9,]*(?:\(\d+\))?)(?:\s|$)/);if(n)return ff(n[1],n[2])}function df(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 ff(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 pf(e,n,r){return r instanceof t?new t(r.code,r.message,{...r.details??{},metric:e,package:n},r):new t(`COMMAND_FAILED`,`Failed to sample Android ${e} for ${n}`,{metric:e,package:n},r)}function mf(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 hf(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 gf(e,t,n){let r=await T(e,[`dumpsys`,`package`,t],{allowFailure:!0});return r.exitCode===0?Ef(r.stdout,n):{requested:void 0,grants:void 0}}async function _f(e){let t=await T(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 vf=/^\s*User (\d+):/,yf=/^\s*runtime permissions:\s*$/,bf=/^\s*([\w.]+): granted=(true|false)\b/,xf=/^\s*Package \[.+?\]/,Sf=/^\s*requested permissions:\s*$/,Cf=/^\s*([A-Za-z][\w.]*)/;function wf(e){return e.split(`
|
|
16
|
+
`).filter(e=>e.trim().length>0).map(e=>({text:e,indent:e.length-e.trimStart().length}))}function Tf(e,t){let n=Q(Q(Q(wf(e),e=>e.indent===0&&e.text.trim()===`Packages:`),e=>vf.exec(e.text)?.[1]===String(t)),e=>yf.test(e.text));if(!n)return;let r=new Map;for(let{text:e}of n){let t=bf.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 Ef(e,t){return{requested:Df(e),grants:Tf(e,t)}}function Df(e){let t=Q(Q(Q(wf(e),e=>e.indent===0&&e.text.trim()===`Packages:`),e=>xf.test(e.text)),e=>Sf.test(e.text));if(!t)return;let n=[];for(let{text:e}of t){let t=Cf.exec(e)?.[1];t&&t.includes(`.`)&&!n.includes(t)&&n.push(t)}return n}function Of(e,t,n){if(n!==`not_granted`)return`${n===`granted`?`${t} was granted before this revoke, and Android kills an app when a granted permission is revoked: if ${e} was running it is no longer.`:`Whether ${t} was granted before this revoke could not be read (adb did not report the acting user's runtime permission state), and Android kills an app when a granted permission is revoked: ${e} may no longer be running.`} Relaunch it with open ${e} --relaunch before the next interaction.`}const kf=[`all`,`camera`,`microphone`,`photos`,`contacts`,`notifications`,`calendar`,`location`,`media-library`],Af={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 jf(e){let n=await _f(e);if(n!==void 0)return n;throw new t(`COMMAND_FAILED`,`Could not determine which Android user the session runs as, so no permission was changed.`,{deviceId:e.id,hint:`Check adb -s ${e.id} shell am get-current-user — if the device is still booting, retry once it reports a user. agent-device refuses to change permissions it cannot scope, because pm would silently apply them to user 0.`})}async function Mf(e,t,n,r){let i=me(n),a=Jf(r?.permissionTarget,r?.permissionMode),o=await jf(e),s=[`--user`,String(o)];if(a.kind===`all`)return await Nf(e,t,i,o,s);if(i===`grant`){await Kf(e,t,a,o,s);return}if(a.kind===`pm`)return await Zf(e,t,i,a,o,s);let{grants:c}=await gf(e,t,o),l=await qf(e,t,i,a,s),{priorGrantState:u,warnings:d}=$f(t,l,l.map(e=>c?.get(e)??`unknown`));return{permission:l.join(`,`),priorGrantState:u,...d.length>0?{warnings:d}:{}}}async function Nf(e,n,r,i,a){let{requested:o,grants:s}=await gf(e,n,i);if(o===void 0)throw new t(`COMMAND_FAILED`,`Could not read declared permissions for ${n}, so no permission was changed.`,{appPackage:n});let c=r===`grant`?void 0:s,l=[],u=[];for(let t of zf(o))await Pf({device:e,appPackage:n,action:r,userArgs:a,grants:c,applied:l,warnings:u},t);return{permission:`all`,applied:l,...u.length>0?{warnings:u}:{}}}async function Pf(e,t){return t.kind===`notification`?await Ff(e):t.kind===`photos`?await If(e):await Lf(e,t.value)}async function Ff(e){let{device:t,appPackage:n,action:r,userArgs:i,grants:a,applied:o,warnings:s}=e;await tp(t,n,r,{appOps:`POST_NOTIFICATION`,permission:`android.permission.POST_NOTIFICATIONS`},i),o.push(`android.permission.POST_NOTIFICATIONS`),Bf(s,a,n,`android.permission.POST_NOTIFICATIONS`)}async function If(e){let{device:t,appPackage:n,action:r,userArgs:i,warnings:a}=e,o=await Uf(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 Rf(e,o)}async function Lf(e,t){let{device:n,appPackage:r,action:i,userArgs:a,warnings:o}=e,s=await Vf(n,i===`grant`?`grant`:`revoke`,a,r,t);if(!s.ok){o.push(`Skipped ${t} for ${r}: ${s.reason}`);return}await Rf(e,t)}async function Rf(e,t){let{device:n,appPackage:r,action:i,userArgs:a,grants:o,applied:s,warnings:c}=e;s.push(t),i===`reset`&&await np(n,r,t,a),i!==`grant`&&Bf(c,o,r,t)}function zf(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 Bf(e,t,n,r){let i=Of(n,r,t?.get(r)??`unknown`);i&&e.push(i)}async function Vf(e,t,n,r,i){let a=await T(e,[`pm`,t,...n,r,i],{allowFailure:!0});if(a.exitCode===0)return{ok:!0};if(Hf(a.stderr))return{ok:!1,reason:Gf(a.stderr)};throw w(`Failed to ${t} Android permission ${i} for ${r}`,a,{appPackage:r,permission:i})}function Hf(e){let t=e.toLowerCase();return t.includes(`not a changeable permission`)||t.includes(`has not requested permission`)||t.includes(`is not a runtime permission`)||t.includes(`unknown permission`)||t.includes(`managed by role`)}async function Uf(e,t,n,r){try{return await ep(e,t,n,r)}catch(e){if(Wf(e))return;throw e}}function Wf(e){if(!(e instanceof t)||e.code!==`COMMAND_FAILED`)return!1;let n=e.details?.attempts;return!Array.isArray(n)||n.length===0?!1:n.every(e=>typeof e.stderr==`string`&&Hf(e.stderr))}function Gf(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 Kf(e,t,n,r,i){if(n.kind===`notifications`)await tp(e,t,`grant`,n,i);else if(n.kind===`photos`)await ep(e,t,`grant`,i);else if(n.kind===`pm`)for(let a of await Yf(e,t,n.values,r))await T(e,[`pm`,`grant`,...i,t,a]);else if(n.kind===`all`)throw Error(`Unhandled Android permission target: all is resolved by the caller.`);else throw Error(`Unhandled Android permission target: ${JSON.stringify(n)}`)}async function qf(e,t,n,r,i){if(r.kind===`notifications`)return await tp(e,t,n,r,i),[r.permission];if(r.kind===`photos`){let r=await ep(e,t,`revoke`,i);return n===`reset`&&await np(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 Jf(e,n){let r=ge(e);if(n?.trim())throw new t(`INVALID_ARGS`,`Android does not support permission modes. Received: ${n}.`);if(r===`all`)return{kind:`all`};if(r===`photos`)return{kind:`photos`};if(r===`notifications`)return{kind:`notifications`,appOps:`POST_NOTIFICATION`,permission:`android.permission.POST_NOTIFICATIONS`};let i=r in Af?Af[r]:void 0;if(i)return{kind:`pm`,values:i};throw new t(`INVALID_ARGS`,`Unsupported permission target on Android: ${e}. Use ${kf.join(`|`)}.`,{hint:`Android custom permission ids are attempted through all, not individually.`})}async function Yf(e,t,n,r){let{requested:i}=await gf(e,t,r);return Xf(i,n,t)}function Xf(e,n,r){if(e===void 0)return n;let i=n.filter(t=>e.includes(t));if(i.length===0)throw new t(`COMMAND_FAILED`,`Package ${r} has not requested permission ${n.join(`, `)}, so no permission was changed.`,{appPackage:r,permission:n.join(`,`)});return i}async function Zf(e,t,n,r,i,a){let{requested:o,grants:s}=await gf(e,t,i),c=Xf(o,r.values,t);await Qf(e,t,c,n,a);let{priorGrantState:l,warnings:u}=$f(t,c,c.map(e=>s?.get(e)??`unknown`));return{permission:[...c].join(`,`),priorGrantState:l,...u.length>0?{warnings:u}:{}}}async function Qf(e,t,n,r,i){for(let r of n)await T(e,[`pm`,`revoke`,...i,t,r]);if(r===`reset`)for(let r of n)await np(e,t,r,i)}function $f(e,t,n){return{priorGrantState:n.includes(`granted`)?`granted`:n.includes(`unknown`)?`unknown`:`not_granted`,warnings:t.flatMap((t,r)=>{let i=Of(e,t,n[r]);return i?[i]:[]})}}async function ep(e,n,r,i){let a=await rp(e),o=a!==null&&a>=33?[`android.permission.READ_MEDIA_IMAGES`,`android.permission.READ_EXTERNAL_STORAGE`]:[`android.permission.READ_EXTERNAL_STORAGE`,`android.permission.READ_MEDIA_IMAGES`],s=[];for(let t of o){let a=await T(e,[`pm`,r,...i,n,t],{allowFailure:!0});if(a.exitCode===0)return t;s.push({permission:t,stderr:a.stderr,exitCode:a.exitCode})}throw new t(`COMMAND_FAILED`,`Failed to ${r} Android photos permission`,{appPackage:n,sdkInt:a,attempts:s})}async function tp(e,t,n,r,i){let a=n===`grant`?`allow`:n===`deny`?`deny`:`default`;n===`grant`?await T(e,[`pm`,`grant`,...i,t,r.permission],{allowFailure:!0}):(await T(e,[`pm`,`revoke`,...i,t,r.permission],{allowFailure:!0}),n===`reset`&&await np(e,t,r.permission,i)),await T(e,[`appops`,`set`,...i,t,r.appOps,a])}async function np(e,t,n,r){for(let i of[`user-set`,`user-fixed`])await T(e,[`pm`,`clear-permission-flags`,...r,t,n,i],{allowFailure:!0})}async function rp(e){let t=await T(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}function ip(e){let n=e.trim().toLowerCase();if(n===`light`)return`light`;if(n===`dark`)return`dark`;if(n===`toggle`)return`toggle`;throw new t(`INVALID_ARGS`,`Invalid appearance state: ${e}. Use light|dark|toggle.`)}function ap(e){let n=e.toLowerCase();if(n===`on`||n===`true`||n===`1`)return!0;if(n===`off`||n===`false`||n===`0`)return!1;throw new t(`INVALID_ARGS`,`Invalid setting state: ${e}`)}function op(e){return e.map(e=>({args:e.args.join(` `),exitCode:e.exitCode,stderr:e.stderr.slice(0,400)}))}const sp=[`cmd`,`connectivity`,`airplane-mode`];async function cp(e,n){let r=n?`enabled`:`disabled`;await lp(e),await T(e,[...sp,n?`enable`:`disable`]);let i=await up(e);if(i!==r)throw new t(`COMMAND_FAILED`,`Android airplane mode reads ${i} after requesting ${r}.`,{deviceId:e.id,requested:r,airplaneMode:i});return{airplaneMode:i}}async function lp(e){let{state:n,result:r}=await dp(e);if(!n)throw r.exitCode!==0&&$e(r.stdout,r.stderr)?new t(`UNSUPPORTED_OPERATION`,`The connectivity service on this Android build has no airplane-mode command, so nothing was changed.`,{deviceId:e.id,hint:`settings airplane needs cmd connectivity airplane-mode, which requires Android 11 (API 30) or newer. Use a newer device or emulator image.`,stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode}):w(`Failed to read Android airplane mode`,r,{deviceId:e.id})}async function up(e){let{state:t,result:n}=await dp(e);if(t)return t;throw w(`Failed to read Android airplane mode after changing it`,n,{deviceId:e.id})}async function dp(e){let t=await T(e,[...sp],{allowFailure:!0});return{state:t.exitCode===0?fp(t.stdout):void 0,result:t}}function fp(e){let t=e.trim().toLowerCase();if(t===`enabled`)return`enabled`;if(t===`disabled`)return`disabled`}const pp=[`window_animation_scale`,`transition_animation_scale`,`animator_duration_scale`];async function mp(e,n,r,i,a){switch(n.toLowerCase()){case`wifi`:{let t=ap(r);await T(e,[`svc`,`wifi`,t?`enable`:`disable`]);return}case`airplane`:return await cp(e,ap(r));case`location`:{if(r.toLowerCase()===`set`){if(e.kind!==`emulator`)throw new t(`UNSUPPORTED_OPERATION`,`Android precise location coordinates are supported only on emulators.`,{deviceId:e.id,hint:`Use an Android emulator for adb emu geo fix, or configure location through device/provider tooling.`});let{latitude:n,longitude:r}=he(a);return await Qe(e,[`emu`,`geo`,`fix`,String(r),String(n)]),{latitude:n,longitude:r}}let n=ap(r)?`3`:`0`;await T(e,[`settings`,`put`,`secure`,`location_mode`,n]);return}case`animations`:{let t=ap(r)?`1`:`0`;for(let n of pp)await T(e,[`settings`,`put`,`global`,n,t]);return{scale:t,keys:[...pp]}}case`appearance`:{let t=await yp(e,r);await T(e,[`cmd`,`uimode`,`night`,t===`dark`?`yes`:`no`]);return}case`clear-app-state`:{if(r.toLowerCase()!==`clear`)throw new t(`INVALID_ARGS`,`settings clear-app-state only supports clear.`);if(!i)throw new t(`INVALID_ARGS`,`settings clear-app-state requires an app id or an active app session.`);let n=await yt(e,i);if(n.type===`intent`)throw new t(`INVALID_ARGS`,`settings clear-app-state requires a package name, not an intent.`);await T(e,[`am`,`force-stop`,n.value],{allowFailure:!0});let a=await T(e,[`pm`,`clear`,n.value],{allowFailure:!0});if(a.exitCode!==0||!/\bSuccess\b/i.test(a.stdout))throw new t(`COMMAND_FAILED`,`Failed to clear Android app data for ${n.value}`,{package:n.value,stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});return{package:n.value,cleared:!0}}case`fingerprint`:await gp(e,hp(r));return;case`permission`:if(!i)throw new t(`INVALID_ARGS`,`permission setting requires an active app in session`);return await Mf(e,i,r,a);default:throw new t(`INVALID_ARGS`,`Unsupported setting: ${n}`)}}function hp(e){let n=e.trim().toLowerCase();if(n===`match`)return`match`;if(n===`nonmatch`)return`nonmatch`;throw new t(`INVALID_ARGS`,`Invalid fingerprint state: ${e}. Use match|nonmatch.`)}async function gp(e,n){let r=_p(e,n),i=[];for(let t of r){let n=await Qe(e,t,{allowFailure:!0});if(n.exitCode===0)return;i.push({args:t,stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode})}let a=op(i);throw i.length>0&&i.every(e=>vp(e.stdout,e.stderr))?new t(`UNSUPPORTED_OPERATION`,`Android fingerprint simulation is not supported on this target/runtime.`,{deviceId:e.id,action:n,hint:`Use an Android emulator with biometric support, or a device/runtime that exposes cmd fingerprint.`,attempts:a}):new t(`COMMAND_FAILED`,`Failed to simulate Android fingerprint.`,{deviceId:e.id,action:n,attempts:a})}function _p(e,t){let n=t===`match`?`1`:`9999`,r=[Te(`adb`,`shell`,[`cmd`,`fingerprint`,`touch`,n]),Te(`adb`,`shell`,[`cmd`,`fingerprint`,`finger`,n])];return e.kind===`emulator`&&r.push([`emu`,`finger`,`touch`,n]),r}function vp(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 yp(e,n){let r=ip(n);if(r!==`toggle`)return r;let i=await T(e,[`cmd`,`uimode`,`night`],{allowFailure:!0});if(i.exitCode!==0)throw w(`Failed to read current Android appearance`,i);let a=bp(i.stdout,i.stderr);if(!a)throw new t(`COMMAND_FAILED`,`Unable to determine current Android appearance for toggle`,{stdout:i.stdout,stderr:i.stderr});return a===`auto`?`dark`:a===`dark`?`light`:`dark`}function bp(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 xp=Buffer.from([137,80,78,71,13,10,26,10]);async function Sp(e,t,n={}){if(n.stabilize===!1){await Tp(e,t);return}await Cp(e);try{await g(1e3),await Tp(e,t)}finally{await wp(e).catch(()=>{})}}async function Cp(e){let t=t=>T(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 wp(e){await T(e,[`am`,`broadcast`,`-a`,`com.android.systemui.demo`,`-e`,`command`,`exit`],{allowFailure:!0})}async function Tp(e,n){let r=await Ze(e,[`screencap`,`-p`],{binaryStdout:!0});if(!r.stdoutBuffer)throw new t(`COMMAND_FAILED`,`Failed to capture screenshot`);let i=r.stdoutBuffer.indexOf(xp);if(i<0)throw new t(`COMMAND_FAILED`,`Screenshot data does not contain a valid PNG header`);let a=Ep(r.stdoutBuffer,i);if(!a)throw new t(`COMMAND_FAILED`,`Screenshot data does not contain a complete PNG payload`);await x().files.writeBytes(n,r.stdoutBuffer.subarray(i,a))}function Ep(e,t){let n=t+xp.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 Dp(e,t,n=0){let r=Re(e);if(r){await r({action:`type`,text:t,delayMs:n}),$(`type`,`provider-native`,t);return}let i=await Mp(e,`type`,t);if(i.backend===`test-ime`){await Np(e,i.packageName,t,n);return}if(n>0&&Array.from(t).length>1){await Fp(e,{action:`type`,text:t,chunkSize:1,delayMs:n});return}await Fp(e,{action:`type`,text:t,chunkSize:8,delayMs:0})}async function Op(e,t,n,r,i=0,a={}){let o=await $l(e,t,n,a),s=Re(e);if(s)return await s({action:`fill`,target:{x:t,y:n},text:r,delayMs:i}),$(`fill`,`provider-native`,r),X(r,o,await Xl(e,t,n,r,a));let c=null;for(let s of kp(i)){await Oa(e,t,n);let i=await Mp(e,`fill`,r);if(i.backend===`test-ime`)return X(r,o,await Pp(e,i.packageName,t,n,r,o,a));let l=await Ap(e,{x:t,y:n,text:r,beforeTarget:o,attempt:s},a);if(c=l,l.ok)return;if(l.reason===`ime_capture`)return X(r,o,l);let u=eu(r,o,l);if(u)return u}return X(r,o,c)}function kp(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 Ap(e,t,n){let{x:r,y:i,text:a,beforeTarget:o,attempt:s}=t;return await Lp(e,jp(a,o,s)),await Fp(e,{action:`fill`,text:a,chunkSize:s.chunkSize,delayMs:s.inputDelayMs}),Xl(e,r,i,a,n)}function jp(e,t,n){let r=Array.from(e).length;return Kp(r>0?r+n.clearPadding:t?.text?Array.from(t.text).length+n.clearPadding:n.maxClear,n.minClear,n.maxClear)}async function Mp(e,t,n){if(Jo(e))return{backend:`test-ime`,packageName:(await Oo(C(e))).manifest.packageName};let r=await Rp(e,t),i=r?.inputMethodPackage;return Po(i)?{backend:`test-ime`,packageName:i}:(Bp(n),zp(r,t),{backend:`adb-shell`})}async function Np(e,t,n,r){let i=y(e),a=n.split(`
|
|
18
|
+
`);for(let[n,o]of a.entries()){let s=r>0?Gp(o,1):[o];for(let[e,o]of s.entries())o&&await Fo(i,t,o),r>0&&(e+1<s.length||n+1<a.length)&&await g(r);n+1<a.length&&await T(e,[`input`,`keyevent`,`ENTER`])}$(`type`,`test-ime`,n)}async function Pp(e,t,n,r,i,a,o){let s=y(e),c=null;for(let l=0;l<2;l+=1){l>0&&await Oa(e,n,r),await Io(s,t),i&&await Fo(s,t,i);let u=await Xl(e,n,r,i,o);if(c=u,u.ok||eu(i,a,u))break}return $(`fill`,`test-ime`,i),c}async function Fp(e,t){let n=t.text.split(`
|
|
19
|
+
`);for(let[r,i]of n.entries()){let a=Gp(i,t.chunkSize);for(let[i,o]of a.entries())await Ip(e,o),t.delayMs>0&&(i+1<a.length||r+1<n.length)&&await g(t.delayMs);r+1<n.length&&await T(e,[`input`,`keyevent`,`ENTER`])}$(t.action,`adb-shell`,t.text)}async function Ip(e,t){if(t)try{await T(e,[`input`,`text`,Hp(t)])}catch(e){throw Up(e)?Wp(t,e):e}}async function Lp(e,t){let n=Math.max(0,t);await T(e,[`input`,`keyevent`,`KEYCODE_MOVE_END`],{allowFailure:!0});for(let t=0;t<n;t+=24){let r=Math.min(24,n-t);await T(e,[`input`,`keyevent`,...Array(r).fill(`KEYCODE_DEL`)],{allowFailure:!0})}}async function Rp(e,t){try{return await oo(e)}catch(e){return h({level:`warn`,phase:`android_input_ownership_probe_failed`,data:{action:t,error:e instanceof Error?e.message:String(e)}}),null}}function zp(e,n){if(!(!e||e.inputOwner!==`ime`))throw new t(`COMMAND_FAILED`,`KEYBOARD_OVERLAY_BLOCKING: Android text input is blocked because the focused input belongs to the active keyboard/IME.`,{failureReason:`ime_capture`,action:n,inputOwner:e.inputOwner,inputType:e.inputType,type:e.type,inputMethodPackage:e.inputMethodPackage,focusedPackage:e.focusedPackage,focusedResourceId:e.focusedResourceId,nextAction:`Focused input appears to be owned by the keyboard/IME; dismiss or change the IME before retrying text entry.`})}function Bp(e){if(!Vp(e))throw Wp(e)}function Vp(e){for(let t of e){let e=t.codePointAt(0);if(e!==void 0&&t!==`
|
|
20
|
+
`&&(e<32||e>126))return!1}return!0}function Hp(e){return e.replaceAll(` `,`%s`)}function Up(e){if(!(e instanceof t)||e.code!==`COMMAND_FAILED`)return!1;let n=e.details?.stderr,r=(typeof n==`string`?n:``).toLowerCase();return!!(r.includes(`exception occurred while executing 'text'`)||r.includes(`nullpointerexception`)&&r.includes(`inputshellcommand.sendtext`))}function Wp(e,n){return new t(`COMMAND_FAILED`,"Android text input requires provider-native text injection or the bundled test IME helper for non-ASCII/control characters; the adb-shell fallback supports ASCII text only. On emulators the test IME activates automatically; on real devices pass `open --test-ime` to enable it (see `agent-device doctor` for the current IME state).",{backend:`adb-shell`,textLength:Array.from(e).length,textPreview:e.slice(0,32)},n instanceof Error?n:void 0)}function Gp(e,t){let n=Math.max(1,Math.floor(t)),r=[],i=Array.from(e);for(let e=0;e<i.length;e+=n)r.push(i.slice(e,e+n).join(``));return r.length>0?r:[``]}function $(e,t,n){h({phase:`android_text_injection`,data:{action:e,backend:t,textLength:Array.from(n).length}})}function Kp(e,t,n){return Math.max(t,Math.min(n,e))}var qp=e({ANDROID_FOCUSED_WINDOW_MARKER:()=>Tt,ANDROID_FOCUS_MARKERS:()=>Ct,ANDROID_IME_HELPER_SERVICE_COMPONENT:()=>`com.callstack.agentdevice.imehelper/.TestInputMethodService`,ANDROID_SNAPSHOT_PRESENTATION_DEFAULT_DEADLINE_MS:()=>250,ANDROID_TEST_IME_SETTINGS_KEYS:()=>Vo,ANDROID_TOUCH_PLAN_PROTOCOL:()=>Xi,AndroidSnapshotPresentationFailure:()=>Y,activateAndroidTestIme:()=>Cu,androidAdbForwardsDeviceExitStatus:()=>zt,androidAdbHostTarget:()=>Ke,androidAdbInvocation:()=>We,androidAdbResultError:()=>w,androidAdbSerialTarget:()=>Ge,androidAppsDiscoveryHint:()=>bt,androidCaptureFailureReasonDetail:()=>pr,androidCaptureFailureReasonFromExitCode:()=>fr,androidCaptureFailureReasonFromHelperResult:()=>dr,androidClipboardShellSupportForResult:()=>Yp,androidDeviceChecks:()=>as,androidFillFailureDetails:()=>iu,androidFillFailureMessage:()=>ru,androidRevokedPermissionWarning:()=>Of,androidSnapshotPublicationInput:()=>xl,androidToolchainCheck:()=>is,androidUiNodes:()=>kc,annotateAndroidNativePerfError:()=>M,appSwitcherAndroid:()=>Ea,attachAdbFailureHint:()=>Je,backAndroid:()=>va,buildAndroidFillUnconfirmedVerification:()=>eu,buildAndroidNativeToolUnavailableHint:()=>Or,buildAndroidSnapshotClickabilityEvidence:()=>Uc,buildAndroidSnapshotHelperArgs:()=>si,buildAndroidSnapshotHelperCaptureOptions:()=>ai,buildUiHierarchySnapshot:()=>lc,captureAndroidHeapSnapshot:()=>tf,captureAndroidLogcatWithAdb:()=>Xp,captureAndroidSnapshotWithHelper:()=>ii,captureAndroidSnapshotWithHelperSession:()=>Gi,classifyAdbFailure:()=>Xe,classifyAndroidAlertIdentifier:()=>Zt,classifyAndroidAppTarget:()=>ht,classifyAndroidHelperContent:()=>Gc,cleanupAndroidNativePerfSession:()=>jd,clearAndroidImeHelperText:()=>Io,clearAndroidTestImeRecoveryMarker:()=>ku,closeAndroidApp:()=>ut,completeAndroidFillVerification:()=>X,createAndroidPortReverseManager:()=>Ie,createAndroidSnapshotCapture:()=>bl,createAndroidSnapshotPresentationBudget:()=>ic,createAndroidSnapshotPresentationNode:()=>ec,createAndroidWindowDumpReader:()=>kt,createDeviceAdbExecutor:()=>Le,createLocalAndroidAdbProvider:()=>Ne,dismissAndroidKeyboard:()=>so,dismissAndroidKeyboardWithAdb:()=>co,ensureAndroidEmulatorBooted:()=>pt,ensureAndroidImeHelper:()=>Mo,ensureAndroidSdkPathConfigured:()=>lt,ensureAndroidSnapshotHelper:()=>ir,executeAndroidTouchHelperPlan:()=>ea,executeAndroidTouchPlan:()=>B,fillAndroid:()=>Op,findAndroidAlertCandidate:()=>Qt,focusAndroid:()=>Oa,forceStopAndroidAppWithAdb:()=>Wa,forgetAndroidSnapshotHelperInstall:()=>$n,formatAndroidInstalledPackageRequiredMessage:()=>vt,getAndroidAppState:()=>Dt,getAndroidBlockingDialogObservation:()=>Ot,getAndroidImeHelperDeviceKey:()=>U,getAndroidKeyboardState:()=>oo,getAndroidKeyboardStatusWithAdb:()=>V,getAndroidScreenSize:()=>Ma,handleAndroidAlert:()=>Na,homeAndroid:()=>ya,inferAndroidAppName:()=>_t,inferAndroidPackageAfterOpen:()=>Qp,inspectInstalledAndroidHelper:()=>Nn,installAndroidAdbPackage:()=>ze,installAndroidInstallablePath:()=>to,isAmStartError:()=>ft,isAndroidImeHelperPackage:()=>Po,isAndroidPermissionPackage:()=>Ut,isAndroidSnapshotPresentationFailure:()=>nc,isAndroidTestImeActive:()=>Jo,listAndroidAdbSerialsQuick:()=>ns,listAndroidAppsWithAdb:()=>Jp,longPressAndroid:()=>Da,lowerAndroidAdbInvocation:()=>He,lowerAndroidTouchPlan:()=>fa,makeEnsureAndroidHelperInstalled:()=>Fn,normalizeAndroidTouchHelperGestureRequest:()=>aa,openAndroidApp:()=>ct,openAndroidAppWithAdb:()=>Ka,openAndroidDevice:()=>ot,parseAndroidAdbArgv:()=>qe,parseAndroidHelperManifest:()=>Kn,parseAndroidLaunchComponent:()=>dt,parseAndroidLaunchablePackages:()=>St,parseAndroidSnapshotHelperManifest:()=>Kn,parseAndroidSnapshotHelperOutput:()=>gi,parseAndroidUserInstalledPackages:()=>xt,parseInstrumentationRecords:()=>Sn,parseUiHierarchyTree:()=>Vc,prepareAndroidInstallArtifact:()=>Ju,pressAndroid:()=>ga,pressAndroidEnter:()=>ba,pressAndroidTvRemote:()=>_a,pullAndroidAdbFile:()=>Fe,pushAndroidNotification:()=>Zu,readAndroidBlockingDialogFocus:()=>wt,readAndroidClipboardText:()=>bo,readAndroidClipboardWithAdb:()=>xo,readAndroidDefaultInputMethod:()=>W,readAndroidFillTargetBeforeMutation:()=>$l,readAndroidGestureViewport:()=>ma,readAndroidHelperManifestInteger:()=>yn,readAndroidHelperManifestLiteral:()=>O,readAndroidTestImeRecoveryMarkers:()=>Au,readAndroidTextAtPoint:()=>Zl,readAndroidTextAtPointInHierarchy:()=>nu,readAndroidTouchHelperFinalRecord:()=>ca,readAndroidTouchHelperViewportReading:()=>ta,readInstrumentationResultBoolean:()=>On,readInstrumentationResultNumber:()=>k,resetAndroidAdbShellProtocolProbes:()=>Bt,resetAndroidFramePerfStats:()=>Ed,resetAndroidImeHelperInstallCache:()=>No,resetAndroidSnapshotHelperInstallCache:()=>er,resetAndroidSnapshotHelperRuntime:()=>vl,resetAndroidSnapshotHelperSessions:()=>Wi,resetAndroidTestImeActivationCacheForTests:()=>Xo,resetAndroidWindowDumpFocusMemoForTests:()=>Et,resolveAndroidAdbExecutor:()=>y,resolveAndroidAdbProvider:()=>C,resolveAndroidApp:()=>yt,resolveAndroidArchivePackageName:()=>Fu,resolveAndroidHelperArtifact:()=>Pn,resolveAndroidImeHelperArtifact:()=>ko,resolveAndroidPackageForOpen:()=>Zp,resolveAndroidSnapshotHelperCaptureOptions:()=>oi,resolveAndroidTextInjector:()=>Re,resolveAndroidTouchProvider:()=>je,resolveScopedAndroidAdbBackgroundTransport:()=>Pe,restoreAndroidTestIme:()=>Qo,restoreOrphanedAndroidTestImeOnDaemonStartup:()=>ts,retireAndroidSnapshotHelperAfterContentFailure:()=>_l,runAdbExecOut:()=>Be,runAdbShell:()=>b,runAndroidAdb:()=>Qe,runAndroidExecOut:()=>Ze,runAndroidHostAdb:()=>Ae,runAndroidShell:()=>T,runAndroidSnapshotHelperSessionTouchCommand:()=>qi,sampleAndroidFramePerf:()=>Td,sampleAndroidMemoryPerf:()=>ef,screenshotAndroid:()=>Sp,scrollAndroid:()=>ka,selectAndroidImeHelperArtifact:()=>Oo,sendAndroidImeHelperText:()=>Fo,serializeAndroidAdbInvocation:()=>Ue,setAndroidOrientation:()=>xa,setAndroidPermission:()=>Mf,setAndroidSetting:()=>mp,setAndroidTestImeActiveForTests:()=>Zo,sleep:()=>g,snapshotAndroid:()=>Cl,startAndroidPerfettoTrace:()=>Vd,startAndroidSimpleperfProfile:()=>Gd,stopAndroidPerfettoTrace:()=>Hd,stopAndroidSimpleperfProfile:()=>Kd,stopAndroidSnapshotHelperSession:()=>z,stopAndroidSnapshotHelperSessionForDevice:()=>Ui,typeAndroid:()=>Dp,validateAndroidGestureViewport:()=>kn,validateAndroidRegularPresentation:()=>ac,verifyAndroidFilledText:()=>Xl,verifyAndroidFilledTextInHierarchy:()=>tu,verifyAndroidHelperApkChecksum:()=>zn,waitForAndroidBoot:()=>st,withAndroidAdbProvider:()=>Me,withAndroidAppResolutionCacheInvalidated:()=>gt,withAndroidHostAdbTransport:()=>Ve,writeAndroidClipboardText:()=>So,writeAndroidClipboardWithAdb:()=>Co,writeAndroidSimpleperfReport:()=>qd,writeAndroidTestImeRecoveryMarker:()=>Ou});async function Jp(...e){let{listAndroidAppsWithAdb:t}=await import(`./app-helpers.js`);return await t(...e)}async function Yp(...e){let{androidClipboardShellSupportForResult:t}=await import(`./clipboard-shell-response.js`);return t(...e)}async function Xp(...e){let{captureAndroidLogcatWithAdb:t}=await import(`./logcat.js`);return await t(...e)}async function Zp(...e){let{resolveAndroidPackageForOpen:t}=await import(`./open-target-resolution.js`);return await t(...e)}async function Qp(...e){let{inferAndroidPackageAfterOpen:t}=await import(`./open-target-resolution.js`);return await t(...e)}export{xa as A,Oa as C,ba as D,ga as E,ma as M,_a as O,va as S,Da as T,Co as _,Dp as a,Na as b,Cl as c,co as d,oo as f,So as g,xo as h,Op as i,B as j,ka as k,xl as l,bo as m,Jp as n,Sp as o,V as p,qp as r,mp as s,Xp as t,so as u,Wa as v,ya as w,Ea as x,Ka as y};
|