stim 1.26.0 → 1.27.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 (171) hide show
  1. package/dist/{acquire-artifact-DVsvSwf7.mjs → acquire-artifact-BKN2Yuhg.mjs} +2 -2
  2. package/dist/{act-C-BqJEpu.mjs → act-ROviTF_t.mjs} +297 -122
  3. package/dist/{activity-Lnb_EoRY.mjs → activity-Cd-ysFes.mjs} +6 -6
  4. package/dist/{agent-device-usage-output-DbXy5tg8.mjs → agent-device-usage-output-C5nCKWp9.mjs} +5 -5
  5. package/dist/{android-CSbLRD53.mjs → android--HBgpvpW.mjs} +5 -5
  6. package/dist/{android-CiNQw3kq.mjs → android-Cd6w7_qw.mjs} +96 -43
  7. package/dist/{android-B5P81yI-.mjs → android-Deb9X3_Y.mjs} +37 -15
  8. package/dist/{android-DTAcRwBC.mjs → android-DriNoAVy.mjs} +23 -18
  9. package/dist/{android-cas-BTVhZ0Qs.mjs → android-cas-D5e6ecUg.mjs} +4 -4
  10. package/dist/android-cas-compiler.mjs +1 -1
  11. package/dist/api.d.mts +13 -3
  12. package/dist/api.mjs +39 -29
  13. package/dist/{apk-signed-tail-B46U9hXc.mjs → apk-signed-tail-BHQHx3Rm.mjs} +2 -2
  14. package/dist/{artifact-BxREhAaV.mjs → artifact-0AGJYB9O.mjs} +18 -23
  15. package/dist/{artifact-CsAP6AGK.mjs → artifact-faemIZv5.mjs} +19 -24
  16. package/dist/{artifact-platform-CMRc0M_r.mjs → artifact-platform-BO2Uvk_A.mjs} +1 -1
  17. package/dist/auto-placement-z-H5pJza.mjs +350 -0
  18. package/dist/{browser-web-rYPyqhTf.mjs → browser-web-slD8AvLp.mjs} +16 -16
  19. package/dist/{build-cache-DrXNCy3T.mjs → build-cache-gBJ-WKzA.mjs} +43 -21
  20. package/dist/{build-DPhApsjV.mjs → build-hS0QyFlQ.mjs} +35 -31
  21. package/dist/{build-plan-DrMMdayj.mjs → build-plan-CBqYbzYM.mjs} +7 -6
  22. package/dist/{cache-manifest-BEZ9Bpl1.mjs → cache-manifest-DEjqGGat.mjs} +1 -1
  23. package/dist/cache-manifest.mjs +1 -1
  24. package/dist/{budget-k2mZGvvk.mjs → ccache-BWTze1Ls.mjs} +560 -1603
  25. package/dist/{cdp-BG3FJCCx.mjs → cdp-C3svvXiE.mjs} +1 -1
  26. package/dist/{chrome-BvV8ssI3.mjs → chrome-DyDWurWG.mjs} +1 -1
  27. package/dist/{cli-BBKFGOFl.mjs → cli-ftXDLto1.mjs} +24 -23
  28. package/dist/cli.mjs +1 -1
  29. package/dist/{client-D9CaRks-.mjs → client-xsdxrhWA.mjs} +48 -62
  30. package/dist/collector-run.d.mts +10 -9
  31. package/dist/collector-run.mjs +42 -27
  32. package/dist/{command-output-BF5AR2dL.mjs → command-output-Dj-WT4BP.mjs} +1 -1
  33. package/dist/{config-BktkY_zC.mjs → config-Cn94Jc0g.mjs} +23 -4
  34. package/dist/{dependencies-Dw6wfQdv.mjs → dependencies-BGokZ-Ng.mjs} +108 -60
  35. package/dist/{dependency-state-DFB41vfr.mjs → dependency-state-C3OtgG94.mjs} +14 -7
  36. package/dist/{detached-entry-KmieOKgN.mjs → detached-entry-BPlSaCwC.mjs} +1 -1
  37. package/dist/{dev-client-DXR_tPVY.mjs → dev-client-BMca82xo.mjs} +2 -2
  38. package/dist/{device-BcYeHSFu.mjs → device-BJm0irrq.mjs} +16 -16
  39. package/dist/{device-capacity-DCSvUF0l.mjs → device-capacity-6LP7QsaA.mjs} +101 -16
  40. package/dist/device-host-worker.mjs +19 -19
  41. package/dist/{device-ios-BLGfXQeK.mjs → device-ios-534c14fz.mjs} +251 -23
  42. package/dist/{device-lease-run-BmvIl7bI.mjs → device-lease-run-DwsGfjUN.mjs} +5 -5
  43. package/dist/{device-pool-Dluix4H3.mjs → device-pool-BnQqvs6o.mjs} +3 -3
  44. package/dist/{device-BK-zwyd_.mjs → device-tM41-TUq.mjs} +25 -24
  45. package/dist/{doctor-Cp-BhzTS.mjs → doctor-Dbx1ZpD2.mjs} +1 -1
  46. package/dist/{doctor-Bhg1ii70.mjs → doctor-DyqE9n1J.mjs} +28 -16
  47. package/dist/{doctor-OnwP94ne.mjs → doctor-F-3VUUyN.mjs} +76 -32
  48. package/dist/{doctor-fingerprint-D3a04Mhu.mjs → doctor-fingerprint-o7ZI9YLn.mjs} +1 -1
  49. package/dist/doctor-fingerprint.mjs +1 -1
  50. package/dist/{doctor-watchman-BStK05nt.mjs → doctor-watchman-CxDbyrrt.mjs} +5 -5
  51. package/dist/{eas-build-Dsj93iM9.mjs → eas-build-CjNSWmjo.mjs} +4 -4
  52. package/dist/eas-fallback-9fqb46kW.mjs +87 -0
  53. package/dist/{eas-session-ledger-B5vygTiD.mjs → eas-session-ledger-DrP4OuuM.mjs} +6 -6
  54. package/dist/{error-diagnostics-BOOm9Db7.mjs → error-diagnostics-snej9k4j.mjs} +51 -25
  55. package/dist/{exec-VFRpu1iA.mjs → exec-aULwtNly.mjs} +57 -6
  56. package/dist/{gc-C_79zvz4.mjs → gc-BRwAY3qT.mjs} +2 -2
  57. package/dist/{gc-ldgr-hXU.mjs → gc-CGZ1Yg88.mjs} +160 -45
  58. package/dist/{guide-D7K0X6KG.mjs → guide-_rfEh_zM.mjs} +580 -183
  59. package/dist/{hosted-android-Bk54ej6n.mjs → hosted-android-BMKzUNnY.mjs} +4 -4
  60. package/dist/{hosted-client-fHO8yqzc.mjs → hosted-client-D7Pk_Oo1.mjs} +12 -8
  61. package/dist/{hosted-logs-BfbmDM4M.mjs → hosted-logs-B1gqQuva.mjs} +8 -8
  62. package/dist/{hosted-logs-sync-B0pvmOk-.mjs → hosted-logs-sync-Dg3qrZmV.mjs} +5 -5
  63. package/dist/{hosted-macos-CPl0OZ9h.mjs → hosted-macos-B9w4H8hc.mjs} +6 -6
  64. package/dist/{hosted-native-CpDB3-PO.mjs → hosted-native-CdgaiuyP.mjs} +17 -16
  65. package/dist/{idle-shutdown-FfxL1KdG.mjs → idle-shutdown-Cbvo5KEh.mjs} +7 -8
  66. package/dist/{ios-ftxdQbJS.mjs → ios-B5HlVMhQ.mjs} +92 -37
  67. package/dist/{ios-B7-lToDu.mjs → ios-Bk4mWbtS.mjs} +8 -8
  68. package/dist/{ios-ENC4sRPA.mjs → ios-CsRVik64.mjs} +7 -1
  69. package/dist/{ios-WxpDJ5T1.mjs → ios-E26qSpkb.mjs} +27 -11
  70. package/dist/{ios-device-CsyryvpT.mjs → ios-device-C_QkIf1Z.mjs} +3 -3
  71. package/dist/{ios-device-B6HK951C.mjs → ios-device-CiBA-er9.mjs} +1 -1
  72. package/dist/{ios-project-Ty5pHl9O.mjs → ios-project-D8Jcy_br.mjs} +22 -9
  73. package/dist/{ios-signing-4c_qXvQm.mjs → ios-signing-BJzvDPfU.mjs} +2 -2
  74. package/dist/{ios-state-Cw7-WQf2.mjs → ios-state-BZ03NFgF.mjs} +1 -1
  75. package/dist/{js-swap-BMhXYVDS.mjs → js-swap-Dg2a945i.mjs} +8 -7
  76. package/dist/{launch-DOp8RjDz.mjs → launch-CRyBeNsA.mjs} +42 -38
  77. package/dist/lightened-BCsdAGj_.mjs +171 -0
  78. package/dist/{logs-dQDki6Tt.mjs → logs-CC_-ZzEE.mjs} +7 -7
  79. package/dist/{logs-s1dRIG1E.mjs → logs-aJQb-RDg.mjs} +46 -21
  80. package/dist/{macos-B0VEV3Gf.mjs → macos-BGmTpnv9.mjs} +1 -1
  81. package/dist/{macos-DBBPNnIA.mjs → macos-DlCBhMw5.mjs} +73 -38
  82. package/dist/macos-run.mjs +1 -1
  83. package/dist/maintenance-run.mjs +7 -7
  84. package/dist/{metro-CjC10t6E.mjs → metro-CvyD-xwe.mjs} +4 -4
  85. package/dist/{metro-gateway-B6_PgD0L.mjs → metro-gateway-BnHdqMO_.mjs} +3 -3
  86. package/dist/{named-ports-BG0j1X4g.mjs → named-ports-BCyMWA6b.mjs} +3 -3
  87. package/dist/{native-android-CL2NGiik.mjs → native-android-DlpxCyOP.mjs} +17 -18
  88. package/dist/{native-gradle-artifact-inputs-btSUulme.mjs → native-gradle-artifact-inputs-C13qT7R_.mjs} +5 -5
  89. package/dist/{native-runtime-Dq3RBcON.mjs → native-runtime-DqaIBO5w.mjs} +9 -8
  90. package/dist/{native-source-D-4Dh4JU.mjs → native-source-D1AzWiuP.mjs} +1 -1
  91. package/dist/{native-xcode-inputs-BW7H8JGu.mjs → native-xcode-inputs-B1W8SrxB.mjs} +3 -3
  92. package/dist/{native-xcode-ios-CBXJAxfC.mjs → native-xcode-ios-QPP0Rm68.mjs} +17 -17
  93. package/dist/{ndjson-CgE_o3Dl.mjs → ndjson-Dy2W4vRa.mjs} +2 -2
  94. package/dist/offload-worker.mjs +23 -24
  95. package/dist/{operation-exec-CUZifp6Z.mjs → operation-exec-Dp4FuIGR.mjs} +1 -1
  96. package/dist/{ownership-BjYvMNX_.mjs → ownership-Bx-0cku-.mjs} +3 -3
  97. package/dist/{page-CzEA_-5_.mjs → page-CQJlcj3x.mjs} +2 -2
  98. package/dist/{phone-reverses-lmj6kcPm.mjs → phone-reverses-C9yAaKEv.mjs} +18 -4
  99. package/dist/{placement-log-DIFPQAXp.mjs → placement-log-BXUbiZM6.mjs} +3 -3
  100. package/dist/{plan-placement-IiiSQhtz.mjs → plan-placement-UxnQjv5Z.mjs} +36 -10
  101. package/dist/{ports-C2_w1Z0Z.mjs → ports-uUrghqWN.mjs} +3 -3
  102. package/dist/{prebuild-gmouvmJZ.mjs → prebuild-BDpToDgR.mjs} +16 -17
  103. package/dist/{project-BUu6Is4k.mjs → project-DYj-HVx6.mjs} +17 -17
  104. package/dist/{pull-request-CbNlkFok.mjs → pull-request-BzLmzAIQ.mjs} +2 -2
  105. package/dist/pull-requests.mjs +1 -1
  106. package/dist/{react-native-android-Cgg99REN.mjs → react-native-android-DDBccgJw.mjs} +32 -26
  107. package/dist/{react-native-build-oNwqF5Wb.mjs → react-native-build-DaK2IFyP.mjs} +9 -9
  108. package/dist/{react-native-doctor-BhA3KUte.mjs → react-native-doctor-B-Mw6DcR.mjs} +6 -6
  109. package/dist/{react-native-ios-B-nf4rjN.mjs → react-native-ios-DjYwUF9U.mjs} +23 -17
  110. package/dist/{recordings-BldzVKq0.mjs → recordings-C20iUZfp.mjs} +1 -1
  111. package/dist/{registration-CN6nlhcD.mjs → registration-BwCe64PH.mjs} +1 -1
  112. package/dist/{reload-C9OduiNc.mjs → reload-DJBeF_rC.mjs} +1 -1
  113. package/dist/{reload-CCR7KC_l.mjs → reload-fUdkH2_p.mjs} +16 -16
  114. package/dist/{remote-C8S7FlPF.mjs → remote-y6n99WMW.mjs} +22 -9
  115. package/dist/{result-7F5hEwQJ.mjs → result-CTqBw2Te.mjs} +32 -21
  116. package/dist/{run-BqB0v3pt.mjs → run-DaCeNKRm.mjs} +3 -3
  117. package/dist/{selection-BNPBZ6T5.mjs → selection-Bs8phwhN.mjs} +37 -29
  118. package/dist/{server-bare-A75rDIdD.mjs → server-bare-BOh-iZEj.mjs} +2 -2
  119. package/dist/{server-command-CssKFOD7.mjs → server-command-8CuA51Cv.mjs} +6 -6
  120. package/dist/{server-expo-eQfOdydb.mjs → server-expo-ABQs2XFA.mjs} +4 -4
  121. package/dist/server-expo-Ba_Y21vB.mjs +2 -0
  122. package/dist/{settings-CosW5X-S.mjs → settings-BDVI8Ivc.mjs} +331 -62
  123. package/dist/{settings-OaGQF-ri.mjs → settings-CMHhQNwI.mjs} +24 -3
  124. package/dist/settings-payload-cm60Zhib.mjs +257 -0
  125. package/dist/settings-write-BdNRLlBn.mjs +185 -0
  126. package/dist/settings.schema.json +51 -33
  127. package/dist/{simslim-Bax1qcxu.mjs → simslim-DCQwzoPy.mjs} +2 -2
  128. package/dist/{slot-launch-CYCEhfBY.mjs → slot-launch-0l7RqSpr.mjs} +6 -6
  129. package/dist/{stage-jKQ7CP_B.mjs → stage-F4cAfJGi.mjs} +2 -2
  130. package/dist/{start-C_wefNKB.mjs → start-DcqnF9p8.mjs} +1 -1
  131. package/dist/{start-_BdJ32cZ.mjs → start-DrPwER_2.mjs} +27 -22
  132. package/dist/{state-C1i2nMOP.mjs → state-BX1y5syV.mjs} +4 -4
  133. package/dist/{state-C4OdpOTF.mjs → state-CZxLyetD.mjs} +2 -2
  134. package/dist/{stats-tEpEEH-u.mjs → stats-GxuCbles.mjs} +5 -5
  135. package/dist/{stats-report-n2U5plhk.mjs → stats-report-B86Cv7Uc.mjs} +1 -1
  136. package/dist/{status-CRXz-Gtj.mjs → status-7ULDEJ1e.mjs} +1 -1
  137. package/dist/{status-DQrqodLj.mjs → status-BfnK9pUd.mjs} +25 -25
  138. package/dist/{status-B9M7x4CZ.mjs → status-Bj7ZYvvc.mjs} +1 -1
  139. package/dist/{status-watch-B5wDIH_o.mjs → status-watch-BfabQn03.mjs} +5 -5
  140. package/dist/status-worker.mjs +1 -1
  141. package/dist/{stim-desktop-6Dqp-gjX.mjs → stim-desktop-CbWo21kb.mjs} +2 -2
  142. package/dist/{stop-ySNQHXMG.mjs → stop-CH79S3IZ.mjs} +5 -5
  143. package/dist/{stop-DRqQVqDJ.mjs → stop-D-EAr25B.mjs} +21 -20
  144. package/dist/{stop-CmdNhGlC.mjs → stop-x1Yu3He4.mjs} +2 -2
  145. package/dist/supervisor-run.mjs +17 -17
  146. package/dist/{support-CVOCp0Ft.mjs → support-Be0UeVZU.mjs} +10 -10
  147. package/dist/{support-BGSCBoib.mjs → support-CNg_YsOk.mjs} +6 -6
  148. package/dist/{swiftpm-artifact-inputs-CfUzt_0Z.mjs → swiftpm-artifact-inputs-uPqYvGBv.mjs} +4 -4
  149. package/dist/{swiftpm-macos-x6HPpl_2.mjs → swiftpm-macos-Ch4YjY_A.mjs} +11 -12
  150. package/dist/{toolchain-J4J8MrAr.mjs → toolchain-CbCG6C5Z.mjs} +321 -15
  151. package/dist/{toolchain-DoavrvIA.mjs → toolchain-JYAOquPg.mjs} +1 -1
  152. package/dist/{trigger-KVaWWNyn.mjs → trigger-DMou-X7j.mjs} +2 -2
  153. package/dist/trigger-qp2ji5wE.mjs +2 -0
  154. package/dist/{warm-progress-DvhTX_eu.mjs → warm-progress-C0RsbngN.mjs} +731 -727
  155. package/dist/{web-Bihbf7-u.mjs → web-Cq_AQ4DK.mjs} +9 -9
  156. package/dist/web-Je6abcpz.mjs +2 -0
  157. package/dist/web-run.mjs +9 -9
  158. package/dist/windows-report.mjs +1 -1
  159. package/dist/{workspace-state-pUg3_RRA.mjs → workspace-state-BjqdjnJR.mjs} +3 -3
  160. package/dist/{workspaces-g2lhdBXF.mjs → workspaces-DFbj07jp.mjs} +1795 -70
  161. package/dist/{worktree-BKuklFh_.mjs → worktree-COAJ3-OD.mjs} +934 -514
  162. package/dist/{worktree-Bm4cb-nU.mjs → worktree-JGUd_53L.mjs} +1 -1
  163. package/package.json +7 -7
  164. package/dist/ccache-Bx5TbxwG.mjs +0 -143
  165. package/dist/eas-fallback-FwkeqqGi.mjs +0 -381
  166. package/dist/hosted-ios-D55QhYaD.mjs +0 -15
  167. package/dist/native-run-BfIDFKLH.mjs +0 -275
  168. package/dist/server-expo-wvcj5tiZ.mjs +0 -2
  169. package/dist/settings-write-QjYfSrjF.mjs +0 -360
  170. package/dist/trigger-DzJu208Q.mjs +0 -2
  171. package/dist/web-BFLueSh-.mjs +0 -2
