Skip to content

Add Plugin Manager System for Claude Code Hooks#21

Open
nodeGarden wants to merge 4 commits intodisler:mainfrom
nodeGarden:feature/plugin-system
Open

Add Plugin Manager System for Claude Code Hooks#21
nodeGarden wants to merge 4 commits intodisler:mainfrom
nodeGarden:feature/plugin-system

Conversation

@nodeGarden
Copy link
Copy Markdown

@nodeGarden nodeGarden commented Nov 30, 2025

Add Plugin Manager System for Claude Code Hooks

Overview

This PR introduces a plugin manager system that allows multiple plugins to be installed and executed for hook events without modifying core hook files. The system auto-discovers plugins, validates metadata, and executes them in priority order with fail-safe error handling.

Caution

This was vibe coded with Claude... but it works for me


Key Features

Plugin Manager (plugin_manager.py)

  • Auto-discovery: Automatically discovers plugins from plugins/ directory
  • Metadata validation: Validates plugin.json against schema with comprehensive error messages
  • Version compatibility: Checks minimum manager version requirements using semantic versioning
  • Priority execution: Executes plugins in configurable priority order (lower = higher priority)
  • Fail-safe design: Plugin errors never crash the hook system
  • Hot-reload support: Development mode with reload_plugins() for testing
  • Structured logging: Configurable logging levels (WARNING default, DEBUG for verbose)
  • Singleton pattern: Single manager instance across all hooks

Plugin Development Support

  • TEMPLATE plugin: Complete skeleton for creating new plugins
  • PLUGIN_DEVELOPMENT.md: Comprehensive guide with examples
  • Test utilities: Simple Python test pattern without external dependencies

Hook Integration

  • Minimal changes: 7-line addition to each hook file
  • Graceful fallback: Continues working if plugin_manager doesn't exist
  • No patching required: Clean single import statement

Changes

New Files

  • .claude/hooks/plugin_manager.py (497 lines) - Core plugin system
  • .claude/hooks/PLUGIN_DEVELOPMENT.md - Developer documentation
  • .claude/hooks/plugins/TEMPLATE/ - Plugin template skeleton
  • .claude/hooks/tests/test_plugin_manager.py (496 lines) - Test suite

Modified Files

  • .claude/hooks/notification.py - Added plugin execution
  • .claude/hooks/post_tool_use.py - Added plugin execution
  • .claude/hooks/pre_compact.py - Added plugin execution
  • .claude/hooks/pre_tool_use.py - Added plugin execution
  • .claude/hooks/session_end.py - Added plugin execution
  • .claude/hooks/session_start.py - Added plugin execution
  • .claude/hooks/stop.py - Added plugin execution
  • .claude/hooks/subagent_stop.py - Added plugin execution
  • .claude/hooks/user_prompt_submit.py - Added plugin execution

Each hook file received this minimal addition:

# Execute plugins for this hook
try:
    from plugin_manager import execute_plugins
    execute_plugins("HookType", input_data)
except ImportError:
    pass  # Plugin manager not available

Technical Implementation

Plugin Structure

plugins/
  my_plugin/
    plugin.json          # Metadata (name, version, entry point, etc.)
    src/
      plugin.py          # Entry point with handle_hook(hook_type, input_data)
    config/
      config.json        # Plugin configuration
    tests/
      test_plugin.py     # Plugin tests

Plugin Metadata Schema

{
  "name": "my_plugin",
  "version": "1.0.0",
  "description": "My awesome plugin",
  "enabled": true,
  "priority": 50,
  "hooks": ["PostToolUse", "Stop"],
  "entry_point": "src.plugin:handle_hook",
  "min_manager_version": "1.0.0"
}

Version Compatibility

  • Semantic versioning (major.minor.patch)
  • Tuple comparison for version checking
  • Plugins requiring newer manager versions are skipped gracefully

Error Handling

  • All plugin exceptions are caught and logged
  • Hooks continue executing even if plugins fail
  • Logging to stderr for debugging

Testing

Test Coverage

Comprehensive test suite with 9 tests covering:

  • ✅ Version compatibility checking
  • ✅ Metadata validation (all fields and formats)
  • ✅ Plugin class functionality
  • ✅ Error handling and fail-safe behavior
  • ✅ Plugin discovery from directory
  • ✅ Version compatibility enforcement
  • ✅ Hot-reload functionality
  • ✅ Priority-based execution order
  • ✅ Convenience function interface

Running Tests

# Run plugin manager tests
cd .claude/hooks/tests
python3 test_plugin_manager.py

# Run with verbose output
python3 test_plugin_manager.py --verbose

# Test results: 9/9 passed ✓

Plugin Manager CLI

# List all discovered plugins
python3 plugin_manager.py --list

# Test plugins for a specific hook
python3 plugin_manager.py --test PostToolUse

# Reload plugins from disk
python3 plugin_manager.py --reload

# Enable verbose logging
python3 plugin_manager.py --list --verbose

Benefits

For Developers

  • Clean git state: No modified core files in plugins directory
  • Easy installation: Drop plugin folder in plugins/ directory
  • No scripting needed: Auto-discovery, no install/uninstall scripts
  • Complete isolation: Each plugin in its own directory
  • Hot-reload: Test changes without restarting
  • Template available: Quick start with TEMPLATE

For Users

  • Multiple plugins: Support unlimited plugins simultaneously
  • Easy management: Enable/disable via plugin.json
  • Priority control: Configure execution order
  • No conflicts: Plugins don't interfere with each other
  • Upstream-friendly: Minimal changes to core hooks

For Maintainers

  • Minimal core changes: 7 lines per hook file
  • No patching: Clean import-based integration
  • Comprehensive validation: Schema-based metadata checking
  • Fail-safe design: Plugin errors can't break hooks
  • Well-tested: 9 comprehensive tests
  • Well-documented: Complete developer guide

Breaking Changes

None. This is a new feature that doesn't modify existing behavior.

Migration Path

Existing hooks continue to work without changes. To adopt the plugin system:

  1. Existing custom code can be migrated to plugins
  2. Plugins can be added incrementally
  3. No changes required to existing hook behavior

Reviewer Checklist

  • Plugin manager auto-discovers plugins correctly
  • Metadata validation catches invalid configurations
  • Version compatibility checking works as expected
  • Plugins execute in correct priority order
  • Plugin errors don't crash hooks (fail-safe)
  • All 9 tests pass successfully
  • Hook files have minimal changes (7 lines each)
  • Documentation is clear and comprehensive
  • TEMPLATE plugin provides good starting point
  • No security concerns (validated in code review)

Follow-up Work

Future enhancements (not in this PR):

  • Plugin dependency management between plugins
  • Plugin lifecycle hooks (on_load, on_unload)
  • Plugin configuration UI/CLI
  • Plugin registry/marketplace
  • Async plugin execution for long-running tasks

Related Issues

This PR builds the foundation for the multi-agent observability system by providing a clean plugin architecture that allows multiple monitoring and notification plugins to coexist without conflicts.


Branch: feature/plugin-system
Base: main
Commits: 3

  • 033dcbc Add plugin manager system for hooks
  • 8c3571f Improve plugin system with logging, validation, and dev tools
  • 5f7384f Add comprehensive test suite for plugin manager

Testing: All tests passing (9/9) ✅
Security: Code review completed, no issues found ✅
Documentation: Complete developer guide included ✅

nodeGarden and others added 4 commits November 30, 2025 17:22
Implements a clean plugin architecture that eliminates dirty git state
and follows Python plugin framework best practices.

**Plugin Manager:**
- Auto-discovers plugins from plugins/ directory
- Loads plugin metadata from plugin.json
- Executes plugins with fail-safe error handling
- Supports multiple plugins per hook with priority ordering

**Hook Integration:**
- Minimal 7-line addition to each of 9 hook files
- Graceful fallback if plugin_manager doesn't exist
- No patching required - clean single import

**Developer Experience:**
- Comprehensive PLUGIN_DEVELOPMENT.md guide
- Complete TEMPLATE plugin skeleton
- Drop-in installation (no scripts needed)
- Clean git state (no modified core files)

**Benefits:**
- Eliminates dirty git state problem
- Upstream-friendly minimal changes
- Supports unlimited plugins simultaneously
- Easy plugin distribution and updates

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Implemented all recommended improvements from code review:

**1. Professional Logging System**
- Replaced all print() statements with proper logging module
- Configured logger with formatter: [PluginManager] LEVEL: message
- Default level: WARNING (configurable with --verbose flag)
- Logs to stderr to avoid interfering with stdout
- Better error context in log messages

