stim 1.20.1 → 1.21.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 (217) hide show
  1. package/README.md +94 -11
  2. package/dist/acquire-artifact-CD4lbiWE.mjs +153 -0
  3. package/dist/act-DHAw2A2S.mjs +2667 -0
  4. package/dist/activity-BzVfHSrY.mjs +1376 -0
  5. package/dist/{agent-device-usage-output-VPaOgGaF.mjs → agent-device-usage-output-zh1vhbLp.mjs} +21 -66
  6. package/dist/{android-CZh6ElG5.mjs → android-BEJ8Jpl7.mjs} +3 -3
  7. package/dist/{android-CLbBJ2ve.mjs → android-BLgbNqox.mjs} +128 -79
  8. package/dist/{android-eXfIjKJr.mjs → android-CV_GCELZ.mjs} +5 -5
  9. package/dist/{android-DE8-JfGW.mjs → android-DUYkNF4u.mjs} +188 -106
  10. package/dist/{android-cas-BFpS84v2.mjs → android-cas-Ct5b1xCK.mjs} +7 -6
  11. package/dist/android-cas-compiler.mjs +2 -2
  12. package/dist/android-project-BCAAmMwz.mjs +12 -0
  13. package/dist/api.d.mts +740 -8
  14. package/dist/api.mjs +585 -1
  15. package/dist/{artifact-Ctb2jpw6.mjs → artifact-B8T3S5gi.mjs} +223 -201
  16. package/dist/{artifact-DXk_Fle_.mjs → artifact-DAuZ-FNU.mjs} +158 -148
  17. package/dist/{browser-web-xQWC2RWl.mjs → browser-web-QQzVjz3O.mjs} +28 -26
  18. package/dist/budget-Bs6SxxzO.mjs +9154 -0
  19. package/dist/{build-COBA1tBc.mjs → build-CoPzQRNw.mjs} +144 -101
  20. package/dist/build-cache-DmyR9Zzc.mjs +602 -0
  21. package/dist/build-plan-CaFskB7_.mjs +188 -0
  22. package/dist/{cache-manifest-qA3dT2x2.mjs → cache-manifest-DkkqguoK.mjs} +10 -5
  23. package/dist/cache-manifest.mjs +1 -1
  24. package/dist/{ccache-CtbqWxIC.mjs → ccache-BJRZ9pG3.mjs} +10 -9
  25. package/dist/{cdp-Dq_ypAlJ.mjs → cdp-CWmIUMbw.mjs} +18 -5
  26. package/dist/{chrome-Dp2lMLBe.mjs → chrome-B6tfCta1.mjs} +7 -4
  27. package/dist/{cli-sGqlPu1n.mjs → cli-0DYf8QhQ.mjs} +20 -20
  28. package/dist/cli.mjs +1 -1
  29. package/dist/client-B7QVOlCr.d.mts +253 -0
  30. package/dist/client-UXD70ZbM.mjs +1406 -0
  31. package/dist/collector-run.d.mts +4 -39
  32. package/dist/collector-run.mjs +9 -9
  33. package/dist/{command-output-CPDq_90S.mjs → command-output-B1UrjZHL.mjs} +1 -1
  34. package/dist/config-CYcBF478.mjs +949 -0
  35. package/dist/{created-devices-CXBMtoj5.mjs → created-devices-CqeBlrEn.mjs} +3 -3
  36. package/dist/{dependency-state-B2m8eqsS.mjs → dependency-state-BbKQW83h.mjs} +20 -5
  37. package/dist/{detached-entry-BXq4fIl-.mjs → detached-entry-DFRyG1_o.mjs} +1 -1
  38. package/dist/{dev-client-BqYjMIaC.mjs → dev-client-UOeESKm6.mjs} +2 -2
  39. package/dist/device-DCxH7_By.mjs +1068 -0
  40. package/dist/{device-D4DqjSZZ.mjs → device-ExJq8Ei7.mjs} +35 -36
  41. package/dist/{device-capacity-DrwHwR97.mjs → device-capacity-CMlqEcvw.mjs} +43 -14
  42. package/dist/device-host-worker.mjs +65 -62
  43. package/dist/{device-ios-DE8KJd3b.mjs → device-ios-DRUeKaFV.mjs} +49 -49
  44. package/dist/{device-lease-run-Baelt3nc.mjs → device-lease-run-C8raGFoP.mjs} +14 -26
  45. package/dist/{device-pool-DtK9S6AD.mjs → device-pool-DMRpVX9a.mjs} +5 -5
  46. package/dist/doctor-BLHCYxzi.mjs +2 -0
  47. package/dist/{doctor-Dunu3Nv1.mjs → doctor-DTvaDOda.mjs} +317 -344
  48. package/dist/{doctor-DiP9HsIP.mjs → doctor-Dhqebm0q.mjs} +183 -91
  49. package/dist/doctor-fingerprint.mjs +19 -0
  50. package/dist/{doctor-watchman-XJzT8tK-.mjs → doctor-watchman-Cv1F10Kj.mjs} +40 -23
  51. package/dist/{eas-build-0gadvrca.mjs → eas-build-BomfRnFT.mjs} +53 -20
  52. package/dist/{build-plan-CRjAA6Qi.mjs → eas-fallback-DJwZpy0c.mjs} +26 -208
  53. package/dist/{watchman-CqmaGcIb.mjs → eas-session-ledger-op6A54yi.mjs} +229 -11
  54. package/dist/{error-diagnostics-BhQtoLrZ.mjs → error-diagnostics-Bf0rZvG9.mjs} +172 -82
  55. package/dist/exec-H20xSg2T.d.mts +65 -0
  56. package/dist/exec-_UbtCQcG.mjs +750 -0
  57. package/dist/gc-C-WwL0yi.mjs +3 -0
  58. package/dist/{gc-D5cz5G0k.mjs → gc-_-dCXdyL.mjs} +625 -786
  59. package/dist/git-C3iTsJaZ.mjs +73 -0
  60. package/dist/{guide-DakjcoUt.mjs → guide-Yqwt2bd6.mjs} +990 -280
  61. package/dist/{hosted-android-C-D8Dj0_.mjs → hosted-android-Bw-honsd.mjs} +8 -6
  62. package/dist/{hosted-client--hNFgixu.mjs → hosted-client-DB_gBPfY.mjs} +47 -24
  63. package/dist/{hosted-ios-Chx9XQyI.mjs → hosted-ios-CUvOf4Vr.mjs} +1 -1
  64. package/dist/{hosted-logs-Bkz0Hxzh.mjs → hosted-logs-DL_P5AdN.mjs} +77 -43
  65. package/dist/{hosted-macos-ckTjN-0V.mjs → hosted-macos-QI141yKk.mjs} +21 -15
  66. package/dist/{hosted-native-3KXZ5-qn.mjs → hosted-native-Ksyjgzq-.mjs} +31 -20
  67. package/dist/idle-BVeRGroT.d.mts +24 -0
  68. package/dist/{idle-shutdown-DhAUyf5s.mjs → idle-shutdown-DaKmZi0z.mjs} +11 -10
  69. package/dist/{ios-BDBN-xpf.mjs → ios-CQ68hG9s.mjs} +8 -8
  70. package/dist/{ios-o896T9PE.mjs → ios-CpByZy12.mjs} +141 -81
  71. package/dist/{ios-device-B1B14xND.mjs → ios-device-CXGP1bsD.mjs} +1 -1
  72. package/dist/{ios-device-BWHKGaJq.mjs → ios-device-CwFMehUS.mjs} +60 -35
  73. package/dist/{ios-project-BeOXKPt2.mjs → ios-project-WuwwBdvW.mjs} +13 -13
  74. package/dist/{ios-VGvNdsv2.mjs → ios-qNJt4dFm.mjs} +1 -1
  75. package/dist/ios-signing-DTTIChGs.mjs +489 -0
  76. package/dist/{ios-state-BsXMwo5y.mjs → ios-state-DvFX-K_l.mjs} +1 -1
  77. package/dist/{ios-CQ8bHQXB.mjs → ios-ubFsBzwq.mjs} +129 -86
  78. package/dist/{js-swap-Z_mSuRrx.mjs → js-swap-Cc1dttps.mjs} +60 -33
  79. package/dist/{launch-V1zqiOYn.mjs → launch-CD1yVc7U.mjs} +92 -91
  80. package/dist/{launch-BootbMk4.mjs → launch-Zq2mOSDy.mjs} +87 -545
  81. package/dist/logs-BS00Anxf.mjs +352 -0
  82. package/dist/logs-CMm05HxN.mjs +255 -0
  83. package/dist/macos-B65--pPd.mjs +2 -0
  84. package/dist/{macos-D7irBW3A.mjs → macos-C-0qJ6zq.mjs} +244 -215
  85. package/dist/macos-run.mjs +1 -1
  86. package/dist/maintenance-run.mjs +122 -247
  87. package/dist/{metro-_ZIE3Axg.mjs → metro-DEXpIhHC.mjs} +71 -17
  88. package/dist/{metro-gateway-BzlQZQmU.mjs → metro-gateway-BMJNlj3E.mjs} +20 -12
  89. package/dist/{named-ports-O1TIl7tx.mjs → named-ports-BWTzt6mu.mjs} +8 -64
  90. package/dist/native-android-JACyjTZs.mjs +844 -0
  91. package/dist/{native-gradle-inputs-BQnIdAlL.mjs → native-gradle-inputs-Bep9JcSF.mjs} +128 -147
  92. package/dist/native-inputs-TRTTTRxt.mjs +91 -0
  93. package/dist/native-run-DY_RLx3C.mjs +277 -0
  94. package/dist/{native-runtime-D024BAvm.mjs → native-runtime-Dg1Q7tfF.mjs} +10 -10
  95. package/dist/{native-xcode-inputs-UElfGs59.mjs → native-xcode-inputs-CB2iQeWq.mjs} +28 -20
  96. package/dist/{native-xcode-ios-CjS-nDVY.mjs → native-xcode-ios-CXX39F7o.mjs} +96 -47
  97. package/dist/{ndjson-GOnbyvso.mjs → ndjson-CgE_o3Dl.mjs} +3 -3
  98. package/dist/offload-worker.d.mts +1 -46
  99. package/dist/offload-worker.mjs +213 -86
  100. package/dist/{ownership-BrjepDiv.mjs → ownership-DEmM5vhh.mjs} +3 -3
  101. package/dist/{page-Bv9s2KwY.mjs → page-CPaHeYqj.mjs} +7 -4
  102. package/dist/paths-BsJMoPP2.mjs +12 -0
  103. package/dist/paths-DQtTgsBf.mjs +42 -0
  104. package/dist/{placement-log-BItXET1x.mjs → placement-log-BqGbTa61.mjs} +5 -5
  105. package/dist/{plan-placement-B466UYMU.mjs → plan-placement-Bwj-IjY1.mjs} +6 -6
  106. package/dist/{ports-BFRL6JTj.mjs → ports-D-MmCTdv.mjs} +3 -3
  107. package/dist/prebuild-uD_ipCxF.mjs +449 -0
  108. package/dist/{project-DX8fXyw_.mjs → project-BZNjmW_8.mjs} +65 -38
  109. package/dist/{pull-request-vOhLNmIb.mjs → pull-request-Lfetn8Kr.mjs} +5 -18
  110. package/dist/pull-request-zjCSAryH.d.mts +120 -0
  111. package/dist/pull-requests.d.mts +1 -119
  112. package/dist/pull-requests.mjs +1 -1
  113. package/dist/{react-native-android-CuXM3QS8.mjs → react-native-android-DuzH0cn3.mjs} +83 -53
  114. package/dist/{gradle-CZZo1TSA.mjs → react-native-build-rhk4smwQ.mjs} +292 -15
  115. package/dist/react-native-doctor-CQpuIMso.mjs +234 -0
  116. package/dist/{react-native-ios-DtVO4qf2.mjs → react-native-ios-Bhq1rJeV.mjs} +46 -28
  117. package/dist/{recordings-Bk-VivUV.mjs → recordings-DYteQSu4.mjs} +12 -9
  118. package/dist/{reload-D9V7D8gP.mjs → reload-CmTRFJaX.mjs} +95 -49
  119. package/dist/reload-DzjSl5P_.mjs +2 -0
  120. package/dist/{remote-CZiTijxG.mjs → remote-ByYkXdGD.mjs} +15 -10
  121. package/dist/result-DNiS-tTP.mjs +434 -0
  122. package/dist/{run-ClC8UVB5.mjs → run-D23HmJMs.mjs} +4 -5
  123. package/dist/selection-CSl9i5qU.mjs +619 -0
  124. package/dist/{server-bare-dWjAarki.mjs → server-bare-CxTrvDg8.mjs} +3 -4
  125. package/dist/{server-command-DnJYLnr4.mjs → server-command-CtzloH3v.mjs} +14 -7
  126. package/dist/server-expo-C-90EhcG.mjs +2 -0
  127. package/dist/{server-expo-CUuzP9Mp.mjs → server-expo-DT_F_uVI.mjs} +51 -15
  128. package/dist/{settings-Bbztm4oV.mjs → settings-CsJDEXgK.mjs} +301 -132
  129. package/dist/{settings-vk3mJGSm.d.mts → settings-DkdmlelE.d.mts} +6 -4
  130. package/dist/settings-T1gtc3bf.mjs +114 -0
  131. package/dist/settings-write-HyVZ8eQ8.mjs +359 -0
  132. package/dist/settings.schema.json +163 -16
  133. package/dist/{simslim-ChMfe8rg.mjs → simslim-Cgk17SXV.mjs} +14 -13
  134. package/dist/{slot-launch-CeCRr6MK.mjs → slot-launch-DF8VfT64.mjs} +15 -20
  135. package/dist/{spawn-entry-Dcb7sDUz.mjs → spawn-entry-jw19m8Nl.mjs} +0 -1
  136. package/dist/stage-BIS0ydsV.mjs +183 -0
  137. package/dist/{start-CRkG-mZ7.mjs → start-7lpH7hmN.mjs} +66 -48
  138. package/dist/{start-mh6bS27z.mjs → start-RChynRDp.mjs} +1 -1
  139. package/dist/{state-lqxdOH_g.mjs → state-C4ZtUisW.mjs} +41 -14
  140. package/dist/{state-BUpAmt2r.mjs → state-XMziexv2.mjs} +3 -2
  141. package/dist/{stats-CaB1MxMi.mjs → stats-53T7OTb9.mjs} +7 -13
  142. package/dist/stats-report-BFfMpWWF.mjs +16 -0
  143. package/dist/{status-C7vzkInu.mjs → status-BL7jVyAB.mjs} +538 -467
  144. package/dist/status-CSi6tlRq.mjs +2 -0
  145. package/dist/{status-BDGHwkCs.mjs → status-DqEUSSxs.mjs} +6 -4
  146. package/dist/{status-watch-ZaVqRdtW.mjs → status-watch-GDCfqpTE.mjs} +187 -22
  147. package/dist/status-worker.d.mts +1 -0
  148. package/dist/status-worker.mjs +19 -0
  149. package/dist/stim-desktop-C12we7lz.mjs +112 -0
  150. package/dist/{stop-BU7JaFCg.mjs → stop-Bk_1qiV6.mjs} +2 -2
  151. package/dist/{stop-BO80KJoT.mjs → stop-CPzlM1L-.mjs} +138 -99
  152. package/dist/{stop-Cftw_sXJ.mjs → stop-D7h6jAXQ.mjs} +11 -10
  153. package/dist/supervisor-run.d.mts +8 -17
  154. package/dist/supervisor-run.mjs +63 -28
  155. package/dist/{support-Ca6PZbpr.mjs → support-67vraa1Q.mjs} +18 -11
  156. package/dist/{support-Co0wk8Cv.mjs → support-Dlu37g6H.mjs} +12 -12
  157. package/dist/{swiftpm-macos-siFSkmCO.mjs → swiftpm-macos-p8WZbxKU.mjs} +35 -24
  158. package/dist/toolchain-DhKwp9iI.mjs +2 -0
  159. package/dist/toolchain-Hp9sCpK4.mjs +873 -0
  160. package/dist/{trigger-C0MWBi8O.mjs → trigger-BAahxUPq.mjs} +20 -5
  161. package/dist/trigger-Bf3uDcpv.mjs +2 -0
  162. package/dist/{warm-progress-5FAXkXIg.mjs → warm-progress-BHX5r0Ei.mjs} +252 -176
  163. package/dist/{web-BTjzE8mc.mjs → web-CJmIj6AI.mjs} +18 -13
  164. package/dist/web-DknQETPs.mjs +2 -0
  165. package/dist/web-run.mjs +16 -17
  166. package/dist/windows-report.d.mts +1 -0
  167. package/dist/windows-report.mjs +18 -0
  168. package/dist/windows-report.ps1 +43 -0
  169. package/dist/workspace-process-lock-1_1OoVW5.mjs +57 -0
  170. package/dist/{workspace-state-CvgTFe-h.mjs → workspace-state-Cjuigeeu.mjs} +70 -56
  171. package/dist/{workspaces-C4kqIOlx.mjs → workspaces-BccMFmGQ.mjs} +1188 -1080
  172. package/dist/worktree-CK2MpJW5.mjs +2 -0
  173. package/dist/{worktree-DtRsh6go.mjs → worktree-DQ6Zi2Mv.mjs} +368 -110
  174. package/dist/xcode-Zlx3qjEs.mjs +896 -0
  175. package/package.json +7 -5
  176. package/shim/android-optimizations.gradle +7 -5
  177. package/dist/activity-BaMpUQ4-.mjs +0 -629
  178. package/dist/api-run.mjs +0 -296
  179. package/dist/api-zuX3ynYN.mjs +0 -154
  180. package/dist/app-install-Cg9YJy3x.mjs +0 -873
  181. package/dist/artifact-lifecycle-DzPpBYvK.mjs +0 -30
  182. package/dist/budget-RFbwFpG5.mjs +0 -4109
  183. package/dist/build-facts-DcLv2HSd.d.mts +0 -111
  184. package/dist/client-zqjFd79D.mjs +0 -1779
  185. package/dist/config-D0LhTY3S.mjs +0 -524
  186. package/dist/device-BgNj-qVj.mjs +0 -290
  187. package/dist/device-lease-C309csaB.mjs +0 -1228
  188. package/dist/device-remote-DjsNw8DD.mjs +0 -1272
  189. package/dist/eas-session-ledger-DJDeL4Uq.mjs +0 -205
  190. package/dist/exec-B81Qodjn.mjs +0 -254
  191. package/dist/launch-verify-Dl78EVgR.mjs +0 -428
  192. package/dist/logs-Bh4eqCCc.mjs +0 -384
  193. package/dist/macos-kivF8qKz.mjs +0 -2
  194. package/dist/miss-reason-SuTptY-I.mjs +0 -238
  195. package/dist/native-android-D94RlJ-X.mjs +0 -226
  196. package/dist/ndjson-Du3j0AQ9.d.mts +0 -17
  197. package/dist/plan-Jwu_vr-F.mjs +0 -260
  198. package/dist/prebuild-DB_zLOLc.mjs +0 -213
  199. package/dist/preview-BRLFRhTz.mjs +0 -1004
  200. package/dist/process-identity-Biv3arCO.mjs +0 -40
  201. package/dist/react-native-build-JUF31S8U.mjs +0 -239
  202. package/dist/react-native-doctor-BQHqiXaQ.mjs +0 -78
  203. package/dist/remote-cache-fxcl5C-L.mjs +0 -526
  204. package/dist/result-BrfgXtdO.mjs +0 -186
  205. package/dist/server-expo-Dvkd7JcF.mjs +0 -2
  206. package/dist/settings-BuKMOANA.mjs +0 -402
  207. package/dist/spawn-claims-Kqiifsk2.mjs +0 -72
  208. package/dist/stage-BNKKdDNc.mjs +0 -157
  209. package/dist/stim-desktop-8GQX2OV8.mjs +0 -63
  210. package/dist/tailnet-D7-tE_ug.mjs +0 -265
  211. package/dist/toolchain-B12psPA2.mjs +0 -2
  212. package/dist/toolchain-SqehyPLw.mjs +0 -1657
  213. package/dist/trigger-SHLOWJ4O.mjs +0 -2
  214. package/dist/web-CHN5gh34.mjs +0 -2
  215. package/dist/worktree-Cgnm6vZt.mjs +0 -2
  216. package/dist/{api-run.d.mts → doctor-fingerprint.d.mts} +0 -0
  217. package/dist/{errors-DzkMYh8Q.mjs → errors-ccaPc4ox.mjs} +2 -2
