A WSL path resolves before anything asks whether it exists
Explore this workspace.
Technical background
The \\wsl.localhost translation was correct and never ran: existence was checked on the path as written, so /home/you/notes.md was asked about as C:\home\you\notes.md, came back false, and the click did nothing. Existence is now asked once, of the path that would actually be opened — and a #L6-L7 fragment is stripped as a fragment rather than carried into the filename.
The problem
A path printed inside WSL means nothing to Windows, and the \\wsl.localhost\<distro>\… translation that fixes that was correct in isolation and never ran. So a path printed by anything inside WSL had no Copy path, no Show in folder, and a click that did nothing at all.
How it works
The order was backwards: the whole thing was gated on the linkifier's verify(), which is fs.access on the string as written — for /home/you/notes.md that asks Windows about C:\home\you\notes.md, which is false, so translation bailed before it could happen. Existence is now asked once, of the path that would actually be opened. What replaces verify as the "is this a path" test is rootedness, not existence.
Try it
- In a WSL tab, print an absolute path:
ls -d ~/Documents. - Hover it. The card shows the
\\wsl.localhost\…path it will really open. - Click it, or use Show in folder. Explorer opens the real file inside the distro.
Details
- Rootedness, not existence, is the right test. A text rule matches things like an issue key, and
fs.access('CAB-8209')is answered against the app's own working directory, where it could plausibly exist. It also drops thefs.accessthat every hoveredhttpURL used to cost. #L6-L7is a fragment, not part of the name (RFC 3986 §3.5), and it was being carried into both the existence check and the shared path. It is stripped before percent-decoding, so a#genuinely in a filename — which has to arrive as%23— survives. Upstream has been asked for this since 2022 (GH#14116).- An OSC 8
file://link arrives with no handler, so thefile://branch of the resolver was dead code. That is the form Claude Code emits, and the one that carries a fragment. file://<authority>/…is a UNC path, which is how an editor writes a WSL link that already names its own distro./mnt/<letter>/becomes the drive, since the share would answer for a file sitting on the local disk.- Clicking takes the new route only when translation changed the path. A Windows path and an
httplink still go through the handler exactly as they did; asserted both ways.
What this does not claim
- Still wrong, and left alone:
~/notesin a WSL tab is untildified to the Windows home by the upstream handler, so it resolves to the wrong file if that path happens to exist. Fixing it needs the distro's home, which costs awsl.exespawn on every hover. verify()is not consulted at all any more rather than being fixed. It is upstream code and every line changed there is rebase surface — and nothing is lost, since it is the existence check and it was being run on the wrong string.- The reference fork's UTF-8 escape handling has no analogue here: its Windows API unescapes
%XXa byte at a time, socaf%C3%A9.mdarrives mojibaked, whiledecodeURIComponentis already correct.