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.
- package/dist/{acquire-artifact-DVsvSwf7.mjs → acquire-artifact-BKN2Yuhg.mjs} +2 -2
- package/dist/{act-C-BqJEpu.mjs → act-ROviTF_t.mjs} +297 -122
- package/dist/{activity-Lnb_EoRY.mjs → activity-Cd-ysFes.mjs} +6 -6
- package/dist/{agent-device-usage-output-DbXy5tg8.mjs → agent-device-usage-output-C5nCKWp9.mjs} +5 -5
- package/dist/{android-CSbLRD53.mjs → android--HBgpvpW.mjs} +5 -5
- package/dist/{android-CiNQw3kq.mjs → android-Cd6w7_qw.mjs} +96 -43
- package/dist/{android-B5P81yI-.mjs → android-Deb9X3_Y.mjs} +37 -15
- package/dist/{android-DTAcRwBC.mjs → android-DriNoAVy.mjs} +23 -18
- package/dist/{android-cas-BTVhZ0Qs.mjs → android-cas-D5e6ecUg.mjs} +4 -4
- package/dist/android-cas-compiler.mjs +1 -1
- package/dist/api.d.mts +13 -3
- package/dist/api.mjs +39 -29
- package/dist/{apk-signed-tail-B46U9hXc.mjs → apk-signed-tail-BHQHx3Rm.mjs} +2 -2
- package/dist/{artifact-BxREhAaV.mjs → artifact-0AGJYB9O.mjs} +18 -23
- package/dist/{artifact-CsAP6AGK.mjs → artifact-faemIZv5.mjs} +19 -24
- package/dist/{artifact-platform-CMRc0M_r.mjs → artifact-platform-BO2Uvk_A.mjs} +1 -1
- package/dist/auto-placement-z-H5pJza.mjs +350 -0
- package/dist/{browser-web-rYPyqhTf.mjs → browser-web-slD8AvLp.mjs} +16 -16
- package/dist/{build-cache-DrXNCy3T.mjs → build-cache-gBJ-WKzA.mjs} +43 -21
- package/dist/{build-DPhApsjV.mjs → build-hS0QyFlQ.mjs} +35 -31
- package/dist/{build-plan-DrMMdayj.mjs → build-plan-CBqYbzYM.mjs} +7 -6
- package/dist/{cache-manifest-BEZ9Bpl1.mjs → cache-manifest-DEjqGGat.mjs} +1 -1
- package/dist/cache-manifest.mjs +1 -1
- package/dist/{budget-k2mZGvvk.mjs → ccache-BWTze1Ls.mjs} +560 -1603
- package/dist/{cdp-BG3FJCCx.mjs → cdp-C3svvXiE.mjs} +1 -1
- package/dist/{chrome-BvV8ssI3.mjs → chrome-DyDWurWG.mjs} +1 -1
- package/dist/{cli-BBKFGOFl.mjs → cli-ftXDLto1.mjs} +24 -23
- package/dist/cli.mjs +1 -1
- package/dist/{client-D9CaRks-.mjs → client-xsdxrhWA.mjs} +48 -62
- package/dist/collector-run.d.mts +10 -9
- package/dist/collector-run.mjs +42 -27
- package/dist/{command-output-BF5AR2dL.mjs → command-output-Dj-WT4BP.mjs} +1 -1
- package/dist/{config-BktkY_zC.mjs → config-Cn94Jc0g.mjs} +23 -4
- package/dist/{dependencies-Dw6wfQdv.mjs → dependencies-BGokZ-Ng.mjs} +108 -60
- package/dist/{dependency-state-DFB41vfr.mjs → dependency-state-C3OtgG94.mjs} +14 -7
- package/dist/{detached-entry-KmieOKgN.mjs → detached-entry-BPlSaCwC.mjs} +1 -1
- package/dist/{dev-client-DXR_tPVY.mjs → dev-client-BMca82xo.mjs} +2 -2
- package/dist/{device-BcYeHSFu.mjs → device-BJm0irrq.mjs} +16 -16
- package/dist/{device-capacity-DCSvUF0l.mjs → device-capacity-6LP7QsaA.mjs} +101 -16
- package/dist/device-host-worker.mjs +19 -19
- package/dist/{device-ios-BLGfXQeK.mjs → device-ios-534c14fz.mjs} +251 -23
- package/dist/{device-lease-run-BmvIl7bI.mjs → device-lease-run-DwsGfjUN.mjs} +5 -5
- package/dist/{device-pool-Dluix4H3.mjs → device-pool-BnQqvs6o.mjs} +3 -3
- package/dist/{device-BK-zwyd_.mjs → device-tM41-TUq.mjs} +25 -24
- package/dist/{doctor-Cp-BhzTS.mjs → doctor-Dbx1ZpD2.mjs} +1 -1
- package/dist/{doctor-Bhg1ii70.mjs → doctor-DyqE9n1J.mjs} +28 -16
- package/dist/{doctor-OnwP94ne.mjs → doctor-F-3VUUyN.mjs} +76 -32
- package/dist/{doctor-fingerprint-D3a04Mhu.mjs → doctor-fingerprint-o7ZI9YLn.mjs} +1 -1
- package/dist/doctor-fingerprint.mjs +1 -1
- package/dist/{doctor-watchman-BStK05nt.mjs → doctor-watchman-CxDbyrrt.mjs} +5 -5
- package/dist/{eas-build-Dsj93iM9.mjs → eas-build-CjNSWmjo.mjs} +4 -4
- package/dist/eas-fallback-9fqb46kW.mjs +87 -0
- package/dist/{eas-session-ledger-B5vygTiD.mjs → eas-session-ledger-DrP4OuuM.mjs} +6 -6
- package/dist/{error-diagnostics-BOOm9Db7.mjs → error-diagnostics-snej9k4j.mjs} +51 -25
- package/dist/{exec-VFRpu1iA.mjs → exec-aULwtNly.mjs} +57 -6
- package/dist/{gc-C_79zvz4.mjs → gc-BRwAY3qT.mjs} +2 -2
- package/dist/{gc-ldgr-hXU.mjs → gc-CGZ1Yg88.mjs} +160 -45
- package/dist/{guide-D7K0X6KG.mjs → guide-_rfEh_zM.mjs} +580 -183
- package/dist/{hosted-android-Bk54ej6n.mjs → hosted-android-BMKzUNnY.mjs} +4 -4
- package/dist/{hosted-client-fHO8yqzc.mjs → hosted-client-D7Pk_Oo1.mjs} +12 -8
- package/dist/{hosted-logs-BfbmDM4M.mjs → hosted-logs-B1gqQuva.mjs} +8 -8
- package/dist/{hosted-logs-sync-B0pvmOk-.mjs → hosted-logs-sync-Dg3qrZmV.mjs} +5 -5
- package/dist/{hosted-macos-CPl0OZ9h.mjs → hosted-macos-B9w4H8hc.mjs} +6 -6
- package/dist/{hosted-native-CpDB3-PO.mjs → hosted-native-CdgaiuyP.mjs} +17 -16
- package/dist/{idle-shutdown-FfxL1KdG.mjs → idle-shutdown-Cbvo5KEh.mjs} +7 -8
- package/dist/{ios-ftxdQbJS.mjs → ios-B5HlVMhQ.mjs} +92 -37
- package/dist/{ios-B7-lToDu.mjs → ios-Bk4mWbtS.mjs} +8 -8
- package/dist/{ios-ENC4sRPA.mjs → ios-CsRVik64.mjs} +7 -1
- package/dist/{ios-WxpDJ5T1.mjs → ios-E26qSpkb.mjs} +27 -11
- package/dist/{ios-device-CsyryvpT.mjs → ios-device-C_QkIf1Z.mjs} +3 -3
- package/dist/{ios-device-B6HK951C.mjs → ios-device-CiBA-er9.mjs} +1 -1
- package/dist/{ios-project-Ty5pHl9O.mjs → ios-project-D8Jcy_br.mjs} +22 -9
- package/dist/{ios-signing-4c_qXvQm.mjs → ios-signing-BJzvDPfU.mjs} +2 -2
- package/dist/{ios-state-Cw7-WQf2.mjs → ios-state-BZ03NFgF.mjs} +1 -1
- package/dist/{js-swap-BMhXYVDS.mjs → js-swap-Dg2a945i.mjs} +8 -7
- package/dist/{launch-DOp8RjDz.mjs → launch-CRyBeNsA.mjs} +42 -38
- package/dist/lightened-BCsdAGj_.mjs +171 -0
- package/dist/{logs-dQDki6Tt.mjs → logs-CC_-ZzEE.mjs} +7 -7
- package/dist/{logs-s1dRIG1E.mjs → logs-aJQb-RDg.mjs} +46 -21
- package/dist/{macos-B0VEV3Gf.mjs → macos-BGmTpnv9.mjs} +1 -1
- package/dist/{macos-DBBPNnIA.mjs → macos-DlCBhMw5.mjs} +73 -38
- package/dist/macos-run.mjs +1 -1
- package/dist/maintenance-run.mjs +7 -7
- package/dist/{metro-CjC10t6E.mjs → metro-CvyD-xwe.mjs} +4 -4
- package/dist/{metro-gateway-B6_PgD0L.mjs → metro-gateway-BnHdqMO_.mjs} +3 -3
- package/dist/{named-ports-BG0j1X4g.mjs → named-ports-BCyMWA6b.mjs} +3 -3
- package/dist/{native-android-CL2NGiik.mjs → native-android-DlpxCyOP.mjs} +17 -18
- package/dist/{native-gradle-artifact-inputs-btSUulme.mjs → native-gradle-artifact-inputs-C13qT7R_.mjs} +5 -5
- package/dist/{native-runtime-Dq3RBcON.mjs → native-runtime-DqaIBO5w.mjs} +9 -8
- package/dist/{native-source-D-4Dh4JU.mjs → native-source-D1AzWiuP.mjs} +1 -1
- package/dist/{native-xcode-inputs-BW7H8JGu.mjs → native-xcode-inputs-B1W8SrxB.mjs} +3 -3
- package/dist/{native-xcode-ios-CBXJAxfC.mjs → native-xcode-ios-QPP0Rm68.mjs} +17 -17
- package/dist/{ndjson-CgE_o3Dl.mjs → ndjson-Dy2W4vRa.mjs} +2 -2
- package/dist/offload-worker.mjs +23 -24
- package/dist/{operation-exec-CUZifp6Z.mjs → operation-exec-Dp4FuIGR.mjs} +1 -1
- package/dist/{ownership-BjYvMNX_.mjs → ownership-Bx-0cku-.mjs} +3 -3
- package/dist/{page-CzEA_-5_.mjs → page-CQJlcj3x.mjs} +2 -2
- package/dist/{phone-reverses-lmj6kcPm.mjs → phone-reverses-C9yAaKEv.mjs} +18 -4
- package/dist/{placement-log-DIFPQAXp.mjs → placement-log-BXUbiZM6.mjs} +3 -3
- package/dist/{plan-placement-IiiSQhtz.mjs → plan-placement-UxnQjv5Z.mjs} +36 -10
- package/dist/{ports-C2_w1Z0Z.mjs → ports-uUrghqWN.mjs} +3 -3
- package/dist/{prebuild-gmouvmJZ.mjs → prebuild-BDpToDgR.mjs} +16 -17
- package/dist/{project-BUu6Is4k.mjs → project-DYj-HVx6.mjs} +17 -17
- package/dist/{pull-request-CbNlkFok.mjs → pull-request-BzLmzAIQ.mjs} +2 -2
- package/dist/pull-requests.mjs +1 -1
- package/dist/{react-native-android-Cgg99REN.mjs → react-native-android-DDBccgJw.mjs} +32 -26
- package/dist/{react-native-build-oNwqF5Wb.mjs → react-native-build-DaK2IFyP.mjs} +9 -9
- package/dist/{react-native-doctor-BhA3KUte.mjs → react-native-doctor-B-Mw6DcR.mjs} +6 -6
- package/dist/{react-native-ios-B-nf4rjN.mjs → react-native-ios-DjYwUF9U.mjs} +23 -17
- package/dist/{recordings-BldzVKq0.mjs → recordings-C20iUZfp.mjs} +1 -1
- package/dist/{registration-CN6nlhcD.mjs → registration-BwCe64PH.mjs} +1 -1
- package/dist/{reload-C9OduiNc.mjs → reload-DJBeF_rC.mjs} +1 -1
- package/dist/{reload-CCR7KC_l.mjs → reload-fUdkH2_p.mjs} +16 -16
- package/dist/{remote-C8S7FlPF.mjs → remote-y6n99WMW.mjs} +22 -9
- package/dist/{result-7F5hEwQJ.mjs → result-CTqBw2Te.mjs} +32 -21
- package/dist/{run-BqB0v3pt.mjs → run-DaCeNKRm.mjs} +3 -3
- package/dist/{selection-BNPBZ6T5.mjs → selection-Bs8phwhN.mjs} +37 -29
- package/dist/{server-bare-A75rDIdD.mjs → server-bare-BOh-iZEj.mjs} +2 -2
- package/dist/{server-command-CssKFOD7.mjs → server-command-8CuA51Cv.mjs} +6 -6
- package/dist/{server-expo-eQfOdydb.mjs → server-expo-ABQs2XFA.mjs} +4 -4
- package/dist/server-expo-Ba_Y21vB.mjs +2 -0
- package/dist/{settings-CosW5X-S.mjs → settings-BDVI8Ivc.mjs} +331 -62
- package/dist/{settings-OaGQF-ri.mjs → settings-CMHhQNwI.mjs} +24 -3
- package/dist/settings-payload-cm60Zhib.mjs +257 -0
- package/dist/settings-write-BdNRLlBn.mjs +185 -0
- package/dist/settings.schema.json +51 -33
- package/dist/{simslim-Bax1qcxu.mjs → simslim-DCQwzoPy.mjs} +2 -2
- package/dist/{slot-launch-CYCEhfBY.mjs → slot-launch-0l7RqSpr.mjs} +6 -6
- package/dist/{stage-jKQ7CP_B.mjs → stage-F4cAfJGi.mjs} +2 -2
- package/dist/{start-C_wefNKB.mjs → start-DcqnF9p8.mjs} +1 -1
- package/dist/{start-_BdJ32cZ.mjs → start-DrPwER_2.mjs} +27 -22
- package/dist/{state-C1i2nMOP.mjs → state-BX1y5syV.mjs} +4 -4
- package/dist/{state-C4OdpOTF.mjs → state-CZxLyetD.mjs} +2 -2
- package/dist/{stats-tEpEEH-u.mjs → stats-GxuCbles.mjs} +5 -5
- package/dist/{stats-report-n2U5plhk.mjs → stats-report-B86Cv7Uc.mjs} +1 -1
- package/dist/{status-CRXz-Gtj.mjs → status-7ULDEJ1e.mjs} +1 -1
- package/dist/{status-DQrqodLj.mjs → status-BfnK9pUd.mjs} +25 -25
- package/dist/{status-B9M7x4CZ.mjs → status-Bj7ZYvvc.mjs} +1 -1
- package/dist/{status-watch-B5wDIH_o.mjs → status-watch-BfabQn03.mjs} +5 -5
- package/dist/status-worker.mjs +1 -1
- package/dist/{stim-desktop-6Dqp-gjX.mjs → stim-desktop-CbWo21kb.mjs} +2 -2
- package/dist/{stop-ySNQHXMG.mjs → stop-CH79S3IZ.mjs} +5 -5
- package/dist/{stop-DRqQVqDJ.mjs → stop-D-EAr25B.mjs} +21 -20
- package/dist/{stop-CmdNhGlC.mjs → stop-x1Yu3He4.mjs} +2 -2
- package/dist/supervisor-run.mjs +17 -17
- package/dist/{support-CVOCp0Ft.mjs → support-Be0UeVZU.mjs} +10 -10
- package/dist/{support-BGSCBoib.mjs → support-CNg_YsOk.mjs} +6 -6
- package/dist/{swiftpm-artifact-inputs-CfUzt_0Z.mjs → swiftpm-artifact-inputs-uPqYvGBv.mjs} +4 -4
- package/dist/{swiftpm-macos-x6HPpl_2.mjs → swiftpm-macos-Ch4YjY_A.mjs} +11 -12
- package/dist/{toolchain-J4J8MrAr.mjs → toolchain-CbCG6C5Z.mjs} +321 -15
- package/dist/{toolchain-DoavrvIA.mjs → toolchain-JYAOquPg.mjs} +1 -1
- package/dist/{trigger-KVaWWNyn.mjs → trigger-DMou-X7j.mjs} +2 -2
- package/dist/trigger-qp2ji5wE.mjs +2 -0
- package/dist/{warm-progress-DvhTX_eu.mjs → warm-progress-C0RsbngN.mjs} +731 -727
- package/dist/{web-Bihbf7-u.mjs → web-Cq_AQ4DK.mjs} +9 -9
- package/dist/web-Je6abcpz.mjs +2 -0
- package/dist/web-run.mjs +9 -9
- package/dist/windows-report.mjs +1 -1
- package/dist/{workspace-state-pUg3_RRA.mjs → workspace-state-BjqdjnJR.mjs} +3 -3
- package/dist/{workspaces-g2lhdBXF.mjs → workspaces-DFbj07jp.mjs} +1795 -70
- package/dist/{worktree-BKuklFh_.mjs → worktree-COAJ3-OD.mjs} +934 -514
- package/dist/{worktree-Bm4cb-nU.mjs → worktree-JGUd_53L.mjs} +1 -1
- package/package.json +7 -7
- package/dist/ccache-Bx5TbxwG.mjs +0 -143
- package/dist/eas-fallback-FwkeqqGi.mjs +0 -381
- package/dist/hosted-ios-D55QhYaD.mjs +0 -15
- package/dist/native-run-BfIDFKLH.mjs +0 -275
- package/dist/server-expo-wvcj5tiZ.mjs +0 -2
- package/dist/settings-write-QjYfSrjF.mjs +0 -360
- package/dist/trigger-DzJu208Q.mjs +0 -2
- package/dist/web-BFLueSh-.mjs +0 -2
|
@@ -1,62 +1,41 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { j as workspaceStateFile$1, k as workspaceLogsDir$1, r as readWorkspaceState$1, u as workspaceLastUsed } from "./workspace-state-
|
|
3
|
-
import { F as isOnMountedVolume, G as projectDeviceSlots, I as listMountedVolumes, L as measuredDirectorySizeAsync, N as directorySizeAsync, P as formatBytes, _ as loadConfig$1, p as getProject } from "./config-
|
|
4
|
-
import { o as formatLongDuration, u as plural } from "./command-output-
|
|
5
|
-
import { c as gitQuiet, l as gitQuietAsync, n as runOperationFileQuiet, r as childEnvironment } from "./operation-exec-
|
|
6
|
-
import {
|
|
7
|
-
import { i as findProjectRoot$1 } from "./project-
|
|
8
|
-
import { F as listAvdsAsync, G as ownedAvdSerialResolverAsync, P as listAvds, V as ownedAvdDirectory, yt as readParked } from "./android-
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
1
|
+
import { l as WorkspaceProcessCleanupError, n as isTimeoutError, t as getExecutor } from "./exec-aULwtNly.mjs";
|
|
2
|
+
import { j as workspaceStateFile$1, k as workspaceLogsDir$1, r as readWorkspaceState$1, u as workspaceLastUsed } from "./workspace-state-BjqdjnJR.mjs";
|
|
3
|
+
import { F as isOnMountedVolume, G as projectDeviceSlots, I as listMountedVolumes, L as measuredDirectorySizeAsync, N as directorySizeAsync, P as formatBytes, _ as loadConfig$1, p as getProject } from "./config-Cn94Jc0g.mjs";
|
|
4
|
+
import { o as formatLongDuration, u as plural } from "./command-output-Dj-WT4BP.mjs";
|
|
5
|
+
import { c as gitQuiet, l as gitQuietAsync, n as runOperationFileQuiet, r as childEnvironment } from "./operation-exec-Dp4FuIGR.mjs";
|
|
6
|
+
import { At as listWorktreesAsync, Bt as resolveSourceCheckoutAsync, Ct as hasPopulatedSubmodulesAsync, Ht as sourceCheckoutOf, O as maintenanceKeepSetting, Tt as hasUncommittedWorkAsync, Ut as unpushedCommitsAsync, X as resolveProjectSettings, Z as resolveProjectSettingsAsync, h as deviceIdleShutdownMinutesSetting, kt as listWorktrees, tn as removeTemporaryEntryAsync, yt as dirtyPathsAsync, zt as resolveFullRefAsync } from "./settings-BDVI8Ivc.mjs";
|
|
7
|
+
import { i as findProjectRoot$1 } from "./project-DYj-HVx6.mjs";
|
|
8
|
+
import { F as listAvdsAsync, G as ownedAvdSerialResolverAsync, P as listAvds, V as ownedAvdDirectory, yt as readParked } from "./android-DriNoAVy.mjs";
|
|
9
|
+
import { A as diskPressureLevel, G as planCacheEmptying, N as lowestFree, P as protectWindowMs, X as collectGradleVersions, Z as deleteGradleVersion, Zn as collectMemoryReport, _ as resolveBudget, at as DEVICE_LIST_TIMEOUT_MS, ct as collectParkedSims, d as enforceBudget, dr as pruneCache, dt as deleteProjectDevices, j as levelFloors, lt as deleteParkedAvds, mt as deviceSweepIsScoped, nr as memorySweepIsScoped, nt as waitForGradleExit, or as stopIdleGradleDaemons, p as machineNumber, sr as phase, st as collectParkedAvds, u as cacheLabel, ur as discoverCaches, ut as deleteParkedSims, v as trimmableCaches, vt as findStaleProjectDevices, y as stopOwnedMetro, z as emptyCaches } from "./ccache-BWTze1Ls.mjs";
|
|
10
|
+
import { a as unregister, n as readManifest } from "./cache-manifest-DEjqGGat.mjs";
|
|
11
|
+
import { Dt as readConcurrency, L as workspaceBuildInProgress, M as collectOwnedDeviceActivityAsync, St as GC_OUTPUT, Tt as eachLimited, _ as withIdleWorkspace, a as collectOrphanedWorkspaces, c as isInsideWorkspaces, h as ARTIFACT_DIRS, i as clearWorkspaceOutputs, j as collectOwnedDeviceActivity, l as listWorkspaceDirs, m as workspaceDirRemoved, o as collectWorkspaceOutputs, p as workspaceBuildReasons, s as deleteOrphanedWorkspaces, t as LIGHTEN_AFTER_MS, u as recentNativeUseReason, v as workspaceInUse, wt as takeGcResults, y as workspaceInUseAsync } from "./workspaces-DFbj07jp.mjs";
|
|
11
12
|
import { t as canonicalPath } from "./paths-BsJMoPP2.mjs";
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import { d as listAllIosSims, f as listAllIosSimsAsync } from "./ios-WxpDJ5T1.mjs";
|
|
13
|
+
import { N as listBuildLocks, _ as workspaceDeviceLastUseAt, b as leaseIsExpired, g as workspaceActivity, x as listLeaseFiles } from "./activity-Cd-ysFes.mjs";
|
|
14
|
+
import { d as listAllIosSims, f as listAllIosSimsAsync } from "./ios-E26qSpkb.mjs";
|
|
15
15
|
import { s as metroStoreRoot } from "./errors-DHm_U5gv.mjs";
|
|
16
16
|
import { t as resolveMaintenanceSettings } from "./settings-Djl-mpjX.mjs";
|
|
17
|
-
import { i as
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
17
|
+
import { D as stimCliEntries, E as serviceRunningFrom, N as worktreeArchiveLimits, O as stimCliUseOf, S as measurePressureAsync, T as uncommittedActivityOf, a as matchWorktreeEntry, b as measureDiskAsync, c as reclaimKeys, i as excludeWatchmanCookies, m as removeWorktreeTarget, o as nestedWorktrees, r as excludePodChurn, s as porcelainPath, v as cacheBlocked, x as measurePressure, y as measureDisk } from "./worktree-COAJ3-OD.mjs";
|
|
18
|
+
import { n as describePullRequest, r as endedPullRequest, s as pullRequestLookups } from "./pull-request-BzLmzAIQ.mjs";
|
|
19
|
+
import { a as lastFetchedAtAsync, c as mergeStateAsync, f as recordPullRequestLookup, i as fetchDefaultBranchAsync, o as localDefaultBranchAsync, r as FETCH_FRESH_MS } from "./warm-progress-C0RsbngN.mjs";
|
|
20
|
+
import { a as restoreProblem, r as recordLightened, t as finishLightened } from "./lightened-BCsdAGj_.mjs";
|
|
21
|
+
import { i as writeIdleShutdownEvent, n as dueIdleDevices, r as shutDownIdleDevices } from "./idle-shutdown-Cbvo5KEh.mjs";
|
|
21
22
|
import { readClaimSet } from "@stim-cli/core/ownership-claim";
|
|
22
|
-
import { existsSync, lstatSync, readdirSync, realpathSync, rmSync, statSync } from "node:fs";
|
|
23
|
+
import { existsSync, lstatSync, readdirSync, readlinkSync, realpathSync, rmSync, statSync } from "node:fs";
|
|
23
24
|
import { tmpdir } from "node:os";
|
|
24
25
|
import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
25
26
|
import { buildCacheRoot, configDir, metroCacheRoot } from "@stim-cli/core";
|
|
26
|
-
import { LAST_BUILD_KEYS, MAINTENANCE_LOG_NAME, loadConfig, readBuildHistory, readMaintenanceState, readPullRequestCache, settingDefinition, sharedCompilationCache } from "@stim-cli/core/state";
|
|
27
|
+
import { LAST_BUILD_KEYS, MAINTENANCE_LOG_NAME, lastNativeUseFrom, loadConfig, readBuildHistory, readMaintenanceState, readPullRequestCache, settingDefinition, sharedCompilationCache } from "@stim-cli/core/state";
|
|
27
28
|
import { isAbsolute as isAbsolute$1, join as join$1 } from "path";
|
|
28
29
|
import chalk from "chalk";
|
|
29
30
|
import { existsSync as existsSync$1, readdirSync as readdirSync$1, statSync as statSync$1 } from "fs";
|
|
30
31
|
import { lstat, readdir, realpath, rename, stat } from "node:fs/promises";
|
|
31
|
-
//#region src/commands/gc/limited.ts
|
|
32
|
-
const isCleanupFailure = (error) => error instanceof WorkspaceProcessCleanupError || error instanceof Error && "reportCleanup" in error;
|
|
33
|
-
async function eachLimited(items, limit, run) {
|
|
34
|
-
const queue = items[Symbol.iterator]();
|
|
35
|
-
let failed = false;
|
|
36
|
-
const worker = async () => {
|
|
37
|
-
for (const item of queue) {
|
|
38
|
-
if (failed) return;
|
|
39
|
-
try {
|
|
40
|
-
await run(item);
|
|
41
|
-
} catch (error) {
|
|
42
|
-
failed = true;
|
|
43
|
-
throw error;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
const errors = (await Promise.allSettled(Array.from({ length: Math.min(limit, items.length) }, worker))).flatMap((result) => result.status === "rejected" ? [result.reason] : []);
|
|
48
|
-
if (errors.length) throw errors.find(isCleanupFailure) ?? errors[0];
|
|
49
|
-
}
|
|
50
|
-
function readConcurrency(operation) {
|
|
51
|
-
return operationState(operation).declaring.size ? 1 : 6;
|
|
52
|
-
}
|
|
53
|
-
//#endregion
|
|
54
32
|
//#region src/commands/gc/worktrees.ts
|
|
55
33
|
const DEFAULT_WORKTREE_IDLE_DAYS = 7;
|
|
56
34
|
const DIRTY_PATHS_SHOWN = 3;
|
|
57
35
|
const DAY_MS = 864e5;
|
|
58
36
|
const MINUTE_MS = 6e4;
|
|
59
37
|
const GRACE_SETTING = "gc.worktreeGraceMinutes";
|
|
38
|
+
const PROTECT_SETTING = "maintenance.protectRecentHours";
|
|
60
39
|
const NO_OWN_COMMITS_PRESSURE_FLOOR_MS = 5 * MINUTE_MS;
|
|
61
40
|
const PULL_REQUEST_NOT_CHECKED = "not checked since the last maintenance worktree check";
|
|
62
41
|
const WORKTREE_CHECK_SETTING = "maintenance.worktreeCheckMinutes";
|
|
@@ -101,6 +80,18 @@ function noOwnCommitsActivityBlocker(activity, idleMs, now) {
|
|
|
101
80
|
eligibleAt
|
|
102
81
|
};
|
|
103
82
|
}
|
|
83
|
+
function dirtyLines(porcelain) {
|
|
84
|
+
return excludePodChurn(excludeWatchmanCookies(porcelain).lines).lines;
|
|
85
|
+
}
|
|
86
|
+
function finished(facts) {
|
|
87
|
+
return Boolean(facts.merge?.merged || endedPullRequest(facts.pullRequest));
|
|
88
|
+
}
|
|
89
|
+
function openPullRequest(lookup) {
|
|
90
|
+
return Boolean(lookup && "pullRequest" in lookup && lookup.pullRequest?.state === "open");
|
|
91
|
+
}
|
|
92
|
+
function newerActivity(a, b) {
|
|
93
|
+
return a && b ? b.at > a.at ? b : a : a ?? b;
|
|
94
|
+
}
|
|
104
95
|
function hasNoOwnCommits(merge) {
|
|
105
96
|
return merge?.merged === false && merge.noOwnCommits === true;
|
|
106
97
|
}
|
|
@@ -139,11 +130,16 @@ function removalBlocker(facts, olderThan, now, noOwnCommitsIdleMs) {
|
|
|
139
130
|
if (facts.nested?.length) return skip("nested-worktree", `contains the worktree ${facts.nested.join(", ")}`);
|
|
140
131
|
if (facts.inUse.length) return skip("in-use", `in use: ${facts.inUse.join("; ")}`);
|
|
141
132
|
if (facts.porcelain === null) return skip("status-unreadable", "git status could not be read");
|
|
142
|
-
const dirty =
|
|
133
|
+
const dirty = dirtyLines(facts.porcelain);
|
|
143
134
|
if (dirty.length) {
|
|
144
135
|
const paths = dirty.slice(0, DIRTY_PATHS_SHOWN).flatMap((line) => porcelainPath(line) ?? []);
|
|
145
136
|
const more = dirty.length > DIRTY_PATHS_SHOWN ? ", ..." : "";
|
|
146
|
-
|
|
137
|
+
const kept = skip("dirty", `dirty: ${plural(dirty.length, "uncommitted or untracked file")} (${paths.join(", ")}${more})`);
|
|
138
|
+
if (!facts.archiveDirty) return kept;
|
|
139
|
+
return removalBlocker({
|
|
140
|
+
...facts,
|
|
141
|
+
porcelain: []
|
|
142
|
+
}, olderThan, now, noOwnCommitsIdleMs) === null && finished(facts) ? null : kept;
|
|
147
143
|
}
|
|
148
144
|
if (facts.unpushed === null) return skip("unpushed-unchecked", "unpushed commits could not be checked");
|
|
149
145
|
const merged = facts.merge?.merged ? facts.merge : null;
|
|
@@ -154,17 +150,9 @@ function removalBlocker(facts, olderThan, now, noOwnCommitsIdleMs) {
|
|
|
154
150
|
if (merged || ended) return null;
|
|
155
151
|
const notMerged = facts.merge && !facts.merge.merged ? facts.merge : null;
|
|
156
152
|
const details = [notMerged?.detail, pullRequestNote(facts.pullRequest)].filter(Boolean);
|
|
157
|
-
|
|
158
|
-
if (olderThan === null)
|
|
159
|
-
if (noOwnCommits && noOwnCommitsIdleMs !== null) return noOwnCommitsActivityBlocker(facts.activity, noOwnCommitsIdleMs, now);
|
|
160
|
-
return skip(notMerged?.unknown ? "merge-unknown" : "not-merged", details.join("; ") || "not merged");
|
|
161
|
-
}
|
|
153
|
+
if (hasNoOwnCommits(notMerged) && !openPullRequest(facts.pullRequest) && noOwnCommitsIdleMs !== null) return noOwnCommitsActivityBlocker(facts.activity, noOwnCommitsIdleMs, now);
|
|
154
|
+
if (olderThan === null) return skip(notMerged?.unknown ? "merge-unknown" : "not-merged", details.join("; ") || "not merged");
|
|
162
155
|
const also = details.map((detail) => `; ${detail}`).join("");
|
|
163
|
-
if (facts.idleDays === null && noOwnCommits && facts.activity) {
|
|
164
|
-
const days = activityIdleDays(facts.activity, now);
|
|
165
|
-
if (days < olderThan) return skip("recently-used", `recently active: ${facts.activity.basis} ${days}d ago${also}`);
|
|
166
|
-
return null;
|
|
167
|
-
}
|
|
168
156
|
if (facts.idleDays === null) return skip("last-use-unknown", `recently used: its last use is unknown${also}`);
|
|
169
157
|
if (facts.idleDays < olderThan) return skip("recently-used", `recently used ${facts.idleDays}d ago${also}`);
|
|
170
158
|
return null;
|
|
@@ -176,11 +164,16 @@ function removalBlocker(facts, olderThan, now, noOwnCommitsIdleMs) {
|
|
|
176
164
|
*/
|
|
177
165
|
function worktreeRemovalReason(candidate, sweep) {
|
|
178
166
|
const { merge, activity } = candidate;
|
|
179
|
-
|
|
167
|
+
const archived = candidate.dirty ? `, ${plural(candidate.dirty, "uncommitted file")} archived first` : "";
|
|
168
|
+
if (merge?.merged) return `merged into ${merge.into}${archived}`;
|
|
180
169
|
const ended = endedPullRequest(candidate.pullRequest);
|
|
181
|
-
if (ended) return describePullRequest(ended)
|
|
170
|
+
if (ended) return `${describePullRequest(ended)}${archived}`;
|
|
182
171
|
if (merge && hasNoOwnCommits(merge)) {
|
|
183
|
-
if (sweep.noOwnCommitsIdleMs !== null && activity)
|
|
172
|
+
if (sweep.noOwnCommitsIdleMs !== null && activity) {
|
|
173
|
+
const age = Math.max(0, sweep.now - activity.at);
|
|
174
|
+
if (sweep.underPressure) return `${merge.detail}, inactive for ${formatLongDuration(age)} under disk pressure`;
|
|
175
|
+
return age >= DAY_MS ? `${merge.detail}, idle ${activityIdleDays(activity, sweep.now)}d` : `${merge.detail}, inactive for ${formatLongDuration(age)}`;
|
|
176
|
+
}
|
|
184
177
|
const days = candidate.idleDays ?? (activity ? activityIdleDays(activity, sweep.now) : null);
|
|
185
178
|
return days === null ? merge.detail : `${merge.detail}, idle ${days}d`;
|
|
186
179
|
}
|
|
@@ -366,6 +359,10 @@ function activityFromGitDir(gitDir, keys) {
|
|
|
366
359
|
const newest = newestMtime(paths);
|
|
367
360
|
return newest === "unreadable" ? null : newest;
|
|
368
361
|
}
|
|
362
|
+
function protectRecentMs(operation) {
|
|
363
|
+
const { value, error } = machineNumber(PROTECT_SETTING, loadConfig$1(), operation?.env ?? process.env);
|
|
364
|
+
return (error ? Number(settingDefinition(PROTECT_SETTING)?.default) : value ?? 0) * 60 * MINUTE_MS;
|
|
365
|
+
}
|
|
369
366
|
function graceMsSetting(operation) {
|
|
370
367
|
const { value, error } = machineNumber(GRACE_SETTING, loadConfig$1(), operation?.env ?? process.env);
|
|
371
368
|
if (error) {
|
|
@@ -493,22 +490,25 @@ async function checkMergeStates(pending, idle, grace, noOwnCommitsIdleMs, refres
|
|
|
493
490
|
}
|
|
494
491
|
}
|
|
495
492
|
/**
|
|
496
|
-
* Classifies each linked worktree of a registered project or its repository. A merged one is removable
|
|
497
|
-
*
|
|
498
|
-
*
|
|
493
|
+
* Classifies each linked worktree of a registered project or its repository. A merged one is removable, a dirty one
|
|
494
|
+
* after archiving its uncommitted work when archives are on; with `idle`, so is one unused for `olderThan` days. One
|
|
495
|
+
* with no commits of its own beyond the default branch is removable once its last activity is older than the grace
|
|
496
|
+
* period and `maintenance.protectRecentHours`, or, `underPressure`, than the grace period alone; never younger than 5
|
|
497
|
+
* minutes. Device use is read last, in one pass against one simulator list and one AVD resolver, so
|
|
499
498
|
* the resolver's time budget covers only device reads. Pull requests are asked once per repository, sequentially
|
|
500
499
|
* with an operation and concurrently otherwise. Merge state is checked only where it decides the verdict, after one fetch per repository.
|
|
501
500
|
* Without `refresh`, it runs no fetch and no `gh`: merge state comes from the existing remote-tracking ref and pull
|
|
502
501
|
* requests from the cache `status --watch` writes, and a kept verdict that fresher state could change says so.
|
|
503
502
|
*/
|
|
504
|
-
async function collectWorktreeSweep({ idle, olderThan, now, graceMs,
|
|
503
|
+
async function collectWorktreeSweep({ idle, olderThan, now, graceMs, underPressure = false, refresh = true, operation }) {
|
|
505
504
|
const days = idle ? olderThan ?? DEFAULT_WORKTREE_IDLE_DAYS : null;
|
|
506
505
|
const grace = {
|
|
507
506
|
ms: graceMs ?? graceMsSetting(operation),
|
|
508
507
|
now
|
|
509
508
|
};
|
|
510
509
|
const freshMs = refresh ? 0 : reportFreshMs(operation);
|
|
511
|
-
const noOwnCommitsIdleMs =
|
|
510
|
+
const noOwnCommitsIdleMs = Math.max(grace.ms, underPressure ? 0 : protectRecentMs(operation), NO_OWN_COMMITS_PRESSURE_FLOOR_MS);
|
|
511
|
+
const cli = stimCliEntries(operation?.env);
|
|
512
512
|
const groups = /* @__PURE__ */ new Map();
|
|
513
513
|
operation?.signal.throwIfAborted();
|
|
514
514
|
const read = {
|
|
@@ -551,22 +551,29 @@ async function collectWorktreeSweep({ idle, olderThan, now, graceMs, removesNoOw
|
|
|
551
551
|
const keys = [.../* @__PURE__ */ new Set([...roots, ...reclaimKeys(path)])];
|
|
552
552
|
const idleDays = idleDaysOf(keys, now);
|
|
553
553
|
const linked = !("refusal" in source) && entry !== null && source.path !== entry.path;
|
|
554
|
-
const
|
|
555
|
-
const
|
|
554
|
+
const porcelain = await porcelainOf(path, linked ? await unlessTimedOut(() => hasUncommittedWorkAsync(path, read), null) : null, operation);
|
|
555
|
+
const dirty = linked ? dirtyLines(porcelain).length : 0;
|
|
556
|
+
const archiveDirty = dirty > 0 && !underPressure && !("refusal" in worktreeArchiveLimits(path, operation?.env));
|
|
557
|
+
let activity = linked ? await worktreeActivityOfAsync(path, keys, operation) : null;
|
|
558
|
+
if (activity && archiveDirty) {
|
|
559
|
+
const edited = await uncommittedActivityOf(path, operation);
|
|
560
|
+
activity = edited === "unreadable" ? null : newerActivity(activity, edited);
|
|
561
|
+
}
|
|
556
562
|
const head = linked ? await resolveFullRefAsync(path, "HEAD", read) : null;
|
|
557
563
|
const facts = {
|
|
558
564
|
source: "refusal" in source ? source : linked ? "linked" : "source",
|
|
559
565
|
bare: Boolean(entry?.bare),
|
|
560
566
|
locked: Boolean(entry?.locked),
|
|
561
567
|
nested: entry ? nestedWorktrees(entries, entry.path) : [],
|
|
562
|
-
porcelain
|
|
568
|
+
porcelain,
|
|
563
569
|
unpushed: linked ? await unlessTimedOut(() => unpushedCommitsAsync(path, read), null) : null,
|
|
564
570
|
submodules: linked ? await unlessTimedOut(() => hasPopulatedSubmodulesAsync(path, read), null) : false,
|
|
565
|
-
inUse: [],
|
|
571
|
+
inUse: linked ? stimCliUseOf(path, canonicalPath, cli) : [],
|
|
566
572
|
idleDays,
|
|
567
573
|
merge: null,
|
|
568
574
|
pullRequest: null,
|
|
569
|
-
activity
|
|
575
|
+
activity,
|
|
576
|
+
archiveDirty
|
|
570
577
|
};
|
|
571
578
|
inspected[index] = {
|
|
572
579
|
candidate: {
|
|
@@ -579,7 +586,8 @@ async function collectWorktreeSweep({ idle, olderThan, now, graceMs, removesNoOw
|
|
|
579
586
|
skipCode: null,
|
|
580
587
|
skipped: null,
|
|
581
588
|
eligibleAt: null,
|
|
582
|
-
activity
|
|
589
|
+
activity,
|
|
590
|
+
...archiveDirty ? { dirty } : {}
|
|
583
591
|
},
|
|
584
592
|
facts,
|
|
585
593
|
repo: "refusal" in source ? null : source.path,
|
|
@@ -602,7 +610,7 @@ async function collectWorktreeSweep({ idle, olderThan, now, graceMs, removesNoOw
|
|
|
602
610
|
skipped: verdict?.text ?? null,
|
|
603
611
|
eligibleAt: verdict?.eligibleAt ?? null
|
|
604
612
|
});
|
|
605
|
-
if (verdict && MERGE_DECIDES.has(verdict.code) && repo !== null) pending.push({
|
|
613
|
+
if (verdict && (MERGE_DECIDES.has(verdict.code) || verdict.code === "dirty" && facts.archiveDirty) && repo !== null) pending.push({
|
|
606
614
|
candidate,
|
|
607
615
|
facts,
|
|
608
616
|
repo
|
|
@@ -619,6 +627,7 @@ async function collectWorktreeSweep({ idle, olderThan, now, graceMs, removesNoOw
|
|
|
619
627
|
graceMs: grace.ms,
|
|
620
628
|
now,
|
|
621
629
|
noOwnCommitsIdleMs,
|
|
630
|
+
underPressure,
|
|
622
631
|
worktrees: listed
|
|
623
632
|
};
|
|
624
633
|
}
|
|
@@ -686,16 +695,8 @@ function cachedPullRequest(cached, branch, head, now, freshMs) {
|
|
|
686
695
|
} };
|
|
687
696
|
}
|
|
688
697
|
async function noOwnCommitsRecheck(sweep, path, keys, now, operation) {
|
|
689
|
-
if (
|
|
690
|
-
|
|
691
|
-
return noOwnCommitsActivityBlocker(await worktreeActivityOfAsync(path, keys, operation), sweep.noOwnCommitsIdleMs, now)?.text ?? null;
|
|
692
|
-
}
|
|
693
|
-
const idleDays = idleDaysOf(keys, now);
|
|
694
|
-
if (idleDays !== null) return idleDays < sweep.idle.olderThan ? `used ${idleDays}d ago since gc checked it` : null;
|
|
695
|
-
const activity = await worktreeActivityOfAsync(path, keys, operation);
|
|
696
|
-
if (!activity) return "its last activity could not be read";
|
|
697
|
-
const days = activityIdleDays(activity, now);
|
|
698
|
-
return days < sweep.idle.olderThan ? `active ${days}d ago since gc checked it: ${activity.basis}` : null;
|
|
698
|
+
if (sweep.noOwnCommitsIdleMs === null) return "it has no commits of its own and is not idle";
|
|
699
|
+
return noOwnCommitsActivityBlocker(await worktreeActivityOfAsync(path, keys, operation), sweep.noOwnCommitsIdleMs, now)?.text ?? null;
|
|
699
700
|
}
|
|
700
701
|
async function removeWorktrees(sweep, { now = Date.now(), operation } = {}, output = GC_OUTPUT) {
|
|
701
702
|
let failures = 0;
|
|
@@ -707,7 +708,11 @@ async function removeWorktrees(sweep, { now = Date.now(), operation } = {}, outp
|
|
|
707
708
|
const keys = [.../* @__PURE__ */ new Set([...candidate.keys, ...lockedKeys])];
|
|
708
709
|
const unlocked = keys.filter((key) => !lockedKeys.includes(key));
|
|
709
710
|
const devices = await reportDeviceReads(keys, operation);
|
|
710
|
-
const reasons = [
|
|
711
|
+
const reasons = [
|
|
712
|
+
...stimCliUseOf(candidate.path, canonicalPath, stimCliEntries(operation?.env)),
|
|
713
|
+
...await inUseOf(lockedKeys, { managedLocks: false }, devices, operation?.signal, operation),
|
|
714
|
+
...await inUseOf(unlocked, { managedLocks: true }, devices, operation?.signal, operation)
|
|
715
|
+
].map((r) => `in use: ${r}`);
|
|
711
716
|
const mergedHead = candidate.merge?.merged ? candidate.merge.head : endedPullRequest(candidate.pullRequest) ? candidate.head : null;
|
|
712
717
|
if (mergedHead) {
|
|
713
718
|
if (await resolveFullRefAsync(candidate.path, "HEAD", {
|
|
@@ -728,10 +733,12 @@ async function removeWorktrees(sweep, { now = Date.now(), operation } = {}, outp
|
|
|
728
733
|
if (idleDays === null || !sweep.idle || idleDays < sweep.idle.olderThan) reasons.push(`used ${idleDays === null ? "at an unknown time" : `${idleDays}d ago`} since gc checked it`);
|
|
729
734
|
}
|
|
730
735
|
if (sweep.graceMs > 0) {
|
|
736
|
+
const activity = await worktreeActivityOfAsync(candidate.path, keys, operation);
|
|
737
|
+
const edited = candidate.dirty && activity ? await uncommittedActivityOf(candidate.path, operation) : null;
|
|
731
738
|
const recent = graceBlocker({
|
|
732
739
|
merge: candidate.merge,
|
|
733
740
|
pullRequest: candidate.pullRequest,
|
|
734
|
-
activity:
|
|
741
|
+
activity: edited === "unreadable" ? null : newerActivity(activity, edited)
|
|
735
742
|
}, {
|
|
736
743
|
ms: sweep.graceMs,
|
|
737
744
|
now: Date.now()
|
|
@@ -743,6 +750,7 @@ async function removeWorktrees(sweep, { now = Date.now(), operation } = {}, outp
|
|
|
743
750
|
};
|
|
744
751
|
let removed = false;
|
|
745
752
|
let error = null;
|
|
753
|
+
const archived = { archive: null };
|
|
746
754
|
try {
|
|
747
755
|
const ended = endedPullRequest(candidate.pullRequest);
|
|
748
756
|
const mergedHead = candidate.merge?.merged && candidate.merge.coversUnpushed ? candidate.merge.head : ended?.state === "merged" ? candidate.head ?? void 0 : void 0;
|
|
@@ -753,7 +761,17 @@ async function removeWorktrees(sweep, { now = Date.now(), operation } = {}, outp
|
|
|
753
761
|
mergedHead,
|
|
754
762
|
expectedHead,
|
|
755
763
|
output,
|
|
756
|
-
operation
|
|
764
|
+
operation,
|
|
765
|
+
...candidate.dirty ? { archiveDirty: {
|
|
766
|
+
pullRequest: ended ? {
|
|
767
|
+
number: ended.number,
|
|
768
|
+
url: ended.url,
|
|
769
|
+
state: ended.state
|
|
770
|
+
} : null,
|
|
771
|
+
onArchived: (saved) => {
|
|
772
|
+
archived.archive = saved;
|
|
773
|
+
}
|
|
774
|
+
} } : {}
|
|
757
775
|
});
|
|
758
776
|
} catch (thrown) {
|
|
759
777
|
if (thrown instanceof WorkspaceProcessCleanupError || thrown instanceof Error && "reportCleanup" in thrown) throw thrown;
|
|
@@ -762,8 +780,16 @@ async function removeWorktrees(sweep, { now = Date.now(), operation } = {}, outp
|
|
|
762
780
|
output.error(chalk.red(`Could not remove ${candidate.path}: ${error}`));
|
|
763
781
|
}
|
|
764
782
|
if (removed) {
|
|
765
|
-
|
|
766
|
-
|
|
783
|
+
const saved = archived.archive;
|
|
784
|
+
const reason = saved ? `${worktreeRemovalReason({
|
|
785
|
+
...candidate,
|
|
786
|
+
dirty: 0
|
|
787
|
+
}, sweep)}; archived ${plural(saved.tracked.length + saved.untracked.length, "uncommitted file")} to ${saved.dir}; restore: ${saved.restore.join(" && ")}` : worktreeRemovalReason({
|
|
788
|
+
...candidate,
|
|
789
|
+
dirty: 0
|
|
790
|
+
}, sweep);
|
|
791
|
+
output.log(chalk.green(`Removed the worktree ${candidate.path} (${reason})`));
|
|
792
|
+
output.record("worktree", "done", candidate.path, { detail: reason });
|
|
767
793
|
} else if (kept.length) {
|
|
768
794
|
output.log(chalk.yellow(`Kept the worktree ${candidate.path}: ${kept.join("; ")}`));
|
|
769
795
|
output.record("worktree", "kept", candidate.path, { detail: kept.join("; ") });
|
|
@@ -1399,7 +1425,7 @@ async function planWorktrees({ protectedRoot, pinned, now, level, graceMs, sizes
|
|
|
1399
1425
|
idle: idleDays !== null,
|
|
1400
1426
|
olderThan: idleDays,
|
|
1401
1427
|
now,
|
|
1402
|
-
|
|
1428
|
+
underPressure: level === 3,
|
|
1403
1429
|
operation,
|
|
1404
1430
|
...graceMs === void 0 ? {} : { graceMs },
|
|
1405
1431
|
...refresh === void 0 ? {} : { refresh }
|
|
@@ -1455,18 +1481,118 @@ async function planWorktrees({ protectedRoot, pinned, now, level, graceMs, sizes
|
|
|
1455
1481
|
};
|
|
1456
1482
|
}
|
|
1457
1483
|
//#endregion
|
|
1484
|
+
//#region src/workspace/running-from.ts
|
|
1485
|
+
const LIST_TIMEOUT_MS = 1e4;
|
|
1486
|
+
function parsePs(text) {
|
|
1487
|
+
return text.split("\n").flatMap((row) => {
|
|
1488
|
+
const match = /^\s*(\d+)\s+(.*)$/.exec(row);
|
|
1489
|
+
return match ? [{
|
|
1490
|
+
pid: Number(match[1]),
|
|
1491
|
+
line: match[2] ?? ""
|
|
1492
|
+
}] : [];
|
|
1493
|
+
});
|
|
1494
|
+
}
|
|
1495
|
+
/** `lsof -Fpn` output: a `p<pid>` line, then the `n<path>` of its working directory. */
|
|
1496
|
+
function parseLsof(text) {
|
|
1497
|
+
const cwds = [];
|
|
1498
|
+
let pid = 0;
|
|
1499
|
+
for (const row of text.split("\n")) if (row.startsWith("p")) pid = Number(row.slice(1));
|
|
1500
|
+
else if (row.startsWith("n") && pid) cwds.push({
|
|
1501
|
+
pid,
|
|
1502
|
+
path: row.slice(1)
|
|
1503
|
+
});
|
|
1504
|
+
return cwds;
|
|
1505
|
+
}
|
|
1506
|
+
function procCwds() {
|
|
1507
|
+
try {
|
|
1508
|
+
return readdirSync("/proc").filter((name) => /^\d+$/.test(name)).flatMap((name) => {
|
|
1509
|
+
try {
|
|
1510
|
+
return [{
|
|
1511
|
+
pid: Number(name),
|
|
1512
|
+
path: readlinkSync(join("/proc", name, "cwd"))
|
|
1513
|
+
}];
|
|
1514
|
+
} catch {
|
|
1515
|
+
return [];
|
|
1516
|
+
}
|
|
1517
|
+
});
|
|
1518
|
+
} catch {
|
|
1519
|
+
return null;
|
|
1520
|
+
}
|
|
1521
|
+
}
|
|
1522
|
+
function listsSelf(list) {
|
|
1523
|
+
return list.some(({ pid }) => pid === process.pid);
|
|
1524
|
+
}
|
|
1525
|
+
function runningFrom(ps, cwds) {
|
|
1526
|
+
if (ps === null || cwds === null) return null;
|
|
1527
|
+
const commands = parsePs(ps);
|
|
1528
|
+
return listsSelf(commands) && listsSelf(cwds) ? {
|
|
1529
|
+
commands,
|
|
1530
|
+
cwds
|
|
1531
|
+
} : null;
|
|
1532
|
+
}
|
|
1533
|
+
const PS_ARGS = [
|
|
1534
|
+
"-axww",
|
|
1535
|
+
"-o",
|
|
1536
|
+
"pid=,args="
|
|
1537
|
+
];
|
|
1538
|
+
const LSOF_ARGS = [
|
|
1539
|
+
"-a",
|
|
1540
|
+
"-d",
|
|
1541
|
+
"cwd",
|
|
1542
|
+
"-Fpn",
|
|
1543
|
+
"-w"
|
|
1544
|
+
];
|
|
1545
|
+
function readRunningProcesses(platform = process.platform) {
|
|
1546
|
+
if (platform !== "darwin" && platform !== "linux") return null;
|
|
1547
|
+
const exec = getExecutor();
|
|
1548
|
+
const ps = exec.runFileQuiet("ps", PS_ARGS, { timeoutMs: LIST_TIMEOUT_MS });
|
|
1549
|
+
if (platform === "linux") return runningFrom(ps, procCwds());
|
|
1550
|
+
const lsof = exec.runFileQuiet("lsof", LSOF_ARGS, { timeoutMs: LIST_TIMEOUT_MS });
|
|
1551
|
+
return runningFrom(ps, lsof === null ? null : parseLsof(lsof));
|
|
1552
|
+
}
|
|
1553
|
+
async function readRunningProcessesAsync(signal, platform = process.platform) {
|
|
1554
|
+
if (platform !== "darwin" && platform !== "linux") return null;
|
|
1555
|
+
const exec = getExecutor();
|
|
1556
|
+
const ps = await exec.runFileQuietAsync("ps", PS_ARGS, {
|
|
1557
|
+
timeoutMs: LIST_TIMEOUT_MS,
|
|
1558
|
+
signal
|
|
1559
|
+
});
|
|
1560
|
+
if (platform === "linux") return runningFrom(ps, procCwds());
|
|
1561
|
+
const lsof = await exec.runFileQuietAsync("lsof", LSOF_ARGS, {
|
|
1562
|
+
timeoutMs: LIST_TIMEOUT_MS,
|
|
1563
|
+
signal
|
|
1564
|
+
});
|
|
1565
|
+
return runningFrom(ps, lsof === null ? null : parseLsof(lsof));
|
|
1566
|
+
}
|
|
1567
|
+
function stimOnPath() {
|
|
1568
|
+
const found = getExecutor().findExecutable("stim");
|
|
1569
|
+
if (!found) return null;
|
|
1570
|
+
try {
|
|
1571
|
+
return realpathSync(found);
|
|
1572
|
+
} catch {
|
|
1573
|
+
return null;
|
|
1574
|
+
}
|
|
1575
|
+
}
|
|
1576
|
+
/**
|
|
1577
|
+
* Why something installed in or running from `folder` still needs it, or null: an installed stim-server service, the
|
|
1578
|
+
* `stim` on PATH, or a live process whose command line or working directory is inside it.
|
|
1579
|
+
*/
|
|
1580
|
+
function runningFromReason(folder, running) {
|
|
1581
|
+
const root = canonicalPath(folder);
|
|
1582
|
+
const inside = (path) => path === root || path.startsWith(`${root}${sep}`);
|
|
1583
|
+
const service = serviceRunningFrom(root, canonicalPath);
|
|
1584
|
+
if (service) return `the stim-server service ${service.label} runs from it`;
|
|
1585
|
+
const stim = stimOnPath();
|
|
1586
|
+
if (stim && inside(stim)) return `the stim on PATH runs from it (${stim})`;
|
|
1587
|
+
if (!running) return "the running processes cannot be listed to prove nothing runs from it";
|
|
1588
|
+
const command = running.commands.find(({ line }) => line.includes(`${root}${sep}`));
|
|
1589
|
+
if (command) return `process ${command.pid} runs from it`;
|
|
1590
|
+
const cwd = running.cwds.find(({ path }) => inside(canonicalPath(path)));
|
|
1591
|
+
if (cwd) return `process ${cwd.pid} works in it`;
|
|
1592
|
+
return null;
|
|
1593
|
+
}
|
|
1594
|
+
//#endregion
|
|
1458
1595
|
//#region src/maintenance/artifacts.ts
|
|
1459
|
-
/** Directories that hold only what a build or an install regenerates, relative to an app or package root. */
|
|
1460
|
-
const ARTIFACT_DIRS = {
|
|
1461
|
-
build: [
|
|
1462
|
-
"ios/build",
|
|
1463
|
-
"android/app/build",
|
|
1464
|
-
"android/build",
|
|
1465
|
-
"android/.gradle",
|
|
1466
|
-
".build"
|
|
1467
|
-
],
|
|
1468
|
-
dependencies: ["node_modules", "ios/Pods"]
|
|
1469
|
-
};
|
|
1470
1596
|
const PACKAGE_PARENTS = ["apps", "packages"];
|
|
1471
1597
|
const SCAN_DEPTH = {
|
|
1472
1598
|
build: 3,
|
|
@@ -1480,6 +1606,14 @@ function isDirectory(path) {
|
|
|
1480
1606
|
return false;
|
|
1481
1607
|
}
|
|
1482
1608
|
}
|
|
1609
|
+
function pathExists(path) {
|
|
1610
|
+
try {
|
|
1611
|
+
lstatSync(path);
|
|
1612
|
+
return true;
|
|
1613
|
+
} catch {
|
|
1614
|
+
return false;
|
|
1615
|
+
}
|
|
1616
|
+
}
|
|
1483
1617
|
function artifactWorktrees() {
|
|
1484
1618
|
const found = /* @__PURE__ */ new Map();
|
|
1485
1619
|
for (const root of candidateRoots()) {
|
|
@@ -1565,8 +1699,8 @@ async function newestWriteAsync(dir, maxDepth, signal) {
|
|
|
1565
1699
|
};
|
|
1566
1700
|
return await walk(dir, 0) ? newest : null;
|
|
1567
1701
|
}
|
|
1568
|
-
function keptReason(candidate, kind, { now, windowMs, pinned, locked }, reads) {
|
|
1569
|
-
const guarded = artifactGuard(candidate, kind, pinned, locked);
|
|
1702
|
+
function keptReason(candidate, kind, { now, windowMs, pinned, locked, running }, reads) {
|
|
1703
|
+
const guarded = artifactGuard(candidate, kind, pinned, locked, running);
|
|
1570
1704
|
if (guarded) return guarded;
|
|
1571
1705
|
const { worktree, path, keys } = candidate;
|
|
1572
1706
|
const tracked = reads ? reads.tracked : gitQuiet(worktree, [
|
|
@@ -1576,15 +1710,22 @@ function keptReason(candidate, kind, { now, windowMs, pinned, locked }, reads) {
|
|
|
1576
1710
|
]);
|
|
1577
1711
|
if (tracked === null) return "git cannot tell whether it holds tracked files";
|
|
1578
1712
|
if (tracked.trim()) return "it holds files git tracks";
|
|
1713
|
+
if (kind === "build") return buildNativeUseReason(keys, now);
|
|
1579
1714
|
const activity = reads ? reads.activity : worktreeActivityOf(worktree, keys);
|
|
1580
1715
|
const written = reads ? reads.written : newestWrite(path, SCAN_DEPTH[kind]);
|
|
1581
1716
|
if (!activity || written === null) return "its last activity cannot be read";
|
|
1582
1717
|
if (now - Math.max(activity.at, written) < windowMs) return `used within the last ${Math.round(windowMs / 6e4)} minutes`;
|
|
1583
1718
|
return null;
|
|
1584
1719
|
}
|
|
1585
|
-
function
|
|
1720
|
+
function buildNativeUseReason(keys, now) {
|
|
1721
|
+
const states = keys.map((key) => readWorkspaceState$1(key)).filter((state) => state !== null);
|
|
1722
|
+
if (!states.length) return "no Stim workspace records when it last ran ios, android or macos";
|
|
1723
|
+
return recentNativeUseReason(Math.max(...states.map((state) => lastNativeUseFrom(state)).filter(Number.isFinite)), now);
|
|
1724
|
+
}
|
|
1725
|
+
function artifactGuard(candidate, kind, pinned, locked, running) {
|
|
1586
1726
|
const { worktree, path, keys } = candidate;
|
|
1587
1727
|
if (keys.some(pinned)) return "pinned by maintenance.keep";
|
|
1728
|
+
if (!pathExists(path)) return "it is already gone";
|
|
1588
1729
|
let real;
|
|
1589
1730
|
try {
|
|
1590
1731
|
real = canonicalPath(path);
|
|
@@ -1592,16 +1733,15 @@ function artifactGuard(candidate, kind, pinned, locked) {
|
|
|
1592
1733
|
return "its path cannot be resolved";
|
|
1593
1734
|
}
|
|
1594
1735
|
if (!isDirectory(path) || real !== join(canonicalPath(worktree), relative(worktree, path))) return "it or a directory above it is a link, or it lies outside its worktree";
|
|
1595
|
-
const inUse = keys.flatMap((key) => workspaceInUse(key, {
|
|
1596
|
-
supervisor: kind === "dependencies",
|
|
1597
|
-
nativeRun: key !== locked
|
|
1598
|
-
}));
|
|
1736
|
+
const inUse = keys.flatMap((key) => kind === "build" ? workspaceBuildReasons(key, { nativeRun: key !== locked }) : workspaceInUse(key, { nativeRun: key !== locked }));
|
|
1599
1737
|
if (inUse.length) return `in use: ${inUse.join("; ")}`;
|
|
1738
|
+
if (kind === "dependencies") return runningFromReason(worktree, running === void 0 ? readRunningProcesses() : running);
|
|
1600
1739
|
return null;
|
|
1601
1740
|
}
|
|
1602
1741
|
async function collectArtifactsAsync(kind, options, signal, operation) {
|
|
1603
1742
|
const candidates = [];
|
|
1604
1743
|
const skips = [];
|
|
1744
|
+
const running = kind === "dependencies" ? await readRunningProcessesAsync(signal) : null;
|
|
1605
1745
|
for (const worktree of await artifactWorktreesAsync(signal, operation)) {
|
|
1606
1746
|
if (kind === "dependencies" && !worktree.linked) continue;
|
|
1607
1747
|
const root = canonicalPath(worktree.path);
|
|
@@ -1632,7 +1772,7 @@ async function collectArtifactsAsync(kind, options, signal, operation) {
|
|
|
1632
1772
|
path,
|
|
1633
1773
|
keys: worktree.keys
|
|
1634
1774
|
};
|
|
1635
|
-
let reason = protectedHere ? "the command that started this pass runs inside its worktree" : artifactGuard(candidate, kind, options.pinned);
|
|
1775
|
+
let reason = protectedHere ? "the command that started this pass runs inside its worktree" : artifactGuard(candidate, kind, options.pinned, void 0, running);
|
|
1636
1776
|
if (!reason) {
|
|
1637
1777
|
const tracked = await gitQuietAsync(worktree.path, [
|
|
1638
1778
|
"ls-files",
|
|
@@ -1645,11 +1785,16 @@ async function collectArtifactsAsync(kind, options, signal, operation) {
|
|
|
1645
1785
|
declareFor: operation,
|
|
1646
1786
|
killSignal: "SIGKILL"
|
|
1647
1787
|
});
|
|
1648
|
-
const
|
|
1649
|
-
|
|
1788
|
+
const windowed = tracked !== null && !tracked.trim() && kind === "dependencies";
|
|
1789
|
+
const activity = windowed ? await worktreeActivityOfAsync(worktree.path, worktree.keys, operation) : null;
|
|
1790
|
+
const written = windowed ? await newestWriteAsync(path, SCAN_DEPTH[kind], signal) : null;
|
|
1791
|
+
reason = keptReason(candidate, kind, {
|
|
1792
|
+
...options,
|
|
1793
|
+
running
|
|
1794
|
+
}, {
|
|
1650
1795
|
tracked,
|
|
1651
|
-
activity
|
|
1652
|
-
written
|
|
1796
|
+
activity,
|
|
1797
|
+
written
|
|
1653
1798
|
});
|
|
1654
1799
|
}
|
|
1655
1800
|
if (reason) skips.push({
|
|
@@ -1668,6 +1813,7 @@ async function collectArtifactsAsync(kind, options, signal, operation) {
|
|
|
1668
1813
|
function collectArtifacts(kind, options) {
|
|
1669
1814
|
const candidates = [];
|
|
1670
1815
|
const skips = [];
|
|
1816
|
+
const running = kind === "dependencies" ? readRunningProcesses() : null;
|
|
1671
1817
|
for (const worktree of artifactWorktrees()) {
|
|
1672
1818
|
if (kind === "dependencies" && !worktree.linked) continue;
|
|
1673
1819
|
const root = canonicalPath(worktree.path);
|
|
@@ -1684,7 +1830,10 @@ function collectArtifacts(kind, options) {
|
|
|
1684
1830
|
path,
|
|
1685
1831
|
keys: worktree.keys
|
|
1686
1832
|
};
|
|
1687
|
-
const reason = protectedHere ? "the command that started this pass runs inside its worktree" : keptReason(candidate, kind,
|
|
1833
|
+
const reason = protectedHere ? "the command that started this pass runs inside its worktree" : keptReason(candidate, kind, {
|
|
1834
|
+
...options,
|
|
1835
|
+
running
|
|
1836
|
+
});
|
|
1688
1837
|
if (reason) skips.push({
|
|
1689
1838
|
target: path,
|
|
1690
1839
|
reason
|
|
@@ -1720,34 +1869,50 @@ async function clearArtifact(action, kind, options) {
|
|
|
1720
1869
|
path: action.target,
|
|
1721
1870
|
keys: worktree.keys
|
|
1722
1871
|
};
|
|
1872
|
+
const running = kind === "dependencies" ? await readRunningProcessesAsync() : null;
|
|
1723
1873
|
const early = keptReason(candidate, kind, {
|
|
1724
1874
|
...options,
|
|
1725
|
-
now: Date.now()
|
|
1875
|
+
now: Date.now(),
|
|
1876
|
+
running
|
|
1726
1877
|
});
|
|
1727
1878
|
if (early) return {
|
|
1728
1879
|
status: "kept",
|
|
1729
1880
|
bytes: 0,
|
|
1730
1881
|
detail: early
|
|
1731
1882
|
};
|
|
1883
|
+
const unrestorable = kind === "dependencies" ? await restoreProblem(candidate, options.restoreCache) : null;
|
|
1884
|
+
if (unrestorable && options.requireRestorable) return {
|
|
1885
|
+
status: "kept",
|
|
1886
|
+
bytes: 0,
|
|
1887
|
+
detail: unrestorable
|
|
1888
|
+
};
|
|
1732
1889
|
const before = lowestFree(measureDisk());
|
|
1733
1890
|
const [key] = candidate.keys;
|
|
1734
|
-
const remove = () => {
|
|
1891
|
+
const remove = async () => {
|
|
1735
1892
|
const reason = keptReason(candidate, kind, {
|
|
1736
1893
|
...options,
|
|
1737
1894
|
now: Date.now(),
|
|
1895
|
+
running: kind === "dependencies" ? await readRunningProcessesAsync() : null,
|
|
1738
1896
|
...key ? { locked: key } : {}
|
|
1739
1897
|
});
|
|
1740
1898
|
if (reason) return reason;
|
|
1899
|
+
const record = kind === "dependencies" && !unrestorable;
|
|
1900
|
+
if (record) recordLightened(candidate.keys, candidate.path);
|
|
1741
1901
|
rmSync(candidate.path, {
|
|
1742
1902
|
recursive: true,
|
|
1743
1903
|
force: true
|
|
1744
1904
|
});
|
|
1905
|
+
if (record) finishLightened(candidate.keys, candidate.path);
|
|
1745
1906
|
return null;
|
|
1746
1907
|
};
|
|
1747
1908
|
const kept = key ? await withIdleWorkspace(key, remove, {
|
|
1748
1909
|
purpose: "maintenance",
|
|
1749
|
-
supervisor: kind === "dependencies"
|
|
1750
|
-
|
|
1910
|
+
supervisor: kind === "dependencies",
|
|
1911
|
+
...kind === "build" ? {
|
|
1912
|
+
hosted: false,
|
|
1913
|
+
managedLocks: false
|
|
1914
|
+
} : {}
|
|
1915
|
+
}).then((run) => run.ran ? run.value : `in use: ${run.reasons.join("; ")}`) : await remove();
|
|
1751
1916
|
if (kept) return {
|
|
1752
1917
|
status: "kept",
|
|
1753
1918
|
bytes: 0,
|
|
@@ -2110,17 +2275,19 @@ async function planLevel2({ settings, sizes, protectedRoot, pinned, now, operati
|
|
|
2110
2275
|
const actions = [];
|
|
2111
2276
|
const skips = [];
|
|
2112
2277
|
const reason = `disk pressure level 2, idle for ${settings.pressureProtectMinutes} minutes`;
|
|
2278
|
+
const lightenReason = `disk pressure level 2, no ios, android or macos run in the last ${LIGHTEN_AFTER_MS / 6e4} minutes`;
|
|
2113
2279
|
const outputs = (await collectWorkspaceOutputs({
|
|
2114
2280
|
olderThan: null,
|
|
2115
2281
|
now,
|
|
2116
2282
|
measure: false,
|
|
2117
2283
|
signal: operation?.signal,
|
|
2118
|
-
operation
|
|
2284
|
+
operation,
|
|
2285
|
+
lighten: true
|
|
2119
2286
|
})).workspaces.flatMap((entry) => {
|
|
2120
2287
|
const root = entry.projectRoot === null ? null : canonicalPath(entry.projectRoot);
|
|
2121
2288
|
if (root === null || !entry.willClear || root === protectedRoot || pinned(root)) return [];
|
|
2122
2289
|
const used = workspaceLastUsed(root);
|
|
2123
|
-
return Number.isFinite(used)
|
|
2290
|
+
return Number.isFinite(used) ? [{
|
|
2124
2291
|
root,
|
|
2125
2292
|
used
|
|
2126
2293
|
}] : [];
|
|
@@ -2132,7 +2299,7 @@ async function planLevel2({ settings, sizes, protectedRoot, pinned, now, operati
|
|
|
2132
2299
|
target: root,
|
|
2133
2300
|
workspace: root,
|
|
2134
2301
|
bytes: size?.bytes ?? 0,
|
|
2135
|
-
reason,
|
|
2302
|
+
reason: lightenReason,
|
|
2136
2303
|
level: 2
|
|
2137
2304
|
});
|
|
2138
2305
|
}
|
|
@@ -2168,7 +2335,7 @@ async function planLevel2({ settings, sizes, protectedRoot, pinned, now, operati
|
|
|
2168
2335
|
kind: "would-clear-build-dirs",
|
|
2169
2336
|
target: candidate.path,
|
|
2170
2337
|
bytes: 0,
|
|
2171
|
-
reason,
|
|
2338
|
+
reason: lightenReason,
|
|
2172
2339
|
level: 2
|
|
2173
2340
|
});
|
|
2174
2341
|
skips.push(...build.skips);
|
|
@@ -2628,14 +2795,16 @@ async function clearOutputs(action, context) {
|
|
|
2628
2795
|
if (!root) return kept("the action names no workspace");
|
|
2629
2796
|
if (root === context.protectedRoot) return kept("the command that started this pass runs in it");
|
|
2630
2797
|
if (maintenancePinned(root)) return kept("pinned by maintenance.keep");
|
|
2631
|
-
const
|
|
2798
|
+
const lighten = action.level === 2;
|
|
2799
|
+
const recent = lighten ? null : recentUse(root, context.settings, protectWindowMs(action, context.settings));
|
|
2632
2800
|
if (recent) return kept(recent);
|
|
2633
2801
|
const olderThan = action.olderThanDays ?? null;
|
|
2634
2802
|
const now = Date.now();
|
|
2635
2803
|
const report = collectWorkspaceOutputs({
|
|
2636
2804
|
olderThan,
|
|
2637
2805
|
now,
|
|
2638
|
-
measure: false
|
|
2806
|
+
measure: false,
|
|
2807
|
+
lighten
|
|
2639
2808
|
});
|
|
2640
2809
|
const entry = report.workspaces.find((candidate) => candidate.projectRoot && canonicalPath(candidate.projectRoot) === root);
|
|
2641
2810
|
if (!entry) return kept("it has no build outputs any more");
|
|
@@ -2644,7 +2813,8 @@ async function clearOutputs(action, context) {
|
|
|
2644
2813
|
workspaces: [entry]
|
|
2645
2814
|
}, {
|
|
2646
2815
|
olderThan,
|
|
2647
|
-
now
|
|
2816
|
+
now,
|
|
2817
|
+
lighten
|
|
2648
2818
|
}));
|
|
2649
2819
|
return outcomeOf(results, action.bytes);
|
|
2650
2820
|
}
|
|
@@ -2660,7 +2830,12 @@ async function removeWorktree(action, context) {
|
|
|
2660
2830
|
...sweep,
|
|
2661
2831
|
worktrees: [worktree]
|
|
2662
2832
|
}));
|
|
2663
|
-
|
|
2833
|
+
const outcome = outcomeOf(results, freedSince(before));
|
|
2834
|
+
const removal = results.find((result) => result.status === "done")?.detail;
|
|
2835
|
+
return outcome.status === "done" ? {
|
|
2836
|
+
...outcome,
|
|
2837
|
+
detail: removal ?? action.reason
|
|
2838
|
+
} : outcome;
|
|
2664
2839
|
}
|
|
2665
2840
|
async function removeOrphan(action) {
|
|
2666
2841
|
const orphan = (await collectOrphanedWorkspaces(Object.keys(loadConfig$1()?.projects ?? {}), listMountedVolumes())).orphaned.find((candidate) => candidate.dir === action.target);
|
|
@@ -2935,4 +3110,4 @@ function diskRecovered(budget) {
|
|
|
2935
3110
|
return measureDisk().every((disk) => disk.freeMb >= floor);
|
|
2936
3111
|
}
|
|
2937
3112
|
//#endregion
|
|
2938
|
-
export {
|
|
3113
|
+
export { worktreeRemovalReason as C, worktreePullRequestNote as S, ownedDeviceUsage as _, previewMaintenance as a, collectWorktreeSweep as b, deleteTempLeftovers as c, appRoots as d, artifactWorktrees as f, measureOwnedDevices as g, finishedWorkspaces as h, plannedMaintenance as i, tempLeftoverLines as l, collectArtifactsAsync as m, diskRecovered as n, triggeringRoot as o, clearArtifact as p, executeAction as r, collectTempLeftovers as s, deleteIdleWorkspaceDevices as t, tempLeftoverSection as u, maintenancePinned as v, removeWorktrees as x, candidateRootsAsync as y };
|