stim 1.20.2 → 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 +88 -8
  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-Dzgv6lgR.mjs → agent-device-usage-output-zh1vhbLp.mjs} +21 -65
  6. package/dist/{android-HqP1_vB_.mjs → android-BEJ8Jpl7.mjs} +2 -2
  7. package/dist/{android-DCKZrNvV.mjs → android-BLgbNqox.mjs} +128 -78
  8. package/dist/{android-Dlzxshgp.mjs → android-CV_GCELZ.mjs} +5 -5
  9. package/dist/{android-Mz_Inn3w.mjs → android-DUYkNF4u.mjs} +184 -102
  10. package/dist/{android-cas-Bl-cLJBk.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-HSwkIWEQ.mjs → artifact-B8T3S5gi.mjs} +223 -201
  16. package/dist/{artifact-D3czlUvT.mjs → artifact-DAuZ-FNU.mjs} +158 -148
  17. package/dist/{browser-web-CA-F1GQo.mjs → browser-web-QQzVjz3O.mjs} +26 -24
  18. package/dist/budget-Bs6SxxzO.mjs +9154 -0
  19. package/dist/{build-DYDbfkk5.mjs → build-CoPzQRNw.mjs} +144 -96
  20. package/dist/build-cache-DmyR9Zzc.mjs +602 -0
  21. package/dist/build-plan-CaFskB7_.mjs +188 -0
  22. package/dist/{cache-manifest-XH-fvDUj.mjs → cache-manifest-DkkqguoK.mjs} +2 -2
  23. package/dist/cache-manifest.mjs +1 -1
  24. package/dist/{ccache-zdKiYQ3E.mjs → ccache-BJRZ9pG3.mjs} +10 -9
  25. package/dist/{cdp-Dq_ypAlJ.mjs → cdp-CWmIUMbw.mjs} +18 -5
  26. package/dist/{chrome-BnzZMqsR.mjs → chrome-B6tfCta1.mjs} +7 -4
  27. package/dist/{cli-CLP3diBm.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 -40
  32. package/dist/collector-run.mjs +9 -8
  33. package/dist/{command-output-BTy8hZ0F.mjs → command-output-B1UrjZHL.mjs} +1 -1
  34. package/dist/config-CYcBF478.mjs +949 -0
  35. package/dist/{created-devices-Dzd5C2LF.mjs → created-devices-CqeBlrEn.mjs} +3 -3
  36. package/dist/{dependency-state-DG0p31-y.mjs → dependency-state-BbKQW83h.mjs} +20 -5
  37. package/dist/{detached-entry-B9C_zeQC.mjs → detached-entry-DFRyG1_o.mjs} +1 -1
  38. package/dist/{dev-client-DAWVIGBu.mjs → dev-client-UOeESKm6.mjs} +2 -2
  39. package/dist/device-DCxH7_By.mjs +1068 -0
  40. package/dist/{device-BECOiufl.mjs → device-ExJq8Ei7.mjs} +35 -35
  41. package/dist/{device-capacity-CBUAcRyQ.mjs → device-capacity-CMlqEcvw.mjs} +43 -13
  42. package/dist/device-host-worker.mjs +65 -61
  43. package/dist/{device-ios-COSi6oS1.mjs → device-ios-DRUeKaFV.mjs} +48 -45
  44. package/dist/{device-lease-run-Cw2M4z51.mjs → device-lease-run-C8raGFoP.mjs} +14 -26
  45. package/dist/{device-pool-Bf-pOhSw.mjs → device-pool-DMRpVX9a.mjs} +5 -5
  46. package/dist/doctor-BLHCYxzi.mjs +2 -0
  47. package/dist/{doctor-kfMBnUw6.mjs → doctor-DTvaDOda.mjs} +281 -317
  48. package/dist/{doctor-CB8oZKCk.mjs → doctor-Dhqebm0q.mjs} +183 -91
  49. package/dist/doctor-fingerprint.mjs +19 -0
  50. package/dist/{doctor-watchman-BRyV2adA.mjs → doctor-watchman-Cv1F10Kj.mjs} +40 -21
  51. package/dist/{eas-build-JyfqyHfC.mjs → eas-build-BomfRnFT.mjs} +53 -20
  52. package/dist/{build-plan-B7SZsc2N.mjs → eas-fallback-DJwZpy0c.mjs} +26 -208
  53. package/dist/{watchman-CPQFZLXY.mjs → eas-session-ledger-op6A54yi.mjs} +229 -11
  54. package/dist/{error-diagnostics-BR677IDM.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-qWOMdnER.mjs → gc-_-dCXdyL.mjs} +584 -796
  59. package/dist/git-C3iTsJaZ.mjs +73 -0
  60. package/dist/{guide-G9cAbVAc.mjs → guide-Yqwt2bd6.mjs} +941 -269
  61. package/dist/{hosted-android-C3MHGld1.mjs → hosted-android-Bw-honsd.mjs} +8 -6
  62. package/dist/{hosted-client-ZEKpS9vw.mjs → hosted-client-DB_gBPfY.mjs} +34 -19
  63. package/dist/{hosted-ios-l-o3iM9J.mjs → hosted-ios-CUvOf4Vr.mjs} +1 -1
  64. package/dist/{hosted-logs-EzQM7-3Z.mjs → hosted-logs-DL_P5AdN.mjs} +77 -43
  65. package/dist/{hosted-macos-BACVAVqE.mjs → hosted-macos-QI141yKk.mjs} +21 -17
  66. package/dist/{hosted-native-A4s1QPXe.mjs → hosted-native-Ksyjgzq-.mjs} +30 -21
  67. package/dist/idle-BVeRGroT.d.mts +24 -0
  68. package/dist/{idle-shutdown-DtxhPTKe.mjs → idle-shutdown-DaKmZi0z.mjs} +11 -10
  69. package/dist/{ios-BwVCF7oA.mjs → ios-CQ68hG9s.mjs} +8 -8
  70. package/dist/{ios-RkW4pnQf.mjs → ios-CpByZy12.mjs} +140 -80
  71. package/dist/{ios-device-B5veSDDQ.mjs → ios-device-CXGP1bsD.mjs} +1 -1
  72. package/dist/{ios-device-D7pi2Sca.mjs → ios-device-CwFMehUS.mjs} +51 -26
  73. package/dist/{ios-project-K9hY_Jab.mjs → ios-project-WuwwBdvW.mjs} +13 -13
  74. package/dist/{ios-nOLJGVdy.mjs → ios-qNJt4dFm.mjs} +1 -1
  75. package/dist/ios-signing-DTTIChGs.mjs +489 -0
  76. package/dist/{ios-state-CBLe1xYw.mjs → ios-state-DvFX-K_l.mjs} +1 -1
  77. package/dist/{ios-Ce7bc7br.mjs → ios-ubFsBzwq.mjs} +129 -86
  78. package/dist/{js-swap-Bb3nsS07.mjs → js-swap-Cc1dttps.mjs} +53 -26
  79. package/dist/{launch-F4sOqAhB.mjs → launch-CD1yVc7U.mjs} +91 -90
  80. package/dist/{launch-C3qJ6Agb.mjs → launch-Zq2mOSDy.mjs} +82 -541
  81. package/dist/logs-BS00Anxf.mjs +352 -0
  82. package/dist/logs-CMm05HxN.mjs +255 -0
  83. package/dist/{macos-D7uDvO-z.mjs → macos-B65--pPd.mjs} +1 -1
  84. package/dist/{macos-Ch5VJmcS.mjs → macos-C-0qJ6zq.mjs} +225 -212
  85. package/dist/macos-run.mjs +1 -1
  86. package/dist/maintenance-run.mjs +122 -247
  87. package/dist/{metro-DnCEjCxs.mjs → metro-DEXpIhHC.mjs} +67 -12
  88. package/dist/{metro-gateway-CX9Xlkq2.mjs → metro-gateway-BMJNlj3E.mjs} +20 -12
  89. package/dist/{named-ports-4WopRPg-.mjs → named-ports-BWTzt6mu.mjs} +8 -63
  90. package/dist/native-android-JACyjTZs.mjs +844 -0
  91. package/dist/{native-gradle-inputs-BsLRrl7u.mjs → native-gradle-inputs-Bep9JcSF.mjs} +128 -140
  92. package/dist/native-inputs-TRTTTRxt.mjs +91 -0
  93. package/dist/native-run-DY_RLx3C.mjs +277 -0
  94. package/dist/{native-runtime-k8dTIrbK.mjs → native-runtime-Dg1Q7tfF.mjs} +9 -8
  95. package/dist/{native-xcode-inputs-CykopJdM.mjs → native-xcode-inputs-CB2iQeWq.mjs} +27 -18
  96. package/dist/{native-xcode-ios-Bbf30Gm0.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 +197 -66
  100. package/dist/{ownership-DCtw_2IA.mjs → ownership-DEmM5vhh.mjs} +3 -3
  101. package/dist/{page-DRHy329N.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-MOfPVgaM.mjs → placement-log-BqGbTa61.mjs} +5 -5
  105. package/dist/{plan-placement-V0TdzYXp.mjs → plan-placement-Bwj-IjY1.mjs} +6 -6
  106. package/dist/{ports-DdSUicVo.mjs → ports-D-MmCTdv.mjs} +3 -3
  107. package/dist/prebuild-uD_ipCxF.mjs +449 -0
  108. package/dist/{project-_phNIJfs.mjs → project-BZNjmW_8.mjs} +65 -37
  109. package/dist/{pull-request-CQ8sPbZa.mjs → pull-request-Lfetn8Kr.mjs} +2 -2
  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-CM1XRDwv.mjs → react-native-android-DuzH0cn3.mjs} +74 -48
  114. package/dist/{gradle-DSrXb6lG.mjs → react-native-build-rhk4smwQ.mjs} +292 -15
  115. package/dist/react-native-doctor-CQpuIMso.mjs +234 -0
  116. package/dist/{react-native-ios-Dhq_eiYQ.mjs → react-native-ios-Bhq1rJeV.mjs} +46 -28
  117. package/dist/{recordings-D0d5aQt0.mjs → recordings-DYteQSu4.mjs} +12 -9
  118. package/dist/{reload-C8JhxjSh.mjs → reload-CmTRFJaX.mjs} +93 -47
  119. package/dist/reload-DzjSl5P_.mjs +2 -0
  120. package/dist/{remote-BiR6aYjy.mjs → remote-ByYkXdGD.mjs} +15 -10
  121. package/dist/result-DNiS-tTP.mjs +434 -0
  122. package/dist/{run-BtPgpKks.mjs → run-D23HmJMs.mjs} +4 -5
  123. package/dist/selection-CSl9i5qU.mjs +619 -0
  124. package/dist/{server-bare-R2m_gsH8.mjs → server-bare-CxTrvDg8.mjs} +3 -4
  125. package/dist/{server-command-CTtCkmcQ.mjs → server-command-CtzloH3v.mjs} +14 -7
  126. package/dist/server-expo-C-90EhcG.mjs +2 -0
  127. package/dist/{server-expo-DsguMGUF.mjs → server-expo-DT_F_uVI.mjs} +50 -9
  128. package/dist/{settings-B717odTD.mjs → settings-CsJDEXgK.mjs} +234 -24
  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-CCr3rE-A.mjs → simslim-Cgk17SXV.mjs} +14 -12
  134. package/dist/{slot-launch-DPt0m9Nd.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-BWqzODpb.mjs → start-7lpH7hmN.mjs} +63 -44
  138. package/dist/{start-TXeMmmO2.mjs → start-RChynRDp.mjs} +1 -1
  139. package/dist/{state-D1Icyjlu.mjs → state-C4ZtUisW.mjs} +40 -13
  140. package/dist/{state-CG_OFoaA.mjs → state-XMziexv2.mjs} +3 -2
  141. package/dist/{stats-BoY5sEPU.mjs → stats-53T7OTb9.mjs} +7 -13
  142. package/dist/stats-report-BFfMpWWF.mjs +16 -0
  143. package/dist/{status-WgFbkRzj.mjs → status-BL7jVyAB.mjs} +535 -447
  144. package/dist/status-CSi6tlRq.mjs +2 -0
  145. package/dist/{status-BTA7kKiQ.mjs → status-DqEUSSxs.mjs} +6 -4
  146. package/dist/{status-watch-C23ILtf9.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-DR6VoDIk.mjs → stop-Bk_1qiV6.mjs} +2 -2
  151. package/dist/{stop-BNmBMi1F.mjs → stop-CPzlM1L-.mjs} +138 -98
  152. package/dist/{stop-DPEhunlw.mjs → stop-D7h6jAXQ.mjs} +11 -10
  153. package/dist/supervisor-run.d.mts +8 -17
  154. package/dist/supervisor-run.mjs +63 -27
  155. package/dist/{support-DMTqj3Hm.mjs → support-67vraa1Q.mjs} +18 -11
  156. package/dist/{support-CwjbFs9H.mjs → support-Dlu37g6H.mjs} +12 -12
  157. package/dist/{swiftpm-macos-DRNVJWlb.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-CigAYjeL.mjs → trigger-BAahxUPq.mjs} +20 -5
  161. package/dist/trigger-Bf3uDcpv.mjs +2 -0
  162. package/dist/{warm-progress-BuY-Fvfn.mjs → warm-progress-BHX5r0Ei.mjs} +250 -156
  163. package/dist/{web-BDBMxDpx.mjs → web-CJmIj6AI.mjs} +18 -13
  164. package/dist/web-DknQETPs.mjs +2 -0
  165. package/dist/web-run.mjs +11 -12
  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-DJt_MMvf.mjs → workspace-state-Cjuigeeu.mjs} +62 -58
  171. package/dist/{workspaces-C36s2jb9.mjs → workspaces-BccMFmGQ.mjs} +1188 -1079
  172. package/dist/worktree-CK2MpJW5.mjs +2 -0
  173. package/dist/{worktree-CgvJYJ-Q.mjs → worktree-DQ6Zi2Mv.mjs} +304 -53
  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-BSV745Kz.mjs +0 -629
  178. package/dist/api-qvOzWyfO.mjs +0 -154
  179. package/dist/api-run.mjs +0 -294
  180. package/dist/app-install-BIKtMfPq.mjs +0 -896
  181. package/dist/artifact-lifecycle-DzPpBYvK.mjs +0 -30
  182. package/dist/budget-f7516Zk0.mjs +0 -4106
  183. package/dist/build-facts-DcLv2HSd.d.mts +0 -111
  184. package/dist/cancellation-C_22VQTH.mjs +0 -24
  185. package/dist/client-qQAaXSUs.mjs +0 -1771
  186. package/dist/config-BYDxlMY3.mjs +0 -562
  187. package/dist/device-DuiPJQSn.mjs +0 -290
  188. package/dist/device-lease-BX1sJQ2E.mjs +0 -1224
  189. package/dist/device-remote-xRT0Vmo9.mjs +0 -1272
  190. package/dist/eas-session-ledger-Cm0Gwq2F.mjs +0 -207
  191. package/dist/exec-DqKo9GKJ.mjs +0 -268
  192. package/dist/git-DDfFzkMm.mjs +0 -45
  193. package/dist/launch-verify-B6Q8hZP-.mjs +0 -428
  194. package/dist/logs-BGrEUaEs.mjs +0 -383
  195. package/dist/miss-reason-mKzZ4VvN.mjs +0 -238
  196. package/dist/native-android-D5qc3-_v.mjs +0 -226
  197. package/dist/ndjson-Du3j0AQ9.d.mts +0 -17
  198. package/dist/plan-C4TjdPsR.mjs +0 -260
  199. package/dist/prebuild-DYbucPXy.mjs +0 -212
  200. package/dist/preview-78a9kR_-.mjs +0 -1011
  201. package/dist/react-native-build-CtCccJtb.mjs +0 -239
  202. package/dist/react-native-doctor-CfRnFfjs.mjs +0 -78
  203. package/dist/remote-cache-OyOyVIS3.mjs +0 -526
  204. package/dist/result-CaJg5Iat.mjs +0 -186
  205. package/dist/server-expo-Bigriskl.mjs +0 -2
  206. package/dist/settings-BORNaaCO.mjs +0 -402
  207. package/dist/spawn-claims-DVS5RkMS.mjs +0 -72
  208. package/dist/stage-KNTQopqv.mjs +0 -157
  209. package/dist/stim-desktop-BzBN2Em2.mjs +0 -63
  210. package/dist/tailnet-Dh-qiYzG.mjs +0 -265
  211. package/dist/toolchain-BFkAcstd.mjs +0 -2
  212. package/dist/toolchain-DxSsNssu.mjs +0 -1657
  213. package/dist/trigger-9_USgmxz.mjs +0 -2
  214. package/dist/web-Dq-i3wzJ.mjs +0 -2
  215. package/dist/worktree-DpLdCHga.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,449 @@
