claude-mpm 4.1.0__py3-none-any.whl → 4.1.2__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 (358) hide show
  1. claude_mpm/BUILD_NUMBER +1 -1
  2. claude_mpm/VERSION +1 -1
  3. claude_mpm/__main__.py +1 -1
  4. claude_mpm/agents/BASE_PM.md +74 -46
  5. claude_mpm/agents/INSTRUCTIONS.md +11 -153
  6. claude_mpm/agents/WORKFLOW.md +61 -321
  7. claude_mpm/agents/__init__.py +11 -11
  8. claude_mpm/agents/agent_loader.py +23 -20
  9. claude_mpm/agents/agent_loader_integration.py +1 -1
  10. claude_mpm/agents/agents_metadata.py +27 -0
  11. claude_mpm/agents/async_agent_loader.py +5 -8
  12. claude_mpm/agents/base_agent_loader.py +36 -25
  13. claude_mpm/agents/frontmatter_validator.py +6 -6
  14. claude_mpm/agents/schema/agent_schema.json +1 -1
  15. claude_mpm/agents/system_agent_config.py +9 -9
  16. claude_mpm/agents/templates/api_qa.json +47 -2
  17. claude_mpm/agents/templates/imagemagick.json +256 -0
  18. claude_mpm/agents/templates/qa.json +41 -2
  19. claude_mpm/agents/templates/ticketing.json +5 -5
  20. claude_mpm/agents/templates/web_qa.json +133 -58
  21. claude_mpm/agents/templates/web_ui.json +3 -3
  22. claude_mpm/cli/__init__.py +51 -46
  23. claude_mpm/cli/__main__.py +1 -1
  24. claude_mpm/cli/commands/__init__.py +10 -12
  25. claude_mpm/cli/commands/agent_manager.py +186 -181
  26. claude_mpm/cli/commands/agents.py +271 -268
  27. claude_mpm/cli/commands/aggregate.py +30 -29
  28. claude_mpm/cli/commands/cleanup.py +50 -44
  29. claude_mpm/cli/commands/cleanup_orphaned_agents.py +25 -25
  30. claude_mpm/cli/commands/config.py +162 -127
  31. claude_mpm/cli/commands/doctor.py +52 -62
  32. claude_mpm/cli/commands/info.py +37 -25
  33. claude_mpm/cli/commands/mcp.py +3 -7
  34. claude_mpm/cli/commands/mcp_command_router.py +14 -18
  35. claude_mpm/cli/commands/mcp_install_commands.py +28 -23
  36. claude_mpm/cli/commands/mcp_pipx_config.py +58 -49
  37. claude_mpm/cli/commands/mcp_server_commands.py +23 -17
  38. claude_mpm/cli/commands/memory.py +192 -141
  39. claude_mpm/cli/commands/monitor.py +117 -88
  40. claude_mpm/cli/commands/run.py +120 -84
  41. claude_mpm/cli/commands/run_config_checker.py +4 -5
  42. claude_mpm/cli/commands/socketio_monitor.py +17 -19
  43. claude_mpm/cli/commands/tickets.py +92 -92
  44. claude_mpm/cli/parser.py +1 -5
  45. claude_mpm/cli/parsers/__init__.py +1 -1
  46. claude_mpm/cli/parsers/agent_manager_parser.py +50 -98
  47. claude_mpm/cli/parsers/agents_parser.py +2 -3
  48. claude_mpm/cli/parsers/base_parser.py +7 -5
  49. claude_mpm/cli/parsers/mcp_parser.py +4 -2
  50. claude_mpm/cli/parsers/monitor_parser.py +26 -18
  51. claude_mpm/cli/shared/__init__.py +10 -10
  52. claude_mpm/cli/shared/argument_patterns.py +57 -71
  53. claude_mpm/cli/shared/base_command.py +61 -53
  54. claude_mpm/cli/shared/error_handling.py +62 -58
  55. claude_mpm/cli/shared/output_formatters.py +78 -77
  56. claude_mpm/cli/startup_logging.py +204 -172
  57. claude_mpm/cli/utils.py +10 -11
  58. claude_mpm/cli_module/__init__.py +1 -1
  59. claude_mpm/cli_module/args.py +1 -1
  60. claude_mpm/cli_module/migration_example.py +5 -5
  61. claude_mpm/config/__init__.py +9 -9
  62. claude_mpm/config/agent_config.py +15 -14
  63. claude_mpm/config/experimental_features.py +4 -4
  64. claude_mpm/config/paths.py +0 -1
  65. claude_mpm/config/socketio_config.py +5 -6
  66. claude_mpm/constants.py +1 -2
  67. claude_mpm/core/__init__.py +8 -8
  68. claude_mpm/core/agent_name_normalizer.py +1 -1
  69. claude_mpm/core/agent_registry.py +20 -23
  70. claude_mpm/core/agent_session_manager.py +3 -3
  71. claude_mpm/core/base_service.py +7 -15
  72. claude_mpm/core/cache.py +4 -6
  73. claude_mpm/core/claude_runner.py +85 -113
  74. claude_mpm/core/config.py +43 -28
  75. claude_mpm/core/config_aliases.py +0 -9
  76. claude_mpm/core/config_constants.py +52 -30
  77. claude_mpm/core/constants.py +0 -1
  78. claude_mpm/core/container.py +18 -27
  79. claude_mpm/core/exceptions.py +2 -2
  80. claude_mpm/core/factories.py +10 -12
  81. claude_mpm/core/framework_loader.py +581 -280
  82. claude_mpm/core/hook_manager.py +26 -22
  83. claude_mpm/core/hook_performance_config.py +58 -47
  84. claude_mpm/core/injectable_service.py +1 -1
  85. claude_mpm/core/interactive_session.py +61 -152
  86. claude_mpm/core/interfaces.py +1 -100
  87. claude_mpm/core/lazy.py +5 -5
  88. claude_mpm/core/log_manager.py +587 -0
  89. claude_mpm/core/logger.py +125 -8
  90. claude_mpm/core/logging_config.py +15 -15
  91. claude_mpm/core/minimal_framework_loader.py +5 -8
  92. claude_mpm/core/oneshot_session.py +15 -33
  93. claude_mpm/core/optimized_agent_loader.py +4 -6
  94. claude_mpm/core/optimized_startup.py +2 -1
  95. claude_mpm/core/output_style_manager.py +147 -106
  96. claude_mpm/core/pm_hook_interceptor.py +0 -1
  97. claude_mpm/core/service_registry.py +11 -8
  98. claude_mpm/core/session_manager.py +1 -2
  99. claude_mpm/core/shared/__init__.py +1 -1
  100. claude_mpm/core/shared/config_loader.py +101 -97
  101. claude_mpm/core/shared/path_resolver.py +72 -68
  102. claude_mpm/core/shared/singleton_manager.py +56 -50
  103. claude_mpm/core/socketio_pool.py +26 -6
  104. claude_mpm/core/tool_access_control.py +4 -5
  105. claude_mpm/core/typing_utils.py +50 -59
  106. claude_mpm/core/unified_agent_registry.py +14 -19
  107. claude_mpm/core/unified_config.py +4 -6
  108. claude_mpm/core/unified_paths.py +197 -109
  109. claude_mpm/dashboard/open_dashboard.py +2 -4
  110. claude_mpm/experimental/cli_enhancements.py +51 -36
  111. claude_mpm/generators/agent_profile_generator.py +2 -4
  112. claude_mpm/hooks/base_hook.py +1 -2
  113. claude_mpm/hooks/claude_hooks/connection_pool.py +72 -26
  114. claude_mpm/hooks/claude_hooks/event_handlers.py +93 -38
  115. claude_mpm/hooks/claude_hooks/hook_handler.py +130 -76
  116. claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +104 -77
  117. claude_mpm/hooks/claude_hooks/memory_integration.py +2 -4
  118. claude_mpm/hooks/claude_hooks/response_tracking.py +15 -11
  119. claude_mpm/hooks/claude_hooks/tool_analysis.py +12 -18
  120. claude_mpm/hooks/memory_integration_hook.py +5 -5
  121. claude_mpm/hooks/tool_call_interceptor.py +1 -1
  122. claude_mpm/hooks/validation_hooks.py +4 -4
  123. claude_mpm/init.py +4 -9
  124. claude_mpm/models/__init__.py +2 -2
  125. claude_mpm/models/agent_session.py +11 -14
  126. claude_mpm/scripts/mcp_server.py +20 -11
  127. claude_mpm/scripts/mcp_wrapper.py +5 -5
  128. claude_mpm/scripts/mpm_doctor.py +321 -0
  129. claude_mpm/scripts/socketio_daemon.py +28 -25
  130. claude_mpm/scripts/socketio_daemon_hardened.py +298 -258
  131. claude_mpm/scripts/socketio_server_manager.py +116 -95
  132. claude_mpm/services/__init__.py +49 -49
  133. claude_mpm/services/agent_capabilities_service.py +12 -18
  134. claude_mpm/services/agents/__init__.py +22 -22
  135. claude_mpm/services/agents/agent_builder.py +140 -119
  136. claude_mpm/services/agents/deployment/__init__.py +3 -3
  137. claude_mpm/services/agents/deployment/agent_config_provider.py +9 -9
  138. claude_mpm/services/agents/deployment/agent_configuration_manager.py +19 -20
  139. claude_mpm/services/agents/deployment/agent_definition_factory.py +1 -5
  140. claude_mpm/services/agents/deployment/agent_deployment.py +136 -106
  141. claude_mpm/services/agents/deployment/agent_discovery_service.py +4 -8
  142. claude_mpm/services/agents/deployment/agent_environment_manager.py +2 -7
  143. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +6 -10
  144. claude_mpm/services/agents/deployment/agent_format_converter.py +11 -15
  145. claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +2 -3
  146. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +5 -5
  147. claude_mpm/services/agents/deployment/agent_metrics_collector.py +13 -19
  148. claude_mpm/services/agents/deployment/agent_restore_handler.py +0 -1
  149. claude_mpm/services/agents/deployment/agent_template_builder.py +26 -35
  150. claude_mpm/services/agents/deployment/agent_validator.py +0 -1
  151. claude_mpm/services/agents/deployment/agent_version_manager.py +7 -9
  152. claude_mpm/services/agents/deployment/agent_versioning.py +3 -3
  153. claude_mpm/services/agents/deployment/agents_directory_resolver.py +6 -7
  154. claude_mpm/services/agents/deployment/async_agent_deployment.py +51 -38
  155. claude_mpm/services/agents/deployment/config/__init__.py +1 -1
  156. claude_mpm/services/agents/deployment/config/deployment_config.py +7 -8
  157. claude_mpm/services/agents/deployment/deployment_type_detector.py +1 -1
  158. claude_mpm/services/agents/deployment/deployment_wrapper.py +18 -18
  159. claude_mpm/services/agents/deployment/facade/__init__.py +1 -1
  160. claude_mpm/services/agents/deployment/facade/deployment_executor.py +0 -3
  161. claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -4
  162. claude_mpm/services/agents/deployment/interface_adapter.py +5 -7
  163. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +345 -276
  164. claude_mpm/services/agents/deployment/pipeline/__init__.py +2 -2
  165. claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +1 -1
  166. claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +6 -4
  167. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +3 -3
  168. claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +2 -2
  169. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +14 -13
  170. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +0 -1
  171. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +1 -1
  172. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +8 -9
  173. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +1 -1
  174. claude_mpm/services/agents/deployment/processors/__init__.py +1 -1
  175. claude_mpm/services/agents/deployment/processors/agent_processor.py +20 -16
  176. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +5 -12
  177. claude_mpm/services/agents/deployment/results/__init__.py +1 -1
  178. claude_mpm/services/agents/deployment/results/deployment_result_builder.py +1 -1
  179. claude_mpm/services/agents/deployment/strategies/__init__.py +2 -2
  180. claude_mpm/services/agents/deployment/strategies/base_strategy.py +1 -7
  181. claude_mpm/services/agents/deployment/strategies/project_strategy.py +1 -4
  182. claude_mpm/services/agents/deployment/strategies/system_strategy.py +2 -3
  183. claude_mpm/services/agents/deployment/strategies/user_strategy.py +3 -7
  184. claude_mpm/services/agents/deployment/validation/__init__.py +1 -1
  185. claude_mpm/services/agents/deployment/validation/agent_validator.py +1 -1
  186. claude_mpm/services/agents/deployment/validation/template_validator.py +2 -2
  187. claude_mpm/services/agents/deployment/validation/validation_result.py +2 -6
  188. claude_mpm/services/agents/loading/__init__.py +1 -1
  189. claude_mpm/services/agents/loading/agent_profile_loader.py +6 -12
  190. claude_mpm/services/agents/loading/base_agent_manager.py +5 -5
  191. claude_mpm/services/agents/loading/framework_agent_loader.py +2 -4
  192. claude_mpm/services/agents/management/__init__.py +1 -1
  193. claude_mpm/services/agents/management/agent_capabilities_generator.py +1 -3
  194. claude_mpm/services/agents/management/agent_management_service.py +5 -9
  195. claude_mpm/services/agents/memory/__init__.py +4 -4
  196. claude_mpm/services/agents/memory/agent_memory_manager.py +280 -160
  197. claude_mpm/services/agents/memory/agent_persistence_service.py +0 -2
  198. claude_mpm/services/agents/memory/content_manager.py +44 -38
  199. claude_mpm/services/agents/memory/template_generator.py +4 -6
  200. claude_mpm/services/agents/registry/__init__.py +10 -6
  201. claude_mpm/services/agents/registry/deployed_agent_discovery.py +30 -27
  202. claude_mpm/services/agents/registry/modification_tracker.py +3 -6
  203. claude_mpm/services/async_session_logger.py +1 -2
  204. claude_mpm/services/claude_session_logger.py +1 -2
  205. claude_mpm/services/command_deployment_service.py +173 -0
  206. claude_mpm/services/command_handler_service.py +20 -22
  207. claude_mpm/services/core/__init__.py +25 -25
  208. claude_mpm/services/core/base.py +0 -5
  209. claude_mpm/services/core/interfaces/__init__.py +32 -32
  210. claude_mpm/services/core/interfaces/agent.py +0 -21
  211. claude_mpm/services/core/interfaces/communication.py +0 -27
  212. claude_mpm/services/core/interfaces/infrastructure.py +0 -56
  213. claude_mpm/services/core/interfaces/service.py +0 -29
  214. claude_mpm/services/diagnostics/__init__.py +1 -1
  215. claude_mpm/services/diagnostics/checks/__init__.py +6 -6
  216. claude_mpm/services/diagnostics/checks/agent_check.py +89 -80
  217. claude_mpm/services/diagnostics/checks/base_check.py +12 -16
  218. claude_mpm/services/diagnostics/checks/claude_desktop_check.py +84 -81
  219. claude_mpm/services/diagnostics/checks/common_issues_check.py +99 -91
  220. claude_mpm/services/diagnostics/checks/configuration_check.py +82 -77
  221. claude_mpm/services/diagnostics/checks/filesystem_check.py +67 -68
  222. claude_mpm/services/diagnostics/checks/installation_check.py +254 -94
  223. claude_mpm/services/diagnostics/checks/mcp_check.py +90 -88
  224. claude_mpm/services/diagnostics/checks/monitor_check.py +75 -76
  225. claude_mpm/services/diagnostics/checks/startup_log_check.py +67 -73
  226. claude_mpm/services/diagnostics/diagnostic_runner.py +67 -59
  227. claude_mpm/services/diagnostics/doctor_reporter.py +107 -70
  228. claude_mpm/services/diagnostics/models.py +21 -19
  229. claude_mpm/services/event_aggregator.py +10 -17
  230. claude_mpm/services/event_bus/__init__.py +1 -1
  231. claude_mpm/services/event_bus/config.py +54 -35
  232. claude_mpm/services/event_bus/event_bus.py +76 -71
  233. claude_mpm/services/event_bus/relay.py +74 -64
  234. claude_mpm/services/events/__init__.py +11 -11
  235. claude_mpm/services/events/consumers/__init__.py +3 -3
  236. claude_mpm/services/events/consumers/dead_letter.py +71 -63
  237. claude_mpm/services/events/consumers/logging.py +39 -37
  238. claude_mpm/services/events/consumers/metrics.py +56 -57
  239. claude_mpm/services/events/consumers/socketio.py +82 -81
  240. claude_mpm/services/events/core.py +110 -99
  241. claude_mpm/services/events/interfaces.py +56 -72
  242. claude_mpm/services/events/producers/__init__.py +1 -1
  243. claude_mpm/services/events/producers/hook.py +38 -38
  244. claude_mpm/services/events/producers/system.py +46 -44
  245. claude_mpm/services/exceptions.py +81 -80
  246. claude_mpm/services/framework_claude_md_generator/__init__.py +2 -4
  247. claude_mpm/services/framework_claude_md_generator/content_assembler.py +3 -5
  248. claude_mpm/services/framework_claude_md_generator/content_validator.py +1 -1
  249. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +4 -4
  250. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +0 -1
  251. claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +0 -2
  252. claude_mpm/services/framework_claude_md_generator/version_manager.py +4 -5
  253. claude_mpm/services/hook_service.py +6 -9
  254. claude_mpm/services/infrastructure/__init__.py +1 -1
  255. claude_mpm/services/infrastructure/context_preservation.py +8 -12
  256. claude_mpm/services/infrastructure/monitoring.py +21 -23
  257. claude_mpm/services/mcp_gateway/__init__.py +37 -37
  258. claude_mpm/services/mcp_gateway/auto_configure.py +95 -103
  259. claude_mpm/services/mcp_gateway/config/__init__.py +1 -1
  260. claude_mpm/services/mcp_gateway/config/config_loader.py +23 -25
  261. claude_mpm/services/mcp_gateway/config/config_schema.py +5 -5
  262. claude_mpm/services/mcp_gateway/config/configuration.py +9 -6
  263. claude_mpm/services/mcp_gateway/core/__init__.py +10 -10
  264. claude_mpm/services/mcp_gateway/core/base.py +0 -3
  265. claude_mpm/services/mcp_gateway/core/interfaces.py +1 -38
  266. claude_mpm/services/mcp_gateway/core/process_pool.py +99 -93
  267. claude_mpm/services/mcp_gateway/core/singleton_manager.py +65 -62
  268. claude_mpm/services/mcp_gateway/core/startup_verification.py +75 -74
  269. claude_mpm/services/mcp_gateway/main.py +2 -1
  270. claude_mpm/services/mcp_gateway/registry/service_registry.py +5 -8
  271. claude_mpm/services/mcp_gateway/registry/tool_registry.py +1 -1
  272. claude_mpm/services/mcp_gateway/server/__init__.py +1 -1
  273. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +12 -19
  274. claude_mpm/services/mcp_gateway/server/stdio_handler.py +4 -3
  275. claude_mpm/services/mcp_gateway/server/stdio_server.py +79 -71
  276. claude_mpm/services/mcp_gateway/tools/__init__.py +2 -2
  277. claude_mpm/services/mcp_gateway/tools/base_adapter.py +5 -6
  278. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +13 -22
  279. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +79 -78
  280. claude_mpm/services/mcp_gateway/tools/hello_world.py +12 -14
  281. claude_mpm/services/mcp_gateway/tools/ticket_tools.py +42 -49
  282. claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +51 -55
  283. claude_mpm/services/memory/__init__.py +3 -3
  284. claude_mpm/services/memory/builder.py +3 -6
  285. claude_mpm/services/memory/cache/__init__.py +1 -1
  286. claude_mpm/services/memory/cache/shared_prompt_cache.py +3 -5
  287. claude_mpm/services/memory/cache/simple_cache.py +1 -1
  288. claude_mpm/services/memory/indexed_memory.py +5 -7
  289. claude_mpm/services/memory/optimizer.py +7 -10
  290. claude_mpm/services/memory/router.py +8 -9
  291. claude_mpm/services/memory_hook_service.py +48 -34
  292. claude_mpm/services/monitor_build_service.py +77 -73
  293. claude_mpm/services/port_manager.py +130 -108
  294. claude_mpm/services/project/analyzer.py +12 -10
  295. claude_mpm/services/project/registry.py +11 -11
  296. claude_mpm/services/recovery_manager.py +10 -19
  297. claude_mpm/services/response_tracker.py +0 -1
  298. claude_mpm/services/runner_configuration_service.py +19 -20
  299. claude_mpm/services/session_management_service.py +7 -11
  300. claude_mpm/services/shared/__init__.py +1 -1
  301. claude_mpm/services/shared/async_service_base.py +58 -50
  302. claude_mpm/services/shared/config_service_base.py +73 -67
  303. claude_mpm/services/shared/lifecycle_service_base.py +82 -78
  304. claude_mpm/services/shared/manager_base.py +94 -82
  305. claude_mpm/services/shared/service_factory.py +96 -98
  306. claude_mpm/services/socketio/__init__.py +3 -3
  307. claude_mpm/services/socketio/client_proxy.py +5 -5
  308. claude_mpm/services/socketio/event_normalizer.py +199 -181
  309. claude_mpm/services/socketio/handlers/__init__.py +3 -3
  310. claude_mpm/services/socketio/handlers/base.py +5 -4
  311. claude_mpm/services/socketio/handlers/connection.py +163 -136
  312. claude_mpm/services/socketio/handlers/file.py +13 -14
  313. claude_mpm/services/socketio/handlers/git.py +12 -7
  314. claude_mpm/services/socketio/handlers/hook.py +49 -44
  315. claude_mpm/services/socketio/handlers/memory.py +0 -1
  316. claude_mpm/services/socketio/handlers/project.py +0 -1
  317. claude_mpm/services/socketio/handlers/registry.py +37 -19
  318. claude_mpm/services/socketio/migration_utils.py +98 -84
  319. claude_mpm/services/socketio/server/__init__.py +1 -1
  320. claude_mpm/services/socketio/server/broadcaster.py +81 -87
  321. claude_mpm/services/socketio/server/core.py +65 -54
  322. claude_mpm/services/socketio/server/eventbus_integration.py +95 -56
  323. claude_mpm/services/socketio/server/main.py +64 -38
  324. claude_mpm/services/socketio_client_manager.py +10 -12
  325. claude_mpm/services/subprocess_launcher_service.py +4 -7
  326. claude_mpm/services/system_instructions_service.py +13 -14
  327. claude_mpm/services/ticket_manager.py +2 -2
  328. claude_mpm/services/utility_service.py +5 -13
  329. claude_mpm/services/version_control/__init__.py +16 -16
  330. claude_mpm/services/version_control/branch_strategy.py +5 -8
  331. claude_mpm/services/version_control/conflict_resolution.py +9 -23
  332. claude_mpm/services/version_control/git_operations.py +5 -7
  333. claude_mpm/services/version_control/semantic_versioning.py +16 -17
  334. claude_mpm/services/version_control/version_parser.py +13 -18
  335. claude_mpm/services/version_service.py +10 -11
  336. claude_mpm/storage/__init__.py +1 -1
  337. claude_mpm/storage/state_storage.py +22 -28
  338. claude_mpm/utils/__init__.py +6 -6
  339. claude_mpm/utils/agent_dependency_loader.py +47 -33
  340. claude_mpm/utils/config_manager.py +11 -14
  341. claude_mpm/utils/dependency_cache.py +1 -1
  342. claude_mpm/utils/dependency_manager.py +13 -17
  343. claude_mpm/utils/dependency_strategies.py +8 -10
  344. claude_mpm/utils/environment_context.py +3 -9
  345. claude_mpm/utils/error_handler.py +3 -13
  346. claude_mpm/utils/file_utils.py +1 -1
  347. claude_mpm/utils/path_operations.py +8 -12
  348. claude_mpm/utils/robust_installer.py +110 -33
  349. claude_mpm/utils/subprocess_utils.py +5 -6
  350. claude_mpm/validation/agent_validator.py +3 -6
  351. claude_mpm/validation/frontmatter_validator.py +1 -1
  352. {claude_mpm-4.1.0.dist-info → claude_mpm-4.1.2.dist-info}/METADATA +1 -1
  353. claude_mpm-4.1.2.dist-info/RECORD +498 -0
  354. claude_mpm-4.1.0.dist-info/RECORD +0 -494
  355. {claude_mpm-4.1.0.dist-info → claude_mpm-4.1.2.dist-info}/WHEEL +0 -0
  356. {claude_mpm-4.1.0.dist-info → claude_mpm-4.1.2.dist-info}/entry_points.txt +0 -0
  357. {claude_mpm-4.1.0.dist-info → claude_mpm-4.1.2.dist-info}/licenses/LICENSE +0 -0
  358. {claude_mpm-4.1.0.dist-info → claude_mpm-4.1.2.dist-info}/top_level.txt +0 -0
