fix(vscode): normalize Windows directory paths for SSE event store lookup (#818)

On Windows, SSE events from OpenCode arrive with native backslash
separators and system-cased drive letters (e.g. D:\Dev\...), while the
UI child store keys use forward slashes with lowercase drive letters
from VS Code's workspace folder (e.g. d:/Dev/...). This mismatch
caused the child store Map lookup to silently miss on every directory
event, preventing session data, messages, and streaming responses from
reaching the React UI.

Changes:
- sync-context.tsx: Normalize incoming SSE event directory paths by
  converting backslashes to forward slashes and uppercasing Windows
  drive letters before the child store lookup.
- useDirectoryStore.ts: Add drive letter uppercasing to
  normalizeDirectoryPath, aligning it with normalizeCandidatePath in
  client.ts and normalizeWorkspacePath in main.tsx.

Both normalizations are no-ops on macOS/Linux where paths already use
forward slashes and have no drive letters.

Closes #816
This commit is contained in:
Willian Diaz Pabón
2026-04-02 11:47:32 +03:00
committed by GitHub
parent 507f429674
commit c9d112871c
2 changed files with 10 additions and 2 deletions
+3 -1
View File
@@ -45,7 +45,9 @@ const normalizeDirectoryPath = (value: string): string => {
if (!trimmed) {
return trimmed;
}
const normalized = trimmed.replace(/\\/g, '/');
const normalized = trimmed
.replace(/\\/g, '/')
.replace(/^([a-z]):/, (_, letter: string) => letter.toUpperCase() + ':');
if (normalized.length > 1) {
return normalized.replace(/\/+$/, '');
}
+7 -1
View File
@@ -108,10 +108,16 @@ function isRecentBoot() {
}
function handleEvent(
directory: string,
rawDirectory: string,
payload: Event,
childStores: ChildStoreManager,
) {
// Normalize directory path: SSE events from OpenCode use native OS separators
// (backslashes on Windows) and may differ in drive-letter case.
// Child stores are keyed with forward slashes and uppercase drive letters.
const directory = rawDirectory && rawDirectory !== "global"
? rawDirectory.replace(/\\/g, "/").replace(/^([a-z]):/, (_, l: string) => l.toUpperCase() + ":")
: rawDirectory
// Global events
if (directory === "global" || !directory) {
const recent = isRecentBoot()