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
@@ -1,8 +1,8 @@
1
- import { t as getExecutor } from "./exec-i8GDPwq9.mjs";
2
- import { s as isAppLaunchError } from "./command-output-Bt8ygHE7.mjs";
3
- import { o as readNdjsonGenerations } from "./ndjson-LGZAMsqa.mjs";
4
- import { f as deviceShellArg, n as ANDROID_DISABLE_AUTO_LAUNCH_EXTRA, s as androidAppProcess } from "./app-install-CFI4ptUL.mjs";
5
- import { t as DEV_MENU_LAUNCH_ARGS } from "./ios-device-CrW8aMb5.mjs";
1
+ import { t as getExecutor } from "./exec-B81Qodjn.mjs";
2
+ import { s as isAppLaunchError } from "./command-output-CPDq_90S.mjs";
3
+ import { s as readNdjsonGenerations } from "./ndjson-GOnbyvso.mjs";
4
+ import { t as DEV_MENU_LAUNCH_ARGS } from "./ios-device-B1B14xND.mjs";
5
+ import { f as deviceShellArg, n as ANDROID_DISABLE_AUTO_LAUNCH_EXTRA, s as androidAppProcess } from "./app-install-Cg9YJy3x.mjs";
6
6
  import { join } from "node:path";
7
7
  //#region src/engine/app-readiness.ts
8
8
  const APP_READINESS_TIMEOUT_MS = 3e4;
@@ -121,7 +121,7 @@ function nativeLaunchFailure({ readCrashes, since, platform, processAlive, mode,
121
121
  waitedMs
122
122
  } : null;
123
123
  }
