claude-mpm 1.0.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 (38) hide show
  1. claude_mpm/_version.py +3 -2
  2. claude_mpm/agents/__init__.py +2 -2
  3. claude_mpm/agents/agent-template.yaml +83 -0
  4. claude_mpm/agents/agent_loader.py +66 -90
  5. claude_mpm/agents/base_agent_loader.py +10 -15
  6. claude_mpm/cli.py +41 -47
  7. claude_mpm/cli_enhancements.py +297 -0
  8. claude_mpm/core/factories.py +1 -46
  9. claude_mpm/core/service_registry.py +0 -8
  10. claude_mpm/core/simple_runner.py +43 -0
  11. claude_mpm/generators/__init__.py +5 -0
  12. claude_mpm/generators/agent_profile_generator.py +137 -0
  13. claude_mpm/hooks/README.md +75 -221
  14. claude_mpm/hooks/builtin/mpm_command_hook.py +125 -0
  15. claude_mpm/hooks/claude_hooks/__init__.py +5 -0
  16. claude_mpm/hooks/claude_hooks/hook_handler.py +399 -0
  17. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +47 -0
  18. claude_mpm/hooks/validation_hooks.py +181 -0
  19. claude_mpm/services/agent_management_service.py +4 -4
  20. claude_mpm/services/agent_profile_loader.py +1 -1
  21. claude_mpm/services/agent_registry.py +0 -1
  22. claude_mpm/services/base_agent_manager.py +3 -3
  23. claude_mpm/utils/error_handler.py +247 -0
  24. claude_mpm/validation/__init__.py +5 -0
  25. claude_mpm/validation/agent_validator.py +175 -0
  26. {claude_mpm-1.0.0.dist-info → claude_mpm-1.1.0.dist-info}/METADATA +44 -7
  27. {claude_mpm-1.0.0.dist-info → claude_mpm-1.1.0.dist-info}/RECORD +30 -26
  28. claude_mpm/config/hook_config.py +0 -42
  29. claude_mpm/hooks/hook_client.py +0 -264
  30. claude_mpm/hooks/hook_runner.py +0 -370
  31. claude_mpm/hooks/json_rpc_executor.py +0 -259
  32. claude_mpm/hooks/json_rpc_hook_client.py +0 -319
  33. claude_mpm/services/hook_service.py +0 -388
  34. claude_mpm/services/hook_service_manager.py +0 -223
  35. claude_mpm/services/json_rpc_hook_manager.py +0 -92
  36. {claude_mpm-1.0.0.dist-info → claude_mpm-1.1.0.dist-info}/WHEEL +0 -0
  37. {claude_mpm-1.0.0.dist-info → claude_mpm-1.1.0.dist-info}/entry_points.txt +0 -0
  38. {claude_mpm-1.0.0.dist-info → claude_mpm-1.1.0.dist-info}/top_level.txt +0 -0
@@ -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: 1.0.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)
@@ -1,18 +1,20 @@
1
1
  claude_mpm/__init__.py,sha256=sAbTZkHe3vWYAKDWdGyGVue5zwLD7nCOHZwZrLALM8A,395
2
2
  claude_mpm/__main__.py,sha256=smBw-5J3nf5s6GgQjj384GUr28YotIX-WNOxqpP0wnE,310
3
- claude_mpm/_version.py,sha256=n7VdPKEcovT2OwODlqBHlbkfj1OEIRsPXhFaCt3nRss,1206
4
- claude_mpm/cli.py,sha256=jQ9w3AqIF_6XHJk4D4NWL5Fo0jNS0wpmfekNlzudSSg,23666
3
+ claude_mpm/_version.py,sha256=8qIojoNf3eo5aQN6bVE2XdbA0APnkFaY0ifCYobPc8k,1307
4
+ claude_mpm/cli.py,sha256=EgzmFR-6njXedJUtMrWY0o-QAezsY3fc8uObehDDPMw,23164
5
+ claude_mpm/cli_enhancements.py,sha256=nwdOrbXITRqvcq_vrJtPKW1GDS7dLIG4UqjoUet2vR0,10890
5
6
  claude_mpm/cli_main.py,sha256=KCAe-ws73NrIg5qmFhPdZ1a4uoiaEZ-lldYzQ6KfnJg,306
6
7
  claude_mpm/constants.py,sha256=5AG5hgBxOC7gMNHDx0lAhS-FQ8gXhtGtqJ9Moj3S6ro,4044
7
8
  claude_mpm/init.py,sha256=gOreOf7BLXkT0_HrQk_As4Kz1OT_NJG_RG0i0hbY0z0,8088
8
9
  claude_mpm/agents/BASE_AGENT_TEMPLATE.md,sha256=TYgSd9jNBMWp4mAOBUl9dconX4RcGbvmMEScRy5uyko,3343
9
10
  claude_mpm/agents/INSTRUCTIONS.md,sha256=FuLq0cBjUjqByA9rdi1H_3SCt8xSjsTWM_VvnIQz2fg,16578
10
- claude_mpm/agents/__init__.py,sha256=DxJswRx5DpgJVZEY5JlZm5VJNb_CakV5Ch231r7nWlo,3292
11
- claude_mpm/agents/agent_loader.py,sha256=RAAoIxM9DONMMIqyEhaU0nEiaZKYkEZpMP6humOBmU0,23669
11
+ claude_mpm/agents/__init__.py,sha256=r-p7ervzjLPD7_8dm2tXX_fwvdTZy6KwKA03ofxN3sA,3275
12
+ claude_mpm/agents/agent-template.yaml,sha256=koKJn8MCAJx0QNQMHouvIZrwvw5qjPV0U-aV-YVyk6s,2036
13
+ claude_mpm/agents/agent_loader.py,sha256=jl7VSdyNQGNfLxIVJ0m0Fm8daEpSeUxgNCpy2asFEkA,22487
12
14
  claude_mpm/agents/agent_loader_integration.py,sha256=z_DXxAIeuUD71HBYdxxvcFKoQYQxITLo8oAdN_M4LTA,7610
13
15
  claude_mpm/agents/agents_metadata.py,sha256=Xju9Yim6XSv2u1J_Swre5VJySbdxxC-9TzpOfXG8ibg,5170
14
16
  claude_mpm/agents/base_agent.json,sha256=P4724UbQJQlZy57WkwIz_f_R86JepljWpTflI9hLrUs,2296
15
- claude_mpm/agents/base_agent_loader.py,sha256=gVWXfxFh3_Z5FJ77SWbxrA8yFOQ8IwwfnOgmv6Z89CQ,18680
17
+ claude_mpm/agents/base_agent_loader.py,sha256=DJ0BDP_7ic3q0Zv5YQFZCYZp2V3bC3bB1v11ohbN8yU,18418
16
18
  claude_mpm/agents/system_agent_config.py,sha256=Lke4FFjU0Vq3LLo4O7KvtHxadP7agAwC-ljCXK40h_A,23526
17
19
  claude_mpm/agents/schema/agent_schema.json,sha256=Ca_8E0QkFpGwQd7XjVy3jnBMv_-Yo2rL7Po-ziHut2U,5472
18
20
  claude_mpm/agents/templates/__init__.py,sha256=7UyIChghCnkrDctvmCRYr0Wrnn8Oj-eCdgL0KpFy1Mo,2668
@@ -34,7 +36,6 @@ claude_mpm/cli_module/refactoring_guide.md,sha256=fl1PGwLZAj4OYWmU0syg1jDd81PqK7
34
36
  claude_mpm/cli_old/__init__.py,sha256=v7mFJSN0p6NOIcURZp5ibZaZBn6iGrLwyGl7tA_lh4c,32
35
37
  claude_mpm/cli_old/ticket_cli.py,sha256=oKIT2LR1tToHybwypRfsNdnYlwdRzjWyjlQN5lYwTOk,3795
36
38
  claude_mpm/config/__init__.py,sha256=p31JuaXLDHgIgoAbHApNvctN2IEZYq2MBkkXROdhbH8,105
37
- claude_mpm/config/hook_config.py,sha256=ehVAVHhn6ZBxrdWXqXB2M8jcAmqaWCnE9gVxuxR2UEs,1334
38
39
  claude_mpm/core/__init__.py,sha256=hE29BeE3qb8vC1-wiKjPh60WZebCwfo9UAUGM1zQnkc,1206
39
40
  claude_mpm/core/agent_name_normalizer.py,sha256=-X68oz3_74t9BRbHA54NEGyjy0xjTsGp_sCUHDtKp1s,9269
40
41
  claude_mpm/core/agent_registry.py,sha256=4MAfc7xDlrYWWkHmDMRmWE8q32teuCmIcud9D0I0dLo,20496
@@ -45,33 +46,36 @@ claude_mpm/core/base_service.py.bak,sha256=48A8eI_HPqxYm42X5jaTo8zQVOfFFXe7SqIUo
45
46
  claude_mpm/core/config.py,sha256=QNPufRWzXl99wAz14Gm2T_CG5K5n8d4eOjmpaxVllv0,12371
46
47
  claude_mpm/core/config_aliases.py,sha256=8eqA4wpWViIDm_9pL3f9j7cR_ssmhOYYiY2UzHrfUzg,10058
47
48
  claude_mpm/core/container.py,sha256=P4c4nSo_USSfHTxvpR1sQkVGNsgqozZBN27l3IXqiDc,12216
48
- claude_mpm/core/factories.py,sha256=ucS_t4mvLjyfQJ2FzMRemHJqKGqb_iTPe6HJ8x-ztOQ,9092
49
+ claude_mpm/core/factories.py,sha256=Qh2n_x112ZIPWEfwFley9bb9IZcSG38LkpT3uValyDk,7484
49
50
  claude_mpm/core/framework_loader.py,sha256=SdONNh8a7vSicr4vVuRzd7OqgDMIyg9k_xxbr8bLRi8,19547
50
51
  claude_mpm/core/injectable_service.py,sha256=7fOny9c6x8IJ9hVZmFql1eNDXXB1jcWbsxfTKbMZk74,7497
51
52
  claude_mpm/core/interfaces.py,sha256=TpP474EKEng-1TrjKUsN69qq6dXy8zIjicS7iV-ZPV0,15269
52
53
  claude_mpm/core/logger.py,sha256=wqYlUy8wlSXyTWOeWCGNYaIWdiFYzT7yw1U0vdT3R_8,15894
53
54
  claude_mpm/core/minimal_framework_loader.py,sha256=liYS4IyuW_aFK7yhRDZwTwT-3q09fT3wIJSUzkI93Ko,3673
54
55
  claude_mpm/core/mixins.py,sha256=rTEH-7FDpNiLB8oo6mSb0CLarJklv4fDJw1xM-gr5wI,5599
55
- claude_mpm/core/service_registry.py,sha256=rRJDidqVU3DmGRuEWcb3-hhK2gxVe7MCFDPNOh7XlbY,10790
56
+ claude_mpm/core/service_registry.py,sha256=wKJUO1g4UFA4dUpE3RkIYz1Ek8kIh4XfvU1kFeLCl2Q,10529
56
57
  claude_mpm/core/session_manager.py,sha256=3rO4KGZp8Qd_cUw6OWv4jyxGCUaL_MNPgCCpnwQt12A,6581
57
- claude_mpm/core/simple_runner.py,sha256=cEaA5fzU8itTIcEF6Zy84S5ZBgKkkAd7IqPEC0YiP64,20914
58
+ claude_mpm/core/simple_runner.py,sha256=WdgPz7qMhb9ApGNK3HnM-p4CAdvzvPGPdXsdLxp4xWQ,22473
58
59
  claude_mpm/core/tool_access_control.py,sha256=htZbDhC8s7D7BVqfmk0BwRrYJnlnUAk8_NeJKOaeNlg,6632
