stim 1.20.2 → 1.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (231) hide show
  1. package/README.md +141 -8
  2. package/dist/acquire-artifact-Co2k4f7O.mjs +171 -0
  3. package/dist/act-DsuqEkiM.mjs +2801 -0
  4. package/dist/activity-CMLmzp7o.mjs +1397 -0
  5. package/dist/{agent-device-usage-output-Dzgv6lgR.mjs → agent-device-usage-output-DUFaTMdd.mjs} +23 -67
  6. package/dist/{android-DCKZrNvV.mjs → android-ByRMUoiJ.mjs} +157 -93
  7. package/dist/{android-Mz_Inn3w.mjs → android-C7sVmyI9.mjs} +299 -116
  8. package/dist/{android-Dlzxshgp.mjs → android-DGkNqa_c.mjs} +5 -5
  9. package/dist/{android-HqP1_vB_.mjs → android-DR5lZ2Az.mjs} +2 -2
  10. package/dist/android-cas-compiler.mjs +2 -2
  11. package/dist/{android-cas-Bl-cLJBk.mjs → android-cas-ngferVq2.mjs} +7 -6
  12. package/dist/android-project-BCAAmMwz.mjs +12 -0
  13. package/dist/android-project-DVWyCbWU.d.mts +391 -0
  14. package/dist/api.d.mts +810 -64
  15. package/dist/api.mjs +782 -1
  16. package/dist/{artifact-HSwkIWEQ.mjs → artifact-8EY8SAPw.mjs} +240 -213
  17. package/dist/{artifact-D3czlUvT.mjs → artifact-DJPy518Y.mjs} +203 -164
  18. package/dist/artifact-platform-CXcmX_j3.mjs +27 -0
  19. package/dist/{browser-web-CA-F1GQo.mjs → browser-web-Bcv99PBM.mjs} +194 -64
  20. package/dist/budget-Cvwn54qV.mjs +9285 -0
  21. package/dist/{build-DYDbfkk5.mjs → build-CabC3G23.mjs} +153 -98
  22. package/dist/build-cache-Dv7RN200.mjs +602 -0
  23. package/dist/build-plan-DUC8Ka9y.mjs +248 -0
  24. package/dist/{cache-manifest-XH-fvDUj.mjs → cache-manifest-DSeQjt-Q.mjs} +2 -2
  25. package/dist/cache-manifest.mjs +1 -1
  26. package/dist/{ccache-zdKiYQ3E.mjs → ccache-Btwc36-I.mjs} +10 -9
  27. package/dist/{cdp-Dq_ypAlJ.mjs → cdp-3fwICjzi.mjs} +18 -5
  28. package/dist/{chrome-BnzZMqsR.mjs → chrome-Bbw689-6.mjs} +7 -4
  29. package/dist/{cli-CLP3diBm.mjs → cli-CHZa9Lvk.mjs} +20 -20
  30. package/dist/cli.mjs +1 -1
  31. package/dist/client-OyRoEuSr.mjs +1577 -0
  32. package/dist/collector-run.d.mts +4 -40
  33. package/dist/collector-run.mjs +9 -8
  34. package/dist/{command-output-BTy8hZ0F.mjs → command-output-gwpm28fu.mjs} +1 -1
  35. package/dist/config-DlrsduwG.mjs +955 -0
  36. package/dist/{created-devices-Dzd5C2LF.mjs → created-devices-x9rN6bhs.mjs} +14 -4
  37. package/dist/{dependency-state-DG0p31-y.mjs → dependency-state-1I9KZT1Y.mjs} +20 -5
  38. package/dist/{detached-entry-B9C_zeQC.mjs → detached-entry-BwNEtIrP.mjs} +1 -1
  39. package/dist/{dev-client-DAWVIGBu.mjs → dev-client-BSDR5h3F.mjs} +2 -2
  40. package/dist/{device-BECOiufl.mjs → device-B-L3Fbxy.mjs} +91 -34
  41. package/dist/device-DklWZLqb.mjs +1068 -0
  42. package/dist/{device-capacity-CBUAcRyQ.mjs → device-capacity-DK5_EwRS.mjs} +42 -13
  43. package/dist/device-host-worker.mjs +76 -79
  44. package/dist/{device-ios-COSi6oS1.mjs → device-ios-DoB6KFCO.mjs} +77 -51
  45. package/dist/{device-lease-run-Cw2M4z51.mjs → device-lease-run-xJPQ_QQG.mjs} +14 -26
  46. package/dist/{device-pool-Bf-pOhSw.mjs → device-pool-BMkdsefq.mjs} +5 -5
  47. package/dist/{doctor-kfMBnUw6.mjs → doctor-Bo7BXLux.mjs} +271 -320
  48. package/dist/{doctor-CB8oZKCk.mjs → doctor-D5_EzwfA.mjs} +186 -91
  49. package/dist/doctor-fingerprint-DZLoYFVb.mjs +16 -0
  50. package/dist/doctor-fingerprint.mjs +19 -0
  51. package/dist/doctor-thjWAV0z.mjs +2 -0
  52. package/dist/{doctor-watchman-BRyV2adA.mjs → doctor-watchman-N2wDotwQ.mjs} +40 -21
  53. package/dist/{eas-build-JyfqyHfC.mjs → eas-build-CwknaQYj.mjs} +53 -20
  54. package/dist/{build-plan-B7SZsc2N.mjs → eas-fallback-CSgAulr5.mjs} +41 -214
  55. package/dist/{watchman-CPQFZLXY.mjs → eas-session-ledger-DlY_serQ.mjs} +230 -11
  56. package/dist/{error-diagnostics-BR677IDM.mjs → error-diagnostics-DBWO2rxE.mjs} +172 -82
  57. package/dist/exec-DEoAhcze.mjs +858 -0
  58. package/dist/exec-DnYc4HGH.d.mts +78 -0
  59. package/dist/{gc-qWOMdnER.mjs → gc-CXxN-4SE.mjs} +1091 -1029
  60. package/dist/gc-DnNDQyaP.mjs +3 -0
  61. package/dist/{guide-G9cAbVAc.mjs → guide-Br0LEfKy.mjs} +1165 -297
  62. package/dist/{hosted-android-C3MHGld1.mjs → hosted-android-B-9f-jkd.mjs} +10 -8
  63. package/dist/{hosted-client-ZEKpS9vw.mjs → hosted-client-DZAPrcro.mjs} +34 -19
  64. package/dist/{hosted-ios-l-o3iM9J.mjs → hosted-ios-CsCS21hn.mjs} +1 -1
  65. package/dist/{hosted-logs-EzQM7-3Z.mjs → hosted-logs-FIRx9X2f.mjs} +77 -43
  66. package/dist/{hosted-macos-BACVAVqE.mjs → hosted-macos-_awYSpfv.mjs} +35 -22
  67. package/dist/{hosted-native-A4s1QPXe.mjs → hosted-native-BdzE668-.mjs} +49 -27
  68. package/dist/idle-C4cZ757K.d.mts +24 -0
  69. package/dist/{idle-shutdown-DtxhPTKe.mjs → idle-shutdown-DDg3SdvY.mjs} +11 -10
  70. package/dist/ios-CDvlmUs7.d.mts +24 -0
  71. package/dist/{ios-BwVCF7oA.mjs → ios-Ds1clbIt.mjs} +8 -8
  72. package/dist/{ios-device-D7pi2Sca.mjs → ios-device--h_-8ENa.mjs} +51 -26
  73. package/dist/{ios-device-B5veSDDQ.mjs → ios-device-BXZ0c7Kb.mjs} +1 -1
  74. package/dist/{ios-RkW4pnQf.mjs → ios-hcBpnEGk.mjs} +200 -93
  75. package/dist/{ios-Ce7bc7br.mjs → ios-pm4nL6By.mjs} +160 -108
  76. package/dist/{ios-project-K9hY_Jab.mjs → ios-project-CZhKODF3.mjs} +13 -13
  77. package/dist/ios-signing-BtAffm0A.mjs +489 -0
  78. package/dist/{ios-state-CBLe1xYw.mjs → ios-state-Dtw5K2aI.mjs} +1 -1
  79. package/dist/{ios-nOLJGVdy.mjs → ios-xtlRHaeB.mjs} +1 -1
  80. package/dist/{js-swap-Bb3nsS07.mjs → js-swap-Bwhh4S7V.mjs} +30 -25
  81. package/dist/{launch-C3qJ6Agb.mjs → launch-BjxemNpK.mjs} +85 -543
  82. package/dist/{launch-F4sOqAhB.mjs → launch-CCzXlc8r.mjs} +91 -90
  83. package/dist/logs-BfwwadsZ.mjs +479 -0
  84. package/dist/logs-jTS_lHSo.mjs +248 -0
  85. package/dist/{macos-D7uDvO-z.mjs → macos-DVlSSyUg.mjs} +1 -1
  86. package/dist/macos-NfV2D7dO.mjs +694 -0
  87. package/dist/macos-run.mjs +1 -1
  88. package/dist/maintenance-run.mjs +123 -248
  89. package/dist/{metro-DnCEjCxs.mjs → metro-DiXtA3Ty.mjs} +107 -30
  90. package/dist/metro-gateway-CKZqKqx7.mjs +209 -0
  91. package/dist/{named-ports-4WopRPg-.mjs → named-ports-DkEzOfzO.mjs} +42 -90
  92. package/dist/native-android-CqgnOgsT.mjs +645 -0
  93. package/dist/native-gradle-artifact-inputs-DHFnmrVf.mjs +270 -0
  94. package/dist/native-gradle-inputs-Dnh84Zbd.mjs +211 -0
  95. package/dist/native-inputs-TRTTTRxt.mjs +91 -0
  96. package/dist/native-run-NwUuxbkg.mjs +276 -0
  97. package/dist/{native-runtime-k8dTIrbK.mjs → native-runtime-B7KIafpM.mjs} +11 -9
  98. package/dist/native-source-Y0yLhFyQ.mjs +133 -0
  99. package/dist/{native-xcode-inputs-CykopJdM.mjs → native-xcode-inputs-D_VOfFL7.mjs} +26 -18
  100. package/dist/{native-xcode-ios-Bbf30Gm0.mjs → native-xcode-ios-BYDOHWLN.mjs} +104 -60
  101. package/dist/{ndjson-GOnbyvso.mjs → ndjson-CgE_o3Dl.mjs} +3 -3
  102. package/dist/offload-worker.d.mts +59 -41
  103. package/dist/offload-worker.mjs +478 -115
  104. package/dist/operation-exec-BW0em61G.mjs +171 -0
  105. package/dist/{ownership-DCtw_2IA.mjs → ownership-C5fo5Edb.mjs} +3 -3
  106. package/dist/{page-DRHy329N.mjs → page-DBL2PiUU.mjs} +12 -5
  107. package/dist/paths-BsJMoPP2.mjs +12 -0
  108. package/dist/paths-DQtTgsBf.mjs +42 -0
  109. package/dist/{placement-log-MOfPVgaM.mjs → placement-log-BnGgJRRZ.mjs} +5 -5
  110. package/dist/{plan-placement-V0TdzYXp.mjs → plan-placement-DIsMtN-d.mjs} +15 -11
  111. package/dist/{ports-DdSUicVo.mjs → ports-Cy1RkmuQ.mjs} +3 -3
  112. package/dist/prebuild-D4JoEAEs.mjs +484 -0
  113. package/dist/{project-_phNIJfs.mjs → project-wM_XFTvE.mjs} +65 -37
  114. package/dist/{pull-request-CQ8sPbZa.mjs → pull-request-W1IuLXDt.mjs} +102 -20
  115. package/dist/pull-request-eODyIqZF.d.mts +124 -0
  116. package/dist/pull-requests.d.mts +2 -120
  117. package/dist/pull-requests.mjs +2 -2
  118. package/dist/{react-native-android-CM1XRDwv.mjs → react-native-android-6OZ7MSM7.mjs} +121 -72
  119. package/dist/{gradle-DSrXb6lG.mjs → react-native-build-Dvd8hC21.mjs} +292 -15
  120. package/dist/react-native-doctor-DsoSF1Y9.mjs +234 -0
  121. package/dist/{react-native-ios-Dhq_eiYQ.mjs → react-native-ios-4u1Rn-GR.mjs} +71 -39
  122. package/dist/{recordings-D0d5aQt0.mjs → recordings-CQmfzAh7.mjs} +12 -9
  123. package/dist/registration-BcRgF6Ox.mjs +51 -0
  124. package/dist/{reload-C8JhxjSh.mjs → reload-BzkYabB-.mjs} +94 -47
  125. package/dist/reload-D7AVlb8N.mjs +2 -0
  126. package/dist/{remote-BiR6aYjy.mjs → remote-DjGDmlTZ.mjs} +26 -18
  127. package/dist/result-D2Ykz_iD.mjs +435 -0
  128. package/dist/{run-BtPgpKks.mjs → run-DidHghD1.mjs} +5 -5
  129. package/dist/selection-DSMbWEX2.mjs +620 -0
  130. package/dist/{server-bare-R2m_gsH8.mjs → server-bare-CafzuyFB.mjs} +3 -4
  131. package/dist/{server-command-CTtCkmcQ.mjs → server-command-C6QjeupS.mjs} +14 -7
  132. package/dist/{server-expo-DsguMGUF.mjs → server-expo-CrjB29pq.mjs} +54 -11
  133. package/dist/server-expo-D58c9L0M.mjs +2 -0
  134. package/dist/{settings-B717odTD.mjs → settings-C7O8A6ZI.mjs} +309 -119
  135. package/dist/settings-DpR-1Wnn.mjs +114 -0
  136. package/dist/settings-write-CzD60rOD.mjs +360 -0
  137. package/dist/settings.schema.json +176 -16
  138. package/dist/{simslim-CCr3rE-A.mjs → simslim-BNckWpXi.mjs} +14 -12
  139. package/dist/{slot-launch-DPt0m9Nd.mjs → slot-launch-CbfmNgM6.mjs} +15 -20
  140. package/dist/{spawn-entry-Dcb7sDUz.mjs → spawn-entry-jw19m8Nl.mjs} +0 -1
  141. package/dist/stage-Bps5oius.mjs +200 -0
  142. package/dist/{start-TXeMmmO2.mjs → start-Br-oxqMD.mjs} +1 -1
  143. package/dist/start-EojN4WFz.mjs +1364 -0
  144. package/dist/{state-D1Icyjlu.mjs → state--smjFSTL.mjs} +55 -13
  145. package/dist/{state-CG_OFoaA.mjs → state-08I3hw3_.mjs} +3 -2
  146. package/dist/{stats-BoY5sEPU.mjs → stats-D3GerlFW.mjs} +7 -13
  147. package/dist/stats-report-BzaPrRm6.mjs +16 -0
  148. package/dist/{status-BTA7kKiQ.mjs → status-BRROykC8.mjs} +7 -5
  149. package/dist/status-EvrK72L2.mjs +2 -0
  150. package/dist/{status-WgFbkRzj.mjs → status-WBDajew2.mjs} +554 -452
  151. package/dist/{status-watch-C23ILtf9.mjs → status-watch-Bg_u-pwR.mjs} +222 -25
  152. package/dist/status-worker.d.mts +1 -0
  153. package/dist/status-worker.mjs +19 -0
  154. package/dist/stim-desktop-D5OGpYZM.mjs +112 -0
  155. package/dist/{stop-DR6VoDIk.mjs → stop-DTZ9uTw3.mjs} +2 -2
  156. package/dist/{stop-DPEhunlw.mjs → stop-Dky10AEJ.mjs} +33 -23
  157. package/dist/{stop-BNmBMi1F.mjs → stop-Mv6W9FAk.mjs} +137 -98
  158. package/dist/supervisor-run.d.mts +8 -17
  159. package/dist/supervisor-run.mjs +56 -28
  160. package/dist/{support-CwjbFs9H.mjs → support-CNioewsd.mjs} +14 -14
  161. package/dist/{support-DMTqj3Hm.mjs → support-yUiOjnVY.mjs} +20 -13
  162. package/dist/swiftpm-artifact-inputs-DFcGsXDP.mjs +153 -0
  163. package/dist/swiftpm-macos-BIak-Rxv.mjs +532 -0
  164. package/dist/toolchain-BY8X8HXx.mjs +2 -0
  165. package/dist/toolchain-DpJMHq0n.mjs +876 -0
  166. package/dist/{trigger-CigAYjeL.mjs → trigger-Cbyc41d_.mjs} +21 -6
  167. package/dist/trigger-yb_nFzPF.mjs +2 -0
  168. package/dist/{warm-progress-BuY-Fvfn.mjs → warm-progress-CA3TgT3-.mjs} +263 -156
  169. package/dist/web-CZ07gd77.mjs +2 -0
  170. package/dist/{web-BDBMxDpx.mjs → web-DKx6yoFA.mjs} +20 -14
  171. package/dist/web-run.mjs +13 -12
  172. package/dist/windows-report.d.mts +1 -0
  173. package/dist/windows-report.mjs +18 -0
  174. package/dist/windows-report.ps1 +43 -0
  175. package/dist/{workspace-state-DJt_MMvf.mjs → workspace-state-U08dEzhG.mjs} +62 -58
  176. package/dist/{workspaces-C36s2jb9.mjs → workspaces-CpANmBlq.mjs} +1723 -1286
  177. package/dist/{worktree-CgvJYJ-Q.mjs → worktree-CHecZ4Oq.mjs} +1097 -547
  178. package/dist/worktree-ZqZVjD9K.mjs +2 -0
  179. package/dist/xcode-BXn9-xYx.mjs +896 -0
  180. package/package.json +7 -5
  181. package/shim/android-audio/Main.java +24 -0
  182. package/shim/android-audio/README.md +17 -0
  183. package/shim/android-audio.jar +0 -0
  184. package/shim/android-optimizations.gradle +7 -5
  185. package/dist/activity-BSV745Kz.mjs +0 -629
  186. package/dist/api-qvOzWyfO.mjs +0 -154
  187. package/dist/api-run.mjs +0 -294
  188. package/dist/app-install-BIKtMfPq.mjs +0 -896
  189. package/dist/artifact-lifecycle-DzPpBYvK.mjs +0 -30
  190. package/dist/budget-f7516Zk0.mjs +0 -4106
  191. package/dist/build-facts-DcLv2HSd.d.mts +0 -111
  192. package/dist/cancellation-C_22VQTH.mjs +0 -24
  193. package/dist/client-qQAaXSUs.mjs +0 -1771
  194. package/dist/config-BYDxlMY3.mjs +0 -562
  195. package/dist/device-DuiPJQSn.mjs +0 -290
  196. package/dist/device-lease-BX1sJQ2E.mjs +0 -1224
  197. package/dist/device-remote-xRT0Vmo9.mjs +0 -1272
  198. package/dist/eas-session-ledger-Cm0Gwq2F.mjs +0 -207
  199. package/dist/exec-DqKo9GKJ.mjs +0 -268
  200. package/dist/git-DDfFzkMm.mjs +0 -45
  201. package/dist/launch-verify-B6Q8hZP-.mjs +0 -428
  202. package/dist/logs-BGrEUaEs.mjs +0 -383
  203. package/dist/macos-Ch5VJmcS.mjs +0 -584
  204. package/dist/metro-gateway-CX9Xlkq2.mjs +0 -103
  205. package/dist/miss-reason-mKzZ4VvN.mjs +0 -238
  206. package/dist/native-android-D5qc3-_v.mjs +0 -226
  207. package/dist/native-gradle-inputs-BsLRrl7u.mjs +0 -349
  208. package/dist/ndjson-Du3j0AQ9.d.mts +0 -17
  209. package/dist/plan-C4TjdPsR.mjs +0 -260
  210. package/dist/prebuild-DYbucPXy.mjs +0 -212
  211. package/dist/preview-78a9kR_-.mjs +0 -1011
  212. package/dist/react-native-build-CtCccJtb.mjs +0 -239
  213. package/dist/react-native-doctor-CfRnFfjs.mjs +0 -78
  214. package/dist/remote-cache-OyOyVIS3.mjs +0 -526
  215. package/dist/result-CaJg5Iat.mjs +0 -186
  216. package/dist/server-expo-Bigriskl.mjs +0 -2
  217. package/dist/settings-BORNaaCO.mjs +0 -402
  218. package/dist/settings-vk3mJGSm.d.mts +0 -13
  219. package/dist/spawn-claims-DVS5RkMS.mjs +0 -72
  220. package/dist/stage-KNTQopqv.mjs +0 -157
  221. package/dist/start-BWqzODpb.mjs +0 -1116
  222. package/dist/stim-desktop-BzBN2Em2.mjs +0 -63
  223. package/dist/swiftpm-macos-DRNVJWlb.mjs +0 -119
  224. package/dist/tailnet-Dh-qiYzG.mjs +0 -265
  225. package/dist/toolchain-BFkAcstd.mjs +0 -2
  226. package/dist/toolchain-DxSsNssu.mjs +0 -1657
  227. package/dist/trigger-9_USgmxz.mjs +0 -2
  228. package/dist/web-Dq-i3wzJ.mjs +0 -2
  229. package/dist/worktree-DpLdCHga.mjs +0 -2
  230. package/dist/{api-run.d.mts → doctor-fingerprint.d.mts} +0 -0
  231. package/dist/{errors-DzkMYh8Q.mjs → errors-ccaPc4ox.mjs} +2 -2
@@ -1,15 +1,73 @@
1
- import { t as getExecutor } from "./exec-DqKo9GKJ.mjs";
1
+ import { d as spawnDeclared, t as getExecutor } from "./exec-DEoAhcze.mjs";
2
+ import { o as sharedCompilationCache } from "./paths-DQtTgsBf.mjs";
2
3
  import { n as stripAnsi, r as waitForChild, t as createLineReader } from "./process-output-Fpl8PYi8.mjs";
3
- import { l as phaseLine } from "./command-output-BTy8hZ0F.mjs";
4
- import { o as androidHome } from "./android-Mz_Inn3w.mjs";
5
- import { a as spawnDeclared } from "./spawn-claims-DVS5RkMS.mjs";
6
- import { a as readCcacheActivity, n as CCACHE_UNAVAILABLE } from "./ccache-zdKiYQ3E.mjs";
7
- import { M as startBuildHeartbeat, y as HEARTBEAT_INTERVAL_MS } from "./toolchain-DxSsNssu.mjs";
4
+ import { l as phaseLine } from "./command-output-gwpm28fu.mjs";
5
+ import { a as killOnAbort } from "./operation-exec-BW0em61G.mjs";
6
+ import { C as resolvePackageJson } from "./project-wM_XFTvE.mjs";
7
+ import { r as register } from "./cache-manifest-DSeQjt-Q.mjs";
8
+ import { o as androidHome } from "./android-C7sVmyI9.mjs";
9
+ import { p as resolveOptimizations } from "./errors-ccaPc4ox.mjs";
10
+ import { a as readCcacheActivity, n as CCACHE_UNAVAILABLE } from "./ccache-Btwc36-I.mjs";
11
+ import { a as buildXcode, d as pickXcodeProject, g as swiftPrefixMappingSupported, h as startBuildHeartbeat, i as SWIFT_PREFIX_MAPPING_MIN_SWIFT, l as parseSwiftVersion, r as HEARTBEAT_INTERVAL_MS, s as compilationCacheSettings, u as parseXcodeMajor } from "./xcode-BXn9-xYx.mjs";
12
+ import { createHash } from "node:crypto";
8
13
  import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync } from "node:fs";
