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,26 +1,200 @@
1
- import { O as writeConfigSetting } from "./config-BYDxlMY3.mjs";
2
- import { t as getExecutor } from "./exec-DqKo9GKJ.mjs";
3
- import { t as git } from "./git-DDfFzkMm.mjs";
4
- import { d as androidLayoutSetting, y as iosProjectDirSetting } from "./settings-B717odTD.mjs";
5
- import { D as fingerprintProject, M as refingerprintAfterMutation } from "./device-lease-BX1sJQ2E.mjs";
6
- import { w as workspaceLogsDir, x as workspaceDir } from "./workspace-state-DJt_MMvf.mjs";
1
+ import { t as getExecutor } from "./exec-DEoAhcze.mjs";
2
+ import { d as workspaceDir, m as workspaceLogsDir$1 } from "./paths-DQtTgsBf.mjs";
3
+ import { k as writeConfigSetting } from "./config-DlrsduwG.mjs";
7
4
  import { n as stripAnsi } from "./process-output-Fpl8PYi8.mjs";
8
- import { d as projectRegistry, h as selectNativeXcodeProject } from "./project-_phNIJfs.mjs";
9
- import { o as parseNdjsonText } from "./ndjson-GOnbyvso.mjs";
10
- import { n as CCACHE_UNAVAILABLE, o as resolveCcache } from "./ccache-zdKiYQ3E.mjs";
11
- import { i as assembleTaskFor } from "./gradle-DSrXb6lG.mjs";
12
- import { f as podsAreStale, g as runPodInstall, p as readPodState, u as workerToolchain } from "./toolchain-DxSsNssu.mjs";
13
- import { a as validateGradleManifest, d as verifyNativeTransfer, m as manifestDigest, n as gradleStateDirectories, o as verifyGradleTransfer, r as nativeGradleOutputs, t as gradleOffloadInputs } from "./native-gradle-inputs-BsLRrl7u.mjs";
14
- import { n as buildAndroid, o as gradlewPath, r as buildIos } from "./react-native-build-CtCccJtb.mjs";
15
- import { n as buildAndroidOperation, t as buildIosOperation } from "./build-DYDbfkk5.mjs";
16
- import { n as recordPrebuild, r as runPrebuild, t as planPrebuild } from "./prebuild-DYbucPXy.mjs";
17
- import { f as podAction } from "./support-CwjbFs9H.mjs";
18
- import { r as stageBundle, t as resolveBundleExtras } from "./stage-KNTQopqv.mjs";
19
- import { t as logLines } from "./run-BtPgpKks.mjs";
20
- import { r as nativeXcodeMetadataDirectories } from "./native-xcode-inputs-CykopJdM.mjs";
21
- import { chmodSync, constants, copyFileSync, cpSync, createReadStream, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, readlinkSync, realpathSync, renameSync, rmSync, statSync, symlinkSync, writeFileSync } from "node:fs";
22
- import { basename, dirname, join } from "node:path";
5
+ import { o as git, s as gitAsync } from "./operation-exec-BW0em61G.mjs";
6
+ import { d as androidLayoutSetting, y as iosProjectDirSetting } from "./settings-C7O8A6ZI.mjs";
7
+ import { f as projectRegistry, g as selectNativeXcodeProject } from "./project-wM_XFTvE.mjs";
8
+ import { o as parseNdjsonText } from "./ndjson-CgE_o3Dl.mjs";
9
+ import { Fn as processContext } from "./budget-Cvwn54qV.mjs";
10
+ import { l as fingerprintProject, m as refingerprintAfterMutation } from "./build-cache-Dv7RN200.mjs";
11
+ import { n as CCACHE_UNAVAILABLE, o as resolveCcache } from "./ccache-Btwc36-I.mjs";
12
+ import { _ as clearCorruptCompilationCache, f as reactNativeArtifactReceipt, g as COMPILATION_CACHE_CORRUPT, m as reactNativeBuildQuery, p as reactNativeArtifactToolchain } from "./client-OyRoEuSr.mjs";
13
+ import { f as workerToolchain, h as readPodState, i as availableIphone, m as podsAreStale, v as runPodInstall } from "./toolchain-DpJMHq0n.mjs";
14
+ import { n as fingerprintNativeInputs, r as manifestDigest } from "./native-inputs-TRTTTRxt.mjs";
15
+ import { a as sourceManifest, o as verifyNativeTransfer } from "./native-source-Y0yLhFyQ.mjs";
16
+ import { i as nativeGradleOutputs, n as gradleStateDirectories, o as validateGradleManifest, s as verifyGradleTransfer, t as gradleOffloadInputs } from "./native-gradle-inputs-Dnh84Zbd.mjs";
17
+ import { n as buildAndroid, o as gradlewPath, r as buildIos, u as assembleTaskFor } from "./react-native-build-Dvd8hC21.mjs";
18
+ import { f as podAction } from "./support-CNioewsd.mjs";
19
+ import { i as runPrebuild, r as recordPrebuild, t as planPrebuild } from "./prebuild-D4JoEAEs.mjs";
20
+ import { g as dumpApkManifest, p as apkPackage } from "./support-yUiOjnVY.mjs";
21
+ import { n as buildAndroidOperation, t as buildIosOperation } from "./build-CabC3G23.mjs";
22
+ import { i as stageBundle, n as resolveBundleExtras } from "./stage-Bps5oius.mjs";
23
+ import { t as logLines } from "./run-DidHghD1.mjs";
24
+ import { r as nativeXcodeMetadataDirectories } from "./native-xcode-inputs-D_VOfFL7.mjs";
25
+ import { n as swiftpmArtifactInputs, r as swiftpmArtifactSnapshot, t as readSwiftpmArtifactToolchain } from "./swiftpm-artifact-inputs-DFcGsXDP.mjs";
26
+ import { a as nativeGradleWorkerArtifactIdentity, i as nativeGradleArtifactSnapshotFromReceipt, o as nativeGradleWorkerScope } from "./native-gradle-artifact-inputs-DHFnmrVf.mjs";
23
27
  import { createHash } from "node:crypto";
