Skip to content

Repository files navigation

wsl-tmux-notifier

Windows toast notifications for Claude Code and Codex CLI in WSL2 — with tmux session awareness and one-click window jump.

中文说明

Toast notification example

Why?

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

Tested Environment

  • Windows 11 + Windows Terminal
  • WSL2 (Ubuntu)
  • tmux

Quick Install

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.sh

What each installer does

Shared steps (both installers handle these, skipping if already done):

  1. Install BurntToast PowerShell module
  2. Deploy notification + jump scripts to ~/.local/bin/
  3. Deploy protocol handler + icons to C:\Users\<YOU>\.wsl-tmux-notifier\
  4. 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

Prerequisites

  • WSL2 with jq installed (sudo apt install jq)
  • Claude Code CLI and/or Codex CLI
  • tmux (recommended, works without it but no Jump button)
  • Windows Terminal

Manual Install

Step 1: Install BurntToast

powershell.exe -NoProfile -Command "Install-Module -Name BurntToast -Force -Scope CurrentUser"

Step 2: Deploy scripts

# 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.sh

Step 3: Deploy Windows-side files

WIN_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/"

Step 4: Register protocol handler

# 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
'@

Step 5a: Configure Claude Code hooks

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" }]
      }
    ]
  }
}

Step 5b: Configure Codex CLI notify

Add to ~/.codex/config.toml:

# Keep this at top level (before any [section] table).
notify = ["~/.local/bin/wsl-codex-notify.sh"]

How It Works

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

Uninstall

# Remove Claude Code components
bash uninstall-claude.sh

# Remove Codex CLI components
bash uninstall-codex.sh

Removes deployed files, registry entries, and tool-specific config.

Troubleshooting

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 notify is 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 a config.toml type 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 jq is 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 $TMUX should have output)

License

MIT

Icon from lobe-icons (MIT License).

About

Windows toast notifications for Claude Code and Codex running in WSL2 + tmux. One-click jump to the right tmux window.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages