agent-device 0.21.0 → 0.21.1

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.
Files changed (282) hide show
  1. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.0.apk → agent-device-android-ime-helper-0.21.1.apk} +0 -0
  2. package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.1.apk.sha256 +1 -0
  3. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.0.manifest.json → agent-device-android-ime-helper-0.21.1.manifest.json} +4 -4
  4. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.0.apk → agent-device-android-snapshot-helper-0.21.1.apk} +0 -0
  5. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.1.apk.sha256 +1 -0
  6. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.0.manifest.json → agent-device-android-snapshot-helper-0.21.1.manifest.json} +6 -6
  7. package/apple/snapshot-bridge/README.md +58 -1
  8. package/apple/snapshot-bridge/SnapshotBridge.m +6 -0
  9. package/apple/snapshot-bridge/SnapshotBridgeCapture.h +25 -0
  10. package/apple/snapshot-bridge/SnapshotBridgeCapture.m +138 -0
  11. package/apple/snapshot-bridge/SnapshotBridgeRuntime.h +1 -0
  12. package/apple/snapshot-bridge/SnapshotBridgeRuntime.m +32 -3
  13. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.h +12 -0
  14. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.m +20 -0
  15. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSelectorMatchPolicy.swift +15 -15
  16. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSystemSurfaceHostPolicy.swift +72 -0
  17. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTapPointPolicy.swift +63 -14
  18. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +668 -82
  19. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +14 -4
  20. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+BlockingSystemModalResolution.swift +39 -4
  21. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +1065 -223
  22. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +290 -0
  23. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Environment.swift +1 -1
  24. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Exceptions.swift +10 -10
  25. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +249 -61
  26. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Keyboard.swift +101 -42
  27. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +13 -13
  28. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +51 -43
  29. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Navigation.swift +71 -4
  30. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+PrivateAXPresentation.swift +144 -7
  31. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScreenRecorder.swift +13 -1
  32. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +216 -17
  33. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SequenceExecution.swift +206 -22
  34. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +289 -42
  35. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotBackendCapabilities.swift +92 -22
  36. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +617 -122
  37. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotTiming.swift +79 -4
  38. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedCommitDeadline.swift +71 -71
  39. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedGesturePolicy.swift +83 -5
  40. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedTextEntry.swift +67 -67
  41. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SystemModal.swift +4 -4
  42. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +17 -17
  43. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryFocus.swift +30 -30
  44. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryReadiness.swift +31 -31
  45. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextInputCandidatePolicy.swift +28 -0
  46. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextInputProbe.swift +101 -0
  47. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextTyping.swift +19 -19
  48. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Transport.swift +55 -17
  49. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TvRemote.swift +26 -5
  50. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +125 -75
  51. package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/RecordingExportSupport.swift +9 -9
  52. package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/recording-overlay.swift +9 -9
  53. package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/recording-trim.swift +4 -4
  54. package/dist/src/adapter.js +1 -1
  55. package/dist/src/adb-executor.js +1 -1
  56. package/dist/src/adb-failure.js +1 -1
  57. package/dist/src/agent-browser-process-record.js +1 -1
  58. package/dist/src/agent-browser-provider.js +1 -1
  59. package/dist/src/agent-browser-tool.js +1 -1
  60. package/dist/src/agent-device-client.js +2 -2
  61. package/dist/src/ai-sdk.d.ts +1 -1
  62. package/dist/src/ai-sdk.js +1 -1
  63. package/dist/src/alert-runtime.js +1 -1
  64. package/dist/src/android-input-ownership.js +1 -1
  65. package/dist/src/app-catalog.js +1 -1
  66. package/dist/src/app-deployment-resolution.js +1 -1
  67. package/dist/src/app-inventory-contract.js +1 -1
  68. package/dist/src/app-inventory.js +1 -1
  69. package/dist/src/app-launch.js +2 -2
  70. package/dist/src/app-lifecycle.js +3 -3
  71. package/dist/src/app-lifecycle2.js +1 -1
  72. package/dist/src/app-log-files.js +1 -1
  73. package/dist/src/app-log-runtime2.js +3 -3
  74. package/dist/src/app-resolution.js +1 -1
  75. package/dist/src/apple-runner-platform.js +1 -0
  76. package/dist/src/application-lifecycle-interaction.js +1 -1
  77. package/dist/src/archive.js +1 -1
  78. package/dist/src/artifact-download.js +1 -1
  79. package/dist/src/auth-session.js +1 -1
  80. package/dist/src/auth.js +1 -1
  81. package/dist/src/backend-snapshot-options.js +1 -1
  82. package/dist/src/boot-diagnostics.js +1 -1
  83. package/dist/src/capture.js +1 -1
  84. package/dist/src/cli-config.js +1 -1
  85. package/dist/src/cli-help.js +25 -21
  86. package/dist/src/cli-runner.js +1 -1
  87. package/dist/src/cli.js +4 -4
  88. package/dist/src/click-button.js +1 -1
  89. package/dist/src/client-metro-companion.js +1 -1
  90. package/dist/src/client-metro.js +1 -1
  91. package/dist/src/client-types.d.ts +27 -13
  92. package/dist/src/code-signature-cache.js +1 -1
  93. package/dist/src/code-signature.js +1 -1
  94. package/dist/src/command-schema.js +3 -3
  95. package/dist/src/command-tools.js +2 -2
  96. package/dist/src/command.js +1 -1
  97. package/dist/src/connection-runtime.js +1 -1
  98. package/dist/src/connection.js +3 -3
  99. package/dist/src/contracts.d.ts +1 -1
  100. package/dist/src/contracts.js +1 -1
  101. package/dist/src/daemon-client-lifecycle.js +1 -1
  102. package/dist/src/daemon.js +1 -1
  103. package/dist/src/debug-symbols-facade.js +1 -1
  104. package/dist/src/device-claim-rule.js +1 -1
  105. package/dist/src/device-inventory-context.js +1 -1
  106. package/dist/src/device-rotation.js +1 -1
  107. package/dist/src/device-selection-resolver.js +1 -1
  108. package/dist/src/device-session.js +1 -1
  109. package/dist/src/device2.js +1 -1
  110. package/dist/src/diagnostics.js +1 -1
  111. package/dist/src/dispatch-resolve.js +1 -1
  112. package/dist/src/doctor2.js +1 -1
  113. package/dist/src/error.js +1 -1
  114. package/dist/src/exec.js +1 -1
  115. package/dist/src/file.js +1 -1
  116. package/dist/src/find.js +1 -1
  117. package/dist/src/generic-settle.js +1 -1
  118. package/dist/src/gesture-plan.js +1 -1
  119. package/dist/src/gesture-runtime.js +1 -1
  120. package/dist/src/harmonyos.js +1 -1
  121. package/dist/src/hdc.js +1 -1
  122. package/dist/src/helper.js +2 -2
  123. package/dist/src/human-control-contract.js +1 -1
  124. package/dist/src/human-control.js +1 -1
  125. package/dist/src/index.d.ts +1 -1
  126. package/dist/src/index.js +1 -1
  127. package/dist/src/input-actions.js +1 -1
  128. package/dist/src/input-actions2.js +2 -2
  129. package/dist/src/install-artifact-facade.js +1 -1
  130. package/dist/src/install-source-network-transport.js +1 -1
  131. package/dist/src/install-source2.js +1 -1
  132. package/dist/src/interaction-positionals.js +1 -1
  133. package/dist/src/interaction-ref-policy.js +1 -1
  134. package/dist/src/interaction2.js +1 -1
  135. package/dist/src/interactor.js +5 -5
  136. package/dist/src/interactor2.js +1 -1
  137. package/dist/src/interactors.js +1 -1
  138. package/dist/src/internal/bin.js +1 -1
  139. package/dist/src/internal/daemon.js +2 -2
  140. package/dist/src/internal/png-worker.js +1 -1
  141. package/dist/src/internal/run-script-http-child.js +1 -1
  142. package/dist/src/inventory.js +2 -2
  143. package/dist/src/inventory2.js +1 -1
  144. package/dist/src/inventory3.js +1 -1
  145. package/dist/src/inventory5.js +1 -1
  146. package/dist/src/ios-snapshot-runtime.js +1 -1
  147. package/dist/src/ios-system-surface.js +1 -0
  148. package/dist/src/lease-scope.js +1 -1
  149. package/dist/src/lease.js +1 -1
  150. package/dist/src/limrun-runtime-dependencies.js +1 -1
  151. package/dist/src/limrun.d.ts +1 -1
  152. package/dist/src/linux.js +1 -1
  153. package/dist/src/location-coordinates.js +1 -1
  154. package/dist/src/managed-device-scope.js +1 -1
  155. package/dist/src/mechanics.js +16 -16
  156. package/dist/src/multitouch-support.js +1 -1
  157. package/dist/src/observation.js +1 -1
  158. package/dist/src/open-target-resolution.js +1 -0
  159. package/dist/src/owner-identity.js +3 -3
  160. package/dist/src/parameterized-recorded-fill.js +1 -1
  161. package/dist/src/perf-facade.js +2 -2
  162. package/dist/src/perf-process-identity.js +1 -0
  163. package/dist/src/perf-runtime-operation-builder.js +1 -1
  164. package/dist/src/perf-runtime-plan.js +1 -1
  165. package/dist/src/perf.js +1 -1
  166. package/dist/src/physical-device-control.js +1 -1
  167. package/dist/src/platform-runtime-android-adb-host.js +1 -1
  168. package/dist/src/platform-runtime-app-log-process.js +1 -1
  169. package/dist/src/platform-runtime-host.js +1 -1
  170. package/dist/src/platform-runtime-managed-owner.js +1 -1
  171. package/dist/src/platform-runtime-open-target.js +1 -1
  172. package/dist/src/platform-runtime-operation-host.js +2 -2
  173. package/dist/src/platform-runtime-runtime-hints.js +2 -2
  174. package/dist/src/platform-runtime-screen-recording-android-host.js +1 -1
  175. package/dist/src/platform-runtime-screen-recording-apple-simulator-host.js +1 -1
  176. package/dist/src/platform-runtime-screen-recording-finalizer-host.js +1 -1
  177. package/dist/src/platform-runtime-unavailable.js +1 -1
  178. package/dist/src/platform-runtime.js +1 -1
  179. package/dist/src/platform-runtime2.js +1 -1
  180. package/dist/src/png-worker-contract.js +1 -1
  181. package/dist/src/prepare-kind.js +1 -1
  182. package/dist/src/provider-device-runtime.js +1 -1
  183. package/dist/src/provider-session-ownership.js +1 -1
  184. package/dist/src/provider-webdriver.js +1 -1
  185. package/dist/src/proxy.js +1 -1
  186. package/dist/src/react-native.js +1 -1
  187. package/dist/src/record-runtime.js +1 -1
  188. package/dist/src/rect-center.js +1 -1
  189. package/dist/src/register-builtins.js +1 -1
  190. package/dist/src/registry.js +37 -36
  191. package/dist/src/remote-config2.js +1 -1
  192. package/dist/src/replay-divergence.js +1 -1
  193. package/dist/src/replay.js +2 -2
  194. package/dist/src/reporting.js +9 -8
  195. package/dist/src/request-admission.js +1 -1
  196. package/dist/src/request-cancel.js +1 -1
  197. package/dist/src/request-runtime-binding.js +1 -1
  198. package/dist/src/retry.js +1 -1
  199. package/dist/src/runner-cache-metadata.js +2 -2
  200. package/dist/src/runner-client.js +1 -1
  201. package/dist/src/runner-disposal.js +1 -1
  202. package/dist/src/runner-operations-facade.js +1 -1
  203. package/dist/src/runner.js +1 -1
  204. package/dist/src/runtime-transport-hints.js +1 -1
  205. package/dist/src/runtime.js +3 -3
  206. package/dist/src/runtime2.js +4 -4
  207. package/dist/src/runtime3.js +1 -1
  208. package/dist/src/runtime4.js +5 -4
  209. package/dist/src/runtime5.js +1 -1
  210. package/dist/src/runtime6.js +1 -1
  211. package/dist/src/runtime7.js +1 -1
  212. package/dist/src/runtime8.js +1 -1
  213. package/dist/src/runtime9.js +1 -1
  214. package/dist/src/screen-recording-live-handle.js +1 -1
  215. package/dist/src/screen-recording-options.js +1 -1
  216. package/dist/src/screen-recording-resource-recovery.js +1 -1
  217. package/dist/src/screenshot-density.js +1 -1
  218. package/dist/src/screenshot-runtime.js +1 -1
  219. package/dist/src/screenshot.js +1 -1
  220. package/dist/src/screenshot3.js +3 -3
  221. package/dist/src/script.js +1 -1
  222. package/dist/src/scroll-command.js +1 -1
  223. package/dist/src/scroll-gesture.js +1 -1
  224. package/dist/src/sdk-batch-runner.js +2 -2
  225. package/dist/src/sdk-batch.js +2 -2
  226. package/dist/src/sdk-contracts.d.ts +44 -1
  227. package/dist/src/sdk-contracts.js +2 -2
  228. package/dist/src/sdk-device.js +1 -1
  229. package/dist/src/sdk-finders.d.ts +1 -1
  230. package/dist/src/sdk-io.js +1 -1
  231. package/dist/src/sdk-remote-config.d.ts +1 -1
  232. package/dist/src/sdk-remote-config.js +1 -1
  233. package/dist/src/sdk-selectors.d.ts +69 -13
  234. package/dist/src/selector-runtime.js +1 -1
  235. package/dist/src/server.js +3 -3
  236. package/dist/src/session-allocation.js +1 -1
  237. package/dist/src/session-observation.js +1 -0
  238. package/dist/src/session-routing.js +1 -1
  239. package/dist/src/session-runtime-admission.js +1 -1
  240. package/dist/src/session-snapshot.js +1 -1
  241. package/dist/src/session-store.js +3 -3
  242. package/dist/src/session-target-evidence.js +1 -1
  243. package/dist/src/session2.js +5 -5
  244. package/dist/src/settings.js +1 -1
  245. package/dist/src/simulator.js +1 -1
  246. package/dist/src/snapshot-quality-backend-capabilities.js +1 -1
  247. package/dist/src/snapshot-quality-verdict.js +1 -1
  248. package/dist/src/snapshot-runtime-binding.js +1 -1
  249. package/dist/src/snapshot-runtime.js +1 -1
  250. package/dist/src/snapshot-state.js +1 -1
  251. package/dist/src/snapshot2.js +1 -1
  252. package/dist/src/snapshot3.js +1 -1
  253. package/dist/src/snapshot4.js +1 -1
  254. package/dist/src/src.js +1 -1
  255. package/dist/src/src7.js +2 -2
  256. package/dist/src/src8.js +2 -2
  257. package/dist/src/string-enum.js +1 -1
  258. package/dist/src/takeover.js +1 -1
  259. package/dist/src/tool-provider.js +2 -2
  260. package/dist/src/tool-provider2.js +1 -1
  261. package/dist/src/tool-provider3.js +1 -1
  262. package/dist/src/toolchain-probe.js +1 -1
  263. package/dist/src/touch-reference-frame.js +1 -0
  264. package/dist/src/touch-runtime.js +1 -1
  265. package/dist/src/transport.js +1 -1
  266. package/dist/src/tv-remote.js +1 -1
  267. package/dist/src/type-text-runtime.js +1 -1
  268. package/dist/src/update-check.js +1 -1
  269. package/dist/src/verified-file.js +1 -1
  270. package/dist/src/video.js +1 -1
  271. package/dist/src/web.js +1 -1
  272. package/dist/src/web2.js +1 -1
  273. package/dist/src/webdriver-source.js +1 -1
  274. package/dist/src/window-state.js +1 -0
  275. package/package.json +3 -2
  276. package/server.json +2 -2
  277. package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.0.apk.sha256 +0 -1
  278. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.0.apk.sha256 +0 -1
  279. package/dist/src/back-mode.js +0 -1
  280. package/dist/src/format.js +0 -2
  281. package/dist/src/platform-runtime-apple-resources.js +0 -1
  282. package/dist/src/runner-selector-query.js +0 -1
