From 652d3ce40cf214576debc56af97740c402ef6ab3 Mon Sep 17 00:00:00 2001 From: Dev Lead Agent Date: Tue, 14 Apr 2026 08:21:57 +0000 Subject: [PATCH 1/2] feat(canvas): add WebSocket connection status indicator to Toolbar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a live/reconnecting/offline pill to the Toolbar so users can see at a glance whether the canvas is receiving real-time updates. Changes: - canvas/src/store/canvas.ts: add wsStatus ('connected'|'connecting'| 'disconnected') field + setWsStatus action to CanvasState (initial: 'connecting') - canvas/src/store/socket.ts: wire setWsStatus into ReconnectingSocket — 'connecting' on connect() call, 'connected' in onopen, 'connecting' in onclose (will reconnect), 'disconnected' in disconnect() - canvas/src/components/Toolbar.tsx: subscribe to wsStatus; render WsStatusPill (green "Live" / amber pulsing "Reconnecting" / red "Offline") after the workspace count section - canvas/src/store/__tests__/socket.test.ts: add setWsStatus: vi.fn() to the canvas store mock (global factory, beforeEach reset, and the mid-test override in the onmessage test) 369/369 canvas tests passing, production build clean. Co-Authored-By: Claude Sonnet 4.6 --- canvas/src/components/Toolbar.tsx | 31 +++++++++++++++++++++++ canvas/src/store/__tests__/socket.test.ts | 3 +++ canvas/src/store/canvas.ts | 5 ++++ canvas/src/store/socket.ts | 4 +++ 4 files changed, 43 insertions(+) diff --git a/canvas/src/components/Toolbar.tsx b/canvas/src/components/Toolbar.tsx index ce766c32..6b5c3bd7 100644 --- a/canvas/src/components/Toolbar.tsx +++ b/canvas/src/components/Toolbar.tsx @@ -10,6 +10,7 @@ import { showToast } from "@/components/Toaster"; export function Toolbar() { const nodes = useCanvasStore((s) => s.nodes); + const wsStatus = useCanvasStore((s) => s.wsStatus); const [stopping, setStopping] = useState(false); const [restartingAll, setRestartingAll] = useState(false); @@ -122,6 +123,11 @@ export function Toolbar() { + {/* WebSocket connection status */} +
+ +
+ {/* Stop All — visible when agents have active tasks */} {counts.activeTasks > 0 && (