28
+ import { chmodSync, constants, copyFileSync, cpSync, createReadStream, createWriteStream, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, readlinkSync, realpathSync, renameSync, rmSync, statSync, symlinkSync, writeFileSync } from "node:fs";
29
+ import { isDeepStrictEqual } from "node:util";
30
+ import { basename, dirname, join, relative, resolve, sep } from "node:path";
31
+ import { dependencyInstall, withAmbientContext } from "@stim-cli/core";
32
+ import { isJsonObject, windowsShortDir, windowsShortDirKey } from "@stim-cli/core/state";
33
+ import { realpath } from "node:fs/promises";
34
+ import { pipeline } from "node:stream/promises";
35
+ import { createGzip } from "node:zlib";
36
+ //#region src/offload/swiftpm-artifact.ts
37
+ async function readSwiftpmWorkerToolchain(context, cwd) {
38
+ const commandPath = async (name) => {
39
+ const path = getExecutor().findExecutable(name, {
40
+ cwd,
41
+ env: context.env
42
+ });
43
+ if (!path) throw new Error(`The SwiftPM tool ${name} is unavailable.`);
44
+ return realpath(path);
45
+ };
46
+ const [selected, xcrun, xcodebuild] = await Promise.all([
47
+ commandPath("swift"),
48
+ commandPath("xcrun"),
49
+ commandPath("xcodebuild")
50
+ ]);
51
+ const compiler = await realpath(await getExecutor().runFileAsync("/usr/bin/xcrun", ["--find", "swift"], {
52
+ cwd,
53
+ timeoutMs: 3e4
54
+ }));
55
+ const sdk = await realpath(context.env.SDKROOT ?? context.env.SWIFTPM_SDKROOT_macosx ?? await getExecutor().runFileAsync("/usr/bin/xcrun", [
56
+ "--sdk",
57
+ "macosx",
58
+ "--show-sdk-path"
59
+ ], {
60
+ cwd,
61
+ timeoutMs: 3e4
62
+ }));
63
+ const overrides = {};
64
+ for (const variable of ["SWIFT_EXEC", "SWIFT_EXEC_MANIFEST"]) {
65
+ const command = context.env[variable];
66
+ if (!command) continue;
67
+ const version = await getExecutor().runFileAsync(command, ["--version"], {
68
+ cwd,
69
+ timeoutMs: 3e4,
70
+ declareFor: context
71
+ });
72
+ if (!version.trim()) throw new Error(`The SwiftPM ${variable} compiler identity is unavailable.`);
73
+ overrides[variable] = {
74
+ command: await commandPath(command),
75
+ version
76
+ };
77
+ }
78
+ const checkoutRequired = Object.keys(overrides).length > 0 || selected !== await realpath("/usr/bin/swift") && selected !== compiler || xcrun !== await realpath("/usr/bin/xcrun") || xcodebuild !== await realpath("/usr/bin/xcodebuild");
79
+ return {
80
+ ...await readSwiftpmArtifactToolchain(context, void 0, cwd),
81
+ selection: {
82
+ command: selected,
83
+ compiler,
84
+ sdk,
85
+ xcrun,
86
+ xcodebuild,
87
+ overrides,
88
+ checkoutRequired
89
+ }
90
+ };
91
+ }
92
+ async function privateSnapshot(root, query, privateLockfile, toolchain, env, signal) {
93
+ const repository = resolve(root, ...query.project.split("/").filter(Boolean).map(() => ".."));
94
+ const declaration = swiftpmArtifactInputs(query.inputs);
95
+ return (await fingerprintNativeInputs([
96
+ ...declaration.ignored.map((path) => ({
97
+ name: `ignored/${path}`,
98
+ path: join(repository, path)
99
+ })),
100
+ ...declaration.localFiles.map((path, index) => ({
101
+ name: `local/${index}`,
102
+ path: resolve(root, path),
103
+ optional: true
104
+ })),
105
+ ...privateLockfile ? [{
106
+ name: "package-resolved",
107
+ path: join(root, "Package.resolved"),
108
+ optional: true
109
+ }] : []
110
+ ], {
111
+ parameters: {
112
+ toolchain,
113
+ environment: Object.fromEntries([.../* @__PURE__ */ new Set([
114
+ ...declaration.environment,
115
+ "DEVELOPER_DIR",
116
+ "TOOLCHAINS",
117
+ "SDKROOT",
118
+ "SWIFT_EXEC",
119
+ "MACOSX_DEPLOYMENT_TARGET"
120
+ ])].toSorted().map((name) => [name, env[name] ?? null]))
121
+ },
122
+ signal
123
+ })).hash;
124
+ }
125
+ /** Certifies actual worker inputs, not the client's transfer digest or cache identity. */
126
+ async function swiftpmWorkerArtifactSnapshot(root, query, toolchain, env, signal) {
127
+ signal?.throwIfAborted();
128
+ root = await realpath(root);
129
+ const repository = await realpath(await gitAsync(root, ["rev-parse", "--show-toplevel"], { signal }));
130
+ const project = relative(repository, await realpath(root)).split(sep).join("/");
131
+ const visible = await sourceManifest(repository, true, signal);
132
+ if (query.project !== project || manifestDigest(visible) !== query.sourceDigest) throw new Error("The SwiftPM worker source does not match its completed transfer.");
133
+ const declaration = swiftpmArtifactInputs(query.inputs);
134
+ const build = {
135
+ ...query.build,
136
+ resources: Object.fromEntries(Object.entries(query.build.resources).map(([name, path]) => [name, relative(root, resolve(repository, path))])),
137
+ assetCatalog: query.build.assetCatalog ? relative(root, resolve(repository, query.build.assetCatalog)) : null
138
+ };
139
+ const snapshot = await swiftpmArtifactSnapshot(root, declaration, build, {
140
+ swift: toolchain.swift,
141
+ sdk: toolchain.sdk,
142
+ xcode: toolchain.xcode,
143
+ arch: toolchain.arch
144
+ }, env, signal);
145
+ const sourcePaths = new Set(visible.map((file) => file.path));
146
+ const privatePaths = /* @__PURE__ */ new Set([...declaration.ignored.map((path) => resolve(repository, path)), ...declaration.localFiles.map((path) => resolve(root, path))]);
147
+ for (const path of [
148
+ build.infoPlist,
149
+ ...Object.values(build.resources),
150
+ build.assetCatalog
151
+ ]) {
152
+ if (path === null) continue;
153
+ const absolute = resolve(root, path);
154
+ const bundled = await fingerprintNativeInputs([{
155
+ name: "bundle",
156
+ path: absolute
157
+ }], {
158
+ parameters: null,
159
+ signal
160
+ });
161
+ for (const entry of bundled.entries) {
162
+ if (entry.kind === "directory") continue;
163
+ const file = join(absolute, entry.path === "bundle" ? "" : entry.path.slice(7));
164
+ const name = relative(repository, file).split(sep).join("/");
165
+ if (!entry.kind.startsWith("file:") || !sourcePaths.has(name) && !privatePaths.has(file)) throw new Error("SwiftPM peer caching requires every ignored bundle file in the private input declaration.");
166
+ }
167
+ }
168
+ const privateLockfile = !sourcePaths.has([project, "Package.resolved"].filter(Boolean).join("/"));
169
+ const privateHash = await privateSnapshot(root, query, privateLockfile, toolchain, env, signal);
170
+ const hash = createHash("sha256").update(JSON.stringify([
171
+ "stim-swiftpm-worker-v1",
172
+ snapshot.hash,
173
+ query,
174
+ privateHash
175
+ ])).digest("hex");
176
+ const identity = {
177
+ hash,
178
+ key: `swiftpm-peer-${hash}`
179
+ };
180
+ return {
181
+ identity,
182
+ receipt: {
183
+ query: structuredClone(query),
184
+ identity,
185
+ privateHash,
186
+ privateLockfile,
187
+ checkoutRequired: toolchain.selection.checkoutRequired
188
+ }
189
+ };
190
+ }
191
+ /** Revalidates private inputs of a receipt bound to a verified completed source transfer. */
192
+ async function swiftpmArtifactFromReceipt(root, query, receipt, toolchain, env, signal) {
193
+ signal?.throwIfAborted();
194
+ if (!isDeepStrictEqual(query, receipt.query) || typeof receipt.checkoutRequired !== "boolean" || receipt.checkoutRequired !== toolchain.selection.checkoutRequired || !/^[a-f0-9]{64}$/.test(receipt.identity.hash) || receipt.identity.key !== `swiftpm-peer-${receipt.identity.hash}`) return null;
195
+ return await privateSnapshot(root, query, receipt.privateLockfile, toolchain, env, signal) === receipt.privateHash ? receipt.identity : null;
196
+ }
197
+ //#endregion
24
198
  //#region src/offload/worker.ts
