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
@@ -0,0 +1,896 @@
1
+ import { c as declareSpawnsOn, d as spawnDeclared, f as stopDeclaringSpawnsOn, t as getExecutor, x as ownership_claim_exports } from "./exec-DEoAhcze.mjs";
2
+ import { u as workspaceDerivedData } from "./paths-DQtTgsBf.mjs";
3
+ import { t as createLineReader } from "./process-output-Fpl8PYi8.mjs";
4
+ import { a as formatElapsed, l as phaseLine } from "./command-output-gwpm28fu.mjs";
5
+ import { a as killOnAbort } from "./operation-exec-BW0em61G.mjs";
6
+ import { d as runCancellationSignal, h as shareCompilationCache } from "./native-run-NwUuxbkg.mjs";
7
+ import { p as resolveOptimizations } from "./errors-ccaPc4ox.mjs";
8
+ import { t as cleanLine } from "./server-expo-CrjB29pq.mjs";
9
+ import { createHash } from "node:crypto";
10
+ import { existsSync, readFileSync, readdirSync, realpathSync, statSync } from "node:fs";
11
+ import { basename, isAbsolute, join, relative, resolve, sep } from "node:path";
12
+ import { ambientContext } from "@stim-cli/core";
13
+ //#region src/engine/bundler.ts
14
+ const COCOAPODS_SPEC = /^ {4}cocoapods \(/m;
15
+ function bundlerPin(root) {
16
+ const gemfile = join(root, "Gemfile");
17
+ const lockfile = join(root, "Gemfile.lock");
18
+ if (!existsSync(gemfile)) return null;
19
+ let lock;
20
+ try {
21
+ lock = readFileSync(lockfile, "utf-8");
22
+ } catch {
23
+ return null;
24
+ }
25
+ if (!COCOAPODS_SPEC.test(lock)) return null;
26
+ return {
27
+ gemfile,
28
+ lockfile
29
+ };
30
+ }
31
+ function podInstallCommand(root, ...args) {
32
+ const pod = [
33
+ "pod",
34
+ "install",
35
+ ...args
36
+ ].join(" ");
37
+ return bundlerPin(root) ? `bundle exec ${pod}` : pod;
38
+ }
39
+ const BUILD_FAILED = "** BUILD FAILED **";
40
+ const POSITIONED = /^(\S[^\t]*?):(\d+):(?:(\d+):)?\s*(?:fatal\s+)?error:\s+(.+)$/;
41
+ const UNPOSITIONED = /^(\S[^\t]*?)?\berror:\s+(.+)$/;
42
+ const LD_ERROR = /^ld:\s+(?!warning:)(.+)$/;
43
+ const UNDEFINED_HEADER = /^(?:ld:\s+)?Undefined symbols?(?:\s+for architecture\s+\S+)?:\s*$/;
44
+ const UNDEFINED_SYMBOL = /^\s+"?([^",]+)"?,\s+referenced from:\s*$/;
45
+ function undefinedSymbolMessage(symbol) {
46
+ return `Undefined symbol: ${symbol}`;
47
+ }
48
+ const PODS_OUT_OF_SYNC = /The sandbox is not in sync with the Podfile\.lock/;
49
+ const SIGNING = [
50
+ /No profiles for '.*' were found/,
51
+ /requires a development team/i,
52
+ /[Cc]ode ?[Ss]igning [Ee]rror/,
53
+ /No signing certificate/i,
54
+ /code signing is required/i,
55
+ /errSecInternalComponent/,
56
+ /Provisioning profile .* doesn't (?:include|match)/i
57
+ ];
58
+ const NO_SUCH_SCHEME = /does not contain a scheme named/;
59
+ const CAS_CORRUPT = /not a IncludeTreeRoot node kind/;
60
+ const COMPILATION_CACHE_CORRUPTION = /OnDiskCAS: corrupt internal reference|CAS operation failed|not a IncludeTreeRoot node kind/;
61
+ const DEVICE_SIGNING_REMEDY = "Set a team for the target's configuration in Xcode > Signing & Capabilities, then run `stim device provision ios`, which lists the Apple Developer account changes and asks before making them (agents run it only with the user's go-ahead), or build once from Xcode to install the profile. Builds never pass -allowProvisioningUpdates, because registering a device or minting a profile changes your Apple Developer account.";
62
+ const SIMULATOR_SIGNING_REMEDY = "Stim builds for the simulator here, which needs no signing. Check CODE_SIGNING_REQUIRED / DEVELOPMENT_TEAM in the target's configuration, or build for a phone with `stim ios --device`.";
63
+ function remedyFor(message, root, sdk) {
64
+ if (CAS_CORRUPT.test(message)) return "The compilation cache holds a damaged object. Run `stim gc --delete --cache \"compilation cache\"` to empty that cache, then build again. The next build is a cold one.";
65
+ if (PODS_OUT_OF_SYNC.test(message)) return `Run \`${root ? podInstallCommand(root) : "pod install"}\` in ios/ (stim ios does this when Podfile.lock and Pods/Manifest.lock disagree), then build again.`;
66
+ if (NO_SUCH_SCHEME.test(message)) return "Run `xcodebuild -list` in ios/ to see the schemes this project defines, and share the app scheme so it is visible to the build.";
67
+ for (const pattern of SIGNING) if (pattern.test(message)) return sdk.startsWith("iphoneos") ? DEVICE_SIGNING_REMEDY : SIMULATOR_SIGNING_REMEDY;
68
+ return null;
69
+ }
70
+ function fileFromPrefix(prefix) {
71
+ const trimmed = String(prefix).trim().replace(/:$/, "");
72
+ if (!trimmed) return null;
73
+ const head = (trimmed.split(": ")[0] ?? "").trim();
74
+ if (!head.includes("/")) return null;
75
+ return head;
76
+ }
77
+ function makeDiagnostic({ file = null, line = null, column = null, message }, root, sdk) {
78
+ const text = String(message).trim();
79
+ const out = { message: text };
80
+ if (file) out.file = file;
81
+ if (line !== null && line !== void 0) out.line = line;
82
+ if (column !== null && column !== void 0) out.column = column;
83
+ out.message = text;
84
+ const remedy = remedyFor(text, root, sdk);
85
+ if (remedy) out.remedy = remedy;
86
+ return out;
87
+ }
88
+ function dedupeKey(d) {
89
+ return `${d.file || ""}|${d.line || ""}|${d.column || ""}|${d.message}`;
90
+ }
91
+ function createXcodeDiagnosticCollector(root = null, sdk = "iphonesimulator") {
92
+ const out = [];
93
+ const seen = /* @__PURE__ */ new Set();
94
+ let finished = false;
95
+ let inUndefinedSymbols = false;
96
+ const add = (d) => {
97
+ const key = dedupeKey(d);
98
+ if (seen.has(key)) return;
99
+ seen.add(key);
100
+ out.push(d);
101
+ };
102
+ const push = (line) => {
103
+ if (finished) return;
104
+ const raw = line.replace(/\r$/, "");
105
+ if (inUndefinedSymbols) {
106
+ const sym = UNDEFINED_SYMBOL.exec(raw);
107
+ if (sym) {
108
+ const symbol = sym[1];
109
+ if (symbol !== void 0) add(makeDiagnostic({ message: undefinedSymbolMessage(symbol) }, root, sdk));
110
+ return;
111
+ }
112
+ if (/^\s+\S/.test(line) && !/^\S/.test(line)) return;
113
+ inUndefinedSymbols = false;
114
+ }
115
+ if (raw.includes(BUILD_FAILED)) {
116
+ finished = true;
117
+ return;
118
+ }
119
+ if (UNDEFINED_HEADER.test(raw)) {
120
+ inUndefinedSymbols = true;
121
+ return;
122
+ }
123
+ const ld = LD_ERROR.exec(raw);
124
+ if (ld) {
125
+ add(makeDiagnostic({ message: `ld: ${ld[1]}` }, root, sdk));
126
+ return;
127
+ }
128
+ const positioned = POSITIONED.exec(raw);
129
+ if (positioned) {
130
+ const posMsg = positioned[4];
131
+ if (posMsg === void 0) return;
132
+ add(makeDiagnostic({
133
+ file: positioned[1],
134
+ line: Number(positioned[2]),
135
+ column: positioned[3] === void 0 ? null : Number(positioned[3]),
136
+ message: posMsg
137
+ }, root, sdk));
138
+ return;
139
+ }
140
+ const plain = UNPOSITIONED.exec(raw);
141
+ if (plain) {
142
+ const plainMsg = plain[2];
143
+ if (plainMsg === void 0) return;
144
+ add(makeDiagnostic({
145
+ file: fileFromPrefix(plain[1] || ""),
146
+ message: plainMsg
147
+ }, root, sdk));
148
+ }
149
+ };
150
+ return {
151
+ push,
152
+ diagnostics: out
153
+ };
154
+ }
155
+ function capDiagnostics(diagnostics, max = 10) {
156
+ const list = Array.isArray(diagnostics) ? diagnostics : [];
157
+ if (list.length <= max) return {
158
+ diagnostics: list.slice(),
159
+ truncated: 0
160
+ };
161
+ return {
162
+ diagnostics: list.slice(0, max),
163
+ truncated: list.length - max
164
+ };
165
+ }
166
+ function describeDiagnostic(diagnostic) {
167
+ if (!diagnostic || typeof diagnostic !== "object") return "";
168
+ const { file, line, column, message } = diagnostic;
169
+ if (!file) return String(message ?? "");
170
+ return `${file}${line ? column ? `:${line}:${column}` : `:${line}` : ""}: ${message}`;
171
+ }
172
+ //#endregion
173
+ //#region src/engine/xcode.ts
174
+ function pickXcodeProject(entries) {
175
+ const names = (Array.isArray(entries) ? entries : []).filter((e) => typeof e === "string");
176
+ const workspaces = names.filter((e) => e.endsWith(".xcworkspace")).toSorted();
177
+ const projects = names.filter((e) => e.endsWith(".xcodeproj")).toSorted();
178
+ if (workspaces.length > 0) {
179
+ const projectNames = new Set(projects.map((p) => basename(p, ".xcodeproj")));
180
+ const file = workspaces.find((w) => projectNames.has(basename(w, ".xcworkspace"))) || workspaces[0];
181
+ if (file === void 0) return null;
182
+ return {
183
+ kind: "workspace",
184
+ flag: "-workspace",
185
+ file,
186
+ name: basename(file, ".xcworkspace")
187
+ };
188
+ }
189
+ if (projects.length > 0) {
190
+ const file = projects[0];
191
+ if (file === void 0) return null;
192
+ return {
193
+ kind: "project",
194
+ flag: "-project",
195
+ file,
196
+ name: basename(file, ".xcodeproj")
197
+ };
198
+ }
199
+ return null;
200
+ }
201
+ function parseSchemeList(text) {
202
+ const empty = {
203
+ name: null,
204
+ schemes: []
205
+ };
206
+ if (typeof text !== "string") return empty;
207
+ const start = text.indexOf("{");
208
+ const end = text.lastIndexOf("}");
209
+ if (start < 0 || end <= start) return empty;
210
+ let data;
211
+ try {
212
+ data = JSON.parse(text.slice(start, end + 1));
213
+ } catch {
214
+ return empty;
215
+ }
216
+ if (!data || typeof data !== "object") return empty;
217
+ const record = data;
218
+ const container = record.workspace || record.project;
219
+ if (!container || typeof container !== "object") return empty;
220
+ const info = container;
221
+ const schemes = Array.isArray(info.schemes) ? info.schemes.filter((s) => typeof s === "string" && s.trim() !== "") : [];
222
+ return {
223
+ name: typeof info.name === "string" ? info.name : null,
224
+ schemes
225
+ };
226
+ }
227
+ const TEST_SCHEME = /(?:UI)?Tests$/;
228
+ function pickScheme(schemes, containerName) {
229
+ const list = (Array.isArray(schemes) ? schemes : []).filter((s) => typeof s === "string" && s.trim() !== "");
230
+ if (list.length === 0) return null;
231
+ const name = typeof containerName === "string" ? containerName.trim() : "";
232
+ if (name) {
233
+ const exact = list.find((s) => s === name);
234
+ if (exact) return exact;
235
+ const insensitive = list.find((s) => s.toLowerCase() === name.toLowerCase());
236
+ if (insensitive) return insensitive;
237
+ }
238
+ const app = list.filter((s) => !TEST_SCHEME.test(s));
239
+ return app.length === 1 ? app[0] : null;
240
+ }
241
+ const LIST_TIMEOUT_MS = 18e4;
242
+ async function probe(executor, file, args, options) {
243
+ const context = ambientContext();
244
+ context?.signal.throwIfAborted();
245
+ try {
246
+ return await executor.runFileAsync(file, args, {
247
+ ...options,
248
+ declareFor: context,
249
+ onSpawn: killOnAbort(context?.signal)
250
+ });
251
+ } finally {
252
+ context?.signal.throwIfAborted();
253
+ }
254
+ }
255
+ async function listSchemes(project, { exec = null } = {}) {
256
+ const executor = exec || getExecutor();
257
+ try {
258
+ return parseSchemeList(await probe(executor, "xcodebuild", [
259
+ project.flag,
260
+ project.path,
261
+ "-list",
262
+ "-json"
263
+ ], { timeoutMs: LIST_TIMEOUT_MS }));
264
+ } catch {
265
+ return null;
266
+ }
267
+ }
268
+ async function resolveScheme(project, { exec = null, scheme: requested = null } = {}) {
269
+ const listing = await listSchemes(project, { exec });
270
+ if (listing === null) return { error: {
271
+ code: "STIM_NO_SCHEME",
272
+ message: `Could not list schemes for ${project.path}.`,
273
+ remedy: `Run \`xcodebuild ${project.flag} ${project.path} -list\` to see what it reports.`
274
+ } };
275
+ if (requested !== null) {
276
+ if (listing.schemes.includes(requested)) return {
277
+ scheme: requested,
278
+ schemes: listing.schemes
279
+ };
280
+ return { error: {
281
+ code: "STIM_NO_SCHEME",
282
+ message: `No shared Xcode scheme named ${JSON.stringify(requested)} in ${project.path}. Available schemes: ${listing.schemes.join(", ") || "none"}.`,
283
+ remedy: "Pass an exact available name with --scheme or set it in ios.scheme, or share the intended app scheme in Xcode."
284
+ } };
285
+ }
286
+ let scheme = pickScheme(listing.schemes, listing.name || project.name);
287
+ if (!scheme && project.dir) try {
288
+ const app = JSON.parse(readFileSync(join(project.appRoot ?? join(project.dir, ".."), "app.json"), "utf8"));
289
+ scheme = pickScheme(listing.schemes, app?.name);
290
+ } catch {}
291
+ if (!scheme) {
292
+ const found = listing.schemes.length ? listing.schemes.join(", ") : "none";
293
+ return { error: {
294
+ code: "STIM_NO_SCHEME",
295
+ message: `Could not select an app scheme in ${project.path} (schemes: ${found}).`,
296
+ remedy: listing.schemes.length > 0 ? "Pass --scheme <name>, or set ios.scheme, to select the intended shared app scheme. Stim does not guess between unmatched schemes." : "Share the app scheme in Xcode (Product > Scheme > Manage Schemes, tick Shared) so xcodebuild can see it."
297
+ } };
298
+ }
299
+ return {
300
+ scheme,
301
+ schemes: listing.schemes
302
+ };
303
+ }
304
+ const PREFIX_MAP_TARGET = "/^src";
305
+ function prefixMapping(workspaceRoot) {
306
+ return `${String(workspaceRoot).replace(/\/+$/, "")}=${PREFIX_MAP_TARGET}`;
307
+ }
308
+ function compilationPrefixMappings(workspaceRoot, derivedDataPath) {
309
+ const source = resolve(workspaceRoot);
310
+ const derived = resolve(derivedDataPath);
311
+ const mappings = [prefixMapping(source)];
312
+ const rel = relative(source, derived);
313
+ if (rel === ".." || rel.startsWith(`..${sep}`) || isAbsolute(rel)) mappings.push(`${derived}=/^derived-data`);
314
+ return mappings.map((mapping) => /[\s"\\]/.test(mapping) ? `"${mapping.replace(/["\\]/g, "\\$&")}"` : mapping).join(" ");
315
+ }
316
+ const SWIFT_PREFIX_MAPPING_MIN_SWIFT = {
317
+ major: 6,
318
+ minor: 4
319
+ };
320
+ function swiftPrefixMappingSupported(version) {
321
+ if (!version) return false;
322
+ const min = SWIFT_PREFIX_MAPPING_MIN_SWIFT;
323
+ return version.major > min.major || version.major === min.major && version.minor >= min.minor;
324
+ }
325
+ function compilationCacheSettings({ workspaceRoot, derivedDataPath, casPath, xcodeMajor, swiftVersion = null, swiftCacheCompatible = false, ccache = false, optimizations = resolveOptimizations({}, {}).ios }) {
326
+ if (xcodeMajor === null || xcodeMajor === void 0) return [];
327
+ if (xcodeMajor < 26) return [];
328
+ if (ccache) return [];
329
+ const swiftMappable = swiftPrefixMappingSupported(swiftVersion);
330
+ const auto = swiftMappable && swiftCacheCompatible;
331
+ const swift = optimizations.compilationCache && (optimizations.swiftCompilationCache ?? auto);
332
+ const mappings = optimizations.prefixMapping ? compilationPrefixMappings(workspaceRoot, derivedDataPath) : "";
333
+ return [
334
+ `COMPILATION_CACHE_ENABLE_CACHING=${optimizations.compilationCache ? "YES" : "NO"}`,
335
+ `COMPILATION_CACHE_CAS_PATH=${casPath}`,
336
+ `SWIFT_ENABLE_COMPILE_CACHE=${swift ? "YES" : "NO"}`,
337
+ `CLANG_ENABLE_PREFIX_MAPPING=${optimizations.prefixMapping ? "YES" : "NO"}`,
338
+ `CLANG_OTHER_PREFIX_MAPPINGS=${mappings}`,
339
+ ...swift && swiftMappable && optimizations.prefixMapping ? ["SWIFT_ENABLE_PREFIX_MAPPING=YES", `SWIFT_OTHER_PREFIX_MAPPINGS=${mappings}`] : ["SWIFT_ENABLE_PREFIX_MAPPING=NO"]
340
+ ];
341
+ }
342
+ function parseSwiftVersion(output) {
343
+ const m = /\bSwift version (\d+)\.(\d+)/.exec(String(output || ""));
344
+ if (!m || m[1] === void 0 || m[2] === void 0) return null;
345
+ const major = parseInt(m[1], 10);
346
+ const minor = parseInt(m[2], 10);
347
+ return Number.isFinite(major) && Number.isFinite(minor) ? {
348
+ major,
349
+ minor
350
+ } : null;
351
+ }
352
+ function parseXcodeMajor(output) {
353
+ const m = /^Xcode\s+(\d+)/m.exec(String(output || ""));
354
+ if (!m) return null;
355
+ const digits = m[1];
356
+ if (digits === void 0) return null;
357
+ const major = parseInt(digits, 10);
358
+ return Number.isFinite(major) ? major : null;
359
+ }
360
+ async function detectXcodeMajorAsync(exec = null) {
361
+ return parseXcodeMajor(await (exec || getExecutor()).runFileQuietAsync("xcodebuild", ["-version"], { timeoutMs: 1e4 }));
362
+ }
363
+ function xcodebuildArgs({ project, scheme, udid = null, destination = null, configuration = "Debug", sdk = "iphonesimulator", derivedDataPath, extraArgs = [], buildSettings = [] }) {
364
+ return [
365
+ project.flag,
366
+ project.path,
367
+ "-scheme",
368
+ scheme,
369
+ "-configuration",
370
+ configuration,
371
+ "-sdk",
372
+ sdk,
373
+ "-destination",
374
+ destination || `id=${udid}`,
375
+ "-derivedDataPath",
376
+ derivedDataPath,
377
+ ...extraArgs,
378
+ "build",
379
+ ...buildSettings
380
+ ];
381
+ }
382
+ function productsDir(derivedDataPath, { configuration = "Debug", sdk = "iphonesimulator" } = {}) {
383
+ return join(derivedDataPath, "Build", "Products", `${configuration}-${sdk}`);
384
+ }
385
+ function pickAppBundle(entries, preferredName = null) {
386
+ const apps = (Array.isArray(entries) ? entries : []).filter((e) => typeof e === "string" && e.endsWith(".app")).toSorted();
387
+ if (apps.length === 0) return null;
388
+ if (preferredName) {
389
+ const wanted = `${preferredName}.app`;
390
+ const exact = apps.find((a) => a === wanted);
391
+ if (exact) return exact;
392
+ }
393
+ return apps[0];
394
+ }
395
+ function findAppBundle(dir, preferredName = null) {
396
+ let entries;
397
+ try {
398
+ entries = readdirSync(dir);
399
+ } catch {
400
+ return null;
401
+ }
402
+ const app = pickAppBundle(entries, preferredName);
403
+ return app ? join(dir, app) : null;
404
+ }
405
+ function parseBundleId(plistJson) {
406
+ if (typeof plistJson !== "string") return null;
407
+ let data;
408
+ try {
409
+ data = JSON.parse(plistJson);
410
+ } catch {
411
+ return null;
412
+ }
413
+ if (!data || typeof data !== "object") return null;
414
+ const id = data.CFBundleIdentifier;
415
+ return typeof id === "string" && id.trim() !== "" ? id.trim() : null;
416
+ }
417
+ async function readBundleId(appPath, { exec = null } = {}) {
418
+ const executor = exec || getExecutor();
419
+ try {
420
+ const id = parseBundleId(await probe(executor, "plutil", [
421
+ "-convert",
422
+ "json",
423
+ "-o",
424
+ "-",
425
+ join(appPath, "Info.plist")
426
+ ], { timeoutMs: 1e4 }));
427
+ if (id) return id;
428
+ } catch {}
429
+ try {
430
+ const value = await probe(executor, "defaults", [
431
+ "read",
432
+ join(appPath, "Info"),
433
+ "CFBundleIdentifier"
434
+ ], { timeoutMs: 1e4 });
435
+ const trimmed = String(value).trim();
436
+ return trimmed === "" ? null : trimmed;
437
+ } catch {
438
+ return null;
439
+ }
440
+ }
441
+ function parseBundleExecutable(plistJson) {
442
+ if (typeof plistJson !== "string") return null;
443
+ let data;
444
+ try {
445
+ data = JSON.parse(plistJson);
446
+ } catch {
447
+ return null;
448
+ }
449
+ if (!data || typeof data !== "object") return null;
450
+ const name = data.CFBundleExecutable;
451
+ return typeof name === "string" && name.trim() !== "" ? name.trim() : null;
452
+ }
453
+ async function readBundleExecutable(appPath, { exec = null } = {}) {
454
+ const executor = exec || getExecutor();
455
+ try {
456
+ const name = parseBundleExecutable(await probe(executor, "plutil", [
457
+ "-convert",
458
+ "json",
459
+ "-o",
460
+ "-",
461
+ join(appPath, "Info.plist")
462
+ ], { timeoutMs: 1e4 }));
463
+ if (name) return name;
464
+ } catch {}
465
+ try {
466
+ const value = await probe(executor, "defaults", [
467
+ "read",
468
+ join(appPath, "Info"),
469
+ "CFBundleExecutable"
470
+ ], { timeoutMs: 1e4 });
471
+ const trimmed = String(value).trim();
472
+ return trimmed === "" ? null : trimmed;
473
+ } catch {
474
+ return null;
475
+ }
476
+ }
477
+ const TAIL_LINES = 5;
478
+ function tailLines(lines, count = TAIL_LINES) {
479
+ return (Array.isArray(lines) ? lines : []).filter((l) => typeof l === "string" && l.trim() !== "").slice(-count);
480
+ }
481
+ const HEARTBEAT_INTERVAL_MS = 3e4;
482
+ const HEARTBEAT_ACTIVITY = {
483
+ build: "compiling",
484
+ deps: "installing",
485
+ pods: "installing"
486
+ };
487
+ function heartbeatLine(elapsedMs, label = "build", estimateMs = null) {
488
+ const activity = HEARTBEAT_ACTIVITY[label] ?? "running";
489
+ const elapsed = formatElapsed(elapsedMs);
490
+ const inside = estimateMs && estimateMs > 0 ? elapsedMs > estimateMs ? `${elapsed}, usually ~${formatElapsed(estimateMs)}` : `${elapsed} of ~${formatElapsed(estimateMs)}` : elapsed;
491
+ return phaseLine(label, `still ${activity} (${inside})`);
492
+ }
493
+ const defaultSchedule = (run, delayMs) => {
494
+ const timer = setTimeout(run, delayMs);
495
+ timer.unref?.();
496
+ return () => clearTimeout(timer);
497
+ };
498
+ function startBuildHeartbeat({ intervalMs, elapsed, emit, label = "build", estimateMs = null, schedule = defaultSchedule }) {
499
+ if (!(intervalMs > 0)) return () => {};
500
+ let stopped = false;
501
+ let lastBeat = 0;
502
+ let cancel = null;
503
+ function tick() {
504
+ if (stopped) return;
505
+ const ms = elapsed();
506
+ const beat = Math.floor(ms / intervalMs) * intervalMs;
507
+ if (beat > lastBeat) {
508
+ lastBeat = beat;
509
+ emit(heartbeatLine(beat, label, estimateMs));
510
+ }
511
+ cancel = schedule(tick, intervalMs - ms % intervalMs);
512
+ }
513
+ cancel = schedule(tick, intervalMs);
514
+ return () => {
515
+ stopped = true;
516
+ cancel?.();
517
+ };
518
+ }
519
+ function failedResult({ code, diagnostics, durationMs, exitCode = null, transcriptLines = 0, tail = [], compilationCache = COMPILATION_CACHE_UNAVAILABLE, compilationCacheCorruption = null }) {
520
+ const capped = capDiagnostics(diagnostics);
521
+ return {
522
+ ok: false,
523
+ code,
524
+ diagnostics: capped.diagnostics,
525
+ truncated: capped.truncated,
526
+ durationMs,
527
+ exitCode,
528
+ transcriptLines,
529
+ tail,
530
+ compilationCache,
531
+ ...compilationCacheCorruption ? { compilationCacheCorruption } : {}
532
+ };
533
+ }
534
+ const COMPILATION_CACHE_UNAVAILABLE = {
535
+ status: "unavailable",
536
+ hits: null,
537
+ cacheableTasks: null,
538
+ hitRatePercent: null
539
+ };
540
+ const COMPILATION_CACHE_NOT_RUN = {
541
+ status: "not-run",
542
+ hits: null,
543
+ cacheableTasks: null,
544
+ hitRatePercent: null
545
+ };
546
+ function parseCompilationCacheActivity(line) {
547
+ if (typeof line !== "string") return null;
548
+ const match = line.match(/(?:note:\s*)?(\d+) hits \/ (\d+) cacheable tasks \((\d+(?:\.\d+)?)%\)/);
549
+ if (!match) return null;
550
+ return {
551
+ status: "reported",
552
+ hits: Number(match[1]),
553
+ cacheableTasks: Number(match[2]),
554
+ hitRatePercent: Number(match[3])
555
+ };
556
+ }
557
+ const SWIFT_CACHING_NEEDS_EXPLICIT_MODULES = /warning: swift compiler caching requires explicit module build/;
558
+ function compilationCacheActivityLine(activity) {
559
+ if (activity.status === "reported") {
560
+ const swift = activity.swiftTargetsWithoutExplicitModules ? `; Swift excluded: ${activity.swiftTargetsWithoutExplicitModules} targets build without explicit modules (SWIFT_ENABLE_EXPLICIT_MODULES=NO)` : "";
561
+ return `${activity.hits}/${activity.cacheableTasks} hits (${activity.hitRatePercent}%)${swift}`;
562
+ }
563
+ if (activity.status === "not-run") return "not run; artifact cache supplied the app";
564
+ return "unavailable; Xcode did not report reliable statistics";
565
+ }
566
+ async function buildXcode({ context = ambientContext(), root, udid = null, logWriter, project, scheme = null, configuration = "Debug", applicationTarget, sdk = "iphonesimulator", destination = null, arch = null, derivedDataPath = null, extraArgs = [], compilationCache, startedAt: clockStart, now = () => Date.now(), exec = null, heartbeatMs = HEARTBEAT_INTERVAL_MS, estimateMs = null, onHeartbeat = (line) => console.error(line) }) {
567
+ if (!root || typeof root !== "string") throw new TypeError("buildXcode requires {root}");
568
+ if (!logWriter || typeof logWriter.write !== "function") throw new TypeError("buildXcode requires {logWriter} with a write() method");
569
+ if (!udid && !destination) throw new TypeError("buildXcode requires {udid} (or an explicit {destination})");
570
+ const executor = exec || getExecutor();
571
+ const dd = derivedDataPath || (scheme ? join(workspaceDerivedData(root), `scheme-${createHash("sha256").update(scheme).digest("hex")}`) : workspaceDerivedData(root));
572
+ const startedAt = clockStart ?? now();
573
+ const elapsed = () => now() - startedAt;
574
+ const reportError = (message, remedy) => {
575
+ logWriter.write({
576
+ src: "build",
577
+ level: "error",
578
+ msg: message,
579
+ event: "build_diagnostic",
580
+ ...remedy ? { remedy } : {}
581
+ });
582
+ };
583
+ if (project.error) {
584
+ reportError(project.error.message, project.error.remedy);
585
+ return failedResult({
586
+ code: project.error.code,
587
+ diagnostics: [{
588
+ message: project.error.message,
589
+ remedy: project.error.remedy ?? void 0
590
+ }],
591
+ durationMs: elapsed()
592
+ });
593
+ }
594
+ const resolvedTarget = project;
595
+ const selected = await resolveScheme(resolvedTarget, {
596
+ exec: executor,
597
+ scheme
598
+ });
599
+ if (selected.error) {
600
+ reportError(selected.error.message, selected.error.remedy);
601
+ return failedResult({
602
+ code: selected.error.code,
603
+ diagnostics: [{
604
+ message: selected.error.message,
605
+ remedy: selected.error.remedy
606
+ }],
607
+ durationMs: elapsed()
608
+ });
609
+ }
610
+ const buildScheme = selected.scheme;
611
+ const cacheSettings = typeof compilationCache === "function" ? await compilationCache({
612
+ derivedDataPath: dd,
613
+ exec: executor
614
+ }) : compilationCache || [];
615
+ const buildSettings = arch ? [
616
+ ...cacheSettings,
617
+ `ARCHS=${arch}`,
618
+ "ONLY_ACTIVE_ARCH=YES"
619
+ ] : cacheSettings;
620
+ const casPathSetting = "COMPILATION_CACHE_CAS_PATH=";
621
+ const casDir = cacheSettings.includes("COMPILATION_CACHE_ENABLE_CACHING=YES") ? cacheSettings.find((setting) => setting.startsWith(casPathSetting))?.slice(27) ?? null : null;
622
+ const args = xcodebuildArgs({
623
+ project: resolvedTarget,
624
+ scheme: buildScheme,
625
+ udid,
626
+ destination,
627
+ configuration,
628
+ sdk,
629
+ derivedDataPath: dd,
630
+ extraArgs,
631
+ buildSettings
632
+ });
633
+ logWriter.write({
634
+ src: "build",
635
+ level: "info",
636
+ msg: `xcodebuild ${args.join(" ")}`,
637
+ event: "build_start"
638
+ });
639
+ const diagnosticCollector = createXcodeDiagnosticCollector(root, sdk);
640
+ const tail = [];
641
+ let transcriptLines = 0;
642
+ let compilationCacheActivity = COMPILATION_CACHE_UNAVAILABLE;
643
+ let swiftTargetsWithoutExplicitModules = 0;
644
+ let compilationCacheCorruption = null;
645
+ const onLine = (line) => {
646
+ const msg = cleanLine(line);
647
+ transcriptLines += 1;
648
+ diagnosticCollector.push(msg);
649
+ if (msg.trim() === "") return;
650
+ if (casDir && !compilationCacheCorruption && COMPILATION_CACHE_CORRUPTION.test(msg)) compilationCacheCorruption = {
651
+ dir: casDir,
652
+ line: msg.trim()
653
+ };
654
+ tail.push(msg);
655
+ if (tail.length > TAIL_LINES) tail.shift();
656
+ logWriter.write({
657
+ src: "build",
658
+ level: "debug",
659
+ msg
660
+ });
661
+ if (SWIFT_CACHING_NEEDS_EXPLICIT_MODULES.test(msg)) swiftTargetsWithoutExplicitModules += 1;
662
+ const parsed = parseCompilationCacheActivity(msg);
663
+ if (parsed) {
664
+ const activity = swiftTargetsWithoutExplicitModules ? {
665
+ ...parsed,
666
+ swiftTargetsWithoutExplicitModules
667
+ } : parsed;
668
+ compilationCacheActivity = activity;
669
+ logWriter.write({
670
+ src: "build",
671
+ level: "info",
672
+ msg: compilationCacheActivityLine(activity),
673
+ event: "compilation_cache",
674
+ hits: activity.hits,
675
+ cacheableTasks: activity.cacheableTasks,
676
+ hitRatePercent: activity.hitRatePercent,
677
+ ...swiftTargetsWithoutExplicitModules ? { swiftTargetsWithoutExplicitModules } : {}
678
+ });
679
+ }
680
+ };
681
+ let cacheClaim = null;
682
+ if (casDir) {
683
+ const shared = await shareCompilationCache({
684
+ dir: casDir,
685
+ projectRoot: root,
686
+ note: onHeartbeat,
687
+ signal: AbortSignal.any([context?.signal, runCancellationSignal(context)].filter((each) => each !== void 0))
688
+ });
689
+ if ("failure" in shared) {
690
+ reportError(shared.failure.message, shared.failure.remedy);
691
+ return failedResult({
692
+ code: shared.failure.code,
693
+ diagnostics: [{
694
+ message: shared.failure.message,
695
+ remedy: shared.failure.remedy
696
+ }],
697
+ durationMs: elapsed()
698
+ });
699
+ }
700
+ cacheClaim = shared.claim;
701
+ declareSpawnsOn(context, cacheClaim);
702
+ }
703
+ const releaseCache = () => {
704
+ stopDeclaringSpawnsOn(context, cacheClaim);
705
+ (0, ownership_claim_exports.releaseClaim)(cacheClaim);
706
+ };
707
+ let child;
708
+ try {
709
+ child = spawnDeclared(context, () => executor.spawn("xcodebuild", args, {
710
+ cwd: resolvedTarget.dir || root,
711
+ stdio: [
712
+ "ignore",
713
+ "pipe",
714
+ "pipe"
715
+ ],
716
+ detached: false,
717
+ env: {
718
+ ...context?.env ?? process.env,
719
+ NSUnbufferedIO: "YES",
720
+ FORCE_COLOR: "0"
721
+ }
722
+ }));
723
+ } catch (err) {
724
+ releaseCache();
725
+ const message = `Could not run xcodebuild: ${err.message}`;
726
+ const remedy = "Install Xcode and select it with `sudo xcode-select -s /Applications/Xcode.app`.";
727
+ reportError(message, remedy);
728
+ return failedResult({
729
+ code: "STIM_BUILD_FAILED",
730
+ diagnostics: [{
731
+ message,
732
+ remedy
733
+ }],
734
+ durationMs: elapsed()
735
+ });
736
+ }
737
+ const outReader = createLineReader(onLine);
738
+ const errReader = createLineReader(onLine);
739
+ child.stdout?.setEncoding?.("utf-8");
740
+ child.stderr?.setEncoding?.("utf-8");
741
+ child.stdout?.on("data", (chunk) => outReader.push(chunk));
742
+ child.stderr?.on("data", (chunk) => errReader.push(chunk));
743
+ const stopHeartbeat = startBuildHeartbeat({
744
+ intervalMs: heartbeatMs,
745
+ elapsed,
746
+ emit: onHeartbeat,
747
+ estimateMs
748
+ });
749
+ const outcome = await new Promise((settlePromise) => {
750
+ let settled = false;
751
+ const finish = (value) => {
752
+ if (settled) return;
753
+ settled = true;
754
+ outReader.flush();
755
+ errReader.flush();
756
+ settlePromise(value);
757
+ };
758
+ child.on("close", (code, signal) => finish({
759
+ code,
760
+ signal
761
+ }));
762
+ child.on("error", (error) => finish({
763
+ code: null,
764
+ signal: null,
765
+ error
766
+ }));
767
+ });
768
+ releaseCache();
769
+ stopHeartbeat();
770
+ const durationMs = elapsed();
771
+ if (outcome.error) {
772
+ const message = `Could not run xcodebuild: ${outcome.error.message}`;
773
+ const remedy = "Install Xcode and select it with `sudo xcode-select -s /Applications/Xcode.app`.";
774
+ reportError(message, remedy);
775
+ return failedResult({
776
+ code: "STIM_BUILD_FAILED",
777
+ diagnostics: [{
778
+ message,
779
+ remedy
780
+ }],
781
+ durationMs,
782
+ transcriptLines,
783
+ tail,
784
+ compilationCache: compilationCacheActivity
785
+ });
786
+ }
787
+ if (outcome.code !== 0) {
788
+ const diagnostics = diagnosticCollector.diagnostics;
789
+ const capped = capDiagnostics(diagnostics);
790
+ for (const d of capped.diagnostics) reportError(describeDiagnostic(d), d.remedy);
791
+ if (capped.diagnostics.length === 0) reportError(`xcodebuild exited ${outcome.code ?? `on ${outcome.signal}`} with no recognizable diagnostic; see the transcript above.`, null);
792
+ return failedResult({
793
+ code: "STIM_BUILD_FAILED",
794
+ diagnostics,
795
+ durationMs,
796
+ exitCode: outcome.code,
797
+ transcriptLines,
798
+ tail,
799
+ compilationCache: compilationCacheActivity,
800
+ compilationCacheCorruption
801
+ });
802
+ }
803
+ const products = productsDir(dd, {
804
+ configuration,
805
+ sdk
806
+ });
807
+ let appPath = null;
808
+ if (scheme) try {
809
+ const targets = JSON.parse(await probe(executor, "xcodebuild", [
810
+ resolvedTarget.flag,
811
+ resolvedTarget.path,
812
+ "-scheme",
813
+ buildScheme,
814
+ "-configuration",
815
+ configuration,
816
+ "-sdk",
817
+ sdk,
818
+ "-destination",
819
+ destination || `id=${udid}`,
820
+ "-derivedDataPath",
821
+ dd,
822
+ ...extraArgs,
823
+ ...buildSettings,
824
+ "-showBuildSettings",
825
+ "-json"
826
+ ], { timeoutMs: 3e4 }));
827
+ const paths = /* @__PURE__ */ new Set();
828
+ for (const item of Array.isArray(targets) ? targets : []) {
829
+ const settings = item?.buildSettings;
830
+ if (settings?.PRODUCT_TYPE !== "com.apple.product-type.application" || settings.PLATFORM_NAME !== sdk) continue;
831
+ if (applicationTarget && (settings.TARGET_NAME !== applicationTarget.name || typeof settings.PROJECT_FILE_PATH !== "string" || realpathSync(settings.PROJECT_FILE_PATH) !== realpathSync(applicationTarget.projectPath))) continue;
832
+ const dir = settings.TARGET_BUILD_DIR;
833
+ const name = settings.FULL_PRODUCT_NAME;
834
+ if (typeof dir !== "string" || !isAbsolute(dir) || typeof name !== "string" || basename(name) !== name || !name.endsWith(".app")) continue;
835
+ const path = join(dir, name);
836
+ if (statSync(path).isDirectory()) paths.add(path);
837
+ }
838
+ if (paths.size === 1) appPath = [...paths][0];
839
+ } catch {}
840
+ else appPath = findAppBundle(products, buildScheme);
841
+ if (!appPath) {
842
+ const message = scheme ? `xcodebuild succeeded, but the built app for scheme ${JSON.stringify(buildScheme)} could not be identified unambiguously from its build settings.` : `xcodebuild reported success but no .app is in ${products}.`;
843
+ const remedy = "Check that the scheme builds one application target for this platform, not a library, test bundle, or several apps.";
844
+ reportError(message, remedy);
845
+ return failedResult({
846
+ code: "STIM_BUILD_FAILED",
847
+ diagnostics: [{
848
+ message,
849
+ remedy
850
+ }],
851
+ durationMs,
852
+ exitCode: 0,
853
+ transcriptLines,
854
+ tail,
855
+ compilationCache: compilationCacheActivity
856
+ });
857
+ }
858
+ const bundleId = await readBundleId(appPath, { exec: executor });
859
+ if (!bundleId) {
860
+ const message = `No readable CFBundleIdentifier in ${join(appPath, "Info.plist")}.`;
861
+ const remedy = "Check PRODUCT_BUNDLE_IDENTIFIER in the target's Debug configuration.";
862
+ reportError(message, remedy);
863
+ return failedResult({
864
+ code: "STIM_BUILD_FAILED",
865
+ diagnostics: [{
866
+ message,
867
+ remedy
868
+ }],
869
+ durationMs,
870
+ exitCode: 0,
871
+ transcriptLines,
872
+ tail,
873
+ compilationCache: compilationCacheActivity
874
+ });
875
+ }
876
+ logWriter.write({
877
+ src: "build",
878
+ level: "info",
879
+ msg: `BUILD SUCCEEDED ${appPath} (${bundleId}) in ${durationMs}ms`,
880
+ event: "build_done"
881
+ });
882
+ return {
883
+ ok: true,
884
+ appPath,
885
+ bundleId,
886
+ durationMs,
887
+ scheme: buildScheme,
888
+ project: resolvedTarget,
889
+ derivedDataPath: dd,
890
+ productsDir: products,
891
+ transcriptLines,
892
+ compilationCache: compilationCacheActivity
893
+ };
894
+ }
895
+ //#endregion
896
+ export { tailLines as _, buildXcode as a, bundlerPin as b, detectXcodeMajorAsync as c, pickXcodeProject as d, readBundleExecutable as f, swiftPrefixMappingSupported as g, startBuildHeartbeat as h, SWIFT_PREFIX_MAPPING_MIN_SWIFT as i, parseSwiftVersion as l, resolveScheme as m, COMPILATION_CACHE_UNAVAILABLE as n, compilationCacheActivityLine as o, readBundleId as p, HEARTBEAT_INTERVAL_MS as r, compilationCacheSettings as s, COMPILATION_CACHE_NOT_RUN as t, parseXcodeMajor as u, xcodebuildArgs as v, podInstallCommand as x, describeDiagnostic as y };