Feature/stop hook and enhanced notifications - #3
Open
Azure12355 wants to merge 5 commits into
Open
Conversation
This commit significantly expands the project documentation to reflect the new hook system and comprehensive notification features. ## Changes to CLAUDE.md - Added "Supported Hook Events" section explaining Notification and Stop hooks - Enhanced build commands with specific test examples - Expanded hook configuration section with: - Basic Notification Hook configuration - Stop Hook (task completion) configuration - Combined hooks configuration - Matcher-based filtering for specific notification types - Added comprehensive JSON Input Schema documentation: - Common fields for all events - Notification Hook specific fields - Stop Hook specific fields - Field descriptions table - Added "Interactive Setup" section documenting the setup wizard: - Features overview (hook selection, sound detection, validation) - Setup options (Notification only, Stop only, Both) - Technical implementation details - Enhanced "Manual Testing Scenarios" with: - Notification Hook testing examples - Stop Hook testing examples - Custom Audio File testing - Error Handling testing - Expanded "Architecture and Implementation" section: - Added "Notification Content Generation" subsection - Added "Notification Display Mechanism" with osascript details - Documented parallel execution with sound - Expanded test documentation with full test list ## Changes to README.md - Added Stop Hook and Notification Hook support to Features section - Added "Settings File Location" section with scope comparison table - Expanded "Configuration Examples" with: - Basic integration - Custom sound configuration - Matcher-based filtering - Stop Hook configuration - Both hooks configuration - Enhanced JSON Input Schema section with: - Additional fields (cwd, permission_mode, hook_event_name) - Notification types documentation - Matcher reference table with regex support - Updated "Manual Testing" section with new test scenarios - Added "Notification Display (macOS)" section explaining osascript usage These documentation updates provide comprehensive guidance for users and developers working with the enhanced notification system. Co-Authored-By: Claude <noreply@anthropic.com>
This commit introduces comprehensive support for Claude Code's Stop hook
and significantly enhances the notification system with intelligent
content generation and improved macOS notification reliability.
## Core Changes
### Extended NotificationInput Structure
Added new fields to support enhanced hook integration:
- `cwd`: Current working directory of the project
- `permission_mode`: Current permission mode (default, plan, etc.)
- `hook_event_name`: Event name ("Notification" or "Stop")
- `notification_type`: Type of notification event
- `stop_hook_active`: Whether stop hook is already active
- `reason`: Stop reason if provided
All fields use `#[serde(default)]` for backward compatibility.
### New: generate_notification_content() Function
Intelligent notification content generation based on hook event type:
**Stop Hook Content:**
- Title: "Claude Code" (or custom title)
- Body: "✅ Task completed!" with working directory
- Supports custom message override
- Shows "Claude stopped: {reason}" if reason provided
**Notification Hook Content:**
- Title: "Claude Code" (or custom title)
- Body: Formats as "{type} - {message}" if notification_type present
- Displays message directly otherwise
**Legacy Format Support:**
- Maintains backward compatibility with inputs without hook_event_name
- Displays title and message as-is for legacy formats
### New: send_notification_osascript() Function
Reliable macOS notification display using native osascript command:
- Sanitizes title and body for AppleScript (escapes backslashes, quotes)
- Replaces newlines with spaces for single-line display
- Uses "Glass" sound name for consistent notification sound
- Provides helpful error messages on failure
- Falls back gracefully if osascript is unavailable
### Enhanced send_notification() Function
Updated to use new content generation system:
- Calls generate_notification_content() for intelligent content
- Uses osascript as primary notification method (more reliable on macOS)
- Maintains notify-rust as fallback for cross-platform compatibility
- Parallel execution of notification and sound playback
### Comprehensive Test Coverage
Added extensive unit tests:
- `test_parse_stop_hook_input`: Validates Stop hook JSON parsing
- `test_parse_notification_hook_input`: Validates Notification hook JSON parsing
- `test_generate_notification_content_stop`: Tests Stop hook content generation
- `test_generate_notification_content_notification`: Tests Notification hook content generation
## Technical Details
**Why osascript for macOS?**
- Ensures notifications appear in macOS Notification Center
- More reliable than notify-rust on macOS
- Native integration with macOS notification system
- Supports sound playback through the same command
**Parallel Execution:**
Notifications and sound execute simultaneously using threading:
```rust
let sound_handle = thread::spawn(move || {
if let Err(e) = play_sound(&sound_clone) {
eprintln!("Warning: Failed to play sound: {}", e);
}
});
send_notification_osascript(&title_clone, &body_clone)?;
sound_handle.join()
```
This ensures immediate notification display while sound plays in background.
**Backward Compatibility:**
All new fields are optional with default values, ensuring legacy input
formats continue to work without modification.
Co-Authored-By: Claude <noreply@anthropic.com>
This commit significantly improves the interactive setup wizard to support configuring multiple hook types (Notification and Stop) with enhanced user experience and better feedback. ## New Features ### Hook Selection Menu Added interactive hook selection at the beginning of setup: - "Notification only" - Configure notifications for permission prompts - "Stop only" - Configure task completion notifications - "Both Notification and Stop" - Full notification coverage (recommended) The selection includes a help message explaining each hook type. ### Conditional Sound Selection Sound selection is now shown only when relevant: - If configuring either hook, shows sound selection menu - Otherwise, defaults to "Glass" system sound - Provides clearer user experience by skipping unnecessary prompts ### Enhanced Configuration Logic **build_command() helper function:** Centralized command building logic that handles: - System sounds: `claude-code-notification --sound Glass` - Custom files: `claude-code-notification --sound "/path/to/file.wav"` - Proper escaping of paths with spaces or special characters **Separate Hook Configuration:** - Notification hook configured independently from Stop hook - Each hook can use the same sound with proper command formatting - Maintains proper JSON structure for Claude Code settings ### Improved User Feedback Enhanced completion message shows: - Settings file location - Selected sound - Configured hooks with descriptions: - "Notification - Shows alerts when Claude sends notifications" - "Stop - Shows alerts when Claude finishes a task" - Clear confirmation message ## Technical Improvements **Hooks Object Management:** - Ensures "hooks" object exists in settings before configuration - Preserves existing hook configurations when updating - Maintains compatibility with other Claude Code settings **Flexible Sound Configuration:** - Same sound can be used for both hooks - Command building logic prevents code duplication - Handles both system sounds and custom file paths ## User Experience Flow 1. Select which hooks to configure 2. (If relevant) Select notification sound 3. Review configuration summary 4. Settings automatically written to Claude Code config file This enhancement makes the setup wizard more flexible and user-friendly while maintaining the robust error handling and validation from the original implementation. Co-Authored-By: Claude <noreply@anthropic.com>
Add a simple example program for testing the notification system independently of the Claude Code integration. ## test-notification.rs A minimal example demonstrating: - Basic notification display using notify-rust - Simple success/error handling - Clear console feedback for testing This example can be useful for: - Verifying notification system setup - Testing cross-platform compatibility - Debugging notification display issues - Demonstrating integration to other developers Run with: ```bash cargo run --example test-notification ``` Co-Authored-By: Claude <noreply@anthropic.com>
This commit adds automatic terminal activation functionality that brings
the terminal window to the front when a notification is displayed. This
is especially useful for users running multiple Claude Code sessions
in different terminals.
## New Features
### Terminal Detection System
Added `TerminalApp` enum that supports detecting and activating various
terminal applications:
- **Terminal.app** (com.apple.Terminal) - Default macOS terminal
- **iTerm2** (com.googlecode.iTerm2) - Popular enhanced terminal
- **Warp** (dev.warp.Warp-Stable) - Modern Rust-based terminal
- **WezTerm** (org.wezfurlong.wezterm) - Cross-platform GPU terminal
- **VSCode Integrated** (com.microsoft.VSCode) - IDE terminal
- **JetBrains IDE** (com.jetbrains.intellij) - IDE integrated terminals
### Detection Method
The terminal is detected by checking environment variables:
- `TERM_PROGRAM` - Set by most macOS terminals
- `TERM` - Contains terminal type (e.g., "wezterm")
- `VSCODE_PID` - Indicates VSCode integrated terminal
- `IDE_PRODUCT`/`JETBRAINS_IDE` - Indicates JetBrains IDE terminal
### Activation Functionality
- Uses AppleScript to activate the terminal application
- 300ms delay ensures notification is visible before switching focus
- Terminal becomes the frontmost window, ready for user input
- Gracefully handles unknown terminals with warning messages
### Command Line Interface
Added `--activate-terminal` flag:
```bash
claude-code-notification --activate-terminal
claude-code-notification --sound Submarine --activate-terminal
```
### Updated Function Signatures
- `main()`: Added `activate_terminal: bool` parameter
- `send_notification()`: Added `terminal: Option<TerminalApp>` parameter
- Updated all test calls to match new signatures
## Documentation Updates
### CLAUDE.md
- Added "Terminal Activation Parameter" section
- Documented supported terminals and detection methods
- Added usage examples and hook configuration examples
- Noted macOS-only requirement
### README.md
- Added "Terminal Auto-Activation" to Features list
- Added testing examples for terminal activation
- Documented how it works and supported terminals
## Technical Details
**Activation Flow:**
1. Notification is displayed using osascript
2. Sound plays in parallel (if configured)
3. 300ms delay allows notification to be seen
4. AppleScript activates the terminal application
5. Terminal becomes frontmost window
**Error Handling:**
- Unknown terminals produce warning but don't fail
- AppleScript failures produce detailed error messages
- Feature is silently ignored on non-macOS platforms
**Hook Configuration:**
```json
{
"hooks": {
"Notification": [{
"hooks": [{
"type": "command",
"command": "claude-code-notification --activate-terminal"
}]
}]
}
}
```
This feature significantly improves workflow efficiency when managing
multiple Claude Code sessions across different terminal windows.
Co-Authored-By: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR introduces comprehensive support for Claude Code's Stop Hook and significantly enhances the notification system with intelligent content generation, improved macOS reliability, and an upgraded setup wizard.
Key Features
osascriptfor reliable notification displayChanges by Category
📚 Documentation (CLAUDE.md & README.md)
🔧 Core Library (src/lib.rs)
NotificationInputstructure with new fieldsgenerate_notification_content()for intelligent message generationsend_notification_osascript()for reliable macOS notificationssend_notification()with parallel execution🎨 Setup Wizard (src/setup.rs)
📦 Examples (examples/)
test-notification.rsfor standalone notification testingTest Plan
cargo test)Breaking Changes
None. All new fields are optional with
#[serde(default)], ensuring full backward compatibility with existing integrations.Co-Authored-By: Claude noreply@anthropic.com