stim 1.19.0 → 1.20.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 (172) hide show
  1. package/README.md +20 -3
  2. package/dist/{activity-BSw0x84R.mjs → activity-BrGh9EAI.mjs} +3 -3
  3. package/dist/{agent-device-usage-output-Bjxu_VmX.mjs → agent-device-usage-output-DVyv_hWj.mjs} +7 -7
  4. package/dist/android-0vv-OruW.mjs +6 -0
  5. package/dist/android-Brx6EKvJ.mjs +1258 -0
  6. package/dist/{android-BdQC6zs1.mjs → android-BsYNR81W.mjs} +103 -45
  7. package/dist/{android-DE5g_5gv.mjs → android-CK3fpEyZ.mjs} +2 -2
  8. package/dist/{android-cas-C87geAg-.mjs → android-cas-DCAuXryb.mjs} +9 -5
  9. package/dist/android-cas-compiler.mjs +1 -1
  10. package/dist/api-run.mjs +159 -8
  11. package/dist/{api-DIf_s86s.mjs → api-zuX3ynYN.mjs} +5 -1
  12. package/dist/api.d.mts +98 -4
  13. package/dist/api.mjs +1 -1
  14. package/dist/{app-install-CFI4ptUL.mjs → app-install-0LgaQRT7.mjs} +9 -8
  15. package/dist/artifact-CnC0mfov.mjs +807 -0
  16. package/dist/artifact-DClXJNWx.mjs +772 -0
  17. package/dist/artifact-lifecycle-DzPpBYvK.mjs +30 -0
  18. package/dist/{browser-web-CDhqQxhv.mjs → browser-web-CzBmhmgs.mjs} +19 -19
  19. package/dist/{budget-Dz-kyXLv.mjs → budget-BONq9vXY.mjs} +3101 -3062
  20. package/dist/build-BixRI6sB.mjs +462 -0
  21. package/dist/{build-facts-B87vo-Im.d.mts → build-facts-DcLv2HSd.d.mts} +1 -32
  22. package/dist/build-plan-CP0tckNU.mjs +553 -0
  23. package/dist/{cache-manifest-DiwKSyv9.mjs → cache-manifest-qA3dT2x2.mjs} +1 -1
  24. package/dist/cache-manifest.mjs +1 -1
  25. package/dist/{manifest-CX0d1IkZ.mjs → ccache-CjHQ5F8g.mjs} +13 -19
  26. package/dist/{chrome-BTUOo8p2.mjs → chrome-Dp2lMLBe.mjs} +1 -1
  27. package/dist/{cli-C9Zvgbdc.mjs → cli-B2R8wH1F.mjs} +20 -20
  28. package/dist/cli.mjs +1 -1
  29. package/dist/{client-CuUo8Nvg.mjs → client-BLy1Pw2V.mjs} +89 -307
  30. package/dist/collector-run.d.mts +4 -0
  31. package/dist/collector-run.mjs +7 -7
  32. package/dist/{command-output-Bt8ygHE7.mjs → command-output-BjPN99ZB.mjs} +2 -2
  33. package/dist/{config-DC5jEtd1.mjs → config-D0LhTY3S.mjs} +8 -12
  34. package/dist/{created-devices-D0s26Hx5.mjs → created-devices-HU_DAb_Q.mjs} +7 -6
  35. package/dist/{dependency-state-DKaS1OM9.mjs → dependency-state-B2m8eqsS.mjs} +2 -2
  36. package/dist/{detached-entry-pB_IPfV4.mjs → detached-entry-BXq4fIl-.mjs} +1 -1
  37. package/dist/{dev-client-CDY_zAmD.mjs → dev-client-ClATaJoH.mjs} +2 -2
  38. package/dist/{device-BHw0WlHl.mjs → device-B7lsC0K1.mjs} +8 -8
  39. package/dist/device-DVCwAFlX.mjs +727 -0
  40. package/dist/{device-capacity-BoN1jQkO.mjs → device-capacity-Ca_ke1LE.mjs} +13 -14
  41. package/dist/device-host-worker.mjs +38 -18
  42. package/dist/device-ios-CRUqPxKw.mjs +413 -0
  43. package/dist/{device-lease-Cu7PtQpZ.mjs → device-lease-DHOBXGgS.mjs} +135 -22
  44. package/dist/{device-lease-run-D38SnZtt.mjs → device-lease-run-CvDeHTkG.mjs} +4 -4
  45. package/dist/{device-pool-CP4rAsHx.mjs → device-pool-L2-5GxMy.mjs} +3 -3
  46. package/dist/{device-remote-B5GiUifk.mjs → device-remote-Bmg42063.mjs} +17 -68
  47. package/dist/doctor-C2MSuMMg.mjs +515 -0
  48. package/dist/{doctor-PRJH94v6.mjs → doctor-DPAqhVCK.mjs} +333 -744
  49. package/dist/{doctor-watchman-wZhyTdp4.mjs → doctor-watchman-CB4NnVZm.mjs} +13 -12
  50. package/dist/{simslim-D9LkJxIO.mjs → eas-build-Dw_ec2Km.mjs} +6 -152
  51. package/dist/{stim-installations-DbmUjsLv.mjs → eas-session-ledger-DZlC-Fq3.mjs} +57 -4
  52. package/dist/{error-diagnostics--v5HGOU0.mjs → error-diagnostics-Du7I_GuY.mjs} +17 -12
  53. package/dist/errors-DzkMYh8Q.mjs +205 -0
  54. package/dist/{exec-i8GDPwq9.mjs → exec-B81Qodjn.mjs} +40 -10
  55. package/dist/{gc-CyHMcKcn.mjs → gc-PWp34zGb.mjs} +21 -20
  56. package/dist/{device-ios-B2ruohE-.mjs → gradle-C2OEKCCI.mjs} +21 -650
  57. package/dist/{guide-dRaQJJk9.mjs → guide-Dai9lphv.mjs} +504 -117
  58. package/dist/{hosted-android-Bs7fytj7.mjs → hosted-android-DQ-Agsd8.mjs} +5 -5
  59. package/dist/{hosted-client-C5G4h_OJ.mjs → hosted-client-Io01s5By.mjs} +9 -3
  60. package/dist/{hosted-ios-Bik035eL.mjs → hosted-ios-DIxFnYp-.mjs} +3 -3
  61. package/dist/{hosted-logs-CI9Az9a4.mjs → hosted-logs-DP-ABU_M.mjs} +8 -8
  62. package/dist/{hosted-macos-DABm3ScO.mjs → hosted-macos-Aziw9T_9.mjs} +7 -6
  63. package/dist/{hosted-native-DbV2aUVw.mjs → hosted-native-BdAQi21M.mjs} +17 -14
  64. package/dist/{idle-shutdown-DYiMBn34.mjs → idle-shutdown-DdMqoSUB.mjs} +7 -7
  65. package/dist/{ios-DYUr9LGc.mjs → ios-BZ9dg2Fr.mjs} +8 -7
  66. package/dist/{ios-BWbHFZVz.mjs → ios-CXLIUxXJ.mjs} +180 -24
  67. package/dist/ios-CZuv6gRv.mjs +1112 -0
  68. package/dist/{ios-DCrkgXEM.mjs → ios-VGvNdsv2.mjs} +1 -1
  69. package/dist/{ios-device-CrW8aMb5.mjs → ios-device-B1B14xND.mjs} +1 -1
  70. package/dist/{ios-device-CJ_ZOGky.mjs → ios-device-BreZOpM0.mjs} +3 -3
  71. package/dist/ios-project-B9drt_aY.mjs +197 -0
  72. package/dist/{ios-state-By0XuLTQ.mjs → ios-state-CjrL2qv-.mjs} +1 -1
  73. package/dist/js-swap-C8icNYIY.mjs +432 -0
  74. package/dist/launch-DxH0THLP.mjs +745 -0
  75. package/dist/{react-native-ios-CSpIxexZ.mjs → launch-YrbqaIFj.mjs} +59 -612
  76. package/dist/{launch-verify-DCveSE6d.mjs → launch-verify-BzRdbuO1.mjs} +26 -7
  77. package/dist/{logs-Bao1HOMy.mjs → logs-DHaRNfg7.mjs} +11 -11
  78. package/dist/macos-C0iljhsN.mjs +2 -0
  79. package/dist/{macos-ciyBdTY5.mjs → macos-V_3Ui7g4.mjs} +42 -50
  80. package/dist/macos-run.mjs +1 -1
  81. package/dist/maintenance-run.mjs +13 -10
  82. package/dist/{metro-DI2AjPF_.mjs → metro-D_j9sN-B.mjs} +18 -5
  83. package/dist/{metro-gateway-BxpJLIwh.mjs → metro-gateway-BBJldOdi.mjs} +2 -2
  84. package/dist/miss-reason-BPAzZS0r.mjs +238 -0
  85. package/dist/{named-ports-B4iWH4E-.mjs → named-ports-C2lvoPsb.mjs} +3 -3
  86. package/dist/native-android-lHzaew7r.mjs +226 -0
  87. package/dist/native-gradle-inputs-BQnIdAlL.mjs +356 -0
  88. package/dist/{native-runtime-BGxsbfny.mjs → native-runtime-BRmWL7ru.mjs} +9 -8
  89. package/dist/native-xcode-inputs-eutS19jU.mjs +307 -0
  90. package/dist/native-xcode-ios-DP3cHLwu.mjs +434 -0
  91. package/dist/{ndjson-LGZAMsqa.mjs → ndjson-GOnbyvso.mjs} +6 -6
  92. package/dist/offload-worker.d.mts +41 -7
  93. package/dist/offload-worker.mjs +409 -74
  94. package/dist/{ownership-EB0ySdGK.mjs → ownership-DXzMMSx6.mjs} +2 -2
  95. package/dist/{placement-log-Dxe34rJm.mjs → placement-log-reFbjqEr.mjs} +1 -1
  96. package/dist/plan-BDk2AeY_.mjs +260 -0
  97. package/dist/plan-placement-D_YYlE6N.mjs +73 -0
  98. package/dist/{ports-ByPc0_97.mjs → ports-jzvAJXXL.mjs} +3 -3
  99. package/dist/{prebuild-BKJ3wJI1.mjs → prebuild-Bw44QxVh.mjs} +4 -4
  100. package/dist/{preview-BbSottmO.mjs → preview-BaBJ72Al.mjs} +50 -32
  101. package/dist/project-B8_duAzW.mjs +1067 -0
  102. package/dist/project-plan-BPwbLwQu.mjs +10 -0
  103. package/dist/{pull-request-IHNdMnG8.mjs → pull-request-vOhLNmIb.mjs} +1 -1
  104. package/dist/pull-requests.mjs +1 -1
  105. package/dist/react-native-android-chm1DMlA.mjs +921 -0
  106. package/dist/react-native-build-oAw6gQeW.mjs +239 -0
  107. package/dist/react-native-doctor-DYXoh-6I.mjs +78 -0
  108. package/dist/react-native-ios-SCTK_CT5.mjs +595 -0
  109. package/dist/{recordings-Bv8McZN4.mjs → recordings-Bk-VivUV.mjs} +1 -1
  110. package/dist/{reload-rAPdqeRR.mjs → reload-D34GkY78.mjs} +17 -13
  111. package/dist/remote-BU9UyhCJ.mjs +192 -0
  112. package/dist/{remote-cache-N3hAEaAL.mjs → remote-cache-Bsts6f6Y.mjs} +5 -5
  113. package/dist/result-BDoRk1k3.mjs +186 -0
  114. package/dist/{run-lAkle1-c.mjs → run-qvff78hv.mjs} +3 -3
  115. package/dist/{server-bare-CkIjnegq.mjs → server-bare-dWjAarki.mjs} +5 -5
  116. package/dist/server-command-7XIKlWtO.mjs +69 -0
  117. package/dist/{server-expo-n3tUi3Em.mjs → server-expo-CsYu2aKL.mjs} +107 -82
  118. package/dist/server-expo-DV43vep4.mjs +2 -0
  119. package/dist/{settings-CxgngUZk.mjs → settings-Bbztm4oV.mjs} +179 -129
  120. package/dist/{settings-2am7TSxp.mjs → settings-CT3E71-i.mjs} +6 -6
  121. package/dist/{state-lKh8shBp.d.mts → settings-vk3mJGSm.d.mts} +4 -2
  122. package/dist/settings.schema.json +84 -0
  123. package/dist/simslim-ChMfe8rg.mjs +149 -0
  124. package/dist/{slot-launch-HV_KtPIw.mjs → slot-launch-B9hn96wd.mjs} +6 -6
  125. package/dist/{stage-BgaZJVZY.mjs → stage-BNKKdDNc.mjs} +6 -3
  126. package/dist/start-CbQCSnXQ.mjs +2 -0
  127. package/dist/{start-DtxthMfI.mjs → start-CdvcTaXr.mjs} +97 -68
  128. package/dist/{state-Tp4uImDS.mjs → state-Boo0IMJq.mjs} +1 -1
  129. package/dist/{state-D2KtnALG.mjs → state-DI84A-uu.mjs} +29 -10
  130. package/dist/{stats-8EJ5ivFT.mjs → stats-BIIDrjA8.mjs} +5 -5
  131. package/dist/{status-BEeL6IKz.mjs → status-BDGHwkCs.mjs} +3 -1
  132. package/dist/{status-BOyp0CUl.mjs → status-DARMkc9q.mjs} +81 -293
  133. package/dist/status-watch-DvmI3SmN.mjs +296 -0
  134. package/dist/{stim-desktop-C65jk_q2.mjs → stim-desktop-8GQX2OV8.mjs} +1 -1
  135. package/dist/{stop-DRipAg-e.mjs → stop-CCZS-C9m.mjs} +2 -2
  136. package/dist/{stop-D0UIpZuh.mjs → stop-WQPQHLuy.mjs} +5 -5
  137. package/dist/{stop-zDlknFoz.mjs → stop-iNemHsJC.mjs} +21 -20
  138. package/dist/supervisor-run.d.mts +7 -2
  139. package/dist/supervisor-run.mjs +32 -20
  140. package/dist/{support-DsNaFg6D.mjs → support-CnE_SIjt.mjs} +17 -7
  141. package/dist/{support-CNqYkV0y.mjs → support-DCco5fut.mjs} +61 -8
  142. package/dist/{swiftpm-macos-aJzPAj1t.mjs → swiftpm-macos-afeNUExW.mjs} +5 -5
  143. package/dist/tailnet-CoJUb2tB.mjs +265 -0
  144. package/dist/toolchain-BIupIro1.mjs +2 -0
  145. package/dist/{toolchain-C3xSoyUl.mjs → toolchain-DqyDXs30.mjs} +206 -53
  146. package/dist/{trigger-CAhmG-4s.mjs → trigger-C0MWBi8O.mjs} +2 -2
  147. package/dist/trigger-SHLOWJ4O.mjs +2 -0
  148. package/dist/{warm-progress-pFLB2e6P.mjs → warm-progress-C3ASD6z5.mjs} +6 -6
  149. package/dist/{watchman-BL1IdOtq.mjs → watchman-CQl51YZu.mjs} +6 -6
  150. package/dist/{web-DbbrPUn0.mjs → web-B3eldHFH.mjs} +9 -13
  151. package/dist/web-BLXpOe6b.mjs +2 -0
  152. package/dist/web-run.mjs +10 -10
  153. package/dist/{workspace-state-CR9X86xJ.mjs → workspace-state-CSIFuuDa.mjs} +33 -33
  154. package/dist/{workspaces-Djb2gfi9.mjs → workspaces-D2xSHBDY.mjs} +1260 -1258
  155. package/dist/{worktree-BL4M1rhB.mjs → worktree-BxDqaTev.mjs} +84 -48
  156. package/dist/worktree-q7_OZNY0.mjs +2 -0
  157. package/package.json +8 -6
  158. package/shim/native-android.gradle +101 -0
  159. package/dist/android-BXc6BmEi.mjs +0 -3732
  160. package/dist/android-BvV1gGdN.mjs +0 -4
  161. package/dist/ios-ITYno9rO.mjs +0 -2241
  162. package/dist/macos-nIOATJmR.mjs +0 -2
  163. package/dist/metro-store-BAHFcJm6.mjs +0 -106
  164. package/dist/miss-reason-CjQCOKqq.mjs +0 -1743
  165. package/dist/plan-placement-BVY59qa8.mjs +0 -290
  166. package/dist/project-B5eQ1USs.mjs +0 -612
  167. package/dist/react-native-ios-BMh2i25I.mjs +0 -2
  168. package/dist/server-expo-DGsdUGX2.mjs +0 -2
  169. package/dist/start-D8NbxNBb.mjs +0 -2
  170. package/dist/trigger-CoalsMTV.mjs +0 -2
  171. package/dist/web-DFpFeZu5.mjs +0 -2
  172. package/dist/worktree-DV-A0LNL.mjs +0 -2
