pyre-cli 9.3.0 → 9.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.
package/README.md CHANGED
@@ -85,6 +85,7 @@ pyre profile save dev # Save active configuration profile
85
85
  pyre profile load dev # Load configuration profile
86
86
  pyre info # Concise hardware, display & Time Machine overview
87
87
  pyre bench "make build" # Benchmark command & estimate kWh energy cost
88
+ pyre benchmark # Run a 1-minute CPU benchmark calculating digits of PI
88
89
  ```
89
90
 
90
91
  ## Options Reference
@@ -150,6 +151,7 @@ These options apply to both static snapshots and `pyre live`, except where noted
150
151
  | Command | Description |
151
152
  |---|---|
152
153
  | `pyre bench <cmd>` | Log CPU, memory, network, power draw, and estimate kWh energy cost during command execution |
154
+ | `pyre benchmark` | Run a 1-minute CPU benchmark calculating digits of PI and score the system |
153
155
  | `pyre xbar` | Generate an xbar / SwiftBar menu bar plugin script for stats display |
154
156
 
155
157
  ### Remote & Multi-host monitoring
@@ -0,0 +1,58 @@
1
+ // src/benchmarkCmd.ts
2
+ import chalk from "chalk";
3
+ async function runBenchmarkCommand() {
4
+ console.log(chalk.bold("\n pyre CPU Benchmark"));
5
+ console.log(chalk.dim(" Calculating digits of Pi to benchmark single-core CPU performance."));
6
+ console.log(chalk.dim(" This will take exactly 1 minute. Please wait...\n"));
7
+ const durationMs = 60 * 1e3;
8
+ const endTime = Date.now() + durationMs;
9
+ let digitsCalculated = 0;
10
+ let q = 1n, r = 0n, t = 1n, k = 1n, n = 3n, l = 3n;
11
+ const spinnerChars = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
12
+ let spinnerIdx = 0;
13
+ const reportInterval = 250;
14
+ let lastReport = Date.now();
15
+ process.stdout.write("\x1B[?25l");
16
+ try {
17
+ while (Date.now() < endTime) {
18
+ for (let i = 0; i < 100; i++) {
19
+ if (4n * q + r - t < n * t) {
20
+ digitsCalculated++;
21
+ const nr = 10n * (r - n * t);
22
+ n = 10n * (3n * q + r) / t - 10n * n;
23
+ q *= 10n;
24
+ r = nr;
25
+ } else {
26
+ const nr = (2n * q + r) * l;
27
+ const nn = (q * (7n * k) + 2n + r * l) / (t * l);
28
+ q *= k;
29
+ t *= l;
30
+ l += 2n;
31
+ k += 1n;
32
+ n = nn;
33
+ r = nr;
34
+ }
35
+ }
36
+ const now = Date.now();
37
+ if (now - lastReport > reportInterval) {
38
+ const elapsed = Math.floor((now - (endTime - durationMs)) / 1e3);
39
+ const remaining = Math.max(0, 60 - elapsed);
40
+ process.stdout.write(`\r ${chalk.cyan(spinnerChars[spinnerIdx])} ${chalk.yellow(digitsCalculated)} digits calculated... ${remaining}s remaining `);
41
+ spinnerIdx = (spinnerIdx + 1) % spinnerChars.length;
42
+ lastReport = now;
43
+ await new Promise((resolve) => setImmediate(resolve));
44
+ }
45
+ }
46
+ } finally {
47
+ process.stdout.write("\x1B[?25h");
48
+ }
49
+ process.stdout.write("\r" + " ".repeat(60) + "\r");
50
+ console.log(chalk.green(` \u2714 Benchmark complete!`));
51
+ console.log(chalk.bold(` Digits calculated: ${chalk.cyan(digitsCalculated)}`));
52
+ const score = Math.floor(digitsCalculated);
53
+ console.log(chalk.bold(` pyre Score: ${chalk.green(score)}
54
+ `));
55
+ }
56
+ export {
57
+ runBenchmarkCommand
58
+ };
@@ -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-PV4MXTAJ.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
+ };