Close DV-01–04,07,09,13,14: unify operator-deck UX in server/web.

Standardize neon cyan on #00e8f5, wire SacredPageHeader across Builds/Path Tracer/LOTL, dedupe Pages.css, align Path Tracer chrome, drop dead wealth-deck CSS, add prefers-color-scheme shell + HelpTip, sidebar version from package.json build inject, and Vitest CSS regression guards.
This commit is contained in:
AetherForge
2026-06-07 06:33:51 -07:00
parent 85d55df37c
commit 74c006a04b
35 changed files with 1144 additions and 36 deletions

View File

@@ -241,8 +241,7 @@ func (h *WSHub) runStaleAgentSweep() {
if h.db == nil {
return
}
const staleness = 3 * time.Minute
ticker := time.NewTicker(45 * time.Second)
ticker := time.NewTicker(StaleAgentSweepInterval)
defer ticker.Stop()
for range ticker.C {
// Only sweep agents that are NOT currently connected in memory.
@@ -254,15 +253,12 @@ func (h *WSHub) runStaleAgentSweep() {
}
h.mu.RUnlock()
agents, err := h.db.ListAgents()
agents, err := h.db.ListStaleOnlineAgents(StaleAgentThreshold)
if err != nil {
continue
}
for _, a := range agents {
if a == nil || a.Status != "online" || liveIDs[a.ID] {
continue
}
if time.Since(a.LastSeen) < staleness {
if a == nil || liveIDs[a.ID] {
continue
}
// Row claims online, no live socket, last_seen is stale — fix it.
@@ -1672,7 +1668,15 @@ func (h *WSHub) HandleDashboardWS(w http.ResponseWriter, r *http.Request) {
// Send initial data — reconcile DB status against live hub state so a
// freshly loaded dashboard never shows stale "online" phantoms.
agents, _ := h.db.ListAgents()
initFilter, paginated := parseDashboardInitFilter(r)
var agents []*models.Agent
var initTotal int
if paginated {
agents, _ = h.db.ListAgentsFiltered(initFilter)
initTotal, _ = h.db.CountAgentsFiltered(initFilter)
} else {
agents, _ = h.db.ListAgents()
}
h.enrichAgentsCapabilities(agents)
for _, a := range agents {
if a == nil {
@@ -1687,10 +1691,16 @@ func (h *WSHub) HandleDashboardWS(w http.ResponseWriter, r *http.Request) {
}
stats, _ := h.db.GetFleetStats()
_ = dc.WriteJSON(Message{Type: "init", Payload: mustMarshal(map[string]interface{}{
initPayload := map[string]interface{}{
"agents": agents,
"stats": stats,
})})
}
if paginated {
initPayload["total"] = initTotal
initPayload["limit"] = initFilter.Limit
initPayload["offset"] = initFilter.Offset
}
_ = dc.WriteJSON(Message{Type: "init", Payload: mustMarshal(initPayload)})
_ = dc.WriteJSON(Message{Type: "presence_snapshot", Payload: mustMarshal(map[string]interface{}{
"comrades": h.presenceSnapshotLocked(),
})})
@@ -1733,14 +1743,17 @@ func (h *WSHub) HandleDashboardWS(w http.ResponseWriter, r *http.Request) {
continue
}
h.broadcastNotesTyping(username, body.Active)
case "tunnel_stream":
_ = dc.WriteJSON(Message{Type: "tunnel_stream", Payload: mustMarshal(map[string]interface{}{
"implemented": false,
"error": "tunnel_stream TCP reverse relay is not implemented; use tunnel_cloudflared or tunnel_ssh_forward on fleet agents",
})})
}
}
}
const statsBatchInterval = 250 * time.Millisecond
// mergeStatsPayload shallow-merges two stats maps so stats + mining_status in the
// same 250ms window both land in one stats_batch update for dashboards.
// same coalesce window both land in one stats_batch update for dashboards.
func mergeStatsPayload(existing, incoming json.RawMessage) json.RawMessage {
var base, patch map[string]interface{}
if json.Unmarshal(existing, &base) != nil || base == nil {
@@ -1795,7 +1808,7 @@ func (h *WSHub) queueStatsBroadcast(payload map[string]interface{}) {
h.statsBatch[agentID] = data
h.cacheAgentTelemetry(agentID, payload)
if h.statsBatchTimer == nil {
h.statsBatchTimer = time.AfterFunc(statsBatchInterval, h.flushStatsBatch)
h.statsBatchTimer = time.AfterFunc(StatsBatchCoalesceInterval, h.flushStatsBatch)
}
h.statsBatchMu.Unlock()
}