claude-mpm 0.3.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.
Potentially problematic release.
This version of claude-mpm might be problematic. Click here for more details.
- claude_mpm/__init__.py +17 -0
- claude_mpm/__main__.py +14 -0
- claude_mpm/_version.py +32 -0
- claude_mpm/agents/BASE_AGENT_TEMPLATE.md +88 -0
- claude_mpm/agents/INSTRUCTIONS.md +375 -0
- claude_mpm/agents/__init__.py +118 -0
- claude_mpm/agents/agent_loader.py +621 -0
- claude_mpm/agents/agent_loader_integration.py +229 -0
- claude_mpm/agents/agents_metadata.py +204 -0
- claude_mpm/agents/base_agent.json +27 -0
- claude_mpm/agents/base_agent_loader.py +519 -0
- claude_mpm/agents/schema/agent_schema.json +160 -0
- claude_mpm/agents/system_agent_config.py +587 -0
- claude_mpm/agents/templates/__init__.py +101 -0
- claude_mpm/agents/templates/data_engineer_agent.json +46 -0
- claude_mpm/agents/templates/documentation_agent.json +45 -0
- claude_mpm/agents/templates/engineer_agent.json +49 -0
- claude_mpm/agents/templates/ops_agent.json +46 -0
- claude_mpm/agents/templates/qa_agent.json +45 -0
- claude_mpm/agents/templates/research_agent.json +49 -0
- claude_mpm/agents/templates/security_agent.json +46 -0
- claude_mpm/agents/templates/update-optimized-specialized-agents.json +374 -0
- claude_mpm/agents/templates/version_control_agent.json +46 -0
- claude_mpm/agents/test_fix_deployment/.claude-pm/config/project.json +6 -0
- claude_mpm/cli.py +655 -0
- claude_mpm/cli_main.py +13 -0
- claude_mpm/cli_module/__init__.py +15 -0
- claude_mpm/cli_module/args.py +222 -0
- claude_mpm/cli_module/commands.py +203 -0
- claude_mpm/cli_module/migration_example.py +183 -0
- claude_mpm/cli_module/refactoring_guide.md +253 -0
- claude_mpm/cli_old/__init__.py +1 -0
- claude_mpm/cli_old/ticket_cli.py +102 -0
- claude_mpm/config/__init__.py +5 -0
- claude_mpm/config/hook_config.py +42 -0
- claude_mpm/constants.py +150 -0
- claude_mpm/core/__init__.py +45 -0
- claude_mpm/core/agent_name_normalizer.py +248 -0
- claude_mpm/core/agent_registry.py +627 -0
- claude_mpm/core/agent_registry.py.bak +312 -0
- claude_mpm/core/agent_session_manager.py +273 -0
- claude_mpm/core/base_service.py +747 -0
- claude_mpm/core/base_service.py.bak +406 -0
- claude_mpm/core/config.py +334 -0
- claude_mpm/core/config_aliases.py +292 -0
- claude_mpm/core/container.py +347 -0
- claude_mpm/core/factories.py +281 -0
- claude_mpm/core/framework_loader.py +472 -0
- claude_mpm/core/injectable_service.py +206 -0
- claude_mpm/core/interfaces.py +539 -0
- claude_mpm/core/logger.py +468 -0
- claude_mpm/core/minimal_framework_loader.py +107 -0
- claude_mpm/core/mixins.py +150 -0
- claude_mpm/core/service_registry.py +299 -0
- claude_mpm/core/session_manager.py +190 -0
- claude_mpm/core/simple_runner.py +511 -0
- claude_mpm/core/tool_access_control.py +173 -0
- claude_mpm/hooks/README.md +243 -0
- claude_mpm/hooks/__init__.py +5 -0
- claude_mpm/hooks/base_hook.py +154 -0
- claude_mpm/hooks/builtin/__init__.py +1 -0
- claude_mpm/hooks/builtin/logging_hook_example.py +165 -0
- claude_mpm/hooks/builtin/post_delegation_hook_example.py +124 -0
- claude_mpm/hooks/builtin/pre_delegation_hook_example.py +125 -0
- claude_mpm/hooks/builtin/submit_hook_example.py +100 -0
- claude_mpm/hooks/builtin/ticket_extraction_hook_example.py +237 -0
- claude_mpm/hooks/builtin/todo_agent_prefix_hook.py +239 -0
- claude_mpm/hooks/builtin/workflow_start_hook.py +181 -0
- claude_mpm/hooks/hook_client.py +264 -0
- claude_mpm/hooks/hook_runner.py +370 -0
- claude_mpm/hooks/json_rpc_executor.py +259 -0
- claude_mpm/hooks/json_rpc_hook_client.py +319 -0
- claude_mpm/hooks/tool_call_interceptor.py +204 -0
- claude_mpm/init.py +246 -0
- claude_mpm/orchestration/SUBPROCESS_DESIGN.md +66 -0
- claude_mpm/orchestration/__init__.py +6 -0
- claude_mpm/orchestration/archive/direct_orchestrator.py +195 -0
- claude_mpm/orchestration/archive/factory.py +215 -0
- claude_mpm/orchestration/archive/hook_enabled_orchestrator.py +188 -0
- claude_mpm/orchestration/archive/hook_integration_example.py +178 -0
- claude_mpm/orchestration/archive/interactive_subprocess_orchestrator.py +826 -0
- claude_mpm/orchestration/archive/orchestrator.py +501 -0
- claude_mpm/orchestration/archive/pexpect_orchestrator.py +252 -0
- claude_mpm/orchestration/archive/pty_orchestrator.py +270 -0
- claude_mpm/orchestration/archive/simple_orchestrator.py +82 -0
- claude_mpm/orchestration/archive/subprocess_orchestrator.py +801 -0
- claude_mpm/orchestration/archive/system_prompt_orchestrator.py +278 -0
- claude_mpm/orchestration/archive/wrapper_orchestrator.py +187 -0
- claude_mpm/scripts/__init__.py +1 -0
- claude_mpm/scripts/ticket.py +269 -0
- claude_mpm/services/__init__.py +10 -0
- claude_mpm/services/agent_deployment.py +955 -0
- claude_mpm/services/agent_lifecycle_manager.py +948 -0
- claude_mpm/services/agent_management_service.py +596 -0
- claude_mpm/services/agent_modification_tracker.py +841 -0
- claude_mpm/services/agent_profile_loader.py +606 -0
- claude_mpm/services/agent_registry.py +677 -0
- claude_mpm/services/base_agent_manager.py +380 -0
- claude_mpm/services/framework_agent_loader.py +337 -0
- claude_mpm/services/framework_claude_md_generator/README.md +92 -0
- claude_mpm/services/framework_claude_md_generator/__init__.py +206 -0
- claude_mpm/services/framework_claude_md_generator/content_assembler.py +151 -0
- claude_mpm/services/framework_claude_md_generator/content_validator.py +126 -0
- claude_mpm/services/framework_claude_md_generator/deployment_manager.py +137 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +106 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +582 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +97 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/core_responsibilities.py +27 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/delegation_constraints.py +23 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/environment_config.py +23 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/footer.py +20 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/header.py +26 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/orchestration_principles.py +30 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/role_designation.py +37 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/subprocess_validation.py +111 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +89 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/troubleshooting.py +39 -0
- claude_mpm/services/framework_claude_md_generator/section_manager.py +106 -0
- claude_mpm/services/framework_claude_md_generator/version_manager.py +121 -0
- claude_mpm/services/framework_claude_md_generator.py +621 -0
- claude_mpm/services/hook_service.py +388 -0
- claude_mpm/services/hook_service_manager.py +223 -0
- claude_mpm/services/json_rpc_hook_manager.py +92 -0
- claude_mpm/services/parent_directory_manager/README.md +83 -0
- claude_mpm/services/parent_directory_manager/__init__.py +577 -0
- claude_mpm/services/parent_directory_manager/backup_manager.py +258 -0
- claude_mpm/services/parent_directory_manager/config_manager.py +210 -0
- claude_mpm/services/parent_directory_manager/deduplication_manager.py +279 -0
- claude_mpm/services/parent_directory_manager/framework_protector.py +143 -0
- claude_mpm/services/parent_directory_manager/operations.py +186 -0
- claude_mpm/services/parent_directory_manager/state_manager.py +624 -0
- claude_mpm/services/parent_directory_manager/template_deployer.py +579 -0
- claude_mpm/services/parent_directory_manager/validation_manager.py +378 -0
- claude_mpm/services/parent_directory_manager/version_control_helper.py +339 -0
- claude_mpm/services/parent_directory_manager/version_manager.py +222 -0
- claude_mpm/services/shared_prompt_cache.py +819 -0
- claude_mpm/services/ticket_manager.py +213 -0
- claude_mpm/services/ticket_manager_di.py +318 -0
- claude_mpm/services/ticketing_service_original.py +508 -0
- claude_mpm/services/version_control/VERSION +1 -0
- claude_mpm/services/version_control/__init__.py +70 -0
- claude_mpm/services/version_control/branch_strategy.py +670 -0
- claude_mpm/services/version_control/conflict_resolution.py +744 -0
- claude_mpm/services/version_control/git_operations.py +784 -0
- claude_mpm/services/version_control/semantic_versioning.py +703 -0
- claude_mpm/ui/__init__.py +1 -0
- claude_mpm/ui/rich_terminal_ui.py +295 -0
- claude_mpm/ui/terminal_ui.py +328 -0
- claude_mpm/utils/__init__.py +16 -0
- claude_mpm/utils/config_manager.py +468 -0
- claude_mpm/utils/import_migration_example.py +80 -0
- claude_mpm/utils/imports.py +182 -0
- claude_mpm/utils/path_operations.py +357 -0
- claude_mpm/utils/paths.py +289 -0
- claude_mpm-0.3.0.dist-info/METADATA +290 -0
- claude_mpm-0.3.0.dist-info/RECORD +159 -0
- claude_mpm-0.3.0.dist-info/WHEEL +5 -0
- claude_mpm-0.3.0.dist-info/entry_points.txt +4 -0
- claude_mpm-0.3.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
"""Agent name normalization utilities for consistent naming across the system."""
|
|
2
|
+
|
|
3
|
+
from typing import Dict, Optional
|
|
4
|
+
import logging
|
|
5
|
+
|
|
6
|
+
logger = logging.getLogger(__name__)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class AgentNameNormalizer:
|
|
10
|
+
"""
|
|
11
|
+
Handles agent name normalization to ensure consistency across:
|
|
12
|
+
- TodoWrite prefixes
|
|
13
|
+
- Task tool display
|
|
14
|
+
- Agent type identification
|
|
15
|
+
- Color coding
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
# Canonical agent names (standardized format)
|
|
19
|
+
CANONICAL_NAMES = {
|
|
20
|
+
"research": "Research",
|
|
21
|
+
"engineer": "Engineer",
|
|
22
|
+
"qa": "QA",
|
|
23
|
+
"security": "Security",
|
|
24
|
+
"documentation": "Documentation",
|
|
25
|
+
"ops": "Ops",
|
|
26
|
+
"version_control": "Version Control",
|
|
27
|
+
"data_engineer": "Data Engineer",
|
|
28
|
+
"architect": "Architect",
|
|
29
|
+
"pm": "PM"
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
# Aliases and variations that map to canonical names
|
|
33
|
+
ALIASES = {
|
|
34
|
+
# Research variations
|
|
35
|
+
"research": "research",
|
|
36
|
+
"Research": "research",
|
|
37
|
+
"RESEARCH": "research",
|
|
38
|
+
"researcher": "research",
|
|
39
|
+
|
|
40
|
+
# Engineer variations
|
|
41
|
+
"engineer": "engineer",
|
|
42
|
+
"Engineer": "engineer",
|
|
43
|
+
"ENGINEER": "engineer",
|
|
44
|
+
"engineering": "engineer",
|
|
45
|
+
"dev": "engineer",
|
|
46
|
+
"developer": "engineer",
|
|
47
|
+
|
|
48
|
+
# QA variations
|
|
49
|
+
"qa": "qa",
|
|
50
|
+
"QA": "qa",
|
|
51
|
+
"Qa": "qa",
|
|
52
|
+
"quality": "qa",
|
|
53
|
+
"testing": "qa",
|
|
54
|
+
"test": "qa",
|
|
55
|
+
|
|
56
|
+
# Security variations
|
|
57
|
+
"security": "security",
|
|
58
|
+
"Security": "security",
|
|
59
|
+
"SECURITY": "security",
|
|
60
|
+
"sec": "security",
|
|
61
|
+
|
|
62
|
+
# Documentation variations
|
|
63
|
+
"documentation": "documentation",
|
|
64
|
+
"Documentation": "documentation",
|
|
65
|
+
"docs": "documentation",
|
|
66
|
+
"doc": "documentation",
|
|
67
|
+
|
|
68
|
+
# Ops variations
|
|
69
|
+
"ops": "ops",
|
|
70
|
+
"Ops": "ops",
|
|
71
|
+
"OPS": "ops",
|
|
72
|
+
"operations": "ops",
|
|
73
|
+
"devops": "ops",
|
|
74
|
+
|
|
75
|
+
# Version Control variations
|
|
76
|
+
"version_control": "version_control",
|
|
77
|
+
"version control": "version_control",
|
|
78
|
+
"Version Control": "version_control",
|
|
79
|
+
"git": "version_control",
|
|
80
|
+
"vcs": "version_control",
|
|
81
|
+
|
|
82
|
+
# Data Engineer variations
|
|
83
|
+
"data_engineer": "data_engineer",
|
|
84
|
+
"data engineer": "data_engineer",
|
|
85
|
+
"Data Engineer": "data_engineer",
|
|
86
|
+
"data": "data_engineer",
|
|
87
|
+
|
|
88
|
+
# Architect variations
|
|
89
|
+
"architect": "architect",
|
|
90
|
+
"Architect": "architect",
|
|
91
|
+
"architecture": "architect",
|
|
92
|
+
"arch": "architect",
|
|
93
|
+
|
|
94
|
+
# PM variations
|
|
95
|
+
"pm": "pm",
|
|
96
|
+
"PM": "pm",
|
|
97
|
+
"project_manager": "pm",
|
|
98
|
+
"project manager": "pm"
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
# Agent colors for consistent display
|
|
102
|
+
AGENT_COLORS = {
|
|
103
|
+
"research": "\033[36m", # Cyan
|
|
104
|
+
"engineer": "\033[32m", # Green
|
|
105
|
+
"qa": "\033[33m", # Yellow
|
|
106
|
+
"security": "\033[31m", # Red
|
|
107
|
+
"documentation": "\033[34m", # Blue
|
|
108
|
+
"ops": "\033[35m", # Magenta
|
|
109
|
+
"version_control": "\033[37m", # White
|
|
110
|
+
"data_engineer": "\033[96m", # Bright Cyan
|
|
111
|
+
"architect": "\033[95m", # Bright Magenta
|
|
112
|
+
"pm": "\033[92m" # Bright Green
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
COLOR_RESET = "\033[0m"
|
|
116
|
+
|
|
117
|
+
@classmethod
|
|
118
|
+
def normalize(cls, agent_name: str) -> str:
|
|
119
|
+
"""
|
|
120
|
+
Normalize an agent name to its canonical form.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
agent_name: The agent name to normalize
|
|
124
|
+
|
|
125
|
+
Returns:
|
|
126
|
+
The canonical agent name
|
|
127
|
+
"""
|
|
128
|
+
if not agent_name:
|
|
129
|
+
return "Engineer" # Default
|
|
130
|
+
|
|
131
|
+
# Clean the input
|
|
132
|
+
cleaned = agent_name.strip().lower().replace("-", "_")
|
|
133
|
+
|
|
134
|
+
# Check aliases first
|
|
135
|
+
if cleaned in cls.ALIASES:
|
|
136
|
+
canonical_key = cls.ALIASES[cleaned]
|
|
137
|
+
return cls.CANONICAL_NAMES.get(canonical_key, "Engineer")
|
|
138
|
+
|
|
139
|
+
# Check if it's already a canonical key
|
|
140
|
+
if cleaned in cls.CANONICAL_NAMES:
|
|
141
|
+
return cls.CANONICAL_NAMES[cleaned]
|
|
142
|
+
|
|
143
|
+
# Try to find partial matches
|
|
144
|
+
for alias, canonical_key in cls.ALIASES.items():
|
|
145
|
+
if cleaned in alias or alias in cleaned:
|
|
146
|
+
return cls.CANONICAL_NAMES.get(canonical_key, "Engineer")
|
|
147
|
+
|
|
148
|
+
logger.warning(f"Unknown agent name '{agent_name}', defaulting to Engineer")
|
|
149
|
+
return "Engineer"
|
|
150
|
+
|
|
151
|
+
@classmethod
|
|
152
|
+
def to_key(cls, agent_name: str) -> str:
|
|
153
|
+
"""
|
|
154
|
+
Convert an agent name to its key format (lowercase with underscores).
|
|
155
|
+
|
|
156
|
+
Args:
|
|
157
|
+
agent_name: The agent name to convert
|
|
158
|
+
|
|
159
|
+
Returns:
|
|
160
|
+
The key format of the agent name
|
|
161
|
+
"""
|
|
162
|
+
normalized = cls.normalize(agent_name)
|
|
163
|
+
return normalized.lower().replace(" ", "_")
|
|
164
|
+
|
|
165
|
+
@classmethod
|
|
166
|
+
def to_todo_prefix(cls, agent_name: str) -> str:
|
|
167
|
+
"""
|
|
168
|
+
Format agent name for TODO prefix (e.g., [Research]).
|
|
169
|
+
|
|
170
|
+
Args:
|
|
171
|
+
agent_name: The agent name to format
|
|
172
|
+
|
|
173
|
+
Returns:
|
|
174
|
+
The formatted TODO prefix
|
|
175
|
+
"""
|
|
176
|
+
normalized = cls.normalize(agent_name)
|
|
177
|
+
return f"[{normalized}]"
|
|
178
|
+
|
|
179
|
+
@classmethod
|
|
180
|
+
def colorize(cls, agent_name: str, text: Optional[str] = None) -> str:
|
|
181
|
+
"""
|
|
182
|
+
Apply consistent color coding to agent names.
|
|
183
|
+
|
|
184
|
+
Args:
|
|
185
|
+
agent_name: The agent name to colorize
|
|
186
|
+
text: Optional text to colorize (defaults to agent name)
|
|
187
|
+
|
|
188
|
+
Returns:
|
|
189
|
+
The colorized text
|
|
190
|
+
"""
|
|
191
|
+
key = cls.to_key(agent_name)
|
|
192
|
+
color = cls.AGENT_COLORS.get(key, "")
|
|
193
|
+
display_text = text if text else cls.normalize(agent_name)
|
|
194
|
+
|
|
195
|
+
if color:
|
|
196
|
+
return f"{color}{display_text}{cls.COLOR_RESET}"
|
|
197
|
+
return display_text
|
|
198
|
+
|
|
199
|
+
@classmethod
|
|
200
|
+
def extract_from_todo(cls, todo_text: str) -> Optional[str]:
|
|
201
|
+
"""
|
|
202
|
+
Extract agent name from a TODO line.
|
|
203
|
+
|
|
204
|
+
Args:
|
|
205
|
+
todo_text: The TODO text (e.g., "[Research] Analyze patterns")
|
|
206
|
+
|
|
207
|
+
Returns:
|
|
208
|
+
The normalized agent name, or None if not found
|
|
209
|
+
"""
|
|
210
|
+
import re
|
|
211
|
+
|
|
212
|
+
# Match [Agent] at the beginning
|
|
213
|
+
match = re.match(r'^\[([^\]]+)\]', todo_text.strip())
|
|
214
|
+
if match:
|
|
215
|
+
return cls.normalize(match.group(1))
|
|
216
|
+
|
|
217
|
+
# Try to find agent mentions in the text
|
|
218
|
+
text_lower = todo_text.lower()
|
|
219
|
+
for alias, canonical_key in cls.ALIASES.items():
|
|
220
|
+
if alias in text_lower:
|
|
221
|
+
return cls.CANONICAL_NAMES.get(canonical_key)
|
|
222
|
+
|
|
223
|
+
return None
|
|
224
|
+
|
|
225
|
+
@classmethod
|
|
226
|
+
def validate_todo_format(cls, todo_text: str) -> tuple[bool, Optional[str]]:
|
|
227
|
+
"""
|
|
228
|
+
Validate that a TODO has proper agent prefix.
|
|
229
|
+
|
|
230
|
+
Args:
|
|
231
|
+
todo_text: The TODO text to validate
|
|
232
|
+
|
|
233
|
+
Returns:
|
|
234
|
+
Tuple of (is_valid, error_message)
|
|
235
|
+
"""
|
|
236
|
+
agent = cls.extract_from_todo(todo_text)
|
|
237
|
+
if not agent:
|
|
238
|
+
return False, "TODO must start with [Agent] prefix (e.g., [Research], [Engineer])"
|
|
239
|
+
|
|
240
|
+
# Check if it's a valid agent
|
|
241
|
+
if cls.to_key(agent) not in cls.CANONICAL_NAMES:
|
|
242
|
+
return False, f"Unknown agent '{agent}'. Valid agents: {', '.join(cls.CANONICAL_NAMES.values())}"
|
|
243
|
+
|
|
244
|
+
return True, None
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
# Global instance for easy access
|
|
248
|
+
agent_name_normalizer = AgentNameNormalizer()
|