agent-device 0.21.13 → 0.21.15

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 (298) hide show
  1. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.13.apk → agent-device-android-ime-helper-0.21.15.apk} +0 -0
  2. package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.15.apk.sha256 +1 -0
  3. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.13.manifest.json → agent-device-android-ime-helper-0.21.15.manifest.json} +4 -4
  4. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.15.apk +0 -0
  5. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.15.apk.sha256 +1 -0
  6. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.13.manifest.json → agent-device-android-snapshot-helper-0.21.15.manifest.json} +6 -6
  7. package/apple/snapshot-bridge/SnapshotBridgeRuntime.m +11 -1
  8. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +110 -2
  9. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.m +4 -2
  10. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerMainOwnedState.swift +27 -0
  11. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedTextEntry.h +8 -2
  12. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedTextEntry.m +26 -1
  13. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +12 -19
  14. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +59 -20
  15. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AlertObservation.swift +2 -3
  16. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandDispatch.swift +179 -91
  17. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +21 -24
  18. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +1 -1
  19. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+GestureExecution.swift +9 -13
  20. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +36 -49
  21. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+MainThreadWork.swift +11 -15
  22. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +136 -29
  23. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Navigation.swift +20 -21
  24. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+PrivateAXPresentation.swift +3 -0
  25. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScreenRecorder.swift +6 -5
  26. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollDragExecution.swift +12 -24
  27. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SequenceExecution.swift +22 -42
  28. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +15 -18
  29. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotAcquisition.swift +73 -31
  30. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +20 -11
  31. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCaptureTarget.swift +9 -7
  32. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotExecution.swift +5 -4
  33. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotTiming.swift +2 -2
  34. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedGesturePolicy.swift +51 -19
  35. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedInteraction.swift +5 -2
  36. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedTextEntry.swift +78 -10
  37. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +32 -2
  38. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryFocus.swift +7 -4
  39. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextTyping.swift +23 -0
  40. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Transport.swift +17 -10
  41. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TvRemote.swift +8 -9
  42. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TypeExecution.swift +9 -15
  43. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +12 -11
  44. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotCoordinateSpace.swift +16 -19
  45. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotGeometry.swift +24 -9
  46. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotModels.swift +66 -10
  47. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentationInvariant.swift +12 -10
  48. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentationProjection.swift +1 -0
  49. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotVisibilityFold.swift +27 -5
  50. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotVisibilityFoldProjection.swift +1 -0
  51. package/dist/src/adapter.js +1 -1
  52. package/dist/src/adb-executor.js +1 -1
  53. package/dist/src/adb-failure.js +1 -1
  54. package/dist/src/adb-transport.js +1 -1
  55. package/dist/src/agent-browser-provider.js +1 -1
  56. package/dist/src/agent-browser-tool.js +1 -1
  57. package/dist/src/agent-device-client.js +2 -2
  58. package/dist/src/ai-sdk.js +1 -1
  59. package/dist/src/alert-runtime.js +1 -1
  60. package/dist/src/android-adb.d.ts +1 -8
  61. package/dist/src/android-input-ownership.js +1 -1
  62. package/dist/src/android-snapshot-quality.js +1 -0
  63. package/dist/src/android-system-chrome.js +1 -1
  64. package/dist/src/android.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.js +1 -1
  68. package/dist/src/app-launch.js +1 -1
  69. package/dist/src/app-lifecycle.js +1 -1
  70. package/dist/src/app-lifecycle2.js +1 -1
  71. package/dist/src/app-log-files.js +1 -1
  72. package/dist/src/app-log-runtime2.js +1 -1
  73. package/dist/src/app-resolution.js +2 -2
  74. package/dist/src/apple-runner-platform.js +1 -1
  75. package/dist/src/application-lifecycle-interaction.js +1 -1
  76. package/dist/src/archive.js +1 -1
  77. package/dist/src/artifact-download.js +1 -1
  78. package/dist/src/auth-session.js +1 -1
  79. package/dist/src/auth.js +1 -1
  80. package/dist/src/backend-snapshot-options.js +1 -1
  81. package/dist/src/boot-diagnostics.js +1 -1
  82. package/dist/src/capture-disclosure.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 +2 -2
  86. package/dist/src/cli.js +4 -4
  87. package/dist/src/click-button.js +1 -1
  88. package/dist/src/client-metro.js +1 -1
  89. package/dist/src/client-types.d.ts +102 -95
  90. package/dist/src/clipboard-shell-response.js +1 -1
  91. package/dist/src/command-schema.js +1 -1
  92. package/dist/src/command-tools.js +3 -3
  93. package/dist/src/connection-runtime.js +1 -1
  94. package/dist/src/connection.js +1 -1
  95. package/dist/src/contracts.d.ts +1 -1
  96. package/dist/src/contracts.js +1 -1
  97. package/dist/src/daemon-client-lifecycle.js +1 -1
  98. package/dist/src/daemon.js +1 -1
  99. package/dist/src/debug-symbols-facade.js +1 -1
  100. package/dist/src/device-claim-rule.js +2 -2
  101. package/dist/src/device-input-state.d.ts +15 -2
  102. package/dist/src/device-inventory-context.js +1 -1
  103. package/dist/src/device-rotation.js +1 -1
  104. package/dist/src/device-selection-resolver.js +1 -1
  105. package/dist/src/device-session.js +1 -1
  106. package/dist/src/device-shell.js +1 -1
  107. package/dist/src/device2.js +1 -1
  108. package/dist/src/devicectl.js +1 -1
  109. package/dist/src/diagnostics.js +1 -1
  110. package/dist/src/dispatch-resolve.js +1 -1
  111. package/dist/src/doctor2.js +1 -1
  112. package/dist/src/engine-eval-script.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/format.js +1 -1
  118. package/dist/src/gesture-plan-types.d.ts +1 -1
  119. package/dist/src/gesture-plan.js +1 -1
  120. package/dist/src/gesture-runtime.js +1 -1
  121. package/dist/src/harmonyos.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 +7 -3
  126. package/dist/src/index.js +1 -1
  127. package/dist/src/input-actions.js +1 -1
  128. package/dist/src/input-actions2.js +1 -1
  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-operation-binding.js +1 -1
  136. package/dist/src/interactor.js +4 -4
  137. package/dist/src/interactor2.js +1 -1
  138. package/dist/src/interactors.js +1 -1
  139. package/dist/src/internal/bin.js +1 -1
  140. package/dist/src/internal/daemon.js +2 -2
  141. package/dist/src/internal/png-worker.js +1 -1
  142. package/dist/src/internal/run-script-http-child.js +1 -1
  143. package/dist/src/inventory.js +1 -1
  144. package/dist/src/inventory2.js +1 -1
  145. package/dist/src/inventory3.js +1 -1
  146. package/dist/src/inventory5.js +1 -1
  147. package/dist/src/ios-snapshot-acquisition.js +1 -1
  148. package/dist/src/ios-snapshot-engine.js +1 -0
  149. package/dist/src/ios-snapshot-runtime.js +1 -1
  150. package/dist/src/lease.js +1 -1
  151. package/dist/src/limrun-download-file.js +1 -1
  152. package/dist/src/limrun-runtime-dependencies.js +1 -1
  153. package/dist/src/limrun.d.ts +16 -3
  154. package/dist/src/linux.js +1 -1
  155. package/dist/src/location-coordinates.js +1 -1
  156. package/dist/src/managed-device-scope.js +1 -1
  157. package/dist/src/mechanics.js +17 -17
  158. package/dist/src/mobile-snapshot-semantics.js +1 -1
  159. package/dist/src/multitouch-support.js +1 -1
  160. package/dist/src/native-build-cache.js +1 -0
  161. package/dist/src/observation.js +1 -1
  162. package/dist/src/overlay.js +3 -0
  163. package/dist/src/parameterized-recorded-fill.js +1 -1
  164. package/dist/src/perf-facade.js +1 -1
  165. package/dist/src/perf-runtime-operation-builder.js +1 -1
  166. package/dist/src/perf-runtime-plan.js +1 -1
  167. package/dist/src/perf-target.js +2 -2
  168. package/dist/src/perf.js +1 -1
  169. package/dist/src/physical-device-control.js +1 -1
  170. package/dist/src/platform-runtime-host.js +1 -1
  171. package/dist/src/platform-runtime-managed-owner.js +1 -1
  172. package/dist/src/platform-runtime-open-target.js +1 -1
  173. package/dist/src/platform-runtime-operation-host.js +4 -4
  174. package/dist/src/platform-runtime-runtime-hints.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-screen-recording-process-host.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-crop-bytes.js +1 -1
  181. package/dist/src/png-size.js +1 -1
  182. package/dist/src/png-worker-client.js +1 -1
  183. package/dist/src/png.js +1 -1
  184. package/dist/src/prepare-kind.js +1 -1
  185. package/dist/src/provider-session-ownership.js +1 -1
  186. package/dist/src/provider-webdriver.js +1 -1
  187. package/dist/src/proxy.js +1 -1
  188. package/dist/src/quality-warnings.js +1 -1
  189. package/dist/src/react-native.js +1 -1
  190. package/dist/src/record-runtime.js +1 -1
  191. package/dist/src/recording.js +1 -1
  192. package/dist/src/rect-center.js +1 -1
  193. package/dist/src/register-builtins.js +1 -1
  194. package/dist/src/registry.js +36 -36
  195. package/dist/src/remote-config2.js +1 -1
  196. package/dist/src/replay-divergence.js +1 -1
  197. package/dist/src/replay.js +1 -1
  198. package/dist/src/reporting.js +1 -1
  199. package/dist/src/request-admission.js +1 -1
  200. package/dist/src/request-cancel.js +1 -1
  201. package/dist/src/request-runtime-binding.js +1 -1
  202. package/dist/src/retry.js +1 -1
  203. package/dist/src/runner-cache-metadata.js +1 -1
  204. package/dist/src/runner-client.js +1 -1
  205. package/dist/src/runner-dev-tools-security.js +1 -1
  206. package/dist/src/runner-device-readiness.js +1 -1
  207. package/dist/src/runner-disposal.js +1 -1
  208. package/dist/src/runner-error-classification.js +1 -1
  209. package/dist/src/runner.js +1 -1
  210. package/dist/src/runtime-transport-hints.js +1 -1
  211. package/dist/src/runtime.js +1 -3
  212. package/dist/src/runtime10.js +2 -2
  213. package/dist/src/runtime2.js +4 -4
  214. package/dist/src/runtime3.js +1 -1
  215. package/dist/src/runtime4.js +5 -5
  216. package/dist/src/runtime5.js +1 -1
  217. package/dist/src/runtime6.js +1 -1
  218. package/dist/src/runtime7.js +1 -1
  219. package/dist/src/runtime8.js +1 -1
  220. package/dist/src/runtime9.js +1 -1
  221. package/dist/src/screen-recording-admission-ledger.js +1 -1
  222. package/dist/src/screen-recording-completion.js +1 -1
  223. package/dist/src/screen-recording-options.js +1 -1
  224. package/dist/src/screen-recording-resource-recovery.js +1 -1
  225. package/dist/src/screenshot-density.js +1 -1
  226. package/dist/src/screenshot-image.js +1 -1
  227. package/dist/src/screenshot-overlay-draw.js +1 -1
  228. package/dist/src/screenshot-runtime.js +1 -1
  229. package/dist/src/screenshot.js +1 -1
  230. package/dist/src/screenshot3.js +1 -1
  231. package/dist/src/script.js +1 -1
  232. package/dist/src/scroll-command.d.ts +13 -6
  233. package/dist/src/scroll-command.js +1 -1
  234. package/dist/src/scroll-gesture.js +1 -1
  235. package/dist/src/sdk-batch-runner.js +2 -2
  236. package/dist/src/sdk-batch.js +2 -2
  237. package/dist/src/sdk-contracts.d.ts +59 -12
  238. package/dist/src/sdk-contracts.js +2 -2
  239. package/dist/src/sdk-device.js +1 -1
  240. package/dist/src/sdk-finders.d.ts +1 -1
  241. package/dist/src/sdk-io.js +1 -1
  242. package/dist/src/sdk-remote-config.js +1 -1
  243. package/dist/src/sdk-selectors.d.ts +1 -1
  244. package/dist/src/selection.js +0 -0
  245. package/dist/src/selector-runtime.js +1 -1
  246. package/dist/src/server.js +1 -1
  247. package/dist/src/session-allocation.js +1 -1
  248. package/dist/src/session-routing.js +1 -1
  249. package/dist/src/session-runtime-admission.js +1 -1
  250. package/dist/src/session-snapshot.js +1 -1
  251. package/dist/src/session-store.js +1 -1
  252. package/dist/src/session.js +1 -1
  253. package/dist/src/session2.js +4 -4
  254. package/dist/src/settings.js +1 -1
  255. package/dist/src/settings2.js +1 -0
  256. package/dist/src/simctl.js +1 -1
  257. package/dist/src/simulator-state.js +1 -1
  258. package/dist/src/simulator.js +1 -1
  259. package/dist/src/snapshot-capture-annotations.js +1 -1
  260. package/dist/src/snapshot-desktop-projection.js +1 -1
  261. package/dist/src/snapshot-runtime-binding.js +1 -1
  262. package/dist/src/snapshot-runtime.js +1 -1
  263. package/dist/src/snapshot-state.js +1 -1
  264. package/dist/src/snapshot2.js +1 -1
  265. package/dist/src/snapshot3.js +1 -1
  266. package/dist/src/snapshot4.js +1 -1
  267. package/dist/src/src.js +1 -1
  268. package/dist/src/src4.js +1 -1
  269. package/dist/src/src7.js +1 -1
  270. package/dist/src/src8.js +1 -1
  271. package/dist/src/string-enum.js +1 -1
  272. package/dist/src/surface-snapshot.js +1 -1
  273. package/dist/src/takeover.js +1 -1
  274. package/dist/src/text-entry-focus.js +1 -1
  275. package/dist/src/tool-provider-facade.js +1 -1
  276. package/dist/src/tool-provider.js +2 -2
  277. package/dist/src/tool-provider2.js +1 -1
  278. package/dist/src/touch-runtime.js +1 -1
  279. package/dist/src/transport.js +1 -1
  280. package/dist/src/tree.js +1 -1
  281. package/dist/src/tv-remote.js +1 -1
  282. package/dist/src/type-text-runtime.js +1 -1
  283. package/dist/src/verified-file.js +1 -1
  284. package/dist/src/video.js +1 -1
  285. package/dist/src/viewport.js +1 -1
  286. package/dist/src/web.js +1 -1
  287. package/dist/src/web2.js +1 -1
  288. package/dist/src/webdriver-source.js +1 -1
  289. package/package.json +1 -1
  290. package/server.json +2 -2
  291. package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.13.apk.sha256 +0 -1
  292. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.13.apk +0 -0
  293. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.13.apk.sha256 +0 -1
  294. package/dist/src/absence-observation-errors.js +0 -1
  295. package/dist/src/runner-presentation.js +0 -1
  296. package/dist/src/semantic-index.js +0 -1
  297. package/dist/src/snapshot-process.js +0 -1
  298. package/dist/src/snapshot-scope.js +0 -1