@@ -0,0 +1,260 @@
1
+ import { p as getProject, z as deviceSlotPlatforms } from "./config-D0LhTY3S.mjs";
2
+ import { B as remoteAndroidSetting, F as parseIosRemote, Q as settingShapeErrors, U as resolveAndroidLayout, W as resolveCacheProviderConfig, Y as settingFile, Z as settingOriginScope, a as SETTING_SHAPE_REMEDY, d as androidLayoutSetting, et as settingsLayers, f as androidLayoutSettingError, nt as unknownSettingKeys, p as cacheProviderSettingError, s as androidAvdConfigSettingError, u as androidDataPartitionSizeGbSettingError } from "./settings-Bbztm4oV.mjs";
3
+ import { _ as detectIsExpo } from "./project-B8_duAzW.mjs";
4
+ import { B as ownedAvdSystemImage, F as ownedAvdDeviceProfile, K as profileNeedsFoldFeature, Q as systemImageSupportsFold, W as pickDefaultSystemImage, dt as parkedMaxSetting, j as listInstalledSystemImages, k as listAvdDeviceProfiles, t as DEFAULT_AVD_DEVICE_PROFILE } from "./android-BsYNR81W.mjs";
5
+ import { d as optimizationBuildProfile, l as artifactCachePolicy, p as resolveOptimizations, u as compilerCacheFallbackMessage } from "./errors-DzkMYh8Q.mjs";
6
+ import { r as isPhysicalDeviceRequest } from "./native-runtime-BRmWL7ru.mjs";
7
+ import { t as DEFAULT_DEVICE_SLOT_WAIT_MS } from "./device-capacity-Ca_ke1LE.mjs";
8
+ import { C as remoteAvdFlagRefusal, D as systemImageRefusal, E as resolveVariant, T as resolveSystemImage, m as deviceProfileRefusal, v as foldableImageRefusal, w as resolveDeviceProfile, y as isReleaseVariant } from "./support-CnE_SIjt.mjs";
9
+ import { c as readProductFlavors, s as productFlavorRefusal } from "./react-native-build-oAw6gQeW.mjs";
10
+ import { n as resolveAndroidCas, r as resolveAndroidCompilerCache } from "./android-cas-DCAuXryb.mjs";
11
+ import { l as parseDeviceWait } from "./device-lease-run-CvDeHTkG.mjs";
12
+ //#region src/integrations/android-project.ts
13
+ var AndroidRecipeRefusal = class extends Error {
14
+ failure;
15
+ missReason;
16
+ constructor(failure, missReason) {
17
+ super(failure.message ?? failure.code);
18
+ this.failure = failure;
19
+ this.missReason = missReason;
20
+ }
21
+ };
22
+ //#endregion
23
+ //#region src/commands/android/plan.ts
24
+ function slotOwnedAvd(projectPath, slot) {
25
+ const android = deviceSlotPlatforms(getProject(projectPath), slot)?.android;
26
+ if (!android?.owned || !android.avdName || android.setupIncomplete) return null;
27
+ const systemImage = ownedAvdSystemImage(android.avdName);
28
+ return systemImage ? {
29
+ avdName: android.avdName,
30
+ systemImage,
31
+ deviceProfile: ownedAvdDeviceProfile(android.avdName)
32
+ } : null;
33
+ }
34
+ function fail(code, message, remedy, { lines = [] } = {}) {
35
+ return {
36
+ ok: false,
37
+ code,
38
+ message,
39
+ remedy,
40
+ lines
41
+ };
42
+ }
43
+ function androidLayoutError(settings, root, bound, isExpo) {
44
+ const error = androidLayoutSettingError(settings, root, bound);
45
+ if (error || !androidLayoutSetting(settings, root, bound).custom || !isExpo()) return error;
46
+ return "android.gradleRoot and android.module apply to bare React Native apps only: expo prebuild generates and builds android/. Remove them for this Expo app.";
47
+ }
48
+ function androidCompilerCache({ root, optimizations, settingsContext, layout }) {
49
+ const { cas, optimizations: resolved } = resolveAndroidCompilerCache({
50
+ optimizations,
51
+ use: (manifest) => resolveAndroidCas(root, {
52
+ ...process.env,
53
+ STIM_ANDROID_CAS_TOOLCHAIN: manifest
54
+ }, layout)
55
+ });
56
+ const fallback = resolved.android.compilerCacheFallback;
57
+ if (!fallback) return {
58
+ cas,
59
+ optimizations: resolved,
60
+ warning: null
61
+ };
62
+ return {
63
+ cas,
64
+ optimizations: resolved,
65
+ warning: `Warning: ${compilerCacheFallbackMessage({
66
+ fallback,
67
+ compilerCache: resolved.android.compilerCache === "none" ? "none" : "ccache",
68
+ file: settingFile(settingsContext, fallback.key)
69
+ })}`
70
+ };
71
+ }
72
+ function resolveAndroidBuildPlan({ settings, settingsContext, easProfile, variant: variantFlag, buildCache: requestedBuildCache }, { warn, runtimeKind, resolveCompilerCache = androidCompilerCache, resolveCacheProvider = resolveCacheProviderConfig, variantProblem, detectExpo = () => detectIsExpo(settingsContext.projectPath) }) {
73
+ const root = settingsContext.projectPath;
74
+ const [shapeError, ...moreShapeErrors] = settingShapeErrors(settings);
75
+ if (shapeError) return fail("STIM_BAD_ARG", shapeError, SETTING_SHAPE_REMEDY, { lines: moreShapeErrors });
76
+ const bound = settingsContext.repoRoot ?? root;
77
+ const layoutError = androidLayoutError(settings, root, bound, detectExpo);
78
+ if (layoutError) return fail("STIM_BAD_ARG", layoutError, SETTING_SHAPE_REMEDY);
79
+ const layout = resolveAndroidLayout(settings, root, bound);
80
+ for (const key of unknownSettingKeys(settings)) warn("setting", `Warning: setting "${key}" is not read by Stim and will be ignored.`);
81
+ let optimizations;
82
+ try {
83
+ optimizations = resolveOptimizations(settings);
84
+ } catch (error) {
85
+ return fail("STIM_BAD_ARG", `Could not configure Android build: ${error.message}`, SETTING_SHAPE_REMEDY);
86
+ }
87
+ const compilerCache = resolveCompilerCache({
88
+ root,
89
+ optimizations,
90
+ settingsContext,
91
+ layout
92
+ });
93
+ const cas = compilerCache.cas;
94
+ optimizations = compilerCache.optimizations;
95
+ if (compilerCache.warning) warn("cache", compilerCache.warning);
96
+ const buildProfile = optimizationBuildProfile("android", optimizations);
97
+ const cacheProviderConfig = resolveCacheProvider(settingsContext);
98
+ const cacheProviderError = cacheProviderSettingError(settings);
99
+ if (cacheProviderError) warn("cache", `${cacheProviderError} Using the local cache.`);
100
+ const variant = easProfile !== void 0 ? "debug" : resolveVariant(variantFlag, settings);
101
+ const flavorRefusal = variantProblem(variant);
102
+ if (flavorRefusal) return fail(flavorRefusal.code, flavorRefusal.reason, flavorRefusal.remedy);
103
+ const release = isReleaseVariant(variant);
104
+ return {
105
+ ok: true,
106
+ plan: {
107
+ build: {
108
+ variant,
109
+ release,
110
+ profile: buildProfile,
111
+ cas,
112
+ cache: artifactCachePolicy(optimizations, requestedBuildCache, runtimeKind({ release }) === "embedded-js"),
113
+ compilerCache: optimizations.android.compilerCache,
114
+ gradleBuildCache: optimizations.android.gradleBuildCache,
115
+ pch: optimizations.android.pch,
116
+ targetAbiOnly: optimizations.android.targetAbiOnly
117
+ },
118
+ metroWarmup: optimizations.metroWarmup,
119
+ cacheProviderConfig
120
+ }
121
+ };
122
+ }
123
+ function resolveAndroidRunPlan({ settings, settingsContext, slot, easProfile, variant: variantFlag, systemImage: systemImageFlag, deviceProfile: deviceProfileFlag, device: deviceFlag, wait: waitFlag, waitConflict, remote: commandRemoteBackend, buildCache: requestedBuildCache }, { warn, runtimeKind, resolveCompilerCache = androidCompilerCache, resolveCacheProvider = resolveCacheProviderConfig, validateAvdConfig = androidAvdConfigSettingError, readFlavors = readProductFlavors, variantProblem = (variant) => productFlavorRefusal({
124
+ flavors: readFlavors(resolveAndroidLayout(settings, settingsContext.projectPath, settingsContext.repoRoot ?? settingsContext.projectPath)),
125
+ variant
126
+ }), detectExpo = () => detectIsExpo(settingsContext.projectPath), listSystemImages = listInstalledSystemImages, listDeviceProfiles = listAvdDeviceProfiles, parkedLimit = parkedMaxSetting, supportsFold = systemImageSupportsFold, ownedAvd = slotOwnedAvd }) {
127
+ const root = settingsContext.projectPath;
128
+ const [shapeError, ...moreShapeErrors] = [parkedLimit("android").error, ...settingShapeErrors(settings)].filter((error) => Boolean(error));
129
+ if (shapeError) return fail("STIM_BAD_ARG", shapeError, SETTING_SHAPE_REMEDY, { lines: moreShapeErrors });
130
+ const plannedBuild = resolveAndroidBuildPlan({
131
+ settings,
132
+ settingsContext,
133
+ easProfile,
134
+ variant: variantFlag,
135
+ buildCache: requestedBuildCache
136
+ }, {
137
+ warn,
138
+ runtimeKind,
139
+ resolveCompilerCache,
140
+ resolveCacheProvider,
141
+ variantProblem,
142
+ detectExpo
143
+ });
144
+ if (!plannedBuild.ok) return plannedBuild;
145
+ const dataPartitionSizeError = androidDataPartitionSizeGbSettingError(settings);
146
+ if (dataPartitionSizeError) return fail("STIM_BAD_ARG", dataPartitionSizeError, "Set android.dataPartitionSizeGb to a whole number of GiB from 6 through 16384.");
147
+ const avdConfigError = validateAvdConfig(settings, root);
148
+ if (avdConfigError) return fail("STIM_BAD_ARG", avdConfigError, "Use only documented android.avdConfig keys, or an android.avdConfigFile fragment contained by the app directory.");
149
+ const systemImage = resolveSystemImage(systemImageFlag, settings);
150
+ const deviceProfile = resolveDeviceProfile(deviceProfileFlag, settings);
151
+ const isExpo = detectExpo();
152
+ const physical = isPhysicalDeviceRequest(deviceFlag);
153
+ if (physical && deviceFlag === "") return fail("STIM_BAD_ARG", "--device was given an empty serial.", "Pass `--device` on its own to take the first connected device this workspace can lease, or `--device <serial>` to name one.");
154
+ if (physical && commandRemoteBackend) return fail("STIM_BAD_ARG", "--device installs on a device connected to this machine, and --remote installs on a remote one.", "Pass only one of --device and --remote.");
155
+ const noWait = waitFlag === false;
156
+ if (waitConflict) return fail("STIM_BAD_ARG", "--wait and --no-wait ask for opposite things.", "Pass only one of `--wait <seconds>` and `--no-wait`.");
157
+ const waitParsed = parseDeviceWait(noWait ? void 0 : waitFlag);
158
+ if ("error" in waitParsed) return fail("STIM_BAD_ARG", waitParsed.error, "Pass a whole number of seconds, e.g. --wait 90. `--wait 0` refuses a busy lease or device slot at once.");
159
+ const waitSeconds = waitParsed.seconds;
160
+ const remoteTarget = commandRemoteBackend !== null ? parseIosRemote(commandRemoteBackend) : remoteAndroidSetting(settings);
161
+ if (physical && remoteTarget?.kind === "machine") return fail("STIM_BAD_ARG", "--device installs on a phone connected to this machine, and --remote installs on a remote one.", "Pass only one of --device and --remote; unset android.remote for a local phone.");
162
+ const machine = remoteTarget?.kind === "machine" ? remoteTarget.machine : null;
163
+ const remoteBackend = !physical && remoteTarget?.kind === "backend" ? remoteTarget.backend : null;
164
+ if (!machine) {
165
+ const refusal = androidDeviceSelectorRefusal({
166
+ settingsContext,
167
+ slot,
168
+ systemImageFlag,
169
+ deviceProfileFlag,
170
+ systemImage,
171
+ deviceProfile,
172
+ physical,
173
+ remoteBackend
174
+ }, {
175
+ listSystemImages,
176
+ listDeviceProfiles,
177
+ supportsFold,
178
+ ownedAvd
179
+ });
180
+ if (refusal) return refusal;
181
+ }
182
+ const target = physical ? {
183
+ kind: "physical",
184
+ serial: typeof deviceFlag === "string" ? deviceFlag : null,
185
+ lease: {
186
+ waitSeconds,
187
+ noWait
188
+ }
189
+ } : machine ? {
190
+ kind: "hosted",
191
+ machine,
192
+ systemImage,
193
+ deviceProfile
194
+ } : remoteBackend ? {
195
+ kind: "remote",
196
+ backend: remoteBackend,
197
+ systemImage,
198
+ deviceProfile
199
+ } : {
200
+ kind: "emulator",
201
+ systemImage,
202
+ deviceProfile
203
+ };
204
+ return {
205
+ ok: true,
206
+ plan: {
207
+ ...plannedBuild.plan,
208
+ target,
209
+ deviceSlotWaitMs: noWait ? 0 : waitFlag === void 0 && !physical ? DEFAULT_DEVICE_SLOT_WAIT_MS : waitSeconds * 1e3,
210
+ isExpo
211
+ }
212
+ };
213
+ }
214
+ function androidDeviceSelectorRefusal({ settingsContext, slot, systemImageFlag, deviceProfileFlag, systemImage, deviceProfile, physical, remoteBackend }, { listSystemImages = listInstalledSystemImages, listDeviceProfiles = listAvdDeviceProfiles, supportsFold = systemImageSupportsFold, ownedAvd = slotOwnedAvd } = {}) {
215
+ const root = settingsContext.projectPath;
216
+ const settingsLayersForOrigin = settingsLayers(settingsContext);
217
+ const imageRefusal = systemImageRefusal({
218
+ slot,
219
+ flag: systemImageFlag,
220
+ resolved: systemImage,
221
+ origin: settingOriginScope(settingsLayersForOrigin, "android.systemImage"),
222
+ physical,
223
+ remoteBackend,
224
+ listImages: listSystemImages
225
+ });
226
+ if (imageRefusal) return fail(imageRefusal.code, imageRefusal.message, imageRefusal.remedy);
227
+ const profileRefusal = deviceProfileRefusal({
228
+ flag: deviceProfileFlag,
229
+ resolved: deviceProfile,
230
+ origin: settingOriginScope(settingsLayersForOrigin, "android.deviceProfile"),
231
+ physical,
232
+ remoteBackend,
233
+ listProfiles: listDeviceProfiles
234
+ });
235
+ if (profileRefusal) return fail(profileRefusal.code, profileRefusal.message, profileRefusal.remedy);
236
+ const avdFlagRefusal = remoteAvdFlagRefusal({
237
+ systemImageFlag,
238
+ deviceProfileFlag,
239
+ remoteBackend
240
+ });
241
+ if (avdFlagRefusal) return fail(avdFlagRefusal.code, avdFlagRefusal.message, avdFlagRefusal.remedy);
242
+ if (!physical && !remoteBackend) {
243
+ const flagImage = typeof systemImageFlag === "string" && systemImageFlag.trim() ? systemImageFlag.trim() : null;
244
+ const existing = ownedAvd(root, slot);
245
+ const profile = deviceProfile ?? existing?.deviceProfile ?? DEFAULT_AVD_DEVICE_PROFILE;
246
+ const image = () => flagImage ?? existing?.systemImage ?? systemImage ?? pickDefaultSystemImage(listSystemImages())?.pkg ?? null;
247
+ const checked = profileNeedsFoldFeature(profile) ? image() : null;
248
+ const foldRefusal = checked !== null && foldableImageRefusal({
249
+ profile,
250
+ image: checked,
251
+ avdName: existing && existing.systemImage === checked && existing.deviceProfile === profile ? existing.avdName : null,
252
+ images: listSystemImages,
253
+ supportsFold
254
+ });
255
+ if (foldRefusal) return fail(foldRefusal.code, foldRefusal.message, foldRefusal.remedy);
256
+ }
257
+ return null;
258
+ }
259
+ //#endregion
260
+ export { AndroidRecipeRefusal as i, resolveAndroidBuildPlan as n, resolveAndroidRunPlan as r, androidDeviceSelectorRefusal as t };
@@ -0,0 +1,73 @@
1
+ import { S as hostingMachines } from "./client-BLy1Pw2V.mjs";
2
+ import { r as readHostedNative } from "./ios-state-CjrL2qv-.mjs";
3
+ import { l as probeHost, s as automaticDevicePlacement } from "./build-plan-CP0tckNU.mjs";
4
+ import { automaticMachineEnabled } from "@stim-cli/core/state";
5
+ //#region src/device-host/plan-placement.ts
6
+ /**
7
+ * Where `--plan` assumes the next run puts its simulator or emulator, with no session, reservation or state write.
8
+ * A named Mac, or the Mac a recorded session already holds, answers with the device its `device-host.offer` would
9
+ * give; `auto` repeats the placement decision a run makes now and, when that stays on this Mac, notes any Mac
10
+ * whose device would key differently. The result predicts the cache key only; a run reads its own device.
11
+ */
12
+ async function planHostedDevice({ root, slot, platform, machine, selectors, sameKey, eas, deps = {} }) {
13
+ const { automatic = automaticDevicePlacement, probe = probeHost, machines = hostingMachines } = deps;
14
+ const named = async (name) => {
15
+ const result = await probe(name, platform, selectors);
16
+ if ("failure" in result.probe) return {
17
+ kind: "unknown",
18
+ reason: `${name} did not give a ${platform} device (${result.probe.failure})`
19
+ };
20
+ const { choice, declined } = result.probe.offer;
21
+ if (!choice) return {
22
+ kind: "unknown",
23
+ reason: `${name} has no ${platform} device for this selection${declined ? ` (${declined})` : ""}`
24
+ };
25
+ return {
26
+ kind: "hosted",
27
+ choice,
28
+ placement: `on ${name}`
29
+ };
30
+ };
31
+ if (machine !== "auto") return named(machine);
32
+ try {
33
+ const recorded = readHostedNative(root, platform, slot)[slot];
34
+ if (recorded) return await named(recorded.machine);
35
+ const placed = await automatic({
36
+ root,
37
+ slot,
38
+ platform,
39
+ selectors,
40
+ noWait: false,
41
+ ...eas ? { eas } : {}
42
+ }, {
43
+ read: () => ({}),
44
+ write: () => {}
45
+ });
46
+ if (placed.placement.decision === "eas") return {
47
+ kind: "unknown",
48
+ reason: `auto would run on an EAS Simulator now (${placed.placement.reason}), which --plan cannot read without a session`
49
+ };
50
+ if (placed.target) return {
51
+ kind: "hosted",
52
+ choice: placed.target.choice,
53
+ placement: `on ${placed.target.host.machine}, as auto would now`
54
+ };
55
+ const names = (machines() ?? []).filter((name) => automaticMachineEnabled("device", name));
56
+ const differs = (await Promise.all(names.map((name) => probe(name, platform, selectors)))).flatMap(({ probe: each }) => "offer" in each && each.offer.choice && sameKey(each.offer.choice) === false ? [each.machine] : []);
57
+ if (differs.length) return {
58
+ kind: "local",
59
+ placement: `this Mac; auto may use ${differs.join(", ")}, which builds for another architecture, so its key differs`
60
+ };
61
+ return {
62
+ kind: "local",
63
+ placement: names.length ? `this Mac; auto may use ${names.join(", ")}` : "this Mac"
64
+ };
65
+ } catch (error) {
66
+ return {
67
+ kind: "unknown",
68
+ reason: error.message
69
+ };
70
+ }
71
+ }
72
+ //#endregion
73
+ export { planHostedDevice as t };
@@ -1,6 +1,6 @@
1
- import { p as getProject } from "./config-DC5jEtd1.mjs";
2
- import { n as findCommandWorkspace } from "./project-B5eQ1USs.mjs";
3
- import { n as getNamedPort, t as clearNamedPorts } from "./named-ports-B4iWH4E-.mjs";
1
+ import { p as getProject } from "./config-D0LhTY3S.mjs";
2
+ import { n as findCommandWorkspace } from "./project-B8_duAzW.mjs";
3
+ import { n as getNamedPort, t as clearNamedPorts } from "./named-ports-C2lvoPsb.mjs";
4
4
  //#region src/commands/ports.ts
