pyre-cli 10.4.0 → 10.6.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 (34) hide show
  1. package/dist/{blender-6ZX5SPYC.js → blender-OXH3PVYM.js} +3 -3
  2. package/dist/{brewHealth-VFW33QB3.js → brewHealth-JE4EZ63L.js} +1 -1
  3. package/dist/{buildCmd-E7KUCFYG.js → buildCmd-R6RY3XZR.js} +3 -3
  4. package/dist/{checkCmd-QLYTP77Y.js → checkCmd-KF6G77SC.js} +5 -5
  5. package/dist/{chunk-RKPGPVTO.js → chunk-2SUFLPIH.js} +5 -5
  6. package/dist/chunk-735X2GPS.js +88 -0
  7. package/dist/{chunk-QEH4LR6P.js → chunk-D3HWHU3X.js} +4 -4
  8. package/dist/{chunk-FYCBGUTW.js → chunk-GPSU54LZ.js} +2 -2
  9. package/dist/{chunk-NMGQVRCA.js → chunk-KLANOKZF.js} +2 -2
  10. package/dist/{chunk-OCL7P7N7.js → chunk-YXZ4XREM.js} +195 -111
  11. package/dist/{collectors-V7SCIIDH.js → collectors-DQEVTONN.js} +5 -5
  12. package/dist/{doctor-O4DIAMHK.js → doctor-SCHRYF6D.js} +2 -2
  13. package/dist/{extensions-QQEV7U3D.js → extensions-BWXMZVMN.js} +1 -1
  14. package/dist/{flightRecorder-GJIAQOXC.js → flightRecorder-J4TESP5M.js} +5 -5
  15. package/dist/index.js +55 -28
  16. package/dist/monitors/platform/windows-ui.ps1 +14 -4
  17. package/dist/{netUsageCmd-JP6YKBPF.js → netUsageCmd-2QVRC6FX.js} +5 -5
  18. package/dist/{optimizeCmd-WZKLFYZU.js → optimizeCmd-ZF7U3DXR.js} +2 -2
  19. package/dist/{pipeCmd-CPK6FVKB.js → pipeCmd-XBWAYRRU.js} +5 -5
  20. package/dist/{profileProcCmd-5Y3733E7.js → profileProcCmd-33YB4RXZ.js} +1 -1
  21. package/dist/{prometheusCmd-G2CSEZRQ.js → prometheusCmd-6PXZG73L.js} +5 -5
  22. package/dist/{run-UJQYT2TO.js → run-744KZ7CE.js} +1 -1
  23. package/dist/{serveCmd-KDPWLVQI.js → serveCmd-R2Y7O3XC.js} +5 -5
  24. package/dist/{smartCmd-2BJJ37GV.js → smartCmd-C33WRXA2.js} +1 -1
  25. package/dist/{statuslineCmd-EUKYRR2G.js → statuslineCmd-QPBGXC2G.js} +5 -5
  26. package/dist/{topoCmd-RTXQJ6XA.js → topoCmd-RVWFSPHE.js} +5 -5
  27. package/dist/{watchdogCmd-XM6OPTKM.js → watchdogCmd-346TXWWH.js} +6 -6
  28. package/package.json +1 -1
  29. package/src/index.ts +31 -2
  30. package/src/monitors/platform/windows-ui.ps1 +14 -4
  31. package/src/monitors/platform/windows.ts +225 -102
  32. package/src/monitors/run.ts +83 -7
  33. package/src/platform.test.ts +24 -0
  34. package/dist/chunk-MZO5QKUR.js +0 -32
@@ -1,11 +1,26 @@
1
1
  import {
2
2
  run,
3
3
  runPowerShell
4
- } from "./chunk-MZO5QKUR.js";
4
+ } from "./chunk-735X2GPS.js";
5
5
 
6
6
  // src/monitors/platform/windows.ts
7
7
  import os from "os";
8
8
  import path from "path";