@@ -54,11 +54,7 @@ final class RunnerTests: XCTestCase {
54
54
  let commandExecutionQueue = DispatchQueue(label: "agent-device.runner.commands")
55
55
  let app = XCUIApplication()
56
56
  lazy var springboard = XCUIApplication(bundleIdentifier: Self.springboardBundleId)
57
-
58
-
59
- var currentApp: XCUIApplication?
60
- var currentBundleId: String?
61
- var currentAppProcessIdentifier: Int?
57
+ let mainOwned = RunnerMainOwnedState()
62
58
 
63
59
 
64
60
  var pendingTargetActivation: TargetActivationFactPayload?
@@ -68,7 +64,7 @@ final class RunnerTests: XCTestCase {
68
64
 
69
65
  var textEntryTapWitness: TextEntryTapWitness?
70
66
  let maxRequestBytes = 2 * 1024 * 1024
71
- let mainThreadExecutionTimeout: TimeInterval = 30
67
+ static let mainThreadExecutionTimeout: TimeInterval = 30
72
68
  let appExistenceTimeout: TimeInterval = 30
73
69
  let retryCooldown: TimeInterval = 0.2
74
70
  let postSnapshotInteractionDelay: TimeInterval = 0.2
@@ -83,27 +79,25 @@ final class RunnerTests: XCTestCase {
83
79
 
84
80
 
85
81
  let recordingFrameCaptureTimeout: TimeInterval = 1
86
- var needsPostSnapshotInteractionDelay = false
87
82
 
88
83
 
89
84
 
90
85
 
91
86
  var lastLoggedFastAppGuardLine: String?
92
87
  var lastLoggedGesturePolicyLines: [SynthesizedGesturePolicyKind: String] = [:]
93
- var runnerMarkerWriter: (String) -> Void = { NSLog("%@", $0) }
88
+ var runnerMarkerWriter: @MainActor (String) -> Void = { NSLog("%@", $0) }
94
89
 
95
90
 
96
91
 
97
92
 
98
93
  var firstInteractionReadyUptime: TimeInterval?
99
- var runnerAccessibilityHealth: RunnerAccessibilityHealth = .unknown
100
94
  var activeRecording: ScreenRecorder?
101
95
  let commandJournal = RunnerCommandJournal()
102
96
 
103
97
 
104
98
  let inFlightCommandLock = NSLock()
105
99
  var inFlightCommandIds: Set<String> = []
106
- var inFlightCommandWaiters: [String: [((data: Data, shouldFinish: Bool)) -> Void]] = [:]
100
+ var inFlightCommandWaiters: [String: [@Sendable ((data: Data, shouldFinish: Bool)) -> Void]] = [:]
107
101
 
108
102
 
109
103
 
@@ -206,6 +200,13 @@ final class RunnerTests: XCTestCase {
206
200
 
207
201
 
208
202
 
203
+
204
+
205
+
206
+
207
+
208
+
209
+
209
210
 
210
211
 
211
212
 
@@ -316,7 +317,7 @@ final class RunnerTests: XCTestCase {
316
317
  deadline: .now() + xctestIdleKeepaliveInterval,
317
318
  repeating: xctestIdleKeepaliveInterval
318
319
  )
319
- idleKeepaliveTimer.setEventHandler {
320
+ idleKeepaliveTimer.setEventHandler { @Sendable in
320
321
  NSLog("AGENT_DEVICE_RUNNER_IDLE_KEEPALIVE")
321
322
  }
322
323
  idleKeepaliveTimer.resume()
@@ -105,7 +105,7 @@ public enum CoordinateSpaceRotation {
105
105
 
106
106
  public enum SnapshotGeometrySpace: Equatable {
107
107
  case appOrientation
108
- case deviceNative(appFrame: CGRect, interfaceOrientation: Int)
108
+ case deviceNative(appFrame: SnapshotViewport.Box, interfaceOrientation: Int)
109
109
 
110
110
  public static let quarterTurnTolerance: Double = 1
111
111
 
@@ -116,22 +116,26 @@ public enum SnapshotGeometrySpace: Equatable {
116
116
  case .deviceNative(let appFrame, let interfaceOrientation):
117
117
  return CoordinateSpaceRotation.oriented(
118
118
  rect: reportedFrame,
119
- in: appFrame,
119
+ in: appFrame.rect,
120
120
  interfaceOrientation: interfaceOrientation
121
121
  )
122
122
  }
123
123
  }
124
124
 
125
+ /// Only a `.reported` viewport carries an orientation, so only it can anchor a rotation.
125
126
  public static func space(
126
127
  reportedBySurfaceHost isSurfaceHost: Bool,
127
128
  reportedFrame: CGRect,
128
129
  inheritedFrom inherited: SnapshotGeometrySpace,
129
- appFrame: CGRect,
130
- interfaceOrientation: Int
130
+ viewport: SnapshotViewport
131
131
  ) -> SnapshotGeometrySpace {
132
132
  guard isSurfaceHost else { return inherited }
133
- guard namesQuarterTurn(interfaceOrientation) else { return .appOrientation }
134
- guard isQuarterTurned(reportedFrame, relativeTo: appFrame) else { return .appOrientation }
133
+ guard case .reported(let appFrame, let interfaceOrientation) = viewport,
134
+ namesQuarterTurn(interfaceOrientation),
135
+ isQuarterTurned(reportedFrame, relativeTo: appFrame.rect)
136
+ else {
137
+ return .appOrientation
138
+ }
135
139
  return .deviceNative(appFrame: appFrame, interfaceOrientation: interfaceOrientation)
136
140
  }
137
141
 
@@ -145,7 +149,7 @@ public enum SnapshotGeometrySpace: Equatable {
145
149
  }
146
150
 
147
151
  private static func isQuarterTurned(_ frame: CGRect, relativeTo appFrame: CGRect) -> Bool {
148
- guard isPlottable(frame), isPlottable(appFrame),
152
+ guard SnapshotGeometry.isPositiveFinite(frame),
149
153
  abs(appFrame.width - appFrame.height) > quarterTurnTolerance
150
154
  else {
151
155
  return false
@@ -153,19 +157,12 @@ public enum SnapshotGeometrySpace: Equatable {
153
157
  return abs(frame.width - appFrame.height) <= quarterTurnTolerance
154
158
  && abs(frame.height - appFrame.width) <= quarterTurnTolerance
155
159
  }
156
-
157
- private static func isPlottable(_ frame: CGRect) -> Bool {
158
- frame.origin.x.isFinite && frame.origin.y.isFinite
159
- && frame.width.isFinite && frame.height.isFinite
160
- && frame.width > 0 && frame.height > 0
161
- }
162
160
  }
163
161
 
164
162
  extension SnapshotGeometrySpace {
165
163
  public static func normalized(
166
164
  nodes: [RawAXNode],
167
- viewport: CGRect,
168
- interfaceOrientation: Int
165
+ viewport: SnapshotViewport
169
166
  ) -> [RawAXNode] {
170
167
  let carriers = SnapshotVisibilityFold.visibilityExemptCarrierTypes
171
168
  var spaces = [SnapshotGeometrySpace](repeating: .appOrientation, count: nodes.count)
@@ -180,16 +177,16 @@ extension SnapshotGeometrySpace {
180
177
  ),
181
178
  reportedFrame: node.rect.cgRect,
182
179
  inheritedFrom: parentIndex.map { spaces[$0] } ?? .appOrientation,
183
- appFrame: viewport,
184
- interfaceOrientation: interfaceOrientation
180
+ viewport: viewport
185
181
  )
186
182
  spaces[position] = nodeSpace
187
183
  let frame = nodeSpace.orientedFrame(of: node.rect.cgRect)
188
184
  result.append(
189
185
  node.replacing(
190
186
  rect: SnapshotRect(frame),
191
- hittable: node.parentIndex != nil
192
- && SnapshotGeometry.isGeometricallyActionable(
187
+ hittable: node.parentIndex == nil
188
+ ? false
189
+ : SnapshotGeometry.isGeometricallyActionable(
193
190
  enabled: node.enabled,
194
191
  frame: frame,
195
192
  viewport: viewport
@@ -2,14 +2,26 @@ import Foundation
2
2
  import CoreGraphics
3
3
 
4
4
  public enum SnapshotGeometry {
5
+ /// Twin of `isPositiveFiniteRect` in `packages/kernel/src/rect.ts`, and the one place the
6
+ /// `hittable` rule asks whether a box may be plotted or measured (#2891). Three refusals, each
7
+ /// reachable by a different input: a non-finite component, a finite box wide enough to overflow
8
+ /// its own right or bottom edge, and `CGRect.infinite`, which is built of finite components and
9
+ /// finite extents and so is refused by identity alone.
10
+ public static func isPositiveFinite(_ rect: CGRect) -> Bool {
11
+ !rect.isInfinite
12
+ && rect.minX.isFinite && rect.minY.isFinite
13
+ && rect.maxX.isFinite && rect.maxY.isFinite
14
+ && rect.size.width > 0 && rect.size.height > 0
15
+ }
16
+
5
17
  public static func effectiveFrame(
6
18
  reportedFrame: CGRect,
7
- viewport: CGRect,
19
+ viewport: SnapshotViewport,
8
20
  ancestorClip: CGRect?
9
21
  ) -> CGRect {
10
22
  var frame = reportedFrame
11
- if !viewport.isInfinite {
12
- frame = clipped(frame, to: viewport)
23
+ if let box = viewport.rect {
24
+ frame = clipped(frame, to: box)
13
25
  }
14
26
  if let ancestorClip {
15
27
  frame = clipped(frame, to: ancestorClip)
@@ -34,15 +46,18 @@ public enum SnapshotGeometry {
34
46
  )
35
47
  }
36
48
 
49
+ /// The shared `hittable` predicate (#1933), twin of `isGeometricallyActionable` in
50
+ /// `packages/kernel/src/rect.ts`, with `CGRect.contains`'s half-open right and bottom edges.
51
+ /// `nil` when only containment is left to decide and the capture has no viewport box: the node's
52
+ /// `hittable` is then absent on the wire, as it is on the host bridge (#2891).
37
53
  public static func isGeometricallyActionable(
38
54
  enabled: Bool,
39
55
  frame: CGRect,
40
- viewport: CGRect
41
- ) -> Bool {
42
- guard enabled, !frame.isNull, !frame.isEmpty else { return false }
43
- if viewport.isInfinite { return true }
44
- let center = CGPoint(x: frame.midX, y: frame.midY)
45
- return viewport.contains(center)
56
+ viewport: SnapshotViewport
57
+ ) -> Bool? {
58
+ guard enabled, isPositiveFinite(frame) else { return false }
59
+ guard let box = viewport.rect else { return nil }
60
+ return box.contains(CGPoint(x: frame.midX, y: frame.midY))
46
61
  }
47
62
 
48
63
  private static func clipped(_ frame: CGRect, to clip: CGRect) -> CGRect {
@@ -34,11 +34,14 @@ public struct RawAXNode: Equatable {
34
34
  public let label: String?
35
35
  public let identifier: String?
36
36
  public let value: String?
37
+ /// The text a text field shows while empty (`placeholderValue`); `nil` for every other node.
38
+ public let placeholder: String?
37
39
  public var rect: SnapshotRect
38
40
  public let enabled: Bool
39
41
  public let focused: Bool?
40
42
  public let selected: Bool?
41
- public var hittable: Bool
43
+ /// Geometric actionability; `nil` when the capture has no viewport box to decide it against.
44
+ public var hittable: Bool?
42
45
  public let depth: Int
43
46
  public let parentIndex: Int?
44
47
  public let hiddenContentAbove: Bool?
@@ -51,11 +54,12 @@ public struct RawAXNode: Equatable {
51
54
  label: String?,
52
55
  identifier: String?,
53
56
  value: String?,
57
+ placeholder: String? = nil,
54
58
  rect: SnapshotRect,
55
59
  enabled: Bool,
56
60
  focused: Bool?,
57
61
  selected: Bool?,
58
- hittable: Bool,
62
+ hittable: Bool?,
59
63
  depth: Int,
60
64
  parentIndex: Int?,
61
65
  hiddenContentAbove: Bool?,
@@ -67,6 +71,7 @@ public struct RawAXNode: Equatable {
67
71
  self.label = label
68
72
  self.identifier = identifier
69
73
  self.value = value
74
+ self.placeholder = placeholder
70
75
  self.rect = rect
71
76
  self.enabled = enabled
72
77
  self.focused = focused
@@ -79,7 +84,7 @@ public struct RawAXNode: Equatable {
79
84
  self.actions = actions
80
85
  }
81
86
 
82
- func replacing(rect: SnapshotRect, hittable: Bool) -> RawAXNode {
87
+ func replacing(rect: SnapshotRect, hittable: Bool?) -> RawAXNode {
83
88
  var updated = self
84
89
  updated.rect = rect
85
90
  updated.hittable = hittable
@@ -153,15 +158,66 @@ public struct PresentationOptions: Equatable {
153
158
  }
154
159
  }
155
160
 
161
+ /// What a capture knows about the viewport hosting its tree: the three cases of the host's
162
+ /// `IosViewportEvidence` (#2891). No rectangle stands for "unknown".
163
+ public enum SnapshotViewport: Equatable {
164
+ /// A box that was checked on the way in. The initializer is the only gate: no caller, inside this
165
+ /// package or outside it, holds a `Box` whose rectangle `SnapshotGeometry.isPositiveFinite`
166
+ /// refuses, so a `.reported` case never needs re-checking what it was handed.
167
+ public struct Box: Equatable {
168
+ public let rect: CGRect
169
+
170
+ init?(checked rect: CGRect) {
171
+ guard SnapshotGeometry.isPositiveFinite(rect) else { return nil }
172
+ self.rect = rect
173
+ }
174
+ }
175
+
176
+ /// The platform's box for the app's surface, with the interface orientation read in the same hop.
177
+ /// Only this case can anchor a rotation (#2612).
178
+ case reported(Box, interfaceOrientation: Int)
179
+ /// A box the capture inferred from its own root element. It clips and contains, and carries no
180
+ /// orientation, so it cannot anchor a rotation.
181
+ case derived(Box)
182
+ case missing(reason: MissingReason)
183
+
184
+ public enum MissingReason: Equatable {
185
+ /// The read was skipped or raised.
186
+ case notProvided
187
+ /// The box read is one `SnapshotGeometry.isPositiveFinite` refuses.
188
+ case invalid
189
+ }
190
+
191
+ public var rect: CGRect? {
192
+ switch self {
193
+ case .reported(let box, _), .derived(let box):
194
+ return box.rect
195
+ case .missing:
196
+ return nil
197
+ }
198
+ }
199
+
200
+ public static func reported(
201
+ box: CGRect,
202
+ interfaceOrientation: Int = RunnerInterfaceOrientation.unknown
203
+ ) -> SnapshotViewport {
204
+ guard let checked = Box(checked: box) else { return .missing(reason: .invalid) }
205
+ return .reported(checked, interfaceOrientation: interfaceOrientation)
206
+ }
207
+
208
+ public static func derived(box: CGRect) -> SnapshotViewport {
209
+ guard let checked = Box(checked: box) else { return .missing(reason: .invalid) }
210
+ return .derived(checked)
211
+ }
212
+ }
213
+
156
214
  public struct SnapshotAcquisition {
157
215
  public let hint: CaptureHint
158
216
  public var nodes: [RawAXNode]
159
217
  public let truncated: Bool
160
218
  public let effectiveDepth: Int?
161
219
  public var customActions: SnapshotCustomActionCoverage?
162
- public let viewport: CGRect
163
- /// The app's interface orientation, consumed by the one `normalized` pass; `unknown` turns nothing.
164
- public let interfaceOrientation: Int
220
+ public let viewport: SnapshotViewport
165
221
 
166
222
  public init(
167
223
  hint: CaptureHint,
@@ -169,8 +225,7 @@ public struct SnapshotAcquisition {
169
225
  truncated: Bool,
170
226
  effectiveDepth: Int?,
171
227
  customActions: SnapshotCustomActionCoverage? = nil,
172
- viewport: CGRect,
173
- interfaceOrientation: Int = 0
228
+ viewport: SnapshotViewport
174
229
  ) {
175
230
  self.hint = hint
176
231
  self.nodes = nodes
@@ -178,7 +233,6 @@ public struct SnapshotAcquisition {
178
233
  self.effectiveDepth = effectiveDepth
179
234
  self.customActions = customActions
180
235
  self.viewport = viewport
181
- self.interfaceOrientation = interfaceOrientation
182
236
  }
183
237
 
184
238
  public func replacingNodes(_ nodes: [RawAXNode]) -> SnapshotAcquisition {
@@ -222,11 +276,12 @@ public struct PresentedNode: Codable, Equatable {
222
276
  public let label: String?
223
277
  public let identifier: String?
224
278
  public let value: String?
279
+ public let placeholder: String?
225
280
  public let rect: SnapshotRect
226
281
  public let enabled: Bool
227
282
  public let focused: Bool?
228
283
  public let selected: Bool?
229
- public let hittable: Bool
284
+ public let hittable: Bool?
230
285
  public let depth: Int
231
286
  public let parentIndex: Int?
232
287
  public let hiddenContentAbove: Bool?
@@ -245,6 +300,7 @@ public struct PresentedNode: Codable, Equatable {
245
300
  self.label = raw.label
246
301
  self.identifier = raw.identifier
247
302
  self.value = raw.value
303
+ self.placeholder = raw.placeholder
248
304
  self.rect = rect ?? raw.rect
249
305
  self.enabled = raw.enabled
250
306
  self.focused = raw.focused
@@ -1,6 +1,7 @@
1
1
  import Foundation
2
2
  import CoreGraphics
3
3
 
4
+ /// With no viewport box the cumulative clip has no root, so containment has nothing to violate.
4
5
  public enum SnapshotPresentationInvariant {
5
6
  struct ValidationStats: Equatable {
6
7
  let parentClipLookups: Int
@@ -12,7 +13,7 @@ public enum SnapshotPresentationInvariant {
12
13
 
13
14
  public static func validateRegular(
14
15
  _ nodes: [SnapshotPresentationNode],
15
- viewport: CGRect,
16
+ viewport: SnapshotViewport,
16
17
  policy: SnapshotVisibilityFold.Policy
17
18
  ) throws {
18
19
  _ = try validateRegularWithStats(nodes, viewport: viewport, policy: policy)
@@ -20,24 +21,25 @@ public enum SnapshotPresentationInvariant {
20
21
 
21
22
  static func validateRegularWithStats(
22
23
  _ nodes: [SnapshotPresentationNode],
23
- viewport: CGRect,
24
+ viewport: SnapshotViewport,
24
25
  policy: SnapshotVisibilityFold.Policy
25
26
  ) throws -> ValidationStats {
26
27
  var parentClipLookups = 0
27
- var clipIncludingNodeByIndex: [Int: CGRect] = [:]
28
+ var clipIncludingNodeByIndex: [Int: CGRect?] = [:]
28
29
  clipIncludingNodeByIndex.reserveCapacity(nodes.count)
30
+ let rootClip = viewport.rect
29
31
 
30
32
  for node in nodes {
31
- let ancestorClip: CGRect
33
+ let ancestorClip: CGRect?
32
34
  if let parentIndex = node.raw.parentIndex {
33
35
  parentClipLookups += 1
34
- ancestorClip = clipIncludingNodeByIndex[parentIndex] ?? viewport
36
+ ancestorClip = clipIncludingNodeByIndex[parentIndex] ?? rootClip
35
37
  } else {
36
- ancestorClip = viewport
38
+ ancestorClip = rootClip
37
39
  }
38
40
 
39
41
  let frame = node.effectiveRect.cgRect
40
- let clipIncludingNode: CGRect
42
+ let clipIncludingNode: CGRect?
41
43
  if policy == .cursorProjected,
42
44
  SnapshotVisibilityFold.scrollContainerTypeNames.contains(node.raw.type),
43
45
  !frame.isNull,
@@ -50,7 +52,7 @@ public enum SnapshotPresentationInvariant {
50
52
  clipIncludingNodeByIndex[node.raw.index] = clipIncludingNode
51
53
 
52
54
  guard !frame.isNull, !frame.isEmpty else {
53
- if node.raw.hittable {
55
+ if node.raw.hittable == true {
54
56
  throw SnapshotPresentationFailure.regularDegenerateNodeIsActionable(
55
57
  index: node.raw.index,
56
58
  frame: node.effectiveRect
@@ -59,11 +61,11 @@ public enum SnapshotPresentationInvariant {
59
61
  continue
60
62
  }
61
63
 
62
- guard contains(frame, in: ancestorClip) else {
64
+ if let clip = ancestorClip, !contains(frame, in: clip) {
63
65
  throw SnapshotPresentationFailure.regularNodeOutsideCumulativeClip(
64
66
  index: node.raw.index,
65
67
  frame: node.effectiveRect,
66
- clip: SnapshotRect(ancestorClip)
68
+ clip: SnapshotRect(clip)
67
69
  )
68
70
  }
69
71
  }
@@ -140,6 +140,7 @@ extension SnapshotPresentation {
140
140
  label: raw.label,
141
141
  identifier: raw.identifier,
142
142
  value: raw.value,
143
+ placeholder: raw.placeholder,
143
144
  rect: raw.rect,
144
145
  enabled: raw.enabled,
145
146
  focused: raw.focused,
@@ -100,7 +100,7 @@ public enum SnapshotVisibilityFold {
100
100
  public static func traversalDecision(
101
101
  for node: RawAXNode,
102
102
  parent: TraversalState,
103
- viewport: CGRect,
103
+ viewport: SnapshotViewport,
104
104
  interactiveOnly: Bool,
105
105
  hasChildren: Bool,
106
106
  policy: Policy
@@ -153,7 +153,7 @@ public enum SnapshotVisibilityFold {
153
153
 
154
154
  public static func fold(
155
155
  _ nodes: [RawAXNode],
156
- viewport: CGRect,
156
+ viewport: SnapshotViewport,
157
157
  interactiveOnly: Bool,
158
158
  policy: Policy
159
159
  ) -> [SnapshotPresentationNode] {
@@ -199,14 +199,17 @@ public enum SnapshotVisibilityFold {
199
199
  label: node.label,
200
200
  identifier: node.identifier,
201
201
  value: node.value,
202
+ placeholder: node.placeholder,
202
203
  rect: node.rect,
203
204
  enabled: node.enabled,
204
205
  focused: node.focused,
205
206
  selected: node.selected,
206
- hittable: node.parentIndex != nil && node.hittable
207
- && SnapshotGeometry.isGeometricallyActionable(
207
+ hittable: node.parentIndex == nil
208
+ ? false
209
+ : clippedHittability(
210
+ source: node.hittable,
208
211
  enabled: node.enabled,
209
- frame: decision.effectiveFrame,
212
+ clippedFrame: decision.effectiveFrame,
210
213
  viewport: viewport
211
214
  ),
212
215
  depth: outDepth,
@@ -239,4 +242,23 @@ public enum SnapshotVisibilityFold {
239
242
  return applyHiddenContentHints(hints, to: kept)
240
243
  }
241
244
 
245
+ /// The fold's share of the `hittable` policy (#2891). A declared `false` is kept; anything the
246
+ /// source left undecided is re-decided on the clipped frame: a disabled or degenerate frame —
247
+ /// including a `visibilityExempt` carrier a scroll anchor clipped to nothing — answers `false`,
248
+ /// and `nil` stays reserved for the one question the clipped frame cannot answer, containment
249
+ /// while the capture has no viewport box.
250
+ private static func clippedHittability(
251
+ source: Bool?,
252
+ enabled: Bool,
253
+ clippedFrame: CGRect,
254
+ viewport: SnapshotViewport
255
+ ) -> Bool? {
256
+ if source == false { return false }
257
+ return SnapshotGeometry.isGeometricallyActionable(
258
+ enabled: enabled,
259
+ frame: clippedFrame,
260
+ viewport: viewport
261
+ )
262
+ }
263
+
242
264
  }
@@ -79,6 +79,7 @@ extension SnapshotVisibilityFold {
79
79
  label: node.label,
80
80
  identifier: node.identifier,
81
81
  value: node.value,
82
+ placeholder: node.placeholder,
82
83
  rect: node.rect,
83
84
  enabled: node.enabled,
84
85
  focused: node.focused,
@@ -1 +1 @@
1
- import{D as e,F as t}from"./sdk-contracts.js";import{Gr as n,Ur as r,Wr as i}from"./sdk-batch.js";import{c as a,r as o}from"./diagnostics.js";import{f as s,x as c}from"./owner-identity.js";import{c as l,l as u,m as d,r as f}from"./exec.js";import{n as p,t as m}from"./file.js";import"./diagnostics2.js";import"./command.js";import{n as ee}from"./retry.js";import{r as te}from"./version.js";import"./process.js";import{C as ne,D as re,c as ie,f as ae,h as oe,n as se,o as ce,w as le,y as ue}from"./host-file.js";import{t as h}from"./apple-runner-platform.js";import{t as de}from"./simctl.js";import{n as fe,r as g,t as pe}from"./snapshot-process.js";import _ from"node:path";import{createHash as v,randomUUID as y}from"node:crypto";import me from"node:net";import{Buffer as b}from"node:buffer";const he={unsupported:`UNSUPPORTED_OPERATION`,"malformed-tree":`COMMAND_FAILED`,"stale-target":`COMMAND_FAILED`,timeout:`COMMAND_FAILED`,cancelled:`COMMAND_FAILED`,"process-crash":`COMMAND_FAILED`,"transport-failure":`COMMAND_FAILED`,preparing:`COMMAND_FAILED`};var x=class extends e{failureKind;failureCode;constructor(e,t,n=`iOS Simulator snapshot source ${e}: ${t}`,r={},i){super(he[e],n,{...r,bridgeFailure:e,bridgeFailureCode:t,...e===`cancelled`?{reason:`request_canceled`}:{}},i),this.name=`SnapshotSourceError`,this.failureKind=e,this.failureCode=t}};function S(e,t,n={},r){return new x(e,t,void 0,n,r)}function C(n){return n instanceof x?n:t(n)?S(`cancelled`,`abort-signal`,{},n):n instanceof e&&typeof n.details?.timeoutMs==`number`?S(`timeout`,`host-operation-timeout`,{timeoutMs:n.details.timeoutMs},n):S(`transport-failure`,`unexpected-host-error`,{error:n instanceof Error?n.message:String(n)},n)}function w(e,t,n=Date.now){if(t?.aborted)throw S(`cancelled`,`abort-signal`);return{clock:ee.fromTimeoutMs(e,n()),now:n,signal:t}}function T(e,t){if(e.signal?.aborted)throw S(`cancelled`,`abort-signal`);let n=e.clock.remainingMs(e.now());if(n<=0)throw S(`timeout`,t);return Math.max(1,Math.floor(n))}async function E(e,t,n,r){let i=Math.min(t,T(e,n));await g({waitMs:i,signal:e.signal,stop:r,cancelled:()=>S(`cancelled`,`abort-signal`)})}var ge=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 D=65536;function _e(){return{projectRoot:te,homeDirectory:ae,run:async(e,t,n)=>await l(e,t,n),start:ve,connect:ye,readText:ue,readBinary:oe,writeText:re,ensureDirectory:ce,chmod:se,exists:ie,rename:le,remove:ne,acquireLock:be,emitDiagnostic:o,withDiagnosticTimer:a,processId:s,readTargetProcessStartTime:pe}}function ve(e,t,n,r={}){if(r.signal?.aborted)throw S(`cancelled`,`abort-signal`);let i=u(`xcrun`,de([`spawn`,e.udid,t,`serve`,n,`--idle-timeout`,`60`,`--exit-on-disconnect`,`false`],{simulatorSetPath:e.simulatorSetPath}),{allowFailure:!0,captureOutput:!1,detached:!0}),a=i.child.pid??0;if(a<=0)throw S(`transport-failure`,`bridge-process-pid-missing`);let o=``;return i.child.stderr?.setEncoding(`utf8`),i.child.stderr?.on(`data`,e=>{o=xe(o,String(e))}),{pid:a,wait:i.wait,isAlive:()=>i.child.exitCode===null&&i.child.signalCode===null,signal:e=>{d(a,e)||i.child.kill(e)},readLog:()=>o}}async function ye(e,t){if(t.signal?.aborted)throw S(`cancelled`,`abort-signal`);let n=Math.max(1,Math.floor(t.timeoutMs));return await new Promise((r,i)=>{let a=me.createConnection({path:e}),o=!1,s=!1,c=setTimeout(()=>{p(S(`timeout`,`bridge-connect-timeout`)),a.destroy()},n),l=()=>{p(S(`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(S(`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 be(e,t){let n=s(),r=t.deadline,i=m({lockDirPath:e,owner:{pid:n,startTime:c(n),acquiredAtMs:Date.now()},timeoutMs:T(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(S(`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().catch(()=>void 0),()=>void 0),r.clock.isExpired()&&!(e instanceof x&&e.failureKind===`cancelled`)?S(`timeout`,`cache-lock-deadline`):e}finally{a.removeEventListener(`abort`,l)}}function xe(e,t){let n=e+t;return n.length<=D?n:n.slice(n.length-D)}function Se(e,t,n){let r=v(`sha256`).update(t).digest(`hex`).slice(0,12),i=v(`sha256`).update(n).digest(`hex`).slice(0,12);return _.join(`/tmp`,`agent-device-ax-${r}-${e.processId()}-${i}`,`snapshot.sock`)}const O=new WeakSet;async function k(e,t){let n;try{n=(await t.wait).exitCode}catch{n=void 0}return O.has(t)||(O.add(t),e.emitDiagnostic({level:`error`,phase:`ios.snapshot-source.bridge-process-exit`,data:{pid:t.pid,...n===void 0?{}:{exitCode:n},stderr:A(t.readLog())}})),S(`process-crash`,`bridge-exited`,{pid:t.pid,...n===void 0?{}:{exitCode:n}})}function A(e){let t=b.from(e);return t.length<=65536?e:t.subarray(-65536).toString(`utf8`)}const j=`agent-device-simulator-ax-v1.7.0`;Object.freeze([`verb`,`requestId`,`pid`,`generation`,`snapshotTree`,`automationMode`,`maxDepth`,`maxNodes`,`maxDurationMs`,`maxResponseBytes`,`nativeLevelsHint`]),Object.freeze([`protocolVersion`,`sourceVersion`,`requestId`,`generation`,`ok`,`pid`,`tree`,`truncated`,`automationEnabled`,`recovery`,`error_kind`,`error_code`,`error`]),Object.freeze([`XC_kAXXCAttributeElementType`,`XC_kAXXCAttributeElementBaseType`,`XC_kAXXCAttributeLabel`,`XC_kAXXCAttributeValue`,`XC_kAXXCAttributeIdentifier`,`XC_kAXXCAttributeFrame`,`XC_kAXXCAttributeAutomationType`,`XC_kAXXCAttributeTraits`,`XC_kAXXCAttributeIsUserInteractionEnabled`,`XC_kAXXCAttributeChildren`]);const Ce=[`requests`,`rejected`,`continuations`,`acceptedLevels`];function we(e){let t=e.recovery;if(!M(t))throw S(`malformed-tree`,`recovery-invalid`);let n=Ce.map(e=>[e,t[e]]);if(n.some(([,e])=>!Number.isSafeInteger(e)||e<0))throw S(`malformed-tree`,`recovery-invalid`);return Object.freeze(Object.fromEntries(n))}function Te(e,t){let n;try{n=b.from(JSON.stringify(e),`utf8`)}catch(e){throw S(`malformed-tree`,`request-not-json`,{},e)}let r=n.length+4;if(r>t.maxRequestBytes)throw S(`transport-failure`,`request-limit-exceeded`,{frameBytes:r,maxRequestBytes:t.maxRequestBytes});let i=b.alloc(4);return i.writeUInt32BE(n.length,0),b.concat([i,n])}var Ee=class{header=b.alloc(4);headerBytes=0;chunks=[];payloadBytes=0;expectedBodyBytes;frame;maxFrameBytes;constructor(e){if(!Number.isSafeInteger(e)||e<=0)throw S(`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=b.concat(this.chunks,t.bodyBytes),this.frame}acceptTrailingChunk(e){if(e.length>0)throw S(`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 S(`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 S(`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 S(`transport-failure`,`bridge-frame-incomplete`,{headerBytes:this.headerBytes,payloadBytes:this.payloadBytes,expectedBodyBytes:this.expectedBodyBytes})}};function De(e){let t;try{t=JSON.parse(e.toString(`utf8`))}catch(e){throw S(`malformed-tree`,`response-not-json`,{},e)}if(!M(t))throw S(`malformed-tree`,`response-not-object`);return t}function Oe(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 ke(e,t){if(e.protocolVersion!==1)throw S(`transport-failure`,`protocol-version-mismatch`,{expected:1,observed:e.protocolVersion});if(e.sourceVersion!==`agent-device-simulator-ax-v1.7.0`)throw S(`transport-failure`,`source-version-mismatch`,{expected:j,observed:e.sourceVersion});if(e.requestId!==t)throw S(`transport-failure`,`request-id-mismatch`,{expected:t,observed:e.requestId})}function Ae(e,t){if(typeof e.pid!=`number`||e.pid!==t.pid)throw S(`stale-target`,`bridge-pid-mismatch`,{expectedPid:t.pid,observedPid:e.pid});if(e.generation!==t.generation)throw S(`stale-target`,`bridge-generation-mismatch`,{expectedGeneration:t.generation,observedGeneration:e.generation})}function je(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 S(t===`unsupported`?`unsupported`:t===`malformed_tree`?`malformed-tree`:t===`application_not_responding`?`timeout`:t===`application_unavailable`?`transport-failure`:t===`bad_request`?`malformed-tree`:`transport-failure`,n,i)}function M(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function Me(e){let t=new Ee(e.limits.maxResponseBytes-4),n=T(e.deadline,`bridge-request-deadline`);return await new Promise((r,i)=>{let a=!1,o=!1,s=setTimeout(()=>{p(S(`timeout`,`bridge-request-deadline`,{dispatched:o})),e.socket.destroy()},n),c=()=>{p(S(`cancelled`,`abort-signal`,{dispatched:o})),e.socket.destroy()},l=n=>{try{if(!Buffer.isBuffer(n))throw S(`transport-failure`,`bridge-data-invalid`);let r=t.push(n);if(r){let t=De(r);if(ke(t,e.requestId),Ae(t,{pid:e.expectedPid,generation:e.expectedGeneration}),t.ok!==!0&&je(t),typeof t.truncated!=`boolean`)throw S(`malformed-tree`,`truncated-invalid`);f(t);return}}catch(t){p(t),e.socket.destroy()}},u=e=>p(C(e)),d=()=>{a||(e.process.isAlive()?p(S(`transport-failure`,`bridge-connection-closed`)):k(e.host,e.process).then(p))};e.process.wait.then(()=>{a||k(e.host,e.process).then(p)},e=>{a||p(C(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 S(`cancelled`,`abort-signal`);o=!0,e.socket.write(e.frame)}catch(t){p(C(t)),e.socket.destroy()}})}var Ne=class{sessions=new Map;requestQueues=new Map;ownerId=y();closed=!1;host;constructor(e){this.host=e}async request(e){if(this.closed)throw S(`unsupported`,`source-closed`);return await this.withSimulatorLock(e.target.udid,e.deadline,()=>this.requestInSimulator(e))}async requestInSimulator(e){if(this.closed)throw S(`unsupported`,`source-closed`);let t=e.deadline;T(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=C(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=Se(this.host,e.target.udid,this.ownerId);await this.host.ensureDirectory(_.dirname(i)),await this.host.remove(i);let a=this.host.start(e.target,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),C(e)}}async connectUntilReady(e,t){let n;for(;;){let r=T(t,`bridge-connect-deadline`);if(!e.process.isAlive())throw await k(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 x&&e.failureKind===`cancelled`)throw e;let r=Math.min(20,T(t,`bridge-connect-deadline`));try{await E(t,r,`bridge-connect-deadline`)}catch(e){throw C(e)}}if(n instanceof x&&n.failureKind===`timeout`)throw n}}async exchange(e,t,n){(!e.socket||e.socket.destroyed)&&(e.socket=await this.connectUntilReady(e,n));let r=y(),i=Te(Oe({requestId:r,pid:t.target.pid,generation:t.target.generation,maxDepth:Math.min(t.limits.maxTraversalDepth,t.maxDepth),maxNodes:t.limits.maxNodes,maxDurationMs:T(n,`bridge-request-deadline`),maxResponseBytes:t.limits.maxResponseBytes,...t.nativeLevelsHint===void 0?{}:{nativeLevelsHint:t.nativeLevelsHint}}),t.limits);return await Me({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:T(t,`target-identity-deadline`)});if(!n)throw S(`stale-target`,`target-process-unavailable`,{pid:e.pid,generation:e.generation});if(e.processStartTime!==void 0&&e.processStartTime!==n)throw S(`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:T(n,`target-identity-deadline`)});if(r!==t)throw S(`stale-target`,`target-process-changed`,{pid:e.pid,generation:e.generation,expectedStartTime:t,observedStartTime:r})}async removeSession(e,t){this.sessions.get(e.udid)===e&&this.sessions.delete(e.udid),await this.dispose(e,t)}async dispose(e,t){e.socket?.destroy(),e.socket=void 0,t&&e.process.isAlive()&&(e.process.signal(`SIGTERM`),await N(e.process,500),e.process.isAlive()&&(e.process.signal(`SIGKILL`),await N(e.process,500))),await this.host.remove(e.socketPath)}};async function Pe(e,t){let n=T(t,`bridge-request-deadline`);await Promise.race([e,E(t,n,`bridge-request-deadline`).then(()=>{throw S(`timeout`,`bridge-request-deadline`)})])}function Fe(e,t,n){return(e.failureKind===`cancelled`||e.failureKind===`timeout`)&&(e.details?.dispatched===!0||n!==t)}async function N(e,t){await Promise.race([e.wait.catch(()=>void 0),new Promise(e=>setTimeout(e,t))])}const P=16777216,F=12e4,I=1e4,Ie=Object.freeze({maxRequestBytes:65536,maxResponseBytes:4194304,maxNodes:5e3,maxTraversalDepth:64,maxDurationMs:5e3});function L(t){let n={...Ie,...t??{}};for(let[t,r]of Object.entries(n))if(!Number.isSafeInteger(r)||r<=0)throw new e(`INVALID_ARGS`,`Snapshot source limit ${t} must be a positive integer`,{name:t,value:r});if(n.maxRequestBytes>n.maxResponseBytes)throw new e(`INVALID_ARGS`,`Snapshot source request bytes cannot exceed response bytes`,{maxRequestBytes:n.maxRequestBytes,maxResponseBytes:n.maxResponseBytes});if(n.maxRequestBytes>P||n.maxResponseBytes>P)throw new e(`INVALID_ARGS`,`Snapshot source frame limits exceed the bridge bound`,{maxRequestBytes:n.maxRequestBytes,maxResponseBytes:n.maxResponseBytes,maximumFrameBytes:P});if(n.maxNodes>I||n.maxTraversalDepth>128)throw new e(`INVALID_ARGS`,`Snapshot source tree limits exceed the bridge bound`,{maxNodes:n.maxNodes,maxTraversalDepth:n.maxTraversalDepth,maximumNodes:I,maximumDepth:128});if(n.maxDurationMs>F)throw new e(`INVALID_ARGS`,`Snapshot source duration exceeds the bridge bound`,{maxDurationMs:n.maxDurationMs,maximumDurationMs:F});if(n.maxRequestBytes<=4||n.maxResponseBytes<=4)throw new e(`INVALID_ARGS`,`Snapshot source frame limits must leave room for a body`,{maxRequestBytes:n.maxRequestBytes,maxResponseBytes:n.maxResponseBytes});return Object.freeze(n)}const R=[`SnapshotBridge.m`,`SnapshotBridgeRuntime.m`,`SnapshotBridgeRuntime.h`,`SnapshotBridgeCapture.h`,`SnapshotBridgeCapture.m`],Le=[`SnapshotBridge.m`,`SnapshotBridgeRuntime.m`,`SnapshotBridgeCapture.m`];async function Re(e,t,n){let r=v(`sha256`);for(let i of R){let a=_.join(t,i);if(T(n,`native-source-fingerprint-deadline`),!e.exists(a))throw S(`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 ze(e,t,n){let r=await z(e,`xcodebuild`,[`-version`],n),i=await z(e,`sw_vers`,[`-productVersion`],n),a=await z(e,`sw_vers`,[`-buildVersion`],n),o=await z(e,`uname`,[`-m`],n),s=t.trim();if(!s)throw S(`unsupported`,`simulator-runtime-missing`);if(o!==`arm64`&&o!==`x86_64`)throw S(`unsupported`,`simulator-architecture-unsupported`,{architecture:o});return{xcode:r,macosProductVersion:i,macosBuild:a,architecture:o,simulatorRuntime:s}}async function z(e,t,n,r){let i=await Be(e,t,n,r);if(i.exitCode!==0)throw S(`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 S(`unsupported`,`toolchain-probe-empty`,{command:t});return a}async function Be(e,t,n,r){let i=[],a;for(let o=1;;o+=1){let s;try{s=Math.min(h,T(r,`toolchain-probe-deadline`))}catch(e){throw a??e}i.push(s);try{return await He(e,t,n,r,s)}catch(e){if(!f(e))throw e;if(r.signal?.aborted)throw S(`cancelled`,`abort-signal`);if(a=Ve(t,i,e),o>=2)throw a}}}function Ve(e,t,n){let r=t.length;return S(`timeout`,`toolchain-probe-stalled`,{command:e,attemptTimeoutsMs:[...t],hint:`${e} did not answer within ${t[r-1]}ms on ${r} attempt(s). A toolchain probe that cannot answer is a host condition rather than a toolchain defect: run \`${e}\` by hand until it answers, then retry.`},n)}function He(e,t,n,r,i){return e.run(t,n,{allowFailure:!0,signal:r.signal,timeoutMs:i})}const B=`snapshot-bridge`,V=`manifest.json`,H=12e4;async function Ue(e){let t=e.deadline,n=e.sourceRoot??Ge(e.host),r=await Re(e.host,n,t),i=await ze(e.host,e.runtime,t),a=qe({schemaVersion:1,protocolVersion:1,sourceVersion:j,sourceHash:r,toolchain:i}),o=e.cacheRoot??_.join(e.host.homeDirectory(),`.agent-device`,`snapshot-source`),s=_.join(o,a);return await p({acquire:()=>e.host.acquireLock(_.join(o,`${a}.lock`),{deadline:t}),task:async()=>{let c=await Ke(e.host,s,{sourceHash:r,cacheKey:a,toolchain:i},t);if(c)return c;T(t,`native-build-deadline`),e.host.exists(s)&&await e.host.remove(s),T(t,`native-build-deadline`),await e.host.ensureDirectory(o);let l=_.join(o,`.${a}.${e.host.processId()}.tmp`);T(t,`native-build-deadline`),await e.host.remove(l);try{T(t,`native-build-deadline`),await e.host.ensureDirectory(l);let o=_.join(l,B),c=await We(e.host,t,i.architecture,n,o);if(c.exitCode!==0||!e.host.exists(o))throw S(`unsupported`,`native-build-failed`,{exitCode:c.exitCode,stderr:c.stderr.slice(0,4096)});T(t,`native-build-deadline`),await e.host.chmod(o,493);let u=await U(e.host,o,t),d={schemaVersion:1,protocolVersion:1,sourceVersion:j,sourceHash:r,cacheKey:a,toolchain:i,binarySha256:u};return await e.host.writeText(_.join(l,V),`${JSON.stringify(d,null,2)}\n`),T(t,`native-build-deadline`),await e.host.rename(l,s),{path:_.join(s,B),sourceHash:r,cacheKey:a,protocolVersion:1,sourceVersion:j}}catch(t){throw await e.host.remove(l),t}}})}async function We(e,t,n,r,i){let a=Math.min(H,T(t,`native-build-deadline`));try{return await e.run(`xcrun`,[`--sdk`,`iphonesimulator`,`clang`,`-arch`,n,`-mios-simulator-version-min=15.0`,`-fobjc-arc`,`-Werror`,`-Wall`,`-Wextra`,`-framework`,`Foundation`,`-framework`,`CoreGraphics`,...Le.map(e=>_.join(r,e)),`-o`,i],{signal:t.signal,timeoutMs:a,allowFailure:!0})}catch(e){throw f(e)?S(`timeout`,`native-build-stalled`,{timeoutMs:a,hint:`The Simulator SDK toolchain did not answer within ${a}ms, which stopped the bridge build before clang reported anything. Run \`xcrun --sdk iphonesimulator clang --version\` by hand until it answers, then retry.`},e):e}}function Ge(e){let t=e.projectRoot(),n=_.join(t,`apple`,`snapshot-bridge`);if(R.every(t=>e.exists(_.join(n,t))))return n;let r=_.join(t,`dist`,`apple`,`snapshot-bridge`);if(R.every(t=>e.exists(_.join(r,t))))return r;throw S(`unsupported`,`native-source-missing`,{projectRoot:t})}async function Ke(e,t,n,r){let i=_.join(t,B);if(!(!e.exists(i)||!e.exists(_.join(t,V))))try{let a=JSON.parse(await e.readText(_.join(t,V)));return a.schemaVersion!==1||a.protocolVersion!==1||a.sourceVersion!==`agent-device-simulator-ax-v1.7.0`||a.sourceHash!==n.sourceHash||a.cacheKey!==n.cacheKey||JSON.stringify(a.toolchain)!==JSON.stringify(n.toolchain)||typeof a.binarySha256!=`string`||await U(e,i,r)!==a.binarySha256?void 0:{path:i,sourceHash:n.sourceHash,cacheKey:n.cacheKey,protocolVersion:1,sourceVersion:j}}catch(e){if(e instanceof x&&(e.failureKind===`cancelled`||e.failureKind===`timeout`))throw e;return}}async function U(e,t,n){return T(n,`native-cache-hash-deadline`),v(`sha256`).update(await e.readBinary(t)).digest(`hex`)}function qe(e){return v(`sha256`).update(JSON.stringify(e)).digest(`hex`).slice(0,32)}const Je=h+H;function Ye(e){let t=e.now??Date.now,n=new Map,r=fe({waitMs:2e3,waitGrant:`first-caller`,retryAfterMs:6e4,now:t}),i=async(r,i)=>{let a=w(Je,i,t);try{let t=await e.host.withDiagnosticTimer(`ios.snapshot-source.prepare`,async()=>await Ue({host:e.host,runtime:r,limits:e.limits,deadline:a,sourceRoot:e.sourceRoot,cacheRoot:e.cacheRoot}),{producer:e.producer});return n.set(r,t),t}catch(e){throw C(e)}};return{readyBinary:async(e,t,a)=>n.get(e)||await r.value(e,{start:t=>i(e,t),wait:(e,n)=>E(t,e,a,n),pending:()=>S(`preparing`,`bridge-preparation-pending`)}),close:()=>{n.clear(),r.close()}}}function Xe(e,t){return!i(e)||!i(t)||Math.abs(t.width-t.height)<=1?!1:Math.abs(e.width-t.height)<=1&&Math.abs(e.height-t.width)<=1}const W=Object.freeze({elementType:`XC_kAXXCAttributeElementType`,elementBaseType:`XC_kAXXCAttributeElementBaseType`,label:`XC_kAXXCAttributeLabel`,value:`XC_kAXXCAttributeValue`,identifier:`XC_kAXXCAttributeIdentifier`,frame:`XC_kAXXCAttributeFrame`,automationType:`XC_kAXXCAttributeAutomationType`,traits:`XC_kAXXCAttributeTraits`,userInteractionEnabled:`XC_kAXXCAttributeIsUserInteractionEnabled`,children:`XC_kAXXCAttributeChildren`}),G=`Other.Other.Application.Group.Window.Sheet.Drawer.Alert.Dialog.Button.RadioButton.RadioGroup.CheckBox.DisclosureTriangle.PopUpButton.ComboBox.MenuButton.ToolbarButton.Popover.Keyboard.Key.NavigationBar.TabBar.TabGroup.Toolbar.StatusBar.Table.TableRow.TableColumn.Outline.OutlineRow.Browser.CollectionView.Slider.PageIndicator.ProgressIndicator.ActivityIndicator.SegmentedControl.Picker.PickerWheel.Switch.Toggle.Link.Image.Icon.SearchField.ScrollView.ScrollBar.StaticText.TextField.SecureTextField.DatePicker.TextView.Menu.MenuItem.MenuBar.MenuBarItem.Map.WebView.IncrementArrow.DecrementArrow.Timeline.RatingIndicator.ValueIndicator.SplitGroup.Splitter.RelevanceIndicator.ColorWell.HelpTag.Matte.DockItem.Ruler.RulerMarker.Grid.LevelIndicator.Cell.LayoutArea.LayoutItem.Handle.Stepper.Tab.TouchBar.StatusItem`.split(`.`),K={UIApplication:`Application`,UIWindow:`Window`},Ze=new Set(Object.values(W)),Qe=1n<<8n,$e=1n<<3n,et={x:0,y:0,width:0,height:0};function tt(e,t,n){let r=Array.isArray(e)?e:[e];if(r.length===0||r.some(e=>!M(e)))throw S(`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 S(`malformed-tree`,`node-limit-exceeded`,{nodeCount:i.length,maxNodes:n.maxNodes});if(o>n.maxTraversalDepth)throw S(`malformed-tree`,`traversal-depth-exceeded`,{maxTraversalDepth:o,maxAllowedDepth:n.maxTraversalDepth});if(typeof t.truncated!=`boolean`)throw S(`malformed-tree`,`truncated-invalid`);let s=ot(i.filter(J)[0]);return s.kind===`reported`&&st(i,s.rect),{nodes:i,maxTraversalDepth:o,viewport:s,opaqueRemoteElements:a.filter(e=>it(e,s)).length,unresolvedCoordinateSpaceWindows:ct(i,s)};function c(e,t,r,s){if(i.length>=n.maxNodes)throw S(`malformed-tree`,`node-limit-exceeded`,{maxNodes:n.maxNodes});for(let t of Object.keys(e))if(!Ze.has(t))throw S(`malformed-tree`,`node-contains-unknown-field`,{key:t});let l=e[W.children];if(!Array.isArray(l))throw S(`malformed-tree`,`children-invalid`);let u=i.length,d=nt(e,u,t,r);i.push(d),o=Math.max(o,r),rt(d,l.length,s)&&a.push(d.rect);let f=s||d.type===`WebView`;for(let e of l){if(!M(e))throw S(`malformed-tree`,`child-invalid`);c(e,u,r+1,f)}}}function nt(e,t,n,r){let i=X(e[W.elementType]),a=X(e[W.elementBaseType]),o=dt(e[W.automationType]),s=at(e[W.frame]),c=lt(e[W.traits]),l=c===void 0?void 0:(c&Qe)===0n,u=c===void 0||(c&$e)===0n?void 0:!0,d=ut(e[W.userInteractionEnabled]);return{index:t,...n===void 0?{}:{parentIndex:n},...q(i,o)?{type:q(i,o)}:{},...i?{role:i}:{},...a&&a!==i?{subrole:a}:{},...X(e[W.label])?{label:X(e[W.label])}:{},...Z(e[W.value])?{value:Z(e[W.value])}:{},...X(e[W.identifier])?{identifier:X(e[W.identifier])}:{},...s?{rect:s}:{},...l===void 0?{}:{enabled:l},...u===void 0?{}:{selected:u},...d===void 0?{}:{userInteractionEnabled:d},depth:r}}function q(e,t){if(e!==void 0&&K[e])return K[e];if(e!==void 0&&G.includes(e))return e;if(t!==void 0)return G[t]??`Other`}function rt(e,t,n){return n&&e.role===`AXRemoteElement`&&t===0}function it(e,t){return e===void 0?!0:i(e)?t.kind!==`reported`||n(e,t.rect):!1}function at(e){if(e===void 0)return;if(!M(e))throw S(`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 S(`malformed-tree`,`frame-invalid`);let[n,r,i,a]=t;if(i<0||a<0)throw S(`malformed-tree`,`frame-invalid`);return{x:n,y:r,width:i,height:a}}function ot(e){return!e||!J(e)?{kind:`missing`,reason:`not-provided`}:i(e.rect)?{kind:`reported`,rect:e.rect}:{kind:`missing`,reason:e.rect?`invalid`:`not-provided`}}function J(e){return e.type===`Application`||e.type===`Window`}function st(e,t){for(let n of e)n.hittable=n.parentIndex!==void 0&&r(n.enabled!==!1,n.rect,t)}function ct(e,t){return t.kind===`reported`?e.filter(n=>Y(n,e)&&Xe(n.rect??et,t.rect)).length:0}function Y(e,t){return J(e)?!0:e.parentIndex!==void 0&&J(t[e.parentIndex]??e)}function X(e){return typeof e==`string`&&e.length>0?e:void 0}function Z(e){if(typeof e==`string`)return e.length>0?e:void 0;if(typeof e==`number`||typeof e==`boolean`)return String(e);if(e!=null)throw S(`malformed-tree`,`scalar-invalid`)}function lt(e){if(e!=null){if(typeof e!=`string`||!/^\d{1,20}$/.test(e))throw S(`malformed-tree`,`traits-invalid`);return BigInt(e)}}function ut(e){if(e!=null){if(typeof e!=`boolean`)throw S(`malformed-tree`,`user-interaction-invalid`);return e}}function dt(e){if(e!=null){if(!Number.isSafeInteger(e))throw S(`malformed-tree`,`automation-type-invalid`);return e}}const Q=`simulator-ax-bridge`;function ft(e={}){let t=e.host??_e(),n=new Ne(t),r=new ge,i=Ye({host:t,limits:L(e.limits),producer:Q,sourceRoot:e.sourceRoot,cacheRoot:e.cacheRoot}),a=!1;return{acquire:async o=>{try{if(a)throw S(`unsupported`,`source-closed`);pt(o);let s=L({...e.limits,...o.limits}),c=w(s.maxDurationMs,o.signal),l=ht(o.hint,s.maxTraversalDepth),u=l+1,d=o.hint.rawTraversalDepth!==null;return await t.withDiagnosticTimer(`ios.snapshot-source.acquire`,async()=>{let e=await i.readyBinary(o.target.runtime,c,`bridge-preparation-deadline`),a=r.consume(o.target,u,d),f=await n.request({target:o.target,bridge:e,limits:s,maxDepth:l,nativeLevelsHint:a.nativeLevels,deadline:c});T(c,`snapshot-decode-deadline`);let p=gt(o.hint,o.target,f,s);return mt(t,r,o.target,u,d,a,f),{stage:`acquired`,acquisition:p}},{producer:Q})}catch(e){let t=C(e);return{stage:`failed`,failure:{kind:t.failureKind,code:t.failureCode,...t.details?{details:t.details}:{}}}}},close:async()=>{a||(a=!0,i.close(),await n.close())}}}function pt(t){if(!t.target.udid.trim()||!t.target.runtime.trim()||!t.target.generation.trim()||!Number.isSafeInteger(t.target.pid)||t.target.pid<=0)throw new e(`INVALID_ARGS`,`Simulator snapshot source target identity is incomplete`);let n=t.hint;if(n.projection!==`raw`&&n.projection!==`regular`||![`full`,`surface-observation`].includes(n.acquisitionIntent)||typeof n.interactiveOnly!=`boolean`||typeof n.customActions!=`boolean`||!$(n.rawTraversalDepth)||!$(n.regularPresentedDepth))throw new e(`INVALID_ARGS`,`Simulator snapshot source capture hint is invalid`)}function mt(e,t,n,r,i,a,o){let s=we(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 ht(t,n){let r=t.rawTraversalDepth??n;if(r>n)throw new e(`INVALID_ARGS`,`Simulator snapshot source depth exceeds its bound`,{requested:r,maximum:n});return r}function $(e){return e===null||Number.isSafeInteger(e)&&e>=0}function gt(e,t,n,r){if(n.automationEnabled!==!0)throw S(`unsupported`,`automation-mode-unavailable`);let i=n.tree,a=n.truncated;if(typeof a!=`boolean`)throw S(`malformed-tree`,`truncated-invalid`);let o=tt(i,{truncated:a},r),s=n.generation;if(typeof s!=`string`||!s)throw S(`malformed-tree`,`generation-invalid`);if(o.opaqueRemoteElements>0)throw S(`unsupported`,`remote-content-boundary`,{remoteElements:o.opaqueRemoteElements});if(o.unresolvedCoordinateSpaceWindows>0)throw S(`unsupported`,`window-coordinate-space-unresolved`,{windows:o.unresolvedCoordinateSpaceWindows});let c=Object.freeze(o.nodes.map(e=>Object.freeze({...e,pid:t.pid}))),l=_t(e,a,o.viewport),u=Object.freeze({...t.targetId?{targetId:t.targetId}:{},generation:s}),d={producer:Q,nodes:c,truncated:a,viewport:o.viewport,lineage:u,residue:l};return e.acquisitionIntent===`full`?{...d,intent:`full`,hint:{...e,acquisitionIntent:`full`}}:{...d,intent:`surface-observation`,hint:{...e,acquisitionIntent:`surface-observation`}}}function _t(e,t,n){let r=n.kind===`reported`?[]:[{kind:`unavailable-fact`,fact:`hittability`}];return Object.freeze([...r,...e.interactiveOnly?[{kind:`unavailable-fact`,fact:`interactive-query`}]:[],...t?[{kind:`truncated`}]:[],...n.kind===`missing`?[{kind:`missing-viewport`,reason:n.reason}]:[]])}export{ft as createSimulatorSnapshotSource};
1
+ import{A as e}from"./sdk-contracts.js";import{Jr as t,Yr as n,qr as r}from"./sdk-batch.js";import{t as i}from"./apple-runner-platform.js";import{_ as a,a as o,d as s,f as c,h as l,i as u,l as d,m as f,n as p,o as m,p as h,r as g,s as _,t as ee,u as v}from"./native-build-cache.js";import y from"node:path";import{randomUUID as b}from"node:crypto";import{Buffer as x}from"node:buffer";var te=class{entries=new Map;probeBackAfterUses;constructor(e=8){this.probeBackAfterUses=e}consume(e,t,n){if(n)return{nativeLevels:void 0,reason:`explicit-depth`};let r=this.currentEntry(e);return r===`unidentified`?{nativeLevels:void 0,reason:`unidentified-target`}:!r||r.nativeLevels>=t?{nativeLevels:void 0,reason:`no-hint`}:r.remainingUses<=0?{nativeLevels:void 0,reason:`probe-back`}:(--r.remainingUses,{nativeLevels:r.nativeLevels,reason:`hinted`})}learn(e,t,n,r){return n||!e.targetId?`ignored`:r.rejected>0&&r.acceptedLevels<t?(this.remember(e.targetId,{generation:e.generation,nativeLevels:r.acceptedLevels,remainingUses:this.probeBackAfterUses}),`learned`):r.rejected===0&&r.acceptedLevels>=t?this.entries.delete(e.targetId)?`forgotten`:`ignored`:this.currentEntry(e)?`kept`:`ignored`}currentEntry(e){if(!e.targetId)return`unidentified`;let t=this.entries.get(e.targetId);if(t){if(t.generation!==e.generation){this.entries.delete(e.targetId);return}return t}}remember(e,t){if(this.entries.delete(e),this.entries.size>=32){let e=this.entries.keys().next().value;e!==void 0&&this.entries.delete(e)}this.entries.set(e,t)}};const S=new WeakSet;async function C(e,t){let n;try{n=(await t.wait).exitCode}catch{n=void 0}return S.has(t)||(S.add(t),e.emitDiagnostic({level:`error`,phase:`ios.snapshot-source.bridge-process-exit`,data:{pid:t.pid,...n===void 0?{}:{exitCode:n},stderr:ne(t.readLog())}})),l(`process-crash`,`bridge-exited`,{pid:t.pid,...n===void 0?{}:{exitCode:n}})}function ne(e){let t=x.from(e);return t.length<=65536?e:t.subarray(-65536).toString(`utf8`)}const w=`agent-device-simulator-ax-v1.8.0`;Object.freeze([`verb`,`requestId`,`pid`,`generation`,`snapshotTree`,`automationMode`,`maxDepth`,`maxNodes`,`maxDurationMs`,`maxResponseBytes`,`nativeLevelsHint`]),Object.freeze([`protocolVersion`,`sourceVersion`,`requestId`,`generation`,`ok`,`pid`,`tree`,`truncated`,`automationEnabled`,`recovery`,`error_kind`,`error_code`,`error`]),Object.freeze([`XC_kAXXCAttributeElementType`,`XC_kAXXCAttributeElementBaseType`,`XC_kAXXCAttributeLabel`,`XC_kAXXCAttributeValue`,`XC_kAXXCAttributePlaceholderValue`,`XC_kAXXCAttributeIdentifier`,`XC_kAXXCAttributeFrame`,`XC_kAXXCAttributeAutomationType`,`XC_kAXXCAttributeTraits`,`XC_kAXXCAttributeIsUserInteractionEnabled`,`XC_kAXXCAttributeChildren`]);const T=[`requests`,`rejected`,`continuations`,`acceptedLevels`];function re(e){let t=e.recovery;if(!j(t))throw l(`malformed-tree`,`recovery-invalid`);let n=T.map(e=>[e,t[e]]);if(n.some(([,e])=>!Number.isSafeInteger(e)||e<0))throw l(`malformed-tree`,`recovery-invalid`);return Object.freeze(Object.fromEntries(n))}function ie(e,t){let n;try{n=x.from(JSON.stringify(e),`utf8`)}catch(e){throw l(`malformed-tree`,`request-not-json`,{},e)}let r=n.length+4;if(r>t.maxRequestBytes)throw l(`transport-failure`,`request-limit-exceeded`,{frameBytes:r,maxRequestBytes:t.maxRequestBytes});let i=x.alloc(4);return i.writeUInt32BE(n.length,0),x.concat([i,n])}var E=class{header=x.alloc(4);headerBytes=0;chunks=[];payloadBytes=0;expectedBodyBytes;frame;maxFrameBytes;constructor(e){if(!Number.isSafeInteger(e)||e<=0)throw l(`malformed-tree`,`frame-limit-invalid`,{maxFrameBytes:e});this.maxFrameBytes=e}push(e){if(this.frame)return this.acceptTrailingChunk(e);let t=this.readHeader(e);if(t&&(this.appendPayload(e,t.offset,t.bodyBytes),this.payloadBytes===t.bodyBytes))return this.frame=x.concat(this.chunks,t.bodyBytes),this.frame}acceptTrailingChunk(e){if(e.length>0)throw l(`malformed-tree`,`multiple-frames`,{trailingBytes:e.length});return this.frame}readHeader(e){if(this.headerBytes===4)return{offset:0,bodyBytes:this.expectedBodyBytes};let t=Math.min(4-this.headerBytes,e.length);if(e.copy(this.header,this.headerBytes,0,t),this.headerBytes+=t,this.headerBytes<4)return;let n=this.header.readUInt32BE(0);if(n===0||n>this.maxFrameBytes)throw l(`malformed-tree`,`frame-limit-exceeded`,{bodyBytes:n,maxFrameBytes:this.maxFrameBytes});return this.expectedBodyBytes=n,{offset:t,bodyBytes:n}}appendPayload(e,t,n){let r=n-this.payloadBytes,i=e.length-t;if(i>r)throw l(`malformed-tree`,`multiple-frames`,{trailingBytes:i-r});i!==0&&(this.chunks.push(e.subarray(t)),this.payloadBytes+=i)}finish(){if(this.frame)return this.frame;throw l(`transport-failure`,`bridge-frame-incomplete`,{headerBytes:this.headerBytes,payloadBytes:this.payloadBytes,expectedBodyBytes:this.expectedBodyBytes})}};function ae(e){let t;try{t=JSON.parse(e.toString(`utf8`))}catch(e){throw l(`malformed-tree`,`response-not-json`,{},e)}if(!j(t))throw l(`malformed-tree`,`response-not-object`);return t}function D(e){return Object.freeze({verb:`describe`,requestId:e.requestId,pid:e.pid,generation:e.generation,snapshotTree:!0,automationMode:!0,maxDepth:e.maxDepth,maxNodes:e.maxNodes,maxDurationMs:e.maxDurationMs,maxResponseBytes:e.maxResponseBytes,...e.nativeLevelsHint===void 0?{}:{nativeLevelsHint:e.nativeLevelsHint}})}function O(e,t){if(e.protocolVersion!==1)throw l(`transport-failure`,`protocol-version-mismatch`,{expected:1,observed:e.protocolVersion});if(e.sourceVersion!==`agent-device-simulator-ax-v1.8.0`)throw l(`transport-failure`,`source-version-mismatch`,{expected:w,observed:e.sourceVersion});if(e.requestId!==t)throw l(`transport-failure`,`request-id-mismatch`,{expected:t,observed:e.requestId})}function k(e,t){if(typeof e.pid!=`number`||e.pid!==t.pid)throw l(`stale-target`,`bridge-pid-mismatch`,{expectedPid:t.pid,observedPid:e.pid});if(e.generation!==t.generation)throw l(`stale-target`,`bridge-generation-mismatch`,{expectedGeneration:t.generation,observedGeneration:e.generation})}function A(e){let t=e.error_kind,n=typeof e.error_code==`string`?e.error_code:`guest-error`,r=typeof e.error==`string`?e.error:void 0,i=r?{guestMessage:r.slice(0,1024)}:{};throw l(t===`unsupported`?`unsupported`:t===`malformed_tree`?`malformed-tree`:t===`application_not_responding`?`timeout`:t===`application_unavailable`?`transport-failure`:t===`bad_request`?`malformed-tree`:`transport-failure`,n,i)}function j(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function oe(e){let t=new E(e.limits.maxResponseBytes-4),n=s(e.deadline,`bridge-request-deadline`);return await new Promise((r,i)=>{let a=!1,o=!1,s=setTimeout(()=>{h(l(`timeout`,`bridge-request-deadline`,{dispatched:o})),e.socket.destroy()},n),c=()=>{h(l(`cancelled`,`abort-signal`,{dispatched:o})),e.socket.destroy()},u=n=>{try{if(!Buffer.isBuffer(n))throw l(`transport-failure`,`bridge-data-invalid`);let r=t.push(n);if(r){let t=ae(r);if(O(t,e.requestId),k(t,{pid:e.expectedPid,generation:e.expectedGeneration}),t.ok!==!0&&A(t),typeof t.truncated!=`boolean`)throw l(`malformed-tree`,`truncated-invalid`);m(t);return}}catch(t){h(t),e.socket.destroy()}},d=e=>h(f(e)),p=()=>{a||(e.process.isAlive()?h(l(`transport-failure`,`bridge-connection-closed`)):C(e.host,e.process).then(h))};e.process.wait.then(()=>{a||C(e.host,e.process).then(h)},e=>{a||h(f(e))});let m=e=>g(()=>r(e)),h=e=>g(()=>i(e)),g=t=>{a||(a=!0,clearTimeout(s),e.deadline.signal?.removeEventListener(`abort`,c),e.socket.off(`data`,u),e.socket.off(`error`,d),e.socket.off(`close`,p),t())};e.socket.on(`data`,u),e.socket.on(`error`,d),e.socket.on(`close`,p),e.deadline.signal?.addEventListener(`abort`,c,{once:!0});try{if(e.deadline.signal?.aborted)throw l(`cancelled`,`abort-signal`);o=!0,e.socket.write(e.frame)}catch(t){h(f(t)),e.socket.destroy()}})}var se=class{sessions=new Map;requestQueues=new Map;ownerId=b();closed=!1;host;constructor(e){this.host=e}async request(e){if(this.closed)throw l(`unsupported`,`source-closed`);return await this.withSimulatorLock(e.target.simulator.udid,e.deadline,()=>this.requestInSimulator(e))}async requestInSimulator(e){if(this.closed)throw l(`unsupported`,`source-closed`);let t=e.deadline;s(t,`bridge-request-deadline`);let n=this.sessions.get(e.target.simulator.udid),r=await this.ensureSession(e,t);try{let n=await this.readTargetStartTime(e.target,t),i=await this.exchange(r,e,t);return await this.assertTargetStillCurrent(e.target,n,t),i}catch(e){throw await this.handleRequestFailure(e,r,n)}}async handleRequestFailure(e,t,n){let r=f(e);return le(r,t,n)?await this.removeSession(t,!0):r.failureKind===`process-crash`?await this.removeSession(t,!1):r.failureKind===`transport-failure`&&(t.socket?.destroy(),t.socket=void 0),r}async withSimulatorLock(e,t,n){let r=this.requestQueues.get(e)??Promise.resolve(),i,a=new Promise(e=>{i=e}),o=r.then(()=>a);this.requestQueues.set(e,o);try{return await ce(r,t),await n()}finally{i(),this.requestQueues.get(e)===o&&this.requestQueues.delete(e)}}async close(){if(this.closed)return;this.closed=!0;let e=[...this.sessions.values()];this.sessions.clear(),await Promise.all(e.map(async e=>await this.dispose(e,!0)))}async ensureSession(e,t){let n=e.target.simulator.udid,r=this.sessions.get(n);if(r&&r.bridgePath===e.bridge.path&&r.process.isAlive())return(!r.socket||r.socket.destroyed)&&(r.socket=await this.connectUntilReady(r,t)),r;r&&await this.removeSession(r,!0);let i=o(this.host,e.target.simulator.udid,this.ownerId);await this.host.ensureDirectory(y.dirname(i)),await this.host.remove(i);let a=this.host.start(e.target.simulator,e.bridge.path,i,{signal:t.signal}),s={udid:e.target.simulator.udid,bridgePath:e.bridge.path,socketPath:i,process:a};this.sessions.set(n,s);try{return s.socket=await this.connectUntilReady(s,t),s}catch(e){throw await this.removeSession(s,!0),f(e)}}async connectUntilReady(e,t){let n;for(;;){let r=s(t,`bridge-connect-deadline`);if(!e.process.isAlive())throw await C(this.host,e.process);try{return await this.host.connect(e.socketPath,{signal:t.signal,timeoutMs:Math.min(250,r)})}catch(e){if(n=e,e instanceof h&&e.failureKind===`cancelled`)throw e;let r=Math.min(20,s(t,`bridge-connect-deadline`));try{await c(t,r,`bridge-connect-deadline`)}catch(e){throw f(e)}}if(n instanceof h&&n.failureKind===`timeout`)throw n}}async exchange(e,t,n){(!e.socket||e.socket.destroyed)&&(e.socket=await this.connectUntilReady(e,n));let r=b(),i=ie(D({requestId:r,pid:t.target.pid,generation:t.target.generation,maxDepth:Math.min(t.limits.maxTraversalDepth,t.maxDepth),maxNodes:t.limits.maxNodes,maxDurationMs:s(n,`bridge-request-deadline`),maxResponseBytes:t.limits.maxResponseBytes,...t.nativeLevelsHint===void 0?{}:{nativeLevelsHint:t.nativeLevelsHint}}),t.limits);return await oe({process:e.process,socket:e.socket,frame:i,requestId:r,deadline:n,limits:t.limits,expectedPid:t.target.pid,expectedGeneration:t.target.generation,host:this.host})}async readTargetStartTime(e,t){let n=await this.host.readTargetProcessStartTime(e.pid,{signal:t.signal,timeoutMs:s(t,`target-identity-deadline`)});if(!n)throw l(`stale-target`,`target-process-unavailable`,{pid:e.pid,generation:e.generation});if(e.processStartTime!==void 0&&e.processStartTime!==n)throw l(`stale-target`,`target-process-changed`,{pid:e.pid,generation:e.generation,expectedStartTime:e.processStartTime,observedStartTime:n});return n}async assertTargetStillCurrent(e,t,n){let r=await this.host.readTargetProcessStartTime(e.pid,{signal:n.signal,timeoutMs:s(n,`target-identity-deadline`)});if(r!==t)throw l(`stale-target`,`target-process-changed`,{pid:e.pid,generation:e.generation,expectedStartTime:t,observedStartTime:r})}async removeSession(e,t){this.sessions.get(e.udid)===e&&this.sessions.delete(e.udid),await this.dispose(e,t)}async dispose(e,t){e.socket?.destroy(),e.socket=void 0,t&&e.process.isAlive()&&(e.process.signal(`SIGTERM`),await M(e.process,500),e.process.isAlive()&&(e.process.signal(`SIGKILL`),await M(e.process,500))),await this.host.remove(e.socketPath)}};async function ce(e,t){let n=s(t,`bridge-request-deadline`);await Promise.race([e,c(t,n,`bridge-request-deadline`).then(()=>{throw l(`timeout`,`bridge-request-deadline`)})])}function le(e,t,n){return(e.failureKind===`cancelled`||e.failureKind===`timeout`)&&(e.details?.dispatched===!0||n!==t)}async function M(e,t){await Promise.race([e.wait.catch(()=>void 0),new Promise(e=>setTimeout(e,t))])}const N=16777216,P=12e4,F=1e4,I=Object.freeze({maxRequestBytes:65536,maxResponseBytes:4194304,maxNodes:5e3,maxTraversalDepth:64,maxDurationMs:5e3});function L(t){let n={...I,...t??{}};for(let[t,r]of Object.entries(n))if(!Number.isSafeInteger(r)||r<=0)throw new e(`INVALID_ARGS`,`Snapshot source limit ${t} must be a positive integer`,{name:t,value:r});if(n.maxRequestBytes>n.maxResponseBytes)throw new e(`INVALID_ARGS`,`Snapshot source request bytes cannot exceed response bytes`,{maxRequestBytes:n.maxRequestBytes,maxResponseBytes:n.maxResponseBytes});if(n.maxRequestBytes>N||n.maxResponseBytes>N)throw new e(`INVALID_ARGS`,`Snapshot source frame limits exceed the bridge bound`,{maxRequestBytes:n.maxRequestBytes,maxResponseBytes:n.maxResponseBytes,maximumFrameBytes:N});if(n.maxNodes>F||n.maxTraversalDepth>128)throw new e(`INVALID_ARGS`,`Snapshot source tree limits exceed the bridge bound`,{maxNodes:n.maxNodes,maxTraversalDepth:n.maxTraversalDepth,maximumNodes:F,maximumDepth:128});if(n.maxDurationMs>P)throw new e(`INVALID_ARGS`,`Snapshot source duration exceeds the bridge bound`,{maxDurationMs:n.maxDurationMs,maximumDurationMs:P});if(n.maxRequestBytes<=4||n.maxResponseBytes<=4)throw new e(`INVALID_ARGS`,`Snapshot source frame limits must leave room for a body`,{maxRequestBytes:n.maxRequestBytes,maxResponseBytes:n.maxResponseBytes});return Object.freeze(n)}const R=12e4;async function z(e){let t=e.deadline,n=e.sourceRoot??V(e.host),r=await g(e.host,n,_,t),i=await d(e.host,e.runtime,t),a=e.cacheRoot??y.join(e.host.homeDirectory(),`.agent-device`,`snapshot-source`),o=await ee({host:e.host,deadline:t,cacheRoot:a,binaryFilename:`snapshot-bridge`,lockDescription:`iOS Simulator snapshot bridge cache`,keyInputs:{schemaVersion:1,protocolVersion:1,sourceVersion:w,sourceHash:r,toolchain:i,compileArgv:B({architecture:i.architecture,sourceRoot:``,outputPath:``})},build:async r=>{let a=await p({host:e.host,deadline:t,argv:B({architecture:i.architecture,sourceRoot:n,outputPath:r}),budgetMs:R,label:`bridge`});if(a.exitCode!==0||!e.host.exists(r))throw l(`unsupported`,`native-build-failed`,{exitCode:a.exitCode,stderr:a.stderr.slice(0,4096)})}});return{path:o.path,sourceHash:r,cacheKey:o.cacheKey,protocolVersion:1,sourceVersion:w}}function B(e){return[`--sdk`,`iphonesimulator`,`clang`,`-arch`,e.architecture,`-mios-simulator-version-min=15.0`,`-fobjc-arc`,`-Wall`,`-Wextra`,`-framework`,`Foundation`,`-framework`,`CoreGraphics`,...m.map(t=>y.join(e.sourceRoot,t)),`-o`,e.outputPath]}function V(e){let t=e.projectRoot(),n=y.join(t,`apple`,`snapshot-bridge`);if(_.every(t=>e.exists(y.join(n,t))))return n;let r=y.join(t,`dist`,`apple`,`snapshot-bridge`);if(_.every(t=>e.exists(y.join(r,t))))return r;throw l(`unsupported`,`native-source-missing`,{projectRoot:t})}const H=i+R;function U(e){let t=e.now??Date.now,n=new Map,r=a({waitMs:2e3,waitGrant:`first-caller`,retryAfterMs:6e4,now:t}),i=async(r,i)=>{let a=v(H,i,t);try{let t=await e.host.withDiagnosticTimer(`ios.snapshot-source.prepare`,async()=>await z({host:e.host,runtime:r,limits:e.limits,deadline:a,sourceRoot:e.sourceRoot,cacheRoot:e.cacheRoot}),{producer:e.producer});return n.set(r,t),t}catch(e){throw f(e)}};return{readyBinary:async(e,t,a)=>n.get(e)||await r.value(e,{start:t=>i(e,t),wait:(e,n)=>c(t,e,a,n),pending:()=>l(`preparing`,`bridge-preparation-pending`)}),close:()=>{n.clear(),r.close()}}}function W(e,n){return!t(e)||!t(n)||Math.abs(n.width-n.height)<=1?!1:Math.abs(e.width-n.height)<=1&&Math.abs(e.height-n.width)<=1}const G=Object.freeze({elementType:`XC_kAXXCAttributeElementType`,elementBaseType:`XC_kAXXCAttributeElementBaseType`,label:`XC_kAXXCAttributeLabel`,value:`XC_kAXXCAttributeValue`,placeholder:`XC_kAXXCAttributePlaceholderValue`,identifier:`XC_kAXXCAttributeIdentifier`,frame:`XC_kAXXCAttributeFrame`,automationType:`XC_kAXXCAttributeAutomationType`,traits:`XC_kAXXCAttributeTraits`,userInteractionEnabled:`XC_kAXXCAttributeIsUserInteractionEnabled`,children:`XC_kAXXCAttributeChildren`}),K=`Other.Other.Application.Group.Window.Sheet.Drawer.Alert.Dialog.Button.RadioButton.RadioGroup.CheckBox.DisclosureTriangle.PopUpButton.ComboBox.MenuButton.ToolbarButton.Popover.Keyboard.Key.NavigationBar.TabBar.TabGroup.Toolbar.StatusBar.Table.TableRow.TableColumn.Outline.OutlineRow.Browser.CollectionView.Slider.PageIndicator.ProgressIndicator.ActivityIndicator.SegmentedControl.Picker.PickerWheel.Switch.Toggle.Link.Image.Icon.SearchField.ScrollView.ScrollBar.StaticText.TextField.SecureTextField.DatePicker.TextView.Menu.MenuItem.MenuBar.MenuBarItem.Map.WebView.IncrementArrow.DecrementArrow.Timeline.RatingIndicator.ValueIndicator.SplitGroup.Splitter.RelevanceIndicator.ColorWell.HelpTag.Matte.DockItem.Ruler.RulerMarker.Grid.LevelIndicator.Cell.LayoutArea.LayoutItem.Handle.Stepper.Tab.TouchBar.StatusItem`.split(`.`),q={UIApplication:`Application`,UIWindow:`Window`},ue=new Set(Object.values(G)),de=1n<<8n,fe=1n<<3n,pe={x:0,y:0,width:0,height:0};function me(e,t,n){let r=Array.isArray(e)?e:[e];if(r.length===0||r.some(e=>!j(e)))throw l(`malformed-tree`,`guest-tree-root-invalid`);let i=[],a=[],o=0;for(let e of r)c(e,void 0,0,!1);if(i.length>n.maxNodes)throw l(`malformed-tree`,`node-limit-exceeded`,{nodeCount:i.length,maxNodes:n.maxNodes});if(o>n.maxTraversalDepth)throw l(`malformed-tree`,`traversal-depth-exceeded`,{maxTraversalDepth:o,maxAllowedDepth:n.maxTraversalDepth});if(typeof t.truncated!=`boolean`)throw l(`malformed-tree`,`truncated-invalid`);let s=ye(i.filter(Y)[0]);return s.kind===`reported`&&be(i,s.rect),{nodes:i,maxTraversalDepth:o,viewport:s,opaqueRemoteElements:a.filter(e=>_e(e,s)).length,unresolvedCoordinateSpaceWindows:xe(i,s)};function c(e,t,r,s){if(i.length>=n.maxNodes)throw l(`malformed-tree`,`node-limit-exceeded`,{maxNodes:n.maxNodes});for(let t of Object.keys(e))if(!ue.has(t))throw l(`malformed-tree`,`node-contains-unknown-field`,{key:t});let u=e[G.children];if(!Array.isArray(u))throw l(`malformed-tree`,`children-invalid`);let d=i.length,f=he(e,d,t,r);i.push(f),o=Math.max(o,r),ge(f,u.length,s)&&a.push(f.rect);let p=s||f.type===`WebView`;for(let e of u){if(!j(e))throw l(`malformed-tree`,`child-invalid`);c(e,d,r+1,p)}}}function he(e,t,n,r){let i=X(e[G.elementType]),a=X(e[G.elementBaseType]),o=Te(e[G.automationType]),s=ve(e[G.frame]),c=Ce(e[G.traits]),l=c===void 0?void 0:(c&de)===0n,u=c===void 0||(c&fe)===0n?void 0:!0,d=we(e[G.userInteractionEnabled]),f=X(e[G.placeholder])?.trim();return{index:t,...n===void 0?{}:{parentIndex:n},...J(i,o)?{type:J(i,o)}:{},...i?{role:i}:{},...a&&a!==i?{subrole:a}:{},...X(e[G.label])?{label:X(e[G.label])}:{},...Z(e[G.value])?{value:Z(e[G.value])}:{},...f?{placeholder:f}:{},...X(e[G.identifier])?{identifier:X(e[G.identifier])}:{},...s?{rect:s}:{},...l===void 0?{}:{enabled:l},...u===void 0?{}:{selected:u},...d===void 0?{}:{userInteractionEnabled:d},depth:r}}function J(e,t){if(e!==void 0&&q[e])return q[e];if(e!==void 0&&K.includes(e))return e;if(t!==void 0)return K[t]??`Other`}function ge(e,t,n){return n&&e.role===`AXRemoteElement`&&t===0}function _e(e,r){return e===void 0?!0:t(e)?r.kind!==`reported`||n(e,r.rect):!1}function ve(e){if(e===void 0)return;if(!j(e))throw l(`malformed-tree`,`frame-invalid`);let t=[`X`,`Y`,`Width`,`Height`].map(t=>e[t]);if(!t.every(e=>typeof e==`number`&&Number.isFinite(e)))throw l(`malformed-tree`,`frame-invalid`);let[n,r,i,a]=t;if(i<0||a<0)throw l(`malformed-tree`,`frame-invalid`);return{x:n,y:r,width:i,height:a}}function ye(e){return!e||!Y(e)?{kind:`missing`,reason:`not-provided`}:t(e.rect)?{kind:`reported`,rect:e.rect}:{kind:`missing`,reason:e.rect?`invalid`:`not-provided`}}function Y(e){return e.type===`Application`||e.type===`Window`}function be(e,t){for(let n of e)n.hittable=n.parentIndex!==void 0&&r(n.enabled!==!1,n.rect,t)}function xe(e,t){return t.kind===`reported`?e.filter(n=>Se(n,e)&&W(n.rect??pe,t.rect)).length:0}function Se(e,t){return Y(e)?!0:e.parentIndex!==void 0&&Y(t[e.parentIndex]??e)}function X(e){return typeof e==`string`&&e.length>0?e:void 0}function Z(e){if(typeof e==`string`)return e.length>0?e:void 0;if(typeof e==`number`||typeof e==`boolean`)return String(e);if(e!=null)throw l(`malformed-tree`,`scalar-invalid`)}function Ce(e){if(e!=null){if(typeof e!=`string`||!/^\d{1,20}$/.test(e))throw l(`malformed-tree`,`traits-invalid`);return BigInt(e)}}function we(e){if(e!=null){if(typeof e!=`boolean`)throw l(`malformed-tree`,`user-interaction-invalid`);return e}}function Te(e){if(e!=null){if(!Number.isSafeInteger(e))throw l(`malformed-tree`,`automation-type-invalid`);return e}}const Q=`simulator-ax-bridge`;function Ee(e={}){let t=e.host??u(),n=new se(t),r=new te,i=U({host:t,limits:L(e.limits),producer:Q,sourceRoot:e.sourceRoot,cacheRoot:e.cacheRoot}),a=!1;return{acquire:async o=>{try{if(a)throw l(`unsupported`,`source-closed`);De(o);let c=L({...e.limits,...o.limits}),u=v(c.maxDurationMs,o.signal),d=ke(o.hint,c.maxTraversalDepth),f=d+1,p=o.hint.rawTraversalDepth!==null;return await t.withDiagnosticTimer(`ios.snapshot-source.acquire`,async()=>{let e=await i.readyBinary(o.target.runtime,u,`bridge-preparation-deadline`),a=r.consume(o.target,f,p),l=await n.request({target:o.target,bridge:e,limits:c,maxDepth:d,nativeLevelsHint:a.nativeLevels,deadline:u});s(u,`snapshot-decode-deadline`);let m=Ae(o.hint,o.target,l,c);return Oe(t,r,o.target,f,p,a,l),{stage:`acquired`,acquisition:m}},{producer:Q})}catch(e){let t=f(e);return{stage:`failed`,failure:{kind:t.failureKind,code:t.failureCode,...t.details?{details:t.details}:{}}}}},close:async()=>{a||(a=!0,i.close(),await n.close())}}}function De(t){if(!t.target.simulator.udid.trim()||!t.target.runtime.trim()||!t.target.generation.trim()||!Number.isSafeInteger(t.target.pid)||t.target.pid<=0)throw new e(`INVALID_ARGS`,`Simulator snapshot source target identity is incomplete`);let n=t.hint;if(n.projection!==`raw`&&n.projection!==`regular`||![`full`,`surface-observation`].includes(n.acquisitionIntent)||typeof n.interactiveOnly!=`boolean`||typeof n.customActions!=`boolean`||!$(n.rawTraversalDepth)||!$(n.regularPresentedDepth))throw new e(`INVALID_ARGS`,`Simulator snapshot source capture hint is invalid`)}function Oe(e,t,n,r,i,a,o){let s=re(o),c=o.truncated===!0,l=t.learn(n,r,i,s);e.emitDiagnostic({level:`debug`,phase:`ios_snapshot_source_recovery`,data:{producer:Q,...n.targetId?{targetId:n.targetId}:{},generation:n.generation,requestedLevels:r,hint:a.reason,...a.nativeLevels===void 0?{}:{hintedLevels:a.nativeLevels},...s,truncated:c,learning:l}})}function ke(t,n){let r=t.rawTraversalDepth??n;if(r>n)throw new e(`INVALID_ARGS`,`Simulator snapshot source depth exceeds its bound`,{requested:r,maximum:n});return r}function $(e){return e===null||Number.isSafeInteger(e)&&e>=0}function Ae(e,t,n,r){if(n.automationEnabled!==!0)throw l(`unsupported`,`automation-mode-unavailable`);let i=n.tree,a=n.truncated;if(typeof a!=`boolean`)throw l(`malformed-tree`,`truncated-invalid`);let o=me(i,{truncated:a},r),s=n.generation;if(typeof s!=`string`||!s)throw l(`malformed-tree`,`generation-invalid`);if(o.opaqueRemoteElements>0)throw l(`unsupported`,`remote-content-boundary`,{remoteElements:o.opaqueRemoteElements});if(o.unresolvedCoordinateSpaceWindows>0)throw l(`unsupported`,`window-coordinate-space-unresolved`,{windows:o.unresolvedCoordinateSpaceWindows});let c=Object.freeze(o.nodes.map(e=>Object.freeze({...e,pid:t.pid}))),u=je(e,a,o.viewport),d=Object.freeze({...t.targetId?{targetId:t.targetId}:{},generation:s}),f={producer:Q,nodes:c,truncated:a,viewport:o.viewport,lineage:d,residue:u};return e.acquisitionIntent===`full`?{...f,intent:`full`,hint:{...e,acquisitionIntent:`full`}}:{...f,intent:`surface-observation`,hint:{...e,acquisitionIntent:`surface-observation`}}}function je(e,t,n){let r=n.kind===`reported`?[]:[{kind:`unavailable-fact`,fact:`hittability`}];return Object.freeze([...r,...e.interactiveOnly?[{kind:`unavailable-fact`,fact:`interactive-query`}]:[],...t?[{kind:`truncated`}]:[],...n.kind===`missing`?[{kind:`missing-viewport`,reason:n.reason}]:[]])}export{Ee as createSimulatorSnapshotSource};