stim 1.28.0 → 1.30.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-CKByBnTD.mjs → acquire-artifact-CrZ4rEbI.mjs} +1 -1
- package/dist/{act-8iswyfRa.mjs → act-BaKjDWGw.mjs} +479 -29
- package/dist/{activity-DRMg4_mD.mjs → activity-BTaUf0tc.mjs} +6 -5
- package/dist/{agent-device-usage-output-tE90fDdo.mjs → agent-device-usage-output-DYBpO17K.mjs} +4 -4
- package/dist/{android-YWCbmkVK.mjs → android-BCYLwmH6.mjs} +5 -5
- package/dist/{android-D577ApKG.mjs → android-BEQUDpOg.mjs} +1 -1
- package/dist/{android-CHmSU4B4.mjs → android-BWqdDK6R.mjs} +44 -42
- package/dist/{android-CsPs-7Mg.mjs → android-DdKG6lyD.mjs} +44 -35
- package/dist/{android-cas-_aDifWW0.mjs → android-cas-BH6K12__.mjs} +4 -4
- package/dist/{android-project-DUGMbq28.d.mts → android-project-CCEQyYJK.d.mts} +6 -2
- package/dist/api.d.mts +7 -4
- package/dist/api.mjs +27 -27
- package/dist/{apk-signed-tail-CQbwM0qO.mjs → apk-signed-tail-B8kw4a8K.mjs} +2 -2
- package/dist/{artifact-DYtHjxsn.mjs → artifact-DTHXcmQ3.mjs} +12 -12
- package/dist/{artifact-bFkfD3vf.mjs → artifact-M6W2l-xh.mjs} +12 -12
- package/dist/{auto-placement-BVqs8AJi.mjs → auto-placement-CZaWDmcY.mjs} +10 -10
- package/dist/{browser-web-BUaLcafY.mjs → browser-web-JQ7lFej3.mjs} +12 -12
- package/dist/{build-cQURy_KW.mjs → build-C2ZWoCmg.mjs} +23 -23
- package/dist/{build-cache-CZULpXVl.mjs → build-cache-DlC3owap.mjs} +4 -4
- package/dist/{build-plan-CxoYfxsc.mjs → build-plan-J3iRR3gI.mjs} +6 -6
- package/dist/{cache-manifest-DEjqGGat.mjs → cache-manifest-evF_zJ9U.mjs} +1 -1
- package/dist/cache-manifest.mjs +1 -1
- package/dist/{ccache-Bm_A1xX9.mjs → ccache-B8gY50-h.mjs} +18 -18
- package/dist/{cli-CpbaLDa7.mjs → cli-xRPXJPtA.mjs} +19 -19
- package/dist/cli.mjs +1 -1
- package/dist/{client-YxCer6ab.mjs → client-DrHykA24.mjs} +5 -5
- package/dist/collector-run.mjs +5 -5
- package/dist/{command-output-C8R1KIvi.mjs → command-output-BBW8eWPL.mjs} +1 -1
- package/dist/{config-Cn94Jc0g.mjs → config-AbUjIBOQ.mjs} +121 -19
- package/dist/{dependencies-DKeMzwXY.mjs → dependencies-vUh9mp5z.mjs} +39 -38
- package/dist/{dependency-state-CojA2o0t.mjs → dependency-state-CPKAKCZ8.mjs} +1 -1
- package/dist/{dev-client-D-BW5uiq.mjs → dev-client-CASgAOu7.mjs} +2 -2
- package/dist/device-ChnO7bR9.mjs +761 -0
- package/dist/device-CsIdRXfm.mjs +175 -0
- package/dist/{device-CgXfbcz5.mjs → device-android-CcdQqQWg.mjs} +28 -195
- package/dist/{device-capacity-Cd8lMSn3.mjs → device-capacity-C5C_jOQd.mjs} +11 -11
- package/dist/device-host-worker.mjs +44 -35
- package/dist/{device-ios-Cc9ulihb.mjs → device-ios-DbmtPIiw.mjs} +28 -18
- package/dist/{device-lease-run-Mtzp4THX.mjs → device-lease-run-Do6zYA7y.mjs} +4 -4
- package/dist/{device-pool-eRz6DtCg.mjs → device-pool-CpoYiCGO.mjs} +3 -3
- package/dist/{device-eeK95Lir.mjs → device-provision-B5Ms94qY.mjs} +11 -302
- package/dist/{doctor-xf7ht-5n.mjs → doctor-CJSB5q-s.mjs} +20 -20
- package/dist/{doctor-Bz_ouYAW.mjs → doctor-CLE4AZEI.mjs} +20 -15
- package/dist/{doctor-C2QyhejJ.mjs → doctor-CpfbYh3Q.mjs} +1 -1
- package/dist/doctor-fingerprint.mjs +1 -1
- package/dist/{doctor-watchman-BTW82PDC.mjs → doctor-watchman-D1IyMle9.mjs} +4 -4
- package/dist/{eas-build-Dm6q68QY.mjs → eas-build-DIDOHw2P.mjs} +2 -2
- package/dist/{eas-fallback-DajNpxf-.mjs → eas-fallback-DVS9oBSc.mjs} +4 -4
- package/dist/{eas-session-ledger-CBFo_Uo1.mjs → eas-session-ledger-CW3l-inB.mjs} +5 -5
- package/dist/{error-diagnostics-D1QfyJzQ.mjs → error-diagnostics-XJ9eWdtq.mjs} +8 -8
- package/dist/{gc-PLFwb0k4.mjs → gc-BVIcxCxE.mjs} +2 -2
- package/dist/{gc-DM5oMm-J.mjs → gc-Co7PE36D.mjs} +80 -18
- package/dist/{guide-C4I46XAk.mjs → guide-DkepBgHT.mjs} +235 -34
- package/dist/{hosted-android-DlaKLbW0.mjs → hosted-android-Du7NxufJ.mjs} +3 -3
- package/dist/{hosted-client-DDRm9hPJ.mjs → hosted-client-Cect92SZ.mjs} +3 -3
- package/dist/{hosted-logs-bSebOKbz.mjs → hosted-logs-Opcjv1Lr.mjs} +17 -8
- package/dist/{hosted-logs-sync-B0c53W_c.mjs → hosted-logs-sync-wsI7N1Hv.mjs} +7 -11
- package/dist/{hosted-macos-B7-8Pv4H.mjs → hosted-macos-BP9Kucat.mjs} +5 -5
- package/dist/{hosted-native-CDe33CSr.mjs → hosted-native-DmdLSmvu.mjs} +9 -8
- package/dist/{idle-shutdown-CQ0QwU9J.mjs → idle-shutdown-BcMN_cLm.mjs} +7 -7
- package/dist/{ios-B1HvafEG.mjs → ios-BFkBHuRT.mjs} +8 -8
- package/dist/{ios-tg4tp3q1.mjs → ios-CG0IsLtt.mjs} +29 -29
- package/dist/{ios-B1DYuOjh.mjs → ios-CXnoVO_z.mjs} +4 -4
- package/dist/{ios-device-B4elVFKi.mjs → ios-device-ClSfuu-_.mjs} +1 -1
- package/dist/{ios-project-CR4mZ7CH.mjs → ios-project-BM9TbTE7.mjs} +7 -7
- package/dist/{ios-state-BPHqMDdZ.mjs → ios-state-Ce_dystM.mjs} +1 -1
- package/dist/{js-swap-CVpSW1fn.mjs → js-swap-9Rx-5Nqz.mjs} +4 -4
- package/dist/{launch-DoySmhjz.mjs → launch-DvJV1Mx4.mjs} +19 -19
- package/dist/{lightened-DFAJgfIk.mjs → lightened-23pqe7LS.mjs} +4 -4
- package/dist/{logs-BGsW7iPe.mjs → logs-DJgZlf2K.mjs} +9 -8
- package/dist/{logs-DI5ILkYB.mjs → logs-Pkeh3wZk.mjs} +7 -6
- package/dist/{macos-Bo9st9Di.mjs → macos-DPvPQadc.mjs} +20 -20
- package/dist/{macos-C12RMJQF.mjs → macos-Du07NsOB.mjs} +1 -1
- package/dist/macos-run.mjs +1 -1
- package/dist/maintenance-run.mjs +13 -9
- package/dist/{metro-BnhXV2Mj.mjs → metro-BMQHczcf.mjs} +2 -2
- package/dist/{metro-request-DXyKjVDF.mjs → metro-request-BtF7ox53.mjs} +1 -1
- package/dist/{named-ports-Phoi2POD.mjs → named-ports-DcktE2Pw.mjs} +2 -2
- package/dist/{native-android-vxgtLD7w.mjs → native-android-CBOM1_gB.mjs} +16 -16
- package/dist/{native-gradle-artifact-inputs-BN96IVw8.mjs → native-gradle-artifact-inputs-D_iAfPuS.mjs} +3 -3
- package/dist/{native-runtime-DG4Rodzj.mjs → native-runtime-D4cTwU0Z.mjs} +6 -6
- package/dist/{native-xcode-inputs-BKarCoKg.mjs → native-xcode-inputs-BF-ogSnG.mjs} +2 -2
- package/dist/{native-xcode-ios-8A-efGa5.mjs → native-xcode-ios-DwJBfMP6.mjs} +15 -15
- package/dist/{ndjson-Dy2W4vRa.mjs → ndjson-CrjIsGzw.mjs} +2 -2
- package/dist/offload-worker.d.mts +1 -1
- package/dist/offload-worker.mjs +22 -22
- package/dist/{ownership-DJCq48IJ.mjs → ownership-Dtz9G5Gl.mjs} +2 -2
- package/dist/{phone-reverses-BzTa8g1F.mjs → phone-reverses-CvhhkGMH.mjs} +4 -4
- package/dist/{placement-log-Cvhta5ib.mjs → placement-log-CRR_TE1r.mjs} +1 -1
- package/dist/{plan-placement-WkZdccuN.mjs → plan-placement-CdLc-pTb.mjs} +6 -6
- package/dist/{ports-UV4mJgyC.mjs → ports-g4N_cfyg.mjs} +3 -3
- package/dist/{prebuild-k8d_tqOq.mjs → prebuild-DBJMhwSS.mjs} +9 -9
- package/dist/{project-Sui52ywT.mjs → project-DPQjnpcI.mjs} +15 -15
- package/dist/{react-native-android-DANlGGQf.mjs → react-native-android-idMWOwkX.mjs} +24 -24
- package/dist/{react-native-build-jUHnIfZ9.mjs → react-native-build-BSoh4HkH.mjs} +7 -7
- package/dist/{react-native-doctor-DCWRjS7K.mjs → react-native-doctor-CYibY8-4.mjs} +9 -8
- package/dist/{react-native-ios-BwMsFMXi.mjs → react-native-ios-13KIIOOy.mjs} +16 -15
- package/dist/{recordings-iy0mkm7b.mjs → recordings-CHMaF73C.mjs} +1 -1
- package/dist/{reload-Bj7QyuDy.mjs → reload-B9DZOjcV.mjs} +1 -1
- package/dist/{reload-c_uEyc_X.mjs → reload-BUQI3dSu.mjs} +14 -14
- package/dist/{remote-DFlpAqdV.mjs → remote-C-RGHhAP.mjs} +8 -8
- package/dist/{result-BIcXREyC.mjs → result-W4HCum4A.mjs} +16 -16
- package/dist/{run-y2HwyNvg.mjs → run-BQAmrohh.mjs} +2 -2
- package/dist/{selection-CXgM_VK_.mjs → selection-PCMT97XD.mjs} +105 -62
- package/dist/{server-bare-2N4vSRZG.mjs → server-bare-CEQdB_F4.mjs} +37 -1
- package/dist/{server-command-qneHPcRI.mjs → server-command-oqi3TDy7.mjs} +5 -5
- package/dist/server-expo-BUFAq2In.mjs +2 -0
- package/dist/{server-expo-Ccm9zB0o.mjs → server-expo-C1K07shx.mjs} +8 -5
- package/dist/{settings-Cfd_Q6ys.mjs → settings-CKlMOmhj.mjs} +2 -2
- package/dist/{settings-CY5JZlNN.mjs → settings-D776ygML.mjs} +1 -1
- package/dist/{settings-Djl-mpjX.mjs → settings-D9LtQaUw.mjs} +2 -1
- package/dist/{settings-payload-DwQiEMCn.mjs → settings-payload-CE-NZ6Lq.mjs} +4 -4
- package/dist/{settings-write-CJpjkeAd.mjs → settings-write-D7Xwa_-M.mjs} +5 -5
- package/dist/settings.schema.json +58 -9
- package/dist/{simslim-DCQwzoPy.mjs → simslim-CbpHERcv.mjs} +1 -1
- package/dist/{slot-launch-BpmanOnk.mjs → slot-launch-CeIK1iUI.mjs} +6 -6
- package/dist/{stage-CmugrSG5.mjs → stage-Blqe6bWb.mjs} +1 -1
- package/dist/{start-DYLk6GXn.mjs → start-B7J5a9nS.mjs} +11 -11
- package/dist/{start-CHH3zgIU.mjs → start-CvP2pJjc.mjs} +1 -1
- package/dist/{state-BXC1Lfxw.mjs → state-C2AUjjhg.mjs} +1 -1
- package/dist/{state-B2QJbDwz.mjs → state-D5ZxwCGJ.mjs} +2 -2
- package/dist/{stats-DxKqhcGp.mjs → stats-Uo7l8OAk.mjs} +4 -4
- package/dist/{status-7ULDEJ1e.mjs → status-CK7ZoEhV.mjs} +2 -2
- package/dist/{status-D_Ljc89p.mjs → status-CqJI1TgG.mjs} +1 -1
- package/dist/{status-BHCkOZga.mjs → status-_rWXFSO7.mjs} +24 -24
- package/dist/{status-watch-BmsPqYSU.mjs → status-watch-CnSyXUmj.mjs} +4 -4
- package/dist/status-worker.mjs +1 -1
- package/dist/{stim-desktop-CbWo21kb.mjs → stim-desktop-CYXLFpFS.mjs} +1 -1
- package/dist/{stop-b2pouxAO.mjs → stop-Bogo9oO2.mjs} +2 -2
- package/dist/{stop-DQvE-P76.mjs → stop-CMVfaA-6.mjs} +4 -4
- package/dist/{stop-D-dGE9gh.mjs → stop-CnF9ixYe.mjs} +20 -19
- package/dist/supervisor-run.d.mts +1 -0
- package/dist/supervisor-run.mjs +23 -19
- package/dist/{support-04IhBUTT.mjs → support-BGqpYMV8.mjs} +15 -11
- package/dist/{support-BtlJKjyQ.mjs → support-DUevTPur.mjs} +9 -9
- package/dist/{swiftpm-artifact-inputs-Cj2UpmPN.mjs → swiftpm-artifact-inputs-BcJk6-3u.mjs} +1 -1
- package/dist/{swiftpm-macos-BhF2stxY.mjs → swiftpm-macos-DBrmoocG.mjs} +8 -8
- package/dist/toolchain-Cw9VVHOY.mjs +2 -0
- package/dist/{toolchain-mLA_km-b.mjs → toolchain-DLdoyxIt.mjs} +19 -11
- package/dist/{trigger-DMou-X7j.mjs → trigger-CfnOfpDd.mjs} +1 -1
- package/dist/trigger-DBZ-GBrl.mjs +2 -0
- package/dist/{warm-progress-B0Vpuvpl.mjs → warm-progress-DQ2wQZKp.mjs} +3 -3
- package/dist/web-CI_qCRPw.mjs +2 -0
- package/dist/{web-BYmK0TjL.mjs → web-g9U7L1sR.mjs} +8 -8
- package/dist/web-run.mjs +5 -5
- package/dist/{workspace-state-kIZrdlSg.mjs → workspace-state-DGwkPXwq.mjs} +2 -2
- package/dist/{workspaces-CmOcceDN.mjs → workspaces-7_RWoi6c.mjs} +11 -11
- package/dist/{worktree-nliAoHxB.mjs → worktree-DEet9H3p.mjs} +1 -1
- package/dist/{worktree-2dk5edza.mjs → worktree-qKJ3x07S.mjs} +25 -25
- package/package.json +7 -7
- package/shim/bundle-response.cjs +37 -0
- package/dist/server-expo-WulkyAwT.mjs +0 -2
- package/dist/toolchain-qktiV8xc.mjs +0 -2
- package/dist/trigger-qp2ji5wE.mjs +0 -2
- package/dist/web-CrVLVQZY.mjs +0 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { l as WorkspaceProcessCleanupError } from "./exec-aULwtNly.mjs";
|
|
2
|
-
import { I as waitForSharedBuild } from "./activity-
|
|
2
|
+
import { I as waitForSharedBuild } from "./activity-BTaUf0tc.mjs";
|
|
3
3
|
import { rmSync } from "node:fs";
|
|
4
4
|
//#region src/engine/artifact-lifecycle.ts
|
|
5
5
|
async function runArtifactLifecycle(phases) {
|
|
@@ -1,30 +1,33 @@
|
|
|
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-
|
|
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-
|
|
1
|
+
import { S as process_identity_exports, d as workspaceProcessLockError, l as WorkspaceProcessCleanupError, n as isTimeoutError, t as getExecutor, u as withWorkspaceProcessLock } from "./exec-aULwtNly.mjs";
|
|
2
|
+
import { E as workspaceDir, j as workspaceStateFile$1, k as workspaceLogsDir$1, r as readWorkspaceState$1, u as workspaceLastUsed, w as workspaceAgentDeviceDir } from "./workspace-state-DGwkPXwq.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-AbUjIBOQ.mjs";
|
|
4
|
+
import { o as formatLongDuration, u as plural } from "./command-output-BBW8eWPL.mjs";
|
|
5
5
|
import { c as gitQuiet, l as gitQuietAsync, n as runOperationFileQuiet, r as childEnvironment } from "./operation-exec-Dp4FuIGR.mjs";
|
|
6
|
-
import { At as listWorktrees, Et as hasUncommittedWorkAsync, Ft as matchWorktreeEntry, Kt as sourceCheckoutOf, O as maintenanceKeepSetting, Pt as lockReason, Ut as resolveFullRefAsync, Wt as resolveSourceCheckoutAsync, X as resolveProjectSettings, Xt as worktreeLockAsync, Z as resolveProjectSettingsAsync, bt as dirtyPathsAsync, h as deviceIdleShutdownMinutesSetting, jt as listWorktreesAsync, mt as LOCKED_REASON, qt as unpushedCommitsAsync, sn as removeTemporaryEntryAsync, wt as hasPopulatedSubmodulesAsync } from "./settings-
|
|
7
|
-
import { i as findProjectRoot$1 } from "./project-
|
|
8
|
-
import { F as
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
6
|
+
import { At as listWorktrees, Et as hasUncommittedWorkAsync, Ft as matchWorktreeEntry, Kt as sourceCheckoutOf, O as maintenanceKeepSetting, Pt as lockReason, Ut as resolveFullRefAsync, Wt as resolveSourceCheckoutAsync, X as resolveProjectSettings, Xt as worktreeLockAsync, Z as resolveProjectSettingsAsync, bt as dirtyPathsAsync, h as deviceIdleShutdownMinutesSetting, it as settingValueAt, jt as listWorktreesAsync, mt as LOCKED_REASON, qt as unpushedCommitsAsync, sn as removeTemporaryEntryAsync, wt as hasPopulatedSubmodulesAsync } from "./settings-D776ygML.mjs";
|
|
7
|
+
import { P as readRemoteSession, i as findProjectRoot$1 } from "./project-DPQjnpcI.mjs";
|
|
8
|
+
import { F as listAvds, G as ownedAvdSerialResolverAsync, I as listAvdsAsync, M as listAdbDevicesAsync, O as getAvdNameForSerial, V as ownedAvdDirectory, j as listAdbDevices, k as getAvdNameForSerialAsync, yt as readParked } from "./android-DdKG6lyD.mjs";
|
|
9
|
+
import { c as pidExists } from "./metro-BMQHczcf.mjs";
|
|
10
|
+
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-B8gY50-h.mjs";
|
|
11
|
+
import { o as readWebRecord, u as webFacts } from "./state-D5ZxwCGJ.mjs";
|
|
12
|
+
import { a as unregister, n as readManifest } from "./cache-manifest-evF_zJ9U.mjs";
|
|
13
|
+
import { B as workspaceBuildInProgress, Et as GC_OUTPUT, F as collectOwnedDeviceActivityAsync, Ot as takeGcResults, P as collectOwnedDeviceActivity, a as collectOrphanedWorkspaces, b as workspaceInUseAsync, c as isInsideWorkspaces, d as recentNativeUseReason, g as ARTIFACT_DIRS, h as workspaceDirRemoved, i as clearWorkspaceOutputs, jt as readConcurrency, kt as eachLimited, l as keptByLock, m as workspaceBuildReasons, o as collectWorkspaceOutputs, s as deleteOrphanedWorkspaces, t as LIGHTEN_AFTER_MS, u as listWorkspaceDirs, v as withIdleWorkspace, x as resolveSupervisorTarget, y as workspaceInUse } from "./workspaces-7_RWoi6c.mjs";
|
|
12
14
|
import { t as canonicalPath } from "./paths-BsJMoPP2.mjs";
|
|
13
|
-
import { N as listBuildLocks, _ as workspaceDeviceLastUseAt, b as leaseIsExpired, g as workspaceActivity, x as listLeaseFiles } from "./activity-
|
|
14
|
-
import { d as listAllIosSims, f as listAllIosSimsAsync } from "./ios-
|
|
15
|
+
import { N as listBuildLocks, _ as workspaceDeviceLastUseAt, b as leaseIsExpired, g as workspaceActivity, x as listLeaseFiles } from "./activity-BTaUf0tc.mjs";
|
|
16
|
+
import { d as listAllIosSims, f as listAllIosSimsAsync } from "./ios-CXnoVO_z.mjs";
|
|
15
17
|
import { s as metroStoreRoot } from "./errors-DHm_U5gv.mjs";
|
|
16
|
-
import { t as resolveMaintenanceSettings } from "./settings-
|
|
17
|
-
import {
|
|
18
|
+
import { t as resolveMaintenanceSettings } from "./settings-D9LtQaUw.mjs";
|
|
19
|
+
import { o as runStop } from "./stop-CnF9ixYe.mjs";
|
|
20
|
+
import { D as stimCliUseOf, E as stimCliEntries, M as worktreeArchiveLimits, T as serviceRunningFrom, _ as cacheBlocked, a as nestedWorktrees, b as measurePressure, i as excludeWatchmanCookies, o as porcelainPath, p as removeWorktreeTarget, r as excludePodChurn, s as reclaimKeys, v as measureDisk, w as uncommittedActivityOf, x as measurePressureAsync, y as measureDiskAsync } from "./worktree-qKJ3x07S.mjs";
|
|
18
21
|
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-
|
|
20
|
-
import { a as restoreProblem, r as recordLightened, t as finishLightened } from "./lightened-
|
|
21
|
-
import { i as writeIdleShutdownEvent, n as dueIdleDevices, r as shutDownIdleDevices } from "./idle-shutdown-
|
|
22
|
+
import { a as lastFetchedAtAsync, c as mergeStateAsync, f as recordPullRequestLookup, i as fetchDefaultBranchAsync, o as localDefaultBranchAsync, r as FETCH_FRESH_MS } from "./warm-progress-DQ2wQZKp.mjs";
|
|
23
|
+
import { a as restoreProblem, r as recordLightened, t as finishLightened } from "./lightened-23pqe7LS.mjs";
|
|
24
|
+
import { i as writeIdleShutdownEvent, n as dueIdleDevices, r as shutDownIdleDevices } from "./idle-shutdown-BcMN_cLm.mjs";
|
|
22
25
|
import { readClaimSet } from "@stim-cli/core/ownership-claim";
|
|
23
|
-
import { existsSync, lstatSync, readdirSync, readlinkSync, realpathSync, rmSync, statSync } from "node:fs";
|
|
26
|
+
import { existsSync, lstatSync, readFileSync, readdirSync, readlinkSync, realpathSync, rmSync, statSync } from "node:fs";
|
|
24
27
|
import { tmpdir } from "node:os";
|
|
25
28
|
import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
26
|
-
import { buildCacheRoot, configDir, metroCacheRoot } from "@stim-cli/core";
|
|
27
|
-
import { LAST_BUILD_KEYS, MAINTENANCE_LOG_NAME, lastNativeUseFrom, loadConfig, readBuildHistory, readMaintenanceState, readPullRequestCache, settingDefinition, sharedCompilationCache } from "@stim-cli/core/state";
|
|
29
|
+
import { buildCacheRoot, configDir, metroCacheRoot, rotatedLogPath } from "@stim-cli/core";
|
|
30
|
+
import { LAST_BUILD_KEYS, MAINTENANCE_LOG_NAME, coerceSettingText, deviceViewersDir, lastNativeUseFrom, loadConfig, parseNdjsonText, readBuildHistory, readJsonObject, readMaintenanceState, readPullRequestCache, settingDefinition, settingValueError, sharedCompilationCache } from "@stim-cli/core/state";
|
|
28
31
|
import { isAbsolute as isAbsolute$1, join as join$1 } from "path";
|
|
29
32
|
import chalk from "chalk";
|
|
30
33
|
import { existsSync as existsSync$1, readdirSync as readdirSync$1, statSync as statSync$1 } from "fs";
|
|
@@ -1486,6 +1489,432 @@ async function planWorktrees({ protectedRoot, pinned, now, level, graceMs, sizes
|
|
|
1486
1489
|
};
|
|
1487
1490
|
}
|
|
1488
1491
|
//#endregion
|
|
1492
|
+
//#region src/maintenance/idle-stop.ts
|
|
1493
|
+
const HOUR_MS = 36e5;
|
|
1494
|
+
const SETTING = "maintenance.idleStopHours";
|
|
1495
|
+
const METRO_REQUESTS = /* @__PURE__ */ new Set([
|
|
1496
|
+
"bundle_response_started",
|
|
1497
|
+
"bundle_response_progress",
|
|
1498
|
+
"bundle_response_finished",
|
|
1499
|
+
"bundle_response_failed",
|
|
1500
|
+
"bundle_build_started",
|
|
1501
|
+
"bundle_build_done",
|
|
1502
|
+
"bundle_build_failed",
|
|
1503
|
+
"manifest_request_started",
|
|
1504
|
+
"manifest_request_finished",
|
|
1505
|
+
"manifest_request_failed",
|
|
1506
|
+
"hmr_update"
|
|
1507
|
+
]);
|
|
1508
|
+
const STIM_SESSION = "stim-teardown-inventory";
|
|
1509
|
+
const AGENT_DEVICE_DRIVERS = /* @__PURE__ */ new Set(["agent-device-claim", "agent-device-lease"]);
|
|
1510
|
+
function decideIdleStop(evidence, { idleMs, now }) {
|
|
1511
|
+
if (!(idleMs > 0)) return {
|
|
1512
|
+
stop: false,
|
|
1513
|
+
reason: `${SETTING} is 0`
|
|
1514
|
+
};
|
|
1515
|
+
const last = evidence.activity.filter(({ at }) => Number.isFinite(at)).reduce((best, entry) => !best || entry.at > best.at ? entry : best, null);
|
|
1516
|
+
const idle = last ? now - last.at : NaN;
|
|
1517
|
+
if (last && idle < idleMs) return {
|
|
1518
|
+
stop: false,
|
|
1519
|
+
active: true,
|
|
1520
|
+
reason: `its last ${last.basis} was ${formatLongDuration(Math.max(0, idle))} ago, within ${SETTING}`
|
|
1521
|
+
};
|
|
1522
|
+
if (evidence.keep.length) return {
|
|
1523
|
+
stop: false,
|
|
1524
|
+
reason: evidence.keep.join("; ")
|
|
1525
|
+
};
|
|
1526
|
+
if (!last) return {
|
|
1527
|
+
stop: false,
|
|
1528
|
+
reason: "its last activity is unknown"
|
|
1529
|
+
};
|
|
1530
|
+
return {
|
|
1531
|
+
stop: true,
|
|
1532
|
+
idleMs: idle
|
|
1533
|
+
};
|
|
1534
|
+
}
|
|
1535
|
+
async function idleStopHours(root, env, operation) {
|
|
1536
|
+
const setting = settingDefinition(SETTING);
|
|
1537
|
+
if (!setting?.env) return { invalid: `${SETTING} is not in the settings registry` };
|
|
1538
|
+
const raw = env[setting.env];
|
|
1539
|
+
const fromEnv = raw !== void 0 && raw !== "";
|
|
1540
|
+
let value;
|
|
1541
|
+
if (fromEnv) value = coerceSettingText(setting, raw);
|
|
1542
|
+
else try {
|
|
1543
|
+
const resolved = operation ? await resolveProjectSettingsAsync(root, {
|
|
1544
|
+
env,
|
|
1545
|
+
signal: operation.signal,
|
|
1546
|
+
declareFor: operation
|
|
1547
|
+
}) : resolveProjectSettings(root);
|
|
1548
|
+
value = settingValueAt(resolved.settings, SETTING);
|
|
1549
|
+
} catch (error) {
|
|
1550
|
+
rethrowCleanup(error, operation?.signal);
|
|
1551
|
+
return { invalid: `${SETTING} cannot be resolved: ${error instanceof Error ? error.message : String(error)}` };
|
|
1552
|
+
}
|
|
1553
|
+
if (value === void 0) return { hours: Number(setting.default) };
|
|
1554
|
+
const error = settingValueError(setting, value);
|
|
1555
|
+
return error || typeof value !== "number" ? { invalid: `${fromEnv ? setting.env : SETTING} is invalid: expected ${error ?? "a number"}` } : { hours: value };
|
|
1556
|
+
}
|
|
1557
|
+
function deviceKeepReason(device, platform) {
|
|
1558
|
+
const { activity } = device;
|
|
1559
|
+
const what = `its ${device.kind === "ios" ? "simulator" : "emulator"} ${device.name}`;
|
|
1560
|
+
if (activity.state === "driven" && !activity.basis.every((basis) => AGENT_DEVICE_DRIVERS.has(basis))) return `${what} is driven by ${activity.driver?.tool ?? "an unknown tool"}`;
|
|
1561
|
+
if (activity.basis.includes("agent-device-claim") && !activity.recent?.["agent-action"]) return `${what} has a live agent-device claim whose session activity cannot be found`;
|
|
1562
|
+
const probed = activity.state === "driven" ? activity.unknown ?? [] : activity.state === "unknown" ? activity.basis : [];
|
|
1563
|
+
const unknown = platform === "win32" ? probed.filter((basis) => basis !== "driver-process") : probed;
|
|
1564
|
+
if (unknown.length) return `${what} has unknown activity (${unknown.join(", ")})`;
|
|
1565
|
+
return null;
|
|
1566
|
+
}
|
|
1567
|
+
function recentAt(activity, basis) {
|
|
1568
|
+
return Date.parse(activity.recent?.[basis] ?? "");
|
|
1569
|
+
}
|
|
1570
|
+
const missing = (error) => error instanceof Error && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR");
|
|
1571
|
+
const message = (error) => error instanceof Error ? error.message : String(error);
|
|
1572
|
+
function agentSessionsActedAt(root) {
|
|
1573
|
+
const dir = join(workspaceAgentDeviceDir(root), "sessions");
|
|
1574
|
+
let names;
|
|
1575
|
+
try {
|
|
1576
|
+
names = readdirSync(dir);
|
|
1577
|
+
} catch (error) {
|
|
1578
|
+
return missing(error) ? NaN : `its agent-device sessions cannot be read (${message(error)})`;
|
|
1579
|
+
}
|
|
1580
|
+
let latest = NaN;
|
|
1581
|
+
for (const name of names) {
|
|
1582
|
+
if (name === STIM_SESSION) continue;
|
|
1583
|
+
try {
|
|
1584
|
+
const at = statSync(join(dir, name, "events.ndjson")).mtimeMs;
|
|
1585
|
+
if (!(at <= latest)) latest = at;
|
|
1586
|
+
} catch (error) {
|
|
1587
|
+
if (!missing(error)) return `its agent-device session ${name} cannot be read (${message(error)})`;
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
return latest;
|
|
1591
|
+
}
|
|
1592
|
+
function metroRequestAt(root, since, serving) {
|
|
1593
|
+
const file = join(workspaceLogsDir$1(root), "metro.ndjson");
|
|
1594
|
+
const rotated = rotatedLogPath(file);
|
|
1595
|
+
const records = [];
|
|
1596
|
+
for (const path of [rotated, file]) try {
|
|
1597
|
+
records.push(...parseNdjsonText(readFileSync(path, "utf8")));
|
|
1598
|
+
} catch (error) {
|
|
1599
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") continue;
|
|
1600
|
+
return `its Metro log cannot be read (${error instanceof Error ? error.message : String(error)})`;
|
|
1601
|
+
}
|
|
1602
|
+
let latest = NaN;
|
|
1603
|
+
let earliest = Infinity;
|
|
1604
|
+
for (const record of records) {
|
|
1605
|
+
if (typeof record.ts !== "number") continue;
|
|
1606
|
+
earliest = Math.min(earliest, record.ts);
|
|
1607
|
+
if (typeof record.event === "string" && METRO_REQUESTS.has(record.event) && !(record.ts <= latest)) latest = record.ts;
|
|
1608
|
+
}
|
|
1609
|
+
if (!Number.isFinite(latest) && earliest > since && existsSync(rotated)) return `its rotated Metro log does not reach back ${SETTING}`;
|
|
1610
|
+
if (serving && earliest === Infinity) return "its dev server runs but its Metro log is missing or empty";
|
|
1611
|
+
return latest;
|
|
1612
|
+
}
|
|
1613
|
+
function unreadableViewers() {
|
|
1614
|
+
const dir = deviceViewersDir();
|
|
1615
|
+
let names;
|
|
1616
|
+
try {
|
|
1617
|
+
names = readdirSync(dir).filter((name) => name.endsWith(".json"));
|
|
1618
|
+
} catch (error) {
|
|
1619
|
+
return missing(error) ? null : `the stim-server viewer records cannot be read (${message(error)})`;
|
|
1620
|
+
}
|
|
1621
|
+
for (const name of names) {
|
|
1622
|
+
const record = readJsonObject(join(dir, name));
|
|
1623
|
+
if (!record) return `the stim-server viewer record ${name} cannot be read`;
|
|
1624
|
+
if ((0, process_identity_exports.inspectProcessIdentity)(record) === "unknown") return `the stim-server behind the viewer record ${name} cannot be verified`;
|
|
1625
|
+
}
|
|
1626
|
+
return null;
|
|
1627
|
+
}
|
|
1628
|
+
async function keepReasons(root, devices, { now, platform, locked, operation }) {
|
|
1629
|
+
const checks = {
|
|
1630
|
+
devServer: false,
|
|
1631
|
+
nativeRun: !locked
|
|
1632
|
+
};
|
|
1633
|
+
const keep = operation ? await workspaceInUseAsync(root, checks, operation.signal, operation) : workspaceInUse(root, checks);
|
|
1634
|
+
if (workspaceBuildInProgress(root)) keep.push("a build is in progress");
|
|
1635
|
+
if (readRemoteSession(root)) keep.push("it has a remote device session");
|
|
1636
|
+
const holder = canonicalPath(root);
|
|
1637
|
+
for (const { lease, path } of listLeaseFiles()) if (!lease) keep.push(`the device lease ${path} cannot be read`);
|
|
1638
|
+
else if (!leaseIsExpired(lease, now) && canonicalPath(lease.holder) === holder) keep.push(`it holds the ${lease.platform} device lease on ${lease.deviceName ?? lease.id}`);
|
|
1639
|
+
const browser = webFacts(readWebRecord(root));
|
|
1640
|
+
if (browser && browser.status !== "stopped") keep.push(`its owned Chrome is ${browser.status}`);
|
|
1641
|
+
for (const device of devices) {
|
|
1642
|
+
const reason = deviceKeepReason(device, platform);
|
|
1643
|
+
if (reason) keep.push(reason);
|
|
1644
|
+
}
|
|
1645
|
+
const viewers = devices.length ? unreadableViewers() : null;
|
|
1646
|
+
if (viewers) keep.push(viewers);
|
|
1647
|
+
return keep;
|
|
1648
|
+
}
|
|
1649
|
+
async function idleStopEvidence(root, devices, { now, idleMs, platform = process.platform, locked = false, serving = false, operation }) {
|
|
1650
|
+
const state = readWorkspaceState$1(root);
|
|
1651
|
+
if (!state && existsSync(workspaceStateFile$1(root))) return {
|
|
1652
|
+
activity: [],
|
|
1653
|
+
keep: ["its state.json cannot be read"]
|
|
1654
|
+
};
|
|
1655
|
+
const sessions = agentSessionsActedAt(root);
|
|
1656
|
+
if (typeof sessions === "string") return {
|
|
1657
|
+
activity: [],
|
|
1658
|
+
keep: [sessions]
|
|
1659
|
+
};
|
|
1660
|
+
const build = state?.lastBuild;
|
|
1661
|
+
const builtAt = Date.parse(String(build?.startedAt ?? "")) + (typeof build?.durationMs === "number" ? build.durationMs : 0);
|
|
1662
|
+
const activity = [
|
|
1663
|
+
{
|
|
1664
|
+
basis: "stim command",
|
|
1665
|
+
at: Date.parse(String(state?.lastUsedAt ?? ""))
|
|
1666
|
+
},
|
|
1667
|
+
{
|
|
1668
|
+
basis: "native run",
|
|
1669
|
+
at: builtAt
|
|
1670
|
+
},
|
|
1671
|
+
{
|
|
1672
|
+
basis: "agent-device command",
|
|
1673
|
+
at: typeof sessions === "number" ? sessions : NaN
|
|
1674
|
+
},
|
|
1675
|
+
...devices.flatMap(({ activity: device }) => [{
|
|
1676
|
+
basis: "agent-device command",
|
|
1677
|
+
at: recentAt(device, "agent-action")
|
|
1678
|
+
}, {
|
|
1679
|
+
basis: "live view",
|
|
1680
|
+
at: recentAt(device, "viewer")
|
|
1681
|
+
}])
|
|
1682
|
+
].filter(({ at }) => Number.isFinite(at));
|
|
1683
|
+
if (activity.some(({ at }) => now - at < idleMs)) return {
|
|
1684
|
+
activity,
|
|
1685
|
+
keep: []
|
|
1686
|
+
};
|
|
1687
|
+
const keep = await keepReasons(root, devices, {
|
|
1688
|
+
now,
|
|
1689
|
+
platform,
|
|
1690
|
+
locked,
|
|
1691
|
+
operation
|
|
1692
|
+
});
|
|
1693
|
+
if (keep.length) return {
|
|
1694
|
+
activity,
|
|
1695
|
+
keep
|
|
1696
|
+
};
|
|
1697
|
+
const metro = metroRequestAt(root, now - idleMs, serving);
|
|
1698
|
+
if (typeof metro === "string") return {
|
|
1699
|
+
activity,
|
|
1700
|
+
keep: [metro]
|
|
1701
|
+
};
|
|
1702
|
+
if (Number.isFinite(metro)) activity.push({
|
|
1703
|
+
basis: "Metro request",
|
|
1704
|
+
at: metro
|
|
1705
|
+
});
|
|
1706
|
+
return {
|
|
1707
|
+
activity,
|
|
1708
|
+
keep
|
|
1709
|
+
};
|
|
1710
|
+
}
|
|
1711
|
+
function rethrowCleanup(error, signal) {
|
|
1712
|
+
if (error instanceof WorkspaceProcessCleanupError || error instanceof Error && "reportCleanup" in error) throw error;
|
|
1713
|
+
signal?.throwIfAborted();
|
|
1714
|
+
}
|
|
1715
|
+
async function unseenEmulatorError(unseen, operation) {
|
|
1716
|
+
try {
|
|
1717
|
+
const signal = operation?.signal;
|
|
1718
|
+
const adb = operation ? await listAdbDevicesAsync({
|
|
1719
|
+
timeoutMs: 5e3,
|
|
1720
|
+
signal,
|
|
1721
|
+
operation
|
|
1722
|
+
}) : listAdbDevices({ timeoutMs: 5e3 });
|
|
1723
|
+
for (const { serial } of [...adb.emulators, ...adb.unhealthy.filter((entry) => entry.kind === "emulator")]) {
|
|
1724
|
+
const name = operation ? await getAvdNameForSerialAsync(serial, {
|
|
1725
|
+
timeoutMs: 5e3,
|
|
1726
|
+
signal,
|
|
1727
|
+
operation
|
|
1728
|
+
}) : getAvdNameForSerial(serial, { timeoutMs: 5e3 });
|
|
1729
|
+
if (name === null) return `its emulators cannot be identified to prove them idle (${serial} gave no AVD name)`;
|
|
1730
|
+
if (unseen.includes(name)) return `its emulator ${name} runs as ${serial}, but its activity could not be read`;
|
|
1731
|
+
}
|
|
1732
|
+
return null;
|
|
1733
|
+
} catch (error) {
|
|
1734
|
+
rethrowCleanup(error, operation?.signal);
|
|
1735
|
+
return `its emulators cannot be listed to prove them idle (${error instanceof Error ? error.message : String(error)})`;
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1738
|
+
function survivingServer(recorded) {
|
|
1739
|
+
const pid = recorded?.serverPid;
|
|
1740
|
+
if (typeof pid !== "number" || !Number.isInteger(pid) || pid <= 0) return null;
|
|
1741
|
+
const token = recorded?.serverProcessToken;
|
|
1742
|
+
return (typeof token === "string" ? ["same", "unknown"].includes((0, process_identity_exports.inspectProcessIdentity)({
|
|
1743
|
+
pid,
|
|
1744
|
+
processToken: token
|
|
1745
|
+
})) : pidExists(pid)) ? `its dev server (pid ${pid}) may still run after its supervisor exited; stim stop ends it` : null;
|
|
1746
|
+
}
|
|
1747
|
+
async function candidate(path, env, devices, operation) {
|
|
1748
|
+
const signal = operation?.signal;
|
|
1749
|
+
const project = loadConfig$1()?.projects?.[path];
|
|
1750
|
+
if (!project) return null;
|
|
1751
|
+
const supervisor = resolveSupervisorTarget({
|
|
1752
|
+
state: readWorkspaceState$1(path)?.supervisor,
|
|
1753
|
+
record: project.supervisor,
|
|
1754
|
+
reservedPort: project.metroPort
|
|
1755
|
+
});
|
|
1756
|
+
const slots = projectDeviceSlots(project);
|
|
1757
|
+
const ownsIos = slots.some(({ platforms }) => platforms.ios?.owned === true);
|
|
1758
|
+
const owns = ownsIos || slots.some(({ platforms }) => platforms.android?.owned === true);
|
|
1759
|
+
if (!owns && (supervisor.status === "none" || supervisor.status === "stale")) return null;
|
|
1760
|
+
const setting = await idleStopHours(path, env, operation);
|
|
1761
|
+
if ("invalid" in setting) return { skip: setting.invalid };
|
|
1762
|
+
if (setting.hours === 0) return null;
|
|
1763
|
+
let booted = [];
|
|
1764
|
+
if (owns) try {
|
|
1765
|
+
booted = (await devices(ownsIos)).filter((device) => device.project === path);
|
|
1766
|
+
} catch (error) {
|
|
1767
|
+
rethrowCleanup(error, signal);
|
|
1768
|
+
return supervisor.status === "none" || supervisor.status === "stale" ? null : { skip: "its owned devices cannot be listed to prove them idle" };
|
|
1769
|
+
}
|
|
1770
|
+
if (supervisor.status === "unverified") return { skip: `its dev server supervisor cannot be verified: ${supervisor.reason ?? "unknown identity"}` };
|
|
1771
|
+
if (supervisor.status === "ours" && readWorkspaceState$1(path)?.supervisor?.mode === "command-child") return { skip: "its dev server runs metro.command, whose bundle and HMR requests Stim cannot see" };
|
|
1772
|
+
if (supervisor.status === "ours" && readWorkspaceState$1(path)?.supervisor?.hmrUpdates !== true) return { skip: "its dev server does not report HMR updates to Stim: an Expo SDK before 54, or a server an older Stim started, which stim stop and stim start restart" };
|
|
1773
|
+
const avdNames = slots.flatMap(({ platforms }) => platforms.android?.owned && platforms.android.avdName ? [platforms.android.avdName] : []);
|
|
1774
|
+
if (supervisor.status !== "ours" && booted.length === 0) return null;
|
|
1775
|
+
const orphan = supervisor.status === "stale" ? survivingServer(readWorkspaceState$1(path)?.supervisor) : null;
|
|
1776
|
+
if (orphan) return { skip: orphan };
|
|
1777
|
+
const seen = new Set(booted.flatMap((device) => device.kind === "android" ? [device.id] : []));
|
|
1778
|
+
const unseen = avdNames.filter((name) => !seen.has(name));
|
|
1779
|
+
const emulators = unseen.length ? await unseenEmulatorError(unseen, operation) : null;
|
|
1780
|
+
if (emulators) return { skip: emulators };
|
|
1781
|
+
return {
|
|
1782
|
+
path,
|
|
1783
|
+
hours: setting.hours,
|
|
1784
|
+
serving: supervisor.status === "ours",
|
|
1785
|
+
devices: booted
|
|
1786
|
+
};
|
|
1787
|
+
}
|
|
1788
|
+
/**
|
|
1789
|
+
* Plans stopping each workspace, other than `protectedRoot`, whose dev server runs or whose owned simulator or
|
|
1790
|
+
* emulator is booted, once it has had no real activity for its maintenance.idleStopHours.
|
|
1791
|
+
*/
|
|
1792
|
+
async function planIdleStop({ protectedRoot, now, devices, env = process.env, platform = process.platform, operation }) {
|
|
1793
|
+
const plan = {
|
|
1794
|
+
actions: [],
|
|
1795
|
+
blocked: [],
|
|
1796
|
+
skips: []
|
|
1797
|
+
};
|
|
1798
|
+
if (deviceSweepIsScoped(env)) return plan;
|
|
1799
|
+
for (const path of Object.keys(loadConfig$1()?.projects ?? {})) {
|
|
1800
|
+
const root = canonicalPath(path);
|
|
1801
|
+
if (root === protectedRoot) continue;
|
|
1802
|
+
operation?.signal.throwIfAborted();
|
|
1803
|
+
const found = await candidate(path, env, devices, operation);
|
|
1804
|
+
if (!found) continue;
|
|
1805
|
+
if ("skip" in found) {
|
|
1806
|
+
plan.skips.push({
|
|
1807
|
+
target: root,
|
|
1808
|
+
reason: found.skip,
|
|
1809
|
+
workspace: root
|
|
1810
|
+
});
|
|
1811
|
+
continue;
|
|
1812
|
+
}
|
|
1813
|
+
const idleMs = found.hours * HOUR_MS;
|
|
1814
|
+
const decision = decideIdleStop(await idleStopEvidence(path, found.devices, {
|
|
1815
|
+
now,
|
|
1816
|
+
idleMs,
|
|
1817
|
+
platform,
|
|
1818
|
+
serving: found.serving,
|
|
1819
|
+
operation
|
|
1820
|
+
}), {
|
|
1821
|
+
idleMs,
|
|
1822
|
+
now
|
|
1823
|
+
});
|
|
1824
|
+
if (!decision.stop) {
|
|
1825
|
+
if (!decision.active) plan.skips.push({
|
|
1826
|
+
target: root,
|
|
1827
|
+
reason: decision.reason,
|
|
1828
|
+
workspace: root
|
|
1829
|
+
});
|
|
1830
|
+
continue;
|
|
1831
|
+
}
|
|
1832
|
+
plan.actions.push({
|
|
1833
|
+
kind: "would-stop-workspace",
|
|
1834
|
+
check: "idle",
|
|
1835
|
+
target: root,
|
|
1836
|
+
workspace: root,
|
|
1837
|
+
bytes: 0,
|
|
1838
|
+
reason: `no real activity for ${formatLongDuration(decision.idleMs)}, over ${SETTING} ${found.hours}`
|
|
1839
|
+
});
|
|
1840
|
+
}
|
|
1841
|
+
return plan;
|
|
1842
|
+
}
|
|
1843
|
+
const kept$1 = (detail) => ({
|
|
1844
|
+
status: "kept",
|
|
1845
|
+
bytes: 0,
|
|
1846
|
+
detail
|
|
1847
|
+
});
|
|
1848
|
+
/**
|
|
1849
|
+
* Stops a planned idle workspace the way `stim stop` does, under its native-run and metro-start locks, after
|
|
1850
|
+
* deciding again that it is still idle. Physical-device leases stay.
|
|
1851
|
+
*/
|
|
1852
|
+
async function stopIdleWorkspace(action, { protectedRoot, devices, operation, env = operation?.env ?? process.env, by = "automatic maintenance" }) {
|
|
1853
|
+
const root = action.workspace ?? action.target;
|
|
1854
|
+
if (root === protectedRoot) return kept$1("the command that started this pass runs in it");
|
|
1855
|
+
if (deviceSweepIsScoped(env)) return kept$1("STIM_HOME scopes this config, and devices are machine-wide");
|
|
1856
|
+
const path = Object.keys(loadConfig$1()?.projects ?? {}).find((entry) => canonicalPath(entry) === root) ?? root;
|
|
1857
|
+
const stillIdle = async () => {
|
|
1858
|
+
const now = Date.now();
|
|
1859
|
+
const found = await candidate(path, env, devices(), operation);
|
|
1860
|
+
if (!found) return "nothing of it runs any more";
|
|
1861
|
+
if ("skip" in found) return found.skip;
|
|
1862
|
+
const idleMs = found.hours * HOUR_MS;
|
|
1863
|
+
const decision = decideIdleStop(await idleStopEvidence(path, found.devices, {
|
|
1864
|
+
now,
|
|
1865
|
+
idleMs,
|
|
1866
|
+
locked: true,
|
|
1867
|
+
serving: found.serving,
|
|
1868
|
+
operation
|
|
1869
|
+
}), {
|
|
1870
|
+
idleMs,
|
|
1871
|
+
now
|
|
1872
|
+
});
|
|
1873
|
+
return decision.stop ? null : decision.reason;
|
|
1874
|
+
};
|
|
1875
|
+
const signal = operation?.signal;
|
|
1876
|
+
const run = await withIdleWorkspace(path, async () => {
|
|
1877
|
+
try {
|
|
1878
|
+
return await withWorkspaceProcessLock(workspaceDir(path), "metro-start", async () => {
|
|
1879
|
+
const active = await stillIdle();
|
|
1880
|
+
if (active) return kept$1(active);
|
|
1881
|
+
const stopped = await runStop({
|
|
1882
|
+
root: path,
|
|
1883
|
+
operation,
|
|
1884
|
+
report: () => {},
|
|
1885
|
+
requester: { by: `${by} (${action.reason})` },
|
|
1886
|
+
releaseLeases: () => []
|
|
1887
|
+
});
|
|
1888
|
+
return stopped.ok ? {
|
|
1889
|
+
status: "done",
|
|
1890
|
+
bytes: 0,
|
|
1891
|
+
detail: stopped.summary
|
|
1892
|
+
} : {
|
|
1893
|
+
status: "failed",
|
|
1894
|
+
bytes: 0,
|
|
1895
|
+
detail: stopped.summary
|
|
1896
|
+
};
|
|
1897
|
+
}, {
|
|
1898
|
+
external: true,
|
|
1899
|
+
waitMs: 0,
|
|
1900
|
+
ownerPurpose: "idle stop",
|
|
1901
|
+
signal,
|
|
1902
|
+
declareSpawnsFor: operation
|
|
1903
|
+
});
|
|
1904
|
+
} catch (error) {
|
|
1905
|
+
if (error instanceof WorkspaceProcessCleanupError || error instanceof Error && "reportCleanup" in error) throw error;
|
|
1906
|
+
signal?.throwIfAborted();
|
|
1907
|
+
if (workspaceProcessLockError(error)) return kept$1("a stim start holds its metro-start lock");
|
|
1908
|
+
throw error;
|
|
1909
|
+
}
|
|
1910
|
+
}, {
|
|
1911
|
+
purpose: "automatic maintenance",
|
|
1912
|
+
devServer: false,
|
|
1913
|
+
operation
|
|
1914
|
+
});
|
|
1915
|
+
return run.ran ? run.value : kept$1(`in use: ${run.reasons.join("; ")}`);
|
|
1916
|
+
}
|
|
1917
|
+
//#endregion
|
|
1489
1918
|
//#region src/workspace/running-from.ts
|
|
1490
1919
|
const LIST_TIMEOUT_MS = 1e4;
|
|
1491
1920
|
function parsePs(text) {
|
|
@@ -2518,7 +2947,7 @@ async function planPressureLevels(level, context) {
|
|
|
2518
2947
|
function triggeringRoot(operation) {
|
|
2519
2948
|
return canonicalPath(findProjectRoot$1(operation?.cwd ?? process.cwd()) ?? join(configDir(), "maintenance", "no-project"));
|
|
2520
2949
|
}
|
|
2521
|
-
async function plannedMaintenance(pressure, recordedSizes, settings, { devices = true, sweep = false, worktrees = false, idle = false, refresh = true, operation } = {}) {
|
|
2950
|
+
async function plannedMaintenance(pressure, recordedSizes, settings, { devices = true, sweep = false, worktrees = false, idle = false, refresh = true, background = false, operation } = {}) {
|
|
2522
2951
|
const env = operation?.env ?? process.env;
|
|
2523
2952
|
const resolved = resolveBudget({ env });
|
|
2524
2953
|
if (resolved.error) throw new Error(resolved.error);
|
|
@@ -2594,7 +3023,7 @@ async function plannedMaintenance(pressure, recordedSizes, settings, { devices =
|
|
|
2594
3023
|
recentlyUsed: (workspace) => recentUse(workspace, settings)
|
|
2595
3024
|
});
|
|
2596
3025
|
const merge = (extra) => {
|
|
2597
|
-
for (const action of extra.actions) if (!result.actions.some((entry) => entry.kind === action.kind && entry.target === action.target && (entry.level === action.level || action.kind === "would-delete-devices"))) result.actions.push(action);
|
|
3026
|
+
for (const action of extra.actions) if (!result.actions.some((entry) => entry.kind === action.kind && entry.target === action.target && (entry.level === action.level || action.kind === "would-delete-devices") && (action.check !== "idle" || entry.check === "idle"))) result.actions.push(action);
|
|
2598
3027
|
result.blocked.push(...extra.blocked);
|
|
2599
3028
|
result.skips.push(...extra.skips);
|
|
2600
3029
|
};
|
|
@@ -2621,11 +3050,27 @@ async function plannedMaintenance(pressure, recordedSizes, settings, { devices =
|
|
|
2621
3050
|
merge(planned);
|
|
2622
3051
|
result.worktreeSweep = planned.sweep;
|
|
2623
3052
|
}
|
|
2624
|
-
if (idle && devices)
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
3053
|
+
if (idle && devices) {
|
|
3054
|
+
merge(planIdleShutdown({
|
|
3055
|
+
protectedRoot: root,
|
|
3056
|
+
now: Date.now(),
|
|
3057
|
+
env
|
|
3058
|
+
}));
|
|
3059
|
+
const now = Date.now();
|
|
3060
|
+
try {
|
|
3061
|
+
merge(await planIdleStop({
|
|
3062
|
+
protectedRoot: background ? "" : root,
|
|
3063
|
+
now,
|
|
3064
|
+
env,
|
|
3065
|
+
operation,
|
|
3066
|
+
devices: operation ? cachedDeviceActivityAsync(now, env, operation.signal, operation) : cachedDeviceActivity(now)
|
|
3067
|
+
}));
|
|
3068
|
+
} catch (error) {
|
|
3069
|
+
if (error instanceof WorkspaceProcessCleanupError || error instanceof Error && "reportCleanup" in error) throw error;
|
|
3070
|
+
operation?.signal.throwIfAborted();
|
|
3071
|
+
result.blocked.push(`idle stop could not be planned: ${error instanceof Error ? error.message : String(error)}`);
|
|
3072
|
+
}
|
|
3073
|
+
}
|
|
2629
3074
|
if (pressure) {
|
|
2630
3075
|
const pressured = await planPressureLevels(diskPressureLevel(lowestFree(pressure.disk), budget, settings), {
|
|
2631
3076
|
settings,
|
|
@@ -3114,7 +3559,12 @@ async function executeAction(action, context) {
|
|
|
3114
3559
|
case "would-delete-parked-device": return deleteParkedDevice(action);
|
|
3115
3560
|
case "would-delete-devices": return deleteDevices(action, context);
|
|
3116
3561
|
case "would-shutdown-device": return action.check === "disk" ? kept("automatic maintenance does not stop devices or dev servers for disk") : shutDownIdleDevice(action);
|
|
3117
|
-
case "would-stop-workspace":
|
|
3562
|
+
case "would-stop-workspace":
|
|
3563
|
+
if (action.level === 3) return stopWorkspace(action, context);
|
|
3564
|
+
return action.check === "idle" ? stopIdleWorkspace(action, {
|
|
3565
|
+
protectedRoot: context.background ? "" : context.protectedRoot,
|
|
3566
|
+
devices: () => cachedDeviceActivity(Date.now())
|
|
3567
|
+
}) : kept("automatic maintenance stops dev servers only at disk pressure level 3 or after maintenance.idleStopHours");
|
|
3118
3568
|
case "would-clear-build-dirs":
|
|
3119
3569
|
case "would-delete-dependencies": return clearArtifacts(action, context);
|
|
3120
3570
|
case "would-stop-gradle-daemons": return stopGradleDaemonsAction(action);
|
|
@@ -3128,4 +3578,4 @@ function diskRecovered(budget) {
|
|
|
3128
3578
|
return measureDisk().every((disk) => disk.freeMb >= floor);
|
|
3129
3579
|
}
|
|
3130
3580
|
//#endregion
|
|
3131
|
-
export {
|
|
3581
|
+
export { candidateRootsAsync as C, worktreeRemovalReason as D, worktreePullRequestNote as E, maintenancePinned as S, removeWorktrees as T, finishedWorkspaces as _, previewMaintenance as a, cachedDeviceActivity as b, deleteTempLeftovers as c, appRoots as d, artifactWorktrees as f, stopIdleWorkspace as g, planIdleStop 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, measureOwnedDevices as v, collectWorktreeSweep as w, cachedDeviceActivityAsync as x, ownedDeviceUsage as y };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { D as ownership_claim_exports, S as process_identity_exports, m as declareSpawnsOn, t as getExecutor, v as stopDeclaringSpawnsOn } from "./exec-aULwtNly.mjs";
|
|
2
|
-
import { M as withDirLock$1, N as withDirLockAsync$1, c as withWorkspaceStateLock, d as writeWorkspaceState, k as workspaceLogsDir$1, l as withWorkspaceStateLockAsync, n as clearWorkspaceStateKeys, r as readWorkspaceState$1 } from "./workspace-state-
|
|
3
|
-
import { U as parseDeviceSlotKey, V as deviceSlotKey, d as getConfigDir, q as validateDeviceSlot } from "./config-
|
|
4
|
-
import { a as formatElapsed, i as formatDuration, m as shortHash } from "./command-output-
|
|
2
|
+
import { M as withDirLock$1, N as withDirLockAsync$1, c as withWorkspaceStateLock, d as writeWorkspaceState, k as workspaceLogsDir$1, l as withWorkspaceStateLockAsync, n as clearWorkspaceStateKeys, r as readWorkspaceState$1 } from "./workspace-state-DGwkPXwq.mjs";
|
|
3
|
+
import { U as parseDeviceSlotKey, V as deviceSlotKey, d as getConfigDir, q as validateDeviceSlot } from "./config-AbUjIBOQ.mjs";
|
|
4
|
+
import { a as formatElapsed, i as formatDuration, m as shortHash } from "./command-output-BBW8eWPL.mjs";
|
|
5
5
|
import { n as runOperationFileQuiet } from "./operation-exec-Dp4FuIGR.mjs";
|
|
6
|
-
import { C as resolveBuild } from "./build-cache-
|
|
6
|
+
import { C as resolveBuild } from "./build-cache-DlC3owap.mjs";
|
|
7
7
|
import { randomBytes } from "node:crypto";
|
|
8
8
|
import { closeSync, fstatSync, mkdirSync, openSync, readFileSync, readSync, readdirSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
9
9
|
import { homedir } from "node:os";
|
|
@@ -814,7 +814,8 @@ function classifyActivity(evidence, now) {
|
|
|
814
814
|
state: "driven",
|
|
815
815
|
driver,
|
|
816
816
|
...lastActivityAt,
|
|
817
|
-
basis: [...new Set(evidence.drivers.map((entry) => entry.basis))]
|
|
817
|
+
basis: [...new Set(evidence.drivers.map((entry) => entry.basis))],
|
|
818
|
+
...evidence.unknown.length ? { unknown: [...new Set(evidence.unknown)] } : {}
|
|
818
819
|
};
|
|
819
820
|
}
|
|
820
821
|
if (evidence.unknown.length) return {
|
package/dist/{agent-device-usage-output-tE90fDdo.mjs → agent-device-usage-output-DYBpO17K.mjs}
RENAMED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { S as process_identity_exports } from "./exec-aULwtNly.mjs";
|
|
2
|
-
import { P as formatBytes } from "./config-
|
|
3
|
-
import { o as formatLongDuration } from "./command-output-
|
|
4
|
-
import { bt as measureDu, u as listWorkspaceDirs, xt as writeUsageCache, yt as canonical } from "./workspaces-
|
|
5
|
-
import { c as parseAgentDeviceRecord, o as envDir, u as processMatches } from "./activity-
|
|
2
|
+
import { P as formatBytes } from "./config-AbUjIBOQ.mjs";
|
|
3
|
+
import { o as formatLongDuration } from "./command-output-BBW8eWPL.mjs";
|
|
4
|
+
import { bt as measureDu, u as listWorkspaceDirs, xt as writeUsageCache, yt as canonical } from "./workspaces-7_RWoi6c.mjs";
|
|
5
|
+
import { c as parseAgentDeviceRecord, o as envDir, u as processMatches } from "./activity-BTaUf0tc.mjs";
|
|
6
6
|
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
7
7
|
import { homedir } from "node:os";
|
|
8
8
|
import { isAbsolute, join, relative, sep } from "node:path";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { i as formatDuration, l as phaseLine, m as shortHash } from "./command-output-
|
|
2
|
-
import { E as resolveVariant, T as resolveSystemImage, _ as findAapt, b as noDeviceDiagnostic, d as androidVariantSetting, f as apkDevClientFacts, g as dumpApkManifest, h as displayPath, i as NO_FINGERPRINT, p as apkPackage, r as NO_DEVICE, s as androidDevClientScheme, u as androidSystemImageSetting, x as parseXmltree, y as isReleaseVariant } from "./support-
|
|
3
|
-
import { r as lastBuildRecord, t as androidFacts } from "./result-
|
|
4
|
-
import { i as runAndroidOperation, n as registerAndroid, r as runAndroid, t as androidCommand } from "./android-
|
|
5
|
-
import { a as collectorLogFile, o as killPreviousCollector, s as startCollector } from "./launch-
|
|
1
|
+
import { i as formatDuration, l as phaseLine, m as shortHash } from "./command-output-BBW8eWPL.mjs";
|
|
2
|
+
import { E as resolveVariant, T as resolveSystemImage, _ as findAapt, b as noDeviceDiagnostic, d as androidVariantSetting, f as apkDevClientFacts, g as dumpApkManifest, h as displayPath, i as NO_FINGERPRINT, p as apkPackage, r as NO_DEVICE, s as androidDevClientScheme, u as androidSystemImageSetting, x as parseXmltree, y as isReleaseVariant } from "./support-BGqpYMV8.mjs";
|
|
3
|
+
import { r as lastBuildRecord, t as androidFacts } from "./result-W4HCum4A.mjs";
|
|
4
|
+
import { i as runAndroidOperation, n as registerAndroid, r as runAndroid, t as androidCommand } from "./android-BWqdDK6R.mjs";
|
|
5
|
+
import { a as collectorLogFile, o as killPreviousCollector, s as startCollector } from "./launch-DvJV1Mx4.mjs";
|
|
6
6
|
export { NO_DEVICE, NO_FINGERPRINT, androidDevClientScheme, androidFacts, androidSystemImageSetting, androidVariantSetting, apkDevClientFacts, apkPackage, collectorLogFile, androidCommand as default, displayPath, dumpApkManifest, findAapt, formatDuration, isReleaseVariant, killPreviousCollector, lastBuildRecord, noDeviceDiagnostic, parseXmltree, phaseLine, registerAndroid, resolveSystemImage, resolveVariant, runAndroid, runAndroidOperation, shortHash, startCollector };
|