stim 1.21.0 → 1.23.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 (184) hide show
  1. package/README.md +60 -7
  2. package/dist/{acquire-artifact-CD4lbiWE.mjs → acquire-artifact-ybouwJSR.mjs} +21 -3
  3. package/dist/{act-DHAw2A2S.mjs → act-DG54PWtJ.mjs} +298 -164
  4. package/dist/{activity-BzVfHSrY.mjs → activity-B5RtpFda.mjs} +33 -12
  5. package/dist/{agent-device-usage-output-zh1vhbLp.mjs → agent-device-usage-output-UJ5gC80l.mjs} +7 -7
  6. package/dist/{android-BLgbNqox.mjs → android-BoUJKbfz.mjs} +66 -52
  7. package/dist/{android-DUYkNF4u.mjs → android-C7sVmyI9.mjs} +160 -59
  8. package/dist/{android-CV_GCELZ.mjs → android-CHH4KLOR.mjs} +5 -5
  9. package/dist/{android-BEJ8Jpl7.mjs → android-DR5lZ2Az.mjs} +2 -2
  10. package/dist/android-cas-compiler.mjs +1 -1
  11. package/dist/{android-cas-Ct5b1xCK.mjs → android-cas-ngferVq2.mjs} +3 -3
  12. package/dist/{client-B7QVOlCr.d.mts → android-project-DVWyCbWU.d.mts} +145 -7
  13. package/dist/api.d.mts +132 -118
  14. package/dist/api.mjs +239 -42
  15. package/dist/{artifact-DAuZ-FNU.mjs → artifact-5RteZem7.mjs} +69 -40
  16. package/dist/{artifact-B8T3S5gi.mjs → artifact-Dwdo7k1E.mjs} +40 -35
  17. package/dist/artifact-platform-CXcmX_j3.mjs +27 -0
  18. package/dist/{browser-web-QQzVjz3O.mjs → browser-web-CeEVlGug.mjs} +187 -59
  19. package/dist/{budget-Bs6SxxzO.mjs → budget-DnPX3DXj.mjs} +830 -699
  20. package/dist/{build-CoPzQRNw.mjs → build-CqufZFqy.mjs} +34 -27
  21. package/dist/{build-cache-DmyR9Zzc.mjs → build-cache-Dv7RN200.mjs} +4 -4
  22. package/dist/{build-plan-CaFskB7_.mjs → build-plan-C8CIvRyi.mjs} +74 -14
  23. package/dist/{cache-manifest-DkkqguoK.mjs → cache-manifest-DSeQjt-Q.mjs} +1 -1
  24. package/dist/cache-manifest.mjs +1 -1
  25. package/dist/{ccache-BJRZ9pG3.mjs → ccache-RcAy92gH.mjs} +6 -6
  26. package/dist/{cdp-CWmIUMbw.mjs → cdp-3fwICjzi.mjs} +1 -1
  27. package/dist/{chrome-B6tfCta1.mjs → chrome-Bbw689-6.mjs} +1 -1
  28. package/dist/{cli-0DYf8QhQ.mjs → cli-D-J9fWGV.mjs} +20 -20
  29. package/dist/cli.mjs +1 -1
  30. package/dist/{client-UXD70ZbM.mjs → client-yyso1bwi.mjs} +218 -47
  31. package/dist/collector-run.d.mts +1 -1
  32. package/dist/collector-run.mjs +6 -6
  33. package/dist/{command-output-B1UrjZHL.mjs → command-output-Db8BqzxH.mjs} +1 -1
  34. package/dist/{config-CYcBF478.mjs → config-DlrsduwG.mjs} +17 -11
  35. package/dist/{created-devices-CqeBlrEn.mjs → created-devices-x9rN6bhs.mjs} +13 -3
  36. package/dist/{dependency-state-BbKQW83h.mjs → dependency-state-1I9KZT1Y.mjs} +2 -2
  37. package/dist/{detached-entry-DFRyG1_o.mjs → detached-entry-BwNEtIrP.mjs} +1 -1
  38. package/dist/{dev-client-UOeESKm6.mjs → dev-client-BnYSDiKa.mjs} +2 -2
  39. package/dist/{device-DCxH7_By.mjs → device-BvzPUBs3.mjs} +16 -16
  40. package/dist/{device-ExJq8Ei7.mjs → device-CCkWmkAA.mjs} +71 -14
  41. package/dist/{device-capacity-CMlqEcvw.mjs → device-capacity-CjaSdrhg.mjs} +9 -10
  42. package/dist/device-host-worker.mjs +25 -32
  43. package/dist/{device-ios-DRUeKaFV.mjs → device-ios-uOiEETX2.mjs} +39 -16
  44. package/dist/{device-lease-run-C8raGFoP.mjs → device-lease-run-BgwPHc6u.mjs} +5 -5
  45. package/dist/{device-pool-DMRpVX9a.mjs → device-pool-C-ptmZTa.mjs} +3 -3
  46. package/dist/{doctor-DTvaDOda.mjs → doctor-8sr2tFOL.mjs} +24 -37
  47. package/dist/{doctor-Dhqebm0q.mjs → doctor-D2SN3Ltx.mjs} +19 -16
  48. package/dist/doctor-fingerprint-DZLoYFVb.mjs +16 -0
  49. package/dist/doctor-fingerprint.mjs +1 -1
  50. package/dist/{doctor-BLHCYxzi.mjs → doctor-pxxvipYC.mjs} +1 -1
  51. package/dist/{doctor-watchman-Cv1F10Kj.mjs → doctor-watchman-sy_RNhFt.mjs} +5 -5
  52. package/dist/{eas-build-BomfRnFT.mjs → eas-build-CyjU5K7E.mjs} +4 -4
  53. package/dist/{eas-fallback-DJwZpy0c.mjs → eas-fallback-DV3Wytf1.mjs} +27 -18
  54. package/dist/{eas-session-ledger-op6A54yi.mjs → eas-session-ledger-BzzsX97d.mjs} +8 -7
  55. package/dist/{error-diagnostics-Bf0rZvG9.mjs → error-diagnostics-C6sVoeqO.mjs} +10 -10
  56. package/dist/{exec-_UbtCQcG.mjs → exec-DEoAhcze.mjs} +155 -47
  57. package/dist/{exec-H20xSg2T.d.mts → exec-DnYc4HGH.d.mts} +17 -4
  58. package/dist/{gc-_-dCXdyL.mjs → gc-CDoogxAI.mjs} +587 -313
  59. package/dist/gc-DLbzvTP2.mjs +3 -0
  60. package/dist/{guide-Yqwt2bd6.mjs → guide-BC37GcDG.mjs} +288 -59
  61. package/dist/{hosted-android-Bw-honsd.mjs → hosted-android-CkclQig_.mjs} +6 -6
  62. package/dist/{hosted-client-DB_gBPfY.mjs → hosted-client-ByuMMO5s.mjs} +4 -4
  63. package/dist/{hosted-ios-CUvOf4Vr.mjs → hosted-ios-DtYHeuYR.mjs} +1 -1
  64. package/dist/{hosted-logs-DL_P5AdN.mjs → hosted-logs-Br84qWy1.mjs} +5 -5
  65. package/dist/{hosted-macos-QI141yKk.mjs → hosted-macos-DdtYajZt.mjs} +21 -12
  66. package/dist/{hosted-native-Ksyjgzq-.mjs → hosted-native-UPI9zdZ4.mjs} +27 -14
  67. package/dist/{idle-BVeRGroT.d.mts → idle-C4cZ757K.d.mts} +3 -3
  68. package/dist/{idle-shutdown-DaKmZi0z.mjs → idle-shutdown-DO7oIRlc.mjs} +7 -7
  69. package/dist/ios-CDvlmUs7.d.mts +24 -0
  70. package/dist/{ios-ubFsBzwq.mjs → ios-DZZbNYlY.mjs} +59 -50
  71. package/dist/{ios-device-CXGP1bsD.mjs → ios-device-BXZ0c7Kb.mjs} +1 -1
  72. package/dist/{ios-device-CwFMehUS.mjs → ios-device-JC3uWM4K.mjs} +3 -3
  73. package/dist/{ios-CpByZy12.mjs → ios-hcBpnEGk.mjs} +81 -34
  74. package/dist/{ios-project-WuwwBdvW.mjs → ios-project-CVyNwjAF.mjs} +5 -5
  75. package/dist/{ios-signing-DTTIChGs.mjs → ios-signing-BtAffm0A.mjs} +2 -2
  76. package/dist/{ios-state-DvFX-K_l.mjs → ios-state-Dtw5K2aI.mjs} +1 -1
  77. package/dist/{ios-CQ68hG9s.mjs → ios-vbUOqGXu.mjs} +8 -8
  78. package/dist/{ios-qNJt4dFm.mjs → ios-xtlRHaeB.mjs} +1 -1
  79. package/dist/{js-swap-Cc1dttps.mjs → js-swap-C3QxUFJR.mjs} +7 -29
  80. package/dist/{launch-CD1yVc7U.mjs → launch-Bz7JtaC4.mjs} +16 -16
  81. package/dist/{launch-Zq2mOSDy.mjs → launch-CHY3p-yz.mjs} +40 -39
  82. package/dist/{logs-CMm05HxN.mjs → logs-CtNeNDuq.mjs} +10 -17
  83. package/dist/{logs-BS00Anxf.mjs → logs-mxqsWpJs.mjs} +151 -24
  84. package/dist/{macos-B65--pPd.mjs → macos-inNFbBWc.mjs} +1 -1
  85. package/dist/macos-run.mjs +1 -1
  86. package/dist/{macos-C-0qJ6zq.mjs → macos-u0BoHKnO.mjs} +143 -46
  87. package/dist/maintenance-run.mjs +8 -8
  88. package/dist/{metro-DEXpIhHC.mjs → metro-DiXtA3Ty.mjs} +59 -37
  89. package/dist/{metro-gateway-BMJNlj3E.mjs → metro-gateway-CKZqKqx7.mjs} +120 -22
  90. package/dist/{named-ports-BWTzt6mu.mjs → named-ports-DkEzOfzO.mjs} +40 -33
  91. package/dist/{native-android-JACyjTZs.mjs → native-android-CdCSylTn.mjs} +43 -242
  92. package/dist/native-gradle-artifact-inputs-DHFnmrVf.mjs +270 -0
  93. package/dist/{native-gradle-inputs-Bep9JcSF.mjs → native-gradle-inputs-Dnh84Zbd.mjs} +3 -129
  94. package/dist/{native-run-DY_RLx3C.mjs → native-run-BUTu8T7A.mjs} +4 -5
  95. package/dist/{native-runtime-Dg1Q7tfF.mjs → native-runtime-CRSOZxKY.mjs} +8 -7
  96. package/dist/native-source-Y0yLhFyQ.mjs +133 -0
  97. package/dist/{native-xcode-inputs-CB2iQeWq.mjs → native-xcode-inputs-G6rkkhxu.mjs} +2 -3
  98. package/dist/{native-xcode-ios-CXX39F7o.mjs → native-xcode-ios-_os2PlCD.mjs} +27 -32
  99. package/dist/offload-worker.d.mts +65 -2
  100. package/dist/offload-worker.mjs +305 -73
  101. package/dist/operation-exec-BW0em61G.mjs +171 -0
  102. package/dist/{ownership-DEmM5vhh.mjs → ownership-C5fo5Edb.mjs} +3 -3
  103. package/dist/{page-CPaHeYqj.mjs → page-DBL2PiUU.mjs} +8 -4
  104. package/dist/{placement-log-BqGbTa61.mjs → placement-log-BnGgJRRZ.mjs} +1 -1
  105. package/dist/{plan-placement-Bwj-IjY1.mjs → plan-placement-BU42oOyT.mjs} +12 -8
  106. package/dist/{ports-D-MmCTdv.mjs → ports-BSmQKzW7.mjs} +3 -3
  107. package/dist/{prebuild-uD_ipCxF.mjs → prebuild-BFm63bQ0.mjs} +63 -16
  108. package/dist/{project-BZNjmW_8.mjs → project-CTLNHCfE.mjs} +16 -16
  109. package/dist/{pull-request-Lfetn8Kr.mjs → pull-request-W1IuLXDt.mjs} +102 -20
  110. package/dist/{pull-request-zjCSAryH.d.mts → pull-request-eODyIqZF.d.mts} +6 -2
  111. package/dist/pull-requests.d.mts +2 -2
  112. package/dist/pull-requests.mjs +2 -2
  113. package/dist/{react-native-android-DuzH0cn3.mjs → react-native-android-CFgUroxW.mjs} +73 -53
  114. package/dist/{react-native-build-rhk4smwQ.mjs → react-native-build-CmJkTljQ.mjs} +8 -8
  115. package/dist/{react-native-doctor-CQpuIMso.mjs → react-native-doctor-LTF-Xt8l.mjs} +7 -7
  116. package/dist/{react-native-ios-Bhq1rJeV.mjs → react-native-ios-ChBF1MkB.mjs} +43 -29
  117. package/dist/{recordings-DYteQSu4.mjs → recordings-CQmfzAh7.mjs} +1 -1
  118. package/dist/registration-BcRgF6Ox.mjs +51 -0
  119. package/dist/{reload-CmTRFJaX.mjs → reload-DF9hqUUB.mjs} +16 -15
  120. package/dist/{reload-DzjSl5P_.mjs → reload-RBi1nj6Z.mjs} +1 -1
  121. package/dist/{remote-ByYkXdGD.mjs → remote-BmvMCcJw.mjs} +18 -15
  122. package/dist/{result-DNiS-tTP.mjs → result-Cx5CRLvS.mjs} +24 -23
  123. package/dist/{run-D23HmJMs.mjs → run-DidHghD1.mjs} +3 -2
  124. package/dist/{selection-CSl9i5qU.mjs → selection-DSMbWEX2.mjs} +6 -5
  125. package/dist/{server-bare-CxTrvDg8.mjs → server-bare-CafzuyFB.mjs} +2 -2
  126. package/dist/{server-command-CtzloH3v.mjs → server-command-BTiGPEjS.mjs} +5 -5
  127. package/dist/server-expo-C-Buqvn_.mjs +2 -0
  128. package/dist/{server-expo-DT_F_uVI.mjs → server-expo-D9lEz4aq.mjs} +7 -5
  129. package/dist/{settings-CsJDEXgK.mjs → settings-C7O8A6ZI.mjs} +223 -243
  130. package/dist/{settings-T1gtc3bf.mjs → settings-eKF_vJJs.mjs} +1 -1
  131. package/dist/{settings-write-HyVZ8eQ8.mjs → settings-write-79mQRr9C.mjs} +7 -6
  132. package/dist/settings.schema.json +13 -0
  133. package/dist/{simslim-Cgk17SXV.mjs → simslim-BNckWpXi.mjs} +2 -2
  134. package/dist/{slot-launch-DF8VfT64.mjs → slot-launch-D7M2nE4b.mjs} +6 -6
  135. package/dist/{stage-BIS0ydsV.mjs → stage-DKNM4ZPd.mjs} +21 -4
  136. package/dist/{start-RChynRDp.mjs → start-CRfN1kWV.mjs} +1 -1
  137. package/dist/{start-7lpH7hmN.mjs → start-bjfiScgz.mjs} +622 -393
  138. package/dist/{state-C4ZtUisW.mjs → state--smjFSTL.mjs} +22 -7
  139. package/dist/{state-XMziexv2.mjs → state-08I3hw3_.mjs} +2 -2
  140. package/dist/{stats-53T7OTb9.mjs → stats-DioA6cBU.mjs} +5 -5
  141. package/dist/{stats-report-BFfMpWWF.mjs → stats-report-BzaPrRm6.mjs} +1 -1
  142. package/dist/{status-DqEUSSxs.mjs → status-BRROykC8.mjs} +2 -2
  143. package/dist/{status-CSi6tlRq.mjs → status-Eqx_20WC.mjs} +1 -1
  144. package/dist/{status-BL7jVyAB.mjs → status-kzbeWk4x.mjs} +43 -29
  145. package/dist/{status-watch-GDCfqpTE.mjs → status-watch-BIqqbJ6q.mjs} +48 -16
  146. package/dist/status-worker.mjs +1 -1
  147. package/dist/{stim-desktop-C12we7lz.mjs → stim-desktop-D5OGpYZM.mjs} +2 -2
  148. package/dist/{stop-Bk_1qiV6.mjs → stop-B18d8KDw.mjs} +2 -2
  149. package/dist/{stop-CPzlM1L-.mjs → stop-B2uLQfoM.mjs} +15 -16
  150. package/dist/{stop-D7h6jAXQ.mjs → stop-DzLJc7Ei.mjs} +31 -22
  151. package/dist/supervisor-run.d.mts +3 -3
  152. package/dist/supervisor-run.mjs +28 -36
  153. package/dist/{support-Dlu37g6H.mjs → support-BTpZ6RAJ.mjs} +15 -11
  154. package/dist/{support-67vraa1Q.mjs → support-DTBV56gy.mjs} +8 -8
  155. package/dist/swiftpm-artifact-inputs-DFcGsXDP.mjs +153 -0
  156. package/dist/swiftpm-macos-r_WSKlXr.mjs +532 -0
  157. package/dist/{toolchain-Hp9sCpK4.mjs → toolchain-CWeGJgCc.mjs} +9 -6
  158. package/dist/toolchain-GVgnf8d1.mjs +2 -0
  159. package/dist/{trigger-BAahxUPq.mjs → trigger-Cbyc41d_.mjs} +3 -3
  160. package/dist/trigger-yb_nFzPF.mjs +2 -0
  161. package/dist/{warm-progress-BHX5r0Ei.mjs → warm-progress-CA3TgT3-.mjs} +29 -16
  162. package/dist/web-Cduk0NSE.mjs +2 -0
  163. package/dist/{web-CJmIj6AI.mjs → web-CwREhjD-.mjs} +11 -10
  164. package/dist/web-run.mjs +11 -9
  165. package/dist/windows-report.mjs +1 -1
  166. package/dist/{workspace-state-Cjuigeeu.mjs → workspace-state-U08dEzhG.mjs} +3 -3
  167. package/dist/{workspaces-BccMFmGQ.mjs → workspaces-BxzYlo3P.mjs} +594 -266
  168. package/dist/{worktree-DQ6Zi2Mv.mjs → worktree-8lqn_lBp.mjs} +850 -551
  169. package/dist/worktree-BxfVxG_b.mjs +2 -0
  170. package/dist/{xcode-Zlx3qjEs.mjs → xcode-iQnROM5o.mjs} +5 -5
  171. package/package.json +7 -7
  172. package/shim/android-audio/Main.java +24 -0
  173. package/shim/android-audio/README.md +17 -0
  174. package/shim/android-audio.jar +0 -0
  175. package/dist/gc-C-WwL0yi.mjs +0 -3
  176. package/dist/git-C3iTsJaZ.mjs +0 -73
  177. package/dist/server-expo-C-90EhcG.mjs +0 -2
  178. package/dist/settings-DkdmlelE.d.mts +0 -15
  179. package/dist/swiftpm-macos-p8WZbxKU.mjs +0 -130
  180. package/dist/toolchain-DhKwp9iI.mjs +0 -2
  181. package/dist/trigger-Bf3uDcpv.mjs +0 -2
  182. package/dist/web-DknQETPs.mjs +0 -2
  183. package/dist/workspace-process-lock-1_1OoVW5.mjs +0 -57
  184. package/dist/worktree-CK2MpJW5.mjs +0 -2