@@ -1,22 +1,20 @@
1
- import { n as ownership_claim_exports, t as process_identity_exports } from "./process-identity-Biv3arCO.mjs";
2
- import { n as debugLog } from "./exec-B81Qodjn.mjs";
3
- import { B as parseDeviceSlotKey, D as withConfigLock$1, E as upsertProject, H as projectDeviceSlots, V as parseDeviceSlotOption, W as validateDeviceSlot, o as clearSupervisor, p as getProject, z as deviceSlotPlatforms } from "./config-D0LhTY3S.mjs";
4
- import { n as fileLeaseIo, u as releaseWorkspaceLeases } from "./device-lease-C309csaB.mjs";
5
- import { a as updateWorkspaceState, c as writeWorkspaceState, n as clearWorkspaceStateKeys, o as withWorkspaceStateLock, r as readWorkspaceState$1, x as workspaceDir } from "./workspace-state-CvgTFe-h.mjs";
6
- import { f as refuseNoProject, l as phaseLine, p as releasedLeaseFact, u as plural } from "./command-output-CPDq_90S.mjs";
7
- import { A as clearWorkspaceSupervisor, D as clearManagedMetroTunnel, N as readRemoteSession, O as clearRemoteSession, j as readMetroTunnel, k as clearWorkspaceLaunches, n as findCommandWorkspace, w as MODE_COMMAND } from "./project-DX8fXyw_.mjs";
8
- import { d as signalProcessTree, r as killMetroTree, s as pidExists, u as resolveProjectMetro } from "./metro-_ZIE3Axg.mjs";
9
- import { D as stopTunnel, P as resolveSupervisorTarget, b as teardownOwnedIosSim, v as teardownOwnedAvd, y as teardownOwnedBrowser } from "./workspaces-C4kqIOlx.mjs";
10
- import { _t as withdrawDevServerStopRequest, ht as requestDevServerStop, pt as logVanishedSupervisor } from "./budget-RFbwFpG5.mjs";
11
- import { a as withWorkspaceProcessLock } from "./named-ports-O1TIl7tx.mjs";
12
- import { _ as nativeRunHolder, d as NATIVE_RUN_LOCK, f as NATIVE_RUN_WAIT_MS, g as describeNativeRunHolder, h as decideStopAction, m as clearNativeRunCancel, v as nativeRunWaitNotice, y as requestNativeRunCancel } from "./tailnet-D7-tE_ug.mjs";
13
- import { f as resolveEasCliBin } from "./remote-cache-fxcl5C-L.mjs";
14
- import { t as macosAppPresent } from "./state-BUpAmt2r.mjs";
15
- import { i as stopHostedAndroid } from "./hosted-android-C-D8Dj0_.mjs";
16
- import { i as endRecordedSession } from "./device-remote-DjsNw8DD.mjs";
17
- import { n as verifyCollectorOwnership } from "./ownership-BrjepDiv.mjs";
18
- import { r as stopHostedIos } from "./hosted-ios-Chx9XQyI.mjs";
19
- import { n as stopMacosApp } from "./stop-Cftw_sXJ.mjs";
1
+ import { _ as debugLog, f as ownership_claim_exports, p as process_identity_exports } from "./exec-_UbtCQcG.mjs";
2
+ import { d as workspaceDir } from "./paths-DQtTgsBf.mjs";
3
+ import { E as upsertProject, G as parseDeviceSlotOption, J as validateDeviceSlot, K as projectDeviceSlots, O as withConfigLockAsync$1, U as deviceSlotPlatforms, W as parseDeviceSlotKey, o as clearSupervisor, p as getProject } from "./config-CYcBF478.mjs";
4
+ import { f as refuseNoProject, l as phaseLine, p as releasedLeaseFact, u as plural } from "./command-output-B1UrjZHL.mjs";
5
+ import { c as withWorkspaceStateLock, d as writeWorkspaceState, l as withWorkspaceStateLockAsync, n as clearWorkspaceStateKeys, r as readWorkspaceState$1, s as updateWorkspaceStateAsync } from "./workspace-state-Cjuigeeu.mjs";
6
+ import { A as clearWorkspaceLaunches, M as readMetroTunnel, O as clearManagedMetroTunnel, P as readRemoteSession, T as MODE_COMMAND, j as clearWorkspaceSupervisor, k as clearRemoteSession, n as findCommandWorkspace } from "./project-BZNjmW_8.mjs";
7
+ import { t as macosAppPresent } from "./state-XMziexv2.mjs";
8
+ import { d as processCwds, f as resolveProjectMetro, g as isMetroRunning, i as killMetroTreeAsync, l as pidExists, m as signalProcessTreeAsync, o as listeningPidsAsync } from "./metro-DEXpIhHC.mjs";
9
+ import { S as withdrawDevServerStopRequest, b as requestDevServerStop, qn as resolveEasCliBin, v as logVanishedSupervisor, zt as endRecordedSession } from "./budget-Bs6SxxzO.mjs";
10
+ import { a as decideStopAction, c as nativeRunWaitNotice, i as clearNativeRunCancel, l as requestNativeRunCancel, n as NATIVE_RUN_WAIT_MS, o as describeNativeRunHolder, s as nativeRunHolder, t as NATIVE_RUN_LOCK } from "./native-run-DY_RLx3C.mjs";
11
+ import { D as teardownOwnedBrowser, E as teardownOwnedAvd, O as teardownOwnedIosSim, g as stopTunnel, m as resolveSupervisorTarget } from "./workspaces-BccMFmGQ.mjs";
12
+ import { O as releaseWorkspaceLeasesAsync, y as fileLeaseIo } from "./activity-BzVfHSrY.mjs";
13
+ import { t as withWorkspaceProcessLock } from "./workspace-process-lock-1_1OoVW5.mjs";
14
+ import { i as stopHostedAndroid } from "./hosted-android-Bw-honsd.mjs";
15
+ import { r as stopHostedIos } from "./hosted-ios-CUvOf4Vr.mjs";
16
+ import { n as stopMacosApp } from "./stop-D7h6jAXQ.mjs";
17
+ import { n as verifyCollectorOwnership } from "./ownership-DEmM5vhh.mjs";
20
18
  import { hostedAndroidDeviceName, hostedAndroidRecords, hostedIosRecords, hostedNativeRecords, isJsonObject, parseHostedNativePlacement } from "@stim-cli/core/state";
21
19
  import chalk from "chalk";
22
20
  //#region src/commands/stop.ts
@@ -104,20 +102,21 @@ function resolveCollectorTargets({ root, collectors, isAlive = pidExists, selfPi
104
102
  }
105
103
  return targets;
106
104
  }
107
- function defaultTeardownRemoteSession(root, sessionId) {
105
+ async function defaultTeardownRemoteSession(root, sessionId, operation) {
108
106
  return endRecordedSession({
109
107
  root,
110
108
  sessionId,
111
- easBin: resolveEasCliBin(root)?.file ?? null
109
+ easBin: resolveEasCliBin(root)?.file ?? null,
110
+ operation
112
111
  });
113
112
  }
114
- function endRemoteSession(root, sessionId, { teardownRemoteSession, report }) {
115
- const result = teardownRemoteSession(root, sessionId);
113
+ async function endRemoteSession(root, sessionId, { teardownRemoteSession, report }) {
114
+ const result = await teardownRemoteSession(root, sessionId);
116
115
  if (result.status === "failed") report(chalk.red(phaseLine("device", result.reason ?? `could not stop remote session ${sessionId}`)));
117
116
  else {
118
117
  report(chalk.dim(phaseLine("device", `stopped remote session ${sessionId}`)));
119
118
  if (result.reason) report(chalk.yellow(phaseLine("device", result.reason)));
120
- else clearRemoteSession(root, sessionId);
119
+ else await withWorkspaceStateLockAsync(root, () => clearRemoteSession(root, sessionId));
121
120
  }
122
121
  return {
123
122
  status: result.status,
@@ -149,19 +148,19 @@ async function runStop(options) {
149
148
  collectors,
150
149
  remoteDevice: null,
151
150
  metroTunnel: null,
152
- clearCollectors: (projectRoot, expected) => withWorkspaceStateLock(projectRoot, () => {
151
+ clearCollectors: (projectRoot, expected) => withWorkspaceStateLockAsync(projectRoot, () => {
153
152
  clearCollectorState(projectRoot, expected);
154
153
  return !Object.keys(readCollectorState(projectRoot)).some((key) => parseDeviceSlotKey(key)?.slot === slot);
155
154
  }),
156
- clearState: (projectRoot) => {
155
+ clearState: (projectRoot) => withWorkspaceStateLockAsync(projectRoot, () => {
157
156
  clearWorkspaceLaunches(projectRoot, slot);
158
157
  return true;
159
- },
158
+ }),
160
159
  clearRegistration: async () => true,
161
160
  teardownBrowser: null,
162
161
  stopMacos: false,
163
162
  hostedSlot: slot,
164
- releaseLeases: (projectRoot) => releaseWorkspaceLeases(projectRoot, { slot })
163
+ releaseLeases: (projectRoot) => releaseWorkspaceLeasesAsync(projectRoot, { slot })
165
164
  });
166
165
  result.outcomes.port = {
167
166
  status: "kept",
@@ -263,7 +262,11 @@ async function stopWorkspaceMacos(root, failed, enabled) {
263
262
  };
264
263
  }
265
264
  }
266
- async function stopWorkspace({ root, project = void 0, state = void 0, collectors = void 0, signalCollector = (pid) => signalProcessTree(pid), verifyCollector = verifyCollectorOwnership, clearCollectors = clearCollectorState, isAlive = pidExists, killGroup = killMetroTree, signalServer = (pid, group) => signalProcessTree(pid, "SIGTERM", { group }), inspectIdentity = process_identity_exports.inspectProcessIdentity, waitForDeath = void 0, waitMs = DEFAULT_WAIT_MS, resolveMetro = resolveProjectMetro, teardownIos = teardownOwnedIosSim, teardownAvd = teardownOwnedAvd, teardownBrowser = (projectRoot) => teardownOwnedBrowser(projectRoot), stopMacos, hostedSlot, remoteDevice = void 0, teardownRemoteSession = defaultTeardownRemoteSession, metroTunnel = void 0, stopMetroTunnel = stopTunnel, releaseLeases = releaseWorkspaceLeases, freePort = defaultFreePort, clearRegistration = defaultClearRegistration, clearState = clearSupervisorState, report = (line) => console.error(line) }) {
265
+ async function stopWorkspace({ root, operation, project = void 0, state = void 0, collectors = void 0, signalCollector = (pid) => signalProcessTreeAsync(pid), verifyCollector = verifyCollectorOwnership, clearCollectors = (projectRoot, expected) => withWorkspaceStateLockAsync(projectRoot, () => clearCollectorState(projectRoot, expected)), isAlive = pidExists, killGroup = killMetroTreeAsync, signalServer = (pid, group) => signalProcessTreeAsync(pid, "SIGTERM", { group }), inspectIdentity = process_identity_exports.inspectProcessIdentity, waitForDeath = void 0, waitMs = DEFAULT_WAIT_MS, resolveMetro = (port, projectRoot) => resolveProjectMetro(port, projectRoot, {
266
+ probe: (candidatePort) => isMetroRunning(candidatePort, operation?.signal),
267
+ pidsOf: listeningPidsAsync,
268
+ cwdOf: async (pid) => (await processCwds([pid])).get(pid) ?? null
269
+ }), teardownIos = teardownOwnedIosSim, teardownAvd = teardownOwnedAvd, teardownBrowser = (projectRoot) => teardownOwnedBrowser(projectRoot), stopMacos, hostedSlot, remoteDevice = void 0, teardownRemoteSession = (projectRoot, id) => defaultTeardownRemoteSession(projectRoot, id, operation), metroTunnel = void 0, stopMetroTunnel = stopTunnel, releaseLeases = releaseWorkspaceLeasesAsync, freePort = defaultFreePort, clearRegistration = (projectRoot, expected) => defaultClearRegistration(projectRoot, expected, report), clearState = (projectRoot, expected) => withWorkspaceStateLockAsync(projectRoot, () => clearSupervisorState(projectRoot, expected)), report = (line) => console.error(line) }) {
267
270
  const proj = project === void 0 ? getProject(root) : project;
268
271
  const sup = state === void 0 ? readSupervisorState(root) : state;
269
272
  const collectorRecords = collectors === void 0 ? readCollectorState(root) : collectors;
@@ -353,7 +356,7 @@ async function stopWorkspace({ root, project = void 0, state = void 0, collector
353
356
  stillHolding ??= "a collector could not be stopped";
354
357
  } else if (outcomes.collectors.entries.length) {
355
358
  debugLog.log("stop.phase.start", { phase: "clear-collectors" });
356
- const cleared = clearCollectors(root, collectorRecords);
359
+ const cleared = await clearCollectors(root, collectorRecords);
357
360
  debugLog.log("stop.phase.end", {
358
361
  phase: "clear-collectors",
359
362
  cleared
@@ -390,8 +393,17 @@ async function stopWorkspace({ root, project = void 0, state = void 0, collector
390
393
  }
391
394
  }
392
395
  const releaseStoppedSupervisor = async () => {
393
- const stateCleared = clearState(root, sup);
396
+ const stateCleared = await clearState(root, sup);
394
397
  const registrationCleared = await clearRegistration(root, proj?.supervisor ?? null);
398
+ if (typeof registrationCleared === "object") {
399
+ ok = false;
400
+ outcomes.port = {
401
+ status: "kept",
402
+ port: reservedPort,
403
+ reason: registrationCleared.error
404
+ };
405
+ return;
406
+ }
395
407
  if (stateCleared === false || registrationCleared === false) {
396
408
  ok = false;
397
409
  outcomes.port = {
@@ -411,7 +423,7 @@ async function stopWorkspace({ root, project = void 0, state = void 0, collector
411
423
  report(chalk.dim(phaseLine("port", `keeping reservation ${reservedPort} -- ${keepPort}`)));
412
424
  return;
413
425
  }
414
- if (freePort(root, reservedPort) === false) {
426
+ if (await freePort(root, reservedPort) === false) {
415
427
  ok = false;
416
428
  outcomes.port = {
417
429
  status: "kept",
@@ -429,7 +441,7 @@ async function stopWorkspace({ root, project = void 0, state = void 0, collector
429
441
  };
430
442
  if (stillHolding) report(chalk.dim(phaseLine("device", "left alone (something is still running)")));
431
443
  else {
432
- outcomes.device = shutDownDevices(proj, root, {
444
+ outcomes.device = await shutDownDevices(proj, root, {
433
445
  teardownIos,
434
446
  teardownAvd,
435
447
  report
@@ -446,7 +458,7 @@ async function stopWorkspace({ root, project = void 0, state = void 0, collector
446
458
  ok = false;
447
459
  });
448
460
  Object.assign(outcomes.device, hosted.devices);
449
- updateWorkspaceState(root, (workspace) => {
461
+ await updateWorkspaceStateAsync(root, (workspace) => {
450
462
  const slots = isJsonObject(workspace.deviceSlots) ? workspace.deviceSlots : {};
451
463
  for (const name of ["default", ...Object.keys(slots)]) {
452
464
  if (hostedSlot !== void 0 && name !== hostedSlot) continue;
@@ -464,7 +476,7 @@ async function stopWorkspace({ root, project = void 0, state = void 0, collector
464
476
  const remote = remoteDevice === void 0 ? readRemoteSession(root) : remoteDevice;
465
477
  const sessionId = typeof remote?.sessionId === "string" ? remote.sessionId : null;
466
478
  if (sessionId) {
467
- outcomes.device.remote = endRemoteSession(root, sessionId, {
479
+ outcomes.device.remote = await endRemoteSession(root, sessionId, {
468
480
  teardownRemoteSession,
469
481
  report
470
482
  });
@@ -484,7 +496,7 @@ async function stopWorkspace({ root, project = void 0, state = void 0, collector
484
496
  tunnelHolding = result.reason ?? `could not stop the ${tunnel.provider} tunnel`;
485
497
  if (!stillHolding) stillHolding = tunnelHolding;
486
498
  report(chalk.red(phaseLine("lan", tunnelHolding)));
487
- } else if (!clearManagedMetroTunnel(root, tunnel)) {
499
+ } else if (!await withWorkspaceStateLockAsync(root, () => clearManagedMetroTunnel(root, tunnel))) {
488
500
  tunnelHolding = "a replacement managed tunnel record appeared during cleanup and remains active";
489
501
  stillHolding = stillHolding ?? tunnelHolding;
490
502
  ok = false;
@@ -496,7 +508,7 @@ async function stopWorkspace({ root, project = void 0, state = void 0, collector
496
508
  report(chalk.red(phaseLine("lan", tunnelHolding)));
497
509
  } else report(chalk.dim(phaseLine("lan", result.status === "missing" ? "tunnel already gone" : `stopped the ${tunnel.provider} tunnel`)));
498
510
  } else if (tunnel?.kind === "expo") outcomes.metroTunnel = { status: "not-managed" };
499
- outcomes.releasedLeases = releaseLeases(root);
511
+ outcomes.releasedLeases = await releaseLeases(root);
500
512
  for (const lease of outcomes.releasedLeases) report(chalk.dim(phaseLine("lease", releasedLeaseFact(lease))));
501
513
  if (stillHolding) {
502
514
  outcomes.port = {
@@ -511,7 +523,7 @@ async function stopWorkspace({ root, project = void 0, state = void 0, collector
511
523
  "stopped"
512
524
  ].includes(outcomes.supervisor.status) && !["refused", "failed"].includes(outcomes.metro.status);
513
525
  if (tunnelHolding && serverIsDown) {
514
- clearState(root, sup);
526
+ await clearState(root, sup);
515
527
  await clearRegistration(root, proj?.supervisor ?? null);
516
528
  }
517
529
  } else await releaseStoppedSupervisor();
@@ -575,7 +587,7 @@ async function reapCollectors(root, collectors, { isAlive, signal, report, verif
575
587
  });
576
588
  continue;
577
589
  }
578
- signal(target.pid);
590
+ await signal(target.pid);
579
591
  if (!await waiter(target.pid, collectors?.[target.platform]?.processToken)) {
580
592
  entries.push({
581
593
  platform: target.platform,
@@ -615,16 +627,20 @@ async function reapCollectors(root, collectors, { isAlive, signal, report, verif
615
627
  }
616
628
  async function stopSupervisor(target, { root, killGroup, waiter, report }) {
617
629
  report(chalk.dim(phaseLine("stop", `sending SIGTERM to supervisor process group ${target.pid}`)));
618
- requestDevServerStop(root, target.processToken, { by: "stim stop" });
630
+ try {
631
+ await withWorkspaceStateLockAsync(root, () => requestDevServerStop(root, target.processToken, { by: "stim stop" }));
632
+ } catch {}
619
633
  let signalled = false;
620
634
  try {
621
- signalled = killGroup(target.pid, target.processToken);
635
+ signalled = await killGroup(target.pid, target.processToken);
622
636
  } catch (e) {
623
637
  signalled = false;
624
638
  report(chalk.red(phaseLine("stop", `could not signal supervisor pid ${target.pid}: ${String(e?.message || e)}`)));
625
639
  }
626
640
  if (!signalled) {
627
- withdrawDevServerStopRequest(root, target.processToken);
641
+ try {
642
+ await withWorkspaceStateLockAsync(root, () => withdrawDevServerStopRequest(root, target.processToken));
643
+ } catch {}
628
644
  const reason = `could not signal supervisor pid ${target.pid}`;
629
645
  report(chalk.red(phaseLine("stop", reason)));
630
646
  return {
@@ -679,7 +695,7 @@ async function stopMetro(port, root, { server, supervisorGone, signalServer, ins
679
695
  report(chalk.dim(phaseLine("metro", `sending SIGTERM to dev server pid ${serverPid} left by the supervisor`)));
680
696
  let signalled = false;
681
697
  try {
682
- signalled = signalServer(serverPid, server?.mode === MODE_COMMAND);
698
+ signalled = await signalServer(serverPid, server?.mode === MODE_COMMAND);
683
699
  } catch {}
684
700
  if (signalled ? await waiter(serverPid, serverProcessToken) : ["gone", "different"].includes(inspectIdentity(serverRecord))) {
685
701
  report(chalk.green(phaseLine("metro", `dev server pid ${serverPid}`)));
@@ -731,7 +747,7 @@ function occupiedSkipReason(reason, holders) {
731
747
  const named = (holders || []).filter(Boolean);
732
748
  return named.length ? `${reason} -- held by UI-test runner ${named.join(", ")}` : `${reason} -- ${OCCUPANCY_HINT}`;
733
749
  }
734
- function shutDownDevices(project, workspace, { teardownIos, teardownAvd, report }) {
750
+ async function shutDownDevices(project, workspace, { teardownIos, teardownAvd, report }) {
735
751
  const device = {
736
752
  ios: null,
737
753
  android: null
@@ -757,7 +773,7 @@ function shutDownDevices(project, workspace, { teardownIos, teardownAvd, report
757
773
  slot,
758
774
  deviceId: iosUdid
759
775
  });
760
- const result = teardownIos(iosUdid, {
776
+ const result = await teardownIos(iosUdid, {
761
777
  del: false,
762
778
  label: iosName,
763
779
  workspace
@@ -787,7 +803,7 @@ function shutDownDevices(project, workspace, { teardownIos, teardownAvd, report
787
803
  slot,
788
804
  deviceId: android.avdName
789
805
  });
790
- const result = teardownAvd(android.avdName, {
806
+ const result = await teardownAvd(android.avdName, {
791
807
  del: false,
792
808
  workspace
793
809
  });
@@ -896,7 +912,7 @@ function summarize(root, outcomes, ok) {
896
912
  return `${ok ? "Stopped" : "Stopped with problems"}: ${what} (${root})`;
897
913
  }
898
914
  function defaultFreePort(root, port) {
899
- return withConfigLock$1(() => {
915
+ return withConfigLockAsync$1(() => {
900
916
  const current = getProject(root);
901
917
  if (!current) return true;
902
918
  if (current.supervisor || current.metroPort !== port) return false;
@@ -904,11 +920,13 @@ function defaultFreePort(root, port) {
904
920
  return true;
905
921
  });
906
922
  }
907
- async function defaultClearRegistration(root, expected) {
923
+ async function defaultClearRegistration(root, expected, report) {
908
924
  try {
909
- return clearSupervisor(root, expected);
910
- } catch {
911
- return false;
925
+ return await withConfigLockAsync$1(() => clearSupervisor(root, expected));
926
+ } catch (error) {
927
+ const message = `Could not clear workspace registration: ${error instanceof Error ? error.message : String(error)}`;
928
+ report(chalk.red(phaseLine("stop", message)));
929
+ return { error: message };
912
930
  }
913
931
  }
914
932
  const INTERRUPT_WAIT_MS = 6e4;
@@ -952,22 +970,30 @@ function workspaceDeviceSlots(root) {
952
970
  if (typeof readRemoteSession(root)?.sessionId === "string" && !slots.includes("default")) slots.push("default");
953
971
  return slots;
954
972
  }
955
- function readRemoteSessionEntry(root, report) {
973
+ async function readRemoteSessionEntry(root, report, operation) {
956
974
  const sessionId = readRemoteSession(root)?.sessionId;
957
975
  if (typeof sessionId !== "string") return null;
958
976
  report(chalk.dim(phaseLine("device", `ending remote session ${sessionId} without waiting on the build lock`)));
959
977
  return endRemoteSession(root, sessionId, {
960
- teardownRemoteSession: defaultTeardownRemoteSession,
978
+ teardownRemoteSession: (projectRoot, id) => defaultTeardownRemoteSession(projectRoot, id, operation),
961
979
  report
962
980
  });
963
981
  }
982
+ function signalledHolder(holder) {
983
+ return nativeRunHolder(holder).takesSignals && holder.owner.pid !== process.pid;
984
+ }
964
985
  /**
965
986
  * `stop` under the workspace's native-run lock. A billable remote session is ended as soon as the lock is
966
- * seen held; a live `ios` or `android` run that the stop leaves nothing to deploy to is interrupted with
967
- * SIGINT and given INTERRUPT_WAIT_MS to exit; a build for another slot that stays is left running while
987
+ * seen held; a live `ios` or `android` run that the stop leaves nothing to deploy to is asked to cancel through
988
+ * its workspace state, sent SIGINT when its holder is a CLI process, and given INTERRUPT_WAIT_MS to exit; a build
989
+ * for another slot that stays is left running while
968
990
  * the slot stops without the lock; any other holder is waited on with a visible notice.
969
991
  */
970
- async function stopWorkspaceNow({ root, slot, report = (line) => console.error(line), now = Date.now, sleep, waitMs = NATIVE_RUN_WAIT_MS, interruptWaitMs = INTERRUPT_WAIT_MS, inspectIdentity = process_identity_exports.inspectProcessIdentity, interrupt = (pid) => process.kill(pid, "SIGINT"), endRemote = (projectRoot) => readRemoteSessionEntry(projectRoot, report), deviceSlots = workspaceDeviceSlots, recordedSlots = recordedDeviceSlots, stop = (options) => runStop(options) }) {
992
+ async function stopWorkspaceNow({ root, operation, slot, report = (line) => console.error(line), now = Date.now, sleep, waitMs = NATIVE_RUN_WAIT_MS, interruptWaitMs = INTERRUPT_WAIT_MS, inspectIdentity = process_identity_exports.inspectProcessIdentity, interrupt = (pid) => process.kill(pid, "SIGINT"), endRemote = (projectRoot) => readRemoteSessionEntry(projectRoot, report, operation), deviceSlots = workspaceDeviceSlots, recordedSlots = recordedDeviceSlots, stop = (options) => runStop({
993
+ ...options,
994
+ operation,
995
+ report
996
+ }) }) {
971
997
  if (slot === "web") return stop({
972
998
  root,
973
999
  slot
@@ -984,10 +1010,10 @@ async function stopWorkspaceNow({ root, slot, report = (line) => console.error(l
984
1010
  };
985
1011
  let remote = null;
986
1012
  let remoteHandled = slot !== void 0;
987
- const endRemoteNow = () => {
1013
+ const endRemoteNow = async () => {
988
1014
  if (remoteHandled) return;
989
1015
  remoteHandled = true;
990
- remote = endRemote(root);
1016
+ remote = await endRemote(root);
991
1017
  };
992
1018
  const notice = nativeRunWaitNotice({
993
1019
  write: (line) => report(chalk.dim(phaseLine("lock", line))),
@@ -995,62 +1021,71 @@ async function stopWorkspaceNow({ root, slot, report = (line) => console.error(l
995
1021
  });
996
1022
  let seen = null;
997
1023
  const interrupted = [];
998
- const onHeld = (holder) => {
1024
+ const onHeld = async (holder) => {
999
1025
  const at = now();
1000
1026
  if (seen?.claimId === holder.claimId) {
1001
1027
  if (seen.action === "interrupt" && at >= seen.deadline) {
1002
1028
  if (inspectIdentity(holder.owner) !== "same") throw ownerGoneRefusal(holder, at);
1029
+ const signalled = signalledHolder(holder);
1003
1030
  throw new StopBlocked({
1004
1031
  code: "STIM_STOP_BLOCKED",
1005
- message: `${describeNativeRunHolder(holder, at)} did not exit within ${Math.round(interruptWaitMs / 1e3)}s of SIGINT; it still holds this workspace's native-run claim at ${holder.path}.`,
1006
- remedy: `Wait for it to finish, or end it with \`kill ${holder.owner.pid}\`, then run \`stim stop\` again.`
1032
+ message: `${describeNativeRunHolder(holder, at)} did not exit within ${Math.round(interruptWaitMs / 1e3)}s of ${signalled ? "SIGINT" : "the stop request"}; it still holds this workspace's native-run claim at ${holder.path}.`,
1033
+ remedy: signalled ? `Wait for it to finish, or end it with \`kill ${holder.owner.pid}\`, then run \`stim stop\` again.` : `It runs inside process ${holder.owner.pid}, which embeds Stim (such as stim-server) and runs other work too. Wait for the run to finish, or cancel it from the client that started it, then run \`stim stop\` again.`
1007
1034
  });
1008
1035
  }
1009
1036
  notice(holder);
1010
1037
  return;
1011
1038
  }
1012
- endRemoteNow();
1013
- const target = nativeRunHolder(holder);
1014
- if (unknownSlot) {
1015
- const refusal = target.slot === slot ? null : stillUnknown();
1016
- if (refusal) throw refusal;
1017
- unknownSlot = false;
1018
- }
1019
- const { action } = decideStopAction({
1020
- stopSlot: slot,
1021
- holder: target,
1022
- ownerIdentity: inspectIdentity(holder.owner),
1023
- deviceSlots: deviceSlots(root)
1024
- });
1025
- seen = {
1026
- claimId: holder.claimId,
1027
- action,
1028
- deadline: Number.POSITIVE_INFINITY
1029
- };
1030
- const who = describeNativeRunHolder(holder, at);
1031
- if (action === "proceed") {
1032
- notice(holder, `leaving ${who} running: slot ${target.slot} stays, so slot ${slot} stops without the build lock`);
1033
- throw new LeaveBuildRunning();
1034
- }
1035
- if (action === "refuse") throw ownerGoneRefusal(holder, at);
1036
- if (action === "interrupt") {
1037
- requestNativeRunCancel(root, holder.claimId);
1038
- interrupted.push(holder.claimId);
1039
+ try {
1040
+ const target = nativeRunHolder(holder);
1041
+ if (unknownSlot) {
1042
+ const refusal = target.slot === slot ? null : stillUnknown();
1043
+ if (refusal) throw refusal;
1044
+ unknownSlot = false;
1045
+ }
1046
+ const { action } = decideStopAction({
1047
+ stopSlot: slot,
1048
+ holder: target,
1049
+ ownerIdentity: inspectIdentity(holder.owner),
1050
+ deviceSlots: deviceSlots(root)
1051
+ });
1039
1052
  seen = {
1040
1053
  claimId: holder.claimId,
1041
1054
  action,
1042
- deadline: now() + interruptWaitMs
1055
+ deadline: Number.POSITIVE_INFINITY
1043
1056
  };
1044
- if (inspectIdentity(holder.owner) !== "same") return;
1045
- try {
1046
- interrupt(holder.owner.pid);
1047
- } catch (error) {
1048
- if (error?.code !== "ESRCH") throw error;
1057
+ const who = describeNativeRunHolder(holder, at);
1058
+ if (action === "proceed") {
1059
+ notice(holder, `leaving ${who} running: slot ${target.slot} stays, so slot ${slot} stops without the build lock`);
1060
+ throw new LeaveBuildRunning();
1049
1061
  }
1050
- notice(holder, `interrupting ${who}: sent SIGINT, waiting up to ${Math.round(interruptWaitMs / 1e3)}s for it to exit`);
1051
- return;
1062
+ if (action === "refuse") throw ownerGoneRefusal(holder, at);
1063
+ if (action === "interrupt") {
1064
+ await withWorkspaceStateLockAsync(root, () => requestNativeRunCancel(root, holder.claimId));
1065
+ interrupted.push(holder.claimId);
1066
+ seen = {
1067
+ claimId: holder.claimId,
1068
+ action,
1069
+ deadline: now() + interruptWaitMs
1070
+ };
1071
+ if (inspectIdentity(holder.owner) !== "same") return;
1072
+ const wait = `waiting up to ${Math.round(interruptWaitMs / 1e3)}s for it to exit`;
1073
+ if (!signalledHolder(holder)) {
1074
+ notice(holder, `interrupting ${who}: asked it to stop, ${wait}`);
1075
+ return;
1076
+ }
1077
+ try {
1078
+ interrupt(holder.owner.pid);
1079
+ } catch (error) {
1080
+ if (error?.code !== "ESRCH") throw error;
1081
+ }
1082
+ notice(holder, `interrupting ${who}: sent SIGINT, ${wait}`);
1083
+ return;
1084
+ }
1085
+ notice(holder);
1086
+ } finally {
1087
+ await endRemoteNow();
1052
1088
  }
1053
- notice(holder);
1054
1089
  };
1055
1090
  const withRemote = (result) => {
1056
1091
  if (!remote || result.outcomes.device.remote) return result;
@@ -1068,9 +1103,11 @@ async function stopWorkspaceNow({ root, slot, report = (line) => console.error(l
1068
1103
  });
1069
1104
  }, {
1070
1105
  external: true,
1106
+ signal: operation?.signal,
1071
1107
  waitMs,
1072
1108
  now,
1073
1109
  ...sleep ? { sleep } : {},
1110
+ declareSpawnsFor: operation,
1074
1111
  details: {
1075
1112
  command: "stop",
1076
1113
  ...slot === void 0 ? {} : { slot }
@@ -1086,10 +1123,12 @@ async function stopWorkspaceNow({ root, slot, report = (line) => console.error(l
1086
1123
  refusal: error.refusal,
1087
1124
  remote
1088
1125
  };
1089
- if ((0, ownership_claim_exports.isClaimRefusal)(error)) endRemoteNow();
1126
+ if ((0, ownership_claim_exports.isClaimRefusal)(error)) await endRemoteNow();
1090
1127
  throw error;
1091
1128
  } finally {
1092
- for (const claimId of interrupted) clearNativeRunCancel(root, claimId);
1129
+ for (const claimId of interrupted) try {
1130
+ await withWorkspaceStateLockAsync(root, () => clearNativeRunCancel(root, claimId));
1131
+ } catch {}
1093
1132
  }
1094
1133
  }
1095
1134
  function stopCommand(program) {
@@ -1,9 +1,10 @@
1
- import { n as ownership_claim_exports, t as process_identity_exports } from "./process-identity-Biv3arCO.mjs";
2
- import { c as writeWorkspaceState, x as workspaceDir } from "./workspace-state-CvgTFe-h.mjs";
3
- import { m as runningBundleInstances } from "./workspaces-C4kqIOlx.mjs";
4
- import { a as withWorkspaceProcessLock } from "./named-ports-O1TIl7tx.mjs";
5
- import { a as macosRuntimeClaim, o as requiredMacosRecord } from "./state-BUpAmt2r.mjs";
6
- import { n as stopHostedMacos } from "./hosted-macos-ckTjN-0V.mjs";
1
+ import { f as ownership_claim_exports, p as process_identity_exports } from "./exec-_UbtCQcG.mjs";
2
+ import { d as workspaceDir } from "./paths-DQtTgsBf.mjs";
3
+ import { d as writeWorkspaceState, l as withWorkspaceStateLockAsync } from "./workspace-state-Cjuigeeu.mjs";
4
+ import { a as macosRuntimeClaim, o as requiredMacosRecord } from "./state-XMziexv2.mjs";
5
+ import { S as runningBundleInstancesAsync } from "./workspaces-BccMFmGQ.mjs";
6
+ import { t as withWorkspaceProcessLock } from "./workspace-process-lock-1_1OoVW5.mjs";
7
+ import { n as stopHostedMacos } from "./hosted-macos-QI141yKk.mjs";
7
8
  import { readMacosRecord } from "@stim-cli/core/state";
8
9
  //#region src/macos/stop.ts
9
10
  const APP_EXIT_MS = 5e3;
@@ -33,7 +34,7 @@ async function stopProcesses(records, waitMs = APP_EXIT_MS) {
33
34
  }
34
35
  /** Stops every running copy of the workspace's owned app bundle, including copies LaunchServices started. */
35
36
  async function stopBundleInstances(root) {
36
- const instances = runningBundleInstances(root);
37
+ const instances = await runningBundleInstancesAsync(root);
37
38
  await stopProcesses(instances);
38
39
  return instances.length > 0;
39
40
  }
@@ -42,7 +43,7 @@ async function stopMacosAppHeld(root) {
42
43
  if (record?.supervisor) await stopProcesses([record.supervisor], SUPERVISOR_EXIT_MS);
43
44
  const app = readMacosRecord(root)?.app ?? record?.app;
44
45
  if (app) await stopProcesses([app]);
45
- const instances = runningBundleInstances(root);
46
+ const instances = await runningBundleInstancesAsync(root);
46
47
  await stopProcesses(instances);
47
48
  if (!record) return instances.length > 0;
48
49
  const claims = (0, ownership_claim_exports.readClaimSet)(macosRuntimeClaim(root));
@@ -56,10 +57,10 @@ function stopMacosApp(root) {
56
57
  if (!record?.host) return stopMacosAppHeld(root);
57
58
  await stopHostedMacos(root, record.host);
58
59
  const { host: _host, hostLaunched: _launched, ...stopped } = record;
59
- writeWorkspaceState(root, { macos: {
60
+ await withWorkspaceStateLockAsync(root, () => writeWorkspaceState(root, { macos: {
60
61
  ...stopped,
61
62
  supervisor: void 0
62
- } });
63
+ } }));
63
64
  return true;
64
65
  };
65
66
  return withWorkspaceProcessLock(workspaceDir(root), "macos-launch", stop, {
@@ -1,6 +1,10 @@
1
- import { a as clearWorkspaceSupervisor, i as clearExpoMetroTunnel, n as MODE_BARE, o as readPidFile, r as MODE_EXPO, s as writePidFile, t as SettingsObject } from "./settings-vk3mJGSm.mjs";
2
- import { t as NdjsonWriter } from "./ndjson-Du3j0AQ9.mjs";
3
- import { DevServerStopRecord, DeviceActivity, DeviceIdleShutdownRecord, IOS_SIMULATOR_APPS } from "@stim-cli/core/state";
1
+ import { a as clearExpoMetroTunnel, c as writePidFile, n as MODE_BARE, o as clearWorkspaceSupervisor, r as MODE_EXPO, s as readPidFile, t as SettingsObject } from "./settings-DkdmlelE.mjs";
2
+ import { n as NdjsonWriter } from "./exec-H20xSg2T.mjs";
3
+ import { n as OwnedDeviceActivity } from "./idle-BVeRGroT.mjs";
4
+ import { DevServerStopRecord, DeviceIdleShutdownRecord } from "@stim-cli/core/state";
5
+ //#region src/watchman.d.ts
6
+ type WatchmanCommand = (args: string[], timeoutMs: number) => Promise<unknown>;
7
+ //#endregion
4
8
  //#region src/supervisor/types.d.ts
5
9
  interface ServerExitInfo {
6
10
  code?: number | null;
@@ -30,16 +34,6 @@ interface IdleProbe {
30
34
  blocker(): string | null;
31
35
  }
32
36
  //#endregion
33
- //#region src/commands/gc/idle.d.ts
34
- interface OwnedDeviceActivity {
35
- kind: "ios" | "android";
36
- id: string;
37
- name: string;
38
- project: string;
39
- slot: string;
40
- activity: DeviceActivity;
41
- }
42
- //#endregion
43
37
  //#region src/devices/idle-shutdown.d.ts
44
38
  interface DueDevice {
45
39
  device: OwnedDeviceActivity;
@@ -60,10 +54,7 @@ interface IdleShutdownEvent {
60
54
  declare function shutDownIdleDevices(root: string, idleMs: number, log: (event: IdleShutdownEvent) => void, now?: number, { only, reason }?: {
61
55
  only?: OwnedDeviceActivity;
62
56
  reason?: DeviceIdleShutdownRecord["reason"];
63
- }): number;
64
- //#endregion
65
- //#region src/watchman.d.ts
66
- type WatchmanCommand = (args: string[], timeoutMs: number) => Promise<unknown>;
57
+ }): Promise<number>;
67
58
  //#endregion
68
59
  //#region src/supervisor/run.d.ts
69
60
  interface ParsedSupervisorArgs {