1
+ import { s as spawnDeclared, t as getExecutor } from "./exec-_UbtCQcG.mjs";
2
+ import { i as sharedBuildCache } from "./paths-DQtTgsBf.mjs";
3
+ import { n as stripAnsi, r as waitForChild, t as createLineReader } from "./process-output-Fpl8PYi8.mjs";
4
+ import { o as updateWorkspaceState, r as readWorkspaceState$1 } from "./workspace-state-Cjuigeeu.mjs";
5
+ import { bt as gitCommonDirOnDisk } from "./settings-CsJDEXgK.mjs";
6
+ import { t as git } from "./git-C3iTsJaZ.mjs";
7
+ import { v as detectIsExpo } from "./project-BZNjmW_8.mjs";
8
+ import { Zn as remoteCliInvocation } from "./budget-Bs6SxxzO.mjs";
9
+ import { a as diffFingerprintSources, v as storedSources } from "./build-cache-DmyR9Zzc.mjs";
10
+ import { i as expoBinRefusal, r as expoBinPath } from "./server-expo-DT_F_uVI.mjs";
11
+ import { existsSync, realpathSync } from "node:fs";
12
+ import { dirname, join, relative } from "node:path";
13
+ import { ambientContext } from "@stim-cli/core";
14
+ import { LAST_BUILD_KEYS, loadConfig, readWorkspaceState } from "@stim-cli/core/state";
15
+ import * as expoFingerprint from "@expo/fingerprint";
16
+ //#region src/cache/miss-reason.ts
17
+ const MISS_CHANGE_CAP = 20;
18
+ function recordedBuilds(state, platform) {
19
+ const builds = [];
20
+ for (const value of [state?.[LAST_BUILD_KEYS[platform]], state?.lastBuild]) {
21
+ const record = value;
22
+ if (record?.platform !== platform) continue;
23
+ const startedAt = typeof record.startedAt === "string" ? record.startedAt : "";
24
+ if (typeof record.fingerprint === "string" && typeof record.cacheKey === "string") builds.push({
25
+ fingerprint: record.fingerprint,
26
+ cacheKey: record.cacheKey,
27
+ startedAt
28
+ });
29
+ const carried = record.missReason?.baseline;
30
+ if (typeof carried?.fingerprint === "string" && typeof carried.cacheKey === "string") builds.push({
31
+ fingerprint: carried.fingerprint,
32
+ cacheKey: carried.cacheKey,
33
+ startedAt
34
+ });
35
+ }
36
+ return builds;
37
+ }
38
+ function projectIdentity(root) {
39
+ let real;
40
+ try {
41
+ real = realpathSync.native(root);
42
+ } catch {
43
+ return null;
44
+ }
45
+ for (let dir = real;; dir = dirname(dir)) {
46
+ if (existsSync(join(dir, ".git"))) {
47
+ const common = gitCommonDirOnDisk(dir);
48
+ return common ? `${common}\n${relative(dir, real)}` : null;
49
+ }
50
+ if (dirname(dir) === dir) return null;
51
+ }
52
+ }
53
+ function findMissBaseline(root, platform, { readState = readWorkspaceState, projectRoots = () => Object.keys(loadConfig()?.projects ?? {}), identity = projectIdentity, sourcesOf = (p, key) => storedSources(p, key, sharedBuildCache()) } = {}) {
54
+ for (const build of recordedBuilds(readState(root), platform)) {
55
+ const sources = sourcesOf(platform, build.cacheKey);
56
+ if (sources) return {
57
+ fingerprint: build.fingerprint,
58
+ cacheKey: build.cacheKey,
59
+ sources,
60
+ from: "workspace"
61
+ };
62
+ }
63
+ const project = identity(root);
64
+ if (!project) return null;
65
+ const others = [];
66
+ for (const other of projectRoots()) {
67
+ if (other === root || identity(other) !== project) continue;
68
+ others.push(...recordedBuilds(readState(other), platform));
69
+ }
70
+ for (const build of others.toSorted((a, b) => (Date.parse(b.startedAt) || 0) - (Date.parse(a.startedAt) || 0))) {
71
+ const sources = sourcesOf(platform, build.cacheKey);
72
+ if (sources) return {
73
+ fingerprint: build.fingerprint,
74
+ cacheKey: build.cacheKey,
75
+ sources,
76
+ from: "project"
77
+ };
78
+ }
79
+ return null;
80
+ }
81
+ const CATEGORY_RANK = {
82
+ "native-dependency": 0,
83
+ "app-config": 1,
84
+ "config-plugin": 2,
85
+ package: 3,
86
+ "native-dir": 4,
87
+ file: 5,
88
+ "app-asset": 6,
89
+ other: 7,
90
+ "package-scripts": 8,
91
+ autolinking: 9
92
+ };
93
+ function packageIn(path) {
94
+ return [...path.matchAll(/(?:^|\/)node_modules\/((?:@[^/]+\/)?[^/]+)/g)].at(-1)?.[1] ?? null;
95
+ }
96
+ function describeChange({ name, change, reasons }) {
97
+ const pkg = packageIn(name);
98
+ if (name === "expoConfig" || reasons.includes("expoConfig")) return {
99
+ category: "app-config",
100
+ label: "app config changed"
101
+ };
102
+ if (pkg && reasons.some((reason) => /^(expo|rncore)Autolinking(Ios|Android)?$/.test(reason))) return {
103
+ category: "native-dependency",
104
+ label: `native dependency ${change}: ${pkg}`
105
+ };
106
+ if (pkg && reasons.includes("expoConfigPlugins")) return {
107
+ category: "config-plugin",
108
+ label: `config plugin ${change}: ${pkg}`
109
+ };
110
+ if (/^(expoAutolinkingConfig|rncoreAutolinkingConfig)(:|$)/.test(name)) return {
111
+ category: "autolinking",
112
+ label: "autolinking config changed"
113
+ };
114
+ if (name.startsWith("package:")) return {
115
+ category: "package",
116
+ label: `${name.slice(8)} ${change}`
117
+ };
118
+ if (name === "packageJson:scripts") return {
119
+ category: "package-scripts",
120
+ label: "package.json scripts changed"
121
+ };
122
+ if (reasons.includes("expoConfigExternalFile")) return {
123
+ category: "app-asset",
124
+ label: `app asset ${change}: ${name}`
125
+ };
126
+ if (reasons.includes("bareNativeDir")) return {
127
+ category: "native-dir",
128
+ label: `${name}/ ${change}`
129
+ };
130
+ if (reasons.length || name.includes("/") || name.includes(".")) return {
131
+ category: "file",
132
+ label: `${name} ${change}`
133
+ };
134
+ return {
135
+ category: "other",
136
+ label: `${name} ${change}`
137
+ };
138
+ }
139
+ function rekeyPrefix(rekeyedBy) {
140
+ return rekeyedBy.length ? `${rekeyedBy.join(" and ")} changed native inputs; ` : "";
141
+ }
142
+ function missReasonFromChanges({ changes, baseline, rekeyedBy = [] }) {
143
+ const prefix = rekeyPrefix(rekeyedBy);
144
+ if (!baseline) return {
145
+ kind: "no-baseline",
146
+ summary: `${prefix}no earlier build of this project in the cache to compare with`,
147
+ changes: [],
148
+ changeCount: 0,
149
+ baseline: null,
150
+ rekeyedBy
151
+ };
152
+ if (!changes.length) return {
153
+ kind: "same-sources",
154
+ summary: `${prefix}native inputs match the last build; no cached app for this configuration or target`,
155
+ changes: [],
156
+ changeCount: 0,
157
+ baseline,
158
+ rekeyedBy
159
+ };
160
+ const described = changes.map((change, index) => ({
161
+ change,
162
+ index,
163
+ ...describeChange(change)
164
+ })).toSorted((a, b) => CATEGORY_RANK[a.category] - CATEGORY_RANK[b.category] || a.index - b.index);
165
+ const dependencyMoved = described.some((entry) => entry.category === "native-dependency");
166
+ const labels = [...new Set(described.filter((entry) => !(dependencyMoved && entry.category === "autolinking")).map((entry) => entry.label))];
167
+ const more = labels.length > 1 ? ` (+${labels.length - 1} more)` : "";
168
+ return {
169
+ kind: "changed",
170
+ summary: `${prefix}${labels[0]}${more}`,
171
+ changes: described.slice(0, MISS_CHANGE_CAP).map(({ change, category }) => ({
172
+ source: change.name,
173
+ change: change.change,
174
+ category
175
+ })),
176
+ changeCount: changes.length,
177
+ baseline,
178
+ rekeyedBy
179
+ };
180
+ }
181
+ function explainBuildMiss({ root, platform, current, rekeyedBy = [], baselineDeps, differ = expoFingerprint.diffFingerprints }) {
182
+ const baseline = findMissBaseline(root, platform, baselineDeps);
183
+ const changes = baseline ? diffFingerprintSources({
184
+ previous: baseline.sources,
185
+ previousHash: baseline.fingerprint,
186
+ current,
187
+ differ
188
+ }) : [];
189
+ return {
190
+ reason: missReasonFromChanges({
191
+ changes,
192
+ baseline: baseline ? {
193
+ fingerprint: baseline.fingerprint,
194
+ cacheKey: baseline.cacheKey,
195
+ from: baseline.from
196
+ } : null,
197
+ rekeyedBy
198
+ }),
199
+ changedNames: changes.map((change) => change.name),
200
+ previousHash: baseline?.fingerprint ?? null
201
+ };
202
+ }
203
+ function predictBuildMiss({ root, platform, current, prebuild }) {
204
+ const { reason } = explainBuildMiss({
205
+ root,
206
+ platform,
207
+ current
208
+ });
209
+ const baseline = reason.baseline && {
210
+ fingerprint: reason.baseline.fingerprint,
211
+ from: reason.baseline.from
212
+ };
213
+ if (!prebuild || !baseline) return {
214
+ ...reason,
215
+ baseline
216
+ };
217
+ const dir = platform === "ios" ? "ios/" : "android/";
218
+ return {
219
+ ...reason,
220
+ kind: "prebuild-pending",
221
+ summary: `${reason.summary} (before prebuild ${prebuild}s ${dir})`,
222
+ baseline
223
+ };
224
+ }
225
+ function skippedMissReason(summary) {
226
+ return {
227
+ kind: "cache-skipped",
228
+ summary,
229
+ changes: [],
230
+ changeCount: 0,
231
+ baseline: null,
232
+ rekeyedBy: []
233
+ };
234
+ }
235
+ function fingerprintErrorMissReason(message) {
236
+ return {
237
+ kind: "fingerprint-error",
238
+ summary: `fingerprinting failed: ${message}`,
239
+ changes: [],
240
+ changeCount: 0,
241
+ baseline: null,
242
+ rekeyedBy: []
243
+ };
244
+ }
245
+ //#endregion
246
+ //#region src/engine/prebuild.ts
247
+ const PREBUILD_ERROR = "STIM_PREBUILD_FAILED";
248
+ const LAST_LINES = 20;
249
+ function nativeDirName(platform) {
250
+ return platform === "android" ? "android" : "ios";
251
+ }
252
+ function nativeDir(root, platform) {
253
+ return join(root, nativeDirName(platform));
254
+ }
255
+ function nativeDirInFingerprint(sources, platform) {
256
+ const dir = nativeDirName(platform);
257
+ return sources.some((source) => source.type === "dir" && source.filePath === dir && source.hash != null);
258
+ }
259
+ /**
260
+ * @expo/fingerprint leaves a native directory out of the hash when git ignores it (CNG), so the cache
261
+ * key only covers that directory when this workspace's recorded prebuild ran on the same fingerprint.
262
+ */
263
+ function prebuildAction({ isExpo, nativeDirExists, nativeDirFingerprinted, nativeDirTracked, generatedFrom, fingerprint }) {
264
+ if (!isExpo) return "none";
265
+ if (!nativeDirExists) return "generate";
266
+ if (nativeDirFingerprinted || generatedFrom === fingerprint) return "none";
267
+ return nativeDirTracked ? "refuse" : "regenerate";
268
+ }
269
+ function prebuildRecord(state) {
270
+ const record = state?.prebuild;
271
+ return record && typeof record === "object" ? record : {};
272
+ }
273
+ function gitTracksNativeDir(root, platform) {
274
+ try {
275
+ return git(root, [
276
+ "ls-files",
277
+ "--",
278
+ nativeDirName(platform)
279
+ ], { env: {
280
+ LC_ALL: "C",
281
+ LANGUAGE: "C"
282
+ } }).trim() !== "";
283
+ } catch (error) {
284
+ if (error?.code === "ENOENT") return false;
285
+ return !/not a git repository \(or any (of the parent directories|parent up to mount point)/.test(String(error?.message));
286
+ }
287
+ }
288
+ function planPrebuild(root, platform, { isExpo, fingerprint, sources }) {
289
+ const nativeDirExists = existsSync(nativeDir(root, platform));
290
+ const fingerprinted = nativeDirInFingerprint(sources, platform);
291
+ const generatedFrom = prebuildRecord(readWorkspaceState$1(root))[platform];
292
+ return prebuildAction({
293
+ isExpo,
294
+ nativeDirExists,
295
+ nativeDirFingerprinted: fingerprinted,
296
+ nativeDirTracked: nativeDirExists && !fingerprinted && gitTracksNativeDir(root, platform),
297
+ generatedFrom: typeof generatedFrom === "string" ? generatedFrom : null,
298
+ fingerprint
299
+ });
300
+ }
301
+ function recordPrebuild(root, platform, fingerprint) {
302
+ updateWorkspaceState(root, (state) => ({
303
+ ...state,
304
+ prebuild: {
305
+ ...prebuildRecord(state),
306
+ [platform]: fingerprint
307
+ }
308
+ }));
309
+ }
310
+ function staleNativeDirRefusal(platform) {
311
+ const dir = nativeDirName(platform);
312
+ return {
313
+ code: PREBUILD_ERROR,
314
+ message: `The fingerprint leaves ${dir}/ out of the cache key, and Stim cannot show that ${dir}/ was generated from the current app config. Git tracks files in it, or could not say whether it does, so Stim will not regenerate it with \`expo prebuild --clean\`.`,
315
+ remedy: `Stop excluding ${dir}/ from the fingerprint (check .fingerprintignore) so the cache key covers its files, or add ${dir}/ to .gitignore and untrack it so Stim regenerates it from the app config.`
316
+ };
317
+ }
318
+ function prebuildRefusal({ isExpo, platform, nativeDirExists }) {
319
+ if (nativeDirExists || isExpo) return null;
320
+ const dir = nativeDirName(platform);
321
+ return {
322
+ code: PREBUILD_ERROR,
323
+ message: `This project has no ${dir}/ directory and is not an Expo (CNG) project, so Stim cannot generate one.`,
324
+ remedy: `Check out or generate the native project (\`npx @react-native-community/cli init\` produced one originally), or add \`expo\` to the project so \`expo prebuild\` can create ${dir}/.`
325
+ };
326
+ }
327
+ function prebuildFailure(logWriter, result) {
328
+ logWriter?.write?.({
329
+ src: "build",
330
+ level: "error",
331
+ msg: result.reason || "Expo prebuild failed.",
332
+ event: "prebuild_failed"
333
+ });
334
+ return result;
335
+ }
336
+ async function runPrebuild(root, platform, logWriter, { spawnFn = null, now = Date.now, isExpo = null, clean = false } = {}) {
337
+ const dirExists = existsSync(nativeDir(root, platform));
338
+ const refusal = prebuildRefusal({
339
+ isExpo: isExpo === null ? detectIsExpo(root) : isExpo,
340
+ platform,
341
+ nativeDirExists: dirExists
342
+ });
343
+ if (refusal) return prebuildFailure(logWriter, {
344
+ failed: true,
345
+ code: refusal.code,
346
+ reason: refusal.message,
347
+ remedy: refusal.remedy,
348
+ error: refusal,
349
+ lastLines: []
350
+ });
351
+ const bin = expoBinPath(root);
352
+ if (!bin) {
353
+ const binRefusal = expoBinRefusal(root, "prebuild");
354
+ return prebuildFailure(logWriter, {
355
+ failed: true,
356
+ code: PREBUILD_ERROR,
357
+ reason: binRefusal.message,
358
+ remedy: binRefusal.remedy,
359
+ lastLines: []
360
+ });
361
+ }
362
+ const spawn = spawnFn || ((cmd, args, opts) => getExecutor().spawn(cmd, args, opts));
363
+ const startedAt = now();
364
+ const tail = [];
365
+ const push = (line) => {
366
+ const msg = stripAnsi(String(line)).trimEnd();
367
+ if (!msg.trim()) return;
368
+ tail.push(msg);
369
+ if (tail.length > LAST_LINES) tail.shift();
370
+ logWriter?.write?.({
371
+ src: "build",
372
+ level: "debug",
373
+ msg,
374
+ raw: true,
375
+ event: "prebuild"
376
+ });
377
+ };
378
+ let child;
379
+ try {
380
+ const invocation = remoteCliInvocation(bin, [
381
+ "prebuild",
382
+ "-p",
383
+ platform,
384
+ "--no-install",
385
+ ...clean ? ["--clean"] : []
386
+ ], "expo");
387
+ child = spawnDeclared(ambientContext(), () => spawn(invocation.file, invocation.args, {
388
+ cwd: root,
389
+ stdio: [
390
+ "ignore",
391
+ "pipe",
392
+ "pipe"
393
+ ],
394
+ env: {
395
+ ...ambientContext()?.env ?? process.env,
396
+ FORCE_COLOR: "0",
397
+ CI: "1"
398
+ }
399
+ }));
400
+ } catch (err) {
401
+ return prebuildFailure(logWriter, {
402
+ failed: true,
403
+ code: PREBUILD_ERROR,
404
+ reason: `Could not run \`expo prebuild\`: ${err?.message || err}`,
405
+ lastLines: []
406
+ });
407
+ }
408
+ const outReader = createLineReader(push);
409
+ const errReader = createLineReader(push);
410
+ child.stdout?.setEncoding?.("utf-8");
411
+ child.stderr?.setEncoding?.("utf-8");
412
+ child.stdout?.on("data", (chunk) => outReader.push(chunk));
413
+ child.stderr?.on("data", (chunk) => errReader.push(chunk));
414
+ const result = await waitForChild(child);
415
+ outReader.flush();
416
+ errReader.flush();
417
+ const durationMs = now() - startedAt;
418
+ if (result.error) return prebuildFailure(logWriter, {
419
+ failed: true,
420
+ code: PREBUILD_ERROR,
421
+ reason: `Could not run \`expo prebuild\`: ${result.error?.message || result.error}`,
422
+ lastLines: tail.slice(),
423
+ durationMs
424
+ });
425
+ if (result.code !== 0) {
426
+ const how = result.signal ? `signal ${result.signal}` : `exit code ${result.code}`;
427
+ return prebuildFailure(logWriter, {
428
+ failed: true,
429
+ code: PREBUILD_ERROR,
430
+ reason: `\`expo prebuild -p ${platform}\` failed (${how}).`,
431
+ lastLines: tail.slice(),
432
+ durationMs
433
+ });
434
+ }
435
+ if (!existsSync(nativeDir(root, platform))) return prebuildFailure(logWriter, {
436
+ failed: true,
437
+ code: PREBUILD_ERROR,
438
+ reason: `\`expo prebuild -p ${platform}\` succeeded but did not create ${nativeDirName(platform)}/.`,
439
+ lastLines: tail.slice(),
440
+ durationMs
441
+ });
442
+ return {
443
+ ok: true,
444
+ durationMs,
445
+ nativeDir: nativeDir(root, platform)
446
+ };
447
+ }
448
+ //#endregion
449
+ export { explainBuildMiss as a, skippedMissReason as c, staleNativeDirRefusal as i, recordPrebuild as n, fingerprintErrorMissReason as o, runPrebuild as r, predictBuildMiss as s, planPrebuild as t };
@@ -1,10 +1,12 @@
1
- import { B as deviceSlotKey, H as parseDeviceSlotKey, _ as loadConfig$1, g as isPathPrefix, k as process_identity_exports, l as findEnclosingWorktreeRoot, p as getProject } from "./config-BYDxlMY3.mjs";
2
- import { $ as settingValueAt, Dt as repoRoot, G as resolveIosProjectDir, U as resolveAndroidLayout, rt as webSettings } from "./settings-B717odTD.mjs";
3
- import { E as workspaceStateFile, a as updateWorkspaceState, o as withWorkspaceStateLock, r as readWorkspaceState$1, t as clearWorkspaceStateKey, v as supervisorPidFile } from "./workspace-state-DJt_MMvf.mjs";
1
+ import { p as process_identity_exports } from "./exec-_UbtCQcG.mjs";
2
+ import { c as supervisorPidFile, g as workspaceStateFile$1 } from "./paths-DQtTgsBf.mjs";
3
+ import { H as deviceSlotKey, W as parseDeviceSlotKey, _ as loadConfig$1, g as isPathPrefix, l as findEnclosingWorktreeRoot, p as getProject } from "./config-CYcBF478.mjs";
4
+ import { c as withWorkspaceStateLock, o as updateWorkspaceState, r as readWorkspaceState$1, t as clearWorkspaceStateKey } from "./workspace-state-Cjuigeeu.mjs";
5
+ import { Ft as repoRoot, K as resolveIosProjectDir, W as resolveAndroidLayout, at as webSettings, tt as settingValueAt } from "./settings-CsJDEXgK.mjs";
4
6
  import { existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, rmSync, statSync, writeFileSync } from "node:fs";
5
7
  import { basename, dirname, isAbsolute, join, relative, resolve } from "node:path";
6
- import { basename as basename$1, dirname as dirname$1, join as join$1, resolve as resolve$1 } from "path";
7
8
  import { projectRootDirectories } from "@stim-cli/core/state";
9
+ import { basename as basename$1, dirname as dirname$1, join as join$1, resolve as resolve$1 } from "path";
8
10
  import { existsSync as existsSync$1, readFileSync as readFileSync$1, realpathSync as realpathSync$1 } from "fs";
9
11
  import { DOMParser } from "@xmldom/xmldom";
10
12
  //#region src/supervisor/state.ts
@@ -133,7 +135,7 @@ function clearExpoMetroTunnel(root) {
133
135
  });