**2. Plugin Version Compatibility**
- Added __version__ = "1.0.0" to plugin manager
- New min_manager_version field in plugin.json
- Automatic version checking during plugin load
- Semantic versioning support (major.minor.patch)
- _is_version_compatible() helper function
- Skips incompatible plugins with clear warning

**3. Plugin Reload Support**
- Added reload_plugins() method to PluginManager
- Clears and rediscovers all plugins from disk
- Useful for development when modifying plugins
- CLI: python3 plugin_manager.py --reload
- Logs reload progress with DEBUG level

**4. Config Schema Validation**
- Comprehensive PLUGIN_METADATA_SCHEMA definition
- Validates all metadata fields and formats
- _validate_metadata() with detailed error messages
- Checks: name format, version format, entry point syntax
- Optional jsonschema support for strict validation
- Falls back to basic validation if jsonschema unavailable

**Enhanced CLI:**
- --list: List all plugins (existing)
- --test HOOK: Test plugins for hook type (existing)
- --reload: Reload plugins from disk (NEW)
- --verbose: Enable DEBUG logging (NEW)

**Benefits:**
- More professional error messages
- Easier debugging with verbose mode
- Prevents incompatible plugin versions
- Hot-reload during development
- Better metadata validation
- Production-ready logging

All improvements backward compatible. Existing plugins work unchanged.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Created complete test coverage for plugin_manager.py following
the project's simple Python test pattern (no pytest required).

**Test Coverage (9 tests, 100% pass):**

1. **test_version_compatibility()**
   - Exact version matches
   - Newer versions (major, minor, patch)
   - Older versions (should fail)
   - Edge cases and boundary conditions

2. **test_metadata_validation()**
   - Valid metadata acceptance
   - Missing required fields detection
   - Invalid name format (uppercase, special chars)
   - Invalid version format (non-semver)
   - Invalid entry point format

3. **test_plugin_class()**
   - Plugin properties (name, version, enabled)
   - Hook support checking
   - Execution without errors
   - Disabled plugin behavior

4. **test_plugin_error_handling()**
   - Plugins that raise exceptions
   - Error catching and logging
   - Hook execution continues despite errors

5. **test_plugin_manager_discovery()**
   - Auto-discovery from plugins directory
   - Plugin loading and initialization
   - Plugin registration

6. **test_plugin_manager_version_check()**
   - Incompatible plugins skipped
   - Version requirement enforcement
   - Warning messages logged

7. **test_plugin_manager_reload()**
   - Plugin rediscovery from disk
   - State clearing and rebuilding
   - Hot-reload during development

8. **test_plugin_priority_execution()**
   - Plugins execute in priority order
   - Lower number = higher priority
   - Execution sequence verification

9. **test_execute_plugins_function()**
   - Convenience function works correctly
   - Singleton manager instance
   - Error handling for unknown hooks

**Test Infrastructure:**
- TestResults class tracks pass/fail
- Temporary directories for isolated testing
- No external dependencies (uses stdlib only)
- Clear pass/fail output with summary
- Proper cleanup after tests

**Usage:**
```bash
# Run all tests
python3 .claude/hooks/tests/test_plugin_manager.py

# Verbose output
python3 .claude/hooks/tests/test_plugin_manager.py --verbose
```

**Benefits:**
- Verifies all improvements work correctly
- Catches regressions during future changes
- Documents expected behavior
- No pytest/dependencies required
- Fast execution (<1 second)

All tests passing ✓

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Implements a flexible source_app detection system with fallback chain:
1. CLAUDE_SOURCE_APP environment variable (highest priority)
2. source_app in .claude/hooks/config.json
3. Project directory name auto-detection (fallback)

**New Files:**
- utils/source_app.py - Detection utility with get_source_app()
- config.json - Configured with "cc-hook-multi-agent-obvs"
- config.json.example - Template for other projects

**Modified Hooks:**
All 9 hook files now add source_app to input_data before calling plugins:
- notification.py
- post_tool_use.py
- pre_compact.py
- pre_tool_use.py
- session_end.py
- session_start.py
- stop.py
- subagent_stop.py
- user_prompt_submit.py

**Benefits:**
- Plugins can now identify which app triggered the hook
- No manual configuration required (auto-detects from folder name)
- Flexible override via env var or config file
- Consistent source_app across all hooks

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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.

1 participant