claude-mpm 4.4.3__py3-none-any.whl → 4.4.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/agent_loader.py +3 -2
- claude_mpm/agents/agent_loader_integration.py +2 -1
- claude_mpm/agents/async_agent_loader.py +2 -2
- claude_mpm/agents/base_agent_loader.py +2 -2
- claude_mpm/agents/frontmatter_validator.py +1 -0
- claude_mpm/agents/system_agent_config.py +2 -1
- claude_mpm/cli/commands/doctor.py +44 -5
- claude_mpm/cli/commands/mpm_init.py +116 -62
- claude_mpm/cli/parsers/configure_parser.py +3 -1
- claude_mpm/cli/startup_logging.py +1 -3
- claude_mpm/config/agent_config.py +1 -1
- claude_mpm/config/paths.py +2 -1
- claude_mpm/core/agent_name_normalizer.py +1 -0
- claude_mpm/core/config.py +2 -1
- claude_mpm/core/config_aliases.py +2 -1
- claude_mpm/core/file_utils.py +0 -1
- claude_mpm/core/framework/__init__.py +6 -6
- claude_mpm/core/framework/formatters/__init__.py +2 -2
- claude_mpm/core/framework/formatters/capability_generator.py +19 -8
- claude_mpm/core/framework/formatters/content_formatter.py +8 -3
- claude_mpm/core/framework/formatters/context_generator.py +7 -3
- claude_mpm/core/framework/loaders/__init__.py +3 -3
- claude_mpm/core/framework/loaders/agent_loader.py +7 -3
- claude_mpm/core/framework/loaders/file_loader.py +16 -6
- claude_mpm/core/framework/loaders/instruction_loader.py +16 -6
- claude_mpm/core/framework/loaders/packaged_loader.py +36 -12
- claude_mpm/core/framework/processors/__init__.py +2 -2
- claude_mpm/core/framework/processors/memory_processor.py +14 -6
- claude_mpm/core/framework/processors/metadata_processor.py +5 -5
- claude_mpm/core/framework/processors/template_processor.py +12 -6
- claude_mpm/core/framework_loader.py +44 -20
- claude_mpm/core/log_manager.py +2 -1
- claude_mpm/core/tool_access_control.py +1 -0
- claude_mpm/core/unified_agent_registry.py +2 -1
- claude_mpm/core/unified_paths.py +1 -0
- claude_mpm/experimental/cli_enhancements.py +1 -0
- claude_mpm/hooks/base_hook.py +1 -0
- claude_mpm/hooks/instruction_reinforcement.py +1 -0
- claude_mpm/hooks/kuzu_memory_hook.py +20 -13
- claude_mpm/hooks/validation_hooks.py +1 -1
- claude_mpm/scripts/mpm_doctor.py +1 -0
- claude_mpm/services/agents/loading/agent_profile_loader.py +1 -1
- claude_mpm/services/agents/loading/base_agent_manager.py +1 -1
- claude_mpm/services/agents/loading/framework_agent_loader.py +1 -1
- claude_mpm/services/agents/management/agent_capabilities_generator.py +1 -0
- claude_mpm/services/agents/management/agent_management_service.py +1 -1
- claude_mpm/services/agents/memory/memory_categorization_service.py +0 -1
- claude_mpm/services/agents/memory/memory_file_service.py +6 -2
- claude_mpm/services/agents/memory/memory_format_service.py +0 -1
- claude_mpm/services/agents/registry/deployed_agent_discovery.py +1 -1
- claude_mpm/services/async_session_logger.py +1 -1
- claude_mpm/services/claude_session_logger.py +1 -0
- claude_mpm/services/core/path_resolver.py +1 -0
- claude_mpm/services/diagnostics/checks/__init__.py +2 -0
- claude_mpm/services/diagnostics/checks/installation_check.py +126 -25
- claude_mpm/services/diagnostics/checks/mcp_services_check.py +399 -0
- claude_mpm/services/diagnostics/diagnostic_runner.py +3 -0
- claude_mpm/services/diagnostics/doctor_reporter.py +259 -32
- claude_mpm/services/event_bus/direct_relay.py +2 -1
- claude_mpm/services/event_bus/event_bus.py +1 -0
- claude_mpm/services/event_bus/relay.py +3 -2
- claude_mpm/services/framework_claude_md_generator/content_assembler.py +1 -1
- claude_mpm/services/infrastructure/daemon_manager.py +1 -1
- claude_mpm/services/mcp_config_manager.py +10 -10
- claude_mpm/services/mcp_gateway/core/process_pool.py +62 -23
- claude_mpm/services/mcp_gateway/tools/__init__.py +6 -5
- claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +3 -1
- claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +16 -31
- claude_mpm/services/memory/cache/simple_cache.py +1 -1
- claude_mpm/services/project/archive_manager.py +159 -96
- claude_mpm/services/project/documentation_manager.py +64 -45
- claude_mpm/services/project/enhanced_analyzer.py +132 -89
- claude_mpm/services/project/project_organizer.py +225 -131
- claude_mpm/services/response_tracker.py +1 -1
- claude_mpm/services/socketio/server/eventbus_integration.py +1 -1
- claude_mpm/services/unified/__init__.py +1 -1
- claude_mpm/services/unified/analyzer_strategies/__init__.py +3 -3
- claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +97 -53
- claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +81 -40
- claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +277 -178
- claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +196 -112
- claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +83 -49
- claude_mpm/services/unified/config_strategies/__init__.py +111 -126
- claude_mpm/services/unified/config_strategies/config_schema.py +157 -111
- claude_mpm/services/unified/config_strategies/context_strategy.py +91 -89
- claude_mpm/services/unified/config_strategies/error_handling_strategy.py +183 -173
- claude_mpm/services/unified/config_strategies/file_loader_strategy.py +160 -152
- claude_mpm/services/unified/config_strategies/unified_config_service.py +124 -112
- claude_mpm/services/unified/config_strategies/validation_strategy.py +298 -259
- claude_mpm/services/unified/deployment_strategies/__init__.py +7 -7
- claude_mpm/services/unified/deployment_strategies/base.py +24 -28
- claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +168 -88
- claude_mpm/services/unified/deployment_strategies/local.py +49 -34
- claude_mpm/services/unified/deployment_strategies/utils.py +39 -43
- claude_mpm/services/unified/deployment_strategies/vercel.py +30 -24
- claude_mpm/services/unified/interfaces.py +0 -26
- claude_mpm/services/unified/migration.py +17 -40
- claude_mpm/services/unified/strategies.py +9 -26
- claude_mpm/services/unified/unified_analyzer.py +48 -44
- claude_mpm/services/unified/unified_config.py +21 -19
- claude_mpm/services/unified/unified_deployment.py +21 -26
- claude_mpm/storage/state_storage.py +1 -0
- claude_mpm/utils/agent_dependency_loader.py +18 -6
- claude_mpm/utils/common.py +14 -12
- claude_mpm/utils/database_connector.py +15 -12
- claude_mpm/utils/error_handler.py +1 -0
- claude_mpm/utils/log_cleanup.py +1 -0
- claude_mpm/utils/path_operations.py +1 -0
- claude_mpm/utils/session_logging.py +1 -1
- claude_mpm/utils/subprocess_utils.py +1 -0
- claude_mpm/validation/agent_validator.py +1 -1
- {claude_mpm-4.4.3.dist-info → claude_mpm-4.4.4.dist-info}/METADATA +9 -3
- {claude_mpm-4.4.3.dist-info → claude_mpm-4.4.4.dist-info}/RECORD +118 -117
- {claude_mpm-4.4.3.dist-info → claude_mpm-4.4.4.dist-info}/WHEEL +0 -0
- {claude_mpm-4.4.3.dist-info → claude_mpm-4.4.4.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.4.3.dist-info → claude_mpm-4.4.4.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.4.3.dist-info → claude_mpm-4.4.4.dist-info}/top_level.txt +0 -0
claude_mpm/core/file_utils.py
CHANGED
@@ -22,7 +22,6 @@ from claude_mpm.core.logging_utils import get_logger
|
|
22
22
|
logger = get_logger(__name__)
|
23
23
|
|
24
24
|
|
25
|
-
|
26
25
|
# ==============================================================================
|
27
26
|
# PATH UTILITIES
|
28
27
|
# ==============================================================================
|
@@ -4,17 +4,17 @@ This module provides the modular framework loading system with specialized compo
|
|
4
4
|
for handling different aspects of framework initialization and management.
|
5
5
|
"""
|
6
6
|
|
7
|
+
from .formatters import (
|
8
|
+
CapabilityGenerator,
|
9
|
+
ContentFormatter,
|
10
|
+
ContextGenerator,
|
11
|
+
)
|
7
12
|
from .loaders import (
|
8
13
|
AgentLoader,
|
9
14
|
FileLoader,
|
10
15
|
InstructionLoader,
|
11
16
|
PackagedLoader,
|
12
17
|
)
|
13
|
-
from .formatters import (
|
14
|
-
CapabilityGenerator,
|
15
|
-
ContentFormatter,
|
16
|
-
ContextGenerator,
|
17
|
-
)
|
18
18
|
from .processors import (
|
19
19
|
MemoryProcessor,
|
20
20
|
MetadataProcessor,
|
@@ -35,4 +35,4 @@ __all__ = [
|
|
35
35
|
"MetadataProcessor",
|
36
36
|
"TemplateProcessor",
|
37
37
|
"MemoryProcessor",
|
38
|
-
]
|
38
|
+
]
|
@@ -1,7 +1,6 @@
|
|
1
1
|
"""Agent capability generator for dynamic agent discovery."""
|
2
2
|
|
3
3
|
import json
|
4
|
-
import time
|
5
4
|
from pathlib import Path
|
6
5
|
from typing import Any, Dict, List, Optional
|
7
6
|
|
@@ -128,7 +127,9 @@ class CapabilityGenerator:
|
|
128
127
|
if agent.get("memory_routing"):
|
129
128
|
memory_routing = agent["memory_routing"]
|
130
129
|
if memory_routing.get("description"):
|
131
|
-
section +=
|
130
|
+
section += (
|
131
|
+
f"- **Memory Routing**: {memory_routing['description']}\n"
|
132
|
+
)
|
132
133
|
|
133
134
|
# Add simple Context-Aware Agent Selection
|
134
135
|
section += "\n## Context-Aware Agent Selection\n\n"
|
@@ -159,7 +160,9 @@ class CapabilityGenerator:
|
|
159
160
|
# Default values
|
160
161
|
agent_data = {
|
161
162
|
"id": agent_file.stem,
|
162
|
-
"display_name": agent_file.stem.replace("_", " ")
|
163
|
+
"display_name": agent_file.stem.replace("_", " ")
|
164
|
+
.replace("-", " ")
|
165
|
+
.title(),
|
163
166
|
"description": "Specialized agent",
|
164
167
|
}
|
165
168
|
|
@@ -191,7 +194,9 @@ class CapabilityGenerator:
|
|
191
194
|
|
192
195
|
# Try to load memory routing metadata from JSON template
|
193
196
|
if "memory_routing" not in agent_data:
|
194
|
-
memory_routing_data = self.load_memory_routing_from_template(
|
197
|
+
memory_routing_data = self.load_memory_routing_from_template(
|
198
|
+
agent_file.stem
|
199
|
+
)
|
195
200
|
if memory_routing_data:
|
196
201
|
agent_data["memory_routing"] = memory_routing_data
|
197
202
|
|
@@ -233,7 +238,9 @@ class CapabilityGenerator:
|
|
233
238
|
return None
|
234
239
|
|
235
240
|
# For development mode, load from filesystem
|
236
|
-
templates_dir =
|
241
|
+
templates_dir = (
|
242
|
+
framework_path / "src" / "claude_mpm" / "agents" / "templates"
|
243
|
+
)
|
237
244
|
template_file = templates_dir / f"{agent_name}.json"
|
238
245
|
|
239
246
|
if template_file.exists():
|
@@ -297,7 +304,9 @@ class CapabilityGenerator:
|
|
297
304
|
return None
|
298
305
|
|
299
306
|
# For development mode, load from filesystem
|
300
|
-
templates_dir =
|
307
|
+
templates_dir = (
|
308
|
+
framework_path / "src" / "claude_mpm" / "agents" / "templates"
|
309
|
+
)
|
301
310
|
template_file = templates_dir / f"{agent_name}.json"
|
302
311
|
|
303
312
|
if template_file.exists():
|
@@ -328,7 +337,9 @@ class CapabilityGenerator:
|
|
328
337
|
return None
|
329
338
|
|
330
339
|
except Exception as e:
|
331
|
-
self.logger.debug(
|
340
|
+
self.logger.debug(
|
341
|
+
f"Could not load memory routing from template for {agent_name}: {e}"
|
342
|
+
)
|
332
343
|
return None
|
333
344
|
|
334
345
|
def get_fallback_capabilities(self) -> str:
|
@@ -353,4 +364,4 @@ You have the following specialized agents available for delegation:
|
|
353
364
|
- **Version Control** (`version-control`): Git operations and version management
|
354
365
|
|
355
366
|
**IMPORTANT**: Use the exact agent ID in parentheses when delegating tasks.
|
356
|
-
"""
|
367
|
+
"""
|
@@ -174,7 +174,10 @@ You are a multi-agent orchestrator. Your primary responsibilities are:
|
|
174
174
|
# Use the actual agent_name as the ID (it's the filename stem)
|
175
175
|
agent_id = agent_name
|
176
176
|
clean_name = agent_name.replace("-", " ").replace("_", " ").title()
|
177
|
-
if
|
177
|
+
if (
|
178
|
+
"engineer" in agent_name.lower()
|
179
|
+
and "data" not in agent_name.lower()
|
180
|
+
):
|
178
181
|
agent_list.append(
|
179
182
|
f"- **Engineer Agent** (`{agent_id}`): Code implementation and development"
|
180
183
|
)
|
@@ -215,7 +218,9 @@ You are a multi-agent orchestrator. Your primary responsibilities are:
|
|
215
218
|
|
216
219
|
# Add full agent details
|
217
220
|
instructions += "### Agent Details\n\n"
|
218
|
-
for agent_name, agent_content in sorted(
|
221
|
+
for agent_name, agent_content in sorted(
|
222
|
+
framework_content["agents"].items()
|
223
|
+
):
|
219
224
|
instructions += f"#### {agent_name.replace('-', ' ').title()}\n"
|
220
225
|
instructions += agent_content + "\n\n"
|
221
226
|
|
@@ -280,4 +285,4 @@ You have the following specialized agents available for delegation:
|
|
280
285
|
- **Version Control** (`version-control`): Git operations and version management
|
281
286
|
|
282
287
|
**IMPORTANT**: Use the exact agent ID in parentheses when delegating tasks.
|
283
|
-
"""
|
288
|
+
"""
|
@@ -54,7 +54,9 @@ class ContextGenerator:
|
|
54
54
|
time_str = now.strftime("%H:%M:%S")
|
55
55
|
day_name = now.strftime("%A")
|
56
56
|
|
57
|
-
context_lines.append(
|
57
|
+
context_lines.append(
|
58
|
+
f"**Current DateTime**: {date_str} {time_str} {tz_info}\n"
|
59
|
+
)
|
58
60
|
context_lines.append(f"**Day**: {day_name}\n")
|
59
61
|
|
60
62
|
except Exception as e:
|
@@ -148,7 +150,9 @@ class ContextGenerator:
|
|
148
150
|
try:
|
149
151
|
platform_version = platform.release()
|
150
152
|
if platform_version:
|
151
|
-
context_lines.append(
|
153
|
+
context_lines.append(
|
154
|
+
f"**System Version**: {platform_version}\n"
|
155
|
+
)
|
152
156
|
except Exception:
|
153
157
|
pass
|
154
158
|
|
@@ -177,4 +181,4 @@ class ContextGenerator:
|
|
177
181
|
context_lines.append(f"**Locale**: {current_locale[0]}\n")
|
178
182
|
except Exception:
|
179
183
|
# Locale is optional
|
180
|
-
pass
|
184
|
+
pass
|
@@ -47,7 +47,9 @@ class AgentLoader:
|
|
47
47
|
self.logger.debug(f"Total deployed agents found: {len(deployed)}")
|
48
48
|
return deployed
|
49
49
|
|
50
|
-
def load_single_agent(
|
50
|
+
def load_single_agent(
|
51
|
+
self, agent_file: Path
|
52
|
+
) -> Tuple[Optional[str], Optional[str]]:
|
51
53
|
"""
|
52
54
|
Load a single agent file.
|
53
55
|
|
@@ -120,7 +122,9 @@ class AgentLoader:
|
|
120
122
|
|
121
123
|
# Check for local JSON templates in priority order
|
122
124
|
template_dirs = [
|
123
|
-
Path.cwd()
|
125
|
+
Path.cwd()
|
126
|
+
/ ".claude-mpm"
|
127
|
+
/ "agents", # Project local agents (highest priority)
|
124
128
|
Path.home() / ".claude-mpm" / "agents", # User local agents
|
125
129
|
]
|
126
130
|
|
@@ -199,4 +203,4 @@ class AgentLoader:
|
|
199
203
|
if "," in tools:
|
200
204
|
return tools
|
201
205
|
return tools
|
202
|
-
return "Standard Tools"
|
206
|
+
return "Standard Tools"
|
@@ -66,7 +66,9 @@ class FileLoader:
|
|
66
66
|
if "INSTRUCTIONS.md" in str(file_path):
|
67
67
|
self.framework_last_modified = timestamp
|
68
68
|
|
69
|
-
def load_instructions_file(
|
69
|
+
def load_instructions_file(
|
70
|
+
self, current_dir: Path
|
71
|
+
) -> tuple[Optional[str], Optional[str]]:
|
70
72
|
"""
|
71
73
|
Load custom INSTRUCTIONS.md from .claude-mpm directories.
|
72
74
|
|
@@ -106,7 +108,9 @@ class FileLoader:
|
|
106
108
|
|
107
109
|
return None, None
|
108
110
|
|
109
|
-
def load_workflow_file(
|
111
|
+
def load_workflow_file(
|
112
|
+
self, current_dir: Path, framework_path: Path
|
113
|
+
) -> tuple[Optional[str], Optional[str]]:
|
110
114
|
"""
|
111
115
|
Load WORKFLOW.md from various locations.
|
112
116
|
|
@@ -148,7 +152,9 @@ class FileLoader:
|
|
148
152
|
|
149
153
|
# Fall back to system workflow (lowest priority)
|
150
154
|
if framework_path and framework_path != Path("__PACKAGED__"):
|
151
|
-
system_workflow_path =
|
155
|
+
system_workflow_path = (
|
156
|
+
framework_path / "src" / "claude_mpm" / "agents" / "WORKFLOW.md"
|
157
|
+
)
|
152
158
|
if system_workflow_path.exists():
|
153
159
|
loaded_content = self.try_load_file(
|
154
160
|
system_workflow_path, "system WORKFLOW.md"
|
@@ -159,7 +165,9 @@ class FileLoader:
|
|
159
165
|
|
160
166
|
return None, None
|
161
167
|
|
162
|
-
def load_memory_file(
|
168
|
+
def load_memory_file(
|
169
|
+
self, current_dir: Path, framework_path: Path
|
170
|
+
) -> tuple[Optional[str], Optional[str]]:
|
163
171
|
"""
|
164
172
|
Load MEMORY.md from various locations.
|
165
173
|
|
@@ -201,7 +209,9 @@ class FileLoader:
|
|
201
209
|
|
202
210
|
# Fall back to system memory instructions (lowest priority)
|
203
211
|
if framework_path and framework_path != Path("__PACKAGED__"):
|
204
|
-
system_memory_path =
|
212
|
+
system_memory_path = (
|
213
|
+
framework_path / "src" / "claude_mpm" / "agents" / "MEMORY.md"
|
214
|
+
)
|
205
215
|
if system_memory_path.exists():
|
206
216
|
loaded_content = self.try_load_file(
|
207
217
|
system_memory_path, "system MEMORY.md"
|
@@ -210,4 +220,4 @@ class FileLoader:
|
|
210
220
|
self.logger.info("Using system memory instructions")
|
211
221
|
return loaded_content, "system"
|
212
222
|
|
213
|
-
return None, None
|
223
|
+
return None, None
|
@@ -75,14 +75,18 @@ class InstructionLoader:
|
|
75
75
|
content["instructions_version"] = self.file_loader.framework_version
|
76
76
|
content["version"] = self.file_loader.framework_version
|
77
77
|
if self.file_loader.framework_last_modified:
|
78
|
-
content["instructions_last_modified"] =
|
78
|
+
content["instructions_last_modified"] = (
|
79
|
+
self.file_loader.framework_last_modified
|
80
|
+
)
|
79
81
|
|
80
82
|
# Transfer metadata from packaged loader if available
|
81
83
|
if self.packaged_loader.framework_version:
|
82
84
|
content["instructions_version"] = self.packaged_loader.framework_version
|
83
85
|
content["version"] = self.packaged_loader.framework_version
|
84
86
|
if self.packaged_loader.framework_last_modified:
|
85
|
-
content["instructions_last_modified"] =
|
87
|
+
content["instructions_last_modified"] = (
|
88
|
+
self.packaged_loader.framework_last_modified
|
89
|
+
)
|
86
90
|
|
87
91
|
def _load_filesystem_framework_instructions(self, content: Dict[str, Any]) -> None:
|
88
92
|
"""Load framework instructions from filesystem.
|
@@ -120,7 +124,9 @@ class InstructionLoader:
|
|
120
124
|
)
|
121
125
|
|
122
126
|
# Load BASE_PM.md for core framework requirements
|
123
|
-
base_pm_path =
|
127
|
+
base_pm_path = (
|
128
|
+
self.framework_path / "src" / "claude_mpm" / "agents" / "BASE_PM.md"
|
129
|
+
)
|
124
130
|
if base_pm_path.exists():
|
125
131
|
base_pm_content = self.file_loader.try_load_file(
|
126
132
|
base_pm_path, "BASE_PM framework requirements"
|
@@ -134,7 +140,9 @@ class InstructionLoader:
|
|
134
140
|
Args:
|
135
141
|
content: Dictionary to update with workflow instructions
|
136
142
|
"""
|
137
|
-
workflow, level = self.file_loader.load_workflow_file(
|
143
|
+
workflow, level = self.file_loader.load_workflow_file(
|
144
|
+
self.current_dir, self.framework_path
|
145
|
+
)
|
138
146
|
if workflow:
|
139
147
|
content["workflow_instructions"] = workflow
|
140
148
|
content["workflow_instructions_level"] = level
|
@@ -145,7 +153,9 @@ class InstructionLoader:
|
|
145
153
|
Args:
|
146
154
|
content: Dictionary to update with memory instructions
|
147
155
|
"""
|
148
|
-
memory, level = self.file_loader.load_memory_file(
|
156
|
+
memory, level = self.file_loader.load_memory_file(
|
157
|
+
self.current_dir, self.framework_path
|
158
|
+
)
|
149
159
|
if memory:
|
150
160
|
content["memory_instructions"] = memory
|
151
|
-
content["memory_instructions_level"] = level
|
161
|
+
content["memory_instructions_level"] = level
|
@@ -68,7 +68,9 @@ class PackagedLoader:
|
|
68
68
|
self.logger.warning(f"File {filename} not found in package")
|
69
69
|
return None
|
70
70
|
except Exception as e:
|
71
|
-
self.logger.error(
|
71
|
+
self.logger.error(
|
72
|
+
f"Failed to load {filename} from package with fallback: {e}"
|
73
|
+
)
|
72
74
|
return None
|
73
75
|
|
74
76
|
def extract_metadata_from_content(self, content: str, filename: str) -> None:
|
@@ -97,7 +99,9 @@ class PackagedLoader:
|
|
97
99
|
content: Dictionary to update with loaded content
|
98
100
|
"""
|
99
101
|
if not files:
|
100
|
-
self.logger.warning(
|
102
|
+
self.logger.warning(
|
103
|
+
"importlib.resources not available, cannot load packaged framework"
|
104
|
+
)
|
101
105
|
self.logger.debug(f"files variable is: {files}")
|
102
106
|
# Try alternative import methods
|
103
107
|
try:
|
@@ -107,7 +111,9 @@ class PackagedLoader:
|
|
107
111
|
self.load_framework_content_fallback(content, resources)
|
108
112
|
return
|
109
113
|
except ImportError:
|
110
|
-
self.logger.error(
|
114
|
+
self.logger.error(
|
115
|
+
"No importlib.resources available, using minimal framework"
|
116
|
+
)
|
111
117
|
return
|
112
118
|
|
113
119
|
try:
|
@@ -118,7 +124,9 @@ class PackagedLoader:
|
|
118
124
|
content["loaded"] = True
|
119
125
|
self.logger.info("Loaded consolidated PM_INSTRUCTIONS.md from package")
|
120
126
|
# Extract and store version/timestamp metadata
|
121
|
-
self.extract_metadata_from_content(
|
127
|
+
self.extract_metadata_from_content(
|
128
|
+
pm_instructions_content, "PM_INSTRUCTIONS.md"
|
129
|
+
)
|
122
130
|
else:
|
123
131
|
# Fall back to legacy INSTRUCTIONS.md
|
124
132
|
instructions_content = self.load_packaged_file("INSTRUCTIONS.md")
|
@@ -127,7 +135,9 @@ class PackagedLoader:
|
|
127
135
|
content["loaded"] = True
|
128
136
|
self.logger.warning("Using legacy INSTRUCTIONS.md from package")
|
129
137
|
# Extract and store version/timestamp metadata
|
130
|
-
self.extract_metadata_from_content(
|
138
|
+
self.extract_metadata_from_content(
|
139
|
+
instructions_content, "INSTRUCTIONS.md"
|
140
|
+
)
|
131
141
|
|
132
142
|
if self.framework_version:
|
133
143
|
content["instructions_version"] = self.framework_version
|
@@ -155,7 +165,9 @@ class PackagedLoader:
|
|
155
165
|
except Exception as e:
|
156
166
|
self.logger.error(f"Failed to load packaged framework content: {e}")
|
157
167
|
|
158
|
-
def load_framework_content_fallback(
|
168
|
+
def load_framework_content_fallback(
|
169
|
+
self, content: Dict[str, Any], resources
|
170
|
+
) -> None:
|
159
171
|
"""Load framework content using importlib.resources fallback.
|
160
172
|
|
161
173
|
Args:
|
@@ -164,22 +176,30 @@ class PackagedLoader:
|
|
164
176
|
"""
|
165
177
|
try:
|
166
178
|
# Try new consolidated PM_INSTRUCTIONS.md first
|
167
|
-
pm_instructions_content = self.load_packaged_file_fallback(
|
179
|
+
pm_instructions_content = self.load_packaged_file_fallback(
|
180
|
+
"PM_INSTRUCTIONS.md", resources
|
181
|
+
)
|
168
182
|
if pm_instructions_content:
|
169
183
|
content["framework_instructions"] = pm_instructions_content
|
170
184
|
content["loaded"] = True
|
171
185
|
self.logger.info("Loaded consolidated PM_INSTRUCTIONS.md via fallback")
|
172
186
|
# Extract and store version/timestamp metadata
|
173
|
-
self.extract_metadata_from_content(
|
187
|
+
self.extract_metadata_from_content(
|
188
|
+
pm_instructions_content, "PM_INSTRUCTIONS.md"
|
189
|
+
)
|
174
190
|
else:
|
175
191
|
# Fall back to legacy INSTRUCTIONS.md
|
176
|
-
instructions_content = self.load_packaged_file_fallback(
|
192
|
+
instructions_content = self.load_packaged_file_fallback(
|
193
|
+
"INSTRUCTIONS.md", resources
|
194
|
+
)
|
177
195
|
if instructions_content:
|
178
196
|
content["framework_instructions"] = instructions_content
|
179
197
|
content["loaded"] = True
|
180
198
|
self.logger.warning("Using legacy INSTRUCTIONS.md via fallback")
|
181
199
|
# Extract and store version/timestamp metadata
|
182
|
-
self.extract_metadata_from_content(
|
200
|
+
self.extract_metadata_from_content(
|
201
|
+
instructions_content, "INSTRUCTIONS.md"
|
202
|
+
)
|
183
203
|
|
184
204
|
if self.framework_version:
|
185
205
|
content["instructions_version"] = self.framework_version
|
@@ -193,7 +213,9 @@ class PackagedLoader:
|
|
193
213
|
content["base_pm_instructions"] = base_pm_content
|
194
214
|
|
195
215
|
# Load WORKFLOW.md
|
196
|
-
workflow_content = self.load_packaged_file_fallback(
|
216
|
+
workflow_content = self.load_packaged_file_fallback(
|
217
|
+
"WORKFLOW.md", resources
|
218
|
+
)
|
197
219
|
if workflow_content:
|
198
220
|
content["workflow_instructions"] = workflow_content
|
199
221
|
content["workflow_instructions_level"] = "system"
|
@@ -205,4 +227,6 @@ class PackagedLoader:
|
|
205
227
|
content["memory_instructions_level"] = "system"
|
206
228
|
|
207
229
|
except Exception as e:
|
208
|
-
self.logger.error(
|
230
|
+
self.logger.error(
|
231
|
+
f"Failed to load packaged framework content with fallback: {e}"
|
232
|
+
)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
"""Memory content processor for framework memory management."""
|
2
2
|
|
3
3
|
from pathlib import Path
|
4
|
-
from typing import Any, Dict,
|
4
|
+
from typing import Any, Dict, Set
|
5
5
|
|
6
6
|
from claude_mpm.core.logging_utils import get_logger
|
7
7
|
|
@@ -28,7 +28,9 @@ class MemoryProcessor:
|
|
28
28
|
content = project_memory_file.read_text()
|
29
29
|
memories["actual_memories"] = content
|
30
30
|
memories["memory_source"] = "project"
|
31
|
-
self.logger.info(
|
31
|
+
self.logger.info(
|
32
|
+
f"Loaded PM memories from project: {project_memory_file}"
|
33
|
+
)
|
32
34
|
return memories
|
33
35
|
except Exception as e:
|
34
36
|
self.logger.error(f"Failed to load project PM memories: {e}")
|
@@ -74,10 +76,14 @@ class MemoryProcessor:
|
|
74
76
|
try:
|
75
77
|
content = memory_file.read_text()
|
76
78
|
agent_memories[agent_name] = content
|
77
|
-
self.logger.debug(
|
79
|
+
self.logger.debug(
|
80
|
+
f"Loaded memories for {agent_name} from {memory_file}"
|
81
|
+
)
|
78
82
|
break # Use first found (project > user)
|
79
83
|
except Exception as e:
|
80
|
-
self.logger.error(
|
84
|
+
self.logger.error(
|
85
|
+
f"Failed to load memories for {agent_name}: {e}"
|
86
|
+
)
|
81
87
|
|
82
88
|
return agent_memories
|
83
89
|
|
@@ -217,6 +223,8 @@ class MemoryProcessor:
|
|
217
223
|
self.logger.info(f"Migrated memories from {old_path} to {new_path}")
|
218
224
|
migrated = True
|
219
225
|
except Exception as e:
|
220
|
-
self.logger.error(
|
226
|
+
self.logger.error(
|
227
|
+
f"Failed to migrate memories from {old_path}: {e}"
|
228
|
+
)
|
221
229
|
|
222
|
-
return migrated
|
230
|
+
return migrated
|
@@ -61,7 +61,9 @@ class MetadataProcessor:
|
|
61
61
|
# Default values
|
62
62
|
agent_data = {
|
63
63
|
"id": agent_file.stem,
|
64
|
-
"display_name": agent_file.stem.replace("_", " ")
|
64
|
+
"display_name": agent_file.stem.replace("_", " ")
|
65
|
+
.replace("-", " ")
|
66
|
+
.title(),
|
65
67
|
"description": "Specialized agent",
|
66
68
|
"file_path": str(agent_file),
|
67
69
|
"file_mtime": agent_file.stat().st_mtime,
|
@@ -96,9 +98,7 @@ class MetadataProcessor:
|
|
96
98
|
self.logger.debug(f"Could not parse metadata from {agent_file}: {e}")
|
97
99
|
return None
|
98
100
|
|
99
|
-
def extract_cache_metadata(
|
100
|
-
self, data: Any, cache_key: str
|
101
|
-
) -> Tuple[Any, float]:
|
101
|
+
def extract_cache_metadata(self, data: Any, cache_key: str) -> Tuple[Any, float]:
|
102
102
|
"""Extract cache metadata for storage.
|
103
103
|
|
104
104
|
Args:
|
@@ -143,4 +143,4 @@ class MetadataProcessor:
|
|
143
143
|
return True
|
144
144
|
except Exception as e:
|
145
145
|
self.logger.debug(f"Cache validation failed: {e}")
|
146
|
-
return False
|
146
|
+
return False
|
@@ -82,7 +82,9 @@ class TemplateProcessor:
|
|
82
82
|
Returns:
|
83
83
|
Template data or None if not found
|
84
84
|
"""
|
85
|
-
templates_dir =
|
85
|
+
templates_dir = (
|
86
|
+
self.framework_path / "src" / "claude_mpm" / "agents" / "templates"
|
87
|
+
)
|
86
88
|
|
87
89
|
# Try exact match first
|
88
90
|
template_file = templates_dir / f"{agent_name}.json"
|
@@ -114,8 +116,8 @@ class TemplateProcessor:
|
|
114
116
|
{
|
115
117
|
agent_name.replace("-", "_"), # api-qa -> api_qa
|
116
118
|
agent_name.replace("_", "-"), # api_qa -> api-qa
|
117
|
-
agent_name.replace("-", ""),
|
118
|
-
agent_name.replace("_", ""),
|
119
|
+
agent_name.replace("-", ""), # api-qa -> apiqa
|
120
|
+
agent_name.replace("_", ""), # api_qa -> apiqa
|
119
121
|
agent_name.replace("-agent", ""), # research-agent -> research
|
120
122
|
agent_name.replace("_agent", ""), # research_agent -> research
|
121
123
|
agent_name + "_agent", # research -> research_agent
|
@@ -123,7 +125,9 @@ class TemplateProcessor:
|
|
123
125
|
}
|
124
126
|
)
|
125
127
|
|
126
|
-
def extract_routing(
|
128
|
+
def extract_routing(
|
129
|
+
self, template_data: Dict[str, Any]
|
130
|
+
) -> Optional[Dict[str, Any]]:
|
127
131
|
"""Extract routing information from template.
|
128
132
|
|
129
133
|
Args:
|
@@ -134,7 +138,9 @@ class TemplateProcessor:
|
|
134
138
|
"""
|
135
139
|
return template_data.get("routing")
|
136
140
|
|
137
|
-
def extract_memory_routing(
|
141
|
+
def extract_memory_routing(
|
142
|
+
self, template_data: Dict[str, Any]
|
143
|
+
) -> Optional[Dict[str, Any]]:
|
138
144
|
"""Extract memory routing information from template.
|
139
145
|
|
140
146
|
Args:
|
@@ -235,4 +241,4 @@ class TemplateProcessor:
|
|
235
241
|
except Exception as e:
|
236
242
|
self.logger.warning(f"Failed to process template {json_file}: {e}")
|
237
243
|
|
238
|
-
return local_agents
|
244
|
+
return local_agents
|