agent-device 0.20.0 → 0.20.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.
Files changed (128) hide show
  1. package/README.md +2 -3
  2. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.0.apk → agent-device-android-ime-helper-0.20.2.apk} +0 -0
  3. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.2.apk.sha256 +1 -0
  4. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.0.manifest.json → agent-device-android-ime-helper-0.20.2.manifest.json} +4 -4
  5. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.0.apk → agent-device-android-snapshot-helper-0.20.2.apk} +0 -0
  6. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.2.apk.sha256 +1 -0
  7. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.0.manifest.json → agent-device-android-snapshot-helper-0.20.2.manifest.json} +6 -6
  8. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +2 -0
  9. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +30 -16
  10. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +1 -1
  11. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +0 -21
  12. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +8 -3
  13. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Orientation.swift +92 -0
  14. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +4 -2
  15. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +1 -1
  16. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +2 -1
  17. package/dist/src/agent-device-client.js +2 -2
  18. package/dist/src/android-input-method-overlays.js +1 -1
  19. package/dist/src/android.js +1 -1
  20. package/dist/src/app-lifecycle.js +5 -5
  21. package/dist/src/app-log-request-scope.js +1 -1
  22. package/dist/src/app-resolution.js +1 -1
  23. package/dist/src/apple-multitouch-support.js +1 -1
  24. package/dist/src/apps.js +5 -5
  25. package/dist/src/boot-diagnostics.js +2 -2
  26. package/dist/src/cli-config.js +1 -1
  27. package/dist/src/cli-help.js +81 -24
  28. package/dist/src/cli-runner.js +1 -1
  29. package/dist/src/cli.js +14 -14
  30. package/dist/src/click-button.d.ts +5 -0
  31. package/dist/src/client-metro.js +1 -0
  32. package/dist/src/command-metadata.js +1 -1
  33. package/dist/src/command-schema.js +3 -3
  34. package/dist/src/compatibility-policy.js +1 -0
  35. package/dist/src/context.js +1 -1
  36. package/dist/src/contracts.d.ts +2 -2
  37. package/dist/src/debug-symbols.js +1 -1
  38. package/dist/src/device-input-state.js +1 -1
  39. package/dist/src/device.js +9 -0
  40. package/dist/src/devices2.js +1 -1
  41. package/dist/src/devices4.js +1 -0
  42. package/dist/src/find.js +1 -1
  43. package/dist/src/finders.js +1 -1
  44. package/dist/src/generic.js +1 -1
  45. package/dist/src/gesture-plan-types.js +1 -0
  46. package/dist/src/gesture-plan.js +1 -0
  47. package/dist/src/index.d.ts +1205 -1309
  48. package/dist/src/input-actions.js +4 -4
  49. package/dist/src/install-artifact.js +5 -1
  50. package/dist/src/install-artifact2.js +1 -0
  51. package/dist/src/interaction-snapshot.js +1 -1
  52. package/dist/src/interaction.d.ts +3 -6
  53. package/dist/src/interaction.js +1 -1
  54. package/dist/src/interactor.js +2 -2
  55. package/dist/src/interactor2.js +1 -0
  56. package/dist/src/internal/bin.js +1 -1
  57. package/dist/src/internal/daemon.js +14 -22
  58. package/dist/src/lease-context.js +1 -1
  59. package/dist/src/lease.js +1 -1
  60. package/dist/src/limrun.d.ts +361 -0
  61. package/dist/src/limrun.js +1 -0
  62. package/dist/src/linux.js +1 -1
  63. package/dist/src/logcat.js +1 -5
  64. package/dist/src/method-scope.js +1 -0
  65. package/dist/src/metro.d.ts +72 -3
  66. package/dist/src/metro.js +1 -1
  67. package/dist/src/metro2.js +1 -1
  68. package/dist/src/notifications.js +1 -1
  69. package/dist/src/physical-device-control.js +1 -0
  70. package/dist/src/plist.js +1 -0
  71. package/dist/src/react-native.js +1 -1
  72. package/dist/src/recording-export-quality.js +15 -0
  73. package/dist/src/register-builtins.js +1 -1
  74. package/dist/src/registry.js +24 -24
  75. package/dist/src/remote-config.d.ts +5 -2
  76. package/dist/src/remote-config.js +1 -1
  77. package/dist/src/remote-config2.js +1 -0
  78. package/dist/src/reporting.js +8 -8
  79. package/dist/src/runner-client.js +1 -1
  80. package/dist/src/runner-disposal.js +1 -2
  81. package/dist/src/runner-lease.js +1 -1
  82. package/dist/src/runner-provider.js +1 -1
  83. package/dist/src/runtime-transport.js +1 -1
  84. package/dist/src/runtime.js +3 -3
  85. package/dist/src/runtime2.js +1 -1
  86. package/dist/src/sdk-android-adb.d.ts +4 -24
  87. package/dist/src/sdk-android-adb.js +4 -4
  88. package/dist/src/sdk-batch-runner.d.ts +13 -3
  89. package/dist/src/sdk-batch-runner.js +3 -2
  90. package/dist/src/sdk-contracts.d.ts +31 -91
  91. package/dist/src/sdk-contracts.js +2 -2
  92. package/dist/src/sdk-device.js +1 -1
  93. package/dist/src/sdk-finders.d.ts +3 -2
  94. package/dist/src/sdk-finders.js +1 -1
  95. package/dist/src/sdk-remote-config.d.ts +83 -53
  96. package/dist/src/sdk-selectors.js +1 -1
  97. package/dist/src/selector-runtime.js +1 -1
  98. package/dist/src/selector-vocabulary.js +1 -1
  99. package/dist/src/selectors.d.ts +1 -1
  100. package/dist/src/selectors.js +1 -1
  101. package/dist/src/server.js +2 -2
  102. package/dist/src/session-target-evidence.js +1 -1
  103. package/dist/src/session.js +8 -8
  104. package/dist/src/simulator.js +1 -1
  105. package/dist/src/snapshot-diagnostics.js +4 -4
  106. package/dist/src/snapshot2.js +1 -1
  107. package/dist/src/tool-provider.js +3 -3
  108. package/dist/src/tool-provider2.js +1 -1
  109. package/dist/src/tool-provider3.js +1 -0
  110. package/dist/src/tv-remote.d.ts +213 -0
  111. package/dist/src/unsupported-interactor.js +1 -0
  112. package/dist/src/web.js +1 -1
  113. package/dist/src/xml.js +2 -0
  114. package/package.json +41 -19
  115. package/server.json +2 -2
  116. package/skills/agent-device/SKILL.md +5 -3
  117. package/smithery.yaml +1 -1
  118. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.0.apk.sha256 +0 -1
  119. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.0.apk.sha256 +0 -1
  120. package/dist/src/android-system-chrome.js +0 -1
  121. package/dist/src/client-metro-companion.js +0 -1
  122. package/dist/src/config.js +0 -1
  123. package/dist/src/daemon-shutdown-report.js +0 -1
  124. package/dist/src/project-runtime.js +0 -1
  125. package/dist/src/scoped-provider.js +0 -1
  126. package/dist/src/sdk-batch.js +0 -2
  127. package/dist/src/snapshot-quality.js +0 -1
  128. package/dist/src/tv-remote.js +0 -15
