import { useCallback, useEffect, useMemo, useState } from "react"; import { Monitor, RefreshCw, X } from "lucide-react"; import { fetchSystemStats, type SystemStatsResponse } from "../api"; import "./SystemStatsModal.css"; interface SystemStatsModalProps { isOpen: boolean; onClose: () => void; projectId?: string; } function formatBytes(bytes: number): string { if (!Number.isFinite(bytes) || bytes < 0) return "—"; const mb = bytes / (1024 * 1024); if (mb < 1024) return `${mb.toFixed(0)} MB`; return `${(mb / 1024).toFixed(2)} GB`; } function toPercent(used: number, total: number): string { if (!Number.isFinite(used) || !Number.isFinite(total) || total <= 0) return "—"; return `${((used / total) * 100).toFixed(1)}%`; } type Severity = "normal" | "warning" | "critical"; function heapSeverity(used: number, limit: number): Severity { if (limit <= 0) return "normal"; const pct = used / limit; if (pct >= 0.85) return "critical"; if (pct >= 0.65) return "warning"; return "normal"; } function rssSeverity(rss: number, totalSystemMem: number): Severity { if (totalSystemMem <= 0) return "normal"; const pct = rss / totalSystemMem; if (pct >= 0.5) return "critical"; if (pct >= 0.25) return "warning"; return "normal"; } function systemMemSeverity(used: number, total: number): Severity { if (total <= 0) return "normal"; const pct = used / total; if (pct >= 0.9) return "critical"; if (pct >= 0.75) return "warning"; return "normal"; } function severityClassName(severity: Severity): string { if (severity === "critical") return "system-stats-modal__value--critical"; if (severity === "warning") return "system-stats-modal__value--warning"; return ""; } /** * SystemStatsModal groups dashboard runtime telemetry into five sections: * process memory metrics, CPU/load information, host memory usage, task counts * by column, and agent state counts. */ export function SystemStatsModal({ isOpen, onClose, projectId }: SystemStatsModalProps) { const [stats, setStats] = useState(null); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const loadStats = useCallback(async () => { setLoading(true); try { const response = await fetchSystemStats(projectId); setStats(response); setError(null); } catch (err) { setError(err instanceof Error ? err.message : "Failed to load system stats"); } finally { setLoading(false); } }, [projectId]); useEffect(() => { if (!isOpen) return; void loadStats(); const timer = window.setInterval(() => { void loadStats(); }, 5_000); return () => { window.clearInterval(timer); }; }, [isOpen, loadStats]); useEffect(() => { if (!isOpen) return; const onKeydown = (event: KeyboardEvent) => { if (event.key === "Escape") onClose(); }; document.addEventListener("keydown", onKeydown); return () => document.removeEventListener("keydown", onKeydown); }, [isOpen, onClose]); const processRows = useMemo(() => { if (!stats) return []; const system = stats.systemStats; const heapClassName = severityClassName(heapSeverity(system.heapUsed, system.heapLimit)); const rssClassName = severityClassName(rssSeverity(system.rss, system.systemTotalMem)); return [ { label: "RSS", value: formatBytes(system.rss), detail: toPercent(system.rss, system.systemTotalMem), className: rssClassName }, { label: "Heap Used", value: formatBytes(system.heapUsed), detail: `of ${formatBytes(system.heapTotal)}`, className: heapClassName }, { label: "Heap Limit", value: formatBytes(system.heapLimit), detail: "V8 limit" }, { label: "External", value: formatBytes(system.external) }, { label: "Array Buffers", value: formatBytes(system.arrayBuffers) }, ]; }, [stats]); if (!isOpen) return null; const system = stats?.systemStats; const taskStats = stats?.taskStats; const usedSystemMem = system ? system.systemTotalMem - system.systemFreeMem : 0; const usedSystemClassName = system ? severityClassName(systemMemSeverity(usedSystemMem, system.systemTotalMem)) : ""; return (
{ if (event.target === event.currentTarget) onClose(); }} data-testid="system-stats-modal-overlay" >

System Stats

{loading && !stats &&
Loading system stats…
} {error && !stats && (
{error}
)} {stats && (

Process

{processRows.map((row) => (
{row.label}
{row.value} {row.detail ? {row.detail} : null}
))}

CPU & Load

Load Avg
{system?.loadAvg.map((value) => value.toFixed(2)).join(" ") ?? "—"}
Cores
{system?.cpuCount ?? "—"}
Platform
{system?.platform ?? "—"}
Node
{system?.nodeVersion ?? "—"}
PID
{system?.pid ?? "—"}

System

Memory Used
{system ? formatBytes(usedSystemMem) : "—"} {system ? `${toPercent(usedSystemMem, system.systemTotalMem)} of ${formatBytes(system.systemTotalMem)}` : ""}
Memory Free
{system ? formatBytes(system.systemFreeMem) : "—"}

Tasks

Total
{taskStats?.total ?? 0}
{Object.entries(taskStats?.byColumn ?? {}).map(([column, count]) => (
{column}
{count}
))}

Agents

idle
{taskStats?.agents.idle ?? 0}
active
{taskStats?.agents.active ?? 0}
running
{taskStats?.agents.running ?? 0}
error
{taskStats?.agents.error ?? 0}
)} {error && stats &&
Latest refresh failed: {error}
}
); }