9
+ import fs from "fs";
10
+ var PS_TTL_RULES = [
11
+ [/Win32_Battery|BatteryCycleCount|BatteryStatus/, 1e4],
12
+ [/Win32_Processor|Win32_VideoController|HardwareInformation|Win32_OperatingSystem/, 10 * 6e4],
13
+ [/GPUEngine/, 3e3],
14
+ [/LibreHardwareMonitor|OpenHardwareMonitor|MSAcpi_ThermalZone|Thermal Zone Information/, 2e4],
15
+ [/Win32_PageFileUsage|Win32_LogicalDisk/, 3e4],
16
+ [/Get-NetIPConfiguration/, 6e4],
17
+ [/Get-NetTCPConnection/, 5e3],
18
+ [/Get-Process\b/, 5e3]
19
+ ];
20
+ function runPowerShell2(script, fallback = "", timeout = 1e4) {
21
+ const rule = PS_TTL_RULES.find(([re]) => re.test(script));
22
+ return runPowerShell(script, fallback, timeout, rule ? rule[1] : 0);
23
+ }
9
24
  var prevNetSample = null;
10
25
  var emaLoadAvg = [0, 0, 0];
11
26
  var lastLoadTime = 0;
@@ -20,7 +35,7 @@ function safeParseInt(s, def = 0) {
20
35
  return Number.isFinite(n) ? n : def;
21
36
  }
22
37
  async function getCimRow(className) {
23
- const raw = await runPowerShell(
38
+ const raw = await runPowerShell2(
24
39
  `Get-CimInstance -ClassName ${className} -ErrorAction SilentlyContinue | Select-Object -Property * -ExcludeProperty CIM* | ConvertTo-Csv -NoTypeInformation`,
25
40
  ""
26
41
  );
@@ -151,45 +166,20 @@ async function collectWindowsCpu(prevCpuTimesRef) {
151
166
  };
152
167
  }
153
168
  async function getWindowsCpuTemperature() {
169
+ const script = [
170
+ `$t = $null`,
171
+ `foreach ($ns in 'root/LibreHardwareMonitor','root/OpenHardwareMonitor') {`,
172
+ ` if ($t) { break }`,
173
+ ` try { $v = Get-CimInstance -Namespace $ns -ClassName Sensor -Filter "SensorType = 'Temperature' and Name like '%CPU%'" -ErrorAction Stop | Select-Object -First 1 -ExpandProperty Value; if ($v) { $t = [double]$v } } catch {}`,
174
+ `}`,
175
+ `if (-not $t) { try { $k = Get-CimInstance -Namespace root/wmi -ClassName MSAcpi_ThermalZoneTemperature -ErrorAction Stop | Select-Object -First 1 -ExpandProperty CurrentTemperature; if ($k -gt 2732) { $t = ($k - 2732) / 10 } } catch {} }`,
176
+ `if (-not $t) { try { $k = Get-CimInstance -ClassName Win32_PerfFormattedData_Counters_ThermalZoneInformation -ErrorAction Stop | Where-Object { $_.Temperature -gt 273 -and $_.Temperature -lt 400 } | Select-Object -First 1 -ExpandProperty Temperature; if ($k) { $t = $k - 273.15 } } catch {} }`,
177
+ `if ($t) { [string]([math]::Round($t, 1)) }`
178
+ ].join("\n");
154
179
  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
- }
180
+ const raw = await runPowerShell2(script, "");
181
+ const val = safeParseFloat(raw.replace(",", "."));
182
+ if (val >= 15 && val <= 115) return Math.round(val * 10) / 10;
193
183
  } catch {
194
184
  }
195
185
  return void 0;
