// The side rail: what's flying across the wire, in aggregate. A leaderboard of // signals by volume (coloured by severity, with a mini bar), then a breakdown // by source — who's doing the signalling: kill(2), tgkill, the kernel, timers. // Pure UI over the `feed` snapshot's running tallies. import { Box, Text } from "yeet:tui"; import { SEV_COLOR, severity, sigName } from "@/lib/signals.js"; import { count, ljust } from "@/lib/format.js"; const HEAD = "#2a8f5a"; const BRIGHT = "#e6f0ea"; const DIM = "#5f6f68"; const FAINT = "#333d38"; const PANEL = "#0c110f"; const BAR_W = 10; // Fixed display order + labels. kill/tgkill always show (they're the point); // the rest appear once they've happened. const SOURCES = [ ["kill", "kill(2)"], ["tgkill", "tgkill"], ["queue", "sigqueue"], ["timer", "timer"], ["kernel", "kernel"], ["fault", "fault"], ["other", "other"], ]; // disposition key → label + colour (matches the feed's disposition tags) const DISPOS = [ ["caught", "caught", "#5fe08a"], ["default", "default", "#e6f0ea"], ["ignored", "ignored", "#9a8a4a"], ]; export default function Tally({ feed, rows }) { return ( {() => { const s = feed.get(); const out = []; out.push({" TOP SIGNALS"}); const sigs = Object.entries(s.bySig) .map(([k, v]) => [+k, v]) .sort((a, b) => b[1] - a[1]); const peak = sigs.length ? sigs[0][1] : 1; const budget = Math.max(3, rows - SOURCES.length - 4); if (!sigs.length) out.push({" —"}); for (const [sig, n] of sigs.slice(0, budget)) { const col = SEV_COLOR[severity(sig)]; const filled = Math.max(1, Math.round((n / peak) * BAR_W)); out.push( {` ${ljust(sigName(sig), 11)}`} {"█".repeat(filled)} {"·".repeat(BAR_W - filled)} {` ${count(n)}`} , ); } out.push({" "}); out.push({" BY SOURCE"}); for (const [key, label] of SOURCES) { const n = s.bySrc[key] || 0; if (!n && key !== "kill" && key !== "tgkill") continue; out.push( {` ${ljust(label, 10)}`} {count(n)} , ); } out.push({" "}); out.push({" DELIVERY"}); const d = s.byDisp || {}; for (const [key, label, color] of DISPOS) { const n = d[key] || 0; out.push( {` ${ljust(label, 10)}`} {count(n)} , ); } const ei = s.eintr || 0; out.push( {` ${ljust("↯ eintr", 10)}`} {count(ei)} , ); return out; }} ); }