59
- claude_mpm/hooks/README.md,sha256=lsvGzw9g8Lf0VfRcqoGNGpAZEQSmpE0C8DksZ4nvDso,8030
60
+ claude_mpm/generators/__init__.py,sha256=l53aBn6kBQSDz3b6bZkMCJBcEmYnV9hHEZq8LKzXgH8,152
61
+ claude_mpm/generators/agent_profile_generator.py,sha256=2HjOscogSyvrtQj8KwdgNPS6Ym_QvgX1BMeauQZewZA,5751
62
+ claude_mpm/hooks/README.md,sha256=AjW-V7WQGf9o5X9otNl5k8rtal_MdyToFqVx_pudOXs,3289
60
63
  claude_mpm/hooks/__init__.py,sha256=Y3JJ_mEtvRP07r_gXkju4c0s18bjIXGH1uAbhSw1ES0,166
61
64
  claude_mpm/hooks/base_hook.py,sha256=a4V2EKEG02QQB0h-pnxhZI-fouKBLYbdBLckcaNuf0k,5098
62
- claude_mpm/hooks/hook_client.py,sha256=XxVIgV3L4RBV9YdfBHnm3oxfd8oZjFC4NYlVAbT5Lbk,8893
63
- claude_mpm/hooks/hook_runner.py,sha256=5cwo7SXRx4qr08JcYY4pbDktzBgJYgRZ624r8veGEgw,12800
64
- claude_mpm/hooks/json_rpc_executor.py,sha256=7D-jU_w1Gt1nV0kx5Rva_hleOPc92LtqZiX99j1MXjY,9091
65
- claude_mpm/hooks/json_rpc_hook_client.py,sha256=VZoTyKKIW0lfb5tZ5E3P_WlqBg6y9gzRG-ydZcomau0,11923
66
65
  claude_mpm/hooks/tool_call_interceptor.py,sha256=08_Odgm6Sg1zBJhGjwzVa03AReeBPZHTjndyjEO99cY,7629
66
+ claude_mpm/hooks/validation_hooks.py,sha256=7TU2N4SzCm2nwpsR0xiNKsHQNsWODnOVAmK9jHq1QqM,6582
67
67
  claude_mpm/hooks/builtin/__init__.py,sha256=Tfh3dIGxlQRUKBzR_MWC64WAKJ0Q_POsVVFl7lz9CD4,36
68
68
  claude_mpm/hooks/builtin/logging_hook_example.py,sha256=SyfdAH9ENTIpMhw2IeqqZpXNBUakYDI1yF5DFS0RJZ4,4971
69
+ claude_mpm/hooks/builtin/mpm_command_hook.py,sha256=PhQl1FifaB61gRrBOIXAim0R-XUBIzZwLdjb6WQuEGQ,4541
69
70
  claude_mpm/hooks/builtin/post_delegation_hook_example.py,sha256=54OJKRgjdXH8A2LHypbXoMlCNlmWXBY5Fvk0-VWq_fI,4596
70
71
  claude_mpm/hooks/builtin/pre_delegation_hook_example.py,sha256=JOAdDm46be_ol7uSmnQaE0jQS8SsiuGei80Auj3sdL8,4692
71
72
  claude_mpm/hooks/builtin/submit_hook_example.py,sha256=x7-yIF_QYe9uwCezeVDA_HdDTLu6uQfbTgZ12pdC4xo,3431
72
73
  claude_mpm/hooks/builtin/ticket_extraction_hook_example.py,sha256=4wNhS2tFUXgdcvepefUvi818Tt8kKnPQQJVxqINGeys,9237
73
74
  claude_mpm/hooks/builtin/todo_agent_prefix_hook.py,sha256=v_4w2vcZIt0bkZxqdHmgtN79yHZ1gviuhhBws0FHpIQ,10226
74
75
  claude_mpm/hooks/builtin/workflow_start_hook.py,sha256=EQrtYD9qLMLSYPl3oQinEheZAJ2i5EO_h2jhhR8lmt0,7490
76
+ claude_mpm/hooks/claude_hooks/__init__.py,sha256=bMUwt2RzDGAcEbtDMA7vWS1uJsauOY0OixIe4pHwgQ0,129
77
+ claude_mpm/hooks/claude_hooks/hook_handler.py,sha256=30YDU6hVoju-vDyhP9HdhdGo5NJ8g4reJiQokLjvSKk,16154
78
+ claude_mpm/hooks/claude_hooks/hook_wrapper.sh,sha256=6n0-G317jIrPuNRGnAyFvBbNM4gVzKEat_WSbpvKN-g,1742
75
79
  claude_mpm/orchestration/SUBPROCESS_DESIGN.md,sha256=YwToiT1_NXblv1XIWhWPNc2uKzDvqY2E_Nix8qK7qk0,2136
76
80
  claude_mpm/orchestration/__init__.py,sha256=C-cwldtfBCgV19mKnJa5U1XiKw1rAZvx-kK61nIdcao,205
77
81
  claude_mpm/orchestration/archive/direct_orchestrator.py,sha256=j-IP-st-Xi9Xf33i-BLPZOE_kkxSZxNNuFZmp6MTuZY,7884
@@ -91,16 +95,13 @@ claude_mpm/scripts/ticket.py,sha256=GmFimtTJxc927cCzJvvJH3gvoxXQtAB-W-xnuclcvNs,
91
95
  claude_mpm/services/__init__.py,sha256=-EBm07Lh9mjcofiQHCqyCCQJMLi9akVArPlz8i_kEOo,226
92
96
  claude_mpm/services/agent_deployment.py,sha256=FqxKBaTl2vQqsxN7QZPKIeLmhO-f8VW6maRBmAUNW50,40398
93
97
  claude_mpm/services/agent_lifecycle_manager.py,sha256=VZBVONepomFpMqL7soaXIawS4NoaltFWKed7tU6bS3w,39057
94
- claude_mpm/services/agent_management_service.py,sha256=aotSxiLzRW1VKPGkanFt7hzyPfxLf8LVE6o1EA7X2BY,22875
98
+ claude_mpm/services/agent_management_service.py,sha256=eX5n6w17b9urcogVdr4V-kXcuo7yyjORTrIihjF8PeQ,22853
95
99
  claude_mpm/services/agent_modification_tracker.py,sha256=7FRDXuCNANUnLatCgtBArG-AxZNtKbGQjgCKjnzmJ80,34050
96
- claude_mpm/services/agent_profile_loader.py,sha256=PMcFbK-acIMleB7xoZMMoDX8xq1a2_PdmZ9-R2V41Cw,23148
97
- claude_mpm/services/agent_registry.py,sha256=X8f6ATNtftZBSR9AaTIZenLyRVAegA3PZ9tGoqpS0uw,24446
98
- claude_mpm/services/base_agent_manager.py,sha256=2u3efvWyw_Ki9l7z81eVGwyPpG__j2etRMQUhvOTpAw,15016
100
+ claude_mpm/services/agent_profile_loader.py,sha256=4D1Xj0vgqV8wN7Y3r8lijh7ghy5cVGU5t5s931sVqGc,23133
101
+ claude_mpm/services/agent_registry.py,sha256=vn8CEW0vppj_0EY2NofmNRZEnpV70mlWiX2kAViFDRg,24374
102
+ claude_mpm/services/base_agent_manager.py,sha256=WEcfzdMaFXmXUSoEYEPNeGu8dvqjIv53zyUU0ITrhsM,14987
99
103
  claude_mpm/services/framework_agent_loader.py,sha256=QdRSYRurYF3YbAXJwIGei71BffD5AqOVcV3ktRPdk7g,14018
100
104
  claude_mpm/services/framework_claude_md_generator.py,sha256=3kHmkRLHTex6HFZ4DhbLVQb48j-5dAoy1q6UW1Qf7U8,22914
101
- claude_mpm/services/hook_service.py,sha256=8CMyvlSK_QvZtJqU3rAv3nST3KJLYhe6nTGdEi51mWE,13619
102
- claude_mpm/services/hook_service_manager.py,sha256=QtDwMdC3PAjoO6oZ3Re3FRPoyHujYnNF4akM4eqlM5U,8523
103
- claude_mpm/services/json_rpc_hook_manager.py,sha256=fd8YN460pVv4aI8vCFFsWMXJ2opYphXitCUkLBaqPL8,2981
104
105
  claude_mpm/services/shared_prompt_cache.py,sha256=D04lrRWyg0lHyqGcAHy7IYvRHRKSg6EOpAJwBUPa2wk,29890
