agent-device 0.20.10 → 0.21.0
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 +2 -2
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.10.apk → agent-device-android-ime-helper-0.21.0.apk} +0 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.0.apk.sha256 +1 -0
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.10.manifest.json → agent-device-android-ime-helper-0.21.0.manifest.json} +4 -4
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.0.apk +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.0.apk.sha256 +1 -0
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.10.manifest.json → agent-device-android-snapshot-helper-0.21.0.manifest.json} +6 -6
- package/apple/macos-helper/Sources/AgentDeviceMacOSHelper/AudioProbe.swift +35 -33
- package/apple/macos-helper/Sources/AgentDeviceMacOSHelper/main.swift +6 -1
- package/apple/snapshot-bridge/LICENSE.idb +23 -0
- package/apple/snapshot-bridge/README.md +49 -0
- package/apple/snapshot-bridge/SnapshotBridge.m +280 -0
- package/apple/snapshot-bridge/SnapshotBridgeRuntime.h +33 -0
- package/apple/snapshot-bridge/SnapshotBridgeRuntime.m +382 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +58 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.pbxproj +19 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAlertVerification.swift +36 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerStringNormalization.swift +8 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.h +12 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.m +100 -6
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTapPointPolicy.swift +2 -2
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +16 -8
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +21 -88
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AlertObservation.swift +124 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +106 -103
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +6 -14
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +63 -91
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +13 -6
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +72 -155
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+PrivateAXElementTypes.swift +12 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+PrivateAXPresentation.swift +74 -78
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScreenRecorder.swift +17 -9
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +42 -11
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +185 -461
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotBackendCapabilities.swift +98 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +224 -164
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotPresentationInvariant.swift +19 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotTiming.swift +110 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedCommitDeadline.swift +206 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedTextEntry.swift +147 -25
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SystemModal.swift +1 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +24 -307
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryFocus.swift +206 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryReadiness.swift +158 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextTyping.swift +49 -16
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Transport.swift +2 -11
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TvRemote.swift +4 -19
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +16 -20
- package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/RecordingExportSupport.swift +111 -0
- package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/recording-overlay.swift +42 -81
- package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/recording-trim.swift +35 -82
- package/dist/apple/snapshot-presentation/Package.swift +21 -0
- package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotGeometry.swift +56 -0
- package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotModels.swift +259 -0
- package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentation.swift +153 -0
- package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentationFailure.swift +27 -0
- package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentationInvariant.swift +91 -0
- package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentationProjection.swift +161 -0
- package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotScopePolicy.swift +53 -0
- package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotVisibilityFold.swift +242 -0
- package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotVisibilityFoldProjection.swift +97 -0
- package/dist/src/adapter.js +1 -0
- package/dist/src/adb-executor.js +2 -0
- package/dist/src/adb-failure.js +1 -0
- package/dist/src/adb-host.js +1 -0
- package/dist/src/adb.js +1 -0
- package/dist/src/agent-browser-lifecycle.js +1 -0
- package/dist/src/agent-browser-process-record.js +1 -0
- package/dist/src/agent-browser-provider.js +1 -0
- package/dist/src/agent-browser-tool.js +1 -1
- package/dist/src/agent-device-client.js +2 -2
- package/dist/src/ai-sdk.d.ts +2 -2
- package/dist/src/ai-sdk.js +1 -1
- package/dist/src/alert-contract.js +1 -0
- package/dist/src/alert-runtime.js +1 -0
- package/dist/src/android-adb.d.ts +27 -19
- package/dist/src/android-adb.js +1 -1
- package/dist/src/android-input-ownership.js +1 -0
- package/dist/src/android-system-chrome.js +1 -0
- package/dist/src/android.js +1 -1
- package/dist/src/api.js +11 -0
- package/dist/src/app-catalog.js +1 -0
- package/dist/src/app-deployment-resolution.js +2 -0
- package/dist/src/app-helpers.js +1 -1
- package/dist/src/app-inventory-contract.js +1 -0
- package/dist/src/app-inventory.js +1 -0
- package/dist/src/app-launch.js +2 -0
- package/dist/src/app-lifecycle-facade.js +1 -0
- package/dist/src/app-lifecycle.js +3 -6
- package/dist/src/app-lifecycle2.js +2 -2
- package/dist/src/app-lifecycle3.js +1 -0
- package/dist/src/app-log-files.js +1 -1
- package/dist/src/app-log-reconnect.js +1 -1
- package/dist/src/app-log-runtime.js +1 -4
- package/dist/src/app-log-runtime2.js +4 -0
- package/dist/src/app-parsers.js +4 -0
- package/dist/src/app-resolution-cache.js +1 -0
- package/dist/src/app-resolution-facade.js +1 -0
- package/dist/src/app-resolution.js +2 -2
- package/dist/src/app-state.js +1 -2
- package/dist/src/application-lifecycle-interaction.js +1 -0
- package/dist/src/application-lifecycle-runtime.js +1 -0
- package/dist/src/apps-simctl.js +1 -0
- package/dist/src/archive.js +4 -0
- package/dist/src/artifact-download.js +1 -0
- package/dist/src/artifacts.d.ts +6 -2
- package/dist/src/artifacts.js +1 -1
- package/dist/src/async-lifecycle.js +1 -0
- package/dist/src/audio-probe-result.js +1 -0
- package/dist/src/audio-probe-runtime.js +1 -0
- package/dist/src/audio-probe-support.js +1 -0
- package/dist/src/auth-session.js +1 -1
- package/dist/src/auth.js +1 -1
- package/dist/src/back-mode.js +1 -0
- package/dist/src/{url.js → base-url.js} +1 -1
- package/dist/src/boot-diagnostics.js +2 -2
- package/dist/src/byte-limit-stream.js +1 -1
- package/dist/src/capabilities.js +1 -0
- package/dist/src/capture.js +1 -0
- package/dist/src/catalog.js +1 -0
- package/dist/src/cli-command-aliases.js +1 -0
- package/dist/src/cli-config.js +1 -1
- package/dist/src/cli-help.js +69 -50
- package/dist/src/cli-output.js +1 -1
- package/dist/src/cli-runner.js +1 -1
- package/dist/src/cli.js +4 -6
- package/dist/src/click-button.js +1 -0
- package/dist/src/client-metro-companion.js +1 -0
- package/dist/src/client-metro.js +1 -1
- package/dist/src/client-types.d.ts +255 -231
- package/dist/src/clipboard.js +1 -0
- package/dist/src/code-signature-cache.js +1 -0
- package/dist/src/code-signature.js +1 -0
- package/dist/src/color.js +1 -0
- package/dist/src/command-metadata.js +1 -1
- package/dist/src/command-schema.js +3 -3
- package/dist/src/command-surface.js +1 -1
- package/dist/src/command-tools.js +2 -2
- package/dist/src/command.js +1 -0
- package/dist/src/compatibility-policy.js +1 -0
- package/dist/src/config.js +1 -1
- package/dist/src/config2.js +1 -0
- package/dist/src/connection-runtime.js +1 -1
- package/dist/src/connection.js +5 -5
- package/dist/src/contracts.d.ts +1 -1
- package/dist/src/contracts.js +1 -1
- package/dist/src/daemon-client-lifecycle.js +1 -0
- package/dist/src/daemon-process.js +1 -0
- package/dist/src/daemon-registration.js +1 -0
- package/dist/src/daemon-shutdown-report.js +1 -1
- package/dist/src/daemon.js +2 -2
- package/dist/src/debug-symbols-facade.js +5 -0
- package/dist/src/deploy-result-target.js +1 -0
- package/dist/src/device-claim-inspection.js +1 -1
- package/dist/src/device-claim-rule.js +1 -0
- package/dist/src/device-input-state.d.ts +190 -3
- package/dist/src/device-inventory-context.js +1 -0
- package/dist/src/device-isolation.js +1 -0
- package/dist/src/device-release.js +1 -0
- package/dist/src/device-rotation.js +1 -0
- package/dist/src/device-selection-resolver.js +1 -0
- package/dist/src/device-session.js +1 -0
- package/dist/src/device.js +1 -1
- package/dist/src/device2.js +3 -2
- package/dist/src/diagnostics.js +3 -0
- package/dist/src/diagnostics2.js +1 -0
- package/dist/src/dispatch-resolve.js +1 -0
- package/dist/src/doctor-facade.js +1 -0
- package/dist/src/doctor-output.js +1 -0
- package/dist/src/doctor.js +1 -0
- package/dist/src/doctor2.js +1 -0
- package/dist/src/doctor3.js +1 -0
- package/dist/src/durable-resource.js +1 -0
- package/dist/src/entities.js +1 -1
- package/dist/src/error.js +2 -0
- package/dist/src/exec.js +1 -0
- package/dist/src/file.js +1 -0
- package/dist/src/find.js +1 -1
- package/dist/src/finders.js +1 -1
- package/dist/src/format.js +2 -0
- package/dist/src/generic-settle.js +1 -1
- package/dist/src/generic.js +1 -1
- package/dist/src/gesture-admission.js +1 -0
- package/dist/src/gesture-plan-types.js +1 -0
- package/dist/src/gesture-plan.js +1 -0
- package/dist/src/gesture-runtime.js +1 -0
- package/dist/src/harmonyos.js +1 -1
- package/dist/src/hdc.js +1 -1
- package/dist/src/helper.js +2 -2
- package/dist/src/host-file.js +1 -0
- package/dist/src/human-control-contract.js +1 -0
- package/dist/src/human-control.js +1 -0
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/input-actions.js +1 -4
- package/dist/src/input-actions2.js +2 -1
- package/dist/src/install-artifact-facade.js +1 -0
- package/dist/src/install-source-network-transport.js +1 -0
- package/dist/src/install-source.d.ts +3 -10
- package/dist/src/install-source2.js +1 -1
- package/dist/src/interaction-positionals.js +1 -0
- package/dist/src/interaction-ref-policy.js +1 -0
- package/dist/src/interaction.js +1 -1
- package/dist/src/interaction2.js +1 -1
- package/dist/src/interactor-operation-catalog.js +1 -0
- package/dist/src/interactor-types.js +1 -0
- package/dist/src/interactor.js +6 -2
- package/dist/src/interactor2.js +1 -1
- package/dist/src/interactors.js +1 -1
- package/dist/src/internal/bin.d.ts +1 -1
- package/dist/src/internal/bin.js +1 -2
- package/dist/src/internal/companion-tunnel.d.ts +1 -1
- package/dist/src/internal/companion-tunnel.js +1 -1
- package/dist/src/internal/daemon.d.ts +1 -1
- package/dist/src/internal/daemon.js +2 -4
- package/dist/src/internal/png-worker.d.ts +4 -4
- package/dist/src/internal/png-worker.js +1 -1
- package/dist/src/internal/run-script-http-child.d.ts +4 -0
- package/dist/src/internal/run-script-http-child.js +1 -0
- package/dist/src/internal/update-check-entry.d.ts +1 -1
- package/dist/src/inventory.js +4 -4
- package/dist/src/inventory2.js +1 -1
- package/dist/src/inventory3.js +1 -1
- package/dist/src/inventory5.js +1 -1
- package/dist/src/inventory6.js +1 -1
- package/dist/src/ios-client.js +16 -0
- package/dist/src/ios-snapshot-acquisition.js +1 -0
- package/dist/src/ios-snapshot-adapter.js +1 -0
- package/dist/src/ios-snapshot-planning.js +1 -0
- package/dist/src/ios-snapshot-runtime.js +1 -0
- package/dist/src/json.js +1 -0
- package/dist/src/keyboard-actions.js +1 -0
- package/dist/src/launch-console.js +1 -0
- package/dist/src/lease-context.js +1 -1
- package/dist/src/lease-scope.js +1 -0
- package/dist/src/lease.js +1 -1
- package/dist/src/limrun-runtime-dependencies.js +1 -1
- package/dist/src/limrun.d.ts +1610 -7
- package/dist/src/limrun.js +1 -1
- package/dist/src/linux.js +1 -1
- package/dist/src/local-interactor-operation-set.js +1 -0
- package/dist/src/location-coordinates.js +1 -1
- package/dist/src/logcat.js +1 -1
- package/dist/src/macos-facade.js +1 -0
- package/dist/src/managed-device-scope.js +1 -0
- package/dist/src/mechanics.js +19 -0
- package/dist/src/metro.d.ts +4 -2
- package/dist/src/metro.js +1 -1
- package/dist/src/metro2.js +1 -1
- package/dist/src/mobile-snapshot-semantics.js +1 -1
- package/dist/src/multitouch-support.js +1 -0
- package/dist/src/numeric.js +1 -0
- package/dist/src/observability.js +1 -1
- package/dist/src/observation.js +2 -0
- package/dist/src/output-path.js +1 -1
- package/dist/src/owner-identity.js +3 -1
- package/dist/src/parameterized-recorded-fill.js +1 -0
- package/dist/src/parser.js +1 -1
- package/dist/src/perf-facade.js +2 -0
- package/dist/src/perf-runtime-operation-builder.js +1 -0
- package/dist/src/perf-runtime-plan.js +1 -0
- package/dist/src/perf-runtime.js +1 -0
- package/dist/src/perf.js +1 -4
- package/dist/src/physical-device-control.js +1 -1
- package/dist/src/physical-device-facade.js +1 -0
- package/dist/src/platform-request-scope.js +1 -0
- package/dist/src/platform-runtime-android-adb-host.js +1 -0
- package/dist/src/platform-runtime-android-mechanics.js +1 -0
- package/dist/src/platform-runtime-app-log-android-transport.js +1 -1
- package/dist/src/platform-runtime-app-log-process.js +1 -1
- package/dist/src/platform-runtime-apple-resources.js +1 -0
- package/dist/src/platform-runtime-host.js +1 -1
- package/dist/src/platform-runtime-managed-owner.js +1 -0
- package/dist/src/platform-runtime-network-web-transport.js +1 -1
- package/dist/src/platform-runtime-open-target.js +1 -1
- package/dist/src/platform-runtime-operation-host.js +4 -4
- package/dist/src/platform-runtime-runtime-hints.js +2 -2
- package/dist/src/platform-runtime-screen-recording-android-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-apple-runner-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-apple-runner-transport.js +1 -1
- package/dist/src/platform-runtime-screen-recording-apple-simulator-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-apple-transport.js +1 -1
- package/dist/src/platform-runtime-screen-recording-finalizer-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-harmony-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-process-host.js +1 -0
- package/dist/src/platform-runtime-screen-recording-web-host.js +1 -1
- package/dist/src/platform-runtime-unavailable.js +1 -0
- package/dist/src/platform-runtime.js +1 -1
- package/dist/src/platform-runtime2.js +1 -1
- package/dist/src/plist.js +1 -1
- package/dist/src/png-worker-contract.js +1 -1
- package/dist/src/prepare-kind.js +1 -0
- package/dist/src/process-exit.js +1 -1
- package/dist/src/process.js +1 -0
- package/dist/src/provider-device-runtime.js +1 -0
- package/dist/src/provider-session-ownership.js +2 -0
- package/dist/src/provider-webdriver.js +1 -1
- package/dist/src/provider.js +1 -1
- package/dist/src/providers.js +1 -0
- package/dist/src/proxy.js +2 -2
- package/dist/src/react-native-overlay.js +1 -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/rect-center.js +1 -0
- package/dist/src/register-builtins.js +1 -0
- package/dist/src/registry.js +39 -28
- package/dist/src/remote-config2.js +1 -1
- package/dist/src/replay-divergence.js +2 -0
- package/dist/src/replay.js +2 -2
- package/dist/src/reporting.js +8 -8
- package/dist/src/request-admission.js +1 -0
- package/dist/src/request-cancel.js +1 -0
- package/dist/src/request-cancellation.js +1 -0
- package/dist/src/request-progress-protocol.js +1 -0
- package/dist/src/request-providers.js +1 -0
- package/dist/src/request-runtime-binding.js +1 -0
- package/dist/src/request.js +1 -0
- package/dist/src/result-serialization.js +1 -0
- package/dist/src/retry.js +1 -0
- package/dist/src/rolldown-runtime.js +1 -1
- package/dist/src/runner-cache-metadata.js +2 -0
- package/dist/src/runner-client.js +1 -1
- package/dist/src/runner-disposal.js +1 -1
- package/dist/src/runner-operations-facade.js +1 -0
- package/dist/src/runner-owner-facade.js +1 -0
- package/dist/src/runner-owner-state.js +1 -0
- package/dist/src/runner-presentation.js +1 -0
- package/dist/src/runner-selector-query.js +1 -0
- package/dist/src/runner.js +1 -0
- package/dist/src/{runtime-transport.js → runtime-transport-hints.js} +1 -1
- package/dist/src/runtime.js +3 -3
- package/dist/src/runtime2.js +4 -4
- package/dist/src/runtime3.js +1 -1
- package/dist/src/runtime4.js +4 -3
- package/dist/src/runtime5.js +1 -1
- package/dist/src/runtime6.js +1 -1
- package/dist/src/runtime7.js +1 -1
- package/dist/src/runtime8.js +1 -1
- package/dist/src/runtime9.js +1 -1
- package/dist/src/scoped-provider.js +1 -1
- package/dist/src/screen-recording-completion.js +1 -0
- package/dist/src/screen-recording-live-handle.js +1 -0
- package/dist/src/screen-recording-options.js +1 -0
- package/dist/src/screen-recording-resource-recovery.js +1 -0
- package/dist/src/screen-recording-runtime.js +1 -0
- package/dist/src/screenshot-density.js +1 -1
- package/dist/src/screenshot-result.js +1 -6
- package/dist/src/screenshot-runtime.js +1 -0
- package/dist/src/screenshot.js +1 -1
- package/dist/src/screenshot2.js +1 -0
- package/dist/src/screenshot3.js +5 -0
- package/dist/src/script.js +1 -0
- package/dist/src/scroll-command.js +1 -0
- package/dist/src/scroll-gesture.js +1 -0
- package/dist/src/scroll-indicator.js +1 -0
- package/dist/src/sdk-batch-runner.d.ts +23 -6
- package/dist/src/sdk-batch-runner.js +2 -3
- package/dist/src/sdk-batch.js +2 -0
- package/dist/src/sdk-contracts.d.ts +127 -41
- package/dist/src/sdk-contracts.js +2 -2
- package/dist/src/sdk-device.js +1 -1
- package/dist/src/sdk-finders.js +1 -1
- package/dist/src/sdk-io.js +1 -1
- package/dist/src/sdk-remote-config.d.ts +1 -1
- package/dist/src/sdk-remote-config.js +1 -1
- package/dist/src/sdk-selectors.d.ts +472 -144
- package/dist/src/sdk-selectors.js +1 -1
- package/dist/src/selection.js +1 -0
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/selectors.js +1 -1
- package/dist/src/semantic-index.js +1 -0
- package/dist/src/server.js +4 -4
- package/dist/src/session-allocation.js +1 -0
- package/dist/src/session-artifact-paths.js +1 -0
- package/dist/src/session-paths.js +1 -0
- package/dist/src/session-repair-tombstone.js +1 -0
- package/dist/src/session-routing.js +1 -0
- package/dist/src/session-runtime-admission.js +1 -0
- package/dist/src/session-snapshot.js +1 -0
- package/dist/src/session-store.js +4 -0
- package/dist/src/session-target-evidence.js +1 -1
- package/dist/src/session2.js +5 -27
- package/dist/src/settings.js +1 -0
- package/dist/src/shared.js +2 -2
- package/dist/src/simctl-facade.js +1 -0
- package/dist/src/simctl.js +1 -1
- package/dist/src/simulator-facade.js +1 -0
- package/dist/src/simulator.js +1 -1
- package/dist/src/snapshot-capture-annotations.js +1 -0
- package/dist/src/snapshot-desktop-projection.js +1 -0
- package/dist/src/snapshot-diagnostics.js +1 -0
- package/dist/src/snapshot-process.js +1 -0
- package/dist/src/snapshot-quality-backend-capabilities.js +1 -0
- package/dist/src/snapshot-quality-verdict.js +1 -0
- package/dist/src/snapshot-runtime-binding.js +1 -0
- package/dist/src/snapshot-runtime.js +1 -1
- package/dist/src/snapshot-scope.js +1 -1
- package/dist/src/snapshot-state.js +1 -0
- package/dist/src/snapshot.js +1 -8
- package/dist/src/snapshot2.js +1 -1
- package/dist/src/snapshot3.js +1 -1
- package/dist/src/snapshot4.js +1 -0
- package/dist/src/src.js +1 -1
- package/dist/src/src2.js +1 -1
- package/dist/src/src3.js +1 -2
- package/dist/src/src4.js +1 -1
- package/dist/src/src5.js +1 -0
- package/dist/src/src6.js +1 -0
- package/dist/src/src7.js +2 -0
- package/dist/src/src8.js +115 -0
- package/dist/src/startup-recovery-fence.js +1 -0
- package/dist/src/status-markers.js +1 -0
- package/dist/src/string-enum.js +1 -1
- package/dist/src/success-text.js +1 -0
- package/dist/src/surface-snapshot.js +1 -0
- package/dist/src/surface-snapshot2.js +1 -0
- package/dist/src/takeover.js +5 -0
- package/dist/src/tool-provider-facade.js +1 -0
- package/dist/src/tool-provider.js +4 -3
- package/dist/src/tool-provider2.js +1 -1
- package/dist/src/tool-provider3.js +1 -1
- package/dist/src/toolchain-probe.js +2 -0
- package/dist/src/touch-runtime.js +1 -0
- package/dist/src/transport.js +3 -0
- package/dist/src/tree.js +1 -0
- package/dist/src/ttl-memo.js +1 -0
- package/dist/src/tv-remote.js +1 -0
- package/dist/src/type-text-runtime.js +1 -0
- package/dist/src/undici.js +99 -0
- package/dist/src/update-check.js +1 -1
- package/dist/src/verified-file.js +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/video.js +2 -2
- package/dist/src/web.js +2 -1
- package/dist/src/web2.js +1 -0
- package/dist/src/webdriver-ios-snapshot.js +1 -0
- package/dist/src/webdriver-source.js +1 -0
- package/linux/atspi-dump.py +54 -9
- package/package.json +56 -34
- package/server.json +9 -3
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.10.apk.sha256 +0 -1
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.10.apk +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.10.apk.sha256 +0 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CoordinateTextEntryTests.swift +0 -4
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+FlatSnapshotFiltering.swift +0 -168
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+LifecycleCacheTests.swift +0 -6
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+RecordingTests.swift +0 -4
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SelectorMatchPolicyTests.swift +0 -4
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotPresentation.swift +0 -183
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotPresentationTests.swift +0 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotTraversalIdentityTests.swift +0 -4
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryPolicyTests.swift +0 -4
- package/dist/src/appearance.js +0 -1
- package/dist/src/apps.js +0 -5
- package/dist/src/audio-probe.js +0 -1
- package/dist/src/cli-grammar.js +0 -1
- package/dist/src/command-catalog.js +0 -1
- package/dist/src/debug-symbols.js +0 -5
- package/dist/src/device-input-state.js +0 -2
- package/dist/src/device-ready.js +0 -1
- package/dist/src/dispatch.js +0 -1
- package/dist/src/handler-utils.js +0 -1
- package/dist/src/helper-package-install.js +0 -1
- package/dist/src/host-process.js +0 -3
- package/dist/src/ime-lifecycle.js +0 -2
- package/dist/src/ime-recovery-marker.js +0 -1
- package/dist/src/input-actions3.js +0 -1
- package/dist/src/install-artifact.js +0 -1
- package/dist/src/install-artifact2.js +0 -1
- package/dist/src/interaction-common.js +0 -1
- package/dist/src/interaction-runtime.js +0 -1
- package/dist/src/interaction-snapshot.js +0 -1
- package/dist/src/manifest.js +0 -1
- package/dist/src/method-scope.js +0 -1
- package/dist/src/png-resize.js +0 -1
- package/dist/src/process-lock.js +0 -1
- package/dist/src/runner-lease.js +0 -1
- package/dist/src/runner-sequence.js +0 -1
- package/dist/src/script-source-bundle.js +0 -16
- package/dist/src/sdk-android-adb.d.ts +0 -245
- package/dist/src/sdk-android-adb.js +0 -4
- package/dist/src/sdk.js +0 -1
- package/dist/src/setting-state.js +0 -1
- package/dist/src/shell-quote.js +0 -1
- package/dist/src/snapshot-session.js +0 -1
- package/dist/src/timing-safe-equal.js +0 -1
- package/dist/src/unsupported-interactor.js +0 -1
- package/dist/src/verdict.js +0 -1
- /package/dist/src/{recording-telemetry.js → telemetry.js} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{y as e}from"./sdk-contracts.js";import{runHarmonyHdc as t}from"./hdc.js";async function n(n,r,i,a){if(r!==`clear-app-state`)throw new e(`UNSUPPORTED_OPERATION`,`HarmonyOS setting "${r}" is not supported`,{hint:`HarmonyOS currently supports settings clear-app-state for an app bundle only.`});if(i!==`clear`)throw new e(`INVALID_ARGS`,`settings clear-app-state only supports clear.`);if(!a)throw new e(`INVALID_ARGS`,`settings clear-app-state requires an app id or an active app session.`);return await t(n,[`shell`,`aa`,`force-stop`,a],{timeoutMs:15e3}),await t(n,[`shell`,`bm`,`clean`,`-n`,a,`-d`,`-c`],{timeoutMs:15e3}),{bundleId:a,forceStopped:!0,clearedData:!0,clearedCache:!0}}export{n as setHarmonySetting};
|
package/dist/src/shared.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
`)?e:`${e}\n`)}export{t};
|
|
1
|
+
async function e(e,n,r){if(e.json){let{printJson:e}=await import(`./json.js`);e({success:!0,data:n});return}let i=r?.();i&&t(i)}function t(e){process.stdout.write(e.endsWith(`
|
|
2
|
+
`)?e:`${e}\n`)}export{e as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as e}from"./simctl.js";export{e as buildSimctlArgsForDevice};
|
package/dist/src/simctl.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{l as e}from"./sdk-device.js";import"./command.js";import{r as t}from"./device-isolation.js";import{o as n}from"./tool-provider.js";function r(e,n={}){let r=t(n.simulatorSetPath);return r?[`simctl`,`--set`,r,...e]:[`simctl`,...e]}function i(t,n){return!e(t)||t.kind!==`simulator`?[`simctl`,...n]:r(n,{simulatorSetPath:t.simulatorSetPath})}function a(e,t,r){return n(i(e,t),r)}export{a as n,i as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as e,n as t,t as n}from"./simulator.js";export{n as ensureBootedSimulator,t as markSimulatorBooted,e as wasSimulatorRecentlyObservedBooted};
|
package/dist/src/simulator.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{y as e}from"./sdk-contracts.js";import{i as t,n}from"./exec.js";import"./command.js";import{i as r,n as i}from"./retry.js";import{t as a}from"./ttl-memo.js";import{n as o,t as s}from"./boot-diagnostics.js";import{t as c}from"./scoped-provider.js";import{n as l,o as u}from"./config2.js";import{a as d,o as f}from"./tool-provider.js";import{t as p}from"./simctl.js";const m=[`Simulator`],h=[`Device Hub`,`Simulator`],g=c(void 0);async function _(e,t){return await g.run(e,t)}const v=a({ttlMs:5e3});function y(e){return`${e.id}|${e.simulatorSetPath??``}`}function b(e){return v.get(y(e))===!0}function x(e){v.set(y(e),!0)}function S(t,n){if(t.kind!==`simulator`)throw new e(`UNSUPPORTED_OPERATION`,`${n} is only supported on iOS simulators`)}async function C(e={}){let t=e.deviceHub?h:m,n=e.background?[`-g`,`-a`]:[`-a`];for(let r of t)if((await d(`open`,[...n,r],{allowFailure:!0,signal:e.signal,timeoutMs:1e4})).exitCode===0)return}async function w(a,c={}){if(a.kind!==`simulator`)return;c.signal?.throwIfAborted();let u=g.resolve();if(u){await u(a),c.signal?.throwIfAborted();return}if((b(a)?`Booted`:await T(a,c.signal))===`Booted`){x(a),c.focusExisting&&await C({background:c.deviceHub,deviceHub:c.deviceHub,signal:c.signal});return}c.onColdBootStart?.(a);let d=i.fromTimeoutMs(l),m,h;try{await r(async({deadline:r})=>{if(r?.isExpired())throw new e(`COMMAND_FAILED`,`iOS simulator boot deadline exceeded`,{timeoutMs:l});let i=Math.max(1e3,r?.remainingMs()??18e4);m=await f(p(a,[`boot`,a.id]),{allowFailure:!0,signal:c.signal,timeoutMs:i});let o=`${m.stdout}\n${m.stderr}`.toLowerCase(),s=o.includes(`already booted`)||o.includes(`current state: booted`);if(m.exitCode!==0&&!s)throw new e(`COMMAND_FAILED`,`simctl boot failed`,n(m));h=await f(p(a,[`bootstatus`,a.id,`-b`]),{allowFailure:!0,signal:c.signal,timeoutMs:i}),t(h,`simctl bootstatus failed`);let u=await T(a,c.signal);if(u!==`Booted`)throw new e(`COMMAND_FAILED`,`Simulator is still booting`,{state:u})},{maxAttempts:3,baseDelayMs:500,maxDelayMs:2e3,jitter:.2,shouldRetry:e=>{let t=o({error:e,stdout:h?.stdout??m?.stdout,stderr:h?.stderr??m?.stderr,context:{platform:`ios`,phase:`boot`}});return t!==`IOS_BOOT_TIMEOUT`&&t!==`CI_RESOURCE_STARVATION_SUSPECTED`}},{deadline:d,phase:`boot`,signal:c.signal,classifyReason:e=>o({error:e,stdout:h?.stdout??m?.stdout,stderr:h?.stderr??m?.stderr,context:{platform:`ios`,phase:`boot`}})})}catch(t){let n=o({error:t,stdout:h?.stdout??m?.stdout,stderr:h?.stderr??m?.stderr,context:{platform:`ios`,phase:`boot`}});throw new e(`COMMAND_FAILED`,`iOS simulator failed to boot`,{platform:`ios`,deviceId:a.id,timeoutMs:l,elapsedMs:d.elapsedMs(),reason:n,hint:s(n),boot:m,bootstatus:h})}x(a),await C({deviceHub:c.deviceHub,signal:c.signal})}async function T(e,t){let n=p(e,[`list`,`devices`,`-j`]),r=await f(n,{allowFailure:!0,signal:t,timeoutMs:u});if(r.exitCode!==0)return null;try{let t=JSON.parse(r.stdout);for(let n of Object.values(t.devices??{})){let t=n.find(t=>t.udid===e.id);if(t)return t.state}return null}catch{return null}}export{_ as a,b as i,x as n,S as r,w as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function e(e){let t=r(e.quality);return{...e.analysis?{analysis:e.analysis}:{},...e.androidSnapshot?{androidSnapshot:e.androidSnapshot}:{},...e.freshness?{freshness:e.freshness}:{},...t?{quality:t}:{},...e.warnings?{warnings:e.warnings}:{}}}function t(e){return{...e.androidSnapshot?{androidSnapshot:e.androidSnapshot}:{},...e.quality?{snapshotQuality:e.quality}:{},...e.warnings&&e.warnings.length>0?{warnings:e.warnings}:{}}}function n(e){let n=i(e.androidSnapshot),a=Array.isArray(e.warnings)?e.warnings.filter(e=>typeof e==`string`):void 0,o=r(e.snapshotQuality);return t({...n?{androidSnapshot:n}:{},...o?{quality:o}:{},...a?{warnings:a}:{}})}function r(e){if(!e||typeof e!=`object`)return;let t=e;return typeof t.state==`string`&&typeof t.backend==`string`?t:void 0}function i(e){return typeof e==`object`&&e?e:void 0}export{n,e as r,t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as e,r as t,t as n}from"./snapshot-scope.js";const r=[`button`,`menu`,`textfield`,`searchfield`,`checkbox`,`radio`,`switch`];function i(e,t){let n=e.nodes??[];return t.scope&&(n=a(n,t.scope,e=>!t.interactiveOnly||n.slice(e.start,e.end).some(c))),t.interactiveOnly&&(n=o(n)),typeof t.depth==`number`&&(n=s(n,t.depth)),{...e,nodes:n}}function a(r,i,a){let o=t(i);if(!o)return e(r);let s=n(r,o,a);if(!s)return[];let c=r.slice(s.start,s.end);return e(c,c[0]?.depth??0)}function o(t){if(t.length===0)return t;let n=new Map(t.map(e=>[e.index,e])),r=new Set;for(let e of t){if(!c(e))continue;let t=e;for(;t&&!r.has(t.index);)r.add(t.index),t=typeof t.parentIndex==`number`?n.get(t.parentIndex):void 0}return r.size===0?t:e(t.filter(e=>r.has(e.index)))}function s(t,n){return e(t.filter(e=>(e.depth??0)<=n))}function c(e){if([e.focused,e.hittable,e.rect].some(Boolean))return!0;let t=`${e.type??``} ${e.role??``} ${e.subrole??``}`.toLowerCase();return r.some(e=>t.includes(e))}export{i as n,a as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{O as e}from"./sdk-batch-runner.js";const t=1500;function n(e,t){e&&(e.snapshotDiagnostics??={samples:[]}).samples.push({...t,durationMs:Math.max(0,Math.round(t.durationMs))})}function r(e){let t=e?.snapshotDiagnostics?.samples;if(!(!t||t.length===0))return i(t)}function i(e){if(e.length===0)return;let n=e.slice(1),r=n.length>=3?s(n):void 0,i=n.filter(e=>e.durationMs>=t).length,a=r!==void 0&&r.p95Ms>=t&&i>=2;return{stats:s(e),...a&&r?{warning:d(r)}:{}}}function a(e){let t=e.filter(e=>e!==void 0),n=t.flatMap(e=>_(e.stats));if(n.length===0)return;let r=s(n),i=t.filter(e=>e.warning);return{stats:r,...i.length>0?{warning:f({warnedCount:i.length,totalCount:t.length,worst:i.reduce((e,t)=>Math.max(e,t.stats.p95Ms),0),platform:r.platform})}:{}}}function o(t){if(!e(t))return;let n=p(t.stats);if(!n)return;let r=typeof t.warning==`string`?t.warning:void 0;return{stats:n,...r?{warning:r}:{}}}function s(e){let n=e.map(e=>e.durationMs).sort((e,t)=>e-t);return{count:n.length,p50Ms:c(n,50),p95Ms:c(n,95),maxMs:n.at(-1)??0,slowThresholdMs:t,...l(e),...u(e)}}function c(e,t){if(e.length===0)return 0;let n=Math.max(0,Math.ceil(t/100*e.length)-1);return e[Math.min(n,e.length-1)]??0}function l(e){let t=e.map(e=>e.platform).filter(e=>!!e);return new Set(t).size===1?{platform:t[0]}:{}}function u(e){let t={};for(let n of e)n.backend&&(t[n.backend]=(t[n.backend]??0)+1);return Object.keys(t).length>0?{backends:t}:{}}function d(e){return`Warning: ${e.platform?`${e.platform} `:``}snapshots are slow in this run: p95 ${e.p95Ms}ms over ${e.count} captures. Possible causes: device load, app or dev server stuck, helper fallback, or stale daemon.`}function f(e){return`Warning: ${e.platform?`${e.platform} `:``}snapshots were slow in ${e.warnedCount} of ${e.totalCount} runs (worst run p95 ${e.worst}ms). Possible causes: device load, app or dev server stuck, helper fallback, or stale daemon.`}function p(t){if(!e(t))return;let n=m(t);if(n)return{...n,...g(t)}}function m(e){let t={count:e.count,p50Ms:e.p50Ms,p95Ms:e.p95Ms,maxMs:e.maxMs,slowThresholdMs:e.slowThresholdMs};if(!Object.values(t).some(e=>typeof e!=`number`))return t}function h(e){let t=Object.entries(e).filter(e=>typeof e[1]==`number`);return t.length>0?Object.fromEntries(t):void 0}function g(t){let n=typeof t.platform==`string`?t.platform:void 0,r=e(t.backends)?h(t.backends):void 0;return{...n?{platform:n}:{},...r?{backends:r}:{}}}function _(e){if(!e||e.count<=0)return[];let t=e.platform;return e.count===1?[{durationMs:e.maxMs,platform:t}]:e.count===2?[{durationMs:e.p50Ms,platform:t},{durationMs:e.maxMs,platform:t}]:[...Array.from({length:e.count-3},()=>({durationMs:e.p50Ms,platform:t})),{durationMs:e.p50Ms,platform:t},{durationMs:e.p95Ms,platform:t},{durationMs:e.maxMs,platform:t}]}export{i as a,r as i,o as n,n as r,a as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as e}from"./tool-provider.js";async function t(t,n){let r=await e(`ps`,[`-p`,String(t),`-o`,`lstart=`],{allowFailure:!0,signal:n.signal,timeoutMs:n.timeoutMs});return r.exitCode===0&&r.stdout.trim()||null}export{t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e={tree:{forceable:!0,supportsRawProjection:!0,regularDepth:`presented-frontier`,hittable:`geometric-actionability`,deepExtension:`no`,depthLadder:`n/a`,knownGaps:[`deep-extension`]},queries:{forceable:!1,supportsRawProjection:!1,regularDepth:`flat`,hittable:`geometric-actionability`,deepExtension:`n/a`,depthLadder:`n/a`,knownGaps:[]},"private-ax":{forceable:!0,supportsRawProjection:!0,regularDepth:`raw-only`,hittable:`geometric-actionability`,deepExtension:`yes`,depthLadder:`yes`,knownGaps:[]}},t={"android-helper":{forceable:!1,supportsRawProjection:!0,regularDepth:`presented-frontier`,hittable:`geometric-actionability`,deepExtension:`n/a`,depthLadder:`n/a`,knownGaps:[]}},n={...e,...t};export{n,e as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{P as e,y as t}from"./sdk-contracts.js";import{a as n}from"./capture.js";import{n as r}from"./snapshot-quality-backend-capabilities.js";import{r as i}from"./diagnostics.js";import"./diagnostics2.js";import{a,i as o,n as s,r as c,t as l}from"./png-worker-contract.js";import u from"node:path";import d,{promises as f}from"node:fs";import{fileURLToPath as p}from"node:url";import{Worker as m}from"node:worker_threads";function h(e,t){try{let n=p(e),r=u.extname(n)||`.js`;return[u.join(u.dirname(n),`${t}${r}`),u.join(u.dirname(n),`internal`,`${t}${r}`)].find(e=>d.existsSync(e))??null}catch{return null}}var g=class extends Error{};let _=null,v=!1,y=!1,b=0;const x=new Map;function S(e){v=!0,!y&&(y=!0,i({level:`warn`,phase:`png_worker_unavailable`,data:{reason:e}}),process.emitWarning(`PNG worker unavailable, falling back to in-process PNG processing: ${e}`))}function C(n){let r=x.get(n.id);r&&(x.delete(n.id),E(),n.ok?r.resolve(n.result):r.reject(new t(e(n.error.code),n.error.message,n.error.details)))}function w(e,t){_===e&&(S(t.message),_=null,e.terminate().catch(()=>{}),T(new g(`PNG worker failed: ${t.message}`)))}function T(e){let t=[...x.values()];x.clear();for(let n of t)n.reject(e)}function E(){_&&(x.size>0?_.ref():_.unref())}function D(){if(v)return null;if(_)return _;let e=h(import.meta.url,`png-worker`);if(!e)return S(`worker entry module not found next to the current module`),null;try{let t=new m(e,{execArgv:e.endsWith(`.ts`)?[`--experimental-strip-types`]:[]});return t.on(`message`,C),t.on(`error`,e=>{w(t,e)}),t.on(`exit`,e=>{w(t,Error(`PNG worker exited with code ${e}`))}),t.unref(),_=t,t}catch(e){return S(`failed to spawn worker: ${e instanceof Error?e.message:String(e)}`),null}}function O(e){let t=D();if(!t)return Promise.reject(new g(`PNG worker is unavailable`));b+=1;let n=b;return new Promise((r,i)=>{x.set(n,{resolve:r,reject:i}),E();try{t.postMessage({...e,id:n})}catch(e){x.delete(n),E(),i(new g(`failed to post job to PNG worker: ${e instanceof Error?e.message:String(e)}`))}})}async function k(e,t){try{return await O(e)}catch(e){if(e instanceof g)return t();throw e}}function A(){D()}async function j(){let e=_;_=null,T(new g(`PNG worker terminated`)),e&&await e.terminate()}async function M(e,t){let n=await k({kind:`decode`,png:e,label:t},()=>{let n=o(e,t);return{kind:`decode`,width:n.width,height:n.height,data:n.data}}),r=new a.PNG({width:n.width,height:n.height});return r.data=l(n.data),r}async function N(e){let t=await k({kind:`encode`,width:e.width,height:e.height,data:e.data},()=>({kind:`encode`,png:a.PNG.sync.write(e)}));return l(t.png)}async function P(e,t,n){let{kind:r,...i}=await k({kind:`rgb-difference`,firstPng:e,secondPng:t,label:n},()=>({kind:`rgb-difference`,...s(o(e,n),o(t,n))}));return i}async function F(e){let{kind:t,...n}=await k({kind:`diff-pixels`,...e},()=>({kind:`diff-pixels`,...c(e)}));return{...n,diffData:l(n.diffData)}}async function I(e,r){let{min:i,max:a}=n;if(!Number.isFinite(r)||r<i||r>a)throw new t(`INVALID_ARGS`,`Screenshot scale must be between ${i} and ${a}`);if(r===1)return;let o=await M(await f.readFile(e),`screenshot`),s=Math.max(1,Math.round(o.width*r)),c=Math.max(1,Math.round(o.height*r));await f.writeFile(e,await N(R(o,s,c)))}async function L(e,n,r){if(!Number.isInteger(n)||n<1||!Number.isInteger(r)||r<1)throw new t(`INVALID_ARGS`,`Screenshot resize dimensions must be positive integers`);let i=await M(await f.readFile(e),`screenshot`);(i.width!==n||i.height!==r)&&await f.writeFile(e,await N(R(i,n,r)))}function R(e,t,n){let r=new a.PNG({width:t,height:n});for(let i=0;i<n;i+=1){let a=i*e.height/n,o=(i+1)*e.height/n;for(let n=0;n<t;n+=1){let s=n*e.width/t,c=(n+1)*e.width/t,l=0,u=0,d=0,f=0,p=0;for(let t=Math.floor(a);t<Math.ceil(o);t+=1){let n=Math.min(t+1,o)-Math.max(t,a);for(let r=Math.floor(s);r<Math.ceil(c);r+=1){let i=n*(Math.min(r+1,c)-Math.max(r,s)),a=(t*e.width+r)*4;l+=(e.data[a]??0)*i,u+=(e.data[a+1]??0)*i,d+=(e.data[a+2]??0)*i,f+=(e.data[a+3]??0)*i,p+=i}}let m=(i*r.width+n)*4;r.data[m]=Math.round(l/p),r.data[m+1]=Math.round(u/p),r.data[m+2]=Math.round(d/p),r.data[m+3]=Math.round(f/p)}}return r}const z=new Set([`healthy`,`recovered`,`sparse`]),B=new Set(Object.keys(r)),V=new Set([`ax-rejected`,`sparse-tree`,`budget`,`no-nodes`,`capture-failed`,`presentation-failed`,`deferred`,`requested-backend`]);function H(e){if(!e||typeof e!=`object`)return;let t=e;if(typeof t.state!=`string`||!z.has(t.state)||typeof t.backend!=`string`||!B.has(t.backend))return;let n=U(t.timing);return{state:t.state,backend:t.backend,reason:typeof t.reason==`string`?t.reason:void 0,reasonCode:typeof t.reasonCode==`string`&&V.has(t.reasonCode)?t.reasonCode:void 0,customActions:W(t.customActions),effectiveDepth:typeof t.effectiveDepth==`number`?t.effectiveDepth:void 0,collapsedLeafIndexes:Array.isArray(t.collapsedLeafIndexes)?t.collapsedLeafIndexes.filter(e=>typeof e==`number`):void 0,...n?{timing:n}:{}}}function U(e){if(!e||typeof e!=`object`)return;let t=e;if(typeof t.acquisitionMs==`number`&&typeof t.presentationMs==`number`)return{acquisitionMs:t.acquisitionMs,presentationMs:t.presentationMs}}function W(e){if(!e||typeof e!=`object`)return;let t=e;if(typeof t.read==`number`&&typeof t.candidates==`number`)return{read:t.read,candidates:t.candidates,truncated:typeof t.truncated==`number`?t.truncated:0,blocked:t.blocked===!0}}function G(e){return e?.state===`sparse`}function K(e){return e?.backend===`private-ax`?`private-ax`:void 0}export{I as a,M as c,j as d,L as i,N as l,K as n,P as o,H as r,F as s,G as t,A as u};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{l as e}from"./sdk-device.js";import{Ft as t}from"./sdk-batch.js";import"./session-store.js";import{r as n}from"./command.js";import{r}from"./provider-device-runtime.js";import{n as i}from"./dispatch-resolve.js";import{i as a,n as o}from"./request-runtime-binding.js";import{f as s,l as c}from"./session-snapshot.js";import{a as l,i as u,n as d,t as f}from"./session-runtime-admission.js";import{a as p}from"./platform-runtime-open-target.js";async function m(e,t,n){let r=e.get(t);return{session:r,device:r?.device??await i(n??{})}}async function h(e,t,n,i){if(!e&&!i)throw Error(`Platform resource cleanup was not injected`);try{return await n()}finally{!e&&!r(t)&&await i.cleanupSessionlessExecutionHost(t)}}function g(e,t,n,r){t&&e.recordAction(t,{command:n.command,positionals:n.positionals??[],flags:n.flags??{},result:r})}function _(e){let{session:t,sessionName:n,sessionScope:r,device:i,snapshot:a,appBundleId:o}=e;return t?{...t,snapshot:a,lastComparisonSafeSnapshot:a?.comparisonSafe===!0?a:t.lastComparisonSafeSnapshot}:{name:n,sessionScope:r,device:i,createdAt:Date.now(),appBundleId:o,snapshot:a,...a?.comparisonSafe===!0?{lastComparisonSafeSnapshot:a}:{},actions:[]}}async function v(t){if(!e(t)||t.kind!==`simulator`)return;let n=await p({simulatorSetPath:t.simulatorSetPath});if(!n)return;let r=y(n.device,n.app.bundleId),i=`One booted device found ("${n.device.name}", udid ${n.device.id}) with ${n.app.bundleId} running. Run: ${r}`;return i.length<=350?i:void 0}function y(e,t){let r=e.simulatorSetPath?` --ios-simulator-device-set ${n(e.simulatorSetPath)}`:``;return`agent-device open ${t} --platform ios --udid ${e.id}${r}`}function b(e){let{readTextAtPoint:t}=e.operations,n=t?{operations:{readTextAtPoint:t}}:void 0;return Object.freeze(n?{readTextAtPoint:async e=>await n.operations.readTextAtPoint(e)}:{})}function x(e){let{findText:t,findSelector:n}=e.operations,r=t?{operations:{findText:t}}:void 0,i=n?{operations:{findSelector:n}}:void 0;return Object.freeze({...r?{findText:async e=>await r.operations.findText(e)}:{},...i?{findSelector:async e=>await i.operations.findSelector(e)}:{}})}function S(e){let{focusPoint:t,typeText:n}=e.operations;return Object.freeze({...t?{focusPoint:t}:{},...n?{typeText:n}:{}})}async function C(e){let{command:t,device:n,session:r,plan:i}=e,a=await f({device:n,plan:i,inspectFacts:e.inspectFacts});if(!a.admitted)return{ok:!1,response:await j({operation:a.operation,fact:a.fact,session:r,device:n,command:t})};let o=await T(e.bindDevice,a,e.readiness);return Object.freeze({ok:!0,capture:async e=>await o.captureSnapshot(e),...o.readTextAtPoint?{readTextAtPoint:o.readTextAtPoint}:{},...o.findText?{findText:o.findText}:{},...o.findSelector?{findSelector:o.findSelector}:{},...o.focusPoint?{focusPoint:o.focusPoint}:{},...o.typeText?{typeText:o.typeText}:{}})}async function w(e,n){let{req:r,sessionName:i,sessionStore:a}=e,{session:o,device:l}=await m(a,i,r.flags),u=c(r.flags?.snapshotScope,o);if(!u.ok)return{ok:!1,response:u};let d=await C({command:n,device:l,session:o,plan:t({customActions:r.flags?.snapshotCustomActions===!0,hasActiveApp:o?.appBundleId!==void 0}),inspectFacts:e.inspectFacts,bindDevice:e.bindDevice,...o?{}:{readiness:{}}});if(!d.ok)return d;let f=s({flags:r.flags,logPath:e.logPath,meta:r.meta,session:o,snapshotScope:u.scope});return Object.freeze({ok:!0,session:o,device:l,snapshotScope:u.scope,captureSnapshot:async()=>await d.capture(f)})}async function T(e,t,n){let r=d(e),i=async(e,t)=>{let i=await r(e,t);return n!==void 0&&await o(i,n),i},{device:a,plan:s}=l(t);switch(s.kind){case`active-app`:return O(await i(a,s.use));case`selector-active-app`:return await E(i,a,s);case`custom-actions-active-app`:return k(await i(a,s.use));case`without-active-app`:return A(await i(a,s.use));case`selector-without-active-app`:return await D(i,a,s);case`custom-actions-without-active-app`:return k(await i(a,s.use))}}async function E(e,t,n){switch(n.intent){case`capture-only`:return O(await e(t,n.use));case`element-text`:{let r=await e(t,n.use);return{...O(r),...b(r)}}case`wait-observation`:{let r=await e(t,n.use);return{...O(r),...x(r)}}case`find-focus`:{let r=await e(t,n.use);return{...O(r),...S(r)}}case`find-type`:{let r=await e(t,n.use);return{...O(r),...S(r)}}}}async function D(e,t,n){switch(n.intent){case`capture-only`:return A(await e(t,n.use));case`element-text`:{let r=await e(t,n.use);return{...A(r),...b(r)}}case`wait-observation`:{let r=await e(t,n.use);return{...A(r),...x(r)}}case`find-focus`:{let r=await e(t,n.use);return{...A(r),...S(r)}}case`find-type`:{let r=await e(t,n.use);return{...A(r),...S(r)}}}}function O(e){return Object.freeze({captureSnapshot:async t=>await e.operations.captureSnapshot(t)})}function k(e){return Object.freeze({captureSnapshot:async t=>await e.operations.captureSnapshotWithCustomActions(t)})}function A(e){return Object.freeze({captureSnapshot:async t=>await e.operations.captureSnapshotWithoutActiveApp(t)})}async function j(e){if(e.operation===`captureSnapshot`||e.operation===`focusPoint`||e.operation===`typeText`)return u(e.command,e.fact);if(e.operation===`captureSnapshotWithCustomActions`)return M(e);let t=await v(e.device);return a(`SESSION_NOT_FOUND`,`iOS ${e.command} requires an active app session on the target device. Run open first (for example: open --session ${e.session?.name??`sim`} --platform ios --device "<name>" <app>).`,{reason:`ios_app_session_required`,...t?{hint:t}:{}})}function M(e){let t=e.command===`diff`?`--actions requires an iOS simulator: custom actions are read through the private accessibility snapshot backend, which ${e.device.platform}/${e.device.kind} targets do not have.`:`--actions requires an iOS simulator: custom actions are unavailable on this ${e.device.platform}/${e.device.kind} target.`;return a(`UNSUPPORTED_OPERATION`,t,{reason:e.fact.available?void 0:e.fact.reason},{hint:e.command===`diff`||e.fact.available||!e.fact.hint?`Re-run without --actions, or target an iOS simulator.`:e.fact.hint})}export{m as a,g as i,w as n,h as o,_ as r,C as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{E as e,_ as t}from"./sdk-contracts.js";import{f as n,g as r}from"./location-coordinates.js";import{wt as i,zt as a}from"./sdk-batch-runner.js";import{_ as o,c as s}from"./sdk-device.js";import{N as c}from"./screenshot-result.js";import{t as l}from"./verdict.js";import{o as u,t as d}from"./runtime.js";import{A as f}from"./sdk-android-adb.js";import{n as p}from"./shell-quote.js";import{j as ee}from"./runner-disposal.js";import{a as m,t as h}from"./dispatch.js";import{Tt as g,_t as _,ct as v,dt as y,ft as te,jt as b,vt as x,wt as S}from"./internal/daemon.js";import{a as C,i as w,r as T,t as E}from"./snapshot-session.js";import{a as D}from"./platform-runtime-open-target.js";import O from"node:path";import{promises as k}from"node:fs";import A from"node:os";function j(e,t){if(!t.available)return m(`UNSUPPORTED_OPERATION`,`${e} is not supported on this device`,{reason:t.reason},t.hint?{hint:t.hint}:void 0)}function M(e){if(e)return e;throw new t(`COMMAND_FAILED`,`Device runtime facts inspection is unavailable.`)}async function N(e){let t=await M(e.inspectFacts)(e.device);for(let n of e.use.required){let e=t.operations[n];if(!e.available)return{admitted:!1,operation:n,fact:e}}return{admitted:!0}}function P(e){if(e)return e;throw new t(`COMMAND_FAILED`,`Device runtime binding is unavailable.`)}async function F(t){if(t.command!==`snapshot`||t.device.platform!==`android`)return;let n=e(t.error);if(B(n))return{ok:!1,error:{...n,details:{...n.details??{},androidSnapshotTimeoutScreenshot:await I(t)}}}}async function I(t){try{let e=await k.mkdtemp(O.join(A.tmpdir(),`agent-device-android-snapshot-timeout-`)),n=O.join(e,`snapshot-timeout-overlay-refs.png`),r=R(await h(t.device,`screenshot`,[n],void 0,{...b(t.logPath,{screenshotNoStabilize:!0},t.session?.appBundleId,t.session?.trace?.outPath),surface:t.session?.surface}),n);await k.access(r);let i=await L(r,t.session);return f({level:`warn`,phase:`android_snapshot_timeout_screenshot_captured`,data:{path:r,overlayRefCount:`overlayRefCount`in i?i.overlayRefCount:void 0,overlayRefsAnnotated:`overlayRefsAnnotated`in i?i.overlayRefsAnnotated:void 0}}),i}catch(t){let n=e(t);return f({level:`warn`,phase:`android_snapshot_timeout_screenshot_failed`,data:{error:n.message}}),{captureFailed:!0,error:n.message}}}async function L(t,n){if(!n?.snapshot)return{path:t,overlayRefsRequested:!0,overlayRefsAnnotated:!1,overlayRefSource:`unavailable`,overlayRefCount:0};try{let e=await v({screenshotPath:t,snapshot:n.snapshot});return{path:t,overlayRefsRequested:!0,overlayRefsAnnotated:e.length>0,overlayRefCount:e.length,overlayRefSource:`session-snapshot`,overlayRefs:e}}catch(n){let r=e(n);return f({level:`warn`,phase:`android_snapshot_timeout_screenshot_overlay_failed`,data:{path:t,error:r.message}}),{path:t,overlayRefsRequested:!0,overlayRefsAnnotated:!1,overlayRefSource:`session-snapshot`,overlayRefCount:0,overlayAnnotationError:r.message}}}function R(e,t){return z(e)?e.path:t}function z(e){return typeof e==`object`&&!!e&&`path`in e&&typeof e.path==`string`}function B(e){return e.code===`COMMAND_FAILED`?V(e)||H(e.details?.helper):!1}function V(e){let t=`${e.message}\n${e.hint??``}`;return/Android accessibility snapshots can be blocked/i.test(t)}function H(e){if(!e||typeof e!=`object`)return!1;let t=e,n=String(t.errorType??``),r=String(t.message??``);return/TimeoutException/i.test(n)||/timed out/i.test(r)}function U(e){let{verdict:t,appBundleId:n,latch:r}=e;return t?t.state===`healthy`?{latch:void 0}:t.state!==`recovered`||t.reasonCode===`requested-backend`?{latch:r}:t.reasonCode===`deferred`?r!==void 0&&r.appBundleId===n?{latch:r}:{warning:u(t.backend),latch:{appBundleId:n}}:{latch:{appBundleId:n}}:{latch:r}}function W(e){let{session:t,data:n,verdict:r,internalObservation:i}=e;if(i||!t)return n;let a=U({verdict:r,appBundleId:t.appBundleId,latch:t.recoveredSnapshotWarningLatch});if(t.recoveredSnapshotWarningLatch=a.latch,!a.warning)return n;let o=Array.isArray(n.warnings)?n.warnings:[];return{...n,warnings:[a.warning,...o]}}async function ne(e){if(!s(e)||e.kind!==`simulator`)return;let t=await D({simulatorSetPath:e.simulatorSetPath});if(!t)return;let n=G(t.device,t.app.bundleId),r=`One booted device found ("${t.device.name}", udid ${t.device.id}) with ${t.app.bundleId} running. Run: ${n}`;return r.length<=350?r:void 0}function G(e,t){let n=e.simulatorSetPath?` --ios-simulator-device-set ${p(e.simulatorSetPath)}`:``;return`agent-device open ${t} --platform ios --udid ${e.id}${n}`}async function K(e,t){let{req:n,sessionName:r,sessionStore:a}=e,{session:o,device:s}=await T(a,r,n.flags),c=g(n.flags?.snapshotScope,o);if(!c.ok)return{ok:!1,response:c};let l=i({customActions:n.flags?.snapshotCustomActions===!0,hasActiveApp:o?.appBundleId!==void 0}),u=await N({device:s,use:l.use,inspectFacts:e.inspectFacts});if(!u.admitted)return{ok:!1,response:await Z({operation:u.operation,fact:u.fact,session:o,device:s,command:t})};let d=await q(e.bindDevice,s,l),f=ie(e,o,c.scope);return Object.freeze({ok:!0,session:o,device:s,snapshotScope:c.scope,captureSnapshot:async()=>await d.captureSnapshot(f)})}async function q(e,t,n){let r=P(e);switch(n.kind){case`active-app`:return J(await r(t,n.use));case`custom-actions-active-app`:return Y(await r(t,n.use));case`without-active-app`:return X(await r(t,n.use));case`custom-actions-without-active-app`:return Y(await r(t,n.use))}}function J(e){return Object.freeze({captureSnapshot:async t=>await e.operations.captureSnapshot(t)})}function Y(e){return Object.freeze({captureSnapshot:async t=>await e.operations.captureSnapshotWithCustomActions(t)})}function X(e){return Object.freeze({captureSnapshot:async t=>await e.operations.captureSnapshotWithoutActiveApp(t)})}async function Z(e){if(e.operation===`captureSnapshot`)return j(e.command,e.fact);if(e.operation===`captureSnapshotWithCustomActions`)return re(e);let t=await ne(e.device);return m(`SESSION_NOT_FOUND`,`iOS ${e.command} requires an active app session on the target device. Run open first (for example: open --session ${e.session?.name??`sim`} --platform ios --device "<name>" <app>).`,{reason:`ios_app_session_required`,...t?{hint:t}:{}})}function re(e){return m(`UNSUPPORTED_OPERATION`,e.command===`diff`?`--actions requires an iOS simulator: custom actions are read through the private accessibility snapshot backend, which ${e.device.platform}/${e.device.kind} targets do not have.`:`--actions requires an iOS simulator: custom actions are unavailable on this ${e.device.platform}/${e.device.kind} target.`,{reason:e.fact.available?void 0:e.fact.reason},{hint:e.command===`diff`||e.fact.available||!e.fact.hint?`Re-run without --actions, or target an iOS simulator.`:e.fact.hint})}function ie(e,t,n){let{req:r,logPath:i}=e,a=r.flags??{},{appBundleId:o,trace:s,surface:c}=t??{},{requestId:l}=r.meta??{},u=b(i,a,o,s?.outPath,l,r.meta);return{options:{appBundleId:o,interactiveOnly:a.snapshotInteractiveOnly,preferredBackend:a.snapshotPreferredBackend,depth:a.snapshotDepth,scope:n,raw:a.snapshotRaw,customActions:a.snapshotCustomActions,includeHiddenContentHints:a.snapshotIncludeHiddenContentHints,surface:c},execution:{requestId:u.requestId,verbose:u.verbose,logPath:u.logPath,traceLogPath:u.traceLogPath,iosXctestrunFile:u.iosXctestrunFile,iosXctestDerivedDataPath:u.iosXctestDerivedDataPath,iosXctestEnvDir:u.iosXctestEnvDir,runnerLeaseContext:u.runnerLeaseContext}}}async function Q(e){let t=await K(e,e.command);if(!t.ok)return t.response;let{session:n,device:r,snapshotScope:i}=t;return await w(n,r,async()=>{let{req:a,sessionName:o,logPath:s,sessionStore:c}=e,l={},u=ae({req:a,sessionName:o,logPath:s,sessionStore:c,session:n,device:r,snapshotScope:i,capturedQuality:l,captureSnapshotData:t.captureSnapshot}),d;try{d=await e.execute({runtime:u,sessionName:o,req:a,snapshotScope:i})}catch(t){let i=await F({error:t,command:e.command,logPath:s,session:n,device:r});if(!i)throw t;return i}return fe({req:a,sessionName:o,sessionStore:c,result:d.record}),{ok:!0,data:W({session:c.get(o),data:d.data,verdict:l.value,internalObservation:a.internal?.observationOnly===!0})}})}function ae(e){let{req:t,sessionName:n,logPath:r,sessionStore:i,session:a,device:o,snapshotScope:s}=e;return d({backend:de({req:t,logPath:r,session:a,device:o,snapshotScope:s,capturedQuality:e.capturedQuality,captureSnapshotData:e.captureSnapshotData}),...C(`snapshot`),signal:ee(t.meta?.requestId),sessions:te({sessionName:n,getSession:()=>i.get(n),recordOptions:{includeSnapshot:!0},setRecord:e=>{let r=pe(e),a=i.get(n);i.set(n,oe({current:a,sessionName:n,device:o,record:r,refScopedSnapshot:se(t),issuesRefsToClient:t.command===`snapshot`&&t.internal?.observationOnly!==!0}))}})})}function oe(e){let{current:t,sessionName:n,device:r,record:i,refScopedSnapshot:a}=e,o=ce(t,i,a),s=E({session:t,sessionName:n,device:r,snapshot:o?t.snapshot:i.snapshot,appBundleId:i.appBundleId});return _(s,{scopeSource:ue({current:t,keepCurrentSnapshot:o,refScopedSnapshot:a}),keptCurrentSnapshot:o,previousGeneration:t?.snapshotGeneration}),le(s,o,e.issuesRefsToClient),i.appName&&(s.appName=i.appName),s}function se(e){return e.flags?.snapshotScope?.trim().startsWith(`@`)===!0}function ce(e,t,n){return n&&t.snapshot?.nodes.length===0&&e?.snapshot!==void 0}function le(e,t,n){!t&&n&&x(e)}function ue(e){let{current:t,keepCurrentSnapshot:n,refScopedSnapshot:r}=e;if(r)return n?t?.snapshotScopeSource:t?.snapshotScopeSource??t?.snapshot}function de(e){let{req:t,logPath:i,session:a,device:s,snapshotScope:c}=e;return{platform:o(s),captureSnapshot:async(o,l)=>{let u=await S({device:s,session:a,flags:t.flags,outPath:l?.outPath??t.flags?.out,logPath:i,snapshotScope:c,signal:o.signal,captureData:e.captureSnapshotData}),d=r(u);e.capturedQuality.value=d.quality;let f=n(a);return{snapshot:u.snapshot,...d,...f?{snapshotDiagnostics:f}:{},appName:a?.appBundleId?a.appName??a.appBundleId:void 0,appBundleId:a?.appBundleId}}}}function fe(e){let t=e.sessionStore.get(e.sessionName);t&&e.sessionStore.recordAction(t,{command:e.req.command,positionals:e.req.positionals??[],flags:e.req.flags??{},result:$(e.result),interactiveObservation:c(e.req)})}function pe(e){if(!e.snapshot)throw new t(`UNKNOWN`,`snapshot runtime did not produce session state`);return e}function $(e){return e.kind===`snapshot`?{nodes:e.nodes,truncated:e.truncated}:{mode:e.mode,baselineInitialized:e.baselineInitialized,summary:e.summary}}async function me(e){let t=e.session;if(!t||!l(e.verdict)||e.req.internal?.observationOnly===!0)return;let n=await he({...e,session:t});if(n!==void 0)return{path:n,artifact:{field:`fallbackScreenshotPath`,artifactType:`screenshot`,path:n,fileName:`snapshot-fallback.png`}}}async function he(e){let{req:t,session:n}=e;try{let r=await y({session:n,sessionName:e.sessionName,outputPlacement:`default`,dispatchContext:b(e.logPath,t.flags,n.appBundleId,n.trace?.outPath,t.meta?.requestId,t.meta)});return typeof r.path==`string`?r.path:void 0}catch{return}}async function ge(e){return await Q({...e,command:`snapshot`,execute:async({runtime:t,sessionName:n,req:r,snapshotScope:i})=>{let o=await t.capture.snapshot({session:n,interactiveOnly:r.flags?.snapshotInteractiveOnly,depth:r.flags?.snapshotDepth,scope:i,raw:r.flags?.snapshotRaw,customActions:r.flags?.snapshotCustomActions,forceFull:r.flags?.snapshotForceFull}),s=_e(r,e.sessionStore.get(n)),c=a(o.nodes),l=c===o.nodes?o:{...o,nodes:c},u=await me({req:r,session:e.sessionStore.get(n),sessionName:n,logPath:e.logPath,verdict:o.snapshotQuality}),d=u?{...l,fallbackScreenshotPath:u.path,artifacts:[u.artifact]}:l;return{data:s===void 0?d:{...d,refsGeneration:s},record:{kind:`snapshot`,nodes:o.nodes.length,truncated:o.truncated}}}})}function _e(e,t){return e.internal?.observationOnly===!0?void 0:t?.snapshotGeneration}export{j as a,M as i,Q as n,P as r,ge as t};
|
|
1
|
+
import{O as e,y as t}from"./sdk-contracts.js";import"./capture.js";import{r as n}from"./snapshot-capture-annotations.js";import{i as r}from"./snapshot-diagnostics.js";import{f as i}from"./android-input-ownership.js";import{v as a}from"./sdk-device.js";import{s as o}from"./session-store.js";import{s}from"./session-target-evidence.js";import{t as c,x as l}from"./runtime.js";import{r as u}from"./diagnostics.js";import"./diagnostics2.js";import{i as d,s as f}from"./android-system-chrome.js";import{r as p}from"./request-cancel.js";import"./request.js";import{a as m,i as h,r as g,t as _}from"./screenshot-runtime.js";import{S as v,a as y,b,o as x,s as S}from"./session-snapshot.js";import{a as C}from"./session-routing.js";import{t as w}from"./snapshot-quality-verdict.js";import{n as T,o as E,r as D}from"./snapshot-runtime-binding.js";import O from"node:path";import{promises as k}from"node:fs";import A from"node:os";function j(e){return{captureFailed:!0,error:e}}function M(e){return{path:e,overlayRefsRequested:!0,overlayRefsAnnotated:!1,overlayRefSource:`unavailable`}}function N(e,t){let n={path:e,overlayRefsRequested:!0,overlayRefSource:`session-snapshot`};return P(t)?{...n,overlayRefsAnnotated:!0,overlayRefs:t}:{...n,overlayRefsAnnotated:!1,overlayRefs:[]}}function P(e){return e.length>0}function F(e,t){return{path:e,overlayRefsRequested:!0,overlayRefsAnnotated:!1,overlayRefSource:`session-snapshot`,overlayAnnotationError:t}}function ee(e){return`captureFailed`in e?{overlayRefCount:void 0,overlayRefsAnnotated:void 0}:{overlayRefCount:`overlayRefs`in e?e.overlayRefs.length:0,overlayRefsAnnotated:e.overlayRefsAnnotated}}function I(e){return f(e)===`accessibility-timeout`}async function L(t){if(t.command!==`snapshot`||t.device.platform!==`android`)return;let n=e(t.error);if(I(n))return{ok:!1,error:{...n,details:{...n.details??{},androidSnapshotTimeoutScreenshot:await R(t)}}}}async function R(n){try{let e=await h({device:n.device,overlayRefs:!1,inspectFacts:n.inspectFacts,bindDevice:n.bindDevice});if(!e.ok)throw new t(`UNSUPPORTED_OPERATION`,`The target does not support screenshot capture, so no timeout evidence was taken.`);let r=await k.mkdtemp(O.join(A.tmpdir(),`agent-device-android-snapshot-timeout-`)),i=O.join(r,`snapshot-timeout-overlay-refs.png`);await e.runtime.captureScreenshot({outPath:i,options:{appBundleId:n.session?.appBundleId,stabilize:!1,surface:n.session?.surface},execution:g(b(n.logPath,{screenshotNoStabilize:!0},n.session?.appBundleId,n.session?.trace?.outPath))}),await k.access(i);let a=await z(i,n.session);return u({level:`warn`,phase:`android_snapshot_timeout_screenshot_captured`,data:{path:i,...ee(a)}}),a}catch(t){let n=e(t);return u({level:`warn`,phase:`android_snapshot_timeout_screenshot_failed`,data:{error:n.message}}),j(n.message)}}async function z(t,n){if(!n?.snapshot)return M(t);try{return N(t,await m({screenshotPath:t,snapshot:n.snapshot}))}catch(n){let r=e(n);return u({level:`warn`,phase:`android_snapshot_timeout_screenshot_overlay_failed`,data:{path:t,error:r.message}}),F(t,r.message)}}function B(e){let{verdict:t,appBundleId:n,latch:r}=e;return!t||t.backend===`android-helper`?{latch:r}:t.state===`healthy`?{latch:void 0}:t.state!==`recovered`||t.reasonCode===`requested-backend`?{latch:r}:t.reasonCode===`deferred`?r!==void 0&&r.appBundleId===n?{latch:r}:{warning:l(t.backend),latch:{appBundleId:n}}:{latch:{appBundleId:n}}}function V(e){let{session:t,data:n,verdict:r,internalObservation:i}=e;if(i||!t)return n;let a=B({verdict:r,appBundleId:t.appBundleId,latch:t.recoveredSnapshotWarningLatch});if(t.recoveredSnapshotWarningLatch=a.latch,!a.warning)return n;let o=Array.isArray(n.warnings)?n.warnings:[];return{...n,warnings:[a.warning,...o]}}async function H(e){let t=await T(e,e.command);if(!t.ok)return t.response;let{session:n,device:r,snapshotScope:a}=t;return await E(n,r,async()=>{let{req:o,sessionName:s,logPath:c,sessionStore:l}=e,u={},d=U({req:o,sessionName:s,logPath:c,sessionStore:l,session:n,device:r,snapshotScope:a,capturedQuality:u,captureSnapshotData:t.captureSnapshot,inspectFacts:e.inspectFacts,bindDevice:e.bindDevice}),f;try{f=await e.execute({runtime:d,sessionName:s,req:o,snapshotScope:a})}catch(t){let i=await L({error:t,command:e.command,logPath:c,session:n,device:r,inspectFacts:e.inspectFacts,bindDevice:e.bindDevice});if(!i)throw t;return i}X({req:o,sessionName:s,sessionStore:l,result:f.record});let p=V({session:l.get(s),data:f.data,verdict:u.value,internalObservation:o.internal?.observationOnly===!0});return{ok:!0,data:i(f.data,p)}},e.platformResourceCleanup)}function U(e){let{req:t,sessionName:n,logPath:r,sessionStore:i,session:a,device:o,snapshotScope:l}=e;return c({backend:Y({req:t,logPath:r,session:a,device:o,snapshotScope:l,capturedQuality:e.capturedQuality,captureSnapshotData:e.captureSnapshotData,inspectFacts:e.inspectFacts,bindDevice:e.bindDevice}),...s(`snapshot`),signal:p(t.meta?.requestId),sessions:x({sessionName:n,getSession:()=>i.get(n),recordOptions:{includeSnapshot:!0},setRecord:e=>{let r=Z(e),a=i.get(n);i.set(n,W({current:a,sessionName:n,sessionScope:C(t),device:o,record:r,refScopedSnapshot:G(t),issuesRefsToClient:t.command===`snapshot`&&t.internal?.observationOnly!==!0}))}})})}function W(e){let{current:t,sessionName:n,sessionScope:r,device:i,record:a,refScopedSnapshot:o}=e,s=K(t,a,o),c=s?t.snapshot:a.snapshot,l=D({session:t,sessionName:n,sessionScope:r,device:i,snapshot:c,appBundleId:a.appBundleId});return y(l,{scopeSource:J({current:t,keepCurrentSnapshot:s,refScopedSnapshot:o}),keptCurrentSnapshot:s,previousGeneration:t?.snapshotGeneration}),q(l,s,e.issuesRefsToClient),a.appName&&(l.appName=a.appName),l}function G(e){return e.flags?.snapshotScope?.trim().startsWith(`@`)===!0}function K(e,t,n){return n&&t.snapshot?.nodes.length===0&&e?.snapshot!==void 0}function q(e,t,n){!t&&n&&v(e)}function J(e){let{current:t,keepCurrentSnapshot:n,refScopedSnapshot:r}=e;if(r)return n?t?.snapshotScopeSource:t?.snapshotScopeSource??t?.snapshot}function Y(e){let{req:t,logPath:i,session:o,device:s,snapshotScope:c}=e;return{platform:a(s),captureSnapshot:async(a,l)=>{let u=await S({device:s,session:o,flags:t.flags,outPath:l?.outPath??t.flags?.out,logPath:i,snapshotScope:c,signal:a.signal,captureData:e.captureSnapshotData,inspectFacts:e.inspectFacts,bindDevice:e.bindDevice}),d=n(u);e.capturedQuality.value=d.quality;let f=r(o);return{snapshot:u.snapshot,...d,...f?{snapshotDiagnostics:f}:{},appName:o?.appBundleId?o.appName??o.appBundleId:void 0,appBundleId:o?.appBundleId}}}}function X(e){let t=e.sessionStore.get(e.sessionName);t&&e.sessionStore.recordAction(t,{command:e.req.command,positionals:e.req.positionals??[],flags:e.req.flags??{},result:Q(e.result),interactiveObservation:o(e.req)})}function Z(e){if(!e.snapshot)throw new t(`UNKNOWN`,`snapshot runtime did not produce session state`);return e}function Q(e){return e.kind===`snapshot`?{nodes:e.nodes,truncated:e.truncated}:{mode:e.mode,baselineInitialized:e.baselineInitialized,summary:e.summary}}async function $(e){let t=e.session;if(!t||!w(e.verdict)||e.req.internal?.observationOnly===!0)return;let n=await te({...e,session:t});if(n!==void 0)return{path:n,artifact:{field:`fallbackScreenshotPath`,artifactType:`screenshot`,path:n,fileName:`snapshot-fallback.png`}}}async function te(e){let{req:t,session:n}=e;try{let r=await h({device:n.device,overlayRefs:!1,inspectFacts:e.inspectFacts,bindDevice:e.bindDevice});return r.ok?(await _({session:n,sessionName:e.sessionName,captureScreenshot:r.runtime.captureScreenshot,dispatchContext:b(e.logPath,t.flags,n.appBundleId,n.trace?.outPath,t.meta?.requestId,t.meta)})).path:void 0}catch{return}}async function ne(e){return await H({...e,command:`snapshot`,execute:async({runtime:t,sessionName:n,req:r,snapshotScope:a})=>{let o=await t.capture.snapshot({session:n,interactiveOnly:r.flags?.snapshotInteractiveOnly,depth:r.flags?.snapshotDepth,scope:a,raw:r.flags?.snapshotRaw,customActions:r.flags?.snapshotCustomActions,forceFull:r.flags?.snapshotForceFull}),s=re(r,e.sessionStore.get(n)),c=d(o.nodes),l=i(o,c===o.nodes?o:{...o,nodes:c}),u=await $({req:r,session:e.sessionStore.get(n),sessionName:n,logPath:e.logPath,verdict:o.snapshotQuality,inspectFacts:e.inspectFacts,bindDevice:e.bindDevice}),f=i(l,u?{...l,fallbackScreenshotPath:u.path,artifacts:[u.artifact]}:l);return{data:s===void 0?f:i(f,{...f,refsGeneration:s}),record:{kind:`snapshot`,nodes:o.nodes.length,truncated:o.truncated}}}})}function re(e,t){return e.internal?.observationOnly===!0?void 0:t?.snapshotGeneration}export{H as n,ne as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function e(e,
|
|
1
|
+
function e(e){return e?.trim().toLowerCase()||null}function t(t,n){let r=e(n);return r?[t.label,t.value,t.identifier].some(e=>(e??``).toLowerCase().includes(r)):!1}function n(n,r,i=()=>!0){if(!e(r))return null;for(let[e,a]of n.entries()){if(!t(a,r))continue;let o=a.depth??0,s=e+1;for(;s<n.length&&(n[s]?.depth??0)>o;)s+=1;let c={start:e,end:s};if(i(c))return c}return null}function r(e,t=0){let n=new Map;for(let[t,r]of e.entries())n.set(r.index,t);return e.map((e,r)=>({...e,index:r,depth:Math.max(0,(e.depth??0)-t),parentIndex:typeof e.parentIndex==`number`?n.get(e.parentIndex):void 0}))}export{r as i,t as n,e as r,n as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as e}from"./rolldown-runtime.js";import{g as t,h as n,l as r,u as i}from"./sdk-contracts.js";import"./capture.js";import{r as a}from"./snapshot-capture-annotations.js";import{c as o,m as s,n as c,s as l}from"./android-input-ownership.js";import{Dr as u,Ir as d,Rr as f,jr as p,kr as m}from"./sdk-batch.js";import{t as h}from"./snapshot-desktop-projection.js";import{a as g}from"./ios-snapshot-planning.js";function _(e,t,n){if(n?.(e.length+t.length)===!1)return;let r=v(t);if(r.length===0)return 0;let i=1/0,a=-1/0;for(let e of r)i=Math.min(i,e.x),a=Math.max(a,e.endX);let o=v(e).filter(e=>e.x<a&&e.endX>i);if(o.length===0)return 0;let s=[...r.flatMap(e=>[e.x,e.endX]),...o.flatMap(e=>[Math.max(e.x,i),Math.min(e.endX,a)])];if(n?.(r.length+o.length+s.length)===!1)return;r.sort(y),o.sort(y);let c=[...new Set(s)].sort((e,t)=>e-t),l=[],u=[],d=0,f=0,p=0,m=0;for(let e=0;e<c.length-1;e+=1){let t=c[e],i=c[e+1];for(l=l.filter(e=>e.endX>t),u=u.filter(e=>e.endX>t);d<r.length&&r[d].x<=t;)l.push(r[d]),d+=1;for(;f<o.length&&o[f].x<=t;)u.push(o[f]),f+=1;if(n?.(1+l.length+u.length)===!1)return;let a=b(l),s=b(u),h=i-t;p+=h*x(a),m+=h*S(a,s)}return p<=0?0:m/p}function v(e){return e.filter(f).map(e=>({...e,endX:e.x+e.width}))}function y(e,t){return e.x-t.x||e.endX-t.endX}function b(e){let t=e.map(e=>({start:e.y,end:e.y+e.height})).sort((e,t)=>e.start-t.start||e.end-t.end),n=[];for(let e of t){let t=n.at(-1);!t||e.start>t.end?n.push({...e}):t.end=Math.max(t.end,e.end)}return n}function x(e){return e.reduce((e,t)=>e+t.end-t.start,0)}function S(e,t){let n=0,r=0,i=0;for(;r<e.length&&i<t.length;){let a=e[r],o=t[i];n+=Math.max(0,Math.min(a.end,o.end)-Math.max(a.start,o.start)),a.end<=o.end?r+=1:i+=1}return n}function C(e,t=new Map){if(t.size===0)return new Set;let n=D(e),r=O(e,n),i={remaining:Math.max(1024,e.length*128),exhausted:!1},a=w(n,{footprints:r,siblingOrders:t,budget:i});return i.exhausted?new Set:L(a,n)}function w(e,t){let n=new Set;for(let r of e.values())for(let e of r)if(T(e,r,t)&&n.add(e.index),t.budget.exhausted)return n;return n}function T(e,t,n){let r=n.siblingOrders.get(e.index),i=n.footprints.get(e.index);if(!r||!i)return!1;for(let e of t){if(!F(n.budget))return!1;if(E(r,i,e,n))return!0}return!1}function E(e,t,n,r){let i=r.siblingOrders.get(n.index),a=r.footprints.get(n.index);if(!i||!a?.hasAction||i.group!==e.group||i.order<=e.order)return!1;let o=P(a,`paint`,r.budget),s=P(t,`show`,r.budget);if(r.budget.exhausted)return!1;let c=_(o,s,e=>I(r.budget,e));return c!==void 0&&c>=.9}function D(e){let t=new Map;for(let n of e){if(typeof n.parentIndex!=`number`)continue;let e=t.get(n.parentIndex)??[];e.push(n),t.set(n.parentIndex,e)}return t}function O(e,t){let n=new Map;for(let r=e.length-1;r>=0;--r){let i=e[r],a=t.get(i.index)??[],o=a.flatMap(e=>n.get(e.index)??[]);n.set(i.index,k(i,a.length,o))}return n}function k(e,t,n){let r=j(e,t),i=r??M(e);return{...i?{showRect:i}:{},showChildren:r?[]:n,...r?{paintRect:r}:{},paintChildren:r?[]:n,hasAction:e.hittable===!0||n.some(A)}}function A(e){return e.hasAction}function j(e,t){if(f(e.rect))return e.hittable===!0||d(e.type)||t===0&&N(e)?e.rect:void 0}function M(e){return f(e.rect)&&N(e)?e.rect:void 0}function N(e){return!!(e.label?.trim()||e.value?.trim()||e.identifier?.trim())}function P(e,t,n){let r=[],i=[e];for(;i.length>0;){if(!F(n))return r;let e=i.pop(),a=t===`paint`?e.paintRect:e.showRect;a&&r.push(a),i.push(...t===`paint`?e.paintChildren:e.showChildren)}return r}function F(e){return I(e,1)}function I(e,t){return t>e.remaining?(e.exhausted=!0,!1):(e.remaining-=t,!0)}function L(e,t){let n=new Set,r=[...e];for(;r.length>0;){let e=r.pop();if(!n.has(e)){n.add(e);for(let n of t.get(e)??[])r.push(n.index)}}return n}function R(e){let t=new Map;for(let[n,r]of e.entries())t.set(r.index,n);let n=[],r=[];for(let[i,a]of e.entries()){let e=Math.max(0,a.depth??0);for(;r.length>0&&e<=r.at(-1).depth;)r.pop();let o=i,s=typeof a.parentIndex==`number`?t.get(a.parentIndex):void 0,c=typeof s==`number`&&s<o?s:r.at(-1)?.index;n.push({...a,index:o,depth:e,parentIndex:c}),r.push({depth:e,index:o})}return n}function z(e){let t=[],n=[];for(let r of e){let e=r.depth??0;for(;t.length>0&&e<=t.at(-1);)t.pop();let i=p(r.type??``),a=m(u(r));if((i===`group`||i===`ioscontentgroup`)&&!a){t.push(e);continue}let o=Math.max(0,e-t.length);n.push({...r,depth:o})}return n}var B=e({buildSnapshotState:()=>V});function V(e,o){let s=e?.nodes??[],c=o?.snapshotRaw,u=H(e,s,c===!0),d=R(c?u:z(u)),f=o?.snapshotScope&&G(e?.backend)?h(d,o.snapshotScope):d,p=a(e).quality;return{nodes:r(c?f:l(f,U(e?.backend))),truncated:e?.truncated,createdAt:Date.now(),...t(e),...p?{snapshotQuality:p}:{},...e.comparisonIdentity?{comparisonKey:g(e.comparisonIdentity)}:{},presentationKey:i(n(o)),comparisonSafe:K(e?.backend,o)}}function H(e,t,n){return e.backend===`android`&&!n?W(e,t):t}function U(e){return e===`android`?{isAdditionalOverlayNode:c}:{}}function W(e,t){let n=s(e),r=C(n?.nodes??t,n?.androidSiblingOrderByNodeIndex);return o(t,e=>{let t=n?.sourceIndexByNodeIndex.get(e.index)??e.index;return r.has(t)})}function G(e){return e===void 0||e===`linux-atspi`||e===`harmonyos-arkui`||e===`web`}function K(e,t){return e===`android`&&t?.snapshotInteractiveOnly!==!0&&typeof t?.snapshotDepth!=`number`&&!t?.snapshotScope}export{B as n,V as t};
|
package/dist/src/snapshot.js
CHANGED
|
@@ -1,8 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
`||e===`\r`||e===` `}function Ne(e){return e===`=`||e===`/`||e===`>`||Me(e)}function Pe(e,t){return e.get(t)??null}function Fe(e){let t={type:null,label:null,value:null,identifier:null,packageName:null,clickable:!1,focusable:!1,depth:-1,children:[]},n=[t],r=/<node\b[^>]*>|<\/node>/g,i=r.exec(e);for(;i;){let t=i[0];if(t.startsWith(`</node`)){n.length>1&&n.pop(),i=r.exec(e);continue}let a=be(t),o=n[n.length-1],s={type:a.className,label:a.text||a.desc,value:a.text,identifier:a.resourceId,packageName:a.packageName,rect:a.rect,enabled:a.enabled,focused:a.focused,visibleToUser:a.visibleToUser,drawingOrder:a.drawingOrder,clickable:a.clickable===!0,focusable:a.focusable===!0,scrollable:a.scrollable,canScrollForward:a.canScrollForward,canScrollBackward:a.canScrollBackward,windowIndex:a.windowIndex,windowType:a.windowType,windowLayer:a.windowLayer,windowActive:a.windowActive,windowFocused:a.windowFocused,windowRect:a.windowRect,depth:o.depth+1,parentIndex:void 0,children:[]};o.children.push(s),t.endsWith(`/>`)||n.push(s),i=r.exec(e)}return qe(t),tt(t),Je(t,{footprintMemo:new WeakMap}),et(t),t}function S(e){return e.clickable}function Ie(e){return e.focusable||e.focused===!0}function C(e){return S(e)||Ie(e)}function Le(e){return $e(e)||Ze(e)}function Re(e){return e.visibleToUser!==!1&&S(e)}function ze(e,t){return e.children.some(e=>e.visibleToUser!==!1&&w(e,t).hasAgentTarget)}function w(e,t){let n=t.footprintMemo.get(e);if(n!==void 0)return n;let r=T(e)?Be(e,e.rect,t):Ve(e,t);return t.footprintMemo.set(e,r),r}function Be(e,t,n){if(He(e))return{paints:[t],shows:[t],hasAgentTarget:C(e)};let r=Ve(e,n);return Le(e)&&r.shows.push(t),r}function Ve(e,t){let n={paints:[],shows:[],hasAgentTarget:C(e)};for(let r of e.children){if(r.visibleToUser===!1)continue;let e=w(r,t);n.hasAgentTarget||=e.hasAgentTarget,n.paints.push(...e.paints),n.shows.push(...e.shows)}return n}function He(e){return S(e)||e.scrollable===!0||e.children.length===0&&$e(e)}function Ue(e,t){let n=We([...e,...t],e=>[e.x,e.x+e.width]),r=We([...e,...t],e=>[e.y,e.y+e.height]),i=Ge(e,n,r),a=Ge(t,n,r),o=0,s=0;for(let e=0;e<n.length-1;e+=1){let t=n[e+1]-n[e];for(let n=0;n<r.length-1;n+=1){let c=e*(r.length-1)+n;if(!a[c])continue;let l=t*(r[n+1]-r[n]);o+=l,i[c]&&(s+=l)}}return o<=0?0:s/o}function We(e,t){return[...new Set(e.flatMap(t))].sort((e,t)=>e-t)}function Ge(e,t,n){let r=n.length-1,i=new Uint8Array((t.length-1)*r);for(let a of e){let e=t.indexOf(a.x),o=t.indexOf(a.x+a.width),s=n.indexOf(a.y),c=n.indexOf(a.y+a.height);for(let t=e;t<o;t+=1)i.fill(1,t*r+s,t*r+c)}return i}function Ke(e){return e.children.length===0&&!C(e)&&Le(e)}function qe(e){let t=0;for(let n of e.children)n.visibleToUser!==!1&&(qe(n),e.children[t]=n,t+=1);t<e.children.length&&(e.children.length=t)}function Je(e,t){for(let n of e.children)Je(n,t);if(e.children.length<2)return;let n=e.children,r=n.map(e=>Qe(e,t)).filter(e=>e!==null);r.length!==0&&(e.children=n.filter(e=>Ye(e,r,t)))}function Ye(e,t,n){return Ke(e)||!Xe(e,t,n)}function Xe(e,t,n){if(e.visibleToUser===!1||e.drawingOrder===void 0||!T(e))return!1;let r=w(e,n).shows,i=r.length>0?r:[e.rect];for(let n of t)if(!(n.node===e||n.drawingOrder<=e.drawingOrder)&&Ue(n.footprint,i)>=.9)return!0;return!1}function Ze(e){let t=e.identifier?.trim()??``;return!!(t&&!E(t))}function Qe(e,t){let{drawingOrder:n}=e;if(e.visibleToUser===!1||n===void 0||!T(e)||!Re(e)&&!ze(e,t))return null;let r=w(e,t).paints;return r.length>0?{node:e,drawingOrder:n,footprint:r}:null}function $e(e){let t=e.label?.trim()??``;return!!(t&&!E(t))}function T(e){return!!(e.rect&&e.rect.width>0&&e.rect.height>0)}function et(e){let t=[...e.children];for(;t.length>0;){let e=t.pop();t.push(...e.children),ot(e)&&(e.canScrollBackward&&(e.hiddenContentAbove=!0),e.canScrollForward&&(e.hiddenContentBelow=!0))}}function tt(e){let t=e.children.filter(rt);if(t.length<2)return;let n=t.filter(e=>it(e)&&at(e));if(n.length===0)return;let r=nt(n);e.children=e.children.filter(e=>it(e)?at(e)?r===void 0||e.windowLayer===r:!1:!0)}function nt(e){let t=e.map(e=>e.windowLayer).filter(e=>e!==void 0);return t.length>0?Math.max(...t):void 0}function rt(e){return e.windowIndex!==void 0||e.windowType!==void 0}function it(e){return e.windowType===1}function at(e){return e.windowActive===!0||e.windowFocused===!0}function ot(e){if(!e.scrollable||!s(e.type)||`${e.type??``}`.toLowerCase().includes(`horizontalscrollview`))return!1;let t=st(e);return!(t&&t.horizontal>t.vertical&&t.horizontal>16)}function st(e){if(!e.rect||e.children.length===0)return null;let t=e.children.map(e=>e.rect).filter(e=>e!==void 0);if(t.length===0)return null;let n=Math.min(...t.map(e=>e.x)),r=Math.max(...t.map(e=>e.x+e.width)),i=Math.min(...t.map(e=>e.y)),a=Math.max(...t.map(e=>e.y+e.height));return{horizontal:Math.max(0,r-n-e.rect.width),vertical:Math.max(0,a-i-e.rect.height)}}function ct(e,t,n,r,i){if(e.visibleToUser===!1)return!1;let a=lt(e);return t.interactiveOnly?ut(e,a,n,r,i):a.isStructural||a.isVisual?pt(e,a,r):!0}function lt(e){let t=ht(e.type),n=!!(e.label&&e.label.trim().length>0),r=!!(e.identifier&&e.identifier.trim().length>0);return{type:t,hasMeaningfulText:n&&!E(e.label??``),hasMeaningfulId:r&&!E(e.identifier??``),isStructural:gt(t),isVisual:t===`imageview`||t===`imagebutton`}}function ut(e,t,n,r,i){return ft(e)?!1:C(e)||s(t.type)&&r?!0:dt(t,n,r,i)}function dt(e,t,n,r){return!e.hasMeaningfulText&&!e.hasMeaningfulId||e.isVisual||e.isStructural&&!r&&!t?!1:t||n||r}function ft(e){return!!(e.rect&&(e.rect.width<=0||e.rect.height<=0))}function pt(e,t,n){return C(e)||t.hasMeaningfulText||t.hasMeaningfulId?!0:n}function mt(e){if(!e)return!1;let t=ht(e);return t.includes(`recyclerview`)||t.includes(`listview`)||t.includes(`gridview`)}function ht(e){return e?e.toLowerCase():``}function gt(e){let t=e.split(`.`).pop()??e;return t.includes(`layout`)||t===`viewgroup`||t===`view`}function E(e){let t=e.trim();return t?/^[\w.]+:id\/[\w.-]+$/i.test(t):!1}function _t(e){let t=0,n=0,r=[...e.children];for(;r.length>0;){let e=r.pop();t+=1,n=Math.max(n,e.depth),r.push(...e.children)}return{rawNodeCount:t,maxDepth:n}}const D=`android-snapshot-helper-v1`,O=`uiautomator-xml`,vt={"-r":`replace`,"-t":`allowTestPackages`,"-d":`allowDowngrade`,"-g":`grantPermissions`};function yt(e){if(!e||typeof e!=`object`||Array.isArray(e))throw new n(`INVALID_ARGS`,`Android snapshot helper manifest must be an object.`);let t=e;return{name:A(t.name,`name`,`android-snapshot-helper`),version:j(t.version,`version`),releaseTag:M(t.releaseTag),assetName:M(t.assetName),apkUrl:wt(t.apkUrl,`apkUrl`),sha256:Ct(t.sha256),checksumName:M(t.checksumName),packageName:j(t.packageName,`packageName`),versionCode:k(t.versionCode,`versionCode`),instrumentationRunner:j(t.instrumentationRunner,`instrumentationRunner`),minSdk:k(t.minSdk,`minSdk`),targetSdk:t.targetSdk===void 0?void 0:k(t.targetSdk,`targetSdk`),outputFormat:A(t.outputFormat,`outputFormat`,O),statusProtocol:A(t.statusProtocol,`statusProtocol`,D),installArgs:xt(t.installArgs)}}function k(e,t){return ue(e,t,`snapshot helper`)}function A(e,t,n){return de(e,t,n,`snapshot helper`)}function bt(e){return St(xt(e.installArgs))}function xt(e){let t=Tt(e,`installArgs`);if(t[0]!==`install`)throw new n(`INVALID_ARGS`,`Android snapshot helper manifest installArgs must start with "install".`);if(t.some(e=>e.includes(`\0`)))throw new n(`INVALID_ARGS`,`Android snapshot helper manifest installArgs must not contain null bytes.`);let r=t.slice(1).find(e=>!Et(e));if(r)throw new n(`INVALID_ARGS`,`Android snapshot helper manifest installArgs contains unsupported install flag "${r}".`);return t}function St(e){let t={};for(let r of e.slice(1)){let e=Dt(r);if(!e)throw new n(`INVALID_ARGS`,`Android snapshot helper manifest installArgs contains unsupported install flag "${r}".`);t[e]=!0}return t}function Ct(e){let t=j(e,`sha256`).trim().toLowerCase();if(t.length!==64||!Ot(t))throw new n(`INVALID_ARGS`,`Android snapshot helper manifest sha256 must be a 64-character hex string.`);return t}function j(e,t){if(typeof e!=`string`||e.trim().length===0)throw new n(`INVALID_ARGS`,`Android snapshot helper manifest ${t} is required.`);return e}function M(e){return typeof e==`string`&&e.trim().length>0?e:void 0}function wt(e,t){return e===null?null:j(e,t)}function Tt(e,t){if(!Array.isArray(e)||!e.every(e=>typeof e==`string`))throw new n(`INVALID_ARGS`,`Android snapshot helper manifest ${t} must be a string array.`);return e}function Et(e){return Dt(e)!==void 0}function Dt(e){if(Object.hasOwn(vt,e))return vt[e]}function Ot(e){for(let t of e){let e=t.charCodeAt(0);if(!(e>=48&&e<=57)&&!(e>=97&&e<=102))return!1}return!0}const kt=2e3,At=`android_snapshot_helper_retirement_unconfirmed`,N=new Map;function P(e){return`${e.platform}:${e.id}`}async function jt(e){await Lt({adb:e.adb,packageName:e.packageName,timeoutMs:2e3})||I(e)}async function F(e){let t=N.get(e.deviceKey);if(t){try{let n=await e.adb([`shell`,`am`,`force-stop`,t.packageName],{allowFailure:!0,timeoutMs:5e3,signal:e.signal});if(e.signal?.throwIfAborted(),n.exitCode===0){N.delete(e.deviceKey);return}}catch{e.signal?.throwIfAborted()}I({deviceKey:e.deviceKey,packageName:t.packageName,cause:t.cause})}}function I(e){let t=e.cause instanceof Error?e.cause.message:String(e.cause);throw N.set(e.deviceKey,{packageName:e.packageName,cause:t}),new n(`COMMAND_FAILED`,`Android snapshot helper could not confirm release of device automation ownership`,{reason:At,deviceKey:e.deviceKey,cause:t,hint:`Retry after the helper process exits, or restart the device if Android still reports automation as busy.`})}function Mt(e){return e instanceof n&&e.details?.reason===At}async function Nt(e){let t=AbortSignal.timeout(e.timeoutMs),[n]=await Promise.allSettled([Lt({adb:e.adb,packageName:e.packageName,timeoutMs:e.timeoutMs,signal:t}),Rt({...e,signal:t})]);return{timedOut:t.aborted,runtimeForceStopped:n?.status===`fulfilled`?n.value:!1}}function Pt(e){return e.exitCode!=null||e.signalCode!=null?Promise.resolve():new Promise(t=>{e.once(`close`,()=>t()),e.once(`exit`,()=>t())})}async function L(e,t,n){let r,i,a=await Promise.race([e.then(()=>!0),new Promise(e=>{r=setTimeout(()=>e(!1),t)}),...n?[new Promise(e=>{i=()=>e(!1),n.addEventListener(`abort`,i,{once:!0}),n.aborted&&i()})]:[]]);return r&&clearTimeout(r),i&&n?.removeEventListener(`abort`,i),a}async function Ft(e){if(e.alreadyExited)return!0;try{e.process.kill(`SIGTERM`)}catch{}return await L(e.processExit,e.timeoutMs)}function It(){N.clear()}async function Lt(e){let t=e.signal??AbortSignal.timeout(e.timeoutMs);try{return(await e.adb([`shell`,`am`,`force-stop`,e.packageName],{allowFailure:!0,timeoutMs:e.timeoutMs,signal:t})).exitCode===0}catch{return!1}}async function Rt(e){e.process.stdin?.end(),e.process.stdout?.destroy(),e.process.stderr?.destroy(),await e.adb([`forward`,`--remove`,`tcp:${e.port}`],{allowFailure:!0,timeoutMs:e.timeoutMs,signal:e.signal})}async function zt(e){let t=R(e),r=e.deviceKey??`android:default`;await F({deviceKey:r,adb:e.adb,signal:e.signal});let i;try{i=await e.adb(Bt(t),{allowFailure:!0,timeoutMs:t.commandTimeoutMs,signal:e.signal})}catch(n){throw e.signal?.aborted?(await jt({deviceKey:r,packageName:t.packageName,adb:e.adb,cause:n}),e.signal.throwIfAborted(),n):n}e.signal?.aborted&&(await jt({deviceKey:r,packageName:t.packageName,adb:e.adb,cause:e.signal.reason}),e.signal.throwIfAborted());let{output:a,cleanupDone:o}=await Vt(e,t,i);if(t.outputPath&&!o&&await Jt(e.adb,t.outputPath),i.exitCode!==0)throw new n(`COMMAND_FAILED`,`Android snapshot helper failed`,ee(i,{helper:a.metadata}));return a}function R(e){let t=z(e.timeoutMs,8e3),n=z(e.packageName,`com.callstack.agentdevice.snapshothelper`);return{waitForIdleTimeoutMs:z(e.waitForIdleTimeoutMs,500),waitForIdleQuietMs:z(e.waitForIdleQuietMs,100),timeoutMs:t,commandTimeoutMs:z(e.commandTimeoutMs,t+5e3),maxDepth:z(e.maxDepth,128),maxNodes:z(e.maxNodes,5e3),packageName:n,runner:z(e.instrumentationRunner,`${n}/.SnapshotInstrumentation`),...e.outputPath?{outputPath:e.outputPath}:{},...e.emitChunks===void 0?{}:{emitChunks:e.emitChunks}}}function z(e,t){return e===void 0?t:e}function Bt(e){return[`shell`,`am`,`instrument`,`-w`,`-e`,`waitForIdleTimeoutMs`,String(e.waitForIdleTimeoutMs),`-e`,`waitForIdleQuietMs`,String(e.waitForIdleQuietMs),`-e`,`timeoutMs`,String(e.timeoutMs),`-e`,`maxDepth`,String(e.maxDepth),`-e`,`maxNodes`,String(e.maxNodes),...e.outputPath?[`-e`,`outputPath`,e.outputPath]:[],...e.emitChunks===void 0?[]:[`-e`,`emitChunks`,String(e.emitChunks)],e.runner]}async function Vt(e,t,n){try{return{output:Yt(`${n.stdout}\n${n.stderr}`),cleanupDone:!1}}catch(r){return await Ht(e,t,n,r)}}async function Ht(e,t,r,i){if(i instanceof n&&r.exitCode!==0&&i.details?.helper)throw i;let a=await Ut(e,t,r);if(a)return{output:a,cleanupDone:!0};throw new n(`COMMAND_FAILED`,r.exitCode===0?`Android snapshot helper output could not be parsed`:`Android snapshot helper failed before returning parseable output`,{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode},i)}async function Ut(e,t,n){if(!(n.exitCode!==0||!t.outputPath))return await Gt(e.adb,t.outputPath,qt(`${n.stdout}\n${n.stderr}`)??Wt(t))}function Wt(e){return{outputFormat:O,waitForIdleTimeoutMs:e.waitForIdleTimeoutMs,waitForIdleQuietMs:e.waitForIdleQuietMs,timeoutMs:e.timeoutMs,maxDepth:e.maxDepth,maxNodes:e.maxNodes,transport:`instrumentation`}}async function Gt(e,t,n){let r;try{r=await e(Kt(t),{allowFailure:!0,timeoutMs:5e3})}catch{return}if(r.exitCode!==0)return;let i=r.stdout.trim();if(!(!i.includes(`<hierarchy`)||!i.includes(`</hierarchy>`)))return{xml:i,metadata:n}}function Kt(e){return[`shell`,`sh`,`-c`,`cat "$1"; status=$?; rm -f "$1"; exit "$status"`,`agent-device-snapshot-helper-output`,e]}function qt(e){try{return rn(Zt(ce(e).results))}catch{return null}}async function Jt(e,t){try{await e([`shell`,`rm`,`-f`,t],{allowFailure:!0,timeoutMs:5e3})}catch{}}function Yt(e){let t=ce(e),n=Zt(t.results);return{xml:$t(Xt(t.status),n),metadata:{...rn(n),transport:`instrumentation`}}}function Xt(e){let t=[];for(let n of e){if(n.agentDeviceProtocol!==`android-snapshot-helper-v1`||n.outputFormat!==`uiautomator-xml`)continue;let{payloadBase64:e}=n;e!==void 0&&t.push({index:B(n.chunkIndex),count:B(n.chunkCount),payloadBase64:e})}return t}function Zt(e){let t=e.find(e=>e.agentDeviceProtocol===D);if(!t)throw new n(`COMMAND_FAILED`,`Android snapshot helper did not return a final result`);if(t.ok!==`true`)throw new n(`COMMAND_FAILED`,Qt(t),{errorType:t.errorType,helper:t});return t}function Qt(e){return e.message&&e.message!==`null`?e.message:e.errorType||`Android snapshot helper returned an error`}function $t(e,t){if(e.length===0)throw new n(`COMMAND_FAILED`,`Android snapshot helper did not return XML chunks`,{helper:t});let r=en(e),i=Buffer.concat(nn(tn(e,r),r)).toString(`utf8`);if(!i.includes(`<hierarchy`)||!i.includes(`</hierarchy>`))throw new n(`COMMAND_FAILED`,`Android snapshot helper output did not contain XML`,{xml:i});return i}function en(e){let t=e[0]?.count??e.length;if(t<1||e.length!==t||e.some(e=>e.count!==t))throw new n(`COMMAND_FAILED`,`Android snapshot helper returned incomplete XML chunks`,{expectedChunks:t,actualChunks:e.length});return t}function tn(e,t){let r=new Map;for(let i of e){if(i.index===void 0||i.index<0||i.index>=t)throw new n(`COMMAND_FAILED`,`Android snapshot helper returned invalid chunk index`,{chunkIndex:i.index,expectedChunks:t});if(r.has(i.index))throw new n(`COMMAND_FAILED`,`Android snapshot helper returned duplicate XML chunks`,{chunkIndex:i.index});r.set(i.index,i.payloadBase64)}return r}function nn(e,t){let r=[];for(let i=0;i<t;i+=1){let a=e.get(i);if(a===void 0)throw new n(`COMMAND_FAILED`,`Android snapshot helper returned incomplete XML chunks`,{missingChunkIndex:i,expectedChunks:t});r.push(Buffer.from(a,`base64`))}return r}function rn(e){return{helperApiVersion:e.helperApiVersion,outputFormat:O,waitForIdleTimeoutMs:B(e.waitForIdleTimeoutMs),waitForIdleQuietMs:B(e.waitForIdleQuietMs),timeoutMs:B(e.timeoutMs),maxDepth:B(e.maxDepth),maxNodes:B(e.maxNodes),rootPresent:on(e.rootPresent),captureMode:an(e.captureMode),windowCount:B(e.windowCount),nodeCount:B(e.nodeCount),truncated:on(e.truncated),elapsedMs:B(e.elapsedMs)}}function an(e){return e===`interactive-windows`||e===`active-window`?e:void 0}const B=g,on=_;function sn(){return new Promise((e,t)=>{let n=pe.createServer();n.unref(),n.on(`error`,t),n.listen(0,`127.0.0.1`,()=>{let r=n.address();if(!r||typeof r==`string`){n.close(()=>t(Error(`Failed to allocate a local TCP port`)));return}let i=r.port;n.close(()=>e(i))})})}function V(e,t,r,i){return new Promise((a,o)=>{let s=pe.connect({host:`127.0.0.1`,port:e}),c=[],l=setTimeout(()=>{u(),s.destroy(),o(new n(`COMMAND_FAILED`,`Android snapshot helper session request timed out`,{command:t,timeoutMs:r,port:e}))},r),u=()=>{clearTimeout(l),i?.removeEventListener(`abort`,d)},d=()=>{u(),s.destroy(),o(i?.reason??new DOMException(`The operation was aborted`,`AbortError`))};if(i?.addEventListener(`abort`,d,{once:!0}),i?.aborted){d();return}s.on(`connect`,()=>s.write(`${t}\n`)),s.on(`data`,e=>c.push(Buffer.from(e))),s.on(`error`,e=>{u(),o(e)}),s.on(`close`,()=>{u(),a(Buffer.concat(c).toString(`utf8`))})})}async function cn(e){let t=`snapshot-${Date.now()}-${Math.random().toString(16).slice(2)}`;return mn(await V(e.port,`snapshot ${t}`,ln(e),e.signal),t)}function ln(e){return Math.min(e.commandTimeoutMs,Math.max(e.timeoutMs+3e3,3e3))}function un(e,t,r){return new Promise((i,a)=>{let o=``,s=setTimeout(()=>{r?.removeEventListener(`abort`,l),a(new n(`COMMAND_FAILED`,`Android snapshot helper session did not become ready`,{output:o,timeoutMs:t}))},t),c=e=>{o+=e.toString(),o.includes(`agentDeviceProtocol=android-snapshot-helper-v1`)&&o.includes(`sessionReady=true`)&&(clearTimeout(s),r?.removeEventListener(`abort`,l),i())},l=()=>{clearTimeout(s),a(r?.reason??new DOMException(`The operation was aborted`,`AbortError`))};if(r?.addEventListener(`abort`,l,{once:!0}),r?.aborted){l();return}e.stdout?.on(`data`,c),e.stderr?.on(`data`,c),e.once(`exit`,(e,t)=>{clearTimeout(s),r?.removeEventListener(`abort`,l),a(new n(`COMMAND_FAILED`,`Android snapshot helper session exited before ready`,{output:o,exitCode:e,signal:t}))}),e.on(`error`,e=>{clearTimeout(s),r?.removeEventListener(`abort`,l),a(e)})})}function dn(e){let t=e.indexOf(`
|
|
3
|
-
|
|
4
|
-
`);return _n(e.slice(0,t<0?e.length:t))}function fn(e,t){if(e.agentDeviceProtocol!==`android-snapshot-helper-v1`)throw new n(`COMMAND_FAILED`,`Android automation helper session returned wrong protocol`,{headers:e});if(e.requestId!==t)throw new n(`COMMAND_FAILED`,`Android automation helper session returned stale output`,{headers:e,requestId:t})}function pn(e,t){let n=dn(e);return n.agentDeviceProtocol===`android-snapshot-helper-v1`&&n.requestId===t&&n.ok===`true`}function mn(e,t){let r=e.indexOf(`
|
|
5
|
-
|
|
6
|
-
`);if(r<0)throw new n(`COMMAND_FAILED`,`Android snapshot helper session returned malformed output`,{response:e});let i=_n(e.slice(0,r)),a=e.slice(r+2);return hn(i,t),gn(i,a),{xml:a,metadata:vn(i)}}function hn(e,t){if(e.agentDeviceProtocol!==`android-snapshot-helper-v1`)throw new n(`COMMAND_FAILED`,`Android snapshot helper session returned wrong protocol`,{headers:e});if(e.outputFormat!==`uiautomator-xml`)throw new n(`COMMAND_FAILED`,`Android snapshot helper session returned wrong output format`,{headers:e});if(e.requestId!==t)throw new n(`COMMAND_FAILED`,`Android snapshot helper session returned stale output`,{headers:e,requestId:t});if(e.ok!==`true`)throw new n(`COMMAND_FAILED`,e.message||e.errorType||`Android snapshot helper session returned an error`,{helper:e})}function gn(e,t){let r=g(e.byteLength);if(r!==void 0&&Buffer.byteLength(t,`utf8`)!==r)throw new n(`COMMAND_FAILED`,`Android snapshot helper session returned truncated XML`,{headers:e,actualByteLength:Buffer.byteLength(t,`utf8`)});if(!t.includes(`<hierarchy`)||!t.includes(`</hierarchy>`))throw new n(`COMMAND_FAILED`,`Android snapshot helper session did not return XML`,{headers:e,xml:t})}function _n(e){let t={};for(let n of e.split(/\r?\n/)){let e=n.indexOf(`=`);e<0||(t[n.slice(0,e)]=n.slice(e+1))}return t}function vn(e){return{helperApiVersion:e.helperApiVersion,outputFormat:O,waitForIdleTimeoutMs:g(e.waitForIdleTimeoutMs),waitForIdleQuietMs:g(e.waitForIdleQuietMs),timeoutMs:g(e.timeoutMs),maxDepth:g(e.maxDepth),maxNodes:g(e.maxNodes),rootPresent:_(e.rootPresent),captureMode:e.captureMode===`interactive-windows`||e.captureMode===`active-window`?e.captureMode:void 0,windowCount:g(e.windowCount),nodeCount:g(e.nodeCount),truncated:_(e.truncated),elapsedMs:g(e.elapsedMs)}}const yn=5e3,H=new Map,U=new Map;async function bn(e){let t=e.deviceKey??`android:default`;if(await F({deviceKey:t,adb:e.adb,signal:e.signal}),!Mn()||!e.adbProvider?.spawn)return;let n=Cn(R(e)),r=await xn({deviceKey:t,identity:jn(t,n,e),options:e,resolved:n});if(r)return await Sn({session:r,deviceKey:t,options:e,resolved:n})}async function xn(e){let{deviceKey:t,identity:n,options:r,resolved:i}=e;if(U.get(t)===n)return;let a=H.get(t);if(a&&a.identity!==n&&(await G(t),a=void 0),!a)try{a=await An({deviceKey:t,identity:n,options:r,resolved:i})}catch(e){if(r.signal?.throwIfAborted(),U.set(t,n),p({level:`warn`,phase:`android_snapshot_helper_session_disabled`,data:{deviceKey:t,reason:e instanceof Error?e.message:String(e)}}),Mt(e))throw e;return}return a}async function Sn(e){let{session:t,deviceKey:n,options:r,resolved:i}=e;try{let e=t.capturedCount>0,n=await cn({port:t.port,timeoutMs:i.timeoutMs,commandTimeoutMs:i.commandTimeoutMs,signal:r.signal});return t.capturedCount+=1,{xml:n.xml,metadata:{...n.metadata,transport:`persistent-session`,sessionReused:e}}}catch(e){await G(n,{force:!0,signal:r.signal,cause:e}),r.signal?.throwIfAborted(),p({level:`warn`,phase:`android_snapshot_helper_session_fallback`,data:{deviceKey:n,reason:e instanceof Error?e.message:String(e),uiAutomationConnectionTimeout:wn(e)}});return}}function Cn(e){let t=Math.min(e.timeoutMs,2e3);return{...e,timeoutMs:t,commandTimeoutMs:Math.min(e.commandTimeoutMs,t+3e3)}}function wn(e){if(!(e instanceof n))return!1;let t=e.details?.helper;return!t||typeof t!=`object`?!1:t.errorType===`java.util.concurrent.TimeoutException`}async function Tn(e){let t=H.get(e.deviceKey);if(!t)return;if(!En(t.helper,e.helper)){p({level:`warn`,phase:`android_snapshot_helper_session_touch_identity_mismatch`,data:{deviceKey:e.deviceKey,sessionHelper:t.helper,requestedHelper:e.helper}}),await G(e.deviceKey);return}let r=`${e.action}-${Date.now()}-${Math.random().toString(16).slice(2)}`,i=e.payloadBase64?`${e.action} ${r} ${e.payloadBase64}`:`${e.action} ${r}`,a;try{a=dn(await V(t.port,i,e.timeoutMs)),fn(a,r)}catch(t){throw await G(e.deviceKey),t}if(a.ok!==`true`)throw new n(`COMMAND_FAILED`,a.message||a.errorType||`Android automation helper ${e.action} failed`,{errorType:a.errorType,helper:a});return a}function En(e,t){return e.packageName===t.packageName&&e.runner===t.runner&&W(e.helperVersion,t.helperVersion)&&W(e.helperVersionCode,t.helperVersionCode)&&W(e.sha256,t.sha256)}function W(e,t){return e===void 0||t===void 0||e===t}async function G(e,t={}){let n=H.get(e);if(!n)return!1;H.delete(e);let r=Pt(n.process),i=t.force===!0||t.signal?.aborted===!0,a=await Dn(n,r,i,t.signal),o=i?t.signal?.aborted===!0?250:kt:yn,s=i?250:2e3,[c,l]=await Promise.all([Ft({process:n.process,processExit:r,alreadyExited:a.exited,timeoutMs:s}),Nt({adb:n.adb,process:n.process,port:n.port,packageName:n.helper.packageName,timeoutMs:o})]);return p({phase:`android_snapshot_helper_session_stop`,data:{deviceKey:e,port:n.port,capturedCount:n.capturedCount,lifetimeMs:Date.now()-n.startedAtMs,quitAcknowledged:a.acknowledged,forceKilled:!a.exited&&c,forced:i||t.signal?.aborted===!0,runtimeForceStopped:l.runtimeForceStopped,externalCleanupTimedOut:l.timedOut}}),!a.exited&&!l.runtimeForceStopped&&I({deviceKey:e,packageName:n.helper.packageName,cause:t.cause}),!0}async function Dn(e,t,n,r){if(n)return{acknowledged:!1,exited:!1};let i=`quit-${Date.now()}`;try{let n=pn(await V(e.port,`quit ${i}`,1e3,r),i);return{acknowledged:n,exited:n&&await L(t,11e3,r)}}catch{return{acknowledged:!1,exited:!1}}}async function On(e){await G(P(e))}async function kn(){let e=await Promise.allSettled([...H.keys()].map(e=>G(e)));U.clear();let t=e.filter(e=>e.status===`rejected`).map(e=>e.reason);if(t.length>0)throw AggregateError(t,`Failed to retire every Android snapshot helper session`);It()}async function An(e){let t=await sn();await e.options.adb([`forward`,`tcp:${t}`,`tcp:${t}`],{allowFailure:!1,timeoutMs:yn,signal:e.options.signal});let r=Bt({...e.resolved,outputPath:void 0,emitChunks:!1}),i=r[r.length-1];if(!i)throw new n(`INVALID_ARGS`,`Android snapshot helper runner was not resolved`);let a=[...r.slice(0,-1),`-e`,`sessionPort`,String(t),i],o=e.options.adbProvider.spawn(a,{allowFailure:!0,captureOutput:!1}),s={identity:e.identity,deviceKey:e.deviceKey,helper:{packageName:e.resolved.packageName,runner:e.resolved.runner,helperVersion:e.options.helperVersion,helperVersionCode:e.options.helperVersionCode,sha256:e.options.helperSha256},port:t,adb:e.options.adb,process:o,startedAtMs:Date.now(),capturedCount:0};try{return await un(o,1e4,e.options.signal),H.set(e.deviceKey,s),p({phase:`android_snapshot_helper_session_ready`,data:{deviceKey:e.deviceKey,port:t,packageName:e.resolved.packageName,runner:e.resolved.runner}}),s}catch(t){let n=Pt(o);try{o.kill(`SIGTERM`)}catch{}let[,r]=await Promise.all([L(n,250),Nt({adb:s.adb,process:s.process,port:s.port,packageName:s.helper.packageName,timeoutMs:kt})]);throw r.runtimeForceStopped||I({deviceKey:e.deviceKey,packageName:s.helper.packageName,cause:t}),t}}function jn(e,t,n){return JSON.stringify({deviceKey:e,packageName:t.packageName,runner:t.runner,helperVersion:n.helperVersion,helperVersionCode:n.helperVersionCode,helperSha256:n.helperSha256,waitForIdleTimeoutMs:t.waitForIdleTimeoutMs,waitForIdleQuietMs:t.waitForIdleQuietMs,timeoutMs:t.timeoutMs,maxDepth:t.maxDepth,maxNodes:t.maxNodes})}function Mn(){let e=process.env.AGENT_DEVICE_ANDROID_SNAPSHOT_HELPER_SESSION;return e===void 0||!/^(0|false|no|off)$/i.test(e)}const K=new Map;function Nn(e){let t=`${e.deviceKey}\0${e.packageName}\0${e.versionCode}\0`;for(let e of K.keys())e.startsWith(t)&&q(e)}function Pn(e,t,n,r){return e?`${e}\0${t}\0${n}\0${r}`:void 0}function Fn(e,t){if(!e)return;let[n,r]=e.split(`\0`),i=`${n}\0${r}\0`;for(let t of K.keys())t!==e&&t.startsWith(i)&&K.delete(t);K.set(e,t)}function q(e){e&&K.delete(e)}async function In(e){let{adb:t,artifact:n}=e,r=e.installPolicy??`missing-or-outdated`,i=n.manifest.packageName,a=n.manifest.versionCode,o=n.manifest.sha256;if(r===`never`)return{packageName:i,versionCode:a,installed:!1,reason:`skipped`};let s=Pn(e.deviceKey,i,a,o),c=s?K.get(s):void 0;if(s&&r!==`always`&&c!==void 0)return{packageName:i,versionCode:a,installedVersionCode:c,installedSha256:o,installed:!1,reason:`current`};await le(n.apkPath,o,`Android snapshot helper`);let l=r===`always`?{installedVersionCode:await zn(t,i,e.timeoutMs,e.signal),reason:`forced`}:await fe({adb:t,adbProvider:Rn(e.adbProvider,t),packageName:i,versionCode:a,sha256:o,signal:e.signal}),{installedVersionCode:u}=l,d=`installedSha256`in l?l.installedSha256:void 0,f=l.reason;if(f===`current`){if(u===void 0)throw Error(`Expected installed versionCode for current Android snapshot helper`);return Fn(s,u),{packageName:i,versionCode:a,installedVersionCode:u,installedSha256:d,installed:!1,reason:f}}let p;try{p=await Bn(t,e.adbProvider??t,n.apkPath,bt(n.manifest),{packageName:i,timeoutMs:e.timeoutMs,signal:e.signal})}catch(e){throw q(s),Ln(e,{packageName:i,versionCode:a})}if(p.exitCode!==0)throw q(s),Ln(ne(`Failed to install Android snapshot helper`,p,{packageName:i,versionCode:a}));return Fn(s,a),{packageName:i,versionCode:a,installedVersionCode:u,installedSha256:d,installed:!0,reason:f}}function Ln(e,t){let n=a(e,`COMMAND_FAILED`);return n.details={...t,...n.details,androidSnapshotHelperInstallFailure:!0},n}function Rn(e,t){return e?typeof e==`function`?{exec:e}:e:{exec:t}}async function zn(e,t,n,r){let i=await e([`shell`,`cmd`,`package`,`list`,`packages`,`--show-versioncode`,t],{allowFailure:!0,timeoutMs:n,signal:r});if(i.exitCode===0)return Vn(`${i.stdout}\n${i.stderr}`,t)}async function Bn(e,t,n,r,i){let a=async()=>await te(n,{allowFailure:!0,provider:t,...r,timeoutMs:i.timeoutMs,signal:i.signal}),o=await a();if(o.exitCode===0||!Hn(o))return o;let s=await e([`uninstall`,i.packageName],{allowFailure:!0,timeoutMs:i.timeoutMs,signal:i.signal}),c=await a();return c.exitCode===0?c:{...c,stderr:[c.stderr,s.stderr?`Previous uninstall stderr after INSTALL_FAILED_UPDATE_INCOMPATIBLE: ${s.stderr}`:``].filter(Boolean).join(`
|
|
7
|
-
`)}}function Vn(e,t){let n=`package:${t}`;for(let t of e.split(/\r?\n/)){if(!t.startsWith(n)||t.length>n.length&&!/\s/.test(t[n.length]??``))continue;let e=/(?:^|\s)versionCode:(\d+)(?:\s|$)/.exec(t);if(e)return Number(e[1])}}function Hn(e){return`${e.stdout}\n${e.stderr}`.includes(`INSTALL_FAILED_UPDATE_INCOMPATIBLE`)}const Un=new Set([`com.android.permissioncontroller`,`com.google.android.permissioncontroller`,`com.google.android.packageinstaller`,`com.android.packageinstaller`]);function Wn(e){return Un.has(e)}const Gn=new Set([`android`,`com.android.systemui`]),Kn=/^android:id\/(?:alertTitle|message|button[123]|parentPanel|buttonPanel|contentPanel)$/i,J=/^android:id\/button[123]$/i,qn=/(?:^|:)id\/permission_/i,Jn=/\b(?:is(?:n't| not) responding|keeps stopping|has stopped|close app|app info)\b/i,Yn=/^(?:ok|allow|allow all|while using the app|only this time|yes|continue|save|confirm|turn on|open settings)$/i,Xn=/^(?:cancel|deny|don.t allow|don’t allow|not now|no|dismiss|close|close app|later|skip)$/i;function Zn(e){if(e!==null){if(J.test(e))return`button`;if(Kn.test(e))return`content`}}function Qn(e){let t=er(e),n=t.nodes;if(n.length===0)return null;let r=ar(n),i=n.filter(e=>Y(e)&&!hr(e)),a=cr(i),o=lr(i,a),s=gr(n);return{alert:{...a?{title:a}:{},...o?{message:o}:{},buttons:r.map(e=>e.label),platform:`android`,source:t.source,...s?{packageName:s}:{}},buttons:r}}function $n(e,t){let n=t===`accept`?`accept`:`dismiss`;return e.find(e=>e.role===n)||(t===`dismiss`?e.find(e=>e.role===`neutral`)??null:e.length===1?e[0]??null:null)}function er(e){let t=e.filter(e=>pr(e));if(t.length)return{nodes:t,source:`permission`};let n=ir(e);return n.length?{nodes:n,source:`system-dialog`}:{nodes:tr(e),source:`native-dialog`}}function tr(e){let t=e.filter(e=>nr(e.type??``)),n=e.filter(e=>Kn.test(e.identifier??``)),r=t.length?[...t,...n]:rr(n);if(r.length===0)return[];let i=ur(e,r);return i===void 0?r:fr(e,i)}function nr(e){return/(?:^|[.$])[^.]*Dialog$/i.test(e)}function rr(e){let t=e.some(e=>J.test(e.identifier??``)),n=e.some(e=>!J.test(e.identifier??``));return t&&n?e:[]}function ir(e){let t=e.filter(e=>mr(e));if(t.length===0)return[];let n=ur(e,t);return n===void 0?t:fr(e,n).filter(e=>e.bundleId&&Gn.has(e.bundleId))}function ar(e){let t=new Set,n=[];for(let r of e){let e=Y(r);if(!e||!r.rect||!hr(r))continue;let a=e.trim().toLowerCase();if(!a||t.has(a))continue;t.add(a);let o=i(r.rect);n.push({label:e,x:o.x,y:o.y,role:or(r,e)})}return n}function or(e,t){return sr(e.identifier??``)||(Yn.test(t.trim())?`accept`:Xn.test(t.trim())?`dismiss`:`neutral`)}function sr(e){return/(?:^|:)id\/button1$/i.test(e)?`accept`:/(?:^|:)id\/button2$/i.test(e)?`dismiss`:/(?:^|:)id\/button3$/i.test(e)?`neutral`:/(?:^|:)id\/permission_allow/i.test(e)?`accept`:/(?:^|:)id\/permission_deny/i.test(e)?`dismiss`:null}function cr(e){return Y(e.find(e=>/(?:^|:)id\/(?:alertTitle|permission_message)$/i.test(e.identifier??``)))||Y(e[0])}function lr(e,t){let n=e.map(e=>Y(e)).filter(e=>e&&e!==t);return n.length?[...new Set(n)].join(`
|
|
8
|
-
`):void 0}function ur(e,t){let n=t[0];if(!n)return;let r=dr(e,n.index);for(let n of t.slice(1)){let t=new Set(dr(e,n.index));for(let e=r.length-1;e>=0;--e)t.has(r[e])||r.splice(e,1)}return r[r.length-1]}function dr(e,t){let n=new Map(e.map(e=>[e.index,e])),r=[],i=n.get(t);for(;i;)r.push(i.index),i=i.parentIndex===void 0?void 0:n.get(i.parentIndex);return r.reverse()}function fr(e,t){let n=new Map;for(let t of e){if(t.parentIndex===void 0)continue;let e=n.get(t.parentIndex)??[];e.push(t),n.set(t.parentIndex,e)}let r=new Set([t]),i=[t];for(let e of i)for(let t of n.get(e)??[])r.has(t.index)||(r.add(t.index),i.push(t.index));return e.filter(e=>r.has(e.index))}function pr(e){let t=e.bundleId??``;return Un.has(t)||qn.test(e.identifier??``)}function mr(e){let t=e.bundleId??``;return Gn.has(t)&&Jn.test(Y(e))}function hr(e){let t=e.type??``,n=e.identifier??``;return!!(e.hittable||/\bbutton\b/i.test(t)||J.test(n)||/(?:^|:)id\/permission_(?:allow|deny)/i.test(n))}function Y(e){return e?[e.label,e.value].filter(e=>typeof e==`string`&&e.trim().length>0)[0]?.trim()??``:``}function gr(e){return e.find(e=>e.bundleId)?.bundleId}const _r=new Set([`android`,`com.android.systemui`]);function vr(e,t,n={}){if(t.backend!==`android-helper`)return{outcome:`ok`};let r=Or(e,n.foregroundAppPackage);return br(r,t)?X(r,t,`empty-helper-output`,`Android snapshot helper returned no accessibility nodes`):Er(r)?{outcome:`ok`}:yr(r)?{outcome:`system-surface-only`}:xr(r)?{outcome:`ok`}:Sr(r)?X(r,t,`content-poor-app-window`,`Android snapshot helper returned insufficient foreground app content`):Cr(r)||wr(r,t)?X(r,t,`content-poor-app-window`,`Android snapshot helper returned insufficient application window content`):Tr(r)?X(r,t,`system-window-only`,`Android snapshot helper returned only non-application windows`):{outcome:`ok`}}function X(e,t,n,r){return{outcome:`unusable`,decision:Dr(e,t,n,r)}}function yr(e){return e.windowRootCount>0&&e.applicationWindowRootCount===0&&e.activeSystemSurfaceMeaningfulNodeCount>=3}function br(e,t){return e.nodeCount===0||t.nodeCount===0||t.rootPresent===!1}function xr(e){return Sr(e)&&e.inputMethodMeaningfulNodeCount>=2}function Sr(e){let t=e.foregroundAppMeaningfulNodeCount;return t===void 0?!1:t===0?e.applicationMeaningfulNodeCount<2:t<2&&e.meaningfulNodeCount>t}function Cr(e){return e.foregroundAppMeaningfulNodeCount===void 0&&e.applicationWindowRootCount>0&&e.applicationMeaningfulNodeCount<2}function wr(e,t){return e.foregroundAppMeaningfulNodeCount===void 0&&e.windowRootCount===0&&(t.windowCount??0)>1&&e.nonSystemMeaningfulNodeCount<2}function Tr(e){return e.windowRootCount>0&&e.applicationWindowRootCount===0||e.windowRootCount===0&&e.nodeCount>0&&e.systemUiNodeCount===e.nodeCount}function Er(e){return e.hasAlertButtonIdentifier&&e.hasAlertContentIdentifier}function Dr(e,t,n,r){return{reason:n,failureReason:r,diagnostics:Vr(e,t)}}function Or(e,t){let n=kr(t);for(let t of ye(e))Ar(n,t);return Lr(n)}function kr(e){return{nodeCount:0,systemUiNodeCount:0,windowRootCount:0,applicationWindowRootCount:0,activeSystemSurfaceMeaningfulNodeCount:0,meaningfulNodeCount:0,applicationMeaningfulNodeCount:0,nonSystemMeaningfulNodeCount:0,inputMethodMeaningfulNodeCount:0,hasAlertButtonIdentifier:!1,hasAlertContentIdentifier:!1,...e===void 0?{}:{foregroundAppPackage:e,foregroundAppMeaningfulNodeCount:0},windowTypes:new Set}}function Ar(e,t){e.nodeCount+=1,Br(t.packageName)&&(e.systemUiNodeCount+=1),t.visibleToUser!==!1&&jr(e,t.resourceId),Mr(e,t),Nr(e,t)}function jr(e,t){let n=Zn(t);n===`button`&&(e.hasAlertButtonIdentifier=!0),n===`content`&&(e.hasAlertContentIdentifier=!0)}function Mr(e,t){t.windowType!==void 0&&(e.currentWindowType=t.windowType,e.currentWindowActiveOrFocused=t.windowActive===!0||t.windowFocused===!0,e.windowRootCount+=1,e.windowTypes.add(t.windowType),t.windowType===1&&(e.applicationWindowRootCount+=1))}function Nr(e,t){Rr(t)&&(e.meaningfulNodeCount+=1,Pr(e,t),Ir(e,t))}function Pr(e,t){e.currentWindowType===1&&!zr(t.packageName)&&(e.applicationMeaningfulNodeCount+=1),Fr(e)&&!o(t)&&(e.activeSystemSurfaceMeaningfulNodeCount+=1)}function Fr(e){return e.currentWindowType!==void 0&&e.currentWindowType!==1&&e.currentWindowActiveOrFocused===!0}function Ir(e,t){zr(t.packageName)||(e.nonSystemMeaningfulNodeCount+=1),l({packageName:t.packageName,resourceId:t.resourceId})&&(e.inputMethodMeaningfulNodeCount+=1),e.foregroundAppPackage!==void 0&&t.packageName===e.foregroundAppPackage&&(e.foregroundAppMeaningfulNodeCount=(e.foregroundAppMeaningfulNodeCount??0)+1)}function Lr(e){return{nodeCount:e.nodeCount,systemUiNodeCount:e.systemUiNodeCount,windowRootCount:e.windowRootCount,applicationWindowRootCount:e.applicationWindowRootCount,activeSystemSurfaceMeaningfulNodeCount:e.activeSystemSurfaceMeaningfulNodeCount,meaningfulNodeCount:e.meaningfulNodeCount,applicationMeaningfulNodeCount:e.applicationMeaningfulNodeCount,nonSystemMeaningfulNodeCount:e.nonSystemMeaningfulNodeCount,inputMethodMeaningfulNodeCount:e.inputMethodMeaningfulNodeCount,hasAlertButtonIdentifier:e.hasAlertButtonIdentifier,hasAlertContentIdentifier:e.hasAlertContentIdentifier,...e.foregroundAppPackage===void 0?{}:{foregroundAppPackage:e.foregroundAppPackage,foregroundAppMeaningfulNodeCount:e.foregroundAppMeaningfulNodeCount??0},windowTypes:[...e.windowTypes].sort((e,t)=>e-t).slice(0,8)}}function Rr(e){return e.visibleToUser===!1?!1:Z(e.text)||Z(e.desc)||Z(e.resourceId)}function Z(e){return e!==null&&e.trim()!==``}function zr(e){return e===null||_r.has(e)}function Br(e){return e!==null&&_r.has(e)}function Vr(e,t){return{helperNodeCount:e.nodeCount,helperSystemUiNodeCount:e.systemUiNodeCount,helperWindowRootCount:e.windowRootCount,helperApplicationWindowRootCount:e.applicationWindowRootCount,helperMeaningfulNodeCount:e.meaningfulNodeCount,helperApplicationMeaningfulNodeCount:e.applicationMeaningfulNodeCount,helperNonSystemMeaningfulNodeCount:e.nonSystemMeaningfulNodeCount,helperInputMethodMeaningfulNodeCount:e.inputMethodMeaningfulNodeCount,...e.foregroundAppPackage===void 0?{}:{helperForegroundAppPackage:e.foregroundAppPackage,helperForegroundAppMeaningfulNodeCount:e.foregroundAppMeaningfulNodeCount,helperForegroundAppMeaningfulNodeThreshold:2},helperWindowTypes:e.windowTypes,...t.captureMode?{helperCaptureMode:t.captureMode}:{}}}async function Hr(e){let t=await G(e.deviceKey,{signal:e.signal,cause:e.cause});e.signal?.throwIfAborted(),t||await Q(e.adb,e.packageName)}async function Q(e,n){try{await e([`shell`,`am`,`force-stop`,n],{allowFailure:!0,timeoutMs:2e3}),await ae(150),p({level:`debug`,phase:`android_snapshot_helper_runtime_reset`,data:{packageName:n}})}catch(e){p({level:`warn`,phase:`android_snapshot_helper_runtime_reset_failed`,data:{packageName:n,error:t(e).message}})}}const $=5e3,Ur=3e4;async function Wr(e,t={}){let n=h(e,t.helperAdb).exec;return(await Zr(e,t,n)).xml}async function Gr(e,t={}){let n=h(e,t.helperAdb).exec,r=await Zr(e,t,n),i=r.xml,a=Fe(i),o=xe(a,void 0,t),s=Jr(o.truncated,r.metadata);t.interactiveOnly&&t.includeHiddenContentHints!==!1&&Xr({options:t,tree:a,xml:i,interactiveSnapshot:o});let{sourceNodes:c,...l}=o;return{...l,...Yr(s),androidSnapshot:Kr(r.metadata,a)}}function Kr(e,t){return qr(t)===!1?{...e,occlusionScanUnavailable:!0}:e}function qr(e){let t=[...e.children];if(t.length!==0){for(;t.length>0;){let e=t.pop();if(e.drawingOrder!==void 0)return!0;t.push(...e.children)}return!1}}function Jr(e,t){return e===!0||t.helperTruncated===!0?!0:e}function Yr(e){return e===!0?{truncated:!0}:{}}function Xr(e){if(gi(e.interactiveSnapshot.nodes).size>0||hi(e.xml))return;let t=xe(e.tree,void 0,{...e.options,interactiveOnly:!1});_i(f(r(t.nodes)),t,e.interactiveSnapshot)}async function Zr(e,t,n){let r=h(e,t.helperAdb),i=await m(`android_snapshot_helper_artifact_resolution`,async()=>await pi(t.helperArtifact??r.snapshotHelperArtifact));if(i.artifact)return await Qr(e,t,n,i.artifact);throw p({level:`error`,phase:`android_snapshot_helper_unavailable`,data:{reason:i.errorReason??`artifact_not_found`}}),mi(i.errorReason)}async function Qr(e,t,n,r){let i=P(e),a=h(e,t.helperAdb),o=t.helperSessionScope!==`daemon-session`;try{let e;for(let o=0;;o+=1){o>0&&await ri(t.signal);let s=await ni({options:t,adb:n,adbProvider:a,artifact:r,helperDeviceKey:i,attempt:o,previousContentReason:e});if(s.outcome===`captured`)return s.capture;if(o+1>=3)return await ii({contentRecovery:s.decision,attempts:o+1,helperDeviceKey:i,artifact:r,adb:n,signal:t.signal});e=s.decision.reason}}finally{o&&await G(i)}}async function $r(e,t,n,r,i){let a=await m(`android_snapshot_helper_install`,async()=>await In({adb:t,adbProvider:n,artifact:r,deviceKey:i,installPolicy:e.helperInstallPolicy,timeoutMs:3e4,signal:e.signal}),{packageName:r.manifest.packageName,versionCode:r.manifest.versionCode,installPolicy:e.helperInstallPolicy??`missing-or-outdated`});return p({phase:`android_snapshot_helper_install_decision`,data:{packageName:a.packageName,versionCode:a.versionCode,installedVersionCode:a.installedVersionCode,artifactSha256:r.manifest.sha256,installedSha256:a.installedSha256,installed:a.installed,reason:a.reason}}),a}async function ei(e){let{signal:n,adb:r,adbProvider:i,artifact:a,helperDeviceKey:o}=e,s={adb:r,adbProvider:i,deviceKey:o,helperVersion:a.manifest.version,helperVersionCode:a.manifest.versionCode,helperSha256:a.manifest.sha256,packageName:a.manifest.packageName,instrumentationRunner:a.manifest.instrumentationRunner,waitForIdleTimeoutMs:500,timeoutMs:$,commandTimeoutMs:Ur,signal:n};try{let e=await m(`android_snapshot_helper_session_capture`,async()=>await bn(s),{packageName:a.manifest.packageName,version:a.manifest.version,timeoutMs:$});if(e)return e}catch(e){if(n?.throwIfAborted(),Mt(e))throw e;p({level:`warn`,phase:`android_snapshot_helper_session_fallback`,data:{reason:t(e).message}}),await Q(r,a.manifest.packageName)}return await m(`android_snapshot_helper_capture`,async()=>await zt(s),{packageName:a.manifest.packageName,version:a.manifest.version,timeoutMs:$,commandTimeoutMs:Ur})}function ti(e,t,n){return{xml:e.xml,metadata:{backend:`android-helper`,helperVersion:t.manifest.version,helperApiVersion:e.metadata.helperApiVersion,helperTransport:e.metadata.transport,helperSessionReused:e.metadata.sessionReused,installReason:n,waitForIdleTimeoutMs:e.metadata.waitForIdleTimeoutMs,waitForIdleQuietMs:e.metadata.waitForIdleQuietMs,timeoutMs:e.metadata.timeoutMs,maxDepth:e.metadata.maxDepth,maxNodes:e.metadata.maxNodes,rootPresent:e.metadata.rootPresent,captureMode:e.metadata.captureMode,windowCount:e.metadata.windowCount,nodeCount:e.metadata.nodeCount,helperTruncated:e.metadata.truncated,elapsedMs:e.metadata.elapsedMs}}}async function ni(e){let{options:t,adb:n,adbProvider:r,artifact:i,helperDeviceKey:a,attempt:o}=e,s;try{let e=await $r(t,n,r,i,a);e.installed&&await G(a),s=ti(await ei({signal:t.signal,adb:n,adbProvider:r,artifact:i,helperDeviceKey:a}),i,e.reason)}catch(e){return t.signal?.throwIfAborted(),{outcome:`captured`,capture:await ai({error:e,helperDeviceKey:a,artifact:i,adb:n})}}let c=vr(s.xml,s.metadata,{foregroundAppPackage:t.appBundleId});return c.outcome===`system-surface-only`?(p({phase:`android_snapshot_helper_system_surface`,data:{foregroundAppPackage:t.appBundleId}}),{outcome:`captured`,capture:{xml:s.xml,metadata:{...s.metadata,systemSurfaceOnly:!0}}}):c.outcome===`ok`?(o>0&&p({phase:`android_snapshot_helper_content_recaptured`,data:{attempts:o+1,recoveredFromReason:e.previousContentReason}}),{outcome:`captured`,capture:s}):{outcome:`unusable`,decision:c.decision}}async function ri(e){e?.throwIfAborted(),await ae(250),e?.throwIfAborted()}async function ii(e){throw p({level:`error`,phase:`android_snapshot_helper_content_invalid`,data:{reason:e.contentRecovery.reason,failureReason:e.contentRecovery.failureReason,attempts:e.attempts,...e.contentRecovery.diagnostics}}),await Hr({adb:e.adb,deviceKey:e.helperDeviceKey,packageName:e.artifact.manifest.packageName,signal:e.signal,cause:e.contentRecovery.failureReason}),new n(`COMMAND_FAILED`,e.contentRecovery.failureReason,{...e.contentRecovery.diagnostics,androidSnapshotHelperFailureReason:e.contentRecovery.reason,attempts:e.attempts,retriable:!0,hint:`Retry after the app UI stabilizes. If this persists, capture a screenshot and report the helper diagnostics; agent-device does not substitute a second snapshot engine.`})}async function ai(e){let t=oi(e.error);throw p({level:`error`,phase:`android_snapshot_helper_failed`,data:{reason:t}}),await G(e.helperDeviceKey),await Q(e.adb,e.artifact.manifest.packageName),Nn({deviceKey:e.helperDeviceKey,packageName:e.artifact.manifest.packageName,versionCode:e.artifact.manifest.versionCode}),si(e.error,t)}function oi(e){let n=t(e),r=di(n.details?.helper);if(r&&r!==n.message)return`${n.message}: ${r}`;if(r)return r;let i=(typeof n.details?.stderr==`string`?n.details.stderr.trim():``).split(/\r?\n/).find(e=>e.trim());return i?`${n.message}: ${i}`:n.message}function si(r,i){let a=t(r);return new n(e(a.code),`Android snapshot helper failed: ${i}`,{...a.details,...li(a),androidSnapshotHelperFailureReason:i,hint:ci(a)},r)}function ci(e){return fi(e.details?.helper,e.message)||ui(e)?`Android accessibility snapshots can be blocked by busy or continuously changing app UI. Use screenshot as visual truth after this timeout and report the busy UI if it persists.`:e.details?.androidSnapshotHelperInstallFailure===!0?[e.hint,`This is a device-side install failure (adb rejection or OEM policy) — the helper artifact itself is present, this is not a missing/unbuilt build.`].filter(Boolean).join(` `):e.hint??`Retry once. If the helper still fails, run agent-device doctor and report the diagnostic log; agent-device does not substitute a second snapshot engine.`}function li(e){let t={};return e.diagnosticId!==void 0&&(t.diagnosticId=e.diagnosticId),e.logPath!==void 0&&(t.logPath=e.logPath),e.retriable!==void 0&&(t.retriable=e.retriable),e.supportedOn!==void 0&&(t.supportedOn=e.supportedOn),t}function ui(e){return e.details?.exitCode===137?/Android snapshot helper (failed before returning parseable output|output could not be parsed)/.test(e.message):!1}function di(e){if(!e||typeof e!=`object`||!(`message`in e))return;let t=String(e.message).trim();return t&&t!==`null`?t:void 0}function fi(e,t){if(!e||typeof e!=`object`)return!1;let n=`errorType`in e?String(e.errorType):``,r=di(e)??t;return/TimeoutException/.test(n)||/timed out/i.test(r)}async function pi(e){if(e)return{artifact:e};let n=re(),r=v.join(ie(),`android`,`snapshot-helper`,`dist`),i=v.join(r,`agent-device-android-snapshot-helper-${n}.manifest.json`);try{await y.access(i)}catch{return{}}try{let e=yt(JSON.parse(await y.readFile(i,`utf8`))),t=v.join(r,e.assetName??`agent-device-android-snapshot-helper-${e.version}.apk`);return await y.access(t),{artifact:{apkPath:t,manifest:e}}}catch(e){return{errorReason:t(e).message}}}function mi(e){let t=e??`the bundled helper artifact was not found`;return new n(`COMMAND_FAILED`,`Android snapshot helper is unavailable: ${t}`,{androidSnapshotHelperFailureReason:t,hint:"Run `pnpm build:android` to build the helper dist for a source checkout — the runtime needs android/snapshot-helper/dist/agent-device-android-snapshot-helper-<version>.manifest.json and the .apk it references. Packaged installs ship these via the prepack script; if they are missing from a packaged install, reinstall agent-device."})}function hi(e){return e.includes(` can-scroll-forward=`)||e.includes(` can-scroll-backward=`)}function gi(e){let t=new Map;for(let n of e){let e={};n.hiddenContentAbove&&(e.hiddenContentAbove=!0),n.hiddenContentBelow&&(e.hiddenContentBelow=!0),(e.hiddenContentAbove||e.hiddenContentBelow)&&t.set(n.index,e)}return t}function _i(e,t,n){if(e.size===0)return;let r=new Map;for(let[e,t]of n.sourceNodes.entries()){let i=n.nodes[e];i&&r.set(t,i)}for(let[n,i]of e){let e=t.sourceNodes[n];if(!e)continue;let a=r.get(e);a&&(i.hiddenContentAbove&&(a.hiddenContentAbove=!0),i.hiddenContentBelow&&(a.hiddenContentBelow=!0))}}export{Wn as a,Tn as c,P as d,F as f,ye as h,Qn as i,G as l,D as m,Gr as n,In as o,yt as p,$n as r,kn as s,Wr as t,On as u};
|
|
1
|
+
import e from"node:path";import t from"node:fs";function n(e){let t=Array.isArray(e)?e:[e],n=[],i=(e,t,a)=>{let o=n.length;n.push(r(e,{index:o,depth:t,parentIndex:a}));for(let n of u(e))i(n,t+1,o)};for(let e of t)i(e,0);return n}function r(e,t){return{index:t.index,type:i(e),role:a(e),label:o(e),value:s(e),identifier:c(e),rect:l(e),enabled:e.enabled,selected:e.selected,hittable:e.hittable,depth:t.depth,parentIndex:t.parentIndex}}function i(e){return e.elementType??e.type}function a(e){return e.role??i(e)}function o(e){return e.label??e.AXLabel??void 0}function s(e){return e.value??e.AXValue??void 0}function c(e){return e.identifier??e.AXUniqueId??void 0}function l(e){let t=e.rect??e.frame;if(!(!t||typeof t.x!=`number`||typeof t.y!=`number`||typeof t.width!=`number`||typeof t.height!=`number`))return{x:t.x,y:t.y,width:t.width,height:t.height}}function u(e){return e.children??e.nodes??e.elements??[]}function d(e){return e.key===`id`?{accessibilityId:e.value}:e.key===`value`?{value:e.value}:{label:e.value}}async function f(n,r){t.mkdirSync(e.dirname(n),{recursive:!0}),await t.promises.writeFile(n,Buffer.from(r,`base64`))}export{d as n,f as r,n as t};
|
package/dist/src/snapshot2.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{y as e}from"./sdk-contracts.js";import{t}from"./ttl-memo.js";import{m as n,x as r,y as i}from"./host-file.js";import{runHarmonyHdc as a}from"./hdc.js";import o from"node:path";import{randomUUID as s}from"node:crypto";const c=t({ttlMs:2e3,scheduleExpiry:!0});async function l(e,t={}){let c=`/data/local/tmp/agent-device-layout-${s()}.json`,l=await n(`agent-device-harmony-layout-`),u=o.join(l,`layout.json`);try{return await a(e,[`shell`,`uitest`,`dumpLayout`,`-p`,c],{timeoutMs:3e4}),await a(e,[`file`,`recv`,c,u],{timeoutMs:15e3}),p(f(await i(u)),t)}finally{await a(e,[`shell`,`rm`,`-f`,c],{allowFailure:!0}).catch(()=>{}),await r(l)}}async function u(t){let n=t.id,r=c.get(n);if(r)return r;let i=(await l(t)).nodes.find(e=>e.type===`Application`&&e.rect)?.rect;if(!i||i.width<=0||i.height<=0)throw new e(`COMMAND_FAILED`,`HarmonyOS snapshot did not expose an application viewport`);return c.set(n,i),i}function d(e){c.delete(e.id)}function f(t){try{let e=JSON.parse(t);if(!e||typeof e!=`object`||Array.isArray(e))throw Error(`layout root is not an object`);return e}catch(t){throw new e(`COMMAND_FAILED`,`HarmonyOS uitest returned an invalid layout JSON document`,{cause:t instanceof Error?t.message:String(t)})}}function p(e,t){let{nodes:n,truncated:r,analysis:i}=m(e,{maxNodes:5e3,maxDepth:t.depth??1/0,interactiveOnly:t.interactiveOnly===!0});return{nodes:n,...r?{truncated:!0}:{},analysis:i}}function m(e,t){let n=[],r=0,i=0,a=!1,o=(e,s,c)=>{r+=1,i=Math.max(i,s);let l=c;if(n.length>=t.maxNodes)a=!0;else{let r=h(e.attributes??{},n.length,s,c);l=!t.interactiveOnly||r.hittable===!0?n.push(r)-1:c}if(s<t.maxDepth)for(let t of e.children??[])o(t,s+1,l)};return o(e,0),{nodes:n,truncated:a,analysis:{rawNodeCount:r,maxDepth:i}}}function h(e,t,n,r){let i=g(e,`text`)??g(e,`originalText`),a=g(e,`description`),o=g(e,`id`)??g(e,`key`),s=_(g(e,`bounds`));return{index:t,type:g(e,`type`)===`root`?`Application`:g(e,`type`),...a?{label:a}:{},...i?{value:i}:{},...o?{identifier:o}:{},...s?{rect:s}:{},enabled:g(e,`enabled`)!==`false`,focused:g(e,`focused`)===`true`,visibleToUser:g(e,`visible`)!==`false`,hittable:g(e,`clickable`)===`true`,depth:n,...r===void 0?{}:{parentIndex:r}}}function g(e,t){let n=e[t];return typeof n==`string`?n:void 0}function _(e){if(!e)return;let t=/^\[(-?\d+),(-?\d+)\]\[(-?\d+),(-?\d+)\]$/.exec(e);if(!t)return;let[,n,r,i,a]=t,o=Number(n),s=Number(r),c=Number(i)-o,l=Number(a)-s;return c>=0&&l>=0?{x:o,y:s,width:c,height:l}:void 0}export{d as invalidateHarmonyGestureViewport,u as readHarmonyGestureViewport,l as snapshotHarmony};
|
package/dist/src/snapshot3.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{y as e}from"./sdk-contracts.js";import{r as t}from"./diagnostics.js";import{d as n}from"./owner-identity.js";import"./diagnostics2.js";import"./process.js";import{c as r}from"./host-file.js";import{n as i,t as a}from"./tool-provider2.js";import o from"node:path";import{fileURLToPath as s}from"node:url";const c={"push button":`Button`,"toggle button":`Button`,"push button menu":`Button`,label:`StaticText`,static:`StaticText`,caption:`StaticText`,text:`TextField`,entry:`TextField`,"password text":`TextField`,"spin button":`TextField`,terminal:`TextArea`,"document text":`TextArea`,paragraph:`TextArea`,frame:`Window`,window:`Window`,dialog:`Dialog`,alert:`Alert`,"file chooser":`Dialog`,"color chooser":`Dialog`,"font chooser":`Dialog`,panel:`Group`,filler:`Group`,section:`Group`,form:`Group`,grouping:`Group`,"layered pane":`Group`,"glass pane":`Group`,"root pane":`Group`,"option pane":`Group`,"internal frame":`Group`,"desktop frame":`Group`,"block quote":`Group`,article:`Group`,comment:`Group`,landmark:`Group`,log:`Group`,marquee:`Group`,math:`Group`,notification:`Group`,"content deletion":`Group`,"content insertion":`Group`,mark:`Group`,suggestion:`Group`,"scroll pane":`ScrollArea`,"scroll bar":`ScrollBar`,"menu bar":`MenuBar`,menu:`Menu`,"popup menu":`Menu`,"menu item":`MenuItem`,"check menu item":`MenuItem`,"radio menu item":`MenuItem`,"tearoff menu item":`MenuItem`,"check box":`CheckBox`,"radio button":`RadioButton`,switch:`Switch`,"combo box":`ComboBox`,"page tab":`Tab`,"page tab list":`TabList`,table:`Table`,"tree table":`Table`,"table cell":`Cell`,"table row":`Row`,"table column header":`Cell`,"table row header":`Cell`,"column header":`Cell`,"row header":`Cell`,list:`List`,"list item":`ListItem`,"list box":`List`,tree:`Tree`,"tree item":`TreeItem`,"description list":`List`,"description term":`ListItem`,"description value":`ListItem`,"tool bar":`Toolbar`,"status bar":`StatusBar`,"info bar":`StatusBar`,slider:`Slider`,"progress bar":`ProgressBar`,"level bar":`ProgressBar`,image:`Image`,icon:`Image`,animation:`Image`,canvas:`Image`,"drawing area":`Image`,video:`Video`,audio:`Audio`,link:`Link`,hyperlink:`Link`,separator:`Separator`,application:`Application`,"tool tip":`Tooltip`,timer:`Timer`,heading:`Heading`,footnote:`Footnote`,"title bar":`TitleBar`,"date editor":`DateEditor`,rating:`Slider`};function l(e){let t=e.toLowerCase().trim();return c[t]||t.split(/[\s_-]+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(``)}const u=`atspi-dump.py`;let d=null;function f(){if(d)return d;let t=o.dirname(s(import.meta.url));for(let e=0;e<6;e++){let e=o.join(t,`linux`,u);if(r(e))return d=e,e;t=o.dirname(t)}throw new e(`TOOL_MISSING`,`Cannot find ${u}. Ensure the agent-device package is installed correctly.`)}async function p(t,r={}){let o=a().accessibility;if(o)return await o.captureTree(t,r);if(n()!==`linux`)throw new e(`UNSUPPORTED_PLATFORM`,`AT-SPI2 bridge is only available on Linux`);if(!await a().whichCommand(`python3`))throw new e(`TOOL_MISSING`,`python3 is required for AT-SPI2 accessibility snapshots on Linux.`);let s=r.maxNodes??1500,c=r.maxDepth??12,u=r.maxApps??24,d=[f(),`--surface`,t,`--max-nodes`,String(s),`--max-depth`,String(c),`--max-apps`,String(u)],p=await i(`python3`,d,{allowFailure:!0,timeoutMs:3e4,signal:r.signal});if(p.exitCode!==0){let t=p.stderr.trim();throw t.includes(`No module named`)||t.includes(`gi.require_version`)?new e(`TOOL_MISSING`,`AT-SPI2 Python bindings not found. Install python3-gi and gir1.2-atspi-2.0.`,{cause:t}):new e(`COMMAND_FAILED`,`AT-SPI2 snapshot failed (exit ${p.exitCode}): ${t||p.stdout}`)}let m;try{m=JSON.parse(p.stdout)}catch{throw new e(`COMMAND_FAILED`,`AT-SPI2 snapshot returned invalid JSON: ${p.stdout.slice(0,200)}`)}if(m.error)throw new e(`COMMAND_FAILED`,`AT-SPI2: ${m.error}`);return{nodes:(m.nodes??[]).map(e=>({index:e.index,type:l(e.role),role:e.role,label:e.label??void 0,value:e.value??void 0,rect:e.rect??void 0,enabled:e.enabled??void 0,selected:e.selected??void 0,hittable:e.hittable??void 0,depth:e.depth,parentIndex:e.parentIndex??void 0,pid:e.pid??void 0,appName:e.appName??void 0,windowTitle:e.windowTitle??void 0})),truncated:m.truncated,surface:t}}function m(e){return e===`desktop`?`desktop`:e===`frontmost-app`||e===`app`?`frontmost-app`:(e===`menubar`&&t({level:`warn`,phase:`linux_snapshot`,data:{message:`menubar surface is not supported on Linux, falling back to desktop`}}),`desktop`)}async function h(e,t){let n=await p(m(e),{signal:t});return{nodes:n.nodes,truncated:n.truncated}}async function g(e,t,n){let{nodes:r}=await h(n),i=r.filter(n=>{let r=n.rect;return r?e>=r.x&&t>=r.y&&e<=r.x+r.width&&t<=r.y+r.height:!1}).sort((e,t)=>{let n=e.depth??0,r=t.depth??0;return n===r?_(e.rect)-_(t.rect):r-n});for(let e of i){let t=v(e);if(t.trim())return t}return``}function _(e){return(e?.width??0)*(e?.height??0)}function v(e){for(let t of[e.value,e.label,e.identifier])if(typeof t==`string`&&t.length>0)return t;return``}export{g as readLinuxTextAtPoint,h as snapshotLinux};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{y as e}from"./sdk-contracts.js";import{u as t}from"./sdk-device.js";import{$ as n,Lt as r,Q as i,Z as a,cr as o,et as s,jr as c,nn as l,on as u,tn as d}from"./sdk-batch.js";import"./session-store.js";import{f}from"./parameterized-recorded-fill.js";import{l as p}from"./runtime.js";import{n as m,r as h}from"./success-text.js";import"./alert-contract.js";import{a as g,o as _,r as v,t as y}from"./location-coordinates.js";import{a as b,t as ee}from"./app-inventory-contract.js";import{r as te}from"./diagnostics.js";import"./diagnostics2.js";import{r as ne}from"./request-cancel.js";import"./request.js";import{m as re}from"./screenshot-runtime.js";import{i as x}from"./request-runtime-binding.js";import{C as S,b as C,f as w,h as T,p as E,r as D,s as ie}from"./session-snapshot.js";import{n as ae,t as oe}from"./snapshot-runtime.js";import{a as O,i as k,o as A}from"./snapshot-runtime-binding.js";import{_ as j,a as M,c as N,g as P,h as F,m as I,o as L,p as R,s as z,t as B,u as V,v as H}from"./selector-runtime.js";async function U(e){let{device:t,action:r,inspectFacts:o,bindDevice:c}=e,l={command:`alert`,device:t,inspectFacts:o,bindDevice:c,...e.session?{}:{readiness:{}}};if(r===`wait`){let e=await T({...l,use:s});if(e.type===`response`)return{ok:!1,response:e.response};let t=e.runtime;return{ok:!0,execute:e=>G(t,e)}}if(r===`accept`){let e=await T({...l,use:a});if(e.type===`response`)return{ok:!1,response:e.response};let t=e.runtime;return{ok:!0,execute:e=>K(t,e)}}if(r===`dismiss`){let e=await T({...l,use:i});if(e.type===`response`)return{ok:!1,response:e.response};let t=e.runtime;return{ok:!0,execute:e=>q(t,e)}}let u=await T({...l,use:n});if(u.type===`response`)return{ok:!1,response:u.response};let d=u.runtime;return{ok:!0,execute:e=>W(d,e)}}async function W(e,t){return await e.operations.readAlert(t)}async function G(e,t){return await e.operations.awaitAlert(t)}async function K(e,t){return await e.operations.acceptAlert(t)}async function q(e,t){return await e.operations.dismissAlert(t)}async function se(e){let{req:t,logPath:n,sessionStore:r,session:i,device:a,inspectFacts:o,bindDevice:s}=e,c=await U({device:a,action:le(t.positionals?.[0]),session:i,inspectFacts:o,bindDevice:s});if(!c.ok)return c.response;i&&re(t)===`may-invalidate`&&S(i);let u=C(n,t.flags,i?.appBundleId,i?.trace?.outPath),d=await c.execute({timeoutMs:l(t.positionals?.[1])??1e4,...ce(i),execution:E(u)});return k(r,i,t,d),{ok:!0,data:d}}function ce(e){return{...e?.appBundleId===void 0?{}:{appBundleId:e.appBundleId},...e?.surface===void 0?{}:{surface:e.surface}}}function le(e){return e===`accept`||e===`dismiss`||e===`wait`?e:`get`}function ue(e){let t=e.positionals?.[0]?.toLowerCase(),n=e.positionals?.[1]?.toLowerCase(),r=e.positionals?.[2]?.toLowerCase();return t===`clear-app-state`?{ok:!0,parsed:{setting:t,state:`clear`,appBundleId:n===`clear`?e.positionals?.[2]:e.positionals?.[1]}}:!t||!n||t===`permission`&&!r||t===`location`&&n===`set`&&(!e.positionals?.[2]||!e.positionals?.[3])||t===`reset-keychain`&&e.positionals?.[2]!==void 0?x(`INVALID_ARGS`,v):{ok:!0,parsed:{setting:t,state:n,permissionTarget:r,permissionMode:e.positionals?.[3],latitude:e.positionals?.[2],longitude:e.positionals?.[3]}}}function de(e){if(e.setting===`permission`)return{permissionTarget:e.permissionTarget,permissionMode:e.permissionMode};if(e.setting===`location`&&e.state===`set`)return{latitude:y(e.latitude,`latitude`),longitude:y(e.longitude,`longitude`)}}function fe(e,t,n){let{setting:r,state:i}=e;return r===`clear-app-state`?{setting:`clear-app-state`,state:`clear`,appBundleId:t,platform:n}:r===`location`&&i===`set`?{setting:r,state:i,latitude:e.latitude,longitude:e.longitude,platform:n}:r===`permission`?{setting:r,state:i,permissionTarget:e.permissionTarget,permissionMode:e.permissionMode,platform:n}:{setting:r,state:i,appBundleId:t,platform:n}}function pe(e){return typeof e.message==`string`&&e.message.length>0?e.message:void 0}async function me(e,t,n){let{setting:r,state:i}=t,a=await e.operations.setSetting(t);return a&&typeof a==`object`?h({setting:r,state:i,...a},pe(a)??n):{setting:r,state:i,...m(n)}}async function he(e){let{req:n,logPath:i,sessionStore:a,session:o,device:s,parsed:c,inspectFacts:l,bindDevice:u}=e,{setting:d,state:f}=c,p=await T({command:`settings`,device:s,use:r,inspectFacts:l,bindDevice:u,...o?{}:{readiness:{}}});if(p.type===`response`)return p.response;if(t(s)&&!_(d))return x(`INVALID_ARGS`,g(d));let m=c.appBundleId??o?.appBundleId;if(d===`clear-app-state`&&!m)return x(`INVALID_ARGS`,`settings clear-app-state requires an app id when no app is bound to the session`);o&&S(o),te({level:`debug`,phase:`settings_apply`,data:fe(c,m,s.platform)});let h=de(c),v=C(i,n.flags,m,o?.trace?.outPath),y=await me(p.runtime,{setting:d,state:f,...m===void 0?{}:{appBundleId:m},...h===void 0?{}:{options:h},execution:E(v)},d===`clear-app-state`?`Cleared user data for ${m}`:`Updated setting: ${d}`);return k(a,o,n,y),{ok:!0,data:y}}async function ge(e){return await ae({...e,command:`diff`,execute:async({runtime:e,sessionName:t,req:n,snapshotScope:r})=>{let i=await e.capture.diffSnapshot({session:t,interactiveOnly:n.flags?.snapshotInteractiveOnly,depth:n.flags?.snapshotDepth,scope:r,raw:n.flags?.snapshotRaw});return{data:i,record:{kind:`diff`,mode:`snapshot`,baselineInitialized:i.baselineInitialized,summary:i.summary}}}})}function _e(e){return e!==`sleep`}async function ve(e){if(!e.operation||!e.session?.appBundleId||e.recordedLandmark||f(e.session))return null;let t=u(e.selectorExpression);if(!t)return null;let n=Date.now();if(!(await e.operation({selector:{key:t.key,value:t.value},options:{appBundleId:e.session.appBundleId,surface:e.session.surface},execution:w({flags:e.req.flags,logPath:e.logPath??``,meta:e.req.meta,session:e.session,snapshotScope:void 0}).execution,signal:e.signal??ne(e.req.meta?.requestId)})).found)return null;let r={kind:`selector`,selector:t.raw,waitedMs:Date.now()-n,selectorChain:[t.raw]};return I(e.sessionStore,e.sessionName,e.req,r),{ok:!0,data:P(r)}}const ye=[`application`,`window`,`tabbar`,`scrollbar`,`image`],be=new Set([`tab bar`]);async function xe(e,t){if(t.ok||!Se(t.error.details?.reason)||t.error.details?.captureStalled===!0||t.error.details?.captureTruncated===!0)return t;let n=await Ce(e).catch(()=>null);return n?x(t.error.code,`${t.error.message}. Current surface: ${n.summary}.`,{...t.error.details??{},currentSurface:n.details}):t}function Se(e){return e===p.targetAbsent||e===p.stableTimeout}async function Ce(e){let t={...e.req.flags,snapshotInteractiveOnly:!0},n=[...(await ie({device:e.device,session:e.session,flags:t,logPath:e.logPath??``,captureData:async()=>await e.capture(w({flags:t,logPath:e.logPath??``,meta:e.req.meta,session:e.session,snapshotScope:void 0}))})).snapshot.nodes].sort(we),r=J(n,6,{includeIdentifiers:!0});if(r.length===0)return null;let i=J(n.filter(e=>!Z(e)),4,{includeIdentifiers:!1}),a=J(n.filter(Ee),4,{includeIdentifiers:!0});return{summary:(i.length>0?i:r.slice(0,4)).join(`, `),details:{labels:r,...a.length>0?{buttons:a}:{}}}}function J(e,t,n){let r=new Set,i=[];for(let a of e){let e=X(a,n);if(!(!e||r.has(e))&&(r.add(e),i.push(e),i.length>=t))break}return i}function we(e,t){return Y(e)-Y(t)||Te(e,t)}function Y(e){let t=!!X(e,{includeIdentifiers:!1});return(Z(e)?2:0)+ +!t}function Te(e,t){return e.rect&&t.rect?e.rect.y-t.rect.y||e.rect.x-t.rect.x:e.rect?-1:t.rect?1:(e.depth??0)-(t.depth??0)||e.index-t.index}function X(e,t){let n=(t.includeIdentifiers?[e.label,e.value,e.identifier]:[e.label,e.value]).map(e=>typeof e==`string`?e.trim():``).find(e=>e.length>0);return n?n.replaceAll(/\s+/g,` `).slice(0,80):``}function Z(e){let t=c(`${e.type??``} ${e.role??``} ${e.subrole??``}`),n=`${e.label??``} ${e.value??``}`.trim().toLowerCase();return ye.some(e=>t.includes(e))||be.has(n)||n.endsWith(`.fill`)}function Ee(e){let t=`${e.type??``} ${e.role??``} ${e.subrole??``}`;return c(t).includes(`button`)}async function De(e){let{req:t,sessionName:n,sessionStore:r}=e,i=Oe(t);if(`ok`in i)return i;let a=i,{session:o,device:s}=await O(r,n,t.flags),c=await ke(e,a,o,s);if(c&&`ok`in c)return c;let l=c,u=t.internal?.replayLandmarkGuard,d=Ae(a,o);if(`ok`in d)return d;let{waitParsed:f,staleRefsWarning:p}=d;return await Q(e,f,o,l,u)||(e.consumedSnapshot??={},a.kind===`sleep`?await $(e,f,o,s,l,p,u):V(await A(o,s,()=>$(e,f,o,s,l,p,u),e.platformResourceCleanup),B(e)))}function Oe(e){let t=d(e.positionals??[]);if(!t)return x(`INVALID_ARGS`,`wait requires a duration or text`);if(t.kind===`invalid`)return x(`INVALID_ARGS`,t.message);if(t.kind!==`absent`)return t;let n=b({depth:e.flags?.snapshotDepth,scope:e.flags?.snapshotScope});if(!n)return t;let r=ee(n,`wait`);return x(r.code,r.message,r.details)}async function ke(e,t,n,r){if(!_e(t.kind))return;let i=await R({command:`wait`,device:r,session:n,inspectFacts:e.inspectFacts,bindDevice:e.bindDevice});return i.ok?i.operations:i.response}function Ae(e,t){if(e.kind!==`ref`)return{waitParsed:e};let n=H(e.rawRef);return n.ok?{waitParsed:{...e,rawRef:n.ref},staleRefsWarning:D({session:t,ref:n.ref,mintedGeneration:n.generation})}:n.response}async function Q(e,t,n,r,i){return t.kind===`selector`?await ve({selectorExpression:t.selectorExpression,operation:r?.findSelector,recordedLandmark:i,req:e.req,session:n,sessionName:e.sessionName,sessionStore:e.sessionStore,logPath:e.logPath,signal:e.signal}):null}async function $(e,t,n,r,i,a,o){let{req:s,sessionName:c,sessionStore:l}=e,u=N({...e,session:n,device:r,bound:i}),d=await z(async()=>{let e=await u.selectors.wait({session:c,requestId:s.meta?.requestId,target:je(t,n,o)}),r=L(e);I(l,c,s,F(e),r,`landmark`);let i=j(e);return a?{...i,warning:a}:i}),f=i?await xe({req:s,logPath:e.logPath,session:n,device:r,capture:i.capture},d):d;return await M(e,f,`wait`)}function je(e,t,n){switch(e.kind){case`sleep`:return{kind:`sleep`,durationMs:e.durationMs};case`selector`:return{kind:`selector`,selector:e.selectorExpression,timeoutMs:e.timeoutMs,...n?{recordedLandmark:n}:{}};case`absent`:return{kind:`absent`,selector:e.selectorExpression,timeoutMs:e.timeoutMs};case`ref`:return Ne(e,t);case`stable`:return{kind:`stable`,quietMs:e.quietMs,timeoutMs:e.timeoutMs};case`text`:return Pe(e);default:return Me(e)}}function Me(e){throw Error(`Unsupported wait positional target: ${String(e)}`)}function Ne(t,n){if(!n?.snapshot)throw new e(`INVALID_ARGS`,`Ref wait requires an existing snapshot in session.`);return{kind:`ref`,ref:t.rawRef,timeoutMs:t.timeoutMs}}function Pe(t){let n=o(t.text);if(!n.ok)throw new e(n.code,n.message);return{kind:`text`,text:n.text,timeoutMs:t.timeoutMs}}const Fe={snapshot:async({req:e,sessionName:t,logPath:n,sessionStore:r,inspectFacts:i,bindDevice:a,platformResourceCleanup:o})=>await oe({req:e,sessionName:t,logPath:n,sessionStore:r,inspectFacts:i,bindDevice:a,platformResourceCleanup:o}),diff:async({req:e,sessionName:t,logPath:n,sessionStore:r,inspectFacts:i,bindDevice:a,platformResourceCleanup:o})=>e.positionals?.[0]===`snapshot`?await ge({req:e,sessionName:t,logPath:n,sessionStore:r,inspectFacts:i,bindDevice:a,platformResourceCleanup:o}):x(`INVALID_ARGS`,`diff currently supports only: diff snapshot`),wait:async({req:e,sessionName:t,logPath:n,sessionStore:r,inspectFacts:i,bindDevice:a,platformResourceCleanup:o})=>await De({req:e,sessionName:t,logPath:n,sessionStore:r,inspectFacts:i,bindDevice:a,platformResourceCleanup:o}),alert:async({req:e,sessionName:t,logPath:n,sessionStore:r,inspectFacts:i,bindDevice:a,platformResourceCleanup:o})=>{let{session:s,device:c}=await O(r,t,e.flags);return await A(s,c,async()=>await se({req:e,logPath:n,sessionStore:r,session:s,device:c,inspectFacts:i,bindDevice:a}),o)},settings:async({req:e,sessionName:t,logPath:n,sessionStore:r,inspectFacts:i,bindDevice:a,platformResourceCleanup:o})=>{let s=ue(e);if(!s.ok)return s;let{session:c,device:l}=await O(r,t,e.flags);return await A(c,l,async()=>await he({req:e,logPath:n,sessionStore:r,session:c,device:l,parsed:s.parsed,inspectFacts:i,bindDevice:a}),o)}};async function Ie(e){let t=e.req.command,n=Fe[t];return n?await n(e):null}export{Ie as handleSnapshotCommands};
|
package/dist/src/src.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{J as n,Ot as r}from"./sdk-batch-runner.js";import{p as i}from"./device.js";import a from"node:path";import{scryptSync as o}from"node:crypto";import s from"node:fs";import c from"node:os";import l from"@limrun/api";import{createInstanceClient as u}from"@limrun/api/instance-client";import{createInstanceClient as ee}from"@limrun/api/ios-client";import{setTimeout as d}from"node:timers/promises";const f=`limrun`,p=f;function m(e){if(e===`ios-instance`)return`ios`;if(e===`android-instance`)return`android`}function h(e,t,n){return{platform:e===`ios`?`apple`:`android`,...e===`ios`?{appleOs:`ios`}:{},id:_(e,t.leaseId),name:`Limrun ${e} ${n.slice(0,8)}`,kind:e===`ios`?`simulator`:`emulator`,target:`mobile`,booted:!0}}function g(e){let[t,n,r]=e.split(`:`);if(t===p&&!(n!==`ios`&&n!==`android`)&&r)return{platform:n,leaseId:r}}function _(e,t){return`${p}:${e}:${t}`}function v(e){return e?.trim()||void 0}async function y(e,t,n=`Limrun provider operation aborted`,r){if(!t)try{return await e}finally{r?.()}return await new Promise((i,a)=>{let o=()=>a(t.reason??Error(n));if(t.aborted){e.then(e=>{r?.(),i(e)},e=>{r?.(),a(e)}),o();return}t.addEventListener(`abort`,o,{once:!0}),e.then(e=>{t.removeEventListener(`abort`,o),r?.(),i(e)},e=>{t.removeEventListener(`abort`,o),r?.(),a(e)})})}function te(){let e=new Set;return{wait:async(t,n,r)=>{let i,a=new Promise(e=>{i=e});return e.add(a),a.then(()=>e.delete(a)),await y(t,n,r,i)},[Symbol.asyncDispose]:async()=>{for(;e.size>0;)await Promise.all(e)}}}async function b(e,t,n,r){return await(e?e.wait(t,n,r):y(t,n,r))}async function x(e,t){let n=await u({apiUrl:e.apiUrl,adbUrl:e.adbUrl,token:e.token,logLevel:`warn`}),r={platform:`android`,lease:e.lease,instanceId:e.instanceId,device:e.device,client:n,dependencies:t},i={exec:async(e,t)=>await T(r,e,t),text:async e=>{await n.setText(e.target,e.text)}};return i.reverse=await t.android.createPortReverse(i.exec),Object.assign(r,{adbProvider:i})}function S(e){return e.dependencies.android.createInteractor(e.device,e.adbProvider)}async function C(e,t,n,r,i,a){i?.throwIfAborted();let o=v(r?.packageNameHint);r?.relaunch&&o&&await T(t,[`shell`,`am`,`force-stop`,o],{allowFailure:!0,signal:i});let s=await b(a,e.assets.getOrUpload({path:n,name:ce(o,n)},{signal:i}),i);await b(a,t.client.sendAsset(s.signedDownloadUrl),i),i?.throwIfAborted();let c=o?await t.dependencies.android.inferAppName(o):void 0;return{...o?{packageName:o,launchTarget:o}:{},...c?{appName:c}:{}}}async function w(e,t){await e.adbProvider.reverse?.ensure({local:E(t.devicePort),remote:E(t.hostPort),ownerId:t.name})}async function ne(e){await e.adbTunnelPromise?.catch(()=>{});let t=e.adbSerial;t&&(await re(e),await e.dependencies.host.runAdb([`disconnect`,t],{allowFailure:!0,timeoutMs:1e4}).catch(()=>{})),e.adbTunnel?.close(),e.adbTunnel=void 0,e.adbSerial=void 0,e.adbTunnelPromise=void 0}async function re(e){let t=e.adbProvider.reverse;if(!t?.list)return;let n=await t.list().catch(()=>[]),r=new Set,i=[];for(let e of n)e.ownerId?r.add(e.ownerId):i.push(e.local);await Promise.allSettled([...[...r].map(async e=>await t.removeAllOwned(e)),...i.map(async e=>await t.remove(e))])}async function T(e,t,n){let{adbArgs:r,result:i}=await ie(e,t,n);return await ae(r,i,n?.allowFailure,e.dependencies)}async function ie(e,t,n){let r=[`-s`,await oe(e),...t];return{adbArgs:r,result:await e.dependencies.host.runAdb(r,{allowFailure:n?.allowFailure,binaryStdout:n?.binaryStdout,stdin:n?.stdin,timeoutMs:n?.timeoutMs??3e4,signal:n?.signal})}}async function ae(e,t,n,r){if(t.exitCode!==0&&n!==!0)throw await r.android.adbError(`Limrun Android ADB command failed`,t,{command:[`adb`,...e].join(` `)});return t}async function oe(e){if(e.adbSerial)return e.adbSerial;let t=e.adbTunnelPromise??se(e);e.adbTunnelPromise=t;try{return await t}catch(n){throw e.adbTunnelPromise===t&&(e.adbTunnelPromise=void 0),n}}async function se(e){let t=await e.client.startAdbTunnel(),n=`${t.address.address}:${t.address.port}`;return e.adbTunnel=t,e.adbSerial=n,n}function E(e){if(!Number.isInteger(e)||e<1||e>65535)throw new t(`INVALID_ARGS`,`Invalid Android tcp reverse port: ${e}`);return`tcp:${e}`}function ce(e,t){let n=a.extname(t)||`.apk`;return`${e?.replace(/[^a-zA-Z0-9_.-]+/g,`-`)||`android-app`}${n}`}function D(e){let t=Array.isArray(e)?e:[e],n=[],r=(e,t,i)=>{let a=n.length;n.push(O(e,{index:a,depth:t,parentIndex:i}));for(let n of F(e))r(n,t+1,a)};for(let e of t)r(e,0);return n}function O(e,t){return{index:t.index,type:k(e),role:A(e),label:j(e),value:M(e),identifier:N(e),rect:P(e),enabled:e.enabled,selected:e.selected,hittable:e.hittable,depth:t.depth,parentIndex:t.parentIndex}}function k(e){return e.elementType??e.type}function A(e){return e.role??k(e)}function j(e){return e.label??e.AXLabel??void 0}function M(e){return e.value??e.AXValue??void 0}function N(e){return e.identifier??e.AXUniqueId??void 0}function P(e){let t=e.rect??e.frame;if(!(!t||typeof t.x!=`number`||typeof t.y!=`number`||typeof t.width!=`number`||typeof t.height!=`number`))return{x:t.x,y:t.y,width:t.width,height:t.height}}function F(e){return e.children??e.nodes??e.elements??[]}function I(e){return e.key===`id`?{accessibilityId:e.value}:e.key===`value`?{value:e.value}:{label:e.value}}async function L(e,t){s.mkdirSync(a.dirname(e),{recursive:!0}),await s.promises.writeFile(e,Buffer.from(t,`base64`))}async function R(e,t){let n=await ee({apiUrl:e.apiUrl,token:e.token,logLevel:`warn`});return{platform:`ios`,lease:e.lease,instanceId:e.instanceId,device:e.device,client:n,dependencies:t}}async function z(e,t,n,r,i,a){i?.throwIfAborted();let o=await le(n,t.dependencies);try{i?.throwIfAborted();let n=await b(a,e.assets.getOrUpload({path:o.uploadPath,name:o.assetName},{signal:i}),i),s=(await B(t,n.signedDownloadUrl,{md5:n.md5,relaunch:r?.relaunch,appIdentifierHint:r?.appIdentifierHint},i,a)).appId;return{...s?{bundleId:s,launchTarget:s}:{},...o.appName?{appName:o.appName}:{}}}finally{await o.cleanup()}}async function B(e,n,r,i,a){i?.throwIfAborted();let o=await b(a,e.client.listApps(),i).catch(e=>{if(i?.aborted)throw e}),s=v((await b(a,e.client.installApp(n,{md5:r?.md5,launchMode:r?.relaunch?`RelaunchIfRunning`:`ForegroundIfRunning`}),i)).bundleId),c=v(r?.appIdentifierHint),l=[];for(let t of W){t>0&&await d(t,void 0,{signal:i}),l=await b(a,e.client.listApps(),i);let n=ue({resultBundleId:s,requestedBundleId:c,beforeInstallApps:o,afterInstallApps:l});if(n)return{appId:n}}throw new t(`COMMAND_FAILED`,`Limrun iOS app installation could not be verified.`,{resultBundleId:s,requestedBundleId:c,installedUserApps:l.filter(G).map(e=>e.bundleId).sort()})}function V(e){return new H(e)}var H=class{session;constructor(e){this.session=e}async open(e,t){if(t?.url){await this.session.client.launchApp(await this.session.dependencies.ios.resolveAppAlias(e)),await this.session.client.openUrl(t.url);return}if(n(e)){await this.session.client.openUrl(e);return}await this.session.client.launchApp(await this.session.dependencies.ios.resolveAppAlias(e))}async openDevice(){}async close(e){e&&await this.session.client.terminateApp(await this.session.dependencies.ios.resolveAppAlias(e)).catch(()=>{})}async tap(e,t){await this.session.client.tap(e,t)}async tapElementSelector(e){await this.session.client.tapElement(I(e))}async doubleTap(e,t){await this.tap(e,t),await this.tap(e,t)}async longPress(){throw K(`longpress`,`Limrun iOS direct sessions do not expose long press yet.`)}async focus(e,t){await this.tap(e,t)}async type(e,t){if(t&&t>0){for(let n of Array.from(e))await this.session.client.typeText(n),await d(t);return}await this.session.client.typeText(e)}async fill(e,t,n){await this.tap(e,t),await this.session.client.typeText(n)}async fillElementSelector(e,t){await this.session.client.setElementValue(t,I(e))}async scroll(e,t){await this.session.client.scroll(e,t?.pixels??300)}async screenshot(e){await L(e,(await this.session.client.screenshot()).base64)}async snapshot(e){let t=await this.session.client.elementTree();return{nodes:D(JSON.parse(t)),backend:`xctest`}}async back(){await this.session.client.pressKey(`escape`)}async home(){throw K(`home`,`Limrun iOS direct sessions do not expose home yet.`)}async setOrientation(e){if(e===`portrait-upside-down`)throw K(`orientation`,`Limrun iOS direct sessions support portrait and landscape orientation, not portrait upside-down.`);await this.session.client.setOrientation(e===`portrait`?`Portrait`:`Landscape`)}async performGesture(){throw K(`gesture`,`Limrun iOS direct sessions do not expose portable gesture execution yet.`)}async appSwitcher(){throw K(`app-switcher`,`Limrun iOS direct sessions do not expose app switcher yet.`)}async tvRemote(){throw K(`tv-remote`,`Limrun iOS direct sessions do not expose tv remote control.`)}async readClipboard(){throw K(`clipboard`,`Limrun iOS direct sessions do not expose clipboard read yet.`)}async writeClipboard(){throw K(`clipboard`,`Limrun iOS direct sessions do not expose clipboard write yet.`)}async setSetting(){throw K(`settings`,`Limrun iOS direct sessions do not expose settings changes yet.`)}};async function le(e,t){if(!(await s.promises.stat(e)).isDirectory())return{uploadPath:e,assetName:a.basename(e),appName:U(e),cleanup:async()=>{}};let n=await s.promises.mkdtemp(a.join(c.tmpdir(),`agent-device-limrun-ios-app-`)),r=a.join(n,`${a.basename(e)}.zip`);try{await t.host.archiveDirectory({sourceDirectory:a.dirname(e),entryName:a.basename(e),archivePath:r})}catch(e){throw await s.promises.rm(n,{recursive:!0,force:!0}),e}return{uploadPath:r,assetName:a.basename(r),appName:await t.ios.readBundleAppName(e)??U(e),cleanup:async()=>{await s.promises.rm(n,{recursive:!0,force:!0})}}}function U(e){return a.basename(e).replace(/\.(?:app|ipa|apk|aab|zip)$/i,``)||void 0}const W=[0,250];function ue(e){let t=new Set(e.afterInstallApps.map(e=>e.bundleId));return(e.resultBundleId&&t.has(e.resultBundleId)?e.resultBundleId:void 0)??(e.requestedBundleId&&t.has(e.requestedBundleId)?e.requestedBundleId:void 0)??de(e.beforeInstallApps,e.afterInstallApps)}function de(e,t){if(!e)return;let n=new Set(e.map(e=>e.bundleId)),r=t.filter(e=>G(e)&&!n.has(e.bundleId));return r.length===1?r[0]?.bundleId:void 0}function G(e){return!e.bundleId.startsWith(`com.apple.`)&&!e.installType.toLowerCase().includes(`system`)}function K(e,n){throw new t(`UNSUPPORTED_OPERATION`,n,{command:e})}function q(e){return e.platform===`android`?fe(e):pe(e)}function fe(e){let t=e.adbProvider.exec;return{platform:`android`,device:e.device,interactor:S(e),adb:e.adbProvider,listApps:async n=>await e.dependencies.android.listApps(t,i(n)),getForegroundApp:async n=>await e.dependencies.android.getForegroundApp(e.device,t,n),pressKey:async(t,n)=>{await e.client.pressKey(t,n)},getKeyboardState:async()=>await e.dependencies.android.getKeyboardState(t),dismissKeyboard:async()=>await e.dependencies.android.dismissKeyboard(t),readLogs:async n=>await e.dependencies.android.readLogs(t,n),...J(e.client),installRemoteApp:async t=>{await e.client.sendAsset(t)}}}function pe(e){return{platform:`ios`,device:e.device,interactor:V(e),viewport:{width:e.client.deviceInfo.screenWidth,height:e.client.deviceInfo.screenHeight},listApps:async t=>(await e.client.listApps()).filter(e=>i(t)===`all`||G(e)).map(e=>({id:e.bundleId,name:e.name,installType:e.installType})).sort((e,t)=>e.id.localeCompare(t.id)),pressKey:async(t,n)=>{await e.client.pressKey(t,n)},readLogs:async(t,n)=>await e.client.appLogTail(t,n),...J(e.client),installRemoteApp:async(t,n)=>await B(e,t,n),runSimctl:t=>e.client.simctl(t)}}function J(e){return{startRecording:async t=>{await e.startRecording(t)},stopRecording:async({outPath:t})=>await e.stopRecording({localPath:t})}}const Y=`agent-device-cli`;function X(e){return{apiKey:e.apiKey,defaultHeaders:{"x-agent-device-client":Y,"x-agent-device-version":e.clientVersion}}}function me(e){if(e.runtimeInstance!==void 0){let t=e.runtimeInstance.trim();if(!t)throw TypeError(`Limrun runtimeInstance must be a non-empty string`);return t}return`principal-${o(JSON.stringify({provider:`limrun`,region:e.region?.trim().toLowerCase()||`default`,apiKey:e.apiKey}),`agent-device:limrun-runtime-owner:v1`,32,{N:16384,r:8,p:1,maxmem:67108864}).toString(`hex`)}`}function Z(e,t,n){let i=new he(e,t);if(!n?.includePlatformModule)return i;let a=r(f,me(e));if(a.kind!==`provider-runtime`)throw TypeError(`Invalid Limrun runtime owner`);return Object.freeze({runtime:i,platformModule:Object.freeze({owner:a,loadRuntime:async e=>await ge(i,a.instance,e)})})}var he=class{limrun;sessions=new Map;options;dependencies;provider=f;leaseLifecycle={allocate:async e=>await this.allocate(e),release:async e=>await this.release(e)};recoverExpiredLease=async e=>{if(e.leaseProvider!==this.provider||!m(e.backend))throw new t(`UNSUPPORTED_OPERATION`,`Limrun cannot recover this expired lease.`,{leaseId:e.leaseId,leaseProvider:e.leaseProvider,leaseBackend:e.backend});await this.release(e)};deviceInventoryProvider=async e=>{if(e.leaseProvider!==this.provider||!e.leaseId)return null;let t=this.sessions.get(e.leaseId);return t?e.platform&&e.platform!==t.platform?[]:[t.device]:null};constructor(e,t){this.options=e,this.dependencies=t,this.limrun=new l(X({apiKey:e.apiKey,clientVersion:t.clientVersion}))}ownsDevice(e){return g(e.id)!==void 0}hasLiveSession(e){return this.getSessionForDevice(e)!==void 0}getInteractor(e,t){let n=this.getSessionForDevice(e);if(n)return n.platform===`ios`?V(n):S(n)}getDeviceSession(e){let t=this.getSessionForDevice(e);return t?q(t):void 0}async installApp(e,t,n,r,i,a){return await this.installInstallablePath(e,n,{...r,appIdentifierHint:r?.appIdentifierHint??t,packageNameHint:r?.packageNameHint??t},i,a)}async installInstallablePath(e,t,n,r,i){let a=this.getSessionForDevice(e);if(a)return a.platform===`ios`?await z(this.limrun,a,t,n,r,i):await C(this.limrun,a,t,n,r,i)}async configurePortReverse(e){let t=this.requireAndroidPortReverseSession(e.leaseId);if(t)return await w(t,e),_e(e)}async shutdown(){let e=[...this.sessions.values()];await Promise.allSettled(e.map(async e=>await this.terminateSession(e))),this.sessions.clear()}async allocate(e){if(e.leaseProvider!==this.provider)return;let t=m(e.backend);if(!t)return;let n=this.sessions.get(e.leaseId);if(n)return{limrunInstanceId:n.instanceId,device:n.device};let r=t===`ios`?await this.createIosSession(e):await this.createAndroidSession(e);return this.sessions.set(e.leaseId,r),{limrunInstanceId:r.instanceId,device:r.device}}async createIosSession(e){let n=await this.limrun.iosInstances.create({wait:!0,metadata:this.buildInstanceMetadata(e),spec:this.options.region?{region:this.options.region}:{}});try{if(!n.status.apiUrl)throw new t(`COMMAND_FAILED`,`Limrun iOS instance did not expose apiUrl`);return await R({lease:e,instanceId:n.metadata.id,device:h(`ios`,e,n.metadata.id),apiUrl:n.status.apiUrl,token:n.status.token},this.dependencies)}catch(e){throw await this.limrun.iosInstances.delete(n.metadata.id).catch(()=>{}),e}}async createAndroidSession(e){let n=await this.limrun.androidInstances.create({wait:!0,metadata:this.buildInstanceMetadata(e),spec:this.options.region?{region:this.options.region}:{}});try{if(!n.status.apiUrl||!n.status.adbWebSocketUrl)throw new t(`COMMAND_FAILED`,`Limrun Android instance did not expose API and ADB websocket endpoints`);return await x({lease:e,instanceId:n.metadata.id,device:h(`android`,e,n.metadata.id),apiUrl:n.status.apiUrl,adbUrl:n.status.adbWebSocketUrl,token:n.status.token},this.dependencies)}catch(e){throw await this.limrun.androidInstances.delete(n.metadata.id).catch(()=>{}),e}}buildInstanceMetadata(e){return{displayName:`agent-device-${e.tenantId}-${e.runId}`,labels:{tenantId:e.tenantId,runId:e.runId,leaseId:e.leaseId,provider:e.leaseProvider??`limrun`,source:Y}}}async release(e){let t=this.sessions.get(e.leaseId);return t?(await this.terminateSession(t),this.sessions.delete(e.leaseId),{limrunInstanceId:t.instanceId}):await this.releaseRecoveredSession(e)}async releaseRecoveredSession(e){let t=m(e.backend);if(!t)return;let n=`provider=${f},leaseId=${e.leaseId}`,r=(t===`ios`?await this.limrun.iosInstances.list({labelSelector:n}):await this.limrun.androidInstances.list({labelSelector:n})).getPaginatedItems().map(e=>e.metadata.id);for(let e of r)t===`ios`?await this.limrun.iosInstances.delete(e):await this.limrun.androidInstances.delete(e);if(r.length!==0)return{limrunInstanceId:r[0],limrunInstanceCount:r.length}}async terminateSession(e){if(e.client.disconnect(),e.platform===`ios`){await this.limrun.iosInstances.delete(e.instanceId);return}await ne(e),await this.limrun.androidInstances.delete(e.instanceId)}getSessionForDevice(e){let t=g(e.id);if(!t)return;let n=this.sessions.get(t.leaseId);return n?.platform===t.platform?n:void 0}currentAppLogReader(e){let t=this.getSessionForDevice(e);if(!t)return;let n=q(t);return{platform:t.platform,leaseId:t.lease.leaseId,instanceId:t.instanceId,readLogs:async(e,t)=>n.platform===`ios`?await n.readLogs(e,t):await n.readLogs(t),[Symbol.asyncDispose]:async()=>void 0}}async reconnectAppLogReader(e,t){let{reconnectLimrunAppLogReader:n}=await import(`./app-log-reconnect.js`);return await n({limrun:this.limrun,descriptor:e,dependencies:this.dependencies,signal:t})}requireAndroidPortReverseSession(e){let t=this.sessions.get(e);if(!t||t.platform===`android`)return t;throw Q(`port reverse`,`Direct Limrun iOS sessions cannot reach local host ports; use a bridge public URL.`)}};async function ge(e,n,r){let{createLimrunPlatformRuntimeOwner:i}=await import(`./app-log-runtime.js`);return i({host:r,runtimeInstance:n,ownsDevice:t=>e.ownsDevice(t),hasLiveSession:t=>e.hasLiveSession(t),getInteractor:(t,n)=>e.getInteractor(t,n),openCurrent:async t=>e.currentAppLogReader(t),reconnect:async(t,n)=>await e.reconnectAppLogReader(t,n),listApps:async(n,r,i)=>{i.throwIfAborted();let a=e.getDeviceSession(n);if(!a)throw new t(`DEVICE_NOT_FOUND`,`Limrun app inventory session is unavailable`,{deviceId:n.id});return(await a.listApps(r)).map(e=>({id:e.id,name:e.name??e.id}))},getAppState:async(n,r)=>{r.throwIfAborted();let i=e.getDeviceSession(n);if(i?.platform!==`android`)throw new t(`UNSUPPORTED_OPERATION`,`Limrun Android appstate requires an active provider session`);let a=await i.getForegroundApp(r);return r.throwIfAborted(),{package:a?.appId,activity:a?.activity}},deployApp:async(t,n,r,i)=>await e.installApp(t,n.app,n.appPath,{relaunch:n.replaceExisting,appIdentifierHint:n.app,packageNameHint:n.app},r,i),deployMaterializedApp:async(t,n,r,i)=>await e.installInstallablePath(t,n.artifact.installablePath,{appIdentifierHint:n.artifact.bundleId,packageNameHint:n.artifact.packageName},r,i),configurePortReverse:async t=>await e.configurePortReverse(t)})}function _e(e){return{leaseId:e.leaseId,devicePort:e.devicePort,hostPort:e.hostPort,name:e.name}}function Q(e,n){throw new t(`UNSUPPORTED_OPERATION`,n,{command:e})}async function $(e){let n=new l({...X(e),timeout:15e3,maxRetries:0}),r={limit:1,...e.region?{region:e.region}:{}};try{e.platform===`android`?await n.androidInstances.list(r):await n.iosInstances.list(r)}catch(e){let n=ve(e);throw n===401||n===403?new t(`UNAUTHORIZED`,`Limrun rejected connection verification.`,{status:n,hint:`Check LIMRUN_API_KEY and its organization access.`}):new t(`COMMAND_FAILED`,`Limrun connection verification failed.`,{hint:`Check Limrun service access, LIMRUN_REGION, and network connectivity, then retry.`},e)}let i=e.platform===`android`?`Android`:`iOS`,a=e.platform===`android`?`emulator`:`simulator`;return{provider:`limrun`,service:`Limrun`,verificationMessage:`Credentials and ${i} instance access verified.`,device:{status:`deferred`,name:`Provider-selected ${i} ${a}`,platform:e.platform},app:{status:`missing`,message:`A new Limrun instance does not have your app yet.`}}}function ve(e){if(!e||typeof e!=`object`)return;let t=e.status;return typeof t==`number`?t:void 0}var ye=e({LIMRUN_PROVIDER:()=>f,createLimrunRuntime:()=>Z,verifyLimrunConnection:()=>$});export{te as a,y as i,$ as n,f as o,Z as r,g as s,ye as t};
|
|
1
|
+
import{r as e}from"./rolldown-runtime.js";import{y as t}from"./sdk-contracts.js";import{qt as n}from"./sdk-batch.js";import{c as r,i,s as a}from"./request-cancellation.js";import{t as o}from"./api.js";import{a as s,i as c,l,n as u,o as d,s as f,t as p}from"./device-session.js";import{scryptSync as m}from"node:crypto";const h=`agent-device-cli`;function g(e){return{apiKey:e.apiKey,defaultHeaders:{"x-agent-device-client":h,"x-agent-device-version":e.clientVersion}}}function _(e){if(e.runtimeInstance!==void 0){let t=e.runtimeInstance.trim();if(!t)throw TypeError(`Limrun runtimeInstance must be a non-empty string`);return t}let t=JSON.stringify({provider:`limrun`,region:e.region?.trim().toLowerCase()||`default`,apiKey:e.apiKey});return`principal-${m(t,`agent-device:limrun-runtime-owner:v1`,32,{N:16384,r:8,p:1,maxmem:67108864}).toString(`hex`)}`}function v(e,t,r){let a=new y(e,t);if(!r?.includePlatformModule)return a;let o=n(i,_(e));if(o.kind!==`provider-runtime`)throw TypeError(`Invalid Limrun runtime owner`);return Object.freeze({runtime:a,platformModule:Object.freeze({owner:o,loadRuntime:async e=>await b(a,o.instance,e)})})}var y=class{limrun;sessions=new Map;appAliases=new Map;options;dependencies;provider=i;leaseLifecycle={allocate:async(e,t)=>await this.allocate(e,t),release:async e=>await this.release(e)};appCatalog=async(e,t)=>{let{assertLimrunUploadedAppAccess:n,listLimrunAppAssets:r}=await import(`./app-catalog.js`);return n(e.publicNetworkOnly),(await r(this.limrun,e.platform,t)).map(e=>e.name)};recoverExpiredLease=async e=>{if(e.leaseProvider!==this.provider||!r(e.backend))throw new t(`UNSUPPORTED_OPERATION`,`Limrun cannot recover this expired lease.`,{leaseId:e.leaseId,leaseProvider:e.leaseProvider,leaseBackend:e.backend});await this.release(e)};deviceInventoryProvider=async e=>{if(e.leaseProvider!==this.provider||!e.leaseId)return null;let t=this.sessions.get(e.leaseId);return t?e.platform&&e.platform!==t.platform?[]:[t.device]:null};constructor(e,t){this.options=e,this.dependencies=t,this.limrun=new o(g({apiKey:e.apiKey,clientVersion:t.clientVersion}))}ownsDevice(e){return a(e.id)!==void 0}hasLiveSession(e){return this.getSessionForDevice(e)!==void 0}getInteractor(e,t){let n=this.getSessionForDevice(e);if(n)return n.platform===`ios`?u(n):f(n)}getDeviceSession(e){let t=this.getSessionForDevice(e);return t?p(t):void 0}async installApp(e,t,n,r,i,a){return await this.installInstallablePath(e,n,{...r,appIdentifierHint:r?.appIdentifierHint??t,packageNameHint:r?.packageNameHint??t},i,a)}async installInstallablePath(e,t,n,r,i){let a=this.getSessionForDevice(e);if(a)return a.platform===`ios`?await c(this.limrun,a,t,n,r,i):await l(this.limrun,a,t,n,r,i)}async configurePortReverse(e){let t=this.requireAndroidPortReverseSession(e.leaseId);if(t)return await d(t,e),x(e)}async shutdown(){let e=[...this.sessions.values()];await Promise.allSettled(e.map(async e=>await this.terminateSession(e))),this.sessions.clear(),this.appAliases.clear()}async allocate(e,t){if(e.leaseProvider!==this.provider)return;let n=r(e.backend);if(!n)return;let i=this.sessions.get(e.leaseId);if(i)return{limrunInstanceId:i.instanceId,device:i.device};let{allocateLimrunAndroidSession:a,allocateLimrunIosSession:o,resolvePreinstalledAppId:s,resolveRequestedLimrunAppAsset:c}=await import(`./session-allocation.js`),l=await c(this.limrun,n,t),u=n===`ios`?await o(this.sessionAllocationParams(e,l)):await a(this.sessionAllocationParams(e,l));if(l)try{let t=await s(u,l);this.appAliases.set(e.leaseId,{assetName:l.name,installedAppId:t})}catch(e){throw await this.terminateSession(u),e}return this.sessions.set(e.leaseId,u),{limrunInstanceId:u.instanceId,device:u.device}}sessionAllocationParams(e,t){return{limrun:this.limrun,lease:e,metadata:this.buildInstanceMetadata(e),region:this.options.region,app:t,dependencies:this.dependencies}}buildInstanceMetadata(e){return{displayName:`agent-device-${e.tenantId}-${e.runId}`,labels:{tenantId:e.tenantId,runId:e.runId,leaseId:e.leaseId,provider:e.leaseProvider??`limrun`,source:h}}}async release(e){let t=this.sessions.get(e.leaseId);return t?(await this.terminateSession(t),this.sessions.delete(e.leaseId),this.appAliases.delete(e.leaseId),{limrunInstanceId:t.instanceId}):await this.releaseRecoveredSession(e)}async releaseRecoveredSession(e){let t=r(e.backend);if(!t)return;let n=`provider=${i},leaseId=${e.leaseId}`,a=(t===`ios`?await this.limrun.iosInstances.list({labelSelector:n}):await this.limrun.androidInstances.list({labelSelector:n})).getPaginatedItems().map(e=>e.metadata.id);for(let e of a)t===`ios`?await this.limrun.iosInstances.delete(e):await this.limrun.androidInstances.delete(e);if(a.length!==0)return{limrunInstanceId:a[0],limrunInstanceCount:a.length}}async terminateSession(e){if(e.client.disconnect(),e.platform===`ios`){await this.limrun.iosInstances.delete(e.instanceId);return}await s(e),await this.limrun.androidInstances.delete(e.instanceId)}getSessionForDevice(e){let t=a(e.id);if(!t)return;let n=this.sessions.get(t.leaseId);return n?.platform===t.platform?n:void 0}resolveAppReference(e,t){let n=a(e.id);if(!n)return t;let r=this.appAliases.get(n.leaseId);return r?.assetName===t?r.installedAppId:t}currentAppLogReader(e){let t=this.getSessionForDevice(e);if(!t)return;let n=p(t);return{platform:t.platform,leaseId:t.lease.leaseId,instanceId:t.instanceId,readLogs:async(e,t)=>n.platform===`ios`?await n.readLogs(e,t):await n.readLogs(t),[Symbol.asyncDispose]:async()=>void 0}}async reconnectAppLogReader(e,t){let{reconnectLimrunAppLogReader:n}=await import(`./app-log-reconnect.js`);return await n({limrun:this.limrun,descriptor:e,dependencies:this.dependencies,signal:t})}requireAndroidPortReverseSession(e){let t=this.sessions.get(e);if(!t||t.platform===`android`)return t;throw S(`port reverse`,`Direct Limrun iOS sessions cannot reach local host ports; use a bridge public URL.`)}};async function b(e,n,r){let{createLimrunPlatformRuntimeOwner:i}=await import(`./app-log-runtime2.js`);return i({host:r,runtimeInstance:n,ownsDevice:t=>e.ownsDevice(t),hasLiveSession:t=>e.hasLiveSession(t),getInteractor:(t,n)=>e.getInteractor(t,n),resolveAppReference:(t,n)=>e.resolveAppReference(t,n),openCurrent:async t=>e.currentAppLogReader(t),reconnect:async(t,n)=>await e.reconnectAppLogReader(t,n),listApps:async(n,r,i)=>{i.throwIfAborted();let a=e.getDeviceSession(n);if(!a)throw new t(`DEVICE_NOT_FOUND`,`Limrun app inventory session is unavailable`,{deviceId:n.id});return(await a.listApps(r)).map(e=>({id:e.id,name:e.name??e.id}))},getAppState:async(n,r)=>{r.throwIfAborted();let i=e.getDeviceSession(n);if(i?.platform!==`android`)throw new t(`UNSUPPORTED_OPERATION`,`Limrun Android appstate requires an active provider session`);let a=await i.getForegroundApp(r);return r.throwIfAborted(),{package:a?.appId,activity:a?.activity}},deployApp:async(t,n,r,i)=>await e.installApp(t,n.app,n.appPath,{relaunch:n.replaceExisting,appIdentifierHint:n.app,packageNameHint:n.app},r,i),deployMaterializedApp:async(t,n,r,i)=>await e.installInstallablePath(t,n.artifact.installablePath,{appIdentifierHint:n.artifact.bundleId,packageNameHint:n.artifact.packageName},r,i),configurePortReverse:async t=>await e.configurePortReverse(t)})}function x(e){return{leaseId:e.leaseId,devicePort:e.devicePort,hostPort:e.hostPort,name:e.name}}function S(e,n){throw new t(`UNSUPPORTED_OPERATION`,n,{command:e})}async function C(e){let n=new o({...g(e),timeout:15e3,maxRetries:0}),r={limit:1,...e.region?{region:e.region}:{}};try{e.platform===`android`?await n.androidInstances.list(r):await n.iosInstances.list(r)}catch(e){let n=w(e);throw n===401||n===403?new t(`UNAUTHORIZED`,`Limrun rejected connection verification.`,{status:n,hint:`Check LIMRUN_API_KEY and its organization access.`}):new t(`COMMAND_FAILED`,`Limrun connection verification failed.`,{hint:`Check Limrun service access, LIMRUN_REGION, and network connectivity, then retry.`},e)}let i=e.platform===`android`?`Android`:`iOS`,a=e.platform===`android`?`emulator`:`simulator`;return{provider:`limrun`,service:`Limrun`,verificationMessage:`Credentials and ${i} instance access verified.`,device:{status:`deferred`,name:`Provider-selected ${i} ${a}`,platform:e.platform},app:{status:`missing`,message:`Run apps to choose an uploaded asset before allocation.`}}}function w(e){if(!e||typeof e!=`object`)return;let t=e.status;return typeof t==`number`?t:void 0}var T=e({LIMRUN_PROVIDER:()=>i,createLimrunRuntime:()=>v,verifyLimrunConnection:()=>C});export{C as n,v as r,T as t};
|