stim 1.20.2 → 1.21.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/README.md +88 -8
- package/dist/acquire-artifact-CD4lbiWE.mjs +153 -0
- package/dist/act-DHAw2A2S.mjs +2667 -0
- package/dist/activity-BzVfHSrY.mjs +1376 -0
- package/dist/{agent-device-usage-output-Dzgv6lgR.mjs → agent-device-usage-output-zh1vhbLp.mjs} +21 -65
- package/dist/{android-HqP1_vB_.mjs → android-BEJ8Jpl7.mjs} +2 -2
- package/dist/{android-DCKZrNvV.mjs → android-BLgbNqox.mjs} +128 -78
- package/dist/{android-Dlzxshgp.mjs → android-CV_GCELZ.mjs} +5 -5
- package/dist/{android-Mz_Inn3w.mjs → android-DUYkNF4u.mjs} +184 -102
- package/dist/{android-cas-Bl-cLJBk.mjs → android-cas-Ct5b1xCK.mjs} +7 -6
- package/dist/android-cas-compiler.mjs +2 -2
- package/dist/android-project-BCAAmMwz.mjs +12 -0
- package/dist/api.d.mts +740 -8
- package/dist/api.mjs +585 -1
- package/dist/{artifact-HSwkIWEQ.mjs → artifact-B8T3S5gi.mjs} +223 -201
- package/dist/{artifact-D3czlUvT.mjs → artifact-DAuZ-FNU.mjs} +158 -148
- package/dist/{browser-web-CA-F1GQo.mjs → browser-web-QQzVjz3O.mjs} +26 -24
- package/dist/budget-Bs6SxxzO.mjs +9154 -0
- package/dist/{build-DYDbfkk5.mjs → build-CoPzQRNw.mjs} +144 -96
- package/dist/build-cache-DmyR9Zzc.mjs +602 -0
- package/dist/build-plan-CaFskB7_.mjs +188 -0
- package/dist/{cache-manifest-XH-fvDUj.mjs → cache-manifest-DkkqguoK.mjs} +2 -2
- package/dist/cache-manifest.mjs +1 -1
- package/dist/{ccache-zdKiYQ3E.mjs → ccache-BJRZ9pG3.mjs} +10 -9
- package/dist/{cdp-Dq_ypAlJ.mjs → cdp-CWmIUMbw.mjs} +18 -5
- package/dist/{chrome-BnzZMqsR.mjs → chrome-B6tfCta1.mjs} +7 -4
- package/dist/{cli-CLP3diBm.mjs → cli-0DYf8QhQ.mjs} +20 -20
- package/dist/cli.mjs +1 -1
- package/dist/client-B7QVOlCr.d.mts +253 -0
- package/dist/client-UXD70ZbM.mjs +1406 -0
- package/dist/collector-run.d.mts +4 -40
- package/dist/collector-run.mjs +9 -8
- package/dist/{command-output-BTy8hZ0F.mjs → command-output-B1UrjZHL.mjs} +1 -1
- package/dist/config-CYcBF478.mjs +949 -0
- package/dist/{created-devices-Dzd5C2LF.mjs → created-devices-CqeBlrEn.mjs} +3 -3
- package/dist/{dependency-state-DG0p31-y.mjs → dependency-state-BbKQW83h.mjs} +20 -5
- package/dist/{detached-entry-B9C_zeQC.mjs → detached-entry-DFRyG1_o.mjs} +1 -1
- package/dist/{dev-client-DAWVIGBu.mjs → dev-client-UOeESKm6.mjs} +2 -2
- package/dist/device-DCxH7_By.mjs +1068 -0
- package/dist/{device-BECOiufl.mjs → device-ExJq8Ei7.mjs} +35 -35
- package/dist/{device-capacity-CBUAcRyQ.mjs → device-capacity-CMlqEcvw.mjs} +43 -13
- package/dist/device-host-worker.mjs +65 -61
- package/dist/{device-ios-COSi6oS1.mjs → device-ios-DRUeKaFV.mjs} +48 -45
- package/dist/{device-lease-run-Cw2M4z51.mjs → device-lease-run-C8raGFoP.mjs} +14 -26
- package/dist/{device-pool-Bf-pOhSw.mjs → device-pool-DMRpVX9a.mjs} +5 -5
- package/dist/doctor-BLHCYxzi.mjs +2 -0
- package/dist/{doctor-kfMBnUw6.mjs → doctor-DTvaDOda.mjs} +281 -317
- package/dist/{doctor-CB8oZKCk.mjs → doctor-Dhqebm0q.mjs} +183 -91
- package/dist/doctor-fingerprint.mjs +19 -0
- package/dist/{doctor-watchman-BRyV2adA.mjs → doctor-watchman-Cv1F10Kj.mjs} +40 -21
- package/dist/{eas-build-JyfqyHfC.mjs → eas-build-BomfRnFT.mjs} +53 -20
- package/dist/{build-plan-B7SZsc2N.mjs → eas-fallback-DJwZpy0c.mjs} +26 -208
- package/dist/{watchman-CPQFZLXY.mjs → eas-session-ledger-op6A54yi.mjs} +229 -11
- package/dist/{error-diagnostics-BR677IDM.mjs → error-diagnostics-Bf0rZvG9.mjs} +172 -82
- package/dist/exec-H20xSg2T.d.mts +65 -0
- package/dist/exec-_UbtCQcG.mjs +750 -0
- package/dist/gc-C-WwL0yi.mjs +3 -0
- package/dist/{gc-qWOMdnER.mjs → gc-_-dCXdyL.mjs} +584 -796
- package/dist/git-C3iTsJaZ.mjs +73 -0
- package/dist/{guide-G9cAbVAc.mjs → guide-Yqwt2bd6.mjs} +941 -269
- package/dist/{hosted-android-C3MHGld1.mjs → hosted-android-Bw-honsd.mjs} +8 -6
- package/dist/{hosted-client-ZEKpS9vw.mjs → hosted-client-DB_gBPfY.mjs} +34 -19
- package/dist/{hosted-ios-l-o3iM9J.mjs → hosted-ios-CUvOf4Vr.mjs} +1 -1
- package/dist/{hosted-logs-EzQM7-3Z.mjs → hosted-logs-DL_P5AdN.mjs} +77 -43
- package/dist/{hosted-macos-BACVAVqE.mjs → hosted-macos-QI141yKk.mjs} +21 -17
- package/dist/{hosted-native-A4s1QPXe.mjs → hosted-native-Ksyjgzq-.mjs} +30 -21
- package/dist/idle-BVeRGroT.d.mts +24 -0
- package/dist/{idle-shutdown-DtxhPTKe.mjs → idle-shutdown-DaKmZi0z.mjs} +11 -10
- package/dist/{ios-BwVCF7oA.mjs → ios-CQ68hG9s.mjs} +8 -8
- package/dist/{ios-RkW4pnQf.mjs → ios-CpByZy12.mjs} +140 -80
- package/dist/{ios-device-B5veSDDQ.mjs → ios-device-CXGP1bsD.mjs} +1 -1
- package/dist/{ios-device-D7pi2Sca.mjs → ios-device-CwFMehUS.mjs} +51 -26
- package/dist/{ios-project-K9hY_Jab.mjs → ios-project-WuwwBdvW.mjs} +13 -13
- package/dist/{ios-nOLJGVdy.mjs → ios-qNJt4dFm.mjs} +1 -1
- package/dist/ios-signing-DTTIChGs.mjs +489 -0
- package/dist/{ios-state-CBLe1xYw.mjs → ios-state-DvFX-K_l.mjs} +1 -1
- package/dist/{ios-Ce7bc7br.mjs → ios-ubFsBzwq.mjs} +129 -86
- package/dist/{js-swap-Bb3nsS07.mjs → js-swap-Cc1dttps.mjs} +53 -26
- package/dist/{launch-F4sOqAhB.mjs → launch-CD1yVc7U.mjs} +91 -90
- package/dist/{launch-C3qJ6Agb.mjs → launch-Zq2mOSDy.mjs} +82 -541
- package/dist/logs-BS00Anxf.mjs +352 -0
- package/dist/logs-CMm05HxN.mjs +255 -0
- package/dist/{macos-D7uDvO-z.mjs → macos-B65--pPd.mjs} +1 -1
- package/dist/{macos-Ch5VJmcS.mjs → macos-C-0qJ6zq.mjs} +225 -212
- package/dist/macos-run.mjs +1 -1
- package/dist/maintenance-run.mjs +122 -247
- package/dist/{metro-DnCEjCxs.mjs → metro-DEXpIhHC.mjs} +67 -12
- package/dist/{metro-gateway-CX9Xlkq2.mjs → metro-gateway-BMJNlj3E.mjs} +20 -12
- package/dist/{named-ports-4WopRPg-.mjs → named-ports-BWTzt6mu.mjs} +8 -63
- package/dist/native-android-JACyjTZs.mjs +844 -0
- package/dist/{native-gradle-inputs-BsLRrl7u.mjs → native-gradle-inputs-Bep9JcSF.mjs} +128 -140
- package/dist/native-inputs-TRTTTRxt.mjs +91 -0
- package/dist/native-run-DY_RLx3C.mjs +277 -0
- package/dist/{native-runtime-k8dTIrbK.mjs → native-runtime-Dg1Q7tfF.mjs} +9 -8
- package/dist/{native-xcode-inputs-CykopJdM.mjs → native-xcode-inputs-CB2iQeWq.mjs} +27 -18
- package/dist/{native-xcode-ios-Bbf30Gm0.mjs → native-xcode-ios-CXX39F7o.mjs} +96 -47
- package/dist/{ndjson-GOnbyvso.mjs → ndjson-CgE_o3Dl.mjs} +3 -3
- package/dist/offload-worker.d.mts +1 -46
- package/dist/offload-worker.mjs +197 -66
- package/dist/{ownership-DCtw_2IA.mjs → ownership-DEmM5vhh.mjs} +3 -3
- package/dist/{page-DRHy329N.mjs → page-CPaHeYqj.mjs} +7 -4
- package/dist/paths-BsJMoPP2.mjs +12 -0
- package/dist/paths-DQtTgsBf.mjs +42 -0
- package/dist/{placement-log-MOfPVgaM.mjs → placement-log-BqGbTa61.mjs} +5 -5
- package/dist/{plan-placement-V0TdzYXp.mjs → plan-placement-Bwj-IjY1.mjs} +6 -6
- package/dist/{ports-DdSUicVo.mjs → ports-D-MmCTdv.mjs} +3 -3
- package/dist/prebuild-uD_ipCxF.mjs +449 -0
- package/dist/{project-_phNIJfs.mjs → project-BZNjmW_8.mjs} +65 -37
- package/dist/{pull-request-CQ8sPbZa.mjs → pull-request-Lfetn8Kr.mjs} +2 -2
- package/dist/pull-request-zjCSAryH.d.mts +120 -0
- package/dist/pull-requests.d.mts +1 -119
- package/dist/pull-requests.mjs +1 -1
- package/dist/{react-native-android-CM1XRDwv.mjs → react-native-android-DuzH0cn3.mjs} +74 -48
- package/dist/{gradle-DSrXb6lG.mjs → react-native-build-rhk4smwQ.mjs} +292 -15
- package/dist/react-native-doctor-CQpuIMso.mjs +234 -0
- package/dist/{react-native-ios-Dhq_eiYQ.mjs → react-native-ios-Bhq1rJeV.mjs} +46 -28
- package/dist/{recordings-D0d5aQt0.mjs → recordings-DYteQSu4.mjs} +12 -9
- package/dist/{reload-C8JhxjSh.mjs → reload-CmTRFJaX.mjs} +93 -47
- package/dist/reload-DzjSl5P_.mjs +2 -0
- package/dist/{remote-BiR6aYjy.mjs → remote-ByYkXdGD.mjs} +15 -10
- package/dist/result-DNiS-tTP.mjs +434 -0
- package/dist/{run-BtPgpKks.mjs → run-D23HmJMs.mjs} +4 -5
- package/dist/selection-CSl9i5qU.mjs +619 -0
- package/dist/{server-bare-R2m_gsH8.mjs → server-bare-CxTrvDg8.mjs} +3 -4
- package/dist/{server-command-CTtCkmcQ.mjs → server-command-CtzloH3v.mjs} +14 -7
- package/dist/server-expo-C-90EhcG.mjs +2 -0
- package/dist/{server-expo-DsguMGUF.mjs → server-expo-DT_F_uVI.mjs} +50 -9
- package/dist/{settings-B717odTD.mjs → settings-CsJDEXgK.mjs} +234 -24
- package/dist/{settings-vk3mJGSm.d.mts → settings-DkdmlelE.d.mts} +6 -4
- package/dist/settings-T1gtc3bf.mjs +114 -0
- package/dist/settings-write-HyVZ8eQ8.mjs +359 -0
- package/dist/settings.schema.json +163 -16
- package/dist/{simslim-CCr3rE-A.mjs → simslim-Cgk17SXV.mjs} +14 -12
- package/dist/{slot-launch-DPt0m9Nd.mjs → slot-launch-DF8VfT64.mjs} +15 -20
- package/dist/{spawn-entry-Dcb7sDUz.mjs → spawn-entry-jw19m8Nl.mjs} +0 -1
- package/dist/stage-BIS0ydsV.mjs +183 -0
- package/dist/{start-BWqzODpb.mjs → start-7lpH7hmN.mjs} +63 -44
- package/dist/{start-TXeMmmO2.mjs → start-RChynRDp.mjs} +1 -1
- package/dist/{state-D1Icyjlu.mjs → state-C4ZtUisW.mjs} +40 -13
- package/dist/{state-CG_OFoaA.mjs → state-XMziexv2.mjs} +3 -2
- package/dist/{stats-BoY5sEPU.mjs → stats-53T7OTb9.mjs} +7 -13
- package/dist/stats-report-BFfMpWWF.mjs +16 -0
- package/dist/{status-WgFbkRzj.mjs → status-BL7jVyAB.mjs} +535 -447
- package/dist/status-CSi6tlRq.mjs +2 -0
- package/dist/{status-BTA7kKiQ.mjs → status-DqEUSSxs.mjs} +6 -4
- package/dist/{status-watch-C23ILtf9.mjs → status-watch-GDCfqpTE.mjs} +187 -22
- package/dist/status-worker.d.mts +1 -0
- package/dist/status-worker.mjs +19 -0
- package/dist/stim-desktop-C12we7lz.mjs +112 -0
- package/dist/{stop-DR6VoDIk.mjs → stop-Bk_1qiV6.mjs} +2 -2
- package/dist/{stop-BNmBMi1F.mjs → stop-CPzlM1L-.mjs} +138 -98
- package/dist/{stop-DPEhunlw.mjs → stop-D7h6jAXQ.mjs} +11 -10
- package/dist/supervisor-run.d.mts +8 -17
- package/dist/supervisor-run.mjs +63 -27
- package/dist/{support-DMTqj3Hm.mjs → support-67vraa1Q.mjs} +18 -11
- package/dist/{support-CwjbFs9H.mjs → support-Dlu37g6H.mjs} +12 -12
- package/dist/{swiftpm-macos-DRNVJWlb.mjs → swiftpm-macos-p8WZbxKU.mjs} +35 -24
- package/dist/toolchain-DhKwp9iI.mjs +2 -0
- package/dist/toolchain-Hp9sCpK4.mjs +873 -0
- package/dist/{trigger-CigAYjeL.mjs → trigger-BAahxUPq.mjs} +20 -5
- package/dist/trigger-Bf3uDcpv.mjs +2 -0
- package/dist/{warm-progress-BuY-Fvfn.mjs → warm-progress-BHX5r0Ei.mjs} +250 -156
- package/dist/{web-BDBMxDpx.mjs → web-CJmIj6AI.mjs} +18 -13
- package/dist/web-DknQETPs.mjs +2 -0
- package/dist/web-run.mjs +11 -12
- package/dist/windows-report.d.mts +1 -0
- package/dist/windows-report.mjs +18 -0
- package/dist/windows-report.ps1 +43 -0
- package/dist/workspace-process-lock-1_1OoVW5.mjs +57 -0
- package/dist/{workspace-state-DJt_MMvf.mjs → workspace-state-Cjuigeeu.mjs} +62 -58
- package/dist/{workspaces-C36s2jb9.mjs → workspaces-BccMFmGQ.mjs} +1188 -1079
- package/dist/worktree-CK2MpJW5.mjs +2 -0
- package/dist/{worktree-CgvJYJ-Q.mjs → worktree-DQ6Zi2Mv.mjs} +304 -53
- package/dist/xcode-Zlx3qjEs.mjs +896 -0
- package/package.json +7 -5
- package/shim/android-optimizations.gradle +7 -5
- package/dist/activity-BSV745Kz.mjs +0 -629
- package/dist/api-qvOzWyfO.mjs +0 -154
- package/dist/api-run.mjs +0 -294
- package/dist/app-install-BIKtMfPq.mjs +0 -896
- package/dist/artifact-lifecycle-DzPpBYvK.mjs +0 -30
- package/dist/budget-f7516Zk0.mjs +0 -4106
- package/dist/build-facts-DcLv2HSd.d.mts +0 -111
- package/dist/cancellation-C_22VQTH.mjs +0 -24
- package/dist/client-qQAaXSUs.mjs +0 -1771
- package/dist/config-BYDxlMY3.mjs +0 -562
- package/dist/device-DuiPJQSn.mjs +0 -290
- package/dist/device-lease-BX1sJQ2E.mjs +0 -1224
- package/dist/device-remote-xRT0Vmo9.mjs +0 -1272
- package/dist/eas-session-ledger-Cm0Gwq2F.mjs +0 -207
- package/dist/exec-DqKo9GKJ.mjs +0 -268
- package/dist/git-DDfFzkMm.mjs +0 -45
- package/dist/launch-verify-B6Q8hZP-.mjs +0 -428
- package/dist/logs-BGrEUaEs.mjs +0 -383
- package/dist/miss-reason-mKzZ4VvN.mjs +0 -238
- package/dist/native-android-D5qc3-_v.mjs +0 -226
- package/dist/ndjson-Du3j0AQ9.d.mts +0 -17
- package/dist/plan-C4TjdPsR.mjs +0 -260
- package/dist/prebuild-DYbucPXy.mjs +0 -212
- package/dist/preview-78a9kR_-.mjs +0 -1011
- package/dist/react-native-build-CtCccJtb.mjs +0 -239
- package/dist/react-native-doctor-CfRnFfjs.mjs +0 -78
- package/dist/remote-cache-OyOyVIS3.mjs +0 -526
- package/dist/result-CaJg5Iat.mjs +0 -186
- package/dist/server-expo-Bigriskl.mjs +0 -2
- package/dist/settings-BORNaaCO.mjs +0 -402
- package/dist/spawn-claims-DVS5RkMS.mjs +0 -72
- package/dist/stage-KNTQopqv.mjs +0 -157
- package/dist/stim-desktop-BzBN2Em2.mjs +0 -63
- package/dist/tailnet-Dh-qiYzG.mjs +0 -265
- package/dist/toolchain-BFkAcstd.mjs +0 -2
- package/dist/toolchain-DxSsNssu.mjs +0 -1657
- package/dist/trigger-9_USgmxz.mjs +0 -2
- package/dist/web-Dq-i3wzJ.mjs +0 -2
- package/dist/worktree-DpLdCHga.mjs +0 -2
- package/dist/{api-run.d.mts → doctor-fingerprint.d.mts} +0 -0
- package/dist/{errors-DzkMYh8Q.mjs → errors-ccaPc4ox.mjs} +2 -2
|
@@ -1,41 +1,39 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import { a as
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import { b as parseSimctlList, f as listAllIosSimsAsync } from "./ios-
|
|
18
|
-
import {
|
|
19
|
-
import
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import "./
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import { n as
|
|
27
|
-
import { a as watchStatusSources, i as watchPayload, n as WATCH_LIGHT_INTERVAL_MS, r as createRefreshScheduler, t as WATCH_FALLBACK_MS } from "./status-watch-C23ILtf9.mjs";
|
|
1
|
+
import { p as process_identity_exports, t as getExecutor } from "./exec-_UbtCQcG.mjs";
|
|
2
|
+
import { m as workspaceLogsDir$1, p as workspaceLogErrorIndex } from "./paths-DQtTgsBf.mjs";
|
|
3
|
+
import { H as deviceSlotKey, K as projectDeviceSlots, P as formatBytes, W as parseDeviceSlotKey, _ as loadConfig$1, d as getConfigDir, z as volumeRootFor } from "./config-CYcBF478.mjs";
|
|
4
|
+
import { a as formatElapsed, i as formatDuration, r as clockTime, u as plural } from "./command-output-B1UrjZHL.mjs";
|
|
5
|
+
import { r as readWorkspaceState$1 } from "./workspace-state-Cjuigeeu.mjs";
|
|
6
|
+
import { Dt as linkedWorktreesOnDisk, Ft as repoRoot, Y as resolveSettings, bt as gitCommonDirOnDisk, ot as workspaceHiddenSetting, vt as gitCommonDir } from "./settings-CsJDEXgK.mjs";
|
|
7
|
+
import { n as gitAsync } from "./git-C3iTsJaZ.mjs";
|
|
8
|
+
import { I as readWorkspaceLaunches, M as readMetroTunnel, P as readRemoteSession, S as readAppJson, a as findServerWorkspace, l as projectShortcut, u as detectPlatforms, v as detectIsExpo, y as detectTutorial } from "./project-BZNjmW_8.mjs";
|
|
9
|
+
import { a as parseNdjsonLine } from "./ndjson-CgE_o3Dl.mjs";
|
|
10
|
+
import { a as listeningPids, d as processCwds, f as resolveProjectMetro, g as isMetroRunning, l as pidExists, s as listeningPidsByPort, u as processCwd } from "./metro-DEXpIhHC.mjs";
|
|
11
|
+
import { a as readWebPage, o as readWebRecord, u as webFacts } from "./state-C4ZtUisW.mjs";
|
|
12
|
+
import { A as remoteDeviceState, C as environmentState, D as parseDfFree, E as metroReverseTargets, M as tightVolumes, N as unprovisionedWorktrees, O as poolLine, P as withWebFacts, S as diskLine, T as gitSummaryText, _ as addReverseMissingIssue, b as deviceLeaseLines, g as activityLabel, j as statusActivity, k as remoteDeviceLine, r as readEasSessionLedger$1, v as applyMachineMemory, x as deviceLeaseStates, y as capacity } from "./eas-session-ledger-op6A54yi.mjs";
|
|
13
|
+
import { F as buildStatusLine, G as readStats$1, I as bundlingActivity, N as activeBuildState, P as buildReport, R as parseActiveBuild, Y as statsProjectKey$1, h as describeMetroLastStop, j as ACTIVE_BUILD_KEY, o as machineNumber, vn as hasMetroReverse, vr as attributeMachineUsage, y as metroLastStop, yr as readFootprints } from "./budget-Bs6SxxzO.mjs";
|
|
14
|
+
import { m as resolveSupervisorTarget } from "./workspaces-BccMFmGQ.mjs";
|
|
15
|
+
import { a as createDeviceProcessTables, b as leaseIsExpired, h as tailLines, m as readWebActivity, r as createActivityReader, w as parseWorkspaceLeases, x as listLeaseFiles } from "./activity-BzVfHSrY.mjs";
|
|
16
|
+
import { H as ownedAvdSerialResolver, R as ownedAvdDeviceProfile, gt as readParked, ht as parkedMaxSetting, k as listAdbDevices, lt as POOL_SETTING_REMEDY } from "./android-DUYkNF4u.mjs";
|
|
17
|
+
import { b as parseSimctlList, f as listAllIosSimsAsync } from "./ios-CpByZy12.mjs";
|
|
18
|
+
import { f as probeHostedSession } from "./hosted-client-DB_gBPfY.mjs";
|
|
19
|
+
import "./hosted-macos-QI141yKk.mjs";
|
|
20
|
+
import { i as readSupervisorState } from "./stop-CPzlM1L-.mjs";
|
|
21
|
+
import { n as maintenanceLines, r as maintenanceStatus } from "./status-DqEUSSxs.mjs";
|
|
22
|
+
import { f as mergeState, i as createStatusMeasurer, n as workspacePhase, r as applyStatusMeasures } from "./warm-progress-BHX5r0Ei.mjs";
|
|
23
|
+
import { r as workspaceRecordingEnabled } from "./recordings-DYteQSu4.mjs";
|
|
24
|
+
import { d as readIosDevices, s as isReachable } from "./ios-device-CwFMehUS.mjs";
|
|
25
|
+
import { t as triggerMaintenance } from "./trigger-BAahxUPq.mjs";
|
|
26
|
+
import { a as createRefreshScheduler, c as watchStatusSources, n as WATCH_LIGHT_INTERVAL_MS, o as watchChangeKey, r as WATCH_MACHINE_INTERVAL_MS, s as watchPayload, t as WATCH_FALLBACK_MS } from "./status-watch-GDCfqpTE.mjs";
|
|
28
27
|
import { t as watchStdoutReader } from "./stdout-reader-C8yjre1x.mjs";
|
|
29
|
-
import {
|
|
28
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
30
29
|
import { mkdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
31
30
|
import { join, posix, resolve } from "node:path";
|
|
32
|
-
import { basename as basename$1, dirname as dirname$1, join as join$1 } from "path";
|
|
33
|
-
import { DEVICE_RECLAIM_REASON, ERROR_SOURCES, archiveRoot, archivedUsage, bundleMarkerPlatform, countErrorEntries, gitMergeCacheDir, hostedAndroidPlacements, hostedAndroidRecords, hostedAndroidStatus, hostedIosPlacements, hostedIosRecords, hostedIosStatus, linkReplacedArchives, logFiles, macosAppState, parseHostedAndroidPlacement, parseHostedIosPlacement, queryLogs, readArchives, readBuildDetail, readBuildHistory, readDeviceIdleShutdowns, readDevicePlacement, readIdleStop, readLastBuilds, readMacosRecord, recordMatches, sortByTs, unreadableHostedAndroid, unreadableHostedIos, withDerivedFacts, withGitChip, withStateReadCache } from "@stim-cli/core/state";
|
|
34
|
-
import { closeSync as closeSync$1, existsSync as existsSync$1, fstatSync as fstatSync$1, openSync as openSync$1, readFileSync as readFileSync$1, readSync as readSync$1, renameSync as renameSync$1, rmSync as rmSync$1, statSync as statSync$1, writeFileSync as writeFileSync$1 } from "fs";
|
|
35
31
|
import { rotatedLogPath } from "@stim-cli/core";
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
32
|
+
import { DEVICE_RECLAIM_REASON, ERROR_SOURCES, archiveRoot, archivedUsage, bundleMarkerPlatform, countErrorEntries, gitMergeCacheDir, hostedAndroidPlacements, hostedAndroidRecords, hostedAndroidStatus, hostedIosPlacements, hostedIosRecords, hostedIosStatus, linkReplacedArchives, logFiles, macosAppState, parseHostedAndroidPlacement, parseHostedIosPlacement, queryLogs, readArchives, readBuildDetail, readBuildHistory, readDeviceIdleShutdowns, readDevicePlacement, readIdleStop, readLastBuilds, readMacosRecord, recordMatches, sortByTs, unreadableHostedAndroid, unreadableHostedIos, withDerivedFacts, withGitChip, withStateReadCache } from "@stim-cli/core/state";
|
|
33
|
+
import { basename as basename$1, dirname as dirname$1, join as join$1 } from "path";
|
|
38
34
|
import chalk from "chalk";
|
|
35
|
+
import { closeSync as closeSync$1, existsSync as existsSync$1, fstatSync as fstatSync$1, openSync as openSync$1, readFileSync as readFileSync$1, readSync as readSync$1, renameSync as renameSync$1, rmSync as rmSync$1, statSync as statSync$1, writeFileSync as writeFileSync$1 } from "fs";
|
|
36
|
+
import { homedir, totalmem, userInfo } from "os";
|
|
39
37
|
//#region src/device-host/hosted-native-status.ts
|
|
40
38
|
function hostedNativeProbe(placement, probe, slot, platform) {
|
|
41
39
|
const label = platform === "ios" ? "iOS" : "Android";
|
|
@@ -778,31 +776,11 @@ function physicalDeviceLine(device, now) {
|
|
|
778
776
|
return `${device.platform}${slot}: ${name} (physical${model}) ${device.connection} -- leased until ${clockTime(device.lease.expiresAt)} (${remaining} left)`;
|
|
779
777
|
}
|
|
780
778
|
//#endregion
|
|
781
|
-
//#region src/
|
|
782
|
-
const WATCH_GIT_MAX_AGE_MS = 6e4;
|
|
779
|
+
//#region src/status-read.ts
|
|
783
780
|
function iosStatusName(ios) {
|
|
784
781
|
const host = ios.host;
|
|
785
782
|
return host && !ios.udid ? `${host.device?.name ?? "iOS simulator"} (${host.device ? `iOS ${host.device.runtime.replace(/^iOS /, "")}` : "runtime pending"}) on ${host.machine}${host.selected === "auto" && host.reason ? ` (auto: ${host.reason})` : ""}` : ios.name ?? ios.udid;
|
|
786
783
|
}
|
|
787
|
-
function iosStatusLines(record, slotLabel) {
|
|
788
|
-
const out = [];
|
|
789
|
-
const host = record?.udid ? record.host : void 0;
|
|
790
|
-
const iosDevices = [record, ...host ? [{
|
|
791
|
-
host,
|
|
792
|
-
name: host.device?.name ?? null,
|
|
793
|
-
udid: "",
|
|
794
|
-
owned: false,
|
|
795
|
-
state: host.state ?? "unverified"
|
|
796
|
-
}] : []];
|
|
797
|
-
for (const ios of iosDevices) {
|
|
798
|
-
if (!ios) continue;
|
|
799
|
-
const booted = ios.state === "Booted" ? chalk.green("booted") : chalk.dim(ios.state.toLowerCase());
|
|
800
|
-
const owned = ios.owned ? chalk.dim(" (owned)") : "";
|
|
801
|
-
out.push(` ios${slotLabel}: ${chalk.cyan(iosStatusName(ios))} ${booted}${owned}${activitySuffix(ios.activity)}${appSuffix(ios.app)}${idleShutdownSuffix(ios.idleShutdown)}`);
|
|
802
|
-
if (!ios.udid && ios.host?.agent.driver === "agent-device") out.push(chalk.dim(` agent: ${ios.host.agent.command}`));
|
|
803
|
-
}
|
|
804
|
-
return out;
|
|
805
|
-
}
|
|
806
784
|
function applyHostedAndroidStates(state, saved, factsBySlot) {
|
|
807
785
|
for (const [slot, record] of Object.entries(hostedAndroidRecords(saved))) if (!parseHostedAndroidPlacement(record)) state.warnings.push(unreadableHostedAndroid(slot));
|
|
808
786
|
for (const [slot, facts] of Object.entries(factsBySlot)) {
|
|
@@ -828,23 +806,6 @@ function applyHostedAndroidStates(state, saved, factsBySlot) {
|
|
|
828
806
|
state.live ||= facts.android.state === "ready";
|
|
829
807
|
}
|
|
830
808
|
}
|
|
831
|
-
function androidStatusLines(record, slotLabel) {
|
|
832
|
-
const out = [];
|
|
833
|
-
if (record?.host && !record.serial) {
|
|
834
|
-
const host = record.host;
|
|
835
|
-
out.push(` android${slotLabel}: ${chalk.cyan(`${host.device?.name ?? "Android emulator"} on ${host.machine}${host.selected === "auto" && host.reason ? ` (auto: ${host.reason})` : ""}`)} ${host.state ?? "unverified"}`);
|
|
836
|
-
} else if (record) {
|
|
837
|
-
const kind = record.physical ? chalk.dim("(physical)") : chalk.dim("(emulator)");
|
|
838
|
-
const observed = record.state ? ` ${record.state}${record.serial ? ` (${record.serial})` : ""}` : "";
|
|
839
|
-
out.push(` android${slotLabel}: ${chalk.cyan(record.name)} ${kind}${observed}${record.owned ? chalk.dim(" (owned)") : ""}${activitySuffix(record.activity)}${appSuffix(record.app)}${idleShutdownSuffix(record.idleShutdown)}`);
|
|
840
|
-
if (record.host) {
|
|
841
|
-
const host = record.host;
|
|
842
|
-
out.push(` android${slotLabel}: ${chalk.cyan(`${host.device?.name ?? "Android emulator"} on ${host.machine}${host.selected === "auto" && host.reason ? ` (auto: ${host.reason})` : ""}`)} ${host.state ?? "unverified"}`);
|
|
843
|
-
}
|
|
844
|
-
}
|
|
845
|
-
if (record?.host?.agent.driver === "agent-device") out.push(chalk.dim(` agent: ${record.host.agent.command}`));
|
|
846
|
-
return out;
|
|
847
|
-
}
|
|
848
809
|
function doctorRunTimes(proj) {
|
|
849
810
|
const runs = {};
|
|
850
811
|
for (const platform of ["ios", "android"]) {
|
|
@@ -853,48 +814,55 @@ function doctorRunTimes(proj) {
|
|
|
853
814
|
}
|
|
854
815
|
return Object.keys(runs).length ? runs : void 0;
|
|
855
816
|
}
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
817
|
+
/**
|
|
818
|
+
* Probes that read everything when asked. `simctlListing`, when given, answers `simulators` without running simctl,
|
|
819
|
+
* `gitMaxAgeMs` reuses git summaries read that recently, and `archives` answers `archives` without reading them.
|
|
820
|
+
*/
|
|
821
|
+
function liveProbes({ simctlListing = null, gitMaxAgeMs = 0, archives } = {}) {
|
|
822
|
+
return {
|
|
823
|
+
simulators: () => simctlListing === null ? listAllIosSimsAsync() : Promise.resolve().then(() => parseSimctlList(simctlListing)),
|
|
824
|
+
metro: readMetroFacts,
|
|
825
|
+
hostedIos: readHostedIosStatus,
|
|
826
|
+
hostedAndroid: readHostedAndroidStatus,
|
|
827
|
+
hostedMacos: readHostedMacosStatus,
|
|
828
|
+
git: (worktrees, skip) => readWorktreeGit(worktrees, {
|
|
829
|
+
maxAgeMs: gitMaxAgeMs,
|
|
830
|
+
skip
|
|
831
|
+
}),
|
|
832
|
+
androidRuntime: androidRuntimeReader(),
|
|
833
|
+
physicalDevice: physicalDeviceReader(),
|
|
834
|
+
deviceTables: createDeviceProcessTables,
|
|
835
|
+
metroReverses: (serial) => getExecutor().runFileQuiet("adb", [
|
|
836
|
+
"-s",
|
|
837
|
+
serial,
|
|
838
|
+
"reverse",
|
|
839
|
+
"--list"
|
|
840
|
+
], { timeoutMs: 5e3 }),
|
|
841
|
+
footprints: readFootprints,
|
|
842
|
+
archives: () => archives ?? readArchives()
|
|
843
|
+
};
|
|
865
844
|
}
|
|
866
|
-
|
|
867
|
-
|
|
845
|
+
/**
|
|
846
|
+
* Reads the status of every environment. With `git: 'all'` it reads the git summary of every worktree before
|
|
847
|
+
* composing; with `'live'` only those of live environments, after composing; with `'none'` no git summary.
|
|
848
|
+
*/
|
|
849
|
+
function readStatus({ probes = liveProbes(), git = "live", cwd = process.cwd() } = {}) {
|
|
850
|
+
return withStateReadCache(() => readStatusFacts(probes, git, cwd));
|
|
868
851
|
}
|
|
869
|
-
async function readStatusFacts(
|
|
852
|
+
async function readStatusFacts(probes, gitScope, cwd) {
|
|
870
853
|
const cfg = loadConfig$1();
|
|
871
854
|
const projects = Object.entries(cfg?.projects || {});
|
|
872
|
-
const iosReads = projects.map(([path]) =>
|
|
873
|
-
const androidReads = projects.map(([path]) =>
|
|
874
|
-
const macosReads = projects.map(([path]) =>
|
|
875
|
-
const cwdRoot = findServerWorkspace(
|
|
876
|
-
const worktrees = linkedWorktrees([
|
|
855
|
+
const iosReads = projects.map(([path]) => probes.hostedIos(hostedIosPlacements(readWorkspaceState$1(path))));
|
|
856
|
+
const androidReads = projects.map(([path]) => probes.hostedAndroid(hostedAndroidPlacements(readWorkspaceState$1(path))));
|
|
857
|
+
const macosReads = projects.map(([path]) => probes.hostedMacos(readMacosRecord(path)));
|
|
858
|
+
const cwdRoot = findServerWorkspace(cwd)?.root ?? null;
|
|
859
|
+
const { worktrees, commonDirs } = linkedWorktrees([cwd, ...projects.map(([path]) => path)]);
|
|
877
860
|
const orphanWorktrees = unprovisionedWorktrees(worktrees, projects.map(([p]) => p));
|
|
878
|
-
const simsRead =
|
|
861
|
+
const simsRead = probes.simulators();
|
|
879
862
|
simsRead.catch(() => {});
|
|
880
|
-
const
|
|
881
|
-
const processes = Promise.all(projects.map(async ([path, proj]) => {
|
|
882
|
-
const metro = proj.metroPort ? await resolveOnPort(proj.metroPort, path, ports) : null;
|
|
883
|
-
return {
|
|
884
|
-
metro,
|
|
885
|
-
supervisor: await supervisorFacts(path, proj, metro, ports)
|
|
886
|
-
};
|
|
887
|
-
}));
|
|
863
|
+
const processes = probes.metro(projects);
|
|
888
864
|
processes.catch(() => {});
|
|
889
|
-
const
|
|
890
|
-
const gitRead = watching ? readGitInto(worktrees, orphanWorktrees, gitMaxAgeMs) : null;
|
|
891
|
-
const androidRuntimeOf = androidRuntimeReader();
|
|
892
|
-
const devices = projects.map(([, proj]) => ({
|
|
893
|
-
androidRuntimes: Object.fromEntries(projectDeviceSlots(proj).slice(1).map(({ slot, platforms }) => [slot, platforms.android?.owned && platforms.android.avdName ? androidRuntimeOf(platforms.android.avdName) : null])),
|
|
894
|
-
androidRuntime: proj.platforms?.android?.owned && proj.platforms.android.avdName ? androidRuntimeOf(proj.platforms.android.avdName) : null,
|
|
895
|
-
androidDeviceProfiles: Object.fromEntries(projectDeviceSlots(proj).slice(1).map(({ slot, platforms }) => [slot, platforms.android?.owned && platforms.android.avdName ? ownedAvdDeviceProfile(platforms.android.avdName) : null])),
|
|
896
|
-
androidDeviceProfile: proj.platforms?.android?.owned && proj.platforms.android.avdName ? ownedAvdDeviceProfile(proj.platforms.android.avdName) : null
|
|
897
|
-
}));
|
|
865
|
+
const gitRead = gitScope === "all" ? readGitInto(probes, worktrees, orphanWorktrees) : null;
|
|
898
866
|
const logs = projects.map(([path]) => logFacts(path));
|
|
899
867
|
const simsByUdid = {};
|
|
900
868
|
let simsAvailable = true;
|
|
@@ -906,6 +874,12 @@ async function readStatusFacts(gitMaxAgeMs, simctlListing, cachedArchives) {
|
|
|
906
874
|
simctlError = String(e?.message || e).split("\n")[0] ?? "";
|
|
907
875
|
}
|
|
908
876
|
const running = await processes;
|
|
877
|
+
const devices = projects.map(([, proj]) => ({
|
|
878
|
+
androidRuntimes: Object.fromEntries(projectDeviceSlots(proj).slice(1).map(({ slot, platforms }) => [slot, platforms.android?.owned && platforms.android.avdName ? probes.androidRuntime(platforms.android.avdName) : null])),
|
|
879
|
+
androidRuntime: proj.platforms?.android?.owned && proj.platforms.android.avdName ? probes.androidRuntime(proj.platforms.android.avdName) : null,
|
|
880
|
+
androidDeviceProfiles: Object.fromEntries(projectDeviceSlots(proj).slice(1).map(({ slot, platforms }) => [slot, platforms.android?.owned && platforms.android.avdName ? ownedAvdDeviceProfile(platforms.android.avdName) : null])),
|
|
881
|
+
androidDeviceProfile: proj.platforms?.android?.owned && proj.platforms.android.avdName ? ownedAvdDeviceProfile(proj.platforms.android.avdName) : null
|
|
882
|
+
}));
|
|
909
883
|
await gitRead;
|
|
910
884
|
const history = readStats$1().record?.history;
|
|
911
885
|
const states = [];
|
|
@@ -919,7 +893,6 @@ async function readStatusFacts(gitMaxAgeMs, simctlListing, cachedArchives) {
|
|
|
919
893
|
now: leaseNow
|
|
920
894
|
});
|
|
921
895
|
const roots = [];
|
|
922
|
-
const readPhysicalDevice = physicalDeviceReader();
|
|
923
896
|
const simulatorUdids = new Set([...Object.keys(simsByUdid), ...projects.flatMap(([, proj]) => projectDeviceSlots(proj).flatMap(({ platforms }) => platforms.ios?.deviceUdid ?? []))].map((udid) => udid.toUpperCase()));
|
|
924
897
|
for (const [i, [path, proj]] of projects.entries()) {
|
|
925
898
|
const { metro, supervisor } = running[i];
|
|
@@ -1024,20 +997,20 @@ async function readStatusFacts(gitMaxAgeMs, simctlListing, cachedArchives) {
|
|
|
1024
997
|
root: path,
|
|
1025
998
|
now: leaseNow,
|
|
1026
999
|
simulatorUdids,
|
|
1027
|
-
read:
|
|
1000
|
+
read: (platform, id) => probes.physicalDevice(platform, id)
|
|
1028
1001
|
});
|
|
1029
1002
|
if (state && physicalDevices.length) state.physicalDevices = physicalDevices;
|
|
1030
1003
|
labelOnlyRoots.push(Boolean(proj.worktreeRoot && !proj.bundleId && !state?.metro && !state?.ios && !state?.android && !state?.web && !state?.macos));
|
|
1031
1004
|
}
|
|
1032
|
-
if (
|
|
1005
|
+
if (gitScope === "live") await readGitInto(probes, worktrees, orphanWorktrees, new Set(states.flatMap((state) => state.live && state.worktree ? [state.worktree.path] : [])));
|
|
1033
1006
|
applyStatusMeasures(states, worktrees);
|
|
1034
1007
|
readLogDerivedFacts(states);
|
|
1035
|
-
const tables =
|
|
1008
|
+
const tables = probes.deviceTables();
|
|
1036
1009
|
readDeviceProcesses(states, tables, {
|
|
1037
1010
|
projects,
|
|
1038
1011
|
launchesByState
|
|
1039
1012
|
});
|
|
1040
|
-
readMetroReverses(states, launchesByState);
|
|
1013
|
+
readMetroReverses(states, launchesByState, probes);
|
|
1041
1014
|
const sims = Object.values(simsByUdid);
|
|
1042
1015
|
const simNames = Object.fromEntries(sims.map((sim) => [sim.udid.toUpperCase(), sim.name]));
|
|
1043
1016
|
const machine = await readMachineUsage({
|
|
@@ -1045,9 +1018,10 @@ async function readStatusFacts(gitMaxAgeMs, simctlListing, cachedArchives) {
|
|
|
1045
1018
|
roots,
|
|
1046
1019
|
simNames,
|
|
1047
1020
|
tables,
|
|
1048
|
-
busy: sims.some((sim) => sim.state === "Booted")
|
|
1021
|
+
busy: sims.some((sim) => sim.state === "Booted"),
|
|
1022
|
+
probes
|
|
1049
1023
|
});
|
|
1050
|
-
const archives =
|
|
1024
|
+
const archives = probes.archives();
|
|
1051
1025
|
const maxCount = machineNumber("archive.maxCount", cfg, process.env);
|
|
1052
1026
|
return {
|
|
1053
1027
|
archived: linkReplacedArchives(archives.slice(0, maxCount.value ?? 200), states.map((state) => state.path)),
|
|
@@ -1065,7 +1039,9 @@ async function readStatusFacts(gitMaxAgeMs, simctlListing, cachedArchives) {
|
|
|
1065
1039
|
tables,
|
|
1066
1040
|
machine,
|
|
1067
1041
|
roots,
|
|
1068
|
-
simNames
|
|
1042
|
+
simNames,
|
|
1043
|
+
probes,
|
|
1044
|
+
gitCommonDirs: commonDirs
|
|
1069
1045
|
};
|
|
1070
1046
|
}
|
|
1071
1047
|
/** Sets the facts status derives from workspace logs, the running build's record and its detail file. */
|
|
@@ -1120,11 +1096,6 @@ function readLogDerivedFacts(states) {
|
|
|
1120
1096
|
}
|
|
1121
1097
|
}
|
|
1122
1098
|
}
|
|
1123
|
-
function phaseMarker({ phase, live, warmStep }) {
|
|
1124
|
-
if (phase === "warming") return chalk.cyan(` [warming: ${warmStep}]`);
|
|
1125
|
-
if (phase === "ready") return chalk.green(" [ready]");
|
|
1126
|
-
return live ? "" : chalk.dim(" [idle]");
|
|
1127
|
-
}
|
|
1128
1099
|
function browserPids(web) {
|
|
1129
1100
|
if (!web) return [];
|
|
1130
1101
|
const chrome = web.record.chromeProcess?.pid;
|
|
@@ -1136,10 +1107,10 @@ function browserPids(web) {
|
|
|
1136
1107
|
* `memoryMb` from them. Reads both only when a simulator is booted, a workspace is live or a build runs, so an idle
|
|
1137
1108
|
* machine runs no `ps` and keeps the estimate.
|
|
1138
1109
|
*/
|
|
1139
|
-
async function readMachineUsage({ states, roots, simNames, tables, busy }) {
|
|
1110
|
+
async function readMachineUsage({ states, roots, simNames, tables, busy, probes }) {
|
|
1140
1111
|
const processes = busy || states.some((state) => state.live || state.build?.state === "running") ? tables.host() : null;
|
|
1141
1112
|
if (!processes) return null;
|
|
1142
|
-
const footprints = await
|
|
1113
|
+
const footprints = await probes.footprints();
|
|
1143
1114
|
const machine = attributeMachineUsage({
|
|
1144
1115
|
processes,
|
|
1145
1116
|
footprints,
|
|
@@ -1151,338 +1122,112 @@ async function readMachineUsage({ states, roots, simNames, tables, busy }) {
|
|
|
1151
1122
|
return machine;
|
|
1152
1123
|
}
|
|
1153
1124
|
/**
|
|
1154
|
-
* Rereads
|
|
1155
|
-
*
|
|
1125
|
+
* Rereads the log-derived facts and the cached measures. With `tables` it also rereads the process tables and the
|
|
1126
|
+
* device activity they show; with `machine` as well, and when the snapshot measured machine usage, the host process
|
|
1127
|
+
* table and machine usage. It reuses every other subprocess fact of the full read.
|
|
1156
1128
|
*/
|
|
1157
|
-
async function refreshLightFacts(snapshot, machine) {
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1129
|
+
async function refreshLightFacts(snapshot, { tables, machine }) {
|
|
1130
|
+
if (tables) {
|
|
1131
|
+
const fresh = snapshot.probes.deviceTables();
|
|
1132
|
+
snapshot.tables = {
|
|
1133
|
+
host: machine && snapshot.machine ? fresh.host : snapshot.tables.host,
|
|
1134
|
+
android: snapshot.tables.android,
|
|
1135
|
+
tcpConnections: fresh.tcpConnections,
|
|
1136
|
+
clients: fresh.host
|
|
1137
|
+
};
|
|
1138
|
+
}
|
|
1165
1139
|
withStateReadCache(() => {
|
|
1166
1140
|
for (const state of snapshot.states) state.logs = logFacts(state.path);
|
|
1167
1141
|
applyStatusMeasures(snapshot.states, snapshot.worktrees);
|
|
1168
1142
|
readLogDerivedFacts(snapshot.states);
|
|
1169
|
-
readDeviceProcesses(snapshot.states, snapshot.tables, null);
|
|
1143
|
+
if (tables) readDeviceProcesses(snapshot.states, snapshot.tables, null);
|
|
1170
1144
|
});
|
|
1171
1145
|
if (machine && snapshot.machine) snapshot.machine = await readMachineUsage({
|
|
1172
1146
|
...snapshot,
|
|
1173
1147
|
busy: true
|
|
1174
1148
|
});
|
|
1175
1149
|
}
|
|
1176
|
-
function
|
|
1177
|
-
const
|
|
1178
|
-
const
|
|
1179
|
-
const
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
});
|
|
1191
|
-
const maintenance = maintenanceStatus();
|
|
1192
|
-
if (json) {
|
|
1193
|
-
const payload = {
|
|
1194
|
-
environments: states.map((state, i) => withDerivedFacts(labelOnlyRoots[i] ? {
|
|
1195
|
-
...state,
|
|
1196
|
-
labelOnly: true
|
|
1197
|
-
} : state)),
|
|
1198
|
-
archived,
|
|
1199
|
-
archivedUsage: usage,
|
|
1200
|
-
capacity: cap,
|
|
1201
|
-
deviceLeases: leases,
|
|
1202
|
-
unprovisionedWorktrees: orphanWorktrees.map(withGitChip),
|
|
1203
|
-
simctlAvailable: simsAvailable,
|
|
1204
|
-
machine,
|
|
1205
|
-
maintenance
|
|
1150
|
+
async function readGitInto(probes, worktrees, orphans, only) {
|
|
1151
|
+
const home = homedir();
|
|
1152
|
+
const byPath = await probes.git(worktrees, (w) => only !== void 0 && !only.has(w.path) || process.platform === "darwin" && orphans.includes(w) && inPrivacyProtectedFolder(w.path, home));
|
|
1153
|
+
for (const worktree of worktrees) worktree.git = byPath.get(worktree.path) ?? null;
|
|
1154
|
+
}
|
|
1155
|
+
function readDeviceProcesses(states, tables, apps) {
|
|
1156
|
+
const readActivity = createActivityReader({ tables });
|
|
1157
|
+
const readAppProcess = createAppProcessReader(tables);
|
|
1158
|
+
for (const [i, state] of states.entries()) {
|
|
1159
|
+
const appIdOn = (platform, slot, deviceId) => {
|
|
1160
|
+
if (!apps) return void 0;
|
|
1161
|
+
const project = apps.projects[i][1];
|
|
1162
|
+
const launch = apps.launchesByState[i][deviceSlotKey(platform, slot)];
|
|
1163
|
+
return launch?.deviceId === deviceId ? launch.appId : platform === "ios" ? project.bundleId : project.androidPackage;
|
|
1206
1164
|
};
|
|
1207
|
-
|
|
1208
|
-
return out;
|
|
1209
|
-
}
|
|
1210
|
-
out.push(...maintenanceLines(maintenance).map((line) => chalk.dim(line)));
|
|
1211
|
-
if (usage.count) out.push(`Archived: ${plural(usage.count, "workspace")}, ${formatBytes(usage.bytes)}`);
|
|
1212
|
-
if (projects.length === 0 && orphanWorktrees.length === 0) {
|
|
1213
|
-
out.push(chalk.dim("No projects registered."));
|
|
1214
|
-
for (const pool of pools) {
|
|
1215
|
-
if (pool.error) out.push(chalk.yellow(`${pool.error} ${POOL_SETTING_REMEDY}`));
|
|
1216
|
-
if (pool.line) out.push(chalk.dim(pool.line));
|
|
1217
|
-
}
|
|
1218
|
-
for (const line of deviceLeaseLines(leases, leaseNow)) out.push(line);
|
|
1219
|
-
return out;
|
|
1220
|
-
}
|
|
1221
|
-
if (!simsAvailable) out.push(chalk.yellow(`simctl could not be read (${simctlError}), so no iOS sim below could be checked.`));
|
|
1222
|
-
for (const [i, [path, proj]] of projects.entries()) {
|
|
1223
|
-
const state = states[i];
|
|
1224
|
-
if (!state) continue;
|
|
1225
|
-
const shortcut = projectShortcut(path, proj);
|
|
1226
|
-
const marker = path === cwdRoot ? chalk.bold.cyan(`* ${shortcut}`) : shortcut;
|
|
1227
|
-
const idle = phaseMarker(state);
|
|
1228
|
-
out.push(`\n${marker}${idle} ${chalk.dim(`(${path})`)}`);
|
|
1229
|
-
out.push(labelOnlyRoots[i] ? chalk.dim(" worktree root (holds the label; the app registers its own entry)") : chalk.dim(` app: ${proj.bundleId ?? "?"} (${proj.isExpo ?? detectIsExpo(path) ? "expo" : "bare"})`));
|
|
1230
|
-
if (state.metro) {
|
|
1231
|
-
const label = state.metro.running ? chalk.green(`running (pid ${state.metro.pid})`) : state.metro.idleStop ? chalk.dim(`stopped (idle) after ${state.metro.idleStop.idleMinutes}m; \`stim start\`, \`ios\` or \`android\` restarts it`) : state.metro.lastStop ? chalk.dim(`not running${state.metro.lastStop.reason === "vanished" ? "" : ` since ${state.metro.lastStop.at}`}; ${describeMetroLastStop(state.metro.lastStop)}`) : chalk.dim("not running");
|
|
1232
|
-
out.push(` metro: port ${state.metro.port} ${label}`);
|
|
1233
|
-
if (state.metro.tunnel) {
|
|
1234
|
-
const { provider, url } = state.metro.tunnel;
|
|
1235
|
-
out.push(` tunnel: ${provider}${provider === "tailscale" ? " (tailnet-only)" : ""} ${url}`);
|
|
1236
|
-
}
|
|
1237
|
-
}
|
|
1238
|
-
if (state.supervisor) {
|
|
1239
|
-
const health = state.supervisor.healthy ? chalk.green("healthy") : chalk.yellow("not answering");
|
|
1240
|
-
const mode = state.supervisor.mode ? chalk.dim(` (${state.supervisor.mode})`) : "";
|
|
1241
|
-
out.push(` supervisor: pid ${state.supervisor.pid}${mode} ${health}`);
|
|
1242
|
-
}
|
|
1243
|
-
if (state.build) {
|
|
1244
|
-
const line = ` ${buildStatusLine(state.build, Date.now())}`;
|
|
1245
|
-
out.push(state.build.state === "running" ? line : chalk.yellow(line));
|
|
1246
|
-
}
|
|
1247
|
-
out.push(...lastBuildsLines(state.lastBuilds));
|
|
1248
|
-
if (state.worktree?.git) out.push(chalk.dim(` git: ${gitSummaryText(state.worktree.git)}`));
|
|
1249
|
-
for (const agent of state.agents ?? []) out.push(chalk.dim(` agent: ${agentLine(agent)}`));
|
|
1250
|
-
if (state.logs) {
|
|
1251
|
-
const n = state.logs.errorsSinceMarker;
|
|
1252
|
-
const errs = n > 0 ? chalk.yellow(` (${n} error${n === 1 ? "" : "s"} since the last marker)`) : "";
|
|
1253
|
-
out.push(chalk.dim(` logs: ${state.logs.dir}`) + errs);
|
|
1254
|
-
}
|
|
1255
|
-
for (const deviceState of [{
|
|
1165
|
+
for (const device of [{
|
|
1256
1166
|
slot: "default",
|
|
1257
1167
|
ios: state.ios,
|
|
1258
1168
|
android: state.android
|
|
1259
1169
|
}, ...state.slots ?? []]) {
|
|
1260
|
-
const
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1170
|
+
const base = {
|
|
1171
|
+
slot: device.slot,
|
|
1172
|
+
workspace: state.path
|
|
1173
|
+
};
|
|
1174
|
+
if (device.ios?.state === "Booted") {
|
|
1175
|
+
const id = device.ios.udid;
|
|
1176
|
+
device.ios.activity = statusActivity(readActivity({
|
|
1177
|
+
...base,
|
|
1178
|
+
platform: "ios",
|
|
1179
|
+
id
|
|
1180
|
+
}));
|
|
1181
|
+
const appId = device.ios.owned ? appIdOn("ios", device.slot, id) : void 0;
|
|
1182
|
+
if (appId) device.ios.app = readAppProcess({
|
|
1183
|
+
platform: "ios",
|
|
1184
|
+
id,
|
|
1185
|
+
appId
|
|
1186
|
+
});
|
|
1187
|
+
}
|
|
1188
|
+
if (device.android && !device.android.physical && device.android.serial) {
|
|
1189
|
+
const id = device.android.serial;
|
|
1190
|
+
device.android.activity = statusActivity(readActivity({
|
|
1191
|
+
...base,
|
|
1192
|
+
platform: "android",
|
|
1193
|
+
id
|
|
1194
|
+
}));
|
|
1195
|
+
const appId = device.android.owned ? appIdOn("android", device.slot, id) : void 0;
|
|
1196
|
+
if (appId) device.android.app = readAppProcess({
|
|
1197
|
+
platform: "android",
|
|
1198
|
+
id,
|
|
1199
|
+
appId
|
|
1200
|
+
});
|
|
1201
|
+
}
|
|
1271
1202
|
}
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1203
|
+
const web = state.web;
|
|
1204
|
+
const port = web?.cdpEndpoint ? Number(new URL(web.cdpEndpoint).port) : null;
|
|
1205
|
+
if (web?.running && port) {
|
|
1206
|
+
web.page = readWebPage(state.path);
|
|
1207
|
+
const ownPids = [web.pid, web.supervisorPid].filter((pid) => pid !== null);
|
|
1208
|
+
web.activity = statusActivity(readWebActivity({
|
|
1209
|
+
port,
|
|
1210
|
+
ownPids,
|
|
1211
|
+
workspace: state.path
|
|
1212
|
+
}, tables));
|
|
1277
1213
|
}
|
|
1278
|
-
for (const device of state.physicalDevices ?? []) out.push(` ${physicalDeviceLine(device, leaseNow)}`);
|
|
1279
|
-
for (const remote of state.remoteDevices ?? []) out.push(` ${remoteDeviceLine(remote)}`);
|
|
1280
|
-
for (const w of state.warnings) out.push(chalk.yellow(` ! ${w}`));
|
|
1281
|
-
for (const note of state.issues.filter((issue) => issue.severity === "info")) out.push(chalk.dim(` - ${note.message}`));
|
|
1282
|
-
}
|
|
1283
|
-
for (const pool of pools) {
|
|
1284
|
-
if (pool.error) out.push(chalk.yellow(`\n${pool.error} ${POOL_SETTING_REMEDY}`));
|
|
1285
|
-
if (pool.line) out.push(chalk.dim(`\n${pool.line}`));
|
|
1286
|
-
}
|
|
1287
|
-
const leaseLines = deviceLeaseLines(leases, leaseNow);
|
|
1288
|
-
if (leaseLines.length) {
|
|
1289
|
-
out.push("");
|
|
1290
|
-
for (const line of leaseLines) out.push(line);
|
|
1291
1214
|
}
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1215
|
+
}
|
|
1216
|
+
function readMetroReverses(states, launchesByState, probes) {
|
|
1217
|
+
for (const [i, state] of states.entries()) for (const target of metroReverseTargets(state, launchesByState[i])) {
|
|
1218
|
+
const listing = probes.metroReverses(target.serial);
|
|
1219
|
+
if (listing !== null && !hasMetroReverse(listing, target.metroPort)) addReverseMissingIssue(state, target);
|
|
1295
1220
|
}
|
|
1296
|
-
out.push(chalk.dim(machine?.memorySource === "footprint" ? `\n${cap.liveCount} active environment(s) use ${formatGb(cap.committedMb)} of ${formatGb(cap.totalMemoryMb)}.` : `\n${cap.liveCount} active environment(s), roughly ${formatGb(cap.committedMb)} of ${formatGb(cap.totalMemoryMb)} committed.`));
|
|
1297
|
-
const volumes = readVolumes(cwdRoot || process.cwd());
|
|
1298
|
-
const line = diskLine(volumes);
|
|
1299
|
-
if (line) {
|
|
1300
|
-
const tight = tightVolumes(volumes);
|
|
1301
|
-
if (tight.length) {
|
|
1302
|
-
const which = tight.map((v) => v.volume).join(" and ");
|
|
1303
|
-
out.push(chalk.yellow(`${line} A single iOS build can exhaust ${which} -- run \`stim gc\` before starting another environment.`));
|
|
1304
|
-
} else out.push(chalk.dim(line));
|
|
1305
|
-
}
|
|
1306
|
-
if (cap.overCapacity) out.push(chalk.yellow("Over comfortable capacity. A machine that swaps is slower than one working in sequence -- release one before starting another."));
|
|
1307
|
-
return out;
|
|
1308
|
-
}
|
|
1309
|
-
async function watchStatus(json) {
|
|
1310
|
-
let last = null;
|
|
1311
|
-
let lastPayload = null;
|
|
1312
|
-
let archiveStamp = null;
|
|
1313
|
-
let archives;
|
|
1314
|
-
let snapshot = null;
|
|
1315
|
-
let sources = null;
|
|
1316
|
-
const measurer = createStatusMeasurer({ updated: () => scheduler.trigger("light") });
|
|
1317
|
-
const scheduler = createRefreshScheduler({
|
|
1318
|
-
debounceMs: 250,
|
|
1319
|
-
lightIntervalMs: WATCH_LIGHT_INTERVAL_MS,
|
|
1320
|
-
run: async (kind) => {
|
|
1321
|
-
triggerMaintenance("status-watch");
|
|
1322
|
-
let text;
|
|
1323
|
-
let payload = null;
|
|
1324
|
-
try {
|
|
1325
|
-
if (kind === "light" && snapshot) await refreshLightFacts(snapshot, json);
|
|
1326
|
-
else {
|
|
1327
|
-
let stamp = null;
|
|
1328
|
-
try {
|
|
1329
|
-
stamp = statSync$1(archiveRoot()).mtimeMs;
|
|
1330
|
-
} catch {}
|
|
1331
|
-
if (archives === void 0 || stamp !== archiveStamp) {
|
|
1332
|
-
archives = readArchives();
|
|
1333
|
-
archiveStamp = stamp;
|
|
1334
|
-
}
|
|
1335
|
-
snapshot = await readStatus(WATCH_GIT_MAX_AGE_MS, sources?.simulatorListing(), archives);
|
|
1336
|
-
}
|
|
1337
|
-
measurer.schedule(snapshot.states, snapshot.worktrees);
|
|
1338
|
-
text = renderStatus(snapshot, json, (full) => payload = watchPayload(lastPayload, full)).join("\n");
|
|
1339
|
-
} catch (error) {
|
|
1340
|
-
console.error(chalk.red(String(error?.message || error)));
|
|
1341
|
-
return;
|
|
1342
|
-
} finally {
|
|
1343
|
-
sources?.reconcile();
|
|
1344
|
-
}
|
|
1345
|
-
if (text === last) return;
|
|
1346
|
-
last = text;
|
|
1347
|
-
lastPayload = payload;
|
|
1348
|
-
process.stdout.write(`${!json && process.stdout.isTTY ? "\x1B[2J\x1B[H" : ""}${text}\n`);
|
|
1349
|
-
}
|
|
1350
|
-
});
|
|
1351
|
-
const fallback = setInterval(() => scheduler.trigger("full"), WATCH_FALLBACK_MS);
|
|
1352
|
-
const machine = setInterval(() => json && snapshot?.machine && scheduler.trigger("light"), WATCH_LIGHT_INTERVAL_MS);
|
|
1353
|
-
const finish = () => {
|
|
1354
|
-
clearInterval(fallback);
|
|
1355
|
-
clearInterval(machine);
|
|
1356
|
-
stopReader();
|
|
1357
|
-
scheduler.stop();
|
|
1358
|
-
sources?.stop();
|
|
1359
|
-
process.exit(0);
|
|
1360
|
-
};
|
|
1361
|
-
const stopReader = watchStdoutReader(finish);
|
|
1362
|
-
process.on("SIGINT", finish);
|
|
1363
|
-
process.on("SIGTERM", finish);
|
|
1364
|
-
sources = watchStatusSources({
|
|
1365
|
-
home: getConfigDir(),
|
|
1366
|
-
onChange: (kind) => scheduler.trigger(kind)
|
|
1367
|
-
});
|
|
1368
|
-
scheduler.trigger("full", 0);
|
|
1369
|
-
await new Promise(() => {});
|
|
1370
|
-
}
|
|
1371
|
-
async function readGitInto(worktrees, orphans, maxAgeMs, only) {
|
|
1372
|
-
const home = homedir();
|
|
1373
|
-
const byPath = await readWorktreeGit(worktrees, {
|
|
1374
|
-
maxAgeMs,
|
|
1375
|
-
skip: (w) => only !== void 0 && !only.has(w.path) || process.platform === "darwin" && orphans.includes(w) && inPrivacyProtectedFolder(w.path, home)
|
|
1376
|
-
});
|
|
1377
|
-
for (const worktree of worktrees) worktree.git = byPath.get(worktree.path) ?? null;
|
|
1378
|
-
}
|
|
1379
|
-
function agentLine({ tool, title, sessionId, lastActiveAt }) {
|
|
1380
|
-
const at = lastActiveAt ? `, active ${lastActiveAt}` : "";
|
|
1381
|
-
return `${tool === "codex" ? "Codex" : "Claude Code"} ${title ? `"${title}"` : sessionId}${at}`;
|
|
1382
|
-
}
|
|
1383
|
-
function orphanWorktreeLine(w) {
|
|
1384
|
-
return `${w.path}${w.branch ? ` [${w.branch}]` : ""}${w.git ? ` -- ${gitSummaryText(w.git)}` : ""}`;
|
|
1385
|
-
}
|
|
1386
|
-
function lastBuildsLines(reports) {
|
|
1387
|
-
const texts = Object.values(reports ?? {}).map(lastBuildText);
|
|
1388
|
-
return texts.length ? [chalk.dim(` last build: ${texts.join(", ")}`)] : [];
|
|
1389
|
-
}
|
|
1390
|
-
function lastBuildText(report) {
|
|
1391
|
-
const source = report.cacheHit ? `${report.cacheHit} cache` : report.status === "ok" ? "compiled" : "no cache hit";
|
|
1392
|
-
const took = report.durationMs === null ? "" : ` in ${formatDuration(report.durationMs)}`;
|
|
1393
|
-
const placement = report.buildMachine === void 0 ? "" : `; build placement ${report.buildMachine}, built on ${report.builtOn ?? (report.cacheHit ? "none (cache)" : "none")}`;
|
|
1394
|
-
return `${report.platform} ${report.status === "ok" ? source : `failed (${report.errorCode ?? "error"}), ${source}`}${took}${placement}`;
|
|
1395
|
-
}
|
|
1396
|
-
function idleShutdownSuffix(record) {
|
|
1397
|
-
return record ? chalk.dim(` -- shut down after ${record.idleMinutes}m idle at ${record.at} (${record.reason === DEVICE_RECLAIM_REASON ? "reclaimed for a waiting run; devices.reclaimIdleMinutes" : "devices.idleShutdownMinutes"})`) : "";
|
|
1398
|
-
}
|
|
1399
|
-
function activitySuffix(activity) {
|
|
1400
|
-
const label = activityLabel(activity, Date.now());
|
|
1401
|
-
return label ? ` -- ${activity?.state === "driven" ? chalk.magenta(label) : chalk.dim(label)}` : "";
|
|
1402
|
-
}
|
|
1403
|
-
function readDeviceProcesses(states, tables, apps) {
|
|
1404
|
-
const readActivity = createActivityReader({ tables });
|
|
1405
|
-
const readAppProcess = createAppProcessReader(tables);
|
|
1406
|
-
for (const [i, state] of states.entries()) {
|
|
1407
|
-
const appIdOn = (platform, slot, deviceId) => {
|
|
1408
|
-
if (!apps) return void 0;
|
|
1409
|
-
const project = apps.projects[i][1];
|
|
1410
|
-
const launch = apps.launchesByState[i][deviceSlotKey(platform, slot)];
|
|
1411
|
-
return launch?.deviceId === deviceId ? launch.appId : platform === "ios" ? project.bundleId : project.androidPackage;
|
|
1412
|
-
};
|
|
1413
|
-
for (const device of [{
|
|
1414
|
-
slot: "default",
|
|
1415
|
-
ios: state.ios,
|
|
1416
|
-
android: state.android
|
|
1417
|
-
}, ...state.slots ?? []]) {
|
|
1418
|
-
const base = {
|
|
1419
|
-
slot: device.slot,
|
|
1420
|
-
workspace: state.path
|
|
1421
|
-
};
|
|
1422
|
-
if (device.ios?.state === "Booted") {
|
|
1423
|
-
const id = device.ios.udid;
|
|
1424
|
-
device.ios.activity = statusActivity(readActivity({
|
|
1425
|
-
...base,
|
|
1426
|
-
platform: "ios",
|
|
1427
|
-
id
|
|
1428
|
-
}));
|
|
1429
|
-
const appId = device.ios.owned ? appIdOn("ios", device.slot, id) : void 0;
|
|
1430
|
-
if (appId) device.ios.app = readAppProcess({
|
|
1431
|
-
platform: "ios",
|
|
1432
|
-
id,
|
|
1433
|
-
appId
|
|
1434
|
-
});
|
|
1435
|
-
}
|
|
1436
|
-
if (device.android && !device.android.physical && device.android.serial) {
|
|
1437
|
-
const id = device.android.serial;
|
|
1438
|
-
device.android.activity = statusActivity(readActivity({
|
|
1439
|
-
...base,
|
|
1440
|
-
platform: "android",
|
|
1441
|
-
id
|
|
1442
|
-
}));
|
|
1443
|
-
const appId = device.android.owned ? appIdOn("android", device.slot, id) : void 0;
|
|
1444
|
-
if (appId) device.android.app = readAppProcess({
|
|
1445
|
-
platform: "android",
|
|
1446
|
-
id,
|
|
1447
|
-
appId
|
|
1448
|
-
});
|
|
1449
|
-
}
|
|
1450
|
-
}
|
|
1451
|
-
const web = state.web;
|
|
1452
|
-
const port = web?.cdpEndpoint ? Number(new URL(web.cdpEndpoint).port) : null;
|
|
1453
|
-
if (web?.running && port) {
|
|
1454
|
-
web.page = readWebPage(state.path);
|
|
1455
|
-
const ownPids = [web.pid, web.supervisorPid].filter((pid) => pid !== null);
|
|
1456
|
-
web.activity = statusActivity(readWebActivity({
|
|
1457
|
-
port,
|
|
1458
|
-
ownPids,
|
|
1459
|
-
workspace: state.path
|
|
1460
|
-
}, tables));
|
|
1461
|
-
}
|
|
1462
|
-
}
|
|
1463
|
-
}
|
|
1464
|
-
function readMetroReverses(states, launchesByState) {
|
|
1465
|
-
for (const [i, state] of states.entries()) for (const target of metroReverseTargets(state, launchesByState[i])) {
|
|
1466
|
-
const listing = getExecutor().runFileQuiet("adb", [
|
|
1467
|
-
"-s",
|
|
1468
|
-
target.serial,
|
|
1469
|
-
"reverse",
|
|
1470
|
-
"--list"
|
|
1471
|
-
], { timeoutMs: 5e3 });
|
|
1472
|
-
if (listing !== null && !hasMetroReverse(listing, target.metroPort)) addReverseMissingIssue(state, target);
|
|
1473
|
-
}
|
|
1474
|
-
}
|
|
1475
|
-
function appSuffix(app) {
|
|
1476
|
-
if (!app) return "";
|
|
1477
|
-
if (app.state === "running") return chalk.dim(` -- ${app.id} running`);
|
|
1478
|
-
if (app.state === "stopped") return ` -- ${chalk.yellow(`${app.id} not running`)}`;
|
|
1479
|
-
return chalk.dim(` -- ${app.id} process unknown`);
|
|
1480
1221
|
}
|
|
1481
1222
|
function linkedWorktrees(paths) {
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1223
|
+
const commonDirs = [...new Set(paths.flatMap((path) => gitCommonDirOnDisk(path) ?? []))];
|
|
1224
|
+
return {
|
|
1225
|
+
worktrees: commonDirs.flatMap((common) => {
|
|
1226
|
+
const repository = basename$1(common) === ".git" ? dirname$1(common) : common;
|
|
1227
|
+
return linkedWorktreesOnDisk(common).map((entry) => Object.assign(entry, { repository }));
|
|
1228
|
+
}),
|
|
1229
|
+
commonDirs
|
|
1230
|
+
};
|
|
1486
1231
|
}
|
|
1487
1232
|
function workspaceBuilds(path, saved, history) {
|
|
1488
1233
|
const lastBuilds = readLastBuilds(saved);
|
|
@@ -1551,21 +1296,15 @@ function readAndroidRuntime(resolveSerial) {
|
|
|
1551
1296
|
};
|
|
1552
1297
|
}
|
|
1553
1298
|
}
|
|
1554
|
-
function
|
|
1555
|
-
const
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
if (disk) volumes.push({
|
|
1564
|
-
volume,
|
|
1565
|
-
disk
|
|
1566
|
-
});
|
|
1567
|
-
}
|
|
1568
|
-
return volumes;
|
|
1299
|
+
async function readMetroFacts(projects) {
|
|
1300
|
+
const ports = await portLookup(projects.flatMap(([, proj]) => proj.metroPort ? [proj.metroPort] : []));
|
|
1301
|
+
return Promise.all(projects.map(async ([path, proj]) => {
|
|
1302
|
+
const metro = proj.metroPort ? await resolveOnPort(proj.metroPort, path, ports) : null;
|
|
1303
|
+
return {
|
|
1304
|
+
metro,
|
|
1305
|
+
supervisor: await supervisorFacts(path, proj, metro, ports)
|
|
1306
|
+
};
|
|
1307
|
+
}));
|
|
1569
1308
|
}
|
|
1570
1309
|
async function portLookup(metroPorts) {
|
|
1571
1310
|
const ports = [...new Set(metroPorts)];
|
|
@@ -1626,4 +1365,353 @@ function logFacts(path) {
|
|
|
1626
1365
|
}
|
|
1627
1366
|
}
|
|
1628
1367
|
//#endregion
|
|
1629
|
-
|
|
1368
|
+
//#region src/commands/status.ts
|
|
1369
|
+
function iosStatusLines(record, slotLabel) {
|
|
1370
|
+
const out = [];
|
|
1371
|
+
const host = record?.udid ? record.host : void 0;
|
|
1372
|
+
const iosDevices = [record, ...host ? [{
|
|
1373
|
+
host,
|
|
1374
|
+
name: host.device?.name ?? null,
|
|
1375
|
+
udid: "",
|
|
1376
|
+
owned: false,
|
|
1377
|
+
state: host.state ?? "unverified"
|
|
1378
|
+
}] : []];
|
|
1379
|
+
for (const ios of iosDevices) {
|
|
1380
|
+
if (!ios) continue;
|
|
1381
|
+
const booted = ios.state === "Booted" ? chalk.green("booted") : chalk.dim(ios.state.toLowerCase());
|
|
1382
|
+
const owned = ios.owned ? chalk.dim(" (owned)") : "";
|
|
1383
|
+
out.push(` ios${slotLabel}: ${chalk.cyan(iosStatusName(ios))} ${booted}${owned}${activitySuffix(ios.activity)}${appSuffix(ios.app)}${idleShutdownSuffix(ios.idleShutdown)}`);
|
|
1384
|
+
if (!ios.udid && ios.host && "command" in ios.host.agent) out.push(chalk.dim(` agent: ${ios.host.agent.command}`));
|
|
1385
|
+
}
|
|
1386
|
+
return out;
|
|
1387
|
+
}
|
|
1388
|
+
function androidStatusLines(record, slotLabel) {
|
|
1389
|
+
const out = [];
|
|
1390
|
+
if (record?.host && !record.serial) {
|
|
1391
|
+
const host = record.host;
|
|
1392
|
+
out.push(` android${slotLabel}: ${chalk.cyan(`${host.device?.name ?? "Android emulator"} on ${host.machine}${host.selected === "auto" && host.reason ? ` (auto: ${host.reason})` : ""}`)} ${host.state ?? "unverified"}`);
|
|
1393
|
+
} else if (record) {
|
|
1394
|
+
const kind = record.physical ? chalk.dim("(physical)") : chalk.dim("(emulator)");
|
|
1395
|
+
const observed = record.state ? ` ${record.state}${record.serial ? ` (${record.serial})` : ""}` : "";
|
|
1396
|
+
out.push(` android${slotLabel}: ${chalk.cyan(record.name)} ${kind}${observed}${record.owned ? chalk.dim(" (owned)") : ""}${activitySuffix(record.activity)}${appSuffix(record.app)}${idleShutdownSuffix(record.idleShutdown)}`);
|
|
1397
|
+
if (record.host) {
|
|
1398
|
+
const host = record.host;
|
|
1399
|
+
out.push(` android${slotLabel}: ${chalk.cyan(`${host.device?.name ?? "Android emulator"} on ${host.machine}${host.selected === "auto" && host.reason ? ` (auto: ${host.reason})` : ""}`)} ${host.state ?? "unverified"}`);
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
if (record?.host && "command" in record.host.agent) out.push(chalk.dim(` agent: ${record.host.agent.command}`));
|
|
1403
|
+
return out;
|
|
1404
|
+
}
|
|
1405
|
+
function formatGb(mb) {
|
|
1406
|
+
return `${(mb / 1024).toFixed(1)} GB`;
|
|
1407
|
+
}
|
|
1408
|
+
function phaseMarker({ phase, live, warmStep }) {
|
|
1409
|
+
if (phase === "warming") return chalk.cyan(` [warming: ${warmStep}]`);
|
|
1410
|
+
if (phase === "ready") return chalk.green(" [ready]");
|
|
1411
|
+
return live ? "" : chalk.dim(" [idle]");
|
|
1412
|
+
}
|
|
1413
|
+
const WATCH_GIT_MAX_AGE_MS = 6e4;
|
|
1414
|
+
function statusCommand(program) {
|
|
1415
|
+
program.command("status").description("Show every environment on this machine: devices, ports, what is actually running, and anything stuck.").option("--json", "print the state as JSON").option("--watch", "keep running and print the state again each time it changes").action(async (opts) => {
|
|
1416
|
+
if (opts.watch) return watchStatus(Boolean(opts.json));
|
|
1417
|
+
const json = Boolean(opts.json);
|
|
1418
|
+
for (const line of renderStatus(await readStatus(), json)) console.log(line);
|
|
1419
|
+
});
|
|
1420
|
+
}
|
|
1421
|
+
function renderStatus({ archived, archivedUsage: usage, projects, states, labelOnlyRoots, leases, leaseNow, orphanWorktrees, simsAvailable, simctlError, cwdRoot, machine }, json, settle = (payload) => payload, cwd = process.cwd()) {
|
|
1422
|
+
const out = [];
|
|
1423
|
+
const totalMemoryMb = Math.round(totalmem() / 1048576);
|
|
1424
|
+
const cap = capacity(states, totalMemoryMb);
|
|
1425
|
+
const pools = ["ios", "android"].map((platform) => {
|
|
1426
|
+
const { max, error } = parkedMaxSetting(platform);
|
|
1427
|
+
return {
|
|
1428
|
+
error,
|
|
1429
|
+
line: poolLine({
|
|
1430
|
+
platform,
|
|
1431
|
+
parked: readParked(platform).length,
|
|
1432
|
+
max
|
|
1433
|
+
})
|
|
1434
|
+
};
|
|
1435
|
+
});
|
|
1436
|
+
const maintenance = maintenanceStatus();
|
|
1437
|
+
if (json) {
|
|
1438
|
+
const payload = {
|
|
1439
|
+
environments: states.map((state, i) => withDerivedFacts(labelOnlyRoots[i] ? {
|
|
1440
|
+
...state,
|
|
1441
|
+
labelOnly: true
|
|
1442
|
+
} : state)),
|
|
1443
|
+
archived,
|
|
1444
|
+
archivedUsage: usage,
|
|
1445
|
+
capacity: cap,
|
|
1446
|
+
deviceLeases: leases,
|
|
1447
|
+
unprovisionedWorktrees: orphanWorktrees.map(withGitChip),
|
|
1448
|
+
simctlAvailable: simsAvailable,
|
|
1449
|
+
machine,
|
|
1450
|
+
maintenance
|
|
1451
|
+
};
|
|
1452
|
+
out.push(JSON.stringify(settle(payload)));
|
|
1453
|
+
return out;
|
|
1454
|
+
}
|
|
1455
|
+
out.push(...maintenanceLines(maintenance).map((line) => chalk.dim(line)));
|
|
1456
|
+
if (usage.count) out.push(`Archived: ${plural(usage.count, "workspace")}, ${formatBytes(usage.bytes)}`);
|
|
1457
|
+
if (projects.length === 0 && orphanWorktrees.length === 0) {
|
|
1458
|
+
out.push(chalk.dim("No projects registered."));
|
|
1459
|
+
for (const pool of pools) {
|
|
1460
|
+
if (pool.error) out.push(chalk.yellow(`${pool.error} ${POOL_SETTING_REMEDY}`));
|
|
1461
|
+
if (pool.line) out.push(chalk.dim(pool.line));
|
|
1462
|
+
}
|
|
1463
|
+
for (const line of deviceLeaseLines(leases, leaseNow)) out.push(line);
|
|
1464
|
+
return out;
|
|
1465
|
+
}
|
|
1466
|
+
if (!simsAvailable) out.push(chalk.yellow(`simctl could not be read (${simctlError}), so no iOS sim below could be checked.`));
|
|
1467
|
+
for (const [i, [path, proj]] of projects.entries()) {
|
|
1468
|
+
const state = states[i];
|
|
1469
|
+
if (!state) continue;
|
|
1470
|
+
const shortcut = projectShortcut(path, proj);
|
|
1471
|
+
const marker = path === cwdRoot ? chalk.bold.cyan(`* ${shortcut}`) : shortcut;
|
|
1472
|
+
const idle = phaseMarker(state);
|
|
1473
|
+
out.push(`\n${marker}${idle} ${chalk.dim(`(${path})`)}`);
|
|
1474
|
+
out.push(labelOnlyRoots[i] ? chalk.dim(" worktree root (holds the label; the app registers its own entry)") : chalk.dim(` app: ${proj.bundleId ?? "?"} (${proj.isExpo ?? detectIsExpo(path) ? "expo" : "bare"})`));
|
|
1475
|
+
if (state.metro) {
|
|
1476
|
+
const label = state.metro.running ? chalk.green(`running (pid ${state.metro.pid})`) : state.metro.idleStop ? chalk.dim(`stopped (idle) after ${state.metro.idleStop.idleMinutes}m; \`stim start\`, \`ios\` or \`android\` restarts it`) : state.metro.lastStop ? chalk.dim(`not running${state.metro.lastStop.reason === "vanished" ? "" : ` since ${state.metro.lastStop.at}`}; ${describeMetroLastStop(state.metro.lastStop)}`) : chalk.dim("not running");
|
|
1477
|
+
out.push(` metro: port ${state.metro.port} ${label}`);
|
|
1478
|
+
if (state.metro.tunnel) {
|
|
1479
|
+
const { provider, url } = state.metro.tunnel;
|
|
1480
|
+
out.push(` tunnel: ${provider}${provider === "tailscale" ? " (tailnet-only)" : ""} ${url}`);
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
1483
|
+
if (state.supervisor) {
|
|
1484
|
+
const health = state.supervisor.healthy ? chalk.green("healthy") : chalk.yellow("not answering");
|
|
1485
|
+
const mode = state.supervisor.mode ? chalk.dim(` (${state.supervisor.mode})`) : "";
|
|
1486
|
+
out.push(` supervisor: pid ${state.supervisor.pid}${mode} ${health}`);
|
|
1487
|
+
}
|
|
1488
|
+
if (state.build) {
|
|
1489
|
+
const line = ` ${buildStatusLine(state.build, Date.now())}`;
|
|
1490
|
+
out.push(state.build.state === "running" ? line : chalk.yellow(line));
|
|
1491
|
+
}
|
|
1492
|
+
out.push(...lastBuildsLines(state.lastBuilds));
|
|
1493
|
+
if (state.worktree?.git) out.push(chalk.dim(` git: ${gitSummaryText(state.worktree.git)}`));
|
|
1494
|
+
for (const agent of state.agents ?? []) out.push(chalk.dim(` agent: ${agentLine(agent)}`));
|
|
1495
|
+
if (state.logs) {
|
|
1496
|
+
const n = state.logs.errorsSinceMarker;
|
|
1497
|
+
const errs = n > 0 ? chalk.yellow(` (${n} error${n === 1 ? "" : "s"} since the last marker)`) : "";
|
|
1498
|
+
out.push(chalk.dim(` logs: ${state.logs.dir}`) + errs);
|
|
1499
|
+
}
|
|
1500
|
+
for (const deviceState of [{
|
|
1501
|
+
slot: "default",
|
|
1502
|
+
ios: state.ios,
|
|
1503
|
+
android: state.android
|
|
1504
|
+
}, ...state.slots ?? []]) {
|
|
1505
|
+
const slotLabel = deviceState.slot === "default" ? "" : ` [${deviceState.slot}]`;
|
|
1506
|
+
out.push(...iosStatusLines(deviceState.ios, slotLabel));
|
|
1507
|
+
out.push(...androidStatusLines(deviceState.android, slotLabel));
|
|
1508
|
+
}
|
|
1509
|
+
if (state.macos) {
|
|
1510
|
+
const host = state.macos.host;
|
|
1511
|
+
const where = host ? ` on ${host.machine} as ${host.bundleId}${chalk.dim(` (session ${host.session})`)}` : "";
|
|
1512
|
+
const build = state.macos.build;
|
|
1513
|
+
const placement = build.buildMachine === void 0 ? "" : `; build placement ${build.buildMachine}, built on ${build.builtOn ?? "none"}`;
|
|
1514
|
+
out.push(` macOS ${state.macos.product}: ${state.macos.state}${where}; build ${build.state}${placement}`);
|
|
1515
|
+
if (host && "command" in host.agent) out.push(chalk.dim(` agent: ${host.agent.command}`));
|
|
1516
|
+
}
|
|
1517
|
+
if (state.web) {
|
|
1518
|
+
const browser = state.web.running ? chalk.green(`running (pid ${state.web.pid}, DevTools ${state.web.cdpEndpoint})`) : chalk.dim("not running");
|
|
1519
|
+
const page = state.web.page;
|
|
1520
|
+
const failed = page?.state === "failed" ? ` -- ${chalk.yellow(`page failed: ${page.error}`)}` : "";
|
|
1521
|
+
out.push(` web: ${chalk.cyan(page?.url ?? state.web.url)} ${browser}${state.web.headless ? "" : chalk.dim(" (headed)")}${activitySuffix(state.web.activity)}${failed}`);
|
|
1522
|
+
}
|
|
1523
|
+
for (const device of state.physicalDevices ?? []) out.push(` ${physicalDeviceLine(device, leaseNow)}`);
|
|
1524
|
+
for (const remote of state.remoteDevices ?? []) out.push(` ${remoteDeviceLine(remote)}`);
|
|
1525
|
+
for (const w of state.warnings) out.push(chalk.yellow(` ! ${w}`));
|
|
1526
|
+
for (const note of state.issues.filter((issue) => issue.severity === "info")) out.push(chalk.dim(` - ${note.message}`));
|
|
1527
|
+
}
|
|
1528
|
+
for (const pool of pools) {
|
|
1529
|
+
if (pool.error) out.push(chalk.yellow(`\n${pool.error} ${POOL_SETTING_REMEDY}`));
|
|
1530
|
+
if (pool.line) out.push(chalk.dim(`\n${pool.line}`));
|
|
1531
|
+
}
|
|
1532
|
+
const leaseLines = deviceLeaseLines(leases, leaseNow);
|
|
1533
|
+
if (leaseLines.length) {
|
|
1534
|
+
out.push("");
|
|
1535
|
+
for (const line of leaseLines) out.push(line);
|
|
1536
|
+
}
|
|
1537
|
+
if (orphanWorktrees.length) {
|
|
1538
|
+
out.push(chalk.dim(`\nWorktrees with no environment (${orphanWorktrees.length}):`));
|
|
1539
|
+
for (const w of orphanWorktrees) out.push(chalk.dim(` ${orphanWorktreeLine(w)}`));
|
|
1540
|
+
}
|
|
1541
|
+
out.push(chalk.dim(machine?.memorySource === "footprint" ? `\n${cap.liveCount} active environment(s) use ${formatGb(cap.committedMb)} of ${formatGb(cap.totalMemoryMb)}.` : `\n${cap.liveCount} active environment(s), roughly ${formatGb(cap.committedMb)} of ${formatGb(cap.totalMemoryMb)} committed.`));
|
|
1542
|
+
const volumes = readVolumes(cwdRoot || cwd);
|
|
1543
|
+
const line = diskLine(volumes);
|
|
1544
|
+
if (line) {
|
|
1545
|
+
const tight = tightVolumes(volumes);
|
|
1546
|
+
if (tight.length) {
|
|
1547
|
+
const which = tight.map((v) => v.volume).join(" and ");
|
|
1548
|
+
out.push(chalk.yellow(`${line} A single iOS build can exhaust ${which} -- run \`stim gc\` before starting another environment.`));
|
|
1549
|
+
} else out.push(chalk.dim(line));
|
|
1550
|
+
}
|
|
1551
|
+
if (cap.overCapacity) out.push(chalk.yellow("Over comfortable capacity. A machine that swaps is slower than one working in sequence -- release one before starting another."));
|
|
1552
|
+
return out;
|
|
1553
|
+
}
|
|
1554
|
+
function watchedPids({ roots, states }) {
|
|
1555
|
+
return [...roots.flatMap((root) => [
|
|
1556
|
+
...root.supervisorPid ? [root.supervisorPid] : [],
|
|
1557
|
+
...root.build ? [root.build.pid] : [],
|
|
1558
|
+
...root.browserPids,
|
|
1559
|
+
...root.macosPids ?? []
|
|
1560
|
+
]), ...states.flatMap((state) => state.metro?.running && state.metro.pid ? [state.metro.pid] : [])];
|
|
1561
|
+
}
|
|
1562
|
+
/**
|
|
1563
|
+
* Reads status now and again on every change until stopped, and calls `emit` with each new rendering: the JSON payload
|
|
1564
|
+
* with `json`, the human view otherwise. `emit` never sees the same rendering twice in a row. `cwd` stands for the
|
|
1565
|
+
* directory status runs in, which marks the current workspace.
|
|
1566
|
+
*/
|
|
1567
|
+
function runStatusWatch({ json, cwd = process.cwd(), emit, failed }) {
|
|
1568
|
+
let last = null;
|
|
1569
|
+
let lastPayload = null;
|
|
1570
|
+
let archiveStamp = null;
|
|
1571
|
+
let archives;
|
|
1572
|
+
let snapshot = null;
|
|
1573
|
+
let sources = null;
|
|
1574
|
+
let tablesAt = 0;
|
|
1575
|
+
let machineDue = false;
|
|
1576
|
+
const measurer = createStatusMeasurer({ updated: () => scheduler.trigger("light") });
|
|
1577
|
+
const scheduler = createRefreshScheduler({
|
|
1578
|
+
debounceMs: 250,
|
|
1579
|
+
lightIntervalMs: WATCH_LIGHT_INTERVAL_MS,
|
|
1580
|
+
run: async (kind) => {
|
|
1581
|
+
triggerMaintenance("status-watch", { warn: false });
|
|
1582
|
+
let text;
|
|
1583
|
+
let payload = null;
|
|
1584
|
+
try {
|
|
1585
|
+
const now = Date.now();
|
|
1586
|
+
if (kind === "light" && snapshot) {
|
|
1587
|
+
const machine = json && machineDue;
|
|
1588
|
+
const tables = machine || now - tablesAt >= 5e3;
|
|
1589
|
+
machineDue = false;
|
|
1590
|
+
await refreshLightFacts(snapshot, {
|
|
1591
|
+
tables,
|
|
1592
|
+
machine
|
|
1593
|
+
});
|
|
1594
|
+
if (tables) tablesAt = now;
|
|
1595
|
+
} else {
|
|
1596
|
+
let stamp = null;
|
|
1597
|
+
try {
|
|
1598
|
+
stamp = statSync$1(archiveRoot()).mtimeMs;
|
|
1599
|
+
} catch {}
|
|
1600
|
+
if (archives === void 0 || stamp !== archiveStamp) {
|
|
1601
|
+
archives = readArchives();
|
|
1602
|
+
archiveStamp = stamp;
|
|
1603
|
+
}
|
|
1604
|
+
const first = snapshot === null;
|
|
1605
|
+
snapshot = await readStatus({
|
|
1606
|
+
git: first ? "none" : "all",
|
|
1607
|
+
cwd,
|
|
1608
|
+
probes: liveProbes({
|
|
1609
|
+
simctlListing: sources?.simulatorListing(),
|
|
1610
|
+
gitMaxAgeMs: WATCH_GIT_MAX_AGE_MS,
|
|
1611
|
+
archives
|
|
1612
|
+
})
|
|
1613
|
+
});
|
|
1614
|
+
tablesAt = now;
|
|
1615
|
+
machineDue = false;
|
|
1616
|
+
sources?.watchRepositories(snapshot.gitCommonDirs);
|
|
1617
|
+
sources?.watchProcesses(watchedPids(snapshot));
|
|
1618
|
+
if (first) scheduler.trigger("full", 0);
|
|
1619
|
+
}
|
|
1620
|
+
measurer.schedule(snapshot.states, snapshot.worktrees);
|
|
1621
|
+
text = renderStatus(snapshot, json, (full) => payload = watchPayload(lastPayload, full), cwd).join("\n");
|
|
1622
|
+
} catch (error) {
|
|
1623
|
+
failed(String(error?.message || error));
|
|
1624
|
+
return;
|
|
1625
|
+
} finally {
|
|
1626
|
+
sources?.reconcile();
|
|
1627
|
+
}
|
|
1628
|
+
const key = json && payload ? watchChangeKey(payload) : text;
|
|
1629
|
+
if (key === last) return;
|
|
1630
|
+
last = key;
|
|
1631
|
+
lastPayload = payload;
|
|
1632
|
+
emit(text);
|
|
1633
|
+
}
|
|
1634
|
+
});
|
|
1635
|
+
const fallback = setInterval(() => scheduler.trigger("full"), WATCH_FALLBACK_MS);
|
|
1636
|
+
const machine = setInterval(() => {
|
|
1637
|
+
if (!json || !snapshot?.machine) return;
|
|
1638
|
+
machineDue = true;
|
|
1639
|
+
scheduler.trigger("light");
|
|
1640
|
+
}, WATCH_MACHINE_INTERVAL_MS);
|
|
1641
|
+
sources = watchStatusSources({
|
|
1642
|
+
home: getConfigDir(),
|
|
1643
|
+
deviceSet: process.platform === "darwin" ? join$1(userInfo().homedir, "Library", "Developer", "CoreSimulator", "Devices") : null,
|
|
1644
|
+
onChange: (kind) => scheduler.trigger(kind)
|
|
1645
|
+
});
|
|
1646
|
+
scheduler.trigger("full", 0);
|
|
1647
|
+
return { stop() {
|
|
1648
|
+
clearInterval(fallback);
|
|
1649
|
+
clearInterval(machine);
|
|
1650
|
+
scheduler.stop();
|
|
1651
|
+
sources?.stop();
|
|
1652
|
+
} };
|
|
1653
|
+
}
|
|
1654
|
+
async function watchStatus(json) {
|
|
1655
|
+
const finish = () => {
|
|
1656
|
+
stopReader();
|
|
1657
|
+
watch.stop();
|
|
1658
|
+
process.exit(0);
|
|
1659
|
+
};
|
|
1660
|
+
process.on("SIGINT", finish);
|
|
1661
|
+
process.on("SIGTERM", finish);
|
|
1662
|
+
const watch = runStatusWatch({
|
|
1663
|
+
json,
|
|
1664
|
+
emit: (text) => process.stdout.write(`${!json && process.stdout.isTTY ? "\x1B[2J\x1B[H" : ""}${text}\n`),
|
|
1665
|
+
failed: (message) => console.error(chalk.red(message))
|
|
1666
|
+
});
|
|
1667
|
+
const stopReader = watchStdoutReader(finish);
|
|
1668
|
+
await new Promise(() => {});
|
|
1669
|
+
}
|
|
1670
|
+
function agentLine({ tool, title, sessionId, lastActiveAt }) {
|
|
1671
|
+
const at = lastActiveAt ? `, active ${lastActiveAt}` : "";
|
|
1672
|
+
return `${tool === "codex" ? "Codex" : "Claude Code"} ${title ? `"${title}"` : sessionId}${at}`;
|
|
1673
|
+
}
|
|
1674
|
+
function orphanWorktreeLine(w) {
|
|
1675
|
+
return `${w.path}${w.branch ? ` [${w.branch}]` : ""}${w.git ? ` -- ${gitSummaryText(w.git)}` : ""}`;
|
|
1676
|
+
}
|
|
1677
|
+
function lastBuildsLines(reports) {
|
|
1678
|
+
const texts = Object.values(reports ?? {}).map(lastBuildText);
|
|
1679
|
+
return texts.length ? [chalk.dim(` last build: ${texts.join(", ")}`)] : [];
|
|
1680
|
+
}
|
|
1681
|
+
function lastBuildText(report) {
|
|
1682
|
+
const source = report.cacheHit ? `${report.cacheHit} cache` : report.status === "ok" ? "compiled" : "no cache hit";
|
|
1683
|
+
const took = report.durationMs === null ? "" : ` in ${formatDuration(report.durationMs)}`;
|
|
1684
|
+
const placement = report.buildMachine === void 0 ? "" : `; build placement ${report.buildMachine}, built on ${report.builtOn ?? (report.cacheHit ? "none (cache)" : "none")}`;
|
|
1685
|
+
return `${report.platform} ${report.status === "ok" ? source : `failed (${report.errorCode ?? "error"}), ${source}`}${took}${placement}`;
|
|
1686
|
+
}
|
|
1687
|
+
function idleShutdownSuffix(record) {
|
|
1688
|
+
return record ? chalk.dim(` -- shut down after ${record.idleMinutes}m idle at ${record.at} (${record.reason === DEVICE_RECLAIM_REASON ? "reclaimed for a waiting run; devices.reclaimIdleMinutes" : "devices.idleShutdownMinutes"})`) : "";
|
|
1689
|
+
}
|
|
1690
|
+
function activitySuffix(activity) {
|
|
1691
|
+
const label = activityLabel(activity, Date.now());
|
|
1692
|
+
return label ? ` -- ${activity?.state === "driven" ? chalk.magenta(label) : chalk.dim(label)}` : "";
|
|
1693
|
+
}
|
|
1694
|
+
function appSuffix(app) {
|
|
1695
|
+
if (!app) return "";
|
|
1696
|
+
if (app.state === "running") return chalk.dim(` -- ${app.id} running`);
|
|
1697
|
+
if (app.state === "stopped") return ` -- ${chalk.yellow(`${app.id} not running`)}`;
|
|
1698
|
+
return chalk.dim(` -- ${app.id} process unknown`);
|
|
1699
|
+
}
|
|
1700
|
+
function readVolumes(projectPath) {
|
|
1701
|
+
const roots = [.../* @__PURE__ */ new Set([
|
|
1702
|
+
"/",
|
|
1703
|
+
volumeRootFor(getConfigDir()),
|
|
1704
|
+
volumeRootFor(projectPath)
|
|
1705
|
+
])];
|
|
1706
|
+
const volumes = [];
|
|
1707
|
+
for (const volume of roots) {
|
|
1708
|
+
const disk = parseDfFree(getExecutor().runFileQuiet("df", ["-k", volume], { timeoutMs: 5e3 }));
|
|
1709
|
+
if (disk) volumes.push({
|
|
1710
|
+
volume,
|
|
1711
|
+
disk
|
|
1712
|
+
});
|
|
1713
|
+
}
|
|
1714
|
+
return volumes;
|
|
1715
|
+
}
|
|
1716
|
+
//#endregion
|
|
1717
|
+
export { runStatusWatch as n, statusCommand as r, readVolumes as t };
|