105
106
  claude_mpm/services/ticket_manager.py,sha256=Ki11YjBkDax8BFVSaDdOBk3K4VU5gvdbgq9AmCyyoZ0,7454
106
107
  claude_mpm/services/ticket_manager_di.py,sha256=pIsIGncbboKzBYSRQTO7ZX5MuQzV6iFfIflvKe6u1jw,11123
@@ -148,12 +149,15 @@ claude_mpm/ui/rich_terminal_ui.py,sha256=gx_9TD0kR4Exq867pHjVVs_b-gw1q267t5oA2ZD
148
149
  claude_mpm/ui/terminal_ui.py,sha256=E_M-L-6EuGp6L8pRpaWEhTqf-ddDXhZp5W85D0XNRPw,11928
149
150
  claude_mpm/utils/__init__.py,sha256=E8Hvv6ykL6rnnc8-YmfoGNpRCZbcIirxcFuNz7YvDIg,346
150
151
  claude_mpm/utils/config_manager.py,sha256=TlekZYIWOz_ouWHQU4Gc-zckhoFK9AqA25b6A_XZdDc,16412
152
+ claude_mpm/utils/error_handler.py,sha256=W_Zc0FrKudpXvxT66Oxx0v8WkR8HA2KlynzzGy3eGcU,8168
151
153
  claude_mpm/utils/import_migration_example.py,sha256=W4a4XH3FY_VBB00BB8Lae2aRPM021PxLHzdUfEs0B5w,2463
152
154
  claude_mpm/utils/imports.py,sha256=wX-SOXUHbemx01MHRGQpVwajzXH6qYdQkYNFCIbb2mw,6851
153
155
  claude_mpm/utils/path_operations.py,sha256=6pLMnAWBVzHkgp6JyQHmHbGD-dWn-nX21yV4E_eT-kM,11614
154
156
  claude_mpm/utils/paths.py,sha256=Xv0SZWdZRkRjN9e6clBcA165ya00GNQxt7SwMz51tfA,10153
155
- claude_mpm-1.0.0.dist-info/METADATA,sha256=s8VhjuHma1JWq9S1G6iq7eNfxD6__qDFbCF6aqZOw4c,8792
156
- claude_mpm-1.0.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
157
- claude_mpm-1.0.0.dist-info/entry_points.txt,sha256=PknO31um7d8bt6GjOiVeYpdJpjND0_C1z-LQfY6UfiU,142
158
- claude_mpm-1.0.0.dist-info/top_level.txt,sha256=1nUg3FEaBySgm8t-s54jK5zoPnu3_eY6EP6IOlekyHA,11
159
- claude_mpm-1.0.0.dist-info/RECORD,,
157
+ claude_mpm/validation/__init__.py,sha256=bJ19g9lnk7yIjtxzN8XPegp87HTFBzCrGQOpFgRTf3g,155
158
+ claude_mpm/validation/agent_validator.py,sha256=6Ry2ogyh9-nNlGT6NyK-HIN7-YvKEGJCU-8XT5QdJ4Y,6921
159
+ claude_mpm-1.1.0.dist-info/METADATA,sha256=xkVOC-NAOLEt2M5EVJhQabxT_dC5pPQC3wak-LS9PS0,10207
160
+ claude_mpm-1.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
161
+ claude_mpm-1.1.0.dist-info/entry_points.txt,sha256=PknO31um7d8bt6GjOiVeYpdJpjND0_C1z-LQfY6UfiU,142
162
+ claude_mpm-1.1.0.dist-info/top_level.txt,sha256=1nUg3FEaBySgm8t-s54jK5zoPnu3_eY6EP6IOlekyHA,11
163
+ claude_mpm-1.1.0.dist-info/RECORD,,