@futdevpro/nts-dynamo 1.15.437 → 1.15.439

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/build/_modules/machine-monitor/_models/disk-space.interface.d.ts +37 -0
  2. package/build/_modules/machine-monitor/_models/disk-space.interface.d.ts.map +1 -0
  3. package/build/_modules/machine-monitor/_models/disk-space.interface.js +3 -0
  4. package/build/_modules/machine-monitor/_models/disk-space.interface.js.map +1 -0
  5. package/build/_modules/machine-monitor/_models/machine-state-recorder-deps.interface.d.ts +18 -0
  6. package/build/_modules/machine-monitor/_models/machine-state-recorder-deps.interface.d.ts.map +1 -0
  7. package/build/_modules/machine-monitor/_models/machine-state-recorder-deps.interface.js +3 -0
  8. package/build/_modules/machine-monitor/_models/machine-state-recorder-deps.interface.js.map +1 -0
  9. package/build/_modules/machine-monitor/_models/machine-state-row.interface.d.ts +34 -0
  10. package/build/_modules/machine-monitor/_models/machine-state-row.interface.d.ts.map +1 -0
  11. package/build/_modules/machine-monitor/_models/machine-state-row.interface.js +3 -0
  12. package/build/_modules/machine-monitor/_models/machine-state-row.interface.js.map +1 -0
  13. package/build/_modules/machine-monitor/_models/machine-state-summary.interface.d.ts +14 -0
  14. package/build/_modules/machine-monitor/_models/machine-state-summary.interface.d.ts.map +1 -0
  15. package/build/_modules/machine-monitor/_models/machine-state-summary.interface.js +3 -0
  16. package/build/_modules/machine-monitor/_models/machine-state-summary.interface.js.map +1 -0
  17. package/build/_modules/machine-monitor/disk-space-windows-reader.util.d.ts +16 -0
  18. package/build/_modules/machine-monitor/disk-space-windows-reader.util.d.ts.map +1 -0
  19. package/build/_modules/machine-monitor/disk-space-windows-reader.util.js +31 -0
  20. package/build/_modules/machine-monitor/disk-space-windows-reader.util.js.map +1 -0
  21. package/build/_modules/machine-monitor/disk-space.runner.d.ts +37 -0
  22. package/build/_modules/machine-monitor/disk-space.runner.d.ts.map +1 -0
  23. package/build/_modules/machine-monitor/disk-space.runner.js +100 -0
  24. package/build/_modules/machine-monitor/disk-space.runner.js.map +1 -0
  25. package/build/_modules/machine-monitor/disk-space.util.d.ts +51 -0
  26. package/build/_modules/machine-monitor/disk-space.util.d.ts.map +1 -0
  27. package/build/_modules/machine-monitor/disk-space.util.js +103 -0
  28. package/build/_modules/machine-monitor/disk-space.util.js.map +1 -0
  29. package/build/_modules/machine-monitor/index.d.ts +12 -0
  30. package/build/_modules/machine-monitor/index.d.ts.map +1 -0
  31. package/build/_modules/machine-monitor/index.js +18 -0
  32. package/build/_modules/machine-monitor/index.js.map +1 -0
  33. package/build/_modules/machine-monitor/machine-state-window.util.d.ts +18 -0
  34. package/build/_modules/machine-monitor/machine-state-window.util.d.ts.map +1 -0
  35. package/build/_modules/machine-monitor/machine-state-window.util.js +68 -0
  36. package/build/_modules/machine-monitor/machine-state-window.util.js.map +1 -0
  37. package/build/_modules/machine-monitor/machine-state-windows-runners.util.d.ts +14 -0
  38. package/build/_modules/machine-monitor/machine-state-windows-runners.util.d.ts.map +1 -0
  39. package/build/_modules/machine-monitor/machine-state-windows-runners.util.js +26 -0
  40. package/build/_modules/machine-monitor/machine-state-windows-runners.util.js.map +1 -0
  41. package/build/_modules/machine-monitor/machine-state.recorder.d.ts +46 -0
  42. package/build/_modules/machine-monitor/machine-state.recorder.d.ts.map +1 -0
  43. package/build/_modules/machine-monitor/machine-state.recorder.js +123 -0
  44. package/build/_modules/machine-monitor/machine-state.recorder.js.map +1 -0
  45. package/build/_modules/machine-monitor/machine-state.util.d.ts +44 -0
  46. package/build/_modules/machine-monitor/machine-state.util.d.ts.map +1 -0
  47. package/build/_modules/machine-monitor/machine-state.util.js +121 -0
  48. package/build/_modules/machine-monitor/machine-state.util.js.map +1 -0
  49. package/package.json +11 -2
@@ -0,0 +1,37 @@
1
+ /** The measurement of one drive. */
2
+ export interface DyNTS_DiskReading_Interface {
3
+ /** The machine the drive belongs to. */
4
+ host: string;
5
+ /** The drive (e.g. `C:` or `/`). */
6
+ mount: string;
7
+ usedPct: number;
8
+ freeGb: number;
9
+ }
10
+ /** One alert to send. */
11
+ export interface DyNTS_DiskAlert_Interface extends DyNTS_DiskReading_Interface {
12
+ level: 'warn' | 'critical';
13
+ }
14
+ /** The saved state: per drive, the last alert. */
15
+ export type DyNTS_DiskAlertState = Record<string, {
16
+ level: 'warn' | 'critical';
17
+ at: string;
18
+ }>;
19
+ /** The dependencies of the disk-space runner — the spec replaces them. */
20
+ export interface DyNTS_DiskSpaceRunnerDeps_Interface {
21
+ /** The JSON file of the alert state. */
22
+ statePath: string;
23
+ /** The machine's drives (local + network); not measurable ⇒ throws. */
24
+ readLocal: () => Promise<DyNTS_DiskReading_Interface[]>;
25
+ /** Further drives (e.g. a remote server's); not reachable ⇒ throws (logged, the local measurement goes on). */
26
+ readRemote?: () => Promise<DyNTS_DiskReading_Interface[]>;
27
+ /** "Do not disturb": only the critical alert goes out. Missing ⇒ never. */
28
+ readDnd?: (now: Date) => Promise<boolean>;
29
+ send: (text: string) => Promise<{
30
+ sent: boolean;
31
+ detail: string;
32
+ }>;
33
+ log: (code: string, detail: string, isError: boolean) => void;
34
+ /** The prefix of the logged codes (`<prefix>-DISK-SPACE-…`). Default: `DyNTS-MM`. */
35
+ codePrefix?: string;
36
+ }
37
+ //# sourceMappingURL=disk-space.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"disk-space.interface.d.ts","sourceRoot":"","sources":["../../../../src/_modules/machine-monitor/_models/disk-space.interface.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,MAAM,WAAW,2BAA2B;IAC1C,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,oCAAoC;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,yBAAyB;AACzB,MAAM,WAAW,yBAA0B,SAAQ,2BAA2B;IAC5E,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC;CAC5B;AAED,kDAAkD;AAClD,MAAM,MAAM,oBAAoB,GAAG,MAAM,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAE9F,0EAA0E;AAC1E,MAAM,WAAW,mCAAmC;IAClD,wCAAwC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,uEAAuE;IACvE,SAAS,EAAE,MAAM,OAAO,CAAC,2BAA2B,EAAE,CAAC,CAAC;IACxD,+GAA+G;IAC/G,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,2BAA2B,EAAE,CAAC,CAAC;IAC1D,2EAA2E;IAC3E,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1C,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnE,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9D,qFAAqF;IACrF,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=disk-space.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"disk-space.interface.js","sourceRoot":"","sources":["../../../../src/_modules/machine-monitor/_models/disk-space.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,18 @@
1
+ /** The dependencies of the machine-state recorder — the spec replaces them. */
2
+ export interface DyNTS_MachineStateRecorderDeps_Interface {
3
+ /** The folder of the daily JSONL files. */
4
+ dir: string;
5
+ runTypeperf: (counters: readonly string[]) => Promise<string>;
6
+ runTasklist: () => Promise<string>;
7
+ /** 🌡️ The `nvidia-smi` output (missing ⇒ no temperature measurement). */
8
+ runGpuTemps?: () => Promise<string>;
9
+ /** 🌡️ The alert above the threshold; missing ⇒ only the log. */
10
+ alert?: (text: string) => Promise<void>;
11
+ log: (code: string, detail: string, isError: boolean) => void;
12
+ /**
13
+ * The prefix of the logged codes (`<prefix>-MACHINE-STATE-FAILED`, …). Default: `DyNTS-MM`. An app that already
14
+ * counts its own codes keeps them (e.g. `MA` ⇒ `MA-MACHINE-STATE-FAILED`).
15
+ */
16
+ codePrefix?: string;
17
+ }
18
+ //# sourceMappingURL=machine-state-recorder-deps.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"machine-state-recorder-deps.interface.d.ts","sourceRoot":"","sources":["../../../../src/_modules/machine-monitor/_models/machine-state-recorder-deps.interface.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,MAAM,WAAW,wCAAwC;IACvD,2CAA2C;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9D,WAAW,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACnC,0EAA0E;IAC1E,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACpC,iEAAiE;IACjE,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9D;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=machine-state-recorder-deps.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"machine-state-recorder-deps.interface.js","sourceRoot":"","sources":["../../../../src/_modules/machine-monitor/_models/machine-state-recorder-deps.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,34 @@
1
+ /** The momentary queue of one disk. */
2
+ export interface DyNTS_MachineDiskState_Interface {
3
+ /** The `typeperf` instance name (e.g. `4 C:`). */
4
+ disk: string;
5
+ queue: number | null;
6
+ /** Average service time, milliseconds. */
7
+ latencyMs: number | null;
8
+ }
9
+ /** The memory of one process. */
10
+ export interface DyNTS_MachineProcessMemory_Interface {
11
+ name: string;
12
+ pid: number;
13
+ memMb: number;
14
+ }
15
+ /** 🌡️ The temperature of one graphics card. */
16
+ export interface DyNTS_MachineGpuTemp_Interface {
17
+ name: string;
18
+ tempC: number | null;
19
+ }
20
+ /** One per-minute row of the machine-state log. */
21
+ export interface DyNTS_MachineStateRow_Interface {
22
+ ts: string;
23
+ availableMb: number | null;
24
+ commitGb: number | null;
25
+ commitLimitGb: number | null;
26
+ /** The commit as a percentage of the limit. */
27
+ commitPct: number | null;
28
+ pagefilePct: number | null;
29
+ disks: DyNTS_MachineDiskState_Interface[];
30
+ top: DyNTS_MachineProcessMemory_Interface[];
31
+ /** 🌡️ The temperature of the graphics cards (`nvidia-smi`; a read error ⇒ missing, the row still goes). */
32
+ gpus?: DyNTS_MachineGpuTemp_Interface[];
33
+ }
34
+ //# sourceMappingURL=machine-state-row.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"machine-state-row.interface.d.ts","sourceRoot":"","sources":["../../../../src/_modules/machine-monitor/_models/machine-state-row.interface.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,MAAM,WAAW,gCAAgC;IAC/C,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,0CAA0C;IAC1C,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,iCAAiC;AACjC,MAAM,WAAW,oCAAoC;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,gDAAgD;AAChD,MAAM,WAAW,8BAA8B;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,mDAAmD;AACnD,MAAM,WAAW,+BAA+B;IAC9C,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,+CAA+C;IAC/C,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,KAAK,EAAE,gCAAgC,EAAE,CAAC;IAC1C,GAAG,EAAE,oCAAoC,EAAE,CAAC;IAC5C,4GAA4G;IAC5G,IAAI,CAAC,EAAE,8BAA8B,EAAE,CAAC;CACzC"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=machine-state-row.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"machine-state-row.interface.js","sourceRoot":"","sources":["../../../../src/_modules/machine-monitor/_models/machine-state-row.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,14 @@
1
+ import { DyNTS_MachineDiskState_Interface, DyNTS_MachineProcessMemory_Interface } from './machine-state-row.interface';
2
+ /** The machine-state summary of a time window (e.g. around a CPU spike). */
3
+ export interface DyNTS_MachineStateSummary_Interface {
4
+ rows: number;
5
+ minAvailableMb: number | null;
6
+ maxCommitPct: number | null;
7
+ maxPagefilePct: number | null;
8
+ /** 🌡️ The highest graphics-card temperature in the window; no data ⇒ `null`. */
9
+ maxGpuTempC: number | null;
10
+ worstDisk: DyNTS_MachineDiskState_Interface | null;
11
+ /** The top processes of the row with the least free memory. */
12
+ topAtLow: DyNTS_MachineProcessMemory_Interface[];
13
+ }
14
+ //# sourceMappingURL=machine-state-summary.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"machine-state-summary.interface.d.ts","sourceRoot":"","sources":["../../../../src/_modules/machine-monitor/_models/machine-state-summary.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gCAAgC,EAAE,oCAAoC,EACvE,MAAM,+BAA+B,CAAC;AAEvC,4EAA4E;AAC5E,MAAM,WAAW,mCAAmC;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,iFAAiF;IACjF,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,gCAAgC,GAAG,IAAI,CAAC;IACnD,+DAA+D;IAC/D,QAAQ,EAAE,oCAAoC,EAAE,CAAC;CAClD"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=machine-state-summary.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"machine-state-summary.interface.js","sourceRoot":"","sources":["../../../../src/_modules/machine-monitor/_models/machine-state-summary.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,16 @@
1
+ import { DyNTS_DiskReading_Interface } from './_models/disk-space.interface';
2
+ /**
3
+ * BFR-FLEET-033 — the default Windows reader of the disk-space watcher: the local and network drives from the CIM
4
+ * (`Win32_LogicalDisk`) through PowerShell, an asynchronous child process with a hidden window and a timeout.
5
+ *
6
+ * @description Transplanted from My Assistant's wiring (the same command and timeout). ⛔ Windows only.
7
+ */
8
+ export declare class DyNTS_DiskSpaceWindowsReader_Util {
9
+ /**
10
+ * The machine's drives.
11
+ *
12
+ * @param skipServers the network servers whose disks are measured directly (their shares are skipped)
13
+ */
14
+ static readLocal(skipServers?: readonly string[]): Promise<DyNTS_DiskReading_Interface[]>;
15
+ }
16
+ //# sourceMappingURL=disk-space-windows-reader.util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"disk-space-windows-reader.util.d.ts","sourceRoot":"","sources":["../../../src/_modules/machine-monitor/disk-space-windows-reader.util.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,2BAA2B,EAAE,MAAM,gCAAgC,CAAC;AAK7E;;;;;GAKG;AACH,qBAAa,iCAAiC;IAE5C;;;;OAIG;WACU,SAAS,CAAC,WAAW,GAAE,SAAS,MAAM,EAAO,GAAG,OAAO,CAAC,2BAA2B,EAAE,CAAC;CASpG"}
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DyNTS_DiskSpaceWindowsReader_Util = void 0;
4
+ const child_process_1 = require("child_process");
5
+ const os_1 = require("os");
6
+ const util_1 = require("util");
7
+ const disk_space_util_1 = require("./disk-space.util");
8
+ const execFileAsync = (0, util_1.promisify)(child_process_1.execFile);
9
+ /**
10
+ * BFR-FLEET-033 — the default Windows reader of the disk-space watcher: the local and network drives from the CIM
11
+ * (`Win32_LogicalDisk`) through PowerShell, an asynchronous child process with a hidden window and a timeout.
12
+ *
13
+ * @description Transplanted from My Assistant's wiring (the same command and timeout). ⛔ Windows only.
14
+ */
15
+ class DyNTS_DiskSpaceWindowsReader_Util {
16
+ /**
17
+ * The machine's drives.
18
+ *
19
+ * @param skipServers the network servers whose disks are measured directly (their shares are skipped)
20
+ */
21
+ static async readLocal(skipServers = []) {
22
+ const { stdout } = await execFileAsync('powershell', [
23
+ '-NoProfile', '-Command',
24
+ 'Get-CimInstance Win32_LogicalDisk | Select-Object DeviceID,DriveType,ProviderName,Size,FreeSpace '
25
+ + '| ConvertTo-Json -Compress',
26
+ ], { windowsHide: true, timeout: 60_000 });
27
+ return disk_space_util_1.DyNTS_DiskSpace_Util.parseCim({ host: (0, os_1.hostname)(), cim: JSON.parse(stdout), skipServers: skipServers });
28
+ }
29
+ }
30
+ exports.DyNTS_DiskSpaceWindowsReader_Util = DyNTS_DiskSpaceWindowsReader_Util;
31
+ //# sourceMappingURL=disk-space-windows-reader.util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"disk-space-windows-reader.util.js","sourceRoot":"","sources":["../../../src/_modules/machine-monitor/disk-space-windows-reader.util.ts"],"names":[],"mappings":";;;AAAA,iDAAyC;AACzC,2BAA8B;AAC9B,+BAAiC;AAGjC,uDAAyD;AAEzD,MAAM,aAAa,GAAG,IAAA,gBAAS,EAAC,wBAAQ,CAAC,CAAC;AAE1C;;;;;GAKG;AACH,MAAa,iCAAiC;IAE5C;;;;OAIG;IACH,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,cAAiC,EAAE;QACxD,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,YAAY,EAAE;YACnD,YAAY,EAAE,UAAU;YACxB,mGAAmG;kBAC/F,4BAA4B;SACjC,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QAE3C,OAAO,sCAAoB,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,IAAA,aAAQ,GAAE,EAAE,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC,CAAC;IAChH,CAAC;CACF;AAhBD,8EAgBC"}
@@ -0,0 +1,37 @@
1
+ import { DyNTS_DiskSpaceRunnerDeps_Interface } from './_models/disk-space.interface';
2
+ /**
3
+ * BFR-FLEET-033 — the disk-space watcher: every 30 minutes on the app's own tick. ⛔ It never throws: a failed
4
+ * measurement is a coded log line, never a silent "all fine".
5
+ *
6
+ * @description Transplanted from My Assistant (`DiskSpaceRunner`), the logic unchanged. The state is written
7
+ * atomically (temporary file + rename); a failed send keeps the state, so the next tick tries again.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * const runner = new DyNTS_DiskSpace_Runner({
12
+ * statePath: DyNTS_DiskSpace_Runner.resolveStatePath('my-app'),
13
+ * readLocal: DyNTS_DiskSpaceWindowsReader_Util.readLocal,
14
+ * send: async (text) => ({ sent: await notify(text), detail: '' }),
15
+ * log: (code, detail) => DyFM_Log.warn(code, detail),
16
+ * });
17
+ * ```
18
+ */
19
+ export declare class DyNTS_DiskSpace_Runner {
20
+ static readonly EVERY_MS: number;
21
+ private lastRunAt;
22
+ private isRunning;
23
+ private readonly deps;
24
+ constructor(deps: DyNTS_DiskSpaceRunnerDeps_Interface);
25
+ /**
26
+ * The state file under the user's config folder.
27
+ *
28
+ * @param appFolder the app's own folder under `~/.config` (e.g. `my-app`)
29
+ * @param userHome the home folder (default: the current user's)
30
+ */
31
+ static resolveStatePath(appFolder: string, userHome?: string): string;
32
+ /** The code with the configured prefix. */
33
+ private code;
34
+ /** One measurement, if 30 minutes passed since the last. */
35
+ tick(now?: Date): Promise<void>;
36
+ }
37
+ //# sourceMappingURL=disk-space.runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"disk-space.runner.d.ts","sourceRoot":"","sources":["../../../src/_modules/machine-monitor/disk-space.runner.ts"],"names":[],"mappings":"AAKA,OAAO,EACyE,mCAAmC,EAClH,MAAM,gCAAgC,CAAC;AAGxC;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,sBAAsB;IAEjC,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAe;IAE/C,OAAO,CAAC,SAAS,CAAoC;IACrD,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAsC;gBAE/C,IAAI,EAAE,mCAAmC;IAIrD;;;;;OAKG;IACH,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAkB,GAAG,MAAM;IAIhF,2CAA2C;IAC3C,OAAO,CAAC,IAAI;IAIZ,4DAA4D;IACtD,IAAI,CAAC,GAAG,GAAE,IAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;CA2DlD"}
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DyNTS_DiskSpace_Runner = void 0;
4
+ const fs_1 = require("fs");
5
+ const promises_1 = require("fs/promises");
6
+ const os_1 = require("os");
7
+ const path_1 = require("path");
8
+ const disk_space_util_1 = require("./disk-space.util");
9
+ /**
10
+ * BFR-FLEET-033 — the disk-space watcher: every 30 minutes on the app's own tick. ⛔ It never throws: a failed
11
+ * measurement is a coded log line, never a silent "all fine".
12
+ *
13
+ * @description Transplanted from My Assistant (`DiskSpaceRunner`), the logic unchanged. The state is written
14
+ * atomically (temporary file + rename); a failed send keeps the state, so the next tick tries again.
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * const runner = new DyNTS_DiskSpace_Runner({
19
+ * statePath: DyNTS_DiskSpace_Runner.resolveStatePath('my-app'),
20
+ * readLocal: DyNTS_DiskSpaceWindowsReader_Util.readLocal,
21
+ * send: async (text) => ({ sent: await notify(text), detail: '' }),
22
+ * log: (code, detail) => DyFM_Log.warn(code, detail),
23
+ * });
24
+ * ```
25
+ */
26
+ class DyNTS_DiskSpace_Runner {
27
+ static EVERY_MS = 30 * 60_000;
28
+ lastRunAt = Number.NEGATIVE_INFINITY;
29
+ isRunning = false;
30
+ deps;
31
+ constructor(deps) {
32
+ this.deps = deps;
33
+ }
34
+ /**
35
+ * The state file under the user's config folder.
36
+ *
37
+ * @param appFolder the app's own folder under `~/.config` (e.g. `my-app`)
38
+ * @param userHome the home folder (default: the current user's)
39
+ */
40
+ static resolveStatePath(appFolder, userHome = (0, os_1.homedir)()) {
41
+ return (0, path_1.join)(userHome, '.config', appFolder, 'status', 'disk-space-alerts.json');
42
+ }
43
+ /** The code with the configured prefix. */
44
+ code(suffix) {
45
+ return `${this.deps.codePrefix ?? 'DyNTS-MM'}-${suffix}`;
46
+ }
47
+ /** One measurement, if 30 minutes passed since the last. */
48
+ async tick(now = new Date()) {
49
+ if (this.isRunning || now.getTime() - this.lastRunAt < DyNTS_DiskSpace_Runner.EVERY_MS)
50
+ return;
51
+ this.isRunning = true;
52
+ this.lastRunAt = now.getTime();
53
+ try {
54
+ let local = [];
55
+ try {
56
+ local = await this.deps.readLocal();
57
+ }
58
+ catch (err) {
59
+ this.deps.log(this.code('DISK-SPACE-LOCAL-UNMEASURABLE'), `the machine's drives are NOT measurable: ${err instanceof Error ? err.message : String(err)}`, true);
60
+ }
61
+ let remote = [];
62
+ try {
63
+ remote = this.deps.readRemote ? await this.deps.readRemote() : [];
64
+ }
65
+ catch (err) {
66
+ this.deps.log(this.code('DISK-SPACE-REMOTE-UNMEASURABLE'), `the remote drives are NOT measurable: ${err instanceof Error ? err.message : String(err)}`, false);
67
+ }
68
+ const state = (0, fs_1.existsSync)(this.deps.statePath)
69
+ ? JSON.parse(await (0, promises_1.readFile)(this.deps.statePath, 'utf-8')) : {};
70
+ const decision = disk_space_util_1.DyNTS_DiskSpace_Util.decide({
71
+ readings: [...local, ...remote],
72
+ state: state,
73
+ now: now,
74
+ dnd: this.deps.readDnd ? await this.deps.readDnd(now) : false,
75
+ });
76
+ if (decision.alerts.length) {
77
+ const result = await this.deps.send(disk_space_util_1.DyNTS_DiskSpace_Util.message(decision.alerts));
78
+ // ⛔ on a failed send the state stays ⇒ the next tick tries again
79
+ if (!result.sent) {
80
+ this.deps.log(this.code('DISK-SPACE-SEND-FAILED'), result.detail, true);
81
+ return;
82
+ }
83
+ this.deps.log(this.code('DISK-SPACE-ALERTED'), decision.alerts
84
+ .map((a) => `${a.host} ${a.mount} ${Math.round(a.usedPct)}%`).join(', '), false);
85
+ }
86
+ await (0, promises_1.mkdir)((0, path_1.dirname)(this.deps.statePath), { recursive: true });
87
+ const temporary = `${this.deps.statePath}.${process.pid}.tmp`;
88
+ await (0, promises_1.writeFile)(temporary, JSON.stringify(decision.state, null, 2), 'utf-8');
89
+ await (0, promises_1.rename)(temporary, this.deps.statePath);
90
+ }
91
+ catch (err) {
92
+ this.deps.log(this.code('DISK-SPACE-FAILED'), err instanceof Error ? err.message : String(err), true);
93
+ }
94
+ finally {
95
+ this.isRunning = false;
96
+ }
97
+ }
98
+ }
99
+ exports.DyNTS_DiskSpace_Runner = DyNTS_DiskSpace_Runner;
100
+ //# sourceMappingURL=disk-space.runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"disk-space.runner.js","sourceRoot":"","sources":["../../../src/_modules/machine-monitor/disk-space.runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ import { DyNTS_DiskAlert_Interface, DyNTS_DiskAlertState, DyNTS_DiskReading_Interface } from './_models/disk-space.interface';
2
+ /**
3
+ * BFR-FLEET-033 — the pure decision logic of the disk-space alert: any drive above 95 % ⇒ an alert, without repeating.
4
+ *
5
+ * @description Transplanted from My Assistant (`cli/src/diagnostics/disk-space.ts`), the logic unchanged:
6
+ * - a drive alerts again ONLY when the level rises (warning ⇒ critical) or 24 hours passed; under 93 % it re-arms
7
+ * (the swing around 95 % is noise);
8
+ * - under "do not disturb" only the critical (≥ 99 %) goes out, and the warning is not stored, so it goes out after.
9
+ */
10
+ export declare class DyNTS_DiskSpace_Util {
11
+ static readonly WARN_PCT: number;
12
+ static readonly CRITICAL_PCT: number;
13
+ /** Under this it re-arms (the swing around 95 % is noise). */
14
+ static readonly CLEAR_PCT: number;
15
+ static readonly REPEAT_MS: number;
16
+ /** The key of a drive. **Pure function.** */
17
+ static keyOf(reading: DyNTS_DiskReading_Interface): string;
18
+ /** The level. **Pure function.** */
19
+ static levelOf(usedPct: number): 'warn' | 'critical' | null;
20
+ /** What goes out now, and the new state. **Pure function.** */
21
+ static decide(params: {
22
+ readings: readonly DyNTS_DiskReading_Interface[];
23
+ state: DyNTS_DiskAlertState;
24
+ now: Date;
25
+ dnd: boolean;
26
+ }): {
27
+ alerts: DyNTS_DiskAlert_Interface[];
28
+ state: DyNTS_DiskAlertState;
29
+ };
30
+ /** The message. **Pure function.** */
31
+ static message(alerts: readonly DyNTS_DiskAlert_Interface[]): string;
32
+ /**
33
+ * The machine's drives from the Windows CIM list (`Win32_LogicalDisk`: `DeviceID`, `DriveType`, `ProviderName`,
34
+ * `Size`, `FreeSpace`). **Pure function.**
35
+ *
36
+ * @description A local disk (3) under the machine's name; a NETWORK drive (4) under ITS OWN server's name (e.g.
37
+ * `\\SERVER\share` ⇒ `SERVER`) — and it is skipped when that server's disks are measured directly
38
+ * (`skipServers`), otherwise the same disk would alert twice. A zero size ⇒ skipped.
39
+ */
40
+ static parseCim(params: {
41
+ host: string;
42
+ cim: unknown;
43
+ skipServers: readonly string[];
44
+ }): DyNTS_DiskReading_Interface[];
45
+ /**
46
+ * A disk list in the `{ disks: [{ mount, freeGb, usedPct }] }` shape (e.g. a remote host's diagnostics JSON) under
47
+ * the given host name. **Pure function.**
48
+ */
49
+ static parseDiskList(host: string, diag: unknown): DyNTS_DiskReading_Interface[];
50
+ }
51
+ //# sourceMappingURL=disk-space.util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"disk-space.util.d.ts","sourceRoot":"","sources":["../../../src/_modules/machine-monitor/disk-space.util.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,EAAE,oBAAoB,EAAE,2BAA2B,EAC7E,MAAM,gCAAgC,CAAC;AAExC;;;;;;;GAOG;AACH,qBAAa,oBAAoB;IAE/B,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAM;IACtC,MAAM,CAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAM;IAC1C,8DAA8D;IAC9D,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAM;IACvC,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAoB;IAErD,6CAA6C;IAC7C,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,2BAA2B,GAAG,MAAM;IAI1D,oCAAoC;IACpC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,IAAI;IAK3D,+DAA+D;IAC/D,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE;QACpB,QAAQ,EAAE,SAAS,2BAA2B,EAAE,CAAC;QAAC,KAAK,EAAE,oBAAoB,CAAC;QAAC,GAAG,EAAE,IAAI,CAAC;QAAC,GAAG,EAAE,OAAO,CAAC;KACxG,GAAG;QAAE,MAAM,EAAE,yBAAyB,EAAE,CAAC;QAAC,KAAK,EAAE,oBAAoB,CAAA;KAAE;IA4BxE,sCAAsC;IACtC,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,SAAS,yBAAyB,EAAE,GAAG,MAAM;IASpE;;;;;;;OAOG;IACH,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,GAAG,2BAA2B,EAAE;IAwBtH;;;OAGG;IACH,MAAM,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,2BAA2B,EAAE;CAYjF"}
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DyNTS_DiskSpace_Util = void 0;
4
+ /**
5
+ * BFR-FLEET-033 — the pure decision logic of the disk-space alert: any drive above 95 % ⇒ an alert, without repeating.
6
+ *
7
+ * @description Transplanted from My Assistant (`cli/src/diagnostics/disk-space.ts`), the logic unchanged:
8
+ * - a drive alerts again ONLY when the level rises (warning ⇒ critical) or 24 hours passed; under 93 % it re-arms
9
+ * (the swing around 95 % is noise);
10
+ * - under "do not disturb" only the critical (≥ 99 %) goes out, and the warning is not stored, so it goes out after.
11
+ */
12
+ class DyNTS_DiskSpace_Util {
13
+ static WARN_PCT = 95;
14
+ static CRITICAL_PCT = 99;
15
+ /** Under this it re-arms (the swing around 95 % is noise). */
16
+ static CLEAR_PCT = 93;
17
+ static REPEAT_MS = 24 * 60 * 60_000;
18
+ /** The key of a drive. **Pure function.** */
19
+ static keyOf(reading) {
20
+ return `${reading.host}|${reading.mount}`;
21
+ }
22
+ /** The level. **Pure function.** */
23
+ static levelOf(usedPct) {
24
+ return usedPct >= DyNTS_DiskSpace_Util.CRITICAL_PCT
25
+ ? 'critical' : usedPct >= DyNTS_DiskSpace_Util.WARN_PCT ? 'warn' : null;
26
+ }
27
+ /** What goes out now, and the new state. **Pure function.** */
28
+ static decide(params) {
29
+ const state = { ...params.state };
30
+ const alerts = [];
31
+ for (const reading of params.readings) {
32
+ const key = DyNTS_DiskSpace_Util.keyOf(reading);
33
+ const level = DyNTS_DiskSpace_Util.levelOf(reading.usedPct);
34
+ const previous = state[key];
35
+ if (!level) {
36
+ if (reading.usedPct < DyNTS_DiskSpace_Util.CLEAR_PCT)
37
+ delete state[key];
38
+ continue;
39
+ }
40
+ // under DND only the critical one — the warning is NOT stored, so it goes out after the DND
41
+ if (params.dnd && level === 'warn')
42
+ continue;
43
+ const escalated = previous?.level === 'warn' && level === 'critical';
44
+ const due = !previous || escalated
45
+ || params.now.getTime() - Date.parse(previous.at) >= DyNTS_DiskSpace_Util.REPEAT_MS;
46
+ if (!due)
47
+ continue;
48
+ alerts.push({ ...reading, level: level });
49
+ state[key] = { level: level, at: params.now.toISOString() };
50
+ }
51
+ return { alerts: alerts, state: state };
52
+ }
53
+ /** The message. **Pure function.** */
54
+ static message(alerts) {
55
+ const critical = alerts.some((alert) => alert.level === 'critical');
56
+ const lines = alerts.map((alert) => `${alert.level === 'critical' ? '🔴' : '🟠'} ${alert.host} ${alert.mount} ${Math.round(alert.usedPct)}% full, `
57
+ + `${Math.round(alert.freeGb)} GB free`);
58
+ return [`${critical ? '[urgent]' : '[serious]'} 💾 Drive filling up:`, ...lines].join('\n');
59
+ }
60
+ /**
61
+ * The machine's drives from the Windows CIM list (`Win32_LogicalDisk`: `DeviceID`, `DriveType`, `ProviderName`,
62
+ * `Size`, `FreeSpace`). **Pure function.**
63
+ *
64
+ * @description A local disk (3) under the machine's name; a NETWORK drive (4) under ITS OWN server's name (e.g.
65
+ * `\\SERVER\share` ⇒ `SERVER`) — and it is skipped when that server's disks are measured directly
66
+ * (`skipServers`), otherwise the same disk would alert twice. A zero size ⇒ skipped.
67
+ */
68
+ static parseCim(params) {
69
+ const rows = Array.isArray(params.cim) ? params.cim : params.cim ? [params.cim] : [];
70
+ const skip = new Set(params.skipServers.map((server) => server.toUpperCase()));
71
+ return rows.flatMap((row) => {
72
+ const field = (key) => Reflect.get(Object(row), key);
73
+ const size = Number(field('Size'));
74
+ const free = Number(field('FreeSpace'));
75
+ const mount = String(field('DeviceID') ?? '');
76
+ const type = Number(field('DriveType'));
77
+ if (!mount || !Number.isFinite(size) || size <= 0 || !Number.isFinite(free) || (type !== 3 && type !== 4)) {
78
+ return [];
79
+ }
80
+ const server = type === 4
81
+ ? (/^\\\\([^\\]+)\\/u.exec(String(field('ProviderName') ?? ''))?.[1] ?? '').toUpperCase() : '';
82
+ if (type === 4 && (!server || skip.has(server)))
83
+ return [];
84
+ return [{ host: server || params.host, mount: mount, usedPct: 100 - (100 * free) / size, freeGb: free / 1e9 }];
85
+ });
86
+ }
87
+ /**
88
+ * A disk list in the `{ disks: [{ mount, freeGb, usedPct }] }` shape (e.g. a remote host's diagnostics JSON) under
89
+ * the given host name. **Pure function.**
90
+ */
91
+ static parseDiskList(host, diag) {
92
+ const disks = Reflect.get(Object(diag), 'disks');
93
+ return (Array.isArray(disks) ? disks : []).flatMap((disk) => {
94
+ const mount = String(Reflect.get(Object(disk), 'mount') ?? '').replace(/\\$/u, '');
95
+ const usedPct = Number(Reflect.get(Object(disk), 'usedPct'));
96
+ const freeGb = Number(Reflect.get(Object(disk), 'freeGb'));
97
+ return mount && Number.isFinite(usedPct)
98
+ ? [{ host: host, mount: mount, usedPct: usedPct, freeGb: Number.isFinite(freeGb) ? freeGb : 0 }] : [];
99
+ });
100
+ }
101
+ }
102
+ exports.DyNTS_DiskSpace_Util = DyNTS_DiskSpace_Util;
103
+ //# sourceMappingURL=disk-space.util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"disk-space.util.js","sourceRoot":"","sources":["../../../src/_modules/machine-monitor/disk-space.util.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ export { DyNTS_MachineDiskState_Interface, DyNTS_MachineGpuTemp_Interface, DyNTS_MachineProcessMemory_Interface, DyNTS_MachineStateRow_Interface, } from './_models/machine-state-row.interface';
2
+ export { DyNTS_MachineStateSummary_Interface } from './_models/machine-state-summary.interface';
3
+ export { DyNTS_MachineStateRecorderDeps_Interface } from './_models/machine-state-recorder-deps.interface';
4
+ export { DyNTS_MachineState_Util } from './machine-state.util';
5
+ export { DyNTS_MachineStateWindow_Util } from './machine-state-window.util';
6
+ export { DyNTS_MachineState_Recorder } from './machine-state.recorder';
7
+ export { DyNTS_MachineStateWindowsRunners_Util } from './machine-state-windows-runners.util';
8
+ export { DyNTS_DiskAlert_Interface, DyNTS_DiskAlertState, DyNTS_DiskReading_Interface, DyNTS_DiskSpaceRunnerDeps_Interface, } from './_models/disk-space.interface';
9
+ export { DyNTS_DiskSpace_Util } from './disk-space.util';
10
+ export { DyNTS_DiskSpace_Runner } from './disk-space.runner';
11
+ export { DyNTS_DiskSpaceWindowsReader_Util } from './disk-space-windows-reader.util';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/_modules/machine-monitor/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gCAAgC,EAChC,8BAA8B,EAC9B,oCAAoC,EACpC,+BAA+B,GAChC,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,mCAAmC,EAAE,MAAM,2CAA2C,CAAC;AAChG,OAAO,EAAE,wCAAwC,EAAE,MAAM,iDAAiD,CAAC;AAC3G,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,EAAE,qCAAqC,EAAE,MAAM,sCAAsC,CAAC;AAC7F,OAAO,EACL,yBAAyB,EACzB,oBAAoB,EACpB,2BAA2B,EAC3B,mCAAmC,GACpC,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,iCAAiC,EAAE,MAAM,kCAAkC,CAAC"}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DyNTS_DiskSpaceWindowsReader_Util = exports.DyNTS_DiskSpace_Runner = exports.DyNTS_DiskSpace_Util = exports.DyNTS_MachineStateWindowsRunners_Util = exports.DyNTS_MachineState_Recorder = exports.DyNTS_MachineStateWindow_Util = exports.DyNTS_MachineState_Util = void 0;
4
+ var machine_state_util_1 = require("./machine-state.util");
5
+ Object.defineProperty(exports, "DyNTS_MachineState_Util", { enumerable: true, get: function () { return machine_state_util_1.DyNTS_MachineState_Util; } });
6
+ var machine_state_window_util_1 = require("./machine-state-window.util");
7
+ Object.defineProperty(exports, "DyNTS_MachineStateWindow_Util", { enumerable: true, get: function () { return machine_state_window_util_1.DyNTS_MachineStateWindow_Util; } });
8
+ var machine_state_recorder_1 = require("./machine-state.recorder");
9
+ Object.defineProperty(exports, "DyNTS_MachineState_Recorder", { enumerable: true, get: function () { return machine_state_recorder_1.DyNTS_MachineState_Recorder; } });
10
+ var machine_state_windows_runners_util_1 = require("./machine-state-windows-runners.util");
11
+ Object.defineProperty(exports, "DyNTS_MachineStateWindowsRunners_Util", { enumerable: true, get: function () { return machine_state_windows_runners_util_1.DyNTS_MachineStateWindowsRunners_Util; } });
12
+ var disk_space_util_1 = require("./disk-space.util");
13
+ Object.defineProperty(exports, "DyNTS_DiskSpace_Util", { enumerable: true, get: function () { return disk_space_util_1.DyNTS_DiskSpace_Util; } });
14
+ var disk_space_runner_1 = require("./disk-space.runner");
15
+ Object.defineProperty(exports, "DyNTS_DiskSpace_Runner", { enumerable: true, get: function () { return disk_space_runner_1.DyNTS_DiskSpace_Runner; } });
16
+ var disk_space_windows_reader_util_1 = require("./disk-space-windows-reader.util");
17
+ Object.defineProperty(exports, "DyNTS_DiskSpaceWindowsReader_Util", { enumerable: true, get: function () { return disk_space_windows_reader_util_1.DyNTS_DiskSpaceWindowsReader_Util; } });
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/_modules/machine-monitor/index.ts"],"names":[],"mappings":";;;AAQA,2DAA+D;AAAtD,6HAAA,uBAAuB,OAAA;AAChC,yEAA4E;AAAnE,0IAAA,6BAA6B,OAAA;AACtC,mEAAuE;AAA9D,qIAAA,2BAA2B,OAAA;AACpC,2FAA6F;AAApF,2JAAA,qCAAqC,OAAA;AAO9C,qDAAyD;AAAhD,uHAAA,oBAAoB,OAAA;AAC7B,yDAA6D;AAApD,2HAAA,sBAAsB,OAAA;AAC/B,mFAAqF;AAA5E,mJAAA,iCAAiC,OAAA"}
@@ -0,0 +1,18 @@
1
+ import { DyNTS_MachineStateRow_Interface } from './_models/machine-state-row.interface';
2
+ import { DyNTS_MachineStateSummary_Interface } from './_models/machine-state-summary.interface';
3
+ /**
4
+ * BFR-FLEET-033 — the helpers of a time window of the machine-state log (e.g. ±2 minutes around a CPU spike).
5
+ *
6
+ * @description Transplanted from My Assistant (`MachineStateWindow_Util`), the logic unchanged.
7
+ */
8
+ export declare class DyNTS_MachineStateWindow_Util {
9
+ /** The rows of a daily JSONL inside `[fromMs, toMs]` (a broken / NUL row is skipped). **Pure function.** */
10
+ static rowsBetween(jsonl: string, fromMs: number, toMs: number): DyNTS_MachineStateRow_Interface[];
11
+ /** The summary of the window; empty ⇒ `null`. **Pure function.** */
12
+ static summarize(rows: readonly DyNTS_MachineStateRow_Interface[]): DyNTS_MachineStateSummary_Interface | null;
13
+ /** The largest value; empty ⇒ `null`. **Pure function.** */
14
+ static max(values: readonly number[]): number | null;
15
+ /** One report line of the summary. **Pure function.** */
16
+ static line(summary: DyNTS_MachineStateSummary_Interface | null | undefined): string;
17
+ }
18
+ //# sourceMappingURL=machine-state-window.util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"machine-state-window.util.d.ts","sourceRoot":"","sources":["../../../src/_modules/machine-monitor/machine-state-window.util.ts"],"names":[],"mappings":"AAAA,OAAO,EACmE,+BAA+B,EACxG,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,mCAAmC,EAAE,MAAM,2CAA2C,CAAC;AAEhG;;;;GAIG;AACH,qBAAa,6BAA6B;IAExC,4GAA4G;IAC5G,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,+BAA+B,EAAE;IAmBlG,oEAAoE;IACpE,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,+BAA+B,EAAE,GAAG,mCAAmC,GAAG,IAAI;IAyB9G,4DAA4D;IAC5D,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI;IAIpD,yDAAyD;IACzD,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,mCAAmC,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM;CAYrF"}
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DyNTS_MachineStateWindow_Util = void 0;
4
+ /**
5
+ * BFR-FLEET-033 — the helpers of a time window of the machine-state log (e.g. ±2 minutes around a CPU spike).
6
+ *
7
+ * @description Transplanted from My Assistant (`MachineStateWindow_Util`), the logic unchanged.
8
+ */
9
+ class DyNTS_MachineStateWindow_Util {
10
+ /** The rows of a daily JSONL inside `[fromMs, toMs]` (a broken / NUL row is skipped). **Pure function.** */
11
+ static rowsBetween(jsonl, fromMs, toMs) {
12
+ const out = [];
13
+ for (const line of jsonl.split(/\r?\n/u)) {
14
+ if (!line.startsWith('{'))
15
+ continue;
16
+ try {
17
+ const row = JSON.parse(line);
18
+ const at = Date.parse(row.ts);
19
+ if (at >= fromMs && at <= toMs)
20
+ out.push(row);
21
+ }
22
+ catch {
23
+ continue;
24
+ }
25
+ }
26
+ return out;
27
+ }
28
+ /** The summary of the window; empty ⇒ `null`. **Pure function.** */
29
+ static summarize(rows) {
30
+ if (!rows.length)
31
+ return null;
32
+ const nums = (pick) => rows.map(pick).filter((value) => value !== null);
33
+ const available = nums((row) => row.availableMb);
34
+ const low = [...rows].sort((a, b) => (a.availableMb ?? Infinity) - (b.availableMb ?? Infinity))[0];
35
+ const disks = rows.flatMap((row) => row.disks);
36
+ const worstDisk = [...disks]
37
+ .sort((a, b) => (b.queue ?? 0) - (a.queue ?? 0) || (b.latencyMs ?? 0) - (a.latencyMs ?? 0))[0] ?? null;
38
+ return {
39
+ rows: rows.length,
40
+ minAvailableMb: available.length ? Math.min(...available) : null,
41
+ maxCommitPct: DyNTS_MachineStateWindow_Util.max(nums((row) => row.commitPct)),
42
+ maxPagefilePct: DyNTS_MachineStateWindow_Util.max(nums((row) => row.pagefilePct)),
43
+ maxGpuTempC: DyNTS_MachineStateWindow_Util.max(rows
44
+ .flatMap((row) => (row.gpus ?? []).map((gpu) => gpu.tempC))
45
+ .filter((value) => value !== null)),
46
+ worstDisk: worstDisk,
47
+ topAtLow: low?.top ?? [],
48
+ };
49
+ }
50
+ /** The largest value; empty ⇒ `null`. **Pure function.** */
51
+ static max(values) {
52
+ return values.length ? Math.max(...values) : null;
53
+ }
54
+ /** One report line of the summary. **Pure function.** */
55
+ static line(summary) {
56
+ if (!summary)
57
+ return '- Machine state (±2 min): no data (the per-minute log wrote no row for this window)';
58
+ const disk = summary.worstDisk;
59
+ return `- Machine state (±2 min, ${summary.rows} samples): least free memory ${summary.minAvailableMb ?? '?'} MB, `
60
+ + `commit max ${summary.maxCommitPct ?? '?'}%, page file max ${summary.maxPagefilePct ?? '?'}%, `
61
+ + `graphics card max ${summary.maxGpuTempC ?? '?'} °C, `
62
+ + `largest disk queue ${disk ? `${disk.disk}: queue ${disk.queue ?? '?'}, ${disk.latencyMs ?? '?'} ms` : '?'}; `
63
+ + `top memory: ${summary.topAtLow
64
+ .map((p) => `${p.name} ${p.memMb} MB`).join(', ') || '?'}`;
65
+ }
66
+ }
67
+ exports.DyNTS_MachineStateWindow_Util = DyNTS_MachineStateWindow_Util;
68
+ //# sourceMappingURL=machine-state-window.util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"machine-state-window.util.js","sourceRoot":"","sources":["../../../src/_modules/machine-monitor/machine-state-window.util.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { DyNTS_MachineStateRecorderDeps_Interface } from './_models/machine-state-recorder-deps.interface';
2
+ /**
3
+ * BFR-FLEET-033 — the default Windows readers of the machine-state recorder: `typeperf`, `tasklist` and `nvidia-smi`,
4
+ * as asynchronous child processes (the event loop never stands), hidden windows, with a timeout each.
5
+ *
6
+ * @description Transplanted from My Assistant's wiring (the same commands and timeouts). ⛔ Windows only; a Linux host
7
+ * needs its own readers (a later step). Without an NVIDIA card `nvidia-smi` fails — the recorder then logs the read
8
+ * error once and keeps writing rows.
9
+ */
10
+ export declare class DyNTS_MachineStateWindowsRunners_Util {
11
+ /** The three readers, to spread into the recorder's dependencies. */
12
+ static runners(): Pick<DyNTS_MachineStateRecorderDeps_Interface, 'runTypeperf' | 'runTasklist' | 'runGpuTemps'>;
13
+ }
14
+ //# sourceMappingURL=machine-state-windows-runners.util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"machine-state-windows-runners.util.d.ts","sourceRoot":"","sources":["../../../src/_modules/machine-monitor/machine-state-windows-runners.util.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,wCAAwC,EAAE,MAAM,iDAAiD,CAAC;AAI3G;;;;;;;GAOG;AACH,qBAAa,qCAAqC;IAEhD,qEAAqE;IACrE,MAAM,CAAC,OAAO,IAAI,IAAI,CAAC,wCAAwC,EAAE,aAAa,GAAG,aAAa,GAAG,aAAa,CAAC;CAahH"}
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DyNTS_MachineStateWindowsRunners_Util = void 0;
4
+ const child_process_1 = require("child_process");
5
+ const util_1 = require("util");
6
+ const execFileAsync = (0, util_1.promisify)(child_process_1.execFile);
7
+ /**
8
+ * BFR-FLEET-033 — the default Windows readers of the machine-state recorder: `typeperf`, `tasklist` and `nvidia-smi`,
9
+ * as asynchronous child processes (the event loop never stands), hidden windows, with a timeout each.
10
+ *
11
+ * @description Transplanted from My Assistant's wiring (the same commands and timeouts). ⛔ Windows only; a Linux host
12
+ * needs its own readers (a later step). Without an NVIDIA card `nvidia-smi` fails — the recorder then logs the read
13
+ * error once and keeps writing rows.
14
+ */
15
+ class DyNTS_MachineStateWindowsRunners_Util {
16
+ /** The three readers, to spread into the recorder's dependencies. */
17
+ static runners() {
18
+ return {
19
+ runTypeperf: async (counters) => (await execFileAsync('typeperf', [...counters, '-sc', '1'], { windowsHide: true, timeout: 30_000 })).stdout,
20
+ runTasklist: async () => (await execFileAsync('tasklist', ['/fo', 'csv', '/nh'], { windowsHide: true, timeout: 30_000 })).stdout,
21
+ runGpuTemps: async () => (await execFileAsync('nvidia-smi', ['--query-gpu=name,temperature.gpu', '--format=csv,noheader,nounits'], { windowsHide: true, timeout: 10_000 })).stdout,
22
+ };
23
+ }
24
+ }
25
+ exports.DyNTS_MachineStateWindowsRunners_Util = DyNTS_MachineStateWindowsRunners_Util;
26
+ //# sourceMappingURL=machine-state-windows-runners.util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"machine-state-windows-runners.util.js","sourceRoot":"","sources":["../../../src/_modules/machine-monitor/machine-state-windows-runners.util.ts"],"names":[],"mappings":";;;AAAA,iDAAyC;AACzC,+BAAiC;AAIjC,MAAM,aAAa,GAAG,IAAA,gBAAS,EAAC,wBAAQ,CAAC,CAAC;AAE1C;;;;;;;GAOG;AACH,MAAa,qCAAqC;IAEhD,qEAAqE;IACrE,MAAM,CAAC,OAAO;QACZ,OAAO;YACL,WAAW,EAAE,KAAK,EAAE,QAA2B,EAAmB,EAAE,CAClE,CAAC,MAAM,aAAa,CAAC,UAAU,EAAE,CAAE,GAAG,QAAQ,EAAE,KAAK,EAAE,GAAG,CAAE,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM;YAC/G,WAAW,EAAE,KAAK,IAAqB,EAAE,CACvC,CAAC,MAAM,aAAa,CAAC,UAAU,EAAE,CAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAE,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM;YAC3G,WAAW,EAAE,KAAK,IAAqB,EAAE,CAAC,CAAC,MAAM,aAAa,CAC5D,YAAY,EACZ,CAAE,kCAAkC,EAAE,+BAA+B,CAAE,EACvE,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CACvC,CAAC,CAAC,MAAM;SACV,CAAC;IACJ,CAAC;CACF;AAhBD,sFAgBC"}
@@ -0,0 +1,46 @@
1
+ import { DyNTS_MachineStateRow_Interface } from './_models/machine-state-row.interface';
2
+ import { DyNTS_MachineStateRecorderDeps_Interface } from './_models/machine-state-recorder-deps.interface';
3
+ /**
4
+ * BFR-FLEET-033 — the per-minute machine-state recorder: one JSONL row per minute into the daily file, with a 7-day
5
+ * retention. ⛔ It never throws.
6
+ *
7
+ * @description Transplanted from My Assistant (`MachineStateRecorder`), the logic unchanged. Run it on the app's own
8
+ * tick (e.g. a watcher loop): `tick()` returns early inside the minute, and the child processes are asynchronous, so
9
+ * the event loop never stands. The error is coded (`<prefix>-MACHINE-STATE-FAILED`), never silent — but the same
10
+ * error is logged only once, not every minute.
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const recorder = new DyNTS_MachineState_Recorder({
15
+ * dir: DyNTS_MachineState_Util.resolveDir('my-app'),
16
+ * ...DyNTS_MachineStateWindowsRunners_Util.runners(),
17
+ * log: (code, detail) => DyFM_Log.warn(code, detail),
18
+ * });
19
+ * setInterval(() => void recorder.tick(), 15_000);
20
+ * ```
21
+ */
22
+ export declare class DyNTS_MachineState_Recorder {
23
+ static readonly EVERY_MS: number;
24
+ /** 🌡️ At least this much time between two heat alerts. */
25
+ static readonly HEAT_ALERT_EVERY_MS: number;
26
+ private lastRunAt;
27
+ private lastPrunedDay;
28
+ private lastError;
29
+ private isRunning;
30
+ /** 🌡️ The time of the last heat alert (at most one per 30 minutes). */
31
+ private lastHeatAlertAt;
32
+ private lastGpuError;
33
+ private readonly deps;
34
+ constructor(deps: DyNTS_MachineStateRecorderDeps_Interface);
35
+ /** The code with the configured prefix. */
36
+ private code;
37
+ /** One measurement, if a minute passed since the last; the written row, or `null`. */
38
+ tick(now?: Date): Promise<DyNTS_MachineStateRow_Interface | null>;
39
+ /** 🌡️ The graphics-card temperature; error ⇒ `null` (the row goes on; the same error is logged once). */
40
+ private readGpus;
41
+ /** 🌡️ Above the threshold: an alert + an error log, at most once per 30 minutes. */
42
+ private alertIfHot;
43
+ /** The files past the retention are removed, once a day. */
44
+ private pruneOncePerDay;
45
+ }
46
+ //# sourceMappingURL=machine-state.recorder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"machine-state.recorder.d.ts","sourceRoot":"","sources":["../../../src/_modules/machine-monitor/machine-state.recorder.ts"],"names":[],"mappings":"AAGA,OAAO,EAC2B,+BAA+B,EAChE,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,wCAAwC,EAAE,MAAM,iDAAiD,CAAC;AAG3G;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,2BAA2B;IAEtC,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAU;IAE1C,2DAA2D;IAC3D,MAAM,CAAC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAe;IAE1D,OAAO,CAAC,SAAS,CAAoC;IACrD,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,SAAS,CAAkB;IACnC,wEAAwE;IACxE,OAAO,CAAC,eAAe,CAAoC;IAC3D,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA2C;gBAEpD,IAAI,EAAE,wCAAwC;IAI1D,2CAA2C;IAC3C,OAAO,CAAC,IAAI;IAIZ,sFAAsF;IAChF,IAAI,CAAC,GAAG,GAAE,IAAiB,GAAG,OAAO,CAAC,+BAA+B,GAAG,IAAI,CAAC;IAyCnF,0GAA0G;YAC5F,QAAQ;IAoBtB,qFAAqF;YACvE,UAAU;IAexB,4DAA4D;YAC9C,eAAe;CAU9B"}
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DyNTS_MachineState_Recorder = void 0;
4
+ const promises_1 = require("fs/promises");
5
+ const path_1 = require("path");
6
+ const machine_state_util_1 = require("./machine-state.util");
7
+ /**
8
+ * BFR-FLEET-033 — the per-minute machine-state recorder: one JSONL row per minute into the daily file, with a 7-day
9
+ * retention. ⛔ It never throws.
10
+ *
11
+ * @description Transplanted from My Assistant (`MachineStateRecorder`), the logic unchanged. Run it on the app's own
12
+ * tick (e.g. a watcher loop): `tick()` returns early inside the minute, and the child processes are asynchronous, so
13
+ * the event loop never stands. The error is coded (`<prefix>-MACHINE-STATE-FAILED`), never silent — but the same
14
+ * error is logged only once, not every minute.
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * const recorder = new DyNTS_MachineState_Recorder({
19
+ * dir: DyNTS_MachineState_Util.resolveDir('my-app'),
20
+ * ...DyNTS_MachineStateWindowsRunners_Util.runners(),
21
+ * log: (code, detail) => DyFM_Log.warn(code, detail),
22
+ * });
23
+ * setInterval(() => void recorder.tick(), 15_000);
24
+ * ```
25
+ */
26
+ class DyNTS_MachineState_Recorder {
27
+ static EVERY_MS = 60_000;
28
+ /** 🌡️ At least this much time between two heat alerts. */
29
+ static HEAT_ALERT_EVERY_MS = 30 * 60_000;
30
+ lastRunAt = Number.NEGATIVE_INFINITY;
31
+ lastPrunedDay = null;
32
+ lastError = null;
33
+ isRunning = false;
34
+ /** 🌡️ The time of the last heat alert (at most one per 30 minutes). */
35
+ lastHeatAlertAt = Number.NEGATIVE_INFINITY;
36
+ lastGpuError = null;
37
+ deps;
38
+ constructor(deps) {
39
+ this.deps = deps;
40
+ }
41
+ /** The code with the configured prefix. */
42
+ code(suffix) {
43
+ return `${this.deps.codePrefix ?? 'DyNTS-MM'}-${suffix}`;
44
+ }
45
+ /** One measurement, if a minute passed since the last; the written row, or `null`. */
46
+ async tick(now = new Date()) {
47
+ if (this.isRunning || now.getTime() - this.lastRunAt < DyNTS_MachineState_Recorder.EVERY_MS - 1_000)
48
+ return null;
49
+ this.isRunning = true;
50
+ this.lastRunAt = now.getTime();
51
+ try {
52
+ const [perf, tasks, gpus] = await Promise.all([
53
+ this.deps.runTypeperf(machine_state_util_1.DyNTS_MachineState_Util.COUNTERS), this.deps.runTasklist(), this.readGpus(),
54
+ ]);
55
+ const row = {
56
+ ts: now.toISOString(),
57
+ ...machine_state_util_1.DyNTS_MachineState_Util.parseTypeperf(perf),
58
+ top: machine_state_util_1.DyNTS_MachineState_Util.topByMemory(tasks),
59
+ ...(gpus ? { gpus: gpus } : {}),
60
+ };
61
+ if (row.availableMb === null && !row.disks.length) {
62
+ throw new Error('the typeperf output is not readable (neither memory nor disk)');
63
+ }
64
+ await (0, promises_1.mkdir)(this.deps.dir, { recursive: true });
65
+ await (0, promises_1.appendFile)((0, path_1.join)(this.deps.dir, `${machine_state_util_1.DyNTS_MachineState_Util.dayOf(now)}.jsonl`), `${JSON.stringify(row)}\n`, 'utf-8');
66
+ await this.pruneOncePerDay(now);
67
+ await this.alertIfHot(row, now);
68
+ this.lastError = null;
69
+ return row;
70
+ }
71
+ catch (err) {
72
+ const detail = err instanceof Error ? err.message : String(err);
73
+ if (detail !== this.lastError)
74
+ this.deps.log(this.code('MACHINE-STATE-FAILED'), detail, true);
75
+ this.lastError = detail;
76
+ return null;
77
+ }
78
+ finally {
79
+ this.isRunning = false;
80
+ }
81
+ }
82
+ /** 🌡️ The graphics-card temperature; error ⇒ `null` (the row goes on; the same error is logged once). */
83
+ async readGpus() {
84
+ if (!this.deps.runGpuTemps)
85
+ return null;
86
+ try {
87
+ const gpus = machine_state_util_1.DyNTS_MachineState_Util.parseGpuTemps(await this.deps.runGpuTemps());
88
+ this.lastGpuError = null;
89
+ return gpus;
90
+ }
91
+ catch (err) {
92
+ const detail = err instanceof Error ? err.message : String(err);
93
+ if (detail !== this.lastGpuError)
94
+ this.deps.log(this.code('MACHINE-TEMP-READ-FAILED'), detail, true);
95
+ this.lastGpuError = detail;
96
+ return null;
97
+ }
98
+ }
99
+ /** 🌡️ Above the threshold: an alert + an error log, at most once per 30 minutes. */
100
+ async alertIfHot(row, now) {
101
+ const hot = (row.gpus ?? [])
102
+ .filter((gpu) => gpu.tempC !== null && gpu.tempC >= machine_state_util_1.DyNTS_MachineState_Util.GPU_TEMP_HIGH_C);
103
+ if (!hot.length || now.getTime() - this.lastHeatAlertAt < DyNTS_MachineState_Recorder.HEAT_ALERT_EVERY_MS)
104
+ return;
105
+ this.lastHeatAlertAt = now.getTime();
106
+ const text = `🌡️ MACHINE TEMPERATURE: ${hot.map((gpu) => `${gpu.name} ${gpu.tempC} °C`).join(', ')} `
107
+ + `(threshold ${machine_state_util_1.DyNTS_MachineState_Util.GPU_TEMP_HIGH_C} °C)`;
108
+ this.deps.log(this.code('MACHINE-TEMP-HIGH'), text, true);
109
+ await this.deps.alert?.(text).catch((err) => this.deps.log(this.code('MACHINE-TEMP-ALERT-FAILED'), err instanceof Error ? err.message : String(err), true));
110
+ }
111
+ /** The files past the retention are removed, once a day. */
112
+ async pruneOncePerDay(now) {
113
+ const day = machine_state_util_1.DyNTS_MachineState_Util.dayOf(now);
114
+ if (this.lastPrunedDay === day)
115
+ return;
116
+ this.lastPrunedDay = day;
117
+ for (const name of machine_state_util_1.DyNTS_MachineState_Util.expired(await (0, promises_1.readdir)(this.deps.dir), now)) {
118
+ await (0, promises_1.rm)((0, path_1.join)(this.deps.dir, name), { force: true });
119
+ }
120
+ }
121
+ }
122
+ exports.DyNTS_MachineState_Recorder = DyNTS_MachineState_Recorder;
123
+ //# sourceMappingURL=machine-state.recorder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"machine-state.recorder.js","sourceRoot":"","sources":["../../../src/_modules/machine-monitor/machine-state.recorder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import { DyNTS_MachineGpuTemp_Interface, DyNTS_MachineProcessMemory_Interface, DyNTS_MachineStateRow_Interface } from './_models/machine-state-row.interface';
2
+ /**
3
+ * BFR-FLEET-033 — the pure helpers of the per-minute machine-state log (Windows): memory, commit, page file, per-disk
4
+ * queue, the top processes by memory and the graphics-card temperature.
5
+ *
6
+ * @description Transplanted from My Assistant (`cli/src/diagnostics/machine-state.ts`), the logic unchanged. Measured
7
+ * there: `typeperf -sc 1` with the English counter names takes ~1.5 s wall time at negligible CPU, `tasklist /fo csv
8
+ * /nh` ~0.8 s (⛔ WMI — it is avoided under load).
9
+ */
10
+ export declare class DyNTS_MachineState_Util {
11
+ /** The `typeperf` counters (English names). */
12
+ static readonly COUNTERS: readonly string[];
13
+ /** The retention (days). */
14
+ static readonly KEEP_DAYS: number;
15
+ /** The time zone of the daily file names. */
16
+ static readonly TIME_ZONE: string;
17
+ /**
18
+ * 🌡️ An alert above this temperature (°C).
19
+ *
20
+ * @description ⚠️ Without elevated rights the CPU and disk temperatures are NOT readable (ACPI: not supported,
21
+ * performance counter: error, disk: access denied) ⇒ those need an administrator sensor — a separate step.
22
+ */
23
+ static readonly GPU_TEMP_HIGH_C: number;
24
+ /** The output of `nvidia-smi --query-gpu=name,temperature.gpu --format=csv,noheader,nounits`. **Pure function.** */
25
+ static parseGpuTemps(output: string): DyNTS_MachineGpuTemp_Interface[];
26
+ /**
27
+ * The folder of the daily files under the user's config folder.
28
+ *
29
+ * @param appFolder the app's own folder under `~/.config` (e.g. `my-app`)
30
+ * @param userHome the home folder (default: the current user's)
31
+ */
32
+ static resolveDir(appFolder: string, userHome?: string): string;
33
+ /** The fields of one CSV line (the quoted form of `typeperf` / `tasklist`). **Pure function.** */
34
+ static csvFields(line: string): string[];
35
+ /** The output of `typeperf -sc 1` ⇒ the memory and disk part of the row. **Pure function.** */
36
+ static parseTypeperf(output: string): Omit<DyNTS_MachineStateRow_Interface, 'ts' | 'top'>;
37
+ /** The output of `tasklist /fo csv /nh` ⇒ the `count` processes using the most memory. **Pure function.** */
38
+ static topByMemory(output: string, count?: number): DyNTS_MachineProcessMemory_Interface[];
39
+ /** The name of the daily file (the day in `TIME_ZONE`). **Pure function.** */
40
+ static dayOf(now: Date): string;
41
+ /** The daily files past the retention. **Pure function.** */
42
+ static expired(names: readonly string[], now: Date, keepDays?: number): string[];
43
+ }
44
+ //# sourceMappingURL=machine-state.util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"machine-state.util.d.ts","sourceRoot":"","sources":["../../../src/_modules/machine-monitor/machine-state.util.ts"],"names":[],"mappings":"AAGA,OAAO,EAC6B,8BAA8B,EAAE,oCAAoC,EACtG,+BAA+B,EAChC,MAAM,uCAAuC,CAAC;AAE/C;;;;;;;GAOG;AACH,qBAAa,uBAAuB;IAElC,+CAA+C;IAC/C,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAOzC;IAEF,4BAA4B;IAC5B,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAK;IAEtC,6CAA6C;IAC7C,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAqB;IAEtD;;;;;OAKG;IACH,MAAM,CAAC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAM;IAE7C,oHAAoH;IACpH,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,8BAA8B,EAAE;IAatE;;;;;OAKG;IACH,MAAM,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAkB,GAAG,MAAM;IAI1E,kGAAkG;IAClG,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE;IAKxC,+FAA+F;IAC/F,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,+BAA+B,EAAE,IAAI,GAAG,KAAK,CAAC;IA0CzF,6GAA6G;IAC7G,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,GAAE,MAAU,GAAG,oCAAoC,EAAE;IAiB7F,8EAA8E;IAC9E,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,GAAG,MAAM;IAI/B,6DAA6D;IAC7D,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,GAAE,MAA0C,GAAG,MAAM,EAAE;CAMpH"}
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DyNTS_MachineState_Util = void 0;
4
+ const os_1 = require("os");
5
+ const path_1 = require("path");
6
+ /**
7
+ * BFR-FLEET-033 — the pure helpers of the per-minute machine-state log (Windows): memory, commit, page file, per-disk
8
+ * queue, the top processes by memory and the graphics-card temperature.
9
+ *
10
+ * @description Transplanted from My Assistant (`cli/src/diagnostics/machine-state.ts`), the logic unchanged. Measured
11
+ * there: `typeperf -sc 1` with the English counter names takes ~1.5 s wall time at negligible CPU, `tasklist /fo csv
12
+ * /nh` ~0.8 s (⛔ WMI — it is avoided under load).
13
+ */
14
+ class DyNTS_MachineState_Util {
15
+ /** The `typeperf` counters (English names). */
16
+ static COUNTERS = [
17
+ '\\Memory\\Available MBytes',
18
+ '\\Memory\\Committed Bytes',
19
+ '\\Memory\\Commit Limit',
20
+ '\\Paging File(_Total)\\% Usage',
21
+ '\\PhysicalDisk(*)\\Avg. Disk Queue Length',
22
+ '\\PhysicalDisk(*)\\Avg. Disk sec/Transfer',
23
+ ];
24
+ /** The retention (days). */
25
+ static KEEP_DAYS = 7;
26
+ /** The time zone of the daily file names. */
27
+ static TIME_ZONE = 'Europe/Budapest';
28
+ /**
29
+ * 🌡️ An alert above this temperature (°C).
30
+ *
31
+ * @description ⚠️ Without elevated rights the CPU and disk temperatures are NOT readable (ACPI: not supported,
32
+ * performance counter: error, disk: access denied) ⇒ those need an administrator sensor — a separate step.
33
+ */
34
+ static GPU_TEMP_HIGH_C = 85;
35
+ /** The output of `nvidia-smi --query-gpu=name,temperature.gpu --format=csv,noheader,nounits`. **Pure function.** */
36
+ static parseGpuTemps(output) {
37
+ return output.split(/\r?\n/u).flatMap((line) => {
38
+ const at = line.lastIndexOf(',');
39
+ if (at < 0)
40
+ return [];
41
+ const name = line.slice(0, at).trim();
42
+ const value = Number(line.slice(at + 1).trim());
43
+ return name ? [{ name: name, tempC: Number.isFinite(value) ? value : null }] : [];
44
+ });
45
+ }
46
+ /**
47
+ * The folder of the daily files under the user's config folder.
48
+ *
49
+ * @param appFolder the app's own folder under `~/.config` (e.g. `my-app`)
50
+ * @param userHome the home folder (default: the current user's)
51
+ */
52
+ static resolveDir(appFolder, userHome = (0, os_1.homedir)()) {
53
+ return (0, path_1.join)(userHome, '.config', appFolder, 'machine-state');
54
+ }
55
+ /** The fields of one CSV line (the quoted form of `typeperf` / `tasklist`). **Pure function.** */
56
+ static csvFields(line) {
57
+ return [...line.matchAll(/"((?:[^"]|"")*)"/gu)]
58
+ .map((match) => (match[1] ?? '').replace(/""/gu, '"'));
59
+ }
60
+ /** The output of `typeperf -sc 1` ⇒ the memory and disk part of the row. **Pure function.** */
61
+ static parseTypeperf(output) {
62
+ const lines = output.split(/\r?\n/u).filter((line) => line.startsWith('"'));
63
+ const header = DyNTS_MachineState_Util.csvFields(lines[0] ?? '');
64
+ const values = DyNTS_MachineState_Util.csvFields(lines[1] ?? '');
65
+ const num = (index) => {
66
+ const value = Number.parseFloat(values[index] ?? '');
67
+ return Number.isFinite(value) ? value : null;
68
+ };
69
+ const find = (suffix) => header.findIndex((name) => name.endsWith(suffix));
70
+ const commit = num(find('\\Memory\\Committed Bytes'));
71
+ const limit = num(find('\\Memory\\Commit Limit'));
72
+ const disks = new Map();
73
+ header.forEach((name, index) => {
74
+ const match = /\\PhysicalDisk\(([^)]+)\)\\(Avg\. Disk Queue Length|Avg\. Disk sec\/Transfer)$/u.exec(name);
75
+ if (!match || match[1] === '_Total')
76
+ return;
77
+ const disk = disks.get(match[1] ?? '') ?? { disk: match[1] ?? '', queue: null, latencyMs: null };
78
+ const value = num(index);
79
+ if (match[2] === 'Avg. Disk Queue Length')
80
+ disk.queue = value === null ? null : Math.round(value * 1000) / 1000;
81
+ else
82
+ disk.latencyMs = value === null ? null : Math.round(value * 1000 * 10) / 10;
83
+ disks.set(disk.disk, disk);
84
+ });
85
+ const gb = (bytes) => bytes === null ? null : Math.round(bytes / 1024 ** 3 * 10) / 10;
86
+ const pagefile = num(find('\\Paging File(_Total)\\% Usage'));
87
+ return {
88
+ availableMb: num(find('\\Memory\\Available MBytes')),
89
+ commitGb: gb(commit),
90
+ commitLimitGb: gb(limit),
91
+ commitPct: commit !== null && limit ? Math.round(commit / limit * 1000) / 10 : null,
92
+ pagefilePct: pagefile === null ? null : Math.round(pagefile * 10) / 10,
93
+ disks: [...disks.values()],
94
+ };
95
+ }
96
+ /** The output of `tasklist /fo csv /nh` ⇒ the `count` processes using the most memory. **Pure function.** */
97
+ static topByMemory(output, count = 5) {
98
+ const out = [];
99
+ for (const line of output.split(/\r?\n/u)) {
100
+ const [name, pid, , , mem] = DyNTS_MachineState_Util.csvFields(line);
101
+ const kb = Number.parseInt((mem ?? '').replace(/[^\d]/gu, ''), 10);
102
+ if (!name || !Number.isFinite(kb))
103
+ continue;
104
+ out.push({ name: name, pid: Number.parseInt(pid ?? '', 10) || 0, memMb: Math.round(kb / 1024) });
105
+ }
106
+ return out
107
+ .sort((a, b) => b.memMb - a.memMb)
108
+ .slice(0, count);
109
+ }
110
+ /** The name of the daily file (the day in `TIME_ZONE`). **Pure function.** */
111
+ static dayOf(now) {
112
+ return new Intl.DateTimeFormat('sv-SE', { timeZone: DyNTS_MachineState_Util.TIME_ZONE }).format(now);
113
+ }
114
+ /** The daily files past the retention. **Pure function.** */
115
+ static expired(names, now, keepDays = DyNTS_MachineState_Util.KEEP_DAYS) {
116
+ const cutoff = DyNTS_MachineState_Util.dayOf(new Date(now.getTime() - keepDays * 86_400_000));
117
+ return names.filter((name) => /^\d{4}-\d{2}-\d{2}\.jsonl$/u.test(name) && name.slice(0, 10) < cutoff);
118
+ }
119
+ }
120
+ exports.DyNTS_MachineState_Util = DyNTS_MachineState_Util;
121
+ //# sourceMappingURL=machine-state.util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"machine-state.util.js","sourceRoot":"","sources":["../../../src/_modules/machine-monitor/machine-state.util.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@futdevpro/nts-dynamo",
3
- "version": "01.15.437",
3
+ "version": "01.15.439",
4
4
  "description": "Dynamic NodeTS (NodeJS-Typescript), MongoDB Backend System Framework by Future Development Program Ltd.",
