stim 1.19.0 → 1.20.1

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 (172) hide show
  1. package/README.md +20 -3
  2. package/dist/{activity-BSw0x84R.mjs → activity-BaMpUQ4-.mjs} +3 -3
  3. package/dist/{agent-device-usage-output-Bjxu_VmX.mjs → agent-device-usage-output-VPaOgGaF.mjs} +7 -7
  4. package/dist/android-CLbBJ2ve.mjs +1258 -0
  5. package/dist/{android-DE5g_5gv.mjs → android-CZh6ElG5.mjs} +2 -2
  6. package/dist/{android-BdQC6zs1.mjs → android-DE8-JfGW.mjs} +105 -47
  7. package/dist/{android-cas-C87geAg-.mjs → android-cas-BFpS84v2.mjs} +9 -5
  8. package/dist/android-cas-compiler.mjs +1 -1
  9. package/dist/android-eXfIjKJr.mjs +6 -0
  10. package/dist/api-run.mjs +159 -8
  11. package/dist/{api-DIf_s86s.mjs → api-zuX3ynYN.mjs} +5 -1
  12. package/dist/api.d.mts +98 -4
  13. package/dist/api.mjs +1 -1
  14. package/dist/{app-install-CFI4ptUL.mjs → app-install-Cg9YJy3x.mjs} +9 -8
  15. package/dist/artifact-Ctb2jpw6.mjs +807 -0
  16. package/dist/artifact-DXk_Fle_.mjs +772 -0
  17. package/dist/artifact-lifecycle-DzPpBYvK.mjs +30 -0
  18. package/dist/{browser-web-CDhqQxhv.mjs → browser-web-xQWC2RWl.mjs} +19 -19
  19. package/dist/{budget-Dz-kyXLv.mjs → budget-RFbwFpG5.mjs} +3101 -3062
  20. package/dist/build-COBA1tBc.mjs +462 -0
  21. package/dist/{build-facts-B87vo-Im.d.mts → build-facts-DcLv2HSd.d.mts} +1 -32
  22. package/dist/build-plan-CRjAA6Qi.mjs +553 -0
  23. package/dist/{cache-manifest-DiwKSyv9.mjs → cache-manifest-qA3dT2x2.mjs} +1 -1
  24. package/dist/cache-manifest.mjs +1 -1
  25. package/dist/{manifest-CX0d1IkZ.mjs → ccache-CtbqWxIC.mjs} +13 -19
  26. package/dist/{chrome-BTUOo8p2.mjs → chrome-Dp2lMLBe.mjs} +1 -1
  27. package/dist/{cli-C9Zvgbdc.mjs → cli-sGqlPu1n.mjs} +20 -20
  28. package/dist/cli.mjs +1 -1
  29. package/dist/{client-CuUo8Nvg.mjs → client-zqjFd79D.mjs} +89 -307
  30. package/dist/collector-run.d.mts +4 -0
  31. package/dist/collector-run.mjs +7 -7
  32. package/dist/{command-output-Bt8ygHE7.mjs → command-output-CPDq_90S.mjs} +2 -2
  33. package/dist/{config-DC5jEtd1.mjs → config-D0LhTY3S.mjs} +8 -12
  34. package/dist/{created-devices-D0s26Hx5.mjs → created-devices-CXBMtoj5.mjs} +7 -6
  35. package/dist/{dependency-state-DKaS1OM9.mjs → dependency-state-B2m8eqsS.mjs} +2 -2
  36. package/dist/{detached-entry-pB_IPfV4.mjs → detached-entry-BXq4fIl-.mjs} +1 -1
  37. package/dist/{dev-client-CDY_zAmD.mjs → dev-client-BqYjMIaC.mjs} +2 -2
  38. package/dist/{device-BHw0WlHl.mjs → device-BgNj-qVj.mjs} +8 -8
  39. package/dist/device-D4DqjSZZ.mjs +727 -0
  40. package/dist/{device-capacity-BoN1jQkO.mjs → device-capacity-DrwHwR97.mjs} +13 -14
  41. package/dist/device-host-worker.mjs +38 -18
  42. package/dist/device-ios-DE8KJd3b.mjs +413 -0
  43. package/dist/{device-lease-Cu7PtQpZ.mjs → device-lease-C309csaB.mjs} +138 -24
  44. package/dist/{device-lease-run-D38SnZtt.mjs → device-lease-run-Baelt3nc.mjs} +4 -4
  45. package/dist/{device-pool-CP4rAsHx.mjs → device-pool-DtK9S6AD.mjs} +3 -3
  46. package/dist/{device-remote-B5GiUifk.mjs → device-remote-DjsNw8DD.mjs} +17 -68
  47. package/dist/doctor-DiP9HsIP.mjs +515 -0
  48. package/dist/{doctor-PRJH94v6.mjs → doctor-Dunu3Nv1.mjs} +333 -744
  49. package/dist/{doctor-watchman-wZhyTdp4.mjs → doctor-watchman-XJzT8tK-.mjs} +15 -13
  50. package/dist/{simslim-D9LkJxIO.mjs → eas-build-0gadvrca.mjs} +6 -152
  51. package/dist/{stim-installations-DbmUjsLv.mjs → eas-session-ledger-DJDeL4Uq.mjs} +57 -4
  52. package/dist/{error-diagnostics--v5HGOU0.mjs → error-diagnostics-BhQtoLrZ.mjs} +17 -12
  53. package/dist/errors-DzkMYh8Q.mjs +205 -0
  54. package/dist/{exec-i8GDPwq9.mjs → exec-B81Qodjn.mjs} +40 -10
  55. package/dist/{gc-CyHMcKcn.mjs → gc-D5cz5G0k.mjs} +22 -21
  56. package/dist/{device-ios-B2ruohE-.mjs → gradle-CZZo1TSA.mjs} +21 -650
  57. package/dist/{guide-dRaQJJk9.mjs → guide-DakjcoUt.mjs} +503 -251
  58. package/dist/{hosted-android-Bs7fytj7.mjs → hosted-android-C-D8Dj0_.mjs} +5 -5
  59. package/dist/{hosted-client-C5G4h_OJ.mjs → hosted-client--hNFgixu.mjs} +9 -3
  60. package/dist/{hosted-ios-Bik035eL.mjs → hosted-ios-Chx9XQyI.mjs} +3 -3
  61. package/dist/{hosted-logs-CI9Az9a4.mjs → hosted-logs-Bkz0Hxzh.mjs} +8 -8
  62. package/dist/{hosted-macos-DABm3ScO.mjs → hosted-macos-ckTjN-0V.mjs} +7 -6
  63. package/dist/{hosted-native-DbV2aUVw.mjs → hosted-native-3KXZ5-qn.mjs} +17 -14
  64. package/dist/{idle-shutdown-DYiMBn34.mjs → idle-shutdown-DhAUyf5s.mjs} +7 -7
  65. package/dist/{ios-DYUr9LGc.mjs → ios-BDBN-xpf.mjs} +8 -7
  66. package/dist/ios-CQ8bHQXB.mjs +1112 -0
  67. package/dist/{ios-DCrkgXEM.mjs → ios-VGvNdsv2.mjs} +1 -1
  68. package/dist/{ios-device-CrW8aMb5.mjs → ios-device-B1B14xND.mjs} +1 -1
  69. package/dist/{ios-device-CJ_ZOGky.mjs → ios-device-BWHKGaJq.mjs} +3 -3
  70. package/dist/{ios-BWbHFZVz.mjs → ios-o896T9PE.mjs} +195 -35
  71. package/dist/ios-project-BeOXKPt2.mjs +197 -0
  72. package/dist/{ios-state-By0XuLTQ.mjs → ios-state-BsXMwo5y.mjs} +1 -1
  73. package/dist/js-swap-Z_mSuRrx.mjs +432 -0
  74. package/dist/{react-native-ios-CSpIxexZ.mjs → launch-BootbMk4.mjs} +59 -612
  75. package/dist/launch-V1zqiOYn.mjs +745 -0
  76. package/dist/{launch-verify-DCveSE6d.mjs → launch-verify-Dl78EVgR.mjs} +26 -7
  77. package/dist/{logs-Bao1HOMy.mjs → logs-Bh4eqCCc.mjs} +11 -11
  78. package/dist/{macos-ciyBdTY5.mjs → macos-D7irBW3A.mjs} +42 -50
  79. package/dist/macos-kivF8qKz.mjs +2 -0
  80. package/dist/macos-run.mjs +1 -1
  81. package/dist/maintenance-run.mjs +13 -10
  82. package/dist/{metro-DI2AjPF_.mjs → metro-_ZIE3Axg.mjs} +18 -5
  83. package/dist/{metro-gateway-BxpJLIwh.mjs → metro-gateway-BzlQZQmU.mjs} +2 -2
  84. package/dist/miss-reason-SuTptY-I.mjs +238 -0
  85. package/dist/{named-ports-B4iWH4E-.mjs → named-ports-O1TIl7tx.mjs} +3 -3
  86. package/dist/native-android-D94RlJ-X.mjs +226 -0
  87. package/dist/native-gradle-inputs-BQnIdAlL.mjs +356 -0
  88. package/dist/{native-runtime-BGxsbfny.mjs → native-runtime-D024BAvm.mjs} +9 -8
  89. package/dist/native-xcode-inputs-UElfGs59.mjs +306 -0
  90. package/dist/native-xcode-ios-CjS-nDVY.mjs +434 -0
  91. package/dist/{ndjson-LGZAMsqa.mjs → ndjson-GOnbyvso.mjs} +6 -6
  92. package/dist/offload-worker.d.mts +41 -7
  93. package/dist/offload-worker.mjs +409 -74
  94. package/dist/{ownership-EB0ySdGK.mjs → ownership-BrjepDiv.mjs} +2 -2
  95. package/dist/{placement-log-Dxe34rJm.mjs → placement-log-BItXET1x.mjs} +1 -1
  96. package/dist/plan-Jwu_vr-F.mjs +260 -0
  97. package/dist/plan-placement-B466UYMU.mjs +73 -0
  98. package/dist/{ports-ByPc0_97.mjs → ports-BFRL6JTj.mjs} +3 -3
  99. package/dist/{prebuild-BKJ3wJI1.mjs → prebuild-DB_zLOLc.mjs} +4 -4
  100. package/dist/{preview-BbSottmO.mjs → preview-BRLFRhTz.mjs} +50 -32
  101. package/dist/project-DX8fXyw_.mjs +1131 -0
  102. package/dist/project-plan-BPwbLwQu.mjs +10 -0
  103. package/dist/{pull-request-IHNdMnG8.mjs → pull-request-vOhLNmIb.mjs} +1 -1
  104. package/dist/pull-requests.mjs +1 -1
  105. package/dist/react-native-android-CuXM3QS8.mjs +921 -0
  106. package/dist/react-native-build-JUF31S8U.mjs +239 -0
  107. package/dist/react-native-doctor-BQHqiXaQ.mjs +78 -0
  108. package/dist/react-native-ios-DtVO4qf2.mjs +595 -0
  109. package/dist/{recordings-Bv8McZN4.mjs → recordings-Bk-VivUV.mjs} +1 -1
  110. package/dist/{reload-rAPdqeRR.mjs → reload-D9V7D8gP.mjs} +17 -13
  111. package/dist/remote-CZiTijxG.mjs +192 -0
  112. package/dist/{remote-cache-N3hAEaAL.mjs → remote-cache-fxcl5C-L.mjs} +5 -5
  113. package/dist/result-BrfgXtdO.mjs +186 -0
  114. package/dist/{run-lAkle1-c.mjs → run-ClC8UVB5.mjs} +3 -3
  115. package/dist/{server-bare-CkIjnegq.mjs → server-bare-dWjAarki.mjs} +5 -5
  116. package/dist/server-command-DnJYLnr4.mjs +69 -0
  117. package/dist/{server-expo-n3tUi3Em.mjs → server-expo-CUuzP9Mp.mjs} +107 -82
  118. package/dist/server-expo-Dvkd7JcF.mjs +2 -0
  119. package/dist/{settings-CxgngUZk.mjs → settings-Bbztm4oV.mjs} +179 -129
  120. package/dist/{settings-2am7TSxp.mjs → settings-BuKMOANA.mjs} +6 -6
  121. package/dist/{state-lKh8shBp.d.mts → settings-vk3mJGSm.d.mts} +4 -2
  122. package/dist/settings.schema.json +84 -0
  123. package/dist/simslim-ChMfe8rg.mjs +149 -0
  124. package/dist/{slot-launch-HV_KtPIw.mjs → slot-launch-CeCRr6MK.mjs} +6 -6
  125. package/dist/{stage-BgaZJVZY.mjs → stage-BNKKdDNc.mjs} +6 -3
  126. package/dist/{start-DtxthMfI.mjs → start-CRkG-mZ7.mjs} +97 -68
  127. package/dist/start-mh6bS27z.mjs +2 -0
  128. package/dist/{state-Tp4uImDS.mjs → state-BUpAmt2r.mjs} +1 -1
  129. package/dist/{state-D2KtnALG.mjs → state-lqxdOH_g.mjs} +32 -12
  130. package/dist/{stats-8EJ5ivFT.mjs → stats-CaB1MxMi.mjs} +5 -5
  131. package/dist/{status-BEeL6IKz.mjs → status-BDGHwkCs.mjs} +3 -1
  132. package/dist/{status-BOyp0CUl.mjs → status-C7vzkInu.mjs} +81 -293
  133. package/dist/status-watch-ZaVqRdtW.mjs +296 -0
  134. package/dist/{stim-desktop-C65jk_q2.mjs → stim-desktop-8GQX2OV8.mjs} +1 -1
  135. package/dist/{stop-zDlknFoz.mjs → stop-BO80KJoT.mjs} +21 -20
  136. package/dist/{stop-DRipAg-e.mjs → stop-BU7JaFCg.mjs} +2 -2
  137. package/dist/{stop-D0UIpZuh.mjs → stop-Cftw_sXJ.mjs} +5 -5
  138. package/dist/supervisor-run.d.mts +7 -2
  139. package/dist/supervisor-run.mjs +32 -20
  140. package/dist/{support-DsNaFg6D.mjs → support-Ca6PZbpr.mjs} +17 -7
  141. package/dist/{support-CNqYkV0y.mjs → support-Co0wk8Cv.mjs} +61 -8
  142. package/dist/{swiftpm-macos-aJzPAj1t.mjs → swiftpm-macos-siFSkmCO.mjs} +5 -5
  143. package/dist/tailnet-D7-tE_ug.mjs +265 -0
  144. package/dist/toolchain-B12psPA2.mjs +2 -0
  145. package/dist/{toolchain-C3xSoyUl.mjs → toolchain-SqehyPLw.mjs} +206 -53
  146. package/dist/{trigger-CAhmG-4s.mjs → trigger-C0MWBi8O.mjs} +2 -2
  147. package/dist/trigger-SHLOWJ4O.mjs +2 -0
  148. package/dist/{warm-progress-pFLB2e6P.mjs → warm-progress-5FAXkXIg.mjs} +6 -6
  149. package/dist/{watchman-BL1IdOtq.mjs → watchman-CqmaGcIb.mjs} +6 -6
  150. package/dist/{web-DbbrPUn0.mjs → web-BTjzE8mc.mjs} +9 -13
  151. package/dist/web-CHN5gh34.mjs +2 -0
  152. package/dist/web-run.mjs +10 -10
  153. package/dist/{workspace-state-CR9X86xJ.mjs → workspace-state-CvgTFe-h.mjs} +36 -36
  154. package/dist/{workspaces-Djb2gfi9.mjs → workspaces-C4kqIOlx.mjs} +1260 -1258
  155. package/dist/worktree-Cgnm6vZt.mjs +2 -0
  156. package/dist/{worktree-BL4M1rhB.mjs → worktree-DtRsh6go.mjs} +86 -50
  157. package/package.json +6 -5
  158. package/shim/native-android.gradle +101 -0
  159. package/dist/android-BXc6BmEi.mjs +0 -3732
  160. package/dist/android-BvV1gGdN.mjs +0 -4
  161. package/dist/ios-ITYno9rO.mjs +0 -2241
  162. package/dist/macos-nIOATJmR.mjs +0 -2
  163. package/dist/metro-store-BAHFcJm6.mjs +0 -106
  164. package/dist/miss-reason-CjQCOKqq.mjs +0 -1743
  165. package/dist/plan-placement-BVY59qa8.mjs +0 -290
  166. package/dist/project-B5eQ1USs.mjs +0 -612
  167. package/dist/react-native-ios-BMh2i25I.mjs +0 -2
  168. package/dist/server-expo-DGsdUGX2.mjs +0 -2
  169. package/dist/start-D8NbxNBb.mjs +0 -2
  170. package/dist/trigger-CoalsMTV.mjs +0 -2
  171. package/dist/web-DFpFeZu5.mjs +0 -2
  172. package/dist/worktree-DV-A0LNL.mjs +0 -2
