SuperClaude/Framework-Hooks/hooks/shared/pattern_detection.py
NomenAK 3e40322d0a refactor: Complete V4 Beta framework restructuring
Major reorganization of SuperClaude V4 Beta directories:
- Moved SuperClaude-Lite content to Framework-Hooks/
- Renamed SuperClaude/ directories to Framework/ for clarity
- Created separate Framework-Lite/ for lightweight variant
- Consolidated hooks system under Framework-Hooks/

This restructuring aligns with the V4 Beta architecture:
- Framework/: Full framework with all features
- Framework-Lite/: Lightweight variant
- Framework-Hooks/: Hooks system implementation

Part of SuperClaude V4 Beta development roadmap.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-05 15:21:02 +02:00

459 lines
19 KiB
Python

"""
Pattern Detection Engine for SuperClaude-Lite
Intelligent pattern detection for automatic mode activation,
MCP server selection, and operational optimization.
"""
import re
import json
from typing import Dict, Any, List, Set, Optional, Tuple
from dataclasses import dataclass
from enum import Enum
from yaml_loader import config_loader
class PatternType(Enum):
"""Types of patterns we can detect."""
MODE_TRIGGER = "mode_trigger"
MCP_SERVER = "mcp_server"
OPERATION_TYPE = "operation_type"
COMPLEXITY_INDICATOR = "complexity_indicator"
PERSONA_HINT = "persona_hint"
PERFORMANCE_HINT = "performance_hint"
@dataclass
class PatternMatch:
"""A detected pattern match."""
pattern_type: PatternType
pattern_name: str
confidence: float # 0.0 to 1.0
matched_text: str
suggestions: List[str]
metadata: Dict[str, Any]
@dataclass
class DetectionResult:
"""Result of pattern detection analysis."""
matches: List[PatternMatch]
recommended_modes: List[str]
recommended_mcp_servers: List[str]
suggested_flags: List[str]
complexity_score: float
confidence_score: float
class PatternDetector:
"""
Intelligent pattern detection system.
Analyzes user input, context, and operation patterns to determine:
- Which SuperClaude modes should be activated
- Which MCP servers are needed
- What optimization flags to apply
- Complexity and performance considerations
"""
def __init__(self):
self.patterns = config_loader.load_config('modes')
self.mcp_patterns = config_loader.load_config('orchestrator')
self._compile_patterns()
def _compile_patterns(self):
"""Compile regex patterns for efficient matching."""
self.compiled_patterns = {}
# Mode detection patterns
for mode_name, mode_config in self.patterns.get('mode_detection', {}).items():
patterns = mode_config.get('trigger_patterns', [])
self.compiled_patterns[f"mode_{mode_name}"] = [
re.compile(pattern, re.IGNORECASE) for pattern in patterns
]
# MCP server patterns
for server_name, server_config in self.mcp_patterns.get('routing_patterns', {}).items():
triggers = server_config.get('triggers', [])
self.compiled_patterns[f"mcp_{server_name}"] = [
re.compile(trigger, re.IGNORECASE) for trigger in triggers
]
def detect_patterns(self,
user_input: str,
context: Dict[str, Any],
operation_data: Dict[str, Any]) -> DetectionResult:
"""
Perform comprehensive pattern detection.
Args:
user_input: User's request or command
context: Session and environment context
operation_data: Information about the planned operation
Returns:
DetectionResult with all detected patterns and recommendations
"""
matches = []
# Detect mode triggers
mode_matches = self._detect_mode_patterns(user_input, context)
matches.extend(mode_matches)
# Detect MCP server needs
mcp_matches = self._detect_mcp_patterns(user_input, context, operation_data)
matches.extend(mcp_matches)
# Detect complexity indicators
complexity_matches = self._detect_complexity_patterns(user_input, operation_data)
matches.extend(complexity_matches)
# Detect persona hints
persona_matches = self._detect_persona_patterns(user_input, context)
matches.extend(persona_matches)
# Calculate overall scores
complexity_score = self._calculate_complexity_score(matches, operation_data)
confidence_score = self._calculate_confidence_score(matches)
# Generate recommendations
recommended_modes = self._get_recommended_modes(matches, complexity_score)
recommended_mcp_servers = self._get_recommended_mcp_servers(matches, context)
suggested_flags = self._get_suggested_flags(matches, complexity_score, context)
return DetectionResult(
matches=matches,
recommended_modes=recommended_modes,
recommended_mcp_servers=recommended_mcp_servers,
suggested_flags=suggested_flags,
complexity_score=complexity_score,
confidence_score=confidence_score
)
def _detect_mode_patterns(self, user_input: str, context: Dict[str, Any]) -> List[PatternMatch]:
"""Detect which SuperClaude modes should be activated."""
matches = []
# Brainstorming mode detection
brainstorm_indicators = [
r"(?:i want to|thinking about|not sure|maybe|could we)\s+(?:build|create|make)",
r"(?:brainstorm|explore|figure out|discuss)",
r"(?:new project|startup idea|feature concept)",
r"(?:ambiguous|uncertain|unclear)\s+(?:requirements|needs)"
]
for pattern in brainstorm_indicators:
if re.search(pattern, user_input, re.IGNORECASE):
matches.append(PatternMatch(
pattern_type=PatternType.MODE_TRIGGER,
pattern_name="brainstorming",
confidence=0.8,
matched_text=re.search(pattern, user_input, re.IGNORECASE).group(),
suggestions=["Enable brainstorming mode for requirements discovery"],
metadata={"mode": "brainstorming", "auto_activate": True}
))
break
# Task management mode detection
task_management_indicators = [
r"(?:multiple|many|several)\s+(?:tasks|files|components)",
r"(?:build|implement|create)\s+(?:system|feature|application)",
r"(?:complex|comprehensive|large-scale)",
r"(?:manage|coordinate|orchestrate)\s+(?:work|tasks|operations)"
]
for pattern in task_management_indicators:
if re.search(pattern, user_input, re.IGNORECASE):
matches.append(PatternMatch(
pattern_type=PatternType.MODE_TRIGGER,
pattern_name="task_management",
confidence=0.7,
matched_text=re.search(pattern, user_input, re.IGNORECASE).group(),
suggestions=["Enable task management for complex operations"],
metadata={"mode": "task_management", "delegation_likely": True}
))
break
# Token efficiency mode detection
efficiency_indicators = [
r"(?:brief|concise|compressed|short)",
r"(?:token|resource|memory)\s+(?:limit|constraint|optimization)",
r"(?:efficient|optimized|minimal)\s+(?:output|response)"
]
for pattern in efficiency_indicators:
if re.search(pattern, user_input, re.IGNORECASE):
matches.append(PatternMatch(
pattern_type=PatternType.MODE_TRIGGER,
pattern_name="token_efficiency",
confidence=0.9,
matched_text=re.search(pattern, user_input, re.IGNORECASE).group(),
suggestions=["Enable token efficiency mode"],
metadata={"mode": "token_efficiency", "compression_needed": True}
))
break
# Check resource usage for automatic efficiency mode
resource_usage = context.get('resource_usage_percent', 0)
if resource_usage > 75:
matches.append(PatternMatch(
pattern_type=PatternType.MODE_TRIGGER,
pattern_name="token_efficiency",
confidence=0.85,
matched_text="high_resource_usage",
suggestions=["Auto-enable token efficiency due to resource constraints"],
metadata={"mode": "token_efficiency", "trigger": "resource_constraint"}
))
return matches
def _detect_mcp_patterns(self, user_input: str, context: Dict[str, Any], operation_data: Dict[str, Any]) -> List[PatternMatch]:
"""Detect which MCP servers should be activated."""
matches = []
# Context7 (library documentation)
context7_patterns = [
r"(?:library|framework|package)\s+(?:documentation|docs|patterns)",
r"(?:react|vue|angular|express|django|flask)",
r"(?:import|require|install|dependency)",
r"(?:official|standard|best practice)\s+(?:way|pattern|approach)"
]
for pattern in context7_patterns:
if re.search(pattern, user_input, re.IGNORECASE):
matches.append(PatternMatch(
pattern_type=PatternType.MCP_SERVER,
pattern_name="context7",
confidence=0.8,
matched_text=re.search(pattern, user_input, re.IGNORECASE).group(),
suggestions=["Enable Context7 for library documentation"],
metadata={"mcp_server": "context7", "focus": "documentation"}
))
break
# Sequential (complex analysis)
sequential_patterns = [
r"(?:analyze|debug|troubleshoot|investigate)",
r"(?:complex|complicated|multi-step|systematic)",
r"(?:architecture|system|design)\s+(?:review|analysis)",
r"(?:root cause|performance|bottleneck)"
]
for pattern in sequential_patterns:
if re.search(pattern, user_input, re.IGNORECASE):
matches.append(PatternMatch(
pattern_type=PatternType.MCP_SERVER,
pattern_name="sequential",
confidence=0.75,
matched_text=re.search(pattern, user_input, re.IGNORECASE).group(),
suggestions=["Enable Sequential for multi-step analysis"],
metadata={"mcp_server": "sequential", "analysis_type": "complex"}
))
break
# Magic (UI components)
magic_patterns = [
r"(?:component|button|form|modal|dialog)",
r"(?:ui|frontend|interface|design)",
r"(?:react|vue|angular)\s+(?:component|element)",
r"(?:responsive|mobile|accessibility)"
]
for pattern in magic_patterns:
if re.search(pattern, user_input, re.IGNORECASE):
matches.append(PatternMatch(
pattern_type=PatternType.MCP_SERVER,
pattern_name="magic",
confidence=0.85,
matched_text=re.search(pattern, user_input, re.IGNORECASE).group(),
suggestions=["Enable Magic for UI component generation"],
metadata={"mcp_server": "magic", "component_type": "ui"}
))
break
# Playwright (testing)
playwright_patterns = [
r"(?:test|testing|e2e|end-to-end)",
r"(?:browser|cross-browser|automation)",
r"(?:performance|visual|regression)\s+(?:test|testing)",
r"(?:validate|verify|check)\s+(?:functionality|behavior)"
]
for pattern in playwright_patterns:
if re.search(pattern, user_input, re.IGNORECASE):
matches.append(PatternMatch(
pattern_type=PatternType.MCP_SERVER,
pattern_name="playwright",
confidence=0.8,
matched_text=re.search(pattern, user_input, re.IGNORECASE).group(),
suggestions=["Enable Playwright for testing operations"],
metadata={"mcp_server": "playwright", "test_type": "e2e"}
))
break
# Morphllm vs Serena intelligence selection
file_count = operation_data.get('file_count', 1)
complexity = operation_data.get('complexity_score', 0.0)
if file_count > 10 or complexity > 0.6:
matches.append(PatternMatch(
pattern_type=PatternType.MCP_SERVER,
pattern_name="serena",
confidence=0.9,
matched_text="high_complexity_operation",
suggestions=["Use Serena for complex multi-file operations"],
metadata={"mcp_server": "serena", "reason": "complexity_threshold"}
))
elif file_count <= 10 and complexity <= 0.6:
matches.append(PatternMatch(
pattern_type=PatternType.MCP_SERVER,
pattern_name="morphllm",
confidence=0.8,
matched_text="moderate_complexity_operation",
suggestions=["Use Morphllm for efficient editing operations"],
metadata={"mcp_server": "morphllm", "reason": "efficiency_optimized"}
))
return matches
def _detect_complexity_patterns(self, user_input: str, operation_data: Dict[str, Any]) -> List[PatternMatch]:
"""Detect complexity indicators in the request."""
matches = []
# High complexity indicators
high_complexity_patterns = [
r"(?:entire|whole|complete)\s+(?:codebase|system|application)",
r"(?:refactor|migrate|restructure)\s+(?:all|everything|entire)",
r"(?:architecture|system-wide|comprehensive)\s+(?:change|update|redesign)",
r"(?:complex|complicated|sophisticated)\s+(?:logic|algorithm|system)"
]
for pattern in high_complexity_patterns:
if re.search(pattern, user_input, re.IGNORECASE):
matches.append(PatternMatch(
pattern_type=PatternType.COMPLEXITY_INDICATOR,
pattern_name="high_complexity",
confidence=0.8,
matched_text=re.search(pattern, user_input, re.IGNORECASE).group(),
suggestions=["Consider delegation and thinking modes"],
metadata={"complexity_level": "high", "score_boost": 0.3}
))
break
# File count indicators
file_count = operation_data.get('file_count', 1)
if file_count > 5:
matches.append(PatternMatch(
pattern_type=PatternType.COMPLEXITY_INDICATOR,
pattern_name="multi_file_operation",
confidence=0.9,
matched_text=f"{file_count}_files",
suggestions=["Enable delegation for multi-file operations"],
metadata={"file_count": file_count, "delegation_recommended": True}
))
return matches
def _detect_persona_patterns(self, user_input: str, context: Dict[str, Any]) -> List[PatternMatch]:
"""Detect hints about which persona should be active."""
matches = []
persona_patterns = {
"architect": [r"(?:architecture|design|structure|system)\s+(?:review|analysis|planning)"],
"performance": [r"(?:performance|optimization|speed|efficiency|bottleneck)"],
"security": [r"(?:security|vulnerability|audit|secure|safety)"],
"frontend": [r"(?:ui|frontend|interface|component|design|responsive)"],
"backend": [r"(?:api|server|database|backend|service)"],
"devops": [r"(?:deploy|deployment|ci|cd|infrastructure|docker|kubernetes)"],
"testing": [r"(?:test|testing|qa|quality|coverage|validation)"]
}
for persona, patterns in persona_patterns.items():
for pattern in patterns:
if re.search(pattern, user_input, re.IGNORECASE):
matches.append(PatternMatch(
pattern_type=PatternType.PERSONA_HINT,
pattern_name=persona,
confidence=0.7,
matched_text=re.search(pattern, user_input, re.IGNORECASE).group(),
suggestions=[f"Consider {persona} persona for specialized expertise"],
metadata={"persona": persona, "domain_specific": True}
))
break
return matches
def _calculate_complexity_score(self, matches: List[PatternMatch], operation_data: Dict[str, Any]) -> float:
"""Calculate overall complexity score from detected patterns."""
base_score = operation_data.get('complexity_score', 0.0)
# Add complexity from pattern matches
for match in matches:
if match.pattern_type == PatternType.COMPLEXITY_INDICATOR:
score_boost = match.metadata.get('score_boost', 0.1)
base_score += score_boost
return min(base_score, 1.0)
def _calculate_confidence_score(self, matches: List[PatternMatch]) -> float:
"""Calculate overall confidence in pattern detection."""
if not matches:
return 0.0
total_confidence = sum(match.confidence for match in matches)
return min(total_confidence / len(matches), 1.0)
def _get_recommended_modes(self, matches: List[PatternMatch], complexity_score: float) -> List[str]:
"""Get recommended modes based on detected patterns."""
modes = set()
for match in matches:
if match.pattern_type == PatternType.MODE_TRIGGER:
modes.add(match.pattern_name)
# Auto-activate based on complexity
if complexity_score > 0.6:
modes.add("task_management")
return list(modes)
def _get_recommended_mcp_servers(self, matches: List[PatternMatch], context: Dict[str, Any]) -> List[str]:
"""Get recommended MCP servers based on detected patterns."""
servers = set()
for match in matches:
if match.pattern_type == PatternType.MCP_SERVER:
servers.add(match.pattern_name)
return list(servers)
def _get_suggested_flags(self, matches: List[PatternMatch], complexity_score: float, context: Dict[str, Any]) -> List[str]:
"""Get suggested flags based on patterns and complexity."""
flags = []
# Thinking flags based on complexity
if complexity_score >= 0.8:
flags.append("--ultrathink")
elif complexity_score >= 0.6:
flags.append("--think-hard")
elif complexity_score >= 0.3:
flags.append("--think")
# Delegation flags
for match in matches:
if match.metadata.get("delegation_recommended"):
flags.append("--delegate auto")
break
# Efficiency flags
for match in matches:
if match.metadata.get("compression_needed") or context.get('resource_usage_percent', 0) > 75:
flags.append("--uc")
break
# Validation flags for high-risk operations
if complexity_score > 0.7 or context.get('is_production', False):
flags.append("--validate")
return flags