stim 1.25.0 → 1.26.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 (158) hide show
  1. package/README.md +1 -1
  2. package/dist/{acquire-artifact-zA4S7RHE.mjs → acquire-artifact-DVsvSwf7.mjs} +1 -1
  3. package/dist/{act-BbHS3oV8.mjs → act-C-BqJEpu.mjs} +157 -35
  4. package/dist/{activity-BpjwrQXU.mjs → activity-Lnb_EoRY.mjs} +4 -5
  5. package/dist/{agent-device-usage-output-Bnkerfod.mjs → agent-device-usage-output-DbXy5tg8.mjs} +4 -4
  6. package/dist/{android-saBeB4lr.mjs → android-B5P81yI-.mjs} +1 -1
  7. package/dist/{android-CNZgRC-4.mjs → android-CSbLRD53.mjs} +5 -5
  8. package/dist/{android-BGwuK3Mc.mjs → android-CiNQw3kq.mjs} +73 -49
  9. package/dist/{android-Cjcj8MCw.mjs → android-DTAcRwBC.mjs} +81 -34
  10. package/dist/{android-cas-BVqh2Zep.mjs → android-cas-BTVhZ0Qs.mjs} +4 -4
  11. package/dist/{android-project-CTYaETc0.d.mts → android-project-DUGMbq28.d.mts} +55 -1
  12. package/dist/api.d.mts +8 -5
  13. package/dist/api.mjs +27 -27
  14. package/dist/apk-signed-tail-B46U9hXc.mjs +142 -0
  15. package/dist/{artifact-Co8zixVx.mjs → artifact-BxREhAaV.mjs} +23 -18
  16. package/dist/{artifact-DN8JNwqS.mjs → artifact-CsAP6AGK.mjs} +35 -20
  17. package/dist/{attempt-DW-mQqM7.mjs → attempt-ClyJlZPT.mjs} +4 -2
  18. package/dist/{browser-web-CCgZsHmI.mjs → browser-web-rYPyqhTf.mjs} +11 -12
  19. package/dist/{budget-HyShrIpL.mjs → budget-k2mZGvvk.mjs} +196 -33
  20. package/dist/{build-CAiw8Ezm.mjs → build-DPhApsjV.mjs} +26 -23
  21. package/dist/{build-cache-CKCzxzxA.mjs → build-cache-DrXNCy3T.mjs} +103 -21
  22. package/dist/{build-plan-zCuHGlA8.mjs → build-plan-DrMMdayj.mjs} +5 -5
  23. package/dist/{cache-manifest-BPXRONJz.mjs → cache-manifest-BEZ9Bpl1.mjs} +1 -1
  24. package/dist/cache-manifest.mjs +1 -1
  25. package/dist/{ccache-h1FKhZeg.mjs → ccache-Bx5TbxwG.mjs} +6 -6
  26. package/dist/{cli-C4w607Pz.mjs → cli-BBKFGOFl.mjs} +19 -19
  27. package/dist/cli.mjs +1 -1
  28. package/dist/{client-BQsmyp_-.mjs → client-D9CaRks-.mjs} +36 -61
  29. package/dist/collector-run.mjs +4 -4
  30. package/dist/{command-output-BBvS1H6v.mjs → command-output-BF5AR2dL.mjs} +1 -1
  31. package/dist/{config-BZhXY15H.mjs → config-BktkY_zC.mjs} +321 -15
  32. package/dist/{launch-DscF1QfM.mjs → dependencies-Dw6wfQdv.mjs} +258 -255
  33. package/dist/{dependency-state-BwNCYG5Q.mjs → dependency-state-DFB41vfr.mjs} +1 -1
  34. package/dist/{dev-client-CHoXXZeg.mjs → dev-client-DXR_tPVY.mjs} +2 -2
  35. package/dist/{device-B9FqTBYW.mjs → device-BK-zwyd_.mjs} +13 -13
  36. package/dist/{device-F5-4z9ef.mjs → device-BcYeHSFu.mjs} +14 -14
  37. package/dist/{device-capacity-ZYaRALv5.mjs → device-capacity-DCSvUF0l.mjs} +10 -17
  38. package/dist/device-host-worker.mjs +11 -13
  39. package/dist/{device-ios-DkHBrmvH.mjs → device-ios-BLGfXQeK.mjs} +49 -17
  40. package/dist/{device-lease-run-ogEeJ62K.mjs → device-lease-run-BmvIl7bI.mjs} +4 -4
  41. package/dist/{device-pool-BIg8MU8l.mjs → device-pool-Dluix4H3.mjs} +3 -3
  42. package/dist/{doctor-k3P3PizH.mjs → doctor-Bhg1ii70.mjs} +14 -14
  43. package/dist/{doctor-A_Nr_fDe.mjs → doctor-Cp-BhzTS.mjs} +1 -1
  44. package/dist/{doctor-Bm8TVpGn.mjs → doctor-OnwP94ne.mjs} +72 -23
  45. package/dist/{doctor-fingerprint-zlujA1Gs.mjs → doctor-fingerprint-D3a04Mhu.mjs} +8 -2
  46. package/dist/doctor-fingerprint.mjs +1 -1
  47. package/dist/{doctor-watchman-BovI1y3-.mjs → doctor-watchman-BStK05nt.mjs} +4 -4
  48. package/dist/{eas-build-CyDKNTBP.mjs → eas-build-Dsj93iM9.mjs} +2 -2
  49. package/dist/{eas-fallback-gaZi-dJL.mjs → eas-fallback-FwkeqqGi.mjs} +10 -10
  50. package/dist/{eas-session-ledger-BMCA1gdO.mjs → eas-session-ledger-B5vygTiD.mjs} +5 -5
  51. package/dist/{error-diagnostics-B1Mj_-7h.mjs → error-diagnostics-BOOm9Db7.mjs} +8 -8
  52. package/dist/{gc-eaz403W6.mjs → gc-C_79zvz4.mjs} +2 -2
  53. package/dist/{gc-B9jcnmIk.mjs → gc-ldgr-hXU.mjs} +74 -43
  54. package/dist/{guide-DR0K0xW9.mjs → guide-D7K0X6KG.mjs} +272 -52
  55. package/dist/{hosted-android-Bvb2-ZxD.mjs → hosted-android-Bk54ej6n.mjs} +3 -3
  56. package/dist/{hosted-client-rsRqysJc.mjs → hosted-client-fHO8yqzc.mjs} +5 -5
  57. package/dist/{hosted-ios-RtVcJH3u.mjs → hosted-ios-D55QhYaD.mjs} +1 -1
  58. package/dist/{hosted-logs-CWKGYWNX.mjs → hosted-logs-BfbmDM4M.mjs} +17 -11
  59. package/dist/hosted-logs-sync-B0pvmOk-.mjs +195 -0
  60. package/dist/{hosted-macos-d0pv9Tth.mjs → hosted-macos-CPl0OZ9h.mjs} +5 -5
  61. package/dist/{hosted-native-BxTizGU2.mjs → hosted-native-CpDB3-PO.mjs} +6 -7
  62. package/dist/{idle-shutdown-BIyfl0Zj.mjs → idle-shutdown-FfxL1KdG.mjs} +22 -9
  63. package/dist/{ios-Dvt97HgQ.mjs → ios-B7-lToDu.mjs} +8 -8
  64. package/dist/{ios-BQzvJlzw.mjs → ios-WxpDJ5T1.mjs} +72 -5
  65. package/dist/{ios-device-CKSvk0bu.mjs → ios-device-CsyryvpT.mjs} +1 -1
  66. package/dist/{ios-BRVM8b0P.mjs → ios-ftxdQbJS.mjs} +74 -46
  67. package/dist/{ios-project-DCUDo06I.mjs → ios-project-Ty5pHl9O.mjs} +6 -6
  68. package/dist/{ios-state-CT9nV5SP.mjs → ios-state-Cw7-WQf2.mjs} +1 -1
  69. package/dist/{js-swap-Z9HbC4cj.mjs → js-swap-BMhXYVDS.mjs} +4 -4
  70. package/dist/{launch-D0lPvFFu.mjs → launch-DOp8RjDz.mjs} +31 -26
  71. package/dist/{logs-BsIRre8x.mjs → logs-dQDki6Tt.mjs} +9 -173
  72. package/dist/{logs-Crs9y34Z.mjs → logs-s1dRIG1E.mjs} +85 -36
  73. package/dist/{macos-CcUlJPMu.mjs → macos-B0VEV3Gf.mjs} +1 -1
  74. package/dist/{macos-D477nfzH.mjs → macos-DBBPNnIA.mjs} +18 -19
  75. package/dist/macos-run.mjs +1 -1
  76. package/dist/maintenance-run.mjs +28 -11
  77. package/dist/{metro-1pJgCX4U.mjs → metro-CjC10t6E.mjs} +2 -2
  78. package/dist/{metro-gateway-Bp9gJQAN.mjs → metro-gateway-B6_PgD0L.mjs} +2 -3
  79. package/dist/{named-ports-BVbn8SvC.mjs → named-ports-BG0j1X4g.mjs} +2 -2
  80. package/dist/{native-android-BvMizJn1.mjs → native-android-CL2NGiik.mjs} +17 -17
  81. package/dist/{native-gradle-artifact-inputs-BJscK4vN.mjs → native-gradle-artifact-inputs-btSUulme.mjs} +3 -3
  82. package/dist/{native-run-D5OJsGwA.mjs → native-run-BfIDFKLH.mjs} +2 -3
  83. package/dist/{native-runtime-B9w_Qyz3.mjs → native-runtime-Dq3RBcON.mjs} +6 -7
  84. package/dist/{native-xcode-inputs-Cv4l-obn.mjs → native-xcode-inputs-BW7H8JGu.mjs} +2 -2
  85. package/dist/{native-xcode-ios-DGrg90hE.mjs → native-xcode-ios-CBXJAxfC.mjs} +15 -16
  86. package/dist/offload-worker.d.mts +3 -1
  87. package/dist/offload-worker.mjs +31 -21
  88. package/dist/{ownership-jxxz-19m.mjs → ownership-BjYvMNX_.mjs} +2 -2
  89. package/dist/{phone-reverses-CYb7RRAx.mjs → phone-reverses-lmj6kcPm.mjs} +3 -3
  90. package/dist/{placement-log-DjOXJRIH.mjs → placement-log-DIFPQAXp.mjs} +1 -1
  91. package/dist/{plan-placement-BqKgKHCi.mjs → plan-placement-IiiSQhtz.mjs} +3 -3
  92. package/dist/{ports-DtS1Amb0.mjs → ports-C2_w1Z0Z.mjs} +3 -3
  93. package/dist/prebuild-gmouvmJZ.mjs +1247 -0
  94. package/dist/{project-BiC68mIp.mjs → project-BUu6Is4k.mjs} +15 -16
  95. package/dist/{react-native-android-DRYqoJc4.mjs → react-native-android-Cgg99REN.mjs} +47 -33
  96. package/dist/{react-native-build-CwZB-agu.mjs → react-native-build-oNwqF5Wb.mjs} +7 -7
  97. package/dist/{react-native-doctor-BCrytK7h.mjs → react-native-doctor-BhA3KUte.mjs} +49 -8
  98. package/dist/{react-native-ios-Cr1buNFo.mjs → react-native-ios-B-nf4rjN.mjs} +37 -23
  99. package/dist/{recordings-BaoQ0t-J.mjs → recordings-BldzVKq0.mjs} +1 -1
  100. package/dist/{reload-Beftw2X3.mjs → reload-C9OduiNc.mjs} +1 -1
  101. package/dist/{reload-FbSgMF8x.mjs → reload-CCR7KC_l.mjs} +14 -14
  102. package/dist/{remote-BuZj6AyU.mjs → remote-C8S7FlPF.mjs} +7 -7
  103. package/dist/{result-CR2vk2cj.mjs → result-7F5hEwQJ.mjs} +16 -16
  104. package/dist/{run-BtzE09Dl.mjs → run-BqB0v3pt.mjs} +1 -1
  105. package/dist/{selection-D5cxEl3t.mjs → selection-BNPBZ6T5.mjs} +155 -42
  106. package/dist/{server-bare-CH9X0RLn.mjs → server-bare-A75rDIdD.mjs} +1 -1
  107. package/dist/{server-command-CaBbDNU2.mjs → server-command-CssKFOD7.mjs} +4 -4
  108. package/dist/{server-expo-Ck8EIidM.mjs → server-expo-eQfOdydb.mjs} +2 -2
  109. package/dist/server-expo-wvcj5tiZ.mjs +2 -0
  110. package/dist/{settings-B5tCoq9N.mjs → settings-CosW5X-S.mjs} +1 -1
  111. package/dist/{settings-DzH9mGQZ.mjs → settings-OaGQF-ri.mjs} +1 -1
  112. package/dist/{settings-write-n0zwfohx.mjs → settings-write-QjYfSrjF.mjs} +5 -5
  113. package/dist/settings.schema.json +33 -6
  114. package/dist/{simslim-BjxszUAb.mjs → simslim-Bax1qcxu.mjs} +3 -2
  115. package/dist/{slot-launch-QeuJMlnJ.mjs → slot-launch-CYCEhfBY.mjs} +6 -6
  116. package/dist/{stage-D8xlRU2D.mjs → stage-jKQ7CP_B.mjs} +1 -1
  117. package/dist/{start-C1JLjkNw.mjs → start-C_wefNKB.mjs} +1 -1
  118. package/dist/{start-YMpNwLhh.mjs → start-_BdJ32cZ.mjs} +9 -10
  119. package/dist/{state-DMRNP7-4.mjs → state-C1i2nMOP.mjs} +2 -3
  120. package/dist/{state-DPaM3u5K.mjs → state-C4OdpOTF.mjs} +1 -2
  121. package/dist/{stats-CP7STzZw.mjs → stats-tEpEEH-u.mjs} +4 -4
  122. package/dist/{status-cNw6i0_t.mjs → status-B9M7x4CZ.mjs} +1 -1
  123. package/dist/{status-Fect2w9R.mjs → status-CRXz-Gtj.mjs} +1 -1
  124. package/dist/{status-CRLiJ-O_.mjs → status-DQrqodLj.mjs} +22 -23
  125. package/dist/{status-watch-Bc2J4TZn.mjs → status-watch-B5wDIH_o.mjs} +4 -4
  126. package/dist/status-worker.mjs +1 -1
  127. package/dist/{stim-desktop-DS0mzR8U.mjs → stim-desktop-6Dqp-gjX.mjs} +1 -1
  128. package/dist/{stop-Br7LKxBE.mjs → stop-CmdNhGlC.mjs} +2 -2
  129. package/dist/{stop-Db9Kh-UA.mjs → stop-DRqQVqDJ.mjs} +21 -19
  130. package/dist/{stop-COP6PQqw.mjs → stop-ySNQHXMG.mjs} +4 -5
  131. package/dist/supervisor-run.d.mts +1 -0
  132. package/dist/supervisor-run.mjs +14 -15
  133. package/dist/{support-Cxj9CmII.mjs → support-BGSCBoib.mjs} +4 -4
  134. package/dist/{support-qKcbgmI5.mjs → support-CVOCp0Ft.mjs} +9 -9
  135. package/dist/{swiftpm-artifact-inputs-iY9fsmOc.mjs → swiftpm-artifact-inputs-CfUzt_0Z.mjs} +1 -1
  136. package/dist/{swiftpm-macos-Bp_sn9P4.mjs → swiftpm-macos-x6HPpl_2.mjs} +9 -9
  137. package/dist/toolchain-DoavrvIA.mjs +2 -0
  138. package/dist/toolchain-J4J8MrAr.mjs +2107 -0
  139. package/dist/trigger-DzJu208Q.mjs +2 -0
  140. package/dist/{trigger-CBMe2YLH.mjs → trigger-KVaWWNyn.mjs} +1 -1
  141. package/dist/{warm-progress-BV3ZPmcY.mjs → warm-progress-DvhTX_eu.mjs} +3 -4
  142. package/dist/web-BFLueSh-.mjs +2 -0
  143. package/dist/{web-B4Yjyt1G.mjs → web-Bihbf7-u.mjs} +8 -9
  144. package/dist/web-run.mjs +4 -4
  145. package/dist/{workspace-state-CPSp3mav.mjs → workspace-state-pUg3_RRA.mjs} +45 -7
  146. package/dist/{workspaces-C9w4aeXF.mjs → workspaces-g2lhdBXF.mjs} +17 -17
  147. package/dist/{worktree-CclFIe1Z.mjs → worktree-BKuklFh_.mjs} +34 -31
  148. package/dist/{worktree-Ct9Gk3KL.mjs → worktree-Bm4cb-nU.mjs} +1 -1
  149. package/package.json +8 -8
  150. package/dist/created-devices-D2Aca-xu.mjs +0 -52
  151. package/dist/paths-DQtTgsBf.mjs +0 -42
  152. package/dist/prebuild-JUaqOLpc.mjs +0 -501
  153. package/dist/server-expo-C16Zf2k7.mjs +0 -2
  154. package/dist/toolchain-DB1aeqxO.mjs +0 -2
  155. package/dist/toolchain-VzLJzZ7O.mjs +0 -908
  156. package/dist/trigger-BLsHgAGR.mjs +0 -2
  157. package/dist/web-DS4UDWvf.mjs +0 -2
  158. package/dist/xcode-CiIIDnuD.mjs +0 -910
@@ -1,16 +1,17 @@
1
1
  import { D as ownership_claim_exports, S as process_identity_exports, l as WorkspaceProcessCleanupError, m as declareSpawnsOn, o as cancellableSleep, t as getExecutor, v as stopDeclaringSpawnsOn } from "./exec-VFRpu1iA.mjs";
2
- import { C as saveConfig, D as withConfigLock$1, G as projectDeviceSlots, H as deviceSlotPlatforms, K as removeSlotDevice, O as withConfigLockAsync$1, _ as loadConfig$1, c as ensureConfig, d as getConfigDir, f as getConfigPath$1, z as assignSlotDevice } from "./config-BZhXY15H.mjs";
2
+ import { M as withDirLock$1, N as withDirLockAsync$1 } from "./workspace-state-pUg3_RRA.mjs";
3
+ import { C as saveConfig, D as withConfigLock$1, G as projectDeviceSlots, H as deviceSlotPlatforms, K as removeSlotDevice, O as withConfigLockAsync$1, _ as loadConfig$1, c as ensureConfig, d as getConfigDir, f as getConfigPath$1, z as assignSlotDevice } from "./config-BktkY_zC.mjs";
3
4
  import { n as runOperationFileQuiet, t as runOperationFile } from "./operation-exec-CUZifp6Z.mjs";
