stim 1.20.2 → 1.22.0

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 (231) hide show
  1. package/README.md +141 -8
  2. package/dist/acquire-artifact-Co2k4f7O.mjs +171 -0
  3. package/dist/act-DsuqEkiM.mjs +2801 -0
  4. package/dist/activity-CMLmzp7o.mjs +1397 -0
  5. package/dist/{agent-device-usage-output-Dzgv6lgR.mjs → agent-device-usage-output-DUFaTMdd.mjs} +23 -67
  6. package/dist/{android-DCKZrNvV.mjs → android-ByRMUoiJ.mjs} +157 -93
  7. package/dist/{android-Mz_Inn3w.mjs → android-C7sVmyI9.mjs} +299 -116
  8. package/dist/{android-Dlzxshgp.mjs → android-DGkNqa_c.mjs} +5 -5
  9. package/dist/{android-HqP1_vB_.mjs → android-DR5lZ2Az.mjs} +2 -2
  10. package/dist/android-cas-compiler.mjs +2 -2
  11. package/dist/{android-cas-Bl-cLJBk.mjs → android-cas-ngferVq2.mjs} +7 -6
  12. package/dist/android-project-BCAAmMwz.mjs +12 -0
  13. package/dist/android-project-DVWyCbWU.d.mts +391 -0
  14. package/dist/api.d.mts +810 -64
  15. package/dist/api.mjs +782 -1
  16. package/dist/{artifact-HSwkIWEQ.mjs → artifact-8EY8SAPw.mjs} +240 -213
  17. package/dist/{artifact-D3czlUvT.mjs → artifact-DJPy518Y.mjs} +203 -164
  18. package/dist/artifact-platform-CXcmX_j3.mjs +27 -0
  19. package/dist/{browser-web-CA-F1GQo.mjs → browser-web-Bcv99PBM.mjs} +194 -64
  20. package/dist/budget-Cvwn54qV.mjs +9285 -0
  21. package/dist/{build-DYDbfkk5.mjs → build-CabC3G23.mjs} +153 -98
  22. package/dist/build-cache-Dv7RN200.mjs +602 -0
  23. package/dist/build-plan-DUC8Ka9y.mjs +248 -0
  24. package/dist/{cache-manifest-XH-fvDUj.mjs → cache-manifest-DSeQjt-Q.mjs} +2 -2
  25. package/dist/cache-manifest.mjs +1 -1
  26. package/dist/{ccache-zdKiYQ3E.mjs → ccache-Btwc36-I.mjs} +10 -9
  27. package/dist/{cdp-Dq_ypAlJ.mjs → cdp-3fwICjzi.mjs} +18 -5
  28. package/dist/{chrome-BnzZMqsR.mjs → chrome-Bbw689-6.mjs} +7 -4
  29. package/dist/{cli-CLP3diBm.mjs → cli-CHZa9Lvk.mjs} +20 -20
  30. package/dist/cli.mjs +1 -1
  31. package/dist/client-OyRoEuSr.mjs +1577 -0
  32. package/dist/collector-run.d.mts +4 -40
  33. package/dist/collector-run.mjs +9 -8
  34. package/dist/{command-output-BTy8hZ0F.mjs → command-output-gwpm28fu.mjs} +1 -1
  35. package/dist/config-DlrsduwG.mjs +955 -0
  36. package/dist/{created-devices-Dzd5C2LF.mjs → created-devices-x9rN6bhs.mjs} +14 -4
  37. package/dist/{dependency-state-DG0p31-y.mjs → dependency-state-1I9KZT1Y.mjs} +20 -5
  38. package/dist/{detached-entry-B9C_zeQC.mjs → detached-entry-BwNEtIrP.mjs} +1 -1
  39. package/dist/{dev-client-DAWVIGBu.mjs → dev-client-BSDR5h3F.mjs} +2 -2
  40. package/dist/{device-BECOiufl.mjs → device-B-L3Fbxy.mjs} +91 -34
  41. package/dist/device-DklWZLqb.mjs +1068 -0
  42. package/dist/{device-capacity-CBUAcRyQ.mjs → device-capacity-DK5_EwRS.mjs} +42 -13
  43. package/dist/device-host-worker.mjs +76 -79
  44. package/dist/{device-ios-COSi6oS1.mjs → device-ios-DoB6KFCO.mjs} +77 -51
  45. package/dist/{device-lease-run-Cw2M4z51.mjs → device-lease-run-xJPQ_QQG.mjs} +14 -26
  46. package/dist/{device-pool-Bf-pOhSw.mjs → device-pool-BMkdsefq.mjs} +5 -5
  47. package/dist/{doctor-kfMBnUw6.mjs → doctor-Bo7BXLux.mjs} +271 -320
  48. package/dist/{doctor-CB8oZKCk.mjs → doctor-D5_EzwfA.mjs} +186 -91
  49. package/dist/doctor-fingerprint-DZLoYFVb.mjs +16 -0
  50. package/dist/doctor-fingerprint.mjs +19 -0
  51. package/dist/doctor-thjWAV0z.mjs +2 -0
  52. package/dist/{doctor-watchman-BRyV2adA.mjs → doctor-watchman-N2wDotwQ.mjs} +40 -21
  53. package/dist/{eas-build-JyfqyHfC.mjs → eas-build-CwknaQYj.mjs} +53 -20
  54. package/dist/{build-plan-B7SZsc2N.mjs → eas-fallback-CSgAulr5.mjs} +41 -214
  55. package/dist/{watchman-CPQFZLXY.mjs → eas-session-ledger-DlY_serQ.mjs} +230 -11
  56. package/dist/{error-diagnostics-BR677IDM.mjs → error-diagnostics-DBWO2rxE.mjs} +172 -82
  57. package/dist/exec-DEoAhcze.mjs +858 -0
  58. package/dist/exec-DnYc4HGH.d.mts +78 -0
  59. package/dist/{gc-qWOMdnER.mjs → gc-CXxN-4SE.mjs} +1091 -1029
  60. package/dist/gc-DnNDQyaP.mjs +3 -0
  61. package/dist/{guide-G9cAbVAc.mjs → guide-Br0LEfKy.mjs} +1165 -297
  62. package/dist/{hosted-android-C3MHGld1.mjs → hosted-android-B-9f-jkd.mjs} +10 -8
  63. package/dist/{hosted-client-ZEKpS9vw.mjs → hosted-client-DZAPrcro.mjs} +34 -19
  64. package/dist/{hosted-ios-l-o3iM9J.mjs → hosted-ios-CsCS21hn.mjs} +1 -1
  65. package/dist/{hosted-logs-EzQM7-3Z.mjs → hosted-logs-FIRx9X2f.mjs} +77 -43
  66. package/dist/{hosted-macos-BACVAVqE.mjs → hosted-macos-_awYSpfv.mjs} +35 -22
  67. package/dist/{hosted-native-A4s1QPXe.mjs → hosted-native-BdzE668-.mjs} +49 -27
  68. package/dist/idle-C4cZ757K.d.mts +24 -0
  69. package/dist/{idle-shutdown-DtxhPTKe.mjs → idle-shutdown-DDg3SdvY.mjs} +11 -10
  70. package/dist/ios-CDvlmUs7.d.mts +24 -0
  71. package/dist/{ios-BwVCF7oA.mjs → ios-Ds1clbIt.mjs} +8 -8
  72. package/dist/{ios-device-D7pi2Sca.mjs → ios-device--h_-8ENa.mjs} +51 -26
  73. package/dist/{ios-device-B5veSDDQ.mjs → ios-device-BXZ0c7Kb.mjs} +1 -1
  74. package/dist/{ios-RkW4pnQf.mjs → ios-hcBpnEGk.mjs} +200 -93
  75. package/dist/{ios-Ce7bc7br.mjs → ios-pm4nL6By.mjs} +160 -108
  76. package/dist/{ios-project-K9hY_Jab.mjs → ios-project-CZhKODF3.mjs} +13 -13
  77. package/dist/ios-signing-BtAffm0A.mjs +489 -0
  78. package/dist/{ios-state-CBLe1xYw.mjs → ios-state-Dtw5K2aI.mjs} +1 -1
  79. package/dist/{ios-nOLJGVdy.mjs → ios-xtlRHaeB.mjs} +1 -1
  80. package/dist/{js-swap-Bb3nsS07.mjs → js-swap-Bwhh4S7V.mjs} +30 -25
  81. package/dist/{launch-C3qJ6Agb.mjs → launch-BjxemNpK.mjs} +85 -543
  82. package/dist/{launch-F4sOqAhB.mjs → launch-CCzXlc8r.mjs} +91 -90
  83. package/dist/logs-BfwwadsZ.mjs +479 -0
  84. package/dist/logs-jTS_lHSo.mjs +248 -0
  85. package/dist/{macos-D7uDvO-z.mjs → macos-DVlSSyUg.mjs} +1 -1
  86. package/dist/macos-NfV2D7dO.mjs +694 -0
  87. package/dist/macos-run.mjs +1 -1
  88. package/dist/maintenance-run.mjs +123 -248
  89. package/dist/{metro-DnCEjCxs.mjs → metro-DiXtA3Ty.mjs} +107 -30
  90. package/dist/metro-gateway-CKZqKqx7.mjs +209 -0
  91. package/dist/{named-ports-4WopRPg-.mjs → named-ports-DkEzOfzO.mjs} +42 -90
  92. package/dist/native-android-CqgnOgsT.mjs +645 -0
  93. package/dist/native-gradle-artifact-inputs-DHFnmrVf.mjs +270 -0
  94. package/dist/native-gradle-inputs-Dnh84Zbd.mjs +211 -0
  95. package/dist/native-inputs-TRTTTRxt.mjs +91 -0
  96. package/dist/native-run-NwUuxbkg.mjs +276 -0
  97. package/dist/{native-runtime-k8dTIrbK.mjs → native-runtime-B7KIafpM.mjs} +11 -9
  98. package/dist/native-source-Y0yLhFyQ.mjs +133 -0
  99. package/dist/{native-xcode-inputs-CykopJdM.mjs → native-xcode-inputs-D_VOfFL7.mjs} +26 -18
  100. package/dist/{native-xcode-ios-Bbf30Gm0.mjs → native-xcode-ios-BYDOHWLN.mjs} +104 -60
  101. package/dist/{ndjson-GOnbyvso.mjs → ndjson-CgE_o3Dl.mjs} +3 -3
  102. package/dist/offload-worker.d.mts +59 -41
  103. package/dist/offload-worker.mjs +478 -115
  104. package/dist/operation-exec-BW0em61G.mjs +171 -0
  105. package/dist/{ownership-DCtw_2IA.mjs → ownership-C5fo5Edb.mjs} +3 -3
  106. package/dist/{page-DRHy329N.mjs → page-DBL2PiUU.mjs} +12 -5
  107. package/dist/paths-BsJMoPP2.mjs +12 -0
  108. package/dist/paths-DQtTgsBf.mjs +42 -0
  109. package/dist/{placement-log-MOfPVgaM.mjs → placement-log-BnGgJRRZ.mjs} +5 -5
  110. package/dist/{plan-placement-V0TdzYXp.mjs → plan-placement-DIsMtN-d.mjs} +15 -11
  111. package/dist/{ports-DdSUicVo.mjs → ports-Cy1RkmuQ.mjs} +3 -3
  112. package/dist/prebuild-D4JoEAEs.mjs +484 -0
  113. package/dist/{project-_phNIJfs.mjs → project-wM_XFTvE.mjs} +65 -37
  114. package/dist/{pull-request-CQ8sPbZa.mjs → pull-request-W1IuLXDt.mjs} +102 -20
  115. package/dist/pull-request-eODyIqZF.d.mts +124 -0
  116. package/dist/pull-requests.d.mts +2 -120
  117. package/dist/pull-requests.mjs +2 -2
  118. package/dist/{react-native-android-CM1XRDwv.mjs → react-native-android-6OZ7MSM7.mjs} +121 -72
  119. package/dist/{gradle-DSrXb6lG.mjs → react-native-build-Dvd8hC21.mjs} +292 -15
  120. package/dist/react-native-doctor-DsoSF1Y9.mjs +234 -0
  121. package/dist/{react-native-ios-Dhq_eiYQ.mjs → react-native-ios-4u1Rn-GR.mjs} +71 -39
  122. package/dist/{recordings-D0d5aQt0.mjs → recordings-CQmfzAh7.mjs} +12 -9
  123. package/dist/registration-BcRgF6Ox.mjs +51 -0
  124. package/dist/{reload-C8JhxjSh.mjs → reload-BzkYabB-.mjs} +94 -47
  125. package/dist/reload-D7AVlb8N.mjs +2 -0
  126. package/dist/{remote-BiR6aYjy.mjs → remote-DjGDmlTZ.mjs} +26 -18
  127. package/dist/result-D2Ykz_iD.mjs +435 -0
  128. package/dist/{run-BtPgpKks.mjs → run-DidHghD1.mjs} +5 -5
  129. package/dist/selection-DSMbWEX2.mjs +620 -0
  130. package/dist/{server-bare-R2m_gsH8.mjs → server-bare-CafzuyFB.mjs} +3 -4
  131. package/dist/{server-command-CTtCkmcQ.mjs → server-command-C6QjeupS.mjs} +14 -7
  132. package/dist/{server-expo-DsguMGUF.mjs → server-expo-CrjB29pq.mjs} +54 -11
  133. package/dist/server-expo-D58c9L0M.mjs +2 -0
  134. package/dist/{settings-B717odTD.mjs → settings-C7O8A6ZI.mjs} +309 -119
  135. package/dist/settings-DpR-1Wnn.mjs +114 -0
  136. package/dist/settings-write-CzD60rOD.mjs +360 -0
  137. package/dist/settings.schema.json +176 -16
  138. package/dist/{simslim-CCr3rE-A.mjs → simslim-BNckWpXi.mjs} +14 -12
  139. package/dist/{slot-launch-DPt0m9Nd.mjs → slot-launch-CbfmNgM6.mjs} +15 -20
  140. package/dist/{spawn-entry-Dcb7sDUz.mjs → spawn-entry-jw19m8Nl.mjs} +0 -1
  141. package/dist/stage-Bps5oius.mjs +200 -0
  142. package/dist/{start-TXeMmmO2.mjs → start-Br-oxqMD.mjs} +1 -1
  143. package/dist/start-EojN4WFz.mjs +1364 -0
  144. package/dist/{state-D1Icyjlu.mjs → state--smjFSTL.mjs} +55 -13
  145. package/dist/{state-CG_OFoaA.mjs → state-08I3hw3_.mjs} +3 -2
  146. package/dist/{stats-BoY5sEPU.mjs → stats-D3GerlFW.mjs} +7 -13
  147. package/dist/stats-report-BzaPrRm6.mjs +16 -0
  148. package/dist/{status-BTA7kKiQ.mjs → status-BRROykC8.mjs} +7 -5
  149. package/dist/status-EvrK72L2.mjs +2 -0
  150. package/dist/{status-WgFbkRzj.mjs → status-WBDajew2.mjs} +554 -452
  151. package/dist/{status-watch-C23ILtf9.mjs → status-watch-Bg_u-pwR.mjs} +222 -25
  152. package/dist/status-worker.d.mts +1 -0
  153. package/dist/status-worker.mjs +19 -0
  154. package/dist/stim-desktop-D5OGpYZM.mjs +112 -0
  155. package/dist/{stop-DR6VoDIk.mjs → stop-DTZ9uTw3.mjs} +2 -2
  156. package/dist/{stop-DPEhunlw.mjs → stop-Dky10AEJ.mjs} +33 -23
  157. package/dist/{stop-BNmBMi1F.mjs → stop-Mv6W9FAk.mjs} +137 -98
  158. package/dist/supervisor-run.d.mts +8 -17
  159. package/dist/supervisor-run.mjs +56 -28
  160. package/dist/{support-CwjbFs9H.mjs → support-CNioewsd.mjs} +14 -14
  161. package/dist/{support-DMTqj3Hm.mjs → support-yUiOjnVY.mjs} +20 -13
  162. package/dist/swiftpm-artifact-inputs-DFcGsXDP.mjs +153 -0
  163. package/dist/swiftpm-macos-BIak-Rxv.mjs +532 -0
  164. package/dist/toolchain-BY8X8HXx.mjs +2 -0
  165. package/dist/toolchain-DpJMHq0n.mjs +876 -0
  166. package/dist/{trigger-CigAYjeL.mjs → trigger-Cbyc41d_.mjs} +21 -6
  167. package/dist/trigger-yb_nFzPF.mjs +2 -0
  168. package/dist/{warm-progress-BuY-Fvfn.mjs → warm-progress-CA3TgT3-.mjs} +263 -156
  169. package/dist/web-CZ07gd77.mjs +2 -0
  170. package/dist/{web-BDBMxDpx.mjs → web-DKx6yoFA.mjs} +20 -14
  171. package/dist/web-run.mjs +13 -12
  172. package/dist/windows-report.d.mts +1 -0
  173. package/dist/windows-report.mjs +18 -0
  174. package/dist/windows-report.ps1 +43 -0
  175. package/dist/{workspace-state-DJt_MMvf.mjs → workspace-state-U08dEzhG.mjs} +62 -58
  176. package/dist/{workspaces-C36s2jb9.mjs → workspaces-CpANmBlq.mjs} +1723 -1286
  177. package/dist/{worktree-CgvJYJ-Q.mjs → worktree-CHecZ4Oq.mjs} +1097 -547
  178. package/dist/worktree-ZqZVjD9K.mjs +2 -0
  179. package/dist/xcode-BXn9-xYx.mjs +896 -0
  180. package/package.json +7 -5
  181. package/shim/android-audio/Main.java +24 -0
  182. package/shim/android-audio/README.md +17 -0
  183. package/shim/android-audio.jar +0 -0
  184. package/shim/android-optimizations.gradle +7 -5
  185. package/dist/activity-BSV745Kz.mjs +0 -629
  186. package/dist/api-qvOzWyfO.mjs +0 -154
  187. package/dist/api-run.mjs +0 -294
  188. package/dist/app-install-BIKtMfPq.mjs +0 -896
  189. package/dist/artifact-lifecycle-DzPpBYvK.mjs +0 -30
  190. package/dist/budget-f7516Zk0.mjs +0 -4106
  191. package/dist/build-facts-DcLv2HSd.d.mts +0 -111
  192. package/dist/cancellation-C_22VQTH.mjs +0 -24
  193. package/dist/client-qQAaXSUs.mjs +0 -1771
  194. package/dist/config-BYDxlMY3.mjs +0 -562
  195. package/dist/device-DuiPJQSn.mjs +0 -290
  196. package/dist/device-lease-BX1sJQ2E.mjs +0 -1224
  197. package/dist/device-remote-xRT0Vmo9.mjs +0 -1272
  198. package/dist/eas-session-ledger-Cm0Gwq2F.mjs +0 -207
  199. package/dist/exec-DqKo9GKJ.mjs +0 -268
  200. package/dist/git-DDfFzkMm.mjs +0 -45
  201. package/dist/launch-verify-B6Q8hZP-.mjs +0 -428
  202. package/dist/logs-BGrEUaEs.mjs +0 -383
  203. package/dist/macos-Ch5VJmcS.mjs +0 -584
  204. package/dist/metro-gateway-CX9Xlkq2.mjs +0 -103
  205. package/dist/miss-reason-mKzZ4VvN.mjs +0 -238
  206. package/dist/native-android-D5qc3-_v.mjs +0 -226
  207. package/dist/native-gradle-inputs-BsLRrl7u.mjs +0 -349
  208. package/dist/ndjson-Du3j0AQ9.d.mts +0 -17
  209. package/dist/plan-C4TjdPsR.mjs +0 -260
  210. package/dist/prebuild-DYbucPXy.mjs +0 -212
  211. package/dist/preview-78a9kR_-.mjs +0 -1011
  212. package/dist/react-native-build-CtCccJtb.mjs +0 -239
  213. package/dist/react-native-doctor-CfRnFfjs.mjs +0 -78
  214. package/dist/remote-cache-OyOyVIS3.mjs +0 -526
  215. package/dist/result-CaJg5Iat.mjs +0 -186
  216. package/dist/server-expo-Bigriskl.mjs +0 -2
  217. package/dist/settings-BORNaaCO.mjs +0 -402
  218. package/dist/settings-vk3mJGSm.d.mts +0 -13
  219. package/dist/spawn-claims-DVS5RkMS.mjs +0 -72
  220. package/dist/stage-KNTQopqv.mjs +0 -157
  221. package/dist/start-BWqzODpb.mjs +0 -1116
  222. package/dist/stim-desktop-BzBN2Em2.mjs +0 -63
  223. package/dist/swiftpm-macos-DRNVJWlb.mjs +0 -119
  224. package/dist/tailnet-Dh-qiYzG.mjs +0 -265
  225. package/dist/toolchain-BFkAcstd.mjs +0 -2
  226. package/dist/toolchain-DxSsNssu.mjs +0 -1657
  227. package/dist/trigger-9_USgmxz.mjs +0 -2
  228. package/dist/web-Dq-i3wzJ.mjs +0 -2
  229. package/dist/worktree-DpLdCHga.mjs +0 -2
  230. package/dist/{api-run.d.mts → doctor-fingerprint.d.mts} +0 -0
  231. package/dist/{errors-DzkMYh8Q.mjs → errors-ccaPc4ox.mjs} +2 -2
@@ -0,0 +1,479 @@
1
+ import { g as process_identity_exports } from "./exec-DEoAhcze.mjs";
2
+ import { m as workspaceLogsDir$1 } from "./paths-DQtTgsBf.mjs";
3
+ import { G as projectDeviceSlots, _ as loadConfig$1 } from "./config-DlrsduwG.mjs";
4
+ import { n as pullHostedNativeLogs, t as pullHostedMacosLogs } from "./hosted-logs-FIRx9X2f.mjs";
5
+ import { l as phaseLine } from "./command-output-gwpm28fu.mjs";
6
+ import { f as readAgentDeviceRecordsAsync, n as agentDeviceLiveness, o as envDir } from "./activity-CMLmzp7o.mjs";
7
+ import { l as connectHost } from "./hosted-client-DZAPrcro.mjs";
8
+ import { n as readHostedIos, t as readHostedAndroid } from "./ios-state-Dtw5K2aI.mjs";
9
+ import "./hosted-macos-_awYSpfv.mjs";
10
+ import { i as captureWorkspaceCrashes } from "./error-diagnostics-DBWO2rxE.mjs";
11
+ import { readdirSync, statSync, watch } from "node:fs";
12
+ import { homedir } from "node:os";
13
+ import { dirname, join, relative, resolve, sep } from "node:path";
14
+ import { ambientWrite, configDir } from "@stim-cli/core";
15
+ import { LEVELS, SOURCES, agentDeviceStateDirsAsync, buildCriteria, compileGrep, createAsyncAgentActionReader, followLogs, logFiles, openLogDir, parseSince, readMacosRecord, recordMatches, workspaceStateFile } from "@stim-cli/core/state";
16
+ import { setImmediate } from "node:timers/promises";
17
+ import { realpath } from "node:fs/promises";
18
+ //#region src/devices/agent-actions.ts
19
+ function workspaceAgentTargets(project, macos) {
20
+ const targets = [];
21
+ if (macos?.app && macos.bundleId) targets.push({
22
+ platform: "macos",
23
+ id: macos.launchId,
24
+ slot: "default",
25
+ bundleId: macos.bundleId,
26
+ launchedAt: macos.app.startedAtMicros / 1e3
27
+ });
28
+ let slots;
29
+ try {
30
+ slots = projectDeviceSlots(project);
31
+ } catch {
32
+ return [];
33
+ }
34
+ for (const { slot, platforms } of slots) {
35
+ const { ios, android } = platforms;
36
+ if (ios?.owned && typeof ios.deviceUdid === "string") targets.push({
37
+ platform: "ios",
38
+ id: ios.deviceUdid,
39
+ slot
40
+ });
41
+ if (android?.owned && typeof android.consolePort === "number" && typeof android.avdName === "string") targets.push({
42
+ platform: "android",
43
+ id: `emulator-${android.consolePort}`,
44
+ slot,
45
+ name: android.avdName
46
+ });
47
+ }
48
+ return targets;
49
+ }
50
+ function createAsyncAgentActionReader$1({ targets, sinceTs, home = homedir(), env, now, startOf = process_identity_exports.inspectProcessStart }, signal) {
51
+ let sessionsDirs = [];
52
+ let claimed = /* @__PURE__ */ new Map();
53
+ let canonical = /* @__PURE__ */ new Map();
54
+ const read = createAsyncAgentActionReader({
55
+ sessionsDirs: () => sessionsDirs,
56
+ targets,
57
+ sinceTs,
58
+ now,
59
+ claimedDevice: (session, sessionsDir) => claimed.get(`${canonical.get(dirname(sessionsDir))}\0${session}`) ?? claimed.get(`\0${session}`) ?? null
60
+ }, signal);
61
+ return async (selection) => {
62
+ signal?.throwIfAborted();
63
+ const roots = await agentDeviceStateDirsAsync(home, env);
64
+ canonical = /* @__PURE__ */ new Map();
65
+ const canonicalize = async (path) => {
66
+ if (canonical.has(path)) return canonical.get(path);
67
+ const value = await realpath(path).catch(() => resolve(path));
68
+ canonical.set(path, value);
69
+ return value;
70
+ };
71
+ for (const root of roots) await canonicalize(root);
72
+ sessionsDirs = roots.map((root) => join(root, "sessions"));
73
+ claimed = /* @__PURE__ */ new Map();
74
+ const byId = new Map((typeof targets === "function" ? targets() : targets).map((target) => [target.id, target]));
75
+ if ([...byId.values()].some((target) => target.platform !== "macos")) for (const record of await readAgentDeviceRecordsAsync(home, env)) {
76
+ signal?.throwIfAborted();
77
+ if (record.kind !== "claim" || !record.session || !record.deviceId) continue;
78
+ const target = byId.get(record.deviceId);
79
+ if (!target || target.platform === "macos" || target.name !== void 0 && target.name !== record.deviceName) continue;
80
+ if (agentDeviceLiveness(record, startOf) === "live") claimed.set(`${record.stateDir ? await canonicalize(record.stateDir) : ""}\0${record.session}`, record.deviceId);
81
+ await setImmediate();
82
+ }
83
+ signal?.throwIfAborted();
84
+ return read(selection);
85
+ };
86
+ }
87
+ //#endregion
88
+ //#region src/devices/agent-actions-follow.ts
89
+ function location(root, recursive) {
90
+ let directory = root;
91
+ while (true) {
92
+ try {
93
+ const info = statSync(directory);
94
+ if (info.isDirectory()) return {
95
+ directory,
96
+ identity: `${info.dev}:${info.ino}`,
97
+ recursive: recursive && directory === root
98
+ };
99
+ } catch {}
100
+ const parent = dirname(directory);
101
+ if (parent === directory) throw new Error(`Cannot watch the agent state directory ${root}.`);
102
+ directory = parent;
103
+ }
104
+ }
105
+ function relevant(root, directory, name) {
106
+ if (name === null || directory === root) return true;
107
+ return name.replaceAll("\\", "/").split("/")[0] === relative(directory, root).split(sep)[0];
108
+ }
109
+ function followAgentActions(context, read, onRecord) {
110
+ const home = context.env.HOME ?? homedir();
111
+ const override = context.env.AGENT_DEVICE_STATE_DIR?.trim();
112
+ const workspaces = join(context.home, "workspaces");
113
+ const baseRoots = /* @__PURE__ */ new Map([
114
+ [override ? resolve(override) : join(home, ".agent-device"), true],
115
+ [envDir("AGENT_DEVICE_CLAIMS_DIR", context.env) ?? join(home, ".agent-device", "device-claims"), true],
116
+ [workspaces, false]
117
+ ]);
118
+ let rootCount = baseRoots.size;
119
+ const bindings = /* @__PURE__ */ new Map();
120
+ let stopped = false;
121
+ let reading = false;
122
+ let pending = false;
123
+ let repair;
124
+ let scheduled;
125
+ const refresh = async () => {
126
+ if (stopped) return;
127
+ if (reading) {
128
+ pending = true;
129
+ return;
130
+ }
131
+ reading = true;
132
+ try {
133
+ for (const record of await read()) {
134
+ if (stopped) break;
135
+ onRecord(record);
136
+ }
137
+ } catch {} finally {
138
+ reading = false;
139
+ if (pending) {
140
+ pending = false;
141
+ refresh();
142
+ }
143
+ }
144
+ };
145
+ const scheduleRefresh = () => {
146
+ if (stopped || scheduled !== void 0) return;
147
+ scheduled = setTimeout(() => {
148
+ scheduled = void 0;
149
+ refresh();
150
+ }, 500);
151
+ };
152
+ const reconcile = () => {
153
+ const roots = new Map(baseRoots);
154
+ try {
155
+ for (const entry of readdirSync(workspaces, { withFileTypes: true })) if (entry.isDirectory() || entry.isSymbolicLink()) roots.set(join(workspaces, entry.name, "agent-device"), true);
156
+ } catch {}
157
+ rootCount = roots.size;
158
+ for (const [root, binding] of bindings) {
159
+ if (roots.has(root)) continue;
160
+ bindings.delete(root);
161
+ binding.watcher.close();
162
+ }
163
+ for (const [root, recursive] of roots) {
164
+ let next;
165
+ try {
166
+ next = location(root, recursive);
167
+ } catch {
168
+ continue;
169
+ }
170
+ const current = bindings.get(root);
171
+ if (current?.directory === next.directory && current.identity === next.identity && current.recursive === next.recursive) continue;
172
+ bindings.delete(root);
173
+ current?.watcher.close();
174
+ try {
175
+ const watcher = watch(next.directory, { recursive: next.recursive }, (event, name) => {
176
+ if (stopped || !relevant(root, next.directory, name)) return;
177
+ if (event === "rename" || next.directory !== root) reconcile();
178
+ scheduleRefresh();
179
+ });
180
+ const binding = {
181
+ ...next,
182
+ watcher
183
+ };
184
+ bindings.set(root, binding);
185
+ const lost = () => {
186
+ if (bindings.get(root) !== binding) return;
187
+ bindings.delete(root);
188
+ watcher.close();
189
+ armRepair(500);
190
+ };
191
+ watcher.once("error", lost);
192
+ watcher.once("close", lost);
193
+ } catch {}
194
+ }
195
+ };
196
+ function armRepair(delay) {
197
+ clearTimeout(repair);
198
+ if (stopped) return;
199
+ repair = setTimeout(() => {
200
+ reconcile();
201
+ refresh();
202
+ armRepair(bindings.size < rootCount ? 500 : 1e4);
203
+ }, delay);
204
+ }
205
+ const stop = () => {
206
+ if (stopped) return;
207
+ stopped = true;
208
+ clearTimeout(repair);
209
+ clearTimeout(scheduled);
210
+ for (const { watcher } of bindings.values()) watcher.close();
211
+ bindings.clear();
212
+ context.signal.removeEventListener("abort", stop);
213
+ };
214
+ context.signal.addEventListener("abort", stop, { once: true });
215
+ if (context.signal.aborted) stop();
216
+ else {
217
+ reconcile();
218
+ refresh();
219
+ armRepair(500);
220
+ }
221
+ return stop;
222
+ }
223
+ //#endregion
224
+ //#region src/device-host/hosted-logs-sync.ts
225
+ function warn(context, machine, error) {
226
+ const text = `${warning(machine, error)}\n`;
227
+ if (context) context.output("stderr", text);
228
+ else ambientWrite("stderr", text);
229
+ }
230
+ function warning(machine, error) {
231
+ const message = error.message.replace(/\.$/, "");
232
+ const hint = message.includes("refused device-host.logs.query") ? ` If ${machine} runs an older stim-server, update it.` : "";
233
+ return phaseLine("device", `Could not read the app's logs from ${machine}: ${message}. Showing the logs already copied here.${hint}`);
234
+ }
235
+ async function syncHostedMacosLogs(root, placement, slot, warnings, platform = "ios", context) {
236
+ let host;
237
+ const cancel = () => host?.connection.close();
238
+ context?.signal.addEventListener("abort", cancel, { once: true });
239
+ try {
240
+ host = await connectHost(placement.machine, void 0, false, context?.signal);
241
+ if (slot !== void 0) await pullHostedNativeLogs(root, slot, placement, host, false, platform, context?.signal);
242
+ else await pullHostedMacosLogs(root, placement, host, void 0, void 0, false, context?.signal);
243
+ return true;
244
+ } catch (error) {
245
+ context?.signal.throwIfAborted();
246
+ if (!warnings?.has(placement.machine)) {
247
+ warn(context, placement.machine, error);
248
+ warnings?.add(placement.machine);
249
+ }
250
+ return false;
251
+ } finally {
252
+ context?.signal.removeEventListener("abort", cancel);
253
+ host?.connection.close();
254
+ }
255
+ }
256
+ function followHostedMacosLogs(root, { failing = false, intervalMs = 500, retryMs = 5e3, slot, platform = "ios", context } = {}) {
257
+ let host;
258
+ const controller = new AbortController();
259
+ const signal = context ? AbortSignal.any([context.signal, controller.signal]) : controller.signal;
260
+ const cancel = () => host?.connection.close();
261
+ signal.addEventListener("abort", cancel, { once: true });
262
+ let retryAt = 0;
263
+ let stopped = false;
264
+ let running = false;
265
+ const tick = async () => {
266
+ if (running || stopped || signal.aborted || Date.now() < retryAt) return;
267
+ running = true;
268
+ try {
269
+ const placement = slot !== void 0 ? (platform === "ios" ? readHostedIos(root) : readHostedAndroid(root))[slot] : readMacosRecord(root)?.host;
270
+ if (!placement) {
271
+ host?.connection.close();
272
+ host = void 0;
273
+ return;
274
+ }
275
+ host ??= await connectHost(placement.machine, void 0, false, signal);
276
+ if (slot !== void 0) await pullHostedNativeLogs(root, slot, placement, host, false, platform, signal);
277
+ else await pullHostedMacosLogs(root, placement, host, void 0, void 0, false, signal);
278
+ failing = false;
279
+ } catch (error) {
280
+ host?.connection.close();
281
+ host = void 0;
282
+ if (signal.aborted) return;
283
+ if (!failing) warn(context, (slot !== void 0 ? (platform === "ios" ? readHostedIos(root) : readHostedAndroid(root))[slot] : readMacosRecord(root)?.host)?.machine ?? "the host", error);
284
+ failing = true;
285
+ retryAt = Date.now() + retryMs;
286
+ } finally {
287
+ running = false;
288
+ }
289
+ };
290
+ const timer = setInterval(() => void tick(), intervalMs);
291
+ return () => {
292
+ stopped = true;
293
+ controller.abort();
294
+ signal.removeEventListener("abort", cancel);
295
+ clearInterval(timer);
296
+ host?.connection.close();
297
+ };
298
+ }
299
+ async function syncHostedLogs(root, context) {
300
+ const macos = readMacosRecord(root)?.host;
301
+ const warnings = /* @__PURE__ */ new Set();
302
+ return (await Promise.all([
303
+ ...macos ? [syncHostedMacosLogs(root, macos, void 0, warnings, "ios", context)] : [],
304
+ ...Object.entries(readHostedIos(root)).map(([slot, placement]) => syncHostedMacosLogs(root, placement, slot, warnings, "ios", context)),
305
+ ...Object.entries(readHostedAndroid(root)).map(([slot, placement]) => syncHostedMacosLogs(root, placement, slot, warnings, "android", context))
306
+ ])).every(Boolean);
307
+ }
308
+ function followHostedLogs(root, failing, context) {
309
+ const stops = /* @__PURE__ */ new Map();
310
+ let closed = false;
311
+ const refresh = () => {
312
+ if (closed) return;
313
+ const active = /* @__PURE__ */ new Set();
314
+ if (readMacosRecord(root)?.host) {
315
+ active.add("macos");
316
+ if (!stops.has("macos")) stops.set("macos", followHostedMacosLogs(root, {
317
+ failing,
318
+ context
319
+ }));
320
+ }
321
+ for (const platform of ["ios", "android"]) for (const slot of Object.keys(platform === "ios" ? readHostedIos(root) : readHostedAndroid(root))) {
322
+ const key = `${platform}:${slot}`;
323
+ active.add(key);
324
+ if (!stops.has(key)) stops.set(key, followHostedMacosLogs(root, {
325
+ failing,
326
+ slot,
327
+ platform,
328
+ context
329
+ }));
330
+ }
331
+ for (const [key, stop] of stops) {
332
+ if (active.has(key)) continue;
333
+ stop();
334
+ stops.delete(key);
335
+ }
336
+ };
337
+ const stateFile = workspaceStateFile(root);
338
+ const home = resolve(configDir());
339
+ let watcher = null;
340
+ const observe = () => {
341
+ if (closed) return;
342
+ watcher?.close();
343
+ watcher = null;
344
+ let directory = dirname(stateFile);
345
+ for (;;) try {
346
+ const entry = relative(directory, stateFile).split(sep)[0];
347
+ const next = watch(directory, (_event, name) => {
348
+ if (name !== null && name.toString() !== entry) return;
349
+ if (directory !== dirname(stateFile)) observe();
350
+ refresh();
351
+ });
352
+ next.on("error", () => {
353
+ next.close();
354
+ if (watcher === next) watcher = null;
355
+ });
356
+ next.unref();
357
+ watcher = next;
358
+ return;
359
+ } catch (error) {
360
+ if (directory === home || !(error instanceof Error && "code" in error && error.code === "ENOENT")) return;
361
+ directory = dirname(directory);
362
+ }
363
+ };
364
+ observe();
365
+ refresh();
366
+ const timer = setInterval(() => {
367
+ observe();
368
+ refresh();
369
+ }, 1e4);
370
+ return () => {
371
+ closed = true;
372
+ watcher?.close();
373
+ clearInterval(timer);
374
+ for (const stop of stops.values()) stop();
375
+ };
376
+ }
377
+ //#endregion
378
+ //#region src/engine/logs.ts
379
+ async function openWorkspaceLogs(context, options = {}, follow = false) {
380
+ context.signal.throwIfAborted();
381
+ const root = context.projectRoot;
382
+ const dir = workspaceLogsDir$1(root);
383
+ if (!logFiles(dir).length) throw Object.assign(/* @__PURE__ */ new Error(`No Stim workspace has run in ${root}. Run stim start, stim ios, or stim android in the app first.`), { code: "STIM_NO_PROJECT" });
384
+ const hostedReachable = await syncHostedLogs(root, context);
385
+ context.signal.throwIfAborted();
386
+ const initial = await openLogDir(dir, { signal: context.signal });
387
+ let attempts;
388
+ try {
389
+ attempts = initial.launchAttempts();
390
+ } finally {
391
+ await initial.close();
392
+ }
393
+ await captureWorkspaceCrashes(root, dir, attempts, context.signal, context.env);
394
+ const view = await openLogDir(dir, {
395
+ order: follow ? "name" : "timeline",
396
+ signal: context.signal
397
+ });
398
+ const agentSince = view.firstTs ?? (follow ? Date.now() : void 0);
399
+ const project = loadConfig$1()?.projects?.[root];
400
+ return {
401
+ view,
402
+ readAgent: (options.sources ? options.sources.includes("agent") : !options.errorsOnly) && agentSince !== void 0 ? createAsyncAgentActionReader$1({
403
+ targets: () => workspaceAgentTargets(project, readMacosRecord(root)),
404
+ sinceTs: agentSince,
405
+ home: context.env.HOME,
406
+ env: context.env
407
+ }, context.signal) : null,
408
+ hostedReachable
409
+ };
410
+ }
411
+ async function readWorkspaceLogs(context, options = {}) {
412
+ validateLogOptions(options);
413
+ const { view, readAgent } = await openWorkspaceLogs(context, options);
414
+ try {
415
+ return await view.query({
416
+ ...options,
417
+ extra: await readAgent?.({
418
+ tail: options.tail,
419
+ matches: view.filter(options)
420
+ })
421
+ });
422
+ } finally {
423
+ await view.close();
424
+ }
425
+ }
426
+ function validateLogOptions(options) {
427
+ const invalid = (options.tail !== void 0 && (!Number.isSafeInteger(options.tail) || options.tail < 0) ? "tail must be a non-negative integer." : options.sources?.some((source) => !SOURCES.includes(source)) ? `sources must contain only ${SOURCES.join(", ")}.` : options.minLevel !== void 0 && !LEVELS.includes(options.minLevel) ? `minLevel must be one of ${LEVELS.join(", ")}.` : void 0) ?? (options.since !== void 0 ? parseSince(options.since).error : void 0) ?? (options.grep !== void 0 ? compileGrep(options.grep).error : void 0);
428
+ if (invalid) throw Object.assign(new Error(invalid), { code: "STIM_BAD_ARG" });
429
+ }
430
+ async function followWorkspaceLogs(context, options, onRecord, onBackfill) {
431
+ validateLogOptions(options);
432
+ const { view, readAgent, hostedReachable } = await openWorkspaceLogs(context, options, true);
433
+ try {
434
+ const query = {
435
+ ...options,
436
+ extra: await readAgent?.({
437
+ tail: options.tail,
438
+ matches: view.filter(options)
439
+ })
440
+ };
441
+ if (onBackfill && options.tail === void 0) for await (const batch of view.batches(query)) {
442
+ await onBackfill(batch);
443
+ context.signal.throwIfAborted();
444
+ }
445
+ else {
446
+ const records = await view.query(query);
447
+ context.signal.throwIfAborted();
448
+ if (onBackfill) await onBackfill(records);
449
+ else for (const record of records) onRecord(record);
450
+ }
451
+ } catch (error) {
452
+ await view.close();
453
+ throw error;
454
+ }
455
+ const criteria = buildCriteria(options);
456
+ const stopLog = followLogs({
457
+ dir: workspaceLogsDir$1(context.projectRoot),
458
+ offsets: view.sizes,
459
+ criteria,
460
+ onRecord,
461
+ errorContext: options.errorsOnly ? "field" : void 0
462
+ });
463
+ await view.close();
464
+ const stopAgent = readAgent ? followAgentActions(context, readAgent, (record) => {
465
+ if (recordMatches(record, criteria)) onRecord(record);
466
+ }) : null;
467
+ const stopHosted = followHostedLogs(context.projectRoot, !hostedReachable, context);
468
+ const stop = () => {
469
+ stopLog();
470
+ stopHosted();
471
+ stopAgent?.();
472
+ context.signal.removeEventListener("abort", stop);
473
+ };
474
+ context.signal.addEventListener("abort", stop, { once: true });
475
+ if (context.signal.aborted) stop();
476
+ return stop;
477
+ }
478
+ //#endregion
479
+ export { followAgentActions as a, followHostedLogs as i, openWorkspaceLogs as n, readWorkspaceLogs as r, followWorkspaceLogs as t };