feat: Enhanced Framework-Hooks with comprehensive testing and validation

- Update compression engine with improved YAML handling and error recovery
- Add comprehensive test suite with 10 test files covering edge cases
- Enhance hook system with better MCP intelligence and pattern detection
- Improve documentation with detailed configuration guides
- Add learned patterns for project optimization
- Strengthen notification and session lifecycle hooks

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
NomenAK
2025-08-05 22:20:42 +02:00
parent cee59e343c
commit 73dfcbb228
30 changed files with 5365 additions and 40 deletions

View File

@@ -54,8 +54,10 @@ class NotificationHook:
self.mcp_intelligence = MCPIntelligence()
self.compression_engine = CompressionEngine()
# Initialize learning engine
cache_dir = Path("cache")
# Initialize learning engine with installation directory cache
import os
cache_dir = Path(os.path.expanduser("~/.claude/cache"))
cache_dir.mkdir(parents=True, exist_ok=True)
self.learning_engine = LearningEngine(cache_dir)
# Load notification configuration

View File

@@ -54,8 +54,10 @@ class PostToolUseHook:
self.mcp_intelligence = MCPIntelligence()
self.compression_engine = CompressionEngine()
# Initialize learning engine
cache_dir = Path("cache")
# Initialize learning engine with installation directory cache
import os
cache_dir = Path(os.path.expanduser("~/.claude/cache"))
cache_dir.mkdir(parents=True, exist_ok=True)
self.learning_engine = LearningEngine(cache_dir)
# Load hook-specific configuration from SuperClaude config

View File

@@ -56,8 +56,10 @@ class PreCompactHook:
self.mcp_intelligence = MCPIntelligence()
self.compression_engine = CompressionEngine()
# Initialize learning engine
cache_dir = Path("cache")
# Initialize learning engine with installation directory cache
import os
cache_dir = Path(os.path.expanduser("~/.claude/cache"))
cache_dir.mkdir(parents=True, exist_ok=True)
self.learning_engine = LearningEngine(cache_dir)
# Load hook-specific configuration from SuperClaude config
@@ -318,7 +320,7 @@ class PreCompactHook:
content_type = metadata.get('content_type', '')
file_path = metadata.get('file_path', '')
if any(pattern in file_path for pattern in ['/SuperClaude/', '/.claude/', 'framework']):
if any(pattern in file_path for pattern in ['/.claude/', 'framework']):
framework_score += 3
if any(pattern in content_type for pattern in user_indicators):

View File

@@ -54,8 +54,10 @@ class PreToolUseHook:
self.mcp_intelligence = MCPIntelligence()
self.compression_engine = CompressionEngine()
# Initialize learning engine
cache_dir = Path("cache")
# Initialize learning engine with installation directory cache
import os
cache_dir = Path(os.path.expanduser("~/.claude/cache"))
cache_dir.mkdir(parents=True, exist_ok=True)
self.learning_engine = LearningEngine(cache_dir)
# Load hook-specific configuration from SuperClaude config

View File