@@ -19,16 +19,15 @@ import asyncio
19
19
  import logging
20
20
  import os
21
21
  import signal
22
- import threading
23
22
  import time
24
23
  from abc import ABC, abstractmethod
25
24
  from collections import deque
26
25
  from dataclasses import dataclass
27
26
  from datetime import datetime, timezone
28
27
  from enum import Enum
29
- from typing import Any, Callable, Dict, List, Optional, Union
28
+ from typing import Any, Callable, Dict, List, Optional
30
29
 
31
- from claude_mpm.core.constants import PerformanceConfig, RetryConfig, TimeoutConfig
30
+ from claude_mpm.core.constants import PerformanceConfig, RetryConfig
32
31
 
33
32
  from .infrastructure.monitoring import HealthCheckResult, HealthStatus
34
33
 
@@ -85,17 +84,14 @@ class RecoveryStrategy(ABC):
85
84
  @abstractmethod
86
85
  def should_recover(self, health_result: HealthCheckResult) -> bool:
87
86
  """Determine if recovery should be triggered based on health result."""
88
- pass
89
87
 
90
88
  @abstractmethod
91
89
  def get_recovery_action(self, health_result: HealthCheckResult) -> RecoveryAction:
92
90
  """Determine the appropriate recovery action."""
93
- pass
94
91
 