package/dist/api.mjs CHANGED
@@ -1,29 +1,32 @@
1
- import { g as trackReportResource, h as runReport, u as operationState } from "./exec-_UbtCQcG.mjs";
2
- import { d as workspaceDir, m as workspaceLogsDir$1, n as ensureWorkspaceStorage } from "./paths-DQtTgsBf.mjs";
3
- import { E as upsertProject, p as getProject, y as refuseRelativeStimPaths } from "./config-CYcBF478.mjs";
4
- import { l as phaseLine } from "./command-output-B1UrjZHL.mjs";
5
- import { a as recordWorkspaceUseAsync, i as recordWorkspaceUse } from "./workspace-state-Cjuigeeu.mjs";
6
- import { $t as cancelledError, It as repoRootAsync, J as resolveProjectSettingsAsync, a as SETTING_SHAPE_REMEDY, en as throwIfCancelled, et as settingShapeErrors } from "./settings-CsJDEXgK.mjs";
7
- import { f as projectRegistry, r as findCommandWorkspaceAsync } from "./project-BZNjmW_8.mjs";
8
- import { n as macosDir } from "./state-XMziexv2.mjs";
1
+ import { m as operationState, r as WorkspaceProcessCleanupError, v as runReport, x as ownership_claim_exports, y as trackReportResource } from "./exec-DEoAhcze.mjs";
2
+ import { d as workspaceDir, m as workspaceLogsDir$1, n as ensureWorkspaceStorage, r as ensureWorkspaceStorageAsync } from "./paths-DQtTgsBf.mjs";
3
+ import { E as upsertProject, p as getProject, q as validateDeviceSlot, y as refuseRelativeStimPaths } from "./config-DlrsduwG.mjs";
4
+ import { l as phaseLine } from "./command-output-Db8BqzxH.mjs";
5
+ import { d as cancelledError, f as throwIfCancelled } from "./operation-exec-BW0em61G.mjs";
6
+ import { a as recordWorkspaceUseAsync, i as recordWorkspaceUse } from "./workspace-state-U08dEzhG.mjs";
7
+ import { J as resolveProjectSettingsAsync, Nt as repoRootAsync, a as SETTING_SHAPE_REMEDY, et as settingShapeErrors, it as unknownSettingKeys, p as cacheProviderSettingError } from "./settings-C7O8A6ZI.mjs";
8
+ import { c as projectProblem, f as projectRegistry, i as findProjectRoot$1, r as findCommandWorkspaceAsync, t as NO_PROJECT_REFUSAL } from "./project-CTLNHCfE.mjs";
9
+ import { n as macosDir } from "./state-08I3hw3_.mjs";
9
10
  import { r as createNdjsonWriter } from "./ndjson-CgE_o3Dl.mjs";
10
- import { B as recordFinishedBuild, H as tapBuildLog, V as startBuildProgress } from "./budget-Bs6SxxzO.mjs";
11
- import { d as runCancellationSignal, f as withNativeBuildRun } from "./native-run-DY_RLx3C.mjs";
12
- import { c as ensureHomeIdentity, s as workspaceShareURL } from "./stim-desktop-C12we7lz.mjs";
13
- import { s as resolveBuildPlacement } from "./selection-CSl9i5qU.mjs";
14
- import { c as stopWorkspaceNow } from "./stop-CPzlM1L-.mjs";
15
- import { r as runReload } from "./reload-CmTRFJaX.mjs";
16
- import { s as recordDoctorCheck } from "./doctor-watchman-Cv1F10Kj.mjs";
17
- import { a as readDoctorReport } from "./doctor-Dhqebm0q.mjs";
18
- import { r as readGcReport } from "./gc-_-dCXdyL.mjs";
19
- import { r as readWorkspaceLogs, t as followWorkspaceLogs } from "./logs-BS00Anxf.mjs";
20
- import { t as readProjectStats } from "./stats-report-BFfMpWWF.mjs";
21
- import { n as buildAndroidOperation, t as buildIosOperation } from "./build-CoPzQRNw.mjs";
22
- import { i as runAndroidOperation } from "./android-BLgbNqox.mjs";
23
- import { r as runIosOperation } from "./ios-ubFsBzwq.mjs";
24
- import { i as buildMacosBundle, n as runMacos } from "./macos-C-0qJ6zq.mjs";
25
- import { t as runWeb } from "./web-CJmIj6AI.mjs";
26
- import { i as SettingsRefusal, o as readSettingsContext, s as readSettingsPayload, t as mutateSetting } from "./settings-write-HyVZ8eQ8.mjs";
11
+ import { B as recordFinishedBuild, H as tapBuildLog, V as startBuildProgress } from "./budget-DnPX3DXj.mjs";
12
+ import { d as runCancellationSignal, f as withNativeBuildRun } from "./native-run-BUTu8T7A.mjs";
13
+ import { c as ensureHomeIdentity, s as workspaceShareURL } from "./stim-desktop-D5OGpYZM.mjs";
14
+ import { s as resolveBuildPlacement } from "./selection-DSMbWEX2.mjs";
15
+ import { c as stopWorkspaceNow } from "./stop-B2uLQfoM.mjs";
16
+ import { r as runReload } from "./reload-DF9hqUUB.mjs";
17
+ import { c as startDevServer } from "./start-bjfiScgz.mjs";
18
+ import { s as recordDoctorCheck } from "./doctor-watchman-sy_RNhFt.mjs";
19
+ import { a as readDoctorReport } from "./doctor-D2SN3Ltx.mjs";
20
+ import { h as warmWorktreeTarget, m as removeWorktreeTarget } from "./worktree-8lqn_lBp.mjs";
21
+ import { i as readGcReport, n as executeGc, o as withGcMaintenanceClaim } from "./gc-CDoogxAI.mjs";
22
+ import { r as readWorkspaceLogs, t as followWorkspaceLogs } from "./logs-mxqsWpJs.mjs";
23
+ import { t as readProjectStats } from "./stats-report-BzaPrRm6.mjs";
24
+ import { n as buildAndroidOperation, t as buildIosOperation } from "./build-CqufZFqy.mjs";
25
+ import { a as readAndroidBuildPlan, i as runAndroidOperation } from "./android-BoUJKbfz.mjs";
26
+ import { i as readIosBuildPlan, r as runIosOperation } from "./ios-DZZbNYlY.mjs";
27
+ import { a as buildMacosBundle, i as planMacos, n as runMacos } from "./macos-u0BoHKnO.mjs";
28
+ import { t as runWeb } from "./web-CwREhjD-.mjs";
29
+ import { i as SettingsRefusal, o as readSettingsContext, s as readSettingsPayload, t as mutateSetting } from "./settings-write-79mQRr9C.mjs";
27
30
  import { randomBytes } from "node:crypto";