@@ -1,9 +1,9 @@
1
- //
2
- // RunnerTests.swift
3
- // AgentDeviceRunnerUITests
4
- //
5
- // Created by Michał Pierzchała on 30/01/2026.
6
- //
1
+
2
+
3
+
4
+
5
+
6
+
7
7
 
8
8
  import XCTest
9
9
  import Network
@@ -29,8 +29,8 @@ final class RunnerTests: XCTestCase {
29
29
  }
30
30
 
31
31
  static let springboardBundleId = "com.apple.springboard"
32
- // SpringBoard hosts blocking system modals on iOS/visionOS; tvOS (PineBoard/HeadBoard)
33
- // and macOS have no such host, so there is nothing to probe there.
32
+
33
+
34
34
  static let hasSpringBoardSystemModalHost: Bool = {
35
35
  #if os(tvOS) || os(macOS)
36
36
  return false
@@ -48,10 +48,10 @@ final class RunnerTests: XCTestCase {
48
48
  var currentApp: XCUIApplication?
49
49
  var currentBundleId: String?
50
50
  var currentAppProcessIdentifier: Int?
51
- // iOS does not reliably expose hasKeyboardFocus for a bare type request, especially when
52
- // hardware-keyboard input hides the software keyboard. A successful tap on a concrete text
53
- // input is a scoped witness for the immediately-following bare type; lifecycle and non-text
54
- // interactions clear it before it can become stale.
51
+
52
+
53
+
54
+
55
55
  var textEntryTapWitness: TextEntryTapWitness?
56
56
  let maxRequestBytes = 2 * 1024 * 1024
57
57
  let mainThreadExecutionTimeout: TimeInterval = 30
@@ -61,84 +61,133 @@ final class RunnerTests: XCTestCase {
61
61
  let firstInteractionAfterActivateDelay: TimeInterval = 0.25
62
62
  let scrollInteractionIdleTimeoutDefault: TimeInterval = 1.0
63
63
  let tvRemoteDoublePressDelayDefault: TimeInterval = 0.0
64
- // Keep a periodic XCTest liveness marker in runner.log without flooding long-lived sessions.
64
+
65
65
  let xctestIdleKeepaliveInterval: TimeInterval = 60.0
66
66
  let minRecordingFps = 1
67
67
  let maxRecordingFps = 120
68
68
  var needsPostSnapshotInteractionDelay = false
69
- /// When the first interaction after an activation may run, on the monotonic uptime clock.
70
- /// The guarantee is a minimum gap *since the activation*, not a pause at the interaction:
71
- /// a caller that already spent that gap elsewhere (an agent's round trip is 190-260 ms)
72
- /// has satisfied it and waits for nothing. `nil` = no activation is pending stabilization.
69
+
70
+
71
+
72
+
73
73
  var firstInteractionReadyUptime: TimeInterval?
74
74
  var runnerAccessibilityHealth: RunnerAccessibilityHealth = .unknown
75
75
  var activeRecording: ScreenRecorder?
76
76
  let commandJournal = RunnerCommandJournal()
77
- // Coalesces duplicate transport sends of the same commandId onto the single in-flight
78
- // execution instead of enqueueing them again behind it (#1105 capture pileup).
77
+
78
+
79
79
  let inFlightCommandLock = NSLock()
80
80
  var inFlightCommandIds: Set<String> = []
81
81
  var inFlightCommandWaiters: [String: [((data: Data, shouldFinish: Bool)) -> Void]] = [:]
82
- // Tracks main-queue work abandoned by the execution watchdog so new main-thread commands
83
- // fail fast as busy instead of queueing behind work that cannot be cancelled (#1105).
82
+
83
+
84
84
  let mainThreadWorkLock = NSLock()
85
85
  var abandonedMainThreadWorkCount = 0
86
86
  var abandonedMainThreadWorkSince: Date?
87
- // Past this age the runner stops claiming "busy, retry soon" and reports itself wedged so
88
- // the daemon recycles it — the only cure once the main thread is stuck for good.
87
+
88
+
89
89
  let mainThreadWedgeThreshold: TimeInterval = 120
90
- // Sticky per-bundle hint: after an XCTest-backed snapshot tier ground past its slice (or a
91
- // snapshot was abandoned by the watchdog), later capture plans avoid the XCTest accessibility
92
- // channel when an independent recovery backend exists, or use a bounded XCTest probe when it
93
- // does not, for the same screen class (#1105/#1156).
90
+
91
+
92
+
93
+
94
94
  let snapshotXCTestChannelPenaltyLock = NSLock()
95
95
  var snapshotXCTestChannelPenaltyBundleId: String?
96
96
  var snapshotXCTestChannelPenaltyUntil = Date.distantPast
97
97
  let snapshotXCTestChannelPenaltyDuration: TimeInterval = 120
98
98
  var snapshotXCTestPenaltyWarmupExemptionPending = false
99
- // Sticky per-bundle hint for the private AX depth ladder: deep RN screens reject the default
100
- // depth with kAXErrorIllegalArgument on EVERY capture, so once a shallower rung is accepted
101
- // later captures start there instead of re-paying the rejected deep request (~300ms per
102
- // capture on the Bluesky feed). Shares the penalty's lifetime model: same duration, cleared
103
- // on target process change, so screens that regain deep-capture ability are re-probed.
99
+
100
+
101
+
102
+
103
+
104
104
  let privateAXAcceptedDepthLock = NSLock()
105
105
  var privateAXAcceptedDepthBundleId: String?
106
- // PID-bound: a relaunch (external or A->B->A while inactive) changes the process, and the new
107
- // tree may accept the full depth again. Any invalidation path that drops the cached PID makes
108
- // the memory unmatchable, so every fresh activation re-probes the full requested depth.
106
+
107
+
108
+
109
109
  var privateAXAcceptedDepthProcessIdentifier: Int?
110
110
  var privateAXAcceptedDepth: Int?
111
111
  var privateAXAcceptedDepthUntil = Date.distantPast
112
- // Bluesky-class screens can grind ~4-8s before an XCTest-backed snapshot tier fails; anything
113
- // past this threshold marks the screen hostile so the next capture uses non-XCTest recovery.
112
+
113
+
114
114
  let snapshotXCTestSlowCaptureThreshold: TimeInterval = 3
115
- // The blocking XCTest tree snapshot XPC runs on the main thread with this slice so a
116
- // content-dependent grind (#1105: seconds to minutes on live Bluesky screens) cannot pin
117
- // the capture plan. On timeout the XPC keeps grinding on main; while any abandoned
118
- // tree capture is outstanding, plans skip XCTest-backed tiers (tree, query sweep) until the
119
- // abandoned work drains.
115
+
116
+
117
+
118
+
119
+
120
120
  let treeCaptureLock = NSLock()
121
121
  var abandonedTreeCaptureCount = 0
122
122
  let treeCaptureSliceBudget: TimeInterval = 8
123
- // Bounds the pre-plan SpringBoard system-modal probe, which can otherwise grind for tens of
124
- // seconds on remote-hosted consent dialogs and bypass the plan budget (#1244).
123
+
124
+
125
125
  let systemModalProbeBudget: TimeInterval = 4
126
- // In-bundle unit tests (every `func test…` except `testCommand` below) compile only under
127
- // `-D AGENT_DEVICE_RUNNER_UNIT_TESTS` and are classified by their `#if` guard (#1781 A7):
128
- // - `#if AGENT_DEVICE_RUNNER_UNIT_TESTS` alone: a pure runner decision (rule table,
129
- // geometry, parser, policy, journal, dispatch bookkeeping) that needs no launched app.
130
- // Runs on the macOS host lane on every PR (ci.yml, no simulator) and on the iOS lanes.
131
- // - `… && os(iOS)` (or a nested `#if os(iOS)`): runner/XCTest semantics — launches the
132
- // host app, routes through SpringBoard, swizzles XCUIApplication, or asserts an
133
- // iOS-only branch. Simulator lanes only (ios.yml PR list, xctest-nightly.yml).
134
- // `pnpm check:xctest-selection` derives each lane's reachable set from these guards and
135
- // fails when a declared test is reachable by no lane, so a test gated to a platform nothing
136
- // runs (the old tvOS-only pair) cannot go dark silently.
137
- // Observability for the record(_:) suppression below: how many AX-broken-screen snapshot
138
- // issues this session muted, so wedge investigations see the volume without grepping logs.
126
+
127
+
128
+
129
+
130
+
131
+
132
+
133
+
134
+
135
+
136
+
137
+
138
+
139
+
140
+
141
+
142
+
143
+
144
+
145
+
146
+
147
+
148
+
149
+
150
+
151
+
152
+
153
+
154
+
155
+
156
+
157
+
158
+
159
+
160
+
161
+
162
+
163
+
164
+
165
+
166
+
167
+
168
+
169
+
170
+
171
+
172
+
173
+
174
+
175
+
176
+
177
+
178
+
179
+
180
+
181
+
182
+
183
+
184
+
185
+
186
+
187
+ var textInputProbeIssues: TextInputProbeIssues?
139
188
  let suppressedIssueLock = NSLock()
140
189
  var suppressedAxSnapshotIssueCount = 0
141
- // Keep blocker actions narrow to avoid false positives from generic hittable containers.
190
+
142
191
  let actionableTypes: Set<XCUIElement.ElementType> = [
143
192
  .button,
144
193
  .cell,
@@ -148,33 +197,34 @@ final class RunnerTests: XCTestCase {
148
197
  .switch
149
198
  ]
150
199
 
151
- // MARK: - XCTest Entry
200
+
152
201
 
153
202
  override func setUp() {
154
203
  continueAfterFailure = true
155
204
  }
156
205
 
157
- /// True for the one recorded-issue class the runner deliberately mutes: an AX-server error
158
- /// (`kAXError*`) inside a "Failed to get matching snapshot" fetch. The kAXError token
159
- /// intentionally covers kAXErrorIllegalArgument and its sibling AX server codes (e.g.
160
- /// kAXErrorCannotComplete): any AX-server rejection inside a matching-snapshot fetch is the
161
- /// same capture-plan noise the plan already classifies and recovers from. The timeout
162
- /// variant ("Failed to get matching snapshot: Timed out while evaluating UI query.") carries
163
- /// no kAXError token and MUST keep recording — it signals a genuinely hung query, exactly
164
- /// the pathology XCTEST_RECORDED_FAILURE must stay able to see.
206
+
207
+
208
+
209
+
210
+
211
+
212
+
213
+
165
214
  static func isSuppressedAxSnapshotIssueDescription(_ description: String) -> Bool {
166
215
  description.contains("Failed to get matching snapshot") && description.contains("kAXError")
167
216
  }
168
217
 
169
- /// On AX-broken screens (deep RN trees, #758/#1105) XCUIApplication queries record
170
- /// "Failed to get matching snapshot: ... kAXError..." issues; XCTest tears the whole test
171
- /// case down once a few accumulate, killing the long-lived runner right after the command
172
- /// completes and forcing a ~25s restart per capture. This override is deliberately
173
- /// suite-global (all commands, not just snapshot capture): tap-triggered element queries on
174
- /// the same screens record the same noise and would still tear the runner down, and command
175
- /// outcomes stay honest through their own error paths — only this issue side-channel is
176
- /// muted. Everything else still records (and still drives XCTEST_RECORDED_FAILURE).
218
+
219
+
220
+
221
+
222
+
223
+
224
+
225
+
177
226
  override func record(_ issue: XCTIssue) {
227
+ if containTextInputProbeIssue(issue) { return }
178
228
  let description = issue.compactDescription
179
229
  if Self.isSuppressedAxSnapshotIssueDescription(description) {
180
230
  suppressedIssueLock.lock()
@@ -1,9 +1,9 @@
1
1
  import AVFoundation
2
2
  import Foundation
3
3
 
4
- /// Shared mechanics for the recording post-processing scripts (overlay burn-in, start trim).
5
- /// Each script keeps its own argument grammar and export-quality policy; this file owns the
6
- /// error vocabulary, flag-value reading, composition assembly, and the bounded export wait.
4
+
5
+
6
+
7
7
 
8
8
  enum RecordingScriptError: Error, CustomStringConvertible {
9
9
  case invalidArgs(String)
@@ -45,10 +45,10 @@ func sourceVideoTrack(of asset: AVURLAsset) throws -> AVAssetTrack {
45
45
  return track
46
46
  }
47
47
 
48
- /// Copies `videoTrack` for `timeRange` into a fresh composition, carrying the optional audio track
49
- /// along when present. The caller owns any `preferredTransform` policy: trim propagates the source
50
- /// transform directly, while overlay re-applies it through a video-composition layer instruction
51
- /// instead.
48
+
49
+
50
+
51
+
52
52
  func makeRecordingComposition(
53
53
  asset: AVURLAsset,
54
54
  videoTrack: AVAssetTrack,
@@ -89,8 +89,8 @@ func makeRecordingExporter(
89
89
  return exporter
90
90
  }
91
91
 
92
- /// Bounded asynchronous export: signals completion through a semaphore and cancels after 120s so a
93
- /// wedged encoder cannot hang the recording pipeline past the caller's own timeout budget.
92
+
93
+
94
94
  func runRecordingExport(
95
95
  _ exporter: AVAssetExportSession,
96
96
  timeoutMessage: String,
@@ -35,8 +35,8 @@ enum ExportQuality: String {
35
35
  case high
36
36
  }
37
37
 
38
- /// Entry point: `@main` because multi-file swiftc compilation reserves top-level statements for
39
- /// `main.swift`, which cannot be shared per-script.
38
+
39
+
40
40
  @main
41
41
  enum RecordingOverlay {
42
42
  static func main() {
@@ -126,9 +126,9 @@ func run() throws {
126
126
  in: parentLayer
127
127
  )
128
128
 
129
- // Overlay burn-in forces a full re-encode; medium quality keeps simulator videos readable
130
- // while avoiding very slow highest-quality exports. Pass --quality high to opt into
131
- // the slower highest-quality export.
129
+
130
+
131
+
132
132
  let presetName = exportPresetName(for: parsedArgs.exportQuality, compatibleWith: composition)
133
133
  let exporter = try makeRecordingExporter(
134
134
  composition,
@@ -149,8 +149,8 @@ func parseArguments(
149
149
  var inputPath: String?
150
150
  var outputPath: String?
151
151
  var eventsPath: String?
152
- // Export quality defaults to medium so existing callers keep the fast, simulator-friendly
153
- // export. Pass --quality high to opt into a slower highest-quality export.
152
+
153
+
154
154
  var exportQuality: ExportQuality = .medium
155
155
  var index = 0
156
156
 
@@ -195,8 +195,8 @@ func exportPresetName(
195
195
  case .high:
196
196
  return AVAssetExportPresetHighestQuality
197
197
  case .medium:
198
- // Prefer the faster medium preset, falling back to highest quality only when medium is
199
- // not available for this composition.
198
+
199
+
200
200
  let compatible = AVAssetExportSession.exportPresets(compatibleWith: asset)
201
201
  return compatible.contains(AVAssetExportPresetMediumQuality)
202
202
  ? AVAssetExportPresetMediumQuality
@@ -1,8 +1,8 @@
1
1
  import AVFoundation
2
2
  import Foundation
3
3
 
4
- /// Entry point: `@main` because multi-file swiftc compilation reserves top-level statements for
5
- /// `main.swift`, which cannot be shared per-script.
4
+
5
+
6
6
  @main
7
7
  enum RecordingTrim {
8
8
  static func main() {
@@ -42,8 +42,8 @@ func run() throws {
42
42
  )
43
43
  composition.tracks(withMediaType: .video).first?.preferredTransform = videoTrack.preferredTransform
44
44
 
45
- // Passthrough keeps the trim lossless when the composition supports it; otherwise re-encode at
46
- // highest quality.
45
+
46
+
47
47
  let presetName = AVAssetExportSession.exportPresets(compatibleWith: composition)
48
48
  .contains(AVAssetExportPresetPassthrough)
49
49
  ? AVAssetExportPresetPassthrough
@@ -1 +1 @@
1
- import{E as e,y as t}from"./sdk-contracts.js";import{Rr as n}from"./sdk-batch.js";import{c as r,r as i}from"./diagnostics.js";import{S as a,b as o,f as s}from"./owner-identity.js";import{c,s as l}from"./exec.js";import{t as u}from"./file.js";import"./diagnostics2.js";import"./command.js";import{n as d}from"./retry.js";import{n as f}from"./version.js";import"./process.js";import{C as p,D as m,c as ee,f as te,h as ne,n as h,o as g,w as _,y as re}from"./host-file.js";import{t as ie}from"./snapshot-process.js";import v from"node:path";import{createHash as y,randomUUID as b}from"node:crypto";import ae from"node:net";import{Buffer as x}from"node:buffer";const S={unsupported:`UNSUPPORTED_OPERATION`,"malformed-tree":`COMMAND_FAILED`,"stale-target":`COMMAND_FAILED`,timeout:`COMMAND_FAILED`,cancelled:`COMMAND_FAILED`,"process-crash":`COMMAND_FAILED`,"transport-failure":`COMMAND_FAILED`};var C=class extends t{failureKind;failureCode;constructor(e,t,n=`iOS Simulator snapshot source ${e}: ${t}`,r={},i){super(S[e],n,{...r,bridgeFailure:e,bridgeFailureCode:t,...e===`cancelled`?{reason:`request_canceled`}:{}},i),this.name=`SnapshotSourceError`,this.failureKind=e,this.failureCode=t}};function w(e,t,n={},r){return new C(e,t,void 0,n,r)}function T(n){return n instanceof C?n:e(n)?w(`cancelled`,`abort-signal`,{},n):n instanceof t&&typeof n.details?.timeoutMs==`number`?w(`timeout`,`host-operation-timeout`,{timeoutMs:n.details.timeoutMs},n):w(`transport-failure`,`unexpected-host-error`,{error:n instanceof Error?n.message:String(n)},n)}function oe(e,t){if(t?.aborted)throw w(`cancelled`,`abort-signal`);return{clock:d.fromTimeoutMs(e),signal:t}}function E(e,t){if(e.signal?.aborted)throw w(`cancelled`,`abort-signal`);let n=e.clock.remainingMs();if(n<=0)throw w(`timeout`,t);return Math.max(1,Math.floor(n))}async function D(e,t,n){let r=Math.min(t,E(e,n));await new Promise((t,n)=>{let i=!1,a=setTimeout(()=>s(t),r),o=()=>{s(()=>n(w(`cancelled`,`abort-signal`)))},s=t=>{i||(i=!0,clearTimeout(a),e.signal?.removeEventListener(`abort`,o),t())};e.signal?.addEventListener(`abort`,o,{once:!0}),e.signal?.aborted&&o()})}const O=[`SnapshotBridge.m`,`SnapshotBridgeRuntime.m`,`SnapshotBridgeRuntime.h`],se=[`SnapshotBridge.m`,`SnapshotBridgeRuntime.m`];async function ce(e,t,n){let r=y(`sha256`);for(let i of O){let a=v.join(t,i);if(E(n,`native-source-fingerprint-deadline`),!e.exists(a))throw w(`unsupported`,`native-source-missing`,{filePath:a});r.update(i),r.update(`\0`),r.update(await e.readBinary(a)),r.update(`\0`)}return r.digest(`hex`)}async function le(e,t,n){let r=await k(e,`xcodebuild`,[`-version`],n),i=await k(e,`sw_vers`,[`-productVersion`],n),a=await k(e,`sw_vers`,[`-buildVersion`],n),o=await k(e,`uname`,[`-m`],n),s=await k(e,`xcrun`,[`--sdk`,`iphonesimulator`,`--show-sdk-version`],n),c=t.trim();if(!c)throw w(`unsupported`,`simulator-runtime-missing`);if(o!==`arm64`&&o!==`x86_64`)throw w(`unsupported`,`simulator-architecture-unsupported`,{architecture:o});return{xcode:r,macosProductVersion:i,macosBuild:a,architecture:o,simulatorSdk:s,simulatorRuntime:c}}async function k(e,t,n,r){let i=await e.run(t,n,{allowFailure:!0,signal:r.signal,timeoutMs:Math.min(1e4,E(r,`toolchain-probe-deadline`))});if(i.exitCode!==0)throw w(`unsupported`,`toolchain-probe-failed`,{command:t,exitCode:i.exitCode,stderr:i.stderr.slice(0,1024)});let a=(i.stdout||i.stderr).trim();if(!a)throw w(`unsupported`,`toolchain-probe-empty`,{command:t});return a}const A=`agent-device-simulator-ax-v1.5.3`;Object.freeze([`verb`,`requestId`,`pid`,`generation`,`snapshotTree`,`automationMode`,`maxDepth`,`maxNodes`,`maxDurationMs`,`maxResponseBytes`]),Object.freeze([`protocolVersion`,`sourceVersion`,`requestId`,`generation`,`ok`,`pid`,`tree`,`truncated`,`automationEnabled`,`error_kind`,`error_code`,`error`]),Object.freeze([`XC_kAXXCAttributeElementType`,`XC_kAXXCAttributeElementBaseType`,`XC_kAXXCAttributeLabel`,`XC_kAXXCAttributeValue`,`XC_kAXXCAttributeIdentifier`,`XC_kAXXCAttributeFrame`,`XC_kAXXCAttributeAutomationType`,`XC_kAXXCAttributeChildren`]);function ue(e,t){let n;try{n=x.from(JSON.stringify(e),`utf8`)}catch(e){throw w(`malformed-tree`,`request-not-json`,{},e)}let r=n.length+4;if(r>t.maxRequestBytes)throw w(`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 de=class{header=x.alloc(4);headerBytes=0;chunks=[];payloadBytes=0;expectedBodyBytes;frame;maxFrameBytes;constructor(e){if(!Number.isSafeInteger(e)||e<=0)throw w(`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 w(`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 w(`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 w(`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 w(`transport-failure`,`bridge-frame-incomplete`,{headerBytes:this.headerBytes,payloadBytes:this.payloadBytes,expectedBodyBytes:this.expectedBodyBytes})}};function fe(e){let t;try{t=JSON.parse(e.toString(`utf8`))}catch(e){throw w(`malformed-tree`,`response-not-json`,{},e)}if(!j(t))throw w(`malformed-tree`,`response-not-object`);return t}function pe(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})}function me(e,t){if(e.protocolVersion!==1)throw w(`transport-failure`,`protocol-version-mismatch`,{expected:1,observed:e.protocolVersion});if(e.sourceVersion!==`agent-device-simulator-ax-v1.5.3`)throw w(`transport-failure`,`source-version-mismatch`,{expected:A,observed:e.sourceVersion});if(e.requestId!==t)throw w(`transport-failure`,`request-id-mismatch`,{expected:t,observed:e.requestId})}function he(e,t){if(typeof e.pid!=`number`||e.pid!==t.pid)throw w(`stale-target`,`bridge-pid-mismatch`,{expectedPid:t.pid,observedPid:e.pid});if(e.generation!==t.generation)throw w(`stale-target`,`bridge-generation-mismatch`,{expectedGeneration:t.generation,observedGeneration:e.generation})}function ge(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 w(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)}const M=`snapshot-bridge`,N=`manifest.json`;async function P(e){let t=e.deadline,n=e.sourceRoot??F(e.host),r=await ce(e.host,n,t),i=await le(e.host,e.runtime,t),a=_e({schemaVersion:1,protocolVersion:1,sourceVersion:A,sourceHash:r,toolchain:i}),o=e.cacheRoot??v.join(e.host.homeDirectory(),`.agent-device`,`snapshot-source`),s=v.join(o,a),c=await e.host.acquireLock(v.join(o,`${a}.lock`),{deadline:t});try{let c=await I(e.host,s,{sourceHash:r,cacheKey:a,toolchain:i},t);if(c)return c;E(t,`native-build-deadline`),e.host.exists(s)&&await e.host.remove(s),E(t,`native-build-deadline`),await e.host.ensureDirectory(o);let l=v.join(o,`.${a}.${e.host.processId()}.tmp`);E(t,`native-build-deadline`),await e.host.remove(l);try{E(t,`native-build-deadline`),await e.host.ensureDirectory(l);let o=v.join(l,M),c=await e.host.run(`xcrun`,[`--sdk`,`iphonesimulator`,`clang`,`-arch`,i.architecture,`-mios-simulator-version-min=15.0`,`-fobjc-arc`,`-Werror`,`-Wall`,`-Wextra`,`-framework`,`Foundation`,`-framework`,`CoreGraphics`,...se.map(e=>v.join(n,e)),`-o`,o],{signal:t.signal,timeoutMs:Math.min(12e4,E(t,`native-build-deadline`)),allowFailure:!0});if(c.exitCode!==0||!e.host.exists(o))throw w(`unsupported`,`native-build-failed`,{exitCode:c.exitCode,stderr:c.stderr.slice(0,4096)});E(t,`native-build-deadline`),await e.host.chmod(o,493);let u=await L(e.host,o,t),d={schemaVersion:1,protocolVersion:1,sourceVersion:A,sourceHash:r,cacheKey:a,toolchain:i,binarySha256:u};return await e.host.writeText(v.join(l,N),`${JSON.stringify(d,null,2)}\n`),E(t,`native-build-deadline`),await e.host.rename(l,s),{path:v.join(s,M),sourceHash:r,cacheKey:a,protocolVersion:1,sourceVersion:A}}catch(t){throw await e.host.remove(l),t}}finally{await c()}}function F(e){let t=e.projectRoot(),n=v.join(t,`apple`,`snapshot-bridge`);if(O.every(t=>e.exists(v.join(n,t))))return n;let r=v.join(t,`dist`,`apple`,`snapshot-bridge`);if(O.every(t=>e.exists(v.join(r,t))))return r;throw w(`unsupported`,`native-source-missing`,{projectRoot:t})}async function I(e,t,n,r){let i=v.join(t,M);if(!(!e.exists(i)||!e.exists(v.join(t,N))))try{let a=JSON.parse(await e.readText(v.join(t,N)));return a.schemaVersion!==1||a.protocolVersion!==1||a.sourceVersion!==`agent-device-simulator-ax-v1.5.3`||a.sourceHash!==n.sourceHash||a.cacheKey!==n.cacheKey||JSON.stringify(a.toolchain)!==JSON.stringify(n.toolchain)||typeof a.binarySha256!=`string`||await L(e,i,r)!==a.binarySha256?void 0:{path:i,sourceHash:n.sourceHash,cacheKey:n.cacheKey,protocolVersion:1,sourceVersion:A}}catch(e){if(e instanceof C&&(e.failureKind===`cancelled`||e.failureKind===`timeout`))throw e;return}}async function L(e,t,n){return E(n,`native-cache-hash-deadline`),y(`sha256`).update(await e.readBinary(t)).digest(`hex`)}function _e(e){return y(`sha256`).update(JSON.stringify(e)).digest(`hex`).slice(0,32)}const R=65536;function ve(){return{projectRoot:f,homeDirectory:te,run:async(e,t,n)=>await l(e,t,n),start:ye,connect:be,readText:re,readBinary:ne,writeText:m,ensureDirectory:g,chmod:h,exists:ee,rename:_,remove:p,acquireLock:xe,emitDiagnostic:i,withDiagnosticTimer:r,processId:s,readTargetProcessStartTime:ie}}function ye(e,t,n,r={}){if(r.signal?.aborted)throw w(`cancelled`,`abort-signal`);let i=c(`xcrun`,[`simctl`,`spawn`,e,t,`serve`,n,`--idle-timeout`,`60`,`--exit-on-disconnect`,`false`],{allowFailure:!0,captureOutput:!1,detached:!0}),o=i.child.pid??0;if(o<=0)throw w(`transport-failure`,`bridge-process-pid-missing`);let s=``;return i.child.stderr?.setEncoding(`utf8`),i.child.stderr?.on(`data`,e=>{s=Se(s,String(e))}),{pid:o,wait:i.wait,isAlive:()=>i.child.exitCode===null&&i.child.signalCode===null,signal:e=>{a(o,e)||i.child.kill(e)},readLog:()=>s}}async function be(e,t){if(t.signal?.aborted)throw w(`cancelled`,`abort-signal`);let n=Math.max(1,Math.floor(t.timeoutMs));return await new Promise((r,i)=>{let a=ae.createConnection({path:e}),o=!1,s=!1,c=setTimeout(()=>{p(w(`timeout`,`bridge-connect-timeout`)),a.destroy()},n),l=()=>{p(w(`cancelled`,`abort-signal`)),a.destroy()},u=()=>{o=!0,clearTimeout(c),t.signal?.removeEventListener(`abort`,l),a.off(`error`,d),a.off(`close`,f),a.setTimeout(0),r(a)},d=e=>{p(e),a.destroy()},f=()=>{o||p(w(`transport-failure`,`bridge-closed-before-connect`))},p=e=>{s||o||(s=!0,clearTimeout(c),t.signal?.removeEventListener(`abort`,l),a.off(`connect`,u),a.off(`error`,d),a.off(`close`,f),i(e))};a.once(`connect`,u),a.once(`error`,d),a.once(`close`,f),t.signal?.addEventListener(`abort`,l,{once:!0}),t.signal?.aborted&&l()})}async function xe(e,t){let n=s(),r=t.deadline,i=u({lockDirPath:e,owner:{pid:n,startTime:o(n),acquiredAtMs:Date.now()},timeoutMs:E(r,`cache-lock-deadline`),pollMs:100,ownerGraceMs:5e3,description:`iOS Simulator snapshot bridge cache`}),a=r.signal;if(!a)return await i;let c=!1,l,d=new Promise((e,t)=>{l=()=>{c=!0,t(w(`cancelled`,`abort-signal`))},a.addEventListener(`abort`,l,{once:!0}),a.aborted&&l()});try{return await Promise.race([i,d])}catch(e){throw c&&i.then(e=>e(),()=>void 0),r.clock.isExpired()&&!(e instanceof C&&e.failureKind===`cancelled`)?w(`timeout`,`cache-lock-deadline`):e}finally{a.removeEventListener(`abort`,l)}}function Se(e,t){let n=e+t;return n.length<=R?n:n.slice(n.length-R)}function Ce(e,t,n){let r=y(`sha256`).update(t).digest(`hex`).slice(0,12),i=y(`sha256`).update(n).digest(`hex`).slice(0,12);return v.join(`/tmp`,`agent-device-ax-${r}-${e.processId()}-${i}`,`snapshot.sock`)}const z=new WeakSet;async function B(e,t){let n;try{n=(await t.wait).exitCode}catch{n=void 0}return z.has(t)||(z.add(t),e.emitDiagnostic({level:`error`,phase:`ios.snapshot-source.bridge-process-exit`,data:{pid:t.pid,...n===void 0?{}:{exitCode:n},stderr:we(t.readLog())}})),w(`process-crash`,`bridge-exited`,{pid:t.pid,...n===void 0?{}:{exitCode:n}})}function we(e){let t=x.from(e);return t.length<=65536?e:t.subarray(-65536).toString(`utf8`)}async function Te(e){let t=new de(e.limits.maxResponseBytes-4),n=E(e.deadline,`bridge-request-deadline`);return await new Promise((r,i)=>{let a=!1,o=!1,s=setTimeout(()=>{p(w(`timeout`,`bridge-request-deadline`,{dispatched:o})),e.socket.destroy()},n),c=()=>{p(w(`cancelled`,`abort-signal`,{dispatched:o})),e.socket.destroy()},l=n=>{try{if(!Buffer.isBuffer(n))throw w(`transport-failure`,`bridge-data-invalid`);let r=t.push(n);if(r){let t=fe(r);if(me(t,e.requestId),he(t,{pid:e.expectedPid,generation:e.expectedGeneration}),t.ok!==!0&&ge(t),typeof t.truncated!=`boolean`)throw w(`malformed-tree`,`truncated-invalid`);f(t);return}}catch(t){p(t),e.socket.destroy()}},u=e=>p(T(e)),d=()=>{a||(e.process.isAlive()?p(w(`transport-failure`,`bridge-connection-closed`)):B(e.host,e.process).then(p))};e.process.wait.then(()=>{a||B(e.host,e.process).then(p)},e=>{a||p(T(e))});let f=e=>m(()=>r(e)),p=e=>m(()=>i(e)),m=t=>{a||(a=!0,clearTimeout(s),e.deadline.signal?.removeEventListener(`abort`,c),e.socket.off(`data`,l),e.socket.off(`error`,u),e.socket.off(`close`,d),t())};e.socket.on(`data`,l),e.socket.on(`error`,u),e.socket.on(`close`,d),e.deadline.signal?.addEventListener(`abort`,c,{once:!0});try{if(e.deadline.signal?.aborted)throw w(`cancelled`,`abort-signal`);o=!0,e.socket.write(e.frame)}catch(t){p(T(t)),e.socket.destroy()}})}var Ee=class{sessions=new Map;requestQueues=new Map;ownerId=b();closed=!1;host;constructor(e){this.host=e}async request(e){if(this.closed)throw w(`unsupported`,`source-closed`);return await this.withSimulatorLock(e.target.udid,e.deadline,()=>this.requestInSimulator(e))}async requestInSimulator(e){if(this.closed)throw w(`unsupported`,`source-closed`);let t=e.deadline;E(t,`bridge-request-deadline`);let n=this.sessions.get(e.target.udid),r=await this.ensureSession(e,t);try{let n=await this.readTargetStartTime(e.target,t),i=await this.exchange(r,e,t);return await this.assertTargetStillCurrent(e.target,n,t),i}catch(e){throw await this.handleRequestFailure(e,r,n)}}async handleRequestFailure(e,t,n){let r=T(e);return Oe(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 De(r,t),await n()}finally{i(),this.requestQueues.get(e)===o&&this.requestQueues.delete(e)}}async close(){if(this.closed)return;this.closed=!0;let e=[...this.sessions.values()];this.sessions.clear(),await Promise.all(e.map(async e=>await this.dispose(e,!0)))}async ensureSession(e,t){let n=e.target.udid,r=this.sessions.get(n);if(r&&r.bridgePath===e.bridge.path&&r.process.isAlive())return(!r.socket||r.socket.destroyed)&&(r.socket=await this.connectUntilReady(r,t)),r;r&&await this.removeSession(r,!0);let i=Ce(this.host,e.target.udid,this.ownerId);await this.host.ensureDirectory(v.dirname(i)),await this.host.remove(i);let a=this.host.start(e.target.udid,e.bridge.path,i,{signal:t.signal}),o={udid:e.target.udid,bridgePath:e.bridge.path,socketPath:i,process:a};this.sessions.set(n,o);try{return o.socket=await this.connectUntilReady(o,t),o}catch(e){throw await this.removeSession(o,!0),T(e)}}async connectUntilReady(e,t){let n;for(;;){let r=E(t,`bridge-connect-deadline`);if(!e.process.isAlive())throw await B(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 C&&e.failureKind===`cancelled`)throw e;let r=Math.min(20,E(t,`bridge-connect-deadline`));try{await D(t,r,`bridge-connect-deadline`)}catch(e){throw T(e)}}if(n instanceof C&&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=ue(pe({requestId:r,pid:t.target.pid,generation:t.target.generation,maxDepth:Math.min(t.limits.maxTraversalDepth,t.maxDepth),maxNodes:t.limits.maxNodes,maxDurationMs:E(n,`bridge-request-deadline`),maxResponseBytes:t.limits.maxResponseBytes}),t.limits);return await Te({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:E(t,`target-identity-deadline`)});if(!n)throw w(`stale-target`,`target-process-unavailable`,{pid:e.pid,generation:e.generation});if(e.processStartTime!==void 0&&e.processStartTime!==n)throw w(`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:E(n,`target-identity-deadline`)});if(r!==t)throw w(`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 V(e.process,500),e.process.isAlive()&&(e.process.signal(`SIGKILL`),await V(e.process,500))),await this.host.remove(e.socketPath)}};async function De(e,t){let n=E(t,`bridge-request-deadline`);await Promise.race([e,D(t,n,`bridge-request-deadline`).then(()=>{throw w(`timeout`,`bridge-request-deadline`)})])}function Oe(e,t,n){return(e.failureKind===`cancelled`||e.failureKind===`timeout`)&&(e.details?.dispatched===!0||n!==t)}async function V(e,t){await Promise.race([e.wait.catch(()=>void 0),new Promise(e=>setTimeout(e,t))])}const H=16777216,U=12e4,W=1e4,ke=Object.freeze({maxRequestBytes:65536,maxResponseBytes:4194304,maxNodes:1500,maxTraversalDepth:64,maxDurationMs:5e3});function Ae(e){let n={...ke,...e??{}};for(let[e,r]of Object.entries(n))if(!Number.isSafeInteger(r)||r<=0)throw new t(`INVALID_ARGS`,`Snapshot source limit ${e} must be a positive integer`,{name:e,value:r});if(n.maxRequestBytes>n.maxResponseBytes)throw new t(`INVALID_ARGS`,`Snapshot source request bytes cannot exceed response bytes`,{maxRequestBytes:n.maxRequestBytes,maxResponseBytes:n.maxResponseBytes});if(n.maxRequestBytes>H||n.maxResponseBytes>H)throw new t(`INVALID_ARGS`,`Snapshot source frame limits exceed the bridge bound`,{maxRequestBytes:n.maxRequestBytes,maxResponseBytes:n.maxResponseBytes,maximumFrameBytes:H});if(n.maxNodes>W||n.maxTraversalDepth>128)throw new t(`INVALID_ARGS`,`Snapshot source tree limits exceed the bridge bound`,{maxNodes:n.maxNodes,maxTraversalDepth:n.maxTraversalDepth,maximumNodes:W,maximumDepth:128});if(n.maxDurationMs>U)throw new t(`INVALID_ARGS`,`Snapshot source duration exceeds the bridge bound`,{maxDurationMs:n.maxDurationMs,maximumDurationMs:U});if(n.maxRequestBytes<=4||n.maxResponseBytes<=4)throw new t(`INVALID_ARGS`,`Snapshot source frame limits must leave room for a body`,{maxRequestBytes:n.maxRequestBytes,maxResponseBytes:n.maxResponseBytes});return Object.freeze(n)}const G=Object.freeze({elementType:`XC_kAXXCAttributeElementType`,elementBaseType:`XC_kAXXCAttributeElementBaseType`,label:`XC_kAXXCAttributeLabel`,value:`XC_kAXXCAttributeValue`,identifier:`XC_kAXXCAttributeIdentifier`,frame:`XC_kAXXCAttributeFrame`,automationType:`XC_kAXXCAttributeAutomationType`,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`},je=new Set(Object.values(G));function Me(e,t,n){let r=Array.isArray(e)?e:[e];if(r.length===0||r.some(e=>!j(e)))throw w(`malformed-tree`,`guest-tree-root-invalid`);let i=[],a=0;for(let e of r)o(e,void 0,0);if(i.length>n.maxNodes)throw w(`malformed-tree`,`node-limit-exceeded`,{nodeCount:i.length,maxNodes:n.maxNodes});if(a>n.maxTraversalDepth)throw w(`malformed-tree`,`traversal-depth-exceeded`,{maxTraversalDepth:a,maxAllowedDepth:n.maxTraversalDepth});if(typeof t.truncated!=`boolean`)throw w(`malformed-tree`,`truncated-invalid`);return{nodes:i,maxTraversalDepth:a,viewport:Fe(i.find(e=>e.type===`Application`||e.type===`Window`))};function o(e,t,r){if(i.length>=n.maxNodes)throw w(`malformed-tree`,`node-limit-exceeded`,{maxNodes:n.maxNodes});for(let t of Object.keys(e))if(!je.has(t))throw w(`malformed-tree`,`node-contains-unknown-field`,{key:t});let s=e[G.children];if(!Array.isArray(s))throw w(`malformed-tree`,`children-invalid`);let c=i.length,l=Ne(e,c,t,r);i.push(l),a=Math.max(a,r);for(let e of s){if(!j(e))throw w(`malformed-tree`,`child-invalid`);o(e,c,r+1)}}}function Ne(e,t,n,r){let i=Y(e[G.elementType]),a=Y(e[G.elementBaseType]),o=Ie(e[G.automationType]),s=Pe(e[G.frame]);return{index:t,...n===void 0?{}:{parentIndex:n},...J(i,o)?{type:J(i,o)}:{},...i?{role:i}:{},...a&&a!==i?{subrole:a}:{},...Y(e[G.label])?{label:Y(e[G.label])}:{},...X(e[G.value])?{value:X(e[G.value])}:{},...Y(e[G.identifier])?{identifier:Y(e[G.identifier])}:{},...s?{rect:s}:{},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 Pe(e){if(e===void 0)return;if(!j(e))throw w(`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 w(`malformed-tree`,`frame-invalid`);let[n,r,i,a]=t;if(i<0||a<0)throw w(`malformed-tree`,`frame-invalid`);return{x:n,y:r,width:i,height:a}}function Fe(e){return!e||e.type!==`Application`&&e.type!==`Window`?{kind:`missing`,reason:`not-provided`}:n(e.rect)?{kind:`reported`,rect:e.rect}:{kind:`missing`,reason:e.rect?`invalid`:`not-provided`}}function Y(e){return typeof e==`string`&&e.length>0?e:void 0}function X(e){if(typeof e==`string`)return e.length>0?e:void 0;if(typeof e==`number`||typeof e==`boolean`)return String(e);if(e!=null)throw w(`malformed-tree`,`scalar-invalid`)}function Ie(e){if(e!=null){if(!Number.isSafeInteger(e))throw w(`malformed-tree`,`automation-type-invalid`);return e}}const Z=`simulator-ax-bridge`;function Le(e={}){let t=e.host??ve(),n=new Ee(t),r=new Map,i=!1,a=async n=>{if(i)throw w(`unsupported`,`source-closed`);let a=r.get(n.runtime);if(a)return a;let o=await t.withDiagnosticTimer(`ios.snapshot-source.prepare`,async()=>await P({host:t,runtime:n.runtime,limits:n.limits,deadline:n.deadline,sourceRoot:e.sourceRoot,cacheRoot:e.cacheRoot}),{producer:Z});return r.set(n.runtime,o),o};return{acquire:async r=>{try{if(i)throw w(`unsupported`,`source-closed`);Re(r);let o=Ae({...e.limits,...r.limits}),s=oe(o.maxDurationMs,r.signal),c=Q(r.hint,o.maxTraversalDepth);return await t.withDiagnosticTimer(`ios.snapshot-source.acquire`,async()=>{let e=await a({runtime:r.target.runtime,limits:o,deadline:s}),t=await n.request({target:r.target,bridge:e,limits:o,maxDepth:c,deadline:s});return E(s,`snapshot-decode-deadline`),{stage:`acquired`,acquisition:ze(r.hint,r.target,t,o,c)}},{producer:Z})}catch(e){let t=T(e);return{stage:`failed`,failure:{kind:t.failureKind,code:t.failureCode,...t.details?{details:t.details}:{}}}}},close:async()=>{i||(i=!0,await n.close())}}}function Re(e){if(!e.target.udid.trim()||!e.target.runtime.trim()||!e.target.generation.trim()||!Number.isSafeInteger(e.target.pid)||e.target.pid<=0)throw new t(`INVALID_ARGS`,`Simulator snapshot source target identity is incomplete`);let n=e.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 t(`INVALID_ARGS`,`Simulator snapshot source capture hint is invalid`)}function Q(e,n){let r=e.rawTraversalDepth??n;if(r>n)throw new t(`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 ze(e,t,n,r,i){if(n.automationEnabled!==!0)throw w(`unsupported`,`automation-mode-unavailable`);let a=n.tree,o=n.truncated;if(typeof o!=`boolean`)throw w(`malformed-tree`,`truncated-invalid`);let s=Me(a,{truncated:o},r),c=n.generation;if(typeof c!=`string`||!c)throw w(`malformed-tree`,`generation-invalid`);let l=Object.freeze(s.nodes.map(e=>Object.freeze({...e,pid:t.pid}))),u=Be(e,o,s,r,i,l.length),d=Object.freeze({...t.targetId?{targetId:t.targetId}:{},generation:c}),f={producer:Z,nodes:l,truncated:o,viewport:s.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 Be(e,t,n,r,i,a){return Object.freeze([{kind:`unavailable-fact`,fact:`hittability`},...e.interactiveOnly?[{kind:`unavailable-fact`,fact:`interactive-query`}]:[],...t?[Ve(n.maxTraversalDepth,a,r,i)]:[],...n.viewport.kind===`missing`?[{kind:`missing-viewport`,reason:n.viewport.reason}]:[]])}function Ve(e,t,n,r){return t>=n.maxNodes?{kind:`truncated`,dimension:`nodes`,limit:n.maxNodes}:e>=r?{kind:`truncated`,dimension:`depth`,limit:r}:{kind:`truncated`,dimension:`payload`,limit:n.maxResponseBytes}}export{Le as createSimulatorSnapshotSource};
1
+ import{A as e,C as t}from"./sdk-contracts.js";import{Rr as n,zr as r}from"./sdk-batch.js";import{c as i,r as a}from"./diagnostics.js";import{S as o,b as s,f as c}from"./owner-identity.js";import{c as l,l as u,r as d}from"./exec.js";import{t as f}from"./file.js";import"./diagnostics2.js";import"./command.js";import{n as p}from"./retry.js";import{n as m}from"./version.js";import"./process.js";import{C as ee,D as te,c as ne,f as re,h as ie,n as ae,o as oe,w as se,y as ce}from"./host-file.js";import{t as le}from"./apple-runner-platform.js";import{t as ue}from"./snapshot-process.js";import h from"node:path";import{createHash as g,randomUUID as _}from"node:crypto";import de from"node:net";import{Buffer as v}from"node:buffer";const fe={unsupported:`UNSUPPORTED_OPERATION`,"malformed-tree":`COMMAND_FAILED`,"stale-target":`COMMAND_FAILED`,timeout:`COMMAND_FAILED`,cancelled:`COMMAND_FAILED`,"process-crash":`COMMAND_FAILED`,"transport-failure":`COMMAND_FAILED`};var y=class extends t{failureKind;failureCode;constructor(e,t,n=`iOS Simulator snapshot source ${e}: ${t}`,r={},i){super(fe[e],n,{...r,bridgeFailure:e,bridgeFailureCode:t,...e===`cancelled`?{reason:`request_canceled`}:{}},i),this.name=`SnapshotSourceError`,this.failureKind=e,this.failureCode=t}};function b(e,t,n={},r){return new y(e,t,void 0,n,r)}function x(n){return n instanceof y?n:e(n)?b(`cancelled`,`abort-signal`,{},n):n instanceof t&&typeof n.details?.timeoutMs==`number`?b(`timeout`,`host-operation-timeout`,{timeoutMs:n.details.timeoutMs},n):b(`transport-failure`,`unexpected-host-error`,{error:n instanceof Error?n.message:String(n)},n)}function pe(e,t,n=Date.now){if(t?.aborted)throw b(`cancelled`,`abort-signal`);return{clock:p.fromTimeoutMs(e,n()),now:n,signal:t}}function S(e,t){if(e.signal?.aborted)throw b(`cancelled`,`abort-signal`);let n=e.clock.remainingMs(e.now());if(n<=0)throw b(`timeout`,t);return Math.max(1,Math.floor(n))}async function C(e,t,n){let r=Math.min(t,S(e,n));await new Promise((t,n)=>{let i=!1,a=setTimeout(()=>s(t),r),o=()=>{s(()=>n(b(`cancelled`,`abort-signal`)))},s=t=>{i||(i=!0,clearTimeout(a),e.signal?.removeEventListener(`abort`,o),t())};e.signal?.addEventListener(`abort`,o,{once:!0}),e.signal?.aborted&&o()})}const w=[`SnapshotBridge.m`,`SnapshotBridgeRuntime.m`,`SnapshotBridgeRuntime.h`,`SnapshotBridgeCapture.h`,`SnapshotBridgeCapture.m`],me=[`SnapshotBridge.m`,`SnapshotBridgeRuntime.m`,`SnapshotBridgeCapture.m`];async function he(e,t,n){let r=g(`sha256`);for(let i of w){let a=h.join(t,i);if(S(n,`native-source-fingerprint-deadline`),!e.exists(a))throw b(`unsupported`,`native-source-missing`,{filePath:a});r.update(i),r.update(`\0`),r.update(await e.readBinary(a)),r.update(`\0`)}return r.digest(`hex`)}async function ge(e,t,n){let r=await T(e,`xcodebuild`,[`-version`],n),i=await T(e,`sw_vers`,[`-productVersion`],n),a=await T(e,`sw_vers`,[`-buildVersion`],n),o=await T(e,`uname`,[`-m`],n),s=await T(e,`xcrun`,[`--sdk`,`iphonesimulator`,`--show-sdk-version`],n),c=t.trim();if(!c)throw b(`unsupported`,`simulator-runtime-missing`);if(o!==`arm64`&&o!==`x86_64`)throw b(`unsupported`,`simulator-architecture-unsupported`,{architecture:o});return{xcode:r,macosProductVersion:i,macosBuild:a,architecture:o,simulatorSdk:s,simulatorRuntime:c}}async function T(e,t,n,r){let i=await _e(e,t,n,r);if(i.exitCode!==0)throw b(`unsupported`,`toolchain-probe-failed`,{command:t,exitCode:i.exitCode,stderr:i.stderr.slice(0,1024)});let a=(i.stdout||i.stderr).trim();if(!a)throw b(`unsupported`,`toolchain-probe-empty`,{command:t});return a}async function _e(e,t,n,r){try{return await E(e,t,n,r)}catch(i){if(!d(i))throw i;if(r.signal?.aborted)throw b(`cancelled`,`abort-signal`);if(r.clock.remainingMs(r.now())<=0)throw i;return await E(e,t,n,r)}}function E(e,t,n,r){return e.run(t,n,{allowFailure:!0,signal:r.signal,timeoutMs:Math.min(le,S(r,`toolchain-probe-deadline`))})}const D=`agent-device-simulator-ax-v1.5.5`;Object.freeze([`verb`,`requestId`,`pid`,`generation`,`snapshotTree`,`automationMode`,`maxDepth`,`maxNodes`,`maxDurationMs`,`maxResponseBytes`,`nativeLevelsHint`]),Object.freeze([`protocolVersion`,`sourceVersion`,`requestId`,`generation`,`ok`,`pid`,`tree`,`truncated`,`automationEnabled`,`recovery`,`error_kind`,`error_code`,`error`]),Object.freeze([`XC_kAXXCAttributeElementType`,`XC_kAXXCAttributeElementBaseType`,`XC_kAXXCAttributeLabel`,`XC_kAXXCAttributeValue`,`XC_kAXXCAttributeIdentifier`,`XC_kAXXCAttributeFrame`,`XC_kAXXCAttributeAutomationType`,`XC_kAXXCAttributeChildren`]);const ve=[`requests`,`rejected`,`continuations`,`acceptedLevels`];function ye(e){let t=e.recovery;if(!P(t))throw b(`malformed-tree`,`recovery-invalid`);let n=ve.map(e=>[e,t[e]]);if(n.some(([,e])=>!Number.isSafeInteger(e)||e<0))throw b(`malformed-tree`,`recovery-invalid`);return Object.freeze(Object.fromEntries(n))}function be(e,t){let n;try{n=v.from(JSON.stringify(e),`utf8`)}catch(e){throw b(`malformed-tree`,`request-not-json`,{},e)}let r=n.length+4;if(r>t.maxRequestBytes)throw b(`transport-failure`,`request-limit-exceeded`,{frameBytes:r,maxRequestBytes:t.maxRequestBytes});let i=v.alloc(4);return i.writeUInt32BE(n.length,0),v.concat([i,n])}var O=class{header=v.alloc(4);headerBytes=0;chunks=[];payloadBytes=0;expectedBodyBytes;frame;maxFrameBytes;constructor(e){if(!Number.isSafeInteger(e)||e<=0)throw b(`malformed-tree`,`frame-limit-invalid`,{maxFrameBytes:e});this.maxFrameBytes=e}push(e){if(this.frame)return this.acceptTrailingChunk(e);let t=this.readHeader(e);if(t&&(this.appendPayload(e,t.offset,t.bodyBytes),this.payloadBytes===t.bodyBytes))return this.frame=v.concat(this.chunks,t.bodyBytes),this.frame}acceptTrailingChunk(e){if(e.length>0)throw b(`malformed-tree`,`multiple-frames`,{trailingBytes:e.length});return this.frame}readHeader(e){if(this.headerBytes===4)return{offset:0,bodyBytes:this.expectedBodyBytes};let t=Math.min(4-this.headerBytes,e.length);if(e.copy(this.header,this.headerBytes,0,t),this.headerBytes+=t,this.headerBytes<4)return;let n=this.header.readUInt32BE(0);if(n===0||n>this.maxFrameBytes)throw b(`malformed-tree`,`frame-limit-exceeded`,{bodyBytes:n,maxFrameBytes:this.maxFrameBytes});return this.expectedBodyBytes=n,{offset:t,bodyBytes:n}}appendPayload(e,t,n){let r=n-this.payloadBytes,i=e.length-t;if(i>r)throw b(`malformed-tree`,`multiple-frames`,{trailingBytes:i-r});i!==0&&(this.chunks.push(e.subarray(t)),this.payloadBytes+=i)}finish(){if(this.frame)return this.frame;throw b(`transport-failure`,`bridge-frame-incomplete`,{headerBytes:this.headerBytes,payloadBytes:this.payloadBytes,expectedBodyBytes:this.expectedBodyBytes})}};function k(e){let t;try{t=JSON.parse(e.toString(`utf8`))}catch(e){throw b(`malformed-tree`,`response-not-json`,{},e)}if(!P(t))throw b(`malformed-tree`,`response-not-object`);return t}function A(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 j(e,t){if(e.protocolVersion!==1)throw b(`transport-failure`,`protocol-version-mismatch`,{expected:1,observed:e.protocolVersion});if(e.sourceVersion!==`agent-device-simulator-ax-v1.5.5`)throw b(`transport-failure`,`source-version-mismatch`,{expected:D,observed:e.sourceVersion});if(e.requestId!==t)throw b(`transport-failure`,`request-id-mismatch`,{expected:t,observed:e.requestId})}function M(e,t){if(typeof e.pid!=`number`||e.pid!==t.pid)throw b(`stale-target`,`bridge-pid-mismatch`,{expectedPid:t.pid,observedPid:e.pid});if(e.generation!==t.generation)throw b(`stale-target`,`bridge-generation-mismatch`,{expectedGeneration:t.generation,observedGeneration:e.generation})}function N(e){let t=e.error_kind,n=typeof e.error_code==`string`?e.error_code:`guest-error`,r=typeof e.error==`string`?e.error:void 0,i=r?{guestMessage:r.slice(0,1024)}:{};throw b(t===`unsupported`?`unsupported`:t===`malformed_tree`?`malformed-tree`:t===`application_not_responding`?`timeout`:t===`application_unavailable`?`transport-failure`:t===`bad_request`?`malformed-tree`:`transport-failure`,n,i)}function P(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}const F=`snapshot-bridge`,I=`manifest.json`;async function xe(e){let t=e.deadline,n=e.sourceRoot??Se(e.host),r=await he(e.host,n,t),i=await ge(e.host,e.runtime,t),a=we({schemaVersion:1,protocolVersion:1,sourceVersion:D,sourceHash:r,toolchain:i}),o=e.cacheRoot??h.join(e.host.homeDirectory(),`.agent-device`,`snapshot-source`),s=h.join(o,a),c=await e.host.acquireLock(h.join(o,`${a}.lock`),{deadline:t});try{let c=await Ce(e.host,s,{sourceHash:r,cacheKey:a,toolchain:i},t);if(c)return c;S(t,`native-build-deadline`),e.host.exists(s)&&await e.host.remove(s),S(t,`native-build-deadline`),await e.host.ensureDirectory(o);let l=h.join(o,`.${a}.${e.host.processId()}.tmp`);S(t,`native-build-deadline`),await e.host.remove(l);try{S(t,`native-build-deadline`),await e.host.ensureDirectory(l);let o=h.join(l,F),c=await e.host.run(`xcrun`,[`--sdk`,`iphonesimulator`,`clang`,`-arch`,i.architecture,`-mios-simulator-version-min=15.0`,`-fobjc-arc`,`-Werror`,`-Wall`,`-Wextra`,`-framework`,`Foundation`,`-framework`,`CoreGraphics`,...me.map(e=>h.join(n,e)),`-o`,o],{signal:t.signal,timeoutMs:Math.min(12e4,S(t,`native-build-deadline`)),allowFailure:!0});if(c.exitCode!==0||!e.host.exists(o))throw b(`unsupported`,`native-build-failed`,{exitCode:c.exitCode,stderr:c.stderr.slice(0,4096)});S(t,`native-build-deadline`),await e.host.chmod(o,493);let u=await L(e.host,o,t),d={schemaVersion:1,protocolVersion:1,sourceVersion:D,sourceHash:r,cacheKey:a,toolchain:i,binarySha256:u};return await e.host.writeText(h.join(l,I),`${JSON.stringify(d,null,2)}\n`),S(t,`native-build-deadline`),await e.host.rename(l,s),{path:h.join(s,F),sourceHash:r,cacheKey:a,protocolVersion:1,sourceVersion:D}}catch(t){throw await e.host.remove(l),t}}finally{await c()}}function Se(e){let t=e.projectRoot(),n=h.join(t,`apple`,`snapshot-bridge`);if(w.every(t=>e.exists(h.join(n,t))))return n;let r=h.join(t,`dist`,`apple`,`snapshot-bridge`);if(w.every(t=>e.exists(h.join(r,t))))return r;throw b(`unsupported`,`native-source-missing`,{projectRoot:t})}async function Ce(e,t,n,r){let i=h.join(t,F);if(!(!e.exists(i)||!e.exists(h.join(t,I))))try{let a=JSON.parse(await e.readText(h.join(t,I)));return a.schemaVersion!==1||a.protocolVersion!==1||a.sourceVersion!==`agent-device-simulator-ax-v1.5.5`||a.sourceHash!==n.sourceHash||a.cacheKey!==n.cacheKey||JSON.stringify(a.toolchain)!==JSON.stringify(n.toolchain)||typeof a.binarySha256!=`string`||await L(e,i,r)!==a.binarySha256?void 0:{path:i,sourceHash:n.sourceHash,cacheKey:n.cacheKey,protocolVersion:1,sourceVersion:D}}catch(e){if(e instanceof y&&(e.failureKind===`cancelled`||e.failureKind===`timeout`))throw e;return}}async function L(e,t,n){return S(n,`native-cache-hash-deadline`),g(`sha256`).update(await e.readBinary(t)).digest(`hex`)}function we(e){return g(`sha256`).update(JSON.stringify(e)).digest(`hex`).slice(0,32)}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 R=65536;function Ee(){return{projectRoot:m,homeDirectory:re,run:async(e,t,n)=>await l(e,t,n),start:De,connect:Oe,readText:ce,readBinary:ie,writeText:te,ensureDirectory:oe,chmod:ae,exists:ne,rename:se,remove:ee,acquireLock:ke,emitDiagnostic:a,withDiagnosticTimer:i,processId:c,readTargetProcessStartTime:ue}}function De(e,t,n,r={}){if(r.signal?.aborted)throw b(`cancelled`,`abort-signal`);let i=u(`xcrun`,[`simctl`,`spawn`,e,t,`serve`,n,`--idle-timeout`,`60`,`--exit-on-disconnect`,`false`],{allowFailure:!0,captureOutput:!1,detached:!0}),a=i.child.pid??0;if(a<=0)throw b(`transport-failure`,`bridge-process-pid-missing`);let s=``;return i.child.stderr?.setEncoding(`utf8`),i.child.stderr?.on(`data`,e=>{s=Ae(s,String(e))}),{pid:a,wait:i.wait,isAlive:()=>i.child.exitCode===null&&i.child.signalCode===null,signal:e=>{o(a,e)||i.child.kill(e)},readLog:()=>s}}async function Oe(e,t){if(t.signal?.aborted)throw b(`cancelled`,`abort-signal`);let n=Math.max(1,Math.floor(t.timeoutMs));return await new Promise((r,i)=>{let a=de.createConnection({path:e}),o=!1,s=!1,c=setTimeout(()=>{p(b(`timeout`,`bridge-connect-timeout`)),a.destroy()},n),l=()=>{p(b(`cancelled`,`abort-signal`)),a.destroy()},u=()=>{o=!0,clearTimeout(c),t.signal?.removeEventListener(`abort`,l),a.off(`error`,d),a.off(`close`,f),a.setTimeout(0),r(a)},d=e=>{p(e),a.destroy()},f=()=>{o||p(b(`transport-failure`,`bridge-closed-before-connect`))},p=e=>{s||o||(s=!0,clearTimeout(c),t.signal?.removeEventListener(`abort`,l),a.off(`connect`,u),a.off(`error`,d),a.off(`close`,f),i(e))};a.once(`connect`,u),a.once(`error`,d),a.once(`close`,f),t.signal?.addEventListener(`abort`,l,{once:!0}),t.signal?.aborted&&l()})}async function ke(e,t){let n=c(),r=t.deadline,i=f({lockDirPath:e,owner:{pid:n,startTime:s(n),acquiredAtMs:Date.now()},timeoutMs:S(r,`cache-lock-deadline`),pollMs:100,ownerGraceMs:5e3,description:`iOS Simulator snapshot bridge cache`}),a=r.signal;if(!a)return await i;let o=!1,l,u=new Promise((e,t)=>{l=()=>{o=!0,t(b(`cancelled`,`abort-signal`))},a.addEventListener(`abort`,l,{once:!0}),a.aborted&&l()});try{return await Promise.race([i,u])}catch(e){throw o&&i.then(e=>e(),()=>void 0),r.clock.isExpired()&&!(e instanceof y&&e.failureKind===`cancelled`)?b(`timeout`,`cache-lock-deadline`):e}finally{a.removeEventListener(`abort`,l)}}function Ae(e,t){let n=e+t;return n.length<=R?n:n.slice(n.length-R)}function je(e,t,n){let r=g(`sha256`).update(t).digest(`hex`).slice(0,12),i=g(`sha256`).update(n).digest(`hex`).slice(0,12);return h.join(`/tmp`,`agent-device-ax-${r}-${e.processId()}-${i}`,`snapshot.sock`)}const z=new WeakSet;async function B(e,t){let n;try{n=(await t.wait).exitCode}catch{n=void 0}return z.has(t)||(z.add(t),e.emitDiagnostic({level:`error`,phase:`ios.snapshot-source.bridge-process-exit`,data:{pid:t.pid,...n===void 0?{}:{exitCode:n},stderr:Me(t.readLog())}})),b(`process-crash`,`bridge-exited`,{pid:t.pid,...n===void 0?{}:{exitCode:n}})}function Me(e){let t=v.from(e);return t.length<=65536?e:t.subarray(-65536).toString(`utf8`)}async function V(e){let t=new O(e.limits.maxResponseBytes-4),n=S(e.deadline,`bridge-request-deadline`);return await new Promise((r,i)=>{let a=!1,o=!1,s=setTimeout(()=>{p(b(`timeout`,`bridge-request-deadline`,{dispatched:o})),e.socket.destroy()},n),c=()=>{p(b(`cancelled`,`abort-signal`,{dispatched:o})),e.socket.destroy()},l=n=>{try{if(!Buffer.isBuffer(n))throw b(`transport-failure`,`bridge-data-invalid`);let r=t.push(n);if(r){let t=k(r);if(j(t,e.requestId),M(t,{pid:e.expectedPid,generation:e.expectedGeneration}),t.ok!==!0&&N(t),typeof t.truncated!=`boolean`)throw b(`malformed-tree`,`truncated-invalid`);f(t);return}}catch(t){p(t),e.socket.destroy()}},u=e=>p(x(e)),d=()=>{a||(e.process.isAlive()?p(b(`transport-failure`,`bridge-connection-closed`)):B(e.host,e.process).then(p))};e.process.wait.then(()=>{a||B(e.host,e.process).then(p)},e=>{a||p(x(e))});let f=e=>m(()=>r(e)),p=e=>m(()=>i(e)),m=t=>{a||(a=!0,clearTimeout(s),e.deadline.signal?.removeEventListener(`abort`,c),e.socket.off(`data`,l),e.socket.off(`error`,u),e.socket.off(`close`,d),t())};e.socket.on(`data`,l),e.socket.on(`error`,u),e.socket.on(`close`,d),e.deadline.signal?.addEventListener(`abort`,c,{once:!0});try{if(e.deadline.signal?.aborted)throw b(`cancelled`,`abort-signal`);o=!0,e.socket.write(e.frame)}catch(t){p(x(t)),e.socket.destroy()}})}var Ne=class{sessions=new Map;requestQueues=new Map;ownerId=_();closed=!1;host;constructor(e){this.host=e}async request(e){if(this.closed)throw b(`unsupported`,`source-closed`);return await this.withSimulatorLock(e.target.udid,e.deadline,()=>this.requestInSimulator(e))}async requestInSimulator(e){if(this.closed)throw b(`unsupported`,`source-closed`);let t=e.deadline;S(t,`bridge-request-deadline`);let n=this.sessions.get(e.target.udid),r=await this.ensureSession(e,t);try{let n=await this.readTargetStartTime(e.target,t),i=await this.exchange(r,e,t);return await this.assertTargetStillCurrent(e.target,n,t),i}catch(e){throw await this.handleRequestFailure(e,r,n)}}async handleRequestFailure(e,t,n){let r=x(e);return Fe(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 Pe(r,t),await n()}finally{i(),this.requestQueues.get(e)===o&&this.requestQueues.delete(e)}}async close(){if(this.closed)return;this.closed=!0;let e=[...this.sessions.values()];this.sessions.clear(),await Promise.all(e.map(async e=>await this.dispose(e,!0)))}async ensureSession(e,t){let n=e.target.udid,r=this.sessions.get(n);if(r&&r.bridgePath===e.bridge.path&&r.process.isAlive())return(!r.socket||r.socket.destroyed)&&(r.socket=await this.connectUntilReady(r,t)),r;r&&await this.removeSession(r,!0);let i=je(this.host,e.target.udid,this.ownerId);await this.host.ensureDirectory(h.dirname(i)),await this.host.remove(i);let a=this.host.start(e.target.udid,e.bridge.path,i,{signal:t.signal}),o={udid:e.target.udid,bridgePath:e.bridge.path,socketPath:i,process:a};this.sessions.set(n,o);try{return o.socket=await this.connectUntilReady(o,t),o}catch(e){throw await this.removeSession(o,!0),x(e)}}async connectUntilReady(e,t){let n;for(;;){let r=S(t,`bridge-connect-deadline`);if(!e.process.isAlive())throw await B(this.host,e.process);try{return await this.host.connect(e.socketPath,{signal:t.signal,timeoutMs:Math.min(250,r)})}catch(e){if(n=e,e instanceof y&&e.failureKind===`cancelled`)throw e;let r=Math.min(20,S(t,`bridge-connect-deadline`));try{await C(t,r,`bridge-connect-deadline`)}catch(e){throw x(e)}}if(n instanceof y&&n.failureKind===`timeout`)throw n}}async exchange(e,t,n){(!e.socket||e.socket.destroyed)&&(e.socket=await this.connectUntilReady(e,n));let r=_(),i=be(A({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 V({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 b(`stale-target`,`target-process-unavailable`,{pid:e.pid,generation:e.generation});if(e.processStartTime!==void 0&&e.processStartTime!==n)throw b(`stale-target`,`target-process-changed`,{pid:e.pid,generation:e.generation,expectedStartTime:e.processStartTime,observedStartTime:n});return n}async assertTargetStillCurrent(e,t,n){let r=await this.host.readTargetProcessStartTime(e.pid,{signal:n.signal,timeoutMs:S(n,`target-identity-deadline`)});if(r!==t)throw b(`stale-target`,`target-process-changed`,{pid:e.pid,generation:e.generation,expectedStartTime:t,observedStartTime:r})}async removeSession(e,t){this.sessions.get(e.udid)===e&&this.sessions.delete(e.udid),await this.dispose(e,t)}async dispose(e,t){e.socket?.destroy(),e.socket=void 0,t&&e.process.isAlive()&&(e.process.signal(`SIGTERM`),await H(e.process,500),e.process.isAlive()&&(e.process.signal(`SIGKILL`),await H(e.process,500))),await this.host.remove(e.socketPath)}};async function Pe(e,t){let n=S(t,`bridge-request-deadline`);await Promise.race([e,C(t,n,`bridge-request-deadline`).then(()=>{throw b(`timeout`,`bridge-request-deadline`)})])}function Fe(e,t,n){return(e.failureKind===`cancelled`||e.failureKind===`timeout`)&&(e.details?.dispatched===!0||n!==t)}async function H(e,t){await Promise.race([e.wait.catch(()=>void 0),new Promise(e=>setTimeout(e,t))])}const U=16777216,W=12e4,G=1e4,Ie=Object.freeze({maxRequestBytes:65536,maxResponseBytes:4194304,maxNodes:1500,maxTraversalDepth:64,maxDurationMs:5e3});function Le(e){let n={...Ie,...e??{}};for(let[e,r]of Object.entries(n))if(!Number.isSafeInteger(r)||r<=0)throw new t(`INVALID_ARGS`,`Snapshot source limit ${e} must be a positive integer`,{name:e,value:r});if(n.maxRequestBytes>n.maxResponseBytes)throw new t(`INVALID_ARGS`,`Snapshot source request bytes cannot exceed response bytes`,{maxRequestBytes:n.maxRequestBytes,maxResponseBytes:n.maxResponseBytes});if(n.maxRequestBytes>U||n.maxResponseBytes>U)throw new t(`INVALID_ARGS`,`Snapshot source frame limits exceed the bridge bound`,{maxRequestBytes:n.maxRequestBytes,maxResponseBytes:n.maxResponseBytes,maximumFrameBytes:U});if(n.maxNodes>G||n.maxTraversalDepth>128)throw new t(`INVALID_ARGS`,`Snapshot source tree limits exceed the bridge bound`,{maxNodes:n.maxNodes,maxTraversalDepth:n.maxTraversalDepth,maximumNodes:G,maximumDepth:128});if(n.maxDurationMs>W)throw new t(`INVALID_ARGS`,`Snapshot source duration exceeds the bridge bound`,{maxDurationMs:n.maxDurationMs,maximumDurationMs:W});if(n.maxRequestBytes<=4||n.maxResponseBytes<=4)throw new t(`INVALID_ARGS`,`Snapshot source frame limits must leave room for a body`,{maxRequestBytes:n.maxRequestBytes,maxResponseBytes:n.maxResponseBytes});return Object.freeze(n)}const K=Object.freeze({elementType:`XC_kAXXCAttributeElementType`,elementBaseType:`XC_kAXXCAttributeElementBaseType`,label:`XC_kAXXCAttributeLabel`,value:`XC_kAXXCAttributeValue`,identifier:`XC_kAXXCAttributeIdentifier`,frame:`XC_kAXXCAttributeFrame`,automationType:`XC_kAXXCAttributeAutomationType`,children:`XC_kAXXCAttributeChildren`}),q=`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(`.`),J={UIApplication:`Application`,UIWindow:`Window`},Re=new Set(Object.values(K));function ze(e,t,n){let r=Array.isArray(e)?e:[e];if(r.length===0||r.some(e=>!P(e)))throw b(`malformed-tree`,`guest-tree-root-invalid`);let i=[],a=[],o=0;for(let e of r)c(e,void 0,0,!1);if(i.length>n.maxNodes)throw b(`malformed-tree`,`node-limit-exceeded`,{nodeCount:i.length,maxNodes:n.maxNodes});if(o>n.maxTraversalDepth)throw b(`malformed-tree`,`traversal-depth-exceeded`,{maxTraversalDepth:o,maxAllowedDepth:n.maxTraversalDepth});if(typeof t.truncated!=`boolean`)throw b(`malformed-tree`,`truncated-invalid`);let s=We(i.find(e=>e.type===`Application`||e.type===`Window`));return{nodes:i,maxTraversalDepth:o,viewport:s,opaqueRemoteElements:a.filter(e=>He(e,s)).length};function c(e,t,r,s){if(i.length>=n.maxNodes)throw b(`malformed-tree`,`node-limit-exceeded`,{maxNodes:n.maxNodes});for(let t of Object.keys(e))if(!Re.has(t))throw b(`malformed-tree`,`node-contains-unknown-field`,{key:t});let l=e[K.children];if(!Array.isArray(l))throw b(`malformed-tree`,`children-invalid`);let u=i.length,d=Be(e,u,t,r);i.push(d),o=Math.max(o,r),Ve(d,l.length,s)&&a.push(d.rect);let f=s||d.type===`WebView`;for(let e of l){if(!P(e))throw b(`malformed-tree`,`child-invalid`);c(e,u,r+1,f)}}}function Be(e,t,n,r){let i=X(e[K.elementType]),a=X(e[K.elementBaseType]),o=Ge(e[K.automationType]),s=Ue(e[K.frame]);return{index:t,...n===void 0?{}:{parentIndex:n},...Y(i,o)?{type:Y(i,o)}:{},...i?{role:i}:{},...a&&a!==i?{subrole:a}:{},...X(e[K.label])?{label:X(e[K.label])}:{},...Z(e[K.value])?{value:Z(e[K.value])}:{},...X(e[K.identifier])?{identifier:X(e[K.identifier])}:{},...s?{rect:s}:{},depth:r}}function Y(e,t){if(e!==void 0&&J[e])return J[e];if(e!==void 0&&q.includes(e))return e;if(t!==void 0)return q[t]??`Other`}function Ve(e,t,n){return n&&e.role===`AXRemoteElement`&&t===0}function He(e,t){return e===void 0?!0:n(e)?t.kind!==`reported`||r(e,t.rect):!1}function Ue(e){if(e===void 0)return;if(!P(e))throw b(`malformed-tree`,`frame-invalid`);let t=[`X`,`Y`,`Width`,`Height`].map(t=>e[t]);if(!t.every(e=>typeof e==`number`&&Number.isFinite(e)))throw b(`malformed-tree`,`frame-invalid`);let[n,r,i,a]=t;if(i<0||a<0)throw b(`malformed-tree`,`frame-invalid`);return{x:n,y:r,width:i,height:a}}function We(e){return!e||e.type!==`Application`&&e.type!==`Window`?{kind:`missing`,reason:`not-provided`}:n(e.rect)?{kind:`reported`,rect:e.rect}:{kind:`missing`,reason:e.rect?`invalid`:`not-provided`}}function X(e){return typeof e==`string`&&e.length>0?e:void 0}function Z(e){if(typeof e==`string`)return e.length>0?e:void 0;if(typeof e==`number`||typeof e==`boolean`)return String(e);if(e!=null)throw b(`malformed-tree`,`scalar-invalid`)}function Ge(e){if(e!=null){if(!Number.isSafeInteger(e))throw b(`malformed-tree`,`automation-type-invalid`);return e}}const Q=`simulator-ax-bridge`;function Ke(e={}){let t=e.host??Ee(),n=new Ne(t),r=new Te,i=new Map,a=!1,o=async n=>{if(a)throw b(`unsupported`,`source-closed`);let r=i.get(n.runtime);if(r)return r;let o=await t.withDiagnosticTimer(`ios.snapshot-source.prepare`,async()=>await xe({host:t,runtime:n.runtime,limits:n.limits,deadline:n.deadline,sourceRoot:e.sourceRoot,cacheRoot:e.cacheRoot}),{producer:Q});return i.set(n.runtime,o),o};return{acquire:async i=>{try{if(a)throw b(`unsupported`,`source-closed`);qe(i);let s=Le({...e.limits,...i.limits}),c=pe(s.maxDurationMs,i.signal),l=Ye(i.hint,s.maxTraversalDepth),u=l+1,d=i.hint.rawTraversalDepth!==null;return await t.withDiagnosticTimer(`ios.snapshot-source.acquire`,async()=>{let e=await o({runtime:i.target.runtime,limits:s,deadline:c}),a=r.consume(i.target,u,d),f=await n.request({target:i.target,bridge:e,limits:s,maxDepth:l,nativeLevelsHint:a.nativeLevels,deadline:c});S(c,`snapshot-decode-deadline`);let p=Xe(i.hint,i.target,f,s,l);return Je(t,r,i.target,u,d,a,f),{stage:`acquired`,acquisition:p}},{producer:Q})}catch(e){let t=x(e);return{stage:`failed`,failure:{kind:t.failureKind,code:t.failureCode,...t.details?{details:t.details}:{}}}}},close:async()=>{a||(a=!0,await n.close())}}}function qe(e){if(!e.target.udid.trim()||!e.target.runtime.trim()||!e.target.generation.trim()||!Number.isSafeInteger(e.target.pid)||e.target.pid<=0)throw new t(`INVALID_ARGS`,`Simulator snapshot source target identity is incomplete`);let n=e.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 t(`INVALID_ARGS`,`Simulator snapshot source capture hint is invalid`)}function Je(e,t,n,r,i,a,o){let s=ye(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 Ye(e,n){let r=e.rawTraversalDepth??n;if(r>n)throw new t(`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 Xe(e,t,n,r,i){if(n.automationEnabled!==!0)throw b(`unsupported`,`automation-mode-unavailable`);let a=n.tree,o=n.truncated;if(typeof o!=`boolean`)throw b(`malformed-tree`,`truncated-invalid`);let s=ze(a,{truncated:o},r),c=n.generation;if(typeof c!=`string`||!c)throw b(`malformed-tree`,`generation-invalid`);if(s.opaqueRemoteElements>0)throw b(`unsupported`,`remote-content-boundary`,{remoteElements:s.opaqueRemoteElements});let l=Object.freeze(s.nodes.map(e=>Object.freeze({...e,pid:t.pid}))),u=Ze(e,o,s,r,i,l.length),d=Object.freeze({...t.targetId?{targetId:t.targetId}:{},generation:c}),f={producer:Q,nodes:l,truncated:o,viewport:s.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 Ze(e,t,n,r,i,a){return Object.freeze([{kind:`unavailable-fact`,fact:`hittability`},...e.interactiveOnly?[{kind:`unavailable-fact`,fact:`interactive-query`}]:[],...t?[Qe(n.maxTraversalDepth,a,r,i)]:[],...n.viewport.kind===`missing`?[{kind:`missing-viewport`,reason:n.viewport.reason}]:[]])}function Qe(e,t,n,r){return t>=n.maxNodes?{kind:`truncated`,dimension:`nodes`,limit:n.maxNodes}:e>=r?{kind:`truncated`,dimension:`depth`,limit:r}:{kind:`truncated`,dimension:`payload`,limit:n.maxResponseBytes}}export{Ke as createSimulatorSnapshotSource};
@@ -1,2 +1,2 @@
1
- import{y as e}from"./sdk-contracts.js";import{a as t,r as n}from"./adb-host.js";import{n as r,s as i}from"./adb-failure.js";import a from"node:path";import{AsyncLocalStorage as o}from"node:async_hooks";const s=new WeakSet;function c(e){return l(typeof e==`function`?{exec:e}:e)}function l(e){if(s.has(e))return e;let t={...e,exec:i(u(e.exec)),...e.pull?{pull:i(u(e.pull))}:{},...e.install?{install:i(u(e.install))}:{},...e.installBundle?{installBundle:i(e.installBundle)}:{}};return s.add(t),t}function u(e){return async(...t)=>n().coerceAdbResult(await e(...t))}const d=new WeakSet;function f(t){let n=c(t);if(n.reverse&&d.has(n.reverse))return n.reverse;let r=n.reverse??p(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 p(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,i){let a=await e([`reverse`,`--remove`,n],{allowFailure:!0,signal:i?.signal,timeoutMs:i?.timeoutMs});if(a.exitCode!==0&&!h(a.stdout,a.stderr))throw r(`Failed to remove Android port reverse ${n}`,a,{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?m(r.stdout,t):[]}}}function m(e,t){let n=new Map;for(let[e,r]of t)for(let t of r)n.set(t,e);return e.split(`
1
+ import{C as e}from"./sdk-contracts.js";import{a as t,r as n}from"./adb-host.js";import{n as r,s as i}from"./adb-failure.js";import a from"node:path";import{AsyncLocalStorage as o}from"node:async_hooks";const s=new WeakSet;function c(e){return l(typeof e==`function`?{exec:e}:e)}function l(e){if(s.has(e))return e;let t={...e,exec:i(u(e.exec)),...e.pull?{pull:i(u(e.pull))}:{},...e.install?{install:i(u(e.install))}:{},...e.installBundle?{installBundle:i(e.installBundle)}:{}};return s.add(t),t}function u(e){return async(...t)=>n().coerceAdbResult(await e(...t))}const d=new WeakSet;function f(t){let n=c(t);if(n.reverse&&d.has(n.reverse))return n.reverse;let r=n.reverse??p(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 p(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,i){let a=await e([`reverse`,`--remove`,n],{allowFailure:!0,signal:i?.signal,timeoutMs:i?.timeoutMs});if(a.exitCode!==0&&!h(a.stdout,a.stderr))throw r(`Failed to remove Android port reverse ${n}`,a,{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?m(r.stdout,t):[]}}}function m(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 h(e,t){let n=`${e}\n${t}`.toLowerCase();return n.includes(`listener`)&&n.includes(`not found`)}function g(e){let{replace:t,allowTestPackages:n,allowDowngrade:r,grantPermissions:i,...a}=e??{},o=[];return t&&o.push(`-r`),n&&o.push(`-t`),r&&o.push(`-d`),i&&o.push(`-g`),{installArgs:o,execOptions:a}}const _=new o;function v(e,t={}){return y(e.id,t.serverPort)}function y(e,t){return i(async(r,i)=>{let a=N(e,t);return await n().execSerialAdb(e,r,a===void 0?i:{...i,serverPort:a})})}function b(e,t){return(r,i)=>{let a=N(e,t);return n().spawnSerialAdb(e,r,a===void 0?i:{...i,serverPort:a})}}function x(e,t={}){let n=v(e,t);return{exec:n,spawn:b(e.id,t.serverPort),reverse:p(n),pull:async(e,t,r)=>await n([`pull`,e,t],r),install:async(e,t)=>{let{installArgs:r,execOptions:i}=g(t);return await n([`install`,...r,e],i)}}}function S(e,t){let n=j(e);return t||(n?.serial===e.id?n.provider.exec:v(e))}function C(e,t){let n=j(e);return t?c(t):n?.serial===e.id?c(n.provider):x(e)}function w(e){let t=j(e);return t?.serial===e.id?{mode:`transport-composed`,...t.provider.spawn?{spawn:t.provider.spawn}:{}}:{mode:`local`}}function T(e){let t=j(e);return t?.serial===e.id?t.provider.text:void 0}function E(e){let t=j(e);return t?.serial===e.id&&t.provider.touch?t.provider:void 0}function D(e,t){if(t)return c(t);if(e)return C(e);let n=_.getStore();if(n)return c(n.provider)}async function O(e,r,i){if(!e)return await i();let a={provider:c(e),serial:r.serial,...r.serverPort===void 0?{}:{serverPort:r.serverPort}},o=k(a),s=async()=>await _.run(a,async()=>await n().withAdbCommandExecutorOverride(o,i));return r.serverPort===void 0?await s():await t(A(a),s)}function k(e){return(t,r,i)=>{if(!P(t)||e.serverPort===void 0&&t!==`adb`)return;let a=F(r);if(M(e,a),!(a&&a!==e.serial)){if(a===e.serial){let t=L(r,e.serial);return t?n().withoutAdbCommandExecutorOverride(async()=>await e.provider.exec(t,i)):void 0}if(e.serverPort!==void 0)return n().withoutAdbCommandExecutorOverride(async()=>await n().execHostAdb([`-s`,e.serial,...r],{...i,allowFailure:!0,serverPort:e.serverPort}))}}}function A(e){return async(t,r)=>{let i=F(t);M(e,i);let a=n();return await a.withoutAdbCommandExecutorOverride(async()=>await a.execHostAdb(i===void 0?[`-s`,e.serial,...t]:t,{...r,allowFailure:!0,serverPort:e.serverPort}))}}function j(e){let t=_.getStore();return M(t,e.id),t}function M(t,n){if(t?.serverPort!==void 0&&n!==void 0&&n!==t.serial)throw new e(`COMMAND_FAILED`,`Managed ADB transport cannot address another device.`,{reason:`managed-device-transport-mismatch`})}function N(t,n){let r=_.getStore();if(M(r,t),r?.serverPort===void 0)return n;if(n!==void 0&&n!==r.serverPort)throw new e(`COMMAND_FAILED`,`Managed ADB transport cannot select another server.`,{reason:`managed-device-transport-mismatch`});return r.serverPort}function P(e){return a.basename(e).replace(/\.(?:com|exe|bat|cmd)$/i,``)===`adb`}function F(e){let t=I(e);return t===void 0?void 0:e[t+1]}function I(e){let t=0;for(;t<e.length;){let n=e[t];if(n===`-s`)return t;if(n===`-P`||n===`-H`||n===`-L`){t+=2;continue}if(n===`-a`||n===`-d`||n===`-e`){t+=1;continue}return}}function L(e,t){let n=I(e);if(n!==void 0&&e[n+1]===t)return[...e.slice(0,n),...e.slice(n+2)]}async function R(t,r,i){let{device:a,provider:o,...s}=i??{},c=D(a,o),l=c?.pull,u=n();if(l)return await u.withoutAdbCommandExecutorOverride(async()=>await l(t,r,s));let d=c?.exec;if(!d)throw new e(`COMMAND_FAILED`,`Android adb pull requires an adb provider`);return await u.withoutAdbCommandExecutorOverride(async()=>await d([`pull`,t,r],s))}async function z(t,r){let{device:i,provider:a,...o}=r??{},s=D(i,a),c=s?.install,l=n();if(c)return await l.withoutAdbCommandExecutorOverride(async()=>await c(t,o));let u=s?.exec;if(!u)throw new e(`COMMAND_FAILED`,`Android adb install requires an adb provider`);let{installArgs:d,execOptions:f}=g(o);return await l.withoutAdbCommandExecutorOverride(async()=>await u([`install`,...d,t],f))}export{S as a,E as c,f as d,x as i,w as l,R as n,C as o,v as r,T as s,z as t,O as u};
@@ -1 +1 @@
1
- import{r as e}from"./rolldown-runtime.js";import{y as t}from"./sdk-contracts.js";var n=e({androidAdbResultError:()=>c,androidDiscoveryCommandError:()=>u,attachAdbFailureHint:()=>o,attachAndroidDiscoveryTimeout:()=>d,classifyAndroidAdbFailure:()=>a,withAdbFailureHints:()=>l});const r=[[/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]],i=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 a(e,t=``){let n=e.toLowerCase(),i=t.toLowerCase();for(let[e,t,a]of r)if(e.test(n)||a&&e.test(i))return t}function o(e){if(!(e instanceof t)||e.code!==`COMMAND_FAILED`)return e;let n=s(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 s(e){return typeof e.details?.timeoutMs==`number`?i:a(typeof e.details?.stderr==`string`?e.details.stderr:``,typeof e.details?.stdout==`string`?e.details.stdout:``)}function c(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 o(new t(`COMMAND_FAILED`,e,i))}function l(e){return async(...t)=>{try{return await e(...t)}catch(e){throw o(e)}}}function u(e,n,r){let i=a(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 d(e){return!(e instanceof t)||e.code!==`COMMAND_FAILED`||typeof e.details?.timeoutMs!=`number`||(e.details={...e.details,adbFailure:i.reason,...typeof e.details.hint==`string`?{}:{hint:i.hint}}),e}export{d as a,o as i,c as n,a as o,u as r,l as s,n as t};
1
+ import{r as e}from"./rolldown-runtime.js";import{C as t}from"./sdk-contracts.js";var n=e({androidAdbResultError:()=>c,androidDiscoveryCommandError:()=>u,attachAdbFailureHint:()=>o,attachAndroidDiscoveryTimeout:()=>d,classifyAndroidAdbFailure:()=>a,withAdbFailureHints:()=>l});const r=[[/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]],i=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 a(e,t=``){let n=e.toLowerCase(),i=t.toLowerCase();for(let[e,t,a]of r)if(e.test(n)||a&&e.test(i))return t}function o(e){if(!(e instanceof t)||e.code!==`COMMAND_FAILED`)return e;let n=s(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 s(e){return typeof e.details?.timeoutMs==`number`?i:a(typeof e.details?.stderr==`string`?e.details.stderr:``,typeof e.details?.stdout==`string`?e.details.stdout:``)}function c(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 o(new t(`COMMAND_FAILED`,e,i))}function l(e){return async(...t)=>{try{return await e(...t)}catch(e){throw o(e)}}}function u(e,n,r){let i=a(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 d(e){return!(e instanceof t)||e.code!==`COMMAND_FAILED`||typeof e.details?.timeoutMs!=`number`||(e.details={...e.details,adbFailure:i.reason,...typeof e.details.hint==`string`?{}:{hint:i.hint}}),e}export{d as a,o as i,c as n,a as o,u as r,l as s,n as t};
@@ -1 +1 @@
1
- import{r as e}from"./rolldown-runtime.js";import{nr as t}from"./sdk-batch.js";import{b as n,f as r,g as i,o as a,y as o}from"./owner-identity.js";import{h as s}from"./exec.js";import"./command.js";import"./process.js";import c from"node:path";import l from"node:crypto";var u=e({agentBrowserChromeLaunchMarker:()=>d,appendAgentDeviceChromeArgs:()=>f,inspectManagedAgentBrowserProcesses:()=>_,matchAgentBrowserChromeProcess:()=>p,recordManagedAgentBrowserProcesses:()=>v,summarizeAgentBrowserProcesses:()=>m,summarizeManagedAgentBrowserProcesses:()=>g});function d(e){let t=l.createHash(`sha256`);return t.update(c.resolve(e.stateDir)),t.update(`\0`),t.update(c.resolve(e.installDir)),`--agent-device-managed-web=${t.digest(`hex`).slice(0,16)}`}function f(e,t){let n=d(t),r=e?.trim();return r?x(r).includes(n)?r:`${r},${n}`:n}function p(e,t){if(!(e.pid===r()||!S(e.command))){if(e.command.includes(d(t)))return{process:e,reason:`launch-marker`};if(w(t).some(t=>T(e,t)))return{process:e,reason:`managed-browser-home`}}}function m(e,t){return b(e,e=>p(e,t))}function h(e,t){return p(e,t)??C(e,t)}function g(e,t){return b(e,e=>h(e,t))}async function _(e){return m(await y(),e)}async function v(e,t){let r=await y(),i=g(r,e),s=a(i.pids,r),c={count:s.length,pids:s.map(({pid:e})=>e),processes:s.map(t=>({process:t,reason:h(t,e)?.reason??`descendant`}))},l=c.processes.flatMap(({process:e})=>{let t=n(e.pid),r=o(e.pid);return t&&r?[{pid:e.pid,startTime:t,command:r,purpose:`managed-web-browser`}]:[]});return l.length>0&&t.replace({kind:`daemon`},l),c}async function y(){return await s(async()=>await i({timeoutMs:1500}))}function b(e,t){let n=e.flatMap(e=>{let n=t(e);return n?[n]:[]});return{count:n.length,pids:n.map(e=>e.process.pid),processes:n}}function x(e){return e.split(/[,\n]/).map(e=>e.trim()).filter(Boolean)}function S(e){return/\b(?:Google Chrome for Testing|Chrome for Testing|Chromium|chrome|chrome\.exe|chromium|chromium-browser|headless_shell)\b/i.test(e)}function C(e,t){if(e.pid===r()||S(e.command))return;let n=E(e.command),i=E(c.resolve(t.installDir));return n.includes(`${i}/`)?{process:e,reason:`agent-browser-daemon`}:void 0}function w(e){return t([c.join(e.homeDir,`.agent-browser`,`browsers`),c.join(e.runtimeHomeDir,`.agent-browser`,`browsers`)])}function T(e,t){let n=E(e.command),r=`${E(c.resolve(t)).replace(/\/+$/,``)}/`;return n.includes(r)}function E(e){return e.replaceAll(`\\`,`/`)}export{v as i,f as n,_ as r,u as t};
1
+ import{r as e}from"./rolldown-runtime.js";import{nr as t}from"./sdk-batch.js";import{b as n,f as r,g as i,o as a,y as o}from"./owner-identity.js";import{g as s}from"./exec.js";import"./command.js";import"./process.js";import c from"node:path";import l from"node:crypto";var u=e({agentBrowserChromeLaunchMarker:()=>d,appendAgentDeviceChromeArgs:()=>f,inspectManagedAgentBrowserProcesses:()=>_,matchAgentBrowserChromeProcess:()=>p,recordManagedAgentBrowserProcesses:()=>v,summarizeAgentBrowserProcesses:()=>m,summarizeManagedAgentBrowserProcesses:()=>g});function d(e){let t=l.createHash(`sha256`);return t.update(c.resolve(e.stateDir)),t.update(`\0`),t.update(c.resolve(e.installDir)),`--agent-device-managed-web=${t.digest(`hex`).slice(0,16)}`}function f(e,t){let n=d(t),r=e?.trim();return r?x(r).includes(n)?r:`${r},${n}`:n}function p(e,t){if(!(e.pid===r()||!S(e.command))){if(e.command.includes(d(t)))return{process:e,reason:`launch-marker`};if(w(t).some(t=>T(e,t)))return{process:e,reason:`managed-browser-home`}}}function m(e,t){return b(e,e=>p(e,t))}function h(e,t){return p(e,t)??C(e,t)}function g(e,t){return b(e,e=>h(e,t))}async function _(e){return m(await y(),e)}async function v(e,t){let r=await y(),i=g(r,e),s=a(i.pids,r),c={count:s.length,pids:s.map(({pid:e})=>e),processes:s.map(t=>({process:t,reason:h(t,e)?.reason??`descendant`}))},l=c.processes.flatMap(({process:e})=>{let t=n(e.pid),r=o(e.pid);return t&&r?[{pid:e.pid,startTime:t,command:r,purpose:`managed-web-browser`}]:[]});return l.length>0&&t.replace({kind:`daemon`},l),c}async function y(){return await s(async()=>await i({timeoutMs:1500}))}function b(e,t){let n=e.flatMap(e=>{let n=t(e);return n?[n]:[]});return{count:n.length,pids:n.map(e=>e.process.pid),processes:n}}function x(e){return e.split(/[,\n]/).map(e=>e.trim()).filter(Boolean)}function S(e){return/\b(?:Google Chrome for Testing|Chrome for Testing|Chromium|chrome|chrome\.exe|chromium|chromium-browser|headless_shell)\b/i.test(e)}function C(e,t){if(e.pid===r()||S(e.command))return;let n=E(e.command),i=E(c.resolve(t.installDir));return n.includes(`${i}/`)?{process:e,reason:`agent-browser-daemon`}:void 0}function w(e){return t([c.join(e.homeDir,`.agent-browser`,`browsers`),c.join(e.runtimeHomeDir,`.agent-browser`,`browsers`)])}function T(e,t){let n=E(e.command),r=`${E(c.resolve(t)).replace(/\/+$/,``)}/`;return n.includes(r)}function E(e){return e.replaceAll(`\\`,`/`)}export{v as i,f as n,_ as r,u as t};