From 3f460bab8427cabc63f4ade1c4195059c4e08765 Mon Sep 17 00:00:00 2001 From: anti Date: Wed, 22 Apr 2026 17:48:04 -0400 Subject: [PATCH] feat(web): show MazeNET decky running count + roll into dashboard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MazeNET header now reports '{running}/{total} DECKIES RUNNING' so operators can see per-topology runtime status at a glance. Dashboard ACTIVE DECKIES counters used to reflect only the fleet state file; TopologyDecky rows (MazeNET deployments) are now added in — deployed_deckies = fleet + all topology rows, active_deckies = fleet (no runtime field) + topology rows whose state is 'running'. --- decnet/web/db/sqlmodel_repo.py | 18 +++++++++++++++--- decnet_web/src/components/MazeNET/MazeNET.tsx | 5 ++++- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/decnet/web/db/sqlmodel_repo.py b/decnet/web/db/sqlmodel_repo.py index 059558cd..fa1e5b9b 100644 --- a/decnet/web/db/sqlmodel_repo.py +++ b/decnet/web/db/sqlmodel_repo.py @@ -349,15 +349,27 @@ class SQLModelRepository(BaseRepository): select(func.count(func.distinct(Log.attacker_ip))) ) ).scalar() or 0 + topo_total = ( + await session.execute(select(func.count()).select_from(TopologyDecky)) + ).scalar() or 0 + topo_running = ( + await session.execute( + select(func.count()) + .select_from(TopologyDecky) + .where(TopologyDecky.state == "running") + ) + ).scalar() or 0 _state = await asyncio.to_thread(load_state) - deployed_deckies = len(_state[0].deckies) if _state else 0 + fleet_deckies = len(_state[0].deckies) if _state else 0 return { "total_logs": total_logs, "unique_attackers": unique_attackers, - "active_deckies": deployed_deckies, - "deployed_deckies": deployed_deckies, + # Fleet state file doesn't track per-decky runtime; treat all + # fleet rows as active and add MazeNET running rows on top. + "active_deckies": fleet_deckies + topo_running, + "deployed_deckies": fleet_deckies + topo_total, } async def get_deckies(self) -> List[dict]: diff --git a/decnet_web/src/components/MazeNET/MazeNET.tsx b/decnet_web/src/components/MazeNET/MazeNET.tsx index d44c6ed6..14cf62a2 100644 --- a/decnet_web/src/components/MazeNET/MazeNET.tsx +++ b/decnet_web/src/components/MazeNET/MazeNET.tsx @@ -529,6 +529,8 @@ const MazeNET: React.FC = () => { }, []); const canDeploy = topoStatus === 'pending' && nets.length > 0; + const deckyNodes = nodes.filter((n) => n.kind === 'decky'); + const runningDeckies = deckyNodes.filter((n) => n.status === 'active').length; return (
@@ -537,7 +539,8 @@ const MazeNET: React.FC = () => {

MAZENET · {topoName || topologyId}

NETWORK OF NETWORKS · {topoStatus.toUpperCase()} · v{topoVersion} ·{' '} - {nets.length} NETS · {nodes.length} NODES · {edges.length} PATHS + {nets.length} NETS · {nodes.length} NODES · {edges.length} PATHS ·{' '} + {runningDeckies}/{deckyNodes.length} DECKIES RUNNING {streamEnabled && ( {' '}· {streamLive ? 'LIVE' : 'CONNECTING…'}