28
31
  import { mkdirSync, mkdtempSync, readFileSync, realpathSync, rmSync } from "node:fs";
29
32
  import { stripVTControlCharacters } from "node:util";
@@ -31,6 +34,7 @@ import { homedir } from "node:os";
31
34
  import { isAbsolute, join, resolve } from "node:path";
32
35
  import { withAmbientContext } from "@stim-cli/core";
33
36
  import { RUN_ID_ENV, findProjectRoot, openLogDir, validRunId } from "@stim-cli/core/state";
37
+ import { decodeSecret } from "@stim-cli/core/noise-session";
34
38
  //#region src/commands/macos-build.ts
35
39
  async function buildMacosOperation(context, root, options) {
36
40
  const note = (line) => context.output("stderr", `${line}\n`);
@@ -121,10 +125,10 @@ async function buildMacosOperation(context, root, options) {
121
125
  platform: "macos",
122
126
  status: build.state,
123
127
  configuration: "Debug",
124
- fingerprint: null,
125
- cacheKey: null,
126
- cacheHit: false,
127
- cacheSkipped: false,
128
+ fingerprint: build.fingerprint ?? null,
129
+ cacheKey: build.cacheKey ?? null,
130
+ cacheHit: build.cacheHit ? build.cacheSource === "provider" ? "remote" : "local" : false,
131
+ cacheSkipped: !build.cacheKey,
128
132
  durationMs: build.durationMs,
129
133
  startedAt: build.startedAt,
130
134
  errorCode: build.errorCode,
@@ -154,8 +158,8 @@ var StimError = class extends Error {
154
158
  code;
155
159
  remedy;
156
160
  details;
157
- constructor({ code, message, remedy = null, details }) {
158
- super(message);
161
+ constructor({ code, message, remedy = null, details }, options) {
162
+ super(message, options);
159
163
  this.name = "StimError";
160
164
  this.code = code;
161
165
  this.remedy = remedy;
@@ -224,7 +228,7 @@ function createStim(options) {
224
228
  dispose: () => signal?.removeEventListener("abort", abort)
225
229
  };
226
230
  };
227
- const report = async (signal, work) => {
231
+ const beginReport = (signal) => {
228
232
  const operation = begin(signal, true);
229
233
  operation.context.env.STIM_HOME = clientContext.env.STIM_HOME;
230
234
  for (const name of [
@@ -235,14 +239,23 @@ function createStim(options) {
235
239
  const directory = operation.context.env[name]?.trim();
236
240
  if (directory) operation.context.env[name] = resolve(operation.context.cwd, directory);
237
241
  }
242
+ return operation;
243
+ };
244
+ const report = async (signal, work, timeoutMs) => {
245
+ const operation = beginReport(signal);
238
246
  try {
239
- return await read(operation, (context) => runReport(context, (request) => withAmbientContext(request, () => work(request))));
247
+ return await read(operation, (context) => runReport(context, (request) => withAmbientContext(request, () => work(request)), timeoutMs));
240
248
  } finally {
241
249
  operation.dispose();
242
250
  }
243
251
  };
244
252
  return {
245
253
  projectRoot,
254
+ start: ({ signal, ...request } = {}) => {
255
+ const operation = begin(signal, true);
256
+ operation.context.env.STIM_HOME = clientContext.env.STIM_HOME;
257
+ return lifecycle(operation, (context) => start(context, request));
258
+ },
246
259
  identity: ({ signal } = {}) => read(begin(signal), (operation) => ensureHomeIdentity(operation.signal)),
247
260
  doctor: async ({ signal, platform, record } = {}) => {
248
261
  if (platform !== void 0 && platform !== "ios" && platform !== "android") return Promise.reject(new StimError({
@@ -256,6 +269,53 @@ function createStim(options) {
256
269
  return result;
257
270
  });
258
271
  },
272
+ requestMachineAccess: async ({ signal, ticket } = {}) => {
273
+ if (ticket !== void 0 && (typeof ticket !== "string" || !decodeSecret(ticket.trim()))) throw new StimError({
274
+ code: "STIM_BAD_ARG",
275
+ message: "The setup ticket must encode 32 random bytes."
276
+ });
277
+ const result = await report(signal, (context) => {
278
+ context.env.STIM_ACCESS_TICKET = ticket?.trim();
279
+ return readDoctorReport(context, "ios", version, true);
280
+ }, 12e4);
281
+ return read(begin(signal), async (context) => {
282
+ await recordDoctorCheck(result.project, "ios", version, context.signal);
283
+ return result;
284
+ });
285
+ },
286
+ plan: ({ signal, ...request }) => report(signal, (context) => {
287
+ const task = Promise.resolve().then(async () => {
288
+ if (request.platform === "macos") try {
289
+ return await planMacos(context, findProjectRoot$1(context.projectRoot) ?? context.projectRoot);
290
+ } catch (cause) {
291
+ if (cause instanceof Error && "reportCleanup" in cause) throw cause;
292
+ context.signal.throwIfAborted();
293
+ const code = cause instanceof Error && "code" in cause && typeof cause.code === "string" ? cause.code : "STIM_BAD_ARG";
294
+ const remedy = cause instanceof Error && "remedy" in cause && typeof cause.remedy === "string" ? cause.remedy : "Check the macOS project settings in stim guide macos.";
295
+ throw new StimError({
296
+ code,
297
+ message: cause instanceof Error ? cause.message : String(cause),
298
+ remedy
299
+ });
300
+ }
301
+ if (request.platform !== "ios" && request.platform !== "android") throw new StimError({
302
+ code: "STIM_BAD_ARG",
303
+ message: "platform must be ios, android or macos."
304
+ });
305
+ const selectors = { slot: validateDeviceSlot(request.slot) };
306
+ const result = request.platform === "ios" ? await readIosBuildPlan(context, selectors) : await readAndroidBuildPlan(context, selectors);
307
+ context.signal.throwIfAborted();
308
+ if ("platform" in result) return result;
309
+ throw new StimError({
310
+ ...result.refusal,
311
+ details: { lines: result.lines }
312
+ });
313
+ });
314
+ trackReportResource(context, task.then(() => void 0, (cause) => {
315
+ if (cause instanceof Error && "reportCleanup" in cause) throw cause;
316
+ }), () => {});
317
+ return task;
318
+ }),
259
319
  gc: ({ signal, olderThan, cache, worktrees } = {}) => {
260
320
  if (olderThan !== void 0 && !Number.isSafeInteger(olderThan)) return Promise.reject(new StimError({
261
321
  code: "STIM_BAD_ARG",
@@ -274,6 +334,82 @@ function createStim(options) {
274
334
  return result;
275
335
  });
276
336
  },
337
+ collectGarbage: ({ signal, olderThan, cache, worktrees, delete: deleting, idleMs } = {}) => {
338
+ const invalid = olderThan !== void 0 && !Number.isSafeInteger(olderThan) ? "olderThan must be a whole number of days." : cache !== void 0 && (typeof cache !== "string" || !cache.trim()) ? "cache must name a cache." : worktrees !== void 0 && typeof worktrees !== "boolean" ? "worktrees must be a boolean." : deleting !== void 0 && typeof deleting !== "boolean" ? "delete must be a boolean." : idleMs !== void 0 && (!Number.isSafeInteger(idleMs) || idleMs <= 0) ? "idleMs must be a positive whole number of milliseconds." : null;
339
+ if (invalid) return Promise.reject(new StimError({
340
+ code: "STIM_BAD_ARG",
341
+ message: invalid
342
+ }));
343
+ const operation = beginReport(signal);
344
+ const request = {
345
+ olderThan,
346
+ cache,
347
+ worktrees,
348
+ delete: deleting,
349
+ idle: idleMs,
350
+ json: true
351
+ };
352
+ return lifecycle(operation, (context) => withGcMaintenanceClaim(request, (claim) => runReport(context, (bounded) => withAmbientContext(bounded, () => {
353
+ const task = executeGc(request, {
354
+ operation: bounded,
355
+ easLedgerRoot: join(bounded.env.HOME || bounded.env.USERPROFILE || homedir(), ".stim", "machine", "eas")
356
+ }, (_stream, line) => bounded.output("stderr", `${line}\n`), claim).then(({ payload, exitCode }) => {
357
+ if ("code" in payload) throw new StimError(payload);
358
+ return {
359
+ report: payload,
360
+ exitCode
361
+ };
362
+ });
363
+ trackReportResource(bounded, task.then(() => void 0, (cause) => {
364
+ if (cause instanceof WorkspaceProcessCleanupError || cause instanceof Error && "reportCleanup" in cause) throw cause;
365
+ }), () => {});
366
+ return task;
367
+ }))).catch((cause) => {
368
+ if (cause instanceof WorkspaceProcessCleanupError) throw cause;
369
+ const failure = (0, ownership_claim_exports.claimFailure)(cause, null);
370
+ if (failure) throw new StimError(failure);
371
+ throw cause;
372
+ }));
373
+ },
374
+ warmWorktree: ({ signal, beforeWarm } = {}) => lifecycle(beginReport(signal), (context) => runReport(context, (bounded) => withAmbientContext(bounded, () => {
375
+ const task = warmWorktreeTarget({
376
+ cwd: bounded.cwd,
377
+ operation: bounded,
378
+ beforeWarm
379
+ });
380
+ trackReportResource(bounded, task.then(() => void 0, (cause) => {
381
+ if (cause instanceof WorkspaceProcessCleanupError || cause instanceof Error && "reportCleanup" in cause) throw cause;
382
+ }), () => {});
383
+ return task;
384
+ }), 54e5)),
385
+ removeWorktree: ({ signal, target, force, beforeRemove } = {}) => {
386
+ const invalid = target !== void 0 && (typeof target !== "string" || target.length === 0) ? "target must be a nonempty path." : force !== void 0 && typeof force !== "boolean" ? "force must be a boolean." : null;
387
+ if (invalid) return Promise.reject(new StimError({
388
+ code: "STIM_BAD_ARG",
389
+ message: invalid
390
+ }));
391
+ return lifecycle(beginReport(signal), (context) => runReport(context, (bounded) => withAmbientContext(bounded, () => {
392
+ let exitCode = 0;
393
+ const task = removeWorktreeTarget(resolve(bounded.cwd, target ?? "."), {
394
+ force,
395
+ beforeRemove,
396
+ operation: bounded,
397
+ output: {
398
+ error: (line) => bounded.output("stderr", `${line}\n`),
399
+ fail: () => {
400
+ exitCode = 1;
401
+ }
402
+ }
403
+ }).then((removed) => ({
404
+ removed,
405
+ exitCode
406
+ }));
407
+ trackReportResource(bounded, task.then(() => void 0, (cause) => {
408
+ if (cause instanceof WorkspaceProcessCleanupError || cause instanceof Error && "reportCleanup" in cause) throw cause;
409
+ }), () => {});
410
+ return task;
411
+ })));
412
+ },
277
413
  settings: ({ signal } = {}) => read(begin(signal), async (operation) => readSettingsPayload(await readSettingsContext(operation.projectRoot, {
278
414
  ...operation.env,
279
415
  STIM_HOME: clientContext.env.STIM_HOME
@@ -320,7 +456,8 @@ function createStim(options) {
320
456
  build: (({ signal, ...request }) => lifecycle(begin(signal, true), (operation) => build(operation, request))),
321
457
  run: (({ signal, ...request }) => lifecycle(begin(signal, true), (operation) => run(operation, request))),
322
458
  stop: ({ signal, ...request } = {}) => read(begin(signal), async (operation) => {
323
- const root = operation.projectRoot;
459
+ const root = findProjectRoot$1(operation.projectRoot) ?? operation.projectRoot;
460
+ request.beforeStop?.(root);
324
461
  const logs = workspaceLogsDir$1(root);
325
462
  let result;
326
463
  try {
@@ -416,16 +553,17 @@ async function read({ context, callback }, operation) {
416
553
  refuseRelativeStimPaths(context.env);
417
554
  result = await withAmbientContext(context, () => operation(context));
418
555
  } catch (error) {
419
- if ("error" in callback) throw callback.error;
420
- if (signal.aborted && !(error instanceof Error && "reportCleanup" in error)) throw cancelled();
556
+ const cleanupUnresolved = error instanceof Error && ("reportCleanup" in error || "code" in error && error.code === "STIM_CLAIM_UNAVAILABLE");
557
+ if ("error" in callback && !cleanupUnresolved) throw callback.error;
558
+ if (signal.aborted && !cleanupUnresolved) throw cancelled();
421
559
  if (error instanceof StimError) throw error;
422
560
  if (error instanceof Error && "code" in error && typeof error.code === "string" && error.code.startsWith("STIM_")) {
423
- const remedy = error instanceof SettingsRefusal ? error.remedy : null;
561
+ const remedy = error instanceof SettingsRefusal ? error.remedy : cleanupUnresolved && "remedy" in error && typeof error.remedy === "string" ? error.remedy : null;
424
562
  throw new StimError({
425
563
  code: error.code,
426
564
  message: error.message,
427
565
  remedy
428
- });
566
+ }, cleanupUnresolved ? { cause: error } : void 0);
429
567
  }
430
568
  throw error;
431
569
  }
@@ -456,7 +594,7 @@ async function lifecycle(operation, work) {
456
594
  remedy: failure?.remedy ?? null,
457
595
  details: {
458
596
  logs,
459
- cause: failure?.details
597
+ cause: error instanceof WorkspaceProcessCleanupError ? { retainedClaimRoots: [...new Set(error.claims.map((claim) => claim.root))] } : failure?.details
460
598
  }
461
599
  });
462
600
  }
@@ -465,6 +603,63 @@ async function lifecycle(operation, work) {
465
603
  operation.dispose();
466
604
  }
467
605
  }
606
+ async function start(context, options) {
607
+ if (options.waitSeconds !== void 0 && (!Number.isSafeInteger(options.waitSeconds) || options.waitSeconds <= 0)) throw new StimError({
608
+ code: "STIM_BAD_ARG",
609
+ message: "waitSeconds must be a positive whole number."
610
+ });
611
+ const root = findProjectRoot$1(context.projectRoot);
612
+ if (!root) throw new StimError(NO_PROJECT_REFUSAL);
613
+ const problem = projectProblem(root, "dev-server");
614
+ if (problem) throw new StimError({
615
+ code: "STIM_NO_PROJECT",
616
+ ...problem
617
+ });
618
+ options.beforeStart?.(root);
619
+ context.signal.throwIfAborted();
620
+ return withAmbientContext({
621
+ ...context,
622
+ projectRoot: root
623
+ }, async () => {
624
+ const { context: settingsContext, settings } = await resolveProjectSettingsAsync(root, {
625
+ env: context.env,
626
+ signal: context.signal
627
+ });
628
+ const shapeErrors = settingShapeErrors(settings);
629
+ if (shapeErrors.length) throw new StimError({
630
+ code: "STIM_BAD_ARG",
631
+ message: shapeErrors.join("\n"),
632
+ remedy: SETTING_SHAPE_REMEDY
633
+ });
634
+ for (const key of unknownSettingKeys(settings)) note(context)(`Warning: setting "${key}" is not read by Stim and will be ignored.`);
635
+ const cacheError = cacheProviderSettingError(settings);
636
+ if (cacheError) note(context)(`Warning: ${cacheError} No cache provider is used.`);
637
+ await ensureWorkspaceStorageAsync(root, context.signal);
638
+ await recordWorkspaceUseAsync(root, /* @__PURE__ */ new Date(), context.env, context.cwd, context.signal);
639
+ const result = await startDevServer({
640
+ root,
641
+ settings,
642
+ settingsContext,
643
+ waitSeconds: options.waitSeconds,
644
+ remote: options.remote,
645
+ resetCache: options.resetCache,
646
+ out: (line) => context.output("stdout", `${line}\n`),
647
+ note: note(context)
648
+ });
649
+ if (!result.ok) {
650
+ for (const line of result.lines) note(context)(line);
651
+ throw new StimError({
652
+ ...result.error,
653
+ details: {
654
+ lines: result.lines,
655
+ reclaimed: result.reclaimed,
656
+ ...result.retainedClaimRoots ? { retainedClaimRoots: result.retainedClaimRoots } : {}
657
+ }
658
+ });
659
+ }
660
+ return result.facts;
661
+ });
662
+ }
468
663
  async function reload(context, options) {
469
664
  if (options.platform !== void 0 && ![
470
665
  "ios",
@@ -540,7 +735,8 @@ async function run(context, options) {
540
735
  if (!result.ok || !result.facts) throw new StimError({
541
736
  code: result.error?.code ?? "STIM_RUN_FAILED",
542
737
  message: result.error?.message ?? "The Android run failed.",
543
- remedy: result.error?.remedy
738
+ remedy: result.error?.remedy,
739
+ details: result.error
544
740
  });
545
741
  return {
546
742
  platform: "android",
@@ -548,7 +744,7 @@ async function run(context, options) {
548
744
  };
549
745
  }
550
746
  case "macos": {
551
- const record = await runMacos(context, root, note(context), void 0, options.remoteBuild);
747
+ const record = await runMacos(context, root, note(context), options.remote, options.remoteBuild);
552
748
  return {
553
749
  platform: "macos",
554
750
  facts: {
@@ -557,7 +753,7 @@ async function run(context, options) {
557
753
  bundleId: record.bundleId,
558
754
  executable: record.executable,
559
755
  pid: record.app?.pid ?? null,
560
- launched: record.app !== void 0,
756
+ launched: record.hostLaunched ?? record.app !== void 0,
561
757
  build: record.build,
562
758
  logs: { dir: workspaceLogsDir$1(root) }
563
759
  }
@@ -571,6 +767,7 @@ async function run(context, options) {
571
767
  context
572
768
  });
573
769
  if (!result.ok) throw new StimError(result.error);
770
+ if (result.remedy) note(context)(result.remedy);
574
771
  return {
575
772
  platform: "web",
576
773
  facts: result.facts
@@ -1,18 +1,18 @@
1
- import { d as withDrainingCancellation, f as ownership_claim_exports } from "./exec-_UbtCQcG.mjs";
1
+ import { h as withDrainingCancellation, x as ownership_claim_exports } from "./exec-DEoAhcze.mjs";
2
2
  import { d as workspaceDir } from "./paths-DQtTgsBf.mjs";
3
- import { _ as stepTimer, i as formatDuration, l as phaseLine, m as shortHash } from "./command-output-B1UrjZHL.mjs";
4
- import { en as throwIfCancelled } from "./settings-CsJDEXgK.mjs";
5
- import { Hn as isEasAuthFailureText, Ln as RESOLVE_TIMEOUT_MS, Vn as easAuthNote } from "./budget-Bs6SxxzO.mjs";
6
- import { d as runCancellationSignal, r as cancelledFailure } from "./native-run-DY_RLx3C.mjs";
7
- import { d as prepareProviderDownloadDir, f as providerDownloadPath } from "./build-cache-DmyR9Zzc.mjs";
8
- import { n as CCACHE_UNAVAILABLE, r as ccacheActivityLine, t as CCACHE_NOT_RUN } from "./ccache-BJRZ9pG3.mjs";
9
- import { c as offloadPlacement, i as closeOffload, l as placementLoad, n as buildPlacementCandidates, o as offloadBuild, r as chooseBuildMachine, u as remotePhaseText } from "./client-UXD70ZbM.mjs";
10
- import { a as requireLocalBuild, r as namedBuildMachine, t as OffloadRefusal } from "./selection-CSl9i5qU.mjs";
11
- import { f as formatDiagnostic } from "./react-native-build-rhk4smwQ.mjs";
12
- import { c as skippedMissReason } from "./prebuild-uD_ipCxF.mjs";
13
- import { t as buildPlacementRecord } from "./placement-log-BqGbTa61.mjs";
14
- import { t as acquireArtifact } from "./acquire-artifact-CD4lbiWE.mjs";
15
- import { a as PLATFORM, h as displayPath } from "./support-67vraa1Q.mjs";
3
+ import { _ as stepTimer, i as formatDuration, l as phaseLine, m as shortHash } from "./command-output-Db8BqzxH.mjs";
4
+ import { f as throwIfCancelled } from "./operation-exec-BW0em61G.mjs";
5
+ import { Hn as isEasAuthFailureText, Ln as RESOLVE_TIMEOUT_MS, Vn as easAuthNote } from "./budget-DnPX3DXj.mjs";
6
+ import { d as runCancellationSignal, r as cancelledFailure } from "./native-run-BUTu8T7A.mjs";
7
+ import { d as prepareProviderDownloadDir, f as providerDownloadPath } from "./build-cache-Dv7RN200.mjs";
8
+ import { n as CCACHE_UNAVAILABLE, r as ccacheActivityLine, t as CCACHE_NOT_RUN } from "./ccache-RcAy92gH.mjs";
9
+ import { c as offloadPlacement, i as closeOffload, l as placementLoad, n as buildPlacementCandidates, o as offloadBuild, r as chooseBuildMachine, u as remotePhaseText } from "./client-yyso1bwi.mjs";
10
+ import { a as requireLocalBuild, r as namedBuildMachine, t as OffloadRefusal } from "./selection-DSMbWEX2.mjs";
11
+ import { f as formatDiagnostic } from "./react-native-build-CmJkTljQ.mjs";
12
+ import { l as skippedMissReason } from "./prebuild-BFm63bQ0.mjs";
13
+ import { t as buildPlacementRecord } from "./placement-log-BnGgJRRZ.mjs";
14
+ import { n as settleArtifactUploads, t as acquireArtifact } from "./acquire-artifact-ybouwJSR.mjs";
15
+ import { a as PLATFORM, h as displayPath } from "./support-DTBV56gy.mjs";
16
16
  import { t as AndroidRecipeRefusal } from "./android-project-BCAAmMwz.mjs";
17
17
  import { rmSync } from "node:fs";
18
18
  import { join } from "node:path";
@@ -74,6 +74,7 @@ async function acquireAndroidArtifact({ context, root, buildLog, writer, recipe,
74
74
  const loadTieredProvider = cachePolicy.remote && cacheProviderConfig ? () => providerLoad ??= loadCacheProviderModule({
75
75
  projectRoot: root,
76
76
  config: cacheProviderConfig,
77
+ env: context.env,
77
78
  timeoutMs: timeoutFromEnv(PROVIDER_LOAD_TIMEOUT_ENV, PROVIDER_LOAD_TIMEOUT_MS, context.env)
78
79
  }).then((loaded) => {
79
80
  if (!loaded.provider || !recipe.providerCache) return loaded;
@@ -160,9 +161,9 @@ async function acquireAndroidArtifact({ context, root, buildLog, writer, recipe,
160
161
  let abandonedRemote = false;
161
162
  let uploadPending = null;
162
163
  async function resolveRemoteArtifact() {
163
- if (cacheIneligible || !recipe.legacyCache) return;
164
+ if (cacheIneligible || !recipe.expoCache) return;
164
165
  if (!apkPath) {
165
- const loaded = await recipe.legacyCache.load();
166
+ const loaded = await recipe.expoCache.load();
166
167
  if (loaded?.unavailable) phase("cache", chalk.yellow(`provider not usable: ${loaded.unavailable}`));
167
168
  else if (loaded?.provider) remote = loaded;
168
169
  if (remote?.name === "eas") {
@@ -185,7 +186,7 @@ async function acquireAndroidArtifact({ context, root, buildLog, writer, recipe,
185
186
  platform: PLATFORM,
186
187
  projectRoot: root,
187
188
  fingerprintHash: hash,
188
- runOptions: recipe.legacyCache?.runOptions ?? null
189
+ runOptions: recipe.expoCache?.runOptions ?? null
189
190
  });
190
191
  if (hit?.appPath) {
191
192
  let stored = null;
@@ -333,6 +334,14 @@ async function acquireAndroidArtifact({ context, root, buildLog, writer, recipe,
333
334
  });
334
335
  if (!placement.offload) {
335
336
  hereReason = placement.reason;
337
+ if (placement.code === "this-mac-free" && cachePolicy.read && cachePolicy.remote && (recipe.offload?.uncachedArtifacts || recipe.offload && !recipe.offload.request.native)) return {
338
+ cacheOnly: true,
339
+ mode,
340
+ here,
341
+ code: placement.code,
342
+ reason: placement.reason,
343
+ machines
344
+ };
336
345
  writer.write(buildPlacementRecord({
337
346
  platform: PLATFORM,
338
347
  buildMachine,
@@ -345,6 +354,7 @@ async function acquireAndroidArtifact({ context, root, buildLog, writer, recipe,
345
354
  return null;
346
355
  }
347
356
  return {
357
+ cacheOnly: false,
348
358
  mode,
349
359
  here,
350
360
  code: placement.code,
@@ -354,14 +364,17 @@ async function acquireAndroidArtifact({ context, root, buildLog, writer, recipe,
354
364
  }
355
365
  /** Asks the paired machines once the post-mutation key is known; null builds here. */
356
366
  async function chooseMachine(candidate) {
367
+ const offload = recipe.offload;
357
368
  let asked = [];
358
369
  let target;
359
370
  try {
360
- target = await recipe.offload.target();
371
+ target = await offload.target();
361
372
  } catch (error) {
373
+ if (candidate.cacheOnly) return null;
362
374
  fallBack(error.message);
363
375
  return null;
364
376
  }
377
+ const request = offload.request;
365
378
  const choice = await chooseBuildMachine({
366
379
  projectRoot: root,
367
380
  target,
@@ -370,9 +383,23 @@ async function acquireAndroidArtifact({ context, root, buildLog, writer, recipe,
370
383
  note: (line) => phase("build", chalk.dim(`offload: ${line}`)),
371
384
  machines: candidate.machines,
372
385
  selected: buildMachine,
373
- onCandidates: (each) => asked = each
386
+ onCandidates: (each) => asked = each,
387
+ cacheOnly: candidate.cacheOnly,
388
+ ...cachePolicy.read && cachePolicy.remote && storeHash && !request.native ? { reactNativeArtifact: {
389
+ fingerprint: storeHash,
390
+ request
391
+ } } : {},
392
+ ...cachePolicy.read && cachePolicy.remote && request.native?.provider === "gradle" && request.android.variant ? { gradleArtifact: {
393
+ sourceDigest: request.native.transfer.digest,
394
+ inputs: request.native.transfer.declaration,
395
+ android: {
396
+ ...request.android,
397
+ variant: request.android.variant
398
+ }
399
+ } } : {}
374
400
  });
375
401
  if (typeof choice === "string") {
402
+ if (candidate.cacheOnly) return null;
376
403
  const only = candidate.machines.length === 1 ? candidate.machines[0].machine : null;
377
404
  if (only && choice.startsWith(`${only}: `)) fallbackMachine = only;
378
405
  fallBack(choice, choice, {
@@ -473,6 +500,7 @@ async function acquireAndroidArtifact({ context, root, buildLog, writer, recipe,
473
500
  throwIfCancelled(signal, "offloaded build cache copy");
474
501
  step("compile");
475
502
  if (!outcome.ok || !stored) {
503
+ if (candidate.cacheOnly) return false;
476
504
  const why = reason ?? "the APK was not stored";
477
505
  fallbackMachine = choice.machine;
478
506
  fallBack(`${choice.machine}: ${why}`, `offload failed: ${why}`, {
@@ -492,9 +520,10 @@ async function acquireAndroidArtifact({ context, root, buildLog, writer, recipe,
492
520
  if (uncached) {
493
521
  record.fingerprint = null;
494
522
  record.cacheKey = null;
495
- record.cacheHit = false;
496
- record.cacheSkipped = true;
523
+ record.cacheHit = outcome.cacheHit ? "remote" : false;
524
+ record.cacheSkipped = !outcome.cacheHit;
497
525
  }
526
+ if (outcome.cacheHit) lateHit();
498
527
  apkPath = stored;
499
528
  handoff = outcome.handoff ?? null;
500
529
  record.builtOn = outcome.machine;
@@ -506,13 +535,13 @@ async function acquireAndroidArtifact({ context, root, buildLog, writer, recipe,
506
535
  buildMs: timings.totalMs
507
536
  });
508
537
  ccacheActivity = outcome.ccache;
509
- phase("build", `built on ${outcome.machine} in ${formatDuration(timings.totalMs)}: offer ${formatDuration(timings.offerMs)}, sync ${formatDuration(timings.syncMs)}, build ${formatDuration(timings.workerMs)}, fetch ${formatDuration(timings.fetchMs)}`);
538
+ phase("build", `${outcome.cacheHit ? "reused from" : "built on"} ${outcome.machine} in ${formatDuration(timings.totalMs)}: offer ${formatDuration(timings.offerMs)}, sync ${formatDuration(timings.syncMs)}, build ${formatDuration(timings.workerMs)}, fetch ${formatDuration(timings.fetchMs)}`);
510
539
  phase("cache", `compilation cache on ${outcome.machine} ${ccacheActivityLine(ccacheActivity)}`);
511
540
  writer.write({
512
541
  src: "build",
513
542
  level: "info",
514
543
  event: "offload_done",
515
- msg: `built on ${outcome.machine}`,
544
+ msg: `${outcome.cacheHit ? "reused from" : "built on"} ${outcome.machine}`,
516
545
  timings
517
546
  });
518
547
  return true;
@@ -574,7 +603,7 @@ async function acquireAndroidArtifact({ context, root, buildLog, writer, recipe,
574
603
  explainMiss(rekeyedBy);
575
604
  step("compile");
576
605
  }
577
- if (offload) stats.setPlacement({
606
+ if (offload && !offload.cacheOnly) stats.setPlacement({
578
607
  decision: "fell-back",
579
608
  slotWaitMs,
580
609
  deviceSlotWaitMs: stats.deviceSlotWaitMs(),
@@ -664,16 +693,19 @@ async function acquireAndroidArtifact({ context, root, buildLog, writer, recipe,
664
693
  phase("cache", chalk.yellow(`could not store the build: ${err?.message || err}`));
665
694
  }
666
695
  }
667
- if (remote) uploadPending = uploadRemoteBuild({
668
- context,
669
- logWriter: writer,
670
- provider: remote.provider,
671
- platform: PLATFORM,
672
- projectRoot: root,
673
- fingerprintHash: storeHash,
674
- buildPath: artifactPath,
675
- runOptions: recipe.legacyCache?.runOptions ?? null
676
- });
696
+ if (remote) {
697
+ uploadPending = uploadRemoteBuild({
698
+ context,
699
+ logWriter: writer,
700
+ provider: remote.provider,
701
+ platform: PLATFORM,
702
+ projectRoot: root,
703
+ fingerprintHash: storeHash,
704
+ buildPath: artifactPath,
705
+ runOptions: recipe.expoCache?.runOptions ?? null
706
+ });
707
+ uploadPending.catch(() => {});
708
+ }
677
709
  }
678
710
  const acquired = await acquireArtifact({
679
711
  platform: PLATFORM,
@@ -719,7 +751,7 @@ async function acquireAndroidArtifact({ context, root, buildLog, writer, recipe,
719
751
  };
720
752
  },
721
753
  settleFailed: async () => {
722
- await Promise.allSettled([uploadPending, providerUpload]);
754
+ await settleArtifactUploads(uploadPending, providerUpload);
723
755
  },
724
756
  refuse: (error) => {
725
757
  if (error instanceof OffloadRefusal) {
@@ -759,11 +791,8 @@ async function acquireAndroidArtifact({ context, root, buildLog, writer, recipe,
759
791
  handoff,
760
792
  androidPackage,
761
793
  release: async () => {
762
- try {
763
- await Promise.allSettled([providerUpload, remote?.provider && "easCli" in remote.provider ? uploadPending : null]);
764
- } finally {
765
- acquired.release();
766
- }
794
+ await settleArtifactUploads(providerUpload, uploadPending);
795
+ acquired.release();
767
796
  },
768
797
  waitedForBuild,
769
798
  ccache: ccacheActivity,