From 681c987911b18e565195ceb85e6c0d02f022bd0c Mon Sep 17 00:00:00 2001 From: dimakis Date: Wed, 20 May 2026 11:18:19 +0100 Subject: [PATCH 1/2] fix(server): add sessionId to user_message echo to prevent cross-session bleed user_message events were echoed to clients without sessionId, bypassing the v2 session filter in the frontend store. The filter treated them as global events, causing user input from other sessions to appear in the active session view. Adding sessionId + v:2 to the echo payload at all three emission sites (resume, send, interrupt) aligns user_message with every other session-scoped v2 event. Co-Authored-By: Claude Opus 4.6 --- frontend/src/types/ws-messages.ts | 1 + server/chat.ts | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/frontend/src/types/ws-messages.ts b/frontend/src/types/ws-messages.ts index a16d8fe1..aa22e1c6 100644 --- a/frontend/src/types/ws-messages.ts +++ b/frontend/src/types/ws-messages.ts @@ -170,6 +170,7 @@ interface UserMessageMsg { v: 2; messageId: string; text: string; + sessionId?: string; } interface SessionRenamedMsg { diff --git a/server/chat.ts b/server/chat.ts index e6f687ce..db8575e4 100644 --- a/server/chat.ts +++ b/server/chat.ts @@ -954,7 +954,7 @@ async function _startChatInner( }); eventStore.updateLastSpeaker(options.resume, 'user'); _onSessionChange?.(clientId, 'user_message'); - const echo = { type: 'user_message', messageId, text: fullPrompt }; + const echo = { type: 'user_message', v: 2, messageId, text: fullPrompt, sessionId: options.resume }; send(transport, echo); broadcastToObservers(session.observers, echo); } @@ -1081,7 +1081,7 @@ export function sendToChat( /* errors logged internally */ }); } - const echo = { type: 'user_message', messageId, text: fullPrompt }; + const echo = { type: 'user_message', v: 2, messageId, text: fullPrompt, ...(session.sessionId ? { sessionId: session.sessionId } : {}) }; send(session.transport, echo); broadcastToObservers(session.observers, echo); session.inputQueue.push(makeUserMessage(fullPrompt, 'next')); @@ -1115,7 +1115,7 @@ export async function interruptChat( eventStore.updateLastSpeaker(session.sessionId, 'user'); _onSessionChange?.(clientId, 'user_message'); } - const echo = { type: 'user_message', messageId, text: fullPrompt }; + const echo = { type: 'user_message', v: 2, messageId, text: fullPrompt, ...(session.sessionId ? { sessionId: session.sessionId } : {}) }; send(session.transport, echo); broadcastToObservers(session.observers, echo); // Stop all active subagent tasks before interrupting the parent query. From baef3938280c2eaa74a1a0b930f052fdbe8041c9 Mon Sep 17 00:00:00 2001 From: dimakis Date: Fri, 29 May 2026 18:16:00 +0100 Subject: [PATCH 2/2] style(server): fix prettier formatting in chat.ts Co-Authored-By: Claude Opus 4.6 --- server/chat.ts | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/server/chat.ts b/server/chat.ts index db8575e4..a5ae2728 100644 --- a/server/chat.ts +++ b/server/chat.ts @@ -954,7 +954,13 @@ async function _startChatInner( }); eventStore.updateLastSpeaker(options.resume, 'user'); _onSessionChange?.(clientId, 'user_message'); - const echo = { type: 'user_message', v: 2, messageId, text: fullPrompt, sessionId: options.resume }; + const echo = { + type: 'user_message', + v: 2, + messageId, + text: fullPrompt, + sessionId: options.resume, + }; send(transport, echo); broadcastToObservers(session.observers, echo); } @@ -1081,7 +1087,13 @@ export function sendToChat( /* errors logged internally */ }); } - const echo = { type: 'user_message', v: 2, messageId, text: fullPrompt, ...(session.sessionId ? { sessionId: session.sessionId } : {}) }; + const echo = { + type: 'user_message', + v: 2, + messageId, + text: fullPrompt, + ...(session.sessionId ? { sessionId: session.sessionId } : {}), + }; send(session.transport, echo); broadcastToObservers(session.observers, echo); session.inputQueue.push(makeUserMessage(fullPrompt, 'next')); @@ -1115,7 +1127,13 @@ export async function interruptChat( eventStore.updateLastSpeaker(session.sessionId, 'user'); _onSessionChange?.(clientId, 'user_message'); } - const echo = { type: 'user_message', v: 2, messageId, text: fullPrompt, ...(session.sessionId ? { sessionId: session.sessionId } : {}) }; + const echo = { + type: 'user_message', + v: 2, + messageId, + text: fullPrompt, + ...(session.sessionId ? { sessionId: session.sessionId } : {}), + }; send(session.transport, echo); broadcastToObservers(session.observers, echo); // Stop all active subagent tasks before interrupting the parent query.