95
92
  @abstractmethod
96
93
  def get_name(self) -> str:
97
94
  """Get the name of this recovery strategy."""
98
- pass
99
95
 
100
96
 
101
97
  class GradedRecoveryStrategy(RecoveryStrategy):
@@ -183,16 +179,14 @@ class GradedRecoveryStrategy(RecoveryStrategy):
183
179
  if health_result.overall_status == HealthStatus.CRITICAL:
184
180
  if failure_count >= 3:
185
181
  return RecoveryAction.EMERGENCY_STOP
186
- elif failure_count >= 2:
182
+ if failure_count >= 2:
187
183
  return RecoveryAction.RESTART_SERVICE
188
- else:
189
- return RecoveryAction.CLEAR_CONNECTIONS
184
+ return RecoveryAction.CLEAR_CONNECTIONS
190
185
 
191
- elif health_result.overall_status == HealthStatus.WARNING:
186
+ if health_result.overall_status == HealthStatus.WARNING:
192
187
  if failure_count >= self.warning_threshold:
193
188
  return RecoveryAction.CLEAR_CONNECTIONS
194
- else:
195
- return RecoveryAction.LOG_WARNING
189
+ return RecoveryAction.LOG_WARNING
196
190
 
197
191
  return RecoveryAction.NONE
