claude-mpm 4.5.8__py3-none-any.whl → 4.5.12__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/__init__.py +20 -5
- claude_mpm/agents/agent_loader.py +19 -2
- claude_mpm/agents/base_agent_loader.py +5 -5
- claude_mpm/agents/frontmatter_validator.py +4 -4
- claude_mpm/agents/templates/agent-manager.json +3 -3
- claude_mpm/agents/templates/agentic-coder-optimizer.json +3 -3
- claude_mpm/agents/templates/api_qa.json +1 -1
- claude_mpm/agents/templates/clerk-ops.json +3 -3
- claude_mpm/agents/templates/code_analyzer.json +3 -3
- claude_mpm/agents/templates/dart_engineer.json +294 -0
- claude_mpm/agents/templates/data_engineer.json +3 -3
- claude_mpm/agents/templates/documentation.json +2 -2
- claude_mpm/agents/templates/engineer.json +2 -2
- claude_mpm/agents/templates/gcp_ops_agent.json +2 -2
- claude_mpm/agents/templates/imagemagick.json +1 -1
- claude_mpm/agents/templates/local_ops_agent.json +319 -41
- claude_mpm/agents/templates/memory_manager.json +2 -2
- claude_mpm/agents/templates/nextjs_engineer.json +2 -2
- claude_mpm/agents/templates/ops.json +2 -2
- claude_mpm/agents/templates/php-engineer.json +1 -1
- claude_mpm/agents/templates/project_organizer.json +1 -1
- claude_mpm/agents/templates/prompt-engineer.json +6 -4
- claude_mpm/agents/templates/python_engineer.json +2 -2
- claude_mpm/agents/templates/qa.json +1 -1
- claude_mpm/agents/templates/react_engineer.json +3 -3
- claude_mpm/agents/templates/refactoring_engineer.json +3 -3
- claude_mpm/agents/templates/research.json +2 -2
- claude_mpm/agents/templates/security.json +2 -2
- claude_mpm/agents/templates/ticketing.json +2 -2
- claude_mpm/agents/templates/typescript_engineer.json +2 -2
- claude_mpm/agents/templates/vercel_ops_agent.json +2 -2
- claude_mpm/agents/templates/version_control.json +2 -2
- claude_mpm/agents/templates/web_qa.json +6 -6
- claude_mpm/agents/templates/web_ui.json +3 -3
- claude_mpm/cli/__init__.py +49 -19
- claude_mpm/cli/commands/agent_manager.py +3 -3
- claude_mpm/cli/commands/agents.py +6 -6
- claude_mpm/cli/commands/aggregate.py +4 -4
- claude_mpm/cli/commands/analyze.py +2 -2
- claude_mpm/cli/commands/analyze_code.py +1 -1
- claude_mpm/cli/commands/cleanup.py +3 -3
- claude_mpm/cli/commands/config.py +2 -2
- claude_mpm/cli/commands/configure.py +605 -21
- claude_mpm/cli/commands/dashboard.py +1 -1
- claude_mpm/cli/commands/debug.py +3 -3
- claude_mpm/cli/commands/doctor.py +1 -1
- claude_mpm/cli/commands/mcp.py +7 -7
- claude_mpm/cli/commands/mcp_command_router.py +1 -1
- claude_mpm/cli/commands/mcp_config.py +2 -2
- claude_mpm/cli/commands/mcp_external_commands.py +2 -2
- claude_mpm/cli/commands/mcp_install_commands.py +3 -3
- claude_mpm/cli/commands/mcp_pipx_config.py +2 -2
- claude_mpm/cli/commands/mcp_setup_external.py +3 -3
- claude_mpm/cli/commands/monitor.py +1 -1
- claude_mpm/cli/commands/mpm_init_handler.py +1 -1
- claude_mpm/cli/interactive/agent_wizard.py +1 -1
- claude_mpm/cli/parsers/configure_parser.py +5 -0
- claude_mpm/cli/parsers/search_parser.py +1 -1
- claude_mpm/cli/shared/argument_patterns.py +2 -2
- claude_mpm/cli/shared/base_command.py +1 -1
- claude_mpm/cli/startup_logging.py +4 -4
- claude_mpm/config/experimental_features.py +4 -4
- claude_mpm/config/socketio_config.py +2 -2
- claude_mpm/core/__init__.py +53 -17
- claude_mpm/core/agent_session_manager.py +2 -2
- claude_mpm/core/api_validator.py +3 -3
- claude_mpm/core/base_service.py +10 -1
- claude_mpm/core/cache.py +2 -2
- claude_mpm/core/config.py +5 -5
- claude_mpm/core/config_aliases.py +4 -4
- claude_mpm/core/config_constants.py +1 -1
- claude_mpm/core/error_handler.py +1 -1
- claude_mpm/core/file_utils.py +5 -5
- claude_mpm/core/framework/formatters/capability_generator.py +5 -5
- claude_mpm/core/framework/loaders/agent_loader.py +1 -1
- claude_mpm/core/framework/processors/metadata_processor.py +1 -1
- claude_mpm/core/framework/processors/template_processor.py +3 -3
- claude_mpm/core/framework_loader.py +2 -2
- claude_mpm/core/log_manager.py +11 -4
- claude_mpm/core/logger.py +2 -2
- claude_mpm/core/optimized_startup.py +1 -1
- claude_mpm/core/output_style_manager.py +1 -1
- claude_mpm/core/service_registry.py +2 -2
- claude_mpm/core/session_manager.py +3 -3
- claude_mpm/core/shared/config_loader.py +1 -1
- claude_mpm/core/socketio_pool.py +2 -2
- claude_mpm/core/unified_agent_registry.py +2 -2
- claude_mpm/core/unified_config.py +6 -6
- claude_mpm/core/unified_paths.py +2 -2
- claude_mpm/dashboard/api/simple_directory.py +1 -1
- claude_mpm/generators/agent_profile_generator.py +1 -1
- claude_mpm/hooks/claude_hooks/event_handlers.py +2 -2
- claude_mpm/hooks/claude_hooks/installer.py +9 -9
- claude_mpm/hooks/claude_hooks/response_tracking.py +16 -11
- claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +16 -13
- claude_mpm/hooks/claude_hooks/tool_analysis.py +2 -2
- claude_mpm/hooks/memory_integration_hook.py +1 -1
- claude_mpm/hooks/validation_hooks.py +1 -1
- claude_mpm/init.py +4 -4
- claude_mpm/models/agent_session.py +1 -1
- claude_mpm/scripts/socketio_daemon.py +5 -5
- claude_mpm/services/__init__.py +145 -161
- claude_mpm/services/agent_capabilities_service.py +1 -1
- claude_mpm/services/agents/agent_builder.py +4 -4
- claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +1 -1
- claude_mpm/services/agents/deployment/agent_metrics_collector.py +1 -1
- claude_mpm/services/agents/deployment/agent_record_service.py +3 -3
- claude_mpm/services/agents/deployment/deployment_config_loader.py +21 -0
- claude_mpm/services/agents/deployment/deployment_wrapper.py +1 -1
- claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +2 -2
- claude_mpm/services/agents/loading/agent_profile_loader.py +2 -2
- claude_mpm/services/agents/loading/base_agent_manager.py +12 -2
- claude_mpm/services/agents/local_template_manager.py +5 -5
- claude_mpm/services/agents/registry/deployed_agent_discovery.py +1 -1
- claude_mpm/services/agents/registry/modification_tracker.py +19 -11
- claude_mpm/services/async_session_logger.py +3 -3
- claude_mpm/services/claude_session_logger.py +4 -4
- claude_mpm/services/cli/agent_listing_service.py +3 -3
- claude_mpm/services/cli/agent_validation_service.py +1 -1
- claude_mpm/services/cli/session_manager.py +2 -2
- claude_mpm/services/core/path_resolver.py +1 -1
- claude_mpm/services/diagnostics/checks/agent_check.py +1 -1
- claude_mpm/services/diagnostics/checks/claude_code_check.py +2 -2
- claude_mpm/services/diagnostics/checks/common_issues_check.py +3 -3
- claude_mpm/services/diagnostics/checks/configuration_check.py +2 -2
- claude_mpm/services/diagnostics/checks/installation_check.py +1 -1
- claude_mpm/services/diagnostics/checks/mcp_check.py +1 -1
- claude_mpm/services/diagnostics/checks/mcp_services_check.py +9 -9
- claude_mpm/services/diagnostics/checks/monitor_check.py +1 -1
- claude_mpm/services/diagnostics/doctor_reporter.py +1 -1
- claude_mpm/services/event_aggregator.py +1 -1
- claude_mpm/services/event_bus/event_bus.py +7 -2
- claude_mpm/services/events/consumers/dead_letter.py +2 -2
- claude_mpm/services/framework_claude_md_generator/__init__.py +1 -1
- claude_mpm/services/framework_claude_md_generator/deployment_manager.py +3 -3
- claude_mpm/services/framework_claude_md_generator/version_manager.py +1 -1
- claude_mpm/services/hook_installer_service.py +7 -7
- claude_mpm/services/infrastructure/context_preservation.py +7 -7
- claude_mpm/services/infrastructure/daemon_manager.py +5 -5
- claude_mpm/services/mcp_config_manager.py +169 -48
- claude_mpm/services/mcp_gateway/__init__.py +98 -94
- claude_mpm/services/mcp_gateway/auto_configure.py +5 -5
- claude_mpm/services/mcp_gateway/config/config_loader.py +2 -2
- claude_mpm/services/mcp_gateway/config/configuration.py +3 -3
- claude_mpm/services/mcp_gateway/core/process_pool.py +3 -3
- claude_mpm/services/mcp_gateway/core/singleton_manager.py +2 -2
- claude_mpm/services/mcp_gateway/core/startup_verification.py +1 -1
- claude_mpm/services/mcp_gateway/main.py +1 -1
- claude_mpm/services/mcp_gateway/registry/service_registry.py +4 -2
- claude_mpm/services/mcp_gateway/registry/tool_registry.py +2 -1
- claude_mpm/services/mcp_gateway/server/stdio_handler.py +1 -1
- claude_mpm/services/mcp_gateway/tools/document_summarizer.py +1 -1
- claude_mpm/services/mcp_gateway/tools/health_check_tool.py +1 -1
- claude_mpm/services/mcp_gateway/tools/hello_world.py +1 -1
- claude_mpm/services/mcp_gateway/utils/package_version_checker.py +5 -5
- claude_mpm/services/mcp_gateway/utils/update_preferences.py +2 -2
- claude_mpm/services/mcp_service_verifier.py +1 -1
- claude_mpm/services/memory/builder.py +1 -1
- claude_mpm/services/memory/cache/shared_prompt_cache.py +2 -1
- claude_mpm/services/memory/indexed_memory.py +3 -3
- claude_mpm/services/monitor/daemon.py +1 -1
- claude_mpm/services/monitor/daemon_manager.py +9 -9
- claude_mpm/services/monitor/event_emitter.py +1 -1
- claude_mpm/services/monitor/handlers/file.py +1 -1
- claude_mpm/services/monitor/handlers/hooks.py +3 -3
- claude_mpm/services/monitor/management/lifecycle.py +7 -7
- claude_mpm/services/monitor/server.py +2 -2
- claude_mpm/services/orphan_detection.py +788 -0
- claude_mpm/services/port_manager.py +2 -2
- claude_mpm/services/project/analyzer.py +3 -3
- claude_mpm/services/project/archive_manager.py +13 -13
- claude_mpm/services/project/dependency_analyzer.py +4 -4
- claude_mpm/services/project/documentation_manager.py +4 -4
- claude_mpm/services/project/enhanced_analyzer.py +8 -8
- claude_mpm/services/project/registry.py +4 -4
- claude_mpm/services/project_port_allocator.py +597 -0
- claude_mpm/services/response_tracker.py +1 -1
- claude_mpm/services/session_management_service.py +1 -1
- claude_mpm/services/session_manager.py +6 -4
- claude_mpm/services/socketio/event_normalizer.py +1 -1
- claude_mpm/services/socketio/handlers/code_analysis.py +14 -12
- claude_mpm/services/socketio/handlers/file.py +1 -1
- claude_mpm/services/socketio/migration_utils.py +1 -1
- claude_mpm/services/socketio/server/core.py +1 -1
- claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +1 -1
- claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +4 -4
- claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +1 -1
- claude_mpm/services/unified/config_strategies/config_schema.py +4 -4
- claude_mpm/services/unified/config_strategies/context_strategy.py +6 -6
- claude_mpm/services/unified/config_strategies/error_handling_strategy.py +10 -10
- claude_mpm/services/unified/config_strategies/file_loader_strategy.py +5 -5
- claude_mpm/services/unified/config_strategies/unified_config_service.py +8 -8
- claude_mpm/services/unified/config_strategies/validation_strategy.py +15 -15
- claude_mpm/services/unified/deployment_strategies/base.py +4 -4
- claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +15 -15
- claude_mpm/services/unified/deployment_strategies/local.py +9 -9
- claude_mpm/services/unified/deployment_strategies/utils.py +9 -9
- claude_mpm/services/unified/deployment_strategies/vercel.py +7 -7
- claude_mpm/services/unified/unified_config.py +5 -5
- claude_mpm/services/unified/unified_deployment.py +2 -2
- claude_mpm/services/utility_service.py +1 -1
- claude_mpm/services/version_control/conflict_resolution.py +2 -2
- claude_mpm/services/version_control/git_operations.py +3 -3
- claude_mpm/services/version_control/semantic_versioning.py +13 -13
- claude_mpm/services/version_control/version_parser.py +1 -1
- claude_mpm/storage/state_storage.py +12 -13
- claude_mpm/tools/code_tree_analyzer.py +5 -5
- claude_mpm/tools/code_tree_builder.py +4 -4
- claude_mpm/tools/socketio_debug.py +1 -1
- claude_mpm/utils/agent_dependency_loader.py +4 -4
- claude_mpm/utils/common.py +2 -2
- claude_mpm/utils/config_manager.py +3 -3
- claude_mpm/utils/dependency_cache.py +2 -2
- claude_mpm/utils/dependency_strategies.py +6 -6
- claude_mpm/utils/file_utils.py +11 -11
- claude_mpm/utils/log_cleanup.py +1 -1
- claude_mpm/utils/path_operations.py +1 -1
- claude_mpm/validation/agent_validator.py +2 -2
- claude_mpm/validation/frontmatter_validator.py +1 -1
- {claude_mpm-4.5.8.dist-info → claude_mpm-4.5.12.dist-info}/METADATA +1 -1
- {claude_mpm-4.5.8.dist-info → claude_mpm-4.5.12.dist-info}/RECORD +226 -223
- {claude_mpm-4.5.8.dist-info → claude_mpm-4.5.12.dist-info}/WHEEL +0 -0
- {claude_mpm-4.5.8.dist-info → claude_mpm-4.5.12.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.5.8.dist-info → claude_mpm-4.5.12.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.5.8.dist-info → claude_mpm-4.5.12.dist-info}/top_level.txt +0 -0
claude_mpm/init.py
CHANGED
@@ -270,11 +270,11 @@ class ProjectInitializer:
|
|
270
270
|
"""
|
271
271
|
try:
|
272
272
|
# Read existing JSON configuration
|
273
|
-
with open(
|
273
|
+
with old_file.open() as f:
|
274
274
|
config = json.load(f)
|
275
275
|
|
276
276
|
# Write as YAML
|
277
|
-
with open(
|
277
|
+
with new_file.open("w") as f:
|
278
278
|
yaml.dump(config, f, default_flow_style=False, sort_keys=False)
|
279
279
|
|
280
280
|
self.logger.info(
|
@@ -310,7 +310,7 @@ class ProjectInitializer:
|
|
310
310
|
},
|
311
311
|
}
|
312
312
|
|
313
|
-
with open(
|
313
|
+
with config_file.open("w") as f:
|
314
314
|
yaml.dump(default_config, f, default_flow_style=False, sort_keys=False)
|
315
315
|
|
316
316
|
def _create_project_config(self, config_file: Path):
|
@@ -322,7 +322,7 @@ class ProjectInitializer:
|
|
322
322
|
"tickets": {"auto_create": True, "prefix": "TSK"},
|
323
323
|
}
|
324
324
|
|
325
|
-
with open(
|
325
|
+
with config_file.open("w") as f:
|
326
326
|
json.dump(project_config, f, indent=2)
|
327
327
|
|
328
328
|
def _copy_agent_templates(self):
|
@@ -448,7 +448,7 @@ class AgentSession:
|
|
448
448
|
filepath = directory / filename
|
449
449
|
|
450
450
|
# Save to file
|
451
|
-
with open(
|
451
|
+
with filepath.open("w", encoding="utf-8") as f:
|
452
452
|
json.dump(self.to_dict(), f, indent=2, ensure_ascii=False)
|
453
453
|
|
454
454
|
return str(filepath)
|
@@ -37,7 +37,7 @@ def is_running(pid_file: Path) -> bool:
|
|
37
37
|
return False
|
38
38
|
|
39
39
|
try:
|
40
|
-
with open(
|
40
|
+
with pid_file.open() as f:
|
41
41
|
pid = int(f.read().strip())
|
42
42
|
|
43
43
|
# Check if process exists
|
@@ -85,7 +85,7 @@ def start_server(port: int = DEFAULT_PORT, daemon: bool = True) -> bool:
|
|
85
85
|
logger.info(f"Socket.IO daemon started on port {actual_port}")
|
86
86
|
# Save the port for clients to discover
|
87
87
|
port_file = pid_file.parent / "socketio-port"
|
88
|
-
with open(
|
88
|
+
with port_file.open("w") as f:
|
89
89
|
f.write(str(actual_port))
|
90
90
|
else:
|
91
91
|
logger.error("Failed to start Socket.IO daemon")
|
@@ -102,7 +102,7 @@ def stop_server() -> bool:
|
|
102
102
|
return False
|
103
103
|
|
104
104
|
try:
|
105
|
-
with open(
|
105
|
+
with pid_file.open() as f:
|
106
106
|
pid = int(f.read().strip())
|
107
107
|
|
108
108
|
# Send SIGTERM for graceful shutdown
|
@@ -155,12 +155,12 @@ def status_server() -> bool:
|
|
155
155
|
|
156
156
|
if is_running(pid_file):
|
157
157
|
try:
|
158
|
-
with open(
|
158
|
+
with pid_file.open() as f:
|
159
159
|
pid = int(f.read().strip())
|
160
160
|
|
161
161
|
port = DEFAULT_PORT
|
162
162
|
if port_file.exists():
|
163
|
-
with open(
|
163
|
+
with port_file.open() as f:
|
164
164
|
port = int(f.read().strip())
|
165
165
|
|
166
166
|
print(f"Socket.IO daemon is running (PID: {pid}, Port: {port})")
|
claude_mpm/services/__init__.py
CHANGED
@@ -13,169 +13,152 @@ New structure:
|
|
13
13
|
|
14
14
|
|
15
15
|
# Use lazy imports to prevent circular dependency issues
|
16
|
-
def __getattr__(name):
|
17
|
-
"""Lazy import to prevent circular dependencies."""
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
#
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
16
|
+
def __getattr__(name):
|
17
|
+
"""Lazy import to prevent circular dependencies using dictionary-based mapping."""
|
18
|
+
from importlib import import_module
|
19
|
+
|
20
|
+
# Dictionary mapping: name -> (module_path, attribute_name)
|
21
|
+
# For agent services, we import from the __init__.py modules to respect their import structure
|
22
|
+
_LAZY_IMPORTS = {
|
23
|
+
# Agent services - use __init__.py modules (not direct file paths) to respect import structure
|
24
|
+
"AgentDeploymentService": (
|
25
|
+
"claude_mpm.services.agents.deployment",
|
26
|
+
"AgentDeploymentService",
|
27
|
+
),
|
28
|
+
"AgentMemoryManager": (
|
29
|
+
"claude_mpm.services.agents.memory",
|
30
|
+
"AgentMemoryManager",
|
31
|
+
),
|
32
|
+
"get_memory_manager": (
|
33
|
+
"claude_mpm.services.agents.memory",
|
34
|
+
"get_memory_manager",
|
35
|
+
),
|
36
|
+
"AgentRegistry": ("claude_mpm.services.agents.registry", "AgentRegistry"),
|
37
|
+
"AgentLifecycleManager": (
|
38
|
+
"claude_mpm.services.agents.deployment",
|
39
|
+
"AgentLifecycleManager",
|
40
|
+
),
|
41
|
+
"AgentManager": ("claude_mpm.services.agents.management", "AgentManager"),
|
42
|
+
"AgentCapabilitiesGenerator": (
|
43
|
+
"claude_mpm.services.agents.management",
|
44
|
+
"AgentCapabilitiesGenerator",
|
45
|
+
),
|
46
|
+
"AgentModificationTracker": (
|
47
|
+
"claude_mpm.services.agents.registry",
|
48
|
+
"AgentModificationTracker",
|
49
|
+
),
|
50
|
+
"AgentPersistenceService": (
|
51
|
+
"claude_mpm.services.agents.memory",
|
52
|
+
"AgentPersistenceService",
|
53
|
+
),
|
54
|
+
"AgentProfileLoader": (
|
55
|
+
"claude_mpm.services.agents.loading",
|
56
|
+
"AgentProfileLoader",
|
57
|
+
),
|
58
|
+
"AgentVersionManager": (
|
59
|
+
"claude_mpm.services.agents.deployment",
|
60
|
+
"AgentVersionManager",
|
61
|
+
),
|
62
|
+
"BaseAgentManager": ("claude_mpm.services.agents.loading", "BaseAgentManager"),
|
63
|
+
"DeployedAgentDiscovery": (
|
64
|
+
"claude_mpm.services.agents.registry",
|
65
|
+
"DeployedAgentDiscovery",
|
66
|
+
),
|
67
|
+
"FrameworkAgentLoader": (
|
68
|
+
"claude_mpm.services.agents.loading",
|
69
|
+
"FrameworkAgentLoader",
|
70
|
+
),
|
71
|
+
"AgentManagementService": (
|
72
|
+
"claude_mpm.services.agents.management",
|
73
|
+
"AgentManager",
|
74
|
+
),
|
75
|
+
# Infrastructure services
|
76
|
+
"HookService": ("claude_mpm.services.hook_service", "HookService"),
|
77
|
+
"ProjectAnalyzer": ("claude_mpm.services.project.analyzer", "ProjectAnalyzer"),
|
78
|
+
"AdvancedHealthMonitor": (
|
79
|
+
"claude_mpm.services.infrastructure.monitoring",
|
80
|
+
"AdvancedHealthMonitor",
|
81
|
+
),
|
82
|
+
"HealthMonitor": (
|
83
|
+
"claude_mpm.services.infrastructure.monitoring",
|
84
|
+
"AdvancedHealthMonitor",
|
85
|
+
),
|
86
|
+
"LoggingService": (
|
87
|
+
"claude_mpm.services.infrastructure.logging",
|
88
|
+
"LoggingService",
|
89
|
+
),
|
90
|
+
# Communication services
|
91
|
+
"StandaloneSocketIOServer": (
|
92
|
+
"claude_mpm.services.socketio_server",
|
93
|
+
"SocketIOServer",
|
94
|
+
),
|
95
|
+
"SocketIOServer": ("claude_mpm.services.socketio_server", "SocketIOServer"),
|
96
|
+
"SocketIOClientManager": (
|
97
|
+
"claude_mpm.services.socketio_client_manager",
|
98
|
+
"SocketIOClientManager",
|
99
|
+
),
|
100
|
+
# Memory services
|
101
|
+
"MemoryBuilder": ("claude_mpm.services.memory.builder", "MemoryBuilder"),
|
102
|
+
"MemoryRouter": ("claude_mpm.services.memory.router", "MemoryRouter"),
|
103
|
+
"MemoryOptimizer": ("claude_mpm.services.memory.optimizer", "MemoryOptimizer"),
|
104
|
+
"SimpleCacheService": (
|
105
|
+
"claude_mpm.services.memory.cache.simple_cache",
|
106
|
+
"SimpleCacheService",
|
107
|
+
),
|
108
|
+
"SharedPromptCache": (
|
109
|
+
"claude_mpm.services.memory.cache.shared_prompt_cache",
|
110
|
+
"SharedPromptCache",
|
111
|
+
),
|
112
|
+
# Project services
|
113
|
+
"ProjectRegistry": ("claude_mpm.services.project.registry", "ProjectRegistry"),
|
114
|
+
# MCP Gateway services
|
115
|
+
"MCPConfiguration": (
|
116
|
+
"claude_mpm.services.mcp_gateway.config.configuration",
|
117
|
+
"MCPConfiguration",
|
118
|
+
),
|
119
|
+
"MCPConfigLoader": (
|
120
|
+
"claude_mpm.services.mcp_gateway.config.config_loader",
|
121
|
+
"MCPConfigLoader",
|
122
|
+
),
|
123
|
+
"MCPServer": ("claude_mpm.services.mcp_gateway.server.mcp_server", "MCPServer"),
|
124
|
+
"MCPToolRegistry": (
|
125
|
+
"claude_mpm.services.mcp_gateway.tools.tool_registry",
|
126
|
+
"MCPToolRegistry",
|
127
|
+
),
|
128
|
+
"BaseMCPService": (
|
129
|
+
"claude_mpm.services.mcp_gateway.core.base",
|
130
|
+
"BaseMCPService",
|
131
|
+
),
|
132
|
+
# Other services
|
133
|
+
"TicketManager": ("claude_mpm.services.ticket_manager", "TicketManager"),
|
134
|
+
}
|
135
|
+
|
136
|
+
# Handle direct mappings
|
137
|
+
if name in _LAZY_IMPORTS:
|
138
|
+
module_path, attr_name = _LAZY_IMPORTS[name]
|
139
|
+
module = import_module(module_path)
|
140
|
+
return getattr(module, attr_name)
|
141
|
+
|
142
|
+
# Handle RecoveryManager with special error handling
|
99
143
|
if name == "RecoveryManager":
|
100
144
|
try:
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
return
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
return
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
return MemoryRouter
|
119
|
-
elif name == "MemoryOptimizer":
|
120
|
-
from .memory.optimizer import MemoryOptimizer
|
121
|
-
|
122
|
-
return MemoryOptimizer
|
123
|
-
elif name == "SimpleCacheService":
|
124
|
-
from .memory.cache.simple_cache import SimpleCacheService
|
125
|
-
|
126
|
-
return SimpleCacheService
|
127
|
-
elif name == "SharedPromptCache":
|
128
|
-
from .memory.cache.shared_prompt_cache import SharedPromptCache
|
129
|
-
|
130
|
-
return SharedPromptCache
|
131
|
-
# New service organization imports
|
132
|
-
elif name == "AgentManagementService":
|
133
|
-
from .agents.management import AgentManager
|
134
|
-
|
135
|
-
return AgentManager
|
136
|
-
elif name == "ProjectRegistry":
|
137
|
-
from .project.registry import ProjectRegistry
|
138
|
-
|
139
|
-
return ProjectRegistry
|
140
|
-
elif name == "LoggingService":
|
141
|
-
from .infrastructure.logging import LoggingService
|
142
|
-
|
143
|
-
return LoggingService
|
144
|
-
elif name == "SocketIOClientManager":
|
145
|
-
from .socketio_client_manager import SocketIOClientManager
|
146
|
-
|
147
|
-
return SocketIOClientManager
|
148
|
-
# MCP Gateway services
|
149
|
-
elif name == "MCPConfiguration":
|
150
|
-
from .mcp_gateway.config.configuration import MCPConfiguration
|
151
|
-
|
152
|
-
return MCPConfiguration
|
153
|
-
elif name == "MCPConfigLoader":
|
154
|
-
from .mcp_gateway.config.config_loader import MCPConfigLoader
|
155
|
-
|
156
|
-
return MCPConfigLoader
|
157
|
-
elif name == "MCPServer":
|
158
|
-
from .mcp_gateway.server.mcp_server import MCPServer
|
159
|
-
|
160
|
-
return MCPServer
|
161
|
-
elif name == "MCPToolRegistry":
|
162
|
-
from .mcp_gateway.tools.tool_registry import MCPToolRegistry
|
163
|
-
|
164
|
-
return MCPToolRegistry
|
165
|
-
elif name == "BaseMCPService":
|
166
|
-
from .mcp_gateway.core.base import BaseMCPService
|
167
|
-
|
168
|
-
return BaseMCPService
|
169
|
-
elif name.startswith("IMCP"):
|
170
|
-
from .mcp_gateway.core import interfaces
|
171
|
-
|
172
|
-
return getattr(interfaces, name)
|
173
|
-
elif name.startswith("MCP") and "Error" in name:
|
174
|
-
from .mcp_gateway.core import exceptions
|
175
|
-
|
176
|
-
return getattr(exceptions, name)
|
177
|
-
# Core interfaces and base classes
|
178
|
-
elif name.startswith("I") or name in [
|
145
|
+
module = import_module("claude_mpm.services.recovery_manager")
|
146
|
+
return module.RecoveryManager
|
147
|
+
except ImportError as e:
|
148
|
+
raise AttributeError(f"Recovery management not available: {name}") from e
|
149
|
+
|
150
|
+
# Handle MCP interfaces (names starting with "IMCP")
|
151
|
+
if name.startswith("IMCP"):
|
152
|
+
module = import_module("claude_mpm.services.mcp_gateway.core.interfaces")
|
153
|
+
return getattr(module, name)
|
154
|
+
|
155
|
+
# Handle MCP exceptions (names starting with "MCP" and containing "Error")
|
156
|
+
if name.startswith("MCP") and "Error" in name:
|
157
|
+
module = import_module("claude_mpm.services.mcp_gateway.core.exceptions")
|
158
|
+
return getattr(module, name)
|
159
|
+
|
160
|
+
# Handle core interfaces and base classes
|
161
|
+
if name.startswith("I") or name in [
|
179
162
|
"BaseService",
|
180
163
|
"SyncBaseService",
|
181
164
|
"SingletonService",
|
@@ -183,6 +166,7 @@ def __getattr__(name): # noqa: PLR0911
|
|
183
166
|
from . import core
|
184
167
|
|
185
168
|
return getattr(core, name)
|
169
|
+
|
186
170
|
raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
|
187
171
|
|
188
172
|
|
@@ -215,7 +215,7 @@ class AgentCapabilitiesService(BaseService, AgentCapabilitiesInterface):
|
|
215
215
|
self.logger.debug(f"Could not parse agent {agent_file}: {e}")
|
216
216
|
continue
|
217
217
|
|
218
|
-
def _categorize_agent(self, agent_id: str, content: str) -> str:
|
218
|
+
def _categorize_agent(self, agent_id: str, content: str) -> str:
|
219
219
|
"""Categorize an agent based on its ID and content."""
|
220
220
|
agent_id_lower = agent_id.lower()
|
221
221
|
content_lower = content.lower()
|
@@ -287,7 +287,7 @@ class AgentBuilderService:
|
|
287
287
|
|
288
288
|
for template_file in self.templates_dir.glob("*.json"):
|
289
289
|
try:
|
290
|
-
with open(
|
290
|
+
with template_file.open() as f:
|
291
291
|
config = json.load(f)
|
292
292
|
|
293
293
|
# Use filename stem as ID if not specified in config
|
@@ -377,12 +377,12 @@ class AgentBuilderService:
|
|
377
377
|
raise AgentDeploymentError(f"Template '{template_id}' not found")
|
378
378
|
|
379
379
|
try:
|
380
|
-
with open(
|
380
|
+
with template_file.open() as f:
|
381
381
|
config = json.load(f)
|
382
382
|
self._template_cache[template_id] = config
|
383
383
|
return config.copy()
|
384
384
|
except Exception as e:
|
385
|
-
raise AgentDeploymentError(f"Failed to load template '{template_id}': {e}")
|
385
|
+
raise AgentDeploymentError(f"Failed to load template '{template_id}': {e}") from e
|
386
386
|
|
387
387
|
def _load_instructions(self, agent_id: str) -> str:
|
388
388
|
"""Load agent instructions.
|
@@ -406,7 +406,7 @@ class AgentBuilderService:
|
|
406
406
|
for instructions_file in possible_files:
|
407
407
|
if instructions_file.exists():
|
408
408
|
try:
|
409
|
-
with open(
|
409
|
+
with instructions_file.open() as f:
|
410
410
|
return f.read()
|
411
411
|
except Exception as e:
|
412
412
|
self.logger.warning(
|
@@ -272,7 +272,7 @@ class AgentLifecycleManager(BaseService):
|
|
272
272
|
# First convert to JSON string with custom encoder, then save
|
273
273
|
json_str = json.dumps(data, indent=2, default=str)
|
274
274
|
records_file.parent.mkdir(parents=True, exist_ok=True)
|
275
|
-
with open(
|
275
|
+
with records_file.open("w", encoding="utf-8") as f:
|
276
276
|
f.write(json_str)
|
277
277
|
|
278
278
|
self.logger.debug(f"Saved {len(self.agent_records)} agent records")
|
@@ -227,7 +227,7 @@ class AgentMetricsCollector:
|
|
227
227
|
return "validation_error"
|
228
228
|
return "other_error"
|
229
229
|
|
230
|
-
def _extract_agent_type(self, agent_name: str) -> str:
|
230
|
+
def _extract_agent_type(self, agent_name: str) -> str:
|
231
231
|
"""
|
232
232
|
Extract agent type from agent name for categorization.
|
233
233
|
|
@@ -80,7 +80,7 @@ class AgentRecordService(BaseService):
|
|
80
80
|
json_str = json.dumps(data, indent=2, default=str)
|
81
81
|
self.records_file.parent.mkdir(parents=True, exist_ok=True)
|
82
82
|
|
83
|
-
with
|
83
|
+
with self.records_file.open("w", encoding="utf-8") as f:
|
84
84
|
f.write(json_str)
|
85
85
|
|
86
86
|
self.logger.debug(f"Saved {len(records)} agent records")
|
@@ -149,7 +149,7 @@ class AgentRecordService(BaseService):
|
|
149
149
|
json_str = json.dumps(data, indent=2, default=str)
|
150
150
|
self.history_file.parent.mkdir(parents=True, exist_ok=True)
|
151
151
|
|
152
|
-
with
|
152
|
+
with self.history_file.open("w", encoding="utf-8") as f:
|
153
153
|
f.write(json_str)
|
154
154
|
|
155
155
|
self.logger.debug(f"Saved {len(history)} operation history entries")
|
@@ -255,7 +255,7 @@ class AgentRecordService(BaseService):
|
|
255
255
|
|
256
256
|
# Write to output path
|
257
257
|
json_str = json.dumps(data, indent=2, default=str)
|
258
|
-
with open(
|
258
|
+
with output_path.open("w", encoding="utf-8") as f:
|
259
259
|
f.write(json_str)
|
260
260
|
|
261
261
|
elif format == "csv":
|
@@ -112,8 +112,29 @@ class DeploymentConfigLoader:
|
|
112
112
|
Returns:
|
113
113
|
True if the agent should be deployed, False otherwise
|
114
114
|
"""
|
115
|
+
if config is None:
|
116
|
+
config = Config()
|
117
|
+
|
115
118
|
settings = self.get_deployment_settings(config)
|
116
119
|
|
120
|
+
# Check startup configuration for system agents
|
121
|
+
if agent_source == "system":
|
122
|
+
# Check startup configuration first
|
123
|
+
startup_enabled = config.get("startup.enabled_agents", [])
|
124
|
+
if startup_enabled:
|
125
|
+
# Normalize for comparison
|
126
|
+
check_id = agent_id if settings["case_sensitive"] else agent_id.lower()
|
127
|
+
startup_list = (
|
128
|
+
startup_enabled
|
129
|
+
if settings["case_sensitive"]
|
130
|
+
else [a.lower() for a in startup_enabled]
|
131
|
+
)
|
132
|
+
if check_id not in startup_list:
|
133
|
+
self.logger.debug(
|
134
|
+
f"Skipping system agent {agent_id} - not in startup enabled list"
|
135
|
+
)
|
136
|
+
return False
|
137
|
+
|
117
138
|
# Check if the source type is enabled
|
118
139
|
if agent_source == "system" and not settings["deploy_system_agents"]:
|
119
140
|
self.logger.debug(
|
@@ -48,10 +48,10 @@ class TargetDirectorySetupStep(BaseDeploymentStep):
|
|
48
48
|
try:
|
49
49
|
test_file.write_text("test")
|
50
50
|
test_file.unlink()
|
51
|
-
except Exception:
|
51
|
+
except Exception as e:
|
52
52
|
raise PermissionError(
|
53
53
|
f"Target directory is not writable: {context.actual_target_dir}"
|
54
|
-
)
|
54
|
+
) from e
|
55
55
|
|
56
56
|
self.logger.info(f"Target directory set up: {context.actual_target_dir}")
|
57
57
|
|
@@ -457,7 +457,7 @@ class AgentProfileLoader(BaseService):
|
|
457
457
|
|
458
458
|
if prompt_file.exists():
|
459
459
|
try:
|
460
|
-
with open(
|
460
|
+
with prompt_file.open() as f:
|
461
461
|
data = json.load(f)
|
462
462
|
for prompt_data in data:
|
463
463
|
prompt = ImprovedPrompt(
|
@@ -500,7 +500,7 @@ class AgentProfileLoader(BaseService):
|
|
500
500
|
|
501
501
|
# Save to file
|
502
502
|
prompt_file = self.improved_prompts_path / f"{agent_name}_prompts.json"
|
503
|
-
with open(
|
503
|
+
with prompt_file.open("w") as f:
|
504
504
|
json.dump(
|
505
505
|
[
|
506
506
|
{
|
@@ -13,7 +13,9 @@ from enum import Enum
|
|
13
13
|
from pathlib import Path
|
14
14
|
from typing import Any, Dict, List, Optional
|
15
15
|
|
16
|
-
|
16
|
+
# Lazy import for base_agent_loader to reduce initialization overhead
|
17
|
+
# base_agent_loader adds ~500ms to import time
|
18
|
+
# from claude_mpm.agents.base_agent_loader import clear_base_agent_cache
|
17
19
|
from claude_mpm.core.logging_utils import get_logger
|
18
20
|
from claude_mpm.services.memory.cache.shared_prompt_cache import SharedPromptCache
|
19
21
|
from claude_mpm.services.shared import ConfigServiceBase
|
@@ -21,6 +23,13 @@ from claude_mpm.services.shared import ConfigServiceBase
|
|
21
23
|
logger = get_logger(__name__)
|
22
24
|
|
23
25
|
|
26
|
+
def _get_clear_base_agent_cache():
|
27
|
+
"""Lazy loader for clear_base_agent_cache function."""
|
28
|
+
from claude_mpm.agents.base_agent_loader import clear_base_agent_cache
|
29
|
+
|
30
|
+
return clear_base_agent_cache
|
31
|
+
|
32
|
+
|
24
33
|
class BaseAgentSection(str, Enum):
|
25
34
|
"""Base agent markdown sections."""
|
26
35
|
|
@@ -134,7 +143,8 @@ class BaseAgentManager(ConfigServiceBase):
|
|
134
143
|
content = self._structure_to_markdown(current)
|
135
144
|
self.base_agent_path.write_text(content, encoding="utf-8")
|
136
145
|
|
137
|
-
# Clear caches
|
146
|
+
# Clear caches (lazy load to avoid import overhead)
|
147
|
+
clear_base_agent_cache = _get_clear_base_agent_cache()
|
138
148
|
clear_base_agent_cache()
|
139
149
|
self.cache.invalidate("base_agent:instructions")
|
140
150
|
|
@@ -195,7 +195,7 @@ class LocalAgentTemplateManager:
|
|
195
195
|
"""
|
196
196
|
for template_file in directory.glob("*.json"):
|
197
197
|
try:
|
198
|
-
with open(
|
198
|
+
with template_file.open() as f:
|
199
199
|
data = json.load(f)
|
200
200
|
|
201
201
|
# Create LocalAgentTemplate
|
@@ -307,7 +307,7 @@ class LocalAgentTemplateManager:
|
|
307
307
|
|
308
308
|
# Save to JSON file
|
309
309
|
template_file = target_dir / f"{template.agent_id}.json"
|
310
|
-
with open(
|
310
|
+
with template_file.open("w") as f:
|
311
311
|
json.dump(template.to_json(), f, indent=2)
|
312
312
|
|
313
313
|
# Invalidate cache
|
@@ -628,7 +628,7 @@ class LocalAgentTemplateManager:
|
|
628
628
|
|
629
629
|
# Save current version
|
630
630
|
old_version_file = versions_dir / f"{template.agent_version}.json"
|
631
|
-
with open(
|
631
|
+
with old_version_file.open("w") as f:
|
632
632
|
json.dump(template.to_json(), f, indent=2)
|
633
633
|
|
634
634
|
# Update template version
|
@@ -691,7 +691,7 @@ class LocalAgentTemplateManager:
|
|
691
691
|
count = 0
|
692
692
|
for agent_id, template in templates.items():
|
693
693
|
output_file = output_dir / f"{agent_id}.json"
|
694
|
-
with open(
|
694
|
+
with output_file.open("w") as f:
|
695
695
|
json.dump(template.to_json(), f, indent=2)
|
696
696
|
count += 1
|
697
697
|
|
@@ -715,7 +715,7 @@ class LocalAgentTemplateManager:
|
|
715
715
|
count = 0
|
716
716
|
for template_file in input_dir.glob("*.json"):
|
717
717
|
try:
|
718
|
-
with open(
|
718
|
+
with template_file.open() as f:
|
719
719
|
data = json.load(f)
|
720
720
|
|
721
721
|
template = LocalAgentTemplate.from_json(data)
|