@@ -1,13 +1,14 @@
1
- import { w as workspaceAgentDeviceDir } from "./workspace-state-pUg3_RRA.mjs";
2
- import { i as formatDuration, l as phaseLine } from "./command-output-BF5AR2dL.mjs";
3
- import { a as workspaceLinkLine } from "./stim-desktop-6Dqp-gjX.mjs";
4
- import { Gn as UPLOAD_TIMEOUT_MS, Jn as easAuthNote, Kn as cacheLevel, W as recordFinishedBuild, Yn as isEasAuthFailureText } from "./budget-k2mZGvvk.mjs";
5
- import { P as compilationCacheActivityLine, k as COMPILATION_CACHE_NOT_RUN } from "./toolchain-J4J8MrAr.mjs";
6
- import { i as deviceLabel } from "./support-CVOCp0Ft.mjs";
1
+ import { w as workspaceAgentDeviceDir } from "./workspace-state-BjqdjnJR.mjs";
2
+ import { i as formatDuration, l as phaseLine } from "./command-output-Dj-WT4BP.mjs";
3
+ import { a as workspaceLinkLine } from "./stim-desktop-CbWo21kb.mjs";
4
+ import { Mn as isEasAuthFailureText, On as UPLOAD_TIMEOUT_MS, jn as easAuthNote, kn as cacheLevel } from "./ccache-BWTze1Ls.mjs";
5
+ import { q as recordFinishedBuild } from "./workspaces-DFbj07jp.mjs";
6
+ import { P as compilationCacheActivityLine, k as COMPILATION_CACHE_NOT_RUN } from "./toolchain-CbCG6C5Z.mjs";
7
+ import { i as deviceLabel } from "./support-Be0UeVZU.mjs";
7
8
  import { buildDiagnostics } from "@stim-cli/core/state";
