Agent Notifications
A Claude Code plugin that sends desktop notifications when the AI agent needs your attention or completes tasks.
Features
- Native terminal support: Uses OSC sequences for Ghostty, WezTerm, iTerm2, and Kitty
- Smart fallback: Automatically uses terminal-notifier for other terminals
- Branch-aware: Shows your current git branch and project name
- Context-rich: Displays question text, permission requests, and task completion previews
- Notification suppression: Prevents duplicate notifications when multiple hooks fire together
- Configurable: Customize sounds, notification types, message detail level, and behavior
Hook Events
| Hook | Matcher | Notification | When it fires |
|---|
PreToolUse | AskUserQuestion | Question | Claude asks you a question |
PreToolUse | ExitPlanMode | Plan Ready | Claude finishes a plan for your review |
Notification | permission_prompt | Permission Needed | Claude needs permission to use a tool |
Stop | — | Task Completed | Claude finishes responding |
Installation
Option A: Plugin Installation (Recommended)
claude --plugin-dir /path/to/agent-notifications
The plugin includes hook configuration automatically — no manual settings.json editing needed.
Option B: Manual Hook Configuration
If you prefer not to use the plugin system, add these hooks to ~/.claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "AskUserQuestion",
"hooks": [{ "type": "command", "command": "node /path/to/agent-notifications/scripts/notify.js question" }]
},
{
"matcher": "ExitPlanMode",
"hooks": [{ "type": "command", "command": "node /path/to/agent-notifications/scripts/notify.js planReady" }]
}
],
"Notification": [
{
"matcher": "permission_prompt",
"hooks": [{ "type": "command", "command": "node /path/to/agent-notifications/scripts/notify.js permission" }]
}
],
"Stop": [
{
"hooks": [{ "type": "command", "command": "node /path/to/agent-notifications/scripts/notify.js stop" }]
}
]
}
}
Install terminal-notifier (optional)
Only needed if your terminal doesn't support OSC notifications natively (see terminal support table below):
brew install terminal-notifier
Configuration
On first notification, the plugin auto-creates a config file at ~/.claude/agent-notifications/config.json with sensible defaults. Edit it to customize behavior.
Or use the /agent-notifications:setup skill to have Claude walk you through configuration interactively.
Config Format
{
"sounds": {
"question": "Blow",
"planReady": "Blow",
"permission": "Blow",
"taskCompleted": "Glass"
},
"notifications": {
"question": true,
"planReady": true,
"permission": true,
"taskCompleted": true
},
"terminal": {
"skipFrontmostDetection": false,
"bundleId": "com.mitchellh.ghostty"
},
"messageDetail": "full"
}
Options
| Option | Description |
|---|
sounds.* | macOS system sound for each event (used with terminal-notifier fallback). List available sounds: ls /System/Library/Sounds/ |
notifications.* | Enable/disable specific notification types |
terminal.skipFrontmostDetection | If true, always send notifications even when your terminal is focused |
terminal.bundleId | App to activate when clicking a notification (terminal-notifier fallback only) |
messageDetail | "minimal" (event + project) or "full" (event + context + branch + project) |
Common Bundle IDs
Only needed if you use terminal-notifier fallback. Find yours with: osascript -e 'id of app "YourTerminal"'
| Terminal | Bundle ID |
|---|
| Ghostty | com.mitchellh.ghostty |
| iTerm2 | com.googlecode.iterm2 |
| Terminal.app | com.apple.Terminal |
| VS Code | com.microsoft.VSCode |
| Cursor | com.todesktop.230313mzl4w4u92 |
| Warp | dev.warp.Warp-Stable |
| Hyper | co.zeit.hyper |
| Alacritty | org.alacritty |
Available Sounds
List macOS system sounds:
ls /System/Library/Sounds/ | sed 's/.aiff//'
Preview a sound:
afplay /System/Library/Sounds/Glass.aiff
Terminal Support
| Terminal | Method | Notes |
|---|
| Ghostty | OSC 777 | Native, works across tabs/windows |
| WezTerm | OSC 777 | Native, works across tabs/windows |
| iTerm2 | OSC 9 | Native, works across tabs/windows |
| Kitty | OSC 99 | Native, works across tabs/windows |
| VS Code, Terminal.app, Warp, Hyper | terminal-notifier | Requires brew install terminal-notifier |
Debugging
Add --log to any hook command in hooks/hooks.json to log payloads:
"command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/notify.js\" stop --log"
Logs are written to notify.log in the plugin root.
Troubleshooting