@@ -203,7 +193,7 @@ async function collectWindowsMemory() {
203
193
  let swapUsed = 0;
204
194
  let swapFree = 0;
205
195
  try {
206
- const rawPage = await runPowerShell(
196
+ const rawPage = await runPowerShell2(
207
197
  `Get-CimInstance Win32_PageFileUsage | ForEach-Object { "$($_.AllocatedBaseSize)|$($_.CurrentUsage)" }`,
208
198
  ""
209
199
  );
@@ -235,7 +225,7 @@ async function collectWindowsMemory() {
235
225
  }
236
226
  async function collectWindowsDisk() {
237
227
  try {
238
- const raw = await runPowerShell(
228
+ const raw = await runPowerShell2(
239
229
  `Get-CimInstance Win32_LogicalDisk -Filter "DriveType=3" | ForEach-Object { "$($_.DeviceID)|$($_.FileSystem)|$($_.Size)|$($_.FreeSpace)" }`,
240
230
  ""
241
231
  );
@@ -265,18 +255,53 @@ async function collectWindowsDisk() {
265
255
  if (disks.length > 0) return disks;
266
256
  } catch {
267
257
  }
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
258
+ const fallback = [];
259
+ for (let code = 67; code <= 90; code++) {
260
+ const drive = `${String.fromCharCode(code)}:`;
261
+ try {
262
+ const st = fs.statfsSync?.(`${drive}\\`);
263
+ if (!st) break;
264
+ const totalBytes = Number(st.blocks) * Number(st.bsize);
265
+ const freeBytes = Number(st.bavail) * Number(st.bsize);
266
+ if (totalBytes > 0) {
267
+ const usedBytes = Math.max(0, totalBytes - freeBytes);
268
+ fallback.push({
269
+ filesystem: drive,
270
+ size: formatBytesStr(totalBytes),
271
+ used: formatBytesStr(usedBytes),
272
+ available: formatBytesStr(freeBytes),
273
+ capacity: `${Math.round(usedBytes / totalBytes * 100)}%`,
274
+ mountpoint: drive,
275
+ readBytesSec: 0,
276
+ writeBytesSec: 0
277
+ });
278
+ }
279
+ } catch {
278
280
  }
279
- ];
281
+ }
282
+ if (fallback.length === 0) {
283
+ try {
284
+ const st = fs.statfsSync?.(os.homedir());
285
+ const totalBytes = st ? Number(st.blocks) * Number(st.bsize) : 0;
286
+ const freeBytes = st ? Number(st.bavail) * Number(st.bsize) : 0;
287
+ if (totalBytes > 0) {
288
+ const usedBytes = Math.max(0, totalBytes - freeBytes);
289
+ const drive = path.parse(os.homedir()).root.replace(/[\\/]+$/, "") || "C:";
290
+ fallback.push({
291
+ filesystem: drive,
292
+ size: formatBytesStr(totalBytes),
293
+ used: formatBytesStr(usedBytes),
294
+ available: formatBytesStr(freeBytes),
295
+ capacity: `${Math.round(usedBytes / totalBytes * 100)}%`,
296
+ mountpoint: drive,
297
+ readBytesSec: 0,
298
+ writeBytesSec: 0
299
+ });
300
+ }
301
+ } catch {
302
+ }
303
+ }
304
+ return fallback;
280
305
  }
281
306
  function formatBytesStr(bytes) {
282
307
  if (bytes >= 1024 * 1024 * 1024 * 1024) return (bytes / (1024 * 1024 * 1024 * 1024)).toFixed(1) + "T";
@@ -284,35 +309,76 @@ function formatBytesStr(bytes) {
284
309
  if (bytes >= 1024 * 1024) return (bytes / (1024 * 1024)).toFixed(1) + "M";
285
310
  return (bytes / 1024).toFixed(0) + "K";
286
311
  }
312
+ function parseWindowsBatteryOutput(raw) {
313
+ const line = raw.split("\n").map((l) => l.trim()).find((l) => l.includes("|"));
314
+ if (!line) return null;
315
+ const p = line.split("|");
316
+ return {
317
+ level: safeParseInt(p[0], 0),
318
+ statusCode: safeParseInt(p[1], 1),
319
+ runTimeMinutes: safeParseInt(p[2], 0),
320
+ winDischargeRate: safeParseInt(p[3], 0),
321
+ cycles: safeParseInt(p[4], 0),
322
+ fullChargeMWh: safeParseInt(p[5], 0),
323
+ designMWh: safeParseInt(p[6], 0),
324
+ rateMilliwatts: safeParseInt(p[7], 0)
325
+ };
326
+ }
287
327
  async function collectWindowsBattery() {
288
328
  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";
329
+ const script = [
330
+ `$b = Get-CimInstance Win32_Battery -ErrorAction SilentlyContinue | Select-Object -First 1`,
331
+ `if ($b) {`,
332
+ ` $cyc = (Get-CimInstance -Namespace root/wmi -ClassName BatteryCycleCount -ErrorAction SilentlyContinue | Select-Object -First 1).CycleCount`,
333
+ ` $full = (Get-CimInstance -Namespace root/wmi -ClassName BatteryFullChargedCapacity -ErrorAction SilentlyContinue | Select-Object -First 1).FullChargedCapacity`,
334
+ ` $des = (Get-CimInstance -Namespace root/wmi -ClassName BatteryStaticData -ErrorAction SilentlyContinue | Select-Object -First 1).DesignedCapacity`,
335
+ ` $st = Get-CimInstance -Namespace root/wmi -ClassName BatteryStatus -ErrorAction SilentlyContinue | Select-Object -First 1`,
336
+ ` $rate = 0; if ($st) { if ($st.Charging) { $rate = $st.ChargeRate } elseif ($st.Discharging) { $rate = $st.DischargeRate } }`,
337
+ ` "$($b.EstimatedChargeRemaining)|$($b.BatteryStatus)|$($b.EstimatedRunTime)|$($b.DischargeRate)|$cyc|$full|$des|$rate"`,
338
+ `}`
339
+ ].join("\n");
340
+ const raw = await runPowerShell2(script, "");
341
+ const b = parseWindowsBatteryOutput(raw);
342
+ if (!b) return null;
343
+ const charging = [2, 6, 7, 8, 9].includes(b.statusCode);
344
+ const onAc = [2, 3, 6, 7, 8, 9, 11].includes(b.statusCode);
345
+ const powerSource = onAc ? "AC" : "Battery";
346
+ const state = b.statusCode === 3 || onAc && b.level >= 100 ? "charged" : charging ? "charging" : "discharging";
301
347
  let timeRemaining = "calculating";
302
348
  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;
349
+ else if (state === "discharging" && b.runTimeMinutes > 0 && b.runTimeMinutes < 7e4) {
350
+ const h = Math.floor(b.runTimeMinutes / 60);
351
+ const m = b.runTimeMinutes % 60;
306
352
  timeRemaining = `${h}:${m.toString().padStart(2, "0")}`;
307
353
  }
308
- const powerWatts = dischargeRate > 0 ? Math.round(dischargeRate / 1e3 * 100) / 100 : void 0;
354
+ const rateMw = Math.abs(b.rateMilliwatts) > 0 && Math.abs(b.rateMilliwatts) < 4e5 ? Math.abs(b.rateMilliwatts) : b.winDischargeRate;
355
+ const powerWatts = rateMw > 0 ? Math.round(rateMw / 1e3 * 100) / 100 : void 0;
356
+ let maxCapacityPercent;
357
+ if (b.designMWh > 0 && b.fullChargeMWh > 0) {
358
+ maxCapacityPercent = Math.min(100, Math.round(b.fullChargeMWh / b.designMWh * 100));
359
+ }
360
+ const cycles = b.cycles > 0 && b.cycles < 1e5 ? b.cycles : void 0;
361
+ let health = "Good";
362
+ let condition = "Normal";
363
+ if (maxCapacityPercent !== void 0) {
364
+ if (maxCapacityPercent < 60) {
365
+ health = "Poor";
366
+ condition = "Service Recommended";
367
+ } else if (maxCapacityPercent < 80) {
368
+ health = "Fair";
369
+ condition = "Reduced Capacity";
370
+ }
371
+ }
309
372
  return {
310
- level,
373
+ level: b.level,
311
374
  state,
312
375
  timeRemaining,
313
- health: "Good",
376
+ health,
314
377
  powerSource,
315
- powerWatts
378
+ powerWatts,
379
+ cycles,
380
+ condition,
381
+ maxCapacityPercent
316
382
  };
317
383
  } catch {
318
384
  return null;
@@ -333,7 +399,7 @@ async function collectWindowsThermal() {
333
399
  }
334
400
  if (gpuTemp === void 0) {
335
401
  try {
336
- const lhmGpu = await runPowerShell(
402
+ const lhmGpu = await runPowerShell2(
337
403
  `Get-CimInstance -Namespace root/LibreHardwareMonitor -ClassName Sensor -Filter "SensorType = 'Temperature' and Name like '%GPU%'" -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty Value`,
338
404
  ""
339
405
  );
@@ -370,7 +436,7 @@ async function collectWindowsThermal() {
370
436
  async function collectWindowsPower() {
371
437
  const power = {};
372
438
  try {
373
- const batRaw = await runPowerShell(
439
+ const batRaw = await runPowerShell2(
374
440
  `$bat = Get-CimInstance Win32_Battery -ErrorAction SilentlyContinue; if ($bat) { "$($bat.DischargeRate)|$($bat.BatteryStatus)" } else { '|0' }`,
375
441
  ""
376
442
  );
@@ -383,13 +449,13 @@ async function collectWindowsPower() {
383
449
  } catch {
384
450
  }
385
451
  try {
386
- const lhmCpu = await runPowerShell(
452
+ const lhmCpu = await runPowerShell2(
387
453
  `Get-CimInstance -Namespace root/LibreHardwareMonitor -ClassName Sensor -Filter "SensorType = 'Power' and Name like '%CPU Package%'" -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty Value`,
388
454
  ""
389
455
  );
390
456
  const cpuP = safeParseFloat(lhmCpu);
391
457
  if (cpuP > 0) power.cpuWatts = Math.round(cpuP * 100) / 100;
392
- const lhmGpu = await runPowerShell(
458
+ const lhmGpu = await runPowerShell2(
393
459
  `Get-CimInstance -Namespace root/LibreHardwareMonitor -ClassName Sensor -Filter "SensorType = 'Power' and Name like '%GPU%'" -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty Value`,
394
460
  ""
395
461
  );
@@ -430,7 +496,13 @@ async function collectWindowsPower() {
430
496
  }
431
497
  return null;
432
498
  }
499
+ var nvidiaSmiPathCache = null;
500
+ var NVIDIA_SMI_NEGATIVE_TTL_MS = 5 * 60 * 1e3;
433
501
  async function findNvidiaSmiPath() {
502
+ if (nvidiaSmiPathCache) {
503
+ if (nvidiaSmiPathCache.path) return nvidiaSmiPathCache.path;
504
+ if (Date.now() - nvidiaSmiPathCache.checkedAt < NVIDIA_SMI_NEGATIVE_TTL_MS) return "nvidia-smi";
505
+ }
434
506
  const commonPaths = [
435
507
  "nvidia-smi",
436
508
  path.join(process.env.ProgramFiles || "C:\\Program Files", "NVIDIA Corporation", "NVSMI", "nvidia-smi.exe"),
@@ -439,14 +511,19 @@ async function findNvidiaSmiPath() {
439
511
  for (const p of commonPaths) {
440
512
  try {
441
513
  const test = await run(`"${p}" -L 2>nul`, "");
442
- if (test.includes("GPU 0:")) return p;
514
+ if (test.includes("GPU 0:")) {
515
+ nvidiaSmiPathCache = { path: p, checkedAt: Date.now() };
516
+ return p;
517
+ }
443
518
  } catch {
444
519
  }
445
520
  }
521
+ nvidiaSmiPathCache = { path: null, checkedAt: Date.now() };
446
522
  return "nvidia-smi";
447
523
  }
448
524
  async function runNvidiaSmiQuery(query) {
449
525
  const smiPath = await findNvidiaSmiPath();
526
+ if (nvidiaSmiPathCache && nvidiaSmiPathCache.path === null) return "";
450
527
  return (await run(`"${smiPath}" --query-gpu=${query} --format=csv,noheader,nounits 2>nul`, "")).trim();
451
528
  }
452
529
  function parseNvidiaSmiOutput(csv) {
@@ -509,33 +586,31 @@ function parseWindowsVideoControllers(csvRaw) {
509
586
  }
510
587
  return controllers;
511
588
  }
589
+ function isVirtualGpuName(name) {
590
+ return /microsoft basic|remote display|hyper-v|virtual|vmware|virtualbox|parsec|citrix|indirect display|displaylink/i.test(name);
591
+ }
592
+ function isDiscreteGpuName(name) {
593
+ const n = name.toLowerCase();
594
+ if (isVirtualGpuName(n)) return false;
595
+ return /\b(rtx|gtx|geforce|quadro|titan|tesla)\b/.test(n) || /\bnvidia\b/.test(n) || /radeon\s+(rx|pro|vii|r[5-9]|hd)\b/.test(n) || /\bfirepro\b/.test(n) || /\barc\b/.test(n) && /\b(a\d{3}|b\d{3}|pro)\b/.test(n);
596
+ }
512
597
  function prioritizeGpuControllers(controllers) {
598
+ const rank = (c) => isVirtualGpuName(c.name) ? 2 : isDiscreteGpuName(c.name) ? 0 : 1;
513
599
  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;
600
+ const ra = rank(a);
601
+ const rb = rank(b);
602
+ if (ra !== rb) return ra - rb;
520
603
  return b.adapterRam - a.adapterRam;
521
604
  });
522
605
  }
523
- async function getWindowsGpu64BitVram() {
606
+ async function getWindowsGpu64BitVram(adapterName) {
524
607
  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`,
608
+ const safeName = (adapterName || "").replace(/'/g, "''");
609
+ const raw = await runPowerShell2(
610
+ `$name = '${safeName}'; $items = Get-ItemProperty -Path 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Class\\{4d36e968-e325-11ce-bfc1-08002be10318}\\0*' -ErrorAction SilentlyContinue | Where-Object { $_.'HardwareInformation.qwMemorySize' -gt 0 }; $pick = $items | Where-Object { $name -and $_.DriverDesc -eq $name } | Select-Object -First 1; if (-not $pick) { $pick = $items | Sort-Object -Property 'HardwareInformation.qwMemorySize' -Descending | Select-Object -First 1 }; if ($pick) { [string][uint64]$pick.'HardwareInformation.qwMemorySize' }`,
527
611
  ""
528
612
  );
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);
613
+ const bytes = safeParseFloat(raw.trim());
539
614
  if (bytes > 0) return bytes;
540
615
  } catch {
541
616
  }
@@ -543,8 +618,8 @@ async function getWindowsGpu64BitVram() {
543
618
  }
544
619
  async function getWindowsGpu3dUtilization() {
545
620
  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' }`,
621
+ const raw = await runPowerShell2(
622
+ `$samples = Get-CimInstance Win32_PerfFormattedData_GPUPerformanceCounters_GPUEngine -ErrorAction SilentlyContinue | Where-Object { $_.Name -like '*engtype_3D*' }; if ($samples) { $activePids = $samples | Where-Object { $_.UtilizationPercentage -gt 0 } | ForEach-Object { if ($_.Name -match 'pid_(\\d+)') { $matches[1] } } | Select-Object -Unique; $total = ($samples | Measure-Object -Property UtilizationPercentage -Sum).Sum; "$total|$(@($activePids).Count)" } else { '0|0' }`,
548
623
  "0|0"
549
624
  );
550
625
  const [utilStr, procCountStr] = raw.split("|");
@@ -559,7 +634,7 @@ async function collectWindowsGpu() {
559
634
  const nv = await getNvidiaGpu();
560
635
  if (nv) return nv;
561
636
  try {
562
- const rawControllers = await runPowerShell(
637
+ const rawControllers = await runPowerShell2(
563
638
  `Get-CimInstance Win32_VideoController | Select-Object Name, AdapterRAM, DriverVersion, VideoProcessor, PNPDeviceID | ConvertTo-Csv -NoTypeInformation`,
564
639
  ""
565
640
  );
@@ -567,14 +642,14 @@ async function collectWindowsGpu() {
567
642
  if (controllers.length === 0) return null;
568
643
  const prioritized = prioritizeGpuControllers(controllers);
569
644
  const bestController = prioritized[0];
570
- let vramBytes = await getWindowsGpu64BitVram();
645
+ let vramBytes = await getWindowsGpu64BitVram(bestController.name);
571
646
  if (vramBytes === 0 && bestController.adapterRam > 0) {
572
647
  vramBytes = bestController.adapterRam;
573
648
  }
574
649
  const { utilization, processCount } = await getWindowsGpu3dUtilization();
575
650
  let temperature;
576
651
  try {
577
- const rawTemp = await runPowerShell(
652
+ const rawTemp = await runPowerShell2(
578
653
  `Get-CimInstance -Namespace root/LibreHardwareMonitor -ClassName Sensor -Filter "SensorType = 'Temperature' and Name like '%GPU%'" -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty Value`,
579
654
  ""
580
655
  );
@@ -632,7 +707,7 @@ async function collectWindowsNetwork() {
632
707
  let rxPackets = 0;
633
708
  let txPackets = 0;
634
709
  try {
635
- const raw = await runPowerShell(
710
+ const raw = await runPowerShell2(
636
711
  `Get-NetIPConfiguration -AddressFamily IPv4 -ErrorAction SilentlyContinue | Where-Object { $_.NetAdapter.Status -eq 'Up' } | Select-Object -First 1 -ExpandProperty NetAdapter.Name`,
637
712
  ""
638
713
  );
@@ -689,7 +764,7 @@ async function getWindowsSocketDetails() {
689
764
  const listeningPorts = [];
690
765
  const topRemoteHosts = [];
691
766
  try {
692
- const raw = await runPowerShell(
767
+ const raw = await runPowerShell2(
693
768
  `$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
769
  "#"
695
770
  );
@@ -719,7 +794,7 @@ async function getWindowsSocketDetails() {
719
794
  async function getWindowsConnectionStates() {
720
795
  const stats = { established: 0, listening: 0, timeWait: 0, closeWait: 0, other: 0 };
721
796
  try {
722
- const raw = await runPowerShell(
797
+ const raw = await runPowerShell2(
723
798
  `$c = Get-NetTCPConnection -ErrorAction SilentlyContinue; if ($c) { $groups = $c | Group-Object State; ($groups | ForEach-Object { "$($_.Name)=$($_.Count)" }) -join '|' } else { '' }`,
724
799
  ""
725
800
  );
@@ -789,12 +864,12 @@ async function collectWindowsPackets() {
789
864
  const { listeningPorts } = await getWindowsSocketDetails();
790
865
  let allProcesses = [];
791
866
  try {
792
- const rawConns = await runPowerShell(
867
+ const rawConns = await runPowerShell2(
793
868
  `Get-NetTCPConnection -State Established,Listen -ErrorAction SilentlyContinue | Select-Object LocalPort, RemoteAddress, RemotePort, State, OwningProcess | ConvertTo-Csv -NoTypeInformation`,
794
869
  ""
795
870
  );
796
871
  const conns = parseWindowsTcpConnections(rawConns);
797
- const rawProcs = await runPowerShell(
872
+ const rawProcs = await runPowerShell2(
798
873
  `Get-Process -ErrorAction SilentlyContinue | Select-Object Id, ProcessName | ForEach-Object { "$($_.Id)|$($_.ProcessName)" }`,
799
874
  ""
800
875
  );
@@ -869,17 +944,26 @@ function parseWindowsProcessCsv(csvRaw, totalMem, cache, now) {
869
944
  procs.sort((a, b) => b.cpu - a.cpu || b.mem - a.mem);
870
945
  return procs;
871
946
  }
947
+ var procListMemo = null;
948
+ var PROC_MEMO_MS = 1500;
872
949
  async function collectWindowsProcesses(limit) {
950
+ const now0 = Date.now();
951
+ if (!procListMemo || now0 - procListMemo.ts > PROC_MEMO_MS) {
952
+ procListMemo = { ts: now0, promise: queryWindowsProcesses() };
953
+ }
954
+ const procs = await procListMemo.promise;
955
+ if (limit && limit > 0) return procs.slice(0, limit);
956
+ return procs;
957
+ }
958
+ async function queryWindowsProcesses() {
873
959
  try {
874
- const raw = await runPowerShell(
960
+ const raw = await runPowerShell2(
875
961
  `Get-CimInstance Win32_Process | Select-Object Name, ProcessId, ParentProcessId, ThreadCount, WorkingSetSize, UserModeTime, KernelModeTime, CommandLine | ConvertTo-Csv -NoTypeInformation`,
876
962
  ""
877
963
  );
878
964
  const now = Date.now();
879
965
  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;
966
+ return parseWindowsProcessCsv(raw, totalMem, winProcCache, now);
883
967
  } catch {
884
968
  return [];
885
969
  }
@@ -898,7 +982,7 @@ async function collectWindowsTasks(limit = 12) {
898
982
  }
899
983
  async function getWindowsDisplayInfo() {
900
984
  try {
901
- const raw = await runPowerShell(
985
+ const raw = await runPowerShell2(
902
986
  `Get-CimInstance Win32_VideoController | ForEach-Object { "$($_.Name)|$($_.VideoModeDescription)|$($_.VideoProcessor)" }`,
903
987
  ""
904
988
  );
@@ -15,11 +15,11 @@ import {
15
15
  collectThermal,
16
16
  getDisplayInfo,
17
17
  getTimeMachineStatus
18
- } from "./chunk-QEH4LR6P.js";
19
- import "./chunk-NMGQVRCA.js";
20
- import "./chunk-FYCBGUTW.js";
21
- import "./chunk-OCL7P7N7.js";
22
- import "./chunk-MZO5QKUR.js";
18
+ } from "./chunk-D3HWHU3X.js";
19
+ import "./chunk-KLANOKZF.js";
20
+ import "./chunk-GPSU54LZ.js";
21
+ import "./chunk-YXZ4XREM.js";
22
+ import "./chunk-735X2GPS.js";
23
23
  import "./chunk-3RG5ZIWI.js";
24
24
  export {
25
25
  collectAll,
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  printDoctorReport,
3
3
  runDoctor
4
- } from "./chunk-RKPGPVTO.js";
5
- import "./chunk-MZO5QKUR.js";
4
+ } from "./chunk-2SUFLPIH.js";
5
+ import "./chunk-735X2GPS.js";
6
6
  import "./chunk-LDJB5V4N.js";
7
7
  import "./chunk-3RG5ZIWI.js";
8
8
  export {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  run
3
- } from "./chunk-MZO5QKUR.js";
3
+ } from "./chunk-735X2GPS.js";
4
4
  import "./chunk-3RG5ZIWI.js";
5
5
 
6
6
  // src/extensions.ts
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  collectAll
3
- } from "./chunk-QEH4LR6P.js";
4
- import "./chunk-NMGQVRCA.js";
5
- import "./chunk-FYCBGUTW.js";
6
- import "./chunk-OCL7P7N7.js";
7
- import "./chunk-MZO5QKUR.js";
3
+ } from "./chunk-D3HWHU3X.js";
4
+ import "./chunk-KLANOKZF.js";
5
+ import "./chunk-GPSU54LZ.js";
6
+ import "./chunk-YXZ4XREM.js";
7
+ import "./chunk-735X2GPS.js";
8
8
  import "./chunk-3RG5ZIWI.js";
9
9
 
10
10
  // src/flightRecorder.ts