134
136
  }
135
137
  function clearManagedMetroTunnel(root, expected) {
136
- if (!existsSync(workspaceStateFile(root))) return true;
138
+ if (!existsSync(workspaceStateFile$1(root))) return true;
137
139
  return clearWorkspaceStateKey(root, "metroTunnel", (value) => {
138
140
  if (typeof value !== "object" || value === null) return false;
139
141
  const record = value;
@@ -306,8 +308,8 @@ const nativeAndroidIntegration = {
306
308
  application: true,
307
309
  platforms: () => ["android"],
308
310
  validate: (operation) => operation === "android" ? null : void 0,
309
- android: async () => (await import("./native-android-D5qc3-_v.mjs")).nativeAndroidProject(root),
310
- doctor: async () => (await import("./native-android-D5qc3-_v.mjs")).nativeAndroidDoctor(root)
311
+ android: async () => (await import("./native-android-JACyjTZs.mjs")).nativeAndroidProject(root),
312
+ doctor: async () => (await import("./native-android-JACyjTZs.mjs")).nativeAndroidDoctor(root)
311
313
  };
312
314
  }
313
315
  };
@@ -735,8 +737,8 @@ const nativeXcodeProjectIntegration = {
735
737
  application: problem === null,
736
738
  platforms: () => problem ? [] : ["ios"],
737
739
  validate: (operation) => operation === "ios" ? problem : void 0,
738
- ios: async () => (await import("./native-xcode-ios-Bbf30Gm0.mjs")).nativeXcodeIosProject(root),
739
- doctor: async () => (await import("./native-xcode-ios-Bbf30Gm0.mjs")).nativeXcodeDoctor(root)
740
+ ios: async () => (await import("./native-xcode-ios-CXX39F7o.mjs")).nativeXcodeIosProject(root),
741
+ doctor: async () => (await import("./native-xcode-ios-CXX39F7o.mjs")).nativeXcodeDoctor(root)
740
742
  };
741
743
  }
