Enhanced Claude Code notification hooks with adorable cat sounds and better styling for macOS.
- π± Adorable cat meow for all notifications
- π¨ Enhanced styling with emojis and better formatting
- π§ Intelligent categorization of notifications (success, error, warning, etc.)
- π Special stop notifications with the same adorable cat meow
- π macOS optimized using native notification system
- π€ Automatic environment detection - works seamlessly in SSH, CI, and pipe environments
# Install globally
npm install -g cat-ccnotify-hook
# Run the installer
cat-ccnotify-installThis will automatically:
- Install the package globally
- Create the
~/.claudedirectory if needed - Update
~/.claude/settings.jsonwith the correct hook configuration - Configure Claude Code to use cat notifications
- Type
/hooksin Claude Code - Press
ESCimmediately
-
Clone this repository:
git clone https://github.com/cat-ccnotify/cat-ccnotify-hook.git cd cat-ccnotify-hook -
Install dependencies:
npm install
-
Run the installer:
npm run install-hooks
Test your installation to make sure everything works:
# Simple notification test (recommended)
cat-notify
# Custom notification
cat-notify "My Title" "My custom message"
# Test actual hook functionality with Claude Code data format
cat-notify --notification-hook
cat-notify --stop-hook
# Test hooks via npm command
cat-ccnotify-test
# Or manually test hooks
node hooks/notification-hook.js
echo '{"title":"Test","message":"Session ended"}' | node hooks/stop-hook.cjsYou should see notifications with:
- π± Cat meow sounds
- π± Native macOS notifications
- π¨ Appropriate emojis (β for success, β for errors, etc.)
- π Your actual message content
All notifications play the same adorable cat meow sound! π±
The system intelligently analyzes your notification content and automatically adds appropriate emojis:
- β
Success:
complete,success,passed,done,deployed,published - β Error:
error,failed,crash,exception,cannot,invalid β οΈ Warning:warning,deprecated,caution,should,might- π‘ Info: General information and status updates
- β³ Progress:
running,processing,installing,building,loading - π Git:
commit,push,pull,merge,branch,repository - ποΈ Build:
build,compile,bundle,webpack,typescript - π§ͺ Test:
test,spec,jest,coverage,assertion - π Deploy:
deploy,release,production,staging,live - π¦ NPM:
npm,yarn,package,dependency,install - π File:
file,directory,write,read,created,modified
Instead of showing generic messages, you'll see your actual notification content:
- "β Tests Passed - All 25 tests completed successfully!"
- "β Git Push Failed - Permission denied to repository"
- "ποΈ Build Complete - TypeScript compilation finished"
Note: All categories use the same adorable cat meow sound. Future versions may include category-specific sounds!
The hooks are automatically configured in ~/.claude/settings.json. You can view the current configuration:
cat ~/.claude/settings.json | jq '.hooks'The hooks are configured in the new Claude Code format:
{
"hooks": {
"Notification": [
{
"type": "command",
"command": "node /path/to/notification-hook.js",
"description": "Cat-themed notification with meow sound"
}
],
"Stop": [
{
"type": "command",
"command": "node /path/to/stop-hook.cjs",
"description": "Cat-themed session end notification"
}
]
}
}After installation or making manual changes:
- Type
/hooksin Claude Code - Press
ESCimmediately to reload settings
You can customize the notification behavior with these environment variables:
# Force console output (echo) instead of system notifications
export CAT_CCNOTIFY_FORCE_CONSOLE=true
# Enable debug logging
export CAT_CCNOTIFY_DEBUG=trueπ€ Automatic Environment Detection: The system automatically detects when to use console output in these scenarios:
- SSH connections without X11 forwarding (
SSH_CONNECTIONwithoutDISPLAY) - CI environments (GitHub Actions, GitLab CI, Jenkins, Travis, CircleCI, etc.)
- Non-TTY environments (pipes, redirects, background processes)
Examples:
# SSH connection - automatically uses console output
ssh user@server
claude-code # β π± Console notifications
# CI environment - automatically uses console output
# GitHub Actions, GitLab CI, etc.
claude-code # β π± Console notifications
# Pipe usage - automatically uses console output
claude-code | tee output.log # β π± Console notifications
# Normal desktop usage - uses GUI notifications
claude-code # β Native macOS notifications + soundManual override (rarely needed):
# Force console output even in GUI environments
export CAT_CCNOTIFY_FORCE_CONSOLE=true
# Or temporarily
CAT_CCNOTIFY_FORCE_CONSOLE=true claude-codePriority order:
CAT_CCNOTIFY_FORCE_CONSOLE=true(manual override)- Automatic environment detection
- Platform-specific GUI notifications
- Console fallback
cat-ccnotify-hook/
βββ package.json # Package configuration and npm scripts
βββ README.md # This documentation
βββ INSTALL.md # Detailed installation guide
βββ PUBLISHING.md # npm publishing instructions
βββ jest.config.js # Test configuration
βββ .npmignore # npm package exclusions
βββ bin/
β βββ cat-notify # Command line testing tool
βββ hooks/ # Core hook implementations
β βββ notification-hook.js # Smart notification processor
β βββ stop-hook.cjs # Session end handler
β βββ hooks.json # Hook configuration template
βββ lib/ # Shared utilities
β βββ shell-executor.js # Secure command execution (ES)
β βββ shell-executor.cjs # Secure command execution (CJS)
β βββ error-handler.js # Comprehensive error handling (ES)
β βββ error-handler.cjs # Comprehensive error handling (CJS)
βββ sounds/ # Audio assets
β βββ cat-meow-1-fx-323465.mp3 # Adorable cat meow sound
βββ scripts/ # Management tools
β βββ install-hooks.js # Intelligent installer
β βββ uninstall-hooks.js # Clean uninstaller
β βββ test-hooks.js # Manual testing utility
βββ test/ # Test suite
βββ unit/ # Unit tests
β βββ shell-executor.test.js # Shell execution tests
β βββ error-handler.test.js # Error handling tests
βββ e2e/ # End-to-end tests
βββ notification-flow.test.js # Full workflow tests
hooks/notification-hook.js: Main notification processor with smart categorizationhooks/stop-hook.cjs: Handles Claude Code session terminationlib/shell-executor.js: Secure execution of macOS commandslib/error-handler.js: Comprehensive error handling and loggingscripts/install-hooks.js: Automatic hook configuration setuptest/: Complete test suite with unit and E2E tests
# Test hooks with different notification types
node hooks/notification-hook.js "Tests Passed" "All 25 tests completed successfully!"
node hooks/notification-hook.js "Build Failed" "TypeScript compilation errors found"
node hooks/notification-hook.js "Git Push" "Successfully pushed to origin/main"
# Test with JSON input
echo '{"title":"Deploy Complete","message":"Application deployed to production"}' | node hooks/notification-hook.js
# Test stop hook
echo '{"title":"Session Ended","message":"Claude Code session terminated"}' | node hooks/stop-hook.cjs
# Run test suite
npm test
npm run test:unit
npm run test:e2e
# Test with debug mode
CAT_CCNOTIFY_DEBUG=true node hooks/notification-hook.js "Debug Test" "Testing with detailed logging"- Add audio files to the
sounds/directory (supported: .mp3, .wav, .m4a, .aiff, .aac) - Update hook files to reference new sounds in the
sendEnhancedNotificationfunction - Test audio playback:
afplay sounds/your-new-sound.mp3 - Test integration:
npm test
- Modify emoji mappings in
enhanceNotificationStyle()function - Add new categories in
analyzeNotificationContent()function - Adjust content patterns to match your workflow
- Test changes: Run notification tests to verify new behavior
# If installed via npm:
cat-ccnotify-uninstall
# If installed locally:
cd /path/to/cat-ccnotify-hook
npm run uninstall-hooks
# Or manually edit ~/.claude/settings.json to remove the notification and stop hook entriesThis will restore Claude Code to use default notifications.
- Claude Code triggers a notification (file saved, command completed, error occurred, etc.)
- Hook receives data via multiple input methods:
- Environment variables (
CLAUDE_NOTIFICATION,NOTIFICATION_TITLE) - JSON data through stdin
- Plain text through stdin
- Command line arguments
- Environment variables (
- Content analysis - AI categorizes the notification (success, error, warning, git, build, etc.)
- Enhancement applied:
- Appropriate emoji added (β
, β,
β οΈ , ποΈ, etc.) - Content formatting and truncation
- Context-aware styling
- Appropriate emoji added (β
, β,
- Native macOS notification displayed using
osascript - Cat sound plays using
afplay
- Claude Code session ends
- Stop hook triggered with session metadata
- Special notification shown: "π± Claude Code - γ»γγ·γ§γ³η΅δΊ: [session info]"
- Cat meow plays to signal session end
The hook intelligently handles various input formats:
// JSON format
{"title":"Build Complete","message":"Compilation successful"}
// Plain text
"Tests passed - 25/25 successful"
// Multi-line
"Git Push Failed\nPermission denied to repository"
// Command args
node notification-hook.js "Title" "Message"For troubleshooting, enable debug mode to see comprehensive logging:
# Enable debug mode for a single test
CAT_CCNOTIFY_DEBUG=true node hooks/notification-hook.js "Debug Test" "Testing notification"
# Set globally for your session
export CAT_CCNOTIFY_DEBUG=true
# View debug logs
tail -f ~/.claude/cat-ccnotify/notification-hook.log
tail -f ~/.claude/cat-ccnotify/stop-hook.log
# View recent debug activity
tail -20 ~/.claude/cat-ccnotify/notification-hook.log- Environment Analysis: All Claude-related environment variables
- Input Processing: Raw stdin, JSON parsing, command line arguments
- Content Analysis: How notifications are categorized
- Enhancement Process: Emoji addition and message formatting
- Execution Flow: Each step of the notification process
- Error Details: Comprehensive error reporting and stack traces
- System Info: Process arguments, working directory, file paths
=== Debug Information ===
Process arguments: ["node", "/path/to/notification-hook.js", "Tests Passed", "All tests successful"]
Env CLAUDECODE: "1"
Using command line arguments: ["Tests Passed", "All tests successful"]
=== Final Result ===
Title: "Tests Passed"
Message: "All tests successful"
Level: "info"
Analyzed notification type: success
Enhanced notification - Title: "β
Tests Passed", Message: "All tests successful"
- Check audio file:
ls sounds/cat-meow-1-fx-323465.mp3 - Test audio manually:
afplay sounds/cat-meow-1-fx-323465.mp3 - Check macOS sound settings and volume levels
- Verify permissions: macOS may block audio from scripts
- Check notification permissions: System Settings β Notifications β Terminal/iTerm
- Test manually:
osascript -e 'display notification "Test" with title "Test"' - Verify hooks config:
cat ~/.claude/settings.json | grep -A 20 hooks - Check Claude Code version: Ensure you're using a compatible version
-
Verify installation:
which claude cat ~/.claude/settings.json | grep hooks
-
Reload hooks: Type
/hooksin Claude Code, then press ESC -
Enable debug mode:
export CAT_CCNOTIFY_DEBUG=true # Test a notification to generate logs echo '{"title":"Debug","message":"Test"}' | node hooks/notification-hook.js # Check logs tail -f ~/.claude/cat-ccnotify/notification-hook.log
-
Check file permissions:
ls -la ~/.claude/settings.json -
Verify hook paths: Ensure the paths in settings.json point to existing files
- "Command not found": Use full paths in settings.json
- "Permission denied": Check file permissions with
chmod +x hooks/*.js - "Module not found": Ensure all dependencies are installed
- Silent failures: Enable debug mode to see detailed error messages
- Script opens when clicking notification: This is a macOS behavior when notifications are sent from scripts
Issue: Clicking on notifications may open the script file in your default editor.
Why this happens: macOS associates notifications with their source. When sent from a script, clicking the notification opens that script.
Solutions:
-
Ignore the behavior: The notification functionality works perfectly; you can simply ignore clicking on them.
-
Install terminal-notifier (recommended):
# Install via Homebrew brew install terminal-notifier # The hooks will automatically use it if available
-
Change default app for .js files:
- Right-click any .js file β "Get Info"
- Under "Open with", select a different app
- Click "Change All..."
-
Disable notification clicking:
- System Settings β Notifications β Script Editor (or Terminal)
- Turn off "Allow Notifications"
- This prevents the script from opening but may disable other notifications
Note: This is a macOS system behavior, not a bug in cat-ccnotify-hook. The notifications work correctly; the click behavior is just a side effect of how macOS handles script-generated notifications.
# Enable debug mode
export CAT_CCNOTIFY_DEBUG=true
# Or set it permanently in your shell profile
echo 'export CAT_CCNOTIFY_DEBUG=true' >> ~/.zshrc
# View logs (only created when debug mode is enabled)
tail -f ~/.claude/cat-ccnotify/notification-hook.log
tail -f ~/.claude/cat-ccnotify/stop-hook.log
# View all cat-ccnotify logs
tail -f ~/.claude/cat-ccnotify/*.log- macOS (uses
afplayandosascript) - Node.js 16+
- Claude Code CLI installed
- Fork the repository
- Create a feature branch
- Make your changes
- Test thoroughly
- Submit a pull request
MIT License - see LICENSE file for details.
- Cat sound effects from freesound.org
- Built for the Claude Code CLI by Anthropic
- Inspired by the need for more delightful notifications
Made with π and π± for Claude Code users who love cats!