25
199
  function emit(value) {
26
200
  process.stdout.write(`${JSON.stringify(value)}\n`);
@@ -90,13 +264,85 @@ function ensureParents(root, path) {
90
264
  mkdirSync(current);
91
265
  }
92
266
  }
93
- function materialize(job, src) {
267
+ const PRIVATE_DIRS = [
268
+ "$ErrorActionPreference = 'Stop'",
269
+ "$me = [Security.Principal.WindowsIdentity]::GetCurrent().User",
270
+ "$acl = New-Object Security.AccessControl.DirectorySecurity",
271
+ "$acl.SetAccessRuleProtection($true, $false)",
272
+ "foreach ($sid in @($me, (New-Object Security.Principal.SecurityIdentifier 'S-1-5-18'))) {",
273
+ " $acl.AddAccessRule((New-Object Security.AccessControl.FileSystemAccessRule($sid, 'FullControl', 'ContainerInherit,ObjectInherit', 'None', 'Allow')))",
274
+ "}",
275
+ "foreach ($line in [Console]::In.ReadToEnd().Split([char]10) | ForEach-Object { $_.Trim() } | Where-Object { $_ }) {",
276
+ " $dir, $key = $line.Split([char]9)",
277
+ " [void][IO.Directory]::CreateDirectory($dir, $acl)",
278
+ " $current = Get-Acl -LiteralPath $dir",
279
+ " $owner = $current.GetOwner([Security.Principal.SecurityIdentifier]).Value",
280
+ " if ($owner -notin @($me.Value, 'S-1-5-32-544', 'S-1-5-18')) { [Console]::Error.WriteLine(\"$dir is owned by $owner\"); exit 3 }",
281
+ " $foreign = $current.GetAccessRules($true, $true, [Security.Principal.SecurityIdentifier]) | Where-Object { $_.IdentityReference.Value -notin @($me.Value, 'S-1-5-18') }",
282
+ " if (-not $current.AreAccessRulesProtected -or $foreign) { Set-Acl -LiteralPath $dir -AclObject $acl }",
283
+ " if ($key) {",
284
+ " $marker = \"$dir.owner\"",
285
+ " if (-not (Test-Path -LiteralPath $marker)) { Set-Content -NoNewline -LiteralPath $marker -Value $key }",
286
+ " elseif ((Get-Content -Raw -LiteralPath $marker) -ne $key) { [Console]::Error.WriteLine(\"$dir belongs to another build area\"); exit 4 }",
287
+ " }",
288
+ "}"
289
+ ].join("\n");
290
+ /**
291
+ * Creates each directory, in order, with access for this user and SYSTEM only, and gives an existing one that ACL.
292
+ * A directory at the drive root inherits the root's ACL, which lets every authenticated user modify it, so another
293
+ * account could plant code in a build; one that another account owns could hold such code, so it is refused. A
294
+ * directory with a key records it in `<dir>.owner` and is refused when another key is recorded there, since the
295
+ * short names of different areas can collide.
296
+ */
297
+ function makePrivateWindowsDirs(dirs) {
298
+ try {
299
+ getExecutor().runFile("powershell.exe", [
300
+ "-NoProfile",
301
+ "-NonInteractive",
302
+ "-Command",
303
+ PRIVATE_DIRS
304
+ ], {
305
+ input: dirs.map((entry) => entry.join(" ")).join("\n"),
306
+ timeoutMs: 6e4
307
+ });
308
+ } catch (error) {
309
+ const reason = (error instanceof Error ? error.message : String(error)).trim().split("\n").at(-1);
310
+ throw new Error(`Could not prepare the private Windows build directories: ${reason}`, { cause: error });
311
+ }
312
+ }
313
+ /**
314
+ * Creates the checkout directory `src` of `area`. On Windows it is a junction to a private `windowsShortDir`, and the
315
+ * client's Gradle home is made private too; an area whose `src` is a directory keeps it.
316
+ */
317
+ function ensureCheckout(area, src) {
318
+ const stat = lstatSync(src, { throwIfNoEntry: false });
319
+ if (process.platform === "win32") {
320
+ const linked = !stat || stat.isSymbolicLink();
321
+ const realArea = realpathSync(area);
322
+ const target = windowsShortDir(realArea);
323
+ const gradleHome = process.env.GRADLE_USER_HOME;
324
+ const dirs = [[dirname(target)]];
325
+ if (linked) dirs.push([target, windowsShortDirKey("checkout", realArea)]);
326
+ if (gradleHome) dirs.push([gradleHome, windowsShortDirKey("gradle", dirname(dirname(area)))]);
327
+ makePrivateWindowsDirs(dirs);
328
+ if (!linked) return;
329
+ let current = null;
330
+ try {
331
+ current = realpathSync(src);
332
+ } catch {}
333
+ if (current?.toLowerCase() === target.toLowerCase()) return;
334
+ if (stat) rmSync(src, { force: true });
335
+ symlinkSync(target, src, "junction");
336
+ return;
337
+ }
338
+ mkdirSync(src, { recursive: true });
339
+ }
340
+ async function materialize(job, src) {
94
341
  const recordFile = join(job.area, "mirror.json");
95
342
  let previous = {};
96
343
  try {
97
344
  previous = JSON.parse(readFileSync(recordFile, "utf8"));
98
345
  } catch {}
99
- mkdirSync(src, { recursive: true });
100
346
  if (!existsSync(join(src, ".git"))) {
101
347
  git(src, ["init", "--quiet"], {
102
348
  write: true,
@@ -126,7 +372,7 @@ function materialize(job, src) {
126
372
  } catch {}
127
373
  const allowed = [...declaration.outputs, ...gradleStateDirectories(job.project)];
128
374
  if (receipt.project === job.project && Array.isArray(receipt.directories)) retained = allowed.filter((path) => receipt.directories.includes(path));
129
- retained = nativeGradleOutputs(src, {
375
+ retained = await nativeGradleOutputs(src, {
130
376
  complete: true,
131
377
  ignored: [],
132
378
  outputs: retained
@@ -238,42 +484,18 @@ function materialize(job, src) {
238
484
  removed
239
485
  };
240
486
  }
241
- function lockfileOf(src) {
242
- if (existsSync(join(src, "pnpm-lock.yaml"))) return {
243
- file: "pnpm-lock.yaml",
244
- command: "pnpm",
245
- args: (pkg) => [
246
- "install",
247
- "--frozen-lockfile",
248
- ...pkg ? ["--filter", `${pkg}...`] : []
249
- ]
250
- };
251
- if (existsSync(join(src, "yarn.lock"))) return {
252
- file: "yarn.lock",
253
- command: "yarn",
254
- args: () => ["install", "--frozen-lockfile"]
255
- };
256
- if (existsSync(join(src, "package-lock.json"))) return {
257
- file: "package-lock.json",
258
- command: "npm",
259
- args: () => ["ci"]
260
- };
261
- return null;
262
- }
263
487
  /** Installs JavaScript dependencies when the lockfile, or the install command, changed since the last install. */
264
488
  async function ensureDependencies(job, src) {
265
- const lock = lockfileOf(src);
266
- if (!lock) return;
267
- const args = lock.args(job.packageName);
268
- const lockfile = readFileSync(join(src, lock.file));
269
- const digest = createHash("sha256").update(lockfile).update(JSON.stringify(args)).digest("hex");
489
+ const install = dependencyInstall(src, job.packageName);
490
+ if (!install) return;
491
+ const { command, args, digest, lockfile } = install;
270
492
  const marker = join(job.area, "dependencies");
271
- const installed = () => writeFileSync(join(job.area, "lockfile"), createHash("sha256").update(lockfile).digest("hex"));
493
+ const installed = () => writeFileSync(join(job.area, "lockfile"), lockfile);
272
494
  if (existsSync(join(src, job.project, "node_modules")) && existsSync(marker)) {
273
495
  if (readFileSync(marker, "utf8") === digest) return installed();
274
496
  }
275
- note("deps", `${lock.command} ${args.join(" ")}`);
276
- const child = getExecutor().spawn(lock.command, args, {
497
+ note("deps", `${command} ${args.join(" ")}`);
498
+ const child = getExecutor().spawn(command, args, {
277
499
  cwd: src,
278
500
  env: {
279
501
  ...process.env,
@@ -296,7 +518,7 @@ async function ensureDependencies(job, src) {
296
518
  child.on("error", reject);
297
519
  child.on("exit", resolve);
298
520
  });
299
- if (code !== 0) throw new Error(`${lock.command} ${args.join(" ")} exited with ${code}: ${tail.join(" | ")}`);
521
+ if (code !== 0) throw new Error(`${command} ${args.join(" ")} exited with ${code}: ${tail.join(" | ")}`);
300
522
  writeFileSync(marker, digest);
301
523
  installed();
302
524
  }
@@ -312,12 +534,55 @@ function destination(runtime) {
312
534
  "devices",
313
535
  "available",
314
536
  "-j"
315
- ], { timeoutMs: 2e4 }) ?? "{}").devices?.[runtime] ?? []).find((each) => each.name.startsWith("iPhone"));
537
+ ], { timeoutMs: 2e4 }) ?? "{}").devices?.[runtime] ?? []).find(availableIphone);
316
538
  return device ? `id=${device.udid}` : null;
317
539
  } catch {
318
540
  return null;
319
541
  }
320
542
  }
543
+ /**
544
+ * Writes `name` under `dir` to `archive` as a gzip tarball at compression level 1. Node does the gzip because tar's
545
+ * compression-level flags differ between bsdtar (macOS, Windows) and GNU tar (Linux).
546
+ */
547
+ async function packArchive(archive, dir, name) {
548
+ const child = getExecutor().spawn("tar", [
549
+ "-cf",
550
+ "-",
551
+ "-C",
552
+ dir,
553
+ name
554
+ ], { stdio: [
555
+ "ignore",
556
+ "pipe",
557
+ "pipe"
558
+ ] });
559
+ const tarball = child.stdout;
560
+ if (!tarball) throw new Error("tar opened no output stream.");
561
+ const stderr = [];
562
+ child.stderr?.on("data", (chunk) => stderr.push(String(chunk)));
563
+ let spawnError = null;
564
+ const exited = new Promise((resolve) => {
565
+ child.once("error", (error) => {
566
+ spawnError = error;
567
+ resolve(null);
568
+ });
569
+ child.once("close", resolve);
570
+ });
571
+ const timeout = new AbortController();
572
+ const timer = setTimeout(() => timeout.abort(), 6e5);
573
+ try {
574
+ await pipeline(tarball, createGzip({ level: 1 }), createWriteStream(archive), { signal: timeout.signal });
575
+ } catch (error) {
576
+ child.kill("SIGKILL");
577
+ await exited;
578
+ throw timeout.signal.aborted ? /* @__PURE__ */ new Error("Packing the artifact did not finish within 10 minutes.") : error;
579
+ } finally {
580
+ clearTimeout(timer);
581
+ }
582
+ const code = await exited;
583
+ if (spawnError) throw spawnError;
584
+ if (code !== 0) throw new Error(`tar exited with ${code}: ${stderr.join("").trim().slice(-500)}`);
585
+ }
321
586
  async function sha256Of(path) {
322
587
  const hash = createHash("sha256");
323
588
  for await (const chunk of createReadStream(path)) hash.update(chunk);
@@ -347,13 +612,14 @@ async function build(job) {
347
612
  message,
348
613
  timings
349
614
  });
350
- const src = join(job.area, "src");
615
+ ensureCheckout(job.area, join(job.area, "src"));
616
+ const src = realpathSync(join(job.area, "src"));
351
617
  const root = join(src, job.project);
352
618
  const log = relayWriter(join(job.area, "build.ndjson"));
353
619
  const mirrored = await time("syncMs", () => materialize(job, src));
354
620
  const realSrc = realpathSync(src);
355
621
  const realRoot = realpathSync(root);
356
- if (realRoot !== realSrc && !realRoot.startsWith(`${realSrc}/`)) return failed("bad-project", `${job.project} leaves the checkout.`);
622
+ if (realRoot !== realSrc && !realRoot.startsWith(`${realSrc}${sep}`)) return failed("bad-project", `${job.project} leaves the checkout.`);
357
623
  note("sync", `${job.manifest.length} files, ${mirrored.written} written, ${mirrored.removed} removed`);
358
624
  let fingerprint;
359
625
  let compiled;
@@ -361,21 +627,11 @@ async function build(job) {
361
627
  if (job.platform !== "android" || job.expectedFingerprint !== null) return failed("unsupported-provider", "Native Gradle needs an Android request with no reusable artifact identity.");
362
628
  const selected = projectRegistry.selectAndroid(root);
363
629
  if ("problem" in selected || selected.id !== "native-android") return failed("provider-mismatch", "The transferred project did not select the native Android integration.");
364
- if (!verifyGradleTransfer(src, job.project, job.native.inputs, job.manifest, job.native.sourceDigest)) return failed("source-mismatch", "The materialized native inputs do not match the source transfer.");
630
+ if (!await verifyGradleTransfer(src, job.project, job.native.inputs, job.manifest, job.native.sourceDigest)) return failed("source-mismatch", "The materialized native inputs do not match the source transfer.");
365
631
  compiled = await compileNativeAndroid(job, root, log, time);
366
632
  if (!compiled.ok) return failed(compiled.code, compiled.message);
367
633
  try {
368
- const model = JSON.parse(readFileSync(join(workspaceDir(root), "gradle-build", `native-apk-${encodeURIComponent(job.android?.variant ?? "debug")}.json`), "utf8"));
369
- const outputs = nativeGradleOutputs(src, job.native.inputs, model.buildDirectories);
370
- if (!verifyGradleTransfer(src, job.project, job.native.inputs, job.manifest, job.native.sourceDigest)) throw new Error("The native source changed while the worker compiled it.");
371
- const directories = [...outputs, ...gradleStateDirectories(job.project).filter((path) => lstatSync(join(src, path), { throwIfNoEntry: false })?.isDirectory())];
372
- const receipt = join(job.area, "gradle-outputs.json");
373
- const tmp = `${receipt}.${process.pid}.tmp`;
374
- writeFileSync(tmp, JSON.stringify({
375
- project: job.project,
376
- directories
377
- }));
378
- renameSync(tmp, receipt);
634
+ if (!await verifyGradleTransfer(src, job.project, job.native.inputs, job.manifest, job.native.sourceDigest)) throw new Error("The native source changed while the worker compiled it.");
379
635
  } catch (error) {
380
636
  if (compiled.temporary) rmSync(compiled.temporary, {
381
637
  recursive: true,
@@ -391,7 +647,7 @@ async function build(job) {
391
647
  let metadataDirectories;
392
648
  try {
393
649
  metadataDirectories = nativeXcodeMetadataDirectories(selectNativeXcodeProject(root, job.scheme ?? void 0, job.configuration ?? void 0));
394
- if (!verifyNativeTransfer(src, job.manifest, job.native.sourceDigest, metadataDirectories)) return failed("source-mismatch", "The materialized native inputs do not match the source transfer.");
650
+ if (!await verifyNativeTransfer(src, job.manifest, job.native.sourceDigest, metadataDirectories)) return failed("source-mismatch", "The materialized native inputs do not match the source transfer.");
395
651
  } catch (error) {
396
652
  return failed("source-mismatch", error.message);
397
653
  }
@@ -401,7 +657,7 @@ async function build(job) {
401
657
  compiled = await compileNativeIos(job, root, log, time);
402
658
  if (!compiled.ok) return failed(compiled.code, compiled.message);
403
659
  try {
404
- if (!verifyNativeTransfer(src, job.manifest, job.native.sourceDigest, metadataDirectories)) throw new Error("The native source changed while the worker compiled it.");
660
+ if (!await verifyNativeTransfer(src, job.manifest, job.native.sourceDigest, metadataDirectories)) throw new Error("The native source changed while the worker compiled it.");
405
661
  } catch (error) {
406
662
  if (compiled.temporary) rmSync(compiled.temporary, {
407
663
  recursive: true,
@@ -413,7 +669,7 @@ async function build(job) {
413
669
  } else if (job.platform === "macos") {
414
670
  fingerprint = await time("fingerprintMs", () => manifestDigest(job.manifest));
415
671
  if (fingerprint !== job.expectedFingerprint) return failed("fingerprint-mismatch", `the manifest there fingerprints ${fingerprint.slice(0, 12)}, here ${job.expectedFingerprint?.slice(0, 12)}`);
416
- compiled = await compileMacos(job, root, log, time);
672
+ compiled = await workerOperation(root, (context) => compileMacos(context, job, root, log, time));
417
673
  if (!compiled.ok) return failed(compiled.code, compiled.message);
418
674
  } else {
419
675
  try {
@@ -424,7 +680,7 @@ async function build(job) {
424
680
  const platform = job.platform;
425
681
  let iosProject;
426
682
  try {
427
- iosProject = iosProjectDirSetting({ ios: { projectPath: job.iosProjectPath ?? void 0 } }, root);
683
+ iosProject = iosProjectDirSetting({ ios: { projectPath: job.iosProjectPath ?? void 0 } }, realRoot);
428
684
  } catch (error) {
429
685
  return failed("bad-request", error.message);
430
686
  }
@@ -433,17 +689,17 @@ async function build(job) {
433
689
  androidLayout = androidLayoutSetting({ android: {
434
690
  gradleRoot: job.android?.gradleRoot ?? void 0,
435
691
  module: job.android?.module ?? void 0
436
- } }, root, realSrc);
692
+ } }, realRoot, realSrc);
437
693
  } catch (error) {
438
694
  return failed("bad-request", error.message);
439
695
  }
440
- const initial = await time("fingerprintMs", () => fingerprintProject(root, {
696
+ const initial = await time("fingerprintMs", () => fingerprintProject(realRoot, {
441
697
  platform,
442
698
  iosProjectPath: iosProject.relative,
443
699
  androidLayout
444
700
  }));
445
- if (!initial) return failed("no-fingerprint", "The remote Mac could not fingerprint the project.");
446
- const plan = planPrebuild(root, platform, {
701
+ if (!initial) return failed("no-fingerprint", "The remote machine could not fingerprint the project.");
702
+ const plan = planPrebuild(realRoot, platform, {
447
703
  isExpo: job.isExpo,
448
704
  fingerprint: initial.hash,
449
705
  sources: initial.sources
@@ -452,17 +708,17 @@ async function build(job) {
452
708
  const mutations = [];
453
709
  if (plan === "generate" || plan === "regenerate") {
454
710
  note("prebuild", plan === "generate" ? `generating ${platform}/` : `regenerating ${platform}/ with --clean`);
455
- recordPrebuild(root, platform, null);
456
- const result = await time("prebuildMs", () => runPrebuild(root, platform, log, { clean: plan === "regenerate" }));
711
+ recordPrebuild(realRoot, platform, null);
712
+ const result = await time("prebuildMs", () => runPrebuild(realRoot, platform, log, { clean: plan === "regenerate" }));
457
713
  if (result?.failed) return failed("prebuild-failed", result.reason ?? "expo prebuild failed.");
458
714
  mutations.push("prebuild");
459
715
  }
460
716
  if (platform === "ios") {
461
- const podState = readPodState(root, iosProject.dir);
717
+ const podState = readPodState(realRoot, iosProject.dir);
462
718
  const pods = podAction(podState, podsAreStale(podState.lockText, podState.manifestText, podState.dir));
463
719
  if (pods.install) {
464
720
  note("pods", `${pods.reason ?? "Pods are stale"} -> pod install`);
465
- const result = await time("podsMs", () => runPodInstall(root, log, {
721
+ const result = await time("podsMs", () => runPodInstall(realRoot, log, {
466
722
  directory: iosProject.dir,
467
723
  onHeartbeat: (line) => note("pods", line)
468
724
  }));
@@ -473,7 +729,7 @@ async function build(job) {
473
729
  fingerprint = initial.hash;
474
730
  if (mutations.length) {
475
731
  const after = await time("fingerprintMs", () => refingerprintAfterMutation({
476
- projectRoot: root,
732
+ projectRoot: realRoot,
477
733
  platform,
478
734
  previousHash: initial.hash,
479
735
  iosProjectPath: iosProject.relative,
@@ -481,20 +737,25 @@ async function build(job) {
481
737
  }));
482
738
  if (!after) return failed("no-fingerprint", `No fingerprint after ${mutations.join(", ")}.`);
483
739
  fingerprint = after.hash;
484
- if (mutations.includes("prebuild")) recordPrebuild(root, platform, after.hash);
740
+ if (mutations.includes("prebuild")) recordPrebuild(realRoot, platform, after.hash);
485
741
  }
486
742
  if (fingerprint !== job.expectedFingerprint) return failed("fingerprint-mismatch", `the checkout there fingerprints ${fingerprint.slice(0, 12)}, here ${job.expectedFingerprint?.slice(0, 12)}`);
487
- compiled = platform === "android" ? await compileAndroid(job, root, log, time, androidLayout) : await compileIos(job, root, log, time);
743
+ const tools = job.cacheArtifact ? await reactNativeArtifactToolchain(platform, realRoot) : null;
744
+ const query = tools ? reactNativeBuildQuery(job, fingerprint, job.project, tools) : null;
745
+ const receipt = query ? reactNativeArtifactReceipt(query, tools) : null;
746
+ compiled = platform === "android" ? await compileAndroid(job, realRoot, log, time, androidLayout) : await compileIos(job, realRoot, log, time);
488
747
  if (!compiled.ok) return failed(compiled.code, compiled.message);
489
748
  const builtFingerprint = fingerprint;
490
749
  const settled = await time("fingerprintMs", () => refingerprintAfterMutation({
491
- projectRoot: root,
750
+ projectRoot: realRoot,
492
751
  platform,
493
752
  previousHash: builtFingerprint,
494
753
  iosProjectPath: iosProject.relative,
495
754
  androidLayout
496
755
  }));
497
756
  if (!settled || settled.moved) return failed("fingerprint-moved", "The inputs changed during the build there.");
757
+ const after = query && receipt ? reactNativeArtifactReceipt(query, await reactNativeArtifactToolchain(platform, realRoot)) : null;
758
+ if (receipt && after && isDeepStrictEqual(receipt, after)) compiled.reactNativeArtifact = receipt;
498
759
  }
499
760
  try {
500
761
  const out = join(job.area, "out", job.job);
@@ -510,15 +771,7 @@ async function build(job) {
510
771
  verbatimSymlinks: true,
511
772
  mode: constants.COPYFILE_FICLONE
512
773
  });
513
- await time("packageMs", () => getExecutor().runFileAsync("tar", [
514
- "-czf",
515
- archive,
516
- "--options",
517
- "gzip:compression-level=1",
518
- "-C",
519
- dirname(compiled.path),
520
- name
521
- ], { timeoutMs: 6e5 }));
774
+ await time("packageMs", () => packArchive(archive, dirname(compiled.path), name));
522
775
  const sha256 = await time("packageMs", () => sha256Of(archive));
523
776
  return {
524
777
  ok: true,
@@ -531,6 +784,9 @@ async function build(job) {
531
784
  fingerprint,
532
785
  ...compiled.androidPackage ? { androidPackage: compiled.androidPackage } : {},
533
786
  ...job.native ? { sourceDigest: job.native.sourceDigest } : {},
787
+ ...compiled.cacheArtifact ? { cacheArtifact: compiled.cacheArtifact } : {},
788
+ ...compiled.reactNativeArtifact ? { reactNativeArtifact: compiled.reactNativeArtifact } : {},
789
+ ...compiled.swiftpmArtifact ? { swiftpmArtifact: compiled.swiftpmArtifact } : {},
534
790
  compilationCache: compiled.cache,
535
791
  timings
536
792
  };
@@ -541,12 +797,9 @@ async function build(job) {
541
797
  });
542
798
  }
543
799
  }
544
- function isRecord(value) {
545
- return typeof value === "object" && value !== null && !Array.isArray(value);
546
- }
547
800
  function differingParameters(here, there, path) {
548
801
  if (JSON.stringify(here) === JSON.stringify(there)) return [];
549
- if (!isRecord(here) || !isRecord(there)) return [path];
802
+ if (!isJsonObject(here) || !isJsonObject(there)) return [path];
550
803
  return [.../* @__PURE__ */ new Set([...Object.keys(here), ...Object.keys(there)])].toSorted().flatMap((key) => differingParameters(here[key], there[key], `${path}.${key}`));
551
804
  }
552
805
  function unused() {
@@ -593,6 +846,10 @@ async function nativeIdentityRefusal(job, native, root, load) {
593
846
  return `This Mac cannot key the native build: ${error.message}`;
594
847
  }
595
848
  }
849
+ function workerOperation(root, fn) {
850
+ const context = processContext(root, new AbortController().signal);
851
+ return withAmbientContext(context, () => fn(context));
852
+ }
596
853
  async function compileNativeIos(job, root, log, time) {
597
854
  if (job.native?.provider !== "xcode" || !job.optimizations) return {
598
855
  ok: false,
@@ -612,15 +869,15 @@ async function compileNativeIos(job, root, log, time) {
612
869
  }, `optimizations.ios.${key}`, value ?? void 0);
613
870
  }
614
871
  note("build", `native Xcode ${job.configuration ?? "Debug"}`);
615
- const logFile = join(workspaceLogsDir(root), "build-ios.ndjson");
872
+ const logFile = join(workspaceLogsDir$1(root), "build-ios.ndjson");
616
873
  try {
617
874
  rmSync(logFile, { force: true });
618
- const built = await time("buildMs", () => buildIosOperation(root, {
875
+ const built = await time("buildMs", () => workerOperation(root, (context) => buildIosOperation(context, root, {
619
876
  scheme: job.scheme ?? void 0,
620
877
  configuration: job.configuration ?? void 0,
621
878
  arch: native.arch ?? "all",
622
879
  remoteBuild: "local"
623
- }));
880
+ })));
624
881
  if (built.cacheKey !== native.cacheKey || built.cacheSkipped) {
625
882
  rmSync(dirname(built.appPath), {
626
883
  recursive: true,
@@ -639,6 +896,14 @@ async function compileNativeIos(job, root, log, time) {
639
896
  temporary: dirname(built.appPath)
640
897
  };
641
898
  } catch (error) {
899
+ if (error instanceof Error && "code" in error && error.code === "STIM_COMPILATION_CACHE_CORRUPT") {
900
+ const remedy = "remedy" in error && typeof error.remedy === "string" ? ` ${error.remedy}` : "";
901
+ return {
902
+ ok: false,
903
+ code: COMPILATION_CACHE_CORRUPT,
904
+ message: `${error.message}${remedy}`
905
+ };
906
+ }
642
907
  return {
643
908
  ok: false,
644
909
  code: "native-build-failed",
@@ -648,6 +913,25 @@ async function compileNativeIos(job, root, log, time) {
648
913
  if (existsSync(logFile)) for (const record of parseNdjsonText(readFileSync(logFile, "utf8"))) log.write(record);
649
914
  }
650
915
  }
916
+ async function validateNativeAndroidOutputs(job, root) {
917
+ if (job.native?.provider !== "gradle") throw new Error("A native Gradle source declaration is required.");
918
+ try {
919
+ const src = realpathSync(join(job.area, "src"));
920
+ const model = JSON.parse(readFileSync(join(workspaceDir(root), "gradle-build", `native-apk-${encodeURIComponent(job.android?.variant ?? "debug")}.json`), "utf8"));
921
+ const outputs = await nativeGradleOutputs(src, job.native.inputs, model.buildDirectories);
922
+ if (!await verifyGradleTransfer(src, job.project, job.native.inputs, job.manifest, job.native.sourceDigest)) throw new Error("The native source changed while the worker compiled it.");
923
+ const directories = [...outputs, ...gradleStateDirectories(job.project).filter((path) => lstatSync(join(src, path), { throwIfNoEntry: false })?.isDirectory())];
924
+ const receipt = join(job.area, "gradle-outputs.json");
925
+ const tmp = `${receipt}.${process.pid}.tmp`;
926
+ writeFileSync(tmp, JSON.stringify({
927
+ project: job.project,
928
+ directories
929
+ }));
930
+ renameSync(tmp, receipt);
931
+ } catch (error) {
932
+ throw Object.assign(new Error(error.message), { code: "source-moved" });
933
+ }
934
+ }
651
935
  async function compileNativeAndroid(job, root, log, time) {
652
936
  const options = job.android;
653
937
  if (!options) return {
@@ -671,24 +955,41 @@ async function compileNativeAndroid(job, root, log, time) {
671
955
  process.exit(143);
672
956
  };
673
957
  process.once("SIGTERM", stop);
674
- const logFile = join(workspaceLogsDir(root), "build-android.ndjson");
958
+ const logFile = join(workspaceLogsDir$1(root), "build-android.ndjson");
959
+ let cacheArtifact;
675
960
  note("build", `native Gradle ${options.variant ?? "debug"}`);
676
961
  try {
677
962
  rmSync(logFile, { force: true });
678
- const built = await time("buildMs", () => buildAndroidOperation(root, {
963
+ const built = await time("buildMs", () => workerOperation(root, (context) => buildAndroidOperation(context, root, {
679
964
  variant: options.variant ?? void 0,
680
965
  abi: options.abi ?? "all",
681
966
  remoteBuild: "local"
682
- }));
683
- if (built.cacheKey !== null || !built.cacheSkipped || !built.androidPackage) {
967
+ }, {
968
+ cachePolicy: job.native?.provider === "gradle" && job.native.cache ? job.native.cache : {
969
+ read: false,
970
+ write: false,
971
+ remote: false
972
+ },
973
+ artifactScope: {
974
+ key: job.native?.provider === "gradle" ? nativeGradleWorkerScope(job.native.sourceDigest, job.native.inputs) : "null",
975
+ validate: () => validateNativeAndroidOutputs(job, root),
976
+ record: (identity, receipt) => {
977
+ cacheArtifact = {
978
+ identity,
979
+ receipt
980
+ };
981
+ }
982
+ }
983
+ })));
984
+ if (!built.androidPackage) {
684
985
  rmSync(dirname(built.apkPath), {
685
986
  recursive: true,
686
987
  force: true
687
988
  });
688
989
  return {
689
990
  ok: false,
690
- code: "unexpected-cache-identity",
691
- message: "The native Gradle worker returned an unsupported artifact identity or package."
991
+ code: "invalid-package",
992
+ message: "The native Gradle worker returned no verified APK package."
692
993
  };
693
994
  }
694
995
  return {
@@ -696,12 +997,13 @@ async function compileNativeAndroid(job, root, log, time) {
696
997
  path: built.apkPath,
697
998
  temporary: dirname(built.apkPath),
698
999
  cache: built.ccache,
699
- androidPackage: built.androidPackage
1000
+ androidPackage: built.androidPackage,
1001
+ ...cacheArtifact && cacheArtifact.identity.key === built.cacheKey ? { cacheArtifact } : {}
700
1002
  };
701
1003
  } catch (error) {
702
1004
  return {
703
1005
  ok: false,
704
- code: "native-build-failed",
1006
+ code: error instanceof Error && "code" in error && error.code === "source-moved" ? "source-moved" : "native-build-failed",
705
1007
  message: error.message
706
1008
  };
707
1009
  } finally {
@@ -710,7 +1012,7 @@ async function compileNativeAndroid(job, root, log, time) {
710
1012
  if (existsSync(logFile)) for (const record of parseNdjsonText(readFileSync(logFile, "utf8"))) log.write(record);
711
1013
  }
712
1014
  }
713
- async function compileMacos(job, root, log, time) {
1015
+ async function compileMacos(context, job, root, log, time) {
714
1016
  const options = job.macos;
715
1017
  if (!options) return {
716
1018
  ok: false,
@@ -757,6 +1059,26 @@ async function compileMacos(job, root, log, time) {
757
1059
  };
758
1060
  try {
759
1061
  const extras = resolveBundleExtras(src, src, options.resources, options.assetCatalog);
1062
+ const query = job.cacheArtifact && options.artifactInputs && job.expectedFingerprint && job.stimBuild ? {
1063
+ project: job.project,
1064
+ sourceDigest: job.expectedFingerprint,
1065
+ stimBuild: job.stimBuild,
1066
+ inputs: options.artifactInputs,
1067
+ build: {
1068
+ product: options.product,
1069
+ infoPlist: options.infoPlist,
1070
+ resources: options.resources ?? {},
1071
+ assetCatalog: options.assetCatalog ?? null
1072
+ }
1073
+ } : null;
1074
+ const snapshot = async () => query ? swiftpmWorkerArtifactSnapshot(root, query, await readSwiftpmWorkerToolchain(context, root), context.env) : null;
1075
+ let before = null;
1076
+ try {
1077
+ before = await snapshot();
1078
+ } catch (error) {
1079
+ context.signal.throwIfAborted();
1080
+ note("build", `SwiftPM artifact inventory unavailable: ${String(error)}`);
1081
+ }
760
1082
  return await time("buildMs", async () => {
761
1083
  await run([
762
1084
  "build",
@@ -780,11 +1102,21 @@ async function compileMacos(job, root, log, time) {
780
1102
  "--show-bin-path"
781
1103
  ], true);
782
1104
  const bundle = join(job.area, "out", job.job, `${options.product}.app`);
783
- stageBundle(root, options.product, options.infoPlist, bin, bundle, options.bundleId, extras);
1105
+ await stageBundle(context, root, options.product, options.infoPlist, bin, bundle, options.bundleId, extras);
1106
+ let swiftpmArtifact = null;
1107
+ if (before) try {
1108
+ const after = await snapshot();
1109
+ if (after?.identity.hash === before.identity.hash) swiftpmArtifact = after;
1110
+ else note("build", "SwiftPM inputs changed during the build; not retaining its artifact.");
1111
+ } catch (error) {
1112
+ context.signal.throwIfAborted();
1113
+ note("build", `SwiftPM artifact inventory skipped: ${String(error)}`);
1114
+ }
784
1115
  return {
785
1116
  ok: true,
786
1117
  path: bundle,
787
- cache: {}
1118
+ cache: {},
1119
+ ...swiftpmArtifact ? { swiftpmArtifact } : {}
788
1120
  };
789
1121
  });
790
1122
  } catch (error) {
@@ -816,6 +1148,14 @@ async function compileIos(job, root, log, time) {
816
1148
  onNote: (line) => note("build", line)
817
1149
  }));
818
1150
  if (!built.ok) {
1151
+ if (built.compilationCacheCorruption) {
1152
+ const report = await clearCorruptCompilationCache(built.compilationCacheCorruption, root);
1153
+ return {
1154
+ ok: false,
1155
+ code: report.code,
1156
+ message: `${report.message} ${report.remedy}`
1157
+ };
1158
+ }
819
1159
  const first = built.diagnostics[0]?.message;
820
1160
  return {
821
1161
  ok: false,
@@ -899,10 +1239,12 @@ async function compileAndroid(job, root, log, time, layout) {
899
1239
  message: first ?? (built.lastLines.slice(-3).join(" | ") || built.reason)
900
1240
  };
901
1241
  }
1242
+ const androidPackage = built.androidPackage ?? apkPackage(await dumpApkManifest(built.apkPath));
902
1243
  return {
903
1244
  ok: true,
904
1245
  path: built.apkPath,
905
- cache: built.ccache ?? CCACHE_UNAVAILABLE
1246
+ cache: built.ccache ?? CCACHE_UNAVAILABLE,
1247
+ ...androidPackage ? { androidPackage } : {}
906
1248
  };
907
1249
  } finally {
908
1250
  process.off("SIGTERM", stop);
@@ -914,6 +1256,27 @@ async function main() {
914
1256
  if (mode === "offer") return emit(workerToolchain(process.argv[3] ?? null));
915
1257
  if (mode === "offer-native-xcode") return emit(workerToolchain(null, "xcode"));
916
1258
  if (mode === "offer-native-gradle") return emit(workerToolchain(null, "gradle"));
1259
+ if (mode === "native-gradle-artifact") {
1260
+ const chunks = [];
1261
+ for await (const chunk of process.stdin) chunks.push(chunk);
1262
+ const input = JSON.parse(Buffer.concat(chunks).toString("utf8"));
1263
+ if (!/^[a-f0-9]{64}$/.test(input.sourceDigest)) throw new Error("The completed transfer identity is invalid.");
1264
+ gradleOffloadInputs(input.inputs);
1265
+ if (input.android) {
1266
+ const { android, receipt } = input;
1267
+ if (android.variant !== null && android.variant !== receipt.build.variant || (android.abi === "all" ? null : android.abi) !== receipt.abi || android.compilerCache !== receipt.build.compilerCache || android.gradleBuildCache !== receipt.build.gradleBuildCache || android.pch !== receipt.build.pch || receipt.build.cas !== null) throw new Error("The completed Gradle build choices do not match this artifact request.");
1268
+ }
1269
+ const snapshot = await workerOperation(input.root, (context) => nativeGradleArtifactSnapshotFromReceipt(input.root, input.receipt, context.env, context.signal));
1270
+ return emit({ identity: nativeGradleWorkerArtifactIdentity(snapshot.hash, nativeGradleWorkerScope(input.sourceDigest, input.inputs), input.receipt.build.variant ?? "debug", input.receipt.abi) });
1271
+ }
1272
+ if (mode === "swiftpm-artifact") {
1273
+ const chunks = [];
1274
+ for await (const chunk of process.stdin) chunks.push(chunk);
1275
+ const input = JSON.parse(Buffer.concat(chunks).toString("utf8"));
1276
+ const checkout = existsSync(input.root);
1277
+ if (!checkout && input.receipt.checkoutRequired !== false) return emit({ identity: null });
1278
+ return emit({ identity: await workerOperation(input.root, async (context) => swiftpmArtifactFromReceipt(input.root, input.query, input.receipt, await readSwiftpmWorkerToolchain(context, checkout ? input.root : process.cwd()), context.env)) });
1279
+ }
917
1280
  if (mode === "build") {
918
1281
  const chunks = [];
919
1282
  for await (const chunk of process.stdin) chunks.push(chunk);
@@ -922,7 +1285,7 @@ async function main() {
922
1285
  ...await build(JSON.parse(Buffer.concat(chunks).toString("utf8")))
923
1286
  });
924
1287
  }
925
- process.stderr.write("usage: offload-worker offer | offer-native-xcode | offer-native-gradle | build < job.json\n");
1288
+ process.stderr.write("usage: offload-worker offer | offer-native-xcode | offer-native-gradle | native-gradle-artifact | build < job.json\n");
926
1289
  process.exitCode = 2;
927
1290
  }
928
1291
  main().catch((error) => {