@@ -46,15 +46,20 @@ class SessionStartHook:
def __init__(self):
start_time = time.time()
# Initialize core components
# Initialize only essential components immediately
self.framework_logic = FrameworkLogic()
self.pattern_detector = PatternDetector()
self.mcp_intelligence = MCPIntelligence()
self.compression_engine = CompressionEngine()
# Initialize learning engine with cache directory
cache_dir = Path("cache")
self.learning_engine = LearningEngine(cache_dir)
# Lazy-load other components to improve performance
self._pattern_detector = None
self._mcp_intelligence = None
self._compression_engine = None
self._learning_engine = None
# Use installation directory for cache
import os
cache_dir = Path(os.path.expanduser("~/.claude/cache"))
cache_dir.mkdir(parents=True, exist_ok=True)
self._cache_dir = cache_dir
# Load hook-specific configuration from SuperClaude config
self.hook_config = config_loader.get_hook_config('session_start')
@@ -69,6 +74,34 @@ class SessionStartHook:
# Performance tracking using configuration
self.initialization_time = (time.time() - start_time) * 1000
self.performance_target_ms = config_loader.get_hook_config('session_start', 'performance_target_ms', 50)
@property
def pattern_detector(self):
"""Lazy-load pattern detector to improve initialization performance."""
if self._pattern_detector is None:
self._pattern_detector = PatternDetector()
return self._pattern_detector
@property
def mcp_intelligence(self):
"""Lazy-load MCP intelligence to improve initialization performance."""
if self._mcp_intelligence is None:
self._mcp_intelligence = MCPIntelligence()
return self._mcp_intelligence
@property
def compression_engine(self):
"""Lazy-load compression engine to improve initialization performance."""
if self._compression_engine is None:
self._compression_engine = CompressionEngine()
return self._compression_engine
@property
def learning_engine(self):
"""Lazy-load learning engine to improve initialization performance."""
if self._learning_engine is None:
self._learning_engine = LearningEngine(self._cache_dir)
return self._learning_engine
def initialize_session(self, session_context: dict) -> dict:
"""

View File

@@ -239,7 +239,6 @@ class CompressionEngine:
# Framework content - complete exclusion
framework_patterns = [
'/SuperClaude/SuperClaude/',
'~/.claude/',
'.claude/',
'SuperClaude/',

View File

@@ -475,4 +475,86 @@ class MCPIntelligence:
efficiency_ratio = metrics.get('efficiency_ratio', 1.0)
efficiency_scores.append(min(efficiency_ratio, 2.0)) # Cap at 200% efficiency
return sum(efficiency_scores) / len(efficiency_scores) if efficiency_scores else 1.0
return sum(efficiency_scores) / len(efficiency_scores) if efficiency_scores else 1.0
def select_optimal_server(self, tool_name: str, context: Dict[str, Any]) -> str:
"""
Select the most appropriate MCP server for a given tool and context.
Args:
tool_name: Name of the tool to be executed
context: Context information for intelligent selection
Returns:
Name of the optimal server for the tool
"""
# Map common tools to server capabilities
tool_server_mapping = {
'read_file': 'morphllm',
'write_file': 'morphllm',
'edit_file': 'morphllm',
'analyze_architecture': 'sequential',
'complex_reasoning': 'sequential',
'debug_analysis': 'sequential',
'create_component': 'magic',
'ui_component': 'magic',
'design_system': 'magic',
'browser_test': 'playwright',
'e2e_test': 'playwright',
'performance_test': 'playwright',
'get_documentation': 'context7',
'library_docs': 'context7',
'framework_patterns': 'context7',
'semantic_analysis': 'serena',
'project_context': 'serena',
'memory_management': 'serena'
}
# Primary server selection based on tool
primary_server = tool_server_mapping.get(tool_name)
if primary_server:
return primary_server
# Context-based selection for unknown tools
if context.get('complexity', 'low') == 'high':
return 'sequential'
elif context.get('type') == 'ui':
return 'magic'
elif context.get('type') == 'browser':
return 'playwright'
elif context.get('file_count', 1) > 10:
return 'serena'
else:
return 'morphllm' # Default fallback
def get_fallback_server(self, tool_name: str, context: Dict[str, Any]) -> str:
"""
Get fallback server when primary server fails.
Args:
tool_name: Name of the tool
context: Context information
Returns:
Name of the fallback server
"""
primary_server = self.select_optimal_server(tool_name, context)
# Define fallback chains
fallback_chains = {
'sequential': 'serena',
'serena': 'morphllm',
'morphllm': 'context7',
'magic': 'morphllm',
'playwright': 'sequential',
'context7': 'morphllm'
}
fallback = fallback_chains.get(primary_server, 'morphllm')
# Avoid circular fallback
if fallback == primary_server:
return 'morphllm'
return fallback

View File

@@ -292,4 +292,6 @@ class UnifiedConfigLoader:
# Global instance for shared use across hooks
config_loader = UnifiedConfigLoader(".")
# Use Claude installation directory instead of current working directory
import os
config_loader = UnifiedConfigLoader(os.path.expanduser("~/.claude"))

View File

@@ -55,8 +55,10 @@ class StopHook:
self.mcp_intelligence = MCPIntelligence()
self.compression_engine = CompressionEngine()
# Initialize learning engine
cache_dir = Path("cache")
# Initialize learning engine with installation directory cache
import os
cache_dir = Path(os.path.expanduser("~/.claude/cache"))
cache_dir.mkdir(parents=True, exist_ok=True)
self.learning_engine = LearningEngine(cache_dir)
# Load hook-specific configuration from SuperClaude config
@@ -508,7 +510,8 @@ class StopHook:
persistence_result['compression_ratio'] = compression_result.compression_ratio
# Simulate saving (real implementation would use actual storage)
cache_dir = Path("cache")
cache_dir = Path(os.path.expanduser("~/.claude/cache"))
cache_dir.mkdir(parents=True, exist_ok=True)
session_file = cache_dir / f"session_{context['session_id']}.json"
with open(session_file, 'w') as f:

View File

@@ -55,8 +55,10 @@ class SubagentStopHook:
self.mcp_intelligence = MCPIntelligence()
self.compression_engine = CompressionEngine()
# Initialize learning engine
cache_dir = Path("cache")
# Initialize learning engine with installation directory cache
import os
cache_dir = Path(os.path.expanduser("~/.claude/cache"))
cache_dir.mkdir(parents=True, exist_ok=True)
self.learning_engine = LearningEngine(cache_dir)
# Load task management configuration