pyre-cli 1.3.0 → 1.4.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 +209 -16
- package/dist/index.js +735 -332
- package/package.json +5 -2
- package/parity.md +542 -0
- package/src/formatters/index.ts +17 -0
- package/src/formatters/output.ts +137 -0
- package/src/formatters/render.ts +468 -0
- package/src/formatters/themes.ts +115 -0
- package/src/formatters/types.ts +58 -0
- package/src/history.ts +115 -0
- package/src/index.ts +81 -0
- package/src/live/export.ts +73 -0
- package/src/live/index.ts +16 -0
- package/src/live/input.ts +311 -0
- package/src/live/render.ts +142 -0
- package/src/live/state.ts +83 -0
- package/src/live/types.ts +23 -0
- package/src/monitors/collectors.ts +484 -0
- package/src/monitors/index.ts +14 -0
- package/src/monitors/run.ts +18 -0
- package/src/monitors/smc.ts +107 -0
- package/src/monitors/types.ts +107 -0
- package/src/pyre_img +0 -0
- package/src/sparkline.ts +34 -0
- package/src/splash.ts +102 -0
- package/tsconfig.json +19 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core data types for system metric collection.
|
|
3
|
+
*
|
|
4
|
+
* Every interface in this file represents a distinct category of
|
|
5
|
+
* system information gathered by the monitors module. The
|
|
6
|
+
* {@link StatsData} aggregate ties them together for downstream
|
|
7
|
+
* formatting and export.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export interface StatsData {
|
|
11
|
+
header: { title: string; hostname: string; os: string; uptime: string };
|
|
12
|
+
cpu: CpuData;
|
|
13
|
+
gpu: GpuData | null;
|
|
14
|
+
memory: MemoryData;
|
|
15
|
+
disk: DiskData[];
|
|
16
|
+
battery: BatteryData | null;
|
|
17
|
+
thermal: ThermalData;
|
|
18
|
+
network: NetworkData;
|
|
19
|
+
processes: ProcessData[];
|
|
20
|
+
power: PowerData | null;
|
|
21
|
+
timestamp: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface GpuData {
|
|
25
|
+
model: string;
|
|
26
|
+
memory: number;
|
|
27
|
+
utilization: number;
|
|
28
|
+
temperature?: number;
|
|
29
|
+
processes: number;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface PowerData {
|
|
33
|
+
cpuWatts?: number;
|
|
34
|
+
gpuWatts?: number;
|
|
35
|
+
combinedWatts?: number;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface CpuData {
|
|
39
|
+
brand: string;
|
|
40
|
+
cores: number;
|
|
41
|
+
physicalCores: number;
|
|
42
|
+
frequency: number;
|
|
43
|
+
usage: number;
|
|
44
|
+
loadAvg: number[];
|
|
45
|
+
temperature?: number;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface MemoryData {
|
|
49
|
+
total: number;
|
|
50
|
+
used: number;
|
|
51
|
+
free: number;
|
|
52
|
+
swapTotal: number;
|
|
53
|
+
swapUsed: number;
|
|
54
|
+
swapFree: number;
|
|
55
|
+
pageSize: number;
|
|
56
|
+
usagePercent: number;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export interface ThermalData {
|
|
60
|
+
state: string;
|
|
61
|
+
detail?: string;
|
|
62
|
+
/** Normalized 0-3 scale (nominal/fair/serious/critical) derived from `state`, for graphing/coloring */
|
|
63
|
+
pressureLevel: number;
|
|
64
|
+
temperatures?: Record<string, number | null>;
|
|
65
|
+
error?: string;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface BatteryData {
|
|
69
|
+
level: number;
|
|
70
|
+
state: string;
|
|
71
|
+
timeRemaining: string;
|
|
72
|
+
health: string;
|
|
73
|
+
powerSource: string;
|
|
74
|
+
cycles?: number;
|
|
75
|
+
condition?: string;
|
|
76
|
+
maxCapacityPercent?: number;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface DiskData {
|
|
80
|
+
filesystem: string;
|
|
81
|
+
size: string;
|
|
82
|
+
used: string;
|
|
83
|
+
available: string;
|
|
84
|
+
capacity: string;
|
|
85
|
+
mountpoint: string;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export interface NetworkData {
|
|
89
|
+
interface: string;
|
|
90
|
+
ip: string;
|
|
91
|
+
rxBytes: number;
|
|
92
|
+
txBytes: number;
|
|
93
|
+
rxPackets: number;
|
|
94
|
+
txPackets: number;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export interface ProcessData {
|
|
98
|
+
pid: number;
|
|
99
|
+
ppid: number;
|
|
100
|
+
user: string;
|
|
101
|
+
cpu: number;
|
|
102
|
+
mem: number;
|
|
103
|
+
command: string;
|
|
104
|
+
state: string;
|
|
105
|
+
threads: number;
|
|
106
|
+
runtime: number;
|
|
107
|
+
}
|
package/src/pyre_img
ADDED
|
Binary file
|
package/src/sparkline.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const BLOCKS = '▁▂▃▄▅▆▇█';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Render a series of numbers as a compact unicode sparkline.
|
|
5
|
+
*
|
|
6
|
+
* Values are normalised against `min`/`max` (auto-computed
|
|
7
|
+
* from the data if not supplied). The output uses eight
|
|
8
|
+
* Unicode block characters to represent the range, making
|
|
9
|
+
* it suitable for inline terminal graphs.
|
|
10
|
+
*
|
|
11
|
+
* @param values - Numeric series to render.
|
|
12
|
+
* @param opts.min - Minimum value for normalisation.
|
|
13
|
+
* @param opts.max - Maximum value for normalisation.
|
|
14
|
+
* @returns A string of block characters whose length equals `values.length`.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* sparkline([10, 20, 15, 30, 25]); // "▁▂▃▅▄"
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export function sparkline(values: number[], opts: { min?: number; max?: number } = {}): string {
|
|
22
|
+
if (!values.length) return '';
|
|
23
|
+
const min = opts.min ?? Math.min(...values);
|
|
24
|
+
const max = opts.max ?? Math.max(...values);
|
|
25
|
+
const range = max - min || 1;
|
|
26
|
+
|
|
27
|
+
return values
|
|
28
|
+
.map(v => {
|
|
29
|
+
const idx = Math.round(((v - min) / range) * (BLOCKS.length - 1));
|
|
30
|
+
const clamped = Math.min(BLOCKS.length - 1, Math.max(0, idx));
|
|
31
|
+
return BLOCKS[clamped];
|
|
32
|
+
})
|
|
33
|
+
.join('');
|
|
34
|
+
}
|
package/src/splash.ts
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ASCII Splash Screen implementation based on the doom-fire effect.
|
|
3
|
+
*/
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
|
|
6
|
+
const MAXV = 36;
|
|
7
|
+
const CHAR_RAMP = [' ', '.', '`', ',', ':', ';', '+', '*', '?', '%', '#', '@'];
|
|
8
|
+
|
|
9
|
+
// Colors for the fire effect
|
|
10
|
+
const palette = [
|
|
11
|
+
'#0a0505', '#1a0806', '#2a0b06', '#3f1004', '#591404', '#791804', '#9e1c04', '#c92004',
|
|
12
|
+
'#d63004', '#e34004', '#f05004', '#fd6004', '#ff7004', '#ff8004', '#ff9004', '#ffa004',
|
|
13
|
+
'#ffb004', '#ffc004', '#ffd004', '#ffe004', '#fff004', '#fff820', '#ffff40', '#ffff60',
|
|
14
|
+
'#ffff80', '#ffffa0', '#ffffc0', '#ffffe0', '#ffffff', '#ffffff', '#ffffff', '#ffffff',
|
|
15
|
+
'#ffffff', '#ffffff', '#ffffff', '#ffffff'
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
function getRgb(hex: string) {
|
|
19
|
+
const r = parseInt(hex.slice(1, 3), 16);
|
|
20
|
+
const g = parseInt(hex.slice(3, 5), 16);
|
|
21
|
+
const b = parseInt(hex.slice(5, 7), 16);
|
|
22
|
+
return { r, g, b };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const rgbPalette = palette.map(getRgb);
|
|
26
|
+
|
|
27
|
+
function getChar(val: number) {
|
|
28
|
+
const idx = Math.min(CHAR_RAMP.length - 1, Math.floor((val / (MAXV + 1)) * CHAR_RAMP.length));
|
|
29
|
+
return CHAR_RAMP[idx];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export async function showSplash() {
|
|
33
|
+
const cols = 60;
|
|
34
|
+
const rows = 15;
|
|
35
|
+
let fire = new Uint8Array(cols * rows);
|
|
36
|
+
|
|
37
|
+
// Clear screen
|
|
38
|
+
process.stdout.write('\x1b[2J');
|
|
39
|
+
const termRows = process.stdout.rows || 24;
|
|
40
|
+
const termCols = process.stdout.columns || 80;
|
|
41
|
+
const startRow = Math.max(0, Math.floor((termRows - rows) / 2));
|
|
42
|
+
const startCol = Math.max(0, Math.floor((termCols - cols) / 2));
|
|
43
|
+
|
|
44
|
+
return new Promise<void>((resolve) => {
|
|
45
|
+
const interval = setInterval(() => {
|
|
46
|
+
// Bottom row heat
|
|
47
|
+
for (let x = 0; x < cols; x++) {
|
|
48
|
+
fire[(rows - 1) * cols + x] = MAXV - Math.floor(Math.random() * 4);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Spread fire
|
|
52
|
+
for (let y = rows - 1; y >= 1; y--) {
|
|
53
|
+
for (let x = 0; x < cols; x++) {
|
|
54
|
+
const src = y * cols + x;
|
|
55
|
+
const val = fire[src];
|
|
56
|
+
if (val === 0) {
|
|
57
|
+
fire[(y - 1) * cols + x] = 0;
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
const decay = Math.floor(Math.random() * 3);
|
|
61
|
+
const drift = Math.floor(Math.random() * 3) - 1;
|
|
62
|
+
let nx = x + drift;
|
|
63
|
+
if (nx < 0) nx = 0; else if (nx >= cols) nx = cols - 1;
|
|
64
|
+
fire[(y - 1) * cols + nx] = Math.max(0, val - decay);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Draw
|
|
69
|
+
let output = '';
|
|
70
|
+
for (let i = 0; i < startRow; i++) output += '\n';
|
|
71
|
+
|
|
72
|
+
for (let y = 0; y < rows; y++) {
|
|
73
|
+
output += ' '.repeat(startCol);
|
|
74
|
+
for (let x = 0; x < cols; x++) {
|
|
75
|
+
const v = fire[y * cols + x];
|
|
76
|
+
const color = rgbPalette[Math.min(v, rgbPalette.length - 1)];
|
|
77
|
+
output += chalk.rgb(color.r, color.g, color.b)(getChar(v));
|
|
78
|
+
}
|
|
79
|
+
output += '\n';
|
|
80
|
+
}
|
|
81
|
+
output += ' '.repeat(Math.max(0, startCol + (cols - 45) / 2)) + chalk.bold.white('🔥 pyre — system monitor (warming up sensors...)\n');
|
|
82
|
+
output += ' '.repeat(Math.max(0, startCol + (cols - 25) / 2)) + chalk.dim('[Press Enter to continue]');
|
|
83
|
+
|
|
84
|
+
// Clear viewport area and redraw
|
|
85
|
+
process.stdout.write(`\x1b[H${output}`);
|
|
86
|
+
}, 65);
|
|
87
|
+
|
|
88
|
+
const onEnter = () => {
|
|
89
|
+
process.stdin.removeListener('data', onEnter);
|
|
90
|
+
clearInterval(interval);
|
|
91
|
+
process.stdout.write('\x1b[2J\x1b[H');
|
|
92
|
+
resolve();
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
process.stdin.setRawMode(true);
|
|
96
|
+
process.stdin.resume();
|
|
97
|
+
process.stdin.on('data', onEnter);
|
|
98
|
+
|
|
99
|
+
// Auto-exit after 5s
|
|
100
|
+
setTimeout(onEnter, 5000);
|
|
101
|
+
});
|
|
102
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ES2022",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"outDir": "./dist",
|
|
7
|
+
"rootDir": "./src",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"forceConsistentCasingInFileNames": true,
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"declaration": false,
|
|
14
|
+
"sourceMap": false,
|
|
15
|
+
"noEmit": false
|
|
16
|
+
},
|
|
17
|
+
"include": ["src/**/*"],
|
|
18
|
+
"exclude": ["node_modules", "dist"]
|
|
19
|
+
}
|