pyre-cli 8.0.0 → 8.2.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
@@ -73,6 +73,9 @@ pyre live # Interactive live dashboard
73
73
  pyre live --interval 3 --log # Custom refresh interval + auto-logging
74
74
  pyre live --alert-cpu 80 --alert-temp 85 --temp-unit f
75
75
 
76
+ pyre ui # Launch native macOS UI dashboard
77
+ pyre web # Serve auto-refreshing live web portal on localhost
78
+
76
79
  pyre anomalies --since 7d # Statistical resource spike digest from past CSV logs
77
80
  pyre doctor # System diagnostics (Gatekeeper, SIP, XProtect, powermetrics)
78
81
  pyre extensions # System extensions inspector (systemextensionsctl)
@@ -162,11 +165,12 @@ These options apply to both static snapshots and `pyre live`, except where noted
162
165
  |---|---|
163
166
  | `pyre live` | Start the interactive live dashboard |
164
167
 
165
- ### Web dashboard
168
+ ### Web & Native dashboards
166
169
 
167
170
  | Command | Description |
168
171
  |---|---|
169
172
  | `pyre web` | Serve an auto-refreshing live web portal with real-time SSE stats streaming on localhost (`--port <port>`) |
173
+ | `pyre ui` | Launch the native macOS UI dashboard (wraps the web portal in a native window) |
170
174
 
171
175
  ### P2P
172
176
 
package/dist/index.js CHANGED
@@ -1508,24 +1508,24 @@ function getDashboardHtml() {
1508
1508
  <style>
1509
1509
  *,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
1510
1510
  :root{
1511
- --bg: #050508;
1512
- --bg1: #0a0c16;
1513
- --bg2: #111427;
1511
+ --bg: #000000;
1512
+ --bg1: #0a0a0a;
1513
+ --bg2: #141414;
1514
1514
  --bg3: rgba(255,255,255,0.05);
1515
- --border: #2a2d42;
1516
- --border2: #3a3f5a;
1517
- --text: #d4d8f0;
1518
- --text2: #8891b4;
1519
- --text3: #505878;
1520
- --accent: #6c8fff;
1521
- --accent2: #4a6ee8;
1522
- --cyan: #3edcff;
1523
- --green: #3effa0;
1524
- --yellow: #ffca3e;
1525
- --red: #ff4d6a;
1526
- --orange: #ff8c4a;
1527
- --purple: #b06cff;
1528
- --glow: rgba(108,143,255,0.15);
1515
+ --border: #333333;
1516
+ --border2: #444444;
1517
+ --text: #ffffff;
1518
+ --text2: #aaaaaa;
1519
+ --text3: #666666;
1520
+ --accent: #ffffff;
1521
+ --accent2: #dddddd;
1522
+ --cyan: #ffffff;
1523
+ --green: #ffffff;
1524
+ --yellow: #bbbbbb;
1525
+ --red: #dddddd;
1526
+ --orange: #cccccc;
1527
+ --purple: #eeeeee;
1528
+ --glow: rgba(255,255,255,0.15);
1529
1529
  --font: 'Inter', -apple-system, sans-serif;
1530
1530
  --mono: 'JetBrains Mono', ui-monospace, monospace;
1531
1531
  }
@@ -1567,7 +1567,7 @@ body {
1567
1567
  text-transform:uppercase;font-weight:600;
1568
1568
  }
1569
1569
  .tab:hover{color:var(--text2);background:var(--bg3);}
1570
- .tab.active{color:var(--accent);border-bottom:2px solid var(--accent);background:linear-gradient(0deg, rgba(108,143,255,0.1), transparent);}
1570
+ .tab.active{color:var(--accent);border-bottom:2px solid var(--accent);background:linear-gradient(0deg, rgba(255,255,255,0.1), transparent);}
1571
1571
  .tab-key{opacity:0.5;margin-right:6px;}
1572
1572
 
1573
1573
  #main{flex:1;overflow-y:auto;overflow-x:hidden;padding:16px;display:flex;flex-direction:column;}
@@ -1594,7 +1594,7 @@ body {
1594
1594
  transition:border-color 0.2s, box-shadow 0.2s;
1595
1595
  display:flex;flex-direction:column;
1596
1596
  }
1597
- .card:hover{border-color:var(--cyan);box-shadow:0 0 10px rgba(62,220,255,0.05);}
1597
+ .card:hover{border-color:var(--cyan);box-shadow:0 0 10px rgba(255,255,255,0.05);}
1598
1598
  .card-title{
1599
1599
  position:absolute;top:-9px;left:12px;
1600
1600
  background:var(--bg);
@@ -1619,7 +1619,7 @@ body {
1619
1619
  .stat-label{font-size:11px;color:var(--text2);}
1620
1620
  .stat-val{font-family:var(--mono);font-size:12px;color:var(--text);font-weight:500;}
1621
1621
  .big-metric{text-align:center;padding:20px 0;}
1622
- .big-val{font-family:var(--mono);font-size:48px;font-weight:700;color:var(--cyan);text-shadow:0 0 15px rgba(62,220,255,0.3);}
1622
+ .big-val{font-family:var(--mono);font-size:48px;font-weight:700;color:var(--cyan);text-shadow:0 0 15px rgba(255,255,255,0.3);}
1623
1623
  .big-unit{font-family:var(--mono);font-size:14px;color:var(--text2);margin-top:8px;}
1624
1624
 
1625
1625
  /* Gauges */
@@ -1628,9 +1628,9 @@ body {
1628
1628
  .gauge-pct{font-weight:600;}
1629
1629
  .gauge-track{height:20px;background:var(--bg2);border-radius:4px;overflow:hidden;position:relative;border:1px solid var(--border);}
1630
1630
  .gauge-fill{height:100%;transition:width 0.4s ease;display:flex;align-items:center;justify-content:flex-end;padding-right:6px;font-family:var(--mono);font-size:10px;font-weight:700;color:#000;}
1631
- .gauge-fill.ok{background:linear-gradient(90deg,var(--green),#a3ffce);}
1632
- .gauge-fill.warn{background:linear-gradient(90deg,var(--yellow),#ffea99);}
1633
- .gauge-fill.crit{background:linear-gradient(90deg,var(--red),#ff99aa);}
1631
+ .gauge-fill.ok{background:linear-gradient(90deg,var(--text),#999);}
1632
+ .gauge-fill.warn{background:linear-gradient(90deg,var(--text2),#666);}
1633
+ .gauge-fill.crit{background:linear-gradient(90deg,var(--text3),#333);}
1634
1634
 
1635
1635
  /* SVG Rings */
1636
1636
  .ring-container { display:flex; justify-content:space-around; padding:20px 0; background:var(--bg1); border:1px solid var(--border); border-radius:6px; margin-bottom:12px; }
@@ -1654,9 +1654,9 @@ canvas.spark.large { height:200px; }
1654
1654
  .core-col { display:flex; flex-direction:column; gap:4px; align-items:center; }
1655
1655
  .core-bar { width:100%; height:100px; background:var(--bg2); border-radius:4px; display:flex; align-items:flex-end; overflow:hidden; border:1px solid var(--border); }
1656
1656
  .core-fill { width:100%; transition:height 0.3s; }
1657
- .core-fill.ok { background:linear-gradient(0deg,var(--green),#a3ffce); }
1658
- .core-fill.warn { background:linear-gradient(0deg,var(--yellow),#ffea99); }
1659
- .core-fill.crit { background:linear-gradient(0deg,var(--red),#ff99aa); }
1657
+ .core-fill.ok { background:linear-gradient(0deg,var(--text),#999); }
1658
+ .core-fill.warn { background:linear-gradient(0deg,var(--text2),#666); }
1659
+ .core-fill.crit { background:linear-gradient(0deg,var(--text3),#333); }
1660
1660
  .core-lbl { font-family:var(--mono); font-size:9px; color:var(--text2); }
1661
1661
 
1662
1662
  /* Table */
@@ -1689,7 +1689,7 @@ table.proc td { padding:6px 12px; white-space:nowrap; overflow:hidden; text-over
1689
1689
  .chip.warn { border-color:var(--yellow); color:var(--yellow); }
1690
1690
  .chip.crit { border-color:var(--red); color:var(--red); }
1691
1691
 
1692
- .anomaly { display:flex; gap:12px; padding:12px; border:1px solid var(--red); background:rgba(255,77,106,0.1); border-radius:6px; margin-bottom:12px; }
1692
+ .anomaly { display:flex; gap:12px; padding:12px; border:1px solid var(--red); background:rgba(255,255,255,0.1); border-radius:6px; margin-bottom:12px; }
1693
1693
  .anomaly-icon { font-size:20px; }
1694
1694
  .anomaly-title { font-family:var(--mono); font-weight:700; color:var(--red); font-size:12px; }
1695
1695
  .anomaly-desc { font-family:var(--mono); font-size:11px; color:var(--text); margin-top:4px; }
@@ -1753,7 +1753,7 @@ function svgRing(val, max, label, unit='', size=100) {
1753
1753
  const pct = Math.min(100, Math.max(0, (val/max)*100));
1754
1754
  const off = circ*(1 - pct/100);
1755
1755
  const cls = statusCls(pct);
1756
- const col = cls==='crit'?'var(--red)':cls==='warn'?'var(--yellow)':'var(--cyan)';
1756
+ const col = cls==='crit'?'var(--text3)':cls==='warn'?'var(--text2)':'var(--text)';
1757
1757
  return \`<div class="ring-box">
1758
1758
  <div class="ring-title">\${label}</div>
1759
1759
  <div class="svg-ring \${size>150?'large':''}">
@@ -2073,14 +2073,14 @@ function renderAnomalies(d) {
2073
2073
  }
2074
2074
 
2075
2075
  function drawSparks() {
2076
- drawSpark('sp-ov-cpu', history.cpu, '#3edcff', '#4a6ee8');
2077
- drawSpark('sp-ov-rx', history.rxRate, '#3edcff', '#4a6ee8');
2078
- drawSpark('sp-ov-tx', history.txRate, '#b06cff', '#6c8fff');
2079
- drawSpark('sp-cpu-l', history.cpu, '#3edcff', '#4a6ee8');
2080
- drawSpark('sp-mem-l', history.mem, '#b06cff', '#6c8fff');
2081
- drawSpark('sp-therm-l', history.temp, '#ffca3e', '#ff4d6a');
2082
- drawSpark('sp-net-rx-l', history.rxRate, '#3edcff', '#4a6ee8');
2083
- drawSpark('sp-net-tx-l', history.txRate, '#b06cff', '#6c8fff');
2076
+ drawSpark('sp-ov-cpu', history.cpu, '#ffffff', '#999999');
2077
+ drawSpark('sp-ov-rx', history.rxRate, '#ffffff', '#999999');
2078
+ drawSpark('sp-ov-tx', history.txRate, '#bbbbbb', '#666666');
2079
+ drawSpark('sp-cpu-l', history.cpu, '#ffffff', '#999999');
2080
+ drawSpark('sp-mem-l', history.mem, '#bbbbbb', '#666666');
2081
+ drawSpark('sp-therm-l', history.temp, '#dddddd', '#888888');
2082
+ drawSpark('sp-net-rx-l', history.rxRate, '#ffffff', '#999999');
2083
+ drawSpark('sp-net-tx-l', history.txRate, '#bbbbbb', '#666666');
2084
2084
  }
2085
2085
 
2086
2086
  function switchView(v) {
@@ -4772,6 +4772,29 @@ var config2 = readConfig();
4772
4772
  var pkg = JSON.parse(fs8.readFileSync(new URL("../package.json", import.meta.url), "utf-8"));
4773
4773
  var program = new Command();
4774
4774
  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("--html", "Output as HTML").option("--md", "Output as Markdown").option("-c, --csv", "Output as CSV").option("-t, --tsv", "Output as TSV").option("--detailed", "Include detailed system info and sensor readings").option("--theme <name>", "Default theme for live mode (default, dracula, cyberpunk, monochrome, nord, gruvbox)", config2.theme).option("--interval <seconds>", "Refresh interval for live mode", String(config2.interval)).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", config2.exportDir).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", config2.sortMode).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("--alert-cpu <pct>", "CPU usage alert threshold (default: 90)", String(config2.cpuAlertPct)).option("--alert-temp <c>", "CPU temperature alert threshold in Celsius (default: 95)", String(config2.tempAlertC)).option("--temp-unit <unit>", "Temperature display unit: c or f (default: c)", "c").option("--p2p-host <host>", "P2P host address (server: bind address, client: server address)").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)").option("--since <range>", "Time range for anomalies digest (e.g. 1d, 7d, yesterday)").option("--plain", "Output in plain accessible text without ANSI colors or line-drawing characters").option("--a11y", "Alias for --plain").option("--webhook-url <url>", "URL to POST to on alert").option("--alert-cmd <cmd>", "Command to execute on alert").option("--port <port>", "Port number for web server mode", "3000");
4775
+ program.addHelpText("after", `
4776
+ Commands:
4777
+ live Interactive live dashboard
4778
+ ui Launch the native macOS UI dashboard
4779
+ web Serve an auto-refreshing live web portal
4780
+ ssh <host> Stream live stats from a remote Mac over SSH
4781
+ fleet <host1> [host2]... Multi-host live dashboard monitoring multiple Macs
4782
+ bench <cmd> Log CPU, memory, network, power draw, and estimate kWh cost
4783
+ anomalies Compute z-score anomalies and print plain-language digest
4784
+ doctor Run system diagnostics
4785
+ extensions System Extensions inspector
4786
+ brew Homebrew health panel
4787
+ update Check for pyre-cli updates
4788
+ profile <save|load|list> Atomic configuration profile management
4789
+ config <show|reset> View or reset persistent configuration file
4790
+ history Graph historical resource trends from CSV logs
4791
+ diff <file1> <file2> Compare two saved snapshot files side-by-side
4792
+ info Concise hardware summary
4793
+ completions <shell> Generate shell auto-completion scripts
4794
+ xbar Generate an xbar / SwiftBar menu bar plugin script
4795
+ p2p <server|connect> Start a P2P server or connect to one
4796
+ server Print commands for starting P2P server/client
4797
+ `);
4775
4798
  program.parse(process.argv);
4776
4799
  var opts = program.opts();
4777
4800
  if (opts.plain || opts.a11y) {
@@ -5401,7 +5424,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
5401
5424
  window.title = "Pyre"
5402
5425
  window.minSize = NSSize(width: 800, height: 600)
5403
5426
  window.appearance = NSAppearance(named: .darkAqua)
5404
- window.backgroundColor = NSColor(red: 0.027, green: 0.031, blue: 0.063, alpha: 1)
5427
+ window.backgroundColor = NSColor(white: 0, alpha: 1)
5405
5428
  window.isReleasedWhenClosed = false
5406
5429
  window.delegate = self
5407
5430
 
@@ -5409,7 +5432,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
5409
5432
  let cfg = WKWebViewConfiguration()
5410
5433
  webView = DraggableWebView(frame: window.contentView!.bounds, configuration: cfg)
5411
5434
  webView.autoresizingMask = [.width, .height]
5412
- webView.setValue(NSColor(red: 0.027, green: 0.031, blue: 0.063, alpha: 1),
5435
+ webView.setValue(NSColor(white: 0, alpha: 1),
5413
5436
  forKey: "backgroundColor")
5414
5437
 
5415
5438
  // Load the dashboard HTML from the local server
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pyre-cli",
3
- "version": "8.0.0",
3
+ "version": "8.2.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
@@ -74,6 +74,30 @@ program
74
74
  .option('--alert-cmd <cmd>', 'Command to execute on alert')
75
75
  .option('--port <port>', 'Port number for web server mode', '3000');
76
76
 
77
+ program.addHelpText('after', `
78
+ Commands:
79
+ live Interactive live dashboard
80
+ ui Launch the native macOS UI dashboard
81
+ web Serve an auto-refreshing live web portal
82
+ ssh <host> Stream live stats from a remote Mac over SSH
83
+ fleet <host1> [host2]... Multi-host live dashboard monitoring multiple Macs
84
+ bench <cmd> Log CPU, memory, network, power draw, and estimate kWh cost
85
+ anomalies Compute z-score anomalies and print plain-language digest
86
+ doctor Run system diagnostics
87
+ extensions System Extensions inspector
88
+ brew Homebrew health panel
89
+ update Check for pyre-cli updates
90
+ profile <save|load|list> Atomic configuration profile management
91
+ config <show|reset> View or reset persistent configuration file
92
+ history Graph historical resource trends from CSV logs
93
+ diff <file1> <file2> Compare two saved snapshot files side-by-side
94
+ info Concise hardware summary
95
+ completions <shell> Generate shell auto-completion scripts
96
+ xbar Generate an xbar / SwiftBar menu bar plugin script
97
+ p2p <server|connect> Start a P2P server or connect to one
98
+ server Print commands for starting P2P server/client
99
+ `);
100
+
77
101
  program.parse(process.argv);
78
102
 
79
103
  const opts = program.opts();