Windows toast notifications for Claude Code and Codex CLI in WSL2 — with tmux session awareness and one-click window jump.
Claude Code and Codex CLI are terminal-based AI coding agents. But if you're running them inside WSL2, there's no built-in way to surface completion events as Windows notifications. You end up alt-tabbing back to check constantly.
It gets worse with tmux — multiple AI sessions across different windows, and no way to know which one needs attention, let alone jump to it.
This tool bridges that gap:
- Windows native toast — real Win11 toast notifications via BurntToast when your AI agent stops or needs input
- Multi-tool support — works with both Claude Code (hooks) and Codex CLI (notify)
- Tmux-aware — notification title shows
[session:window]so you instantly know which session finished - One-click jump — click "Jump" on the toast to activate Windows Terminal and switch directly to the right tmux window (pane-level jump is WIP)
- Tool icons — Claude and Codex notifications support separate icons for clear visual identification
- Zero config — one script installs everything: PowerShell module, shell scripts, custom protocol handler, tool-specific config
- Windows 11 + Windows Terminal
- WSL2 (Ubuntu)
- tmux
Install for the tools you use — run one or both:
git clone <repo-url>
cd wsl-tmux-notifier
# For Claude Code users
bash install-claude.sh
# For Codex CLI users
bash install-codex.shShared steps (both installers handle these, skipping if already done):
- Install BurntToast PowerShell module
- Deploy notification + jump scripts to
~/.local/bin/ - Deploy protocol handler + icons to
C:\Users\<YOU>\.wsl-tmux-notifier\ - Register
tmux-jump://custom protocol
Upgrade note: older versions used .wsl-claude-notifier; after reinstalling, you can remove that legacy folder.
Claude Code (step 5): Add hooks to ~/.claude/settings.json
Codex CLI (step 5): Add notify to ~/.codex/config.toml
- WSL2 with
jqinstalled (sudo apt install jq) - Claude Code CLI and/or Codex CLI
- tmux (recommended, works without it but no Jump button)
- Windows Terminal
powershell.exe -NoProfile -Command "Install-Module -Name BurntToast -Force -Scope CurrentUser"# For Claude Code
cp scripts/wsl-tmux-notify.sh ~/.local/bin/
chmod +x ~/.local/bin/wsl-tmux-notify.sh
# For Codex CLI
cp scripts/wsl-codex-notify.sh ~/.local/bin/
chmod +x ~/.local/bin/wsl-codex-notify.sh
# Jump helper (shared)
cp scripts/tmux-jump.sh ~/.local/bin/
chmod +x ~/.local/bin/tmux-jump.shWIN_USER=$(cmd.exe /C "echo %USERNAME%" 2>/dev/null | tr -d '\r')
mkdir -p "/mnt/c/Users/${WIN_USER}/.wsl-tmux-notifier"
cp windows/tmux-jump.ps1 assets/icon.png "/mnt/c/Users/${WIN_USER}/.wsl-tmux-notifier/"
cp assets/codex-icon.png "/mnt/c/Users/${WIN_USER}/.wsl-tmux-notifier/"# Replace <USER> with your Windows username
powershell.exe -NoProfile -Command @'
$proto = "tmux-jump"
$handler = 'powershell.exe -NoProfile -ExecutionPolicy Bypass -File "C:\Users\<USER>\.wsl-tmux-notifier\tmux-jump.ps1" "%1"'
New-Item -Path "HKCU:\Software\Classes\$proto" -Force | Out-Null
Set-ItemProperty -Path "HKCU:\Software\Classes\$proto" -Name "(Default)" -Value "URL:tmux-jump Protocol"
New-ItemProperty -Path "HKCU:\Software\Classes\$proto" -Name "URL Protocol" -Value "" -Force | Out-Null
New-Item -Path "HKCU:\Software\Classes\$proto\shell\open\command" -Force | Out-Null
Set-ItemProperty -Path "HKCU:\Software\Classes\$proto\shell\open\command" -Name "(Default)" -Value $handler
'@Add to ~/.claude/settings.json:
{
"hooks": {
"Stop": [
{
"matcher": "",
"hooks": [{ "type": "command", "command": "~/.local/bin/wsl-tmux-notify.sh" }]
}
],
"Notification": [
{
"matcher": "",
"hooks": [{ "type": "command", "command": "~/.local/bin/wsl-tmux-notify.sh" }]
}
]
}
}Add to ~/.codex/config.toml:
# Keep this at top level (before any [section] table).
notify = ["~/.local/bin/wsl-codex-notify.sh"]Claude Code hook event (Stop / Notification)
│ stdin: JSON with event type, message, cwd
▼
wsl-tmux-notify.sh ──────────────────────────────┐
│
Codex CLI notify (agent-turn-complete) ├──► BurntToast toast notification
│ last argv: JSON with type, last-assistant-message │ │
▼ │ Click "Jump"
wsl-codex-notify.sh ─────────────────────────────-┘ │
├─ Reads tmux session:window.pane ▼
├─ Builds BurntToast command + Jump button tmux-jump:// protocol
└─ PowerShell -EncodedCommand (UTF-16LE) │
▼
tmux-jump.ps1
├─ SetForegroundWindow() → activate Windows Terminal
└─ wsl.exe tmux-jump.sh → switch tmux window
# Remove Claude Code components
bash uninstall-claude.sh
# Remove Codex CLI components
bash uninstall-codex.shRemoves deployed files, registry entries, and tool-specific config.
No toast appears?
- Test Claude Code notification:
echo '{"hook_event_name":"Stop","cwd":"/tmp","last_assistant_message":"Test message"}' | ~/.local/bin/wsl-tmux-notify.sh
- Test Codex CLI notification:
~/.local/bin/wsl-codex-notify.sh '{"type":"agent-turn-complete","cwd":"/tmp","last-assistant-message":"Test message"}'
- Ensure
notifyis top-level in~/.codex/config.toml(before any[section]table):notify = ["~/.local/bin/wsl-codex-notify.sh"]
- Validate Codex config parse:
codex --version(should not print aconfig.tomltype error) - Verify BurntToast:
powershell.exe -NoProfile -Command "Import-Module BurntToast; New-BurntToastNotification -Text 'Test'" - Check Codex icon file:
ls /mnt/c/Users/*/.wsl-tmux-notifier/codex-icon.png - Check Windows notification settings (Settings > System > Notifications)
- Ensure
jqis installed:which jq
Jump button doesn't switch window?
- Check current tmux target:
tmux display-message -p '#{session_name}:#{window_index}.#{pane_index}' - Test jump directly:
bash ~/.local/bin/tmux-jump.sh <session>:<window>.<pane> - Test protocol handler:
powershell.exe -Command "Start-Process 'tmux-jump://<session>:<window>.<pane>'" - Check handler exists:
ls /mnt/c/Users/*/.wsl-tmux-notifier/tmux-jump.ps1 - Check protocol log:
cat /mnt/c/Users/*/.wsl-tmux-notifier/tmux-jump.log
No Jump button on toast?
- Jump button only appears when running inside tmux (
echo $TMUXshould have output)
Icon from lobe-icons (MIT License).