742
744
  };
@@ -941,7 +943,7 @@ function createProjectRegistry(integrations) {
941
943
  //#region src/integrations/projects.ts
942
944
  const expo = {
943
945
  mode: MODE_EXPO,
944
- loadDevServer: async () => (await import("./server-expo-Bigriskl.mjs")).startExpoServer,
946
+ loadDevServer: async () => (await import("./server-expo-C-90EhcG.mjs")).startExpoServer,
945
947
  platforms(root) {
946
948
  const appJson = readAppJson(root);
947
949
  const config = appJson?.expo ?? appJson;
@@ -961,7 +963,7 @@ const expo = {
961
963
  };
962
964
  const reactNative = {
963
965
  mode: MODE_BARE,
964
- loadDevServer: async () => (await import("./server-bare-R2m_gsH8.mjs")).startBareServer,
966
+ loadDevServer: async () => (await import("./server-bare-CxTrvDg8.mjs")).startBareServer,
965
967
  platforms(root, { context, settings }) {
966
968
  if (!declaresAppDependency(readPackageJson(root))) return [];
967
969
  const platforms = [];
@@ -991,9 +993,9 @@ const projectRegistry = createProjectRegistry([
991
993
  ownedRoots: problem === null ? [join(root, "ios"), join(root, "android")] : [],
992
994
  platforms: (resolved) => nativeProjectIntegration(root).platforms(root, resolved),
993
995
  validate: (operation) => operation === "ios" || operation === "android" || operation === "dev-server" ? problem : void 0,
994
- ios: async (settings) => (await import("./react-native-ios-Dhq_eiYQ.mjs")).reactNativeIosProject(root, settings),
995
- android: async (resolved) => (await import("./react-native-android-CM1XRDwv.mjs")).reactNativeAndroidProject(root, resolved),
996
- doctor: async () => (await import("./react-native-doctor-CfRnFfjs.mjs")).reactNativeProjectDoctor(root)
996
+ ios: async (settings) => (await import("./react-native-ios-Bhq1rJeV.mjs")).reactNativeIosProject(root, settings),
997
+ android: async (resolved) => (await import("./react-native-android-DuzH0cn3.mjs")).reactNativeAndroidProject(root, resolved),
998
+ doctor: async () => (await import("./react-native-doctor-CQpuIMso.mjs")).reactNativeProjectDoctor(root)
997
999
  };
998
1000
  }
999
1001
  },
@@ -1007,14 +1009,14 @@ const projectRegistry = createProjectRegistry([
1007
1009
  application: true,
1008
1010
  platforms: ({ settings }) => settingValueAt(settings, "macos.product") && settingValueAt(settings, "macos.infoPlist") ? ["macos"] : [],
1009
1011
  validate: (operation) => operation === "macos" ? null : void 0,
1010
- macos: async () => (await import("./swiftpm-macos-DRNVJWlb.mjs")).swiftpmMacosProject(root),
1012
+ macos: async () => (await import("./swiftpm-macos-p8WZbxKU.mjs")).swiftpmMacosProject(root),
1011
1013
  doctor: async () => {
1012
- const { macosToolchain } = await import("./toolchain-BFkAcstd.mjs");
1014
+ const { macosToolchain, macosToolchainAsync } = await import("./toolchain-DhKwp9iI.mjs");
1013
1015
  return {
1014
1016
  inspect: () => [],
1015
- offloadTargets: ({ options: { host = process.platform, platform } }) => host === "darwin" && platform === void 0 ? async () => [{
1017
+ offloadTargets: ({ options: { host = process.platform, platform, operation } }) => host === "darwin" && platform === void 0 ? async () => [{
1016
1018
  platform: "macos",
1017
- local: macosToolchain()
1019
+ local: operation ? await macosToolchainAsync() : macosToolchain()
1018
1020
  }] : null
1019
1021
  };
1020
1022
  }
@@ -1029,7 +1031,7 @@ const projectRegistry = createProjectRegistry([
1029
1031
  application: false,
1030
1032
  platforms: ({ settings }) => webSettings(settings).url !== null ? ["web"] : [],
1031
1033
  validate: (operation) => operation === "web" ? null : void 0,
1032
- web: async () => (await import("./browser-web-CA-F1GQo.mjs")).browserWebProject(root)
1034
+ web: async () => (await import("./browser-web-QQzVjz3O.mjs")).browserWebProject(root)
1033
1035
  };
1034
1036
  }
1035
1037
  },
@@ -1062,7 +1064,7 @@ function literalPlatforms(text) {
1062
1064
  }
1063
1065
  //#endregion
1064
1066
  //#region src/workspace/project.ts
1065
- const findProjectRoot = projectRegistry.findProjectRoot;
1067
+ const findProjectRoot$1 = projectRegistry.findProjectRoot;
1066
1068
  const projectProblem = projectRegistry.projectProblem;
1067
1069
  const isMobileProject = projectRegistry.isMobileProject;
1068
1070
  function projectShortcut(path, proj) {
@@ -1084,27 +1086,28 @@ const NO_PROJECT_REFUSAL = {
1084
1086
  message: "No supported app project was found from this directory.",
1085
1087
  remedy: "Run this from the directory of a supported app."
1086
1088
  };
1087
- function findServerWorkspace(startDir, registry = projectRegistry) {
1089
+ function startServerWorkspace(startDir, registry) {
1088
1090
  const nearest = registry.findProjectRoot(startDir);
1089
- if (!nearest) return null;
1090
- if (registry.keepsWorkspace(nearest)) return {
1091
- root: nearest,
1092
- from: null
1093
- };
1094
- if (Object.keys(getProject(nearest)?.ports ?? {}).length) return {
1091
+ if (!nearest) return { found: null };
1092
+ if (registry.keepsWorkspace(nearest)) return { found: {
1095
1093
  root: nearest,
1096
1094
  from: null
1097
- };
1098
- const top = repoRoot(nearest);
1099
- if (!top) return {
1095
+ } };
1096
+ if (Object.keys(getProject(nearest)?.ports ?? {}).length) return { found: {
1100
1097
  root: nearest,
1101
1098
  from: null
1102
- };
1099
+ } };
1100
+ return { nearest };
1101
+ }
1102
+ function sameRepositoryApps(nearest, top, registry) {
1103
+ const worktree = expandedRealpath(top);
1104
+ return Object.keys(loadConfig$1()?.projects ?? {}).filter((path) => path !== nearest && isPathPrefix(worktree, expandedRealpath(path)) && registry.isMobileProject(path));
1105
+ }
1106
+ function chooseServerWorkspace(nearest, top, candidates, owners) {
1103
1107
  const worktree = expandedRealpath(top);
1104
- const apps = Object.keys(loadConfig$1()?.projects ?? {}).filter((path) => {
1105
- if (path === nearest || !isPathPrefix(worktree, expandedRealpath(path)) || !registry.isMobileProject(path)) return false;
1106
- const owner = repoRoot(path);
1107
- return owner !== null && expandedRealpath(owner) === worktree;
1108
+ const apps = candidates.filter((_, index) => {
1109
+ const owner = owners[index];
1110
+ return owner !== null && owner !== void 0 && expandedRealpath(owner) === worktree;
1108
1111
  });
1109
1112
  return apps.length === 1 ? {
1110
1113
  root: apps[0],
@@ -1114,9 +1117,34 @@ function findServerWorkspace(startDir, registry = projectRegistry) {
1114
1117
  from: null
1115
1118
  };
1116
1119
  }
1120
+ function findServerWorkspace(startDir, registry = projectRegistry) {
1121
+ const start = startServerWorkspace(startDir, registry);
1122
+ if ("found" in start) return start.found;
1123
+ const top = repoRoot(start.nearest);
1124
+ if (!top) return {
1125
+ root: start.nearest,
1126
+ from: null
1127
+ };
1128
+ const candidates = sameRepositoryApps(start.nearest, top, registry);
1129
+ return chooseServerWorkspace(start.nearest, top, candidates, candidates.map(repoRoot));
1130
+ }
1131
+ /** `findCommandWorkspace` with the repository roots read by `repoRootOf`, so no Git call blocks the event loop. */
1132
+ async function findCommandWorkspaceAsync(startDir, repoRootOf, note) {
1133
+ const start = startServerWorkspace(startDir, projectRegistry);
1134
+ if ("found" in start) return start.found?.root ?? null;
1135
+ const top = await repoRootOf(start.nearest);
1136
+ if (!top) return start.nearest;
1137
+ const candidates = sameRepositoryApps(start.nearest, top, projectRegistry);
1138
+ const workspace = chooseServerWorkspace(start.nearest, top, candidates, await Promise.all(candidates.map(repoRootOf)));
1139
+ if (workspace.from) noteWorkspace(workspace, note);
1140
+ return workspace.root;
1141
+ }
1142
+ function noteWorkspace(workspace, note) {
1143
+ note(`Using the Stim workspace ${workspace.root}: ${workspace.from} is not a React Native or Expo app.`);
1144
+ }
1117
1145
  function findCommandWorkspace(startDir, note = (line) => console.error(line)) {
1118
1146
  const workspace = findServerWorkspace(startDir);
1119
- if (workspace?.from) note(`Using the Stim workspace ${workspace.root}: ${workspace.from} is not a React Native or Expo app.`);
1147
+ if (workspace?.from) noteWorkspace(workspace, note);
1120
1148
  return workspace?.root ?? null;
1121
1149
  }
1122
1150
  function expandedRealpath(path) {
@@ -1127,4 +1155,4 @@ function expandedRealpath(path) {
1127
1155
  }
1128
1156
  }
1129
1157
  //#endregion
1130
- export { clearWorkspaceSupervisor as A, MODE_BARE as C, clearManagedMetroTunnel as D, clearExpoMetroTunnel as E, readWorkspaceLaunches as F, workspaceDevServerMode as I, writePidFile as L, readPidFile as M, readRemoteSession as N, clearRemoteSession as O, readRemoteSessionId as P, writeWorkspaceLaunch as R, resolvePackageJson as S, MODE_EXPO as T, detectIsExpo as _, isMobileProject as a, readAppConfigText as b, projectShortcut as c, projectRegistry as d, NativeXcodeError as f, appProjectProblem as g, selectNativeXcodeProject as h, findServerWorkspace as i, readMetroTunnel as j, clearWorkspaceLaunches as k, detectPlatforms as l, pbxString as m, findCommandWorkspace as n, ownedDeviceLabel as o, pbxReferences as p, findProjectRoot as r, projectProblem as s, NO_PROJECT_REFUSAL as t, nativeProjectIntegration as u, detectTutorial as v, MODE_COMMAND as w, readAppJson as x, isPackageResolvable as y };
1158
+ export { clearWorkspaceLaunches as A, resolvePackageJson as C, clearExpoMetroTunnel as D, MODE_EXPO as E, readRemoteSessionId as F, readWorkspaceLaunches as I, workspaceDevServerMode as L, readMetroTunnel as M, readPidFile as N, clearManagedMetroTunnel as O, readRemoteSession as P, writePidFile as R, readAppJson as S, MODE_COMMAND as T, appProjectProblem as _, findServerWorkspace as a, isPackageResolvable as b, projectProblem as c, nativeProjectIntegration as d, projectRegistry as f, selectNativeXcodeProject as g, pbxString as h, findProjectRoot$1 as i, clearWorkspaceSupervisor as j, clearRemoteSession as k, projectShortcut as l, pbxReferences as m, findCommandWorkspace as n, isMobileProject as o, NativeXcodeError as p, findCommandWorkspaceAsync as r, ownedDeviceLabel as s, NO_PROJECT_REFUSAL as t, detectPlatforms as u, detectIsExpo as v, MODE_BARE as w, readAppConfigText as x, detectTutorial as y, writeWorkspaceLaunch as z };
@@ -1,5 +1,5 @@
1
- import { t as getExecutor } from "./exec-DqKo9GKJ.mjs";
2
- import { n as gitAsync, r as gitQuiet } from "./git-DDfFzkMm.mjs";
1
+ import { t as getExecutor } from "./exec-_UbtCQcG.mjs";
2
+ import { n as gitAsync, r as gitQuiet } from "./git-C3iTsJaZ.mjs";
3
3
  //#region src/workspace/pull-request.ts
4
4
  const GH_TIMEOUT_MS = 2e4;
5
5
  const GH_ENV = {