agent-device 0.21.22 → 0.21.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -6
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.22.apk → agent-device-android-ime-helper-0.21.24.apk} +0 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.24.apk.sha256 +1 -0
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.22.manifest.json → agent-device-android-ime-helper-0.21.24.manifest.json} +4 -4
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.24.apk +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.24.apk.sha256 +1 -0
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.22.manifest.json → agent-device-android-snapshot-helper-0.21.24.manifest.json} +6 -6
- package/apple/macos-helper/Sources/AgentDeviceMacOSHelper/SnapshotTraversal.swift +12 -6
- package/apple/macos-helper/Tests/AgentDeviceMacOSHelperTests/RectResponseTests.swift +21 -0
- package/apple/snapshot-bridge/README.md +9 -7
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandDispatch.swift +56 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +14 -5
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +8 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +12 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCaptureTarget.swift +1 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotExecution.swift +29 -5
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +34 -10
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryFocus.swift +19 -5
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextTyping.swift +3 -3
- package/dist/src/adapter.js +1 -1
- package/dist/src/adb.js +1 -1
- package/dist/src/agent-browser-lifecycle.js +1 -1
- package/dist/src/agent-browser-process-record.js +1 -1
- package/dist/src/agent-browser-provider.js +1 -1
- package/dist/src/agent-device-client.js +2 -2
- package/dist/src/alert-runtime.js +1 -1
- package/dist/src/alert.js +1 -1
- package/dist/src/android-adb.d.ts +3 -2
- package/dist/src/android-input-ownership.js +1 -1
- package/dist/src/app-backend.js +1 -1
- package/dist/src/app-inventory.d.ts +4 -0
- package/dist/src/app-launch.js +1 -1
- package/dist/src/app-lifecycle.js +1 -1
- package/dist/src/app-log-reconnect.js +1 -1
- package/dist/src/app-log-runtime2.js +3 -3
- package/dist/src/app-resolution.js +2 -2
- package/dist/src/app-state-runtime.d.ts +15 -0
- package/dist/src/apple-runner-platform.js +1 -1
- package/dist/src/application-lifecycle-interaction.js +1 -1
- package/dist/src/aws-device-farm-connection.js +1 -0
- package/dist/src/back-mode.js +1 -1
- package/dist/src/backend-snapshot-options.js +1 -1
- package/dist/src/browserstack-connection.js +1 -0
- package/dist/src/browserstack-device-features.js +1 -0
- package/dist/src/browserstack.js +1 -0
- package/dist/src/cache.js +1 -1
- package/dist/src/cli-config.js +1 -1
- package/dist/src/cli-help.js +35 -19
- package/dist/src/cli-runner.js +1 -1
- package/dist/src/cli.js +3 -4
- package/dist/src/client-companion-tunnel.js +1 -0
- package/dist/src/client-metro-companion.js +1 -1
- package/dist/src/client-metro.js +1 -1
- package/dist/src/client-options.js +3 -3
- package/dist/src/client-types.d.ts +7 -5
- package/dist/src/cloud-artifacts.d.ts +9 -2
- package/dist/src/code-signature-cache.js +1 -1
- package/dist/src/command-metadata.js +1 -1
- package/dist/src/command-schema.js +1 -1
- package/dist/src/command-tools.js +2 -2
- package/dist/src/connection-runtime.js +1 -1
- package/dist/src/connection-verification.js +1 -0
- package/dist/src/connection.js +5 -5
- package/dist/src/contracts.d.ts +1 -1
- package/dist/src/daemon-client-lease-beat.js +1 -1
- package/dist/src/daemon-client-lifecycle.js +1 -1
- package/dist/src/daemon-client-transport.js +1 -1
- package/dist/src/daemon-http.js +1 -1
- package/dist/src/daemon-policy-file.js +1 -1
- package/dist/src/daemon-registration-owner.js +1 -1
- package/dist/src/device-claim-inspection.js +1 -1
- package/dist/src/device-input-state.d.ts +2 -15
- package/dist/src/device-readiness-runtime.js +1 -1
- package/dist/src/device-selection-resolver.js +1 -1
- package/dist/src/device-session.js +3 -1
- package/dist/src/device.js +1 -1
- package/dist/src/device2.js +1 -1
- package/dist/src/device3.js +1 -1
- package/dist/src/dispatch-resolve.js +3 -3
- package/dist/src/doctor-facade.js +1 -1
- package/dist/src/durable-capture-resource.js +1 -1
- package/dist/src/durable-resource.js +1 -1
- package/dist/src/exec.js +1 -1
- package/dist/src/file.js +1 -1
- package/dist/src/find.js +1 -1
- package/dist/src/finders.js +1 -1
- package/dist/src/format.js +2 -1
- package/dist/src/gesture-admission.js +1 -1
- package/dist/src/gesture-plan-types.d.ts +2 -5
- package/dist/src/gesture-runtime.js +1 -1
- package/dist/src/helper.js +2 -2
- package/dist/src/human-control.js +1 -1
- package/dist/src/ime-rebind.js +1 -0
- package/dist/src/ime-settings-record.js +1 -0
- package/dist/src/ime-state.js +1 -0
- package/dist/src/index.d.ts +3 -3
- package/dist/src/input-actions.js +1 -1
- package/dist/src/input-actions2.js +1 -1
- package/dist/src/install-source2.js +1 -1
- package/dist/src/instance-client.js +1 -1
- package/dist/src/interaction-positionals.js +1 -1
- package/dist/src/interaction-ref-policy.js +1 -1
- package/dist/src/interaction.js +1 -1
- package/dist/src/interaction2.js +1 -1
- package/dist/src/interactor.js +5 -5
- package/dist/src/interactors.js +1 -1
- package/dist/src/internal/bin.js +1 -1
- package/dist/src/internal/daemon.js +1 -1
- package/dist/src/inventory2.js +1 -1
- package/dist/src/ios-client.js +4 -4
- package/dist/src/ios-snapshot-acquisition.js +1 -1
- package/dist/src/ios-snapshot-engine.js +1 -1
- package/dist/src/ios-snapshot-runtime.js +1 -1
- package/dist/src/launch-confirmation.js +1 -1
- package/dist/src/lease-scope.js +1 -1
- package/dist/src/lease.js +1 -1
- package/dist/src/limrun.d.ts +4 -555
- package/dist/src/load.js +1 -1
- package/dist/src/local-interactor-operation-set.js +1 -1
- package/dist/src/log-stream.js +33 -0
- package/dist/src/managed-device-scope.js +1 -1
- package/dist/src/manifest.js +1 -0
- package/dist/src/mechanics.js +16 -16
- package/dist/src/mobile-snapshot-semantics.js +1 -1
- package/dist/src/node-http.js +1 -0
- package/dist/src/observation.js +1 -2
- package/dist/src/overlay.js +3 -3
- package/dist/src/owner-identity.js +3 -3
- package/dist/src/perf-facade.js +1 -1
- package/dist/src/perf-runtime-plan.js +1 -1
- package/dist/src/perf-target.js +1 -1
- package/dist/src/physical-device-control.js +1 -1
- package/dist/src/platform-request-scope.js +1 -1
- package/dist/src/platform-runtime-app-log-process.js +1 -1
- package/dist/src/platform-runtime-open-target.js +1 -1
- package/dist/src/platform-runtime-operation-host.js +4 -4
- package/dist/src/platform-runtime-runtime-hints.js +1 -1
- package/dist/src/platform-runtime-screen-recording-finalizer-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-process-host.js +1 -1
- package/dist/src/platform-runtime-unavailable.js +1 -1
- package/dist/src/platform-runtime.js +1 -1
- package/dist/src/platform-runtime2.js +1 -1
- package/dist/src/plugin.js +1 -0
- package/dist/src/plugins/webdriver.d.ts +111 -0
- package/dist/src/plugins/webdriver.js +1 -0
- package/dist/src/plugins.d.ts +2 -1
- package/dist/src/plugins2.js +1 -1
- package/dist/src/process-exit.js +1 -1
- package/dist/src/process.js +1 -1
- package/dist/src/provider-credential-fingerprint.js +1 -1
- package/dist/src/provider-device-admission.js +1 -1
- package/dist/src/provider-device-runtime.d.ts +556 -0
- package/dist/src/provider-policy.js +1 -0
- package/dist/src/provider-profile-fields.js +1 -1
- package/dist/src/provider-webdriver.js +1 -2
- package/dist/src/providers.js +1 -1
- package/dist/src/proxy.js +2 -2
- package/dist/src/react-devtools.js +2 -0
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-runtime.js +1 -1
- package/dist/src/record-trace.js +1 -1
- package/dist/src/recording.js +1 -1
- package/dist/src/registry.js +24 -24
- package/dist/src/remote-bridge.js +1 -0
- package/dist/src/remote-config-core.js +1 -0
- package/dist/src/remote-config.js +1 -1
- package/dist/src/remote-config2.js +1 -1
- package/dist/src/remote-connection-state.js +1 -0
- package/dist/src/replay.js +2 -2
- package/dist/src/request-admission.js +1 -1
- package/dist/src/request-runtime-binding.js +1 -1
- package/dist/src/result-serialization.js +1 -1
- package/dist/src/retry.js +1 -1
- package/dist/src/retry2.js +1 -0
- package/dist/src/runner-artifact-manifest.js +1 -1
- package/dist/src/runner-cache-metadata.js +2 -3
- package/dist/src/runner-cache-retention.js +1 -0
- package/dist/src/runner-cache-trim.js +1 -0
- package/dist/src/runner-client.js +1 -1
- package/dist/src/runner-dev-tools-security.js +1 -1
- package/dist/src/runner-device-readiness.js +1 -1
- package/dist/src/runner-device-set.js +1 -0
- package/dist/src/runner-disposal.js +1 -1
- package/dist/src/runner-error-classification.js +1 -1
- package/dist/src/runner-exchange.js +1 -1
- package/dist/src/runner-lease.js +1 -0
- package/dist/src/runner-operations-facade.js +1 -1
- package/dist/src/runner-session-types.js +1 -1
- package/dist/src/runner-start-budget.js +1 -1
- package/dist/src/runner-toolchain-probe.js +2 -0
- package/dist/src/runner.js +1 -1
- package/dist/src/runtime-deployment.js +1 -0
- package/dist/src/runtime.js +1 -1
- package/dist/src/runtime10.js +1 -2
- package/dist/src/runtime11.js +2 -0
- package/dist/src/runtime2.js +2 -5
- package/dist/src/runtime3.js +5 -1
- package/dist/src/runtime4.js +1 -5
- package/dist/src/runtime5.js +5 -1
- package/dist/src/runtime6.js +1 -1
- package/dist/src/runtime7.js +1 -1
- package/dist/src/runtime8.js +1 -1
- package/dist/src/runtime9.js +1 -1
- package/dist/src/screen-recording-transport.js +1 -1
- package/dist/src/screenshot-density.js +1 -1
- package/dist/src/screenshot-overlay-draw.js +1 -1
- package/dist/src/screenshot3.js +2 -2
- package/dist/src/script.js +1 -1
- package/dist/src/scroll-gesture.js +1 -1
- package/dist/src/sdk-batch.js +2 -2
- package/dist/src/sdk-contracts.d.ts +25 -33
- package/dist/src/sdk-contracts.js +2 -2
- package/dist/src/sdk-device.js +1 -1
- package/dist/src/sdk-finders.d.ts +1 -1
- package/dist/src/sdk-finders.js +1 -1
- package/dist/src/sdk-remote-config.d.ts +4 -0
- package/dist/src/sdk-remote-config.js +1 -1
- package/dist/src/sdk-selectors.d.ts +1 -1
- package/dist/src/sdk-selectors.js +1 -1
- package/dist/src/selection.js +0 -0
- package/dist/src/selector-pipeline-policy.js +1 -1
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/selectors.js +1 -1
- package/dist/src/server.js +2 -2
- package/dist/src/session-snapshot.js +1 -1
- package/dist/src/session2.js +5 -5
- package/dist/src/simctl.js +1 -1
- package/dist/src/simulator-boot.js +1 -1
- package/dist/src/simulator-state.js +1 -1
- package/dist/src/simulator.js +1 -1
- package/dist/src/snapshot-capture-annotations.js +1 -1
- package/dist/src/snapshot-desktop-projection.js +1 -1
- package/dist/src/snapshot-private-evidence.js +1 -0
- package/dist/src/snapshot-runtime-binding.js +1 -1
- package/dist/src/snapshot-runtime.js +1 -1
- package/dist/src/snapshot-state.js +1 -1
- package/dist/src/snapshot4.js +1 -1
- package/dist/src/src2.js +1 -1
- package/dist/src/src3.js +1 -1
- package/dist/src/src4.js +1 -1
- package/dist/src/src5.js +1 -1
- package/dist/src/src6.js +1 -1
- package/dist/src/src7.js +1 -1
- package/dist/src/src8.js +20 -20
- package/dist/src/store.js +1 -1
- package/dist/src/target-evidence.js +1 -1
- package/dist/src/text-entry-focus.js +1 -1
- package/dist/src/tool-provider2.js +1 -1
- package/dist/src/touch-runtime2.js +1 -1
- package/dist/src/tree.js +1 -1
- package/dist/src/type-text-runtime.js +1 -1
- package/dist/src/video.js +1 -1
- package/package.json +24 -16
- package/server.json +2 -2
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.22.apk.sha256 +0 -1
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.22.apk +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.22.apk.sha256 +0 -1
- package/dist/src/capabilities.js +0 -1
- package/dist/src/compatibility-policy.js +0 -1
- package/dist/src/daemon-artifacts.js +0 -1
- package/dist/src/device-claim-rule.js +0 -1
- package/dist/src/human-control-contract.js +0 -1
- package/dist/src/prepare-kind.js +0 -1
- package/dist/src/provider-device-runtimes.js +0 -1
- package/dist/src/screen-recording-admission-ledger.js +0 -1
- package/dist/src/screenshot-runtime.js +0 -1
- package/dist/src/session-routing.js +0 -1
- package/dist/src/session-runtime-admission.js +0 -1
- package/dist/src/session-stream.js +0 -27
- package/dist/src/timeouts.js +0 -1
- package/dist/src/touch-reference-frame.js +0 -1
- package/dist/src/vars.js +0 -2
- package/dist/src/viewport.js +0 -1
package/dist/src/format.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
import e from"node:path";function t(t){let n=e.
|
|
1
|
+
import{P as e}from"./sdk-contracts.js";import{t}from"./script.js";import n from"node:path";function r(e){return e.startsWith(`AD_`)}function i(t){return new e(`INVALID_ARGS`,`The AD_* namespace is reserved for built-in variables. Rename ${t} to avoid the AD_ prefix.`)}function a(e){let t={};if(e.builtins)for(let[n,r]of Object.entries(e.builtins))t[n]=r;let n=[e.fileEnv,e.shellEnv,e.cliEnv];for(let e of n)if(e)for(let[n,a]of Object.entries(e)){if(r(n))throw i(n);t[n]=a}return{values:t,expandedBuiltinNames:new Set}}function o(e){let n={};for(let[i,a]of Object.entries(e)){if(typeof a!=`string`||!i.startsWith(`AD_VAR_`))continue;let e=i.slice(7);e.length!==0&&t.test(e)&&(r(e)||(n[e]=a))}return n}function s(n){let a={};for(let o of n){let n=o.indexOf(`=`);if(n<=0)throw new e(`INVALID_ARGS`,`Invalid -e entry "${o}": expected KEY=VALUE.`);let s=o.slice(0,n);if(!t.test(s))throw new e(`INVALID_ARGS`,`Invalid -e key "${s}": keys must be uppercase letters, digits, and underscores (e.g. APP_ID).`);if(r(s))throw i(s);a[s]=o.slice(n+1)}return a}function c(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`):[]}function l(e){if(e&&typeof e==`object`&&!Array.isArray(e)){let t={};for(let[n,r]of Object.entries(e))typeof r==`string`&&(t[n]=r);return t}return process.env}function u(e){return e>=`A`&&e<=`Z`||e>=`a`&&e<=`z`||e===`_`}function d(e){return u(e)||e>=`0`&&e<=`9`||e===`.`}function f(e){return e===`
|
|
2
|
+
`||e===`\r`||e===`\u2028`||e===`\u2029`}function p(e,t){let n=t+2;if(n>=e.length||!u(e[n]))return null;for(n+=1;n<e.length&&d(e[n]);)n+=1;let r=e.slice(t+2,n);if(e[n]===`}`)return{key:r,fallback:void 0,end:n+1};if(e[n]!==`:`||e[n+1]!==`-`)return null;n+=2;let i=``;for(;n<e.length;){let t=e[n];if(t===`}`)return{key:r,fallback:i,end:n+1};if(t===`\\`){let t=e[n+1];if(t===void 0)return{abortEnd:e.length};if(f(t))return{abortEnd:n+2};i+=t,n+=2;continue}i+=t,n+=1}return{abortEnd:e.length}}function m(t,n,i){let a=``,o=0;for(;o<t.length;){let s=t[o];if(s===`\\`&&t.startsWith("${",o+1)){a+="${",o+=3;continue}if(s===`$`&&t[o+1]===`{`){let s=p(t,o);if(s!==null&&`abortEnd`in s){a+=t.slice(o,s.abortEnd),o=s.abortEnd;continue}if(s!==null){let{key:t,fallback:c}=s;if(Object.prototype.hasOwnProperty.call(n.values,t))r(t)&&(n.expandedBuiltinNames??=new Set).add(t),a+=String(n.values[t]);else if(c!==void 0)a+=c;else throw new e(`INVALID_ARGS`,`Unresolved variable \${${t}} at ${i.file}:${i.line}.`);o=s.end;continue}}a+=s,o+=1}return a}function h(e,t,n){return{...e,positionals:(e.positionals??[]).map(e=>m(e,t,n)),flags:g(e.flags,t,n)??{},runtime:g(e.runtime,t,n)}}function g(e,t,n){return e&&_(e,t,n)}function _(e,t,n){return typeof e==`string`?m(e,t,n):Array.isArray(e)?e.map(e=>_(e,t,n)):e&&typeof e==`object`?Object.fromEntries(Object.entries(e).map(([e,r])=>[e,_(r,t,n)])):e}function v(e){return Object.entries(e.values).filter(([t,n])=>n.length>0&&(!r(t)||e.expandedBuiltinNames?.has(t))).map(([e,t])=>({name:e,value:t})).sort((e,t)=>t.value.length-e.value.length)}function y(e){let t=n.extname(e).toLowerCase();return t===`.yaml`||t===`.yml`}function b(e,t){return`Maestro YAML requires explicit --maestro routing: ${e} ${t} --maestro`}function x(e,t){return t===`maestro`&&y(e)?`maestro`:`ad`}export{v as a,c,a as i,l,b as n,o,x as r,s,y as t,h as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{A as e,f as t}from"./sdk-device.js";const n={ios:`iOS`,ipados:`iPadOS`,tvos:`tvOS`,watchos:`watchOS`,visionos:`visionOS`,macos:`macOS`},r=`Target-authored drag requires an adapter that preserves source hold, timed movement, and destination hold; it is supported on Android touch devices and iOS/iPadOS.`,i=`Android TV has no touch input — this gesture is supported on Android phones, tablets, and the iOS simulator only.`,a=`Two-finger gesture synthesis is iOS-simulator only — not available on physical iOS devices.`;function o(e,t){return(t===`multi-touch`?s(e):t===`directional-fling`&&e.platform===`linux`?`Linux`:void 0)??e.appleOs??e.platform}function s(r){if(r.platform===`android`)return r.target===`tv`?`Android TV`:void 0;if(!t(r.platform))return;let i=e(r);if(i===`ios`||i===`ipados`)return`physical iOS devices`;if(i===`macos`||i===`tvos`||i===`visionos`)return n[i]}function c(e,t,n){return`gesture ${n} is not supported on ${o(e,t)}`}export{c as a,r as i,n,a as r,i as t};
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
//#region packages/contracts/src/app-inventory.d.ts
|
|
3
|
-
type AppsFilter = 'user-installed' | 'all';
|
|
4
|
-
//#endregion
|
|
1
|
+
import { j as Rect, k as Point } from "./sdk-contracts.js";
|
|
5
2
|
//#region packages/contracts/src/gesture-plan-types.d.ts
|
|
6
3
|
type GesturePointerCount = 1 | 2;
|
|
7
4
|
/** Selects one-pointer release timing without changing semantic gesture intent. */
|
|
@@ -35,4 +32,4 @@ type MultiTouchGesturePlan = {
|
|
|
35
32
|
};
|
|
36
33
|
type GesturePlan = SinglePointerGesturePlan | MultiTouchGesturePlan;
|
|
37
34
|
//#endregion
|
|
38
|
-
export { PointerTrajectorySample as a, PointerTrajectory as i, GesturePointerCount as n, SinglePointerGesturePlan as o, MultiTouchGesturePlan as r,
|
|
35
|
+
export { PointerTrajectorySample as a, PointerTrajectory as i, GesturePointerCount as n, SinglePointerGesturePlan as o, MultiTouchGesturePlan as r, GesturePlan as t };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{J as e,P as t}from"./sdk-contracts.js";import{Ft as n,bt as r}from"./sdk-batch.js";import{
|
|
1
|
+
import{J as e,P as t}from"./sdk-contracts.js";import{Ft as n,bt as r}from"./sdk-batch.js";import{h as i}from"./session-snapshot.js";import{n as a,t as o}from"./runtime-admission.js";import{a as s}from"./gesture-admission.js";async function c(e){let t=await a({command:`runtime gesture-viewport`,device:e.device,use:r,inspectFacts:e.inspectFacts,bindDevice:e.bindDevice});return t.type===`response`?{ok:!1,response:t.response}:{ok:!0,read:d(t.runtime).gestureViewport}}async function l(r){let i=n(r.input),a=await o({command:`gesture`,device:r.device,required:i.use.required,inspectFacts:r.inspectFacts,bindDevice:r.bindDevice,unavailableResponse:n=>({ok:!1,error:e(new t(`UNSUPPORTED_OPERATION`,s(r.device,i.tier,r.input.intent),{gesture:r.input.intent,...n.hint===void 0?{}:{hint:n.hint}}))})});return a.type===`response`?{ok:!1,response:a.response}:{ok:!0,gestures:await u(a.bind,r.device,i)}}async function u(e,t,n){switch(n.tier){case`plan`:{let r=await e(t,n.use);return{performPlan:async(e,t)=>await r.operations.performGesturePlan(f(e,t)),...d(r)}}case`directional-fling`:{let r=await e(t,n.use);return{performPlan:async(e,t)=>await r.operations.performDirectionalFlingPlan(f(e,t)),...d(r)}}case`multi-touch`:{let r=await e(t,n.use);return{performPlan:async(e,t)=>await r.operations.performMultiTouchGesturePlan(f(e,t)),...d(r)}}case`target-authored-drag`:{let r=await e(t,n.use);return{performPlan:async(e,t)=>await r.operations.performTargetAuthoredDrag(f(e,t)),...d(r)}}}}function d(e){let{gestureViewport:t}=e.operations,n=e.operations.captureSnapshot?{operations:{captureSnapshot:e.operations.captureSnapshot}}:void 0,r=t?{operations:{gestureViewport:t}}:void 0;return Object.freeze({...n?{captureSnapshot:async e=>await n.operations.captureSnapshot(e)}:{},...r?{gestureViewport:async e=>await r.operations.gestureViewport(p(e))}:{}})}function f(e,t){return{plan:e,...t.appBundleId===void 0?{}:{options:{appBundleId:t.appBundleId}},execution:i(t)}}function p(e){return{...e.appBundleId===void 0?{}:{options:{appBundleId:e.appBundleId}},execution:i(e)}}export{c as n,l as t};
|
package/dist/src/helper.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime.js";import{P as t}from"./sdk-contracts.js";import{
|
|
2
|
-
`),await g(`swift`,[`build`,`-c`,`release`,`--package-path`,t],{cwd:t,timeoutMs:12e4}),await ee(C);let l=`${o}.tmp`;return await te(c,l),await m(l,o),await f(o,493),await s(w,`${JSON.stringify({fingerprint:
|
|
1
|
+
import{r as e}from"./rolldown-runtime.js";import{P as t}from"./sdk-contracts.js";import{b as n,f as r,k as i}from"./owner-identity.js";import{s as a,u as o}from"./exec.js";import"./command.js";import"./process.js";import{D as s,c,f as l,g as u,h as d,n as f,o as ee,r as te,t as p,w as m,y as h}from"./host-file.js";import{a as g,i as _,n as v}from"./tool-provider.js";import{createHash as ne}from"node:crypto";import y from"node:path";import{fileURLToPath as re}from"node:url";var b=e({MACOS_HELPER_REFUSAL_REASONS:()=>A,macOsClickScheduleMs:()=>J,quitMacOsApp:()=>U,resolveFrontmostMacOsApp:()=>H,resolveMacOsHelperPackageRootFrom:()=>j,runMacOsAlertAction:()=>G,runMacOsFillAction:()=>Z,runMacOsPermissionAction:()=>W,runMacOsPressAction:()=>Y,runMacOsReadTextAction:()=>q,runMacOsScreenshotAction:()=>$,runMacOsScrollAction:()=>Q,runMacOsSnapshotAction:()=>K,runMacOsTypeAction:()=>X,startMacOsAudioProbeProcess:()=>z});const x=`agent-device-macos-helper`,S=`AGENT_DEVICE_MACOS_HELPER_BIN`,C=y.join(l(),`.agent-device`,`macos-helper`,`current`),w=y.join(C,`manifest.json`),T=/^[A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)+$/;function E(e){let n=e.trim();if(!T.test(n))throw new t(`INVALID_ARGS`,`macOS bundle id must use reverse-DNS form like com.example.App`,{bundleId:e});return n}function D(e,t){t.bundleId&&e.push(`--bundle-id`,E(t.bundleId)),t.surface&&e.push(`--surface`,t.surface)}function O(e,t){t===`app`&&n(`AGENT_DEVICE_MACOS_GHOST_CURSOR`)?.trim()!==`0`&&e.push(`--ghost-cursor`)}function k(e){return e.includes(`--ghost-cursor`)?1e3:0}const A=[`background-pointer-gesture`,`no-accessible-target`,`no-settable-text-input`,`no-scroll-bar`];function j(e){let n=y.dirname(e);for(;;){let e=y.join(n,`apple`,`macos-helper`);if(c(y.join(e,`Package.swift`)))return e;let t=y.dirname(n);if(t===n)break;n=t}throw new t(`COMMAND_FAILED`,`Unable to locate macOS helper package root`,{modulePath:e})}function M(){return j(re(import.meta.url))}function N(){return y.join(M(),`.build`,`release`,x)}function ie(){return y.join(C,x)}async function P(e){let t=await u(e,{withFileTypes:!0});return(await Promise.all(t.map(async t=>{let n=y.join(e,t.name);return t.isDirectory()?t.name===`.build`?[]:await P(n):!t.isFile()||!t.name.endsWith(`.swift`)&&t.name!==`Package.swift`?[]:[n]}))).flat().sort()}async function F(e){let t=await P(e),n=ne(`sha256`);for(let r of t)n.update(y.relative(e,r)),n.update(`\0`),n.update(await d(r)),n.update(`\0`);let r=await g(`swift`,[`--version`],{allowFailure:!0,cwd:e,timeoutMs:1e4});return n.update(`swift-version`),n.update(`\0`),n.update(r.stdout||r.stderr||`exit:${r.exitCode}`),n.update(`\0`),n.digest(`hex`)}async function I(){try{let e=JSON.parse(await h(w));return typeof e.fingerprint==`string`?e.fingerprint:null}catch{return null}}async function L(){let e=await a(n(S),S);if(e)return e;let t=M(),r=await F(t),o=ie();try{if(await I()===r)return await p(o),o}catch{}let c=N();i(`agent-device: building macOS helper (first run or helper update)
|
|
2
|
+
`),await g(`swift`,[`build`,`-c`,`release`,`--package-path`,t],{cwd:t,timeoutMs:12e4}),await ee(C);let l=`${o}.tmp`;return await te(c,l),await m(l,o),await f(o,493),await s(w,`${JSON.stringify({fingerprint:r},null,2)}\n`),o}async function R(){let e=n(S)?.trim();if(e){let t=await a(e,S);if(t)return t}if(v())return x;if(r()!==`darwin`)throw new t(`UNSUPPORTED_PLATFORM`,`macOS helper is only available on macOS`);return await L()}async function z(e){let t=await R();return o(t,[`audio-probe`,`--duration-ms`,String(e.durationMs),`--bucket-ms`,String(e.bucketMs),`--out`,e.statusPath],{allowFailure:!0,captureOutput:!0})}const B=3e4;async function V(e,n={}){let r={allowFailure:!0,timeoutMs:n.timeoutMs??B,signal:n.signal,kill:{signal:`SIGTERM`,graceMs:1e3}},i=_().macosHelper,a=i?x:await R(),o=i?await i.run(e,r):await g(a,e,r),s=o.stdout.trim(),c=null;if(s)try{c=JSON.parse(s)}catch{c=null}if(o.exitCode===0&&c?.ok)return c.data;let l=c&&!c.ok?c.error?.message??`macOS helper exited with code ${o.exitCode}`:s||o.stderr.trim()||`macOS helper exited with code ${o.exitCode}`;throw new t(`COMMAND_FAILED`,l,{helperPath:a,args:e,stdout:o.stdout,stderr:o.stderr,exitCode:o.exitCode,...c&&!c.ok?c.error?.details:{}})}async function H(){return await V([`app`,`frontmost`])}async function U(e){return await V([`app`,`quit`,`--bundle-id`,E(e)])}async function W(e,t){return await V([`permission`,e,t])}async function G(e,t={}){let n=[`alert`,e];return D(n,t),await V(n)}async function K(e,t={}){let n=[`snapshot`,`--surface`,e];return D(n,t),await V(n,{signal:t.signal})}async function q(e,t,n){let r=[`read`,`--x`,String(e),`--y`,String(t)];return D(r,n),await V(r,{signal:n.signal})}function J(e){let t=e.holdMs&&e.holdMs>0?Math.max(e.holdMs,40):60,n=Math.max(e.clicks??1,1),r=Math.max(e.intervalMs??120,0);return n*(e.doubleClick?2*t+80:t)+(n-1)*r}async function Y(e,t,n){let r=[`press`,`--x`,String(e),`--y`,String(t)];n.holdMs&&n.holdMs>0&&r.push(`--hold-ms`,String(n.holdMs));let i=n.clicks??1;return i>1&&(r.push(`--clicks`,String(i)),n.intervalMs!==void 0&&r.push(`--interval-ms`,String(Math.max(n.intervalMs,0)))),n.doubleClick&&r.push(`--double-click`),D(r,n),O(r,n.surface),await V(r,{signal:n.signal,timeoutMs:J(n)+B+k(r)})}async function X(e,t){let n=[`type`,`--text`,e];return t.delayMs&&t.delayMs>0&&n.push(`--delay-ms`,String(t.delayMs)),D(n,{bundleId:t.bundleId}),O(n,`app`),await V(n,{signal:t.signal,timeoutMs:B+k(n)+e.length*(t.delayMs??0)})}async function Z(e,t,n,r){let i=[`fill`,`--x`,String(e),`--y`,String(t),`--text`,n];return D(i,{bundleId:r.bundleId}),O(i,`app`),await V(i,{signal:r.signal,timeoutMs:B+k(i)})}async function Q(e,t){let n=[`scroll`,`--direction`,e];return t.amount!==void 0&&n.push(`--amount`,String(t.amount)),t.pixels!==void 0&&n.push(`--pixels`,String(t.pixels)),D(n,{bundleId:t.bundleId}),O(n,`app`),await V(n,{signal:t.signal,timeoutMs:B+k(n)})}async function $(e,t){let n=[`screenshot`,`--out`,e];return D(n,t),await V(n,{signal:t.signal})}export{G as a,Y as c,X as d,z as f,H as i,$ as l,b as n,Z as o,U as r,W as s,A as t,Q as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{P as e}from"./sdk-contracts.js";import{r as t}from"./request-cancel.js";import"./request.js";import{
|
|
1
|
+
import{P as e}from"./sdk-contracts.js";import{r as t}from"./request-cancel.js";import"./request.js";import{ut as n}from"./internal/daemon.js";async function r(n){let{req:r,registry:s}=n,c=r.internal?.admittedLease;if(!c)throw new e(`UNAUTHORIZED`,`Human control requires an admitted remote lease.`);let l={kind:`lease`,leaseId:c.leaseId},u=r.positionals??[],[d,f=``,p=``]=u;switch(d){case`list`:return a(u,1),{ok:!0,data:{holds:s.listHumanControlHolds(l)}};case`put`:return a(u,3),{ok:!0,data:{hold:await s.putHumanControlHold(l,f,i(p),t(r.meta?.requestId)),state:`active`}};case`remove`:{a(u,2);let e=s.removeHumanControlHold(l,f);return{ok:!0,data:{released:!!e,...e?{hold:e}:{}}}}default:throw o()}}function i(t){let r;try{r=JSON.parse(t)}catch(t){throw new e(`INVALID_ARGS`,`Human-control payload must be valid JSON.`,void 0,t)}return n(r)}function a(e,t){if(e.length!==t)throw o()}function o(){return new e(`INVALID_ARGS`,`human_control requires list, put <id> <payload>, or remove <id>.`)}export{r as handleHumanControlCommand};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{K as e}from"./sdk-contracts.js";import{a as t,d as n,h as r,o as i}from"./adb-executor.js";import{_ as a,i as o,l as s}from"./ime-state.js";import{c,i as l,r as u}from"./ime-settings-record.js";async function d(u){let d=o(u);return d?await s(d.stateDir,u.id,async()=>{if(o(u)!==d)return{kind:`not-owned`};let s=t(u),{manifest:m}=await a(i(u));r({level:`warn`,phase:`android_test_ime_rebind`,data:{device:u.id}}),d.rebindUnconfirmed=!0;let h=`record-write`;try{if(!await c(s))return f(u.id,h);h=`command-failed`;for(let e of[`disable`,`enable`,`set`])if((await n(s,[`ime`,e,m.serviceComponent],{allowFailure:!0,timeoutMs:1e4})).exitCode!==0)return f(u.id,h);h=`read-failed`;let e=await l(s);return e===m.serviceComponent?(d.rebindUnconfirmed=!await p(s,u.id),{kind:`confirmed`}):f(u.id,e?`helper-not-selected`:`read-failed`)}catch(t){if(e(t))throw t}return f(u.id,h)}):{kind:`not-owned`}}function f(e,t){return r({level:`warn`,phase:`android_test_ime_rebind_failed`,data:{device:e,cause:t}}),{kind:`unconfirmed`,cause:t}}async function p(e,t){let n=await u(e);return n||r({level:`warn`,phase:`android_test_ime_rebind_record_clear_failed`,data:{device:t}}),n}export{d as rebindAndroidTestIme};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{J as e}from"./sdk-contracts.js";import{d as t,h as n}from"./adb-executor.js";const r=`agent_device_ime_helper_previous_ime`,i=`agent_device_ime_helper_rebind_displaced`,a=`secure`,o=`default_input_method`,s={previousIme:r,rebindDisplaced:i,defaultInputMethod:o};async function c(e){let n=await t(e,[`settings`,`get`,a,o],{allowFailure:!0,timeoutMs:5e3});return v(n.exitCode===0?n.stdout:``)}async function l(e){return await _(e,r)||void 0}async function u(e,n){return(await t(e,[`settings`,`put`,a,r,n],{allowFailure:!0,timeoutMs:5e3})).exitCode===0&&await l(e)===n}async function d(e){await t(e,[`settings`,`delete`,a,r],{allowFailure:!0,timeoutMs:5e3})}async function f(e){let t=await _(e,r),n=await _(e,i);if(t===void 0||n===void 0)return{kind:`unreadable`};let a=n===`1`;return t?{kind:`owned`,previousIme:t,rebindDisplaced:a}:{kind:`absent`,rebindDisplaced:a}}async function p(e){return(await t(e,[`settings`,`put`,a,i,`1`],{allowFailure:!0,timeoutMs:5e3})).exitCode===0&&await _(e,i)===`1`}async function m(e){return await t(e,[`settings`,`delete`,a,i],{allowFailure:!0,timeoutMs:5e3}),await _(e,i)===``}async function h(t,r,i){try{(r?await u(t,r):await g(t))||n({level:`warn`,phase:`android_test_ime_record_rollback_failed`,data:{device:i,hadPriorRecord:r!==void 0}})}catch(t){n({level:`warn`,phase:`android_test_ime_record_rollback_failed`,data:{device:i,hadPriorRecord:r!==void 0,error:e(t).message}})}}async function g(e){return await d(e),await l(e)===void 0}async function _(e,n){let r=await t(e,[`settings`,`get`,a,n],{allowFailure:!0,timeoutMs:5e3});return r.exitCode===0?v(r.stdout):void 0}function v(e){let t=e.trim();return!t||t===`null`?``:t}export{f as a,p as c,c as i,d as n,h as o,m as r,u as s,s as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{P as e}from"./sdk-contracts.js";import{i as t}from"./retry.js";import"./retry2.js";import{d as n,g as r}from"./adb-executor.js";import{c as i,n as a}from"./adb-failure.js";import{t as o}from"./keyed-lock.js";function s(t,n,r){if(typeof t!=`number`||!Number.isInteger(t))throw new e(`INVALID_ARGS`,`Android ${r} manifest ${n} must be an integer.`);return t}function c(t,n,r,i){if(t!==r)throw new e(`INVALID_ARGS`,`Android ${i} manifest ${n} must be "${r}".`);return r}function l(t,n,r){if(typeof t!=`string`||t.length===0)throw new e(`INVALID_ARGS`,`Android ${r} manifest ${n} is required.`);return t}function u(t,n){let r=l(t,`sha256`,n).trim().toLowerCase();if(r.length!==64||!/^[0-9a-f]+$/.test(r))throw new e(`INVALID_ARGS`,`Android ${n} manifest sha256 must be a 64-character hex string.`);return r}const d=`com.callstack.agentdevice.imehelper`,f=`com.callstack.agentdevice.imehelper/.TestInputMethodService`,p=`android-ime-helper-v1`,m=f;async function h(e){return e.imeHelperArtifact??await g()}async function g(){return await r().resolveHelperArtifact({helperDirName:`ime-helper`,manifestFileName:e=>`agent-device-android-ime-helper-${e}.manifest.json`,parseManifest:v,unavailableMessage:`Android test IME text entry requires the bundled Android IME helper artifact, but it was not found or could not be read`})}const _=`IME helper`;function v(t){if(!t||typeof t!=`object`||Array.isArray(t))throw new e(`INVALID_ARGS`,`Android IME helper manifest must be an object.`);let n=t;return{name:c(n.name,`name`,`android-ime-helper`,_),version:l(n.version,`version`,_),assetName:l(n.assetName,`assetName`,_),sha256:u(n.sha256,_),packageName:c(n.packageName,`packageName`,d,_),versionCode:s(n.versionCode,`versionCode`,_),serviceComponent:c(n.serviceComponent,`serviceComponent`,f,_),broadcastProtocol:c(n.broadcastProtocol,`broadcastProtocol`,p,_)}}const y=new Set;async function b(e){return await r().ensureHelperInstalled({cache:y,installTimeoutMs:3e4,helperLabel:`Android IME helper`},e)}function x(){y.clear()}function S(e){return`${e.platform}:${e.id}`}function C(e){return e===d}async function w(e,t,n){await E(e,t,`com.callstack.agentdevice.imehelper.ACTION_INPUT_TEXT_B64`,{text:Buffer.from(n,`utf8`).toString(`base64`)})}async function T(e,t){await E(e,t,`com.callstack.agentdevice.imehelper.ACTION_CLEAR_TEXT`,{})}async function E(e,t,r,o){let s=[`am`,`broadcast`,`-p`,t,`-a`,r];s.push(`--es`,`protocol`,p);for(let[e,t]of Object.entries(o))s.push(`--es`,e,t);try{let i=await n(e,s,{allowFailure:!0,timeoutMs:1e4});if(i.exitCode!==0)throw a(`Android IME helper broadcast failed`,i,{action:r,packageName:t})}catch(e){throw i(e)}}const D=new Map,O=new Map;function k(e){let t=O.get(e);t||(t=new Set,O.set(e,t));let n,r=new Promise(e=>{n=e});return t.add(r),()=>{t.delete(r),t.size===0&&O.get(e)===t&&O.delete(e),n()}}function A(e){let t=O.get(e);if(!(!t||t.size===0))return Promise.allSettled(t).then(()=>void 0)}async function j(e,t){if(!t){await e;return}await new Promise(n=>{let r=()=>{t.removeEventListener(`abort`,r),n()};t.addEventListener(`abort`,r,{once:!0}),e.then(r,r)})}function M(e,t){let n=D.get(e)?.atPerfMs??0;D.set(e,{atPerfMs:Math.max(n,performance.now()),confirmed:t})}async function N(e,t){if(t?.aborted)return`aborted`;for(;;){let n=await P(e,t);if(n!==`extended`)return n}}async function P(e,n){if(!await F(e,n))return`aborted`;let r=D.get(e);if(r===void 0)return`idle`;let i=r.atPerfMs+2500-performance.now();return i>0&&(await t(i,n),n?.aborted)?`aborted`:I(e,r)}async function F(e,t){let n=A(e);return!n||(await j(n,t),!t?.aborted)}function I(e,t){if(A(e))return`extended`;let n=D.get(e);return n===void 0||n===t?(D.delete(e),t.confirmed?`covered-confirmed`:`covered-issued`):`extended`}const L=new Map,R=new Map;function z(e){return L.has(S(e))}function B(e){return L.get(S(e))}function V(e,t,n){return o(R,`${e}:${t}`,n)}function H(){L.clear(),D.clear(),O.clear()}function U(e,t,n=`/state`){let r=S(e);t?L.set(r,{stateDir:n,rebindUnconfirmed:!1}):L.delete(r)}export{h as _,z as a,c as b,U as c,T as d,b as f,g,x as h,B as i,V as l,C as m,N as n,M as o,S as p,k as r,H as s,L as t,m as u,w as v,s as y};
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { $ as normalizeAgentDeviceError, A as RawSnapshotNode, F as SnapshotNode, G as AppErrorCode, J as ErrorCause, K as AppErrorDetails, Q as isAgentDeviceError, U as centerOfRect, W as AppError, X as NormalizedError, Y as KnownAppErrorCode, j as Rect, k as Point, y as AppleOS, z as SnapshotState } from "./sdk-contracts.js";
|
|
2
|
+
import { t as AppsFilter } from "./app-inventory.js";
|
|
3
3
|
import { $ as NetworkOptions, $t as AppTriggerEventOptions, A as WaitCommandOptions, At as ElementTarget, B as GetOptions, Bt as FindSnapshotCommandOptions, C as HomeCommandOptions, Cn as isRecord, Ct as RotateGestureOptions, D as ReactNativeCommandOptions, Dt as SwipeOptions, E as PrepareCommandOptions, Et as SwipeGestureOptions, F as SessionCloseResult, Ft as CaptureDiffOptions, G as CommandRequestResult, Gt as AppDeployResult, H as IsStatePredicateOptions, Ht as AppCloseOptions, I as SessionSaveScriptOptions, It as CaptureScreenshotOptions, J as ReplayRunOptions, Jt as AppInstallOptions, K as BatchRunOptions, Kt as AppInstallFromSourceOptions, L as SessionSaveScriptResult, Lt as CaptureScreenshotResult, M as AlertAction, Mt as PointTarget, N as PermissionTarget, Nt as RefTarget, O as TvRemoteCommandOptions, Ot as TransformGestureOptions, P as SettingsUpdateOptions, Pt as SelectorTarget, Q as LogsOptions, Qt as AppPushOptions, R as FindBaseOptions, Rt as CaptureSnapshotOptions, S as FoldCommandOptions, Sn as JsonValue, St as RepeatedPressOptions, T as OrientationCommandOptions, Tt as SettleCommandOptions, U as IsTextPredicateOptions, Ut as AppCloseResult, V as IsOptions, Vt as SelectorSnapshotCommandOptions, W as RecordControlOptions, Wt as AppDeployOptions, X as AudioOptions, Xt as AppOpenOptions, Y as ReplayTestOptions, Yt as AppListOptions, Z as EventsOptions, Zt as AppOpenResult, _ as AppStateCommandOptions, _n as AgentDeviceSelectionOptions, _t as LongPressOptions, a as WaitCommandResult, an as AgentDeviceCapabilitiesResult, at as HumanControlHoldOptions, b as ClipboardCommandOptions, bn as JsonObject, bt as PressOptions, c as DebugSymbolsOptions, cn as AgentDeviceSessionDevice, ct as LeaseAllocateOptions, d as PrepareCommandResult, dn as StartupPerfSample, dt as ClickOptions, en as DeviceSelectionMetadata, et as PerfOptions, f as ReplayCommandResult, fn as AgentDeviceClientConfig, ft as DragOptions, g as AlertCommandOptions, gn as AgentDeviceRequestOverrides, gt as HoverOptions, h as ActionButtonCommandOptions, hn as AgentDeviceIdentifiers, ht as FocusOptions, i as TraceCommandResult, in as MaterializationReleaseResult, it as HumanControlHold, j as WaitCommandTarget, jt as InteractionTarget, k as ViewportCommandOptions, kt as TypeTextOptions, l as DebugSymbolsResult, ln as DeviceBootOptions, lt as LeaseOptions, m as TriggerAppEventCommandResult, mn as AgentDeviceDaemonTransportContext, mt as FlingOptions, n as AgentDeviceCommandClient, nn as DeviceSelectionSource, nt as TraceOptions, o as DiffSnapshotCommandResult, on as AgentDeviceDevice, ot as HumanControlHoldScope, p as ReplaySuiteResult, pn as AgentDeviceDaemonTransport, pt as FillOptions, q as BatchStep, qt as AppInstallFromSourceResult, r as RecordingCommandResult, rn as MaterializationReleaseOptions, rt as CloudArtifactsOptions, s as DoctorCommandResult, sn as AgentDeviceSession, st as Lease, t as AgentDeviceClient, tn as DeviceSelectionReason, tt as RecordOptions, u as PushCommandResult, un as DeviceShutdownOptions, ut as LeaseScopedOptions, v as AppSwitcherCommandOptions, vn as DeviceCommandBaseOptions, vt as PanOptions, w as KeyboardCommandOptions, wt as ScrollOptions, x as DoctorCommandOptions, xn as JsonPrimitive, xt as ReadinessBudgetOptions, y as BackCommandOptions, yn as TargetShutdownResult, yt as PinchOptions, z as FindOptions, zt as CaptureSnapshotResult } from "./client-types.js";
|
|
4
|
-
import {
|
|
4
|
+
import { i as CloudProviderSessionResult, t as AgentArtifactsResult } from "./cloud-artifacts.js";
|
|
5
5
|
import { c as MetroPrepareResult, l as MetroReloadOptions, p as MetroBridgeScope, s as MetroPrepareOptions, u as MetroReloadResult } from "./sdk-remote-config.js";
|
|
6
6
|
import { t as BatchRunResult } from "./sdk-batch-runner.js";
|
|
7
7
|
import { p as createLocalArtifactAdapter } from "./sdk-io.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{P as e}from"./sdk-contracts.js";import{d as t}from"./scroll-gesture.js";import{
|
|
1
|
+
import{P as e}from"./sdk-contracts.js";import{d as t}from"./scroll-gesture.js";import{i as n}from"./retry.js";import"./retry2.js";import{runHarmonyShell as r}from"./hdc.js";import{invalidateHarmonyGestureViewport as i,readHarmonyGestureViewport as a}from"./snapshot2.js";async function o(e,t,n){await r(e,[`uitest`,`uiInput`,`click`,t,n])}async function s(e,t,n){await r(e,[`uitest`,`uiInput`,`doubleClick`,t,n])}async function c(e,t,n,i=800){await r(e,[`uitest`,`uiInput`,`longClick`,t,n])}async function l(e,t,i=0){await r(e,[`uitest`,`uiInput`,`text`,t]),i>0&&await n(i)}async function u(e,t,i,a,o=0){await r(e,[`uitest`,`uiInput`,`inputText`,t,i,a]),o>0&&await n(o)}async function d(e,n,i){let o=await a(e),s=t({direction:n,amount:i?.amount,pixels:i?.pixels,referenceWidth:o.width,referenceHeight:o.height});return await r(e,[`uitest`,`uiInput`,`swipe`,s.x1,s.y1,s.x2,s.y2,i?.durationMs??300]),s}async function f(t,n){if(n.topology!==`single`)throw new e(`UNSUPPORTED_OPERATION`,`HarmonyOS HDC does not support multi-touch gestures`);let i=n.pointers[0].samples,a=i[0],o=i.at(-1);if(!a||!o)throw new e(`COMMAND_FAILED`,`HarmonyOS gesture plan has no pointer endpoints`);let s=Math.hypot(o.point.x-a.point.x,o.point.y-a.point.y),c=Math.max(200,Math.min(4e4,Math.round(s/n.durationMs*1e3))),l=n.intent===`fling`?`fling`:`swipe`;return await r(t,[`uitest`,`uiInput`,l,Math.round(a.point.x),Math.round(a.point.y),Math.round(o.point.x),Math.round(o.point.y),c]),{backend:`harmonyos-hdc-uiinput`,command:l,velocity:c,viewport:n.viewport}}async function p(e){await r(e,[`uitest`,`uiInput`,`keyEvent`,`Back`]),i(e)}async function m(e){await r(e,[`uitest`,`uiInput`,`keyEvent`,`Home`]),i(e)}async function h(e){await r(e,[`uitest`,`uiInput`,`keyEvent`,`Recent`]),i(e)}async function g(e,t){if(t===`Back`){await p(e);return}await r(e,[`uitest`,`uiInput`,`keyEvent`,t])}async function _(t,n){throw new e(`UNSUPPORTED_OPERATION`,`HarmonyOS orientation control is not available through the public HDC API.`)}export{h as appSwitcherHarmony,p as backHarmony,s as doubleClickHarmony,u as fillHarmony,m as homeHarmony,c as longPressHarmony,f as performHarmonyGesture,o as pressHarmony,g as pressHarmonyKeyboardKey,d as scrollHarmony,_ as setHarmonyOrientation,l as typeHarmony};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{B as e,P as t}from"./sdk-contracts.js";import{t as n}from"./scroll-gesture.js";import{l as r}from"./owner-identity.js";import{
|
|
1
|
+
import{B as e,P as t}from"./sdk-contracts.js";import{t as n}from"./scroll-gesture.js";import{l as r}from"./owner-identity.js";import{i}from"./retry.js";import"./process.js";import"./retry2.js";import{t as a}from"./tool-provider2.js";function o(){let e=r();return e.WAYLAND_DISPLAY||e.XDG_SESSION_TYPE===`wayland`?`wayland`:`x11`}let s=null;async function c(){let e=a();if(s?.provider===e)return s;let n=o();if(n===`wayland`){if(await e.whichCommand(`ydotool`))return s={tool:`ydotool`,display:n,provider:e},s;throw new t(`TOOL_MISSING`,`ydotool is required for input synthesis on Wayland (xdotool does not work on Wayland). Install it via your package manager.`)}if(await e.whichCommand(`xdotool`))return s={tool:`xdotool`,display:n,provider:e},s;throw new t(`TOOL_MISSING`,`xdotool is required for input synthesis on X11. Install it via your package manager.`)}const l=1e4;async function u(...e){await a().runCommand(`xdotool`,e,{allowFailure:!1,timeoutMs:l})}async function d(...e){await a().runCommand(`ydotool`,e,{allowFailure:!1,timeoutMs:l})}function f(){return a().input}async function p(e,t){let{tool:n}=await c();if(n===`xdotool`){if(await m(e,t))return;await u(`mousemove`,`--sync`,String(e),String(t))}else await d(`mousemove`,`--absolute`,`-x`,String(e),`-y`,String(t))}async function m(e,t){try{let n=await a().runCommand(`xdotool`,[`getmouselocation`,`--shell`],{allowFailure:!0,timeoutMs:l}),r=new Map(n.stdout.split(`
|
|
2
2
|
`).map(e=>e.trim().split(`=`)).filter(e=>e.length===2).map(([e,t])=>[e,Number(t)]));return r.get(`X`)===Math.round(e)&&r.get(`Y`)===Math.round(t)}catch{return!1}}async function h(e,t){let n=f();if(n){await n.key(e,t);return}let{tool:r}=await c();r===`xdotool`?await u(`key`,`--clearmodifiers`,e):await d(`key`,...t)}async function g(e,t,n,r){await p(e,t);let{tool:i}=await c();i===`xdotool`?await u(`click`,n):await d(`click`,r)}async function _(e,t,n,r,i){let a=f();if(a){await a.click(e,t,n);return}await g(e,t,r,i)}async function v(e,t){await _(e,t,`primary`,`1`,`0xC0`)}async function y(e,t){await _(e,t,`secondary`,`3`,`0xC1`)}async function b(e,t){await _(e,t,`middle`,`2`,`0xC2`)}async function x(e,t){let n=f();if(n){await n.doubleClick(e,t);return}let{tool:r}=await c();await p(e,t),r===`xdotool`?await u(`click`,`--repeat`,`2`,`1`):(await d(`click`,`0xC0`),await d(`click`,`0xC0`))}async function S(e,t,n=800){let r=f();if(r){await r.longPress(e,t,n);return}let{tool:a}=await c();await p(e,t),a===`xdotool`?(await u(`mousedown`,`1`),await i(n),await u(`mouseup`,`1`)):(await d(`click`,`--down`,`0xC0`),await i(n),await d(`click`,`--up`,`0xC0`))}async function C(e,t){await v(e,t)}async function w(e,t,n,r,a=300){let o=f();if(o){await o.drag(e,t,n,r,a);return}let{tool:s}=await c();await p(e,t),s===`xdotool`?(await u(`mousedown`,`1`),await u(`mousemove`,`--sync`,String(n),String(r)),await i(a),await u(`mouseup`,`1`)):(await d(`click`,`--down`,`0xC0`),await d(`mousemove`,`--absolute`,`-x`,String(n),`-y`,String(r)),await i(a),await d(`click`,`--up`,`0xC0`))}async function T(e,t){let r=f();if(r)return await r.scroll(e,t),D(t);let{tool:i}=await c(),a=5;if(t?.pixels==null?t?.amount!=null&&(a=Math.max(1,Math.round(5*(t.amount/n)))):a=i===`xdotool`?Math.max(1,Math.round(t.pixels/15)):Math.max(1,Math.round(t.pixels/40)),i===`xdotool`){let n=e===`up`?`4`:e===`down`?`5`:e===`left`?`6`:`7`;await E(a,t?.durationMs,async e=>{await u(`click`,`--repeat`,String(e),n)})}else e===`up`||e===`down`?await E(a,t?.durationMs,async t=>{await d(`mousemove`,`--wheel`,`-y`,String(e===`up`?-t:t))}):await E(a,t?.durationMs,async t=>{await d(`mousemove`,`--wheel`,`-x`,String(e===`left`?-t:t))});return D(t)}async function E(t,n,r){if(n===void 0||n<=0||t<=1){await r(t);return}let a=n/Math.max(1,t-1),o=0;try{for(let e=0;e<t;e+=1)await r(1),o+=1,e<t-1&&await i(a)}catch(t){throw e(t,o)}}function D(e){return e?.durationMs===void 0?{}:{durationMs:e.durationMs}}async function O(e,t=0){let n=f();if(n){await n.typeText(e,{delayMs:t});return}let{tool:r}=await c();if(r===`xdotool`){let n=[`type`];t>0&&n.push(`--delay`,String(t)),n.push(`--clearmodifiers`,`--`,e),await u(...n)}else await d(`type`,`--`,e)}async function k(e,t,n,r=0){if(await v(e,t),await i(100),await h(`ctrl+a`,[`29:1`,`30:1`,`30:0`,`29:0`]),await i(50),n.length===0){await h(`BackSpace`,[`14:1`,`14:0`]);return}await O(n,r)}export{x as doubleClickLinux,k as fillLinux,C as focusLinux,S as longPressLinux,b as middleClickLinux,v as pressLinux,y as rightClickLinux,T as scrollLinux,h as sendKey,w as swipeLinux,O as typeLinux};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{I as e,P as t}from"./sdk-contracts.js";import{t as n}from"./path-resolution.js";import"./file.js";import{a as r,i,n as a,r as o}from"./archive.js";import{t as s}from"./byte-limit-stream.js";import{r as c,t as
|
|
1
|
+
import{I as e,P as t}from"./sdk-contracts.js";import{t as n}from"./path-resolution.js";import"./file.js";import{a as r,i,n as a,r as o}from"./archive.js";import{t as s}from"./byte-limit-stream.js";import{r as c,t as l}from"./install-source-network-transport.js";import{AsyncLocalStorage as u}from"node:async_hooks";import{createWriteStream as ee,promises as d}from"node:fs";import f from"node:os";import p from"node:path";import{pipeline as m}from"node:stream/promises";function h(e,t){return{archivePath:t.archivePath,...t.containingArchivePath?{containingArchivePath:t.containingArchivePath}:{},installablePath:e}}async function g(e,n){let r=await d.stat(e).catch(()=>null);if(!r)throw new t(`INVALID_ARGS`,`App source not found: ${e}`);if(n.isInstallablePath(e,r))return h(e,n);if(r.isFile()&&b(e))return await _(e,n);if(r.isDirectory()){let r=await y(e,n.isInstallablePath);if(r.length===1)return h(r[0],n);if(r.length>1)throw new t(`INVALID_ARGS`,`Found multiple ${n.installableLabel} candidates under ${e}: ${r.join(`, `)}`,{matches:r});let i=await y(e,(e,t)=>!!(t.isFile()&&b(e)));if(i.length===1)return await _(i[0],n);if(i.length>1)throw new t(`INVALID_ARGS`,`Found multiple nested archives under ${e}; expected one ${n.installableLabel} source`,{matches:i})}throw new t(`INVALID_ARGS`,`Expected ${n.installableLabel} source, but got ${e}`)}async function _(e,t){let n=await v(e,t.budget,t.archiveDepth+1);return t.onArchiveAccepted?.(t.archiveDepth+1),t.registerCleanup(n.cleanup),await g(n.outputPath,{...t,archivePath:t.archivePath??e,containingArchivePath:e,archiveDepth:t.archiveDepth+1})}async function v(e,n,r){let i=a(e);if(!i)throw new t(`INVALID_ARGS`,`Unsupported archive: ${e}`);let s=await d.mkdtemp(p.join(f.tmpdir(),`agent-device-archive-`)),c=p.join(s,`extracted`);try{return await o({archivePath:e,outputRoot:c,type:i,budget:n,depth:r}),{outputPath:c,cleanup:async()=>await d.rm(s,{recursive:!0,force:!0})}}catch(e){throw await d.rm(s,{recursive:!0,force:!0}),e}}async function y(e,t){let n=[],r=[{path:e,depth:0}];for(;r.length>0;){let e=r.shift();if(!e)continue;let i=await d.readdir(e.path,{withFileTypes:!0});i.sort((e,t)=>e.name.localeCompare(t.name));for(let a of i){if(a.name===`__MACOSX`||a.name.startsWith(`._`))continue;let i=p.join(e.path,a.name);t(i,a)?n.push(i):a.isDirectory()&&e.depth<5&&r.push({path:i,depth:e.depth+1})}}return[...new Set(n)]}function b(e){return a(e)!==void 0}const x=new u;async function S(e){return await x.run({budget:new i,depth:0},e)}function C(){return x.getStore()?.budget}function w(){return x.getStore()?.depth??0}function T(e){let t=x.getStore();t&&(t.depth=Math.max(t.depth,e))}const E=new Set([301,302,303,307,308]),D=/^[A-Z][A-Z0-9_]{0,63}$/,O=new Set([`accept-encoding`,`connection`,`content-length`,`host`,`keep-alive`,`proxy-connection`,`proxy-authorization`,`te`,`trailer`,`transfer-encoding`,`upgrade`]);async function k(e){let t=V(e.url),n=L(I(e.headers));for(let r=0;;r+=1){let i=await A(t,n,e.signal);try{let a=M(i,t,r);if(a){a.origin!==t.origin&&(n=R(n)),t=a;continue}return N(i),await P(e.tempDir,t,i)}finally{await i.close()}}}async function A(e,n,r){let i=await c(e,r);try{return await l({url:e,approvedAddress:i.address,family:i.family,headers:{...n,"accept-encoding":`identity`},signal:r})}catch(e){if(e instanceof t)throw e;let n=j(e);throw new t(`COMMAND_FAILED`,n?`The daemon failed to fetch the app source (network error code: ${n})`:`The daemon failed to fetch the app source`,n?{networkErrorCode:n}:void 0,e)}}function j(e){let t=e?.code;return typeof t==`string`&&D.test(t)?t:void 0}function M(e,n,r){if(!E.has(e.statusCode))return;e.body.resume?.();let i=B(e.headers,`location`);if(!i||r>=5)throw new t(`COMMAND_FAILED`,`App source redirect limit was exceeded`,{status:e.statusCode});let a=new URL(i,n);if(n.protocol===`https:`&&a.protocol!==`https:`)throw new t(`COMMAND_FAILED`,`App source redirect downgraded HTTPS`);return a}function N(e){if(!(e.statusCode>=200&&e.statusCode<300))throw new t(`COMMAND_FAILED`,`Failed to download app source: ${e.statusCode}`,{status:e.statusCode})}async function P(e,n,i){let a=B(i.headers,`content-encoding`);if(a&&a.toLowerCase()!==`identity`)throw new t(`COMMAND_FAILED`,`App source response used unsupported content encoding`);F(B(i.headers,`content-length`));let o=p.join(e,z(i,n)),c=s({maxBytes:r,createLimitError:()=>new t(`COMMAND_FAILED`,`App source exceeds maximum size of ${r} bytes`,{reason:`ARTIFACT_BYTE_LIMIT`})});try{return await m(i.body,c,ee(o,{flags:`wx`})),o}catch(e){throw await d.rm(o,{force:!0}).catch(()=>{}),e}}function F(e){if(e===null)return;if(!/^\d+$/.test(e))throw new t(`COMMAND_FAILED`,`App source response had invalid content-length`);let n=Number(e);if(!Number.isSafeInteger(n)||n>2147483648)throw new t(`COMMAND_FAILED`,`App source response exceeded the byte limit`,{reason:`ARTIFACT_BYTE_LIMIT`})}function I(e){let t=new Set(Object.entries(e??{}).filter(([e])=>e.toLowerCase()===`connection`).flatMap(([,e])=>e.split(`,`).map(e=>e.trim().toLowerCase())));return Object.fromEntries(Object.entries(e??{}).filter(([e])=>{let n=e.toLowerCase();return!O.has(n)&&!t.has(n)}))}function L(e){return Object.keys(e).some(e=>e.toLowerCase()===`user-agent`)?e:{...e,"user-agent":`agent-device`}}function R(e){return Object.fromEntries(Object.entries(e).filter(([e])=>[`accept`,`user-agent`].includes(e.toLowerCase())))}function z(e,t){let n=(B(e.headers,`content-disposition`)?.match(/filename\*?=(?:UTF-8'')?"?([^";]+)"?/i))?.[1]?.trim()||p.basename(t.pathname)||`downloaded-artifact.bin`;return p.basename(n)}function B(e,t){let n=e[t];return Array.isArray(n)?n[0]??null:n??null}function V(e){let n;try{n=new URL(e)}catch{throw H()}if(n.username||n.password)throw new t(`INVALID_ARGS`,`Source URL credentials are not allowed`);return n}function H(){return new t(`INVALID_ARGS`,`Invalid source URL`)}const U=Object.freeze([`.zip`,`.tar`,`.tar.gz`,`.tgz`]),W=12e4;async function G(e){let t=[];try{let n=await q(e.source,{signal:e.signal});t.push(n.cleanup);let r=await g(n.localPath,{archivePath:void 0,isInstallablePath:e.isInstallablePath,installableLabel:e.installableLabel,registerCleanup:e=>{t.push(e)},budget:C()??new i,archiveDepth:0,onArchiveAccepted:T});return{archivePath:r.archivePath,...r.containingArchivePath?{containingArchivePath:r.containingArchivePath}:{},installablePath:r.installablePath,cleanup:async()=>{await $(t)}}}catch(e){throw await $(t),e}}function K(e){return n(e)}async function q(e,t){if(e.kind===`path`)return{localPath:K(e.path),cleanup:async()=>{}};let n=await d.mkdtemp(p.join(f.tmpdir(),`agent-device-source-`));try{return{localPath:await J(n,e.url,e.headers,t),cleanup:async()=>{await d.rm(n,{recursive:!0,force:!0})}}}catch(e){throw await d.rm(n,{recursive:!0,force:!0}),e}}async function J(t,n,r,i){let a=i?.signal;if(a?.aborted)throw e();let o=AbortSignal.timeout(W),s=a?AbortSignal.any([a,o]):o;try{return await k({tempDir:t,url:n,headers:r,signal:s})}catch(e){throw Y(e,a,o,W)}}function Y(n,r,i,a){return r?.aborted?e(void 0,n):i.aborted?new t(`COMMAND_FAILED`,`App source download timed out after ${a}ms`,{timeoutMs:a},n):n}async function X(e){await c(e)}function Z(e){let t=e instanceof URL?e:URL.parse(e);if(!t)throw H();let n=t.hostname.toLowerCase();if(!n)return!1;let r=t.pathname;return Q(n,r)||te(n,r)}function Q(e,t){return e===`api.github.com`?/^\/repos\/[^/]+\/[^/]+\/actions\/artifacts\/\d+\/zip$/i.test(t):e===`github.com`&&/^\/[^/]+\/[^/]+\/(?:actions\/runs\/\d+\/artifacts\/\d+|suites\/\d+\/artifacts\/\d+)$/i.test(t)}function te(e,t){return e!==`expo.dev`&&!e.endsWith(`.expo.dev`)?!1:/^\/(?:artifacts\/eas\/|accounts\/[^/]+\/projects\/[^/]+\/builds\/)/i.test(t)}async function $(e){for(let t of[...e].reverse())await t()}export{C as a,S as c,X as i,Z as n,w as o,G as r,T as s,U as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime.js";import{a as t,b as n,c as r,f as i,i as a,m as o,n as s,p as c,r as l,s as u,t as d,u as f}from"./session-stream.js";import{execFile as p}from"node:child_process";import m from"fs";import{Readable as h}from"stream";import g from"os";import _ from"path";import v from"crypto";const y=/^[0-9a-f]{64}$/i,b=/^[0-9a-f]{32}$/i;function x(e){return v.createHash(`sha256`).update(e).digest(`hex`).slice(0,32)}function S(e,t){let n=t*e.blockSize;return{offset:n,length:Math.min(e.blockSize,e.fileSize-n)}}async function C(e){return await new Promise((t,n)=>{let r=v.createHash(`sha256`),i=m.createReadStream(e);i.on(`data`,e=>r.update(e)),i.on(`error`,n),i.on(`end`,()=>t(r.digest(`hex`)))})}function w(e,t){if(!e||typeof e!=`object`)throw Error(`Invalid seed signature: expected an object`);let n=e;if(n.version!==1)throw Error(`Unsupported seed signature version: ${String(n.version)}`);if(!Number.isSafeInteger(n.blockSize)||n.blockSize<=0)throw Error(`Invalid seed signature blockSize`);if(!Number.isSafeInteger(n.fileSize)||n.fileSize<0)throw Error(`Invalid seed signature fileSize`);if(typeof n.sha256!=`string`||!y.test(n.sha256)||n.sha256.toLowerCase()!==t.toLowerCase())throw Error(`Seed signature sha256 does not match the requested seed`);if(!Array.isArray(n.blocks))throw Error(`Invalid seed signature blocks`);let r=Math.ceil(n.fileSize/n.blockSize);if(n.blocks.length!==r)throw Error(`Invalid seed signature block count: got ${n.blocks.length}, expected ${r}`);let i=n.blocks.map((e,t)=>{if(!e||!Number.isInteger(e.w)||e.w<0||e.w>4294967295||typeof e.s!=`string`||!b.test(e.s))throw Error(`Invalid seed signature block at index ${t}`);return{w:e.w,s:e.s.toLowerCase()}});return{version:n.version,blockSize:n.blockSize,fileSize:n.fileSize,sha256:n.sha256.toLowerCase(),blocks:i}}async function T(e,t,r){let i=await n.fetch(e,{method:`GET`,headers:{Authorization:`Bearer ${t}`}});if(!i.ok){let e=await i.text();throw Error(`Seed signature download failed: ${i.status} ${e}`)}return w(await i.json(),r)}async function E(e,t,n,r){let i=0;for(;i<n;){let{bytesRead:a}=await e.read(t,i,n-i,r+i);if(a<=0)throw Error(`Unexpected EOF at offset ${r+i}`);i+=a}}async function D(e,t,n,r,i){let a=n.blockSize,o=await m.promises.open(e.path,`r`);try{if(e.size<a||i.size===0)return;let s=Buffer.allocUnsafe(a);await E(o,s,a,0);let c=0,l=0;for(let e=0;e<a;e++){let t=s[e];c=c+t&65535,l=l+(a-e)*t&65535}let u=0,d=0,f,p=async t=>{f??=Buffer.allocUnsafe(a),await E(o,f,a,d);let s=x(f);for(let a of t)i.has(a)&&n.blocks[a].s===s&&(r.set(a,{sourcePath:e.path,sourceOffset:d}),i.delete(a))},m=t.get(l*65536+c);m?.some(e=>i.has(e))&&await p(m);let h=Buffer.allocUnsafe(1048576),g=a;for(;g<e.size&&i.size>0;){let n=Math.min(h.byteLength,e.size-g),{bytesRead:r}=await o.read(h,0,n,g);if(r<=0)break;for(let e=0;e<r&&i.size>0;e++){let n=s[u],r=h[e];s[u]=r,u++,u===a&&(u=0),c=c-n+r&65535,l=l-(a*n&65535)+c&65535,d++,m=t.get(l*65536+c),m?.some(e=>i.has(e))&&await p(m)}g+=r}}finally{await o.close()}}async function O(e){let t=[];for(let n of e){let e=await m.promises.stat(n).catch(()=>void 0);e?.isFile()&&t.push({path:n,size:e.size})}return t}async function k(e,t,n){for(let r of e){let e=await m.promises.open(r.path,`r`),i=Buffer.allocUnsafe(t.blockSize);try{for(let a=0;a<t.blocks.length;a++){if(n.has(a))continue;let o=S(t,a);o.offset+o.length>r.size||(await E(e,i,o.length,o.offset),x(i.subarray(0,o.length))===t.blocks[a].s&&n.set(a,{sourcePath:r.path,sourceOffset:o.offset}))}}finally{await e.close()}}}async function A(e,t,n){if(t.fileSize===0||t.fileSize%t.blockSize===0)return;let r=t.blocks.length-1;if(n.has(r))return;let i=S(t,r),a=t.blocks[r].s,o=Buffer.allocUnsafe(i.length);for(let t of e){if(t.size<i.length)continue;let e=t.size-i.length;if(e===i.offset)continue;let s=await m.promises.open(t.path,`r`);try{if(await E(s,o,i.length,e),x(o)===a){n.set(r,{sourcePath:t.path,sourceOffset:e});return}}finally{await s.close()}}}function j(e,t){let n=0;for(let r=0;r<e.blocks.length;r++)t.has(r)||(n+=S(e,r).length);return(e.blocks.length===0?1:t.size/e.blocks.length)>=.8&&n<=33554432}async function M(e,t,n){let r=Math.floor(t.fileSize/t.blockSize),i=new Set,a=new Map;for(let e=0;e<r;e++){if(n.has(e))continue;i.add(e);let r=t.blocks[e].w,o=a.get(r)??[];o.push(e),a.set(r,o)}for(let r of e){if(i.size===0)return;await D(r,a,t,n,i)}}async function N(e,t){let n=await O(e),r=new Map;return await k(n,t,r),await A(n,t,r),j(t,r)||await M(n,t,r),r}function P(e,t){let n=[],r;for(let i=0;i<=e.blocks.length;i++){let a=i<e.blocks.length&&!t.has(i);if(a&&r===void 0)r=i;else if(!a&&r!==void 0){let t=S(e,r),a=S(e,i-1);n.push({start:t.offset,end:a.offset+a.length-1}),r=void 0}}return n}async function F(e,t,n){let r=new Map;try{for(let[i,a]of n){let n=r.get(a.sourcePath);n||(n=await m.promises.open(a.sourcePath,`r`),r.set(a.sourcePath,n));let o=S(t,i),s=Buffer.allocUnsafe(o.length);await E(n,s,o.length,a.sourceOffset),await I(e,s,o.offset)}}finally{await Promise.all([...r.values()].map(e=>e.close()))}}async function I(e,t,n){let r=0;for(;r<t.byteLength;){let{bytesWritten:i}=await e.write(t,r,t.byteLength-r,n+r);if(i<=0)throw Error(`Unable to write reconstructed seed at offset ${n+r}`);r+=i}}async function L(e,t,r,i,a,o){let s=await n.fetch(e,{method:`GET`,headers:{Authorization:`Bearer ${t}`,Range:`bytes=${r.start}-${r.end}`}});if(s.status!==206||!s.body){let e=await s.text();throw Error(`Seed range download failed: ${s.status} ${e}`)}let c=`bytes ${r.start}-${r.end}/${i}`;if(s.headers.get(`content-range`)!==c)throw Error(`Invalid Content-Range for seed: ${s.headers.get(`content-range`)??`<missing>`}`);let l=r.end-r.start+1,u=0,d=h.fromWeb(s.body);for await(let e of d){let t=Buffer.isBuffer(e)?e:Buffer.from(e);if(u+t.byteLength>l)throw Error(`Seed range response exceeded the requested length`);await I(a,t,r.start+u),u+=t.byteLength,o(t.byteLength)}if(u!==l)throw Error(`Seed range response was truncated: got ${u}, expected ${l}`)}async function R(e){let t=e.expectedSha256.toLowerCase(),n=await T(e.signatureUrl,e.token,t),r=await N([...new Set(e.sourcePaths.map(e=>_.resolve(e)))],n),i=P(n,r),a=i.reduce((e,t)=>e+t.end-t.start+1,0),o=0;e.onProgress?.(0,a),await m.promises.mkdir(_.dirname(e.outputPath),{recursive:!0});let s=`${e.outputPath}.reconstruct-${process.pid}-${v.randomBytes(6).toString(`hex`)}`,c=await m.promises.open(s,`wx`),l=!1,u=!1;try{await c.truncate(n.fileSize),await F(c,n,r);for(let t of i)await L(e.seedUrl,e.token,t,n.fileSize,c,t=>{o+=t,e.onProgress?.(o,a)});await c.close(),l=!0;let d=await C(s);if(d!==t)throw Error(`Reconstructed seed SHA-256 mismatch: got ${d}, expected ${t}`);await m.promises.rm(e.outputPath,{force:!0}),await m.promises.rename(s,e.outputPath),u=!0}finally{l||await c.close().catch(()=>void 0),u||await m.promises.rm(s,{force:!0})}return{downloadedBytes:o,totalDownloadBytes:a,matchedBlocks:r.size}}function z(e){return`${e}/sync/state`}function B(e,t){return`${e}/sync/seeds/${encodeURIComponent(t)}`}async function V(e){return await new Promise((t,n)=>{let r=v.createHash(`sha256`),i=m.createReadStream(e);i.on(`data`,e=>r.update(e)),i.on(`error`,n),i.on(`end`,()=>t(r.digest(`hex`)))})}async function H(e,t){let r=await n.fetch(z(e),{method:`GET`,headers:{Authorization:`Bearer ${t}`}});if(!r.ok){let e=await r.text();throw Error(`Failed to fetch Android sync state: ${r.status} ${e}`)}return await r.json()}async function ee(e,t,n,i,a,o){let s=_.basename(e),c=_.join(t,s),l=await H(n,i).catch(e=>{a(`debug`,`android sync state unavailable: ${e instanceof Error?e.message:String(e)}`)});if(!l)return;let u=new Set;for(let e of l.roots??[])for(let t of e.files??[])t.path===s&&typeof t.sha256==`string`&&u.add(t.sha256.toLowerCase());let d=[...l.seeds??[]].filter(e=>typeof e.sha256==`string`&&/^[0-9a-f]{64}$/i.test(e.sha256)).sort((e,t)=>(t.mtime??0)-(e.mtime??0));for(let e of d)u.add(e.sha256.toLowerCase());let f;if(m.existsSync(c)){let e=(await V(c)).toLowerCase();if(u.has(e))return;a(`debug`,`local basis ${e} unknown to instance; re-seeding basis cache`),f=c}let p=(await V(e)).toLowerCase();if(u.has(p)){await m.promises.mkdir(_.dirname(c),{recursive:!0}),await m.promises.copyFile(e,c),a(`debug`,`seeded Android basis cache from local APK already known to instance: ${p}`);return}let h=d[0];if(!h){f&&await m.promises.rm(f,{force:!0});return}let g=B(n,h.sha256);try{let t=await R({signatureUrl:`${g}.sig`,seedUrl:g,token:i,sourcePaths:f?[e,f]:[e],outputPath:c,expectedSha256:h.sha256,...o?{onProgress:o}:{}});a(`debug`,`reconstructed Android basis seed ${h.sha256}: matched=${t.matchedBlocks} downloaded=${t.downloadedBytes}`)}catch(e){a(`debug`,`basis seed reconstruction unavailable; downloading full seed: ${e instanceof Error?e.message:String(e)}`),o?.(0,h.size??0),await r(g,i,c,o),a(`debug`,`seeded Android basis cache from full instance seed: ${h.sha256}`)}}var U=e({RecordingQuality:()=>K,createInstanceClient:()=>q});function W(e){let t=new URL(e);return t.protocol=t.protocol===`https:`?`wss:`:`ws:`,t.search=``,t.hash=``,t.pathname=`${t.pathname.replace(/\/$/,``)}/ws`,t.toString().replace(/\/$/,``)}function te(e){return`${e}/files?path=%2Fdata%2Flocal%2Ftmp%2Frecordings%2Fvideo_recording.mp4`}function G(e,t){if(!Number.isInteger(t)||t<0)throw Error(`${e} must be a non-negative integer Kbps value`)}async function ne(e){if(!(await m.promises.stat(e).catch(()=>null))?.isFile())throw Error(`APK file not found: ${e}`);let t=await m.promises.open(e,`r`);try{let n=Buffer.alloc(4),{bytesRead:r}=await t.read(n,0,4,0);if(r<4||n[0]!==80||n[1]!==75)throw Error(`File is not an APK/ZIP archive: ${e}`)}finally{await t.close()}}var K;(function(e){e[e.Q5=5]=`Q5`,e[e.Q6=6]=`Q6`,e[e.Q7=7]=`Q7`,e[e.Q8=8]=`Q8`,e[e.Q9=9]=`Q9`,e[e.Q10=10]=`Q10`})(K||={});function re(e){return e.map(e=>`'${e.replace(/'/g,`'\\''`)}'`).join(` `)}async function q(e){let h=`${W(e.apiUrl)}?token=${e.token}`,y=e.apiUrl,b=e.logLevel??`info`,x=e.maxReconnectAttempts??6,S=e.reconnectDelay??1e3,C=e.maxReconnectDelay??3e4,w,T=`connecting`,E=0,D,O=!1,k,A=new Map,j=new Map,M=new Map,N=new Set,P={debug:(...e)=>{b===`debug`&&console.log(`[Endpoint]`,...e)},info:(...e)=>{(b===`info`||b===`debug`)&&console.log(`[Endpoint]`,...e)},warn:(...e)=>{(b===`warn`||b===`info`||b===`debug`)&&console.warn(`[Endpoint]`,...e)},error:(...e)=>{b!==`none`&&console.error(`[Endpoint]`,...e)}},F=e=>{T!==e&&(T=e,P.debug(`Connection state changed to: ${e}`),N.forEach(t=>{try{t(e)}catch(e){P.error(`Error in connection state callback:`,e)}}))},I=e=>{A.forEach(t=>{clearTimeout(t.timeout),t.reject(Error(e))}),A.clear(),j.forEach(t=>{t.forEach(t=>{clearTimeout(t.timeout),t.reject(Error(e))})}),j.clear()},L=()=>{D&&=(clearTimeout(D),void 0),R&&=(clearInterval(R),void 0),w&&=(w.removeAllListeners(),(w.readyState===c.default.OPEN||w.readyState===c.default.CONNECTING)&&w.close(),void 0)},R,z=0,B=Math.random().toString(36).substring(2,15)+Math.random().toString(36).substring(2,15);return new Promise((V,H)=>{let U=!1,W=e=>(z+=1,`${e}-${Date.now()}-${z}`),K=(e,t)=>{let n=A.get(e);if(!n){P.debug(`Received response for unknown/already-settled request: ${e}`);return}clearTimeout(n.timeout),A.delete(e),n.resolve(t)},q=(e,t)=>{let n=A.get(e);if(!n){P.debug(`Received error for unknown/already-settled request: ${e}`);return}clearTimeout(n.timeout),A.delete(e),n.reject(t)},J=e=>{if(`message`in e&&typeof e.message==`string`)return e.message;if(`error`in e&&typeof e.error==`string`&&e.error)return e.error;if(`error`in e&&e.error&&typeof e.error==`object`){let t=e.error;return typeof t.message==`string`&&t.message?t.message:typeof t.code==`string`&&t.code?t.code:`Server returned ${String(e.type)} with an error payload but no error message/code`}},ie=e=>{if(!(`type`in e)||typeof e.type!=`string`)return!1;switch(e.type){case`screenshotResult`:case`getElementTreeResult`:case`findElementResult`:case`tapResult`:case`setTextResult`:case`pressKeyResult`:case`scrollScreenResult`:case`scrollElementResult`:case`openUrlResult`:case`launchAppResult`:case`terminateAppResult`:case`watchAppResult`:case`unwatchAppResult`:case`listAppsResult`:case`playOnMicrophoneResult`:case`cameraControlResult`:case`adbShellResult`:case`setWifiBandwidthResult`:case`startRecordingResult`:case`stopRecordingResult`:case`startAppLogCaptureResult`:case`stopAppLogCaptureResult`:case`startEventCaptureResult`:case`stopEventCaptureResult`:return`id`in e&&typeof e.id==`string`;default:return!1}},Y=async(e,t,n=3e4)=>{if(!w||w.readyState!==c.default.OPEN)return Promise.reject(Error(`WebSocket is not connected or connection is not open.`));let r=W(`ts-client`),i=Object.keys(t).length>0?{type:e,id:r,...t,payload:t}:{type:e,id:r};return new Promise((t,a)=>{let o=setTimeout(()=>{A.has(r)&&(A.delete(r),a(Error(`Request ${e} timed out`)))},n);A.set(r,{resolve:e=>t(e),reject:e=>a(e),timeout:o}),w.send(JSON.stringify(i),e=>{e&&(clearTimeout(o),A.delete(r),a(e))})})},ae=()=>{if(O){P.debug(`Skipping reconnection (intentional disconnect)`);return}if(f(k??``)){P.debug(`Skipping reconnection (non-retryable error)`);return}if(E>=x){P.error(`Max reconnection attempts (${x}) reached. Giving up.`,k?`Last error: ${k}`:``),F(`disconnected`);return}let e=Math.min(S*2**E,C);E++,P.debug(`Scheduling reconnection attempt ${E} in ${e}ms...`),F(`reconnecting`),D=setTimeout(()=>{P.debug(`Attempting to reconnect (attempt ${E})...`),X()},e)},X=()=>{L(),F(`connecting`);let e=n.getWebSocketAgent(h);w=new c.default(h,e?{agent:e}:{}),w.on(`message`,e=>{let t;try{t=JSON.parse(e.toString())}catch(t){P.error({data:e,error:t},`Failed to parse JSON message`);return}switch(t.type){case`screenshot`:{if(!(`dataUri`in t)||typeof t.dataUri!=`string`||!(`id`in t)){P.warn(`Received invalid screenshot message:`,t);break}let e=t;P.debug(`Received screenshot data URI for request ${e.id}.`),K(e.id,{dataUri:e.dataUri});break}case`appExit`:{let e=t,{execId:n,packageName:r,reason:i}=e;if(typeof n!=`string`||typeof r!=`string`||typeof i!=`string`){P.warn(`Received malformed appExit message:`,t);break}let a=M.get(n);if(!a){P.debug(`Received appExit for unknown or already handled execId: ${n}`);break}M.delete(n);let o=Array.isArray(e.logs)?e.logs.map(String):[],s={packageName:r,reason:i,...e.crash?{crash:e.crash}:{},...e.anr?{anr:e.anr}:{}};Promise.resolve().then(()=>a(o,s)).catch(e=>{P.error(`Error in onExit callback for execId ${n}:`,e)});break}case`screenshotResult`:{let e=t,n=J(e);if(n){q(e.id,Error(n));break}let r=typeof e.payload?.dataUri==`string`?e.payload.dataUri:``;if(!r){q(e.id,Error(`Received screenshotResult without payload.dataUri`));break}K(e.id,{dataUri:r});break}case`screenshotError`:{if(!(`message`in t)||!(`id`in t)){P.warn(`Received invalid screenshot error message:`,t);break}let e=t;P.error(`Server reported an error capturing screenshot for request ${e.id}:`,e.message),q(e.id,Error(e.message));break}case`assetResult`:{P.debug(`Received assetResult:`,t);let e=t.url,n=j.get(e);if(!n||n.length===0){P.warn(`Received assetResult for unknown or already handled url: ${t.url}`);break}let r=n.shift();if(n.length===0?j.delete(e):j.set(e,n),clearTimeout(r.timeout),t.result===`success`){P.debug(`Asset result is success`),r.resolve();break}let i=typeof t.message==`string`&&t.message?t.message:`Asset processing failed: ${JSON.stringify(t)}`;P.debug(`Asset result is failure`,i),r.reject(Error(i));break}default:if(ie(t)){let e=J(t);e?q(t.id,Error(e)):K(t.id,t.payload??t);break}P.warn(`Received unexpected message type: ${t.type}`)}}),w.on(`error`,e=>{let t=e.message;k=t,P.debug(`WebSocket error:`,t),!U&&(w?.readyState===c.default.CONNECTING||w?.readyState===c.default.OPEN)&&H(e)}),w.on(`close`,()=>{R&&=(clearInterval(R),void 0);let e=!O&&!f(k??``)&&T!==`disconnected`;F(`disconnected`),P.debug(`Disconnected from server.`),I(`Connection closed`),e?ae():f(k??``)&&(P.error(`Closing connection due to non-retryable error: ${k}`),L(),F(`disconnected`),I(`Non-retryable error`),P.debug(`Non-retryable error. Closing connection.`))}),w.on(`open`,()=>{P.debug(`Connected to ${h}`),E=0,k=void 0,F(`connected`),R=setInterval(()=>{w&&w.readyState===c.default.OPEN&&w.ping()},3e4),U||(U=!0,V({screenshot:oe,getElementTree:se,findElement:ce,tap:le,setText:ue,pressKey:de,scrollScreen:fe,scrollElement:pe,openUrl:me,launchApp:he,terminateApp:ge,listApps:_e,watchApp:ve,playOnMicrophone:ye,pushFile:Q,pullFile:be,setCameraVideo:xe,clearCameraVideo:Se,adbShell:Ce,setWifiBandwidth:we,startRecording:Te,stopRecording:Ee,startAppLogCapture:De,stopAppLogCapture:Oe,startEventCapture:ke,stopEventCapture:Ae,streamAppLogCapture:je,streamEventCapture:Me,keepAlive:Ne,disconnect:Pe,startAdbTunnel:Le,startTunnel:Re,getTunnelStatus:ze,stopTunnel:Be,sendAsset:Ve,syncApp:He,getConnectionState:Fe,onConnectionStateChange:Ie}))})},oe=async()=>Y(`screenshot`,{}),se=async e=>{let t=await Y(`getElementTree`,e??{},3e4+(e?.waitForIdleTimeoutMs??0));return{xml:typeof t.xml==`string`?t.xml:``,nodes:Array.isArray(t.nodes)?t.nodes:[]}},ce=async(e,t=20)=>{let n=await Y(`findElement`,{selector:e,limit:t}),r=Array.isArray(n.elements)?n.elements:[];return{elements:r,count:typeof n.count==`number`?n.count:r.length}},le=async e=>{let t=await Y(`tap`,e);return{x:Number(t.x??0),y:Number(t.y??0)}},ue=async(e,t)=>{let n={text:t};e?.selector&&(n.selector=e.selector),typeof e?.x==`number`&&(n.x=e.x),typeof e?.y==`number`&&(n.y=e.y);let r=await Y(`setText`,n);return{textLength:Number(r.textLength??t.length)}},de=async(e,t)=>{let n={keyName:e,...t?{modifiers:t}:{}},r=await Y(`pressKey`,n);return{key:typeof r.key==`string`?r.key:String(e)}},fe=async(e,t=6)=>await Y(`scrollScreen`,{direction:e,amount:t}),pe=async(e,t,n=6)=>await Y(`scrollElement`,{...e,direction:t,amount:n}),me=async e=>{let t=await Y(`openUrl`,{url:e});return{url:typeof t.url==`string`?t.url:e}},Z=async(e,t,n)=>{let r=W(e);M.set(r,t);try{return{execId:r,result:await n(r)}}catch(e){throw M.delete(r),e}},he=async(e,t={})=>{let n=n=>{let r={packageName:e};return t.mode&&(r.mode=t.mode),n&&(r.execId=n),Y(`launchApp`,r,6e4)},r=t.onExit?(await Z(`exec`,t.onExit,n)).result:await n();return{packageName:typeof r.packageName==`string`?r.packageName:e}},ge=async e=>{await Y(`terminateApp`,{packageName:e})},_e=async()=>(await Y(`listApps`,{})).apps??[],ve=async(e,t)=>{let{execId:n}=await Z(`watch`,t,t=>Y(`watchApp`,{packageName:e,execId:t}));return{execId:n,stop:async()=>{M.delete(n),await Y(`unwatchApp`,{execId:n})}}},ye=async(e,t)=>{if(!e)throw Error(`path must be a non-empty string`);return Y(`playOnMicrophone`,{path:e,...t?.once===void 0?{}:{once:t.once}})},Q=async(t,r)=>{let i=r===void 0?`${e.apiUrl}/files`:`${e.apiUrl}/files?path=${encodeURIComponent(r)}`,a=m.createReadStream(t),o=await n.fetch(i,{method:`PUT`,headers:{"Content-Type":`application/octet-stream`,"Content-Length":m.statSync(t).size.toString(),Authorization:`Bearer ${e.token}`},body:a,duplex:`half`});if(!o.ok){let e=await o.text();throw P.debug(`Upload failed: ${o.status} ${e}`),Error(`Upload failed: ${o.status} ${e}`)}return(await o.json()).path},be=async(t,n)=>{let i=`${e.apiUrl}/files?path=${encodeURIComponent(t)}`;await r(i,e.token,n)},xe=async(e,t)=>{let n=await Q(e);await Y(`cameraControl`,{action:`setSource`,source:`video`,arg:n,loop:t?.loop??!0})},Se=async()=>{await Y(`cameraControl`,{action:`reset`})},Ce=async(e,t=[],n)=>{if(!e)throw Error(`command must be a non-empty string`);let r=re([e,...t]),i=n?.timeoutMs,a=(i??3e4)+15e3,o=await Y(`adbShell`,{command:r,...i===void 0?{}:{timeoutMs:i}},a),s=n?.encoding??`utf8`;return{stdout:Buffer.from(o.stdout??``,`base64`).toString(s),stderr:Buffer.from(o.stderr??``,`base64`).toString(s),exitCode:typeof o.exitCode==`number`?o.exitCode:-1,truncated:o.truncated===!0}},we=async e=>{let t={};if(e.downKbps!==void 0&&(G(`downKbps`,e.downKbps),t.downKbps=e.downKbps),e.upKbps!==void 0&&(G(`upKbps`,e.upKbps),t.upKbps=e.upKbps),t.downKbps===void 0&&t.upKbps===void 0)throw Error(`setWifiBandwidth requires downKbps, upKbps, or both`);await Y(`setWifiBandwidth`,t)},Te=async e=>{let t={...s(e?.persist)};if(e?.quality!==void 0){if(!Number.isInteger(e.quality)||e.quality<5||e.quality>10)throw Error(`quality must be one of: 5, 6, 7, 8, 9, 10`);t.quality=e.quality}await Y(`startRecording`,t)},Ee=async t=>{let n={};t.presignedUrl&&(n.upload={presignedUrl:t.presignedUrl}),await Y(`stopRecording`,n);let i=te(y);return t.localPath&&await r(i,e.token,t.localPath),i},De=async e=>{if(!e.bundleId)throw Error(`bundleId must be a non-empty string`);await Y(`startAppLogCapture`,{bundleId:e.bundleId,...s(e.persist)})},Oe=async()=>{await Y(`stopAppLogCapture`,{})},ke=async e=>{await Y(`startEventCapture`,{...s(e?.persist)})},Ae=async()=>{await Y(`stopEventCapture`,{})},je=t=>d({url:`${e.apiUrl}/session/applogs/events`,token:e.token,onEntry:t.onLine,onError:t.onError}),Me=t=>d({url:`${e.apiUrl}/session/events/events`,token:e.token,onEntry:t.onEvent,onError:t.onError}),Ne=()=>{!w||w.readyState!==c.default.OPEN||w.send(JSON.stringify({type:`keepAlive`,sessionId:B}))},Pe=()=>{O=!0,L(),F(`disconnected`),I(`Intentional disconnect`),P.debug(`Intentionally disconnected from WebSocket.`)},Fe=()=>T,Ie=e=>(N.add(e),()=>{N.delete(e)}),Le=async()=>{if(!e.adbUrl)throw Error(`adbUrl is required to start an ADB tunnel.`);let t=await i(e.adbUrl,e.token,`127.0.0.1`,0,{maxReconnectAttempts:x,reconnectDelay:S,maxReconnectDelay:C,logLevel:b});try{await new Promise((n,r)=>{p(e.adbPath??`adb`,[`connect`,`${t.address.address}:${t.address.port}`],e=>{if(e)return r(e);n()})}),P.debug(`ADB connected on ${t.address.address}`)}catch(e){throw t.close(),e}return t},$=()=>{if(!e.adbUrl)throw Error(`adbUrl is required to manage a destination tunnel.`);return e.adbUrl},Re=async n=>t(u($()),e.token,{selectors:n.selectors,inspection:{enabled:!0,captureBodies:!1,...n.inspection??{}},...n.onInspectionEvent?{onInspectionEvent:n.onInspectionEvent}:{},...n.onInspectionError?{onInspectionError:n.onInspectionError}:{},...n.window===void 0?{}:{window:n.window},logLevel:n.logLevel??b}),ze=async()=>l($(),e.token),Be=async t=>{await a($(),e.token,t)},Ve=async(e,t)=>{if(!w||w.readyState!==c.default.OPEN)return Promise.reject(Error(`WebSocket is not connected or connection is not open.`));let n={type:`asset`,url:e};return new Promise((r,i)=>{let a,o=setTimeout(()=>{let t=j.get(e);if(!t)return;let n=t.indexOf(a);n>=0&&(t.splice(n,1),i(Error(`Request asset timed out for url: ${e}`))),t.length===0?j.delete(e):j.set(e,t)},t??12e4);a={resolve:r,reject:e=>i(e),timeout:o};let s=j.get(e)??[];s.push(a),j.set(e,s),w.send(JSON.stringify(n),t=>{if(t){clearTimeout(o);let n=j.get(e)??[],r=n.indexOf(a);r>=0&&n.splice(r,1),n.length===0?j.delete(e):j.set(e,n),P.error(`Failed to send asset request:`,t),i(t)}})})},He=async(t,n)=>{let r=_.resolve(t);await ne(r);let i=`limsync-cache-android-${_.basename(r)}-${v.createHash(`sha1`).update(r).digest(`hex`).slice(0,8)}`,a=n?.basisCacheDir??_.join(g.tmpdir(),i),s=(e,t)=>{switch(e){case`debug`:P.debug(t);break;case`info`:P.info(t);break;case`warn`:P.warn(t);break;case`error`:P.error(t);break;default:P.info(t)}};return await m.promises.mkdir(a,{recursive:!0}),await ee(r,a,e.apiUrl,e.token,s,n?.onBasisDownloadProgress),await o(r,{apiUrl:e.apiUrl,token:e.token,udid:i,basisCacheDir:a,install:n?.install??!0,launchMode:n?.launchMode??`ForegroundIfRunning`,watch:n?.watch??!1,ignoreFn:()=>!1,log:s,compression:`identity`,...n?.onSyncComplete?{onSyncComplete:n.onSyncComplete}:{}})};X()})}export{U as n,q as t};
|
|
1
|
+
import{r as e}from"./rolldown-runtime.js";import{C as t,a as n,c as r,f as i,g as a,h as o,i as s,l as c,m as l,n as u,o as d,r as f,s as p,u as m}from"./log-stream.js";import{execFile as h}from"node:child_process";import{EventEmitter as g}from"events";import _ from"fs";import{Readable as v}from"stream";import ee from"os";import y from"path";import b from"crypto";const x=/^[0-9a-f]{64}$/i,S=/^[0-9a-f]{32}$/i;function C(e){return b.createHash(`sha256`).update(e).digest(`hex`).slice(0,32)}function w(e,t){let n=t*e.blockSize;return{offset:n,length:Math.min(e.blockSize,e.fileSize-n)}}async function T(e){return await new Promise((t,n)=>{let r=b.createHash(`sha256`),i=_.createReadStream(e);i.on(`data`,e=>r.update(e)),i.on(`error`,n),i.on(`end`,()=>t(r.digest(`hex`)))})}function E(e,t){if(!e||typeof e!=`object`)throw Error(`Invalid seed signature: expected an object`);let n=e;if(n.version!==1)throw Error(`Unsupported seed signature version: ${String(n.version)}`);if(!Number.isSafeInteger(n.blockSize)||n.blockSize<=0)throw Error(`Invalid seed signature blockSize`);if(!Number.isSafeInteger(n.fileSize)||n.fileSize<0)throw Error(`Invalid seed signature fileSize`);if(typeof n.sha256!=`string`||!x.test(n.sha256)||n.sha256.toLowerCase()!==t.toLowerCase())throw Error(`Seed signature sha256 does not match the requested seed`);if(!Array.isArray(n.blocks))throw Error(`Invalid seed signature blocks`);let r=Math.ceil(n.fileSize/n.blockSize);if(n.blocks.length!==r)throw Error(`Invalid seed signature block count: got ${n.blocks.length}, expected ${r}`);let i=n.blocks.map((e,t)=>{if(!e||!Number.isInteger(e.w)||e.w<0||e.w>4294967295||typeof e.s!=`string`||!S.test(e.s))throw Error(`Invalid seed signature block at index ${t}`);return{w:e.w,s:e.s.toLowerCase()}});return{version:n.version,blockSize:n.blockSize,fileSize:n.fileSize,sha256:n.sha256.toLowerCase(),blocks:i}}async function D(e,n,r){let i=await t.fetch(e,{method:`GET`,headers:{Authorization:`Bearer ${n}`}});if(!i.ok){let e=await i.text();throw Error(`Seed signature download failed: ${i.status} ${e}`)}return E(await i.json(),r)}async function O(e,t,n,r){let i=0;for(;i<n;){let{bytesRead:a}=await e.read(t,i,n-i,r+i);if(a<=0)throw Error(`Unexpected EOF at offset ${r+i}`);i+=a}}async function k(e,t,n,r,i){let a=n.blockSize,o=await _.promises.open(e.path,`r`);try{if(e.size<a||i.size===0)return;let s=Buffer.allocUnsafe(a);await O(o,s,a,0);let c=0,l=0;for(let e=0;e<a;e++){let t=s[e];c=c+t&65535,l=l+(a-e)*t&65535}let u=0,d=0,f,p=async t=>{f??=Buffer.allocUnsafe(a),await O(o,f,a,d);let s=C(f);for(let a of t)i.has(a)&&n.blocks[a].s===s&&(r.set(a,{sourcePath:e.path,sourceOffset:d}),i.delete(a))},m=t.get(l*65536+c);m?.some(e=>i.has(e))&&await p(m);let h=Buffer.allocUnsafe(1048576),g=a;for(;g<e.size&&i.size>0;){let n=Math.min(h.byteLength,e.size-g),{bytesRead:r}=await o.read(h,0,n,g);if(r<=0)break;for(let e=0;e<r&&i.size>0;e++){let n=s[u],r=h[e];s[u]=r,u++,u===a&&(u=0),c=c-n+r&65535,l=l-(a*n&65535)+c&65535,d++,m=t.get(l*65536+c),m?.some(e=>i.has(e))&&await p(m)}g+=r}}finally{await o.close()}}async function A(e){let t=[];for(let n of e){let e=await _.promises.stat(n).catch(()=>void 0);e?.isFile()&&t.push({path:n,size:e.size})}return t}async function j(e,t,n){for(let r of e){let e=await _.promises.open(r.path,`r`),i=Buffer.allocUnsafe(t.blockSize);try{for(let a=0;a<t.blocks.length;a++){if(n.has(a))continue;let o=w(t,a);o.offset+o.length>r.size||(await O(e,i,o.length,o.offset),C(i.subarray(0,o.length))===t.blocks[a].s&&n.set(a,{sourcePath:r.path,sourceOffset:o.offset}))}}finally{await e.close()}}}async function M(e,t,n){if(t.fileSize===0||t.fileSize%t.blockSize===0)return;let r=t.blocks.length-1;if(n.has(r))return;let i=w(t,r),a=t.blocks[r].s,o=Buffer.allocUnsafe(i.length);for(let t of e){if(t.size<i.length)continue;let e=t.size-i.length;if(e===i.offset)continue;let s=await _.promises.open(t.path,`r`);try{if(await O(s,o,i.length,e),C(o)===a){n.set(r,{sourcePath:t.path,sourceOffset:e});return}}finally{await s.close()}}}function N(e,t){let n=0;for(let r=0;r<e.blocks.length;r++)t.has(r)||(n+=w(e,r).length);return(e.blocks.length===0?1:t.size/e.blocks.length)>=.8&&n<=33554432}async function P(e,t,n){let r=Math.floor(t.fileSize/t.blockSize),i=new Set,a=new Map;for(let e=0;e<r;e++){if(n.has(e))continue;i.add(e);let r=t.blocks[e].w,o=a.get(r)??[];o.push(e),a.set(r,o)}for(let r of e){if(i.size===0)return;await k(r,a,t,n,i)}}async function F(e,t){let n=await A(e),r=new Map;return await j(n,t,r),await M(n,t,r),N(t,r)||await P(n,t,r),r}function I(e,t){let n=[],r;for(let i=0;i<=e.blocks.length;i++){let a=i<e.blocks.length&&!t.has(i);if(a&&r===void 0)r=i;else if(!a&&r!==void 0){let t=w(e,r),a=w(e,i-1);n.push({start:t.offset,end:a.offset+a.length-1}),r=void 0}}return n}async function L(e,t,n){let r=new Map;try{for(let[i,a]of n){let n=r.get(a.sourcePath);n||(n=await _.promises.open(a.sourcePath,`r`),r.set(a.sourcePath,n));let o=w(t,i),s=Buffer.allocUnsafe(o.length);await O(n,s,o.length,a.sourceOffset),await R(e,s,o.offset)}}finally{await Promise.all([...r.values()].map(e=>e.close()))}}async function R(e,t,n){let r=0;for(;r<t.byteLength;){let{bytesWritten:i}=await e.write(t,r,t.byteLength-r,n+r);if(i<=0)throw Error(`Unable to write reconstructed seed at offset ${n+r}`);r+=i}}async function z(e,n,r,i,a,o){let s=await t.fetch(e,{method:`GET`,headers:{Authorization:`Bearer ${n}`,Range:`bytes=${r.start}-${r.end}`}});if(s.status!==206||!s.body){let e=await s.text();throw Error(`Seed range download failed: ${s.status} ${e}`)}let c=`bytes ${r.start}-${r.end}/${i}`;if(s.headers.get(`content-range`)!==c)throw Error(`Invalid Content-Range for seed: ${s.headers.get(`content-range`)??`<missing>`}`);let l=r.end-r.start+1,u=0,d=v.fromWeb(s.body);for await(let e of d){let t=Buffer.isBuffer(e)?e:Buffer.from(e);if(u+t.byteLength>l)throw Error(`Seed range response exceeded the requested length`);await R(a,t,r.start+u),u+=t.byteLength,o(t.byteLength)}if(u!==l)throw Error(`Seed range response was truncated: got ${u}, expected ${l}`)}async function B(e){let t=e.expectedSha256.toLowerCase(),n=await D(e.signatureUrl,e.token,t),r=await F([...new Set(e.sourcePaths.map(e=>y.resolve(e)))],n),i=I(n,r),a=i.reduce((e,t)=>e+t.end-t.start+1,0),o=0;e.onProgress?.(0,a),await _.promises.mkdir(y.dirname(e.outputPath),{recursive:!0});let s=`${e.outputPath}.reconstruct-${process.pid}-${b.randomBytes(6).toString(`hex`)}`,c=await _.promises.open(s,`wx`),l=!1,u=!1;try{await c.truncate(n.fileSize),await L(c,n,r);for(let t of i)await z(e.seedUrl,e.token,t,n.fileSize,c,t=>{o+=t,e.onProgress?.(o,a)});await c.close(),l=!0;let d=await T(s);if(d!==t)throw Error(`Reconstructed seed SHA-256 mismatch: got ${d}, expected ${t}`);await _.promises.rm(e.outputPath,{force:!0}),await _.promises.rename(s,e.outputPath),u=!0}finally{l||await c.close().catch(()=>void 0),u||await _.promises.rm(s,{force:!0})}return{downloadedBytes:o,totalDownloadBytes:a,matchedBlocks:r.size}}function V(e){return`${e}/sync/state`}function H(e,t){return`${e}/sync/seeds/${encodeURIComponent(t)}`}async function U(e){return await new Promise((t,n)=>{let r=b.createHash(`sha256`),i=_.createReadStream(e);i.on(`data`,e=>r.update(e)),i.on(`error`,n),i.on(`end`,()=>t(r.digest(`hex`)))})}async function W(e,n){let r=await t.fetch(V(e),{method:`GET`,headers:{Authorization:`Bearer ${n}`}});if(!r.ok){let e=await r.text();throw Error(`Failed to fetch Android sync state: ${r.status} ${e}`)}return await r.json()}async function te(e,t,n,r,i,a){let o=y.basename(e),s=y.join(t,o),c=await W(n,r).catch(e=>{i(`debug`,`android sync state unavailable: ${e instanceof Error?e.message:String(e)}`)});if(!c)return;let l=new Set;for(let e of c.roots??[])for(let t of e.files??[])t.path===o&&typeof t.sha256==`string`&&l.add(t.sha256.toLowerCase());let u=[...c.seeds??[]].filter(e=>typeof e.sha256==`string`&&/^[0-9a-f]{64}$/i.test(e.sha256)).sort((e,t)=>(t.mtime??0)-(e.mtime??0));for(let e of u)l.add(e.sha256.toLowerCase());let d;if(_.existsSync(s)){let e=(await U(s)).toLowerCase();if(l.has(e))return;i(`debug`,`local basis ${e} unknown to instance; re-seeding basis cache`),d=s}let f=(await U(e)).toLowerCase();if(l.has(f)){await _.promises.mkdir(y.dirname(s),{recursive:!0}),await _.promises.copyFile(e,s),i(`debug`,`seeded Android basis cache from local APK already known to instance: ${f}`);return}let p=u[0];if(!p){d&&await _.promises.rm(d,{force:!0});return}let h=H(n,p.sha256);try{let t=await B({signatureUrl:`${h}.sig`,seedUrl:h,token:r,sourcePaths:d?[e,d]:[e],outputPath:s,expectedSha256:p.sha256,...a?{onProgress:a}:{}});i(`debug`,`reconstructed Android basis seed ${p.sha256}: matched=${t.matchedBlocks} downloaded=${t.downloadedBytes}`)}catch(e){i(`debug`,`basis seed reconstruction unavailable; downloading full seed: ${e instanceof Error?e.message:String(e)}`),a?.(0,p.size??0),await m(h,r,s,a),i(`debug`,`seeded Android basis cache from full instance seed: ${p.sha256}`)}}async function ne(e,n,i){let a=await t.fetch(r(e,`trusted-cas`).toString(),{method:`POST`,headers:{"Content-Type":`application/x-pem-file`,Authorization:`Bearer ${n}`},body:i});if(!a.ok){let e=(await a.text()).trim();throw Error(`Adding the CA certificate failed (${a.status}): ${e}`)}return await a.json()}var re=class extends g{constructor(e,t,n){super(),this.apiUrl=e,this.token=t,this.stopStream=null,this.runId=null,this.stopped=!1,this.exited=!1,this.exitPromise=new Promise(e=>{this.settleExit=e}),this.start(n)}on(e,t){return super.on(e,t)}once(e,t){return super.once(e,t)}off(e,t){return super.off(e,t)}wait(){return this.exitPromise}stop(){this.stopped||this.exited||(this.stopped=!0,this.deleteRun(this.runId),this.finish(-1))}deleteRun(e){e&&t.fetch(`${this.apiUrl}/logcat/${e}`,{method:`DELETE`,headers:{Authorization:`Bearer ${this.token}`}}).catch(()=>{})}finish(e){this.exited||(this.exited=!0,this.stopStream?.(),this.stopStream=null,this.settleExit(e),this.emit(`exit`,e))}fail(e){this.exited||(this.deleteRun(this.runId),this.emit(`error`,e),this.finish(-1))}async start(e){let n;try{let r=await t.fetch(`${this.apiUrl}/logcat`,{method:`POST`,headers:{Authorization:`Bearer ${this.token}`,"Content-Type":`application/json`},body:JSON.stringify({args:e})});if(!r.ok){let e=await r.text().catch(()=>``);throw Error(`logcat failed to start: HTTP ${r.status}${e?` ${e.trim()}`:``}`)}let i=await r.json();if(!i.id)throw Error(`logcat failed to start: server returned no run id`);n=i.id}catch(e){this.fail(e instanceof Error?e:Error(String(e)));return}if(this.stopped){this.deleteRun(n);return}this.runId=n,this.stopStream=u({url:`${this.apiUrl}/logcat/${n}/events`,token:this.token,onEntry:e=>{if(e.lines&&e.lines.length>0){this.emit(`lines`,e.lines);for(let t of e.lines)this.emit(`line`,t)}e.error&&this.emit(`error`,Error(e.error)),typeof e.exitCode==`number`&&this.finish(e.exitCode)},onError:e=>this.fail(e)})}},G=e({RecordingQuality:()=>J,createInstanceClient:()=>Y});function K(e){let t=new URL(e);return t.protocol=t.protocol===`https:`?`wss:`:`ws:`,t.search=``,t.hash=``,t.pathname=`${t.pathname.replace(/\/$/,``)}/ws`,t.toString().replace(/\/$/,``)}function ie(e){return`${e}/files?path=%2Fdata%2Flocal%2Ftmp%2Frecordings%2Fvideo_recording.mp4`}function q(e,t){if(!Number.isInteger(t)||t<0)throw Error(`${e} must be a non-negative integer Kbps value`)}async function ae(e){if(!(await _.promises.stat(e).catch(()=>null))?.isFile())throw Error(`APK file not found: ${e}`);let t=await _.promises.open(e,`r`);try{let n=Buffer.alloc(4),{bytesRead:r}=await t.read(n,0,4,0);if(r<4||n[0]!==80||n[1]!==75)throw Error(`File is not an APK/ZIP archive: ${e}`)}finally{await t.close()}}var J;(function(e){e[e.Q5=5]=`Q5`,e[e.Q6=6]=`Q6`,e[e.Q7=7]=`Q7`,e[e.Q8=8]=`Q8`,e[e.Q9=9]=`Q9`,e[e.Q10=10]=`Q10`})(J||={});function oe(e){return e.map(e=>`'${e.replace(/'/g,`'\\''`)}'`).join(` `)}async function Y(e){let r=`${K(e.apiUrl)}?token=${e.token}`,g=e.apiUrl,v=e.logLevel??`info`,x=e.maxReconnectAttempts??6,S=e.reconnectDelay??1e3,C=e.maxReconnectDelay??3e4,w,T=`connecting`,E=0,D,O=!1,k,A=new Map,j=new Map,M=new Map,N=new Set,P={debug:(...e)=>{v===`debug`&&console.log(`[Endpoint]`,...e)},info:(...e)=>{(v===`info`||v===`debug`)&&console.log(`[Endpoint]`,...e)},warn:(...e)=>{(v===`warn`||v===`info`||v===`debug`)&&console.warn(`[Endpoint]`,...e)},error:(...e)=>{v!==`none`&&console.error(`[Endpoint]`,...e)}},F=e=>{T!==e&&(T=e,P.debug(`Connection state changed to: ${e}`),N.forEach(t=>{try{t(e)}catch(e){P.error(`Error in connection state callback:`,e)}}))},I=e=>{A.forEach(t=>{clearTimeout(t.timeout),t.reject(Error(e))}),A.clear(),j.forEach(t=>{t.forEach(t=>{clearTimeout(t.timeout),t.reject(Error(e))})}),j.clear()},L=()=>{D&&=(clearTimeout(D),void 0),R&&=(clearInterval(R),void 0),w&&=(w.removeAllListeners(),(w.readyState===o.default.OPEN||w.readyState===o.default.CONNECTING)&&w.close(),void 0)},R,z=0,B=Math.random().toString(36).substring(2,15)+Math.random().toString(36).substring(2,15);return new Promise((V,H)=>{let U=!1,W=e=>(z+=1,`${e}-${Date.now()}-${z}`),G=(e,t)=>{let n=A.get(e);if(!n){P.debug(`Received response for unknown/already-settled request: ${e}`);return}clearTimeout(n.timeout),A.delete(e),n.resolve(t)},K=(e,t)=>{let n=A.get(e);if(!n){P.debug(`Received error for unknown/already-settled request: ${e}`);return}clearTimeout(n.timeout),A.delete(e),n.reject(t)},J=e=>{if(`message`in e&&typeof e.message==`string`)return e.message;if(`error`in e&&typeof e.error==`string`&&e.error)return e.error;if(`error`in e&&e.error&&typeof e.error==`object`){let t=e.error;return typeof t.message==`string`&&t.message?t.message:typeof t.code==`string`&&t.code?t.code:`Server returned ${String(e.type)} with an error payload but no error message/code`}},Y=e=>{if(!(`type`in e)||typeof e.type!=`string`)return!1;switch(e.type){case`screenshotResult`:case`getElementTreeResult`:case`findElementResult`:case`tapResult`:case`setTextResult`:case`pressKeyResult`:case`scrollScreenResult`:case`scrollElementResult`:case`openUrlResult`:case`launchAppResult`:case`terminateAppResult`:case`watchAppResult`:case`unwatchAppResult`:case`listAppsResult`:case`playOnMicrophoneResult`:case`cameraControlResult`:case`adbShellResult`:case`setWifiBandwidthResult`:case`startRecordingResult`:case`stopRecordingResult`:case`startAppLogCaptureResult`:case`stopAppLogCaptureResult`:case`startEventCaptureResult`:case`stopEventCaptureResult`:return`id`in e&&typeof e.id==`string`;default:return!1}},X=async(e,t,n=3e4)=>{if(!w||w.readyState!==o.default.OPEN)return Promise.reject(Error(`WebSocket is not connected or connection is not open.`));let r=W(`ts-client`),i=Object.keys(t).length>0?{type:e,id:r,...t,payload:t}:{type:e,id:r};return new Promise((t,a)=>{let o=setTimeout(()=>{A.has(r)&&(A.delete(r),a(Error(`Request ${e} timed out`)))},n);A.set(r,{resolve:e=>t(e),reject:e=>a(e),timeout:o}),w.send(JSON.stringify(i),e=>{e&&(clearTimeout(o),A.delete(r),a(e))})})},se=()=>{if(O){P.debug(`Skipping reconnection (intentional disconnect)`);return}if(i(k??``)){P.debug(`Skipping reconnection (non-retryable error)`);return}if(E>=x){P.error(`Max reconnection attempts (${x}) reached. Giving up.`,k?`Last error: ${k}`:``),F(`disconnected`);return}let e=Math.min(S*2**E,C);E++,P.debug(`Scheduling reconnection attempt ${E} in ${e}ms...`),F(`reconnecting`),D=setTimeout(()=>{P.debug(`Attempting to reconnect (attempt ${E})...`),Z()},e)},Z=()=>{L(),F(`connecting`);let e=t.getWebSocketAgent(r);w=new o.default(r,e?{agent:e}:{}),w.on(`message`,e=>{let t;try{t=JSON.parse(e.toString())}catch(t){P.error({data:e,error:t},`Failed to parse JSON message`);return}switch(t.type){case`screenshot`:{if(!(`dataUri`in t)||typeof t.dataUri!=`string`||!(`id`in t)){P.warn(`Received invalid screenshot message:`,t);break}let e=t;P.debug(`Received screenshot data URI for request ${e.id}.`),G(e.id,{dataUri:e.dataUri});break}case`appExit`:{let e=t,{execId:n,packageName:r,reason:i}=e;if(typeof n!=`string`||typeof r!=`string`||typeof i!=`string`){P.warn(`Received malformed appExit message:`,t);break}let a=M.get(n);if(!a){P.debug(`Received appExit for unknown or already handled execId: ${n}`);break}M.delete(n);let o=Array.isArray(e.logs)?e.logs.map(String):[],s={packageName:r,reason:i,...e.crash?{crash:e.crash}:{},...e.anr?{anr:e.anr}:{}};Promise.resolve().then(()=>a(o,s)).catch(e=>{P.error(`Error in onExit callback for execId ${n}:`,e)});break}case`screenshotResult`:{let e=t,n=J(e);if(n){K(e.id,Error(n));break}let r=typeof e.payload?.dataUri==`string`?e.payload.dataUri:``;if(!r){K(e.id,Error(`Received screenshotResult without payload.dataUri`));break}G(e.id,{dataUri:r});break}case`screenshotError`:{if(!(`message`in t)||!(`id`in t)){P.warn(`Received invalid screenshot error message:`,t);break}let e=t;P.error(`Server reported an error capturing screenshot for request ${e.id}:`,e.message),K(e.id,Error(e.message));break}case`assetResult`:{P.debug(`Received assetResult:`,t);let e=t.url,n=j.get(e);if(!n||n.length===0){P.warn(`Received assetResult for unknown or already handled url: ${t.url}`);break}let r=n.shift();if(n.length===0?j.delete(e):j.set(e,n),clearTimeout(r.timeout),t.result===`success`){P.debug(`Asset result is success`),r.resolve();break}let i=typeof t.message==`string`&&t.message?t.message:`Asset processing failed: ${JSON.stringify(t)}`;P.debug(`Asset result is failure`,i),r.reject(Error(i));break}default:if(Y(t)){let e=J(t);e?K(t.id,Error(e)):G(t.id,t.payload??t);break}P.warn(`Received unexpected message type: ${t.type}`)}}),w.on(`error`,e=>{let t=e.message;k=t,P.debug(`WebSocket error:`,t),!U&&(w?.readyState===o.default.CONNECTING||w?.readyState===o.default.OPEN)&&H(e)}),w.on(`close`,()=>{R&&=(clearInterval(R),void 0);let e=!O&&!i(k??``)&&T!==`disconnected`;F(`disconnected`),P.debug(`Disconnected from server.`),I(`Connection closed`),e?se():i(k??``)&&(P.error(`Closing connection due to non-retryable error: ${k}`),L(),F(`disconnected`),I(`Non-retryable error`),P.debug(`Non-retryable error. Closing connection.`))}),w.on(`open`,()=>{P.debug(`Connected to ${r}`),E=0,k=void 0,F(`connected`),R=setInterval(()=>{w&&w.readyState===o.default.OPEN&&w.ping()},3e4),U||(U=!0,V({screenshot:ce,getElementTree:le,findElement:ue,tap:de,setText:fe,pressKey:pe,scrollScreen:me,scrollElement:he,openUrl:ge,launchApp:_e,terminateApp:ve,listApps:ye,watchApp:be,playOnMicrophone:xe,pushFile:Se,pullFile:Ce,setCameraVideo:we,clearCameraVideo:Te,adbShell:Ee,logcat:De,setWifiBandwidth:Oe,startRecording:ke,stopRecording:Ae,startAppLogCapture:je,stopAppLogCapture:Me,startEventCapture:Ne,stopEventCapture:Pe,streamAppLogCapture:Fe,streamEventCapture:Ie,keepAlive:Le,disconnect:Re,startAdbTunnel:Ve,startTunnel:He,getTunnelStatus:Ue,stopTunnel:We,addCaCertificate:Ge,sendAsset:Ke,syncApp:qe,getConnectionState:ze,onConnectionStateChange:Be}))})},ce=async()=>X(`screenshot`,{}),le=async e=>{let t=await X(`getElementTree`,e??{},3e4+(e?.waitForIdleTimeoutMs??0));return{xml:typeof t.xml==`string`?t.xml:``,nodes:Array.isArray(t.nodes)?t.nodes:[]}},ue=async(e,t=20)=>{let n=await X(`findElement`,{selector:e,limit:t}),r=Array.isArray(n.elements)?n.elements:[];return{elements:r,count:typeof n.count==`number`?n.count:r.length}},de=async e=>{let t=await X(`tap`,e);return{x:Number(t.x??0),y:Number(t.y??0)}},fe=async(e,t)=>{let n={text:t};e?.selector&&(n.selector=e.selector),typeof e?.x==`number`&&(n.x=e.x),typeof e?.y==`number`&&(n.y=e.y);let r=await X(`setText`,n);return{textLength:Number(r.textLength??t.length)}},pe=async(e,t)=>{let n={keyName:e,...t?{modifiers:t}:{}},r=await X(`pressKey`,n);return{key:typeof r.key==`string`?r.key:String(e)}},me=async(e,t=6)=>await X(`scrollScreen`,{direction:e,amount:t}),he=async(e,t,n=6)=>await X(`scrollElement`,{...e,direction:t,amount:n}),ge=async e=>{let t=await X(`openUrl`,{url:e});return{url:typeof t.url==`string`?t.url:e}},Q=async(e,t,n)=>{let r=W(e);M.set(r,t);try{return{execId:r,result:await n(r)}}catch(e){throw M.delete(r),e}},_e=async(e,t={})=>{let n=n=>{let r={packageName:e};return t.mode&&(r.mode=t.mode),n&&(r.execId=n),X(`launchApp`,r,6e4)},r=t.onExit?(await Q(`exec`,t.onExit,n)).result:await n();return{packageName:typeof r.packageName==`string`?r.packageName:e}},ve=async e=>{await X(`terminateApp`,{packageName:e})},ye=async()=>(await X(`listApps`,{})).apps??[],be=async(e,t)=>{let{execId:n}=await Q(`watch`,t,t=>X(`watchApp`,{packageName:e,execId:t}));return{execId:n,stop:async()=>{M.delete(n),await X(`unwatchApp`,{execId:n})}}},xe=async(e,t)=>{if(!e)throw Error(`path must be a non-empty string`);return X(`playOnMicrophone`,{path:e,...t?.once===void 0?{}:{once:t.once}})},Se=async(n,r)=>{let i=r===void 0?`${e.apiUrl}/files`:`${e.apiUrl}/files?path=${encodeURIComponent(r)}`,a=_.createReadStream(n),o=await t.fetch(i,{method:`PUT`,headers:{"Content-Type":`application/octet-stream`,"Content-Length":_.statSync(n).size.toString(),Authorization:`Bearer ${e.token}`},body:a,duplex:`half`});if(!o.ok){let e=await o.text();throw P.debug(`Upload failed: ${o.status} ${e}`),Error(`Upload failed: ${o.status} ${e}`)}return(await o.json()).path},Ce=async(t,n)=>{let r=`${e.apiUrl}/files?path=${encodeURIComponent(t)}`;await m(r,e.token,n)},we=async(e,t)=>{let n=await Se(e);await X(`cameraControl`,{action:`setSource`,source:`video`,arg:n,loop:t?.loop??!0})},Te=async()=>{await X(`cameraControl`,{action:`reset`})},Ee=async(e,t=[],n)=>{if(!e)throw Error(`command must be a non-empty string`);let r=oe([e,...t]),i=n?.timeoutMs,a=(i??3e4)+15e3,o=await X(`adbShell`,{command:r,...i===void 0?{}:{timeoutMs:i}},a),s=n?.encoding??`utf8`;return{stdout:Buffer.from(o.stdout??``,`base64`).toString(s),stderr:Buffer.from(o.stderr??``,`base64`).toString(s),exitCode:typeof o.exitCode==`number`?o.exitCode:-1,truncated:o.truncated===!0}},De=(t=[])=>new re(e.apiUrl,e.token,t),Oe=async e=>{let t={};if(e.downKbps!==void 0&&(q(`downKbps`,e.downKbps),t.downKbps=e.downKbps),e.upKbps!==void 0&&(q(`upKbps`,e.upKbps),t.upKbps=e.upKbps),t.downKbps===void 0&&t.upKbps===void 0)throw Error(`setWifiBandwidth requires downKbps, upKbps, or both`);await X(`setWifiBandwidth`,t)},ke=async e=>{let t={...f(e?.persist)};if(e?.quality!==void 0){if(!Number.isInteger(e.quality)||e.quality<5||e.quality>10)throw Error(`quality must be one of: 5, 6, 7, 8, 9, 10`);t.quality=e.quality}await X(`startRecording`,t)},Ae=async t=>{let n={};t.presignedUrl&&(n.upload={presignedUrl:t.presignedUrl}),await X(`stopRecording`,n);let r=ie(g);return t.localPath&&await m(r,e.token,t.localPath),r},je=async e=>{if(!e.bundleId)throw Error(`bundleId must be a non-empty string`);await X(`startAppLogCapture`,{bundleId:e.bundleId,...f(e.persist)})},Me=async()=>{await X(`stopAppLogCapture`,{})},Ne=async e=>{await X(`startEventCapture`,{...f(e?.persist)})},Pe=async()=>{await X(`stopEventCapture`,{})},Fe=t=>u({url:`${e.apiUrl}/session/applogs/events`,token:e.token,onEntry:t.onLine,onError:t.onError}),Ie=t=>u({url:`${e.apiUrl}/session/events/events`,token:e.token,onEntry:t.onEvent,onError:t.onError}),Le=()=>{!w||w.readyState!==o.default.OPEN||w.send(JSON.stringify({type:`keepAlive`,sessionId:B}))},Re=()=>{O=!0,L(),F(`disconnected`),I(`Intentional disconnect`),P.debug(`Intentionally disconnected from WebSocket.`)},ze=()=>T,Be=e=>(N.add(e),()=>{N.delete(e)}),Ve=async()=>{if(!e.adbUrl)throw Error(`adbUrl is required to start an ADB tunnel.`);let t=await l(e.adbUrl,e.token,`127.0.0.1`,0,{maxReconnectAttempts:x,reconnectDelay:S,maxReconnectDelay:C,logLevel:v});try{await new Promise((n,r)=>{h(e.adbPath??`adb`,[`connect`,`${t.address.address}:${t.address.port}`],e=>{if(e)return r(e);n()})}),P.debug(`ADB connected on ${t.address.address}`)}catch(e){throw t.close(),e}return t},$=(t=`manage a destination tunnel`)=>{if(!e.adbUrl)throw Error(`adbUrl is required to ${t}.`);return e.adbUrl},He=async t=>p(c($()),e.token,d(t,v)),Ue=async()=>s($(),e.token),We=async t=>{await n($(),e.token,t)},Ge=t=>ne($(`add a CA certificate`),e.token,t),Ke=async(e,t)=>{if(!w||w.readyState!==o.default.OPEN)return Promise.reject(Error(`WebSocket is not connected or connection is not open.`));let n={type:`asset`,url:e};return new Promise((r,i)=>{let a,o=setTimeout(()=>{let t=j.get(e);if(!t)return;let n=t.indexOf(a);n>=0&&(t.splice(n,1),i(Error(`Request asset timed out for url: ${e}`))),t.length===0?j.delete(e):j.set(e,t)},t??12e4);a={resolve:r,reject:e=>i(e),timeout:o};let s=j.get(e)??[];s.push(a),j.set(e,s),w.send(JSON.stringify(n),t=>{if(t){clearTimeout(o);let n=j.get(e)??[],r=n.indexOf(a);r>=0&&n.splice(r,1),n.length===0?j.delete(e):j.set(e,n),P.error(`Failed to send asset request:`,t),i(t)}})})},qe=async(t,n)=>{let r=y.resolve(t);await ae(r);let i=`limsync-cache-android-${y.basename(r)}-${b.createHash(`sha1`).update(r).digest(`hex`).slice(0,8)}`,o=n?.basisCacheDir??y.join(ee.tmpdir(),i),s=(e,t)=>{switch(e){case`debug`:P.debug(t);break;case`info`:P.info(t);break;case`warn`:P.warn(t);break;case`error`:P.error(t);break;default:P.info(t)}};return await _.promises.mkdir(o,{recursive:!0}),await te(r,o,e.apiUrl,e.token,s,n?.onBasisDownloadProgress),await a(r,{apiUrl:e.apiUrl,token:e.token,udid:i,basisCacheDir:o,install:n?.install??!0,launchMode:n?.launchMode??`ForegroundIfRunning`,watch:n?.watch??!1,ignoreFn:()=>!1,log:s,compression:`identity`,...n?.onSyncComplete?{onSyncComplete:n.onSyncComplete}:{}})};Z()})}export{G as n,Y as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{P as e}from"./sdk-contracts.js";import{
|
|
1
|
+
import{P as e}from"./sdk-contracts.js";import{Sr as t,br as n,wr as r,xr as i,yr as a}from"./sdk-batch.js";function o(e){return e?.startsWith(`@`)?e.slice(1):e}const s=/^e\d+$/;function c(t){if(t[0]?.startsWith(`@`)){let e=_(t.slice(1));return{ref:t[0],...e===void 0?{}:{label:e}}}if(s.test(t[0]??``))throw new e(`INVALID_ARGS`,`Did you mean "@${t[0]}"? Snapshot refs need the @ prefix.`);let n=r(t);if(n){if(n.rest.length>0)throw new e(`INVALID_ARGS`,m(t,n));return{selector:n.selectorExpression}}return u(t)}function l(t){let n=t[0];if(n?.startsWith(`@`)){let e=t.slice(1),r=e.length===0?void 0:e.join(` `);return{kind:`ref`,target:{ref:n},text:r}}if(s.test(n??``))throw new e(`INVALID_ARGS`,`Did you mean "@${n}"? Snapshot refs need the @ prefix.`);let i=r(t,{preferTrailingValue:!0});if(i)return{kind:`selector`,target:{selector:i.selectorExpression},text:i.rest.length===0?void 0:i.rest.join(` `)};let a=t.slice(2);return{kind:`point`,target:u(t.slice(0,2)),text:a.length===0?void 0:a.join(` `)}}function u(t){let r=t[0]??``,i=n(r);if(i){let n=d(r)?i.value:[i.value,...t.slice(1)].join(` `).trim();throw new e(`INVALID_ARGS`,f({key:i.key,value:n}))}let a=Number(t[0]),o=Number(t[1]);if(Number.isFinite(a)&&Number.isFinite(o))return{x:a,y:o};throw new e(`INVALID_ARGS`,p(t))}function d(e){let t=e.slice(e.indexOf(`=`)+1).trim();if(t.length<2)return!1;let n=t[0];return(n===`"`||n===`'`)&&t.endsWith(n)}function f(e){let{key:t,value:n}=e;return`Unknown selector key "${t}". Supported: ${a.join(`, `)}. ${i(t)?`Did you mean role=${t} label=${g(n)}?`:`Did you mean label=${g(n)}?`}`}function p(e){let n=e.filter(e=>e!==void 0).join(` `);if(!n.trim())return`Missing target. Pass an @ref from snapshot, a selector like text="Sign in", or "x y" coordinates.`;let r=`Target "${n}" is not a @ref, selector, or "x y" point.`;return e.some(e=>t(e??``))?`${r} Selector values with spaces need quotes, e.g. text="Sign in".`:`${r} To match by visible text, use text=${g(n)} (or label=/id=/role=), or pass an @ref from snapshot.`}function m(e,t){return`${`Selector ${t.selectorExpression} is followed by unexpected extra arguments: "${t.rest.join(` `)}".`} Selector values with spaces need quotes, e.g. ${h(e,t)??`text="Sign in"`}.`}function h(e,t){let n=e.length-t.rest.length,r=e[n-1];if(r===void 0)return;let i=r.indexOf(`=`);if(i<=0)return;let a=[r.slice(i+1),...t.rest].join(` `),o=`${r.slice(0,i+1)}${g(a)}`;return[...e.slice(0,n-1),o].join(` `)}function g(e){return`"${e.replaceAll(`\\`,String.raw`\\`).replaceAll(`"`,String.raw`\"`)}"`}function _(e){return e.join(` `).trim()||void 0}export{c as n,o as r,l as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{F as e,K as t,P as n,r}from"./sdk-contracts.js";import{
|
|
1
|
+
import{F as e,K as t,P as n,r}from"./sdk-contracts.js";import{E as i,h as a}from"./sdk-device.js";import{pn as o}from"./sdk-batch.js";import{i as s,s as c,u as l}from"./target-evidence.js";import{M as u,P as d,n as f,p,r as m}from"./provider-device-admission.js";import{i as h}from"./mobile-snapshot-semantics.js";import{r as g}from"./request-cancel.js";import"./request.js";import{_,b as v,c as y,j as b,p as x,s as S,x as C,y as w}from"./session-snapshot.js";import{Q as T}from"./internal/daemon.js";function E(e){return{...e,sessionRef:`sessionRef`in e?e.sessionRef:e.sessionStore.lookup(e.sessionName)}}function D(e){let{req:t,logPath:n,traceLogPath:r}=e;return{verbose:t.flags?.verbose,logPath:n,traceLogPath:r,requestId:t.meta?.requestId,iosXctestrunFile:t.flags?.iosXctestrunFile,iosXctestDerivedDataPath:t.flags?.iosXctestDerivedDataPath,iosXctestEnvDir:t.flags?.iosXctestEnvDir}}function O(e,t){return!(!e||!a(e.device)||f(e.device)||t.skipPendingPostGestureStabilization&&w(e))}function k(e){let{session:t,selectorExpression:n}=e;return O(t,{skipPendingPostGestureStabilization:!0})?o(n):null}function A(e){let t=e.identifier?.trim();if(t)return{key:`id`,value:t};let n=e.label?.trim();return n?{key:`label`,value:n}:null}async function j(e,t,n){let r=await _(e.device,t,e.appBundleId,n),i=r.found===!0,a=M(r);return{found:i,...typeof r.text==`string`?{text:r.text}:{},...a?{node:a}:{}}}function M(e){let t=e.nodes;if(!Array.isArray(t))return;let n=t[0];if(!(!n||typeof n!=`object`))return n}const N=new Set([`ELEMENT_NOT_FOUND`,`ELEMENT_OFFSCREEN`,`AMBIGUOUS_MATCH`]);function P(n,r){let i=e(n);return i.details?.dispatched!==`no`||t(i)?!1:N.has(i.code)?r.delegateSemanticFailures:i.code===`COMMAND_FAILED`}async function F(e){let{session:t,node:n,rootViewport:r,requestOptions:i}=e,a=A(n);if(!a)return null;let o;try{o=await j(t,a,i)}catch{return null}if(!o.found||!o.node?.rect)return null;let s={rect:o.node.rect,hittable:o.node.hittable===!0};return h(s,r)?s.rect:null}function I(e){let{operations:t,command:n,positionals:r,actionCommand:i=n,flags:a,result:o,responseData:c,recordedTarget:l,recordedTargets:u,actionStartedAt:d,actionFinishedAt:f,androidFreshnessBaseline:p}=e,m=C(a),[h,g]=R({command:n,positionals:r,flags:m,result:o,responseData:c}),_=t.isSessionRecording()&&l?s(l):void 0,v=t.isSessionRecording()&&u?L(u):void 0;return t.recordAction({command:n,positionals:r,flags:m??{},result:h,..._?{targetEvidence:_}:{},...v?{targetEvidences:v}:{}}),t.markDeferredOutcome({command:n,action:i,positionals:r,flags:a,androidFreshnessBaseline:p}),t.recordGestureVisualization(i,r,h,m??{},d,f),{ok:!0,data:g}}function L(e){let t=s(e.source),n=s(e.destination);return t&&n?{source:t,destination:n}:void 0}function R(e){if(e.command!==`fill`||typeof e.flags?.recordAs!=`string`)return[e.result,e.responseData];let t=u({ts:0,command:`fill`,positionals:e.positionals,flags:e.flags,result:e.result}),n=d(e.flags.recordAs);return[m(e.result,t,n),m(e.responseData,t,n)]}function z(e){let t=E(e).sessionRef;if(!t)throw new n(`SESSION_NOT_FOUND`,r);let i=e.sessionStore.requireCurrent(t);return V({requestId:e.req.meta?.requestId,flags:e.req.flags,session:i,contextFromFlags:e.contextFromFlags,captureSnapshot:async(n,r)=>{let i=await e.captureSnapshotForSession(t,n,e.sessionStore,e.contextFromFlags,r);return e.consumedCapture&&(e.consumedCapture.state=i),c(e.captureProof,i)},runtimeSessions:y({sessionName:e.sessionName,sessionStore:e.sessionStore,ref:t,recordOptions:{includeSnapshot:!0,omitRefFrameSnapshot:e.req.internal?.findResolvedTarget!==void 0},setRecord:(e,t)=>{e.snapshot&&S(t,e.snapshot)}}),expireRefFrame:()=>b(e.sessionStore.requireCurrent(t)),confirmOffscreenTargetVisible:O(i,{skipPendingPostGestureStabilization:!1})?async(t,n)=>await F({session:i,node:t,rootViewport:n,requestOptions:D({req:e.req,logPath:e.logPath,traceLogPath:i.trace?.outPath})}):void 0,pairedGestureViewport:e.pairedGestureViewport,touchExecutor:e.touchExecutor,gestures:e.gestures})}function B(e){let{ref:t,sessionStore:n,...r}=e,i=n.requireCurrent(t);return I({...r,operations:{recordAction:n.recordAction.bind(n,t),markDeferredOutcome:e=>v({session:i,...e}),isSessionRecording:p.bind(null,i),recordGestureVisualization:T.bind(null,i)}})}function V(e){return x({backend:H(e),...l(`interaction commands`,{plural:!0}),sessions:e.runtimeSessions,signal:g(e.requestId)})}function H(e){let{flags:t,session:n}=e;return{platform:i(n.device),captureSnapshot:async(n,r)=>({snapshot:await e.captureSnapshot(t,{interactiveOnly:r?.interactiveOnly===!0,preferredBackend:r?.preferredBackend,includeRects:r?.includeRects===!0,signal:n.signal,boundCapture:e.touchExecutor?.captureSnapshot??e.gestures?.captureSnapshot})}),...U(e,()=>e.contextFromFlags(t,n.appBundleId,n.trace?.outPath)),...e.confirmOffscreenTargetVisible?{confirmOffscreenTargetVisible:async(t,n,r)=>await e.confirmOffscreenTargetVisible(n,r)}:{},...W(e.touchExecutor,e.expireRefFrame,t)}}function U(e,t){let n=e.gestures,r=e.pairedGestureViewport;return n?{resolveGestureViewport:async()=>r??await n.gestureViewport?.(t()),performGesture:async(r,i)=>(e.expireRefFrame(),G(await n.performPlan(i,t())))}:r?{resolveGestureViewport:async()=>r}:{}}function W(e,t,n){if(!e)return{};let{tapPoint:r,tapRef:i,fillPoint:a,fillRef:o,longPressPoint:s,hoverPoint:c,hoverRef:l}=e,u=async e=>(t(),G(await e()));return{tap:r?(e,t)=>u(()=>r(t,n)):void 0,tapTarget:i?(e,t)=>u(()=>i(t.ref)):void 0,fill:a?(e,t,n,r)=>u(()=>a(t,n,r)):void 0,fillTarget:o?(e,t,n,r)=>u(()=>o(t.ref,n,r)):void 0,longPress:s?(e,t,n)=>u(()=>s(t,n?.durationMs)):void 0,hover:c?(e,t)=>u(()=>c(t)):void 0,hoverTarget:l?(e,t)=>u(()=>l(t.ref)):void 0}}function G(e){return e&&typeof e==`object`?e:void 0}function K(e,t,n){return{ok:!1,error:{code:e,message:t,...n?{details:n}:{}}}}function q(e,t){if(!t||t.settle===!0)return null;let n=[];return t.settleQuietMs!==void 0&&n.push(`--settle-quiet`),n.length===0?null:K(`INVALID_ARGS`,`${e}: ${n.join(`, `)} require${n.length===1?`s`:``} --settle.`)}function J(e){if(e?.settle===!0)return{...e.settleQuietMs===void 0?{}:{quietMs:e.settleQuietMs},...e.timeoutMs===void 0?{}:{timeoutMs:e.timeoutMs}}}function Y(e){try{return X(e),null}catch(e){if(e instanceof n)return K(e.code,e.message,e.details);throw e}}function X(e){let t=e.ref.startsWith(`@`)?e.ref.slice(1):e.ref,{admission:r,scope:i,currentGeneration:a}=e.frame;if(r.admitted)return;let o=r.reason===`plain_ref_requires_complete_frame`&&i!==`all`&&i.has(t)&&a!==void 0?`@${t}~s${a}`:void 0;throw new n(`COMMAND_FAILED`,Q(r.reason,e.ref),{reason:r.reason,ref:e.ref,currentGeneration:a,scope:i===`all`?`all`:Array.from(i),...e.mintedGeneration===void 0?{}:{mintedGeneration:e.mintedGeneration},...o?{suggestedRef:o}:{},hint:o?`Retry with the exact emitted ref ${o}.`:e.staleRefsWarning??Z})}const Z=`Capture a fresh interactive snapshot (snapshot -i) or use a stable selector, then retry.`;function Q(e,t){switch(e){case`ref_frame_expired`:return`Ref ${t} belongs to an expired ref frame — a device action since the snapshot invalidated it`;case`ref_generation_mismatch`:return`Ref ${t} was minted from a superseded snapshot generation`;case`plain_ref_requires_complete_frame`:return`Ref ${t} needs a complete snapshot — the current frame only authorizes its emitted refs`;case`ref_not_issued`:return`Ref ${t} was not issued by the current ref frame`}}export{z as a,O as c,q as i,k as l,Y as n,B as o,J as r,P as s,X as t,E as u};
|
package/dist/src/interaction.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{m as e,s as t,u as n}from"./session-snapshot.js";import{s as r}from"./quality-warnings.js";import{a as i,i as a,n as o,o as s,r as c,u as l}from"./interaction-ref-policy.js";import{t as u}from"./backend-snapshot-options.js";async function d(e){let{session:t,flags:n,contextFromFlags:i,options:a}=e,o={...n??{},...u(a)},s=i(o,t.appBundleId,t.trace?.outPath),c=await e.capture({flags:o,options:a,context:s});return r(c.snapshotQuality)||e.publishSnapshot(c),c}const f=async(r,i,a,o,s)=>{let c=a.requireCurrent(r);return await d({session:c,flags:i,contextFromFlags:o,options:s,capture:async({flags:t,options:r,context:i})=>{let{snapshot:a}=await n({device:c.device,session:c,flags:t,logPath:i.logPath??``,includeRects:r.includeRects,androidFreshnessMode:r.androidFreshnessMode,signal:r.signal,...r.boundCapture?{captureData:async()=>await r.boundCapture(e({flags:t,session:c,snapshotScope:t.snapshotScope,includeRects:r.includeRects,signal:r.signal,context:i}))}:{}});return a},publishSnapshot:e=>{t(a.requireCurrent(r),e)}})};function p(e){return i({...l(e),captureSnapshotForSession:e.captureSnapshotForSession??f})}async function m(e){return(await import(`./find.js`)).handleFindCommands(e)}async function h(e){let t=l(e);return await(await import(`./interaction2.js`)).handleInteractionCommands({...t,captureSnapshotForSession:e.captureSnapshotForSession??f})}export{l as bindInteractionSession,f as captureSnapshotForSession,p as createInteractionRuntime,s as finalizeTouchInteraction,m as handleFindCommands,h as handleInteractionCommands,c as readSettleRequest,o as refMutationAdmissionResponse,a as settleFlagGuardResponse};
|
package/dist/src/interaction2.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{F as e,J as t,M as n,P as r,X as i,f as a,h as o,s}from"./sdk-contracts.js";import{m as c}from"./sdk-batch-runner.js";import{r as l}from"./diagnostics.js";import"./diagnostics2.js";import{m as u,w as d}from"./sdk-device.js";import{g as f,h as p,m as ee,w as te}from"./sdk-batch.js";import{c as ne,o as re}from"./scroll-gesture.js";import{C as m,E as ie,S as ae,v as oe,x as h}from"./script.js";import{c as se}from"./target-evidence.js";import{F as ce,n as g,p as _}from"./provider-device-admission.js";import{S as le,v as ue}from"./runtime.js";import{n as v}from"./catalog.js";import{r as de}from"./success-text.js";import{i as y,n as fe,r as pe}from"./click-button.js";import{r as me,t as he}from"./interaction-positionals.js";import{t as ge}from"./timeouts.js";import"./retry.js";import"./gesture-plan.js";import{r as _e}from"./request-cancel.js";import"./request.js";import{A as b,N as x,O as ve,i as S,n as C,r as ye}from"./session-snapshot.js";import{n as w,t as T}from"./touch-reference-frame.js";import{c as be,s as xe}from"./quality-warnings.js";import{a as E,n as D,o as Se,t as O}from"./internal/daemon.js";import{a as k,c as Ce,i as we,l as Te,n as A,o as j,r as M,s as Ee,t as De,u as N}from"./interaction-ref-policy.js";import{n as Oe,t as ke}from"./touch-runtime2.js";import{t as P}from"./gesture-runtime.js";import{d as Ae,g as F,i as je,r as Me,u as Ne}from"./selector-runtime.js";import{n as Pe}from"./type-text-runtime.js";function Fe(e){let t=e.flags?.recordAs;if(t!==void 0){if(ce(t),e.flags?.noRecord)throw new r(`INVALID_ARGS`,`fill --record-as cannot be combined with --no-record because no script step would be published.`);if(!e.isSessionRecording&&!e.replayPlanStep)throw new r(`INVALID_ARGS`,`fill --record-as requires an armed script recording. Start a fresh session with open --save-script, then retry the fill.`)}}async function I(e,t){if(!ve(t))return;let n=t.snapshot?.comparisonSafe===!0?t.snapshot:void 0;try{await e.captureSnapshotForSession(e.sessionRef,e.req.flags,e.sessionStore,e.contextFromFlags,{interactiveOnly:!0,androidFreshnessMode:`ref-refresh`})}catch(t){l({level:`warn`,phase:`android_ref_snapshot_refresh_failed`,data:{command:e.req.command,error:t instanceof Error?t.message:String(t)}})}return n}function L(e,t){return!u(e.device)||e.surface!==`desktop`&&e.surface!==`menubar`||e.surface===`menubar`&&(t===`click`||t===`press`)?null:s(`UNSUPPORTED_OPERATION`,`${t} is not supported on macOS ${e.surface} sessions yet. Open an app session to act, or use the ${e.surface} surface to inspect.`)}const Ie=new Set(f()),Le=new Set([`currentUptimeMs`,`gestureEndUptimeMs`,`gestureStartUptimeMs`,`sequenceResults`]);function R(e){if(e)return Object.fromEntries(Object.entries(e).filter(([e])=>!Le.has(e)))}function Re(e){return Be({fields:ze(e.command),input:e.input??{},data:R(e.data),controlledFields:Ie})}function ze(e){let t=te(e);if(!t)throw Error(`Missing response data transform descriptor for ${e}`);return t.fields}function Be(e){let t=Object.fromEntries(Object.entries(e.data??{}).filter(([t])=>!e.controlledFields.has(t)));for(let[n,r]of Object.entries(e.fields)){let i=e.input[n]===void 0?r.defaultValue:e.input[n];if(i===void 0||r.omitDefault===!0&&i===r.defaultValue){delete t[n];continue}t[n]=i}return Object.fromEntries(Object.entries(t).filter(([,e])=>e!==void 0))}async function Ve(e){let{ref:t,flags:n,sessionStore:r,contextFromFlags:i,captureSnapshotForSession:a,observation:o}=e,s=r.resolveCurrent(t);if(!s)return;let c=s.screenRecording;if(!c)return;let l=c.handle,u=e=>{if(!(!e||r.resolveCurrent(t)?.screenRecording!==c))return l.setTouchReferenceFrame(e),e},d=l.inspect().touchReferenceFrame;if(d)return d;if(s.device.platform===`android`&&!s.lease?.leaseProvider&&!g(s.device)){if(!o)throw Error(`Android observation was not injected into the request`);let e=await o.readScreenSize(s.device);return u({referenceWidth:e.width,referenceHeight:e.height})}let f=T(s.snapshot);if(f)return u(f);let p=await a(t,n,r,i,{interactiveOnly:!0});return u(T(p))}async function He(e){try{return await Ve(e)}catch(t){let n=e.sessionStore.resolveCurrent(e.ref);if(!n)return;l({level:`warn`,phase:`touch_reference_frame_resolve_failed`,data:{platform:n.device.platform,error:t instanceof Error?t.message:String(t)}});return}}function z(e){let{data:t,fallbackX:n,fallbackY:r,referenceFrame:i,extra:a}=e,o=We(a,n,r)??(typeof t?.message==`string`?t.message:void 0);return Ue({...t??{},...n===void 0||r===void 0?{}:{x:n,y:r},...i??{},...a??{},...de(o)})}function Ue(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>e!==void 0))}function We(e,t,n){let r=B(e,`text`);if(r!==void 0)return`Filled ${Array.from(r).length} chars`;let i=Ge(t,n),a=Ke(e);if(a)return Je(a,e??{},i);if(i)return qe(e,i)}function B(e,t){let n=e?.[t];return typeof n==`string`?n:void 0}function Ge(e,t){return e===void 0||t===void 0?``:` (${e}, ${t})`}function Ke(e){let t=B(e,`ref`);return t===void 0?B(e,`selector`):`@${t}`}function qe(e,t){return e?.gesture===`longpress`?`Long pressed${t}`:e?.gesture===`hover`?`Hovered${t}`:`Tapped${t}`}function Je(e,t,n){let r=typeof t.button==`string`?t.button:void 0;return t.gesture===`longpress`?`Long pressed ${e}${n}`:t.gesture===`hover`?`Hovered ${e}${n}`:r&&r!==`primary`?`Clicked ${r} ${e}${n}`:`Tapped ${e}${n}`}function V(e){if(e.length<2)return null;let t=Number(e[0]),n=Number(e[1]);return!Number.isFinite(t)||!Number.isFinite(n)?null:{x:t,y:n}}function H(e,t){let n=V(e);if(n)return{ok:!0,target:{kind:`point`,x:n.x,y:n.y}};let r=e[0]??``;if(r.startsWith(`@`)){let t=F(r);return t.ok?{ok:!0,target:{kind:`ref`,ref:t.ref,fallbackLabel:e.slice(1).join(` `).trim()},refGeneration:t.generation}:{ok:!1,response:t.response}}let i=e.join(` `).trim();return i?{ok:!0,target:{kind:`selector`,selector:i}}:{ok:!1,response:s(`INVALID_ARGS`,`${t} requires @ref, selector expression, or x y coordinates`)}}function Ye(e){let t=V(e);if(t)return{ok:!0,target:{kind:`point`,x:t.x,y:t.y},...tt(e[2])};let n=et(e),r=H(n.targetPositionals,`longpress`);return r.ok?{ok:!0,target:r.target,refGeneration:r.refGeneration,...n.duration}:r}function U(e){return{ok:!1,response:s(`INVALID_ARGS`,`fill requires text after ${e} (use "" to clear the field)`)}}function Xe(e){let t=Ze(e);if(!t)return{ok:!1,response:s(`INVALID_ARGS`,`fill requires x y text, @ref text, or selector text`)};switch(t.kind){case`ref`:{let n=F(e[0]??``);return n.ok?t.text===void 0?U(`ref`):{ok:!0,target:{kind:`ref`,ref:n.ref},refGeneration:n.generation,text:t.text}:{ok:!1,response:n.response}}case`point`:return t.text===void 0?U(`coordinates`):{ok:!0,target:{kind:`point`,x:t.target.x,y:t.target.y},text:t.text};case`selector`:return t.text===void 0||t.text.length>0&&!t.text.trim()?U(`selector`):{ok:!0,target:{kind:`selector`,selector:t.target.selector},text:t.text}}}function Ze(e){try{return he(e)}catch{return null}}function Qe(e){let t=`evidence`in e?e.evidence:void 0,n=e.settle;return e.kind===`ref`?{ref:me(e.target?.kind===`ref`?e.target.ref:void 0),refLabel:e.refLabel,selectorChain:e.selectorChain,targetHittable:e.targetHittable,hint:e.hint,evidence:t,settle:n,resolution:e.resolution}:e.kind===`selector`?{selector:e.target?.kind===`selector`?e.target.selector:void 0,selectorChain:e.selectorChain,refLabel:e.refLabel,targetHittable:e.targetHittable,hint:e.hint,evidence:t,settle:n,resolution:e.resolution}:{evidence:t,settle:n}}function $e(e,t){return e.kind===`point`?`coordinate tap`:t.kind===`ref`&&t.target?.kind===`ref`?t.target.ref:t.kind===`selector`&&t.target?.kind===`selector`?t.target.selector:`target`}function et(e){let t=e.at(-1);return e.length>1&&nt(t)?{targetPositionals:e.slice(0,-1),duration:{durationMs:Number(t)}}:{targetPositionals:e,duration:{}}}function tt(e){return e===void 0?{}:{durationMs:Number(e)}}function nt(e){return e===void 0||e.trim()===``?!1:Number.isFinite(Number(e))}const rt={source:`direct-ios`,kind:`not-observed`};function W(e,t){if(!it(e))return t;let{resolution:n,...r}=t;return r}function it(e){return`dispatchPath`in e&&e.dispatchPath===`maestro-non-hittable-fallback`}function at(e){return G({source:{kind:`corroborated-tap`,targetKind:e.targetKind,data:{warning:e.warning},publicData:{warning:e.warning},point:e.point,resolution:e.resolution},referenceFrame:e.referenceFrame,extra:e.extra})}function G(e){let{source:t,referenceFrame:n,extra:r}=e;if(t.kind===`runner-payload`||t.kind===`corroborated-tap`){let e={targetKind:t.targetKind,...W(t,{resolution:t.kind===`runner-payload`?rt:t.resolution}),...r??{}};return{result:z({data:t.data,fallbackX:t.point?.x,fallbackY:t.point?.y,referenceFrame:n,extra:e}),responseData:z({data:t.publicData,fallbackX:t.point?.x,fallbackY:t.point?.y,referenceFrame:n,extra:e})}}let{result:i}=t,a={targetKind:i.kind,...W(t,Qe(i)),...ct(i.settle,e.settleRefsGeneration),...r??{}},o=z({data:i.backendResult,fallbackX:i.point?.x,fallbackY:i.point?.y,referenceFrame:n,extra:{...a,...st(i)}}),s=z({data:t.publicData,fallbackX:i.point?.x,fallbackY:i.point?.y,referenceFrame:n,extra:a}),c=lt(`warning`in i?i.warning:void 0,e.staleRefsWarning);return c&&(o.warning=c,s.warning=c),`readiness`in i&&i.readiness&&(s.readiness=i.readiness),{result:o,responseData:s,...ot(i)}}function ot(e){let t=K(e)?.node??(`node`in e?e.node:void 0),n=`preAction`in e?e.preAction?.nodes:void 0;return t&&n?{recordedTarget:{node:t,preActionNodes:n}}:{}}function st(e){let t=K(e);return t?{selectorChain:t.selectorChain,refLabel:t.refLabel}:{}}function K(e){return`recordingTarget`in e?e.recordingTarget:void 0}function ct(e,t){return!e?.diff||t===void 0?{}:{settle:{...e,refsGeneration:t}}}function lt(e,t){return t?e?`${e} ${t}`:t:e}async function ut(e){let{params:t,result:n,publicData:r,extra:i}=e,a=n.kind===`point`?await He({ref:t.sessionRef,flags:t.req.flags,sessionStore:t.sessionStore,contextFromFlags:t.contextFromFlags,captureSnapshotForSession:t.captureSnapshotForSession,observation:t.androidObservation}):void 0,o=t.sessionStore.resolveCurrent(t.sessionRef),s=o?n.kind===`point`?a:w(o.snapshot?.nodes??[]):void 0,c=o?n:{...n,settle:void 0};return G({source:{kind:`runtime`,result:c,publicData:r},referenceFrame:s,extra:i,staleRefsWarning:e.staleRefsWarning,settleRefsGeneration:C(t.sessionRef,t.sessionStore,c.settle)})}function q(e){return e.command?Re({command:e.command,input:e.flags,data:e.data}):R(e.data)}function dt(e,t){return e===`click`||e===`press`||e===`fill`?e:t}function J(e,t){if(!e)return{used:!1,extra:{}};let n=t?.maestroNonHittableCoordinateFallbackUsed===!0;return{used:n,extra:{maestroNonHittableCoordinateFallbackAllowed:!0,maestroNonHittableCoordinateFallbackUsed:n,...n?{maestroFallbackReason:`non-hittable-coordinate`}:{}}}}function ft(e){let{error:t,snapshotGeneration:n,publishPartialRefs:a}=e;if(t.code!==`AMBIGUOUS_MATCH`)return t;let o=i(t.details);return o.length===0||n===void 0?t:(a(o),new r(t.code,t.message,{...t.details,refsGeneration:n},t.cause))}async function pt(e,t,n){let i=await Ne(e,n);if(i){if(i.permissionDialog)return`press ${t} opened an Android permission dialog (${i.foregroundPackage}) over ${i.expectedPackage}. ${i.hint}`;throw new r(`COMMAND_FAILED`,`press ${t} left ${e.appBundleId} and foregrounded ${i.foregroundPackage}. The tap likely escaped the app.`,i)}}function mt(e){return e.code===`COMMAND_FAILED`&&typeof e.details?.expectedPackage==`string`&&typeof e.details?.foregroundPackage==`string`}async function Y(e){let t=e.sessionStore.resolveCurrent(e.ref);if(!t||!ht(e,t))return;let n=_t(t.snapshot);if(!n)return;let r=await vt(e,n.snapshot.snapshotQuality,n.presentation);if(!(!r||!yt(n.snapshot,r,e.command)))return St(n.snapshot,r,e.command)}function ht(t,n){return gt(t.command)&&e(t.error).code===`XCTEST_RECORDED_FAILURE`&&Ce(n,{skipPendingPostGestureStabilization:!1})}function gt(e){return e===`click`||e===`press`}function _t(e){if(!X(e))return;let t=Date.now()-e.createdAt;if(t<0||t>15e3){l({level:`debug`,phase:`ios_tap_failure_corroboration_stale_baseline`,data:{ageMs:t}});return}let n=Ct(e.presentationKey);if(n){if(n.raw){l({level:`debug`,phase:`ios_tap_failure_corroboration_raw_baseline`,data:{presentationKey:e.presentationKey}});return}return{snapshot:e,presentation:n}}}async function vt(e,t,n){try{let r=be(t);return await e.captureSnapshotForSession(e.ref,Ot(e.flags,n),e.sessionStore,e.contextFromFlags,{interactiveOnly:n?.interactiveOnly??!0,...r?{preferredBackend:r}:{},signal:_e(e.requestId)})}catch(t){l({level:`debug`,phase:`ios_tap_failure_corroboration_capture_failed`,data:{command:e.command,error:t instanceof Error?t.message:String(t)}});return}}function yt(e,t,n){let r=bt(e,t);return r===void 0?xt(e,t,n):r?!0:(l({level:`debug`,phase:`ios_tap_failure_corroboration_identity_mismatch`,data:{command:n}}),!1)}function bt(e,t){if(e.comparisonKey!==void 0||t.comparisonKey!==void 0)return e.comparisonKey!==void 0&&e.comparisonKey===t.comparisonKey}function xt(e,t,n){let r=e.snapshotQuality?.backend,i=t.snapshotQuality?.backend;return!r||r!==i?(l({level:`debug`,phase:`ios_tap_failure_corroboration_backend_mismatch`,data:{command:n,baselineBackend:r,afterBackend:i}}),!1):e.presentationKey===t.presentationKey||(l({level:`debug`,phase:`ios_tap_failure_corroboration_scope_mismatch`,data:{command:n,baselinePresentationKey:e.presentationKey,afterPresentationKey:t.presentationKey}}),!1)}function St(e,t,n){if(!X(t))return;let r=ue(e.nodes),i=ue(t.nodes);if(r.digest!==i.digest)return l({level:`warn`,phase:`ios_tap_failure_corroborated`,data:{command:n,beforeNodeCount:r.nodeCount,afterNodeCount:i.nodeCount}}),{warning:`XCTest reported the tap as failed, but a same-scope post-action accessibility capture changed; treating the tap as landed. Observe the current screen before issuing another tap.`}}function X(e){return!!(e&&e.nodes.length>0&&!xe(e.snapshotQuality))}function Ct(e){if(!e)return;let t;try{t=JSON.parse(e)}catch{return}return wt(t)}function wt(e){let t=Tt(e);if(!(!t||typeof t.interactiveOnly!=`boolean`||typeof t.raw!=`boolean`)&&!(!Et(t.depth)||!Dt(t.scope)))return{interactiveOnly:t.interactiveOnly,...typeof t.depth==`number`?{depth:t.depth}:{},...typeof t.scope==`string`?{scope:t.scope}:{},raw:t.raw}}function Tt(e){return typeof e==`object`&&e?e:void 0}function Et(e){return e==null||typeof e==`number`}function Dt(e){return e==null||typeof e==`string`}function Ot(e,t){if(!(!e&&!t))return{...e??{},out:void 0,...t?{snapshotDepth:t.depth,snapshotScope:t.scope,snapshotRaw:t.raw}:{}}}function kt(e){return e.kind===`selector`?{selector:e.selector}:e.kind===`ref`?{ref:e.ref.startsWith(`@`)?e.ref.slice(1):e.ref}:{}}async function At(e,t,n,r,i){if(e.lease?.leaseProvider)return{aborted:!1,readiness:{status:`clear`},runtimeResult:await r()};let a=await E({session:e,command:t,phase:`before-command`,observation:i});if(n.refContext&&a.status===`recovered`){let t=A({ref:n.refContext.ref,mintedGeneration:n.refContext.mintedGeneration,staleRefsWarning:n.refContext.staleRefsWarning,frame:x({session:e,ref:n.refContext.ref,mintedGeneration:n.refContext.mintedGeneration})});if(t)return{aborted:!0,response:t}}let o=await r();return await E({session:e,command:t,phase:`after-command`,observation:i}),{aborted:!1,readiness:a,runtimeResult:o}}async function Z(t,n){if(t=N(t),!t.sessionRef)return a();let r=t.sessionStore.requireCurrent(t.sessionRef),i=k({...t,touchExecutor:n.touchExecutor}),o=Date.now();try{let e,a=await At(r,t.req.command,{refContext:n.refContext},async()=>{let t=await n.run(i);return e=await n.afterRun?.(t),t},t.androidObservation);if(a.aborted)return a.response;let{readiness:s,runtimeResult:c}=a,l=Date.now(),{result:u,responseData:d,recordedTarget:f}=await n.buildPayloads(c),p=[...s.status===`recovered`?[s.warning]:[],...e?[e]:[]];if(p.length>0){let e=[...typeof d.warning==`string`?[d.warning]:[],...p].join(` `);u.warning=e,d.warning=e}return j({ref:t.sessionRef,sessionStore:t.sessionStore,command:t.req.command,positionals:t.req.positionals??[],flags:t.req.flags,result:u,responseData:d,recordedTarget:f,actionStartedAt:o,actionFinishedAt:l,androidFreshnessBaseline:n.androidFreshnessBaseline})}catch(i){let a=ft({error:e(i),snapshotGeneration:r.snapshotGeneration,publishPartialRefs:e=>ye(r,e)});if(mt(a))throw a;return a.code===`AMBIGUOUS_MATCH`?Q(a):await jt({error:a,handlerParams:t,session:r,target:n.iosTapCorroboration?.target,extra:n.iosTapCorroboration?.extra,actionStartedAt:o,androidFreshnessBaseline:n.androidFreshnessBaseline})||Q(a)}}async function jt(e){if(!e.target)return;let t=le(e.error);if(!t&&_(e.session))return;let n=await Y({error:e.error,command:e.handlerParams.req.command,requestId:e.handlerParams.req.meta?.requestId,flags:e.handlerParams.req.flags,ref:e.handlerParams.sessionRef,sessionStore:e.handlerParams.sessionStore,contextFromFlags:e.handlerParams.contextFromFlags,captureSnapshotForSession:e.handlerParams.captureSnapshotForSession});if(!n)return;let r=Mt({target:e.target,resolvedTarget:t,warning:n.warning,referenceFrame:w(e.session.snapshot?.nodes??[]),extra:e.extra});return j({ref:e.handlerParams.sessionRef,sessionStore:e.handlerParams.sessionStore,command:e.handlerParams.req.command,positionals:e.handlerParams.req.positionals??[],flags:e.handlerParams.req.flags,result:r.result,responseData:r.responseData,recordedTarget:r.recordedTarget,actionStartedAt:e.actionStartedAt,actionFinishedAt:Date.now(),androidFreshnessBaseline:e.androidFreshnessBaseline})}function Mt(e){return e.resolvedTarget?G({source:{kind:`runtime`,result:{...e.resolvedTarget,warning:e.warning}},referenceFrame:e.referenceFrame,extra:e.extra}):at({targetKind:e.target.kind,point:Nt(e.target),warning:e.warning,referenceFrame:e.referenceFrame,extra:{...kt(e.target),...e.extra??{}}})}function Nt(e){return e.kind===`point`?{x:e.x,y:e.y}:void 0}function Q(e){return{ok:!1,error:t(e)}}async function Pt(e,t,n,r){let i=await Oe({device:t.device,command:n,requiresCapture:r,inspectFacts:e.inspectFacts,bindDevice:e.bindDevice});return i.ok?{ok:!0,touchExecutor:ke(i.runtime,e.contextFromFlags(e.req.flags,t.appBundleId,t.trace?.outPath))}:{ok:!1,response:O(i.response)}}async function Ft(e){e=N(e);let t=await It(e);if(`response`in t)return t.response;let{parsedTarget:n,touchExecutor:r,staleRefsWarning:i}=t.admitted,{req:a,sessionName:o}=e,s=a.internal?.replayTargetGuard;return await Z(e,{touchExecutor:r,refContext:n.target.kind===`ref`&&a.internal?.findResolvedTarget===void 0?{ref:n.target.ref,mintedGeneration:n.refGeneration,staleRefsWarning:i}:void 0,run:async e=>await e.interactions.fill(n.target,n.text,{session:o,requestId:a.meta?.requestId,delayMs:a.flags?.delayMs,allowNonHittableCoordinateFallback:a.flags?.maestro?.allowNonHittableCoordinateFallback,verify:a.flags?.verify,settle:M(a.flags),expectedResolvedTarget:s,preresolvedTarget:a.internal?.findResolvedTarget}),buildPayloads:t=>Bt({ref:e.sessionRef,sessionStore:e.sessionStore,result:t,text:n.text,flags:a.flags,staleRefsWarning:i})})}async function It(e){try{let t=await Lt(e);return`response`in t?{response:O(t.response)}:t}catch(e){throw D(e)}}async function Lt(e){let{req:t}=e,n=Rt(e);if(`response`in n)return n;let{session:r,parsedTarget:i}=n,a=await Pt(e,r,`fill`,i.target.kind!==`point`);if(!a.ok)return{response:a.response};Fe({flags:t.flags,replayPlanStep:t.internal?.replayPlanStep===!0,isSessionRecording:_(r)});let o=we(`fill`,t.flags);if(o)return{response:o};let s=await zt(e,r,i.target,i.refGeneration);return s.response?{response:s.response}:{admitted:{session:r,parsedTarget:i,touchExecutor:a.touchExecutor,staleRefsWarning:s.staleRefsWarning}}}function Rt(e){let t=e.sessionStore.get(e.sessionName);if(!t)return{response:a()};let n=L(t,`fill`);if(n)return{response:n};let r=Xe(e.req.positionals??[]);return r.ok?{session:t,parsedTarget:r}:{response:r.response}}async function zt(e,t,n,r){if(n.kind!==`ref`)return{};let i=e.req.internal?.findResolvedTarget===void 0?S({session:t,ref:n.ref,mintedGeneration:r}):void 0,a=e.refSnapshotFlagGuardResponse(`fill`,e.req.flags);if(a)return{response:a,staleRefsWarning:i};let o=e.req.internal?.findResolvedTarget?null:A({ref:n.ref,mintedGeneration:r,staleRefsWarning:i,frame:x({session:t,ref:n.ref,mintedGeneration:r})});return o?{response:o,staleRefsWarning:i}:(await I(e,t),{staleRefsWarning:i})}function Bt(e){let{result:t,ref:n,sessionStore:r}=e,i=r.requireCurrent(n),a=J(e.flags?.maestro?.allowNonHittableCoordinateFallback===!0,t.backendResult),o=t.kind===`point`?void 0:w(i.snapshot?.nodes??[]);return G({source:{kind:`runtime`,result:t,publicData:q({command:`fill`,flags:e.flags,data:t.backendResult}),...a.used?{dispatchPath:`maestro-non-hittable-fallback`}:{}},referenceFrame:o,extra:{text:e.text,...a.extra},staleRefsWarning:e.staleRefsWarning,settleRefsGeneration:C(n,r,t.settle)})}async function Vt(e,n,r,i){let a=e,o={selector:r.raw},s=Date.now();b(n);try{let e=await i(r)??{},t=Date.now(),n=Ut(e),c=q({command:dt(a.req.command,`press`),flags:a.req.flags,data:e}),l=J(r.allowNonHittableCoordinateFallback===!0,e),{result:u,responseData:d}=G({source:{kind:`runner-payload`,targetKind:`selector`,data:e,publicData:c,point:n,dispatchPath:l.used?`maestro-non-hittable-fallback`:`maestro-direct-selector`},referenceFrame:Wt(e),extra:{...o,...l.extra}});return j({ref:a.sessionRef,sessionStore:a.sessionStore,command:a.req.command,positionals:a.req.positionals??[],flags:a.req.flags,result:u,responseData:d,actionStartedAt:s,actionFinishedAt:t})}catch(e){return await Ht({error:e,handlerParams:a,extra:o,positionals:[],actionStartedAt:s})||(Ee(e,{delegateSemanticFailures:r.allowNonHittableCoordinateFallback!==!0})?(l({level:`debug`,phase:`ios_direct_selector_tap_fallback`,data:{selector:r.raw,error:e instanceof Error?e.message:String(e)}}),null):{ok:!1,error:t(e)})}}async function Ht(e){let{error:t,handlerParams:n,extra:r,positionals:i,actionStartedAt:a}=e,o=await Y({error:t,command:n.req.command,requestId:n.req.meta?.requestId,flags:n.req.flags,ref:n.sessionRef,sessionStore:n.sessionStore,contextFromFlags:n.contextFromFlags,captureSnapshotForSession:n.captureSnapshotForSession});if(!o)return;let{result:s,responseData:c}=at({targetKind:`selector`,warning:o.warning,resolution:{source:`direct-ios`,kind:`not-observed`},extra:r});return j({ref:n.sessionRef,sessionStore:n.sessionStore,command:n.req.command,positionals:n.req.positionals??i,flags:n.req.flags,result:s,responseData:c,actionStartedAt:a,actionFinishedAt:Date.now()})}function Ut(e){let t=typeof e.x==`number`?e.x:void 0,n=typeof e.y==`number`?e.y:void 0;return t!==void 0&&n!==void 0?{x:t,y:n}:{x:0,y:0}}function Wt(e){return typeof e.referenceWidth==`number`&&typeof e.referenceHeight==`number`?{referenceWidth:e.referenceWidth,referenceHeight:e.referenceHeight}:void 0}function Gt(e){let{session:t,commandLabel:n,target:r,flags:i}=e;return!e.tapElementSelectorAvailable||i?.maestro?.allowNonHittableCoordinateFallback!==!0||n!==`click`||r.kind!==`selector`||_(t)||Jt(i)||p(n)&&i?.verify===!0||ee(n)&&i?.settle===!0?null:Kt(t,r.selector,i)}function Kt(e,t,n){let r=Te({session:e,selectorExpression:t});return r?{...r,...n?.maestro?.allowNonHittableCoordinateFallback?{allowNonHittableCoordinateFallback:!0}:{},...n?.maestro?.expectedTapPoint?{expectedPoint:n.maestro.expectedTapPoint}:{}}:null}const qt=[`count`,`intervalMs`,`holdMs`,`jitterPx`,`doubleTap`];function Jt(e){return qt.some(t=>e?.[t]!==void 0)?!0:e?.clickButton!==void 0&&e.clickButton!==`primary`}const Yt=new Set([`press`,`click`]);async function Xt(e,t){let n=await Zt(e,t);return`response`in n?{response:O(n.response)}:n}async function Zt(e,t){let{req:n,sessionStore:r,sessionName:i}=e,o=r.get(i);if(!o)return{response:a()};let s=t===`click`?`click`:t,c=Qt(o,t,s,n.flags);if(c)return{response:c};let l=n.positionals??[],u=t===`longpress`?Ye(l):H(l,s);if(!u.ok)return{response:u.response};let d=en(o,n,u),f=nn(e,o,t,u,d);if(f.response)return{response:f.response};let p=y(n.flags);return{admitted:{session:o,commandLabel:s,clickButton:p,resultButtonTag:fe(p),target:u.target,durationMs:t===`longpress`?u.durationMs:void 0,staleRefsWarning:d,refContext:tn(n,u,d)}}}function Qt(e,t,n,r){return L(e,n)||we(t,r)||$t(e,t,n,r)}function $t(e,t,n,r){let i=y(r);if(!Yt.has(t)||i===`primary`)return;let a=pe({commandLabel:n,platform:d(e.device),button:i,count:r?.count,intervalMs:r?.intervalMs,holdMs:r?.holdMs,jitterPx:r?.jitterPx,doubleTap:r?.doubleTap});if(a)return s(a.code,a.message,a.details)}function en(e,t,n){if(n.target.kind===`ref`&&t.internal?.findResolvedTarget===void 0)return S({session:e,ref:n.target.ref,mintedGeneration:n.refGeneration})}function tn(e,t,n){if(t.target.kind===`ref`&&e.internal?.findResolvedTarget===void 0)return{ref:t.target.ref,mintedGeneration:t.refGeneration,staleRefsWarning:n}}function nn(e,t,n,r,i){let{req:a}=e;if(r.target.kind!==`ref`)return{};let o=e.refSnapshotFlagGuardResponse(n===`click`?`press`:n,a.flags);if(o)return{response:o};let s=a.internal?.findResolvedTarget?null:A({ref:r.target.ref,mintedGeneration:r.refGeneration,staleRefsWarning:i,frame:x({session:t,ref:r.target.ref,mintedGeneration:r.refGeneration})});return s?{response:s}:{}}async function $(e,t){e=N(e);let n=await Xt(e,t);if(`response`in n)return n.response;let{admitted:r}=n,i=await Pt(e,r.session,t,r.target.kind!==`point`);if(!i.ok)return i.response;let{touchExecutor:a}=i,o=r.target.kind===`ref`?await I(e,r.session):void 0,s={...r,androidFreshnessBaseline:o},c=e.req.internal?.replayTargetGuard?null:Gt({session:s.session,commandLabel:s.commandLabel,target:s.target,flags:e.req.flags,tapElementSelectorAvailable:a.tapElementSelector!==void 0});if(c&&a.tapElementSelector){let t=await Vt(e,s.session,c,a.tapElementSelector);if(t)return t}return await Z(e,{...rn(e,t,s),touchExecutor:a})}function rn(e,t,n){let{req:r,sessionName:i}=e,{session:a,target:o,durationMs:s,staleRefsWarning:c,resultButtonTag:l}=n,u=t===`longpress`?{...s===void 0?{}:{durationMs:s},gesture:`longpress`}:t===`hover`?{gesture:`hover`}:l;return{androidFreshnessBaseline:n.androidFreshnessBaseline,refContext:n.refContext,iosTapCorroboration:{target:o,extra:u},run:async e=>await an({runtime:e,command:t,target:o,sessionName:i,requestId:r.meta?.requestId,clickButton:n.clickButton,flags:r.flags,durationMs:s,expectedResolvedTarget:r.internal?.replayTargetGuard,preresolvedTarget:r.internal?.findResolvedTarget}),afterRun:async t=>{if(!a.lease?.leaseProvider)return await pt(a,$e(o,t),e.androidObservation)},buildPayloads:async n=>{let i=sn(n);return await ut({params:e,result:n,staleRefsWarning:c,publicData:q({command:t===`longpress`||t===`hover`?void 0:t,flags:r.flags,data:n.backendResult}),extra:t===`longpress`?{...i===void 0?{}:{durationMs:i},gesture:`longpress`}:t===`hover`?{gesture:`hover`}:l})}}}async function an(e){let{runtime:t,command:n,target:r,sessionName:i,requestId:a,flags:o,expectedResolvedTarget:s}=e,c={session:i,requestId:a,settle:M(o),expectedResolvedTarget:s};switch(n){case`longpress`:return await t.interactions.longPress(r,{...c,durationMs:e.durationMs,readinessTimeoutMs:o?.readinessTimeoutMs});case`hover`:return await t.interactions.hover(r,c);case`click`:return await t.interactions.click(r,on(e,c));case`press`:return await t.interactions.press(r,on(e,c))}}function on(e,t){let{flags:n}=e;return{...t,button:e.clickButton,count:n?.count,intervalMs:n?.intervalMs,holdMs:n?.holdMs,jitterPx:n?.jitterPx,doubleTap:n?.doubleTap,verify:n?.verify,readinessTimeoutMs:n?.readinessTimeoutMs,preresolvedTarget:e.preresolvedTarget}}function sn(e){return`durationMs`in e?e.durationMs:void 0}function cn(e,t={}){let n=typeof t.executionProfile==`string`?t.executionProfile:void 0;return{kind:e.kind,durationMs:e.durationMs,pointerCount:e.pointerCount,from:e.from,to:e.to,...e.kind===`drag`?{targets:e.targets}:{},...e.backendResult??{},...t,...n?{timing:{executionProfile:n,gestureDurationMs:e.durationMs}}:{},message:e.message}}function ln(e){return`refused`in e}async function un(e){return e=N(e),await gn(e,`gesture`,async(t,n)=>dn(e,t,n))}async function dn(e,t,n){let r=ie(e.req.input),i=vn(r,t,n);i.intent===`pan`&&e.req.internal?.gestureExecutionProfile&&(i.executionProfile=e.req.internal.gestureExecutionProfile);let a=await P({device:t.device,input:i,inspectFacts:e.inspectFacts,bindDevice:e.bindDevice});return a.ok?pn(r,i,await fn(hn(e,a.gestures),{session:e.sessionName,requestId:e.req.meta?.requestId},i,e.req.internal),e.req.flags):{refused:a.response}}async function fn(e,t,n,r){if(n.intent!==`drag`)return await e.interactions.gesture({...t,gesture:n});let i=r?.replayTargetGuards??(r?.replayTargetGuard?{source:r.replayTargetGuard}:void 0);return await e.interactions.gesture({...t,gesture:n,...i?{expectedResolvedTargets:i}:{}})}function pn(e,t,n,r){let i=n.kind===`drag`?n.recording:void 0,a=i?.sourceTarget,o=i?.destinationTarget;return{positionals:bn(e,i),flags:Dn(e,r),responseData:cn(n,{executionProfile:_n(t)}),...e.kind===`pinch`?{recordingResultExtra:{scale:e.scale}}:a?{recordingResultExtra:{selectorChain:a.selectorChain}}:{},...a&&o?{recordedTargets:{source:{node:a.node,preActionNodes:a.preActionNodes},destination:{node:o.node,preActionNodes:o.preActionNodes}}}:{}}}async function mn(e){return e=N(e),await gn(e,`swipe`,async t=>{let n=xn(e.req.input),r=await P({device:t.device,input:m(n).gesture,inspectFacts:e.inspectFacts,bindDevice:e.bindDevice});if(!r.ok)return{refused:r.response};let i=n.count??1,a=n.pauseMs??0,o=n.pattern??`one-way`,s=await Tn(hn(e,r.gestures),e,n,i,a,o);return{positionals:wn(n),flags:e.req.flags,responseData:cn(s,{from:n.from,to:n.to,x1:n.from.x,y1:n.from.y,x2:n.to.x,y2:n.to.y,effectiveDurationMs:s.durationMs,timingMode:`direct`,executionProfile:`endpoint-hold`,count:i,pauseMs:a,pattern:o})}})}function hn(e,t){return k({...e,gestures:t,pairedGestureViewport:e.req.internal?.gestureViewport})}async function gn(e,n,r){let i=e.sessionStore.get(e.sessionName);if(!i)return a();let o=Date.now();try{let t=g(i.device),a=t?{status:`clear`}:await E({session:i,command:n,phase:`before-command`,observation:e.androidObservation}),s=await r(i,a);if(ln(s))return s.refused;t||await E({session:i,command:n,phase:`after-command`,observation:e.androidObservation});let c={...s.responseData};return a.status===`recovered`&&(c.warning=`${typeof c.warning==`string`?`${c.warning} `:``}${a.warning}`),j({ref:e.sessionRef,sessionStore:e.sessionStore,command:n,actionCommand:n,positionals:s.positionals,flags:s.flags,result:{...c,...s.recordingResultExtra??{}},responseData:c,recordedTargets:s.recordedTargets,actionStartedAt:o,actionFinishedAt:Date.now()})}catch(e){return{ok:!1,error:t(e)}}}function _n(e){if(e.intent===`fling`)return`endpoint-hold`;if(e.intent===`pan`)return e.executionProfile??`timed-pan`;if(e.intent===`drag`)return`timed-pan`}function vn(t,n,r){let i=ae(t);if(i.intent!==`drag`)return i;try{return{...i,source:yn(i.source,n),destination:yn(i.destination,n)}}catch(t){if(r.status===`recovered`){let n=e(t),i=typeof n.details?.warning==`string`?n.details.warning+` `:``;throw n.details={...n.details,warning:i+r.warning},n}throw D(t)}}function yn(e,t){if(!e.startsWith(`@`))return e;let i=n(e);if(!i)throw new r(`INVALID_ARGS`,`Invalid ref "${e}" — malformed generation suffix.`,{hint:o});return De({ref:i.base,mintedGeneration:i.generation,frame:x({session:t,ref:i.base,mintedGeneration:i.generation})}),i.base}function bn(e,t){return e.kind!==`drag`||!t?h(e):h({...e,source:t.sourceSelector??e.source,destination:t.destinationSelector??e.destination})}function xn(e){if(!e||typeof e!=`object`||Array.isArray(e))throw new r(`INVALID_ARGS`,`swipe requires structured object input`);oe(e);let t=e,n=t.pattern;if(n!==void 0&&n!==`one-way`&&n!==`ping-pong`)throw new r(`INVALID_ARGS`,`swipe pattern must be one-way or ping-pong`);let i={from:Cn(t.from,`swipe from`),to:Cn(t.to,`swipe to`),count:c(t,`count`,{min:1,max:200}),pauseMs:c(t,`pauseMs`,{min:0,max:re}),pattern:n};return Sn(i),i}function Sn(e){let t=e.count??1,n=e.pauseMs??0,i=t*100+Math.max(0,t-1)*n;if(!(i<=6e4))throw new r(`INVALID_ARGS`,`Swipe series must fit within ${ne}ms.`,{count:t,pauseMs:n,gestureDurationMs:100,scheduledDurationMs:i,hint:`Reduce --count or --pause-ms.`})}function Cn(e,t){if(!e||typeof e!=`object`||Array.isArray(e))throw new r(`INVALID_ARGS`,`${t} must be a point`);let n=e;if(typeof n.x!=`number`||!Number.isFinite(n.x))throw new r(`INVALID_ARGS`,`${t} x must be finite`);if(typeof n.y!=`number`||!Number.isFinite(n.y))throw new r(`INVALID_ARGS`,`${t} y must be finite`);return{x:n.x,y:n.y}}function wn(e){return[String(e.from.x),String(e.from.y),String(e.to.x),String(e.to.y)]}async function Tn(e,t,n,r,i,a){let o;for(let s=0;s<r;s+=1){let c=m(En(n,a,s));o=await e.interactions.gesture({session:t.sessionName,requestId:t.req.meta?.requestId,gesture:c.gesture}),i>0&&s+1<r&&await ge(i)}if(!o)throw Error(`Swipe orchestration did not execute a gesture.`);return o}function En(e,t,n){return t!==`ping-pong`||n%2!=1?e:{...e,from:e.to,to:e.from}}function Dn(e,t){return e.kind!==`pan`||e.pointerCount===void 0?t:{...t,pointerCount:e.pointerCount}}async function On(e){let t={},n=e.sessionRef,r=await kn({...e,sessionRef:n,refSnapshotFlagGuardResponse:Ae,captureProof:t});return r&&se({response:r,consumedTree:t,captureProof:t})}async function kn(e){switch(e.req.command){case`press`:return await $(e,`press`);case`click`:return await $(e,`click`);case`longpress`:return await $(e,`longpress`);case`hover`:return await $(e,`hover`);case`fill`:return await Ft(e);default:return await An(e)}}async function An(e){switch(e.req.command){case v.gesture:return await un(e);case v.swipe:return await mn(e);case v.type:return await jn(e);case`get`:return await Me(e);case`is`:return await je(e);default:return null}}async function jn(e){let{sessionName:t,sessionStore:n}=e,r=n.get(t);if(!r)return a();let i=await Pe({device:r.device,inspectFacts:e.inspectFacts,bindDevice:e.bindDevice});if(!i.ok)return i.response;let o=await Mn(r,e.androidObservation);return o.response?o.response:await Nn(e,r,i.typeText,o.warning)}async function Mn(e,t){if(e.device.platform===`android`&&e.screenRecording){let n=await Se({session:e,observation:t});if(n.status===`failed`)return{response:s(`COMMAND_FAILED`,`Android system dialog blocked the recording session`)};if(n.status===`unknown`)return{warning:n.warning}}return{}}async function Nn(e,n,r,i){let{req:a,sessionStore:o}=e,s=Date.now();try{let t=await E({session:n,command:a.command,phase:`before-command`,observation:e.androidObservation});b(n);let c=await r(a.positionals??[],e.contextFromFlags(a.flags,n.appBundleId,n.trace?.outPath));await E({session:n,command:a.command,phase:`after-command`,observation:e.androidObservation});let l=Date.now(),u={...c};return Pn(u,i,t),j({ref:e.sessionRef,sessionStore:o,command:a.command,positionals:a.positionals??[],flags:a.flags,result:u,responseData:u,actionStartedAt:s,actionFinishedAt:l})}catch(e){return{ok:!1,error:t(e)}}}function Pn(e,t,n){let r=[typeof e.warning==`string`?e.warning:void 0,t];n.status===`recovered`&&r.push(n.warning);let i=r.filter(e=>typeof e==`string`&&e.length>0).join(` `);i.length>0&&(e.warning=i)}export{On as handleInteractionCommands};
|
|
1
|
+
import{F as e,J as t,M as n,P as r,f as i,h as a,s as o}from"./sdk-contracts.js";import{m as s}from"./sdk-batch-runner.js";import{r as c}from"./diagnostics.js";import"./diagnostics2.js";import{E as l,g as u}from"./sdk-device.js";import{g as d,h as f,m as p,w as ee}from"./sdk-batch.js";import{c as te,o as ne}from"./scroll-gesture.js";import{C as m,E as re,S as ie,v as ae,x as oe}from"./script.js";import{c as se}from"./target-evidence.js";import{F as ce,n as h,p as g}from"./provider-device-admission.js";import{S as le,v as ue}from"./runtime.js";import{n as _}from"./catalog.js";import{r as de}from"./success-text.js";import{i as v,n as fe,r as pe}from"./click-button.js";import{r as me,t as he}from"./interaction-positionals.js";import{i as ge}from"./retry.js";import"./retry2.js";import"./gesture-plan.js";import{r as _e}from"./request-cancel.js";import"./request.js";import{P as y,a as b,i as ve,j as x,k as ye,n as S}from"./session-snapshot.js";import{c as be,s as xe}from"./quality-warnings.js";import{$ as C,et as w,n as T,nt as Se,t as E,tt as D}from"./internal/daemon.js";import{a as Ce,c as we,i as O,l as Te,n as k,o as A,r as j,s as Ee,t as De,u as M}from"./interaction-ref-policy.js";import{n as Oe,t as ke}from"./touch-runtime2.js";import{t as N}from"./gesture-runtime.js";import{d as Ae,g as P,i as je,r as Me,u as Ne}from"./selector-runtime.js";import{n as Pe}from"./type-text-runtime.js";function Fe(e){let t=e.flags?.recordAs;if(t!==void 0){if(ce(t),e.flags?.noRecord)throw new r(`INVALID_ARGS`,`fill --record-as cannot be combined with --no-record because no script step would be published.`);if(!e.isSessionRecording&&!e.replayPlanStep)throw new r(`INVALID_ARGS`,`fill --record-as requires an armed script recording. Start a fresh session with open --save-script, then retry the fill.`)}}async function F(e,t){if(!ye(t))return;let n=t.snapshot?.comparisonSafe===!0?t.snapshot:void 0;try{await e.captureSnapshotForSession(e.sessionRef,e.req.flags,e.sessionStore,e.contextFromFlags,{interactiveOnly:!0,androidFreshnessMode:`ref-refresh`})}catch(t){c({level:`warn`,phase:`android_ref_snapshot_refresh_failed`,data:{command:e.req.command,error:t instanceof Error?t.message:String(t)}})}return n}function I(e,t){return!u(e.device)||e.surface!==`desktop`&&e.surface!==`menubar`||e.surface===`menubar`&&(t===`click`||t===`press`)?null:o(`UNSUPPORTED_OPERATION`,`${t} is not supported on macOS ${e.surface} sessions yet. Open an app session to act, or use the ${e.surface} surface to inspect.`)}const Ie=new Set(d()),Le=new Set([`currentUptimeMs`,`gestureEndUptimeMs`,`gestureStartUptimeMs`,`sequenceResults`]);function L(e){if(e)return Object.fromEntries(Object.entries(e).filter(([e])=>!Le.has(e)))}function Re(e){return Be({fields:ze(e.command),input:e.input??{},data:L(e.data),controlledFields:Ie})}function ze(e){let t=ee(e);if(!t)throw Error(`Missing response data transform descriptor for ${e}`);return t.fields}function Be(e){let t=Object.fromEntries(Object.entries(e.data??{}).filter(([t])=>!e.controlledFields.has(t)));for(let[n,r]of Object.entries(e.fields)){let i=e.input[n]===void 0?r.defaultValue:e.input[n];if(i===void 0||r.omitDefault===!0&&i===r.defaultValue){delete t[n];continue}t[n]=i}return Object.fromEntries(Object.entries(t).filter(([,e])=>e!==void 0))}async function Ve(e){let{ref:t,flags:n,sessionStore:r,contextFromFlags:i,captureSnapshotForSession:a,observation:o}=e,s=r.resolveCurrent(t);if(!s)return;let c=s.screenRecording;if(!c)return;let l=c.handle,u=e=>{if(!(!e||r.resolveCurrent(t)?.screenRecording!==c))return l.setTouchReferenceFrame(e),e},d=l.inspect().touchReferenceFrame;if(d)return d;if(s.device.platform===`android`&&!s.lease?.leaseProvider&&!h(s.device)){if(!o)throw Error(`Android observation was not injected into the request`);let e=await o.readScreenSize(s.device);return u({referenceWidth:e.width,referenceHeight:e.height})}let f=C(s.snapshot);if(f)return u(f);let p=await a(t,n,r,i,{interactiveOnly:!0});return u(C(p))}async function He(e){try{return await Ve(e)}catch(t){let n=e.sessionStore.resolveCurrent(e.ref);if(!n)return;c({level:`warn`,phase:`touch_reference_frame_resolve_failed`,data:{platform:n.device.platform,error:t instanceof Error?t.message:String(t)}});return}}function R(e){let{data:t,fallbackX:n,fallbackY:r,referenceFrame:i,extra:a}=e,o=We(a,n,r)??(typeof t?.message==`string`?t.message:void 0);return Ue({...t??{},...n===void 0||r===void 0?{}:{x:n,y:r},...i??{},...a??{},...de(o)})}function Ue(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>e!==void 0))}function We(e,t,n){let r=z(e,`text`);if(r!==void 0)return`Filled ${Array.from(r).length} chars`;let i=Ge(t,n),a=Ke(e);if(a)return Je(a,e??{},i);if(i)return qe(e,i)}function z(e,t){let n=e?.[t];return typeof n==`string`?n:void 0}function Ge(e,t){return e===void 0||t===void 0?``:` (${e}, ${t})`}function Ke(e){let t=z(e,`ref`);return t===void 0?z(e,`selector`):`@${t}`}function qe(e,t){return e?.gesture===`longpress`?`Long pressed${t}`:e?.gesture===`hover`?`Hovered${t}`:`Tapped${t}`}function Je(e,t,n){let r=typeof t.button==`string`?t.button:void 0;return t.gesture===`longpress`?`Long pressed ${e}${n}`:t.gesture===`hover`?`Hovered ${e}${n}`:r&&r!==`primary`?`Clicked ${r} ${e}${n}`:`Tapped ${e}${n}`}function B(e){if(e.length<2)return null;let t=Number(e[0]),n=Number(e[1]);return!Number.isFinite(t)||!Number.isFinite(n)?null:{x:t,y:n}}function V(e,t){let n=B(e);if(n)return{ok:!0,target:{kind:`point`,x:n.x,y:n.y}};let r=e[0]??``;if(r.startsWith(`@`)){let t=P(r);return t.ok?{ok:!0,target:{kind:`ref`,ref:t.ref,fallbackLabel:e.slice(1).join(` `).trim()},refGeneration:t.generation}:{ok:!1,response:t.response}}let i=e.join(` `).trim();return i?{ok:!0,target:{kind:`selector`,selector:i}}:{ok:!1,response:o(`INVALID_ARGS`,`${t} requires @ref, selector expression, or x y coordinates`)}}function Ye(e){let t=B(e);if(t)return{ok:!0,target:{kind:`point`,x:t.x,y:t.y},...tt(e[2])};let n=et(e),r=V(n.targetPositionals,`longpress`);return r.ok?{ok:!0,target:r.target,refGeneration:r.refGeneration,...n.duration}:r}function H(e){return{ok:!1,response:o(`INVALID_ARGS`,`fill requires text after ${e} (use "" to clear the field)`)}}function Xe(e){let t=Ze(e);if(!t)return{ok:!1,response:o(`INVALID_ARGS`,`fill requires x y text, @ref text, or selector text`)};switch(t.kind){case`ref`:{let n=P(e[0]??``);return n.ok?t.text===void 0?H(`ref`):{ok:!0,target:{kind:`ref`,ref:n.ref},refGeneration:n.generation,text:t.text}:{ok:!1,response:n.response}}case`point`:return t.text===void 0?H(`coordinates`):{ok:!0,target:{kind:`point`,x:t.target.x,y:t.target.y},text:t.text};case`selector`:return t.text===void 0||t.text.length>0&&!t.text.trim()?H(`selector`):{ok:!0,target:{kind:`selector`,selector:t.target.selector},text:t.text}}}function Ze(e){try{return he(e)}catch{return null}}function Qe(e){let t=`evidence`in e?e.evidence:void 0,n=e.settle;return e.kind===`ref`?{ref:me(e.target?.kind===`ref`?e.target.ref:void 0),refLabel:e.refLabel,selectorChain:e.selectorChain,targetHittable:e.targetHittable,hint:e.hint,evidence:t,settle:n,resolution:e.resolution}:e.kind===`selector`?{selector:e.target?.kind===`selector`?e.target.selector:void 0,selectorChain:e.selectorChain,refLabel:e.refLabel,targetHittable:e.targetHittable,hint:e.hint,evidence:t,settle:n,resolution:e.resolution}:{evidence:t,settle:n}}function $e(e,t){return e.kind===`point`?`coordinate tap`:t.kind===`ref`&&t.target?.kind===`ref`?t.target.ref:t.kind===`selector`&&t.target?.kind===`selector`?t.target.selector:`target`}function et(e){let t=e.at(-1);return e.length>1&&nt(t)?{targetPositionals:e.slice(0,-1),duration:{durationMs:Number(t)}}:{targetPositionals:e,duration:{}}}function tt(e){return e===void 0?{}:{durationMs:Number(e)}}function nt(e){return e===void 0||e.trim()===``?!1:Number.isFinite(Number(e))}const rt={source:`direct-ios`,kind:`not-observed`};function U(e,t){if(!it(e))return t;let{resolution:n,...r}=t;return r}function it(e){return`dispatchPath`in e&&e.dispatchPath===`maestro-non-hittable-fallback`}function at(e){return W({source:{kind:`corroborated-tap`,targetKind:e.targetKind,data:{warning:e.warning},publicData:{warning:e.warning},point:e.point,resolution:e.resolution},referenceFrame:e.referenceFrame,extra:e.extra})}function W(e){let{source:t,referenceFrame:n,extra:r}=e;if(t.kind===`runner-payload`||t.kind===`corroborated-tap`){let e={targetKind:t.targetKind,...U(t,{resolution:t.kind===`runner-payload`?rt:t.resolution}),...r??{}};return{result:R({data:t.data,fallbackX:t.point?.x,fallbackY:t.point?.y,referenceFrame:n,extra:e}),responseData:R({data:t.publicData,fallbackX:t.point?.x,fallbackY:t.point?.y,referenceFrame:n,extra:e})}}let{result:i}=t,a={targetKind:i.kind,...U(t,Qe(i)),...ct(i.settle,e.settleRefsGeneration),...r??{}},o=R({data:i.backendResult,fallbackX:i.point?.x,fallbackY:i.point?.y,referenceFrame:n,extra:{...a,...st(i)}}),s=R({data:t.publicData,fallbackX:i.point?.x,fallbackY:i.point?.y,referenceFrame:n,extra:a}),c=lt(`warning`in i?i.warning:void 0,e.staleRefsWarning);return c&&(o.warning=c,s.warning=c),`readiness`in i&&i.readiness&&(s.readiness=i.readiness),{result:o,responseData:s,...ot(i)}}function ot(e){let t=G(e)?.node??(`node`in e?e.node:void 0),n=`preAction`in e?e.preAction?.nodes:void 0;return t&&n?{recordedTarget:{node:t,preActionNodes:n}}:{}}function st(e){let t=G(e);return t?{selectorChain:t.selectorChain,refLabel:t.refLabel}:{}}function G(e){return`recordingTarget`in e?e.recordingTarget:void 0}function ct(e,t){return!e?.diff||t===void 0?{}:{settle:{...e,refsGeneration:t}}}function lt(e,t){return t?e?`${e} ${t}`:t:e}async function ut(e){let{params:t,result:n,publicData:r,extra:i}=e,a=n.kind===`point`?await He({ref:t.sessionRef,flags:t.req.flags,sessionStore:t.sessionStore,contextFromFlags:t.contextFromFlags,captureSnapshotForSession:t.captureSnapshotForSession,observation:t.androidObservation}):void 0,o=t.sessionStore.resolveCurrent(t.sessionRef),s=o?n.kind===`point`?a:w(o.snapshot?.nodes??[]):void 0,c=o?n:{...n,settle:void 0};return W({source:{kind:`runtime`,result:c,publicData:r},referenceFrame:s,extra:i,staleRefsWarning:e.staleRefsWarning,settleRefsGeneration:S(t.sessionRef,t.sessionStore,c.settle)})}function K(e){return e.command?Re({command:e.command,input:e.flags,data:e.data}):L(e.data)}function dt(e,t){return e===`click`||e===`press`||e===`fill`?e:t}function q(e,t){if(!e)return{used:!1,extra:{}};let n=t?.maestroNonHittableCoordinateFallbackUsed===!0;return{used:n,extra:{maestroNonHittableCoordinateFallbackAllowed:!0,maestroNonHittableCoordinateFallbackUsed:n,...n?{maestroFallbackReason:`non-hittable-coordinate`}:{}}}}async function ft(e,t,n){let i=await Ne(e,n);if(i){if(i.permissionDialog)return`press ${t} opened an Android permission dialog (${i.foregroundPackage}) over ${i.expectedPackage}. ${i.hint}`;throw new r(`COMMAND_FAILED`,`press ${t} left ${e.appBundleId} and foregrounded ${i.foregroundPackage}. The tap likely escaped the app.`,i)}}function pt(e){return e.code===`COMMAND_FAILED`&&typeof e.details?.expectedPackage==`string`&&typeof e.details?.foregroundPackage==`string`}async function J(e){let t=e.sessionStore.resolveCurrent(e.ref);if(!t||!mt(e,t))return;let n=gt(t.snapshot);if(!n)return;let r=await _t(e,n.snapshot.snapshotQuality,n.presentation);if(!(!r||!vt(n.snapshot,r,e.command)))return xt(n.snapshot,r,e.command)}function mt(t,n){return ht(t.command)&&e(t.error).code===`XCTEST_RECORDED_FAILURE`&&we(n,{skipPendingPostGestureStabilization:!1})}function ht(e){return e===`click`||e===`press`}function gt(e){if(!Y(e))return;let t=Date.now()-e.createdAt;if(t<0||t>15e3){c({level:`debug`,phase:`ios_tap_failure_corroboration_stale_baseline`,data:{ageMs:t}});return}let n=St(e.presentationKey);if(n){if(n.raw){c({level:`debug`,phase:`ios_tap_failure_corroboration_raw_baseline`,data:{presentationKey:e.presentationKey}});return}return{snapshot:e,presentation:n}}}async function _t(e,t,n){try{let r=be(t);return await e.captureSnapshotForSession(e.ref,Dt(e.flags,n),e.sessionStore,e.contextFromFlags,{interactiveOnly:n?.interactiveOnly??!0,...r?{preferredBackend:r}:{},signal:_e(e.requestId)})}catch(t){c({level:`debug`,phase:`ios_tap_failure_corroboration_capture_failed`,data:{command:e.command,error:t instanceof Error?t.message:String(t)}});return}}function vt(e,t,n){let r=yt(e,t);return r===void 0?bt(e,t,n):r?!0:(c({level:`debug`,phase:`ios_tap_failure_corroboration_identity_mismatch`,data:{command:n}}),!1)}function yt(e,t){if(e.comparisonKey!==void 0||t.comparisonKey!==void 0)return e.comparisonKey!==void 0&&e.comparisonKey===t.comparisonKey}function bt(e,t,n){let r=e.snapshotQuality?.backend,i=t.snapshotQuality?.backend;return!r||r!==i?(c({level:`debug`,phase:`ios_tap_failure_corroboration_backend_mismatch`,data:{command:n,baselineBackend:r,afterBackend:i}}),!1):e.presentationKey===t.presentationKey||(c({level:`debug`,phase:`ios_tap_failure_corroboration_scope_mismatch`,data:{command:n,baselinePresentationKey:e.presentationKey,afterPresentationKey:t.presentationKey}}),!1)}function xt(e,t,n){if(!Y(t))return;let r=ue(e.nodes),i=ue(t.nodes);if(r.digest!==i.digest)return c({level:`warn`,phase:`ios_tap_failure_corroborated`,data:{command:n,beforeNodeCount:r.nodeCount,afterNodeCount:i.nodeCount}}),{warning:`XCTest reported the tap as failed, but a same-scope post-action accessibility capture changed; treating the tap as landed. Observe the current screen before issuing another tap.`}}function Y(e){return!!(e&&e.nodes.length>0&&!xe(e.snapshotQuality))}function St(e){if(!e)return;let t;try{t=JSON.parse(e)}catch{return}return Ct(t)}function Ct(e){let t=wt(e);if(!(!t||typeof t.interactiveOnly!=`boolean`||typeof t.raw!=`boolean`)&&!(!Tt(t.depth)||!Et(t.scope)))return{interactiveOnly:t.interactiveOnly,...typeof t.depth==`number`?{depth:t.depth}:{},...typeof t.scope==`string`?{scope:t.scope}:{},raw:t.raw}}function wt(e){return typeof e==`object`&&e?e:void 0}function Tt(e){return e==null||typeof e==`number`}function Et(e){return e==null||typeof e==`string`}function Dt(e,t){if(!(!e&&!t))return{...e??{},out:void 0,...t?{snapshotDepth:t.depth,snapshotScope:t.scope,snapshotRaw:t.raw}:{}}}function Ot(e){return e.kind===`selector`?{selector:e.selector}:e.kind===`ref`?{ref:e.ref.startsWith(`@`)?e.ref.slice(1):e.ref}:{}}async function kt(e,t,n,r,i){if(e.lease?.leaseProvider)return{aborted:!1,readiness:{status:`clear`},runtimeResult:await r()};let a=await D({session:e,command:t,phase:`before-command`,observation:i});if(n.refContext&&a.status===`recovered`){let t=k({ref:n.refContext.ref,mintedGeneration:n.refContext.mintedGeneration,staleRefsWarning:n.refContext.staleRefsWarning,frame:y({session:e,ref:n.refContext.ref,mintedGeneration:n.refContext.mintedGeneration})});if(t)return{aborted:!0,response:t}}let o=await r();return await D({session:e,command:t,phase:`after-command`,observation:i}),{aborted:!1,readiness:a,runtimeResult:o}}async function X(t,n){if(t=M(t),!t.sessionRef)return i();let r=t.sessionStore.requireCurrent(t.sessionRef),a={},o=Ce({...t,touchExecutor:n.touchExecutor,consumedCapture:a}),s=Date.now();try{let e,i=await kt(r,t.req.command,{refContext:n.refContext},async()=>{let t=await n.run(o);return e=await n.afterRun?.(t),t},t.androidObservation);if(i.aborted)return i.response;let{readiness:a,runtimeResult:c}=i,l=Date.now(),{result:u,responseData:d,recordedTarget:f}=await n.buildPayloads(c),p=[...a.status===`recovered`?[a.warning]:[],...e?[e]:[]];if(p.length>0){let e=[...typeof d.warning==`string`?[d.warning]:[],...p].join(` `);u.warning=e,d.warning=e}return A({ref:t.sessionRef,sessionStore:t.sessionStore,command:t.req.command,positionals:t.req.positionals??[],flags:t.req.flags,result:u,responseData:d,recordedTarget:f,actionStartedAt:s,actionFinishedAt:l,androidFreshnessBaseline:n.androidFreshnessBaseline})}catch(i){let o=ve(t.sessionRef,t.sessionStore,e(i),a.state);if(pt(o))throw o;return o.code===`AMBIGUOUS_MATCH`?Z(o):await At({error:o,handlerParams:t,session:r,target:n.iosTapCorroboration?.target,extra:n.iosTapCorroboration?.extra,actionStartedAt:s,androidFreshnessBaseline:n.androidFreshnessBaseline})||Z(o)}}async function At(e){if(!e.target)return;let t=le(e.error);if(!t&&g(e.session))return;let n=await J({error:e.error,command:e.handlerParams.req.command,requestId:e.handlerParams.req.meta?.requestId,flags:e.handlerParams.req.flags,ref:e.handlerParams.sessionRef,sessionStore:e.handlerParams.sessionStore,contextFromFlags:e.handlerParams.contextFromFlags,captureSnapshotForSession:e.handlerParams.captureSnapshotForSession});if(!n)return;let r=jt({target:e.target,resolvedTarget:t,warning:n.warning,referenceFrame:w(e.session.snapshot?.nodes??[]),extra:e.extra});return A({ref:e.handlerParams.sessionRef,sessionStore:e.handlerParams.sessionStore,command:e.handlerParams.req.command,positionals:e.handlerParams.req.positionals??[],flags:e.handlerParams.req.flags,result:r.result,responseData:r.responseData,recordedTarget:r.recordedTarget,actionStartedAt:e.actionStartedAt,actionFinishedAt:Date.now(),androidFreshnessBaseline:e.androidFreshnessBaseline})}function jt(e){return e.resolvedTarget?W({source:{kind:`runtime`,result:{...e.resolvedTarget,warning:e.warning}},referenceFrame:e.referenceFrame,extra:e.extra}):at({targetKind:e.target.kind,point:Mt(e.target),warning:e.warning,referenceFrame:e.referenceFrame,extra:{...Ot(e.target),...e.extra??{}}})}function Mt(e){return e.kind===`point`?{x:e.x,y:e.y}:void 0}function Z(e){return{ok:!1,error:t(e)}}async function Nt(e,t,n,r){let i=await Oe({device:t.device,command:n,requiresCapture:r,inspectFacts:e.inspectFacts,bindDevice:e.bindDevice});return i.ok?{ok:!0,touchExecutor:ke(i.runtime,e.contextFromFlags(e.req.flags,t.appBundleId,t.trace?.outPath))}:{ok:!1,response:E(i.response)}}async function Pt(e){e=M(e);let t=await Ft(e);if(`response`in t)return t.response;let{parsedTarget:n,touchExecutor:r,staleRefsWarning:i}=t.admitted,{req:a,sessionName:o}=e,s=a.internal?.replayTargetGuard;return await X(e,{touchExecutor:r,refContext:n.target.kind===`ref`&&a.internal?.findResolvedTarget===void 0?{ref:n.target.ref,mintedGeneration:n.refGeneration,staleRefsWarning:i}:void 0,run:async e=>await e.interactions.fill(n.target,n.text,{session:o,requestId:a.meta?.requestId,delayMs:a.flags?.delayMs,allowNonHittableCoordinateFallback:a.flags?.maestro?.allowNonHittableCoordinateFallback,verify:a.flags?.verify,settle:j(a.flags),expectedResolvedTarget:s,preresolvedTarget:a.internal?.findResolvedTarget}),buildPayloads:t=>zt({ref:e.sessionRef,sessionStore:e.sessionStore,result:t,text:n.text,flags:a.flags,staleRefsWarning:i})})}async function Ft(e){try{let t=await It(e);return`response`in t?{response:E(t.response)}:t}catch(e){throw T(e)}}async function It(e){let{req:t}=e,n=Lt(e);if(`response`in n)return n;let{session:r,parsedTarget:i}=n,a=await Nt(e,r,`fill`,i.target.kind!==`point`);if(!a.ok)return{response:a.response};Fe({flags:t.flags,replayPlanStep:t.internal?.replayPlanStep===!0,isSessionRecording:g(r)});let o=O(`fill`,t.flags);if(o)return{response:o};let s=await Rt(e,r,i.target,i.refGeneration);return s.response?{response:s.response}:{admitted:{session:r,parsedTarget:i,touchExecutor:a.touchExecutor,staleRefsWarning:s.staleRefsWarning}}}function Lt(e){let t=e.sessionStore.get(e.sessionName);if(!t)return{response:i()};let n=I(t,`fill`);if(n)return{response:n};let r=Xe(e.req.positionals??[]);return r.ok?{session:t,parsedTarget:r}:{response:r.response}}async function Rt(e,t,n,r){if(n.kind!==`ref`)return{};let i=e.req.internal?.findResolvedTarget===void 0?b({session:t,ref:n.ref,mintedGeneration:r}):void 0,a=e.refSnapshotFlagGuardResponse(`fill`,e.req.flags);if(a)return{response:a,staleRefsWarning:i};let o=e.req.internal?.findResolvedTarget?null:k({ref:n.ref,mintedGeneration:r,staleRefsWarning:i,frame:y({session:t,ref:n.ref,mintedGeneration:r})});return o?{response:o,staleRefsWarning:i}:(await F(e,t),{staleRefsWarning:i})}function zt(e){let{result:t,ref:n,sessionStore:r}=e,i=r.requireCurrent(n),a=q(e.flags?.maestro?.allowNonHittableCoordinateFallback===!0,t.backendResult),o=t.kind===`point`?void 0:w(i.snapshot?.nodes??[]);return W({source:{kind:`runtime`,result:t,publicData:K({command:`fill`,flags:e.flags,data:t.backendResult}),...a.used?{dispatchPath:`maestro-non-hittable-fallback`}:{}},referenceFrame:o,extra:{text:e.text,...a.extra},staleRefsWarning:e.staleRefsWarning,settleRefsGeneration:S(n,r,t.settle)})}async function Bt(e,n,r,i){let a=e,o={selector:r.raw},s=Date.now();x(n);try{let e=await i(r)??{},t=Date.now(),n=Ht(e),c=K({command:dt(a.req.command,`press`),flags:a.req.flags,data:e}),l=q(r.allowNonHittableCoordinateFallback===!0,e),{result:u,responseData:d}=W({source:{kind:`runner-payload`,targetKind:`selector`,data:e,publicData:c,point:n,dispatchPath:l.used?`maestro-non-hittable-fallback`:`maestro-direct-selector`},referenceFrame:Ut(e),extra:{...o,...l.extra}});return A({ref:a.sessionRef,sessionStore:a.sessionStore,command:a.req.command,positionals:a.req.positionals??[],flags:a.req.flags,result:u,responseData:d,actionStartedAt:s,actionFinishedAt:t})}catch(e){return await Vt({error:e,handlerParams:a,extra:o,positionals:[],actionStartedAt:s})||(Ee(e,{delegateSemanticFailures:r.allowNonHittableCoordinateFallback!==!0})?(c({level:`debug`,phase:`ios_direct_selector_tap_fallback`,data:{selector:r.raw,error:e instanceof Error?e.message:String(e)}}),null):{ok:!1,error:t(e)})}}async function Vt(e){let{error:t,handlerParams:n,extra:r,positionals:i,actionStartedAt:a}=e,o=await J({error:t,command:n.req.command,requestId:n.req.meta?.requestId,flags:n.req.flags,ref:n.sessionRef,sessionStore:n.sessionStore,contextFromFlags:n.contextFromFlags,captureSnapshotForSession:n.captureSnapshotForSession});if(!o)return;let{result:s,responseData:c}=at({targetKind:`selector`,warning:o.warning,resolution:{source:`direct-ios`,kind:`not-observed`},extra:r});return A({ref:n.sessionRef,sessionStore:n.sessionStore,command:n.req.command,positionals:n.req.positionals??i,flags:n.req.flags,result:s,responseData:c,actionStartedAt:a,actionFinishedAt:Date.now()})}function Ht(e){let t=typeof e.x==`number`?e.x:void 0,n=typeof e.y==`number`?e.y:void 0;return t!==void 0&&n!==void 0?{x:t,y:n}:{x:0,y:0}}function Ut(e){return typeof e.referenceWidth==`number`&&typeof e.referenceHeight==`number`?{referenceWidth:e.referenceWidth,referenceHeight:e.referenceHeight}:void 0}function Wt(e){let{session:t,commandLabel:n,target:r,flags:i}=e;return!e.tapElementSelectorAvailable||i?.maestro?.allowNonHittableCoordinateFallback!==!0||n!==`click`||r.kind!==`selector`||g(t)||qt(i)||f(n)&&i?.verify===!0||p(n)&&i?.settle===!0?null:Gt(t,r.selector,i)}function Gt(e,t,n){let r=Te({session:e,selectorExpression:t});return r?{...r,...n?.maestro?.allowNonHittableCoordinateFallback?{allowNonHittableCoordinateFallback:!0}:{},...n?.maestro?.expectedTapPoint?{expectedPoint:n.maestro.expectedTapPoint}:{}}:null}const Kt=[`count`,`intervalMs`,`holdMs`,`jitterPx`,`doubleTap`];function qt(e){return Kt.some(t=>e?.[t]!==void 0)?!0:e?.clickButton!==void 0&&e.clickButton!==`primary`}const Jt=new Set([`press`,`click`]);async function Yt(e,t){let n=await Xt(e,t);return`response`in n?{response:E(n.response)}:n}async function Xt(e,t){let{req:n,sessionStore:r,sessionName:a}=e,o=r.get(a);if(!o)return{response:i()};let s=t===`click`?`click`:t,c=Zt(o,t,s,n.flags);if(c)return{response:c};let l=n.positionals??[],u=t===`longpress`?Ye(l):V(l,s);if(!u.ok)return{response:u.response};let d=$t(o,n,u),f=tn(e,o,t,u,d);if(f.response)return{response:f.response};let p=v(n.flags);return{admitted:{session:o,commandLabel:s,clickButton:p,resultButtonTag:fe(p),target:u.target,durationMs:t===`longpress`?u.durationMs:void 0,staleRefsWarning:d,refContext:en(n,u,d)}}}function Zt(e,t,n,r){return I(e,n)||O(t,r)||Qt(e,t,n,r)}function Qt(e,t,n,r){let i=v(r);if(!Jt.has(t)||i===`primary`)return;let a=pe({commandLabel:n,platform:l(e.device),button:i,count:r?.count,intervalMs:r?.intervalMs,holdMs:r?.holdMs,jitterPx:r?.jitterPx,doubleTap:r?.doubleTap});if(a)return o(a.code,a.message,a.details)}function $t(e,t,n){if(n.target.kind===`ref`&&t.internal?.findResolvedTarget===void 0)return b({session:e,ref:n.target.ref,mintedGeneration:n.refGeneration})}function en(e,t,n){if(t.target.kind===`ref`&&e.internal?.findResolvedTarget===void 0)return{ref:t.target.ref,mintedGeneration:t.refGeneration,staleRefsWarning:n}}function tn(e,t,n,r,i){let{req:a}=e;if(r.target.kind!==`ref`)return{};let o=e.refSnapshotFlagGuardResponse(n===`click`?`press`:n,a.flags);if(o)return{response:o};let s=a.internal?.findResolvedTarget?null:k({ref:r.target.ref,mintedGeneration:r.refGeneration,staleRefsWarning:i,frame:y({session:t,ref:r.target.ref,mintedGeneration:r.refGeneration})});return s?{response:s}:{}}async function Q(e,t){e=M(e);let n=await Yt(e,t);if(`response`in n)return n.response;let{admitted:r}=n,i=await Nt(e,r.session,t,r.target.kind!==`point`);if(!i.ok)return i.response;let{touchExecutor:a}=i,o=r.target.kind===`ref`?await F(e,r.session):void 0,s={...r,androidFreshnessBaseline:o},c=e.req.internal?.replayTargetGuard?null:Wt({session:s.session,commandLabel:s.commandLabel,target:s.target,flags:e.req.flags,tapElementSelectorAvailable:a.tapElementSelector!==void 0});if(c&&a.tapElementSelector){let t=await Bt(e,s.session,c,a.tapElementSelector);if(t)return t}return await X(e,{...nn(e,t,s),touchExecutor:a})}function nn(e,t,n){let{req:r,sessionName:i}=e,{session:a,target:o,durationMs:s,staleRefsWarning:c,resultButtonTag:l}=n,u=t===`longpress`?{...s===void 0?{}:{durationMs:s},gesture:`longpress`}:t===`hover`?{gesture:`hover`}:l;return{androidFreshnessBaseline:n.androidFreshnessBaseline,refContext:n.refContext,iosTapCorroboration:{target:o,extra:u},run:async e=>await rn({runtime:e,command:t,target:o,sessionName:i,requestId:r.meta?.requestId,clickButton:n.clickButton,flags:r.flags,durationMs:s,expectedResolvedTarget:r.internal?.replayTargetGuard,preresolvedTarget:r.internal?.findResolvedTarget}),afterRun:async t=>{if(!a.lease?.leaseProvider)return await ft(a,$e(o,t),e.androidObservation)},buildPayloads:async n=>{let i=on(n);return await ut({params:e,result:n,staleRefsWarning:c,publicData:K({command:t===`longpress`||t===`hover`?void 0:t,flags:r.flags,data:n.backendResult}),extra:t===`longpress`?{...i===void 0?{}:{durationMs:i},gesture:`longpress`}:t===`hover`?{gesture:`hover`}:l})}}}async function rn(e){let{runtime:t,command:n,target:r,sessionName:i,requestId:a,flags:o,expectedResolvedTarget:s}=e,c={session:i,requestId:a,settle:j(o),expectedResolvedTarget:s};switch(n){case`longpress`:return await t.interactions.longPress(r,{...c,durationMs:e.durationMs,readinessTimeoutMs:o?.readinessTimeoutMs});case`hover`:return await t.interactions.hover(r,c);case`click`:return await t.interactions.click(r,an(e,c));case`press`:return await t.interactions.press(r,an(e,c))}}function an(e,t){let{flags:n}=e;return{...t,button:e.clickButton,count:n?.count,intervalMs:n?.intervalMs,holdMs:n?.holdMs,jitterPx:n?.jitterPx,doubleTap:n?.doubleTap,verify:n?.verify,readinessTimeoutMs:n?.readinessTimeoutMs,preresolvedTarget:e.preresolvedTarget}}function on(e){return`durationMs`in e?e.durationMs:void 0}function sn(e,t={}){let n=typeof t.executionProfile==`string`?t.executionProfile:void 0;return{kind:e.kind,durationMs:e.durationMs,pointerCount:e.pointerCount,from:e.from,to:e.to,...e.kind===`drag`?{targets:e.targets}:{},...e.backendResult??{},...t,...n?{timing:{executionProfile:n,gestureDurationMs:e.durationMs}}:{},message:e.message}}function cn(e){return`refused`in e}async function ln(e){return e=M(e),await hn(e,`gesture`,async(t,n)=>un(e,t,n))}async function un(e,t,n){let r=re(e.req.input),i=_n(r,t,n);i.intent===`pan`&&e.req.internal?.gestureExecutionProfile&&(i.executionProfile=e.req.internal.gestureExecutionProfile);let a=await N({device:t.device,input:i,inspectFacts:e.inspectFacts,bindDevice:e.bindDevice});return a.ok?fn(r,i,await dn(mn(e,a.gestures),{session:e.sessionName,requestId:e.req.meta?.requestId},i,e.req.internal),e.req.flags):{refused:a.response}}async function dn(e,t,n,r){if(n.intent!==`drag`)return await e.interactions.gesture({...t,gesture:n});let i=r?.replayTargetGuards??(r?.replayTargetGuard?{source:r.replayTargetGuard}:void 0);return await e.interactions.gesture({...t,gesture:n,...i?{expectedResolvedTargets:i}:{}})}function fn(e,t,n,r){let i=n.kind===`drag`?n.recording:void 0,a=i?.sourceTarget,o=i?.destinationTarget;return{positionals:yn(e,i),flags:Tn(e,r),responseData:sn(n,{executionProfile:gn(t)}),...e.kind===`pinch`?{recordingResultExtra:{scale:e.scale}}:a?{recordingResultExtra:{selectorChain:a.selectorChain}}:{},...a&&o?{recordedTargets:{source:{node:a.node,preActionNodes:a.preActionNodes},destination:{node:o.node,preActionNodes:o.preActionNodes}}}:{}}}async function pn(e){return e=M(e),await hn(e,`swipe`,async t=>{let n=bn(e.req.input),r=await N({device:t.device,input:m(n).gesture,inspectFacts:e.inspectFacts,bindDevice:e.bindDevice});if(!r.ok)return{refused:r.response};let i=n.count??1,a=n.pauseMs??0,o=n.pattern??`one-way`,s=await Cn(mn(e,r.gestures),e,n,i,a,o);return{positionals:Sn(n),flags:e.req.flags,responseData:sn(s,{from:n.from,to:n.to,x1:n.from.x,y1:n.from.y,x2:n.to.x,y2:n.to.y,effectiveDurationMs:s.durationMs,timingMode:`direct`,executionProfile:`endpoint-hold`,count:i,pauseMs:a,pattern:o})}})}function mn(e,t){return Ce({...e,gestures:t,pairedGestureViewport:e.req.internal?.gestureViewport})}async function hn(e,n,r){let a=e.sessionStore.get(e.sessionName);if(!a)return i();let o=Date.now();try{let t=h(a.device),i=t?{status:`clear`}:await D({session:a,command:n,phase:`before-command`,observation:e.androidObservation}),s=await r(a,i);if(cn(s))return s.refused;t||await D({session:a,command:n,phase:`after-command`,observation:e.androidObservation});let c={...s.responseData};return i.status===`recovered`&&(c.warning=`${typeof c.warning==`string`?`${c.warning} `:``}${i.warning}`),A({ref:e.sessionRef,sessionStore:e.sessionStore,command:n,actionCommand:n,positionals:s.positionals,flags:s.flags,result:{...c,...s.recordingResultExtra??{}},responseData:c,recordedTargets:s.recordedTargets,actionStartedAt:o,actionFinishedAt:Date.now()})}catch(e){return{ok:!1,error:t(e)}}}function gn(e){if(e.intent===`fling`)return`endpoint-hold`;if(e.intent===`pan`)return e.executionProfile??`timed-pan`;if(e.intent===`drag`)return`timed-pan`}function _n(t,n,r){let i=ie(t);if(i.intent!==`drag`)return i;try{return{...i,source:vn(i.source,n),destination:vn(i.destination,n)}}catch(t){if(r.status===`recovered`){let n=e(t),i=typeof n.details?.warning==`string`?n.details.warning+` `:``;throw n.details={...n.details,warning:i+r.warning},n}throw T(t)}}function vn(e,t){if(!e.startsWith(`@`))return e;let i=n(e);if(!i)throw new r(`INVALID_ARGS`,`Invalid ref "${e}" — malformed generation suffix.`,{hint:a});return De({ref:i.base,mintedGeneration:i.generation,frame:y({session:t,ref:i.base,mintedGeneration:i.generation})}),i.base}function yn(e,t){return e.kind!==`drag`||!t?oe(e):oe({...e,source:t.sourceSelector??e.source,destination:t.destinationSelector??e.destination})}function bn(e){if(!e||typeof e!=`object`||Array.isArray(e))throw new r(`INVALID_ARGS`,`swipe requires structured object input`);ae(e);let t=e,n=t.pattern;if(n!==void 0&&n!==`one-way`&&n!==`ping-pong`)throw new r(`INVALID_ARGS`,`swipe pattern must be one-way or ping-pong`);let i={from:$(t.from,`swipe from`),to:$(t.to,`swipe to`),count:s(t,`count`,{min:1,max:200}),pauseMs:s(t,`pauseMs`,{min:0,max:ne}),pattern:n};return xn(i),i}function xn(e){let t=e.count??1,n=e.pauseMs??0,i=t*100+Math.max(0,t-1)*n;if(!(i<=6e4))throw new r(`INVALID_ARGS`,`Swipe series must fit within ${te}ms.`,{count:t,pauseMs:n,gestureDurationMs:100,scheduledDurationMs:i,hint:`Reduce --count or --pause-ms.`})}function $(e,t){if(!e||typeof e!=`object`||Array.isArray(e))throw new r(`INVALID_ARGS`,`${t} must be a point`);let n=e;if(typeof n.x!=`number`||!Number.isFinite(n.x))throw new r(`INVALID_ARGS`,`${t} x must be finite`);if(typeof n.y!=`number`||!Number.isFinite(n.y))throw new r(`INVALID_ARGS`,`${t} y must be finite`);return{x:n.x,y:n.y}}function Sn(e){return[String(e.from.x),String(e.from.y),String(e.to.x),String(e.to.y)]}async function Cn(e,t,n,r,i,a){let o;for(let s=0;s<r;s+=1){let c=m(wn(n,a,s));o=await e.interactions.gesture({session:t.sessionName,requestId:t.req.meta?.requestId,gesture:c.gesture}),i>0&&s+1<r&&await ge(i)}if(!o)throw Error(`Swipe orchestration did not execute a gesture.`);return o}function wn(e,t,n){return t!==`ping-pong`||n%2!=1?e:{...e,from:e.to,to:e.from}}function Tn(e,t){return e.kind!==`pan`||e.pointerCount===void 0?t:{...t,pointerCount:e.pointerCount}}async function En(e){let t={},n=e.sessionRef,r=await Dn({...e,sessionRef:n,refSnapshotFlagGuardResponse:Ae,captureProof:t});return r&&se({response:r,consumedTree:t,captureProof:t})}async function Dn(e){switch(e.req.command){case`press`:return await Q(e,`press`);case`click`:return await Q(e,`click`);case`longpress`:return await Q(e,`longpress`);case`hover`:return await Q(e,`hover`);case`fill`:return await Pt(e);default:return await On(e)}}async function On(e){switch(e.req.command){case _.gesture:return await ln(e);case _.swipe:return await pn(e);case _.type:return await kn(e);case`get`:return await Me(e);case`is`:return await je(e);default:return null}}async function kn(e){let{sessionName:t,sessionStore:n}=e,r=n.get(t);if(!r)return i();let a=await Pe({device:r.device,inspectFacts:e.inspectFacts,bindDevice:e.bindDevice});if(!a.ok)return a.response;let o=await An(r,e.androidObservation);return o.response?o.response:await jn(e,r,a.typeText,o.warning)}async function An(e,t){if(e.device.platform===`android`&&e.screenRecording){let n=await Se({session:e,observation:t});if(n.status===`failed`)return{response:o(`COMMAND_FAILED`,`Android system dialog blocked the recording session`)};if(n.status===`unknown`)return{warning:n.warning}}return{}}async function jn(e,n,r,i){let{req:a,sessionStore:o}=e,s=Date.now();try{let t=await D({session:n,command:a.command,phase:`before-command`,observation:e.androidObservation});x(n);let c=await r(a.positionals??[],e.contextFromFlags(a.flags,n.appBundleId,n.trace?.outPath));await D({session:n,command:a.command,phase:`after-command`,observation:e.androidObservation});let l=Date.now(),u={...c};return Mn(u,i,t),A({ref:e.sessionRef,sessionStore:o,command:a.command,positionals:a.positionals??[],flags:a.flags,result:u,responseData:u,actionStartedAt:s,actionFinishedAt:l})}catch(e){return{ok:!1,error:t(e)}}}function Mn(e,t,n){let r=[typeof e.warning==`string`?e.warning:void 0,t];n.status===`recovered`&&r.push(n.warning);let i=r.filter(e=>typeof e==`string`&&e.length>0).join(` `);i.length>0&&(e.warning=i)}export{En as handleInteractionCommands};
|