mirror of
https://github.com/SuperClaude-Org/SuperClaude_Framework.git
synced 2025-12-17 17:56:46 +00:00
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>
459 lines
19 KiB
Python
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 |