feat(wsl): open links in the Windows browser - #677
Merged
Conversation
A WSL distro has no graphical browser and no xdg-open, so anything that "opens a browser" — `gh auth login`, OAuth flows, `npm docs` — falls back to whatever terminal browser happens to be installed. Completing an OAuth flow in lynx is not a good time. Ship `~/.local/bin/wsl-browser`, which hands the URL to Windows via `powershell.exe Start-Process`, and export BROWSER at it under WSL. That fixes every such tool at once rather than configuring them one by one. Guarded on WSL_DISTRO_NAME and on powershell.exe being reachable, so it stays inert on native Linux/macOS and when WSL interop is disabled — matching the existing wsl-ssh guards. Two deliberate choices in the script: - It accepts only http(s) URLs or files that exist. Start-Process is Windows' general "run this" verb, not a browser: handed calc.exe or a path to an executable it would run it. Since $BROWSER is invoked by other programs, anything else is refused rather than quietly launched. - The URL is passed through WSLENV rather than interpolated into the PowerShell command string, so a URL containing quotes or semicolons is always data and never code. wslu's `wslview` would have been the obvious dependency, but it was archived upstream in 2025 (last release 4.1.3, April 2024) and is not packaged for Debian 13 — installing an unmaintained .deb outside apt is worse than shipping these few lines. Documented, with a note that wslview is a drop-in replacement if it ever returns. .editorconfig gains a rule for home/dot_local/bin/*: scripts there are extensionless by convention, so [*.sh] missed them and they would have been formatted at 2 spaces rather than 4 like every other shell script. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
DevSecNinja
force-pushed
the
feat/wsl-browser-integration
branch
from
August 7, 2026 11:57
65c53a5 to
f3b8740
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
A WSL distro has no graphical browser and no
xdg-open. Anything that "opens a browser" —gh auth login, OAuth flows,npm docs— looks forxdg-openor$BROWSER, and when neither points anywhere useful it falls back to whatever terminal browser happens to be installed. On this machine that waslynx, which is a miserable way to complete an OAuth flow.Fixing it per-tool (
gh config set browser …) treats the symptom. Setting$BROWSERfixes every tool at once.What
~/.local/bin/wsl-browser— hands the URL to Windows viapowershell.exe Start-Process, which opens it in the real default browser.$BROWSERexported fromconf.d/wsl-browser.fishandshell/functions/wsl-browser.sh, mirroring the existingwsl-sshpair so bash/zsh and fish stay in step.Guarded on
WSL_DISTRO_NAMEand onpowershell.exebeing reachable — same guards aswsl-ssh, so nothing leaks into a native Linux or macOS session, or when interop is disabled.Two deliberate choices in the script
http(s)URLs or files that exist.Start-Processis Windows' general "run this" verb, not a browser — handedcalc.exeor a path to an executable, it would run it. Since$BROWSERgets invoked by other programs with whatever string they happen to have, anything else is refused rather than quietly launched.WSLENV, not interpolated into the PowerShell command string, so a URL containing quotes or semicolons is always data and never code. (My first draft did interpolate;powershell.exe -Command '…' "$url"appends the argument to the command text, which is exactly the footgun you'd expect.)Why not wslu?
wsluprovideswslview, which does this job properly and would have been the obvious dependency — it's what I reached for first. Two problems:apt-cache policy wslu→ nothing; it's an Ubuntu-universe package, and this machine is Debian trixie with onlymain).Installing an unmaintained
.deboutsideaptis worse than shipping ~30 lines we control. Documented indocs/wsl.md, with a note thatwslviewis a drop-in replacement if it ever returns to the archives — pointBROWSERat it and delete the script..editorconfigAdds a rule for
home/dot_local/bin/*. Scripts there are extensionless by convention, so[*.sh]missed them and[*]would have formatted them at 2 spaces instead of the 4 every other shell script here uses.Verification
Applied on this machine and tested:
chezmoi apply→ exec bit fromexecutable_prefix-rwxr-xr-x✓BROWSER=/home/jean-paul/.local/bin/wsl-browser✓WSL_DISTRO_NAMEunset (both shells)BROWSERunset ✓wsl-browser calc.exe/javascript:alert(1)wsl-browser https://github.com/…shellcheck,shfmt,dprintandfish -nall clean.Note
chezmoi diffon my machine also wants to revert~/.config/git/config, removing thegh auth git-credentialhelper entries thatgh auth setup-gitwrote. That's pre-existing drift, unrelated to this PR — I applied only the three files here rather than a fullchezmoi apply. Worth deciding separately whether those entries should be managed.