5
5
  async function inProject(action) {
6
6
  try {
@@ -1,9 +1,9 @@
1
- import { t as getExecutor } from "./exec-i8GDPwq9.mjs";
1
+ import { t as getExecutor } from "./exec-B81Qodjn.mjs";
2
+ import { a as updateWorkspaceState, r as readWorkspaceState } from "./workspace-state-CSIFuuDa.mjs";
2
3
  import { n as stripAnsi, r as waitForChild, t as createLineReader } from "./process-output-Fpl8PYi8.mjs";
3
- import { a as updateWorkspaceState, r as readWorkspaceState } from "./workspace-state-CR9X86xJ.mjs";
4
- import { p as detectIsExpo } from "./project-B5eQ1USs.mjs";
4
+ import { _ as detectIsExpo } from "./project-B8_duAzW.mjs";
5
5
  import { a as spawnDeclared } from "./spawn-claims-Kqiifsk2.mjs";
6
- import { i as expoBinRefusal, r as expoBinPath } from "./server-expo-n3tUi3Em.mjs";
6
+ import { i as expoBinRefusal, r as expoBinPath } from "./server-expo-CsYu2aKL.mjs";
7
7
  import { existsSync } from "node:fs";
8
8
  import { join } from "node:path";
9
9
  //#region src/engine/prebuild.ts
@@ -1,28 +1,28 @@
1
- import { t as getExecutor } from "./exec-i8GDPwq9.mjs";
2
- import { o as formatLongDuration, u as plural } from "./command-output-Bt8ygHE7.mjs";
3
- import { H as projectDeviceSlots, M as isOnMountedVolume, N as listMountedVolumes, P as measuredDirectorySize, _ as loadConfig$1, p as getProject } from "./config-DC5jEtd1.mjs";
4
- import { C as workspaceStateFile, r as readWorkspaceState$1, s as workspaceLastUsed, x as workspaceLogsDir$1 } from "./workspace-state-CR9X86xJ.mjs";
5
- import { r as findProjectRoot } from "./project-B5eQ1USs.mjs";
6
- import { D as projectMaintenancePinned, ht as resolveFullRef, it as hasPopulatedSubmodules, lt as listWorktrees, ot as hasUncommittedWork, tt as dirtyPaths, vt as sourceCheckoutOf, yt as unpushedCommits } from "./settings-CxgngUZk.mjs";
7
- import { n as readManifest } from "./cache-manifest-DiwKSyv9.mjs";
8
- import { At as phase, G as DEVICE_LIST_TIMEOUT_MS, Nt as discoverCaches, c as readVolumeSpace, i as enforceBudget, l as resolveBudget, o as machineNumber, pt as planCacheEmptying, r as cacheLabel, u as trimmableCaches } from "./budget-Dz-kyXLv.mjs";
9
- import { F as recordGcResult, L as canonicalPath, N as listBuildSlots, a as collectWorkspaceOutputs, c as listWorkspaceDirs, i as collectOrphanedWorkspaces, p as workspaceInUse, s as isInsideWorkspaces } from "./workspaces-Djb2gfi9.mjs";
10
- import { h as listBuildLocks, i as listLeaseFiles, r as leaseIsExpired } from "./device-lease-Cu7PtQpZ.mjs";
11
- import { pt as readParked, z as ownedAvdSerialResolver } from "./android-BdQC6zs1.mjs";
12
- import { M as readHostMemoryPressure, d as listAllIosSims } from "./ios-BWbHFZVz.mjs";
13
- import { a as metroStoreRoot } from "./metro-store-BAHFcJm6.mjs";
14
- import { n as describePullRequest, o as pullRequestLookups, r as endedPullRequest } from "./pull-request-IHNdMnG8.mjs";
1
+ import { t as getExecutor } from "./exec-B81Qodjn.mjs";
2
+ import { H as projectDeviceSlots, M as isOnMountedVolume, N as listMountedVolumes, P as measuredDirectorySize, _ as loadConfig$1, p as getProject } from "./config-D0LhTY3S.mjs";
3
+ import { n as readManifest } from "./cache-manifest-qA3dT2x2.mjs";
4
+ import { At as sourceCheckoutOf, Dt as resolveFullRef, E as maintenanceKeepSetting, K as resolveProjectSettings, gt as hasPopulatedSubmodules, jt as unpushedCommits, pt as dirtyPaths, vt as hasUncommittedWork, xt as listWorktrees } from "./settings-Bbztm4oV.mjs";
5
+ import { h as listBuildLocks, i as listLeaseFiles, r as leaseIsExpired } from "./device-lease-DHOBXGgS.mjs";
6
+ import { E as workspaceStateFile, r as readWorkspaceState$1, s as workspaceLastUsed, w as workspaceLogsDir$1 } from "./workspace-state-CSIFuuDa.mjs";
7
+ import { o as formatLongDuration, u as plural } from "./command-output-BjPN99ZB.mjs";
8
+ import { r as findProjectRoot } from "./project-B8_duAzW.mjs";
9
+ import { ft as readParked, z as ownedAvdSerialResolver } from "./android-BsYNR81W.mjs";
10
+ import { C as recordGcResult, I as listBuildSlots, T as canonicalPath, a as collectWorkspaceOutputs, c as listWorkspaceDirs, i as collectOrphanedWorkspaces, p as workspaceInUse, s as isInsideWorkspaces } from "./workspaces-D2xSHBDY.mjs";
11
+ import { _ as DEVICE_LIST_TIMEOUT_MS, at as discoverCaches, c as readVolumeSpace, i as enforceBudget, l as resolveBudget, nt as phase, o as machineNumber, r as cacheLabel, u as trimmableCaches, z as planCacheEmptying } from "./budget-BONq9vXY.mjs";
12
+ import { s as metroStoreRoot } from "./errors-DzkMYh8Q.mjs";
13
+ import { P as readHostMemoryPressure, d as listAllIosSims } from "./ios-CXLIUxXJ.mjs";
14
+ import { n as describePullRequest, o as pullRequestLookups, r as endedPullRequest } from "./pull-request-vOhLNmIb.mjs";
15
15
  import { t as resolveMaintenanceSettings } from "./settings-Djl-mpjX.mjs";
16
- import { o as fetchDefaultBranch, s as mergeState } from "./warm-progress-pFLB2e6P.mjs";
17
- import { f as removeWorktreeTarget, i as matchWorktreeEntry, n as excludePodChurn, o as reclaimKeys, r as excludeWatchmanCookies } from "./worktree-BL4M1rhB.mjs";
16
+ import { o as fetchDefaultBranch, s as mergeState } from "./warm-progress-C3ASD6z5.mjs";
17
+ import { a as matchWorktreeEntry, i as excludeWatchmanCookies, p as removeWorktreeTarget, r as excludePodChurn, s as reclaimKeys } from "./worktree-BxDqaTev.mjs";
18
18
  import { existsSync } from "node:fs";
19
19
  import { basename, isAbsolute, join, sep } from "node:path";
20
20
  import { isAbsolute as isAbsolute$1, join as join$1 } from "path";
21
- import { LAST_BUILD_KEYS, MAINTENANCE_LOG_NAME, buildWorkerRoot, loadConfig, readMaintenanceState, settingDefinition, sharedCcache, sharedCompilationCache } from "@stim-cli/core/state";
22
- import { cpus, freemem, loadavg, totalmem } from "node:os";
23
- import chalk from "chalk";
21
+ import { LAST_BUILD_KEYS, MAINTENANCE_LOG_NAME, buildWorkerRoot, loadConfig, readBuildHistory, readMaintenanceState, settingDefinition, sharedCcache, sharedCompilationCache } from "@stim-cli/core/state";
24
22
  import { existsSync as existsSync$1, readdirSync as readdirSync$1, statSync as statSync$1 } from "fs";
25
23
  import { buildCacheRoot, configDir, metroCacheRoot } from "@stim-cli/core";
24
+ import { cpus, freemem, loadavg, totalmem } from "node:os";
25
+ import chalk from "chalk";
26
26
  //#region src/maintenance/measure.ts
27
27
  function measureDisk() {
28
28
  return readVolumeSpace([
@@ -585,6 +585,10 @@ function protectedCacheKeys(config = loadConfig$1()) {
585
585
  for (const root of Object.keys(config?.projects ?? {})) {
586
586
  const state = readWorkspaceState$1(root);
587
587
  for (const name of BUILD_RECORDS) for (const key of recordKeys(state?.[name])) keys.add(key);
588
+ for (const entries of Object.values(readBuildHistory(state))) {
589
+ const key = entries.find((entry) => entry.result === "succeeded")?.cacheKey;
590
+ if (key) keys.add(key);
591
+ }
588
592
  }
589
593
  for (const platform of ["ios", "android"]) for (const record of readParked(platform, { config })) if (record.cacheKey) keys.add(record.cacheKey);
590
594
  for (const lock of listBuildLocks()) if ((lock.alive || lock.unresolved) && lock.key) keys.add(lock.key);
@@ -612,6 +616,13 @@ function cacheEntryProtection(config = loadConfig$1()) {
612
616
  return () => reason;
613
617
  }
614
618
  }
619
+ function maintenancePinned(root) {
620
+ try {
621
+ return maintenanceKeepSetting(resolveProjectSettings(root).settings);
622
+ } catch {
623
+ return true;
624
+ }
625
+ }
615
626
  function recentUse(workspace, settings) {
616
627
  const since = Date.now() - workspaceLastUsed(workspace);
617
628
  return Number.isFinite(since) && since < settings.protectRecentHours * 36e5 ? `used within the last ${settings.protectRecentHours} hours` : null;
@@ -889,24 +900,31 @@ async function plannedMaintenance(pressure, sizes, settings, { devices = true, s
889
900
  now: Date.now(),
890
901
  measure: false
891
902
  });
903
+ const currentSizes = sizes.map((size) => {
904
+ if (size.category === "compilation-cache") return {
905
+ ...size,
906
+ blocked: cacheBlocked(size)
907
+ };
908
+ if (!size.workspace) return size;
909
+ const current = outputs.workspaces.find((entry) => entry.projectRoot && canonicalPath(entry.projectRoot) === size.workspace);
910
+ return Object.assign({}, size, { blocked: current?.willClear ? void 0 : current?.keptReason ?? "workspace outputs cannot be resolved" });
911
+ });
912
+ const pins = /* @__PURE__ */ new Map();
913
+ const pinned = (workspace) => {
914
+ let value = pins.get(workspace);
915
+ if (value === void 0) pins.set(workspace, value = maintenancePinned(workspace));
916
+ return value;
917
+ };
892
918
  const result = plan({
893
919
  pressure,
894
- sizes: sizes.map((size) => {
895
- if (size.category === "compilation-cache") return {
896
- ...size,
897
- blocked: cacheBlocked(size)
898
- };
899
- if (!size.workspace) return size;
900
- const current = outputs.workspaces.find((entry) => entry.projectRoot && canonicalPath(entry.projectRoot) === size.workspace);
901
- return Object.assign({}, size, { blocked: current?.willClear ? void 0 : current?.keptReason ?? "workspace outputs cannot be resolved" });
902
- }),
920
+ sizes: currentSizes,
903
921
  settings,
904
922
  budget,
905
923
  diskSteps: outcome?.status === "ok" ? outcome.reclaimed.filter((step) => devices || step.step !== "idle-devices") : [],
906
924
  protectedRoot: root,
907
925
  scoped: Boolean(process.env.STIM_HOME),
908
926
  projects: Object.keys(loadConfig()?.projects ?? {}).map(canonicalPath),
909
- pinned: projectMaintenancePinned,
927
+ pinned,
910
928
  recentlyUsed: (workspace) => recentUse(workspace, settings)
911
929
  });
912
930
  const merge = (extra) => {
@@ -918,13 +936,13 @@ async function plannedMaintenance(pressure, sizes, settings, { devices = true, s
918
936
  settings,
919
937
  sizes,
920
938
  protectedRoot: root,
921
- pinned: projectMaintenancePinned,
939
+ pinned,
922
940
  now: Date.now()
923
941
  }));
924
942
  if (worktrees) {
925
943
  const planned = await planWorktrees({
926
944
  protectedRoot: root,
927
- pinned: projectMaintenancePinned,
945
+ pinned,
928
946
  now: Date.now()
929
947
  });
930
948
  merge(planned);
@@ -983,4 +1001,4 @@ async function previewMaintenance({ devices = true } = {}) {
983
1001
  }
984
1002
  }
985
1003
  //#endregion
986
- export { recentUse as a, worktreePullRequestNote as c, measureDisk as d, measurePressure as f, cacheEntryProtection as i, worktreeRemovalReason as l, sizeScanDeferred as m, previewMaintenance as n, collectWorktreeSweep as o, measureSizes as p, triggeringRoot as r, removeWorktrees as s, plannedMaintenance as t, cacheBlocked as u };
1004
+ export { maintenancePinned as a, removeWorktrees as c, cacheBlocked as d, measureDisk as f, sizeScanDeferred as h, cacheEntryProtection as i, worktreePullRequestNote as l, measureSizes as m, previewMaintenance as n, recentUse as o, measurePressure as p, triggeringRoot as r, collectWorktreeSweep as s, plannedMaintenance as t, worktreeRemovalReason as u };