agent-device 0.21.15 → 0.21.16
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.15.apk → agent-device-android-ime-helper-0.21.16.apk} +0 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.16.apk.sha256 +1 -0
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.15.manifest.json → agent-device-android-ime-helper-0.21.16.manifest.json} +4 -4
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.15.apk → agent-device-android-snapshot-helper-0.21.16.apk} +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.16.apk.sha256 +1 -0
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.15.manifest.json → agent-device-android-snapshot-helper-0.21.16.manifest.json} +6 -6
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +1 -4
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedTextEntry.h +9 -9
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedTextEntry.m +13 -22
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSystemSurfaceHostPolicy.swift +0 -9
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedTextEntry.swift +202 -73
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +17 -2
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextTyping.swift +109 -128
- 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-provider.js +1 -1
- package/dist/src/agent-browser-tool.js +1 -1
- package/dist/src/agent-device-client.js +2 -2
- package/dist/src/ai-sdk.js +1 -1
- package/dist/src/alert-runtime.js +1 -1
- package/dist/src/android-input-ownership.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 +1 -1
- package/dist/src/apple-runner-platform.js +1 -1
- package/dist/src/application-lifecycle-interaction.js +1 -1
- package/dist/src/archive.js +1 -1
- package/dist/src/artifact-download.js +1 -1
- package/dist/src/auth-session.js +1 -1
- package/dist/src/auth.js +1 -1
- package/dist/src/backend-snapshot-options.js +1 -1
- package/dist/src/boot-diagnostics.js +1 -1
- package/dist/src/capture-disclosure.js +1 -1
- package/dist/src/capture.js +1 -1
- package/dist/src/cli-config.js +1 -1
- package/dist/src/cli-help.js +3 -2
- package/dist/src/cli.js +4 -4
- package/dist/src/click-button.js +1 -1
- package/dist/src/client-metro.js +1 -1
- package/dist/src/client-types.d.ts +1 -1
- package/dist/src/clipboard-shell-response.js +1 -1
- package/dist/src/command-schema.js +1 -1
- package/dist/src/command-tools.js +2 -2
- package/dist/src/connection-runtime.js +1 -1
- package/dist/src/connection.js +5 -5
- package/dist/src/contracts.js +1 -1
- package/dist/src/daemon-client-lease-beat.js +1 -0
- package/dist/src/daemon-client-lifecycle.js +1 -1
- package/dist/src/daemon-client-transport.js +1 -0
- 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 +2 -2
- package/dist/src/device-inventory-context.js +1 -1
- package/dist/src/device-rotation.js +1 -1
- package/dist/src/device-selection-resolver.js +1 -1
- package/dist/src/device-session.js +1 -1
- package/dist/src/device-shell.js +1 -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 -1
- package/dist/src/gesture-admission.js +1 -1
- package/dist/src/gesture-plan.js +1 -1
- package/dist/src/gesture-runtime.js +1 -1
- package/dist/src/harmonyos.js +1 -1
- package/dist/src/helper.js +1 -1
- 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.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 -4
- 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-engine.js +1 -1
- package/dist/src/ios-snapshot-runtime.js +1 -1
- package/dist/src/lease-context.js +1 -1
- package/dist/src/lease-scope.js +1 -1
- package/dist/src/lease.js +1 -1
- package/dist/src/limrun-download-file.js +1 -1
- package/dist/src/limrun-runtime-dependencies.js +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 +15 -15
- package/dist/src/multitouch-support.js +1 -1
- package/dist/src/native-build-cache.js +1 -1
- package/dist/src/observation.js +1 -1
- package/dist/src/overlay.js +2 -2
- 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-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/provider-session-ownership.js +1 -1
- package/dist/src/provider-webdriver.js +1 -1
- package/dist/src/proxy.js +1 -1
- package/dist/src/quality-warnings.js +1 -1
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-runtime.js +1 -1
- package/dist/src/recording.js +1 -1
- package/dist/src/rect-center.js +1 -1
- package/dist/src/register-builtins.js +1 -1
- package/dist/src/registry.js +13 -13
- 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-artifact-manifest.js +1 -0
- package/dist/src/runner-cache-metadata.js +3 -2
- package/dist/src/runner-client.js +1 -1
- package/dist/src/runner-dev-tools-security.js +1 -1
- package/dist/src/runner-device-readiness.js +1 -1
- package/dist/src/runner-disposal.js +1 -1
- package/dist/src/runner-error-classification.js +3 -3
- package/dist/src/runner-operations-facade.js +1 -1
- 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 +4 -4
- 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.js +1 -1
- package/dist/src/scroll-gesture.js +1 -1
- package/dist/src/sdk-batch-runner.js +2 -2
- package/dist/src/sdk-batch.js +1 -1
- 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/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 +3 -3
- package/dist/src/session2.js +3 -3
- 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 +1 -1
- package/dist/src/stop-sequence.js +1 -1
- package/dist/src/string-enum.js +1 -1
- package/dist/src/takeover.js +1 -1
- package/dist/src/text-entry-focus.js +1 -1
- package/dist/src/tool-provider.js +1 -1
- package/dist/src/tool-provider2.js +1 -1
- package/dist/src/touch-runtime.js +1 -1
- package/dist/src/transport.js +1 -1
- package/dist/src/tv-remote.js +1 -1
- package/dist/src/type-text-runtime.js +1 -1
- package/dist/src/verified-file.js +1 -1
- package/dist/src/video.js +1 -1
- package/dist/src/viewport.js +1 -1
- package/dist/src/web.js +1 -1
- package/dist/src/web2.js +1 -1
- package/dist/src/webdriver-source.js +1 -1
- package/package.json +2 -2
- package/server.json +2 -2
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.15.apk.sha256 +0 -1
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.15.apk.sha256 +0 -1
package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextTyping.swift
CHANGED
|
@@ -136,6 +136,39 @@ extension RunnerTests {
|
|
|
136
136
|
}
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
let synthesizedTypePlan = Self.synthesizedTextPlan(
|
|
145
|
+
characterCount: text.count,
|
|
146
|
+
delaySeconds: delaySeconds,
|
|
147
|
+
selectsExistingText: false,
|
|
148
|
+
peelsWarmupCharacter: repairMode != .none
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
let synthesizedTypeCarriesTheCommand = !SynthesizedDeliveryBudget.exceeds(synthesizedTypePlan)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
func typeApplicationWide(_ value: String, reason: String) -> (element: XCUIElement?, failure: TextEntryFailure?) {
|
|
161
|
+
NSLog(
|
|
162
|
+
"AGENT_DEVICE_RUNNER_TEXT_ENTRY_ROUTE route=xctest-application-fallback reason=%@ chars=%d commandChars=%d",
|
|
163
|
+
reason,
|
|
164
|
+
value.count,
|
|
165
|
+
text.count
|
|
166
|
+
)
|
|
167
|
+
textEntryRoute = "xctest-application-fallback"
|
|
168
|
+
app.typeText(value)
|
|
169
|
+
return (resolveTextEntryElement(app: app, target: activeTarget), nil)
|
|
170
|
+
}
|
|
171
|
+
|
|
139
172
|
func typeIntoCurrentTarget(_ value: String) -> (element: XCUIElement?, failure: TextEntryFailure?) {
|
|
140
173
|
#if os(iOS)
|
|
141
174
|
if shouldUseSynthesizedFirstResponderType {
|
|
@@ -167,35 +200,14 @@ extension RunnerTests {
|
|
|
167
200
|
|
|
168
201
|
|
|
169
202
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
if SynthesizedDeliveryBudget.exceeds(
|
|
175
|
-
textLength: text.count,
|
|
176
|
-
delaySeconds: delaySeconds,
|
|
177
|
-
typeWarmup: repairMode != .none
|
|
178
|
-
) {
|
|
179
|
-
textEntryRoute = "xctest-application-fallback"
|
|
180
|
-
NSLog(
|
|
181
|
-
"AGENT_DEVICE_RUNNER_TEXT_ENTRY_ROUTE route=xctest-application-fallback "
|
|
182
|
-
+ "reason=delivery-budget chars=%d",
|
|
183
|
-
value.count
|
|
184
|
-
)
|
|
185
|
-
app.typeText(value)
|
|
186
|
-
return (resolveTextEntryElement(app: app, target: activeTarget), nil)
|
|
203
|
+
guard synthesizedTypeCarriesTheCommand else {
|
|
204
|
+
return typeApplicationWide(value, reason: "delivery-budget")
|
|
187
205
|
}
|
|
188
206
|
textEntryRoute = "synthesized-first-responder"
|
|
189
207
|
NSLog("AGENT_DEVICE_RUNNER_TEXT_ENTRY_ROUTE route=synthesized-first-responder")
|
|
190
|
-
|
|
191
|
-
app: app,
|
|
192
|
-
text: value,
|
|
193
|
-
replacingExistingText: false
|
|
194
|
-
)
|
|
195
|
-
switch action {
|
|
208
|
+
switch synthesizer.enterText(app: app, text: value, replacingExistingText: false) {
|
|
196
209
|
case .fallback:
|
|
197
|
-
|
|
198
|
-
app.typeText(value)
|
|
210
|
+
return typeApplicationWide(value, reason: "synthesis-unavailable")
|
|
199
211
|
case .raise(let message):
|
|
200
212
|
NSException(
|
|
201
213
|
name: NSExceptionName.internalInconsistencyException,
|
|
@@ -223,131 +235,100 @@ extension RunnerTests {
|
|
|
223
235
|
)
|
|
224
236
|
}
|
|
225
237
|
|
|
226
|
-
func
|
|
227
|
-
|
|
238
|
+
func readBackWarmupCharacter(_ peeledCharacter: String) {
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
let warmupExpectedText = expectedTextEntryValue(
|
|
243
|
+
typedText: peeledCharacter,
|
|
244
|
+
mode: repairMode,
|
|
245
|
+
initialText: initialText
|
|
246
|
+
)
|
|
247
|
+
guard let warmupExpectedText else {
|
|
228
248
|
sleepFor(TextEntryTiming.pollInterval)
|
|
229
249
|
return
|
|
230
250
|
}
|
|
231
251
|
let deadline = Date().addingTimeInterval(TextEntryTiming.warmupValueTimeout)
|
|
232
252
|
while Date() < deadline {
|
|
233
|
-
if editableTextValue(for: resolveTextEntryElement(app: app, target:
|
|
253
|
+
if editableTextValue(for: resolveTextEntryElement(app: app, target: activeTarget)) == warmupExpectedText {
|
|
234
254
|
return
|
|
235
255
|
}
|
|
236
256
|
sleepFor(TextEntryTiming.pollInterval)
|
|
237
257
|
}
|
|
238
258
|
}
|
|
239
259
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
var typedTarget: XCUIElement?
|
|
263
|
+
var sawWarmupPost = false
|
|
264
|
+
var planFailure: TextEntryResult?
|
|
265
|
+
var stepStartedAt = Date()
|
|
266
|
+
let pacedStartedAt = Date()
|
|
267
|
+
runSynthesizedTextPlan(
|
|
268
|
+
synthesizedTypePlan,
|
|
269
|
+
text: text,
|
|
270
|
+
post: { slice, step in
|
|
271
|
+
stepStartedAt = Date()
|
|
272
|
+
let dispatch = typeIntoCurrentTarget(slice)
|
|
246
273
|
if let failure = dispatch.failure {
|
|
247
|
-
|
|
274
|
+
planFailure = dispatchFailureResult(failure)
|
|
275
|
+
return .stop
|
|
248
276
|
}
|
|
249
277
|
typedTarget = dispatch.element ?? typedTarget
|
|
250
|
-
if
|
|
251
|
-
|
|
278
|
+
if step.warmsUpField {
|
|
279
|
+
|
|
280
|
+
activeTarget = activeTarget.withElement(typedTarget)
|
|
252
281
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
282
|
+
return .posted
|
|
283
|
+
},
|
|
284
|
+
waitAfterWarmupCharacter: { peeledCharacter in
|
|
285
|
+
let warmupStartedAt = Date()
|
|
286
|
+
readBackWarmupCharacter(peeledCharacter)
|
|
287
|
+
logTextEntryPhase(
|
|
288
|
+
commandId: commandId,
|
|
289
|
+
phase: "warmup",
|
|
290
|
+
startedAt: warmupStartedAt,
|
|
291
|
+
chars: 1,
|
|
292
|
+
mode: repairMode
|
|
293
|
+
)
|
|
294
|
+
},
|
|
295
|
+
didPostStep: { step in
|
|
296
|
+
guard !synthesizedTypePlan.pacesEveryCharacter else {
|
|
297
|
+
return
|
|
298
|
+
}
|
|
299
|
+
let phase: String
|
|
300
|
+
if step.warmsUpField {
|
|
301
|
+
phase = "type-first"
|
|
302
|
+
sawWarmupPost = true
|
|
303
|
+
} else {
|
|
304
|
+
phase = sawWarmupPost ? "type-remaining" : "type-all"
|
|
305
|
+
}
|
|
306
|
+
logTextEntryPhase(
|
|
307
|
+
commandId: commandId,
|
|
308
|
+
phase: phase,
|
|
309
|
+
startedAt: stepStartedAt,
|
|
310
|
+
chars: step.characterCount,
|
|
311
|
+
mode: repairMode
|
|
269
312
|
)
|
|
270
313
|
}
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
expectedText: expectedText,
|
|
276
|
-
repairMode: repairMode
|
|
277
|
-
)
|
|
314
|
+
)
|
|
315
|
+
if synthesizedTypePlan.pacesEveryCharacter {
|
|
316
|
+
|
|
317
|
+
|
|
278
318
|
logTextEntryPhase(
|
|
279
319
|
commandId: commandId,
|
|
280
|
-
phase: "
|
|
281
|
-
startedAt:
|
|
282
|
-
chars:
|
|
320
|
+
phase: "type-delayed",
|
|
321
|
+
startedAt: pacedStartedAt,
|
|
322
|
+
chars: text.count,
|
|
283
323
|
mode: repairMode
|
|
284
324
|
)
|
|
285
|
-
logTextEntryPhase(commandId: commandId, phase: "total", startedAt: totalStartedAt, chars: text.count, mode: repairMode)
|
|
286
|
-
result.textEntryRoute = textEntryRoute
|
|
287
|
-
return result
|
|
288
325
|
}
|
|
289
326
|
|
|
290
|
-
|
|
291
|
-
if
|
|
292
|
-
|
|
293
|
-
let firstStartedAt = Date()
|
|
294
|
-
let firstDispatch = typeIntoCurrentTarget(firstCharacter)
|
|
295
|
-
if let failure = firstDispatch.failure {
|
|
296
|
-
return dispatchFailureResult(failure)
|
|
297
|
-
}
|
|
298
|
-
var firstTypedTarget = firstDispatch.element
|
|
299
|
-
logTextEntryPhase(
|
|
300
|
-
commandId: commandId,
|
|
301
|
-
phase: "type-first",
|
|
302
|
-
startedAt: firstStartedAt,
|
|
303
|
-
chars: 1,
|
|
304
|
-
mode: repairMode
|
|
305
|
-
)
|
|
306
|
-
activeTarget = activeTarget.withElement(firstTypedTarget)
|
|
307
|
-
let warmupExpectedText = expectedTextEntryValue(
|
|
308
|
-
typedText: firstCharacter,
|
|
309
|
-
mode: repairMode,
|
|
310
|
-
initialText: initialText
|
|
311
|
-
)
|
|
312
|
-
let warmupStartedAt = Date()
|
|
313
|
-
waitForWarmupValue(warmupExpectedText, target: activeTarget)
|
|
314
|
-
logTextEntryPhase(
|
|
315
|
-
commandId: commandId,
|
|
316
|
-
phase: "warmup",
|
|
317
|
-
startedAt: warmupStartedAt,
|
|
318
|
-
chars: 1,
|
|
319
|
-
mode: repairMode
|
|
320
|
-
)
|
|
321
|
-
let remainingText = String(characters.dropFirst())
|
|
322
|
-
let remainingStartedAt = Date()
|
|
323
|
-
let remainingDispatch = typeIntoCurrentTarget(remainingText)
|
|
324
|
-
if let failure = remainingDispatch.failure {
|
|
325
|
-
return dispatchFailureResult(failure)
|
|
326
|
-
}
|
|
327
|
-
firstTypedTarget = remainingDispatch.element ?? firstTypedTarget
|
|
328
|
-
logTextEntryPhase(
|
|
329
|
-
commandId: commandId,
|
|
330
|
-
phase: "type-remaining",
|
|
331
|
-
startedAt: remainingStartedAt,
|
|
332
|
-
chars: characters.count - 1,
|
|
333
|
-
mode: repairMode
|
|
334
|
-
)
|
|
335
|
-
typedTarget = firstTypedTarget
|
|
336
|
-
} else {
|
|
337
|
-
let typeStartedAt = Date()
|
|
338
|
-
let dispatch = typeIntoCurrentTarget(text)
|
|
339
|
-
if let failure = dispatch.failure {
|
|
340
|
-
return dispatchFailureResult(failure)
|
|
341
|
-
}
|
|
342
|
-
typedTarget = dispatch.element
|
|
343
|
-
logTextEntryPhase(
|
|
344
|
-
commandId: commandId,
|
|
345
|
-
phase: "type-all",
|
|
346
|
-
startedAt: typeStartedAt,
|
|
347
|
-
chars: characters.count,
|
|
348
|
-
mode: repairMode
|
|
349
|
-
)
|
|
327
|
+
|
|
328
|
+
if let failure = planFailure {
|
|
329
|
+
return failure
|
|
350
330
|
}
|
|
331
|
+
activeTarget = activeTarget.withElement(typedTarget)
|
|
351
332
|
if repairMode == .none {
|
|
352
333
|
logTextEntryPhase(commandId: commandId, phase: "total", startedAt: totalStartedAt, chars: text.count, mode: repairMode)
|
|
353
334
|
return TextEntryResult(
|
|
@@ -361,7 +342,7 @@ extension RunnerTests {
|
|
|
361
342
|
let verifyStartedAt = Date()
|
|
362
343
|
var result = verifyTextEntryWithRepairIfNeeded(
|
|
363
344
|
app: app,
|
|
364
|
-
target: activeTarget
|
|
345
|
+
target: activeTarget,
|
|
365
346
|
expectedText: expectedText,
|
|
366
347
|
repairMode: repairMode
|
|
367
348
|
)
|
|
@@ -369,7 +350,7 @@ extension RunnerTests {
|
|
|
369
350
|
commandId: commandId,
|
|
370
351
|
phase: "verify",
|
|
371
352
|
startedAt: verifyStartedAt,
|
|
372
|
-
chars:
|
|
353
|
+
chars: text.count,
|
|
373
354
|
mode: repairMode
|
|
374
355
|
)
|
|
375
356
|
logTextEntryPhase(commandId: commandId, phase: "total", startedAt: totalStartedAt, chars: text.count, mode: repairMode)
|
package/dist/src/adapter.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{A 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{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};
|
package/dist/src/adb-executor.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{M 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{M 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{M 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{A 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{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 +1 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime.js";import{
|
|
1
|
+
import{r as e}from"./rolldown-runtime.js";import{M as t,N as n}from"./sdk-contracts.js";import{c as r,d as i,f as a,l as o,s,u as c,x 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:r(),timeoutMs:e.timeoutMs})}function O(e){p(T.join(e.installDir,`manifest.json`),JSON.stringify({package:e.packageName,version:e.version,node:c(),installedAt:new Date().toISOString()},null,2))}function ee(e){if(i()!==`win32`)return{command:`npm`,args:e};let n=k(r());if(!n)throw new t(`TOOL_MISSING`,`npm not found in PATH`,{nodeExecPath:o(),hint:"Install Node.js with npm, or add npm to PATH, and run `agent-device web setup` again."});return{command:o(),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(o()),`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=a();return await d({acquire:()=>f({lockDirPath:T.join(t.installDir,`..`,`.agent-browser-install.lock`),owner:{pid:n,startTime:l(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??r().AGENT_DEVICE_STATE_DIR??ne(),n=T.join(t,`tools`,`agent-browser`,M),i=K(n),a=q(n),o=W(i),s=T.join(n,`home`),l=Z(n),u=Q(n),d=o!==void 0&&U(n),f=Number.parseInt(c().replace(/^v/,``).split(`.`)[0]??`0`,10);return{version:M,stateDir:t,installDir:n,packageDir:i,binaryPath:a,entryScript:o,homeDir:s,runtimeHomeDir:l,socketDir:u,installed:d,nodeMajor:f,nodeSupported:f>=24}}async function B(e,t,n){if(!e.entryScript)throw J(e);return await u(o(),[e.entryScript,...t],{allowFailure:n.allowFailure,env:V(e,r()),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=i()===`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 ${c()}.`:"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:c(),requiredNodeMajor:24,hint:`Run agent-device with Node 24+ for web setup and web automation.`})}function Z(e){if(i()===`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(r().HOME??s(),`.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};
|