mirror of
https://github.com/samvallad33/vestige.git
synced 2026-05-17 18:35:17 +02:00
feat(dashboard): surface Heartbeat uptime_secs in the sidebar footer
The Heartbeat event has shipped since v2.0.5 carrying uptime_secs,
memory_count, avg_retention, suppressed_count. Three of the four were
already wired into the sidebar footer (memory count, retention,
forgetting indicator). uptime_secs was the one field that fired every
30 seconds into a silent void.
Added:
- `uptimeSeconds` derived store + `formatUptime(secs)` helper in
websocket.ts. The helper picks the two most significant units so the
sidebar stays tight: "3d 4h" instead of "3d 4h 22m 17s", "18m 43s"
for shorter runs, "47s" on a fresh boot.
- New line in the sidebar status footer between retention and the
ForgettingIndicator: "up 3d 4h" with a hover tooltip ("MCP server
uptime") for discoverability. Hidden at sub-lg breakpoints to match
the existing responsive pattern of the surrounding text.
Zero backend work — the data was already on the wire. This is pure
UI gap closure: four of four Heartbeat fields now visible.
svelte-check clean (580 files, 0 errors).
This commit is contained in:
parent
fc6dca6338
commit
7a3d30914d
2 changed files with 36 additions and 2 deletions
|
|
@ -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`;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue