fix(ui,server): normalize Windows drive letter casing for consistent path resolution (#2154)
* fix(ui,server): normalize Windows drive letter casing for consistent path resolution Provider settings were failing to persist for specific projects on Windows because path normalization was inconsistent across the codebase. Some normalizePath functions uppercased the Windows drive letter (c:\ -> C:\) and others did not, causing: - directoryScoped cache misses (different keys for the same directory) - broken model selection in the affected project - lost conversation history (sessions could not match their project) - false cache hits in resolveConfigDirectory on undefined inputs This change extracts a single shared normalizePath utility and uses it from the 5 client sites that were missing the drive letter normalization. The server-side normalizePathForPersistence is updated to uppercase the drive letter both before and after safeRealpathSync, so the persisted path is consistent even when realpath returns a symlink/junction with a lowercase drive letter on some Windows environments. Fixes #2109 * test(ui,server): add coverage for Windows path normalization Address review feedback on #2154: - Add Windows-platform test for normalizePathForPersistence covering drive letter uppercase on input and after realpath resolution - Add dedicated test suite for the shared normalizePath utility - Defensive fix: normalizePath now returns null for paths that consist only of slashes (\\, ///), matching the documented contract Refs #2154 * fix(server): scope drive casing normalization to Windows --------- Co-authored-by: bashrusakh <bashrusakh@users.noreply.github.com> Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
This commit is contained in:
committed by
GitHub
co-authored by
bashrusakh
Bohdan Triapitsyn
parent
9dd389fe8e
commit
9624d4b6f6
@@ -52,6 +52,27 @@ describe('settings normalization runtime - symlink resolution', () => {
|
||||
const result = runtime.normalizePathForPersistence('/some/path');
|
||||
expect(result).toBe('/some/path');
|
||||
});
|
||||
|
||||
it('preserves lowercase colon-prefixed paths on non-Windows platforms', () => {
|
||||
const runtime = createTestRuntime({ realpathSync: undefined });
|
||||
|
||||
expect(runtime.normalizePathForPersistence('c:project')).toBe('c:project');
|
||||
});
|
||||
|
||||
it('uppercases Windows drive letter before and after realpath resolution', () => {
|
||||
const runtime = createTestRuntime({
|
||||
processLike: { platform: 'win32', env: {} },
|
||||
realpathSync: (p) => {
|
||||
// Simulate safeRealpathSync returning a lowercase drive letter
|
||||
if (p === 'C:\\Users\\me\\project') return 'c:\\real\\project';
|
||||
return p;
|
||||
},
|
||||
});
|
||||
|
||||
const result = runtime.normalizePathForPersistence('c:\\Users\\me\\project');
|
||||
// Drive letter uppercased on input AND after realpath
|
||||
expect(result).toBe('C:\\real\\project');
|
||||
});
|
||||
});
|
||||
|
||||
describe('sanitizeProjects', () => {
|
||||
|
||||
Reference in New Issue
Block a user