pyre-cli 10.3.0 → 10.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/README.md +41 -0
  2. package/dist/{alertChannels-TPSQIJ7S.js → alertChannels-MNX4XH6J.js} +1 -0
  3. package/dist/{anomaliesCmd-25OFKYPK.js → anomaliesCmd-HHTY5LYL.js} +2 -0
  4. package/dist/benchGitCmd-HIXUC5EK.js +87 -0
  5. package/dist/{benchmarkCmd-A3ETK6VY.js → benchmarkCmd-B7DLP2VC.js} +2 -0
  6. package/dist/{blender-FGH3ASEQ.js → blender-6ZX5SPYC.js} +3 -1
  7. package/dist/{brewHealth-P2GW5Y5C.js → brewHealth-VFW33QB3.js} +1 -0
  8. package/dist/budgetCmd-TGO3RYLN.js +11 -0
  9. package/dist/{buildCmd-CDPZ2ZFA.js → buildCmd-E7KUCFYG.js} +3 -1
  10. package/dist/{checkCmd-WQAHAUWO.js → checkCmd-QLYTP77Y.js} +5 -3
  11. package/dist/chunk-3RG5ZIWI.js +10 -0
  12. package/dist/{chunk-VIACN2RU.js → chunk-FYCBGUTW.js} +41 -19
  13. package/dist/chunk-JH7P6KLN.js +143 -0
  14. package/dist/{chunk-QM5L43EK.js → chunk-LDJB5V4N.js} +5 -1
  15. package/dist/chunk-NMGQVRCA.js +111 -0
  16. package/dist/chunk-OCL7P7N7.js +936 -0
  17. package/dist/{chunk-23YWCI3O.js → chunk-QEH4LR6P.js} +28 -686
  18. package/dist/{chunk-KVUMOA6C.js → chunk-RKPGPVTO.js} +77 -4
  19. package/dist/chunk-UF3XQ3R3.js +3800 -0
  20. package/dist/{collectors-JDN5Y7EV.js → collectors-V7SCIIDH.js} +5 -3
  21. package/dist/{completions-ZVTNE52B.js → completions-FTPXDSR2.js} +44 -3
  22. package/dist/{config-J4YMADEF.js → config-5WW5M63G.js} +2 -1
  23. package/dist/containersCmd-FSMYOBG2.js +84 -0
  24. package/dist/{doctor-LHFW4UJP.js → doctor-O4DIAMHK.js} +3 -2
  25. package/dist/{explainCmd-MF6PIMLW.js → explainCmd-7PBPA7O5.js} +1 -0
  26. package/dist/{extensions-XJGHG7X3.js → extensions-QQEV7U3D.js} +1 -0
  27. package/dist/{firebaseSync-ON3RZ6KX.js → firebaseSync-LRN67UTV.js} +2 -0
  28. package/dist/flightRecorder-GJIAQOXC.js +162 -0
  29. package/dist/index.js +736 -4125
  30. package/dist/inspectCmd-5FXJBJTK.js +137 -0
  31. package/dist/menu-AJFGDLBP.js +1233 -0
  32. package/dist/monitors/platform/windows-ui.ps1 +31 -29
  33. package/dist/{netUsageCmd-67IBZZYN.js → netUsageCmd-JP6YKBPF.js} +7 -5
  34. package/dist/optimizeCmd-WZKLFYZU.js +1110 -0
  35. package/dist/{pipeCmd-2N4JPKYE.js → pipeCmd-CPK6FVKB.js} +5 -3
  36. package/dist/playbookCmd-FRROIEXR.js +145 -0
  37. package/dist/{profileProcCmd-N4H6MCBT.js → profileProcCmd-5Y3733E7.js} +64 -13
  38. package/dist/{prometheus-5BL5PVLC.js → prometheus-CYNUR3QT.js} +1 -0
  39. package/dist/{prometheusCmd-LEUM5WCZ.js → prometheusCmd-G2CSEZRQ.js} +5 -3
  40. package/dist/{replayCmd-Z3PYXY7V.js → replayCmd-ODB5SPOQ.js} +25 -6
  41. package/dist/{run-HOGQDDTA.js → run-UJQYT2TO.js} +1 -0
  42. package/dist/{serveCmd-L7LVJOZN.js → serveCmd-KDPWLVQI.js} +5 -3
  43. package/dist/{service-7GIX3YNC.js → service-LIYYR3UI.js} +1 -0
  44. package/dist/{smartCmd-ODWKSFNG.js → smartCmd-2BJJ37GV.js} +130 -5
  45. package/dist/statuslineCmd-EUKYRR2G.js +75 -0
  46. package/dist/{stressCmd-MFXMFXYX.js → stressCmd-GKHGY26X.js} +2 -0
  47. package/dist/{syncCmd-42IRF633.js → syncCmd-MIBFKX24.js} +16 -5
  48. package/dist/topoCmd-RTXQJ6XA.js +189 -0
  49. package/dist/{updateCheck-52X6LJG5.js → updateCheck-LJHEMG3G.js} +2 -0
  50. package/dist/{watchdogCmd-6GR4UN6B.js → watchdogCmd-XM6OPTKM.js} +41 -6
  51. package/dist/{wizard-JQMQWFAW.js → wizard-PRDOJROQ.js} +2 -1
  52. package/package.json +2 -2
  53. package/src/benchGitCmd.ts +110 -0
  54. package/src/budgetCmd.ts +199 -0
  55. package/src/completions.ts +42 -3
  56. package/src/containersCmd.ts +106 -0
  57. package/src/doctor.ts +86 -6
  58. package/src/easy_features.test.ts +83 -0
  59. package/src/flightRecorder.ts +214 -0
  60. package/src/index.ts +181 -8
  61. package/src/inspectCmd.ts +165 -0
  62. package/src/live/input.ts +70 -3
  63. package/src/live/render.ts +1 -1
  64. package/src/live/state.ts +2 -1
  65. package/src/menu/commands.ts +754 -0
  66. package/src/menu/index.ts +358 -0
  67. package/src/menu/render.ts +272 -0
  68. package/src/menu/types.ts +63 -0
  69. package/src/menu.test.ts +110 -0
  70. package/src/monitors/blender.ts +49 -19
  71. package/src/monitors/buildTracker.ts +72 -54
  72. package/src/monitors/platform/windows-ui.ps1 +31 -29
  73. package/src/monitors/platform/windows.ts +636 -280
  74. package/src/optimizeCmd.ts +1248 -0
  75. package/src/platform.test.ts +146 -0
  76. package/src/playbookCmd.ts +156 -0
  77. package/src/power_features.test.ts +251 -0
  78. package/src/profileProcCmd.ts +68 -21
  79. package/src/replayCmd.ts +15 -6
  80. package/src/smartCmd.ts +149 -10
  81. package/src/state/config.ts +13 -0
  82. package/src/statuslineCmd.ts +87 -0
  83. package/src/syncCmd.ts +12 -0
  84. package/src/topoCmd.ts +83 -50
  85. package/src/watchdogCmd.ts +40 -3
  86. package/src/xbar.ts +195 -17
  87. package/dist/chunk-M73HCQD2.js +0 -95
  88. package/dist/topoCmd-DZ3YS5IL.js +0 -148