@@ -1,4 +1,4 @@
1
- import{d as e,p as t,r as n}from"./registry.js";import{r}from"./command-metadata.js";const i={cdp:{usageOverride:`cdp [...args]`,listUsageOverride:`cdp`,helpDescription:`Run CDP commands for React Native diagnostics, JS heap usage, heap snapshots, and leak analysis`,summary:`Inspect React Native CDP targets, JS heap growth, heap snapshots, retainers, and leak signals`,positionalArgs:[`args?`],allowsExtraPositionals:!0,supportedFlags:e},auth:{usageOverride:`auth status|login|logout`,listUsageOverride:`auth`,helpDescription:`Manage cloud login state used by remote daemon and cloud device workflows.`,summary:`Manage cloud login state used by remote daemon and cloud device workflows`,positionalArgs:[`status|login|logout`],supportedFlags:[`remoteConfig`,`stateDir`]},daemon:{usageOverride:`daemon stop [--state-dir <path>] [--clean]`,listUsageOverride:`daemon stop`,helpDescription:`Stop a local daemon after verifying its PID/start-time identity. Use --clean to remove retained Apple runner processes and leases owned by that daemon.`,summary:`Safely stop a local daemon and optionally clean retained runner resources`,positionalArgs:[`stop`],allowedFlags:[`clean`],supportedFlags:[`stateDir`]},device:{usageOverride:`device status [--platform <platform>] [--udid <udid>] [--serial <serial>]`,listUsageOverride:`device status`,helpDescription:`Inspect advisory host-local device ownership claims without starting or contacting a daemon.`,summary:`Inspect local advisory device ownership without daemon side effects`,positionalArgs:[`status`],supportedFlags:[`platform`,`device`,`udid`,`serial`]},connect:{usageOverride:`connect [cloud|proxy|limrun|browserstack|aws-device-farm] [--remote-config <path>] [--daemon-base-url <url>] [--tenant <id>] [--run-id <id>] [--lease-id <id>] [--lease-backend <backend>] [--force] [--no-login]`,helpDescription:`Connect to a remote daemon, authenticate when needed, and save remote session state. AGENT_DEVICE_CLOUD_BASE_URL is the bridge/control-plane API origin; use AGENT_DEVICE_DAEMON_AUTH_TOKEN=adc_live_... for CI/service-token automation.`,listUsageOverride:`connect`,summary:`Attach CLI commands to a saved remote daemon/cloud lease; inspect for remote runs, tenants, or service-token CI`,allowedFlags:[`remoteConfig`,`daemonBaseUrl`,`tenant`,`runId`,`leaseId`,`leaseBackend`,`providerApp`,`providerOsVersion`,`providerProject`,`providerBuild`,`providerSessionName`,`awsProjectArn`,`awsDeviceArn`,`awsAppArn`,`awsRegion`,`awsInteractionMode`,`force`,`noLogin`],supportedFlags:[`stateDir`,`daemonAuthToken`,`session`,`platform`,`device`,...t,`launchUrl`]},connection:{usageOverride:`connection status`,listUsageOverride:`connection`,helpDescription:`Inspect active remote connection state`,summary:`Inspect the active saved remote connection before assuming commands are local`,positionalArgs:[`status`],supportedFlags:[`remoteConfig`,`stateDir`,`session`]},disconnect:{helpDescription:`Disconnect remote daemon state, stop owned Metro companion, and release lease`,listUsageOverride:`disconnect`,summary:`Clear remote connection state, stop owned Metro companions, and release remote leases`,allowedFlags:[`shutdown`],supportedFlags:[`remoteConfig`,`stateDir`,`session`]},mcp:{helpDescription:`Start the official stdio MCP server. It exposes structured command tools backed by the agent-device client.`,summary:`Start MCP server`},proxy:{usageOverride:`proxy [--host <host>] [--port <port>] [--daemon-auth-token <token>] [--state-dir <path>]`,listUsageOverride:`proxy`,helpDescription:`Expose the local daemon HTTP contract through a tunnel-friendly reverse proxy.
1
+ import{_ as e}from"./sdk-contracts.js";import{d as t,p as n,r}from"./registry.js";import{r as i}from"./command-metadata.js";const a={cdp:{usageOverride:`cdp [...args]`,listUsageOverride:`cdp`,helpDescription:`Run CDP commands for React Native diagnostics, JS heap usage, heap snapshots, and leak analysis`,summary:`Inspect React Native CDP targets, JS heap growth, heap snapshots, retainers, and leak signals`,positionalArgs:[`args?`],allowsExtraPositionals:!0,supportedFlags:t},auth:{usageOverride:`auth status|login|logout`,listUsageOverride:`auth`,helpDescription:`Manage cloud login state used by remote daemon and cloud device workflows.`,summary:`Manage cloud login state used by remote daemon and cloud device workflows`,positionalArgs:[`status|login|logout`],supportedFlags:[`remoteConfig`,`stateDir`]},daemon:{usageOverride:`daemon stop [--state-dir <path>] [--clean]`,listUsageOverride:`daemon stop`,helpDescription:`Stop a local daemon after verifying its PID/start-time identity. Use --clean to remove retained Apple runner processes and leases owned by that daemon.`,summary:`Safely stop a local daemon and optionally clean retained runner resources`,positionalArgs:[`stop`],allowedFlags:[`clean`],supportedFlags:[`stateDir`]},device:{usageOverride:`device status [--platform <platform>] [--udid <udid>] [--serial <serial>] [--stale]`,listUsageOverride:`device status`,helpDescription:`Inspect advisory host-local device ownership claims without starting or contacting a daemon. --stale only inspects proven-stale claims; it does not reclaim claims or clean platform resources.`,summary:`Inspect local advisory device ownership without daemon side effects`,positionalArgs:[`status`],allowedFlags:[`stale`],supportedFlags:[`platform`,`device`,`udid`,`serial`]},connect:{usageOverride:`connect [cloud|proxy|limrun|browserstack|aws-device-farm] [--remote-config <path>] [--daemon-base-url <url>] [--tenant <id>] [--run-id <id>] [--lease-id <id>] [--lease-backend <backend>] [--force] [--no-login]`,helpDescription:`Connect to a remote daemon, authenticate when needed, and save remote session state. AGENT_DEVICE_CLOUD_BASE_URL is the bridge/control-plane API origin; use AGENT_DEVICE_DAEMON_AUTH_TOKEN=adc_live_... for CI/service-token automation.`,listUsageOverride:`connect`,summary:`Attach CLI commands to a saved remote daemon/cloud lease; inspect for remote runs, tenants, or service-token CI`,positionalArgs:[`provider?`],allowedFlags:[`remoteConfig`,`daemonBaseUrl`,`tenant`,`runId`,`leaseId`,`leaseBackend`,`providerApp`,`providerOsVersion`,`providerProject`,`providerBuild`,`providerSessionName`,`awsProjectArn`,`awsDeviceArn`,`awsAppArn`,`awsRegion`,`awsInteractionMode`,`force`,`noLogin`],supportedFlags:[`stateDir`,`daemonAuthToken`,`session`,`platform`,`device`,...n,`launchUrl`]},connection:{usageOverride:`connection status`,listUsageOverride:`connection`,helpDescription:`Inspect active remote connection state`,summary:`Inspect the active saved remote connection before assuming commands are local`,positionalArgs:[`status`],supportedFlags:[`remoteConfig`,`stateDir`,`session`]},disconnect:{helpDescription:`Disconnect remote daemon state, stop owned Metro companion, and release lease`,listUsageOverride:`disconnect`,summary:`Clear remote connection state, stop owned Metro companions, and release remote leases`,allowedFlags:[`shutdown`],supportedFlags:[`remoteConfig`,`stateDir`,`session`]},mcp:{helpDescription:`Start the official stdio MCP server. It exposes structured command tools backed by the agent-device client.`,summary:`Start MCP server`},proxy:{usageOverride:`proxy [--host <host>] [--port <port>] [--daemon-auth-token <token>] [--state-dir <path>]`,listUsageOverride:`proxy`,helpDescription:`Expose the local daemon HTTP contract through a tunnel-friendly reverse proxy.
2
2
 
3
3
  Run this on the host that has access to simulators/devices, expose the printed local proxy URL through a tunnel, then point another machine at the tunnel URL with connect proxy.
4
4
 
@@ -9,7 +9,7 @@ Use the /agent-device base path when connecting through cloudflared, ngrok, or a
9
9
  Examples:
10
10
  agent-device proxy --port 4310
11
11
  cloudflared tunnel --url http://127.0.0.1:4310
12
- agent-device connect proxy --daemon-base-url https://example.trycloudflare.com/agent-device --daemon-auth-token <token>`,summary:`Expose a local daemon through cloudflared, ngrok, or another HTTP tunnel`,allowedFlags:[`proxyHost`,`proxyPort`,`daemonAuthToken`,`stateDir`]},"react-devtools":{usageOverride:`react-devtools [...args]`,listUsageOverride:`react-devtools`,helpDescription:`Run pinned agent-react-devtools commands for React Native performance profiling, component trees, props/state/hooks, and render analysis`,summary:`Inspect React Native components, props, hooks, errors, slow renders, and rerender profiles`,positionalArgs:[`args?`],allowsExtraPositionals:!0,supportedFlags:e},web:{usageOverride:`web setup | web doctor`,listUsageOverride:`web setup|doctor`,helpDescription:`Install and inspect the managed web automation backend used by --platform web.
12
+ agent-device connect proxy --daemon-base-url https://example.trycloudflare.com/agent-device --daemon-auth-token <token>`,summary:`Expose a local daemon through cloudflared, ngrok, or another HTTP tunnel`,allowedFlags:[`proxyHost`,`proxyPort`,`daemonAuthToken`,`stateDir`]},"react-devtools":{usageOverride:`react-devtools [...args]`,listUsageOverride:`react-devtools`,helpDescription:`Run pinned agent-react-devtools commands for React Native performance profiling, component trees, props/state/hooks, and render analysis`,summary:`Inspect React Native components, props, hooks, errors, slow renders, and rerender profiles`,positionalArgs:[`args?`],allowsExtraPositionals:!0,supportedFlags:t},web:{usageOverride:`web setup | web doctor`,listUsageOverride:`web setup|doctor`,helpDescription:`Install and inspect the managed web automation backend used by --platform web.
13
13
 
14
14
  First-run flow:
15
15
  agent-device web setup
@@ -19,4 +19,4 @@ First-run flow:
19
19
 
20
20
  Runtime web commands do not install the backend implicitly. If the managed backend is missing, run agent-device web setup. The backend is resolved only from the managed install in the effective agent-device state dir.
21
21
 
22
- Use web setup to install or reuse the pinned backend. Use web doctor after setup to verify browser backend health.`,summary:`Manage web automation backend`,positionalArgs:[`setup|doctor`],supportedFlags:[`stateDir`]}},a=n();function o(e){return Object.hasOwn(i,e)?i[e]:void 0}function s(e){return Object.hasOwn(a,e)?a[e]:void 0}const c=new Map(r().map(t=>[t.name,{helpDescription:t.description,supportedFlags:e}]));function l(e){if(e)return d(e)}function u(e){let t=d(e);if(!t)throw Error(`Missing command schema for ${e}`);return t}function d(e){let t=o(e);if(t)return t;let n=c.get(e),r=s(e);if(n)return r?{...n,...r}:n}function f(e,t){let n=l(e);if(!n?.defaults)return!1;let r=!1;for(let[e,i]of Object.entries(n.defaults))t[e]===void 0&&(t[e]=i,r=!0);return r}export{u as n,l as r,f as t};
22
+ Use web setup to install or reuse the pinned backend. Use web doctor after setup to verify browser backend health.`,summary:`Manage web automation backend`,positionalArgs:[`setup|doctor`],supportedFlags:[`stateDir`]}},o=r();function s(e){return Object.hasOwn(a,e)?a[e]:void 0}function c(e){return Object.hasOwn(o,e)?o[e]:void 0}const l=new Map(i().map(e=>[e.name,{helpDescription:e.description,supportedFlags:t}]));function u(e){if(e)return p(e)}function d(e){let t=p(e);if(!t)throw Error(`Missing command schema for ${e}`);return t}function f(t,n,r){let i=u(t);if(!t||!i||i.allowsExtraPositionals)return;let a=i.positionalArgs?.length??0;if(!(n.length<=a))throw new e(`INVALID_ARGS`,`${r?`${r} ${t}`:t} accepts at most ${a} positional argument(s), received ${n.length}: ${n.join(` `)}`)}function p(e){let t=s(e);if(t)return t;let n=l.get(e),r=c(e);if(n)return r?{...n,...r}:n}function m(e,t){let n=u(e);if(!n?.defaults)return!1;let r=!1;for(let[e,i]of Object.entries(n.defaults))t[e]===void 0&&(t[e]=i,r=!0);return r}export{u as i,f as n,d as r,m as t};
@@ -0,0 +1 @@
1
+ const e={control:{retryMaxRetries:3},command:{retryTapMaxAttempts:2,targetLookupTimeoutMs:17e3,optionalTargetLookupTimeoutMs:7e3,scrollUntilVisibleTimeoutMs:2e4,waitForAnimationToEndTimeoutMs:15e3,waitForAnimationToEndDifferencePercent:.005,longPressDurationMs:3e3,swipeDurationMs:400,repeatDelayMs:100,scrollUntilVisibleSpeed:40,scrollUntilVisiblePercentage:100,eraseTextMaxCharacters:50},observation:{pollIntervalMs:200,defaultSettleAttempts:10},targetSwipe:{nearEdgeFraction:.1,farEdgeFraction:.9},screenSwipe:{nearEdgeFraction:.1,farEdgeFraction:.9,centerFraction:.5,downStartFraction:.2,upStartFraction:{android:.5,ios:.9}},scrollUntilVisibleSwipe:{nearEdgeFraction:.1,farEdgeFraction:.9}};function t(e){return Math.trunc(1e3*(100-e)/100)+1}const n={assertVisibleTimeoutMs:e.command.targetLookupTimeoutMs,assertNotVisibleTimeoutMs:e.command.targetLookupTimeoutMs,extendedWaitUntilTimeoutMs:e.command.targetLookupTimeoutMs,runFlowConditionTimeoutMs:e.command.optionalTargetLookupTimeoutMs},r=e.observation.pollIntervalMs*e.observation.defaultSettleAttempts;export{t as i,e as n,r,n as t};
@@ -1 +1 @@
1
- import{_ as e}from"./sdk-contracts.js";import{F as t,N as n,j as r}from"./sdk-android-adb.js";import{l as i,s as a}from"./sdk-batch.js";import{Ct as o,Dt as s,Jn as c,Ot as l,St as u,Ut as d,at as f,bt as p,c as m,ct as h,er as ee,ot as te,p as g,qn as _,r as ne,st as re,tr as ie,wt as ae}from"./tv-remote.js";import{_ as v,c as y,d as oe,g as se,m as b,o as ce,s as x}from"./sdk-device.js";import{t as le}from"./timeouts.js";import{m as ue,p as de}from"./runtime.js";import{d as S}from"./logcat.js";import{a as fe,o as pe}from"./boot-diagnostics.js";import{i as me}from"./lease-context.js";import{a as he,i as ge,r as _e,t as C}from"./register-builtins.js";import{t as ve}from"./apple-multitouch-support.js";import{n as ye,t as be}from"./launch-console.js";import{AsyncLocalStorage as w}from"node:async_hooks";import xe,{promises as T}from"node:fs";import Se from"node:path";let Ce=[];const E=new w;async function we(e,t){return await E.run([...e],t)}function Te(e){for(let t of O()){if(!t.ownsDevice(e))continue;let n=t.getInteractor(e);if(n)return n}}function D(e){return O().some(t=>t.ownsDevice(e))}async function Ee(e,t,n,r){for(let i of O()){if(!i.ownsDevice(e))continue;if(!i.installApp)throw j(i,e,`install`);let a=await i.installApp?.(e,t,n,r);if(a)return a;throw j(i,e,`install`)}}async function De(e,t,n){for(let r of O()){if(!r.ownsDevice(e))continue;if(!r.installInstallablePath)throw j(r,e,`install_from_source`);let i=await r.installInstallablePath?.(e,t,n);if(i)return i;throw j(r,e,`install_from_source`)}}async function Oe(e){for(let t of O()){if(!A(t,e.provider))continue;let n=await t.configurePortReverse?.(e);if(n)return n}}function O(){return E.getStore()??Ce}function ke(e,t={}){let n=e.map(e=>e.provider);return{providerRuntimeIds:n,providerRuntimeRequiredIds:je([...n,...t.providerRuntimeRequiredIds??[]]),leaseLifecycleProvider:Ne(e),recoverableProviderIds:e.filter(e=>e.recoverExpiredLease!==void 0).map(e=>e.provider),recoverExpiredLease:Ae(e),cloudArtifactProvider:Pe(e),deviceInventoryProvider:Fe(e),providerDeviceRuntimeScope:async t=>await we(e,t)}}function Ae(t){if(t.some(e=>e.recoverExpiredLease!==void 0))return async n=>{let r=t.find(e=>A(e,n.leaseProvider));if(!r?.recoverExpiredLease)throw new e(`UNSUPPORTED_OPERATION`,`Provider ${n.leaseProvider??`unknown`} cannot recover an expired lease.`,{provider:n.leaseProvider,leaseId:n.leaseId});await r.recoverExpiredLease(n)}}function je(e){return[...new Set(e)]}function Me(...e){let t=e.filter(e=>e!==void 0);if(t.length!==0)return{listCloudArtifacts:async e=>{for(let n of t){let t=await n.listCloudArtifacts?.(e);if(t)return t}}}}function Ne(e){if(e.length!==0)return{allocate:async(t,n)=>await k(e,`allocate`,t,n),heartbeat:async(t,n)=>await k(e,`heartbeat`,t,n),release:async(t,n)=>await k(e,`release`,t,n)}}function Pe(e){if(e.length!==0)return{listCloudArtifacts:async t=>await Ie(e,t)}}function Fe(e){if(e.length!==0)return async t=>{for(let n of e){if(!A(n,t.leaseProvider))continue;let e=await n.deviceInventoryProvider(t);if(e)return e}return null}}async function Ie(e,t){for(let n of e){if(!A(n,t.provider))continue;let e=await n.cloudArtifacts?.listCloudArtifacts?.(t);if(e)return e}}async function k(e,t,n,r){for(let i of e){if(!A(i,n.leaseProvider))continue;let e=i.leaseLifecycle[t],a=e?await e(n,r):void 0;if(a)return a}}function A(e,t){return e.provider===t}function j(t,n,r){throw new e(`UNSUPPORTED_OPERATION`,`Provider device runtime ${t.provider} does not support ${r} for this device.`,{provider:t.provider,deviceId:n.id,platform:b(n)})}const M=new w,Le=new w;async function Re(t,n,r){let i=await ze(t,n,r);if(r.allowLocalSimulatorFallback!==!1&&Ve(n,i)){let{findBootableIosSimulator:e}=await import(`./devices2.js`),t=await e({simulatorSetPath:r.simulatorSetPath,target:n.target});if(t)return t}if(i)return i;throw new e(`DEVICE_NOT_FOUND`,`No devices found`,{selector:n})}async function ze(e,t,n){try{return await v(e,t,n)}catch(e){if(Be(e,t))return;throw e}}function Be(t,n){return!N(n)&&t instanceof e&&t.code===`DEVICE_NOT_FOUND`}function Ve(e,t){return!N(e)&&(!e.platform||e.platform===`apple`||e.platform===`ios`)&&e.target!==`desktop`&&(!t||t.kind===`device`)}function N(e){return!!(e.udid||e.serial||e.deviceName)}async function He(e,n={}){let r=P(e),{iosSimulatorSetPath:i,...a}=r,o=Je(r,n),s={simulatorSetPath:i,allowStoppedAndroidAvdPlaceholders:n.allowStoppedAndroidAvdPlaceholders},c={platform:r.platform,target:e.target,cacheHit:!1};return await t(`resolve_target_device`,async()=>{let e=qe(o);if(e)return c.cacheHit=!0,e;let t=await F(r);if(t)return I(a)?L(o,await Re(t,a,{simulatorSetPath:i,allowLocalSimulatorFallback:r.leaseProvider===void 0})):L(o,await v(t,a,s));let n=await he(r);return I(a)?L(o,await Re(n,a,{simulatorSetPath:i})):L(o,await v(n,a,s))},c)}function P(t){let n=t.platform;if(t.target&&!n)throw new e(`INVALID_ARGS`,`Device target selector requires --platform. Use --platform ios|macos|android|linux|apple with --target mobile|tv|desktop.`);let r=se({simulatorSetPath:pe(t.iosSimulatorDeviceSet),platform:n,target:t.target}),i=fe(t.androidDeviceAllowlist);return{platform:n,target:t.target,deviceName:t.device,udid:t.udid,serial:t.serial,leaseId:t.leaseId,leaseProvider:t.leaseProvider,deviceKey:t.deviceKey,clientId:t.clientId,iosSimulatorSetPath:r,androidSerialAllowlist:i?Array.from(i).sort():void 0}}async function Ue(e){return M.getStore()?await e():await M.run(new Map,e)}async function We(e,t){return e?await Le.run(e,t):await t()}async function Ge(e,t){return await We(e,async()=>await Ue(t))}async function Ke(e){return await F(e)??await he(e)}async function F(e){let t=Le.getStore();if(!t)return null;let n=await t(e);return n==null?null:n.map(e=>({...e}))}function I(e){return ce(e.platform)}function qe(e){let t=M.getStore()?.get(e);if(t)return{...t}}function L(e,t){return M.getStore()?.set(e,{...t}),t}function Je(e,t){return JSON.stringify({request:e,options:t})}C();const Ye={device:!0},Xe=[`open`,`close`],Ze=[`record`],Qe=[`audio`,`find`,`get`,`is`,`network`,`screenshot`,`snapshot`,`wait`],$e=[`click`,`fill`,`focus`,`press`,`scroll`,`type`],et=[`viewport`],R=new Set([...Xe,...Ze,...Qe,...$e,...et]),z=tt(a(i));function tt(e){let t={};for(let[n,r]of Object.entries(e))t[n]=R.has(n)?{...r,web:Ye}:r;for(let t of R)if(!(t in e))throw Error(`Web command "${t}" missing from capability matrix`);return t}function B(e,t){let n=z[e];if(!n)return!0;let r=ge(t.platform);if(!r)return!1;let i=n[r.capability.bucket];if(!i)return!1;let a=r.capability.supportsByDefault?.[e];return a&&!a(t)?!1:i[t.kind??`unknown`]===!0}function nt(e,t){return ge(t.platform)?.capability.unsupportedHintByDefault?.[e]?.(t)}function rt(){return Object.keys(z).sort()}function it(e){let t=z[e];if(!t)return[];let n=[`apple`,`android`,`linux`,`web`],r=[];for(let e of n){let n=t[e];n&&Object.values(n).some(e=>e===!0)&&r.push(e)}return r}function at(e,t){if(t.platform===`web`||t.appleOs===`watchos`)throw H(e,V(e,t));if(ot(e)){st(e,t);return}if(t.appleOs===`visionos`)throw H(e,V(e,t));if(e.intent===`fling`&&`direction`in e&&t.platform===`linux`)throw H(e,`gesture fling is not supported on Linux`)}function ot(e){return e.intent===`pan`?(`pointerCount`in e?e.pointerCount:1)===2:e.intent===`pinch`||e.intent===`rotate`||e.intent===`transform`}function st(e,t){if(t.platform===`android`){if(t.target!==`tv`)return;throw H(e,`gesture ${e.intent} is not supported on Android TV`,`Android TV has no touch input — this gesture is supported on Android phones, tablets, and the iOS simulator only.`)}if(t.platform!==`apple`)throw H(e,V(e,t));ve(t,e.intent)}function V(e,t){return`gesture ${e.intent} is not supported on ${t.appleOs??t.platform}`}function H(t,n,r){return new e(`UNSUPPORTED_OPERATION`,n,{gesture:t.intent,...r?{hint:r}:{}})}const U=`No active session. Run open first.`;function W(e,t,n){return{ok:!1,error:{code:e,message:t,...n?{details:n}:{}}}}function ct(){return W(`SESSION_NOT_FOUND`,U)}function lt(e,t,n){if(B(e,t))return null;let r=n?.hint?nt(e,t):void 0;return{ok:!1,error:{code:`UNSUPPORTED_OPERATION`,message:n?.message??`${e} is not supported on this device`,...r?{hint:r}:{}}}}C();async function G(t,n){if(D(t)){let n=Te(t);if(n)return n;throw new e(`UNSUPPORTED_OPERATION`,`Provider device runtime does not have an active interactor for this device.`,{deviceId:t.id,platform:b(t)})}return await _e(t.platform).createInteractor(t,n)}const ut=/^[A-Za-z0-9_.:-]{1,64}$/,K=8*1024,q=4*1024;function dt(t){let n=t[0]?.trim(),r=t[1]?.trim();if(!n)throw new e(`INVALID_ARGS`,`trigger-app-event requires <event> [payloadJson]`);if(!ut.test(n))throw new e(`INVALID_ARGS`,`Invalid trigger-app-event event name: ${n}`,{hint:`Use 1-64 chars: letters, numbers, underscore, dot, colon, or dash.`});if(t.length>2)throw new e(`INVALID_ARGS`,`trigger-app-event accepts at most two arguments: <event> [payloadJson]`);return{eventName:n,payload:pt(r,n)}}function ft(t,n,r){let i=b(t),a=mt(t);if(!a)throw new e(`UNSUPPORTED_OPERATION`,`No app event URL template configured for ${i}.`,{hint:`Set AGENT_DEVICE_${i.toUpperCase()}_APP_EVENT_URL_TEMPLATE or AGENT_DEVICE_APP_EVENT_URL_TEMPLATE, for example "myapp://agent-device/event?name={event}&payload={payload}".`});let o=r?JSON.stringify(r):``,s=a.replaceAll(`{event}`,encodeURIComponent(n)).replaceAll(`{payload}`,encodeURIComponent(o)).replaceAll(`{platform}`,encodeURIComponent(i));if(s.length>q)throw new e(`INVALID_ARGS`,`trigger-app-event URL exceeds maximum supported length`,{hint:`Reduce payload size or shorten AGENT_DEVICE_*_APP_EVENT_URL_TEMPLATE.`,length:s.length,maxLength:q});return s}function pt(t,n){if(t)try{let r=JSON.parse(t);if(!r||typeof r!=`object`||Array.isArray(r))throw new e(`INVALID_ARGS`,`trigger-app-event payload for "${n}" must be a JSON object`);let i=JSON.stringify(r);if(Buffer.byteLength(i,`utf8`)>K)throw new e(`INVALID_ARGS`,`trigger-app-event payload for "${n}" exceeds ${K} bytes`);return r}catch(n){throw n instanceof e?n:new e(`INVALID_ARGS`,`Invalid trigger-app-event payload JSON: ${t}`)}}function mt(e){return((x(e)?process.env.AGENT_DEVICE_IOS_APP_EVENT_URL_TEMPLATE:y(e)?process.env.AGENT_DEVICE_MACOS_APP_EVENT_URL_TEMPLATE:process.env.AGENT_DEVICE_ANDROID_APP_EVENT_URL_TEMPLATE)??process.env.AGENT_DEVICE_APP_EVENT_URL_TEMPLATE)?.trim()||void 0}const J=[[0,0],[1,0],[0,1],[-1,0],[0,-1],[1,1],[-1,1],[1,-1],[-1,-1]];function ht(e,t){return ce(e.platform)&&t>1}function gt(e,t,n=2e4){if(e.length===0)return[];let r=t>0?t:e.length,i=[],a=[],o=0;for(let t of e){let e=(t.durationMs??0)+(t.pauseMs??0)+250,s=a.length>0&&o+e>n,c=a.length>=r;(s||c)&&(i.push(a),a=[],o=0),a.push(t),o+=e}return a.length>0&&i.push(a),i}function _t(e,t){if(t<=0)return[0,0];let[n,r]=J[e%J.length];return[n*t,r*t]}async function vt(e,t,n){for(let r=0;r<e;r+=1)await n(r),r<e-1&&t>0&&await le(t)}async function yt(e,t){let{x:n,y:r}=Y(t,`longpress requires x y [durationMs]`,{hint:`Direct platform longpress requires coordinates. In an open daemon session, use agent-device longpress @ref|selector [durationMs]; otherwise run snapshot -i, use the target rect center as x y, then retry longpress x y durationMs.`}),i=t[2]?Number(t[2]):void 0;return await e.longPress(n,r,i),{x:n,y:r,durationMs:i,..._(`Long pressed (${n}, ${r})`)}}async function bt(e,t){let{x:n,y:r}=Y(t,`focus requires x y`);return await e.focus(n,r),{x:n,y:r,..._(`Focused (${n}, ${r})`)}}async function xt(t,n,r){let i=Kt(n);if(i)throw new e(`INVALID_ARGS`,`type does not accept a target ref like "${i}"`,{hint:`Use fill ${i} "text" to target that field, or press ${i} then type "text" to append.`});let a=n.join(` `);if(!a)throw new e(`INVALID_ARGS`,`type requires text`);let o=h(r?.delayMs??0,`delay-ms`,0,1e4);return await t.type(a,o),{text:a,delayMs:o,..._(Q(`Typed`,a))}}async function St(t,n,r){if(r?.directElementSelector)return await Ct(t,r.directElementSelector,n,r);let i=Number(n[0]),a=Number(n[1]),o=n.slice(2).join(` `);if(Number.isNaN(i)||Number.isNaN(a)||!o)throw new e(`INVALID_ARGS`,`fill requires x y text`);let s=h(r?.delayMs??0,`delay-ms`,0,1e4);return await t.fill(i,a,o,s),{x:i,y:a,text:o,delayMs:s,..._(Q(`Filled`,o))}}async function Ct(t,n,r,i){if(!t.fillElementSelector)throw new e(`UNSUPPORTED_OPERATION`,`direct element selector fill is not supported`);let a=r.join(` `);if(!a)throw new e(`INVALID_ARGS`,`fill requires text`);let o=h(i.delayMs??0,`delay-ms`,0,1e4),s=await t.fillElementSelector(n,a,o);return{selector:n.raw,text:a,delayMs:o,...s??{},..._(Q(`Filled`,a))}}async function wt(e,t,n,r){if(r?.directElementSelector&&x(e))return await Tt(t,r.directElementSelector);let{x:i,y:a}=Y(n,`press requires x y`);if(y(e)&&r?.surface&&r.surface!==`app`)return await Et(i,a,r);let o=l(r);if(o!==`primary`)return await Dt(e,i,a,o,r);let s=At(r);return jt(s),ht(e,s.count)?await Nt(e,i,a,s,r):await It(t,i,a,s)}async function Tt(t,n){if(!t.tapElementSelector)throw new e(`UNSUPPORTED_OPERATION`,`direct element selector tap is not supported`);let r=await t.tapElementSelector(n),i=r?.maestroNonHittableCoordinateFallbackUsed===!0;return{selector:n.raw,...r??{},..._(i?`tapped via non-hittable coordinate fallback`:`Tapped ${n.raw}`)}}function Y(t,n,r){let i=Number(t[0]),a=Number(t[1]);if(Number.isNaN(i)||Number.isNaN(a))throw new e(`INVALID_ARGS`,n,r);return{x:i,y:a}}async function Et(t,n,r){let i=l(r);if(i!==`primary`)throw new e(`UNSUPPORTED_OPERATION`,`${i} click is not supported on macOS ${r.surface} sessions.`);let{runMacOsPressAction:a}=await import(`./helper.js`).then(e=>e.t);return await a(t,n,{bundleId:r.appBundleId,surface:r.surface}),{x:t,y:n,..._(Z({x:t,y:n}))}}async function Dt(e,t,n,r,i){if(Ot(e,r,i),e.platform===`linux`)return await kt(t,n,r);let{runAppleRunnerCommand:a}=await import(`./runner-client.js`).then(e=>e.o);return await a(e,{command:`mouseClick`,x:t,y:n,button:r,appBundleId:i?.appBundleId},Lt(i)),{x:t,y:n,button:r,..._(Z({x:t,y:n,button:r}))}}function Ot(e,t,n){let r=s({commandLabel:`click`,platform:b(e),button:t,count:n?.count,intervalMs:n?.intervalMs,holdMs:n?.holdMs,jitterPx:n?.jitterPx,doubleTap:n?.doubleTap});if(r)throw r}async function kt(e,t,n){if(n===`secondary`){let{rightClickLinux:n}=await import(`./input-actions2.js`);await n(e,t)}else{let{middleClickLinux:n}=await import(`./input-actions2.js`);await n(e,t)}return{x:e,y:t,button:n,..._(Z({x:e,y:t,button:n}))}}function At(e){return{count:X(e?.count,1,`count`,1,200),intervalMs:X(e?.intervalMs,0,`interval-ms`,0,1e4),holdMs:X(e?.holdMs,0,`hold-ms`,0,1e4),jitterPx:X(e?.jitterPx,0,`jitter-px`,0,100),doubleTap:!!e?.doubleTap}}function X(e,t,n,r,i){return h(e===void 0?t:e,n,r,i)}function jt({doubleTap:t,holdMs:n,jitterPx:r}){if(t&&n>0)throw new e(`INVALID_ARGS`,`double-tap cannot be combined with hold-ms`);if(t&&r>0)throw new e(`INVALID_ARGS`,`double-tap cannot be combined with jitter-px`)}async function Mt(e,t,n){let{runAppleRunnerCommand:r}=await import(`./runner-client.js`).then(e=>e.o),{MAX_RUNNER_SEQUENCE_STEPS:i,buildRunnerSequenceCommand:a,parseRunnerSequenceResult:o}=await import(`./runner-sequence.js`).then(e=>e.r),s=gt(t,i),c,l,u=0,d=[],f=0;for(let t of s){let i=await r(e,a(t,n?.appBundleId),Lt(n));c??=i,l=i;let s;try{s=o(i)}catch(e){throw Ft(e,f)}u+=s.completedSteps,d.push(...s.results),f+=t.length}return{...c??{},completedSteps:u,sequenceResults:d,...l?.gestureEndUptimeMs===void 0?{}:{gestureEndUptimeMs:l.gestureEndUptimeMs}}}async function Nt(e,t,n,r,i){let a=await Mt(e,Pt(e,t,n,r),i);return{x:t,y:n,count:r.count,intervalMs:r.intervalMs,holdMs:r.holdMs,jitterPx:r.jitterPx,doubleTap:r.doubleTap,timingMode:`runner-sequence`,...a,..._(Z({x:t,y:n}))}}function Pt(e,t,n,r){let i=r.doubleTap?`doubleTap`:r.holdMs>0?`longPress`:`tap`,a=i===`tap`&&x(e)&&!oe(e);return Array.from({length:r.count},(e,o)=>{let[s,c]=_t(o,r.jitterPx),l=o===r.count-1;return{kind:i,x:t+s,y:n+c,...a?{synthesized:!0}:{},...r.holdMs>0?{durationMs:r.holdMs}:{},...!l&&r.intervalMs>0?{pauseMs:r.intervalMs}:{}}})}function Ft(t,n){if(n===0||!(t instanceof e)||!t.details)return t;let r=t.details.failedStepIndex;if(typeof r!=`number`)return t;let i=t.details.completedSteps;return new e(t.code,t.message,{...t.details,failedStepIndex:r+n,chunkStepIndex:r,...typeof i==`number`?{completedSteps:n+i}:{}},t.cause)}async function It(e,t,n,r){let i;return await vt(r.count,r.intervalMs,async a=>{let[o,s]=_t(a,r.jitterPx),c=t+o,l=n+s;if(r.doubleTap){let t=await e.doubleTap(c,l);i??=t??void 0;return}if(r.holdMs>0){let t=await e.longPress(c,l,r.holdMs);i??=t??void 0}else{let t=await e.tap(c,l);i??=t??void 0}}),c({x:t,y:n,count:r.count,intervalMs:r.intervalMs,holdMs:r.holdMs,jitterPx:r.jitterPx,doubleTap:r.doubleTap,...i},Z({x:t,y:n}))}function Lt(e){return{verbose:e?.verbose,logPath:e?.logPath,traceLogPath:e?.traceLogPath,requestId:e?.requestId,iosXctestrunFile:e?.iosXctestrunFile,iosXctestDerivedDataPath:e?.iosXctestDerivedDataPath,iosXctestEnvDir:e?.iosXctestEnvDir}}async function Rt(t,n,r){let i=n[0],a=n[1]?Number(n[1]):void 0,o=r?.pixels,s=r?.durationMs;if(!i)throw new e(`INVALID_ARGS`,`scroll requires direction`);zt(a,o,s);let l=Wt(i),u={amount:a,pixels:o,durationMs:s},{interactionResult:d,completedPasses:f}=await Vt(t,r,l,u);return c(Ht(l,u,f,d),te(l.direction,l.edge,f,a,o))}function zt(e,t,n){Bt(e),ae(n),u({amount:e,pixels:t})}function Bt(t){if(t!==void 0&&!Number.isFinite(t))throw new e(`INVALID_ARGS`,`scroll amount must be a number`)}async function Vt(e,t,n,r){if(n.edge){let i=n.edge,a=await re({edge:i,captureState:async n=>await Ut(e,t,i,n),scroll:async()=>await e.scroll(n.direction,r)});return{interactionResult:a.result??{},completedPasses:a.passes}}return{interactionResult:await e.scroll(n.direction,r)??{},completedPasses:1}}function Ht(e,t,n,r){let i=o(r);return{direction:e.direction,...e.edge?{edge:e.edge,passes:n}:{},...t.amount===void 0?{}:{amount:t.amount},...t.pixels===void 0?{}:{pixels:t.pixels},...i===void 0?{}:{durationMs:i},...r}}async function Ut(t,n,r,i){if(typeof t.snapshot!=`function`)throw new e(`UNSUPPORTED_OPERATION`,`scroll ${r} requires snapshot support to verify hidden content before scrolling`);let a=t.snapshot;return await f({edge:r,scope:i,captureNodes:async e=>(await a({appBundleId:n?.appBundleId,scope:e})).nodes??[]})}function Wt(e){return e===`bottom`?{direction:`down`,edge:`bottom`}:e===`top`?{direction:`up`,edge:`top`}:{direction:p(e)}}async function Gt(e,t,n){let{x:r,y:i}=Y(t,`read requires x y`);if(e.platform===`android`){let{readAndroidTextAtPoint:t}=await import(`./input-actions.js`).then(e=>e.s);return{action:`read`,text:await t(e,r,i)??``}}if(e.platform===`linux`){let{readLinuxTextAtPoint:e}=await import(`./snapshot.js`).then(e=>e.n);return{action:`read`,text:await e(r,i,n?.surface)}}if(y(e)&&n?.surface&&n.surface!==`app`){let{runMacOsReadTextAction:e}=await import(`./helper.js`).then(e=>e.t);return{action:`read`,text:(await e(r,i,{bundleId:n.appBundleId,surface:n.surface})).text}}let{runAppleRunnerCommand:a}=await import(`./runner-client.js`).then(e=>e.o),o=await a(e,{command:`readText`,x:r,y:i,appBundleId:n?.appBundleId},{verbose:n?.verbose,logPath:n?.logPath,traceLogPath:n?.traceLogPath,requestId:n?.requestId,iosXctestrunFile:n?.iosXctestrunFile,iosXctestDerivedDataPath:n?.iosXctestDerivedDataPath,iosXctestEnvDir:n?.iosXctestEnvDir});return{action:`read`,text:typeof o.text==`string`?o.text:typeof o.message==`string`?o.message:``}}function Kt(e){return de(e[0])}function Z(e){return e.button&&e.button!==`primary`?`Clicked ${e.button} (${e.x}, ${e.y})`:`Tapped (${e.x}, ${e.y})`}function Q(e,t){return`${e} ${Array.from(t).length} chars`}function qt(e){let t=e.trim();return t.startsWith(`{`)&&t.endsWith(`}`)||t.startsWith(`[`)&&t.endsWith(`]`)}function Jt(t,n){let r=n?.subject??`Payload`,i=t.trim();if(!i)throw new e(`INVALID_ARGS`,`${r} cannot be empty`);let a=n?.expandPath?n.expandPath(i,n.cwd):i;try{if(!xe.statSync(a).isFile())throw new e(`INVALID_ARGS`,`${r} path is not a file: ${a}`);return{kind:`file`,path:a}}catch(t){if(t instanceof e)throw t;let n=t.code;if(n===`EACCES`||n===`EPERM`)throw new e(`INVALID_ARGS`,`${r} file is not readable: ${a}`);if(n&&n!==`ENOENT`)throw new e(`COMMAND_FAILED`,`Unable to read ${r} file: ${a}`,{cause:String(t)})}if(qt(i))return{kind:`inline`,text:i};throw new e(`INVALID_ARGS`,`${r} file not found: ${a}`)}async function Yt(t){let n=Jt(t,{subject:`Push payload`}),r=n.kind===`inline`?n.text:await Xt(n.path);try{let t=JSON.parse(r);if(!t||typeof t!=`object`||Array.isArray(t))throw new e(`INVALID_ARGS`,`push payload must be a JSON object`);return t}catch(n){throw n instanceof e?n:new e(`INVALID_ARGS`,`Invalid push payload JSON: ${t}`)}}async function Xt(t){try{return await T.readFile(t,`utf8`)}catch(n){let r=n.code;throw r===`ENOENT`?new e(`INVALID_ARGS`,`Push payload file not found: ${t}`):r===`EISDIR`?new e(`INVALID_ARGS`,`Push payload path is not a file: ${t}`):r===`EACCES`||r===`EPERM`?new e(`INVALID_ARGS`,`Push payload file is not readable: ${t}`):new e(`COMMAND_FAILED`,`Unable to read push payload file: ${t}`,{cause:String(n)})}}async function Zt(e,n,i,a,o){let s=$(o),c=await G(e,s);return r({level:`debug`,phase:`platform_command_prepare`,data:{command:n,platform:e.platform,kind:e.kind}}),await t(`platform_command`,async()=>await tn(e,c,n,i,a,o,s),{command:n,platform:e.platform})}async function Qt(t,n,r){let i=await G(t,$(r));if(!i.performGesture)throw new e(`UNSUPPORTED_OPERATION`,`Gesture execution is unavailable`);return await i.performGesture(n)}async function $t(e,t){return await(await G(e,$(t))).gestureViewport?.()}function $(e){return{requestId:e?.requestId,appBundleId:e?.appBundleId,verbose:e?.verbose,logPath:e?.logPath,traceLogPath:e?.traceLogPath,iosXctestrunFile:e?.iosXctestrunFile,iosXctestDerivedDataPath:e?.iosXctestDerivedDataPath,iosXctestEnvDir:e?.iosXctestEnvDir,runnerLeaseContext:e?.runnerLeaseContext}}const en={open:({device:e,interactor:t,positionals:n,context:r})=>nn(e,t,n,r),close:async({device:e,interactor:t,positionals:n})=>{let r=n[0];return r?(await t.close(r),{app:r,..._(`Closed: ${r}`)}):(e.platform===`web`&&await t.close(``),{closed:`session`,..._(`Closed session`)})},press:({device:e,interactor:t,positionals:n,context:r})=>wt(e,t,n,r),longpress:({interactor:e,positionals:t})=>yt(e,t),focus:({interactor:e,positionals:t})=>bt(e,t),type:({interactor:e,positionals:t,context:n})=>xt(e,t,n),fill:({interactor:e,positionals:t,context:n})=>St(e,t,n),scroll:({interactor:e,positionals:t,context:n})=>Rt(e,t,n),"trigger-app-event":({device:e,interactor:t,positionals:n,context:r})=>rn(e,t,n,r),screenshot:({interactor:e,positionals:t,outPath:n,context:r})=>an(e,t,n,r),viewport:({interactor:e,positionals:t})=>on(e,t),back:async({interactor:e,context:t})=>(await e.back(t?.backMode),{action:`back`,mode:t?.backMode??`in-app`,..._(`Back`)}),home:async({interactor:e})=>(await e.home(),{action:`home`,..._(`Home`)}),orientation:async({interactor:e,positionals:t})=>{let n=m(t[0]);return await e.setOrientation(n),{action:`orientation`,orientation:n,..._(`Rotated to ${n}`)}},"app-switcher":async({interactor:e})=>(await e.appSwitcher(),{action:`app-switcher`,..._(`Opened app switcher`)}),clipboard:({interactor:e,positionals:t})=>sn(e,t),keyboard:({device:e,positionals:t,context:n,runnerCtx:r})=>ln(e,t,n,r),"tv-remote":({device:e,interactor:t,positionals:n,context:r})=>cn(e,t,n,r),settings:({device:e,interactor:t,positionals:n,context:r})=>fn(e,t,n,r),push:({device:e,positionals:t,context:n})=>pn(e,t,n),snapshot:({interactor:e,context:t})=>mn(e,t),read:({device:e,positionals:t,context:n})=>Gt(e,t,n)};async function tn(t,n,r,i,a,o,s){let c=Object.hasOwn(en,r)?en[r]:void 0;if(!c)throw new e(`INVALID_ARGS`,`Unknown command: ${r}`);return await c({device:t,interactor:n,positionals:i,outPath:a,context:o,runnerCtx:s})}async function nn(t,n,r,i){let a=r[0],o=r[1],s=i?.launchConsole,c=i?.launchArgs;if(r.length>2)throw new e(`INVALID_ARGS`,`open accepts at most two arguments: <app|url> [url]`);if(!a){if(s)throw new e(`INVALID_ARGS`,`--launch-console requires an app target`);if(c&&c.length>0)throw new e(`INVALID_ARGS`,`--launch-args requires an app target`);return await n.openDevice(),{app:null,..._(`Opened device`)}}if(s&&(!x(t)||t.kind!==`simulator`))throw new e(`UNSUPPORTED_OPERATION`,ye);if(t.platform===`linux`&&c&&c.length>0)throw new e(`UNSUPPORTED_OPERATION`,`--launch-args is not supported on Linux.`);if(o!==void 0){if(S(a))throw new e(`INVALID_ARGS`,`open <app> <url> requires an app target as the first argument`);if(!S(o))throw new e(`INVALID_ARGS`,`open <app> <url> requires a valid URL target`);if(s)throw new e(`INVALID_ARGS`,be);return await n.open(a,{activity:i?.activity,appBundleId:i?.appBundleId,launchArgs:c,url:o}),{app:a,url:o,..._(`Opened: ${a}`)}}if(s&&S(a))throw new e(`INVALID_ARGS`,be);if(i?.clearAppState){if(S(a))throw new e(`INVALID_ARGS`,`Clearing app state requires an app target, not a deep link.`);await n.setSetting(`clear-app-state`,`clear`,a)}return await n.open(a,{activity:i?.activity,appBundleId:i?.appBundleId,launchConsole:s,launchArgs:c,terminateRunningApp:i?.terminateRunningApp}),{app:a,...s?{launchConsole:s}:{},..._(`Opened: ${a}`)}}async function rn(e,t,n,r){let{eventName:i,payload:a}=dt(n),o=ft(e,i,a);return await t.open(o,{appBundleId:r?.appBundleId}),{event:i,eventUrl:o,transport:`deep-link`,..._(`Triggered app event: ${i}`)}}async function an(e,t,n,r){let i=t[0]??n??`./screenshot-${Date.now()}.png`;await T.mkdir(Se.dirname(i),{recursive:!0});let a=ie(r);return await e.screenshot(i,{appBundleId:r?.appBundleId,pixelDensity:a.pixelDensity,fullscreen:a.fullscreen,normalizeStatusBar:a.normalizeStatusBar,stabilize:a.stabilize,surface:r?.surface,skipIosSimulatorBootCheck:r?.skipIosSimulatorBootCheck,captureBackend:r?.screenshotCaptureBackend}),{path:i,..._(`Saved screenshot: ${i}`)}}async function on(t,n){if(n.length!==2)throw new e(`INVALID_ARGS`,`viewport requires exactly two arguments: <width> <height>`);let r=g(n[0],`width`),i=g(n[1],`height`);if(!t.setViewport)throw new e(`UNSUPPORTED_OPERATION`,`viewport is not supported by this backend`);return await t.setViewport(r,i),{width:r,height:i,..._(`Viewport set: ${r}x${i}`)}}async function sn(t,n){let r=(n[0]??``).toLowerCase();if(r!==`read`&&r!==`write`)throw new e(`INVALID_ARGS`,`clipboard requires a subcommand: read or write`);if(r===`read`){if(n.length!==1)throw new e(`INVALID_ARGS`,`clipboard read does not accept additional arguments`);return{action:r,text:await t.readClipboard()}}if(n.length<2)throw new e(`INVALID_ARGS`,`clipboard write requires text (use "" to clear clipboard)`);let i=n.slice(1).join(` `);return await t.writeClipboard(i),{action:r,textLength:Array.from(i).length,..._(`Clipboard updated`)}}async function cn(t,n,r,i){if(t.target!==`tv`)throw new e(`UNSUPPORTED_OPERATION`,`tv-remote is supported only on TV targets`,{hint:`Select an Android TV or tvOS target with --target tv.`});if(r.length!==1)throw new e(`INVALID_ARGS`,`tv-remote requires exactly one button`);let a=ne(r[0]),o=i?.durationMs===void 0?void 0:h(i.durationMs,`durationMs`,0,1e4);return await n.tvRemote(a,o),{action:`tv-remote`,button:a,...o===void 0?{}:{durationMs:o},..._(`Pressed TV remote ${a}`)}}async function ln(t,n,r,i){let a=(n[0]??`status`).toLowerCase();if(!ue(a))throw new e(`INVALID_ARGS`,`keyboard requires a subcommand: status, get, dismiss, enter, or return`);if(n.length>1)throw new e(`INVALID_ARGS`,`keyboard accepts at most one subcommand argument`);if(t.platform===`android`)return await un(t,a);if(x(t))return await dn(t,a,r,i);throw new e(`UNSUPPORTED_OPERATION`,`keyboard is supported only on Android and iOS`)}async function un(e,t){if(t===`enter`||t===`return`){let{pressAndroidEnter:t}=await import(`./input-actions.js`).then(e=>e.s);return await t(e),{platform:`android`,action:`enter`,..._(`Keyboard enter pressed`)}}if(t===`dismiss`){let{dismissAndroidKeyboard:t}=await import(`./device-input-state.js`).then(e=>e.t),n=await t(e);return{platform:`android`,action:`dismiss`,attempts:n.attempts,wasVisible:n.wasVisible,dismissed:n.dismissed,visible:n.visible,inputType:n.inputType,type:n.type,inputMethodPackage:n.inputMethodPackage,focusedPackage:n.focusedPackage,focusedResourceId:n.focusedResourceId,inputOwner:n.inputOwner}}let{getAndroidKeyboardState:n}=await import(`./device-input-state.js`).then(e=>e.t),r=await n(e);return{platform:`android`,action:`status`,visible:r.visible,inputType:r.inputType,type:r.type,inputMethodPackage:r.inputMethodPackage,focusedPackage:r.focusedPackage,focusedResourceId:r.focusedResourceId,inputOwner:r.inputOwner}}async function dn(t,n,r,i){if(n!==`dismiss`&&n!==`enter`&&n!==`return`)throw new e(`UNSUPPORTED_OPERATION`,`keyboard status/get is currently supported only on Android; use keyboard dismiss or enter on iOS`);if(n===`enter`||n===`return`){let{runAppleRunnerCommand:e}=await import(`./runner-client.js`).then(e=>e.o),n=await e(t,{command:`keyboardReturn`,appBundleId:r?.appBundleId},i);return{platform:`ios`,action:`enter`,visible:n.visible,wasVisible:n.wasVisible,..._(`Keyboard enter pressed`)}}let{runAppleRunnerCommand:a}=await import(`./runner-client.js`).then(e=>e.o),o=await a(t,{command:`keyboardDismiss`,appBundleId:r?.appBundleId},i);return{platform:`ios`,action:`dismiss`,wasVisible:o.wasVisible,dismissed:o.dismissed,visible:o.visible,..._(o.dismissed?`Keyboard dismissed`:`Keyboard already hidden`)}}async function fn(t,n,i,a){let[o,s,l,u]=i;if(!o||!s&&o!==`clear-app-state`)throw new e(`INVALID_ARGS`,`settings requires setting state`);if(o===`clear-app-state`){let i=(s===`clear`?l:s)??a?.appBundleId;if(!i)throw new e(`INVALID_ARGS`,`settings clear-app-state requires an app id or an active app session.`);r({level:`debug`,phase:`settings_apply`,data:{setting:o,state:`clear`,appBundleId:i,platform:t.platform}});let u=await n.setSetting(o,`clear`,i);return u&&typeof u==`object`?c({setting:o,state:`clear`,...u},hn(u)??`Cleared user data for ${i}`):{setting:o,state:`clear`,..._(`Cleared user data for ${i}`)}}if(!s)throw new e(`INVALID_ARGS`,`settings requires setting state`);let f=o===`location`&&s===`set`,p=(o===`permission`||f?i[4]:i[2])??a?.appBundleId,m=o===`permission`?{permissionTarget:l,permissionMode:u}:f?{latitude:d(l,`latitude`),longitude:d(u,`longitude`)}:void 0;r({level:`debug`,phase:`settings_apply`,data:f?{setting:o,state:s,latitude:l,longitude:u,platform:t.platform}:o===`permission`?{setting:o,state:s,permissionTarget:l,permissionMode:u,platform:t.platform}:{setting:o,state:s,appBundleId:p,platform:t.platform}});let h=await n.setSetting(o,s,p,m);return h&&typeof h==`object`?c({setting:o,state:s,...h},hn(h)??`Updated setting: ${o}`):{setting:o,state:s,..._(`Updated setting: ${o}`)}}async function pn(t,n,r){let i=n[0]?.trim(),a=n[1]?.trim();if(!i||!a)throw new e(`INVALID_ARGS`,`push requires <bundle|package> <payload.json|inline-json>`);let o=await Yt(a);if(x(t)){let{pushIosNotification:e}=await import(`./apps.js`).then(e=>e.t);return await e(t,i,o),{platform:`ios`,bundleId:i,..._(`Pushed notification to ${i}`)}}let{pushAndroidNotification:s}=await import(`./notifications.js`),c=await s(t,i,o);return{platform:`android`,package:i,action:c.action,extrasCount:c.extrasCount,..._(`Pushed notification to ${i}`)}}async function mn(e,t){return await e.snapshot({appBundleId:t?.appBundleId,interactiveOnly:t?.snapshotInteractiveOnly,depth:t?.snapshotDepth,scope:t?.snapshotScope,raw:t?.snapshotRaw,includeRects:t?.snapshotIncludeRects,includeHiddenContentHints:t?.snapshotIncludeHiddenContentHints,surface:t?.surface})}function hn(e){return typeof e.message==`string`&&e.message.length>0?e.message:void 0}function gn(e,t,r,i,a,o){return{requestId:a??n().requestId,appBundleId:r,runnerLeaseContext:me({meta:o}),activity:t?.activity,launchConsole:t?.launchConsole,launchArgs:t?.launchArgs,clearAppState:t?.clearAppState,verbose:t?.verbose,logPath:e,traceLogPath:i,iosXctestrunFile:t?.iosXctestrunFile,iosXctestDerivedDataPath:t?.iosXctestDerivedDataPath,iosXctestEnvDir:t?.iosXctestEnvDir,screenshotCaptureBackend:t?.maestro?.screenshotCaptureBackend,snapshotInteractiveOnly:t?.snapshotInteractiveOnly,snapshotDepth:t?.snapshotDepth,snapshotScope:t?.snapshotScope,snapshotRaw:t?.snapshotRaw,snapshotIncludeHiddenContentHints:t?.snapshotIncludeHiddenContentHints,...ee(t),count:t?.count,intervalMs:t?.intervalMs,delayMs:t?.delayMs,durationMs:t?.durationMs,holdMs:t?.holdMs,jitterPx:t?.jitterPx,pixels:t?.pixels,doubleTap:t?.doubleTap,clickButton:l(t),backMode:t?.backMode,pauseMs:t?.pauseMs,pattern:t?.pattern}}export{D as C,De as S,Ge as _,Jt as a,ke as b,ct as c,rt as d,at as f,He as g,Ke as h,$t as i,lt as l,P as m,Zt as n,U as o,it as p,Qt as r,W as s,gn as t,B as u,Me as v,Ee as x,Oe as y};
1
+ import{_ as e}from"./sdk-contracts.js";import{I as t,N as n,j as r}from"./sdk-android-adb.js";import{E as i,a}from"./sdk-batch-runner.js";import{En as o,G as s,J as c,K as l,Q as u,Tn as d,X as f,Z as p,a as m,dn as h,q as ee,sn as te,un as ne,vn as g,yn as _}from"./recording-export-quality.js";import{L as re}from"./snapshot-diagnostics.js";import{_ as ie,c as v,f as ae,h as y,o as oe,p as se,s as b,v as x}from"./sdk-device.js";import{H as ce,T as le,x as ue}from"./gesture-plan-types.js";import{t as de}from"./timeouts.js";import{d as fe}from"./runtime.js";import{l as S}from"./install-artifact.js";import{a as pe,o as me}from"./boot-diagnostics.js";import{i as he}from"./lease-context.js";import{a as C,i as w,r as ge,t as T}from"./register-builtins.js";import{t as _e}from"./apple-multitouch-support.js";import{n as ve,t as E}from"./launch-console.js";import{AsyncLocalStorage as D}from"node:async_hooks";import ye,{promises as O}from"node:fs";import be from"node:path";let xe=[];const k=new D;async function Se(e,t){return await k.run([...e],t)}function Ce(e,t){for(let n of A()){if(!n.ownsDevice(e))continue;let r=n.getInteractor(e,t);if(r)return r}}function we(e){return A().some(t=>t.ownsDevice(e))}async function Te(e,t,n,r){for(let i of A()){if(!i.ownsDevice(e))continue;if(!i.installApp)throw N(i,e,`install`);let a=await i.installApp?.(e,t,n,r);if(a)return a;throw N(i,e,`install`)}}async function Ee(e,t,n){for(let r of A()){if(!r.ownsDevice(e))continue;if(!r.installInstallablePath)throw N(r,e,`install_from_source`);let i=await r.installInstallablePath?.(e,t,n);if(i)return i;throw N(r,e,`install_from_source`)}}async function De(e){for(let t of A()){if(!M(t,e.provider))continue;let n=await t.configurePortReverse?.(e);if(n)return n}}function A(){return k.getStore()??xe}function Oe(e,t={}){let n=e.map(e=>e.provider);return{providerRuntimeIds:n,providerRuntimeRequiredIds:je([...n,...t.providerRuntimeRequiredIds??[]]),leaseLifecycleProvider:Ne(e),recoverableProviderIds:e.filter(e=>e.recoverExpiredLease!==void 0).map(e=>e.provider),recoverExpiredLease:Ae(e),cloudArtifactProvider:Pe(e),deviceInventoryProvider:Fe(e),appleRunnerProvider:ke(e),providerDeviceRuntimeScope:async t=>await Se(e,t)}}function ke(e){if(e.some(e=>e.getAppleRunnerProvider!==void 0))return t=>{for(let n of e){if(!n.ownsDevice(t.device))continue;let e=n.getAppleRunnerProvider?.(t.device);if(e)return e}}}function Ae(t){if(t.some(e=>e.recoverExpiredLease!==void 0))return async n=>{let r=t.find(e=>M(e,n.leaseProvider));if(!r?.recoverExpiredLease)throw new e(`UNSUPPORTED_OPERATION`,`Provider ${n.leaseProvider??`unknown`} cannot recover an expired lease.`,{provider:n.leaseProvider,leaseId:n.leaseId});await r.recoverExpiredLease(n)}}function je(e){return[...new Set(e)]}function Me(...e){let t=e.filter(e=>e!==void 0);if(t.length!==0)return{listCloudArtifacts:async e=>{for(let n of t){let t=await n.listCloudArtifacts?.(e);if(t)return t}}}}function Ne(e){if(e.length!==0)return{allocate:async(t,n)=>await j(e,`allocate`,t,n),heartbeat:async(t,n)=>await j(e,`heartbeat`,t,n),release:async(t,n)=>await j(e,`release`,t,n)}}function Pe(e){if(e.length!==0)return{listCloudArtifacts:async t=>await Ie(e,t)}}function Fe(e){if(e.length!==0)return async t=>{for(let n of e){if(!M(n,t.leaseProvider))continue;let e=await n.deviceInventoryProvider(t);if(e)return e}return null}}async function Ie(e,t){for(let n of e){if(!M(n,t.provider))continue;let e=await n.cloudArtifacts?.listCloudArtifacts?.(t);if(e)return e}}async function j(e,t,n,r){for(let i of e){if(!M(i,n.leaseProvider))continue;let e=i.leaseLifecycle[t],a=e?await e(n,r):void 0;if(a)return a}}function M(e,t){return e.provider===t}function N(t,n,r){throw new e(`UNSUPPORTED_OPERATION`,`Provider device runtime ${t.provider} does not support ${r} for this device.`,{provider:t.provider,deviceId:n.id,platform:y(n)})}const P=new D,Le=new D;async function Re(t,n,r){let i=await ze(t,n,r);if(i)return i;let a=await Be(t,n,r);if(r.allowLocalSimulatorFallback!==!1&&He(n,a)){let{findBootableIosSimulator:e}=await import(`./devices2.js`),t=await e({simulatorSetPath:r.simulatorSetPath,target:n.target});if(t)return t}if(a)return a;throw new e(`DEVICE_NOT_FOUND`,`No devices found`,{selector:n})}async function ze(t,n,r){let i=r.appleSimulatorAppTarget?.trim();if(!i||F(n)||r.allowLocalSimulatorFallback===!1)return;let a=t.filter(e=>se(e,n)&&b(e)&&e.kind===`simulator`&&e.booted===!0);if(a.length<2)return;let{findIosSimulatorInstalledApp:o}=await import(`./apps.js`).then(e=>e.t),s=(await Promise.all(a.map(async e=>await o(e,i)?e:void 0))).filter(e=>e!==void 0);if(s.length===1)return s[0];let c=a.map(e=>({id:e.id,name:e.name}));throw s.length===0?new e(`APP_NOT_INSTALLED`,`No booted iOS simulator has ${i} installed`,{appTarget:i,candidates:c,hint:`Install the app on a booted simulator, or pass --udid to select the intended device explicitly.`}):new e(`AMBIGUOUS_MATCH`,`Multiple booted iOS simulators have ${i} installed`,{appTarget:i,candidates:s.map(e=>({id:e.id,name:e.name})),hint:`Pass --udid to select the intended simulator explicitly.`})}async function Be(e,t,n){try{return await x(e,t,n)}catch(e){if(Ve(e,t))return;throw e}}function Ve(t,n){return!F(n)&&t instanceof e&&t.code===`DEVICE_NOT_FOUND`}function He(e,t){return!F(e)&&(!e.platform||e.platform===`apple`||e.platform===`ios`)&&e.target!==`desktop`&&(!t||t.kind===`device`)}function F(e){return!!(e.udid||e.serial||e.deviceName)}async function Ue(e,n={}){let r=We(e),{iosSimulatorSetPath:i,...a}=r,o=Ze(r,n),s={simulatorSetPath:i,allowStoppedAndroidAvdPlaceholders:n.allowStoppedAndroidAvdPlaceholders},c={platform:r.platform,target:e.target,cacheHit:!1};return await t(`resolve_target_device`,async()=>{let e=Xe(o);if(e)return c.cacheHit=!0,e;let t=await I(r);if(t)return L(a)?R(o,await Re(t,a,{simulatorSetPath:i,allowLocalSimulatorFallback:r.leaseProvider===void 0,appleSimulatorAppTarget:n.appleSimulatorAppTarget})):R(o,await x(t,a,s));let l=await C(r);return L(a)?R(o,await Re(l,a,{simulatorSetPath:i,appleSimulatorAppTarget:n.appleSimulatorAppTarget})):R(o,await x(l,a,s))},c)}function We(t){let n=t.platform;if(t.target&&!n)throw new e(`INVALID_ARGS`,`Device target selector requires --platform. Use --platform ios|macos|android|vega|linux|apple with --target mobile|tv|desktop.`);let r=ie({simulatorSetPath:me(t.iosSimulatorDeviceSet),platform:n,target:t.target}),i=pe(t.androidDeviceAllowlist);return{platform:n,target:t.target,deviceName:t.device,udid:t.udid,serial:t.serial,leaseId:t.leaseId,leaseProvider:t.leaseProvider,deviceKey:t.deviceKey,clientId:t.clientId,iosSimulatorSetPath:r,androidSerialAllowlist:i?Array.from(i).sort():void 0}}async function Ge(e){return P.getStore()?await e():await P.run(new Map,e)}async function Ke(e,t){return e?await Le.run(e,t):await t()}async function qe(e,t){return await Ke(e,async()=>await Ge(t))}async function Je(e){return await I(e)??await C(e)}async function I(e){let t=Le.getStore();if(!t)return null;let n=await t(e);return n==null?null:n.map(e=>({...e}))}function Ye(e){return oe(e.platform)}function L(e){return Ye(e)}function Xe(e){let t=P.getStore()?.get(e);if(t)return{...t}}function R(e,t){return P.getStore()?.set(e,{...t}),t}function Ze(e,t){let{appleSimulatorAppTarget:n,...r}=t;return JSON.stringify({request:e,options:r})}T();const Qe={device:!0},$e=[`open`,`close`],et=[`record`],tt=[`audio`,`find`,`get`,`is`,`network`,`screenshot`,`snapshot`,`wait`],nt=[`click`,`fill`,`focus`,`press`,`scroll`,`type`],rt=[`viewport`],z=new Set([...$e,...et,...tt,...nt,...rt]),B=it(a(i));function it(e){let t={};for(let[n,r]of Object.entries(e))t[n]=z.has(n)?{...r,web:Qe}:r;for(let t of z)if(!(t in e))throw Error(`Web command "${t}" missing from capability matrix`);return t}function V(e,t){let n=B[e];if(!n)return!0;let r=w(t.platform);if(!r)return!1;let i=n[r.capability.bucket];if(!i)return!1;let a=r.capability.supportsByDefault?.[e];return a&&!a(t)?!1:i[t.kind??`unknown`]===!0}function at(e,t){return w(t.platform)?.capability.unsupportedHintByDefault?.[e]?.(t)}function ot(){return Object.keys(B).sort()}function st(e){let t=B[e];if(!t)return[];let n=[`apple`,`android`,`vega`,`linux`,`web`],r=[];for(let e of n){let n=t[e];n&&Object.values(n).some(e=>e===!0)&&r.push(e)}return r}function ct(e,t){if(t.platform===`web`||t.appleOs===`watchos`)throw U(e,H(e,t));if(lt(e)){ut(e,t);return}if(t.appleOs===`visionos`)throw U(e,H(e,t));if(e.intent===`fling`&&`direction`in e&&t.platform===`linux`)throw U(e,`gesture fling is not supported on Linux`)}function lt(e){return e.intent===`pan`?(`pointerCount`in e?e.pointerCount:1)===2:e.intent===`pinch`||e.intent===`rotate`||e.intent===`transform`}function ut(e,t){if(t.platform===`android`){if(t.target!==`tv`)return;throw U(e,`gesture ${e.intent} is not supported on Android TV`,`Android TV has no touch input — this gesture is supported on Android phones, tablets, and the iOS simulator only.`)}if(t.platform!==`apple`)throw U(e,H(e,t));_e(t,e.intent)}function H(e,t){return`gesture ${e.intent} is not supported on ${t.appleOs??t.platform}`}function U(t,n,r){return new e(`UNSUPPORTED_OPERATION`,n,{gesture:t.intent,...r?{hint:r}:{}})}const W=`No active session. Run open first.`;function G(e,t,n){return{ok:!1,error:{code:e,message:t,...n?{details:n}:{}}}}function dt(){return G(`SESSION_NOT_FOUND`,W)}function ft(e,t,n){if(V(e,t))return null;let r=n?.hint?at(e,t):void 0;return{ok:!1,error:{code:`UNSUPPORTED_OPERATION`,message:n?.message??`${e} is not supported on this device`,...r?{hint:r}:{}}}}T();async function K(t,n){if(we(t)){let r=Ce(t,n);if(r)return r;throw new e(`UNSUPPORTED_OPERATION`,`Provider device runtime does not have an active interactor for this device.`,{deviceId:t.id,platform:y(t)})}return await ge(t.platform).createInteractor(t,n)}const pt=/^[A-Za-z0-9_.:-]{1,64}$/,q=8*1024,J=4*1024;function mt(t){let n=t[0]?.trim(),r=t[1]?.trim();if(!n)throw new e(`INVALID_ARGS`,`trigger-app-event requires <event> [payloadJson]`);if(!pt.test(n))throw new e(`INVALID_ARGS`,`Invalid trigger-app-event event name: ${n}`,{hint:`Use 1-64 chars: letters, numbers, underscore, dot, colon, or dash.`});if(t.length>2)throw new e(`INVALID_ARGS`,`trigger-app-event accepts at most two arguments: <event> [payloadJson]`);return{eventName:n,payload:gt(r,n)}}function ht(t,n,r){let i=y(t),a=_t(t);if(!a)throw new e(`UNSUPPORTED_OPERATION`,`No app event URL template configured for ${i}.`,{hint:`Set AGENT_DEVICE_${i.toUpperCase()}_APP_EVENT_URL_TEMPLATE or AGENT_DEVICE_APP_EVENT_URL_TEMPLATE, for example "myapp://agent-device/event?name={event}&payload={payload}".`});let o=r?JSON.stringify(r):``,s=a.replaceAll(`{event}`,encodeURIComponent(n)).replaceAll(`{payload}`,encodeURIComponent(o)).replaceAll(`{platform}`,encodeURIComponent(i));if(s.length>J)throw new e(`INVALID_ARGS`,`trigger-app-event URL exceeds maximum supported length`,{hint:`Reduce payload size or shorten AGENT_DEVICE_*_APP_EVENT_URL_TEMPLATE.`,length:s.length,maxLength:J});return s}function gt(t,n){if(t)try{let r=JSON.parse(t);if(!r||typeof r!=`object`||Array.isArray(r))throw new e(`INVALID_ARGS`,`trigger-app-event payload for "${n}" must be a JSON object`);let i=JSON.stringify(r);if(Buffer.byteLength(i,`utf8`)>q)throw new e(`INVALID_ARGS`,`trigger-app-event payload for "${n}" exceeds ${q} bytes`);return r}catch(n){throw n instanceof e?n:new e(`INVALID_ARGS`,`Invalid trigger-app-event payload JSON: ${t}`)}}function _t(e){return((b(e)?process.env.AGENT_DEVICE_IOS_APP_EVENT_URL_TEMPLATE:v(e)?process.env.AGENT_DEVICE_MACOS_APP_EVENT_URL_TEMPLATE:process.env.AGENT_DEVICE_ANDROID_APP_EVENT_URL_TEMPLATE)??process.env.AGENT_DEVICE_APP_EVENT_URL_TEMPLATE)?.trim()||void 0}const vt=[[0,0],[1,0],[0,1],[-1,0],[0,-1],[1,1],[-1,1],[1,-1],[-1,-1]];function yt(e,t){return oe(e.platform)&&t>1}function bt(e,t,n=2e4){if(e.length===0)return[];let r=t>0?t:e.length,i=[],a=[],o=0;for(let t of e){let e=(t.durationMs??0)+(t.pauseMs??0)+250,s=a.length>0&&o+e>n,c=a.length>=r;(s||c)&&(i.push(a),a=[],o=0),a.push(t),o+=e}return a.length>0&&i.push(a),i}function xt(e,t){if(t<=0)return[0,0];let[n,r]=vt[e%vt.length];return[n*t,r*t]}async function St(e,t,n){for(let r=0;r<e;r+=1)await n(r),r<e-1&&t>0&&await de(t)}async function Ct(e,t){let{x:n,y:r}=Y(t,`longpress requires x y [durationMs]`,{hint:`Direct platform longpress requires coordinates. In an open daemon session, use agent-device longpress @ref|selector [durationMs]; otherwise run snapshot -i, use the target rect center as x y, then retry longpress x y durationMs.`}),i=t[2]?Number(t[2]):void 0;return await e.longPress(n,r,i),{x:n,y:r,durationMs:i,...g(`Long pressed (${n}, ${r})`)}}async function wt(e,t){let{x:n,y:r}=Y(t,`focus requires x y`);return await e.focus(n,r),{x:n,y:r,...g(`Focused (${n}, ${r})`)}}async function Tt(t,n,r){let i=Xt(n);if(i)throw new e(`INVALID_ARGS`,`type does not accept a target ref like "${i}"`,{hint:`Use fill ${i} "text" to target that field, or press ${i} then type "text" to append.`});let a=n.join(` `);if(!a)throw new e(`INVALID_ARGS`,`type requires text`);let o=c(r?.delayMs??0,`delay-ms`,0,1e4);return await t.type(a,o),{text:a,delayMs:o,...g(Q(`Typed`,a))}}async function Et(t,n,r){if(r?.directElementSelector)return await Dt(t,r.directElementSelector,n,r);let i=Number(n[0]),a=Number(n[1]),o=n.slice(2).join(` `);if(Number.isNaN(i)||Number.isNaN(a)||!o)throw new e(`INVALID_ARGS`,`fill requires x y text`);let s=c(r?.delayMs??0,`delay-ms`,0,1e4);return await t.fill(i,a,o,s),{x:i,y:a,text:o,delayMs:s,...g(Q(`Filled`,o))}}async function Dt(t,n,r,i){if(!t.fillElementSelector)throw new e(`UNSUPPORTED_OPERATION`,`direct element selector fill is not supported`);let a=r.join(` `);if(!a)throw new e(`INVALID_ARGS`,`fill requires text`);let o=c(i.delayMs??0,`delay-ms`,0,1e4),s=await t.fillElementSelector(n,a,o);return{selector:n.raw,text:a,delayMs:o,...s??{},...g(Q(`Filled`,a))}}async function Ot(e,t,n,r){if(r?.directElementSelector&&b(e))return await kt(t,r.directElementSelector);let{x:i,y:a}=Y(n,`press requires x y`);if(v(e)&&r?.surface&&r.surface!==`app`)return await At(i,a,r);let o=h(r);if(o!==`primary`)return await jt(e,i,a,o,r);let s=Pt(r);return Ft(s),yt(e,s.count)?await Lt(e,i,a,s,r):await Bt(t,i,a,s)}async function kt(t,n){if(!t.tapElementSelector)throw new e(`UNSUPPORTED_OPERATION`,`direct element selector tap is not supported`);let r=await t.tapElementSelector(n),i=r?.maestroNonHittableCoordinateFallbackUsed===!0;return{selector:n.raw,...r??{},...g(i?`tapped via non-hittable coordinate fallback`:`Tapped ${n.raw}`)}}function Y(t,n,r){let i=Number(t[0]),a=Number(t[1]);if(Number.isNaN(i)||Number.isNaN(a))throw new e(`INVALID_ARGS`,n,r);return{x:i,y:a}}async function At(t,n,r){let i=h(r);if(i!==`primary`)throw new e(`UNSUPPORTED_OPERATION`,`${i} click is not supported on macOS ${r.surface} sessions.`);let{runMacOsPressAction:a}=await import(`./helper.js`).then(e=>e.t);return await a(t,n,{bundleId:r.appBundleId,surface:r.surface}),{x:t,y:n,...g(Z({x:t,y:n}))}}async function jt(e,t,n,r,i){if(Mt(e,r,i),e.platform===`linux`)return await Nt(t,n,r);let{runAppleRunnerCommand:a}=await import(`./runner-client.js`).then(e=>e.o);return await a(e,{command:`mouseClick`,x:t,y:n,button:r,appBundleId:i?.appBundleId},Vt(i)),{x:t,y:n,button:r,...g(Z({x:t,y:n,button:r}))}}function Mt(e,t,n){let r=ne({commandLabel:`click`,platform:y(e),button:t,count:n?.count,intervalMs:n?.intervalMs,holdMs:n?.holdMs,jitterPx:n?.jitterPx,doubleTap:n?.doubleTap});if(r)throw r}async function Nt(e,t,n){if(n===`secondary`){let{rightClickLinux:n}=await import(`./input-actions2.js`);await n(e,t)}else{let{middleClickLinux:n}=await import(`./input-actions2.js`);await n(e,t)}return{x:e,y:t,button:n,...g(Z({x:e,y:t,button:n}))}}function Pt(e){return{count:X(e?.count,1,`count`,1,200),intervalMs:X(e?.intervalMs,0,`interval-ms`,0,1e4),holdMs:X(e?.holdMs,0,`hold-ms`,0,1e4),jitterPx:X(e?.jitterPx,0,`jitter-px`,0,100),doubleTap:!!e?.doubleTap}}function X(e,t,n,r,i){return c(e===void 0?t:e,n,r,i)}function Ft({doubleTap:t,holdMs:n,jitterPx:r}){if(t&&n>0)throw new e(`INVALID_ARGS`,`double-tap cannot be combined with hold-ms`);if(t&&r>0)throw new e(`INVALID_ARGS`,`double-tap cannot be combined with jitter-px`)}async function It(e,t,n){let{runAppleRunnerCommand:r}=await import(`./runner-client.js`).then(e=>e.o),{MAX_RUNNER_SEQUENCE_STEPS:i,buildRunnerSequenceCommand:a,parseRunnerSequenceResult:o}=await import(`./runner-sequence.js`).then(e=>e.r),s=bt(t,i),c,l,u=0,d=[],f=0;for(let t of s){let i=await r(e,a(t,n?.appBundleId),Vt(n));c??=i,l=i;let s;try{s=o(i)}catch(e){throw zt(e,f)}u+=s.completedSteps,d.push(...s.results),f+=t.length}return{...c??{},completedSteps:u,sequenceResults:d,...l?.gestureEndUptimeMs===void 0?{}:{gestureEndUptimeMs:l.gestureEndUptimeMs}}}async function Lt(e,t,n,r,i){let a=await It(e,Rt(e,t,n,r),i);return{x:t,y:n,count:r.count,intervalMs:r.intervalMs,holdMs:r.holdMs,jitterPx:r.jitterPx,doubleTap:r.doubleTap,timingMode:`runner-sequence`,...a,...g(Z({x:t,y:n}))}}function Rt(e,t,n,r){let i=r.doubleTap?`doubleTap`:r.holdMs>0?`longPress`:`tap`,a=i===`tap`&&b(e)&&!ae(e);return Array.from({length:r.count},(e,o)=>{let[s,c]=xt(o,r.jitterPx),l=o===r.count-1;return{kind:i,x:t+s,y:n+c,...a?{synthesized:!0}:{},...r.holdMs>0?{durationMs:r.holdMs}:{},...!l&&r.intervalMs>0?{pauseMs:r.intervalMs}:{}}})}function zt(t,n){if(n===0||!(t instanceof e)||!t.details)return t;let r=t.details.failedStepIndex;if(typeof r!=`number`)return t;let i=t.details.completedSteps;return new e(t.code,t.message,{...t.details,failedStepIndex:r+n,chunkStepIndex:r,...typeof i==`number`?{completedSteps:n+i}:{}},t.cause)}async function Bt(e,t,n,r){let i;return await St(r.count,r.intervalMs,async a=>{let[o,s]=xt(a,r.jitterPx),c=t+o,l=n+s;if(r.doubleTap){let t=await e.doubleTap(c,l);i??=t??void 0;return}if(r.holdMs>0){let t=await e.longPress(c,l,r.holdMs);i??=t??void 0}else{let t=await e.tap(c,l);i??=t??void 0}}),_({x:t,y:n,count:r.count,intervalMs:r.intervalMs,holdMs:r.holdMs,jitterPx:r.jitterPx,doubleTap:r.doubleTap,...i},Z({x:t,y:n}))}function Vt(e){return{verbose:e?.verbose,logPath:e?.logPath,traceLogPath:e?.traceLogPath,requestId:e?.requestId,iosXctestrunFile:e?.iosXctestrunFile,iosXctestDerivedDataPath:e?.iosXctestDerivedDataPath,iosXctestEnvDir:e?.iosXctestEnvDir}}async function Ht(t,n,r){let i=n[0],a=n[1]?Number(n[1]):void 0,o=r?.pixels,s=r?.durationMs;if(!i)throw new e(`INVALID_ARGS`,`scroll requires direction`);Ut(a,o,s);let c=Jt(i),u={amount:a,pixels:o,durationMs:s},{interactionResult:d,completedPasses:f}=await Gt(t,r,c,u);return _(Kt(c,u,f,d),l(c.direction,c.edge,f,a,o))}function Ut(e,t,n){Wt(e),u(n),f({amount:e,pixels:t})}function Wt(t){if(t!==void 0&&!Number.isFinite(t))throw new e(`INVALID_ARGS`,`scroll amount must be a number`)}async function Gt(e,t,n,r){if(n.edge){let i=n.edge,a=await ee({edge:i,captureState:async n=>await qt(e,t,i,n),scroll:async()=>await e.scroll(n.direction,r)});return{interactionResult:a.result??{},completedPasses:a.passes}}return{interactionResult:await e.scroll(n.direction,r)??{},completedPasses:1}}function Kt(e,t,n,r){let i=p(r);return{direction:e.direction,...e.edge?{edge:e.edge,passes:n}:{},...t.amount===void 0?{}:{amount:t.amount},...t.pixels===void 0?{}:{pixels:t.pixels},...i===void 0?{}:{durationMs:i},...r}}async function qt(t,n,r,i){if(typeof t.snapshot!=`function`)throw new e(`UNSUPPORTED_OPERATION`,`scroll ${r} requires snapshot support to verify hidden content before scrolling`);let a=t.snapshot;return await s({edge:r,scope:i,captureNodes:async e=>(await a({appBundleId:n?.appBundleId,scope:e})).nodes??[]})}function Jt(e){return e===`bottom`?{direction:`down`,edge:`bottom`}:e===`top`?{direction:`up`,edge:`top`}:{direction:ce(e)}}async function Yt(e,t,n){let{x:r,y:i}=Y(t,`read requires x y`);if(e.platform===`android`){let{readAndroidTextAtPoint:t}=await import(`./input-actions.js`).then(e=>e.s);return{action:`read`,text:await t(e,r,i)??``}}if(e.platform===`linux`){let{readLinuxTextAtPoint:e}=await import(`./snapshot.js`).then(e=>e.n);return{action:`read`,text:await e(r,i,n?.surface)}}if(v(e)&&n?.surface&&n.surface!==`app`){let{runMacOsReadTextAction:e}=await import(`./helper.js`).then(e=>e.t);return{action:`read`,text:(await e(r,i,{bundleId:n.appBundleId,surface:n.surface})).text}}let{runAppleRunnerCommand:a}=await import(`./runner-client.js`).then(e=>e.o),o=await a(e,{command:`readText`,x:r,y:i,appBundleId:n?.appBundleId},{verbose:n?.verbose,logPath:n?.logPath,traceLogPath:n?.traceLogPath,requestId:n?.requestId,iosXctestrunFile:n?.iosXctestrunFile,iosXctestDerivedDataPath:n?.iosXctestDerivedDataPath,iosXctestEnvDir:n?.iosXctestEnvDir});return{action:`read`,text:typeof o.text==`string`?o.text:typeof o.message==`string`?o.message:``}}function Xt(e){return fe(e[0])}function Z(e){return e.button&&e.button!==`primary`?`Clicked ${e.button} (${e.x}, ${e.y})`:`Tapped (${e.x}, ${e.y})`}function Q(e,t){return`${e} ${Array.from(t).length} chars`}function Zt(e){let t=e.trim();return t.startsWith(`{`)&&t.endsWith(`}`)||t.startsWith(`[`)&&t.endsWith(`]`)}function Qt(t,n){let r=n?.subject??`Payload`,i=t.trim();if(!i)throw new e(`INVALID_ARGS`,`${r} cannot be empty`);let a=n?.expandPath?n.expandPath(i,n.cwd):i;try{if(!ye.statSync(a).isFile())throw new e(`INVALID_ARGS`,`${r} path is not a file: ${a}`);return{kind:`file`,path:a}}catch(t){if(t instanceof e)throw t;let n=t.code;if(n===`EACCES`||n===`EPERM`)throw new e(`INVALID_ARGS`,`${r} file is not readable: ${a}`);if(n&&n!==`ENOENT`)throw new e(`COMMAND_FAILED`,`Unable to read ${r} file: ${a}`,{cause:String(t)})}if(Zt(i))return{kind:`inline`,text:i};throw new e(`INVALID_ARGS`,`${r} file not found: ${a}`)}async function $t(t){let n=Qt(t,{subject:`Push payload`}),r=n.kind===`inline`?n.text:await en(n.path);try{let t=JSON.parse(r);if(!t||typeof t!=`object`||Array.isArray(t))throw new e(`INVALID_ARGS`,`push payload must be a JSON object`);return t}catch(n){throw n instanceof e?n:new e(`INVALID_ARGS`,`Invalid push payload JSON: ${t}`)}}async function en(t){try{return await O.readFile(t,`utf8`)}catch(n){let r=n.code;throw r===`ENOENT`?new e(`INVALID_ARGS`,`Push payload file not found: ${t}`):r===`EISDIR`?new e(`INVALID_ARGS`,`Push payload path is not a file: ${t}`):r===`EACCES`||r===`EPERM`?new e(`INVALID_ARGS`,`Push payload file is not readable: ${t}`):new e(`COMMAND_FAILED`,`Unable to read push payload file: ${t}`,{cause:String(n)})}}async function tn(e,n,i,a,o){let s=$(o),c=await K(e,s);return r({level:`debug`,phase:`platform_command_prepare`,data:{command:n,platform:e.platform,kind:e.kind}}),await t(`platform_command`,async()=>await on(e,c,n,i,a,o,s),{command:n,platform:e.platform})}async function nn(t,n,r){let i=await K(t,$(r));if(!i.performGesture)throw new e(`UNSUPPORTED_OPERATION`,`Gesture execution is unavailable`);return await i.performGesture(n)}async function rn(e,t){return await(await K(e,$(t))).gestureViewport?.()}function $(e){return{requestId:e?.requestId,appBundleId:e?.appBundleId,verbose:e?.verbose,logPath:e?.logPath,traceLogPath:e?.traceLogPath,iosXctestrunFile:e?.iosXctestrunFile,iosXctestDerivedDataPath:e?.iosXctestDerivedDataPath,iosXctestEnvDir:e?.iosXctestEnvDir,runnerLeaseContext:e?.runnerLeaseContext}}const an={open:({device:e,interactor:t,positionals:n,context:r})=>sn(e,t,n,r),close:async({device:e,interactor:t,positionals:n})=>{let r=n[0];return r?(await t.close(r),{app:r,...g(`Closed: ${r}`)}):(e.platform===`web`&&await t.close(``),{closed:`session`,...g(`Closed session`)})},press:({device:e,interactor:t,positionals:n,context:r})=>Ot(e,t,n,r),longpress:({interactor:e,positionals:t})=>Ct(e,t),focus:({interactor:e,positionals:t})=>wt(e,t),type:({interactor:e,positionals:t,context:n})=>Tt(e,t,n),fill:({interactor:e,positionals:t,context:n})=>Et(e,t,n),scroll:({interactor:e,positionals:t,context:n})=>Ht(e,t,n),"trigger-app-event":({device:e,interactor:t,positionals:n,context:r})=>cn(e,t,n,r),screenshot:({interactor:e,positionals:t,outPath:n,context:r})=>ln(e,t,n,r),viewport:({interactor:e,positionals:t})=>un(e,t),back:async({interactor:e,context:t})=>(await e.back(t?.backMode),{action:`back`,mode:t?.backMode??`in-app`,...g(`Back`)}),home:async({interactor:e})=>(await e.home(),{action:`home`,...g(`Home`)}),orientation:async({interactor:e,positionals:t})=>{let n=te(t[0]),r=(await e.setOrientation(n))?.orientation??n;return{action:`orientation`,orientation:r,...g(`Rotated to ${r}`)}},"app-switcher":async({interactor:e})=>(await e.appSwitcher(),{action:`app-switcher`,...g(`Opened app switcher`)}),clipboard:({interactor:e,positionals:t})=>dn(e,t),keyboard:({device:e,positionals:t,context:n,runnerCtx:r})=>pn(e,t,n,r),"tv-remote":({device:e,interactor:t,positionals:n,context:r})=>fn(e,t,n,r),settings:({device:e,interactor:t,positionals:n,context:r})=>gn(e,t,n,r),push:({device:e,positionals:t,context:n})=>_n(e,t,n),snapshot:({interactor:e,context:t})=>vn(e,t),read:({device:e,positionals:t,context:n})=>Yt(e,t,n)};async function on(t,n,r,i,a,o,s){let c=Object.hasOwn(an,r)?an[r]:void 0;if(!c)throw new e(`INVALID_ARGS`,`Unknown command: ${r}`);return await c({device:t,interactor:n,positionals:i,outPath:a,context:o,runnerCtx:s})}async function sn(t,n,r,i){let a=r[0],o=r[1],s=i?.launchConsole,c=i?.launchArgs;if(r.length>2)throw new e(`INVALID_ARGS`,`open accepts at most two arguments: <app|url> [url]`);if(!a){if(s)throw new e(`INVALID_ARGS`,`--launch-console requires an app target`);if(c&&c.length>0)throw new e(`INVALID_ARGS`,`--launch-args requires an app target`);return await n.openDevice(),{app:null,...g(`Opened device`)}}if(s&&(!b(t)||t.kind!==`simulator`))throw new e(`UNSUPPORTED_OPERATION`,ve);if(t.platform===`linux`&&c&&c.length>0)throw new e(`UNSUPPORTED_OPERATION`,`--launch-args is not supported on Linux.`);if(o!==void 0){if(S(a))throw new e(`INVALID_ARGS`,`open <app> <url> requires an app target as the first argument`);if(!S(o))throw new e(`INVALID_ARGS`,`open <app> <url> requires a valid URL target`);if(s)throw new e(`INVALID_ARGS`,E);return await n.open(a,{activity:i?.activity,appBundleId:i?.appBundleId,launchArgs:c,url:o}),{app:a,url:o,...g(`Opened: ${a}`)}}if(s&&S(a))throw new e(`INVALID_ARGS`,E);if(i?.clearAppState){if(S(a))throw new e(`INVALID_ARGS`,`Clearing app state requires an app target, not a deep link.`);await n.setSetting(`clear-app-state`,`clear`,a)}return await n.open(a,{activity:i?.activity,appBundleId:i?.appBundleId,launchConsole:s,launchArgs:c,terminateRunningApp:i?.terminateRunningApp}),{app:a,...s?{launchConsole:s}:{},...g(`Opened: ${a}`)}}async function cn(e,t,n,r){let{eventName:i,payload:a}=mt(n),o=ht(e,i,a);return await t.open(o,{appBundleId:r?.appBundleId}),{event:i,eventUrl:o,transport:`deep-link`,...g(`Triggered app event: ${i}`)}}async function ln(e,t,n,r){let i=t[0]??n??`./screenshot-${Date.now()}.png`;await O.mkdir(be.dirname(i),{recursive:!0});let a=o(r);return await e.screenshot(i,{appBundleId:r?.appBundleId,pixelDensity:a.pixelDensity,fullscreen:a.fullscreen,normalizeStatusBar:a.normalizeStatusBar,stabilize:a.stabilize,surface:r?.surface,skipIosSimulatorBootCheck:r?.skipIosSimulatorBootCheck,captureBackend:r?.screenshotCaptureBackend}),{path:i,...g(`Saved screenshot: ${i}`)}}async function un(t,n){if(n.length!==2)throw new e(`INVALID_ARGS`,`viewport requires exactly two arguments: <width> <height>`);let r=m(n[0],`width`),i=m(n[1],`height`);if(!t.setViewport)throw new e(`UNSUPPORTED_OPERATION`,`viewport is not supported by this backend`);return await t.setViewport(r,i),{width:r,height:i,...g(`Viewport set: ${r}x${i}`)}}async function dn(t,n){let r=(n[0]??``).toLowerCase();if(r!==`read`&&r!==`write`)throw new e(`INVALID_ARGS`,`clipboard requires a subcommand: read or write`);if(r===`read`){if(n.length!==1)throw new e(`INVALID_ARGS`,`clipboard read does not accept additional arguments`);return{action:r,text:await t.readClipboard()}}if(n.length<2)throw new e(`INVALID_ARGS`,`clipboard write requires text (use "" to clear clipboard)`);let i=n.slice(1).join(` `);return await t.writeClipboard(i),{action:r,textLength:Array.from(i).length,...g(`Clipboard updated`)}}async function fn(t,n,r,i){if(t.target!==`tv`)throw new e(`UNSUPPORTED_OPERATION`,`tv-remote is supported only on TV targets`,{hint:`Select an Android TV, tvOS, or Vega OS target with --target tv.`});if(r.length!==1)throw new e(`INVALID_ARGS`,`tv-remote requires exactly one button`);let a=le(r[0]),o=i?.durationMs===void 0?void 0:c(i.durationMs,`durationMs`,0,1e4);return await n.tvRemote(a,o),{action:`tv-remote`,button:a,...o===void 0?{}:{durationMs:o},...g(`Pressed TV remote ${a}`)}}async function pn(t,n,r,i){let a=(n[0]??`status`).toLowerCase();if(!re(a))throw new e(`INVALID_ARGS`,`keyboard requires a subcommand: status, get, dismiss, enter, or return`);if(n.length>1)throw new e(`INVALID_ARGS`,`keyboard accepts at most one subcommand argument`);if(t.platform===`android`)return await mn(t,a);if(b(t))return await hn(t,a,r,i);throw new e(`UNSUPPORTED_OPERATION`,`keyboard is supported only on Android and iOS`)}async function mn(e,t){if(t===`enter`||t===`return`){let{pressAndroidEnter:t}=await import(`./input-actions.js`).then(e=>e.s);return await t(e),{platform:`android`,action:`enter`,...g(`Keyboard enter pressed`)}}if(t===`dismiss`){let{dismissAndroidKeyboard:t}=await import(`./device-input-state.js`).then(e=>e.t),n=await t(e);return{platform:`android`,action:`dismiss`,attempts:n.attempts,wasVisible:n.wasVisible,dismissed:n.dismissed,visible:n.visible,inputType:n.inputType,type:n.type,inputMethodPackage:n.inputMethodPackage,focusedPackage:n.focusedPackage,focusedResourceId:n.focusedResourceId,inputOwner:n.inputOwner}}let{getAndroidKeyboardState:n}=await import(`./device-input-state.js`).then(e=>e.t),r=await n(e);return{platform:`android`,action:`status`,visible:r.visible,inputType:r.inputType,type:r.type,inputMethodPackage:r.inputMethodPackage,focusedPackage:r.focusedPackage,focusedResourceId:r.focusedResourceId,inputOwner:r.inputOwner}}async function hn(t,n,r,i){if(n!==`dismiss`&&n!==`enter`&&n!==`return`)throw new e(`UNSUPPORTED_OPERATION`,`keyboard status/get is currently supported only on Android; use keyboard dismiss or enter on iOS`);if(n===`enter`||n===`return`){let{runAppleRunnerCommand:e}=await import(`./runner-client.js`).then(e=>e.o),n=await e(t,{command:`keyboardReturn`,appBundleId:r?.appBundleId},i);return{platform:`ios`,action:`enter`,visible:n.visible,wasVisible:n.wasVisible,...g(`Keyboard enter pressed`)}}let{runAppleRunnerCommand:a}=await import(`./runner-client.js`).then(e=>e.o),o=await a(t,{command:`keyboardDismiss`,appBundleId:r?.appBundleId},i);return{platform:`ios`,action:`dismiss`,wasVisible:o.wasVisible,dismissed:o.dismissed,visible:o.visible,...g(o.dismissed?`Keyboard dismissed`:`Keyboard already hidden`)}}async function gn(t,n,i,a){let[o,s,c,l]=i;if(!o||!s&&o!==`clear-app-state`)throw new e(`INVALID_ARGS`,`settings requires setting state`);if(o===`clear-app-state`){let i=(s===`clear`?c:s)??a?.appBundleId;if(!i)throw new e(`INVALID_ARGS`,`settings clear-app-state requires an app id or an active app session.`);r({level:`debug`,phase:`settings_apply`,data:{setting:o,state:`clear`,appBundleId:i,platform:t.platform}});let l=await n.setSetting(o,`clear`,i);return l&&typeof l==`object`?_({setting:o,state:`clear`,...l},yn(l)??`Cleared user data for ${i}`):{setting:o,state:`clear`,...g(`Cleared user data for ${i}`)}}if(!s)throw new e(`INVALID_ARGS`,`settings requires setting state`);let u=o===`location`&&s===`set`,d=(o===`permission`||u?i[4]:i[2])??a?.appBundleId,f=o===`permission`?{permissionTarget:c,permissionMode:l}:u?{latitude:ue(c,`latitude`),longitude:ue(l,`longitude`)}:void 0;r({level:`debug`,phase:`settings_apply`,data:u?{setting:o,state:s,latitude:c,longitude:l,platform:t.platform}:o===`permission`?{setting:o,state:s,permissionTarget:c,permissionMode:l,platform:t.platform}:{setting:o,state:s,appBundleId:d,platform:t.platform}});let p=await n.setSetting(o,s,d,f);return p&&typeof p==`object`?_({setting:o,state:s,...p},yn(p)??`Updated setting: ${o}`):{setting:o,state:s,...g(`Updated setting: ${o}`)}}async function _n(t,n,r){let i=n[0]?.trim(),a=n[1]?.trim();if(!i||!a)throw new e(`INVALID_ARGS`,`push requires <bundle|package> <payload.json|inline-json>`);let o=await $t(a);if(b(t)){let{pushIosNotification:e}=await import(`./apps.js`).then(e=>e.t);return await e(t,i,o),{platform:`ios`,bundleId:i,...g(`Pushed notification to ${i}`)}}let{pushAndroidNotification:s}=await import(`./notifications.js`),c=await s(t,i,o);return{platform:`android`,package:i,action:c.action,extrasCount:c.extrasCount,...g(`Pushed notification to ${i}`)}}async function vn(e,t){return await e.snapshot({appBundleId:t?.appBundleId,interactiveOnly:t?.snapshotInteractiveOnly,depth:t?.snapshotDepth,scope:t?.snapshotScope,raw:t?.snapshotRaw,includeRects:t?.snapshotIncludeRects,includeHiddenContentHints:t?.snapshotIncludeHiddenContentHints,surface:t?.surface})}function yn(e){return typeof e.message==`string`&&e.message.length>0?e.message:void 0}function bn(e,t,r,i,a,o){return{requestId:a??n().requestId,appBundleId:r,runnerLeaseContext:he({meta:o}),activity:t?.activity,launchConsole:t?.launchConsole,launchArgs:t?.launchArgs,clearAppState:t?.clearAppState,verbose:t?.verbose,logPath:e,traceLogPath:i,iosXctestrunFile:t?.iosXctestrunFile,iosXctestDerivedDataPath:t?.iosXctestDerivedDataPath,iosXctestEnvDir:t?.iosXctestEnvDir,screenshotCaptureBackend:t?.maestro?.screenshotCaptureBackend,snapshotInteractiveOnly:t?.snapshotInteractiveOnly,snapshotDepth:t?.snapshotDepth,snapshotScope:t?.snapshotScope,snapshotRaw:t?.snapshotRaw,snapshotIncludeHiddenContentHints:t?.snapshotIncludeHiddenContentHints,...d(t),count:t?.count,intervalMs:t?.intervalMs,delayMs:t?.delayMs,durationMs:t?.durationMs,holdMs:t?.holdMs,jitterPx:t?.jitterPx,pixels:t?.pixels,doubleTap:t?.doubleTap,clickButton:h(t),backMode:t?.backMode,pauseMs:t?.pauseMs,pattern:t?.pattern}}export{we as C,Ee as S,qe as _,Qt as a,Oe as b,dt as c,ot as d,ct as f,Ue as g,Je as h,rn as i,ft as l,We as m,tn as n,W as o,st as p,nn as r,G as s,bn as t,V as u,Me as v,Te as x,De as y};
@@ -1,2 +1,2 @@
1
- import { E as defaultHintForCode, R as centerOfRect, c as DaemonResponseData, d as JsonRpcId, f as JsonRpcRequestEnvelope, g as LeaseReleasePayload, h as LeaseHeartbeatPayload, i as DaemonInstallSource, k as normalizeError, m as LeaseBackend, o as DaemonRequest, p as LeaseAllocatePayload, r as DaemonError, s as DaemonResponse, x as SessionRuntimeHints } from "./sdk-contracts.js";
2
- export { type DaemonError, type DaemonInstallSource, type DaemonRequest, type DaemonResponse, type DaemonResponseData, type JsonRpcId, type JsonRpcRequestEnvelope, type LeaseAllocatePayload, type LeaseBackend, type LeaseHeartbeatPayload, type LeaseReleasePayload, type SessionRuntimeHints, centerOfRect, defaultHintForCode, normalizeError };
1
+ import { I as centerOfRect, c as DaemonResponseData, d as JsonRpcId, f as JsonRpcRequestEnvelope, i as DaemonInstallSource, o as DaemonRequest, p as LeaseBackend, r as DaemonError, s as DaemonResponse, v as SessionRuntimeHints, w as normalizeError, x as defaultHintForCode } from "./sdk-contracts.js";
2
+ export { type DaemonError, type DaemonInstallSource, type DaemonRequest, type DaemonResponse, type DaemonResponseData, type JsonRpcId, type JsonRpcRequestEnvelope, type LeaseBackend, type SessionRuntimeHints, centerOfRect, defaultHintForCode, normalizeError };
@@ -1,4 +1,4 @@
1
- import{_ as e}from"./sdk-contracts.js";import{h as t,v as n}from"./sdk-android-adb.js";import{u as r}from"./sdk-batch-runner.js";import i from"node:path";import a from"node:fs/promises";const o=/^[0-9a-fA-F-]{32,36}$/;function s(e){if(!(!e||!o.test(e)))return e.replaceAll(`-`,``).toUpperCase()}function c(e,t){return`${e.uuid}:${l(t)}`}function l(e){return`0x${e.toString(16)}`}function u(e){return typeof e==`string`&&e.length>0?e:void 0}function d(...e){for(let t of e){let e=u(t);if(e)return e}}function f(e){let t=e.filter(e=>!!e);return t.length>0?t.join(` `):void 0}function p(e){try{let t=JSON.parse(e);return r(t)?t:null}catch{return null}}function m(e){if(typeof e==`number`&&Number.isSafeInteger(e))return e;if(typeof e==`string`){let t=e.startsWith(`0x`)?Number.parseInt(e,16):Number(e);return Number.isSafeInteger(t)?t:void 0}}function h(e,t,n){if(!Object.hasOwn(e,t))return;let r=m(e[t]);if(r!==void 0)return r;v(n,t)}function g(e,t,n){if(!Object.hasOwn(e,t))return;let r=_(e[t]);if(r!==void 0)return r;v(n,t)}function _(e){if(typeof e==`bigint`)return e;if(typeof e==`number`&&Number.isSafeInteger(e)||typeof e==`string`&&/^(?:0x[0-9a-fA-F]+|\d+)$/.test(e))return BigInt(e)}function v(t,n){throw new e(`INVALID_ARGS`,`Invalid ${t} numeric field: ${n}`,{hint:`Crash artifact numeric fields must be integer numbers or integer numeric strings.`})}function y(e){return e.length===1?e[0]:void 0}function b(e){return[...new Set(e)]}function x(e){let t=e.match(/^(.*) \+ (\d+)$/);return t?{symbol:t[1],location:Number(t[2])}:{symbol:e}}const S=/^(?:arm64e?|arm64_32|x86_64|armv7[sk]?|i386)$/;function ee(e){return te(e)??w(e)}function te(e){let t=ne(e);if(!t)return null;let n=(Array.isArray(t.payload.usedImages)?t.payload.usedImages:[]).flatMap((e,t)=>C(e,t));if(n.length===0)return null;let r=re(Array.isArray(t.payload.threads)?t.payload.threads:[],n);return{format:`ips`,images:n,addresses:r.map(({frame:e,...t})=>t),document:t,frameMatches:r,write:e=>oe(t,r,e)}}function ne(e){let t=p(e);if(t)return{payload:t};let n=e.indexOf(`
1
+ import{_ as e}from"./sdk-contracts.js";import{h as t,v as n}from"./sdk-android-adb.js";import{m as r}from"./sdk-batch-runner.js";import i from"node:path";import a from"node:fs/promises";const o=/^[0-9a-fA-F-]{32,36}$/;function s(e){if(!(!e||!o.test(e)))return e.replaceAll(`-`,``).toUpperCase()}function c(e,t){return`${e.uuid}:${l(t)}`}function l(e){return`0x${e.toString(16)}`}function u(e){return typeof e==`string`&&e.length>0?e:void 0}function d(...e){for(let t of e){let e=u(t);if(e)return e}}function f(e){let t=e.filter(e=>!!e);return t.length>0?t.join(` `):void 0}function p(e){try{let t=JSON.parse(e);return r(t)?t:null}catch{return null}}function m(e){if(typeof e==`number`&&Number.isSafeInteger(e))return e;if(typeof e==`string`){let t=e.startsWith(`0x`)?Number.parseInt(e,16):Number(e);return Number.isSafeInteger(t)?t:void 0}}function h(e,t,n){if(!Object.hasOwn(e,t))return;let r=m(e[t]);if(r!==void 0)return r;v(n,t)}function g(e,t,n){if(!Object.hasOwn(e,t))return;let r=_(e[t]);if(r!==void 0)return r;v(n,t)}function _(e){if(typeof e==`bigint`)return e;if(typeof e==`number`&&Number.isSafeInteger(e)||typeof e==`string`&&/^(?:0x[0-9a-fA-F]+|\d+)$/.test(e))return BigInt(e)}function v(t,n){throw new e(`INVALID_ARGS`,`Invalid ${t} numeric field: ${n}`,{hint:`Crash artifact numeric fields must be integer numbers or integer numeric strings.`})}function y(e){return e.length===1?e[0]:void 0}function b(e){return[...new Set(e)]}function x(e){let t=e.match(/^(.*) \+ (\d+)$/);return t?{symbol:t[1],location:Number(t[2])}:{symbol:e}}const S=/^(?:arm64e?|arm64_32|x86_64|armv7[sk]?|i386)$/;function ee(e){return te(e)??w(e)}function te(e){let t=ne(e);if(!t)return null;let n=(Array.isArray(t.payload.usedImages)?t.payload.usedImages:[]).flatMap((e,t)=>C(e,t));if(n.length===0)return null;let r=re(Array.isArray(t.payload.threads)?t.payload.threads:[],n);return{format:`ips`,images:n,addresses:r.map(({frame:e,...t})=>t),document:t,frameMatches:r,write:e=>oe(t,r,e)}}function ne(e){let t=p(e);if(t)return{payload:t};let n=e.indexOf(`
2
2
  `);if(n===-1)return null;let r=e.slice(0,n),i=p(e.slice(n+1));return i?{header:r,payload:i}:null}function re(e,t){let n=new Map(t.map(e=>[e.index,e]));return e.flatMap((e,t)=>ie(e).flatMap((e,r)=>ae(e,n,t,r)))}function ie(e){return!r(e)||!Array.isArray(e.frames)?[]:e.frames.filter(r)}function ae(e,t,n,r){let i=h(e,`imageIndex`,`IPS frame`),a=g(e,`imageOffset`,`IPS frame`);if(i===void 0||a===void 0)return[];let o=t.get(i);return o?[{frame:e,frameIndex:r,threadIndex:n,image:o,address:o.base+a}]:[]}function oe(e,t,n){for(let e of t){let t=n.get(c(e.image,e.address))?.text;t&&se(e.frame,t)}e.payload.agentDeviceSymbolication={tool:`agent-device debug symbols`,symbolicatedFrames:[...n.values()].filter(e=>e.text).length};let r=`${JSON.stringify(e.payload,null,2)}\n`;return e.header?`${e.header}\n${r}`:r}function se(e,t){let n=x(t);e.symbol=n.symbol,n.location!==void 0&&(e.symbolLocation=n.location)}function C(e,t){if(!r(e))return[];let n=s(u(e.uuid)),a=g(e,`base`,`IPS usedImages`);if(!n||a===void 0)return[];let o=u(e.path);return[{index:t,name:u(e.name)??(o?i.basename(o):`image-${t}`),uuid:n,arch:u(e.arch),base:a,path:o}]}function w(e){let t=e.split(`
3
3
  `),n=T(t);if(n.length===0)return null;let r=O(t,n);return{format:`text`,images:n,addresses:r,lines:t,frameMatches:r,write(e){let n=new Map(r.map(e=>[e.lineIndex,e]));return t.map((t,r)=>{let i=n.get(r);if(!i)return t;let a=e.get(c(i.image,i.address))?.text;return!a||t.includes(a)?t:`${t} // ${a}`}).join(`
4
4
  `)}}}function T(e){let t=[],n=e.findIndex(e=>/^Binary Images:/i.test(e.trim()));if(n===-1)return t;for(let r of e.slice(n+1)){let e=E(r);e&&t.push(e)}return t}function E(e){let t=e.match(/^\s*(0x[0-9a-fA-F]+)\s*-\s*(0x[0-9a-fA-F]+)\s+\+?(.+?)\s+<([0-9a-fA-F-]{32,36})>\s+(.+)$/);if(!t)return null;let n=s(t[4]);if(!n)return null;let r=D(t[3].trim(),t[5].trim());return{name:r.name,arch:r.arch,uuid:n,base:BigInt(t[1]),end:BigInt(t[2]),path:t[5].trim()}}function D(e,t){let n=e.split(/\s+/),r=n.at(-1);if(r&&S.test(r))return{name:n.slice(0,-1).join(` `).trim(),arch:r};let a=i.basename(t);return{name:e.startsWith(a)?a:e}}function O(e,t){let n=[],r;for(let[i,a]of e.entries()){let e=a.match(/^Thread\s+(\d+)\s+Crashed:/);e?r=Number(e[1]):(a.trim().length===0||/^Thread\s+\d+/.test(a))&&(r=void 0);let o=k(a,t),s=a.match(/^\s*(\d+)/);o&&s&&n.push({...o,frameIndex:Number(s[1]),lineIndex:i,threadIndex:r})}return n}function k(e,t){let n=e.match(/^\s*\d+\s+(.+?)\s+(0x[0-9a-fA-F]+)\b/);if(!n)return null;let r=n[1].trim(),i=BigInt(n[2]),a=A(t,r,i);return a?{image:a,address:i}:null}function A(e,t,n){let r=e.filter(e=>e.name===t);return r.find(e=>j(e,n))??y(r)}function j(e,t){return e.end!==void 0&&e.base<=t&&t<=e.end}const M=1e4;async function N(e){return e.dsym&&e.searchPath?[H(e.cwd,e.dsym),...await P(H(e.cwd,e.searchPath))]:e.dsym?[H(e.cwd,e.dsym)]:e.searchPath?await P(H(e.cwd,e.searchPath)):[]}async function P(t){let n=[],r=0;async function o(s){if(n.length>=200)return;if(r+=1,r>M)throw new e(`COMMAND_FAILED`,`debug symbols search-path scan exceeded bounds.`,{searchPath:t,maxEntries:M,hint:`Pass --dsym <App.dSYM> directly or narrow --search-path to the build products directory.`});if(!(await F(s,t)).isDirectory()){s===t&&I(t);return}if(s.endsWith(`.dSYM`)){n.push(s);return}let c=await a.readdir(s,{withFileTypes:!0});for(let e of c)e.isDirectory()&&await o(i.join(s,e.name))}return await o(t),n}async function F(t,n){try{return await a.stat(t)}catch{throw new e(`INVALID_ARGS`,`debug symbols search path does not exist: ${n}`,{hint:`Pass an existing build products directory to --search-path, or pass --dsym <App.dSYM> directly.`})}}function I(t){throw new e(`INVALID_ARGS`,`debug symbols search path is not a directory: ${t}`,{hint:`Pass an existing build products directory to --search-path, or pass --dsym <App.dSYM> directly.`})}async function L(t,n){let r=(await Promise.all(b(t).map(e=>R(e,n)))).flat();if(r.length===0)throw new e(`COMMAND_FAILED`,`No UUIDs found in dSYM bundle.`,{hint:`Verify the path points to a built .dSYM bundle with DWARF contents.`});return r}async function R(e,r){return await z(e),B(e,t(await n(r,[`--uuid`,e],{timeoutMs:15e3,allowFailure:!0}),`Failed to inspect dSYM UUIDs: ${e}`,{hint:`Verify the dSYM bundle is valid and readable.`}).stdout)}async function z(t){if(!((await a.stat(t).catch(()=>null))?.isDirectory()&&t.endsWith(`.dSYM`)))throw new e(`INVALID_ARGS`,`Not a .dSYM bundle: ${t}`,{hint:`Pass the .dSYM bundle path, not the DWARF executable inside it.`})}function B(e,t){return t.split(`
@@ -1,2 +1,2 @@
1
- import{t as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{j as n,n as r,s as i}from"./sdk-android-adb.js";import{t as a}from"./timeouts.js";import{a as o,i as s,o as c,t as l}from"./android-input-ownership.js";import{o as u}from"./logcat.js";var d=e({dismissAndroidKeyboard:()=>v,dismissAndroidKeyboardWithAdb:()=>y,getAndroidKeyboardState:()=>g,getAndroidKeyboardStatusWithAdb:()=>_,readAndroidClipboardText:()=>A,readAndroidClipboardWithAdb:()=>j,writeAndroidClipboardText:()=>M,writeAndroidClipboardWithAdb:()=>N});const f=[`mInputShown`,`mIsInputViewShown`,`isInputViewShown`,`mDecorViewVisible`,`mWindowVisible`,`mInShowWindow`],p=new Map([[2,`number`],[3,`phone`],[4,`datetime`]]),m=new Set([32,208]),h=new Set([128,224,144]);async function g(e){return await _(i(e))}async function _(e){let t=await e([`shell`,`dumpsys`,`input_method`],{allowFailure:!0});if(t.exitCode!==0)throw r(`Failed to query Android keyboard state`,t);return b(t.stdout)}async function v(e){return await y(i(e))}async function y(e){let n=await _(e),r=n,i=0;for(;r.visible&&i<2;)await e([`shell`,`input`,`keyevent`,`111`]),i+=1,await a(120),r=await _(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 b(e){let t=T(e)??x(e),n=S(e),r=C(e,/\bpackageName=([A-Za-z0-9_.]+)\b/g),i=C(e,/\b(?:resourceId|resource-id)=([^\s,}]+)/g),a=c(e),o=l(r,i,a);return w(r,i,a),{visible:t??!1,inputType:n,type:n?k(n):void 0,inputMethodPackage:a,focusedPackage:r,focusedResourceId:i,inputOwner:o}}function x(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)!=0}function S(e){let t=C(e,/\binputType=0x([0-9a-fA-F]+)\b/gi);return t?`0x${t.toLowerCase()}`:void 0}function C(e,t){let n;for(let r of e.matchAll(t))n=r[1];return n}function w(e,t,r){r||!s(e)&&!o(t)||n({level:`warn`,phase:`android_input_ownership_fallback`,data:{focusedPackage:e,focusedResourceId:t}})}function T(e){return D(E(e,f))}function E(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 D(e){if(e.size===0)return null;let t=O(e,[`mWindowVisible`,`mDecorViewVisible`,`mInShowWindow`]);if(t!==void 0)return t;let n=e.get(`mInputShown`);return n===void 0?O(e,[`mIsInputViewShown`,`isInputViewShown`])??null:n}function O(e,t){for(let n of t){let t=e.get(n);if(t!==void 0)return t}}function k(e){let t=Number.parseInt(e.replace(/^0x/i,``),16);if(Number.isNaN(t))return`unknown`;let n=t&15,r=p.get(n);if(r)return r;if(n!==1)return`unknown`;let i=t&4080;return m.has(i)?`email`:h.has(i)?`password`:`text`}async function A(e){return await j(i(e))}async function j(e){return F(await P(e,[`shell`,`cmd`,`clipboard`,`get`,`text`],`read`))}async function M(e,t){await N(i(e),t)}async function N(e,t){await P(e,[`shell`,`cmd`,`clipboard`,`set`,`text`,t],`write`)}async function P(e,n,i){let a=await e(n,{allowFailure:!0});if(u(a.stdout,a.stderr))throw new t(`UNSUPPORTED_OPERATION`,`Android shell clipboard ${i} is not supported on this device.`);if(a.exitCode!==0)throw r(`Failed to ${i} Android clipboard text`,a);return a.stdout}function F(e){let t=e.replace(/\r\n/g,`
1
+ import{t as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{j as n,n as r,s as i}from"./sdk-android-adb.js";import{t as a}from"./timeouts.js";import{a as o,i as s,o as c,t as l}from"./android-input-ownership.js";import{i as u}from"./install-artifact.js";var d=e({dismissAndroidKeyboard:()=>v,dismissAndroidKeyboardWithAdb:()=>y,getAndroidKeyboardState:()=>g,getAndroidKeyboardStatusWithAdb:()=>_,readAndroidClipboardText:()=>A,readAndroidClipboardWithAdb:()=>j,writeAndroidClipboardText:()=>M,writeAndroidClipboardWithAdb:()=>N});const f=[`mInputShown`,`mIsInputViewShown`,`isInputViewShown`,`mDecorViewVisible`,`mWindowVisible`,`mInShowWindow`],p=new Map([[2,`number`],[3,`phone`],[4,`datetime`]]),m=new Set([32,208]),h=new Set([128,224,144]);async function g(e){return await _(i(e))}async function _(e){let t=await e([`shell`,`dumpsys`,`input_method`],{allowFailure:!0});if(t.exitCode!==0)throw r(`Failed to query Android keyboard state`,t);return b(t.stdout)}async function v(e){return await y(i(e))}async function y(e){let n=await _(e),r=n,i=0;for(;r.visible&&i<2;)await e([`shell`,`input`,`keyevent`,`111`]),i+=1,await a(120),r=await _(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 b(e){let t=T(e)??x(e),n=S(e),r=C(e,/\bpackageName=([A-Za-z0-9_.]+)\b/g),i=C(e,/\b(?:resourceId|resource-id)=([^\s,}]+)/g),a=c(e),o=l(r,i,a);return w(r,i,a),{visible:t??!1,inputType:n,type:n?k(n):void 0,inputMethodPackage:a,focusedPackage:r,focusedResourceId:i,inputOwner:o}}function x(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)!=0}function S(e){let t=C(e,/\binputType=0x([0-9a-fA-F]+)\b/gi);return t?`0x${t.toLowerCase()}`:void 0}function C(e,t){let n;for(let r of e.matchAll(t))n=r[1];return n}function w(e,t,r){r||!s(e)&&!o(t)||n({level:`warn`,phase:`android_input_ownership_fallback`,data:{focusedPackage:e,focusedResourceId:t}})}function T(e){return D(E(e,f))}function E(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 D(e){if(e.size===0)return null;let t=O(e,[`mWindowVisible`,`mDecorViewVisible`,`mInShowWindow`]);if(t!==void 0)return t;let n=e.get(`mInputShown`);return n===void 0?O(e,[`mIsInputViewShown`,`isInputViewShown`])??null:n}function O(e,t){for(let n of t){let t=e.get(n);if(t!==void 0)return t}}function k(e){let t=Number.parseInt(e.replace(/^0x/i,``),16);if(Number.isNaN(t))return`unknown`;let n=t&15,r=p.get(n);if(r)return r;if(n!==1)return`unknown`;let i=t&4080;return m.has(i)?`email`:h.has(i)?`password`:`text`}async function A(e){return await j(i(e))}async function j(e){return F(await P(e,[`shell`,`cmd`,`clipboard`,`get`,`text`],`read`))}async function M(e,t){await N(i(e),t)}async function N(e,t){await P(e,[`shell`,`cmd`,`clipboard`,`set`,`text`,t],`write`)}async function P(e,n,i){let a=await e(n,{allowFailure:!0});if(u(a.stdout,a.stderr))throw new t(`UNSUPPORTED_OPERATION`,`Android shell clipboard ${i} is not supported on this device.`);if(a.exitCode!==0)throw r(`Failed to ${i} Android clipboard text`,a);return a.stdout}function F(e){let t=e.replace(/\r\n/g,`
2
2
  `).replace(/\n$/,``),n=t.match(/^clipboard text:\s*(.*)$/i);return n?n[1]??``:t.trim().toLowerCase()===`null`?``:t}export{A as a,N as c,_ as i,y as n,j as o,g as r,M as s,d as t};
@@ -0,0 +1,9 @@
1
+ import{S as e,_ as t,c as n,u as r,v as i,w as a}from"./sdk-contracts.js";import{I as o,a as s,c,j as l,n as u,o as d,p as f,s as p,v as m}from"./sdk-android-adb.js";import{n as h,t as ee}from"./version.js";import{G as te,X as ne}from"./sdk-selectors.js";import{i as re,l as ie,r as ae}from"./gesture-plan-types.js";import{t as oe}from"./timeouts.js";import{r as se}from"./android-input-ownership.js";import"./install-artifact.js";import ce from"node:crypto";import le from"node:os";import g from"node:path";import _ from"node:fs/promises";import ue from"node:net";function v(e){if(!e)return;let t=/\[(-?\d+),(-?\d+)\]\[(-?\d+),(-?\d+)\]/.exec(e);if(!t)return;let n=Number(t[1]),r=Number(t[2]),i=Number(t[3]),a=Number(t[4]);return{x:n,y:r,width:Math.max(0,i-n),height:Math.max(0,a-r)}}function de(){let e=[],t=()=>e[e.length-1]===!0;return{open(n,r){let i=t()||re(n);return r||e.push(i),i},close(){e.pop()}}}function*fe(e){let t=/<node\b[^>]*>|<\/node>/g,n=de(),r=t.exec(e);for(;r;){let i=r[0];if(i.startsWith(`</node`))n.close();else{let e=pe(i);yield n.open(e.resourceId,i.endsWith(`/>`))?{...e,systemChrome:!0}:e}r=t.exec(e)}}function pe(e){let t=ye(e),n=v(t.bounds);return{...t,...n?{rect:n}:{}}}function me(e,t,n){let{sourceNodes:r,...i}=y(Ne(e),t,n);return i}function y(e,t,n){let r={nodes:[],sourceNodes:[],...t===void 0?{}:{maxNodes:t},maxDepth:n.depth??1/0,options:n,analysis:lt(e),interactiveDescendantMemo:new Map,truncated:!1},i=n.scope?ct(e,n.scope):null,a=i?[i]:e.children;for(let e of a)if(he(r,e,0),r.truncated)break;let o={nodes:r.nodes,sourceNodes:r.sourceNodes,analysis:r.analysis};return r.truncated?{...o,truncated:!0}:o}function he(e,t,n,r,i=!1,a=!1,o=!1){if(e.maxNodes!==void 0&&e.nodes.length>=e.maxNodes){e.truncated=!0;return}if(n>e.maxDepth)return;let s=e.options.raw?!0:$e(t,e.options,i,ve(e,t),a),c=o||re(t.identifier),l=s?ge(e,t,r,c):r,u=i||!!t.hittable,d=a||at(t.type);for(let r of t.children)if(he(e,r,n+1,l,u,d,c),e.truncated)return}function ge(e,t,n,r){let i=e.nodes.length;return e.sourceNodes.push(t),e.nodes.push({index:i,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,visibleToUser:t.visibleToUser,hittable:t.hittable,depth:_e(e.nodes,n),parentIndex:n,...t.hiddenContentAbove?{hiddenContentAbove:!0}:{},...t.hiddenContentBelow?{hiddenContentBelow:!0}:{},...r?{systemChrome:!0}:{}}),i}function _e(e,t){return t===void 0?0:(e[t]?.depth??-1)+1}function ve(e,t){let n=e.interactiveDescendantMemo.get(t);if(n!==void 0)return n;for(let n of t.children)if(n.visibleToUser!==!1&&(n.hittable||ve(e,n)))return e.interactiveDescendantMemo.set(t,!0),!0;return e.interactiveDescendantMemo.set(t,!1),!1}function ye(e){let t=be(e),n=e=>Me(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=v(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(`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 be(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=xe(e,i,r);if(!n)break;t.set(n.name,n.value),i=n.nextCursor}return t}function xe(e,t,n){if(t=Ce(e,t,n),t>=n||we(e[t]))return;let r=t;t=Se(e,t,n);let i=e.slice(r,t);if(t=Ce(e,t,n),!i||e[t]!==`=`)return;t=Ce(e,t+1,n);let a=e[t];if(!Te(a))return;let o=t+1,s=e.indexOf(a,o);if(!(s<0||s>=n))return{name:i,value:Oe(e.slice(o,s)),nextCursor:s+1}}function Se(e,t,n){for(;t<n&&!De(e[t]??``);)t+=1;return t}function Ce(e,t,n){for(;t<n&&Ee(e[t]??``);)t+=1;return t}function we(e){return e===`/`||e===`>`}function Te(e){return e===`"`||e===`'`}function Ee(e){return e===` `||e===`
2
+ `||e===`\r`||e===` `}function De(e){return e===`=`||e===`/`||e===`>`||Ee(e)}function Oe(e){let t=``,n=0;for(;n<e.length;){let r=e.indexOf(`&`,n);if(r<0){t+=e.slice(n);break}t+=e.slice(n,r);let i=e.indexOf(`;`,r+1);if(i<0){t+=e.slice(r);break}let a=e.slice(r+1,i);t+=ke(a)??e.slice(r,i+1),n=i+1}return t}function ke(e){switch(e){case`amp`:return`&`;case`lt`:return`<`;case`gt`:return`>`;case`quot`:return`"`;case`apos`:return`'`;default:return Ae(e)}}function Ae(e){if(!e.startsWith(`#`))return;let t=e[1]?.toLowerCase()===`x`?16:10,n=t===16?e.slice(2):e.slice(1);if(!n||!je(n,t))return;let r=Number.parseInt(n,t);if(Number.isFinite(r))try{return String.fromCodePoint(r)}catch{return}}function je(e,t){for(let n of e){let e=n.charCodeAt(0),r=e>=48&&e<=57;if(t===10){if(!r)return!1;continue}if(!r&&!(e>=65&&e<=70)&&!(e>=97&&e<=102))return!1}return!0}function Me(e,t){return e.get(t)??null}function Ne(e){let t={type:null,label:null,value:null,identifier:null,packageName:null,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=pe(t),o=n[n.length-1],s={type:a.className,label:a.text||a.desc,value:a.text,identifier:a.resourceId,packageName:a.packageName,rect:a.rect,enabled:a.enabled,focused:a.focused,visibleToUser:a.visibleToUser,drawingOrder:a.drawingOrder,hittable:a.clickable??a.focusable,scrollable:a.scrollable,canScrollForward:a.canScrollForward,canScrollBackward:a.canScrollBackward,windowIndex:a.windowIndex,windowType:a.windowType,windowLayer:a.windowLayer,windowActive:a.windowActive,windowFocused:a.windowFocused,windowRect:a.windowRect,depth:o.depth+1,parentIndex:void 0,children:[]};o.children.push(s),t.endsWith(`/>`)||n.push(s),i=r.exec(e)}return Pe(t),Ke(t),Fe(t,{actionableContentMemo:new WeakMap}),Ge(t),t}function Pe(e){let t=0;for(let n of e.children)n.visibleToUser!==!1&&(Pe(n),e.children[t]=n,t+=1);t<e.children.length&&(e.children.length=t)}function Fe(e,t){for(let n of e.children)Fe(n,t);if(e.children.length<2)return;let n=e.children,r=n.filter(e=>Be(e,t));r.length!==0&&(e.children=n.filter(e=>Ie(e,r)))}function Ie(e,t){return Le(e)||!Re(e,t)}function Le(e){return ze(e)&&!e.hittable&&e.children.length===0}function Re(e,t){if(e.visibleToUser===!1||e.drawingOrder===void 0||!Ue(e))return!1;for(let n of t)if(!(n===e||n.drawingOrder<=e.drawingOrder)&&We(n.rect,e.rect)>=.9)return!0;return!1}function ze(e){let t=e.identifier?.trim()??``;return!!(t&&!b(t))}function Be(e,t){return e.visibleToUser!==!1&&e.drawingOrder!==void 0&&Ue(e)&&(Ve(e)||He(e,t))}function Ve(e){if(e.visibleToUser===!1)return!1;if(e.hittable)return!0;let t=e.label?.trim()??``;if(t&&!b(t))return!0;let n=e.identifier?.trim()??``;return!!(n&&!b(n))}function He(e,t){let n=t.actionableContentMemo.get(e);if(n!==void 0)return n;let r=e.children.some(e=>e.visibleToUser!==!1&&(!!e.hittable||He(e,t)));return t.actionableContentMemo.set(e,r),r}function Ue(e){return!!(e.rect&&e.rect.width>0&&e.rect.height>0)}function We(e,t){let n=t.width*t.height;return n<=0?0:ie(e,t)/n}function Ge(e){let t=[...e.children];for(;t.length>0;){let e=t.pop();t.push(...e.children),Ze(e)&&(e.canScrollBackward&&(e.hiddenContentAbove=!0),e.canScrollForward&&(e.hiddenContentBelow=!0))}}function Ke(e){let t=e.children.filter(Je);if(t.length<2)return;let n=t.filter(e=>Ye(e)&&Xe(e));if(n.length===0)return;let r=qe(n);e.children=e.children.filter(e=>Ye(e)?Xe(e)?r===void 0||e.windowLayer===r:!1:!0)}function qe(e){let t=e.map(e=>e.windowLayer).filter(e=>e!==void 0);return t.length>0?Math.max(...t):void 0}function Je(e){return e.windowIndex!==void 0||e.windowType!==void 0}function Ye(e){return e.windowType===1}function Xe(e){return e.windowActive===!0||e.windowFocused===!0}function Ze(e){if(!e.scrollable||!ne(e.type)||`${e.type??``}`.toLowerCase().includes(`horizontalscrollview`))return!1;let t=Qe(e);return!(t&&t.horizontal>t.vertical&&t.horizontal>16)}function Qe(e){if(!e.rect||e.children.length===0)return null;let t=e.children.map(e=>e.rect).filter(e=>e!==void 0);if(t.length===0)return null;let n=Math.min(...t.map(e=>e.x)),r=Math.max(...t.map(e=>e.x+e.width)),i=Math.min(...t.map(e=>e.y)),a=Math.max(...t.map(e=>e.y+e.height));return{horizontal:Math.max(0,r-n-e.rect.width),vertical:Math.max(0,a-i-e.rect.height)}}function $e(e,t,n,r,i){if(e.visibleToUser===!1)return!1;let a=et(e);return t.interactiveOnly?tt(e,a,n,r,i):a.isStructural||a.isVisual?it(e,a,r):!0}function et(e){let t=ot(e.type),n=!!(e.label&&e.label.trim().length>0),r=!!(e.identifier&&e.identifier.trim().length>0);return{type:t,hasMeaningfulText:n&&!b(e.label??``),hasMeaningfulId:r&&!b(e.identifier??``),isStructural:st(t),isVisual:t===`imageview`||t===`imagebutton`}}function tt(e,t,n,r,i){return rt(e)?!1:e.focused||e.hittable||ne(t.type)&&r?!0:nt(t,n,r,i)}function nt(e,t,n,r){return!e.hasMeaningfulText&&!e.hasMeaningfulId||e.isVisual||e.isStructural&&!r?!1:t||n||r}function rt(e){return!!(e.rect&&(e.rect.width<=0||e.rect.height<=0))}function it(e,t,n){return e.hittable||t.hasMeaningfulText||t.hasMeaningfulId?!0:n}function at(e){if(!e)return!1;let t=ot(e);return t.includes(`recyclerview`)||t.includes(`listview`)||t.includes(`gridview`)}function ot(e){return e?e.toLowerCase():``}function st(e){let t=e.split(`.`).pop()??e;return t.includes(`layout`)||t===`viewgroup`||t===`view`}function b(e){let t=e.trim();return t?/^[\w.]+:id\/[\w.-]+$/i.test(t):!1}function ct(e,t){let n=t.toLowerCase(),r=[...e.children],i=0;for(;i<r.length;){let e=r[i++],t=e.label?.toLowerCase()??``,a=e.value?.toLowerCase()??``,o=e.identifier?.toLowerCase()??``;if(t.includes(n)||a.includes(n)||o.includes(n))return e;r.push(...e.children)}return null}function lt(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 x(e){let t={status:[],results:[],currentStatus:null,currentResult:null};for(let n of e.split(/\r?\n/))ut(n,t);return dt(t),{status:t.status,results:t.results}}function ut(e,t){if(e.startsWith(`INSTRUMENTATION_STATUS: `)){t.currentStatus??={},mt(e.slice(24),t.currentStatus);return}if(e.startsWith(`INSTRUMENTATION_STATUS_CODE: `)){ft(t);return}if(e.startsWith(`INSTRUMENTATION_RESULT: `)){t.currentResult??={},mt(e.slice(24),t.currentResult);return}e.startsWith(`INSTRUMENTATION_CODE: `)&&pt(t)}function dt(e){ft(e),pt(e)}function ft(e){e.currentStatus&&=(e.status.push(e.currentStatus),null)}function pt(e){e.currentResult&&=(e.results.push(e.currentResult),null)}function mt(e,t){let n=e.indexOf(`=`);n<0||(t[e.slice(0,n)]=e.slice(n+1))}function S(e){if(e===void 0)return;let t=Number(e);return Number.isFinite(t)?t:void 0}function C(e){if(e===`true`)return!0;if(e===`false`)return!1}function ht(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 w(e,n,r,i){if(e!==r)throw new t(`INVALID_ARGS`,`Android ${i} manifest ${n} must be "${r}".`);return r}function T(e,n,r){if(typeof e!=`string`||e.length===0)throw new t(`INVALID_ARGS`,`Android ${r} manifest ${n} is required.`);return e}function gt(e,n){let r=T(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}const E=`android-snapshot-helper-v1`,D=`uiautomator-xml`,_t={"-r":`replace`,"-t":`allowTestPackages`,"-d":`allowDowngrade`,"-g":`grantPermissions`};function vt(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:k(n.name,`name`,`android-snapshot-helper`),version:A(n.version,`version`),releaseTag:Ct(n.releaseTag),assetName:Ct(n.assetName),apkUrl:wt(n.apkUrl,`apkUrl`),sha256:St(n.sha256),checksumName:Ct(n.checksumName),packageName:A(n.packageName,`packageName`),versionCode:O(n.versionCode,`versionCode`),instrumentationRunner:A(n.instrumentationRunner,`instrumentationRunner`),minSdk:O(n.minSdk,`minSdk`),targetSdk:n.targetSdk===void 0?void 0:O(n.targetSdk,`targetSdk`),outputFormat:k(n.outputFormat,`outputFormat`,D),statusProtocol:k(n.statusProtocol,`statusProtocol`,E),installArgs:bt(n.installArgs)}}function O(e,t){return ht(e,t,`snapshot helper`)}function k(e,t,n){return w(e,t,n,`snapshot helper`)}function yt(e){return xt(bt(e.installArgs))}function bt(e){let n=Tt(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=>!Et(e));if(r)throw new t(`INVALID_ARGS`,`Android snapshot helper manifest installArgs contains unsupported install flag "${r}".`);return n}function xt(e){let n={};for(let r of e.slice(1)){let e=Dt(r);if(!e)throw new t(`INVALID_ARGS`,`Android snapshot helper manifest installArgs contains unsupported install flag "${r}".`);n[e]=!0}return n}function St(e){let n=A(e,`sha256`).trim().toLowerCase();if(n.length!==64||!Ot(n))throw new t(`INVALID_ARGS`,`Android snapshot helper manifest sha256 must be a 64-character hex string.`);return n}function A(e,n){if(typeof e!=`string`||e.trim().length===0)throw new t(`INVALID_ARGS`,`Android snapshot helper manifest ${n} is required.`);return e}function Ct(e){return typeof e==`string`&&e.trim().length>0?e:void 0}function wt(e,t){return e===null?null:A(e,t)}function Tt(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 Et(e){return Dt(e)!==void 0}function Dt(e){if(Object.hasOwn(_t,e))return _t[e]}function Ot(e){for(let t of e){let e=t.charCodeAt(0);if(!(e>=48&&e<=57)&&!(e>=97&&e<=102))return!1}return!0}async function kt(e){let n=At(e),r=await e.adb(jt(n),{allowFailure:!0,timeoutMs:n.commandTimeoutMs}),{output:i,cleanupDone:a}=await Mt(e,n,r);if(n.outputPath&&!a&&await zt(e.adb,n.outputPath),r.exitCode!==0)throw new t(`COMMAND_FAILED`,`Android snapshot helper failed`,f(r,{helper:i.metadata}));return i}function At(e){let t=j(e.timeoutMs,8e3),n=j(e.packageName,`com.callstack.agentdevice.snapshothelper`);return{waitForIdleTimeoutMs:j(e.waitForIdleTimeoutMs,500),waitForIdleQuietMs:j(e.waitForIdleQuietMs,100),timeoutMs:t,commandTimeoutMs:j(e.commandTimeoutMs,t+5e3),maxDepth:j(e.maxDepth,128),maxNodes:j(e.maxNodes,5e3),packageName:n,runner:j(e.instrumentationRunner,`${n}/.SnapshotInstrumentation`),...e.outputPath?{outputPath:e.outputPath}:{},...e.emitChunks===void 0?{}:{emitChunks:e.emitChunks}}}function j(e,t){return e===void 0?t:e}function jt(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 Mt(e,t,n){try{return{output:Bt(`${n.stdout}\n${n.stderr}`),cleanupDone:!1}}catch(r){return await Nt(e,t,n,r)}}async function Nt(e,n,r,i){if(i instanceof t&&r.exitCode!==0&&i.details?.helper)throw i;let a=await Pt(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},i)}async function Pt(e,t,n){if(!(n.exitCode!==0||!t.outputPath))return await It(e.adb,t.outputPath,Rt(`${n.stdout}\n${n.stderr}`)??Ft(t))}function Ft(e){return{outputFormat:D,waitForIdleTimeoutMs:e.waitForIdleTimeoutMs,waitForIdleQuietMs:e.waitForIdleQuietMs,timeoutMs:e.timeoutMs,maxDepth:e.maxDepth,maxNodes:e.maxNodes,transport:`instrumentation`}}async function It(e,t,n){let r;try{r=await e(Lt(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 Lt(e){return[`shell`,`sh`,`-c`,`cat "$1"; status=$?; rm -f "$1"; exit "$status"`,`agent-device-snapshot-helper-output`,e]}function Rt(e){try{return Jt(Ht(x(e).results))}catch{return null}}async function zt(e,t){try{await e([`shell`,`rm`,`-f`,t],{allowFailure:!0,timeoutMs:5e3})}catch{}}function Bt(e){let t=x(e),n=Ht(t.results);return{xml:Wt(Vt(t.status),n),metadata:{...Jt(n),transport:`instrumentation`}}}function Vt(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:M(n.chunkIndex),count:M(n.chunkCount),payloadBase64:e})}return t}function Ht(e){let n=e.find(e=>e.agentDeviceProtocol===E);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`,Ut(n),{errorType:n.errorType,helper:n});return n}function Ut(e){return e.message&&e.message!==`null`?e.message:e.errorType||`Android snapshot helper returned an error`}function Wt(e,n){if(e.length===0)throw new t(`COMMAND_FAILED`,`Android snapshot helper did not return XML chunks`,{helper:n});let r=Gt(e),i=Buffer.concat(qt(Kt(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 Gt(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 Kt(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 qt(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 Jt(e){return{helperApiVersion:e.helperApiVersion,outputFormat:D,waitForIdleTimeoutMs:M(e.waitForIdleTimeoutMs),waitForIdleQuietMs:M(e.waitForIdleQuietMs),timeoutMs:M(e.timeoutMs),maxDepth:M(e.maxDepth),maxNodes:M(e.maxNodes),rootPresent:Xt(e.rootPresent),captureMode:Yt(e.captureMode),windowCount:M(e.windowCount),nodeCount:M(e.nodeCount),truncated:Xt(e.truncated),elapsedMs:M(e.elapsedMs)}}function Yt(e){return e===`interactive-windows`||e===`active-window`?e:void 0}const M=S,Xt=C,Zt=2e3,Qt=5e3,N=new Map,$t=new Map;async function en(e){if(!xn()||!e.adbProvider?.spawn)return;let t=At(e),n=e.deviceKey??`android:default`,r=bn(n,t,e);if($t.get(n)===r)return;let i=N.get(n);if(i&&i.identity!==r&&(await F(n),i=void 0),!i)try{i=await cn({deviceKey:n,identity:r,options:e,resolved:t})}catch(e){$t.set(n,r),l({level:`warn`,phase:`android_snapshot_helper_session_disabled`,data:{deviceKey:n,reason:e instanceof Error?e.message:String(e)}});return}try{let e=i.capturedCount>0,n=await dn(i,t);return i.capturedCount+=1,{xml:n.xml,metadata:{...n.metadata,transport:`persistent-session`,sessionReused:e}}}catch(e){throw await F(n),e}}async function tn(e){let n=N.get(e.deviceKey);if(!n)return;if(!nn(n.helper,e.helper)){l({level:`warn`,phase:`android_snapshot_helper_session_touch_identity_mismatch`,data:{deviceKey:e.deviceKey,sessionHelper:n.helper,requestedHelper:e.helper}}),await F(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{let t=await L(n,i,e.timeoutMs);a=gn(t.slice(0,rn(t))),an(a,r)}catch(t){throw await F(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 nn(e,t){return e.packageName===t.packageName&&e.runner===t.runner&&P(e.helperVersion,t.helperVersion)&&P(e.helperVersionCode,t.helperVersionCode)&&P(e.sha256,t.sha256)}function P(e,t){return e===void 0||t===void 0||e===t}function rn(e){let t=e.indexOf(`
3
+
4
+ `);return t<0?e.length:t}function an(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})}async function F(e){let t=N.get(e);if(t){N.delete(e);try{await L(t,`quit ${Date.now()}`,1e3)}catch{}try{await t.process.kill(`SIGTERM`)}catch{}await ln(t.process,Zt);try{await vn(t)}catch{}l({phase:`android_snapshot_helper_session_stop`,data:{deviceKey:e,port:t.port,capturedCount:t.capturedCount,lifetimeMs:Date.now()-t.startedAtMs}})}}async function on(e){await F(I(e))}function I(e){return`${e.platform}:${e.id}`}function sn(e){return Math.min(e.commandTimeoutMs,Math.max(e.timeoutMs+1e4,3e3))}async function cn(e){let n=await Sn();await e.options.adb([`forward`,`tcp:${n}`,`tcp:${n}`],{allowFailure:!1,timeoutMs:Qt});let r=jt({...e.resolved,outputPath:void 0,emitChunks:!1}),i=r[r.length-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 un(o,1e4),N.set(e.deviceKey,s),l({phase:`android_snapshot_helper_session_ready`,data:{deviceKey:e.deviceKey,port:n,packageName:e.resolved.packageName,runner:e.resolved.runner}}),s}catch(e){await vn(s);try{o.kill(`SIGTERM`)}catch{}throw await ln(o,Zt),e}}function ln(e,t){return new Promise(n=>{let r=setTimeout(n,t);e.once(`close`,()=>{clearTimeout(r),n()}),e.once(`exit`,()=>{clearTimeout(r),n()})})}function un(e,n){return new Promise((r,i)=>{let a=``,o=setTimeout(()=>{i(new t(`COMMAND_FAILED`,`Android snapshot helper session did not become ready`,{output:a,timeoutMs:n}))},n),s=e=>{a+=e.toString(),a.includes(`agentDeviceProtocol=android-snapshot-helper-v1`)&&a.includes(`sessionReady=true`)&&(clearTimeout(o),r())};e.stdout?.on(`data`,s),e.stderr?.on(`data`,s),e.once(`exit`,(e,n)=>{clearTimeout(o),i(new t(`COMMAND_FAILED`,`Android snapshot helper session exited before ready`,{output:a,exitCode:e,signal:n}))}),e.on(`error`,e=>{clearTimeout(o),i(e)})})}async function dn(e,t){let n=`snapshot-${Date.now()}-${Math.random().toString(16).slice(2)}`,r=sn(t);return fn(await L(e,`snapshot ${n}`,r),n)}function L(e,n,r){return new Promise((i,a)=>{let o=ue.connect({host:`127.0.0.1`,port:e.port}),s=[],c=setTimeout(()=>{o.destroy(),a(new t(`COMMAND_FAILED`,`Android snapshot helper session request timed out`,{command:n,timeoutMs:r,port:e.port}))},r);o.on(`connect`,()=>{o.write(`${n}\n`)}),o.on(`data`,e=>{s.push(Buffer.from(e))}),o.on(`error`,e=>{clearTimeout(c),a(e)}),o.on(`close`,()=>{clearTimeout(c),i(Buffer.concat(s).toString(`utf8`))})})}function fn(e,t){let{headers:n,xml:r}=pn(e);return mn(n,t),hn(n,r),{xml:r,metadata:_n(n)}}function pn(e){let n=e.indexOf(`
5
+
6
+ `);if(n<0)throw new t(`COMMAND_FAILED`,`Android snapshot helper session returned malformed output`,{response:e});return{headers:gn(e.slice(0,n)),xml:e.slice(n+2)}}function mn(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})}function hn(e,n){let r=S(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 gn(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 _n(e){return{helperApiVersion:e.helperApiVersion,outputFormat:D,waitForIdleTimeoutMs:S(e.waitForIdleTimeoutMs),waitForIdleQuietMs:S(e.waitForIdleQuietMs),timeoutMs:S(e.timeoutMs),maxDepth:S(e.maxDepth),maxNodes:S(e.maxNodes),rootPresent:C(e.rootPresent),captureMode:e.captureMode===`interactive-windows`||e.captureMode===`active-window`?e.captureMode:void 0,windowCount:S(e.windowCount),nodeCount:S(e.nodeCount),truncated:C(e.truncated),elapsedMs:S(e.elapsedMs)}}async function vn(e){await e.process.stdin?.end(),await e.process.stdout?.destroy(),await e.process.stderr?.destroy(),await yn(e)}async function yn(e){await e.adb([`forward`,`--remove`,`tcp:${e.port}`],{allowFailure:!0,timeoutMs:Qt})}function bn(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 xn(){let e=process.env.AGENT_DEVICE_ANDROID_SNAPSHOT_HELPER_SESSION;return e===void 0||!/^(0|false|no|off)$/i.test(e)}function Sn(){return new Promise((e,t)=>{let n=ue.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))})})}const Cn=1e4;async function wn(e){let{adb:t,adbProvider:n,packageName:r,versionCode:i,apkPath:a,sha256:o,cache:c,deviceKey:l,installTimeoutMs:d,helperLabel:f}=e,p=`${l}\0${r}\0${i}\0${o}`;if(c.has(p))return{packageName:r,versionCode:i,installedSha256:o,installed:!1,reason:`current`};await jn(a,o,f);let m=await Tn({adb:t,adbProvider:n,packageName:r,versionCode:i,sha256:o});if(m.reason===`current`)return c.add(p),{packageName:r,versionCode:i,...m,installed:!1};let h=await s(a,{provider:n,replace:!0,allowTestPackages:!0,allowFailure:!0,timeoutMs:d});if(h.exitCode!==0)throw u(`Failed to install ${f}`,h,{packageName:r,versionCode:i,reason:m.reason});return c.add(p),{packageName:r,versionCode:i,...m,installed:!0}}async function Tn(e){let{adb:t,adbProvider:n,packageName:r,versionCode:i,sha256:a}=e,o=await On(t,r);if(o===void 0)return{reason:`missing`};if(o<i)return{installedVersionCode:o,reason:`outdated`};if(o>i)return{installedVersionCode:o,reason:`current`};try{let e=await kn(t,n,r);return{installedVersionCode:o,installedSha256:e,reason:e===a?`current`:`mismatched`}}catch{return{installedVersionCode:o,reason:`unverifiable`}}}async function En(n){let r=h(),i=g.join(ee(),`android`,n.helperDirName,`dist`),a=g.join(i,n.manifestFileName(r));try{let e=n.parseManifest(JSON.parse(await _.readFile(a,`utf8`))),t=g.join(i,e.assetName);return await _.access(t),{apkPath:t,manifest:e}}catch(r){throw new t(`UNSUPPORTED_OPERATION`,n.unavailableMessage,{manifestPath:a,error:e(r).message},r)}}function Dn(e){return async t=>await wn({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 On(e,t){let n=await e([`shell`,`cmd`,`package`,`list`,`packages`,`--show-versioncode`,t],{allowFailure:!0,timeoutMs:5e3});if(n.exitCode!==0)return;let r=RegExp(`package:${Nn(t)}(?:\\s|$).*versionCode:(\\d+)`).exec(`${n.stdout}\n${n.stderr}`);return r?Number(r[1]):void 0}async function kn(e,n,r){let i=await e([`shell`,`pm`,`path`,r],{allowFailure:!0,timeoutMs:Cn}),a=An(`${i.stdout}\n${i.stderr}`);if(i.exitCode!==0||!a)throw new t(`COMMAND_FAILED`,`Could not resolve installed Android helper APK`);let o=await _.mkdtemp(g.join(le.tmpdir(),`agent-device-helper-`)),s=g.join(o,`base.apk`);try{let e=await d(a,s,{provider:n,allowFailure:!0,timeoutMs:Cn});if(e.exitCode!==0)throw u(`Could not read installed Android helper APK`,e,{packageName:r,remotePath:a});return await Mn(s)}finally{await _.rm(o,{recursive:!0,force:!0})}}function An(e){return e.split(/\r?\n/).map(e=>e.startsWith(`package:`)?e.slice(8).trim():``).find(e=>e.endsWith(`/base.apk`))}async function jn(e,n,r){let i=await Mn(e);if(i!==n)throw new t(`COMMAND_FAILED`,`${r} APK checksum mismatch`,{apkPath:e,expectedSha256:n,actualSha256:i})}async function Mn(e){let t=ce.createHash(`sha256`);return t.update(await _.readFile(e)),t.digest(`hex`)}function Nn(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}const R=new Map;function Pn(e){let t=`${e.deviceKey}\0${e.packageName}\0${e.versionCode}\0`;for(let e of R.keys())e.startsWith(t)&&z(e)}function Fn(e,t,n,r){return e?`${e}\0${t}\0${n}\0${r}`:void 0}function In(e,t){if(!e)return;let[n,r]=e.split(`\0`),i=`${n}\0${r}\0`;for(let t of R.keys())t!==e&&t.startsWith(i)&&R.delete(t);R.set(e,t)}function z(e){e&&R.delete(e)}async function Ln(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=Fn(e.deviceKey,i,a,o),c=s?R.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 jn(n.apkPath,o,`Android snapshot helper`);let l=r===`always`?{installedVersionCode:await Bn(t,i,e.timeoutMs),reason:`forced`}:await Tn({adb:t,adbProvider:zn(e.adbProvider,t),packageName:i,versionCode:a,sha256:o}),{installedVersionCode:d}=l,f=`installedSha256`in l?l.installedSha256:void 0,p=l.reason;if(p===`current`){if(d===void 0)throw Error(`Expected installed versionCode for current Android snapshot helper`);return In(s,d),{packageName:i,versionCode:a,installedVersionCode:d,installedSha256:f,installed:!1,reason:p}}let m;try{m=await Vn(t,e.adbProvider??t,n.apkPath,yt(n.manifest),{packageName:i,timeoutMs:e.timeoutMs})}catch(e){throw z(s),Rn(e,{packageName:i,versionCode:a})}if(m.exitCode!==0)throw z(s),Rn(u(`Failed to install Android snapshot helper`,m,{packageName:i,versionCode:a}));return In(s,a),{packageName:i,versionCode:a,installedVersionCode:d,installedSha256:f,installed:!0,reason:p}}function Rn(e,t){let n=i(e,`COMMAND_FAILED`);return n.details={...t,...n.details,androidSnapshotHelperInstallFailure:!0},n}function zn(e,t){return e?typeof e==`function`?{exec:e}:e:{exec:t}}async function Bn(e,t,n){let r=await e([`shell`,`cmd`,`package`,`list`,`packages`,`--show-versioncode`,t],{allowFailure:!0,timeoutMs:n});if(r.exitCode===0)return Hn(`${r.stdout}\n${r.stderr}`,t)}async function Vn(e,t,n,r,i){let a=async()=>await s(n,{allowFailure:!0,provider:t,...r,timeoutMs:i.timeoutMs}),o=await a();if(o.exitCode===0||!Un(o))return o;let c=await e([`uninstall`,i.packageName],{allowFailure:!0,timeoutMs:i.timeoutMs}),l=await a();return l.exitCode===0?l:{...l,stderr:[l.stderr,c.stderr?`Previous uninstall stderr after INSTALL_FAILED_UPDATE_INCOMPATIBLE: ${c.stderr}`:``].filter(Boolean).join(`
7
+ `)}}function Hn(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 Un(e){return`${e.stdout}\n${e.stderr}`.includes(`INSTALL_FAILED_UPDATE_INCOMPATIBLE`)}const Wn=new Set([`com.android.permissioncontroller`,`com.google.android.permissioncontroller`,`com.google.android.packageinstaller`,`com.android.packageinstaller`]),Gn=new Set([`android`,`com.android.systemui`]),Kn=/^android:id\/(?:alertTitle|message|button[123]|parentPanel|buttonPanel|contentPanel)$/i,B=/^android:id\/button[123]$/i,qn=/(?:^|:)id\/permission_/i,Jn=/\b(?:is(?:n't| not) responding|keeps stopping|has stopped|close app|app info)\b/i,Yn=/^(?:ok|allow|allow all|while using the app|only this time|yes|continue|save|confirm|turn on|open settings)$/i,Xn=/^(?:cancel|deny|don.t allow|don’t allow|not now|no|dismiss|close|close app|later|skip)$/i;function Zn(e){if(e!==null){if(B.test(e))return`button`;if(Kn.test(e))return`content`}}function Qn(e){let t=er(e),n=t.nodes;if(n.length===0)return null;let r=ar(n),i=n.filter(e=>V(e)&&!hr(e)),a=cr(i),o=lr(i,a),s=gr(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 $n(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 er(e){let t=e.filter(e=>pr(e));if(t.length)return{nodes:t,source:`permission`};let n=ir(e);return n.length?{nodes:n,source:`system-dialog`}:{nodes:tr(e),source:`native-dialog`}}function tr(e){let t=e.filter(e=>nr(e.type??``)),n=e.filter(e=>Kn.test(e.identifier??``)),r=t.length?[...t,...n]:rr(n);if(r.length===0)return[];let i=ur(e,r);return i===void 0?r:fr(e,i)}function nr(e){return/(?:^|[.$])[^.]*Dialog$/i.test(e)}function rr(e){let t=e.some(e=>B.test(e.identifier??``)),n=e.some(e=>!B.test(e.identifier??``));return t&&n?e:[]}function ir(e){let t=e.filter(e=>mr(e));if(t.length===0)return[];let n=ur(e,t);return n===void 0?t:fr(e,n).filter(e=>e.bundleId&&Gn.has(e.bundleId))}function ar(e){let t=new Set,n=[];for(let i of e){let e=V(i);if(!e||!i.rect||!hr(i))continue;let a=e.trim().toLowerCase();if(!a||t.has(a))continue;t.add(a);let o=r(i.rect);n.push({label:e,x:o.x,y:o.y,role:or(i,e)})}return n}function or(e,t){return sr(e.identifier??``)||(Yn.test(t.trim())?`accept`:Xn.test(t.trim())?`dismiss`:`neutral`)}function sr(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 cr(e){return V(e.find(e=>/(?:^|:)id\/(?:alertTitle|permission_message)$/i.test(e.identifier??``)))||V(e[0])}function lr(e,t){let n=e.map(e=>V(e)).filter(e=>e&&e!==t);return n.length?[...new Set(n)].join(`
8
+ `):void 0}function ur(e,t){let n=t[0];if(!n)return;let r=dr(e,n.index);for(let n of t.slice(1)){let t=new Set(dr(e,n.index));for(let e=r.length-1;e>=0;--e)t.has(r[e])||r.splice(e,1)}return r[r.length-1]}function dr(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 fr(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 pr(e){let t=e.bundleId??``;return Wn.has(t)||qn.test(e.identifier??``)}function mr(e){let t=e.bundleId??``;return Gn.has(t)&&Jn.test(V(e))}function hr(e){let t=e.type??``,n=e.identifier??``;return!!(e.hittable||/\bbutton\b/i.test(t)||B.test(n)||/(?:^|:)id\/permission_(?:allow|deny)/i.test(n))}function V(e){return e?[e.label,e.value].filter(e=>typeof e==`string`&&e.trim().length>0)[0]?.trim()??``:``}function gr(e){return e.find(e=>e.bundleId)?.bundleId}const _r=new Set([`android`,`com.android.systemui`]);function vr(e,t,n={}){if(t.backend!==`android-helper`)return{outcome:`ok`};let r=Or(e,n.foregroundAppPackage);return br(r,t)?H(r,t,`empty-helper-output`,`Android snapshot helper returned no accessibility nodes`):Er(r)?{outcome:`ok`}:yr(r)?{outcome:`system-surface-only`}:xr(r)?{outcome:`ok`}:Sr(r)?H(r,t,`content-poor-app-window`,`Android snapshot helper returned insufficient foreground app content`):Cr(r)||wr(r,t)?H(r,t,`content-poor-app-window`,`Android snapshot helper returned insufficient application window content`):Tr(r)?H(r,t,`system-window-only`,`Android snapshot helper returned only non-application windows`):{outcome:`ok`}}function H(e,t,n,r){return{outcome:`unusable`,decision:Dr(e,t,n,r)}}function yr(e){return e.windowRootCount>0&&e.applicationWindowRootCount===0&&e.activeSystemSurfaceMeaningfulNodeCount>=3}function br(e,t){return e.nodeCount===0||t.nodeCount===0||t.rootPresent===!1}function xr(e){return Sr(e)&&e.inputMethodMeaningfulNodeCount>=2}function Sr(e){let t=e.foregroundAppMeaningfulNodeCount;return t===void 0?!1:t===0?e.applicationMeaningfulNodeCount<2:t<2&&e.meaningfulNodeCount>t}function Cr(e){return e.foregroundAppMeaningfulNodeCount===void 0&&e.applicationWindowRootCount>0&&e.applicationMeaningfulNodeCount<2}function wr(e,t){return e.foregroundAppMeaningfulNodeCount===void 0&&e.windowRootCount===0&&(t.windowCount??0)>1&&e.nonSystemMeaningfulNodeCount<2}function Tr(e){return e.windowRootCount>0&&e.applicationWindowRootCount===0||e.windowRootCount===0&&e.nodeCount>0&&e.systemUiNodeCount===e.nodeCount}function Er(e){return e.hasAlertButtonIdentifier&&e.hasAlertContentIdentifier}function Dr(e,t,n,r){return{reason:n,failureReason:r,diagnostics:Vr(e,t)}}function Or(e,t){let n=kr(t);for(let t of fe(e))Ar(n,t);return Lr(n)}function kr(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 Ar(e,t){e.nodeCount+=1,Br(t.packageName)&&(e.systemUiNodeCount+=1),t.visibleToUser!==!1&&jr(e,t.resourceId),Mr(e,t),Nr(e,t)}function jr(e,t){let n=Zn(t);n===`button`&&(e.hasAlertButtonIdentifier=!0),n===`content`&&(e.hasAlertContentIdentifier=!0)}function Mr(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 Nr(e,t){Rr(t)&&(e.meaningfulNodeCount+=1,Pr(e,t),Ir(e,t))}function Pr(e,t){e.currentWindowType===1&&!zr(t.packageName)&&(e.applicationMeaningfulNodeCount+=1),Fr(e)&&!ae(t)&&(e.activeSystemSurfaceMeaningfulNodeCount+=1)}function Fr(e){return e.currentWindowType!==void 0&&e.currentWindowType!==1&&e.currentWindowActiveOrFocused===!0}function Ir(e,t){zr(t.packageName)||(e.nonSystemMeaningfulNodeCount+=1),se({packageName:t.packageName,resourceId:t.resourceId})&&(e.inputMethodMeaningfulNodeCount+=1),e.foregroundAppPackage!==void 0&&t.packageName===e.foregroundAppPackage&&(e.foregroundAppMeaningfulNodeCount=(e.foregroundAppMeaningfulNodeCount??0)+1)}function Lr(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 Rr(e){return e.visibleToUser===!1?!1:U(e.text)||U(e.desc)||U(e.resourceId)}function U(e){return e!==null&&e.trim()!==``}function zr(e){return e===null||_r.has(e)}function Br(e){return e!==null&&_r.has(e)}function Vr(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}:{}}}const W=5e3,Hr=3e4;async function Ur(e,t={}){let n=c(e,t.helperAdb).exec;return(await Jr(e,t,n)).xml}async function Wr(e,t={}){let n=c(e,t.helperAdb).exec,r=await Jr(e,t,n),i=r.xml;if(!t.interactiveOnly){let e=me(i,void 0,t),n=Gr(e.truncated,r.metadata);return{...e,...Kr(n),androidSnapshot:r.metadata}}let a=Ne(i),o=y(a,void 0,t),s=Gr(o.truncated,r.metadata);t.includeHiddenContentHints!==!1&&qr({options:t,tree:a,xml:i,interactiveSnapshot:o});let{sourceNodes:l,...u}=o;return{...u,...Kr(s),androidSnapshot:r.metadata}}function Gr(e,t){return e===!0||t.helperTruncated===!0?!0:e}function Kr(e){return e===!0?{truncated:!0}:{}}function qr(e){if(di(e.interactiveSnapshot.nodes).size>0||ui(e.xml))return;let t=y(e.tree,void 0,{...e.options,interactiveOnly:!1});fi(te(n(t.nodes)),t,e.interactiveSnapshot)}async function Jr(e,t,n){let r=c(e,t.helperAdb),i=await o(`android_snapshot_helper_artifact_resolution`,async()=>await ci(t.helperArtifact??r.snapshotHelperArtifact));if(i.artifact)return await Yr(e,t,n,i.artifact);throw l({level:`error`,phase:`android_snapshot_helper_unavailable`,data:{reason:i.errorReason??`artifact_not_found`}}),li(i.errorReason)}async function Yr(e,t,n,r){let i=I(e),a=c(e,t.helperAdb),o=t.helperSessionScope!==`daemon-session`;try{let e;try{let o=await Xr(t,n,a,r,i);o.installed&&await F(i),e=Qr(await Zr({options:t,adb:n,adbProvider:a,artifact:r,helperDeviceKey:i}),r,o.reason)}catch(e){return await ei({error:e,helperDeviceKey:i,artifact:r,adb:n})}let o=vr(e.xml,e.metadata,{foregroundAppPackage:t.appBundleId});return o.outcome===`system-surface-only`?(l({phase:`android_snapshot_helper_system_surface`,data:{foregroundAppPackage:t.appBundleId}}),{xml:e.xml,metadata:{...e.metadata,systemSurfaceOnly:!0}}):o.outcome===`ok`?e:await $r({contentRecovery:o.decision,helperDeviceKey:i,artifact:r,adb:n})}finally{o&&await F(i)}}async function Xr(e,t,n,r,i){let a=await o(`android_snapshot_helper_install`,async()=>await Ln({adb:t,adbProvider:n,artifact:r,deviceKey:i,installPolicy:e.helperInstallPolicy,timeoutMs:3e4}),{packageName:r.manifest.packageName,versionCode:r.manifest.versionCode,installPolicy:e.helperInstallPolicy??`missing-or-outdated`});return l({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 Zr(t){let{options:n,adb:r,adbProvider:i,artifact:a,helperDeviceKey:s}=t,c={adb:r,adbProvider:i,deviceKey:s,helperVersion:a.manifest.version,helperVersionCode:a.manifest.versionCode,helperSha256:a.manifest.sha256,packageName:a.manifest.packageName,instrumentationRunner:a.manifest.instrumentationRunner,waitForIdleTimeoutMs:n.helperWaitForIdleTimeoutMs??500,timeoutMs:W,commandTimeoutMs:Hr};try{let e=await o(`android_snapshot_helper_session_capture`,async()=>await en(c),{packageName:a.manifest.packageName,version:a.manifest.version,timeoutMs:W});if(e)return e}catch(t){l({level:`warn`,phase:`android_snapshot_helper_session_fallback`,data:{reason:e(t).message}}),await G(r,a.manifest.packageName)}return await o(`android_snapshot_helper_capture`,async()=>await kt(c),{packageName:a.manifest.packageName,version:a.manifest.version,timeoutMs:W,commandTimeoutMs:Hr})}function Qr(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 $r(e){throw l({level:`error`,phase:`android_snapshot_helper_content_invalid`,data:{reason:e.contentRecovery.reason,failureReason:e.contentRecovery.failureReason,...e.contentRecovery.diagnostics}}),await G(e.adb,e.artifact.manifest.packageName),new t(`COMMAND_FAILED`,e.contentRecovery.failureReason,{...e.contentRecovery.diagnostics,androidSnapshotHelperFailureReason:e.contentRecovery.reason,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 ei(e){let t=ti(e.error);throw l({level:`error`,phase:`android_snapshot_helper_failed`,data:{reason:t}}),await F(e.helperDeviceKey),await G(e.adb,e.artifact.manifest.packageName),Pn({deviceKey:e.helperDeviceKey,packageName:e.artifact.manifest.packageName,versionCode:e.artifact.manifest.versionCode}),ni(e.error,t)}async function G(t,n){try{await t([`shell`,`am`,`force-stop`,n],{allowFailure:!0,timeoutMs:2e3}),await oe(150),l({level:`debug`,phase:`android_snapshot_helper_runtime_reset`,data:{packageName:n}})}catch(t){l({level:`warn`,phase:`android_snapshot_helper_runtime_reset_failed`,data:{packageName:n,error:e(t).message}})}}function ti(t){let n=e(t),r=oi(n.details?.helper);if(r&&r!==n.message)return`${n.message}: ${r}`;if(r)return r;let i=(typeof n.details?.stderr==`string`?n.details.stderr.trim():``).split(/\r?\n/).find(e=>e.trim());return i?`${n.message}: ${i}`:n.message}function ni(n,r){let i=e(n);return new t(a(i.code),`Android snapshot helper failed: ${r}`,{...i.details,...ii(i),androidSnapshotHelperFailureReason:r,hint:ri(i)},n)}function ri(e){return si(e.details?.helper,e.message)||ai(e)?`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 ii(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 ai(e){return e.details?.exitCode===137?/Android snapshot helper (failed before returning parseable output|output could not be parsed)/.test(e.message):!1}function oi(e){if(!e||typeof e!=`object`||!(`message`in e))return;let t=String(e.message).trim();return t&&t!==`null`?t:void 0}function si(e,t){if(!e||typeof e!=`object`)return!1;let n=`errorType`in e?String(e.errorType):``,r=oi(e)??t;return/TimeoutException/.test(n)||/timed out/i.test(r)}async function ci(t){if(t)return{artifact:t};let n=h(),r=g.join(ee(),`android`,`snapshot-helper`,`dist`),i=g.join(r,`agent-device-android-snapshot-helper-${n}.manifest.json`);try{await _.access(i)}catch{return{}}try{let e=vt(JSON.parse(await _.readFile(i,`utf8`))),t=g.join(r,e.assetName??`agent-device-android-snapshot-helper-${e.version}.apk`);return await _.access(t),{artifact:{apkPath:t,manifest:e}}}catch(t){return{errorReason:e(t).message}}}function li(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 ui(e){return e.includes(` can-scroll-forward=`)||e.includes(` can-scroll-backward=`)}function di(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 fi(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))}}const K=`IME helper`,pi=`android-ime-helper-v1`;async function mi(){return await En({helperDirName:`ime-helper`,manifestFileName:e=>`agent-device-android-ime-helper-${e}.manifest.json`,parseManifest:hi,unavailableMessage:`Android test IME text entry requires the bundled Android IME helper artifact, but it was not found or could not be read`})}function hi(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:w(n.name,`name`,`android-ime-helper`,K),version:T(n.version,`version`,K),assetName:T(n.assetName,`assetName`,K),sha256:gt(n.sha256,K),packageName:w(n.packageName,`packageName`,`com.callstack.agentdevice.imehelper`,K),versionCode:ht(n.versionCode,`versionCode`,K),serviceComponent:w(n.serviceComponent,`serviceComponent`,`com.callstack.agentdevice.imehelper/.TestInputMethodService`,K),broadcastProtocol:w(n.broadcastProtocol,`broadcastProtocol`,pi,K)}}const gi=Dn({cache:new Set,installTimeoutMs:3e4,helperLabel:`Android IME helper`});function q(e){return`${e.platform}:${e.id}`}async function _i(e,t,n){await yi(e,t,`com.callstack.agentdevice.imehelper.ACTION_INPUT_TEXT_B64`,{text:Buffer.from(n,`utf8`).toString(`base64`)})}async function vi(e,t){await yi(e,t,`com.callstack.agentdevice.imehelper.ACTION_CLEAR_TEXT`,{})}async function yi(e,t,n,r){let i=[`shell`,`am`,`broadcast`,`-p`,t,`-a`,n];i.push(`--es`,`protocol`,pi);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 u(`Android IME helper broadcast failed`,a,{action:n,packageName:t})}const J=`agent_device_ime_helper_previous_ime`,Y=`secure`,bi=`default_input_method`,X=new Set;function xi(e){return X.has(q(e))}function Z(e){return g.join(e,`android-test-ime-pending`)}function Si(e,t){return g.join(Z(e),t.replace(/[^a-zA-Z0-9._-]/g,`_`))}async function Ci(t,n){try{await _.mkdir(Z(t),{recursive:!0}),await _.writeFile(Si(t,n),n)}catch(r){l({level:`debug`,phase:`android_test_ime_marker_write_failed`,data:{stateDir:t,serial:n,error:e(r).message}})}}async function Q(e,t){await _.rm(Si(e,t),{force:!0}).catch(()=>{})}async function wi(e){let t;try{t=await _.readdir(Z(e))}catch{return[]}let n=[];for(let r of t)try{let t=(await _.readFile(g.join(Z(e),r),`utf8`)).trim();t&&n.push(t)}catch{}return n}async function Ti(e,t={}){let n=p(e),r=c(e),i=await mi(),{manifest:a}=i,o=q(e);await gi({adb:n,adbProvider:r,artifact:i,deviceKey:o});let s=await $(n);if(s===a.serviceComponent)return X.add(o),t.stateDir&&await Ci(t.stateDir,e.id),{activated:!1,alreadyActive:!0,previousIme:await Ai(n),helperServiceComponent:a.serviceComponent,helperPackageName:a.packageName};if(X.add(o),!await ji(n,s))return X.delete(o),l({level:`warn`,phase:`android_test_ime_persist_failed`,data:{device:e.id,previousIme:s}}),{activated:!1,alreadyActive:!1,persistFailed:!0,helperServiceComponent:a.serviceComponent,helperPackageName:a.packageName};t.stateDir&&await Ci(t.stateDir,e.id),await n([`shell`,`ime`,`enable`,a.serviceComponent],{allowFailure:!0,timeoutMs:1e4});let u=await n([`shell`,`ime`,`set`,a.serviceComponent],{allowFailure:!0,timeoutMs:1e4}),d=await $(n);return d===a.serviceComponent?(l({phase:`android_test_ime_activated`,data:{device:e.id,previousIme:s}}),{activated:!0,alreadyActive:!1,previousIme:s,helperServiceComponent:a.serviceComponent,helperPackageName:a.packageName}):(X.delete(o),await Mi(n).catch(()=>{}),t.stateDir&&await Q(t.stateDir,e.id),l({level:`warn`,phase:`android_test_ime_activate_failed`,data:{device:e.id,activeIme:d,stderr:u.stderr.trim()}}),{activated:!1,alreadyActive:!1,helperServiceComponent:a.serviceComponent,helperPackageName:a.packageName})}async function Ei(e,t={}){let n=q(e);if(!X.has(n))return{restored:!1,reason:`no-record`};X.delete(n);let r=await Oi(p(e),e);return t.stateDir&&Di(r.reason)&&await Q(t.stateDir,e.id),r}function Di(e){return e===`ok`||e===`helper-not-active`||e===`no-record`}async function Oi(e,t){let n=t.id;if(X.has(q(t)))return{restored:!1,reason:`owned-by-live-session`};let r=await Ai(e);if(!r)return{restored:!1,reason:`no-record`};let i=await $(e);if(i!==`com.callstack.agentdevice.imehelper/.TestInputMethodService`)return l({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 $(e);return a===r?(await Mi(e).catch(()=>{}),l({phase:`android_test_ime_restored`,data:{device:n,previousIme:r}}),{restored:!0,previousIme:r,reason:`ok`}):(l({level:`warn`,phase:`android_test_ime_restore_failed`,data:{device:n,previousIme:r,afterIme:a}}),{restored:!1,previousIme:r,reason:`set-failed`})}async function ki(t){let n=await wi(t.stateDir);if(n.length===0)return;let r;try{r=new Set(await t.listSerials())}catch(t){l({level:`debug`,phase:`android_test_ime_startup_scan_failed`,data:{error:e(t).message}});return}for(let i of n){if(!r.has(i))continue;let n={platform:`android`,id:i,name:i,kind:i.startsWith(`emulator-`)?`emulator`:`device`,booted:!0};try{let e=await Oi(p(n),n);e.restored&&l({level:`warn`,phase:`android_test_ime_orphan_restored`,data:{device:i,previousIme:e.previousIme}}),Di(e.reason)&&await Q(t.stateDir,i)}catch(t){l({level:`debug`,phase:`android_test_ime_orphan_restore_failed`,data:{device:i,error:e(t).message}})}}}async function $(e){let t=await e([`shell`,`settings`,`get`,Y,bi],{allowFailure:!0,timeoutMs:5e3});return Ni(t.exitCode===0?t.stdout:``)}async function Ai(e){let t=await e([`shell`,`settings`,`get`,Y,J],{allowFailure:!0,timeoutMs:5e3});return Ni(t.exitCode===0?t.stdout:``)||void 0}async function ji(e,t){return(await e([`shell`,`settings`,`put`,Y,J,t],{allowFailure:!0,timeoutMs:5e3})).exitCode===0?await Ai(e)===t:!1}async function Mi(e){await e([`shell`,`settings`,`delete`,Y,J],{allowFailure:!0,timeoutMs:5e3})}function Ni(e){let t=e.trim();return!t||t===`null`?``:t}async function Pi(){try{return(await m(`adb`,[`devices`],{timeoutMs:5e3})).stdout.split(`
9
+ `).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 Fi={previousIme:J,defaultInputMethod:bi},Ii=`limrun`,Li=Ii;function Ri(e){if(e===`ios-instance`)return`ios`;if(e===`android-instance`)return`android`}function zi(e,t,n){return{platform:e===`ios`?`apple`:`android`,...e===`ios`?{appleOs:`ios`}:{},id:Vi(e,t.leaseId),name:`Limrun ${e} ${n.slice(0,8)}`,kind:e===`ios`?`simulator`:`emulator`,target:`mobile`,booted:!0}}function Bi(e){let[t,n,r]=e.split(`:`);if(t===Li&&!(n!==`ios`&&n!==`android`)&&r)return{platform:n,leaseId:r}}function Vi(e,t){return`${Li}:${e}:${t}`}export{v as A,F as C,x as D,E,S as O,tn as S,vt as T,$n as _,Fi as a,En as b,Pi as c,ki as d,vi as f,Wr as g,Ur as h,Ri as i,fe as k,$ as l,_i as m,zi as n,Ti as o,mi as p,Bi as r,xi as s,Ii as t,Ei as u,Qn as v,on as w,I as x,Ln as y};
@@ -1 +1 @@
1
- import{_ as e}from"./sdk-contracts.js";import{s as t,y as n}from"./sdk-device.js";import{o as r}from"./boot-diagnostics.js";import{j as i}from"./runner-disposal.js";import{a,r as o}from"./tool-provider.js";import{r as s}from"./simulator.js";import{buildHostMacDevice as c}from"./devices.js";import{promises as l}from"node:fs";import u from"node:os";import d from"node:path";const f=/^(iphone|ipad|ipod|appletv|realitydevice)/i,p=/ipad/i,m=/\b(apple vision|vision pro|xros|visionos|realitydevice)\b/i,h=/\b(iphone|ipad|ipod)\b/i,g=/^appletv/i,_=[`apple tv`,`appletv`,`tvos`],v=/^==\s*(.+?)\s*==$/,y=/^(?<name>.+?)\s+\[(?<id>[^[\]]+)\]\s*$/;function b(e){return(e??``).trim().toLowerCase()}function x(e){return b(e)}function S(e){return b(e.hardwareProperties?.platform)}function C(e){return e.includes(`tvos`)}function w(e){return e.includes(`xros`)||e.includes(`visionos`)}function T(e){return C(x(e))?`tv`:`mobile`}function E(e){let t=x(e);return t.includes(`ios`)||t.includes(`tvos`)||t.includes(`xros`)||t.includes(`visionos`)}function D(e){let t=b(e);return _.some(e=>t.includes(e))}function O(e){return h.test(e.trim())}function k(e){return D(e)?`tv`:O(e)||m.test(e)?`mobile`:null}function A(e,t){return e===`tv`?`tvos`:t.some(e=>m.test(e))?`visionos`:t.some(e=>p.test(e))?`ipados`:`ios`}function j(e){return f.test(e.trim())}function M(e){return g.test(e.trim())}function N(e){return[e.name??``,e.deviceProperties?.name??``,e.deviceProperties?.deviceType??``]}function P(e){return e.hardwareProperties?.productType??e.deviceProperties?.productType??``}function F(e){return C(S(e))||M(P(e))||N(e).some(D)?`tv`:`mobile`}function I(e){let t=S(e);return t.includes(`ios`)||t.includes(`tvos`)||w(t)||j(P(e))?!0:N(e).some(D)}async function L(e={}){let t=r(e.simulatorSetPath),o=e.target,s;try{s=await a(i([`list`,`devices`,`-j`],{simulatorSetPath:t}))}catch{return null}let c;try{c=JSON.parse(s.stdout)}catch{return null}return n(R(c,t)).find(e=>!o||e.target===o)??null}function R(e,t){let n=[];for(let[r,i]of Object.entries(e.devices))if(E(r))for(let e of i){if(!e.isAvailable)continue;let i=T(r),a={platform:`apple`,id:e.udid,name:e.name,kind:`simulator`,target:i,appleOs:A(i,[e.deviceTypeIdentifier??``,e.name]),booted:e.state===`Booted`,...t?{simulatorSetPath:t}:{}};a.booted&&s(a),n.push(a)}return n}function z(e){let t=[];for(let n of e.result?.devices??[]){if(!I(n))continue;let e=n.hardwareProperties?.udid??n.identifier??``,r=n.name??n.deviceProperties?.name??e;if(!e)continue;let i=F(n);t.push({platform:`apple`,id:e,name:r,kind:`device`,target:i,appleOs:A(i,[P(n),...N(n)]),booted:!0})}return t}function B(e){let t=[],n=null;for(let r of e.split(/\r?\n/)){let e=r.trim();if(!e)continue;let i=v.exec(e);if(i){n=i[1]?.trim()??null;continue}if(n!==`Devices`)continue;let a=y.exec(e),o=a?.groups?.id?.trim()??``,s=a?.groups?.name?.trim()??``;if(!o||!s)continue;let c=k(s);c&&t.push({platform:`apple`,id:o,name:s,kind:`device`,target:c,appleOs:A(c,[s]),booted:!0})}return t}function V(e,t){let n=new Set(e.map(e=>e.id)),r=[...e];for(let e of t)n.has(e.id)||(n.add(e.id),r.push(e));return r}async function H(){let e=null;try{if(e=d.join(u.tmpdir(),`agent-device-devicectl-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),(await a([`devicectl`,`list`,`devices`,`--json-output`,e],{allowFailure:!0,timeoutMs:8e3})).exitCode!==0)return[];let t=await l.readFile(e,`utf8`);return z(JSON.parse(t))}catch{return[]}finally{e&&await l.rm(e,{force:!0}).catch(()=>{})}}async function U(){try{let e=await a([`xctrace`,`list`,`devices`],{allowFailure:!0});return e.exitCode===0?B(e.stdout):[]}catch{return[]}}async function W(s={}){if(process.platform!==`darwin`)throw new e(`UNSUPPORTED_PLATFORM`,`Apple tools are only available on macOS`);if(!await o().whichCommand(`xcrun`))throw new e(`TOOL_MISSING`,`xcrun not found in PATH`);let l=r(s.simulatorSetPath),u=await a(i([`list`,`devices`,`-j`],{simulatorSetPath:l})),d=[];try{d=R(JSON.parse(u.stdout),l)}catch(t){throw new e(`COMMAND_FAILED`,`Failed to parse simctl devices JSON`,void 0,t)}if(d.push(c()),s.udid&&d.some(e=>t(e)&&e.id===s.udid))return d;if(l)return n(d);let[f,p]=await Promise.all([H(),U()]);return d=V(d,f),n(V(d,p))}export{L as findBootableIosSimulator,W as listAppleDevices};
1
+ import{_ as e}from"./sdk-contracts.js";import{b as t,s as n}from"./sdk-device.js";import{o as r}from"./boot-diagnostics.js";import{a as i,r as a}from"./tool-provider.js";import{I as o}from"./physical-device-control.js";import{r as s}from"./simulator.js";import{buildHostMacDevice as c}from"./devices.js";import{promises as l}from"node:fs";import u from"node:os";import d from"node:path";const f=/^(iphone|ipad|ipod|appletv|realitydevice)/i,p=/ipad/i,m=/\b(apple vision|vision pro|xros|visionos|realitydevice)\b/i,h=/\b(iphone|ipad|ipod)\b/i,g=/^appletv/i,_=[`apple tv`,`appletv`,`tvos`],v=/^==\s*(.+?)\s*==$/,y=/^(?<name>.+?)\s+(?:\[(?<idBracket>[^[\]]+)\]|\((?<osVersion>[^)]+)\)\s+\((?<idParen>[^)]+)\))\s*$/;function b(e){return(e??``).trim().toLowerCase()}function x(e){return b(e)}function S(e){return b(e.hardwareProperties?.platform)}function C(e){return e.includes(`tvos`)}function w(e){return e.includes(`xros`)||e.includes(`visionos`)}function T(e){return C(x(e))?`tv`:`mobile`}function E(e){let t=x(e);return t.includes(`ios`)||t.includes(`tvos`)||t.includes(`xros`)||t.includes(`visionos`)}function D(e){let t=b(e);return _.some(e=>t.includes(e))}function O(e){return h.test(e.trim())}function k(e){return D(e)?`tv`:O(e)||m.test(e)?`mobile`:null}function A(e,t){return e===`tv`?`tvos`:t.some(e=>m.test(e))?`visionos`:t.some(e=>p.test(e))?`ipados`:`ios`}function j(e){return f.test(e.trim())}function M(e){return g.test(e.trim())}function N(e){return[e.name??``,e.deviceProperties?.name??``,e.deviceProperties?.deviceType??``]}function P(e){return e.hardwareProperties?.productType??e.deviceProperties?.productType??``}function F(e){return C(S(e))||M(P(e))||N(e).some(D)?`tv`:`mobile`}function I(e){let t=S(e);return t.includes(`ios`)||t.includes(`tvos`)||w(t)||j(P(e))?!0:N(e).some(D)}async function L(e={}){let n=r(e.simulatorSetPath),a=e.target,s;try{s=await i(o([`list`,`devices`,`-j`],{simulatorSetPath:n}))}catch{return null}let c;try{c=JSON.parse(s.stdout)}catch{return null}return t(R(c,n)).find(e=>!a||e.target===a)??null}function R(e,t){let n=[];for(let[r,i]of Object.entries(e.devices))if(E(r))for(let e of i){if(!e.isAvailable)continue;let i=T(r),a={platform:`apple`,id:e.udid,name:e.name,kind:`simulator`,target:i,appleOs:A(i,[e.deviceTypeIdentifier??``,e.name]),booted:e.state===`Booted`,...t?{simulatorSetPath:t}:{}};a.booted&&s(a),n.push(a)}return n}function z(e){let t=[];for(let n of e.result?.devices??[]){if(!I(n))continue;let e=n.hardwareProperties?.udid??n.identifier??``,r=n.name??n.deviceProperties?.name??e;if(!e)continue;let i=F(n);t.push({platform:`apple`,id:e,name:r,kind:`device`,target:i,appleOs:A(i,[P(n),...N(n)]),iosPhysicalDeviceBackend:`coredevice`,booted:!0})}return t}function B(e){let t=y.exec(e);if(!t?.groups)return null;let n=t.groups.name?.trim()??``,r=t.groups.idBracket?.trim()??t.groups.idParen?.trim()??``,i=t.groups.osVersion?.trim();return!n||!r?null:{name:n,id:r,osVersion:i}}function V(e,t,n){let r=k(e);return r?{platform:`apple`,id:t,name:e,kind:`device`,target:r,appleOs:A(r,n?[e,n]:[e]),iosPhysicalDeviceBackend:`xctest`,booted:!0}:null}function H(e){let t=[],n=null;for(let r of e.split(/\r?\n/)){let e=r.trim();if(!e)continue;let i=v.exec(e);if(i){n=i[1]?.trim()??null;continue}if(n!==`Devices`)continue;let a=B(e);if(!a)continue;let o=V(a.name,a.id,a.osVersion);o&&t.push(o)}return t}function U(e,t){let n=new Set(e.map(e=>e.id)),r=[...e];for(let e of t)n.has(e.id)||(n.add(e.id),r.push(e));return r}async function W(){let e=null;try{if(e=d.join(u.tmpdir(),`agent-device-devicectl-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),(await i([`devicectl`,`list`,`devices`,`--json-output`,e],{allowFailure:!0,timeoutMs:8e3})).exitCode!==0)return[];let t=await l.readFile(e,`utf8`);return z(JSON.parse(t))}catch{return[]}finally{e&&await l.rm(e,{force:!0}).catch(()=>{})}}async function G(){try{let e=await i([`xctrace`,`list`,`devices`],{allowFailure:!0});return e.exitCode===0?H(e.stdout):[]}catch{return[]}}async function K(s={}){if(process.platform!==`darwin`)throw new e(`UNSUPPORTED_PLATFORM`,`Apple tools are only available on macOS`);if(!await a().whichCommand(`xcrun`))throw new e(`TOOL_MISSING`,`xcrun not found in PATH`);let l=r(s.simulatorSetPath),u=await i(o([`list`,`devices`,`-j`],{simulatorSetPath:l})),d=[];try{d=R(JSON.parse(u.stdout),l)}catch(t){throw new e(`COMMAND_FAILED`,`Failed to parse simctl devices JSON`,void 0,t)}if(d.push(c()),s.udid&&d.some(e=>n(e)&&e.id===s.udid))return d;if(l)return t(d);let[f,p]=await Promise.all([W(),G()]);return d=U(d,f),t(U(d,p))}export{L as findBootableIosSimulator,K as listAppleDevices};
@@ -0,0 +1 @@
1
+ import{_ as e}from"./sdk-contracts.js";import{h as t}from"./sdk-android-adb.js";import{t as n}from"./tool-provider3.js";const r=`VirtualDevice`;async function i(){let r=n();if(!await r.isAvailable())throw new e(`TOOL_MISSING`,`Vega CLI not found in PATH`,{hint:`Install Vega Developer Tools, source ~/vega/env, and retry devices.`});let i=t(await r.listDevices({allowFailure:!0,timeoutMs:1e4}),`Failed to list Vega devices`),o=a(i.stdout),c=s(i.stdout);if(o.length===0&&c.length>0)throw new e(`DEVICE_NOT_FOUND`,`Vega CLI found devices, but no supported Vega Virtual Device is running.`,{listedSerials:c,hint:`Start the Vega Virtual Device, then retry with --platform vega --target tv.`});return o}function a(e){return s(e).some(o)?[{platform:`vega`,id:r,name:`Vega Virtual Device (${r})`,kind:`emulator`,target:`tv`,booted:!0}]:[]}function o(e){return e.toLowerCase()===`virtualdevice`}function s(e){let t=new Set;for(let n of e.split(/\r?\n/)){let e=/^\s*([^\s:]+)\s*:\s*\S/.exec(n)?.[1]?.trim();e&&t.add(e)}return[...t]}export{i as listVegaDevices,a as parseVegaDeviceList};
package/dist/src/find.js CHANGED
@@ -1 +1 @@
1
- import{u as e}from"./sdk-contracts.js";import{C as t,D as n,E as r,w as i}from"./sdk-batch.js";import{K as a,Kn as o,q as s,qn as c}from"./tv-remote.js";import"./snapshot-diagnostics.js";import{D as l,m as u}from"./sdk-selectors.js";import{t as d}from"./snapshot-quality.js";import{r as f}from"./android-input-method-overlays.js";import{c as p,n as m,s as h,t as g}from"./context.js";import{$t as _,h as v,un as y}from"./internal/daemon.js";import{a as b,t as x,w as S}from"./selector-runtime.js";async function C(e){let{req:t,sessionName:a,logPath:o,sessionStore:s,invoke:c}=e,l=t.command;if(l!==`find`)return null;let u=t.positionals??[];if(u.length===0)return h(`INVALID_ARGS`,`find requires a locator or text`);let{locator:f,query:m,action:g,value:_}=r(u);if(!m)return h(`INVALID_ARGS`,`find requires a value`);if(t.flags?.findFirst&&t.flags?.findLast)return h(`INVALID_ARGS`,`find accepts only one of --first or --last`);if(t.flags?.record&&!i(g))return h(`INVALID_ARGS`,`find ${g} is a mutating action and is always recorded; --record only applies to a read-only find (exists, wait, get text, get attrs).`);let v=await x({req:t,sessionName:a,logPath:o,sessionStore:s});if(v)return v;let y=s.get(a);if(!y)return p();let b=y.device,C=n(f,m),O=T({device:b,session:y,req:t,logPath:o,locator:f,query:m,sessionStore:s,sessionName:a}),k={req:t,sessionName:a,logPath:o,sessionStore:s,invoke:c,session:y,device:b,command:l,locator:f,query:m,publicFlags:W(t.flags)},A=await O();if(d(A.snapshotQuality))return E(A.snapshotQuality);let{nodes:j}=A,M=D({nodes:j,locator:f,query:m,selectorChain:C,flags:t.flags,platform:b.platform});if(!M.ok)return S(M.response,A);let N=M.node,F=P(j,N),I=await w(k,{node:N,resolvedNode:F,ref:`@${F.ref}`,nodes:j,actionFlags:{...t.flags??{},noRecord:!0}},g,_);return I&&S(I,A)}async function w(e,t,n,r){let i={click:()=>L(e,t),fill:()=>R(e,t,r),focus:()=>z(e,t),type:()=>B(e,t,r)}[n];return i?await i():null}function T(e){let{device:t,session:n,req:r,logPath:i,locator:a,query:o}=e,{sessionStore:s,sessionName:c}=e,l=b({device:t,session:n,sessionStore:s,sessionName:c,req:r,logPath:i});return async()=>{let{snapshot:e}=await l.capture({flags:{...r.flags,snapshotInteractiveOnly:!0},recovery:{legacyIosSparse:{query:o,shouldScope:K(a)},sparseVerdictQueryScope:{query:o,shouldScope:K(a)}}});return{nodes:e.nodes,snapshotQuality:e.snapshotQuality,systemSurfaceOnly:e.systemSurfaceOnly}}}function E(e){return h(`COMMAND_FAILED`,`find could not read the current accessibility tree`,{reason:e.reason,hint:`The snapshot quality verdict is sparse. Use screenshot as visual truth, navigate with coordinates if needed, then retry find after reaching a readable screen.`})}function D(e){let{nodes:n,locator:r,query:i,selectorChain:a,flags:o,platform:s}=e,c=n.filter(e=>!F(e,n[0]));if(a){let e=u(c,a,{platform:s,requireRect:!0,requireUnique:!1});return e?{ok:!0,node:e.node}:{ok:!1,response:h(`COMMAND_FAILED`,`find did not match any element`)}}let l=t(c,r,i,{requireRect:!0});if(l.matches=k(l.matches,n),l.matches.length>1){let e=O(l.matches,o);if(!e)return{ok:!1,response:G(l.matches,r,i)};l.matches=e}let d=l.matches[0]??null;return d?{ok:!0,node:d}:{ok:!1,response:h(`COMMAND_FAILED`,`find did not match any element`)}}function O(e,t){return t?.findFirst?[e[0]]:t?.findLast?[e[e.length-1]]:null}function k(t,n){let r=n[0]?.rect;if(!r)return t;let i=t.filter(t=>{if(!t.rect)return!1;let n=e(t.rect);return n.x>=r.x&&n.x<=r.x+r.width&&n.y>=r.y&&n.y<=r.y+r.height});return A(i.length>0?i:t,n)}function A(e,t){return e.length<2?e:e.map((e,n)=>({node:e,index:n,score:j(e,t)})).sort((e,t)=>t.score===e.score?N(e.node)-N(t.node)||e.index-t.index:t.score-e.score).map(e=>e.node)}function j(e,t){let n=s(t,e);if(n.reason===`covered`)return 0;let r=M(n,t[0]);return r>0?r:e.hittable&&e.rect&&!F(e,t[0])?3:+!!e.rect}function M(e,t){return e.node.rect?e.reason===`semantic-target`||e.reason===`same-rect-descendant`?4:e.reason===`hittable-ancestor`&&!F(e.node,t)?2:0:0}function N(e){return e.rect?e.rect.width*e.rect.height:1/0}function P(e,t){let n=a(e,t);return F(n,e[0])&&t.rect?t:n}function F(e,t){if(!t?.rect||!e.rect)return!1;let n=e.type?.toLowerCase()??``;return!n.includes(`application`)&&!n.includes(`window`)?!1:I(e.rect,t.rect)}function I(e,t){return e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height}async function L(t,n){let{req:r,sessionName:i,sessionStore:a,session:s,invoke:l,command:u,locator:d,query:f,publicFlags:p}=t,m=await l({token:r.token,session:i,command:`click`,positionals:[n.ref],flags:n.actionFlags,internal:{findResolvedTarget:!0}});if(!m.ok)return m;let h=n.resolvedNode.rect?e(n.resolvedNode.rect):n.node.rect?e(n.node.rect):null,g={ref:n.ref,locator:d,query:f};h&&(g.x=h.x,g.y=h.y);let _=o(m.data)??`Tapped ${n.ref}${h?` (${h.x}, ${h.y})`:``}`;return Object.assign(g,c(_)),v(a,s,r,u,{ref:n.ref,action:`click`,locator:d,query:f},{flags:p}),{ok:!0,data:g}}async function R(e,t,n){let{req:r,sessionName:i,sessionStore:a,session:o,invoke:s,command:c,publicFlags:l}=e;if(!n)return h(`INVALID_ARGS`,`find fill requires text`);let u=await s({token:r.token,session:i,command:`fill`,positionals:[t.ref,n],flags:t.actionFlags,internal:{findResolvedTarget:!0}});return u.ok&&v(a,o,r,c,{ref:t.ref,action:`fill`},{flags:l}),u}async function z(e,t){let n=await V(e,t);return n.ok&&U(e,t,`focus`),n}async function B(e,t,n){let{req:r,device:i,logPath:a,session:o}=e;if(!n)return h(`INVALID_ARGS`,`find type requires text`);let s=await V(e,t);if(!s.ok)return s;_(o);let c=await m(i,`type`,[n],r.flags?.out,{...g(a,r.flags,o.appBundleId,o.trace?.outPath)});return U(e,t,`type`),{ok:!0,data:c??{ref:t.ref}}}async function V(t,n){let{req:r,device:i,logPath:a,session:o}=t,s=H(n,`be focused`);if(s)return s;let c=n.resolvedNode.rect?e(n.resolvedNode.rect):null;return c?(_(o),{ok:!0,data:await m(i,`focus`,[String(c.x),String(c.y)],r.flags?.out,{...g(a,r.flags,o.appBundleId,o.trace?.outPath)})??{ref:n.ref}}):h(`COMMAND_FAILED`,`matched element has no bounds`)}function H(e,t){let n=[e.resolvedNode,e.node].find(f);return n?h(`COMMAND_FAILED`,`Matched element ${e.ref} is covered by another visible element and cannot ${t} safely`,{ref:`@${n.ref}`,interactionBlocked:n.interactionBlocked,hint:`Use a different visible target, scroll it clear of the overlay, or inspect with snapshot/screenshot before retrying.`}):null}function U(e,t,n){let{req:r,sessionStore:i,session:a,command:o,publicFlags:s}=e;v(i,a,r,o,{ref:t.ref,action:n},{flags:s})}function W(e){return{...y(e)??{}}}function G(e,t,n){let r=e.slice(0,8).map(e=>{let t=l(e)||e.label||e.identifier||e.type||``;return`@${e.ref}${t?`(${t})`:``}`});return h(`AMBIGUOUS_MATCH`,`find matched ${e.length} elements for ${t} "${n}". Use a more specific locator or selector.`,{locator:t,query:n,matches:e.length,candidates:r})}function K(e){return e!==`role`}export{C as handleFindCommands};
1
+ import{u as e}from"./sdk-contracts.js";import{H as t,U as n,W as r,q as i}from"./sdk-batch-runner.js";import{R as a,_n as o,vn as s,z as c}from"./recording-export-quality.js";import"./snapshot-diagnostics.js";import{M as l,h as u}from"./sdk-selectors.js";import{_ as d}from"./gesture-plan-types.js";import{r as f}from"./android-input-method-overlays.js";import{c as p,n as m,s as h,t as g}from"./context.js";import{Ft as _,Kt as v,h as y}from"./internal/daemon.js";import{a as b,t as x,w as S}from"./selector-runtime.js";async function C(e){let{req:n,sessionName:a,logPath:o,sessionStore:s,invoke:c}=e,l=n.command;if(l!==`find`)return null;let u=t(n.positionals??[],n.flags);if(!u.ok)return h(u.code,u.message);let{locator:f,query:m,action:g,value:_}=u.parsed;if(n.flags?.record&&!r(g))return h(`INVALID_ARGS`,`find ${g} is a mutating action and is always recorded; --record only applies to a read-only find (exists, wait, get text, get attrs).`);let v=await x({req:n,sessionName:a,logPath:o,sessionStore:s});if(v)return v;let y=s.get(a);if(!y)return p();let b=y.device,C=i(f,m),O=T({device:b,session:y,req:n,logPath:o,locator:f,query:m,sessionStore:s,sessionName:a}),k={req:n,sessionName:a,logPath:o,sessionStore:s,invoke:c,session:y,device:b,command:l,locator:f,query:m,publicFlags:W(n.flags)},A=await O();if(d(A.snapshotQuality))return E(A.snapshotQuality);let{nodes:j}=A,M=D({nodes:j,locator:f,query:m,selectorChain:C,flags:n.flags,platform:b.platform});if(!M.ok)return S(M.response,A);let N=M.node,F=P(j,N),I=await w(k,{node:N,resolvedNode:F,ref:`@${F.ref}`,nodes:j,actionFlags:{...n.flags??{},noRecord:!0}},g,_);return I&&S(I,A)}async function w(e,t,n,r){let i={click:()=>L(e,t),fill:()=>R(e,t,r),focus:()=>z(e,t),type:()=>B(e,t,r)}[n];return i?await i():null}function T(e){let{device:t,session:n,req:r,logPath:i,locator:a,query:o}=e,{sessionStore:s,sessionName:c}=e,l=b({device:t,session:n,sessionStore:s,sessionName:c,req:r,logPath:i});return async()=>{let{snapshot:e}=await l.capture({flags:{...r.flags,snapshotInteractiveOnly:!0},recovery:{legacyIosSparse:{query:o,shouldScope:K(a)},sparseVerdictQueryScope:{query:o,shouldScope:K(a)}}});return{nodes:e.nodes,snapshotQuality:e.snapshotQuality,systemSurfaceOnly:e.systemSurfaceOnly}}}function E(e){return h(`COMMAND_FAILED`,`find could not read the current accessibility tree`,{reason:e.reason,hint:`The snapshot quality verdict is sparse. Use screenshot as visual truth, navigate with coordinates if needed, then retry find after reaching a readable screen.`})}function D(e){let{nodes:t,locator:r,query:i,selectorChain:a,flags:o,platform:s}=e,c=t.filter(e=>!F(e,t[0]));if(a){let e=u(c,a,{platform:s,requireRect:!0,requireUnique:!1});return e?{ok:!0,node:e.node}:{ok:!1,response:h(`COMMAND_FAILED`,`find did not match any element`)}}let l=n(c,r,i,{requireRect:!0});if(l.matches=k(l.matches,t),l.matches.length>1){let e=O(l.matches,o);if(!e)return{ok:!1,response:G(l.matches,r,i)};l.matches=e}let d=l.matches[0]??null;return d?{ok:!0,node:d}:{ok:!1,response:h(`COMMAND_FAILED`,`find did not match any element`)}}function O(e,t){return t?.findFirst?[e[0]]:t?.findLast?[e[e.length-1]]:null}function k(t,n){let r=n[0]?.rect;if(!r)return t;let i=t.filter(t=>{if(!t.rect)return!1;let n=e(t.rect);return n.x>=r.x&&n.x<=r.x+r.width&&n.y>=r.y&&n.y<=r.y+r.height});return A(i.length>0?i:t,n)}function A(e,t){return e.length<2?e:e.map((e,n)=>({node:e,index:n,score:j(e,t)})).sort((e,t)=>t.score===e.score?N(e.node)-N(t.node)||e.index-t.index:t.score-e.score).map(e=>e.node)}function j(e,t){let n=c(t,e);if(n.reason===`covered`)return 0;let r=M(n,t[0]);return r>0?r:e.hittable&&e.rect&&!F(e,t[0])?3:+!!e.rect}function M(e,t){return e.node.rect?e.reason===`semantic-target`||e.reason===`same-rect-descendant`?4:e.reason===`hittable-ancestor`&&!F(e.node,t)?2:0:0}function N(e){return e.rect?e.rect.width*e.rect.height:1/0}function P(e,t){let n=a(e,t);return F(n,e[0])&&t.rect?t:n}function F(e,t){if(!t?.rect||!e.rect)return!1;let n=e.type?.toLowerCase()??``;return!n.includes(`application`)&&!n.includes(`window`)?!1:I(e.rect,t.rect)}function I(e,t){return e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height}async function L(t,n){let{req:r,sessionName:i,sessionStore:a,session:c,invoke:l,command:u,locator:d,query:f,publicFlags:p}=t,m=await l({token:r.token,session:i,command:`click`,positionals:[n.ref],flags:n.actionFlags,internal:{findResolvedTarget:!0}});if(!m.ok)return m;let h=n.resolvedNode.rect?e(n.resolvedNode.rect):n.node.rect?e(n.node.rect):null,g={ref:n.ref,locator:d,query:f};h&&(g.x=h.x,g.y=h.y);let _=o(m.data)??`Tapped ${n.ref}${h?` (${h.x}, ${h.y})`:``}`;return Object.assign(g,s(_)),y(a,c,r,u,{ref:n.ref,action:`click`,locator:d,query:f},{flags:p}),{ok:!0,data:g}}async function R(e,t,n){let{req:r,sessionName:i,sessionStore:a,session:o,invoke:s,command:c,publicFlags:l}=e;if(!n)return h(`INVALID_ARGS`,`find fill requires text`);let u=await s({token:r.token,session:i,command:`fill`,positionals:[t.ref,n],flags:t.actionFlags,internal:{findResolvedTarget:!0}});return u.ok&&y(a,o,r,c,{ref:t.ref,action:`fill`},{flags:l}),u}async function z(e,t){let n=await V(e,t);return n.ok&&U(e,t,`focus`),n}async function B(e,t,n){let{req:r,device:i,logPath:a,session:o}=e;if(!n)return h(`INVALID_ARGS`,`find type requires text`);let s=await V(e,t);if(!s.ok)return s;_(o);let c=await m(i,`type`,[n],r.flags?.out,{...g(a,r.flags,o.appBundleId,o.trace?.outPath)});return U(e,t,`type`),{ok:!0,data:c??{ref:t.ref}}}async function V(t,n){let{req:r,device:i,logPath:a,session:o}=t,s=H(n,`be focused`);if(s)return s;let c=n.resolvedNode.rect?e(n.resolvedNode.rect):null;return c?(_(o),{ok:!0,data:await m(i,`focus`,[String(c.x),String(c.y)],r.flags?.out,{...g(a,r.flags,o.appBundleId,o.trace?.outPath)})??{ref:n.ref}}):h(`COMMAND_FAILED`,`matched element has no bounds`)}function H(e,t){let n=[e.resolvedNode,e.node].find(f);return n?h(`COMMAND_FAILED`,`Matched element ${e.ref} is covered by another visible element and cannot ${t} safely`,{ref:`@${n.ref}`,interactionBlocked:n.interactionBlocked,hint:`Use a different visible target, scroll it clear of the overlay, or inspect with snapshot/screenshot before retrying.`}):null}function U(e,t,n){let{req:r,sessionStore:i,session:a,command:o,publicFlags:s}=e;y(i,a,r,o,{ref:t.ref,action:n},{flags:s})}function W(e){return{...v(e)??{}}}function G(e,t,n){let r=e.slice(0,8).map(e=>{let t=l(e)||e.label||e.identifier||e.type||``;return`@${e.ref}${t?`(${t})`:``}`});return h(`AMBIGUOUS_MATCH`,`find matched ${e.length} elements for ${t} "${n}". Use a more specific locator or selector.`,{locator:t,query:n,matches:e.length,candidates:r})}function K(e){return e!==`role`}export{G as buildAmbiguousMatchError,C as handleFindCommands};
@@ -1 +1 @@
1
- import{E as e}from"./sdk-batch.js";import{t}from"./sdk-finders.js";export{t as findBestMatchesByLocator,e as parseFindArgs};
1
+ import{K as e}from"./sdk-batch-runner.js";import{t}from"./sdk-finders.js";export{t as findBestMatchesByLocator,e as parseFindArgs};
@@ -1 +1 @@
1
- import{a as e}from"./sdk-contracts.js";import{Kn as t}from"./tv-remote.js";import{i as n,n as r}from"./cli-runner.js";async function i({command:t,positionals:i,flags:s,client:c,debug:l,replayTestReporterRuntime:u}){let{result:d,cliOutput:f}=await r({client:c,command:t,positionals:i,flags:s});if(e(s.responseLevel))return n(s,d,()=>JSON.stringify(d,null,2)),!0;if(f)o(s,f);else{let e=await a(t,s,d,{debug:l,replayTestReporterRuntime:u});e!==0&&process.exit(e)}return!0}function a(e,r,i,a={}){return e===`test`?import(`./reporting.js`).then(({renderReplayTestResponse:e})=>e({suite:i,debug:a.debug,verbose:r.verbose,json:r.json,reporter:r.reporter,reportJunit:r.reportJunit,reporterRuntime:a.replayTestReporterRuntime})):(n(r,i,()=>t(i)),0)}function o(e,t){!e.json&&t.stderr&&process.stderr.write(t.stderr),n(e,e.json?t.jsonData??t.data:t.data,()=>t.text)}export{i as runGenericClientBackedCommand};
1
+ import{a as e}from"./sdk-contracts.js";import{_n as t}from"./recording-export-quality.js";import{i as n,n as r}from"./cli-runner.js";async function i({command:t,positionals:i,flags:s,client:c,debug:l,replayTestReporterRuntime:u}){let{result:d,cliOutput:f}=await r({client:c,command:t,positionals:i,flags:s});if(e(s.responseLevel))return n(s,d,()=>JSON.stringify(d,null,2)),!0;if(f)o(s,f);else{let e=await a(t,s,d,{debug:l,replayTestReporterRuntime:u});e!==0&&process.exit(e)}return!0}function a(e,r,i,a={}){return e===`test`?import(`./reporting.js`).then(({renderReplayTestResponse:e})=>e({suite:i,debug:a.debug,verbose:r.verbose,json:r.json,reporter:r.reporter,reportJunit:r.reportJunit,reporterRuntime:a.replayTestReporterRuntime})):(n(r,i,()=>t(i)),0)}function o(e,t){!e.json&&t.stderr&&process.stderr.write(t.stderr),n(e,e.json?t.jsonData??t.data:t.data,()=>t.text)}export{i as runGenericClientBackedCommand};
@@ -0,0 +1 @@
1
+ import{_ as e}from"./sdk-contracts.js";function t(e,t){return e.includes(t)}function n(n,r,i={}){let a=r===void 0?void 0:i.normalize?.(r)??r;if(a!==void 0&&t(n,a))return a;throw new e(`INVALID_ARGS`,(typeof i.message==`function`?i.message(r):i.message)??`Invalid value: ${r}. Use ${n.join(`|`)}.`)}function r(e,r={}){return{values:e,is:n=>t(e,n),parse:t=>n(e,t,r)}}const i=[`up`,`down`,`left`,`right`,`top`,`bottom`],a=[`up`,`down`,`left`,`right`],o=[`left`,`right`,`left-edge`,`right-edge`],s=[`one-way`,`ping-pong`],c=1e4,l=6e4,u=r(a,{message:e=>`Unknown direction: ${e}`});function d(e){let t=e.direction,n=t===`up`||t===`down`?e.referenceHeight:e.referenceWidth,r=b(e.amount),i=e.pixels===void 0?Math.round(n*r):x(e.pixels),a=Math.max(1,Math.round(n*.05)),o=Math.max(1,n-a*2),s=Math.max(1,Math.min(i,o)),c=Math.round(s/2),l=Math.round(e.referenceWidth/2),u=Math.round(e.referenceHeight/2),d=(n,r,i,a)=>({direction:t,x1:n,y1:r,x2:i,y2:a,referenceWidth:e.referenceWidth,referenceHeight:e.referenceHeight,amount:e.amount,pixels:s});switch(t){case`up`:return d(l,u-c,l,u+c);case`down`:return d(l,u+c,l,u-c);case`left`:return d(l-c,u,l+c,u);case`right`:return d(l+c,u,l-c,u)}}function f(e){b(e.amount),e.pixels!==void 0&&x(e.pixels)}function ee(e,t){if(e===`left`||e===`right`){let n=p(e,t);return{preset:e,x1:n.x1,y1:n.y1,x2:n.x2,y2:n.y2,referenceWidth:n.referenceWidth,referenceHeight:n.referenceHeight}}let[n,r]=e===`left-edge`?[99,15]:[1,85],i=g(h(t,n,50),t,8),a=g(h(t,r,50),t,8);return{preset:e,x1:i.x,y1:i.y,x2:a.x,y2:a.y,referenceWidth:t.referenceWidth,referenceHeight:t.referenceHeight}}function te(e,t){switch(e){case`up`:return{x:0,y:-t};case`down`:return{x:0,y:t};case`left`:return{x:-t,y:0};case`right`:return{x:t,y:0}}}function p(e,t){let n=e===`left`||e===`up`,r=n?85:15,i=n?15:85,a=e===`up`||e===`down`,o=g(h(t,a?50:r,a?r:50),t,8),s=g(h(t,a?50:i,a?i:50),t,8);return{direction:e,x1:o.x,y1:o.y,x2:s.x,y2:s.y,referenceWidth:t.referenceWidth,referenceHeight:t.referenceHeight}}function m(e){let t=_(e);if(t)return{referenceWidth:t.width,referenceHeight:t.height}}function h(e,t,n){let r=Math.trunc(e.referenceWidth*t/100),i=Math.trunc(e.referenceHeight*n/100);return{x:Number.isFinite(r)?r:0,y:Number.isFinite(i)?i:0}}function g(e,t,n){return{x:S(e.x,n,t.referenceWidth),y:S(e.y,n,t.referenceHeight)}}function ne(e){return u.parse(e)}function _(e){let t=e.filter(e=>v(e.type)&&y(e.rect)).map(e=>e.rect).sort((e,t)=>(t?.width??0)*(t?.height??0)-(e?.width??0)*(e?.height??0))[0];if(t)return t;let n=e.map(e=>e.rect).filter(y);if(n.length===0)return;let r=Math.max(...n.map(e=>e.x+e.width)),i=Math.max(...n.map(e=>e.y+e.height));if(!(r<=0||i<=0))return{x:0,y:0,width:r,height:i}}function v(e){if(!e)return!1;let t=e.toLowerCase();return t.includes(`application`)||t.includes(`window`)}function y(e){return!!e&&e.width>0&&e.height>0}function b(t){if(t===void 0)return .6;if(!Number.isFinite(t)||t<=0)throw new e(`INVALID_ARGS`,`scroll amount must be a positive number`);return t}function x(t){if(!Number.isFinite(t)||t<=0)throw new e(`INVALID_ARGS`,`scroll pixels must be a positive integer`);return Math.max(1,Math.round(t))}function S(e,t,n){let r=Math.round(t);if(!Number.isFinite(r))return 0;let i=Math.max(r,Math.round(n-t));return!Number.isFinite(i)||!Number.isFinite(e)?r:Math.min(i,Math.max(r,Math.round(e)))}const re={android:`longpress`,apple:`exact`,vega:`exact`},C={up:{aliases:[],androidKeyevent:`KEYCODE_DPAD_UP`,appleRemoteButton:`up`,vegaKey:`KEY_UP`},down:{aliases:[],androidKeyevent:`KEYCODE_DPAD_DOWN`,appleRemoteButton:`down`,vegaKey:`KEY_DOWN`},left:{aliases:[],androidKeyevent:`KEYCODE_DPAD_LEFT`,appleRemoteButton:`left`,vegaKey:`KEY_LEFT`},right:{aliases:[],androidKeyevent:`KEYCODE_DPAD_RIGHT`,appleRemoteButton:`right`,vegaKey:`KEY_RIGHT`},select:{aliases:[`ok`,`center`,`enter`],androidKeyevent:`KEYCODE_DPAD_CENTER`,appleRemoteButton:`select`,vegaKey:`KEY_ENTER`},menu:{aliases:[],androidKeyevent:`KEYCODE_MENU`,appleRemoteButton:`menu`,vegaKey:`KEY_MENU`},home:{aliases:[],androidKeyevent:`KEYCODE_HOME`,appleRemoteButton:`home`,vegaKey:`KEY_HOMEPAGE`},back:{aliases:[],androidKeyevent:`KEYCODE_BACK`,appleRemoteButton:`menu`,vegaKey:`KEY_BACK`}},w=Object.keys(C),T=`<${w.join(`|`)}>`;function E(t){let n=t?.toLowerCase();if(D(n))return n;let r=n?M.get(n):void 0;if(r)return r;throw new e(`INVALID_ARGS`,`tv-remote button must be one of: ${w.join(`, `)}.`)}function D(e){return typeof e==`string`&&w.includes(e)}function O(e){return C[e].appleRemoteButton}function k(e){return C[e].androidKeyevent}function A(e){return C[e].vegaKey}function j(e){return re[e]}const M=new Map(w.flatMap(e=>C[e].aliases.map(t=>[t,e])));function N(t,n){if(t===void 0||t.trim()===``)throw new e(`INVALID_ARGS`,`settings location set requires ${n}`);return F(Number(t),n)}function P(e){return{latitude:F(e?.latitude,`latitude`),longitude:F(e?.longitude,`longitude`)}}function F(t,n){let r=n===`latitude`?-90:-180,i=n===`latitude`?90:180;if(typeof t!=`number`||!Number.isFinite(t)||t<r||t>i)throw new e(`INVALID_ARGS`,`${n} must be a number from ${r} to ${i}`);return t}const I=new Set([`healthy`,`recovered`,`sparse`]),L=new Set([`tree`,`queries`,`private-ax`]),R=new Set([`ax-rejected`,`sparse-tree`,`budget`,`no-nodes`,`capture-failed`]);function z(e){if(!e||typeof e!=`object`)return;let t=e;if(!(typeof t.state!=`string`||!I.has(t.state))&&!(typeof t.backend!=`string`||!L.has(t.backend)))return{state:t.state,backend:t.backend,reason:typeof t.reason==`string`?t.reason:void 0,reasonCode:typeof t.reasonCode==`string`&&R.has(t.reasonCode)?t.reasonCode:void 0,effectiveDepth:typeof t.effectiveDepth==`number`?t.effectiveDepth:void 0,collapsedLeafIndexes:Array.isArray(t.collapsedLeafIndexes)?t.collapsedLeafIndexes.filter(e=>typeof e==`number`):void 0}}function B(e){return e?.state===`sparse`}function V(e,t){return[...H(e),...U(e),...ie(e,t)]}function H(e){return e.state===`recovered`?[`Detected an overly complex or slow accessibility tree. Fell back to the ${e.backend} snapshot backend. It is OK to continue; use --json to inspect snapshotQuality.reason if you need recovery details.`]:e.state===`sparse`?[`No snapshot backend could read this screen`+(e.reason?` (${e.reason})`:``)+`. Use screenshot as visual truth and coordinate taps; retry snapshot after navigating.`]:[]}function U(e){return e.effectiveDepth===void 0?[]:[`Some deeper accessibility nodes were omitted; this tree is capped at depth ${e.effectiveDepth}. Re-run with --depth ${e.effectiveDepth} --scope <container> only if you need deeper content.`]}function ie(e,t){let n=[];for(let r of e.collapsedLeafIndexes??[]){let e=t.find(e=>e.index===r);if(!e)continue;let i=e.identifier?` (${e.identifier})`:``;n.push(`@${e.ref} [${e.type??`element`}]${i} merges many labels into a single accessibility element. The app likely marks a container as accessible, which hides every descendant from assistive tech and automation — the children cannot be addressed individually. Fix the app's accessibility (mark the rows, not the container); until then use screenshot as visual truth and coordinate taps.`)}return n}const W=new Set([`empty-helper-output`,`system-window-only`,`content-poor-app-window`]);function G(e){if(!e||typeof e!=`object`)return!1;let t=e.details?.androidSnapshotHelperFailureReason;return typeof t==`string`&&W.has(t)}function K(e){let t=z(e.quality);return{...e.analysis?{analysis:e.analysis}:{},...e.androidSnapshot?{androidSnapshot:e.androidSnapshot}:{},...e.freshness?{freshness:e.freshness}:{},...t?{quality:t}:{},...e.warnings?{warnings:e.warnings}:{}}}function q(e){return{...e.androidSnapshot?{androidSnapshot:e.androidSnapshot}:{},...e.quality?{snapshotQuality:e.quality}:{},...e.warnings&&e.warnings.length>0?{warnings:e.warnings}:{}}}function J(e){let t=Y(e.androidSnapshot),n=Array.isArray(e.warnings)?e.warnings.filter(e=>typeof e==`string`):void 0,r=z(e.snapshotQuality);return q({...t?{androidSnapshot:t}:{},...r?{quality:r}:{},...n?{warnings:n}:{}})}function Y(e){return typeof e==`object`&&e?e:void 0}function ae(e){return e}function oe(e){let t=1/0,n=1/0,r=-1/0,i=-1/0;for(let a of e)t=Math.min(t,a.x),n=Math.min(n,a.y),r=Math.max(r,a.x+a.width),i=Math.max(i,a.y+a.height);return{x:t,y:n,width:r-t,height:i-n}}function se(e,t){return{x:e.x-t,y:e.y-t,width:e.width+t*2,height:e.height+t*2}}function ce(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);return i<=n||a<=r?0:(i-n)*(a-r)}function le(e){return{x:e.x+e.width/2,y:e.y+e.height/2}}function X(e,t){return(e.x-t.x)**2+(e.y-t.y)**2}function ue(e,t,n){return Math.min(Math.max(e,t),n)}const Z=`com.android.systemui`;function de(e){let t=e??``;if(!t.startsWith(`com.android.systemui:id/`))return!1;let n=t.slice(`${Z}:id/`.length);return/(^|_)(status_bar|navigation_bar)(_|$)/.test(n)}function Q(e){return`systemChrome`in e&&e.systemChrome===!0}function $(e){if(!Q(e))return e;let{systemChrome:t,...n}=e;return n}function fe(e){return e.some(Q)?e.map($):e}const pe=1e4;export{a as A,te as B,w as C,O as D,k as E,l as F,ne as H,f as I,p as L,s as M,c as N,A as O,o as P,d as R,P as S,E as T,r as U,m as V,n as W,B as _,fe as a,V as b,se as c,le as d,X as f,K as g,J as h,de as i,i as j,j as k,ce as l,q as m,Z as n,$ as o,oe as p,Q as r,ue as s,pe as t,ae as u,G as v,T as w,N as x,z as y,ee as z};
@@ -0,0 +1 @@
1
+ import{_ as e}from"./sdk-contracts.js";import{B as t,t as n,z as r}from"./gesture-plan-types.js";const i={pinchAxisDegrees:-90,frameCount:Math.floor},a={ios:i,macos:i,android:{pinchAxisDegrees:0,frameCount:Math.round},vega:i,linux:i,web:i};function o(e,t,n){let r=v(t),i=k(n);switch(e.intent){case`fling`:return c(e,r,i);case`pan`:return l(e,r,i);case`pinch`:return d({intent:`pinch`,origin:e.origin??T(r),delta:{x:0,y:0},scale:C(e.scale,`gesture pinch scale`),rotationDegrees:0,durationMs:300},r,i);case`rotate`:{let t=S(e.degrees,`gesture rotate degrees`);return d({intent:`rotate`,origin:e.origin??T(r),delta:{x:0,y:0},scale:1,rotationDegrees:t,durationMs:b(t)},r,i)}case`transform`:{let t=S(e.degrees,`gesture transform degrees`);return d({intent:`transform`,origin:e.origin,delta:e.delta,scale:C(e.scale,`gesture transform scale`),rotationDegrees:t,durationMs:y(e.durationMs,b(t),`gesture transform durationMs`)},r,i)}}}function s(t){let n=t.pointers[0].samples[0]?.point,r=t.pointers[0].samples.at(-1)?.point;if(!n||!r)throw new e(`INVALID_ARGS`,`single-pointer gesture plan requires samples`);return{start:n,end:r}}function c(e,n,r){if(`preset`in e){let{from:t,to:i}=O(e.preset,n);return u(`fling`,t,i,100,n,`endpoint-hold`,r)}if(`from`in e)return u(`fling`,e.from,e.to,100,n,`endpoint-hold`,r);let i=x(e.origin,`gesture fling origin`),a=w(e.distance??180,`gesture fling distance`);return u(`fling`,i,E(i,t(e.direction,a)),100,n,`endpoint-hold`,r)}function l(t,n,r){let i=y(t.durationMs,500,`gesture pan durationMs`);if((t.pointerCount??1)===1){let e=x(t.origin,`gesture pan origin`);return u(`pan`,e,E(e,x(t.delta,`gesture pan delta`)),i,n,t.executionProfile??`timed-pan`,r)}if(t.pointerCount!==2)throw new e(`INVALID_ARGS`,`gesture pan pointerCount must be 1 or 2`);return d({intent:`pan`,origin:t.origin,delta:t.delta,scale:1,rotationDegrees:0,durationMs:i},n,r)}function u(e,t,n,r,i,a,o){let s=x(t,`gesture ${e} start`),c=x(n,`gesture ${e} end`),l=h(r,o).map(e=>({offsetMs:e,point:D(s,c,e/r)}));return g(l,i,{intent:e,pointerId:0}),{topology:`single`,intent:e,executionProfile:a,durationMs:r,viewport:i,pointers:[{pointerId:0,samples:l}]}}function d(e,t,n){let r=x(e.origin,`gesture ${e.intent} origin`),i=E(r,x(e.delta,`gesture ${e.intent} delta`)),a=Math.min(t.width,t.height)*m(e.intent),o=e.scale>1?a/e.scale:a,s=o*e.scale;if(Math.min(o,s)<48)throw _({intent:e.intent,viewport:t,initialSpan:o,finalSpan:s,minimumReliableSpan:48});let c=o/2,l=h(e.durationMs,n),u=(a,o)=>{let s=l.map(t=>({offsetMs:t,point:f({...e,start:r,end:i,initialRadius:c,offsetMs:t,side:o,profile:n})}));return g(s,t,{intent:e.intent,pointerId:a}),{pointerId:a,samples:s}};return{topology:`two`,intent:e.intent,durationMs:e.durationMs,viewport:t,pointers:[u(0,1),u(1,-1)]}}function f(e){let t=e.offsetMs/e.durationMs,n=D(e.start,e.end,t),r=e.initialRadius*(1+(e.scale-1)*t),i=A(p(e.intent,e.profile)+e.rotationDegrees*t);return{x:n.x+Math.cos(i)*r*e.side,y:n.y+Math.sin(i)*r*e.side}}function p(e,t){return e===`pinch`?t.pinchAxisDegrees:-90}function m(e){return e===`pinch`?.4:.25}function h(e,t){let n=e/16,r=Math.max(3,t.frameCount(n));return Array.from({length:r+1},(t,n)=>Math.round(e*n/r))}function g(t,n,r){let i=n.x+n.width-1,a=n.y+n.height-1;for(let o of t){let{x:t,y:s}=o.point;if(!Number.isFinite(t)||!Number.isFinite(s))throw new e(`INVALID_ARGS`,`Gesture motion produces non-finite pointer coordinates`,{...r,reason:`GESTURE_TRAJECTORY_NON_FINITE`,hint:`Reduce the requested rotation, translation, or scale.`});if(t<n.x+1||t>i||s<n.y+1||s>a)throw _({...r,viewport:n,sample:o})}}function _(t){return new e(`INVALID_ARGS`,`Gesture trajectory does not fit inside the viewport`,{...t,reason:`GESTURE_TRAJECTORY_OUT_OF_BOUNDS`,hint:`Move the gesture away from the edge or reduce its translation, scale, or rotation.`})}function v(t){let n={x:S(t.x,`gesture viewport x`),y:S(t.y,`gesture viewport y`),width:S(t.width,`gesture viewport width`),height:S(t.height,`gesture viewport height`)};if(n.width<=0||n.height<=0)throw new e(`INVALID_ARGS`,`gesture viewport width and height must be positive`);return n}function y(t,r,i){let a=t??r;if(!Number.isInteger(a)||a<16||a>1e4)throw new e(`INVALID_ARGS`,`${i} must be an integer between 16 and ${n}`);return a}function b(e){let t=Math.ceil(Math.abs(e)/3)*16;return Math.min(Math.max(300,t),2400)}function x(e,t){return{x:S(e.x,`${t} x`),y:S(e.y,`${t} y`)}}function S(t,n){if(!Number.isFinite(t))throw new e(`INVALID_ARGS`,`${n} must be a finite number`);return t}function C(t,n){let r=S(t,n);if(r<=0)throw new e(`INVALID_ARGS`,`${n} must be greater than 0`);return r}function w(t,n){let r=S(t,n);if(r<=0)throw new e(`INVALID_ARGS`,`${n} must be a positive number`);return r}function T(e){return{x:e.x+e.width/2,y:e.y+e.height/2}}function E(e,t){return{x:e.x+t.x,y:e.y+t.y}}function D(e,t,n){return{x:e.x+(t.x-e.x)*n,y:e.y+(t.y-e.y)*n}}function O(e,t){let n=r(e,{referenceWidth:t.width,referenceHeight:t.height});return{from:{x:t.x+n.x1,y:t.y+n.y1},to:{x:t.x+n.x2,y:t.y+n.y2}}}function k(e){return e===void 0?i:a[e]}function A(e){return e*Math.PI/180}export{s as n,o as t};