198
192
 
@@ -242,17 +236,14 @@ class CircuitBreaker:
242
236
  if self.state == CircuitState.CLOSED:
243
237
  return True
244
238
 
245
- elif self.state == CircuitState.OPEN:
239
+ if self.state == CircuitState.OPEN:
246
240
  # Check if timeout has elapsed
247
241
  if current_time - self.last_failure_time >= self.timeout_seconds:
248
242
  self._transition_to_half_open()
249
243
  return True
250
244
  return False
251
245
 
252
- elif self.state == CircuitState.HALF_OPEN:
253
- return True
254
-
255
- return False
246
+ return self.state == CircuitState.HALF_OPEN
256
247
 
257
248
  def record_success(self) -> None:
258
249
  """Record a successful recovery operation."""
@@ -612,8 +603,8 @@ class RecoveryManager:
612
603
  self.logger.info("Attempting graceful service restart")
613
604
 
614
605
  # Save current configuration
615
- host = getattr(self.server_instance, "host", "localhost")
616
- port = getattr(self.server_instance, "port", 8765)
606
+ getattr(self.server_instance, "host", "localhost")
607
+ getattr(self.server_instance, "port", 8765)
617
608
 
618
609
  # Stop current server
619
610
  try:
@@ -24,7 +24,6 @@ from typing import Any, Dict, Optional
24
24
 
25
25
  from claude_mpm.core.config import Config
26
26
  from claude_mpm.core.shared.config_loader import ConfigLoader
27
- from claude_mpm.services.claude_session_logger import ClaudeSessionLogger
28
27
 
29
28
  logger = logging.getLogger(__name__)
30
29
 
@@ -17,9 +17,8 @@ from typing import Any, Dict, List, Optional, Tuple
17
17
 
18
18
  from claude_mpm.core.base_service import BaseService
19
19
  from claude_mpm.core.config import Config
20
- from claude_mpm.core.container import ServiceLifetime, get_container
20
+ from claude_mpm.core.container import ServiceLifetime
21
21
  from claude_mpm.core.logger import get_project_logger
22
- from claude_mpm.core.logging_config import get_logger
23
22
  from claude_mpm.core.shared.config_loader import ConfigLoader
24
23
  from claude_mpm.services.core.interfaces import RunnerConfigurationInterface
25
24
 
@@ -33,11 +32,9 @@ class RunnerConfigurationService(BaseService, RunnerConfigurationInterface):
33
32
 
34
33
  async def _initialize(self) -> None:
35
34
  """Initialize the service. No special initialization needed."""
36
- pass
37
35
 
38
36
  async def _cleanup(self) -> None:
39
37
  """Cleanup service resources. No cleanup needed."""