@@ -0,0 +1,936 @@
1
+ import {
2
+ run,
3
+ runPowerShell
4
+ } from "./chunk-MZO5QKUR.js";
5
+
6
+ // src/monitors/platform/windows.ts
7
+ import os from "os";
8
+ import path from "path";
9
+ var prevNetSample = null;
10
+ var emaLoadAvg = [0, 0, 0];
11
+ var lastLoadTime = 0;
12
+ function safeParseFloat(s) {
13
+ if (!s) return 0;
14
+ const n = parseFloat(s);
15
+ return Number.isFinite(n) ? n : 0;
16
+ }
17
+ function safeParseInt(s, def = 0) {
18
+ if (!s) return def;
19
+ const n = parseInt(s, 10);
20
+ return Number.isFinite(n) ? n : def;
21
+ }
22
+ async function getCimRow(className) {
23
+ const raw = await runPowerShell(
24
+ `Get-CimInstance -ClassName ${className} -ErrorAction SilentlyContinue | Select-Object -Property * -ExcludeProperty CIM* | ConvertTo-Csv -NoTypeInformation`,
25
+ ""
26
+ );
27
+ const lines = raw.split("\n").filter((l) => l.trim().length > 0);
28
+ if (lines.length < 2) return {};
29
+ const headers = lines[0].split(",").map((h) => h.trim().replace(/^"|"$/g, ""));
30
+ const values = lines[1].split(",").map((v) => v.trim().replace(/^"|"$/g, ""));
31
+ const row = {};
32
+ headers.forEach((h, i) => {
33
+ row[h] = values[i] || "";
34
+ });
35
+ return row;
36
+ }
37
+ async function collectWindowsSystem() {
38
+ const hostname = os.hostname();
39
+ const rel = os.release();
40
+ const build = parseInt(rel.split(".")[2] || "0", 10);
41
+ let osName = "Windows";
42
+ if (build >= 22e3) {
43
+ osName = `Windows 11 (${rel})`;
44
+ } else if (rel.startsWith("10.0")) {
45
+ osName = `Windows 10 (${rel})`;
46
+ } else {
47
+ osName = `Windows (${rel})`;
48
+ }
49
+ const uptimeSec = Math.floor(os.uptime());
50
+ const days = Math.floor(uptimeSec / 86400);
51
+ const hours = Math.floor(uptimeSec % 86400 / 3600);
52
+ const minutes = Math.floor(uptimeSec % 3600 / 60);
53
+ let uptime = "";
54
+ if (days > 0) uptime += `${days} ${days === 1 ? "day" : "days"}, `;
55
+ uptime += `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
56
+ return { hostname, os: osName, uptime };
57
+ }
58
+ function parseWindowsCpuBrand(rawName, fallback) {
59
+ if (!rawName) return fallback;
60
+ return rawName.replace(/\s+/g, " ").replace(/,\s*$/, "").trim() || fallback;
61
+ }
62
+ function estimateCpuTdp(brand) {
63
+ const b = brand.toLowerCase();
64
+ const isAmd = b.includes("amd") || b.includes("ryzen");
65
+ const isIntel = b.includes("intel") || b.includes("core");
66
+ if (isAmd) {
67
+ if (b.includes("threadripper") || b.includes("epyc")) return 280;
68
+ if (b.includes("ryzen 9") || b.includes("7950") || b.includes("7900") || b.includes("5950") || b.includes("5900") || b.includes("9950") || b.includes("9900")) return 170;
69
+ if (b.includes("ryzen 7") || b.includes("7700") || b.includes("7800x3d") || b.includes("5800") || b.includes("9700")) return 105;
70
+ if (b.includes("ryzen 5") || b.includes("7600") || b.includes("5600")) return 65;
71
+ if (b.includes("u") || b.includes("hs") || b.includes("mobile")) return 28;
72
+ return 65;
73
+ }
74
+ if (isIntel) {
75
+ if (b.includes("xeon")) return 205;
76
+ if (b.includes("i9") || b.includes("14900") || b.includes("13900") || b.includes("12900")) return 125;
77
+ if (b.includes("i7") || b.includes("14700") || b.includes("13700") || b.includes("12700")) return 125;
78
+ if (b.includes("i5")) return 65;
79
+ if (b.includes("i3")) return 60;
80
+ if (b.includes("ultra")) return 45;
81
+ if (b.includes("h") || b.includes("hx")) return 45;
82
+ if (b.includes("u") || b.includes("p")) return 28;
83
+ return 65;
84
+ }
85
+ return 65;
86
+ }
87
+ function updateEmaLoadAvg(currentUsage, cores) {
88
+ const activeLoad = Math.round(currentUsage / 100 * cores * 100) / 100;
89
+ const now = Date.now();
90
+ if (lastLoadTime === 0) {
91
+ lastLoadTime = now;
92
+ emaLoadAvg = [activeLoad, activeLoad, activeLoad];
93
+ return emaLoadAvg;
94
+ }
95
+ const dtSec = Math.max((now - lastLoadTime) / 1e3, 0.1);
96
+ lastLoadTime = now;
97
+ const exp1 = Math.exp(-dtSec / 60);
98
+ const exp5 = Math.exp(-dtSec / 300);
99
+ const exp15 = Math.exp(-dtSec / 900);
100
+ emaLoadAvg = [
101
+ Math.round((activeLoad * (1 - exp1) + emaLoadAvg[0] * exp1) * 100) / 100,
102
+ Math.round((activeLoad * (1 - exp5) + emaLoadAvg[1] * exp5) * 100) / 100,
103
+ Math.round((activeLoad * (1 - exp15) + emaLoadAvg[2] * exp15) * 100) / 100
104
+ ];
105
+ return emaLoadAvg;
106
+ }
107
+ async function collectWindowsCpu(prevCpuTimesRef) {
108
+ const cpus = os.cpus();
109
+ const cores = cpus.length || 1;
110
+ let brand = cpus[0]?.model || "Windows CPU";
111
+ let physicalCores = cores;
112
+ let frequency = cpus[0]?.speed || 0;
113
+ try {
114
+ const cpuRow = await getCimRow("Win32_Processor");
115
+ if (cpuRow.Name) brand = parseWindowsCpuBrand(cpuRow.Name, brand);
116
+ if (cpuRow.NumberOfCores) physicalCores = safeParseInt(cpuRow.NumberOfCores, cores);
117
+ if (cpuRow.MaxClockSpeed) frequency = safeParseInt(cpuRow.MaxClockSpeed, frequency);
118
+ } catch {
119
+ }
120
+ const current = cpus.map((cpu) => ({
121
+ total: cpu.times.user + cpu.times.nice + cpu.times.sys + cpu.times.idle + cpu.times.irq,
122
+ idle: cpu.times.idle
123
+ }));
124
+ let coreUsage = [];
125
+ let usage = 0;
126
+ const prevCpuTimes = prevCpuTimesRef.current;
127
+ if (prevCpuTimes && prevCpuTimes.length === current.length) {
128
+ coreUsage = current.map((c, i) => {
129
+ const prev = prevCpuTimes[i];
130
+ const totalDelta = c.total - prev.total;
131
+ const idleDelta = c.idle - prev.idle;
132
+ if (totalDelta <= 0) return 0;
133
+ return Math.min(100, Math.max(0, Math.round((totalDelta - idleDelta) / totalDelta * 100)));
134
+ });
135
+ if (coreUsage.length > 0) {
136
+ usage = Math.round(coreUsage.reduce((a, b) => a + b, 0) / coreUsage.length);
137
+ }
138
+ }
139
+ prevCpuTimesRef.current = current;
140
+ const loadAvg = updateEmaLoadAvg(usage, cores);
141
+ let temperature = await getWindowsCpuTemperature();
142
+ return {
143
+ brand,
144
+ cores,
145
+ physicalCores,
146
+ frequency,
147
+ usage,
148
+ loadAvg,
149
+ temperature,
150
+ coreUsage
151
+ };
152
+ }
153
+ async function getWindowsCpuTemperature() {
154
+ try {
155
+ const lhmRaw = await runPowerShell(
156
+ `Get-CimInstance -Namespace root/LibreHardwareMonitor -ClassName Sensor -Filter "SensorType = 'Temperature' and Name like '%CPU%'" -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty Value`,
157
+ ""
158
+ );
159
+ const lhmVal = safeParseFloat(lhmRaw);
160
+ if (lhmVal >= 15 && lhmVal <= 115) return Math.round(lhmVal * 10) / 10;
161
+ } catch {
162
+ }
163
+ try {
164
+ const ohmRaw = await runPowerShell(
165
+ `Get-CimInstance -Namespace root/OpenHardwareMonitor -ClassName Sensor -Filter "SensorType = 'Temperature' and Name like '%CPU%'" -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty Value`,
166
+ ""
167
+ );
168
+ const ohmVal = safeParseFloat(ohmRaw);
169
+ if (ohmVal >= 15 && ohmVal <= 115) return Math.round(ohmVal * 10) / 10;
170
+ } catch {
171
+ }
172
+ try {
173
+ const cimRaw = await runPowerShell(
174
+ `(Get-CimInstance -Namespace root/wmi -ClassName MSAcpi_ThermalZoneTemperature -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty CurrentTemperature)`,
175
+ ""
176
+ );
177
+ const kelvinTenths = safeParseInt(cimRaw);
178
+ if (kelvinTenths > 2732 && kelvinTenths < 4200) {
179
+ const c = Math.round((kelvinTenths - 2732) / 10 * 10) / 10;
180
+ if (c >= 15 && c <= 115) return c;
181
+ }
182
+ } catch {
183
+ }
184
+ try {
185
+ const raw = await runPowerShell(
186
+ `(Get-Counter '\\Thermal Zone Information(*)\\*' -ErrorAction SilentlyContinue).CounterSamples | Where-Object { $_.CookedValue -gt 200 -and $_.CookedValue -lt 400 } | Select-Object -First 1 -ExpandProperty CookedValue`,
187
+ ""
188
+ );
189
+ const tempK = safeParseFloat(raw);
190
+ if (tempK > 200 && tempK < 400) {
191
+ return Math.round((tempK - 273.15) * 10) / 10;
192
+ }
193
+ } catch {
194
+ }
195
+ return void 0;
196
+ }
197
+ async function collectWindowsMemory() {
198
+ const total = os.totalmem();
199
+ const free = os.freemem();
200
+ const used = Math.max(0, total - free);
201
+ const usagePercent = total > 0 ? Math.round(used / total * 100) : 0;
202
+ let swapTotal = 0;
203
+ let swapUsed = 0;
204
+ let swapFree = 0;
205
+ try {
206
+ const rawPage = await runPowerShell(
207
+ `Get-CimInstance Win32_PageFileUsage | ForEach-Object { "$($_.AllocatedBaseSize)|$($_.CurrentUsage)" }`,
208
+ ""
209
+ );
210
+ const lines = rawPage.split("\n").filter((l) => l.trim().length > 0);
211
+ for (const line of lines) {
212
+ const [allocStr, usedStr] = line.split("|");
213
+ const allocMb = safeParseInt(allocStr);
214
+ const usedMb = safeParseInt(usedStr);
215
+ swapTotal += allocMb * 1024 * 1024;
216
+ swapUsed += usedMb * 1024 * 1024;
217
+ }
218
+ swapFree = Math.max(0, swapTotal - swapUsed);
219
+ } catch {
220
+ }
221
+ let pressureLevel = "Normal";
222
+ if (usagePercent > 92) pressureLevel = "Critical";
223
+ else if (usagePercent > 82) pressureLevel = "Warning";
224
+ return {
225
+ total,
226
+ used,
227
+ free,
228
+ swapTotal,
229
+ swapUsed,
230
+ swapFree,
231
+ pageSize: 4096,
232
+ usagePercent,
233
+ pressureLevel
234
+ };
235
+ }
236
+ async function collectWindowsDisk() {
237
+ try {
238
+ const raw = await runPowerShell(
239
+ `Get-CimInstance Win32_LogicalDisk -Filter "DriveType=3" | ForEach-Object { "$($_.DeviceID)|$($_.FileSystem)|$($_.Size)|$($_.FreeSpace)" }`,
240
+ ""
241
+ );
242
+ const disks = [];
243
+ for (const line of raw.split("\n")) {
244
+ const parts = line.trim().split("|");
245
+ if (parts.length >= 4) {
246
+ const drive = parts[0];
247
+ const totalBytes = safeParseInt(parts[2]);
248
+ const freeBytes = safeParseInt(parts[3]);
249
+ if (totalBytes > 0) {
250
+ const usedBytes = Math.max(0, totalBytes - freeBytes);
251
+ const capPct = Math.round(usedBytes / totalBytes * 100);
252
+ disks.push({
253
+ filesystem: drive,
254
+ size: formatBytesStr(totalBytes),
255
+ used: formatBytesStr(usedBytes),
256
+ available: formatBytesStr(freeBytes),
257
+ capacity: `${capPct}%`,
258
+ mountpoint: drive,
259
+ readBytesSec: 0,
260
+ writeBytesSec: 0
261
+ });
262
+ }
263
+ }
264
+ }
265
+ if (disks.length > 0) return disks;
266
+ } catch {
267
+ }
268
+ return [
269
+ {
270
+ filesystem: "C:",
271
+ size: "500G",
272
+ used: "150G",
273
+ available: "350G",
274
+ capacity: "30%",
275
+ mountpoint: "C:",
276
+ readBytesSec: 0,
277
+ writeBytesSec: 0
278
+ }
279
+ ];
280
+ }
281
+ function formatBytesStr(bytes) {
282
+ if (bytes >= 1024 * 1024 * 1024 * 1024) return (bytes / (1024 * 1024 * 1024 * 1024)).toFixed(1) + "T";
283
+ if (bytes >= 1024 * 1024 * 1024) return (bytes / (1024 * 1024 * 1024)).toFixed(1) + "G";
284
+ if (bytes >= 1024 * 1024) return (bytes / (1024 * 1024)).toFixed(1) + "M";
285
+ return (bytes / 1024).toFixed(0) + "K";
286
+ }
287
+ async function collectWindowsBattery() {
288
+ try {
289
+ const raw = await runPowerShell(
290
+ `$bat = Get-CimInstance Win32_Battery -ErrorAction SilentlyContinue; if ($bat) { "$($bat.EstimatedChargeRemaining)|$($bat.BatteryStatus)|$($bat.EstimatedRunTime)|$($bat.DischargeRate)" } else { '' }`,
291
+ ""
292
+ );
293
+ if (!raw) return null;
294
+ const parts = raw.split("|");
295
+ const level = safeParseInt(parts[0], 0);
296
+ const statusCode = safeParseInt(parts[1], 1);
297
+ const runTimeMinutes = safeParseInt(parts[2], 0);
298
+ const dischargeRate = safeParseInt(parts[3], 0);
299
+ const powerSource = statusCode === 2 || statusCode === 3 || statusCode === 6 ? "AC" : "Battery";
300
+ const state = statusCode === 3 ? "charged" : statusCode === 6 || statusCode === 2 ? "charging" : "discharging";
301
+ let timeRemaining = "calculating";
302
+ if (state === "charged") timeRemaining = "\u221E";
303
+ else if (runTimeMinutes && runTimeMinutes > 0 && runTimeMinutes < 7e4) {
304
+ const h = Math.floor(runTimeMinutes / 60);
305
+ const m = runTimeMinutes % 60;
306
+ timeRemaining = `${h}:${m.toString().padStart(2, "0")}`;
307
+ }
308
+ const powerWatts = dischargeRate > 0 ? Math.round(dischargeRate / 1e3 * 100) / 100 : void 0;
309
+ return {
310
+ level,
311
+ state,
312
+ timeRemaining,
313
+ health: "Good",
314
+ powerSource,
315
+ powerWatts
316
+ };
317
+ } catch {
318
+ return null;
319
+ }
320
+ }
321
+ async function collectWindowsThermal() {
322
+ const temperatures = {};
323
+ const cpuTemp = await getWindowsCpuTemperature();
324
+ if (cpuTemp !== void 0) {
325
+ temperatures["cpu"] = cpuTemp;
326
+ }
327
+ let gpuTemp;
328
+ try {
329
+ const nvRaw = await runNvidiaSmiQuery("temperature.gpu");
330
+ const t = safeParseFloat(nvRaw);
331
+ if (t > 0 && t < 125) gpuTemp = t;
332
+ } catch {
333
+ }
334
+ if (gpuTemp === void 0) {
335
+ try {
336
+ const lhmGpu = await runPowerShell(
337
+ `Get-CimInstance -Namespace root/LibreHardwareMonitor -ClassName Sensor -Filter "SensorType = 'Temperature' and Name like '%GPU%'" -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty Value`,
338
+ ""
339
+ );
340
+ const t = safeParseFloat(lhmGpu);
341
+ if (t > 0 && t < 125) gpuTemp = t;
342
+ } catch {
343
+ }
344
+ }
345
+ if (gpuTemp !== void 0) {
346
+ temperatures["gpu"] = gpuTemp;
347
+ }
348
+ const primaryTemp = cpuTemp ?? gpuTemp;
349
+ let state = "Nominal";
350
+ let pressureLevel = 0;
351
+ if (primaryTemp !== void 0) {
352
+ if (primaryTemp >= 100) {
353
+ state = "Critical";
354
+ pressureLevel = 3;
355
+ } else if (primaryTemp >= 90) {
356
+ state = "Serious";
357
+ pressureLevel = 2;
358
+ } else if (primaryTemp >= 80) {
359
+ state = "Fair";
360
+ pressureLevel = 1;
361
+ }
362
+ }
363
+ return {
364
+ state,
365
+ detail: primaryTemp !== void 0 ? `${state} (${primaryTemp}\xB0C)` : state,
366
+ pressureLevel,
367
+ temperatures: Object.keys(temperatures).length ? temperatures : void 0
368
+ };
369
+ }
370
+ async function collectWindowsPower() {
371
+ const power = {};
372
+ try {
373
+ const batRaw = await runPowerShell(
374
+ `$bat = Get-CimInstance Win32_Battery -ErrorAction SilentlyContinue; if ($bat) { "$($bat.DischargeRate)|$($bat.BatteryStatus)" } else { '|0' }`,
375
+ ""
376
+ );
377
+ const [dischargeStr, statusStr] = batRaw.split("|");
378
+ const dischargeRate = safeParseInt(dischargeStr);
379
+ const statusCode = safeParseInt(statusStr, 1);
380
+ if (dischargeRate > 0 && (statusCode === 1 || statusCode === 2)) {
381
+ power.combinedWatts = Math.round(dischargeRate / 1e3 * 100) / 100;
382
+ }
383
+ } catch {
384
+ }
385
+ try {
386
+ const lhmCpu = await runPowerShell(
387
+ `Get-CimInstance -Namespace root/LibreHardwareMonitor -ClassName Sensor -Filter "SensorType = 'Power' and Name like '%CPU Package%'" -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty Value`,
388
+ ""
389
+ );
390
+ const cpuP = safeParseFloat(lhmCpu);
391
+ if (cpuP > 0) power.cpuWatts = Math.round(cpuP * 100) / 100;
392
+ const lhmGpu = await runPowerShell(
393
+ `Get-CimInstance -Namespace root/LibreHardwareMonitor -ClassName Sensor -Filter "SensorType = 'Power' and Name like '%GPU%'" -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty Value`,
394
+ ""
395
+ );
396
+ const gpuP = safeParseFloat(lhmGpu);
397
+ if (gpuP > 0) power.gpuWatts = Math.round(gpuP * 100) / 100;
398
+ } catch {
399
+ }
400
+ if (!power.gpuWatts) {
401
+ try {
402
+ const nvPower = await runNvidiaSmiQuery("power.draw");
403
+ const p = safeParseFloat(nvPower);
404
+ if (p > 0) power.gpuWatts = Math.round(p * 100) / 100;
405
+ } catch {
406
+ }
407
+ }
408
+ if (!power.cpuWatts) {
409
+ try {
410
+ const cpu = os.cpus();
411
+ const brand = cpu[0]?.model || "";
412
+ const tdpWatts = estimateCpuTdp(brand);
413
+ const usage = cpu.length > 0 ? Math.round(
414
+ cpu.reduce(
415
+ (a, c) => a + (c.times.user + c.times.nice + c.times.sys + c.times.irq - c.times.idle) / (c.times.user + c.times.nice + c.times.sys + c.times.idle + c.times.irq),
416
+ 0
417
+ ) / cpu.length * 100
418
+ ) : 0;
419
+ if (usage > 0) {
420
+ power.cpuWatts = Math.round(usage / 100 * tdpWatts * 100) / 100;
421
+ }
422
+ } catch {
423
+ }
424
+ }
425
+ if (power.combinedWatts || power.cpuWatts || power.gpuWatts) {
426
+ if (!power.combinedWatts) {
427
+ power.combinedWatts = Math.round(((power.cpuWatts || 0) + (power.gpuWatts || 0)) * 100) / 100;
428
+ }
429
+ return power;
430
+ }
431
+ return null;
432
+ }
433
+ async function findNvidiaSmiPath() {
434
+ const commonPaths = [
435
+ "nvidia-smi",
436
+ path.join(process.env.ProgramFiles || "C:\\Program Files", "NVIDIA Corporation", "NVSMI", "nvidia-smi.exe"),
437
+ path.join(process.env.SystemRoot || "C:\\Windows", "System32", "nvidia-smi.exe")
438
+ ];
439
+ for (const p of commonPaths) {
440
+ try {
441
+ const test = await run(`"${p}" -L 2>nul`, "");
442
+ if (test.includes("GPU 0:")) return p;
443
+ } catch {
444
+ }
445
+ }
446
+ return "nvidia-smi";
447
+ }
448
+ async function runNvidiaSmiQuery(query) {
449
+ const smiPath = await findNvidiaSmiPath();
450
+ return (await run(`"${smiPath}" --query-gpu=${query} --format=csv,noheader,nounits 2>nul`, "")).trim();
451
+ }
452
+ function parseNvidiaSmiOutput(csv) {
453
+ const lines = csv.split("\n").filter((l) => l.trim().length > 0);
454
+ if (lines.length === 0) return null;
455
+ const parts = lines[0].split(",").map((s) => s.trim());
456
+ if (parts.length < 3) return null;
457
+ const model = parts[0];
458
+ const memory = safeParseFloat(parts[1]) * 1024 * 1024;
459
+ const utilization = Math.min(100, Math.max(0, Math.round(safeParseFloat(parts[2]))));
460
+ const temperature = parts[3] ? safeParseFloat(parts[3]) : void 0;
461
+ const powerDraw = parts[4] ? safeParseFloat(parts[4]) : void 0;
462
+ return {
463
+ model,
464
+ memory,
465
+ utilization,
466
+ temperature: Number.isFinite(temperature) && temperature > 0 ? temperature : void 0,
467
+ processes: 0,
468
+ powerDraw: Number.isFinite(powerDraw) && powerDraw > 0 ? powerDraw : void 0
469
+ };
470
+ }
471
+ async function getNvidiaGpu() {
472
+ try {
473
+ const raw = await runNvidiaSmiQuery("gpu_name,memory.total,utilization.gpu,temperature.gpu,power.draw");
474
+ const parsed = parseNvidiaSmiOutput(raw);
475
+ if (parsed) {
476
+ try {
477
+ const smiPath = await findNvidiaSmiPath();
478
+ const procList = await run(`"${smiPath}" --query-compute-apps=pid --format=csv,noheader 2>nul`, "");
479
+ const pids = procList.split("\n").filter((l) => l.trim().length > 0);
480
+ parsed.processes = pids.length;
481
+ } catch {
482
+ }
483
+ return parsed;
484
+ }
485
+ } catch {
486
+ }
487
+ return null;
488
+ }
489
+ function parseWindowsVideoControllers(csvRaw) {
490
+ const lines = csvRaw.split("\n").filter((l) => l.trim().length > 0);
491
+ if (lines.length < 2) return [];
492
+ const headers = lines[0].split(",").map((h) => h.trim().replace(/^"|"$/g, ""));
493
+ const controllers = [];
494
+ for (const line of lines.slice(1)) {
495
+ const values = line.split(",").map((v) => v.trim().replace(/^"|"$/g, ""));
496
+ const row = {};
497
+ headers.forEach((h, i) => {
498
+ row[h] = values[i] || "";
499
+ });
500
+ const name = row.Name || row.VideoProcessor || "Windows Display Adapter";
501
+ const ram = safeParseInt(row.AdapterRAM, 0);
502
+ controllers.push({
503
+ name,
504
+ adapterRam: ram,
505
+ driverVersion: row.DriverVersion || "",
506
+ videoProcessor: row.VideoProcessor || "",
507
+ pnpDeviceId: row.PNPDeviceID || ""
508
+ });
509
+ }
510
+ return controllers;
511
+ }
512
+ function prioritizeGpuControllers(controllers) {
513
+ return [...controllers].sort((a, b) => {
514
+ const aName = a.name.toLowerCase();
515
+ const bName = b.name.toLowerCase();
516
+ const aIsDiscrete = aName.includes("rtx") || aName.includes("gtx") || aName.includes("geforce") || aName.includes("radeon rx") || aName.includes("arc");
517
+ const bIsDiscrete = bName.includes("rtx") || bName.includes("gtx") || bName.includes("geforce") || bName.includes("radeon rx") || bName.includes("arc");
518
+ if (aIsDiscrete && !bIsDiscrete) return -1;
519
+ if (!aIsDiscrete && bIsDiscrete) return 1;
520
+ return b.adapterRam - a.adapterRam;
521
+ });
522
+ }
523
+ async function getWindowsGpu64BitVram() {
524
+ try {
525
+ const raw = await runPowerShell(
526
+ `Get-ItemProperty -Path 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Class\\{4d36e968-e325-11ce-bfc1-08002be10318}\\0*' -ErrorAction SilentlyContinue | Where-Object { $_.HardwareInformation.qwMemorySize -gt 0 } | Select-Object -First 1 -ExpandProperty HardwareInformation.qwMemorySize`,
527
+ ""
528
+ );
529
+ const bytes = safeParseInt(raw, 0);
530
+ if (bytes > 0) return bytes;
531
+ } catch {
532
+ }
533
+ try {
534
+ const rawDedicated = await runPowerShell(
535
+ `(Get-Counter '\\GPU Adapter Memory(*)\\Dedicated Usage' -ErrorAction SilentlyContinue).CounterSamples | Measure-Object -Property CookedValue -Sum | Select-Object -ExpandProperty Sum`,
536
+ ""
537
+ );
538
+ const bytes = safeParseFloat(rawDedicated);
539
+ if (bytes > 0) return bytes;
540
+ } catch {
541
+ }
542
+ return 0;
543
+ }
544
+ async function getWindowsGpu3dUtilization() {
545
+ try {
546
+ const raw = await runPowerShell(
547
+ `$samples = (Get-Counter '\\GPU Engine(*engtype_3D*)\\Utilization Percentage' -ErrorAction SilentlyContinue).CounterSamples; if ($samples) { $activePids = $samples | Where-Object { $_.CookedValue -gt 0 } | ForEach-Object { if ($_.InstanceName -match 'pid_(\\d+)') { $matches[1] } } | Select-Object -Unique; $total = ($samples | Measure-Object -Property CookedValue -Sum).Sum; "$total|$($activePids.Count)" } else { '0|0' }`,
548
+ "0|0"
549
+ );
550
+ const [utilStr, procCountStr] = raw.split("|");
551
+ const util = Math.min(100, Math.max(0, Math.round(safeParseFloat(utilStr))));
552
+ const processCount = safeParseInt(procCountStr, 0);
553
+ return { utilization: util, processCount };
554
+ } catch {
555
+ return { utilization: 0, processCount: 0 };
556
+ }
557
+ }
558
+ async function collectWindowsGpu() {
559
+ const nv = await getNvidiaGpu();
560
+ if (nv) return nv;
561
+ try {
562
+ const rawControllers = await runPowerShell(
563
+ `Get-CimInstance Win32_VideoController | Select-Object Name, AdapterRAM, DriverVersion, VideoProcessor, PNPDeviceID | ConvertTo-Csv -NoTypeInformation`,
564
+ ""
565
+ );
566
+ const controllers = parseWindowsVideoControllers(rawControllers);
567
+ if (controllers.length === 0) return null;
568
+ const prioritized = prioritizeGpuControllers(controllers);
569
+ const bestController = prioritized[0];
570
+ let vramBytes = await getWindowsGpu64BitVram();
571
+ if (vramBytes === 0 && bestController.adapterRam > 0) {
572
+ vramBytes = bestController.adapterRam;
573
+ }
574
+ const { utilization, processCount } = await getWindowsGpu3dUtilization();
575
+ let temperature;
576
+ try {
577
+ const rawTemp = await runPowerShell(
578
+ `Get-CimInstance -Namespace root/LibreHardwareMonitor -ClassName Sensor -Filter "SensorType = 'Temperature' and Name like '%GPU%'" -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty Value`,
579
+ ""
580
+ );
581
+ const t = safeParseFloat(rawTemp);
582
+ if (t > 0 && t < 125) temperature = t;
583
+ } catch {
584
+ }
585
+ return {
586
+ model: bestController.name,
587
+ memory: vramBytes,
588
+ utilization,
589
+ temperature,
590
+ processes: processCount
591
+ };
592
+ } catch {
593
+ return null;
594
+ }
595
+ }
596
+ function parseWindowsTcpConnections(csvRaw) {
597
+ const lines = csvRaw.split("\n").filter((l) => l.trim().length > 0);
598
+ if (lines.length < 2) return [];
599
+ const headers = lines[0].split(",").map((h) => h.trim().replace(/^"|"$/g, ""));
600
+ const connections = [];
601
+ for (const line of lines.slice(1)) {
602
+ const values = line.split(",").map((v) => v.trim().replace(/^"|"$/g, ""));
603
+ const row = {};
604
+ headers.forEach((h, i) => {
605
+ row[h] = values[i] || "";
606
+ });
607
+ const localPort = safeParseInt(row.LocalPort, 0);
608
+ const remoteAddress = row.RemoteAddress || "";
609
+ const remotePort = safeParseInt(row.RemotePort, 0);
610
+ const state = row.State || "";
611
+ const owningPid = safeParseInt(row.OwningProcess, 0);
612
+ if (owningPid > 0) {
613
+ connections.push({ localPort, remoteAddress, remotePort, state, owningPid });
614
+ }
615
+ }
616
+ return connections;
617
+ }
618
+ async function collectWindowsNetwork() {
619
+ let iface = "Ethernet";
620
+ let ip = "127.0.0.1";
621
+ const interfaces = os.networkInterfaces();
622
+ for (const [name, addrs] of Object.entries(interfaces)) {
623
+ const addr = addrs?.find((a) => a.family === "IPv4" && !a.internal);
624
+ if (addr) {
625
+ iface = name;
626
+ ip = addr.address;
627
+ break;
628
+ }
629
+ }
630
+ let rxBytes = 0;
631
+ let txBytes = 0;
632
+ let rxPackets = 0;
633
+ let txPackets = 0;
634
+ try {
635
+ const raw = await runPowerShell(
636
+ `Get-NetIPConfiguration -AddressFamily IPv4 -ErrorAction SilentlyContinue | Where-Object { $_.NetAdapter.Status -eq 'Up' } | Select-Object -First 1 -ExpandProperty NetAdapter.Name`,
637
+ ""
638
+ );
639
+ if (raw) iface = raw;
640
+ } catch {
641
+ }
642
+ try {
643
+ const netstatE = await run("netstat -e 2>nul", "", 1500);
644
+ const lines = netstatE.split("\n");
645
+ for (const line of lines) {
646
+ const parts = line.trim().split(/\s+/);
647
+ if (parts[0] && parts[0].toLowerCase() === "bytes" && parts.length >= 3) {
648
+ rxBytes = parseInt(parts[1], 10) || 0;
649
+ txBytes = parseInt(parts[2], 10) || 0;
650
+ } else if (parts[0] && parts[0].toLowerCase().includes("unicast") && parts.length >= 3) {
651
+ rxPackets += parseInt(parts[1], 10) || 0;
652
+ txPackets += parseInt(parts[2], 10) || 0;
653
+ }
654
+ }
655
+ } catch {
656
+ }
657
+ const now = Date.now();
658
+ let rxRate = 0;
659
+ let txRate = 0;
660
+ if (prevNetSample && prevNetSample.ts > 0) {
661
+ const dt = Math.max((now - prevNetSample.ts) / 1e3, 1e-3);
662
+ rxRate = Math.max(0, (rxBytes - prevNetSample.rxBytes) / dt);
663
+ txRate = Math.max(0, (txBytes - prevNetSample.txBytes) / dt);
664
+ }
665
+ prevNetSample = { rxBytes, txBytes, ts: now };
666
+ const connectionStates = await getWindowsConnectionStates();
667
+ const { listeningPorts, topRemoteHosts } = await getWindowsSocketDetails();
668
+ return {
669
+ interface: iface,
670
+ ip,
671
+ rxBytes,
672
+ txBytes,
673
+ rxPackets,
674
+ txPackets,
675
+ rxRate,
676
+ txRate,
677
+ connections: connectionStates.established,
678
+ protocols: {
679
+ tcp: { connections: connectionStates.established, rxBytes: 0, txBytes: 0 },
680
+ udp: { connections: 0, rxBytes: 0, txBytes: 0 }
681
+ },
682
+ connectionStates,
683
+ listeningPorts,
684
+ establishedConnections: connectionStates.established,
685
+ topRemoteHosts
686
+ };
687
+ }
688
+ async function getWindowsSocketDetails() {
689
+ const listeningPorts = [];
690
+ const topRemoteHosts = [];
691
+ try {
692
+ const raw = await runPowerShell(
693
+ `$conns = Get-NetTCPConnection -ErrorAction SilentlyContinue; if ($conns) { $ports = ($conns | Where-Object { $_.State -eq 'Listen' } | Select-Object -ExpandProperty LocalPort -Unique) -join ','; $hosts = ($conns | Where-Object { $_.State -eq 'Established' -and $_.RemoteAddress -ne '127.0.0.1' -and $_.RemoteAddress -ne '0.0.0.0' } | Group-Object RemoteAddress | Sort-Object Count -Descending | Select-Object -First 10 | ForEach-Object { "$($_.Name):$($_.Count)" }) -join '|'; "$ports#$hosts" } else { '#' }`,
694
+ "#"
695
+ );
696
+ const [portsPart, hostsPart] = raw.split("#");
697
+ if (portsPart) {
698
+ portsPart.split(",").forEach((p) => {
699
+ const portNum = safeParseInt(p);
700
+ if (portNum > 0 && !listeningPorts.includes(portNum)) listeningPorts.push(portNum);
701
+ });
702
+ }
703
+ if (hostsPart) {
704
+ hostsPart.split("|").forEach((h) => {
705
+ const [ip, countStr] = h.split(":");
706
+ if (ip) {
707
+ topRemoteHosts.push({
708
+ ip,
709
+ connections: safeParseInt(countStr, 1),
710
+ activePids: []
711
+ });
712
+ }
713
+ });
714
+ }
715
+ } catch {
716
+ }
717
+ return { listeningPorts, topRemoteHosts };
718
+ }
719
+ async function getWindowsConnectionStates() {
720
+ const stats = { established: 0, listening: 0, timeWait: 0, closeWait: 0, other: 0 };
721
+ try {
722
+ const raw = await runPowerShell(
723
+ `$c = Get-NetTCPConnection -ErrorAction SilentlyContinue; if ($c) { $groups = $c | Group-Object State; ($groups | ForEach-Object { "$($_.Name)=$($_.Count)" }) -join '|' } else { '' }`,
724
+ ""
725
+ );
726
+ for (const pair of raw.split("|")) {
727
+ const [state, countStr] = pair.split("=");
728
+ const count = safeParseInt(countStr, 0);
729
+ if (state === "Established") stats.established = count;
730
+ else if (state === "Listen") stats.listening = count;
731
+ else if (state === "TimeWait") stats.timeWait = count;
732
+ else if (state === "CloseWait") stats.closeWait = count;
733
+ else if (count > 0) stats.other += count;
734
+ }
735
+ } catch {
736
+ }
737
+ return stats;
738
+ }
739
+ function buildWindowsNetworkProcesses(conns, procMap) {
740
+ const agg = /* @__PURE__ */ new Map();
741
+ for (const c of conns) {
742
+ const pid = c.owningPid;
743
+ const name = procMap.get(pid) || `pid-${pid}`;
744
+ let item = agg.get(pid);
745
+ if (!item) {
746
+ item = {
747
+ pid,
748
+ command: name,
749
+ rxBytes: 0,
750
+ txBytes: 0,
751
+ rxPackets: 0,
752
+ txPackets: 0,
753
+ connections: []
754
+ };
755
+ agg.set(pid, item);
756
+ }
757
+ if (c.remoteAddress && c.remoteAddress !== "0.0.0.0") {
758
+ item.connections.push({
759
+ proto: "tcp",
760
+ localAddress: `127.0.0.1:${c.localPort}`,
761
+ remoteAddress: `${c.remoteAddress}:${c.remotePort}`,
762
+ state: c.state
763
+ });
764
+ }
765
+ }
766
+ return Array.from(agg.values()).sort((a, b) => b.connections.length - a.connections.length);
767
+ }
768
+ async function collectWindowsPackets() {
769
+ let rxBytes = 0;
770
+ let txBytes = 0;
771
+ let rxPackets = 0;
772
+ let txPackets = 0;
773
+ try {
774
+ const netstatE = await run("netstat -e 2>nul", "", 1500);
775
+ const lines = netstatE.split("\n");
776
+ for (const line of lines) {
777
+ const parts = line.trim().split(/\s+/);
778
+ if (parts[0] && parts[0].toLowerCase() === "bytes" && parts.length >= 3) {
779
+ rxBytes = parseInt(parts[1], 10) || 0;
780
+ txBytes = parseInt(parts[2], 10) || 0;
781
+ } else if (parts[0] && parts[0].toLowerCase().includes("unicast") && parts.length >= 3) {
782
+ rxPackets += parseInt(parts[1], 10) || 0;
783
+ txPackets += parseInt(parts[2], 10) || 0;
784
+ }
785
+ }
786
+ } catch {
787
+ }
788
+ const connectionStates = await getWindowsConnectionStates();
789
+ const { listeningPorts } = await getWindowsSocketDetails();
790
+ let allProcesses = [];
791
+ try {
792
+ const rawConns = await runPowerShell(
793
+ `Get-NetTCPConnection -State Established,Listen -ErrorAction SilentlyContinue | Select-Object LocalPort, RemoteAddress, RemotePort, State, OwningProcess | ConvertTo-Csv -NoTypeInformation`,
794
+ ""
795
+ );
796
+ const conns = parseWindowsTcpConnections(rawConns);
797
+ const rawProcs = await runPowerShell(
798
+ `Get-Process -ErrorAction SilentlyContinue | Select-Object Id, ProcessName | ForEach-Object { "$($_.Id)|$($_.ProcessName)" }`,
799
+ ""
800
+ );
801
+ const procMap = /* @__PURE__ */ new Map();
802
+ for (const line of rawProcs.split("\n")) {
803
+ const [idStr, name] = line.trim().split("|");
804
+ const pid = safeParseInt(idStr);
805
+ if (pid > 0 && name) procMap.set(pid, name);
806
+ }
807
+ allProcesses = buildWindowsNetworkProcesses(conns, procMap);
808
+ } catch {
809
+ }
810
+ return {
811
+ totalPackets: rxPackets + txPackets,
812
+ rxPackets,
813
+ txPackets,
814
+ rxRate: 0,
815
+ txRate: 0,
816
+ connections: connectionStates.established,
817
+ topProcesses: allProcesses.slice(0, 10),
818
+ interfaces: [{ iface: "Primary", rxPackets, txPackets, rxBytes, txBytes }],
819
+ allProcesses,
820
+ connectionStates,
821
+ listeningPorts
822
+ };
823
+ }
824
+ var winProcCache = /* @__PURE__ */ new Map();
825
+ function parseWindowsProcessCsv(csvRaw, totalMem, cache, now) {
826
+ const lines = csvRaw.split("\n").filter((l) => l.trim().length > 0 && !l.startsWith('"Name"'));
827
+ const procs = [];
828
+ for (const line of lines) {
829
+ const parts = line.split(",").map((s) => s.trim().replace(/^"|"$/g, ""));
830
+ if (parts.length < 6) continue;
831
+ const name = parts[0];
832
+ const pid = safeParseInt(parts[1], 0);
833
+ const ppid = safeParseInt(parts[2], 0);
834
+ const threads = safeParseInt(parts[3], 0);
835
+ const memBytes = safeParseInt(parts[4], 0);
836
+ const userTime = safeParseInt(parts[5], 0);
837
+ const kernelTime = safeParseInt(parts[6], 0);
838
+ const commandLine = parts[7] || name;
839
+ if (!pid || pid <= 0) continue;
840
+ const totalTime = userTime + kernelTime;
841
+ let cpu = 0;
842
+ const prev = cache.get(pid);
843
+ if (prev) {
844
+ const dt = now - prev.ts;
845
+ if (dt > 0) {
846
+ const timeDelta = totalTime - (prev.user + prev.kernel);
847
+ if (timeDelta > 0) {
848
+ const cpuSeconds = timeDelta / 1e7;
849
+ cpu = Math.min(100, Math.round(cpuSeconds / dt * 1e4) / 100);
850
+ }
851
+ }
852
+ }
853
+ cache.set(pid, { user: userTime, kernel: kernelTime, ts: now });
854
+ const memPct = totalMem > 0 ? Math.round(memBytes / totalMem * 1e3) / 10 : 0;
855
+ const isGpuOrMl = /gpu|vulkan|cuda|ollama|llama|torch|python|nvidia|amd|radeon|directx|game/i.test(name) || /python|node|ollama/i.test(commandLine);
856
+ procs.push({
857
+ pid,
858
+ ppid,
859
+ user: "SYSTEM",
860
+ cpu,
861
+ mem: memPct,
862
+ state: "R",
863
+ threads,
864
+ runtime: 0,
865
+ command: name,
866
+ isGpuOrMlAttributed: isGpuOrMl
867
+ });
868
+ }
869
+ procs.sort((a, b) => b.cpu - a.cpu || b.mem - a.mem);
870
+ return procs;
871
+ }
872
+ async function collectWindowsProcesses(limit) {
873
+ try {
874
+ const raw = await runPowerShell(
875
+ `Get-CimInstance Win32_Process | Select-Object Name, ProcessId, ParentProcessId, ThreadCount, WorkingSetSize, UserModeTime, KernelModeTime, CommandLine | ConvertTo-Csv -NoTypeInformation`,
876
+ ""
877
+ );
878
+ const now = Date.now();
879
+ const totalMem = os.totalmem();
880
+ const procs = parseWindowsProcessCsv(raw, totalMem, winProcCache, now);
881
+ if (limit && limit > 0) return procs.slice(0, limit);
882
+ return procs;
883
+ } catch {
884
+ return [];
885
+ }
886
+ }
887
+ async function collectWindowsTasks(limit = 12) {
888
+ const procs = await collectWindowsProcesses(limit);
889
+ return procs.map((p) => ({
890
+ pid: p.pid,
891
+ user: p.user,
892
+ cpu: p.cpu,
893
+ mem: p.mem,
894
+ state: p.state,
895
+ runtime: p.runtime,
896
+ command: p.command
897
+ }));
898
+ }
899
+ async function getWindowsDisplayInfo() {
900
+ try {
901
+ const raw = await runPowerShell(
902
+ `Get-CimInstance Win32_VideoController | ForEach-Object { "$($_.Name)|$($_.VideoModeDescription)|$($_.VideoProcessor)" }`,
903
+ ""
904
+ );
905
+ const displays = [];
906
+ for (const line of raw.split("\n")) {
907
+ const parts = line.trim().split("|");
908
+ if (parts[0]) {
909
+ displays.push({
910
+ name: parts[0],
911
+ resolution: parts[1] || "Unknown",
912
+ isMain: displays.length === 0
913
+ });
914
+ }
915
+ }
916
+ return displays.length > 0 ? displays : [{ name: "Default Display", resolution: "1920x1080", isMain: true }];
917
+ } catch {
918
+ return [{ name: "Default Display", resolution: "1920x1080", isMain: true }];
919
+ }
920
+ }
921
+
922
+ export {
923
+ collectWindowsSystem,
924
+ collectWindowsCpu,
925
+ collectWindowsMemory,
926
+ collectWindowsDisk,
927
+ collectWindowsBattery,
928
+ collectWindowsThermal,
929
+ collectWindowsPower,
930
+ collectWindowsGpu,
931
+ collectWindowsNetwork,
932
+ collectWindowsPackets,
933
+ collectWindowsProcesses,
934
+ collectWindowsTasks,
935
+ getWindowsDisplayInfo
936
+ };