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
@@ -1,9 +1,9 @@
1
- import { d as getConfigDir, j as ownership_claim_exports, k as process_identity_exports } from "./config-BYDxlMY3.mjs";
2
- import { t as getExecutor } from "./exec-DqKo9GKJ.mjs";
1
+ import { f as ownership_claim_exports, l as isTermination, p as process_identity_exports, t as getExecutor, u as operationState } from "./exec-_UbtCQcG.mjs";
2
+ import { d as getConfigDir } from "./config-CYcBF478.mjs";
3
3
  import { n as stripAnsi, r as waitForChild, t as createLineReader } from "./process-output-Fpl8PYi8.mjs";
4
4
  import { join } from "node:path";
5
5
  //#region src/engine/simslim.ts
6
- async function reconcileSimSlim({ udid, profile, previouslyManaged = false, out = () => {}, spawn, timeoutMs = 72e4, cleanupMs = 1e4 }) {
6
+ async function reconcileSimSlim({ udid, profile, previouslyManaged = false, out = () => {}, spawn, timeoutMs = 72e4, cleanupMs = 1e4, context }) {
7
7
  if (!profile && !previouslyManaged) return {
8
8
  managed: false,
9
9
  profile: null
@@ -53,8 +53,12 @@ async function reconcileSimSlim({ udid, profile, previouslyManaged = false, out
53
53
  cancellation ??= signal;
54
54
  stopGroup();
55
55
  };
56
- const onInterrupt = () => cancel("SIGINT");
57
- const onTerminate = () => cancel("SIGTERM");
56
+ const state = operationState(context);
57
+ const onAbort = () => {
58
+ state.handled = true;
59
+ state.draining = true;
60
+ cancel(isTermination(context?.signal.reason) ? "SIGTERM" : "SIGINT");
61
+ };
58
62
  const groupAlive = () => child?.pid !== void 0 && (0, ownership_claim_exports.processGroupAlive)(child.pid);
59
63
  const settled = () => result !== void 0 && !groupAlive();
60
64
  const waitUntil = async (deadline, cancellable = false) => {
@@ -64,10 +68,10 @@ async function reconcileSimSlim({ udid, profile, previouslyManaged = false, out
64
68
  }
65
69
  return settled();
66
70
  };
67
- process.on("SIGINT", onInterrupt);
68
- process.on("SIGTERM", onTerminate);
69
- process.on("exit", stopGroup);
71
+ context?.signal.addEventListener("abort", onAbort);
72
+ state.exitCleanups.add(stopGroup);
70
73
  try {
74
+ if (context?.signal.aborted) onAbort();
71
75
  (0, ownership_claim_exports.markClaimChildPending)(claim);
72
76
  try {
73
77
  child = (spawn ?? ((cmd, childArgs, opts) => getExecutor().spawn(cmd, childArgs, opts)))("simslim", args, {
@@ -115,10 +119,8 @@ async function reconcileSimSlim({ udid, profile, previouslyManaged = false, out
115
119
  child.stderr?.destroy?.();
116
120
  child.unref();
117
121
  }
118
- process.off("SIGINT", onInterrupt);
119
- process.off("SIGTERM", onTerminate);
120
- process.off("exit", stopGroup);
121
- if (cancellation) process.exit(cancellation === "SIGINT" ? 130 : 143);
122
+ context?.signal.removeEventListener("abort", onAbort);
123
+ state.exitCleanups.delete(stopGroup);
122
124
  }
123
125
  stdout.flush();
124
126
  stderr.flush();
@@ -1,9 +1,9 @@
1
- import { H as parseDeviceSlotKey, W as projectDeviceSlots, p as getProject } from "./config-BYDxlMY3.mjs";
2
- import { n as fileLeaseIo } from "./device-lease-BX1sJQ2E.mjs";
3
- import { r as readWorkspaceState$1 } from "./workspace-state-DJt_MMvf.mjs";
4
- import { E as getAvdNameForSerial, O as listAdbDevices } from "./android-Mz_Inn3w.mjs";
5
- import { d as listAllIosSims } from "./ios-RkW4pnQf.mjs";
6
- import { p as deviceShellArg } from "./app-install-BIKtMfPq.mjs";
1
+ import { K as projectDeviceSlots, W as parseDeviceSlotKey, p as getProject } from "./config-CYcBF478.mjs";
2
+ import { r as readWorkspaceState$1 } from "./workspace-state-Cjuigeeu.mjs";
3
+ import { gn as deviceShellArg } from "./budget-Bs6SxxzO.mjs";
4
+ import { y as fileLeaseIo } from "./activity-BzVfHSrY.mjs";
5
+ import { A as listAdbDevicesAsync, D as getAvdNameForSerialAsync } from "./android-DUYkNF4u.mjs";
6
+ import { f as listAllIosSimsAsync } from "./ios-CpByZy12.mjs";
7
7
  import { hostedNativeRecords } from "@stim-cli/core/state";
8
8
  //#region src/engine/slot-launch.ts
9
9
  function launchSlotScope(root, slot = "default") {
@@ -19,31 +19,26 @@ function launchSlotScope(root, slot = "default") {
19
19
  const DEVICE_LISTING_TIMEOUT_MS = 5e3;
20
20
  function ownedDeviceRunning(platform) {
21
21
  let listing = null;
22
- const list = () => {
22
+ const list = async () => {
23
23
  if (platform === "android") {
24
- const { emulators, unhealthy } = listAdbDevices({ timeoutMs: DEVICE_LISTING_TIMEOUT_MS });
24
+ const { emulators, unhealthy } = await listAdbDevicesAsync({ timeoutMs: DEVICE_LISTING_TIMEOUT_MS });
25
25
  const names = [];
26
26
  for (const entry of [...emulators, ...unhealthy.filter((candidate) => candidate.kind === "emulator")]) {
27
- const name = getAvdNameForSerial(entry.serial, { timeoutMs: DEVICE_LISTING_TIMEOUT_MS });
27
+ const name = await getAvdNameForSerialAsync(entry.serial, { timeoutMs: DEVICE_LISTING_TIMEOUT_MS });
28
28
  if (name === null) return () => true;
29
29
  names.push(name);
30
30
  }
31
31
  return (device) => typeof device.avdName === "string" && names.includes(device.avdName);
32
32
  }
33
- const booted = new Set(listAllIosSims({ timeoutMs: DEVICE_LISTING_TIMEOUT_MS }).filter((sim) => sim.state === "Booted").map((sim) => sim.udid));
33
+ const booted = new Set((await listAllIosSimsAsync({ timeoutMs: DEVICE_LISTING_TIMEOUT_MS })).filter((sim) => sim.state === "Booted").map((sim) => sim.udid));
34
34
  return (device) => typeof device.deviceUdid === "string" && booted.has(device.deviceUdid);
35
35
  };
36
- return (device) => {
37
- try {
38
- listing ??= list();
39
- return listing(device);
40
- } catch {
41
- listing = () => true;
42
- return true;
43
- }
36
+ return async (device) => {
37
+ listing ??= list().catch(() => () => true);
38
+ return (await listing)(device);
44
39
  };
45
40
  }
46
- function siblingPlatformSlots(root, platform, slot = "default", { deviceRunning = ownedDeviceRunning(platform) } = {}) {
41
+ async function siblingPlatformSlots(root, platform, slot = "default", { deviceRunning = ownedDeviceRunning(platform) } = {}) {
47
42
  const slots = /* @__PURE__ */ new Set();
48
43
  const state = readWorkspaceState$1(root);
49
44
  for (const hosted of Object.keys(hostedNativeRecords(state, platform))) slots.add(hosted);
@@ -56,7 +51,7 @@ function siblingPlatformSlots(root, platform, slot = "default", { deviceRunning
56
51
  }
57
52
  for (const { slot: other, platforms } of projectDeviceSlots(getProject(root))) {
58
53
  const device = platforms[platform];
59
- if (other !== slot && !slots.has(other) && device && deviceRunning(device)) slots.add(other);
54
+ if (other !== slot && !slots.has(other) && device && await deviceRunning(device)) slots.add(other);
60
55
  }
61
56
  slots.delete(slot);
62
57
  return [...slots].toSorted();
@@ -2,7 +2,6 @@ import { basename, dirname, join } from "node:path";
2
2
  import { fileURLToPath } from "node:url";
3
3
  //#region src/spawn-entry.ts
4
4
  const DEV_ENTRIES = {
5
- "api-run": "./api-run.ts",
6
5
  "supervisor-run": "./supervisor/run.ts",
7
6
  "collector-run": "./collector/run.ts",
8
7
  "web-run": "./web/run.ts",
@@ -0,0 +1,183 @@
1
+ import { d as withDrainingCancellation, t as getExecutor } from "./exec-_UbtCQcG.mjs";
2
+ import { en as throwIfCancelled } from "./settings-CsJDEXgK.mjs";
3
+ import { d as runCancellationSignal } from "./native-run-DY_RLx3C.mjs";
4
+ import { existsSync, lstatSync, promises, readdirSync, realpathSync, statSync } from "node:fs";
5
+ import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
6
+ import { validMacosResourceDestination } from "@stim-cli/core";
7
+ //#region src/macos/stage.ts
8
+ async function validateInfoPlist(context, root, product, infoPlist) {
9
+ const source = resolve(root, infoPlist);
10
+ const inside = relative(realpathSync(root), realpathSync(source));
11
+ if (!lstatSync(source).isFile() || inside === ".." || inside.startsWith(`..${sep}`) || isAbsolute(inside)) throw new Error("macos.infoPlist must be a regular file inside the project, not a symbolic link. See stim guide macos.");
12
+ const plist = JSON.parse(await tool(context, "plutil", [
13
+ "-convert",
14
+ "json",
15
+ "-o",
16
+ "-",
17
+ source
18
+ ], { timeoutMs: 1e4 }));
19
+ if (typeof plist.CFBundleIdentifier !== "string" || plist.CFBundleExecutable !== product) throw new Error("macos.infoPlist must name a CFBundleIdentifier and the selected product as CFBundleExecutable.");
20
+ if (plist.CFBundleURLTypes || plist.SUFeedURL) throw new Error("Use a development Info.plist without shared URL schemes or an update feed.");
21
+ if (plist.LSMinimumSystemVersion !== void 0 && typeof plist.LSMinimumSystemVersion !== "string") throw new Error("macos.infoPlist LSMinimumSystemVersion must be a string. See stim guide macos.");
22
+ return {
23
+ bundleId: plist.CFBundleIdentifier,
24
+ minimumSystemVersion: plist.LSMinimumSystemVersion
25
+ };
26
+ }
27
+ async function setBundleName(context, plistPath, name) {
28
+ for (const key of ["CFBundleDisplayName", "CFBundleName"]) await tool(context, "plutil", [
29
+ "-replace",
30
+ key,
31
+ "-string",
32
+ name,
33
+ plistPath
34
+ ], { timeoutMs: 1e4 });
35
+ }
36
+ function resourceError(key, entry, reason) {
37
+ throw new Error(`${key} entry ${JSON.stringify(entry)}: ${reason}. See stim guide macos.`);
38
+ }
39
+ function containsSymlink(dir) {
40
+ return readdirSync(dir, { withFileTypes: true }).some((entry) => entry.isSymbolicLink() || entry.isDirectory() && containsSymlink(join(dir, entry.name)));
41
+ }
42
+ function overlaps(a, b) {
43
+ a = a.normalize("NFC").toLowerCase();
44
+ b = b.normalize("NFC").toLowerCase();
45
+ return a === b || a.startsWith(`${b}/`) || b.startsWith(`${a}/`);
46
+ }
47
+ function resolveBundleExtras(root, repository, resources = {}, assetCatalog) {
48
+ const boundary = realpathSync(repository);
49
+ const sourcePath = (key, entry) => {
50
+ if (typeof entry !== "string" || !entry || isAbsolute(entry) || entry.includes("\0")) resourceError(key, entry, "source must be a non-empty relative path");
51
+ let source;
52
+ try {
53
+ source = realpathSync(resolve(root, entry));
54
+ } catch {
55
+ resourceError(key, entry, "source does not exist");
56
+ }
57
+ const path = relative(boundary, source);
58
+ if (path === ".." || path.startsWith(`..${sep}`) || isAbsolute(path)) resourceError(key, entry, "source leaves the repository");
59
+ if (path === "") resourceError(key, entry, "source is the repository root");
60
+ const stat = statSync(source);
61
+ if (!stat.isFile() && !stat.isDirectory()) resourceError(key, entry, "source must be a regular file or directory");
62
+ if (stat.isDirectory() && containsSymlink(source)) resourceError(key, entry, "source directory contains a symbolic link");
63
+ return source;
64
+ };
65
+ let catalog;
66
+ if (assetCatalog !== void 0 && assetCatalog !== null) {
67
+ catalog = sourcePath("macos.assetCatalog", assetCatalog);
68
+ if (!catalog.endsWith(".xcassets") || !statSync(catalog).isDirectory()) resourceError("macos.assetCatalog", assetCatalog, "catalog must be a .xcassets directory");
69
+ }
70
+ if (!resources || typeof resources !== "object" || Array.isArray(resources)) resourceError("macos.resources", resources, "expected an object");
71
+ const entries = Object.entries(resources);
72
+ if (entries.length > 256) {
73
+ const [destination, source] = entries[256];
74
+ resourceError(`macos.resources[${JSON.stringify(destination)}]`, source, "at most 256 entries are allowed");
75
+ }
76
+ const reserved = catalog ? ["Assets.car"] : [];
77
+ const resolved = [];
78
+ for (const [destination, source] of entries) {
79
+ const key = `macos.resources[${JSON.stringify(destination)}]`;
80
+ if (!validMacosResourceDestination(destination)) resourceError(key, source, "invalid destination");
81
+ if (reserved.some((other) => overlaps(destination, other))) resourceError(key, source, "destination collides with another resource");
82
+ reserved.push(destination);
83
+ resolved.push([destination, sourcePath(key, source)]);
84
+ }
85
+ return {
86
+ resources: Object.fromEntries(resolved),
87
+ assetCatalog: catalog
88
+ };
89
+ }
90
+ async function stageBundle(context, root, product, infoPlist, bin, bundle, bundleId, extras = { resources: {} }, displayName) {
91
+ const signal = runCancellationSignal(context) ?? context.signal;
92
+ await withDrainingCancellation(context, signal, async () => {
93
+ throwIfCancelled(signal, "macOS bundle staging");
94
+ const { minimumSystemVersion } = await validateInfoPlist(context, root, product, infoPlist);
95
+ for (const entry of readdirSync(bin).filter((name) => name.endsWith(".bundle"))) for (const [destination, source] of Object.entries(extras.resources)) if (overlaps(destination, entry)) resourceError(`macos.resources[${JSON.stringify(destination)}]`, source, `destination collides with ${entry}`);
96
+ await promises.rm(bundle, {
97
+ recursive: true,
98
+ force: true
99
+ });
100
+ const contents = join(bundle, "Contents");
101
+ await promises.mkdir(join(contents, "MacOS"), { recursive: true });
102
+ await promises.mkdir(join(contents, "Resources"), { recursive: true });
103
+ await promises.mkdir(join(contents, "Frameworks"), { recursive: true });
104
+ const executable = join(contents, "MacOS", product);
105
+ await copy(context, join(bin, product), executable);
106
+ await copy(context, resolve(root, infoPlist), join(contents, "Info.plist"));
107
+ await tool(context, "/usr/libexec/PlistBuddy", [
108
+ "-c",
109
+ `Set :CFBundleIdentifier ${bundleId}`,
110
+ join(contents, "Info.plist")
111
+ ], { timeoutMs: 1e4 });
112
+ if (displayName !== void 0) await setBundleName(context, join(contents, "Info.plist"), displayName);
113
+ for (const entry of readdirSync(bin)) if (entry.endsWith(".framework")) {
114
+ const target = join(contents, "Frameworks", entry);
115
+ await copy(context, join(bin, entry), target, {
116
+ recursive: true,
117
+ dereference: false,
118
+ verbatimSymlinks: true
119
+ });
120
+ await tool(context, "codesign", [
121
+ "--force",
122
+ "--sign",
123
+ "-",
124
+ target
125
+ ], { timeoutMs: "unbounded" });
126
+ } else if (entry.endsWith(".bundle")) await copy(context, join(bin, entry), join(contents, "Resources", entry), { recursive: true });
127
+ const frameworkPath = "@executable_path/../Frameworks";
128
+ if (!(await tool(context, "otool", ["-l", executable], { timeoutMs: 3e4 })).includes(frameworkPath)) await tool(context, "install_name_tool", [
129
+ "-add_rpath",
130
+ frameworkPath,
131
+ executable
132
+ ], { timeoutMs: 3e4 });
133
+ for (const [destination, source] of Object.entries(extras.resources)) {
134
+ const target = join(contents, "Resources", destination);
135
+ await promises.mkdir(dirname(target), { recursive: true });
136
+ await copy(context, source, target, { recursive: true });
137
+ }
138
+ if (extras.assetCatalog) {
139
+ await tool(context, "xcrun", [
140
+ "actool",
141
+ extras.assetCatalog,
142
+ "--compile",
143
+ join(contents, "Resources"),
144
+ "--platform",
145
+ "macosx",
146
+ ...minimumSystemVersion === void 0 ? [] : ["--minimum-deployment-target", minimumSystemVersion],
147
+ "--output-partial-info-plist",
148
+ "/dev/null"
149
+ ], { timeoutMs: "unbounded" });
150
+ if (!existsSync(join(contents, "Resources", "Assets.car"))) resourceError("macos.assetCatalog", extras.assetCatalog, "actool did not produce Assets.car");
151
+ }
152
+ await tool(context, "codesign", [
153
+ "--force",
154
+ "--sign",
155
+ "-",
156
+ bundle
157
+ ], { timeoutMs: "unbounded" });
158
+ });
159
+ }
160
+ async function tool(context, file, args, options) {
161
+ const signal = runCancellationSignal(context) ?? context.signal;
162
+ throwIfCancelled(signal, "macOS bundle staging");
163
+ const result = await getExecutor().runFileAsync(file, args, {
164
+ ...options,
165
+ declareFor: context
166
+ });
167
+ throwIfCancelled(signal, "macOS bundle staging");
168
+ return result;
169
+ }
170
+ async function copy(context, source, target, options = {}) {
171
+ const signal = runCancellationSignal(context) ?? context.signal;
172
+ throwIfCancelled(signal, "macOS bundle staging");
173
+ await promises.cp(source, target, {
174
+ ...options,
175
+ filter: () => {
176
+ throwIfCancelled(signal, "macOS bundle staging");
177
+ return true;
178
+ }
179
+ });
180
+ throwIfCancelled(signal, "macOS bundle staging");
181
+ }
182
+ //#endregion
183
+ export { validateInfoPlist as i, setBundleName as n, stageBundle as r, resolveBundleExtras as t };
@@ -1,26 +1,26 @@
1
- import { E as upsertProject, k as process_identity_exports, p as getProject } from "./config-BYDxlMY3.mjs";
2
- import { t as getExecutor } from "./exec-DqKo9GKJ.mjs";
3
- import { t as spawnEntry } from "./spawn-entry-Dcb7sDUz.mjs";
4
- import { A as metroIdleStopMinutesSetting, B as remoteAndroidSetting, G as resolveIosProjectDir, H as remoteIosSetting, K as resolveProjectSettings, L as publicUrlSetting, M as metroTunnelSettingError, O as metroCommandSetting, P as ngrokUrlSetting, Q as settingShapeErrors, U as resolveAndroidLayout, W as resolveCacheProviderConfig, a as SETTING_SHAPE_REMEDY, at as PUBLIC_METRO_ENV, h as deviceIdleShutdownMinutesSetting, j as metroPortSetting, k as metroCommandSettingError, m as defaultAndroidLayout, nt as unknownSettingKeys, ot as detectProviders, p as cacheProviderSettingError, st as planMetroReach, tt as tunnelModeSetting } from "./settings-B717odTD.mjs";
5
- import { _ as supervisorLogFile, c as writeWorkspaceState, i as recordWorkspaceUse, n as clearWorkspaceStateKeys, p as ensureWorkspaceStorage, r as readWorkspaceState$1, w as workspaceLogsDir$1, y as workspaceAgentDeviceDir } from "./workspace-state-DJt_MMvf.mjs";
6
- import { _ as stepTimer, l as phaseLine } from "./command-output-BTy8hZ0F.mjs";
7
- import { C as MODE_BARE, D as clearManagedMetroTunnel, T as MODE_EXPO, _ as detectIsExpo, b as readAppConfigText, j as readMetroTunnel, r as findProjectRoot, s as projectProblem, t as NO_PROJECT_REFUSAL, w as MODE_COMMAND, x as readAppJson } from "./project-_phNIJfs.mjs";
8
- import { a as workspaceLinks, i as workspaceLinkLine } from "./stim-desktop-BzBN2Em2.mjs";
9
- import { d as signalProcessTree, g as PortInspectionError, h as PORT_INSPECTION_REMEDY, m as reserveMetroPort, s as pidExists, u as resolveProjectMetro } from "./metro-DnCEjCxs.mjs";
10
- import { D as stopTunnel, E as startTunnelSequence, O as terminateChild, P as resolveSupervisorTarget, j as withManagedTunnelLock, k as withManagedRemoteWorktreeLock } from "./workspaces-C36s2jb9.mjs";
11
- import { ct as stopOwnedMetroForReset, t as budgetGate } from "./budget-f7516Zk0.mjs";
12
- import { a as withWorkspaceProcessLock, o as workspaceProcessLockError } from "./named-ports-4WopRPg-.mjs";
13
- import { t as cancellableSleep } from "./cancellation-C_22VQTH.mjs";
14
- import { i as levelRank } from "./ndjson-GOnbyvso.mjs";
15
- import { d as readProjectConfig } from "./remote-cache-OyOyVIS3.mjs";
16
- import { n as windowsLauncherArgs } from "./detached-entry-B9C_zeQC.mjs";
1
+ import { p as process_identity_exports, t as getExecutor } from "./exec-_UbtCQcG.mjs";
2
+ import { l as workspaceAgentDeviceDir, m as workspaceLogsDir$1, n as ensureWorkspaceStorage, s as supervisorLogFile } from "./paths-DQtTgsBf.mjs";
3
+ import { E as upsertProject, p as getProject } from "./config-CYcBF478.mjs";
4
+ import { _ as stepTimer, l as phaseLine } from "./command-output-B1UrjZHL.mjs";
5
+ import { d as writeWorkspaceState, i as recordWorkspaceUse, n as clearWorkspaceStateKeys, r as readWorkspaceState$1 } from "./workspace-state-Cjuigeeu.mjs";
6
+ import { A as metroIdleStopMinutesSetting, G as resolveCacheProviderConfig, J as resolveProjectSettingsAsync, K as resolveIosProjectDir, M as metroTunnelSettingError, O as metroCommandSetting, P as ngrokUrlSetting, Qt as cancellableSleep, R as publicUrlSetting, U as remoteIosSetting, V as remoteAndroidSetting, W as resolveAndroidLayout, a as SETTING_SHAPE_REMEDY, ct as detectProviders, en as throwIfCancelled, et as settingShapeErrors, h as deviceIdleShutdownMinutesSetting, it as unknownSettingKeys, j as metroPortSetting, k as metroCommandSettingError, lt as planMetroReach, m as defaultAndroidLayout, p as cacheProviderSettingError, rt as tunnelModeSetting, st as PUBLIC_METRO_ENV } from "./settings-CsJDEXgK.mjs";
7
+ import { E as MODE_EXPO, M as readMetroTunnel, O as clearManagedMetroTunnel, S as readAppJson, T as MODE_COMMAND, c as projectProblem, i as findProjectRoot$1, t as NO_PROJECT_REFUSAL, v as detectIsExpo, w as MODE_BARE, x as readAppConfigText } from "./project-BZNjmW_8.mjs";
8
+ import { i as levelRank } from "./ndjson-CgE_o3Dl.mjs";
9
+ import { _ as reserveMetroPort, d as processCwds, f as resolveProjectMetro, g as isMetroRunning, l as pidExists, o as listeningPidsAsync, p as signalProcessTree, v as PORT_INSPECTION_REMEDY, y as PortInspectionError } from "./metro-DEXpIhHC.mjs";
10
+ import { Kn as readProjectConfig, p as stopOwnedMetroForReset, t as budgetGate } from "./budget-Bs6SxxzO.mjs";
11
+ import { _ as terminateChild, b as withManagedTunnelLock, g as stopTunnel, h as startTunnelSequence, m as resolveSupervisorTarget, v as withManagedRemoteWorktreeLock } from "./workspaces-BccMFmGQ.mjs";
12
+ import { a as workspaceLinkLine, o as workspaceLinks } from "./stim-desktop-C12we7lz.mjs";
13
+ import { n as workspaceProcessLockError, t as withWorkspaceProcessLock } from "./workspace-process-lock-1_1OoVW5.mjs";
14
+ import { t as spawnEntry } from "./spawn-entry-jw19m8Nl.mjs";
15
+ import { n as windowsLauncherArgs } from "./detached-entry-DFRyG1_o.mjs";
17
16
  import { appendFileSync, mkdirSync, openSync, readFileSync } from "node:fs";
18
17
  import { dirname } from "node:path";
19
- import { join as join$1 } from "path";
18
+ import { ambientContext, ambientEnv } from "@stim-cli/core";
20
19
  import { IDLE_STOP_KEY, queryLogs } from "@stim-cli/core/state";
21
- import { CACHE_PROVIDER_ENV, cacheProviderEnv } from "@stim-cli/cache";
22
- import { existsSync as existsSync$1, readFileSync as readFileSync$1, readdirSync as readdirSync$1 } from "fs";
20
+ import { join as join$1 } from "path";
23
21
  import chalk from "chalk";
22
+ import { existsSync as existsSync$1, readFileSync as readFileSync$1, readdirSync as readdirSync$1 } from "fs";
23
+ import { CACHE_PROVIDER_ENV, cacheProviderEnv } from "@stim-cli/cache";
24
24
  import { EventEmitter } from "node:events";
25
25
  //#region src/workspace/app-id.ts
26
26
  const ANDROID_PACKAGE_NAME = /^[A-Za-z0-9_]+(?:\.[A-Za-z0-9_]+)+$/;
@@ -42,8 +42,8 @@ function configString(config, platform, key) {
42
42
  function literalString(text, key) {
43
43
  return text?.match(new RegExp(`${key}\\s*:\\s*["']([^"']+)["']`))?.[1] ?? null;
44
44
  }
45
- function idsFromConfig(projectRoot) {
46
- const read = readProjectConfig(projectRoot);
45
+ async function idsFromConfig(projectRoot) {
46
+ const read = await readProjectConfig(projectRoot);
47
47
  if (!read.unavailable) return {
48
48
  bundleId: configString(read.config, "ios", "bundleIdentifier"),
49
49
  androidPackage: configString(read.config, "android", "package")
@@ -55,8 +55,8 @@ function idsFromConfig(projectRoot) {
55
55
  androidPackage: configString(appJson, "android", "package") ?? literalString(text, "package")
56
56
  };
57
57
  }
58
- function detectAppIds(projectRoot, iosDir = join$1(projectRoot, "ios"), androidModuleDir = defaultAndroidLayout(projectRoot).moduleDir) {
59
- const ids = idsFromConfig(projectRoot);
58
+ async function detectAppIds(projectRoot, iosDir = join$1(projectRoot, "ios"), androidModuleDir = defaultAndroidLayout(projectRoot).moduleDir) {
59
+ const ids = await idsFromConfig(projectRoot);
60
60
  const problems = [];
61
61
  const accept = androidPackageFilter(problems);
62
62
  return {
@@ -65,11 +65,11 @@ function detectAppIds(projectRoot, iosDir = join$1(projectRoot, "ios"), androidM
65
65
  androidPackageProblem: problems.length > 0 ? problems.join(" ") : null
66
66
  };
67
67
  }
68
- function detectBundleId(projectRoot, iosDir = join$1(projectRoot, "ios")) {
69
- return detectAppIds(projectRoot, iosDir).bundleId;
68
+ async function detectBundleId(projectRoot, iosDir = join$1(projectRoot, "ios")) {
69
+ return (await detectAppIds(projectRoot, iosDir)).bundleId;
70
70
  }
71
- function detectAndroidPackage(projectRoot, androidModuleDir = defaultAndroidLayout(projectRoot).moduleDir) {
72
- return detectAppIds(projectRoot, void 0, androidModuleDir).androidPackage;
71
+ async function detectAndroidPackage(projectRoot, androidModuleDir = defaultAndroidLayout(projectRoot).moduleDir) {
72
+ return (await detectAppIds(projectRoot, void 0, androidModuleDir)).androidPackage;
73
73
  }
74
74
  function detectBundleIdFromPbxproj(iosDir) {
75
75
  if (!existsSync$1(iosDir)) return null;
@@ -123,6 +123,23 @@ function detectAndroidPackageFromGradle(moduleDir, accept) {
123
123
  const DEFAULT_WAIT_SECONDS = 60;
124
124
  const POLL_MS = 500;
125
125
  const LOG_TAIL_LINES = 5;
126
+ async function resolveStartupMetro(port, root) {
127
+ const signal = ambientContext()?.signal;
128
+ throwIfCancelled(signal, "Metro startup");
129
+ const result = await resolveProjectMetro(port, root, {
130
+ pidsOf: listeningPidsAsync,
131
+ cwdOf: async (pid) => (await processCwds([pid])).get(pid) ?? null,
132
+ probe: (candidate) => isMetroRunning(candidate, signal)
133
+ });
134
+ throwIfCancelled(signal, "Metro startup");
135
+ return result;
136
+ }
137
+ function waitForStartup(ms) {
138
+ return cancellableSleep(ms, {
139
+ signal: ambientContext()?.signal,
140
+ what: "Metro startup"
141
+ });
142
+ }
126
143
  function writeNote(line) {
127
144
  console.error(line);
128
145
  }
@@ -264,7 +281,7 @@ function registerStart(program, overrides = {}) {
264
281
  remedy: "Pass a whole number of seconds, e.g. --wait 90."
265
282
  });
266
283
  const waitSeconds = wait.seconds;
267
- const root = findProjectRoot(process.cwd());
284
+ const root = findProjectRoot$1(process.cwd());
268
285
  if (!root) return fail(NO_PROJECT_REFUSAL);
269
286
  const problem = projectProblem(root, "dev-server");
270
287
  if (problem) return fail({
@@ -282,7 +299,7 @@ function registerStart(program, overrides = {}) {
282
299
  });
283
300
  }
284
301
  recordWorkspaceUse(root);
285
- const { context: settingsContext, settings } = resolveProjectSettings(root);
302
+ const { context: settingsContext, settings } = await resolveProjectSettingsAsync(root);
286
303
  const [shapeError, ...moreShapeErrors] = settingShapeErrors(settings);
287
304
  if (shapeError) return fail({
288
305
  code: "STIM_BAD_ARG",
@@ -314,7 +331,7 @@ function registerStart(program, overrides = {}) {
314
331
  facts: result.facts,
315
332
  waited: result.waited,
316
333
  reclaimed: result.reclaimed,
317
- links: workspaceLinks(root)
334
+ links: await workspaceLinks(root)
318
335
  });
319
336
  });
320
337
  }
@@ -376,7 +393,7 @@ async function startDevServer({ root, settings, settingsContext, waitSeconds = D
376
393
  if (tunnel) note(chalk.dim("note requesting an Expo tunnel for this workspace's dev server"));
377
394
  const managedRemote = remote && !tunnel && !publicUrl && tunnelMode !== "off";
378
395
  const runStart = async () => {
379
- const appIds = detectAppIds(root, resolveIosProjectDir(settings, root).dir, resolveAndroidLayout(settings, root, settingsContext.repoRoot ?? root).moduleDir);
396
+ const appIds = await detectAppIds(root, resolveIosProjectDir(settings, root).dir, resolveAndroidLayout(settings, root, settingsContext.repoRoot ?? root).moduleDir);
380
397
  upsertProject(root, {
381
398
  bundleId: appIds.bundleId ?? void 0,
382
399
  androidPackage: appIds.androidPackage ?? void 0,
@@ -385,14 +402,15 @@ async function startDevServer({ root, settings, settingsContext, waitSeconds = D
385
402
  const gateBudget = async () => {
386
403
  const budget = await d.budgetGate({
387
404
  root,
388
- note
405
+ note,
406
+ env: ambientEnv()
389
407
  });
390
408
  reclaimed = budget.reclaimed;
391
409
  if (budget.refusal) return fail(budget.refusal);
392
410
  };
393
411
  if (resetCache) {
394
412
  await gateBudget();
395
- const pin = metroPortSetting(settings);
413
+ const pin = metroPortSetting(settings, ambientEnv());
396
414
  if (pin.port !== null || pin.error) {
397
415
  const pinCheck = await resolveWorkspaceMetroPort(root, settings, note, "start", false);
398
416
  if (typeof pinCheck !== "number") return fail(pinCheck);
@@ -413,7 +431,7 @@ async function startDevServer({ root, settings, settingsContext, waitSeconds = D
413
431
  const logFile = supervisorLogFile(root);
414
432
  const port = await resolvePort(root, settings, note, fail);
415
433
  let publicOrigin = remote ? publicUrl : null;
416
- let resolution = await resolveProjectMetro(port, root);
434
+ let resolution = await resolveStartupMetro(port, root);
417
435
  let supervisor = liveSupervisor({
418
436
  state: readWorkspaceState$1(root),
419
437
  project: getProject(root),
@@ -539,7 +557,7 @@ async function startDevServer({ root, settings, settingsContext, waitSeconds = D
539
557
  String(deviceIdleShutdownMinutesSetting(settings))
540
558
  ];
541
559
  const childEnv = {
542
- ...process.env,
560
+ ...ambientEnv(),
543
561
  ...origin ? {
544
562
  [PUBLIC_METRO_ENV]: origin,
545
563
  EXPO_PACKAGER_PROXY_URL: origin
@@ -612,7 +630,7 @@ async function startDevServer({ root, settings, settingsContext, waitSeconds = D
612
630
  startedHere: false
613
631
  };
614
632
  } else {
615
- const currentResolution = await resolveProjectMetro(port, root);
633
+ const currentResolution = await resolveStartupMetro(port, root);
616
634
  const currentSupervisor = liveSupervisor({
617
635
  state: readWorkspaceState$1(root),
618
636
  project: getProject(root),
@@ -662,7 +680,7 @@ async function startDevServer({ root, settings, settingsContext, waitSeconds = D
662
680
  startedHere: true
663
681
  };
664
682
  }
665
- const currentResolution = await resolveProjectMetro(port, root);
683
+ const currentResolution = await resolveStartupMetro(port, root);
666
684
  const currentSupervisor = liveSupervisor({
667
685
  state: readWorkspaceState$1(root),
668
686
  project: getProject(root),
@@ -739,6 +757,7 @@ async function startDevServer({ root, settings, settingsContext, waitSeconds = D
739
757
  };
740
758
  });
741
759
  } catch (err) {
760
+ if (err instanceof Error && "code" in err && err.code === "STIM_CANCELLED") throw err;
742
761
  return fail({
743
762
  code: "STIM_REMOTE_METRO_UNREACHABLE",
744
763
  message: `Could not acquire the managed Metro tunnel lock: ${err?.message || err}`,
@@ -749,7 +768,7 @@ async function startDevServer({ root, settings, settingsContext, waitSeconds = D
749
768
  publicOrigin = acquisition.origin;
750
769
  managedTunnel = acquisition.tunnel;
751
770
  if (managedTunnel.record.provider === "tailscale") note(phaseLine("lan", `tailnet-only Metro: ${publicOrigin}`));
752
- resolution = await resolveProjectMetro(port, root);
771
+ resolution = await resolveStartupMetro(port, root);
753
772
  supervisor = liveSupervisor({
754
773
  state: readWorkspaceState$1(root),
755
774
  project: getProject(root),
@@ -991,7 +1010,7 @@ async function resolvePort(root, settings, note, fail) {
991
1010
  return typeof result === "number" ? result : fail(result);
992
1011
  }
993
1012
  async function resolveWorkspaceMetroPort(root, settings, note, command, reserve = true) {
994
- const setting = metroPortSetting(settings);
1013
+ const setting = metroPortSetting(settings, ambientEnv());
995
1014
  if (setting.error) return {
996
1015
  code: "STIM_BAD_ARG",
997
1016
  message: setting.error,
@@ -1022,7 +1041,7 @@ async function resolveWorkspaceMetroPort(root, settings, note, command, reserve
1022
1041
  }
1023
1042
  }
1024
1043
  if (pinned !== null) {
1025
- const held = await resolveProjectMetro(pinned, root);
1044
+ const held = await resolveStartupMetro(pinned, root);
1026
1045
  if (held.notOurs) return {
1027
1046
  code: "STIM_BAD_ARG",
1028
1047
  message: `Port ${pinned} is held by something else (${held.notOurs}), and metro.port pins this workspace's Metro to it.`,
@@ -1030,7 +1049,7 @@ async function resolveWorkspaceMetroPort(root, settings, note, command, reserve
1030
1049
  };
1031
1050
  if (recorded === pinned) return recorded;
1032
1051
  } else if (recorded) {
1033
- const held = await resolveProjectMetro(recorded, root);
1052
+ const held = await resolveStartupMetro(recorded, root);
1034
1053
  if (!held.notOurs) return recorded;
1035
1054
  const fresh = await reservePort(root, null);
1036
1055
  if (typeof fresh === "number" && fresh !== recorded) {
@@ -1058,12 +1077,12 @@ async function reservePort(root, pinned) {
1058
1077
  };
1059
1078
  }
1060
1079
  }
1061
- async function waitForMetro({ root, port, seconds, aborted = () => false, probe = resolveProjectMetro }) {
1080
+ async function waitForMetro({ root, port, seconds, aborted = () => false, probe = resolveStartupMetro }) {
1062
1081
  const deadline = Date.now() + seconds * 1e3;
1063
1082
  while (Date.now() < deadline) {
1064
1083
  if ((await probe(port, root)).metro) return true;
1065
1084
  if (aborted()) return false;
1066
- await cancellableSleep(POLL_MS);
1085
+ await waitForStartup(POLL_MS);
1067
1086
  }
1068
1087
  const last = await probe(port, root);
1069
1088
  return Boolean(last.metro);
@@ -1073,7 +1092,7 @@ async function waitForExpoTunnel({ root, seconds, aborted = () => false }) {
1073
1092
  while (Date.now() < deadline) {
1074
1093
  if (aborted()) return false;
1075
1094
  if (readMetroTunnel(root)?.kind === "expo") return true;
1076
- await cancellableSleep(POLL_MS);
1095
+ await waitForStartup(POLL_MS);
1077
1096
  }
1078
1097
  return !aborted() && readMetroTunnel(root)?.kind === "expo";
1079
1098
  }
@@ -1,2 +1,2 @@
1
- import { a as registerStart, c as startDevServer, d as supervisorSignalable, f as tailLines, i as readLogTail, l as startFacts, n as liveSupervisor, o as resolveWorkspaceMetroPort, p as wantsExpoOwnTunnel, r as parseWait, s as startCommand, t as failureEvidence, u as supervisorEntry } from "./start-BWqzODpb.mjs";
1
+ import { a as registerStart, c as startDevServer, d as supervisorSignalable, f as tailLines, i as readLogTail, l as startFacts, n as liveSupervisor, o as resolveWorkspaceMetroPort, p as wantsExpoOwnTunnel, r as parseWait, s as startCommand, t as failureEvidence, u as supervisorEntry } from "./start-7lpH7hmN.mjs";
2
2
  export { startCommand as default, failureEvidence, liveSupervisor, parseWait, readLogTail, registerStart, resolveWorkspaceMetroPort, startDevServer, startFacts, supervisorEntry, supervisorSignalable, tailLines, wantsExpoOwnTunnel };