@@ -0,0 +1,807 @@
1
+ import { n as ownership_claim_exports } from "./process-identity-Biv3arCO.mjs";
2
+ import { A as providerDownloadPath, j as providerUploadOutcome, k as prepareProviderDownloadDir, v as waitForSharedBuild } from "./device-lease-C309csaB.mjs";
3
+ import { x as workspaceDir } from "./workspace-state-CvgTFe-h.mjs";
4
+ import { _ as stepTimer, i as formatDuration, l as phaseLine, m as shortHash } from "./command-output-CPDq_90S.mjs";
5
+ import { x as runCancellationSignal } from "./tailnet-D7-tE_ug.mjs";
6
+ import { a as easAuthNote, s as isEasAuthFailureText, t as RESOLVE_TIMEOUT_MS } from "./remote-cache-fxcl5C-L.mjs";
7
+ import { _ as requireLocalBuild, c as offloadPlacement, h as namedBuildMachine, i as closeOffload, l as placementLoad, n as buildPlacementCandidates, o as offloadBuild, p as OffloadRefusal, r as chooseBuildMachine, u as remotePhaseText } from "./client-zqjFd79D.mjs";
8
+ import { i as skippedMissReason } from "./miss-reason-SuTptY-I.mjs";
9
+ import { t as buildPlacementRecord } from "./placement-log-BItXET1x.mjs";
10
+ import { t as runArtifactLifecycle } from "./artifact-lifecycle-DzPpBYvK.mjs";
11
+ import { S as compilationCacheActivityLine, _ as COMPILATION_CACHE_NOT_RUN } from "./toolchain-SqehyPLw.mjs";
12
+ import { S as xcodeFailureReport, p as printDiagnostics } from "./support-Co0wk8Cv.mjs";
13
+ import { r as finishIosUpload, t as IosRecipeRefusal } from "./ios-project-BeOXKPt2.mjs";
14
+ import { rmSync } from "node:fs";
15
+ import { join } from "node:path";
16
+ import { machineCapacity } from "@stim-cli/core/state";
17
+ import { createWarnOnce, resolveTieredBuild, storeTieredBuild } from "@stim-cli/cache";
18
+ import chalk from "chalk";
19
+ //#region src/commands/ios/artifact.ts
20
+ const PROVIDER_SKIPPED_ON_DEVICE = "a device build is local-tier only: its cache key names the iphoneos slice, and a remote or provider entry is keyed for the simulator";
21
+ function fail(failure) {
22
+ throw new IosRecipeRefusal(failure);
23
+ }
24
+ async function acquireIosArtifact({ root, logFile, recipe, physical, configuration, buildMachine = "auto", cache, easBuild, maxBuilds, progress }, d) {
25
+ const { phase, note, logWriter, stats, step, miss, hit: lateHit, place, waitingOn, waitingFor } = progress;
26
+ const cachePolicy = cache.policy;
27
+ const signal = runCancellationSignal() ?? new AbortController().signal;
28
+ const cacheTarget = (key) => ({
29
+ projectRoot: root,
30
+ platform: "ios",
31
+ key,
32
+ signal
33
+ });
34
+ let useBuildCache = cachePolicy.read;
35
+ let cacheIneligible = null;
36
+ const cacheProviderConfig = cache.providerConfig;
37
+ let compilationCache = COMPILATION_CACHE_NOT_RUN;
38
+ const temporaryDirs = /* @__PURE__ */ new Set();
39
+ const releaseArtifact = () => {
40
+ for (const directory of temporaryDirs) {
41
+ try {
42
+ rmSync(directory, {
43
+ recursive: true,
44
+ force: true
45
+ });
46
+ } catch {}
47
+ temporaryDirs.delete(directory);
48
+ }
49
+ };
50
+ let buildLock = null;
51
+ const releaseLock = () => {
52
+ if (!buildLock) return;
53
+ const held = buildLock;
54
+ buildLock = null;
55
+ try {
56
+ d.releaseBuildLock(held);
57
+ } catch (e) {
58
+ note(chalk.dim(`Could not release the build lock at ${held.path}: ${e?.message || e}`));
59
+ }
60
+ };
61
+ let buildSlot = null;
62
+ const releaseSlot = () => {
63
+ if (!buildSlot) return;
64
+ const held = buildSlot;
65
+ buildSlot = null;
66
+ try {
67
+ d.releaseBuildSlot(held);
68
+ } catch (e) {
69
+ note(chalk.dim(`Could not release the build slot: ${e?.message || e}`));
70
+ }
71
+ };
72
+ let fingerprint = "";
73
+ let cacheKey = "";
74
+ let storeHash = null;
75
+ let storeKey = null;
76
+ let appPath = null;
77
+ let bundleId = null;
78
+ let cacheHit = false;
79
+ let offloadedTo = null;
80
+ let handoff = null;
81
+ let offloadFallback = null;
82
+ let fallbackMachine = null;
83
+ let hereReason = "no remote Mac is paired";
84
+ let slotWaitMs;
85
+ let builtOn;
86
+ const fallBack = (reason, line = reason, info = {}) => {
87
+ logWriter().write(buildPlacementRecord({
88
+ platform: "ios",
89
+ buildMachine,
90
+ candidates: info.candidates,
91
+ event: "placement_fallback",
92
+ fallback: {
93
+ code: info.code ?? "fallback",
94
+ reason,
95
+ machine: info.machine
96
+ }
97
+ }));
98
+ if (namedBuildMachine(buildMachine)) throw new OffloadRefusal(buildMachine, reason);
99
+ requireLocalBuild(buildMachine);
100
+ offloadFallback = reason;
101
+ buildFailure = {
102
+ ...buildFailure,
103
+ offloadFallback: reason
104
+ };
105
+ phase("build", `${line} -> building here`);
106
+ };
107
+ const openOffload = { choice: null };
108
+ let remote = null;
109
+ let abandonedRemote = false;
110
+ let uploadPending = null;
111
+ let providerUpload = null;
112
+ let providerName = null;
113
+ let providerLoad = null;
114
+ const cacheWarn = createWarnOnce((line) => note(chalk.yellow(phaseLine("cache", line))));
115
+ const loadProvider = cachePolicy.remote && cacheProviderConfig && !physical ? () => providerLoad ??= d.loadCacheProvider({
116
+ projectRoot: root,
117
+ config: cacheProviderConfig
118
+ }) : null;
119
+ if (cacheProviderConfig && physical) note(chalk.dim(phaseLine("cache", PROVIDER_SKIPPED_ON_DEVICE)));
120
+ let waitedForBuild = null;
121
+ let releasedWait = null;
122
+ let swapFellBack = false;
123
+ let buildFailure = {};
124
+ let missReason = null;
125
+ async function resolveInitialFingerprint() {
126
+ if (easBuild?.ok) {
127
+ fingerprint = storeHash = easBuild.fingerprint;
128
+ cacheKey = storeKey = easBuild.cacheKey;
129
+ appPath = easBuild.path;
130
+ cacheHit = easBuild.cacheHit;
131
+ providerName = "eas";
132
+ stats.setCacheKey(cacheKey);
133
+ recipe.validateExternal(appPath);
134
+ return;
135
+ }
136
+ if (useBuildCache) step("cache-lookup");
137
+ const fingerprintTimer = stepTimer(d.now);
138
+ const identity = await recipe.identity();
139
+ if ("cacheIneligible" in identity) {
140
+ cacheIneligible = identity.cacheIneligible;
141
+ useBuildCache = false;
142
+ phase("fingerprint", `unavailable: ${cacheIneligible}`);
143
+ return;
144
+ }
145
+ fingerprint = identity.hash;
146
+ cacheKey = identity.key;
147
+ stats.setCacheKey(cacheKey);
148
+ storeHash = fingerprint;
149
+ storeKey = cacheKey;
150
+ const found = await resolveTieredBuild({
151
+ local: recipe.cache(),
152
+ loadProvider,
153
+ target: {
154
+ projectRoot: root,
155
+ platform: "ios",
156
+ key: cacheKey
157
+ },
158
+ destinationDir: providerDownloadPath(workspaceDir(root)),
159
+ ensureDestination: prepareProviderDownloadDir,
160
+ skipRead: !useBuildCache,
161
+ warn: cacheWarn
162
+ });
163
+ const cached = found?.tier === "local" ? found.path : null;
164
+ cacheHit = cached ? "local" : false;
165
+ phase("fingerprint", `${shortHash(fingerprint)} ${cached ? "hit" : "miss"}${useBuildCache ? "" : cache.disabledByFlag ? " (--no-build-cache)" : " (cache reuse off in config)"} ${fingerprintTimer()}`);
166
+ if (found?.tier === "provider") {
167
+ cacheHit = "remote";
168
+ providerName = found.providerName ?? null;
169
+ phase("cache", `provider hit (${providerName})${found.storedLocally ? " -> stored locally" : ""}`);
170
+ }
171
+ appPath = found?.path ?? null;
172
+ }
173
+ async function resolveRemoteArtifact() {
174
+ if (cacheIneligible || !recipe.legacyCache) return null;
175
+ if (!appPath) {
176
+ const loaded = await recipe.legacyCache.load();
177
+ if (loaded?.unavailable) note(chalk.yellow(phaseLine("cache", `provider not usable: ${loaded.unavailable}`)));
178
+ else if (loaded?.provider) remote = loaded;
179
+ if (remote?.name === "eas") {
180
+ const auth = d.checkEasAuth({
181
+ projectRoot: root,
182
+ owner: loaded?.owner || null
183
+ });
184
+ const authNote = easAuthNote(auth);
185
+ if (authNote) note(chalk.yellow(phaseLine("cache", authNote)));
186
+ if (auth?.code === "logged-out") remote = null;
187
+ }
188
+ }
189
+ if (remote && useBuildCache) {
190
+ const remoteTimer = stepTimer(d.now);
191
+ const hit = await d.resolveRemote({
192
+ logWriter: logWriter(),
193
+ provider: remote.provider,
194
+ platform: "ios",
195
+ projectRoot: root,
196
+ fingerprintHash: fingerprint,
197
+ runOptions: recipe.legacyCache?.runOptions ?? null
198
+ });
199
+ if (hit?.appPath) {
200
+ let stored = null;
201
+ try {
202
+ stored = await recipe.cache().store({
203
+ ...cacheTarget(cacheKey),
204
+ sourcePath: hit.appPath,
205
+ overwrite: false
206
+ }) ?? null;
207
+ } catch (e) {
208
+ note(chalk.yellow(phaseLine("cache", `remote hit could not be stored locally: ${e?.message || e}`)));
209
+ }
210
+ appPath = stored || hit.appPath;
211
+ cacheHit = "remote";
212
+ phase("cache", `remote hit (${remote.name})${stored ? " -> stored locally" : ""} ${remoteTimer()}`);
213
+ } else if (hit?.timedOut) {
214
+ abandonedRemote = true;
215
+ note(chalk.yellow(phaseLine("cache", `${remote.name} did not answer within ${formatDuration(RESOLVE_TIMEOUT_MS)}; building instead`)));
216
+ } else if (hit?.failed) {
217
+ const authNote = remote.name === "eas" && isEasAuthFailureText(hit.failed) ? easAuthNote({
218
+ code: "logged-out",
219
+ reason: hit.failed
220
+ }) : null;
221
+ note(chalk.yellow(phaseLine("cache", authNote || `${remote.name} could not be used: ${hit.failed}; building instead`)));
222
+ } else phase("cache", `remote miss (${remote.name}) ${remoteTimer()}`);
223
+ }
224
+ return remote;
225
+ }
226
+ async function awaitSharedBuild() {
227
+ if (!useBuildCache || appPath) return;
228
+ const shared = await waitForSharedBuild({
229
+ platform: "ios",
230
+ key: cacheKey,
231
+ fingerprint,
232
+ root,
233
+ logFile,
234
+ command: "stim ios",
235
+ acquire: d.acquireBuildLock,
236
+ wait: d.waitForBuild,
237
+ now: d.now,
238
+ phase: (text) => {
239
+ step("wait");
240
+ phase("build", text);
241
+ },
242
+ waitingOn,
243
+ warn: (text) => note(chalk.yellow(phaseLine("build", text))),
244
+ out: note
245
+ });
246
+ if (shared.refusal) fail({
247
+ ...shared.refusal,
248
+ build: {
249
+ fingerprint,
250
+ cacheKey,
251
+ cacheHit,
252
+ cacheSkipped: !useBuildCache
253
+ }
254
+ });
255
+ buildLock = shared.lock;
256
+ releasedWait = shared.released;
257
+ if (shared.hit) {
258
+ appPath = shared.hit.path;
259
+ cacheHit = "local";
260
+ waitedForBuild = shared.hit.waited;
261
+ }
262
+ }
263
+ const installableCachedApp = async (path) => {
264
+ const prepared = await recipe.materialize(path, {
265
+ fresh: false,
266
+ ownTemporary: (directory) => temporaryDirs.add(directory)
267
+ });
268
+ if (!prepared) swapFellBack = true;
269
+ return prepared;
270
+ };
271
+ async function prepareCachedArtifact(cachedPath) {
272
+ const prepared = await installableCachedApp(cachedPath);
273
+ if (!prepared) {
274
+ cacheHit = false;
275
+ waitedForBuild = null;
276
+ }
277
+ return prepared;
278
+ }
279
+ function reasonForMiss(rekeyedBy) {
280
+ if (swapFellBack) return {
281
+ reason: skippedMissReason("the cached app could not be reused, so this run built it fresh"),
282
+ diff: null
283
+ };
284
+ if (cacheIneligible) return {
285
+ reason: skippedMissReason(cacheIneligible),
286
+ diff: null
287
+ };
288
+ if (!useBuildCache) return {
289
+ reason: skippedMissReason(cache.disabledByFlag ? "cache reuse turned off by --no-build-cache" : "cache reuse off in config"),
290
+ diff: null
291
+ };
292
+ return recipe.explain(rekeyedBy);
293
+ }
294
+ function explainMiss(rekeyedBy) {
295
+ const explained = reasonForMiss(rekeyedBy);
296
+ missReason = explained.reason;
297
+ if (explained.diff) logWriter().write(explained.diff);
298
+ buildFailure = {
299
+ ...buildFailure,
300
+ missReason
301
+ };
302
+ miss(missReason);
303
+ phase("cache", `miss: ${missReason.summary}`);
304
+ if (missReason.kind === "no-baseline") {
305
+ const untracked = recipe.untrackedLine();
306
+ if (untracked) note(chalk.dim(phaseLine("fingerprint", untracked)));
307
+ }
308
+ }
309
+ async function settleStoreKeyAfterCompile() {
310
+ if (!storeHash || !storeKey) return;
311
+ const identity = await recipe.validate();
312
+ storeHash = identity?.hash ?? null;
313
+ storeKey = identity?.key ?? null;
314
+ buildFailure = {
315
+ ...buildFailure,
316
+ fingerprint: storeHash,
317
+ cacheKey: storeKey
318
+ };
319
+ }
320
+ async function takeBuildSlot() {
321
+ requireLocalBuild(buildMachine);
322
+ if (!maxBuilds) return;
323
+ try {
324
+ buildSlot = await d.acquireBuildSlot({
325
+ automatic: buildMachine === "auto",
326
+ max: maxBuilds,
327
+ root,
328
+ logFile,
329
+ out: note,
330
+ waitingFor: (info) => waitingFor?.(info, "build-slot")
331
+ });
332
+ slotWaitMs = buildSlot.slotWaitMs;
333
+ } catch (e) {
334
+ requireLocalBuild(buildMachine);
335
+ const refusal = (0, ownership_claim_exports.claimFailure)(e, "stim ios");
336
+ if (refusal) fail({
337
+ code: refusal.code,
338
+ message: refusal.message,
339
+ remedy: refusal.remedy,
340
+ build: buildFailure
341
+ });
342
+ note(chalk.yellow(phaseLine("build", `could not take a build slot: ${e?.message || e}; building anyway`)));
343
+ }
344
+ }
345
+ /** Whether this build should leave this Mac, before any machine is asked; null builds here. */
346
+ function placeBuild() {
347
+ if (cacheIneligible) {
348
+ if (namedBuildMachine(buildMachine)) throw new OffloadRefusal(buildMachine, cacheIneligible);
349
+ hereReason = cacheIneligible;
350
+ return null;
351
+ }
352
+ const { mode, machines, localEnabled } = buildPlacementCandidates(buildMachine);
353
+ if (localEnabled && machines.length === 0 && !namedBuildMachine(buildMachine) && buildMachine !== "local") return null;
354
+ const { runtime, unsupported } = mode === "off" && !namedBuildMachine(buildMachine) ? {
355
+ runtime: null,
356
+ unsupported: null
357
+ } : recipe.offload?.context() ?? {
358
+ runtime: null,
359
+ unsupported: "this project integration does not support offloaded builds"
360
+ };
361
+ const here = machineCapacity();
362
+ const placement = offloadPlacement({
363
+ mode,
364
+ localEnabled,
365
+ machines: machines.length,
366
+ here,
367
+ unsupported,
368
+ selected: buildMachine
369
+ });
370
+ if (!placement.offload) {
371
+ hereReason = placement.reason;
372
+ logWriter().write(buildPlacementRecord({
373
+ platform: "ios",
374
+ buildMachine,
375
+ stays: {
376
+ code: placement.code,
377
+ reason: placement.reason
378
+ }
379
+ }));
380
+ if (mode !== "off") phase("build", `placement: here (${placement.reason})`);
381
+ return null;
382
+ }
383
+ return {
384
+ mode,
385
+ here,
386
+ code: placement.code,
387
+ reason: placement.reason,
388
+ runtime,
389
+ machines
390
+ };
391
+ }
392
+ /** Asks the paired machines once the post-mutation key is known; null builds here. */
393
+ async function chooseMachine(candidate) {
394
+ let asked = [];
395
+ const choice = await chooseBuildMachine({
396
+ projectRoot: root,
397
+ target: recipe.offload.target(candidate.runtime),
398
+ mode: candidate.mode,
399
+ here: candidate.here,
400
+ note: (line) => note(chalk.dim(phaseLine("build", `offload: ${line}`))),
401
+ machines: candidate.machines,
402
+ selected: buildMachine,
403
+ onCandidates: (each) => asked = each
404
+ });
405
+ if (typeof choice === "string") {
406
+ const only = candidate.machines.length === 1 ? candidate.machines[0].machine : null;
407
+ if (only && choice.startsWith(`${only}: `)) fallbackMachine = only;
408
+ fallBack(choice, choice, {
409
+ code: "no-remote-mac-took-it",
410
+ candidates: asked
411
+ });
412
+ return null;
413
+ }
414
+ openOffload.choice = choice;
415
+ logWriter().write(buildPlacementRecord({
416
+ platform: "ios",
417
+ buildMachine,
418
+ candidates: asked,
419
+ chose: {
420
+ machine: choice.machine,
421
+ reason: `${candidate.reason}${placementLoad(choice)}`
422
+ }
423
+ }));
424
+ phase("build", `placement: ${choice.machine} (${candidate.reason}${placementLoad(choice)})`);
425
+ return choice;
426
+ }
427
+ /** Builds on the chosen machine and stores the app under the post-mutation key; false builds here instead unless a machine was named. */
428
+ async function compileElsewhere({ choice, candidate }) {
429
+ const runtime = candidate.runtime;
430
+ if (!storeKey || !storeHash) {
431
+ if (namedBuildMachine(buildMachine)) fallBack("the build fingerprint or cache key is unavailable");
432
+ return false;
433
+ }
434
+ const stagingDir = join(workspaceDir(root), "offload", "ios");
435
+ const outcome = await offloadBuild({
436
+ choice,
437
+ expectedFingerprint: storeHash,
438
+ request: recipe.offload.request(runtime),
439
+ stagingDir,
440
+ onPhase: (name, msg) => phase(name, remotePhaseText(name, msg, choice.machine)),
441
+ onEnter: (name) => {
442
+ if (name === "compile" || name === "build" || name === "prebuild" || name === "pods") {
443
+ builtOn = choice.machine;
444
+ buildFailure = {
445
+ ...buildFailure,
446
+ builtOn
447
+ };
448
+ }
449
+ place({
450
+ host: choice.machine,
451
+ phase: name
452
+ });
453
+ step(name === "prebuild" || name === "pods" ? name : "compile");
454
+ },
455
+ onRecord: (record) => logWriter().write({
456
+ ...record,
457
+ offloadedTo: choice.machine
458
+ }),
459
+ note: (line) => phase("build", line)
460
+ });
461
+ place(null);
462
+ let stored = null;
463
+ let reason = outcome.ok ? null : outcome.reason;
464
+ if (outcome.ok) {
465
+ if (!await recipe.offload.unchanged()) reason = "the checkout here changed while it built";
466
+ else try {
467
+ stored = await recipe.cache().store({
468
+ ...cacheTarget(storeKey),
469
+ sourcePath: outcome.artifactPath,
470
+ overwrite: !useBuildCache
471
+ }) ?? null;
472
+ } catch (e) {
473
+ reason = `could not store the app: ${e?.message || e}`;
474
+ }
475
+ }
476
+ try {
477
+ rmSync(stagingDir, {
478
+ recursive: true,
479
+ force: true
480
+ });
481
+ } catch {}
482
+ step("compile");
483
+ const prepared = stored ? await installableCachedApp(stored) : null;
484
+ if (!outcome.ok || !prepared) {
485
+ const why = reason ?? "the stored app is not installable";
486
+ fallbackMachine = choice.machine;
487
+ fallBack(`${choice.machine}: ${why}`, `offload failed: ${why}`, {
488
+ code: "offload-failed",
489
+ machine: choice.machine
490
+ });
491
+ logWriter().write({
492
+ src: "build",
493
+ level: "warn",
494
+ event: "offload_failed",
495
+ msg: reason,
496
+ machine: choice.machine
497
+ });
498
+ return false;
499
+ }
500
+ const { timings } = outcome;
501
+ appPath = prepared;
502
+ builtOn = outcome.machine;
503
+ offloadedTo = outcome.machine;
504
+ handoff = outcome.handoff ?? null;
505
+ stats.setPlacement({
506
+ decision: "offloaded",
507
+ machine: outcome.machine,
508
+ reason: `${candidate.reason}${placementLoad(choice)}`,
509
+ buildMs: timings.totalMs
510
+ });
511
+ 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)}`);
512
+ compilationCache = outcome.compilationCache;
513
+ phase("cache", `compilation cache on ${outcome.machine} ${compilationCacheActivityLine(compilationCache)}`);
514
+ logWriter().write({
515
+ src: "build",
516
+ level: "info",
517
+ event: "offload_done",
518
+ msg: `built on ${outcome.machine}`,
519
+ timings
520
+ });
521
+ return true;
522
+ }
523
+ async function prepareSource() {
524
+ await recipe.prepare(() => miss(reasonForMiss([]).reason, true));
525
+ return recipe.reconcile();
526
+ }
527
+ async function revalidateSource({ identity, mutationLabel }) {
528
+ if (cacheIneligible || !identity) {
529
+ storeHash = null;
530
+ storeKey = null;
531
+ buildFailure = {
532
+ ...buildFailure,
533
+ fingerprint: null,
534
+ cacheKey: null
535
+ };
536
+ } else if (identity.key !== storeKey) {
537
+ storeHash = identity.hash;
538
+ storeKey = identity.key;
539
+ buildFailure = {
540
+ ...buildFailure,
541
+ fingerprint: storeHash,
542
+ cacheKey: storeKey
543
+ };
544
+ const late = useBuildCache ? await recipe.cache().resolve({
545
+ ...cacheTarget(storeKey),
546
+ destinationDir: providerDownloadPath(workspaceDir(root))
547
+ }) : null;
548
+ if (late) {
549
+ const prepared = await installableCachedApp(late);
550
+ if (prepared) {
551
+ appPath = prepared;
552
+ cacheHit = "local";
553
+ lateHit();
554
+ phase("cache", `hit ${shortHash(storeHash)} (post-${mutationLabel} key)`);
555
+ if (releasedWait) {
556
+ waitedForBuild = releasedWait.facts;
557
+ phase("build", `waited ${formatDuration(waitedForBuild.ms)} for ${releasedWait.who}'s build -> installed from cache -- stim guide lifecycle concurrency`);
558
+ }
559
+ }
560
+ }
561
+ }
562
+ return appPath ? { ready: appPath } : null;
563
+ }
564
+ async function acquireRemoteArtifact(offload, { rekeyedBy }) {
565
+ explainMiss(rekeyedBy);
566
+ step("compile");
567
+ if (!storeKey) fallBack("no cache key to store the app under", "offload failed: no cache key to store the app under");
568
+ const choice = storeKey ? await chooseMachine(offload) : null;
569
+ if (choice) await compileElsewhere({
570
+ choice,
571
+ candidate: offload
572
+ });
573
+ return appPath ? { ready: appPath } : null;
574
+ }
575
+ async function compileHere(offload, { rekeyedBy }) {
576
+ if (!offload) explainMiss(rekeyedBy);
577
+ step("compile");
578
+ if (offload) stats.setPlacement({
579
+ decision: "fell-back",
580
+ slotWaitMs,
581
+ deviceSlotWaitMs: stats.deviceSlotWaitMs(),
582
+ reason: offloadFallback ?? "offload failed",
583
+ ...fallbackMachine ? { machine: fallbackMachine } : {}
584
+ });
585
+ else stats.setPlacement({
586
+ decision: "here",
587
+ reason: hereReason,
588
+ slotWaitMs,
589
+ deviceSlotWaitMs: stats.deviceSlotWaitMs()
590
+ });
591
+ requireLocalBuild(buildMachine);
592
+ builtOn = "here";
593
+ buildFailure = {
594
+ ...buildFailure,
595
+ builtOn
596
+ };
597
+ phase("build", `compiling ${configuration || "Debug"} with xcodebuild`);
598
+ const result = await recipe.compile();
599
+ compilationCache = result.compilationCache;
600
+ phase("cache", `compilation cache ${compilationCacheActivityLine(compilationCache)}`);
601
+ if (!result.ok) {
602
+ phase("build", `FAILED after ${formatDuration(result.durationMs)}`);
603
+ printDiagnostics(note, result);
604
+ const report = xcodeFailureReport(result, logFile);
605
+ fail({
606
+ code: result.code,
607
+ message: report.message,
608
+ remedy: report.remedy,
609
+ logPath: logFile,
610
+ build: {
611
+ ...buildFailure,
612
+ diagnostics: result.diagnostics
613
+ }
614
+ });
615
+ }
616
+ stats.setBuildMs(result.durationMs);
617
+ phase("build", `ok (${formatDuration(result.durationMs)})`);
618
+ appPath = result.appPath;
619
+ bundleId = result.bundleId;
620
+ return appPath;
621
+ }
622
+ async function storeArtifact(artifactPath) {
623
+ if (storeKey && cachePolicy.write) try {
624
+ const stored = await storeTieredBuild({
625
+ local: recipe.cache(),
626
+ loadProvider,
627
+ target: {
628
+ projectRoot: root,
629
+ platform: "ios",
630
+ key: storeKey
631
+ },
632
+ sourcePath: artifactPath,
633
+ overwrite: !useBuildCache || swapFellBack,
634
+ warn: cacheWarn
635
+ });
636
+ providerUpload = stored.providerUpload;
637
+ providerName = stored.providerName ?? providerName;
638
+ } catch (e) {
639
+ note(chalk.yellow(`Could not store the build in the shared cache: ${e?.message || e}`));
640
+ }
641
+ }
642
+ async function finishArtifact(artifactPath) {
643
+ let installPath = artifactPath;
644
+ const prepared = await recipe.materialize(installPath, {
645
+ fresh: true,
646
+ ownTemporary: (directory) => temporaryDirs.add(directory)
647
+ });
648
+ if (!prepared) fail({
649
+ code: "STIM_INSTALL_FAILED",
650
+ message: "The project integration could not prepare the built app for installation.",
651
+ remedy: "Check the artifact preparation details above, then retry.",
652
+ build: {
653
+ ...buildFailure,
654
+ appPath: installPath
655
+ }
656
+ });
657
+ installPath = prepared;
658
+ if (remote && !physical && storeHash) uploadPending = d.uploadRemote({
659
+ logWriter: logWriter(),
660
+ provider: remote.provider,
661
+ platform: "ios",
662
+ projectRoot: root,
663
+ fingerprintHash: storeHash,
664
+ buildPath: installPath,
665
+ runOptions: recipe.legacyCache?.runOptions ?? null
666
+ });
667
+ return installPath;
668
+ }
669
+ let transferred = false;
670
+ try {
671
+ appPath = await runArtifactLifecycle({
672
+ resolve: async () => {
673
+ await resolveInitialFingerprint();
674
+ if (easBuild) return {
675
+ kind: "ready",
676
+ artifact: appPath
677
+ };
678
+ remote = await resolveRemoteArtifact();
679
+ if (appPath) return {
680
+ kind: "cached",
681
+ artifact: appPath
682
+ };
683
+ miss(reasonForMiss([]).reason);
684
+ return { kind: "miss" };
685
+ },
686
+ claim: useBuildCache ? async () => {
687
+ await awaitSharedBuild();
688
+ return appPath;
689
+ } : void 0,
690
+ reuse: async (cached) => {
691
+ appPath = await prepareCachedArtifact(cached);
692
+ if (appPath) lateHit();
693
+ else if (swapFellBack) miss(reasonForMiss([]).reason);
694
+ return appPath;
695
+ },
696
+ build: {
697
+ placement: {
698
+ select: () => {
699
+ buildFailure = {
700
+ fingerprint,
701
+ cacheKey,
702
+ cacheHit,
703
+ cacheSkipped: !useBuildCache,
704
+ buildMachine
705
+ };
706
+ return placeBuild();
707
+ },
708
+ acquire: acquireRemoteArtifact
709
+ },
710
+ admit: takeBuildSlot,
711
+ prepare: prepareSource,
712
+ revalidate: revalidateSource,
713
+ compile: compileHere,
714
+ validate: async () => {
715
+ await settleStoreKeyAfterCompile();
716
+ return storeKey ? "cacheable" : "uncacheable";
717
+ },
718
+ store: storeArtifact,
719
+ finish: finishArtifact
720
+ },
721
+ release: () => {
722
+ if (openOffload.choice) closeOffload(openOffload.choice);
723
+ releaseLock();
724
+ releaseSlot();
725
+ }
726
+ });
727
+ const artifact = {
728
+ handoff,
729
+ path: appPath,
730
+ bundleId,
731
+ cache: {
732
+ identity: storeHash && storeKey ? {
733
+ fingerprint: storeHash,
734
+ key: storeKey
735
+ } : null,
736
+ hit: cacheHit,
737
+ providerName: remote?.name ?? providerName,
738
+ buildMachine,
739
+ ...builtOn ? { builtOn } : {},
740
+ offloadedTo,
741
+ offloadFallback: offloadedTo ? null : offloadFallback,
742
+ readEnabled: useBuildCache,
743
+ missReason: cacheHit ? null : missReason,
744
+ waitedForBuild,
745
+ compilation: compilationCache
746
+ },
747
+ failureFields: {
748
+ ...buildFailure,
749
+ buildMachine,
750
+ ...builtOn ? { builtOn } : {},
751
+ fingerprint: storeHash,
752
+ cacheKey: storeKey,
753
+ cacheHit,
754
+ cacheSkipped: !useBuildCache
755
+ },
756
+ completeUploads: async () => {
757
+ const uploadWasAbandoned = await finishIosUpload(uploadPending, remote, phase, note);
758
+ const outcome = providerUploadOutcome(providerUpload ? await providerUpload : null, providerName);
759
+ if (outcome) {
760
+ if (outcome.warn) note(chalk.yellow(phaseLine("cache", outcome.line)));
761
+ else phase("cache", outcome.line);
762
+ }
763
+ return abandonedRemote || uploadWasAbandoned;
764
+ },
765
+ release: releaseArtifact
766
+ };
767
+ transferred = true;
768
+ return {
769
+ ok: true,
770
+ artifact
771
+ };
772
+ } catch (error) {
773
+ if (error instanceof OffloadRefusal) {
774
+ const refusal = error;
775
+ return {
776
+ ok: false,
777
+ failure: {
778
+ code: refusal.code,
779
+ message: refusal.message,
780
+ remedy: refusal.remedy,
781
+ build: {
782
+ ...buildFailure,
783
+ buildMachine,
784
+ ...builtOn ? { builtOn } : {}
785
+ }
786
+ },
787
+ compilationCache
788
+ };
789
+ }
790
+ if (error instanceof IosRecipeRefusal) return {
791
+ ok: false,
792
+ failure: {
793
+ ...error.failure,
794
+ build: {
795
+ ...buildFailure,
796
+ ...error.failure.build
797
+ }
798
+ },
799
+ compilationCache
800
+ };
801
+ throw error;
802
+ } finally {
803
+ if (!transferred) releaseArtifact();
804
+ }
805
+ }
806
+ //#endregion
807
+ export { acquireIosArtifact as t };