agent-device 0.21.16 → 0.21.17
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.16.apk → agent-device-android-ime-helper-0.21.17.apk} +0 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.17.apk.sha256 +1 -0
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.16.manifest.json → agent-device-android-ime-helper-0.21.17.manifest.json} +4 -4
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.16.apk → agent-device-android-snapshot-helper-0.21.17.apk} +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.17.apk.sha256 +1 -0
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.16.manifest.json → agent-device-android-snapshot-helper-0.21.17.manifest.json} +6 -6
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandDispatch.swift +31 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +1 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +1 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +9 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +40 -6
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +4 -0
- package/dist/src/adapter.js +1 -1
- package/dist/src/adb-executor.js +1 -1
- package/dist/src/adb-failure.js +1 -1
- package/dist/src/adb-transport.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/app-catalog.js +1 -1
- package/dist/src/app-deployment-resolution.js +1 -1
- package/dist/src/app-inventory.js +1 -1
- package/dist/src/app-launch.js +1 -1
- package/dist/src/app-lifecycle.js +1 -1
- package/dist/src/app-lifecycle2.js +1 -1
- package/dist/src/app-log-files.js +1 -1
- package/dist/src/app-log-runtime2.js +1 -1
- package/dist/src/app-resolution.js +2 -2
- 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/cache.js +1 -0
- package/dist/src/capture.js +1 -1
- package/dist/src/cli-config.js +1 -1
- package/dist/src/cli-help.js +6 -5
- package/dist/src/cli-runner.js +1 -1
- package/dist/src/cli.js +4 -4
- package/dist/src/click-button.js +1 -1
- package/dist/src/client-metro-companion.js +1 -1
- package/dist/src/client-metro.js +1 -1
- package/dist/src/client-types.d.ts +5 -5
- package/dist/src/clipboard-shell-response.js +1 -1
- package/dist/src/code-signature-cache.js +1 -1
- package/dist/src/command-schema.js +3 -3
- package/dist/src/command-tools.js +3 -3
- package/dist/src/connection-runtime.js +1 -1
- package/dist/src/connection.js +1 -1
- package/dist/src/contracts.js +1 -1
- package/dist/src/daemon-client-lease-beat.js +1 -1
- package/dist/src/daemon-client-lifecycle.js +1 -1
- package/dist/src/daemon-client-transport.js +1 -1
- package/dist/src/daemon-policy-file.js +1 -0
- package/dist/src/daemon-process.js +1 -1
- package/dist/src/daemon-registration.js +1 -1
- package/dist/src/daemon-shutdown-report.js +1 -1
- package/dist/src/daemon.js +1 -1
- package/dist/src/debug-symbols-facade.js +1 -1
- package/dist/src/device-claim-inspection.js +1 -1
- package/dist/src/device-claim-rule.js +1 -2
- package/dist/src/device-inventory-context.js +1 -1
- package/dist/src/{stop-sequence.js → device-readiness-runtime.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 -1
- package/dist/src/device.js +1 -1
- package/dist/src/device2.js +1 -1
- package/dist/src/devicectl.js +1 -1
- package/dist/src/diagnostics.js +1 -1
- package/dist/src/dispatch-resolve.js +1 -1
- 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/format.js +1 -2
- 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/helper.js +2 -2
- package/dist/src/host.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/interaction2.js +1 -1
- package/dist/src/interactor-operation-binding.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.js +1 -1
- package/dist/src/internal/run-script-http-child.js +1 -1
- package/dist/src/inventory.js +1 -1
- package/dist/src/inventory2.js +1 -1
- package/dist/src/inventory3.js +1 -1
- package/dist/src/inventory5.js +1 -1
- package/dist/src/ios-snapshot-runtime.js +1 -1
- package/dist/src/lease.js +1 -1
- package/dist/src/legacy-xctest-device-set.js +1 -0
- package/dist/src/limrun-download-file.js +1 -1
- package/dist/src/limrun-runtime-dependencies.js +1 -1
- package/dist/src/limrun.d.ts +1 -1
- package/dist/src/linux.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 +10 -10
- package/dist/src/multitouch-support.js +1 -1
- package/dist/src/observation.js +1 -1
- package/dist/src/overlay.js +3 -3
- package/dist/src/owner-identity.js +3 -3
- package/dist/src/parameterized-recorded-fill.js +1 -1
- package/dist/src/perf-facade.js +1 -1
- package/dist/src/perf-runtime-operation-builder.js +1 -1
- package/dist/src/perf-runtime-plan.js +1 -1
- package/dist/src/perf-target.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-app-log-process.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 +2 -2
- package/dist/src/platform-runtime-runtime-hints.js +1 -1
- package/dist/src/platform-runtime-screen-recording-apple-simulator-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-finalizer-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-process-host.js +1 -1
- package/dist/src/platform-runtime-unavailable.js +1 -1
- package/dist/src/platform-runtime.js +1 -1
- package/dist/src/platform-runtime2.js +1 -1
- package/dist/src/png-crop-bytes.js +1 -1
- package/dist/src/png-size.js +1 -1
- package/dist/src/png-worker-client.js +1 -1
- package/dist/src/png.js +1 -1
- package/dist/src/prepare-kind.js +1 -1
- package/dist/src/process.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 +2 -2
- 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/recording.js +1 -1
- package/dist/src/register-builtins.js +1 -1
- package/dist/src/registry.js +36 -36
- package/dist/src/remote-config2.js +1 -1
- package/dist/src/replay-divergence.js +1 -1
- package/dist/src/replay.js +1 -1
- 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 +3 -3
- package/dist/src/runner-client.js +1 -1
- package/dist/src/runner-command-traits.js +1 -0
- package/dist/src/runner-dev-tools-security.js +1 -1
- package/dist/src/runner-device-readiness.js +1 -1
- package/dist/src/runner-disposal.js +1 -1
- package/dist/src/runner-error-classification.js +2 -2
- package/dist/src/runner-exchange.js +1 -0
- package/dist/src/runner-operations-facade.js +1 -1
- package/dist/src/runner-owner-facade.js +1 -1
- package/dist/src/runner-session-types.js +1 -0
- package/dist/src/runner-start-budget.js +1 -0
- package/dist/src/runner-startup-transport.js +1 -0
- package/dist/src/runner-xctestrun.js +1 -0
- package/dist/src/runner.js +1 -1
- package/dist/src/runtime-transport-hints.js +1 -1
- package/dist/src/runtime.js +1 -1
- package/dist/src/runtime10.js +2 -2
- package/dist/src/runtime2.js +3 -3
- 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 -1
- 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 -1
- package/dist/src/screenshot-density.js +1 -1
- package/dist/src/screenshot-image.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.d.ts +4 -1
- package/dist/src/scroll-command.js +1 -1
- package/dist/src/scroll-gesture.js +1 -1
- package/dist/src/sdk-batch-runner.js +1 -1
- package/dist/src/sdk-batch.js +2 -2
- package/dist/src/sdk-contracts.d.ts +10 -0
- package/dist/src/sdk-contracts.js +2 -2
- package/dist/src/sdk-device.js +1 -1
- package/dist/src/sdk-io.js +1 -1
- package/dist/src/sdk-remote-config.js +1 -1
- package/dist/src/selection.js +0 -0
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/server.js +1 -1
- package/dist/src/session-allocation.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 +1 -1
- package/dist/src/session2.js +5 -4
- package/dist/src/settings.js +1 -1
- package/dist/src/settings2.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-runtime-binding.js +1 -1
- package/dist/src/snapshot-runtime.js +1 -1
- package/dist/src/snapshot-state.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/src7.js +1 -1
- package/dist/src/src8.js +2 -2
- package/dist/src/string-enum.js +1 -1
- package/dist/src/takeover.js +1 -1
- package/dist/src/target-evidence.js +1 -0
- 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 +2 -2
- package/dist/src/tv-remote.js +1 -1
- package/dist/src/type-text-runtime.js +1 -1
- package/dist/src/vars.js +2 -0
- 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/package.json +1 -1
- package/server.json +2 -2
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.16.apk.sha256 +0 -1
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.16.apk.sha256 +0 -1
- package/dist/src/capture-disclosure.js +0 -1
- package/dist/src/fold-runtime.js +0 -1
- package/dist/src/native-build-cache.js +0 -1
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
8217a388cb181b785090b23258a1c412319d03869d9627f9ee5a81f6746fbe48 agent-device-android-ime-helper-0.21.17.apk
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "android-ime-helper",
|
|
3
|
-
"version": "0.21.
|
|
4
|
-
"assetName": "agent-device-android-ime-helper-0.21.
|
|
5
|
-
"sha256": "
|
|
3
|
+
"version": "0.21.17",
|
|
4
|
+
"assetName": "agent-device-android-ime-helper-0.21.17.apk",
|
|
5
|
+
"sha256": "8217a388cb181b785090b23258a1c412319d03869d9627f9ee5a81f6746fbe48",
|
|
6
6
|
"packageName": "com.callstack.agentdevice.imehelper",
|
|
7
|
-
"versionCode":
|
|
7
|
+
"versionCode": 21017,
|
|
8
8
|
"serviceComponent": "com.callstack.agentdevice.imehelper/.TestInputMethodService",
|
|
9
9
|
"broadcastProtocol": "android-ime-helper-v1"
|
|
10
10
|
}
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
b8801f4de4f76f9ed646694b0b0785c511a7a3cfef2744bdd746055176e1bf06 agent-device-android-snapshot-helper-0.21.17.apk
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "android-snapshot-helper",
|
|
3
|
-
"version": "0.21.
|
|
4
|
-
"releaseTag": "v0.21.
|
|
5
|
-
"assetName": "agent-device-android-snapshot-helper-0.21.
|
|
3
|
+
"version": "0.21.17",
|
|
4
|
+
"releaseTag": "v0.21.17",
|
|
5
|
+
"assetName": "agent-device-android-snapshot-helper-0.21.17.apk",
|
|
6
6
|
"apkUrl": null,
|
|
7
|
-
"sha256": "
|
|
8
|
-
"checksumName": "agent-device-android-snapshot-helper-0.21.
|
|
7
|
+
"sha256": "b8801f4de4f76f9ed646694b0b0785c511a7a3cfef2744bdd746055176e1bf06",
|
|
8
|
+
"checksumName": "agent-device-android-snapshot-helper-0.21.17.apk.sha256",
|
|
9
9
|
"packageName": "com.callstack.agentdevice.snapshothelper",
|
|
10
|
-
"versionCode":
|
|
10
|
+
"versionCode": 21017,
|
|
11
11
|
"instrumentationRunner": "com.callstack.agentdevice.snapshothelper/.SnapshotInstrumentation",
|
|
12
12
|
"minSdk": 23,
|
|
13
13
|
"targetSdk": 36,
|
|
@@ -68,6 +68,35 @@ extension RunnerTests {
|
|
|
68
68
|
|
|
69
69
|
|
|
70
70
|
|
|
71
|
+
|
|
72
|
+
@MainActor
|
|
73
|
+
func executePasteboardWrite(command: Command) -> Response {
|
|
74
|
+
guard let text = command.text else {
|
|
75
|
+
return Response(
|
|
76
|
+
ok: false,
|
|
77
|
+
error: ErrorPayload(
|
|
78
|
+
code: "INVALID_ARGS",
|
|
79
|
+
message: "pasteboardWrite requires text",
|
|
80
|
+
hint: "Set text to the string the pasteboard should hold."
|
|
81
|
+
)
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
#if os(iOS) || os(visionOS)
|
|
85
|
+
UIPasteboard.general.string = text
|
|
86
|
+
return Response(ok: true, data: DataPayload(message: "pasteboard written"))
|
|
87
|
+
#else
|
|
88
|
+
return Response(
|
|
89
|
+
ok: false,
|
|
90
|
+
error: ErrorPayload(
|
|
91
|
+
code: "UNSUPPORTED_OPERATION",
|
|
92
|
+
message: "pasteboardWrite is supported on iOS and visionOS runners"
|
|
93
|
+
)
|
|
94
|
+
)
|
|
95
|
+
#endif
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
|
|
71
100
|
static func applicationStateName(_ state: XCUIApplication.State) -> String {
|
|
72
101
|
switch state {
|
|
73
102
|
case .unknown: return "unknown"
|
|
@@ -423,6 +452,8 @@ extension RunnerTests {
|
|
|
423
452
|
return executeUptime()
|
|
424
453
|
case .appState:
|
|
425
454
|
return executeAppState(command: command)
|
|
455
|
+
case .pasteboardWrite:
|
|
456
|
+
return executePasteboardWrite(command: command)
|
|
426
457
|
case .activate:
|
|
427
458
|
guard
|
|
428
459
|
let bundleId = command.appBundleId?.trimmingCharacters(in: .whitespacesAndNewlines),
|
|
@@ -14,7 +14,7 @@ extension RunnerTests {
|
|
|
14
14
|
}
|
|
15
15
|
switch command.command {
|
|
16
16
|
case .status, .activate, .terminate, .targetReset, .shutdown, .recordStart, .recordStop, .uptime,
|
|
17
|
-
.appState, .snapshot:
|
|
17
|
+
.appState, .pasteboardWrite, .snapshot:
|
|
18
18
|
return Response(
|
|
19
19
|
ok: false,
|
|
20
20
|
error: ErrorPayload(
|
|
@@ -139,7 +139,7 @@ final class RunnerCommandJournal {
|
|
|
139
139
|
.remotePress, .type, .swipe, .scroll, .desktopScroll, .findText, .querySelector, .readText,
|
|
140
140
|
.backInApp, .backSystem, .home, .rotate, .appSwitcher, .actionButton, .keyboardDismiss, .keyboardReturn,
|
|
141
141
|
.alert, .sequence, .gesture, .gestureViewport, .recordStart, .recordStop,
|
|
142
|
-
.status, .uptime, .appState, .activate, .terminate, .targetReset, .shutdown:
|
|
142
|
+
.status, .uptime, .appState, .pasteboardWrite, .activate, .terminate, .targetReset, .shutdown:
|
|
143
143
|
return true
|
|
144
144
|
}
|
|
145
145
|
}
|
package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift
CHANGED
|
@@ -34,6 +34,7 @@ enum CommandType: String, Codable, CaseIterable {
|
|
|
34
34
|
case status
|
|
35
35
|
case uptime
|
|
36
36
|
case appState
|
|
37
|
+
case pasteboardWrite
|
|
37
38
|
case activate
|
|
38
39
|
case terminate
|
|
39
40
|
case targetReset
|
|
@@ -152,6 +153,11 @@ fileprivate extension CommandTraits {
|
|
|
152
153
|
|
|
153
154
|
|
|
154
155
|
|
|
156
|
+
static let deviceState = CommandTraits(launchPolicy: .noApp)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
|
|
155
161
|
static let presentedSurfaceMutation = CommandTraits(
|
|
156
162
|
launchPolicy: .presentedSurface,
|
|
157
163
|
convertsRecordedFailure: true
|
|
@@ -253,6 +259,9 @@ extension Command {
|
|
|
253
259
|
case .recordStop, .uptime, .terminate, .targetReset, .shutdown:
|
|
254
260
|
return .runnerLifecycle
|
|
255
261
|
|
|
262
|
+
case .pasteboardWrite:
|
|
263
|
+
return .deviceState
|
|
264
|
+
|
|
256
265
|
case .actionButton:
|
|
257
266
|
return .presentedSurfaceMutation
|
|
258
267
|
|
|
@@ -209,6 +209,19 @@ extension RunnerTests {
|
|
|
209
209
|
|
|
210
210
|
|
|
211
211
|
|
|
212
|
+
static func planVerdictReason(
|
|
213
|
+
xCTestTierRan: Bool,
|
|
214
|
+
state: SnapshotXCTestChannelPlanState,
|
|
215
|
+
firstFailure: (reason: String, code: String)?
|
|
216
|
+
) -> (reason: String, code: String)? {
|
|
217
|
+
guard xCTestTierRan, state == .deferredToIndependentBackend else { return firstFailure }
|
|
218
|
+
return xcTestChannelStateFirstFailure(.boundedXCTestProbe)
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
|
|
212
225
|
static func snapshotXCTestChannelTreatedAsPenalized(
|
|
213
226
|
penalized: Bool,
|
|
214
227
|
preferredBackend: String?
|
|
@@ -251,10 +264,14 @@ extension RunnerTests {
|
|
|
251
264
|
let availablePlan = plan.filter { availableBackends.contains($0) }
|
|
252
265
|
let recoveryPlan = availablePlan.filter { !$0.usesXCTestAccessibilityChannel }
|
|
253
266
|
if !recoveryPlan.isEmpty {
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
|
|
254
271
|
return EffectiveSnapshotCapturePlan(
|
|
255
|
-
plan: recoveryPlan,
|
|
272
|
+
plan: recoveryPlan + availablePlan.filter { $0 == .recursiveTree },
|
|
256
273
|
xCTestChannelState: .deferredToIndependentBackend,
|
|
257
|
-
treeCaptureSliceBudgetOverride:
|
|
274
|
+
treeCaptureSliceBudgetOverride: Self.penalizedXCTestProbeTreeSliceBudget,
|
|
258
275
|
preferredBackend: nil
|
|
259
276
|
)
|
|
260
277
|
}
|
|
@@ -285,6 +302,7 @@ extension RunnerTests {
|
|
|
285
302
|
|
|
286
303
|
let deadline = deadline ?? Date().addingTimeInterval(Self.snapshotPlanBudget)
|
|
287
304
|
let suppressXCTestPenalty = snapshotXCTestPenaltyWarmupExemption.consume()
|
|
305
|
+
var xCTestTierRan = false
|
|
288
306
|
|
|
289
307
|
|
|
290
308
|
|
|
@@ -344,6 +362,7 @@ extension RunnerTests {
|
|
|
344
362
|
}
|
|
345
363
|
continue
|
|
346
364
|
}
|
|
365
|
+
if kind.usesXCTestAccessibilityChannel { xCTestTierRan = true }
|
|
347
366
|
let attempt = try captureWithBackend(
|
|
348
367
|
kind,
|
|
349
368
|
target: target,
|
|
@@ -391,18 +410,23 @@ extension RunnerTests {
|
|
|
391
410
|
}
|
|
392
411
|
|
|
393
412
|
let recovered = kind != effectivePlan.first || effective.xCTestChannelState != .normal
|
|
413
|
+
let verdictReason = Self.planVerdictReason(
|
|
414
|
+
xCTestTierRan: kind.usesXCTestAccessibilityChannel,
|
|
415
|
+
state: effective.xCTestChannelState,
|
|
416
|
+
firstFailure: firstFailure
|
|
417
|
+
)
|
|
394
418
|
if recovered {
|
|
395
419
|
NSLog(
|
|
396
420
|
"AGENT_DEVICE_RUNNER_SNAPSHOT_RECOVERED backend=%@ reason=%@",
|
|
397
421
|
kind.rawValue,
|
|
398
|
-
|
|
422
|
+
verdictReason?.reason ?? "sparse tree"
|
|
399
423
|
)
|
|
400
424
|
}
|
|
401
425
|
return stampedSnapshotPayload(
|
|
402
426
|
capture,
|
|
403
427
|
backend: kind,
|
|
404
428
|
state: recovered ? .recovered : .healthy,
|
|
405
|
-
reason: recovered || firstFailure?.code == "requested-backend" ?
|
|
429
|
+
reason: recovered || firstFailure?.code == "requested-backend" ? verdictReason : nil
|
|
406
430
|
)
|
|
407
431
|
}
|
|
408
432
|
|
|
@@ -425,13 +449,18 @@ extension RunnerTests {
|
|
|
425
449
|
}
|
|
426
450
|
}
|
|
427
451
|
|
|
452
|
+
let terminalReason = Self.planVerdictReason(
|
|
453
|
+
xCTestTierRan: xCTestTierRan,
|
|
454
|
+
state: effective.xCTestChannelState,
|
|
455
|
+
firstFailure: firstFailure
|
|
456
|
+
)
|
|
428
457
|
let fallbackPayload =
|
|
429
|
-
best.map { stampedSnapshotPayload($0.capture, backend: $0.kind, state: .sparse, reason:
|
|
458
|
+
best.map { stampedSnapshotPayload($0.capture, backend: $0.kind, state: .sparse, reason: terminalReason) }
|
|
430
459
|
?? stampedSnapshotPayload(
|
|
431
460
|
SnapshotBackendCapture(payload: sparseTruncatedSnapshotPayload(), effectiveDepth: nil),
|
|
432
461
|
backend: effectivePlan.last ?? plan.last ?? .recursiveTree,
|
|
433
462
|
state: .sparse,
|
|
434
|
-
reason:
|
|
463
|
+
reason: terminalReason
|
|
435
464
|
)
|
|
436
465
|
return fallbackPayload
|
|
437
466
|
}
|
|
@@ -491,6 +520,11 @@ extension RunnerTests {
|
|
|
491
520
|
}
|
|
492
521
|
return (sweep.acquisition, sweep.outcome)
|
|
493
522
|
case .privateAX:
|
|
523
|
+
|
|
524
|
+
|
|
525
|
+
|
|
526
|
+
|
|
527
|
+
|
|
494
528
|
return (
|
|
495
529
|
self.privateAXSnapshotAcquisition(
|
|
496
530
|
target: target,
|
package/dist/src/adapter.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{M as e}from"./sdk-contracts.js";import{Jr as t,Yr as n,qr as r}from"./sdk-batch.js";import{t as i}from"./apple-runner-platform.js";import{_ as a,a as o,d as s,f as c,h as l,i as u,l as d,m as f,n as p,o as m,p as h,r as g,s as _,t as ee,u as v}from"./native-build-cache.js";import y from"node:path";import{randomUUID as b}from"node:crypto";import{Buffer as x}from"node:buffer";var te=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 S=new WeakSet;async function C(e,t){let n;try{n=(await t.wait).exitCode}catch{n=void 0}return S.has(t)||(S.add(t),e.emitDiagnostic({level:`error`,phase:`ios.snapshot-source.bridge-process-exit`,data:{pid:t.pid,...n===void 0?{}:{exitCode:n},stderr:ne(t.readLog())}})),l(`process-crash`,`bridge-exited`,{pid:t.pid,...n===void 0?{}:{exitCode:n}})}function ne(e){let t=x.from(e);return t.length<=65536?e:t.subarray(-65536).toString(`utf8`)}const w=`agent-device-simulator-ax-v1.8.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_kAXXCAttributePlaceholderValue`,`XC_kAXXCAttributeIdentifier`,`XC_kAXXCAttributeFrame`,`XC_kAXXCAttributeAutomationType`,`XC_kAXXCAttributeTraits`,`XC_kAXXCAttributeIsUserInteractionEnabled`,`XC_kAXXCAttributeChildren`]);const T=[`requests`,`rejected`,`continuations`,`acceptedLevels`];function re(e){let t=e.recovery;if(!j(t))throw l(`malformed-tree`,`recovery-invalid`);let n=T.map(e=>[e,t[e]]);if(n.some(([,e])=>!Number.isSafeInteger(e)||e<0))throw l(`malformed-tree`,`recovery-invalid`);return Object.freeze(Object.fromEntries(n))}function ie(e,t){let n;try{n=x.from(JSON.stringify(e),`utf8`)}catch(e){throw l(`malformed-tree`,`request-not-json`,{},e)}let r=n.length+4;if(r>t.maxRequestBytes)throw l(`transport-failure`,`request-limit-exceeded`,{frameBytes:r,maxRequestBytes:t.maxRequestBytes});let i=x.alloc(4);return i.writeUInt32BE(n.length,0),x.concat([i,n])}var E=class{header=x.alloc(4);headerBytes=0;chunks=[];payloadBytes=0;expectedBodyBytes;frame;maxFrameBytes;constructor(e){if(!Number.isSafeInteger(e)||e<=0)throw l(`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=x.concat(this.chunks,t.bodyBytes),this.frame}acceptTrailingChunk(e){if(e.length>0)throw l(`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 l(`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 l(`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 l(`transport-failure`,`bridge-frame-incomplete`,{headerBytes:this.headerBytes,payloadBytes:this.payloadBytes,expectedBodyBytes:this.expectedBodyBytes})}};function ae(e){let t;try{t=JSON.parse(e.toString(`utf8`))}catch(e){throw l(`malformed-tree`,`response-not-json`,{},e)}if(!j(t))throw l(`malformed-tree`,`response-not-object`);return t}function D(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 O(e,t){if(e.protocolVersion!==1)throw l(`transport-failure`,`protocol-version-mismatch`,{expected:1,observed:e.protocolVersion});if(e.sourceVersion!==`agent-device-simulator-ax-v1.8.0`)throw l(`transport-failure`,`source-version-mismatch`,{expected:w,observed:e.sourceVersion});if(e.requestId!==t)throw l(`transport-failure`,`request-id-mismatch`,{expected:t,observed:e.requestId})}function k(e,t){if(typeof e.pid!=`number`||e.pid!==t.pid)throw l(`stale-target`,`bridge-pid-mismatch`,{expectedPid:t.pid,observedPid:e.pid});if(e.generation!==t.generation)throw l(`stale-target`,`bridge-generation-mismatch`,{expectedGeneration:t.generation,observedGeneration:e.generation})}function A(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 l(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 oe(e){let t=new E(e.limits.maxResponseBytes-4),n=s(e.deadline,`bridge-request-deadline`);return await new Promise((r,i)=>{let a=!1,o=!1,s=setTimeout(()=>{h(l(`timeout`,`bridge-request-deadline`,{dispatched:o})),e.socket.destroy()},n),c=()=>{h(l(`cancelled`,`abort-signal`,{dispatched:o})),e.socket.destroy()},u=n=>{try{if(!Buffer.isBuffer(n))throw l(`transport-failure`,`bridge-data-invalid`);let r=t.push(n);if(r){let t=ae(r);if(O(t,e.requestId),k(t,{pid:e.expectedPid,generation:e.expectedGeneration}),t.ok!==!0&&A(t),typeof t.truncated!=`boolean`)throw l(`malformed-tree`,`truncated-invalid`);m(t);return}}catch(t){h(t),e.socket.destroy()}},d=e=>h(f(e)),p=()=>{a||(e.process.isAlive()?h(l(`transport-failure`,`bridge-connection-closed`)):C(e.host,e.process).then(h))};e.process.wait.then(()=>{a||C(e.host,e.process).then(h)},e=>{a||h(f(e))});let m=e=>g(()=>r(e)),h=e=>g(()=>i(e)),g=t=>{a||(a=!0,clearTimeout(s),e.deadline.signal?.removeEventListener(`abort`,c),e.socket.off(`data`,u),e.socket.off(`error`,d),e.socket.off(`close`,p),t())};e.socket.on(`data`,u),e.socket.on(`error`,d),e.socket.on(`close`,p),e.deadline.signal?.addEventListener(`abort`,c,{once:!0});try{if(e.deadline.signal?.aborted)throw l(`cancelled`,`abort-signal`);o=!0,e.socket.write(e.frame)}catch(t){h(f(t)),e.socket.destroy()}})}var se=class{sessions=new Map;requestQueues=new Map;ownerId=b();closed=!1;host;constructor(e){this.host=e}async request(e){if(this.closed)throw l(`unsupported`,`source-closed`);return await this.withSimulatorLock(e.target.simulator.udid,e.deadline,()=>this.requestInSimulator(e))}async requestInSimulator(e){if(this.closed)throw l(`unsupported`,`source-closed`);let t=e.deadline;s(t,`bridge-request-deadline`);let n=this.sessions.get(e.target.simulator.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=f(e);return le(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 ce(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.simulator.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=o(this.host,e.target.simulator.udid,this.ownerId);await this.host.ensureDirectory(y.dirname(i)),await this.host.remove(i);let a=this.host.start(e.target.simulator,e.bridge.path,i,{signal:t.signal}),s={udid:e.target.simulator.udid,bridgePath:e.bridge.path,socketPath:i,process:a};this.sessions.set(n,s);try{return s.socket=await this.connectUntilReady(s,t),s}catch(e){throw await this.removeSession(s,!0),f(e)}}async connectUntilReady(e,t){let n;for(;;){let r=s(t,`bridge-connect-deadline`);if(!e.process.isAlive())throw await C(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 h&&e.failureKind===`cancelled`)throw e;let r=Math.min(20,s(t,`bridge-connect-deadline`));try{await c(t,r,`bridge-connect-deadline`)}catch(e){throw f(e)}}if(n instanceof h&&n.failureKind===`timeout`)throw n}}async exchange(e,t,n){(!e.socket||e.socket.destroyed)&&(e.socket=await this.connectUntilReady(e,n));let r=b(),i=ie(D({requestId:r,pid:t.target.pid,generation:t.target.generation,maxDepth:Math.min(t.limits.maxTraversalDepth,t.maxDepth),maxNodes:t.limits.maxNodes,maxDurationMs:s(n,`bridge-request-deadline`),maxResponseBytes:t.limits.maxResponseBytes,...t.nativeLevelsHint===void 0?{}:{nativeLevelsHint:t.nativeLevelsHint}}),t.limits);return await oe({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:s(t,`target-identity-deadline`)});if(!n)throw l(`stale-target`,`target-process-unavailable`,{pid:e.pid,generation:e.generation});if(e.processStartTime!==void 0&&e.processStartTime!==n)throw l(`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:s(n,`target-identity-deadline`)});if(r!==t)throw l(`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 ce(e,t){let n=s(t,`bridge-request-deadline`);await Promise.race([e,c(t,n,`bridge-request-deadline`).then(()=>{throw l(`timeout`,`bridge-request-deadline`)})])}function le(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,I=Object.freeze({maxRequestBytes:65536,maxResponseBytes:4194304,maxNodes:5e3,maxTraversalDepth:64,maxDurationMs:5e3});function L(t){let n={...I,...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 R=12e4;async function z(e){let t=e.deadline,n=e.sourceRoot??V(e.host),r=await g(e.host,n,_,t),i=await d(e.host,e.runtime,t),a=e.cacheRoot??y.join(e.host.homeDirectory(),`.agent-device`,`snapshot-source`),o=await ee({host:e.host,deadline:t,cacheRoot:a,binaryFilename:`snapshot-bridge`,lockDescription:`iOS Simulator snapshot bridge cache`,keyInputs:{schemaVersion:1,protocolVersion:1,sourceVersion:w,sourceHash:r,toolchain:i,compileArgv:B({architecture:i.architecture,sourceRoot:``,outputPath:``})},build:async r=>{let a=await p({host:e.host,deadline:t,argv:B({architecture:i.architecture,sourceRoot:n,outputPath:r}),budgetMs:R,label:`bridge`});if(a.exitCode!==0||!e.host.exists(r))throw l(`unsupported`,`native-build-failed`,{exitCode:a.exitCode,stderr:a.stderr.slice(0,4096)})}});return{path:o.path,sourceHash:r,cacheKey:o.cacheKey,protocolVersion:1,sourceVersion:w}}function B(e){return[`--sdk`,`iphonesimulator`,`clang`,`-arch`,e.architecture,`-mios-simulator-version-min=15.0`,`-fobjc-arc`,`-Wall`,`-Wextra`,`-framework`,`Foundation`,`-framework`,`CoreGraphics`,...m.map(t=>y.join(e.sourceRoot,t)),`-o`,e.outputPath]}function V(e){let t=e.projectRoot(),n=y.join(t,`apple`,`snapshot-bridge`);if(_.every(t=>e.exists(y.join(n,t))))return n;let r=y.join(t,`dist`,`apple`,`snapshot-bridge`);if(_.every(t=>e.exists(y.join(r,t))))return r;throw l(`unsupported`,`native-source-missing`,{projectRoot:t})}const H=i+R;function U(e){let t=e.now??Date.now,n=new Map,r=a({waitMs:2e3,waitGrant:`first-caller`,retryAfterMs:6e4,now:t}),i=async(r,i)=>{let a=v(H,i,t);try{let t=await e.host.withDiagnosticTimer(`ios.snapshot-source.prepare`,async()=>await z({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 f(e)}};return{readyBinary:async(e,t,a)=>n.get(e)||await r.value(e,{start:t=>i(e,t),wait:(e,n)=>c(t,e,a,n),pending:()=>l(`preparing`,`bridge-preparation-pending`)}),close:()=>{n.clear(),r.close()}}}function W(e,n){return!t(e)||!t(n)||Math.abs(n.width-n.height)<=1?!1:Math.abs(e.width-n.height)<=1&&Math.abs(e.height-n.width)<=1}const G=Object.freeze({elementType:`XC_kAXXCAttributeElementType`,elementBaseType:`XC_kAXXCAttributeElementBaseType`,label:`XC_kAXXCAttributeLabel`,value:`XC_kAXXCAttributeValue`,placeholder:`XC_kAXXCAttributePlaceholderValue`,identifier:`XC_kAXXCAttributeIdentifier`,frame:`XC_kAXXCAttributeFrame`,automationType:`XC_kAXXCAttributeAutomationType`,traits:`XC_kAXXCAttributeTraits`,userInteractionEnabled:`XC_kAXXCAttributeIsUserInteractionEnabled`,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`},ue=new Set(Object.values(G)),de=1n<<8n,fe=1n<<3n,pe={x:0,y:0,width:0,height:0};function me(e,t,n){let r=Array.isArray(e)?e:[e];if(r.length===0||r.some(e=>!j(e)))throw l(`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 l(`malformed-tree`,`node-limit-exceeded`,{nodeCount:i.length,maxNodes:n.maxNodes});if(o>n.maxTraversalDepth)throw l(`malformed-tree`,`traversal-depth-exceeded`,{maxTraversalDepth:o,maxAllowedDepth:n.maxTraversalDepth});if(typeof t.truncated!=`boolean`)throw l(`malformed-tree`,`truncated-invalid`);let s=ye(i.filter(Y)[0]);return s.kind===`reported`&&be(i,s.rect),{nodes:i,maxTraversalDepth:o,viewport:s,opaqueRemoteElements:a.filter(e=>_e(e,s)).length,unresolvedCoordinateSpaceWindows:xe(i,s)};function c(e,t,r,s){if(i.length>=n.maxNodes)throw l(`malformed-tree`,`node-limit-exceeded`,{maxNodes:n.maxNodes});for(let t of Object.keys(e))if(!ue.has(t))throw l(`malformed-tree`,`node-contains-unknown-field`,{key:t});let u=e[G.children];if(!Array.isArray(u))throw l(`malformed-tree`,`children-invalid`);let d=i.length,f=he(e,d,t,r);i.push(f),o=Math.max(o,r),ge(f,u.length,s)&&a.push(f.rect);let p=s||f.type===`WebView`;for(let e of u){if(!j(e))throw l(`malformed-tree`,`child-invalid`);c(e,d,r+1,p)}}}function he(e,t,n,r){let i=X(e[G.elementType]),a=X(e[G.elementBaseType]),o=Te(e[G.automationType]),s=ve(e[G.frame]),c=Ce(e[G.traits]),l=c===void 0?void 0:(c&de)===0n,u=c===void 0||(c&fe)===0n?void 0:!0,d=we(e[G.userInteractionEnabled]),f=X(e[G.placeholder])?.trim();return{index:t,...n===void 0?{}:{parentIndex:n},...J(i,o)?{type:J(i,o)}:{},...i?{role:i}:{},...a&&a!==i?{subrole:a}:{},...X(e[G.label])?{label:X(e[G.label])}:{},...Z(e[G.value])?{value:Z(e[G.value])}:{},...f?{placeholder:f}:{},...X(e[G.identifier])?{identifier:X(e[G.identifier])}:{},...s?{rect:s}:{},...l===void 0?{}:{enabled:l},...u===void 0?{}:{selected:u},...d===void 0?{}:{userInteractionEnabled:d},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 ge(e,t,n){return n&&e.role===`AXRemoteElement`&&t===0}function _e(e,r){return e===void 0?!0:t(e)?r.kind!==`reported`||n(e,r.rect):!1}function ve(e){if(e===void 0)return;if(!j(e))throw l(`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 l(`malformed-tree`,`frame-invalid`);let[n,r,i,a]=t;if(i<0||a<0)throw l(`malformed-tree`,`frame-invalid`);return{x:n,y:r,width:i,height:a}}function ye(e){return!e||!Y(e)?{kind:`missing`,reason:`not-provided`}:t(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 be(e,t){for(let n of e)n.hittable=n.parentIndex!==void 0&&r(n.enabled!==!1,n.rect,t)}function xe(e,t){return t.kind===`reported`?e.filter(n=>Se(n,e)&&W(n.rect??pe,t.rect)).length:0}function Se(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 l(`malformed-tree`,`scalar-invalid`)}function Ce(e){if(e!=null){if(typeof e!=`string`||!/^\d{1,20}$/.test(e))throw l(`malformed-tree`,`traits-invalid`);return BigInt(e)}}function we(e){if(e!=null){if(typeof e!=`boolean`)throw l(`malformed-tree`,`user-interaction-invalid`);return e}}function Te(e){if(e!=null){if(!Number.isSafeInteger(e))throw l(`malformed-tree`,`automation-type-invalid`);return e}}const Q=`simulator-ax-bridge`;function Ee(e={}){let t=e.host??u(),n=new se(t),r=new te,i=U({host:t,limits:L(e.limits),producer:Q,sourceRoot:e.sourceRoot,cacheRoot:e.cacheRoot}),a=!1;return{acquire:async o=>{try{if(a)throw l(`unsupported`,`source-closed`);De(o);let c=L({...e.limits,...o.limits}),u=v(c.maxDurationMs,o.signal),d=ke(o.hint,c.maxTraversalDepth),f=d+1,p=o.hint.rawTraversalDepth!==null;return await t.withDiagnosticTimer(`ios.snapshot-source.acquire`,async()=>{let e=await i.readyBinary(o.target.runtime,u,`bridge-preparation-deadline`),a=r.consume(o.target,f,p),l=await n.request({target:o.target,bridge:e,limits:c,maxDepth:d,nativeLevelsHint:a.nativeLevels,deadline:u});s(u,`snapshot-decode-deadline`);let m=Ae(o.hint,o.target,l,c);return Oe(t,r,o.target,f,p,a,l),{stage:`acquired`,acquisition:m}},{producer:Q})}catch(e){let t=f(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 De(t){if(!t.target.simulator.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 Oe(e,t,n,r,i,a,o){let s=re(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 ke(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 Ae(e,t,n,r){if(n.automationEnabled!==!0)throw l(`unsupported`,`automation-mode-unavailable`);let i=n.tree,a=n.truncated;if(typeof a!=`boolean`)throw l(`malformed-tree`,`truncated-invalid`);let o=me(i,{truncated:a},r),s=n.generation;if(typeof s!=`string`||!s)throw l(`malformed-tree`,`generation-invalid`);if(o.opaqueRemoteElements>0)throw l(`unsupported`,`remote-content-boundary`,{remoteElements:o.opaqueRemoteElements});if(o.unresolvedCoordinateSpaceWindows>0)throw l(`unsupported`,`window-coordinate-space-unresolved`,{windows:o.unresolvedCoordinateSpaceWindows});let c=Object.freeze(o.nodes.map(e=>Object.freeze({...e,pid:t.pid}))),u=je(e,a,o.viewport),d=Object.freeze({...t.targetId?{targetId:t.targetId}:{},generation:s}),f={producer:Q,nodes:c,truncated:a,viewport:o.viewport,lineage:d,residue:u};return e.acquisitionIntent===`full`?{...f,intent:`full`,hint:{...e,acquisitionIntent:`full`}}:{...f,intent:`surface-observation`,hint:{...e,acquisitionIntent:`surface-observation`}}}function je(e,t,n){let r=n.kind===`reported`?[]:[{kind:`unavailable-fact`,fact:`hittability`}];return Object.freeze([...r,...e.interactiveOnly?[{kind:`unavailable-fact`,fact:`interactive-query`}]:[],...t?[{kind:`truncated`}]:[],...n.kind===`missing`?[{kind:`missing-viewport`,reason:n.reason}]:[]])}export{Ee as createSimulatorSnapshotSource};
|
|
1
|
+
import{N as e,V as t}from"./sdk-contracts.js";import{Jr as n,Yr as r,qr as i}from"./sdk-batch.js";import{c as a,r as o}from"./diagnostics.js";import{c as s,l as c,m as l}from"./exec.js";import"./diagnostics2.js";import"./command.js";import"./process.js";import{r as u}from"./version.js";import{f as d}from"./host-file.js";import{t as f}from"./apple-runner-platform.js";import{t as p}from"./simctl.js";import{a as m,c as ee,d as te,i as ne,l as re,n as ie,o as ae,r as oe,s as se,t as ce,u as le}from"./cache.js";import h from"node:path";import{createHash as g,randomUUID as _}from"node:crypto";import ue from"node:net";import{Buffer as v}from"node:buffer";const de={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 y=class extends e{failureKind;failureCode;constructor(e,t,n=`iOS Simulator snapshot source ${e}: ${t}`,r={},i){super(de[e],n,{...r,bridgeFailure:e,bridgeFailureCode:t,...e===`cancelled`?{reason:`request_canceled`}:{}},i),this.name=`SnapshotSourceError`,this.failureKind=e,this.failureCode=t}};function b(e,t,n={},r){return new y(e,t,void 0,n,r)}function x(e){return e instanceof ee?new y(e.buildFailureKind,e.buildFailureCode,void 0,e.buildDetails,e.cause):e}function S(n){return n instanceof y||(n=x(n),n instanceof y)?n:t(n)?b(`cancelled`,`abort-signal`,{},n):n instanceof e&&typeof n.details?.timeoutMs==`number`?b(`timeout`,`host-operation-timeout`,{timeoutMs:n.details.timeoutMs},n):b(`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 b(`cancelled`,`abort-signal`);return ae(e,t,n)}function w(e,t){try{return se(e,t)}catch(e){throw x(e)}}async function T(e,t,n,r){let i=Math.min(t,w(e,n));await te({waitMs:i,signal:e.signal,stop:r,cancelled:()=>b(`cancelled`,`abort-signal`)})}var fe=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 pe(){return{...m(async(e,t,n)=>await s(e,t,n)),projectRoot:u,homeDirectory:d,start:me,connect:he,emitDiagnostic:o,withDiagnosticTimer:a,readTargetProcessStartTime:re}}function me(e,t,n,r={}){if(r.signal?.aborted)throw b(`cancelled`,`abort-signal`);let i=c(`xcrun`,p(e,[`spawn`,e.udid,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 b(`transport-failure`,`bridge-process-pid-missing`);let o=``;return i.child.stderr?.setEncoding(`utf8`),i.child.stderr?.on(`data`,e=>{o=ge(o,String(e))}),{pid:a,wait:i.wait,isAlive:()=>i.child.exitCode===null&&i.child.signalCode===null,signal:e=>{l(a,e)||i.child.kill(e)},readLog:()=>o}}async function he(e,t){if(t.signal?.aborted)throw b(`cancelled`,`abort-signal`);let n=Math.max(1,Math.floor(t.timeoutMs));return await new Promise((r,i)=>{let a=ue.createConnection({path:e}),o=!1,s=!1,c=setTimeout(()=>{p(b(`timeout`,`bridge-connect-timeout`)),a.destroy()},n),l=()=>{p(b(`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(b(`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()})}function ge(e,t){let n=e+t;return n.length<=E?n:n.slice(n.length-E)}function _e(e,t,n){let r=g(`sha256`).update(t).digest(`hex`).slice(0,12),i=g(`sha256`).update(n).digest(`hex`).slice(0,12);return h.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:ve(t.readLog())}})),b(`process-crash`,`bridge-exited`,{pid:t.pid,...n===void 0?{}:{exitCode:n}})}function ve(e){let t=v.from(e);return t.length<=65536?e:t.subarray(-65536).toString(`utf8`)}const k=`agent-device-simulator-ax-v1.8.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_kAXXCAttributePlaceholderValue`,`XC_kAXXCAttributeIdentifier`,`XC_kAXXCAttributeFrame`,`XC_kAXXCAttributeAutomationType`,`XC_kAXXCAttributeTraits`,`XC_kAXXCAttributeIsUserInteractionEnabled`,`XC_kAXXCAttributeChildren`]);const ye=[`requests`,`rejected`,`continuations`,`acceptedLevels`];function A(e){let t=e.recovery;if(!F(t))throw b(`malformed-tree`,`recovery-invalid`);let n=ye.map(e=>[e,t[e]]);if(n.some(([,e])=>!Number.isSafeInteger(e)||e<0))throw b(`malformed-tree`,`recovery-invalid`);return Object.freeze(Object.fromEntries(n))}function j(e,t){let n;try{n=v.from(JSON.stringify(e),`utf8`)}catch(e){throw b(`malformed-tree`,`request-not-json`,{},e)}let r=n.length+4;if(r>t.maxRequestBytes)throw b(`transport-failure`,`request-limit-exceeded`,{frameBytes:r,maxRequestBytes:t.maxRequestBytes});let i=v.alloc(4);return i.writeUInt32BE(n.length,0),v.concat([i,n])}var M=class{header=v.alloc(4);headerBytes=0;chunks=[];payloadBytes=0;expectedBodyBytes;frame;maxFrameBytes;constructor(e){if(!Number.isSafeInteger(e)||e<=0)throw b(`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=v.concat(this.chunks,t.bodyBytes),this.frame}acceptTrailingChunk(e){if(e.length>0)throw b(`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 b(`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 b(`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 b(`transport-failure`,`bridge-frame-incomplete`,{headerBytes:this.headerBytes,payloadBytes:this.payloadBytes,expectedBodyBytes:this.expectedBodyBytes})}};function N(e){let t;try{t=JSON.parse(e.toString(`utf8`))}catch(e){throw b(`malformed-tree`,`response-not-json`,{},e)}if(!F(t))throw b(`malformed-tree`,`response-not-object`);return t}function P(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 be(e,t){if(e.protocolVersion!==1)throw b(`transport-failure`,`protocol-version-mismatch`,{expected:1,observed:e.protocolVersion});if(e.sourceVersion!==`agent-device-simulator-ax-v1.8.0`)throw b(`transport-failure`,`source-version-mismatch`,{expected:k,observed:e.sourceVersion});if(e.requestId!==t)throw b(`transport-failure`,`request-id-mismatch`,{expected:t,observed:e.requestId})}function xe(e,t){if(typeof e.pid!=`number`||e.pid!==t.pid)throw b(`stale-target`,`bridge-pid-mismatch`,{expectedPid:t.pid,observedPid:e.pid});if(e.generation!==t.generation)throw b(`stale-target`,`bridge-generation-mismatch`,{expectedGeneration:t.generation,observedGeneration:e.generation})}function Se(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 b(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 F(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function Ce(e){let t=new M(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(b(`timeout`,`bridge-request-deadline`,{dispatched:o})),e.socket.destroy()},n),c=()=>{p(b(`cancelled`,`abort-signal`,{dispatched:o})),e.socket.destroy()},l=n=>{try{if(!Buffer.isBuffer(n))throw b(`transport-failure`,`bridge-data-invalid`);let r=t.push(n);if(r){let t=N(r);if(be(t,e.requestId),xe(t,{pid:e.expectedPid,generation:e.expectedGeneration}),t.ok!==!0&&Se(t),typeof t.truncated!=`boolean`)throw b(`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(b(`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 b(`cancelled`,`abort-signal`);o=!0,e.socket.write(e.frame)}catch(t){p(S(t)),e.socket.destroy()}})}var we=class{sessions=new Map;requestQueues=new Map;ownerId=_();closed=!1;host;constructor(e){this.host=e}async request(e){if(this.closed)throw b(`unsupported`,`source-closed`);return await this.withSimulatorLock(e.target.simulator.udid,e.deadline,()=>this.requestInSimulator(e))}async requestInSimulator(e){if(this.closed)throw b(`unsupported`,`source-closed`);let t=e.deadline;w(t,`bridge-request-deadline`);let n=this.sessions.get(e.target.simulator.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 Ee(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 Te(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.simulator.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=_e(this.host,e.target.simulator.udid,this.ownerId);await this.host.ensureDirectory(h.dirname(i)),await this.host.remove(i);let a=this.host.start(e.target.simulator,e.bridge.path,i,{signal:t.signal}),o={udid:e.target.simulator.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 y&&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 y&&n.failureKind===`timeout`)throw n}}async exchange(e,t,n){(!e.socket||e.socket.destroyed)&&(e.socket=await this.connectUntilReady(e,n));let r=_(),i=j(P({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 Ce({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 b(`stale-target`,`target-process-unavailable`,{pid:e.pid,generation:e.generation});if(e.processStartTime!==void 0&&e.processStartTime!==n)throw b(`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 b(`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 I(e.process,500),e.process.isAlive()&&(e.process.signal(`SIGKILL`),await I(e.process,500))),await this.host.remove(e.socketPath)}};async function Te(e,t){let n=w(t,`bridge-request-deadline`);await Promise.race([e,T(t,n,`bridge-request-deadline`).then(()=>{throw b(`timeout`,`bridge-request-deadline`)})])}function Ee(e,t,n){return(e.failureKind===`cancelled`||e.failureKind===`timeout`)&&(e.details?.dispatched===!0||n!==t)}async function I(e,t){await Promise.race([e.wait.catch(()=>void 0),new Promise(e=>setTimeout(e,t))])}const L=16777216,R=12e4,z=1e4,De=Object.freeze({maxRequestBytes:65536,maxResponseBytes:4194304,maxNodes:5e3,maxTraversalDepth:64,maxDurationMs:5e3});function B(t){let n={...De,...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>L||n.maxResponseBytes>L)throw new e(`INVALID_ARGS`,`Snapshot source frame limits exceed the bridge bound`,{maxRequestBytes:n.maxRequestBytes,maxResponseBytes:n.maxResponseBytes,maximumFrameBytes:L});if(n.maxNodes>z||n.maxTraversalDepth>128)throw new e(`INVALID_ARGS`,`Snapshot source tree limits exceed the bridge bound`,{maxNodes:n.maxNodes,maxTraversalDepth:n.maxTraversalDepth,maximumNodes:z,maximumDepth:128});if(n.maxDurationMs>R)throw new e(`INVALID_ARGS`,`Snapshot source duration exceeds the bridge bound`,{maxDurationMs:n.maxDurationMs,maximumDurationMs:R});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 V=[`SnapshotBridge.m`,`SnapshotBridgeRuntime.m`,`SnapshotBridgeRuntime.h`,`SnapshotBridgeCapture.h`,`SnapshotBridgeCapture.m`],Oe=[`SnapshotBridge.m`,`SnapshotBridgeRuntime.m`,`SnapshotBridgeCapture.m`];async function ke(e,t,n){let r=await ne(e,n).catch(e=>{throw x(e)}),i=t.trim();if(!i)throw b(`unsupported`,`simulator-runtime-missing`);return{...r,simulatorRuntime:i}}const H=12e4;async function Ae(e){let t=e.deadline,n=e.sourceRoot??je(e.host);try{let r=await oe(e.host,n,V,t),i=await ke(e.host,e.runtime,t),a=e.cacheRoot??h.join(e.host.homeDirectory(),`.agent-device`,`snapshot-source`),o=await ce({host:e.host,deadline:t,cacheRoot:a,binaryFilename:`snapshot-bridge`,lockDescription:`iOS Simulator snapshot bridge cache`,keyInputs:{schemaVersion:1,protocolVersion:1,sourceVersion:k,sourceHash:r,toolchain:i,compileArgv:U({architecture:i.architecture,sourceRoot:``,outputPath:``})},build:async r=>{let a=await ie({host:e.host,deadline:t,argv:U({architecture:i.architecture,sourceRoot:n,outputPath:r}),budgetMs:H,label:`bridge`});if(a.exitCode!==0||!e.host.exists(r))throw b(`unsupported`,`native-build-failed`,{exitCode:a.exitCode,stderr:a.stderr.slice(0,4096)})}});return{path:o.path,sourceHash:r,cacheKey:o.cacheKey,protocolVersion:1,sourceVersion:k}}catch(e){throw x(e)}}function U(e){return[`--sdk`,`iphonesimulator`,`clang`,`-arch`,e.architecture,`-mios-simulator-version-min=15.0`,`-fobjc-arc`,`-Wall`,`-Wextra`,`-framework`,`Foundation`,`-framework`,`CoreGraphics`,...Oe.map(t=>h.join(e.sourceRoot,t)),`-o`,e.outputPath]}function je(e){let t=e.projectRoot(),n=h.join(t,`apple`,`snapshot-bridge`);if(V.every(t=>e.exists(h.join(n,t))))return n;let r=h.join(t,`dist`,`apple`,`snapshot-bridge`);if(V.every(t=>e.exists(h.join(r,t))))return r;throw b(`unsupported`,`native-source-missing`,{projectRoot:t})}const Me=f+H;function Ne(e){let t=e.now??Date.now,n=new Map,r=le({waitMs:2e3,waitGrant:`first-caller`,retryAfterMs:6e4,now:t}),i=async(r,i)=>{let a=C(Me,i,t);try{let t=await e.host.withDiagnosticTimer(`ios.snapshot-source.prepare`,async()=>await Ae({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:()=>b(`preparing`,`bridge-preparation-pending`)}),close:()=>{n.clear(),r.close()}}}function Pe(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`,placeholder:`XC_kAXXCAttributePlaceholderValue`,identifier:`XC_kAXXCAttributeIdentifier`,frame:`XC_kAXXCAttributeFrame`,automationType:`XC_kAXXCAttributeAutomationType`,traits:`XC_kAXXCAttributeTraits`,userInteractionEnabled:`XC_kAXXCAttributeIsUserInteractionEnabled`,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`},Fe=new Set(Object.values(W)),Ie=1n<<8n,Le=1n<<3n,Re={x:0,y:0,width:0,height:0};function ze(e,t,n){let r=Array.isArray(e)?e:[e];if(r.length===0||r.some(e=>!F(e)))throw b(`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 b(`malformed-tree`,`node-limit-exceeded`,{nodeCount:i.length,maxNodes:n.maxNodes});if(o>n.maxTraversalDepth)throw b(`malformed-tree`,`traversal-depth-exceeded`,{maxTraversalDepth:o,maxAllowedDepth:n.maxTraversalDepth});if(typeof t.truncated!=`boolean`)throw b(`malformed-tree`,`truncated-invalid`);let s=We(i.filter(J)[0]);return s.kind===`reported`&&Ge(i,s.rect),{nodes:i,maxTraversalDepth:o,viewport:s,opaqueRemoteElements:a.filter(e=>He(e,s)).length,unresolvedCoordinateSpaceWindows:Y(i,s)};function c(e,t,r,s){if(i.length>=n.maxNodes)throw b(`malformed-tree`,`node-limit-exceeded`,{maxNodes:n.maxNodes});for(let t of Object.keys(e))if(!Fe.has(t))throw b(`malformed-tree`,`node-contains-unknown-field`,{key:t});let l=e[W.children];if(!Array.isArray(l))throw b(`malformed-tree`,`children-invalid`);let u=i.length,d=Be(e,u,t,r);i.push(d),o=Math.max(o,r),Ve(d,l.length,s)&&a.push(d.rect);let f=s||d.type===`WebView`;for(let e of l){if(!F(e))throw b(`malformed-tree`,`child-invalid`);c(e,u,r+1,f)}}}function Be(e,t,n,r){let i=X(e[W.elementType]),a=X(e[W.elementBaseType]),o=Ye(e[W.automationType]),s=Ue(e[W.frame]),c=qe(e[W.traits]),l=c===void 0?void 0:(c&Ie)===0n,u=c===void 0||(c&Le)===0n?void 0:!0,d=Je(e[W.userInteractionEnabled]),f=X(e[W.placeholder])?.trim();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])}:{},...f?{placeholder:f}:{},...X(e[W.identifier])?{identifier:X(e[W.identifier])}:{},...s?{rect:s}:{},...l===void 0?{}:{enabled:l},...u===void 0?{}:{selected:u},...d===void 0?{}:{userInteractionEnabled:d},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 Ve(e,t,n){return n&&e.role===`AXRemoteElement`&&t===0}function He(e,t){return e===void 0?!0:n(e)?t.kind!==`reported`||r(e,t.rect):!1}function Ue(e){if(e===void 0)return;if(!F(e))throw b(`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 b(`malformed-tree`,`frame-invalid`);let[n,r,i,a]=t;if(i<0||a<0)throw b(`malformed-tree`,`frame-invalid`);return{x:n,y:r,width:i,height:a}}function We(e){return!e||!J(e)?{kind:`missing`,reason:`not-provided`}:n(e.rect)?{kind:`reported`,rect:e.rect}:{kind:`missing`,reason:e.rect?`invalid`:`not-provided`}}function J(e){return e.type===`Application`||e.type===`Window`}function Ge(e,t){for(let n of e)n.hittable=n.parentIndex!==void 0&&i(n.enabled!==!1,n.rect,t)}function Y(e,t){return t.kind===`reported`?e.filter(n=>Ke(n,e)&&Pe(n.rect??Re,t.rect)).length:0}function Ke(e,t){return J(e)?!0:e.parentIndex!==void 0&&J(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 b(`malformed-tree`,`scalar-invalid`)}function qe(e){if(e!=null){if(typeof e!=`string`||!/^\d{1,20}$/.test(e))throw b(`malformed-tree`,`traits-invalid`);return BigInt(e)}}function Je(e){if(e!=null){if(typeof e!=`boolean`)throw b(`malformed-tree`,`user-interaction-invalid`);return e}}function Ye(e){if(e!=null){if(!Number.isSafeInteger(e))throw b(`malformed-tree`,`automation-type-invalid`);return e}}const Q=`simulator-ax-bridge`;function Xe(e={}){let t=e.host??pe(),n=new we(t),r=new fe,i=Ne({host:t,limits:B(e.limits),producer:Q,sourceRoot:e.sourceRoot,cacheRoot:e.cacheRoot}),a=!1;return{acquire:async o=>{try{if(a)throw b(`unsupported`,`source-closed`);Ze(o);let s=B({...e.limits,...o.limits}),c=C(s.maxDurationMs,o.signal),l=$e(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=et(o.hint,o.target,f,s);return Qe(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 Ze(t){if(!t.target.simulator.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 Qe(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 $e(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 et(e,t,n,r){if(n.automationEnabled!==!0)throw b(`unsupported`,`automation-mode-unavailable`);let i=n.tree,a=n.truncated;if(typeof a!=`boolean`)throw b(`malformed-tree`,`truncated-invalid`);let o=ze(i,{truncated:a},r),s=n.generation;if(typeof s!=`string`||!s)throw b(`malformed-tree`,`generation-invalid`);if(o.opaqueRemoteElements>0)throw b(`unsupported`,`remote-content-boundary`,{remoteElements:o.opaqueRemoteElements});if(o.unresolvedCoordinateSpaceWindows>0)throw b(`unsupported`,`window-coordinate-space-unresolved`,{windows:o.unresolvedCoordinateSpaceWindows});let c=Object.freeze(o.nodes.map(e=>Object.freeze({...e,pid:t.pid}))),l=tt(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 tt(e,t,n){let r=n.kind===`reported`?[]:[{kind:`unavailable-fact`,fact:`hittability`}];return Object.freeze([...r,...e.interactiveOnly?[{kind:`unavailable-fact`,fact:`interactive-query`}]:[],...t?[{kind:`truncated`}]:[],...n.kind===`missing`?[{kind:`missing-viewport`,reason:n.reason}]:[]])}export{Xe as createSimulatorSnapshotSource};
|
package/dist/src/adb-executor.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{N 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
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{N 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};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime.js";import{
|
|
1
|
+
import{r as e}from"./rolldown-runtime.js";import{N as t}from"./sdk-contracts.js";import{i as n}from"./device-shell.js";var r=e({ADB_GLOBAL_OPTIONS:()=>a,ADB_MANAGED_FORBIDDEN_COMMANDS:()=>c,ADB_WAIT_STATES:()=>s,ADB_WAIT_TRANSPORTS:()=>o,adoptAndroidAdbSerial:()=>g,androidAdbHostTarget:()=>m,androidAdbInvocation:()=>h,androidAdbPayloadWithoutSerial:()=>T,androidAdbSerialTarget:()=>p,androidManagedAdbEnvironment:()=>P,applyManagedAndroidAdbServer:()=>E,lowerAndroidAdbInvocation:()=>N,normalizeAndroidAdbInstallOptions:()=>i,parseAndroidAdbArgv:()=>x,requireAndroidAdbServerPort:()=>C,requireManagedAndroidAdbAddressing:()=>k,requireManagedAndroidAdbCommand:()=>A,requireManagedAndroidAdbSerial:()=>D,requireSameAndroidAdbServer:()=>w,requireUnconflictedAndroidAdbSelector:()=>O,serializeAndroidAdbInvocation:()=>_});function i(e){let{replace:t,...n}=e??{};return{installArgs:t?[`-r`]:[],execOptions:n}}const a={"-a":0,"-d":0,"-e":0,"-s":1,"-t":1,"-H":1,"-P":1,"-L":1,"--one-device":1,"--exit-on-write-error":0},o=[``,`usb-`,`local-`,`any-`],s=[`device`,`recovery`,`bootloader`,`sideload`,`sideload-window`],c=[`nodaemon`,`server`,`fork-server`,`kill-server`,`start-server`,`connect`,`disconnect`,`reconnect`,`attach`,`detach`,`pair`],l=new Set(c);function u(e){return e.startsWith(`wait-for-`)}function d(e){if(!u(e))return;let t=e.slice(9);return o.some(e=>t.startsWith(e)&&s.includes(t.slice(e.length)))?e:void 0}function f(e){return l.has(e)}function p(e,t){return{selector:{kind:`serial`,serial:e},server:t===void 0?{kind:`ambient`}:{kind:`port`,port:t}}}function m(){return{selector:{kind:`unspecified`},server:{kind:`ambient`}}}function h(e,t,n){return{target:e,command:t,...n?{rawArgv:n}:{}}}function g(e,t){return{...e,selector:{kind:`serial`,serial:t}}}function _(e){if(e.rawArgv)return[...e.rawArgv];let{target:t,command:n}=e,r=[];return t.server.kind===`port`&&r.push(`-P`,String(t.server.port)),t.selector.kind===`serial`&&r.push(`-s`,t.selector.serial),t.hostGlobals&&r.push(...t.hostGlobals),t.waitFor&&r.push(t.waitFor),r.push(...n),r}const v={"-s":`serial`,"-P":`server`};function y(e,t){let n=e[t],r=d(n);if(r)return{kind:`wait`,waitFor:r,next:t+1};if(u(n))return{kind:`unknown-wait`,token:n,next:t+1};let i=v[n];if(i===void 0){if(!n.startsWith(`-`))return{kind:`stop`,next:t};let r=a[n]??0;return{kind:`global`,tokens:[n,...e.slice(t+1,t+1+r)],next:t+1+r}}let o=e[t+1]??``;if(i===`serial`)return{kind:`serial`,serial:o,next:t+2};let s=Number(o);return Number.isInteger(s)?{kind:`server`,port:s,next:t+2}:{kind:`global`,tokens:[n,o],next:t+2}}function b(e,t){e.kind===`wait`?t.waitFor===void 0?t.waitFor=e.waitFor:t.hostGlobals.push(e.waitFor):e.kind===`unknown-wait`?t.hostGlobals.push(e.token):e.kind===`serial`?t.selector.kind===`unspecified`?t.selector={kind:`serial`,serial:e.serial}:t.selector.serial!==e.serial&&t.hostGlobals.push(`-s`,e.serial):e.kind===`server`?t.server={kind:`port`,port:e.port}:e.kind===`global`&&t.hostGlobals.push(...e.tokens)}function x(e){let t=m(),r={selector:t.selector,server:t.server,waitFor:void 0,hostGlobals:[]},i=0;for(;;){let t=i<e.length?y(e,i):{kind:`stop`,next:i};if(t.kind===`stop`)break;b(t,r),i=t.next}let{selector:a,server:o,waitFor:s,hostGlobals:c}=r,l={selector:a,server:o,...s?{waitFor:s}:{},...c.length>0?{hostGlobals:c}:{}},u=c.length>0||s!==void 0||a.kind!==`unspecified`||o.kind===`port`;return{target:l,command:n(e,0,i),rawArgv:u?e:void 0}}function S(e){if(e.rawArgv===void 0)return e.target.server.kind===`port`?e.target.server.port:void 0}function C(e,t){return w(S(e),t?.serverPort)}function w(e,t){if(e!==void 0&&t!==void 0&&e!==t)throw M(`server`);return e??t}function T(e,t){let r=0;for(;;){let i=r<e.length?y(e,r):{kind:`stop`,next:r};if(i.kind===`stop`)return;if(i.kind===`serial`)return i.serial===t?n(e,r,2):void 0;r=i.next}}function E(e,t){let{target:n,command:r}=e;return k(n,t.port),A(r),h({selector:n.selector,server:{kind:`port`,port:t.port},...n.waitFor?{waitFor:n.waitFor}:{}},r)}function D(e,t){return O(e.selector,t),{...e,selector:{kind:`serial`,serial:t}}}function O(e,t){if(e.kind===`serial`&&e.serial!==t)throw M(`device`)}function k(e,t){if(e.hostGlobals)throw M(`target`);w(t,e.server.kind===`port`?e.server.port:void 0)}function A(e){if(f(e.find(e=>!u(e))??``))throw M(`target`)}const j={device:`Managed ADB transport cannot address another device.`,target:`Managed ADB transport cannot select another target.`,server:`Managed ADB transport cannot select another server.`};function M(e){throw new t(`COMMAND_FAILED`,j[e],{reason:`managed-device-transport-mismatch`})}function N(e,t,n){let{serverPort:r,...i}=t??{},a=C(e,t),o=a===void 0?e:E(e,{port:a}),s=a===void 0?void 0:P(o.target,n,i.env);return{args:_(o),options:{...i,...s===void 0?{}:{env:s}}}}function P(e,t,n){return e.server.kind===`port`?{...t,...n??{},ADB_SERVER_SOCKET:void 0,ANDROID_ADB_SERVER_PORT:String(e.server.port),ANDROID_ADB_SERVER_ADDRESS:`127.0.0.1`}:n}export{T as a,N as c,k as d,D as f,_ as h,h as i,i as l,O as m,g as n,p as o,w as p,m as r,E as s,r as t,x as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime.js";import{sr as t}from"./sdk-batch.js";import{
|
|
1
|
+
import{r as e}from"./rolldown-runtime.js";import{sr as t}from"./sdk-batch.js";import{C as n,f as r,g as i,o as a,x as o}from"./owner-identity.js";import{_ as s}from"./exec.js";import"./command.js";import"./process.js";import c from"node:path";import l from"node:crypto";var u=e({agentBrowserChromeLaunchMarker:()=>d,appendAgentDeviceChromeArgs:()=>f,inspectManagedAgentBrowserProcesses:()=>_,matchAgentBrowserChromeProcess:()=>p,recordManagedAgentBrowserProcesses:()=>v,summarizeAgentBrowserProcesses:()=>m,summarizeManagedAgentBrowserProcesses:()=>g});function d(e){let t=l.createHash(`sha256`);return t.update(c.resolve(e.stateDir)),t.update(`\0`),t.update(c.resolve(e.installDir)),`--agent-device-managed-web=${t.digest(`hex`).slice(0,16)}`}function f(e,t){let n=d(t),r=e?.trim();return r?x(r).includes(n)?r:`${r},${n}`:n}function p(e,t){if(!(e.pid===r()||!S(e.command))){if(e.command.includes(d(t)))return{process:e,reason:`launch-marker`};if(w(t).some(t=>T(e,t)))return{process:e,reason:`managed-browser-home`}}}function m(e,t){return b(e,e=>p(e,t))}function h(e,t){return p(e,t)??C(e,t)}function g(e,t){return b(e,e=>h(e,t))}async function _(e){return m(await y(),e)}async function v(e,t){let r=await y(),i=g(r,e),s=a(i.pids,r),c={count:s.length,pids:s.map(({pid:e})=>e),processes:s.map(t=>({process:t,reason:h(t,e)?.reason??`descendant`}))},l=c.processes.flatMap(({process:e})=>{let t=n(e.pid),r=o(e.pid);return t&&r?[{pid:e.pid,startTime:t,command:r,purpose:`managed-web-browser`}]:[]});return l.length>0&&t.replace({kind:`daemon`},l),c}async function y(){return await s(async()=>await i({timeoutMs:1500}))}function b(e,t){let n=e.flatMap(e=>{let n=t(e);return n?[n]:[]});return{count:n.length,pids:n.map(e=>e.process.pid),processes:n}}function x(e){return e.split(/[,\n]/).map(e=>e.trim()).filter(Boolean)}function S(e){return/\b(?:Google Chrome for Testing|Chrome for Testing|Chromium|chrome|chrome\.exe|chromium|chromium-browser|headless_shell)\b/i.test(e)}function C(e,t){if(e.pid===r()||S(e.command))return;let n=E(e.command),i=E(c.resolve(t.installDir));return n.includes(`${i}/`)?{process:e,reason:`agent-browser-daemon`}:void 0}function w(e){return t([c.join(e.homeDir,`.agent-browser`,`browsers`),c.join(e.runtimeHomeDir,`.agent-browser`,`browsers`)])}function T(e,t){let n=E(e.command),r=`${E(c.resolve(t)).replace(/\/+$/,``)}/`;return n.includes(r)}function E(e){return e.replaceAll(`\\`,`/`)}export{v as i,f as n,_ as r,u as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{M as e}from"./sdk-contracts.js";import{k as t}from"./sdk-batch-runner.js";import{t as n}from"./scroll-gesture.js";import{r}from"./diagnostics.js";import{d as i}from"./owner-identity.js";import{n as a}from"./exec.js";import{t as o}from"./timeouts.js";import"./diagnostics2.js";import"./command.js";import"./retry.js";import"./process.js";import{n as s}from"./audio-probe-result.js";import{i as c}from"./agent-browser-process-record.js";import{n as l}from"./agent-browser-lifecycle.js";import{i as ee,n as u,r as te}from"./agent-browser-tool.js";function d(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function f(e,t){return d(e)?e[t]:void 0}function p(e,t){let n=f(e,t);return typeof n==`string`?n:void 0}function ne(e,t){let n=f(e,t);return typeof n==`boolean`?n:void 0}function m(e,t){let n=e[t];return typeof n==`number`&&Number.isFinite(n)?n:void 0}const re=[g,_,v,y,b,x,S,C,w,T,E,D,O,k,A,j,M];function ie(e){let t=re.map(e=>`${e.toString()};`).join(``),n=oe(e.action),r=h(e.durationMs),i=h(e.bucketMs);return`(()=>{${t}return ${M.name}({action:${n},durationMs:${r},bucketMs:${i}})})()`}function ae(e){let t=s(se(e),{source:`media-elements`,backend:`agent-browser`,durationMs:0,elapsedMs:0,bucketMs:1e3,activeFallback:!1,mediaElementCount:0,sourceCount:0});return{...t,source:`media-elements`,mediaElementCount:t.mediaElementCount??0}}function oe(e){switch(e){case`start`:return`'start'`;case`stop`:return`'stop'`;default:return`'status'`}}function h(e){return e===void 0||!Number.isFinite(e)?`undefined`:String(Math.trunc(e))}function g(e){return!Number.isFinite(e)||e<=0?-90:Math.max(-90,Math.min(0,Math.round(20*Math.log10(e))))}function _(e,t){e.notes.includes(t)||e.notes.push(t)}function v(){return Array.from(document.querySelectorAll(`audio,video`))}function y(e,t){if(!e||e.state===`stopped`)return e;clearInterval(e.timer),clearTimeout(e.timeout),e.timer=void 0,e.timeout=void 0,e.state=`stopped`,e.active=!1,e.reason=t,e.stoppedAt=Date.now();for(let t of e.analysers)try{t.analyser.disconnect(),t.source.disconnect(),t.audible&&t.source.connect(e.context.destination)}catch{}if(e.resumeOnGesture){for(let t of[`click`,`pointerdown`,`keydown`])window.removeEventListener(t,e.resumeOnGesture,!0);e.resumeOnGesture=void 0}return e}function b(e){let t=window.AudioContext||window.webkitAudioContext;if(!t)return;let n=window[e];if(n&&n.state!==`closed`)return n;let r=new t;return window[e]=r,r}function x(e,t,n){if(!(!t.currentSrc&&!t.src&&t.readyState===0))try{window[n]||(window[n]=new WeakMap);let r=window[n].get(t);return r||(r=e.context.createMediaElementSource(t),window[n].set(t,r)),r.disconnect(),{source:r,audible:!0}}catch{return}}function S(e,t){if(!(!t||typeof t.getAudioTracks!=`function`)&&t.getAudioTracks().length!==0)return{source:e.context.createMediaStreamSource(t),audible:!1}}function C(e,t){if(typeof t.captureStream==`function`)return S(e,t.captureStream())}function w(e,t){let n=e.context.createAnalyser();n.fftSize=2048,t.source.connect(n),n.connect(t.audible?e.context.destination:e.sink),e.analysers.push({...t,analyser:n,buffer:new Float32Array(n.fftSize)})}function T(e,t){let n=v();e.mediaElementCount=n.length;for(let r of n){if(e.seen.has(r))continue;let n=S(e,r.srcObject)??C(e,r)??x(e,r,t);if(!n){_(e,`Some media elements do not expose capturable audio to Web Audio.`);continue}e.seen.add(r),w(e,n)}e.sourceCount=e.analysers.length,e.sourceCount===0&&_(e,`No capturable page media audio sources were found yet.`)}function E(e){let t=0,n=0,r=0;for(let i of e.analysers){i.analyser.getFloatTimeDomainData(i.buffer);for(let e of i.buffer)t+=e*e,n+=1,r=Math.max(r,Math.abs(e))}return{rms:n>0?Math.sqrt(t/n):0,peak:r}}function D(e){let t=Math.ceil(e.durationMs/e.bucketMs)+2;e.rmsDbfs.length>t&&e.rmsDbfs.splice(0,e.rmsDbfs.length-t),e.peakDbfs.length>t&&e.peakDbfs.splice(0,e.peakDbfs.length-t)}function O(e,t){if(!e||e.state!==`running`)return;T(e,t);let n=E(e),r=g(n.rms),i=g(n.peak);e.rmsDbfs.push(r),e.peakDbfs.push(i),e.heard=e.heard||r>-90||i>-90,D(e),Date.now()-e.startedAt>=e.durationMs&&y(e,`duration`)}function k(e,t){return{audio:`probe`,state:`stopped`,active:!1,heard:!1,source:`media-elements`,backend:`agent-browser`,durationMs:Number(e.durationMs)||1e4,elapsedMs:0,bucketMs:Number(e.bucketMs)||1e3,sampleCount:0,mediaElementCount:v().length,sourceCount:0,rmsDbfs:[],peakDbfs:[],notes:t}}function A(e,t,n,r){return e?{audio:`probe`,state:e.state,active:e.state===`running`,heard:e.heard,source:`media-elements`,backend:`agent-browser`,durationMs:e.durationMs,elapsedMs:Math.max(0,Math.min((e.stoppedAt||Date.now())-e.startedAt,e.durationMs)),bucketMs:e.bucketMs,sampleCount:e.rmsDbfs.length,mediaElementCount:v().length,sourceCount:e.sourceCount,rmsDbfs:e.rmsDbfs.slice(),peakDbfs:e.peakDbfs.slice(),startedAt:new Date(e.startedAt).toISOString(),stoppedAt:e.stoppedAt?new Date(e.stoppedAt).toISOString():void 0,reason:e.reason,notes:[n,r,...e.notes]}:k(t,[n,r])}function j(e,t,n,r,i,a,o){t&&y(t,`restarted`);let s=b(r);if(!s)return k(e,[`Web Audio API is not available in this browser context.`]);let c=s.createGain();c.gain.value=0,c.connect(s.destination);let l={state:`running`,active:!0,context:s,sink:c,seen:new WeakSet,analysers:[],mediaElementCount:0,sourceCount:0,durationMs:Math.max(100,Number(e.durationMs)||1e4),bucketMs:Math.max(100,Number(e.bucketMs)||1e3),startedAt:Date.now(),stoppedAt:void 0,reason:void 0,heard:!1,rmsDbfs:[],peakDbfs:[],notes:[]};try{s.resume()}catch{_(l,`AudioContext could not be resumed by the probe.`)}l.resumeOnGesture=()=>{try{s.resume()}catch{_(l,`AudioContext could not be resumed from a user gesture.`)}};for(let e of[`click`,`pointerdown`,`keydown`])window.addEventListener(e,l.resumeOnGesture,{capture:!0,once:!0});return T(l,i),l.timer=setInterval(()=>O(l,i),l.bucketMs),l.timeout=setTimeout(()=>y(l,`duration`),l.durationMs),window[n]=l,A(l,e,a,o)}function M(e){let t=`__agentDeviceAudioProbe`,n=`__agentDeviceAudioProbeSources`,r=`Audio probe samples HTML media elements exposed to Web Audio; it is not whole-tab or system audio capture.`,i=`URL-backed media elements may be routed through the probe AudioContext while they are observed.`,a=window[t];return a&&a.state===`running`&&Date.now()-a.startedAt>=a.durationMs&&(O(a,n),y(a,`duration`)),e.action===`start`?j(e,a,t,`__agentDeviceAudioProbeContext`,n,r,i):e.action===`stop`?(a&&O(a,n),y(a,`manual`),A(a,e,r,i)):(a&&O(a,n),A(a,e,r,i))}function se(e){return d(e)?d(e.result)?e.result:e:{}}function ce(e,t={}){let n=le(e),r=pe(t.limit),i=t.include===`headers`||t.include===`all`,a=n.slice(-r).reverse().map(e=>de(e,i)),o=t.include===`body`||t.include===`all`?[`agent-browser network requests does not expose request or response bodies.`]:void 0;return{entries:a,backend:`agent-browser`,redacted:!1,...o?{notes:o}:{}}}function le(e){let t=d(e)&&Array.isArray(e.requests)?e.requests:e;return Array.isArray(t)?t.filter(ue).map(e=>({headers:N(e.headers),method:p(e,`method`),mimeType:p(e,`mimeType`),requestId:p(e,`requestId`),resourceType:p(e,`resourceType`),responseHeaders:N(e.responseHeaders),status:m(e,`status`),timestamp:fe(e.timestamp),url:p(e,`url`)})):[]}function ue(e){return d(e)}function de(e,n){let r=e.timestamp===void 0?void 0:P(e.timestamp),i=t({requestId:e.requestId,resourceType:e.resourceType,mimeType:e.mimeType});return t({timestamp:r,method:e.method,url:e.url,status:e.status,requestHeaders:n?e.headers:void 0,responseHeaders:n?e.responseHeaders:void 0,metadata:Object.keys(i).length>0?i:void 0})}function N(e){if(!d(e))return;let t={};for(let[n,r]of Object.entries(e))typeof r==`string`&&(t[n]=r);return Object.keys(t).length>0?t:void 0}function fe(e){if(typeof e==`number`||typeof e==`string`)return e}function P(e){if(typeof e==`string`){let t=Number(e);return Number.isFinite(t)?P(t):e}let t=e>1e10?e:e*1e3,n=new Date(t);return Number.isNaN(n.getTime())?String(e):n.toISOString()}function pe(e){return typeof e!=`number`||!Number.isInteger(e)?25:Math.max(1,Math.min(e,200))}async function me(e,t){let n=F(p(e,`snapshot`)??``,R(f(e,`refs`)));return t&&await he(n,t),{nodes:n.map((e,t)=>({...e.node,index:t,ref:e.ref})),truncated:ne(e,`truncated`)}}async function he(e,t){for(let n=0;n<e.length;n+=8){let r=e.slice(n,n+8),i=await Promise.all(r.map(e=>t(e.ref)));for(let[e,t]of i.entries())t&&(r[e].node.rect=t)}}function F(e,t){let n=new Map(t.map(e=>[e.ref,e])),r=[],i=new Set,a=new Map;for(let t of e.split(/\r?\n/)){let e=ve(t);if(!e)continue;i.add(e);let o=n.get(e)?.data,s=ge(t),c=I(t,o,s),l=_e(a,s);l!==void 0&&(c.parentIndex=l),r.push({ref:e,node:{...c,index:r.length}}),a.set(s,r.length-1)}for(let e of t)i.has(e.ref)||r.push({ref:e.ref,node:{...L(e.data),index:r.length}});return r}function I(e,t,n){let r=ye(e)??V(t,[`role`,`type`]);return{index:0,type:r,role:r,label:be(e)??V(t,[`label`,`name`,`text`]),value:Se(e)??V(t,[`value`]),depth:n,enabled:H(t,[`enabled`])??(!xe(e)&&void 0),focused:H(t,[`focused`])}}function L(e){let t=V(e,[`role`,`type`]);return{index:0,type:t,role:t,label:V(e,[`label`,`name`,`text`]),value:V(e,[`value`]),enabled:H(e,[`enabled`]),focused:H(e,[`focused`])}}function R(e){return Array.isArray(e)?e.flatMap(e=>{let t=d(e)?e:void 0,n=B(V(t,[`ref`,`id`])??String(e));return n?[{ref:n,data:t}]:[]}):d(e)?Object.entries(e).flatMap(([e,t])=>{let n=B(e);return n?[{ref:n,data:d(t)?t:void 0}]:[]}):[]}function ge(e){let t=e.match(/^\s*/)?.[0].length??0;return Math.floor(t/2)}function _e(e,t){for(let n=t-1;n>=0;--n){let t=e.get(n);if(t!==void 0)return t}}function ve(e){return B(z(e)?.match(/\bref\s*=\s*['"]?(@?e\d+)['"]?/i)?.[1]??e.match(/@?(e\d+)\b/i)?.[1])}function z(e){return e.replaceAll(/"(?:[^"\\]|\\.)*"/g,`""`).replaceAll(/'(?:[^'\\]|\\.)*'/g,`''`).match(/\[([^\]]*\bref\s*=\s*['"]?@?e\d+[^\]]*)\]\s*(?=:|$)/i)?.[1]}function B(e){let t=e?.trim().replace(/^@/,``);return t&&/^e\d+$/i.test(t)?t.toLowerCase():null}function ye(e){return e.replaceAll(/\[[^\]]*ref[^\]]*\]/gi,``).replaceAll(/@?e\d+\b/gi,``).replaceAll(/^[\s|├└─>*-]+/g,``).trim().match(/^([A-Za-z][\w-]*)\b/)?.[1]}function be(e){return e.match(/"([^"]+)"/)?.[1]??e.match(/'([^']+)'/)?.[1]}function xe(e){return/\bdisabled\b/i.test(z(e)??``)}function Se(e){return Ce(e)??e.match(/\bvalue=(?:"([^"]*)"|'([^']*)'|([^\s\]]+))/i)?.slice(1).find(U)??e.match(/\bvalue:\s*(?:"([^"]*)"|'([^']*)'|([^\s\]]+))/i)?.slice(1).find(U)}function Ce(e){return e.match(/\]\s*:\s*(.+)$/)?.[1]?.trim()||void 0}function V(e,t){if(e)for(let n of t){let t=e[n];if(typeof t==`string`&&t.length>0)return t}}function H(e,t){if(e)for(let n of t){let t=e[n];if(typeof t==`boolean`)return t}}function U(e){return typeof e==`string`}const W=`agent-browser`,G="Run `agent-device web setup` to install the managed web backend.";function we(e={}){let t=e.session?.trim(),n=async(n,r)=>await Pe(n,{session:t,options:e,signal:r});return{async open(e){await n([`open`,e])},async close(){await n([`close`])},async startRecording(e){await n([`record`,`start`,e])},async stopRecording(){await n([`record`,`stop`])},async snapshot(e){return await Ae(t=>n(t,e?.signal),e)},async screenshot(e,t){await n([`screenshot`,...t?.fullscreen?[`--full`]:[],e])},async setViewport(e,t){await n([`set`,`viewport`,String(e),String(t)])},async click(e,t){await K(n,e,t)},async hover(e,t){await q(n,e,t)},async hoverRef(e){await n([`hover`,Z(e)])},async clickRef(e){await n([`click`,Z(e)])},async fill(e,t,r){if(await K(n,e,t),await n([`press`,He()]),r.length===0){await n([`press`,`Backspace`]);return}await n([`keyboard`,`type`,r])},async fillRef(e,t){await n([`fill`,Z(e),t])},async typeText(e){await n([`keyboard`,`type`,e])},async scroll(e,t){return await Te(n,e,t),t?.durationMs===void 0?{}:{durationMs:t.durationMs}},async dumpNetwork(e){return ce(await n([`network`,`requests`]),e)},async probeAudio(e){return ae(await n([`eval`,ie(e)]))}}}async function Te(e,t,n){let r=De(Ee(n));for(let n of r)await e(ke(t,n.distance)),n.delayAfterMs>0&&await o(n.delayAfterMs)}function Ee(e){let t=e?.durationMs,r=t===void 0?{}:{durationMs:t};return e?.pixels===void 0?e?.amount===void 0?r:{distance:Math.max(1,Math.round(300*e.amount/n)),...r}:{distance:e.pixels,...r}}function De(e){let{distance:t,durationMs:n}=e;if(n===void 0||n<=0)return[{distance:t,delayAfterMs:0}];let r=Math.max(1,Math.min(20,Math.ceil(n/50))),i=n/Math.max(1,r-1);return Oe(Math.round(t??300),r).map((e,t)=>({distance:e,delayAfterMs:t<r-1?i:0}))}function Oe(e,t){let n=Math.floor(e/t),r=e-n*t;return Array.from({length:t},(e,t)=>t<r?n+1:n)}function ke(e,t){return[`scroll`,e,...t===void 0?[]:[String(t)]]}async function K(e,t,n){await q(e,t,n),await e([`mouse`,`down`]),await e([`mouse`,`up`])}async function q(e,t,n){await e([`mouse`,`move`,String(Math.round(t)),String(Math.round(n))])}async function Ae(e,t){return await me(await e(je(t)),t?.includeRects?async t=>await Me(e,t):void 0)}function je(e){return[`snapshot`,...e?.interactiveOnly?[`--interactive`]:[],...e?.raw?[]:[`--compact`],...typeof e?.depth==`number`?[`--depth`,String(e.depth)]:[],...e?.scope?[`--selector`,e.scope]:[]]}async function Me(e,t){try{return Ue(await e([`get`,`box`,Z(t)]))}catch(e){if(Ne(e))return;throw e}}function Ne(e){let t=e instanceof Error?e.message:String(e);return!/\bstale\b/i.test(t)&&/\bbox\b|not visible|not found|no element/i.test(t)}async function Pe(e,t){let{session:n,options:r,signal:i}=t,a=[...e,`--json`,...n?[`--session`,n]:[]];return await Fe(a,r,e=>Re(ze(e.stdout,e.stderr,a,e.exitCode),e,a),i)}async function Fe(e,t,n,r){let i=``,a=``,o=0,s=!1,c=!1,l=u({stateDir:t.stateDir});try{await Le(t);let n=await ee(e,{stateDir:t.stateDir,allowFailure:!0,timeoutMs:3e4,signal:r});i=n.stdout,a=n.stderr,o=n.exitCode,s=!0}catch(n){throw await J({cliArgs:e,commandCompleted:s,exitCode:o,semanticSuccess:c,options:t,status:l}),Be(n,e)}try{let e=n({stdout:i,stderr:a,exitCode:o});return c=!0,e}finally{await J({cliArgs:e,commandCompleted:s,exitCode:o,semanticSuccess:c,options:t,status:l})}}async function J(e){let t=e.options.ownedProcessRecords;if(!(!t||!e.status.installed))try{let n=e.options.openWebSessionNames?.()??[],r=e.options.session?.trim();Ie(e,n.filter(e=>e!==r).length)?t.clear({kind:`daemon`}):await c(e.status,t)}catch(e){r({level:`warn`,phase:`web_agent_browser_process_record_failed`,data:{error:e instanceof Error?e.message:String(e)}})}}function Ie(e,t){return e.commandCompleted&&e.semanticSuccess&&e.cliArgs[0]===`close`&&e.exitCode===0&&t===0}async function Le(e){if(!e.openWebSessionNames)return;let t=u({stateDir:e.stateDir});if(t.installed)try{await l(t,{openWebSessionNames:e.openWebSessionNames(),...e.ownedProcessRecords===void 0?{}:{ownedProcessRecords:e.ownedProcessRecords}})}catch(e){r({level:`warn`,phase:`web_agent_browser_provider_orphan_cleanup_failed`,data:{error:e instanceof Error?e.message:String(e)}})}}function Re(t,n,r){if(!d(t))return t;if((t.success??t.ok)===!1)throw new e(Ve(t.code),X(t),{cmd:W,args:r,hint:p(t,`hint`)??G,agentBrowserError:t.error});if(n.exitCode!==0)throw new e(`COMMAND_FAILED`,`agent-browser command failed`,a(n,{cmd:W,args:r,stdout:n.stdout.slice(0,500),stderr:n.stderr.slice(0,500),hint:p(t,`hint`)??G}));return Object.hasOwn(t,`data`)?t.data:t}function ze(t,n,r,i){try{return JSON.parse(t)}catch(a){let o=i!==0;throw new e(`COMMAND_FAILED`,o?`agent-browser command failed`:`agent-browser returned invalid JSON`,{cmd:W,args:r,...o?{exitCode:i}:{},stdout:t.slice(0,500),stderr:n.slice(0,500),hint:G},a instanceof Error?a:void 0)}}function Be(t,n){let r=te(t);return r.code===`TOOL_MISSING`?new e(`TOOL_MISSING`,r.message,{...r.details??{},cmd:W,args:n,hint:Y(r)},r):r.code===`COMMAND_FAILED`?new e(`COMMAND_FAILED`,r.message,{...r.details??{},cmd:W,args:n,hint:Y(r)},r):r}function Y(e){return typeof e.details?.hint==`string`?e.details.hint:G}function X(e){let t=e.error;if(typeof t==`string`&&t.trim())return t.trim();if(d(t)){let e=p(t,`message`)??p(t,`error`);if(e)return e}return p(e,`message`)??`agent-browser command failed`}function Ve(e){return typeof e==`string`&&e.length>0?e:`COMMAND_FAILED`}function Z(e){return e.startsWith(`@`)?e:`@${e}`}function He(){return i()===`darwin`?`Meta+a`:`Control+a`}function Ue(e){let t=d(e)&&d(e.box)?e.box:e;if(d(t))return We(t)??Ge(t)}function We(e){return Q(m(e,`x`),m(e,`y`),m(e,`width`),m(e,`height`))}function Ge(e){let t=m(e,`left`),n=m(e,`top`),r=m(e,`right`),i=m(e,`bottom`);return Q(t,n,$(r,t),$(i,n))}function Q(e,t,n,r){if(e!==void 0&&t!==void 0&&n!==void 0&&r!==void 0)return{x:e,y:t,width:n,height:r}}function $(e,t){return e===void 0||t===void 0?void 0:e-t}export{we as createAgentBrowserWebProvider};
|
|
1
|
+
import{N as e}from"./sdk-contracts.js";import{k as t}from"./sdk-batch-runner.js";import{t as n}from"./scroll-gesture.js";import{r}from"./diagnostics.js";import{d as i}from"./owner-identity.js";import{n as a}from"./exec.js";import{t as o}from"./timeouts.js";import"./diagnostics2.js";import"./command.js";import"./process.js";import"./retry.js";import{n as s}from"./audio-probe-result.js";import{i as c}from"./agent-browser-process-record.js";import{n as l}from"./agent-browser-lifecycle.js";import{i as ee,n as u,r as te}from"./agent-browser-tool.js";function d(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function f(e,t){return d(e)?e[t]:void 0}function p(e,t){let n=f(e,t);return typeof n==`string`?n:void 0}function ne(e,t){let n=f(e,t);return typeof n==`boolean`?n:void 0}function m(e,t){let n=e[t];return typeof n==`number`&&Number.isFinite(n)?n:void 0}const re=[g,_,v,y,b,x,S,C,w,T,E,D,O,k,A,j,M];function ie(e){let t=re.map(e=>`${e.toString()};`).join(``),n=oe(e.action),r=h(e.durationMs),i=h(e.bucketMs);return`(()=>{${t}return ${M.name}({action:${n},durationMs:${r},bucketMs:${i}})})()`}function ae(e){let t=s(se(e),{source:`media-elements`,backend:`agent-browser`,durationMs:0,elapsedMs:0,bucketMs:1e3,activeFallback:!1,mediaElementCount:0,sourceCount:0});return{...t,source:`media-elements`,mediaElementCount:t.mediaElementCount??0}}function oe(e){switch(e){case`start`:return`'start'`;case`stop`:return`'stop'`;default:return`'status'`}}function h(e){return e===void 0||!Number.isFinite(e)?`undefined`:String(Math.trunc(e))}function g(e){return!Number.isFinite(e)||e<=0?-90:Math.max(-90,Math.min(0,Math.round(20*Math.log10(e))))}function _(e,t){e.notes.includes(t)||e.notes.push(t)}function v(){return Array.from(document.querySelectorAll(`audio,video`))}function y(e,t){if(!e||e.state===`stopped`)return e;clearInterval(e.timer),clearTimeout(e.timeout),e.timer=void 0,e.timeout=void 0,e.state=`stopped`,e.active=!1,e.reason=t,e.stoppedAt=Date.now();for(let t of e.analysers)try{t.analyser.disconnect(),t.source.disconnect(),t.audible&&t.source.connect(e.context.destination)}catch{}if(e.resumeOnGesture){for(let t of[`click`,`pointerdown`,`keydown`])window.removeEventListener(t,e.resumeOnGesture,!0);e.resumeOnGesture=void 0}return e}function b(e){let t=window.AudioContext||window.webkitAudioContext;if(!t)return;let n=window[e];if(n&&n.state!==`closed`)return n;let r=new t;return window[e]=r,r}function x(e,t,n){if(!(!t.currentSrc&&!t.src&&t.readyState===0))try{window[n]||(window[n]=new WeakMap);let r=window[n].get(t);return r||(r=e.context.createMediaElementSource(t),window[n].set(t,r)),r.disconnect(),{source:r,audible:!0}}catch{return}}function S(e,t){if(!(!t||typeof t.getAudioTracks!=`function`)&&t.getAudioTracks().length!==0)return{source:e.context.createMediaStreamSource(t),audible:!1}}function C(e,t){if(typeof t.captureStream==`function`)return S(e,t.captureStream())}function w(e,t){let n=e.context.createAnalyser();n.fftSize=2048,t.source.connect(n),n.connect(t.audible?e.context.destination:e.sink),e.analysers.push({...t,analyser:n,buffer:new Float32Array(n.fftSize)})}function T(e,t){let n=v();e.mediaElementCount=n.length;for(let r of n){if(e.seen.has(r))continue;let n=S(e,r.srcObject)??C(e,r)??x(e,r,t);if(!n){_(e,`Some media elements do not expose capturable audio to Web Audio.`);continue}e.seen.add(r),w(e,n)}e.sourceCount=e.analysers.length,e.sourceCount===0&&_(e,`No capturable page media audio sources were found yet.`)}function E(e){let t=0,n=0,r=0;for(let i of e.analysers){i.analyser.getFloatTimeDomainData(i.buffer);for(let e of i.buffer)t+=e*e,n+=1,r=Math.max(r,Math.abs(e))}return{rms:n>0?Math.sqrt(t/n):0,peak:r}}function D(e){let t=Math.ceil(e.durationMs/e.bucketMs)+2;e.rmsDbfs.length>t&&e.rmsDbfs.splice(0,e.rmsDbfs.length-t),e.peakDbfs.length>t&&e.peakDbfs.splice(0,e.peakDbfs.length-t)}function O(e,t){if(!e||e.state!==`running`)return;T(e,t);let n=E(e),r=g(n.rms),i=g(n.peak);e.rmsDbfs.push(r),e.peakDbfs.push(i),e.heard=e.heard||r>-90||i>-90,D(e),Date.now()-e.startedAt>=e.durationMs&&y(e,`duration`)}function k(e,t){return{audio:`probe`,state:`stopped`,active:!1,heard:!1,source:`media-elements`,backend:`agent-browser`,durationMs:Number(e.durationMs)||1e4,elapsedMs:0,bucketMs:Number(e.bucketMs)||1e3,sampleCount:0,mediaElementCount:v().length,sourceCount:0,rmsDbfs:[],peakDbfs:[],notes:t}}function A(e,t,n,r){return e?{audio:`probe`,state:e.state,active:e.state===`running`,heard:e.heard,source:`media-elements`,backend:`agent-browser`,durationMs:e.durationMs,elapsedMs:Math.max(0,Math.min((e.stoppedAt||Date.now())-e.startedAt,e.durationMs)),bucketMs:e.bucketMs,sampleCount:e.rmsDbfs.length,mediaElementCount:v().length,sourceCount:e.sourceCount,rmsDbfs:e.rmsDbfs.slice(),peakDbfs:e.peakDbfs.slice(),startedAt:new Date(e.startedAt).toISOString(),stoppedAt:e.stoppedAt?new Date(e.stoppedAt).toISOString():void 0,reason:e.reason,notes:[n,r,...e.notes]}:k(t,[n,r])}function j(e,t,n,r,i,a,o){t&&y(t,`restarted`);let s=b(r);if(!s)return k(e,[`Web Audio API is not available in this browser context.`]);let c=s.createGain();c.gain.value=0,c.connect(s.destination);let l={state:`running`,active:!0,context:s,sink:c,seen:new WeakSet,analysers:[],mediaElementCount:0,sourceCount:0,durationMs:Math.max(100,Number(e.durationMs)||1e4),bucketMs:Math.max(100,Number(e.bucketMs)||1e3),startedAt:Date.now(),stoppedAt:void 0,reason:void 0,heard:!1,rmsDbfs:[],peakDbfs:[],notes:[]};try{s.resume()}catch{_(l,`AudioContext could not be resumed by the probe.`)}l.resumeOnGesture=()=>{try{s.resume()}catch{_(l,`AudioContext could not be resumed from a user gesture.`)}};for(let e of[`click`,`pointerdown`,`keydown`])window.addEventListener(e,l.resumeOnGesture,{capture:!0,once:!0});return T(l,i),l.timer=setInterval(()=>O(l,i),l.bucketMs),l.timeout=setTimeout(()=>y(l,`duration`),l.durationMs),window[n]=l,A(l,e,a,o)}function M(e){let t=`__agentDeviceAudioProbe`,n=`__agentDeviceAudioProbeSources`,r=`Audio probe samples HTML media elements exposed to Web Audio; it is not whole-tab or system audio capture.`,i=`URL-backed media elements may be routed through the probe AudioContext while they are observed.`,a=window[t];return a&&a.state===`running`&&Date.now()-a.startedAt>=a.durationMs&&(O(a,n),y(a,`duration`)),e.action===`start`?j(e,a,t,`__agentDeviceAudioProbeContext`,n,r,i):e.action===`stop`?(a&&O(a,n),y(a,`manual`),A(a,e,r,i)):(a&&O(a,n),A(a,e,r,i))}function se(e){return d(e)?d(e.result)?e.result:e:{}}function ce(e,t={}){let n=le(e),r=pe(t.limit),i=t.include===`headers`||t.include===`all`,a=n.slice(-r).reverse().map(e=>de(e,i)),o=t.include===`body`||t.include===`all`?[`agent-browser network requests does not expose request or response bodies.`]:void 0;return{entries:a,backend:`agent-browser`,redacted:!1,...o?{notes:o}:{}}}function le(e){let t=d(e)&&Array.isArray(e.requests)?e.requests:e;return Array.isArray(t)?t.filter(ue).map(e=>({headers:N(e.headers),method:p(e,`method`),mimeType:p(e,`mimeType`),requestId:p(e,`requestId`),resourceType:p(e,`resourceType`),responseHeaders:N(e.responseHeaders),status:m(e,`status`),timestamp:fe(e.timestamp),url:p(e,`url`)})):[]}function ue(e){return d(e)}function de(e,n){let r=e.timestamp===void 0?void 0:P(e.timestamp),i=t({requestId:e.requestId,resourceType:e.resourceType,mimeType:e.mimeType});return t({timestamp:r,method:e.method,url:e.url,status:e.status,requestHeaders:n?e.headers:void 0,responseHeaders:n?e.responseHeaders:void 0,metadata:Object.keys(i).length>0?i:void 0})}function N(e){if(!d(e))return;let t={};for(let[n,r]of Object.entries(e))typeof r==`string`&&(t[n]=r);return Object.keys(t).length>0?t:void 0}function fe(e){if(typeof e==`number`||typeof e==`string`)return e}function P(e){if(typeof e==`string`){let t=Number(e);return Number.isFinite(t)?P(t):e}let t=e>1e10?e:e*1e3,n=new Date(t);return Number.isNaN(n.getTime())?String(e):n.toISOString()}function pe(e){return typeof e!=`number`||!Number.isInteger(e)?25:Math.max(1,Math.min(e,200))}async function me(e,t){let n=F(p(e,`snapshot`)??``,R(f(e,`refs`)));return t&&await he(n,t),{nodes:n.map((e,t)=>({...e.node,index:t,ref:e.ref})),truncated:ne(e,`truncated`)}}async function he(e,t){for(let n=0;n<e.length;n+=8){let r=e.slice(n,n+8),i=await Promise.all(r.map(e=>t(e.ref)));for(let[e,t]of i.entries())t&&(r[e].node.rect=t)}}function F(e,t){let n=new Map(t.map(e=>[e.ref,e])),r=[],i=new Set,a=new Map;for(let t of e.split(/\r?\n/)){let e=ve(t);if(!e)continue;i.add(e);let o=n.get(e)?.data,s=ge(t),c=I(t,o,s),l=_e(a,s);l!==void 0&&(c.parentIndex=l),r.push({ref:e,node:{...c,index:r.length}}),a.set(s,r.length-1)}for(let e of t)i.has(e.ref)||r.push({ref:e.ref,node:{...L(e.data),index:r.length}});return r}function I(e,t,n){let r=ye(e)??V(t,[`role`,`type`]);return{index:0,type:r,role:r,label:be(e)??V(t,[`label`,`name`,`text`]),value:Se(e)??V(t,[`value`]),depth:n,enabled:H(t,[`enabled`])??(!xe(e)&&void 0),focused:H(t,[`focused`])}}function L(e){let t=V(e,[`role`,`type`]);return{index:0,type:t,role:t,label:V(e,[`label`,`name`,`text`]),value:V(e,[`value`]),enabled:H(e,[`enabled`]),focused:H(e,[`focused`])}}function R(e){return Array.isArray(e)?e.flatMap(e=>{let t=d(e)?e:void 0,n=B(V(t,[`ref`,`id`])??String(e));return n?[{ref:n,data:t}]:[]}):d(e)?Object.entries(e).flatMap(([e,t])=>{let n=B(e);return n?[{ref:n,data:d(t)?t:void 0}]:[]}):[]}function ge(e){let t=e.match(/^\s*/)?.[0].length??0;return Math.floor(t/2)}function _e(e,t){for(let n=t-1;n>=0;--n){let t=e.get(n);if(t!==void 0)return t}}function ve(e){return B(z(e)?.match(/\bref\s*=\s*['"]?(@?e\d+)['"]?/i)?.[1]??e.match(/@?(e\d+)\b/i)?.[1])}function z(e){return e.replaceAll(/"(?:[^"\\]|\\.)*"/g,`""`).replaceAll(/'(?:[^'\\]|\\.)*'/g,`''`).match(/\[([^\]]*\bref\s*=\s*['"]?@?e\d+[^\]]*)\]\s*(?=:|$)/i)?.[1]}function B(e){let t=e?.trim().replace(/^@/,``);return t&&/^e\d+$/i.test(t)?t.toLowerCase():null}function ye(e){return e.replaceAll(/\[[^\]]*ref[^\]]*\]/gi,``).replaceAll(/@?e\d+\b/gi,``).replaceAll(/^[\s|├└─>*-]+/g,``).trim().match(/^([A-Za-z][\w-]*)\b/)?.[1]}function be(e){return e.match(/"([^"]+)"/)?.[1]??e.match(/'([^']+)'/)?.[1]}function xe(e){return/\bdisabled\b/i.test(z(e)??``)}function Se(e){return Ce(e)??e.match(/\bvalue=(?:"([^"]*)"|'([^']*)'|([^\s\]]+))/i)?.slice(1).find(U)??e.match(/\bvalue:\s*(?:"([^"]*)"|'([^']*)'|([^\s\]]+))/i)?.slice(1).find(U)}function Ce(e){return e.match(/\]\s*:\s*(.+)$/)?.[1]?.trim()||void 0}function V(e,t){if(e)for(let n of t){let t=e[n];if(typeof t==`string`&&t.length>0)return t}}function H(e,t){if(e)for(let n of t){let t=e[n];if(typeof t==`boolean`)return t}}function U(e){return typeof e==`string`}const W=`agent-browser`,G="Run `agent-device web setup` to install the managed web backend.";function we(e={}){let t=e.session?.trim(),n=async(n,r)=>await Pe(n,{session:t,options:e,signal:r});return{async open(e){await n([`open`,e])},async close(){await n([`close`])},async startRecording(e){await n([`record`,`start`,e])},async stopRecording(){await n([`record`,`stop`])},async snapshot(e){return await Ae(t=>n(t,e?.signal),e)},async screenshot(e,t){await n([`screenshot`,...t?.fullscreen?[`--full`]:[],e])},async setViewport(e,t){await n([`set`,`viewport`,String(e),String(t)])},async click(e,t){await K(n,e,t)},async hover(e,t){await q(n,e,t)},async hoverRef(e){await n([`hover`,Z(e)])},async clickRef(e){await n([`click`,Z(e)])},async fill(e,t,r){if(await K(n,e,t),await n([`press`,He()]),r.length===0){await n([`press`,`Backspace`]);return}await n([`keyboard`,`type`,r])},async fillRef(e,t){await n([`fill`,Z(e),t])},async typeText(e){await n([`keyboard`,`type`,e])},async scroll(e,t){return await Te(n,e,t),t?.durationMs===void 0?{}:{durationMs:t.durationMs}},async dumpNetwork(e){return ce(await n([`network`,`requests`]),e)},async probeAudio(e){return ae(await n([`eval`,ie(e)]))}}}async function Te(e,t,n){let r=De(Ee(n));for(let n of r)await e(ke(t,n.distance)),n.delayAfterMs>0&&await o(n.delayAfterMs)}function Ee(e){let t=e?.durationMs,r=t===void 0?{}:{durationMs:t};return e?.pixels===void 0?e?.amount===void 0?r:{distance:Math.max(1,Math.round(300*e.amount/n)),...r}:{distance:e.pixels,...r}}function De(e){let{distance:t,durationMs:n}=e;if(n===void 0||n<=0)return[{distance:t,delayAfterMs:0}];let r=Math.max(1,Math.min(20,Math.ceil(n/50))),i=n/Math.max(1,r-1);return Oe(Math.round(t??300),r).map((e,t)=>({distance:e,delayAfterMs:t<r-1?i:0}))}function Oe(e,t){let n=Math.floor(e/t),r=e-n*t;return Array.from({length:t},(e,t)=>t<r?n+1:n)}function ke(e,t){return[`scroll`,e,...t===void 0?[]:[String(t)]]}async function K(e,t,n){await q(e,t,n),await e([`mouse`,`down`]),await e([`mouse`,`up`])}async function q(e,t,n){await e([`mouse`,`move`,String(Math.round(t)),String(Math.round(n))])}async function Ae(e,t){return await me(await e(je(t)),t?.includeRects?async t=>await Me(e,t):void 0)}function je(e){return[`snapshot`,...e?.interactiveOnly?[`--interactive`]:[],...e?.raw?[]:[`--compact`],...typeof e?.depth==`number`?[`--depth`,String(e.depth)]:[],...e?.scope?[`--selector`,e.scope]:[]]}async function Me(e,t){try{return Ue(await e([`get`,`box`,Z(t)]))}catch(e){if(Ne(e))return;throw e}}function Ne(e){let t=e instanceof Error?e.message:String(e);return!/\bstale\b/i.test(t)&&/\bbox\b|not visible|not found|no element/i.test(t)}async function Pe(e,t){let{session:n,options:r,signal:i}=t,a=[...e,`--json`,...n?[`--session`,n]:[]];return await Fe(a,r,e=>Re(ze(e.stdout,e.stderr,a,e.exitCode),e,a),i)}async function Fe(e,t,n,r){let i=``,a=``,o=0,s=!1,c=!1,l=u({stateDir:t.stateDir});try{await Le(t);let n=await ee(e,{stateDir:t.stateDir,allowFailure:!0,timeoutMs:3e4,signal:r});i=n.stdout,a=n.stderr,o=n.exitCode,s=!0}catch(n){throw await J({cliArgs:e,commandCompleted:s,exitCode:o,semanticSuccess:c,options:t,status:l}),Be(n,e)}try{let e=n({stdout:i,stderr:a,exitCode:o});return c=!0,e}finally{await J({cliArgs:e,commandCompleted:s,exitCode:o,semanticSuccess:c,options:t,status:l})}}async function J(e){let t=e.options.ownedProcessRecords;if(!(!t||!e.status.installed))try{let n=e.options.openWebSessionNames?.()??[],r=e.options.session?.trim();Ie(e,n.filter(e=>e!==r).length)?t.clear({kind:`daemon`}):await c(e.status,t)}catch(e){r({level:`warn`,phase:`web_agent_browser_process_record_failed`,data:{error:e instanceof Error?e.message:String(e)}})}}function Ie(e,t){return e.commandCompleted&&e.semanticSuccess&&e.cliArgs[0]===`close`&&e.exitCode===0&&t===0}async function Le(e){if(!e.openWebSessionNames)return;let t=u({stateDir:e.stateDir});if(t.installed)try{await l(t,{openWebSessionNames:e.openWebSessionNames(),...e.ownedProcessRecords===void 0?{}:{ownedProcessRecords:e.ownedProcessRecords}})}catch(e){r({level:`warn`,phase:`web_agent_browser_provider_orphan_cleanup_failed`,data:{error:e instanceof Error?e.message:String(e)}})}}function Re(t,n,r){if(!d(t))return t;if((t.success??t.ok)===!1)throw new e(Ve(t.code),X(t),{cmd:W,args:r,hint:p(t,`hint`)??G,agentBrowserError:t.error});if(n.exitCode!==0)throw new e(`COMMAND_FAILED`,`agent-browser command failed`,a(n,{cmd:W,args:r,stdout:n.stdout.slice(0,500),stderr:n.stderr.slice(0,500),hint:p(t,`hint`)??G}));return Object.hasOwn(t,`data`)?t.data:t}function ze(t,n,r,i){try{return JSON.parse(t)}catch(a){let o=i!==0;throw new e(`COMMAND_FAILED`,o?`agent-browser command failed`:`agent-browser returned invalid JSON`,{cmd:W,args:r,...o?{exitCode:i}:{},stdout:t.slice(0,500),stderr:n.slice(0,500),hint:G},a instanceof Error?a:void 0)}}function Be(t,n){let r=te(t);return r.code===`TOOL_MISSING`?new e(`TOOL_MISSING`,r.message,{...r.details??{},cmd:W,args:n,hint:Y(r)},r):r.code===`COMMAND_FAILED`?new e(`COMMAND_FAILED`,r.message,{...r.details??{},cmd:W,args:n,hint:Y(r)},r):r}function Y(e){return typeof e.details?.hint==`string`?e.details.hint:G}function X(e){let t=e.error;if(typeof t==`string`&&t.trim())return t.trim();if(d(t)){let e=p(t,`message`)??p(t,`error`);if(e)return e}return p(e,`message`)??`agent-browser command failed`}function Ve(e){return typeof e==`string`&&e.length>0?e:`COMMAND_FAILED`}function Z(e){return e.startsWith(`@`)?e:`@${e}`}function He(){return i()===`darwin`?`Meta+a`:`Control+a`}function Ue(e){let t=d(e)&&d(e.box)?e.box:e;if(d(t))return We(t)??Ge(t)}function We(e){return Q(m(e,`x`),m(e,`y`),m(e,`width`),m(e,`height`))}function Ge(e){let t=m(e,`left`),n=m(e,`top`),r=m(e,`right`),i=m(e,`bottom`);return Q(t,n,$(r,t),$(i,n))}function Q(e,t,n,r){if(e!==void 0&&t!==void 0&&n!==void 0&&r!==void 0)return{x:e,y:t,width:n,height:r}}function $(e,t){return e===void 0||t===void 0?void 0:e-t}export{we as createAgentBrowserWebProvider};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime.js";import{
|
|
1
|
+
import{r as e}from"./rolldown-runtime.js";import{N as t,P as n}from"./sdk-contracts.js";import{C as r,c as i,d as a,f as o,l as s,s as c,u as l}from"./owner-identity.js";import{c as u}from"./exec.js";import{n as d,t as f}from"./file.js";import"./command.js";import"./process.js";import{O as p,S as m,a as h,b as g,c as _,d as v,l as y,p as b,s as x,v as S}from"./host-file.js";import{n as C}from"./agent-browser-process-record.js";import{r as w}from"./agent-browser-lifecycle.js";import T from"node:path";import E from"node:crypto";async function D(e){x(e.packageRoot);let t=ee([`install`,`--prefix`,e.packageRoot,`--no-global`,`--no-audit`,`--no-fund`,`--no-save`,e.packageSpec]);await u(t.command,t.args,{env:i(),timeoutMs:e.timeoutMs})}function O(e){p(T.join(e.installDir,`manifest.json`),JSON.stringify({package:e.packageName,version:e.version,node:l(),installedAt:new Date().toISOString()},null,2))}function ee(e){if(a()!==`win32`)return{command:`npm`,args:e};let n=k(i());if(!n)throw new t(`TOOL_MISSING`,`npm not found in PATH`,{nodeExecPath:s(),hint:"Install Node.js with npm, or add npm to PATH, and run `agent-device web setup` again."});return{command:s(),args:[n,...e]}}function k(e){let t=e.npm_execpath?.trim();if(t){let e=T.resolve(t);if(T.basename(e)===`npm-cli.js`&&A(e))return e}let n=T.join(T.dirname(s()),`node_modules`,`npm`,`bin`,`npm-cli.js`);return A(n)?n:void 0}function A(e){try{return v(e).isFile()}catch{return!1}}var j=e({doctorManagedAgentBrowser:()=>R,getManagedAgentBrowserStatus:()=>z,mapManagedAgentBrowserError:()=>$,runManagedAgentBrowser:()=>I,setupManagedAgentBrowser:()=>L});const M=`0.27.1`,N=`agent-browser`,P=3e5,F=6e4;async function I(e,t){let n=z({stateDir:t.stateDir});if(!n.installed)throw J(n);return await B(n,e,t)}async function L(e){let t=z(e);X(t.nodeMajor);let n=o();return await d({acquire:()=>f({lockDirPath:T.join(t.installDir,`..`,`.agent-browser-install.lock`),owner:{pid:n,startTime:r(n),acquiredAtMs:Date.now()},timeoutMs:P,description:`managed agent-browser setup`}),task:async()=>{let t=z(e);if(t.installed)return t;x(t.installDir),await D({packageRoot:T.join(t.installDir,`package`),packageSpec:`${N}@${M}`,timeoutMs:P});let n=z(e);if(!n.entryScript)throw Y(n);return await B(n,[`install`],{timeoutMs:P}),await B(n,[`doctor`,`--offline`,`--quick`],{timeoutMs:F}),O({installDir:n.installDir,packageName:N,version:M}),await z(e)}})}async function R(e){let t=z(e);if(!t.installed)throw J(t);return{status:t,...await B(t,[`doctor`,`--offline`,`--quick`],{timeoutMs:F,allowFailure:!0})}}function z(e){let t=e.stateDir??i().AGENT_DEVICE_STATE_DIR??ne(),n=T.join(t,`tools`,`agent-browser`,M),r=K(n),a=q(n),o=W(r),s=T.join(n,`home`),c=Z(n),u=Q(n),d=o!==void 0&&U(n),f=Number.parseInt(l().replace(/^v/,``).split(`.`)[0]??`0`,10);return{version:M,stateDir:t,installDir:n,packageDir:r,binaryPath:a,entryScript:o,homeDir:s,runtimeHomeDir:c,socketDir:u,installed:d,nodeMajor:f,nodeSupported:f>=24}}async function B(e,t,n){if(!e.entryScript)throw J(e);return await u(s(),[e.entryScript,...t],{allowFailure:n.allowFailure,env:V(e,i()),timeoutMs:n.timeoutMs,signal:n.signal})}function V(e,t){return x(e.homeDir),H(e),x(e.socketDir),{...t,HOME:e.runtimeHomeDir,AGENT_BROWSER_SOCKET_DIR:e.socketDir,AGENT_BROWSER_IDLE_TIMEOUT_MS:String(w(t)),AGENT_BROWSER_ARGS:C(t.AGENT_BROWSER_ARGS,e)}}function H(e){if(e.runtimeHomeDir!==e.homeDir){x(T.dirname(e.runtimeHomeDir));try{let t=y(e.runtimeHomeDir);if(t.isSymbolicLink()&&S(e.runtimeHomeDir)===e.homeDir||t.isDirectory())return;t.isSymbolicLink()&&m(e.runtimeHomeDir)}catch(e){if(!te(e))throw e}try{h(e.homeDir,e.runtimeHomeDir)}catch{x(e.runtimeHomeDir)}}}function U(e){return _(T.join(e,`manifest.json`))}function W(e){let t;try{let n=JSON.parse(g(T.join(e,`package.json`)));t=typeof n==`object`&&n?n.bin:void 0}catch{return}let n=typeof t==`string`?t:typeof t==`object`&&t?t[N]:void 0;if(typeof n!=`string`)return;let r=T.resolve(e,n);return G(r)?r:void 0}function G(e){try{return v(e).isFile()}catch{return!1}}function K(e){return T.join(e,`package`,`node_modules`,N)}function q(e){let t=a()===`win32`?`${N}.cmd`:N;return T.join(e,`package`,`node_modules`,`.bin`,t)}function J(e){return new t(`TOOL_MISSING`,`Managed web browser backend is not installed.`,{version:M,installDir:e.installDir,hint:e.nodeSupported===!1?`Web automation requires Node 24+; current Node is ${l()}.`:"Run `agent-device web setup` to install the managed web backend."})}function Y(e){return new t(`TOOL_MISSING`,`Managed web backend install produced no runnable entry.`,{version:M,installDir:e.installDir,packageDir:e.packageDir,hint:`Remove ${e.installDir} and run \`agent-device web setup\` again.`})}function X(e){if(!(e>=24))throw new t(`UNSUPPORTED_OPERATION`,`Web automation requires Node 24 or newer.`,{currentNode:l(),requiredNodeMajor:24,hint:`Run agent-device with Node 24+ for web setup and web automation.`})}function Z(e){if(a()===`win32`)return T.join(e,`home`);let t=E.createHash(`sha1`).update(e).digest(`hex`).slice(0,12);return T.join(b(),`agent-device-web`,t)}function Q(e){let t=E.createHash(`sha1`).update(e).digest(`hex`).slice(0,12);return T.join(b(),`adw`,t)}function te(e){return typeof e==`object`&&!!e&&`code`in e&&e.code===`ENOENT`}function ne(){return T.join(i().HOME??c(),`.agent-device`)}function $(e){let r=n(e);return r.code===`TOOL_MISSING`?new t(r.code,r.message,{...r.details??{},hint:typeof r.details?.hint==`string`?r.details.hint:"Run `agent-device web setup` to install the managed web backend."}):r}export{I as i,z as n,$ as r,j as t};
|