claude-mpm 2.1.1__py3-none-any.whl → 3.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- claude_mpm/_version.py +2 -2
- claude_mpm/agents/agent_loader.py +682 -102
- claude_mpm/agents/base_agent_loader.py +23 -8
- claude_mpm/agents/schema/agent_schema.json +237 -83
- claude_mpm/agents/templates/data_engineer.json +6 -3
- claude_mpm/agents/templates/documentation.json +6 -3
- claude_mpm/agents/templates/engineer.json +7 -4
- claude_mpm/agents/templates/ops.json +6 -3
- claude_mpm/agents/templates/qa.json +10 -5
- claude_mpm/agents/templates/research.json +31 -42
- claude_mpm/agents/templates/security.json +14 -6
- claude_mpm/agents/templates/version_control.json +9 -5
- claude_mpm/core/base_service.py +61 -1
- claude_mpm/hooks/claude_hooks/hook_handler.py +224 -20
- claude_mpm/schemas/README_SECURITY.md +92 -0
- claude_mpm/schemas/agent_schema.json +130 -51
- claude_mpm/schemas/agent_schema_security_notes.md +165 -0
- claude_mpm/services/agent_capabilities_generator.py +0 -1
- claude_mpm/services/agent_deployment.py +479 -91
- claude_mpm/services/agent_lifecycle_manager.py +62 -4
- claude_mpm/services/deployed_agent_discovery.py +0 -1
- claude_mpm/services/version_control/semantic_versioning.py +165 -16
- claude_mpm/validation/agent_validator.py +147 -13
- {claude_mpm-2.1.1.dist-info → claude_mpm-3.0.1.dist-info}/METADATA +2 -2
- {claude_mpm-2.1.1.dist-info → claude_mpm-3.0.1.dist-info}/RECORD +29 -29
- claude_mpm/cli_old/__init__.py +0 -1
- claude_mpm/cli_old/ticket_cli.py +0 -102
- {claude_mpm-2.1.1.dist-info → claude_mpm-3.0.1.dist-info}/WHEEL +0 -0
- {claude_mpm-2.1.1.dist-info → claude_mpm-3.0.1.dist-info}/entry_points.txt +0 -0
- {claude_mpm-2.1.1.dist-info → claude_mpm-3.0.1.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-2.1.1.dist-info → claude_mpm-3.0.1.dist-info}/top_level.txt +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"schema_version": "1.
|
|
2
|
+
"schema_version": "1.2.0",
|
|
3
3
|
"agent_id": "research_agent",
|
|
4
|
-
"agent_version": "2.
|
|
4
|
+
"agent_version": "2.2.0",
|
|
5
5
|
"agent_type": "research",
|
|
6
6
|
"metadata": {
|
|
7
7
|
"name": "Research Agent",
|
|
@@ -15,61 +15,50 @@
|
|
|
15
15
|
"confidence-validation",
|
|
16
16
|
"pm-escalation"
|
|
17
17
|
],
|
|
18
|
-
"
|
|
19
|
-
"tree-sitter-analysis",
|
|
20
|
-
"confidence-assessment",
|
|
21
|
-
"requirement-validation",
|
|
22
|
-
"pm-escalation"
|
|
23
|
-
]
|
|
18
|
+
"category": "research"
|
|
24
19
|
},
|
|
25
20
|
"capabilities": {
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
21
|
+
"model": "claude-sonnet-4-20250514",
|
|
22
|
+
"tools": [
|
|
23
|
+
"Read",
|
|
24
|
+
"Grep",
|
|
25
|
+
"Glob",
|
|
26
|
+
"LS",
|
|
27
|
+
"WebSearch",
|
|
28
|
+
"WebFetch",
|
|
29
|
+
"Bash",
|
|
30
|
+
"TodoWrite"
|
|
32
31
|
],
|
|
33
|
-
"
|
|
32
|
+
"resource_tier": "standard",
|
|
33
|
+
"temperature": 0.20,
|
|
34
|
+
"max_tokens": 12288,
|
|
35
|
+
"timeout": 900,
|
|
36
|
+
"memory_limit": 3072,
|
|
37
|
+
"cpu_limit": 60,
|
|
38
|
+
"network_access": true
|
|
39
|
+
},
|
|
40
|
+
"knowledge": {
|
|
41
|
+
"domain_expertise": [
|
|
34
42
|
"Tree-sitter AST analysis and code structure extraction",
|
|
35
43
|
"Confidence assessment frameworks and escalation protocols",
|
|
36
44
|
"Security pattern recognition and vulnerability assessment",
|
|
37
45
|
"Performance pattern identification and optimization opportunities",
|
|
38
46
|
"PM communication and requirement clarification techniques"
|
|
39
47
|
],
|
|
40
|
-
"
|
|
48
|
+
"best_practices": [
|
|
41
49
|
"Validate confidence levels before agent delegation",
|
|
42
50
|
"Generate specific questions for PM when information gaps exist",
|
|
43
51
|
"Assess implementation readiness with quantifiable confidence metrics",
|
|
44
52
|
"Create risk-aware analysis with mitigation strategies",
|
|
45
53
|
"Escalate to PM with actionable clarification requests"
|
|
46
|
-
]
|
|
47
|
-
},
|
|
48
|
-
"configuration": {
|
|
49
|
-
"model": "claude-4-sonnet-20250514",
|
|
50
|
-
"tools": [
|
|
51
|
-
"Read",
|
|
52
|
-
"Grep",
|
|
53
|
-
"Glob",
|
|
54
|
-
"LS",
|
|
55
|
-
"WebSearch",
|
|
56
|
-
"WebFetch",
|
|
57
|
-
"Bash"
|
|
58
54
|
],
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
"
|
|
65
|
-
|
|
66
|
-
"cpu_limit": 60
|
|
67
|
-
},
|
|
68
|
-
"permissions": {
|
|
69
|
-
"file_access": "project_only",
|
|
70
|
-
"network_access": true,
|
|
71
|
-
"dangerous_tools": false
|
|
72
|
-
}
|
|
55
|
+
"constraints": [
|
|
56
|
+
"Pre-implementation codebase analysis with confidence validation",
|
|
57
|
+
"Technical requirement clarification and validation",
|
|
58
|
+
"Implementation guidance preparation for specialized agents",
|
|
59
|
+
"Risk assessment and constraint identification",
|
|
60
|
+
"PM escalation when information gaps prevent reliable guidance"
|
|
61
|
+
]
|
|
73
62
|
},
|
|
74
63
|
"instructions": "# Research Agent - PRESCRIPTIVE ANALYSIS WITH CONFIDENCE VALIDATION\n\nConduct comprehensive codebase analysis with mandatory confidence validation. If confidence <80%, escalate to PM with specific questions needed to reach analysis threshold.\n\n## MANDATORY CONFIDENCE PROTOCOL\n\n### Confidence Assessment Framework\nAfter each analysis phase, evaluate confidence using this rubric:\n\n**80-100% Confidence (PROCEED)**: \n- All technical requirements clearly understood\n- Implementation patterns and constraints identified\n- Security and performance considerations documented\n- Clear path forward for target agent\n\n**60-79% Confidence (CONDITIONAL)**: \n- Core understanding present but gaps exist\n- Some implementation details unclear\n- Minor ambiguities in requirements\n- **ACTION**: Document gaps and proceed with caveats\n\n**<60% Confidence (ESCALATE)**: \n- Significant knowledge gaps preventing effective analysis\n- Unclear requirements or conflicting information\n- Unable to provide actionable guidance to target agent\n- **ACTION**: MANDATORY escalation to PM with specific questions\n\n### Escalation Protocol\nWhen confidence <80%, use TodoWrite to escalate:\n\n```\n[Research] CONFIDENCE THRESHOLD NOT MET - PM CLARIFICATION REQUIRED\n\nCurrent Confidence: [X]%\nTarget Agent: [Engineer/QA/Security/etc.]\n\nCRITICAL GAPS IDENTIFIED:\n1. [Specific gap 1] - Need: [Specific information needed]\n2. [Specific gap 2] - Need: [Specific information needed]\n3. [Specific gap 3] - Need: [Specific information needed]\n\nQUESTIONS FOR PM TO ASK USER:\n1. [Specific question about requirement/constraint]\n2. [Specific question about technical approach]\n3. [Specific question about integration/dependencies]\n\nIMPACT: Cannot provide reliable guidance to [Target Agent] without this information.\nRISK: Implementation may fail or require significant rework.\n```\n\n## Enhanced Analysis Protocol\n\n### Phase 1: Repository Structure Analysis (5 min)\n```bash\n# Get overall structure and file inventory\nfind . -name \"*.ts\" -o -name \"*.js\" -o -name \"*.py\" -o -name \"*.java\" -o -name \"*.rb\" -o -name \"*.php\" -o -name \"*.go\" | head -20\ntree -I 'node_modules|.git|dist|build|vendor|gems' -L 3\n\n# CONFIDENCE CHECK 1: Can I understand the project structure?\n# Required: Framework identification, file organization, entry points\n```\n\n### Phase 2: Tree-sitter Structural Extraction (10-15 min)\n```bash\n# Parse key files for structural data\ntree-sitter parse [file] --quiet | grep -E \"(function_declaration|class_declaration|interface_declaration|import_statement)\"\n\n# CONFIDENCE CHECK 2: Do I understand the code patterns and architecture?\n# Required: Component relationships, data flow, integration points\n```\n\n### Phase 3: Requirement Validation (5-10 min)\n```bash\n# Security patterns\ngrep -r \"password\\|token\\|auth\\|crypto\\|encrypt\" --include=\"*.ts\" --include=\"*.js\" --include=\"*.py\" --include=\"*.rb\" --include=\"*.php\" --include=\"*.go\" .\n# Performance patterns\ngrep -r \"async\\|await\\|Promise\\|goroutine\\|channel\" --include=\"*.ts\" --include=\"*.js\" --include=\"*.go\" .\n# Error handling\ngrep -r \"try.*catch\\|throw\\|Error\\|rescue\\|panic\\|recover\" --include=\"*.ts\" --include=\"*.js\" --include=\"*.py\" --include=\"*.rb\" --include=\"*.php\" --include=\"*.go\" .\n\n# CONFIDENCE CHECK 3: Do I understand the specific task requirements?\n# Required: Clear understanding of what needs to be implemented/fixed/analyzed\n```\n\n### Phase 4: Target Agent Preparation Assessment\n```bash\n# Assess readiness for specific agent delegation\n# For Engineer Agent: Implementation patterns, constraints, dependencies\n# For QA Agent: Testing infrastructure, validation requirements\n# For Security Agent: Attack surfaces, authentication flows, data handling\n\n# CONFIDENCE CHECK 4: Can I provide actionable guidance to the target agent?\n# Required: Specific recommendations, clear constraints, risk identification\n```\n\n### Phase 5: Final Confidence Evaluation\n**MANDATORY**: Before generating final report, assess overall confidence:\n\n1. **Technical Understanding**: Do I understand the codebase structure and patterns? [1-10]\n2. **Requirement Clarity**: Are the task requirements clear and unambiguous? [1-10]\n3. **Implementation Path**: Can I provide clear guidance for the target agent? [1-10]\n4. **Risk Assessment**: Have I identified the key risks and constraints? [1-10]\n5. **Context Completeness**: Do I have all necessary context for success? [1-10]\n\n**Overall Confidence**: (Sum / 5) * 10 = [X]%\n\n**Decision Matrix**:\n- 80-100%: Generate report and delegate\n- 60-79%: Generate report with clear caveats\n- <60%: ESCALATE to PM immediately\n\n## Enhanced Output Format\n\n```markdown\n# Tree-sitter Code Analysis Report\n\n## CONFIDENCE ASSESSMENT\n- **Overall Confidence**: [X]% \n- **Technical Understanding**: [X]/10\n- **Requirement Clarity**: [X]/10 \n- **Implementation Path**: [X]/10\n- **Risk Assessment**: [X]/10\n- **Context Completeness**: [X]/10\n- **Status**: [PROCEED/CONDITIONAL/ESCALATED]\n\n## Executive Summary\n- **Codebase**: [Project name]\n- **Primary Language**: [TypeScript/Python/Ruby/PHP/Go/JavaScript/Java]\n- **Architecture**: [MVC/Component-based/Microservices]\n- **Complexity Level**: [Low/Medium/High]\n- **Ready for [Agent Type] Work**: [✓/⚠️/❌]\n- **Confidence Level**: [High/Medium/Low]\n\n## Key Components Analysis\n### [Critical File 1]\n- **Type**: [Component/Service/Utility]\n- **Size**: [X lines, Y functions, Z classes]\n- **Key Functions**: `funcName()` - [purpose] (lines X-Y)\n- **Patterns**: [Error handling: ✓/⚠️/❌, Async: ✓/⚠️/❌]\n- **Confidence**: [High/Medium/Low] - [Rationale]\n\n## Agent-Specific Guidance\n### For [Target Agent]:\n**Confidence Level**: [X]%\n\n**Clear Requirements**:\n1. [Specific requirement 1] - [Confidence: High/Medium/Low]\n2. [Specific requirement 2] - [Confidence: High/Medium/Low]\n\n**Implementation Constraints**:\n1. [Technical constraint 1] - [Impact level]\n2. [Business constraint 2] - [Impact level]\n\n**Risk Areas**:\n1. [Risk 1] - [Likelihood/Impact] - [Mitigation strategy]\n2. [Risk 2] - [Likelihood/Impact] - [Mitigation strategy]\n\n**Success Criteria**:\n1. [Measurable outcome 1]\n2. [Measurable outcome 2]\n\n## KNOWLEDGE GAPS (if confidence <80%)\n### Unresolved Questions:\n1. [Question about requirement/constraint]\n2. [Question about technical approach]\n3. [Question about integration/dependencies]\n\n### Information Needed:\n1. [Specific information needed for confident analysis]\n2. [Additional context required]\n\n### Escalation Required:\n[YES/NO] - If YES, see TodoWrite escalation above\n\n## Recommendations\n1. **Immediate**: [Most urgent actions with confidence level]\n2. **Implementation**: [Specific guidance for target agent with confidence level]\n3. **Quality**: [Testing and validation needs with confidence level]\n4. **Risk Mitigation**: [Address identified uncertainties]\n```\n\n## Quality Standards\n- ✓ Confidence assessment completed for each phase\n- ✓ Overall confidence ≥80% OR escalation to PM\n- ✓ Agent-specific actionable insights with confidence levels\n- ✓ File paths and line numbers for reference\n- ✓ Security and performance concerns highlighted\n- ✓ Clear implementation recommendations with risk assessment\n- ✓ Knowledge gaps explicitly documented\n- ✓ Success criteria defined for target agent\n\n## Escalation Triggers\n- Confidence <80% on any critical aspect\n- Ambiguous or conflicting requirements\n- Missing technical context needed for implementation\n- Unclear success criteria or acceptance criteria\n- Unknown integration constraints or dependencies\n- Security implications not fully understood\n- Performance requirements unclear or unmeasurable"
|
|
75
64
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
"
|
|
2
|
+
"schema_version": "1.2.0",
|
|
3
|
+
"agent_id": "security_agent",
|
|
4
|
+
"agent_version": "1.1.0",
|
|
5
|
+
"agent_type": "security",
|
|
4
6
|
"metadata": {
|
|
5
7
|
"name": "Security Agent",
|
|
6
8
|
"description": "Security analysis and vulnerability assessment",
|
|
@@ -22,12 +24,12 @@
|
|
|
22
24
|
"Grep",
|
|
23
25
|
"Glob",
|
|
24
26
|
"LS",
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
+
"WebSearch",
|
|
28
|
+
"TodoWrite"
|
|
27
29
|
],
|
|
28
30
|
"resource_tier": "standard",
|
|
29
31
|
"max_tokens": 8192,
|
|
30
|
-
"temperature": 0.
|
|
32
|
+
"temperature": 0.0,
|
|
31
33
|
"timeout": 600,
|
|
32
34
|
"memory_limit": 3072,
|
|
33
35
|
"cpu_limit": 50,
|
|
@@ -39,7 +41,13 @@
|
|
|
39
41
|
"write_paths": [
|
|
40
42
|
"./"
|
|
41
43
|
]
|
|
42
|
-
}
|
|
44
|
+
},
|
|
45
|
+
"disallowed_tools": [
|
|
46
|
+
"Bash",
|
|
47
|
+
"Write",
|
|
48
|
+
"Edit",
|
|
49
|
+
"MultiEdit"
|
|
50
|
+
]
|
|
43
51
|
},
|
|
44
52
|
"instructions": "# Security Agent - AUTO-ROUTED\n\nAutomatically handle all security-sensitive operations. Focus on vulnerability assessment and secure implementation patterns.\n\n## Security Protocol\n1. **Threat Assessment**: Identify potential security risks and vulnerabilities\n2. **Secure Design**: Recommend secure implementation patterns\n3. **Compliance Check**: Validate against OWASP and security standards\n4. **Risk Mitigation**: Provide specific security improvements\n\n## Security Focus\n- OWASP compliance and best practices\n- Authentication/authorization security\n- Data protection and encryption standards",
|
|
45
53
|
"knowledge": {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
"
|
|
2
|
+
"schema_version": "1.2.0",
|
|
3
|
+
"agent_id": "version_control_agent",
|
|
4
|
+
"agent_version": "1.1.0",
|
|
5
|
+
"agent_type": "version_control",
|
|
4
6
|
"metadata": {
|
|
5
7
|
"name": "Version Control Agent",
|
|
6
8
|
"description": "Git operations and version management",
|
|
@@ -9,7 +11,8 @@
|
|
|
9
11
|
"git",
|
|
10
12
|
"versioning",
|
|
11
13
|
"releases",
|
|
12
|
-
"branches"
|
|
14
|
+
"branches",
|
|
15
|
+
"todo-write"
|
|
13
16
|
],
|
|
14
17
|
"author": "Claude MPM Team",
|
|
15
18
|
"created_at": "2025-07-27T03:45:51.494064Z",
|
|
@@ -22,11 +25,12 @@
|
|
|
22
25
|
"Bash",
|
|
23
26
|
"Grep",
|
|
24
27
|
"Glob",
|
|
25
|
-
"LS"
|
|
28
|
+
"LS",
|
|
29
|
+
"TodoWrite"
|
|
26
30
|
],
|
|
27
31
|
"resource_tier": "lightweight",
|
|
28
32
|
"max_tokens": 8192,
|
|
29
|
-
"temperature": 0.
|
|
33
|
+
"temperature": 0.0,
|
|
30
34
|
"timeout": 600,
|
|
31
35
|
"memory_limit": 1024,
|
|
32
36
|
"cpu_limit": 20,
|
claude_mpm/core/base_service.py
CHANGED
|
@@ -720,7 +720,67 @@ class BaseService(LoggerMixin, ABC):
|
|
|
720
720
|
return None
|
|
721
721
|
|
|
722
722
|
async def _collect_custom_metrics(self) -> None:
|
|
723
|
-
"""Collect custom metrics. Override in subclasses.
|
|
723
|
+
"""Collect custom metrics. Override in subclasses.
|
|
724
|
+
|
|
725
|
+
METRICS COLLECTION PATTERN:
|
|
726
|
+
This method is called periodically by the metrics task to collect
|
|
727
|
+
service-specific metrics. Subclasses should override this to:
|
|
728
|
+
|
|
729
|
+
1. COLLECT OPERATIONAL METRICS:
|
|
730
|
+
- Request rates and latencies
|
|
731
|
+
- Queue depths and processing times
|
|
732
|
+
- Error rates by type
|
|
733
|
+
- Resource utilization
|
|
734
|
+
|
|
735
|
+
2. COLLECT BUSINESS METRICS:
|
|
736
|
+
- Agent usage patterns
|
|
737
|
+
- Model selection distribution
|
|
738
|
+
- Task complexity trends
|
|
739
|
+
- Cost tracking metrics
|
|
740
|
+
|
|
741
|
+
3. COLLECT PERFORMANCE METRICS:
|
|
742
|
+
- Cache hit rates
|
|
743
|
+
- Database query times
|
|
744
|
+
- API call latencies
|
|
745
|
+
- Memory usage patterns
|
|
746
|
+
|
|
747
|
+
EXAMPLE IMPLEMENTATION:
|
|
748
|
+
```python
|
|
749
|
+
async def _collect_custom_metrics(self) -> None:
|
|
750
|
+
# Collect agent-specific metrics
|
|
751
|
+
if hasattr(self, 'agent_loader'):
|
|
752
|
+
loader_metrics = self.agent_loader.get_metrics()
|
|
753
|
+
self.update_metrics(
|
|
754
|
+
cache_hit_rate=loader_metrics['cache_hit_rate_percent'],
|
|
755
|
+
top_agents=loader_metrics['top_agents_by_usage']
|
|
756
|
+
)
|
|
757
|
+
|
|
758
|
+
# Collect deployment metrics
|
|
759
|
+
if hasattr(self, 'deployment_service'):
|
|
760
|
+
deploy_metrics = self.deployment_service.get_deployment_metrics()
|
|
761
|
+
self.update_metrics(
|
|
762
|
+
deployment_success_rate=deploy_metrics['success_rate_percent'],
|
|
763
|
+
avg_deployment_time=deploy_metrics['average_deployment_time_ms']
|
|
764
|
+
)
|
|
765
|
+
|
|
766
|
+
# Collect resource metrics
|
|
767
|
+
import psutil
|
|
768
|
+
process = psutil.Process()
|
|
769
|
+
self.update_metrics(
|
|
770
|
+
cpu_percent=process.cpu_percent(),
|
|
771
|
+
memory_mb=process.memory_info().rss / 1024 / 1024,
|
|
772
|
+
open_files=len(process.open_files()),
|
|
773
|
+
thread_count=process.num_threads()
|
|
774
|
+
)
|
|
775
|
+
```
|
|
776
|
+
|
|
777
|
+
BEST PRACTICES:
|
|
778
|
+
- Keep collection fast (< 100ms)
|
|
779
|
+
- Handle errors gracefully
|
|
780
|
+
- Use sampling for expensive operations
|
|
781
|
+
- Store aggregated data, not raw events
|
|
782
|
+
- Consider metric cardinality
|
|
783
|
+
"""
|
|
724
784
|
pass
|
|
725
785
|
|
|
726
786
|
# Utility methods
|
|
@@ -4,6 +4,31 @@
|
|
|
4
4
|
This script is called by hook_wrapper.sh, which is the shell script
|
|
5
5
|
that gets installed in ~/.claude/settings.json. The wrapper handles
|
|
6
6
|
environment setup and then executes this Python handler.
|
|
7
|
+
|
|
8
|
+
## Hook System Architecture:
|
|
9
|
+
|
|
10
|
+
The claude-mpm hook system follows an event-driven architecture where Claude Code
|
|
11
|
+
emits events that are intercepted by this handler. The system consists of:
|
|
12
|
+
|
|
13
|
+
1. **Event Source (Claude Code)**: Emits hook events for various actions
|
|
14
|
+
2. **Hook Wrapper (hook_wrapper.sh)**: Shell script that sets up the environment
|
|
15
|
+
3. **Hook Handler (this file)**: Python script that processes events
|
|
16
|
+
4. **Response Actions**: Continue, block, or modify Claude Code behavior
|
|
17
|
+
|
|
18
|
+
## Design Patterns Used:
|
|
19
|
+
|
|
20
|
+
1. **Chain of Responsibility**: Each hook type has its own handler method
|
|
21
|
+
2. **Strategy Pattern**: Different handling strategies for different event types
|
|
22
|
+
3. **Template Method**: Base handling logic with hook-specific implementations
|
|
23
|
+
|
|
24
|
+
## Event Flow:
|
|
25
|
+
|
|
26
|
+
1. User types in Claude Code -> Claude Code emits event
|
|
27
|
+
2. Event is passed to hook_wrapper.sh via stdin as JSON
|
|
28
|
+
3. Wrapper sets up Python environment and calls this handler
|
|
29
|
+
4. Handler reads event, logs it, and routes to appropriate method
|
|
30
|
+
5. Handler returns action response (continue/block) via stdout
|
|
31
|
+
6. Claude Code acts based on the response
|
|
7
32
|
"""
|
|
8
33
|
|
|
9
34
|
import json
|
|
@@ -25,48 +50,93 @@ logger = None
|
|
|
25
50
|
|
|
26
51
|
|
|
27
52
|
class ClaudeHookHandler:
|
|
28
|
-
"""Handler for all Claude Code hook events.
|
|
53
|
+
"""Handler for all Claude Code hook events.
|
|
54
|
+
|
|
55
|
+
This is the main service class that implements the hook system logic.
|
|
56
|
+
It acts as a central dispatcher for all hook events from Claude Code.
|
|
57
|
+
|
|
58
|
+
The handler follows these principles:
|
|
59
|
+
- **Fail-safe**: Always returns a continue action on errors
|
|
60
|
+
- **Non-blocking**: Quick responses to avoid UI delays
|
|
61
|
+
- **Project-aware**: Maintains separate logs per project
|
|
62
|
+
- **Extensible**: Easy to add new commands and event handlers
|
|
63
|
+
"""
|
|
29
64
|
|
|
30
65
|
def __init__(self):
|
|
31
|
-
|
|
32
|
-
|
|
66
|
+
"""Initialize the hook handler.
|
|
67
|
+
|
|
68
|
+
Sets up the handler state and defines available MPM commands.
|
|
69
|
+
The handler is stateless between invocations - each hook event
|
|
70
|
+
creates a new instance.
|
|
71
|
+
"""
|
|
72
|
+
self.event = None # The current event being processed
|
|
73
|
+
self.hook_type = None # Type of hook event (UserPromptSubmit, etc.)
|
|
33
74
|
|
|
34
|
-
#
|
|
75
|
+
# Registry of available MPM commands
|
|
76
|
+
# This acts as a command registry pattern for extensibility
|
|
35
77
|
self.mpm_args = {
|
|
36
78
|
'status': 'Show claude-mpm system status',
|
|
37
79
|
'agents': 'Show deployed agent versions',
|
|
38
|
-
#
|
|
80
|
+
# Future commands can be added here:
|
|
39
81
|
# 'config': 'Configure claude-mpm settings',
|
|
40
82
|
# 'debug': 'Toggle debug mode',
|
|
83
|
+
# 'logs': 'Show recent hook logs',
|
|
84
|
+
# 'reload': 'Reload agent configurations',
|
|
41
85
|
}
|
|
42
86
|
|
|
43
87
|
def handle(self):
|
|
44
|
-
"""Main entry point for hook handling.
|
|
88
|
+
"""Main entry point for hook handling.
|
|
89
|
+
|
|
90
|
+
This is the core method that:
|
|
91
|
+
1. Reads the event from stdin (passed by Claude Code)
|
|
92
|
+
2. Sets up project-specific logging
|
|
93
|
+
3. Routes the event to the appropriate handler
|
|
94
|
+
4. Returns the action response
|
|
95
|
+
|
|
96
|
+
The method implements the Template Method pattern where the overall
|
|
97
|
+
algorithm is defined here, but specific steps are delegated to
|
|
98
|
+
specialized methods.
|
|
99
|
+
|
|
100
|
+
Error Handling:
|
|
101
|
+
- All exceptions are caught to ensure fail-safe behavior
|
|
102
|
+
- Errors result in a 'continue' action to avoid blocking Claude Code
|
|
103
|
+
- Debug logs are written to /tmp for troubleshooting
|
|
104
|
+
"""
|
|
45
105
|
global logger
|
|
46
106
|
try:
|
|
47
|
-
# Quick debug log to file
|
|
107
|
+
# Quick debug log to file for troubleshooting
|
|
108
|
+
# This is separate from the main logger for bootstrap debugging
|
|
48
109
|
with open('/tmp/claude-mpm-hook.log', 'a') as f:
|
|
49
110
|
f.write(f"[{datetime.now().isoformat()}] Hook called\n")
|
|
50
111
|
|
|
51
112
|
# Read event from stdin
|
|
113
|
+
# Claude Code passes the event as JSON on stdin
|
|
114
|
+
# Format: {"hook_event_name": "...", "prompt": "...", ...}
|
|
52
115
|
event_data = sys.stdin.read()
|
|
53
116
|
self.event = json.loads(event_data)
|
|
54
117
|
self.hook_type = self.event.get('hook_event_name', 'unknown')
|
|
55
118
|
|
|
56
119
|
# Get the working directory from the event
|
|
120
|
+
# This ensures logs are written to the correct project directory
|
|
57
121
|
cwd = self.event.get('cwd', os.getcwd())
|
|
58
122
|
project_dir = Path(cwd)
|
|
59
123
|
|
|
60
124
|
# Initialize project-specific logging
|
|
125
|
+
# Each project gets its own log directory to avoid conflicts
|
|
126
|
+
# Logs are rotated daily by using date in filename
|
|
61
127
|
log_dir = project_dir / '.claude-mpm' / 'logs'
|
|
62
128
|
log_dir.mkdir(parents=True, exist_ok=True)
|
|
63
129
|
|
|
64
130
|
# Set up logging for this specific project
|
|
65
|
-
#
|
|
131
|
+
# Design decisions:
|
|
132
|
+
# - One log file per day for easy rotation and cleanup
|
|
133
|
+
# - Project-specific logger names to avoid cross-contamination
|
|
134
|
+
# - Environment variable for log level control
|
|
66
135
|
log_level = os.environ.get('CLAUDE_MPM_LOG_LEVEL', 'INFO')
|
|
67
136
|
log_file = log_dir / f"hooks_{datetime.now().strftime('%Y%m%d')}.log"
|
|
68
137
|
|
|
69
138
|
# Only set up logging if we haven't already for this project
|
|
139
|
+
# This avoids duplicate handlers when multiple hooks fire quickly
|
|
70
140
|
logger_name = f"claude_mpm_hooks_{project_dir.name}"
|
|
71
141
|
if not logging.getLogger(logger_name).handlers:
|
|
72
142
|
logger = setup_logging(
|
|
@@ -92,7 +162,16 @@ class ClaudeHookHandler:
|
|
|
92
162
|
# Log the event if DEBUG logging is enabled
|
|
93
163
|
self._log_event()
|
|
94
164
|
|
|
95
|
-
# Route to appropriate handler
|
|
165
|
+
# Route to appropriate handler based on event type
|
|
166
|
+
# This implements the Chain of Responsibility pattern
|
|
167
|
+
# Each handler method is responsible for its specific event type
|
|
168
|
+
#
|
|
169
|
+
# Available hook types:
|
|
170
|
+
# - UserPromptSubmit: User submits a prompt (can intercept /mpm commands)
|
|
171
|
+
# - PreToolUse: Before Claude uses a tool (can block/modify)
|
|
172
|
+
# - PostToolUse: After tool execution (for logging/monitoring)
|
|
173
|
+
# - Stop: Session or task ends
|
|
174
|
+
# - SubagentStop: Subagent completes its task
|
|
96
175
|
if self.hook_type == 'UserPromptSubmit':
|
|
97
176
|
with open('/tmp/claude-mpm-hook.log', 'a') as f:
|
|
98
177
|
f.write(f"[{datetime.now().isoformat()}] About to call _handle_user_prompt_submit\n")
|
|
@@ -119,7 +198,16 @@ class ClaudeHookHandler:
|
|
|
119
198
|
return self._continue()
|
|
120
199
|
|
|
121
200
|
def _log_event(self):
|
|
122
|
-
"""Log the event details if DEBUG logging is enabled.
|
|
201
|
+
"""Log the event details if DEBUG logging is enabled.
|
|
202
|
+
|
|
203
|
+
This method provides visibility into the hook system's operation.
|
|
204
|
+
It logs at different levels:
|
|
205
|
+
- INFO: Basic event occurrence (always logged)
|
|
206
|
+
- DEBUG: Full event details (only when DEBUG is enabled)
|
|
207
|
+
|
|
208
|
+
The method handles different event types specially to avoid
|
|
209
|
+
logging sensitive information or overly verbose data.
|
|
210
|
+
"""
|
|
123
211
|
global logger
|
|
124
212
|
if not logger:
|
|
125
213
|
return
|
|
@@ -179,7 +267,23 @@ class ClaudeHookHandler:
|
|
|
179
267
|
logger.info(f"SubagentStop: agent_type={agent_type}, agent_id={agent_id}, reason={reason} at {timestamp}")
|
|
180
268
|
|
|
181
269
|
def _handle_user_prompt_submit(self):
|
|
182
|
-
"""Handle UserPromptSubmit events.
|
|
270
|
+
"""Handle UserPromptSubmit events.
|
|
271
|
+
|
|
272
|
+
This is the most important handler as it intercepts user prompts
|
|
273
|
+
before they reach the LLM. It can:
|
|
274
|
+
- Detect and handle /mpm commands
|
|
275
|
+
- Modify prompts before processing
|
|
276
|
+
- Block prompts from reaching the LLM
|
|
277
|
+
|
|
278
|
+
Returns:
|
|
279
|
+
- Calls _continue() to let prompt pass through
|
|
280
|
+
- Exits with code 2 to block LLM processing (for /mpm commands)
|
|
281
|
+
|
|
282
|
+
Command Processing:
|
|
283
|
+
The method checks if the prompt starts with '/mpm' and routes
|
|
284
|
+
to the appropriate command handler. This allows claude-mpm to
|
|
285
|
+
provide an in-IDE command interface.
|
|
286
|
+
"""
|
|
183
287
|
try:
|
|
184
288
|
prompt = self.event.get('prompt', '').strip()
|
|
185
289
|
|
|
@@ -218,11 +322,29 @@ class ClaudeHookHandler:
|
|
|
218
322
|
return self._continue()
|
|
219
323
|
|
|
220
324
|
def _handle_pre_tool_use(self):
|
|
221
|
-
"""Handle PreToolUse events.
|
|
325
|
+
"""Handle PreToolUse events.
|
|
326
|
+
|
|
327
|
+
This handler is called before Claude executes any tool. It implements
|
|
328
|
+
security policies by:
|
|
329
|
+
- Checking for path traversal attempts
|
|
330
|
+
- Ensuring file operations stay within the working directory
|
|
331
|
+
- Blocking dangerous operations
|
|
332
|
+
|
|
333
|
+
Security Design:
|
|
334
|
+
- Fail-secure: Block suspicious operations
|
|
335
|
+
- Clear error messages to help users understand restrictions
|
|
336
|
+
- Log security events for auditing
|
|
337
|
+
|
|
338
|
+
Returns:
|
|
339
|
+
- JSON response with action="continue" to allow the tool
|
|
340
|
+
- JSON response with action="block" and error message to prevent execution
|
|
341
|
+
"""
|
|
222
342
|
tool_name = self.event.get('tool_name', '')
|
|
223
343
|
tool_input = self.event.get('tool_input', {})
|
|
224
344
|
|
|
225
345
|
# List of tools that perform write operations
|
|
346
|
+
# These tools need special security checks to prevent
|
|
347
|
+
# writing outside the project directory
|
|
226
348
|
write_tools = ['Write', 'Edit', 'MultiEdit', 'NotebookEdit']
|
|
227
349
|
|
|
228
350
|
# Check if this is a write operation
|
|
@@ -296,22 +418,68 @@ class ClaudeHookHandler:
|
|
|
296
418
|
return self._continue()
|
|
297
419
|
|
|
298
420
|
def _handle_post_tool_use(self):
|
|
299
|
-
"""Handle PostToolUse events.
|
|
421
|
+
"""Handle PostToolUse events.
|
|
422
|
+
|
|
423
|
+
Called after a tool has been executed. Currently used for:
|
|
424
|
+
- Logging tool execution results
|
|
425
|
+
- Monitoring tool usage patterns
|
|
426
|
+
- Future: Could modify tool outputs or trigger follow-up actions
|
|
427
|
+
|
|
428
|
+
This handler always continues as it's for observation only.
|
|
429
|
+
"""
|
|
300
430
|
# For now, just log and continue
|
|
431
|
+
# Future enhancements could include:
|
|
432
|
+
# - Modifying tool outputs
|
|
433
|
+
# - Triggering notifications on certain conditions
|
|
434
|
+
# - Collecting metrics on tool usage
|
|
301
435
|
return self._continue()
|
|
302
436
|
|
|
303
437
|
def _handle_stop(self):
|
|
304
|
-
"""Handle Stop events.
|
|
438
|
+
"""Handle Stop events.
|
|
439
|
+
|
|
440
|
+
Called when a Claude Code session or task ends. Useful for:
|
|
441
|
+
- Cleanup operations
|
|
442
|
+
- Final logging
|
|
443
|
+
- Session statistics
|
|
444
|
+
|
|
445
|
+
Currently just logs the event for monitoring purposes.
|
|
446
|
+
"""
|
|
305
447
|
# Log the stop event and continue
|
|
448
|
+
# Future: Could trigger cleanup or summary generation
|
|
306
449
|
return self._continue()
|
|
307
450
|
|
|
308
451
|
def _handle_subagent_stop(self):
|
|
309
|
-
"""Handle SubagentStop events.
|
|
452
|
+
"""Handle SubagentStop events.
|
|
453
|
+
|
|
454
|
+
Called when a subagent completes its task. Provides:
|
|
455
|
+
- Agent type and ID for tracking
|
|
456
|
+
- Completion reason
|
|
457
|
+
- Timing information
|
|
458
|
+
|
|
459
|
+
This is particularly useful for multi-agent workflows to track
|
|
460
|
+
which agents were involved and how they performed.
|
|
461
|
+
"""
|
|
310
462
|
# Log the subagent stop event and continue
|
|
463
|
+
# Future: Could aggregate subagent performance metrics
|
|
311
464
|
return self._continue()
|
|
312
465
|
|
|
313
466
|
def _handle_mpm_status(self, args=None):
|
|
314
|
-
"""Handle the /mpm
|
|
467
|
+
"""Handle the /mpm status command.
|
|
468
|
+
|
|
469
|
+
Displays comprehensive status information about the claude-mpm system.
|
|
470
|
+
This helps users verify their installation and troubleshoot issues.
|
|
471
|
+
|
|
472
|
+
Args:
|
|
473
|
+
args: Optional arguments like --verbose for detailed output
|
|
474
|
+
|
|
475
|
+
The method collects information about:
|
|
476
|
+
- Version information
|
|
477
|
+
- Python environment
|
|
478
|
+
- Logging configuration
|
|
479
|
+
- Hook system status
|
|
480
|
+
|
|
481
|
+
Uses ANSI colors for better readability in the terminal.
|
|
482
|
+
"""
|
|
315
483
|
# Parse arguments if provided
|
|
316
484
|
verbose = False
|
|
317
485
|
if args:
|
|
@@ -429,9 +597,17 @@ class ClaudeHookHandler:
|
|
|
429
597
|
def _handle_mpm_agents(self):
|
|
430
598
|
"""Handle the /mpm agents command to display deployed agent versions.
|
|
431
599
|
|
|
432
|
-
|
|
600
|
+
This command provides users with a quick way to check deployed agent versions
|
|
433
601
|
directly from within Claude Code, maintaining consistency with the CLI
|
|
434
602
|
and startup display functionality.
|
|
603
|
+
|
|
604
|
+
Design Philosophy:
|
|
605
|
+
- Reuse existing CLI functionality for consistency
|
|
606
|
+
- Display agent versions in the same format as CLI startup
|
|
607
|
+
- Graceful error handling with helpful messages
|
|
608
|
+
|
|
609
|
+
The method imports and reuses the CLI's agent version display function
|
|
610
|
+
to ensure consistent formatting across all interfaces.
|
|
435
611
|
"""
|
|
436
612
|
try:
|
|
437
613
|
# Import the agent version display function
|
|
@@ -463,7 +639,20 @@ class ClaudeHookHandler:
|
|
|
463
639
|
sys.exit(2)
|
|
464
640
|
|
|
465
641
|
def _handle_mpm_help(self, unknown_arg=None):
|
|
466
|
-
"""Show help for MPM commands.
|
|
642
|
+
"""Show help for MPM commands.
|
|
643
|
+
|
|
644
|
+
Displays a formatted help screen with available commands.
|
|
645
|
+
This serves as the primary documentation for in-IDE commands.
|
|
646
|
+
|
|
647
|
+
Args:
|
|
648
|
+
unknown_arg: If provided, shows an error for unknown command
|
|
649
|
+
|
|
650
|
+
Design:
|
|
651
|
+
- Uses ANSI colors that work in Claude Code's output
|
|
652
|
+
- Lists all registered commands from self.mpm_args
|
|
653
|
+
- Provides examples for common use cases
|
|
654
|
+
- Extensible: New commands automatically appear in help
|
|
655
|
+
"""
|
|
467
656
|
# ANSI colors
|
|
468
657
|
CYAN = '\033[96m'
|
|
469
658
|
RED = '\033[91m'
|
|
@@ -497,14 +686,29 @@ class ClaudeHookHandler:
|
|
|
497
686
|
sys.exit(2)
|
|
498
687
|
|
|
499
688
|
def _continue(self):
|
|
500
|
-
"""Return continue response to let prompt pass through.
|
|
689
|
+
"""Return continue response to let prompt pass through.
|
|
690
|
+
|
|
691
|
+
This is the default response for most hooks. It tells Claude Code
|
|
692
|
+
to continue with normal processing.
|
|
693
|
+
|
|
694
|
+
Response Format:
|
|
695
|
+
- {"action": "continue"}: Process normally
|
|
696
|
+
- Exit code 0: Success
|
|
697
|
+
|
|
698
|
+
This method ensures consistent response formatting across all handlers.
|
|
699
|
+
"""
|
|
501
700
|
response = {"action": "continue"}
|
|
502
701
|
print(json.dumps(response))
|
|
503
702
|
sys.exit(0)
|
|
504
703
|
|
|
505
704
|
|
|
506
705
|
def main():
|
|
507
|
-
"""Main entry point.
|
|
706
|
+
"""Main entry point.
|
|
707
|
+
|
|
708
|
+
Creates a new handler instance and processes the current event.
|
|
709
|
+
Each hook invocation is independent - no state is maintained
|
|
710
|
+
between calls. This ensures reliability and prevents memory leaks.
|
|
711
|
+
"""
|
|
508
712
|
handler = ClaudeHookHandler()
|
|
509
713
|
handler.handle()
|
|
510
714
|
|