9
14
  import { dirname, isAbsolute, join, relative, sep } from "node:path";
15
+ import { ambientContext } from "@stim-cli/core";
10
16
  import { fileURLToPath } from "node:url";
11
- import { createHash } from "node:crypto";
12
17
  import chalk from "chalk";
18
+ //#region src/engine/android-path-limit.ts
19
+ /**
20
+ * CMake's single-config Ninja generator measures an object against CMAKE_OBJECT_PATH_MAX from
21
+ * `<target>.dir/./`, two characters longer than the directory the object is written to, so a
22
+ * shortened object path fits only up to this length.
23
+ * https://github.com/Kitware/CMake/blob/v3.22.1/Source/cmGlobalNinjaGenerator.cxx#L1005-L1013
24
+ */
25
+ const LONGEST_SHORTENED_OBJECT_PATH = 238;
26
+ /**
27
+ * `\android\app\.cxx\<4 hex>\Debug\<8 chars>\<abi>\safeareacontext_autolinked_build/CMakeFiles/react_codegen_safeareacontext.dir/<md5>/RNCSafeAreaViewShadowNode.cpp.o`,
28
+ * measured on the bare e2e fixture and on trailhead (Expo SDK 58, RN 0.88).
29
+ */
30
+ const SAFE_AREA_CONTEXT_OBJECT = {
31
+ target: "react_codegen_safeareacontext",
32
+ tail: 181
33
+ };
34
+ /**
35
+ * react-native-gesture-handler 3 compiles shadow nodes from its `shared/shadowNodes` directory into
36
+ * its codegen library:
37
+ * `\android\app\.cxx\<4 hex>\Debug\<8 chars>\<abi>\rngesturehandler_codegen_autolinked_build/CMakeFiles/react_codegen_rngesturehandler_codegen.dir/<md5>/RNGestureHandlerDetectorShadowNode.cpp.o`,
38
+ * measured on trailhead. https://github.com/appandflow/stim/issues/3641
39
+ */
40
+ const GESTURE_HANDLER_OBJECT = {
41
+ target: "react_codegen_rngesturehandler_codegen",
42
+ tail: 208
43
+ };
44
+ function longestAndroidObject(root) {
45
+ const gestureHandler = resolvePackageJson(root, "react-native-gesture-handler");
46
+ return gestureHandler && existsSync(join(dirname(gestureHandler), "shared", "shadowNodes")) ? GESTURE_HANDLER_OBJECT : SAFE_AREA_CONTEXT_OBJECT;
47
+ }
48
+ /** The ABI name a build for every ABI has to fit; `stim android` narrows a build to the device's. */
49
+ const LONGEST_ANDROID_ABI = "armeabi-v7a";
50
+ function androidPathRoom(root, { abi = null, variant = null, platform = process.platform, object = null } = {}) {
51
+ if (platform !== "win32") return null;
52
+ const { target, tail: objectTail } = object ?? longestAndroidObject(root);
53
+ const abiName = abi ?? LONGEST_ANDROID_ABI;
54
+ const tail = objectTail + (/release$/i.test(variant ?? "") ? 14 : 5) - 5 + abiName.length;
55
+ const longest = root.length + tail;
56
+ if (longest <= LONGEST_SHORTENED_OBJECT_PATH) return null;
57
+ return {
58
+ root,
59
+ abi: abiName,
60
+ target,
61
+ longest,
62
+ maxRootLength: LONGEST_SHORTENED_OBJECT_PATH - tail
63
+ };
64
+ }
65
+ function androidPathRoomMessage({ root, abi, target, longest, maxRootLength }) {
66
+ return `The project root ${root} is ${root.length} characters, so the longest known Android native object path (${target} for ${abi}) reaches ${longest} characters, past the ${LONGEST_SHORTENED_OBJECT_PATH} CMake can shorten it to for the NDK's ninja on Windows; the root can be at most ${maxRootLength} characters.`;
67
+ }
68
+ function androidPathRoomRemedy({ maxRootLength }) {
69
+ return `Move or clone the project to a real path of at most ${maxRootLength} characters, such as C:\\src\\<name>, and run Stim there. A subst drive does not help: Node and Expo autolinking resolve it back to the long path.`;
70
+ }
13
71
  const MAX_MESSAGE_LENGTH = 300;
