fix: WSL mount path translation + Windows drive letter normalization

Manually ported from upstream:
- c239cda6: translateWslMountPath() converts /mnt/X/... → X:/... on Windows
- 7f5fbdab: normalizeDriveLetter() uppercases drive letter (c:/ → C:/)

Both are no-op on macOS/Linux. Fixes session fragmentation on Windows+WSL.
This commit is contained in:
iliya 2026-03-25 14:22:04 +02:00
parent aeed5a0873
commit e30f6482bf
2 changed files with 35 additions and 2 deletions

View file

@ -9,11 +9,24 @@ import * as readline from 'readline';
import { LocalFileSystemProvider } from '../services/infrastructure/LocalFileSystemProvider';
import { type ChatHistoryEntry, isTextContent, type UserEntry } from '../types';
import { translateWslMountPath } from './pathDecoder';
import type { FileSystemProvider } from '../services/infrastructure/FileSystemProvider';
import type { Readable } from 'stream';
const logger = createLogger('Util:metadataExtraction');
/**
* Normalize Windows drive letter to uppercase for consistent path comparison.
* CLI uses uppercase (C:\...) while VS Code extension uses lowercase (c:\...).
*/
function normalizeDriveLetter(p: string): string {
if (p.length >= 2 && p[1] === ':') {
return p[0].toUpperCase() + p.slice(1);
}
return p;
}
const defaultProvider = new LocalFileSystemProvider();
const JSONL_HEAD_TIMEOUT_MS = 2000;
@ -100,7 +113,7 @@ export async function extractCwd(
}
// Only conversational entries have cwd
if ('cwd' in entry && entry.cwd) {
return entry.cwd;
return normalizeDriveLetter(translateWslMountPath(entry.cwd));
}
}
} catch (error) {

View file

@ -69,7 +69,10 @@ export function decodePath(encodedName: string): string {
}
// Ensure leading slash for POSIX-style absolute paths
return decodedPath.startsWith('/') ? decodedPath : `/${decodedPath}`;
const absolutePath = decodedPath.startsWith('/') ? decodedPath : `/${decodedPath}`;
// Translate WSL mount paths to Windows drive-letter paths on Windows
return translateWslMountPath(absolutePath);
}
/**
@ -91,6 +94,23 @@ export function extractProjectName(encodedName: string, cwdHint?: string): strin
return segments[segments.length - 1] || encodedName;
}
/**
* Translate WSL mount paths (/mnt/X/...) to Windows drive-letter paths (X:/...)
* when running on Windows. No-op on other platforms.
*/
export function translateWslMountPath(posixPath: string): string {
if (process.platform !== 'win32') {
return posixPath;
}
const match = /^\/mnt\/([a-zA-Z])(\/.*)?$/.exec(posixPath);
if (match) {
const drive = match[1].toUpperCase();
const rest = match[2] ?? '';
return `${drive}:${rest}`;
}
return posixPath;
}
// =============================================================================
// Validation
// =============================================================================