claude-mpm 0.3.0__py3-none-any.whl → 1.1.0__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.
Files changed (42) hide show
  1. claude_mpm/_version.py +3 -2
  2. claude_mpm/agents/INSTRUCTIONS.md +23 -0
  3. claude_mpm/agents/__init__.py +2 -2
  4. claude_mpm/agents/agent-template.yaml +83 -0
  5. claude_mpm/agents/agent_loader.py +66 -90
  6. claude_mpm/agents/base_agent_loader.py +10 -15
  7. claude_mpm/cli.py +41 -47
  8. claude_mpm/cli_enhancements.py +297 -0
  9. claude_mpm/core/agent_name_normalizer.py +49 -0
  10. claude_mpm/core/factories.py +1 -46
  11. claude_mpm/core/service_registry.py +0 -8
  12. claude_mpm/core/simple_runner.py +50 -0
  13. claude_mpm/generators/__init__.py +5 -0
  14. claude_mpm/generators/agent_profile_generator.py +137 -0
  15. claude_mpm/hooks/README.md +75 -221
  16. claude_mpm/hooks/builtin/mpm_command_hook.py +125 -0
  17. claude_mpm/hooks/builtin/todo_agent_prefix_hook.py +8 -7
  18. claude_mpm/hooks/claude_hooks/__init__.py +5 -0
  19. claude_mpm/hooks/claude_hooks/hook_handler.py +399 -0
  20. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +47 -0
  21. claude_mpm/hooks/validation_hooks.py +181 -0
  22. claude_mpm/services/agent_management_service.py +4 -4
  23. claude_mpm/services/agent_profile_loader.py +1 -1
  24. claude_mpm/services/agent_registry.py +0 -1
  25. claude_mpm/services/base_agent_manager.py +3 -3
  26. claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +57 -31
  27. claude_mpm/utils/error_handler.py +247 -0
  28. claude_mpm/validation/__init__.py +5 -0
  29. claude_mpm/validation/agent_validator.py +175 -0
  30. {claude_mpm-0.3.0.dist-info → claude_mpm-1.1.0.dist-info}/METADATA +44 -7
  31. {claude_mpm-0.3.0.dist-info → claude_mpm-1.1.0.dist-info}/RECORD +34 -30
  32. claude_mpm/config/hook_config.py +0 -42
  33. claude_mpm/hooks/hook_client.py +0 -264
  34. claude_mpm/hooks/hook_runner.py +0 -370
  35. claude_mpm/hooks/json_rpc_executor.py +0 -259
  36. claude_mpm/hooks/json_rpc_hook_client.py +0 -319
  37. claude_mpm/services/hook_service.py +0 -388
  38. claude_mpm/services/hook_service_manager.py +0 -223
  39. claude_mpm/services/json_rpc_hook_manager.py +0 -92
  40. {claude_mpm-0.3.0.dist-info → claude_mpm-1.1.0.dist-info}/WHEEL +0 -0
  41. {claude_mpm-0.3.0.dist-info → claude_mpm-1.1.0.dist-info}/entry_points.txt +0 -0
  42. {claude_mpm-0.3.0.dist-info → claude_mpm-1.1.0.dist-info}/top_level.txt +0 -0
@@ -25,31 +25,56 @@ class TodoTaskToolsGenerator(BaseSectionGenerator):
25
25
  ### Agent Name Prefix System
26
26
 
27
27
  **Standard TodoWrite Entry Format:**
28
- - **Research tasks** → `Researcher: [task description]`
29
- - **Documentation tasks** → `Documentater: [task description]`
30
- - **Changelog tasks** → `Documentater: [changelog description]`
31
- - **QA tasks** → `QA: [task description]`
32
- - **DevOps tasks** → `Ops: [task description]`
33
- - **Security tasks** → `Security: [task description]`
34
- - **Version Control tasks** → `Versioner: [task description]`
35
- - **Version Management tasks** → `Versioner: [version management description]`
36
- - **Code Implementation tasks** → `Engineer: [implementation description]`
37
- - **Data Operations tasks** → `Data Engineer: [data management description]`
28
+ - **Research tasks** → `[Research] Analyze patterns and investigate implementation`
29
+ - **Documentation tasks** → `[Documentation] Update API reference and user guide`
30
+ - **Changelog tasks** → `[Documentation] Generate changelog for version 2.0`
31
+ - **QA tasks** → `[QA] Execute test suite and validate functionality`
32
+ - **DevOps tasks** → `[Ops] Configure deployment pipeline`
33
+ - **Security tasks** → `[Security] Perform vulnerability assessment`
34
+ - **Version Control tasks** → `[Version Control] Create feature branch and manage tags`
35
+ - **Version Management tasks** → `[Version Control] Apply semantic version bump`
36
+ - **Code Implementation tasks** → `[Engineer] Implement authentication system`
37
+ - **Data Operations tasks** → `[Data Engineer] Optimize database queries`
38
38
 
39
39
  ### Task Tool Subprocess Naming Conventions
40
40
 
41
- **Template Pattern:**
41
+ **Task Tool Usage Pattern:**
42
42
  ```
43
- **[Agent Nickname]**: [Specific task description with clear deliverables]
43
+ Task(description="[task description]", subagent_type="[agent-type]")
44
44
  ```
45
45
 
46
- **Examples of Proper Naming:**
47
- - ✅ **Documentationer**: Update framework/CLAUDE.md with Task Tool naming conventions
48
- - **QA**: Execute comprehensive test suite validation for merge readiness
49
- - **Versioner**: Create feature branch and sync with remote repository
50
- - **Researcher**: Investigate Next.js 14 performance optimization patterns
51
- - **Engineer**: Implement user authentication system with JWT tokens
52
- - **Data Engineer**: Configure PostgreSQL database and optimize query performance
46
+ **Valid subagent_type values (both formats accepted):**
47
+
48
+ **Lowercase-hyphenated format (traditional):**
49
+ - `subagent_type="research"` - For investigation and analysis
50
+ - `subagent_type="engineer"` - For coding and implementation
51
+ - `subagent_type="qa"` - For testing and quality assurance
52
+ - `subagent_type="documentation"` - For docs and guides
53
+ - `subagent_type="security"` - For security assessments
54
+ - `subagent_type="ops"` - For deployment and infrastructure
55
+ - `subagent_type="version-control"` - For git and version management
56
+ - `subagent_type="data-engineer"` - For data processing and APIs
57
+
58
+ **Capitalized format (matching TodoWrite prefixes - also accepted):**
59
+ - `subagent_type="Research"` - For investigation and analysis
60
+ - `subagent_type="Engineer"` - For coding and implementation
61
+ - `subagent_type="QA"` - For testing and quality assurance
62
+ - `subagent_type="Documentation"` - For docs and guides
63
+ - `subagent_type="Security"` - For security assessments
64
+ - `subagent_type="Ops"` - For deployment and infrastructure
65
+ - `subagent_type="Version Control"` - For git and version management
66
+ - `subagent_type="Data Engineer"` - For data processing and APIs
67
+
68
+ **Examples of Proper Task Tool Usage (both formats work):**
69
+ - ✅ `Task(description="Update framework documentation", subagent_type="documentation")`
70
+ - ✅ `Task(description="Execute test suite validation", subagent_type="qa")`
71
+ - ✅ `Task(description="Create feature branch and sync", subagent_type="version-control")`
72
+ - ✅ `Task(description="Investigate performance patterns", subagent_type="research")`
73
+ - ✅ `Task(description="Implement authentication system", subagent_type="engineer")`
74
+ - ✅ `Task(description="Configure database and optimize queries", subagent_type="data-engineer")`
75
+ - ✅ `Task(description="Analyze code patterns", subagent_type="Research")` (capitalized format)
76
+ - ✅ `Task(description="Update API docs", subagent_type="Documentation")` (capitalized format)
77
+ - ✅ `Task(description="Create release tags", subagent_type="Version Control")` (capitalized format)
53
78
 
54
79
  ### 🚨 MANDATORY: THREE SHORTCUT COMMANDS
55
80
 
@@ -72,18 +97,19 @@ class TodoTaskToolsGenerator(BaseSectionGenerator):
72
97
 
73
98
  **Example Integration:**
74
99
  ```
75
- TodoWrite: Create prefixed todos for "Push release"
76
- - ☐ Documentation Agent: Generate changelog and analyze version impact
77
- - ☐ QA Agent: Execute full test suite and quality validation
78
- - ☐ Data Engineer Agent: Validate data integrity and verify API connectivity
79
- - ☐ Version Control Agent: Apply semantic version bump and create release tags
80
-
81
- Task Tool → Documentation Agent: Generate changelog and analyze version impact
82
- Task Tool QA Agent: Execute full test suite and quality validation
83
- Task Tool Data Engineer Agent: Validate data integrity and verify API connectivity
84
- Task Tool Version Control Agent: Apply semantic version bump and create release tags
85
-
86
- Update TodoWrite status based on agent completions
100
+ # TodoWrite entries with proper agent prefixes:
101
+ - ☐ [Documentation] Generate changelog and analyze version impact
102
+ - ☐ [QA] Execute full test suite and quality validation
103
+ - ☐ [Data Engineer] Validate data integrity and verify API connectivity
104
+ - ☐ [Version Control] Apply semantic version bump and create release tags
105
+
106
+ # Corresponding Task Tool delegations:
107
+ Task(description="Generate changelog and analyze version impact", subagent_type="documentation")
108
+ Task(description="Execute full test suite and quality validation", subagent_type="qa")
109
+ Task(description="Validate data integrity and verify API connectivity", subagent_type="data-engineer")
110
+ Task(description="Apply semantic version bump and create release tags", subagent_type="version-control")
111
+
112
+ # Update TodoWrite status based on agent completions
87
113
  ```
88
114
 
89
115
  ---"""
@@ -0,0 +1,247 @@
1
+ """
2
+ Enhanced error handling utilities for claude-mpm.
3
+
4
+ Inspired by awesome-claude-code's comprehensive error handling approach.
5
+ """
6
+
7
+ import logging
8
+ import sys
9
+ from typing import Optional, Type, Callable, Any, Dict
10
+ from functools import wraps
11
+ import traceback
12
+ from datetime import datetime
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+
17
+ class MPMError(Exception):
18
+ """Base exception for claude-mpm errors."""
19
+
20
+ def __init__(self, message: str, details: Optional[Dict[str, Any]] = None,
21
+ suggestions: Optional[List[str]] = None):
22
+ """Initialize MPM error with details and suggestions."""
23
+ super().__init__(message)
24
+ self.details = details or {}
25
+ self.suggestions = suggestions or []
26
+ self.timestamp = datetime.now()
27
+
28
+ def get_user_friendly_message(self) -> str:
29
+ """Get a user-friendly error message."""
30
+ lines = [f"❌ Error: {str(self)}"]
31
+
32
+ if self.details:
33
+ lines.append("\nDetails:")
34
+ for key, value in self.details.items():
35
+ lines.append(f" {key}: {value}")
36
+
37
+ if self.suggestions:
38
+ lines.append("\n💡 Suggestions:")
39
+ for suggestion in self.suggestions:
40
+ lines.append(f" - {suggestion}")
41
+
42
+ return '\n'.join(lines)
43
+
44
+
45
+ class AgentLoadError(MPMError):
46
+ """Raised when agent loading fails."""
47
+ pass
48
+
49
+
50
+ class ValidationError(MPMError):
51
+ """Raised when validation fails."""
52
+ pass
53
+
54
+
55
+ class ExecutionError(MPMError):
56
+ """Raised when agent execution fails."""
57
+ pass
58
+
59
+
60
+ class ConfigurationError(MPMError):
61
+ """Raised when configuration is invalid."""
62
+ pass
63
+
64
+
65
+ def handle_errors(error_type: Type[Exception] = Exception,
66
+ fallback_value: Any = None,
67
+ log_level: int = logging.ERROR) -> Callable:
68
+ """
69
+ Decorator for handling errors with detailed logging and user feedback.
70
+
71
+ Args:
72
+ error_type: Type of exception to catch
73
+ fallback_value: Value to return on error
74
+ log_level: Logging level for errors
75
+ """
76
+ def decorator(func: Callable) -> Callable:
77
+ @wraps(func)
78
+ def wrapper(*args, **kwargs):
79
+ try:
80
+ return func(*args, **kwargs)
81
+ except error_type as e:
82
+ # Log the error with full traceback
83
+ logger.log(log_level, f"Error in {func.__name__}: {e}", exc_info=True)
84
+
85
+ # Provide user-friendly feedback
86
+ if isinstance(e, MPMError):
87
+ print(e.get_user_friendly_message(), file=sys.stderr)
88
+ else:
89
+ print(f"❌ Error: {e}", file=sys.stderr)
90
+
91
+ return fallback_value
92
+ except Exception as e:
93
+ # Catch unexpected errors
94
+ logger.critical(f"Unexpected error in {func.__name__}: {e}", exc_info=True)
95
+ print(f"❌ Unexpected error: {e}", file=sys.stderr)
96
+ print("💡 This might be a bug. Please report it.", file=sys.stderr)
97
+ return fallback_value
98
+
99
+ return wrapper
100
+ return decorator
101
+
102
+
103
+ class ErrorContext:
104
+ """Context manager for enhanced error reporting."""
105
+
106
+ def __init__(self, operation: str, details: Optional[Dict[str, Any]] = None):
107
+ """Initialize error context."""
108
+ self.operation = operation
109
+ self.details = details or {}
110
+
111
+ def __enter__(self):
112
+ """Enter the context."""
113
+ logger.debug(f"Starting operation: {self.operation}")
114
+ return self
115
+
116
+ def __exit__(self, exc_type, exc_val, exc_tb):
117
+ """Exit the context, handling any errors."""
118
+ if exc_type is None:
119
+ logger.debug(f"Completed operation: {self.operation}")
120
+ return
121
+
122
+ # Log the error with context
123
+ logger.error(
124
+ f"Error during {self.operation}: {exc_val}",
125
+ extra={'operation': self.operation, 'details': self.details},
126
+ exc_info=True
127
+ )
128
+
129
+ # Don't suppress the exception
130
+ return False
131
+
132
+
133
+ def retry_on_error(max_attempts: int = 3,
134
+ delay: float = 1.0,
135
+ backoff_factor: float = 2.0,
136
+ exceptions: tuple = (Exception,)) -> Callable:
137
+ """
138
+ Decorator for retrying operations on error.
139
+
140
+ Args:
141
+ max_attempts: Maximum number of attempts
142
+ delay: Initial delay between attempts
143
+ backoff_factor: Multiplier for delay after each failure
144
+ exceptions: Tuple of exceptions to retry on
145
+ """
146
+ def decorator(func: Callable) -> Callable:
147
+ @wraps(func)
148
+ async def async_wrapper(*args, **kwargs):
149
+ import asyncio
150
+
151
+ last_exception = None
152
+ current_delay = delay
153
+
154
+ for attempt in range(max_attempts):
155
+ try:
156
+ return await func(*args, **kwargs)
157
+ except exceptions as e:
158
+ last_exception = e
159
+ if attempt < max_attempts - 1:
160
+ logger.warning(
161
+ f"Attempt {attempt + 1}/{max_attempts} failed for {func.__name__}: {e}"
162
+ )
163
+ await asyncio.sleep(current_delay)
164
+ current_delay *= backoff_factor
165
+ else:
166
+ logger.error(
167
+ f"All {max_attempts} attempts failed for {func.__name__}"
168
+ )
169
+
170
+ raise last_exception
171
+
172
+ @wraps(func)
173
+ def sync_wrapper(*args, **kwargs):
174
+ import time
175
+
176
+ last_exception = None
177
+ current_delay = delay
178
+
179
+ for attempt in range(max_attempts):
180
+ try:
181
+ return func(*args, **kwargs)
182
+ except exceptions as e:
183
+ last_exception = e
184
+ if attempt < max_attempts - 1:
185
+ logger.warning(
186
+ f"Attempt {attempt + 1}/{max_attempts} failed for {func.__name__}: {e}"
187
+ )
188
+ time.sleep(current_delay)
189
+ current_delay *= backoff_factor
190
+ else:
191
+ logger.error(
192
+ f"All {max_attempts} attempts failed for {func.__name__}"
193
+ )
194
+
195
+ raise last_exception
196
+
197
+ # Return appropriate wrapper based on function type
198
+ import asyncio
199
+ if asyncio.iscoroutinefunction(func):
200
+ return async_wrapper
201
+ else:
202
+ return sync_wrapper
203
+
204
+ return decorator
205
+
206
+
207
+ def format_exception_chain(exc: Exception) -> str:
208
+ """Format an exception chain for display."""
209
+ lines = []
210
+ current = exc
211
+ level = 0
212
+
213
+ while current is not None:
214
+ indent = " " * level
215
+ lines.append(f"{indent}{'└─' if level > 0 else ''}{type(current).__name__}: {current}")
216
+
217
+ if hasattr(current, '__cause__'):
218
+ current = current.__cause__
219
+ level += 1
220
+ else:
221
+ break
222
+
223
+ return '\n'.join(lines)
224
+
225
+
226
+ # Setup patterns from awesome-claude-code
227
+ def suggest_setup_fix(error: Exception) -> List[str]:
228
+ """Suggest fixes for common setup errors."""
229
+ suggestions = []
230
+ error_msg = str(error).lower()
231
+
232
+ if 'git' in error_msg and 'not found' in error_msg:
233
+ suggestions.append("Install git from https://git-scm.com/downloads")
234
+
235
+ if 'python' in error_msg and 'module' in error_msg:
236
+ suggestions.append("Ensure you're in a virtual environment")
237
+ suggestions.append("Run: pip install -e .")
238
+
239
+ if 'permission' in error_msg:
240
+ suggestions.append("Check file permissions")
241
+ suggestions.append("You may need to run with appropriate privileges")
242
+
243
+ if 'config' in error_msg or 'configuration' in error_msg:
244
+ suggestions.append("Check your configuration files")
245
+ suggestions.append("Run: mpm validate-config")
246
+
247
+ return suggestions
@@ -0,0 +1,5 @@
1
+ """Validation framework for claude-mpm."""
2
+
3
+ from .agent_validator import AgentValidator, ValidationResult
4
+
5
+ __all__ = ['AgentValidator', 'ValidationResult']
@@ -0,0 +1,175 @@
1
+ """
2
+ Agent validation framework inspired by awesome-claude-code validation patterns.
3
+
4
+ This module provides comprehensive validation for agent configurations with
5
+ override support, field locking, and detailed error reporting.
6
+ """
7
+
8
+ import logging
9
+ from pathlib import Path
10
+ from typing import Dict, List, Tuple, Optional, Set, Any
11
+ import yaml
12
+ from dataclasses import dataclass, field
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+
17
+ @dataclass
18
+ class ValidationResult:
19
+ """Result of agent validation."""
20
+ is_valid: bool
21
+ errors: List[str] = field(default_factory=list)
22
+ warnings: List[str] = field(default_factory=list)
23
+ locked_fields: Set[str] = field(default_factory=set)
24
+ applied_overrides: Dict[str, Any] = field(default_factory=dict)
25
+
26
+
27
+ class AgentValidator:
28
+ """Validates agent configurations with override support."""
29
+
30
+ REQUIRED_FIELDS = ['name', 'version', 'description', 'agents']
31
+ AGENT_REQUIRED_FIELDS = ['name', 'role', 'prompt_template']
32
+
33
+ def __init__(self, override_file: Optional[Path] = None):
34
+ """Initialize the validator with optional override configuration."""
35
+ self.overrides = {}
36
+ if override_file and override_file.exists():
37
+ self.overrides = self._load_overrides(override_file)
38
+
39
+ def _load_overrides(self, override_file: Path) -> Dict[str, Any]:
40
+ """Load override configuration from YAML file."""
41
+ try:
42
+ with open(override_file, 'r') as f:
43
+ data = yaml.safe_load(f)
44
+ return data.get('overrides', {})
45
+ except Exception as e:
46
+ logger.warning(f"Failed to load overrides from {override_file}: {e}")
47
+ return {}
48
+
49
+ def validate_agent_config(self, config: Dict[str, Any], agent_id: str) -> ValidationResult:
50
+ """Validate a single agent configuration."""
51
+ result = ValidationResult(is_valid=True)
52
+
53
+ # Apply overrides
54
+ config, locked_fields, skip_validation = self._apply_overrides(config, agent_id)
55
+ result.locked_fields = locked_fields
56
+
57
+ if skip_validation:
58
+ logger.info(f"Skipping validation for agent {agent_id} - marked as skip_validation")
59
+ return result
60
+
61
+ # Validate required fields
62
+ for field in self.AGENT_REQUIRED_FIELDS:
63
+ if field not in locked_fields and field not in config:
64
+ result.errors.append(f"Missing required field: {field}")
65
+ result.is_valid = False
66
+
67
+ # Validate prompt template
68
+ if 'prompt_template' in config and 'prompt_template' not in locked_fields:
69
+ template_result = self._validate_prompt_template(config['prompt_template'])
70
+ if not template_result[0]:
71
+ result.errors.extend(template_result[1])
72
+ result.is_valid = False
73
+
74
+ # Validate tools if present
75
+ if 'tools' in config:
76
+ tools_result = self._validate_tools(config['tools'])
77
+ if not tools_result[0]:
78
+ result.errors.extend(tools_result[1])
79
+ result.is_valid = False
80
+
81
+ return result
82
+
83
+ def _apply_overrides(self, config: Dict[str, Any], agent_id: str) -> Tuple[Dict[str, Any], Set[str], bool]:
84
+ """Apply overrides to an agent configuration."""
85
+ if agent_id not in self.overrides:
86
+ return config, set(), False
87
+
88
+ override_config = self.overrides[agent_id]
89
+ locked_fields = set()
90
+ skip_validation = override_config.get('skip_validation', False)
91
+
92
+ # Apply each override
93
+ for field, value in override_config.items():
94
+ if field.endswith('_locked'):
95
+ base_field = field.replace('_locked', '')
96
+ if override_config.get(field, False):
97
+ locked_fields.add(base_field)
98
+ elif field not in ['notes', 'skip_validation']:
99
+ config[field] = value
100
+
101
+ return config, locked_fields, skip_validation
102
+
103
+ def _validate_prompt_template(self, template: str) -> Tuple[bool, List[str]]:
104
+ """Validate prompt template format and placeholders."""
105
+ errors = []
106
+
107
+ if not template or not isinstance(template, str):
108
+ errors.append("Prompt template must be a non-empty string")
109
+ return False, errors
110
+
111
+ # Check for common placeholders
112
+ expected_placeholders = ['{context}', '{task}', '{constraints}']
113
+ missing_placeholders = []
114
+
115
+ for placeholder in expected_placeholders:
116
+ if placeholder not in template:
117
+ missing_placeholders.append(placeholder)
118
+
119
+ if missing_placeholders:
120
+ errors.append(f"Prompt template missing placeholders: {', '.join(missing_placeholders)}")
121
+
122
+ return len(errors) == 0, errors
123
+
124
+ def _validate_tools(self, tools: List[str]) -> Tuple[bool, List[str]]:
125
+ """Validate agent tools configuration."""
126
+ errors = []
127
+
128
+ if not isinstance(tools, list):
129
+ errors.append("Tools must be a list")
130
+ return False, errors
131
+
132
+ # Known valid tools
133
+ valid_tools = {
134
+ 'file_operations', 'code_analysis', 'git_operations',
135
+ 'testing', 'documentation', 'security_scan'
136
+ }
137
+
138
+ for tool in tools:
139
+ if tool not in valid_tools:
140
+ errors.append(f"Unknown tool: {tool}")
141
+
142
+ return len(errors) == 0, errors
143
+
144
+ def validate_profile(self, profile_path: Path) -> ValidationResult:
145
+ """Validate an entire agent profile."""
146
+ result = ValidationResult(is_valid=True)
147
+
148
+ try:
149
+ with open(profile_path, 'r') as f:
150
+ profile_data = yaml.safe_load(f)
151
+ except Exception as e:
152
+ result.errors.append(f"Failed to load profile: {e}")
153
+ result.is_valid = False
154
+ return result
155
+
156
+ # Validate top-level fields
157
+ for field in self.REQUIRED_FIELDS:
158
+ if field not in profile_data:
159
+ result.errors.append(f"Missing required top-level field: {field}")
160
+ result.is_valid = False
161
+
162
+ # Validate each agent
163
+ if 'agents' in profile_data:
164
+ for agent_config in profile_data['agents']:
165
+ agent_id = agent_config.get('name', 'unknown')
166
+ agent_result = self.validate_agent_config(agent_config, agent_id)
167
+
168
+ if not agent_result.is_valid:
169
+ result.is_valid = False
170
+ result.errors.extend([f"Agent '{agent_id}': {e}" for e in agent_result.errors])
171
+
172
+ result.warnings.extend([f"Agent '{agent_id}': {w}" for w in agent_result.warnings])
173
+ result.locked_fields.update(agent_result.locked_fields)
174
+
175
+ return result
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: claude-mpm
3
- Version: 0.3.0
3
+ Version: 1.1.0
4
4
  Summary: Claude Multi-agent Project Manager - Clean orchestration with ticket management
5
5
  Home-page: https://github.com/bobmatnyc/claude-mpm
6
6
  Author: Claude MPM Team
@@ -44,6 +44,8 @@ Dynamic: requires-python
44
44
 
45
45
  # Claude MPM - Multi-Agent Project Manager
46
46
 
47
+ > **Note**: This project is a fork of [claude-multiagent-pm](https://github.com/kfsone/claude-multiagent-pm), enhanced to integrate with [Claude Code](https://docs.anthropic.com/en/docs/claude-code) v1.0.60+'s native agent system. This integration enables seamless orchestration of Claude Code's built-in agents (research, engineer, qa, documentation, security, ops, version_control, data_engineer) through a unified project management interface.
48
+
47
49
  A framework for Claude that enables multi-agent workflows and extensible capabilities through a modular architecture.
48
50
 
49
51
 
@@ -117,17 +119,52 @@ Claude MPM provides a modular framework for extending Claude's capabilities:
117
119
 
118
120
  ## Installation
119
121
 
120
- ### From Source
122
+ ### Quick Install Options
123
+
124
+ #### Option 1: Using UV (Recommended - Fast)
125
+ UV is a lightning-fast Python package manager written in Rust, offering 10-100x speed improvements over pip.
126
+
127
+ ```bash
128
+ # Install UV (if not already installed)
129
+ curl -LsSf https://astral.sh/uv/install.sh | sh
130
+
131
+ # Install claude-mpm with UV
132
+ uv pip install claude-mpm
133
+
134
+ # Or install from git
135
+ uv pip install git+https://github.com/bobmatnyc/claude-mpm.git
136
+ ```
137
+
138
+ #### Option 2: Using pip (Traditional)
139
+ ```bash
140
+ # Install from PyPI
141
+ pip install claude-mpm
142
+
143
+ # Or install from git
144
+ pip install git+https://github.com/bobmatnyc/claude-mpm.git
145
+ ```
146
+
147
+ #### Option 3: Using npm (Wrapper)
148
+ **Note**: This installs a wrapper that still requires Python. It's provided for convenience but the Python package is the primary distribution method.
149
+
150
+ ```bash
151
+ npm install -g @bobmatnyc/claude-mpm
152
+ ```
153
+
154
+ ### From Source (Development)
121
155
 
122
156
  ```bash
123
157
  # Clone the repository
124
- git clone https://github.com/yourusername/claude-mpm.git
158
+ git clone https://github.com/bobmatnyc/claude-mpm.git
125
159
  cd claude-mpm
126
160
 
127
- # Run development installation script
128
- ./install_dev.sh
161
+ # Option A: Using UV (Recommended - Much faster)
162
+ uv venv
163
+ source venv/bin/activate # On Windows: venv\Scripts\activate
164
+ uv pip install -e .
129
165
 
130
- # Activate virtual environment
166
+ # Option B: Traditional approach
167
+ ./install_dev.sh
131
168
  source venv/bin/activate
132
169
  ```
133
170
 
@@ -135,7 +172,7 @@ source venv/bin/activate
135
172
 
136
173
  #### Core Requirements
137
174
  - Python 3.8+
138
- - Claude CLI (must be installed and in PATH)
175
+ - Claude Code CLI 1.0.60+ (must be installed and in PATH)
139
176
 
140
177
  #### Automatically Installed
141
178
  - tree-sitter & language packs (for code analysis)