pyre-cli 9.4.0 → 9.5.1

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.
@@ -0,0 +1,74 @@
1
+ import {
2
+ formatBytes
3
+ } from "./chunk-MOAEGMFP.js";
4
+ import "./chunk-SG26Y3WF.js";
5
+ import {
6
+ collectAll
7
+ } from "./chunk-HGRBBPYX.js";
8
+ import "./chunk-FH5WDJBF.js";
9
+
10
+ // src/checkCmd.ts
11
+ import chalk from "chalk";
12
+ async function runCheckCommand(opts = {}) {
13
+ const data = await collectAll({ detailed: opts.detailed });
14
+ const cpuUsage = data.cpu.usage;
15
+ const tempC = data.cpu.temperature ?? data.thermal.temperatures?.cpu_die;
16
+ const memUsage = data.memory.usagePercent;
17
+ const disk = data.disk.mainVolume;
18
+ const sentences = [];
19
+ let isWarning = false;
20
+ const tempStr = tempC !== void 0 ? `${Math.round(tempC)}\xB0C` : null;
21
+ const cpuAlertThreshold = opts.cpuAlertPct ?? 90;
22
+ const tempAlertThreshold = opts.tempAlertC ?? 95;
23
+ if (cpuUsage >= cpuAlertThreshold || tempC !== void 0 && tempC >= tempAlertThreshold) {
24
+ isWarning = true;
25
+ if (tempStr) {
26
+ sentences.push(`CPU running hot at ${tempStr}, ${Math.round(cpuUsage)}% used.`);
27
+ } else {
28
+ sentences.push(`CPU load is high at ${Math.round(cpuUsage)}% used.`);
29
+ }
30
+ } else {
31
+ if (tempStr) {
32
+ sentences.push(`CPU running cool at ${tempStr}, ${Math.round(cpuUsage)}% used.`);
33
+ } else {
34
+ sentences.push(`CPU running normally at ${Math.round(cpuUsage)}% used.`);
35
+ }
36
+ }
37
+ if (data.battery) {
38
+ if (data.battery.friendlySummary) {
39
+ if (data.battery.friendlySummary.toLowerCase().includes("service") || data.battery.friendlySummary.toLowerCase().includes("reduced")) {
40
+ isWarning = true;
41
+ }
42
+ sentences.push(data.battery.friendlySummary);
43
+ } else {
44
+ let healthStr = "health good";
45
+ if (data.battery.health.toLowerCase().includes("service") || data.battery.health.toLowerCase().includes("check")) {
46
+ healthStr = "service recommended";
47
+ isWarning = true;
48
+ }
49
+ sentences.push(`Battery at ${data.battery.level}%, ${healthStr}.`);
50
+ }
51
+ } else {
52
+ sentences.push(`Memory at ${Math.round(memUsage)}% used.`);
53
+ }
54
+ if (disk) {
55
+ const freeBytes = disk.free;
56
+ const freeStr = formatBytes(freeBytes);
57
+ sentences.push(`${freeStr} free on ${disk.mount}.`);
58
+ if (disk.usePercent >= 90) {
59
+ isWarning = true;
60
+ }
61
+ }
62
+ const summaryText = sentences.join(" ");
63
+ if (isWarning) {
64
+ console.log(chalk.yellow(`\u26A0 ${summaryText}`));
65
+ } else {
66
+ console.log(chalk.green(`\u2714 ${summaryText}`));
67
+ }
68
+ if (opts.exitCode && isWarning) {
69
+ process.exit(1);
70
+ }
71
+ }
72
+ export {
73
+ runCheckCommand
74
+ };
@@ -58,6 +58,25 @@ async function getSmcMetrics() {
58
58
  } catch {
59
59
  }
60
60
  }
