agent-device 0.21.1 → 0.21.2
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.1.apk → agent-device-android-ime-helper-0.21.2.apk} +0 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.2.apk.sha256 +1 -0
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.1.manifest.json → agent-device-android-ime-helper-0.21.2.manifest.json} +4 -4
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.2.apk +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.2.apk.sha256 +1 -0
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.1.manifest.json → agent-device-android-snapshot-helper-0.21.2.manifest.json} +6 -6
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerScrollViewportPolicy.swift +413 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +34 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +56 -31
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +1 -13
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +4 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedGesturePolicy.swift +9 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +1 -0
- package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/RecordingExportSupport.swift +0 -4
- package/dist/src/absence-observation-errors.js +1 -0
- package/dist/src/adapter.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-tool.js +1 -1
- package/dist/src/agent-device-client.js +2 -2
- package/dist/src/ai-sdk.d.ts +1 -1
- package/dist/src/ai-sdk.js +1 -1
- package/dist/src/alert-runtime.js +1 -1
- package/dist/src/android-input-ownership.js +1 -1
- package/dist/src/app-helpers.js +1 -1
- package/dist/src/app-inventory-contract.js +1 -1
- package/dist/src/app-inventory.js +1 -1
- package/dist/src/app-log-runtime2.js +2 -2
- package/dist/src/auth-session.js +1 -1
- package/dist/src/back-mode.js +1 -0
- package/dist/src/browser-launch.js +1 -0
- package/dist/src/catalog.js +1 -1
- package/dist/src/cli-config.js +1 -1
- package/dist/src/cli-help.js +12 -12
- package/dist/src/cli-runner.js +1 -1
- package/dist/src/cli.js +3 -3
- package/dist/src/client-metro-companion.js +1 -1
- package/dist/src/client-metro.js +1 -1
- package/dist/src/client-types.d.ts +2 -1
- package/dist/src/code-signature-cache.js +1 -1
- package/dist/src/code-signature.js +1 -1
- package/dist/src/command-metadata.js +1 -1
- package/dist/src/command-schema.js +3 -3
- package/dist/src/command-tools.js +2 -2
- package/dist/src/config.js +1 -1
- package/dist/src/connection-runtime.js +1 -1
- package/dist/src/contracts.d.ts +1 -1
- package/dist/src/daemon-client-lifecycle.js +1 -1
- package/dist/src/daemon-process.js +1 -1
- package/dist/src/daemon-shutdown-report.js +1 -1
- package/dist/src/device-boot.js +1 -0
- package/dist/src/device-claim-inspection.js +1 -1
- package/dist/src/device-claim-rule.js +1 -1
- package/dist/src/device-input-state.d.ts +1 -1
- package/dist/src/device-session.js +1 -1
- package/dist/src/durable-resource.js +1 -1
- package/dist/src/engine-eval-script.js +1 -0
- 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 +1 -0
- package/dist/src/generic-settle.js +1 -1
- package/dist/src/gesture-plan.js +1 -1
- package/dist/src/gesture-runtime.js +1 -1
- package/dist/src/helper.js +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/input-actions.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.js +5 -5
- package/dist/src/internal/bin.js +1 -1
- package/dist/src/internal/daemon.js +2 -2
- package/dist/src/internal/png-worker.d.ts +3 -0
- package/dist/src/internal/png-worker.js +1 -1
- package/dist/src/ios-snapshot-acquisition.js +1 -1
- package/dist/src/ios-snapshot-planning.js +1 -1
- package/dist/src/ios-snapshot-runtime.js +1 -1
- package/dist/src/lease.js +1 -1
- package/dist/src/limrun.d.ts +1 -1
- package/dist/src/local-interactor-operation-set.js +1 -1
- package/dist/src/mechanics.js +16 -16
- package/dist/src/mobile-snapshot-semantics.js +1 -1
- package/dist/src/mp4-atoms.js +1 -0
- package/dist/src/owner-identity.js +3 -3
- package/dist/src/parameterized-recorded-fill.js +1 -1
- package/dist/src/perf-facade.js +1 -1
- package/dist/src/perf-runtime-plan.js +1 -1
- package/dist/src/platform-request-scope.js +1 -1
- package/dist/src/platform-runtime-app-log-process.js +1 -1
- package/dist/src/platform-runtime-managed-owner.js +1 -1
- package/dist/src/platform-runtime-operation-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-android-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-apple-runner-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-finalizer-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-process-host.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 -0
- package/dist/src/png-worker-contract.js +1 -1
- package/dist/src/png.js +1 -0
- package/dist/src/process.js +1 -1
- package/dist/src/provider-webdriver.js +1 -1
- package/dist/src/quality-warnings.js +1 -0
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-runtime.js +1 -1
- package/dist/src/registry.js +36 -37
- package/dist/src/replay.js +1 -1
- package/dist/src/request-admission.js +1 -1
- package/dist/src/request-cancellation.js +1 -1
- package/dist/src/request-runtime-binding.js +1 -1
- package/dist/src/runner-client.js +1 -1
- package/dist/src/runner-disposal.js +1 -1
- package/dist/src/runner-presentation.js +1 -1
- package/dist/src/runtime.js +3 -3
- package/dist/src/runtime10.js +1 -0
- package/dist/src/runtime2.js +4 -4
- package/dist/src/runtime4.js +3 -3
- 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-live-handle.js +1 -1
- package/dist/src/screen-recording-resource-recovery.js +1 -1
- package/dist/src/screenshot-runtime.js +1 -1
- package/dist/src/screenshot3.js +2 -2
- package/dist/src/script.js +1 -1
- package/dist/src/scroll-gesture.js +1 -1
- package/dist/src/sdk-batch.js +1 -1
- package/dist/src/sdk-contracts.d.ts +26 -26
- package/dist/src/sdk-finders.d.ts +1 -1
- package/dist/src/sdk-finders.js +1 -1
- package/dist/src/sdk-remote-config.d.ts +1 -1
- package/dist/src/sdk-selectors.d.ts +12 -4
- 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-snapshot.js +1 -1
- package/dist/src/session-store.js +2 -2
- package/dist/src/session-target-evidence.js +1 -1
- package/dist/src/session2.js +5 -5
- package/dist/src/simulator-boot.js +3 -0
- 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/snapshot4.js +1 -1
- package/dist/src/src.js +1 -1
- package/dist/src/src7.js +1 -1
- package/dist/src/src8.js +2 -2
- package/dist/src/telemetry.js +1 -1
- package/dist/src/touch-reference-frame.js +1 -1
- package/dist/src/tree.js +1 -1
- package/dist/src/type-text-runtime.js +1 -1
- package/dist/src/vars.js +2 -0
- package/dist/src/version.js +1 -1
- package/dist/src/video.js +2 -2
- package/dist/src/viewport.js +1 -0
- package/dist/src/webdriver-ios-snapshot.js +1 -1
- package/package.json +2 -1
- package/server.json +2 -2
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.1.apk.sha256 +0 -1
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.1.apk +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.1.apk.sha256 +0 -1
- package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/recording-trim.swift +0 -93
- package/dist/src/snapshot-quality-verdict.js +0 -1
package/dist/src/mechanics.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime.js";import{C as t,M as n,R as r,d as i,p as a,w as o}from"./sdk-contracts.js";import"./capture.js";import{E as s}from"./sdk-batch-runner.js";import{a as c,d as l,i as u,l as d,o as f,r as p,t as ee,u as te}from"./android-input-ownership.js";import{
|
|
2
|
-
`).map(e=>e.trim()).filter(Boolean)}const
|
|
3
|
-
`):void 0}function $t(e,t){let n=t[0];if(!n)return;let r=en(e,n.index);for(let n of t.slice(1)){let t=new Set(en(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 en(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 tn(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 nn(e){let t=e.bundleId??``;return At.has(t)||Ft.test(e.identifier??``)}function rn(e){let t=e.bundleId??``;return Mt.has(t)&&It.test(w(e))}function an(e){let t=e.type??``,n=e.identifier??``;return!!(e.hittable||/\bbutton\b/i.test(t)||Pt.test(n)||/(?:^|:)id\/permission_(?:allow|deny)/i.test(n))}function w(e){return e?[e.label,e.value].filter(e=>typeof e==`string`&&e.trim().length>0)[0]?.trim()??``:``}function on(e){return e.find(e=>e.bundleId)?.bundleId}function sn(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 T(e,n,r,i){if(e!==r)throw new t(`INVALID_ARGS`,`Android ${i} manifest ${n} must be "${r}".`);return r}function cn(e,n,r){if(typeof e!=`string`||e.length===0)throw new t(`INVALID_ARGS`,`Android ${r} manifest ${n} is required.`);return e}function ln(e,n){let r=cn(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 un(e){let t={status:[],results:[],currentStatus:null,currentResult:null};for(let n of e.split(/\r?\n/))dn(n,t);return fn(t),{status:t.status,results:t.results}}function dn(e,t){if(e.startsWith(`INSTRUMENTATION_STATUS: `)){t.currentStatus??={},hn(e.slice(24),t.currentStatus);return}if(e.startsWith(`INSTRUMENTATION_STATUS_CODE: `)){pn(t);return}if(e.startsWith(`INSTRUMENTATION_RESULT: `)){t.currentResult??={},hn(e.slice(24),t.currentResult);return}e.startsWith(`INSTRUMENTATION_CODE: `)&&mn(t)}function fn(e){pn(e),mn(e)}function pn(e){e.currentStatus&&=(e.status.push(e.currentStatus),null)}function mn(e){e.currentResult&&=(e.results.push(e.currentResult),null)}function hn(e,t){let n=e.indexOf(`=`);n<0||(t[e.slice(0,n)]=e.slice(n+1))}function E(e){if(e===void 0)return;let t=Number(e);return Number.isFinite(t)?t:void 0}function gn(e){if(e===`true`)return!0;if(e===`false`)return!1}function _n(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 vn=1e4;async function yn(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 En(a,o,u);let f=await bn({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 ze(a,{provider:n,replace:!0,allowTestPackages:!0,allowFailure:!0,timeoutMs:l});if(p.exitCode!==0)throw y(`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 bn(e){let{adb:t,adbProvider:n,packageName:r,versionCode:i,sha256:a,signal:o}=e,s=await Cn(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 wn(t,n,r,o);return{installedVersionCode:s,installedSha256:e,reason:e===a?`current`:`mismatched`}}catch{return o?.throwIfAborted(),{installedVersionCode:s,reason:`unverifiable`}}}async function xn(e){let r=v().files,i=Te(),a=C.join(we(),`android`,e.helperDirName,`dist`),o=C.join(a,e.manifestFileName(i));try{let t=e.parseManifest(JSON.parse(await r.readText(o))),n=C.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 Sn(e){return async t=>await yn({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 Cn(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:${On(t)}(?:\\s|$).*versionCode:(\\d+)`).exec(`${r.stdout}\n${r.stderr}`);return i?Number(i[1]):void 0}async function wn(e,n,r,i){let a=await e([`shell`,`pm`,`path`,r],{allowFailure:!0,timeoutMs:vn,signal:i}),o=Tn(`${a.stdout}\n${a.stderr}`);if(a.exitCode!==0||!o)throw new t(`COMMAND_FAILED`,`Could not resolve installed Android helper APK`);let s=v().files,c=await s.makeTempDirectory(`agent-device-helper-`),l=C.join(c,`base.apk`);try{let e=await Ie(o,l,{provider:n,allowFailure:!0,timeoutMs:vn,signal:i});if(e.exitCode!==0)throw y(`Could not read installed Android helper APK`,e,{packageName:r,remotePath:o});return await Dn(l)}finally{await s.remove(c,{recursive:!0,force:!0})}}function Tn(e){return e.split(/\r?\n/).map(e=>e.startsWith(`package:`)?e.slice(8).trim():``).find(e=>e.endsWith(`/base.apk`))}async function En(e,n,r){let i=await Dn(e);if(i!==n)throw new t(`COMMAND_FAILED`,`${r} APK checksum mismatch`,{apkPath:e,expectedSha256:n,actualSha256:i})}async function Dn(e){let t=v().files;return t.sha256(await t.readBytes(e))}function On(e){return e.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`)}const kn=`android-snapshot-helper-v1`,An=`uiautomator-xml`,jn=5e3,Mn=3e4,Nn={"-r":`replace`,"-t":`allowTestPackages`,"-d":`allowDowngrade`,"-g":`grantPermissions`};function D(e){if(!e||typeof e!=`object`||Array.isArray(e))throw new t(`INVALID_ARGS`,`Android snapshot helper manifest must be an object.`);let n=e;return{name:Fn(n.name,`name`,`android-snapshot-helper`),version:O(n.version,`version`),releaseTag:Bn(n.releaseTag),assetName:Bn(n.assetName),apkUrl:Vn(n.apkUrl,`apkUrl`),sha256:zn(n.sha256),checksumName:Bn(n.checksumName),packageName:O(n.packageName,`packageName`),versionCode:Pn(n.versionCode,`versionCode`),instrumentationRunner:O(n.instrumentationRunner,`instrumentationRunner`),minSdk:Pn(n.minSdk,`minSdk`),targetSdk:n.targetSdk===void 0?void 0:Pn(n.targetSdk,`targetSdk`),outputFormat:Fn(n.outputFormat,`outputFormat`,An),statusProtocol:Fn(n.statusProtocol,`statusProtocol`,kn),installArgs:Ln(n.installArgs)}}function Pn(e,t){return sn(e,t,`snapshot helper`)}function Fn(e,t,n){return T(e,t,n,`snapshot helper`)}function In(e){return Rn(Ln(e.installArgs))}function Ln(e){let n=Hn(e,`installArgs`);if(n[0]!==`install`)throw new t(`INVALID_ARGS`,`Android snapshot helper manifest installArgs must start with "install".`);if(n.some(e=>e.includes(`\0`)))throw new t(`INVALID_ARGS`,`Android snapshot helper manifest installArgs must not contain null bytes.`);let r=n.slice(1).find(e=>!Un(e));if(r)throw new t(`INVALID_ARGS`,`Android snapshot helper manifest installArgs contains unsupported install flag "${r}".`);return n}function Rn(e){let n={};for(let r of e.slice(1)){let e=Wn(r);if(!e)throw new t(`INVALID_ARGS`,`Android snapshot helper manifest installArgs contains unsupported install flag "${r}".`);n[e]=!0}return n}function zn(e){let n=O(e,`sha256`).trim().toLowerCase();if(n.length!==64||!Gn(n))throw new t(`INVALID_ARGS`,`Android snapshot helper manifest sha256 must be a 64-character hex string.`);return n}function O(e,n){if(typeof e!=`string`||e.trim().length===0)throw new t(`INVALID_ARGS`,`Android snapshot helper manifest ${n} is required.`);return e}function Bn(e){return typeof e==`string`&&e.trim().length>0?e:void 0}function Vn(e,t){return e===null?null:O(e,t)}function Hn(e,n){if(!Array.isArray(e)||!e.every(e=>typeof e==`string`))throw new t(`INVALID_ARGS`,`Android snapshot helper manifest ${n} must be a string array.`);return e}function Un(e){return Wn(e)!==void 0}function Wn(e){if(Object.hasOwn(Nn,e))return Nn[e]}function Gn(e){for(let t of e){let e=t.charCodeAt(0);if(!(e>=48&&e<=57)&&!(e>=97&&e<=102))return!1}return!0}const k=new Map;function Kn(e){let t=`${e.deviceKey}\0${e.packageName}\0${e.versionCode}\0`;for(let e of k.keys())e.startsWith(t)&&Xn(e)}function qn(){k.clear()}function Jn(e,t,n,r){return e?`${e}\0${t}\0${n}\0${r}`:void 0}function Yn(e,t){if(!e)return;let[n,r]=e.split(`\0`),i=`${n}\0${r}\0`;for(let t of k.keys())t!==e&&t.startsWith(i)&&k.delete(t);k.set(e,t)}function Xn(e){e&&k.delete(e)}async function Zn(e){let{adb:t,artifact:n}=e,r=e.installPolicy??`missing-or-outdated`,i=n.manifest.packageName,a=n.manifest.versionCode,o=n.manifest.sha256;if(r===`never`)return{packageName:i,versionCode:a,installed:!1,reason:`skipped`};let s=Jn(e.deviceKey,i,a,o),c=s?k.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 En(n.apkPath,o,`Android snapshot helper`);let l=r===`always`?{installedVersionCode:await er(t,i,e.timeoutMs,e.signal),reason:`forced`}:await bn({adb:t,adbProvider:$n(e.adbProvider,t),packageName:i,versionCode:a,sha256:o,signal:e.signal}),{installedVersionCode:u}=l,d=`installedSha256`in l?l.installedSha256:void 0,f=l.reason;if(f===`current`){if(u===void 0)throw Error(`Expected installed versionCode for current Android snapshot helper`);return Yn(s,u),{packageName:i,versionCode:a,installedVersionCode:u,installedSha256:d,installed:!1,reason:f}}let p;try{p=await tr(t,e.adbProvider??t,n.apkPath,In(n.manifest),{packageName:i,timeoutMs:e.timeoutMs,signal:e.signal})}catch(e){throw Xn(s),Qn(e,{packageName:i,versionCode:a})}if(p.exitCode!==0)throw Xn(s),Qn(y(`Failed to install Android snapshot helper`,p,{packageName:i,versionCode:a}));return Yn(s,a),{packageName:i,versionCode:a,installedVersionCode:u,installedSha256:d,installed:!0,reason:f}}function Qn(e,t){let n=o(e,`COMMAND_FAILED`);return n.details={...t,...n.details,androidSnapshotHelperInstallFailure:!0},n}function $n(e,t){return e?typeof e==`function`?{exec:e}:e:{exec:t}}async function er(e,t,n,r){let i=await e([`shell`,`cmd`,`package`,`list`,`packages`,`--show-versioncode`,t],{allowFailure:!0,timeoutMs:n,signal:r});if(i.exitCode===0)return nr(`${i.stdout}\n${i.stderr}`,t)}async function tr(e,t,n,r,i){let a=async()=>await ze(n,{allowFailure:!0,provider:t,...r,timeoutMs:i.timeoutMs,signal:i.signal}),o=await a();if(o.exitCode===0||!rr(o))return o;let s=await e([`uninstall`,i.packageName],{allowFailure:!0,timeoutMs:i.timeoutMs,signal:i.signal}),c=await a();return c.exitCode===0?c:{...c,stderr:[c.stderr,s.stderr?`Previous uninstall stderr after INSTALL_FAILED_UPDATE_INCOMPATIBLE: ${s.stderr}`:``].filter(Boolean).join(`
|
|
4
|
-
`)}}function
|
|
1
|
+
import{r as e}from"./rolldown-runtime.js";import{C as t,M as n,R as r,d as i,p as a,w as o}from"./sdk-contracts.js";import"./capture.js";import{E as s}from"./sdk-batch-runner.js";import{a as c,d as l,i as u,l as d,o as f,r as p,t as ee,u as te}from"./android-input-ownership.js";import{Lr as ne,Rr as re,Vr as ie,zr as ae}from"./sdk-batch.js";import{i as oe,n as se,r as ce}from"./snapshot-scope.js";import{_ as le,d as ue,p as de}from"./scroll-gesture.js";import{n as fe}from"./success-text.js";import{n as pe}from"./alert-contract.js";import{c as me,n as he,s as ge}from"./location-coordinates.js";import{r as _e}from"./mobile-snapshot-semantics.js";import"./device.js";import{n as ve}from"./device-rotation.js";import{c as m,r as h}from"./diagnostics.js";import{a as ye,c as be,m as xe,n as Se,s as Ce}from"./exec.js";import{t as g}from"./timeouts.js";import{i as we}from"./tv-remote.js";import"./diagnostics2.js";import{r as Te}from"./command.js";import"./retry.js";import{n as Ee,r as De}from"./version.js";import{n as Oe,r as ke}from"./install-source2.js";import{a as Ae,i as je,n as _,r as v}from"./adb-host.js";import{i as Me,n as y,o as Ne}from"./adb-failure.js";import{a as b,c as Pe,d as Fe,i as Ie,l as Le,n as Re,o as x,r as ze,s as Be,t as Ve,u as He}from"./adb-executor.js";import{n as Ue,r as S}from"./adb.js";import{i as We,n as Ge,r as Ke}from"./gesture-plan.js";import{n as qe,r as Je,s as Ye}from"./android-system-chrome.js";import{a as Xe,c as Ze,i as Qe,l as $e,n as et,o as tt,r as nt,s as rt,u as it}from"./app-lifecycle.js";import{a as at,i as ot,n as st,o as ct,r as lt,t as ut}from"./app-deployment-resolution.js";import{a as dt,i as ft,n as pt,o as mt,t as ht}from"./app-parsers.js";import{i as gt,n as _t,r as vt,t as yt}from"./window-state.js";import{n as bt}from"./toolchain-probe.js";import{t as xt}from"./keyed-lock.js";import{t as St}from"./bounds.js";import{t as Ct}from"./entities.js";import{n as wt}from"./startup-recovery-fence.js";import{n as Tt}from"./numeric.js";import C from"node:path";import Et from"node:net";import{TextDecoder as Dt}from"node:util";const Ot=new Map;async function kt(e){let t=Ot.get(e.deviceKey);if(t!==void 0)return t;let n;try{let t=await e.adb([`features`],{allowFailure:!0,timeoutMs:2e3,...e.signal?{signal:e.signal}:{}});if(t.exitCode!==0)return!1;n=t.stdout}catch{return!1}let r=jt(n).includes(`shell_v2`);return Ot.set(e.deviceKey,r),r}function At(){Ot.clear()}function jt(e){return e.split(`
|
|
2
|
+
`).map(e=>e.trim()).filter(Boolean)}const Mt=new Set([`com.android.permissioncontroller`,`com.google.android.permissioncontroller`,`com.google.android.packageinstaller`,`com.android.packageinstaller`]);function Nt(e){return Mt.has(e)}const Pt=new Set([`android`,`com.android.systemui`]),Ft=/^android:id\/(?:alertTitle|message|button[123]|parentPanel|buttonPanel|contentPanel)$/i,It=/^android:id\/button[123]$/i,Lt=/(?:^|:)id\/permission_/i,Rt=/\b(?:is(?:n't| not) responding|keeps stopping|has stopped|close app|app info)\b/i,zt=/^(?:ok|allow|allow all|while using the app|only this time|yes|continue|save|confirm|turn on|open settings)$/i,Bt=/^(?:cancel|deny|don.t allow|don’t allow|not now|no|dismiss|close|close app|later|skip)$/i;function Vt(e){if(e!==null){if(It.test(e))return`button`;if(Ft.test(e))return`content`}}function Ht(e){let t=Gt(e.filter(Ut)),n=t.nodes;if(n.length===0)return null;let r=Xt(n),i=n.filter(e=>w(e)&&!sn(e)),a=$t(i),o=en(i,a);if(!a&&!o&&r.length===0)return null;let s=cn(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 Ut(e){return!d(e)}function Wt(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 Gt(e){let t=e.filter(e=>an(e));if(t.length)return{nodes:t,source:`permission`};let n=Yt(e);return n.length?{nodes:n,source:`system-dialog`}:{nodes:Kt(e),source:`native-dialog`}}function Kt(e){let t=e.filter(e=>qt(e.type??``)),n=e.filter(e=>Ft.test(e.identifier??``)),r=t.length?[...t,...n]:Jt(n);if(r.length===0)return[];let i=tn(e,r);return i===void 0?r:rn(e,i)}function qt(e){let t=Math.max(e.lastIndexOf(`.`),e.lastIndexOf(`$`));return e.slice(t+1).toLowerCase().endsWith(`dialog`)}function Jt(e){let t=e.some(e=>It.test(e.identifier??``)),n=e.some(e=>!It.test(e.identifier??``));return t&&n?e:[]}function Yt(e){let t=e.filter(e=>on(e));if(t.length===0)return[];let n=tn(e,t);return n===void 0?t:rn(e,n).filter(e=>e.bundleId&&Pt.has(e.bundleId))}function Xt(e){let t=new Set,n=[];for(let r of e){let e=w(r);if(!e||!r.rect||!sn(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:Zt(r,e)})}return n}function Zt(e,t){return Qt(e.identifier??``)||(zt.test(t.trim())?`accept`:Bt.test(t.trim())?`dismiss`:`neutral`)}function Qt(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 $t(e){return w(e.find(e=>/(?:^|:)id\/(?:alertTitle|permission_message)$/i.test(e.identifier??``)))||w(e[0])}function en(e,t){let n=e.map(e=>w(e)).filter(e=>e&&e!==t);return n.length?[...new Set(n)].join(`
|
|
3
|
+
`):void 0}function tn(e,t){let n=t[0];if(!n)return;let r=nn(e,n.index);for(let n of t.slice(1)){let t=new Set(nn(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 nn(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 rn(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 an(e){let t=e.bundleId??``;return Mt.has(t)||Lt.test(e.identifier??``)}function on(e){let t=e.bundleId??``;return Pt.has(t)&&Rt.test(w(e))}function sn(e){let t=e.type??``,n=e.identifier??``;return!!(e.hittable||/\bbutton\b/i.test(t)||It.test(n)||/(?:^|:)id\/permission_(?:allow|deny)/i.test(n))}function w(e){return e?[e.label,e.value].filter(e=>typeof e==`string`&&e.trim().length>0)[0]?.trim()??``:``}function cn(e){return e.find(e=>e.bundleId)?.bundleId}function ln(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 T(e,n,r,i){if(e!==r)throw new t(`INVALID_ARGS`,`Android ${i} manifest ${n} must be "${r}".`);return r}function un(e,n,r){if(typeof e!=`string`||e.length===0)throw new t(`INVALID_ARGS`,`Android ${r} manifest ${n} is required.`);return e}function dn(e,n){let r=un(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 fn(e){let t={status:[],results:[],currentStatus:null,currentResult:null};for(let n of e.split(/\r?\n/))pn(n,t);return mn(t),{status:t.status,results:t.results}}function pn(e,t){if(e.startsWith(`INSTRUMENTATION_STATUS: `)){t.currentStatus??={},_n(e.slice(24),t.currentStatus);return}if(e.startsWith(`INSTRUMENTATION_STATUS_CODE: `)){hn(t);return}if(e.startsWith(`INSTRUMENTATION_RESULT: `)){t.currentResult??={},_n(e.slice(24),t.currentResult);return}e.startsWith(`INSTRUMENTATION_CODE: `)&&gn(t)}function mn(e){hn(e),gn(e)}function hn(e){e.currentStatus&&=(e.status.push(e.currentStatus),null)}function gn(e){e.currentResult&&=(e.results.push(e.currentResult),null)}function _n(e,t){let n=e.indexOf(`=`);n<0||(t[e.slice(0,n)]=e.slice(n+1))}function E(e){if(e===void 0)return;let t=Number(e);return Number.isFinite(t)?t:void 0}function vn(e){if(e===`true`)return!0;if(e===`false`)return!1}function yn(e){if(!Number.isFinite(e.x)||!Number.isFinite(e.y)||!Number.isFinite(e.width)||!Number.isFinite(e.height)||e.width<=0||e.height<=0)throw new t(`COMMAND_FAILED`,`Android helper returned an invalid gesture viewport`);return e}const bn=1e4;async function xn(e){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 On(a,o,u);let f=await Sn({adb:t,adbProvider:n,packageName:r,versionCode:i,sha256:o});if(f.reason===`current`)return s.add(d),{packageName:r,versionCode:i,...f,installed:!1};let p=await Ve(a,{provider:n,replace:!0,allowTestPackages:!0,allowFailure:!0,timeoutMs:l});if(p.exitCode!==0)throw y(`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 Sn(e){let{adb:t,adbProvider:n,packageName:r,versionCode:i,sha256:a,signal:o}=e,s=await Tn(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 En(t,n,r,o);return{installedVersionCode:s,installedSha256:e,reason:e===a?`current`:`mismatched`}}catch{return o?.throwIfAborted(),{installedVersionCode:s,reason:`unverifiable`}}}async function Cn(e){let r=v().files,i=De(),a=C.join(Ee(),`android`,e.helperDirName,`dist`),o=C.join(a,e.manifestFileName(i));try{let t=e.parseManifest(JSON.parse(await r.readText(o))),n=C.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 wn(e){return async t=>await xn({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 Tn(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:${An(t)}(?:\\s|$).*versionCode:(\\d+)`).exec(`${r.stdout}\n${r.stderr}`);return i?Number(i[1]):void 0}async function En(e,n,r,i){let a=await e([`shell`,`pm`,`path`,r],{allowFailure:!0,timeoutMs:bn,signal:i}),o=Dn(`${a.stdout}\n${a.stderr}`);if(a.exitCode!==0||!o)throw new t(`COMMAND_FAILED`,`Could not resolve installed Android helper APK`);let s=v().files,c=await s.makeTempDirectory(`agent-device-helper-`),l=C.join(c,`base.apk`);try{let e=await Re(o,l,{provider:n,allowFailure:!0,timeoutMs:bn,signal:i});if(e.exitCode!==0)throw y(`Could not read installed Android helper APK`,e,{packageName:r,remotePath:o});return await kn(l)}finally{await s.remove(c,{recursive:!0,force:!0})}}function Dn(e){return e.split(/\r?\n/).map(e=>e.startsWith(`package:`)?e.slice(8).trim():``).find(e=>e.endsWith(`/base.apk`))}async function On(e,n,r){let i=await kn(e);if(i!==n)throw new t(`COMMAND_FAILED`,`${r} APK checksum mismatch`,{apkPath:e,expectedSha256:n,actualSha256:i})}async function kn(e){let t=v().files;return t.sha256(await t.readBytes(e))}function An(e){return e.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`)}const jn=`android-snapshot-helper-v1`,Mn=`uiautomator-xml`,Nn=5e3,Pn=3e4,Fn={"-r":`replace`,"-t":`allowTestPackages`,"-d":`allowDowngrade`,"-g":`grantPermissions`};function D(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:Ln(n.name,`name`,`android-snapshot-helper`),version:O(n.version,`version`),releaseTag:Hn(n.releaseTag),assetName:Hn(n.assetName),apkUrl:Un(n.apkUrl,`apkUrl`),sha256:Vn(n.sha256),checksumName:Hn(n.checksumName),packageName:O(n.packageName,`packageName`),versionCode:In(n.versionCode,`versionCode`),instrumentationRunner:O(n.instrumentationRunner,`instrumentationRunner`),minSdk:In(n.minSdk,`minSdk`),targetSdk:n.targetSdk===void 0?void 0:In(n.targetSdk,`targetSdk`),outputFormat:Ln(n.outputFormat,`outputFormat`,Mn),statusProtocol:Ln(n.statusProtocol,`statusProtocol`,jn),installArgs:zn(n.installArgs)}}function In(e,t){return ln(e,t,`snapshot helper`)}function Ln(e,t,n){return T(e,t,n,`snapshot helper`)}function Rn(e){return Bn(zn(e.installArgs))}function zn(e){let n=Wn(e,`installArgs`);if(n[0]!==`install`)throw new t(`INVALID_ARGS`,`Android snapshot helper manifest installArgs must start with "install".`);if(n.some(e=>e.includes(`\0`)))throw new t(`INVALID_ARGS`,`Android snapshot helper manifest installArgs must not contain null bytes.`);let r=n.slice(1).find(e=>!Gn(e));if(r)throw new t(`INVALID_ARGS`,`Android snapshot helper manifest installArgs contains unsupported install flag "${r}".`);return n}function Bn(e){let n={};for(let r of e.slice(1)){let e=Kn(r);if(!e)throw new t(`INVALID_ARGS`,`Android snapshot helper manifest installArgs contains unsupported install flag "${r}".`);n[e]=!0}return n}function Vn(e){let n=O(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 O(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 Hn(e){return typeof e==`string`&&e.trim().length>0?e:void 0}function Un(e,t){return e===null?null:O(e,t)}function Wn(e,n){if(!Array.isArray(e)||!e.every(e=>typeof e==`string`))throw new t(`INVALID_ARGS`,`Android snapshot helper manifest ${n} must be a string array.`);return e}function Gn(e){return Kn(e)!==void 0}function Kn(e){if(Object.hasOwn(Fn,e))return Fn[e]}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 k=new Map;function Jn(e){let t=`${e.deviceKey}\0${e.packageName}\0${e.versionCode}\0`;for(let e of k.keys())e.startsWith(t)&&Qn(e)}function Yn(){k.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 k.keys())t!==e&&t.startsWith(i)&&k.delete(t);k.set(e,t)}function Qn(e){e&&k.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?k.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 On(n.apkPath,o,`Android snapshot helper`);let l=r===`always`?{installedVersionCode:await nr(t,i,e.timeoutMs,e.signal),reason:`forced`}:await Sn({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,Rn(n.manifest),{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(y(`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=o(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,i){let a=async()=>await Ve(n,{allowFailure:!0,provider:t,...r,timeoutMs:i.timeoutMs,signal:i.signal}),o=await a();if(o.exitCode===0||!ar(o))return o;let s=await e([`uninstall`,i.packageName],{allowFailure:!0,timeoutMs:i.timeoutMs,signal:i.signal}),c=await a();return c.exitCode===0?c:{...c,stderr:[c.stderr,s.stderr?`Previous uninstall stderr after INSTALL_FAILED_UPDATE_INCOMPATIBLE: ${s.stderr}`:``].filter(Boolean).join(`
|
|
4
|
+
`)}}function ir(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 ar(e){return`${e.stdout}\n${e.stderr}`.includes(`INSTALL_FAILED_UPDATE_INCOMPATIBLE`)}function or(e){return e.errorType===`java.util.concurrent.TimeoutException`?`accessibility-timeout`:void 0}function sr(e){return e===137?`accessibility-timeout`:void 0}function A(e){return e?{androidCaptureFailureReason:e}:{}}function cr(){return new Promise((e,t)=>{let n=Et.createServer();n.unref(),n.on(`error`,t),n.listen(0,`127.0.0.1`,()=>{let r=n.address();if(!r||typeof r==`string`){n.close(()=>t(Error(`Failed to allocate a local TCP port`)));return}let i=r.port;n.close(()=>e(i))})})}function lr(e,n,r,i){return new Promise((a,o)=>{let s=Et.connect({host:`127.0.0.1`,port:e}),c=[],l=setTimeout(()=>{u(),s.destroy(),o(new t(`COMMAND_FAILED`,`Android snapshot helper session request timed out`,{command:n,timeoutMs:r,port:e}))},r),u=()=>{clearTimeout(l),i?.removeEventListener(`abort`,d)},d=()=>{u(),s.destroy(),o(i?.reason??new DOMException(`The operation was aborted`,`AbortError`))};if(i?.addEventListener(`abort`,d,{once:!0}),i?.aborted){d();return}s.on(`connect`,()=>s.write(`${n}\n`)),s.on(`data`,e=>c.push(Buffer.from(e))),s.on(`error`,e=>{u(),o(e)}),s.on(`close`,()=>{u(),a(Buffer.concat(c).toString(`utf8`))})})}async function ur(e){let t=`snapshot-${Date.now()}-${Math.random().toString(16).slice(2)}`;return gr(await lr(e.port,`snapshot ${t}`,dr(e),e.signal),t)}function dr(e){return Math.min(e.commandTimeoutMs,Math.max(e.timeoutMs+3e3,3e3))}function fr(e,n,r){return new Promise((i,a)=>{let o=``,s=setTimeout(()=>{r?.removeEventListener(`abort`,l),a(new t(`COMMAND_FAILED`,`Android snapshot helper session did not become ready`,{output:o,timeoutMs:n}))},n),c=e=>{o+=e.toString(),o.includes(`agentDeviceProtocol=android-snapshot-helper-v1`)&&o.includes(`sessionReady=true`)&&(clearTimeout(s),r?.removeEventListener(`abort`,l),i())},l=()=>{clearTimeout(s),a(r?.reason??new DOMException(`The operation was aborted`,`AbortError`))};if(r?.addEventListener(`abort`,l,{once:!0}),r?.aborted){l();return}e.stdout?.on(`data`,c),e.stderr?.on(`data`,c),e.once(`exit`,(e,n)=>{clearTimeout(s),r?.removeEventListener(`abort`,l),a(new t(`COMMAND_FAILED`,`Android snapshot helper session exited before ready`,{output:o,exitCode:e,signal:n}))}),e.on(`error`,e=>{clearTimeout(s),r?.removeEventListener(`abort`,l),a(e)})})}function pr(e){let t=e.indexOf(`
|
|
5
5
|
|
|
6
|
-
`);return
|
|
6
|
+
`);return yr(e.slice(0,t<0?e.length:t))}function mr(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 hr(e,t){let n=pr(e);return n.agentDeviceProtocol===`android-snapshot-helper-v1`&&n.requestId===t&&n.ok===`true`}function gr(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=_r(e.slice(0,r)),a=e.slice(r+2);return hr(i,n),gr(i,a),{xml:a,metadata:vr(i)}}function hr(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,...A(ir(e))})}function gr(e,n){let r=E(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 _r(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 vr(e){return{helperApiVersion:e.helperApiVersion,outputFormat:An,waitForIdleTimeoutMs:E(e.waitForIdleTimeoutMs),waitForIdleQuietMs:E(e.waitForIdleQuietMs),timeoutMs:E(e.timeoutMs),maxDepth:E(e.maxDepth),maxNodes:E(e.maxNodes),rootPresent:gn(e.rootPresent),captureMode:e.captureMode===`interactive-windows`||e.captureMode===`active-window`?e.captureMode:void 0,windowCount:E(e.windowCount),nodeCount:E(e.nodeCount),truncated:gn(e.truncated),elapsedMs:E(e.elapsedMs)}}const yr=2e3,br=`android_snapshot_helper_retirement_unconfirmed`,j=new Map;function M(e){return`${e.platform}:${e.id}`}async function xr(e){await Ar({adb:e.adb,packageName:e.packageName,timeoutMs:2e3})||N(e)}async function Sr(e){let t=j.get(e.deviceKey);if(t){try{let n=await e.adb([`shell`,`am`,`force-stop`,t.packageName],{allowFailure:!0,timeoutMs:5e3,signal:e.signal});if(e.signal?.throwIfAborted(),n.exitCode===0){j.delete(e.deviceKey);return}}catch{e.signal?.throwIfAborted()}N({deviceKey:e.deviceKey,packageName:t.packageName,cause:t.cause})}}function N(e){let n=e.cause instanceof Error?e.cause.message:String(e.cause);throw j.set(e.deviceKey,{packageName:e.packageName,cause:n}),new t(`COMMAND_FAILED`,`Android snapshot helper could not confirm release of device automation ownership`,{reason:br,deviceKey:e.deviceKey,cause:n,hint:`Retry after the helper process exits, or restart the device if Android still reports automation as busy.`})}function Cr(e){return e instanceof t&&e.details?.reason===br}async function wr(e){let t=AbortSignal.timeout(e.timeoutMs),[n]=await Promise.allSettled([e.forceStopRuntime?Ar({adb:e.adb,packageName:e.packageName,timeoutMs:e.timeoutMs,signal:t}):Promise.resolve(!1),jr({...e,signal:t})]);return{timedOut:t.aborted,runtimeForceStopped:n?.status===`fulfilled`&&n.value}}function Tr(e){let t=Er(e);return{ended:t?Promise.resolve():new Promise(t=>{e.once(`close`,()=>t()),e.once(`exit`,()=>t())}),hasEnded:()=>Er(e),completedCleanly:()=>!t&&e.exitCode===0&&e.signalCode==null}}function Er(e){return e.exitCode!=null||e.signalCode!=null}async function Dr(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 Or(e){if(e.processExit.hasEnded())return!0;try{e.process.kill(`SIGTERM`)}catch{}return await Dr(e.processExit.ended,e.timeoutMs)}function kr(){j.clear()}async function Ar(e){let t=e.signal??AbortSignal.timeout(e.timeoutMs);try{return(await e.adb([`shell`,`am`,`force-stop`,e.packageName],{allowFailure:!0,timeoutMs:e.timeoutMs,signal:t})).exitCode===0}catch{return!1}}async function jr(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 Mr(e){let n=Pr(e),r=e.deviceKey??`android:default`;await Sr({deviceKey:r,adb:e.adb,signal:e.signal});let i;try{i=await e.adb(Fr(n),{allowFailure:!0,timeoutMs:n.commandTimeoutMs,signal:e.signal})}catch(t){throw e.signal?.aborted?(await xr({deviceKey:r,packageName:n.packageName,adb:e.adb,cause:t}),e.signal.throwIfAborted(),t):t}e.signal?.aborted&&(await xr({deviceKey:r,packageName:n.packageName,adb:e.adb,cause:e.signal.reason}),e.signal.throwIfAborted());let{output:a,cleanupDone:o}=await Ir(e,n,i);if(n.outputPath&&!o&&await Ur(e.adb,n.outputPath),i.exitCode!==0)throw new t(`COMMAND_FAILED`,`Android snapshot helper failed`,be(i,{helper:a.metadata}));return a}function Nr(e){return{adb:e.adb,adbProvider:e.adbProvider,deviceKey:e.deviceKey,helperVersion:e.artifact.manifest.version,helperVersionCode:e.artifact.manifest.versionCode,helperSha256:e.artifact.manifest.sha256,packageName:e.artifact.manifest.packageName,instrumentationRunner:e.artifact.manifest.instrumentationRunner,waitForIdleTimeoutMs:500,timeoutMs:jn,commandTimeoutMs:Mn,...e.signal?{signal:e.signal}:{}}}function Pr(e){let t=P(e.timeoutMs,8e3),n=P(e.packageName,`com.callstack.agentdevice.snapshothelper`);return{waitForIdleTimeoutMs:P(e.waitForIdleTimeoutMs,500),waitForIdleQuietMs:P(e.waitForIdleQuietMs,100),timeoutMs:t,commandTimeoutMs:P(e.commandTimeoutMs,t+5e3),maxDepth:P(e.maxDepth,128),maxNodes:P(e.maxNodes,5e3),packageName:n,runner:P(e.instrumentationRunner,`${n}/.SnapshotInstrumentation`),...e.outputPath?{outputPath:e.outputPath}:{},...e.emitChunks===void 0?{}:{emitChunks:e.emitChunks}}}function P(e,t){return e===void 0?t:e}function Fr(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 Ir(e,t,n){try{return{output:Wr(`${n.stdout}\n${n.stderr}`),cleanupDone:!1}}catch(r){return await Lr(e,t,n,r)}}async function Lr(e,n,r,i){if(i instanceof t&&r.exitCode!==0&&i.details?.helper)throw i;let a=await Rr(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,...A(ar(r.exitCode))},i)}async function Rr(e,t,n){if(!(n.exitCode!==0||!t.outputPath))return await Br(e.adb,t.outputPath,Hr(`${n.stdout}\n${n.stderr}`)??zr(t))}function zr(e){return{outputFormat:An,waitForIdleTimeoutMs:e.waitForIdleTimeoutMs,waitForIdleQuietMs:e.waitForIdleQuietMs,timeoutMs:e.timeoutMs,maxDepth:e.maxDepth,maxNodes:e.maxNodes,transport:`instrumentation`}}async function Br(e,t,n){let r;try{r=await e(Vr(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 Vr(e){return[`shell`,`sh`,`-c`,`cat "$1"; status=$?; rm -f "$1"; exit "$status"`,`agent-device-snapshot-helper-output`,e]}function Hr(e){try{return Qr(Kr(un(e).results))}catch{return null}}async function Ur(e,t){try{await e([`shell`,`rm`,`-f`,t],{allowFailure:!0,timeoutMs:5e3})}catch{}}function Wr(e){let t=un(e),n=Kr(t.results);return{xml:Jr(Gr(t.status),n),metadata:{...Qr(n),transport:`instrumentation`}}}function Gr(e){let t=[];for(let n of e){if(n.agentDeviceProtocol!==`android-snapshot-helper-v1`||n.outputFormat!==`uiautomator-xml`)continue;let{payloadBase64:e}=n;e!==void 0&&t.push({index:F(n.chunkIndex),count:F(n.chunkCount),payloadBase64:e})}return t}function Kr(e){let n=e.find(e=>e.agentDeviceProtocol===kn);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`,qr(n),{errorType:n.errorType,helper:n,...A(ir(n))});return n}function qr(e){return e.message&&e.message!==`null`?e.message:e.errorType||`Android snapshot helper returned an error`}function Jr(e,n){if(e.length===0)throw new t(`COMMAND_FAILED`,`Android snapshot helper did not return XML chunks`,{helper:n});let r=Yr(e),i=Buffer.concat(Zr(Xr(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 Yr(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 Xr(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 Zr(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 Qr(e){return{helperApiVersion:e.helperApiVersion,outputFormat:An,waitForIdleTimeoutMs:F(e.waitForIdleTimeoutMs),waitForIdleQuietMs:F(e.waitForIdleQuietMs),timeoutMs:F(e.timeoutMs),maxDepth:F(e.maxDepth),maxNodes:F(e.maxNodes),rootPresent:ei(e.rootPresent),captureMode:$r(e.captureMode),windowCount:F(e.windowCount),nodeCount:F(e.nodeCount),truncated:ei(e.truncated),elapsedMs:F(e.elapsedMs)}}function $r(e){return e===`interactive-windows`||e===`active-window`?e:void 0}const F=E,ei=gn,ti=5e3,I=new Map,ni=new Map;async function ri(e){return await ii(e)!==void 0}async function ii(e){let t=e.deviceKey??`android:default`;if(await Sr({deviceKey:t,adb:e.adb,signal:e.signal}),!ui()||!e.adbProvider?.spawn)return;let n=li(Pr(e)),r=await oi({deviceKey:t,identity:ci(t,n,e),options:e,resolved:n});return r?{session:r,resolved:n,deviceKey:t}:void 0}function ai(e){return I.get(e)}async function oi(e){let{deviceKey:t,identity:n,options:r,resolved:i}=e;if(ni.get(t)===n)return;let a=I.get(t);if(a&&a.identity!==n&&(await L(t),a=void 0),!a)try{a=await si({deviceKey:t,identity:n,options:r,resolved:i})}catch(e){if(r.signal?.throwIfAborted(),ni.set(t,n),h({level:`warn`,phase:`android_snapshot_helper_session_disabled`,data:{deviceKey:t,reason:e instanceof Error?e.message:String(e)}}),Cr(e))throw e;return}return a}async function si(e){let n=await or();await e.options.adb([`forward`,`tcp:${n}`,`tcp:${n}`],{allowFailure:!1,timeoutMs:ti,signal:e.options.signal});let r=Fr({...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 ur(o,1e4,e.options.signal),I.set(e.deviceKey,s),h({phase:`android_snapshot_helper_session_ready`,data:{deviceKey:e.deviceKey,port:n,packageName:e.resolved.packageName,runner:e.resolved.runner}}),s}catch(t){let n=Tr(o);try{o.kill(`SIGTERM`)}catch{}let[,r]=await Promise.all([Dr(n.ended,250),wr({adb:s.adb,process:s.process,port:s.port,packageName:s.helper.packageName,timeoutMs:yr,forceStopRuntime:!0})]);throw r.runtimeForceStopped||N({deviceKey:e.deviceKey,packageName:s.helper.packageName,cause:t}),t}}function ci(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 li(e){let t=Math.min(e.timeoutMs,2e3);return{...e,timeoutMs:t,commandTimeoutMs:Math.min(e.commandTimeoutMs,t+3e3)}}function ui(){let e=v().environment.AGENT_DEVICE_ANDROID_SNAPSHOT_HELPER_SESSION;return e===void 0||!/^(0|false|no|off)$/i.test(e)}async function L(e,t={}){let n=I.get(e);if(!n)return!1;I.delete(e);let r=Tr(n.process),i=t.force===!0||t.signal?.aborted===!0,a=await di(n,r,i,t.signal),o=r.hasEnded(),s=a.acknowledged&&a.exited,c=s&&await Dt({adb:n.adb,deviceKey:e,signal:t.signal}),l=i?t.signal?.aborted===!0?250:yr:ti,u=i?250:2e3,[d,f]=await Promise.all([Or({process:n.process,processExit:r,timeoutMs:u}),wr({adb:n.adb,process:n.process,port:n.port,packageName:n.helper.packageName,timeoutMs:l,forceStopRuntime:t.resetRuntime===!0||!c})]);return h({phase:`android_snapshot_helper_session_stop`,data:{deviceKey:e,port:n.port,capturedCount:n.capturedCount,lifetimeMs:Date.now()-n.startedAtMs,quitAcknowledged:a.acknowledged,quitExitObserved:s,runtimeReleaseConfirmed:c,forceKilled:!o&&d,forced:i||t.signal?.aborted===!0,runtimeForceStopped:f.runtimeForceStopped,externalCleanupTimedOut:f.timedOut}}),!c&&!f.runtimeForceStopped&&N({deviceKey:e,packageName:n.helper.packageName,cause:t.cause}),!0}async function di(e,t,n,r){if(n)return{acknowledged:!1,exited:!1};let i=`quit-${Date.now()}`;try{let n=pr(await sr(e.port,`quit ${i}`,1e3,r),i);return{acknowledged:n,exited:n&&await Dr(t.ended,11e3,r)&&t.completedCleanly()}}catch{return{acknowledged:!1,exited:!1}}}async function fi(e){await L(M(e))}async function pi(){let e=await Promise.allSettled([...I.keys()].map(e=>L(e)));ni.clear();let t=e.filter(e=>e.status===`rejected`).map(e=>e.reason);if(t.length>0)throw AggregateError(t,`Failed to retire every Android snapshot helper session`);kr(),Ot()}async function mi(e){let t=await ii(e);if(t)return await hi({session:t.session,deviceKey:t.deviceKey,options:e,resolved:t.resolved})}async function hi(e){let{session:t,deviceKey:n,options:r,resolved:i}=e;try{let e=t.capturedCount>0,n=await cr({port:t.port,timeoutMs:i.timeoutMs,commandTimeoutMs:i.commandTimeoutMs,signal:r.signal});return t.capturedCount+=1,{xml:n.xml,metadata:{...n.metadata,transport:`persistent-session`,sessionReused:e}}}catch(e){await L(n,{force:!0,signal:r.signal,cause:e}),r.signal?.throwIfAborted(),h({level:`warn`,phase:`android_snapshot_helper_session_fallback`,data:{deviceKey:n,reason:e instanceof Error?e.message:String(e),uiAutomationConnectionTimeout:qe(e)===`accessibility-timeout`}});return}}async function gi(e){let n=ai(e.deviceKey);if(!n)return;if(!_i(n.helper,e.helper)){h({level:`warn`,phase:`android_snapshot_helper_session_touch_identity_mismatch`,data:{deviceKey:e.deviceKey,sessionHelper:n.helper,requestedHelper:e.helper}}),await L(e.deviceKey);return}let r=`${e.action}-${Date.now()}-${Math.random().toString(16).slice(2)}`,i=e.payloadBase64?`${e.action} ${r} ${e.payloadBase64}`:`${e.action} ${r}`,a;try{a=dr(await sr(n.port,i,e.timeoutMs)),fr(a,r)}catch(t){throw await L(e.deviceKey),t}if(a.ok!==`true`)throw new t(`COMMAND_FAILED`,a.message||a.errorType||`Android automation helper ${e.action} failed`,{errorType:a.errorType,helper:a});return a}function _i(e,t){return e.packageName===t.packageName&&e.runner===t.runner&&vi(e.helperVersion,t.helperVersion)&&vi(e.helperVersionCode,t.helperVersionCode)&&vi(e.sha256,t.sha256)}function vi(e,t){return e===void 0||t===void 0||e===t}const yi=`android-touch-plan-v1`,bi=45e3,xi=`ANDROID_TOUCH_HELPER_NO_FINAL_RESULT`,Si=`ANDROID_TOUCH_HELPER_REPORTED_FAILURE`;async function Ci(e,t){let n=await Ei(e),r=Oi(t),i=Math.max(45e3,r.durationMs+15e3),a=Buffer.from(JSON.stringify({protocol:yi,...r})).toString(`base64`),o=await m(`android_touch_helper_gesture`,async()=>{let e=await gi({deviceKey:n.deviceKey,action:`gesture`,helper:Ti(n.artifact),payloadBase64:a,timeoutMs:i});return e?{...Mi(e),helperTransport:`persistent-session`}:{...await Ai({adb:n.adb,runner:n.artifact.manifest.instrumentationRunner,extraArgs:[`-e`,`mode`,`gesture`,`-e`,`payloadBase64`,a],timeoutMs:i,readResult:Mi}),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 wi(e,t={}){let n=await Ei(e);t.helperSessionScope===`daemon-session`&&await ri(Nr({adb:n.adb,adbProvider:n.adbProvider,artifact:n.artifact,deviceKey:n.deviceKey}));try{let e=await gi({deviceKey:n.deviceKey,action:`viewport`,helper:Ti(n.artifact),timeoutMs:bi});if(e)return Ni(e)}catch(e){await L(n.deviceKey),h({level:`warn`,phase:`android_touch_helper_viewport_session_fallback`,data:{reason:e instanceof Error?e.message:String(e)}})}return await Ai({adb:n.adb,runner:n.artifact.manifest.instrumentationRunner,extraArgs:[`-e`,`mode`,`viewport`],timeoutMs:bi,readResult:Ni})}function Ti(e){return{packageName:e.manifest.packageName,runner:e.manifest.instrumentationRunner,helperVersion:e.manifest.version,helperVersionCode:e.manifest.versionCode,sha256:e.manifest.sha256}}async function Ei(e){let t=x(e),n=t.snapshotHelperArtifact??await Di(),r=M(e);await Sr({deviceKey:r,adb:t.exec});let i=await m(`android_touch_helper_install`,async()=>await Zn({adb:t.exec,adbProvider:t,artifact:n,deviceKey:r,timeoutMs:3e4}),{packageName:n.manifest.packageName,versionCode:n.manifest.versionCode});return h({phase:`android_touch_helper_install_decision`,data:i}),i.installed&&await L(r),{adb:t.exec,adbProvider:t,artifact:n,install:i,deviceKey:r}}async function Di(){return await xn({helperDirName:`snapshot-helper`,manifestFileName:e=>`agent-device-android-snapshot-helper-${e}.manifest.json`,parseManifest:e=>{let t=D(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 Oi(e){return{kind:e.topology===`single`?`swipe`:`transform`,durationMs:e.durationMs,pointers:e.pointers.map(ki)}}function ki(e){return{pointerId:e.pointerId,samples:e.samples.map(({offsetMs:e,point:t})=>({offsetMs:e,x:t.x,y:t.y}))}}async function Ai(e){let n=await e.adb([`shell`,`am`,`instrument`,`-w`,...e.extraArgs,e.runner],{allowFailure:!0,timeoutMs:e.timeoutMs}),r;try{r=ji(`${n.stdout}\n${n.stderr}`)}catch(e){if(e instanceof t){if(e.code===Si)throw new t(`COMMAND_FAILED`,e.message,e.details,e);if(e.code!==xi)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`,be(n),e)}if(n.exitCode!==0)throw new t(`COMMAND_FAILED`,`Android automation helper failed`,be(n,{helper:r}));return e.readResult(r)}function ji(e){let n=un(e).results.find(e=>e.agentDeviceProtocol===kn);if(!n)throw new t(xi,`Android automation helper did not return a final result`);if(n.ok!==`true`)throw new t(Si,n.message&&n.message!==`null`?n.message:n.errorType||`Android automation helper returned an error`,{errorType:n.errorType,helper:n});return n}function Mi(e){return{helperKind:e.kind,helperApiVersion:e.helperApiVersion,injectedEvents:E(e.injectedEvents),elapsedMs:E(e.elapsedMs)}}function Ni(e){let n=E(e.x),r=E(e.y),i=E(e.width),a=E(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`);return _n({x:n,y:r,width:i,height:a})}function Pi(e){if(e.topology===`two`||e.intent===`longPress`)return e;let{releaseBehavior:t,...n}=e,[{pointerId:r,samples:i}]=n.pointers,a=[...new Set([...He(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:We(n.point,r.point,t===`controlled`?Fi(s,a):s)}}),c=[s[0],s[1],s[2],...s.slice(3)];return{...n,pointers:[{pointerId:r,samples:c}]}}function Fi(e,t){let n=Math.min(16/t,.5);return e<n?e**2/n:1-(1-e)**2/(1-n)}async function Ii(e,t){let n=Pi(t),r=Me(e);if(r){let e=n.intent===`longPress`?{...n,viewport:_n(await r.gestureViewport())}:n;return{backend:`provider-native-touch`,...await r.touch(e)??{}}}return await Ci(e,n)}async function Li(e,t={}){let n=Me(e);return n?_n(await n.gestureViewport()):await wi(e,t)}async function Ri(e,t,n){await S(e,[`shell`,`input`,`tap`,String(t),String(n)])}async function zi(e,t,n){let r=Se(t);await S(e,[`shell`,`input`,...n&&n>0?[`keyevent`,`--longpress`]:[`keyevent`],r])}async function Bi(e){await S(e,[`shell`,`input`,`keyevent`,`4`])}async function Vi(e){await S(e,[`shell`,`input`,`keyevent`,`3`])}async function Hi(e){await S(e,[`shell`,`input`,`keyevent`,`ENTER`])}async function Ui(e,t){let n=Qi(t);await S(e,[`shell`,`settings`,`put`,`system`,`accelerometer_rotation`,`0`]),await S(e,[`shell`,`settings`,`put`,`system`,`user_rotation`,n]),await Gi(e,t,n)}const Wi=15e3;async function Gi(e,n,r){let i=Date.now()+Wi,a=await Ki(e,n,i);for(;a!==void 0&&a!==r&&Date.now()<i;)await g(Math.min(500,qi(i))),a=await Ki(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 ${Wi}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 Ki(e,n,r){try{let t=await S(e,[`shell`,`dumpsys`,`display`],{timeoutMs:qi(r)});return/mCurrentOrientation=(\d)/.exec(t.stdout)?.[1]}catch(e){throw new t(`COMMAND_FAILED`,`orientation ${n} could not confirm the display rotation: ${e instanceof Error?e.message:String(e)}`,{hint:"The device did not answer `dumpsys display` within the orientation budget."})}}function qi(e){return Math.max(1,e-Date.now())}async function Ji(e){await S(e,[`shell`,`input`,`keyevent`,`187`])}async function Yi(e,t,n,r=800){let i={x:t,y:n};return await Ii(e,{topology:`single`,intent:`longPress`,durationMs:r,pointers:[{pointerId:0,samples:[{offsetMs:0,point:i},{offsetMs:r,point:i}]}]})}async function Xi(e,t,n){await Ri(e,t,n)}async function Zi(e,t,n){let r=await Li(e,{helperSessionScope:n?.helperSessionScope}),i=le({direction:t,amount:n?.amount,pixels:n?.pixels,referenceWidth:r.width,referenceHeight:r.height}),a={...i,referenceWidth:r.x+r.width,referenceHeight:r.y+r.height,x1:r.x+i.x1,y1:r.y+i.y1,x2:r.x+i.x2,y2:r.y+i.y2},o=Math.max(n?.durationMs??300,16),s=await Ii(e,{...Ue({intent:`pan`,origin:{x:a.x1,y:a.y1},delta:{x:a.x2-a.x1,y:a.y2-a.y1},durationMs:o},r,`android`),releaseBehavior:n?.releaseBehavior??`controlled`});return{...a,...n?.durationMs===void 0?{}:{durationMs:o},...s}}function Qi(e){let n=ge[e];if(n===void 0)throw new t(`INVALID_ARGS`,`Unsupported Android rotation: ${e}`);return String(n)}async function $i(e){let n=(await S(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 ea(e,t,n){return t===`wait`?await ta(n.captureNodes,n.timeoutMs??1e4):t===`get`?sa((await oa(n.captureNodes))?.alert??null):await na(e,t,n.captureNodes)}async function ta(e,n){let r=Date.now(),i=await aa(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,...ue(`Alert visible`)}}async function na(e,n,r){let i=await aa(r,de);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=Ht(i.buttons,n);if(a)return await Ri(e,a.x,a.y),await ra(i.alert,n,r),ca(n,i.alert,a.label,{x:a.x,y:a.y});if(n===`dismiss`)return await Bi(e),await ra(i.alert,n,r),ca(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 ra(e,n,r){let i=Date.now();for(;;){let a=await oa(r);if(!a||!ia(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 ia(e,t){return e.title===t.title&&e.buttons.join(`\0`)===t.buttons.join(`\0`)}async function aa(e,t){let n=Date.now();for(;Date.now()-n<t;){let t=await oa(e);if(t)return t;await g(300)}return null}async function oa(e){return Bt(await m(`snapshot_capture`,e,{backend:`android`,purpose:`alert`}))}function sa(e){return{kind:`alertStatus`,platform:`android`,action:`get`,alert:e,...ue(e?`Alert visible`:`No alert visible`)}}function ca(e,t,n,r){return{kind:`alertHandled`,platform:`android`,action:e,handled:!0,alert:t,button:n,...r?{coordinates:r}:{},...ue(`Alert ${e}ed`)}}const la=`android.intent.category.LAUNCHER`,ua=`android.intent.category.DEFAULT`;async function da(e,t){await e([`shell`,`am`,`force-stop`,t])}async function fa(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=$e(n.stdout);if(i)return i}return null}async function pa(e,n,r={}){let i=r.category??la;if(r.activity){await e([`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,ua,`-c`,i,`-n`,ma(n,r.activity)]);return}let a=await e([`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,ua,`-c`,i,`-p`,n],{allowFailure:!0});if(a.exitCode===0&&!et(a.stdout,a.stderr))return;let o=await fa(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`,ua,`-c`,i,`-n`,o])}function ma(e,t){return t.includes(`/`)?t:`${e}/${t.startsWith(`.`)?t:`.${t}`}`}let ha=null;function ga(e){return`${e.PATH??``}::${e.AGENT_DEVICE_BUNDLETOOL_JAR??``}`}async function _a(e){let n=ga(e);if(ha?.key===n)return ha.invocation;if(await ye(`bundletool`)){let e={cmd:`bundletool`,prefixArgs:[]};return ha={key:n,invocation:e},e}let r=await xe(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 ha={key:n,invocation:i},i}async function va(e,t,n){let r=await _a(n);await ve(r.cmd,[...r.prefixArgs,...e],{signal:t})}function ya(e){return C.extname(e).toLowerCase()===`.aab`}async function ba(e,t,n={}){let r=x(e),i=`universal`;if(r.installBundle){await r.installBundle(t,{mode:i,signal:n.signal});return}let a=v().files,o=await a.makeTempDirectory(`agent-device-aab-`),s=C.join(o,`bundle.apks`);try{await va([`build-apks`,`--bundle`,t,`--output`,s,`--mode`,i],n.signal,n.environment??v().environment),await va([`install-apks`,`--apks`,s,`--device-id`,e.id],n.signal,n.environment??v().environment)}finally{await a.remove(o,{recursive:!0,force:!0})}}async function xa(e,t,n={}){if(ya(t)){await ba(e,t,n);return}await ze(t,{device:e,replace:!0,signal:n.signal})}async function Sa(e,t,n={}){await it(e,async()=>{e.booted||await Ye(e.id,void 0,n.signal),await xa(e,t,n)})}const Ca=[`mInputShown`,`mIsInputViewShown`,`isInputViewShown`,`mDecorViewVisible`,`mWindowVisible`,`mInShowWindow`],wa=new Map([[2,`number`],[3,`phone`],[4,`datetime`]]),Ta=new Set([32,208]),Ea=new Set([128,224,144]);async function Da(e){return await R(b(e))}async function R(e){let t=await e([`shell`,`dumpsys`,`input_method`],{allowFailure:!0});if(t.exitCode!==0)throw y(`Failed to query Android keyboard state`,t);return Aa(t.stdout)}async function Oa(e){return await ka(b(e))}async function ka(e){let n=await R(e),r=n,i=0;for(;r.visible&&i<2;)await e([`shell`,`input`,`keyevent`,`111`]),i+=1,await g(120),r=await R(e);if(n.visible&&r.visible)throw new t(`UNSUPPORTED_OPERATION`,`Android keyboard dismiss is unavailable for the current IME without back navigation.`,{attempts:i,inputType:r.inputType,type:r.type,inputMethodPackage:r.inputMethodPackage,focusedPackage:r.focusedPackage,focusedResourceId:r.focusedResourceId,inputOwner:r.inputOwner});return{attempts:i,wasVisible:n.visible,dismissed:n.visible&&!r.visible,visible:r.visible,inputType:r.inputType,type:r.type,inputMethodPackage:r.inputMethodPackage,focusedPackage:r.focusedPackage,focusedResourceId:r.focusedResourceId,inputOwner:r.inputOwner}}function Aa(e){let t=Fa(e)??ja(e),n=Ma(e),r=Na(e,/\bpackageName=([A-Za-z0-9_.]+)\b/g),i=Na(e,/\b(?:resourceId|resource-id)=([^\s,}]+)/g),a=f(e),o=ee(r,i,a);return Pa(r,i,a),{visible:t??!1,inputType:n,type:n?za(n):void 0,inputMethodPackage:a,focusedPackage:r,focusedResourceId:i,inputOwner:o}}function ja(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 Ma(e){let t=Na(e,/\binputType=0x([0-9a-fA-F]+)\b/gi);return t?`0x${t.toLowerCase()}`:void 0}function Na(e,t){let n;for(let r of e.matchAll(t))n=r[1];return n}function Pa(e,t,n){n||!u(e)&&!c(t)||h({level:`warn`,phase:`android_input_ownership_fallback`,data:{focusedPackage:e,focusedResourceId:t}})}function Fa(e){return La(Ia(e,Ca))}function Ia(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 La(e){if(e.size===0)return null;let t=Ra(e,[`mWindowVisible`,`mDecorViewVisible`,`mInShowWindow`]);if(t!==void 0)return t;let n=e.get(`mInputShown`);return n===void 0?Ra(e,[`mIsInputViewShown`,`isInputViewShown`])??null:n}function Ra(e,t){for(let n of t){let t=e.get(n);if(t!==void 0)return t}}function za(e){let t=Number.parseInt(e.replace(/^0x/i,``),16);if(Number.isNaN(t))return`unknown`;let n=t&15,r=wa.get(n);if(r)return r;if(n!==1)return`unknown`;let i=t&4080;return Ta.has(i)?`email`:Ea.has(i)?`password`:`text`}async function Ba(e){return await Va(b(e))}async function Va(e){return Ga(await Wa(e,[`shell`,`cmd`,`clipboard`,`get`,`text`],`read`))}async function Ha(e,t){await Ua(b(e),t)}async function Ua(e,t){await Wa(e,[`shell`,`cmd`,`clipboard`,`set`,`text`,Ce(t)],`write`)}async function Wa(e,n,r){let i=await e(n,{allowFailure:!0});if(i.exitCode===0)return i.stdout;throw Ve(i.stdout,i.stderr)?new t(`UNSUPPORTED_OPERATION`,`Android shell clipboard ${r} is not supported on this device.`):y(`Failed to ${r} Android clipboard text`,i)}function Ga(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=yr(e.slice(0,r)),a=e.slice(r+2);return _r(i,n),vr(i,a),{xml:a,metadata:br(i)}}function _r(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,...A(or(e))})}function vr(e,n){let r=E(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 yr(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 br(e){return{helperApiVersion:e.helperApiVersion,outputFormat:Mn,waitForIdleTimeoutMs:E(e.waitForIdleTimeoutMs),waitForIdleQuietMs:E(e.waitForIdleQuietMs),timeoutMs:E(e.timeoutMs),maxDepth:E(e.maxDepth),maxNodes:E(e.maxNodes),rootPresent:vn(e.rootPresent),captureMode:e.captureMode===`interactive-windows`||e.captureMode===`active-window`?e.captureMode:void 0,windowCount:E(e.windowCount),nodeCount:E(e.nodeCount),truncated:vn(e.truncated),elapsedMs:E(e.elapsedMs)}}const xr=2e3,Sr=`android_snapshot_helper_retirement_unconfirmed`,j=new Map;function M(e){return`${e.platform}:${e.id}`}async function Cr(e){await Mr({adb:e.adb,packageName:e.packageName,timeoutMs:2e3})||N(e)}async function wr(e){let t=j.get(e.deviceKey);if(t){try{let n=await e.adb([`shell`,`am`,`force-stop`,t.packageName],{allowFailure:!0,timeoutMs:5e3,signal:e.signal});if(e.signal?.throwIfAborted(),n.exitCode===0){j.delete(e.deviceKey);return}}catch{e.signal?.throwIfAborted()}N({deviceKey:e.deviceKey,packageName:t.packageName,cause:t.cause})}}function N(e){let n=e.cause instanceof Error?e.cause.message:String(e.cause);throw j.set(e.deviceKey,{packageName:e.packageName,cause:n}),new t(`COMMAND_FAILED`,`Android snapshot helper could not confirm release of device automation ownership`,{reason:Sr,deviceKey:e.deviceKey,cause:n,hint:`Retry after the helper process exits, or restart the device if Android still reports automation as busy.`})}function Tr(e){return e instanceof t&&e.details?.reason===Sr}async function Er(e){let t=AbortSignal.timeout(e.timeoutMs),[n]=await Promise.allSettled([e.forceStopRuntime?Mr({adb:e.adb,packageName:e.packageName,timeoutMs:e.timeoutMs,signal:t}):Promise.resolve(!1),Nr({...e,signal:t})]);return{timedOut:t.aborted,runtimeForceStopped:n?.status===`fulfilled`&&n.value}}function Dr(e){let t=Or(e);return{ended:t?Promise.resolve():new Promise(t=>{e.once(`close`,()=>t()),e.once(`exit`,()=>t())}),hasEnded:()=>Or(e),completedCleanly:()=>!t&&e.exitCode===0&&e.signalCode==null}}function Or(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 Ar(e){if(e.processExit.hasEnded())return!0;try{e.process.kill(`SIGTERM`)}catch{}return await kr(e.processExit.ended,e.timeoutMs)}function jr(){j.clear()}async function Mr(e){let t=e.signal??AbortSignal.timeout(e.timeoutMs);try{return(await e.adb([`shell`,`am`,`force-stop`,e.packageName],{allowFailure:!0,timeoutMs:e.timeoutMs,signal:t})).exitCode===0}catch{return!1}}async function Nr(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 Pr(e){let n=Ir(e),r=e.deviceKey??`android:default`;await wr({deviceKey:r,adb:e.adb,signal:e.signal});let i;try{i=await e.adb(Lr(n),{allowFailure:!0,timeoutMs:n.commandTimeoutMs,signal:e.signal})}catch(t){throw e.signal?.aborted?(await Cr({deviceKey:r,packageName:n.packageName,adb:e.adb,cause:t}),e.signal.throwIfAborted(),t):t}e.signal?.aborted&&(await Cr({deviceKey:r,packageName:n.packageName,adb:e.adb,cause:e.signal.reason}),e.signal.throwIfAborted());let{output:a,cleanupDone:o}=await Rr(e,n,i);if(n.outputPath&&!o&&await Gr(e.adb,n.outputPath),i.exitCode!==0)throw new t(`COMMAND_FAILED`,`Android snapshot helper failed`,Se(i,{helper:a.metadata}));return a}function Fr(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:Nn,commandTimeoutMs:Pn,...e.signal?{signal:e.signal}:{}}}function Ir(e){let t=P(e.timeoutMs,8e3),n=P(e.packageName,`com.callstack.agentdevice.snapshothelper`);return{waitForIdleTimeoutMs:P(e.waitForIdleTimeoutMs,500),waitForIdleQuietMs:P(e.waitForIdleQuietMs,100),timeoutMs:t,commandTimeoutMs:P(e.commandTimeoutMs,t+5e3),maxDepth:P(e.maxDepth,128),maxNodes:P(e.maxNodes,5e3),packageName:n,runner:P(e.instrumentationRunner,`${n}/.SnapshotInstrumentation`),...e.outputPath?{outputPath:e.outputPath}:{},...e.emitChunks===void 0?{}:{emitChunks:e.emitChunks}}}function P(e,t){return e===void 0?t:e}function Lr(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 Rr(e,t,n){try{return{output:Kr(`${n.stdout}\n${n.stderr}`),cleanupDone:!1}}catch(r){return await zr(e,t,n,r)}}async function zr(e,n,r,i){if(i instanceof t&&r.exitCode!==0&&i.details?.helper)throw i;let a=await Br(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,...A(sr(r.exitCode))},i)}async function Br(e,t,n){if(!(n.exitCode!==0||!t.outputPath))return await Hr(e.adb,t.outputPath,Wr(`${n.stdout}\n${n.stderr}`)??Vr(t))}function Vr(e){return{outputFormat:Mn,waitForIdleTimeoutMs:e.waitForIdleTimeoutMs,waitForIdleQuietMs:e.waitForIdleQuietMs,timeoutMs:e.timeoutMs,maxDepth:e.maxDepth,maxNodes:e.maxNodes,transport:`instrumentation`}}async function Hr(e,t,n){let r;try{r=await e(Ur(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 Ur(e){return[`shell`,`sh`,`-c`,`cat "$1"; status=$?; rm -f "$1"; exit "$status"`,`agent-device-snapshot-helper-output`,e]}function Wr(e){try{return ei(Jr(fn(e).results))}catch{return null}}async function Gr(e,t){try{await e([`shell`,`rm`,`-f`,t],{allowFailure:!0,timeoutMs:5e3})}catch{}}function Kr(e){let t=fn(e),n=Jr(t.results);return{xml:Xr(qr(t.status),n),metadata:{...ei(n),transport:`instrumentation`}}}function qr(e){let t=[];for(let n of e){if(n.agentDeviceProtocol!==`android-snapshot-helper-v1`||n.outputFormat!==`uiautomator-xml`)continue;let{payloadBase64:e}=n;e!==void 0&&t.push({index:F(n.chunkIndex),count:F(n.chunkCount),payloadBase64:e})}return t}function Jr(e){let n=e.find(e=>e.agentDeviceProtocol===jn);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`,Yr(n),{errorType:n.errorType,helper:n,...A(or(n))});return n}function Yr(e){return e.message&&e.message!==`null`?e.message:e.errorType||`Android snapshot helper returned an error`}function Xr(e,n){if(e.length===0)throw new t(`COMMAND_FAILED`,`Android snapshot helper did not return XML chunks`,{helper:n});let r=Zr(e),i=Buffer.concat($r(Qr(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 Zr(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 Qr(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 $r(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 ei(e){return{helperApiVersion:e.helperApiVersion,outputFormat:Mn,waitForIdleTimeoutMs:F(e.waitForIdleTimeoutMs),waitForIdleQuietMs:F(e.waitForIdleQuietMs),timeoutMs:F(e.timeoutMs),maxDepth:F(e.maxDepth),maxNodes:F(e.maxNodes),rootPresent:ni(e.rootPresent),captureMode:ti(e.captureMode),windowCount:F(e.windowCount),nodeCount:F(e.nodeCount),truncated:ni(e.truncated),elapsedMs:F(e.elapsedMs)}}function ti(e){return e===`interactive-windows`||e===`active-window`?e:void 0}const F=E,ni=vn,ri=5e3,I=new Map,ii=new Map;async function ai(e){return await oi(e)!==void 0}async function oi(e){let t=e.deviceKey??`android:default`;if(await wr({deviceKey:t,adb:e.adb,signal:e.signal}),!fi()||!e.adbProvider?.spawn)return;let n=di(Ir(e)),r=await ci({deviceKey:t,identity:ui(t,n,e),options:e,resolved:n});return r?{session:r,resolved:n,deviceKey:t}:void 0}function si(e){return I.get(e)}async function ci(e){let{deviceKey:t,identity:n,options:r,resolved:i}=e;if(ii.get(t)===n)return;let a=I.get(t);if(a&&a.identity!==n&&(await L(t),a=void 0),!a)try{a=await li({deviceKey:t,identity:n,options:r,resolved:i})}catch(e){if(r.signal?.throwIfAborted(),ii.set(t,n),h({level:`warn`,phase:`android_snapshot_helper_session_disabled`,data:{deviceKey:t,reason:e instanceof Error?e.message:String(e)}}),Tr(e))throw e;return}return a}async function li(e){let n=await cr();await e.options.adb([`forward`,`tcp:${n}`,`tcp:${n}`],{allowFailure:!1,timeoutMs:ri,signal:e.options.signal});let r=Lr({...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 fr(o,1e4,e.options.signal),I.set(e.deviceKey,s),h({phase:`android_snapshot_helper_session_ready`,data:{deviceKey:e.deviceKey,port:n,packageName:e.resolved.packageName,runner:e.resolved.runner}}),s}catch(t){let n=Dr(o);try{o.kill(`SIGTERM`)}catch{}let[,r]=await Promise.all([kr(n.ended,250),Er({adb:s.adb,process:s.process,port:s.port,packageName:s.helper.packageName,timeoutMs:xr,forceStopRuntime:!0})]);throw r.runtimeForceStopped||N({deviceKey:e.deviceKey,packageName:s.helper.packageName,cause:t}),t}}function ui(e,t,n){return JSON.stringify({deviceKey:e,packageName:t.packageName,runner:t.runner,helperVersion:n.helperVersion,helperVersionCode:n.helperVersionCode,helperSha256:n.helperSha256,waitForIdleTimeoutMs:t.waitForIdleTimeoutMs,waitForIdleQuietMs:t.waitForIdleQuietMs,timeoutMs:t.timeoutMs,maxDepth:t.maxDepth,maxNodes:t.maxNodes})}function di(e){let t=Math.min(e.timeoutMs,2e3);return{...e,timeoutMs:t,commandTimeoutMs:Math.min(e.commandTimeoutMs,t+3e3)}}function fi(){let e=v().environment.AGENT_DEVICE_ANDROID_SNAPSHOT_HELPER_SESSION;return e===void 0||!/^(0|false|no|off)$/i.test(e)}async function L(e,t={}){let n=I.get(e);if(!n)return!1;I.delete(e);let r=Dr(n.process),i=t.force===!0||t.signal?.aborted===!0,a=await pi(n,r,i,t.signal),o=r.hasEnded(),s=a.acknowledged&&a.exited,c=s&&await kt({adb:n.adb,deviceKey:e,signal:t.signal}),l=i?t.signal?.aborted===!0?250:xr:ri,u=i?250:2e3,[d,f]=await Promise.all([Ar({process:n.process,processExit:r,timeoutMs:u}),Er({adb:n.adb,process:n.process,port:n.port,packageName:n.helper.packageName,timeoutMs:l,forceStopRuntime:t.resetRuntime===!0||!c})]);return h({phase:`android_snapshot_helper_session_stop`,data:{deviceKey:e,port:n.port,capturedCount:n.capturedCount,lifetimeMs:Date.now()-n.startedAtMs,quitAcknowledged:a.acknowledged,quitExitObserved:s,runtimeReleaseConfirmed:c,forceKilled:!o&&d,forced:i||t.signal?.aborted===!0,runtimeForceStopped:f.runtimeForceStopped,externalCleanupTimedOut:f.timedOut}}),!c&&!f.runtimeForceStopped&&N({deviceKey:e,packageName:n.helper.packageName,cause:t.cause}),!0}async function pi(e,t,n,r){if(n)return{acknowledged:!1,exited:!1};let i=`quit-${Date.now()}`;try{let n=hr(await lr(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 mi(e){await L(M(e))}async function hi(){let e=await Promise.allSettled([...I.keys()].map(e=>L(e)));ii.clear();let t=e.filter(e=>e.status===`rejected`).map(e=>e.reason);if(t.length>0)throw AggregateError(t,`Failed to retire every Android snapshot helper session`);jr(),At()}async function gi(e){let t=await oi(e);if(t)return await _i({session:t.session,deviceKey:t.deviceKey,options:e,resolved:t.resolved})}async function _i(e){let{session:t,deviceKey:n,options:r,resolved:i}=e;try{let e=t.capturedCount>0,n=await ur({port:t.port,timeoutMs:i.timeoutMs,commandTimeoutMs:i.commandTimeoutMs,signal:r.signal});return t.capturedCount+=1,{xml:n.xml,metadata:{...n.metadata,transport:`persistent-session`,sessionReused:e}}}catch(e){await L(n,{force:!0,signal:r.signal,cause:e}),r.signal?.throwIfAborted(),h({level:`warn`,phase:`android_snapshot_helper_session_fallback`,data:{deviceKey:n,reason:e instanceof Error?e.message:String(e),uiAutomationConnectionTimeout:Ye(e)===`accessibility-timeout`}});return}}async function vi(e){let n=si(e.deviceKey);if(!n)return;if(!yi(n.helper,e.helper)){h({level:`warn`,phase:`android_snapshot_helper_session_touch_identity_mismatch`,data:{deviceKey:e.deviceKey,sessionHelper:n.helper,requestedHelper:e.helper}}),await L(e.deviceKey);return}let r=`${e.action}-${Date.now()}-${Math.random().toString(16).slice(2)}`,i=e.payloadBase64?`${e.action} ${r} ${e.payloadBase64}`:`${e.action} ${r}`,a;try{a=pr(await lr(n.port,i,e.timeoutMs)),mr(a,r)}catch(t){throw await L(e.deviceKey),t}if(a.ok!==`true`)throw new t(`COMMAND_FAILED`,a.message||a.errorType||`Android automation helper ${e.action} failed`,{errorType:a.errorType,helper:a});return a}function yi(e,t){return e.packageName===t.packageName&&e.runner===t.runner&&bi(e.helperVersion,t.helperVersion)&&bi(e.helperVersionCode,t.helperVersionCode)&&bi(e.sha256,t.sha256)}function bi(e,t){return e===void 0||t===void 0||e===t}const xi=`android-touch-plan-v1`,Si=45e3,Ci=`ANDROID_TOUCH_HELPER_NO_FINAL_RESULT`,wi=`ANDROID_TOUCH_HELPER_REPORTED_FAILURE`;async function Ti(e,t){let n=await Oi(e),r=Ai(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 vi({deviceKey:n.deviceKey,action:`gesture`,helper:Di(n.artifact),payloadBase64:a,timeoutMs:i});return e?{...Pi(e),helperTransport:`persistent-session`}:{...await Mi({adb:n.adb,runner:n.artifact.manifest.instrumentationRunner,extraArgs:[`-e`,`mode`,`gesture`,`-e`,`payloadBase64`,a],timeoutMs:i,readResult:Pi}),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 Ei(e,t={}){let n=await Oi(e);t.helperSessionScope===`daemon-session`&&await ai(Fr({adb:n.adb,adbProvider:n.adbProvider,artifact:n.artifact,deviceKey:n.deviceKey}));try{let e=await vi({deviceKey:n.deviceKey,action:`viewport`,helper:Di(n.artifact),timeoutMs:Si});if(e)return Fi(e)}catch(e){await L(n.deviceKey),h({level:`warn`,phase:`android_touch_helper_viewport_session_fallback`,data:{reason:e instanceof Error?e.message:String(e)}})}return await Mi({adb:n.adb,runner:n.artifact.manifest.instrumentationRunner,extraArgs:[`-e`,`mode`,`viewport`],timeoutMs:Si,readResult:Fi})}function Di(e){return{packageName:e.manifest.packageName,runner:e.manifest.instrumentationRunner,helperVersion:e.manifest.version,helperVersionCode:e.manifest.versionCode,sha256:e.manifest.sha256}}async function Oi(e){let t=x(e),n=t.snapshotHelperArtifact??await ki(),r=M(e);await wr({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 L(r),{adb:t.exec,adbProvider:t,artifact:n,install:i,deviceKey:r}}async function ki(){return await Cn({helperDirName:`snapshot-helper`,manifestFileName:e=>`agent-device-android-snapshot-helper-${e}.manifest.json`,parseManifest:e=>{let t=D(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 Ai(e){return{kind:e.topology===`single`?`swipe`:`transform`,durationMs:e.durationMs,pointers:e.pointers.map(ji)}}function ji(e){return{pointerId:e.pointerId,samples:e.samples.map(({offsetMs:e,point:t})=>({offsetMs:e,x:t.x,y:t.y}))}}async function Mi(e){let n=await e.adb([`shell`,`am`,`instrument`,`-w`,...e.extraArgs,e.runner],{allowFailure:!0,timeoutMs:e.timeoutMs}),r;try{r=Ni(`${n.stdout}\n${n.stderr}`)}catch(e){if(e instanceof t){if(e.code===wi)throw new t(`COMMAND_FAILED`,e.message,e.details,e);if(e.code!==Ci)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 Ni(e){let n=fn(e).results.find(e=>e.agentDeviceProtocol===jn);if(!n)throw new t(Ci,`Android automation helper did not return a final result`);if(n.ok!==`true`)throw new t(wi,n.message&&n.message!==`null`?n.message:n.errorType||`Android automation helper returned an error`,{errorType:n.errorType,helper:n});return n}function Pi(e){return{helperKind:e.kind,helperApiVersion:e.helperApiVersion,injectedEvents:E(e.injectedEvents),elapsedMs:E(e.elapsedMs)}}function Fi(e){let n=E(e.x),r=E(e.y),i=E(e.width),a=E(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=Ii(e);return{viewport:yn({x:n,y:r,width:i,height:a}),...o?{keyboard:o}:{}}}function Ii(e){let t=E(e.keyboardX),n=E(e.keyboardY),r=E(e.keyboardWidth),i=E(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 Li(e){if(e.topology===`two`||e.intent===`longPress`)return e;let{releaseBehavior:t,...n}=e,[{pointerId:r,samples:i}]=n.pointers,a=[...new Set([...We(e.durationMs,`android`),...i.map(({offsetMs:e})=>e)])].sort((e,t)=>e-t),o=0,s=a.map(e=>{for(;o<i.length-2&&e>i[o+1].offsetMs;)o+=1;let n=i[o],r=i[o+1],a=r.offsetMs-n.offsetMs,s=(e-n.offsetMs)/a;return{offsetMs:e,point:e===r.offsetMs||a===0?r.point:Ke(n.point,r.point,t===`controlled`?Ri(s,a):s)}}),c=[s[0],s[1],s[2],...s.slice(3)];return{...n,pointers:[{pointerId:r,samples:c}]}}function Ri(e,t){let n=Math.min(16/t,.5);return e<n?e**2/n:1-(1-e)**2/(1-n)}async function zi(e,t){let n=Li(t),r=Pe(e);if(r){let e=n.intent===`longPress`?{...n,viewport:yn(await r.gestureViewport())}:n;return{backend:`provider-native-touch`,...await r.touch(e)??{}}}return await Ti(e,n)}async function Bi(e,t={}){return(await Vi(e,t)).viewport}async function Vi(e,t={}){let n=Pe(e);return n?{viewport:yn(await n.gestureViewport())}:await Ei(e,t)}async function Hi(e,t,n){await S(e,[`shell`,`input`,`tap`,String(t),String(n)])}async function Ui(e,t,n){let r=we(t);await S(e,[`shell`,`input`,...n&&n>0?[`keyevent`,`--longpress`]:[`keyevent`],r])}async function Wi(e){await S(e,[`shell`,`input`,`keyevent`,`4`])}async function Gi(e){await S(e,[`shell`,`input`,`keyevent`,`3`])}async function Ki(e){await S(e,[`shell`,`input`,`keyevent`,`ENTER`])}async function qi(e,t){let n=na(t);await S(e,[`shell`,`settings`,`put`,`system`,`accelerometer_rotation`,`0`]),await S(e,[`shell`,`settings`,`put`,`system`,`user_rotation`,n]),await Yi(e,t,n)}const Ji=15e3;async function Yi(e,n,r){let i=Date.now()+Ji,a=await Xi(e,n,i);for(;a!==void 0&&a!==r&&Date.now()<i;)await g(Math.min(500,Zi(i))),a=await Xi(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 ${Ji}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 Xi(e,n,r){try{let t=await S(e,[`shell`,`dumpsys`,`display`],{timeoutMs:Zi(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 Zi(e){return Math.max(1,e-Date.now())}async function Qi(e){await S(e,[`shell`,`input`,`keyevent`,`187`])}async function $i(e,t,n,r=800){let i={x:t,y:n};return await zi(e,{topology:`single`,intent:`longPress`,durationMs:r,pointers:[{pointerId:0,samples:[{offsetMs:0,point:i},{offsetMs:r,point:i}]}]})}async function R(e,t,n){await Hi(e,t,n)}async function ea(e,t,n){let{viewport:r,keyboard:i}=await Vi(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 zi(e,{...Ge({intent:`pan`,origin:{x:s.x1,y:s.y1},delta:{x:s.x2-s.x1,y:s.y2-s.y1},durationMs:c},a.viewport,`android`),releaseBehavior:n?.releaseBehavior??`controlled`});return{...s,...a.evidence,...n?.durationMs===void 0?{}:{durationMs:c},...l}}function 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 na(e){let n=ve[e];if(n===void 0)throw new t(`INVALID_ARGS`,`Unsupported Android rotation: ${e}`);return String(n)}async function ra(e){let n=(await S(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 ia(e,t,n){return t===`wait`?await aa(n.captureNodes,n.timeoutMs??1e4):t===`get`?da((await ua(n.captureNodes))?.alert??null):await oa(e,t,n.captureNodes)}async function aa(e,n){let r=Date.now(),i=await la(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 oa(e,n,r){let i=await la(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=Wt(i.buttons,n);if(a)return await Hi(e,a.x,a.y),await sa(i.alert,n,r),fa(n,i.alert,a.label,{x:a.x,y:a.y});if(n===`dismiss`)return await Wi(e),await sa(i.alert,n,r),fa(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 sa(e,n,r){let i=Date.now();for(;;){let a=await ua(r);if(!a||!ca(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 ca(e,t){return e.title===t.title&&e.buttons.join(`\0`)===t.buttons.join(`\0`)}async function la(e,t){let n=Date.now();for(;Date.now()-n<t;){let t=await ua(e);if(t)return t;await g(300)}return null}async function ua(e){return Ht(await m(`snapshot_capture`,e,{backend:`android`,purpose:`alert`}))}function da(e){return{kind:`alertStatus`,platform:`android`,action:`get`,alert:e,...fe(e?`Alert visible`:`No alert visible`)}}function fa(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 pa=`android.intent.category.LAUNCHER`,ma=`android.intent.category.DEFAULT`;async function ha(e,t){await e([`shell`,`am`,`force-stop`,t])}async function ga(e,t,n=[pa]){for(let r of n){let n=await e([`shell`,`cmd`,`package`,`resolve-activity`,`--brief`,`-a`,`android.intent.action.MAIN`,`-c`,r,t],{allowFailure:!0});if(n.exitCode!==0)continue;let i=tt(n.stdout);if(i)return i}return null}async function _a(e,n,r={}){let i=r.category??pa;if(r.activity){await e([`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,ma,`-c`,i,`-n`,va(n,r.activity)]);return}let a=await e([`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,ma,`-c`,i,`-p`,n],{allowFailure:!0});if(a.exitCode===0&&!nt(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 e([`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,ma,`-c`,i,`-n`,o])}function va(e,t){return t.includes(`/`)?t:`${e}/${t.startsWith(`.`)?t:`.${t}`}`}let ya=null;function ba(e){return`${e.PATH??``}::${e.AGENT_DEVICE_BUNDLETOOL_JAR??``}`}async function xa(e){let n=ba(e);if(ya?.key===n)return ya.invocation;if(await xe(`bundletool`)){let e={cmd:`bundletool`,prefixArgs:[]};return ya={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 ya={key:n,invocation:i},i}async function Sa(e,t,n){let r=await xa(n);await be(r.cmd,[...r.prefixArgs,...e],{signal:t})}function Ca(e){return C.extname(e).toLowerCase()===`.aab`}async function wa(e,t,n={}){let r=x(e),i=`universal`;if(r.installBundle){await r.installBundle(t,{mode:i,signal:n.signal});return}let a=v().files,o=await a.makeTempDirectory(`agent-device-aab-`),s=C.join(o,`bundle.apks`);try{await Sa([`build-apks`,`--bundle`,t,`--output`,s,`--mode`,i],n.signal,n.environment??v().environment),await Sa([`install-apks`,`--apks`,s,`--device-id`,e.id],n.signal,n.environment??v().environment)}finally{await a.remove(o,{recursive:!0,force:!0})}}async function Ta(e,t,n={}){if(Ca(t)){await wa(e,t,n);return}await Ve(t,{device:e,replace:!0,signal:n.signal})}async function Ea(e,t,n={}){await ot(e,async()=>{e.booted||await Ze(e.id,void 0,n.signal),await Ta(e,t,n)})}const Da=[`mInputShown`,`mIsInputViewShown`,`isInputViewShown`,`mDecorViewVisible`,`mWindowVisible`,`mInShowWindow`],Oa=new Map([[2,`number`],[3,`phone`],[4,`datetime`]]),ka=new Set([32,208]),Aa=new Set([128,224,144]);async function ja(e){return await z(b(e))}async function z(e){let t=await e([`shell`,`dumpsys`,`input_method`],{allowFailure:!0});if(t.exitCode!==0)throw y(`Failed to query Android keyboard state`,t);return Pa(t.stdout)}async function Ma(e){return await Na(b(e))}async function Na(e){let n=await z(e),r=n,i=0;for(;r.visible&&i<2;)await e([`shell`,`input`,`keyevent`,`111`]),i+=1,await g(120),r=await z(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 Pa(e){let t=za(e)??Fa(e),n=Ia(e),r=La(e,/\bpackageName=([A-Za-z0-9_.]+)\b/g),i=La(e,/\b(?:resourceId|resource-id)=([^\s,}]+)/g),a=f(e),o=ee(r,i,a);return Ra(r,i,a),{visible:t??!1,inputType:n,type:n?Ua(n):void 0,inputMethodPackage:a,focusedPackage:r,focusedResourceId:i,inputOwner:o}}function Fa(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 Ia(e){let t=La(e,/\binputType=0x([0-9a-fA-F]+)\b/gi);return t?`0x${t.toLowerCase()}`:void 0}function La(e,t){let n;for(let r of e.matchAll(t))n=r[1];return n}function Ra(e,t,n){n||!u(e)&&!c(t)||h({level:`warn`,phase:`android_input_ownership_fallback`,data:{focusedPackage:e,focusedResourceId:t}})}function za(e){return Va(Ba(e,Da))}function Ba(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 Va(e){if(e.size===0)return null;let t=Ha(e,[`mWindowVisible`,`mDecorViewVisible`,`mInShowWindow`]);if(t!==void 0)return t;let n=e.get(`mInputShown`);return n===void 0?Ha(e,[`mIsInputViewShown`,`isInputViewShown`])??null:n}function Ha(e,t){for(let n of t){let t=e.get(n);if(t!==void 0)return t}}function Ua(e){let t=Number.parseInt(e.replace(/^0x/i,``),16);if(Number.isNaN(t))return`unknown`;let n=t&15,r=Oa.get(n);if(r)return r;if(n!==1)return`unknown`;let i=t&4080;return ka.has(i)?`email`:Aa.has(i)?`password`:`text`}async function Wa(e){return await Ga(b(e))}async function Ga(e){return Ya(await Ja(e,[`shell`,`cmd`,`clipboard`,`get`,`text`],`read`))}async function Ka(e,t){await qa(b(e),t)}async function qa(e,t){await Ja(e,[`shell`,`cmd`,`clipboard`,`set`,`text`,Te(t)],`write`)}async function Ja(e,n,r){let i=await e(n,{allowFailure:!0});if(i.exitCode===0)return i.stdout;throw Ue(i.stdout,i.stderr)?new t(`UNSUPPORTED_OPERATION`,`Android shell clipboard ${r} is not supported on this device.`):y(`Failed to ${r} Android clipboard text`,i)}function Ya(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 wo=2e3;async function To(e=v().environment,t=v().files){let n=e.ANDROID_HOME||e.ANDROID_SDK_ROOT,r=await Lo(n,t),i=await vt(`adb`,[`version`]);return i?No({license:r,sdkRoot:n,versionLine:i}):Io(n,r)}async function Eo(e,t){if(e.platform!==`android`)return[];let n=b(e,t.transportOverrides.androidAdb),r=[];return t.shouldProbeMetro&&r.push(await Mo(n,e.id,t.metroPort)),r.push(await Do(n,e)),r}async function Do(e,t){try{let n=await V(e),r=ho(t);return n===await Oo()&&!r?await ko(e,t,n):Ao(t,n,r)}catch(e){return jo(e)}}async function Oo(){try{return(await Ya()).manifest.serviceComponent}catch{return}}async function ko(e,t,n){let r=(await e([`shell`,`settings`,`get`,`secure`,so.previousIme],{allowFailure:!0,timeoutMs:wo})).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 Ao(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 jo(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 Mo(e,t,r){try{let n=await e([`reverse`,`--list`],{allowFailure:!0,timeoutMs:wo}),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 No(e){return{id:`toolchain`,status:Po(e),summary:e.versionLine?`Android toolchain: ${e.versionLine}; ${Fo(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 Po(e){return e.versionLine&&e.sdkRoot&&e.license!==`missing`?`pass`:`info`}function Fo(e){return e?`ANDROID_HOME/ANDROID_SDK_ROOT set`:`ANDROID_HOME unset`}function Io(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 Lo(e,t){if(!e)return`unknown`;try{return await t.access(C.join(e,`licenses`,`android-sdk-license`)),`accepted`}catch{return`missing`}}function Ro(e,t){if(!t)return{expected:e,actual:null,failureReason:`text_mismatch`,targetInput:null,actualInput:null};let n=Ho(t),r={failureReason:t.reason??`text_mismatch`,targetInput:Bo(t.targetInput),actualInput:Bo(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 W(e){return e?e.password?!0:zo(e.text):!1}function zo(e){return e?Array.from(e).every(Vo):!1}function Bo(e){if(!e)return null;let t=W(e);return{...e,text:t?null:e.text,...t?{textRedacted:!0}:{}}}function Vo(e){return e===`•`||e===`*`||e===`●`}function Ho(e){return e.masked===!0||W(e.targetInput)||W(e.actualInput)}const Uo=new WeakMap;function Wo(e,t){return t&&Uo.set(e,t),e}function Go(e){return Uo.get(e)}function Ko(e){return e.clickable}function qo(e){return e.focusable||e.focused===!0}function G(e){return Ko(e)||qo(e)}function Jo(e){let t=e.trim();return t?/^[\w.]+:id\/[\w.-]+$/i.test(t):!1}function Yo(e,t){return{raw:e,...t?{effectiveRect:t}:{}}}function Xo(e,t,n){if(!e)return;let r=$o(e);return t&&(r=Qo(r,t)),n&&(r=Qo(r,n)),r}function Zo(e){return{...e.raw,...e.effectiveRect?{rect:e.effectiveRect}:{rect:void 0},hittable:e.raw.hittable===!0&&ae(e.effectiveRect)?!0:void 0}}function Qo(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 $o(e){return{x:e.x,y:e.y,width:Math.max(0,e.width),height:Math.max(0,e.height)}}function es(e,t){let n=new Set;return ts(e,n,t),rs(e,n,t),n}function ts(e,t,n){for(let r of e.children){if(n?.check(`work`),r.visibleToUser===!1){t.add(r);continue}ts(r,t,n)}}function ns(e,t,n){return n?.check(`work`),e.children.filter(e=>!t.has(e)&&e.visibleToUser!==!1)}function rs(e,t,n){let r=ns(e,t,n).filter(as);if(r.length<2)return;let i=r.filter(e=>os(e)&&ss(e));if(i.length===0)return;let a=is(i);for(let r of ns(e,t,n))n?.check(`work`),os(r)&&(ss(r)&&(a===void 0||r.windowLayer===a)||t.add(r))}function is(e){let t=e.map(e=>e.windowLayer).filter(e=>e!==void 0);return t.length>0?Math.max(...t):void 0}function as(e){return e.windowIndex!==void 0||e.windowType!==void 0}function os(e){return e.windowType===1}function ss(e){return e.windowActive===!0||e.windowFocused===!0}function cs(e,t,n,r,i){let a=new Set(e.sourceNodes),o=us(t,i),s=ls(o,n,ds(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 ls(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 ds(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 fs(e,t,n,r,i){if(e.visibleToUser===!1)return!1;let a=ps(e);return t.interactiveOnly?ms(e,a,n,r,i):a.isStructural||a.isVisual?_s(e,a,r):!0}function ps(e){let t=ys(e.type),n=!!(e.label&&e.label.trim().length>0),r=!!(e.identifier&&e.identifier.trim().length>0);return{type:t,hasMeaningfulText:n&&!Jo(e.label??``),hasMeaningfulId:r&&!Jo(e.identifier??``),isStructural:bs(t),isVisual:t===`imageview`||t===`imagebutton`}}function ms(e,t,n,r,i){return gs(e)?!1:G(e)||re(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 gs(e){return!!(e.rect&&(e.rect.width<=0||e.rect.height<=0))}function _s(e,t,n){return G(e)||t.hasMeaningfulText||t.hasMeaningfulId?!0:n}function vs(e){if(!e)return!1;let t=ys(e);return t.includes(`recyclerview`)||t.includes(`listview`)||t.includes(`gridview`)}function ys(e){return e?e.toLowerCase():``}function bs(e){let t=e.split(`.`).pop()??e;return t.includes(`layout`)||t===`viewgroup`||t===`view`}function xs(e,t,n,r){return{...Yo(e,t),...n?{clipsDescendants:!0}:{},...r?{windowRect:r}:{}}}const Ss=`ANDROID_SNAPSHOT_PRESENTATION_FAILED`;var K=class extends Error{code=Ss;qualityReasonCode=`presentation-failed`;details;analysis;constructor(e,t,n){super(e),this.name=`AndroidSnapshotPresentationFailure`,this.details=t,this.analysis=n}};function Cs(e){return e instanceof K?e.code===Ss:!!(e&&typeof e==`object`&&e.code===Ss)}var ws=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()+ks()}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 K(`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 K(`Android snapshot presentation exceeded its cooperative deadline`,{phase:`deadline`,workUnits:this.workUnits,deadlineAtMs:this.deadlineAtMs,maxWorkUnits:t})}};function Ts(e,t){return new ws(e??{},t)}function Es(e,t,n){let r=new Map;for(let i of e){n.check(`regular-invariant`);let e=Ds(i,r,t),a=i.effectiveRect;if(!a||!ae(a)){if(Zo(i).hittable===!0)throw new K(`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&&!Os(a,e))throw new K(`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 Ds(e,t,n){let r=e.raw.parentIndex;return r===void 0?e.windowRect??n:t.get(r)??e.windowRect??n}function Os(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 ks(){return 250}function As(e,t,n){let r=n.depth??1/0,i=ce(n.scope),a=Js(e),o=Ts(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=Vs(e,o),s.hidden=n.raw?new Set:es(e,o);for(let t of e.children)if(Ms(s,t,0),s.truncated)break;n.raw||Es(s.presentationNodes,s.viewport,o);let t=s.nodes,a=new Map(s.sourceNodes.map((e,t)=>[e,t])),{nodes:c,sourceNodes:l}=i?cs(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:js(s.sourceNodes)},analysis:s.analysis};return s.truncated?{...u,truncated:!0}:u}catch(e){throw Cs(e)&&(e.analysis??=s.analysis),e}}function js(e){let t=new Map,n=new Map;for(let[r,i]of e.entries()){let e=Go(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 Ms(e,t,n,r,i=!1,a=!1,o=!1,s,c){if(e.presentationBudget.check(`work`),Ns(e,t,n))return;let l=t.windowRect??s??e.viewport,u=Ps(e,t,c,l),d=Fs(e,t,r,i,a,o,u,l),f=i||G(t),p=a||vs(t.type),ee=Is(e,t,u,c);Ls(e,t,n,d,f,p,o||Ke(t.identifier),l,ee)}function Ns(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 Ps(e,t,n,r){return e.options.raw?t.rect:Xo(t.rect,r,n)}function Fs(e,t,n,r,i,a,o,s){return!e.options.raw&&!fs(t,e.options,r,Ws(e,t),i)?n:Rs(e,t,n,a||Ke(t.identifier),o,s)}function Is(e,t,n,r){return e.options.raw||!Hs(t)?r:n}function Ls(e,t,n,r,i,a,o,s,c){for(let l of t.children)if(Ms(e,l,n+1,r,i,a,o,s,c),e.truncated)return}function Rs(e,t,n,r,i,a){let o=e.nodes.length;return e.sourceNodes.push(t),Bs(e,t,zs(e,t,n,r),i,a),o}function zs(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,editable:t.editable,password:t.password,hintShowing:t.hintShowing,selectionStart:t.selectionStart,selectionEnd:t.selectionEnd,visibleToUser:t.visibleToUser,hittable:G(t)||void 0,depth:Us(e.nodes,n),parentIndex:n,...Gs(t,e.hidden),...r?{systemChrome:!0}:{}}}function Bs(e,t,n,r,i){let a=xs(n,r,!e.options.raw&&Hs(t),i);e.presentationNodes.push(a),e.nodes.push(e.options.raw?a.raw:Zo(a))}function Vs(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 ne(n)??void 0}function Hs(e){return e.scrollable===!0&&re(e.type)}function Us(e,t){return t===void 0?0:(e[t]?.depth??-1)+1}function Ws(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&&(G(n)||Ws(e,n)))return e.interactiveDescendantMemo.set(t,!0),!0;return e.interactiveDescendantMemo.set(t,!1),!1}function Gs(e,t){return Ks(e,t)?{...e.canScrollBackward?{hiddenContentAbove:!0}:{},...e.canScrollForward?{hiddenContentBelow:!0}:{}}:{}}function Ks(e,t){if(!e.scrollable||!re(e.type)||`${e.type??``}`.toLowerCase().includes(`horizontalscrollview`))return!1;let n=qs(e,t);return!(n&&n.horizontal>n.vertical&&n.horizontal>16)}function qs(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 Js(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 Ys(){let e=[],t=()=>e.at(-1)===!0;return{open(n,r){let i=t()||Ke(n);return r||e.push(i),i},close(){e.pop()}}}function*Xs(e){let t=/<node\b[^>]*>|<\/node>/g,n=Ys(),r=t.exec(e);for(;r;){let i=r[0];if(i.startsWith(`</node`))n.close();else{let e=Zs(i);yield n.open(e.resourceId,i.endsWith(`/>`))?{...e,systemChrome:!0}:e}r=t.exec(e)}}function Zs(e){let t=Qs(e),n=bt(t.bounds);return{...t,...n?{rect:n}:{}}}function Qs(e){let t=$s(e),n=e=>sc(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=bt(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`),...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 $s(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=ec(e,i,r);if(!n)break;t.set(n.name,n.value),i=n.nextCursor}return t}function ec(e,t,n){if(t=nc(e,t,n),t>=n||rc(e[t]))return;let r=t;t=tc(e,t,n);let i=e.slice(r,t);if(t=nc(e,t,n),!i||e[t]!==`=`)return;t=nc(e,t+1,n);let a=e[t];if(!ic(a))return;let o=t+1,s=e.indexOf(a,o);if(!(s<0||s>=n))return{name:i,value:xt(e.slice(o,s)),nextCursor:s+1}}function tc(e,t,n){for(;t<n&&!oc(e[t]??``);)t+=1;return t}function nc(e,t,n){for(;t<n&&ac(e[t]??``);)t+=1;return t}function rc(e){return e===`/`||e===`>`}function ic(e){return e===`"`||e===`'`}function ac(e){return e===` `||e===`
|
|
12
|
-
`||e===`\r`||e===` `}function oc(e){return e===`=`||e===`/`||e===`>`||ac(e)}function sc(e,t){return e.get(t)??null}function cc(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=Zs(t),o=n.at(-1),s=lc(a,o.depth+1,o);o.children.push(s),t.endsWith(`/>`)||n.push(s),i=r.exec(e)}return t}function lc(e,t,n){return Wo({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,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 dc=new Set([`android`,`com.android.systemui`]);function fc(e,t,n={}){if(t.backend!==`android-helper`)return{outcome:`ok`};let r=Cc(e,n.foregroundAppPackage);return hc(r,t)?pc(r,t,`empty-helper-output`,`Android snapshot helper returned no accessibility nodes`):xc(r)?{outcome:`ok`}:mc(r)?{outcome:`system-surface-only`}:gc(r)?{outcome:`ok`}:_c(r)?pc(r,t,`content-poor-app-window`,`Android snapshot helper returned insufficient foreground app content`):vc(r)||yc(r,t)?pc(r,t,`content-poor-app-window`,`Android snapshot helper returned insufficient application window content`):bc(r)?pc(r,t,`system-window-only`,`Android snapshot helper returned only non-application windows`):{outcome:`ok`}}function pc(e,t,n,r){return{outcome:`unusable`,decision:Sc(e,t,n,r)}}function mc(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 gc(e){return _c(e)&&e.inputMethodMeaningfulNodeCount>=2}function _c(e){let t=e.foregroundAppMeaningfulNodeCount;return t===void 0?!1:t===0?e.applicationMeaningfulNodeCount<2:t<2&&e.meaningfulNodeCount>t}function vc(e){return e.foregroundAppMeaningfulNodeCount===void 0&&e.applicationWindowRootCount>0&&e.applicationMeaningfulNodeCount<2}function yc(e,t){return e.foregroundAppMeaningfulNodeCount===void 0&&e.windowRootCount===0&&(t.windowCount??0)>1&&e.nonSystemMeaningfulNodeCount<2}function bc(e){return e.windowRootCount>0&&e.applicationWindowRootCount===0||e.windowRootCount===0&&e.nodeCount>0&&e.systemUiNodeCount===e.nodeCount}function xc(e){return e.hasAlertButtonIdentifier&&e.hasAlertContentIdentifier}function Sc(e,t,n,r){return{reason:n,failureReason:r,diagnostics:Lc(e,t)}}function Cc(e,t){let n=wc(t);for(let t of Xs(e))Tc(n,t);return Mc(n)}function wc(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 Tc(e,t){e.nodeCount+=1,Ic(t.packageName)&&(e.systemUiNodeCount+=1),t.visibleToUser!==!1&&Ec(e,t.resourceId),Dc(e,t),Oc(e,t)}function Ec(e,t){let n=zt(t);n===`button`&&(e.hasAlertButtonIdentifier=!0),n===`content`&&(e.hasAlertContentIdentifier=!0)}function Dc(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 Oc(e,t){Nc(t)&&(e.meaningfulNodeCount+=1,kc(e,t),jc(e,t))}function kc(e,t){e.currentWindowType===1&&!Fc(t.packageName)&&(e.applicationMeaningfulNodeCount+=1),Ac(e)&&!Ge(t)&&(e.activeSystemSurfaceMeaningfulNodeCount+=1)}function Ac(e){return e.currentWindowType!==void 0&&e.currentWindowType!==1&&e.currentWindowActiveOrFocused===!0}function jc(e,t){Fc(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 Mc(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 Nc(e){return e.visibleToUser===!1?!1:Pc(e.text)||Pc(e.desc)||Pc(e.resourceId)}function Pc(e){return e!==null&&e.trim()!==``}function Fc(e){return e===null||dc.has(e)}function Ic(e){return e!==null&&dc.has(e)}function Lc(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 Rc(e){let t=await L(e.deviceKey,{resetRuntime:!0,signal:e.signal,cause:e.cause});e.signal?.throwIfAborted(),t||await zc(e.adb,e.packageName)}async function zc(e,t){try{await e([`shell`,`am`,`force-stop`,t],{allowFailure:!0,timeoutMs:2e3}),await g(150),h({level:`debug`,phase:`android_snapshot_helper_runtime_reset`,data:{packageName:t}})}catch(e){h({level:`warn`,phase:`android_snapshot_helper_runtime_reset_failed`,data:{packageName:t,error:n(e).message}})}}const Bc=Symbol(`androidSnapshotCaptureEvidence`);function Vc(e,t){return Object.defineProperty(e,Bc,{value:t}),e}function Hc(e){let t={...e,backend:`android`,producer:`android-uiautomator`},n=e[Bc];return te(t,n.clickability),n.occlusionContext&&l(t,n.occlusionContext),t}async function Uc(e,t={}){let n=x(e,t.helperAdb).exec;return(await Zc(e,t,n)).xml}async function Wc(e,t={}){let n=x(e,t.helperAdb).exec,r=await Zc(e,t,n),i=r.xml,a=cc(i),o=qc(r.metadata,a),s={...t,androidPresentation:{...t.androidPresentation,deadlineAtMs:t.androidPresentation?.deadlineAtMs??Date.now()+250}};try{let e=As(a,void 0,s),n=Kc(e.truncated,r.metadata);t.interactiveOnly&&t.includeHiddenContentHints!==!1&&Xc({options:s,tree:a,xml:i,interactiveSnapshot:e});let{sourceNodes:c,occlusionContext:l,...u}=e;return Vc({...u,...Yc(n),androidSnapshot:o,quality:{state:`healthy`,backend:`android-helper`}},{clickability:uc(e),occlusionContext:l})}catch(e){if(!Cs(e))throw e;return Gc({failure:e,androidSnapshot:o})}}function Gc(e){return Vc({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 Kc(e,t){return e===!0||t.helperTruncated===!0||e}function qc(e,t){return Jc(t)===!1?{...e,occlusionScanUnavailable:!0}:e}function Jc(e){let t=[...e.children];if(t.length!==0){for(;t.length>0;){let e=t.pop();if(Go(e)!==void 0)return!0;t.push(...e.children)}return!1}}function Yc(e){return e===!0?{truncated:!0}:{}}function Xc(e){if(hl(e.interactiveSnapshot.nodes).size>0||ml(e.xml))return;let t=As(e.tree,void 0,{...e.options,interactiveOnly:!1});gl(he(i(t.nodes)),t,e.interactiveSnapshot)}async function Zc(e,t,n){let r=x(e,t.helperAdb),i=await m(`android_snapshot_helper_artifact_resolution`,async()=>await fl(t.helperArtifact??r.snapshotHelperArtifact));if(i.artifact)return await Qc(e,t,n,i.artifact);throw h({level:`error`,phase:`android_snapshot_helper_unavailable`,data:{reason:i.errorReason??`artifact_not_found`}}),pl(i.errorReason)}async function Qc(e,t,n,r){let i=M(e),a=x(e,t.helperAdb),o=t.helperSessionScope!==`daemon-session`;try{let e;for(let o=0;;o+=1){o>0&&await rl(t.signal);let s=await nl({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 il({contentRecovery:s.decision,attempts:o+1,helperDeviceKey:i,artifact:r,adb:n,signal:t.signal});e=s.decision.reason}}finally{o&&await L(i)}}async function $c(e,t,n,r,i){let a=await m(`android_snapshot_helper_install`,async()=>await Zn({adb:t,adbProvider:n,artifact:r,deviceKey:i,installPolicy:e.helperInstallPolicy,timeoutMs:3e4,signal:e.signal}),{packageName:r.manifest.packageName,versionCode:r.manifest.versionCode,installPolicy:e.helperInstallPolicy??`missing-or-outdated`});return h({phase:`android_snapshot_helper_install_decision`,data:{packageName:a.packageName,versionCode:a.versionCode,installedVersionCode:a.installedVersionCode,artifactSha256:r.manifest.sha256,installedSha256:a.installedSha256,installed:a.installed,reason:a.reason}}),a}async function el(e){let{signal:t,adb:r,adbProvider:i,artifact:a,helperDeviceKey:o}=e,s=Nr({adb:r,adbProvider:i,artifact:a,deviceKey:o,signal:t});try{let e=await m(`android_snapshot_helper_session_capture`,async()=>await mi(s),{packageName:a.manifest.packageName,version:a.manifest.version,timeoutMs:jn});if(e)return e}catch(e){if(t?.throwIfAborted(),Cr(e))throw e;h({level:`warn`,phase:`android_snapshot_helper_session_fallback`,data:{reason:n(e).message}}),await zc(r,a.manifest.packageName)}return await m(`android_snapshot_helper_capture`,async()=>await Mr(s),{packageName:a.manifest.packageName,version:a.manifest.version,timeoutMs:jn,commandTimeoutMs:Mn})}function tl(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 nl(e){let{options:t,adb:n,adbProvider:r,artifact:i,helperDeviceKey:a,attempt:o}=e,s;try{let e=await $c(t,n,r,i,a);e.installed&&await L(a),s=tl(await el({signal:t.signal,adb:n,adbProvider:r,artifact:i,helperDeviceKey:a}),i,e.reason)}catch(e){return t.signal?.throwIfAborted(),{outcome:`captured`,capture:await al({error:e,helperDeviceKey:a,artifact:i,adb:n})}}let c=fc(s.xml,s.metadata,{foregroundAppPackage:t.appBundleId});return c.outcome===`system-surface-only`?(h({phase:`android_snapshot_helper_system_surface`,data:{foregroundAppPackage:t.appBundleId}}),{outcome:`captured`,capture:{xml:s.xml,metadata:{...s.metadata,systemSurfaceOnly:!0}}}):c.outcome===`ok`?(o>0&&h({phase:`android_snapshot_helper_content_recaptured`,data:{attempts:o+1,recoveredFromReason:e.previousContentReason}}),{outcome:`captured`,capture:s}):{outcome:`unusable`,decision:c.decision}}async function rl(e){e?.throwIfAborted(),await g(250),e?.throwIfAborted()}async function il(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 Rc({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 al(e){let t=ol(e.error);throw h({level:`error`,phase:`android_snapshot_helper_failed`,data:{reason:t}}),await L(e.helperDeviceKey),await zc(e.adb,e.artifact.manifest.packageName),Kn({deviceKey:e.helperDeviceKey,packageName:e.artifact.manifest.packageName,versionCode:e.artifact.manifest.versionCode}),sl(e.error,t)}function ol(e){let t=n(e),r=dl(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 sl(e,i){let a=n(e),o=cl(a);return new t(r(a.code),`Android snapshot helper failed: ${i}`,{...a.details,...ul(a),androidSnapshotHelperFailureReason:i,...o?{androidCaptureFailureReason:o}:{},hint:ll(a,o)},e)}function cl(e){return qe(e)}function ll(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 dl(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 fl(e){if(e)return{artifact:e};let t=Te(),r=C.join(we(),`android`,`snapshot-helper`,`dist`),i=C.join(r,`agent-device-android-snapshot-helper-${t}.manifest.json`);try{await v().files.access(i)}catch{return{}}try{let e=D(JSON.parse(await v().files.readText(i))),t=C.join(r,e.assetName??`agent-device-android-snapshot-helper-${e.version}.apk`);return await v().files.access(t),{artifact:{apkPath:t,manifest:e}}}catch(e){return{errorReason:n(e).message}}}function pl(e){let n=e??`the bundled helper artifact was not found`;return new t(`COMMAND_FAILED`,`Android snapshot helper is unavailable: ${n}`,{androidSnapshotHelperFailureReason:n,hint:"Run `pnpm build:android` to build the helper dist for a source checkout — the runtime needs android/snapshot-helper/dist/agent-device-android-snapshot-helper-<version>.manifest.json and the .apk it references. Packaged installs ship these via the prepack script; if they are missing from a packaged install, reinstall agent-device."})}function ml(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 gl(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 _l(e,t,n,r,i={}){let a=[0,150,350],o=null,s=null,c=await Il(e);for(let l of a){l>0&&await g(l);let a=await El(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 vl(e,t,n,r={}){return Cl(await Uc(e,r),t,n)}async function yl(e,t,n,r){let i=await Il(e);return Dl(await Uc(e,r),t,n,i).targetInput}async function bl(e,t,n,r={}){try{return await yl(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 q(e,n,r){if(r?.ok)return;let i=r?xl(e,n,r):null;if(i)return i;throw new t(`COMMAND_FAILED`,wl(r),Tl(e,r))}function xl(e,t,n){let r=n.targetInput,i=n.actualInput;if(e.length===0||n.reason===`ime_capture`||!t||!r||!i||W(t)||W(r)||W(i)||!Hl(t,r)||!Hl(t,i)||t.text===n.actual)return null;let a=Ul(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 Sl(e,t,n,r,i={}){let a=Dl(e,t,n,i);return Ol(a)?{ok:!1,actual:a.actualInput?.text??null,reason:`ime_capture`,targetInput:a.targetInput,actualInput:a.actualInput}:kl(a,r)??Al(a,r)}function Cl(e,t,n){return Dl(e,t,n).targetInput?.text??null}function wl(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 Tl(e,t){let n=Ro(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 El(e,t,n,r,i,a){return Sl(await Uc(e,a),t,n,r,i)}function Dl(e,t,n,r={}){let i={focusedEdit:null,editAtPoint:null,anyAtPoint:null};for(let a of Xs(e)){let e=Fl(a,r);e&&Ll(i,e,t,n)}return zl(i)}function Ol(e){let{targetInput:t,actualInput:n}=e;return!t||!n||n===t?!1:n.inputMethodOwned&&!t.inputMethodOwned}function kl(e,t){let n=e.actualInput;if(!n||!Vl(n))return null;let r=n.text??null,i=Array.from(jl(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 Al(e,t){let n=e.actualInput;return{ok:n!==null&&Ml(jl(n),t),actual:n?.text??null,reason:`text_mismatch`,targetInput:e.targetInput,actualInput:n}}function jl(e){return e.hintShowing?``:e.text??``}function Ml(e,t){if(e===t)return!0;if(t.length===0)return!1;let n=Nl(e),r=Nl(t);return!n||!r?!1:!!(n===r||Pl(n,r))}function Nl(e){return e.replaceAll(/\s+/g,` `).trim()}function Pl(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 Fl(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:Bl(e.className??``),hintShowing:e.hintShowing===!0}}async function Il(e){try{return{activeInputMethodPackage:(await Da(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 Ll(e,t,n,r){let i=ie(t.rect,n,r);if(i&&t.editText&&(e.editAtPoint=Rl(e.editAtPoint,t)),t.focused&&t.editText){e.focusedEdit=Rl(e.focusedEdit,t);return}i&&t.text&&(e.anyAtPoint=Rl(e.anyAtPoint,t))}function Rl(e,t){return e&&e.area<t.area?e:t}function zl(e){let t=e.editAtPoint??e.anyAtPoint;return{targetInput:t,actualInput:(e.focusedEdit?.text?e.focusedEdit:null)??t}}function Bl(e){let t=e.toLowerCase();return t.includes(`edittext`)||t.includes(`textfield`)}function Vl(e){return W(e)}function Hl(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 Ul(e){return{resourceId:e.resourceId,className:e.className,packageName:e.packageName,rect:e.rect}}async function Wl(e,t){return await St(t.stateDir),await go(t.stateDir,e.id,async()=>await Gl(e,t))}async function Gl(e,t){let r=v().imeRecoveryMarkers,i=b(e),a=x(e),o=B(e),s;try{s=await Ja(a),await Qa({adb:i,adbProvider:a,artifact:s,deviceKey:o})}catch(e){return{outcome:`helper-unavailable`,reason:n(e).message}}let{manifest:c}=s,l=await V(i);if(l===c.serviceComponent){let n=await r.write(t.stateDir,e.id),a=await H(i);return n&&U.add(o),{outcome:`settled`,activated:!1,alreadyActive:!0,...n?{}:{persistFailed:!0},previousIme:a,helperServiceComponent:c.serviceComponent,helperPackageName:c.packageName}}let u=await H(i);if(!await co(i,l))return await uo(i,u,e.id),_({level:`warn`,phase:`android_test_ime_persist_failed`,data:{device:e.id,previousIme:l}}),{outcome:`settled`,activated:!1,alreadyActive:!1,persistFailed:!0,helperServiceComponent:c.serviceComponent,helperPackageName:c.packageName};let d=(await r.read(t.stateDir)).includes(e.id);if(!await r.write(t.stateDir,e.id))return await uo(i,u,e.id),_({level:`warn`,phase:`android_test_ime_marker_persist_failed`,data:{device:e.id,previousIme:l}}),{outcome:`settled`,activated:!1,alreadyActive:!1,persistFailed:!0,helperServiceComponent:c.serviceComponent,helperPackageName:c.packageName};await i([`shell`,`ime`,`enable`,c.serviceComponent],{allowFailure:!0,timeoutMs:1e4});let f=await i([`shell`,`ime`,`set`,c.serviceComponent],{allowFailure:!0,timeoutMs:1e4}),p=await V(i);return p===c.serviceComponent?(U.add(o),_({phase:`android_test_ime_activated`,data:{device:e.id,previousIme:l}}),{outcome:`settled`,activated:!0,alreadyActive:!1,previousIme:l,helperServiceComponent:c.serviceComponent,helperPackageName:c.packageName}):(U.delete(o),await uo(i,u,e.id),d||await r.clear(t.stateDir,e.id),_({level:`warn`,phase:`android_test_ime_activate_failed`,data:{device:e.id,activeIme:p,stderr:f.stderr.trim()}}),{outcome:`settled`,activated:!1,alreadyActive:!1,helperServiceComponent:c.serviceComponent,helperPackageName:c.packageName})}function Kl(e){return C.join(e,`android-test-ime-pending`)}function ql(e,t){return C.join(Kl(e),encodeURIComponent(t))}async function Jl(e,t){let r=v().files,i,a=!1;try{let n=Kl(e);if(i=ql(e,t),await r.ensureDirectory(n),(await Zl(i))?.serial===t)return!0;let o={version:1,serial:t};if(await r.writeAtomicText(i,`${JSON.stringify(o)}\n`,384),a=!0,(await Zl(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 Yl(e,t){await v().files.remove(ql(e,t),{force:!0}).catch(()=>{})}async function Xl(e){let t=v().files,n;try{n=await t.readDirectory(Kl(e))}catch{return[]}let r=[];for(let t of n)try{let n=C.join(Kl(e),t),i=await Zl(n);i&&ql(e,i.serial)===n&&r.push(i.serial)}catch{}return[...new Set(r)].sort()}async function Zl(e){try{return Ql(await v().files.readText(e))}catch{return}}function Ql(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 $l=new Tt(`utf-16le`);let eu;async function tu(e,t){for(let n of[`AndroidManifest.xml`,`base/manifest/AndroidManifest.xml`]){let r=await nu(e,n,t);if(!r)continue;let i=ru(r);if(i)return i}return await fu(e,t)}async function nu(e,t,n){try{let r=await ve(`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 ru(e){return e.subarray(0,Math.min(e.length,128)).toString(`utf8`).trimStart().startsWith(`<`)?iu(e.toString(`utf8`)):au(e)}function iu(e){return e.match(/<manifest\b[^>]*\bpackage\s*=\s*["']([^"']+)["']/i)?.[1]}function au(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=su(e.subarray(n,n+a));else if(r===258&&t){let r=ou(e,n,i,t);if(r)return r}n+=a}}function ou(e,t,n,r){if(n<36||t+n>e.length||r[e.readUInt32LE(t+20)]!==`manifest`)return;let i=e.readUInt16LE(t+24),a=e.readUInt16LE(t+26),o=e.readUInt16LE(t+28),s=t+i;for(let t=0;t<o;t+=1){let n=s+t*a;if(n+20>e.length)return;if(r[e.readUInt32LE(n+4)]!==`package`)continue;let i=e.readUInt32LE(n+8);if(i!==4294967295)return r[i];let o=e.readUInt8(n+15),c=e.readUInt32LE(n+16);return o===3?r[c]:void 0}}function su(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?cu(e,o):lu(e,o))}return a}function cu(e,t){let[,n]=uu(e,t),[r,i]=uu(e,t+n),a=t+n+i;return e.subarray(a,a+r).toString(`utf8`)}function lu(e,t){let[n,r]=du(e,t),i=t+r;return $l.decode(e.subarray(i,i+n*2))}function uu(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 du(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 fu(e,t){t?.throwIfAborted();let n=await pu();if(!n)return;let r=await ve(n,[`dump`,`badging`,e],{allowFailure:!0,signal:t});if(r.exitCode===0)return r.stdout.match(/package:\s+name='([^']+)'/)?.[1]}async function pu(){if(eu!==void 0)return eu??void 0;try{let e=v().files;for(let t of nt()){let n=C.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=C.join(n,r,`aapt`);if(C.isAbsolute(t)&&await e.isExecutable(t))return eu=t,t}}catch{}}}catch{}eu=null}async function mu(e,t){let n=e.kind===`url`&&Ee(e.url),r=await De({source:e,isInstallablePath:(e,t)=>t.isFile()&&hu(e),installableLabel:`Android installable (.apk or .aab)`,allowArchiveExtraction:e.kind!==`url`||n,signal:t?.signal});try{let e=t?.resolveIdentity===!1?{}:await gu(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 hu(e){let t=C.extname(e).toLowerCase();return t===`.apk`||t===`.aab`}async function gu(e,t){let n=C.extname(e).toLowerCase();return n!==`.apk`&&n!==`.aab`?{}:{packageName:await tu(e,t)}}async function _u(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&&(vu(o,e,t),u+=1);return await S(e,o,{signal:i.signal}),{action:a,extrasCount:u}}function vu(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 J(e){let t=e.replaceAll(`,`,``).match(/^-?\d+(?:\.\d+)?/);if(!t)return null;let n=Number(t[0]);return Number.isFinite(n)?n:null}function yu(e){let t=wu(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 Tu(n)}function bu(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 xu(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=>Cu({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 Su(e){return Math.round(e*10)/10}function Cu(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:Su(Math.max(...t.map(e=>e.durationNs))/1e6)}}function wu(e){return[...new Set(e.filter(e=>Number.isFinite(e)))].sort((e,t)=>e-t)}function Tu(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 Eu(e,t,n){Du(e,t);let r=Lu(e),i=Nu(e),a=ku(i,r,t),o=Date.parse(n),s=zu({frames:i,measuredAtMs:o,summary:r}),c=bu({frames:i,frameDeadlineNs:a,summaryDroppedFrameCount:r?.droppedFrameCount}),l=r?.sampleWindowMs??s.sampleWindowMs??Uu(i),u=Au(r,i,c),d=Mu({droppedFrames:c,timing:s,measuredAtMs:o,summary:r});return{...u,sampleWindowMs:l,...ju(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 Du(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 Ou(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 ku(e,n,r){let i=yu(e);if(!n&&e.length===0&&Ou(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 Au(e,t,n){let r=e?.totalFrameCount??t.length,i=e?.droppedFrameCount??n.length;return{totalFrameCount:r,droppedFrameCount:i,droppedFramePercent:e?.droppedFramePercent??(r>0?Ct(i/r*100):0)}}function ju(e){return{frameDeadlineMs:e===void 0?void 0:Su(e/1e6),refreshRateHz:e===void 0?void 0:Su(1e9/e)}}function Mu(e){let{droppedFrames:t,timing:n,measuredAtMs:r,summary:i}=e;if(t.length===0)return;let a=xu({frames:t,windowStartNs:n.windowStartNs,measuredAtMs:r,uptimeMs:i?.uptimeMs});return a.length>0?a:void 0}function Nu(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(Pu(i)){n=new Map(i.map((e,t)=>[e,t]));continue}let a=Fu(i,n);a&&t.push(a)}return t.sort((e,t)=>e.intendedVsyncNs-t.intendedVsyncNs)}function Pu(e){return e.includes(`IntendedVsync`)&&e.includes(`FrameCompleted`)}function Fu(e,t){if(!t||e.length<t.size)return;let n=Iu(e,t,`Flags`),r=Iu(e,t,`IntendedVsync`),i=Iu(e,t,`FrameCompleted`);if(!(n!==0||r===null||i===null||r<=0||i<=r))return{intendedVsyncNs:r,frameCompletedNs:i,durationNs:i-r}}function Iu(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 Lu(e){let t=e.split(/\nProfile data in ms:\n/i)[0]??``,n=Wu(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=J(i)??void 0,s=Number(a);if(o===void 0||!Number.isFinite(s)||n<0)return;let c=Wu(t,`Uptime`),l=Wu(t,`Stats since`);return{droppedFramePercent:Ct(s),droppedFrameCount:o,totalFrameCount:n,sampleWindowMs:Ru({uptimeMs:c,statsSinceNs:l}),uptimeMs:c,statsSinceNs:l}}function Ru(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 zu(e){let{frames:t,measuredAtMs:n,summary:r}=e,i=Bu(t),a=r?.statsSinceNs,o=a??i.firstFrameNs,s=Vu(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:Hu({deviceBootWallClockMs:l,measuredAtMs:n,summaryStartNs:a,lastFrameNs:i.lastFrameNs}),timestampSource:`estimated-from-device-uptime`}}function Bu(e){return e.length===0?{}:{firstFrameNs:Math.min(...e.map(e=>e.intendedVsyncNs)),lastFrameNs:Math.max(...e.map(e=>e.frameCompletedNs))}}function Vu(e,t){if(e!==void 0&&t!==void 0)return Math.max(0,Math.round((t-e)/1e6))}function Hu(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 Uu(e){if(e.length===0)return;let t=Bu(e);return Vu(t.firstFrameNs,t.lastFrameNs)}function Wu(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:J(i)??void 0}async function Gu(e,t,n={}){let r=b(e,n.adb);try{let i=Eu((await r([`shell`,`dumpsys`,`gfxinfo`,t,`framestats`],{timeoutMs:15e3})).stdout,t,new Date().toISOString());return await Ku(e,t,n),i}catch(e){throw qu(t,e)}}async function Ku(e,t,n={}){let r=b(e,n.adb);try{await r([`shell`,`dumpsys`,`gfxinfo`,t,`reset`],{allowFailure:!0,timeoutMs:3e3})}catch{}}function qu(e,n){return n instanceof t?new t(n.code,n.message,{...n.details??{},metric:`fps`,package:e},n):new t(`COMMAND_FAILED`,`Failed to sample Android fps for ${e}`,{metric:`fps`,package:e},n)}function Y(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:Xu(n,a)},i)}return new t(`COMMAND_FAILED`,`Failed to ${e} Android ${n} for ${r}`,{action:e,package:r,tool:n,hint:Ju(n)},i)}function Ju(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 Yu(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 Xu(e,t){let n=(typeof t.stderr==`string`?t.stderr:``).toLowerCase();return e===`simpleperf`?Zu(n):$u(n)?`Use a device image that permits perfetto trace capture for shell, keep the app running, then retry perf trace start.`:Ju(e)}function Zu(e){return Qu(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.`:Ju(`simpleperf`)}function Qu(e){return e.includes(`permission denied`)||e.includes(`not profileable`)||e.includes(`profileable`)}function $u(e){return e.includes(`permission denied`)||e.includes(`not allowed`)}async function ed(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 td(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 td(e,t,n){try{let r=await Gu(e,t,n);return{available:!0,droppedFramePercent:r.droppedFramePercent,droppedFrameCount:r.droppedFrameCount,totalFrameCount:r.totalFrameCount,method:r.method,worstWindows:r.worstWindows?.slice(0,3).map(e=>({startOffsetMs:e.startOffsetMs,endOffsetMs:e.endOffsetMs,missedDeadlineFrameCount:e.missedDeadlineFrameCount,worstFrameMs:e.worstFrameMs}))}}catch(e){return{available:!1,reason:e instanceof Error?e.message:`Android frame health was not available`}}}const nd=`adb-shell-simpleperf`,rd=`adb-shell-perfetto`,id=15e3,X=3e4,ad=`/data/local/tmp`;async function od(e,t,n){let r=b(e,n.adb);await dd(r,t),await md(r,t),await pd(r,t,n.files);let i=await ud(t.outPath,n.files);await Z(r,t.remotePath);let a=Date.now(),o=Math.max(0,a-t.startedAt),s=await ed(e,t,i,o,{adb:r});return{...t,action:`stop`,platform:`android`,state:`stopped`,stoppedAt:a,durationMs:o,sizeBytes:i,method:t.kind===`simpleperf`?nd:rd,artifact:{path:t.outPath,sizeBytes:i},summary:s,message:`Stopped Android ${t.kind} ${t.type} for ${t.packageName}`}}async function sd(e,t,n={}){let r=b(e,n.adb);try{t.state===`running`&&(await dd(r,t),await md(r,t).catch(()=>{}))}finally{await Z(r,t.remotePath)}}function cd(e,t,n=ad){return`${n}/agent-device-${e.replaceAll(/[^A-Za-z0-9_.-]/g,`_`)}-${Date.now()}-${t}`}async function Z(e,t){try{await e([`shell`,`rm -f ${Q(t)}`],{allowFailure:!0,timeoutMs:id})}catch{}}async function ld(e,t,n=v().files){await n.ensureDirectory(C.dirname(e)),await n.writeBytes(e,Buffer.from(`${JSON.stringify(t,null,2)}\n`))}async function ud(e,n=v().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)}}function Q(e){return`'${e.replaceAll(`'`,`'\\''`)}'`}async function dd(e,t){try{await e([`shell`,fd(t.profilerPid)],{timeoutMs:X})}catch(e){throw Y(`stop`,t.kind,t.packageName,e)}}function fd(e){return[`pid=${Q(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 pd(e,n,r){await(r??v().files).ensureDirectory(C.dirname(n.outPath));try{await e([`pull`,n.remotePath,n.outPath],{timeoutMs:X})}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 md(e,n){let r;for(let t=0;t<12;t+=1){let t=await hd(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 hd(e,t){let n=Q(t),r=await e([`shell`,`if [ -f ${n} ]; then stat -c %s ${n} 2>/dev/null || wc -c < ${n}; fi`],{allowFailure:!0,timeoutMs:id});if(r.exitCode!==0)return;let i=Number(r.stdout.trim().split(/\s+/)[0]);return Number.isFinite(i)?i:void 0}async function gd(e,n){try{let t=await e([`shell`,`pidof`,n],{allowFailure:!0,timeoutMs:id}),r=vd(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 _d(e,n,r){let i=await e([`shell`,`command -v ${n} || which ${n}`],{allowFailure:!0,timeoutMs:id});if(!(i.exitCode===0&&i.stdout.trim()))throw new t(`UNSUPPORTED_OPERATION`,`Android device does not expose ${n}`,{package:r,tool:n,hint:Yu(n)})}function vd(e){return e.trim().split(/\s+/).find(e=>/^\d+$/.test(e))}async function yd(e,t,n,r={}){let i=b(e,r.adb),a=await gd(i,t);await _d(i,`perfetto`,t);let o=cd(t,`app.perfetto-trace`,`/data/misc/perfetto-traces`),s;try{await Ku(e,t,{adb:i}),s=await xd(i,o,t)}catch(e){throw await Z(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:rd,message:`Started Android Perfetto trace for ${t}`}}async function bd(e,t,n,r={}){return await od(e,{...t,outPath:n},r)}async function xd(e,n,r){try{let i=vd((await e([`shell`,`perfetto`,`--background-wait`,`-o`,n,`-t`,`3600s`,`sched`,`freq`,`idle`,`am`,`wm`,`gfx`,`view`,`binder_driver`,`hal`,`dalvik`],{timeoutMs:X})).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 Y(`start`,`perfetto`,r,e)}}function Sd(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:Ct(r),command:a[0],dso:a[1],symbol:a.slice(2).join(` `)||void 0}),t.length>=50)break}return t}async function Cd(e,t,n,r={}){let i=b(e,r.adb),a=await gd(i,t);await _d(i,`simpleperf`,t);let o=cd(t,`cpu.perf.data`),s;try{s=await Ed(i,a,o,t)}catch(e){throw await Z(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:nd,message:`Started Android Simpleperf CPU profile for ${t}`}}async function wd(e,t,n,r={}){return await od(e,{...t,outPath:n},r)}async function Td(e,t,n,r={}){let i=b(e,r.adb);await _d(i,`simpleperf`,t.packageName);let a=await kd(i,t),o=new Date().toISOString(),s=Sd(a.stdout),c=s.slice(0,10).map(e=>({symbol:e.symbol??`<unknown>`,binary:e.dso,selfSamplePercent:e.percentage}));await ld(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 ud(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:nd,message:`Wrote Android Simpleperf report for ${t.packageName}`}}async function Ed(e,n,r,i){try{let a=vd((await e([`shell`,Dd(n,r)],{timeoutMs:X})).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 Y(`start`,`simpleperf`,i,e)}}function Dd(e,t){return Od([`simpleperf`,`record`,`-e`,`cpu-clock:u`,`-p`,e,`-o`,t,`--duration`,`3600`],`simpleperf`)}function Od(e,t){let n=e.map(Q).join(` `);return[`err=${Q(`${ad}/agent-device-${t}-${Date.now()}.err`)}`,`(${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 kd(e,t){try{return await e([`shell`,`simpleperf`,`report`,`-i`,t.remotePath,`--stdio`,`--sort`,`comm,dso,symbol`],{timeoutMs:X})}catch(e){throw Y(`report`,`simpleperf`,t.packageName,e)}}const Ad=15e3,jd=12e4;async function Md(e,t,n={}){let r=b(e,n.adb);try{return Id((await r([`shell`,`dumpsys`,`meminfo`,t],{timeoutMs:Ad})).stdout,t,new Date().toISOString())}catch(e){throw Wd(`memory`,t,e)}}async function Nd(e,n,r,i={}){let a=b(e,i.adb),o=i.files??v().files,s=await Ld(a,n),c=Rd(n);await o.ensureDirectory(C.dirname(r));let l=await Pd(o,r);try{_e(await a([`shell`,`am`,`dumpheap`,n,c],{allowFailure:!0,timeoutMs:jd}),`Failed to capture Android heap dump for ${n}`,e=>({kind:`android-hprof`,package:n,pid:s,remotePath:c,hint:zd(e.stdout,e.stderr)}));let e=await a([`pull`,c,r],{allowFailure:!0,timeoutMs:jd});if(e.exitCode!==0)throw await Fd(o,r,l),y(`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 Fd(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:Ad}).catch(()=>{})}}async function Pd(e,t){return await e.stat(t).then(e=>e.isFile).catch(()=>!1)}async function Fd(e,t,n){n||await e.remove(t,{force:!0}).catch(()=>{})}function Id(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=Gd(e,`TOTAL PSS`)??Kd(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:Gd(e,`TOTAL RSS`),measuredAt:r,method:`adb-shell-dumpsys-meminfo`,topConsumers:Bd(e)}}async function Ld(e,n){let r=await e([`shell`,`pidof`,n],{allowFailure:!0,timeoutMs:Ad}),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 Rd(e){return`/data/local/tmp/agent-device-${e.replaceAll(/[^a-zA-Z0-9._-]/g,`_`)}-${Date.now()}.hprof`}function zd(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 Bd(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=>Yd.exec(e.text)?.[1]===String(t)),e=>Xd.test(e.text));if(!n)return;let r=new Map;for(let{text:e}of n){let t=Zd.exec(e);t&&r.set(t[1],t[2]===`true`?`granted`:`not_granted`)}return r}function $d(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,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 tf(e){let n=await Jd(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 nf(e,t,n,r){let i=me(n),a=of(r?.permissionTarget,r?.permissionMode),o=await tf(e),s=[`--user`,String(o)];if(i===`grant`){await rf(e,t,a,s);return}let c=await qd(e,t,o),l=await af(e,t,i,a,s),u=c?.get(l)??`unknown`,d=ef(t,l,u);return{permission:l,priorGrantState:u,...d?{warnings:[d]}:{}}}async function rf(e,t,n,r){n.kind===`notifications`?await cf(e,t,`grant`,n,r):n.type===`photos`?await sf(e,t,`grant`,r):await S(e,[`shell`,`pm`,`grant`,...r,t,n.value])}async function af(e,t,n,r,i){if(r.kind===`notifications`)return await cf(e,t,n,r,i),r.permission;let a;return r.type===`photos`?a=await sf(e,t,`revoke`,i):(a=r.value,await S(e,[`shell`,`pm`,`revoke`,...i,t,a])),n===`reset`&&await lf(e,t,a,i),a}function of(e,n){let r=fe(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 sf(e,n,r,i){let a=await uf(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 S(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 cf(e,t,n,r,i){let a=n===`grant`?`allow`:n===`deny`?`deny`:`default`;n===`grant`?await S(e,[`shell`,`pm`,`grant`,...i,t,r.permission],{allowFailure:!0}):(await S(e,[`shell`,`pm`,`revoke`,...i,t,r.permission],{allowFailure:!0}),n===`reset`&&await lf(e,t,r.permission,i)),await S(e,[`shell`,`appops`,`set`,...i,t,r.appOps,a])}async function lf(e,t,n,r){for(let i of[`user-set`,`user-fixed`])await S(e,[`shell`,`pm`,`clear-permission-flags`,...r,t,n,i],{allowFailure:!0})}async function uf(e){let t=await S(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 ff(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 pf(e){return e.map(e=>({args:e.args.join(` `),exitCode:e.exitCode,stderr:e.stderr.slice(0,400)}))}const mf=[`shell`,`cmd`,`connectivity`,`airplane-mode`];async function hf(e,n){let r=n?`enabled`:`disabled`;await gf(e),await S(e,[...mf,n?`enable`:`disable`]);let i=await _f(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 gf(e){let{state:n,result:r}=await vf(e);if(!n)throw r.exitCode!==0&&Ve(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}):y(`Failed to read Android airplane mode`,r,{deviceId:e.id})}async function _f(e){let{state:t,result:n}=await vf(e);if(t)return t;throw y(`Failed to read Android airplane mode after changing it`,n,{deviceId:e.id})}async function vf(e){let t=await S(e,[...mf],{allowFailure:!0});return{state:t.exitCode===0?yf(t.stdout):void 0,result:t}}function yf(e){let t=e.trim().toLowerCase();if(t===`enabled`)return`enabled`;if(t===`disabled`)return`disabled`}const bf=[`window_animation_scale`,`transition_animation_scale`,`animator_duration_scale`];async function xf(e,n,r,i,a){switch(n.toLowerCase()){case`wifi`:{let t=ff(r);await S(e,[`shell`,`svc`,`wifi`,t?`enable`:`disable`]);return}case`airplane`:return await hf(e,ff(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}=pe(a);return await S(e,[`emu`,`geo`,`fix`,String(r),String(n)]),{latitude:n,longitude:r}}let n=ff(r)?`3`:`0`;await S(e,[`shell`,`settings`,`put`,`secure`,`location_mode`,n]);return}case`animations`:{let t=ff(r)?`1`:`0`;for(let n of bf)await S(e,[`shell`,`settings`,`put`,`global`,n,t]);return{scale:t,keys:[...bf]}}case`appearance`:{let t=await Ef(e,r);await S(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 st(e,i);if(n.type===`intent`)throw new t(`INVALID_ARGS`,`settings clear-app-state requires a package name, not an intent.`);await S(e,[`shell`,`am`,`force-stop`,n.value],{allowFailure:!0});let a=await S(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 Cf(e,Sf(r));return;case`permission`:if(!i)throw new t(`INVALID_ARGS`,`permission setting requires an active app in session`);return await nf(e,i,r,a);default:throw new t(`INVALID_ARGS`,`Unsupported setting: ${n}`)}}function Sf(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 Cf(e,n){let r=wf(e,n),i=[];for(let t of r){let n=await S(e,t,{allowFailure:!0});if(n.exitCode===0)return;i.push({args:t,stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode})}let a=pf(i);throw i.length>0&&i.every(e=>Tf(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 wf(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 Tf(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 Ef(e,n){let r=df(n);if(r!==`toggle`)return r;let i=await S(e,[`shell`,`cmd`,`uimode`,`night`],{allowFailure:!0});if(i.exitCode!==0)throw y(`Failed to read current Android appearance`,i);let a=Df(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 Df(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 Of=Buffer.from([137,80,78,71,13,10,26,10]);async function kf(e,t,n={}){if(n.stabilize===!1){await Mf(e,t);return}await Af(e);try{await g(1e3),await Mf(e,t)}finally{await jf(e).catch(()=>{})}}async function Af(e){let t=t=>S(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 jf(e){await S(e,[`shell`,`am broadcast -a com.android.systemui.demo -e command exit`],{allowFailure:!0})}async function Mf(e,n){let r=await S(e,[`exec-out`,`screencap`,`-p`],{binaryStdout:!0});if(!r.stdoutBuffer)throw new t(`COMMAND_FAILED`,`Failed to capture screenshot`);let i=r.stdoutBuffer.indexOf(Of);if(i<0)throw new t(`COMMAND_FAILED`,`Screenshot data does not contain a valid PNG header`);let a=Nf(r.stdoutBuffer,i);if(!a)throw new t(`COMMAND_FAILED`,`Screenshot data does not contain a complete PNG payload`);await v().files.writeBytes(n,r.stdoutBuffer.subarray(i,a))}function Nf(e,t){let n=t+Of.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 Pf(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 zf(e,`type`,t);if(i.backend===`test-ime`){await Bf(e,i.packageName,t,n);return}if(n>0&&Array.from(t).length>1){await Hf(e,{action:`type`,text:t,chunkSize:1,delayMs:n});return}await Hf(e,{action:`type`,text:t,chunkSize:8,delayMs:0})}async function Ff(e,t,n,r,i=0,a={}){let o=await bl(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),q(r,o,await _l(e,t,n,r,a));let c=null;for(let s of If(i)){await Xi(e,t,n);let i=await zf(e,`fill`,r);if(i.backend===`test-ime`)return q(r,o,await Vf(e,i.packageName,t,n,r,o,a));let l=await Lf(e,{x:t,y:n,text:r,beforeTarget:o,attempt:s},a);if(c=l,l.ok)return;if(l.reason===`ime_capture`)return q(r,o,l);let u=xl(r,o,l);if(u)return u}return q(r,o,c)}function If(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 Lf(e,t,n){let{x:r,y:i,text:a,beforeTarget:o,attempt:s}=t;return await Wf(e,Rf(a,o,s)),await Hf(e,{action:`fill`,text:a,chunkSize:s.chunkSize,delayMs:s.inputDelayMs}),_l(e,r,i,a,n)}function Rf(e,t,n){let r=Array.from(e).length;return $f(r>0?r+n.clearPadding:t?.text?Array.from(t.text).length+n.clearPadding:n.maxClear,n.minClear,n.maxClear)}async function zf(e,t,n){if(ho(e))return{backend:`test-ime`,packageName:(await Ja(x(e))).manifest.packageName};let r=await Gf(e,t),i=r?.inputMethodPackage;return eo(i)?{backend:`test-ime`,packageName:i}:(qf(n),Kf(r,t),{backend:`adb-shell`})}async function Bf(e,t,n,r){let i=b(e),a=n.split(`
|
|
17
|
-
`);for(let[n,o]of a.entries()){let s=r>0?
|
|
18
|
-
`);for(let[r,i]of n.entries()){let a=
|
|
19
|
-
`&&(e<32||e>126))return!1}return!0}function
|
|
10
|
+
`).replace(/\n$/,``),n=t.match(/^clipboard text:\s*(.*)$/i);return n?n[1]??``:t.trim().toLowerCase()===`null`?``:t}const Xa=`com.callstack.agentdevice.imehelper`,Za=`android-ime-helper-v1`;async function Qa(e){return e.imeHelperArtifact??await $a()}async function $a(){return await v().resolveHelperArtifact({helperDirName:`ime-helper`,manifestFileName:e=>`agent-device-android-ime-helper-${e}.manifest.json`,parseManifest:eo,unavailableMessage:`Android test IME text entry requires the bundled Android IME helper artifact, but it was not found or could not be read`})}const B=`IME helper`;function eo(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:T(n.name,`name`,`android-ime-helper`,B),version:un(n.version,`version`,B),assetName:un(n.assetName,`assetName`,B),sha256:dn(n.sha256,B),packageName:T(n.packageName,`packageName`,Xa,B),versionCode:ln(n.versionCode,`versionCode`,B),serviceComponent:T(n.serviceComponent,`serviceComponent`,`com.callstack.agentdevice.imehelper/.TestInputMethodService`,B),broadcastProtocol:T(n.broadcastProtocol,`broadcastProtocol`,Za,B)}}const to=new Set;async function no(e){return await v().ensureHelperInstalled({cache:to,installTimeoutMs:3e4,helperLabel:`Android IME helper`},e)}function ro(){to.clear()}function V(e){return`${e.platform}:${e.id}`}function io(e){return e===Xa}async function ao(e,t,n){await so(e,t,`com.callstack.agentdevice.imehelper.ACTION_INPUT_TEXT_B64`,{text:Buffer.from(n,`utf8`).toString(`base64`)})}async function oo(e,t){await so(e,t,`com.callstack.agentdevice.imehelper.ACTION_CLEAR_TEXT`,{})}async function so(e,t,n,r){let i=[`shell`,`am`,`broadcast`,`-p`,t,`-a`,n];i.push(`--es`,`protocol`,Za);for(let[e,t]of Object.entries(r))i.push(`--es`,e,t);let a=await e(i,{allowFailure:!0,timeoutMs:1e4});if(a.exitCode!==0)throw y(`Android IME helper broadcast failed`,a,{action:n,packageName:t})}const co=`agent_device_ime_helper_previous_ime`,lo=`secure`,uo=`default_input_method`,fo={previousIme:co,defaultInputMethod:uo};async function H(e){let t=await e([`shell`,`settings`,`get`,lo,uo],{allowFailure:!0,timeoutMs:5e3});return _o(t.exitCode===0?t.stdout:``)}async function U(e){let t=await e([`shell`,`settings`,`get`,lo,co],{allowFailure:!0,timeoutMs:5e3});return _o(t.exitCode===0?t.stdout:``)||void 0}async function po(e,t){return(await e([`shell`,`settings`,`put`,lo,co,t],{allowFailure:!0,timeoutMs:5e3})).exitCode===0&&await U(e)===t}async function mo(e){await e([`shell`,`settings`,`delete`,lo,co],{allowFailure:!0,timeoutMs:5e3})}async function ho(e,t,r){try{(t?await po(e,t):await go(e))||_({level:`warn`,phase:`android_test_ime_record_rollback_failed`,data:{device:r,hadPriorRecord:t!==void 0}})}catch(e){_({level:`warn`,phase:`android_test_ime_record_rollback_failed`,data:{device:r,hadPriorRecord:t!==void 0,error:n(e).message}})}}async function go(e){return await mo(e),await U(e)===void 0}function _o(e){let t=e.trim();return!t||t===`null`?``:t}const W=new Set,vo=new Map;function yo(e){return W.has(V(e))}function bo(e,t,n){return xt(vo,`${e}:${t}`,n)}function xo(){W.clear()}function So(e,t){let n=V(e);t?W.add(n):W.delete(n)}async function Co(e,t){return await bo(t.stateDir,e.id,async()=>{let n=V(e);if(!W.has(n))return{restored:!1,reason:`no-record`};W.delete(n);let r=await To(b(e),e);return wo(r.reason)&&await v().imeRecoveryMarkers.clear(t.stateDir,e.id),r})}function wo(e){return e===`ok`||e===`helper-not-active`||e===`no-record`}async function To(e,t){let n=t.id;if(W.has(V(t)))return{restored:!1,reason:`owned-by-live-session`};let r=await U(e);if(!r)return{restored:!1,reason:`no-record`};let i=await H(e);if(i!==`com.callstack.agentdevice.imehelper/.TestInputMethodService`)return _({level:`debug`,phase:`android_test_ime_restore_skipped`,data:{device:n,currentIme:i,previousIme:r}}),{restored:!1,previousIme:r,reason:`helper-not-active`};await e([`shell`,`ime`,`set`,r],{allowFailure:!0,timeoutMs:1e4});let a=await H(e);return a===r?(await mo(e).catch(()=>{}),_({phase:`android_test_ime_restored`,data:{device:n,previousIme:r}}),{restored:!0,previousIme:r,reason:`ok`}):(_({level:`warn`,phase:`android_test_ime_restore_failed`,data:{device:n,previousIme:r,afterIme:a}}),{restored:!1,previousIme:r,reason:`set-failed`})}async function Eo(e){let t=v().imeRecoveryMarkers,r=await t.read(e.stateDir);if(r.length===0)return;let i;try{i=new Set(await e.listSerials())}catch(e){_({level:`debug`,phase:`android_test_ime_startup_scan_failed`,data:{error:n(e).message}});return}for(let a of r){if(!i.has(a))continue;let r={platform:`android`,id:a,name:a,kind:a.startsWith(`emulator-`)?`emulator`:`device`,booted:!0};try{await bo(e.stateDir,a,async()=>{let n=await To(b(r),r);n.restored&&_({level:`warn`,phase:`android_test_ime_orphan_restored`,data:{device:a,previousIme:n.previousIme}}),wo(n.reason)&&await t.clear(e.stateDir,a)})}catch(e){_({level:`debug`,phase:`android_test_ime_orphan_restore_failed`,data:{device:a,error:n(e).message}})}}}async function Do(){v();try{return(await je([`devices`],{timeoutMs:5e3})).stdout.split(`
|
|
11
|
+
`).map(e=>e.trim()).filter(e=>e.length>0&&!e.startsWith(`List of devices`)).map(e=>e.split(/\s+/)).filter(e=>e[1]===`device`).map(e=>e[0])}catch{return[]}}const Oo=2e3;async function ko(e=v().environment,t=v().files){let n=e.ANDROID_HOME||e.ANDROID_SDK_ROOT,r=await Vo(n,t),i=await bt(`adb`,[`version`]);return i?Lo({license:r,sdkRoot:n,versionLine:i}):Bo(n,r)}async function Ao(e,t){if(e.platform!==`android`)return[];let n=b(e,t.transportOverrides.androidAdb),r=[];return t.shouldProbeMetro&&r.push(await Io(n,e.id,t.metroPort)),r.push(await jo(n,e)),r}async function jo(e,t){try{let n=await H(e),r=yo(t);return n===await Mo()&&!r?await No(e,t,n):Po(t,n,r)}catch(e){return Fo(e)}}async function Mo(){try{return(await $a()).manifest.serviceComponent}catch{return}}async function No(e,t,n){let r=(await e([`shell`,`settings`,`get`,`secure`,fo.previousIme],{allowFailure:!0,timeoutMs:Oo})).stdout.trim(),i=r&&r!==`null`?r:void 0;return{id:`android-test-ime`,status:`fail`,summary:`Android test IME helper is the active input method on ${t.id}, but no active session owns it -- likely left over from a crashed session.`,hint:`A stuck test IME leaves the real keyboard unavailable on this device until restored.`,command:i?`adb -s ${t.id} shell ime set ${i}`:`adb -s ${t.id} shell ime list -s`,evidence:{currentIme:n,previousIme:i}}}function Po(e,t,n){return{id:`android-test-ime`,status:`pass`,summary:n?`Android test IME helper is active for this session on ${e.id}.`:`Android test IME helper is not active on ${e.id}; the device's normal IME is in use.`,evidence:{currentIme:t}}}function Fo(e){let t=n(e);return{id:`android-test-ime`,status:`warn`,summary:`Could not inspect the Android test IME helper state.`,hint:t.message,evidence:{code:t.code}}}async function Io(e,t,r){try{let n=await e([`reverse`,`--list`],{allowFailure:!0,timeoutMs:Oo}),i=`tcp:${r} tcp:${r}`,a=n.stdout.includes(i);return{id:`android-reverse`,status:a?`pass`:`warn`,summary:a?`Android adb reverse exists for Metro port ${r}.`:`Android adb reverse is missing for Metro port ${r}.`,command:a?void 0:`adb -s ${t} reverse tcp:${r} tcp:${r}`,evidence:{stdout:n.stdout.trim()}}}catch(e){let t=n(e);return{id:`android-reverse`,status:`warn`,summary:`Could not inspect Android adb reverse mappings.`,hint:t.message,evidence:{code:t.code}}}}function Lo(e){return{id:`toolchain`,status:Ro(e),summary:e.versionLine?`Android toolchain: ${e.versionLine}; ${zo(e.sdkRoot)}.`:`Android toolchain: adb is present but version check failed.`,hint:e.license===`missing`?`Accept Android SDK licenses before installing/building apps.`:void 0,command:e.license===`missing`?`sdkmanager --licenses`:void 0,evidence:{adbVersion:e.versionLine??null,androidHome:e.sdkRoot??null,license:e.license}}}function Ro(e){return e.versionLine&&e.sdkRoot&&e.license!==`missing`?`pass`:`info`}function zo(e){return e?`ANDROID_HOME/ANDROID_SDK_ROOT set`:`ANDROID_HOME unset`}function Bo(e,t){return{id:`toolchain`,status:`info`,summary:`Android toolchain: adb not found on PATH.`,hint:`Install Android platform-tools or add adb to PATH.`,evidence:{androidHome:e??null,license:t}}}async function Vo(e,t){if(!e)return`unknown`;try{return await t.access(C.join(e,`licenses`,`android-sdk-license`)),`accepted`}catch{return`missing`}}function Ho(e,t){if(!t)return{expected:e,actual:null,failureReason:`text_mismatch`,targetInput:null,actualInput:null};let n=Ko(t),r={failureReason:t.reason??`text_mismatch`,targetInput:Wo(t.targetInput),actualInput:Wo(t.actualInput)};return n?{...r,expectedLength:Array.from(e).length,actual:null,masked:!0,actualLength:Array.from(t.actual??``).length}:{...r,expected:e,actual:t.actual}}function G(e){return e?e.password?!0:Uo(e.text):!1}function Uo(e){return e?Array.from(e).every(Go):!1}function Wo(e){if(!e)return null;let t=G(e);return{...e,text:t?null:e.text,...t?{textRedacted:!0}:{}}}function Go(e){return e===`•`||e===`*`||e===`●`}function Ko(e){return e.masked===!0||G(e.targetInput)||G(e.actualInput)}const qo=new WeakMap;function Jo(e,t){return t&&qo.set(e,t),e}function Yo(e){return qo.get(e)}function Xo(e){return e.clickable}function Zo(e){return e.focusable||e.focused===!0}function K(e){return Xo(e)||Zo(e)}function Qo(e){let t=e.trim();return t?/^[\w.]+:id\/[\w.-]+$/i.test(t):!1}function $o(e,t){return{raw:e,...t?{effectiveRect:t}:{}}}function es(e,t,n){if(!e)return;let r=rs(e);return t&&(r=ns(r,t)),n&&(r=ns(r,n)),r}function ts(e){return{...e.raw,...e.effectiveRect?{rect:e.effectiveRect}:{rect:void 0},hittable:e.raw.hittable===!0&&ae(e.effectiveRect)?!0:void 0}}function ns(e,t){let n=Math.max(e.x,t.x),r=Math.max(e.y,t.y),i=Math.min(e.x+e.width,t.x+t.width),a=Math.min(e.y+e.height,t.y+t.height),o=i>n&&a>r;return{x:o?n:e.x,y:o?r:e.y,width:o?i-n:0,height:o?a-r:0}}function rs(e){return{x:e.x,y:e.y,width:Math.max(0,e.width),height:Math.max(0,e.height)}}function is(e,t){let n=new Set;return as(e,n,t),ss(e,n,t),n}function as(e,t,n){for(let r of e.children){if(n?.check(`work`),r.visibleToUser===!1){t.add(r);continue}as(r,t,n)}}function os(e,t,n){return n?.check(`work`),e.children.filter(e=>!t.has(e)&&e.visibleToUser!==!1)}function ss(e,t,n){let r=os(e,t,n).filter(ls);if(r.length<2)return;let i=r.filter(e=>us(e)&&ds(e));if(i.length===0)return;let a=cs(i);for(let r of os(e,t,n))n?.check(`work`),us(r)&&(ds(r)&&(a===void 0||r.windowLayer===a)||t.add(r))}function cs(e){let t=e.map(e=>e.windowLayer).filter(e=>e!==void 0);return t.length>0?Math.max(...t):void 0}function ls(e){return e.windowIndex!==void 0||e.windowType!==void 0}function us(e){return e.windowType===1}function ds(e){return e.windowActive===!0||e.windowFocused===!0}function fs(e,t,n,r,i){let a=new Set(e.sourceNodes),o=ms(t,i),s=ps(o,n,hs(o,a,i),i);if(!s)return{nodes:[],sourceNodes:[]};let c=new Set(ms([s],i)),l=[];for(let[t,n]of e.sourceNodes.entries())i.check(`work`),c.has(n)&&l.push(t);if(l.length===0)return{nodes:[],sourceNodes:[]};let u=1/0;for(let t of l)i.check(`work`),u=Math.min(u,e.nodes[t]?.depth??0);let d=[];for(let t of l)i.check(`work`),(e.nodes[t]?.depth??0)-u<=r&&d.push(t);return i.consume(d.length),{nodes:oe(d.map(t=>e.nodes[t]),u),sourceNodes:d.map(t=>e.sourceNodes[t])}}function ps(e,t,n,r){for(let i of e)if(r.check(`work`),se(i,t)&&n.has(i))return i;return null}function ms(e,t){let n=[],r=[...e].reverse();for(;r.length>0;){t.check(`work`);let e=r.pop();n.push(e);for(let n=e.children.length-1;n>=0;--n)t.check(`work`),r.push(e.children[n])}return n}function hs(e,t,n){let r=new Set;for(let i=e.length-1;i>=0;--i){n.check(`work`);let a=e[i];if(t.has(a)){r.add(a);continue}for(let e of a.children)if(n.check(`work`),r.has(e)){r.add(a);break}}return r}function gs(e,t,n,r,i){if(e.visibleToUser===!1)return!1;let a=_s(e);return t.interactiveOnly?vs(e,a,n,r,i):a.isStructural||a.isVisual?xs(e,a,r):!0}function _s(e){let t=Cs(e.type),n=!!(e.label&&e.label.trim().length>0),r=!!(e.identifier&&e.identifier.trim().length>0);return{type:t,hasMeaningfulText:n&&!Qo(e.label??``),hasMeaningfulId:r&&!Qo(e.identifier??``),isStructural:ws(t),isVisual:t===`imageview`||t===`imagebutton`}}function vs(e,t,n,r,i){return bs(e)?!1:K(e)||ne(t.type)&&r?!0:ys(t,n,r,i)}function ys(e,t,n,r){return!e.hasMeaningfulText&&!e.hasMeaningfulId||e.isVisual||e.isStructural&&!r&&!t?!1:t||n||r}function bs(e){return!!(e.rect&&(e.rect.width<=0||e.rect.height<=0))}function xs(e,t,n){return K(e)||t.hasMeaningfulText||t.hasMeaningfulId?!0:n}function Ss(e){if(!e)return!1;let t=Cs(e);return t.includes(`recyclerview`)||t.includes(`listview`)||t.includes(`gridview`)}function Cs(e){return e?e.toLowerCase():``}function ws(e){let t=e.split(`.`).pop()??e;return t.includes(`layout`)||t===`viewgroup`||t===`view`}function Ts(e,t,n,r){return{...$o(e,t),...n?{clipsDescendants:!0}:{},...r?{windowRect:r}:{}}}const Es=`ANDROID_SNAPSHOT_PRESENTATION_FAILED`;var q=class extends Error{code=Es;qualityReasonCode=`presentation-failed`;details;analysis;constructor(e,t,n){super(e),this.name=`AndroidSnapshotPresentationFailure`,this.details=t,this.analysis=n}};function Ds(e){return e instanceof q?e.code===Es:!!(e&&typeof e==`object`&&e.code===Es)}var Os=class{workUnits=0;options;defaultMaxWorkUnits;deadlineAtMs;constructor(e,t){this.options=e,this.defaultMaxWorkUnits=t;let n=e.now??Date.now;this.deadlineAtMs=e.deadlineAtMs??n()+Ns()}get workUnitCount(){return this.workUnits}check(e){this.consume(1)}consume(e){this.workUnits+=e;let t=this.options.maxWorkUnits??this.defaultMaxWorkUnits;if(this.workUnits>t)throw new q(`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 q(`Android snapshot presentation exceeded its cooperative deadline`,{phase:`deadline`,workUnits:this.workUnits,deadlineAtMs:this.deadlineAtMs,maxWorkUnits:t})}};function ks(e,t){return new Os(e??{},t)}function As(e,t,n){let r=new Map;for(let i of e){n.check(`regular-invariant`);let e=js(i,r,t),a=i.effectiveRect;if(!a||!ae(a)){if(ts(i).hittable===!0)throw new q(`Android regular snapshot node ${i.raw.index} with degenerate effective geometry was marked hittable`,{phase:`regular-invariant`,workUnits:n.workUnitCount,nodeIndex:i.raw.index,frame:a});r.set(i.raw.index,e);continue}if(e&&!Ms(a,e))throw new q(`Android regular snapshot node ${i.raw.index} escaped its cumulative clip`,{phase:`regular-invariant`,workUnits:n.workUnitCount,nodeIndex:i.raw.index,frame:a,clip:e});r.set(i.raw.index,i.clipsDescendants?a:e)}}function js(e,t,n){let r=e.raw.parentIndex;return r===void 0?e.windowRect??n:t.get(r)??e.windowRect??n}function Ms(e,t){let n=1e-4;return e.x>=t.x-n&&e.y>=t.y-n&&e.x+e.width<=t.x+t.width+n&&e.y+e.height<=t.y+t.height+n}function Ns(){return 250}function Ps(e,t,n){let r=n.depth??1/0,i=ce(n.scope),a=Qs(e),o=ks(n.androidPresentation,Math.max(1024,a.rawNodeCount*128)),s={nodes:[],sourceNodes:[],...t===void 0?{}:{maxNodes:t},maxDepth:i?1/0:r,options:n,analysis:a,interactiveDescendantMemo:new Map,hidden:new Set,presentationBudget:o,presentationNodes:[],truncated:!1};try{o.check(`work`),s.viewport=Gs(e,o),s.hidden=n.raw?new Set:is(e,o);for(let t of e.children)if(Is(s,t,0),s.truncated)break;n.raw||As(s.presentationNodes,s.viewport,o);let t=s.nodes,a=new Map(s.sourceNodes.map((e,t)=>[e,t])),{nodes:c,sourceNodes:l}=i?fs(s,e.children,i,r,o):s,u={nodes:c,sourceNodes:l,occlusionContext:{nodes:t,sourceIndexByNodeIndex:new Map(l.flatMap((e,t)=>{let n=a.get(e),r=c[t]?.index;return n===void 0||r===void 0?[]:[[r,n]]})),androidSiblingOrderByNodeIndex:Fs(s.sourceNodes)},analysis:s.analysis};return s.truncated?{...u,truncated:!0}:u}catch(e){throw Ds(e)&&(e.analysis??=s.analysis),e}}function Fs(e){let t=new Map,n=new Map;for(let[r,i]of e.entries()){let e=Yo(i);if(!e)continue;let a=t.get(e.parent);a===void 0&&(a=t.size,t.set(e.parent,a)),n.set(r,{group:a,order:e.order})}return n}function Is(e,t,n,r,i=!1,a=!1,o=!1,s,c){if(e.presentationBudget.check(`work`),Ls(e,t,n))return;let l=t.windowRect??s??e.viewport,u=Rs(e,t,c,l),d=zs(e,t,r,i,a,o,u,l),f=i||K(t),p=a||Ss(t.type),ee=Bs(e,t,u,c);Vs(e,t,n,d,f,p,o||Je(t.identifier),l,ee)}function Ls(e,t,n){return e.maxNodes!==void 0&&e.nodes.length>=e.maxNodes?(e.truncated=!0,!0):n>e.maxDepth||e.hidden.has(t)}function Rs(e,t,n,r){return e.options.raw?t.rect:es(t.rect,r,n)}function zs(e,t,n,r,i,a,o,s){return!e.options.raw&&!gs(t,e.options,r,Js(e,t),i)?n:Hs(e,t,n,a||Je(t.identifier),o,s)}function Bs(e,t,n,r){return e.options.raw||!Ks(t)?r:n}function Vs(e,t,n,r,i,a,o,s,c){for(let l of t.children)if(Is(e,l,n+1,r,i,a,o,s,c),e.truncated)return}function Hs(e,t,n,r,i,a){let o=e.nodes.length;return e.sourceNodes.push(t),Ws(e,t,Us(e,t,n,r),i,a),o}function Us(e,t,n,r){return{index:e.nodes.length,type:t.type??void 0,label:t.label??void 0,value:t.value??void 0,identifier:t.identifier??void 0,bundleId:t.packageName??void 0,rect:t.rect,enabled:t.enabled,focused:t.focused,selected:t.selected,editable:t.editable,password:t.password,hintShowing:t.hintShowing,selectionStart:t.selectionStart,selectionEnd:t.selectionEnd,visibleToUser:t.visibleToUser,hittable:K(t)||void 0,depth:qs(e.nodes,n),parentIndex:n,...Ys(t,e.hidden),...r?{systemChrome:!0}:{}}}function Ws(e,t,n,r,i){let a=Ts(n,r,!e.options.raw&&Ks(t),i);e.presentationNodes.push(a),e.nodes.push(e.options.raw?a.raw:ts(a))}function Gs(e,t){let n=[],r=[...e.children];for(;r.length>0;){t.check(`work`);let e=r.pop();ae(e.windowRect)&&n.push(e.windowRect),r.push(...e.children)}return ie(n)??void 0}function Ks(e){return e.scrollable===!0&&ne(e.type)}function qs(e,t){return t===void 0?0:(e[t]?.depth??-1)+1}function Js(e,t){let n=e.interactiveDescendantMemo.get(t);if(n!==void 0)return n;for(let n of t.children)if(!e.hidden.has(n)&&n.visibleToUser!==!1&&(K(n)||Js(e,n)))return e.interactiveDescendantMemo.set(t,!0),!0;return e.interactiveDescendantMemo.set(t,!1),!1}function Ys(e,t){return Xs(e,t)?{...e.canScrollBackward?{hiddenContentAbove:!0}:{},...e.canScrollForward?{hiddenContentBelow:!0}:{}}:{}}function Xs(e,t){if(!e.scrollable||!ne(e.type)||`${e.type??``}`.toLowerCase().includes(`horizontalscrollview`))return!1;let n=Zs(e,t);return!(n&&n.horizontal>n.vertical&&n.horizontal>16)}function Zs(e,t){let n=e.children.filter(e=>!t.has(e)&&e.visibleToUser!==!1);if(!e.rect||n.length===0)return null;let r=n.map(e=>e.rect).filter(e=>e!==void 0);if(r.length===0)return null;let i=Math.min(...r.map(e=>e.x)),a=Math.max(...r.map(e=>e.x+e.width)),o=Math.min(...r.map(e=>e.y)),s=Math.max(...r.map(e=>e.y+e.height));return{horizontal:Math.max(0,a-i-e.rect.width),vertical:Math.max(0,s-o-e.rect.height)}}function Qs(e){let t=0,n=0,r=[...e.children];for(;r.length>0;){let e=r.pop();t+=1,n=Math.max(n,e.depth),r.push(...e.children)}return{rawNodeCount:t,maxDepth:n}}function $s(){let e=[],t=()=>e.at(-1)===!0;return{open(n,r){let i=t()||Je(n);return r||e.push(i),i},close(){e.pop()}}}function*ec(e){let t=/<node\b[^>]*>|<\/node>/g,n=$s(),r=t.exec(e);for(;r;){let i=r[0];if(i.startsWith(`</node`))n.close();else{let e=tc(i);yield n.open(e.resourceId,i.endsWith(`/>`))?{...e,systemChrome:!0}:e}r=t.exec(e)}}function tc(e){let t=nc(e),n=St(t.bounds);return{...t,...n?{rect:n}:{}}}function nc(e){let t=rc(e),n=e=>dc(t,e),r=e=>{let t=n(e);if(t!==null)return t===`true`},i=e=>{let t=n(e);if(t===null||t.trim()===``)return;let r=Number(t);return Number.isFinite(r)?r:void 0},a=(e,t)=>{let n=i(t);return n===void 0?{}:{[e]:n}},o=(e,t)=>{let r=St(n(t));return r===void 0?{}:{[e]:r}},s=(e,t)=>{let n=r(t);return n===void 0?{}:{[e]:n}};return{text:n(`text`),desc:n(`content-desc`),resourceId:n(`resource-id`),packageName:n(`package`),className:n(`class`),bounds:n(`bounds`),clickable:r(`clickable`),enabled:r(`enabled`),focusable:r(`focusable`),focused:r(`focused`),password:r(`password`),...s(`editable`,`editable`),...a(`selectionStart`,`selection-start`),...a(`selectionEnd`,`selection-end`),...s(`hintShowing`,`hint-showing`),...s(`visibleToUser`,`visible-to-user`),...s(`selected`,`selected`),...a(`drawingOrder`,`drawing-order`),...s(`scrollable`,`scrollable`),...s(`canScrollForward`,`can-scroll-forward`),...s(`canScrollBackward`,`can-scroll-backward`),...a(`windowIndex`,`window-index`),...a(`windowType`,`window-type`),...a(`windowLayer`,`window-layer`),...s(`windowActive`,`window-active`),...s(`windowFocused`,`window-focused`),...o(`windowRect`,`window-bounds`)}}function rc(e){let t=new Map,n=e.indexOf(` `),r=e.lastIndexOf(`>`);if(n<0||r<=n)return t;let i=n;for(;i<r;){let n=ic(e,i,r);if(!n)break;t.set(n.name,n.value),i=n.nextCursor}return t}function ic(e,t,n){if(t=oc(e,t,n),t>=n||sc(e[t]))return;let r=t;t=ac(e,t,n);let i=e.slice(r,t);if(t=oc(e,t,n),!i||e[t]!==`=`)return;t=oc(e,t+1,n);let a=e[t];if(!cc(a))return;let o=t+1,s=e.indexOf(a,o);if(!(s<0||s>=n))return{name:i,value:Ct(e.slice(o,s)),nextCursor:s+1}}function ac(e,t,n){for(;t<n&&!uc(e[t]??``);)t+=1;return t}function oc(e,t,n){for(;t<n&&lc(e[t]??``);)t+=1;return t}function sc(e){return e===`/`||e===`>`}function cc(e){return e===`"`||e===`'`}function lc(e){return e===` `||e===`
|
|
12
|
+
`||e===`\r`||e===` `}function uc(e){return e===`=`||e===`/`||e===`>`||lc(e)}function dc(e,t){return e.get(t)??null}function fc(e){let t={type:null,label:null,value:null,identifier:null,packageName:null,clickable:!1,focusable:!1,depth:-1,children:[]},n=[t],r=/<node\b[^>]*>|<\/node>/g,i=r.exec(e);for(;i;){let t=i[0];if(t.startsWith(`</node`)){n.length>1&&n.pop(),i=r.exec(e);continue}let a=tc(t),o=n.at(-1),s=pc(a,o.depth+1,o);o.children.push(s),t.endsWith(`/>`)||n.push(s),i=r.exec(e)}return t}function pc(e,t,n){return Jo({type:e.className,label:e.text||e.desc,value:e.text,identifier:e.resourceId,packageName:e.packageName,rect:e.rect,enabled:e.enabled,focused:e.focused,selected:e.selected,editable:e.editable,password:e.password,hintShowing:e.hintShowing,selectionStart:e.selectionStart,selectionEnd:e.selectionEnd,visibleToUser:e.visibleToUser,clickable:e.clickable===!0,focusable:e.focusable===!0,scrollable:e.scrollable,canScrollForward:e.canScrollForward,canScrollBackward:e.canScrollBackward,windowIndex:e.windowIndex,windowType:e.windowType,windowLayer:e.windowLayer,windowActive:e.windowActive,windowFocused:e.windowFocused,windowRect:e.windowRect,depth:t,parentIndex:void 0,children:[]},e.drawingOrder===void 0?void 0:{parent:n,order:e.drawingOrder})}function mc(e){let t=new Map;return e.nodes.forEach((n,r)=>{t.set(n.index,e.sourceNodes[r]?.clickable)}),{kind:`exact`,provider:`android-helper`,clickableByNodeIndex:t}}const hc=new Set([`android`,`com.android.systemui`]);function gc(e,t,n={}){if(t.backend!==`android-helper`)return{outcome:`ok`};let r=Dc(e,n.foregroundAppPackage);return yc(r,t)?_c(r,t,`empty-helper-output`,`Android snapshot helper returned no accessibility nodes`):Tc(r)?{outcome:`ok`}:vc(r)?{outcome:`system-surface-only`}:bc(r)?{outcome:`ok`}:xc(r)?_c(r,t,`content-poor-app-window`,`Android snapshot helper returned insufficient foreground app content`):Sc(r)||Cc(r,t)?_c(r,t,`content-poor-app-window`,`Android snapshot helper returned insufficient application window content`):wc(r)?_c(r,t,`system-window-only`,`Android snapshot helper returned only non-application windows`):{outcome:`ok`}}function _c(e,t,n,r){return{outcome:`unusable`,decision:Ec(e,t,n,r)}}function vc(e){return e.windowRootCount>0&&e.applicationWindowRootCount===0&&e.activeSystemSurfaceMeaningfulNodeCount>=3}function yc(e,t){return e.nodeCount===0||t.nodeCount===0||t.rootPresent===!1}function bc(e){return xc(e)&&e.inputMethodMeaningfulNodeCount>=2}function xc(e){let t=e.foregroundAppMeaningfulNodeCount;return t===void 0?!1:t===0?e.applicationMeaningfulNodeCount<2:t<2&&e.meaningfulNodeCount>t}function Sc(e){return e.foregroundAppMeaningfulNodeCount===void 0&&e.applicationWindowRootCount>0&&e.applicationMeaningfulNodeCount<2}function Cc(e,t){return e.foregroundAppMeaningfulNodeCount===void 0&&e.windowRootCount===0&&(t.windowCount??0)>1&&e.nonSystemMeaningfulNodeCount<2}function wc(e){return e.windowRootCount>0&&e.applicationWindowRootCount===0||e.windowRootCount===0&&e.nodeCount>0&&e.systemUiNodeCount===e.nodeCount}function Tc(e){return e.hasAlertButtonIdentifier&&e.hasAlertContentIdentifier}function Ec(e,t,n,r){return{reason:n,failureReason:r,diagnostics:Vc(e,t)}}function Dc(e,t){let n=Oc(t);for(let t of ec(e))kc(n,t);return Ic(n)}function Oc(e){return{nodeCount:0,systemUiNodeCount:0,windowRootCount:0,applicationWindowRootCount:0,activeSystemSurfaceMeaningfulNodeCount:0,meaningfulNodeCount:0,applicationMeaningfulNodeCount:0,nonSystemMeaningfulNodeCount:0,inputMethodMeaningfulNodeCount:0,hasAlertButtonIdentifier:!1,hasAlertContentIdentifier:!1,...e===void 0?{}:{foregroundAppPackage:e,foregroundAppMeaningfulNodeCount:0},windowTypes:new Set}}function kc(e,t){e.nodeCount+=1,Bc(t.packageName)&&(e.systemUiNodeCount+=1),t.visibleToUser!==!1&&Ac(e,t.resourceId),jc(e,t),Mc(e,t)}function Ac(e,t){let n=Vt(t);n===`button`&&(e.hasAlertButtonIdentifier=!0),n===`content`&&(e.hasAlertContentIdentifier=!0)}function jc(e,t){t.windowType!==void 0&&(e.currentWindowType=t.windowType,e.currentWindowActiveOrFocused=t.windowActive===!0||t.windowFocused===!0,e.windowRootCount+=1,e.windowTypes.add(t.windowType),t.windowType===1&&(e.applicationWindowRootCount+=1))}function Mc(e,t){Lc(t)&&(e.meaningfulNodeCount+=1,Nc(e,t),Fc(e,t))}function Nc(e,t){e.currentWindowType===1&&!zc(t.packageName)&&(e.applicationMeaningfulNodeCount+=1),Pc(e)&&!qe(t)&&(e.activeSystemSurfaceMeaningfulNodeCount+=1)}function Pc(e){return e.currentWindowType!==void 0&&e.currentWindowType!==1&&e.currentWindowActiveOrFocused===!0}function Fc(e,t){zc(t.packageName)||(e.nonSystemMeaningfulNodeCount+=1),p({packageName:t.packageName,resourceId:t.resourceId})&&(e.inputMethodMeaningfulNodeCount+=1),e.foregroundAppPackage!==void 0&&t.packageName===e.foregroundAppPackage&&(e.foregroundAppMeaningfulNodeCount=(e.foregroundAppMeaningfulNodeCount??0)+1)}function Ic(e){return{nodeCount:e.nodeCount,systemUiNodeCount:e.systemUiNodeCount,windowRootCount:e.windowRootCount,applicationWindowRootCount:e.applicationWindowRootCount,activeSystemSurfaceMeaningfulNodeCount:e.activeSystemSurfaceMeaningfulNodeCount,meaningfulNodeCount:e.meaningfulNodeCount,applicationMeaningfulNodeCount:e.applicationMeaningfulNodeCount,nonSystemMeaningfulNodeCount:e.nonSystemMeaningfulNodeCount,inputMethodMeaningfulNodeCount:e.inputMethodMeaningfulNodeCount,hasAlertButtonIdentifier:e.hasAlertButtonIdentifier,hasAlertContentIdentifier:e.hasAlertContentIdentifier,...e.foregroundAppPackage===void 0?{}:{foregroundAppPackage:e.foregroundAppPackage,foregroundAppMeaningfulNodeCount:e.foregroundAppMeaningfulNodeCount??0},windowTypes:[...e.windowTypes].sort((e,t)=>e-t).slice(0,8)}}function Lc(e){return e.visibleToUser===!1?!1:Rc(e.text)||Rc(e.desc)||Rc(e.resourceId)}function Rc(e){return e!==null&&e.trim()!==``}function zc(e){return e===null||hc.has(e)}function Bc(e){return e!==null&&hc.has(e)}function Vc(e,t){return{helperNodeCount:e.nodeCount,helperSystemUiNodeCount:e.systemUiNodeCount,helperWindowRootCount:e.windowRootCount,helperApplicationWindowRootCount:e.applicationWindowRootCount,helperMeaningfulNodeCount:e.meaningfulNodeCount,helperApplicationMeaningfulNodeCount:e.applicationMeaningfulNodeCount,helperNonSystemMeaningfulNodeCount:e.nonSystemMeaningfulNodeCount,helperInputMethodMeaningfulNodeCount:e.inputMethodMeaningfulNodeCount,...e.foregroundAppPackage===void 0?{}:{helperForegroundAppPackage:e.foregroundAppPackage,helperForegroundAppMeaningfulNodeCount:e.foregroundAppMeaningfulNodeCount,helperForegroundAppMeaningfulNodeThreshold:2},helperWindowTypes:e.windowTypes,...t.captureMode?{helperCaptureMode:t.captureMode}:{}}}async function Hc(e){let t=await L(e.deviceKey,{resetRuntime:!0,signal:e.signal,cause:e.cause});e.signal?.throwIfAborted(),t||await Uc(e.adb,e.packageName)}async function Uc(e,t){try{await e([`shell`,`am`,`force-stop`,t],{allowFailure:!0,timeoutMs:2e3}),await g(150),h({level:`debug`,phase:`android_snapshot_helper_runtime_reset`,data:{packageName:t}})}catch(e){h({level:`warn`,phase:`android_snapshot_helper_runtime_reset_failed`,data:{packageName:t,error:n(e).message}})}}const Wc=Symbol(`androidSnapshotCaptureEvidence`);function Gc(e,t){return Object.defineProperty(e,Wc,{value:t}),e}function Kc(e){let t={...e,backend:`android`,producer:`android-uiautomator`},n=e[Wc];return te(t,n.clickability),n.occlusionContext&&l(t,n.occlusionContext),t}async function qc(e,t={}){let n=x(e,t.helperAdb).exec;return(await tl(e,t,n)).xml}async function Jc(e,t={}){let n=x(e,t.helperAdb).exec,r=await tl(e,t,n),i=r.xml,a=fc(i),o=Zc(r.metadata,a),s={...t,androidPresentation:{...t.androidPresentation,deadlineAtMs:t.androidPresentation?.deadlineAtMs??Date.now()+250}};try{let e=Ps(a,void 0,s),n=Xc(e.truncated,r.metadata);t.interactiveOnly&&t.includeHiddenContentHints!==!1&&el({options:s,tree:a,xml:i,interactiveSnapshot:e});let{sourceNodes:c,occlusionContext:l,...u}=e;return Gc({...u,...$c(n),androidSnapshot:o,quality:{state:`healthy`,backend:`android-helper`}},{clickability:mc(e),occlusionContext:l})}catch(e){if(!Ds(e))throw e;return Yc({failure:e,androidSnapshot:o})}}function Yc(e){return Gc({nodes:[],truncated:!0,analysis:e.failure.analysis??{rawNodeCount:0,maxDepth:0},androidSnapshot:{...e.androidSnapshot,presentationFailure:{phase:e.failure.details.phase,workUnits:e.failure.details.workUnits,...e.failure.details.maxWorkUnits===void 0?{}:{maxWorkUnits:e.failure.details.maxWorkUnits}}},quality:{state:`sparse`,backend:`android-helper`,reason:e.failure.message,reasonCode:e.failure.qualityReasonCode}},{clickability:{kind:`exact`,provider:`android-helper`,clickableByNodeIndex:new Map}})}function Xc(e,t){return e===!0||t.helperTruncated===!0||e}function Zc(e,t){return Qc(t)===!1?{...e,occlusionScanUnavailable:!0}:e}function Qc(e){let t=[...e.children];if(t.length!==0){for(;t.length>0;){let e=t.pop();if(Yo(e)!==void 0)return!0;t.push(...e.children)}return!1}}function $c(e){return e===!0?{truncated:!0}:{}}function el(e){if(yl(e.interactiveSnapshot.nodes).size>0||vl(e.xml))return;let t=Ps(e.tree,void 0,{...e.options,interactiveOnly:!1});bl(_e(i(t.nodes)),t,e.interactiveSnapshot)}async function tl(e,t,n){let r=x(e,t.helperAdb),i=await m(`android_snapshot_helper_artifact_resolution`,async()=>await gl(t.helperArtifact??r.snapshotHelperArtifact));if(i.artifact)return await nl(e,t,n,i.artifact);throw h({level:`error`,phase:`android_snapshot_helper_unavailable`,data:{reason:i.errorReason??`artifact_not_found`}}),_l(i.errorReason)}async function nl(e,t,n,r){let i=M(e),a=x(e,t.helperAdb),o=t.helperSessionScope!==`daemon-session`;try{let e;for(let o=0;;o+=1){o>0&&await sl(t.signal);let s=await ol({options:t,adb:n,adbProvider:a,artifact:r,helperDeviceKey:i,attempt:o,previousContentReason:e});if(s.outcome===`captured`)return s.capture;if(o+1>=3)return await cl({contentRecovery:s.decision,attempts:o+1,helperDeviceKey:i,artifact:r,adb:n,signal:t.signal});e=s.decision.reason}}finally{o&&await L(i)}}async function rl(e,t,n,r,i){let a=await m(`android_snapshot_helper_install`,async()=>await $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 il(e){let{signal:t,adb:r,adbProvider:i,artifact:a,helperDeviceKey:o}=e,s=Fr({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:Nn});if(e)return e}catch(e){if(t?.throwIfAborted(),Tr(e))throw e;h({level:`warn`,phase:`android_snapshot_helper_session_fallback`,data:{reason:n(e).message}}),await Uc(r,a.manifest.packageName)}return await m(`android_snapshot_helper_capture`,async()=>await Pr(s),{packageName:a.manifest.packageName,version:a.manifest.version,timeoutMs:Nn,commandTimeoutMs:Pn})}function al(e,t,n){return{xml:e.xml,metadata:{backend:`android-helper`,helperVersion:t.manifest.version,helperApiVersion:e.metadata.helperApiVersion,helperTransport:e.metadata.transport,helperSessionReused:e.metadata.sessionReused,installReason:n,waitForIdleTimeoutMs:e.metadata.waitForIdleTimeoutMs,waitForIdleQuietMs:e.metadata.waitForIdleQuietMs,timeoutMs:e.metadata.timeoutMs,maxDepth:e.metadata.maxDepth,maxNodes:e.metadata.maxNodes,rootPresent:e.metadata.rootPresent,captureMode:e.metadata.captureMode,windowCount:e.metadata.windowCount,nodeCount:e.metadata.nodeCount,helperTruncated:e.metadata.truncated,elapsedMs:e.metadata.elapsedMs}}}async function ol(e){let{options:t,adb:n,adbProvider:r,artifact:i,helperDeviceKey:a,attempt:o}=e,s;try{let e=await rl(t,n,r,i,a);e.installed&&await L(a),s=al(await il({signal:t.signal,adb:n,adbProvider:r,artifact:i,helperDeviceKey:a}),i,e.reason)}catch(e){return t.signal?.throwIfAborted(),{outcome:`captured`,capture:await ll({error:e,helperDeviceKey:a,artifact:i,adb:n})}}let c=gc(s.xml,s.metadata,{foregroundAppPackage:t.appBundleId});return c.outcome===`system-surface-only`?(h({phase:`android_snapshot_helper_system_surface`,data:{foregroundAppPackage:t.appBundleId}}),{outcome:`captured`,capture:{xml:s.xml,metadata:{...s.metadata,systemSurfaceOnly:!0}}}):c.outcome===`ok`?(o>0&&h({phase:`android_snapshot_helper_content_recaptured`,data:{attempts:o+1,recoveredFromReason:e.previousContentReason}}),{outcome:`captured`,capture:s}):{outcome:`unusable`,decision:c.decision}}async function sl(e){e?.throwIfAborted(),await g(250),e?.throwIfAborted()}async function cl(e){throw h({level:`error`,phase:`android_snapshot_helper_content_invalid`,data:{reason:e.contentRecovery.reason,failureReason:e.contentRecovery.failureReason,attempts:e.attempts,...e.contentRecovery.diagnostics}}),await Hc({adb:e.adb,deviceKey:e.helperDeviceKey,packageName:e.artifact.manifest.packageName,signal:e.signal,cause:e.contentRecovery.failureReason}),new t(`COMMAND_FAILED`,e.contentRecovery.failureReason,{...e.contentRecovery.diagnostics,androidSnapshotHelperFailureReason:e.contentRecovery.reason,attempts:e.attempts,retriable:!0,hint:`Retry after the app UI stabilizes. If this persists, capture a screenshot and report the helper diagnostics; agent-device does not substitute a second snapshot engine.`})}async function ll(e){let t=ul(e.error);throw h({level:`error`,phase:`android_snapshot_helper_failed`,data:{reason:t}}),await L(e.helperDeviceKey),await Uc(e.adb,e.artifact.manifest.packageName),Jn({deviceKey:e.helperDeviceKey,packageName:e.artifact.manifest.packageName,versionCode:e.artifact.manifest.versionCode}),dl(e.error,t)}function ul(e){let t=n(e),r=hl(t.details?.helper);if(r&&r!==t.message)return`${t.message}: ${r}`;if(r)return r;let i=(typeof t.details?.stderr==`string`?t.details.stderr.trim():``).split(/\r?\n/).find(e=>e.trim());return i?`${t.message}: ${i}`:t.message}function dl(e,i){let a=n(e),o=fl(a);return new t(r(a.code),`Android snapshot helper failed: ${i}`,{...a.details,...ml(a),androidSnapshotHelperFailureReason:i,...o?{androidCaptureFailureReason:o}:{},hint:pl(a,o)},e)}function fl(e){return Ye(e)}function pl(e,t){return t===`accessibility-timeout`?`Android accessibility snapshots can be blocked by busy or continuously changing app UI. Use screenshot as visual truth after this timeout and report the busy UI if it persists.`:e.details?.androidSnapshotHelperInstallFailure===!0?[e.hint,`This is a device-side install failure (adb rejection or OEM policy) — the helper artifact itself is present, this is not a missing/unbuilt build.`].filter(Boolean).join(` `):e.hint??`Retry once. If the helper still fails, run agent-device doctor and report the diagnostic log; agent-device does not substitute a second snapshot engine.`}function ml(e){let t={};return e.diagnosticId!==void 0&&(t.diagnosticId=e.diagnosticId),e.logPath!==void 0&&(t.logPath=e.logPath),e.retriable!==void 0&&(t.retriable=e.retriable),e.supportedOn!==void 0&&(t.supportedOn=e.supportedOn),t}function hl(e){if(!e||typeof e!=`object`||!(`message`in e))return;let t=String(e.message).trim();return t&&t!==`null`?t:void 0}async function gl(e){if(e)return{artifact:e};let t=De(),r=C.join(Ee(),`android`,`snapshot-helper`,`dist`),i=C.join(r,`agent-device-android-snapshot-helper-${t}.manifest.json`);try{await v().files.access(i)}catch{return{}}try{let e=D(JSON.parse(await v().files.readText(i))),t=C.join(r,e.assetName??`agent-device-android-snapshot-helper-${e.version}.apk`);return await v().files.access(t),{artifact:{apkPath:t,manifest:e}}}catch(e){return{errorReason:n(e).message}}}function _l(e){let n=e??`the bundled helper artifact was not found`;return new t(`COMMAND_FAILED`,`Android snapshot helper is unavailable: ${n}`,{androidSnapshotHelperFailureReason:n,hint:"Run `pnpm build:android` to build the helper dist for a source checkout — the runtime needs android/snapshot-helper/dist/agent-device-android-snapshot-helper-<version>.manifest.json and the .apk it references. Packaged installs ship these via the prepack script; if they are missing from a packaged install, reinstall agent-device."})}function vl(e){return e.includes(` can-scroll-forward=`)||e.includes(` can-scroll-backward=`)}function yl(e){let t=new Map;for(let n of e){let e={};n.hiddenContentAbove&&(e.hiddenContentAbove=!0),n.hiddenContentBelow&&(e.hiddenContentBelow=!0),(e.hiddenContentAbove||e.hiddenContentBelow)&&t.set(n.index,e)}return t}function bl(e,t,n){if(e.size===0)return;let r=new Map;for(let[e,t]of n.sourceNodes.entries()){let i=n.nodes[e];i&&r.set(t,i)}for(let[n,i]of e){let e=t.sourceNodes[n];if(!e)continue;let a=r.get(e);a&&(i.hiddenContentAbove&&(a.hiddenContentAbove=!0),i.hiddenContentBelow&&(a.hiddenContentBelow=!0))}}async function xl(e,t,n,r,i={}){let a=[0,150,350],o=null,s=null,c=await Bl(e);for(let l of a){l>0&&await g(l);let a=await Al(e,t,n,r,c,i);if(o=a,a.reason===`ime_capture`)return a;s=a.ok?a:null}return s??o??{ok:!1,actual:null,reason:`text_mismatch`,targetInput:null,actualInput:null}}async function Sl(e,t,n,r={}){return Dl(await qc(e,r),t,n)}async function Cl(e,t,n,r){let i=await Bl(e);return jl(await qc(e,r),t,n,i).targetInput}async function wl(e,t,n,r={}){try{return await Cl(e,t,n,r)}catch(e){return h({level:`warn`,phase:`android_fill_pre_action_target_capture_failed`,data:{error:e instanceof Error?e.message:String(e)}}),null}}function J(e,n,r){if(r?.ok)return;let i=r?Tl(e,n,r):null;if(i)return i;throw new t(`COMMAND_FAILED`,Ol(r),kl(e,r))}function Tl(e,t,n){let r=n.targetInput,i=n.actualInput;if(e.length===0||n.reason===`ime_capture`||!t||!r||!i||G(t)||G(r)||G(i)||!Kl(t,r)||!Kl(t,i)||t.text===n.actual)return null;let a=ql(t);return h({level:`warn`,phase:`android_fill_verification_unconfirmed`,data:{target:a}}),{verification:`unconfirmed`,requested:e,before:t.text,after:n.actual,target:a}}function El(e,t,n,r,i={}){let a=jl(e,t,n,i);return Ml(a)?{ok:!1,actual:a.actualInput?.text??null,reason:`ime_capture`,targetInput:a.targetInput,actualInput:a.actualInput}:Nl(a,r)??Pl(a,r)}function Dl(e,t,n){return jl(e,t,n).targetInput?.text??null}function Ol(e){return e?.reason===`ime_capture`?`Android fill input was captured by the active keyboard instead of the app field`:e?.reason===`masked_unverified`?`Android fill verification could not confirm masked text value`:`Android fill verification failed`}function kl(e,t){let n=Ho(e,t);return t?.reason===`ime_capture`&&(n.hint=`The focused input belongs to the Android keyboard/IME, not the app field. Disable handwriting/stylus input or switch to a standard IME, then retry fill.`),n}async function Al(e,t,n,r,i,a){return El(await qc(e,a),t,n,r,i)}function jl(e,t,n,r={}){let i={focusedEdit:null,editAtPoint:null,anyAtPoint:null};for(let a of ec(e)){let e=zl(a,r);e&&Vl(i,e,t,n)}return Ul(i)}function Ml(e){let{targetInput:t,actualInput:n}=e;return!t||!n||n===t?!1:n.inputMethodOwned&&!t.inputMethodOwned}function Nl(e,t){let n=e.actualInput;if(!n||!Gl(n))return null;let r=n.text??null,i=Array.from(Fl(n)).length,a=Array.from(t).length,o=a===0?i===0:i>0&&i===a;return{ok:o,actual:r,reason:o?void 0:`masked_unverified`,masked:!0,targetInput:e.targetInput,actualInput:n}}function Pl(e,t){let n=e.actualInput;return{ok:n!==null&&Il(Fl(n),t),actual:n?.text??null,reason:`text_mismatch`,targetInput:e.targetInput,actualInput:n}}function Fl(e){return e.hintShowing?``:e.text??``}function Il(e,t){if(e===t)return!0;if(t.length===0)return!1;let n=Ll(e),r=Ll(t);return!n||!r?!1:!!(n===r||Rl(n,r))}function Ll(e){return e.replaceAll(/\s+/g,` `).trim()}function Rl(e,t){if(e.length!==t.length||e.length===0||e.slice(1)!==t.slice(1))return!1;let n=e[0],r=t[0];return!n||!r?!1:r.toLowerCase()===r&&n===r.toUpperCase()}function zl(e,t){if(!e.rect)return null;let n=e.text??``,r=Math.max(1,e.rect.width*e.rect.height);return{text:n||null,className:e.className,resourceId:e.resourceId,packageName:e.packageName,rect:e.rect,focused:e.focused??!1,password:e.password===!0,inputMethodOwned:p({packageName:e.packageName,resourceId:e.resourceId,activeInputMethodPackage:t.activeInputMethodPackage}),area:r,editText:Wl(e.className??``),hintShowing:e.hintShowing===!0}}async function Bl(e){try{return{activeInputMethodPackage:(await ja(e)).inputMethodPackage}}catch(e){return h({level:`warn`,phase:`android_fill_verification_input_method_probe_failed`,data:{error:e instanceof Error?e.message:String(e)}}),{}}}function Vl(e,t,n,r){let i=re(t.rect,n,r);if(i&&t.editText&&(e.editAtPoint=Hl(e.editAtPoint,t)),t.focused&&t.editText){e.focusedEdit=Hl(e.focusedEdit,t);return}i&&t.text&&(e.anyAtPoint=Hl(e.anyAtPoint,t))}function Hl(e,t){return e&&e.area<t.area?e:t}function Ul(e){let t=e.editAtPoint??e.anyAtPoint;return{targetInput:t,actualInput:(e.focusedEdit?.text?e.focusedEdit:null)??t}}function Wl(e){let t=e.toLowerCase();return t.includes(`edittext`)||t.includes(`textfield`)}function Gl(e){return G(e)}function Kl(e,t){return e.resourceId||t.resourceId?e.resourceId===t.resourceId&&e.packageName===t.packageName:e.className===t.className&&e.packageName===t.packageName&&e.rect.x===t.rect.x&&e.rect.y===t.rect.y&&e.rect.width===t.rect.width&&e.rect.height===t.rect.height}function ql(e){return{resourceId:e.resourceId,className:e.className,packageName:e.packageName,rect:e.rect}}async function Jl(e,t){return await wt(t.stateDir),await bo(t.stateDir,e.id,async()=>await Yl(e,t))}async function Yl(e,t){let r=v().imeRecoveryMarkers,i=b(e),a=x(e),o=V(e),s;try{s=await Qa(a),await no({adb:i,adbProvider:a,artifact:s,deviceKey:o})}catch(e){return{outcome:`helper-unavailable`,reason:n(e).message}}let{manifest:c}=s,l=await H(i);if(l===c.serviceComponent){let n=await r.write(t.stateDir,e.id),a=await U(i);return n&&W.add(o),{outcome:`settled`,activated:!1,alreadyActive:!0,...n?{}:{persistFailed:!0},previousIme:a,helperServiceComponent:c.serviceComponent,helperPackageName:c.packageName}}let u=await U(i);if(!await po(i,l))return await ho(i,u,e.id),_({level:`warn`,phase:`android_test_ime_persist_failed`,data:{device:e.id,previousIme:l}}),{outcome:`settled`,activated:!1,alreadyActive:!1,persistFailed:!0,helperServiceComponent:c.serviceComponent,helperPackageName:c.packageName};let d=(await r.read(t.stateDir)).includes(e.id);if(!await r.write(t.stateDir,e.id))return await ho(i,u,e.id),_({level:`warn`,phase:`android_test_ime_marker_persist_failed`,data:{device:e.id,previousIme:l}}),{outcome:`settled`,activated:!1,alreadyActive:!1,persistFailed:!0,helperServiceComponent:c.serviceComponent,helperPackageName:c.packageName};await i([`shell`,`ime`,`enable`,c.serviceComponent],{allowFailure:!0,timeoutMs:1e4});let f=await i([`shell`,`ime`,`set`,c.serviceComponent],{allowFailure:!0,timeoutMs:1e4}),p=await H(i);return p===c.serviceComponent?(W.add(o),_({phase:`android_test_ime_activated`,data:{device:e.id,previousIme:l}}),{outcome:`settled`,activated:!0,alreadyActive:!1,previousIme:l,helperServiceComponent:c.serviceComponent,helperPackageName:c.packageName}):(W.delete(o),await ho(i,u,e.id),d||await r.clear(t.stateDir,e.id),_({level:`warn`,phase:`android_test_ime_activate_failed`,data:{device:e.id,activeIme:p,stderr:f.stderr.trim()}}),{outcome:`settled`,activated:!1,alreadyActive:!1,helperServiceComponent:c.serviceComponent,helperPackageName:c.packageName})}function Xl(e){return C.join(e,`android-test-ime-pending`)}function Zl(e,t){return C.join(Xl(e),encodeURIComponent(t))}async function Ql(e,t){let r=v().files,i,a=!1;try{let n=Xl(e);if(i=Zl(e,t),await r.ensureDirectory(n),(await tu(i))?.serial===t)return!0;let o={version:1,serial:t};if(await r.writeAtomicText(i,`${JSON.stringify(o)}\n`,384),a=!0,(await tu(i))?.serial!==t)throw Error(`Android test IME marker read-back did not match the requested device.`);return!0}catch(o){return a&&i&&await r.remove(i,{force:!0}).catch(()=>{}),h({level:`debug`,phase:`android_test_ime_marker_write_failed`,data:{stateDir:e,serial:t,error:n(o).message}}),!1}}async function $l(e,t){await v().files.remove(Zl(e,t),{force:!0}).catch(()=>{})}async function eu(e){let t=v().files,n;try{n=await t.readDirectory(Xl(e))}catch{return[]}let r=[];for(let t of n)try{let n=C.join(Xl(e),t),i=await tu(n);i&&Zl(e,i.serial)===n&&r.push(i.serial)}catch{}return[...new Set(r)].sort()}async function tu(e){try{return nu(await v().files.readText(e))}catch{return}}function nu(e){try{let t=JSON.parse(e);if(!t||typeof t!=`object`||Array.isArray(t))return;let n=t;return n.version===1&&typeof n.serial==`string`&&n.serial.length>0?{version:1,serial:n.serial}:void 0}catch{return}}const ru=new Dt(`utf-16le`);let iu;async function au(e,t){for(let n of[`AndroidManifest.xml`,`base/manifest/AndroidManifest.xml`]){let r=await ou(e,n,t);if(!r)continue;let i=su(r);if(i)return i}return await gu(e,t)}async function ou(e,t,n){try{let r=await be(`unzip`,[`-p`,e,t],{allowFailure:!0,binaryStdout:!0,signal:n});return r.exitCode!==0||!r.stdoutBuffer||r.stdoutBuffer.length===0?void 0:r.stdoutBuffer}catch{n?.throwIfAborted();return}}function su(e){return e.subarray(0,Math.min(e.length,128)).toString(`utf8`).trimStart().startsWith(`<`)?cu(e.toString(`utf8`)):lu(e)}function cu(e){return e.match(/<manifest\b[^>]*\bpackage\s*=\s*["']([^"']+)["']/i)?.[1]}function lu(e){if(e.length<8||e.readUInt16LE(0)!==3)return;let t;for(let n=e.readUInt16LE(2);n+8<=e.length;){let r=e.readUInt16LE(n),i=e.readUInt16LE(n+2),a=e.readUInt32LE(n+4);if(a<=0||n+a>e.length)return;if(r===1)t=du(e.subarray(n,n+a));else if(r===258&&t){let r=uu(e,n,i,t);if(r)return r}n+=a}}function uu(e,t,n,r){if(n<36||t+n>e.length||r[e.readUInt32LE(t+20)]!==`manifest`)return;let i=e.readUInt16LE(t+24),a=e.readUInt16LE(t+26),o=e.readUInt16LE(t+28),s=t+i;for(let t=0;t<o;t+=1){let n=s+t*a;if(n+20>e.length)return;if(r[e.readUInt32LE(n+4)]!==`package`)continue;let i=e.readUInt32LE(n+8);if(i!==4294967295)return r[i];let o=e.readUInt8(n+15),c=e.readUInt32LE(n+16);return o===3?r[c]:void 0}}function du(e){if(e.length<28)return[];let t=e.readUInt32LE(8),n=e.readUInt32LE(16),r=e.readUInt32LE(20),i=!!(n&256),a=[];for(let n=0;n<t;n+=1){let t=28+n*4;if(t+4>e.length)return a;let o=r+e.readUInt32LE(t);a.push(i?fu(e,o):pu(e,o))}return a}function fu(e,t){let[,n]=mu(e,t),[r,i]=mu(e,t+n),a=t+n+i;return e.subarray(a,a+r).toString(`utf8`)}function pu(e,t){let[n,r]=hu(e,t),i=t+r;return ru.decode(e.subarray(i,i+n*2))}function mu(e,t){let n=e.readUInt8(t);if(!(n&128))return[n,1];let r=e.readUInt8(t+1);return[(n&127)<<8|r,2]}function hu(e,t){let n=e.readUInt16LE(t);if(!(n&32768))return[n,2];let r=e.readUInt16LE(t+2);return[(n&32767)<<16|r,4]}async function gu(e,t){t?.throwIfAborted();let n=await _u();if(!n)return;let r=await be(n,[`dump`,`badging`,e],{allowFailure:!0,signal:t});if(r.exitCode===0)return r.stdout.match(/package:\s+name='([^']+)'/)?.[1]}async function _u(){if(iu!==void 0)return iu??void 0;try{let e=v().files;for(let t of it()){let n=C.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=C.join(n,r,`aapt`);if(C.isAbsolute(t)&&await e.isExecutable(t))return iu=t,t}}catch{}}}catch{}iu=null}async function vu(e,t){let n=e.kind===`url`&&Oe(e.url),r=await ke({source:e,isInstallablePath:(e,t)=>t.isFile()&&yu(e),installableLabel:`Android installable (.apk or .aab)`,allowArchiveExtraction:e.kind!==`url`||n,signal:t?.signal});try{let e=t?.resolveIdentity===!1?{}:await bu(r.installablePath,t?.signal);return{archivePath:r.archivePath,installablePath:r.installablePath,packageName:e.packageName,cleanup:r.cleanup}}catch(e){throw await r.cleanup(),e}}function yu(e){let t=C.extname(e).toLowerCase();return t===`.apk`||t===`.aab`}async function bu(e,t){let n=C.extname(e).toLowerCase();return n!==`.apk`&&n!==`.aab`?{}:{packageName:await au(e,t)}}async function xu(e,n,r,i={}){let a=typeof r.action==`string`&&r.action.trim()?r.action.trim():`${n}.TEST_PUSH`,o=[`shell`,`am`,`broadcast`,`-a`,a,`-p`,n],s=typeof r.receiver==`string`?r.receiver.trim():``;s&&o.push(`-n`,s);let c=r.extras;if(c!==void 0&&(typeof c!=`object`||!c||Array.isArray(c)))throw new t(`INVALID_ARGS`,`Android push payload extras must be an object`);let l=c??{},u=0;for(let[e,t]of Object.entries(l))e&&(Su(o,e,t),u+=1);return await S(e,o,{signal:i.signal}),{action:a,extrasCount:u}}function Su(e,n,r){if(typeof r==`string`){e.push(`--es`,n,r);return}if(typeof r==`boolean`){e.push(`--ez`,n,r?`true`:`false`);return}if(typeof r==`number`&&Number.isFinite(r)){if(Number.isInteger(r)){e.push(`--ei`,n,String(r));return}e.push(`--ef`,n,String(r));return}throw new t(`INVALID_ARGS`,`Unsupported Android broadcast extra type for "${n}". Use string, boolean, or number.`)}function Y(e){let t=e.replaceAll(`,`,``).match(/^-?\d+(?:\.\d+)?/);if(!t)return null;let n=Number(t[0]);return Number.isFinite(n)?n:null}function Cu(e){let t=Ou(e.map(e=>e.intendedVsyncNs)),n=[];for(let e=1;e<t.length;e+=1){let r=t[e]-t[e-1];r>=4e6&&r<=5e7&&n.push(r)}if(n.length!==0)return ku(n)}function wu(e){let{frames:t,frameDeadlineNs:n,summaryDroppedFrameCount:r}=e;return r===void 0?n===void 0?[]:t.filter(e=>e.durationNs>n):r<=0?[]:[...t].sort((e,t)=>t.durationNs-e.durationNs).slice(0,r).sort((e,t)=>e.intendedVsyncNs-t.intendedVsyncNs)}function Tu(e){let{frames:t,windowStartNs:n,measuredAtMs:r,uptimeMs:i}=e;if(t.length===0||n===void 0)return[];let a=[],o=[];for(let e of t){let t=o.at(-1);if(!t||e.intendedVsyncNs-t.frameCompletedNs<=5e8){o.push(e);continue}a.push(o),o=[e]}return o.length>0&&a.push(o),a.map(e=>Du({frames:e,windowStartNs:n,measuredAtMs:r,uptimeMs:i})).sort((e,t)=>t.missedDeadlineFrameCount-e.missedDeadlineFrameCount||t.worstFrameMs-e.worstFrameMs).slice(0,3).sort((e,t)=>e.startOffsetMs-t.startOffsetMs)}function Eu(e){return Math.round(e*10)/10}function Du(e){let{frames:t,windowStartNs:n,measuredAtMs:r,uptimeMs:i}=e,a=Math.min(...t.map(e=>e.intendedVsyncNs)),o=Math.max(...t.map(e=>e.frameCompletedNs)),s=Math.max(0,Math.round((a-n)/1e6)),c=Math.max(s,Math.round((o-n)/1e6)),l=i!==void 0&&Number.isFinite(r)?r-i:void 0;return{startOffsetMs:s,endOffsetMs:c,startAt:l===void 0?void 0:new Date(l+a/1e6).toISOString(),endAt:l===void 0?void 0:new Date(l+o/1e6).toISOString(),missedDeadlineFrameCount:t.length,worstFrameMs:Eu(Math.max(...t.map(e=>e.durationNs))/1e6)}}function Ou(e){return[...new Set(e.filter(e=>Number.isFinite(e)))].sort((e,t)=>e-t)}function ku(e){let t=[...e].sort((e,t)=>e-t),n=Math.floor(t.length/2);return t.length%2==1?t[n]:(t[n-1]+t[n])/2}function Au(e,t,n){ju(e,t);let r=Vu(e),i=Lu(e),a=Nu(i,r,t),o=Date.parse(n),s=Uu({frames:i,measuredAtMs:o,summary:r}),c=wu({frames:i,frameDeadlineNs:a,summaryDroppedFrameCount:r?.droppedFrameCount}),l=r?.sampleWindowMs??s.sampleWindowMs??qu(i),u=Pu(r,i,c),d=Iu({droppedFrames:c,timing:s,measuredAtMs:o,summary:r});return{...u,sampleWindowMs:l,...Fu(a),windowStartedAt:s.windowStartedAt,windowEndedAt:s.windowEndedAt,timestampSource:s.timestampSource,measuredAt:n,method:`adb-shell-dumpsys-gfxinfo-framestats`,source:r?`android-gfxinfo-summary`:`framestats-rows`,worstWindows:d&&d.length>0?d:void 0}}function ju(e,n){if(/no process found for:/i.test(e))throw new t(`COMMAND_FAILED`,`Android gfxinfo did not find a running process for ${n}`,{metric:`fps`,package:n,hint:`Run open <app> for this session again to ensure the Android app is active, then retry perf after the interaction you want to inspect.`})}function Mu(e){throw new t(`COMMAND_FAILED`,`Failed to parse Android framestats output for ${e}`,{metric:`fps`,package:e,hint:`Retry perf after exercising the app screen. If the problem persists, capture adb shell dumpsys gfxinfo <package> framestats output for debugging.`})}function Nu(e,n,r){let i=Cu(e);if(!n&&e.length===0&&Mu(r),n||i!==void 0)return i;throw new t(`COMMAND_FAILED`,`Failed to infer Android frame deadline from framestats output for ${r}`,{metric:`fps`,package:r,hint:`Retry perf after a longer interaction window so consecutive Android frame timestamps are available.`})}function Pu(e,t,n){let r=e?.totalFrameCount??t.length,i=e?.droppedFrameCount??n.length;return{totalFrameCount:r,droppedFrameCount:i,droppedFramePercent:e?.droppedFramePercent??(r>0?Tt(i/r*100):0)}}function Fu(e){return{frameDeadlineMs:e===void 0?void 0:Eu(e/1e6),refreshRateHz:e===void 0?void 0:Eu(1e9/e)}}function Iu(e){let{droppedFrames:t,timing:n,measuredAtMs:r,summary:i}=e;if(t.length===0)return;let a=Tu({frames:t,windowStartNs:n.windowStartNs,measuredAtMs:r,uptimeMs:i?.uptimeMs});return a.length>0?a:void 0}function Lu(e){let t=[],n=null;for(let r of e.split(`
|
|
13
|
+
`)){let e=r.trim();if(e.length===0||e===`---PROFILEDATA---`)continue;let i=e.split(`,`).map(e=>e.trim());if(Ru(i)){n=new Map(i.map((e,t)=>[e,t]));continue}let a=zu(i,n);a&&t.push(a)}return t.sort((e,t)=>e.intendedVsyncNs-t.intendedVsyncNs)}function Ru(e){return e.includes(`IntendedVsync`)&&e.includes(`FrameCompleted`)}function zu(e,t){if(!t||e.length<t.size)return;let n=Bu(e,t,`Flags`),r=Bu(e,t,`IntendedVsync`),i=Bu(e,t,`FrameCompleted`);if(!(n!==0||r===null||i===null||r<=0||i<=r))return{intendedVsyncNs:r,frameCompletedNs:i,durationNs:i-r}}function Bu(e,t,n){let r=t.get(n);if(r===void 0)return null;let i=Number(e[r]);return Number.isFinite(i)?i:null}function Vu(e){let t=e.split(/\nProfile data in ms:\n/i)[0]??``,n=Ju(t,`Total frames rendered`),r=t.match(/^\s*Janky frames:\s*([0-9][0-9,]*)\s*\(([0-9.]+)%\)/im);if(n===void 0||!r)return;let i=r[1],a=r[2];if(i===void 0||a===void 0)return;let o=Y(i)??void 0,s=Number(a);if(o===void 0||!Number.isFinite(s)||n<0)return;let c=Ju(t,`Uptime`),l=Ju(t,`Stats since`);return{droppedFramePercent:Tt(s),droppedFrameCount:o,totalFrameCount:n,sampleWindowMs:Hu({uptimeMs:c,statsSinceNs:l}),uptimeMs:c,statsSinceNs:l}}function Hu(e){let{uptimeMs:t,statsSinceNs:n}=e;if(t===void 0||n===void 0)return;let r=t-Math.round(n/1e6);return r>=0?r:void 0}function Uu(e){let{frames:t,measuredAtMs:n,summary:r}=e,i=Wu(t),a=r?.statsSinceNs,o=a??i.firstFrameNs,s=Gu(o,i.lastFrameNs),c=r?.sampleWindowMs??s;if(!Number.isFinite(n)||r?.uptimeMs===void 0||o===void 0)return{sampleWindowMs:c,windowStartNs:o};let l=n-r.uptimeMs;return{sampleWindowMs:c,windowStartNs:o,windowStartedAt:new Date(l+o/1e6).toISOString(),windowEndedAt:Ku({deviceBootWallClockMs:l,measuredAtMs:n,summaryStartNs:a,lastFrameNs:i.lastFrameNs}),timestampSource:`estimated-from-device-uptime`}}function Wu(e){return e.length===0?{}:{firstFrameNs:Math.min(...e.map(e=>e.intendedVsyncNs)),lastFrameNs:Math.max(...e.map(e=>e.frameCompletedNs))}}function Gu(e,t){if(e!==void 0&&t!==void 0)return Math.max(0,Math.round((t-e)/1e6))}function Ku(e){let{deviceBootWallClockMs:t,measuredAtMs:n,summaryStartNs:r,lastFrameNs:i}=e;return r===void 0?i===void 0?void 0:new Date(t+i/1e6).toISOString():new Date(n).toISOString()}function qu(e){if(e.length===0)return;let t=Wu(e);return Gu(t.firstFrameNs,t.lastFrameNs)}function Ju(e,t){let n=t.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`),r=e.match(RegExp(`^\\s*${n}:\\s*([0-9][0-9,]*)`,`im`));if(!r)return;let i=r[1];return i===void 0?void 0:Y(i)??void 0}async function Yu(e,t,n={}){let r=b(e,n.adb);try{let i=Au((await r([`shell`,`dumpsys`,`gfxinfo`,t,`framestats`],{timeoutMs:15e3})).stdout,t,new Date().toISOString());return await Xu(e,t,n),i}catch(e){throw Zu(t,e)}}async function Xu(e,t,n={}){let r=b(e,n.adb);try{await r([`shell`,`dumpsys`,`gfxinfo`,t,`reset`],{allowFailure:!0,timeoutMs:3e3})}catch{}}function Zu(e,n){return n instanceof t?new t(n.code,n.message,{...n.details??{},metric:`fps`,package:e},n):new t(`COMMAND_FAILED`,`Failed to sample Android fps for ${e}`,{metric:`fps`,package:e},n)}function X(e,n,r,i){if(i instanceof t){let a=i.details??{};return new t(i.code,i.message,{...a,action:e,package:r,tool:n,hint:typeof a.hint==`string`?a.hint:ed(n,a)},i)}return new t(`COMMAND_FAILED`,`Failed to ${e} Android ${n} for ${r}`,{action:e,package:r,tool:n,hint:Qu(n)},i)}function Qu(e){return e===`simpleperf`?`Verify simpleperf is available, the app process is running, and the app/device permits native CPU profiling.`:`Verify perfetto is available, the app process is running, and the device permits trace capture.`}function $u(e){return e===`simpleperf`?`Use an emulator/system image with simpleperf available, or install the Android NDK simpleperf binary for this device.`:`Use Android 10+ or a system image that exposes the perfetto command-line binary.`}function ed(e,t){let n=(typeof t.stderr==`string`?t.stderr:``).toLowerCase();return e===`simpleperf`?td(n):rd(n)?`Use a device image that permits perfetto trace capture for shell, keep the app running, then retry perf trace start.`:Qu(e)}function td(e){return nd(e)?`Use a debuggable/profileable Android app or a device image that permits simpleperf for the target process, then retry perf cpu profile start.`:e.includes(`not supported`)||e.includes(`failed to open perf event`)?`This device image does not expose the requested simpleperf event for the app process. Try a different emulator/system image or a profileable app.`:Qu(`simpleperf`)}function nd(e){return e.includes(`permission denied`)||e.includes(`not profileable`)||e.includes(`profileable`)}function rd(e){return e.includes(`permission denied`)||e.includes(`not allowed`)}async function id(e,t,n,r,i){return{capture:{durationMs:r,packageName:t.packageName,appPid:t.appPid,artifactPath:t.outPath,sizeBytes:n},frameHealth:t.kind===`perfetto`?await ad(e,t.packageName,i):void 0,notes:[t.kind===`perfetto`?`Frame health is sampled from Android gfxinfo around the trace window; open the Perfetto artifact for timeline root cause.`:`Open the Simpleperf report artifact for symbol-level CPU attribution.`]}}async function ad(e,t,n){try{let r=await Yu(e,t,n);return{available:!0,droppedFramePercent:r.droppedFramePercent,droppedFrameCount:r.droppedFrameCount,totalFrameCount:r.totalFrameCount,method:r.method,worstWindows:r.worstWindows?.slice(0,3).map(e=>({startOffsetMs:e.startOffsetMs,endOffsetMs:e.endOffsetMs,missedDeadlineFrameCount:e.missedDeadlineFrameCount,worstFrameMs:e.worstFrameMs}))}}catch(e){return{available:!1,reason:e instanceof Error?e.message:`Android frame health was not available`}}}const od=`adb-shell-simpleperf`,sd=`adb-shell-perfetto`,cd=15e3,Z=3e4,ld=`/data/local/tmp`;async function ud(e,t,n){let r=b(e,n.adb);await gd(r,t),await yd(r,t),await vd(r,t,n.files);let i=await hd(t.outPath,n.files);await pd(r,t.remotePath);let a=Date.now(),o=Math.max(0,a-t.startedAt),s=await id(e,t,i,o,{adb:r});return{...t,action:`stop`,platform:`android`,state:`stopped`,stoppedAt:a,durationMs:o,sizeBytes:i,method:t.kind===`simpleperf`?od:sd,artifact:{path:t.outPath,sizeBytes:i},summary:s,message:`Stopped Android ${t.kind} ${t.type} for ${t.packageName}`}}async function dd(e,t,n={}){let r=b(e,n.adb);try{t.state===`running`&&(await gd(r,t),await yd(r,t).catch(()=>{}))}finally{await pd(r,t.remotePath)}}function fd(e,t,n=ld){return`${n}/agent-device-${e.replaceAll(/[^A-Za-z0-9_.-]/g,`_`)}-${Date.now()}-${t}`}async function pd(e,t){try{await e([`shell`,`rm -f ${Q(t)}`],{allowFailure:!0,timeoutMs:cd})}catch{}}async function md(e,t,n=v().files){await n.ensureDirectory(C.dirname(e)),await n.writeBytes(e,Buffer.from(`${JSON.stringify(t,null,2)}\n`))}async function hd(e,n=v().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)}}function Q(e){return`'${e.replaceAll(`'`,`'\\''`)}'`}async function gd(e,t){try{await e([`shell`,_d(t.profilerPid)],{timeoutMs:Z})}catch(e){throw X(`stop`,t.kind,t.packageName,e)}}function _d(e){return[`pid=${Q(e)}`,`kill -INT "$pid" 2>/dev/null || true`,`for i in 1 2 3 4 5 6 7 8 9 10; do kill -0 "$pid" 2>/dev/null || exit 0; sleep 0.2; done`,`kill -TERM "$pid" 2>/dev/null || true`,`for i in 1 2 3 4 5 6 7 8 9 10; do kill -0 "$pid" 2>/dev/null || exit 0; sleep 0.2; done`,`echo "profiler process did not stop after SIGTERM" >&2`,`exit 1`].join(`; `)}async function vd(e,n,r){await(r??v().files).ensureDirectory(C.dirname(n.outPath));try{await e([`pull`,n.remotePath,n.outPath],{timeoutMs:Z})}catch(e){throw new t(`COMMAND_FAILED`,`Failed to pull Android ${n.kind} artifact for ${n.packageName}`,{package:n.packageName,tool:n.kind,remotePath:n.remotePath,outPath:n.outPath,hint:`Check that the profiling command ran long enough to create an artifact, then retry stop with the same session.`},e)}}async function yd(e,n){let r;for(let t=0;t<12;t+=1){let t=await bd(e,n.remotePath);if(t!==void 0&&t>0&&t===r)return;r=t,await g(250)}throw new t(`COMMAND_FAILED`,`Android ${n.kind} artifact is not ready to pull`,{package:n.packageName,tool:n.kind,remotePath:n.remotePath,hint:`The profiler stopped, but the remote artifact was missing, empty, or still changing. Retry stop with the same session or inspect the device-side artifact.`})}async function bd(e,t){let n=Q(t),r=await e([`shell`,`if [ -f ${n} ]; then stat -c %s ${n} 2>/dev/null || wc -c < ${n}; fi`],{allowFailure:!0,timeoutMs:cd});if(r.exitCode!==0)return;let i=Number(r.stdout.trim().split(/\s+/)[0]);return Number.isFinite(i)?i:void 0}async function xd(e,n){try{let t=await e([`shell`,`pidof`,n],{allowFailure:!0,timeoutMs:cd}),r=Cd(t.stdout);if(t.exitCode===0&&r)return r}catch{}throw new t(`COMMAND_FAILED`,`No active Android app process found for ${n}`,{package:n,hint:`Run open <app> for this session again, wait for the app UI to appear, then retry perf.`})}async function Sd(e,n,r){let i=await e([`shell`,`command -v ${n} || which ${n}`],{allowFailure:!0,timeoutMs:cd});if(!(i.exitCode===0&&i.stdout.trim()))throw new t(`UNSUPPORTED_OPERATION`,`Android device does not expose ${n}`,{package:r,tool:n,hint:$u(n)})}function Cd(e){return e.trim().split(/\s+/).find(e=>/^\d+$/.test(e))}async function wd(e,t,n,r={}){let i=b(e,r.adb),a=await xd(i,t);await Sd(i,`perfetto`,t);let o=fd(t,`app.perfetto-trace`,`/data/misc/perfetto-traces`),s;try{await Xu(e,t,{adb:i}),s=await Ed(i,o,t)}catch(e){throw await pd(i,o),e}return{type:`trace`,kind:`perfetto`,packageName:t,appPid:a,profilerPid:s,remotePath:o,outPath:n,startedAt:Date.now(),state:`running`,action:`start`,platform:`android`,method:sd,message:`Started Android Perfetto trace for ${t}`}}async function Td(e,t,n,r={}){return await ud(e,{...t,outPath:n},r)}async function Ed(e,n,r){try{let i=Cd((await e([`shell`,`perfetto`,`--background-wait`,`-o`,n,`-t`,`3600s`,`sched`,`freq`,`idle`,`am`,`wm`,`gfx`,`view`,`binder_driver`,`hal`,`dalvik`],{timeoutMs:Z})).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 X(`start`,`perfetto`,r,e)}}function Dd(e){let t=[];for(let n of s(e)){let e=n.match(/^([0-9]+(?:\.[0-9]+)?)%\s+(.+)$/);if(!e)continue;let r=Number(e[1]),i=e[2]?.trim();if(!Number.isFinite(r)||!i)continue;let a=i.split(/\s{2,}/).filter(Boolean);if(t.push({percentage:Tt(r),command:a[0],dso:a[1],symbol:a.slice(2).join(` `)||void 0}),t.length>=50)break}return t}async function Od(e,t,n,r={}){let i=b(e,r.adb),a=await xd(i,t);await Sd(i,`simpleperf`,t);let o=fd(t,`cpu.perf.data`),s;try{s=await jd(i,a,o,t)}catch(e){throw await pd(i,o),e}return{type:`cpu-profile`,kind:`simpleperf`,packageName:t,appPid:a,profilerPid:s,remotePath:o,outPath:n,startedAt:Date.now(),state:`running`,action:`start`,platform:`android`,method:od,message:`Started Android Simpleperf CPU profile for ${t}`}}async function kd(e,t,n,r={}){return await ud(e,{...t,outPath:n},r)}async function Ad(e,t,n,r={}){let i=b(e,r.adb);await Sd(i,`simpleperf`,t.packageName);let a=await Pd(i,t),o=new Date().toISOString(),s=Dd(a.stdout),c=s.slice(0,10).map(e=>({symbol:e.symbol??`<unknown>`,binary:e.dso,selfSamplePercent:e.percentage}));await md(n,{kind:`simpleperf-report`,generatedAt:o,packageName:t.packageName,appPid:t.appPid,sourceProfilePath:t.outPath,sourceRemotePath:t.remotePath,entryCount:s.length,summary:{topFunctions:c},entries:s},r.files);let l=await hd(n,r.files);return{action:`report`,platform:`android`,type:`cpu-profile-report`,kind:`simpleperf`,packageName:t.packageName,appPid:t.appPid,sourceProfilePath:t.outPath,outPath:n,sizeBytes:l,generatedAt:o,entryCount:s.length,summary:{topFunctions:c},method:od,message:`Wrote Android Simpleperf report for ${t.packageName}`}}async function jd(e,n,r,i){try{let a=Cd((await e([`shell`,Md(n,r)],{timeoutMs:Z})).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 X(`start`,`simpleperf`,i,e)}}function Md(e,t){return Nd([`simpleperf`,`record`,`-e`,`cpu-clock:u`,`-p`,e,`-o`,t,`--duration`,`3600`],`simpleperf`)}function Nd(e,t){let n=e.map(Q).join(` `);return[`err=${Q(`${ld}/agent-device-${t}-${Date.now()}.err`)}`,`(${n}) >/dev/null 2>"$err" & pid=$!`,`sleep 1`,`if kill -0 "$pid" 2>/dev/null; then rm -f "$err"; echo "$pid"; exit 0; fi`,`cat "$err" >&2`,`rm -f "$err"`,`exit 1`].join(`; `)}async function Pd(e,t){try{return await e([`shell`,`simpleperf`,`report`,`-i`,t.remotePath,`--stdio`,`--sort`,`comm,dso,symbol`],{timeoutMs:Z})}catch(e){throw X(`report`,`simpleperf`,t.packageName,e)}}const Fd=15e3,Id=12e4;async function Ld(e,t,n={}){let r=b(e,n.adb);try{return Vd((await r([`shell`,`dumpsys`,`meminfo`,t],{timeoutMs:Fd})).stdout,t,new Date().toISOString())}catch(e){throw Yd(`memory`,t,e)}}async function Rd(e,n,r,i={}){let a=b(e,i.adb),o=i.files??v().files,s=await Hd(a,n),c=Ud(n);await o.ensureDirectory(C.dirname(r));let l=await zd(o,r);try{ye(await a([`shell`,`am`,`dumpheap`,n,c],{allowFailure:!0,timeoutMs:Id}),`Failed to capture Android heap dump for ${n}`,e=>({kind:`android-hprof`,package:n,pid:s,remotePath:c,hint:Wd(e.stdout,e.stderr)}));let e=await a([`pull`,c,r],{allowFailure:!0,timeoutMs:Id});if(e.exitCode!==0)throw await Bd(o,r,l),y(`Failed to pull Android heap dump for ${n}`,e,{kind:`android-hprof`,package:n,pid:s,remotePath:c,path:r,hint:`Verify the daemon can write the requested --out path and retry. The heap dump stays on-device only until cleanup runs.`});let i=await o.stat(r).catch(()=>null);if(!i?.isFile||i.size<=0)throw await Bd(o,r,l),new t(`COMMAND_FAILED`,`Android heap dump artifact is missing or empty`,{kind:`android-hprof`,package:n,pid:s,path:r,remotePath:c,hint:`Retry with a writable --out path. If the file is still empty, inspect adb pull output with --debug.`});return{available:!0,kind:`android-hprof`,path:r,sizeBytes:i.size,measuredAt:new Date().toISOString(),method:`adb-shell-am-dumpheap`,packageName:n,pid:s,remotePath:c}}finally{await a([`shell`,`rm`,`-f`,c],{allowFailure:!0,timeoutMs:Fd}).catch(()=>{})}}async function zd(e,t){return await e.stat(t).then(e=>e.isFile).catch(()=>!1)}async function Bd(e,t,n){n||await e.remove(t,{force:!0}).catch(()=>{})}function Vd(e,n,r){if(/no process found for:/i.test(e))throw new t(`COMMAND_FAILED`,`Android meminfo did not find a running process for ${n}`,{metric:`memory`,package:n,hint:`Run open <app> for this session again to ensure the Android app is active, then retry perf.`});let i=Xd(e,`TOTAL PSS`)??Zd(e);if(i===void 0)throw new t(`COMMAND_FAILED`,`Failed to parse Android meminfo output for ${n}`,{metric:`memory`,package:n,hint:`Retry perf after reopening the app session. If the problem persists, capture adb shell dumpsys meminfo output for debugging.`});return{totalPssKb:i,totalRssKb:Xd(e,`TOTAL RSS`),measuredAt:r,method:`adb-shell-dumpsys-meminfo`,topConsumers:Gd(e)}}async function Hd(e,n){let r=await e([`shell`,`pidof`,n],{allowFailure:!0,timeoutMs:Fd}),i=r.stdout.trim().split(/\s+/).map(Number).find(e=>Number.isInteger(e)&&e>0);if(r.exitCode===0&&i!==void 0)return i;throw new t(`COMMAND_FAILED`,`No running Android process found for ${n}`,{kind:`android-hprof`,package:n,stdout:r.stdout,stderr:r.stderr,hint:`Run open <app> for this session again to ensure the Android app is active, then retry perf memory snapshot.`})}function Ud(e){return`/data/local/tmp/agent-device-${e.replaceAll(/[^a-zA-Z0-9._-]/g,`_`)}-${Date.now()}.hprof`}function Wd(e,t){let n=`${e}\n${t}`.toLowerCase();return n.includes(`profileable`)||n.includes(`debuggable`)||n.includes(`not allowed`)?`Android heap dumps require a debuggable/profileable app process on many devices. Use a debug/profileable build, reopen the app, then retry.`:n.includes(`permission`)||n.includes(`denied`)?`The device denied heap dump access. Use a debug/profileable build or a device image that permits app heap dumping.`:`Reopen the app to refresh the process, then retry perf memory snapshot. If it still fails, run with --debug and inspect adb am dumpheap output.`}function Gd(e){let t=e.split(`
|
|
14
|
+
`).flatMap(e=>Kd(e)??[]).sort((e,t)=>t.pssKb-e.pssKb).slice(0,5);return t.length>0?t:void 0}function Kd(e){let t=e.trim();if(qd(t))return;let n=t.match(/^(.+?)\s+([0-9][0-9,]*(?:\(\d+\))?)(?:\s|$)/);if(n)return Jd(n[1],n[2])}function qd(e){if(!e||e.startsWith(`**`)||e.startsWith(`-`)||e.includes(`:`))return!0;let t=/^\S.+\s+\d/.test(e);return/^(pss|total|native|dalvik|unknown|app summary\b)/i.test(e)&&!t}function Jd(e,t){let n=e?.trim(),r=t?Y(t):null;if(!(!n||n===`TOTAL`||r===null||r<=0)&&!/^(pss|private|shared|heap|size|alloc|free)$/i.test(n))return{name:n,pssKb:r}}function Yd(e,n,r){return r instanceof t?new t(r.code,r.message,{...r.details??{},metric:e,package:n},r):new t(`COMMAND_FAILED`,`Failed to sample Android ${e} for ${n}`,{metric:e,package:n},r)}function Xd(e,t){let n=t.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`),r=e.match(RegExp(`${n}:\\s*([0-9][0-9,]*)`,`i`));if(!r)return;let i=r[1];return i===void 0?void 0:Y(i)??void 0}function Zd(e){for(let t of e.split(`
|
|
15
|
+
`)){let e=t.trim();if(!/^TOTAL\b(?!\s+PSS:)/.test(e))continue;let n=e.split(/\s+/).slice(1).find(e=>Y(e)!==null);return n?Y(n)??void 0:void 0}}async function Qd(e,t,n){let r=await S(e,[`shell`,`dumpsys`,`package`,t],{allowFailure:!0});if(r.exitCode===0)return rf(r.stdout,n)}async function $d(e){let t=await S(e,[`shell`,`am`,`get-current-user`],{allowFailure:!0});if(t.exitCode!==0)return;let n=Number.parseInt(t.stdout.trim(),10);return Number.isInteger(n)&&n>=0?n:void 0}const ef=/^\s*User (\d+):/,tf=/^\s*runtime permissions:\s*$/,nf=/^\s*([\w.]+): granted=(true|false)\b/;function rf(e,t){let n=af(af(af(e.split(`
|
|
16
|
+
`).filter(e=>e.trim().length>0).map(e=>({text:e,indent:e.length-e.trimStart().length})),e=>e.indent===0&&e.text.trim()===`Packages:`),e=>ef.exec(e.text)?.[1]===String(t)),e=>tf.test(e.text));if(!n)return;let r=new Map;for(let{text:e}of n){let t=nf.exec(e);t&&r.set(t[1],t[2]===`true`?`granted`:`not_granted`)}return r}function af(e,t){if(!e)return;let n=e.findIndex(e=>t(e));if(n<0)return;let r=e.slice(n+1),i=r.findIndex(t=>t.indent<=e[n].indent);return i<0?r:r.slice(0,i)}function of(e,t,n){if(n!==`not_granted`)return`${n===`granted`?`${t} was granted before this revoke, and Android kills an app when a granted permission is revoked: if ${e} was running it is no longer.`:`Whether ${t} was granted before this revoke could not be read (adb did not report the acting user's runtime permission state), and Android kills an app when a granted permission is revoked: ${e} may no longer be running.`} Relaunch it with open ${e} --relaunch before the next interaction.`}async function sf(e){let n=await $d(e);if(n!==void 0)return n;throw new t(`COMMAND_FAILED`,`Could not determine which Android user the session runs as, so no permission was changed.`,{deviceId:e.id,hint:`Check adb -s ${e.id} shell am get-current-user — if the device is still booting, retry once it reports a user. agent-device refuses to change permissions it cannot scope, because pm would silently apply them to user 0.`})}async function cf(e,t,n,r){let i=ge(n),a=df(r?.permissionTarget,r?.permissionMode),o=await sf(e),s=[`--user`,String(o)];if(i===`grant`){await lf(e,t,a,s);return}let c=await Qd(e,t,o),l=await uf(e,t,i,a,s),u=c?.get(l)??`unknown`,d=of(t,l,u);return{permission:l,priorGrantState:u,...d?{warnings:[d]}:{}}}async function lf(e,t,n,r){n.kind===`notifications`?await pf(e,t,`grant`,n,r):n.type===`photos`?await ff(e,t,`grant`,r):await S(e,[`shell`,`pm`,`grant`,...r,t,n.value])}async function uf(e,t,n,r,i){if(r.kind===`notifications`)return await pf(e,t,n,r,i),r.permission;let a;return r.type===`photos`?a=await ff(e,t,`revoke`,i):(a=r.value,await S(e,[`shell`,`pm`,`revoke`,...i,t,a])),n===`reset`&&await mf(e,t,a,i),a}function df(e,n){let r=me(e);if(n?.trim())throw new t(`INVALID_ARGS`,`Permission mode is only supported for photos. Received: ${n}.`);if(r===`camera`)return{kind:`pm`,value:`android.permission.CAMERA`,type:`camera`};if(r===`microphone`)return{kind:`pm`,value:`android.permission.RECORD_AUDIO`,type:`microphone`};if(r===`photos`)return{kind:`pm`,value:`android.permission.READ_MEDIA_IMAGES`,type:`photos`};if(r===`contacts`)return{kind:`pm`,value:`android.permission.READ_CONTACTS`,type:`contacts`};if(r===`notifications`)return{kind:`notifications`,appOps:`POST_NOTIFICATION`,permission:`android.permission.POST_NOTIFICATIONS`};throw new t(`INVALID_ARGS`,`Unsupported permission target on Android: ${e}. Use camera|microphone|photos|contacts|notifications.`)}async function ff(e,n,r,i){let a=await hf(e),o=a!==null&&a>=33?[`android.permission.READ_MEDIA_IMAGES`,`android.permission.READ_EXTERNAL_STORAGE`]:[`android.permission.READ_EXTERNAL_STORAGE`,`android.permission.READ_MEDIA_IMAGES`],s=[];for(let t of o){let a=await S(e,[`shell`,`pm`,r,...i,n,t],{allowFailure:!0});if(a.exitCode===0)return t;s.push({permission:t,stderr:a.stderr,exitCode:a.exitCode})}throw new t(`COMMAND_FAILED`,`Failed to ${r} Android photos permission`,{appPackage:n,sdkInt:a,attempts:s})}async function pf(e,t,n,r,i){let a=n===`grant`?`allow`:n===`deny`?`deny`:`default`;n===`grant`?await S(e,[`shell`,`pm`,`grant`,...i,t,r.permission],{allowFailure:!0}):(await S(e,[`shell`,`pm`,`revoke`,...i,t,r.permission],{allowFailure:!0}),n===`reset`&&await mf(e,t,r.permission,i)),await S(e,[`shell`,`appops`,`set`,...i,t,r.appOps,a])}async function mf(e,t,n,r){for(let i of[`user-set`,`user-fixed`])await S(e,[`shell`,`pm`,`clear-permission-flags`,...r,t,n,i],{allowFailure:!0})}async function hf(e){let t=await S(e,[`shell`,`getprop`,`ro.build.version.sdk`],{allowFailure:!0});if(t.exitCode!==0)return null;let n=Number.parseInt(t.stdout.trim(),10);return!Number.isFinite(n)||n<=0?null:n}function gf(e){let n=e.trim().toLowerCase();if(n===`light`)return`light`;if(n===`dark`)return`dark`;if(n===`toggle`)return`toggle`;throw new t(`INVALID_ARGS`,`Invalid appearance state: ${e}. Use light|dark|toggle.`)}function _f(e){let n=e.toLowerCase();if(n===`on`||n===`true`||n===`1`)return!0;if(n===`off`||n===`false`||n===`0`)return!1;throw new t(`INVALID_ARGS`,`Invalid setting state: ${e}`)}function vf(e){return e.map(e=>({args:e.args.join(` `),exitCode:e.exitCode,stderr:e.stderr.slice(0,400)}))}const yf=[`shell`,`cmd`,`connectivity`,`airplane-mode`];async function bf(e,n){let r=n?`enabled`:`disabled`;await xf(e),await S(e,[...yf,n?`enable`:`disable`]);let i=await Sf(e);if(i!==r)throw new t(`COMMAND_FAILED`,`Android airplane mode reads ${i} after requesting ${r}.`,{deviceId:e.id,requested:r,airplaneMode:i});return{airplaneMode:i}}async function xf(e){let{state:n,result:r}=await Cf(e);if(!n)throw r.exitCode!==0&&Ue(r.stdout,r.stderr)?new t(`UNSUPPORTED_OPERATION`,`The connectivity service on this Android build has no airplane-mode command, so nothing was changed.`,{deviceId:e.id,hint:`settings airplane needs cmd connectivity airplane-mode, which requires Android 11 (API 30) or newer. Use a newer device or emulator image.`,stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode}):y(`Failed to read Android airplane mode`,r,{deviceId:e.id})}async function Sf(e){let{state:t,result:n}=await Cf(e);if(t)return t;throw y(`Failed to read Android airplane mode after changing it`,n,{deviceId:e.id})}async function Cf(e){let t=await S(e,[...yf],{allowFailure:!0});return{state:t.exitCode===0?wf(t.stdout):void 0,result:t}}function wf(e){let t=e.trim().toLowerCase();if(t===`enabled`)return`enabled`;if(t===`disabled`)return`disabled`}const Tf=[`window_animation_scale`,`transition_animation_scale`,`animator_duration_scale`];async function Ef(e,n,r,i,a){switch(n.toLowerCase()){case`wifi`:{let t=_f(r);await S(e,[`shell`,`svc`,`wifi`,t?`enable`:`disable`]);return}case`airplane`:return await bf(e,_f(r));case`location`:{if(r.toLowerCase()===`set`){if(e.kind!==`emulator`)throw new t(`UNSUPPORTED_OPERATION`,`Android precise location coordinates are supported only on emulators.`,{deviceId:e.id,hint:`Use an Android emulator for adb emu geo fix, or configure location through device/provider tooling.`});let{latitude:n,longitude:r}=he(a);return await S(e,[`emu`,`geo`,`fix`,String(r),String(n)]),{latitude:n,longitude:r}}let n=_f(r)?`3`:`0`;await S(e,[`shell`,`settings`,`put`,`secure`,`location_mode`,n]);return}case`animations`:{let t=_f(r)?`1`:`0`;for(let n of Tf)await S(e,[`shell`,`settings`,`put`,`global`,n,t]);return{scale:t,keys:[...Tf]}}case`appearance`:{let t=await jf(e,r);await S(e,[`shell`,`cmd`,`uimode`,`night`,t===`dark`?`yes`:`no`]);return}case`clear-app-state`:{if(r.toLowerCase()!==`clear`)throw new t(`INVALID_ARGS`,`settings clear-app-state only supports clear.`);if(!i)throw new t(`INVALID_ARGS`,`settings clear-app-state requires an app id or an active app session.`);let n=await lt(e,i);if(n.type===`intent`)throw new t(`INVALID_ARGS`,`settings clear-app-state requires a package name, not an intent.`);await S(e,[`shell`,`am`,`force-stop`,n.value],{allowFailure:!0});let a=await S(e,[`shell`,`pm`,`clear`,n.value],{allowFailure:!0});if(a.exitCode!==0||!/\bSuccess\b/i.test(a.stdout))throw new t(`COMMAND_FAILED`,`Failed to clear Android app data for ${n.value}`,{package:n.value,stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});return{package:n.value,cleared:!0}}case`fingerprint`:await Of(e,Df(r));return;case`permission`:if(!i)throw new t(`INVALID_ARGS`,`permission setting requires an active app in session`);return await cf(e,i,r,a);default:throw new t(`INVALID_ARGS`,`Unsupported setting: ${n}`)}}function Df(e){let n=e.trim().toLowerCase();if(n===`match`)return`match`;if(n===`nonmatch`)return`nonmatch`;throw new t(`INVALID_ARGS`,`Invalid fingerprint state: ${e}. Use match|nonmatch.`)}async function Of(e,n){let r=kf(e,n),i=[];for(let t of r){let n=await S(e,t,{allowFailure:!0});if(n.exitCode===0)return;i.push({args:t,stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode})}let a=vf(i);throw i.length>0&&i.every(e=>Af(e.stdout,e.stderr))?new t(`UNSUPPORTED_OPERATION`,`Android fingerprint simulation is not supported on this target/runtime.`,{deviceId:e.id,action:n,hint:`Use an Android emulator with biometric support, or a device/runtime that exposes cmd fingerprint.`,attempts:a}):new t(`COMMAND_FAILED`,`Failed to simulate Android fingerprint.`,{deviceId:e.id,action:n,attempts:a})}function kf(e,t){let n=t===`match`?`1`:`9999`,r=[[`shell`,`cmd`,`fingerprint`,`touch`,n],[`shell`,`cmd`,`fingerprint`,`finger`,n]];return e.kind===`emulator`&&r.push([`emu`,`finger`,`touch`,n]),r}function Af(e,t){let n=`${e}\n${t}`.toLowerCase();return n.includes(`unknown command`)||n.includes(`can't find service: fingerprint`)||n.includes(`service fingerprint was not found`)||n.includes(`fingerprint cmd unavailable`)||n.includes(`emu command is not supported`)||n.includes(`emulator console is not running`)||n.includes(`fingerprint`)&&n.includes(`not found`)}async function jf(e,n){let r=gf(n);if(r!==`toggle`)return r;let i=await S(e,[`shell`,`cmd`,`uimode`,`night`],{allowFailure:!0});if(i.exitCode!==0)throw y(`Failed to read current Android appearance`,i);let a=Mf(i.stdout,i.stderr);if(!a)throw new t(`COMMAND_FAILED`,`Unable to determine current Android appearance for toggle`,{stdout:i.stdout,stderr:i.stderr});return a===`auto`?`dark`:a===`dark`?`light`:`dark`}function Mf(e,t){let n=/night mode:\s*(yes|no|auto)\b/i.exec(`${e}\n${t}`);if(!n)return null;let r=n[1]?.toLowerCase();return r===`yes`?`dark`:r===`no`?`light`:r===`auto`?`auto`:null}const Nf=Buffer.from([137,80,78,71,13,10,26,10]);async function Pf(e,t,n={}){if(n.stabilize===!1){await Lf(e,t);return}await Ff(e);try{await g(1e3),await Lf(e,t)}finally{await If(e).catch(()=>{})}}async function Ff(e){let t=t=>S(e,[`shell`,t],{allowFailure:!0});await t(`settings put global sysui_demo_allowed 1`);let n=e=>t(`am broadcast -a com.android.systemui.demo -e command ${e}`);await n(`clock -e hhmm 0941`),await n(`notifications -e visible false`)}async function If(e){await S(e,[`shell`,`am broadcast -a com.android.systemui.demo -e command exit`],{allowFailure:!0})}async function Lf(e,n){let r=await S(e,[`exec-out`,`screencap`,`-p`],{binaryStdout:!0});if(!r.stdoutBuffer)throw new t(`COMMAND_FAILED`,`Failed to capture screenshot`);let i=r.stdoutBuffer.indexOf(Nf);if(i<0)throw new t(`COMMAND_FAILED`,`Screenshot data does not contain a valid PNG header`);let a=Rf(r.stdoutBuffer,i);if(!a)throw new t(`COMMAND_FAILED`,`Screenshot data does not contain a complete PNG payload`);await v().files.writeBytes(n,r.stdoutBuffer.subarray(i,a))}function Rf(e,t){let n=t+Nf.length;for(;n+8<=e.length;){let t=e.readUInt32BE(n),r=n+4,i=e.toString(`ascii`,r,r+4),a=n+12+t;if(a>e.length)return null;if(i===`IEND`)return a;n=a}return null}async function zf(e,t,n=0){let r=Be(e);if(r){await r({action:`type`,text:t,delayMs:n}),$(`type`,`provider-native`,t);return}let i=await Wf(e,`type`,t);if(i.backend===`test-ime`){await Gf(e,i.packageName,t,n);return}if(n>0&&Array.from(t).length>1){await qf(e,{action:`type`,text:t,chunkSize:1,delayMs:n});return}await qf(e,{action:`type`,text:t,chunkSize:8,delayMs:0})}async function Bf(e,t,n,r,i=0,a={}){let o=await wl(e,t,n,a),s=Be(e);if(s)return await s({action:`fill`,target:{x:t,y:n},text:r,delayMs:i}),$(`fill`,`provider-native`,r),J(r,o,await xl(e,t,n,r,a));let c=null;for(let s of Vf(i)){await R(e,t,n);let i=await Wf(e,`fill`,r);if(i.backend===`test-ime`)return J(r,o,await Kf(e,i.packageName,t,n,r,o,a));let l=await Hf(e,{x:t,y:n,text:r,beforeTarget:o,attempt:s},a);if(c=l,l.ok)return;if(l.reason===`ime_capture`)return J(r,o,l);let u=Tl(r,o,l);if(u)return u}return J(r,o,c)}function Vf(e){return[{clearPadding:12,minClear:8,maxClear:48,chunkSize:e>0?1:8,inputDelayMs:e},{clearPadding:24,minClear:16,maxClear:96,chunkSize:e>0?1:4,inputDelayMs:e>0?e:15}]}async function Hf(e,t,n){let{x:r,y:i,text:a,beforeTarget:o,attempt:s}=t;return await Yf(e,Uf(a,o,s)),await qf(e,{action:`fill`,text:a,chunkSize:s.chunkSize,delayMs:s.inputDelayMs}),xl(e,r,i,a,n)}function Uf(e,t,n){let r=Array.from(e).length;return ip(r>0?r+n.clearPadding:t?.text?Array.from(t.text).length+n.clearPadding:n.maxClear,n.minClear,n.maxClear)}async function Wf(e,t,n){if(yo(e))return{backend:`test-ime`,packageName:(await Qa(x(e))).manifest.packageName};let r=await Xf(e,t),i=r?.inputMethodPackage;return io(i)?{backend:`test-ime`,packageName:i}:(Qf(n),Zf(r,t),{backend:`adb-shell`})}async function Gf(e,t,n,r){let i=b(e),a=n.split(`
|
|
17
|
+
`);for(let[n,o]of a.entries()){let s=r>0?rp(o,1):[o];for(let[e,o]of s.entries())o&&await ao(i,t,o),r>0&&(e+1<s.length||n+1<a.length)&&await g(r);n+1<a.length&&await S(e,[`shell`,`input`,`keyevent`,`ENTER`])}$(`type`,`test-ime`,n)}async function Kf(e,t,n,r,i,a,o){let s=b(e),c=null;for(let l=0;l<2;l+=1){l>0&&await R(e,n,r),await oo(s,t),i&&await ao(s,t,i);let u=await xl(e,n,r,i,o);if(c=u,u.ok||Tl(i,a,u))break}return $(`fill`,`test-ime`,i),c}async function qf(e,t){let n=t.text.split(`
|
|
18
|
+
`);for(let[r,i]of n.entries()){let a=rp(i,t.chunkSize);for(let[i,o]of a.entries())await Jf(e,o),t.delayMs>0&&(i+1<a.length||r+1<n.length)&&await g(t.delayMs);r+1<n.length&&await S(e,[`shell`,`input`,`keyevent`,`ENTER`])}$(t.action,`adb-shell`,t.text)}async function Jf(e,t){if(t)try{await S(e,[`shell`,`input`,`text`,Te(ep(t))])}catch(e){throw tp(e)?np(t,e):e}}async function Yf(e,t){let n=Math.max(0,t);await S(e,[`shell`,`input`,`keyevent`,`KEYCODE_MOVE_END`],{allowFailure:!0});for(let t=0;t<n;t+=24){let r=Math.min(24,n-t);await S(e,[`shell`,`input`,`keyevent`,...Array(r).fill(`KEYCODE_DEL`)],{allowFailure:!0})}}async function Xf(e,t){try{return await ja(e)}catch(e){return h({level:`warn`,phase:`android_input_ownership_probe_failed`,data:{action:t,error:e instanceof Error?e.message:String(e)}}),null}}function Zf(e,n){if(!(!e||e.inputOwner!==`ime`))throw new t(`COMMAND_FAILED`,`KEYBOARD_OVERLAY_BLOCKING: Android text input is blocked because the focused input belongs to the active keyboard/IME.`,{failureReason:`ime_capture`,action:n,inputOwner:e.inputOwner,inputType:e.inputType,type:e.type,inputMethodPackage:e.inputMethodPackage,focusedPackage:e.focusedPackage,focusedResourceId:e.focusedResourceId,nextAction:`Focused input appears to be owned by the keyboard/IME; dismiss or change the IME before retrying text entry.`})}function Qf(e){if(!$f(e))throw np(e)}function $f(e){for(let t of e){let e=t.codePointAt(0);if(e!==void 0&&t!==`
|
|
19
|
+
`&&(e<32||e>126))return!1}return!0}function ep(e){return e.replaceAll(` `,`%s`)}function tp(e){if(!(e instanceof t)||e.code!==`COMMAND_FAILED`)return!1;let n=e.details?.stderr,r=(typeof n==`string`?n:``).toLowerCase();return!!(r.includes(`exception occurred while executing 'text'`)||r.includes(`nullpointerexception`)&&r.includes(`inputshellcommand.sendtext`))}function np(e,n){return new t(`COMMAND_FAILED`,"Android text input requires provider-native text injection or the bundled test IME helper for non-ASCII/control characters; the adb-shell fallback supports ASCII text only. On emulators the test IME activates automatically; on real devices pass `open --test-ime` to enable it (see `agent-device doctor` for the current IME state).",{backend:`adb-shell`,textLength:Array.from(e).length,textPreview:e.slice(0,32)},n instanceof Error?n:void 0)}function rp(e,t){let n=Math.max(1,Math.floor(t)),r=[],i=Array.from(e);for(let e=0;e<i.length;e+=n)r.push(i.slice(e,e+n).join(``));return r.length>0?r:[``]}function $(e,t,n){h({phase:`android_text_injection`,data:{action:e,backend:t,textLength:Array.from(n).length}})}function ip(e,t,n){return Math.max(t,Math.min(n,e))}var ap=e({ANDROID_FOCUSED_WINDOW_MARKER:()=>ht,ANDROID_FOCUS_MARKERS:()=>pt,ANDROID_IME_HELPER_SERVICE_COMPONENT:()=>`com.callstack.agentdevice.imehelper/.TestInputMethodService`,ANDROID_SNAPSHOT_PRESENTATION_DEFAULT_DEADLINE_MS:()=>250,ANDROID_TEST_IME_SETTINGS_KEYS:()=>fo,ANDROID_TOUCH_PLAN_PROTOCOL:()=>xi,AndroidSnapshotPresentationFailure:()=>q,activateAndroidTestIme:()=>Jl,androidAdbForwardsDeviceExitStatus:()=>kt,androidAdbResultError:()=>y,androidAppsDiscoveryHint:()=>ut,androidCaptureFailureReasonDetail:()=>A,androidCaptureFailureReasonFromExitCode:()=>sr,androidCaptureFailureReasonFromHelperResult:()=>or,androidDeviceChecks:()=>Ao,androidFillFailureDetails:()=>kl,androidFillFailureMessage:()=>Ol,androidRevokedPermissionWarning:()=>of,androidSnapshotPublicationInput:()=>Kc,androidToolchainCheck:()=>ko,androidUiNodes:()=>ec,annotateAndroidNativePerfError:()=>X,appSwitcherAndroid:()=>Qi,attachAdbFailureHint:()=>Me,backAndroid:()=>Wi,buildAndroidFillUnconfirmedVerification:()=>Tl,buildAndroidNativeToolUnavailableHint:()=>$u,buildAndroidSnapshotClickabilityEvidence:()=>mc,buildAndroidSnapshotHelperArgs:()=>Lr,buildAndroidSnapshotHelperCaptureOptions:()=>Fr,buildUiHierarchySnapshot:()=>Ps,captureAndroidHeapSnapshot:()=>Rd,captureAndroidLogcatWithAdb:()=>sp,captureAndroidSnapshotWithHelper:()=>Pr,captureAndroidSnapshotWithHelperSession:()=>gi,classifyAdbFailure:()=>Ne,classifyAndroidAlertIdentifier:()=>Vt,classifyAndroidAppTarget:()=>at,classifyAndroidHelperContent:()=>gc,cleanupAndroidNativePerfSession:()=>dd,clearAndroidImeHelperText:()=>oo,clearAndroidTestImeRecoveryMarker:()=>$l,closeAndroidApp:()=>et,completeAndroidFillVerification:()=>J,createAndroidPortReverseManager:()=>Fe,createAndroidSnapshotCapture:()=>Gc,createAndroidSnapshotPresentationBudget:()=>ks,createAndroidSnapshotPresentationNode:()=>Ts,createAndroidWindowDumpReader:()=>yt,createDeviceAdbExecutor:()=>ze,createLocalAndroidAdbProvider:()=>Ie,dismissAndroidKeyboard:()=>Ma,dismissAndroidKeyboardWithAdb:()=>Na,ensureAndroidEmulatorBooted:()=>rt,ensureAndroidImeHelper:()=>no,ensureAndroidSdkPathConfigured:()=>$e,ensureAndroidSnapshotHelper:()=>$n,executeAndroidTouchHelperPlan:()=>Ti,executeAndroidTouchPlan:()=>zi,fillAndroid:()=>Bf,findAndroidAlertCandidate:()=>Ht,focusAndroid:()=>R,forceStopAndroidAppWithAdb:()=>ha,forgetAndroidSnapshotHelperInstall:()=>Jn,formatAndroidInstalledPackageRequiredMessage:()=>ct,getAndroidAppState:()=>_t,getAndroidBlockingDialogObservation:()=>vt,getAndroidImeHelperDeviceKey:()=>V,getAndroidKeyboardState:()=>ja,getAndroidKeyboardStatusWithAdb:()=>z,getAndroidScreenSize:()=>ra,getAndroidSnapshotHelperSessionDeviceKey:()=>M,handleAndroidAlert:()=>ia,homeAndroid:()=>Gi,inferAndroidAppName:()=>st,inferAndroidPackageAfterOpen:()=>lp,inspectInstalledAndroidHelper:()=>Sn,installAndroidAdbPackage:()=>Ve,installAndroidInstallablePath:()=>Ea,isAmStartError:()=>nt,isAndroidImeHelperPackage:()=>io,isAndroidPermissionPackage:()=>Nt,isAndroidShellCommandUnsupported:()=>Ue,isAndroidSnapshotHelperRetirementUnconfirmedError:()=>Tr,isAndroidSnapshotPresentationFailure:()=>Ds,isAndroidTestImeActive:()=>yo,listAndroidAdbSerialsQuick:()=>Do,listAndroidAppsWithAdb:()=>op,longPressAndroid:()=>$i,lowerAndroidTouchPlan:()=>Li,makeEnsureAndroidHelperInstalled:()=>wn,normalizeAndroidTouchHelperGestureRequest:()=>Ai,openAndroidApp:()=>Qe,openAndroidAppWithAdb:()=>_a,openAndroidDevice:()=>Xe,parseAndroidHelperManifest:()=>D,parseAndroidLaunchComponent:()=>tt,parseAndroidLaunchablePackages:()=>ft,parseAndroidSnapshotHelperManifest:()=>D,parseAndroidSnapshotHelperOutput:()=>Kr,parseAndroidUserInstalledPackages:()=>dt,parseInstrumentationRecords:()=>fn,parseUiHierarchyTree:()=>fc,prepareAndroidInstallArtifact:()=>vu,pressAndroid:()=>Hi,pressAndroidEnter:()=>Ki,pressAndroidTvRemote:()=>Ui,pullAndroidAdbFile:()=>Re,pushAndroidNotification:()=>xu,readAndroidBlockingDialogFocus:()=>mt,readAndroidClipboardText:()=>Wa,readAndroidClipboardWithAdb:()=>Ga,readAndroidDefaultInputMethod:()=>H,readAndroidFillTargetBeforeMutation:()=>wl,readAndroidGestureViewport:()=>Bi,readAndroidHelperManifestInteger:()=>ln,readAndroidHelperManifestLiteral:()=>T,readAndroidSnapshotHelperInstallOptions:()=>Rn,readAndroidTestImeRecoveryMarkers:()=>eu,readAndroidTextAtPoint:()=>Sl,readAndroidTextAtPointInHierarchy:()=>Dl,readAndroidTouchHelperFinalRecord:()=>Ni,readAndroidTouchHelperViewportReading:()=>Ei,readInstrumentationResultBoolean:()=>vn,readInstrumentationResultNumber:()=>E,resetAndroidAdbShellProtocolProbes:()=>At,resetAndroidFramePerfStats:()=>Xu,resetAndroidImeHelperInstallCache:()=>ro,resetAndroidSnapshotHelperInstallCache:()=>Yn,resetAndroidSnapshotHelperRuntime:()=>Uc,resetAndroidSnapshotHelperSessions:()=>hi,resetAndroidTestImeActivationCacheForTests:()=>xo,resetAndroidWindowDumpFocusMemoForTests:()=>gt,resolveAndroidAdbExecutor:()=>b,resolveAndroidAdbProvider:()=>x,resolveAndroidApp:()=>lt,resolveAndroidArchivePackageName:()=>au,resolveAndroidHelperArtifact:()=>Cn,resolveAndroidImeHelperArtifact:()=>$a,resolveAndroidPackageForOpen:()=>cp,resolveAndroidSnapshotHelperCaptureOptions:()=>Ir,resolveAndroidTextInjector:()=>Be,resolveAndroidTouchProvider:()=>Pe,resolveScopedAndroidAdbBackgroundTransport:()=>Le,restoreAndroidTestIme:()=>Co,restoreOrphanedAndroidTestImeOnDaemonStartup:()=>Eo,retireAndroidSnapshotHelperAfterContentFailure:()=>Hc,runAndroidAdb:()=>S,runAndroidHostAdb:()=>je,runAndroidSnapshotHelperSessionTouchCommand:()=>vi,sampleAndroidFramePerf:()=>Yu,sampleAndroidMemoryPerf:()=>Ld,screenshotAndroid:()=>Pf,scrollAndroid:()=>ea,selectAndroidImeHelperArtifact:()=>Qa,sendAndroidImeHelperText:()=>ao,setAndroidOrientation:()=>qi,setAndroidPermission:()=>cf,setAndroidSetting:()=>Ef,setAndroidTestImeActiveForTests:()=>So,sleep:()=>g,snapshotAndroid:()=>Jc,startAndroidPerfettoTrace:()=>wd,startAndroidSimpleperfProfile:()=>Od,stopAndroidPerfettoTrace:()=>Td,stopAndroidSimpleperfProfile:()=>kd,stopAndroidSnapshotHelperSession:()=>L,stopAndroidSnapshotHelperSessionForDevice:()=>mi,typeAndroid:()=>zf,validateAndroidGestureViewport:()=>yn,validateAndroidRegularPresentation:()=>As,verifyAndroidFilledText:()=>xl,verifyAndroidFilledTextInHierarchy:()=>El,verifyAndroidHelperApkChecksum:()=>On,waitForAndroidBoot:()=>Ze,withAndroidAdbProvider:()=>He,withAndroidAppResolutionCacheInvalidated:()=>ot,withAndroidHostAdbTransport:()=>Ae,writeAndroidClipboardText:()=>Ka,writeAndroidClipboardWithAdb:()=>qa,writeAndroidSimpleperfReport:()=>Ad,writeAndroidTestImeRecoveryMarker:()=>Ql});async function op(...e){let{listAndroidAppsWithAdb:t}=await import(`./app-helpers.js`);return await t(...e)}async function sp(...e){let{captureAndroidLogcatWithAdb:t}=await import(`./logcat.js`);return await t(...e)}async function cp(...e){let{resolveAndroidPackageForOpen:t}=await import(`./open-target-resolution.js`);return await t(...e)}async function lp(...e){let{inferAndroidPackageAfterOpen:t}=await import(`./open-target-resolution.js`);return await t(...e)}export{qi as A,R as C,Ki as D,Hi as E,Bi as M,Ui as O,Wi as S,$i as T,qa as _,zf as a,ia as b,Jc as c,Na as d,ja as f,Ka as g,Ga as h,Bf as i,zi as j,ea as k,Kc as l,Wa as m,op as n,Pf as o,z as p,ap as r,Ef as s,sp as t,Ma as u,ha as v,Gi as w,Qi as x,_a as y};
|