14
72
  const KOTLIN_URI = /^e:\s+file:\/\/(\/\S+?):(\d+):(\d+)\s+(.*)$/;
15
73
  const KOTLIN_PAREN = /^e:\s+(\S+?):\s*\((\d+),\s*(\d+)\):\s*(.*)$/;
@@ -31,7 +89,7 @@ const BUILD_TAIL = /^(?:BUILD (?:FAILED|SUCCESSFUL) in\b|Deprecated Gradle featu
31
89
  const MAX_CAUSE_LINES = 6;
32
90
  const REMEDIES = [
33
91
  [/JAVA_HOME is (?:set to an invalid directory|not set)/i, "Point JAVA_HOME at a JDK 17 install (`export JAVA_HOME=$(/usr/libexec/java_home -v 17)`) and run again."],
34
- [/SDK location not found|ANDROID_HOME|ANDROID_SDK_ROOT|sdk\.dir/i, "Set ANDROID_HOME to the Android SDK (usually ~/Library/Android/sdk), or write sdk.dir into android/local.properties."],
92
+ [/SDK location not found|ANDROID_HOME|ANDROID_SDK_ROOT|sdk\.dir/i, "Set ANDROID_HOME to the Android SDK (usually ~/Library/Android/sdk on macOS, ~/Android/Sdk on Linux), or write sdk.dir into android/local.properties."],
35
93
  [/licen[cs]es? (?:have not been|has not been) accepted|You have not accepted the license/i, "Accept the SDK licences: `$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --licenses`."],
36
94
  [/Failed to install the following (?:Android )?SDK packages|package is not installed/i, "Install the missing SDK package with `$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager \"<package>\"`."],
37
95
  [/Unsupported class file major version|invalid source release|compiled by a more recent version of the Java|Could not determine java version/i, "The JDK does not match what this project builds with; select JDK 17 (`export JAVA_HOME=$(/usr/libexec/java_home -v 17)`)."],
@@ -275,7 +333,7 @@ function androidSdkRefusal({ sdkPath, sdkExists, hasLocalProperties, localProper
275
333
  return {
276
334
  code: BUILD_ERROR,
277
335
  reason: `No Android SDK at ${sdkPath}.`,
278
- remedy: `Set ANDROID_HOME to the Android SDK (Android Studio installs it at ~/Library/Android/sdk), or write sdk.dir into ${localPropertiesPath}. JAVA_HOME must point at a JDK 17 install as well.`
336
+ remedy: `Set ANDROID_HOME to the Android SDK (Android Studio installs it at ~/Library/Android/sdk on macOS and ~/Android/Sdk on Linux), or write sdk.dir into ${localPropertiesPath}. JAVA_HOME must point at a JDK 17 install as well.`
279
337
  };
280
338
  }
281
339
  function pickDebugApk(files) {
@@ -311,7 +369,7 @@ function variantNameOf(segments) {
311
369
  return (Array.isArray(segments) ? segments : []).filter((s) => typeof s === "string" && s.trim()).map((s, i) => i === 0 ? s : `${s[0].toUpperCase()}${s.slice(1)}`).join("");
312
370
  }
313
371
  function apkInDir(dir) {
314
- const metadata = readOrNull(join(dir, "output-metadata.json"));
372
+ const metadata = readOrNull$1(join(dir, "output-metadata.json"));
315
373
  if (metadata) {
316
374
  const named = parseOutputMetadata(metadata);
317
375
  if (named) {
@@ -539,7 +597,7 @@ function gradleArgs(task, { buildCache = true, projectArgs = [] } = {}) {
539
597
  ...projectArgs
540
598
  ];
541
599
  }
542
- async function buildGradle({ root, logWriter, variant = null, project, task, projectArgs = [], preflightFailure = null, locate }, { spawnFn = null, now = Date.now, env = process.env, buildCache = true, ccache = null, cas = null, pch = "auto", compilerCacheDisabled = false, heartbeatMs = HEARTBEAT_INTERVAL_MS, estimateMs = null, onHeartbeat = (line) => console.error(line), onNote = (line) => console.error(line) } = {}) {
600
+ async function buildGradle({ root, logWriter, variant = null, project, task, projectArgs = [], preflightFailure = null, locate }, { spawnFn = null, now = Date.now, env = ambientContext()?.env ?? process.env, buildCache = true, ccache = null, cas = null, pch = "auto", compilerCacheDisabled = false, heartbeatMs = HEARTBEAT_INTERVAL_MS, estimateMs = null, onHeartbeat = (line) => console.error(line), onNote = (line) => console.error(line) } = {}) {
543
601
  const sdk = androidHome(env);
544
602
  const sdkExists = existsSync(sdk);
545
603
  const refusal = androidSdkRefusal({
@@ -623,7 +681,7 @@ async function buildGradle({ root, logWriter, variant = null, project, task, pro
623
681
  if (ccache) resetStatsLog(ccache.statsLog);
624
682
  let child;
625
683
  try {
626
- child = spawnDeclared(() => spawn(project.gradlew, args, {
684
+ child = spawnDeclared(ambientContext(), () => spawn(project.gradlew, args, {
627
685
  cwd: project.directory,
628
686
  stdio: [
629
687
  "ignore",
@@ -639,7 +697,7 @@ async function buildGradle({ root, logWriter, variant = null, project, task, pro
639
697
  TERM: "dumb",
640
698
  FORCE_COLOR: "0"
641
699
  }
642
- }));
700
+ }), { until: process.platform === "win32" ? "close" : "exit" });
643
701
  } catch (err) {
644
702
  return spawnFailure(err, root, project, now() - startedAt);
645
703
  }
@@ -655,7 +713,9 @@ async function buildGradle({ root, logWriter, variant = null, project, task, pro
655
713
  emit: onHeartbeat,
656
714
  estimateMs
657
715
  });
716
+ const closed = process.platform === "win32" ? new Promise((resolve) => child.once("close", () => resolve())) : void 0;
658
717
  const result = await waitForChild(child);
718
+ await closed;
659
719
  stopHeartbeat();
660
720
  outReader.flush();
661
721
  errReader.flush();
@@ -755,7 +815,7 @@ function safeList(dir) {
755
815
  return [];
756
816
  }
757
817
  }
758
- function readOrNull(file) {
818
+ function readOrNull$1(file) {
759
819
  try {
760
820
  return readFileSync(file, "utf-8");
761
821
  } catch {
@@ -763,4 +823,221 @@ function readOrNull(file) {
763
823
  }
764
824
  }
765
825
  //#endregion
766
- export { buildGradle as a, formatDiagnostic as c, assembleTaskFor as i, BUILD_ERROR as n, parseProductFlavors as o, androidSdkRefusal as r, variantNameOf as s, ASSEMBLE_TASK as t };
826
+ //#region src/integrations/react-native-build.ts
827
+ function gradlewPath(layout) {
828
+ return join(layout.gradleRoot, process.platform === "win32" ? "gradlew.bat" : "gradlew");
829
+ }
830
+ function apkOutputsDir(layout) {
831
+ return join(layout.moduleDir, "build", "outputs", "apk");
832
+ }
833
+ function discoverAndroidProject(root, layout) {
834
+ const dir = layout.gradleRoot;
835
+ if (!existsSync(dir)) return {
836
+ failed: true,
837
+ code: BUILD_ERROR,
838
+ reason: `No ${relative(root, dir) || "."}/ directory in ${root}.`,
839
+ remedy: "Generate it (`npx expo prebuild -p android`, which `stim android` runs itself on an Expo project) or check out the native sources."
840
+ };
841
+ const gradlew = gradlewPath(layout);
842
+ if (!existsSync(gradlew)) return {
843
+ failed: true,
844
+ code: BUILD_ERROR,
845
+ reason: `${gradlew} does not exist, so there is no gradle wrapper to build with.`,
846
+ remedy: `Restore the wrapper (\`gradle wrapper\` in ${relative(root, dir) || "."}/, or regenerate the project with \`npx expo prebuild -p android --clean\`).`
847
+ };
848
+ return {
849
+ androidDir: dir,
850
+ gradlew
851
+ };
852
+ }
853
+ function readProductFlavors(layout) {
854
+ return parseProductFlavors(readOrNull(join(layout.moduleDir, "build.gradle")));
855
+ }
856
+ function productFlavorRefusal({ flavors, variant }) {
857
+ if (variant) return null;
858
+ if (!flavors.known || flavors.dimensions.length === 0) return null;
859
+ let combinations = [[]];
860
+ for (const group of flavors.dimensions) combinations = combinations.flatMap((combination) => group.map((flavor) => combination.concat(flavor)));
861
+ if (combinations.length < 2) return null;
862
+ const count = flavors.dimensions.reduce((total, group) => total + group.length, 0);
863
+ const variants = combinations.map((combination) => variantNameOf(combination.concat("debug")));
864
+ return {
865
+ code: "STIM_BAD_ARG",
866
+ reason: `android/app/build.gradle declares ${count} product flavors, so \`./gradlew ${ASSEMBLE_TASK}\` builds an APK for each of them and nothing says which flavor to install.`,
867
+ remedy: `Pass \`--variant ${variants[0]}\` or set the android.variant setting -- e.g. {"android": {"variant": "${variants[0]}"}} in .stim.json. The debug variants are: ${variants.join(", ")}.`
868
+ };
869
+ }
870
+ function readOrNull(path) {
871
+ try {
872
+ return readFileSync(path, "utf-8");
873
+ } catch {
874
+ return null;
875
+ }
876
+ }
877
+ async function buildAndroid({ root, layout, logWriter, variant = null, abi = null }, options = {}) {
878
+ const project = discoverAndroidProject(root, layout);
879
+ if (project.failed) return {
880
+ ok: false,
881
+ code: project.code,
882
+ reason: project.reason,
883
+ remedy: project.remedy,
884
+ diagnostics: [],
885
+ truncated: 0,
886
+ lastLines: [],
887
+ durationMs: 0
888
+ };
889
+ const room = androidPathRoom(root, {
890
+ abi,
891
+ variant,
892
+ platform: options.platform ?? process.platform
893
+ });
894
+ return buildGradle({
895
+ root,
896
+ logWriter,
897
+ variant,
898
+ project: {
899
+ directory: project.androidDir,
900
+ gradlew: project.gradlew,
901
+ module: layout.module,
902
+ outputsDir: apkOutputsDir(layout)
903
+ },
904
+ task: layout.custom ? `${layout.module}:${assembleTaskFor(variant)}` : assembleTaskFor(variant),
905
+ projectArgs: abi ? [`-PreactNativeArchitectures=${abi}`] : [],
906
+ preflightFailure: room ? {
907
+ code: "STIM_PATH_TOO_LONG",
908
+ reason: androidPathRoomMessage(room),
909
+ remedy: androidPathRoomRemedy(room)
910
+ } : null
911
+ }, options);
912
+ }
913
+ const PREBUILD_REMEDY = "Generate it with `npx expo prebuild -p ios` (stim ios does this automatically for an Expo project with no ios/ directory), or commit the native project.";
914
+ function buildFailure(message, remedy) {
915
+ return { error: {
916
+ code: "STIM_BUILD_FAILED",
917
+ message,
918
+ remedy
919
+ } };
920
+ }
921
+ function discoverXcodeProject(root, dir) {
922
+ let entries;
923
+ try {
924
+ entries = readdirSync(dir);
925
+ } catch {
926
+ return buildFailure(`No ${relative(root, dir) || "."}/ directory in ${root}.`, PREBUILD_REMEDY);
927
+ }
928
+ const picked = pickXcodeProject(entries);
929
+ if (!picked) return buildFailure(`${dir} contains no .xcworkspace and no .xcodeproj.`, PREBUILD_REMEDY);
930
+ return {
931
+ ...picked,
932
+ dir,
933
+ appRoot: root,
934
+ path: join(dir, picked.file)
935
+ };
936
+ }
937
+ function ccacheEnabled(podfileProperties) {
938
+ if (!podfileProperties || typeof podfileProperties !== "object") return false;
939
+ return podfileProperties["apple.ccacheEnabled"] === "true";
940
+ }
941
+ function readPodfileProperties(iosDir) {
942
+ try {
943
+ const parsed = JSON.parse(readFileSync(join(iosDir, "Podfile.properties.json"), "utf-8"));
944
+ return parsed && typeof parsed === "object" ? parsed : null;
945
+ } catch {
946
+ return null;
947
+ }
948
+ }
949
+ const SWIFT_CACHE_MIN_REACT_NATIVE = {
950
+ major: 0,
951
+ minor: 87
952
+ };
953
+ function reactNativeSupportsSwiftCache(version) {
954
+ if (!version) return false;
955
+ const min = SWIFT_CACHE_MIN_REACT_NATIVE;
956
+ return version.major > min.major || version.major === min.major && version.minor >= min.minor;
957
+ }
958
+ function parseReactNativeVersion(packageJson) {
959
+ if (!packageJson || typeof packageJson !== "object") return null;
960
+ const raw = packageJson.version;
961
+ const m = typeof raw === "string" ? /^(\d+)\.(\d+)\./.exec(raw) : null;
962
+ if (!m || m[1] === void 0 || m[2] === void 0) return null;
963
+ return {
964
+ major: parseInt(m[1], 10),
965
+ minor: parseInt(m[2], 10)
966
+ };
967
+ }
968
+ function detectReactNativeVersion(root) {
969
+ const file = resolvePackageJson(root, "react-native");
970
+ if (!file) return null;
971
+ try {
972
+ return parseReactNativeVersion(JSON.parse(readFileSync(file, "utf-8")));
973
+ } catch {
974
+ return null;
975
+ }
976
+ }
977
+ function reactNativeCompilationCacheSettings({ reactNativeVersion = null, ...options }) {
978
+ return compilationCacheSettings({
979
+ ...options,
980
+ swiftCacheCompatible: reactNativeSupportsSwiftCache(reactNativeVersion)
981
+ });
982
+ }
983
+ async function resolveCompilationCacheSettings({ context, root, iosDir, derivedDataPath, exec = null, casPath = sharedCompilationCache(), optimizations = resolveOptimizations({}, {}).ios, onNote = (line) => console.error(line) }) {
984
+ const executor = exec ?? getExecutor();
985
+ context?.signal.throwIfAborted();
986
+ const probeOptions = {
987
+ timeoutMs: 1e4,
988
+ declareFor: context,
989
+ onSpawn: killOnAbort(context?.signal)
990
+ };
991
+ const xcodeMajor = parseXcodeMajor(await executor.runFileQuietAsync("xcodebuild", ["-version"], probeOptions));
992
+ context?.signal.throwIfAborted();
993
+ const ccache = ccacheEnabled(readPodfileProperties(iosDir));
994
+ const probe = xcodeMajor !== null && xcodeMajor >= 26 && !ccache && optimizations.compilationCache && optimizations.swiftCompilationCache !== false;
995
+ const swiftVersion = probe ? parseSwiftVersion(await executor.runFileQuietAsync("xcrun", ["swift", "--version"], probeOptions)) : null;
996
+ context?.signal.throwIfAborted();
997
+ const reactNativeVersion = probe ? detectReactNativeVersion(root) : null;
998
+ const settings = reactNativeCompilationCacheSettings({
999
+ workspaceRoot: root,
1000
+ derivedDataPath,
1001
+ casPath,
1002
+ xcodeMajor,
1003
+ swiftVersion,
1004
+ reactNativeVersion,
1005
+ ccache,
1006
+ optimizations
1007
+ });
1008
+ if (settings.length > 0 && optimizations.compilationCache) {
1009
+ register({
1010
+ dir: casPath,
1011
+ registeredBy: context?.cwd ?? root,
1012
+ name: "Xcode compilation cache",
1013
+ prune: "atomic",
1014
+ note: "shared Xcode compilation cache"
1015
+ });
1016
+ const swift = settings.includes("SWIFT_ENABLE_COMPILE_CACHE=YES") ? settings.includes("SWIFT_ENABLE_PREFIX_MAPPING=YES") ? "Swift on" : "Swift on, unmapped" : swiftVersion && !swiftPrefixMappingSupported(swiftVersion) ? `Swift off, ${swiftVersion.major}.${swiftVersion.minor} < ${SWIFT_PREFIX_MAPPING_MIN_SWIFT.major}.${SWIFT_PREFIX_MAPPING_MIN_SWIFT.minor}` : swiftVersion && reactNativeVersion && !reactNativeSupportsSwiftCache(reactNativeVersion) ? `Swift off, react-native ${reactNativeVersion.major}.${reactNativeVersion.minor} < ${SWIFT_CACHE_MIN_REACT_NATIVE.major}.${SWIFT_CACHE_MIN_REACT_NATIVE.minor}` : "Swift off";
1017
+ onNote(chalk.dim(phaseLine("cache", `compilation cache on (CAS at ${casPath}, ${swift})`)));
1018
+ }
1019
+ return settings;
1020
+ }
1021
+ async function buildIos(inputs) {
1022
+ const { root, iosDir, logWriter, udid, destination, now = () => Date.now() } = inputs;
1023
+ if (!root || typeof root !== "string") throw new TypeError("buildIos requires {root}");
1024
+ if (!logWriter || typeof logWriter.write !== "function") throw new TypeError("buildIos requires {logWriter} with a write() method");
1025
+ if (!udid && !destination) throw new TypeError("buildIos requires {udid} (or an explicit {destination})");
1026
+ const startedAt = now();
1027
+ return buildXcode({
1028
+ ...inputs,
1029
+ startedAt,
1030
+ project: inputs.project ?? discoverXcodeProject(root, iosDir),
1031
+ compilationCache: inputs.compilationCache === void 0 ? ({ derivedDataPath, exec }) => resolveCompilationCacheSettings({
1032
+ context: inputs.context,
1033
+ root,
1034
+ iosDir,
1035
+ derivedDataPath,
1036
+ exec,
1037
+ optimizations: inputs.optimizations,
1038
+ onNote: inputs.onNote
1039
+ }) : inputs.compilationCache
1040
+ });
1041
+ }
1042
+ //#endregion
1043
+ export { discoverXcodeProject as a, readProductFlavors as c, buildGradle as d, formatDiagnostic as f, androidPathRoomRemedy as h, ccacheEnabled as i, androidSdkRefusal as l, androidPathRoomMessage as m, buildAndroid as n, gradlewPath as o, androidPathRoom as p, buildIos as r, productFlavorRefusal as s, apkOutputsDir as t, assembleTaskFor as u };
@@ -0,0 +1,234 @@
1
+ import { t as getExecutor } from "./exec-DEoAhcze.mjs";
2
+ import { l as phaseLine } from "./command-output-gwpm28fu.mjs";
3
+ import { K as resolveIosProjectDir, W as resolveAndroidLayout } from "./settings-C7O8A6ZI.mjs";
4
+ import { v as detectIsExpo } from "./project-wM_XFTvE.mjs";
5
+ import { b as bundlerPin } from "./xcode-BXn9-xYx.mjs";
6
+ import { a as iosToolchainAsync, n as androidToolchain, r as androidToolchainAsync, t as androidRequirements } from "./toolchain-DpJMHq0n.mjs";
7
+ import { a as reactNativeDoctorFindings, i as mainCheckoutProjectRoot, n as detectFingerprintParity, r as detectLinkedLibraryGitMetadata, s as repairCxxLauncherState, t as checkMainCheckout } from "./doctor-Bo7BXLux.mjs";
8
+ import { existsSync, readdirSync } from "node:fs";
9
+ import { join, relative } from "node:path";
10
+ //#region src/diagnostics/doctor-ios-architectures.ts
11
+ const COMPILED_PRODUCTS = /* @__PURE__ */ new Set([
12
+ "com.apple.product-type.application",
13
+ "com.apple.product-type.application.on-demand-install-capable",
14
+ "com.apple.product-type.app-extension",
15
+ "com.apple.product-type.framework",
16
+ "com.apple.product-type.library.static",
17
+ "com.apple.product-type.library.dynamic"
18
+ ]);
19
+ function architectureList(value) {
20
+ if (typeof value !== "string" || /[^\w\s-]/.test(value)) return null;
21
+ return [...new Set(value.split(/\s+/).filter(Boolean))];
22
+ }
23
+ function parseIosDebugArchitectures(output) {
24
+ const report = {
25
+ affected: [],
26
+ unknown: false
27
+ };
28
+ let data;
29
+ try {
30
+ data = JSON.parse(output);
31
+ } catch {
32
+ return {
33
+ ...report,
34
+ unknown: true
35
+ };
36
+ }
37
+ if (!Array.isArray(data) || data.length === 0) return {
38
+ ...report,
39
+ unknown: true
40
+ };
41
+ let inspected = false;
42
+ for (const entry of data) {
43
+ if (!entry || typeof entry !== "object" || entry.error || !entry.buildSettings) {
44
+ report.unknown = true;
45
+ continue;
46
+ }
47
+ const settings = entry.buildSettings;
48
+ if (settings.CONFIGURATION !== "Debug" || settings.PLATFORM_NAME !== "iphonesimulator") {
49
+ report.unknown = true;
50
+ continue;
51
+ }
52
+ if (!settings.PRODUCT_TYPE) continue;
53
+ if (settings.PRODUCT_TYPE === "com.apple.product-type.bundle") {
54
+ inspected = true;
55
+ continue;
56
+ }
57
+ if (!COMPILED_PRODUCTS.has(settings.PRODUCT_TYPE)) {
58
+ report.unknown = true;
59
+ continue;
60
+ }
61
+ inspected = true;
62
+ if (settings.ONLY_ACTIVE_ARCH === "YES") continue;
63
+ const archs = architectureList(settings.ARCHS);
64
+ const valid = settings.VALID_ARCHS === void 0 ? archs : architectureList(settings.VALID_ARCHS);
65
+ const excluded = architectureList(settings.EXCLUDED_ARCHS ?? "");
66
+ if (settings.ONLY_ACTIVE_ARCH !== "NO" || !archs?.length || !valid || !excluded || typeof entry.target !== "string") {
67
+ report.unknown = true;
68
+ continue;
69
+ }
70
+ const architectures = archs.filter((arch) => valid.includes(arch) && !excluded.includes(arch));
71
+ if (architectures.length > 1) report.affected.push({
72
+ target: entry.target,
73
+ architectures
74
+ });
75
+ }
76
+ return {
77
+ ...report,
78
+ unknown: report.unknown || !inspected
79
+ };
80
+ }
81
+ async function inspectIosDebugArchitectures(projectRoot, iosProjectPath = "ios") {
82
+ const iosRoot = join(projectRoot, iosProjectPath);
83
+ if (!existsSync(iosRoot)) return [];
84
+ const findings = [];
85
+ const unknown = [];
86
+ let projects;
87
+ try {
88
+ projects = readdirSync(iosRoot).filter((name) => name.endsWith(".xcodeproj")).toSorted().map((name) => join(iosRoot, name));
89
+ } catch {
90
+ projects = [];
91
+ }
92
+ if (!projects.length) unknown.push("app project");
93
+ const pods = join(iosRoot, "Pods", "Pods.xcodeproj");
94
+ if (existsSync(pods)) projects.push(pods);
95
+ else if (existsSync(join(iosRoot, "Podfile"))) unknown.push("Pods project (not generated)");
96
+ const deadline = Date.now() + 6e4;
97
+ for (const project of projects) {
98
+ const label = relative(projectRoot, project);
99
+ const timeoutMs = Math.min(3e4, deadline - Date.now());
100
+ if (timeoutMs <= 0) {
101
+ unknown.push(label);
102
+ continue;
103
+ }
104
+ try {
105
+ const report = parseIosDebugArchitectures(await getExecutor().runFileAsync("xcodebuild", [
106
+ "-project",
107
+ project,
108
+ "-alltargets",
109
+ "-configuration",
110
+ "Debug",
111
+ "-sdk",
112
+ "iphonesimulator",
113
+ "-showBuildSettings",
114
+ "-json",
115
+ "-disableAutomaticPackageResolution",
116
+ "-skipPackageUpdates"
117
+ ], {
118
+ cwd: iosRoot,
119
+ timeoutMs
120
+ }));
121
+ if (report.unknown) unknown.push(label);
122
+ if (report.affected.length) {
123
+ const targets = report.affected.slice(0, 5).map(({ target, architectures }) => `${target} (${architectures.join(", ")})`).join("; ");
124
+ findings.push({
125
+ code: "ios-debug-architectures",
126
+ level: "cost",
127
+ title: "iOS Debug targets build multiple simulator architectures",
128
+ detail: `${label}: ${report.affected.length} Debug target(s) resolve ONLY_ACTIVE_ARCH=NO with multiple architectures after exclusions: ${targets}${report.affected.length > 5 ? `; plus ${report.affected.length - 5} more` : ""}. This can compile extra native code when targeting one simulator.`,
129
+ fix: "Review the Debug ONLY_ACTIVE_ARCH override in the project, xcconfig, or Podfile post_install helpers. Prefer YES for local Debug simulator builds where appropriate; preserve intentional Release and distribution settings. Regenerate Pods through the project workflow after changing a helper, then rerun stim doctor --platform ios. Doctor --fix does not change architecture settings."
130
+ });
131
+ }
132
+ } catch {
133
+ unknown.push(label);
134
+ }
135
+ }
136
+ if (unknown.length) findings.push({
137
+ code: "ios-debug-architectures-unknown",
138
+ level: "note",
139
+ title: "iOS Debug architecture settings could not be fully inspected",
140
+ detail: `Effective Debug simulator settings are unavailable for ${unknown.join(", ")}. Architecture policy is not verified for those targets. Metadata inspection has a 60-second total budget.`,
141
+ fix: "Ensure Xcode can read the generated app and Pods projects, then rerun stim doctor --platform ios. Doctor does not evaluate Podfiles or install Pods to inspect architecture settings."
142
+ });
143
+ return findings;
144
+ }
145
+ //#endregion
146
+ //#region src/integrations/react-native-doctor.ts
147
+ function reactNativeProjectDoctor(root) {
148
+ return {
149
+ inspect: reactNativeDoctorFindings,
150
+ async inspectAsync({ options: { platform, host = process.platform, machineSettings, operation }, settings, repoRoot }) {
151
+ const iosProjectPath = resolveIosProjectDir(settings, root).relative;
152
+ const source = machineSettings?.corrupt ? [] : await checkMainCheckout(root, {
153
+ platform,
154
+ localIos: platform !== "android" && host === "darwin",
155
+ iosProjectPath,
156
+ androidLayout: resolveAndroidLayout(settings, root, repoRoot ?? root)
157
+ });
158
+ const architectures = !machineSettings?.corrupt && platform !== "android" && host === "darwin" ? await inspectIosDebugArchitectures(await mainCheckoutProjectRoot(root), iosProjectPath) : [];
159
+ const parity = await detectFingerprintParity(root, {
160
+ platform,
161
+ iosProjectPath,
162
+ operation
163
+ });
164
+ const linkedGit = await detectLinkedLibraryGitMetadata(root, {
165
+ platform,
166
+ operation
167
+ });
168
+ return [
169
+ ...source,
170
+ ...architectures,
171
+ parity,
172
+ linkedGit?.code === parity?.code ? null : linkedGit
173
+ ].filter((finding) => finding !== null);
174
+ },
175
+ offloadTargets({ options: { platform, host = process.platform, operation }, settings, repoRoot }, iosRuntime) {
176
+ const checksIos = platform !== "android" && host === "darwin";
177
+ const androidDir = resolveAndroidLayout(settings, root, repoRoot ?? root).gradleRoot;
178
+ const checksAndroid = platform === "android" || platform === void 0 && (existsSync(androidDir) || detectIsExpo(root));
179
+ if (!checksIos && !checksAndroid) return null;
180
+ return async () => {
181
+ const targets = [];
182
+ if (checksIos) {
183
+ const [local, runtime] = await Promise.all([iosToolchainAsync(root), iosRuntime()]);
184
+ targets.push({
185
+ platform: "ios",
186
+ local,
187
+ runtime,
188
+ cocoapodsPinned: bundlerPin(root) !== null
189
+ });
190
+ }
191
+ if (checksAndroid) targets.push({
192
+ platform: "android",
193
+ local: operation ? await androidToolchainAsync(operation.env) : androidToolchain(),
194
+ requires: androidRequirements(root)
195
+ });
196
+ return targets;
197
+ };
198
+ },
199
+ repair: (platform, settings, repoRoot) => platform === "ios" ? {
200
+ removed: [],
201
+ refused: []
202
+ } : repairCxxLauncherState(root, settings, resolveAndroidLayout(settings, root, repoRoot ?? root)),
203
+ successLines: reactNativeDoctorSuccessLines
204
+ };
205
+ }
206
+ function reactNativeDoctorSuccessLines(platform) {
207
+ const lines = [
208
+ "",
209
+ "Project",
210
+ phaseLine("project", "source checkout, dependencies, local upstream, nested worktrees Watchman would crawl")
211
+ ];
212
+ if (platform !== "android") {
213
+ lines.push("", "iOS");
214
+ lines.push(phaseLine("setup", "CocoaPods, warm state, effective Debug simulator architectures"));
215
+ lines.push(phaseLine("caches", "Metro, Xcode compilation, ccache, build provider"));
216
+ lines.push(phaseLine("devices", "remote device, SimSlim profile"));
217
+ }
218
+ if (platform !== "ios") {
219
+ lines.push("", "Android");
220
+ lines.push(phaseLine("setup", "Android SDK, warm state"));
221
+ lines.push(phaseLine("caches", "Metro, Gradle, ccache, build provider"));
222
+ lines.push(phaseLine("devices", "remote device"));
223
+ }
224
+ lines.push("", "Expo and React Native");
225
+ lines.push(phaseLine("services", "EAS session"));
226
+ lines.push(phaseLine("fingerprint", "parity when dependencies are absent"));
227
+ lines.push("", "Handled automatically");
228
+ const suppliedCaches = platform === "ios" ? "Metro transform store, Xcode compilation cache" : platform === "android" ? "Metro transform store, Gradle build cache, ccache" : "Metro transform store, Xcode compilation cache, Gradle build cache, ccache";
229
+ lines.push(phaseLine("caches", suppliedCaches));
230
+ lines.push(phaseLine("meaning", "missing project cache settings are healthy"));
231
+ return lines;
232
+ }
233
+ //#endregion
234
+ export { reactNativeProjectDoctor };