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.
Files changed (226) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/__init__.py +20 -5
  3. claude_mpm/agents/agent_loader.py +19 -2
  4. claude_mpm/agents/base_agent_loader.py +5 -5
  5. claude_mpm/agents/frontmatter_validator.py +4 -4
  6. claude_mpm/agents/templates/agent-manager.json +3 -3
  7. claude_mpm/agents/templates/agentic-coder-optimizer.json +3 -3
  8. claude_mpm/agents/templates/api_qa.json +1 -1
  9. claude_mpm/agents/templates/clerk-ops.json +3 -3
  10. claude_mpm/agents/templates/code_analyzer.json +3 -3
  11. claude_mpm/agents/templates/dart_engineer.json +294 -0
  12. claude_mpm/agents/templates/data_engineer.json +3 -3
  13. claude_mpm/agents/templates/documentation.json +2 -2
  14. claude_mpm/agents/templates/engineer.json +2 -2
  15. claude_mpm/agents/templates/gcp_ops_agent.json +2 -2
  16. claude_mpm/agents/templates/imagemagick.json +1 -1
  17. claude_mpm/agents/templates/local_ops_agent.json +319 -41
  18. claude_mpm/agents/templates/memory_manager.json +2 -2
  19. claude_mpm/agents/templates/nextjs_engineer.json +2 -2
  20. claude_mpm/agents/templates/ops.json +2 -2
  21. claude_mpm/agents/templates/php-engineer.json +1 -1
  22. claude_mpm/agents/templates/project_organizer.json +1 -1
  23. claude_mpm/agents/templates/prompt-engineer.json +6 -4
  24. claude_mpm/agents/templates/python_engineer.json +2 -2
  25. claude_mpm/agents/templates/qa.json +1 -1
  26. claude_mpm/agents/templates/react_engineer.json +3 -3
  27. claude_mpm/agents/templates/refactoring_engineer.json +3 -3
  28. claude_mpm/agents/templates/research.json +2 -2
  29. claude_mpm/agents/templates/security.json +2 -2
  30. claude_mpm/agents/templates/ticketing.json +2 -2
  31. claude_mpm/agents/templates/typescript_engineer.json +2 -2
  32. claude_mpm/agents/templates/vercel_ops_agent.json +2 -2
  33. claude_mpm/agents/templates/version_control.json +2 -2
  34. claude_mpm/agents/templates/web_qa.json +6 -6
  35. claude_mpm/agents/templates/web_ui.json +3 -3
  36. claude_mpm/cli/__init__.py +49 -19
  37. claude_mpm/cli/commands/agent_manager.py +3 -3
  38. claude_mpm/cli/commands/agents.py +6 -6
  39. claude_mpm/cli/commands/aggregate.py +4 -4
  40. claude_mpm/cli/commands/analyze.py +2 -2
  41. claude_mpm/cli/commands/analyze_code.py +1 -1
  42. claude_mpm/cli/commands/cleanup.py +3 -3
  43. claude_mpm/cli/commands/config.py +2 -2
  44. claude_mpm/cli/commands/configure.py +605 -21
  45. claude_mpm/cli/commands/dashboard.py +1 -1
  46. claude_mpm/cli/commands/debug.py +3 -3
  47. claude_mpm/cli/commands/doctor.py +1 -1
  48. claude_mpm/cli/commands/mcp.py +7 -7
  49. claude_mpm/cli/commands/mcp_command_router.py +1 -1
  50. claude_mpm/cli/commands/mcp_config.py +2 -2
  51. claude_mpm/cli/commands/mcp_external_commands.py +2 -2
  52. claude_mpm/cli/commands/mcp_install_commands.py +3 -3
  53. claude_mpm/cli/commands/mcp_pipx_config.py +2 -2
  54. claude_mpm/cli/commands/mcp_setup_external.py +3 -3
  55. claude_mpm/cli/commands/monitor.py +1 -1
  56. claude_mpm/cli/commands/mpm_init_handler.py +1 -1
  57. claude_mpm/cli/interactive/agent_wizard.py +1 -1
  58. claude_mpm/cli/parsers/configure_parser.py +5 -0
  59. claude_mpm/cli/parsers/search_parser.py +1 -1
  60. claude_mpm/cli/shared/argument_patterns.py +2 -2
  61. claude_mpm/cli/shared/base_command.py +1 -1
  62. claude_mpm/cli/startup_logging.py +4 -4
  63. claude_mpm/config/experimental_features.py +4 -4
  64. claude_mpm/config/socketio_config.py +2 -2
  65. claude_mpm/core/__init__.py +53 -17
  66. claude_mpm/core/agent_session_manager.py +2 -2
  67. claude_mpm/core/api_validator.py +3 -3
  68. claude_mpm/core/base_service.py +10 -1
  69. claude_mpm/core/cache.py +2 -2
  70. claude_mpm/core/config.py +5 -5
  71. claude_mpm/core/config_aliases.py +4 -4
  72. claude_mpm/core/config_constants.py +1 -1
  73. claude_mpm/core/error_handler.py +1 -1
  74. claude_mpm/core/file_utils.py +5 -5
  75. claude_mpm/core/framework/formatters/capability_generator.py +5 -5
  76. claude_mpm/core/framework/loaders/agent_loader.py +1 -1
  77. claude_mpm/core/framework/processors/metadata_processor.py +1 -1
  78. claude_mpm/core/framework/processors/template_processor.py +3 -3
  79. claude_mpm/core/framework_loader.py +2 -2
  80. claude_mpm/core/log_manager.py +11 -4
  81. claude_mpm/core/logger.py +2 -2
  82. claude_mpm/core/optimized_startup.py +1 -1
  83. claude_mpm/core/output_style_manager.py +1 -1
  84. claude_mpm/core/service_registry.py +2 -2
  85. claude_mpm/core/session_manager.py +3 -3
  86. claude_mpm/core/shared/config_loader.py +1 -1
  87. claude_mpm/core/socketio_pool.py +2 -2
  88. claude_mpm/core/unified_agent_registry.py +2 -2
  89. claude_mpm/core/unified_config.py +6 -6
  90. claude_mpm/core/unified_paths.py +2 -2
  91. claude_mpm/dashboard/api/simple_directory.py +1 -1
  92. claude_mpm/generators/agent_profile_generator.py +1 -1
  93. claude_mpm/hooks/claude_hooks/event_handlers.py +2 -2
  94. claude_mpm/hooks/claude_hooks/installer.py +9 -9
  95. claude_mpm/hooks/claude_hooks/response_tracking.py +16 -11
  96. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +16 -13
  97. claude_mpm/hooks/claude_hooks/tool_analysis.py +2 -2
  98. claude_mpm/hooks/memory_integration_hook.py +1 -1
  99. claude_mpm/hooks/validation_hooks.py +1 -1
  100. claude_mpm/init.py +4 -4
  101. claude_mpm/models/agent_session.py +1 -1
  102. claude_mpm/scripts/socketio_daemon.py +5 -5
  103. claude_mpm/services/__init__.py +145 -161
  104. claude_mpm/services/agent_capabilities_service.py +1 -1
  105. claude_mpm/services/agents/agent_builder.py +4 -4
  106. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +1 -1
  107. claude_mpm/services/agents/deployment/agent_metrics_collector.py +1 -1
  108. claude_mpm/services/agents/deployment/agent_record_service.py +3 -3
  109. claude_mpm/services/agents/deployment/deployment_config_loader.py +21 -0
  110. claude_mpm/services/agents/deployment/deployment_wrapper.py +1 -1
  111. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +2 -2
  112. claude_mpm/services/agents/loading/agent_profile_loader.py +2 -2
  113. claude_mpm/services/agents/loading/base_agent_manager.py +12 -2
  114. claude_mpm/services/agents/local_template_manager.py +5 -5
  115. claude_mpm/services/agents/registry/deployed_agent_discovery.py +1 -1
  116. claude_mpm/services/agents/registry/modification_tracker.py +19 -11
  117. claude_mpm/services/async_session_logger.py +3 -3
  118. claude_mpm/services/claude_session_logger.py +4 -4
  119. claude_mpm/services/cli/agent_listing_service.py +3 -3
  120. claude_mpm/services/cli/agent_validation_service.py +1 -1
  121. claude_mpm/services/cli/session_manager.py +2 -2
  122. claude_mpm/services/core/path_resolver.py +1 -1
  123. claude_mpm/services/diagnostics/checks/agent_check.py +1 -1
  124. claude_mpm/services/diagnostics/checks/claude_code_check.py +2 -2
  125. claude_mpm/services/diagnostics/checks/common_issues_check.py +3 -3
  126. claude_mpm/services/diagnostics/checks/configuration_check.py +2 -2
  127. claude_mpm/services/diagnostics/checks/installation_check.py +1 -1
  128. claude_mpm/services/diagnostics/checks/mcp_check.py +1 -1
  129. claude_mpm/services/diagnostics/checks/mcp_services_check.py +9 -9
  130. claude_mpm/services/diagnostics/checks/monitor_check.py +1 -1
  131. claude_mpm/services/diagnostics/doctor_reporter.py +1 -1
  132. claude_mpm/services/event_aggregator.py +1 -1
  133. claude_mpm/services/event_bus/event_bus.py +7 -2
  134. claude_mpm/services/events/consumers/dead_letter.py +2 -2
  135. claude_mpm/services/framework_claude_md_generator/__init__.py +1 -1
  136. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +3 -3
  137. claude_mpm/services/framework_claude_md_generator/version_manager.py +1 -1
  138. claude_mpm/services/hook_installer_service.py +7 -7
  139. claude_mpm/services/infrastructure/context_preservation.py +7 -7
  140. claude_mpm/services/infrastructure/daemon_manager.py +5 -5
  141. claude_mpm/services/mcp_config_manager.py +169 -48
  142. claude_mpm/services/mcp_gateway/__init__.py +98 -94
  143. claude_mpm/services/mcp_gateway/auto_configure.py +5 -5
  144. claude_mpm/services/mcp_gateway/config/config_loader.py +2 -2
  145. claude_mpm/services/mcp_gateway/config/configuration.py +3 -3
  146. claude_mpm/services/mcp_gateway/core/process_pool.py +3 -3
  147. claude_mpm/services/mcp_gateway/core/singleton_manager.py +2 -2
  148. claude_mpm/services/mcp_gateway/core/startup_verification.py +1 -1
  149. claude_mpm/services/mcp_gateway/main.py +1 -1
  150. claude_mpm/services/mcp_gateway/registry/service_registry.py +4 -2
  151. claude_mpm/services/mcp_gateway/registry/tool_registry.py +2 -1
  152. claude_mpm/services/mcp_gateway/server/stdio_handler.py +1 -1
  153. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +1 -1
  154. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +1 -1
  155. claude_mpm/services/mcp_gateway/tools/hello_world.py +1 -1
  156. claude_mpm/services/mcp_gateway/utils/package_version_checker.py +5 -5
  157. claude_mpm/services/mcp_gateway/utils/update_preferences.py +2 -2
  158. claude_mpm/services/mcp_service_verifier.py +1 -1
  159. claude_mpm/services/memory/builder.py +1 -1
  160. claude_mpm/services/memory/cache/shared_prompt_cache.py +2 -1
  161. claude_mpm/services/memory/indexed_memory.py +3 -3
  162. claude_mpm/services/monitor/daemon.py +1 -1
  163. claude_mpm/services/monitor/daemon_manager.py +9 -9
  164. claude_mpm/services/monitor/event_emitter.py +1 -1
  165. claude_mpm/services/monitor/handlers/file.py +1 -1
  166. claude_mpm/services/monitor/handlers/hooks.py +3 -3
  167. claude_mpm/services/monitor/management/lifecycle.py +7 -7
  168. claude_mpm/services/monitor/server.py +2 -2
  169. claude_mpm/services/orphan_detection.py +788 -0
  170. claude_mpm/services/port_manager.py +2 -2
  171. claude_mpm/services/project/analyzer.py +3 -3
  172. claude_mpm/services/project/archive_manager.py +13 -13
  173. claude_mpm/services/project/dependency_analyzer.py +4 -4
  174. claude_mpm/services/project/documentation_manager.py +4 -4
  175. claude_mpm/services/project/enhanced_analyzer.py +8 -8
  176. claude_mpm/services/project/registry.py +4 -4
  177. claude_mpm/services/project_port_allocator.py +597 -0
  178. claude_mpm/services/response_tracker.py +1 -1
  179. claude_mpm/services/session_management_service.py +1 -1
  180. claude_mpm/services/session_manager.py +6 -4
  181. claude_mpm/services/socketio/event_normalizer.py +1 -1
  182. claude_mpm/services/socketio/handlers/code_analysis.py +14 -12
  183. claude_mpm/services/socketio/handlers/file.py +1 -1
  184. claude_mpm/services/socketio/migration_utils.py +1 -1
  185. claude_mpm/services/socketio/server/core.py +1 -1
  186. claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +1 -1
  187. claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +4 -4
  188. claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +1 -1
  189. claude_mpm/services/unified/config_strategies/config_schema.py +4 -4
  190. claude_mpm/services/unified/config_strategies/context_strategy.py +6 -6
  191. claude_mpm/services/unified/config_strategies/error_handling_strategy.py +10 -10
  192. claude_mpm/services/unified/config_strategies/file_loader_strategy.py +5 -5
  193. claude_mpm/services/unified/config_strategies/unified_config_service.py +8 -8
  194. claude_mpm/services/unified/config_strategies/validation_strategy.py +15 -15
  195. claude_mpm/services/unified/deployment_strategies/base.py +4 -4
  196. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +15 -15
  197. claude_mpm/services/unified/deployment_strategies/local.py +9 -9
  198. claude_mpm/services/unified/deployment_strategies/utils.py +9 -9
  199. claude_mpm/services/unified/deployment_strategies/vercel.py +7 -7
  200. claude_mpm/services/unified/unified_config.py +5 -5
  201. claude_mpm/services/unified/unified_deployment.py +2 -2
  202. claude_mpm/services/utility_service.py +1 -1
  203. claude_mpm/services/version_control/conflict_resolution.py +2 -2
  204. claude_mpm/services/version_control/git_operations.py +3 -3
  205. claude_mpm/services/version_control/semantic_versioning.py +13 -13
  206. claude_mpm/services/version_control/version_parser.py +1 -1
  207. claude_mpm/storage/state_storage.py +12 -13
  208. claude_mpm/tools/code_tree_analyzer.py +5 -5
  209. claude_mpm/tools/code_tree_builder.py +4 -4
  210. claude_mpm/tools/socketio_debug.py +1 -1
  211. claude_mpm/utils/agent_dependency_loader.py +4 -4
  212. claude_mpm/utils/common.py +2 -2
  213. claude_mpm/utils/config_manager.py +3 -3
  214. claude_mpm/utils/dependency_cache.py +2 -2
  215. claude_mpm/utils/dependency_strategies.py +6 -6
  216. claude_mpm/utils/file_utils.py +11 -11
  217. claude_mpm/utils/log_cleanup.py +1 -1
  218. claude_mpm/utils/path_operations.py +1 -1
  219. claude_mpm/validation/agent_validator.py +2 -2
  220. claude_mpm/validation/frontmatter_validator.py +1 -1
  221. {claude_mpm-4.5.8.dist-info → claude_mpm-4.5.12.dist-info}/METADATA +1 -1
  222. {claude_mpm-4.5.8.dist-info → claude_mpm-4.5.12.dist-info}/RECORD +226 -223
  223. {claude_mpm-4.5.8.dist-info → claude_mpm-4.5.12.dist-info}/WHEEL +0 -0
  224. {claude_mpm-4.5.8.dist-info → claude_mpm-4.5.12.dist-info}/entry_points.txt +0 -0
  225. {claude_mpm-4.5.8.dist-info → claude_mpm-4.5.12.dist-info}/licenses/LICENSE +0 -0
  226. {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(old_file) as f:
273
+ with old_file.open() as f:
274
274
  config = json.load(f)
275
275
 
276
276
  # Write as YAML
277
- with open(new_file, "w") as f:
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(config_file, "w") as f:
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(config_file, "w") as f:
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(filepath, "w", encoding="utf-8") as f:
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(pid_file) as f:
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(port_file, "w") as f:
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(pid_file) as f:
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(pid_file) as f:
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(port_file) as f:
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})")
@@ -13,169 +13,152 @@ New structure:
13
13
 
14
14
 
15
15
  # Use lazy imports to prevent circular dependency issues
16
- def __getattr__(name): # noqa: PLR0911
17
- """Lazy import to prevent circular dependencies."""
18
- if name == "TicketManager":
19
- from .ticket_manager import TicketManager
20
-
21
- return TicketManager
22
- if name == "AgentDeploymentService":
23
- # Use correct path
24
- from .agents.deployment import AgentDeploymentService
25
-
26
- return AgentDeploymentService
27
- if name == "AgentMemoryManager":
28
- from .agents.memory import AgentMemoryManager
29
-
30
- return AgentMemoryManager
31
- if name == "get_memory_manager":
32
- from .agents.memory import get_memory_manager
33
-
34
- return get_memory_manager
35
- # Add backward compatibility for other agent services
36
- if name == "AgentRegistry":
37
- # Use correct path
38
- from .agents.registry import AgentRegistry
39
-
40
- return AgentRegistry
41
- if name == "AgentLifecycleManager":
42
- from .agents.deployment import AgentLifecycleManager
43
-
44
- return AgentLifecycleManager
45
- if name == "AgentManager":
46
- from .agents.management import AgentManager
47
-
48
- return AgentManager
49
- if name == "AgentCapabilitiesGenerator":
50
- from .agents.management import AgentCapabilitiesGenerator
51
-
52
- return AgentCapabilitiesGenerator
53
- if name == "AgentModificationTracker":
54
- from .agents.registry import AgentModificationTracker
55
-
56
- return AgentModificationTracker
57
- if name == "AgentPersistenceService":
58
- from .agents.memory import AgentPersistenceService
59
-
60
- return AgentPersistenceService
61
- if name == "AgentProfileLoader":
62
- from .agents.loading import AgentProfileLoader
63
-
64
- return AgentProfileLoader
65
- if name == "AgentVersionManager":
66
- from .agents.deployment import AgentVersionManager
67
-
68
- return AgentVersionManager
69
- if name == "BaseAgentManager":
70
- from .agents.loading import BaseAgentManager
71
-
72
- return BaseAgentManager
73
- if name == "DeployedAgentDiscovery":
74
- from .agents.registry import DeployedAgentDiscovery
75
-
76
- return DeployedAgentDiscovery
77
- if name == "FrameworkAgentLoader":
78
- from .agents.loading import FrameworkAgentLoader
79
-
80
- return FrameworkAgentLoader
81
- if name == "HookService":
82
- from .hook_service import HookService
83
-
84
- return HookService
85
- if name == "ProjectAnalyzer":
86
- from .project.analyzer import ProjectAnalyzer
87
-
88
- return ProjectAnalyzer
89
- if name == "AdvancedHealthMonitor":
90
- from .infrastructure.monitoring import AdvancedHealthMonitor
91
-
92
- return AdvancedHealthMonitor
93
- if name == "HealthMonitor":
94
- # For backward compatibility, return AdvancedHealthMonitor
95
- # Note: There's also a different HealthMonitor in infrastructure.health_monitor
96
- from .infrastructure.monitoring import AdvancedHealthMonitor
97
-
98
- return AdvancedHealthMonitor
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
- from .recovery_manager import RecoveryManager
102
-
103
- return RecoveryManager
104
- except ImportError:
105
- raise AttributeError(f"Recovery management not available: {name}")
106
- elif name in {"StandaloneSocketIOServer", "SocketIOServer"}:
107
- from .socketio_server import SocketIOServer
108
-
109
- return SocketIOServer
110
- # Backward compatibility for memory services
111
- elif name == "MemoryBuilder":
112
- from .memory.builder import MemoryBuilder
113
-
114
- return MemoryBuilder
115
- elif name == "MemoryRouter":
116
- from .memory.router import MemoryRouter
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: # noqa: PLR0911
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(template_file) as f:
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(template_file) as f:
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(instructions_file) as f:
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(records_file, "w", encoding="utf-8") as f:
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: # noqa: PLR0911
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 open(self.records_file, "w", encoding="utf-8") as f:
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 open(self.history_file, "w", encoding="utf-8") as f:
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(output_path, "w", encoding="utf-8") as f:
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(
@@ -91,7 +91,7 @@ class DeploymentServiceWrapper:
91
91
 
92
92
  # Read agent content if file exists
93
93
  if agent_path.exists():
94
- with open(agent_path) as f:
94
+ with agent_path.open() as f:
95
95
  content = f.read()
96
96
 
97
97
  # Parse metadata from content
@@ -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(prompt_file) as f:
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(prompt_file, "w") as f:
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
- from claude_mpm.agents.base_agent_loader import clear_base_agent_cache
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(template_file) as f:
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(template_file, "w") as f:
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(old_version_file, "w") as f:
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(output_file, "w") as f:
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(template_file) as f:
718
+ with template_file.open() as f:
719
719
  data = json.load(f)
720
720
 
721
721
  template = LocalAgentTemplate.from_json(data)