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 +2 -0
- package/dist/benchmarkCmd-A3ETK6VY.js +58 -0
- package/dist/checkCmd-ULNENOPZ.js +74 -0
- package/dist/chunk-MOAEGMFP.js +1042 -0
- package/dist/{chunk-QOLZ7T32.js → chunk-PV4MXTAJ.js} +46 -3
- package/dist/chunk-SG26Y3WF.js +0 -0
- package/dist/{collectors-VACLPHRP.js → collectors-VYUH3UWY.js} +1 -1
- package/dist/index.js +349 -1271
- package/dist/pipeCmd-BWNMUV2X.js +39 -0
- package/dist/prometheus-LFYHF6VO.js +56 -0
- package/dist/service-WTS3NBQU.js +73 -0
- package/dist/stressCmd-MFXMFXYX.js +51 -0
- package/dist/wizard-GVIAHIVV.js +55 -0
- package/package.json +1 -1
- package/src/benchmarkCmd.ts +69 -0
- package/src/checkCmd.ts +83 -0
- package/src/fleet.ts +17 -16
- package/src/formatters/render.ts +46 -9
- package/src/formatters/types.ts +2 -0
- package/src/index.ts +84 -7
- package/src/monitors/collectors.ts +50 -3
- package/src/monitors/types.ts +10 -0
- package/src/pipeCmd.ts +42 -0
- package/src/prometheus.ts +74 -0
- package/src/service.ts +77 -0
- package/src/stressCmd.ts +59 -0
- package/src/wizard.ts +61 -0
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
|
+
};
|