pyre-cli 9.5.1 → 10.0.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 +84 -14
- package/dist/alertChannels-TPSQIJ7S.js +8 -0
- package/dist/blender-FGH3ASEQ.js +7 -0
- package/dist/brewHealth-P2GW5Y5C.js +176 -0
- package/dist/buildCmd-CDPZ2ZFA.js +38 -0
- package/dist/{checkCmd-EWFNLBWE.js → checkCmd-RKW6QGDR.js} +10 -11
- package/dist/{chunk-RVGKEJXT.js → chunk-53O2RGSL.js} +47 -17
- package/dist/{chunk-MOAEGMFP.js → chunk-6UHZP4QP.js} +204 -46
- package/dist/chunk-GHRDW646.js +2506 -0
- package/dist/{prometheus-LFYHF6VO.js → chunk-HT4VQ4OH.js} +1 -0
- package/dist/chunk-M73HCQD2.js +95 -0
- package/dist/chunk-MZO5QKUR.js +32 -0
- package/dist/chunk-VIACN2RU.js +133 -0
- package/dist/chunk-Z2YV5HKV.js +87 -0
- package/dist/chunk-ZLVIVFSO.js +110 -0
- package/dist/{collectors-WD6VKH6M.js → collectors-H43PN4PS.js} +8 -2
- package/dist/{completions-VQMHQCXE.js → completions-JKYEJNGR.js} +34 -1
- package/dist/{config-4ZLF4HTS.js → config-GYGJXU2Q.js} +9 -1
- package/dist/doctor-GYHFTNZQ.js +387 -0
- package/dist/explainCmd-MF6PIMLW.js +222 -0
- package/dist/extensions-XJGHG7X3.js +134 -0
- package/dist/index.js +841 -206
- package/dist/ioreport.py +72 -0
- package/dist/netUsageCmd-WKBTW2YG.js +90 -0
- package/dist/{pipeCmd-7THXEGDH.js → pipeCmd-7REDBLBU.js} +5 -3
- package/dist/profileProcCmd-N4H6MCBT.js +107 -0
- package/dist/prometheus-5BL5PVLC.js +6 -0
- package/dist/prometheusCmd-PL64BLN5.js +93 -0
- package/dist/replayCmd-Z3PYXY7V.js +164 -0
- package/dist/run-HOGQDDTA.js +8 -0
- package/dist/serveCmd-2H5VLF3P.js +153 -0
- package/dist/service-Q74BBILO.js +181 -0
- package/dist/smartCmd-ODWKSFNG.js +166 -0
- package/dist/syncCmd-A2W3QB3S.js +126 -0
- package/dist/topoCmd-DU2HHZNH.js +148 -0
- package/dist/watchdogCmd-UF53JPZB.js +161 -0
- package/dist/{wizard-GVIAHIVV.js → wizard-TD7BGX6O.js} +1 -1
- package/install.ps1 +29 -0
- package/install.sh +10 -9
- package/package.json +7 -3
- package/src/ai/models.ts +138 -0
- package/src/alertChannels.ts +119 -0
- package/src/anomalies.ts +114 -60
- package/src/brewHealth.ts +157 -40
- package/src/buildCmd.ts +48 -0
- package/src/checkCmd.ts +5 -5
- package/src/completions.ts +35 -0
- package/src/doctor.ts +235 -7
- package/src/easy_features.test.ts +40 -0
- package/src/explainCmd.ts +261 -0
- package/src/extensions.ts +71 -7
- package/src/formatters/index.ts +1 -1
- package/src/formatters/output.ts +100 -13
- package/src/formatters/render.ts +274 -38
- package/src/formatters/themes.ts +8 -0
- package/src/formatters/types.ts +6 -1
- package/src/index.ts +298 -56
- package/src/live/input.ts +122 -4
- package/src/live/render.ts +98 -0
- package/src/live/state.ts +70 -52
- package/src/live/types.ts +2 -2
- package/src/monitors/batteryPredictor.ts +143 -0
- package/src/monitors/blender.ts +144 -0
- package/src/monitors/buildTracker.ts +121 -0
- package/src/monitors/collectors.ts +558 -147
- package/src/monitors/dns_cache.ts +48 -0
- package/src/monitors/index.ts +3 -2
- package/src/monitors/ioreport.py +72 -0
- package/src/monitors/platform/linux.ts +756 -0
- package/src/monitors/platform/windows.ts +519 -0
- package/src/monitors/run.ts +27 -3
- package/src/monitors/smc.ts +21 -1
- package/src/monitors/types.ts +112 -14
- package/src/netUsageCmd.ts +121 -0
- package/src/platform.test.ts +99 -0
- package/src/plugins/index.ts +143 -0
- package/src/profileProcCmd.ts +133 -0
- package/src/prometheusCmd.ts +107 -0
- package/src/replayCmd.ts +186 -0
- package/src/serveCmd.ts +180 -0
- package/src/service.ts +125 -7
- package/src/smartCmd.ts +205 -0
- package/src/state/config.ts +64 -17
- package/src/syncCmd.ts +166 -0
- package/src/topoCmd.ts +176 -0
- package/src/watchdogCmd.ts +198 -0
- package/src/xbar.ts +22 -11
- package/dist/brewHealth-F2BXF5M6.js +0 -74
- package/dist/chunk-FH5WDJBF.js +0 -15
- package/dist/chunk-HGRBBPYX.js +0 -937
- package/dist/doctor-L6FZYA7F.js +0 -184
- package/dist/extensions-DVA5YLGH.js +0 -74
- package/dist/service-WTS3NBQU.js +0 -73
- /package/dist/{chunk-SG26Y3WF.js → chunk-IM3IQMMT.js} +0 -0
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
explainAnomaliesLocally
|
|
3
|
+
} from "./chunk-ZLVIVFSO.js";
|
|
4
|
+
|
|
1
5
|
// src/formatters/render.ts
|
|
2
6
|
import chalk2 from "chalk";
|
|
3
7
|
|
|
@@ -106,7 +110,8 @@ var BUILTIN_THEMES = {
|
|
|
106
110
|
network: chalk.hex("#60a5fa"),
|
|
107
111
|
disk: chalk.hex("#f472b6"),
|
|
108
112
|
graphs: chalk.hex("#22d3ee"),
|
|
109
|
-
process: chalk.hex("#e5e7eb")
|
|
113
|
+
process: chalk.hex("#e5e7eb"),
|
|
114
|
+
blender: chalk.hex("#f97316")
|
|
110
115
|
},
|
|
111
116
|
dracula: {
|
|
112
117
|
border: chalk.hex("#6272a4"),
|
|
@@ -119,7 +124,8 @@ var BUILTIN_THEMES = {
|
|
|
119
124
|
network: chalk.hex("#ff79c6"),
|
|
120
125
|
disk: chalk.hex("#ff5555"),
|
|
121
126
|
graphs: chalk.hex("#8be9fd"),
|
|
122
|
-
process: chalk.hex("#f8f8f2")
|
|
127
|
+
process: chalk.hex("#f8f8f2"),
|
|
128
|
+
blender: chalk.hex("#ffb86c")
|
|
123
129
|
},
|
|
124
130
|
cyberpunk: {
|
|
125
131
|
border: chalk.hex("#ff0055"),
|
|
@@ -132,7 +138,8 @@ var BUILTIN_THEMES = {
|
|
|
132
138
|
network: chalk.hex("#00ffff"),
|
|
133
139
|
disk: chalk.hex("#ff007f"),
|
|
134
140
|
graphs: chalk.hex("#00ffcc"),
|
|
135
|
-
process: chalk.hex("#ffffff")
|
|
141
|
+
process: chalk.hex("#ffffff"),
|
|
142
|
+
blender: chalk.hex("#ff6600")
|
|
136
143
|
},
|
|
137
144
|
monochrome: {
|
|
138
145
|
border: chalk.gray,
|
|
@@ -145,7 +152,8 @@ var BUILTIN_THEMES = {
|
|
|
145
152
|
network: chalk.white.bold,
|
|
146
153
|
disk: chalk.white.bold,
|
|
147
154
|
graphs: chalk.white.bold,
|
|
148
|
-
process: chalk.white.bold
|
|
155
|
+
process: chalk.white.bold,
|
|
156
|
+
blender: chalk.white.bold
|
|
149
157
|
},
|
|
150
158
|
nord: {
|
|
151
159
|
border: chalk.hex("#4c566a"),
|
|
@@ -158,7 +166,8 @@ var BUILTIN_THEMES = {
|
|
|
158
166
|
network: chalk.hex("#81a1c1"),
|
|
159
167
|
disk: chalk.hex("#b48ead"),
|
|
160
168
|
graphs: chalk.hex("#88c0d0"),
|
|
161
|
-
process: chalk.hex("#eceff4")
|
|
169
|
+
process: chalk.hex("#eceff4"),
|
|
170
|
+
blender: chalk.hex("#d08770")
|
|
162
171
|
},
|
|
163
172
|
gruvbox: {
|
|
164
173
|
border: chalk.hex("#928374"),
|
|
@@ -171,7 +180,8 @@ var BUILTIN_THEMES = {
|
|
|
171
180
|
network: chalk.hex("#83a598"),
|
|
172
181
|
disk: chalk.hex("#d3869b"),
|
|
173
182
|
graphs: chalk.hex("#fb4934"),
|
|
174
|
-
process: chalk.hex("#ebdbb2")
|
|
183
|
+
process: chalk.hex("#ebdbb2"),
|
|
184
|
+
blender: chalk.hex("#fe8019")
|
|
175
185
|
}
|
|
176
186
|
};
|
|
177
187
|
function loadCustomThemes() {
|
|
@@ -198,7 +208,8 @@ function loadCustomThemes() {
|
|
|
198
208
|
network: buildColor(data.network),
|
|
199
209
|
disk: buildColor(data.disk),
|
|
200
210
|
graphs: buildColor(data.graphs),
|
|
201
|
-
process: buildColor(data.process)
|
|
211
|
+
process: buildColor(data.process),
|
|
212
|
+
blender: buildColor(data.blender)
|
|
202
213
|
};
|
|
203
214
|
} catch {
|
|
204
215
|
}
|
|
@@ -440,8 +451,17 @@ function batteryCard(data, contentWidth) {
|
|
|
440
451
|
if (data.battery.estimatedTimeToEmpty && data.battery.state !== "charged") {
|
|
441
452
|
lines.push(statRow("Est. Empty", data.battery.estimatedTimeToEmpty));
|
|
442
453
|
}
|
|
443
|
-
if (data.battery.
|
|
444
|
-
lines.push(statRow("
|
|
454
|
+
if (data.battery.powerWatts !== void 0 && data.battery.powerWatts > 0 && data.battery.state !== "charged") {
|
|
455
|
+
lines.push(statRow("Power Draw", `${data.battery.powerWatts.toFixed(2)} W`));
|
|
456
|
+
}
|
|
457
|
+
if (data.battery.smartPrediction) {
|
|
458
|
+
const sp = data.battery.smartPrediction;
|
|
459
|
+
lines.push("");
|
|
460
|
+
lines.push(chalk2.bold("SMART RUNTIME FORECAST:"));
|
|
461
|
+
lines.push(statRow("Light Load", `${chalk2.green(sp.scenarios.idle.timeRemaining)} (~${sp.scenarios.idle.ratePerHour}%/h)`));
|
|
462
|
+
lines.push(statRow("Current Load", `${chalk2.yellow(sp.scenarios.current.timeRemaining)} (~${sp.scenarios.current.ratePerHour}%/h)`));
|
|
463
|
+
lines.push(statRow("Heavy Load", `${chalk2.red(sp.scenarios.heavy.timeRemaining)} (~${sp.scenarios.heavy.ratePerHour}%/h)`));
|
|
464
|
+
lines.push(chalk2.dim(`Advice: ${sp.recommendation}`));
|
|
445
465
|
}
|
|
446
466
|
return lines;
|
|
447
467
|
}
|
|
@@ -458,11 +478,83 @@ function thermalCard(data, contentWidth) {
|
|
|
458
478
|
}
|
|
459
479
|
function networkCard(data, contentWidth) {
|
|
460
480
|
const valW = Math.max(6, contentWidth - 8);
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
481
|
+
const lines = [];
|
|
482
|
+
lines.push(statRow("Iface", truncatePlain(`${data.network.interface} (${data.network.ip})`, valW)));
|
|
483
|
+
const rxTotal = formatBytes(data.network.rxBytes);
|
|
484
|
+
const txTotal = formatBytes(data.network.txBytes);
|
|
485
|
+
const rxRateStr = formatBytes(data.network.rxRate);
|
|
486
|
+
const txRateStr = formatBytes(data.network.txRate);
|
|
487
|
+
lines.push(statRow("RX", `${rxTotal} \xB7 ${rxRateStr}/s`));
|
|
488
|
+
lines.push(statRow("TX", `${txTotal} \xB7 ${txRateStr}/s`));
|
|
489
|
+
const totalBytes = data.network.rxBytes + data.network.txBytes;
|
|
490
|
+
if (totalBytes > 0) {
|
|
491
|
+
const rxPct = Math.round(data.network.rxBytes / totalBytes * 100);
|
|
492
|
+
const barW = Math.max(4, contentWidth - 20);
|
|
493
|
+
const rxBar = gaugeBar(rxPct, barW);
|
|
494
|
+
lines.push(statRow("RX/TX", `${rxBar} ${rxPct}%`));
|
|
495
|
+
}
|
|
496
|
+
if (data.network.protocols) {
|
|
497
|
+
const p = data.network.protocols;
|
|
498
|
+
const totalConns = (p.tcp.connections || 0) + (p.udp.connections || 0);
|
|
499
|
+
if (totalConns > 0) {
|
|
500
|
+
const tcpPct = Math.round(p.tcp.connections / totalConns * 100);
|
|
501
|
+
lines.push(statRow("TCP", `${p.tcp.connections} conns \xB7 ${gaugeBar(tcpPct, Math.max(4, contentWidth - 20))} ${tcpPct}%`));
|
|
502
|
+
lines.push(statRow("UDP", `${p.udp.connections} conns`));
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
if (data.network.connectionStates) {
|
|
506
|
+
const cs = data.network.connectionStates;
|
|
507
|
+
const total = cs.established + cs.listening + cs.timeWait + cs.closeWait + cs.other;
|
|
508
|
+
if (total > 0) {
|
|
509
|
+
const estPct = Math.round(cs.established / total * 100);
|
|
510
|
+
lines.push(statRow("Active", `${cs.established} ESTABLISHED \xB7 ${estPct}%`));
|
|
511
|
+
lines.push(statRow("Listen", `${cs.listening} LISTEN`));
|
|
512
|
+
if (cs.timeWait > 0) lines.push(statRow("TimeWait", `${cs.timeWait}`));
|
|
513
|
+
if (cs.closeWait > 0) lines.push(statRow("CloseWait", `${cs.closeWait}`));
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
if (data.network.listeningPorts && data.network.listeningPorts.length > 0) {
|
|
517
|
+
const ports = data.network.listeningPorts.slice(0, 8).join(", ");
|
|
518
|
+
lines.push(statRow("Ports", truncatePlain(ports, valW)));
|
|
519
|
+
}
|
|
520
|
+
if (data.network.topRemoteHosts && data.network.topRemoteHosts.length > 0) {
|
|
521
|
+
for (const host of data.network.topRemoteHosts.slice(0, 3)) {
|
|
522
|
+
lines.push(statRow("Host", truncatePlain(`${host.host} (${host.connectionCount})`, valW)));
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
return lines;
|
|
526
|
+
}
|
|
527
|
+
function networkDetailCard(data, width, theme) {
|
|
528
|
+
const contentWidth = width - 4;
|
|
529
|
+
const lines = networkCard(data, contentWidth);
|
|
530
|
+
if (data.packets && data.packets.allProcesses && data.packets.allProcesses.length > 0) {
|
|
531
|
+
lines.push("");
|
|
532
|
+
lines.push(chalk2.bold("PROCESSES & BANDWIDTH USAGE:"));
|
|
533
|
+
lines.push(chalk2.dim("\u2500".repeat(contentWidth)));
|
|
534
|
+
const pWidth = 8;
|
|
535
|
+
const rxWidth = 12;
|
|
536
|
+
const txWidth = 12;
|
|
537
|
+
const totalWidth = 12;
|
|
538
|
+
const cmdWidth = Math.max(15, contentWidth - (pWidth + rxWidth + txWidth + totalWidth + 4 * 2));
|
|
539
|
+
lines.push(
|
|
540
|
+
chalk2.bold("PID".padEnd(pWidth)) + " " + chalk2.bold("COMMAND".padEnd(cmdWidth)) + " " + chalk2.bold("RX".padStart(rxWidth)) + " " + chalk2.bold("TX".padStart(txWidth)) + " " + chalk2.bold("TOTAL".padStart(totalWidth))
|
|
541
|
+
);
|
|
542
|
+
const sorted = [...data.packets.allProcesses].sort((a, b) => b.rxBytes + b.txBytes - (a.rxBytes + a.txBytes));
|
|
543
|
+
for (const proc of sorted) {
|
|
544
|
+
if (proc.rxBytes + proc.txBytes === 0) continue;
|
|
545
|
+
const rxStr = formatBytes(proc.rxBytes).padStart(rxWidth);
|
|
546
|
+
const txStr = formatBytes(proc.txBytes).padStart(txWidth);
|
|
547
|
+
const totalStr = formatBytes(proc.rxBytes + proc.txBytes).padStart(totalWidth);
|
|
548
|
+
const cmdStr = truncatePlain(proc.command, cmdWidth).padEnd(cmdWidth);
|
|
549
|
+
lines.push(
|
|
550
|
+
chalk2.cyan(proc.pid.toString().padEnd(pWidth)) + " " + cmdStr + " " + chalk2.yellow(rxStr) + " " + chalk2.yellow(txStr) + " " + chalk2.bold(totalStr)
|
|
551
|
+
);
|
|
552
|
+
}
|
|
553
|
+
} else {
|
|
554
|
+
lines.push("");
|
|
555
|
+
lines.push(chalk2.dim("No active network process data available."));
|
|
556
|
+
}
|
|
557
|
+
return lines;
|
|
466
558
|
}
|
|
467
559
|
function tasksCard(data, contentWidth) {
|
|
468
560
|
if (!data.tasks || !data.tasks.length) return null;
|
|
@@ -488,13 +580,14 @@ var TAB_DEFS = [
|
|
|
488
580
|
{ id: "power", label: "Power", key: "4" },
|
|
489
581
|
{ id: "battery", label: "Battery", key: "5" },
|
|
490
582
|
{ id: "thermal", label: "Thermal", key: "6" },
|
|
491
|
-
{ id: "
|
|
492
|
-
{ id: "
|
|
493
|
-
{ id: "
|
|
494
|
-
{ id: "
|
|
495
|
-
{ id: "process", label: "Process", key: "P" },
|
|
583
|
+
{ id: "packets", label: "Conns", key: "7" },
|
|
584
|
+
{ id: "tasks", label: "Tasks", key: "8" },
|
|
585
|
+
{ id: "disk", label: "Disk", key: "9" },
|
|
586
|
+
{ id: "process", label: "Process", key: "0" },
|
|
496
587
|
{ id: "p2p", label: "P2P", key: "R" },
|
|
497
|
-
{ id: "anomalies", label: "Anomalies", key: "A" }
|
|
588
|
+
{ id: "anomalies", label: "Anomalies", key: "A" },
|
|
589
|
+
{ id: "containers", label: "Containers", key: "C" },
|
|
590
|
+
{ id: "blender", label: "Blender", key: "B" }
|
|
498
591
|
];
|
|
499
592
|
var TAB_BAR_INDENT = 2;
|
|
500
593
|
var TAB_SEPARATOR_WIDTH = 3;
|
|
@@ -645,6 +738,31 @@ function diskTableLines(disks, contentWidth, borderAccent = THEMES.default.borde
|
|
|
645
738
|
});
|
|
646
739
|
return [head, borderAccent("\u2500".repeat(contentWidth)), ...rows];
|
|
647
740
|
}
|
|
741
|
+
function containersTableLines(containers, contentWidth, borderAccent = THEMES.default.border) {
|
|
742
|
+
const idW = 14, cpuW = 8, memW = 8, memUsgW = 20, netW = 20, blockW = 20, pidsW = 6;
|
|
743
|
+
const nameW = Math.max(10, contentWidth - idW - cpuW - memW - memUsgW - netW - blockW - pidsW - 7);
|
|
744
|
+
const head = chalk2.bold.hex("#f8f8f2").bgHex("#44475a")(" CONTAINER ID ") + chalk2.bold.hex("#f8f8f2").bgHex("#44475a")(" CPU% ") + chalk2.bold.hex("#f8f8f2").bgHex("#44475a")(" MEM% ") + chalk2.bold.hex("#f8f8f2").bgHex("#44475a")(" MEM USAGE ") + chalk2.bold.hex("#f8f8f2").bgHex("#44475a")(" NET I/O ") + chalk2.bold.hex("#f8f8f2").bgHex("#44475a")(" BLOCK I/O ") + chalk2.bold.hex("#f8f8f2").bgHex("#44475a")(" PIDS ") + chalk2.bold.hex("#f8f8f2").bgHex("#44475a")(" NAME".padEnd(nameW + 1));
|
|
745
|
+
const rows = containers.map((c) => {
|
|
746
|
+
const cpuStr = pctColor(c.cpuPercent)(`${c.cpuPercent.toFixed(1)}`.padEnd(cpuW));
|
|
747
|
+
const memStr = pctColor(c.memPercent)(`${c.memPercent.toFixed(1)}`.padEnd(memW));
|
|
748
|
+
return truncatePlain(c.id, idW - 1).padEnd(idW) + cpuStr + memStr + c.memUsage.padEnd(memUsgW) + c.netIO.padEnd(netW) + c.blockIO.padEnd(blockW) + String(c.pids).padEnd(pidsW) + truncatePlain(c.name, nameW);
|
|
749
|
+
});
|
|
750
|
+
return [head, borderAccent("\u2500".repeat(contentWidth)), ...rows];
|
|
751
|
+
}
|
|
752
|
+
function blenderCard(renders, contentWidth, theme) {
|
|
753
|
+
if (!renders.length) return ["No active Blender renders detected"];
|
|
754
|
+
const lines = [];
|
|
755
|
+
for (const r of renders.slice(0, 8)) {
|
|
756
|
+
const statusColor = r.status === "rendering" ? chalk2.green : r.status === "finalizing" ? chalk2.yellow : r.status === "loading" ? chalk2.cyan : chalk2.dim;
|
|
757
|
+
const pctStr = `${r.completionPercent}%`;
|
|
758
|
+
const barW = Math.max(4, contentWidth - 28);
|
|
759
|
+
const bar = gaugeBar(r.completionPercent, barW);
|
|
760
|
+
lines.push(`${theme.blender(`PID ${r.pid}`)} ${truncatePlain(r.blendFile, 18)} ${r.renderEngine}`);
|
|
761
|
+
lines.push(` Fra ${String(r.currentFrame).padStart(4)}/${r.totalFrames} ${bar} ${pctStr}`);
|
|
762
|
+
lines.push(` ${r.elapsedSec}s elapsed \xB7 ${statusColor(r.status)}${r.sampleCount !== void 0 ? ` \xB7 ${r.sampleCount} spp` : ""}`);
|
|
763
|
+
}
|
|
764
|
+
return lines;
|
|
765
|
+
}
|
|
648
766
|
function detailPanelTitle(panel2, trackedPid) {
|
|
649
767
|
const map = {
|
|
650
768
|
cpu: "CPU",
|
|
@@ -657,7 +775,9 @@ function detailPanelTitle(panel2, trackedPid) {
|
|
|
657
775
|
packets: "Packets",
|
|
658
776
|
tasks: "Tasks",
|
|
659
777
|
disk: "Disk",
|
|
660
|
-
process: trackedPid !== void 0 && trackedPid !== null ? `Processes (Following PID ${trackedPid})` : "Processes"
|
|
778
|
+
process: trackedPid !== void 0 && trackedPid !== null ? `Processes (Following PID ${trackedPid})` : "Processes",
|
|
779
|
+
containers: "Containers",
|
|
780
|
+
blender: "Blender Renders"
|
|
661
781
|
};
|
|
662
782
|
return map[panel2] || panel2;
|
|
663
783
|
}
|
|
@@ -676,37 +796,50 @@ function activeDetailLines(data, activePanel, width, opts = {}) {
|
|
|
676
796
|
}
|
|
677
797
|
case "power": {
|
|
678
798
|
const power = powerCard(data);
|
|
679
|
-
if (!power
|
|
680
|
-
|
|
681
|
-
if (power) lines.push(...power);
|
|
682
|
-
if (data.battery?.powerWatts !== void 0 && data.battery.powerWatts > 0) {
|
|
683
|
-
lines.push(statRow("Battery", `${data.battery.powerWatts.toFixed(2)} W`));
|
|
684
|
-
}
|
|
685
|
-
return lines.length ? lines : ["No power data available"];
|
|
799
|
+
if (!power) return ["No power data available"];
|
|
800
|
+
return power;
|
|
686
801
|
}
|
|
687
802
|
case "battery":
|
|
688
803
|
return data.battery ? batteryCard(data, contentWidth) : ["No battery data available"];
|
|
689
804
|
case "thermal":
|
|
690
805
|
return thermalCard(data, contentWidth);
|
|
691
806
|
case "network":
|
|
692
|
-
return
|
|
807
|
+
return networkDetailCard(data, width, theme);
|
|
693
808
|
case "packets": {
|
|
694
|
-
if (!data.packets
|
|
695
|
-
|
|
696
|
-
lines.push(statRow("Total", `${data.packets.totalPackets} pkt`));
|
|
697
|
-
lines.push(statRow("RX", `${data.packets.rxPackets} pkt`));
|
|
698
|
-
lines.push(statRow("TX", `${data.packets.txPackets} pkt`));
|
|
699
|
-
lines.push(statRow("Conns", `${data.packets.connections} TCP`));
|
|
700
|
-
if (data.packets.interfaces && data.packets.interfaces.length) {
|
|
701
|
-
lines.push(statRow("Ifaces", `${data.packets.interfaces.length} active`));
|
|
702
|
-
for (const iface of data.packets.interfaces.slice(0, 8)) {
|
|
703
|
-
lines.push(statRow(` ${iface.iface}`, `RX ${formatBytes(iface.rxBytes)} / TX ${formatBytes(iface.txBytes)}`));
|
|
704
|
-
}
|
|
809
|
+
if (!data.packets || !data.packets.allProcesses || !data.packets.allProcesses.length) {
|
|
810
|
+
return ["No advanced network tracking data available."];
|
|
705
811
|
}
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
812
|
+
const lines = [];
|
|
813
|
+
const pWidth = 8;
|
|
814
|
+
const cmdWidth = 15;
|
|
815
|
+
const protoWidth = 5;
|
|
816
|
+
const stateWidth = 11;
|
|
817
|
+
const rxWidth = 10;
|
|
818
|
+
const txWidth = 10;
|
|
819
|
+
const remaining = Math.max(20, width - (pWidth + cmdWidth + protoWidth + stateWidth + rxWidth + txWidth + 7 * 2));
|
|
820
|
+
const localWidth = Math.floor(remaining * 0.4);
|
|
821
|
+
const remoteWidth = remaining - localWidth;
|
|
822
|
+
const header2 = chalk2.bold("PID".padEnd(pWidth)) + " " + chalk2.bold("COMMAND".padEnd(cmdWidth)) + " " + chalk2.bold("PROTO".padEnd(protoWidth)) + " " + chalk2.bold("LOCAL".padEnd(localWidth)) + " " + chalk2.bold("REMOTE".padEnd(remoteWidth)) + " " + chalk2.bold("STATE".padEnd(stateWidth)) + " " + chalk2.bold("RX".padStart(rxWidth)) + " " + chalk2.bold("TX".padStart(txWidth));
|
|
823
|
+
lines.push(header2);
|
|
824
|
+
lines.push(chalk2.dim("\u2500".repeat(width)));
|
|
825
|
+
for (const proc of data.packets.allProcesses) {
|
|
826
|
+
if (!proc.connections || proc.connections.length === 0) continue;
|
|
827
|
+
const summaryCmd = truncatePlain(proc.command, cmdWidth + protoWidth + localWidth + remoteWidth + stateWidth + 8);
|
|
828
|
+
const summaryRx = formatBytes(proc.rxBytes).padStart(rxWidth);
|
|
829
|
+
const summaryTx = formatBytes(proc.txBytes).padStart(txWidth);
|
|
830
|
+
lines.push(
|
|
831
|
+
chalk2.cyan(proc.pid.toString().padEnd(pWidth)) + " " + chalk2.cyan(summaryCmd.padEnd(width - pWidth - rxWidth - txWidth - 6)) + " " + chalk2.yellow(summaryRx) + " " + chalk2.yellow(summaryTx)
|
|
832
|
+
);
|
|
833
|
+
for (const conn of proc.connections) {
|
|
834
|
+
const cProto = chalk2.dim(truncatePlain(conn.protocol, protoWidth).padEnd(protoWidth));
|
|
835
|
+
const cLocal = chalk2.dim(truncatePlain(conn.local, localWidth).padEnd(localWidth));
|
|
836
|
+
const cRemote = truncatePlain(conn.remote, remoteWidth).padEnd(remoteWidth);
|
|
837
|
+
const cStateStr = conn.state === "Established" ? chalk2.green("ESTABLISHED".padEnd(stateWidth)) : chalk2.dim(truncatePlain(conn.state, stateWidth).padEnd(stateWidth));
|
|
838
|
+
const cRx = chalk2.dim(formatBytes(conn.rxBytes).padStart(rxWidth));
|
|
839
|
+
const cTx = chalk2.dim(formatBytes(conn.txBytes).padStart(txWidth));
|
|
840
|
+
lines.push(
|
|
841
|
+
" ".repeat(pWidth) + " " + " ".repeat(cmdWidth) + " " + cProto + " " + cLocal + " " + cRemote + " " + cStateStr + " " + cRx + " " + cTx
|
|
842
|
+
);
|
|
710
843
|
}
|
|
711
844
|
}
|
|
712
845
|
return lines;
|
|
@@ -760,15 +893,40 @@ function activeDetailLines(data, activePanel, width, opts = {}) {
|
|
|
760
893
|
if (!opts.anomalyHistory || opts.anomalyHistory.length === 0) return ["No anomalies detected yet."];
|
|
761
894
|
const lines = [];
|
|
762
895
|
const sorted = [...opts.anomalyHistory].sort((a, b) => (b.timestamp?.getTime() || 0) - (a.timestamp?.getTime() || 0));
|
|
763
|
-
for (const a of sorted) {
|
|
896
|
+
for (const a of sorted.slice(0, 10)) {
|
|
764
897
|
const color = a.severity === "critical" ? chalk2.red.bold : chalk2.yellow;
|
|
765
898
|
const direction = a.zScore > 0 ? "\u2191 spike" : "\u2193 drop";
|
|
766
899
|
const valStr = a.metric.toLowerCase().includes("net") ? `${formatBytes(a.value)}/s` : `${a.value.toFixed(1)}%`;
|
|
767
900
|
const timeStr = a.timestamp ? a.timestamp.toLocaleTimeString() : "";
|
|
768
901
|
lines.push(color(` ${timeStr.padEnd(10)} \u26A0 ${a.metric.padEnd(8)}: ${valStr.padEnd(12)} (${direction}, \u03C3=${a.zScore.toFixed(1)})`));
|
|
769
902
|
}
|
|
903
|
+
lines.push("");
|
|
904
|
+
const modelId = opts.aiModel || "expert-rules-v1";
|
|
905
|
+
const aiAnalysis = explainAnomaliesLocally(sorted, modelId);
|
|
906
|
+
for (const al of aiAnalysis.split("\n")) {
|
|
907
|
+
if (al.startsWith("Diagnosis Engine:")) {
|
|
908
|
+
lines.push(chalk2.bold.magenta(al));
|
|
909
|
+
} else if (al.startsWith("Tip:")) {
|
|
910
|
+
lines.push(chalk2.cyan.bold(al));
|
|
911
|
+
} else if (al.startsWith(" \u2022 Recommendation:")) {
|
|
912
|
+
lines.push(chalk2.green(al));
|
|
913
|
+
} else if (al.startsWith(" \u2022 Cause:")) {
|
|
914
|
+
lines.push(chalk2.yellow(al));
|
|
915
|
+
} else if (al.startsWith(" \u2022 Verdict:")) {
|
|
916
|
+
lines.push(chalk2.dim(al));
|
|
917
|
+
} else {
|
|
918
|
+
lines.push(chalk2.dim(al));
|
|
919
|
+
}
|
|
920
|
+
}
|
|
770
921
|
return lines;
|
|
771
922
|
}
|
|
923
|
+
case "containers": {
|
|
924
|
+
return data.containers && data.containers.length ? containersTableLines(data.containers, width - 4, theme.border) : ["No container data available"];
|
|
925
|
+
}
|
|
926
|
+
case "blender": {
|
|
927
|
+
const renders = data.blenderRenders && data.blenderRenders.length ? data.blenderRenders : [];
|
|
928
|
+
return blenderCard(renders, contentWidth, theme);
|
|
929
|
+
}
|
|
772
930
|
default:
|
|
773
931
|
return null;
|
|
774
932
|
}
|
|
@@ -992,7 +1150,7 @@ function formatTable(data, opts = {}) {
|
|
|
992
1150
|
lines.push(gaugeRow("GPU", data.gpu.utilization, contentWidth));
|
|
993
1151
|
}
|
|
994
1152
|
const tempC = data.cpu.temperature ?? data.thermal.temperatures?.cpu_die;
|
|
995
|
-
if (tempC
|
|
1153
|
+
if (tempC != null) {
|
|
996
1154
|
const tempStr = formatTempUnit(tempC, opts.tempUnit);
|
|
997
1155
|
lines.push(statRow("Temp", thermalColor(data.thermal.pressureLevel)(tempStr)));
|
|
998
1156
|
}
|