My active Claude Code setup for WSL2 + Windows Terminal.
The repo only tracks the pieces I actually use: LSP navigation, screenshot paste, Windows
notifications, statusline, and token/context hygiene hooks. Anything optional is marked as
such — my own Claude Code config is deliberately minimal beyond the above: no custom
skills, no MCP servers, no global CLAUDE.md.
Use this if you run Claude Code from WSL2 and want the Windows side to stop feeling bolted on: screenshots paste as WSL paths, notifications land in Windows, browser links open in your normal browser, and long implementation loops can move to Codex without filling Claude's main conversation.
Where to start, depending on what hurts most:
- Context burn →
lsp-setup. - Windows/WSL friction →
image-pasteandclaude-notify. - No visibility into what Claude did →
statusline, plus optionallangsmith-tracingwhen you want full turn-level traces.

claude-code-wsl2-setup | main | [░░░░░░░░░░] 6% | 5h:10% | W:95%

Balloon tip fires on Claude Code Notification events, skipped when Windows Terminal is focused

Codex's top-level notify command shows the completed turn's last reply

Shell-managed titles keep Claude Code and Codex tabs distinguishable.
git clone https://github.com/congmnguyen/claude-code-wsl2-setup.git
cd claude-code-wsl2-setup
claudeThen prompt:
Set this up
Claude will read the docs and configure everything.
For a manual install, copy the relevant files from agents/ and skills/
into the matching ~/.claude/ directories, then read the linked setup page for the feature
you want.
| File | Fix |
|---|---|
lsp-setup.md |
Official LSP plugins + language servers for TypeScript, Python, Go, and Rust, so Claude uses real Go-to-Definition / find-references instead of burning tokens on broad file search |
statusline.md |
Project dir, git branch, context-window fill bar, and 5-hour / 7-day usage, color-coded by severity |
langsmith-tracing.md |
Optional. Project-level LangSmith traces for turns, tool calls, subagent runs, and compaction events — without enabling telemetry for every local session |
settings.md |
Disabling the Co-authored-by: Claude git attribution and session links, and pre-accepting the project trust dialog |
| File | Fix |
|---|---|
mcp-setup.md |
Optional project-specific Figma Desktop MCP |
| File | Fix |
|---|---|
image-paste.md |
Copy a screenshot on Windows, paste the file path straight into Claude Code or Codex. A systemd user service keeps wsl-screenshot-cli running, saves shots under /tmp/.wsl-screenshot-cli/, and restarts the monitor if it exits. Optional Alt+V keybinding |
terminal-title.md |
Distinct zsh tab titles for the current project and active agent, such as text2sql-agent · ✳ Claude or text2sql-agent · >_ Codex |
claude-notify.md |
Windows balloon tip on Claude Code Notification events — Claude finished, needs permission, or a background agent completed — suppressed when Windows Terminal is already focused |
codex-notify.md |
Reuse the same balloon script through Codex's top-level notify command |
bin/tmux-notify-run |
Detached tmux jobs with logs, exit status, and Windows completion notification |
shift-enter.md |
Shift+Enter inserts a newline instead of submitting, in both the VSCode integrated terminal and Windows Terminal |
browser.md |
Open links and OAuth flows in your Windows browser via BROWSER, plus an XDG fallback for OAuth CLIs |
capslock-esc.md |
CapsLock → Escape via a SharpKeys registry remap — works in WSL2, Vim, games, and elevated processes |
| Path | Contents |
|---|---|
agents/ |
code-architect |
skills/ |
Skills to copy in as needed: commit-push-pr, deep-teach, pytorch-training. My own ~/.claude/skills/ stays empty — I install per project instead of globally, so nothing competes for context on unrelated work |
Copy the matching files to ~/.claude/agents/ and ~/.claude/skills/.
After adding or updating a skill, run /reload-skills to make it available without
restarting the session. Custom agents still require a restart.
Dropped pieces (Codex delegation and its companion repo) live in archive/.
If a hook, plugin, or other customization breaks Claude Code, start a clean diagnostic
session with claude --safe-mode. Use /doctor, /hooks, and /mcp to inspect the
installation and loaded integrations.
Native Windows PowerShell notifications, WSLg voice-mode audio, Playwright browser automation, and uninstalled Claude skills were removed from the main repo because they are not part of the active local setup. Git history keeps them if you want the old versions.
The three PreToolUse / PostToolUse hooks were removed for a different reason: each one
judged tool input by pattern, and each was measurably wrong in both directions.
truncate-bash-outputrewrote.stdoutto head + tail. Claude Code already saves oversized output to a file and shows a preview, losing nothing; truncating below that threshold suppressed the built-in behaviour and destroyed the middle permanently — where test failures and stack traces live. It also cost more context than the preview it replaced, and died on long lines (jq: Argument list too long), passing the full untruncated output through.block-secret-readsblocked reads of credential files by regex. Probed with synthetic payloads it caught 1 of 11 trivial rephrasings (dd,od,nl,tac,rev,perl,tee, awhile readloop,tar | base64,python3 -c) while rejecting all 5 ordinary source files named liketoken_manager.pyorcredentials_service.py. Exact-matchpermissions.denyrules do the same job without guessing.format-python-with-ruffranruff check --fixafter every Python edit, which deleted animportout of a file the moment it was written — leaving what is on disk different from what the agent believes it wrote. It could also spin forever on a relative path, sincedirname .never reaches/.
Notification hooks stayed. They react to events rather than judging tool input, so there
is no pattern to get wrong.
Skills not authored here but worth installing alongside the setup:
-
liteparse (LlamaIndex, MIT) — parse PDF, DOCX, PPTX, XLSX, and images locally with no cloud calls. Useful for feeding unstructured documents into Claude or Codex without uploading them. Try it in the browser first: simonw.github.io/liteparse. Then install the npm package globally and copy the upstream
SKILL.mdinto~/.claude/skills/liteparse/:npm i -g @llamaindex/liteparse sudo apt-get install -y libreoffice # required for DOCX/PPTX/XLSX
MIT — feel free to copy, fork, or adapt for your own setup.