diff --git a/apps/dashboard/src/lib/stores/websocket.ts b/apps/dashboard/src/lib/stores/websocket.ts index 8ae8c65..f96d229 100644 --- a/apps/dashboard/src/lib/stores/websocket.ts +++ b/apps/dashboard/src/lib/stores/websocket.ts @@ -105,3 +105,24 @@ export const avgRetention = derived(websocket, $ws => export const suppressedCount = derived(websocket, $ws => ($ws.lastHeartbeat?.data?.suppressed_count as number) ?? 0 ); + +// v2.0.7: uptime of the MCP server in seconds, refreshed every heartbeat. +// Exposed raw so callers can format as they like; the helper below is the +// standard compact format ("3d 4h 22m", "18m", "47s") used in the sidebar. +export const uptimeSeconds = derived(websocket, $ws => + ($ws.lastHeartbeat?.data?.uptime_secs as number) ?? 0 +); + +export function formatUptime(secs: number): string { + if (!Number.isFinite(secs) || secs < 0) return '—'; + const d = Math.floor(secs / 86_400); + const h = Math.floor((secs % 86_400) / 3_600); + const m = Math.floor((secs % 3_600) / 60); + const s = Math.floor(secs % 60); + // Compact representation: show the two most significant units so the + // sidebar stays readable ("3d 4h" not "3d 4h 22m 17s", "18m 43s", etc). + if (d > 0) return h > 0 ? `${d}d ${h}h` : `${d}d`; + if (h > 0) return m > 0 ? `${h}h ${m}m` : `${h}h`; + if (m > 0) return s > 0 ? `${m}m ${s}s` : `${m}m`; + return `${s}s`; +} diff --git a/apps/dashboard/src/routes/+layout.svelte b/apps/dashboard/src/routes/+layout.svelte index 5050f37..48eb79a 100644 --- a/apps/dashboard/src/routes/+layout.svelte +++ b/apps/dashboard/src/routes/+layout.svelte @@ -4,7 +4,15 @@ import { page } from '$app/stores'; import { goto } from '$app/navigation'; import { base } from '$app/paths'; - import { websocket, isConnected, memoryCount, avgRetention, suppressedCount } from '$stores/websocket'; + import { + websocket, + isConnected, + memoryCount, + avgRetention, + suppressedCount, + uptimeSeconds, + formatUptime, + } from '$stores/websocket'; import ForgettingIndicator from '$lib/components/ForgettingIndicator.svelte'; let { children } = $props(); @@ -141,9 +149,14 @@
-