Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ This repo is a collection of documentation files and scripts that fix Claude Cod
|------|-------------------|
| `image-paste.md` | `~/.local/bin/clip2png` (BMP→PNG clipboard poller) + `~/.claude/keybindings.json` (Alt+V) + `SessionStart` hook only (no SessionEnd) |
| `shift-enter.md` | VSCode `/terminal-setup` + Windows Terminal `settings.json` action (`\u001b\r`) |
| `claude-notify.md` | `~/bin/claude-notify` (bash → PowerShell balloon tip) + `Notification`/`PermissionRequest` hooks — **WSL2 only** |
| `claude-notify-powershell.md` | `%USERPROFILE%\.claude\claude-hook-toast.ps1` + `Stop`/`Notification`/`PermissionRequest` hooks — **native Windows PowerShell only** |
| `claude-notify.md` | `~/bin/claude-notify` (bash → PowerShell balloon tip) + `PermissionRequest` hook only — **WSL2 only** |
| `claude-notify-powershell.md` | `%USERPROFILE%\.claude\claude-hook-toast.ps1` + `PermissionRequest` hook only — **native Windows PowerShell only** |
| `settings.md` | `~/.claude/settings.json` `attribution` field + `~/.claude.json` `hasTrustDialogAccepted` |
| `browser.md` | `BROWSER` env var in `~/.zshrc` pointing to Windows `.exe` |

Expand All @@ -29,9 +29,9 @@ This repo is a collection of documentation files and scripts that fix Claude Cod

**clip2png SessionEnd pitfall**: Do not add a `SessionEnd` hook to stop the poller. Claude Code fires `SessionStart`/`SessionEnd` for every subagent spawned by the Task tool. The subagent's `SessionEnd` would kill the poller mid-session for the main session.

**claude-notify async (WSL2)**: The `Notification` hook command must be wrapped as `bash -c '... &'` because the PowerShell script sleeps 6 s. Running it synchronously blocks Claude Code's UI for that duration.
**claude-notify async (WSL2)**: The `PermissionRequest` hook command must be wrapped as `bash -c '... &'` because the PowerShell script sleeps 6 s. Running it synchronously blocks Claude Code's UI for that duration.

**claude-notify async (Windows PowerShell)**: Uses the Windows Toast API (`Windows.UI.Notifications`) via [soulee-dev/claude-code-notify-powershell](https://github.com/soulee-dev/claude-code-notify-powershell). The script reads hook event JSON from stdin. No async wrapper needed — toast fires and exits immediately. The key hook is `Stop` (fires when Claude finishes a response), not just `Notification`. Script lives at `%USERPROFILE%\.claude\claude-hook-toast.ps1`; hook configured in `C:\Users\cong\.claude\settings.json`. Both variants skip the notification when Windows Terminal is the foreground window.
**claude-notify async (Windows PowerShell)**: Uses the Windows Toast API (`Windows.UI.Notifications`) via [soulee-dev/claude-code-notify-powershell](https://github.com/soulee-dev/claude-code-notify-powershell). The script reads hook event JSON from stdin. No async wrapper needed — toast fires and exits immediately. Only the `PermissionRequest` hook is used — notifications fire only when Claude needs you to approve a tool. Script lives at `%USERPROFILE%\.claude\claude-hook-toast.ps1`; hook configured in `C:\Users\cong\.claude\settings.json`. Both variants skip the notification when Windows Terminal is the foreground window.

**clip2png re-serve logic**: When `image/png` disappears from the clipboard (WSLg clipboard sync can take back ownership) and no new content was copied, the script re-serves `/tmp/clip2png-last.png`. The detection condition is: no `image/png` AND no `text/` type AND the last PNG file exists.

Expand All @@ -44,7 +44,7 @@ This repo is a collection of documentation files and scripts that fix Claude Cod
Read all five `*.md` files, then:
1. Install `wl-clipboard` and `imagemagick` if not present.
2. Create `~/.local/bin/clip2png` and `~/bin/claude-notify` with the exact script contents from the docs, then `chmod +x` both.
3. Merge the hooks (`SessionStart`, `Notification`, `PermissionRequest`) into `~/.claude/settings.json`. Do NOT add a `SessionEnd` hook for clip2png — subagents fire `SessionEnd` too, which would kill the poller mid-session.
3. Merge the hooks (`SessionStart`, `PermissionRequest`) into `~/.claude/settings.json`. Do NOT add a `SessionEnd` hook for clip2png — subagents fire `SessionEnd` too, which would kill the poller mid-session.
4. Create/update `~/.claude/keybindings.json` with the Alt+V binding.
5. Set `attribution` in `~/.claude/settings.json`.
6. Copy `agents/*.md` → `~/.claude/agents/` and `skills/*/SKILL.md` → `~/.claude/skills/<name>/SKILL.md`.
Expand Down
32 changes: 6 additions & 26 deletions claude-notify-powershell.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ Credit: [soulee-dev/claude-code-notify-powershell](https://github.com/soulee-dev

## How It Works

1. Claude Code fires the `Stop` hook when it finishes responding and waits for input,
and the `Notification` hook for explicit notifications.
2. Both hooks run `claude-hook-toast.ps1` via `cmd /c chcp 65001 && powershell ...`.
1. Claude Code fires the `PermissionRequest` hook when it is blocked on a tool-use
approval prompt (e.g. "Do you want to proceed?").
2. The hook runs `claude-hook-toast.ps1` via `cmd /c chcp 65001 && powershell ...`.
The `chcp 65001` sets UTF-8 code page so message text renders correctly.
3. Claude Code pipes a JSON payload into the script's stdin containing `hook_event_name`
and `message`.
Expand All @@ -26,8 +26,8 @@ Credit: [soulee-dev/claude-code-notify-powershell](https://github.com/soulee-dev
5. Otherwise it uses the Windows Toast Notification API (`Windows.UI.Notifications`)
to show a modern toast — no sleep needed, no background process required.

The key hook is **`Stop`** (fires when Claude finishes a response), not just
`Notification` (fires for explicit notification messages).
The key hook is **`PermissionRequest`** — it fires only when Claude is blocked on a
permission prompt, not on every completed response.

---

Expand All @@ -52,26 +52,6 @@ and a foreground window check skips the toast if Windows Terminal is already act
```json
{
"hooks": {
"Notification": [
{
"hooks": [
{
"type": "command",
"command": "cmd /c chcp 65001 >nul && powershell -ExecutionPolicy Bypass -File %USERPROFILE%\\.claude\\claude-hook-toast.ps1"
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "cmd /c chcp 65001 >nul && powershell -ExecutionPolicy Bypass -File %USERPROFILE%\\.claude\\claude-hook-toast.ps1"
}
]
}
],
"PermissionRequest": [
{
"hooks": [
Expand Down Expand Up @@ -112,7 +92,7 @@ echo '{"hook_event_name":"Stop","message":""}' | powershell -ExecutionPolicy Byp
| Script type | bash wrapper | native `.ps1` |
| Notification type | `NotifyIcon` balloon tip | Windows Toast API |
| Async mechanism | `bash -c '... &'` | not needed — toast fires and exits |
| Key hook | `Notification` | `Stop` + `Notification` |
| Key hook | `PermissionRequest` | `PermissionRequest` |
| Script location | `~/bin/claude-notify` | `%USERPROFILE%\.claude\claude-hook-toast.ps1` |
| Settings file | `~/.claude/settings.json` | `C:\Users\cong\.claude\settings.json` |

Expand Down
29 changes: 10 additions & 19 deletions claude-notify.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@
When Claude Code finishes a long task on WSL2, the terminal gives no visual signal that
it is waiting. You only notice if you switch back to the terminal yourself.

The `Notification` hook lets Claude Code fire a Windows balloon tip (system tray popup)
so you get an OS-level alert even when the terminal is in the background.
The `PermissionRequest` hook lets Claude Code fire a Windows balloon tip (system tray popup)
when it needs you to approve or deny a tool use — so you get an OS-level alert even when
the terminal is in the background.

---

## How It Works

1. Claude Code fires the `Notification` hook whenever it needs the user's attention.
1. Claude Code fires the `PermissionRequest` hook whenever it is blocked on a tool-use
approval prompt (e.g. "Do you want to proceed?").
2. The hook runs `~/bin/claude-notify`, a bash script that calls Windows PowerShell
directly from WSL via `/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe`.
3. PowerShell creates a `NotifyIcon` (system tray icon) and shows a balloon tip for 5 s.
Expand Down Expand Up @@ -75,17 +77,6 @@ chmod +x ~/bin/claude-notify
In `~/.claude/settings.json`, add inside the `"hooks"` object:

```json
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "bash -c '~/bin/claude-notify \"Claude Code\" \"Needs your input!\" &'"
}
]
}
],
"PermissionRequest": [
{
"matcher": "",
Expand All @@ -99,9 +90,8 @@ In `~/.claude/settings.json`, add inside the `"hooks"` object:
]
```

Both hooks use the same message — `Notification` fires when Claude needs attention,
`PermissionRequest` fires when Claude is waiting for you to approve a tool use (e.g.
creating a file or running a command).
`PermissionRequest` fires when Claude is waiting for you to approve or deny a tool use
(e.g. "Do you want to proceed? Yes / No").

> **Why `bash -c '... &'` and not just the command directly?**
>
Expand All @@ -117,8 +107,9 @@ Restart Claude Code for the hook to take effect.

## Result

When Claude Code finishes a task and is waiting, a Windows balloon tip appears in the
system tray with the title **Claude Code** and the message **Needs your input!**
When Claude Code hits a permission prompt and is waiting for your approval, a Windows
balloon tip appears in the system tray with the title **Claude Code** and the message
**Needs your input!**

---

Expand Down