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
@@ -0,0 +1,277 @@
1
+ import { a as refuseDeclaredSpawns, f as ownership_claim_exports, l as isTermination, o as signalDeclaredSpawns, r as allowDeclaredSpawns, u as operationState } from "./exec-_UbtCQcG.mjs";
2
+ import { d as workspaceDir } from "./paths-DQtTgsBf.mjs";
3
+ import { a as formatElapsed, l as phaseLine } from "./command-output-B1UrjZHL.mjs";
4
+ import { o as updateWorkspaceState, r as readWorkspaceState, t as clearWorkspaceStateKey } from "./workspace-state-Cjuigeeu.mjs";
5
+ import { t as canonicalPath } from "./paths-BsJMoPP2.mjs";
6
+ import { t as withWorkspaceProcessLock } from "./workspace-process-lock-1_1OoVW5.mjs";
7
+ import { existsSync, mkdirSync } from "node:fs";
8
+ import { basename, dirname, join } from "node:path";
9
+ import { setTimeout } from "node:timers/promises";
10
+ //#region src/cache/cache-claim.ts
11
+ const LABEL = "cache";
12
+ const POLL_MS = 500;
13
+ const EMPTYING_WAIT_MS = 6e5;
14
+ /**
15
+ * The claim set guarding a cache Stim can only empty whole. It sits beside the cache's resolved directory, so emptying
16
+ * the cache never removes it and every path that reaches the same cache names the same set; before the cache exists,
17
+ * its resolved parent stands in for it.
18
+ */
19
+ function cacheClaimRoot(dir) {
20
+ return `${existsSync(dir) ? canonicalPath(dir) : join(canonicalPath(dirname(dir)), basename(dir))}.claims`;
21
+ }
22
+ function describe(holder) {
23
+ const { platform, projectRoot } = holder.details;
24
+ const where = typeof projectRoot === "string" ? ` in ${projectRoot}` : "";
25
+ return holder.mode === "shared" ? `the ${typeof platform === "string" ? platform : "iOS"} build (pid ${holder.owner.pid}${where}) may be using it` : `pid ${holder.owner.pid} is emptying it`;
26
+ }
27
+ /** Why the cache at `dir` may be in use, from its claim set, without taking or removing any claim. */
28
+ function cacheUser(dir) {
29
+ const root = cacheClaimRoot(dir);
30
+ const survey = (0, ownership_claim_exports.readClaimSet)(root);
31
+ const problem = survey.unresolved[0];
32
+ if (problem) return `the cache claim ${problem.path} is unresolved, so a build may be using it`;
33
+ const holder = survey.live[0];
34
+ return holder ? describe(holder) : void 0;
35
+ }
36
+ /**
37
+ * Takes the exclusive claim an emptier holds while it removes the cache's contents; a string is why it cannot.
38
+ * It never waits for a build that holds the cache.
39
+ */
40
+ function claimForEmptying(dir) {
41
+ try {
42
+ const attempt = (0, ownership_claim_exports.tryAcquireClaim)({
43
+ root: cacheClaimRoot(dir),
44
+ mode: "exclusive",
45
+ label: LABEL
46
+ });
47
+ if (attempt.acquired) return attempt.acquired;
48
+ if (attempt.pending) (0, ownership_claim_exports.releaseClaim)(attempt.pending);
49
+ const holder = attempt.held ?? attempt.waitingFor?.[0];
50
+ return holder ? describe(holder) : `its claim at ${cacheClaimRoot(dir)} could not be taken`;
51
+ } catch (error) {
52
+ if ((0, ownership_claim_exports.isClaimRefusal)(error) || (0, ownership_claim_exports.isClaimUnavailable)(error)) return error.message;
53
+ return `its claim at ${cacheClaimRoot(dir)} could not be taken: ${error instanceof Error ? error.message : String(error)}`;
54
+ }
55
+ }
56
+ /**
57
+ * Takes the shared claim a build holds on the compilation cache it compiles with, waiting while an emptier holds it.
58
+ * A claim set Stim cannot resolve, or no process identity, is a failure: the build never runs unguarded.
59
+ */
60
+ async function shareCompilationCache({ dir, projectRoot, note, signal }) {
61
+ const started = Date.now();
62
+ let told = false;
63
+ for (;;) {
64
+ signal?.throwIfAborted();
65
+ let attempt;
66
+ let root = `${dir}.claims`;
67
+ try {
68
+ mkdirSync(dirname(dir), { recursive: true });
69
+ root = cacheClaimRoot(dir);
70
+ attempt = (0, ownership_claim_exports.tryAcquireClaim)({
71
+ root,
72
+ mode: "shared",
73
+ label: LABEL,
74
+ details: {
75
+ platform: "ios",
76
+ projectRoot
77
+ }
78
+ });
79
+ } catch (error) {
80
+ return { failure: (0, ownership_claim_exports.claimFailure)(error, null) ?? {
81
+ code: ownership_claim_exports.CLAIM_UNAVAILABLE,
82
+ message: `Stim could not take the compilation cache claim at ${root}: ${error instanceof Error ? error.message : String(error)}.`,
83
+ remedy: `Restore write access to ${dirname(root)}, then retry the same Stim command.`
84
+ } };
85
+ }
86
+ if (attempt.acquired) return { claim: attempt.acquired };
87
+ const emptier = attempt.held ? `pid ${attempt.held.owner.pid}` : "another process";
88
+ const waited = Date.now() - started;
89
+ if (waited >= EMPTYING_WAIT_MS) return { failure: {
90
+ code: "STIM_BUILD_FAILED",
91
+ message: `${emptier} has been emptying the compilation cache at ${dir} for ${formatElapsed(waited)}.`,
92
+ remedy: "Run the same command again once it has finished."
93
+ } };
94
+ if (!told) note(phaseLine("build", `waiting for ${emptier} to finish emptying the compilation cache at ${dir}`));
95
+ told = true;
96
+ await setTimeout(POLL_MS);
97
+ }
98
+ }
99
+ //#endregion
100
+ //#region src/engine/native-run.ts
101
+ const NATIVE_RUN_LOCK = "native-run";
102
+ const NATIVE_RUN_WAIT_MS = 18e5;
103
+ const WAIT_HEARTBEAT_MS = 3e4;
104
+ const CANCEL_REQUEST_KEY = "nativeRunCancel";
105
+ const REQUEST_POLL_MS = 250;
106
+ function nativeRunHolder(holder) {
107
+ const { command, platform, slot, interrupt } = holder.details;
108
+ return {
109
+ command: typeof command === "string" ? command : null,
110
+ platform: typeof platform === "string" ? platform : null,
111
+ slot: typeof slot === "string" ? slot : "default",
112
+ takesSignals: interrupt === "signal"
113
+ };
114
+ }
115
+ function describeNativeRunHolder(holder, now) {
116
+ const { command, slot } = nativeRunHolder(holder);
117
+ const started = Date.parse(holder.startedAt);
118
+ const facts = [`pid ${holder.owner.pid}`];
119
+ if (Number.isFinite(started)) facts.push(`running for ${formatElapsed(now - started)}`);
120
+ if (command === null) return `another Stim run (${facts.join(", ")})`;
121
+ if (command === "build") return `an artifact build (${facts.join(", ")})`;
122
+ return `\`stim ${command}${slot === "default" ? "" : ` --slot ${slot}`}\` (${facts.join(", ")})`;
123
+ }
124
+ /**
125
+ * Report a wait on the native-run lock: one line as soon as a holder is seen, a line for each new
126
+ * holder, and a heartbeat every WAIT_HEARTBEAT_MS while the same holder keeps it.
127
+ */
128
+ function nativeRunWaitNotice({ write, now = Date.now, describe = describeNativeRunHolder }) {
129
+ let claimId = null;
130
+ let lastAt = 0;
131
+ return (holder, firstLine) => {
132
+ const at = now();
133
+ if (holder.claimId !== claimId) {
134
+ claimId = holder.claimId;
135
+ lastAt = at;
136
+ write(firstLine ?? `waiting for ${describe(holder, at)} in this workspace to finish`);
137
+ return;
138
+ }
139
+ if (at - lastAt < WAIT_HEARTBEAT_MS) return;
140
+ lastAt = at;
141
+ write(`still waiting for ${describe(holder, at)}`);
142
+ };
143
+ }
144
+ /**
145
+ * What `stop` does about the run holding the native-run lock. A build is interrupted only when the stop
146
+ * leaves it nothing to deploy to: the whole workspace stops, the build targets the stopped slot, or the
147
+ * stopped slot is the workspace's only device. A build for another slot that stays is left running and
148
+ * the stop proceeds without the lock. Only an owner whose identity is proven live is signalled.
149
+ */
150
+ function decideStopAction({ stopSlot, holder, ownerIdentity, deviceSlots }) {
151
+ if (holder.command === "macos" || holder.command === "build") {
152
+ if (stopSlot !== void 0) return { action: "proceed" };
153
+ return ownerIdentity === "same" ? { action: "interrupt" } : { action: "refuse" };
154
+ }
155
+ if (holder.command !== "ios" && holder.command !== "android") return { action: "wait" };
156
+ if (!(stopSlot === void 0 || holder.slot === stopSlot || deviceSlots.includes(stopSlot) && deviceSlots.every((slot) => slot === stopSlot))) return { action: "proceed" };
157
+ return ownerIdentity === "same" ? { action: "interrupt" } : { action: "refuse" };
158
+ }
159
+ const requestListeners = /* @__PURE__ */ new Map();
160
+ /**
161
+ * Ask the run holding `claimId` to cancel: the request is written to the workspace state, where the run's watch
162
+ * finds it, and a run in this process is told at once.
163
+ */
164
+ function requestNativeRunCancel(root, claimId, pid = process.pid) {
165
+ updateWorkspaceState(root, (state) => ({
166
+ ...state,
167
+ [CANCEL_REQUEST_KEY]: {
168
+ claimId,
169
+ pid,
170
+ at: (/* @__PURE__ */ new Date()).toISOString()
171
+ }
172
+ }));
173
+ requestListeners.get(claimId)?.();
174
+ }
175
+ function cancelRequestFor(root, claimId) {
176
+ const request = readWorkspaceState(root)?.[CANCEL_REQUEST_KEY];
177
+ if (request?.claimId !== claimId || typeof request.pid !== "number") return null;
178
+ return { pid: request.pid };
179
+ }
180
+ function clearNativeRunCancel(root, claimId) {
181
+ try {
182
+ clearWorkspaceStateKey(root, CANCEL_REQUEST_KEY, (value) => value?.claimId === claimId);
183
+ } catch {}
184
+ }
185
+ /** The active native run of `context`'s operation aborts this signal when it is cancelled. */
186
+ function runCancellationSignal(context) {
187
+ return operationState(context).runSignal;
188
+ }
189
+ /** Why `context`'s native run was cancelled, or null while it was not. */
190
+ function runCancellation(context) {
191
+ return operationState(context).cancelled;
192
+ }
193
+ function cancelledFailure(context, platform, { code, message }) {
194
+ const cancelled = runCancellation(context);
195
+ if (cancelled === null) return null;
196
+ return {
197
+ code: "STIM_CANCELLED",
198
+ message: `The ${platform} run was ${cancelled} before it finished.`,
199
+ remedy: `Run \`stim ${platform}\` again when you want the app on a device.`,
200
+ lines: [`it stopped at ${code ?? "an unfinished step"}${message ? `: ${message}` : ""}`]
201
+ };
202
+ }
203
+ function cancelOnAbort({ context, root, claim, write, controller }) {
204
+ const state = operationState(context);
205
+ const cancel = () => {
206
+ if (controller.signal.aborted) return;
207
+ const request = cancelRequestFor(root, claim.claimId);
208
+ const cancelled = request ? `cancelled by \`stim stop\` (pid ${request.pid})` : "cancelled by an interrupt";
209
+ state.cancelled = cancelled;
210
+ state.handled = true;
211
+ controller.abort();
212
+ refuseDeclaredSpawns(context, `the run was ${cancelled}`);
213
+ const signalled = signalDeclaredSpawns(context, "SIGINT");
214
+ if (signalled > 0 || request) state.draining = true;
215
+ write(signalled > 0 ? `${cancelled}; stopping the running build tool` : request ? `${cancelled}; stopping before the next build tool or install` : cancelled);
216
+ };
217
+ const onAbort = () => {
218
+ if (!isTermination(context.signal.reason)) cancel();
219
+ };
220
+ const onRequest = () => {
221
+ if (controller.signal.aborted || !cancelRequestFor(root, claim.claimId)) return;
222
+ cancel();
223
+ state.abortOperation?.("stop");
224
+ };
225
+ context.signal.addEventListener("abort", onAbort);
226
+ if (context.signal.aborted) onAbort();
227
+ requestListeners.set(claim.claimId, onRequest);
228
+ const watch = setInterval(onRequest, REQUEST_POLL_MS);
229
+ watch.unref();
230
+ return () => {
231
+ clearInterval(watch);
232
+ requestListeners.delete(claim.claimId);
233
+ context.signal.removeEventListener("abort", onAbort);
234
+ allowDeclaredSpawns(context);
235
+ clearNativeRunCancel(root, claim.claimId);
236
+ };
237
+ }
238
+ /**
239
+ * Run an `ios`, `android` or `macos` invocation under the workspace's native-run lock: the claim records the
240
+ * command, platform and slot, and a wait for another holder is reported on `write`. An abort of `context.signal`
241
+ * forwards an interrupt to the running declared build tool and refuses any later one; a run `stim stop` cancelled
242
+ * stops before its next build tool or install. A `SIGTERM` abort reason is left to the caller.
243
+ */
244
+ function withNativeBuildRun(context, root, details, fn, { write }) {
245
+ const notice = nativeRunWaitNotice({ write });
246
+ const state = operationState(context);
247
+ return withWorkspaceProcessLock(workspaceDir(root), NATIVE_RUN_LOCK, async (claim) => {
248
+ state.cancelled = null;
249
+ const controller = new AbortController();
250
+ state.runSignal = controller.signal;
251
+ const dispose = cancelOnAbort({
252
+ context,
253
+ root,
254
+ claim,
255
+ write,
256
+ controller
257
+ });
258
+ try {
259
+ return await fn(claim);
260
+ } finally {
261
+ dispose();
262
+ state.runSignal = void 0;
263
+ }
264
+ }, {
265
+ external: true,
266
+ signal: context.signal,
267
+ waitMs: NATIVE_RUN_WAIT_MS,
268
+ declareSpawnsFor: context,
269
+ details: {
270
+ ...details,
271
+ interrupt: state.takesSignals ? "signal" : "request"
272
+ },
273
+ onHeld: (holder) => notice(holder)
274
+ });
275
+ }
276
+ //#endregion
277
+ export { decideStopAction as a, nativeRunWaitNotice as c, runCancellationSignal as d, withNativeBuildRun as f, shareCompilationCache as h, clearNativeRunCancel as i, requestNativeRunCancel as l, claimForEmptying as m, NATIVE_RUN_WAIT_MS as n, describeNativeRunHolder as o, cacheUser as p, cancelledFailure as r, nativeRunHolder as s, NATIVE_RUN_LOCK as t, runCancellation as u };
@@ -1,15 +1,15 @@
1
- import { j as metroPortSetting } from "./settings-Bbztm4oV.mjs";
2
- import { p as ensureWorkspaceStorage, r as readWorkspaceState$1 } from "./workspace-state-CvgTFe-h.mjs";
3
- import { l as phaseLine } from "./command-output-CPDq_90S.mjs";
4
- import { u as resolveProjectMetro } from "./metro-_ZIE3Axg.mjs";
5
- import { c as startDevServer } from "./start-CRkG-mZ7.mjs";
6
- import { r as LAUNCH_UNVERIFIED, t as LAUNCH_BUNDLING } from "./launch-verify-Dl78EVgR.mjs";
1
+ import { n as ensureWorkspaceStorage } from "./paths-DQtTgsBf.mjs";
2
+ import { l as phaseLine } from "./command-output-B1UrjZHL.mjs";
3
+ import { r as readWorkspaceState$1 } from "./workspace-state-Cjuigeeu.mjs";
4
+ import { j as metroPortSetting } from "./settings-CsJDEXgK.mjs";
5
+ import { f as resolveProjectMetro } from "./metro-DEXpIhHC.mjs";
6
+ import { Yt as LAUNCH_UNVERIFIED, qt as LAUNCH_BUNDLING } from "./budget-Bs6SxxzO.mjs";
7
+ import { c as startDevServer } from "./start-7lpH7hmN.mjs";
7
8
  import { readIdleStop } from "@stim-cli/core/state";
8
9
  import chalk from "chalk";
9
10
  //#region src/commands/native-runtime.ts
10
- const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
11
- async function ensureDevServer({ root, port, settings, settingsContext, remote, note, resolve = resolveProjectMetro, start = startDevServer, readState = readWorkspaceState$1 }) {
12
- const pin = metroPortSetting(settings);
11
+ async function ensureDevServer({ root, port, settings, settingsContext, remote, env, note, resolve = resolveProjectMetro, start = startDevServer, readState = readWorkspaceState$1 }) {
12
+ const pin = metroPortSetting(settings, env);
13
13
  const canReuse = !pin.error && (pin.port === null || pin.port === port);
14
14
  const held = port === null || !canReuse ? null : (await resolve(port, root)).metro;
15
15
  if (port !== null && held) return {
@@ -77,4 +77,4 @@ function isPhysicalDeviceRequest(flag) {
77
77
  return flag !== null && flag !== void 0 && flag !== false;
78
78
  }
79
79
  //#endregion
80
- export { sleep as a, launchOutcomeRecord as i, ensureWorkspaceStorageSafely as n, isPhysicalDeviceRequest as r, ensureDevServer as t };
80
+ export { launchOutcomeRecord as i, ensureWorkspaceStorageSafely as n, isPhysicalDeviceRequest as r, ensureDevServer as t };
@@ -1,10 +1,11 @@
1
- import { t as getExecutor } from "./exec-B81Qodjn.mjs";
2
- import { b as workspaceDerivedData, x as workspaceDir } from "./workspace-state-CvgTFe-h.mjs";
3
- import { m as pbxString, p as pbxReferences } from "./project-DX8fXyw_.mjs";
4
- import { f as NativeInputError, p as fingerprintNativeInputs } from "./native-gradle-inputs-BQnIdAlL.mjs";
1
+ import { d as workspaceDir, u as workspaceDerivedData } from "./paths-DQtTgsBf.mjs";
2
+ import { Gt as childEnvironment, qt as killOnAbort } from "./settings-CsJDEXgK.mjs";
3
+ import { i as gitQuietAsync } from "./git-C3iTsJaZ.mjs";
4
+ import { h as pbxString, m as pbxReferences } from "./project-BZNjmW_8.mjs";
5
+ import { n as fingerprintNativeInputs, t as NativeInputError } from "./native-inputs-TRTTTRxt.mjs";
6
+ import { createHash } from "node:crypto";
5
7
  import { existsSync, readFileSync, realpathSync } from "node:fs";
6
8
  import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
7
- import { createHash } from "node:crypto";
8
9
  //#region src/integrations/native-xcode-inputs.ts
9
10
  function nativeXcodePackages(root) {
10
11
  return join(workspaceDir(root), "xcode-packages");
@@ -66,25 +67,30 @@ function inside(root, path) {
66
67
  function fold(path) {
67
68
  return path.normalize("NFC").toLowerCase();
68
69
  }
69
- function gitVisibility(sourceRoot) {
70
+ async function gitVisibility(sourceRoot, env, signal) {
71
+ signal?.throwIfAborted();
70
72
  if (!existsSync(join(sourceRoot, ".git"))) return null;
71
- const listing = getExecutor().runFileQuiet("git", [
72
- "-C",
73
- sourceRoot,
73
+ const childEnv = childEnvironment(env);
74
+ const listing = await gitQuietAsync(sourceRoot, [
74
75
  "ls-files",
75
76
  "-z",
76
77
  "--cached",
77
78
  "--others",
78
79
  "--exclude-standard"
79
80
  ], {
81
+ env: childEnv.env,
80
82
  untrimmed: true,
81
83
  omitEnv: [
84
+ ...childEnv.omitEnv,
82
85
  "GIT_DIR",
83
86
  "GIT_WORK_TREE",
84
87
  "GIT_INDEX_FILE",
85
88
  "GIT_COMMON_DIR"
86
- ]
89
+ ],
90
+ timeoutMs: 12e4,
91
+ onSpawn: killOnAbort(signal)
87
92
  });
93
+ signal?.throwIfAborted();
88
94
  if (listing === null) return null;
89
95
  const listed = /* @__PURE__ */ new Set();
90
96
  const whole = /* @__PURE__ */ new Set();
@@ -106,9 +112,9 @@ function gitVisibility(sourceRoot) {
106
112
  include
107
113
  };
108
114
  }
109
- function nativeXcodeInputSnapshot(root, selection, parameters, sourceRoot = root) {
115
+ async function nativeXcodeInputSnapshot(root, selection, parameters, env, sourceRoot = root, signal) {
110
116
  if (selection.platform === "unknown") return { cacheIneligible: "The selected application platform cannot be resolved from its project configuration" };
111
- const visibility = gitVisibility(sourceRoot);
117
+ const visibility = await gitVisibility(sourceRoot, env, signal);
112
118
  const inputs = [{
113
119
  name: "repository",
114
120
  path: sourceRoot,
@@ -121,7 +127,7 @@ function nativeXcodeInputSnapshot(root, selection, parameters, sourceRoot = root
121
127
  ];
122
128
  const reasons = /* @__PURE__ */ new Set();
123
129
  const environment = {};
124
- for (const [name, value] of Object.entries(process.env).toSorted(([a], [b]) => a.localeCompare(b))) if (value !== void 0 && /^(?:DEVELOPER_DIR|TOOLCHAINS|SDKROOT|CFLAGS|CPPFLAGS|CXXFLAGS|OBJCFLAGS|LDFLAGS|ARCHS|ONLY_ACTIVE_ARCH|SOURCE_DATE_EPOCH|ZERO_AR_DATE|IPHONEOS_DEPLOYMENT_TARGET|MACOSX_DEPLOYMENT_TARGET|DEVELOPMENT_TEAM|XCODE_.*|SWIFT_.*|CLANG_.*|GCC_.*|OTHER_.*FLAGS|CODE_SIGN.*|PROVISIONING_.*)$/.test(name)) environment[name] = value;
130
+ for (const [name, value] of Object.entries(env).toSorted(([a], [b]) => a.localeCompare(b))) if (value !== void 0 && /^(?:DEVELOPER_DIR|TOOLCHAINS|SDKROOT|CFLAGS|CPPFLAGS|CXXFLAGS|OBJCFLAGS|LDFLAGS|ARCHS|ONLY_ACTIVE_ARCH|SOURCE_DATE_EPOCH|ZERO_AR_DATE|IPHONEOS_DEPLOYMENT_TARGET|MACOSX_DEPLOYMENT_TARGET|DEVELOPMENT_TEAM|XCODE_.*|SWIFT_.*|CLANG_.*|GCC_.*|OTHER_.*FLAGS|CODE_SIGN.*|PROVISIONING_.*)$/.test(name)) environment[name] = value;
125
131
  const dependencyRoots = /* @__PURE__ */ new Map();
126
132
  const synchronizedRoots = [];
127
133
  const reveal = (path, complete = true) => {
@@ -145,10 +151,10 @@ function nativeXcodeInputSnapshot(root, selection, parameters, sourceRoot = root
145
151
  const result = value.replace(/\$\(([^)]+)\)|\$\{([^}]+)\}/g, (_match, parenthesized, braced) => {
146
152
  const name = parenthesized ?? braced;
147
153
  if (known[name] !== void 0) return known[name];
148
- const env = process.env[name];
149
- if (env !== void 0) {
150
- environment[name] = env;
151
- return env;
154
+ const supplied = env[name];
155
+ if (supplied !== void 0) {
156
+ environment[name] = supplied;
157
+ return supplied;
152
158
  }
153
159
  missing = true;
154
160
  return "";
@@ -273,8 +279,8 @@ function nativeXcodeInputSnapshot(root, selection, parameters, sourceRoot = root
273
279
  "CCC_OVERRIDE_OPTIONS",
274
280
  "CLANG_CONFIG_FILE_USER_DIR",
275
281
  "CLANG_CONFIG_FILE_SYSTEM_DIR"
276
- ]) if (process.env[name]) reasons.add(`Environment ${name} supplies native inputs outside the resolved project`);
277
- if (process.env.XCODE_XCCONFIG_FILE) xcconfig(resolve(process.env.XCODE_XCCONFIG_FILE), selection.targetProject);
282
+ ]) if (env[name]) reasons.add(`Environment ${name} supplies native inputs outside the resolved project`);
283
+ if (env.XCODE_XCCONFIG_FILE) xcconfig(resolve(selection.container.dir, env.XCODE_XCCONFIG_FILE), selection.targetProject);
278
284
  for (const [name, value] of Object.entries(environment)) if (/(?:FLAGS|OTHER_.*FLAGS)$/.test(name) && /(?:[/@]|(?:^|\s)-(?:I|F|L|include|isystem|iquote|iframework|ivfsoverlay|fmodule|fplugin|resource-dir|sdk))/.test(value)) reasons.add(`Environment ${name} supplies compiler inputs outside the resolved project`);
279
285
  if (nativeXcodeHasPackages(selection)) reasons.add("Swift package manifests, plugins and transitive local dependencies have no verified input closure");
280
286
  if (reasons.size) return { cacheIneligible: [...reasons].join("; ") };
@@ -282,8 +288,9 @@ function nativeXcodeInputSnapshot(root, selection, parameters, sourceRoot = root
282
288
  name,
283
289
  path: realpathSync(path)
284
290
  });
285
- const snapshot = fingerprintNativeInputs(inputs, {
291
+ const snapshot = await fingerprintNativeInputs(inputs, {
286
292
  excluded,
293
+ signal,
287
294
  ignoredDirectoryMarkers: nativeXcodeMetadataDirectories(selection),
288
295
  parameters: {
289
296
  recipe: "native-xcode-v1",
@@ -299,6 +306,7 @@ function nativeXcodeInputSnapshot(root, selection, parameters, sourceRoot = root
299
306
  if (snapshot.entries.some((entry) => synchronizedRoots.some((prefix) => entry.path.startsWith(`${prefix}/`)) && /\.(?:c|cc|cpp|cxx|m|mm|h|hh|hpp|hxx|metal)$/i.test(entry.path))) return { cacheIneligible: "C-family or Metal sources need a verified compiler include dependency graph" };
300
307
  return snapshot;
301
308
  } catch (error) {
309
+ signal?.throwIfAborted();
302
310
  return { cacheIneligible: error instanceof NativeInputError ? error.message : `Native input closure is unavailable: ${error.message}` };
303
311
  }
304
312
  }