8
9
  import chalk from "chalk";
9
10
  //#region src/commands/ios/result.ts
10
- function lastBuildRecord({ devicePlacement, fingerprint = null, cacheKey = null, cacheHit = false, cacheSkipped = false, durationMs = 0, appPath = null, bundleId = null, startedAt, status, errorCode = null, missReason = null, diagnostics = null, configuration = null, buildMachine = "auto", builtOn, offloadedTo = null, offloadFallback = null }) {
11
+ function lastBuildRecord({ devicePlacement, fingerprint = null, cacheKey = null, cacheHit = false, cacheSkipped = false, durationMs = 0, appPath = null, bundleId = null, startedAt, status, errorCode = null, missReason = null, diagnostics = null, configuration = null, buildMachine = "auto", builtOn, offloadedTo = null, offloadFallback = null, ledger }) {
11
12
  const record = {
12
13
  platform: "ios",
13
14
  fingerprint,
@@ -30,6 +31,7 @@ function lastBuildRecord({ devicePlacement, fingerprint = null, cacheKey = null,
30
31
  if (missReason && !cacheLevel(cacheHit)) record.missReason = missReason;
31
32
  const recorded = status === "failed" ? buildDiagnostics(diagnostics) : [];
32
33
  if (recorded.length) record.diagnostics = recorded;
34
+ if (ledger) record.ledger = ledger;
33
35
  return record;
34
36
  }
35
37
  function iosFacts({ root, slot, udid, deviceName, deviceType = null, runtime = null, fingerprint, configuration = null, scheme = null, cacheKey, cacheHit, cacheSkipped = false, compilationCache = COMPILATION_CACHE_NOT_RUN, waitedForBuild = null, appPath, bundleId, installSkipped = false, metroPort, logsDir, durationMs, launched = true, webPreviewUrl = null, lease, devServer = null, buildMachine = "auto", builtOn, offloadedTo = null, offloadFallback = null }) {
@@ -68,6 +70,13 @@ function iosFacts({ root, slot, udid, deviceName, deviceType = null, runtime = n
68
70
  ...devServer ? { devServer } : {}
69
71
  };
70
72
  }
73
+ function iosLedgerDevice(device) {
74
+ const name = device?.deviceName ?? device?.name;
75
+ return name && name !== device?.deviceUdid ? {
76
+ name,
77
+ runtime: device?.runtime ?? null
78
+ } : null;
79
+ }
71
80
  function writeLastBuild(root, record, { record: recordBuild = recordFinishedBuild } = {}) {
72
81
  try {
73
82
  recordBuild(root, record);
@@ -118,7 +127,11 @@ function reportIosResult({ output, devicePlacement, host, slot, root, json, rele
118
127
  buildMachine,
119
128
  builtOn,
120
129
  offloadedTo,
121
- offloadFallback
130
+ offloadFallback,
131
+ ledger: {
132
+ scheme: buildScheme,
133
+ device: iosLedgerDevice(device)
134
+ }
122
135
  }));
123
136
  closeWriter();
124
137
  const facts = iosFacts({
@@ -194,4 +207,4 @@ var IosRecipeRefusal = class extends Error {
194
207
  }
195
208
  };
196
209
  //#endregion
197
- export { lastBuildRecord as a, iosFacts as i, cacheDescription as n, reportIosResult as o, finishIosUpload as r, writeLastBuild as s, IosRecipeRefusal as t };
210
+ export { iosLedgerDevice as a, writeLastBuild as c, iosFacts as i, cacheDescription as n, lastBuildRecord as o, finishIosUpload as r, reportIosResult as s, IosRecipeRefusal as t };
@@ -1,5 +1,5 @@
1
- import { c as throwIfCancelled, t as getExecutor } from "./exec-VFRpu1iA.mjs";
2
- import { a as killOnAbort, r as childEnvironment } from "./operation-exec-CUZifp6Z.mjs";
1
+ import { c as throwIfCancelled, t as getExecutor } from "./exec-aULwtNly.mjs";
2
+ import { a as killOnAbort, r as childEnvironment } from "./operation-exec-Dp4FuIGR.mjs";
3
3
  import { X509Certificate } from "node:crypto";
4
4
  import { existsSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
5
5
  import { tmpdir } from "node:os";
@@ -1,4 +1,4 @@
1
- import { l as withWorkspaceStateLockAsync, o as updateWorkspaceState, r as readWorkspaceState$1 } from "./workspace-state-pUg3_RRA.mjs";
1
+ import { l as withWorkspaceStateLockAsync, o as updateWorkspaceState, r as readWorkspaceState$1 } from "./workspace-state-BjqdjnJR.mjs";
2
2
  import { HOSTED_METRO_REQUESTS_KEY, hostedMetroRequests, hostedNativeRecords, isJsonObject, parseHostedNativePlacement, unreadableHostedNative } from "@stim-cli/core/state";
3
3
  //#region src/device-host/ios-state.ts
4
4
  function readHostedNative(root, platform, slot) {
@@ -1,10 +1,10 @@
1
- import { _ as spawnDeclared, b as operationState, c as throwIfCancelled, t as getExecutor } from "./exec-VFRpu1iA.mjs";
1
+ import { _ as spawnDeclared, b as operationState, c as throwIfCancelled, t as getExecutor } from "./exec-aULwtNly.mjs";
2
2
  import { r as waitForChild, t as createLineReader } from "./process-output-Fpl8PYi8.mjs";
3
- import { a as killOnAbort, t as runOperationFile } from "./operation-exec-CUZifp6Z.mjs";
4
- import { Ut as makeTemporaryDirectory, Wt as removeTemporaryEntry } from "./settings-CosW5X-S.mjs";
5
- import { rr as bundleInvocation } from "./budget-k2mZGvvk.mjs";
6
- import { s as expoTelemetryEnv, t as cleanLine } from "./server-expo-eQfOdydb.mjs";
7
- import { G as tailLines, U as startBuildHeartbeat, j as HEARTBEAT_INTERVAL_MS } from "./toolchain-J4J8MrAr.mjs";
3
+ import { a as killOnAbort, t as runOperationFile } from "./operation-exec-Dp4FuIGR.mjs";
4
+ import { $t as makeTemporaryDirectory, en as removeTemporaryEntry } from "./settings-BDVI8Ivc.mjs";
5
+ import { Bn as bundleInvocation } from "./ccache-BWTze1Ls.mjs";
6
+ import { G as tailLines, U as startBuildHeartbeat, j as HEARTBEAT_INTERVAL_MS } from "./toolchain-CbCG6C5Z.mjs";
7
+ import { s as expoTelemetryEnv, t as cleanLine } from "./server-expo-ABQs2XFA.mjs";
8
8
  import { randomUUID } from "node:crypto";
9
9
  import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
10
10
  import { basename, join } from "node:path";
@@ -120,7 +120,8 @@ async function readPlistKey(context, e, plist, key, format) {
120
120
  plist
121
121
  ], { timeoutMs: 1e4 });
122
122
  } catch (err) {
123
- if (/No value at that key path/.test(describe(err))) return null;
123
+ const stdout = typeof err === "object" && err !== null && "stdout" in err ? String(err.stdout) : "";
124
+ if (/No value at that key path/.test(`${describe(err)}\n${stdout}`)) return null;
124
125
  throw err;
125
126
  }
126
127
  }
@@ -1,23 +1,24 @@
1
- import { k as workspaceLogsDir } from "./workspace-state-pUg3_RRA.mjs";
2
- import { B as deviceSlotFileKey, C as saveConfig, E as upsertProject, H as deviceSlotPlatforms, O as withConfigLockAsync, P as formatBytes, V as deviceSlotKey, _ as loadConfig, w as setDevice } from "./config-BktkY_zC.mjs";
3
- import { _ as stepTimer, c as launchErrorReport, i as formatDuration, l as phaseLine, n as appReadinessMessage, v as launchErrorPreview } from "./command-output-BF5AR2dL.mjs";
4
- import { L as workspaceDevServerMode } from "./project-BUu6Is4k.mjs";
5
- import { o as workspaceLinks } from "./stim-desktop-6Dqp-gjX.mjs";
6
- import { i as androidDataFreeBytes, ot as trimAndroidCaches, tt as resetAdoptedAvd, u as androidToolCwd } from "./android-DTAcRwBC.mjs";
7
- import { c as pidExists, f as signalProcessTree } from "./metro-CjC10t6E.mjs";
8
- import { $t as LAUNCH_BUNDLING, Dn as installConflictKind, Nn as restartedAppNote, cn as unattributedLaunchLines, en as LAUNCH_FATAL, in as VERIFY_TIMEOUT_MS, ln as unverifiedLaunchLines, mn as ADB_INSTALL_TIMEOUT_MS, rn as RELEASE_VERIFY_WAIT_MS, tn as LAUNCH_UNVERIFIED, vn as androidAppProcess, yn as androidDevClientUrl } from "./budget-k2mZGvvk.mjs";
9
- import { O as teardownOwnedAvd } from "./workspaces-g2lhdBXF.mjs";
10
- import { b as providerUploadOutcome } from "./build-cache-DrXNCy3T.mjs";
11
- import { n as verifyCollectorOwnership, r as readCollectors } from "./ownership-BjYvMNX_.mjs";
12
- import { t as recordPhoneReverse } from "./phone-reverses-lmj6kcPm.mjs";
13
- import { n as nativeRunCommand, r as siblingPlatformSlots, t as launchSlotScope } from "./slot-launch-CYCEhfBY.mjs";
1
+ import { x as withDrainingCancellation } from "./exec-aULwtNly.mjs";
2
+ import { k as workspaceLogsDir } from "./workspace-state-BjqdjnJR.mjs";
3
+ import { B as deviceSlotFileKey, C as saveConfig, E as upsertProject, H as deviceSlotPlatforms, O as withConfigLockAsync, P as formatBytes, V as deviceSlotKey, _ as loadConfig, w as setDevice } from "./config-Cn94Jc0g.mjs";
4
+ import { _ as stepTimer, c as launchErrorReport, i as formatDuration, l as phaseLine, n as appReadinessMessage, v as launchErrorPreview } from "./command-output-Dj-WT4BP.mjs";
5
+ import { L as workspaceDevServerMode } from "./project-DYj-HVx6.mjs";
6
+ import { o as workspaceLinks } from "./stim-desktop-CbWo21kb.mjs";
7
+ import { i as androidDataFreeBytes, ot as trimAndroidCaches, tt as resetAdoptedAvd, u as androidToolCwd } from "./android-DriNoAVy.mjs";
8
+ import { c as pidExists, f as signalProcessTree } from "./metro-CvyD-xwe.mjs";
9
+ import { Bt as RELEASE_VERIFY_WAIT_MS, Gt as unattributedLaunchLines, It as LAUNCH_BUNDLING, Kt as unverifiedLaunchLines, Lt as LAUNCH_FATAL, Rt as LAUNCH_UNVERIFIED, Vt as VERIFY_TIMEOUT_MS, Zt as ADB_INSTALL_TIMEOUT_MS, gn as restartedAppNote, nn as androidDevClientUrl, tn as androidAppProcess, un as installConflictKind } from "./ccache-BWTze1Ls.mjs";
10
+ import { ut as teardownOwnedAvd } from "./workspaces-DFbj07jp.mjs";
11
+ import { x as providerUploadOutcome } from "./build-cache-gBJ-WKzA.mjs";
12
+ import { t as recordPhoneReverse } from "./phone-reverses-C9yAaKEv.mjs";
13
+ import { n as verifyCollectorOwnership, r as readCollectors } from "./ownership-Bx-0cku-.mjs";
14
+ import { n as nativeRunCommand, r as siblingPlatformSlots, t as launchSlotScope } from "./slot-launch-0l7RqSpr.mjs";
14
15
  import { t as spawnEntry } from "./spawn-entry-jw19m8Nl.mjs";
15
- import { c as lostRefusal, s as lostLine, t as DEBUG_VERIFY_STEP_MS } from "./device-lease-run-BmvIl7bI.mjs";
16
- import { a as printNativeCrashReport, r as captureNativeCrashes, t as errorDiagnostics } from "./error-diagnostics-BOOm9Db7.mjs";
17
- import { f as settleFingerprintCheck } from "./prebuild-gmouvmJZ.mjs";
18
- import { i as launchOutcomeRecord } from "./native-runtime-Dq3RBcON.mjs";
19
- import { a as PLATFORM, b as noDeviceDiagnostic, h as displayPath, n as LAUNCH_FAILED, r as NO_DEVICE, t as INSTALL_FAILED } from "./support-BGSCBoib.mjs";
20
- import { a as persistLastBuild, n as finishAndroidUpload, s as reportAndroidResult } from "./result-7F5hEwQJ.mjs";
16
+ import { c as lostRefusal, s as lostLine, t as DEBUG_VERIFY_STEP_MS } from "./device-lease-run-DwsGfjUN.mjs";
17
+ import { a as captureNativeCrashes, r as androidCrashClockOffset, s as printNativeCrashReport, t as errorDiagnostics } from "./error-diagnostics-snej9k4j.mjs";
18
+ import { f as settleFingerprintCheck } from "./prebuild-BDpToDgR.mjs";
19
+ import { i as launchOutcomeRecord } from "./native-runtime-DqaIBO5w.mjs";
20
+ import { a as PLATFORM, b as noDeviceDiagnostic, h as displayPath, n as LAUNCH_FAILED, r as NO_DEVICE, t as INSTALL_FAILED } from "./support-CNg_YsOk.mjs";
21
+ import { a as persistLastBuild, n as finishAndroidUpload, s as reportAndroidResult } from "./result-CTqBw2Te.mjs";
21
22
  import { mkdirSync, openSync, statSync } from "node:fs";
22
23
  import { basename, join } from "node:path";
23
24
  import { ambientEnv } from "@stim-cli/core";
@@ -104,17 +105,11 @@ async function startCollector({ root, slot = "default", serial, packageName, spa
104
105
  //#endregion
105
106
  //#region src/commands/android/launch.ts
106
107
  function androidLaunchOutcomeRecord(kind, args) {
107
- if (kind !== "process") return launchOutcomeRecord({
108
+ return launchOutcomeRecord({
108
109
  ...args,
109
- release: kind === "embedded-js"
110
+ release: kind === "embedded-js",
111
+ process: kind === "process"
110
112
  });
111
- const unverified = args.launchState === LAUNCH_UNVERIFIED;
112
- return {
113
- src: "build",
114
- level: unverified ? "warn" : "info",
115
- event: unverified ? "launch_unverified" : "launch_verified",
116
- msg: unverified ? `${args.bundleId} could not be verified as running` : `${args.bundleId} is running its native process`
117
- };
118
113
  }
119
114
  function androidProcessRuntime(prepare, kind = "process") {
120
115
  return {
@@ -192,19 +187,28 @@ async function verifyAndroidMetroRun({ operation, root, slot, remoteDevice, veri
192
187
  physical,
193
188
  deviceId: serial
194
189
  });
195
- const readNativeCrashes = () => hostedLogs ? hostedLogs.readNativeCrashes() : remoteDevice ? [] : captureNativeCrashes({
196
- root,
197
- slot,
198
- platform: "android",
199
- deviceId: serial,
200
- appId: androidPackage,
201
- since: launchedAt
202
- }, logsDir, operation?.signal, operation?.env);
190
+ let clockOffsetMs;
191
+ const readNativeCrashes = async () => {
192
+ if (hostedLogs) return hostedLogs.readNativeCrashes();
193
+ if (remoteDevice) return [];
194
+ const measured = clockOffsetMs ?? await androidCrashClockOffset(serial, operation?.signal);
195
+ if (measured !== null) clockOffsetMs = measured;
196
+ return captureNativeCrashes({
197
+ root,
198
+ slot,
199
+ platform: "android",
200
+ deviceId: serial,
201
+ appId: androidPackage,
202
+ since: launchedAt,
203
+ clockOffsetMs: measured
204
+ }, logsDir, operation?.signal, operation?.env);
205
+ };
203
206
  const freshEmulator = Boolean((device.created || device.adoptionPending) && device.owned && !remoteDevice);
204
207
  const timeoutMs = freshEmulator ? 6e4 : VERIFY_TIMEOUT_MS;
205
208
  if (metroCheck && freshEmulator) phase("verify", `waiting up to 60s for bundle load (${device.created ? "new" : "adopted"} emulator)`);
206
209
  const siblings = metroCheck ? await siblingPlatformSlots(root, "android", slot) : [];
207
- const verification = metroCheck ? await verifyLaunched({
210
+ const verification = metroCheck ? await withDrainingCancellation(operation, operation?.signal, () => verifyLaunched({
211
+ signal: operation?.signal,
208
212
  timeoutMs,
209
213
  requireBundleResponse: true,
210
214
  slot: launchSlotScope(root, slot),
@@ -223,7 +227,7 @@ async function verifyAndroidMetroRun({ operation, root, slot, remoteDevice, veri
223
227
  const running = await androidAppProcess(serial, androidPackage);
224
228
  return running.state === "unknown" ? null : running.state === "running";
225
229
  }
226
- }) : {
230
+ })) : {
227
231
  verified: false,
228
232
  skipped: true
229
233
  };
@@ -0,0 +1,171 @@
1
+ import { l as WorkspaceProcessCleanupError } from "./exec-aULwtNly.mjs";
2
+ import { c as withWorkspaceStateLock } from "./workspace-state-BjqdjnJR.mjs";
3
+ import { l as phaseLine } from "./command-output-Dj-WT4BP.mjs";
4
+ import { Nt as podsOutOfSync, Ot as listCarryableIgnoredEntries, Pt as readWorktreeExclude, Q as resolveSettings, Wt as warmWorktreePaths, _t as depsOutOfSync } from "./settings-BDVI8Ivc.mjs";
5
+ import { t as canonicalPath } from "./paths-BsJMoPP2.mjs";
6
+ import { h as warmWorktreeTarget } from "./worktree-COAJ3-OD.mjs";
7
+ import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
8
+ import { basename, dirname, join, relative } from "node:path";
9
+ import { isJsonObject, readJsonObject, workspaceLightenedFile, workspaceMetadataFile } from "@stim-cli/core/state";
10
+ //#region src/workspace/lightened.ts
11
+ function strings(value) {
12
+ return Array.isArray(value) ? value.filter((entry) => typeof entry === "string") : [];
13
+ }
14
+ function readRecord(root) {
15
+ const record = readJsonObject(workspaceLightenedFile(root));
16
+ return isJsonObject(record) ? {
17
+ dirs: strings(record.dirs),
18
+ pending: strings(record.pending)
19
+ } : {
20
+ dirs: [],
21
+ pending: []
22
+ };
23
+ }
24
+ /** The keys among `keys` that have a Stim workspace, which is what restores a lightened worktree. */
25
+ function workspaceKeys(keys) {
26
+ return keys.filter((key) => existsSync(workspaceMetadataFile(key)));
27
+ }
28
+ const LOCKFILES = [
29
+ "pnpm-lock.yaml",
30
+ "package-lock.json",
31
+ "yarn.lock",
32
+ "bun.lock",
33
+ "bun.lockb"
34
+ ];
35
+ function readOrNull(path) {
36
+ try {
37
+ return readFileSync(path);
38
+ } catch {
39
+ return null;
40
+ }
41
+ }
42
+ async function sourceFacts(worktree, operation) {
43
+ try {
44
+ const { root: source, common } = await warmWorktreePaths(worktree, operation);
45
+ const settings = resolveSettings({
46
+ gitCommonDir: common,
47
+ repoRoot: source
48
+ }).worktree;
49
+ const configured = isJsonObject(settings) && Array.isArray(settings.exclude) ? settings.exclude.filter((entry) => typeof entry === "string") : [];
50
+ const excluded = readWorktreeExclude(source);
51
+ const patterns = excluded?.length ? excluded : configured;
52
+ return {
53
+ source,
54
+ carryable: new Set(await listCarryableIgnoredEntries(source, patterns, {
55
+ env: operation?.env,
56
+ signal: operation?.signal,
57
+ declareFor: operation
58
+ }))
59
+ };
60
+ } catch (error) {
61
+ operation?.signal.throwIfAborted();
62
+ if (error instanceof WorkspaceProcessCleanupError) throw error;
63
+ return null;
64
+ }
65
+ }
66
+ /**
67
+ * Why `worktree warm` could not put back what is deleted at `path`, or null when it copies the same versions back: it
68
+ * carries that directory from the source checkout, and both hold the same lockfile.
69
+ */
70
+ async function restoreProblem({ worktree, path }, cache = /* @__PURE__ */ new Map(), operation) {
71
+ let pending = cache.get(worktree);
72
+ if (!pending) cache.set(worktree, pending = sourceFacts(worktree, operation));
73
+ const facts = await pending;
74
+ if (!facts) return "its source checkout cannot be resolved, so worktree warm could not restore it";
75
+ const rel = relative(worktree, path);
76
+ if (!facts.carryable.has(rel)) return `worktree warm would not copy ${rel} back from the source checkout`;
77
+ const pods = basename(rel) === "Pods";
78
+ if ((pods ? podsOutOfSync(facts.source, [rel]) : depsOutOfSync(facts.source, facts.source, [rel])).length) return `the source checkout's ${rel} was not installed from its own lockfile, so worktree warm would restore other versions`;
79
+ const differs = (pods ? [join(dirname(rel), "Podfile.lock")] : [.../* @__PURE__ */ new Set([".", dirname(rel)])].flatMap((dir) => LOCKFILES.map((name) => join(dir, name)))).find((lock) => {
80
+ const mine = readOrNull(join(worktree, lock));
81
+ const theirs = readOrNull(join(facts.source, lock));
82
+ return mine === null ? theirs !== null : theirs === null || !mine.equals(theirs);
83
+ });
84
+ return differs ? `its ${differs} differs from the source checkout's, so worktree warm would restore other versions` : null;
85
+ }
86
+ function writeRecord(key, update) {
87
+ withWorkspaceStateLock(key, () => {
88
+ const file = workspaceLightenedFile(key);
89
+ mkdirSync(dirname(file), { recursive: true });
90
+ const tmp = `${file}.tmp-${process.pid}`;
91
+ writeFileSync(tmp, `${JSON.stringify({
92
+ at: (/* @__PURE__ */ new Date()).toISOString(),
93
+ ...update(readRecord(key))
94
+ }, null, 2)}\n`, { mode: 384 });
95
+ renameSync(tmp, file);
96
+ });
97
+ }
98
+ /**
99
+ * Records in each Stim workspace among `keys` that `dir` is being deleted to lighten its worktree, before the deletion;
100
+ * it stays pending until `finishLightened`, so a deletion that stops part-way is still restored.
101
+ */
102
+ function recordLightened(keys, dir) {
103
+ for (const key of workspaceKeys(keys)) writeRecord(key, ({ dirs, pending }) => ({
104
+ dirs: [.../* @__PURE__ */ new Set([...dirs, dir])],
105
+ pending: [.../* @__PURE__ */ new Set([...pending, dir])]
106
+ }));
107
+ }
108
+ function finishLightened(keys, dir) {
109
+ for (const key of workspaceKeys(keys)) writeRecord(key, ({ dirs, pending }) => ({
110
+ dirs,
111
+ pending: pending.filter((entry) => entry !== dir)
112
+ }));
113
+ }
114
+ function depsFailure(root, message, remedy = `Run \`stim worktree warm\` in ${root}, or install the project's dependencies, then retry.`) {
115
+ return {
116
+ code: "STIM_DEPS_FAILED",
117
+ message: `gc lightened this worktree, and ${message}`,
118
+ remedy: `${remedy} If you installed them yourself, delete ${workspaceLightenedFile(root)} so Stim stops restoring them.`
119
+ };
120
+ }
121
+ /**
122
+ * Restores the dependencies gc deleted from this workspace's worktree through `stim worktree warm`, or returns the
123
+ * failure to report. A workspace gc never lightened is left alone.
124
+ */
125
+ async function restoreLightenedDependencies(root, operation) {
126
+ const { dirs, pending } = readRecord(root);
127
+ if (!dirs.length) return null;
128
+ const missing = () => dirs.filter((dir) => pending.includes(dir) || !existsSync(dir));
129
+ if (missing().length) {
130
+ const cache = /* @__PURE__ */ new Map();
131
+ const worktree = (await warmWorktreePaths(root, operation).catch(() => null))?.target;
132
+ for (const dir of missing()) {
133
+ const problem = worktree ? await restoreProblem({
134
+ worktree,
135
+ path: dir
136
+ }, cache, operation) : "its worktree cannot be resolved";
137
+ if (problem) return depsFailure(root, `${dir} cannot be restored by worktree warm: ${problem}.`, `Install the project's dependencies in ${root} (for example \`pnpm install\` or \`pod install\`), then retry.`);
138
+ }
139
+ operation.output("stderr", `${phaseLine("deps", `gc lightened this worktree; restoring ${missing().join(", ")} with worktree warm`)}\n`);
140
+ for (const dir of pending) {
141
+ if (!worktree || canonicalPath(dir) !== join(canonicalPath(worktree), relative(worktree, dir))) return depsFailure(root, `${dir} is reached through a link or lies outside its worktree, so it was not removed.`);
142
+ rmSync(dir, {
143
+ recursive: true,
144
+ force: true
145
+ });
146
+ }
147
+ let exitCode;
148
+ try {
149
+ ({exitCode} = await warmWorktreeTarget({
150
+ cwd: root,
151
+ operation
152
+ }));
153
+ } catch (error) {
154
+ operation.signal.throwIfAborted();
155
+ if (error instanceof WorkspaceProcessCleanupError) throw error;
156
+ return depsFailure(root, `worktree warm failed: ${error instanceof Error ? error.message : String(error)}`);
157
+ }
158
+ const left = dirs.filter((dir) => !existsSync(dir));
159
+ if (exitCode !== 0 || left.length) return depsFailure(root, `worktree warm did not restore ${left.join(", ") || "its dependencies"}.`);
160
+ }
161
+ withWorkspaceStateLock(root, () => rmSync(workspaceLightenedFile(root), { force: true }));
162
+ return null;
163
+ }
164
+ /** Prints a restore failure the way a native run reports a refusal, with the JSON line on stdout when asked. */
165
+ function printLightenedFailure(operation, failure, json) {
166
+ operation.output("stderr", `${phaseLine("error", `${failure.code}: ${failure.message}`)}\n`);
167
+ operation.output("stderr", `${phaseLine("remedy", failure.remedy)}\n`);
168
+ if (json) operation.output("stdout", `${JSON.stringify(failure)}\n`);
169
+ }
170
+ //#endregion
171
+ export { restoreProblem as a, restoreLightenedDependencies as i, printLightenedFailure as n, workspaceKeys as o, recordLightened as r, finishLightened as t };
@@ -1,9 +1,9 @@
1
- import { S as process_identity_exports } from "./exec-VFRpu1iA.mjs";
2
- import { k as workspaceLogsDir$1 } from "./workspace-state-pUg3_RRA.mjs";
3
- import { G as projectDeviceSlots, _ as loadConfig$1 } from "./config-BktkY_zC.mjs";
4
- import { f as readAgentDeviceRecordsAsync, n as agentDeviceLiveness, o as envDir } from "./activity-Lnb_EoRY.mjs";
5
- import { i as captureWorkspaceCrashes } from "./error-diagnostics-BOOm9Db7.mjs";
6
- import { n as followHostedLogs, r as syncHostedLogs } from "./hosted-logs-sync-B0pvmOk-.mjs";
1
+ import { S as process_identity_exports } from "./exec-aULwtNly.mjs";
2
+ import { k as workspaceLogsDir$1 } from "./workspace-state-BjqdjnJR.mjs";
3
+ import { G as projectDeviceSlots, _ as loadConfig$1 } from "./config-Cn94Jc0g.mjs";
4
+ import { f as readAgentDeviceRecordsAsync, n as agentDeviceLiveness, o as envDir } from "./activity-Cd-ysFes.mjs";
5
+ import { o as captureWorkspaceCrashes } from "./error-diagnostics-snej9k4j.mjs";
6
+ import { n as followHostedLogs, r as syncHostedLogs } from "./hosted-logs-sync-Dg3qrZmV.mjs";
7
7
  import { readdirSync, statSync, watch } from "node:fs";
8
8
  import { homedir } from "node:os";
9
9
  import { dirname, join, relative, resolve, sep } from "node:path";
@@ -264,7 +264,7 @@ async function readWorkspaceLogs(context, options = {}) {
264
264
  await view.close();
265
265
  }
266
266
  }
267
- const WORKSPACE_SOURCES = SOURCES.filter((source) => source !== "gc");
267
+ const WORKSPACE_SOURCES = SOURCES.filter((source) => source !== "gc" && source !== "builds");
268
268
  function validateLogOptions(options) {
269
269
  const invalid = (options.tail !== void 0 && (!Number.isSafeInteger(options.tail) || options.tail < 0) ? "tail must be a non-negative integer." : options.sources?.some((source) => !WORKSPACE_SOURCES.includes(source)) ? `sources must contain only ${WORKSPACE_SOURCES.join(", ")}.` : options.minLevel !== void 0 && !LEVELS.includes(options.minLevel) ? `minLevel must be one of ${LEVELS.join(", ")}.` : void 0) ?? (options.since !== void 0 ? parseSince(options.since).error : void 0) ?? (options.grep !== void 0 ? compileGrep(options.grep).error : void 0);
270
270
  if (invalid) throw Object.assign(new Error(invalid), { code: "STIM_BAD_ARG" });
@@ -1,18 +1,19 @@
1
- import { k as workspaceLogsDir$1, r as readWorkspaceState$1 } from "./workspace-state-pUg3_RRA.mjs";
2
- import { W as parseDeviceSlotOption, _ as loadConfig$1, g as isPathPrefix } from "./config-BktkY_zC.mjs";
3
- import { f as refuseNoProject, v as launchErrorPreview } from "./command-output-BF5AR2dL.mjs";
4
- import { n as findCommandWorkspace } from "./project-BUu6Is4k.mjs";
5
- import { n as SOURCES$1, t as LEVELS$1 } from "./ndjson-CgE_o3Dl.mjs";
6
- import { i as followAgentActions, n as openWorkspaceLogs } from "./logs-dQDki6Tt.mjs";
7
- import { t as errorDiagnostics } from "./error-diagnostics-BOOm9Db7.mjs";
8
- import { n as followHostedLogs } from "./hosted-logs-sync-B0pvmOk-.mjs";
1
+ import { k as workspaceLogsDir$1, r as readWorkspaceState$1 } from "./workspace-state-BjqdjnJR.mjs";
2
+ import { W as parseDeviceSlotOption, _ as loadConfig$1, g as isPathPrefix$1 } from "./config-Cn94Jc0g.mjs";
3
+ import { f as refuseNoProject, v as launchErrorPreview } from "./command-output-Dj-WT4BP.mjs";
4
+ import { n as findCommandWorkspace } from "./project-DYj-HVx6.mjs";
5
+ import { n as SOURCES$1, t as LEVELS$1 } from "./ndjson-Dy2W4vRa.mjs";
6
+ import { i as followAgentActions, n as openWorkspaceLogs } from "./logs-CC_-ZzEE.mjs";
7
+ import { t as errorDiagnostics } from "./error-diagnostics-snej9k4j.mjs";
8
+ import { n as followHostedLogs } from "./hosted-logs-sync-Dg3qrZmV.mjs";
9
9
  import { t as watchStdoutReader } from "./stdout-reader-C8yjre1x.mjs";
10
10
  import { realpathSync } from "node:fs";
11
11
  import { relative, sep } from "node:path";
12
12
  import { configDir } from "@stim-cli/core";
13
- import { buildCriteria, compileGrep, fileSizes, followLogs, gcLogDir, logFiles, parseSince, queryLogs, readGcLog, recordMatches, runId, sortByTs } from "@stim-cli/core/state";
13
+ import { buildCriteria, buildLedgerDir, compileGrep, fileSizes, followLogs, gcLogDir, logFiles, parseSince, queryLogs, readBuildLedger, readGcLog, recordMatches, runId, sortByTs } from "@stim-cli/core/state";
14
14
  import chalk from "chalk";
15
15
  //#region src/commands/logs.ts
16
+ const MACHINE_SOURCES = ["gc", "builds"];
16
17
  const LEVEL_WIDTH = 5;
17
18
  const SRC_WIDTH = 6;
18
19
  const INDENT = " ";
@@ -58,7 +59,8 @@ function validateSources(sources) {
58
59
  if (sources === void 0 || sources === null) return { sources: void 0 };
59
60
  const list = Array.isArray(sources) ? sources : [sources];
60
61
  if (list.includes("gc") && list.length > 1) return { error: "--source gc reads the machine-wide gc log and cannot be combined with other sources." };
61
- if (list.includes("all")) return { sources: SOURCES$1.filter((source) => source !== "gc") };
62
+ if (list.includes("builds") && list.length > 1) return { error: "--source builds reads the machine-wide build ledger and cannot be combined with other sources." };
63
+ if (list.includes("all")) return { sources: SOURCES$1.filter((source) => !MACHINE_SOURCES.includes(source)) };
62
64
  const unknown = list.filter((s) => !SOURCES$1.includes(s));
63
65
  if (unknown.length > 0) return { error: `Unknown --source value(s): ${unknown.join(", ")}. Use one or more of: ${SOURCES$1.join(", ")}, or all.` };
64
66
  return { sources: list };
@@ -69,7 +71,7 @@ function validateLevel(level) {
69
71
  }
70
72
  const ERRORS_PRINT_CAP = 20;
71
73
  function nearestRegisteredLogsProject(root, candidates) {
72
- return candidates.filter((candidate) => candidate !== root && isPathPrefix(root, candidate)).toSorted((a, b) => {
74
+ return candidates.filter((candidate) => candidate !== root && isPathPrefix$1(root, candidate)).toSorted((a, b) => {
73
75
  const depth = (path) => relative(root, path).split(sep).length;
74
76
  return depth(a) - depth(b) || a.length - b.length || a.localeCompare(b);
75
77
  })[0] ?? null;
@@ -98,11 +100,12 @@ const LEVEL_COLOURS = {
98
100
  fatal: chalk.bgRed
99
101
  };
100
102
  function logsCommand(program) {
101
- program.command("logs").description("Query this workspace's merged NDJSON log timeline (bundler, client, device, build, agent actions, maintenance). Prints and exits; an existing timeline with nothing matching is a successful, empty result. Use --follow to stream.").option("--slot <name>", "Only this device slot's records, plus the shared Metro and app client records once it has launched", parseDeviceSlotOption).option("--source <s...>", "Only these sources: metro, client, device, build, agent, maintenance, placement, or all; gc alone reads the machine-wide gc log of what gc and maintenance cleared").option("--level <l>", `Minimum level: ${LEVELS$1.join(", ")}`).option("--since <d>", "Only records newer than this, e.g. 30s, 5m, 2h").option("--grep <re>", "Only records whose message matches this regular expression").option("--tail <n>", "Only the last n matching records").option("--errors", "Errors and fatals since the last marker, from metro, client and build, plus confirmed native app-crash reports and stim web browser errors. Add --source maintenance for maintenance failures, or --source device or --source all for general device errors.").option("--follow", "Keep streaming new records until interrupted").option("--json", "Emit the raw records, one per line (valid NDJSON; zero matches is zero bytes, exit 0)").action(async (opts) => {
103
+ program.command("logs").description("Query this workspace's merged NDJSON log timeline (bundler, client, device, build, agent actions, maintenance). Prints and exits; an existing timeline with nothing matching is a successful, empty result. Use --follow to stream.").option("--slot <name>", "Only this device slot's records, plus the shared Metro and app client records once it has launched", parseDeviceSlotOption).option("--source <s...>", "Only these sources: metro, client, device, build, agent, maintenance, placement, or all; gc alone reads the machine-wide gc log of what gc and maintenance cleared, and builds alone reads the machine-wide ledger of native builds").option("--level <l>", `Minimum level: ${LEVELS$1.join(", ")}`).option("--since <d>", "Only records newer than this, e.g. 30s, 5m, 2h").option("--grep <re>", "Only records whose message matches this regular expression").option("--tail <n>", "Only the last n matching records").option("--errors", "Errors and fatals since the last marker, from metro, client and build, plus confirmed native app-crash reports and stim web browser errors. Add --source maintenance for maintenance failures, or --source device or --source all for general device errors.").option("--follow", "Keep streaming new records until interrupted").option("--json", "Emit the raw records, one per line (valid NDJSON; zero matches is zero bytes, exit 0)").action(async (opts) => {
102
104
  const requested = [opts.source ?? []].flat();
103
- if (requested.length === 1 && requested[0] === "gc") {
105
+ const [only] = requested;
106
+ if (requested.length === 1 && only !== void 0 && MACHINE_SOURCES.includes(only)) {
104
107
  const { minLevel, tail } = validateOptions(opts);
105
- printGcLog(opts, opts.errors ? "error" : minLevel, tail);
108
+ printMachineLog(only === "gc" ? GC_LOG : BUILD_LEDGER, opts, opts.errors ? "error" : minLevel, tail);
106
109
  return;
107
110
  }
108
111
  const root = findCommandWorkspace(process.cwd());
@@ -257,27 +260,49 @@ function validateOptions(opts) {
257
260
  tail
258
261
  };
259
262
  }
260
- function printGcLog(opts, minLevel, tail) {
261
- const emit = (record) => console.log(opts.json ? JSON.stringify(record) : formatRecord(record, { paint: record.level ? LEVEL_COLOURS[record.level] : void 0 }));
263
+ const GC_LOG = {
264
+ source: "gc",
265
+ dir: gcLogDir,
266
+ read: readGcLog
267
+ };
268
+ const BUILD_LEDGER = {
269
+ source: "builds",
270
+ dir: buildLedgerDir,
271
+ read: readBuildLedger,
272
+ key: (record) => `${record.id}:${record.ts}`
273
+ };
274
+ function printMachineLog(log, opts, minLevel, tail) {
275
+ const printed = /* @__PURE__ */ new Set();
276
+ const emit = (record) => {
277
+ if (opts.follow && log.key) {
278
+ const key = log.key(record);
279
+ if (printed.has(key)) return;
280
+ printed.add(key);
281
+ }
282
+ console.log(opts.json ? JSON.stringify(record) : formatRecord(record, { paint: record.level ? LEVEL_COLOURS[record.level] : void 0 }));
283
+ };
262
284
  const query = {
263
- sources: ["gc"],
285
+ sources: [log.source],
264
286
  minLevel,
265
287
  since: opts.since,
266
288
  grep: opts.grep
267
289
  };
268
- const offsets = opts.follow ? fileSizes(gcLogDir()) : null;
290
+ const dir = log.dir();
291
+ const offsets = opts.follow ? fileSizes(dir) : null;
292
+ const all = log.read();
269
293
  const records = queryLogs({
270
294
  ...query,
271
- records: readGcLog(),
295
+ records: all,
272
296
  tail
273
297
  });
274
298
  for (const record of records) emit(record);
299
+ if (opts.follow && log.key) for (const record of all) printed.add(log.key(record));
275
300
  if (!opts.follow) {
276
- if (records.length === 0 && !opts.json) console.error(chalk.dim(`No matching log records in ${gcLogDir()}`));
301
+ if (records.length === 0 && !opts.json) console.error(chalk.dim(`No matching log records in ${dir}`));
277
302
  return;
278
303
  }
279
304
  const stop = followLogs({
280
- dir: gcLogDir(),
305
+ dir,
281
306
  offsets,
282
307
  criteria: buildCriteria(query),
283
308
  onRecord: emit
@@ -1,2 +1,2 @@
1
- import { n as runMacos, r as waitForLaunchServices, t as macosCommand } from "./macos-DBBPNnIA.mjs";
1
+ import { n as runMacos, r as waitForLaunchServices, t as macosCommand } from "./macos-DlCBhMw5.mjs";
2
2
  export { macosCommand as default, runMacos, waitForLaunchServices };