5
5
  "DyBu_settings": {
6
6
  "packageType": "server-package",
@@ -297,6 +297,12 @@
297
297
  "types": "./build/_modules/logs/index.d.ts",
298
298
  "typings": "./build/_modules/logs/index.d.ts"
299
299
  },
300
+ "./machine-monitor": {
301
+ "default": "./build/_modules/machine-monitor/index.js",
302
+ "module": "./build/_modules/machine-monitor/index.js",
303
+ "types": "./build/_modules/machine-monitor/index.d.ts",
304
+ "typings": "./build/_modules/machine-monitor/index.d.ts"
305
+ },
300
306
  "./usage": {
301
307
  "default": "./build/_modules/usage/index.js",
302
308
  "module": "./build/_modules/usage/index.js",
@@ -450,6 +456,9 @@
450
456
  "logs": [
451
457
  "build/_modules/logs/index.d.ts"
452
458
  ],
459
+ "machine-monitor": [
460
+ "build/_modules/machine-monitor/index.d.ts"
461
+ ],
453
462
  "usage": [
454
463
  "build/_modules/usage/index.d.ts"
455
464
  ],
@@ -544,7 +553,7 @@
544
553
  }
545
554
  },
546
555
  "devDependencies": {
547
- "@futdevpro/fsm-dynamo": "1.20.135",
556
+ "@futdevpro/fsm-dynamo": "1.20.136",
548
557
  "@futdevpro/dynamo-eslint": "1.20.74",
549
558
  "@discordjs/opus": "^0.10.0",
550
559
  "@discordjs/voice": "^0.18.0",