agent-device 0.21.6 → 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.6.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.6.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.6.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.6.manifest.json → agent-device-android-snapshot-helper-0.21.7.manifest.json} +6 -6
- 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 -1
- package/dist/src/adb.js +1 -1
- package/dist/src/agent-browser-lifecycle.js +1 -1
- package/dist/src/agent-browser-process-record.js +1 -1
- package/dist/src/agent-browser-provider.js +1 -1
- package/dist/src/agent-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 +2 -2
- package/dist/src/app-lifecycle2.js +2 -2
- package/dist/src/app-log-files.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 +4 -4
- 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.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/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 +1 -1
- 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 +2 -1
- package/server.json +2 -2
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.6.apk.sha256 +0 -1
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.6.apk.sha256 +0 -1
- package/dist/src/session-target-evidence.js +0 -1
- package/dist/src/vars.js +0 -2
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import CoreGraphics
|
|
3
|
+
|
|
4
|
+
// Rotation between an app's interface space and the device's native (portrait-up) space, shared by
|
|
5
|
+
// synthesized dispatch (forward) and capture (inverse). Rationale and measurements: ADR 0004
|
|
6
|
+
// "the coordinate space of a captured subtree" and contracts/fixtures/window-coordinate-space.json.
|
|
7
|
+
|
|
8
|
+
public enum RunnerInterfaceOrientation {
|
|
9
|
+
public static let unknown = 0
|
|
10
|
+
public static let portrait = 1
|
|
11
|
+
public static let portraitUpsideDown = 2
|
|
12
|
+
public static let landscapeRight = 3
|
|
13
|
+
public static let landscapeLeft = 4
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
public enum CoordinateSpaceRotation {
|
|
17
|
+
public static func native(
|
|
18
|
+
point: CGPoint,
|
|
19
|
+
in frame: CGRect,
|
|
20
|
+
interfaceOrientation: Int
|
|
21
|
+
) -> CGPoint {
|
|
22
|
+
let localX = Double(point.x) - Double(frame.minX)
|
|
23
|
+
let localY = Double(point.y) - Double(frame.minY)
|
|
24
|
+
let width = Double(frame.width)
|
|
25
|
+
let height = Double(frame.height)
|
|
26
|
+
switch interfaceOrientation {
|
|
27
|
+
case RunnerInterfaceOrientation.landscapeRight:
|
|
28
|
+
return CGPoint(x: height - localY, y: localX)
|
|
29
|
+
case RunnerInterfaceOrientation.landscapeLeft:
|
|
30
|
+
return CGPoint(x: localY, y: width - localX)
|
|
31
|
+
case RunnerInterfaceOrientation.portraitUpsideDown:
|
|
32
|
+
return CGPoint(x: width - localX, y: height - localY)
|
|
33
|
+
default:
|
|
34
|
+
return CGPoint(x: localX, y: localY)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public static func native(vector: CGVector, interfaceOrientation: Int) -> CGVector {
|
|
39
|
+
switch interfaceOrientation {
|
|
40
|
+
case RunnerInterfaceOrientation.landscapeRight:
|
|
41
|
+
return CGVector(dx: -vector.dy, dy: vector.dx)
|
|
42
|
+
case RunnerInterfaceOrientation.landscapeLeft:
|
|
43
|
+
return CGVector(dx: vector.dy, dy: -vector.dx)
|
|
44
|
+
case RunnerInterfaceOrientation.portraitUpsideDown:
|
|
45
|
+
return CGVector(dx: -vector.dx, dy: -vector.dy)
|
|
46
|
+
default:
|
|
47
|
+
return vector
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
public static func oriented(
|
|
52
|
+
point: CGPoint,
|
|
53
|
+
in frame: CGRect,
|
|
54
|
+
interfaceOrientation: Int
|
|
55
|
+
) -> CGPoint {
|
|
56
|
+
let width = Double(frame.width)
|
|
57
|
+
let height = Double(frame.height)
|
|
58
|
+
let localX: Double
|
|
59
|
+
let localY: Double
|
|
60
|
+
switch interfaceOrientation {
|
|
61
|
+
case RunnerInterfaceOrientation.landscapeRight:
|
|
62
|
+
localX = Double(point.y)
|
|
63
|
+
localY = height - Double(point.x)
|
|
64
|
+
case RunnerInterfaceOrientation.landscapeLeft:
|
|
65
|
+
localX = width - Double(point.y)
|
|
66
|
+
localY = Double(point.x)
|
|
67
|
+
case RunnerInterfaceOrientation.portraitUpsideDown:
|
|
68
|
+
localX = width - Double(point.x)
|
|
69
|
+
localY = height - Double(point.y)
|
|
70
|
+
default:
|
|
71
|
+
localX = Double(point.x)
|
|
72
|
+
localY = Double(point.y)
|
|
73
|
+
}
|
|
74
|
+
return CGPoint(x: localX + Double(frame.minX), y: localY + Double(frame.minY))
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
public static func oriented(
|
|
78
|
+
rect: CGRect,
|
|
79
|
+
in frame: CGRect,
|
|
80
|
+
interfaceOrientation: Int
|
|
81
|
+
) -> CGRect {
|
|
82
|
+
let leading = oriented(
|
|
83
|
+
point: CGPoint(x: rect.minX, y: rect.minY),
|
|
84
|
+
in: frame,
|
|
85
|
+
interfaceOrientation: interfaceOrientation
|
|
86
|
+
)
|
|
87
|
+
let trailing = oriented(
|
|
88
|
+
point: CGPoint(x: rect.maxX, y: rect.maxY),
|
|
89
|
+
in: frame,
|
|
90
|
+
interfaceOrientation: interfaceOrientation
|
|
91
|
+
)
|
|
92
|
+
return CGRect(
|
|
93
|
+
x: min(leading.x, trailing.x),
|
|
94
|
+
y: min(leading.y, trailing.y),
|
|
95
|
+
width: abs(trailing.x - leading.x),
|
|
96
|
+
height: abs(trailing.y - leading.y)
|
|
97
|
+
)
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
public enum SnapshotGeometrySpace: Equatable {
|
|
102
|
+
case appOrientation
|
|
103
|
+
case deviceNative(appFrame: CGRect, interfaceOrientation: Int)
|
|
104
|
+
|
|
105
|
+
public static let quarterTurnTolerance: Double = 1
|
|
106
|
+
|
|
107
|
+
public func orientedFrame(of reportedFrame: CGRect) -> CGRect {
|
|
108
|
+
switch self {
|
|
109
|
+
case .appOrientation:
|
|
110
|
+
return reportedFrame
|
|
111
|
+
case .deviceNative(let appFrame, let interfaceOrientation):
|
|
112
|
+
return CoordinateSpaceRotation.oriented(
|
|
113
|
+
rect: reportedFrame,
|
|
114
|
+
in: appFrame,
|
|
115
|
+
interfaceOrientation: interfaceOrientation
|
|
116
|
+
)
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
public static func space(
|
|
121
|
+
reportedBySurfaceHost isSurfaceHost: Bool,
|
|
122
|
+
reportedFrame: CGRect,
|
|
123
|
+
inheritedFrom inherited: SnapshotGeometrySpace,
|
|
124
|
+
appFrame: CGRect,
|
|
125
|
+
interfaceOrientation: Int
|
|
126
|
+
) -> SnapshotGeometrySpace {
|
|
127
|
+
guard isSurfaceHost else { return inherited }
|
|
128
|
+
guard namesQuarterTurn(interfaceOrientation) else { return .appOrientation }
|
|
129
|
+
guard isQuarterTurned(reportedFrame, relativeTo: appFrame) else { return .appOrientation }
|
|
130
|
+
return .deviceNative(appFrame: appFrame, interfaceOrientation: interfaceOrientation)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
public static func namesQuarterTurn(_ interfaceOrientation: Int) -> Bool {
|
|
134
|
+
interfaceOrientation == RunnerInterfaceOrientation.landscapeLeft
|
|
135
|
+
|| interfaceOrientation == RunnerInterfaceOrientation.landscapeRight
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
public static func isSurfaceHost(isWindow: Bool, parentIsWindow: Bool) -> Bool {
|
|
139
|
+
isWindow || parentIsWindow
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
private static func isQuarterTurned(_ frame: CGRect, relativeTo appFrame: CGRect) -> Bool {
|
|
143
|
+
guard isPlottable(frame), isPlottable(appFrame),
|
|
144
|
+
abs(appFrame.width - appFrame.height) > quarterTurnTolerance
|
|
145
|
+
else {
|
|
146
|
+
return false
|
|
147
|
+
}
|
|
148
|
+
return abs(frame.width - appFrame.height) <= quarterTurnTolerance
|
|
149
|
+
&& abs(frame.height - appFrame.width) <= quarterTurnTolerance
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
private static func isPlottable(_ frame: CGRect) -> Bool {
|
|
153
|
+
frame.origin.x.isFinite && frame.origin.y.isFinite
|
|
154
|
+
&& frame.width.isFinite && frame.height.isFinite
|
|
155
|
+
&& frame.width > 0 && frame.height > 0
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
extension SnapshotGeometrySpace {
|
|
160
|
+
public static func normalized(
|
|
161
|
+
nodes: [RawAXNode],
|
|
162
|
+
viewport: CGRect,
|
|
163
|
+
interfaceOrientation: Int
|
|
164
|
+
) -> [RawAXNode] {
|
|
165
|
+
let carriers = SnapshotVisibilityFold.visibilityExemptCarrierTypes
|
|
166
|
+
var spaces = [SnapshotGeometrySpace](repeating: .appOrientation, count: nodes.count)
|
|
167
|
+
var result: [RawAXNode] = []
|
|
168
|
+
result.reserveCapacity(nodes.count)
|
|
169
|
+
for (position, node) in nodes.enumerated() {
|
|
170
|
+
let parentIndex = node.parentIndex.flatMap { $0 >= 0 && $0 < position ? $0 : nil }
|
|
171
|
+
let nodeSpace = space(
|
|
172
|
+
reportedBySurfaceHost: isSurfaceHost(
|
|
173
|
+
isWindow: carriers.contains(node.type),
|
|
174
|
+
parentIsWindow: parentIndex.map { carriers.contains(nodes[$0].type) } ?? false
|
|
175
|
+
),
|
|
176
|
+
reportedFrame: node.rect.cgRect,
|
|
177
|
+
inheritedFrom: parentIndex.map { spaces[$0] } ?? .appOrientation,
|
|
178
|
+
appFrame: viewport,
|
|
179
|
+
interfaceOrientation: interfaceOrientation
|
|
180
|
+
)
|
|
181
|
+
spaces[position] = nodeSpace
|
|
182
|
+
let frame = nodeSpace.orientedFrame(of: node.rect.cgRect)
|
|
183
|
+
result.append(
|
|
184
|
+
node.replacing(
|
|
185
|
+
rect: SnapshotRect(frame),
|
|
186
|
+
hittable: node.parentIndex != nil
|
|
187
|
+
&& SnapshotGeometry.isGeometricallyActionable(
|
|
188
|
+
enabled: node.enabled,
|
|
189
|
+
frame: frame,
|
|
190
|
+
viewport: viewport
|
|
191
|
+
)
|
|
192
|
+
)
|
|
193
|
+
)
|
|
194
|
+
}
|
|
195
|
+
return result
|
|
196
|
+
}
|
|
197
|
+
}
|
|
@@ -17,6 +17,15 @@ public struct SnapshotRect: Codable, Equatable {
|
|
|
17
17
|
public var cgRect: CGRect {
|
|
18
18
|
CGRect(x: x, y: y, width: width, height: height)
|
|
19
19
|
}
|
|
20
|
+
|
|
21
|
+
public init(_ rect: CGRect) {
|
|
22
|
+
self.init(
|
|
23
|
+
x: Double(rect.origin.x),
|
|
24
|
+
y: Double(rect.origin.y),
|
|
25
|
+
width: Double(rect.size.width),
|
|
26
|
+
height: Double(rect.size.height)
|
|
27
|
+
)
|
|
28
|
+
}
|
|
20
29
|
}
|
|
21
30
|
|
|
22
31
|
public struct RawAXNode: Equatable {
|
|
@@ -25,11 +34,11 @@ public struct RawAXNode: Equatable {
|
|
|
25
34
|
public let label: String?
|
|
26
35
|
public let identifier: String?
|
|
27
36
|
public let value: String?
|
|
28
|
-
public
|
|
37
|
+
public var rect: SnapshotRect
|
|
29
38
|
public let enabled: Bool
|
|
30
39
|
public let focused: Bool?
|
|
31
40
|
public let selected: Bool?
|
|
32
|
-
public
|
|
41
|
+
public var hittable: Bool
|
|
33
42
|
public let depth: Int
|
|
34
43
|
public let parentIndex: Int?
|
|
35
44
|
public let hiddenContentAbove: Bool?
|
|
@@ -70,6 +79,13 @@ public struct RawAXNode: Equatable {
|
|
|
70
79
|
self.actions = actions
|
|
71
80
|
}
|
|
72
81
|
|
|
82
|
+
func replacing(rect: SnapshotRect, hittable: Bool) -> RawAXNode {
|
|
83
|
+
var updated = self
|
|
84
|
+
updated.rect = rect
|
|
85
|
+
updated.hittable = hittable
|
|
86
|
+
return updated
|
|
87
|
+
}
|
|
88
|
+
|
|
73
89
|
public var hasSemanticContent: Bool {
|
|
74
90
|
[label, identifier, value].contains {
|
|
75
91
|
!($0?.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty ?? true)
|
|
@@ -139,11 +155,13 @@ public struct PresentationOptions: Equatable {
|
|
|
139
155
|
|
|
140
156
|
public struct SnapshotAcquisition {
|
|
141
157
|
public let hint: CaptureHint
|
|
142
|
-
public
|
|
158
|
+
public var nodes: [RawAXNode]
|
|
143
159
|
public let truncated: Bool
|
|
144
160
|
public let effectiveDepth: Int?
|
|
145
161
|
public var customActions: SnapshotCustomActionCoverage?
|
|
146
162
|
public let viewport: CGRect
|
|
163
|
+
/// The app's interface orientation, consumed by the one `normalized` pass; `unknown` turns nothing.
|
|
164
|
+
public let interfaceOrientation: Int
|
|
147
165
|
|
|
148
166
|
public init(
|
|
149
167
|
hint: CaptureHint,
|
|
@@ -151,7 +169,8 @@ public struct SnapshotAcquisition {
|
|
|
151
169
|
truncated: Bool,
|
|
152
170
|
effectiveDepth: Int?,
|
|
153
171
|
customActions: SnapshotCustomActionCoverage? = nil,
|
|
154
|
-
viewport: CGRect
|
|
172
|
+
viewport: CGRect,
|
|
173
|
+
interfaceOrientation: Int = 0
|
|
155
174
|
) {
|
|
156
175
|
self.hint = hint
|
|
157
176
|
self.nodes = nodes
|
|
@@ -159,6 +178,13 @@ public struct SnapshotAcquisition {
|
|
|
159
178
|
self.effectiveDepth = effectiveDepth
|
|
160
179
|
self.customActions = customActions
|
|
161
180
|
self.viewport = viewport
|
|
181
|
+
self.interfaceOrientation = interfaceOrientation
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
public func replacingNodes(_ nodes: [RawAXNode]) -> SnapshotAcquisition {
|
|
185
|
+
var updated = self
|
|
186
|
+
updated.nodes = nodes
|
|
187
|
+
return updated
|
|
162
188
|
}
|
|
163
189
|
}
|
|
164
190
|
|
|
@@ -66,87 +66,6 @@ public enum SnapshotPresentation {
|
|
|
66
66
|
)
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
public static func shouldAcquireChildren(
|
|
70
|
-
for hint: CaptureHint,
|
|
71
|
-
rawDepth: Int,
|
|
72
|
-
regularPresentedDepth: Int
|
|
73
|
-
) -> Bool {
|
|
74
|
-
if let rawLimit = hint.rawTraversalDepth {
|
|
75
|
-
return rawDepth < rawLimit
|
|
76
|
-
}
|
|
77
|
-
if let presentedLimit = hint.regularPresentedDepth {
|
|
78
|
-
return regularPresentedDepth < presentedLimit
|
|
79
|
-
}
|
|
80
|
-
return true
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
public static func regularTraversalTransition(
|
|
84
|
-
for raw: RawAXNode,
|
|
85
|
-
parentPresentedDepth: Int,
|
|
86
|
-
parentTraversal: SnapshotVisibilityFold.TraversalState,
|
|
87
|
-
hint: CaptureHint,
|
|
88
|
-
rawDepth: Int,
|
|
89
|
-
viewport: CGRect,
|
|
90
|
-
hasChildren: Bool,
|
|
91
|
-
isDuplicate: Bool,
|
|
92
|
-
policy: SnapshotVisibilityFold.Policy = .platformDefault
|
|
93
|
-
) -> (
|
|
94
|
-
presentedDepth: Int,
|
|
95
|
-
traversal: SnapshotVisibilityFold.TraversalState,
|
|
96
|
-
shouldVisitChildren: Bool
|
|
97
|
-
) {
|
|
98
|
-
guard hint.regularPresentedDepth != nil else {
|
|
99
|
-
return (
|
|
100
|
-
parentPresentedDepth,
|
|
101
|
-
parentTraversal,
|
|
102
|
-
shouldAcquireChildren(
|
|
103
|
-
for: hint,
|
|
104
|
-
rawDepth: rawDepth,
|
|
105
|
-
regularPresentedDepth: parentPresentedDepth
|
|
106
|
-
)
|
|
107
|
-
)
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
let visibility = SnapshotVisibilityFold.traversalDecision(
|
|
111
|
-
for: raw,
|
|
112
|
-
parent: parentTraversal,
|
|
113
|
-
viewport: viewport,
|
|
114
|
-
interactiveOnly: hint.interactiveOnly,
|
|
115
|
-
hasChildren: hasChildren,
|
|
116
|
-
policy: policy
|
|
117
|
-
)
|
|
118
|
-
let presentedDepth = regularPresentedDepth(
|
|
119
|
-
for: raw,
|
|
120
|
-
parentPresentedDepth: parentPresentedDepth,
|
|
121
|
-
visibility: visibility
|
|
122
|
-
)
|
|
123
|
-
let nextPresentedDepth = isDuplicate ? parentPresentedDepth : presentedDepth
|
|
124
|
-
let nextTraversal = isDuplicate ? parentTraversal : visibility.descendants
|
|
125
|
-
let descendantsMayBeVisible = isDuplicate
|
|
126
|
-
? parentTraversal.descendantsMayBeVisible
|
|
127
|
-
: visibility.descendantsMayBeVisible
|
|
128
|
-
return (
|
|
129
|
-
nextPresentedDepth,
|
|
130
|
-
nextTraversal,
|
|
131
|
-
shouldAcquireChildren(
|
|
132
|
-
for: hint,
|
|
133
|
-
rawDepth: rawDepth,
|
|
134
|
-
regularPresentedDepth: nextPresentedDepth
|
|
135
|
-
) && descendantsMayBeVisible
|
|
136
|
-
)
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
public static func regularPresentedDepth(
|
|
140
|
-
for raw: RawAXNode,
|
|
141
|
-
parentPresentedDepth: Int,
|
|
142
|
-
visibility: SnapshotVisibilityFold.TraversalDecision
|
|
143
|
-
) -> Int {
|
|
144
|
-
guard raw.parentIndex != nil else { return 0 }
|
|
145
|
-
return visibility.isIncluded && isEligibleForRegularPresentation(raw)
|
|
146
|
-
? parentPresentedDepth + 1
|
|
147
|
-
: parentPresentedDepth
|
|
148
|
-
}
|
|
149
|
-
|
|
150
69
|
public static func singleElementRead(_ node: RawAXNode) -> PresentedNode {
|
|
151
70
|
PresentedNode(presenting: node)
|
|
152
71
|
}
|
|
@@ -63,7 +63,7 @@ public enum SnapshotPresentationInvariant {
|
|
|
63
63
|
throw SnapshotPresentationFailure.regularNodeOutsideCumulativeClip(
|
|
64
64
|
index: node.raw.index,
|
|
65
65
|
frame: node.effectiveRect,
|
|
66
|
-
clip:
|
|
66
|
+
clip: SnapshotRect(ancestorClip)
|
|
67
67
|
)
|
|
68
68
|
}
|
|
69
69
|
}
|
|
@@ -80,12 +80,4 @@ public enum SnapshotPresentationInvariant {
|
|
|
80
80
|
&& frame.maxY <= clip.maxY + tolerance
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
private static func snapshotRect(from rect: CGRect) -> SnapshotRect {
|
|
84
|
-
SnapshotRect(
|
|
85
|
-
x: Double(rect.minX),
|
|
86
|
-
y: Double(rect.minY),
|
|
87
|
-
width: Double(rect.width),
|
|
88
|
-
height: Double(rect.height)
|
|
89
|
-
)
|
|
90
|
-
}
|
|
91
83
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{D as e,O as t}from"./sdk-contracts.js";import{Nr as n,Wn as r,er as i,kr as a}from"./sdk-batch.js";import{n as o}from"./scroll-indicator.js";function s(e){let t=f(e.label),n=f(e.value),r=f(e.identifier),i=m(r)?r:``;return p(e.type??``)?n||t||i:t||n||i}function c(e,t){if(t===`text-view`||t===`text-field`||t===`search`)return!0;let r=n(e.type??``),i=`${e.role??``} ${e.subrole??``}`.toLowerCase();return r.includes(`textview`)||r.includes(`textarea`)||r.includes(`textfield`)||r.includes(`securetextfield`)||r.includes(`searchfield`)||r.includes(`edittext`)||i.includes(`text area`)||i.includes(`text field`)}function l(e){let t=e.replaceAll(/\s+/g,` `).trim();return t.length<=48?t:`${t.slice(0,45)}...`}function u(e,t){let n=s(e),r=c(e,t);return{text:n,isLargeSurface:r,shouldSummarize:r&&d(n)}}function d(e){return e?e.length>80||/[\r\n]/.test(e):!1}function f(e){return typeof e==`string`?e.trim():``}function p(e){let t=n(e);return t.includes(`textfield`)||t.includes(`securetextfield`)||t.includes(`searchfield`)||t.includes(`edittext`)||t.includes(`textview`)||t.includes(`textarea`)}function m(e){return e?!/^[\w.]+:id\/[\w.-]+$/i.test(e)&&!/^_?NS:\d+$/i.test(e):!1}const h={application:`application`,navigationbar:`navigation-bar`,tabbar:`tab-bar`,button:`button`,imagebutton:`button`,link:`link`,cell:`cell`,statictext:`text`,checkedtextview:`text`,textbox:`text-field`,textfield:`text-field`,edittext:`text-field`,textarea:`text-view`,switch:`switch`,slider:`slider`,image:`image`,imageview:`image`,webview:`webview`,framelayout:`group`,linearlayout:`group`,relativelayout:`group`,constraintlayout:`group`,viewgroup:`group`,view:`group`,listview:`list`,recyclerview:`list`,collectionview:`collection`,searchfield:`search`,heading:`heading`,activityindicator:`activity-indicator`,progressindicator:`progress-indicator`,segmentedcontrol:`segmented-control`,group:`group`,window:`window`,checkbox:`checkbox`,radio:`radio`,menuitem:`menu-item`,toolbar:`toolbar`,scrollarea:`scroll-area`,scrollview:`scroll-area`,nestedscrollview:`scroll-area`,table:`table`};function g(e,t={}){let n=[],r=[];for(let i of e){let e=i.depth??0,a=i.label?.trim()||i.value?.trim()||i.identifier?.trim()||``,o=x(i.type??`Element`),s=i.inheritsLabel===!0||i.inheritsIdentifier===!0;if(o===`group`&&!a&&!s)continue;for(;n.length>0&&e<=n.at(-1);)n.pop();let c=n.length;n.push(e),r.push({node:i,depth:c,type:o,text:_(i,c,!1,o,t)})}return r}function _(e,t,n,r,i={}){let a=r??x(e.type??`Element`),o=u(e,a),s=E(e,a,i,o),c=` `.repeat(t),l=e.ref?`@${e.ref}`:``,d=D(e,a,i,o);!s&&(e.inheritsLabel===!0||e.inheritsIdentifier===!0)&&d.push(`same label as parent`);let f=d.map(e=>` [${e}]`).join(``),p=s?` "${s}"`:``,m=v(e);return n?`${c}${l} [${a}]${f}${m}`.trimEnd():`${c}${l} [${a}]${p}${f}${m}`.trimEnd()}function v(e){let t=e.actions?.filter(e=>e.trim().length>0);return!t||t.length===0?``:` actions: [${t.map(e=>`"${A(y(e))}"`).join(`, `)}]`}function y(e){return e.replaceAll(/\s+/g,` `).replaceAll(/[\u0000-\u001f\u007f-\u009f]/g,``).trim()}function b(e,t){let n=e.label?.trim();if(n&&w(t,n))return``;let r=e.value?.trim();if(C(t)){if(r)return r;if(n)return n}else if(n)return n;if(r)return r;let i=e.identifier?.trim();return!i||T(i)&&(t===`group`||t===`image`||t===`list`||t===`collection`)?``:i}function x(e){let t=e,n=e.replaceAll(/XCUIElementType/gi,``).toLowerCase(),r=t.includes(`.`)&&(t.startsWith(`android.`)||t.startsWith(`androidx.`)||t.startsWith(`com.`));return n.includes(`.`)&&(n=n.replace(/^android\.widget\./,``).replace(/^android\.view\./,``).replace(/^android\.webkit\./,``).replace(/^androidx\./,``).replace(/^com\.google\.android\./,``).replace(/^com\.android\./,``),r&&n.includes(`.`)&&(n=n.slice(n.lastIndexOf(`.`)+1))),n===`textview`?r?`text`:`text-view`:S(n)||n||`element`}function S(e){return Object.prototype.hasOwnProperty.call(h,e)?h[e]:void 0}function C(e){return e===`text-field`||e===`text-view`||e===`search`}function w(e,t){return e!==`scroll-area`&&e!==`list`&&e!==`collection`&&e!==`table`?!1:o(t)}function T(e){return/^[\w.]+:id\/[\w.-]+$/i.test(e)}function E(e,t,n,r){return!n.summarizeTextSurfaces||!r.shouldSummarize?b(e,t):O(e,t,r.text)||b(e,t)}function D(e,t,n,r){let i=[];return e.enabled===!1&&i.push(`disabled`),e.selected===!0&&i.push(`selected`),i.push(...e.presentationHints??[]),!n.summarizeTextSurfaces||(e.focused===!0&&i.push(`focused`),C(t)&&i.push(`editable`),k(e,t)&&i.push(`scrollable`),!r.shouldSummarize)?j(i):(i.push(`preview:"${A(l(r.text))}"`),i.push(`truncated`),j(i))}function O(e,t,n){let r=f(e.label);if(r&&r!==n)return r;let i=f(e.identifier);if(i&&!T(i)&&i!==n)return i;switch(t){case`text`:case`text-view`:return`Text view`;case`text-field`:return`Text field`;case`search`:return`Search field`;default:return``}}function k(e,t){if(t===`scroll-area`)return!0;let n=(e.type??``).toLowerCase(),r=`${e.role??``} ${e.subrole??``}`.toLowerCase();return n.includes(`scroll`)||r.includes(`scroll`)}function A(e){return e.replaceAll(`\\`,String.raw`\\`).replaceAll(`"`,String.raw`\"`)}function j(e){return[...new Set(e)]}const M={state:`sparse`,backend:`tree`,reason:`legacy iOS capture exposed only the application root`,reasonCode:`sparse-tree`};function N(e){if(e.scope!==void 0)return`scope`;if(e.depth!==void 0)return`depth`}function P(e,t=`is`){let n=`${t} absent`;return e===`scope`?`${n} does not support --scope; it requires an unscoped capture`:`${n} does not support --depth; it requires a full-depth capture`}function F(e,t){let n=t[0]?R(t[0]):void 0,r=t.length;if(e.truncated===!0)return{kind:`truncated`,matches:r,...n?{firstMatch:n}:{}};let i=I(e);return i?{kind:`sparse`,matches:r,...n?{firstMatch:n}:{},quality:{state:i.state,backend:i.backend,...i.reason?{reason:i.reason}:{},...i.reasonCode?{reasonCode:i.reasonCode}:{}}}:r===0?{kind:`absent`,matches:0}:{kind:`present`,matches:r,firstMatch:n}}function I(e){let t=e.snapshotQuality;return t?.state===`sparse`?{state:t.state,backend:t.backend,...t.reason?{reason:t.reason}:{},...t.reasonCode?{reasonCode:t.reasonCode}:{}}:L(e)?M:void 0}function L(e){return e.snapshotQuality||e.backend!==`xctest`||e.nodes.length!==1?!1:n(e.nodes[0]?.type??``)===`application`}function R(e){let t=r(e),n=i(a(e),256);return{...t,...n&&n!==t.label?{text:n}:{}}}const z={selectorNotFound:`selector_not_found`,predicateFailed:`predicate_failed`};function B(t,n=`is`){return new e(`INVALID_ARGS`,P(t,n),{command:n,predicate:`absent`,rejectedOption:t})}function V(t,n,r=`is`){let i=`firstMatch`in n?n.firstMatch:void 0,a={command:r,reason:z.predicateFailed,predicate:`absent`,selector:t,matches:n.matches,observation:n.kind,...i?{firstMatch:i}:{},...n.kind===`sparse`?{snapshotQuality:n.quality}:{},...n.kind===`truncated`?{truncated:!0}:{}};if(n.kind===`present`){let i=n.matches>1;return new e(`COMMAND_FAILED`,`${r} absent failed for selector ${t}: ${n.matches} match${i?`es`:``} found`,{...a,...i?{hint:`Refine the selector to match no elements.`}:{}})}return new e(`COMMAND_FAILED`,`${r} absent could not prove absence for selector ${t}: ${n.kind===`sparse`?`capture was sparse`:`capture was truncated`}`,{...a,hint:`Retry after the accessibility capture is complete.`})}function H(n,r,i=`is`){let a=t(r),o=typeof a.details?.reason==`string`?a.details.reason:typeof a.details?.androidSnapshotHelperFailureReason==`string`?a.details.androidSnapshotHelperFailureReason:void 0;return new e(`COMMAND_FAILED`,`${i} absent could not prove absence for selector ${n}: capture was unreadable`,{command:i,reason:z.predicateFailed,predicate:`absent`,selector:n,matches:0,observation:`unreadable`,captureErrorCode:a.code,...o?{captureErrorReason:o}:{},hint:`Retry after the accessibility capture is readable.`},a)}export{N as a,I as c,x as d,_ as f,z as i,g as l,p as m,V as n,F as o,s as p,H as r,L as s,B as t,b as u};
|
package/dist/src/adapter.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{C as e,j as t}from"./sdk-contracts.js";import{Br as n,zr as r}from"./sdk-batch.js";import{c as i,r as a}from"./diagnostics.js";import{f as o,x as s}from"./owner-identity.js";import{c,l,m as u,r as d}from"./exec.js";import{n as f,t as p}from"./file.js";import"./diagnostics2.js";import"./command.js";import{n as m}from"./retry.js";import{n as ee}from"./version.js";import"./process.js";import{C as te,D as ne,c as re,f as ie,h as ae,n as oe,o as se,w as ce,y as le}from"./host-file.js";import{t as h}from"./apple-runner-platform.js";import{n as ue,r as de,t as fe}from"./snapshot-process.js";import g from"node:path";import{createHash as _,randomUUID as v}from"node:crypto";import pe from"node:net";import{Buffer as y}from"node:buffer";const me={unsupported:`UNSUPPORTED_OPERATION`,"malformed-tree":`COMMAND_FAILED`,"stale-target":`COMMAND_FAILED`,timeout:`COMMAND_FAILED`,cancelled:`COMMAND_FAILED`,"process-crash":`COMMAND_FAILED`,"transport-failure":`COMMAND_FAILED`,preparing:`COMMAND_FAILED`};var b=class extends e{failureKind;failureCode;constructor(e,t,n=`iOS Simulator snapshot source ${e}: ${t}`,r={},i){super(me[e],n,{...r,bridgeFailure:e,bridgeFailureCode:t,...e===`cancelled`?{reason:`request_canceled`}:{}},i),this.name=`SnapshotSourceError`,this.failureKind=e,this.failureCode=t}};function x(e,t,n={},r){return new b(e,t,void 0,n,r)}function S(n){return n instanceof b?n:t(n)?x(`cancelled`,`abort-signal`,{},n):n instanceof e&&typeof n.details?.timeoutMs==`number`?x(`timeout`,`host-operation-timeout`,{timeoutMs:n.details.timeoutMs},n):x(`transport-failure`,`unexpected-host-error`,{error:n instanceof Error?n.message:String(n)},n)}function C(e,t,n=Date.now){if(t?.aborted)throw x(`cancelled`,`abort-signal`);return{clock:m.fromTimeoutMs(e,n()),now:n,signal:t}}function w(e,t){if(e.signal?.aborted)throw x(`cancelled`,`abort-signal`);let n=e.clock.remainingMs(e.now());if(n<=0)throw x(`timeout`,t);return Math.max(1,Math.floor(n))}async function T(e,t,n,r){let i=Math.min(t,w(e,n));await de({waitMs:i,signal:e.signal,stop:r,cancelled:()=>x(`cancelled`,`abort-signal`)})}var he=class{entries=new Map;probeBackAfterUses;constructor(e=8){this.probeBackAfterUses=e}consume(e,t,n){if(n)return{nativeLevels:void 0,reason:`explicit-depth`};let r=this.currentEntry(e);return r===`unidentified`?{nativeLevels:void 0,reason:`unidentified-target`}:!r||r.nativeLevels>=t?{nativeLevels:void 0,reason:`no-hint`}:r.remainingUses<=0?{nativeLevels:void 0,reason:`probe-back`}:(--r.remainingUses,{nativeLevels:r.nativeLevels,reason:`hinted`})}learn(e,t,n,r){return n||!e.targetId?`ignored`:r.rejected>0&&r.acceptedLevels<t?(this.remember(e.targetId,{generation:e.generation,nativeLevels:r.acceptedLevels,remainingUses:this.probeBackAfterUses}),`learned`):r.rejected===0&&r.acceptedLevels>=t?this.entries.delete(e.targetId)?`forgotten`:`ignored`:this.currentEntry(e)?`kept`:`ignored`}currentEntry(e){if(!e.targetId)return`unidentified`;let t=this.entries.get(e.targetId);if(t){if(t.generation!==e.generation){this.entries.delete(e.targetId);return}return t}}remember(e,t){if(this.entries.delete(e),this.entries.size>=32){let e=this.entries.keys().next().value;e!==void 0&&this.entries.delete(e)}this.entries.set(e,t)}};const E=65536;function ge(){return{projectRoot:ee,homeDirectory:ie,run:async(e,t,n)=>await c(e,t,n),start:_e,connect:ve,readText:le,readBinary:ae,writeText:ne,ensureDirectory:se,chmod:oe,exists:re,rename:ce,remove:te,acquireLock:ye,emitDiagnostic:a,withDiagnosticTimer:i,processId:o,readTargetProcessStartTime:fe}}function _e(e,t,n,r={}){if(r.signal?.aborted)throw x(`cancelled`,`abort-signal`);let i=l(`xcrun`,[`simctl`,`spawn`,e,t,`serve`,n,`--idle-timeout`,`60`,`--exit-on-disconnect`,`false`],{allowFailure:!0,captureOutput:!1,detached:!0}),a=i.child.pid??0;if(a<=0)throw x(`transport-failure`,`bridge-process-pid-missing`);let o=``;return i.child.stderr?.setEncoding(`utf8`),i.child.stderr?.on(`data`,e=>{o=be(o,String(e))}),{pid:a,wait:i.wait,isAlive:()=>i.child.exitCode===null&&i.child.signalCode===null,signal:e=>{u(a,e)||i.child.kill(e)},readLog:()=>o}}async function ve(e,t){if(t.signal?.aborted)throw x(`cancelled`,`abort-signal`);let n=Math.max(1,Math.floor(t.timeoutMs));return await new Promise((r,i)=>{let a=pe.createConnection({path:e}),o=!1,s=!1,c=setTimeout(()=>{p(x(`timeout`,`bridge-connect-timeout`)),a.destroy()},n),l=()=>{p(x(`cancelled`,`abort-signal`)),a.destroy()},u=()=>{o=!0,clearTimeout(c),t.signal?.removeEventListener(`abort`,l),a.off(`error`,d),a.off(`close`,f),a.setTimeout(0),r(a)},d=e=>{p(e),a.destroy()},f=()=>{o||p(x(`transport-failure`,`bridge-closed-before-connect`))},p=e=>{s||o||(s=!0,clearTimeout(c),t.signal?.removeEventListener(`abort`,l),a.off(`connect`,u),a.off(`error`,d),a.off(`close`,f),i(e))};a.once(`connect`,u),a.once(`error`,d),a.once(`close`,f),t.signal?.addEventListener(`abort`,l,{once:!0}),t.signal?.aborted&&l()})}async function ye(e,t){let n=o(),r=t.deadline,i=p({lockDirPath:e,owner:{pid:n,startTime:s(n),acquiredAtMs:Date.now()},timeoutMs:w(r,`cache-lock-deadline`),pollMs:100,ownerGraceMs:5e3,description:`iOS Simulator snapshot bridge cache`}),a=r.signal;if(!a)return await i;let c=!1,l,u=new Promise((e,t)=>{l=()=>{c=!0,t(x(`cancelled`,`abort-signal`))},a.addEventListener(`abort`,l,{once:!0}),a.aborted&&l()});try{return await Promise.race([i,u])}catch(e){throw c&&i.then(e=>e().catch(()=>void 0),()=>void 0),r.clock.isExpired()&&!(e instanceof b&&e.failureKind===`cancelled`)?x(`timeout`,`cache-lock-deadline`):e}finally{a.removeEventListener(`abort`,l)}}function be(e,t){let n=e+t;return n.length<=E?n:n.slice(n.length-E)}function xe(e,t,n){let r=_(`sha256`).update(t).digest(`hex`).slice(0,12),i=_(`sha256`).update(n).digest(`hex`).slice(0,12);return g.join(`/tmp`,`agent-device-ax-${r}-${e.processId()}-${i}`,`snapshot.sock`)}const D=new WeakSet;async function O(e,t){let n;try{n=(await t.wait).exitCode}catch{n=void 0}return D.has(t)||(D.add(t),e.emitDiagnostic({level:`error`,phase:`ios.snapshot-source.bridge-process-exit`,data:{pid:t.pid,...n===void 0?{}:{exitCode:n},stderr:Se(t.readLog())}})),x(`process-crash`,`bridge-exited`,{pid:t.pid,...n===void 0?{}:{exitCode:n}})}function Se(e){let t=y.from(e);return t.length<=65536?e:t.subarray(-65536).toString(`utf8`)}const k=`agent-device-simulator-ax-v1.6.0`;Object.freeze([`verb`,`requestId`,`pid`,`generation`,`snapshotTree`,`automationMode`,`maxDepth`,`maxNodes`,`maxDurationMs`,`maxResponseBytes`,`nativeLevelsHint`]),Object.freeze([`protocolVersion`,`sourceVersion`,`requestId`,`generation`,`ok`,`pid`,`tree`,`truncated`,`automationEnabled`,`recovery`,`error_kind`,`error_code`,`error`]),Object.freeze([`XC_kAXXCAttributeElementType`,`XC_kAXXCAttributeElementBaseType`,`XC_kAXXCAttributeLabel`,`XC_kAXXCAttributeValue`,`XC_kAXXCAttributeIdentifier`,`XC_kAXXCAttributeFrame`,`XC_kAXXCAttributeAutomationType`,`XC_kAXXCAttributeTraits`,`XC_kAXXCAttributeChildren`]);const A=[`requests`,`rejected`,`continuations`,`acceptedLevels`];function j(e){let t=e.recovery;if(!M(t))throw x(`malformed-tree`,`recovery-invalid`);let n=A.map(e=>[e,t[e]]);if(n.some(([,e])=>!Number.isSafeInteger(e)||e<0))throw x(`malformed-tree`,`recovery-invalid`);return Object.freeze(Object.fromEntries(n))}function Ce(e,t){let n;try{n=y.from(JSON.stringify(e),`utf8`)}catch(e){throw x(`malformed-tree`,`request-not-json`,{},e)}let r=n.length+4;if(r>t.maxRequestBytes)throw x(`transport-failure`,`request-limit-exceeded`,{frameBytes:r,maxRequestBytes:t.maxRequestBytes});let i=y.alloc(4);return i.writeUInt32BE(n.length,0),y.concat([i,n])}var we=class{header=y.alloc(4);headerBytes=0;chunks=[];payloadBytes=0;expectedBodyBytes;frame;maxFrameBytes;constructor(e){if(!Number.isSafeInteger(e)||e<=0)throw x(`malformed-tree`,`frame-limit-invalid`,{maxFrameBytes:e});this.maxFrameBytes=e}push(e){if(this.frame)return this.acceptTrailingChunk(e);let t=this.readHeader(e);if(t&&(this.appendPayload(e,t.offset,t.bodyBytes),this.payloadBytes===t.bodyBytes))return this.frame=y.concat(this.chunks,t.bodyBytes),this.frame}acceptTrailingChunk(e){if(e.length>0)throw x(`malformed-tree`,`multiple-frames`,{trailingBytes:e.length});return this.frame}readHeader(e){if(this.headerBytes===4)return{offset:0,bodyBytes:this.expectedBodyBytes};let t=Math.min(4-this.headerBytes,e.length);if(e.copy(this.header,this.headerBytes,0,t),this.headerBytes+=t,this.headerBytes<4)return;let n=this.header.readUInt32BE(0);if(n===0||n>this.maxFrameBytes)throw x(`malformed-tree`,`frame-limit-exceeded`,{bodyBytes:n,maxFrameBytes:this.maxFrameBytes});return this.expectedBodyBytes=n,{offset:t,bodyBytes:n}}appendPayload(e,t,n){let r=n-this.payloadBytes,i=e.length-t;if(i>r)throw x(`malformed-tree`,`multiple-frames`,{trailingBytes:i-r});i!==0&&(this.chunks.push(e.subarray(t)),this.payloadBytes+=i)}finish(){if(this.frame)return this.frame;throw x(`transport-failure`,`bridge-frame-incomplete`,{headerBytes:this.headerBytes,payloadBytes:this.payloadBytes,expectedBodyBytes:this.expectedBodyBytes})}};function Te(e){let t;try{t=JSON.parse(e.toString(`utf8`))}catch(e){throw x(`malformed-tree`,`response-not-json`,{},e)}if(!M(t))throw x(`malformed-tree`,`response-not-object`);return t}function Ee(e){return Object.freeze({verb:`describe`,requestId:e.requestId,pid:e.pid,generation:e.generation,snapshotTree:!0,automationMode:!0,maxDepth:e.maxDepth,maxNodes:e.maxNodes,maxDurationMs:e.maxDurationMs,maxResponseBytes:e.maxResponseBytes,...e.nativeLevelsHint===void 0?{}:{nativeLevelsHint:e.nativeLevelsHint}})}function De(e,t){if(e.protocolVersion!==1)throw x(`transport-failure`,`protocol-version-mismatch`,{expected:1,observed:e.protocolVersion});if(e.sourceVersion!==`agent-device-simulator-ax-v1.6.0`)throw x(`transport-failure`,`source-version-mismatch`,{expected:k,observed:e.sourceVersion});if(e.requestId!==t)throw x(`transport-failure`,`request-id-mismatch`,{expected:t,observed:e.requestId})}function Oe(e,t){if(typeof e.pid!=`number`||e.pid!==t.pid)throw x(`stale-target`,`bridge-pid-mismatch`,{expectedPid:t.pid,observedPid:e.pid});if(e.generation!==t.generation)throw x(`stale-target`,`bridge-generation-mismatch`,{expectedGeneration:t.generation,observedGeneration:e.generation})}function ke(e){let t=e.error_kind,n=typeof e.error_code==`string`?e.error_code:`guest-error`,r=typeof e.error==`string`?e.error:void 0,i=r?{guestMessage:r.slice(0,1024)}:{};throw x(t===`unsupported`?`unsupported`:t===`malformed_tree`?`malformed-tree`:t===`application_not_responding`?`timeout`:t===`application_unavailable`?`transport-failure`:t===`bad_request`?`malformed-tree`:`transport-failure`,n,i)}function M(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function Ae(e){let t=new we(e.limits.maxResponseBytes-4),n=w(e.deadline,`bridge-request-deadline`);return await new Promise((r,i)=>{let a=!1,o=!1,s=setTimeout(()=>{p(x(`timeout`,`bridge-request-deadline`,{dispatched:o})),e.socket.destroy()},n),c=()=>{p(x(`cancelled`,`abort-signal`,{dispatched:o})),e.socket.destroy()},l=n=>{try{if(!Buffer.isBuffer(n))throw x(`transport-failure`,`bridge-data-invalid`);let r=t.push(n);if(r){let t=Te(r);if(De(t,e.requestId),Oe(t,{pid:e.expectedPid,generation:e.expectedGeneration}),t.ok!==!0&&ke(t),typeof t.truncated!=`boolean`)throw x(`malformed-tree`,`truncated-invalid`);f(t);return}}catch(t){p(t),e.socket.destroy()}},u=e=>p(S(e)),d=()=>{a||(e.process.isAlive()?p(x(`transport-failure`,`bridge-connection-closed`)):O(e.host,e.process).then(p))};e.process.wait.then(()=>{a||O(e.host,e.process).then(p)},e=>{a||p(S(e))});let f=e=>m(()=>r(e)),p=e=>m(()=>i(e)),m=t=>{a||(a=!0,clearTimeout(s),e.deadline.signal?.removeEventListener(`abort`,c),e.socket.off(`data`,l),e.socket.off(`error`,u),e.socket.off(`close`,d),t())};e.socket.on(`data`,l),e.socket.on(`error`,u),e.socket.on(`close`,d),e.deadline.signal?.addEventListener(`abort`,c,{once:!0});try{if(e.deadline.signal?.aborted)throw x(`cancelled`,`abort-signal`);o=!0,e.socket.write(e.frame)}catch(t){p(S(t)),e.socket.destroy()}})}var je=class{sessions=new Map;requestQueues=new Map;ownerId=v();closed=!1;host;constructor(e){this.host=e}async request(e){if(this.closed)throw x(`unsupported`,`source-closed`);return await this.withSimulatorLock(e.target.udid,e.deadline,()=>this.requestInSimulator(e))}async requestInSimulator(e){if(this.closed)throw x(`unsupported`,`source-closed`);let t=e.deadline;w(t,`bridge-request-deadline`);let n=this.sessions.get(e.target.udid),r=await this.ensureSession(e,t);try{let n=await this.readTargetStartTime(e.target,t),i=await this.exchange(r,e,t);return await this.assertTargetStillCurrent(e.target,n,t),i}catch(e){throw await this.handleRequestFailure(e,r,n)}}async handleRequestFailure(e,t,n){let r=S(e);return Ne(r,t,n)?await this.removeSession(t,!0):r.failureKind===`process-crash`?await this.removeSession(t,!1):r.failureKind===`transport-failure`&&(t.socket?.destroy(),t.socket=void 0),r}async withSimulatorLock(e,t,n){let r=this.requestQueues.get(e)??Promise.resolve(),i,a=new Promise(e=>{i=e}),o=r.then(()=>a);this.requestQueues.set(e,o);try{return await Me(r,t),await n()}finally{i(),this.requestQueues.get(e)===o&&this.requestQueues.delete(e)}}async close(){if(this.closed)return;this.closed=!0;let e=[...this.sessions.values()];this.sessions.clear(),await Promise.all(e.map(async e=>await this.dispose(e,!0)))}async ensureSession(e,t){let n=e.target.udid,r=this.sessions.get(n);if(r&&r.bridgePath===e.bridge.path&&r.process.isAlive())return(!r.socket||r.socket.destroyed)&&(r.socket=await this.connectUntilReady(r,t)),r;r&&await this.removeSession(r,!0);let i=xe(this.host,e.target.udid,this.ownerId);await this.host.ensureDirectory(g.dirname(i)),await this.host.remove(i);let a=this.host.start(e.target.udid,e.bridge.path,i,{signal:t.signal}),o={udid:e.target.udid,bridgePath:e.bridge.path,socketPath:i,process:a};this.sessions.set(n,o);try{return o.socket=await this.connectUntilReady(o,t),o}catch(e){throw await this.removeSession(o,!0),S(e)}}async connectUntilReady(e,t){let n;for(;;){let r=w(t,`bridge-connect-deadline`);if(!e.process.isAlive())throw await O(this.host,e.process);try{return await this.host.connect(e.socketPath,{signal:t.signal,timeoutMs:Math.min(250,r)})}catch(e){if(n=e,e instanceof b&&e.failureKind===`cancelled`)throw e;let r=Math.min(20,w(t,`bridge-connect-deadline`));try{await T(t,r,`bridge-connect-deadline`)}catch(e){throw S(e)}}if(n instanceof b&&n.failureKind===`timeout`)throw n}}async exchange(e,t,n){(!e.socket||e.socket.destroyed)&&(e.socket=await this.connectUntilReady(e,n));let r=v(),i=Ce(Ee({requestId:r,pid:t.target.pid,generation:t.target.generation,maxDepth:Math.min(t.limits.maxTraversalDepth,t.maxDepth),maxNodes:t.limits.maxNodes,maxDurationMs:w(n,`bridge-request-deadline`),maxResponseBytes:t.limits.maxResponseBytes,...t.nativeLevelsHint===void 0?{}:{nativeLevelsHint:t.nativeLevelsHint}}),t.limits);return await Ae({process:e.process,socket:e.socket,frame:i,requestId:r,deadline:n,limits:t.limits,expectedPid:t.target.pid,expectedGeneration:t.target.generation,host:this.host})}async readTargetStartTime(e,t){let n=await this.host.readTargetProcessStartTime(e.pid,{signal:t.signal,timeoutMs:w(t,`target-identity-deadline`)});if(!n)throw x(`stale-target`,`target-process-unavailable`,{pid:e.pid,generation:e.generation});if(e.processStartTime!==void 0&&e.processStartTime!==n)throw x(`stale-target`,`target-process-changed`,{pid:e.pid,generation:e.generation,expectedStartTime:e.processStartTime,observedStartTime:n});return n}async assertTargetStillCurrent(e,t,n){let r=await this.host.readTargetProcessStartTime(e.pid,{signal:n.signal,timeoutMs:w(n,`target-identity-deadline`)});if(r!==t)throw x(`stale-target`,`target-process-changed`,{pid:e.pid,generation:e.generation,expectedStartTime:t,observedStartTime:r})}async removeSession(e,t){this.sessions.get(e.udid)===e&&this.sessions.delete(e.udid),await this.dispose(e,t)}async dispose(e,t){e.socket?.destroy(),e.socket=void 0,t&&e.process.isAlive()&&(e.process.signal(`SIGTERM`),await N(e.process,500),e.process.isAlive()&&(e.process.signal(`SIGKILL`),await N(e.process,500))),await this.host.remove(e.socketPath)}};async function Me(e,t){let n=w(t,`bridge-request-deadline`);await Promise.race([e,T(t,n,`bridge-request-deadline`).then(()=>{throw x(`timeout`,`bridge-request-deadline`)})])}function Ne(e,t,n){return(e.failureKind===`cancelled`||e.failureKind===`timeout`)&&(e.details?.dispatched===!0||n!==t)}async function N(e,t){await Promise.race([e.wait.catch(()=>void 0),new Promise(e=>setTimeout(e,t))])}const P=16777216,F=12e4,I=1e4,Pe=Object.freeze({maxRequestBytes:65536,maxResponseBytes:4194304,maxNodes:5e3,maxTraversalDepth:64,maxDurationMs:5e3});function L(t){let n={...Pe,...t??{}};for(let[t,r]of Object.entries(n))if(!Number.isSafeInteger(r)||r<=0)throw new e(`INVALID_ARGS`,`Snapshot source limit ${t} must be a positive integer`,{name:t,value:r});if(n.maxRequestBytes>n.maxResponseBytes)throw new e(`INVALID_ARGS`,`Snapshot source request bytes cannot exceed response bytes`,{maxRequestBytes:n.maxRequestBytes,maxResponseBytes:n.maxResponseBytes});if(n.maxRequestBytes>P||n.maxResponseBytes>P)throw new e(`INVALID_ARGS`,`Snapshot source frame limits exceed the bridge bound`,{maxRequestBytes:n.maxRequestBytes,maxResponseBytes:n.maxResponseBytes,maximumFrameBytes:P});if(n.maxNodes>I||n.maxTraversalDepth>128)throw new e(`INVALID_ARGS`,`Snapshot source tree limits exceed the bridge bound`,{maxNodes:n.maxNodes,maxTraversalDepth:n.maxTraversalDepth,maximumNodes:I,maximumDepth:128});if(n.maxDurationMs>F)throw new e(`INVALID_ARGS`,`Snapshot source duration exceeds the bridge bound`,{maxDurationMs:n.maxDurationMs,maximumDurationMs:F});if(n.maxRequestBytes<=4||n.maxResponseBytes<=4)throw new e(`INVALID_ARGS`,`Snapshot source frame limits must leave room for a body`,{maxRequestBytes:n.maxRequestBytes,maxResponseBytes:n.maxResponseBytes});return Object.freeze(n)}const R=[`SnapshotBridge.m`,`SnapshotBridgeRuntime.m`,`SnapshotBridgeRuntime.h`,`SnapshotBridgeCapture.h`,`SnapshotBridgeCapture.m`],Fe=[`SnapshotBridge.m`,`SnapshotBridgeRuntime.m`,`SnapshotBridgeCapture.m`];async function Ie(e,t,n){let r=_(`sha256`);for(let i of R){let a=g.join(t,i);if(w(n,`native-source-fingerprint-deadline`),!e.exists(a))throw x(`unsupported`,`native-source-missing`,{filePath:a});r.update(i),r.update(`\0`),r.update(await e.readBinary(a)),r.update(`\0`)}return r.digest(`hex`)}async function Le(e,t,n){let r=await z(e,`xcodebuild`,[`-version`],n),i=await z(e,`sw_vers`,[`-productVersion`],n),a=await z(e,`sw_vers`,[`-buildVersion`],n),o=await z(e,`uname`,[`-m`],n),s=await z(e,`xcrun`,[`--sdk`,`iphonesimulator`,`--show-sdk-version`],n),c=t.trim();if(!c)throw x(`unsupported`,`simulator-runtime-missing`);if(o!==`arm64`&&o!==`x86_64`)throw x(`unsupported`,`simulator-architecture-unsupported`,{architecture:o});return{xcode:r,macosProductVersion:i,macosBuild:a,architecture:o,simulatorSdk:s,simulatorRuntime:c}}async function z(e,t,n,r){let i=await Re(e,t,n,r);if(i.exitCode!==0)throw x(`unsupported`,`toolchain-probe-failed`,{command:t,exitCode:i.exitCode,stderr:i.stderr.slice(0,1024)});let a=(i.stdout||i.stderr).trim();if(!a)throw x(`unsupported`,`toolchain-probe-empty`,{command:t});return a}async function Re(e,t,n,r){try{return await B(e,t,n,r)}catch(i){if(!d(i))throw i;if(r.signal?.aborted)throw x(`cancelled`,`abort-signal`);if(r.clock.remainingMs(r.now())<=0)throw i;return await B(e,t,n,r)}}function B(e,t,n,r){return e.run(t,n,{allowFailure:!0,signal:r.signal,timeoutMs:Math.min(h,w(r,`toolchain-probe-deadline`))})}const V=`snapshot-bridge`,H=`manifest.json`,U=12e4;async function ze(e){let t=e.deadline,n=e.sourceRoot??Be(e.host),r=await Ie(e.host,n,t),i=await Le(e.host,e.runtime,t),a=He({schemaVersion:1,protocolVersion:1,sourceVersion:k,sourceHash:r,toolchain:i}),o=e.cacheRoot??g.join(e.host.homeDirectory(),`.agent-device`,`snapshot-source`),s=g.join(o,a);return await f({acquire:()=>e.host.acquireLock(g.join(o,`${a}.lock`),{deadline:t}),task:async()=>{let c=await Ve(e.host,s,{sourceHash:r,cacheKey:a,toolchain:i},t);if(c)return c;w(t,`native-build-deadline`),e.host.exists(s)&&await e.host.remove(s),w(t,`native-build-deadline`),await e.host.ensureDirectory(o);let l=g.join(o,`.${a}.${e.host.processId()}.tmp`);w(t,`native-build-deadline`),await e.host.remove(l);try{w(t,`native-build-deadline`),await e.host.ensureDirectory(l);let o=g.join(l,V),c=await e.host.run(`xcrun`,[`--sdk`,`iphonesimulator`,`clang`,`-arch`,i.architecture,`-mios-simulator-version-min=15.0`,`-fobjc-arc`,`-Werror`,`-Wall`,`-Wextra`,`-framework`,`Foundation`,`-framework`,`CoreGraphics`,...Fe.map(e=>g.join(n,e)),`-o`,o],{signal:t.signal,timeoutMs:Math.min(U,w(t,`native-build-deadline`)),allowFailure:!0});if(c.exitCode!==0||!e.host.exists(o))throw x(`unsupported`,`native-build-failed`,{exitCode:c.exitCode,stderr:c.stderr.slice(0,4096)});w(t,`native-build-deadline`),await e.host.chmod(o,493);let u=await W(e.host,o,t),d={schemaVersion:1,protocolVersion:1,sourceVersion:k,sourceHash:r,cacheKey:a,toolchain:i,binarySha256:u};return await e.host.writeText(g.join(l,H),`${JSON.stringify(d,null,2)}\n`),w(t,`native-build-deadline`),await e.host.rename(l,s),{path:g.join(s,V),sourceHash:r,cacheKey:a,protocolVersion:1,sourceVersion:k}}catch(t){throw await e.host.remove(l),t}}})}function Be(e){let t=e.projectRoot(),n=g.join(t,`apple`,`snapshot-bridge`);if(R.every(t=>e.exists(g.join(n,t))))return n;let r=g.join(t,`dist`,`apple`,`snapshot-bridge`);if(R.every(t=>e.exists(g.join(r,t))))return r;throw x(`unsupported`,`native-source-missing`,{projectRoot:t})}async function Ve(e,t,n,r){let i=g.join(t,V);if(!(!e.exists(i)||!e.exists(g.join(t,H))))try{let a=JSON.parse(await e.readText(g.join(t,H)));return a.schemaVersion!==1||a.protocolVersion!==1||a.sourceVersion!==`agent-device-simulator-ax-v1.6.0`||a.sourceHash!==n.sourceHash||a.cacheKey!==n.cacheKey||JSON.stringify(a.toolchain)!==JSON.stringify(n.toolchain)||typeof a.binarySha256!=`string`||await W(e,i,r)!==a.binarySha256?void 0:{path:i,sourceHash:n.sourceHash,cacheKey:n.cacheKey,protocolVersion:1,sourceVersion:k}}catch(e){if(e instanceof b&&(e.failureKind===`cancelled`||e.failureKind===`timeout`))throw e;return}}async function W(e,t,n){return w(n,`native-cache-hash-deadline`),_(`sha256`).update(await e.readBinary(t)).digest(`hex`)}function He(e){return _(`sha256`).update(JSON.stringify(e)).digest(`hex`).slice(0,32)}const Ue=h+U;function We(e){let t=e.now??Date.now,n=new Map,r=ue({waitMs:2e3,waitGrant:`first-caller`,retryAfterMs:6e4,now:t}),i=async(r,i)=>{let a=C(Ue,i,t);try{let t=await e.host.withDiagnosticTimer(`ios.snapshot-source.prepare`,async()=>await ze({host:e.host,runtime:r,limits:e.limits,deadline:a,sourceRoot:e.sourceRoot,cacheRoot:e.cacheRoot}),{producer:e.producer});return n.set(r,t),t}catch(e){throw S(e)}};return{readyBinary:async(e,t,a)=>n.get(e)||await r.value(e,{start:t=>i(e,t),wait:(e,n)=>T(t,e,a,n),pending:()=>x(`preparing`,`bridge-preparation-pending`)}),close:()=>{n.clear(),r.close()}}}const G=Object.freeze({elementType:`XC_kAXXCAttributeElementType`,elementBaseType:`XC_kAXXCAttributeElementBaseType`,label:`XC_kAXXCAttributeLabel`,value:`XC_kAXXCAttributeValue`,identifier:`XC_kAXXCAttributeIdentifier`,frame:`XC_kAXXCAttributeFrame`,automationType:`XC_kAXXCAttributeAutomationType`,traits:`XC_kAXXCAttributeTraits`,children:`XC_kAXXCAttributeChildren`}),K=`Other.Other.Application.Group.Window.Sheet.Drawer.Alert.Dialog.Button.RadioButton.RadioGroup.CheckBox.DisclosureTriangle.PopUpButton.ComboBox.MenuButton.ToolbarButton.Popover.Keyboard.Key.NavigationBar.TabBar.TabGroup.Toolbar.StatusBar.Table.TableRow.TableColumn.Outline.OutlineRow.Browser.CollectionView.Slider.PageIndicator.ProgressIndicator.ActivityIndicator.SegmentedControl.Picker.PickerWheel.Switch.Toggle.Link.Image.Icon.SearchField.ScrollView.ScrollBar.StaticText.TextField.SecureTextField.DatePicker.TextView.Menu.MenuItem.MenuBar.MenuBarItem.Map.WebView.IncrementArrow.DecrementArrow.Timeline.RatingIndicator.ValueIndicator.SplitGroup.Splitter.RelevanceIndicator.ColorWell.HelpTag.Matte.DockItem.Ruler.RulerMarker.Grid.LevelIndicator.Cell.LayoutArea.LayoutItem.Handle.Stepper.Tab.TouchBar.StatusItem`.split(`.`),q={UIApplication:`Application`,UIWindow:`Window`},Ge=new Set(Object.values(G)),Ke=1n<<8n;function qe(e,t,n){let r=Array.isArray(e)?e:[e];if(r.length===0||r.some(e=>!M(e)))throw x(`malformed-tree`,`guest-tree-root-invalid`);let i=[],a=[],o=0;for(let e of r)c(e,void 0,0,!1);if(i.length>n.maxNodes)throw x(`malformed-tree`,`node-limit-exceeded`,{nodeCount:i.length,maxNodes:n.maxNodes});if(o>n.maxTraversalDepth)throw x(`malformed-tree`,`traversal-depth-exceeded`,{maxTraversalDepth:o,maxAllowedDepth:n.maxTraversalDepth});if(typeof t.truncated!=`boolean`)throw x(`malformed-tree`,`truncated-invalid`);let s=Qe(i.find(e=>e.type===`Application`||e.type===`Window`));return{nodes:i,maxTraversalDepth:o,viewport:s,opaqueRemoteElements:a.filter(e=>Xe(e,s)).length};function c(e,t,r,s){if(i.length>=n.maxNodes)throw x(`malformed-tree`,`node-limit-exceeded`,{maxNodes:n.maxNodes});for(let t of Object.keys(e))if(!Ge.has(t))throw x(`malformed-tree`,`node-contains-unknown-field`,{key:t});let l=e[G.children];if(!Array.isArray(l))throw x(`malformed-tree`,`children-invalid`);let u=i.length,d=Je(e,u,t,r);i.push(d),o=Math.max(o,r),Ye(d,l.length,s)&&a.push(d.rect);let f=s||d.type===`WebView`;for(let e of l){if(!M(e))throw x(`malformed-tree`,`child-invalid`);c(e,u,r+1,f)}}}function Je(e,t,n,r){let i=Y(e[G.elementType]),a=Y(e[G.elementBaseType]),o=Z(e[G.automationType]),s=Ze(e[G.frame]),c=$e(e[G.traits]);return{index:t,...n===void 0?{}:{parentIndex:n},...J(i,o)?{type:J(i,o)}:{},...i?{role:i}:{},...a&&a!==i?{subrole:a}:{},...Y(e[G.label])?{label:Y(e[G.label])}:{},...X(e[G.value])?{value:X(e[G.value])}:{},...Y(e[G.identifier])?{identifier:Y(e[G.identifier])}:{},...s?{rect:s}:{},...c===void 0?{}:{enabled:c},depth:r}}function J(e,t){if(e!==void 0&&q[e])return q[e];if(e!==void 0&&K.includes(e))return e;if(t!==void 0)return K[t]??`Other`}function Ye(e,t,n){return n&&e.role===`AXRemoteElement`&&t===0}function Xe(e,t){return e===void 0?!0:r(e)?t.kind!==`reported`||n(e,t.rect):!1}function Ze(e){if(e===void 0)return;if(!M(e))throw x(`malformed-tree`,`frame-invalid`);let t=[`X`,`Y`,`Width`,`Height`].map(t=>e[t]);if(!t.every(e=>typeof e==`number`&&Number.isFinite(e)))throw x(`malformed-tree`,`frame-invalid`);let[n,r,i,a]=t;if(i<0||a<0)throw x(`malformed-tree`,`frame-invalid`);return{x:n,y:r,width:i,height:a}}function Qe(e){return!e||e.type!==`Application`&&e.type!==`Window`?{kind:`missing`,reason:`not-provided`}:r(e.rect)?{kind:`reported`,rect:e.rect}:{kind:`missing`,reason:e.rect?`invalid`:`not-provided`}}function Y(e){return typeof e==`string`&&e.length>0?e:void 0}function X(e){if(typeof e==`string`)return e.length>0?e:void 0;if(typeof e==`number`||typeof e==`boolean`)return String(e);if(e!=null)throw x(`malformed-tree`,`scalar-invalid`)}function $e(e){if(e!=null){if(typeof e!=`string`||!/^\d{1,20}$/.test(e))throw x(`malformed-tree`,`traits-invalid`);return(BigInt(e)&Ke)===0n}}function Z(e){if(e!=null){if(!Number.isSafeInteger(e))throw x(`malformed-tree`,`automation-type-invalid`);return e}}const Q=`simulator-ax-bridge`;function et(e={}){let t=e.host??ge(),n=new je(t),r=new he,i=We({host:t,limits:L(e.limits),producer:Q,sourceRoot:e.sourceRoot,cacheRoot:e.cacheRoot}),a=!1;return{acquire:async o=>{try{if(a)throw x(`unsupported`,`source-closed`);tt(o);let s=L({...e.limits,...o.limits}),c=C(s.maxDurationMs,o.signal),l=rt(o.hint,s.maxTraversalDepth),u=l+1,d=o.hint.rawTraversalDepth!==null;return await t.withDiagnosticTimer(`ios.snapshot-source.acquire`,async()=>{let e=await i.readyBinary(o.target.runtime,c,`bridge-preparation-deadline`),a=r.consume(o.target,u,d),f=await n.request({target:o.target,bridge:e,limits:s,maxDepth:l,nativeLevelsHint:a.nativeLevels,deadline:c});w(c,`snapshot-decode-deadline`);let p=it(o.hint,o.target,f,s);return nt(t,r,o.target,u,d,a,f),{stage:`acquired`,acquisition:p}},{producer:Q})}catch(e){let t=S(e);return{stage:`failed`,failure:{kind:t.failureKind,code:t.failureCode,...t.details?{details:t.details}:{}}}}},close:async()=>{a||(a=!0,i.close(),await n.close())}}}function tt(t){if(!t.target.udid.trim()||!t.target.runtime.trim()||!t.target.generation.trim()||!Number.isSafeInteger(t.target.pid)||t.target.pid<=0)throw new e(`INVALID_ARGS`,`Simulator snapshot source target identity is incomplete`);let n=t.hint;if(n.projection!==`raw`&&n.projection!==`regular`||![`full`,`surface-observation`].includes(n.acquisitionIntent)||typeof n.interactiveOnly!=`boolean`||typeof n.customActions!=`boolean`||!$(n.rawTraversalDepth)||!$(n.regularPresentedDepth))throw new e(`INVALID_ARGS`,`Simulator snapshot source capture hint is invalid`)}function nt(e,t,n,r,i,a,o){let s=j(o),c=o.truncated===!0,l=t.learn(n,r,i,s);e.emitDiagnostic({level:`debug`,phase:`ios_snapshot_source_recovery`,data:{producer:Q,...n.targetId?{targetId:n.targetId}:{},generation:n.generation,requestedLevels:r,hint:a.reason,...a.nativeLevels===void 0?{}:{hintedLevels:a.nativeLevels},...s,truncated:c,learning:l}})}function rt(t,n){let r=t.rawTraversalDepth??n;if(r>n)throw new e(`INVALID_ARGS`,`Simulator snapshot source depth exceeds its bound`,{requested:r,maximum:n});return r}function $(e){return e===null||Number.isSafeInteger(e)&&e>=0}function it(e,t,n,r){if(n.automationEnabled!==!0)throw x(`unsupported`,`automation-mode-unavailable`);let i=n.tree,a=n.truncated;if(typeof a!=`boolean`)throw x(`malformed-tree`,`truncated-invalid`);let o=qe(i,{truncated:a},r),s=n.generation;if(typeof s!=`string`||!s)throw x(`malformed-tree`,`generation-invalid`);if(o.opaqueRemoteElements>0)throw x(`unsupported`,`remote-content-boundary`,{remoteElements:o.opaqueRemoteElements});let c=Object.freeze(o.nodes.map(e=>Object.freeze({...e,pid:t.pid}))),l=at(e,a,o.viewport),u=Object.freeze({...t.targetId?{targetId:t.targetId}:{},generation:s}),d={producer:Q,nodes:c,truncated:a,viewport:o.viewport,lineage:u,residue:l};return e.acquisitionIntent===`full`?{...d,intent:`full`,hint:{...e,acquisitionIntent:`full`}}:{...d,intent:`surface-observation`,hint:{...e,acquisitionIntent:`surface-observation`}}}function at(e,t,n){return Object.freeze([{kind:`unavailable-fact`,fact:`hittability`},...e.interactiveOnly?[{kind:`unavailable-fact`,fact:`interactive-query`}]:[],...t?[{kind:`truncated`}]:[],...n.kind===`missing`?[{kind:`missing-viewport`,reason:n.reason}]:[]])}export{et as createSimulatorSnapshotSource};
|
|
1
|
+
import{D as e,F as t}from"./sdk-contracts.js";import{Br as n,Vr as r}from"./sdk-batch.js";import{c as i,r as a}from"./diagnostics.js";import{f as o,x as s}from"./owner-identity.js";import{c,l,m as u,r as d}from"./exec.js";import{n as f,t as p}from"./file.js";import"./diagnostics2.js";import"./command.js";import{n as m}from"./retry.js";import{n as ee}from"./version.js";import"./process.js";import{C as te,D as ne,c as re,f as ie,h as ae,n as oe,o as se,w as ce,y as le}from"./host-file.js";import{t as h}from"./apple-runner-platform.js";import{n as ue,r as de,t as fe}from"./snapshot-process.js";import g from"node:path";import{createHash as _,randomUUID as v}from"node:crypto";import pe from"node:net";import{Buffer as y}from"node:buffer";const me={unsupported:`UNSUPPORTED_OPERATION`,"malformed-tree":`COMMAND_FAILED`,"stale-target":`COMMAND_FAILED`,timeout:`COMMAND_FAILED`,cancelled:`COMMAND_FAILED`,"process-crash":`COMMAND_FAILED`,"transport-failure":`COMMAND_FAILED`,preparing:`COMMAND_FAILED`};var b=class extends e{failureKind;failureCode;constructor(e,t,n=`iOS Simulator snapshot source ${e}: ${t}`,r={},i){super(me[e],n,{...r,bridgeFailure:e,bridgeFailureCode:t,...e===`cancelled`?{reason:`request_canceled`}:{}},i),this.name=`SnapshotSourceError`,this.failureKind=e,this.failureCode=t}};function x(e,t,n={},r){return new b(e,t,void 0,n,r)}function S(n){return n instanceof b?n:t(n)?x(`cancelled`,`abort-signal`,{},n):n instanceof e&&typeof n.details?.timeoutMs==`number`?x(`timeout`,`host-operation-timeout`,{timeoutMs:n.details.timeoutMs},n):x(`transport-failure`,`unexpected-host-error`,{error:n instanceof Error?n.message:String(n)},n)}function C(e,t,n=Date.now){if(t?.aborted)throw x(`cancelled`,`abort-signal`);return{clock:m.fromTimeoutMs(e,n()),now:n,signal:t}}function w(e,t){if(e.signal?.aborted)throw x(`cancelled`,`abort-signal`);let n=e.clock.remainingMs(e.now());if(n<=0)throw x(`timeout`,t);return Math.max(1,Math.floor(n))}async function T(e,t,n,r){let i=Math.min(t,w(e,n));await de({waitMs:i,signal:e.signal,stop:r,cancelled:()=>x(`cancelled`,`abort-signal`)})}var he=class{entries=new Map;probeBackAfterUses;constructor(e=8){this.probeBackAfterUses=e}consume(e,t,n){if(n)return{nativeLevels:void 0,reason:`explicit-depth`};let r=this.currentEntry(e);return r===`unidentified`?{nativeLevels:void 0,reason:`unidentified-target`}:!r||r.nativeLevels>=t?{nativeLevels:void 0,reason:`no-hint`}:r.remainingUses<=0?{nativeLevels:void 0,reason:`probe-back`}:(--r.remainingUses,{nativeLevels:r.nativeLevels,reason:`hinted`})}learn(e,t,n,r){return n||!e.targetId?`ignored`:r.rejected>0&&r.acceptedLevels<t?(this.remember(e.targetId,{generation:e.generation,nativeLevels:r.acceptedLevels,remainingUses:this.probeBackAfterUses}),`learned`):r.rejected===0&&r.acceptedLevels>=t?this.entries.delete(e.targetId)?`forgotten`:`ignored`:this.currentEntry(e)?`kept`:`ignored`}currentEntry(e){if(!e.targetId)return`unidentified`;let t=this.entries.get(e.targetId);if(t){if(t.generation!==e.generation){this.entries.delete(e.targetId);return}return t}}remember(e,t){if(this.entries.delete(e),this.entries.size>=32){let e=this.entries.keys().next().value;e!==void 0&&this.entries.delete(e)}this.entries.set(e,t)}};const E=65536;function ge(){return{projectRoot:ee,homeDirectory:ie,run:async(e,t,n)=>await c(e,t,n),start:_e,connect:ve,readText:le,readBinary:ae,writeText:ne,ensureDirectory:se,chmod:oe,exists:re,rename:ce,remove:te,acquireLock:ye,emitDiagnostic:a,withDiagnosticTimer:i,processId:o,readTargetProcessStartTime:fe}}function _e(e,t,n,r={}){if(r.signal?.aborted)throw x(`cancelled`,`abort-signal`);let i=l(`xcrun`,[`simctl`,`spawn`,e,t,`serve`,n,`--idle-timeout`,`60`,`--exit-on-disconnect`,`false`],{allowFailure:!0,captureOutput:!1,detached:!0}),a=i.child.pid??0;if(a<=0)throw x(`transport-failure`,`bridge-process-pid-missing`);let o=``;return i.child.stderr?.setEncoding(`utf8`),i.child.stderr?.on(`data`,e=>{o=be(o,String(e))}),{pid:a,wait:i.wait,isAlive:()=>i.child.exitCode===null&&i.child.signalCode===null,signal:e=>{u(a,e)||i.child.kill(e)},readLog:()=>o}}async function ve(e,t){if(t.signal?.aborted)throw x(`cancelled`,`abort-signal`);let n=Math.max(1,Math.floor(t.timeoutMs));return await new Promise((r,i)=>{let a=pe.createConnection({path:e}),o=!1,s=!1,c=setTimeout(()=>{p(x(`timeout`,`bridge-connect-timeout`)),a.destroy()},n),l=()=>{p(x(`cancelled`,`abort-signal`)),a.destroy()},u=()=>{o=!0,clearTimeout(c),t.signal?.removeEventListener(`abort`,l),a.off(`error`,d),a.off(`close`,f),a.setTimeout(0),r(a)},d=e=>{p(e),a.destroy()},f=()=>{o||p(x(`transport-failure`,`bridge-closed-before-connect`))},p=e=>{s||o||(s=!0,clearTimeout(c),t.signal?.removeEventListener(`abort`,l),a.off(`connect`,u),a.off(`error`,d),a.off(`close`,f),i(e))};a.once(`connect`,u),a.once(`error`,d),a.once(`close`,f),t.signal?.addEventListener(`abort`,l,{once:!0}),t.signal?.aborted&&l()})}async function ye(e,t){let n=o(),r=t.deadline,i=p({lockDirPath:e,owner:{pid:n,startTime:s(n),acquiredAtMs:Date.now()},timeoutMs:w(r,`cache-lock-deadline`),pollMs:100,ownerGraceMs:5e3,description:`iOS Simulator snapshot bridge cache`}),a=r.signal;if(!a)return await i;let c=!1,l,u=new Promise((e,t)=>{l=()=>{c=!0,t(x(`cancelled`,`abort-signal`))},a.addEventListener(`abort`,l,{once:!0}),a.aborted&&l()});try{return await Promise.race([i,u])}catch(e){throw c&&i.then(e=>e().catch(()=>void 0),()=>void 0),r.clock.isExpired()&&!(e instanceof b&&e.failureKind===`cancelled`)?x(`timeout`,`cache-lock-deadline`):e}finally{a.removeEventListener(`abort`,l)}}function be(e,t){let n=e+t;return n.length<=E?n:n.slice(n.length-E)}function xe(e,t,n){let r=_(`sha256`).update(t).digest(`hex`).slice(0,12),i=_(`sha256`).update(n).digest(`hex`).slice(0,12);return g.join(`/tmp`,`agent-device-ax-${r}-${e.processId()}-${i}`,`snapshot.sock`)}const D=new WeakSet;async function O(e,t){let n;try{n=(await t.wait).exitCode}catch{n=void 0}return D.has(t)||(D.add(t),e.emitDiagnostic({level:`error`,phase:`ios.snapshot-source.bridge-process-exit`,data:{pid:t.pid,...n===void 0?{}:{exitCode:n},stderr:Se(t.readLog())}})),x(`process-crash`,`bridge-exited`,{pid:t.pid,...n===void 0?{}:{exitCode:n}})}function Se(e){let t=y.from(e);return t.length<=65536?e:t.subarray(-65536).toString(`utf8`)}const k=`agent-device-simulator-ax-v1.6.0`;Object.freeze([`verb`,`requestId`,`pid`,`generation`,`snapshotTree`,`automationMode`,`maxDepth`,`maxNodes`,`maxDurationMs`,`maxResponseBytes`,`nativeLevelsHint`]),Object.freeze([`protocolVersion`,`sourceVersion`,`requestId`,`generation`,`ok`,`pid`,`tree`,`truncated`,`automationEnabled`,`recovery`,`error_kind`,`error_code`,`error`]),Object.freeze([`XC_kAXXCAttributeElementType`,`XC_kAXXCAttributeElementBaseType`,`XC_kAXXCAttributeLabel`,`XC_kAXXCAttributeValue`,`XC_kAXXCAttributeIdentifier`,`XC_kAXXCAttributeFrame`,`XC_kAXXCAttributeAutomationType`,`XC_kAXXCAttributeTraits`,`XC_kAXXCAttributeChildren`]);const Ce=[`requests`,`rejected`,`continuations`,`acceptedLevels`];function A(e){let t=e.recovery;if(!j(t))throw x(`malformed-tree`,`recovery-invalid`);let n=Ce.map(e=>[e,t[e]]);if(n.some(([,e])=>!Number.isSafeInteger(e)||e<0))throw x(`malformed-tree`,`recovery-invalid`);return Object.freeze(Object.fromEntries(n))}function we(e,t){let n;try{n=y.from(JSON.stringify(e),`utf8`)}catch(e){throw x(`malformed-tree`,`request-not-json`,{},e)}let r=n.length+4;if(r>t.maxRequestBytes)throw x(`transport-failure`,`request-limit-exceeded`,{frameBytes:r,maxRequestBytes:t.maxRequestBytes});let i=y.alloc(4);return i.writeUInt32BE(n.length,0),y.concat([i,n])}var Te=class{header=y.alloc(4);headerBytes=0;chunks=[];payloadBytes=0;expectedBodyBytes;frame;maxFrameBytes;constructor(e){if(!Number.isSafeInteger(e)||e<=0)throw x(`malformed-tree`,`frame-limit-invalid`,{maxFrameBytes:e});this.maxFrameBytes=e}push(e){if(this.frame)return this.acceptTrailingChunk(e);let t=this.readHeader(e);if(t&&(this.appendPayload(e,t.offset,t.bodyBytes),this.payloadBytes===t.bodyBytes))return this.frame=y.concat(this.chunks,t.bodyBytes),this.frame}acceptTrailingChunk(e){if(e.length>0)throw x(`malformed-tree`,`multiple-frames`,{trailingBytes:e.length});return this.frame}readHeader(e){if(this.headerBytes===4)return{offset:0,bodyBytes:this.expectedBodyBytes};let t=Math.min(4-this.headerBytes,e.length);if(e.copy(this.header,this.headerBytes,0,t),this.headerBytes+=t,this.headerBytes<4)return;let n=this.header.readUInt32BE(0);if(n===0||n>this.maxFrameBytes)throw x(`malformed-tree`,`frame-limit-exceeded`,{bodyBytes:n,maxFrameBytes:this.maxFrameBytes});return this.expectedBodyBytes=n,{offset:t,bodyBytes:n}}appendPayload(e,t,n){let r=n-this.payloadBytes,i=e.length-t;if(i>r)throw x(`malformed-tree`,`multiple-frames`,{trailingBytes:i-r});i!==0&&(this.chunks.push(e.subarray(t)),this.payloadBytes+=i)}finish(){if(this.frame)return this.frame;throw x(`transport-failure`,`bridge-frame-incomplete`,{headerBytes:this.headerBytes,payloadBytes:this.payloadBytes,expectedBodyBytes:this.expectedBodyBytes})}};function Ee(e){let t;try{t=JSON.parse(e.toString(`utf8`))}catch(e){throw x(`malformed-tree`,`response-not-json`,{},e)}if(!j(t))throw x(`malformed-tree`,`response-not-object`);return t}function De(e){return Object.freeze({verb:`describe`,requestId:e.requestId,pid:e.pid,generation:e.generation,snapshotTree:!0,automationMode:!0,maxDepth:e.maxDepth,maxNodes:e.maxNodes,maxDurationMs:e.maxDurationMs,maxResponseBytes:e.maxResponseBytes,...e.nativeLevelsHint===void 0?{}:{nativeLevelsHint:e.nativeLevelsHint}})}function Oe(e,t){if(e.protocolVersion!==1)throw x(`transport-failure`,`protocol-version-mismatch`,{expected:1,observed:e.protocolVersion});if(e.sourceVersion!==`agent-device-simulator-ax-v1.6.0`)throw x(`transport-failure`,`source-version-mismatch`,{expected:k,observed:e.sourceVersion});if(e.requestId!==t)throw x(`transport-failure`,`request-id-mismatch`,{expected:t,observed:e.requestId})}function ke(e,t){if(typeof e.pid!=`number`||e.pid!==t.pid)throw x(`stale-target`,`bridge-pid-mismatch`,{expectedPid:t.pid,observedPid:e.pid});if(e.generation!==t.generation)throw x(`stale-target`,`bridge-generation-mismatch`,{expectedGeneration:t.generation,observedGeneration:e.generation})}function Ae(e){let t=e.error_kind,n=typeof e.error_code==`string`?e.error_code:`guest-error`,r=typeof e.error==`string`?e.error:void 0,i=r?{guestMessage:r.slice(0,1024)}:{};throw x(t===`unsupported`?`unsupported`:t===`malformed_tree`?`malformed-tree`:t===`application_not_responding`?`timeout`:t===`application_unavailable`?`transport-failure`:t===`bad_request`?`malformed-tree`:`transport-failure`,n,i)}function j(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function je(e){let t=new Te(e.limits.maxResponseBytes-4),n=w(e.deadline,`bridge-request-deadline`);return await new Promise((r,i)=>{let a=!1,o=!1,s=setTimeout(()=>{p(x(`timeout`,`bridge-request-deadline`,{dispatched:o})),e.socket.destroy()},n),c=()=>{p(x(`cancelled`,`abort-signal`,{dispatched:o})),e.socket.destroy()},l=n=>{try{if(!Buffer.isBuffer(n))throw x(`transport-failure`,`bridge-data-invalid`);let r=t.push(n);if(r){let t=Ee(r);if(Oe(t,e.requestId),ke(t,{pid:e.expectedPid,generation:e.expectedGeneration}),t.ok!==!0&&Ae(t),typeof t.truncated!=`boolean`)throw x(`malformed-tree`,`truncated-invalid`);f(t);return}}catch(t){p(t),e.socket.destroy()}},u=e=>p(S(e)),d=()=>{a||(e.process.isAlive()?p(x(`transport-failure`,`bridge-connection-closed`)):O(e.host,e.process).then(p))};e.process.wait.then(()=>{a||O(e.host,e.process).then(p)},e=>{a||p(S(e))});let f=e=>m(()=>r(e)),p=e=>m(()=>i(e)),m=t=>{a||(a=!0,clearTimeout(s),e.deadline.signal?.removeEventListener(`abort`,c),e.socket.off(`data`,l),e.socket.off(`error`,u),e.socket.off(`close`,d),t())};e.socket.on(`data`,l),e.socket.on(`error`,u),e.socket.on(`close`,d),e.deadline.signal?.addEventListener(`abort`,c,{once:!0});try{if(e.deadline.signal?.aborted)throw x(`cancelled`,`abort-signal`);o=!0,e.socket.write(e.frame)}catch(t){p(S(t)),e.socket.destroy()}})}var Me=class{sessions=new Map;requestQueues=new Map;ownerId=v();closed=!1;host;constructor(e){this.host=e}async request(e){if(this.closed)throw x(`unsupported`,`source-closed`);return await this.withSimulatorLock(e.target.udid,e.deadline,()=>this.requestInSimulator(e))}async requestInSimulator(e){if(this.closed)throw x(`unsupported`,`source-closed`);let t=e.deadline;w(t,`bridge-request-deadline`);let n=this.sessions.get(e.target.udid),r=await this.ensureSession(e,t);try{let n=await this.readTargetStartTime(e.target,t),i=await this.exchange(r,e,t);return await this.assertTargetStillCurrent(e.target,n,t),i}catch(e){throw await this.handleRequestFailure(e,r,n)}}async handleRequestFailure(e,t,n){let r=S(e);return Pe(r,t,n)?await this.removeSession(t,!0):r.failureKind===`process-crash`?await this.removeSession(t,!1):r.failureKind===`transport-failure`&&(t.socket?.destroy(),t.socket=void 0),r}async withSimulatorLock(e,t,n){let r=this.requestQueues.get(e)??Promise.resolve(),i,a=new Promise(e=>{i=e}),o=r.then(()=>a);this.requestQueues.set(e,o);try{return await Ne(r,t),await n()}finally{i(),this.requestQueues.get(e)===o&&this.requestQueues.delete(e)}}async close(){if(this.closed)return;this.closed=!0;let e=[...this.sessions.values()];this.sessions.clear(),await Promise.all(e.map(async e=>await this.dispose(e,!0)))}async ensureSession(e,t){let n=e.target.udid,r=this.sessions.get(n);if(r&&r.bridgePath===e.bridge.path&&r.process.isAlive())return(!r.socket||r.socket.destroyed)&&(r.socket=await this.connectUntilReady(r,t)),r;r&&await this.removeSession(r,!0);let i=xe(this.host,e.target.udid,this.ownerId);await this.host.ensureDirectory(g.dirname(i)),await this.host.remove(i);let a=this.host.start(e.target.udid,e.bridge.path,i,{signal:t.signal}),o={udid:e.target.udid,bridgePath:e.bridge.path,socketPath:i,process:a};this.sessions.set(n,o);try{return o.socket=await this.connectUntilReady(o,t),o}catch(e){throw await this.removeSession(o,!0),S(e)}}async connectUntilReady(e,t){let n;for(;;){let r=w(t,`bridge-connect-deadline`);if(!e.process.isAlive())throw await O(this.host,e.process);try{return await this.host.connect(e.socketPath,{signal:t.signal,timeoutMs:Math.min(250,r)})}catch(e){if(n=e,e instanceof b&&e.failureKind===`cancelled`)throw e;let r=Math.min(20,w(t,`bridge-connect-deadline`));try{await T(t,r,`bridge-connect-deadline`)}catch(e){throw S(e)}}if(n instanceof b&&n.failureKind===`timeout`)throw n}}async exchange(e,t,n){(!e.socket||e.socket.destroyed)&&(e.socket=await this.connectUntilReady(e,n));let r=v(),i=we(De({requestId:r,pid:t.target.pid,generation:t.target.generation,maxDepth:Math.min(t.limits.maxTraversalDepth,t.maxDepth),maxNodes:t.limits.maxNodes,maxDurationMs:w(n,`bridge-request-deadline`),maxResponseBytes:t.limits.maxResponseBytes,...t.nativeLevelsHint===void 0?{}:{nativeLevelsHint:t.nativeLevelsHint}}),t.limits);return await je({process:e.process,socket:e.socket,frame:i,requestId:r,deadline:n,limits:t.limits,expectedPid:t.target.pid,expectedGeneration:t.target.generation,host:this.host})}async readTargetStartTime(e,t){let n=await this.host.readTargetProcessStartTime(e.pid,{signal:t.signal,timeoutMs:w(t,`target-identity-deadline`)});if(!n)throw x(`stale-target`,`target-process-unavailable`,{pid:e.pid,generation:e.generation});if(e.processStartTime!==void 0&&e.processStartTime!==n)throw x(`stale-target`,`target-process-changed`,{pid:e.pid,generation:e.generation,expectedStartTime:e.processStartTime,observedStartTime:n});return n}async assertTargetStillCurrent(e,t,n){let r=await this.host.readTargetProcessStartTime(e.pid,{signal:n.signal,timeoutMs:w(n,`target-identity-deadline`)});if(r!==t)throw x(`stale-target`,`target-process-changed`,{pid:e.pid,generation:e.generation,expectedStartTime:t,observedStartTime:r})}async removeSession(e,t){this.sessions.get(e.udid)===e&&this.sessions.delete(e.udid),await this.dispose(e,t)}async dispose(e,t){e.socket?.destroy(),e.socket=void 0,t&&e.process.isAlive()&&(e.process.signal(`SIGTERM`),await M(e.process,500),e.process.isAlive()&&(e.process.signal(`SIGKILL`),await M(e.process,500))),await this.host.remove(e.socketPath)}};async function Ne(e,t){let n=w(t,`bridge-request-deadline`);await Promise.race([e,T(t,n,`bridge-request-deadline`).then(()=>{throw x(`timeout`,`bridge-request-deadline`)})])}function Pe(e,t,n){return(e.failureKind===`cancelled`||e.failureKind===`timeout`)&&(e.details?.dispatched===!0||n!==t)}async function M(e,t){await Promise.race([e.wait.catch(()=>void 0),new Promise(e=>setTimeout(e,t))])}const N=16777216,P=12e4,F=1e4,Fe=Object.freeze({maxRequestBytes:65536,maxResponseBytes:4194304,maxNodes:5e3,maxTraversalDepth:64,maxDurationMs:5e3});function I(t){let n={...Fe,...t??{}};for(let[t,r]of Object.entries(n))if(!Number.isSafeInteger(r)||r<=0)throw new e(`INVALID_ARGS`,`Snapshot source limit ${t} must be a positive integer`,{name:t,value:r});if(n.maxRequestBytes>n.maxResponseBytes)throw new e(`INVALID_ARGS`,`Snapshot source request bytes cannot exceed response bytes`,{maxRequestBytes:n.maxRequestBytes,maxResponseBytes:n.maxResponseBytes});if(n.maxRequestBytes>N||n.maxResponseBytes>N)throw new e(`INVALID_ARGS`,`Snapshot source frame limits exceed the bridge bound`,{maxRequestBytes:n.maxRequestBytes,maxResponseBytes:n.maxResponseBytes,maximumFrameBytes:N});if(n.maxNodes>F||n.maxTraversalDepth>128)throw new e(`INVALID_ARGS`,`Snapshot source tree limits exceed the bridge bound`,{maxNodes:n.maxNodes,maxTraversalDepth:n.maxTraversalDepth,maximumNodes:F,maximumDepth:128});if(n.maxDurationMs>P)throw new e(`INVALID_ARGS`,`Snapshot source duration exceeds the bridge bound`,{maxDurationMs:n.maxDurationMs,maximumDurationMs:P});if(n.maxRequestBytes<=4||n.maxResponseBytes<=4)throw new e(`INVALID_ARGS`,`Snapshot source frame limits must leave room for a body`,{maxRequestBytes:n.maxRequestBytes,maxResponseBytes:n.maxResponseBytes});return Object.freeze(n)}const L=[`SnapshotBridge.m`,`SnapshotBridgeRuntime.m`,`SnapshotBridgeRuntime.h`,`SnapshotBridgeCapture.h`,`SnapshotBridgeCapture.m`],Ie=[`SnapshotBridge.m`,`SnapshotBridgeRuntime.m`,`SnapshotBridgeCapture.m`];async function Le(e,t,n){let r=_(`sha256`);for(let i of L){let a=g.join(t,i);if(w(n,`native-source-fingerprint-deadline`),!e.exists(a))throw x(`unsupported`,`native-source-missing`,{filePath:a});r.update(i),r.update(`\0`),r.update(await e.readBinary(a)),r.update(`\0`)}return r.digest(`hex`)}async function Re(e,t,n){let r=await R(e,`xcodebuild`,[`-version`],n),i=await R(e,`sw_vers`,[`-productVersion`],n),a=await R(e,`sw_vers`,[`-buildVersion`],n),o=await R(e,`uname`,[`-m`],n),s=await R(e,`xcrun`,[`--sdk`,`iphonesimulator`,`--show-sdk-version`],n),c=t.trim();if(!c)throw x(`unsupported`,`simulator-runtime-missing`);if(o!==`arm64`&&o!==`x86_64`)throw x(`unsupported`,`simulator-architecture-unsupported`,{architecture:o});return{xcode:r,macosProductVersion:i,macosBuild:a,architecture:o,simulatorSdk:s,simulatorRuntime:c}}async function R(e,t,n,r){let i=await ze(e,t,n,r);if(i.exitCode!==0)throw x(`unsupported`,`toolchain-probe-failed`,{command:t,exitCode:i.exitCode,stderr:i.stderr.slice(0,1024)});let a=(i.stdout||i.stderr).trim();if(!a)throw x(`unsupported`,`toolchain-probe-empty`,{command:t});return a}async function ze(e,t,n,r){try{return await z(e,t,n,r)}catch(i){if(!d(i))throw i;if(r.signal?.aborted)throw x(`cancelled`,`abort-signal`);if(r.clock.remainingMs(r.now())<=0)throw i;return await z(e,t,n,r)}}function z(e,t,n,r){return e.run(t,n,{allowFailure:!0,signal:r.signal,timeoutMs:Math.min(h,w(r,`toolchain-probe-deadline`))})}const B=`snapshot-bridge`,V=`manifest.json`,H=12e4;async function Be(e){let t=e.deadline,n=e.sourceRoot??Ve(e.host),r=await Le(e.host,n,t),i=await Re(e.host,e.runtime,t),a=Ue({schemaVersion:1,protocolVersion:1,sourceVersion:k,sourceHash:r,toolchain:i}),o=e.cacheRoot??g.join(e.host.homeDirectory(),`.agent-device`,`snapshot-source`),s=g.join(o,a);return await f({acquire:()=>e.host.acquireLock(g.join(o,`${a}.lock`),{deadline:t}),task:async()=>{let c=await He(e.host,s,{sourceHash:r,cacheKey:a,toolchain:i},t);if(c)return c;w(t,`native-build-deadline`),e.host.exists(s)&&await e.host.remove(s),w(t,`native-build-deadline`),await e.host.ensureDirectory(o);let l=g.join(o,`.${a}.${e.host.processId()}.tmp`);w(t,`native-build-deadline`),await e.host.remove(l);try{w(t,`native-build-deadline`),await e.host.ensureDirectory(l);let o=g.join(l,B),c=await e.host.run(`xcrun`,[`--sdk`,`iphonesimulator`,`clang`,`-arch`,i.architecture,`-mios-simulator-version-min=15.0`,`-fobjc-arc`,`-Werror`,`-Wall`,`-Wextra`,`-framework`,`Foundation`,`-framework`,`CoreGraphics`,...Ie.map(e=>g.join(n,e)),`-o`,o],{signal:t.signal,timeoutMs:Math.min(H,w(t,`native-build-deadline`)),allowFailure:!0});if(c.exitCode!==0||!e.host.exists(o))throw x(`unsupported`,`native-build-failed`,{exitCode:c.exitCode,stderr:c.stderr.slice(0,4096)});w(t,`native-build-deadline`),await e.host.chmod(o,493);let u=await U(e.host,o,t),d={schemaVersion:1,protocolVersion:1,sourceVersion:k,sourceHash:r,cacheKey:a,toolchain:i,binarySha256:u};return await e.host.writeText(g.join(l,V),`${JSON.stringify(d,null,2)}\n`),w(t,`native-build-deadline`),await e.host.rename(l,s),{path:g.join(s,B),sourceHash:r,cacheKey:a,protocolVersion:1,sourceVersion:k}}catch(t){throw await e.host.remove(l),t}}})}function Ve(e){let t=e.projectRoot(),n=g.join(t,`apple`,`snapshot-bridge`);if(L.every(t=>e.exists(g.join(n,t))))return n;let r=g.join(t,`dist`,`apple`,`snapshot-bridge`);if(L.every(t=>e.exists(g.join(r,t))))return r;throw x(`unsupported`,`native-source-missing`,{projectRoot:t})}async function He(e,t,n,r){let i=g.join(t,B);if(!(!e.exists(i)||!e.exists(g.join(t,V))))try{let a=JSON.parse(await e.readText(g.join(t,V)));return a.schemaVersion!==1||a.protocolVersion!==1||a.sourceVersion!==`agent-device-simulator-ax-v1.6.0`||a.sourceHash!==n.sourceHash||a.cacheKey!==n.cacheKey||JSON.stringify(a.toolchain)!==JSON.stringify(n.toolchain)||typeof a.binarySha256!=`string`||await U(e,i,r)!==a.binarySha256?void 0:{path:i,sourceHash:n.sourceHash,cacheKey:n.cacheKey,protocolVersion:1,sourceVersion:k}}catch(e){if(e instanceof b&&(e.failureKind===`cancelled`||e.failureKind===`timeout`))throw e;return}}async function U(e,t,n){return w(n,`native-cache-hash-deadline`),_(`sha256`).update(await e.readBinary(t)).digest(`hex`)}function Ue(e){return _(`sha256`).update(JSON.stringify(e)).digest(`hex`).slice(0,32)}const We=h+H;function Ge(e){let t=e.now??Date.now,n=new Map,r=ue({waitMs:2e3,waitGrant:`first-caller`,retryAfterMs:6e4,now:t}),i=async(r,i)=>{let a=C(We,i,t);try{let t=await e.host.withDiagnosticTimer(`ios.snapshot-source.prepare`,async()=>await Be({host:e.host,runtime:r,limits:e.limits,deadline:a,sourceRoot:e.sourceRoot,cacheRoot:e.cacheRoot}),{producer:e.producer});return n.set(r,t),t}catch(e){throw S(e)}};return{readyBinary:async(e,t,a)=>n.get(e)||await r.value(e,{start:t=>i(e,t),wait:(e,n)=>T(t,e,a,n),pending:()=>x(`preparing`,`bridge-preparation-pending`)}),close:()=>{n.clear(),r.close()}}}function Ke(e,t){return!n(e)||!n(t)||Math.abs(t.width-t.height)<=1?!1:Math.abs(e.width-t.height)<=1&&Math.abs(e.height-t.width)<=1}const W=Object.freeze({elementType:`XC_kAXXCAttributeElementType`,elementBaseType:`XC_kAXXCAttributeElementBaseType`,label:`XC_kAXXCAttributeLabel`,value:`XC_kAXXCAttributeValue`,identifier:`XC_kAXXCAttributeIdentifier`,frame:`XC_kAXXCAttributeFrame`,automationType:`XC_kAXXCAttributeAutomationType`,traits:`XC_kAXXCAttributeTraits`,children:`XC_kAXXCAttributeChildren`}),G=`Other.Other.Application.Group.Window.Sheet.Drawer.Alert.Dialog.Button.RadioButton.RadioGroup.CheckBox.DisclosureTriangle.PopUpButton.ComboBox.MenuButton.ToolbarButton.Popover.Keyboard.Key.NavigationBar.TabBar.TabGroup.Toolbar.StatusBar.Table.TableRow.TableColumn.Outline.OutlineRow.Browser.CollectionView.Slider.PageIndicator.ProgressIndicator.ActivityIndicator.SegmentedControl.Picker.PickerWheel.Switch.Toggle.Link.Image.Icon.SearchField.ScrollView.ScrollBar.StaticText.TextField.SecureTextField.DatePicker.TextView.Menu.MenuItem.MenuBar.MenuBarItem.Map.WebView.IncrementArrow.DecrementArrow.Timeline.RatingIndicator.ValueIndicator.SplitGroup.Splitter.RelevanceIndicator.ColorWell.HelpTag.Matte.DockItem.Ruler.RulerMarker.Grid.LevelIndicator.Cell.LayoutArea.LayoutItem.Handle.Stepper.Tab.TouchBar.StatusItem`.split(`.`),K={UIApplication:`Application`,UIWindow:`Window`},qe=new Set(Object.values(W)),Je=1n<<8n,Ye={x:0,y:0,width:0,height:0};function Xe(e,t,n){let r=Array.isArray(e)?e:[e];if(r.length===0||r.some(e=>!j(e)))throw x(`malformed-tree`,`guest-tree-root-invalid`);let i=[],a=[],o=0;for(let e of r)c(e,void 0,0,!1);if(i.length>n.maxNodes)throw x(`malformed-tree`,`node-limit-exceeded`,{nodeCount:i.length,maxNodes:n.maxNodes});if(o>n.maxTraversalDepth)throw x(`malformed-tree`,`traversal-depth-exceeded`,{maxTraversalDepth:o,maxAllowedDepth:n.maxTraversalDepth});if(typeof t.truncated!=`boolean`)throw x(`malformed-tree`,`truncated-invalid`);let s=et(i.filter(Y)[0]);return{nodes:i,maxTraversalDepth:o,viewport:s,opaqueRemoteElements:a.filter(e=>$e(e,s)).length,unresolvedCoordinateSpaceWindows:tt(i,s)};function c(e,t,r,s){if(i.length>=n.maxNodes)throw x(`malformed-tree`,`node-limit-exceeded`,{maxNodes:n.maxNodes});for(let t of Object.keys(e))if(!qe.has(t))throw x(`malformed-tree`,`node-contains-unknown-field`,{key:t});let l=e[W.children];if(!Array.isArray(l))throw x(`malformed-tree`,`children-invalid`);let u=i.length,d=Ze(e,u,t,r);i.push(d),o=Math.max(o,r),Qe(d,l.length,s)&&a.push(d.rect);let f=s||d.type===`WebView`;for(let e of l){if(!j(e))throw x(`malformed-tree`,`child-invalid`);c(e,u,r+1,f)}}}function Ze(e,t,n,r){let i=X(e[W.elementType]),a=X(e[W.elementBaseType]),o=it(e[W.automationType]),s=J(e[W.frame]),c=rt(e[W.traits]);return{index:t,...n===void 0?{}:{parentIndex:n},...q(i,o)?{type:q(i,o)}:{},...i?{role:i}:{},...a&&a!==i?{subrole:a}:{},...X(e[W.label])?{label:X(e[W.label])}:{},...Z(e[W.value])?{value:Z(e[W.value])}:{},...X(e[W.identifier])?{identifier:X(e[W.identifier])}:{},...s?{rect:s}:{},...c===void 0?{}:{enabled:c},depth:r}}function q(e,t){if(e!==void 0&&K[e])return K[e];if(e!==void 0&&G.includes(e))return e;if(t!==void 0)return G[t]??`Other`}function Qe(e,t,n){return n&&e.role===`AXRemoteElement`&&t===0}function $e(e,t){return e===void 0?!0:n(e)?t.kind!==`reported`||r(e,t.rect):!1}function J(e){if(e===void 0)return;if(!j(e))throw x(`malformed-tree`,`frame-invalid`);let t=[`X`,`Y`,`Width`,`Height`].map(t=>e[t]);if(!t.every(e=>typeof e==`number`&&Number.isFinite(e)))throw x(`malformed-tree`,`frame-invalid`);let[n,r,i,a]=t;if(i<0||a<0)throw x(`malformed-tree`,`frame-invalid`);return{x:n,y:r,width:i,height:a}}function et(e){return!e||!Y(e)?{kind:`missing`,reason:`not-provided`}:n(e.rect)?{kind:`reported`,rect:e.rect}:{kind:`missing`,reason:e.rect?`invalid`:`not-provided`}}function Y(e){return e.type===`Application`||e.type===`Window`}function tt(e,t){return t.kind===`reported`?e.filter(n=>nt(n,e)&&Ke(n.rect??Ye,t.rect)).length:0}function nt(e,t){return Y(e)?!0:e.parentIndex!==void 0&&Y(t[e.parentIndex]??e)}function X(e){return typeof e==`string`&&e.length>0?e:void 0}function Z(e){if(typeof e==`string`)return e.length>0?e:void 0;if(typeof e==`number`||typeof e==`boolean`)return String(e);if(e!=null)throw x(`malformed-tree`,`scalar-invalid`)}function rt(e){if(e!=null){if(typeof e!=`string`||!/^\d{1,20}$/.test(e))throw x(`malformed-tree`,`traits-invalid`);return(BigInt(e)&Je)===0n}}function it(e){if(e!=null){if(!Number.isSafeInteger(e))throw x(`malformed-tree`,`automation-type-invalid`);return e}}const Q=`simulator-ax-bridge`;function at(e={}){let t=e.host??ge(),n=new Me(t),r=new he,i=Ge({host:t,limits:I(e.limits),producer:Q,sourceRoot:e.sourceRoot,cacheRoot:e.cacheRoot}),a=!1;return{acquire:async o=>{try{if(a)throw x(`unsupported`,`source-closed`);ot(o);let s=I({...e.limits,...o.limits}),c=C(s.maxDurationMs,o.signal),l=ct(o.hint,s.maxTraversalDepth),u=l+1,d=o.hint.rawTraversalDepth!==null;return await t.withDiagnosticTimer(`ios.snapshot-source.acquire`,async()=>{let e=await i.readyBinary(o.target.runtime,c,`bridge-preparation-deadline`),a=r.consume(o.target,u,d),f=await n.request({target:o.target,bridge:e,limits:s,maxDepth:l,nativeLevelsHint:a.nativeLevels,deadline:c});w(c,`snapshot-decode-deadline`);let p=lt(o.hint,o.target,f,s);return st(t,r,o.target,u,d,a,f),{stage:`acquired`,acquisition:p}},{producer:Q})}catch(e){let t=S(e);return{stage:`failed`,failure:{kind:t.failureKind,code:t.failureCode,...t.details?{details:t.details}:{}}}}},close:async()=>{a||(a=!0,i.close(),await n.close())}}}function ot(t){if(!t.target.udid.trim()||!t.target.runtime.trim()||!t.target.generation.trim()||!Number.isSafeInteger(t.target.pid)||t.target.pid<=0)throw new e(`INVALID_ARGS`,`Simulator snapshot source target identity is incomplete`);let n=t.hint;if(n.projection!==`raw`&&n.projection!==`regular`||![`full`,`surface-observation`].includes(n.acquisitionIntent)||typeof n.interactiveOnly!=`boolean`||typeof n.customActions!=`boolean`||!$(n.rawTraversalDepth)||!$(n.regularPresentedDepth))throw new e(`INVALID_ARGS`,`Simulator snapshot source capture hint is invalid`)}function st(e,t,n,r,i,a,o){let s=A(o),c=o.truncated===!0,l=t.learn(n,r,i,s);e.emitDiagnostic({level:`debug`,phase:`ios_snapshot_source_recovery`,data:{producer:Q,...n.targetId?{targetId:n.targetId}:{},generation:n.generation,requestedLevels:r,hint:a.reason,...a.nativeLevels===void 0?{}:{hintedLevels:a.nativeLevels},...s,truncated:c,learning:l}})}function ct(t,n){let r=t.rawTraversalDepth??n;if(r>n)throw new e(`INVALID_ARGS`,`Simulator snapshot source depth exceeds its bound`,{requested:r,maximum:n});return r}function $(e){return e===null||Number.isSafeInteger(e)&&e>=0}function lt(e,t,n,r){if(n.automationEnabled!==!0)throw x(`unsupported`,`automation-mode-unavailable`);let i=n.tree,a=n.truncated;if(typeof a!=`boolean`)throw x(`malformed-tree`,`truncated-invalid`);let o=Xe(i,{truncated:a},r),s=n.generation;if(typeof s!=`string`||!s)throw x(`malformed-tree`,`generation-invalid`);if(o.opaqueRemoteElements>0)throw x(`unsupported`,`remote-content-boundary`,{remoteElements:o.opaqueRemoteElements});if(o.unresolvedCoordinateSpaceWindows>0)throw x(`unsupported`,`window-coordinate-space-unresolved`,{windows:o.unresolvedCoordinateSpaceWindows});let c=Object.freeze(o.nodes.map(e=>Object.freeze({...e,pid:t.pid}))),l=ut(e,a,o.viewport),u=Object.freeze({...t.targetId?{targetId:t.targetId}:{},generation:s}),d={producer:Q,nodes:c,truncated:a,viewport:o.viewport,lineage:u,residue:l};return e.acquisitionIntent===`full`?{...d,intent:`full`,hint:{...e,acquisitionIntent:`full`}}:{...d,intent:`surface-observation`,hint:{...e,acquisitionIntent:`surface-observation`}}}function ut(e,t,n){return Object.freeze([{kind:`unavailable-fact`,fact:`hittability`},...e.interactiveOnly?[{kind:`unavailable-fact`,fact:`interactive-query`}]:[],...t?[{kind:`truncated`}]:[],...n.kind===`missing`?[{kind:`missing-viewport`,reason:n.reason}]:[]])}export{at as createSimulatorSnapshotSource};
|
package/dist/src/adb-executor.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{
|
|
2
|
-
`).map(e=>e.trim().split(/\s+/)).filter(e=>e.length>=3).map(([,e,t])=>{let r=e;return{local:r,remote:t,ownerId:n.get(r)}})}function A(e,t){let n=`${e}\n${t}`.toLowerCase();return n.includes(`listener`)&&n.includes(`not found`)}const j=new
|
|
1
|
+
import{D as e}from"./sdk-contracts.js";import{n as t,r as n,t as r}from"./device-shell.js";import{a as i,d as a,f as o,i as s,l as c,m as l,n as u,p as d,s as f,u as p}from"./adb-transport.js";import{c as m,n as h}from"./adb-failure.js";import{AsyncLocalStorage as g}from"node:async_hooks";let _;const v=new g;function y(e){_=e}function b(){if(!_)throw Error(`Android adb host port is not bound; import the platform composition wiring (src/platform-runtime-android-adb-host.ts) before using the adb/IME cluster.`);return _}async function x(e,t){let n=b(),r=v.getStore(),i=n.coerceAdbResult(r?await r(e,t):await n.execAdb(e,{...t,allowFailure:!0}));if(!t?.allowFailure&&i.exitCode!==0){let{androidAdbResultError:t}=await import(`./adb-failure.js`).then(e=>e.t),{serializeAndroidAdbInvocation:n}=await import(`./adb-transport.js`).then(e=>e.t);throw t(`adb ${n(e).join(` `)} exited with code ${i.exitCode}`,i)}return i}async function S(e,t){return await v.run(e,t)}function ee(e){b().emitDiagnostic(e)}const C=new WeakSet;function w(e){return T(typeof e==`function`?{exec:e}:e)}function T(e){if(C.has(e))return e;let t={...e,exec:m(E(e.exec)),...e.pull?{pull:m(E(e.pull))}:{},...e.install?{install:m(E(e.install))}:{},...e.installBundle?{installBundle:m(e.installBundle)}:{}};return C.add(t),t}function E(e){return async(...t)=>b().coerceAdbResult(await e(...t))}const D=new WeakSet;function te(t){let n=w(t);if(n.reverse&&D.has(n.reverse))return n.reverse;let r=n.reverse??O(n.exec),i=new Map,a={async ensure(t,n){let a=i.get(t.local);if(a&&a.ownerId!==t.ownerId)throw new e(`COMMAND_FAILED`,`Android port reverse ${t.local} is already owned by ${a.ownerId??`another session`}`,{current:a,requested:t});a?.remote!==t.remote&&(await r.ensure(t,n),i.set(t.local,{...t}))},async remove(e,t){if(!i.has(e)){await r.remove(e,t);return}await r.remove(e,t),i.delete(e)},async removeAllOwned(e,t){let n=[...i.values()].filter(t=>t.ownerId===e).map(e=>e.local);if(n.length===0){await r.removeAllOwned(e,t);return}for(let e of n)await r.remove(e,t),i.delete(e)},async list(e){return r.list?await r.list(e):[...i.values()]}};return D.add(a),a}function O(e){let t=new Map;return{async ensure(n,r){if(await e([`reverse`,n.local,n.remote],{allowFailure:!1,signal:r?.signal,timeoutMs:r?.timeoutMs}),n.ownerId){let e=t.get(n.ownerId)??new Set;e.add(n.local),t.set(n.ownerId,e)}},async remove(n,r){let i=await e([`reverse`,`--remove`,n],{allowFailure:!0,signal:r?.signal,timeoutMs:r?.timeoutMs});if(i.exitCode!==0&&!A(i.stdout,i.stderr))throw h(`Failed to remove Android port reverse ${n}`,i,{local:n});for(let e of t.values())e.delete(n)},async removeAllOwned(e,n){let r=[...t.get(e)??[]];for(let e of r)await this.remove(e,n);t.delete(e)},async list(n){let r=await e([`reverse`,`--list`],{allowFailure:!0,signal:n?.signal,timeoutMs:n?.timeoutMs});return r.exitCode===0?k(r.stdout,t):[]}}}function k(e,t){let n=new Map;for(let[e,r]of t)for(let t of r)n.set(t,e);return e.split(`
|
|
2
|
+
`).map(e=>e.trim().split(/\s+/)).filter(e=>e.length>=3).map(([,e,t])=>{let r=e;return{local:r,remote:t,ownerId:n.get(r)}})}function A(e,t){let n=`${e}\n${t}`.toLowerCase();return n.includes(`listener`)&&n.includes(`not found`)}const j=new g;function M(e,t={}){return Q(N(e.id,t.serverPort))}function N(e,t){return m(async(n,r)=>{let i=F(e,t,n,r);return await b().withoutAdbCommandExecutorOverride(async()=>await b().execAdb(i.invocation,i.options))})}function P(e,t){return $((n,r)=>{let i=F(e,t,n,r);return b().spawnAdb(i.invocation,i.options)})}function F(e,t,n,r){let{serverPort:i,...a}=r??{};return{invocation:I(e,n,L(e,t,i)),options:a}}function I(e,t,n){let r=p(t),i=u(r.target,e);if(n===void 0)return s(i,r.command,[`-s`,e,...t]);let a=f(r,{port:n});return s(o(a.target,e),a.command)}function L(e,t,n){let r=j.getStore();return r&&X(r,{kind:`serial`,serial:e}),r?.serverPort===void 0?t??n:(d(t,r.serverPort),d(n,r.serverPort))}function R(e,t={}){let n=M(e,t);return{exec:n,spawn:P(e.id,t.serverPort),reverse:O(n),pull:async(e,t,r)=>await n([`pull`,e,t],r),install:async(e,t)=>{let{installArgs:r,execOptions:i}=c(t);return await n([`install`,...r,e],i)}}}function z(e,t){let n=Y(e);return t?Q(t):n?.serial===e.id?Q(n.provider.exec):M(e)}function B(e,t){let n=Y(e);return ie(t?w(t):n?.serial===e.id?w(n.provider):R(e))}function V(e){let t=Y(e);return t?.serial===e.id?{mode:`transport-composed`,...t.provider.spawn?{spawn:$(t.provider.spawn)}:{}}:{mode:`local`}}function H(e){let t=Y(e);return t?.serial===e.id?t.provider.text:void 0}function U(e){let t=Y(e);return t?.serial===e.id&&t.provider.touch?t.provider:void 0}function W(e,t){if(t)return w(t);if(e)return B(e);let n=j.getStore();if(n)return w(n.provider)}async function G(e,t,n){if(!e)return await n();let r={provider:w(e),serial:t.serial,...t.serverPort===void 0?{}:{serverPort:t.serverPort}},i=K(r),a=async()=>await j.run(r,async()=>await b().withAdbCommandExecutorOverride(i,n));return t.serverPort===void 0?await a():await S(q(r,t.serverPort),a)}function K(e){return(t,n,r)=>{if(!Z(t)||e.serverPort===void 0&&t!==`adb`)return;let o=p(n);if(X(e,o.target.selector),o.target.selector.kind===`serial`){if(o.target.selector.serial!==e.serial)return;e.serverPort!==void 0&&a(o.target,e.serverPort);let t=i(n,e.serial);return t===void 0?void 0:b().withoutAdbCommandExecutorOverride(async()=>await e.provider.exec(t,r))}let s=e.serverPort;if(s!==void 0)return J(e,s,o,r)}}function q(e,t){return async(n,r)=>(X(e,n.target.selector),J(e,t,n,r))}async function J(e,t,n,r){d(t,r?.serverPort);let{serverPort:i,...a}=r??{},c=o(n.target,e.serial),l=f(s(c,n.command),{port:t}),u=b();return await u.withoutAdbCommandExecutorOverride(async()=>await u.execAdb(l,{...a,allowFailure:!0}))}function Y(e){let t=j.getStore();return t&&X(t,{kind:`serial`,serial:e.id}),t}function X(e,t){e?.serverPort!==void 0&&l(t,e.serial)}function Z(e){return n(e)===`adb`}async function ne(e,n,r){return await e(t(`adb`,`shell`,n),r)}async function re(e,n,r){return await e(t(`adb`,`exec-out`,n),r)}function Q(e){return async(t,n)=>(r(t,`adb`),await e(t,n))}function $(e){return(t,n)=>(r(t,`adb`),e(t,n))}function ie(e){return{...e,exec:Q(e.exec),...e.spawn?{spawn:$(e.spawn)}:{}}}async function ae(t,n,r){let{device:i,provider:a,...o}=r??{},s=W(i,a),c=s?.pull,l=b();if(c)return await l.withoutAdbCommandExecutorOverride(async()=>await c(t,n,o));let u=s?.exec;if(!u)throw new e(`COMMAND_FAILED`,`Android adb pull requires an adb provider`);return await l.withoutAdbCommandExecutorOverride(async()=>await u([`pull`,t,n],o))}async function oe(t,n){let{device:r,provider:i,...a}=n??{},o=W(r,i),s=o?.install,l=b();if(s)return await l.withoutAdbCommandExecutorOverride(async()=>await s(t,a));let u=o?.exec;if(!u)throw new e(`COMMAND_FAILED`,`Android adb install requires an adb provider`);let{installArgs:d,execOptions:f}=c(a);return await l.withoutAdbCommandExecutorOverride(async()=>await u([`install`,...d,t],f))}export{x as _,z as a,U as c,ne as d,G as f,b as g,ee as h,R as i,V as l,y as m,ae as n,B as o,te as p,M as r,H as s,oe as t,re as u,S as v};
|
package/dist/src/adb-failure.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime.js";import{
|
|
1
|
+
import{r as e}from"./rolldown-runtime.js";import{D as t}from"./sdk-contracts.js";import{r as n}from"./exec.js";import"./command.js";var r=e({androidAdbResultError:()=>u,androidDiscoveryCommandError:()=>f,attachAdbFailureHint:()=>s,attachAndroidDiscoveryTimeout:()=>p,attachAndroidHelperInstallTimeoutHint:()=>c,classifyAndroidAdbFailure:()=>o,withAdbFailureHints:()=>d});const i=[[/device unauthorized|device still authorizing/,{reason:`device_unauthorized`,hint:`USB debugging is not authorized — accept the authorization prompt on the device screen (re-plug the cable if none appears), then retry.`}],[/device offline/,{reason:`device_offline`,hint:`The device is connected but offline — wait for it to finish booting or run adb reconnect, then retry.`,retriable:!0}],[/more than one (?:device\/emulator|device and emulator)/,{reason:`multiple_devices`,hint:`Multiple Android devices are connected — pass --serial <serial> (see adb devices) to select one.`}],[/no devices\/emulators found|no devices found/,{reason:`no_devices`,hint:`No Android devices detected — boot an emulator or connect a device and verify it appears in adb devices.`}],[/device (?:'[^']*' )?not found/,{reason:`device_not_found`,hint:`The device disconnected or is restarting — verify it is listed in adb devices, then retry.`,retriable:!0}],[/adb server version \(\d+\) doesn't match this client/,{reason:`server_version_mismatch`,hint:`Multiple adb installs conflict — adb restarts its server automatically, so retry; align PATH to a single adb to stop recurrences.`,retriable:!0}],[/transport error|connection reset|broken pipe|protocol fault/,{reason:`connection_dropped`,hint:`The adb connection dropped — retry; if it persists, run adb kill-server and reconnect the device.`,retriable:!0}],[/install_failed_insufficient_storage/,{reason:`install_insufficient_storage`,hint:`The device is out of storage — free up space or uninstall unused apps, then retry the install.`},!0],[/install_failed_update_incompatible/,{reason:`install_update_incompatible`,hint:`The installed app has an incompatible signature — uninstall the existing app first, then retry the install.`},!0],[/install_failed_version_downgrade/,{reason:`install_version_downgrade`,hint:`The APK is older than the installed app — uninstall the app first (or install with downgrade allowed), then retry.`},!0],[/install_failed_\w+|install_parse_failed_\w+/,{reason:`install_failed`,hint:`The Android package installer rejected the APK — see the INSTALL_FAILED code in the error output for the exact cause.`},!0]],a=Object.freeze({reason:`timeout`,hint:`adb timed out — the adb server may be wedged. Run adb kill-server && adb start-server, check adb devices, then retry.`});function o(e,t=``){let n=e.toLowerCase(),r=t.toLowerCase();for(let[e,t,a]of i)if(e.test(n)||a&&e.test(r))return t}function s(e){if(!(e instanceof t)||e.code!==`COMMAND_FAILED`)return e;let n=l(e);return n&&(e.details={...e.details,adbFailure:n.reason,...typeof e.details?.hint==`string`?{}:{hint:n.hint},...n.retriable!==void 0&&e.details?.retriable===void 0?{retriable:n.retriable}:{}}),e}function c(e){if(!n(e))return e;let t=e.details?.hint;if(typeof t==`string`&&t!==a.hint)return e;let r=s(e);return r.details={...r.details,hint:`The helper install timed out — some OEM builds (ColorOS is one) hold the first install of each package behind a system install-confirmation dialog and adb waits for it. Check the device screen, confirm any pending install prompt, then retry; if none is showing, run adb kill-server && adb start-server and retry.`},r}function l(e){return typeof e.details?.timeoutMs==`number`?a:o(typeof e.details?.stderr==`string`?e.details.stderr:``,typeof e.details?.stdout==`string`?e.details.stdout:``)}function u(e,n,r){let i=n.exitCode===0?{stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode,...r}:{stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode,processExitError:!0,...r};return s(new t(`COMMAND_FAILED`,e,i))}function d(e){return async(...t)=>{try{return await e(...t)}catch(e){throw s(e)}}}function f(e,n,r){let i=o(n.stderr,n.stdout);return new t(`COMMAND_FAILED`,e,{stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode,processExitError:!0,hint:i?.hint??r,...i?{adbFailure:i.reason}:{},...i?.retriable===void 0?{}:{retriable:i.retriable}})}function p(e){return n(e)&&(e.details={...e.details,adbFailure:a.reason,...typeof e.details?.hint==`string`?{}:{hint:a.hint}}),e}export{p as a,d as c,s as i,u as n,c as o,f as r,o as s,r as t};
|