diff --git a/packages/vscode/src/AgentManagerPanelProvider.ts b/packages/vscode/src/AgentManagerPanelProvider.ts index b5dafa98..86e7c2d8 100644 --- a/packages/vscode/src/AgentManagerPanelProvider.ts +++ b/packages/vscode/src/AgentManagerPanelProvider.ts @@ -156,7 +156,12 @@ export class AgentManagerPanelProvider { const { path, headers } = (payload || {}) as { path?: string; headers?: Record }; const normalizedPath = typeof path === 'string' && path.trim().length > 0 ? path.trim() : '/event'; - const shouldInjectActivity = normalizedPath === '/event' || normalizedPath === '/global/event'; + const normalizedPathname = (() => { + const rawPathname = normalizedPath.split('?')[0]; + if (rawPathname === '/') return '/'; + return rawPathname.replace(/\/+$/, ''); + })(); + const shouldInjectActivity = normalizedPathname === '/event' || normalizedPathname === '/global/event'; if (!apiBaseUrl) { return { @@ -189,7 +194,7 @@ export class AgentManagerPanelProvider { }); // Fallback for OpenCode versions without /global/event. - if ((!response.ok || !response.body) && normalizedPath === '/global/event') { + if ((!response.ok || !response.body) && normalizedPathname === '/global/event') { const fallbackUrl = new URL('event', base).toString(); response = await fetch(fallbackUrl, { method: 'GET', @@ -259,7 +264,7 @@ export class AgentManagerPanelProvider { if (!chunk) continue; // Reduce webview message pressure by forwarding complete SSE blocks. - sseBuffer += shouldInjectActivity ? chunk.replace(/\r\n/g, '\n') : chunk; + sseBuffer += chunk.replace(/\r\n/g, '\n'); const blocks = sseBuffer.split('\n\n'); sseBuffer = blocks.pop() ?? ''; if (blocks.length > 0) { @@ -275,7 +280,7 @@ export class AgentManagerPanelProvider { const tail = decoder.decode(); if (tail) { - sseBuffer += shouldInjectActivity ? tail.replace(/\r\n/g, '\n') : tail; + sseBuffer += tail.replace(/\r\n/g, '\n'); } if (sseBuffer) { if (shouldInjectActivity) { diff --git a/packages/vscode/src/ChatViewProvider.ts b/packages/vscode/src/ChatViewProvider.ts index 4cadab28..888b7685 100644 --- a/packages/vscode/src/ChatViewProvider.ts +++ b/packages/vscode/src/ChatViewProvider.ts @@ -184,7 +184,12 @@ export class ChatViewProvider implements vscode.WebviewViewProvider { const { path, headers } = (payload || {}) as { path?: string; headers?: Record }; const normalizedPath = typeof path === 'string' && path.trim().length > 0 ? path.trim() : '/event'; - const shouldInjectActivity = normalizedPath === '/event' || normalizedPath === '/global/event'; + const normalizedPathname = (() => { + const rawPathname = normalizedPath.split('?')[0]; + if (rawPathname === '/') return '/'; + return rawPathname.replace(/\/+$/, ''); + })(); + const shouldInjectActivity = normalizedPathname === '/event' || normalizedPathname === '/global/event'; if (!apiBaseUrl) { return { @@ -218,7 +223,7 @@ export class ChatViewProvider implements vscode.WebviewViewProvider { // Fallback: OpenCode versions without /global/event. // VS Code is single-workspace, so we can wrap /event into { directory, payload }. - if ((!response.ok || !response.body) && normalizedPath === '/global/event') { + if ((!response.ok || !response.body) && normalizedPathname === '/global/event') { const fallbackUrl = new URL('event', base).toString(); response = await fetch(fallbackUrl, { method: 'GET', @@ -290,7 +295,7 @@ export class ChatViewProvider implements vscode.WebviewViewProvider { // Reduce webview message pressure by forwarding complete SSE blocks. // The SDK SSE parser is block-based (\n\n delimited) and can consume // partial chunks, but VS Code's postMessage channel can be a bottleneck. - sseBuffer += shouldInjectActivity ? chunk.replace(/\r\n/g, '\n') : chunk; + sseBuffer += chunk.replace(/\r\n/g, '\n'); const blocks = sseBuffer.split('\n\n'); sseBuffer = blocks.pop() ?? ''; if (blocks.length > 0) { @@ -306,7 +311,7 @@ export class ChatViewProvider implements vscode.WebviewViewProvider { const tail = decoder.decode(); if (tail) { - sseBuffer += shouldInjectActivity ? tail.replace(/\r\n/g, '\n') : tail; + sseBuffer += tail.replace(/\r\n/g, '\n'); } if (sseBuffer) { if (shouldInjectActivity) { diff --git a/packages/vscode/src/SessionEditorPanelProvider.ts b/packages/vscode/src/SessionEditorPanelProvider.ts index 5790c3fc..e44692f6 100644 --- a/packages/vscode/src/SessionEditorPanelProvider.ts +++ b/packages/vscode/src/SessionEditorPanelProvider.ts @@ -179,7 +179,12 @@ export class SessionEditorPanelProvider { const { path, headers } = (payload || {}) as { path?: string; headers?: Record }; const normalizedPath = typeof path === 'string' && path.trim().length > 0 ? path.trim() : '/event'; - const shouldInjectActivity = normalizedPath === '/event' || normalizedPath === '/global/event'; + const normalizedPathname = (() => { + const rawPathname = normalizedPath.split('?')[0]; + if (rawPathname === '/') return '/'; + return rawPathname.replace(/\/+$/, ''); + })(); + const shouldInjectActivity = normalizedPathname === '/event' || normalizedPathname === '/global/event'; if (!apiBaseUrl) { return { @@ -213,7 +218,7 @@ export class SessionEditorPanelProvider { // Fallback: OpenCode versions without /global/event. // VS Code is single-workspace, so we can wrap /event into { directory, payload }. - if ((!response.ok || !response.body) && normalizedPath === '/global/event') { + if ((!response.ok || !response.body) && normalizedPathname === '/global/event') { const fallbackUrl = new URL('event', base).toString(); response = await fetch(fallbackUrl, { method: 'GET', @@ -282,7 +287,7 @@ export class SessionEditorPanelProvider { const chunk = decoder.decode(value, { stream: true }); if (!chunk) continue; - sseBuffer += shouldInjectActivity ? chunk.replace(/\r\n/g, '\n') : chunk; + sseBuffer += chunk.replace(/\r\n/g, '\n'); const blocks = sseBuffer.split('\n\n'); sseBuffer = blocks.pop() ?? ''; if (blocks.length > 0) { @@ -298,7 +303,7 @@ export class SessionEditorPanelProvider { const tail = decoder.decode(); if (tail) { - sseBuffer += shouldInjectActivity ? tail.replace(/\r\n/g, '\n') : tail; + sseBuffer += tail.replace(/\r\n/g, '\n'); } if (sseBuffer) { if (shouldInjectActivity) {