Skip to content

Feature/stop hook and enhanced notifications - #3

Open
Azure12355 wants to merge 5 commits into
wyattjoh:mainfrom
Azure12355:feature/stop-hook-and-enhanced-notifications
Open

Feature/stop hook and enhanced notifications#3
Azure12355 wants to merge 5 commits into
wyattjoh:mainfrom
Azure12355:feature/stop-hook-and-enhanced-notifications

Conversation

@Azure12355

Copy link
Copy Markdown

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

  • Stop Hook Support - Get notified when Claude Code finishes responding to a prompt
  • Notification Hook Enhancements - Better handling of permission prompts and system events
  • Intelligent Content Generation - Context-aware notification messages based on hook type
  • macOS Notification Improvements - Uses native osascript for reliable notification display
  • Enhanced Setup Wizard - Interactive configuration for multiple hook types
  • Comprehensive Documentation - Expanded guides for all new features

Changes by Category

📚 Documentation (CLAUDE.md & README.md)

  • Added "Supported Hook Events" section
  • Expanded JSON input schema documentation
  • Added interactive setup wizard documentation
  • Enhanced testing scenarios and examples
  • Added notification display mechanism documentation

🔧 Core Library (src/lib.rs)

  • Extended NotificationInput structure with new fields
  • Added generate_notification_content() for intelligent message generation
  • Added send_notification_osascript() for reliable macOS notifications
  • Enhanced send_notification() with parallel execution
  • Added comprehensive unit tests for Stop and Notification hooks

🎨 Setup Wizard (src/setup.rs)

  • Added hook selection menu (Notification, Stop, or Both)
  • Conditional sound selection for better UX
  • Enhanced configuration logic with helper functions
  • Improved user feedback and completion messages

📦 Examples (examples/)

  • Added test-notification.rs for standalone notification testing

Test Plan

  • Manual testing with Notification hook input
  • Manual testing with Stop hook input
  • Testing with custom sound files
  • Testing setup wizard with all hook configurations
  • Unit tests pass (cargo test)
  • Cross-platform compatibility verified

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

MusingAzure and others added 5 commits February 1, 2026 15:46
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants