claude-mpm 2.0.0__py3-none-any.whl → 2.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.
@@ -0,0 +1,222 @@
1
+ """Deployed Agent Discovery Service.
2
+
3
+ This service discovers and analyzes deployed agents in the project,
4
+ handling both new standardized schema and legacy agent formats.
5
+ """
6
+
7
+ from pathlib import Path
8
+ from typing import List, Dict, Any
9
+ import logging
10
+ import json
11
+
12
+ from claude_mpm.core.agent_registry import AgentRegistryAdapter
13
+ from claude_mpm.utils.paths import PathResolver
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+
18
+ class DeployedAgentDiscovery:
19
+ """Discovers and analyzes deployed agents in the project."""
20
+
21
+ def __init__(self, project_root: Path = None):
22
+ """Initialize the discovery service.
23
+
24
+ Args:
25
+ project_root: Project root path. Defaults to auto-detected root.
26
+ """
27
+ self.project_root = project_root or PathResolver.get_project_root()
28
+ self.agent_registry = AgentRegistryAdapter()
29
+ logger.debug(f"Initialized DeployedAgentDiscovery with root: {self.project_root}")
30
+
31
+ def discover_deployed_agents(self) -> List[Dict[str, Any]]:
32
+ """Discover all deployed agents following hierarchy precedence.
33
+
34
+ Returns:
35
+ List of agent information dictionaries with standardized fields.
36
+ """
37
+ try:
38
+ # Get effective agents (respects project > user > system precedence)
39
+ agents = self.agent_registry.list_agents()
40
+ logger.info(f"Discovered {len(agents)} agents from registry")
41
+
42
+ # Handle both dict and list formats
43
+ if isinstance(agents, dict):
44
+ agent_list = list(agents.values())
45
+ else:
46
+ agent_list = list(agents)
47
+
48
+ deployed_agents = []
49
+ for agent in agent_list:
50
+ try:
51
+ agent_info = self._extract_agent_info(agent)
52
+ if agent_info and self._is_valid_agent(agent_info):
53
+ deployed_agents.append(agent_info)
54
+ logger.debug(f"Extracted info for agent: {agent_info['id']}")
55
+ except Exception as e:
56
+ logger.error(f"Failed to extract info from agent {agent}: {e}")
57
+ continue
58
+
59
+ logger.info(f"Successfully extracted info for {len(deployed_agents)} agents")
60
+ return deployed_agents
61
+
62
+ except Exception as e:
63
+ logger.error(f"Failed to discover deployed agents: {e}")
64
+ # Return empty list on failure to allow graceful degradation
65
+ return []
66
+
67
+ def _extract_agent_info(self, agent) -> Dict[str, Any]:
68
+ """Extract relevant information from agent definition.
69
+
70
+ Args:
71
+ agent: Agent object from registry (can be dict or object)
72
+
73
+ Returns:
74
+ Dictionary with standardized agent information
75
+ """
76
+ try:
77
+ # Handle dictionary format (current format from registry)
78
+ if isinstance(agent, dict):
79
+ # If we have a path, try to load full agent data from JSON
80
+ agent_path = agent.get('path')
81
+ if agent_path and agent_path.endswith('.json'):
82
+ full_data = self._load_full_agent_data(agent_path)
83
+ if full_data:
84
+ return self._extract_from_json_data(full_data, agent)
85
+
86
+ # Otherwise use basic info from registry
87
+ return {
88
+ 'id': agent.get('type', agent.get('name', 'unknown')),
89
+ 'name': agent.get('name', 'Unknown'),
90
+ 'description': agent.get('description', 'No description available'),
91
+ 'specializations': agent.get('specializations', []),
92
+ 'capabilities': agent.get('capabilities', {}),
93
+ 'source_tier': agent.get('tier', 'system'),
94
+ 'tools': agent.get('tools', [])
95
+ }
96
+ # Handle object format with metadata (new standardized schema)
97
+ elif hasattr(agent, 'metadata'):
98
+ return {
99
+ 'id': agent.agent_id,
100
+ 'name': agent.metadata.name,
101
+ 'description': agent.metadata.description,
102
+ 'specializations': agent.metadata.specializations,
103
+ 'capabilities': getattr(agent, 'capabilities', {}),
104
+ 'source_tier': self._determine_source_tier(agent),
105
+ 'tools': getattr(agent.configuration, 'tools', []) if hasattr(agent, 'configuration') else []
106
+ }
107
+ else:
108
+ # Legacy object format fallback
109
+ agent_type = getattr(agent, 'type', None)
110
+ agent_name = getattr(agent, 'name', None)
111
+
112
+ # Generate name from type if name not present
113
+ if not agent_name and agent_type:
114
+ agent_name = agent_type.replace('_', ' ').title()
115
+ elif not agent_name:
116
+ agent_name = 'Unknown Agent'
117
+
118
+ return {
119
+ 'id': getattr(agent, 'agent_id', agent_type or 'unknown'),
120
+ 'name': agent_name,
121
+ 'description': getattr(agent, 'description', 'No description available'),
122
+ 'specializations': getattr(agent, 'specializations', []),
123
+ 'capabilities': {},
124
+ 'source_tier': self._determine_source_tier(agent),
125
+ 'tools': getattr(agent, 'tools', [])
126
+ }
127
+ except Exception as e:
128
+ logger.error(f"Error extracting agent info: {e}")
129
+ return None
130
+
131
+ def _load_full_agent_data(self, agent_path: str) -> Dict[str, Any]:
132
+ """Load full agent data from JSON file.
133
+
134
+ Args:
135
+ agent_path: Path to agent JSON file
136
+
137
+ Returns:
138
+ Full agent data dictionary or None if loading fails
139
+ """
140
+ try:
141
+ path = Path(agent_path)
142
+ if path.exists() and path.suffix == '.json':
143
+ with open(path, 'r') as f:
144
+ return json.load(f)
145
+ except Exception as e:
146
+ logger.warning(f"Failed to load full agent data from {agent_path}: {e}")
147
+ return None
148
+
149
+ def _extract_from_json_data(self, json_data: Dict[str, Any], registry_info: Dict[str, Any]) -> Dict[str, Any]:
150
+ """Extract agent info from full JSON data.
151
+
152
+ Args:
153
+ json_data: Full agent JSON data
154
+ registry_info: Basic info from registry
155
+
156
+ Returns:
157
+ Extracted agent information
158
+ """
159
+ # Extract metadata
160
+ metadata = json_data.get('metadata', {})
161
+ capabilities = json_data.get('capabilities', {})
162
+ configuration = json_data.get('configuration', {})
163
+
164
+ return {
165
+ 'id': json_data.get('agent_type', registry_info.get('type', 'unknown')),
166
+ 'name': metadata.get('name', registry_info.get('name', 'Unknown')),
167
+ 'description': metadata.get('description', registry_info.get('description', 'No description available')),
168
+ 'specializations': metadata.get('specializations', registry_info.get('specializations', [])),
169
+ 'capabilities': capabilities,
170
+ 'source_tier': registry_info.get('tier', 'system'),
171
+ 'tools': configuration.get('tools', [])
172
+ }
173
+
174
+ def _determine_source_tier(self, agent) -> str:
175
+ """Determine if agent comes from project, user, or system tier.
176
+
177
+ Args:
178
+ agent: Agent object from registry (can be dict or object)
179
+
180
+ Returns:
181
+ Source tier string: 'project', 'user', or 'system'
182
+ """
183
+ # Handle dictionary format
184
+ if isinstance(agent, dict):
185
+ return agent.get('tier', 'system')
186
+
187
+ # First check if agent has explicit source_tier attribute
188
+ if hasattr(agent, 'source_tier'):
189
+ return agent.source_tier
190
+
191
+ # Try to determine from file path if available
192
+ if hasattr(agent, 'source_path'):
193
+ source_path = str(agent.source_path)
194
+ if '.claude/agents' in source_path:
195
+ return 'project'
196
+ elif str(Path.home()) in source_path:
197
+ return 'user'
198
+
199
+ # Default to system tier
200
+ return 'system'
201
+
202
+ def _is_valid_agent(self, agent_info: Dict[str, Any]) -> bool:
203
+ """Check if agent is a valid deployable agent (not a template).
204
+
205
+ Args:
206
+ agent_info: Extracted agent information
207
+
208
+ Returns:
209
+ True if agent is valid, False if it's a template or invalid
210
+ """
211
+ # Filter out known templates and non-agent files
212
+ invalid_names = ['BASE_AGENT_TEMPLATE', 'INSTRUCTIONS', 'base_agent', 'template']
213
+
214
+ agent_id = agent_info.get('id', '').upper()
215
+ agent_name = agent_info.get('name', '').upper()
216
+
217
+ for invalid in invalid_names:
218
+ if invalid.upper() in agent_id or invalid.upper() in agent_name:
219
+ logger.debug(f"Filtering out template/invalid agent: {agent_info['id']}")
220
+ return False
221
+
222
+ return True
@@ -8,6 +8,12 @@ import hashlib
8
8
  from datetime import datetime
9
9
  from typing import Dict, List, Optional, Any
10
10
  from collections import OrderedDict
11
+ import logging
12
+
13
+ from claude_mpm.services.deployed_agent_discovery import DeployedAgentDiscovery
14
+ from claude_mpm.services.agent_capabilities_generator import AgentCapabilitiesGenerator
15
+
16
+ logger = logging.getLogger(__name__)
11
17
 
12
18
 
13
19
  class ContentAssembler:
@@ -16,6 +22,9 @@ class ContentAssembler:
16
22
  def __init__(self):
17
23
  """Initialize content assembler."""
18
24
  self.template_variables = {}
25
+ self.agent_discovery = DeployedAgentDiscovery()
26
+ self.capabilities_generator = AgentCapabilitiesGenerator()
27
+ logger.debug("Initialized ContentAssembler with dynamic agent capabilities support")
19
28
 
20
29
  def generate_content_hash(self) -> str:
21
30
  """
@@ -63,12 +72,32 @@ class ContentAssembler:
63
72
  """
64
73
  Apply template variable substitution to content.
65
74
 
75
+ WHY: Enhanced to support dynamic agent capabilities generation.
76
+ - Generates fresh agent capabilities on each call
77
+ - Provides graceful fallback if generation fails
78
+ - Ensures INSTRUCTIONS.md always reflects current deployed agents
79
+
66
80
  Args:
67
81
  content: Content with template variables
68
82
 
69
83
  Returns:
70
84
  str: Content with variables substituted
71
85
  """
86
+ # Check if we need to generate dynamic capabilities
87
+ if "{{capabilities-list}}" in content:
88
+ try:
89
+ # Discover deployed agents
90
+ deployed_agents = self.agent_discovery.discover_deployed_agents()
91
+ # Generate capabilities content
92
+ capabilities_content = self.capabilities_generator.generate_capabilities_section(deployed_agents)
93
+ # Add to template variables
94
+ self.template_variables['capabilities-list'] = capabilities_content
95
+ logger.info(f"Generated dynamic capabilities for {len(deployed_agents)} agents")
96
+ except Exception as e:
97
+ logger.error(f"Failed to generate dynamic capabilities: {e}")
98
+ # Fallback is handled by the generator's internal fallback mechanism
99
+
100
+ # Apply all template variables
72
101
  for var_name, var_value in self.template_variables.items():
73
102
  placeholder = f"{{{{{var_name}}}}}"
74
103
  content = content.replace(placeholder, var_value)
@@ -35,6 +35,11 @@ class DeploymentManager:
35
35
  """
36
36
  Deploy generated content to a parent directory.
37
37
 
38
+ WHY: Enhanced to ensure fresh agent capabilities generation on each deployment.
39
+ - Checks for template variables that need processing
40
+ - Re-processes content to get current deployed agents
41
+ - Ensures INSTRUCTIONS.md always reflects latest agent configuration
42
+
38
43
  Args:
39
44
  content: Content to deploy
40
45
  parent_path: Path to parent directory
@@ -52,16 +57,33 @@ class DeploymentManager:
52
57
  target_file = parent_path / "INSTRUCTIONS.md"
53
58
  # TODO: Make this configurable via parameter
54
59
 
60
+ # Check if content contains template variables that need processing
61
+ if '{{capabilities-list}}' in content:
62
+ # Content needs processing - let ContentAssembler handle it
63
+ from .content_assembler import ContentAssembler
64
+ assembler = ContentAssembler()
65
+
66
+ # Re-process content to get fresh agent data
67
+ # Pass content as a single section to preserve structure
68
+ processed_content = assembler.apply_template_variables(content)
69
+ content = processed_content
70
+
55
71
  # Validate content before deployment
56
- is_valid, issues = self.validator.validate_content(content)
57
- if not is_valid:
58
- return False, f"Validation failed: {'; '.join(issues)}"
72
+ # Skip validation for INSTRUCTIONS.md format (different from CLAUDE.md)
73
+ if "<!-- FRAMEWORK_VERSION:" in content and "# Claude Multi-Agent Project Manager Instructions" in content:
74
+ # This is INSTRUCTIONS.md format, skip CLAUDE.md validation
75
+ pass
76
+ else:
77
+ # This is CLAUDE.md format, validate normally
78
+ is_valid, issues = self.validator.validate_content(content)
79
+ if not is_valid:
80
+ return False, f"Validation failed: {'; '.join(issues)}"
59
81
 
60
82
  # Check if file exists and compare versions
61
83
  if target_file.exists() and not force:
62
84
  with open(target_file, 'r') as f:
63
85
  existing_content = f.read()
64
- existing_fw_ver, _ = self.version_manager.parse_current_version(existing_content)
86
+ existing_fw_ver = self.version_manager.parse_current_version(existing_content)
65
87
 
66
88
  if existing_fw_ver == self.version_manager.framework_version:
67
89
  return True, f"Version {existing_fw_ver} already deployed"
@@ -76,8 +98,8 @@ class DeploymentManager:
76
98
  f.write(content)
77
99
 
78
100
  # Get version info for success message
79
- fw_ver, serial = self.version_manager.parse_current_version(content)
80
- version_str = f"{fw_ver}-{serial:03d}"
101
+ fw_ver = self.version_manager.parse_current_version(content)
102
+ version_str = fw_ver
81
103
 
82
104
  return True, f"Successfully deployed version {version_str}"
83
105
  except Exception as e:
@@ -101,7 +123,7 @@ class DeploymentManager:
101
123
  try:
102
124
  with open(target_file, 'r') as f:
103
125
  existing_content = f.read()
104
- existing_fw_ver, _ = self.version_manager.parse_current_version(existing_content)
126
+ existing_fw_ver = self.version_manager.parse_current_version(existing_content)
105
127
 
106
128
  if existing_fw_ver != self.version_manager.framework_version:
107
129
  return True, f"Version mismatch: {existing_fw_ver} vs {self.version_manager.framework_version}"
@@ -0,0 +1,39 @@
1
+ """Framework source directory detection utilities.
2
+
3
+ WHY: This module provides utilities to detect if we're in the framework source directory
4
+ to prevent accidental overwrites of the template files during deployment.
5
+ """
6
+
7
+ from pathlib import Path
8
+ from typing import Tuple, List
9
+
10
+
11
+ def is_framework_source_directory(path: Path) -> Tuple[bool, List[str]]:
12
+ """
13
+ Check if the given path is the framework source directory.
14
+
15
+ WHY: We need to prevent deployment to the framework source directory itself
16
+ to avoid overwriting template files.
17
+
18
+ Args:
19
+ path: Path to check
20
+
21
+ Returns:
22
+ Tuple of (is_framework_source, list of detected markers)
23
+ """
24
+ markers = []
25
+
26
+ # Check for framework source markers
27
+ if (path / "src" / "claude_mpm").exists():
28
+ markers.append("src/claude_mpm")
29
+
30
+ if (path / "pyproject.toml").exists():
31
+ markers.append("pyproject.toml")
32
+
33
+ if (path / "src" / "claude_mpm" / "agents" / "INSTRUCTIONS.md").exists():
34
+ markers.append("framework INSTRUCTIONS.md template")
35
+
36
+ # If we have multiple markers, it's likely the framework source
37
+ is_framework = len(markers) >= 2
38
+
39
+ return is_framework, markers
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: claude-mpm
3
- Version: 2.0.0
3
+ Version: 2.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
@@ -194,6 +194,7 @@ Claude MPM provides a modular framework for extending Claude's capabilities:
194
194
  - Dynamic agent discovery and registration
195
195
  - Template-based agent definitions
196
196
  - Extensible agent architecture
197
+ - **Dynamic Capabilities**: Agent documentation automatically generated from deployed agents
197
198
 
198
199
  ### Hook System
199
200
  - Pre and post-processing hooks
@@ -213,6 +214,13 @@ Claude MPM provides a modular framework for extending Claude's capabilities:
213
214
  - Organized log structure
214
215
  - Performance monitoring
215
216
 
217
+ ### Security Features
218
+ - **File System Protection**: Automatic sandboxing prevents file operations outside the working directory
219
+ - **Path Traversal Prevention**: Blocks attempts to escape the project directory using `..` or symlinks
220
+ - **Write Operation Control**: All write operations are validated while read operations remain unrestricted
221
+ - **Transparent Security**: Zero-configuration security that works automatically in the background
222
+ - **Comprehensive Logging**: All security events are logged for audit purposes
223
+
216
224
  ## Installation
217
225
 
218
226
  ### Other Installation Methods
@@ -1,13 +1,13 @@
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=Ng-R0tLTmF6GT0YoJek11nrB3KB8c3Q4YfYsQ_cKXvw,1394
4
- claude_mpm/cli.py,sha256=EgzmFR-6njXedJUtMrWY0o-QAezsY3fc8uObehDDPMw,23164
3
+ claude_mpm/_version.py,sha256=HBkjBFMyGB0Jyz0lTkWhWTEalldfBZqkqfHkyuIxBJk,159
4
+ claude_mpm/cli.py,sha256=_6tUSY0FqBN6cHR6awuXgqm2-Hlh-L508rB-RDgflPU,26036
5
5
  claude_mpm/cli_enhancements.py,sha256=nwdOrbXITRqvcq_vrJtPKW1GDS7dLIG4UqjoUet2vR0,10890
6
6
  claude_mpm/cli_main.py,sha256=KCAe-ws73NrIg5qmFhPdZ1a4uoiaEZ-lldYzQ6KfnJg,306
7
7
  claude_mpm/constants.py,sha256=5AG5hgBxOC7gMNHDx0lAhS-FQ8gXhtGtqJ9Moj3S6ro,4044
8
8
  claude_mpm/init.py,sha256=gOreOf7BLXkT0_HrQk_As4Kz1OT_NJG_RG0i0hbY0z0,8088
9
9
  claude_mpm/agents/BASE_AGENT_TEMPLATE.md,sha256=TYgSd9jNBMWp4mAOBUl9dconX4RcGbvmMEScRy5uyko,3343
10
- claude_mpm/agents/INSTRUCTIONS.md,sha256=I2Y_Aed6-E6p7gd2ujy5cyFuMIZorqFz_NbF4Y60Oz0,8013
10
+ claude_mpm/agents/INSTRUCTIONS.md,sha256=X6bOhSII3pZVZh_Vw_zMYRdfLtyl5Mmf_jhrVYfNxFs,7200
11
11
  claude_mpm/agents/__init__.py,sha256=r-p7ervzjLPD7_8dm2tXX_fwvdTZy6KwKA03ofxN3sA,3275
12
12
  claude_mpm/agents/agent-template.yaml,sha256=koKJn8MCAJx0QNQMHouvIZrwvw5qjPV0U-aV-YVyk6s,2036
13
13
  claude_mpm/agents/agent_loader.py,sha256=aZiTX8u0__8ueHzwney98PHfVMSkrpF3Nh-DoFlso74,18675
@@ -23,7 +23,7 @@ claude_mpm/agents/templates/documentation.json,sha256=W6gF0p2XpXrYPng7aUjbpE0Z3I
23
23
  claude_mpm/agents/templates/engineer.json,sha256=vRAr9sEgKt7_IVg2e3iZmLQFQHTzjgM-YQepS-TL6rY,8829
24
24
  claude_mpm/agents/templates/ops.json,sha256=mNoS_OS_e4Ht2drx3d7H0I18x38LX16E-mhsJn95ydQ,2899
25
25
  claude_mpm/agents/templates/qa.json,sha256=qEsJzkXbqM4pAdl4vyW1HeaQME5SvnIk4XttPWI2Dhw,2942
26
- claude_mpm/agents/templates/research.json,sha256=cfZlfJ9NMEUAb9BxqK_uo2bdRiMIt842jwQxolZ7YIM,6129
26
+ claude_mpm/agents/templates/research.json,sha256=nwqExnDvMVGih7RGzbwpYGBb1NbAdHRq3L03S4QtzKs,10180
27
27
  claude_mpm/agents/templates/security.json,sha256=T0hRMeHq54ryblR2QsBFBJtNx-mYR3VEtwQYOvx4EOU,2945
28
28
  claude_mpm/agents/templates/version_control.json,sha256=RsV0WLs58boDOzurwB75Zdol4uXf_Za0VHOqQ3Og2Rw,2923
29
29
  claude_mpm/agents/templates/backup/data_engineer_agent_20250726_234551.json,sha256=lLso4RHXVTQmX4A1XwF84kT59zZDblPO1xCgBj4S4x8,5060
@@ -62,7 +62,7 @@ claude_mpm/core/minimal_framework_loader.py,sha256=liYS4IyuW_aFK7yhRDZwTwT-3q09f
62
62
  claude_mpm/core/mixins.py,sha256=rTEH-7FDpNiLB8oo6mSb0CLarJklv4fDJw1xM-gr5wI,5599
63
63
  claude_mpm/core/service_registry.py,sha256=wKJUO1g4UFA4dUpE3RkIYz1Ek8kIh4XfvU1kFeLCl2Q,10529
64
64
  claude_mpm/core/session_manager.py,sha256=3rO4KGZp8Qd_cUw6OWv4jyxGCUaL_MNPgCCpnwQt12A,6581
65
- claude_mpm/core/simple_runner.py,sha256=WdgPz7qMhb9ApGNK3HnM-p4CAdvzvPGPdXsdLxp4xWQ,22473
65
+ claude_mpm/core/simple_runner.py,sha256=DRChSTgPt6g0zQUZe9cEpH9ky2aZyLnlH0bhOI63vfc,24645
66
66
  claude_mpm/core/tool_access_control.py,sha256=htZbDhC8s7D7BVqfmk0BwRrYJnlnUAk8_NeJKOaeNlg,6632
67
67
  claude_mpm/generators/__init__.py,sha256=l53aBn6kBQSDz3b6bZkMCJBcEmYnV9hHEZq8LKzXgH8,152
68
68
  claude_mpm/generators/agent_profile_generator.py,sha256=2HjOscogSyvrtQj8KwdgNPS6Ym_QvgX1BMeauQZewZA,5751
@@ -81,7 +81,7 @@ claude_mpm/hooks/builtin/ticket_extraction_hook_example.py,sha256=4wNhS2tFUXgdcv
81
81
  claude_mpm/hooks/builtin/todo_agent_prefix_hook.py,sha256=v_4w2vcZIt0bkZxqdHmgtN79yHZ1gviuhhBws0FHpIQ,10226
82
82
  claude_mpm/hooks/builtin/workflow_start_hook.py,sha256=EQrtYD9qLMLSYPl3oQinEheZAJ2i5EO_h2jhhR8lmt0,7490
83
83
  claude_mpm/hooks/claude_hooks/__init__.py,sha256=bMUwt2RzDGAcEbtDMA7vWS1uJsauOY0OixIe4pHwgQ0,129
84
- claude_mpm/hooks/claude_hooks/hook_handler.py,sha256=30YDU6hVoju-vDyhP9HdhdGo5NJ8g4reJiQokLjvSKk,16154
84
+ claude_mpm/hooks/claude_hooks/hook_handler.py,sha256=r1OqgtXw04u47FVV8Ks2ppHh8hC4xSQrj3Q3hWHuHxs,21627
85
85
  claude_mpm/hooks/claude_hooks/hook_wrapper.sh,sha256=6n0-G317jIrPuNRGnAyFvBbNM4gVzKEat_WSbpvKN-g,1742
86
86
  claude_mpm/orchestration/SUBPROCESS_DESIGN.md,sha256=YwToiT1_NXblv1XIWhWPNc2uKzDvqY2E_Nix8qK7qk0,2136
87
87
  claude_mpm/orchestration/__init__.py,sha256=C-cwldtfBCgV19mKnJa5U1XiKw1rAZvx-kK61nIdcao,205
@@ -101,13 +101,15 @@ claude_mpm/schemas/agent_schema.json,sha256=xPqYaZ8VNFyabdpEL91kufKPsWk36v6hYbqo
101
101
  claude_mpm/scripts/__init__.py,sha256=M2n9fQeyfILC8gogXvJv6ixnu7hwpqLEqLWJRaUN0MU,37
102
102
  claude_mpm/scripts/ticket.py,sha256=GmFimtTJxc927cCzJvvJH3gvoxXQtAB-W-xnuclcvNs,9350
103
103
  claude_mpm/services/__init__.py,sha256=-EBm07Lh9mjcofiQHCqyCCQJMLi9akVArPlz8i_kEOo,226
104
- claude_mpm/services/agent_deployment.py,sha256=FqxKBaTl2vQqsxN7QZPKIeLmhO-f8VW6maRBmAUNW50,40398
104
+ claude_mpm/services/agent_capabilities_generator.py,sha256=K0oO2N4yjRXmf27FF6dbWCXcugT-7uGWz5p0p0APDSg,6658
105
+ claude_mpm/services/agent_deployment.py,sha256=23nvYNyDj7QXxaiDsbwhuYhNDAv9vJ-KJI-SEHWcH5I,49837
105
106
  claude_mpm/services/agent_lifecycle_manager.py,sha256=VZBVONepomFpMqL7soaXIawS4NoaltFWKed7tU6bS3w,39057
106
107
  claude_mpm/services/agent_management_service.py,sha256=eX5n6w17b9urcogVdr4V-kXcuo7yyjORTrIihjF8PeQ,22853
107
108
  claude_mpm/services/agent_modification_tracker.py,sha256=7FRDXuCNANUnLatCgtBArG-AxZNtKbGQjgCKjnzmJ80,34050
108
109
  claude_mpm/services/agent_profile_loader.py,sha256=4D1Xj0vgqV8wN7Y3r8lijh7ghy5cVGU5t5s931sVqGc,23133
109
110
  claude_mpm/services/agent_registry.py,sha256=vn8CEW0vppj_0EY2NofmNRZEnpV70mlWiX2kAViFDRg,24374
110
111
  claude_mpm/services/base_agent_manager.py,sha256=WEcfzdMaFXmXUSoEYEPNeGu8dvqjIv53zyUU0ITrhsM,14987
112
+ claude_mpm/services/deployed_agent_discovery.py,sha256=suzDPVt3eSGjyO1tkpuYNrMbgPz_uUuAWHWimtjvT3A,9299
111
113
  claude_mpm/services/framework_agent_loader.py,sha256=QdRSYRurYF3YbAXJwIGei71BffD5AqOVcV3ktRPdk7g,14018
112
114
  claude_mpm/services/framework_claude_md_generator.py,sha256=3kHmkRLHTex6HFZ4DhbLVQb48j-5dAoy1q6UW1Qf7U8,22914
113
115
  claude_mpm/services/shared_prompt_cache.py,sha256=D04lrRWyg0lHyqGcAHy7IYvRHRKSg6EOpAJwBUPa2wk,29890
@@ -116,9 +118,9 @@ claude_mpm/services/ticket_manager_di.py,sha256=pIsIGncbboKzBYSRQTO7ZX5MuQzV6iFf
116
118
  claude_mpm/services/ticketing_service_original.py,sha256=Dg3TYKsy0Z3JCqV5rlMBXeMrhrkAGxOgAMUNRZtJIhw,16680
117
119
  claude_mpm/services/framework_claude_md_generator/README.md,sha256=_-ty72t2afPagDVVUEizPkhs4BYkCeqCnZDNPgZAYtY,3511
118
120
  claude_mpm/services/framework_claude_md_generator/__init__.py,sha256=OtnwxLiJektfFtsKdkHM1X27rKkFiNd_rcf4843ziKw,7334
119
- claude_mpm/services/framework_claude_md_generator/content_assembler.py,sha256=B2AFqKsmp0K-bqM69p1ucosRrBiZPWGgujh6qa_voJQ,5000
121
+ claude_mpm/services/framework_claude_md_generator/content_assembler.py,sha256=CZlw84bBWjvK68VQhjAdLnMxXBXipZtcdyPtYWLdrKo,6590
120
122
  claude_mpm/services/framework_claude_md_generator/content_validator.py,sha256=89QSGil9_NL15ci3HsVVQmfg7MZvsJS3i_ELP5yD-gA,4583
121
- claude_mpm/services/framework_claude_md_generator/deployment_manager.py,sha256=gnW4RU5TKMstQ8u1bGdr_BlIQb4223MzRRaqd90sMCc,4991
123
+ claude_mpm/services/framework_claude_md_generator/deployment_manager.py,sha256=G0-JBMf7WH8VScCVUbXxSpmxBP_Qy_UX4TEgc4ajHFk,6187
122
124
  claude_mpm/services/framework_claude_md_generator/section_manager.py,sha256=KbipmnUg7FD3YnVdUj4Ttrm3HMmWrDnjWC6fKX5D3tI,3222
123
125
  claude_mpm/services/framework_claude_md_generator/version_manager.py,sha256=VpJMieGEVkkKC6vyhHxKcUjPNzxBuPwD61lTyPJwxXM,4284
124
126
  claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py,sha256=HIIW34LgzTJk_ne4qoNxXgYZp3EhEisJR0SjfNjPG7o,3486
@@ -158,14 +160,15 @@ claude_mpm/ui/terminal_ui.py,sha256=E_M-L-6EuGp6L8pRpaWEhTqf-ddDXhZp5W85D0XNRPw,
158
160
  claude_mpm/utils/__init__.py,sha256=E8Hvv6ykL6rnnc8-YmfoGNpRCZbcIirxcFuNz7YvDIg,346
159
161
  claude_mpm/utils/config_manager.py,sha256=TlekZYIWOz_ouWHQU4Gc-zckhoFK9AqA25b6A_XZdDc,16412
160
162
  claude_mpm/utils/error_handler.py,sha256=W_Zc0FrKudpXvxT66Oxx0v8WkR8HA2KlynzzGy3eGcU,8168
163
+ claude_mpm/utils/framework_detection.py,sha256=nzs1qRZK9K-zT0382z1FpGDvgzUNrUg8rBL-O_WLq-Q,1217
161
164
  claude_mpm/utils/import_migration_example.py,sha256=W4a4XH3FY_VBB00BB8Lae2aRPM021PxLHzdUfEs0B5w,2463
162
165
  claude_mpm/utils/imports.py,sha256=wX-SOXUHbemx01MHRGQpVwajzXH6qYdQkYNFCIbb2mw,6851
163
166
  claude_mpm/utils/path_operations.py,sha256=6pLMnAWBVzHkgp6JyQHmHbGD-dWn-nX21yV4E_eT-kM,11614
164
167
  claude_mpm/utils/paths.py,sha256=Xv0SZWdZRkRjN9e6clBcA165ya00GNQxt7SwMz51tfA,10153
165
168
  claude_mpm/validation/__init__.py,sha256=bJ19g9lnk7yIjtxzN8XPegp87HTFBzCrGQOpFgRTf3g,155
166
169
  claude_mpm/validation/agent_validator.py,sha256=gxBn3m3NyJiHymIoNGUBk4dzRjIrw3TVL6lWPpmZmW8,11693
167
- claude_mpm-2.0.0.dist-info/METADATA,sha256=RC_YCOD4Ed-EIA2RU4THxcAwU8mqthscpZdz-XetqBg,13250
168
- claude_mpm-2.0.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
169
- claude_mpm-2.0.0.dist-info/entry_points.txt,sha256=PknO31um7d8bt6GjOiVeYpdJpjND0_C1z-LQfY6UfiU,142
170
- claude_mpm-2.0.0.dist-info/top_level.txt,sha256=1nUg3FEaBySgm8t-s54jK5zoPnu3_eY6EP6IOlekyHA,11
171
- claude_mpm-2.0.0.dist-info/RECORD,,
170
+ claude_mpm-2.1.0.dist-info/METADATA,sha256=WOaRAE-7Fy72GQtEEJ1BvK7IIRKbqbpdUvnHTzR7RQE,13862
171
+ claude_mpm-2.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
172
+ claude_mpm-2.1.0.dist-info/entry_points.txt,sha256=PknO31um7d8bt6GjOiVeYpdJpjND0_C1z-LQfY6UfiU,142
173
+ claude_mpm-2.1.0.dist-info/top_level.txt,sha256=1nUg3FEaBySgm8t-s54jK5zoPnu3_eY6EP6IOlekyHA,11
174
+ claude_mpm-2.1.0.dist-info/RECORD,,