pyre-cli 3.1.0 → 3.3.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/dist/index.js CHANGED
@@ -2515,6 +2515,29 @@ function restartTicker() {
2515
2515
  if (state.intervalHandle) clearInterval(state.intervalHandle);
2516
2516
  state.intervalHandle = setInterval(tick, state.interval * 1e3);
2517
2517
  }
2518
+ async function doWarmup() {
2519
+ try {
2520
+ const data = await collectAll({ detailed: state.detailed, processLimit: processRowBudget() });
2521
+ state.lastData = data;
2522
+ const temp = data.cpu.temperature ?? data.thermal.temperatures?.cpu_die ?? null;
2523
+ state.history.push({
2524
+ cpuUsage: data.cpu.usage,
2525
+ memUsage: data.memory.usagePercent,
2526
+ temp,
2527
+ rxBytes: data.network.rxBytes,
2528
+ txBytes: data.network.txBytes,
2529
+ gpuUtil: data.gpu?.utilization,
2530
+ powerWatts: data.power?.combinedWatts ?? data.power?.cpuWatts ?? 0,
2531
+ rxPackets: data.network.rxPackets,
2532
+ txPackets: data.network.txPackets,
2533
+ connections: data.network.connections ?? 0
2534
+ });
2535
+ writeLogRow(data);
2536
+ checkAlerts(data);
2537
+ syncP2PEvents();
2538
+ } catch {
2539
+ }
2540
+ }
2518
2541
  async function tick() {
2519
2542
  if (state.paused) return;
2520
2543
  try {
@@ -2540,7 +2563,7 @@ async function tick() {
2540
2563
  } catch {
2541
2564
  }
2542
2565
  }
2543
- async function startLive(opts2) {
2566
+ async function startLive(opts2, splashPromise) {
2544
2567
  if (state.running) return;
2545
2568
  state.running = true;
2546
2569
  state.paused = false;
@@ -2551,6 +2574,10 @@ async function startLive(opts2) {
2551
2574
  state.termHeight = process.stdout.rows || 24;
2552
2575
  state.history.reset();
2553
2576
  state.history.setMaxLen(Math.max(20, Math.min(200, state.termWidth - 30)));
2577
+ const warmupPromise = doWarmup();
2578
+ if (splashPromise) {
2579
+ await splashPromise;
2580
+ }
2554
2581
  process.stdout.write("\x1B[?1049h");
2555
2582
  process.stdout.write("\x1B[?25l");
2556
2583
  process.stdout.write("\x1B[2J\x1B[H");
@@ -2558,7 +2585,8 @@ async function startLive(opts2) {
2558
2585
  if (state.mouseEnabled) {
2559
2586
  process.stdout.write("\x1B[?1000h");
2560
2587
  }
2561
- await tick();
2588
+ await warmupPromise;
2589
+ render();
2562
2590
  restartTicker();
2563
2591
  if (opts2.autoLog) startLogging();
2564
2592
  readline.emitKeypressEvents(process.stdin);
@@ -2947,8 +2975,9 @@ async function showSplash() {
2947
2975
  }
2948
2976
 
2949
2977
  // src/index.ts
2978
+ var pkg = JSON.parse(fs4.readFileSync(new URL("../package.json", import.meta.url), "utf-8"));
2950
2979
  var program = new Command();
2951
- program.name("pyre").version("2.0.0").description("Mac system monitoring CLI: interactive live dashboard, stats, graphs, export, packet monitor, battery predictor").option("-j, --json", "Output as JSON").option("-c, --csv", "Output as CSV").option("-t, --tsv", "Output as TSV").option("--detailed", "Include detailed system info and sensor readings").option("--interval <seconds>", "Refresh interval for live mode", "2").option("--once", "Show a single static snapshot instead of live feed").option("--out <file>", "Also write the snapshot output to a file (--once/--json/--csv/--tsv modes)").option("--export-dir <dir>", "Directory used for live-mode snapshot exports and logs", "./pyre-exports").option("--log", "Start continuous CSV logging immediately when live mode starts").option("--tree", "Show process tree view instead of flat list").option("--sort <key>", "Sort processes by: cpu, mem, pid, user, command, state, threads, runtime", "cpu").option("--packets", "Include packet monitor panel in output").option("--limit <n>", "Max number of processes to include in --once/--json/--csv/--tsv snapshots (0 = all)", "10").option("--p2p-host <host>", "P2P host address (server: bind address, client: server address)", "0.0.0.0").option("--p2p-port <port>", "P2P port number", "9876").option("--p2p-password <password>", "Password for P2P authentication").option("--p2p-tls", "Enable TLS encryption for P2P connections").option("--p2p-cert <file>", "TLS certificate file (PEM) for P2P server").option("--p2p-key <file>", "TLS private key file (PEM) for P2P server").option("--p2p-ca <file>", "TLS CA certificate file (PEM) for P2P client").option("--p2p-insecure", "Skip TLS certificate verification (client only)").option("--p2p-rate-limit <n>", "Max auth attempts per IP per minute (default: 5)", "5").option("--p2p-allow <ips>", "Comma-separated list of allowed IPs (empty = all)").option("--p2p-deny <ips>", "Comma-separated list of denied IPs").option("--p2p-audit-log <dir>", "Directory for P2P audit logs").option("--p2p-hmac-key <key>", "HMAC key for message signing (default: derived from password)");
2980
+ program.name("pyre").version(pkg.version).description("Mac system monitoring CLI: interactive live dashboard, stats, graphs, export, packet monitor, battery predictor").option("-j, --json", "Output as JSON").option("-c, --csv", "Output as CSV").option("-t, --tsv", "Output as TSV").option("--detailed", "Include detailed system info and sensor readings").option("--interval <seconds>", "Refresh interval for live mode", "2").option("--once", "Show a single static snapshot instead of live feed").option("--out <file>", "Also write the snapshot output to a file (--once/--json/--csv/--tsv modes)").option("--export-dir <dir>", "Directory used for live-mode snapshot exports and logs", "./pyre-exports").option("--log", "Start continuous CSV logging immediately when live mode starts").option("--tree", "Show process tree view instead of flat list").option("--sort <key>", "Sort processes by: cpu, mem, pid, user, command, state, threads, runtime", "cpu").option("--packets", "Include packet monitor panel in output").option("--limit <n>", "Max number of processes to include in --once/--json/--csv/--tsv snapshots (0 = all)", "10").option("--p2p-host <host>", "P2P host address (server: bind address, client: server address)", "0.0.0.0").option("--p2p-port <port>", "P2P port number", "9876").option("--p2p-password <password>", "Password for P2P authentication").option("--p2p-tls", "Enable TLS encryption for P2P connections").option("--p2p-cert <file>", "TLS certificate file (PEM) for P2P server").option("--p2p-key <file>", "TLS private key file (PEM) for P2P server").option("--p2p-ca <file>", "TLS CA certificate file (PEM) for P2P client").option("--p2p-insecure", "Skip TLS certificate verification (client only)").option("--p2p-rate-limit <n>", "Max auth attempts per IP per minute (default: 5)", "5").option("--p2p-allow <ips>", "Comma-separated list of allowed IPs (empty = all)").option("--p2p-deny <ips>", "Comma-separated list of denied IPs").option("--p2p-audit-log <dir>", "Directory for P2P audit logs").option("--p2p-hmac-key <key>", "HMAC key for message signing (default: derived from password)");
2952
2981
  program.parse(process.argv);
2953
2982
  var opts = program.opts();
2954
2983
  function isExportMode() {
@@ -2963,14 +2992,14 @@ async function main() {
2963
2992
  if (cmd === "live") {
2964
2993
  program.args.shift();
2965
2994
  }
2966
- await showSplash();
2995
+ const splashPromise = showSplash();
2967
2996
  const interval = parseFloat(opts.interval) || 2;
2968
2997
  await startLive({
2969
2998
  interval,
2970
2999
  detailed: opts.detailed,
2971
3000
  exportDir: opts.exportDir,
2972
3001
  autoLog: opts.log
2973
- });
3002
+ }, splashPromise);
2974
3003
  return;
2975
3004
  }
2976
3005
  if (cmd === "p2p") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pyre-cli",
3
- "version": "3.1.0",
3
+ "version": "3.3.0",
4
4
  "description": "CLI Mac monitoring tool: temps, system stats, live dashboard, packet monitor, battery predictor, export",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
package/src/index.ts CHANGED
@@ -16,11 +16,13 @@ import { startLive, stopLive } from './live/index.js';
16
16
  import { showSplash } from './splash.js';
17
17
  import { P2PServer, P2PClient } from './p2p/index.js';
18
18
 
19
+ const pkg = JSON.parse(fs.readFileSync(new URL('../package.json', import.meta.url), 'utf-8'));
20
+
19
21
  const program = new Command();
20
22
 
21
23
  program
22
24
  .name('pyre')
23
- .version('2.0.0')
25
+ .version(pkg.version)
24
26
  .description('Mac system monitoring CLI: interactive live dashboard, stats, graphs, export, packet monitor, battery predictor')
25
27
  .option('-j, --json', 'Output as JSON')
26
28
  .option('-c, --csv', 'Output as CSV')
@@ -69,14 +71,14 @@ async function main() {
69
71
  if (cmd === 'live') {
70
72
  program.args.shift();
71
73
  }
72
- await showSplash();
74
+ const splashPromise = showSplash();
73
75
  const interval = parseFloat(opts.interval) || 2;
74
76
  await startLive({
75
77
  interval,
76
78
  detailed: opts.detailed,
77
79
  exportDir: opts.exportDir,
78
80
  autoLog: opts.log,
79
- });
81
+ }, splashPromise);
80
82
  return;
81
83
  }
82
84
 
package/src/live/input.ts CHANGED
@@ -199,6 +199,33 @@ function killProcess(pidStr: string, signal: string = 'SIGTERM') {
199
199
  state.intervalHandle = setInterval(tick, state.interval * 1000);
200
200
  }
201
201
 
202
+ async function doWarmup() {
203
+ try {
204
+ const data = await collectAll({ detailed: state.detailed, processLimit: processRowBudget() });
205
+ state.lastData = data;
206
+
207
+ const temp = data.cpu.temperature ?? data.thermal.temperatures?.cpu_die ?? null;
208
+ state.history.push({
209
+ cpuUsage: data.cpu.usage,
210
+ memUsage: data.memory.usagePercent,
211
+ temp,
212
+ rxBytes: data.network.rxBytes,
213
+ txBytes: data.network.txBytes,
214
+ gpuUtil: data.gpu?.utilization,
215
+ powerWatts: data.power?.combinedWatts ?? data.power?.cpuWatts ?? 0,
216
+ rxPackets: data.network.rxPackets,
217
+ txPackets: data.network.txPackets,
218
+ connections: data.network.connections ?? 0,
219
+ });
220
+
221
+ writeLogRow(data);
222
+ checkAlerts(data);
223
+ syncP2PEvents();
224
+ } catch {
225
+ // skip bad warmup
226
+ }
227
+ }
228
+
202
229
  async function tick() {
203
230
  if (state.paused) return;
204
231
  try {
@@ -235,7 +262,7 @@ function killProcess(pidStr: string, signal: string = 'SIGTERM') {
235
262
  * rendering interval. Idempotent — calling while already
236
263
  * running is a no-op.
237
264
  */
238
- export async function startLive(opts: LiveOptions) {
265
+ export async function startLive(opts: LiveOptions, splashPromise?: Promise<void>) {
239
266
  if (state.running) return;
240
267
  state.running = true;
241
268
  state.paused = false;
@@ -247,6 +274,12 @@ function killProcess(pidStr: string, signal: string = 'SIGTERM') {
247
274
  state.history.reset();
248
275
  state.history.setMaxLen(Math.max(20, Math.min(200, state.termWidth - 30)));
249
276
 
277
+ const warmupPromise = doWarmup();
278
+
279
+ if (splashPromise) {
280
+ await splashPromise;
281
+ }
282
+
250
283
  process.stdout.write('\x1b[?1049h');
251
284
  process.stdout.write('\x1b[?25l');
252
285
  process.stdout.write('\x1b[2J\x1b[H');
@@ -256,7 +289,9 @@ function killProcess(pidStr: string, signal: string = 'SIGTERM') {
256
289
  process.stdout.write('\x1b[?1000h');
257
290
  }
258
291
 
259
- await tick();
292
+ await warmupPromise;
293
+ render();
294
+
260
295
  restartTicker();
261
296
 
262
297
  if (opts.autoLog) startLogging();