agent-device 0.21.5 → 0.21.7
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.5.apk → agent-device-android-ime-helper-0.21.7.apk} +0 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.7.apk.sha256 +1 -0
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.5.manifest.json → agent-device-android-ime-helper-0.21.7.manifest.json} +4 -4
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.5.apk → agent-device-android-snapshot-helper-0.21.7.apk} +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.7.apk.sha256 +1 -0
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.5.manifest.json → agent-device-android-snapshot-helper-0.21.7.manifest.json} +6 -6
- package/apple/snapshot-bridge/SnapshotBridgeRuntime.m +8 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.h +4 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.m +20 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerScrollViewportPolicy.swift +1 -2
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +25 -12
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +56 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +1 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +36 -108
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Keyboard.swift +241 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +29 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +46 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+PrivateAXPresentation.swift +85 -26
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +134 -117
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotBackendCapabilities.swift +1 -3
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +25 -4
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SystemModal.swift +1 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +3 -0
- package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotCoordinateSpace.swift +197 -0
- package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotModels.swift +30 -4
- package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentation.swift +0 -81
- package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentationInvariant.swift +1 -9
- package/dist/src/absence-observation-errors.js +1 -1
- package/dist/src/adapter.js +1 -1
- package/dist/src/adb-executor.js +2 -2
- package/dist/src/adb-failure.js +1 -1
- package/dist/src/adb-transport.js +1 -0
- package/dist/src/adb.js +1 -1
- package/dist/src/agent-browser-lifecycle.js +1 -1
- package/dist/src/agent-browser-process-record.js +1 -1
- package/dist/src/agent-browser-provider.js +1 -1
- package/dist/src/agent-browser-tool.js +1 -1
- package/dist/src/agent-device-client.js +2 -2
- package/dist/src/ai-sdk.js +1 -1
- package/dist/src/alert-runtime.js +1 -1
- package/dist/src/android-adb.d.ts +29 -2
- package/dist/src/android-adb.js +1 -1
- package/dist/src/android-input-ownership.js +1 -1
- package/dist/src/android.js +1 -1
- package/dist/src/app-catalog.js +1 -1
- package/dist/src/app-deployment-resolution.js +1 -1
- package/dist/src/app-helpers.js +1 -1
- package/dist/src/app-inventory.js +1 -1
- package/dist/src/app-launch.js +2 -2
- package/dist/src/app-lifecycle.js +3 -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.js +2 -2
- package/dist/src/app-state.js +1 -1
- package/dist/src/apple-runner-platform.js +1 -1
- package/dist/src/application-lifecycle-interaction.js +1 -1
- package/dist/src/archive.js +1 -1
- package/dist/src/artifact-download.js +1 -1
- package/dist/src/auth-session.js +1 -1
- package/dist/src/auth.js +1 -1
- package/dist/src/back-mode.js +1 -1
- package/dist/src/backend-snapshot-options.js +1 -1
- package/dist/src/boot-diagnostics.js +1 -1
- package/dist/src/capture-disclosure.js +1 -0
- package/dist/src/capture.js +1 -1
- package/dist/src/cli-config.js +1 -1
- package/dist/src/cli-help.js +15 -2
- package/dist/src/cli-output.js +1 -1
- package/dist/src/cli.js +4 -4
- package/dist/src/click-button.js +1 -1
- package/dist/src/client-metro.js +1 -1
- package/dist/src/client-types.d.ts +32 -2
- package/dist/src/clipboard-shell-response.js +1 -0
- package/dist/src/command-schema.js +1 -1
- package/dist/src/command-tools.js +4 -2
- package/dist/src/command.js +1 -1
- package/dist/src/config.js +1 -1
- package/dist/src/connection-runtime.js +1 -1
- package/dist/src/connection.js +1 -1
- package/dist/src/contracts.d.ts +1 -1
- package/dist/src/contracts.js +1 -1
- package/dist/src/daemon-client-lifecycle.js +1 -1
- package/dist/src/daemon.js +1 -1
- package/dist/src/debug-symbols-facade.js +1 -1
- package/dist/src/device-boot.js +1 -1
- package/dist/src/device-claim-inspection.js +1 -1
- package/dist/src/device-claim-rule.js +2 -1
- package/dist/src/device-input-state.d.ts +7 -8
- package/dist/src/device-inventory-context.js +1 -1
- package/dist/src/device-rotation.js +1 -1
- package/dist/src/device-selection-resolver.js +1 -1
- package/dist/src/device-session.js +1 -1
- package/dist/src/device-shell.js +1 -0
- package/dist/src/device.js +1 -1
- package/dist/src/device2.js +1 -1
- package/dist/src/devicectl.js +1 -0
- package/dist/src/diagnostics.js +1 -1
- package/dist/src/dispatch-resolve.js +1 -1
- package/dist/src/display-inventory.js +1 -0
- package/dist/src/doctor-facade.js +1 -1
- package/dist/src/doctor2.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/file.js +1 -1
- package/dist/src/find.js +1 -1
- package/dist/src/finders.js +1 -1
- package/dist/src/format.js +2 -1
- package/dist/src/generic.js +1 -1
- package/dist/src/gesture-admission.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 +1 -1
- package/dist/src/human-control-contract.js +1 -1
- package/dist/src/human-control.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 +1 -1
- package/dist/src/install-artifact-facade.js +1 -1
- package/dist/src/install-source-network-transport.js +1 -1
- package/dist/src/install-source2.js +1 -1
- package/dist/src/interaction-positionals.js +1 -1
- package/dist/src/interaction-ref-policy.js +1 -1
- package/dist/src/interaction.js +1 -1
- package/dist/src/interaction2.js +1 -1
- package/dist/src/interactor-operation-catalog.js +1 -1
- package/dist/src/interactor.js +5 -5
- package/dist/src/interactor2.js +1 -1
- package/dist/src/interactors.js +1 -1
- package/dist/src/internal/bin.js +1 -1
- package/dist/src/internal/daemon.js +2 -2
- package/dist/src/internal/png-worker.d.ts +4 -1
- package/dist/src/internal/png-worker.js +1 -1
- package/dist/src/internal/run-script-http-child.d.ts +1 -1
- package/dist/src/internal/run-script-http-child.js +1 -1
- package/dist/src/inventory.js +4 -4
- package/dist/src/inventory2.js +1 -1
- package/dist/src/inventory3.js +2 -2
- package/dist/src/inventory5.js +1 -1
- package/dist/src/ios-snapshot-acquisition.js +1 -1
- package/dist/src/ios-snapshot-runtime.js +1 -1
- package/dist/src/ios-target-activation.js +1 -0
- package/dist/src/lease-context.js +1 -1
- package/dist/src/lease-scope.js +1 -1
- package/dist/src/lease.js +1 -1
- package/dist/src/limrun-download-file.js +1 -0
- package/dist/src/limrun-runtime-dependencies.js +1 -1
- package/dist/src/limrun.d.ts +10 -4
- package/dist/src/linux.js +1 -1
- package/dist/src/local-interactor-operation-set.js +1 -1
- package/dist/src/location-coordinates.js +1 -1
- package/dist/src/logcat.js +1 -1
- package/dist/src/managed-device-scope.js +1 -1
- package/dist/src/mechanics.js +16 -16
- package/dist/src/mobile-snapshot-semantics.js +1 -1
- package/dist/src/multitouch-support.js +1 -1
- package/dist/src/observation.js +2 -2
- package/dist/src/output-common.js +5 -2
- package/dist/src/parameterized-recorded-fill.js +1 -1
- package/dist/src/perf-facade.js +2 -2
- package/dist/src/perf-runtime-operation-builder.js +1 -1
- package/dist/src/perf-runtime-plan.js +1 -1
- package/dist/src/perf.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-host.js +1 -1
- package/dist/src/platform-runtime-managed-owner.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-apple-transport.js +1 -1
- package/dist/src/platform-runtime-screen-recording-finalizer-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-harmony-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-process-host.js +1 -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/png-crop-bytes.js +1 -1
- package/dist/src/png-transcode.js +1 -0
- package/dist/src/png-worker-client.js +1 -0
- package/dist/src/png.js +1 -1
- package/dist/src/prepare-kind.js +1 -1
- package/dist/src/provider-session-ownership.js +1 -1
- package/dist/src/provider-webdriver.js +1 -1
- package/dist/src/proxy.js +1 -1
- package/dist/src/quality-warnings.js +1 -1
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-runtime.js +1 -1
- package/dist/src/record-trace.js +1 -1
- package/dist/src/rect-center.js +1 -1
- package/dist/src/register-builtins.js +1 -1
- package/dist/src/registry.js +35 -35
- package/dist/src/remote-config2.js +1 -1
- package/dist/src/replay-divergence.js +1 -1
- package/dist/src/replay.js +2 -2
- package/dist/src/reporting.js +1 -1
- package/dist/src/request-admission.js +1 -1
- package/dist/src/request-cancel.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-metadata.js +2 -2
- package/dist/src/runner-client.js +1 -1
- package/dist/src/runner-disposal.js +1 -1
- package/dist/src/runner-operations-facade.js +1 -1
- package/dist/src/runner-presentation.js +1 -1
- package/dist/src/runner.js +1 -1
- package/dist/src/runtime-transport-hints.js +1 -1
- package/dist/src/runtime.js +3 -3
- package/dist/src/runtime10.js +1 -1
- package/dist/src/runtime2.js +4 -4
- package/dist/src/runtime3.js +1 -1
- package/dist/src/runtime4.js +5 -5
- package/dist/src/runtime5.js +1 -1
- package/dist/src/runtime6.js +1 -1
- package/dist/src/runtime7.js +1 -1
- package/dist/src/runtime8.js +1 -1
- package/dist/src/runtime9.js +1 -1
- package/dist/src/screen-recording-admission-ledger.js +1 -0
- package/dist/src/screen-recording-completion.js +1 -1
- package/dist/src/screen-recording-options.js +1 -1
- package/dist/src/screen-recording-resource-recovery.js +1 -1
- package/dist/src/screen-recording-transport.js +1 -0
- package/dist/src/screenshot-density.js +1 -1
- package/dist/src/screenshot-runtime.js +1 -1
- package/dist/src/screenshot.js +1 -1
- package/dist/src/screenshot3.js +1 -1
- package/dist/src/script.js +1 -1
- package/dist/src/scroll-command.js +1 -1
- package/dist/src/scroll-gesture.js +1 -1
- package/dist/src/sdk-batch-runner.js +2 -2
- package/dist/src/sdk-batch.js +2 -2
- package/dist/src/sdk-contracts.d.ts +76 -1
- package/dist/src/sdk-contracts.js +1 -1
- package/dist/src/sdk-device.js +1 -1
- package/dist/src/sdk-finders.d.ts +1 -1
- package/dist/src/sdk-finders.js +1 -1
- package/dist/src/sdk-io.js +1 -1
- package/dist/src/sdk-remote-config.js +1 -1
- package/dist/src/sdk-selectors.d.ts +18 -1
- package/dist/src/sdk-selectors.js +1 -1
- package/dist/src/selection.js +0 -0
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/selectors.js +1 -1
- package/dist/src/semantic-index.js +1 -1
- package/dist/src/server.js +1 -1
- package/dist/src/session-allocation.js +1 -1
- package/dist/src/session-observation.js +1 -1
- package/dist/src/session-routing.js +1 -1
- package/dist/src/session-runtime-admission.js +1 -1
- package/dist/src/session-snapshot.js +1 -1
- package/dist/src/session-store.js +3 -3
- package/dist/src/session2.js +4 -5
- package/dist/src/settings.js +1 -1
- package/dist/src/simctl-facade.js +1 -1
- package/dist/src/simctl.js +1 -1
- package/dist/src/simulator-boot.js +1 -1
- package/dist/src/simulator.js +1 -1
- package/dist/src/snapshot-capture-annotations.js +1 -1
- package/dist/src/snapshot-diagnostics.js +1 -1
- package/dist/src/snapshot-quality-backend-capabilities.js +1 -1
- 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/snapshot4.js +1 -1
- package/dist/src/src.js +1 -1
- package/dist/src/src4.js +1 -1
- package/dist/src/src7.js +1 -1
- package/dist/src/src8.js +1 -1
- package/dist/src/stop-sequence.js +1 -1
- package/dist/src/string-enum.js +1 -1
- package/dist/src/takeover.js +1 -1
- package/dist/src/text-entry-focus.js +1 -1
- package/dist/src/tool-provider.js +1 -1
- package/dist/src/tool-provider2.js +1 -1
- package/dist/src/touch-runtime.js +1 -1
- package/dist/src/transport.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/verified-file.js +1 -1
- package/dist/src/video.js +2 -2
- package/dist/src/viewport.js +1 -1
- package/dist/src/web.js +1 -1
- package/dist/src/web2.js +1 -1
- package/dist/src/webdriver-source.js +1 -1
- package/dist/src/window-state.js +1 -1
- package/package.json +3 -2
- package/server.json +2 -2
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.5.apk.sha256 +0 -1
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.5.apk.sha256 +0 -1
- package/dist/src/adb-host.js +0 -1
- package/dist/src/session-target-evidence.js +0 -1
- package/dist/src/vars.js +0 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { E as IosTargetActivation, H as DaemonError, I as SnapshotQualityVerdict, M as SnapshotKeyboardBandFact, N as SnapshotNode, R as SnapshotUnchanged, S as DeviceTarget, T as PublicPlatform, U as NormalizedError, _ as SessionIsolationMode, a as DaemonRequest, f as LeaseBackend, g as ResponseLevel, i as DaemonLockPolicy, j as SnapshotCommandOptionFields, m as NetworkIncludeMode, o as DaemonResponse, r as DaemonInstallSource, s as DaemonResponseData, t as DaemonArtifact, v as SessionRuntimeHints, w as PlatformSelector, x as DeviceKind, y as AppleOS, z as SnapshotVisibility } from "./sdk-contracts.js";
|
|
2
2
|
import { t as AppsFilter } from "./app-inventory.js";
|
|
3
3
|
import { B as FindLocator, C as MACOS_PERMISSION_TARGETS, D as BackMode, E as PermissionMode, F as SwipePattern, H as SnapshotDiagnosticsSummary, I as SwipePreset, L as TransformGestureParams, N as ScrollDirection, O as GesturePointerCount, P as ScrollInputDirection, R as ClickButton, S as DeviceRotation, T as PermissionAction, U as SessionSurface, V as ScreenshotResultData, _ as HoverCommandResponseData, b as SettleObservation, g as FindCommandResponseData, h as FillCommandResponseData, m as ClickCommandResponseData, p as ScrollCommandResult, v as LongPressCommandResponseData, w as MOBILE_PERMISSION_TARGETS, x as TvRemoteButton, y as PressCommandResponseData, z as AndroidSnapshotBackendMetadata } from "./sdk-selectors.js";
|
|
4
4
|
import { a as RemoteConnectionProfileFields, c as MetroPrepareResult, i as CloudProviderProfileFields, l as MetroReloadOptions, s as MetroPrepareOptions, u as MetroReloadResult } from "./sdk-remote-config.js";
|
|
@@ -194,6 +194,14 @@ type AppOpenOptions = AgentDeviceRequestOverrides & AgentDeviceSelectionOptions
|
|
|
194
194
|
relaunch?: boolean;
|
|
195
195
|
/** Startup budget in milliseconds: bounds the Simulator boot wait on a cold device. */
|
|
196
196
|
timeoutMs?: number;
|
|
197
|
+
/**
|
|
198
|
+
* Block this open for up to n milliseconds (100-120000) while another session holds the device,
|
|
199
|
+
* then fail with DEVICE_IN_USE naming that session. Only session contention is waited for: a
|
|
200
|
+
* device claim held by another workspace is refused at once with its recovery command. A device
|
|
201
|
+
* that never frees, or is taken again while this open waits, costs the full budget, which
|
|
202
|
+
* extends this command's timeout envelope rather than eating into it.
|
|
203
|
+
*/
|
|
204
|
+
waitMs?: number;
|
|
197
205
|
/**
|
|
198
206
|
* Include an initial interactive snapshot in a fresh open response. With no
|
|
199
207
|
* app argument, discover the sole running app on the sole booted iOS
|
|
@@ -313,8 +321,10 @@ type SnapshotCaptureAnnotations = {
|
|
|
313
321
|
freshness?: SnapshotCaptureFreshness;
|
|
314
322
|
quality?: SnapshotQualityVerdict;
|
|
315
323
|
warnings?: string[];
|
|
324
|
+
/** The Apple runner re-activated the session app while serving this capture (#2682). */
|
|
325
|
+
targetActivation?: IosTargetActivation;
|
|
316
326
|
};
|
|
317
|
-
type PublicSnapshotCaptureAnnotations = Pick<SnapshotCaptureAnnotations, 'androidSnapshot' | 'warnings'> & {
|
|
327
|
+
type PublicSnapshotCaptureAnnotations = Pick<SnapshotCaptureAnnotations, 'androidSnapshot' | 'warnings' | 'targetActivation'> & {
|
|
318
328
|
snapshotQuality?: SnapshotQualityVerdict;
|
|
319
329
|
};
|
|
320
330
|
//#endregion
|
|
@@ -348,6 +358,13 @@ type CaptureSnapshotResult = {
|
|
|
348
358
|
visibility?: SnapshotVisibility;
|
|
349
359
|
unchanged?: SnapshotUnchanged;
|
|
350
360
|
snapshotDiagnostics?: SnapshotDiagnosticsSummary;
|
|
361
|
+
/**
|
|
362
|
+
* The keyboard band this capture's producer measured (#2660), in the same orientation space as the
|
|
363
|
+
* node rects. The acting commands read it off the session state they act with; it is published so a
|
|
364
|
+
* caller can see the band a `tap_keyboard_occludes_target` refusal measured against. Absent means
|
|
365
|
+
* the producer measured no band and the tap guard derived one from the tree.
|
|
366
|
+
*/
|
|
367
|
+
keyboard?: SnapshotKeyboardBandFact;
|
|
351
368
|
/**
|
|
352
369
|
* Screenshot captured automatically when the semantic snapshot was sparse.
|
|
353
370
|
* Remote clients receive a materialized local path through the daemon artifact channel.
|
|
@@ -998,6 +1015,7 @@ type OrientationCommandOptions = DeviceCommandBaseOptions & {
|
|
|
998
1015
|
orientation: DeviceRotation;
|
|
999
1016
|
};
|
|
1000
1017
|
type AppSwitcherCommandOptions = DeviceCommandBaseOptions;
|
|
1018
|
+
type ActionButtonCommandOptions = DeviceCommandBaseOptions;
|
|
1001
1019
|
type TvRemoteCommandOptions = DeviceCommandBaseOptions & {
|
|
1002
1020
|
button: TvRemoteButton;
|
|
1003
1021
|
durationMs?: number;
|
|
@@ -1315,6 +1333,16 @@ type AppSwitcherCommandResult = {
|
|
|
1315
1333
|
action: 'app-switcher';
|
|
1316
1334
|
message: string;
|
|
1317
1335
|
};
|
|
1336
|
+
/**
|
|
1337
|
+
* `action-button` — `{ action: 'action-button', message: 'Pressed Action Button' }`.
|
|
1338
|
+
*
|
|
1339
|
+
* Deliberately narrower than `tv-remote`: `XCUIDevice.press(.action)` takes no hold duration, so
|
|
1340
|
+
* there is no `durationMs` to report and no button to name.
|
|
1341
|
+
*/
|
|
1342
|
+
type ActionButtonCommandResult = {
|
|
1343
|
+
action: 'action-button';
|
|
1344
|
+
message: string;
|
|
1345
|
+
};
|
|
1318
1346
|
/** `tv-remote` — `{ action: 'tv-remote', button, durationMs?, message }`. */
|
|
1319
1347
|
type TvRemoteCommandResult = {
|
|
1320
1348
|
action: 'tv-remote';
|
|
@@ -1522,6 +1550,7 @@ type TraceCommandResult = {
|
|
|
1522
1550
|
* re-read of the handler's literal return; see the per-type docstrings.
|
|
1523
1551
|
*/
|
|
1524
1552
|
interface CommandResultMap {
|
|
1553
|
+
'action-button': ActionButtonCommandResult;
|
|
1525
1554
|
'app-switcher': AppSwitcherCommandResult;
|
|
1526
1555
|
appstate: AppStateCommandResult;
|
|
1527
1556
|
back: BackCommandResult;
|
|
@@ -1566,6 +1595,7 @@ type AgentDeviceCommandClient = {
|
|
|
1566
1595
|
home: (options?: HomeCommandOptions) => Promise<CommandResult<'home'>>;
|
|
1567
1596
|
orientation: (options: OrientationCommandOptions) => Promise<CommandResult<'orientation'>>;
|
|
1568
1597
|
appSwitcher: (options?: AppSwitcherCommandOptions) => Promise<CommandResult<'app-switcher'>>;
|
|
1598
|
+
actionButton: (options?: ActionButtonCommandOptions) => Promise<CommandResult<'action-button'>>;
|
|
1569
1599
|
tvRemote: (options: TvRemoteCommandOptions) => Promise<CommandResult<'tv-remote'>>;
|
|
1570
1600
|
wait: (options: WaitCommandOptions) => Promise<CommandResult<'wait'>>;
|
|
1571
1601
|
alert: (options?: AlertCommandOptions) => Promise<CommandRequestResult>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{D as e}from"./sdk-contracts.js";import{n as t,r as n}from"./adb.js";const r=`This Android build ships no shell implementation for the clipboard service, so adb cannot read or write the clipboard on it. Verify a copy flow by pasting into a focused field and reading that field back.`;function i(e){return n(e.stderr)?`no-shell-command`:e.exitCode===0?`executed`:t(e.stdout,e.stderr)?`no-shell-command`:`call-failed`}function a(e){return e===`executed`?`supported`:e===`no-shell-command`?`unsupported`:`probe-failed`}function o(e){return a(i(e))}function s(t){return new e(`UNSUPPORTED_OPERATION`,`Android shell clipboard ${t} is not supported on this device.`,{reason:`android_clipboard_shell_command_unavailable`,hint:r})}export{r as ANDROID_CLIPBOARD_SHELL_COMMAND_UNAVAILABLE_HINT,s as androidClipboardShellCommandUnavailableError,o as androidClipboardShellSupportForResult,i as classifyAndroidClipboardShellResponse};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{D as e}from"./sdk-contracts.js";import{p as t,r as n,u as r}from"./registry.js";import{r as i}from"./command-metadata.js";const a={cdp:{text:{summary:`Inspect CDP targets, JS heap, and leaks`,description:`Run CDP commands for React Native diagnostics, JS heap usage, heap snapshots, and leak analysis`},usageOverride:`cdp [...args]`,listUsageOverride:`cdp`,positionalArgs:[`args?`],allowsExtraPositionals:!0,supportedFlags:r},auth:{text:{summary:`Manage cloud login state`,description:`Manage cloud login state used by remote daemon and cloud device workflows.`},usageOverride:`auth status|login|logout`,listUsageOverride:`auth`,positionalArgs:[`status|login|logout`],supportedFlags:[`remoteConfig`,`stateDir`]},daemon:{text:{summary:`Stop a local daemon and clean up resources`,description:`Stop a local daemon after verifying its PID/start-time identity. Use --clean to remove retained Apple runner processes and leases owned by that daemon.`},usageOverride:`daemon stop [--state-dir <path>]`,listUsageOverride:`daemon stop`,positionalArgs:[`stop`],allowedFlags:[`clean`],supportedFlags:[`stateDir`]},device:{text:{summary:`Inspect and recover enforced local device ownership without a daemon`,description:`Inspect enforced host-local device ownership claims without starting or contacting a daemon; status --stale only inspects proven-stale claims. release --stale settles a provably dead owner through exact-owner resource reconciliation and clears its claim last — live and uncertain owners always fail closed. Automatic reclamation still occurs during open and daemon startup.`},usageOverride:`device status|release [--platform <platform>] [--udid <udid>] [--serial <serial>]`,listUsageOverride:`device status`,positionalArgs:[`status|release`],allowedFlags:[`stale`],supportedFlags:[`platform`,`device`,`udid`,`serial`]},connect:{text:{summary:`Configure remote or provider state`,description:`Configure remote access without allocating a device. Direct providers validate credentials/resources before saving state and print the exact device/app preparation needed before open. AGENT_DEVICE_CLOUD_BASE_URL is the bridge/control-plane API origin; use AGENT_DEVICE_DAEMON_AUTH_TOKEN=adc_live_... for CI/service-token automation.`},usageOverride:`connect [cloud|proxy|limrun|browserstack|aws-device-farm] [--remote-config <path>] [--daemon-base-url <url>] [--tenant <id>] [--run-id <id>] [--lease-id <id>] [--lease-backend <backend>] [--force] [--no-login]`,usageFlags:[],listUsageOverride:`connect`,positionalArgs:[`provider?`],allowedFlags:`remoteConfig.daemonBaseUrl.tenant.runId.leaseId.leaseBackend.providerApp.providerOsVersion.providerProject.providerBuild.providerSessionName.providerDeviceOrientation.providerGeoLocation.providerTimezone.providerAppiumVersion.providerLanguage.providerLocale.providerNetworkProfile.providerCustomNetwork.providerNoResignApp.awsProjectArn.awsDeviceArn.awsAppArn.awsRegion.awsInteractionMode.force.noLogin`.split(`.`),supportedFlags:[`stateDir`,`daemonAuthToken`,`session`,`platform`,`device`,...t,`launchUrl`]},connection:{text:{summary:`Inspect the saved remote connection`,description:`Inspect active remote connection state`},usageOverride:`connection status`,listUsageOverride:`connection`,positionalArgs:[`status`],supportedFlags:[`remoteConfig`,`stateDir`,`session`]},disconnect:{text:{summary:`Clear remote connection state and release leases`,description:`Disconnect remote daemon state, stop owned Metro companion, and release lease`},listUsageOverride:`disconnect`,allowedFlags:[`shutdown`],supportedFlags:[`remoteConfig`,`stateDir`,`session`]},mcp:{text:{summary:`Start MCP server`,description:`Start the official stdio MCP server. It exposes structured command tools backed by the agent-device client.`}},proxy:{text:{summary:`Expose a local daemon through an HTTP tunnel`,description:`Expose the local daemon HTTP contract through a tunnel-friendly reverse proxy.
|
|
2
2
|
|
|
3
3
|
Run this on the host that has access to simulators/devices, expose the printed local proxy URL through a tunnel, then point another machine at the tunnel URL with connect proxy.
|
|
4
4
|
|
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
import{C as e,F as t,I as n,N as r,n as i}from"./sdk-contracts.js";import{g as a,m as o}from"./sdk-batch-runner.js";import{i as s,t as c}from"./sdk-device.js";import{S as l,c as u,d,p as f,w as ee}from"./sdk-batch.js";import{t as te}from"./back-mode.js";import{t as ne}from"./session.js";import{C as re,S as p,_ as m,b as ie,g as h,h as g,y as ae}from"./registry.js";import{n as oe}from"./success-text.js";import{t as se}from"./output-common.js";import"./device.js";import{t as ce}from"./device-rotation.js";import{t as le}from"./tv-remote.js";import{i as ue,n as _,r as de,t as v}from"./command-metadata.js";import{r as fe}from"./replay-divergence.js";import{t as pe}from"./cli-output.js";import{r as me,t as he}from"./recording-stop-observation.js";import{n as ge}from"./error.js";import{n as _e,r as ve,t as ye}from"./cli-config.js";import{n as be}from"./result-serialization.js";const y=[`simulator`,`emulator`,`device`];function b(e){return{type:`number`,...e?{description:e}:{}}}function x(e,t){return{type:`string`,enum:e,...t?{description:t}:{}}}function S(e){return{type:`string`,const:e}}function C(e){return{type:[`string`,`null`],...e?{description:e}:{}}}function w(e,t=[],n){return{type:`object`,...n?{description:n}:{},properties:e,...t.length>0?{required:t}:{}}}const T={type:`array`,items:{type:`string`}},E=w({wallClockMs:b(`Total wall-clock time for the request in milliseconds.`),runnerRoundTrips:b(`Number of real runner round-trips made while serving the request.`),nodeCount:b(`Number of nodes in the original node tree when the response carries one.`)},[`wallClockMs`,`runnerRoundTrips`]),D=w({field:m(),artifactType:m(),path:m(),localPath:m(),fileName:m()},[`field`]);function O(e={}){let t=e.properties??{},n=e.required??[];return w({targetKind:x([`point`,`ref`,`selector`],`Resolved interaction target kind.`),x:b(`Resolved interaction x coordinate when available.`),y:b(`Resolved interaction y coordinate when available.`),referenceWidth:b(`Reference frame width for visualizing the interaction point.`),referenceHeight:b(`Reference frame height for visualizing the interaction point.`),ref:m(`Snapshot ref without the @ prefix when the target was an @ref.`),selector:m(`Selector expression when the target was a selector.`),selectorChain:T,refLabel:m(),targetHittable:g(),hint:m(),warning:m(),message:m(),evidence:j,resolution:xe,cost:E,maestroNonHittableCoordinateFallbackAllowed:g(`Whether the direct iOS Maestro coordinate fallback was allowed for this selector.`),maestroNonHittableCoordinateFallbackUsed:g(`Whether the direct iOS Maestro coordinate fallback was actually used.`),maestroFallbackReason:S(`non-hittable-coordinate`),...t},[`targetKind`,...n])}const k=w({diagnosticRef:m(`Opaque non-@ diagnostic token. Never a snapshot ref: not issued via refsGeneration and cannot be pinned or reused as an @ref target. UTF-8 truncated to 256 bytes.`),role:m(`UTF-8 truncated to 256 bytes.`),label:m(`UTF-8 truncated to 256 bytes.`)},[`diagnosticRef`]),xe={type:`object`,description:`Pre-action disclosure of how the acting path resolved its target. Absent when resolutionDisclosure is inapplicable for the path.`,oneOf:[w({source:S(`runtime`),phase:S(`pre-action`),kind:S(`unique`)},[`source`,`phase`,`kind`]),w({source:S(`runtime`),phase:S(`pre-action`),kind:S(`disambiguated`),matchCount:b(`Total matches resolveSelectorChain found before disambiguation.`),winnerDiagnostic:k,tiebreak:x([`visible`,`deepest`,`smallest-area`,`structural-equivalence`],`The comparison that decided the winner.`),alternatives:{type:`array`,description:`At most 5 losing candidates, document order. Present at default/full response levels and omitted in digest. The winner is never included.`,items:k}},[`source`,`phase`,`kind`,`matchCount`,`winnerDiagnostic`,`tiebreak`]),w({source:S(`ref`),phase:S(`pre-action`),kind:S(`exact`)},[`source`,`phase`,`kind`]),w({source:S(`ref`),phase:S(`pre-action`),kind:S(`label-fallback`)},[`source`,`phase`,`kind`]),w({source:S(`direct-ios`),kind:S(`not-observed`)},[`source`,`kind`])]},A=w({from:m(`Surface the pre-action baseline described: a host bundle id, or app.`),to:m(`Surface the post-action capture describes: a host bundle id, or app.`),disclosure:m(`Agent-facing sentence explaining the surface transition.`)},[`from`,`to`,`disclosure`],`Present when an in-place system surface (web sign-in or Apple Pay sheet) was presented over the app, or left it.`),j=w({foregroundApp:m(`Foreground app bundle id or name, when the capture carries it.`),nodeCount:b(`Node count in the post-action interactive-only capture.`),interactiveNodeCount:b(`Subset of nodeCount the platform reports as hittable.`),digest:m(`Order-independent digest of the post-action node multiset.`),changedFromBefore:g(`Whether the post-action digest differs from the pre-action capture digest. false is evidence, not failure. With surfaceChange present, no digest comparison is made: it reports that surface transition.`),surfaceChange:A},[`nodeCount`,`interactiveNodeCount`,`digest`,`changedFromBefore`]),Se=w({settled:g(`Whether the UI held the quiet window before the deadline. false is advisory, not failure.`),waitedMs:b(),captures:b(),quietMs:b(),timeoutMs:b(),refsGeneration:b(`Snapshot generation of the stored settled tree; refs on added diff lines were minted from it.`),refs:{type:`array`,items:w({ref:m(`Plain ref body (e12) minted from the stored settled tree.`)},[`ref`])},surfaceChange:A,diff:w({summary:w({additions:b(),removals:b(),unchanged:b()},[`additions`,`removals`,`unchanged`]),lines:{type:`array`,items:w({kind:x([`added`,`removed`]),text:m(),ref:m(`Plain ref body (e12) for added lines.`)},[`kind`,`text`])},truncated:g(`Lines were capped to the response bound.`)},[`summary`,`lines`],`Settled diff vs the pre-action tree (changed lines only).`),tail:{type:`array`,description:`Unchanged interactive refs tail: still-present, actionable elements from the settled tree, attached only when diff carries zero added-line refs (a modal-dismiss/toast-only diff).`,items:w({ref:m(`Plain ref body (e12) minted from the stored settled tree.`),role:m(),label:m()},[`ref`,`role`])},tailTruncated:g(`Present (true) when tail candidates exceeded the response cap.`),hint:m()},[`settled`,`waitedMs`,`captures`,`quietMs`,`timeoutMs`]),M={platform:x(s),target:x(c),device:m(`Human-readable device name.`),id:m(`Stable device id.`),kind:x(y)},N=[`platform`,`target`,`device`,`id`,`kind`],Ce=w({success:g(),exitCode:b(),stdout:m(),stderr:m(),error:h(`Normalized error detail when shutdown failed.`)},[`success`,`exitCode`,`stdout`,`stderr`]);function P(e){return e.oneOf?{...e,oneOf:e.oneOf.map(P)}:{...e,properties:{...e.properties??{},settle:Se}}}function we(e){let t={...e};for(let e of Object.keys(t))f(e)&&(t[e]=P(t[e]));return t}const F=O({properties:{evidence:j,button:x([`secondary`,`middle`]),count:b(`Number of press/click repetitions.`),intervalMs:b(`Delay between repeated press/click actions.`),holdMs:b(`Hold duration for each action.`),jitterPx:b(`Randomization radius in pixels.`),doubleTap:g(`Whether the command requested a double-tap action.`)}}),I={text:m(`Text submitted to the field.`),delayMs:b(`Delay between typed characters in milliseconds.`),evidence:j},Te=w({resourceId:C(`Android resource id of the exact field that changed.`),className:C(`Android class name of the exact field that changed.`),packageName:C(`Android package name that owns the exact field.`),rect:w({x:b(),y:b(),width:b(),height:b()},[`x`,`y`,`width`,`height`],`Screen-space rectangle of the exact field that changed.`)},[`resourceId`,`className`,`packageName`,`rect`],`Target identity captured before fill and matched after fill.`),Ee=we({press:F,click:F,fill:{type:`object`,description:`Fill response. Android may return target-bound unconfirmed evidence when the exact app-owned field changed but formatting prevented raw equality.`,oneOf:[{...O({properties:I,required:[`text`]}),not:w({},[`verification`])},O({properties:{...I,verification:S(`unconfirmed`),requested:m(`Literal text requested by the fill command.`),before:C(`Raw target text captured before the fill.`),after:C(`Raw target text captured after the fill.`),target:Te},required:[`text`,`verification`,`requested`,`before`,`after`,`target`]})]},longpress:O({properties:{durationMs:b(),gesture:S(`longpress`)}}),hover:O({properties:{gesture:S(`hover`)}}),find:w({ref:m(`Snapshot ref without the @ prefix when the find action returns one.`),refsGeneration:b(`ADR 0014 ref frame epoch for read-only find actions.`),found:g(`Whether a wait/exists/read-only find satisfied its condition.`),waitedMs:b(`Milliseconds waited for a read-only find condition.`),text:m(`Text value returned by find get_text.`),node:h(`Snapshot node for find get_attrs/get_text.`),matches:{type:`array`,description:`Every match for the read-only find list action (#1625): { ref, node } each.`,items:h(`One listed match with its snapshot ref and node.`)},locator:m(`Locator kind used for the find action.`),query:m(`Query argument used for the find action.`),x:b(`Resolved x coordinate for mutating find actions.`),y:b(`Resolved y coordinate for mutating find actions.`),message:m(`Diagnostic message for mutating find actions.`),cost:E},[],`Daemon response data for the find command.`),boot:w({...M,booted:{type:`boolean`,const:!0}},[...N,`booted`]),shutdown:w({...M,shutdown:Ce},[...N,`shutdown`]),viewport:w({width:b(),height:b(),message:m()},[`width`,`height`,`message`]),back:w({action:S(`back`),mode:x(te),message:m()},[`action`,`mode`,`message`]),home:w({action:S(`home`),message:m()},[`action`,`message`]),orientation:w({action:S(`orientation`),orientation:x(ce),message:m(),confirmed:g(),warning:m()},[`action`,`orientation`,`message`]),"app-switcher":w({action:S(`app-switcher`),message:m()},[`action`,`message`]),"tv-remote":w({action:S(`tv-remote`),button:x(le),durationMs:b(),message:m()},[`action`,`button`,`message`]),wait:w({waitedMs:b(),kind:S(`selector`),text:m(),selector:m(),captures:b(),nodeCount:b(),hint:m(),warning:m()},[`waitedMs`]),scroll:w({direction:x([`up`,`down`,`left`,`right`]),edge:x([`top`,`bottom`]),until:m(`Until scrolls only: the selector the passes stopped on.`),passes:b(`Edge and until scrolls only: how many scroll-and-check passes ran.`),amount:b(),pixels:b(),durationMs:b(),message:m(),keyboardAvoided:g(`Present only when an on-screen keyboard forced the swipe into the band above it; the reported pixels were planned against the shorter referenceHeight.`),keyboardMinY:b(`Where the keyboard began, in the same unit as the gesture coordinates. Clipped scrolls only.`)},[`direction`]),prepare:w({action:S(`ios-runner`),platform:x(s),deviceId:m(),deviceName:m(),kind:x(y),durationMs:b(),runner:w({},[]),cache:x([`exact`,`restore-key`,`miss`,`external`]),artifact:x([`valid`,`rebuilt`]),buildMs:b(),connectMs:b(),healthCheckMs:b(),xctestrunPath:m(),recoveryReason:m(),failureReason:m(),timing:w({totalMs:b(),additiveParts:w({buildMs:b(),connectAfterBuildMs:b(),healthCheckMs:b()},[`connectAfterBuildMs`,`healthCheckMs`]),containment:w({connectMs:{type:`array`,items:S(`buildMs`)},healthCheckMs:{type:`array`,items:m()}},[`healthCheckMs`]),note:m()},[`totalMs`,`additiveParts`,`containment`,`note`]),message:m()},[`action`,`platform`,`deviceId`,`deviceName`,`kind`,`durationMs`,`runner`,`connectMs`,`healthCheckMs`,`timing`,`message`]),push:{type:`object`,oneOf:[w({platform:S(`ios`),bundleId:m(),message:m()},[`platform`,`bundleId`,`message`]),w({platform:S(`android`),package:m(),action:m(),extrasCount:b(),message:m()},[`platform`,`package`,`action`,`extrasCount`,`message`])]},"trigger-app-event":w({event:m(),eventUrl:m(),transport:S(`deep-link`),message:m()},[`event`,`eventUrl`,`transport`,`message`]),clipboard:{type:`object`,oneOf:[w({action:S(`read`),text:m()},[`action`,`text`]),w({action:S(`write`),textLength:b(),message:m()},[`action`,`textLength`,`message`])]},appstate:{type:`object`,oneOf:[w({platform:x([`ios`,`macos`]),appName:m(),appBundleId:m(),source:S(`session`),surface:x(ne),device_udid:m(`iOS only — the session device UDID.`),ios_simulator_device_set:{type:[`string`,`null`],description:`iOS only — the simulator set path, or null when unknown.`}},[`platform`,`appName`,`source`,`surface`]),w({platform:S(`android`),package:m(),activity:m()},[`platform`,`package`,`activity`])]},keyboard:w({platform:x([`android`,`ios`]),action:x([`status`,`dismiss`,`enter`]),visible:g(),wasVisible:g(),dismissed:g(),attempts:b(),inputType:m(),type:x([`text`,`number`,`email`,`phone`,`password`,`datetime`,`unknown`]),inputMethodPackage:m(),focusedPackage:m(),focusedResourceId:m(),inputOwner:x([`app`,`ime`,`unknown`]),message:m()},[`platform`,`action`]),doctor:w({status:x([`pass`,`warn`,`fail`,`info`]),summary:m(),kind:x([`auto`,`react-native`,`expo`,`repack`]),platform:m(),target:x(c),targetApp:m(),metro:w({host:m(),port:b()},[`host`,`port`]),checks:{type:`array`,items:w({id:m(),status:x([`pass`,`warn`,`fail`,`info`]),summary:m(),hint:m(),command:m(),evidence:h()},[`id`,`status`,`summary`])}},[`status`,`summary`,`kind`,`checks`]),diff:w({mode:S(`snapshot`),baselineInitialized:g(),summary:w({additions:b(),removals:b(),unchanged:b()},[`additions`,`removals`,`unchanged`]),lines:{type:`array`,items:w({kind:x([`added`,`removed`]),text:m(),ref:m()},[`kind`,`text`])},warnings:T},[`mode`,`baselineInitialized`,`summary`,`lines`]),replay:w({replayed:b(),healed:b(),session:m(),sessionActive:g(`True iff the session is still active — the script had no terminal close.`),artifactPaths:T,snapshotDiagnostics:h(),message:m()},[`replayed`,`healed`,`session`,`sessionActive`,`artifactPaths`,`message`]),test:w({total:b(),executed:b(),passed:b(),failed:b(),skipped:b(),notRun:b(),durationMs:b(),failures:{type:`array`,items:h()},tests:{type:`array`,items:h()},snapshotDiagnostics:h()},[`total`,`executed`,`passed`,`failed`,`skipped`,`notRun`,`durationMs`,`failures`,`tests`]),record:{type:`object`,oneOf:[w({recording:S(`started`),outPath:m(),sessionStateDir:m(),recordingBackend:m(),recordingScope:m(),recordOnlySession:g(),activeSessionApp:h(),showTouches:g()},[`recording`,`outPath`,`sessionStateDir`,`showTouches`]),w({recording:S(`stopped`),outPath:m(),telemetryPath:m(),artifacts:{type:`array`,items:D},recordingBackend:m(),recordingScope:m(),recordOnlySession:g(),activeSessionApp:h(),durationMs:b(),capturedDurationMs:b(),recorder:x(he,`What the recorder was observed doing when the recording was stopped: confirmed, or lost when the session holding it died. ADR 0024 reserves unconfirmed for the step that gains the probe.`),nativePathDisposition:x(me,`What became of the artifact path the recorder writes to: retirable while it still owes a removal, retired once that removal was verified. ADR 0024 reserves pending.`),showTouches:g(),warning:m(),overlayWarning:m(),chunks:{type:`array`,items:h()}},[`recording`,`outPath`,`artifacts`,`durationMs`,`showTouches`])]},trace:{type:`object`,oneOf:[w({trace:S(`started`),outPath:m()},[`trace`,`outPath`]),w({trace:S(`stopped`),outPath:m(),artifacts:{type:`array`,items:D}},[`trace`,`outPath`,`artifacts`])]}}),De={devices:{type:`object`,properties:{devices:{type:`array`,items:{type:`object`,properties:{platform:{type:`string`,enum:s},target:{type:`string`,enum:c},kind:{type:`string`,enum:y},id:{type:`string`},name:{type:`string`}},required:[`platform`,`target`,`kind`,`id`,`name`]}}},required:[`devices`]},apps:{type:`object`,properties:{apps:{type:`array`,items:{type:`string`}}},required:[`apps`]}},L={...Ee,...De},Oe={stateDir:{schema:{type:`string`,description:`Agent-device state directory.`},audience:p({operatorConfig:!0})},mcpOutputFormat:{schema:{type:`string`,enum:[`optimized`,`json`],description:`MCP text content format. Defaults to optimized agent-friendly text; use json for JSON text. Structured content is always returned separately.`}},includeCost:{schema:{type:`boolean`,description:`Include per-command agent-cost (cost.wallClockMs, …) in structuredContent. Defaults to off; the default response shape is unchanged.`}},responseLevel:{schema:{type:`string`,enum:[`digest`,`default`,`full`],description:`Response verbosity: token-cheap digest / default (today) / full. Defaults to default; the default response shape is unchanged.`}}},R=Object.entries(Oe),z=new Set(R.map(([e])=>e)),ke=Object.fromEntries(R.flatMap(([e,t])=>t.audience?[[e,t.audience]]:[]));function Ae(){return Object.fromEntries(R.map(([e,t])=>[e,t.schema]))}function B(e){return r(e)}function V(e){let t=[`Error (${e.code}): ${e.message}`];if(e.cause){let n=e.cause.code?`${e.cause.code} `:``;t.push(`Cause: ${n}${e.cause.message}`)}e.hint&&t.push(`Hint: ${e.hint}`);for(let n of oe(e.details))t.push(`Warning: ${se(n)}`);t.push(...ge(n(e.details))),e.supportedOn&&t.push(`Supported on: ${e.supportedOn}`);let r=fe(e.details);return r&&t.push(r),t.join(`
|
|
2
|
-
`)}function
|
|
1
|
+
import{B as e,D as t,L as n,r,z as i}from"./sdk-contracts.js";import{g as a,m as o}from"./sdk-batch-runner.js";import{i as s,t as c}from"./sdk-device.js";import{S as l,c as u,d,p as f,w as ee}from"./sdk-batch.js";import{t as te}from"./back-mode.js";import{t as ne}from"./session.js";import{C as re,S as p,_ as m,b as ie,g as h,h as g,y as ae}from"./registry.js";import{n as oe}from"./success-text.js";import{t as se}from"./output-common.js";import"./device.js";import{t as ce}from"./device-rotation.js";import{t as le}from"./tv-remote.js";import{i as ue,n as _,r as de,t as v}from"./command-metadata.js";import{r as fe}from"./replay-divergence.js";import{n as pe,t as me}from"./cli-output.js";import{r as he,t as ge}from"./recording-stop-observation.js";import{n as _e}from"./error.js";import{n as ve,r as ye,t as be}from"./cli-config.js";import{n as xe}from"./result-serialization.js";const y=[`simulator`,`emulator`,`device`];function b(e){return{type:`number`,...e?{description:e}:{}}}function x(e,t){return{type:`string`,enum:e,...t?{description:t}:{}}}function S(e){return{type:`string`,const:e}}function C(e){return{type:[`string`,`null`],...e?{description:e}:{}}}function w(e,t=[],n){return{type:`object`,...n?{description:n}:{},properties:e,...t.length>0?{required:t}:{}}}const T={type:`array`,items:{type:`string`}},E=w({wallClockMs:b(`Total wall-clock time for the request in milliseconds.`),runnerRoundTrips:b(`Number of real runner round-trips made while serving the request.`),nodeCount:b(`Number of nodes in the original node tree when the response carries one.`)},[`wallClockMs`,`runnerRoundTrips`]),D=w({field:m(),artifactType:m(),path:m(),localPath:m(),fileName:m()},[`field`]);function O(e={}){let t=e.properties??{},n=e.required??[];return w({targetKind:x([`point`,`ref`,`selector`],`Resolved interaction target kind.`),x:b(`Resolved interaction x coordinate when available.`),y:b(`Resolved interaction y coordinate when available.`),referenceWidth:b(`Reference frame width for visualizing the interaction point.`),referenceHeight:b(`Reference frame height for visualizing the interaction point.`),ref:m(`Snapshot ref without the @ prefix when the target was an @ref.`),selector:m(`Selector expression when the target was a selector.`),selectorChain:T,refLabel:m(),targetHittable:g(),hint:m(),warning:m(),message:m(),evidence:j,resolution:Se,cost:E,maestroNonHittableCoordinateFallbackAllowed:g(`Whether the direct iOS Maestro coordinate fallback was allowed for this selector.`),maestroNonHittableCoordinateFallbackUsed:g(`Whether the direct iOS Maestro coordinate fallback was actually used.`),maestroFallbackReason:S(`non-hittable-coordinate`),...t},[`targetKind`,...n])}const k=w({diagnosticRef:m(`Opaque non-@ diagnostic token. Never a snapshot ref: not issued via refsGeneration and cannot be pinned or reused as an @ref target. UTF-8 truncated to 256 bytes.`),role:m(`UTF-8 truncated to 256 bytes.`),label:m(`UTF-8 truncated to 256 bytes.`)},[`diagnosticRef`]),Se={type:`object`,description:`Pre-action disclosure of how the acting path resolved its target. Absent when resolutionDisclosure is inapplicable for the path.`,oneOf:[w({source:S(`runtime`),phase:S(`pre-action`),kind:S(`unique`)},[`source`,`phase`,`kind`]),w({source:S(`runtime`),phase:S(`pre-action`),kind:S(`disambiguated`),matchCount:b(`Total matches resolveSelectorChain found before disambiguation.`),winnerDiagnostic:k,tiebreak:x([`visible`,`deepest`,`smallest-area`,`structural-equivalence`],`The comparison that decided the winner.`),alternatives:{type:`array`,description:`At most 5 losing candidates, document order. Present at default/full response levels and omitted in digest. The winner is never included.`,items:k}},[`source`,`phase`,`kind`,`matchCount`,`winnerDiagnostic`,`tiebreak`]),w({source:S(`ref`),phase:S(`pre-action`),kind:S(`exact`)},[`source`,`phase`,`kind`]),w({source:S(`ref`),phase:S(`pre-action`),kind:S(`label-fallback`)},[`source`,`phase`,`kind`]),w({source:S(`direct-ios`),kind:S(`not-observed`)},[`source`,`kind`])]},A=w({from:m(`Surface the pre-action baseline described: a host bundle id, or app.`),to:m(`Surface the post-action capture describes: a host bundle id, or app.`),disclosure:m(`Agent-facing sentence explaining the surface transition.`)},[`from`,`to`,`disclosure`],`Present when an in-place system surface (web sign-in or Apple Pay sheet) was presented over the app, or left it.`),j=w({foregroundApp:m(`Foreground app bundle id or name, when the capture carries it.`),nodeCount:b(`Node count in the post-action interactive-only capture.`),interactiveNodeCount:b(`Subset of nodeCount the platform reports as hittable.`),digest:m(`Order-independent digest of the post-action node multiset.`),changedFromBefore:g(`Whether the post-action digest differs from the pre-action capture digest. false is evidence, not failure. With surfaceChange present, no digest comparison is made: it reports that surface transition.`),surfaceChange:A},[`nodeCount`,`interactiveNodeCount`,`digest`,`changedFromBefore`]),Ce=w({settled:g(`Whether the UI held the quiet window before the deadline. false is advisory, not failure.`),waitedMs:b(),captures:b(),quietMs:b(),timeoutMs:b(),refsGeneration:b(`Snapshot generation of the stored settled tree; refs on added diff lines were minted from it.`),refs:{type:`array`,items:w({ref:m(`Plain ref body (e12) minted from the stored settled tree.`)},[`ref`])},surfaceChange:A,diff:w({summary:w({additions:b(),removals:b(),unchanged:b()},[`additions`,`removals`,`unchanged`]),lines:{type:`array`,items:w({kind:x([`added`,`removed`]),text:m(),ref:m(`Plain ref body (e12) for added lines.`)},[`kind`,`text`])},truncated:g(`Lines were capped to the response bound.`)},[`summary`,`lines`],`Settled diff vs the pre-action tree (changed lines only).`),tail:{type:`array`,description:`Unchanged interactive refs tail: still-present, actionable elements from the settled tree, attached only when diff carries zero added-line refs (a modal-dismiss/toast-only diff).`,items:w({ref:m(`Plain ref body (e12) minted from the stored settled tree.`),role:m(),label:m()},[`ref`,`role`])},tailTruncated:g(`Present (true) when tail candidates exceeded the response cap.`),hint:m()},[`settled`,`waitedMs`,`captures`,`quietMs`,`timeoutMs`]),M={platform:x(s),target:x(c),device:m(`Human-readable device name.`),id:m(`Stable device id.`),kind:x(y)},N=[`platform`,`target`,`device`,`id`,`kind`],we=w({success:g(),exitCode:b(),stdout:m(),stderr:m(),error:h(`Normalized error detail when shutdown failed.`)},[`success`,`exitCode`,`stdout`,`stderr`]);function P(e){return e.oneOf?{...e,oneOf:e.oneOf.map(P)}:{...e,properties:{...e.properties??{},settle:Ce}}}function Te(e){let t={...e};for(let e of Object.keys(t))f(e)&&(t[e]=P(t[e]));return t}const F=O({properties:{evidence:j,button:x([`secondary`,`middle`]),count:b(`Number of press/click repetitions.`),intervalMs:b(`Delay between repeated press/click actions.`),holdMs:b(`Hold duration for each action.`),jitterPx:b(`Randomization radius in pixels.`),doubleTap:g(`Whether the command requested a double-tap action.`)}}),I={text:m(`Text submitted to the field.`),delayMs:b(`Delay between typed characters in milliseconds.`),evidence:j},Ee=w({resourceId:C(`Android resource id of the exact field that changed.`),className:C(`Android class name of the exact field that changed.`),packageName:C(`Android package name that owns the exact field.`),rect:w({x:b(),y:b(),width:b(),height:b()},[`x`,`y`,`width`,`height`],`Screen-space rectangle of the exact field that changed.`)},[`resourceId`,`className`,`packageName`,`rect`],`Target identity captured before fill and matched after fill.`),De=Te({press:F,click:F,fill:{type:`object`,description:`Fill response. Android may return target-bound unconfirmed evidence when the exact app-owned field changed but formatting prevented raw equality.`,oneOf:[{...O({properties:I,required:[`text`]}),not:w({},[`verification`])},O({properties:{...I,verification:S(`unconfirmed`),requested:m(`Literal text requested by the fill command.`),before:C(`Raw target text captured before the fill.`),after:C(`Raw target text captured after the fill.`),target:Ee},required:[`text`,`verification`,`requested`,`before`,`after`,`target`]})]},longpress:O({properties:{durationMs:b(),gesture:S(`longpress`)}}),hover:O({properties:{gesture:S(`hover`)}}),find:w({ref:m(`Snapshot ref without the @ prefix when the find action returns one.`),refsGeneration:b(`ADR 0014 ref frame epoch for read-only find actions.`),found:g(`Whether a wait/exists/read-only find satisfied its condition.`),waitedMs:b(`Milliseconds waited for a read-only find condition.`),text:m(`Text value returned by find get_text.`),node:h(`Snapshot node for find get_attrs/get_text.`),matches:{type:`array`,description:`Every match for the read-only find list action (#1625): { ref, node } each.`,items:h(`One listed match with its snapshot ref and node.`)},locator:m(`Locator kind used for the find action.`),query:m(`Query argument used for the find action.`),x:b(`Resolved x coordinate for mutating find actions.`),y:b(`Resolved y coordinate for mutating find actions.`),message:m(`Diagnostic message for mutating find actions.`),cost:E},[],`Daemon response data for the find command.`),boot:w({...M,booted:{type:`boolean`,const:!0}},[...N,`booted`]),shutdown:w({...M,shutdown:we},[...N,`shutdown`]),viewport:w({width:b(),height:b(),message:m()},[`width`,`height`,`message`]),back:w({action:S(`back`),mode:x(te),message:m()},[`action`,`mode`,`message`]),home:w({action:S(`home`),message:m()},[`action`,`message`]),orientation:w({action:S(`orientation`),orientation:x(ce),message:m(),confirmed:g(),warning:m()},[`action`,`orientation`,`message`]),"app-switcher":w({action:S(`app-switcher`),message:m()},[`action`,`message`]),"action-button":w({action:S(`action-button`),message:m()},[`action`,`message`]),"tv-remote":w({action:S(`tv-remote`),button:x(le),durationMs:b(),message:m()},[`action`,`button`,`message`]),wait:w({waitedMs:b(),kind:S(`selector`),text:m(),selector:m(),captures:b(),nodeCount:b(),hint:m(),warning:m()},[`waitedMs`]),scroll:w({direction:x([`up`,`down`,`left`,`right`]),edge:x([`top`,`bottom`]),until:m(`Until scrolls only: the selector the passes stopped on.`),passes:b(`Edge and until scrolls only: how many scroll-and-check passes ran.`),amount:b(),pixels:b(),durationMs:b(),message:m(),keyboardAvoided:g(`Present only when an on-screen keyboard forced the swipe into the band above it; the reported pixels were planned against the shorter referenceHeight.`),keyboardMinY:b(`Where the keyboard began, in the same unit as the gesture coordinates. Clipped scrolls only.`)},[`direction`]),prepare:w({action:S(`ios-runner`),platform:x(s),deviceId:m(),deviceName:m(),kind:x(y),durationMs:b(),runner:w({},[]),cache:x([`exact`,`restore-key`,`miss`,`external`]),artifact:x([`valid`,`rebuilt`]),buildMs:b(),connectMs:b(),healthCheckMs:b(),xctestrunPath:m(),recoveryReason:m(),failureReason:m(),timing:w({totalMs:b(),additiveParts:w({buildMs:b(),connectAfterBuildMs:b(),healthCheckMs:b()},[`connectAfterBuildMs`,`healthCheckMs`]),containment:w({connectMs:{type:`array`,items:S(`buildMs`)},healthCheckMs:{type:`array`,items:m()}},[`healthCheckMs`]),note:m()},[`totalMs`,`additiveParts`,`containment`,`note`]),message:m()},[`action`,`platform`,`deviceId`,`deviceName`,`kind`,`durationMs`,`runner`,`connectMs`,`healthCheckMs`,`timing`,`message`]),push:{type:`object`,oneOf:[w({platform:S(`ios`),bundleId:m(),message:m()},[`platform`,`bundleId`,`message`]),w({platform:S(`android`),package:m(),action:m(),extrasCount:b(),message:m()},[`platform`,`package`,`action`,`extrasCount`,`message`])]},"trigger-app-event":w({event:m(),eventUrl:m(),transport:S(`deep-link`),message:m()},[`event`,`eventUrl`,`transport`,`message`]),clipboard:{type:`object`,oneOf:[w({action:S(`read`),text:m()},[`action`,`text`]),w({action:S(`write`),textLength:b(),message:m()},[`action`,`textLength`,`message`])]},appstate:{type:`object`,oneOf:[w({platform:x([`ios`,`macos`]),appName:m(),appBundleId:m(),source:S(`session`),surface:x(ne),device_udid:m(`iOS only — the session device UDID.`),ios_simulator_device_set:{type:[`string`,`null`],description:`iOS only — the simulator set path, or null when unknown.`}},[`platform`,`appName`,`source`,`surface`]),w({platform:S(`android`),package:m(),activity:m()},[`platform`,`package`,`activity`])]},keyboard:w({platform:x([`android`,`ios`]),action:x([`status`,`dismiss`,`enter`]),visible:g(),wasVisible:g(),dismissed:g(),attempts:b(),inputType:m(),type:x([`text`,`number`,`email`,`phone`,`password`,`datetime`,`unknown`]),inputMethodPackage:m(),focusedPackage:m(),focusedResourceId:m(),inputOwner:x([`app`,`ime`,`unknown`]),message:m()},[`platform`,`action`]),doctor:w({status:x([`pass`,`warn`,`fail`,`info`]),summary:m(),kind:x([`auto`,`react-native`,`expo`,`repack`]),platform:m(),target:x(c),targetApp:m(),metro:w({host:m(),port:b()},[`host`,`port`]),checks:{type:`array`,items:w({id:m(),status:x([`pass`,`warn`,`fail`,`info`]),summary:m(),hint:m(),command:m(),evidence:h()},[`id`,`status`,`summary`])}},[`status`,`summary`,`kind`,`checks`]),diff:w({mode:S(`snapshot`),baselineInitialized:g(),summary:w({additions:b(),removals:b(),unchanged:b()},[`additions`,`removals`,`unchanged`]),lines:{type:`array`,items:w({kind:x([`added`,`removed`]),text:m(),ref:m()},[`kind`,`text`])},warnings:T},[`mode`,`baselineInitialized`,`summary`,`lines`]),replay:w({replayed:b(),healed:b(),session:m(),sessionActive:g(`True iff the session is still active — the script had no terminal close.`),artifactPaths:T,snapshotDiagnostics:h(),message:m()},[`replayed`,`healed`,`session`,`sessionActive`,`artifactPaths`,`message`]),test:w({total:b(),executed:b(),passed:b(),failed:b(),skipped:b(),notRun:b(),durationMs:b(),failures:{type:`array`,items:h()},tests:{type:`array`,items:h()},snapshotDiagnostics:h()},[`total`,`executed`,`passed`,`failed`,`skipped`,`notRun`,`durationMs`,`failures`,`tests`]),record:{type:`object`,oneOf:[w({recording:S(`started`),outPath:m(),sessionStateDir:m(),recordingBackend:m(),recordingScope:m(),recordOnlySession:g(),activeSessionApp:h(),showTouches:g()},[`recording`,`outPath`,`sessionStateDir`,`showTouches`]),w({recording:S(`stopped`),outPath:m(),telemetryPath:m(),artifacts:{type:`array`,items:D},recordingBackend:m(),recordingScope:m(),recordOnlySession:g(),activeSessionApp:h(),durationMs:b(),capturedDurationMs:b(),recorder:x(ge,`What the recorder was observed doing when the recording was stopped: confirmed, or lost when the session holding it died. ADR 0024 reserves unconfirmed for the step that gains the probe.`),nativePathDisposition:x(he,`What became of the artifact path the recorder writes to: retirable while it still owes a removal, retired once that removal was verified. ADR 0024 reserves pending.`),showTouches:g(),warning:m(),overlayWarning:m(),chunks:{type:`array`,items:h()}},[`recording`,`outPath`,`artifacts`,`durationMs`,`showTouches`])]},trace:{type:`object`,oneOf:[w({trace:S(`started`),outPath:m()},[`trace`,`outPath`]),w({trace:S(`stopped`),outPath:m(),artifacts:{type:`array`,items:D}},[`trace`,`outPath`,`artifacts`])]}}),Oe={devices:{type:`object`,properties:{devices:{type:`array`,items:{type:`object`,properties:{platform:{type:`string`,enum:s},target:{type:`string`,enum:c},kind:{type:`string`,enum:y},id:{type:`string`},name:{type:`string`}},required:[`platform`,`target`,`kind`,`id`,`name`]}}},required:[`devices`]},apps:{type:`object`,properties:{apps:{type:`array`,items:{type:`string`}}},required:[`apps`]}},L={...De,...Oe},ke={stateDir:{schema:{type:`string`,description:`Agent-device state directory.`},audience:p({operatorConfig:!0})},mcpOutputFormat:{schema:{type:`string`,enum:[`optimized`,`json`],description:`MCP text content format. Defaults to optimized agent-friendly text; use json for JSON text. Structured content is always returned separately.`}},includeCost:{schema:{type:`boolean`,description:`Include per-command agent-cost (cost.wallClockMs, …) in structuredContent. Defaults to off; the default response shape is unchanged.`}},responseLevel:{schema:{type:`string`,enum:[`digest`,`default`,`full`],description:`Response verbosity: token-cheap digest / default (today) / full. Defaults to default; the default response shape is unchanged.`}}},R=Object.entries(ke),z=new Set(R.map(([e])=>e)),Ae=Object.fromEntries(R.flatMap(([e,t])=>t.audience?[[e,t.audience]]:[]));function je(){return Object.fromEntries(R.map(([e,t])=>[e,t.schema]))}function B(e){return n(e)}function V(t){let n=[`Error (${t.code}): ${t.message}`];if(t.cause){let e=t.cause.code?`${t.cause.code} `:``;n.push(`Cause: ${e}${t.cause.message}`)}t.hint&&n.push(`Hint: ${t.hint}`);for(let e of oe(t.details))n.push(`Warning: ${se(e)}`);n.push(..._e(e(t.details))),t.supportedOn&&n.push(`Supported on: ${t.supportedOn}`);let r=fe(t.details);return r&&n.push(r),n.join(`
|
|
2
|
+
`)}function Me(e,t,n){let r=be({command:e,cwd:process.cwd(),cliFlags:t}),i={};for(let[t,a]of Object.entries(r))Object.hasOwn(n,t)&&ye(t,e)&&(i[t]=a);return ve(i,t)}const Ne={devices:async e=>({devices:e.map(xe)}),apps:async e=>({apps:e})};async function Pe(e,t){let n=Ne[e];return n?await n(t):t}function Fe(){let e=new Map;return{pinInput:(t,n,r)=>Ye(t,n,Be(e,r,n.session)),mergeCommandResult:(t,n,r,i)=>Ve(e,t,n,r,i),mergeErrorDetails:(t,n,r)=>{let i=H(n,r);Ie(e,i,t),qe(e,i,t)}}}function Ie(e,t,n){let r=n?.refsGeneration;typeof r==`number`&&U(e,t,i(n),r)}const Le=new Set([`snapshot`,`find`]),Re=new Set(d.map(e=>e.name).filter(_).filter(e=>f(e))),ze=new Set([`press`,`click`,`fill`,`longpress`,`hover`,`get`]);function Be(e,t,n){return e.get(H(t,n))}function H(e,t){let n=typeof t==`string`&&t.length>0?t:`default`;return`${e??``}\u0000${n}`}function Ve(e,t,n,r,i){let a=H(r,i);if(Re.has(t)){We(e,a,Ge(n));return}Le.has(t)&&(t===`find`?Ue(e,a,n):He(e,a,n))}function He(e,t,n){let r=n.refsGeneration;if(typeof r!=`number`){e.delete(t);return}let i=[];for(let{ref:e}of n.refs??[])i.push(e);for(let e of n.nodes??[])i.push(e.ref);U(e,t,i,r)}function Ue(e,t,n){let r=n.refsGeneration;if(typeof r!=`number`)return;let i=[];typeof n.ref==`string`&&n.ref.startsWith(`@`)&&i.push(n.ref.slice(1));for(let e of n.matches??[])typeof e.ref==`string`&&e.ref.length>0&&i.push(e.ref.startsWith(`@`)?e.ref.slice(1):e.ref);U(e,t,i,r)}function We(e,t,n){n?.refsGeneration!==void 0&&U(e,t,[...n.diff?.lines??[],...n.refs??[],...n.tail??[]].map(e=>e.ref).filter(e=>typeof e==`string`),n.refsGeneration)}function Ge(e){let t=e.settle;return typeof t==`object`&&t?t:void 0}function U(e,t,n,r){if(n.length===0)return;let i=e.get(t)??new Map;e.set(t,i),Ke(i,n,r)}function Ke(e,t,n){for(let r of t)e.delete(r),e.set(r,n);for(;e.size>1e3;)e.delete(e.keys().next().value)}function qe(e,t,n){let r=o(n?.divergence),i=o(r?.screen);if(i?.state!==`available`)return;let a=i.refsGeneration;if(typeof a!=`number`)return;let s=[];Je(i.refs,s),U(e,t,s,a)}function Je(e,t){if(Array.isArray(e))for(let n of e){let e=o(n)?.ref;typeof e==`string`&&e.length>0&&t.push(e)}}function Ye(e,t,n){return n===void 0||n.size===0?t:e===`wait`?Xe(t,n)??t:ze.has(e)?Ze(t,n)??t:t}function Xe(e,t){if(typeof e.ref!=`string`)return;let n=W(e.ref,t);return n===e.ref?void 0:{...e,ref:n}}function Ze(e,t){let n=o(e.target);if(n?.kind!==`ref`||typeof n.ref!=`string`)return;let r=W(n.ref,t);return r===n.ref?void 0:{...e,target:{...n,ref:r}}}function W(e,t){if(!e.startsWith(`@`)||e.includes(`~`))return e;let n=t.get(e.slice(1));return n===void 0?e:`${e}~s${n}`}const Qe={config:p({operatorPath:`Point the process serving these tools at a config file with the AGENT_DEVICE_CONFIG environment variable.`}),remoteConfig:p({operatorPath:`Configure the remote profile on the process serving these tools, not per tool call.`})},$e=Object.fromEntries(de().flatMap(e=>Object.entries(e.inputAudience).filter(([,e])=>e.kind===`operator`)));function G(e){return{...e.inputAudience,...ie,...Ae,...Qe,...$e}}function et(){return ue().map(e=>{let t=e.name in L?L[e.name]:void 0,n=J(e.name,e);return{name:e.name,description:ut(e.name,ae(e)),inputSchema:n,...t?{outputSchema:t}:{}}})}function K(e={}){let n=Fe();return{execute:async(r,i)=>{if(!_(r))throw new t(`INVALID_ARGS`,`Unknown command tool: ${r}`);let a=v(r),o=Y(r,a,i)??X(a.inputSchema,i,r);if(o)return await q(new t(`INVALID_ARGS`,o),n,void 0,i.session);let s=Q(r,a.inputSchema).properties,c=Me(r,i,s),l=it(c),u=ct(c),d=n.pinInput(r,u,l.client.stateDir),f=await nt(e,l.client);try{let t=await(e.runCommand??rt)(f,r,d);return n.mergeCommandResult(r,t,l.client.stateDir,u.session),{isError:!1,structuredContent:await Pe(r,t),content:[{type:`text`,text:await dt({name:r,input:u,result:t,outputFormat:l.outputFormat,responseLevel:l.client.responseLevel})}]}}catch(e){return await q(e,n,l.client.stateDir,u.session)}}}}async function q(e,t,n,r){let i=B(e);return t.mergeErrorDetails(i.details,n,r),{isError:!0,structuredContent:i,content:[{type:`text`,text:V(i)}]}}const tt=K();async function nt(e,t){if(e.createClient)return await e.createClient(t);let{createAgentDeviceClient:n}=await import(`./agent-device-client.js`).then(e=>e.t);return n(t)}async function rt(e,t,n){return await(await import(`./command-surface.js`).then(e=>e.t)).runCommand(e,t,n)}function it(e){return{client:at(e),outputFormat:st(e.mcpOutputFormat)}}function at(e){let n=e.stateDir,r=e.includeCost,i=e.responseLevel,a={};if(n!==void 0){if(typeof n!=`string`||n.length===0)throw new t(`INVALID_ARGS`,`Expected stateDir to be a non-empty string.`);a.stateDir=n}if(r!==void 0){if(typeof r!=`boolean`)throw new t(`INVALID_ARGS`,`Expected includeCost to be a boolean.`);r&&(a.cost=!0)}let o=ot(i);return o!==void 0&&(a.responseLevel=o),a}function ot(e){if(e===void 0)return;let n=r.find(t=>t===e);if(n===void 0)throw new t(`INVALID_ARGS`,`Expected responseLevel to be one of 'digest', 'default', or 'full'.`);return n}function st(e){if(e===void 0)return`optimized`;if(e!==`optimized`&&e!==`json`)throw new t(`INVALID_ARGS`,`Expected mcpOutputFormat to be "optimized" or "json".`);return e}function ct(e){return Object.fromEntries(Object.entries(e).filter(([e])=>!z.has(e)))}function J(e,t){let n=G(t),r=Q(e,t.inputSchema);return{...r,properties:Object.fromEntries(Object.entries(r.properties).filter(([e])=>n[e]?.kind!==`operator`))}}function Y(e,t,n){let r=J(e,t).properties,i=G(t);for(let t of Object.keys(n)){if(Object.hasOwn(r,t))continue;let n=Object.hasOwn(i,t)?i[t]:void 0;if(n?.kind!==`retired`)return n?.kind===`operator`?re(t,n.source):`${t} is not an accepted argument for the ${e} tool.`}}function X(e,t,n){if(!(!e||t===void 0)){if(Array.isArray(t))return Z(t,(t,r)=>X(e.items,t,`${n}[${r}]`));if(a(t))return Z(e.oneOf??[],e=>X(e,t,n))??Z(Object.entries(e.properties??{}),([e,r])=>Object.hasOwn(t,e)?lt(r,t,e,`${n}.${e}`):void 0)}}function lt(e,t,n,r){let i=e.commandInputFor;if(i===void 0)return X(e,t[n],r);let o=t[n],s=u(t[i]);if(s===void 0||!a(o))return;let c=Y(s,v(s),o);return c===void 0?void 0:`${r}: ${c}`}function Z(e,t){for(let[n,r]of e.entries()){let e=t(r,n);if(e)return e}}function ut(e,t){let n=ee(e);if(n.envelopeMs===`unbounded`)return`${t} Streams progress; no fixed client timeout.`;let r=Math.round(n.envelopeMs/1e3);return n.budget.source===`none`?`${t} Times out after ${r}s.`:`${t} Times out after ${r}s; a caller-supplied budget extends it.`}function Q(e,t){let n=l(e);return{...t,properties:{...t.properties,...n&&!t.properties?.noRecord?{noRecord:{type:`boolean`,description:`Do not record this action.`}}:{},...je()}}}async function dt(e){if(e.outputFormat===`json`||e.responseLevel!==void 0&&e.responseLevel!=="default")return $(e.result);let t=await me({name:e.name,input:e.input,result:e.result});return typeof t?.text==`string`?ft(e.name,t):$(t?.data??e.result)}function ft(e,t){let n=t.text??``;if(!pe(e))return n;let r=t.stderr?.trimEnd()??``;return r===``?n:`${n}${n.endsWith(`
|
|
3
|
+
`)?``:`
|
|
4
|
+
`}${r}`}function $(e){return typeof e==`string`?e:JSON.stringify(e,null,2)}export{B as a,V as i,K as n,z as o,et as r,tt as t};
|
package/dist/src/command.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime.js";import{_ as t,a as n,c as r,d as i,f as a,g as o,h as s,i as c,l,n as u,o as d,p as f,r as p,s as m,t as h,u as g}from"./exec.js";
|
|
1
|
+
import{r as e}from"./rolldown-runtime.js";import{_ as t,a as n,c as r,d as i,f as a,g as o,h as s,i as c,l,n as u,o as d,p as f,r as p,s as m,t as h,u as g}from"./exec.js";var _=e({coerceExecResult:()=>h,execFailureDetails:()=>u,isCommandTimeoutError:()=>p,isExecutablePath:()=>c,requireExecSuccess:()=>n,resolveExecutableOverridePath:()=>d,resolveFileOverridePath:()=>m,runCmd:()=>r,runCmdBackground:()=>l,runCmdDetached:()=>g,runCmdDetachedMonitored:()=>i,runCmdStreaming:()=>a,runCmdSync:()=>f,whichCmd:()=>s,withCommandExecutorOverride:()=>o,withoutCommandExecutorOverride:()=>t});export{_ as t};
|
package/dist/src/config.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const e=18e4,t=6e4,n=6e4,r=2e4,i=12e4,a=1e4,o=15e3,s=2e4,c=
|
|
1
|
+
const e=18e4,t=6e4,n=6e4,r=2e4,i=12e4,a=1e4,o=15e3,s=2e4,c=5e3,l=15e3,u=2e4,d=1e3,f=5e3;export{i as a,a as c,l as d,s as f,r as i,d as l,n,u as o,o as p,e as r,t as s,c as t,f as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{C as e,o as t}from"./sdk-contracts.js";import{a as n,l as r,v as i,x as a}from"./sdk-device.js";import{c as o,i as s,s as c}from"./lease-scope.js";import{n as l,t as u}from"./catalog.js";import{t as d}from"./sdk-remote-config.js";import{t as f}from"./prepare-kind.js";import{r as p}from"./diagnostics.js";import{D as m}from"./owner-identity.js";import{f as h}from"./exec.js";import"./file.js";import"./diagnostics2.js";import"./command.js";import{t as ee}from"./daemon-resolution.js";import{_ as g}from"./base-url.js";import{i as _,r as v}from"./client-metro-companion.js";import{n as y}from"./metro2.js";import{n as te,r as b,t as ne}from"./remote-config2.js";import{n as x,t as S}from"./providers.js";import C from"node:path";import w from"node:fs";import T from"node:crypto";const E={slug:`react-devtools-companion`,runArg:g,displayName:`React DevTools companion`};async function re(e){return await v({...e,definition:E,localBaseUrl:e.localBaseUrl??`http://127.0.0.1:8097`,registerPath:`/api/react-devtools/companion/register`,unregisterPath:`/api/react-devtools/companion/unregister`,devicePort:e.devicePort??8097})}async function D(e){return await _({...e,definition:E})}function O(e){return e===`android-instance`||e===`ios-instance`}function ie(e){return[`exec`,`--yes`,`--package`,`agent-cdp@1.6.1`,`--`,`agent-cdp`,...e]}function ae(e){return e.some(e=>e===`--url`||e.startsWith(`--url=`))}function k(e){return e[0]===`target`&&(e[1]===`list`||e[1]===`select`)&&!ae(e)}function oe(e){let t=new URL(e);t.search=``,t.hash=``;let n=t.pathname.replace(/\/+$/,``);return t.pathname=n.endsWith(`/index.bundle`)?n.slice(0,-13)||`/`:n||`/`,t.toString().replace(/\/+$/,``)}function se(e){let t=e?.metroPublicBaseUrl?.trim();return t?oe(t):null}function ce(t,n={}){if(!k(t)||!n.flags?.metroProxyBaseUrl||!O(n.flags.leaseBackend))return t;let r=se(n.flags);if(!r)throw new e(`INVALID_ARGS`,`cdp remote bridge target discovery requires a React Native dev-server public base URL.`,{hint:`Include metroPublicBaseUrl in the remote config so cdp can reach the local or tunneled Metro/Re.Pack CDP endpoint without bridge proxy authentication.`});return[...t,`--url`,r]}async function le(e,t={}){let n=ce(e,t);return(await h(`npm`,ie(n),{cwd:t.cwd??process.cwd(),env:t.env??process.env,allowFailure:!0,onStdoutChunk:e=>{process.stdout.write(e)},onStderrChunk:e=>{process.stderr.write(e)}})).exitCode}function A(e){let t=L(e);if(!w.existsSync(t))return null;let n;try{n=JSON.parse(w.readFileSync(t,`utf8`))}catch(t){return H(e,t),null}return ge(n)?n:(H(e),null)}function j(e){let t=L({stateDir:e.stateDir,session:e.state.session});w.mkdirSync(C.dirname(t),{recursive:!0}),V(t,e.state),V(R(e.stateDir),{session:e.state.session})}function M(e){return{baseUrl:me(e.daemonBaseUrl),transport:e.daemonTransport,serverMode:e.daemonServerMode}}function N(e){w.rmSync(L(e),{force:!0});let t=R(e.stateDir);B(e.stateDir)===e.session&&w.rmSync(t,{force:!0})}function ue(t){let n=t.validateRemoteConfigHash??!0,r=t.remoteConfig?te({configPath:t.remoteConfig,cwd:t.cwd,env:t.env}):void 0,i=A(t)??(t.allowActiveFallback?z({stateDir:t.stateDir}):null);if(!i||r&&i.remoteConfigPath!==r)return null;if(n&&I(i.remoteConfigPath)!==i.remoteConfigHash)throw new e(`INVALID_ARGS`,`Active remote connection config changed. Run agent-device connect --force to refresh it.`,{remoteConfig:i.remoteConfigPath});let a=pe(i,t),l=s(i);return{runtime:i.runtime,connection:o(l),flags:{...a,remoteConfig:i.remoteConfigPath,daemonBaseUrl:i.daemon?.baseUrl??a.daemonBaseUrl,daemonAuthToken:a.daemonAuthToken,daemonTransport:i.daemon?.transport??a.daemonTransport,daemonServerMode:i.daemon?.serverMode??a.daemonServerMode,...c(l),sessionIsolation:`tenant`,session:i.session,platform:i.platform??a.platform,target:i.target??a.target}}}function P(e){return o(s(e))}function F(e,t){return{leaseProvider:e.leaseProvider??t.leaseProvider,clientId:e.clientId??t.clientId,deviceKey:e.deviceKey??t.deviceKey}}function de(e,t){return!t||(t.leaseProvider===void 0||e.leaseProvider===t.leaseProvider)&&(t.clientId===void 0||e.clientId===t.clientId)}function I(t){try{return T.createHash(`sha256`).update(w.readFileSync(t)).digest(`hex`)}catch(n){throw new e(`INVALID_ARGS`,`Remote config file not found: ${t}`,{cause:n instanceof Error?n.message:String(n)})}}function L(e){return C.join(e.stateDir,`remote-connections`,`${he(e.session)}.json`)}function R(e){return C.join(e,`remote-connections`,`.active-session.json`)}function z(e){let t=B(e.stateDir);return t?A({stateDir:e.stateDir,session:t}):null}function B(e){let t=R(e);if(w.existsSync(t))try{let e=JSON.parse(w.readFileSync(t,`utf8`));return typeof e.session==`string`?e.session:void 0}catch{return}}function fe(e){if(e)return T.createHash(`sha256`).update(e).digest(`hex`).slice(0,12)}function pe(e,t){try{return b({configPath:e.remoteConfigPath,cwd:t.cwd,env:t.env}).profile}catch(e){if(t.validateRemoteConfigHash===!1)return{};throw e}}function V(e,t){m({destination:e,contents:`${JSON.stringify(t,null,2)}\n`,mode:384})}function me(e){if(!e)return;let t=new URL(e);t.username=``,t.password=``;for(let e of Array.from(t.searchParams.keys()))/(auth|key|password|secret|token)/i.test(e)&&t.searchParams.delete(e);return t.toString().replace(/\/+$/,``)}function H(e,t){p({level:`warn`,phase:`remote_connection_state_invalid`,data:{session:e.session,cause:t instanceof Error?t.message:t?String(t):void 0}}),N(e)}function he(e){let t=e.replaceAll(/[^a-zA-Z0-9._-]/g,`_`);return t?t===e?t:`${t}-${T.createHash(`sha256`).update(e).digest(`hex`).slice(0,8)}`:`default`}function ge(e){if(!e||typeof e!=`object`||Array.isArray(e))return!1;let t=e;return t.version===1&&_e(t,[`session`,`remoteConfigPath`,`remoteConfigHash`,`tenant`,`runId`,`connectedAt`,`updatedAt`])&&ve(t,[`leaseId`,`leaseBackend`,`leaseProvider`,`deviceKey`,`clientId`])&&ye(t.daemon)}function _e(e,t){return t.every(t=>typeof e[t]==`string`)}function ve(e,t){return t.every(t=>e[t]===void 0||typeof e[t]==`string`)}function ye(e){return e===void 0?!0:!e||typeof e!=`object`||Array.isArray(e)?!1:be(e)}function be(e){let t=e;return(t.baseUrl===void 0||typeof t.baseUrl==`string`)&&(t.authToken===void 0||typeof t.authToken==`string`)&&(t.transport===void 0||typeof t.transport==`string`)&&(t.serverMode===void 0||typeof t.serverMode==`string`)}const xe=d.map(e=>e.key);function U(e){let t={};for(let n of xe){let r=e[n];r!==void 0&&(t[n]=r)}return t}function Se(e){return e.remoteConfig?{...U(b({configPath:e.remoteConfig,cwd:e.cwd,env:e.env}).profile),remoteConfig:e.remoteConfig}:{}}function Ce(e){return e===`cloud`||e===`proxy`||W(e)}function W(e){return e===`limrun`||x(e)}function we(){return[`cloud`,`proxy`,S.browserStack,S.awsDeviceFarm,`limrun`].join(`, `)}function G(e){let t=W(e),n=x(e);return{leaseKind:e===`proxy`?`proxy`:t?`direct-device-provider`:`remote-provider`,requiresAppAttachment:e===S.awsDeviceFarm,requiresRemoteDaemon:!t,supportsArtifacts:n,supportsDeferredAppSelection:e===`limrun`,supportsDirectPortReverse:e===`limrun`,usesCloudWebDriverLease:n}}function K(e){return{providerDeviceOrientation:e.providerDeviceOrientation,providerGeoLocation:e.providerGeoLocation,providerTimezone:e.providerTimezone,providerAppiumVersion:e.providerAppiumVersion,providerLanguage:e.providerLanguage,providerLocale:e.providerLocale,providerNetworkProfile:e.providerNetworkProfile,providerCustomNetwork:e.providerCustomNetwork,providerNoResignApp:e.providerNoResignApp}}function Te(e){return{metroProjectRoot:e.metroProjectRoot,metroKind:e.metroKind,metroPublicBaseUrl:e.metroPublicBaseUrl,metroProxyBaseUrl:e.metroProxyBaseUrl,metroPreparePort:e.metroPreparePort,metroListenHost:e.metroListenHost,metroStatusHost:e.metroStatusHost,metroStartupTimeoutMs:e.metroStartupTimeoutMs,metroProbeTimeoutMs:e.metroProbeTimeoutMs,metroRuntimeFile:e.metroRuntimeFile,metroNoReuseExisting:e.metroNoReuseExisting,metroNoInstallDeps:e.metroNoInstallDeps,launchUrl:e.launchUrl}}const q=new Set([`artifacts`,`connect`,`connection`,`close`,`disconnect`,`metro`,`session`]),J=new Set([`open`]),Ee=new Set([l.open,l.install,l.reinstall,u.installSource]);async function De(t){let{command:n,flags:r,client:i}=t;if(!r.remoteConfig)return{flags:r,runtime:t.runtime};let a=ee(r.stateDir).baseDir,o=b({configPath:r.remoteConfig,cwd:process.cwd(),env:process.env}),s={...U(o.profile),...r,remoteConfig:o.resolvedPath},c=A({stateDir:a,session:s.session??`default`});if(c&&c.remoteConfigPath!==o.resolvedPath)throw new e(`INVALID_ARGS`,`A different remote connection is already active for this session. Run connect --force or disconnect before using a different --remote-config.`,{session:c.session,activeRemoteConfig:c.remoteConfigPath,requestedRemoteConfig:o.resolvedPath});let u=c??Qe(s,o.resolvedPath,o.profile),d={...s,session:u.session},f=G(u.leaseProvider).supportsDeferredAppSelection,p=f&&n===l.open?t.positionals?.[0]:void 0;f&&delete d.providerApp;let m=Ze(u.runtime,d.platform)??t.runtime,h=u,g=!c,_,v=Fe(h);if(v.shouldAllocate(n)){let e=await Me({command:n,client:i,state:u,nextState:h,nextFlags:d,initialApp:p,policy:v});h=e.state,g||=e.changed,_=e.acquiredLeaseForCleanup}let y=await Oe({command:n,flags:d,client:i,state:u,nextState:h,runtime:m,positionals:t.positionals,batchSteps:t.batchSteps,forceRuntimePrepare:t.forceRuntimePrepare});return h=y.state,m=y.runtime,g||=y.changed,await je({changed:g,stateDir:a,state:h,client:i,acquiredLeaseForCleanup:_,preparedMetroCleanupOnFailure:y.preparedMetroCleanupOnFailure,metroCleanupToStop:y.metroCleanupToStop}),{flags:{...d,session:h.session,leaseId:h.leaseId,leaseBackend:h.leaseBackend,platform:h.platform??d.platform,target:h.target??d.target},runtime:m,connection:P(h)}}async function Oe(t){let{command:n,flags:r,state:i,client:a}=t,o=ke(t.nextState,r),s=t.runtime;if(!Je(n,r,t.batchSteps,t.positionals)||!$(r)||!Ae(t.forceRuntimePrepare,s,r.platform))return{state:o,runtime:s,changed:!1};if(!o.leaseId)throw new e(`INVALID_ARGS`,`${n} requires a resolved remote lease before Metro runtime can be prepared.`);let c=await Be(r,a,i.remoteConfigPath,i.session,{tenantId:i.tenant,runId:i.runId,leaseId:o.leaseId}),l=!Xe(o.metro,c.cleanup);return o={...o,runtime:c.runtime,metro:c.cleanup,updatedAt:new Date().toISOString()},{state:o,runtime:c.runtime,changed:!0,metroCleanupToStop:l?t.nextState.metro:void 0,preparedMetroCleanupOnFailure:l?c.cleanup:void 0}}function ke(e,t){return e.leaseId||!t.leaseId?e:{...e,leaseId:t.leaseId,leaseBackend:t.leaseBackend}}function Ae(e,t,n){return e===!0||!t||!Ye(t,n)}async function je(e){if(e.changed)try{j({stateDir:e.stateDir,state:e.state})}catch(t){throw await Y(e.preparedMetroCleanupOnFailure),await Ke(e.client,e.state,e.acquiredLeaseForCleanup),t}await Y(e.metroCleanupToStop)}async function Me(e){let{command:t,client:n,state:r,nextFlags:i,policy:a}=e,o=r.leaseBackend??Q(i),s=e.nextState,c=await a.resolveLeaseState({command:t,client:n,state:s,flags:i,leaseBackend:o});s=c.state,c.device&&tt(i,c.device);let l=s.leaseBackend??o??qe(i,t);at(r,i,l);let u=await $e(n,s,l,a,i,e.initialApp),d=u.lease;return i.leaseId=d.leaseId,i.leaseBackend=l,i.platform=s.platform??i.platform,i.target=s.target??i.target,Ne(s,d,l)?{state:s,changed:!1,acquiredLeaseForCleanup:u.acquired?d:void 0}:{state:Pe(s,d,l,i),changed:!0,acquiredLeaseForCleanup:u.acquired?d:void 0}}function Ne(e,t,n){return e.leaseId===t.leaseId&&e.leaseBackend===n&&e.deviceKey===(t.deviceKey??e.deviceKey)}function Pe(e,t,n,r){let i=F(t,e);return{...e,leaseId:t.leaseId,leaseBackend:n,...i,platform:e.platform??r.platform,target:e.target??r.target,updatedAt:new Date().toISOString()}}function Fe(e){let t=G(e.leaseProvider);return t.leaseKind===`proxy`?Re:t.supportsDeferredAppSelection?Ie:t.usesCloudWebDriverLease?ze:Le}const Ie={shouldAllocate:e=>e!==l.apps&&!q.has(e),ttlMs:()=>void 0,resolveLeaseState:async e=>({state:e.state})},Le={shouldAllocate:e=>!q.has(e),ttlMs:()=>void 0,resolveLeaseState:async e=>({state:e.state})},Re={shouldAllocate:e=>e!==`devices`&&!q.has(e),ttlMs:()=>3e5,resolveLeaseState:et},ze={shouldAllocate:e=>!q.has(e),ttlMs:()=>6e5,resolveLeaseState:async e=>({state:e.state})};async function Be(t,n,r,i,a){if(!t.metroProjectRoot&&!t.metroPublicBaseUrl&&!t.metroProxyBaseUrl)return{};if(t.platform!==`ios`&&t.platform!==`android`)throw new e(`INVALID_ARGS`,`Deferred Metro preparation requires platform "ios" or "android".`);if(!t.metroPublicBaseUrl&&!t.metroProxyBaseUrl)throw new e(`INVALID_ARGS`,`Deferred Metro preparation requires metroPublicBaseUrl or metroProxyBaseUrl when Metro settings are provided.`);let o=await n.metro.prepare({projectRoot:t.metroProjectRoot,kind:f(t.metroKind),publicBaseUrl:t.metroPublicBaseUrl,proxyBaseUrl:t.metroProxyBaseUrl,bearerToken:t.metroBearerToken,bridgeScope:a,launchUrl:t.launchUrl,companionProfileKey:r,companionConsumerKey:i,port:t.metroPreparePort,listenHost:t.metroListenHost,statusHost:t.metroStatusHost,startupTimeoutMs:t.metroStartupTimeoutMs,probeTimeoutMs:t.metroProbeTimeoutMs,reuseExisting:!t.metroNoReuseExisting&&void 0,installDependenciesIfNeeded:!t.metroNoInstallDeps&&void 0,runtimeFilePath:t.metroRuntimeFile});return{runtime:t.platform===`ios`?o.iosRuntime:o.androidRuntime,cleanup:t.metroProxyBaseUrl?{projectRoot:o.projectRoot,profileKey:r,consumerKey:i}:void 0}}async function Y(e){if(e)try{await y(e)}catch{}}async function Ve(e){try{await D({projectRoot:process.cwd(),stateDir:e.stateDir,profileKey:e.state.remoteConfigPath,consumerKey:e.state.session})}catch{}}async function X(e,t,n){return t.leaseId?await e.leases.release({tenant:t.tenant,runId:t.runId,leaseId:t.leaseId,leaseBackend:t.leaseBackend,daemonBaseUrl:t.daemon?.baseUrl,daemonAuthToken:n,daemonTransport:t.daemon?.transport,daemonServerMode:t.daemon?.serverMode,...P(t)}):{released:!1}}function He(e){let t=Ue(e.previous,e.cwd,e.env);return t?{canAuthenticate:!0,daemonAuthToken:t}:e.previous.daemon?.baseUrl===e.nextDaemonBaseUrl?{canAuthenticate:!0,daemonAuthToken:e.ambientDaemonAuthToken}:{canAuthenticate:!1}}function Ue(e,t,n){try{let{profile:r}=ne({configPath:e.remoteConfigPath,cwd:t,env:n});return r.daemonAuthToken&&We(e,r.daemonBaseUrl)?r.daemonAuthToken:void 0}catch{return}}function We(e,t){let n=M({daemonBaseUrl:t})?.baseUrl;return n!==void 0&&n===e.daemon?.baseUrl}async function Ge(e,t,n){if(!t.leaseId)return;let r=He({previous:t,nextDaemonBaseUrl:n.nextDaemonBaseUrl,ambientDaemonAuthToken:n.ambientDaemonAuthToken,cwd:n.cwd,env:n.env});if(!r.canAuthenticate)return Z(t,`no credential known to belong to that endpoint was available`);try{await X(e,t,r.daemonAuthToken);return}catch{return Z(t,`the release request failed`)}}function Z(e,t){return{status:`unreleased`,message:`Could not release the previous lease ${e.leaseId} (tenant ${e.tenant}, run ${e.runId}) at ${e.daemon?.baseUrl??`its daemon`}: ${t}. It was left in place — release it manually if it is still active.`}}async function Ke(e,t,n){if(n)try{let r=F(t,n);await e.leases.release({tenant:t.tenant,runId:t.runId,leaseId:n.leaseId,leaseBackend:t.leaseBackend??n.backend,...r})}catch{}}function Q(e){if(e.leaseBackend)return e.leaseBackend;if(e.platform===`android`)return`android-instance`;if(e.platform===`ios`)return`ios-instance`;if(e.platform===`harmonyos`)return`harmonyos-instance`}function qe(t,n){let r=Q(t);if(r)return r;throw new e(`INVALID_ARGS`,`${n} requires --platform ios|android|harmonyos or --lease-backend when the remote connection has not resolved a lease yet.`)}function Je(e,t,n,r=[]){return e===`cdp`?k(r)&&!!t.metroPublicBaseUrl:J.has(e)?!0:e!==`batch`||!n?!1:n.some(e=>{let t=e.command.trim().toLowerCase();return J.has(t)&&e.runtime===void 0})}function $(e){let t=e.metroKind;return!!(e.metroPublicBaseUrl||e.metroProxyBaseUrl||e.metroProjectRoot||t)}function Ye(e,n){return!e.platform||!n||!t(n)||e.platform===n}function Xe(e,t){return e?.projectRoot===t?.projectRoot&&e?.profileKey===t?.profileKey&&e?.consumerKey===t?.consumerKey}function Ze(e,t){if(e)return Ye(e,t)?e:void 0}function Qe(t,n,r={}){if(!t.tenant)throw new e(`INVALID_ARGS`,`remote command requires tenant in remote config or via --tenant <id>.`);if(!t.runId)throw new e(`INVALID_ARGS`,`remote command requires runId in remote config or via --run-id <id>.`);if(!t.daemonBaseUrl&&G(r.leaseProvider).requiresRemoteDaemon)throw new e(`INVALID_ARGS`,`remote command requires daemonBaseUrl in remote config, config, env, or --daemon-base-url.`);let i=new Date().toISOString();return{version:1,session:t.session??`default`,remoteConfigPath:n,remoteConfigHash:I(n),daemon:M(t),tenant:t.tenant,runId:t.runId,leaseId:t.leaseId,leaseBackend:t.leaseBackend??Q(t),leaseProvider:r.leaseProvider,clientId:r.clientId,deviceKey:r.deviceKey,platform:t.platform,target:t.target,connectedAt:i,updatedAt:i}}async function $e(e,t,n,r,i,a){let o=P(t);if(t.leaseId&&t.leaseBackend===n){let i=await ot(e,t.leaseId,{tenant:t.tenant,runId:t.runId,leaseBackend:n,...o,ttlMs:r.ttlMs(t)});if(i)return{lease:i,acquired:!1}}return{lease:await e.leases.allocate({tenant:t.tenant,runId:t.runId,leaseBackend:n,...o,ttlMs:r.ttlMs(t),platform:t.platform??i.platform,target:t.target??i.target,device:i.device,udid:i.udid,serial:i.serial,providerApp:a??i.providerApp,providerOsVersion:i.providerOsVersion,providerProject:i.providerProject,providerBuild:i.providerBuild,providerSessionName:i.providerSessionName,...K(i),awsProjectArn:i.awsProjectArn,awsDeviceArn:i.awsDeviceArn,awsAppArn:i.awsAppArn,awsRegion:i.awsRegion,awsInteractionMode:i.awsInteractionMode}),acquired:!0}}async function et(t){if(!Ee.has(t.command)){if(t.state.leaseId&&t.state.deviceKey)return{state:t.state};throw new e(`INVALID_ARGS`,`No active proxy device lease for this session; run open first.`)}let n=await nt(t.client,t.flags),r=rt(n);return{state:{...t.state,deviceKey:r,leaseBackend:t.state.leaseBackend??t.leaseBackend??it(n),platform:t.state.platform??n.platform,target:t.state.target??n.target,updatedAt:new Date().toISOString()},device:n}}function tt(e,t){if(e.platform=t.platform,e.target=t.target??e.target,r(t)){e.udid=t.id;return}(t.platform===`android`||t.platform===`harmonyos`)&&(e.serial=t.id)}async function nt(e,t){let r=await e.devices.list({platform:t.platform,target:t.target,device:t.device,udid:t.udid,serial:t.serial,iosSimulatorDeviceSet:t.iosSimulatorDeviceSet,androidDeviceAllowlist:t.androidDeviceAllowlist});return await a(r.map(e=>({...n(e.platform),id:e.id,name:e.name,kind:e.kind,target:e.target,booted:e.booted})),{platform:t.platform,target:t.target,deviceName:t.device,udid:t.udid,serial:t.serial})}function rt(e){return`${i(e)}:${e.target??`mobile`}:${e.id}`}function it(e){if(r(e))return`ios-instance`;if(e.platform===`android`)return`android-instance`;if(e.platform===`harmonyos`)return`harmonyos-instance`}function at(t,n,r){if(t.leaseBackend&&t.leaseBackend!==r)throw new e(`INVALID_ARGS`,`Active remote connection is already bound to a different lease backend. Re-run connect --force to replace it.`,{session:t.session,leaseBackend:t.leaseBackend});if(t.platform&&n.platform&&t.platform!==n.platform)throw new e(`INVALID_ARGS`,`Active remote connection is already bound to a different platform. Re-run connect --force to replace it.`,{session:t.session,platform:t.platform});if(t.target&&n.target&&t.target!==n.target)throw new e(`INVALID_ARGS`,`Active remote connection is already bound to a different target. Re-run connect --force to replace it.`,{session:t.session,target:t.target})}async function ot(e,t,n){try{return await e.leases.heartbeat({...n,leaseId:t})}catch(e){if(st(e))return;throw e}}function st(t){return!(t instanceof e)||t.code!==`UNAUTHORIZED`?!1:t.details?.reason===`LEASE_NOT_FOUND`||t.details?.reason===`LEASE_EXPIRED`||t.details?.reason===`LEASE_REVOKED`}export{N as C,O as D,le as E,re as O,de as S,j as T,fe as _,Q as a,z as b,K as c,G as d,Ce as f,P as g,M as h,X as i,D as k,Te as l,Se as m,De as n,Y as o,U as p,Ge as r,Ve as s,$ as t,we as u,I as v,ue as w,A as x,F as y};
|
|
1
|
+
import{D as e,c as t}from"./sdk-contracts.js";import{S as n,a as r,u as i,y as a}from"./sdk-device.js";import{c as o,i as s,s as c}from"./lease-scope.js";import{n as l,t as u}from"./catalog.js";import{t as d}from"./sdk-remote-config.js";import{t as f}from"./prepare-kind.js";import{r as p}from"./diagnostics.js";import{D as m}from"./owner-identity.js";import{f as h}from"./exec.js";import"./file.js";import"./diagnostics2.js";import"./command.js";import{t as ee}from"./daemon-resolution.js";import{_ as g}from"./base-url.js";import{i as _,r as v}from"./client-metro-companion.js";import{n as y}from"./metro2.js";import{n as te,r as b,t as ne}from"./remote-config2.js";import{n as x,t as S}from"./providers.js";import C from"node:path";import w from"node:fs";import T from"node:crypto";const E={slug:`react-devtools-companion`,runArg:g,displayName:`React DevTools companion`};async function re(e){return await v({...e,definition:E,localBaseUrl:e.localBaseUrl??`http://127.0.0.1:8097`,registerPath:`/api/react-devtools/companion/register`,unregisterPath:`/api/react-devtools/companion/unregister`,devicePort:e.devicePort??8097})}async function D(e){return await _({...e,definition:E})}function O(e){return e===`android-instance`||e===`ios-instance`}function ie(e){return[`exec`,`--yes`,`--package`,`agent-cdp@1.6.1`,`--`,`agent-cdp`,...e]}function ae(e){return e.some(e=>e===`--url`||e.startsWith(`--url=`))}function k(e){return e[0]===`target`&&(e[1]===`list`||e[1]===`select`)&&!ae(e)}function oe(e){let t=new URL(e);t.search=``,t.hash=``;let n=t.pathname.replace(/\/+$/,``);return t.pathname=n.endsWith(`/index.bundle`)?n.slice(0,-13)||`/`:n||`/`,t.toString().replace(/\/+$/,``)}function se(e){let t=e?.metroPublicBaseUrl?.trim();return t?oe(t):null}function ce(t,n={}){if(!k(t)||!n.flags?.metroProxyBaseUrl||!O(n.flags.leaseBackend))return t;let r=se(n.flags);if(!r)throw new e(`INVALID_ARGS`,`cdp remote bridge target discovery requires a React Native dev-server public base URL.`,{hint:`Include metroPublicBaseUrl in the remote config so cdp can reach the local or tunneled Metro/Re.Pack CDP endpoint without bridge proxy authentication.`});return[...t,`--url`,r]}async function le(e,t={}){let n=ce(e,t);return(await h(`npm`,ie(n),{cwd:t.cwd??process.cwd(),env:t.env??process.env,allowFailure:!0,onStdoutChunk:e=>{process.stdout.write(e)},onStderrChunk:e=>{process.stderr.write(e)}})).exitCode}function A(e){let t=L(e);if(!w.existsSync(t))return null;let n;try{n=JSON.parse(w.readFileSync(t,`utf8`))}catch(t){return H(e,t),null}return ge(n)?n:(H(e),null)}function j(e){let t=L({stateDir:e.stateDir,session:e.state.session});w.mkdirSync(C.dirname(t),{recursive:!0}),V(t,e.state),V(R(e.stateDir),{session:e.state.session})}function M(e){return{baseUrl:me(e.daemonBaseUrl),transport:e.daemonTransport,serverMode:e.daemonServerMode}}function N(e){w.rmSync(L(e),{force:!0});let t=R(e.stateDir);B(e.stateDir)===e.session&&w.rmSync(t,{force:!0})}function ue(t){let n=t.validateRemoteConfigHash??!0,r=t.remoteConfig?te({configPath:t.remoteConfig,cwd:t.cwd,env:t.env}):void 0,i=A(t)??(t.allowActiveFallback?z({stateDir:t.stateDir}):null);if(!i||r&&i.remoteConfigPath!==r)return null;if(n&&I(i.remoteConfigPath)!==i.remoteConfigHash)throw new e(`INVALID_ARGS`,`Active remote connection config changed. Run agent-device connect --force to refresh it.`,{remoteConfig:i.remoteConfigPath});let a=pe(i,t),l=s(i);return{runtime:i.runtime,connection:o(l),flags:{...a,remoteConfig:i.remoteConfigPath,daemonBaseUrl:i.daemon?.baseUrl??a.daemonBaseUrl,daemonAuthToken:a.daemonAuthToken,daemonTransport:i.daemon?.transport??a.daemonTransport,daemonServerMode:i.daemon?.serverMode??a.daemonServerMode,...c(l),sessionIsolation:`tenant`,session:i.session,platform:i.platform??a.platform,target:i.target??a.target}}}function P(e){return o(s(e))}function F(e,t){return{leaseProvider:e.leaseProvider??t.leaseProvider,clientId:e.clientId??t.clientId,deviceKey:e.deviceKey??t.deviceKey}}function de(e,t){return!t||(t.leaseProvider===void 0||e.leaseProvider===t.leaseProvider)&&(t.clientId===void 0||e.clientId===t.clientId)}function I(t){try{return T.createHash(`sha256`).update(w.readFileSync(t)).digest(`hex`)}catch(n){throw new e(`INVALID_ARGS`,`Remote config file not found: ${t}`,{cause:n instanceof Error?n.message:String(n)})}}function L(e){return C.join(e.stateDir,`remote-connections`,`${he(e.session)}.json`)}function R(e){return C.join(e,`remote-connections`,`.active-session.json`)}function z(e){let t=B(e.stateDir);return t?A({stateDir:e.stateDir,session:t}):null}function B(e){let t=R(e);if(w.existsSync(t))try{let e=JSON.parse(w.readFileSync(t,`utf8`));return typeof e.session==`string`?e.session:void 0}catch{return}}function fe(e){if(e)return T.createHash(`sha256`).update(e).digest(`hex`).slice(0,12)}function pe(e,t){try{return b({configPath:e.remoteConfigPath,cwd:t.cwd,env:t.env}).profile}catch(e){if(t.validateRemoteConfigHash===!1)return{};throw e}}function V(e,t){m({destination:e,contents:`${JSON.stringify(t,null,2)}\n`,mode:384})}function me(e){if(!e)return;let t=new URL(e);t.username=``,t.password=``;for(let e of Array.from(t.searchParams.keys()))/(auth|key|password|secret|token)/i.test(e)&&t.searchParams.delete(e);return t.toString().replace(/\/+$/,``)}function H(e,t){p({level:`warn`,phase:`remote_connection_state_invalid`,data:{session:e.session,cause:t instanceof Error?t.message:t?String(t):void 0}}),N(e)}function he(e){let t=e.replaceAll(/[^a-zA-Z0-9._-]/g,`_`);return t?t===e?t:`${t}-${T.createHash(`sha256`).update(e).digest(`hex`).slice(0,8)}`:`default`}function ge(e){if(!e||typeof e!=`object`||Array.isArray(e))return!1;let t=e;return t.version===1&&_e(t,[`session`,`remoteConfigPath`,`remoteConfigHash`,`tenant`,`runId`,`connectedAt`,`updatedAt`])&&ve(t,[`leaseId`,`leaseBackend`,`leaseProvider`,`deviceKey`,`clientId`])&&ye(t.daemon)}function _e(e,t){return t.every(t=>typeof e[t]==`string`)}function ve(e,t){return t.every(t=>e[t]===void 0||typeof e[t]==`string`)}function ye(e){return e===void 0?!0:!e||typeof e!=`object`||Array.isArray(e)?!1:be(e)}function be(e){let t=e;return(t.baseUrl===void 0||typeof t.baseUrl==`string`)&&(t.authToken===void 0||typeof t.authToken==`string`)&&(t.transport===void 0||typeof t.transport==`string`)&&(t.serverMode===void 0||typeof t.serverMode==`string`)}const xe=d.map(e=>e.key);function U(e){let t={};for(let n of xe){let r=e[n];r!==void 0&&(t[n]=r)}return t}function Se(e){return e.remoteConfig?{...U(b({configPath:e.remoteConfig,cwd:e.cwd,env:e.env}).profile),remoteConfig:e.remoteConfig}:{}}function Ce(e){return e===`cloud`||e===`proxy`||W(e)}function W(e){return e===`limrun`||x(e)}function we(){return[`cloud`,`proxy`,S.browserStack,S.awsDeviceFarm,`limrun`].join(`, `)}function G(e){let t=W(e),n=x(e);return{leaseKind:e===`proxy`?`proxy`:t?`direct-device-provider`:`remote-provider`,requiresAppAttachment:e===S.awsDeviceFarm,requiresRemoteDaemon:!t,supportsArtifacts:n,supportsDeferredAppSelection:e===`limrun`,supportsDirectPortReverse:e===`limrun`,usesCloudWebDriverLease:n}}function K(e){return{providerDeviceOrientation:e.providerDeviceOrientation,providerGeoLocation:e.providerGeoLocation,providerTimezone:e.providerTimezone,providerAppiumVersion:e.providerAppiumVersion,providerLanguage:e.providerLanguage,providerLocale:e.providerLocale,providerNetworkProfile:e.providerNetworkProfile,providerCustomNetwork:e.providerCustomNetwork,providerNoResignApp:e.providerNoResignApp}}function Te(e){return{metroProjectRoot:e.metroProjectRoot,metroKind:e.metroKind,metroPublicBaseUrl:e.metroPublicBaseUrl,metroProxyBaseUrl:e.metroProxyBaseUrl,metroPreparePort:e.metroPreparePort,metroListenHost:e.metroListenHost,metroStatusHost:e.metroStatusHost,metroStartupTimeoutMs:e.metroStartupTimeoutMs,metroProbeTimeoutMs:e.metroProbeTimeoutMs,metroRuntimeFile:e.metroRuntimeFile,metroNoReuseExisting:e.metroNoReuseExisting,metroNoInstallDeps:e.metroNoInstallDeps,launchUrl:e.launchUrl}}const q=new Set([`artifacts`,`connect`,`connection`,`close`,`disconnect`,`metro`,`session`]),J=new Set([`open`]),Ee=new Set([l.open,l.install,l.reinstall,u.installSource]);async function De(t){let{command:n,flags:r,client:i}=t;if(!r.remoteConfig)return{flags:r,runtime:t.runtime};let a=ee(r.stateDir).baseDir,o=b({configPath:r.remoteConfig,cwd:process.cwd(),env:process.env}),s={...U(o.profile),...r,remoteConfig:o.resolvedPath},c=A({stateDir:a,session:s.session??`default`});if(c&&c.remoteConfigPath!==o.resolvedPath)throw new e(`INVALID_ARGS`,`A different remote connection is already active for this session. Run connect --force or disconnect before using a different --remote-config.`,{session:c.session,activeRemoteConfig:c.remoteConfigPath,requestedRemoteConfig:o.resolvedPath});let u=c??Qe(s,o.resolvedPath,o.profile),d={...s,session:u.session},f=G(u.leaseProvider).supportsDeferredAppSelection,p=f&&n===l.open?t.positionals?.[0]:void 0;f&&delete d.providerApp;let m=Ze(u.runtime,d.platform)??t.runtime,h=u,g=!c,_,v=Fe(h);if(v.shouldAllocate(n)){let e=await Me({command:n,client:i,state:u,nextState:h,nextFlags:d,initialApp:p,policy:v});h=e.state,g||=e.changed,_=e.acquiredLeaseForCleanup}let y=await Oe({command:n,flags:d,client:i,state:u,nextState:h,runtime:m,positionals:t.positionals,batchSteps:t.batchSteps,forceRuntimePrepare:t.forceRuntimePrepare});return h=y.state,m=y.runtime,g||=y.changed,await je({changed:g,stateDir:a,state:h,client:i,acquiredLeaseForCleanup:_,preparedMetroCleanupOnFailure:y.preparedMetroCleanupOnFailure,metroCleanupToStop:y.metroCleanupToStop}),{flags:{...d,session:h.session,leaseId:h.leaseId,leaseBackend:h.leaseBackend,platform:h.platform??d.platform,target:h.target??d.target},runtime:m,connection:P(h)}}async function Oe(t){let{command:n,flags:r,state:i,client:a}=t,o=ke(t.nextState,r),s=t.runtime;if(!Je(n,r,t.batchSteps,t.positionals)||!$(r)||!Ae(t.forceRuntimePrepare,s,r.platform))return{state:o,runtime:s,changed:!1};if(!o.leaseId)throw new e(`INVALID_ARGS`,`${n} requires a resolved remote lease before Metro runtime can be prepared.`);let c=await Be(r,a,i.remoteConfigPath,i.session,{tenantId:i.tenant,runId:i.runId,leaseId:o.leaseId}),l=!Xe(o.metro,c.cleanup);return o={...o,runtime:c.runtime,metro:c.cleanup,updatedAt:new Date().toISOString()},{state:o,runtime:c.runtime,changed:!0,metroCleanupToStop:l?t.nextState.metro:void 0,preparedMetroCleanupOnFailure:l?c.cleanup:void 0}}function ke(e,t){return e.leaseId||!t.leaseId?e:{...e,leaseId:t.leaseId,leaseBackend:t.leaseBackend}}function Ae(e,t,n){return e===!0||!t||!Ye(t,n)}async function je(e){if(e.changed)try{j({stateDir:e.stateDir,state:e.state})}catch(t){throw await Y(e.preparedMetroCleanupOnFailure),await Ke(e.client,e.state,e.acquiredLeaseForCleanup),t}await Y(e.metroCleanupToStop)}async function Me(e){let{command:t,client:n,state:r,nextFlags:i,policy:a}=e,o=r.leaseBackend??Q(i),s=e.nextState,c=await a.resolveLeaseState({command:t,client:n,state:s,flags:i,leaseBackend:o});s=c.state,c.device&&tt(i,c.device);let l=s.leaseBackend??o??qe(i,t);at(r,i,l);let u=await $e(n,s,l,a,i,e.initialApp),d=u.lease;return i.leaseId=d.leaseId,i.leaseBackend=l,i.platform=s.platform??i.platform,i.target=s.target??i.target,Ne(s,d,l)?{state:s,changed:!1,acquiredLeaseForCleanup:u.acquired?d:void 0}:{state:Pe(s,d,l,i),changed:!0,acquiredLeaseForCleanup:u.acquired?d:void 0}}function Ne(e,t,n){return e.leaseId===t.leaseId&&e.leaseBackend===n&&e.deviceKey===(t.deviceKey??e.deviceKey)}function Pe(e,t,n,r){let i=F(t,e);return{...e,leaseId:t.leaseId,leaseBackend:n,...i,platform:e.platform??r.platform,target:e.target??r.target,updatedAt:new Date().toISOString()}}function Fe(e){let t=G(e.leaseProvider);return t.leaseKind===`proxy`?Re:t.supportsDeferredAppSelection?Ie:t.usesCloudWebDriverLease?ze:Le}const Ie={shouldAllocate:e=>e!==l.apps&&!q.has(e),ttlMs:()=>void 0,resolveLeaseState:async e=>({state:e.state})},Le={shouldAllocate:e=>!q.has(e),ttlMs:()=>void 0,resolveLeaseState:async e=>({state:e.state})},Re={shouldAllocate:e=>e!==`devices`&&!q.has(e),ttlMs:()=>3e5,resolveLeaseState:et},ze={shouldAllocate:e=>!q.has(e),ttlMs:()=>6e5,resolveLeaseState:async e=>({state:e.state})};async function Be(t,n,r,i,a){if(!t.metroProjectRoot&&!t.metroPublicBaseUrl&&!t.metroProxyBaseUrl)return{};if(t.platform!==`ios`&&t.platform!==`android`)throw new e(`INVALID_ARGS`,`Deferred Metro preparation requires platform "ios" or "android".`);if(!t.metroPublicBaseUrl&&!t.metroProxyBaseUrl)throw new e(`INVALID_ARGS`,`Deferred Metro preparation requires metroPublicBaseUrl or metroProxyBaseUrl when Metro settings are provided.`);let o=await n.metro.prepare({projectRoot:t.metroProjectRoot,kind:f(t.metroKind),publicBaseUrl:t.metroPublicBaseUrl,proxyBaseUrl:t.metroProxyBaseUrl,bearerToken:t.metroBearerToken,bridgeScope:a,launchUrl:t.launchUrl,companionProfileKey:r,companionConsumerKey:i,port:t.metroPreparePort,listenHost:t.metroListenHost,statusHost:t.metroStatusHost,startupTimeoutMs:t.metroStartupTimeoutMs,probeTimeoutMs:t.metroProbeTimeoutMs,reuseExisting:!t.metroNoReuseExisting&&void 0,installDependenciesIfNeeded:!t.metroNoInstallDeps&&void 0,runtimeFilePath:t.metroRuntimeFile});return{runtime:t.platform===`ios`?o.iosRuntime:o.androidRuntime,cleanup:t.metroProxyBaseUrl?{projectRoot:o.projectRoot,profileKey:r,consumerKey:i}:void 0}}async function Y(e){if(e)try{await y(e)}catch{}}async function Ve(e){try{await D({projectRoot:process.cwd(),stateDir:e.stateDir,profileKey:e.state.remoteConfigPath,consumerKey:e.state.session})}catch{}}async function X(e,t,n){return t.leaseId?await e.leases.release({tenant:t.tenant,runId:t.runId,leaseId:t.leaseId,leaseBackend:t.leaseBackend,daemonBaseUrl:t.daemon?.baseUrl,daemonAuthToken:n,daemonTransport:t.daemon?.transport,daemonServerMode:t.daemon?.serverMode,...P(t)}):{released:!1}}function He(e){let t=Ue(e.previous,e.cwd,e.env);return t?{canAuthenticate:!0,daemonAuthToken:t}:e.previous.daemon?.baseUrl===e.nextDaemonBaseUrl?{canAuthenticate:!0,daemonAuthToken:e.ambientDaemonAuthToken}:{canAuthenticate:!1}}function Ue(e,t,n){try{let{profile:r}=ne({configPath:e.remoteConfigPath,cwd:t,env:n});return r.daemonAuthToken&&We(e,r.daemonBaseUrl)?r.daemonAuthToken:void 0}catch{return}}function We(e,t){let n=M({daemonBaseUrl:t})?.baseUrl;return n!==void 0&&n===e.daemon?.baseUrl}async function Ge(e,t,n){if(!t.leaseId)return;let r=He({previous:t,nextDaemonBaseUrl:n.nextDaemonBaseUrl,ambientDaemonAuthToken:n.ambientDaemonAuthToken,cwd:n.cwd,env:n.env});if(!r.canAuthenticate)return Z(t,`no credential known to belong to that endpoint was available`);try{await X(e,t,r.daemonAuthToken);return}catch{return Z(t,`the release request failed`)}}function Z(e,t){return{status:`unreleased`,message:`Could not release the previous lease ${e.leaseId} (tenant ${e.tenant}, run ${e.runId}) at ${e.daemon?.baseUrl??`its daemon`}: ${t}. It was left in place — release it manually if it is still active.`}}async function Ke(e,t,n){if(n)try{let r=F(t,n);await e.leases.release({tenant:t.tenant,runId:t.runId,leaseId:n.leaseId,leaseBackend:t.leaseBackend??n.backend,...r})}catch{}}function Q(e){if(e.leaseBackend)return e.leaseBackend;if(e.platform===`android`)return`android-instance`;if(e.platform===`ios`)return`ios-instance`;if(e.platform===`harmonyos`)return`harmonyos-instance`}function qe(t,n){let r=Q(t);if(r)return r;throw new e(`INVALID_ARGS`,`${n} requires --platform ios|android|harmonyos or --lease-backend when the remote connection has not resolved a lease yet.`)}function Je(e,t,n,r=[]){return e===`cdp`?k(r)&&!!t.metroPublicBaseUrl:J.has(e)?!0:e!==`batch`||!n?!1:n.some(e=>{let t=e.command.trim().toLowerCase();return J.has(t)&&e.runtime===void 0})}function $(e){let t=e.metroKind;return!!(e.metroPublicBaseUrl||e.metroProxyBaseUrl||e.metroProjectRoot||t)}function Ye(e,n){return!e.platform||!n||!t(n)||e.platform===n}function Xe(e,t){return e?.projectRoot===t?.projectRoot&&e?.profileKey===t?.profileKey&&e?.consumerKey===t?.consumerKey}function Ze(e,t){if(e)return Ye(e,t)?e:void 0}function Qe(t,n,r={}){if(!t.tenant)throw new e(`INVALID_ARGS`,`remote command requires tenant in remote config or via --tenant <id>.`);if(!t.runId)throw new e(`INVALID_ARGS`,`remote command requires runId in remote config or via --run-id <id>.`);if(!t.daemonBaseUrl&&G(r.leaseProvider).requiresRemoteDaemon)throw new e(`INVALID_ARGS`,`remote command requires daemonBaseUrl in remote config, config, env, or --daemon-base-url.`);let i=new Date().toISOString();return{version:1,session:t.session??`default`,remoteConfigPath:n,remoteConfigHash:I(n),daemon:M(t),tenant:t.tenant,runId:t.runId,leaseId:t.leaseId,leaseBackend:t.leaseBackend??Q(t),leaseProvider:r.leaseProvider,clientId:r.clientId,deviceKey:r.deviceKey,platform:t.platform,target:t.target,connectedAt:i,updatedAt:i}}async function $e(e,t,n,r,i,a){let o=P(t);if(t.leaseId&&t.leaseBackend===n){let i=await ot(e,t.leaseId,{tenant:t.tenant,runId:t.runId,leaseBackend:n,...o,ttlMs:r.ttlMs(t)});if(i)return{lease:i,acquired:!1}}return{lease:await e.leases.allocate({tenant:t.tenant,runId:t.runId,leaseBackend:n,...o,ttlMs:r.ttlMs(t),platform:t.platform??i.platform,target:t.target??i.target,device:i.device,udid:i.udid,serial:i.serial,providerApp:a??i.providerApp,providerOsVersion:i.providerOsVersion,providerProject:i.providerProject,providerBuild:i.providerBuild,providerSessionName:i.providerSessionName,...K(i),awsProjectArn:i.awsProjectArn,awsDeviceArn:i.awsDeviceArn,awsAppArn:i.awsAppArn,awsRegion:i.awsRegion,awsInteractionMode:i.awsInteractionMode}),acquired:!0}}async function et(t){if(!Ee.has(t.command)){if(t.state.leaseId&&t.state.deviceKey)return{state:t.state};throw new e(`INVALID_ARGS`,`No active proxy device lease for this session; run open first.`)}let n=await nt(t.client,t.flags),r=rt(n);return{state:{...t.state,deviceKey:r,leaseBackend:t.state.leaseBackend??t.leaseBackend??it(n),platform:t.state.platform??n.platform,target:t.state.target??n.target,updatedAt:new Date().toISOString()},device:n}}function tt(e,t){if(e.platform=t.platform,e.target=t.target??e.target,i(t)){e.udid=t.id;return}(t.platform===`android`||t.platform===`harmonyos`)&&(e.serial=t.id)}async function nt(e,t){let i=await e.devices.list({platform:t.platform,target:t.target,device:t.device,udid:t.udid,serial:t.serial,iosSimulatorDeviceSet:t.iosSimulatorDeviceSet,androidDeviceAllowlist:t.androidDeviceAllowlist});return await n(i.map(e=>({...r(e.platform),id:e.id,name:e.name,kind:e.kind,target:e.target,booted:e.booted})),{platform:t.platform,target:t.target,deviceName:t.device,udid:t.udid,serial:t.serial})}function rt(e){return`${a(e)}:${e.target??`mobile`}:${e.id}`}function it(e){if(i(e))return`ios-instance`;if(e.platform===`android`)return`android-instance`;if(e.platform===`harmonyos`)return`harmonyos-instance`}function at(t,n,r){if(t.leaseBackend&&t.leaseBackend!==r)throw new e(`INVALID_ARGS`,`Active remote connection is already bound to a different lease backend. Re-run connect --force to replace it.`,{session:t.session,leaseBackend:t.leaseBackend});if(t.platform&&n.platform&&t.platform!==n.platform)throw new e(`INVALID_ARGS`,`Active remote connection is already bound to a different platform. Re-run connect --force to replace it.`,{session:t.session,platform:t.platform});if(t.target&&n.target&&t.target!==n.target)throw new e(`INVALID_ARGS`,`Active remote connection is already bound to a different target. Re-run connect --force to replace it.`,{session:t.session,target:t.target})}async function ot(e,t,n){try{return await e.leases.heartbeat({...n,leaseId:t})}catch(e){if(st(e))return;throw e}}function st(t){return!(t instanceof e)||t.code!==`UNAUTHORIZED`?!1:t.details?.reason===`LEASE_NOT_FOUND`||t.details?.reason===`LEASE_EXPIRED`||t.details?.reason===`LEASE_REVOKED`}export{N as C,O as D,le as E,re as O,de as S,j as T,fe as _,Q as a,z as b,K as c,G as d,Ce as f,P as g,M as h,X as i,D as k,Te as l,Se as m,De as n,Y as o,U as p,Ge as r,Ve as s,$ as t,we as u,I as v,ue as w,A as x,F as y};
|
package/dist/src/connection.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{C as e,w as t}from"./sdk-contracts.js";import{r as n}from"./command.js";import{r}from"./version.js";import{t as i}from"./daemon-resolution.js";import{r as a}from"./remote-config2.js";import{n as o}from"./src.js";import{n as s,r as c,t as l}from"./provider-webdriver.js";import{t as u}from"./providers.js";import{C as d,S as f,T as p,_ as m,a as h,b as g,c as _,d as v,f as y,g as ee,h as te,i as ne,l as b,o as x,p as S,r as re,s as C,t as ie,u as ae,v as oe,x as w,y as se}from"./connection-runtime.js";import{o as ce,r as le}from"./auth-session.js";import{t as T}from"./shared.js";import E from"node:path";import D from"node:fs";import O from"node:crypto";const ue=new Set([`daemonAuthToken`,`metroBearerToken`]);function de(e){let t=A(pe(e.profile)),n=E.join(e.stateDir,`remote-connections`,`generated`);D.mkdirSync(n,{recursive:!0,mode:448});let r=E.join(n,`${he(e.provider)}-${me(t)}.json`);D.writeFileSync(r,`${JSON.stringify(t,null,2)}\n`,{mode:384});try{D.chmodSync(r,384)}catch{}return r}function fe(n){try{return a(n)}catch(r){let i=t(r);throw new e(`COMMAND_FAILED`,`${n.provider} connection profile returned invalid remote config.`,{generatedConfigPath:n.configPath,cause:i.message},i)}}function k(e){let t=fe({configPath:de({stateDir:e.stateDir,provider:e.provider,profile:e.profile}),cwd:e.cwd,env:e.env,provider:ge(e.provider)});return{flags:{...S(t.profile),...e.flags,...e.extraFlags??{},remoteConfig:t.resolvedPath},remoteConfigPath:t.resolvedPath}}function pe(e){return Object.fromEntries(Object.entries(e).filter(([e])=>!ue.has(e)))}function me(e){return O.createHash(`sha256`).update(JSON.stringify(e)).digest(`hex`).slice(0,16)}function A(e){return Array.isArray(e)?e.map(A):e&&typeof e==`object`?Object.fromEntries(Object.entries(e).filter(([,e])=>e!==void 0).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>[e,A(t)])):e}function he(e){return e.replaceAll(/[^a-zA-Z0-9._-]/g,`_`)||`generated`}function ge(e){let[t=``,...n]=e;return`${t.toUpperCase()}${n.join(``)}`}function j(...e){return O.createHash(`sha256`).update(e.map(e=>e??``).join(`\0`)).digest(`hex`).slice(0,16)}async function _e(e){let t=await le({stateDir:e.stateDir,flags:e.flags,env:e.env,io:{env:e.env,fetch:e.fetchImpl}}),n=await ve({cloudBaseUrl:t.cloudBaseUrl,accessToken:t.accessToken,fetchImpl:e.fetchImpl}),r=j(e.stateDir,t.cloudBaseUrl,typeof n.daemonBaseUrl==`string`?n.daemonBaseUrl:``,e.flags.session);return k({stateDir:e.stateDir,provider:`cloud`,profile:{...n,leaseProvider:n.leaseProvider??`cloud`,clientId:n.clientId??r,runId:n.runId??`cloud-${r}`},cwd:e.cwd,env:e.env,flags:e.flags,extraFlags:{daemonAuthToken:t.accessToken}})}async function ve(e){let t=await(e.fetchImpl??fetch)(new URL(`/api/control-plane/connection-profile`,e.cloudBaseUrl),{method:`GET`,headers:{authorization:`Bearer ${e.accessToken}`},signal:AbortSignal.timeout(15e3)});return ye(await ce(t,{invalidJsonMessage:`Cloud connection profile endpoint returned invalid JSON (${t.status}).`,rejectedMessage:`Cloud connection profile endpoint rejected the request.`}))}function ye(t){if(!t||typeof t!=`object`||Array.isArray(t))throw new e(`COMMAND_FAILED`,`Cloud connection profile response is invalid.`);let n=t.connection;if(!n||typeof n!=`object`)throw new e(`COMMAND_FAILED`,`Cloud connection profile response is missing profile.`);if(n.remoteConfigProfile!==void 0)return be(n.remoteConfigProfile);throw new e(`COMMAND_FAILED`,`Cloud connection profile did not include remoteConfigProfile.`)}function be(t){if(!t||typeof t!=`object`||Array.isArray(t))throw new e(`COMMAND_FAILED`,`Cloud connection profile remoteConfigProfile is invalid.`);if(Object.keys(t).length===0)throw new e(`COMMAND_FAILED`,`Cloud connection profile remoteConfigProfile is empty.`);return t}function M(e){let t=xe(e.provider)(e),n=j(e.provider,e.stateDir,e.flags.session,t.device),r={tenant:e.flags.tenant??e.provider,sessionIsolation:e.flags.sessionIsolation??`tenant`,runId:e.flags.runId??`${e.provider}-${n}`,leaseProvider:e.provider,clientId:n,leaseBackend:e.flags.leaseBackend??h(e.flags),target:e.flags.target??`mobile`,session:e.flags.session,...t,...b(e.flags)};return k({stateDir:e.stateDir,provider:e.provider,profile:r,cwd:e.cwd,env:e.env,flags:e.flags})}const N=[{provider:u.browserStack,buildProfileFields:Se},{provider:u.awsDeviceFarm,buildProfileFields:we}];function xe(t){let n=N.find(e=>e.provider===t)?.buildProfileFields;if(n)return n;throw new e(`INVALID_ARGS`,`Unsupported cloud WebDriver provider "${t}".`)}function Se(e){return I(e.env,`BROWSERSTACK_USERNAME`,`connect browserstack`),I(e.env,`BROWSERSTACK_ACCESS_KEY`,`connect browserstack`),{platform:P(e.flags.platform,`connect browserstack requires --platform ios|android.`),device:F(e.flags.device,`connect browserstack requires --device <name>.`),providerOsVersion:F(e.flags.providerOsVersion,`connect browserstack requires --provider-os-version <version>.`),providerApp:Ce(F(e.flags.providerApp,`connect browserstack requires --provider-app <bs://app-id-or-local-path>.`),e.cwd),providerProject:e.flags.providerProject,providerBuild:e.flags.providerBuild,providerSessionName:e.flags.providerSessionName,..._(e.flags)}}function Ce(t,n){if(t.startsWith(`bs://`)||/^https?:\/\//i.test(t))return t;let r=E.resolve(n,t);try{if(D.statSync(r).isFile())return r}catch{}throw new e(`INVALID_ARGS`,`BrowserStack app file not found: ${r}`)}function we(e){let{env:t,flags:n}=e;c(n,u.awsDeviceFarm);let r=P(n.platform,`connect aws-device-farm requires --platform ios|android.`),i=L(n.awsProjectArn,t,[`AGENT_DEVICE_AWS_DEVICE_FARM_PROJECT_ARN`,`AWS_DEVICE_FARM_PROJECT_ARN`],`connect aws-device-farm requires --aws-project-arn <arn> or AWS_DEVICE_FARM_PROJECT_ARN.`);return{platform:r,device:n.device,awsProjectArn:i,awsDeviceArn:L(n.awsDeviceArn,t,[`AGENT_DEVICE_AWS_DEVICE_FARM_DEVICE_ARN`,`AWS_DEVICE_FARM_DEVICE_ARN`],`connect aws-device-farm requires --aws-device-arn <arn> or AWS_DEVICE_FARM_DEVICE_ARN.`),awsAppArn:R(n.awsAppArn,t,[`AGENT_DEVICE_AWS_DEVICE_FARM_APP_ARN`,`AWS_DEVICE_FARM_APP_ARN`]),awsRegion:R(n.awsRegion,t,[`AWS_REGION`,`AWS_DEFAULT_REGION`])??s(i),awsInteractionMode:n.awsInteractionMode,providerSessionName:n.providerSessionName}}function P(t,n){if(t===`android`||t===`ios`)return t;throw new e(`INVALID_ARGS`,n)}function F(t,n){if(t)return t;throw new e(`INVALID_ARGS`,n)}function I(t,n,r){let i=t?.[n];if(i)return i;throw new e(`INVALID_ARGS`,`${r} requires ${n} in the environment.`)}function L(e,t,n,r){return F(R(e,t,n),r)}function R(e,t,n){return e||n.map(e=>t?.[e]).find(e=>!!e)}function Te(t){let n=t.env??process.env;if(!n.LIMRUN_API_KEY?.trim())throw new e(`INVALID_ARGS`,`connect limrun requires LIMRUN_API_KEY.`,{hint:`Set LIMRUN_API_KEY in the environment before running agent-device connect limrun.`});let r=Ee({flags:t.flags});return k({stateDir:t.stateDir,provider:`limrun`,profile:r,cwd:t.cwd,env:n,flags:t.flags})}function Ee(e){let t=e.flags,n=De(t);return{stateDir:i(t.stateDir).baseDir,daemonTransport:`auto`,tenant:t.tenant??`limrun`,runId:t.runId??`cli-${Date.now().toString(36)}`,sessionIsolation:`tenant`,leaseBackend:n,leaseProvider:`limrun`,platform:t.platform,target:`mobile`,session:t.session,...b(t)}}function De(t){if(t.platform!==`android`&&t.platform!==`ios`)throw new e(`INVALID_ARGS`,`connect limrun requires --platform ios or android.`);if(t.device!==void 0)throw new e(`INVALID_ARGS`,`connect limrun does not accept --device; Limrun selects a remote simulator or emulator.`);let n=h(t),r=t.platform===`ios`?`ios-instance`:`android-instance`;if(n!==r)throw new e(`INVALID_ARGS`,`connect limrun --platform ${t.platform} requires --lease-backend ${r}.`);return r}function Oe(t){let n=t.flags.daemonBaseUrl??t.env?.AGENT_DEVICE_DAEMON_BASE_URL;if(!n)throw new e(`INVALID_ARGS`,`connect proxy requires --daemon-base-url <url> or AGENT_DEVICE_DAEMON_BASE_URL.`);let r=j(t.stateDir,n,t.flags.session),i={daemonBaseUrl:n,daemonTransport:t.flags.daemonTransport??`http`,daemonServerMode:t.flags.daemonServerMode,tenant:t.flags.tenant??`proxy`,sessionIsolation:t.flags.sessionIsolation??`tenant`,runId:t.flags.runId??`proxy-${r}`,leaseProvider:`proxy`,clientId:r,leaseBackend:t.flags.leaseBackend??h(t.flags),platform:t.flags.platform,target:t.flags.target,device:t.flags.device,udid:t.flags.udid,serial:t.flags.serial,iosSimulatorDeviceSet:t.flags.iosSimulatorDeviceSet,androidDeviceAllowlist:t.flags.androidDeviceAllowlist,session:t.flags.session,...b(t.flags)};return k({stateDir:t.stateDir,provider:`proxy`,profile:i,cwd:t.cwd,env:t.env,flags:t.flags,extraFlags:{daemonBaseUrl:n,daemonTransport:t.flags.daemonTransport??`http`}})}const z={cloud:{resolve:_e,verify:async()=>({service:`the configured cloud service`,status:`verified`,verificationMessage:`Credentials and connection profile verified.`})},proxy:{resolve:Oe,verify:async()=>({service:`Agent Device Proxy`,status:`configured`,verificationMessage:`Proxy configuration saved. Access is checked by the first remote command.`})},browserstack:{resolve:e=>M({provider:`browserstack`,...e}),verify:je},"aws-device-farm":{resolve:e=>M({provider:`aws-device-farm`,...e}),verify:Me},limrun:{resolve:Te,verify:Ne}};async function ke(e){let t=e.cwd??process.cwd(),n=e.env??process.env;if(e.flags.remoteConfig){let r=a({configPath:e.flags.remoteConfig,cwd:t,env:n}),i=r.profile.leaseProvider;return{flags:{...S(r.profile),...e.flags,remoteConfig:r.resolvedPath},remoteConfigPath:r.resolvedPath,...y(i)?{provider:i}:{}}}let r=e.provider??(Pe(e.flags)?`proxy`:`cloud`);return{...await z[r].resolve({flags:e.flags,stateDir:e.stateDir,cwd:t,env:n}),provider:r}}async function Ae(e){return e.provider?await z[e.provider].verify({flags:e.flags,env:process.env}):{service:`remote provider`,status:`configured`,verificationMessage:`Remote connection profile loaded. Access is checked by the first remote command.`}}async function je(e){let{flags:t,env:n}=e;return await l.verifyConnection({provider:`browserstack`,username:B(n.BROWSERSTACK_USERNAME,`BrowserStack profile missed BROWSERSTACK_USERNAME.`),accessKey:B(n.BROWSERSTACK_ACCESS_KEY,`BrowserStack profile missed BROWSERSTACK_ACCESS_KEY.`),platform:V(t.platform,`BrowserStack`),deviceName:B(t.device,`BrowserStack profile missed device.`),osVersion:B(t.providerOsVersion,`BrowserStack profile missed OS version.`),app:B(t.providerApp,`BrowserStack profile missed app.`)})}async function Me(e){let{flags:t}=e;return await l.verifyConnection({provider:`aws-device-farm`,platform:V(t.platform,`AWS Device Farm`),projectArn:B(t.awsProjectArn,`AWS Device Farm profile missed project ARN.`),deviceArn:B(t.awsDeviceArn,`AWS Device Farm profile missed device ARN.`),appArn:t.awsAppArn,region:t.awsRegion})}async function Ne(e){return await o({apiKey:B(e.env.LIMRUN_API_KEY,`Limrun profile missed LIMRUN_API_KEY.`),clientVersion:r(),platform:V(e.flags.platform,`Limrun`),region:e.env.LIMRUN_REGION?.trim()||void 0})}function Pe(e){if(!e.daemonBaseUrl||e.tenant||e.runId||e.leaseId||e.leaseBackend)return!1;try{return new URL(e.daemonBaseUrl).pathname.replace(/\/+$/,``).endsWith(`/agent-device`)}catch{return!1}}function B(t,n){if(t!==void 0)return t;throw new e(`COMMAND_FAILED`,n,{hint:`Reconnect to regenerate and validate the provider profile.`})}function V(t,n){if(t===`android`||t===`ios`)return t;throw new e(`COMMAND_FAILED`,`${n} profile missed a mobile platform.`,{hint:`Reconnect with --platform ios|android.`})}function Fe(e){let{stateDir:t,flags:n,remoteConfigPath:r}=e,i=n.session??Ie();return{session:i,previous:n.session?w({stateDir:t,session:i}):null,remoteConfigHash:oe(r),daemon:te(n)}}function Ie(){return`adc-${O.randomBytes(16).toString(`hex`)}`}function H(e,t){if(e.leaseId)return;let n=v(e.leaseProvider),r=n.leaseKind;if(r===`proxy`)return{status:`deferred`,nextSteps:W(e,t).nextSteps,message:`No live device session has been created. Run devices to inspect inventory without allocating, then open when ready.`};if(n.supportsDeferredAppSelection)return{status:`deferred`,nextSteps:W(e,t).nextSteps,message:`No live device session has been created. Run apps to inspect uploaded assets without allocating; open <uploaded-asset-name> creates the instance.`};if(r===`direct-device-provider`)return{status:`deferred`,nextSteps:W(e,t).nextSteps,message:`No live device session has been created. The first device command shown below will allocate one.`};let i=e.platform===void 0&&e.leaseBackend===void 0?` Add --platform ios|android if the profile does not set a platform.`:``;return{status:`deferred`,nextSteps:K(e,[`agent-device install-from-source <artifact-url> --platform ios|android`,`agent-device open <app-id> --relaunch`,`agent-device snapshot -i`,`agent-device devices`]),message:`No live device session has been created. Run a device command when ready to allocate or refresh the lease.`+i}}function Le(e,t){return{...t,preparationMessage:H(e,t)?.message??`No live device session has been created.`,...W(e,t)}}function Re(e){let{state:t,readiness:n,runtimePreparation:r,previousLeaseNotice:i}=e;if(!n){let e=H(t);return[`Configured remote session "${t.session}" tenant "${t.tenant}" run "${t.runId}"${t.leaseId?` lease ${t.leaseId}`:``}.`,e?.message,r?.message,i?.message].filter(e=>!!e).join(`
|
|
1
|
+
import{D as e,O as t}from"./sdk-contracts.js";import{s as n}from"./device-shell.js";import{r}from"./version.js";import{t as i}from"./daemon-resolution.js";import{r as a}from"./remote-config2.js";import{n as o}from"./src.js";import{n as s,r as c,t as l}from"./provider-webdriver.js";import{t as u}from"./providers.js";import{C as d,S as f,T as p,_ as m,a as h,b as g,c as _,d as v,f as y,g as ee,h as te,i as ne,l as b,o as x,p as S,r as re,s as C,t as ie,u as ae,v as oe,x as w,y as se}from"./connection-runtime.js";import{o as ce,r as le}from"./auth-session.js";import{t as T}from"./shared.js";import E from"node:path";import D from"node:fs";import O from"node:crypto";const ue=new Set([`daemonAuthToken`,`metroBearerToken`]);function de(e){let t=A(pe(e.profile)),n=E.join(e.stateDir,`remote-connections`,`generated`);D.mkdirSync(n,{recursive:!0,mode:448});let r=E.join(n,`${he(e.provider)}-${me(t)}.json`);D.writeFileSync(r,`${JSON.stringify(t,null,2)}\n`,{mode:384});try{D.chmodSync(r,384)}catch{}return r}function fe(n){try{return a(n)}catch(r){let i=t(r);throw new e(`COMMAND_FAILED`,`${n.provider} connection profile returned invalid remote config.`,{generatedConfigPath:n.configPath,cause:i.message},i)}}function k(e){let t=fe({configPath:de({stateDir:e.stateDir,provider:e.provider,profile:e.profile}),cwd:e.cwd,env:e.env,provider:ge(e.provider)});return{flags:{...S(t.profile),...e.flags,...e.extraFlags??{},remoteConfig:t.resolvedPath},remoteConfigPath:t.resolvedPath}}function pe(e){return Object.fromEntries(Object.entries(e).filter(([e])=>!ue.has(e)))}function me(e){return O.createHash(`sha256`).update(JSON.stringify(e)).digest(`hex`).slice(0,16)}function A(e){return Array.isArray(e)?e.map(A):e&&typeof e==`object`?Object.fromEntries(Object.entries(e).filter(([,e])=>e!==void 0).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>[e,A(t)])):e}function he(e){return e.replaceAll(/[^a-zA-Z0-9._-]/g,`_`)||`generated`}function ge(e){let[t=``,...n]=e;return`${t.toUpperCase()}${n.join(``)}`}function j(...e){return O.createHash(`sha256`).update(e.map(e=>e??``).join(`\0`)).digest(`hex`).slice(0,16)}async function _e(e){let t=await le({stateDir:e.stateDir,flags:e.flags,env:e.env,io:{env:e.env,fetch:e.fetchImpl}}),n=await ve({cloudBaseUrl:t.cloudBaseUrl,accessToken:t.accessToken,fetchImpl:e.fetchImpl}),r=j(e.stateDir,t.cloudBaseUrl,typeof n.daemonBaseUrl==`string`?n.daemonBaseUrl:``,e.flags.session);return k({stateDir:e.stateDir,provider:`cloud`,profile:{...n,leaseProvider:n.leaseProvider??`cloud`,clientId:n.clientId??r,runId:n.runId??`cloud-${r}`},cwd:e.cwd,env:e.env,flags:e.flags,extraFlags:{daemonAuthToken:t.accessToken}})}async function ve(e){let t=await(e.fetchImpl??fetch)(new URL(`/api/control-plane/connection-profile`,e.cloudBaseUrl),{method:`GET`,headers:{authorization:`Bearer ${e.accessToken}`},signal:AbortSignal.timeout(15e3)});return ye(await ce(t,{invalidJsonMessage:`Cloud connection profile endpoint returned invalid JSON (${t.status}).`,rejectedMessage:`Cloud connection profile endpoint rejected the request.`}))}function ye(t){if(!t||typeof t!=`object`||Array.isArray(t))throw new e(`COMMAND_FAILED`,`Cloud connection profile response is invalid.`);let n=t.connection;if(!n||typeof n!=`object`)throw new e(`COMMAND_FAILED`,`Cloud connection profile response is missing profile.`);if(n.remoteConfigProfile!==void 0)return be(n.remoteConfigProfile);throw new e(`COMMAND_FAILED`,`Cloud connection profile did not include remoteConfigProfile.`)}function be(t){if(!t||typeof t!=`object`||Array.isArray(t))throw new e(`COMMAND_FAILED`,`Cloud connection profile remoteConfigProfile is invalid.`);if(Object.keys(t).length===0)throw new e(`COMMAND_FAILED`,`Cloud connection profile remoteConfigProfile is empty.`);return t}function M(e){let t=xe(e.provider)(e),n=j(e.provider,e.stateDir,e.flags.session,t.device),r={tenant:e.flags.tenant??e.provider,sessionIsolation:e.flags.sessionIsolation??`tenant`,runId:e.flags.runId??`${e.provider}-${n}`,leaseProvider:e.provider,clientId:n,leaseBackend:e.flags.leaseBackend??h(e.flags),target:e.flags.target??`mobile`,session:e.flags.session,...t,...b(e.flags)};return k({stateDir:e.stateDir,provider:e.provider,profile:r,cwd:e.cwd,env:e.env,flags:e.flags})}const N=[{provider:u.browserStack,buildProfileFields:Se},{provider:u.awsDeviceFarm,buildProfileFields:we}];function xe(t){let n=N.find(e=>e.provider===t)?.buildProfileFields;if(n)return n;throw new e(`INVALID_ARGS`,`Unsupported cloud WebDriver provider "${t}".`)}function Se(e){return I(e.env,`BROWSERSTACK_USERNAME`,`connect browserstack`),I(e.env,`BROWSERSTACK_ACCESS_KEY`,`connect browserstack`),{platform:P(e.flags.platform,`connect browserstack requires --platform ios|android.`),device:F(e.flags.device,`connect browserstack requires --device <name>.`),providerOsVersion:F(e.flags.providerOsVersion,`connect browserstack requires --provider-os-version <version>.`),providerApp:Ce(F(e.flags.providerApp,`connect browserstack requires --provider-app <bs://app-id-or-local-path>.`),e.cwd),providerProject:e.flags.providerProject,providerBuild:e.flags.providerBuild,providerSessionName:e.flags.providerSessionName,..._(e.flags)}}function Ce(t,n){if(t.startsWith(`bs://`)||/^https?:\/\//i.test(t))return t;let r=E.resolve(n,t);try{if(D.statSync(r).isFile())return r}catch{}throw new e(`INVALID_ARGS`,`BrowserStack app file not found: ${r}`)}function we(e){let{env:t,flags:n}=e;c(n,u.awsDeviceFarm);let r=P(n.platform,`connect aws-device-farm requires --platform ios|android.`),i=L(n.awsProjectArn,t,[`AGENT_DEVICE_AWS_DEVICE_FARM_PROJECT_ARN`,`AWS_DEVICE_FARM_PROJECT_ARN`],`connect aws-device-farm requires --aws-project-arn <arn> or AWS_DEVICE_FARM_PROJECT_ARN.`);return{platform:r,device:n.device,awsProjectArn:i,awsDeviceArn:L(n.awsDeviceArn,t,[`AGENT_DEVICE_AWS_DEVICE_FARM_DEVICE_ARN`,`AWS_DEVICE_FARM_DEVICE_ARN`],`connect aws-device-farm requires --aws-device-arn <arn> or AWS_DEVICE_FARM_DEVICE_ARN.`),awsAppArn:R(n.awsAppArn,t,[`AGENT_DEVICE_AWS_DEVICE_FARM_APP_ARN`,`AWS_DEVICE_FARM_APP_ARN`]),awsRegion:R(n.awsRegion,t,[`AWS_REGION`,`AWS_DEFAULT_REGION`])??s(i),awsInteractionMode:n.awsInteractionMode,providerSessionName:n.providerSessionName}}function P(t,n){if(t===`android`||t===`ios`)return t;throw new e(`INVALID_ARGS`,n)}function F(t,n){if(t)return t;throw new e(`INVALID_ARGS`,n)}function I(t,n,r){let i=t?.[n];if(i)return i;throw new e(`INVALID_ARGS`,`${r} requires ${n} in the environment.`)}function L(e,t,n,r){return F(R(e,t,n),r)}function R(e,t,n){return e||n.map(e=>t?.[e]).find(e=>!!e)}function Te(t){let n=t.env??process.env;if(!n.LIMRUN_API_KEY?.trim())throw new e(`INVALID_ARGS`,`connect limrun requires LIMRUN_API_KEY.`,{hint:`Set LIMRUN_API_KEY in the environment before running agent-device connect limrun.`});let r=Ee({flags:t.flags});return k({stateDir:t.stateDir,provider:`limrun`,profile:r,cwd:t.cwd,env:n,flags:t.flags})}function Ee(e){let t=e.flags,n=De(t);return{stateDir:i(t.stateDir).baseDir,daemonTransport:`auto`,tenant:t.tenant??`limrun`,runId:t.runId??`cli-${Date.now().toString(36)}`,sessionIsolation:`tenant`,leaseBackend:n,leaseProvider:`limrun`,platform:t.platform,target:`mobile`,session:t.session,...b(t)}}function De(t){if(t.platform!==`android`&&t.platform!==`ios`)throw new e(`INVALID_ARGS`,`connect limrun requires --platform ios or android.`);if(t.device!==void 0)throw new e(`INVALID_ARGS`,`connect limrun does not accept --device; Limrun selects a remote simulator or emulator.`);let n=h(t),r=t.platform===`ios`?`ios-instance`:`android-instance`;if(n!==r)throw new e(`INVALID_ARGS`,`connect limrun --platform ${t.platform} requires --lease-backend ${r}.`);return r}function Oe(t){let n=t.flags.daemonBaseUrl??t.env?.AGENT_DEVICE_DAEMON_BASE_URL;if(!n)throw new e(`INVALID_ARGS`,`connect proxy requires --daemon-base-url <url> or AGENT_DEVICE_DAEMON_BASE_URL.`);let r=j(t.stateDir,n,t.flags.session),i={daemonBaseUrl:n,daemonTransport:t.flags.daemonTransport??`http`,daemonServerMode:t.flags.daemonServerMode,tenant:t.flags.tenant??`proxy`,sessionIsolation:t.flags.sessionIsolation??`tenant`,runId:t.flags.runId??`proxy-${r}`,leaseProvider:`proxy`,clientId:r,leaseBackend:t.flags.leaseBackend??h(t.flags),platform:t.flags.platform,target:t.flags.target,device:t.flags.device,udid:t.flags.udid,serial:t.flags.serial,iosSimulatorDeviceSet:t.flags.iosSimulatorDeviceSet,androidDeviceAllowlist:t.flags.androidDeviceAllowlist,session:t.flags.session,...b(t.flags)};return k({stateDir:t.stateDir,provider:`proxy`,profile:i,cwd:t.cwd,env:t.env,flags:t.flags,extraFlags:{daemonBaseUrl:n,daemonTransport:t.flags.daemonTransport??`http`}})}const z={cloud:{resolve:_e,verify:async()=>({service:`the configured cloud service`,status:`verified`,verificationMessage:`Credentials and connection profile verified.`})},proxy:{resolve:Oe,verify:async()=>({service:`Agent Device Proxy`,status:`configured`,verificationMessage:`Proxy configuration saved. Access is checked by the first remote command.`})},browserstack:{resolve:e=>M({provider:`browserstack`,...e}),verify:je},"aws-device-farm":{resolve:e=>M({provider:`aws-device-farm`,...e}),verify:Me},limrun:{resolve:Te,verify:Ne}};async function ke(e){let t=e.cwd??process.cwd(),n=e.env??process.env;if(e.flags.remoteConfig){let r=a({configPath:e.flags.remoteConfig,cwd:t,env:n}),i=r.profile.leaseProvider;return{flags:{...S(r.profile),...e.flags,remoteConfig:r.resolvedPath},remoteConfigPath:r.resolvedPath,...y(i)?{provider:i}:{}}}let r=e.provider??(Pe(e.flags)?`proxy`:`cloud`);return{...await z[r].resolve({flags:e.flags,stateDir:e.stateDir,cwd:t,env:n}),provider:r}}async function Ae(e){return e.provider?await z[e.provider].verify({flags:e.flags,env:process.env}):{service:`remote provider`,status:`configured`,verificationMessage:`Remote connection profile loaded. Access is checked by the first remote command.`}}async function je(e){let{flags:t,env:n}=e;return await l.verifyConnection({provider:`browserstack`,username:B(n.BROWSERSTACK_USERNAME,`BrowserStack profile missed BROWSERSTACK_USERNAME.`),accessKey:B(n.BROWSERSTACK_ACCESS_KEY,`BrowserStack profile missed BROWSERSTACK_ACCESS_KEY.`),platform:V(t.platform,`BrowserStack`),deviceName:B(t.device,`BrowserStack profile missed device.`),osVersion:B(t.providerOsVersion,`BrowserStack profile missed OS version.`),app:B(t.providerApp,`BrowserStack profile missed app.`)})}async function Me(e){let{flags:t}=e;return await l.verifyConnection({provider:`aws-device-farm`,platform:V(t.platform,`AWS Device Farm`),projectArn:B(t.awsProjectArn,`AWS Device Farm profile missed project ARN.`),deviceArn:B(t.awsDeviceArn,`AWS Device Farm profile missed device ARN.`),appArn:t.awsAppArn,region:t.awsRegion})}async function Ne(e){return await o({apiKey:B(e.env.LIMRUN_API_KEY,`Limrun profile missed LIMRUN_API_KEY.`),clientVersion:r(),platform:V(e.flags.platform,`Limrun`),region:e.env.LIMRUN_REGION?.trim()||void 0})}function Pe(e){if(!e.daemonBaseUrl||e.tenant||e.runId||e.leaseId||e.leaseBackend)return!1;try{return new URL(e.daemonBaseUrl).pathname.replace(/\/+$/,``).endsWith(`/agent-device`)}catch{return!1}}function B(t,n){if(t!==void 0)return t;throw new e(`COMMAND_FAILED`,n,{hint:`Reconnect to regenerate and validate the provider profile.`})}function V(t,n){if(t===`android`||t===`ios`)return t;throw new e(`COMMAND_FAILED`,`${n} profile missed a mobile platform.`,{hint:`Reconnect with --platform ios|android.`})}function Fe(e){let{stateDir:t,flags:n,remoteConfigPath:r}=e,i=n.session??Ie();return{session:i,previous:n.session?w({stateDir:t,session:i}):null,remoteConfigHash:oe(r),daemon:te(n)}}function Ie(){return`adc-${O.randomBytes(16).toString(`hex`)}`}function H(e,t){if(e.leaseId)return;let n=v(e.leaseProvider),r=n.leaseKind;if(r===`proxy`)return{status:`deferred`,nextSteps:W(e,t).nextSteps,message:`No live device session has been created. Run devices to inspect inventory without allocating, then open when ready.`};if(n.supportsDeferredAppSelection)return{status:`deferred`,nextSteps:W(e,t).nextSteps,message:`No live device session has been created. Run apps to inspect uploaded assets without allocating; open <uploaded-asset-name> creates the instance.`};if(r===`direct-device-provider`)return{status:`deferred`,nextSteps:W(e,t).nextSteps,message:`No live device session has been created. The first device command shown below will allocate one.`};let i=e.platform===void 0&&e.leaseBackend===void 0?` Add --platform ios|android if the profile does not set a platform.`:``;return{status:`deferred`,nextSteps:K(e,[`agent-device install-from-source <artifact-url> --platform ios|android`,`agent-device open <app-id> --relaunch`,`agent-device snapshot -i`,`agent-device devices`]),message:`No live device session has been created. Run a device command when ready to allocate or refresh the lease.`+i}}function Le(e,t){return{...t,preparationMessage:H(e,t)?.message??`No live device session has been created.`,...W(e,t)}}function Re(e){let{state:t,readiness:n,runtimePreparation:r,previousLeaseNotice:i}=e;if(!n){let e=H(t);return[`Configured remote session "${t.session}" tenant "${t.tenant}" run "${t.runId}"${t.leaseId?` lease ${t.leaseId}`:``}.`,e?.message,r?.message,i?.message].filter(e=>!!e).join(`
|
|
2
2
|
`)}let a=G(n),o=[`${a===`verified`?`Connected`:`Configured`} successfully with ${n.service}.`,`${a===`verified`?`Verified`:`Status`}: ${n.verificationMessage}`];return n.project&&o.push(`Project: ${n.project.name??n.project.reference} — verified`),n.device&&o.push(He(n.device)),n.app&&o.push(Ue(t,n.app)),o.push(n.preparationMessage),o.push(`Next:`),o.push(...n.nextSteps.map(e=>` ${e}`)),o.push(...n.notes??[]),r&&o.push(r.message),i&&o.push(i.message),o.join(`
|
|
3
3
|
`)}function U(e){let{state:t,runtimePreparation:n,readiness:r,previousLeaseNotice:i}=e,a=H(t,r);return{connected:!0,session:t.session,tenant:t.tenant,runId:t.runId,leaseAllocated:!!t.leaseId,leaseId:t.leaseId,leaseBackend:t.leaseBackend,leaseProvider:t.leaseProvider,platform:t.platform,target:t.target,remoteConfig:t.remoteConfigPath,remoteConfigHash:t.remoteConfigHash,daemonBaseUrlFingerprint:m(t.daemon?.baseUrl),liveSession:ze(t),...Be(r,a),metro:t.metro?{prepared:!0,projectRoot:t.metro.projectRoot}:{prepared:!1},...Ve({leasePreparation:a,runtimePreparation:n,previousLeaseNotice:i}),connectedAt:t.connectedAt,updatedAt:t.updatedAt}}function ze(e){return{status:e.leaseId?`created`:`not-created`,...e.leaseId?{leaseId:e.leaseId}:{}}}function Be(e,t){return e?{verification:{status:G(e),service:e.service,message:e.verificationMessage,...e.project?{project:e.project}:{}},...e.device?{device:e.device}:{},...e.app?{app:e.app}:{},nextSteps:e.nextSteps??t?.nextSteps??[],...e.notes?{notes:e.notes}:{}}:{}}function Ve(e){let{leasePreparation:t,runtimePreparation:n,previousLeaseNotice:r}=e;return{...t?{leasePreparation:t}:{},...n?{runtimePreparation:n}:{},...r?{previousLeaseNotice:r}:{}}}function He(e){let t=`osVersion`in e?e.osVersion:void 0,n=[e.platform,t].filter(Boolean).join(` `),r=n?` (${n})`:``;return e.status===`deferred`?`Device: ${e.name??`Provider-selected device`} — allocated on first device command`:`Device: ${e.name??e.reference??`Configured device`}${r} — verified`}function Ue(e,t){return t.status===`missing`?`App: ${Qe(e)} — ${t.message??`Install or attach an app before open.`}`:`App: ${t.name??t.reference??`configured app`} — ${t.status===`verified`?`verified`:t.message??`configured`}`}function W(e,t){let n=We(e,t);return{...n,nextSteps:K(e,n.nextSteps)}}function We(e,t){let n=v(e.leaseProvider).leaseKind;if(n===`proxy`)return{nextSteps:[`agent-device devices`,`agent-device open ${J(e.platform)} --relaunch`]};if(!t&&n===`direct-device-provider`)return{nextSteps:Ze()};if(v(t?.provider).supportsDeferredAppSelection)return{nextSteps:[`agent-device apps`,`agent-device open <uploaded-asset-name>`]};let r=t?.app?.status===`missing`;return{nextSteps:Ge(t)?Xe(e):[...qe(t),...Ye(e).nextSteps],...Ke(t)?{notes:Je(e,!r)}:{}}}function Ge(e){return e?.app?.status===`missing`&&e.device?.status===`deferred`}function Ke(e){return v(e?.provider).supportsArtifacts}function qe(e){return e?.app?.status!==`missing`||!e.project?.reference||!e.device?.reference?[]:[`agent-device connect aws-device-farm --platform ${e.device.platform} --aws-project-arn ${e.project.reference} --aws-device-arn ${e.device.reference} --aws-app-arn <arn> --force`]}function Je(e,t){return[...t?[`Use the installed package or bundle identifier in open, not the app artifact name.`]:[],`After close, run ${q(e,`agent-device artifacts --json`)} for provider video and logs.`]}function Ye(e){return{nextSteps:[`agent-device open ${J(e.platform)} --relaunch`]}}function Xe(e){let t=J(e.platform);return[`agent-device install ${t} <app-path-or-url>`,`agent-device open ${t} --relaunch`]}function G(e){return`status`in e?e.status:`verified`}function Ze(){return[`agent-device open <package-or-bundle-id> --relaunch`,`agent-device snapshot -i`,`agent-device close`,`agent-device artifacts --json`]}function K(e,t){return t.map(t=>q(e,t))}function q(e,t){return`${t} --session ${n(e.session)}`}function J(e){return e===`ios`?`<bundle-id>`:`<package-id>`}function Qe(e){let t=v(e.leaseProvider);return t.requiresAppAttachment?`not attached`:t.supportsDeferredAppSelection?`not installed yet`:`not available`}const $e=async({positionals:e,flags:t,client:n})=>{let r=i(t.stateDir).baseDir,a=ht(e);et(a,t);let o=await ke({provider:a,flags:t,stateDir:r}),s=o.flags,c=ct(o.remoteConfigPath),l=tt(s,c),u=Fe({stateDir:r,flags:s,remoteConfigPath:o.remoteConfigPath});nt(u.previous,{flags:s,session:u.session,remoteConfigPath:o.remoteConfigPath,remoteConfigHash:u.remoteConfigHash,desiredLeaseBackend:h(s),connection:c,daemon:u.daemon});let d=await Ae(o),f=rt({flags:s,scope:l,connectionMetadata:c,context:u,remoteConfigPath:o.remoteConfigPath});p({stateDir:r,state:f});let m=await st(n,r,s,u.previous,f.daemon?.baseUrl),g=bt(s,f),_=Le(f,d);return await T(s,U({state:f,runtimePreparation:g,readiness:_,previousLeaseNotice:m}),()=>Re({state:f,runtimePreparation:g,readiness:_,previousLeaseNotice:m})),!0};function et(t,n){if(!(!t||!n.remoteConfig))throw new e(`INVALID_ARGS`,`connect provider positional and --remote-config are mutually exclusive.`)}function tt(t,n){if(!t.tenant)throw new e(`INVALID_ARGS`,`connect requires tenant in remote config or via --tenant <id>.`);if(!t.runId)throw new e(`INVALID_ARGS`,`connect requires runId in remote config or via --run-id <id>.`);if(!t.daemonBaseUrl&&v(n?.leaseProvider).requiresRemoteDaemon)throw new e(`INVALID_ARGS`,`connect requires daemonBaseUrl in remote config, config, env, or --daemon-base-url.`);return{tenant:t.tenant,runId:t.runId}}function nt(t,n){if(!(!t||gt(t,n))&&!n.flags.force)throw new e(`INVALID_ARGS`,`A different remote connection is already active for this session. Re-run connect with --force to replace it.`,{session:n.session,remoteConfig:t.remoteConfigPath})}function rt(e){let{flags:t,scope:n,connectionMetadata:r,context:i,remoteConfigPath:a}=e,o=ot(t,i.previous)?i.previous:null,s=new Date().toISOString(),c=it(t,o,r),l=at(t,o,s);return{version:1,session:i.session,remoteConfigPath:a,remoteConfigHash:i.remoteConfigHash,daemon:i.daemon,tenant:n.tenant,runId:n.runId,...c,...l,updatedAt:s}}function it(e,t,n){let r=se(n??{},t??{});return{leaseId:t?.leaseId,leaseBackend:t?.leaseBackend??h(e),...r,deviceKey:t?.deviceKey??r.deviceKey}}function at(e,t,n){return{platform:e.platform??t?.platform,target:e.target??t?.target,runtime:t?.runtime,metro:t?.metro,connectedAt:t?.connectedAt??n}}function ot(e,t){return!!(t&&!e.force)}async function st(e,t,n,r,i){if(!(!r||!n.force))return await x(r.metro),await C({stateDir:t,state:r}),await re(e,r,{nextDaemonBaseUrl:i,ambientDaemonAuthToken:n.daemonAuthToken,cwd:process.cwd(),env:process.env})}function ct(e){let t=a({configPath:e,cwd:process.cwd(),env:process.env}).profile;return ee(t)}const lt=async({flags:e,client:t})=>{let{session:n,stateDir:r,state:i}=Y(e);if(!i)return await X(e,n),!0;let a=i.session,o;if(i.leaseId||i.runtime||i.metro)try{o=(await t.sessions.close({session:a,shutdown:e.shutdown})).provider}catch{}await x(i.metro),await C({stateDir:r,state:i});let s=!1;if(i.leaseId)try{let n=await ne(t,i,e.daemonAuthToken);s=n.released,o??=n.provider}catch{}return d({stateDir:r,session:a}),await T(e,{connected:!1,session:a,released:s,...o?{provider:o}:{}},()=>dt(a,o)),!0},ut=async({positionals:t,flags:n})=>{if(t[0]!==`status`)throw new e(`INVALID_ARGS`,`connection accepts only: status`);let{session:r,state:i}=Y(n);if(!i)return await X(n,r),!0;let a=H(i),o=Z(i);return await T(n,U({state:i,runtimePreparation:o}),()=>[`Configured remote session "${i.session}".`,`tenant=${i.tenant} runId=${i.runId} leaseId=${i.leaseId??`pending`} backend=${i.leaseBackend??`pending`}`,`remoteConfig=${i.remoteConfigPath}`,i.runtime?`metro=prepared`:`metro=not-prepared`,a?.message,o?.message].filter(e=>!!e).join(`
|
|
4
4
|
`)),!0};function dt(e,t){return[`Disconnected remote session "${e}".`,...ft(t),...mt(t?.cloudArtifacts?.cloudArtifacts)].join(`
|
package/dist/src/contracts.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { B as
|
|
1
|
+
import { B as centerOfRect, H as DaemonError, W as defaultHintForCode, a as DaemonRequest, d as JsonRpcRequestEnvelope, f as LeaseBackend, o as DaemonResponse, q as normalizeError, r as DaemonInstallSource, s as DaemonResponseData, u as JsonRpcId, v as SessionRuntimeHints } from "./sdk-contracts.js";
|
|
2
2
|
export { type DaemonError, type DaemonInstallSource, type DaemonRequest, type DaemonResponse, type DaemonResponseData, type JsonRpcId, type JsonRpcRequestEnvelope, type LeaseBackend, type SessionRuntimeHints, centerOfRect, defaultHintForCode, normalizeError };
|
package/dist/src/contracts.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{A as e,L as t,g as n}from"./sdk-contracts.js";export{n as centerOfRect,e as defaultHintForCode,t as normalizeError};
|