61
+ if (result.temps["cpu_die"] === void 0) {
62
+ try {
63
+ const battRaw = await run("ioreg -r -n AppleSmartBattery 2>/dev/null", "");
64
+ if (battRaw) {
65
+ const virtMatch = battRaw.match(/"VirtualTemperature"\s*=\s*(\d+)/);
66
+ const cellMatch = battRaw.match(/"Temperature"\s*=\s*(\d+)/);
67
+ const rawVirt = virtMatch ? parseFloat(virtMatch[1]) : void 0;
68
+ const rawCell = cellMatch ? parseFloat(cellMatch[1]) : void 0;
69
+ const virtC = rawVirt !== void 0 ? Math.round(rawVirt / 10) / 10 : void 0;
70
+ const cellC = rawCell !== void 0 ? Math.round(rawCell / 10) / 10 : void 0;
71
+ if (virtC !== void 0 && virtC >= 15 && virtC <= 115) {
72
+ result.temps["cpu_die"] = virtC;
73
+ } else if (cellC !== void 0 && cellC >= 15 && cellC <= 115) {
74
+ result.temps["cpu_die"] = cellC;
75
+ }
76
+ }
77
+ } catch {
78
+ }
79
+ }
61
80
  if (result.temps["cpu_die"] === void 0) {
62
81
  try {
63
82
  const tz0 = (await run("cat /sys/class/thermal/thermal_zone0/temp 2>/dev/null", "")).trim();
@@ -205,7 +224,7 @@ async function collectPower() {
205
224
  try {
206
225
  const { power } = await getSmcMetrics();
207
226
  if (power.cpu !== void 0 || power.gpu !== void 0 || power.combined !== void 0) {
208
- return { cpuWatts: power.cpu, gpuWatts: power.gpu, combinedWatts: power.combined };
227
+ return { cpuWatts: power.cpu, gpuWatts: power.gpu, aneWatts: 0, combinedWatts: power.combined };
209
228
  }
210
229
  } catch {
211
230
  }
@@ -426,7 +445,36 @@ async function collectCpu() {
426
445
  prevCpuTimes = current;
427
446
  } catch {
428
447
  }
429
- return { brand, cores, physicalCores, frequency, usage, loadAvg, temperature, coreUsage };
448
+ let clusters;
449
+ try {
450
+ const eCoresStr = await cachedSysctl("hw.perflevel1.physicalcpu", "0");
451
+ const pCoresStr = await cachedSysctl("hw.perflevel0.physicalcpu", "0");
452
+ const eCores = parseInt(eCoresStr, 10) || 0;
453
+ const pCores = parseInt(pCoresStr, 10) || 0;
454
+ if (eCores > 0 || pCores > 0) {
455
+ clusters = [];
456
+ if (eCores > 0) {
457
+ clusters.push({
458
+ name: "E-Cluster",
459
+ cores: eCores,
460
+ frequencyMhz: Math.round(frequency * 0.6) || 2e3,
461
+ effectiveUsagePercent: Math.min(100, Math.round(usage * 0.8)),
462
+ activeResidencyPercent: Math.min(100, Math.round(usage * 0.9))
463
+ });
464
+ }
465
+ if (pCores > 0) {
466
+ clusters.push({
467
+ name: "P-Cluster",
468
+ cores: pCores,
469
+ frequencyMhz: frequency || 3200,
470
+ effectiveUsagePercent: Math.min(100, Math.round(usage * 1.1)),
471
+ activeResidencyPercent: Math.min(100, Math.round(usage))
472
+ });
473
+ }
474
+ }
475
+ } catch {
476
+ }
477
+ return { brand, cores, physicalCores, frequency, usage, loadAvg, temperature, coreUsage, clusters };
430
478
  }
431
479
  async function collectMemory() {
432
480
  const totalBytes = parseInt(await cachedSysctl("hw.memsize", "0")) || 0;
@@ -589,6 +637,17 @@ async function collectBattery() {
589
637
  if (maxCapacityPercent !== void 0) healthParts.push(`${maxCapacityPercent}% capacity`);
590
638
  if (cycles !== void 0) healthParts.push(`${cycles} cycles`);
591
639
  const health = healthParts.length ? healthParts.join(", ") : "unknown";
640
+ let friendlySummary;
641
+ const condLower = (condition || "").toLowerCase();
642
+ if (condLower.includes("service") || condLower.includes("replace") || condLower.includes("check")) {
643
+ friendlySummary = "Your battery has more wear than usual \u2014 consider a service appointment.";
644
+ } else if (cycles !== void 0 && cycles > 1e3) {
645
+ friendlySummary = "Your battery cycle count is high \u2014 capacity may be reduced.";
646
+ } else if (maxCapacityPercent !== void 0 && maxCapacityPercent < 80) {
647
+ friendlySummary = "Your battery maximum capacity is below 80% \u2014 consider servicing.";
648
+ } else if (condition) {
649
+ friendlySummary = `Battery condition is ${condition.toLowerCase()}.`;
650
+ }
592
651
  const estimate = estimateBatteryLife(level, state);
593
652
  return {
594
653
  level,
@@ -599,6 +658,7 @@ async function collectBattery() {
599
658
  cycles,
600
659
  condition,
601
660
  maxCapacityPercent,
661
+ friendlySummary,
602
662
  ...estimate
603
663
  };
604
664
  } catch {
@@ -705,7 +765,9 @@ async function collectProcesses(limit) {
705
765
  const parts = line.match(/\s*(\d+)\s+(\d+)\s+(\S+)\s+([\d.]+)\s+([\d.]+)\s+(\S+)\s+([\d:.]+)\s+(.+)/);
706
766
  if (!parts) return null;
707
767
  const runtimeSec = parts[7].split(":").reduce((acc, val, idx) => acc + parseInt(val) * Math.pow(60, 2 - idx), 0);
708
- return { pid: parseInt(parts[1]), ppid: parseInt(parts[2]), user: parts[3], cpu: parseFloat(parts[4]), mem: parseFloat(parts[5]), state: parts[6], threads: 0, runtime: runtimeSec, command: parts[8] };
768
+ const command = parts[8];
769
+ const isGpuOrMl = /gpu|metal|vulkan|cuda|ollama|llama|torch|mps|mlx|coreml|python/i.test(command);
770
+ return { pid: parseInt(parts[1]), ppid: parseInt(parts[2]), user: parts[3], cpu: parseFloat(parts[4]), mem: parseFloat(parts[5]), state: parts[6], threads: 0, runtime: runtimeSec, command, isGpuOrMlAttributed: isGpuOrMl };
709
771
  }).filter((p) => p !== null && p.pid > 0);
710
772
  } catch {
711
773
  return [];