4
- import { c as androidDataPartitionSizeBytes } from "./settings-B5tCoq9N.mjs";
5
- import { i as stimDesktopInstalledAsync, n as settingDefault, t as STIM_DESKTOP_OPEN_OPTIONS } from "./stim-desktop-DS0mzR8U.mjs";
6
- import { a as recordCreatedDeviceAsync, n as forgetCreatedDeviceAsync, r as readCreatedDevices$1 } from "./created-devices-D2Aca-xu.mjs";
7
- import { c as pidExists, p as signalProcessTreeAsync } from "./metro-1pJgCX4U.mjs";
5
+ import { c as androidDataPartitionSizeBytes } from "./settings-CosW5X-S.mjs";
6
+ import { i as stimDesktopInstalledAsync, n as settingDefault, t as STIM_DESKTOP_OPEN_OPTIONS } from "./stim-desktop-6Dqp-gjX.mjs";
7
+ import { c as pidExists, p as signalProcessTreeAsync } from "./metro-CjC10t6E.mjs";
8
+ import { renameSync, rmSync, writeFileSync } from "node:fs";
8
9
  import { isDeepStrictEqual } from "node:util";
9
10
  import { join } from "node:path";
10
- import { ambientEnv, ambientWrite } from "@stim-cli/core";
11
- import { ANDROID_EMULATOR_APPS, getParkedMax, isJsonObject, loadConfig, settingDefinition } from "@stim-cli/core/state";
11
+ import { ambientEnv, ambientWrite, ensurePrivateDir } from "@stim-cli/core";
12
+ import { ANDROID_EMULATOR_APPS, createdDevicesFile, createdDevicesLock, getParkedMax, isJsonObject, loadConfig, readCreatedDevices, readCreatedDevices as readCreatedDevices$1, settingDefinition } from "@stim-cli/core/state";
12
13
  import { dirname as dirname$1, isAbsolute as isAbsolute$1, join as join$1, resolve as resolve$1 } from "path";
13
- import { existsSync, lstatSync, mkdirSync, openSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, writeFileSync } from "fs";
14
+ import { existsSync as existsSync$1, lstatSync as lstatSync$1, mkdirSync as mkdirSync$1, openSync as openSync$1, readFileSync as readFileSync$1, readdirSync as readdirSync$1, realpathSync as realpathSync$1, renameSync as renameSync$1, rmSync as rmSync$1, statSync as statSync$1, writeFileSync as writeFileSync$1 } from "fs";
14
15
  import { rm } from "node:fs/promises";
15
16
  import { homedir, tmpdir } from "os";
16
17
  //#region src/devices/android-emulator-viewer.ts
@@ -34,6 +35,52 @@ async function openEmulatorInStimDesktop(serial) {
34
35
  ], STIM_DESKTOP_OPEN_OPTIONS);
35
36
  }
36
37
  //#endregion
38
+ //#region src/devices/created-devices.ts
39
+ function update(platform, change) {
40
+ const dir = getConfigDir();
41
+ withDirLock$1(createdDevicesLock(), () => {
42
+ const current = readCreatedDevices();
43
+ const entries = new Set(current[platform]);
44
+ if (!change(entries)) return;
45
+ const next = {
46
+ version: 1,
47
+ ios: [...current.ios],
48
+ android: [...current.android],
49
+ web: [...current.web],
50
+ [platform]: [...entries]
51
+ };
52
+ const file = createdDevicesFile();
53
+ const tmp = `${file}.${process.pid}.${Math.random().toString(36).slice(2)}.tmp`;
54
+ writeFileSync(tmp, `${JSON.stringify(next, null, 2)}\n`, { mode: 384 });
55
+ try {
56
+ renameSync(tmp, file);
57
+ } catch (error) {
58
+ rmSync(tmp, { force: true });
59
+ throw error;
60
+ }
61
+ }, { ensureParent: () => ensurePrivateDir(dir) });
62
+ }
63
+ function recordCreatedDevice(platform, id) {
64
+ update(platform, (entries) => entries.size !== entries.add(id).size);
65
+ }
66
+ function forgetCreatedDevice(platform, id) {
67
+ update(platform, (entries) => entries.delete(id));
68
+ }
69
+ /** Waits asynchronously for the ledger lock, then records the device. */
70
+ function recordCreatedDeviceAsync(platform, id) {
71
+ return withDirLockAsync$1(createdDevicesLock(), () => recordCreatedDevice(platform, id), { ensureParent: () => ensurePrivateDir(getConfigDir()) });
72
+ }
73
+ /** Waits asynchronously for the ledger lock, then atomically forgets the device. The synchronous transaction decides whether to commit the removal; cancellation stops admission. */
74
+ function forgetCreatedDeviceAsync(platform, id, signal, transaction = (forget) => {
75
+ forget();
76
+ return true;
77
+ }) {
78
+ return withDirLockAsync$1(createdDevicesLock(), () => transaction(() => forgetCreatedDevice(platform, id)), {
79
+ ensureParent: () => ensurePrivateDir(getConfigDir()),
80
+ signal
81
+ });
82
+ }
83
+ //#endregion
37
84
  //#region src/devices/sim-pool.ts
38
85
  const POOL_SETTING_REMEDY = "Run `stim guide settings` for the device pool bounds and where it can be set.";
