Tab title indicators and desktop notifications for Claude Code on macOS + iTerm2.
Works out of the box on macOS — no additional installation required (osascript, python3 are pre-installed).
Optionally uses terminal-notifier for click-to-focus support.
- Tab title status — See Claude's state at a glance:
- ⚡ Processing
- ✅ Complete
- ❓ Waiting for permission
- Desktop notifications — Get notified when Claude finishes or needs input
- Click to focus tab — Clicking the notification switches to the exact iTerm2 tab (requires
terminal-notifier) - Event-specific sounds — Different sounds for completion, permission requests, etc.
sh -c "$(curl -fsSL https://raw.githubusercontent.com/hatayama/claude-code-notify/main/install.sh)"Manual installation (git clone)
git clone https://github.com/hatayama/claude-code-notify.git
cd claude-code-notify
python3 install.pyThe installer will:
- Copy hook scripts to
~/.claude/hooks/ - Configure hooks in
~/.claude/settings.json - Add
CLAUDE_TTYto your shell profile
Restart your terminal after installation.
Re-run the install command:
sh -c "$(curl -fsSL https://raw.githubusercontent.com/hatayama/claude-code-notify/main/install.sh)"uninstall_claude_code_notifyOverride prefixes via environment variables in your ~/.zshrc:
export CLAUDE_NOTIFY_PREFIX_ON="🔥" # Processing (default: ⚡)
export CLAUDE_NOTIFY_PREFIX_DONE="🎉" # Complete (default: ✅)
export CLAUDE_NOTIFY_PREFIX_ASK="🔔" # Permission (default: ❓)Override sounds via environment variables in your ~/.zshrc:
export CLAUDE_NOTIFY_SOUND_STOP="Funk" # When Claude stops (default: Funk)
export CLAUDE_NOTIFY_SOUND_PERMISSION="Hero" # Permission requests (default: Hero)
export CLAUDE_NOTIFY_SOUND_NOTIFICATION="Submarine" # Other notifications (default: Submarine)Available sounds: /System/Library/Sounds/
Use CLI options in ~/.claude/settings.json hooks:
"command": "~/.claude/hooks/notify.py --title 'Done!' --sound Glass"Options: --title, --message, --sound
Uses ANSI escape sequences (\033]0;...\007) to set the terminal tab title. The CLAUDE_TTY environment variable tells the script which terminal to update.
A marker file in /tmp/claude-iterm2-title-* stores the current state, which can be used by external scripts (e.g., iTerm2 AutoLaunch) to clear the prefix on tab focus.
On iTerm2, an AutoLaunch script automatically clears tab title prefixes when you switch to a tab:
- ⚡ (processing) — not cleared on focus (stays visible while Claude is working)
- ✅ (complete) / ❓ (permission) — cleared on focus
This requires iTerm2's Python API:
- iTerm2 > Settings > General > Magic > Enable Python API
- The installer copies the script to
~/Library/Application Support/iTerm2/Scripts/AutoLaunch/ - Restart iTerm2 (or reload scripts via Scripts menu)
If the AutoLaunch directory doesn't exist, the installer skips this step and prints setup instructions.
If terminal-notifier is installed (brew install terminal-notifier), notifications support click-to-focus: clicking a notification activates iTerm2 and switches to the exact tab that triggered it, using the session UUID from TERM_SESSION_ID.
Without terminal-notifier, falls back to osascript (display notification) for basic notifications.
The installer configures these Claude Code hooks:
| Hook | Action |
|---|---|
UserPromptSubmit |
Set tab title to ⚡ |
PreToolUse |
Keep tab title as ⚡ |
Notification (permission_prompt) |
Set tab title to ❓ + desktop notification |
Stop |
Set tab title to ✅ + desktop notification |
- macOS
- Claude Code CLI
- iTerm2 (recommended — required for focus clearing and click-to-focus notifications)
MIT