124
- async function verifyLaunch({ slot, appPid, platformShared, logsDir, since, metroPort = null, platform = null, mode = null, requireBundleResponse, timeoutMs = VERIFY_TIMEOUT_MS, stabilityMs = STABILITY_WINDOW_MS, pollMs = VERIFY_POLL_MS, readRecords = null, readDeviceRecords = null, readClientRecords = null, readNativeCrashes = null, processAlive = null, onReadinessPending = null, now = Date.now, sleep = (ms) => new Promise((r) => setTimeout(r, ms)) } = {}) {
124
+ async function verifyLaunch({ slot, appPid, platformShared, logsDir, since, metroPort = null, platform = null, mode = null, requireBundleResponse, timeoutMs = VERIFY_TIMEOUT_MS, stabilityMs = STABILITY_WINDOW_MS, pollMs = VERIFY_POLL_MS, readRecords = null, readDeviceRecords = null, readClientRecords = null, readNativeCrashes = null, processAlive = null, onReadinessPending = null, onActivity, now = Date.now, sleep = (ms) => new Promise((r) => setTimeout(r, ms)) } = {}) {
125
125
  const delivered = (record) => deliveryOwner(record, {
126
126
  slot,
127
127
  appPid,
@@ -140,6 +140,13 @@ async function verifyLaunch({ slot, appPid, platformShared, logsDir, since, metr
140
140
  let runtimeLoadingAt = null;
141
141
  let runtimeStartedAt = null;
142
142
  let nextCrashCheck = startedAt + 1e3;
143
+ let bundlingAt = null;
144
+ let reported = null;
145
+ const report = (name, at) => {
146
+ if (name === reported) return;
147
+ reported = name;
148
+ onActivity?.(name, at);
149
+ };
143
150
  while (true) {
144
151
  const metroRecords = read().filter((record) => after(record, since));
145
152
  const bundleRecords = metroRecords.filter((record) => (!requireBundleResponse || String(record.event).startsWith("bundle_response_")) && delivered(record));
@@ -161,6 +168,7 @@ async function verifyLaunch({ slot, appPid, platformShared, logsDir, since, metr
161
168
  const request = bundleRecords.find((record) => record.event === "bundle_response_started" && typeof record.requestId === "string" && isBundleProof(record, since, platform));
162
169
  if (request) {
163
170
  deliveryId = request.requestId;
171
+ bundlingAt = request;
164
172
  proof = null;
165
173
  stabilityDeadline = null;
166
174
  }
@@ -193,6 +201,7 @@ async function verifyLaunch({ slot, appPid, platformShared, logsDir, since, metr
193
201
  onReadinessPending?.();
194
202
  }
195
203
  }
204
+ report(...launchActivity(pendingAt, proof, bundlingAt));
196
205
  const ready = pendingAt !== null && signals.some((record) => Number(record.ts) >= pendingAt && Number(record.ts) <= readinessDeadline && appReadinessSignal(record, platform) === "ready");
197
206
  const bundleErrors = bundleRecords.filter((record) => isFatalLaunchError(record, platform) || deliveryId !== null && record.event === "bundle_response_failed" && record.requestId === deliveryId && isBundleProof(record, since, platform));
198
207
  if (bundleErrors.length) {
@@ -257,6 +266,11 @@ async function verifyLaunch({ slot, appPid, platformShared, logsDir, since, metr
257
266
  await sleep(Math.min(pollMs, Math.max(0, (runtimeWaiting ? bundleDeadline : proof && pendingAt !== null ? readinessDeadline : stabilityDeadline ?? bundleDeadline) - now())));
258
267
  }
259
268
  }
269
+ function launchActivity(pendingAt, proof, bundling) {
270
+ if (pendingAt !== null) return ["waiting-ready", pendingAt];
271
+ if (proof) return [null, Number(proof.ts)];
272
+ return bundling ? ["bundling", Number(bundling.ts)] : [null, 0];
273
+ }
260
274
  function deliveryOwner(record, { slot, appPid, platformShared }) {
261
275
  if (slot === void 0) return "this";
262
276
  if (typeof record.clientPid === "number" && appPid) return record.clientPid === appPid ? "this" : "other";
@@ -306,7 +320,12 @@ function isIosConnectionRefusal(record, platform) {
306
320
  }
307
321
  function isFatalLaunchError(record, platform) {
308
322
  if (platform && recordPlatform(record) !== platform) return false;
309
- return record.event === "bundle_build_failed" || record.event === "bundling_error" || record.event === "transformer_error" || (record.event === "expo_stdout" || record.event === "expo_stderr") && typeof record.msg === "string" && /\bBundling failed\b/.test(record.msg);
323
+ return record.event === "bundle_build_failed" || record.event === "bundling_error" || record.event === "transformer_error" || [
324
+ "expo_stdout",
325
+ "expo_stderr",
326
+ "command_stdout",
327
+ "command_stderr"
328
+ ].includes(String(record.event)) && typeof record.msg === "string" && /\bBundling failed\b/.test(record.msg);
310
329
  }
311
330
  function isBundleReadyProof(record, since = 0, platform = null) {
312
331
  if (!isBundleProof(record, since, platform)) return false;
@@ -1,15 +1,15 @@
1
1
  import { t as process_identity_exports } from "./process-identity-Biv3arCO.mjs";
2
- import { f as refuseNoProject, l as phaseLine, v as launchErrorPreview } from "./command-output-Bt8ygHE7.mjs";
3
- import { H as projectDeviceSlots, V as parseDeviceSlotOption, _ as loadConfig$1, g as isPathPrefix } from "./config-DC5jEtd1.mjs";
4
- import { r as readWorkspaceState$1, x as workspaceLogsDir$1 } from "./workspace-state-CR9X86xJ.mjs";
5
- import { n as findCommandWorkspace } from "./project-B5eQ1USs.mjs";
6
- import { n as agentDeviceLiveness, u as readAgentDeviceRecords } from "./activity-BSw0x84R.mjs";
7
- import { n as SOURCES, t as LEVELS } from "./ndjson-LGZAMsqa.mjs";
8
- import { o as connectHost } from "./hosted-client-C5G4h_OJ.mjs";
9
- import { n as pullHostedNativeLogs, t as pullHostedMacosLogs } from "./hosted-logs-CI9Az9a4.mjs";
10
- import { n as readHostedIos, t as readHostedAndroid } from "./ios-state-By0XuLTQ.mjs";
11
- import { i as captureWorkspaceCrashes, t as errorDiagnostics } from "./error-diagnostics--v5HGOU0.mjs";
12
- import "./hosted-macos-DABm3ScO.mjs";
2
+ import { H as projectDeviceSlots, V as parseDeviceSlotOption, _ as loadConfig$1, g as isPathPrefix } from "./config-D0LhTY3S.mjs";
3
+ import { r as readWorkspaceState$1, w as workspaceLogsDir$1 } from "./workspace-state-CvgTFe-h.mjs";
4
+ import { f as refuseNoProject, l as phaseLine, v as launchErrorPreview } from "./command-output-CPDq_90S.mjs";
5
+ import { n as findCommandWorkspace } from "./project-DX8fXyw_.mjs";
6
+ import { n as SOURCES, t as LEVELS } from "./ndjson-GOnbyvso.mjs";
7
+ import { n as agentDeviceLiveness, u as readAgentDeviceRecords } from "./activity-BaMpUQ4-.mjs";
8
+ import { s as connectHost } from "./hosted-client--hNFgixu.mjs";
9
+ import { n as pullHostedNativeLogs, t as pullHostedMacosLogs } from "./hosted-logs-Bkz0Hxzh.mjs";
10
+ import { n as readHostedIos, t as readHostedAndroid } from "./ios-state-BsXMwo5y.mjs";
11
+ import { i as captureWorkspaceCrashes, t as errorDiagnostics } from "./error-diagnostics-BhQtoLrZ.mjs";
12
+ import "./hosted-macos-ckTjN-0V.mjs";
13
13
  import { t as watchStdoutReader } from "./stdout-reader-C8yjre1x.mjs";
14
14
  import { realpathSync } from "node:fs";
15
15
  import { dirname, join, relative, resolve, sep } from "node:path";
@@ -1,48 +1,30 @@
1
1
  import { t as process_identity_exports } from "./process-identity-Biv3arCO.mjs";
2
- import { t as getExecutor } from "./exec-i8GDPwq9.mjs";
2
+ import { t as getExecutor } from "./exec-B81Qodjn.mjs";
3
3
  import { t as spawnEntry } from "./spawn-entry-Dcb7sDUz.mjs";
4
- import { l as phaseLine } from "./command-output-Bt8ygHE7.mjs";
5
- import { E as upsertProject, u as getConcurrencyLimits } from "./config-DC5jEtd1.mjs";
6
- import { c as writeWorkspaceState, g as workspaceAgentDeviceDir, i as recordWorkspaceUse, u as ensureWorkspaceStorage, v as workspaceDir, x as workspaceLogsDir$1 } from "./workspace-state-CR9X86xJ.mjs";
7
- import { d as projectRegistry, o as ownedDeviceLabel, r as findProjectRoot } from "./project-B5eQ1USs.mjs";
8
- import { B as settingShapeErrors, I as resolveSettings, i as SETTING_SHAPE_REMEDY, mt as repoRoot, nt as gitCommonDir } from "./settings-CxgngUZk.mjs";
9
- import { F as recordFinishedBuild, I as startBuildProgress, L as tapBuildLog, O as NO_BUILD_PROGRESS, P as recordBuildPhase } from "./budget-Dz-kyXLv.mjs";
10
- import { M as acquireBuildSlot, P as releaseBuildSlot } from "./workspaces-Djb2gfi9.mjs";
4
+ import { E as upsertProject, u as getConcurrencyLimits } from "./config-D0LhTY3S.mjs";
5
+ import { K as resolveProjectSettings, Q as settingShapeErrors, a as SETTING_SHAPE_REMEDY } from "./settings-Bbztm4oV.mjs";
6
+ import { c as writeWorkspaceState, i as recordWorkspaceUse, p as ensureWorkspaceStorage, w as workspaceLogsDir$1, x as workspaceDir, y as workspaceAgentDeviceDir } from "./workspace-state-CvgTFe-h.mjs";
7
+ import { l as phaseLine } from "./command-output-CPDq_90S.mjs";
8
+ import { d as projectRegistry, o as ownedDeviceLabel, r as findProjectRoot } from "./project-DX8fXyw_.mjs";
11
9
  import { a as spawnDeclared } from "./spawn-claims-Kqiifsk2.mjs";
12
- import { E as sanitizeDeviceLabel } from "./ios-BWbHFZVz.mjs";
13
- import { a as withWorkspaceProcessLock } from "./named-ports-B4iWH4E-.mjs";
14
- import { i as macosProcess, n as macosDir, o as requiredMacosRecord, r as macosLogFile } from "./state-Tp4uImDS.mjs";
15
- import { r as createNdjsonWriter } from "./ndjson-LGZAMsqa.mjs";
16
- import { A as resolveBuildPlacement, C as setRemoteLogSink, D as parseBuildMachineOption, E as namedBuildMachine, O as requireLocalBuild, S as withNativeBuildRun, a as offloadBuild, c as placementLoad, i as closeOffload, l as remotePhaseText, n as buildPlacementCandidates, r as chooseBuildMachine, s as offloadPlacement, w as OffloadRefusal } from "./client-CuUo8Nvg.mjs";
17
- import { o as connectHost } from "./hosted-client-C5G4h_OJ.mjs";
18
- import { t as buildPlacementRecord } from "./placement-log-Dxe34rJm.mjs";
19
- import { t as placeHostedMacos } from "./hosted-macos-DABm3ScO.mjs";
20
- import { i as validateInfoPlist, t as resolveBundleExtras } from "./stage-BgaZJVZY.mjs";
21
- import { r as stopMacosAppHeld, t as stopBundleInstances } from "./stop-D0UIpZuh.mjs";
10
+ import { F as acquireBuildSlot, L as releaseBuildSlot } from "./workspaces-C4kqIOlx.mjs";
11
+ import { Dt as recordFinishedBuild, Et as recordBuildPhase, Ot as startBuildProgress, kt as tapBuildLog, yt as NO_BUILD_PROGRESS } from "./budget-RFbwFpG5.mjs";
12
+ import { a as withWorkspaceProcessLock } from "./named-ports-O1TIl7tx.mjs";
13
+ import { S as withNativeBuildRun } from "./tailnet-D7-tE_ug.mjs";
14
+ import { r as createNdjsonWriter } from "./ndjson-GOnbyvso.mjs";
15
+ import { _ as requireLocalBuild, c as offloadPlacement, f as setRemoteLogSink, g as parseBuildMachineOption, h as namedBuildMachine, i as closeOffload, l as placementLoad, n as buildPlacementCandidates, o as offloadBuild, p as OffloadRefusal, r as chooseBuildMachine, u as remotePhaseText, y as resolveBuildPlacement } from "./client-zqjFd79D.mjs";
16
+ import { D as sanitizeDeviceLabel } from "./ios-o896T9PE.mjs";
17
+ import { i as macosProcess, n as macosDir, o as requiredMacosRecord, r as macosLogFile } from "./state-BUpAmt2r.mjs";
18
+ import { t as buildPlacementRecord } from "./placement-log-BItXET1x.mjs";
19
+ import { s as connectHost } from "./hosted-client--hNFgixu.mjs";
20
+ import { t as placeHostedMacos } from "./hosted-macos-ckTjN-0V.mjs";
21
+ import { i as validateInfoPlist, t as resolveBundleExtras } from "./stage-BNKKdDNc.mjs";
22
+ import { r as stopMacosAppHeld, t as stopBundleInstances } from "./stop-Cftw_sXJ.mjs";
22
23
  import { closeSync, existsSync, mkdirSync, mkdtempSync, openSync, realpathSync, renameSync, rmSync } from "node:fs";
23
24
  import { join } from "node:path";
24
25
  import { machineCapacity, readMacosRecord, validHostedAppArguments } from "@stim-cli/core/state";
25
26
  import { LOG_ROTATE_BYTES } from "@stim-cli/core";
26
27
  import { createHash, randomUUID } from "node:crypto";
27
- //#region src/macos/app-name.ts
28
- const DOT = String.fromCodePoint(183);
29
- const ELLIPSIS = String.fromCodePoint(8230);
30
- const LABEL_MAX = 24;
31
- const PRODUCT_MAX = 40;
32
- function clip(text, max) {
33
- const chars = [...text];
34
- return chars.length <= max ? text : `${chars.slice(0, max - 1).join("")}${ELLIPSIS}`;
35
- }
36
- /** The visible app name for a run: `<product> <dot> <label>`, or just the product when the label is empty. */
37
- function macosAppName(product, label) {
38
- const name = clip(product.replace(/[\p{Cc}/:\\]+/gu, " ").trim(), PRODUCT_MAX) || "App";
39
- const suffix = clip(sanitizeDeviceLabel(label), LABEL_MAX);
40
- return suffix ? `${name} ${DOT} ${suffix}` : name;
41
- }
42
- function workspaceAppName(root, product) {
43
- return macosAppName(product, ownedDeviceLabel(root));
44
- }
45
- //#endregion
46
28
  //#region src/macos/build.ts
47
29
  async function buildMacosBundle({ root, recipe, bundle, bundleId, displayName, scratch, writer, note, record, buildMachine, progress = NO_BUILD_PROGRESS }) {
48
30
  if (record) record.buildMachine = buildMachine;
@@ -233,17 +215,31 @@ async function buildMacosBundle({ root, recipe, bundle, bundleId, displayName, s
233
215
  }
234
216
  }
235
217
  //#endregion
218
+ //#region src/macos/app-name.ts
219
+ const DOT = String.fromCodePoint(183);
220
+ const ELLIPSIS = String.fromCodePoint(8230);
221
+ const LABEL_MAX = 24;
222
+ const PRODUCT_MAX = 40;
223
+ function clip(text, max) {
224
+ const chars = [...text];
225
+ return chars.length <= max ? text : `${chars.slice(0, max - 1).join("")}${ELLIPSIS}`;
226
+ }
227
+ /** The visible app name for a run: `<product> <dot> <label>`, or just the product when the label is empty. */
228
+ function macosAppName(product, label) {
229
+ const name = clip(product.replace(/[\p{Cc}/:\\]+/gu, " ").trim(), PRODUCT_MAX) || "App";
230
+ const suffix = clip(sanitizeDeviceLabel(label), LABEL_MAX);
231
+ return suffix ? `${name} ${DOT} ${suffix}` : name;
232
+ }
233
+ function workspaceAppName(root, product) {
234
+ return macosAppName(product, ownedDeviceLabel(root));
235
+ }
236
+ //#endregion
236
237
  //#region src/macos/plan.ts
237
238
  function planMacos(root, buildMachineFlag) {
238
239
  if (process.platform !== "darwin") throw new Error("stim macos requires a Mac with Swift installed.");
239
240
  root = realpathSync(root);
240
241
  if (!existsSync(join(root, "Package.swift"))) throw new Error("Run stim macos from the directory containing Package.swift.");
241
- const repository = repoRoot(root);
242
- const settings = resolveSettings({
243
- projectPath: root,
244
- gitCommonDir: gitCommonDir(root),
245
- repoRoot: repository
246
- });
242
+ const { context, settings } = resolveProjectSettings(root);
247
243
  const [shape] = settingShapeErrors(settings);
248
244
  if (shape) throw new Error(`${shape} ${SETTING_SHAPE_REMEDY}`);
249
245
  const selected = resolveBuildPlacement(buildMachineFlag);
@@ -251,7 +247,7 @@ function planMacos(root, buildMachineFlag) {
251
247
  const macos = settings.macos;
252
248
  if (!macos?.product || !macos.infoPlist) throw Object.assign(/* @__PURE__ */ new Error("Set macos.product and macos.infoPlist explicitly in .stim.json. See stim guide macos."), { code: "STIM_BAD_ARG" });
253
249
  validateInfoPlist(root, macos.product, macos.infoPlist);
254
- resolveBundleExtras(root, repository ?? root, macos.resources, macos.assetCatalog);
250
+ resolveBundleExtras(root, context.repoRoot ?? root, macos.resources, macos.assetCatalog);
255
251
  return {
256
252
  platform: "macos",
257
253
  product: macos.product,
@@ -284,11 +280,7 @@ async function runMacos(root, note = console.error, remote, buildMachineFlag) {
284
280
  code: "STIM_NO_PROJECT",
285
281
  remedy: operation.problem.remedy
286
282
  });
287
- const settings = resolveSettings({
288
- projectPath: root,
289
- gitCommonDir: gitCommonDir(root),
290
- repoRoot: repoRoot(root)
291
- });
283
+ const { settings } = resolveProjectSettings(root);
292
284
  const [shape] = settingShapeErrors(settings);
293
285
  if (shape) throw new Error(`${shape} ${SETTING_SHAPE_REMEDY}`);
294
286
  const selected = resolveBuildPlacement(buildMachineFlag);
@@ -573,4 +565,4 @@ function macosCommand(program) {
573
565
  });
574
566
  }
575
567
  //#endregion
576
- export { runMacos as n, macosCommand as t };
568
+ export { runMacos as n, buildMacosBundle as r, macosCommand as t };
@@ -0,0 +1,2 @@
1
+ import { n as runMacos, t as macosCommand } from "./macos-D7irBW3A.mjs";
2
+ export { macosCommand as default, runMacos };
@@ -1,2 +1,2 @@
1
- import { n as runMacosSupervisor, t as logLines } from "./run-lAkle1-c.mjs";
1
+ import { n as runMacosSupervisor, t as logLines } from "./run-ClC8UVB5.mjs";
2
2
  export { logLines, runMacosSupervisor };
@@ -1,13 +1,13 @@
1
- import { M as isOnMountedVolume, N as listMountedVolumes, _ as loadConfig$1, j as formatBytes } from "./config-DC5jEtd1.mjs";
2
- import { D as projectMaintenancePinned } from "./settings-CxgngUZk.mjs";
3
- import { a as unregister, n as readManifest } from "./cache-manifest-DiwKSyv9.mjs";
4
- import { Nt as discoverCaches, Pt as pruneCache, l as resolveBudget, pt as planCacheEmptying, r as cacheLabel, st as emptyCaches } from "./budget-Dz-kyXLv.mjs";
5
- import { I as takeGcResults, L as canonicalPath, a as collectWorkspaceOutputs, i as collectOrphanedWorkspaces, o as deleteOrphanedWorkspaces, r as clearWorkspaceOutputs } from "./workspaces-Djb2gfi9.mjs";
6
- import { r as createNdjsonWriter } from "./ndjson-LGZAMsqa.mjs";
7
- import { t as relaunchWithLogFile } from "./detached-entry-pB_IPfV4.mjs";
1
+ import { M as isOnMountedVolume, N as listMountedVolumes, _ as loadConfig$1, j as formatBytes } from "./config-D0LhTY3S.mjs";
2
+ import { a as unregister, n as readManifest } from "./cache-manifest-qA3dT2x2.mjs";
3
+ import { T as canonicalPath, a as collectWorkspaceOutputs, i as collectOrphanedWorkspaces, o as deleteOrphanedWorkspaces, r as clearWorkspaceOutputs, w as takeGcResults } from "./workspaces-C4kqIOlx.mjs";
4
+ import { N as emptyCaches, at as discoverCaches, l as resolveBudget, ot as pruneCache, r as cacheLabel, z as planCacheEmptying } from "./budget-RFbwFpG5.mjs";
5
+ import { r as createNdjsonWriter } from "./ndjson-GOnbyvso.mjs";
6
+ import { t as relaunchWithLogFile } from "./detached-entry-BXq4fIl-.mjs";
7
+ import { F as memoryCulpritAdvice, N as memoryCulpritsUnder } from "./ios-o896T9PE.mjs";
8
8
  import { t as resolveMaintenanceSettings } from "./settings-Djl-mpjX.mjs";
9
9
  import { r as due, t as capChildLog } from "./attempt-DW-mQqM7.mjs";
10
- import { a as recentUse, d as measureDisk, f as measurePressure, i as cacheEntryProtection, m as sizeScanDeferred, p as measureSizes, r as triggeringRoot, s as removeWorktrees, t as plannedMaintenance, u as cacheBlocked } from "./preview-BbSottmO.mjs";
10
+ import { a as maintenancePinned, c as removeWorktrees, d as cacheBlocked, f as measureDisk, h as sizeScanDeferred, i as cacheEntryProtection, m as measureSizes, o as recentUse, p as measurePressure, r as triggeringRoot, t as plannedMaintenance } from "./preview-BRLFRhTz.mjs";
11
11
  import { appendFileSync, existsSync, mkdirSync, renameSync, statSync, unlinkSync, writeFileSync } from "node:fs";
12
12
  import { basename, join, resolve, sep } from "node:path";
13
13
  import { MAINTENANCE_LOG_NAME, maintenanceChildLogFile, maintenanceDir, maintenanceNdjsonFile, maintenanceRunClaims, maintenanceStateFile, readMaintenanceState, sharedCompilationCache, workspaceLogsDir } from "@stim-cli/core/state";
@@ -123,7 +123,7 @@ async function clearOutputs(action, context) {
123
123
  const root = action.workspace;
124
124
  if (!root) return kept("the action names no workspace");
125
125
  if (root === context.protectedRoot) return kept("the command that started this pass runs in it");
126
- if (projectMaintenancePinned(root)) return kept("pinned by maintenance.keep");
126
+ if (maintenancePinned(root)) return kept("pinned by maintenance.keep");
127
127
  const recent = recentUse(root, context.settings);
128
128
  if (recent) return kept(recent);
129
129
  const olderThan = action.olderThanDays ?? null;
@@ -150,7 +150,7 @@ async function removeWorktree(action, context) {
150
150
  if (!sweep || !worktree) return kept("it is not in this pass's worktree check");
151
151
  const path = canonicalPath(worktree.path);
152
152
  if (context.protectedRoot === path || context.protectedRoot.startsWith(`${path}${sep}`)) return kept("the command that started this pass runs inside it");
153
- if (worktree.keys.some(projectMaintenancePinned)) return kept("pinned by maintenance.keep");
153
+ if (worktree.keys.some(maintenancePinned)) return kept("pinned by maintenance.keep");
154
154
  const { results } = await quietly(() => removeWorktrees({
155
155
  ...sweep,
156
156
  worktrees: [worktree]
@@ -343,6 +343,8 @@ async function runMaintenance(trigger) {
343
343
  if (check === "worktree" || check === "sweep") continue;
344
344
  if (check === "pressure") {
345
345
  state.pressure = measurePressure(settings, state.pressure, state.lastAt[check]);
346
+ const culprits = settings.memoryPressureLevel === "off" ? null : memoryCulpritsUnder(state.pressure.memory.level);
347
+ if (culprits) state.pressure.memory.culprits = culprits;
346
348
  const floor = Math.max(budget.minFreeDiskMb, budget.hardFloorDiskMb);
347
349
  for (const disk of state.pressure.disk) record("maintenance_check", "debug", `Disk free on ${disk.volume}: ${(disk.freeMb / 1024).toFixed(1)}G`, { check: {
348
350
  kind: "disk-free",
@@ -356,6 +358,7 @@ async function runMaintenance(trigger) {
356
358
  threshold: state.pressure.memory.availableBytes === null ? settings.memoryPressureLevel : settings.minAvailableMemoryGb ?? "10% of RAM",
357
359
  unit: state.pressure.memory.availableBytes === null ? "level" : "GiB"
358
360
  } });
361
+ for (const culprit of state.pressure.memory.culprits ?? []) record("maintenance_check", "info", memoryCulpritAdvice([culprit]), { culprit });
359
362
  } else {
360
363
  measuredSizes = true;
361
364
  state.sizes = measureSizes(state.lastAt[check], (target, workspace) => {
@@ -1,7 +1,7 @@
1
1
  import { t as process_identity_exports } from "./process-identity-Biv3arCO.mjs";
2
- import { t as getExecutor } from "./exec-i8GDPwq9.mjs";
3
- import { M as isOnMountedVolume, N as listMountedVolumes, _ as loadConfig, n as allMetroPorts, r as claimMetroPort, x as releaseMetroPort } from "./config-DC5jEtd1.mjs";
4
- import { r as readWorkspaceState } from "./workspace-state-CR9X86xJ.mjs";
2
+ import { t as getExecutor } from "./exec-B81Qodjn.mjs";
3
+ import { M as isOnMountedVolume, N as listMountedVolumes, _ as loadConfig, n as allMetroPorts, r as claimMetroPort, x as releaseMetroPort } from "./config-D0LhTY3S.mjs";
4
+ import { r as readWorkspaceState } from "./workspace-state-CvgTFe-h.mjs";
5
5
  import { sep } from "path";
6
6
  import { existsSync, readlinkSync, realpathSync } from "fs";
7
7
  import { readFile } from "node:fs/promises";
@@ -297,7 +297,12 @@ function parseNetstatPids(out, port) {
297
297
  return pids;
298
298
  }
299
299
  function listeningPids(port, platform = process.platform) {
300
- const pids = parseLsofPids(getExecutor().runQuiet(`lsof -nP -iTCP:${port} -sTCP:LISTEN -t`));
300
+ const pids = parseLsofPids(getExecutor().runFileQuiet("lsof", [
301
+ "-nP",
302
+ `-iTCP:${port}`,
303
+ "-sTCP:LISTEN",
304
+ "-t"
305
+ ]));
301
306
  if (pids.length > 0 || platform !== "win32") return pids;
302
307
  return parseNetstatPids(getExecutor().runQuiet("netstat -ano"), port);
303
308
  }
@@ -371,7 +376,14 @@ function processCwd(pid) {
371
376
  if (process.platform === "linux") try {
372
377
  return readlinkSync(`/proc/${pid}/cwd`);
373
378
  } catch {}
374
- return parseLsofCwd(getExecutor().runQuiet(`lsof -a -p ${pid} -d cwd -Fn`));
379
+ return parseLsofCwd(getExecutor().runFileQuiet("lsof", [
380
+ "-a",
381
+ "-p",
382
+ String(pid),
383
+ "-d",
384
+ "cwd",
385
+ "-Fn"
386
+ ]));
375
387
  }
376
388
  function canonicalPath(path) {
377
389
  try {
@@ -439,6 +451,7 @@ async function resolveProjectMetro(port, projectPath, { probe = isMetroRunning,
439
451
  * always forceful.
440
452
  */
441
453
  function signalProcessTree(pid, signal = "SIGTERM", { group = false, platform = process.platform } = {}) {
454
+ if (!Number.isSafeInteger(pid) || pid <= 1) throw new Error(`Refusing to signal pid ${pid}.`);
442
455
  if (platform !== "win32") return process.kill(group ? -pid : pid, signal);
443
456
  return getExecutor().runFileQuiet("taskkill", [
444
457
  "/PID",
@@ -1,6 +1,6 @@
1
1
  import { t as process_identity_exports } from "./process-identity-Biv3arCO.mjs";
2
- import { a as updateWorkspaceState, r as readWorkspaceState$1 } from "./workspace-state-CR9X86xJ.mjs";
3
- import { L as realIo } from "./client-CuUo8Nvg.mjs";
2
+ import { a as updateWorkspaceState, r as readWorkspaceState$1 } from "./workspace-state-CvgTFe-h.mjs";
3
+ import { l as realIo } from "./tailnet-D7-tE_ug.mjs";
4
4
  import { HOSTED_METRO_REQUESTS_KEY, findPeer, hostedMetroGateways, hostedMetroRequests, isJsonObject, parseMachine } from "@stim-cli/core/state";
5
5
  import { randomBytes, randomUUID } from "node:crypto";
6
6
  import { isIP } from "node:net";
@@ -0,0 +1,238 @@
1
+ import { ht as gitCommonDirOnDisk } from "./settings-Bbztm4oV.mjs";
2
+ import { C as diffFingerprintSources, I as storedSources } from "./device-lease-C309csaB.mjs";
3
+ import { m as sharedBuildCache } from "./workspace-state-CvgTFe-h.mjs";
4
+ import { existsSync, realpathSync } from "node:fs";
5
+ import { dirname, join, relative } from "node:path";
6
+ import { LAST_BUILD_KEYS, loadConfig, readWorkspaceState } from "@stim-cli/core/state";
7
+ import * as expoFingerprint from "@expo/fingerprint";
8
+ //#region src/cache/miss-reason.ts
9
+ const MISS_CHANGE_CAP = 20;
10
+ function recordedBuilds(state, platform) {
11
+ const builds = [];
12
+ for (const value of [state?.[LAST_BUILD_KEYS[platform]], state?.lastBuild]) {
13
+ const record = value;
14
+ if (record?.platform !== platform) continue;
15
+ const startedAt = typeof record.startedAt === "string" ? record.startedAt : "";
16
+ if (typeof record.fingerprint === "string" && typeof record.cacheKey === "string") builds.push({
17
+ fingerprint: record.fingerprint,
18
+ cacheKey: record.cacheKey,
19
+ startedAt
20
+ });
21
+ const carried = record.missReason?.baseline;
22
+ if (typeof carried?.fingerprint === "string" && typeof carried.cacheKey === "string") builds.push({
23
+ fingerprint: carried.fingerprint,
24
+ cacheKey: carried.cacheKey,
25
+ startedAt
26
+ });
27
+ }
28
+ return builds;
29
+ }
30
+ function projectIdentity(root) {
31
+ let real;
32
+ try {
33
+ real = realpathSync.native(root);
34
+ } catch {
35
+ return null;
36
+ }
37
+ for (let dir = real;; dir = dirname(dir)) {
38
+ if (existsSync(join(dir, ".git"))) {
39
+ const common = gitCommonDirOnDisk(dir);
40
+ return common ? `${common}\n${relative(dir, real)}` : null;
41
+ }
42
+ if (dirname(dir) === dir) return null;
43
+ }
44
+ }
45
+ function findMissBaseline(root, platform, { readState = readWorkspaceState, projectRoots = () => Object.keys(loadConfig()?.projects ?? {}), identity = projectIdentity, sourcesOf = (p, key) => storedSources(p, key, sharedBuildCache()) } = {}) {
46
+ for (const build of recordedBuilds(readState(root), platform)) {
47
+ const sources = sourcesOf(platform, build.cacheKey);
48
+ if (sources) return {
49
+ fingerprint: build.fingerprint,
50
+ cacheKey: build.cacheKey,
51
+ sources,
52
+ from: "workspace"
53
+ };
54
+ }
55
+ const project = identity(root);
56
+ if (!project) return null;
57
+ const others = [];
58
+ for (const other of projectRoots()) {
59
+ if (other === root || identity(other) !== project) continue;
60
+ others.push(...recordedBuilds(readState(other), platform));
61
+ }
62
+ for (const build of others.toSorted((a, b) => (Date.parse(b.startedAt) || 0) - (Date.parse(a.startedAt) || 0))) {
63
+ const sources = sourcesOf(platform, build.cacheKey);
64
+ if (sources) return {
65
+ fingerprint: build.fingerprint,
66
+ cacheKey: build.cacheKey,
67
+ sources,
68
+ from: "project"
69
+ };
70
+ }
71
+ return null;
72
+ }
73
+ const CATEGORY_RANK = {
74
+ "native-dependency": 0,
75
+ "app-config": 1,
76
+ "config-plugin": 2,
77
+ package: 3,
78
+ "native-dir": 4,
79
+ file: 5,
80
+ "app-asset": 6,
81
+ other: 7,
82
+ "package-scripts": 8,
83
+ autolinking: 9
84
+ };
85
+ function packageIn(path) {
86
+ return [...path.matchAll(/(?:^|\/)node_modules\/((?:@[^/]+\/)?[^/]+)/g)].at(-1)?.[1] ?? null;
87
+ }
88
+ function describeChange({ name, change, reasons }) {
89
+ const pkg = packageIn(name);
90
+ if (name === "expoConfig" || reasons.includes("expoConfig")) return {
91
+ category: "app-config",
92
+ label: "app config changed"
93
+ };
94
+ if (pkg && reasons.some((reason) => /^(expo|rncore)Autolinking(Ios|Android)?$/.test(reason))) return {
95
+ category: "native-dependency",
96
+ label: `native dependency ${change}: ${pkg}`
97
+ };
98
+ if (pkg && reasons.includes("expoConfigPlugins")) return {
99
+ category: "config-plugin",
100
+ label: `config plugin ${change}: ${pkg}`
101
+ };
102
+ if (/^(expoAutolinkingConfig|rncoreAutolinkingConfig)(:|$)/.test(name)) return {
103
+ category: "autolinking",
104
+ label: "autolinking config changed"
105
+ };
106
+ if (name.startsWith("package:")) return {
107
+ category: "package",
108
+ label: `${name.slice(8)} ${change}`
109
+ };
110
+ if (name === "packageJson:scripts") return {
111
+ category: "package-scripts",
112
+ label: "package.json scripts changed"
113
+ };
114
+ if (reasons.includes("expoConfigExternalFile")) return {
115
+ category: "app-asset",
116
+ label: `app asset ${change}: ${name}`
117
+ };
118
+ if (reasons.includes("bareNativeDir")) return {
119
+ category: "native-dir",
120
+ label: `${name}/ ${change}`
121
+ };
122
+ if (reasons.length || name.includes("/") || name.includes(".")) return {
123
+ category: "file",
124
+ label: `${name} ${change}`
125
+ };
126
+ return {
127
+ category: "other",
128
+ label: `${name} ${change}`
129
+ };
130
+ }
131
+ function rekeyPrefix(rekeyedBy) {
132
+ return rekeyedBy.length ? `${rekeyedBy.join(" and ")} changed native inputs; ` : "";
133
+ }
134
+ function missReasonFromChanges({ changes, baseline, rekeyedBy = [] }) {
135
+ const prefix = rekeyPrefix(rekeyedBy);
136
+ if (!baseline) return {
137
+ kind: "no-baseline",
138
+ summary: `${prefix}no earlier build of this project in the cache to compare with`,
139
+ changes: [],
140
+ changeCount: 0,
141
+ baseline: null,
142
+ rekeyedBy
143
+ };
144
+ if (!changes.length) return {
145
+ kind: "same-sources",
146
+ summary: `${prefix}native inputs match the last build; no cached app for this configuration or target`,
147
+ changes: [],
148
+ changeCount: 0,
149
+ baseline,
150
+ rekeyedBy
151
+ };
152
+ const described = changes.map((change, index) => ({
153
+ change,
154
+ index,
155
+ ...describeChange(change)
156
+ })).toSorted((a, b) => CATEGORY_RANK[a.category] - CATEGORY_RANK[b.category] || a.index - b.index);
157
+ const dependencyMoved = described.some((entry) => entry.category === "native-dependency");
158
+ const labels = [...new Set(described.filter((entry) => !(dependencyMoved && entry.category === "autolinking")).map((entry) => entry.label))];
159
+ const more = labels.length > 1 ? ` (+${labels.length - 1} more)` : "";
160
+ return {
161
+ kind: "changed",
162
+ summary: `${prefix}${labels[0]}${more}`,
163
+ changes: described.slice(0, MISS_CHANGE_CAP).map(({ change, category }) => ({
164
+ source: change.name,
165
+ change: change.change,
166
+ category
167
+ })),
168
+ changeCount: changes.length,
169
+ baseline,
170
+ rekeyedBy
171
+ };
172
+ }
173
+ function explainBuildMiss({ root, platform, current, rekeyedBy = [], baselineDeps, differ = expoFingerprint.diffFingerprints }) {
174
+ const baseline = findMissBaseline(root, platform, baselineDeps);
175
+ const changes = baseline ? diffFingerprintSources({
176
+ previous: baseline.sources,
177
+ previousHash: baseline.fingerprint,
178
+ current,
179
+ differ
180
+ }) : [];
181
+ return {
182
+ reason: missReasonFromChanges({
183
+ changes,
184
+ baseline: baseline ? {
185
+ fingerprint: baseline.fingerprint,
186
+ cacheKey: baseline.cacheKey,
187
+ from: baseline.from
188
+ } : null,
189
+ rekeyedBy
190
+ }),
191
+ changedNames: changes.map((change) => change.name),
192
+ previousHash: baseline?.fingerprint ?? null
193
+ };
194
+ }
195
+ function predictBuildMiss({ root, platform, current, prebuild }) {
196
+ const { reason } = explainBuildMiss({
197
+ root,
198
+ platform,
199
+ current
200
+ });
201
+ const baseline = reason.baseline && {
202
+ fingerprint: reason.baseline.fingerprint,
203
+ from: reason.baseline.from
204
+ };
205
+ if (!prebuild || !baseline) return {
206
+ ...reason,
207
+ baseline
208
+ };
209
+ const dir = platform === "ios" ? "ios/" : "android/";
210
+ return {
211
+ ...reason,
212
+ kind: "prebuild-pending",
213
+ summary: `${reason.summary} (before prebuild ${prebuild}s ${dir})`,
214
+ baseline
215
+ };
216
+ }
217
+ function skippedMissReason(summary) {
218
+ return {
219
+ kind: "cache-skipped",
220
+ summary,
221
+ changes: [],
222
+ changeCount: 0,
223
+ baseline: null,
224
+ rekeyedBy: []
225
+ };
226
+ }
227
+ function fingerprintErrorMissReason(message) {
228
+ return {
229
+ kind: "fingerprint-error",
230
+ summary: `fingerprinting failed: ${message}`,
231
+ changes: [],
232
+ changeCount: 0,
233
+ baseline: null,
234
+ rekeyedBy: []
235
+ };
236
+ }
237
+ //#endregion
238
+ export { skippedMissReason as i, fingerprintErrorMissReason as n, predictBuildMiss as r, explainBuildMiss as t };
@@ -1,7 +1,7 @@
1
1
  import { n as ownership_claim_exports, t as process_identity_exports } from "./process-identity-Biv3arCO.mjs";
2
- import { t as getExecutor } from "./exec-i8GDPwq9.mjs";
3
- import { C as saveConfig, D as withConfigLock, _ as loadConfig, c as ensureConfig, d as getConfigDir, p as getProject } from "./config-DC5jEtd1.mjs";
4
- import { d as signalProcessTree, f as createPortProbe, o as parseNetstatPids } from "./metro-DI2AjPF_.mjs";
2
+ import { t as getExecutor } from "./exec-B81Qodjn.mjs";
3
+ import { C as saveConfig, D as withConfigLock, _ as loadConfig, c as ensureConfig, d as getConfigDir, p as getProject } from "./config-D0LhTY3S.mjs";
4
+ import { d as signalProcessTree, f as createPortProbe, o as parseNetstatPids } from "./metro-_ZIE3Axg.mjs";
5
5
  import { n as declareSpawnsOn, o as stopDeclaringSpawnsOn } from "./spawn-claims-Kqiifsk2.mjs";
6
6
  import { realpathSync } from "node:fs";
7
7
  import { join } from "node:path";