From 3d641c2b60e9ae4c62c4ac7634e48685d4a568f6 Mon Sep 17 00:00:00 2001 From: congmnguyen Date: Wed, 25 Feb 2026 13:54:32 +0700 Subject: [PATCH] Narrow notifications to PermissionRequest only Remove Notification (and Stop) hooks from both claude-notify variants so balloon tips / toasts fire only when Claude is blocked on a permission prompt ("Do you want to proceed?"), not on every completed response. --- CLAUDE.md | 10 +++++----- claude-notify-powershell.md | 32 ++++++-------------------------- claude-notify.md | 29 ++++++++++------------------- 3 files changed, 21 insertions(+), 50 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 1a83bfc..5c9b0d3 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -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` | @@ -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. @@ -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//SKILL.md`. diff --git a/claude-notify-powershell.md b/claude-notify-powershell.md index c73cf27..b29f396 100644 --- a/claude-notify-powershell.md +++ b/claude-notify-powershell.md @@ -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`. @@ -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. --- @@ -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": [ @@ -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` | diff --git a/claude-notify.md b/claude-notify.md index 150429c..d86b517 100644 --- a/claude-notify.md +++ b/claude-notify.md @@ -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. @@ -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": "", @@ -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?** > @@ -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!** ---