39
86
  function parkedMaxSetting(platform, options = {}) {
@@ -307,7 +354,7 @@ function androidToolPath(tool, platform = process.platform, env = ambientEnv())
307
354
  const bare = location.at(-1);
308
355
  const name = platform === "win32" ? `${bare}${WINDOWS_SDK_TOOL_EXTENSIONS[tool]}` : bare;
309
356
  const abs = join$1(androidHome(env), ...location.slice(0, -1), name);
310
- return existsSync(abs) ? abs : bare;
357
+ return existsSync$1(abs) ? abs : bare;
311
358
  }
312
359
  const WINDOWS_BUILD_TOOL_EXTENSIONS = { apksigner: ".bat" };
313
360
  function androidBuildToolName(tool, platform = process.platform) {
@@ -329,7 +376,7 @@ function buildToolsMajor(version) {
329
376
  const major = Number(String(version ?? "").split(/[.-]/)[0]);
330
377
  return Number.isFinite(major) ? major : 0;
331
378
  }
332
- function findBuildTool(tools, { home = androidHome(), readDir = readdirSync, exists = existsSync, platform = process.platform } = {}) {
379
+ function findBuildTool(tools, { home = androidHome(), readDir = readdirSync$1, exists = existsSync$1, platform = process.platform } = {}) {
333
380
  const root = join$1(home, "build-tools");
334
381
  let versions = [];
335
382
  try {
@@ -358,7 +405,7 @@ function listInstalledSystemImages(onUnreadable, env = ambientEnv()) {
358
405
  const images = [];
359
406
  const list = (dir) => {
360
407
  try {
361
- return readdirSync(dir);
408
+ return readdirSync$1(dir);
362
409
  } catch (error) {
363
410
  const code = error.code;
364
411
  if (code !== "ENOENT" && code !== "ENOTDIR") onUnreadable?.(error);
@@ -397,7 +444,7 @@ function profileNeedsFoldFeature(profile) {
397
444
  }
398
445
  function systemImageSupportsFold(pkg, home = androidHome()) {
399
446
  try {
400
- const ini = readFileSync(join$1(home, ...pkg.split(";"), "advancedFeatures.ini"), "utf8");
447
+ const ini = readFileSync$1(join$1(home, ...pkg.split(";"), "advancedFeatures.ini"), "utf8");
401
448
  return /^\s*SupportPixelFold\s*=\s*on\s*$/im.test(ini);
402
449
  } catch {
403
450
  return false;
@@ -425,7 +472,7 @@ async function createOwnedAvd(label, { systemImage, deviceProfile = DEFAULT_AVD_
425
472
  let env = ambientEnv();
426
473
  if (!env.ANDROID_AVD_HOME) {
427
474
  const root = avdLookupRoots(env, (process.platform === "win32" ? env.USERPROFILE : env.HOME) || homedir())[0];
428
- mkdirSync(root, { recursive: true });
475
+ mkdirSync$1(root, { recursive: true });
429
476
  env = {
430
477
  ...env,
431
478
  ANDROID_AVD_HOME: root
@@ -479,7 +526,7 @@ function avdIniValue(configIni, key) {
479
526
  }
480
527
  return null;
481
528
  }
482
- function ownedAvdSystemImage(avdName, { avdDirectory = ownedAvdDirectory, readFile = (path) => readFileSync(path, "utf8") } = {}) {
529
+ function ownedAvdSystemImage(avdName, { avdDirectory = ownedAvdDirectory, readFile = (path) => readFileSync$1(path, "utf8") } = {}) {
483
530
  const directory = avdDirectory(avdName);
484
531
  if (!directory) return null;
485
532
  try {
@@ -516,7 +563,7 @@ function sanitizeAvdLabel(label) {
516
563
  function avdConfigIni(avdName, directory = ownedAvdDirectory(avdName)) {
517
564
  if (!directory) return null;
518
565
  try {
519
- return readFileSync(join$1(directory, "config.ini"), "utf8");
566
+ return readFileSync$1(join$1(directory, "config.ini"), "utf8");
520
567
  } catch {
521
568
  return null;
522
569
  }
@@ -779,7 +826,7 @@ function avdStorageRoots(env = ambientEnv()) {
779
826
  }
780
827
  function avdPathExists(path) {
781
828
  try {
782
- lstatSync(path);
829
+ lstatSync$1(path);
783
830
  return true;
784
831
  } catch (error) {
785
832
  if (error.code === "ENOENT") return false;
@@ -797,7 +844,7 @@ function avdNameAbsent(avdName, roots = avdStorageRoots()) {
797
844
  }
798
845
  function isDirectoryPath(path) {
799
846
  try {
800
- return statSync(path).isDirectory();
847
+ return statSync$1(path).isDirectory();
801
848
  } catch (error) {
802
849
  if (error.code === "ENOENT") return false;
803
850
  throw error;
@@ -807,17 +854,17 @@ function listOrphanedAvdDirectories(avdName) {
807
854
  const roots = avdStorageRoots();
808
855
  const stores = roots.filter(avdPathExists).map((root) => ({
809
856
  root,
810
- canonicalRoot: realpathSync(root),
811
- names: readdirSync(root)
857
+ canonicalRoot: realpathSync$1(root),
858
+ names: readdirSync$1(root)
812
859
  }));
813
860
  const registered = /* @__PURE__ */ new Set();
814
861
  for (const { root, canonicalRoot, names } of stores) for (const name of names.filter((entry) => entry.endsWith(".ini"))) {
815
862
  const path = join$1(root, name);
816
- const ini = readFileSync(path, "utf8");
863
+ const ini = readFileSync$1(path, "utf8");
817
864
  const targets = /* @__PURE__ */ new Set([...avdIniPaths(root, ini), ...avdIniPaths(canonicalRoot, ini)]);
818
865
  if (!targets.size) throw new Error(`Cannot verify AVD registration at ${path}; its data was kept.`);
819
866
  for (const target of targets) try {
820
- registered.add(realpathSync(target));
867
+ registered.add(realpathSync$1(target));
821
868
  } catch (error) {
822
869
  const code = error.code;
823
870
  if (code !== "ENOENT" && code !== "ENOTDIR") throw error;
@@ -832,8 +879,8 @@ function listOrphanedAvdDirectories(avdName) {
832
879
  if (roots.some((candidate) => avdPathExists(join$1(candidate, `${name}.ini`)))) continue;
833
880
  const directory = join$1(canonicalRoot, entry);
834
881
  if (registered.has(directory) || !avdPathExists(directory)) continue;
835
- const stat = lstatSync(directory);
836
- if (!stat.isDirectory() || stat.isSymbolicLink() || realpathSync(directory) !== directory) throw new Error(`Cannot verify AVD data at ${directory}; it was kept.`);
882
+ const stat = lstatSync$1(directory);
883
+ if (!stat.isDirectory() || stat.isSymbolicLink() || realpathSync$1(directory) !== directory) throw new Error(`Cannot verify AVD data at ${directory}; it was kept.`);
837
884
  if (!orphaned.some((candidate) => candidate.directory === directory)) orphaned.push({
838
885
  name,
839
886
  directory,
@@ -852,7 +899,7 @@ function avdLookupRoots(env, home) {
852
899
  ];
853
900
  return [...new Set(roots.filter((value) => Boolean(value)))];
854
901
  }
855
- function ownedAvdDirectory(avdName, { env = ambientEnv(), home = (process.platform === "win32" ? env.USERPROFILE : env.HOME) || homedir(), readFile = (path) => readFileSync(path, "utf8"), realpath = realpathSync, isDirectory = (path) => statSync(path).isDirectory() } = {}) {
902
+ function ownedAvdDirectory(avdName, { env = ambientEnv(), home = (process.platform === "win32" ? env.USERPROFILE : env.HOME) || homedir(), readFile = (path) => readFileSync$1(path, "utf8"), realpath = realpathSync$1, isDirectory = (path) => statSync$1(path).isDirectory() } = {}) {
856
903
  if (!/^stim-[A-Za-z0-9._-]+$/.test(avdName)) return null;
857
904
  for (const root of avdLookupRoots(env, home)) {
858
905
  let ini;
@@ -910,10 +957,10 @@ function withAvdConfigOverrides(contents, overrides) {
910
957
  return updated.join(newline) + (trailingNewline ? newline : "");
911
958
  }
912
959
  let avdConfigWriteSequence = 0;
913
- function configureNewOwnedAvd(avdName, { dataPartitionSizeGb, avdConfig = {} }, { avdDirectory = ownedAvdDirectory, readFile = (path) => readFileSync(path, "utf8"), writeFile = (path, contents) => writeFileSync(path, contents, {
960
+ function configureNewOwnedAvd(avdName, { dataPartitionSizeGb, avdConfig = {} }, { avdDirectory = ownedAvdDirectory, readFile = (path) => readFileSync$1(path, "utf8"), writeFile = (path, contents) => writeFileSync$1(path, contents, {
914
961
  encoding: "utf8",
915
962
  flag: "wx"
916
- }), rename = renameSync, remove = (path) => rmSync(path, { force: true }) } = {}) {
963
+ }), rename = renameSync$1, remove = (path) => rmSync$1(path, { force: true }) } = {}) {
917
964
  const sizeBytes = androidDataPartitionSizeBytes(dataPartitionSizeGb);
918
965
  const directory = avdDirectory(avdName);
919
966
  if (!directory) throw new Error(`Could not resolve the content directory for newly created AVD ${avdName}.`);
@@ -953,7 +1000,7 @@ function avdPoolConfiguration(dataPartitionSizeGb, avdConfig, deviceProfile = DE
953
1000
  function ownedAvdMatchesConfiguration(avdName, configuration) {
954
1001
  const directory = ownedAvdDirectory(avdName);
955
1002
  if (!directory) return false;
956
- const contents = readFileSync(join$1(directory, "config.ini"), "utf8");
1003
+ const contents = readFileSync$1(join$1(directory, "config.ini"), "utf8");
957
1004
  const expected = JSON.parse(configuration);
958
1005
  return Array.isArray(expected) && expected.length > 0 && expected.every((entry) => Array.isArray(entry) && entry.length === 2 && entry.every((value) => typeof value === "string") && contents.split(/\r?\n/).some((line) => line.trim() === `${entry[0]}=${entry[1]}`));
959
1006
  }
@@ -1068,7 +1115,7 @@ const CRASH_REPORT_MODE_EMULATOR_VERSION = 37;
1068
1115
  function emulatorCrashDatabases(env = ambientEnv()) {
1069
1116
  const root = join$1(env.TMP || env.TEMP || tmpdir(), "AndroidEmulator");
1070
1117
  try {
1071
- return readdirSync(root).filter((name) => /^emu-crash-.*\.db$/.test(name)).map((name) => join$1(root, name));
1118
+ return readdirSync$1(root).filter((name) => /^emu-crash-.*\.db$/.test(name)).map((name) => join$1(root, name));
1072
1119
  } catch {
1073
1120
  return [];
1074
1121
  }
@@ -1082,7 +1129,7 @@ function emulatorCrashDatabases(env = ambientEnv()) {
1082
1129
  * removed instead, which has the same effect unless a crash handler is still writing into it.
1083
1130
  * https://github.com/appandflow/stim/issues/918
1084
1131
  */
1085
- function suppressEmulatorCrashConsent({ platform = process.platform, version = emulatorMajorVersion, databases = emulatorCrashDatabases, remove = (path) => rmSync(path, {
1132
+ function suppressEmulatorCrashConsent({ platform = process.platform, version = emulatorMajorVersion, databases = emulatorCrashDatabases, remove = (path) => rmSync$1(path, {
1086
1133
  recursive: true,
1087
1134
  force: true
1088
1135
  }) } = {}) {
@@ -1120,8 +1167,8 @@ async function bootAndroidEmulator(avdName, consolePort, { logFile, platform = p
1120
1167
  function emulatorStdio(logFile) {
1121
1168
  if (!logFile) return "ignore";
1122
1169
  try {
1123
- mkdirSync(dirname$1(logFile), { recursive: true });
1124
- const fd = openSync(logFile, "w");
1170
+ mkdirSync$1(dirname$1(logFile), { recursive: true });
1171
+ const fd = openSync$1(logFile, "w");
1125
1172
  return [
1126
1173
  "ignore",
1127
1174
  fd,
@@ -1329,7 +1376,7 @@ function avdProcessLockPaths(avdDirectory, platform) {
1329
1376
  }
1330
1377
  function readAvdProcessId(path) {
1331
1378
  try {
1332
- const pid = Number(readFileSync(path, "utf8").split("\0")[0]);
1379
+ const pid = Number(readFileSync$1(path, "utf8").split("\0")[0]);
1333
1380
  if (!Number.isSafeInteger(pid) || pid <= 0) throw new Error(`Could not read the emulator PID from process lock ${path}.`);
1334
1381
  return pid;
1335
1382
  } catch (error) {
@@ -1459,7 +1506,7 @@ const EMULATOR_SIGNAL_GRACE_MS = 5e3;
1459
1506
  async function waitForAndroidEmulatorShutdown(avdName, shutdown, { operation, timeoutMs = ANDROID_EMULATOR_SHUTDOWN_TIMEOUT_MS, pollMs = ANDROID_EMULATOR_SHUTDOWN_POLL_MS, signalGraceMs = EMULATOR_SIGNAL_GRACE_MS, platform = process.platform, resolveDirectory = ownedAvdDirectory, readProcessId = readAvdProcessId, processAlive = pidExists, listProcesses = (name, host) => listAvdEmulatorProcessesAsync(name, host, operation), captureIdentity = process_identity_exports.captureProcessIdentity, inspectIdentity = process_identity_exports.inspectProcessIdentity, signal = (pid, name) => signalProcessTreeAsync(pid, name, {
1460
1507
  platform,
1461
1508
  operation
1462
- }), directoryExists = (path) => statSync(path).isDirectory(), crashHandlerPids = (pid) => emulatorCrashHandlerPids(pid, operation), killCrashHandler = (pid) => signalProcessTreeAsync(pid, "SIGKILL", {
1509
+ }), directoryExists = (path) => statSync$1(path).isDirectory(), crashHandlerPids = (pid) => emulatorCrashHandlerPids(pid, operation), killCrashHandler = (pid) => signalProcessTreeAsync(pid, "SIGKILL", {
1463
1510
  platform,
1464
1511
  operation
1465
1512
  }), now = Date.now, sleep = (ms) => cancellableSleep(ms, {
@@ -1725,4 +1772,4 @@ function ownedAvdSerialResolver({ timeoutMs } = {}) {
1725
1772
  };
1726
1773
  }
1727
1774
  //#endregion
1728
- export { removeMetroReverses as $, listAdbDevices as A, ownedAvdDeviceProfile as B, emulatorDiskSpaceRemedy as C, getAvdNameForSerial as D, findBuildTool as E, listAvdsAsync as F, ownedAvdSerialResolverAsync as G, ownedAvdMatchesConfiguration as H, listInstalledSystemImages as I, parseAvdSystemImage as J, ownedAvdSystemImage as K, listOrphanedAvdDirectories as L, listAvdDeviceProfiles as M, listAvdDeviceProfilesAsync as N, getAvdNameForSerialAsync as O, listAvds as P, profileNeedsFoldFeature as Q, memoizeEmulatorProbe as R, deleteAvd as S, configuredAndroidEmulatorApp as St, extractEmulatorFailure as T, ownedAvdName as U, ownedAvdDirectory as V, ownedAvdSerialResolver as W, pickDefaultSystemImage as X, physicalDeviceModel as Y, probeEmulatorSerial as Z, avdPoolConfiguration as _, parkSim as _t, androidDeviceAbi as a, systemImageSupportsFold as at, configureNewOwnedAvd as b, removeParkedAfter as bt, androidPoolNoCandidatesRefusal as c, waitForBoot as ct, androidToolPath as d, isStimOwnedSim as dt, removeOwnedEmulatorMetroReverses as et, assertOwnedAvdStopped as f, POOL_SETTING_REMEDY as ft, avdPathExists as g, isLegacyDeletionClaim as gt, avdNameAbsent as h, eraseParkedAfter as ht, androidDataFreeBytes as i, shutdownAndroidEmulator as it, listAdbDevicesAsync as j, hostSystemImageArch as k, androidSystemImageAbi as l, wipeAvdUserData as lt, avdIniPaths as m, dropParked as mt, OWNED_AVD_CONFIG_DEFAULTS as n, resolveOwnedAvdSerialAsync as nt, androidHome as o, trimAndroidCaches as ot, assertOwnedAvdStoppedAsync as p, adoptParked as pt, parseAvdDeviceProfile as q, androidBuildToolName as r, resolvePhysicalDevice as rt, androidPoolCandidates as s, waitForAndroidEmulatorShutdown as st, DEFAULT_AVD_DEVICE_PROFILE as t, resetAdoptedAvd as tt, androidToolCwd as u, isStimOwnedAvd as ut, avdStorageRoots as v, parkedMaxSetting as vt, emulatorFailureRemedy as w, createOwnedAvd as x, selectParked as xt, bootAndroidEmulator as y, readParked as yt, nextConsolePort as z };
1775
+ export { removeMetroReverses as $, listAdbDevices as A, ownedAvdDeviceProfile as B, emulatorDiskSpaceRemedy as C, forgetCreatedDeviceAsync as Ct, getAvdNameForSerial as D, configuredAndroidEmulatorApp as Dt, findBuildTool as E, recordCreatedDeviceAsync as Et, listAvdsAsync as F, ownedAvdSerialResolverAsync as G, ownedAvdMatchesConfiguration as H, listInstalledSystemImages as I, parseAvdSystemImage as J, ownedAvdSystemImage as K, listOrphanedAvdDirectories as L, listAvdDeviceProfiles as M, listAvdDeviceProfilesAsync as N, getAvdNameForSerialAsync as O, listAvds as P, profileNeedsFoldFeature as Q, memoizeEmulatorProbe as R, deleteAvd as S, forgetCreatedDevice as St, extractEmulatorFailure as T, recordCreatedDevice as Tt, ownedAvdName as U, ownedAvdDirectory as V, ownedAvdSerialResolver as W, pickDefaultSystemImage as X, physicalDeviceModel as Y, probeEmulatorSerial as Z, avdPoolConfiguration as _, parkSim as _t, androidDeviceAbi as a, systemImageSupportsFold as at, configureNewOwnedAvd as b, removeParkedAfter as bt, androidPoolNoCandidatesRefusal as c, waitForBoot as ct, androidToolPath as d, isStimOwnedSim as dt, removeOwnedEmulatorMetroReverses as et, assertOwnedAvdStopped as f, POOL_SETTING_REMEDY as ft, avdPathExists as g, isLegacyDeletionClaim as gt, avdNameAbsent as h, eraseParkedAfter as ht, androidDataFreeBytes as i, shutdownAndroidEmulator as it, listAdbDevicesAsync as j, hostSystemImageArch as k, androidSystemImageAbi as l, wipeAvdUserData as lt, avdIniPaths as m, dropParked as mt, OWNED_AVD_CONFIG_DEFAULTS as n, resolveOwnedAvdSerialAsync as nt, androidHome as o, trimAndroidCaches as ot, assertOwnedAvdStoppedAsync as p, adoptParked as pt, parseAvdDeviceProfile as q, androidBuildToolName as r, resolvePhysicalDevice as rt, androidPoolCandidates as s, waitForAndroidEmulatorShutdown as st, DEFAULT_AVD_DEVICE_PROFILE as t, resetAdoptedAvd as tt, androidToolCwd as u, isStimOwnedAvd as ut, avdStorageRoots as v, parkedMaxSetting as vt, emulatorFailureRemedy as w, readCreatedDevices$1 as wt, createOwnedAvd as x, selectParked as xt, bootAndroidEmulator as y, readParked as yt, nextConsolePort as z };
@@ -1,7 +1,7 @@
1
- import { n as ensureWorkspaceStorage, v as withDirLock$1 } from "./paths-DQtTgsBf.mjs";
2
- import { d as getConfigDir } from "./config-BZhXY15H.mjs";
3
- import { m as defaultAndroidLayout } from "./settings-B5tCoq9N.mjs";
4
- import { r as register } from "./cache-manifest-BPXRONJz.mjs";
1
+ import { M as withDirLock$1, _ as ensureWorkspaceStorage } from "./workspace-state-pUg3_RRA.mjs";
2
+ import { d as getConfigDir } from "./config-BktkY_zC.mjs";
3
+ import { m as defaultAndroidLayout } from "./settings-CosW5X-S.mjs";
4
+ import { r as register } from "./cache-manifest-BEZ9Bpl1.mjs";
5
5
  import { createHash, randomUUID } from "node:crypto";
6
6
  import { accessSync, constants, existsSync, mkdirSync, readFileSync, realpathSync, renameSync, statSync, writeFileSync } from "node:fs";
7
7
  import { join } from "node:path";
@@ -8,7 +8,7 @@ import { readFileSync as readFileSync$1 } from "fs";
8
8
  import { Command } from "commander";
9
9
  import "@expo/fingerprint";
10
10
  import { CacheProviderConfig, loadCacheProvider } from "@stim-cli/cache";
11
- import { BuildReactNativeArtifactQuery, BuildSwiftpmArtifactQuery, GradleOffloadInputs, HelloResult } from "@stim-cli/core/protocol";
11
+ import { BuildReactNativeArtifactQuery, BuildSwiftpmArtifactQuery, GradleOffloadInputs, HelloResult, RemoteDiagnosis } from "@stim-cli/core/protocol";
12
12
  import { ChildProcess } from "node:child_process";
13
13
  //#region src/engine/build-facts.d.ts
14
14
  type CacheHitLevel = "local" | "remote" | false;
@@ -230,6 +230,14 @@ interface IosToolchain {
230
230
  simulatorSdk: string | null;
231
231
  cocoapods: string | null;
232
232
  }
233
+ /** An Xcode app in `/Applications`, with the license and first-launch checks of its developer directory when they ran. */
234
+ interface XcodeApp {
235
+ path: string;
236
+ version: string | null;
237
+ build: string | null;
238
+ license?: boolean;
239
+ firstLaunch?: boolean;
240
+ }
233
241
  /** A remote machine's toolchain, the simulator runtimes it can build for, and its JDK and Android SDK packages. */
234
242
  interface WorkerToolchain extends Omit<IosToolchain, "compat"> {
235
243
  /** Absent from a stim-server older than build compatibility versions. */
@@ -239,17 +247,53 @@ interface WorkerToolchain extends Omit<IosToolchain, "compat"> {
239
247
  macosSdk: string | null;
240
248
  bundler: string | null;
241
249
  runtimes: string[];
250
+ /** The developer directory `xcode-select -p` prints, null when it prints none; absent from a stim-server older than this field. */
251
+ developerDir?: string | null;
252
+ /** The Xcode apps in `/Applications`; their license and first-launch checks run only while `xcode` is null. */
253
+ xcodeApps?: XcodeApp[];
242
254
  jdk: string | null;
255
+ /** The majors of every JDK found on the machine, `jdk` included; absent from a stim-server older than this field. */
256
+ jdks?: string[];
243
257
  androidSdk: {
244
258
  ndk: string[];
245
259
  buildTools: string[];
246
260
  platforms: string[];
247
261
  } | null;
262
+ /** Whether that SDK has its licenses accepted, so Gradle can download a missing package; absent from a stim-server older than this field. */
263
+ androidLicenses?: boolean;
264
+ /** The SDK directory `androidSdk` was read from, for the commands that install into it; absent from a stim-server older than this field. */
265
+ androidHome?: string;
248
266
  }
249
267
  /** One reason a remote machine cannot take this build now, with a stable `code` for doctor's JSON. */
250
268
  interface OffloadProblem {
251
269
  code: "unreachable" | "checkout" | "stim-build" | "arch" | "xcode" | "macos-sdk" | "simulator-sdk" | "cocoapods" | "bundler" | "runtime" | "jdk" | "android-sdk" | "ndk" | "build-tools" | "compile-sdk" | "disk" | "busy" | "platform";
252
270
  reason: string;
271
+ /** Shell commands that clear it, to run on the remote machine, and what they do, as the end of "On <machine>, ...". */
272
+ commands?: string[];
273
+ lead?: string;
274
+ /** The problem whose fix also clears this one, so it carries no fix of its own. */
275
+ followsFrom?: OffloadProblem["code"];
276
+ }
277
+ //#endregion
278
+ //#region src/offload/diagnosis.d.ts
279
+ type Transport = {
280
+ kind: "http";
281
+ status: number;
282
+ } | {
283
+ kind: "refused";
284
+ } | {
285
+ kind: "silent";
286
+ } | {
287
+ kind: "tls";
288
+ message: string;
289
+ } | {
290
+ kind: "other";
291
+ message: string;
292
+ };
293
+ /** What a peer's `/health` says about a server that answered 503 (see `peerHealth` in stim-server). */
294
+ interface PeerStartup {
295
+ state: "pending" | "degraded";
296
+ cause?: "home-unreadable" | "start-failed";
253
297
  }
254
298
  //#endregion
255
299
  //#region src/offload/tailnet.d.ts
@@ -291,11 +335,18 @@ type HelloReply = {
291
335
  };
292
336
  } | {
293
337
  failed: string;
338
+ transport?: Transport;
294
339
  };
295
340
  interface TailnetMachineIo {
296
341
  /** `tailscale status --json`, or null when Tailscale is not running. */
297
342
  status: () => unknown;
298
343
  hello: (endpoint: Endpoint, auth: MachineAuth) => Promise<HelloReply>;
344
+ /** `tailscale status --json` whatever its backend state, or null when no command answered; says why `status` is null. */
345
+ rawStatus?: () => unknown;
346
+ /** The `startup` of the peer's `/health` after a 503, or null when it says none. */
347
+ startup?: (endpoint: Endpoint) => Promise<PeerStartup | null>;
348
+ /** Whether `tailscale ping` gets an answer from the peer's address. */
349
+ ping?: (address: string) => Promise<boolean>;
299
350
  }
300
351
  type GeneratedTickets = Map<string, {
301
352
  ticket: string;
@@ -311,6 +362,7 @@ type GeneratedTickets = Map<string, {
311
362
  interface BuildMachineReport {
312
363
  machine: string;
313
364
  state: "invalid" | "tailscale-off" | "not-on-tailnet" | "key-changed" | "not-asked" | "pending" | "approved" | "revoked" | "lapsed" | "outdated" | "unreachable";
365
+ diagnosis?: RemoteDiagnosis;
314
366
  dnsName?: string;
315
367
  deviceId?: string;
316
368
  requestedAt?: string;
@@ -321,6 +373,8 @@ interface BuildMachineReport {
321
373
  reasons?: string[];
322
374
  /** The same reasons with the code of each, in the same order. */
323
375
  problems?: OffloadProblem[];
376
+ /** What a build there does beyond the match, such as downloading an SDK package; none of it stops the build. */
377
+ notes?: OffloadProblem[];
324
378
  /** The machine's reported capacity, when it answered an offer. */
325
379
  capacity?: Record<string, unknown>;
326
380
  }
package/dist/api.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { _ as IosFacts, a as BuildMachinesInspection, d as DoctorPlatform, f as Finding, g as CompilationCacheActivity, h as CcacheActivity, m as AndroidFacts, n as WebLaunched, o as GeneratedTickets, s as TailnetMachineIo, u as BudgetReport } from "./android-project-CTYaETc0.mjs";
1
+ import { _ as IosFacts, a as BuildMachinesInspection, d as DoctorPlatform, f as Finding, g as CompilationCacheActivity, h as CcacheActivity, m as AndroidFacts, n as WebLaunched, o as GeneratedTickets, s as TailnetMachineIo, u as BudgetReport } from "./android-project-DUGMbq28.mjs";
2
2
  import { a as WorkspaceLaunchPlatform } from "./ios-CDvlmUs7.mjs";
3
3
  import "./exec-DnYc4HGH.mjs";
4
4
  import "./pull-request-eODyIqZF.mjs";
@@ -8,7 +8,7 @@ import { AgentDeviceUsage, ArchivedWorkspace, BuildPlanPayload, MacosBuild, Maco
8
8
  import { statSync } from "fs";
9
9
  import { Command } from "commander";
10
10
  import { ToolchainEntry } from "@stim-cli/core/toolchain";
11
- import { HelloResult, PlatformBuildOptions, PlatformRunOptions } from "@stim-cli/core/protocol";
11
+ import { HelloResult, PlatformBuildOptions, PlatformRunOptions, RemoteDiagnosis } from "@stim-cli/core/protocol";
12
12
  //#region src/engine/device-lease.d.ts
13
13
  type LeasePlatform = "ios" | "android";
14
14
  interface ReleasedLease {
@@ -19,7 +19,7 @@ interface ReleasedLease {
19
19
  }
20
20
  //#endregion
21
21
  //#region src/commands/gc/results.d.ts
22
- type GcResultKind = "archive" | "device" | "parkedDevice" | "parkedHostedDevice" | "idleDevice" | "deviceRecord" | "workspaceOutputs" | "recording" | "workspaceDirectory" | "project" | "buildLock" | "buildSlot" | "deviceLease" | "easSession" | "worktree" | "cache" | "statusCache" | "tempLeftover" | "trash" | "watchmanRoot" | "watchman" | "gradleDaemon" | "gradleVersion" | "kotlinDaemon";
22
+ type GcResultKind = "archive" | "device" | "parkedDevice" | "parkedHostedDevice" | "idleDevice" | "deviceRecord" | "workspaceOutputs" | "recording" | "workspaceDirectory" | "project" | "buildLock" | "buildSlot" | "deviceLease" | "easSession" | "worktree" | "cache" | "statusCache" | "tempLeftover" | "trash" | "watchmanRoot" | "watchman" | "gradleDaemon" | "gradleVersion" | "kotlinDaemon" | "devServer" | "workspaceLogs" | "ledgerEntry" | "easLedgerEntry";
23
23
  type GcResultStatus = "done" | "kept" | "failed";
24
24
  interface GcResult {
25
25
  kind: GcResultKind;
@@ -214,6 +214,7 @@ interface StimVersionReport {
214
214
  interface MachineReport {
215
215
  machine: string;
216
216
  state: "invalid" | "tailscale-off" | "not-on-tailnet" | "key-changed" | "not-asked" | "pending" | "approved" | "revoked" | "lapsed" | "outdated" | "unreachable" | "credentials-unavailable" | "busy";
217
+ diagnosis?: RemoteDiagnosis;
217
218
  dnsName?: string;
218
219
  deviceId?: string;
219
220
  requestedAt?: string;
@@ -779,6 +780,8 @@ interface RunGcOptions {
779
780
  delete?: boolean;
780
781
  worktrees?: boolean;
781
782
  json?: boolean;
783
+ /** False reports worktree build-state sizes only from the disk-usage cache: a stale one is unmeasured (null), and no `du` runs for it. */
784
+ measureBuildState?: boolean;
782
785
  }
783
786
  interface GcRefusal {
784
787
  code: string;
@@ -801,7 +804,7 @@ type GcPayload = {
801
804
  results: GcResult[];
802
805
  inventory: GcInventory | null;
803
806
  } | GcRefusal;
804
- type GcReadOptions = Pick<RunGcOptions, "olderThan" | "cache" | "worktrees">;
807
+ type GcReadOptions = Pick<RunGcOptions, "olderThan" | "cache" | "worktrees" | "measureBuildState">;
805
808
  //#endregion
806
809
  //#region src/commands/reload.d.ts
807
810
  type ReloadPlatform = WorkspaceLaunchPlatform | "web";
@@ -951,7 +954,7 @@ type StimGcOptions = GcReadOptions & StimReadOptions;
951
954
  type StimGcReport = Exclude<GcPayload, {
952
955
  code: string;
953
956
  }>;
954
- type StimGcMutationOptions = StimGcOptions & {
957
+ type StimGcMutationOptions = Omit<StimGcOptions, "measureBuildState"> & {
955
958
  delete?: boolean;
956
959
  /** Shuts down owned devices idle for at least this many milliseconds, including without `delete`. */
957
960
  idleMs?: number;
package/dist/api.mjs CHANGED
@@ -1,31 +1,30 @@
1
1
  import { D as ownership_claim_exports, T as trackReportResource, b as operationState, c as throwIfCancelled, l as WorkspaceProcessCleanupError, s as cancelledError, w as runReport } from "./exec-VFRpu1iA.mjs";
2
- import { d as workspaceDir, m as workspaceLogsDir$1, r as ensureWorkspaceStorageAsync } from "./paths-DQtTgsBf.mjs";
3
- import { E as upsertProject, O as withConfigLockAsync$1, p as getProject, q as validateDeviceSlot, y as refuseRelativeStimPaths } from "./config-BZhXY15H.mjs";
4
- import { l as phaseLine } from "./command-output-BBvS1H6v.mjs";
5
- import { a as recordWorkspaceUseAsync } from "./workspace-state-CPSp3mav.mjs";
6
- import { Pt as repoRootAsync, Y as resolveProjectSettingsAsync, a as SETTING_SHAPE_REMEDY, at as unknownSettingKeys, p as cacheProviderSettingError, tt as settingShapeErrors } from "./settings-B5tCoq9N.mjs";
7
- import { c as projectProblem, f as projectRegistry, i as findProjectRoot$1, r as findCommandWorkspaceAsync, t as NO_PROJECT_REFUSAL } from "./project-BiC68mIp.mjs";
8
- import { n as macosDir } from "./state-DPaM3u5K.mjs";
9
- import { c as ensureHomeIdentity, s as workspaceShareURL } from "./stim-desktop-DS0mzR8U.mjs";
2
+ import { E as workspaceDir, a as recordWorkspaceUseAsync, k as workspaceLogsDir$1, v as ensureWorkspaceStorageAsync } from "./workspace-state-pUg3_RRA.mjs";
3
+ import { E as upsertProject, O as withConfigLockAsync$1, p as getProject, q as validateDeviceSlot, y as refuseRelativeStimPaths } from "./config-BktkY_zC.mjs";
4
+ import { l as phaseLine } from "./command-output-BF5AR2dL.mjs";
5
+ import { Pt as repoRootAsync, Y as resolveProjectSettingsAsync, a as SETTING_SHAPE_REMEDY, at as unknownSettingKeys, p as cacheProviderSettingError, tt as settingShapeErrors } from "./settings-CosW5X-S.mjs";
6
+ import { c as projectProblem, f as projectRegistry, i as findProjectRoot$1, r as findCommandWorkspaceAsync, t as NO_PROJECT_REFUSAL } from "./project-BUu6Is4k.mjs";
7
+ import { n as macosDir } from "./state-C4OdpOTF.mjs";
8
+ import { c as ensureHomeIdentity, s as workspaceShareURL } from "./stim-desktop-6Dqp-gjX.mjs";
10
9
  import { r as createNdjsonWriter } from "./ndjson-CgE_o3Dl.mjs";
11
- import { B as recordFinishedBuild, H as startBuildProgress, U as tapBuildLog } from "./budget-HyShrIpL.mjs";
12
- import { d as runCancellationSignal, f as withNativeBuildRun } from "./native-run-D5OJsGwA.mjs";
13
- import { c as resolveBuildPlacement } from "./selection-D5cxEl3t.mjs";
14
- import { c as stopWorkspaceNow } from "./stop-Db9Kh-UA.mjs";
15
- import { r as runReload } from "./reload-FbSgMF8x.mjs";
16
- import { c as startDevServer } from "./start-YMpNwLhh.mjs";
17
- import { s as recordDoctorCheck } from "./doctor-watchman-BovI1y3-.mjs";
18
- import { a as readDoctorReport } from "./doctor-k3P3PizH.mjs";
19
- import { h as warmWorktreeTarget, m as removeWorktreeTarget } from "./worktree-CclFIe1Z.mjs";
20
- import { i as readGcReport, n as executeGc, o as withGcMaintenanceClaim } from "./gc-B9jcnmIk.mjs";
21
- import { r as readWorkspaceLogs, t as followWorkspaceLogs } from "./logs-BsIRre8x.mjs";
10
+ import { K as startBuildProgress, W as recordFinishedBuild, q as tapBuildLog } from "./budget-k2mZGvvk.mjs";
11
+ import { d as runCancellationSignal, f as withNativeBuildRun } from "./native-run-BfIDFKLH.mjs";
12
+ import { l as resolveBuildPlacement } from "./selection-BNPBZ6T5.mjs";
13
+ import { c as stopWorkspaceNow } from "./stop-DRqQVqDJ.mjs";
14
+ import { r as runReload } from "./reload-CCR7KC_l.mjs";
15
+ import { c as startDevServer } from "./start-_BdJ32cZ.mjs";
16
+ import { s as recordDoctorCheck } from "./doctor-watchman-BStK05nt.mjs";
17
+ import { a as readDoctorReport } from "./doctor-Bhg1ii70.mjs";
18
+ import { h as warmWorktreeTarget, m as removeWorktreeTarget } from "./worktree-BKuklFh_.mjs";
19
+ import { i as readGcReport, n as executeGc, o as withGcMaintenanceClaim } from "./gc-ldgr-hXU.mjs";
20
+ import { r as readWorkspaceLogs, t as followWorkspaceLogs } from "./logs-dQDki6Tt.mjs";
22
21
  import { t as readProjectStats } from "./stats-report-n2U5plhk.mjs";
23
- import { n as buildAndroidOperation, t as buildIosOperation } from "./build-CAiw8Ezm.mjs";
24
- import { a as readAndroidBuildPlan, i as runAndroidOperation } from "./android-BGwuK3Mc.mjs";
25
- import { i as readIosBuildPlan, r as runIosOperation } from "./ios-BRVM8b0P.mjs";
26
- import { a as buildMacosBundle, i as planMacos, n as runMacos } from "./macos-D477nfzH.mjs";
27
- import { t as runWeb } from "./web-B4Yjyt1G.mjs";
28
- import { i as SettingsRefusal, o as readSettingsContext, s as readSettingsPayload, t as mutateSetting } from "./settings-write-n0zwfohx.mjs";
22
+ import { n as buildAndroidOperation, t as buildIosOperation } from "./build-DPhApsjV.mjs";
23
+ import { a as readAndroidBuildPlan, i as runAndroidOperation } from "./android-CiNQw3kq.mjs";
24
+ import { i as readIosBuildPlan, r as runIosOperation } from "./ios-ftxdQbJS.mjs";
25
+ import { a as buildMacosBundle, i as planMacos, n as runMacos } from "./macos-DBBPNnIA.mjs";
26
+ import { t as runWeb } from "./web-Bihbf7-u.mjs";
27
+ import { i as SettingsRefusal, o as readSettingsContext, s as readSettingsPayload, t as mutateSetting } from "./settings-write-QjYfSrjF.mjs";
29
28
  import { randomBytes } from "node:crypto";
30
29
  import { mkdirSync, mkdtempSync, readFileSync, realpathSync, rmSync } from "node:fs";
31
30
  import { stripVTControlCharacters } from "node:util";
@@ -317,7 +316,7 @@ function createStim(options) {
317
316
  }), () => {});
318
317
  return task;
319
318
  }),
320
- gc: ({ signal, olderThan, cache, worktrees } = {}) => {
319
+ gc: ({ signal, olderThan, cache, worktrees, measureBuildState } = {}) => {
321
320
  if (olderThan !== void 0 && !Number.isSafeInteger(olderThan)) return Promise.reject(new StimError({
322
321
  code: "STIM_BAD_ARG",
323
322
  message: "olderThan must be a whole number of days."
@@ -326,7 +325,8 @@ function createStim(options) {
326
325
  const result = await readGcReport({
327
326
  olderThan,
328
327
  cache,
329
- worktrees
328
+ worktrees,
329
+ measureBuildState
330
330
  }, {
331
331
  operation: context,
332
332
  easLedgerRoot: join(context.env.HOME || context.env.USERPROFILE || homedir(), ".stim", "machine", "eas")