From e27289860f31364b5b4e8e487dc35ed3e135fcc7 Mon Sep 17 00:00:00 2001 From: 4 Bytes Robby Date: Sun, 14 Jun 2026 14:11:13 +0200 Subject: [PATCH] fix: filter bus messages by session ID to prevent cross-session bleed #143 - status.ts: include sessionId in published payload - tui.tsx: filter brain/status subscription by current sessionId - tui.tsx: defensive filter on per-session channel too --- src/status.ts | 2 +- src/tui.tsx | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/status.ts b/src/status.ts index caf77dd..6753a67 100644 --- a/src/status.ts +++ b/src/status.ts @@ -116,7 +116,7 @@ export function stopStatusServer(): void { function write(data: Record): void { _state.current = { ..._state.current, ...data }; - const payload = { ..._state.current, version: _version } as BrainStatusEvent; + const payload = { ..._state.current, version: _version, sessionId: _sessionId || undefined } as BrainStatusEvent; // Real-time push via plugin bus (HTTP fallback still serves status endpoint) getBus() diff --git a/src/tui.tsx b/src/tui.tsx index 6e9568a..1e8f550 100644 --- a/src/tui.tsx +++ b/src/tui.tsx @@ -87,7 +87,10 @@ function BrainStatusBar(props: { centered?: boolean; api: TuiPluginApi; sessionI // also subscribe to the per-session channel (server switches to it // after first chat.message). Prevents missing pre-session status updates. unsub = b.subscribe("brain/status", (envelope) => { - handleStatus(envelope.payload as BrainStatusEvent); + const data = envelope.payload as BrainStatusEvent & { sessionId?: string }; + // Only process if no session ID OR matches current session + if (data.sessionId && props.sessionId && data.sessionId !== props.sessionId) return; + handleStatus(data); }); }) .catch((err) => { @@ -103,7 +106,9 @@ function BrainStatusBar(props: { centered?: boolean; api: TuiPluginApi; sessionI sessionUnsub?.(); if (!sid || !b) return; sessionUnsub = b.subscribe(`brain/${sid}`, (envelope) => { - handleStatus(envelope.payload as BrainStatusEvent); + const data = envelope.payload as BrainStatusEvent & { sessionId?: string }; + if (data.sessionId && data.sessionId !== sid) return; + handleStatus(data); }); }); });