agent-device 0.21.24 → 0.21.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.25.apk +0 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.25.apk.sha256 +1 -0
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.24.manifest.json → agent-device-android-ime-helper-0.21.25.manifest.json} +4 -4
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.25.apk +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.25.apk.sha256 +1 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.25.manifest.json +16 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +159 -4
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerHttpRequestFraming.swift +139 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerListenerPeer.swift +41 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerListenerToken.swift +25 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Environment.swift +18 -11
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Navigation.swift +25 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedTextEntry.swift +0 -3
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +1 -3
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryConfirmation.swift +59 -26
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextTyping.swift +47 -103
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Transport.swift +142 -54
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TypeExecution.swift +4 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +21 -19
- package/dist/src/absence-observation-errors.js +1 -0
- package/dist/src/adapter.js +1 -1
- package/dist/src/adb-executor.js +2 -2
- package/dist/src/adb-failure.js +2 -2
- package/dist/src/agent-browser-lifecycle.js +1 -1
- package/dist/src/agent-browser-process-record.js +1 -1
- package/dist/src/agent-browser-provider.js +1 -1
- package/dist/src/agent-browser-tool.js +1 -1
- package/dist/src/agent-device-client.js +2 -2
- package/dist/src/android-adb.js +1 -1
- package/dist/src/android-input-ownership.js +1 -1
- package/dist/src/android-system-surface-disclosure.js +1 -0
- package/dist/src/android-text-entry.js +1 -0
- package/dist/src/android.js +1 -1
- package/dist/src/app-backend.js +1 -1
- package/dist/src/app-helpers.js +1 -1
- package/dist/src/app-launch.js +1 -1
- package/dist/src/app-lifecycle.js +4 -3
- package/dist/src/app-lifecycle2.js +2 -2
- package/dist/src/app-log-files.js +1 -1
- package/dist/src/app-log-reconnect.js +1 -1
- package/dist/src/app-log-runtime2.js +3 -3
- package/dist/src/app-resolution-facade.js +1 -1
- package/dist/src/app-resolution.js +2 -2
- package/dist/src/apple-runner-platform.js +1 -1
- package/dist/src/artifact-download.js +1 -1
- package/dist/src/auth.js +1 -1
- package/dist/src/aws-device-farm-connection.js +1 -1
- package/dist/src/back-mode.js +1 -1
- package/dist/src/boot-diagnostics.js +1 -1
- package/dist/src/browserstack-connection.js +1 -1
- package/dist/src/capture-disclosure.js +1 -0
- package/dist/src/cli-config.js +1 -1
- package/dist/src/cli-help.js +17 -14
- package/dist/src/cli-output.js +1 -1
- package/dist/src/cli-runner.js +3 -1
- package/dist/src/cli.js +3 -3
- package/dist/src/client-companion-tunnel.js +1 -1
- package/dist/src/client-metro.js +1 -1
- package/dist/src/client-types.d.ts +8 -2
- package/dist/src/code-signature-cache.js +1 -1
- package/dist/src/code-signature.js +1 -1
- package/dist/src/command-metadata.js +73 -1
- package/dist/src/command-policy.js +1 -0
- 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/connection-runtime.js +1 -1
- package/dist/src/connection-verification.js +1 -1
- package/dist/src/connection.js +3 -3
- package/dist/src/contracts.js +1 -1
- package/dist/src/daemon-client-lease-beat.js +1 -1
- package/dist/src/daemon-client-lifecycle.js +1 -1
- package/dist/src/daemon-client-liveness-probe.js +1 -1
- package/dist/src/daemon-policy-file.js +1 -1
- package/dist/src/daemon-registration-owner.js +1 -1
- package/dist/src/daemon-registration.js +1 -1
- package/dist/src/daemon-resolution.js +3 -1
- package/dist/src/debug-symbols-facade.js +1 -1
- package/dist/src/device-claim-inspection.js +1 -1
- package/dist/src/device-input-state.d.ts +5 -3
- package/dist/src/device-inventory-context.js +1 -1
- package/dist/src/device-readiness-runtime.js +1 -1
- package/dist/src/device-release.js +1 -1
- package/dist/src/device-shell.js +1 -1
- package/dist/src/device.js +3 -1
- package/dist/src/devicectl.js +1 -1
- package/dist/src/diagnostics.js +1 -1
- package/dist/src/doctor-facade.js +1 -1
- package/dist/src/durable-capture-resource.js +1 -1
- package/dist/src/durable-resource.js +1 -1
- package/dist/src/engine-eval-script.js +1 -1
- package/dist/src/error.js +1 -1
- package/dist/src/exec.js +1 -1
- package/dist/src/expo-dev-client-launch.js +1 -0
- package/dist/src/file.js +3 -1
- package/dist/src/find.js +1 -1
- package/dist/src/finders.js +1 -1
- package/dist/src/generic-settle.js +1 -1
- package/dist/src/generic.js +1 -1
- package/dist/src/gesture-plan.js +1 -1
- package/dist/src/gesture-runtime.js +1 -1
- package/dist/src/harmonyos.js +1 -1
- package/dist/src/hdc.js +1 -1
- package/dist/src/helper.js +2 -2
- package/dist/src/human-control.js +1 -1
- package/dist/src/ime-rebind.js +1 -1
- package/dist/src/ime-state.js +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/input-actions.js +1 -1
- package/dist/src/input-actions2.js +2 -2
- package/dist/src/install-source-network-transport.js +1 -1
- package/dist/src/install-source2.js +1 -1
- package/dist/src/interaction-error.js +1 -0
- package/dist/src/interaction-positionals.js +1 -1
- package/dist/src/interaction.js +1 -1
- package/dist/src/interaction2.js +1 -1
- package/dist/src/interactor-operation-catalog.js +1 -1
- package/dist/src/interactor.js +5 -5
- package/dist/src/interactor2.js +1 -1
- package/dist/src/internal/bin.js +1 -1
- package/dist/src/internal/daemon.js +5 -1
- package/dist/src/internal/png-worker.js +1 -1
- package/dist/src/inventory.js +2 -2
- package/dist/src/inventory6.js +1 -1
- package/dist/src/io.d.ts +2 -2
- package/dist/src/ios-client.js +1 -1
- package/dist/src/ios-settings.js +1 -1
- package/dist/src/ios-snapshot-acquisition.js +1 -1
- package/dist/src/ios-snapshot-adapter.js +1 -1
- package/dist/src/ios-snapshot-engine.js +1 -1
- package/dist/src/ios-snapshot-runtime.js +1 -1
- package/dist/src/keyed-lock.js +1 -1
- package/dist/src/launch-confirmation.js +1 -1
- package/dist/src/lease.js +1 -1
- package/dist/src/limrun-runtime-dependencies.js +1 -1
- package/dist/src/limrun.d.ts +2 -10
- package/dist/src/limrun.js +1 -1
- package/dist/src/linux.js +1 -1
- package/dist/src/load.js +1 -1
- package/dist/src/local-interactor-operation-set.js +1 -1
- package/dist/src/log-stream.js +9 -9
- package/dist/src/mechanics.js +16 -16
- 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/observability.js +1 -1
- package/dist/src/open-target-resolution.js +1 -1
- package/dist/src/output-path.js +1 -1
- package/dist/src/overlay.js +1 -3
- package/dist/src/perf-facade.js +1 -1
- package/dist/src/perf-runtime-operation-builder.js +1 -1
- package/dist/src/perf-runtime.js +1 -1
- package/dist/src/physical-device-control.js +1 -1
- package/dist/src/platform-request-scope.js +1 -1
- package/dist/src/platform-runtime-android-adb-host.js +1 -1
- package/dist/src/platform-runtime-app-log-android-transport.js +1 -1
- package/dist/src/platform-runtime-apple-resources.js +1 -0
- package/dist/src/platform-runtime-claim-recovery.js +1 -0
- package/dist/src/platform-runtime-daemon-services.js +1 -0
- package/dist/src/platform-runtime-host.js +1 -1
- 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-transport.js +1 -1
- package/dist/src/platform-runtime-screen-recording-apple-simulator-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-harmony-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-web-host.js +1 -1
- package/dist/src/platform-runtime-unavailable.js +1 -1
- package/dist/src/platform-runtime.js +1 -1
- package/dist/src/platform-runtime2.js +1 -1
- package/dist/src/plugin.js +1 -1
- package/dist/src/png-crop-bytes.js +1 -1
- package/dist/src/png-resize.js +1 -0
- package/dist/src/png-worker-client.js +1 -1
- package/dist/src/png-worker-contract.js +1 -1
- package/dist/src/process-entry.js +1 -1
- package/dist/src/process.js +1 -1
- package/dist/src/provider-credential-fingerprint.js +1 -1
- package/dist/src/provider-device-admission.js +1 -1
- package/dist/src/provider-policy.js +1 -1
- package/dist/src/provider-webdriver.js +1 -1
- package/dist/src/proxy.js +2 -2
- package/dist/src/quality-warnings.js +1 -1
- package/dist/src/react-native-overlay2.js +3 -0
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-runtime.js +1 -1
- package/dist/src/record-trace.js +1 -1
- package/dist/src/recording.js +2 -2
- package/dist/src/register-builtins.js +1 -1
- package/dist/src/remote-config-core.js +1 -1
- package/dist/src/replay-backend-registry.js +1 -0
- package/dist/src/replay-divergence.js +1 -1
- package/dist/src/replay-maestro-backend.js +117 -0
- package/dist/src/replay-script-selection.js +1 -0
- package/dist/src/replay.js +1 -3
- package/dist/src/replay2.js +1 -0
- package/dist/src/reporting.js +3 -3
- package/dist/src/request-cancel.js +1 -1
- package/dist/src/request-providers.js +1 -1
- package/dist/src/request-runtime-binding.js +1 -1
- package/dist/src/result-serialization.js +1 -1
- package/dist/src/retry.js +1 -1
- package/dist/src/runner-cache-retention.js +1 -1
- package/dist/src/runner-cache-trim.js +1 -1
- package/dist/src/runner-client.js +1 -1
- package/dist/src/runner-dev-tools-security.js +1 -1
- package/dist/src/runner-device-readiness.js +1 -1
- package/dist/src/runner-device-set.js +1 -1
- package/dist/src/runner-error-classification.js +3 -3
- package/dist/src/runner-exchange.js +1 -1
- package/dist/src/runner-lease.js +1 -1
- package/dist/src/runner-operations-facade.js +1 -1
- package/dist/src/runner-retention.js +1 -0
- package/dist/src/runner-start-budget.js +1 -1
- package/dist/src/runner-startup-transport.js +1 -0
- package/dist/src/runner-toolchain-probe.js +1 -1
- package/dist/src/runner.js +2 -1
- package/dist/src/runtime-command-surface.js +1 -0
- package/dist/src/runtime-deployment.js +1 -1
- package/dist/src/runtime-factory.js +1 -0
- package/dist/src/runtime-session.js +1 -0
- package/dist/src/runtime-transport-hints.js +1 -1
- package/dist/src/runtime.js +2 -1
- package/dist/src/runtime10.js +2 -1
- package/dist/src/runtime2.js +5 -2
- package/dist/src/runtime3.js +1 -5
- package/dist/src/runtime4.js +5 -1
- package/dist/src/runtime5.js +1 -5
- 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/screenshot-image.js +1 -1
- package/dist/src/screenshot-runtime.js +1 -0
- package/dist/src/screenshot3.js +5 -5
- package/dist/src/sdk-batch-runner.js +2 -2
- package/dist/src/sdk-batch.js +1 -1
- package/dist/src/sdk-contracts.js +2 -2
- package/dist/src/sdk-finders.js +1 -1
- package/dist/src/sdk-io.d.ts +4 -2
- package/dist/src/sdk-selectors.d.ts +4 -5
- package/dist/src/sdk-selectors.js +1 -1
- package/dist/src/selection.js +0 -0
- package/dist/src/selector-pipeline-policy.js +1 -1
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/selectors.js +1 -1
- package/dist/src/server.js +2 -2
- package/dist/src/session-allocation.js +1 -1
- package/dist/src/session-replay-runtime-failure-response.js +1 -0
- package/dist/src/session-runtime-admission.js +1 -0
- package/dist/src/session.js +1 -1
- package/dist/src/session2.js +5 -5
- package/dist/src/settings.js +1 -1
- package/dist/src/settings2.js +1 -1
- package/dist/src/simctl-settings.js +1 -1
- package/dist/src/simulator.js +1 -1
- package/dist/src/snapshot-chrome.js +1 -0
- package/dist/src/snapshot-desktop-projection.js +1 -1
- package/dist/src/snapshot-evidence.js +1 -0
- package/dist/src/snapshot-node-lookup.js +1 -0
- package/dist/src/snapshot-occlusion.js +1 -0
- package/dist/src/snapshot-quality-verdict.js +1 -0
- package/dist/src/snapshot-runtime-binding.js +1 -1
- package/dist/src/snapshot-runtime.js +1 -1
- package/dist/src/snapshot-state.js +1 -1
- package/dist/src/snapshot.js +1 -1
- package/dist/src/snapshot2.js +1 -1
- package/dist/src/snapshot3.js +1 -1
- package/dist/src/src.js +5 -1
- package/dist/src/src2.js +1 -1
- package/dist/src/src3.js +2 -1
- package/dist/src/store.js +1 -1
- package/dist/src/surface-snapshot2.js +1 -1
- package/dist/src/target-evidence-tree.js +1 -0
- package/dist/src/target-evidence.js +1 -1
- package/dist/src/text-entry-focus.js +1 -1
- package/dist/src/tool-provider2.js +1 -1
- package/dist/src/touch-runtime.js +1 -1
- package/dist/src/touch-runtime2.js +1 -1
- package/dist/src/tree.js +1 -1
- package/dist/src/tv-remote.js +1 -1
- package/dist/src/type-text-runtime.js +1 -1
- package/dist/src/undici.js +8 -8
- package/dist/src/update-check.js +1 -1
- package/dist/src/vars.js +2 -0
- package/dist/src/version.js +1 -1
- package/dist/src/video.js +2 -2
- package/dist/src/wait.js +1 -0
- package/dist/src/web.js +1 -1
- package/dist/src/web2.js +1 -1
- package/package.json +9 -11
- package/server.json +2 -2
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.24.apk +0 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.24.apk.sha256 +0 -1
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.24.apk +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.24.apk.sha256 +0 -1
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.24.manifest.json +0 -16
- package/dist/src/adb-transport.js +0 -1
- package/dist/src/alert-runtime.js +0 -1
- package/dist/src/app-deployment-resolution.js +0 -2
- package/dist/src/app-inventory-contract.js +0 -1
- package/dist/src/app-log-session-resource.js +0 -1
- package/dist/src/application-lifecycle-runtime.js +0 -1
- package/dist/src/auth-session.js +0 -1
- package/dist/src/browserstack-device-features.js +0 -1
- package/dist/src/browserstack.js +0 -1
- package/dist/src/cache.js +0 -1
- package/dist/src/capture.js +0 -1
- package/dist/src/catalog.js +0 -1
- package/dist/src/click-button.js +0 -1
- package/dist/src/client-metro-companion.js +0 -1
- package/dist/src/client-options.js +0 -3
- package/dist/src/daemon-client-transport.js +0 -1
- package/dist/src/daemon-http.js +0 -1
- package/dist/src/device-rotation.js +0 -1
- package/dist/src/device-session.js +0 -3
- package/dist/src/device2.js +0 -1
- package/dist/src/device3.js +0 -3
- package/dist/src/dispatch-resolve.js +0 -4
- package/dist/src/format.js +0 -2
- package/dist/src/gesture-plan-types.js +0 -1
- package/dist/src/host.js +0 -1
- package/dist/src/ime-settings-record.js +0 -1
- package/dist/src/interaction-ref-policy.js +0 -1
- package/dist/src/interactor-operation-binding.js +0 -1
- package/dist/src/keyboard-actions.js +0 -1
- package/dist/src/lease-context.js +0 -1
- package/dist/src/lease-registry-scope.js +0 -1
- package/dist/src/lease-scope.js +0 -1
- package/dist/src/managed-device-scope.js +0 -1
- package/dist/src/manifest.js +0 -1
- package/dist/src/observe-until.js +0 -1
- package/dist/src/output-common.js +0 -5
- package/dist/src/owner-identity.js +0 -3
- package/dist/src/path-resolution.js +0 -1
- package/dist/src/perf-runtime-plan.js +0 -1
- package/dist/src/platform-runtime-app-log-process.js +0 -1
- package/dist/src/platform-runtime-managed-owner.js +0 -1
- package/dist/src/platform-runtime-screen-recording-process-host.js +0 -1
- package/dist/src/png.js +0 -1
- package/dist/src/provider-session-ownership.js +0 -2
- package/dist/src/providers.js +0 -1
- package/dist/src/registry.js +0 -68
- package/dist/src/remote-connection-state.js +0 -1
- package/dist/src/request-admission.js +0 -1
- package/dist/src/request-cancellation.js +0 -1
- package/dist/src/request-progress-protocol.js +0 -1
- package/dist/src/runner-cache-metadata.js +0 -2
- package/dist/src/runner-disposal.js +0 -1
- package/dist/src/runner-session-types.js +0 -1
- package/dist/src/runtime-admission.js +0 -1
- package/dist/src/runtime11.js +0 -2
- package/dist/src/screen-recording-resource-recovery.js +0 -1
- package/dist/src/screenshot-result.js +0 -1
- package/dist/src/script.js +0 -1
- package/dist/src/scroll-command.js +0 -1
- package/dist/src/scroll-gesture.js +0 -1
- package/dist/src/scroll-indicator.js +0 -1
- package/dist/src/session-artifact-paths.js +0 -1
- package/dist/src/session-paths.js +0 -1
- package/dist/src/session-repair-tombstone.js +0 -1
- package/dist/src/session-snapshot.js +0 -1
- package/dist/src/snapshot-private-evidence.js +0 -1
- package/dist/src/snapshot4.js +0 -1
- package/dist/src/src4.js +0 -1
- package/dist/src/src5.js +0 -1
- package/dist/src/src6.js +0 -1
- package/dist/src/src7.js +0 -2
- package/dist/src/src8.js +0 -115
- package/dist/src/string-enum.js +0 -1
- package/dist/src/success-text.js +0 -1
- package/dist/src/transport.js +0 -3
- package/dist/src/ttl-memo.js +0 -1
- package/dist/src/verified-file.js +0 -1
- package/dist/src/window-state.js +0 -1
- /package/dist/src/{doctor-output.js → doctor-lines.js} +0 -0
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{
|
|
2
|
-
`).toLowerCase()}function
|
|
3
|
-
`).some(e=>t.every(t=>e.includes(t)))}function G(e,t){if(e instanceof n){for(let n of H)if(n.verdicts[t]!==void 0&&U(e,n.match))return n.verdicts[t]}}function
|
|
1
|
+
import{K as e,L as t,P as n,it as r}from"./sdk-contracts.js";import{i}from"./alert-contract.js";import{D as a,M as o,w as s}from"./apple-runner-platform.js";import c from"node:crypto";const l=`RUNNER_BUSY`,u=`RUNNER_WEDGED`,d=`APP_NOT_RUNNING`;function ee(e){let t=s(e.requestId);return e.signal?!t||t===e.signal?e.signal:AbortSignal.any([t,e.signal]):t}function f(e){return e instanceof DOMException&&e.name===`TimeoutError`}function te(e){return o(e.requestId)||s(e.requestId)?.aborted?!1:e.signal?.aborted===!0&&f(e.signal.reason)}function ne(e){let t=s(e.requestId),n=e.signal;if(!n||n===t)return t;let r=new AbortController,i=()=>{f(n.reason)||r.abort(n.reason)};return n.aborted?i():n.addEventListener(`abort`,i,{once:!0}),t?AbortSignal.any([t,r.signal]):r.signal}const p=`SCROLL_KEYBOARD_OCCLUDES_SURFACE`,m=new Set([`APP_SCREEN_WINDOW_UNRESOLVED`,`APP_SCREEN_UNRESOLVED`,`APP_SCREEN_CAPTURE_UNRENDERABLE`]),re=new Map([[l,{retriable:!0,reason:`runner_busy`}],[`MAIN_THREAD_TIMEOUT`,{reason:`runner_main_thread_timeout`}],[d,{retriable:!0}],[i,{}],[p,{}],...[...m].map(e=>[e,{}])]),ie=new Map([[`INVALID_ARGS`,`no`],[`ELEMENT_NOT_FOUND`,`no`],[`ELEMENT_OFFSCREEN`,`no`],[`AMBIGUOUS_MATCH`,`no`],[l,`no`],[u,`no`],[d,`no`],[`OBSERVATION_UNAVAILABLE`,`no`],[p,`no`],[i,`no`],...[...m].map(e=>[e,`no`])]);function h(e){let t=e===void 0?void 0:re.get(e);return Object.freeze({code:t?`COMMAND_FAILED`:r(e),details:Object.freeze({runnerErrorCode:e,...t,dispatched:(e===void 0?void 0:ie.get(e))??`unknown`})})}function ae(e){let t;try{t=JSON.parse(e)}catch{throw new n(`COMMAND_FAILED`,`Invalid runner response`,{text:e})}if(!oe(t))throw new n(`COMMAND_FAILED`,`Invalid runner response`,{text:e});return t}function oe(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function g(e){return e.ok===!0}function _(e){return!e.data||typeof e.data!=`object`||Array.isArray(e.data)?{}:e.data}function v(e,t){let r=y(e.error?.code),i=typeof e.error?.message==`string`?e.error.message:void 0,a=typeof e.error?.hint==`string`?e.error.hint:void 0,o=h(r);return new n(o.code,i??`Runner error`,{runner:e,...o.details,xcodebuild:{exitCode:1,stdout:``,stderr:``},hint:a,logPath:t})}function y(e){return typeof e==`string`&&e.trim().length>0?e.trim():void 0}function se(e){return e.command===`status`||e.commandId?.trim()?e:{...e,commandId:ce()}}function ce(){return`runner-${c.randomUUID()}`}function le(e){if(o(e))throw t()}const b=`runner_token_unsupported`;function ue(){return c.randomBytes(24).toString(`base64url`)}function de(e){return{AGENT_DEVICE_RUNNER_PORT:String(e.port),AGENT_DEVICE_RUNNER_TOKEN:e.token}}function fe(e){return{"Content-Type":`application/json`,"X-Agent-Device-Runner-Token":e.token}}function pe(e){if(e.headers.get(`X-Agent-Device-Runner-Auth`)===`required`)return e;throw new n(`COMMAND_FAILED`,`XCTest runner does not require a listener token`,{reason:b,hint:`Rebuild the runner with this agent-device version. A configured iosXctestrunFile must come from the same version.`})}const x={readOnly:!1,readinessProbe:!1,readinessPreflightExempt:!1,readinessPreflightSkipEligibleAfterHealthyMutation:!1},S={...x,readinessPreflightExempt:!0},C={...x,readOnly:!0},w={...C,readinessProbe:!0},T={...x,readinessPreflightSkipEligibleAfterHealthyMutation:!0},me={tap:T,mouseClick:x,longPress:T,drag:T,remotePress:x,type:x,swipe:T,scroll:T,desktopScroll:T,findText:C,querySelector:C,readText:C,snapshot:C,screenshot:C,backInApp:x,backSystem:x,home:x,rotate:x,gesture:T,gestureViewport:C,appSwitcher:x,actionButton:x,keyboardDismiss:x,keyboardReturn:x,alert:e=>(e.action??`get`).toLowerCase()===`get`?C:x,sequence:T,recordStart:x,recordStop:x,status:w,uptime:w,appState:C,pasteboardWrite:x,activate:S,terminate:S,targetReset:S,shutdown:x};function E(e){return k(e).readOnly}function he(e){return k(e).readinessProbe}function D(e){return k(e).readinessPreflightExempt}function O(e){return k(e).readinessPreflightSkipEligibleAfterHealthyMutation}function k(e){let t=me[e.command];return typeof t==`function`?t(e):t}const A="If runner build products look stale or corrupted, run `pnpm clean:xcuitest` in a local checkout, or remove ~/.agent-device/apple-runner/derived, then retry.";function j(e){return{runnerConnectFailureReason:e}}const M=`runner_reply_lost`,N=e=>e.reason===M,P=e=>e.reason===b,F=e=>e.runnerErrorCode===l,I=e=>typeof e.devToolsSecurityStatus==`string`,L=e=>typeof e.simulatorSetPath==`string`,R=e=>e.usbmuxDeviceAttached===!1,z=e=>t=>t.runnerConnectFailureReason===e,ge=t=>t.runnerReadinessPreflightFailed===!0&&!e(t),B=`build_failed_unclassified`,V={reason:`signing_provisioning_profile_missing`,hint:`Install/select a valid iOS provisioning profile, or set AGENT_DEVICE_IOS_PROVISIONING_PROFILE.`},H=[{reason:M,match:{code:`COMMAND_FAILED`,details:N},verdicts:{retryable:!1,drainResend:!1,connectRetry:!1,restartBeforeSend:!1,restartAfterReadinessPreflight:!1}},{reason:b,match:{code:`COMMAND_FAILED`,details:P},verdicts:{retryable:!1,drainResend:!1,connectRetry:!1,sessionFatalReason:b,restartBeforeSend:!1,restartAfterReadinessPreflight:!1,artifactSuspect:!1}},{reason:`usbmux_device_unattached`,match:{code:`DEVICE_NOT_FOUND`,details:R},verdicts:{connectRetry:!1}},{reason:`runner_busy_refusal`,match:{code:`COMMAND_FAILED`,details:F},verdicts:{retryable:!0,connectRetry:!0,drainResend:!0}},{reason:`xcodebuild_exited_early`,match:{code:`COMMAND_FAILED`,details:z(`xcodebuild_exited_early`)},verdicts:{retryable:!1,connectRetry:!1,artifactSuspect:!1}},{reason:`device_busy_connecting`,match:{code:`COMMAND_FAILED`,foreignMessageIncludesAll:[`device is busy`,`connecting`]},verdicts:{retryable:!1,connectRetry:!1}},{reason:`runner_readiness_preflight_failed`,match:{code:`COMMAND_FAILED`,details:ge},verdicts:{restartAfterReadinessPreflight:!0}},{reason:`runner_connect_refused`,match:{code:`COMMAND_FAILED`,details:z(`runner_connect_refused`)},verdicts:{retryable:!0,connectRetry:!0,restartBeforeSend:!0,artifactSuspect:!0}},{reason:`runner_endpoint_probe_exhausted`,match:{code:`COMMAND_FAILED`,details:z(`runner_endpoint_probe_exhausted`)},verdicts:{artifactSuspect:!0}},{reason:`fetch_failed`,match:{code:`COMMAND_FAILED`,foreignMessageIncludesAll:[`fetch failed`]},verdicts:{retryable:!0,connectRetry:!0}},{reason:`econnrefused`,match:{code:`COMMAND_FAILED`,foreignMessageIncludesAll:[`econnrefused`]},verdicts:{retryable:!0,connectRetry:!0}},{reason:`socket_hang_up`,match:{code:`COMMAND_FAILED`,foreignMessageIncludesAll:[`socket hang up`]},verdicts:{retryable:!0,connectRetry:!0}},{reason:`ax_snapshot_failure`,match:{code:`IOS_AX_SNAPSHOT_FAILED`},verdicts:{sessionFatalReason:`ax_snapshot_failure`}},{reason:`xctest_recorded_failure`,match:{code:`XCTEST_RECORDED_FAILURE`},verdicts:{sessionFatalReason:`xctest_recorded_failure`}},{reason:`runner_main_thread_wedged`,match:{code:u},verdicts:{sessionFatalReason:`runner_main_thread_wedged`}},{reason:`simulator_set_destination_not_found`,match:{toolTextIncludesAll:[`matching the provided destination specifier`],details:L},verdicts:{},buildFailure:{reason:`simulator_set_destination_not_found`,hint:"Check that the simulator still exists in the --ios-simulator-device-set this error names (`xcrun simctl --set <set> list devices`). If it does, the Xcode this error names no longer honors -DVTSimulatorSetLocation, so use a simulator in the default set."}},{reason:`bundle_identifier_registration_failed`,match:{toolTextIncludesAll:[`failed registering bundle identifier`]},verdicts:{},buildFailure:{reason:`bundle_identifier_already_registered`,hint:`Set AGENT_DEVICE_IOS_BUNDLE_ID to a unique reverse-DNS value (for example, com.yourname.agentdevice.runner), then retry.`}},{reason:`bundle_identifier_unavailable`,match:{toolTextLineIncludesAll:[`app identifier`,`not available`]},verdicts:{},buildFailure:{reason:`bundle_identifier_already_registered`,hint:`Set AGENT_DEVICE_IOS_BUNDLE_ID to a unique reverse-DNS value (for example, com.yourname.agentdevice.runner), then retry.`}},{reason:`signing_requires_development_team`,match:{toolTextIncludesAll:[`requires a development team`]},verdicts:{},buildFailure:{reason:`signing_no_development_team`,hint:`Configure signing in Xcode or set AGENT_DEVICE_IOS_TEAM_ID for physical-device runs.`}},{reason:`conflicting_provisioning_settings_unproven`,match:{toolTextIncludesAll:[`conflicting provisioning settings`]},verdicts:{},buildFailure:{reason:B,hint:A}},{reason:`signing_no_profiles_for_bundle_id`,match:{toolTextIncludesAll:[`no profiles for`]},verdicts:{},buildFailure:V},{reason:`signing_provisioning_profile_xcode_error`,match:{toolTextLineIncludesAll:[`provisioning profile`,`ideprovisioningerrordomain`]},verdicts:{},buildFailure:V},{reason:`signing_provisioning_profile_does_not_cover`,match:{toolTextLineIncludesAll:[`provisioning profile`,`doesn't include`]},verdicts:{},buildFailure:V},{reason:`signing_provisioning_profile_expired`,match:{toolTextLineIncludesAll:[`provisioning profile`,`has expired`]},verdicts:{},buildFailure:V},{reason:`signing_unspecified`,match:{toolTextIncludesAll:[`code signing`]},verdicts:{},buildFailure:{reason:`signing_unspecified`,hint:`Enable Automatic Signing in Xcode or provide AGENT_DEVICE_IOS_TEAM_ID and optional AGENT_DEVICE_IOS_SIGNING_IDENTITY.`}},{reason:`devtools_security_refused`,match:{code:`COMMAND_FAILED`,details:I},verdicts:{},buildFailure:{reason:`devtools_security_developer_mode_disabled`,hint:"Run `sudo DevToolsSecurity -enable`, then retry the iOS runner. UI test runners start suspended until Xcode/testmanagerd can attach."}}];function U(e,t){return t.code!==void 0&&e.code!==t.code||!_e(e,t.details)||!ye(e,t.toolTextIncludesAll)||!be(e,t.toolTextLineIncludesAll)?!1:ve(e,t.foreignMessageIncludesAll)}function _e(e,t){return t===void 0||t(e.details??{})}function ve(e,t){if(!t)return!0;let n=`${e.message??``}`.toLowerCase();return t.every(e=>n.includes(e))}function W(e){let t=e.details??{};return[e.message,t.stdout,t.stderr].filter(e=>typeof e==`string`).join(`
|
|
2
|
+
`).toLowerCase()}function ye(e,t){if(!t)return!0;let n=W(e);return t.every(e=>n.includes(e))}function be(e,t){return!t||W(e).split(`
|
|
3
|
+
`).some(e=>t.every(t=>e.includes(t)))}function G(e,t){if(e instanceof n){for(let n of H)if(n.verdicts[t]!==void 0&&U(e,n.match))return n.verdicts[t]}}function xe(e){return!(e instanceof n)||e.code!==`COMMAND_FAILED`?!1:G(e,`retryable`)??!1}function Se(e){return K(e)?!0:e instanceof n&&e.details?.runnerErrorCode===`MAIN_THREAD_TIMEOUT`}function K(e){return G(e,`drainResend`)??!1}function Ce(e){return e instanceof n&&e.details?.runner!==void 0}function we(e){return!(e instanceof n)||e.code!==`DEVICE_NOT_FOUND`?!1:R(e.details??{})}function Te(e){return G(e,`connectRetry`)??!0}function q(e){return G(e,`restartAfterReadinessPreflight`)??!1}function J(e){return G(e,`artifactSuspect`)??!1}function Ee(e){return G(e,`sessionFatalReason`)}function De(e,t){return Y(e)?Z(e)===`no`||E(t):!1}function Y(e){return G(e,`restartBeforeSend`)??!1}function Oe(e){return Y(e)&&X(e)||q(e)||K(e)}function X(e){return e instanceof n&&e.details?.dispatched===`no`||Q(e,0)}function Z(e){return X(e)?`no`:`unknown`}function Q(e,t){return t>4||typeof e!=`object`||!e?!1:e.code===`ECONNREFUSED`?!0:e instanceof AggregateError&&e.errors.length>0?e.errors.every(e=>Q(e,t+1)):Q(e.cause,t+1)}function $(e){if(e instanceof n)for(let t of H){let n=t.buildFailure;if(n&&U(e,t.match))return{reason:n.reason,hint:n.hint,matched:!0}}return{reason:B,hint:A,matched:!1}}function ke(e,t){if(!t||!(e instanceof n))return e;let r=Ae(e)===void 0&&t.developerDiskImage===`unavailable`&&!Me(e)&&!je(e);return new n(e.code,e.message,{...e.details??{},...r?{reason:`device_developer_disk_image_unavailable`,hint:t.developerDiskImageHint}:{},developerDiskImage:t.developerDiskImage},e.cause)}function Ae(e){let t=e.details?.reason;if(typeof t==`string`&&t!==`build_failed_unclassified`)return t}function je(e){let t=e.details?.startupHostDeadlineHit;return typeof t==`boolean`?t:a(e)}function Me(e){let t=e.details?.startupRuleMatched;return typeof t==`boolean`?t:$(e).matched}export{g as A,p as C,h as D,te as E,ne as F,de as I,fe as L,_ as M,pe as N,ae as O,ee as P,se as R,he as S,v as T,De as _,xe as a,E as b,Se as c,we as d,Z as f,q as g,J as h,ke as i,ue as j,f as k,Oe as l,j as m,M as n,K as o,Ee as p,$ as r,X as s,A as t,Ce as u,Te as v,le as w,D as x,O as y};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{P as e}from"./sdk-contracts.js";import{
|
|
1
|
+
import{P as e,q as t}from"./sdk-contracts.js";import{$ as n,f as r,x as i}from"./apple-runner-platform.js";import{_ as a,b as o,g as s}from"./runner-client.js";import{a as c,c as l,i as u,n as d,t as f}from"./runner-startup-transport.js";import{A as p,M as m,O as h,R as g,S as _,T as v,b as y,c as b,p as x,s as S,u as C,x as w,y as T}from"./runner-error-classification.js";import E from"node:fs/promises";const D=2e3;async function ee(e,t={}){if(e){try{await l(e,{timeoutMs:Math.min(D,t.timeoutMs??D),signal:t.signal})}catch{return}try{return{logPath:e,byteOffset:(await E.stat(e)).size}}catch{return{logPath:e,byteOffset:0}}}}async function te(t){let n=await O(t.logSince)??A(t.error);return n?new e(n.code??t.error.code,t.error.message,{...t.error.details??{},hint:typeof t.error.details?.hint==`string`?`${t.error.details.hint} ${n.hint}`:n.hint,runnerFailureReason:n.reason},t.error):t.error}async function O(e){if(!e)return;let t=await P(e,65536);if(t)return k(t)}function k(e){let t=e.toLowerCase();if(j(t))return{code:`IOS_TARGET_APP_CRASH`,reason:`target_app_axruntime_coretext_crash`,hint:`The target iOS app appears to have crashed while XCTest/AXRuntime read accessibility attributes. This is usually a simulator/XCTest/runtime or app accessibility payload issue, not a text-entry failure. Reproduce on the latest stable simulator runtime, reinstall the app, and capture the app crash from Console.app or ~/Library/Logs/DiagnosticReports with the exact command, selector/ref, app build, Xcode, and simulator runtime.`};if(M(t))return{code:`IOS_TARGET_APP_CRASH`,reason:`target_app_crash`,hint:`The target iOS app appears to have crashed while the runner was executing the command. Reopen or reinstall the app, retry on a fresh/latest stable simulator runtime, and capture the app crash from Console.app or ~/Library/Logs/DiagnosticReports with the exact command, selector/ref, app build, Xcode, and simulator runtime.`}}function A(e){if(N(e.message))return{reason:`runner_main_thread_execution_timeout`,hint:`XCTest timed out waiting for main-thread work on the current iOS screen. The app may still be visually responsive, especially on focused React Native overlays or animating screens. Use screenshot as visual truth, use coordinate presses only to prove or leave the state, and retry snapshot -i after the UI settles or after navigating away.`}}function j(e){return e.includes(`axruntime`)&&e.includes(`coretext`)&&(e.includes(`attributesforelement`)||e.includes(`axuielementcopymultipleattributevalues`)||e.includes(`reconstitutedsmuggledctfontfromdictionary`)||e.includes(`reconstitutedsmuggledattributedstringfromdictionary`))}function M(e){return e.includes(`process crashed`)||e.includes(`the application under test`)||e.includes(`terminated unexpectedly`)||e.includes(`exception type:`)&&e.includes(`thread 0 crashed`)}function N(e){return e.toLowerCase().includes(`main thread execution timed out`)}async function P(e,t){let n;try{let r=await E.stat(e.logPath),i=Math.max(e.byteOffset,r.size-t),a=r.size-i;if(a<=0)return;n=await E.open(e.logPath,`r`);let o=Buffer.alloc(a);return await n.read(o,0,a,i),o.toString(`utf8`)}catch{return}finally{await n?.close().catch(()=>{})}}async function F(e,t,n,r,i,a,o){try{return await I(e,t,n,r,i,a,o)}catch(e){let n=x(e);throw n&&(t.lastHealthyMutation=void 0,await a(n)),e}}async function I(e,t,n,i,a,o,s){let c=await ee(i,{timeoutMs:a,signal:s}),l=g(n),u=y(l),d=r.fromTimeoutMs(a),f=X(t,l);f.action===`run`?await G({device:e,session:t,runnerCommand:l,logAttempt:c,deadline:d,signal:s,decision:f}):K(l,t,f);let p;try{p=await V({device:e,session:t,runnerCommand:l,logPath:i,deadline:d,timeoutMs:a,signal:s,readOnlyCommand:u})}catch(e){throw B(e,t,f)}try{let e=await q(p,t,c);return await L(t,l,e,o),e}catch(e){let n=R(t,l,e);throw x(e)||n?e:B(e,t,f)}}async function L(e,t,n,r){e.commandCharges.settleAnswered(t.commandId);let i=z(n);i!==void 0&&(e.runnerMainThreadBusy=i);let a=Y(n);a?(e.lastHealthyMutation=void 0,await r(a)):T(t)&&(e.lastHealthyMutation={atMs:Date.now(),appBundleId:t.appBundleId})}function R(e,t,n){let r=C(n);return r?e.commandCharges.settleAnswered(t.commandId):e.commandCharges.markAbandoned(t.commandId),b(n)?e.runnerMainThreadBusy=!0:r&&(e.runnerMainThreadBusy=!1),r}function z(e){return typeof e.runnerMainThreadBusy==`boolean`?e.runnerMainThreadBusy:void 0}function B(e,t,n){return n.action!==`skip`||n.reason!==`recent_healthy_mutation`?e:(t.lastHealthyMutation=void 0,Q(e,{runnerReadinessPreflightSkipped:!0,runnerReadinessPreflightSkipReason:n.reason,runnerReadinessPreflightSkippedAgeMs:n.lastHealthyMutationAgeMs}))}async function V(t){let{device:r,session:i,runnerCommand:a,logPath:o,deadline:s,timeoutMs:l,signal:f,readOnlyCommand:p}=t,m=s.remainingMs();if(m<=0)throw new e(`COMMAND_FAILED`,`Runner command deadline exceeded`,{timeoutMs:l});let h=p?{command:a.command,commandId:a.commandId,readOnly:!0,sessionReady:i.state===`ready`,timeoutMs:m}:{command:a.command,commandId:a.commandId};c(f);let g=!_(a);g&&i.commandCharges.charge(a.commandId);try{return await n(`ios_runner_command_send`,async()=>p?await d(r,i.endpoint,a,o,m,i,f):await u(r,i.endpoint,a,m,f),h)}catch(e){throw g&&await H({device:r,session:i,runnerCommand:a,deadline:s,signal:f,error:e}),e}}async function H(e){let{session:n,runnerCommand:r,signal:i,error:a}=e;if(S(a)){n.commandCharges.withdrawUnsent(r.commandId);return}n.commandCharges.markAbandoned(r.commandId),!(!t(i?.reason)||n.state!==`ready`)&&await U(e)}async function U(e){let{device:t,session:n,runnerCommand:r,deadline:a}=e,c=Date.now(),l=`deadline_exceeded`,u,d=0;for(;a.remainingMs()>0;){d+=1;try{u=await W(t,n,r,Math.min(1e3,a.remainingMs()))}catch{l=`status_unavailable`;break}if(o(n,r,u)!==void 0){l=`terminal`;break}if(!s.has(u)){l=`not_in_flight`;break}let e=Math.min(100,a.remainingMs());await new Promise(t=>setTimeout(t,e))}i({level:l===`terminal`?`debug`:`warn`,phase:`ios_runner_canceled_command_drain`,durationMs:Date.now()-c,data:{command:r.command,commandId:r.commandId,outcome:l,lifecycleState:u,polls:d}})}async function W(e,t,n,r){let i=await q(await u(e,t.endpoint,{command:`status`,statusCommandId:n.commandId},r),t);return typeof i.lifecycleState==`string`?i.lifecycleState:``}async function G(e){let{device:t,session:r,runnerCommand:i,logAttempt:a,deadline:o,signal:s,decision:c}=e,l=a?.logPath,u=r.state===`ready`?Math.min(1e3,o.remainingMs()):Math.min($(r),o.remainingMs());try{let e=z(await q(await n(`ios_runner_readiness_preflight`,async()=>await d(t,r.endpoint,g({command:`uptime`}),l,u,r,s),{command:i.command,commandId:i.commandId,reason:c.reason,lastHealthyMutationAgeMs:c.lastHealthyMutationAgeMs,sessionReady:r.state===`ready`,timeoutMs:u}),r,a));e!==void 0&&(r.runnerMainThreadBusy=e)}catch(e){throw Z(e)}}function K(e,t,n){i({level:`debug`,phase:`ios_runner_readiness_preflight_skipped`,data:{command:e.command,commandId:e.commandId,reason:n.reason,lastHealthyMutationAgeMs:n.reason===`recent_healthy_mutation`?n.lastHealthyMutationAgeMs:void 0,sessionReady:t.state===`ready`}})}async function q(e,t,n){let r=h(await e.text());if(!p(r))throw await te({error:v(r,n?.logPath),logSince:n});a(t,`ready`);let i=m(r);return J(i),i}function J(e){let t=e.gestureFallback;typeof t==`string`&&t.length!==0&&i({level:`debug`,phase:`ios_runner_gesture_fallback`,data:{fallback:t,message:typeof e.gestureFallbackMessage==`string`?e.gestureFallbackMessage:void 0,hint:typeof e.gestureFallbackHint==`string`?e.gestureFallbackHint:void 0}})}function Y(e){if(e.runnerFatal===!0)return typeof e.runnerFatalReason==`string`&&e.runnerFatalReason.trim().length>0?e.runnerFatalReason:`runner_reported_fatal_response`}function X(e,t){let n=y(t);if(e.state!==`ready`)return n?{action:`skip`,reason:`read_only_startup_command`}:{action:`run`,reason:`startup`};if(w(t))return{action:`skip`,reason:`preflight_exempt_command`};if(_(t))return{action:`skip`,reason:`readiness_probe_command`};if(!T(t))return{action:`run`,reason:`conservative_command`};let r=e.lastHealthyMutation;if(!r)return{action:`run`,reason:`no_recent_healthy_mutation`};if(t.appBundleId!==r.appBundleId)return{action:`run`,reason:`app_activation_uncertain`};let i=Date.now()-r.atMs;return i>5e3?{action:`run`,reason:`healthy_mutation_stale`,lastHealthyMutationAgeMs:i}:{action:`skip`,reason:`recent_healthy_mutation`,lastHealthyMutationAgeMs:i}}function Z(e){return Q(e,{runnerReadinessPreflightFailed:!0})}function Q(t,n){let r=t instanceof e?t:new e(`COMMAND_FAILED`,t instanceof Error?t.message:String(t),void 0,t);return new e(r.code,r.message,{...r.details??{},...n},r.cause??t)}function $(e){let t=e.launchDeadline;return t?Math.max(0,Math.floor(t.remainingMs())):f}export{F as executeRunnerExchange,$ as readRunnerStartupTimeoutMs};
|
package/dist/src/runner-lease.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{P as e}from"./sdk-contracts.js";import{D as t,G as n,O as r,R as i,S as a,_ as ee,f as o,m as te,n as s,s as c,u as l,v as u,w as ne}from"./host.js";import"./runner-toolchain-probe.js";import{i as re,n as d,r as f,v as p}from"./runner-cache-metadata.js";import{r as ie}from"./runner-device-set.js";import m from"node:crypto";import h from"node:fs";import ae from"node:os";import g from"node:path";const _=new Set;function v(e){return g.join(e,d)}function oe(e,t){h.mkdirSync(e,{recursive:!0}),h.writeFileSync(v(e),`${JSON.stringify(t,null,2)}\n`)}async function se(e,t){if(e.cache===`external`){T(`preserve`,`external_bad_artifact`,{derived:e.derived,xctestrunPath:e.xctestrunPath,reason:t});return}_.add(e.derived),await n({acquire:()=>y(e.derived),task:async()=>{T(`clean`,`bad_artifact`,{derived:e.derived,xctestrunPath:e.xctestrunPath,reason:t}),w(e.derived),S(e.derived)}})}async function y(e,t=6e5){return await s({lockDirPath:ce(e),owner:{pid:process.pid,startTime:r(process.pid),acquiredAtMs:Date.now()},timeoutMs:t,pollMs:100,description:`iOS runner cache lock`})}function ce(e){return g.join(g.dirname(e),`${g.basename(e)}.lock`)}function le(e,t){!pe()&&!t&&!_.has(e)||(T(`clean`,t?`forced_rebuild`:`forced_clean`,{derived:e}),w(e),S(e),_.delete(e))}async function b(e,t,n,r){let{buildRunnerCacheArtifactManifest:i}=await import(`./runner-artifact-manifest.js`),a=i(e,n,r);return oe(e,a.ok?{...t,artifacts:a.artifacts}:t),a.ok?null:(T(`preserve`,`uncertifiable_products`,{derived:e,xctestrunPath:n,...a.refusal?{refusal:a.refusal}:{}}),a.refusal)}function x(t,n){if(t)throw new e(`COMMAND_FAILED`,`The Apple runner products cannot be certified for cache reuse`,{reason:`runner_cache_uncertifiable`,refusalReason:t.reason,refusingPath:t.path??n,...t.reason===`root_unusable`?{}:{resolvesTo:t.target},derived:n,hint:`Inspect ${t.path??n} under ${n}. A symlinked or unreadable product tree must be replaced; run pnpm build:xcuitest with a clean AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH.`})}function S(e){try{if(!h.existsSync(e))return;if(g.basename(e)!==`derived`){h.rmSync(e,{recursive:!0,force:!0});return}for(let t of h.readdirSync(e,{withFileTypes:!0}))ue(t.name)&&h.rmSync(g.join(e,t.name),{recursive:!0,force:!0})}catch{}}const C=new Set([d,`Build`,`BuildCache.noindex`,`Index.noindex`,`Logs`,`ModuleCache.noindex`,`SDKStatCaches.noindex`,`SourcePackages`,`TextBasedInstallAPI`,`info.plist`]);function ue(e){return C.has(e)}function de(e){try{let t=JSON.parse(h.readFileSync(v(e),`utf8`));return!t||typeof t!=`object`||Array.isArray(t)?null:t}catch{return null}}function fe(e,t){let n=de(e);return n?p(f(n))===p(f(t))?{ok:!0,metadata:n}:{ok:!1,reason:`cache_metadata_mismatch`,differences:re(t,n)}:{ok:!1,reason:`cache_metadata_missing`}}function pe(){return ee(process.env.AGENT_DEVICE_IOS_CLEAN_DERIVED)}function w(t,n=process.env){if(n.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim()&&!me(t))throw new e(`COMMAND_FAILED`,`Refusing to clean AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH automatically`,{derivedPath:t,hint:`Unset AGENT_DEVICE_IOS_CLEAN_DERIVED, or move AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH under a subdirectory of ${g.join(o(),`.tmp`)}.`})}function me(e){let t=g.resolve(o(),`.tmp`),n=g.relative(t,g.resolve(e));return n!==``&&!n.startsWith(`..`)&&!g.isAbsolute(n)}async function he(e){let t=fe(e.derived,e.expectedCacheMetadata);if(!t.ok)return t.reason===`cache_metadata_mismatch`?{reason:t.reason,xctestrunPath:null,productPaths:[],metadataDifferences:t.differences}:{reason:t.reason,xctestrunPath:null,productPaths:[]};let{validateRunnerCacheArtifactManifest:n}=await import(`./runner-artifact-manifest.js`),r=n(e.derived,t.metadata);return r.ok?{reason:`reuse_ready`,xctestrunPath:r.xctestrunPath,productPaths:r.productPaths}:r.mismatch?{reason:`artifact_content_mismatch`,xctestrunPath:null,productPaths:[],mismatch:r.mismatch}:{reason:`artifact_manifest_missing`,xctestrunPath:null,productPaths:[]}}function ge(e,t){T(`rebuild`,e.reason,{derived:t,...e.reason===`cache_metadata_mismatch`?{metadataDifferences:e.metadataDifferences}:{},...e.reason===`artifact_content_mismatch`?{mismatch:e.mismatch}:{}})}function T(e,t,n){l({level:e===`rebuild`||e===`preserve`?`warn`:`info`,phase:`runner_xctestrun_cache`,data:{action:e,reason:t,...n}})}const E=process.pid;let D;function O(){return D??={value:r(process.pid)},D.value}function k(){return Re(E,O())}function A(e){let t=q(e.runnerLogPath);return{schemaVersion:1,deviceId:e.device.id,ownerToken:k(),ownerPid:E,ownerStartTime:O(),ownerStateDir:R(),sessionId:e.sessionId,runnerPid:e.runnerPid??null,runnerStartTime:e.runnerPid?r(e.runnerPid):null,port:e.port,xctestrunPath:e.xctestrunPath,cacheKey:e.cacheKey,jsonPath:e.jsonPath,...t?{runnerLogPath:t}:{},...J(ie(e.device)),createdAtMs:Date.now(),deviceClaimProtocol:1}}async function j(e,t){return await n({acquire:()=>s({lockDirPath:`${H(e)}.lock`,owner:{pid:E,startTime:O(),acquiredAtMs:Date.now()},timeoutMs:3e4,pollMs:100,description:`iOS runner lease for ${e}`}),task:t})}function M(e){try{return G(JSON.parse(h.readFileSync(H(e),`utf8`)),e)}catch{return null}}function N(e){if(!e)return{type:`empty`};if(e.ownerToken===k())return{type:`owned`,lease:e};let t=c({owner:{pid:e.ownerPid,startTime:e.ownerStartTime},...e.ownerStateDir?{stateDir:e.ownerStateDir}:{}});return t!==`live`&&t!==`unknown`?{type:`stale`,lease:e,staleReason:t}:{type:`busy`,lease:e}}async function P(t,n,r){let i=t.id,a=N(M(i));if(a.type===`empty`){await n.cleanupRunnerXcodebuildProcesses({deviceId:i});return}if(a.type===`busy`){if(F(a.lease)){await Z(a.lease,`same-state-dir`,n);return}if(I(a.lease,t)){await Z(a.lease,`device-claim-takeover`,n);return}if(L(a.lease,r)){await Z(a.lease,`logical-lease-takeover`,n);return}throw new e(`COMMAND_FAILED`,r?`iOS runner for ${i} is busy after device lease admission`:`iOS runner for ${i} is already owned by another agent-device daemon`,{reason:`IOS_RUNNER_OWNED_BY_OTHER_DAEMON`,deviceId:i,logicalLeaseContext:r,ownerPid:a.lease.ownerPid,ownerStartTime:a.lease.ownerStartTime,ownerStateDir:a.lease.ownerStateDir,ownerToken:a.lease.ownerToken,sessionId:a.lease.sessionId,hint:ve(a.lease,r)})}await Z(a.lease,a.type,n)}function F(e){let t=R();return!t||!e.ownerStateDir?!1:g.resolve(t)===g.resolve(e.ownerStateDir)}function I(e,t){return e.deviceClaimProtocol===1&&e.deviceId===t.id&&te(t)}function L(e,t){return!t||t.leaseProvider!==`proxy`||!t.leaseId||!t.clientId?!1:_e(t.deviceKey,e.deviceId)}function _e(e,t){if(!e)return!1;if(e===t)return!0;let[,,n]=e.split(`:`,3);return n===t}function R(){return a()||process.env.AGENT_DEVICE_STATE_DIR?.trim()||void 0}function ve(e,t){let n=ye(e),r=be(e);return t?[r,n,`The device is busy because another active device lease owns it, or the runner is owned by another daemon/process after lease admission.`,`Retry after the owning session closes or after the five-minute inactivity lease expires.`].join(` `):[r,n,`If the runner is still active, wait for it to finish. Do not run prepare ios-runner from another daemon/client to recover this.`].join(` `)}function ye(e){let t=`Runner owner: PID ${e.ownerPid}`;return e.ownerStateDir?`${t} with AGENT_DEVICE_STATE_DIR=${e.ownerStateDir}`:`${t}.`}function be(e){return e.ownerStateDir?`If it is stuck, stop the owning agent-device daemon for ${xe(`AGENT_DEVICE_STATE_DIR`,e.ownerStateDir)} and retry.`:`If it is stuck, stop the owning agent-device daemon and retry.`}function xe(e,t){return`${e}=${i(t)}`}function z(e){let t=N(M(e));switch(t.type){case`empty`:return{type:`absent`};case`owned`:return{type:`refused`,reason:`lease_owned_by_this_daemon`,lease:t.lease};case`busy`:return{type:`refused`,reason:`lease_owner_live`,lease:t.lease};case`stale`:return t.staleReason===`owner-state-dir-gone`?{type:`refused`,reason:`lease_owner_state_dir_gone`,lease:t.lease}:{type:`adoptable`,lease:t.lease}}}function Se(e){let t=z(e);return t.type===`adoptable`?t.lease:null}function B(e){return{...e,ownerToken:`detached-${e.ownerToken}`}}async function Ce(e,t){let n=N(M(e));n.type===`owned`&&await Z(n.lease,`owned`,t)}async function we(e,t){if(!Number.isInteger(e.pid)||e.pid<=0)return;let n=Oe(e);await Promise.all(n.map(async e=>{await Z(e,`owned`,t)}))}function Te(e){return M(e)?.ownerToken??null}function V(e){e&&De({deviceId:e.deviceId,ownerToken:e.ownerToken,sessionId:e.sessionId})}function Ee(e){let t=H(e.deviceId);h.mkdirSync(g.dirname(t),{recursive:!0}),ne({destination:t,contents:JSON.stringify(e,null,2)})}function De(e){let t=M(e.deviceId);if(t&&!(e.ownerToken&&t.ownerToken!==e.ownerToken)&&!(e.sessionId&&t.sessionId!==e.sessionId))try{h.unlinkSync(H(e.deviceId))}catch{}}function H(e){return g.join(U(),`${ze(e)}.json`)}function U(){let e=process.env.AGENT_DEVICE_IOS_RUNNER_LEASE_DIR?.trim();return e?g.resolve(e):g.join(ae.homedir(),`.agent-device`,`apple-runner`,`leases`)}function Oe(e){return W({strict:!1}).filter(t=>t.ownerPid===e.pid&&(e.startTime===void 0||t.ownerStartTime===e.startTime))}function W(e){let t=e.strict?Ae:ke,n=U(),r=t(()=>h.readdirSync(n,{withFileTypes:!0}))??[],i=[];for(let e of r){if(!e.isFile()||!e.name.endsWith(`.json`))continue;let r=t(()=>h.readFileSync(g.join(n,e.name),`utf8`)),a=r===null?null:Ne(r);a&&i.push(a)}return i}function ke(e){try{return e()}catch{return null}}function Ae(e){try{return e()}catch(e){if(e.code===`ENOENT`)return null;throw e}}function je(){return W({strict:!0}).filter(e=>!Me(e)).map(({xctestrunPath:e,cacheKey:t})=>({xctestrunPath:e,cacheKey:t}))}function Me(e){let t=N(e);if(t.type!==`stale`||t.staleReason===`owner-state-dir-gone`)return!1;if(e.runnerPid===null)return!0;let n=c({owner:{pid:e.runnerPid,startTime:e.runnerStartTime??null}});return n===`owner-process-dead`||n===`owner-process-reused`}function Ne(e){try{let t=JSON.parse(e),n=K(t.deviceId);return n?G(t,n):null}catch{return null}}function G(e,t){if(!e||typeof e!=`object`||Array.isArray(e))return null;let n=e;if(n.schemaVersion!==1||n.deviceId!==t)return null;let r=Pe(n);return r?{schemaVersion:1,deviceId:t,...r,ownerStartTime:Y(n.ownerStartTime),ownerStateDir:Y(n.ownerStateDir)??void 0,runnerPid:X(n.runnerPid),runnerStartTime:Y(n.runnerStartTime),runnerLogPath:q(n.runnerLogPath),cacheKey:q(n.cacheKey),...J(n.simulatorSetPath),...n.deviceClaimProtocol===1?{deviceClaimProtocol:1}:{}}:null}function Pe(e){let t={ownerToken:K(e.ownerToken),ownerPid:X(e.ownerPid),sessionId:K(e.sessionId),port:X(e.port),xctestrunPath:K(e.xctestrunPath),jsonPath:K(e.jsonPath),createdAtMs:Fe(e.createdAtMs)};return Object.values(t).some(e=>e===null)?null:t}function K(e){return typeof e==`string`&&e.length>0?e:null}function q(e){return K(e)??void 0}function J(e){let t=K(e);return t?{simulatorSetPath:t}:{}}function Y(e){return typeof e==`string`?e:null}function X(e){return typeof e==`number`&&Number.isInteger(e)&&e>0?e:null}function Fe(e){return typeof e==`number`&&Number.isFinite(e)?e:null}async function Z(e,t,n){l({level:t===`owned`?`debug`:`warn`,phase:`ios_runner_lease_cleanup`,data:{deviceId:e.deviceId,ownerPid:e.ownerPid,ownerStateDir:e.ownerStateDir,ownerToken:e.ownerToken,runnerPid:e.runnerPid,sessionId:e.sessionId,reason:t}}),await n.cleanupRunnerProcessTree(Q(e),`SIGTERM`),await n.cleanupRunnerXcodebuildProcesses({deviceId:e.deviceId,xctestrunPath:e.xctestrunPath}),await n.cleanupRunnerProcessTree(Q(e),`SIGKILL`),n.cleanupTempFile(e.xctestrunPath),n.cleanupTempFile(e.jsonPath),V(e)}function Ie(e,t){return u(t)&&$(e,t)}function Q(e){let t=e.runnerPid??void 0;if(!(!t||!u(t))){if($(e,t))return t;l({level:`warn`,phase:`ios_runner_lease_recycled_pid_skipped`,data:{deviceId:e.deviceId,runnerPid:t,runnerStartTime:e.runnerStartTime??null,sessionId:e.sessionId}})}}function $(e,n){return e.runnerStartTime?r(n)===e.runnerStartTime:Le(t(n))}function Le(e){return!!e&&e.includes(`xcodebuild`)&&e.includes(`AgentDeviceRunner`)}function Re(e,t){let n=m.createHash(`sha256`);return n.update(String(e)),n.update(`\0`),n.update(t??`unknown-start`),`owner-${e}-${n.digest(`hex`).slice(0,8)}`}function ze(e){return e.replaceAll(/[^A-Za-z0-9._-]/g,`-`)||`unknown-device`}export{se as C,b as E,he as S,v as T,w as _,Te as a,T as b,P as c,V as d,k as f,y as g,Ee as h,we as i,z as l,j as m,A as n,Ie as o,$ as p,Ce as r,je as s,B as t,Se as u,S as v,x as w,ge as x,le as y};
|
|
1
|
+
import{P as e}from"./sdk-contracts.js";import{a as t,i as n,r,y as i}from"./runner.js";import{C as a,F as ee,J as o,L as s,N as c,O as te,R as l,T as u,k as d,p as f,tt as p,v as m,x as h}from"./apple-runner-platform.js";import"./runner-toolchain-probe.js";import{r as ne}from"./runner-device-set.js";import re from"node:crypto";import g from"node:fs";import _ from"node:os";import v from"node:path";const y=new Set;function b(e){return v.join(e,r)}function x(e,t){g.mkdirSync(e,{recursive:!0}),g.writeFileSync(b(e),`${JSON.stringify(t,null,2)}\n`)}async function ie(e,t){if(e.cache===`external`){T(`preserve`,`external_bad_artifact`,{derived:e.derived,xctestrunPath:e.xctestrunPath,reason:t});return}y.add(e.derived),await p({acquire:()=>S(e.derived),task:async()=>{T(`clean`,`bad_artifact`,{derived:e.derived,xctestrunPath:e.xctestrunPath,reason:t}),w(e.derived),C(e.derived)}})}async function S(e,t=6e5){return await f({lockDirPath:ae(e),owner:{pid:process.pid,startTime:l(process.pid),acquiredAtMs:Date.now()},timeoutMs:t,pollMs:100,description:`iOS runner cache lock`})}function ae(e){return v.join(v.dirname(e),`${v.basename(e)}.lock`)}function oe(e,t){!pe()&&!t&&!y.has(e)||(T(`clean`,t?`forced_rebuild`:`forced_clean`,{derived:e}),w(e),C(e),y.delete(e))}async function se(e,t,n,r){let{buildRunnerCacheArtifactManifest:i}=await import(`./runner-artifact-manifest.js`),a=i(e,n,r);return x(e,a.ok?{...t,artifacts:a.artifacts}:t),a.ok?null:(T(`preserve`,`uncertifiable_products`,{derived:e,xctestrunPath:n,...a.refusal?{refusal:a.refusal}:{}}),a.refusal)}function ce(t,n){if(t)throw new e(`COMMAND_FAILED`,`The Apple runner products cannot be certified for cache reuse`,{reason:`runner_cache_uncertifiable`,refusalReason:t.reason,refusingPath:t.path??n,...t.reason===`root_unusable`?{}:{resolvesTo:t.target},derived:n,hint:`Inspect ${t.path??n} under ${n}. A symlinked or unreadable product tree must be replaced; run pnpm build:xcuitest with a clean AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH.`})}function C(e){try{if(!g.existsSync(e))return;if(v.basename(e)!==`derived`){g.rmSync(e,{recursive:!0,force:!0});return}for(let t of g.readdirSync(e,{withFileTypes:!0}))ue(t.name)&&g.rmSync(v.join(e,t.name),{recursive:!0,force:!0})}catch{}}const le=new Set([r,`Build`,`BuildCache.noindex`,`Index.noindex`,`Logs`,`ModuleCache.noindex`,`SDKStatCaches.noindex`,`SourcePackages`,`TextBasedInstallAPI`,`info.plist`]);function ue(e){return le.has(e)}function de(e){try{let t=JSON.parse(g.readFileSync(b(e),`utf8`));return!t||typeof t!=`object`||Array.isArray(t)?null:t}catch{return null}}function fe(e,r){let a=de(e);return a?i(n(a))===i(n(r))?{ok:!0,metadata:a}:{ok:!1,reason:`cache_metadata_mismatch`,differences:t(r,a)}:{ok:!1,reason:`cache_metadata_missing`}}function pe(){return te(process.env.AGENT_DEVICE_IOS_CLEAN_DERIVED)}function w(t,n=process.env){if(n.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim()&&!me(t))throw new e(`COMMAND_FAILED`,`Refusing to clean AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH automatically`,{derivedPath:t,hint:`Unset AGENT_DEVICE_IOS_CLEAN_DERIVED, or move AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH under a subdirectory of ${v.join(a(),`.tmp`)}.`})}function me(e){let t=v.resolve(a(),`.tmp`),n=v.relative(t,v.resolve(e));return n!==``&&!n.startsWith(`..`)&&!v.isAbsolute(n)}async function he(e){let t=fe(e.derived,e.expectedCacheMetadata);if(!t.ok)return t.reason===`cache_metadata_mismatch`?{reason:t.reason,xctestrunPath:null,productPaths:[],metadataDifferences:t.differences}:{reason:t.reason,xctestrunPath:null,productPaths:[]};let{validateRunnerCacheArtifactManifest:n}=await import(`./runner-artifact-manifest.js`),r=n(e.derived,t.metadata);return r.ok?{reason:`reuse_ready`,xctestrunPath:r.xctestrunPath,productPaths:r.productPaths}:r.mismatch?{reason:`artifact_content_mismatch`,xctestrunPath:null,productPaths:[],mismatch:r.mismatch}:{reason:`artifact_manifest_missing`,xctestrunPath:null,productPaths:[]}}function ge(e,t){T(`rebuild`,e.reason,{derived:t,...e.reason===`cache_metadata_mismatch`?{metadataDifferences:e.metadataDifferences}:{},...e.reason===`artifact_content_mismatch`?{mismatch:e.mismatch}:{}})}function T(e,t,n){h({level:e===`rebuild`||e===`preserve`?`warn`:`info`,phase:`runner_xctestrun_cache`,data:{action:e,reason:t,...n}})}const E=process.pid;let D;function O(){return D??={value:l(process.pid)},D.value}function k(){return ze(E,O())}function A(e){let t=q(e.runnerLogPath);return{schemaVersion:1,deviceId:e.device.id,ownerToken:k(),ownerPid:E,ownerStartTime:O(),ownerStateDir:R(),sessionId:e.sessionId,runnerPid:e.runnerPid??null,runnerStartTime:e.runnerPid?l(e.runnerPid):null,port:e.endpoint.port,runnerToken:e.endpoint.token,xctestrunPath:e.xctestrunPath,cacheKey:e.cacheKey,jsonPath:e.jsonPath,...t?{runnerLogPath:t}:{},...J(ne(e.device)),createdAtMs:Date.now(),deviceClaimProtocol:1}}async function j(e,t){return await p({acquire:()=>f({lockDirPath:`${V(e)}.lock`,owner:{pid:E,startTime:O(),acquiredAtMs:Date.now()},timeoutMs:3e4,pollMs:100,description:`iOS runner lease for ${e}`}),task:t})}function M(e){try{return W(JSON.parse(g.readFileSync(V(e),`utf8`)),e)}catch{return null}}function N(e){if(!e)return{type:`empty`};if(e.ownerToken===k())return{type:`owned`,lease:e};let t=m({owner:{pid:e.ownerPid,startTime:e.ownerStartTime},...e.ownerStateDir?{stateDir:e.ownerStateDir}:{}});return t!==`live`&&t!==`unknown`?{type:`stale`,lease:e,staleReason:t}:{type:`busy`,lease:e}}async function P(t,n,r){let i=t.id,a=N(M(i));if(a.type===`empty`){await n.cleanupRunnerXcodebuildProcesses({deviceId:i});return}if(a.type===`busy`){if(F(a.lease)){await Z(a.lease,`same-state-dir`,n);return}if(I(a.lease,t)){await Z(a.lease,`device-claim-takeover`,n);return}if(L(a.lease,r)){await Z(a.lease,`logical-lease-takeover`,n);return}throw new e(`COMMAND_FAILED`,r?`iOS runner for ${i} is busy after device lease admission`:`iOS runner for ${i} is already owned by another agent-device daemon`,{reason:`IOS_RUNNER_OWNED_BY_OTHER_DAEMON`,deviceId:i,logicalLeaseContext:r,ownerPid:a.lease.ownerPid,ownerStartTime:a.lease.ownerStartTime,ownerStateDir:a.lease.ownerStateDir,ownerToken:a.lease.ownerToken,sessionId:a.lease.sessionId,hint:ve(a.lease,r)})}await Z(a.lease,a.type,n)}function F(e){let t=R();return!t||!e.ownerStateDir?!1:v.resolve(t)===v.resolve(e.ownerStateDir)}function I(e,t){return e.deviceClaimProtocol===1&&e.deviceId===t.id&&u(t)}function L(e,t){return!t||t.leaseProvider!==`proxy`||!t.leaseId||!t.clientId?!1:_e(t.deviceKey,e.deviceId)}function _e(e,t){if(!e)return!1;if(e===t)return!0;let[,,n]=e.split(`:`,3);return n===t}function R(){return c()||process.env.AGENT_DEVICE_STATE_DIR?.trim()||void 0}function ve(e,t){let n=ye(e),r=be(e);return t?[r,n,`The device is busy because another active device lease owns it, or the runner is owned by another daemon/process after lease admission.`,`Retry after the owning session closes or after the five-minute inactivity lease expires.`].join(` `):[r,n,`If the runner is still active, wait for it to finish. Do not run prepare ios-runner from another daemon/client to recover this.`].join(` `)}function ye(e){let t=`Runner owner: PID ${e.ownerPid}`;return e.ownerStateDir?`${t} with AGENT_DEVICE_STATE_DIR=${e.ownerStateDir}`:`${t}.`}function be(e){return e.ownerStateDir?`If it is stuck, stop the owning agent-device daemon for ${xe(`AGENT_DEVICE_STATE_DIR`,e.ownerStateDir)} and retry.`:`If it is stuck, stop the owning agent-device daemon and retry.`}function xe(e,t){return`${e}=${o(t)}`}function Se(e){return e.runnerToken?{port:e.port,token:e.runnerToken}:null}function z(e){let t=N(M(e));switch(t.type){case`empty`:return{type:`absent`};case`owned`:return{type:`refused`,reason:`lease_owned_by_this_daemon`,lease:t.lease};case`busy`:return{type:`refused`,reason:`lease_owner_live`,lease:t.lease};case`stale`:return t.staleReason===`owner-state-dir-gone`?{type:`refused`,reason:`lease_owner_state_dir_gone`,lease:t.lease}:{type:`adoptable`,lease:t.lease}}}function Ce(e){let t=z(e);return t.type===`adoptable`?t.lease:null}function we(e){return{...e,ownerToken:`detached-${e.ownerToken}`}}async function Te(e,t){let n=N(M(e));n.type===`owned`&&await Z(n.lease,`owned`,t)}async function Ee(e,t){if(!Number.isInteger(e.pid)||e.pid<=0)return;let n=Ae(e);await Promise.all(n.map(async e=>{await Z(e,`owned`,t)}))}function De(e){return M(e)?.ownerToken??null}function B(e){e&&ke({deviceId:e.deviceId,ownerToken:e.ownerToken,sessionId:e.sessionId})}function Oe(e){let t=V(e.deviceId);g.mkdirSync(v.dirname(t),{recursive:!0}),ee({destination:t,contents:JSON.stringify(e,null,2),mode:384})}function ke(e){let t=M(e.deviceId);if(t&&!(e.ownerToken&&t.ownerToken!==e.ownerToken)&&!(e.sessionId&&t.sessionId!==e.sessionId))try{g.unlinkSync(V(e.deviceId))}catch{}}function V(e){return v.join(H(),`${Be(e)}.json`)}function H(){let e=process.env.AGENT_DEVICE_IOS_RUNNER_LEASE_DIR?.trim();return e?v.resolve(e):v.join(_.homedir(),`.agent-device`,`apple-runner`,`leases`)}function Ae(e){return U({strict:!1}).filter(t=>t.ownerPid===e.pid&&(e.startTime===void 0||t.ownerStartTime===e.startTime))}function U(e){let t=e.strict?Me:je,n=H(),r=t(()=>g.readdirSync(n,{withFileTypes:!0}))??[],i=[];for(let e of r){if(!e.isFile()||!e.name.endsWith(`.json`))continue;let r=t(()=>g.readFileSync(v.join(n,e.name),`utf8`)),a=r===null?null:Fe(r);a&&i.push(a)}return i}function je(e){try{return e()}catch{return null}}function Me(e){try{return e()}catch(e){if(e.code===`ENOENT`)return null;throw e}}function Ne(){return U({strict:!0}).filter(e=>!Pe(e)).map(({xctestrunPath:e,cacheKey:t})=>({xctestrunPath:e,cacheKey:t}))}function Pe(e){let t=N(e);if(t.type!==`stale`||t.staleReason===`owner-state-dir-gone`)return!1;if(e.runnerPid===null)return!0;let n=m({owner:{pid:e.runnerPid,startTime:e.runnerStartTime??null}});return n===`owner-process-dead`||n===`owner-process-reused`}function Fe(e){try{let t=JSON.parse(e),n=K(t.deviceId);return n?W(t,n):null}catch{return null}}function W(e,t){if(!e||typeof e!=`object`||Array.isArray(e))return null;let n=e;if(n.schemaVersion!==1||n.deviceId!==t)return null;let r=G(n);return r?{schemaVersion:1,deviceId:t,...r,ownerStartTime:Y(n.ownerStartTime),ownerStateDir:Y(n.ownerStateDir)??void 0,runnerPid:X(n.runnerPid),runnerStartTime:Y(n.runnerStartTime),runnerLogPath:q(n.runnerLogPath),runnerToken:q(n.runnerToken),cacheKey:q(n.cacheKey),...J(n.simulatorSetPath),...n.deviceClaimProtocol===1?{deviceClaimProtocol:1}:{}}:null}function G(e){let t={ownerToken:K(e.ownerToken),ownerPid:X(e.ownerPid),sessionId:K(e.sessionId),port:X(e.port),xctestrunPath:K(e.xctestrunPath),jsonPath:K(e.jsonPath),createdAtMs:Ie(e.createdAtMs)};return Object.values(t).some(e=>e===null)?null:t}function K(e){return typeof e==`string`&&e.length>0?e:null}function q(e){return K(e)??void 0}function J(e){let t=K(e);return t?{simulatorSetPath:t}:{}}function Y(e){return typeof e==`string`?e:null}function X(e){return typeof e==`number`&&Number.isInteger(e)&&e>0?e:null}function Ie(e){return typeof e==`number`&&Number.isFinite(e)?e:null}async function Z(e,t,n){h({level:t===`owned`?`debug`:`warn`,phase:`ios_runner_lease_cleanup`,data:{deviceId:e.deviceId,ownerPid:e.ownerPid,ownerStateDir:e.ownerStateDir,ownerToken:e.ownerToken,runnerPid:e.runnerPid,sessionId:e.sessionId,reason:t}}),await n.cleanupRunnerProcessTree(Q(e),`SIGTERM`),await n.cleanupRunnerXcodebuildProcesses({deviceId:e.deviceId,xctestrunPath:e.xctestrunPath}),await n.cleanupRunnerProcessTree(Q(e),`SIGKILL`),n.cleanupTempFile(e.xctestrunPath),n.cleanupTempFile(e.jsonPath),B(e)}function Le(e,t){return d(t)&&$(e,t)}function Q(e){let t=e.runnerPid??void 0;if(!(!t||!d(t))){if($(e,t))return t;h({level:`warn`,phase:`ios_runner_lease_recycled_pid_skipped`,data:{deviceId:e.deviceId,runnerPid:t,runnerStartTime:e.runnerStartTime??null,sessionId:e.sessionId}})}}function $(e,t){return e.runnerStartTime?l(t)===e.runnerStartTime:Re(s(t))}function Re(e){return!!e&&e.includes(`xcodebuild`)&&e.includes(`AgentDeviceRunner`)}function ze(e,t){let n=re.createHash(`sha256`);return n.update(String(e)),n.update(`\0`),n.update(t??`unknown-start`),`owner-${e}-${n.digest(`hex`).slice(0,8)}`}function Be(e){return e.replaceAll(/[^A-Za-z0-9._-]/g,`-`)||`unknown-device`}export{he as C,se as D,b as E,ge as S,ce as T,S as _,De as a,oe as b,Ne as c,Ce as d,B as f,Oe as g,j as h,Ee as i,P as l,$ as m,A as n,Le as o,k as p,Te as r,Se as s,we as t,z as u,w as v,ie as w,T as x,C as y};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{_ as e,c as t,d as n,g as r,l as i,o as a,s as o,v as s}from"./runner.js";import{l as c,n as l}from"./apple-runner-platform.js";import{C as u,D as d,O as f,a as p,c as m,d as h,f as g,i as _,l as v,n as y,o as b,p as x,r as S,s as C,u as w}from"./runner-client.js";import{D as T,T as E,d as D,m as O}from"./runner-lease.js";async function k(e,t,n,r){return await m(e,{command:`querySelector`,selectorKey:t.key,selectorValue:t.value,appBundleId:n},r)}async function A(e){let{cleanupRunnerLeasesForOwner:t}=await import(`./runner-client.js`).then(e=>e.t),{runnerLeaseCleanupAdapter:n}=await import(`./runner-client.js`).then(e=>e.m);await t(e,n)}export{d as applyXctestRunnerAppIconFromDerivedPath,A as cleanupRunnerLeasesForOwner,v as detachIosRunnerSessionsForShutdown,u as findRunnerXctestrun,y as hasLiveIosRunnerSession,l as isRunnerXcuitestScriptPlatform,S as notifyIosRunnerAppRelaunched,_ as prepareIosRunner,p as prewarmAppleRunnerCache,b as prewarmIosRunnerSession,k as queryAppleRunnerSelector,w as readRunnerSessionLiveness,D as readStaleRunnerLease,h as releaseIosRunnerOnClose,C as releaseSpeculativeIosRunnerSessionFor,E as requireCertifiedRunnerCacheArtifacts,a as requireRunnerBuildSettingsMatchBuildLog,f as resolveExistingRunnerProductPaths,o as resolveExpectedRunnerCacheMetadata,t as resolveRunnerAppBundleId,i as resolveRunnerArchBuildSettings,n as resolveRunnerBundleBuildSettings,r as resolveRunnerPerformanceBuildSettings,e as resolveRunnerSandboxBuildArgs,c as resolveRunnerScriptDevice,s as resolveRunnerSigningBuildSettings,m as runAppleRunnerCommand,g as stopAllIosRunnerSessions,x as stopIosRunnerSession,O as verifyLeaseRunnerPidIdentity,T as writeRunnerCacheMetadataForArtifacts};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{h as e}from"./sdk-device.js";import{x as t}from"./apple-runner-platform.js";import{v as n}from"./runner-client.js";import r from"node:net";function i(e,n){if(e.state!==`ready`||!o(e)||e.listenerWatch)return;let i=r.connect(e.endpoint.port,`127.0.0.1`);i.unref();let a,s=new Promise(e=>{a=e}),c=setTimeout(()=>i.destroy(),500);c.unref();let l={lost:!1,ready:s,close(){clearTimeout(c),l.lost=!0,a(!1),i.removeAllListeners(),i.on(`error`,()=>{}),i.destroy()}};e.listenerWatch=l,i.on(`connect`,()=>{clearTimeout(c),a(!0)}),i.on(`error`,()=>{}),i.on(`close`,()=>{clearTimeout(c),l.lost=!0,a(!1),n()?.catch(n=>{t({level:`warn`,phase:`ios_runner_warm_stop_failed`,data:{deviceId:e.deviceId,sessionId:e.sessionId,error:String(n)}})})})}async function a(e,r){if(e.state!==`ready`||n(e)||e.commandCharges.hasOutstandingCharges)return!1;if(o(e)){let t=e.listenerWatch;if(!t||!await t.ready||t.lost)return!1}if(e.state!==`ready`||n(e)||e.commandCharges.hasOutstandingCharges)return!1;e.retention?.cancel();let i,a={cancel(){clearTimeout(i),e.retention===a&&(e.retention=void 0)}};e.retention=a;let c=s();return c>0&&(i=setTimeout(()=>{r(a,`idle_timeout`).catch(n=>{t({level:`warn`,phase:`ios_runner_idle_stop_failed`,data:{deviceId:e.deviceId,sessionId:e.sessionId,error:String(n)}})})},c),i.unref(),t({level:`debug`,phase:`ios_runner_idle_stop_scheduled`,data:{deviceId:e.deviceId,sessionId:e.sessionId,idleMs:c}})),!0}function o(t){return t.device.kind===`simulator`&&e(t.device)}function s(e=process.env){let t=e.AGENT_DEVICE_IOS_RUNNER_IDLE_STOP_MS?.trim();if(t){let e=Number(t);if(Number.isFinite(e)&&e>=0)return Math.min(Math.floor(e),2**31-1)}return 3e5}export{i as observeRunnerListener,a as retainRunnerSession};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{L as e,P as t,q as n}from"./sdk-contracts.js";import{x as r}from"./apple-runner-platform.js";import{r as i}from"./runner-toolchain-probe.js";import{E as a,S as o,T as s,h as c,x as l,y as u}from"./runner-client.js";import{F as d,k as f}from"./runner-error-classification.js";function p(e){let t=u(e.startupTimeoutMs),n=t??6e5,r=new AbortController,a=setTimeout(()=>{r.abort(m(n,t!==void 0))},n);a.unref?.();let o=d(e),s=o?AbortSignal.any([o,r.signal]):r.signal;return{phase:i(n,s),timeoutMs:n,explicit:t!==void 0,exhausted:r.signal,close:()=>clearTimeout(a)}}function m(e,n){return new t(`COMMAND_FAILED`,`Apple runner start exceeded its ${n?`startup timeout`:`default start budget`} of ${e}ms`,{reason:`runner_start_budget_exhausted`,timeoutMs:e,retriable:!0,hint:n?"Raise the startup timeout, or run `prepare ios-runner` first so the runner is built before it is needed.":"Run `prepare ios-runner --timeout <ms>` so the cold build has a budget of your choosing; the session runner.log names the step that stalled."})}async function h(t,n,r){return r?await new Promise((i,u)=>{let d=r.aborted?`already-spent`:l(n,r),p=()=>{if(u(e(void 0,r.reason)),t.catch(_),f(r.reason)){d===`interested`&&a(n,r),s(n);return}o(n,r)&&c(n.deviceId)};r.aborted?p():r.addEventListener(`abort`,p,{once:!0}),t.then(i,u).finally(()=>{r.removeEventListener(`abort`,p),d===`interested`&&a(n,r)})}):await t}function g(e,t){let n=t.signal?void 0:d(t);if(!n||l(e,n)!==`interested`)return()=>{};let r=()=>{o(e,n)&&c(e.deviceId)};return n.addEventListener(`abort`,r,{once:!0}),()=>{n.removeEventListener(`abort`,r),a(e,n)}}function _(e){if(n(e))return;let i=e instanceof t?e:void 0;r({level:`warn`,phase:`ios_runner_detached_start_failed`,data:{code:i?.code,reason:i?.details?.reason,error:e instanceof Error?e.message:String(e)}})}export{p as openRunnerStartBudget,h as raceRunnerStartAgainstCaller,g as reserveRunnerStartOwnerInterest};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{B as e,H as t,L as n,P as r,q as i}from"./sdk-contracts.js";import{g as a}from"./sdk-device.js";import{n as o}from"./entities.js";import{t as s}from"./parser.js";import{H as c,V as l,_ as u,f as d,h as f}from"./apple-runner-platform.js";import{L as p,N as m,d as h,i as g,m as _,r as v,s as y,t as b,v as ee}from"./runner-error-classification.js";import{i as x,n as te}from"./runner-device-set.js";import S from"node:fs";import ne from"node:os";import C from"node:path";import w from"node:net";import T from"node:http";async function re(){return await new Promise((e,t)=>{let n=w.createServer();n.listen(0,`127.0.0.1`,()=>{let i=n.address();if(typeof i==`object`&&i?.port){let t=i.port;n.close(()=>e(t))}else n.close(()=>t(new r(`COMMAND_FAILED`,`Failed to allocate port`)))}),n.on(`error`,t)})}function ie(e,t,n,r){t&&O(t,e),n&&O(n,e),r&&process.stderr.write(e)}const E=new Map,D=new Map;function O(e,t){let n=(E.get(e)??Promise.resolve()).then(()=>k(e,t),()=>k(e,t)).then(()=>{D.delete(e)},t=>{D.set(e,t)}).finally(()=>{E.get(e)===n&&E.delete(e)});E.set(e,n)}async function k(e,t){await S.promises.mkdir(C.dirname(e),{recursive:!0}),await S.promises.appendFile(e,t)}async function A(e,t={}){let n=AbortSignal.any([t.signal??new AbortController().signal,AbortSignal.timeout(t.timeoutMs??2e3)]);if(n.aborted)throw n.reason;let r=E.get(e);if(r){let e=()=>{};try{await Promise.race([r,new Promise((t,r)=>{e=()=>r(n.reason),n.addEventListener(`abort`,e,{once:!0})})])}finally{n.removeEventListener(`abort`,e)}}let i=D.get(e);if(i!==void 0)throw i}function ae(e){try{S.existsSync(e)&&S.unlinkSync(e)}catch{}}function oe(e,t){if(e)return e;let n=t.replaceAll(/[^A-Za-z0-9._-]/g,`_`);return C.join(ne.tmpdir(),`agent-device`,`apple-runner`,`logs`,`${n}.log`)}function se(e,t){let n=0;try{n=S.fstatSync(t).size}catch{}return{logPath:e,startOffset:n}}function ce(e){let t=e.pollMs??50,n=Buffer.alloc(65536),r=e.file.startOffset,i=null,a=null,o=!1,s=()=>{if(!o)try{i??=S.openSync(e.file.logPath,`r`);let t=S.fstatSync(i).size;for(t<r&&(r=0);r<t;){let a=Math.min(n.length,t-r),o=S.readSync(i,n,0,a,r);if(o<=0)break;r+=o,e.onOutput(n.toString(`utf8`,0,o)),t=S.fstatSync(i).size}}catch{l()}},c=()=>{o||(a=setTimeout(()=>{s(),c()},t),a.unref?.())};function l(){if(!o&&(o=!0,a&&clearTimeout(a),a=null,i!==null)){try{S.closeSync(i)}catch{}i=null}}return c(),{drain:()=>{s(),l()},stop:l}}function le(e,t){if(!e)return``;let n=null;try{n=S.openSync(e.logPath,`r`);let r=S.fstatSync(n).size,i=Math.max(e.startOffset,r-t),a=r-i;if(a<=0)return``;let o=Buffer.alloc(a),s=S.readSync(n,o,0,a,i);return o.toString(`utf8`,0,Math.max(s,0))}catch{return``}finally{if(n!==null)try{S.closeSync(n)}catch{}}}const j=new Map;function M(e,t){let n,r=!1;return{markUsbmuxUnattached:()=>{r=!0},resolveRoute:async(i,a=!1)=>{if(de(e))return fe(t);let o=l(e);if(o.backend===`xctest`||!r)return ue(e,t);if(!a){let r=pe(e.id);if(r)return P(t,r,!0);if(n!==void 0)return P(t,n,!1)}let{tunnelIp:s}=await o.resolveTunnel(e,i);return n=s,s&&me(e.id,s),P(t,s,!1)}}}function N(e){j.delete(e)}function ue(e,t){return{kind:`usbmux`,url:`usbmux://${e.id}:${t}/command`,cachedTunnelIp:!1}}function de(e){return e.kind!==`device`||a(e)}function fe(e){return{kind:`network`,url:`http://127.0.0.1:${e}/command`,cachedTunnelIp:!1}}function P(e,t,n){return{kind:`network`,url:t?`http://[${t}]:${e}/command`:null,cachedTunnelIp:n}}function pe(e){let t=j.get(e);return t?t.expiresAt<=Date.now()?(j.delete(e),null):t.ip:null}function me(e,t){j.set(e,{ip:t,expiresAt:Date.now()+3e4})}const F=`Connect the device by cable, trust this Mac, keep it unlocked, and retry.`;async function he(e,t,n,r,i){let a=d.fromTimeoutMs(r);return await I(e,t,await ge(e,t,a.remainingMs(),i),n,a.remainingMs(),i)}async function ge(e,t,n,i){let a=await L(e,n,i);try{await R(a,1,B(`ListDevices`));let e=_e((await z(a,n,i)).payload.toString(`utf8`),t);if(e!==void 0)return e;throw new r(`DEVICE_NOT_FOUND`,`iOS device is not available through usbmux`,{deviceId:t,backend:`xctest`,usbmuxDeviceAttached:!1,hint:F})}finally{a.destroy()}}async function I(e,t,n,r,i,a){let o=await L(e,i,a);try{await R(o,2,B(`Connect`,{DeviceID:n,PortNumber:xe(r)}));let e=ye((await z(o,i,a)).payload.toString(`utf8`),`Number`);if(e!==0)throw be({result:e,udid:t,deviceId:n,port:r});return o}catch(e){throw o.destroy(),e}}async function L(e,t,i){if(U(t,`connect to usbmuxd`),i?.aborted)throw n();return await new Promise((a,o)=>{let s=w.createConnection(e),c=!1,l=setTimeout(()=>{p(new r(`COMMAND_FAILED`,`Timed out connecting to usbmuxd`,{backend:`xctest`,socketPath:e,timeoutMs:t}))},t),u=()=>p(),d=e=>p(e),f=()=>p(n()),p=e=>{c||(c=!0,clearTimeout(l),s.off(`connect`,u),s.off(`error`,d),i?.removeEventListener(`abort`,f),e?(s.destroy(),o(e)):a(s))};s.once(`connect`,u),s.once(`error`,d),i?.addEventListener(`abort`,f,{once:!0})})}async function R(e,t,n){let r=Buffer.from(n,`utf8`),i=Buffer.alloc(16+r.length);i.writeUInt32LE(i.length,0),i.writeUInt32LE(1,4),i.writeUInt32LE(8,8),i.writeUInt32LE(t,12),r.copy(i,16),!e.write(i)&&await new Promise((t,n)=>{e.once(`drain`,t),e.once(`error`,n)})}async function z(e,t,i){if(U(t,`read usbmuxd response`),i?.aborted)throw n();return await new Promise((a,o)=>{let s=Buffer.alloc(0),c=!1,l=setTimeout(()=>m(new r(`COMMAND_FAILED`,`Timed out reading usbmuxd response`,{backend:`xctest`,timeoutMs:t})),t),u=e=>{if(s=Buffer.concat([s,e]),s.length<16)return;let t=s.readUInt32LE(0);if(t<16||t>4194304){m(new r(`COMMAND_FAILED`,`Invalid usbmuxd response length`));return}s.length<t||m(void 0,{payload:s.subarray(16,t)})},d=e=>m(e),f=()=>m(new r(`COMMAND_FAILED`,`usbmuxd closed the connection unexpectedly`)),p=()=>m(n()),m=(t,n)=>{c||(c=!0,clearTimeout(l),e.off(`data`,u),e.off(`error`,d),e.off(`close`,f),i?.removeEventListener(`abort`,p),e.pause(),t?o(t):a(n))};e.on(`data`,u),e.once(`error`,d),e.once(`close`,f),i?.addEventListener(`abort`,p,{once:!0}),e.resume()})}function B(e,t={}){return`<?xml version="1.0" encoding="UTF-8"?><plist version="1.0"><dict>${[[`BundleID`,`com.callstack.agent-device`],[`ClientVersionString`,`agent-device`],[`MessageType`,e],[`ProgName`,`agent-device`],[`kLibUSBMuxVersion`,3],...Object.entries(t)].map(([e,t])=>typeof t==`number`?`<key>${o(e)}</key><integer>${t}</integer>`:`<key>${o(e)}</key><string>${o(t)}</string>`).join(``)}</dict></plist>`}function _e(e,t){let n;for(let r of H(s(e))){let e=ve(r);if(e?.udid===t){if(V(V(r,`Properties`),`ConnectionType`)?.text===`USB`)return e.id;n??=e.id}}return n}function ve(e){if(e.name!==`dict`)return;let t=V(e,`Properties`);if(t?.name!==`dict`)return;let n=V(t,`SerialNumber`)?.text,r=Number(V(e,`DeviceID`)?.text);if(!(!n||!Number.isSafeInteger(r)||r<=0))return{udid:n,id:r}}function ye(e,t){for(let n of H(s(e))){if(n.name!==`dict`)continue;let e=V(n,t);if(e?.name!==`integer`)continue;let r=Number(e.text);if(Number.isSafeInteger(r))return r}}function V(e,t){for(let n=0;n<e.children.length-1;n+=1){let r=e.children[n];if(r?.name===`key`&&r.text===t)return e.children[n+1]}}function*H(e){for(let t of e)yield t,yield*H(t.children)}function be(e){let{result:t,udid:n,deviceId:i,port:a}=e;return t===2?new r(`DEVICE_NOT_FOUND`,`iOS device is no longer available through usbmux`,{deviceId:n,backend:`xctest`,usbmuxDeviceAttached:!1,usbmuxResult:t,hint:F}):t===3?new r(`COMMAND_FAILED`,`XCTest runner is not listening on the device port`,{backend:`xctest`,deviceId:i,port:a,usbmuxResult:t,hint:`The device is reachable but nothing is bound to the runner port yet; this resolves once the runner finishes starting.`}):new r(`COMMAND_FAILED`,`Failed to connect to XCTest runner through usbmux`,{backend:`xctest`,deviceId:i,port:a,usbmuxResult:t,hint:`Keep the device connected by cable and unlocked, then retry.`})}function xe(e){return(e&255)<<8|e>>>8&255}function U(e,t){if(!(e>0))throw new r(`COMMAND_FAILED`,`No time remaining to ${t}`,{backend:`xctest`,timeoutMs:e})}function Se(t){return{postCommand:async(n,i,a,o,s)=>{let c=d.fromTimeoutMs(o),l=await he(t,n,i.port,c.remainingMs(),s).catch(t=>{throw t instanceof r?e(t,`no`):t});try{return await we(l,i,a,c.remainingMs(),s)}catch(e){throw l.destroy(),e}}}}const Ce=Se(`/var/run/usbmuxd`);async function we(e,t,i,a,o){if(Oe(a),o?.aborted)throw n({dispatched:`no`});let s=Buffer.from(JSON.stringify(i),`utf8`),c=AbortSignal.timeout(a),l=o?AbortSignal.any([o,c]):c,u=new T.Agent;u.createConnection=(t,n)=>(n?.(null,e),e);try{let n=await Te(u,e,t,s,l);return new Response((await De(n)).toString(`utf8`),{status:n.statusCode??500,headers:Ee(n)})}catch(e){throw o?.aborted?n():c.aborted?new r(`COMMAND_FAILED`,`Timed out waiting for XCTest runner over usbmux`,{backend:`xctest`,timeoutMs:a}):e}finally{u.destroy(),e.destroy()}}async function Te(e,t,n,r,i){return await new Promise((a,o)=>{let s=T.request({method:`POST`,host:`127.0.0.1`,path:`/command`,headers:{...p(n),"Content-Length":r.length,Connection:`close`},agent:e,signal:i},a);s.once(`error`,o),t.resume(),s.end(r)})}function Ee(e){let t=new Headers;for(let[n,r]of Object.entries(e.headers))typeof r==`string`&&t.set(n,r);return t}async function De(e){let t=[],n=0;for await(let i of e){let e=Buffer.isBuffer(i)?i:Buffer.from(i);if(n+=e.length,n>67108864)throw new r(`COMMAND_FAILED`,`XCTest runner response exceeded size limit`);t.push(e)}return Buffer.concat(t)}function Oe(e){if(!(e>0))throw new r(`COMMAND_FAILED`,`No time remaining to send XCTest runner command`,{backend:`xctest`,timeoutMs:e})}const W=45e3;async function ke(e,t,n,r=W,i){return m(await Ae(e,t,n,r,i))}async function Ae(e,t,n,r,i){K(i);let a=d.fromTimeoutMs(r),o=M(e,t.port),s=await o.resolveRoute(a.remainingMs());if(s.kind===`usbmux`)try{return await G(e,s,{endpoint:t,command:n,timeoutMs:a.remainingMs(),signal:i})}catch(t){if(!q(e,t))throw t;o.markUsbmuxUnattached(),s=await o.resolveRoute(a.remainingMs())}return await G(e,s,{endpoint:t,command:n,timeoutMs:a.remainingMs(),signal:i})}async function G(t,n,i){let{endpoint:a,command:o,timeoutMs:s,signal:c}=i;if(K(c),s<=0)throw e(new r(`COMMAND_FAILED`,`Runner command deadline exceeded`,{port:a.port,timeoutMs:s}),`no`);if(n.kind===`usbmux`)return await Ce.postCommand(t.id,a,o,s,c);if(!n.url)throw e(new r(`COMMAND_FAILED`,`Runner command endpoint not available`,{port:a.port}),`no`);return await je(n.url,{method:`POST`,headers:p(a),body:JSON.stringify(o)},s,c)}function K(e){if(e?.aborted)throw n({dispatched:`no`})}function q(e,t){return h(t)?l(e).backend!==`xctest`:!1}async function je(e,t,n,i){let a=AbortSignal.timeout(n),o=i?AbortSignal.any([i,a]):a;try{return await fetch(e,{...t,redirect:`error`,signal:o})}catch(e){throw e===a.reason?new r(`COMMAND_FAILED`,`Runner command deadline exceeded`,{timeoutMs:n},e):e}}const J=45e3;async function Me(e,t,n,r,a=J,o,s){let l=d.fromTimeoutMs(a),u=t.port,{resolveRoute:f,markUsbmuxUnattached:p}=M(e,u),g=await f(l.remainingMs()),_=null,v=!1,b=Math.max(1,Math.ceil(a/250)),x;try{x=await c(async({deadline:c})=>{let l=await Pe({device:e,endpoint:t,command:n,timeoutMs:a,logPath:r,session:o,route:g,resolveRoute:f,markUsbmuxUnattached:p,signal:s,attemptDeadline:c,setRoute:e=>{g=e},setLastError:e=>{_=e,y(e)||(v=!0)}}).catch(e=>{throw i(e)&&!y(e)&&(v=!0),e});if(l)return l;throw Re({port:u,url:g.url,lastError:_,signal:s})},{maxAttempts:b,baseDelayMs:300,maxDelayMs:2e3,jitter:.2,shouldRetry:ee},{deadline:l,phase:`ios_runner_connect`,signal:s,retryWakeSignal:e.kind===`simulator`?o?.startupRetryWake:void 0})}catch(e){if(s?.aborted||i(e))throw Y(v);if(h(e))throw e;_||=e}if(x)return m(x);throw s?.aborted?Y(v):o?.child.exitCode!==null&&o?.child.exitCode!==void 0?Z(await $({session:o,port:u,logPath:r}),v):Z(Be({port:u,url:g.url,logPath:r,lastError:_,deviceStates:o?.startupDeviceStates}),v)}function Y(e){return n({dispatched:e?`unknown`:`no`})}function Ne(e,t){return n(X(e,t)?{dispatched:`no`}:{})}function X(e,t){return e!==t?.reason&&y(e)}function Z(n,i){return n instanceof r?i?e(n,`unknown`):t(n,`no`):n}async function Pe(e){await Fe(e);let t=await Ie(e);return t.response?t.response:await Le(e,t.usedCachedTunnelIp)}async function Fe(e){if(e.attemptDeadline?.isExpired())throw new r(`COMMAND_FAILED`,`Runner connection deadline exceeded`,{port:e.endpoint.port,timeoutMs:e.timeoutMs});if(e.session?.child.exitCode!==null&&e.session?.child.exitCode!==void 0)throw await $({session:e.session,port:e.endpoint.port,logPath:e.logPath})}async function Ie(e){let t=e.route,n=!1;e.device.kind===`device`&&(t=await e.resolveRoute(e.attemptDeadline?.remainingMs()),n=t.cachedTunnelIp,e.setRoute(t));let r=async t=>await Q(e.device,t,{command:e.command,endpoint:e.endpoint,timeoutMs:e.timeoutMs,signal:e.signal,attemptDeadline:e.attemptDeadline,onUsbmuxUnattached:e.markUsbmuxUnattached,onError:n=>{e.setLastError(n),e.device.kind===`device`&&t.cachedTunnelIp&&N(e.device.id)}}),i=await r(t);if(i||t.kind!==`usbmux`)return{response:i,usedCachedTunnelIp:n};let a=await e.resolveRoute(e.attemptDeadline?.remainingMs());return a.kind===`usbmux`?{response:null,usedCachedTunnelIp:n}:(e.setRoute(a),{response:await r(a),usedCachedTunnelIp:a.cachedTunnelIp})}async function Le(e,t){if(e.device.kind!==`device`||!t)return null;N(e.device.id);let n=await e.resolveRoute(e.attemptDeadline?.remainingMs(),!0);return e.setRoute(n),await Q(e.device,n,{command:e.command,endpoint:e.endpoint,timeoutMs:e.timeoutMs,signal:e.signal,attemptDeadline:e.attemptDeadline,onError:e.setLastError})}function Re(e){if(e.signal?.aborted)throw n();return new r(`COMMAND_FAILED`,`Runner endpoint probe failed`,{port:e.port,url:e.url,lastError:e.lastError?String(e.lastError):void 0,..._(`runner_endpoint_probe_exhausted`)})}async function Q(e,t,n){let r=n.attemptDeadline?.remainingMs()??n.timeoutMs;try{return await G(e,t,{endpoint:n.endpoint,command:n.command,timeoutMs:Math.min(2e4,r),signal:n.signal})}catch(r){if(n.signal?.aborted||i(r))throw Ne(r,n.signal);if(t.kind===`usbmux`&&h(r)){if(!q(e,r))throw r;return n.onUsbmuxUnattached?.(),null}return n.onError(r),null}}function ze(e,t,n,r){let i=`${e}\n${t}\n${n}`.toLowerCase();if(i.includes(`device is busy`)&&i.includes(`connecting`))return`Target iOS device is still connecting. Keep it unlocked, wait for device trust/connection to settle, then retry.`;let a=r??`IOS_RUNNER_CONNECT_TIMEOUT`;return a===`IOS_RUNNER_DEVICE_NOT_PROVISIONED`?f(a):`${f(a)} ${b}`}function Be(e){let{port:t,url:n,logPath:i,lastError:a,deviceStates:o}=e,s=`Runner did not accept connection`,c=new r(`COMMAND_FAILED`,s,{port:t,url:n,logPath:i,lastError:a?String(a):void 0,reason:u({error:a,message:s,context:{platform:`ios`,phase:`connect`}}),hint:f(`IOS_RUNNER_CONNECT_TIMEOUT`),..._(`runner_connect_refused`)});return g(c,o)}async function $(e){let{session:t,port:n,logPath:i}=e,a=await t.testPromise,o=`Runner did not accept connection (xcodebuild exited early)`,s=t.readLogTail?.(65536)??``,c=u({message:o,stdout:s,stderr:s,context:{platform:`ios`,phase:`connect`}}),l=te(t.device),d=v(new r(`COMMAND_FAILED`,o,{stderr:s,...l})),f=d.reason===`simulator_set_destination_not_found`,p=new r(`COMMAND_FAILED`,f?x(o,t.device,l):o,{port:n,logPath:t.runnerLogPath??i,xcodebuild:{exitCode:a.exitCode,stderr:s},reason:f?d.reason:c,hint:f?d.hint:ze(o,s,s,c),...l,..._(`xcodebuild_exited_early`)});return g(p,t.startupDeviceStates)}export{K as a,A as c,le as d,oe as f,ke as i,re as l,Me as n,ae as o,ce as p,W as r,se as s,J as t,ie as u};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{L as e,P as t,q as n}from"./sdk-contracts.js";import{D as r,K as i,b as a,c as o,f as s,t as c,u as l,y as u}from"./apple-runner-platform.js";function d(e,t){return{deadline:e!==void 0&&Number.isFinite(e)?s.fromTimeoutMs(Math.max(0,e)):void 0,signal:t}}function f(e,t){let n=e?.deadline;if(!n)return;let r=Math.floor(n.remainingMs());if(r<=0)throw p(t);return r}function p(e){return new t(`COMMAND_FAILED`,`The Apple runner budget ran out before this step began`,{phase:e,reason:`runner_phase_budget_exhausted`,retriable:!0})}function m(e){return e instanceof t&&e.details?.reason===`runner_phase_budget_exhausted`}function h(t){let n=t?.deadline,r=s.fromTimeoutMs(Math.min(45e3,n?n.remainingMs():1/0));return{attemptTimeoutMs:()=>Math.min(c,Math.floor(r.remainingMs())),throwIfCanceled:()=>{if(t?.signal?.aborted)throw e({phase:`apple_toolchain_probe`})}}}let g;function _(){return g??=a({ttlMs:6e5,scheduleExpiry:!0}),g}function v(e,t){let n=h(t);n.throwIfCanceled();let r=y(e),i=_().get(r);if(i)return _().set(r,i),i;let a=x(e,n);if(!a.ok)throw S(a.failures);return _().set(r,a.value),a.value}function y(e){return`${u()??``}\0${e}`}function b(e){return _().get(y(l(o(e),e.kind)))?.xcodeVersion}function x(e,t){let n=E(C(`xcodebuild`,[`-version`],t)),r=C(`xcrun`,[`--sdk`,e,`--show-sdk-version`],t),i=C(`xcrun`,[`--sdk`,e,`--show-sdk-build-version`],t);return!n.ok||!r.ok||!i.ok?{ok:!1,failures:[n,r,i].flatMap(e=>e.ok?[]:[e.failure])}:{ok:!0,value:{xcodeVersion:n.value.version,xcodeBuildVersion:n.value.buildVersion,sdkName:e,sdkVersion:r.value,sdkBuildVersion:i.value}}}function S(e){return new t(`COMMAND_FAILED`,`Could not read the Xcode toolchain versions the Apple runner cache is keyed on (${e.map(e=>`${e.probe}: ${e.detail}`).join(`; `)})`,{reason:`apple_toolchain_probe_unavailable`,retriable:!0,probes:e,hint:"The Apple runner cache is keyed on the toolchain version, so a cache decision cannot be made without it. Retry once the host is less loaded, or check `xcode-select -p` and `xcodebuild -version`."})}function C(e,t,r){let i=[e,...t].join(` `),a;try{a=w(e,t,r)}catch(e){if(r.throwIfCanceled(),n(e)||m(e))throw e;return D(i,`probe_error`,e instanceof Error?e.message:`${e}`)}if(a.exitCode!==0)return D(i,`nonzero_exit`,`exit ${a.exitCode}${a.stderr.trim()?`: ${a.stderr.trim()}`:``}`);let o=a.stdout.trim();return o?{ok:!0,value:o}:D(i,`empty_output`,`no output`)}function w(e,t,n){try{return T(e,t,n)}catch(i){if(!r(i))throw i;return T(e,t,n)}}function T(e,t,n){n.throwIfCanceled();let r=n.attemptTimeoutMs();if(r<=0)throw p(`apple_toolchain_probe`);return i(e,t,{allowFailure:!0,timeoutMs:r,maxBuffer:131072})}function E(e){if(!e.ok)return e;let t=e.value.match(/^Xcode\s+(.+)$/m)?.[1]?.trim(),n=e.value.match(/^Build version\s+(.+)$/m)?.[1]?.trim();return!t||!n?D(`xcodebuild -version`,`unparsable_output`,`unrecognized output: ${e.value.replaceAll(`
|
|
2
2
|
`,` `)}`):{ok:!0,value:{version:t,buildVersion:n}}}function D(e,t,n){return{ok:!1,failure:{probe:e,reason:t,detail:n.length>200?`${n.slice(0,200)}…`:n}}}export{f as i,v as n,d as r,b as t};
|
package/dist/src/runner.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime.js";import{B as t,P as n,rt as r,z as i}from"./sdk-contracts.js";import{j as a}from"./sdk-device.js";import{r as o}from"./touch-runtime.js";import{t as s}from"./runner-cache-metadata.js";import{AsyncLocalStorage as c}from"node:async_hooks";const l=new c;function u(e,t){return{runCommand:e,...t}}function d(e,t,n={}){let r=f(e,n);return m(r?r.provider:t)}function f(e,t={}){let n=l.getStore();return n&&n.deviceId===e.id&&(n.requestId?n.requestId===t.requestId:!t.requestId)?n:void 0}async function p(e,t,n){if(!e)return await n();let r={provider:m(e),deviceId:t.deviceId,requestId:t.requestId};return await l.run(r,n)}function m(e){return typeof e==`function`?{runCommand:e,hasLiveSession:()=>!0}:e}const h=[`tap`,`doubleTap`,`longPress`];function g(e){return typeof e==`string`&&h.includes(e)}function _(e,t){return i(new n(`INVALID_ARGS`,e,{...t,reason:`runner_sequence_invalid`}),`no`)}function v(e,t,n){return _(n,{stepIndex:e,kind:typeof t==`string`?t:void 0})}function y(e){if(!Array.isArray(e)||e.length===0)throw _(`sequence requires at least one step`,{stepCount:Array.isArray(e)?e.length:0});if(e.length>20)throw _(`sequence accepts at most 20 steps, received ${e.length}`,{stepCount:e.length,maxSteps:20});e.forEach((e,t)=>b(e,t))}function b(e,t){if(!g(e.kind))throw v(t,e.kind,`sequence step ${t} has unsupported kind "${String(e.kind)}"; allowed: ${h.join(`, `)}`);if(!Number.isFinite(e.x)||!Number.isFinite(e.y))throw v(t,e.kind,`sequence step ${t} (${e.kind}) requires finite x and y`);e.durationMs!==void 0&&x(e.durationMs,0,1e4,t,e.kind,`durationMs`),e.pauseMs!==void 0&&x(e.pauseMs,0,1e4,t,e.kind,`pauseMs`)}function x(e,t,n,r,i,a){if(!Number.isFinite(e)||e<t||e>n)throw v(r,i,`sequence step ${r} (${i}) ${a} must be between ${t} and ${n}`)}function S(e,t){return y(e),{command:`sequence`,steps:e,appBundleId:t}}async function C(e,n,r,i,a){let o=w(T(e,n,r),20).map(e=>S(e,i)),s,c,l=0,u=[],d=0;for(let e of o){let n;try{n=await a(e)}catch(e){throw t(e,l)}s??=n,c=n;let r;try{r=O(n)}catch(e){throw t(D(e,d),l+E(e))}l+=r.completedSteps,u.push(...r.results),d+=e.steps?.length??0}return{...s??{},completedSteps:l,sequenceResults:u,...c?.gestureEndUptimeMs===void 0?{}:{gestureEndUptimeMs:c.gestureEndUptimeMs},timingMode:`runner-sequence`}}function w(e,t,n=2e4){let r=[],i=[],a=0;for(let o of e){let e=(o.durationMs??0)+(o.pauseMs??0)+250;i.length>0&&(i.length>=t||a+e>n)&&(r.push(i),i=[],a=0),i.push(o),a+=e}return i.length>0&&r.push(i),r}function T(e,t,n){let r=n.doubleTap?`doubleTap`:n.holdMs>0?`longPress`:`tap`,i=r===`tap`&&a(e);return Array.from({length:n.count},(e,a)=>{let[s,c]=o(a,n.jitterPx);return{kind:r,x:t.x+s,y:t.y+c,...i?{synthesized:!0}:{},...n.holdMs>0?{durationMs:n.holdMs}:{},...a<n.count-1&&n.intervalMs>0?{pauseMs:n.intervalMs}:{}}})}function E(e){let t=e instanceof n?e.details?.completedSteps:void 0;return typeof t==`number`?t:0}function D(e,t){if(t===0||!(e instanceof n)||!e.details)return e;let r=e.details.failedStepIndex;if(typeof r!=`number`)return e;let i=e.details.completedSteps;return new n(e.code,e.message,{...e.details,failedStepIndex:r+t,chunkStepIndex:r,...typeof i==`number`?{completedSteps:t+i}:{}},e.cause)}function O(e){let t=A(e.sequenceResults),n=typeof e.completedSteps==`number`&&Number.isFinite(e.completedSteps)?e.completedSteps:t.filter(e=>e.ok).length,r=t.findIndex(e=>!e.ok),i=typeof e.failedStepIndex==`number`&&Number.isFinite(e.failedStepIndex)?e.failedStepIndex:r>=0?r:void 0;if(i!==void 0)throw k(t,n,i);return{results:t,completedSteps:n,failedStepIndex:i}}function k(e,t,i){let a=e[i],o=a?.kind??`step`,s=a?.errorMessage??`sequence step ${i} (${o}) failed`;return new n(r(a?.errorCode),s,{failedStepIndex:i,failedStepKind:o,completedSteps:t,sequenceResults:e,hint:`Run snapshot -i to inspect the current UI, then continue from the observed state.`})}function A(e){return Array.isArray(e)?e.map(e=>{let t=e??{};return{ok:t.ok===!0,kind:typeof t.kind==`string`?t.kind:`unknown`,errorCode:typeof t.errorCode==`string`?t.errorCode:void 0,errorMessage:typeof t.errorMessage==`string`?t.errorMessage:void 0,gestureStartUptimeMs:typeof t.gestureStartUptimeMs==`number`?t.gestureStartUptimeMs:void 0,gestureEndUptimeMs:typeof t.gestureEndUptimeMs==`number`?t.gestureEndUptimeMs:void 0}}):[]}var j=e({IOS_RUNNER_CONTAINER_BUNDLE_IDS:()=>s,withAppleRunnerProvider:()=>p});export{u as a,C as i,S as n,d as o,O as r,p as s,j as t};
|
|
1
|
+
import{r as e}from"./rolldown-runtime.js";import{B as t,P as n,V as r,it as i}from"./sdk-contracts.js";import{g as a,j as o}from"./sdk-device.js";import{r as s}from"./touch-runtime.js";import{C as c,O as l,a as u,c as d,i as ee,u as f,z as te}from"./apple-runner-platform.js";import{n as ne}from"./runner-toolchain-probe.js";import{AsyncLocalStorage as re}from"node:async_hooks";import p from"node:crypto";import m from"node:fs";import ie from"node:os";import h from"node:path";const g=new re;function ae(e,t){return{runCommand:e,...t}}function oe(e,t,n={}){let r=se(e,n);return v(r?r.provider:t)}function se(e,t={}){let n=g.getStore();return n&&n.deviceId===e.id&&(n.requestId?n.requestId===t.requestId:!t.requestId)?n:void 0}async function _(e,t,n){if(!e)return await n();let r={provider:v(e),deviceId:t.deviceId,requestId:t.requestId};return await g.run(r,n)}function v(e){return typeof e==`function`?{runCommand:e,hasLiveSession:()=>!0}:e}const y=[`tap`,`doubleTap`,`longPress`];function ce(e){return typeof e==`string`&&y.includes(e)}function b(e,r){return t(new n(`INVALID_ARGS`,e,{...r,reason:`runner_sequence_invalid`}),`no`)}function x(e,t,n){return b(n,{stepIndex:e,kind:typeof t==`string`?t:void 0})}function le(e){if(!Array.isArray(e)||e.length===0)throw b(`sequence requires at least one step`,{stepCount:Array.isArray(e)?e.length:0});if(e.length>20)throw b(`sequence accepts at most 20 steps, received ${e.length}`,{stepCount:e.length,maxSteps:20});e.forEach((e,t)=>S(e,t))}function S(e,t){if(!ce(e.kind))throw x(t,e.kind,`sequence step ${t} has unsupported kind "${String(e.kind)}"; allowed: ${y.join(`, `)}`);if(!Number.isFinite(e.x)||!Number.isFinite(e.y))throw x(t,e.kind,`sequence step ${t} (${e.kind}) requires finite x and y`);e.durationMs!==void 0&&C(e.durationMs,0,1e4,t,e.kind,`durationMs`),e.pauseMs!==void 0&&C(e.pauseMs,0,1e4,t,e.kind,`pauseMs`)}function C(e,t,n,r,i,a){if(!Number.isFinite(e)||e<t||e>n)throw x(r,i,`sequence step ${r} (${i}) ${a} must be between ${t} and ${n}`)}function w(e,t){return le(e),{command:`sequence`,steps:e,appBundleId:t}}async function ue(e,t,n,i,a){let o=de(fe(e,t,n),20).map(e=>w(e,i)),s,c,l=0,u=[],d=0;for(let e of o){let t;try{t=await a(e)}catch(e){throw r(e,l)}s??=t,c=t;let n;try{n=T(t)}catch(e){throw r(me(e,d),l+pe(e))}l+=n.completedSteps,u.push(...n.results),d+=e.steps?.length??0}return{...s??{},completedSteps:l,sequenceResults:u,...c?.gestureEndUptimeMs===void 0?{}:{gestureEndUptimeMs:c.gestureEndUptimeMs},timingMode:`runner-sequence`}}function de(e,t,n=2e4){let r=[],i=[],a=0;for(let o of e){let e=(o.durationMs??0)+(o.pauseMs??0)+250;i.length>0&&(i.length>=t||a+e>n)&&(r.push(i),i=[],a=0),i.push(o),a+=e}return i.length>0&&r.push(i),r}function fe(e,t,n){let r=n.doubleTap?`doubleTap`:n.holdMs>0?`longPress`:`tap`,i=r===`tap`&&o(e);return Array.from({length:n.count},(e,a)=>{let[o,c]=s(a,n.jitterPx);return{kind:r,x:t.x+o,y:t.y+c,...i?{synthesized:!0}:{},...n.holdMs>0?{durationMs:n.holdMs}:{},...a<n.count-1&&n.intervalMs>0?{pauseMs:n.intervalMs}:{}}})}function pe(e){let t=e instanceof n?e.details?.completedSteps:void 0;return typeof t==`number`?t:0}function me(e,t){if(t===0||!(e instanceof n)||!e.details)return e;let r=e.details.failedStepIndex;if(typeof r!=`number`)return e;let i=e.details.completedSteps;return new n(e.code,e.message,{...e.details,failedStepIndex:r+t,chunkStepIndex:r,...typeof i==`number`?{completedSteps:t+i}:{}},e.cause)}function T(e){let t=ge(e.sequenceResults),n=typeof e.completedSteps==`number`&&Number.isFinite(e.completedSteps)?e.completedSteps:t.filter(e=>e.ok).length,r=t.findIndex(e=>!e.ok),i=typeof e.failedStepIndex==`number`&&Number.isFinite(e.failedStepIndex)?e.failedStepIndex:r>=0?r:void 0;if(i!==void 0)throw he(t,n,i);return{results:t,completedSteps:n,failedStepIndex:i}}function he(e,t,r){let a=e[r],o=a?.kind??`step`,s=a?.errorMessage??`sequence step ${r} (${o}) failed`;return new n(i(a?.errorCode),s,{failedStepIndex:r,failedStepKind:o,completedSteps:t,sequenceResults:e,hint:`Run snapshot -i to inspect the current UI, then continue from the observed state.`})}function ge(e){return Array.isArray(e)?e.map(e=>{let t=e??{};return{ok:t.ok===!0,kind:typeof t.kind==`string`?t.kind:`unknown`,errorCode:typeof t.errorCode==`string`?t.errorCode:void 0,errorMessage:typeof t.errorMessage==`string`?t.errorMessage:void 0,gestureStartUptimeMs:typeof t.gestureStartUptimeMs==`number`?t.gestureStartUptimeMs:void 0,gestureEndUptimeMs:typeof t.gestureEndUptimeMs==`number`?t.gestureEndUptimeMs:void 0}}):[]}const _e=h.join(`apple`,`runner`,`AgentDeviceRunner`),ve=h.join(`dist`,`apple`,`runner`,`AgentDeviceRunner`),ye=h.join(`apple`,`snapshot-presentation`),be=h.join(`dist`,`apple`,`snapshot-presentation`);function E(e){let t=h.join(e,_e);return m.existsSync(t)?t:h.join(e,ve)}function D(e){return h.join(E(e),`AgentDeviceRunner.xcodeproj`)}function O(e){let t=h.join(e,ye);return m.existsSync(t)?t:h.join(e,be)}const k=new Set([`.build`,`.swiftpm`,`xcuserdata`]),A=new Set([`.DS_Store`]),j=new Set([`.xcuserstate`]),M=new Set([`.build`,`.swiftpm`,`SnapshotPresentationConformance`,`Tests`,`xcuserdata`]),N=new Map;function xe(e){let t=[{path:E(e),ignoredDirectoryNames:k},{path:O(e),ignoredDirectoryNames:M}],n=Ce(t),r=Se(e,n),i=JSON.stringify(t.map(({path:e})=>e)),a=N.get(i);if(a?.fileStatsFingerprint===r)return a.sourceFingerprint;let o=p.createHash(`sha256`);for(let t of n){let n=h.relative(e,t);o.update(n),o.update(`\0`),o.update(m.readFileSync(t)),o.update(`\0`)}let s=o.digest(`hex`);return N.set(i,{fileStatsFingerprint:r,sourceFingerprint:s}),s}function Se(e,t){let n=p.createHash(`sha256`);for(let r of t){let t=h.relative(e,r),i=m.statSync(r);n.update(t),n.update(`\0`),n.update(String(i.size)),n.update(`\0`),n.update(String(Math.trunc(i.mtimeMs))),n.update(`\0`)}return n.digest(`hex`)}function Ce(e){return[...new Set(e.flatMap(({path:e,ignoredDirectoryNames:t})=>we(e,t)))].sort((e,t)=>e.localeCompare(t))}function we(e,t){return m.existsSync(e)?P(e,t,!1):[]}function P(e,t,n){let r=[];for(let i of m.readdirSync(e,{withFileTypes:!0})){let a=h.join(e,i.name);if(i.isDirectory()){if(t.has(i.name))continue;let e=n||Ee(i.name);r.push(...P(a,t,e))}else if(i.isFile()){if(n?Te(i.name):!Oe(i.name))continue;r.push(a)}}return r}function Te(e){return A.has(e)||j.has(h.extname(e))}function Ee(e){return e.endsWith(`.xcodeproj`)||e.endsWith(`.xcworkspace`)}const De=new Set([`.jpg`,`.json`,`.png`,`.swift`,`.m`,`.h`,`.plist`,`.entitlements`,`.xctestplan`,`.xcconfig`,`.storyboard`,`.xib`,`.xcscheme`,`.xcworkspacedata`]);function Oe(e){return De.has(h.extname(e))}const ke=h.join(ie.homedir(),`.agent-device`,`apple-runner`),Ae=`.agent-device-runner-cache.json`,je=[`-IDEPackageSupportDisableManifestSandbox=1`,`-IDEPackageSupportDisablePluginExecutionSandbox=1`,`ENABLE_USER_SCRIPT_SANDBOXING=NO`],F=`$(inherited) -disable-sandbox -D AGENT_DEVICE_RUNNER_ISOLATION_CANARY`,Me=`${F} -D AGENT_DEVICE_RUNNER_UNIT_TESTS`;function I(e){return e?.trim()??``}function L(e=process.env){return I(e.AGENT_DEVICE_IOS_BUNDLE_ID)||I(e.AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID)||`com.callstack.agentdevice.runner`}function R(e=process.env){return I(e.AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID)||`${L(e)}.uitests`}function Ne(e=process.env){let t=L(e),n=R(e);return Array.from(new Set([I(e.AGENT_DEVICE_IOS_RUNNER_CONTAINER_BUNDLE_ID),`${n}.xctrunner`,t].filter(e=>e.length>0)))}const z=Ne(process.env);function Pe(e,t=c(),n){let r=d(e);return{schemaVersion:3,packageVersion:te(t),runnerSourceFingerprint:xe(t),...ne(f(r,e.kind),n),platformName:r,deviceKind:e.kind,target:e.target??`mobile`,buildDestinationFamily:ee(e),runnerBundleBuildSettings:J(process.env),runnerSigningBuildSettings:q(process.env,e.kind===`device`,e),runnerPerformanceBuildSettings:Y(),runnerArchBuildSettings:X(process.env),runnerSandboxBuildArgs:Z()}}function Fe(e,t){let n=process.env.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim();return n?h.resolve(n):B(e,t)}function B(e,t){return h.join(Ie(e),V(t))}function Ie(e){return h.join(ke,`derived`,u(e))}function V(e){return`cache-${p.createHash(`sha256`).update(G(H(e))).digest(`hex`).slice(0,16)}`}function H(e){let{artifacts:t,packageVersion:n,...r}=e;return r}function Le(e,t){let n=H(e),r=H(t);return[...new Set([...Object.keys(n),...Object.keys(r)])].sort((e,t)=>e.localeCompare(t)).flatMap(e=>{let t=U(n[e]),i=U(r[e]);return t===i?[]:[{key:e,expected:W(t),actual:W(i)}]})}function U(e){return e===void 0?`(absent)`:G(e)}function W(e){return e.length<=300?e:`${e.slice(0,149)}…${e.slice(-149)}`}function G(e){return JSON.stringify(K(e))}function K(e){return Array.isArray(e)?e.map(e=>K(e)):!e||typeof e!=`object`?e:Object.fromEntries(Object.entries(e).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>[e,K(t)]))}function Re(e){return a(e)||e.kind===`device`?`-maximum-concurrent-test-device-destinations`:`-maximum-concurrent-test-simulator-destinations`}function q(e=process.env,t=!1,n={platform:`apple`}){if(a(n))return[`CODE_SIGNING_ALLOWED=NO`,`CODE_SIGNING_REQUIRED=NO`,`CODE_SIGN_IDENTITY=`,`DEVELOPMENT_TEAM=`];if(!t)return[];let r=e.AGENT_DEVICE_IOS_TEAM_ID?.trim()||``,i=e.AGENT_DEVICE_IOS_SIGNING_IDENTITY?.trim()||``,o=e.AGENT_DEVICE_IOS_PROVISIONING_PROFILE?.trim()||``,s=[`CODE_SIGN_STYLE=${o?`Manual`:`Automatic`}`];return r&&s.push(`DEVELOPMENT_TEAM=${r}`),i&&s.push(`CODE_SIGN_IDENTITY=${i}`),o&&s.push(`PROVISIONING_PROFILE_SPECIFIER=${o}`),s}function J(e=process.env){let t=L(e),n=R(e);return[`AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID=${t}`,`AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID=${n}`]}function Y(){return[`COMPILER_INDEX_STORE_ENABLE=NO`,`ENABLE_CODE_COVERAGE=NO`,`ONLY_ACTIVE_ARCH=YES`,`ENABLE_PREVIEWS=NO`,`ENABLE_DEBUG_DYLIB=NO`]}function X(e=process.env){let t=e.AGENT_DEVICE_XCUITEST_ARCHS?.trim();return t?[`ARCHS=${t}`]:[]}function ze(e){let t=h.join(e,`Build`,`Intermediates.noindex`);return[`SYMROOT=${h.join(e,`Build`,`Products`)}`,`OBJROOT=${t}`,`SHARED_PRECOMPS_DIR=${h.join(t,`PrecompiledHeaders`)}`]}function Z(){return[...je,`OTHER_SWIFT_FLAGS=${Be(process.env)}`]}function Be(e){return l(e.AGENT_DEVICE_XCUITEST_INCLUDE_UNIT_TESTS)?Me:F}const Ve=/^\s*Build settings from command line:\s*$/,He=/^\s+([A-Z][A-Z0-9_]*)\s*=\s*(.*)$/,Q=/^([A-Z][A-Z0-9_]*)=(.*)$/,Ue=/^\s*Command line invocation:\s*$/;function We(e){let t;try{t=m.readFileSync(e,`utf8`)}catch{return null}let n=t.split(`
|
|
2
|
+
`),r=new Map,i=!1,a=``;for(let[e,t]of n.entries()){if(Ue.test(t)){a=n[e+1]??``;continue}if(Ve.test(t)){i=!0;continue}if(!i)continue;let o=He.exec(t);if(!o)break;r.set(o[1],o[2].trimEnd())}return i?{settings:r,invocationLine:a}:null}function $(e){return[...e.runnerBundleBuildSettings,...e.runnerSigningBuildSettings,...e.runnerPerformanceBuildSettings,...e.runnerArchBuildSettings,...e.runnerSandboxBuildArgs]}function Ge(e){let t={};for(let n of $(e)){let e=Q.exec(n);e&&(t[e[1]]=e[2])}return t}function Ke(e,t){return $(e).filter(e=>!Q.test(e)).filter(e=>!t.includes(e)).map(e=>({key:`(invocation flag)`,expected:e,actual:`absent from the "Command line invocation:" line`}))}function qe(e,t){let n=We(t);return n?[...Object.entries(Ge(e)).filter(([e,t])=>{let r=n.settings.get(e);return r===void 0?t!==``:r!==t}).map(([e,t])=>({key:e,expected:t,actual:n.settings.get(e)??`(absent)`})),...Ke(e,n.invocationLine)]:[{key:`(build log)`,expected:`a "Build settings from command line:" block`,actual:`missing or unreadable log`}]}function Je(e,t){let r=qe(e,t);if(r.length!==0)throw new n(`COMMAND_FAILED`,`The Apple runner build did not use the settings its cache identity records`,{reason:`runner_build_settings_mismatch`,buildLogPath:t,differences:r,hint:`Align the build invocation with the runner cache identity resolvers, or rebuild without the cache.`})}var Ye=e({IOS_RUNNER_CONTAINER_BUNDLE_IDS:()=>z,withAppleRunnerProvider:()=>_});export{ue as C,_ as E,T as S,oe as T,Z as _,Le as a,D as b,L as c,J as d,V as f,Y as g,Re as h,H as i,X as l,B as m,z as n,Je as o,Fe as p,Ae as r,Pe as s,Ye as t,ze as u,q as v,ae as w,w as x,G as y};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as e,n as t,o as n,t as r}from"./runtime-factory.js";function i(i){let a=r(i);return{...a,capture:t(a),selectors:n(a),interactions:e(a)}}export{i as createCommandSurfaceAgentDevice};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{P as e}from"./sdk-contracts.js";import{E as t}from"./sdk-device.js";import{
|
|
1
|
+
import{P as e}from"./sdk-contracts.js";import{E as t}from"./sdk-device.js";import{en as n}from"./sdk-batch.js";const r={support:`supported`},i={support:`unsupported`},a={lease:r,inventory:{support:`partial`,note:`Inventory exposes only the leased cloud device, not the provider catalog.`},install:{support:`partial`,note:`Requires provider-specific upload or a path visible to the remote Appium server.`},snapshot:{support:`partial`,note:`Uses Appium page source XML, not agent-device native snapshot backends.`},screenshot:r,tap:r,doubleTap:r,longPress:r,swipe:r,scroll:{support:`partial`,note:`Implemented as viewport-relative W3C pointer gestures.`},fill:r,type:r,keyboard:{support:`partial`,note:"Enter presses Android keycode 66 through `mobile: pressKey` and types a newline into the focused iOS field; dismiss uses the Appium hide-keyboard route, and Android status uses the Appium keyboard probe."},back:r,home:{support:`partial`,note:`Uses provider/Appium mobile pressButton support where available.`},orientation:{support:`partial`,note:`Uses the WebDriver rotation/orientation endpoints; four-way rotation collapses to portrait/landscape on drivers that only accept the two-way endpoint. Rotates the current display, so an activity that does not pin its orientation may need rotating again once it is foreground.`},appSwitcher:{support:`partial`,note:`Uses provider/Appium mobile pressButton support where available.`},tvRemote:i,"clipboard.read":{support:`partial`,note:`Uses provider/Appium clipboard extension support where available.`},"clipboard.write":{support:`partial`,note:`Uses provider/Appium clipboard extension support where available.`},settings:i,alert:i,pinch:i,rotateGesture:i,transformGesture:i,logs:i,record:i,artifacts:i,portReverse:i,nativeSnapshotBackend:{support:`unsupported`,note:`Cloud WebDriver cannot upload or run agent-device native runner/helper backends.`}};function o(e){return{provider:e.provider,platform:e.platform,snapshotBackend:e.platform===`ios`?`xctest`:`android`,snapshotSource:`appium-page-source`,operations:l(a,e.overrides)}}function s(e,t){return e.operations[t].support!==`unsupported`}function c(e,t){let n=e.operations[t],r=n.note?` ${n.note}`:``;return`${e.provider} WebDriver runtime does not support ${t}.${r}`}function l(e,t){let n={...e};for(let[r,i]of Object.entries(t??{}))n[r]=typeof i==`string`?{...e[r],support:i}:{...e[r],...i};return n}function u(e,t,n={}){return{platformName:e===`ios`?`iOS`:`Android`,"appium:deviceName":t,...n}}function d(e,t){let n=e?.bundleId??t?.appIdentifierHint,r=e?.packageName??t?.packageNameHint;return{bundleId:n,packageName:r,appName:e?.appName,launchTarget:p(e?.launchTarget,n,r)}}function f(e){return e===`ios`?`xctest`:`android`}function p(...e){return e.find(e=>e!==void 0)}const m=n(`owner-capability-missing`,`The WebDriver provider session is no longer active for this device.`);function h(e){let t=async(t,n,r,i,a)=>{let o=e.findSessionForDevice(t);if(!o)return;let s=await _(e,o,t,n,r.uploadPath,i,a);return await o.client.installApp(s?.appReference??r.appPath,a),d(s,i)},n=async(e,n,r,i,a)=>await t(e,n,{appPath:r,uploadPath:r},i,a);return Object.freeze({fact:t=>g(e.findSessionForDevice(t)),installApp:n,installInstallablePath:async(e,t,r,i)=>await n(e,``,t,r,i),deployApp:async(e,t,r)=>v(await n(e,t.app,t.appPath,{relaunch:t.replaceExisting,appIdentifierHint:t.app,packageNameHint:t.app},r),t.app),deployMaterializedApp:async(e,n,r)=>v(await t(e,``,{appPath:n.artifact.installablePath,uploadPath:n.artifact.uploadPath??n.artifact.installablePath},{appIdentifierHint:n.artifact.bundleId,packageNameHint:n.artifact.packageName},r))})}function g(e){return e?s(e.capabilities,`install`)?Object.freeze({available:!0}):n(`owner-capability-missing`,c(e.capabilities,`install`)):m}async function _(n,r,i,a,o,l,u){if(!s(r.capabilities,`install`))throw new e(`UNSUPPORTED_OPERATION`,c(r.capabilities,`install`),{provider:n.provider,deviceId:i.id,platform:t(i)});let d=r.prepared.uploadApp??n.uploadApp;if(d)return await d({provider:n.provider,lease:r.lease,device:i,app:a,appPath:o,options:l,signal:u})}function v(t,n){if(!t)throw new e(`UNSUPPORTED_OPERATION`,`The WebDriver provider session no longer supports app deployment.`);return{...t.bundleId?{bundleId:t.bundleId}:{},...t.packageName?{packageName:t.packageName}:{},...t.appName?{appName:t.appName}:{},...t.launchTarget??n?{launchTarget:t.launchTarget??n}:{}}}export{s as a,u as i,m as n,o,f as r,c as s,h as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{B as e,C as t,D as n,I as r,N as i,P as a,S as o,q as s,x as c,y as l}from"./sdk-contracts.js";import{H as u,St as d}from"./tv-remote.js";import{i as f,t as p}from"./snapshot-capture-annotations.js";import{l as m,n as h}from"./android-input-ownership.js";import{_ as g,c as _,d as v,g as y,h as b,l as ee,m as te,p as ne,v as re}from"./back-mode.js";import{An as ie,Ar as ae,Bn as oe,Er as x,Ir as se,Jn as ce,Jr as le,Kr as S,Ln as ue,Nn as de,Nr as fe,On as pe,Qr as me,Rn as C,Sn as w,Vn as he,Wn as ge,Xn as _e,cr as ve,hr as ye,mr as be,pr as xe,qn as T,un as Se,wn as Ce,zn as we}from"./sdk-batch.js";import{n as Te,r as Ee,t as De}from"./target-evidence-tree.js";import{n as Oe,t as ke}from"./mobile-snapshot-semantics.js";import{t as E}from"./interaction-error.js";import{n as Ae,r as je,t as Me}from"./absence-observation-errors.js";import{n as Ne}from"./react-native-overlay2.js";import"./overlay.js";import{i as D,n as Pe,t as Fe}from"./rect-center.js";import{a as Ie,n as Le,t as Re}from"./gesture-plan.js";import{t as ze}from"./android-snapshot-quality.js";import{n as Be,r as Ve}from"./snapshot-chrome.js";import{O as He,_ as Ue,a as O,c as We,f as Ge,g as Ke,i as qe,m as Je,n as Ye,o as Xe,p as Ze,s as Qe,t as k,y as $e}from"./selector-pipeline-policy.js";import{a as et,n as tt,o as nt}from"./png-worker-client.js";import{o as rt}from"./png-worker-contract.js";import{i as it}from"./ios-system-surface.js";import{r as at}from"./png-resize.js";import{n as ot}from"./ios-snapshot-acquisition.js";import{n as st,r as ct}from"./quality-warnings.js";import{n as lt,t as A}from"./snapshot-quality-verdict.js";import{n as ut}from"./command-policy.js";import{n as dt,t as ft}from"./snapshot-evidence.js";import{n as pt,t as j}from"./snapshot-node-lookup.js";import{n as mt,t as M}from"./wait.js";import{n as ht,t as gt}from"./replay2.js";import{t as _t}from"./android-system-surface-disclosure.js";import{promises as N}from"node:fs";import vt from"node:path";function P(e,t){return{session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata}}function F(e){return e.clock?.now()??Date.now()}async function yt(e,t){e.clock?await e.clock.sleep(t):await new Promise(e=>setTimeout(e,t))}function bt(e,t){return Object.fromEntries(Object.entries(e).map(([e,n])=>[e,e=>n(t,e)]))}function I(e){return e&&typeof e==`object`?e:void 0}async function L(e,t,n){if(!e.backend.captureSnapshot)throw new a(`UNSUPPORTED_OPERATION`,`snapshot is not supported by this backend`);let r=t.session??`default`,i=await e.sessions.get(r);if(!i)throw new a(`SESSION_NOT_FOUND`,`No active session. Run open first.`);let o=await e.backend.captureSnapshot(P(e,t),{interactiveOnly:n,includeRects:!0}),s=o.snapshot??{nodes:o.nodes??[],truncated:o.truncated,backend:o.backend,createdAt:F(e)};return await e.sessions.set({...i,snapshot:s}),{snapshot:s}}function R(e){return{nodes:e.nodes,...e.iosSystemSurfaceBundleId?{surfaceBundleId:e.iosSystemSurfaceBundleId}:{}}}function xt(e,t){if(!e||e.surfaceBundleId===t.surfaceBundleId)return;let n={from:e.surfaceBundleId??`app`,to:t.surfaceBundleId??`app`};return{...n,disclosure:it(n)}}function St(e,t){let n=ft(e.nodes),r=xt(t,e);if(r)return{...n,changedFromBefore:!0,surfaceChange:r};let i=t!==void 0&&n.digest!==ft(t.nodes).digest;return{...n,changedFromBefore:i}}function Ct(e){return`${e.disclosure} The settled tree and the pre-action tree describe different surfaces (${e.from} → ${e.to}), so no settled diff or refs are shown; take a snapshot to read the current surface.`}function wt(e,t){let n=o(e.type??`Element`),r=te(e,n),i=g(e).join(`,`),a=e.hittable===!0?`hittable`:`not-hittable`;return[String(t??e.depth??0),n,r,i,a,e.actions?JSON.stringify(e.actions):``].join(`|`)}function Tt(e,t,n={}){let r=Ot(Dt(e,n),Dt(t,n)),i={additions:0,removals:0,unchanged:0};for(let e of r)e.kind===`added`&&(i.additions+=1),e.kind===`removed`&&(i.removals+=1),e.kind===`unchanged`&&(i.unchanged+=1);return{summary:i,lines:r}}function Et(e,t={}){return Dt(e,t).length}function Dt(e,t){return t.flatten?e.map(e=>({text:y(e,0,!1),comparable:wt(e,0),...t.withRefs&&e.ref?{ref:e.ref}:{}})):ne(e).map(e=>({text:e.text,comparable:wt(e.node,e.depth),...t.withRefs&&e.node.ref?{ref:e.node.ref}:{}}))}function Ot(e,t){let n=e.length,r=t.length,i=n+r,a=new Map,o=[];a.set(1,0);for(let s=0;s<=i;s+=1){o.push(new Map(a));for(let i=-s;i<=s;i+=2){let c=At(a,i,s)?z(a,i+1):z(a,i-1)+1,l=c-i;for(;c<n&&l<r&&e[c].comparable===t[l].comparable;)c+=1,l+=1;if(a.set(i,c),c>=n&&l>=r)return kt(o,e,t,n,r)}}return[]}function kt(e,t,n,r,i){let a=[],o=r,s=i;for(let r=e.length-1;r>=0;--r){let i=e[r],c=o-s,l=At(i,c,r)?c+1:c-1,u=z(i,l),d=u-l;for(;o>u&&s>d;)a.push({kind:`unchanged`,text:n[s-1].text}),--o,--s;if(r===0)break;if(o===u){let e=n[d];a.push({kind:`added`,text:e.text,...e.ref?{ref:e.ref}:{}}),s=d}else a.push({kind:`removed`,text:t[u].text}),o=u}return a.reverse(),a}function At(e,t,n){return t===-n||t!==n&&z(e,t-1)<z(e,t+1)}function z(e,t){return e.get(t)??0}function jt(e){return e===`text`||e===`label`||e===`any`}function Mt(e,t,n,r){if(!(r||e===`web`))return jt(t)?n:void 0}function Nt(e){return new a(`COMMAND_FAILED`,`find could not read the current accessibility tree`,{reason:e.reason,hint:`The snapshot quality verdict is sparse. Use screenshot as visual truth, navigate with coordinates if needed, then retry find after reaching a readable screen.`})}async function Pt(e,t){let n=t??`default`,r=await e.sessions.get(n);if(!r)throw new a(`SESSION_NOT_FOUND`,`No active session. Run open first.`);let i=r.refFrameSnapshot??r.snapshot;if(!i)throw new a(`INVALID_ARGS`,`No snapshot in session. Run snapshot first.`);return{sessionName:n,session:r,snapshot:i}}async function B(e,t,n={updateSession:!0}){let r=e.backend.captureSnapshot;if(!r)throw new a(`UNSUPPORTED_OPERATION`,`snapshot is not supported by this backend`);let i=t.session??`default`,o=await e.sessions.get(i),s=Ft(await r(P(e,t),{interactiveOnly:n.interactiveOnly??!1,depth:t.depth,scope:n.scope??t.scope,raw:t.raw,includeRects:n.includeRects,...n.preferredBackend?{preferredBackend:n.preferredBackend}:{},...n.includeHiddenContentHints===void 0?{}:{includeHiddenContentHints:n.includeHiddenContentHints}}),e);return(t.signal??e.signal)?.throwIfAborted(),n.updateSession&&o&&!A(s.snapshotQuality)&&await e.sessions.set({...o,snapshot:s}),{sessionName:i,session:o,snapshot:s}}function Ft(e,t){return e.snapshot?It(e.snapshot,e):{nodes:e.nodes??[],truncated:e.truncated,backend:e.backend,...e.quality?{snapshotQuality:e.quality}:{},createdAt:F(t)}}function It(e,t){let n={...e};return t.truncated===!0||n.truncated===!0?n.truncated=!0:t.truncated!==void 0&&(n.truncated=t.truncated),t.quality&&n.snapshotQuality===void 0&&(n.snapshotQuality=t.quality),n}async function Lt(e,t,n){if(e.backend.readText){let r=await e.backend.readText(P(e,{session:t.sessionName}),n);if(r.text.trim())return r.text}return re(n)}function Rt(e,t,r){let i=n(t);if(!i)throw new a(`INVALID_ARGS`,r.invalidRefMessage);let o=c(e,i)??(r.fallbackLabel.length>0?pt(e,r.fallbackLabel):null);if(!o)throw new a(`COMMAND_FAILED`,r.notFoundMessage,{reason:E.refNotFound,ref:i,hint:w});return{ref:i,node:o}}function zt(t,n){let{diagnostics:r=[],unique:i=!0,dispatched:o,...s}=n,c=new a(`COMMAND_FAILED`,Ce(t,r,{unique:i}),{...s,reason:E.selectorNotFound,hint:pe(r)});return o===void 0?c:e(c,o)}function Bt(e,t,n){let{command:r,...i}=n;return new a(`AMBIGUOUS_MATCH`,`Selector matched ${t.length} elements: ${e}`,{...i,...b(t),command:r,selector:e,hint:`Narrow the selector with role/id/longer text, or act on a printed candidate with a command that takes refs, such as press.`})}function Vt(e){let{outcome:t,selectorExpression:n,command:r,details:i}=e;return t.kind===`ambiguous`?Bt(t.selector,t.matchedNodes,{command:r,...i}):zt(n,{command:r,unique:!0,...i})}async function Ht(e,t,n,r){let i=new AbortController,a=[t.signal,e.signal].filter(e=>e!==void 0),o=AbortSignal.any([...a,i.signal]),s=!1,c=setTimeout(()=>{s=!0,i.abort(new DOMException(`Wait deadline exceeded`,`TimeoutError`))},Math.max(0,n));c.unref();try{let e=await r(o);return s&&!a.some(e=>e.aborted)?{timedOut:!0}:(o.throwIfAborted(),{timedOut:!1,value:e})}catch(e){if(s&&!a.some(e=>e.aborted))return{timedOut:!0,error:e};throw e}finally{clearTimeout(c)}}function Ut(e){let t=e.snapshotQuality?.backend,n=(e.backend===`xctest`?Wt(e.nodes):e.nodes).map(qt);return n.sort((e,t)=>Yt(e).localeCompare(Yt(t))),{captureBackend:t,nodes:n}}function Wt(e){let t=x(e);return e.filter(e=>ae(e)||t.isVisibleOnScreen(e))}function Gt(e,t){return!e||e.captureBackend!==t.captureBackend||e.nodes.length!==t.nodes.length?!1:e.nodes.every((e,n)=>{let r=t.nodes[n];if(!r||e.identity!==r.identity)return!1;if(!e.rect||!r.rect)return e.rect===r.rect;let i=e.rect,a=r.rect;return[`x`,`y`,`width`,`height`].every(e=>Math.abs(Math.round(i[e])-Math.round(a[e]))<=1)})}function Kt(e,t){if(!e||e.nodes.length===0||t.nodes.length===0)return!1;let n=new Map;for(let t of e.nodes)n.set(t.identity,(n.get(t.identity)??0)+1);let r=0;for(let e of t.nodes){let t=n.get(e.identity)??0;t!==0&&(r+=1,n.set(e.identity,t-1))}return r/Math.max(e.nodes.length,t.nodes.length)<.5}function qt(e){return{identity:`${e.type??``}#${Jt(e)}`,...e.rect?{rect:{...e.rect}}:{}}}function Jt(e){return[e.label,e.identifier,e.value].map(e=>String(e??``).trim()).join(`#`)}function Yt(e){let t=e.rect;return`${e.identity}#${t?`${t.x},${t.y},${t.width},${t.height}`:``}`}const Xt=`Settled on a nearly-empty tree — the app may still be loading. Wait for specific content (wait text ...) before interacting.`;async function Zt(e,t,n){let{quietMs:r,timeoutMs:i}=n,a=F(e),o=a+i,s=!1,c=await e.sessions.get(t.session??`default`),l,u=lt(c?.snapshot?.snapshotQuality),d=Math.min(300,Math.max(25,r)),f=0,p,m=0,h,g=a,_=r;for(;F(e)<o;){let c=await an(e,t,o-F(e),u);if(!c)return{settled:!1,stalled:!0,waitedMs:F(e)-a,captures:f,nodeCount:m,lastCapture:h};f+=1,h=c,l??=Qt(n.broadTransitionBaselineNodes,c.snapshot,e.backend.platform);let v=Ut(c.snapshot);_=en({baseline:l,signal:v,requestedQuietMs:r,currentQuietMs:_}),u??=lt(c.snapshot.snapshotQuality);let y=F(e),b=nn({resetRequested:n.resetBudgetOnPrivateAxRecovery,alreadyReset:s,verdict:c.snapshot.snapshotQuality,nowMs:y,timeoutMs:i,deadlineMs:o});if(b!==void 0){s=!0,o=b,g=y,p=v,m=c.snapshot.nodes.length;let t=rn({nowMs:y,quietSinceMs:g,quietMs:_,pollMs:d,deadlineMs:o});if(t<=0)break;await yt(e,t);continue}if(!Gt(p,v))p=v,m=c.snapshot.nodes.length,g=y;else if(f>=2&&y-g>=_)return{settled:!0,stalled:!1,waitedMs:y-a,captures:f,nodeCount:m,lastCapture:h};let ee=rn({nowMs:y,quietSinceMs:g,quietMs:_,pollMs:d,deadlineMs:o});if(ee<=0)break;await yt(e,ee)}return{settled:!1,stalled:!1,waitedMs:F(e)-a,captures:f,nodeCount:m,lastCapture:h}}function Qt(e,t,n){if(!e||!t||!$t(t.backend,n))return;let r=t.nodes.some(ae),i=e.length<=5;if(!(!r&&!i))return Ut({...t,nodes:e})}function $t(e,t){return e===`xctest`||e===void 0&&t===`ios`}function en(e){return e.requestedQuietMs<500||!Kt(e.baseline,e.signal)?e.currentQuietMs:Math.max(e.requestedQuietMs,1500)}function tn(e){return e?.state===`recovered`&&e.backend===`private-ax`&&e.reasonCode!==`deferred`}function nn(e){if(!(e.resetRequested!==!0||e.alreadyReset||!tn(e.verdict)))return Math.max(e.deadlineMs,e.nowMs+e.timeoutMs)}function rn(e){let t=e.quietSinceMs+e.quietMs-e.nowMs,n=t>e.pollMs?e.pollMs:Math.max(25,t+2),r=e.deadlineMs-e.nowMs,i=r-1;return i<2?r>=2?r:0:Math.min(n,i)}async function an(e,t,n,r){let i=await Ht(e,t,n,async n=>await B(e,{...t,signal:n},{updateSession:!1,interactiveOnly:!0,preferredBackend:r}));return i.timedOut?void 0:i.value}const on=`The UI kept changing for the whole settle budget (animation, carousel, or ticker?), so no settled diff is shown. Raise --timeout, wait for specific content, or take a fresh snapshot.`,sn=`A snapshot capture stalled past the settle budget, so no settled diff is shown. The action itself succeeded; observe with wait stable or snapshot.`;async function cn(e,t,n){return await un(e,t,{...n,baseline:await pn(e,t,n.resolved),actionPoint:n.resolved.point})}const ln=async(e,t)=>(await un(e,t,t)).observation;async function un(e,t,n){let r=n.quietMs??500,i=n.timeoutMs??1e4,a={settled:!1,waitedMs:0,captures:0,quietMs:r,timeoutMs:i};try{return await dn(e,t,n,a,await Zt(e,t,{quietMs:r,timeoutMs:i,resetBudgetOnPrivateAxRecovery:!0,broadTransitionBaselineNodes:n.baseline.nodes}))}catch(e){return{observation:{...a,hint:`Settle observation unavailable (${e instanceof Error?e.message:String(e)}). The action itself succeeded; take a snapshot to observe the result.`}}}}async function dn(e,t,n,r,i){let a={...r,settled:i.settled,waitedMs:i.waitedMs,captures:i.captures};if(!i.lastCapture)return{observation:{...a,hint:i.stalled?sn:on}};let{stored:o,session:s}=await En(e,t,i.lastCapture),c=R(i.lastCapture.snapshot),l=c.nodes,u=xt(n.baseline,c);return{observation:{...a,...u?{surfaceChange:u}:{},...i.settled&&o&&!u?vn(n.baseline.nodes,l,n.actionPoint,s?.appBundleId):{},...wn(i,o,l.length,u)},settledCapture:c}}function fn(e,t){if(e)return St(e,t)}async function pn(e,t,n){let r=await e.sessions.get(t.session??`default`);return mn(n,r)??gn(n.preAction)??hn(r)}function mn(e,t){if(e.kind!==`ref`)return;let n=t?.refFrameSnapshot;return n?gn(R(n)):void 0}function hn(e){let t=e?.refFrameSnapshot??e?.snapshot;return t?R(t):{nodes:[]}}function gn(e){return e?.nodes.length?e:void 0}function _n(e,t,n){let r=Tt(Ve(e,n),Ve(t,n),{flatten:!0,withRefs:!0}),i=r.lines.filter(e=>e.kind!==`unchanged`),a=Cn(i).map(e=>({kind:e.kind,text:e.text,...e.ref?{ref:e.ref}:{}}));return{summary:r.summary,lines:a,...i.length>a.length?{truncated:!0}:{}}}function vn(e,t,n,r){let i=_n(e,t,r);return{diff:i,...yn(i,t,n,r)}}function yn(e,t,n,r){let i=new Set(e.lines.filter(e=>e.kind===`added`&&e.ref).map(e=>e.ref)),a=Be(t,r),o=new Map(t.filter(e=>e.ref).map(e=>[e.ref,e]));return[...i].some(e=>e!==void 0&&!a.has(e)&&!bn(o.get(e),n))?{}:Sn(t,i,r)}function bn(e,t){if(!e?.rect||!t)return!1;let{x:n,y:r,width:i,height:a}=e.rect;return t.x>=n&&t.x<=n+i&&t.y>=r&&t.y<=r+a}const xn=new Set([`application`,`window`]);function Sn(e,t,n){let r=Be(e,n),i=e.filter(e=>e.ref&&e.interactionBlocked!==`covered`&&!t.has(e.ref)&&!r.has(e.ref)&&!xn.has(o(e.type??`Element`)));if(i.length===0)return{};let a=i.slice(0,20).map(e=>{let t=o(e.type??`Element`),n=te(e,t);return{ref:e.ref,role:t,...n?{label:n}:{}}});return{tail:a,...i.length>a.length?{tailTruncated:!0}:{}}}function Cn(e){if(e.length<=80)return e;let t=e.filter(e=>e.kind===`added`),n=new Set(t.slice(0,80)),r=80-n.size,i=[];for(let t of e)n.has(t)?i.push(t):t.kind===`removed`&&r>0&&(i.push(t),--r);return i}function wn(e,t,n,r){let i=Tn(e,t,n).hint;if(!r)return i===void 0?{}:{hint:i};let a=Ct(r);return{hint:i===void 0?a:`${a} ${i}`}}function Tn(e,t,n){return e.stalled?{hint:sn}:e.settled?t?n<5?{hint:Xt}:{}:{hint:`Settled on a sparse, unreadable tree — the diff is omitted and its refs/selectors are invalid. Use screenshot as visual truth and coordinate taps; retry snapshot after navigating.`}:{hint:on}}async function En(e,t,n){if(A(n.snapshot.snapshotQuality))return{stored:!1};let r=await e.sessions.get(t.session??`default`);return r?(await e.sessions.set({...r,snapshot:n.snapshot}),{stored:!0,session:r}):{stored:!1}}function V(e){let t=e.verify===!0;return{verify:t,needsPreActionBaseline:t||e.settle!==void 0,...e.settle===void 0?{}:{settle:e.settle}}}async function H(e,t,n,r,i){let a=await Dn(e,t,n,i);return kn({...r,...a})}async function Dn(e,t,n,r){if(r.settle!==void 0){let i=await cn(e,t,{...r.settle,resolved:n}),a=r.verify?fn(i.settledCapture,n.preAction):void 0;return{settle:i.observation,...a?{evidence:a}:{}}}if(!r.verify)return{};let i=await On(e,t,n);return i?{evidence:i}:{}}async function On(e,t,n){try{return St(R((await L(e,t,!0)).snapshot),n.preAction)}catch{return}}function kn(e){let t=e;if(t.targetHittable!==!1||!An(t)||t.hint===void 0)return e;let{hint:n,...r}=t;return r}function An(e){if(e.evidence?.changedFromBefore===!0||e.settle?.surfaceChange!==void 0)return!0;let t=e.settle?.diff?.summary;return!!t&&(t.additions>0||t.removals>0)}const jn=Object.freeze({reason:`tap_keyboard_occludes_target`,hint:"The visible keyboard covers this target, so the tap would land on a key instead of on it. End editing first: tap the app's own Done/Cancel/close control, or run `keyboard enter` when submitting is what you want (`keyboard dismiss` works only when the keyboard exposes its own dismiss key). This reads the snapshot the command measured against, so if the keyboard closed since it was taken, run `snapshot -i` and retry."}),Mn=new Set([`keyboard`,`key`]);function Nn(e){return Mn.has(se(e.type??``))||h(e)}const Pn=new Set([`UIKeyboardDockItemButton`,`UIAccessibilityElementKBKey`]);function Fn(e){return Nn(e)||Pn.has(e.role??``)}function In(e,t,n){return n.has(e.index)||zn(t,n,e.index).length>0}function Ln(e){return e!==null&&le(e)}function U(e){return e.flatMap(e=>le(e.rect)?[e.rect]:[])}function Rn(e,t){let n=new Map(e.map(e=>[e.index,e.parentIndex])),r=new Set(t.map(e=>e.index)),i=new Set;for(let e of t)for(let t of zn(n,r,e.index))i.add(t);return i}function zn(e,t,n){let r=[],i=new Set,a=e.get(n);for(;typeof a==`number`&&!i.has(a);)i.add(a),t.has(a)&&r.push(a),a=e.get(a);return r}function Bn(e){let t=e.map(e=>[e.x,e.x+e.width]).sort((e,t)=>e[0]-t[0]),n=t[0]?.[1]??0;for(let[e,r]of t){if(e-n>2)return!1;n=Math.max(n,r)}return!0}function Vn(e){let t=Math.min(...e.anchorRects.map(e=>e.y)),n=Math.min(...e.anchorRects.map(e=>e.x)),r=Math.max(...e.anchorRects.map(e=>e.x+e.width)),i=e.viewport.y+e.viewport.height;return e.reportedBottom<i-80||r-n<=e.reportedBottom-t?null:{x:n,y:t,width:r-n,height:i-t}}function Hn(e){let t=U(e.anchorNodes.filter(t=>!e.planeIndices.has(t.index)));return Bn(t.length>0?t:e.anchorRects)}function Un(e){let t=e.filter(Fn),n=Rn(e,t);return U(t.filter(e=>!n.has(e.index)))}function Wn(e,t){let n=e.filter(Nn),r=U(n);if(r.length===0||!Ln(t))return null;let i=e.filter(Fn),a=U(i);if(a.length===0)return null;let o=Vn({anchorRects:r,reportedBottom:Math.max(...a.map(e=>e.y+e.height)),viewport:t});if(!o)return null;let s=Rn(e,i);return Hn({anchorNodes:n,anchorRects:r,planeIndices:s})?{frame:o,controlRects:U(i.filter(e=>!s.has(e.index)))}:null}function Gn(e){if(e.keyboard?.kind===`absent`)return{kind:`no-keyboard`};let t=e.keyboard?.kind===`visible`?{frame:e.keyboard.frame,controlRects:Un(e.nodes)}:Wn(e.nodes,e.viewport);if(!t)return e.nodes.some(Nn)?{kind:`undetermined`}:{kind:`no-keyboard`};if(!e.node)return Kn(e.point,t);let n=new Map(e.nodes.map(e=>[e.index,e.parentIndex])),r=new Set(e.nodes.filter(Fn).map(e=>e.index));return In(e.node,n,r)?{kind:`clear`,surface:t}:S(t.frame,e.point.x,e.point.y)?{kind:`occluded`,surface:t}:{kind:`clear`,surface:t}}function Kn(e,t){return t.controlRects.some(t=>S(t,e.x,e.y))?{kind:`clear`,surface:t}:S(t.frame,e.x,e.y)?{kind:`occluded`,surface:t}:{kind:`clear`,surface:t}}function qn(e){switch(e){case`fill`:return`be filled`;case`focus`:return`be focused`;case`longPress`:return`be long-pressed`;case`hover`:return`be hovered`;default:return`be tapped`}}function Jn(e){let t=e.node.rect;if(!t||!e.tapPoint)return;let n=Gn({nodes:e.nodes,viewport:x(e.nodes).resolveViewport(t),point:e.tapPoint,node:e.node,...e.keyboard?{keyboard:e.keyboard}:{}});if(n.kind===`occluded`)throw Zn({label:e.label,action:e.action,ref:e.node.ref,targetRect:t,surface:n.surface})}function Yn(e){let t=Gn({nodes:e.nodes,viewport:e.viewport,point:e.point,...e.keyboard?{keyboard:e.keyboard}:{}});if(t.kind===`occluded`)return Xn(e.point,t.surface)}function Xn(e,t){return`(${e.x}, ${e.y}) is behind the visible keyboard, so this tap lands on the keyboard rather than anything under it (${jn.reason}; keyboard frame ${Math.round(t.frame.y)}..${Math.round(t.frame.y+t.frame.height)}). `+jn.hint}function Zn(t){return e(new a(`COMMAND_FAILED`,`${t.label} is behind the visible keyboard and cannot ${qn(t.action)} safely`,{...jn,ref:`@${t.ref}`,rect:t.targetRect,keyboardFrame:t.surface.frame}),`no`)}function Qn(t){return e(new a(`COMMAND_FAILED`,`${t.label} is covered by another visible element and cannot ${qn(t.action)} safely`,{reason:E.targetCovered,hint:`Use a different visible target, scroll it clear of the overlay, or inspect with snapshot/screenshot before retrying.`,...t.selector?{selector:t.selector}:{},ref:`@${t.node.ref}`,interactionBlocked:t.node.interactionBlocked}),`no`)}async function $n(e){let t=await Xe(e.policy,e.nodes,e.node,e.hooks);if(t.kind===`occluded`)throw Qn({label:e.label,node:t.node,action:e.action});let n=e.resolveTapPoint(t.node);return Jn({nodes:e.nodes,node:t.node,action:e.action,label:e.label,...e.keyboard?{keyboard:e.keyboard}:{},tapPoint:n}),{node:t.node,tapPoint:n}}async function er(e,t,n,r,i,{action:a}){return await rr(e,t,n,r,{message:`Selector ${i} resolved to an off-screen element and is not safe to ${a}`,details:{reason:`offscreen_selector`,selector:i},hint:e=>`${nr(e,i)} then retry ${a} with the same selector. --until checks the selector between passes, so it stops on the target rather than sailing past it. If it is inside a closed drawer or another tab, open that container first.`})}async function tr(e,t,r,i,a,{action:o}){return await rr(e,t,r,i,{message:`Ref ${a} is off-screen and not safe to ${o}`,details:{reason:`offscreen_ref`,ref:n(a)},hint:e=>`${nr(e,null)} then retry ${o} with a selector (e.g. text=/id=) rather than this @ref — the scroll expires the ref frame, so re-run snapshot -i before reusing any @ref.`})}function nr(e,t){return e?t?`Run scroll ${e} --until '${t}' to bring it on screen,`:`Scroll ${e} toward it,`:`Scroll toward it,`}async function rr(t,n,r,i,o){let s=x(i),c=r.rect?s.resolveEffectiveViewport(r):null;if(!r.rect||!c||s.isVisibleOnScreen(r))return r;let l=s.resolveViewport(r.rect),u=await t.backend.confirmOffscreenTargetVisible?.(P(t,n),r,l);if(u)return{...r,rect:u};let d=Oe(r,s);throw e(new a(`COMMAND_FAILED`,o.message,{...o.details,rect:r.rect,viewport:c,...d?{scrollDirection:d}:{},hint:o.hint(d)}),`no`)}function ir(e,t,n,r){let{candidates:i,list:o}=qe(r,e,t,{platform:n}),s=o?.matchedNodes??[];if(!o||s.length===0)return null;let c=[{selector:o.selector,matches:s.length}];if(s.length===1)return{node:s[0],selector:o.selector,selectorIndex:o.selectorIndex,matches:1,diagnostics:c};let l=We(i,s);if(l.kind===`ambiguous`)throw new a(`AMBIGUOUS_MATCH`,`Selector matched ${l.candidates.length} distinct actionable elements: ${o.selector}`,{selector:o.selector,...b(l.candidates)});return{node:l.node,selector:o.selector,selectorIndex:o.selectorIndex,matches:s.length,diagnostics:c,disambiguation:{matchCount:s.length,tiebreak:`structural-equivalence`,alternatives:s.filter(e=>e.index!==l.node.index)}}}async function ar(e,n,r,i){let a=await L(e,n,i.requireInteractive),o=ir(a.snapshot.nodes,r,e.backend.platform,i.pipeline);if((!o||!o.node.rect)&&i.requireInteractive){let s=a.snapshot;a=await L(e,n,!1),t(s,a.snapshot),o=ir(a.snapshot.nodes,r,e.backend.platform,i.pipeline)}return{capture:a,resolved:o}}async function or(e){let{runtime:t,nodes:n,selectorExpression:r,action:i}=e,a=await O(k.coveredDiagnosis,n,r,{platform:t.backend.platform});if(a.kind===`occluded`)return Qn({label:`Selector ${a.selector}`,node:a.node,action:i,selector:a.selector})}async function sr(e){let{runtime:t,nodes:n,selectorExpression:r,action:i,resolved:a}=e;return await or({runtime:t,nodes:n,selectorExpression:r,action:i})||zt(r,{diagnostics:a?.diagnostics??[],unique:!0,dispatched:`no`})}async function cr(n,r,i,o,s){let c=await ar(n,r,i,o);if(s&&t(s.snapshot,c.capture.snapshot),c.resolved?.node.rect)return c;let l=c.capture.snapshot.snapshotQuality;if(A(l))throw e(new a(`COMMAND_FAILED`,`Selector ${i} was not found in a sparse capture; the tree cannot prove it absent`,{reason:E.captureSparse,snapshotQuality:l,hint:`Re-run after the screen settles, or capture a snapshot to inspect the tree.`}),`no`);let u=await or({runtime:n,nodes:c.capture.snapshot.nodes,selectorExpression:i,action:o.action});if(u)throw u;return c}async function lr(e,t,n,r){if(r.last===void 0&&r.lastError!==void 0)return r.lastError;let i={polls:r.polls.length,waitedMs:r.waitedMs,end:r.kind},a=await sr({runtime:e,nodes:r.last?.capture.snapshot.nodes??[],selectorExpression:t,action:n.action,resolved:r.last?.resolved??null});return a.details={...a.details,readiness:i},a}async function ur(e,t,n,r,i){let a=t.signal??e.signal,o,s=await $e({capture:async i=>{let a=await cr(e,{...t,signal:i},n,r,o);return o=a.capture,a},verdict:e=>e.resolved&&e.resolved.node.rect?{kind:`done`,result:{capture:e.capture,resolved:e.resolved}}:{kind:`continue`},schedule:{...i,captureDeadline:`cancel`},rideOut:ze,...a?{signal:a}:{},...e.clock?{clock:e.clock}:{},phase:`interaction_target_readiness`});if(s.kind===`done`)return s.polls.length>1?{...s.result,readiness:{polls:s.polls.length,waitedMs:s.waitedMs}}:s.result;throw s.kind===`failed`?dr(s.error,s):await lr(e,n,r,s)}function dr(e,t){if(!(e instanceof a)||e.details?.reason!==E.captureSparse)return e;let n={polls:t.polls.length,waitedMs:t.waitedMs,end:`sparse`};return e.details={...e.details,readiness:n},e}function W(t,n,r,i,o){if(!r)return;let s=T(t),c=ce(t,n);if(!(ge(s,r.identity)&&_e(c,r.structural)))throw e(new a(`COMMAND_FAILED`,`${i} resolved to a different element than replay verification isolated; the action was not sent`,{reason:gt,observed:s,observedStructural:c,expected:r.identity,expectedStructural:r.structural,...o?{targetRole:o}:{}}),`no`)}function fr(e,t,n){W(e,t,n.expectedResolvedTarget,n.action,n.replayTargetRole)}function pr(e){return e.hittable===!0||Ge(e)}function mr(e,t){let n=he(T(e),t);return n.id!==void 0||n.label!==void 0?!1:we(e.value)===null}function hr(e,t,n){let r=new Set,i=e;for(;typeof i.parentIndex==`number`;){if(r.has(i.index))return!1;if(r.add(i.index),i.parentIndex===t.index)return!0;let e=n.get(i.parentIndex);if(!e)return!1;i=e}return!1}function gr(e,t){let n=Te(t);return t.filter(t=>t.index!==e.index&&hr(t,e,n)).sort((e,t)=>e.index-t.index)}function _r(e,t){let n=D(e.rect);return!n||!t.rect?!1:S(t.rect,n.x,n.y)}function vr(e,t){if(!mr(e,t))return e;let n=gr(e,t);if(n.some(pr))return e;let r=n.find(e=>T(e).label!==void 0);return!r||!_r(r,e)?e:r}function yr(e,t){if(Buffer.byteLength(e,`utf8`)<=t)return e;let n=Buffer.byteLength(`…`,`utf8`),r=Math.max(0,t-n),i=Buffer.from(e,`utf8`),a=Math.min(r,i.length);for(;a>0&&(i[a]&192)==128;)--a;return i.subarray(0,a).toString(`utf8`)+`…`}const br={source:`ref`,phase:`pre-action`,kind:`exact`},xr={source:`ref`,phase:`pre-action`,kind:`label-fallback`};function Sr(e,t,n){return{ref:e,node:t,resolution:n===`exact`?br:xr}}const Cr={source:`runtime`,phase:`pre-action`,kind:`unique`};function wr(e,t){return e.disambiguation?{source:`runtime`,phase:`pre-action`,kind:`disambiguated`,matchCount:e.disambiguation.matchCount,winnerDiagnostic:Tr(e.node,t),tiebreak:e.disambiguation.tiebreak,alternatives:e.disambiguation.alternatives.slice(0,5).map(e=>Tr(e,t))}:Cr}function Tr(e,t){let n=se(e.type??``),r=j(e,t);return{diagnosticRef:`diag-${e.ref}`,...n?{role:yr(n,256)}:{},...r===void 0?{}:{label:yr(r,256)}}}function Er(e,t,n,r,i){let a=n.nodes;return{node:t,selectorChain:C(t,e.backend.platform,{action:r===`fill`?`fill`:`click`,nodes:a}),refLabel:j(t,a),...Or(t,r),preAction:n,resolution:i,...Dr(e,t,a,r)}}function Dr(e,t,n,r){if(r!==`click`&&r!==`press`)return{};let i=vr(t,n);return i===t?{}:{recordingTarget:{node:i,selectorChain:C(i,e.backend.platform,{action:`click`,nodes:n}),refLabel:j(i,n)}}}function Or(e,t){return e.hittable===!1?{targetHittable:!1,hint:`The resolved element reports hittable: false, so this ${t} may have had no visible effect. Verify with a snapshot, or prefer a @ref or a longer/more specific selector to target the intended element.`}:{}}function kr(e,t,n={}){let r=Pe(t.rect),i=D(r??void 0);if(!r||!i)return{kind:`invalid`};let a=Ar(e,t,r);if(a.length===0)return{kind:`resolved`,point:i,strategy:`center`};let o=(n.bounds??[]).reduce((e,t)=>e?Mr(e,t):null,r),s=o?Nr(r,o,i,a):null;return s?{kind:`resolved`,point:s,strategy:`parent-owned`}:{kind:`blocked`,competitorRefs:a.map(e=>e.ref)}}function Ar(e,t,n){let r=new Map(e.map(e=>[e.index,e]));return e.filter(e=>e.index!==t.index).filter(e=>jr(e,t,r)).filter(Ge).flatMap(e=>{let t=Pe(e.rect);if(!t||Fe(t,n))return[];let r=Mr(t,n);return r&&r.width>0&&r.height>0?[{ref:e.ref,index:e.index,rect:r}]:[]}).sort((e,t)=>e.index-t.index)}function jr(e,t,n){let r=new Set,i=e;for(;typeof i.parentIndex==`number`&&!r.has(i.index);){if(r.add(i.index),i.parentIndex===t.index)return!0;let e=n.get(i.parentIndex);if(!e)return!1;i=e}return!1}function Mr(e,t){let n=Math.max(e.x,t.x),r=Math.max(e.y,t.y),i=Math.min(e.x+e.width,t.x+t.width),a=Math.min(e.y+e.height,t.y+t.height);return i<=n||a<=r?null:{x:n,y:r,width:i-n,height:a-r}}function Nr(e,t,n,r){let i=Rr(e),a=Ir(t.x,t.width,n.x,r.flatMap(({rect:e})=>[e.x,e.x+e.width]),i),o=Ir(t.y,t.height,n.y,r.flatMap(({rect:e})=>[e.y,e.y+e.height]),i);return a.flatMap(a=>o.flatMap(o=>{let s={x:Math.round(a),y:Math.round(o)};if(!S(t,s.x,s.y))return[];let c=Pr(s,e,n,r,i);return c?[c]:[]})).sort(Fr)[0]?.point??null}function Pr(e,t,n,r,i){let a=Lr(e,t,r);return a.parentEdge<i||a.competitor<12?null:{point:e,distanceSquared:(e.x-n.x)**2+(e.y-n.y)**2,clearance:Math.min(a.parentEdge,a.competitor)}}function Fr(e,t){return e.distanceSquared-t.distanceSquared||t.clearance-e.clearance||e.point.y-t.point.y||e.point.x-t.point.x}function Ir(e,t,n,r,i){let a=e+i,o=e+t-i;if(a>o)return[];let s=[...new Set([e,e+t,...r])].sort((e,t)=>e-t),c=new Set([n,a,o]);for(let e of r)c.add(e-12),c.add(e+12);for(let e=1;e<s.length;e+=1)c.add((s[e-1]+s[e])/2);return[...c].filter(e=>e>=a&&e<=o).sort((e,t)=>e-t)}function Lr(e,t,n){let r=Math.min(e.x-t.x,t.x+t.width-e.x,e.y-t.y,t.y+t.height-e.y),i=1/0;for(let{rect:t}of n){let n=e.x<t.x?t.x-e.x:Math.max(0,e.x-(t.x+t.width)),r=e.y<t.y?t.y-e.y:Math.max(0,e.y-(t.y+t.height));i=Math.min(i,Math.max(n,r))}return{parentEdge:r,competitor:i}}function Rr(e){let t=Math.min(e.width,e.height);return Math.max(0,Math.min(12,Math.floor(t/2)-1))}function zr(t,n,r){let i=x(n),o=kr(n,t,{bounds:[i.resolveEffectiveViewport(t),t.rect?i.resolveViewport(t.rect):null].filter(e=>e!==null)});if(o.kind===`resolved`)return o.point;throw o.kind===`invalid`?e(new a(`COMMAND_FAILED`,r.invalidMessage,{reason:E.targetBoundsInvalid,...Br(r.blockedTargetDetails)}),`no`):e(new a(`COMMAND_FAILED`,`${r.blockedTargetLabel} has no parent-owned touch point outside its interactive descendants`,{reason:`covered_by_interactive_descendants`,...r.blockedTargetDetails,competitorRefs:o.competitorRefs.slice(0,5).map(e=>`@${e}`),competitorCount:o.competitorRefs.length,hint:`Tap the specific interactive child you intend, or use a more specific selector. Every safely tappable region of the parent belongs to one of its child controls.`}),`no`)}function Br(e){return`ref`in e?{ref:n(e.ref)??e.ref}:e}function Vr(e,t){let r=n(e.ref);if(!r)throw new a(`INVALID_ARGS`,`Invalid ref: ${e.ref}`);let i=n(t.ref),o=t.node.ref?n(t.node.ref):null;if(i!==r||o!==r||!t.nodes.includes(t.node))throw new a(`COMMAND_FAILED`,`Internal find target provenance does not match the interaction ref`);return{tree:{nodes:t.nodes,...t.iosSystemSurfaceBundleId?{surfaceBundleId:t.iosSystemSurfaceBundleId}:{}},...t.keyboard?{keyboard:t.keyboard}:{},resolved:Sr(r,t.node,`exact`)}}async function Hr(e,t,n){let r=await Wr(e,t,n);return{tree:R(r.snapshot),...r.snapshot.keyboard?{keyboard:r.snapshot.keyboard}:{},resolved:r.resolved}}async function Ur(e,t,r,i){let{tree:a,keyboard:o,resolved:s}=i.preresolvedTarget?Vr(r,i.preresolvedTarget):await Hr(e,t,r),c=a.nodes,{node:l,tapPoint:u}=await $n({policy:i.pipeline,nodes:c,...o?{keyboard:o}:{},node:s.node,action:i.action,label:`Ref ${r.ref}`,hooks:{onResolved:(e,t)=>fr(e,t,i),offscreen:async(n,a)=>await tr(e,t,n,a,r.ref,i)},resolveTapPoint:e=>zr(e,c,{invalidMessage:`Ref ${r.ref} has no usable bounds`,blockedTargetLabel:`Ref ${r.ref}`,blockedTargetDetails:{ref:`@${n(r.ref)??e.ref}`}})});return{kind:`ref`,point:u,target:{kind:`ref`,ref:`@${s.ref}`},...Er(e,l,a,i.action,s.resolution)}}async function Wr(e,t,n){let{session:r,snapshot:i}=await Pt(e,t.session),a=n.fallbackLabel??``,o=Kr(i.nodes,n.ref,{fallbackLabel:a});if(o.kind!==`resolved`)throw qr(o,n.ref);return Gr({session:r,frameTree:i,target:n,fallbackLabel:a,authorized:o.resolved})}function Gr(e){let{session:t,frameTree:n,target:r,fallbackLabel:i,authorized:a}=e,o=t.snapshot;if(!o||o===n)return{snapshot:n,resolved:a};let s=Kr(o.nodes,r.ref,{fallbackLabel:i});return s.kind===`resolved`&&ge(T(a.node),T(s.resolved.node))?{snapshot:o,resolved:s.resolved}:{snapshot:n,resolved:a}}function Kr(e,t,r){let i=n(t);if(!i)throw new a(`INVALID_ARGS`,`Invalid ref: ${t}`);let o=c(e,i);if(Jr(o))return{kind:`resolved`,resolved:Sr(i,o,`exact`)};let s=r.fallbackLabel.length>0?pt(e,r.fallbackLabel):null;if(Jr(s))return{kind:`resolved`,resolved:Sr(i,s,`label-fallback`)};let l=o??s;return l?{kind:`unusable`,node:l}:{kind:`missing`}}function qr(t,r){let i=n(r)??r,o=t.kind===`unusable`?new a(`COMMAND_FAILED`,`Ref ${r} has no usable bounds`,{reason:E.targetBoundsInvalid,ref:i,hint:w}):new a(`COMMAND_FAILED`,`Ref ${r} not found`,{reason:E.refNotFound,ref:i,hint:w});return e(o,`no`)}function Jr(e){return e?D(e.rect)!==null:!1}async function G(e,t,n){return await $r(e,t,n.action),t.target.kind===`point`?await Xr(e,t,t.target,n):t.target.kind===`ref`?await Ur(e,t,t.target,n):await Qr(e,t,t.target,n)}async function Yr(e,t,n){let r=(await e.sessions.get(t.session??`default`))?.snapshot,i=r?.nodes;if(!i)return;let a={x:n.x,y:n.y},o=x(i).resolveViewport({x:a.x,y:a.y,width:0,height:0});return o&&!S(o,a.x,a.y)?`Coordinates (${a.x}, ${a.y}) are outside the last-known viewport (${o.width}x${o.height}). The tap will be forwarded anyway; take a fresh snapshot if the screen changed.`:Yn({nodes:i,point:a,viewport:o,...r?.keyboard?{keyboard:r.keyboard}:{}})}async function Xr(e,t,n,r){let i=await Yr(e,t,n);if(!r.captureEvidenceBaseline)return{kind:`point`,point:{x:n.x,y:n.y},...i?{warning:i}:{}};let a=await Zr(e,t);return{kind:`point`,point:{x:n.x,y:n.y},...a?{preAction:a}:{},...i?{warning:i}:{}}}async function Zr(e,t){try{return R((await L(e,t,!0)).snapshot)}catch{return}}async function Qr(e,t,n,r){let i=n.selector,a,o,s,c=Ye(r.pipeline.poll,r.readinessTimeoutMs);if(c){let n=await ur(e,t,i,r,c);a=n.capture,o=n.resolved,s=n.readiness}else{let n=await ar(e,t,i,r);if(a=n.capture,o=n.resolved,!o||!o.node.rect)throw await sr({runtime:e,nodes:a.snapshot.nodes,selectorExpression:i,action:r.action,resolved:o})}let l=o,{node:u,tapPoint:d}=await $n({policy:r.pipeline,nodes:a.snapshot.nodes,...a.snapshot.keyboard?{keyboard:a.snapshot.keyboard}:{},node:l.node,action:r.action,label:`Selector ${l.selector}`,hooks:{onResolved:(e,t)=>fr(e,t,r),offscreen:async(n,i)=>await er(e,t,n,i,l.selector,r)},resolveTapPoint:e=>zr(e,a.snapshot.nodes,{invalidMessage:`Selector ${o.selector} resolved to invalid bounds`,blockedTargetLabel:`Selector ${i}`,blockedTargetDetails:{selector:i}})});return{kind:`selector`,point:d,target:{kind:`selector`,selector:o.selector},...s?{readiness:s}:{},...Er(e,u,R(a.snapshot),r.action,wr(o,a.snapshot.nodes))}}async function $r(e,t,n){if(e.backend.platform!==`macos`)return;let r=await ei(e,t);if((r===`desktop`||r===`menubar`)&&(r!==`menubar`||n!==`click`&&n!==`press`))throw new a(`UNSUPPORTED_OPERATION`,`${n} is not supported on macOS ${r} sessions yet. Open an app session to act, or use the ${r} surface to inspect.`)}async function ei(e,t){return(await e.sessions.get(t.session??`default`))?.metadata?.surface}async function ti(e,t,r,i){let a=(await e.sessions.get(t.session??`default`))?.snapshot,o=a?.nodes;if(!a||!o||n(r.ref)===null)return{};let s=Kr(o,r.ref,{fallbackLabel:r.fallbackLabel??``});if(s.kind!==`resolved`)return{};let{resolved:c}=s,l=k.resolvedTarget,{node:u}=await $n({policy:l,nodes:o,node:c.node,action:i,label:`Ref ${r.ref}`,hooks:{offscreen:async(n,a)=>await tr(e,t,n,a,r.ref,{action:i,pipeline:l})},resolveTapPoint:e=>D(e.rect)});return{...Or(u,i),node:u,preAction:R(a)}}async function ni(e,t,n,r,i){let a=await ti(e,t,n,r),o=I(await i(P(e,t),{kind:`ref`,ref:n.ref,...n.fallbackLabel?{fallbackLabel:n.fallbackLabel}:{}}));return{kind:`ref`,target:{kind:`ref`,ref:n.ref},resolution:br,...a,...o?{backendResult:o}:{}}}function ri(e,t){let n=x(e),r=e.filter(n.isVisibleInEffectiveViewport).map(e=>e.rect).filter(ii),i=r.length>0?r:e.map(e=>e.rect).filter(ii);if(i.length===0)throw new a(`COMMAND_FAILED`,`Cannot infer viewport for ${t}`);let o=Math.min(...i.map(e=>e.x)),s=Math.min(...i.map(e=>e.y)),c=Math.max(...i.map(e=>e.x+e.width)),l=Math.max(...i.map(e=>e.y+e.height));return{x:o,y:s,width:c-o,height:l-s}}function ii(e){return!!(e&&e.width>0&&e.height>0)}async function ai(e,t){return await e.backend.resolveGestureViewport?.(P(e,t))||ri((await L(e,t,!1)).snapshot.nodes,`gesture`)}const oi=async(e,t)=>{let n=await G(e,t,{action:`focus`,requireInteractive:!0,pipeline:k.resolvedTarget});if(!e.backend.focus)throw new a(`UNSUPPORTED_OPERATION`,`focus is not supported by this backend`);let r=K(n),i=I(await e.backend.focus(P(e,t),r));return{...n,...i?{backendResult:i}:{},...u(`Focused (${r.x}, ${r.y})`)}},si=async(e,t)=>{let n=V(t),r=await G(e,t,{action:`longPress`,requireInteractive:!0,pipeline:k.promotedTarget,captureEvidenceBaseline:n.needsPreActionBaseline,expectedResolvedTarget:t.expectedResolvedTarget,readinessTimeoutMs:t.readinessTimeoutMs});if(!e.backend.longPress)throw new a(`UNSUPPORTED_OPERATION`,`longPress is not supported by this backend`);let i=t.durationMs===void 0?void 0:Ke(t.durationMs,`durationMs`,0,12e4),o=K(r),s=I(await e.backend.longPress(P(e,t),o,{durationMs:i}));return await H(e,t,r,{...r,...i===void 0?{}:{durationMs:i},...s?{backendResult:s}:{},...u(`Long pressed (${o.x}, ${o.y})`)},n)},ci=async(e,t)=>{let n=V(t),r=n.needsPreActionBaseline?null:await li(e,t);if(r)return r;let i=await G(e,t,{action:`hover`,requireInteractive:!1,pipeline:k.resolvedTarget,captureEvidenceBaseline:n.needsPreActionBaseline,expectedResolvedTarget:t.expectedResolvedTarget});if(!e.backend.hover)throw new a(`UNSUPPORTED_OPERATION`,`hover is not supported by this backend`);let o=K(i),s=I(await e.backend.hover(P(e,t),o));return await H(e,t,i,{...i,...s?{backendResult:s}:{},...u(`Hovered (${o.x}, ${o.y})`)},n)};async function li(e,t){if(t.target.kind!==`ref`||!e.backend.hoverTarget||t.expectedResolvedTarget)return null;let{hoverTarget:n}=e.backend;return await ni(e,t,t.target,`hover`,async(e,t)=>await n(e,t))}const ui=async(e,t)=>{if(!e.backend.performGesture)throw new a(`UNSUPPORTED_OPERATION`,`gesture is not supported by this backend`);await $r(e,t,`drag`);let n=await ai(e,t),r=await di(e,t,`source`),i=await di(e,t,`destination`),o=Re({from:K(r),to:K(i),sourceHoldMs:t.gesture.sourceHoldMs,moveMs:t.gesture.moveMs,destinationHoldMs:t.gesture.destinationHoldMs},n),s=I(await e.backend.performGesture(P(e,t),o)),{start:c,end:l}=Ie(o);return{kind:`drag`,durationMs:o.durationMs,pointerCount:1,from:c,to:l,targets:{source:fi(r),destination:fi(i)},recording:pi(r,i),...s?{backendResult:s}:{},...u(`Dragged ${t.gesture.source} to ${t.gesture.destination}`)}};async function di(e,t,n){let r=t.gesture[n];return await G(e,{...t,target:r.startsWith(`@`)?{kind:`ref`,ref:r}:{kind:`selector`,selector:r}},{action:`drag`,requireInteractive:!1,pipeline:k.resolvedTarget,expectedResolvedTarget:t.expectedResolvedTargets?.[n],replayTargetRole:n})}function fi(e){if(e.kind===`point`||!e.resolution)throw new a(`COMMAND_FAILED`,`gesture drag target resolution was not disclosed`);let t=`selectorChain`in e?e.selectorChain:void 0;return{...t?.length?{selectorChain:t}:{},resolution:e.resolution}}function pi(e,t){let n=mi(e),r=mi(t),i=hi(e),a=hi(t);return{...n?{sourceSelector:n}:{},...r?{destinationSelector:r}:{},...i?{sourceTarget:i}:{},...a?{destinationTarget:a}:{}}}function mi(e){return`selectorChain`in e&&e.selectorChain?.length?e.selectorChain.join(` || `):void 0}function hi(e){if(!(!(`selectorChain`in e)||!e.selectorChain?.length||!e.node||!e.preAction))return{selectorChain:e.selectorChain,node:e.node,preActionNodes:e.preAction.nodes}}function K(e){if(!e.point)throw new a(`COMMAND_FAILED`,`Interaction target resolved without coordinates`);return e.point}const gi=async(e,t)=>await yi(e,t,`press`),_i=async(e,t)=>await yi(e,t,`click`),vi=async(e,t)=>{if(typeof t.text!=`string`)throw new a(`INVALID_ARGS`,`fill requires text`);let n=V(t),r=n.needsPreActionBaseline?null:await Si(e,t);if(r)return r;let i=await G(e,t,{action:`fill`,requireInteractive:!0,pipeline:k.resolvedTarget,captureEvidenceBaseline:n.needsPreActionBaseline,expectedResolvedTarget:t.expectedResolvedTarget,preresolvedTarget:t.preresolvedTarget});if(!e.backend.fill)throw new a(`UNSUPPORTED_OPERATION`,`fill is not supported by this backend`);let o=bi(i),s=`node`in i?i.node?.type??``:``,c=s!==``&&fe(s,e.backend.platform),l=t.allowNonHittableCoordinateFallback===!0&&`node`in i&&i.node?.hittable===!1,u=I(await e.backend.fill(P(e,t),o,t.text,{delayMs:t.delayMs,allowNonHittableCoordinateFallback:l})),d=s&&!c?`fill target ${wi(i)} resolved to "${s}", attempting fill anyway.`:void 0;return await H(e,t,i,{...i,text:t.text,...d?{warning:d}:{},...u?{backendResult:u}:{}},n)};async function yi(e,t,n){let r=V(t),i=r.needsPreActionBaseline?null:await xi(e,t,n);if(i)return i;let o=await G(e,t,{action:n,requireInteractive:!0,pipeline:k.promotedTarget,captureEvidenceBaseline:r.needsPreActionBaseline,expectedResolvedTarget:t.expectedResolvedTarget,preresolvedTarget:t.preresolvedTarget,readinessTimeoutMs:t.readinessTimeoutMs});if(!e.backend.tap)throw new a(`UNSUPPORTED_OPERATION`,`tap is not supported by this backend`);let s=bi(o),c;try{c=await e.backend.tap(P(e,t),s,{button:t.button,count:t.count,intervalMs:t.intervalMs,holdMs:t.holdMs,jitterPx:t.jitterPx,doubleTap:t.doubleTap})}catch(e){throw dt(e,o),e}let l=I(c);return await H(e,t,o,{...o,...l?{backendResult:l}:{}},r)}function bi(e){if(!e.point)throw new a(`COMMAND_FAILED`,`Interaction target resolved without coordinates`);return e.point}async function xi(e,t,n){if(n!==`click`||t.target.kind!==`ref`||!e.backend.tapTarget||Ci(t)||t.expectedResolvedTarget)return null;let{tapTarget:r}=e.backend;return await ni(e,t,t.target,n,async(e,t)=>await r(e,t))}async function Si(e,t){if(t.target.kind!==`ref`||!e.backend.fillTarget||t.expectedResolvedTarget)return null;let{fillTarget:n}=e.backend;return{...await ni(e,t,t.target,`fill`,async(e,r)=>await n(e,r,t.text,{delayMs:t.delayMs})),text:t.text}}function Ci(e){return e.count!==void 0||e.intervalMs!==void 0||e.holdMs!==void 0||e.jitterPx!==void 0||e.doubleTap!==void 0||e.button!==void 0&&e.button!==`primary`}function wi(e){return e.target?.kind===`ref`?e.target.ref:e.target?.kind===`selector`?e.target.selector:`point`}function q(e){return{includeRects:e===`visible`||e===`hidden`,interactiveOnly:!1}}const Ti=k.wait.poll.defaultTimeoutMs;function Ei(e,t,n,r,i={}){let a=Qe(r),o=n??a.defaultTimeoutMs,s=X(e),c=Vi(i.isUnreadableError),l=[],u={},d=()=>Math.max(0,o-(X(e)-s));return{capture:async n=>{let r=!1,i=X(e)-s,a=t=>l.push({startedMs:i,durationMs:X(e)-s-i,outcome:t}),o=await Ht(e,t,d(),async e=>await c.attempt(async()=>{let t=await n(e);return r=!0,t}));if(!o.timedOut)return r&&c.recordReadableCapture(),a(Di(r,c.lastUnobservedCause())),o;let f=Oi(o.error,c.readableCaptures());return a(f.outcome),u=f.evidence,{timedOut:!0,deadline:f.deadline}},hasTimeRemaining:()=>d()>0,failureEvidence:()=>({timeoutMs:o,readableCaptures:c.readableCaptures(),captures:l.length,polls:ki(l),waitedMs:X(e)-s,...u}),preserveUnreadableOnStall:i.preserveUnreadableOnStall,neverReadableCause:c.neverReadableCause,sleepUntilNextPoll:async()=>await Hi(e,t,Math.min(a.intervalMs,d())),timeoutMs:o,waitedMs:()=>X(e)-s}}function Di(e,t){return e?`readable`:t?.outcome??`unreadable`}function Oi(e,t){let n=zi(e);if(n)return{outcome:`runner-restart`,deadline:`runner-restart-exhausted`,evidence:n};let r=mt(e instanceof a?e.details:void 0);return r?{outcome:`readiness`,deadline:`readiness-exhausted`,evidence:{readinessPhase:r}}:{outcome:`deadline`,deadline:t===0?`capture-stalled`:`capture-truncated`,evidence:{}}}function ki(e){return e.length<=30?[...e]:[...e.slice(0,5),...e.slice(-25)]}function Ai(e,t){return new a(`COMMAND_FAILED`,e,{reason:M.captureStalled,captureStalled:!0,...t,retriable:!0,hint:`No readable snapshot capture completed before the wait timeout. Retry, or use screenshot to inspect the current surface.`})}function ji(e,t){return new a(`COMMAND_FAILED`,e,{reason:M.runnerRestartExhausted,waitRunnerRestartExhausted:!0,...t,retriable:!0,hint:`An iOS runner restart consumed the wait timeout before a readable snapshot completed. Inspect the diagnostics log for the runner invalidation/restart sequence, then retry.`})}function Mi(e,t){return new a(`COMMAND_FAILED`,e,{reason:M.readinessExhausted,...t,retriable:!0,hint:`The wait timeout ended during readiness work (${t.readinessPhase}), before that poll could capture the screen. Retry with a timeout long enough to cover it.`})}function Ni(e,t){return new a(`COMMAND_FAILED`,e,{reason:M.deadlineExceeded,captureTruncated:!0,...t})}function Pi(e,t){return new a(`COMMAND_FAILED`,e,{reason:M.targetAbsent,...t})}function Fi(e,t,n){let r=e.neverReadableCause();if(r!==void 0){if(r.outcome===`retriable`)throw Ii(r.error,t);if(n)throw r.error}}function Ii(e,t){let n=r(e);return new a(n.code,n.message,{reason:M.captureStalled,...n.details,...t},n)}function J(e,t,n){let r=t.failureEvidence();switch(n){case`runner-restart-exhausted`:return ji(e,r);case`readiness-exhausted`:return Fi(t,r,!1),Mi(e,r);case`capture-stalled`:return Fi(t,r,t.preserveUnreadableOnStall===!0),Ai(e,r);case`capture-truncated`:return Ni(e,r);case void 0:return Fi(t,r,!0),r.readableCaptures===0?Ai(e,r):Pi(e,r);default:return Ri(n)}}function Li(e){return e===`runner-restart-exhausted`||e===`readiness-exhausted`}function Ri(e){throw Error(`Unhandled wait deadline: ${String(e)}`)}function zi(e){if(!(e instanceof a))return;let t=e.details;if(t?.runnerRestarted===!0)return{runnerRestarted:!0,...Y(t,`runnerRestartReason`),...Y(t,`runnerRestartCommand`),...Y(t,`runnerRestartCommandId`),...Y(t,`runnerInvalidatedSessionId`),...Y(t,`runnerRestartSessionId`),...Y(t,`logPath`),...Y(t,`diagnosticId`)}}function Y(e,t){let n=e?.[t];return typeof n==`string`?{[t]:n}:{}}function Bi(e){return e instanceof a&&e.details?.retriable===!0}function Vi(e=ze){let t=0,n;return{attempt:async t=>{try{return await t()}catch(t){if(e(t))n={outcome:`unreadable`,error:t};else if(Bi(t))n={outcome:`retriable`,error:t};else throw t;return}},lastUnobservedCause:()=>n,recordReadableCapture:()=>{t+=1},readableCaptures:()=>t,neverReadableCause:()=>t===0?n:void 0}}function X(e){return e.clock?.now()??Date.now()}async function Hi(e,t,n){let r=[t.signal,e.signal].filter(e=>e!==void 0);for(let e of r)e.throwIfAborted();if(n<=0)return!1;if(e.clock){await e.clock.sleep(n);for(let e of r)e.throwIfAborted();return!0}return await new Promise((e,t)=>{let i=r.length>0?AbortSignal.any(r):void 0,a=()=>i?.removeEventListener(`abort`,s),o=setTimeout(()=>{a(),e()},n),s=()=>{clearTimeout(o),a(),t(i?.reason)};i?.addEventListener(`abort`,s,{once:!0}),o.unref()}),!0}async function Ui(e,t,n){let r=await O(k.readAny,e.nodes,t,{platform:n}),i=r.kind===`target`||r.kind===`ambiguous`?r.matchedNodes:r.kind===`occluded`?[r.node]:[];return{selector:r.kind===`target`||r.kind===`ambiguous`?r.selector:t,observation:ee(e,i)}}async function Wi(e,t,n){let r=await Ui(e,t,n),i=r.observation;if(i.kind!==`absent`)throw Ae(r.selector,i);return{predicate:`absent`,pass:!0,selector:t,matches:i.matches}}async function Gi(e,t,n,r,i){let a=_(n);if(a)throw Me(a,`wait`);let o=Ei(t,n,i,k.wait,{isUnreadableError:qi,preserveUnreadableOnStall:!0}),s=q(),c,l;for(;o.hasTimeRemaining();){let i=await o.capture(async i=>{try{let{observation:a}=await Ui((await e.captureSnapshot(t,{...n,signal:i},{updateSession:!0,includeHiddenContentHints:!1,...s})).snapshot,r,t.backend.platform);if(v(a.kind))throw Ae(r,a,`wait`);return a}catch(e){throw ze(e)?je(r,e,`wait`):e}});if(i.timedOut){l=i.deadline;break}let a=i.value;if(a?.kind===`absent`)return{kind:`absent`,waitedMs:o.waitedMs()};a?.kind===`present`&&(c=a),await o.sleepUntilNextPoll()}throw Li(l)?J(`wait absent timed out for selector: ${r}`,o,l):c?Ki(r,c,o.failureEvidence()):J(`wait absent timed out for selector: ${r}`,o,l)}function Ki(e,t,n){let r=t.matches!==1;return new a(`COMMAND_FAILED`,`wait absent timed out for selector ${e}: ${t.matches} match${r?`es`:``} remain`,{reason:M.targetPresent,selector:e,...n,matches:t.matches,firstMatch:t.firstMatch})}function qi(e){if(!(e instanceof a))return!1;let t=e.details;return t?.command===`wait`&&t.predicate===`absent`&&(v(t.observation)||t.observation===`unreadable`)}function Ji(e){if(e.kind===`ambiguous`||e.kind===`target`)return{selector:e.selector,selectorIndex:e.selectorIndex,matchedNodes:e.matchedNodes}}async function Yi(e,t,n,r,i,o){let s=Ei(t,n,i,k.wait),c=q(),l,u;for(;s.hasTimeRemaining();){let i=await s.capture(async r=>await e.captureSnapshot(t,{...n,signal:r},{updateSession:!0,includeHiddenContentHints:!1,...c}));if(i.timedOut){u=i.deadline;break}let a=i.value;if(a){let e=a.snapshot.nodes,n=Ji(await O(k.wait,e,r,{platform:t.backend.platform}));if(n){let t=Xi(e,n,o);if(t.kind===`satisfied`)return{kind:`selector`,selector:n.selector,waitedMs:s.waitedMs(),node:t.node,preActionNodes:e};l=t.evidence}}await s.sleepUntilNextPoll()}throw u!==`capture-stalled`&&l?new a(`COMMAND_FAILED`,`wait matched selector ${r} but no candidate carried the recorded landmark identity`,{reason:ht,...s.failureEvidence(),...l}):J(`wait timed out for selector: ${r}`,s,u)}function Xi(e,t,n){let r=t.matchedNodes[0];if(!n)return{kind:`satisfied`,node:r};let i=Te(e),a=Ee(t.matchedNodes,i,oe(n),n.ancestry)[0];return a?{kind:`satisfied`,node:a}:{kind:`identity-mismatch`,evidence:{matchCount:t.matchedNodes.length,observed:T(r),observedAncestry:De(r,i,Math.max(n.ancestry.length,1)).chain}}}async function Zi(e,t,n,r,i){let o=i??Ti,s=r??e.stable.defaultQuietMs,c=await e.stable.capture(t,n,{quietMs:s,timeoutMs:o});if(!c.settled)throw new a(`COMMAND_FAILED`,`wait timed out waiting for a stable UI`,{reason:M.stableTimeout,...c.stalled?{captureStalled:!0}:{},quietMs:s,timeoutMs:o,captures:c.captures,nodeCount:c.nodeCount,...c.stalled?{hint:`A snapshot capture stalled past the wait timeout, so no settle verdict is available. The UI may still be readable: retry, or use screenshot to inspect the surface.`}:{}});return{kind:`stable`,waitedMs:c.waitedMs,captures:c.captures,nodeCount:c.nodeCount,...c.nodeCount<e.stable.tinyTreeNodeCount?{hint:e.stable.tinyTreeHint}:{}}}async function Qi(e,t,n,r,i){let a=Ei(t,n,i,k.wait),o;for(;a.hasTimeRemaining();){let i=await a.capture(async i=>await $i(e,t,{...n,signal:i},r));if(i.timedOut){o=i.deadline;break}if(i.value)return{kind:`text`,text:r,waitedMs:a.waitedMs()};await a.sleepUntilNextPoll()}throw J(`wait timed out for text: ${r}`,a,o)}async function $i(e,t,n,r){return t.backend.findText&&(await t.backend.findText(ta(t,n),r)).found?!0:await ea(e,t,n,r)}async function ea(e,t,n,r){let i=await e.captureSnapshot(t,n,{updateSession:!0,includeHiddenContentHints:!1});return!!pt(i.snapshot.nodes,r)}function ta(e,t){return{session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata}}function na(e){let t=async(t,n)=>{switch(n.target.kind){case`sleep`:return await Hi(t,n,n.target.durationMs),{kind:`sleep`,waitedMs:n.target.durationMs};case`ref`:return await ra(e,t,n,n.target.ref,n.target.timeoutMs);case`selector`:return await Yi(e,t,n,n.target.selector,n.target.timeoutMs,n.target.recordedLandmark);case`absent`:return await Gi(e,t,n,n.target.selector,n.target.timeoutMs);case`stable`:return await Zi(e,t,n,n.target.quietMs,n.target.timeoutMs);case`text`:return await ia(e,t,n,n.target.text,n.target.timeoutMs);default:return aa(n.target)}};return{waitCommand:t,waitForTextCommand:async(e,n)=>{let r=await t(e,{...n,target:{kind:`text`,text:n.text,timeoutMs:n.timeoutMs}});if(r.kind!==`text`)throw new a(`COMMAND_FAILED`,`waitForText returned non-text result`);return r}}}async function ra(e,t,r,i,o){let s=await e.requireSnapshot(t,r.session),l=n(i);if(!l)throw new a(`INVALID_ARGS`,`Invalid ref: ${i}`);let u=c(s.snapshot.nodes,l);if(!u)throw new a(`COMMAND_FAILED`,`Ref ${i} not found`,{reason:E.refNotFound,ref:l,hint:w});let d=j(u,s.snapshot.nodes);if(!d)throw new a(`COMMAND_FAILED`,`Ref ${i} has no label to wait for`,{reason:E.refUnlabeled,ref:l});return await Qi(e,t,r,d,o)}async function ia(e,t,n,r,i){let o=xe(r);if(!o.ok)throw new a(o.code,o.message);return await Qi(e,t,n,o.text,i)}function aa(e){throw Error(`Unsupported wait target: ${String(e)}`)}const oa=na({captureSnapshot:B,requireSnapshot:Pt,stable:{defaultQuietMs:500,tinyTreeHint:Xt,tinyTreeNodeCount:5,capture:Zt}}),sa=oa.waitCommand,ca=oa.waitForTextCommand,la=async(e,t)=>{let n=t.locator??`any`;if(!t.query)throw new a(`INVALID_ARGS`,ie);if(t.action===`wait`)return await pa(e,t,n);if(t.action===`list`)return await ma(e,t,n);let{capture:r,match:i}=await ha(e,t,n);if(!i)throw new a(`COMMAND_FAILED`,`find did not match any element`);if(t.action===`exists`)return{kind:`found`,found:!0};let o=`@${i.ref}`;return t.action===`get_attrs`?{kind:`attrs`,ref:o,node:i}:{kind:`text`,ref:o,text:await Lt(e,r,i),node:i}},ua=async(e,t)=>{if(t.target.kind===`ref`){let n=await Pt(e,t.session),r=Rt(n.snapshot.nodes,t.target.ref,{fallbackLabel:t.target.fallbackLabel??``,invalidRefMessage:`get text requires a ref like @e2`,notFoundMessage:`Ref ${t.target.ref} not found`});W(r.node,n.snapshot.nodes,t.expectedResolvedTarget,`get`);let i=C(r.node,e.backend.platform,{action:`get`,nodes:n.snapshot.nodes}),a={kind:`ref`,ref:`@${r.ref}`},o=n.snapshot.nodes;return t.property===`attrs`?{kind:`attrs`,target:a,node:r.node,selectorChain:i,preActionNodes:o}:{kind:`text`,target:a,text:await Lt(e,n,r.node),node:r.node,selectorChain:i,preActionNodes:o}}let n=await ga(e,t,t.session??`default`,{selector:t.target.selector,policy:t.property===`text`?k.readText:k.readUnique,hooks:{onResolved:(e,n)=>W(e,n,t.expectedResolvedTarget,`get`)}}),r=C(n.node,e.backend.platform,{action:`get`,nodes:n.capture.snapshot.nodes});if(t.property===`attrs`)return{kind:`attrs`,target:{kind:`selector`,selector:n.selector},node:n.node,selectorChain:r,preActionNodes:n.capture.snapshot.nodes};let i=await Lt(e,n.capture,n.node);return{kind:`text`,target:{kind:`selector`,selector:n.selector},text:i,node:n.node,selectorChain:r,preActionNodes:n.capture.snapshot.nodes}},da=async(e,t)=>{let n=await ua(e,{...t,property:`text`,target:t.target});if(n.kind!==`text`)throw new a(`COMMAND_FAILED`,`getText returned non-text result`);return n},fa=async(e,t)=>{let n=await ua(e,{...t,property:`attrs`,target:t.target});if(n.kind!==`attrs`)throw new a(`COMMAND_FAILED`,`getAttrs returned non-attrs result`);return n};async function pa(e,t,n){let r=Ei(e,t,t.timeoutMs,k.findWait),i;for(;r.hasTimeRemaining();){let a=await r.capture(async r=>await ha(e,{...t,signal:r},n,{includeHiddenContentHints:!1}));if(a.timedOut){i=a.deadline;break}if(a.value?.match)return{kind:`found`,found:!0,waitedMs:r.waitedMs()};await r.sleepUntilNextPoll()}throw J(`find wait timed out`,r,i)}async function ma(e,t,n){let r=ue(n,t.query),i=await B(e,t,{updateSession:!0,...q()});if(A(i.snapshot.snapshotQuality))throw Nt(i.snapshot.snapshotQuality);return{kind:`list`,matches:(r?qe(k.readList,i.snapshot.nodes,r,{platform:e.backend.platform}).list?.matchedNodes??[]:de(i.snapshot.nodes,n,t.query,{}).matches).map(e=>({ref:`@${e.ref}`,node:e}))}}async function ha(e,t,n,r){let i=ue(n,t.query),a=await B(e,t,{updateSession:!0,scope:Mt(e.backend.platform,n,t.query,i),includeHiddenContentHints:r?.includeHiddenContentHints,...q()});if(A(a.snapshot.snapshotQuality))throw Nt(a.snapshot.snapshotQuality);if(i){let t=await O(k.readAny,a.snapshot.nodes,i,{platform:e.backend.platform});return{capture:a,match:t.kind===`target`?t.node:void 0}}return{capture:a,match:de(a.snapshot.nodes,n,t.query,{requireRect:!1}).matches[0]}}async function ga(e,t,n,r){let i=await B(e,{...t,session:n},{updateSession:!0,...q()}),a=await O(r.policy,i.snapshot.nodes,r.selector,{platform:e.backend.platform},r.hooks);if(a.kind!==`target`)throw Vt({outcome:a,selectorExpression:r.selector,command:`get`});return{capture:i,node:a.node,selector:a.selector,ref:`@${a.node.ref}`}}const _a=async(e,t)=>{let n=be(t.predicate);if(!n.ok)throw new a(n.code,n.message,{hint:n.hint});let r=n.predicate;if(r===`absent`){let e=_(t);if(e)throw Me(e)}if(r===`text`&&!t.expectedText)throw new a(`INVALID_ARGS`,ve);let i=t.selector,o=await va(e,t,r,i);return r===`exists`?await ya(e,o,i):r===`absent`?await Wi(o.snapshot,i,e.backend.platform):await ba(e,t,o,r,i)};async function va(e,t,n,r){try{return await B(e,t,{updateSession:!0,...q(n)})}catch(e){throw n!==`absent`||s(e)?e:je(r,e)}}async function ya(e,t,n){let r=await O(k.readAny,t.snapshot.nodes,n,{platform:e.backend.platform});if(r.kind!==`target`)throw new a(`COMMAND_FAILED`,Ce(n,[],{unique:!1}),{hint:pe([])});return{predicate:`exists`,pass:!0,selector:r.selector,matches:r.matches,selectorChain:Se(n)}}async function ba(e,t,n,r,i){let o=await O(k.readUnique,n.snapshot.nodes,i,{platform:e.backend.platform},{onResolved:(e,n)=>W(e,n,t.expectedResolvedTarget,`is`)});if(o.kind!==`target`)throw Vt({outcome:o,selectorExpression:i,command:`is`,details:{predicate:r,selector:i}});let s=ye({predicate:r,node:o.node,visibility:x(n.snapshot.nodes),expectedText:t.expectedText,platform:e.backend.platform});if(!s.pass)throw new a(`COMMAND_FAILED`,`is ${r} failed for selector ${o.selector}: ${s.details}`,{command:`is`,reason:E.predicateFailed,predicate:r,selector:o.selector,predicateDetails:s.details});return{predicate:r,pass:!0,selector:o.selector,...r===`text`?{text:s.actualText}:{},selectorChain:Se(i),node:o.node,preActionNodes:n.snapshot.nodes}}const xa=async(e,t)=>await _a(e,{...t,predicate:`visible`,selector:t.target.selector}),Sa=async(e,t)=>await _a(e,{...t,predicate:`hidden`,selector:t.target.selector}),Ca=async(e,t)=>{if(!e.backend.performGesture)throw new a(`UNSUPPORTED_OPERATION`,`gesture is not supported by this backend`);await $r(e,t,t.gesture.intent);let n=await ai(e,t),r=Le(t.gesture,n,e.backend.platform),i=I(await e.backend.performGesture(P(e,t),r)),o=Ta(r.pointers,0),s=Ta(r.pointers,-1);return{kind:t.gesture.intent,durationMs:r.durationMs,pointerCount:r.topology===`single`?1:2,from:o,to:s,...i?{backendResult:i}:{},...u(Ea(t.gesture,o,s))}},wa=async(e,t)=>{let n=t.gesture;return n.intent===`drag`?await ui(e,{...t,gesture:n}):await Ca(e,{...t,gesture:n})};function Ta(e,t){let n=e.map(e=>t===0?e.samples[0]?.point:e.samples.at(-1)?.point);if(n.some(e=>e===void 0))throw new a(`COMMAND_FAILED`,`Gesture plan did not contain endpoint samples.`);let r=n;return{x:r.reduce((e,t)=>e+t.x,0)/r.length,y:r.reduce((e,t)=>e+t.y,0)/r.length}}function Ea(e,t,n){switch(e.intent){case`pan`:{let r=`preset`in e?t:e.origin,i=`preset`in e?{x:n.x-t.x,y:n.y-t.y}:e.delta;return`Panned (${r.x}, ${r.y}) by (${i.x}, ${i.y})`}case`fling`:return`direction`in e?`Flung ${e.direction}`:`Flung`;case`pinch`:return`Pinched to scale ${e.scale}`;case`rotate`:return`Rotated gesture ${e.degrees} degrees`;case`transform`:return`Requested transform gesture by (${e.delta.x}, ${e.delta.y}), scale ${e.scale}, rotate ${e.degrees} degrees`}}const Z={find:la,get:ua,getText:da,getAttrs:fa,is:_a,isVisible:xa,isHidden:Sa,wait:sa,waitForText:ca},Q={click:_i,press:gi,fill:vi,focus:oi,longPress:si,hover:ci,gesture:wa,settleObservation:ln};function Da(e){return{find:t=>Z.find(e,t),get:t=>Z.get(e,t),getText:(t,n={})=>Z.getText(e,{...n,target:t}),getAttrs:(t,n={})=>Z.getAttrs(e,{...n,target:t}),is:t=>Z.is(e,t),isVisible:(t,n={})=>Z.isVisible(e,{...n,target:t}),isHidden:(t,n={})=>Z.isHidden(e,{...n,target:t}),wait:t=>Z.wait(e,t),waitForText:(t,n={})=>Z.waitForText(e,{...n,text:t})}}function Oa(e){return{click:(t,n={})=>Q.click(e,{...n,target:t}),press:(t,n={})=>Q.press(e,{...n,target:t}),fill:(t,n,r={})=>Q.fill(e,{...r,target:t,text:n}),focus:(t,n={})=>Q.focus(e,{...n,target:t}),longPress:(t,n={})=>Q.longPress(e,{...n,target:t}),hover:(t,n={})=>Q.hover(e,{...n,target:t}),gesture:t=>Q.gesture(e,t),settleObservation:t=>Q.settleObservation(e,t)}}const ka=[0,187,255,255];function Aa(e,t){for(let n of t)n.rect.width<4||n.rect.height<4||ja(e,n.rect)}function ja(e,t){let n=Ma(t);if(n==null)return;let r=Pa(n.x,0,e.width-1),i=Pa(n.y,0,e.height-1),a=Pa(n.right,0,e.width-1),o=Pa(n.bottom,0,e.height-1);for(let t=0;t<2;t+=1){for(let n=r;n<=a;n+=1)Na(e,n,i+t,ka),Na(e,n,o-t,ka);for(let n=i;n<=o;n+=1)Na(e,r+t,n,ka),Na(e,a-t,n,ka)}}function Ma(e){let t=e.x+e.width-1,n=e.y+e.height-1;return[e.x,e.y,e.width,e.height,t,n].every(Number.isFinite)?{x:e.x,y:e.y,right:t,bottom:n}:null}function Na(e,t,n,r){if(t<0||t>=e.width||n<0||n>=e.height)return;let i=(n*e.width+t)*4;e.data[i]=r[0],e.data[i+1]=r[1],e.data[i+2]=r[2],e.data[i+3]=r[3]}function Pa(e,t,n){return Number.isFinite(e)?Math.min(Math.max(e,t),n):t}const Fa=[{x:-1,y:-1},{x:0,y:-1},{x:1,y:-1},{x:-1,y:0},{x:1,y:0},{x:-1,y:1},{x:0,y:1},{x:1,y:1}];function Ia(e){let{mask:t,width:n,height:r,hooks:i}=e,a=new Uint8Array(t.length),o=new Int32Array(t.length),s=[];for(let e=0;e<t.length;e+=1){if(!za(t,a,e))continue;let c=0,l=Ra(o,a,0,e),u=i.create(e);for(;c<l;){let e=o[c];c+=1,i.visit(u,e),l=La({mask:t,visited:a,queue:o,queueEnd:l,width:n,height:r,pixelIndex:e})}s.push(u)}return s}function La(e){let{mask:t,visited:n,queue:r,width:i,height:a,pixelIndex:o}=e,s=o%i,c=Math.floor(o/i),l=e.queueEnd;for(let e of Fa){let o=s+e.x,u=c+e.y;if(!Ba(o,u,i,a))continue;let d=u*i+o;za(t,n,d)&&(l=Ra(r,n,l,d))}return l}function Ra(e,t,n,r){return t[r]=1,e[n]=r,n+1}function za(e,t,n){return e[n]===1&&t[n]!==1}function Ba(e,t,n,r){return e>=0&&e<n&&t>=0&&t<r}function Va(e,t){return e.flatMap(e=>Ha(e,t.baseline.width,t.baseline.height)?Ua(e,t,Ya(t.baseline.height)):[e])}function Ha(e,t,n){let r=e.maxX-e.minX+1;return e.maxY-e.minY+1>=Ja(n)&&r>=t*.35}function Ua(e,t,n){let r=qa(e,Ka(Ga(Wa(e,t.diffMask,t.baseline.width)),Math.max(1,Math.round((e.maxX-e.minX+1)*.08))),n);if(r.length<=1)return[e];let i=r.map(([n,r])=>Xa(e,n,r,t)).filter(e=>e!==null);return i.length>1?i:[e]}function Wa(e,t,n){let r=[];for(let i=e.minY;i<=e.maxY;i+=1){let a=0;for(let r=e.minX;r<=e.maxX;r+=1)t[i*n+r]===1&&(a+=1);r.push(a)}return r}function Ga(e){return e.map((t,n)=>{let r=0,i=0,a=Math.max(0,n-3),o=Math.min(e.length-1,n+3);for(let t=a;t<=o;t+=1)r+=e[t],i+=1;return Math.round(r/i)})}function Ka(e,t){let n=[],r=null;for(let i=0;i<e.length;i+=1){if(e[i]<=t){r??=i;continue}r!==null&&(i-r>=6&&n.push([r,i-1]),r=null)}return r!==null&&e.length-r>=6&&n.push([r,e.length-1]),n}function qa(e,t,n){let r=[],i=e.minY;for(let[a,o]of t){let t=e.minY+Math.round((a+o)/2);t-i+1<n||e.maxY-t<n||(r.push([i,t]),i=t+1)}return r.push([i,e.maxY]),r}function Ja(e){return Math.max(48,Math.round(e*.07))}function Ya(e){return Math.max(24,Math.round(e*.03))}function Xa(e,t,n,r){let i=null;for(let a=t;a<=n;a+=1)for(let t=e.minX;t<=e.maxX;t+=1){let e=a*r.baseline.width+t;r.diffMask[e]===1&&(i??=Za(t,a),Qa(i,e,t,a,r.baseline,r.current))}return i}function Za(e,t){return{minX:e,minY:t,maxX:e,maxY:t,differentPixels:0,baselineRed:0,baselineGreen:0,baselineBlue:0,currentRed:0,currentGreen:0,currentBlue:0}}function Qa(e,t,n,r,i,a){let o=t*4;e.minX=Math.min(e.minX,n),e.minY=Math.min(e.minY,r),e.maxX=Math.max(e.maxX,n),e.maxY=Math.max(e.maxY,r),e.differentPixels+=1,e.baselineRed+=i.data[o],e.baselineGreen+=i.data[o+1],e.baselineBlue+=i.data[o+2],e.currentRed+=a.data[o],e.currentGreen+=a.data[o+1],e.currentBlue+=a.data[o+2]}const $a=2.5;function eo(e){let t=to(e);return Va(t.length<=2e3?io(t,12):t,e).sort((e,t)=>{let n=t.differentPixels-e.differentPixels;if(n!==0)return n;let r=e.minY-t.minY;return r===0?e.minX-t.minX:r}).slice(0,8).map((t,n)=>so(t,n+1,{width:e.baseline.width,height:e.baseline.height,totalPixels:e.totalPixels,differentPixels:e.differentPixels}))}function to(e){let{diffMask:t,baseline:n,current:r}=e,{width:i,height:a}=n;return Ia({mask:t,width:i,height:a,hooks:{create:e=>no(e,i),visit:(e,t)=>ro(e,t,i,n,r)}})}function no(e,t){let n=e%t,r=Math.floor(e/t);return{minX:n,minY:r,maxX:n,maxY:r,differentPixels:0,baselineRed:0,baselineGreen:0,baselineBlue:0,currentRed:0,currentGreen:0,currentBlue:0}}function ro(e,t,n,r,i){let a=t%n,o=Math.floor(t/n),s=t*4;e.minX=Math.min(e.minX,a),e.minY=Math.min(e.minY,o),e.maxX=Math.max(e.maxX,a),e.maxY=Math.max(e.maxY,o),e.differentPixels+=1,e.baselineRed+=r.data[s],e.baselineGreen+=r.data[s+1],e.baselineBlue+=r.data[s+2],e.currentRed+=i.data[s],e.currentGreen+=i.data[s+1],e.currentBlue+=i.data[s+2]}function io(e,t){let n=[];for(let r of e.sort((e,t)=>{let n=e.minY-t.minY;return n===0?e.minX-t.minX:n})){let e=n.find(e=>ao(e,r,t));if(!e){n.push({...r});continue}oo(e,r)}return n}function ao(e,t,n){return e.minX-n<=t.maxX&&t.minX-n<=e.maxX&&e.minY-n<=t.maxY&&t.minY-n<=e.maxY}function oo(e,t){e.minX=Math.min(e.minX,t.minX),e.minY=Math.min(e.minY,t.minY),e.maxX=Math.max(e.maxX,t.maxX),e.maxY=Math.max(e.maxY,t.maxY),e.differentPixels+=t.differentPixels,e.baselineRed+=t.baselineRed,e.baselineGreen+=t.baselineGreen,e.baselineBlue+=t.baselineBlue,e.currentRed+=t.currentRed,e.currentGreen+=t.currentGreen,e.currentBlue+=t.currentBlue}function so(e,t,n){let r={x:e.minX,y:e.minY,width:e.maxX-e.minX+1,height:e.maxY-e.minY+1},i={x:Math.round(e.minX+r.width/2),y:Math.round(e.minY+r.height/2)},a=co(e.baselineRed,e.baselineGreen,e.baselineBlue,e.differentPixels),o=co(e.currentRed,e.currentGreen,e.currentBlue,e.differentPixels),s=r.width*r.height;return{index:t,rect:r,normalizedRect:Je({x:$(r.x/n.width),y:$(r.y/n.height),width:$(r.width/n.width),height:$(r.height/n.height)}),differentPixels:e.differentPixels,shareOfDiffPercentage:$(e.differentPixels/n.differentPixels),densityPercentage:$(e.differentPixels/s),shape:fo(r,n.width,n.height),size:po(s,n.totalPixels),location:lo(i,n.width,n.height),averageBaselineColorHex:ho(a),averageCurrentColorHex:ho(o),baselineLuminance:Math.round(mo(a)),currentLuminance:Math.round(mo(o)),dominantChange:uo(a,o)}}function co(e,t,n,r){return{r:Math.round(e/r),g:Math.round(t/r),b:Math.round(n/r)}}function lo(e,t,n){let r=e.x<t/3?`left`:e.x>t*2/3?`right`:`center`,i=e.y<n/3?`top`:e.y>n*2/3?`bottom`:`middle`;return r===`center`&&i===`middle`?`center`:`${i}-${r}`}function uo(e,t){let n=mo(t)-mo(e);return Math.abs(n)>=12?n>0?`brighter`:`darker`:Math.max(Math.abs(t.r-e.r),Math.abs(t.g-e.g),Math.abs(t.b-e.b))>=12?`color-shift`:`mixed`}function fo(e,t,n){return e.width>=t*.55&&e.height>=n*.12?`large-area`:e.width>=e.height*$a?`horizontal-band`:e.height>=e.width*$a?`vertical-band`:`compact`}function po(e,t){let n=e/t;return n>=.04?`large`:n>=.01?`medium`:`small`}function mo(e){return e.r*.2126+e.g*.7152+e.b*.0722}function ho(e){return`#${go(e.r)}${go(e.g)}${go(e.b)}`}function go(e){return e.toString(16).padStart(2,`0`)}function $(e){return Math.round(e*100*100)/100}const _o=Math.sqrt(3*255**2);async function vo(e,t,n={}){await yo(e,`Baseline image not found`),await yo(t,`Current screenshot not found`);let r=n.outputPath,[i,a]=await Promise.all([N.readFile(e),N.readFile(t)]),[o,s]=await Promise.all([et(i,`baseline screenshot`),et(a,`current screenshot`)]);bo(o.width,o.height,`baseline screenshot`,n.maxPixels),bo(s.width,s.height,`current screenshot`,n.maxPixels);let c=n.threshold??.1;if(o.width!==s.width||o.height!==s.height){let e=o.width*o.height;return await xo(n.outputPath),{match:!1,mismatchPercentage:100,totalPixels:e,differentPixels:e,dimensionMismatch:{expected:{width:o.width,height:o.height},actual:{width:s.width,height:s.height}}}}let l=o.width*o.height,u=c*_o,{diffData:d,diffMask:f,differentPixels:p}=await tt({baselineData:o.data,currentData:s.data,width:o.width,height:o.height,maxColorDistance:u}),m=p>0?eo({diffMask:f,baseline:o,current:s,totalPixels:l,differentPixels:p}):[];if(p>0&&r){let e=new rt.PNG({width:o.width,height:o.height});e.data=d,Aa(e,m),await N.mkdir(vt.dirname(r),{recursive:!0}),await N.writeFile(r,await nt(e))}else await xo(n.outputPath);let h=l>0?Math.round(p/l*100*100)/100:0;return{...p>0&&r?{diffPath:r}:{},...m.length>0?{regions:m}:{},totalPixels:l,differentPixels:p,mismatchPercentage:h,match:p===0}}async function yo(e,t){try{await N.access(e)}catch{throw new a(`INVALID_ARGS`,`${t}: ${e}`)}}function bo(e,t,n,r){if(r==null||r<=0)return;let i=e*t;if(!(i<=r))throw new a(`INVALID_ARGS`,`${n} is ${i} pixels, which exceeds the configured maxImagePixels limit of ${r}`)}async function xo(e){if(e)try{await N.unlink(e)}catch(e){if(!So(e,`ENOENT`))throw e}}function So(e,t){return typeof e==`object`&&!!e&&`code`in e&&e.code===t}function Co(e,t){return e.map(e=>{let n=wo(e,t);return n.length>0?{...e,currentOverlayMatches:n}:e})}function wo(e,t){let n=me(e.rect);return t.map(t=>{let r=t.overlayRect,i=Ze(e.rect,r);return i<=0?null:{ref:t.ref,...t.label?{label:t.label}:{},rect:r,overlayCoveragePercentage:To(i/me(r)),regionCoveragePercentage:To(i/n)}}).filter(e=>e!==null).sort((e,t)=>{let n=t.regionCoveragePercentage-e.regionCoveragePercentage;return n===0?t.overlayCoveragePercentage-e.overlayCoveragePercentage:n}).slice(0,3).map(e=>({ref:e.ref,...e.label?{label:e.label}:{},rect:e.rect,regionCoveragePercentage:e.regionCoveragePercentage}))}function To(e){return Math.round(e*100*100)/100}async function Eo(e,t,n){if(t.kind===`path`&&!e.policy.allowLocalInputPaths)throw new a(`INVALID_ARGS`,`Local ${n.field??`input`} paths are not allowed by command policy`);try{return await e.artifacts.resolveInput(t,n)}catch(e){throw r(e)}}async function Do(e,t,n){if(t?.kind===`path`&&!e.policy.allowLocalOutputPaths)throw new a(`INVALID_ARGS`,`Local output paths are not allowed by command policy`);try{return await e.artifacts.reserveOutput(t,{...n,visibility:n.visibility??`client-visible`,requestedClientPath:t?.kind===`downloadableArtifact`?t.clientPath??n.requestedClientPath:n.requestedClientPath})}catch(e){throw r(e)}}async function Oo(e,t){try{return await e.artifacts.createTempFile(t)}catch(e){throw r(e)}}const ko=async(e,t)=>{if(!t.baseline)throw new a(`INVALID_ARGS`,`diff screenshot requires a baseline image`);let n=Ao(t.threshold),r=t.current??{kind:`live`};if(t.overlayRefs&&!Ro(r))throw new a(`INVALID_ARGS`,`diff screenshot <current.png> cannot use --overlay-refs because saved-image comparisons have no live accessibility refs`);let i=await Eo(e,t.baseline,{usage:`diff screenshot baseline`,field:`baseline`}),o,s,c,l=[];try{let a;Ro(r)?(s=await jo(e,t),a=s.path):(o=await Eo(e,r,{usage:`diff screenshot current`,field:`current`}),a=o.path),c=t.out?await Do(e,t.out,{field:`diffPath`,ext:`.png`,artifactType:`screenshot-diff`}):void 0;let u=await vo(i.path,a,{threshold:n,outputPath:c?.path,maxPixels:e.policy.maxImagePixels});Ro(r)&&(u=await Mo(e,t,c?.path,u,l));let d=u.diffPath?await c?.publish():void 0;return d&&l.push(d),u.diffPath||await c?.cleanup?.(),{...u,...l.length>0?{artifacts:l}:{}}}catch(e){throw await c?.cleanup?.(),e}finally{await i.cleanup?.(),await o?.cleanup?.(),await s?.cleanup?.()}};function Ao(e){if(e==null||e===``)return .1;let t=Number(e);if(Number.isNaN(t)||t<0||t>1)throw new a(`INVALID_ARGS`,`--threshold must be a number between 0 and 1`);return t}async function jo(e,t){let n=await Oo(e,{prefix:`agent-device-diff-current`,ext:`.png`});try{await No(e,t,n.path,Po(t))}catch(e){throw await n.cleanup(),e}return n}async function Mo(e,t,n,r,i){if(!t.overlayRefs)return r;if(r.match||r.dimensionMismatch)return n&&await Lo(n),r;let a=await Do(e,Fo(t,n),{field:`currentOverlayPath`,ext:`.png`,artifactType:`screenshot`});try{let n=await No(e,t,a.path,{overlayRefs:!0,...Po(t)}),o=await a.publish();return o&&i.push(o),{...r,currentOverlayPath:n.path??a.path,...n.overlayRefs?{currentOverlayRefCount:n.overlayRefs.length}:{},...r.regions&&n.overlayRefs?{regions:Co(r.regions,n.overlayRefs)}:{}}}catch(e){throw await a.cleanup?.(),e}}async function No(e,t,n,r={}){if(!e.backend.captureScreenshot)throw new a(`UNSUPPORTED_OPERATION`,`screenshot is not supported by this backend`);return await e.backend.captureScreenshot({session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata},n,r)??{}}function Po(e){return{normalizeStatusBar:e.normalizeStatusBar??!0,...e.surface?{surface:e.surface}:{}}}function Fo(e,t){if(e.currentOverlayOut)return e.currentOverlayOut;if(e.out?.kind===`path`)return{kind:`path`,path:Io(t??e.out.path)};if(e.out?.kind===`downloadableArtifact`)return{kind:`downloadableArtifact`,...e.out.clientPath?{clientPath:Io(e.out.clientPath)}:{},...e.out.fileName?{fileName:Io(e.out.fileName)}:{}}}function Io(e){let t=vt.extname(e);return`${t?e.slice(0,-t.length):e}.current-overlay${t||`.png`}`}async function Lo(e){try{await N.unlink(Io(e))}catch(e){if(!zo(e,`ENOENT`))throw e}}function Ro(e){return e.kind===`live`}function zo(e,t){return typeof e==`object`&&!!e&&`code`in e&&e.code===t}const Bo=async(e,t)=>{if(!e.backend.captureScreenshot)throw new a(`UNSUPPORTED_OPERATION`,`screenshot is not supported by this backend`);d(t);let n=await Do(e,t.out,{field:`path`,ext:`.png`,artifactType:`screenshot`}),r,i;try{i=(await e.backend.captureScreenshot({session:t.session,requestId:t.requestId,appId:t.appId,appBundleId:t.appBundleId,signal:t.signal??e.signal,metadata:t.metadata},n.path,{fullscreen:t.fullscreen,overlayRefs:t.overlayRefs,pixelDensity:t.pixelDensity,stabilize:t.stabilize,normalizeStatusBar:t.normalizeStatusBar,surface:t.surface}))?.displayRotation,t.scale!==void 0&&await at(n.path,t.scale),r=await n.publish()}catch(e){throw await n.cleanup?.(),e}return{path:n.path,...r?{artifacts:[r]}:{},...i?{displayRotation:i}:{},...u(`Saved screenshot: ${n.path}`)}};function Vo(e){let{nodes:t,backend:n,snapshotRaw:r}=e;if(r||!i(n))return{partial:!1,visibleNodeCount:t.length,totalNodeCount:t.length,reasons:[]};let a=ke(t),o=new Set;return a.hiddenCount>0&&o.add(`offscreen-nodes`),a.nodes.some(e=>e.hiddenContentAbove)&&o.add(`scroll-hidden-above`),a.nodes.some(e=>e.hiddenContentBelow)&&o.add(`scroll-hidden-below`),{partial:o.size>0,visibleNodeCount:a.nodes.length,totalNodeCount:t.length,reasons:[...o]}}function Ho(e,t){return e.presentationKey?e:{...e,presentationKey:l(t)}}function Uo(e){let{previous:t,current:n,options:r,identity:i}=e;if(r.forceFull===!0||r.raw===!0||!t||t.comparisonSafe===!1||n.comparisonSafe===!1||!Wo(t,n,i)||!t.presentationKey||t.presentationKey!==n.presentationKey||!Go(t,n))return;let a=r.scope?.trim();return{ageMs:Math.max(0,n.createdAt-t.createdAt),nodeCount:n.nodes.length,...r.interactiveOnly===!0?{interactiveOnly:!0}:{},...a?{scope:a}:{}}}function Wo(e,t,n){return!(e.backend&&t.backend&&e.backend!==t.backend||n?.previousAppBundleId&&n.currentAppBundleId&&n.previousAppBundleId!==n.currentAppBundleId)}function Go(e,t){return e.truncated===t.truncated&&e.nodes.length===t.nodes.length&&e.nodes.every((e,n)=>qo(e,t.nodes[n]))}const Ko=Object.keys({index:!0,depth:!0,parentIndex:!0,type:!0,kind:!0,role:!0,subrole:!0,label:!0,value:!0,contentDescription:!0,identifier:!0,enabled:!0,selected:!0,checked:!0,focused:!0,heading:!0,roleDescription:!0,placeholder:!0,hittable:!0,bundleId:!0,appName:!0,windowTitle:!0,surface:!0,hiddenContentAbove:!0,hiddenContentBelow:!0,interactionBlocked:!0});function qo(e,t){return Ko.every(n=>e[n]===t[n])&&Jo(e.rect,t.rect)&&Yo(e.presentationHints,t.presentationHints)&&Yo(e.actions,t.actions)}function Jo(e,t){return!e||!t?e===t:e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height}function Yo(e,t){return!e||!t?e===t:e.length===t.length&&e.every((e,n)=>e===t[n])}const Xo=async(e,t)=>{let n=await Qo(e,t),r=Uo({previous:n.session?.snapshot,current:n.snapshot,options:t,identity:{previousAppBundleId:n.session?.appBundleId,currentAppBundleId:n.result.appBundleId??n.session?.appBundleId}});await e.sessions.set(es(t.session,n));let i=ns(n.snapshot);return m(n.snapshot,{nodes:n.snapshot.nodes,...i===void 0?{}:{truncated:i},visibility:Vo({nodes:n.snapshot.nodes,backend:n.snapshot.backend,snapshotRaw:t.raw}),...p({...n.annotations,warnings:n.warnings}),...r?{unchanged:r}:{},...n.result.snapshotDiagnostics?{snapshotDiagnostics:n.result.snapshotDiagnostics}:{},...n.snapshot.keyboard?{keyboard:n.snapshot.keyboard}:{},...n.snapshot.viewport?{viewport:n.snapshot.viewport}:{},...ts(n)})},Zo=async(e,t)=>{if(t.observeOnly===!0)throw new a(`INVALID_ARGS`,`observeOnly is supported by snapshot, not diff.`);let n=await Qo(e,t),r=t.interactiveOnly===!0,i=n.session?.snapshot,o=es(t.session,n);if(!i){let t=Et(n.snapshot.nodes,{flatten:r});return await e.sessions.set(o),{mode:`snapshot`,baselineInitialized:!0,summary:{additions:0,removals:0,unchanged:t},lines:[],...n.warnings.length>0?{warnings:n.warnings}:{}}}let s=Tt(i.nodes,n.snapshot.nodes,{flatten:r});return await e.sessions.set(o),{mode:`snapshot`,baselineInitialized:!1,summary:s.summary,lines:s.lines,...n.warnings.length>0?{warnings:n.warnings}:{}}};async function Qo(e,t){if(!e.backend.captureSnapshot)throw new a(`UNSUPPORTED_OPERATION`,`snapshot is not supported by this backend`);let n=t.session??`default`,r=await e.sessions.get(n),i=await e.backend.captureSnapshot({session:n,requestId:t.requestId,appId:r?.appId,appBundleId:r?.appBundleId,signal:t.signal??e.signal,metadata:t.metadata},{interactiveOnly:t.interactiveOnly,depth:t.depth,scope:t.scope,raw:t.raw,customActions:t.customActions,...t.observeOnly===void 0?{}:{observeOnly:t.observeOnly}}),o=$o(i,e),s=m(o,Ho(o,t)),c=f(i),l=F(e);return{snapshot:s,result:i,session:r,annotations:c,warnings:rs({result:i,annotations:c,snapshot:s,options:t,session:r,capturedAt:s.createdAt??l,runtimeNow:l})}}function $o(e,t){return e.snapshot?m(e.snapshot,{...e.snapshot,...e.keyboard?{keyboard:e.keyboard}:{},...e.viewport?{viewport:e.viewport}:{}}):{nodes:e.nodes??[],truncated:e.truncated,backend:e.backend,createdAt:F(t),...e.keyboard?{keyboard:e.keyboard}:{},...e.viewport?{viewport:e.viewport}:{}}}function es(e,t){let n=t.session?.name??e??`default`;return{...t.session??{name:n},name:n,snapshot:t.snapshot,appName:t.result.appName??t.session?.appName,appBundleId:t.result.appBundleId??t.session?.appBundleId}}function ts(e){let t=e.result.appName??e.session?.appName,n=e.result.appBundleId??e.session?.appBundleId;return{...t||n?{appName:t??n}:{},...n?{appBundleId:n}:{}}}function ns(e){return e.truncated===void 0?e.backend!==`xctest`||e.producer===void 0?!1:ot(e.producer)===`unavailable`&&void 0:e.truncated}function rs(e){let t=[...e.annotations.warnings??[]];e.annotations.quality&&t.push(...st(e.annotations.quality,e.snapshot.nodes)),t.push(...ct(ns(e.snapshot))),e.snapshot.postGestureOutcome&&t.push(Ue(e.snapshot.postGestureOutcome)),t.push(...cs(e)),e.annotations.quality||(t.push(...as(e)),t.push(...ss(e.snapshot.nodes)));let n=Ne(e.snapshot.nodes);n&&t.push(n);let r=is(e.annotations);r&&t.push(r);let i=ls(e);return i&&t.push(i),t.push(...ps(e.annotations.freshness,e.snapshot.backend)),Array.from(new Set(t))}function is(e){if(e.androidSnapshot?.systemSurfaceOnly===!0)return _t}function as(e){if(e.snapshot.backend!==`xctest`||e.options.interactiveOnly!==!0||e.snapshot.nodes.length!==1)return[];let t=e.snapshot.nodes[0];return os(t)?e.snapshot.producer===`appium-source`?[`Appium page source exposed only the application root. Descendants may be absent from the acquired hierarchy; use snapshot --raw to inspect the source and verify the app accessibility tree.`]:e.snapshot.producer!==void 0&&e.snapshot.producer!==`apple-runner`?[]:[`iOS interactive snapshot exposed only the application root. XCTest accessibility queries can fail to enumerate some simulator UI trees even when screenshots and direct gestures still work. Use screenshot as visual truth, try a scoped/full snapshot for diagnostics, and prefer direct selectors when known.`]:[]}function os(e){return e?se(e.type??``)===`application`:!1}function ss(e){let t=new Set(e.map(e=>e.parentIndex).filter(e=>e!==void 0));return e.filter(e=>t.has(e.index)||(e.type?.toLowerCase()??``).includes(`text`)?!1:(e.label??``).split(`, `).length>10).map(e=>{let t=(e.label??``).split(`, `).length,n=e.identifier?` (${e.identifier})`:``;return`@${e.ref} [${e.type??`element`}]${n} merges ~${t} labels into a single accessibility element. The app likely marks a container as accessible, which hides every descendant from assistive tech and automation — the children cannot be addressed individually. Fix the app's accessibility (mark the rows, not the container); until then use screenshot as visual truth and coordinate taps.`})}function cs(e){let t=e.annotations.analysis;if(e.snapshot.backend!==`android`||e.options.interactiveOnly!==!0||e.snapshot.nodes.length>0||!t||(t.rawNodeCount??0)<12)return[];let n=[`Interactive snapshot is empty after filtering ${t.rawNodeCount} raw Android nodes. Likely causes: the app content is not accessibility-visible yet, a transient route change, or depth/filter options hid the target.`];return typeof e.options.depth==`number`&&typeof t.maxDepth==`number`&&t.maxDepth>=e.options.depth+2&&n.push(`Interactive output is empty at depth ${e.options.depth}; retry without -d.`),n}function ls(e){let t=e.session?.snapshot;if(!e.annotations.freshness&&t&&us(t,e.snapshot)&&ds(t,e.capturedAt,e.runtimeNow)&&He(t.nodes.length,e.snapshot.nodes.length))return fs}function us(e,t){return e.presentationKey===void 0||t.presentationKey===void 0||e.presentationKey===t.presentationKey}function ds(e,t,n){return[t,n].some(t=>{let n=t-e.createdAt;return n>=0&&n<=2e3})}const fs=`Recent snapshots dropped sharply in node count, which suggests stale or mid-transition UI. Use screenshot as visual truth, wait briefly, then re-snapshot once.`;function ps(e,t){return!e?.staleAfterRetries||t!==`android`?[]:e.reason===`stuck-route`?[`Recent ${e.action} was followed by a nearly identical snapshot after ${e.retryCount} automatic retr${e.retryCount===1?`y`:`ies`}. If you expected navigation or submit, the tree may still be stale. Use screenshot as visual truth, wait briefly, then re-snapshot once.`]:e.reason===`sharp-drop`?[fs]:[]}const ms={screenshot:Bo,diffScreenshot:ko,snapshot:Xo,diffSnapshot:Zo};function hs(e){return bt(ms,e)}function gs(e){return{backend:e.backend,artifacts:e.artifacts,sessions:e.sessions??_s(),policy:e.policy??ut(),diagnostics:e.diagnostics,clock:e.clock,signal:e.signal}}function _s(e=[]){let t=new Map(e.map(e=>[e.name,vs(e)]));return{get:e=>vs(t.get(e)),set:e=>{t.set(e.name,vs(e))},delete:e=>{t.delete(e)},list:()=>Array.from(t.values(),e=>vs(e))}}function vs(e){if(e)return{...e,...e.snapshot?{snapshot:structuredClone(e.snapshot)}:{},...e.metadata?{metadata:ys(e.metadata)}:{}}}function ys(e){try{return structuredClone(e)}catch{return{...e}}}export{Oa as a,I as c,Eo as i,P as l,hs as n,Da as o,Do as r,bt as s,gs as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{D as e,P as t,Z as n,g as r,k as i,s as a,x as o}from"./sdk-contracts.js";import"./tv-remote.js";import{i as s}from"./snapshot-capture-annotations.js";import{r as c}from"./snapshot-diagnostics.js";import{l}from"./android-input-ownership.js";import{r as u}from"./diagnostics.js";import"./diagnostics2.js";import{E as d}from"./sdk-device.js";import{Sn as f}from"./sdk-batch.js";import{t as p}from"./interaction-error.js";import{t as m}from"./snapshot-state.js";import{H as h,Y as g,ct as _,et as v,lt as y,q as b,st as x,yt as S}from"./internal/daemon.js";import{t as C}from"./snapshot-node-lookup.js";import{randomInt as w}from"node:crypto";function T(e,t){e.snapshot!==t&&(e.snapshotGeneration=O(e.snapshotGeneration)),e.snapshot=t,e.snapshotScopeSource=void 0,t.comparisonSafe===!0&&(e.lastComparisonSafeSnapshot=t)}function E(e){e.snapshot=void 0}function D(e,t){e.snapshot=t.snapshot,t.snapshot.comparisonSafe===!0&&(e.lastComparisonSafeSnapshot=t.snapshot),e.snapshotScopeSource=t.scopeSource,e.snapshotGeneration=t.keptCurrentSnapshot?t.previousGeneration:O(t.previousGeneration)}function O(e){return e===void 0?w(1e5,1e6):e+1}function k(e){let t=e.startsWith(`@`)?e.slice(1):e,n=t.indexOf(`~`);return n===-1?t:t.slice(0,n)}function A(e,t){let n=new Set;for(let e of t){let t=k(e);t.length>0&&n.add(t)}n.size!==0&&v(e,n)}function j(e,t,n){if(!e||!n?.diff)return;let r=t.resolveCurrent(e);if(r)return A(r,P(n)),r.snapshotGeneration}function M(e,r,i,a){if(i.code!==`AMBIGUOUS_MATCH`)return i;let o=n(i.details);if(o.length===0)return i;let s=e?r.resolveCurrent(e):void 0;return s?.snapshot&&s.snapshotGeneration!==void 0&&a!==void 0&&a.nodes===s.snapshot.nodes?(A(s,o),new t(i.code,i.message,{...i.details,refsGeneration:s.snapshotGeneration},i.cause)):N(i)}function N(e){let{candidates:n,refsGeneration:r,...i}=e.details??{};return new t(e.code,e.message,{...i,hint:`Narrow the selector with role/id/longer text and retry.`},e.cause)}function P(e){let t=[];for(let n of e.diff?.lines??[])n.ref&&t.push(n.ref);for(let n of e.refs??[])t.push(n.ref);for(let n of e.tail??[])t.push(n.ref);return t}function F(e){return`Ref @${e.ref.startsWith(`@`)?e.ref.slice(1):e.ref} was minted from snapshot s${e.mintedGeneration} but the session's ref frame is now s${e.currentFrameEpoch} — re-run snapshot -i.`}function I(e){let{session:t,ref:n,mintedGeneration:r}=e;if(t&&_(t)===`expired`)return`The UI may have changed since these refs were issued, so they no longer represent current device state. Take a new snapshot before relying on or interacting with them.`;if(r!==void 0){let e=t?x(t)??0:0;if(r!==e)return F({ref:n,mintedGeneration:r,currentFrameEpoch:e})}}async function L(e){let t=await(await S().resolve(e.device,e.runnerContext)).snapshot(e.options);if(!(`stage`in t))return t;let{presentIosSnapshotAcquisition:n}=await import(`./ios-snapshot-runtime.js`);return await n(t,e.options)}async function R(e){let t=await b({session:e.session,device:e.device,interactiveOnly:e.flags?.snapshotInteractiveOnly===!0,androidFreshnessMode:e.androidFreshnessMode,capture:()=>B(e)});if(t)return t;let n=await B(e);return g(e.session),{snapshot:n.snapshot,...n.annotations}}async function z(e){if(e.captureData)return await e.captureData();let{device:t,session:n,logPath:a}=e,o=h(a,V(e),n?.appBundleId,n?.trace?.outPath);return await L({device:t,runnerContext:{requestId:o.requestId,signal:e.signal,appBundleId:o.appBundleId,verbose:o.verbose,logPath:o.logPath,traceLogPath:o.traceLogPath,iosXctestrunFile:o.iosXctestrunFile,iosXctestDerivedDataPath:o.iosXctestDerivedDataPath,iosXctestEnvDir:o.iosXctestEnvDir,runnerLeaseContext:o.runnerLeaseContext},options:{appBundleId:o.appBundleId,signal:e.signal,...i(o,r),includeRects:e.includeRects,surface:n?.surface}})}async function B(e){let t=Date.now(),n=await z(e);c(e.session,{durationMs:Date.now()-t,backend:n.backend,platform:d(e.device)});let r=s(n),i=l(n,m(n,V(e)));return r.androidSnapshot?.systemSurfaceOnly===!0&&(i.systemSurfaceOnly=!0),{data:n,snapshot:i,annotations:r}}function V(e){return e.snapshotScope===void 0?e.flags:{...e.flags,snapshotScope:e.snapshotScope}}function H(t,n){if(!t||!t.trim().startsWith(`@`))return{ok:!0,scope:t};if(!n?.snapshot)return a(`INVALID_ARGS`,`Ref scope requires an existing snapshot in session.`);let r=e(t.trim());if(!r)return a(`INVALID_ARGS`,`Invalid ref scope: ${t}`);let i=[n.snapshot,...n.snapshotScopeSource?[n.snapshotScopeSource]:[]],s=!1,c;for(let e of i){let t=o(e.nodes,r);if(t&&(s=!0,c=C(t,e.nodes),c))break}return s?c?{ok:!0,scope:c}:a(`COMMAND_FAILED`,`Ref ${t} has no label to scope by`,{reason:p.refUnlabeled,ref:r}):a(`COMMAND_FAILED`,`Ref ${t} not found`,{reason:p.refNotFound,ref:r},{hint:f})}function U(e,t,n={}){if(!e)return;let r=y(e);return{name:t,appBundleId:e.appBundleId,appName:e.appName,...n.includeSnapshot===!0?{snapshot:e.snapshot,...r&&n.omitRefFrameSnapshot!==!0?{refFrameSnapshot:r}:{}}:{},metadata:{surface:e.surface,...n.metadata??{}}}}function W(e,t){return{get:n=>n===e?U(t,e):void 0,set:()=>{}}}function G(e){let t=e.ref;return{getRef:()=>t?e.sessionStore.refresh(t):void 0,get:n=>n===e.sessionName?U(t?e.sessionStore.resolveCurrent(t):void 0,e.sessionName,e.recordOptions):void 0,set:n=>{if(n.name!==e.sessionName){u({level:`warn`,phase:`runtime_session_write_skipped`,data:{expected:e.sessionName,received:n.name}});return}let r=t?e.sessionStore.requireCurrent(t):void 0,i=e.setRecord(n,r,t);i&&(t=i)}}}export{H as a,A as c,D as d,T as f,z as i,M as l,W as n,E as o,R as r,j as s,G as t,I as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{P as e}from"./sdk-contracts.js";import{URL as t}from"node:url";function n(n){if(!n)return;let
|
|
1
|
+
import{P as e}from"./sdk-contracts.js";import{URL as t}from"node:url";function n(n){if(!n)return;let i=a(n.metroHost),c=o(n.metroPort),l=`http`,u=r(n.bundleUrl);if(u){let n;try{n=new t(u)}catch(t){throw new e(`INVALID_ARGS`,`Invalid runtime bundle URL: ${u}`,{},t)}(n.protocol===`http:`||n.protocol===`https:`)&&(i??=r(n.hostname),c??=o(n.port.length>0?Number(n.port):s(n.protocol)),l=n.protocol===`https:`?`https`:`http`)}if(!(!i||!c))return{host:i,port:c,scheme:l}}function r(e){let t=e?.trim();return t&&t.length>0?t:void 0}function i(e){let r=n(e);if(!r)return;let i=r.host.includes(`:`)&&!r.host.startsWith(`[`)?`[${r.host}]`:r.host,a=new t(`${r.scheme}://${i}:${r.port}`);if(e?.bundleUrl?.trim()){let n=new t(e.bundleUrl).pathname.replace(/\/+$/,``);a.pathname=n.endsWith(`/.expo/.virtual-metro-entry.bundle`)?n.slice(0,-34):/\.(?:bundle|jsbundle|js)$/.test(n)?n.slice(0,n.lastIndexOf(`/`)):n}return a}function a(t){let n=r(t);if(n&&/[/\\?#@\s]/.test(n))throw new e(`INVALID_ARGS`,`Invalid runtime Metro host: ${n}. Use a hostname or IP address.`);return n}function o(e){if(Number.isInteger(e)&&!(e<=0||e>65535))return e}function s(e){if(e===`https:`)return 443;if(e===`http:`)return 80}export{n,r,i as t};
|