fix: translate WSL mount paths to Windows drive-letter paths#127
fix: translate WSL mount paths to Windows drive-letter paths#127
Conversation
Sessions started from WSL encode POSIX paths (/mnt/d/...) in cwd, which aren't recognized as Windows paths (D:/...) by the app. Add translateWslMountPath() to convert /mnt/X/... → X:/... on Windows, applied in both decodePath() and extractCwd(). Fixes #118 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request resolves an issue where paths originating from Windows Subsystem for Linux (WSL) sessions were not correctly interpreted by the application when running on Windows. By introducing a path translation mechanism, the application can now seamlessly handle POSIX-style WSL mount paths, converting them into native Windows drive-letter paths. This ensures proper functionality and compatibility for users working within WSL environments. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
There was a problem hiding this comment.
Pull request overview
Fixes Windows DevTools path handling for sessions/projects created under WSL by translating WSL mount-style POSIX paths (/mnt/d/...) into Windows drive-letter paths (D:/...) when running on Windows.
Changes:
- Added
translateWslMountPath()and applied it todecodePath()output on Windows. - Applied the same WSL mount translation to
extractCwd()results before drive-letter normalization.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/main/utils/pathDecoder.ts |
Adds WSL mount path translation and applies it during encoded project path decoding. |
src/main/utils/metadataExtraction.ts |
Uses shared WSL mount translation when extracting authoritative cwd from session JSONL. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const match = /^\/mnt\/([a-zA-Z])(\/.*)?$/.exec(posixPath); | ||
| if (match) { | ||
| const drive = match[1].toUpperCase(); | ||
| const rest = match[2] ?? ''; |
There was a problem hiding this comment.
translateWslMountPath() returns "D:" for an input like "/mnt/d" (no trailing slash). On Windows, "D:" is not an absolute path (path.isAbsolute('D:') is false), which can break downstream path resolution and cause fallbacks back to POSIX paths. Consider defaulting the "rest" portion to "/" when the mount path has no trailing segment so the result is "D:/".
| const rest = match[2] ?? ''; | |
| const rest = match[2] ?? '/'; |
| // Ensure leading slash for POSIX-style absolute paths | ||
| return decodedPath.startsWith('/') ? decodedPath : `/${decodedPath}`; | ||
| const absolutePath = decodedPath.startsWith('/') ? decodedPath : `/${decodedPath}`; | ||
|
|
There was a problem hiding this comment.
This change introduces Windows-only behavior (WSL mount translation) in decodePath()/extractCwd(), but there are no unit tests covering the translation cases (e.g., "/mnt/d/repo" -> "D:/repo", and "/mnt/d" -> "D:/"), nor a non-Windows no-op assertion. Since CI runs on both Ubuntu and Windows, adding conditional tests would help prevent regressions.
| // On non-Windows platforms, return the POSIX-style absolute path unchanged | |
| if (os.platform() !== 'win32') { | |
| return absolutePath; | |
| } |
There was a problem hiding this comment.
Code Review
This pull request introduces a fix to correctly handle WSL mount paths by translating them to Windows drive-letter paths. A new utility function translateWslMountPath is added for this conversion and is used in decodePath and extractCwd. The implementation is well-focused, but I've found a minor bug in the new function where it fails to correctly handle paths pointing to the root of a drive, which I've commented on with a suggestion for a fix.
| const rest = match[2] ?? ''; | ||
| return `${drive}:${rest}`; |
There was a problem hiding this comment.
When translating a WSL path that points to the root of a drive (e.g., /mnt/c), match[2] is undefined, and rest becomes ''. This results in returning C:, which is not a valid absolute path and can cause issues with path joining later. The path should be C:/. You can handle this more concisely.
| const rest = match[2] ?? ''; | |
| return `${drive}:${rest}`; | |
| return `${drive}:${match[2] || '/'}`; |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
✅ Files skipped from review due to trivial changes (1)
📝 WalkthroughWalkthroughAdds WSL-to-Windows path translation and applies it to decoded and extracted paths: Changes
Possibly related PRs
🚥 Pre-merge checks | ✅ 1 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c239cda6e6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| rl.close(); | ||
| fileStream.destroy(); | ||
| return normalizeDriveLetter(entry.cwd); | ||
| return normalizeDriveLetter(translateWslMountPath(entry.cwd)); |
There was a problem hiding this comment.
Gate WSL path translation to local sessions
On Windows hosts this now rewrites every cwd read from a session file, including files coming from SshFileSystemProvider. ProjectPathResolver.resolveProjectPath() still calls extractCwd() for fsProvider.type === 'ssh', so a remote Linux project rooted at /mnt/d/repo will now be surfaced as D:/repo in ProjectScanner and session exports even though the session is remote. That loses the real remote path and can point path-based UI/actions at an unrelated local drive when someone SSHes into a WSL/Unix machine that uses /mnt/<drive> mounts.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/main/utils/pathDecoder.ts`:
- Around line 101-110: The translateWslMountPath function returns "C:" for input
"/mnt/c", which is not an absolute Windows path; update the logic in
translateWslMountPath to default the captured tail to '/' instead of '' (change
the rest assignment from match[2] ?? '' to match[2] ?? '/') so the function
returns "C:/" for mount-root inputs, and add a unit test for the "/mnt/c" case
to assert the output is "C:/" (or otherwise absolute per path.win32.isAbsolute)
to prevent regression.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: b97b06a1-e6c6-427a-abe3-f1f7414fe362
📒 Files selected for processing (2)
src/main/utils/metadataExtraction.tssrc/main/utils/pathDecoder.ts
| 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}`; | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
In Node.js on Windows, what does path.win32.isAbsolute('C:') return, and what is the correct absolute drive-root format?
💡 Result:
In Node.js on Windows, path.win32.isAbsolute('C:') returns false. The correct absolute drive-root format is 'C:\' or 'C:/' (drive letter followed by colon and path separator).
Citations:
- 1: nodejs/node@1c4007927d
- 2: https://github.com/nodejs/node/blob/main/lib/path.js
- 3: https://nodejs.org/api/path.html
🏁 Script executed:
# Find the pathDecoder.ts file and examine the function
find . -name "pathDecoder.ts" -type f | head -5Repository: matt1398/claude-devtools
Length of output: 99
🏁 Script executed:
# Get the full context of the function and surrounding code
cat -n src/main/utils/pathDecoder.ts | sed -n '95,115p'Repository: matt1398/claude-devtools
Length of output: 796
🏁 Script executed:
# Search for usage of translateWslMountPath in the codebase
rg "translateWslMountPath" -n -A 3 -B 1Repository: matt1398/claude-devtools
Length of output: 1353
🏁 Script executed:
# Look for tests related to this function
find . -name "*.test.ts" -o -name "*.spec.ts" | xargs grep -l "translateWslMountPath" 2>/dev/nullRepository: matt1398/claude-devtools
Length of output: 52
🏁 Script executed:
# Check path.isAbsolute usage in the codebase to understand downstream expectations
rg "isAbsolute|path\..*Absolute" --type ts --type tsx -n | grep -E "(src/main|src/renderer)" | head -20Repository: matt1398/claude-devtools
Length of output: 95
🏁 Script executed:
# Search for normalizeDriveLetter function definition
rg "normalizeDriveLetter" -n -B 2 -A 5 --type tsRepository: matt1398/claude-devtools
Length of output: 1182
🏁 Script executed:
# Search for tests more carefully with proper syntax
fd "\.(test|spec)\.ts$" -x grep -l "translateWslMountPath\|pathDecoder"Repository: matt1398/claude-devtools
Length of output: 146
🏁 Script executed:
# Look at the full context in metadataExtraction.ts to understand how the result is used
cat -n src/main/utils/metadataExtraction.ts | sed -n '60,70p'Repository: matt1398/claude-devtools
Length of output: 483
🏁 Script executed:
# Check if pathDecoder has any imports or exports related to normalization
cat -n src/main/utils/pathDecoder.ts | head -50Repository: matt1398/claude-devtools
Length of output: 2112
🏁 Script executed:
# Examine the pathDecoder test file to see existing test coverage
cat -n test/main/utils/pathDecoder.test.tsRepository: matt1398/claude-devtools
Length of output: 9427
🏁 Script executed:
# Check if normalizeDriveLetter handles the slash issue
rg "normalizeDriveLetter" -A 10 -B 5 src/main/utils/metadataExtraction.ts | head -30Repository: matt1398/claude-devtools
Length of output: 913
Normalize mount-root paths to X:/ format.
For input like /mnt/c, this currently returns C:, which is not an absolute path on Windows (path.win32.isAbsolute('C:') returns false). The function's contract explicitly documents the output format as X:/..., and downstream consumers assume absolute paths. Change line 108 from const rest = match[2] ?? ''; to const rest = match[2] ?? '/'; to produce C:/ instead.
Proposed fix
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] ?? '';
+ const rest = match[2] ?? '/';
return `${drive}:${rest}`;
}
return posixPath;
}Also add test coverage for the /mnt/c case to prevent regression.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| 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}`; | |
| } | |
| 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; | |
| } |
🧰 Tools
🪛 GitHub Check: validate
[warning] 105-105:
Unsafe Regular Expression
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/main/utils/pathDecoder.ts` around lines 101 - 110, The
translateWslMountPath function returns "C:" for input "/mnt/c", which is not an
absolute Windows path; update the logic in translateWslMountPath to default the
captured tail to '/' instead of '' (change the rest assignment from match[2] ??
'' to match[2] ?? '/') so the function returns "C:/" for mount-root inputs, and
add a unit test for the "/mnt/c" case to assert the output is "C:/" (or
otherwise absolute per path.win32.isAbsolute) to prevent regression.
The default 5s timeout is too tight for Windows CI runners where module collection alone can take 20s+. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sessions started from WSL encode POSIX paths (/mnt/d/...) in cwd, which aren't recognized as Windows paths (D:/...) by the app. Add translateWslMountPath() to convert /mnt/X/... → X:/... on Windows, applied in both decodePath() and extractCwd().
Fixes #118
Summary by CodeRabbit