40
- pass
41
38
 
42
39
  # Implementation of abstract methods from RunnerConfigurationInterface
43
40
 
@@ -61,7 +58,6 @@ class RunnerConfigurationService(BaseService, RunnerConfigurationInterface):
61
58
  """
62
59
  # This method can delegate to existing service registration methods
63
60
  # For now, this is a no-op as service registration is handled elsewhere
64
- pass
65
61
 
66
62
  def load_configuration(self, config_path: Optional[Path] = None) -> Dict[str, Any]:
67
63
  """Load configuration from file or defaults.
@@ -78,12 +74,15 @@ class RunnerConfigurationService(BaseService, RunnerConfigurationInterface):
78
74
  if config_path:
79
75
  # Use specific config file with ConfigLoader
80
76
  from claude_mpm.core.shared.config_loader import ConfigPattern
77
+
81
78
  pattern = ConfigPattern(
82
79
  filenames=[Path(config_path).name],
83
80
  search_paths=[str(Path(config_path).parent)],
84
- env_prefix="CLAUDE_MPM_"
81
+ env_prefix="CLAUDE_MPM_",
82
+ )
83
+ config = config_loader.load_config(
84
+ pattern, cache_key=f"runner_{config_path}"
85
85
  )
86
- config = config_loader.load_config(pattern, cache_key=f"runner_{config_path}")
87
86
  else:
88
87
  # Use main config
89
88
  config = config_loader.load_main_config()
@@ -198,7 +197,7 @@ class RunnerConfigurationService(BaseService, RunnerConfigurationInterface):
198
197
  try:
199
198
  project_logger = get_project_logger(log_level)
200
199
  project_logger.log_system(
201
- f"Initializing ClaudeRunner", level="INFO", component="runner"
200
+ "Initializing ClaudeRunner", level="INFO", component="runner"
202
201
  )
203
202
  return project_logger
204
203
  except ImportError as e:
@@ -231,7 +230,7 @@ class RunnerConfigurationService(BaseService, RunnerConfigurationInterface):
231
230
  "Response logging initialized", level="INFO", component="logging"
232
231
  )
233
232
  return response_logger
234
- except Exception as e:
233
+ except Exception:
235
234
  self.logger.warning("Failed to initialize response logger", exc_info=True)
236
235
  return None
237
236
 
@@ -244,7 +243,7 @@ class RunnerConfigurationService(BaseService, RunnerConfigurationInterface):
244
243
  if "CLAUDE_MPM_USER_PWD" in os.environ:
245
244
  user_working_dir = Path(os.environ["CLAUDE_MPM_USER_PWD"])
246
245
  self.logger.info(
247
- f"Using user working directory from CLAUDE_MPM_USER_PWD",
246
+ "Using user working directory from CLAUDE_MPM_USER_PWD",
248
247
  extra={"directory": str(user_working_dir)},
249
248
  )
250
249
  return user_working_dir
@@ -310,7 +309,7 @@ class RunnerConfigurationService(BaseService, RunnerConfigurationInterface):
310
309
 
311
310
  try:
312
311
  return container.get(HookServiceInterface)
313
- except Exception as e:
312
+ except Exception:
314
313
  self.logger.warning("Failed to initialize hook service", exc_info=True)
315
314
  return None
316
315
 
@@ -336,7 +335,7 @@ class RunnerConfigurationService(BaseService, RunnerConfigurationInterface):
336
335
 
337
336
  try:
338
337
  return container.get(AgentCapabilitiesInterface)
339
- except Exception as e:
338
+ except Exception:
340
339
  self.logger.warning(
341
340
  "Failed to initialize agent capabilities service", exc_info=True
342
341
  )
@@ -371,7 +370,7 @@ class RunnerConfigurationService(BaseService, RunnerConfigurationInterface):
371
370
 
372
371
  try:
373
372
  return container.get(SystemInstructionsInterface)
374
- except Exception as e:
373
+ except Exception:
375
374
  self.logger.warning(
376
375
  "Failed to initialize system instructions service", exc_info=True
377
376
  )
@@ -407,7 +406,7 @@ class RunnerConfigurationService(BaseService, RunnerConfigurationInterface):
407
406
 
408
407
  try:
409
408
  return container.get(SubprocessLauncherInterface)
410
- except Exception as e:
409
+ except Exception:
411
410
  self.logger.warning(
412
411
  "Failed to initialize subprocess launcher service", exc_info=True
413
412
  )
@@ -431,7 +430,7 @@ class RunnerConfigurationService(BaseService, RunnerConfigurationInterface):
431
430
 
432
431
  try:
433
432
  return container.get(VersionServiceInterface)
434
- except Exception as e:
433
+ except Exception:
435
434
  self.logger.warning("Failed to initialize version service", exc_info=True)
436
435
  return None
437
436
 
@@ -460,7 +459,7 @@ class RunnerConfigurationService(BaseService, RunnerConfigurationInterface):
460
459
 
461
460
  try:
462
461
  return container.get(CommandHandlerInterface)
463
- except Exception as e:
462
+ except Exception:
464
463
  self.logger.warning(
465
464
  "Failed to initialize command handler service", exc_info=True
466
465
  )
@@ -489,7 +488,7 @@ class RunnerConfigurationService(BaseService, RunnerConfigurationInterface):
489
488
 
490
489
  try:
491
490
  return container.get(MemoryHookInterface)
492
- except Exception as e:
491
+ except Exception:
493
492
  self.logger.warning(
494
493
  "Failed to initialize memory hook service", exc_info=True
495
494
  )
@@ -520,7 +519,7 @@ class RunnerConfigurationService(BaseService, RunnerConfigurationInterface):
520
519
 
521
520
  try:
522
521
  return container.get(SessionManagementInterface)
523
- except Exception as e:
522
+ except Exception:
524
523
  self.logger.warning(
525
524
  "Failed to initialize session management service", exc_info=True
526
525
  )
@@ -544,7 +543,7 @@ class RunnerConfigurationService(BaseService, RunnerConfigurationInterface):
544
543
 
545
544
  try:
546
545
  return container.get(UtilityServiceInterface)
547
- except Exception as e:
546
+ except Exception:
548
547
  self.logger.warning("Failed to initialize utility service", exc_info=True)
549
548
  return None
550
549
 
@@ -569,7 +568,7 @@ class RunnerConfigurationService(BaseService, RunnerConfigurationInterface):
569
568
  session_log_file = project_logger.session_dir / "system.jsonl"
570
569
 
571
570
  # Log session start event
572
- session_event = {
571
+ {
573
572
  "event": "session_start",
574
573
  "runner": "ClaudeRunner",
575
574
  "enable_tickets": config_data.get("enable_tickets"),
@@ -34,11 +34,9 @@ class SessionManagementService(BaseService, SessionManagementInterface):
34
34
 
35
35
  async def _initialize(self) -> None:
36
36
  """Initialize the service. No special initialization needed."""
37
- pass
38
37
 
39
38
  async def _cleanup(self) -> None:
40
39
  """Cleanup service resources. No cleanup needed."""
41
- pass
42
40
 
43
41
  def run_interactive_session(self, initial_context: Optional[str] = None) -> bool:
44
42
  """Run Claude in interactive mode using session delegation.
@@ -252,9 +250,8 @@ class SessionManagementService(BaseService, SessionManagementInterface):
252
250
 
253
251
  self.logger.info(f"Ended session {session_id}")
254
252
  return True
255
- else:
256
- self.logger.warning(f"Session {session_id} not found")
257
- return False
253
+ self.logger.warning(f"Session {session_id} not found")
254
+ return False
258
255
 
259
256
  def get_session_status(self, session_id: str) -> Dict[str, Any]:
260
257
  """Get status of a session.
@@ -267,12 +264,11 @@ class SessionManagementService(BaseService, SessionManagementInterface):
267
264
  """
268
265
  if session_id in self.active_sessions:
269
266
  return self.active_sessions[session_id].copy()
270
- else:
271
- return {
272
- "id": session_id,
273
- "status": "not_found",
274
- "error": "Session not found",
275
- }
267
+ return {
268
+ "id": session_id,
269
+ "status": "not_found",
270
+ "error": "Session not found",
271
+ }
276
272
 
277
273
  def list_active_sessions(self) -> List[str]:
278
274
  """List all active session IDs.
@@ -13,7 +13,7 @@ from .service_factory import ServiceFactory
13
13
 
14
14
  __all__ = [
15
15
  "AsyncServiceBase",
16
- "ConfigServiceBase",
16
+ "ConfigServiceBase",
17
17
  "LifecycleServiceBase",
18
18
  "ManagerBase",
19
19
  "ServiceFactory",
@@ -12,6 +12,7 @@ from ...core.mixins import LoggerMixin
12
12
 
13
13
  class AsyncServiceState(Enum):
14
14
  """Standard states for async services."""
15
+
15
16
  UNINITIALIZED = "uninitialized"
16
17
  INITIALIZING = "initializing"
17
18
  RUNNING = "running"
@@ -23,18 +24,18 @@ class AsyncServiceState(Enum):
23
24
  class AsyncServiceBase(LoggerMixin, ABC):
24
25
  """
25
26
  Base class for asynchronous services.
26
-
27
+
27
28
  Provides common patterns:
28
29
  - State management
29
30
  - Lifecycle methods
30
31
  - Error handling
31
32
  - Background task management
32
33
  """
33
-
34
+
34
35
  def __init__(self, service_name: str, config: Optional[Dict[str, Any]] = None):
35
36
  """
36
37
  Initialize async service.
37
-
38
+
38
39
  Args:
39
40
  service_name: Name of the service
40
41
  config: Optional configuration dictionary
@@ -42,38 +43,38 @@ class AsyncServiceBase(LoggerMixin, ABC):
42
43
  self.service_name = service_name
43
44
  self._logger_name = f"service.{service_name}"
44
45
  self.config = config or {}
45
-
46
+
46
47
  # State management
47
48
  self._state = AsyncServiceState.UNINITIALIZED
48
49
  self._state_lock = asyncio.Lock()
49
-
50
+
50
51
  # Background tasks
51
52
  self._background_tasks: set = set()
52
53
  self._shutdown_event = asyncio.Event()
53
-
54
+
54
55
  # Error tracking
55
56
  self._last_error: Optional[Exception] = None
56
57
  self._error_count = 0
57
-
58
+
58
59
  @property
59
60
  def state(self) -> AsyncServiceState:
60
61
  """Get current service state."""
61
62
  return self._state
62
-
63
+
63
64
  @property
64
65
  def is_running(self) -> bool:
65
66
  """Check if service is running."""
66
67
  return self._state == AsyncServiceState.RUNNING
67
-
68
+
68
69
  @property
69
70
  def is_healthy(self) -> bool:
70
71
  """Check if service is healthy."""
71
72
  return self._state == AsyncServiceState.RUNNING and self._last_error is None
72
-
73
+
73
74
  async def initialize(self) -> bool:
74
75
  """
75
76
  Initialize the service.
76
-
77
+
77
78
  Returns:
78
79
  True if initialization successful
79
80
  """
@@ -81,113 +82,122 @@ class AsyncServiceBase(LoggerMixin, ABC):
81
82
  if self._state != AsyncServiceState.UNINITIALIZED:
82
83
  self.logger.warning(f"Service {self.service_name} already initialized")
83
84
  return self._state == AsyncServiceState.RUNNING
84
-
85
+
85
86
  self._state = AsyncServiceState.INITIALIZING
86
87
  self.logger.info(f"Initializing service: {self.service_name}")
87
-
88
+
88
89
  try:
89
90
  success = await self._do_initialize()
90
91
  if success:
91
92
  self._state = AsyncServiceState.RUNNING
92
- self.logger.info(f"Service {self.service_name} initialized successfully")
93
+ self.logger.info(
94
+ f"Service {self.service_name} initialized successfully"
95
+ )
93
96
  else:
94
97
  self._state = AsyncServiceState.ERROR
95
- self.logger.error(f"Service {self.service_name} initialization failed")
96
-
98
+ self.logger.error(
99
+ f"Service {self.service_name} initialization failed"
100
+ )
101
+
97
102
  return success
98
-
103
+
99
104
  except Exception as e:
100
105
  self._state = AsyncServiceState.ERROR
101
106
  self._last_error = e
102
107
  self._error_count += 1
103
- self.logger.error(f"Service {self.service_name} initialization error: {e}", exc_info=True)
108
+ self.logger.error(
109
+ f"Service {self.service_name} initialization error: {e}",
110
+ exc_info=True,
111
+ )
104
112
  return False
105
-
113
+
106
114
  async def shutdown(self) -> None:
107
115
  """Shutdown the service gracefully."""
108
116
  async with self._state_lock:
109
117
  if self._state in (AsyncServiceState.STOPPED, AsyncServiceState.STOPPING):
110
118
  return
111
-
119
+
112
120
  self._state = AsyncServiceState.STOPPING
113
121
  self.logger.info(f"Shutting down service: {self.service_name}")
114
-
122
+
115
123
  try:
116
124
  # Signal shutdown to background tasks
117
125
  self._shutdown_event.set()
118
-
126
+
119
127
  # Cancel background tasks
120
128
  await self._cancel_background_tasks()
121
-
129
+
122
130
  # Service-specific shutdown
123
131
  await self._do_shutdown()
124
-
132
+
125
133
  self._state = AsyncServiceState.STOPPED
126
134
  self.logger.info(f"Service {self.service_name} shut down successfully")
127
-
135
+
128
136
  except Exception as e:
129
137
  self._state = AsyncServiceState.ERROR
130
138
  self._last_error = e
131
- self.logger.error(f"Service {self.service_name} shutdown error: {e}", exc_info=True)
132
-
139
+ self.logger.error(
140
+ f"Service {self.service_name} shutdown error: {e}", exc_info=True
141
+ )
142
+
133
143
  async def restart(self) -> bool:
134
144
  """Restart the service."""
135
145
  self.logger.info(f"Restarting service: {self.service_name}")
136
146
  await self.shutdown()
137
-
147
+
138
148
  # Reset state for restart
139
149
  self._state = AsyncServiceState.UNINITIALIZED
140
150
  self._shutdown_event.clear()
141
151
  self._last_error = None
142
-
152
+
143
153
  return await self.initialize()
144
-
145
- def create_background_task(self, coro, name: str = None) -> asyncio.Task:
154
+
155
+ def create_background_task(self, coro, name: Optional[str] = None) -> asyncio.Task:
146
156
  """
147
157
  Create and track a background task.
148
-
158
+
149
159
  Args:
150
160
  coro: Coroutine to run
151
161
  name: Optional task name
152
-
162
+
153
163
  Returns:
154
164
  Created task
155
165
  """
156
166
  task = asyncio.create_task(coro, name=name)
157
167
  self._background_tasks.add(task)
158
-
168
+
159
169
  # Remove task from set when done
160
170
  task.add_done_callback(self._background_tasks.discard)
161
-
171
+
162
172
  return task
163
-
173
+
164
174
  async def _cancel_background_tasks(self) -> None:
165
175
  """Cancel all background tasks."""
166
176
  if not self._background_tasks:
167
177
  return
168
-
178
+
169
179
  self.logger.debug(f"Cancelling {len(self._background_tasks)} background tasks")
170
-
180
+
171
181
  # Cancel all tasks
172
182
  for task in self._background_tasks:
173
183
  if not task.done():
174
184
  task.cancel()
175
-
185
+
176
186
  # Wait for cancellation with timeout
177
187
  try:
178
188
  await asyncio.wait_for(
179
189
  asyncio.gather(*self._background_tasks, return_exceptions=True),
180
- timeout=5.0
190
+ timeout=5.0,
181
191
  )
182
192
  except asyncio.TimeoutError:
183
193
  self.logger.warning("Some background tasks did not cancel within timeout")
184
-
194
+
185
195
  self._background_tasks.clear()
186
-
196
+
187
197
  async def health_check(self) -> Dict[str, Any]:
188
198
  """
189
199
  Perform health check.
190
-
200
+
191
201
  Returns:
192
202
  Health status dictionary
193
203
  """
@@ -197,23 +207,21 @@ class AsyncServiceBase(LoggerMixin, ABC):
197
207
  "healthy": self.is_healthy,
198
208
  "error_count": self._error_count,
199
209
  "last_error": str(self._last_error) if self._last_error else None,
200
- "background_tasks": len(self._background_tasks)
210
+ "background_tasks": len(self._background_tasks),
201
211
  }
202
-
212
+
203
213
  @abstractmethod
204
214
  async def _do_initialize(self) -> bool:
205
215
  """
206
216
  Service-specific initialization logic.
207
-
217
+
208
218
  Returns:
209
219
  True if initialization successful
210
220
  """
211
- pass
212
-
221
+
213
222
  async def _do_shutdown(self) -> None:
214
223
  """Service-specific shutdown logic."""
215
- pass
216
-
224
+
217
225
  def __repr__(self) -> str:
218
226
  """String representation."""
219
227
  return f"{self.__class__.__name__}(name={self.service_name}, state={self._state.value})"