Smart Notifications for Claude Code on Desktop and Mobile
Click notifications to instantly restore your exact Claude Code context across macOS Spacesβnot just the app, but your specific terminal/IDE window (and iTerm2 tab when available).
Also enables seamless π± mobile development via push notifications.
- π― Click-to-Focus - Restore exact window across Spaces, not just the app. With iTerm2, cc-notifier also restores the original tab/session within that window.
- π§ Intelligent Detection - π» Desktop: notifies when you switch windows | π Remote: notifies when idle
- β‘ Fast & Async - Runs in background, never blocks Claude Code
- π² Push Notifications - Desktop: optional idle alerts | Remote: primary notification method (Pushover)
- π± Mobile Handoff - (Optional) Desktopβphone workflow via Blink Shell
# Install dependencies
brew install --cask hammerspoon
brew install terminal-notifier
# Configure Hammerspoon (~/.hammerspoon/init.lua)
require("hs.ipc")
require("hs.window")
require("hs.window.filter")
require("hs.timer")
# Reload: hs -c "hs.timer.doAfter(0, hs.reload)"
# Install cc-notifier
git clone https://github.com/trentmcnitt/cc-notifier.git
cd cc-notifier
./install.shAdd hooks to ~/.claude/settings.json (see Configuration below).
Add to ~/.claude/settings.json:
{
"hooks": {
"SessionStart": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "$HOME/.cc-notifier/cc-notifier init"
}
]
}
],
"Stop": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "$HOME/.cc-notifier/cc-notifier notify"
}
]
}
],
"Notification": [
{
"matcher": "permission_prompt|elicitation_dialog",
"hooks": [
{
"type": "command",
"command": "$HOME/.cc-notifier/cc-notifier notify"
}
]
}
],
"SessionEnd": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "$HOME/.cc-notifier/cc-notifier cleanup"
}
]
}
]
},
// Optional: Push notifications (requires Pushover account)
"env": {
"PUSHOVER_API_TOKEN": "your_pushover_app_token",
"PUSHOVER_USER_KEY": "your_pushover_user_key"
}
}- Session Start β Captures your focused window ID
- Task Completion β Compares current window vs original window
- Smart Notification:
- πͺ Switched windows? β Local notification with click-to-focus
- ποΈ Switched iTerm2 tabs in same window? β Local notification with tab-aware click-to-focus
- π€ Idle at desk? β Optional push notification via Pushover
- Click Notification β Hammerspoon restores your exact window across Spaces; iTerm2 sessions also restore the original tab
- Auto-Detection β Detects SSH via
SSH_CONNECTIONenvironment variable - Session Start β Skips window tracking (uses placeholder)
- Task Completion β Checks TTY idle time (st_atime)
- Smart Notification:
- π€ User idle? β Push notification with resume URL
- β‘ User active? β No notification
- Tap Notification β Pushover opens β Tap URL β Blink Shell auto-resumes session
π§ Tested Stack: Tailscale + mosh + tmux + Blink Shell
Start coding on your desktop, continue seamlessly on your phone.
When Claude Code completes a task and you're away from your desk, you'll get a push notification. Tap it to instantly resume your exact conversation in Blink Shell.
- π» Start coding task on desktop
- πΆ Walk away from computer
- π² Push notification arrives on your phone
- π Tap notification β Pushover opens
- π Tap URL β Blink Shell opens
- β‘ Auto-resumes exact Claude Code session
π Complete Setup Guide: Mobile workflow documentation β
Add to ~/.claude/settings.json (extends the Configuration section above):
{
"env": {
"PUSHOVER_API_TOKEN": "your_token",
"PUSHOVER_USER_KEY": "your_key",
"CC_NOTIFIER_PUSH_URL": "blinkshell://run?key=YOUR_KEY&cmd=mosh mbp -- ~/bin/mosh-cc-resume.sh {session_id} {cwd}"
}
}Placeholders (auto-replaced at runtime):
{session_id}β Claude Code session ID{cwd}β Current working directory
Debug Mode:
Enable detailed logging for troubleshooting:
{
"hooks": {
"SessionStart": [{
"matcher": "*",
"hooks": [{
"type": "command",
"command": "$HOME/.cc-notifier/cc-notifier --debug init"
}]
}]
// Add --debug to all other hooks (notify, cleanup)
}
}Debug mode features:
- File logging with timestamps:
~/.cc-notifier/cc-notifier.log - Desktop: "[DEBUG]" prefix on notifications
- Remote: Precise timestamps on push notifications
- Logs: Hook events, window IDs, idle checks, notification sends
View logs:
tail -f ~/.cc-notifier/cc-notifier.log # Follow in real-time
cat ~/.cc-notifier/cc-notifier.log # View entire logDisable: Remove --debug flag from hook commands in settings.json
Wrong window focused:
- Window ID captured at session start
- Solution: Restart Claude Code or clear/resume session
- Prevention: Keep Claude focused when starting sessions
Mac sleep interrupts tasks:
sudo pmset -g # Check settings
sudo pmset -c sleep 0 # Disable while plugged in
caffeinate -i # Temporary preventionHammerspoon window discovery:
- Visit Spaces and click windows after Hammerspoon restart
- Auto-populates during normal use
Window focus issues:
- Try closing and re-opening the terminal/IDE window
- Apps can get into states where Hammerspoon can't focus them
Tmux "attached" does not mean "viewing": When Hammerspoon is unavailable (e.g., remote mode without window tracking), cc-notifier uses tmux session attachment status as a proxy for whether you're looking at Claude Code output. However, a tmux session being attached only means a terminal client is connectedβyou could be looking at a completely different tmux window or pane. This can lead to false notification suppression if you have complex multi-window tmux setups.
python3 -m venv .venv
source .venv/bin/activate
make install
pre-commit install
make check # format, lint, typecheck, testContributing: Fork, make check, test, PR.
Project structure:
~/.cc-notifier/ # Installation
βββ cc-notifier # Entry point
βββ cc_notifier.py # Implementation
mobile/ # Mobile workflow
βββ README.md
βββ mosh-cc-resume.sh
βββ tmux-idle-cleanup.sh
MIT

