claude-mpm 4.1.1__py3-none-any.whl → 4.1.3__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 (389) 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/engineer.json +33 -11
  18. claude_mpm/agents/templates/imagemagick.json +256 -0
  19. claude_mpm/agents/templates/qa.json +41 -2
  20. claude_mpm/agents/templates/ticketing.json +5 -5
  21. claude_mpm/agents/templates/web_qa.json +50 -2
  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 +648 -1098
  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 +339 -967
  39. claude_mpm/cli/commands/monitor.py +117 -88
  40. claude_mpm/cli/commands/run.py +233 -542
  41. claude_mpm/cli/commands/socketio_monitor.py +17 -19
  42. claude_mpm/cli/commands/tickets.py +92 -92
  43. claude_mpm/cli/parser.py +1 -5
  44. claude_mpm/cli/parsers/__init__.py +1 -1
  45. claude_mpm/cli/parsers/agent_manager_parser.py +50 -98
  46. claude_mpm/cli/parsers/agents_parser.py +2 -3
  47. claude_mpm/cli/parsers/base_parser.py +7 -5
  48. claude_mpm/cli/parsers/mcp_parser.py +4 -2
  49. claude_mpm/cli/parsers/monitor_parser.py +26 -18
  50. claude_mpm/cli/shared/__init__.py +10 -10
  51. claude_mpm/cli/shared/argument_patterns.py +57 -71
  52. claude_mpm/cli/shared/base_command.py +61 -53
  53. claude_mpm/cli/shared/error_handling.py +62 -58
  54. claude_mpm/cli/shared/output_formatters.py +78 -77
  55. claude_mpm/cli/startup_logging.py +280 -172
  56. claude_mpm/cli/utils.py +10 -11
  57. claude_mpm/cli_module/__init__.py +1 -1
  58. claude_mpm/cli_module/args.py +1 -1
  59. claude_mpm/cli_module/migration_example.py +5 -5
  60. claude_mpm/config/__init__.py +9 -9
  61. claude_mpm/config/agent_config.py +15 -14
  62. claude_mpm/config/experimental_features.py +4 -4
  63. claude_mpm/config/paths.py +0 -1
  64. claude_mpm/config/socketio_config.py +5 -6
  65. claude_mpm/constants.py +1 -2
  66. claude_mpm/core/__init__.py +8 -8
  67. claude_mpm/core/agent_name_normalizer.py +1 -1
  68. claude_mpm/core/agent_registry.py +22 -29
  69. claude_mpm/core/agent_session_manager.py +3 -3
  70. claude_mpm/core/base_service.py +7 -15
  71. claude_mpm/core/cache.py +4 -6
  72. claude_mpm/core/claude_runner.py +85 -113
  73. claude_mpm/core/config.py +43 -28
  74. claude_mpm/core/config_aliases.py +0 -9
  75. claude_mpm/core/config_constants.py +52 -30
  76. claude_mpm/core/constants.py +0 -1
  77. claude_mpm/core/container.py +18 -27
  78. claude_mpm/core/exceptions.py +2 -2
  79. claude_mpm/core/factories.py +10 -12
  80. claude_mpm/core/framework_loader.py +500 -680
  81. claude_mpm/core/hook_manager.py +26 -22
  82. claude_mpm/core/hook_performance_config.py +58 -47
  83. claude_mpm/core/injectable_service.py +1 -1
  84. claude_mpm/core/interactive_session.py +61 -152
  85. claude_mpm/core/interfaces.py +1 -100
  86. claude_mpm/core/lazy.py +5 -5
  87. claude_mpm/core/log_manager.py +587 -0
  88. claude_mpm/core/logger.py +125 -8
  89. claude_mpm/core/logging_config.py +15 -17
  90. claude_mpm/core/minimal_framework_loader.py +5 -8
  91. claude_mpm/core/oneshot_session.py +15 -33
  92. claude_mpm/core/optimized_agent_loader.py +4 -6
  93. claude_mpm/core/optimized_startup.py +2 -1
  94. claude_mpm/core/output_style_manager.py +147 -106
  95. claude_mpm/core/pm_hook_interceptor.py +0 -1
  96. claude_mpm/core/service_registry.py +11 -8
  97. claude_mpm/core/session_manager.py +1 -2
  98. claude_mpm/core/shared/__init__.py +1 -1
  99. claude_mpm/core/shared/config_loader.py +101 -97
  100. claude_mpm/core/shared/path_resolver.py +72 -68
  101. claude_mpm/core/shared/singleton_manager.py +56 -50
  102. claude_mpm/core/socketio_pool.py +26 -6
  103. claude_mpm/core/tool_access_control.py +4 -5
  104. claude_mpm/core/typing_utils.py +50 -59
  105. claude_mpm/core/unified_agent_registry.py +14 -19
  106. claude_mpm/core/unified_config.py +4 -6
  107. claude_mpm/core/unified_paths.py +197 -109
  108. claude_mpm/dashboard/open_dashboard.py +2 -4
  109. claude_mpm/experimental/cli_enhancements.py +51 -36
  110. claude_mpm/generators/agent_profile_generator.py +2 -4
  111. claude_mpm/hooks/base_hook.py +1 -2
  112. claude_mpm/hooks/claude_hooks/connection_pool.py +72 -26
  113. claude_mpm/hooks/claude_hooks/event_handlers.py +99 -154
  114. claude_mpm/hooks/claude_hooks/hook_handler.py +110 -720
  115. claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +104 -77
  116. claude_mpm/hooks/claude_hooks/hook_handler_original.py +1040 -0
  117. claude_mpm/hooks/claude_hooks/hook_handler_refactored.py +347 -0
  118. claude_mpm/hooks/claude_hooks/memory_integration.py +2 -4
  119. claude_mpm/hooks/claude_hooks/response_tracking.py +15 -11
  120. claude_mpm/hooks/claude_hooks/services/__init__.py +13 -0
  121. claude_mpm/hooks/claude_hooks/services/connection_manager.py +190 -0
  122. claude_mpm/hooks/claude_hooks/services/duplicate_detector.py +106 -0
  123. claude_mpm/hooks/claude_hooks/services/state_manager.py +282 -0
  124. claude_mpm/hooks/claude_hooks/services/subagent_processor.py +374 -0
  125. claude_mpm/hooks/claude_hooks/tool_analysis.py +12 -18
  126. claude_mpm/hooks/memory_integration_hook.py +5 -5
  127. claude_mpm/hooks/tool_call_interceptor.py +1 -1
  128. claude_mpm/hooks/validation_hooks.py +4 -4
  129. claude_mpm/init.py +4 -9
  130. claude_mpm/models/__init__.py +2 -2
  131. claude_mpm/models/agent_session.py +11 -14
  132. claude_mpm/scripts/mcp_server.py +20 -11
  133. claude_mpm/scripts/mcp_wrapper.py +5 -5
  134. claude_mpm/scripts/mpm_doctor.py +321 -0
  135. claude_mpm/scripts/socketio_daemon.py +28 -25
  136. claude_mpm/scripts/socketio_daemon_hardened.py +298 -258
  137. claude_mpm/scripts/socketio_server_manager.py +116 -95
  138. claude_mpm/services/__init__.py +49 -49
  139. claude_mpm/services/agent_capabilities_service.py +12 -18
  140. claude_mpm/services/agents/__init__.py +22 -22
  141. claude_mpm/services/agents/agent_builder.py +140 -119
  142. claude_mpm/services/agents/deployment/__init__.py +3 -3
  143. claude_mpm/services/agents/deployment/agent_config_provider.py +9 -9
  144. claude_mpm/services/agents/deployment/agent_configuration_manager.py +19 -20
  145. claude_mpm/services/agents/deployment/agent_definition_factory.py +1 -5
  146. claude_mpm/services/agents/deployment/agent_deployment.py +129 -511
  147. claude_mpm/services/agents/deployment/agent_discovery_service.py +4 -8
  148. claude_mpm/services/agents/deployment/agent_environment_manager.py +2 -7
  149. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +6 -10
  150. claude_mpm/services/agents/deployment/agent_format_converter.py +11 -15
  151. claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +2 -3
  152. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +5 -5
  153. claude_mpm/services/agents/deployment/agent_metrics_collector.py +13 -19
  154. claude_mpm/services/agents/deployment/agent_restore_handler.py +0 -1
  155. claude_mpm/services/agents/deployment/agent_template_builder.py +26 -35
  156. claude_mpm/services/agents/deployment/agent_validator.py +0 -1
  157. claude_mpm/services/agents/deployment/agent_version_manager.py +7 -9
  158. claude_mpm/services/agents/deployment/agent_versioning.py +3 -3
  159. claude_mpm/services/agents/deployment/agents_directory_resolver.py +6 -7
  160. claude_mpm/services/agents/deployment/async_agent_deployment.py +51 -38
  161. claude_mpm/services/agents/deployment/base_agent_locator.py +132 -0
  162. claude_mpm/services/agents/deployment/config/__init__.py +1 -1
  163. claude_mpm/services/agents/deployment/config/deployment_config.py +7 -8
  164. claude_mpm/services/agents/deployment/deployment_results_manager.py +185 -0
  165. claude_mpm/services/agents/deployment/deployment_type_detector.py +1 -1
  166. claude_mpm/services/agents/deployment/deployment_wrapper.py +18 -18
  167. claude_mpm/services/agents/deployment/facade/__init__.py +1 -1
  168. claude_mpm/services/agents/deployment/facade/deployment_executor.py +0 -3
  169. claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -4
  170. claude_mpm/services/agents/deployment/interface_adapter.py +5 -7
  171. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +345 -276
  172. claude_mpm/services/agents/deployment/pipeline/__init__.py +2 -2
  173. claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +1 -1
  174. claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +6 -4
  175. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +3 -3
  176. claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +2 -2
  177. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +14 -13
  178. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +0 -1
  179. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +1 -1
  180. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +8 -9
  181. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +1 -1
  182. claude_mpm/services/agents/deployment/processors/__init__.py +1 -1
  183. claude_mpm/services/agents/deployment/processors/agent_processor.py +20 -16
  184. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +5 -12
  185. claude_mpm/services/agents/deployment/results/__init__.py +1 -1
  186. claude_mpm/services/agents/deployment/results/deployment_result_builder.py +1 -1
  187. claude_mpm/services/agents/deployment/single_agent_deployer.py +315 -0
  188. claude_mpm/services/agents/deployment/strategies/__init__.py +2 -2
  189. claude_mpm/services/agents/deployment/strategies/base_strategy.py +1 -7
  190. claude_mpm/services/agents/deployment/strategies/project_strategy.py +1 -4
  191. claude_mpm/services/agents/deployment/strategies/system_strategy.py +2 -3
  192. claude_mpm/services/agents/deployment/strategies/user_strategy.py +3 -7
  193. claude_mpm/services/agents/deployment/validation/__init__.py +1 -1
  194. claude_mpm/services/agents/deployment/validation/agent_validator.py +1 -1
  195. claude_mpm/services/agents/deployment/validation/template_validator.py +2 -2
  196. claude_mpm/services/agents/deployment/validation/validation_result.py +2 -6
  197. claude_mpm/services/agents/loading/__init__.py +1 -1
  198. claude_mpm/services/agents/loading/agent_profile_loader.py +6 -12
  199. claude_mpm/services/agents/loading/base_agent_manager.py +5 -5
  200. claude_mpm/services/agents/loading/framework_agent_loader.py +2 -4
  201. claude_mpm/services/agents/management/__init__.py +1 -1
  202. claude_mpm/services/agents/management/agent_capabilities_generator.py +1 -3
  203. claude_mpm/services/agents/management/agent_management_service.py +5 -9
  204. claude_mpm/services/agents/memory/__init__.py +4 -4
  205. claude_mpm/services/agents/memory/agent_memory_manager.py +157 -503
  206. claude_mpm/services/agents/memory/agent_persistence_service.py +0 -2
  207. claude_mpm/services/agents/memory/content_manager.py +44 -38
  208. claude_mpm/services/agents/memory/memory_categorization_service.py +165 -0
  209. claude_mpm/services/agents/memory/memory_file_service.py +103 -0
  210. claude_mpm/services/agents/memory/memory_format_service.py +201 -0
  211. claude_mpm/services/agents/memory/memory_limits_service.py +99 -0
  212. claude_mpm/services/agents/memory/template_generator.py +4 -6
  213. claude_mpm/services/agents/registry/__init__.py +11 -7
  214. claude_mpm/services/agents/registry/deployed_agent_discovery.py +30 -27
  215. claude_mpm/services/agents/registry/modification_tracker.py +3 -6
  216. claude_mpm/services/async_session_logger.py +1 -2
  217. claude_mpm/services/claude_session_logger.py +1 -2
  218. claude_mpm/services/cli/__init__.py +18 -0
  219. claude_mpm/services/cli/agent_cleanup_service.py +407 -0
  220. claude_mpm/services/cli/agent_dependency_service.py +395 -0
  221. claude_mpm/services/cli/agent_listing_service.py +463 -0
  222. claude_mpm/services/cli/agent_output_formatter.py +605 -0
  223. claude_mpm/services/cli/agent_validation_service.py +589 -0
  224. claude_mpm/services/cli/dashboard_launcher.py +424 -0
  225. claude_mpm/services/cli/memory_crud_service.py +617 -0
  226. claude_mpm/services/cli/memory_output_formatter.py +604 -0
  227. claude_mpm/services/cli/session_manager.py +513 -0
  228. claude_mpm/services/cli/socketio_manager.py +498 -0
  229. claude_mpm/services/cli/startup_checker.py +370 -0
  230. claude_mpm/services/command_deployment_service.py +173 -0
  231. claude_mpm/services/command_handler_service.py +20 -22
  232. claude_mpm/services/core/__init__.py +25 -25
  233. claude_mpm/services/core/base.py +0 -5
  234. claude_mpm/services/core/cache_manager.py +311 -0
  235. claude_mpm/services/core/interfaces/__init__.py +32 -32
  236. claude_mpm/services/core/interfaces/agent.py +0 -21
  237. claude_mpm/services/core/interfaces/communication.py +0 -27
  238. claude_mpm/services/core/interfaces/infrastructure.py +0 -56
  239. claude_mpm/services/core/interfaces/service.py +0 -29
  240. claude_mpm/services/core/memory_manager.py +637 -0
  241. claude_mpm/services/core/path_resolver.py +498 -0
  242. claude_mpm/services/core/service_container.py +520 -0
  243. claude_mpm/services/core/service_interfaces.py +436 -0
  244. claude_mpm/services/diagnostics/__init__.py +1 -1
  245. claude_mpm/services/diagnostics/checks/__init__.py +6 -6
  246. claude_mpm/services/diagnostics/checks/agent_check.py +152 -97
  247. claude_mpm/services/diagnostics/checks/base_check.py +12 -16
  248. claude_mpm/services/diagnostics/checks/claude_desktop_check.py +84 -81
  249. claude_mpm/services/diagnostics/checks/common_issues_check.py +99 -91
  250. claude_mpm/services/diagnostics/checks/configuration_check.py +82 -77
  251. claude_mpm/services/diagnostics/checks/filesystem_check.py +67 -68
  252. claude_mpm/services/diagnostics/checks/installation_check.py +254 -94
  253. claude_mpm/services/diagnostics/checks/mcp_check.py +90 -88
  254. claude_mpm/services/diagnostics/checks/monitor_check.py +75 -76
  255. claude_mpm/services/diagnostics/checks/startup_log_check.py +67 -73
  256. claude_mpm/services/diagnostics/diagnostic_runner.py +67 -59
  257. claude_mpm/services/diagnostics/doctor_reporter.py +107 -70
  258. claude_mpm/services/diagnostics/models.py +21 -19
  259. claude_mpm/services/event_aggregator.py +10 -17
  260. claude_mpm/services/event_bus/__init__.py +1 -1
  261. claude_mpm/services/event_bus/config.py +54 -35
  262. claude_mpm/services/event_bus/event_bus.py +76 -71
  263. claude_mpm/services/event_bus/relay.py +74 -64
  264. claude_mpm/services/events/__init__.py +11 -11
  265. claude_mpm/services/events/consumers/__init__.py +3 -3
  266. claude_mpm/services/events/consumers/dead_letter.py +71 -63
  267. claude_mpm/services/events/consumers/logging.py +39 -37
  268. claude_mpm/services/events/consumers/metrics.py +56 -57
  269. claude_mpm/services/events/consumers/socketio.py +82 -81
  270. claude_mpm/services/events/core.py +110 -99
  271. claude_mpm/services/events/interfaces.py +56 -72
  272. claude_mpm/services/events/producers/__init__.py +1 -1
  273. claude_mpm/services/events/producers/hook.py +38 -38
  274. claude_mpm/services/events/producers/system.py +46 -44
  275. claude_mpm/services/exceptions.py +81 -80
  276. claude_mpm/services/framework_claude_md_generator/__init__.py +2 -4
  277. claude_mpm/services/framework_claude_md_generator/content_assembler.py +3 -5
  278. claude_mpm/services/framework_claude_md_generator/content_validator.py +1 -1
  279. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +4 -4
  280. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +0 -1
  281. claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +0 -2
  282. claude_mpm/services/framework_claude_md_generator/version_manager.py +4 -5
  283. claude_mpm/services/hook_service.py +6 -9
  284. claude_mpm/services/infrastructure/__init__.py +1 -1
  285. claude_mpm/services/infrastructure/context_preservation.py +8 -12
  286. claude_mpm/services/infrastructure/monitoring.py +21 -23
  287. claude_mpm/services/mcp_gateway/__init__.py +37 -37
  288. claude_mpm/services/mcp_gateway/auto_configure.py +95 -103
  289. claude_mpm/services/mcp_gateway/config/__init__.py +1 -1
  290. claude_mpm/services/mcp_gateway/config/config_loader.py +23 -25
  291. claude_mpm/services/mcp_gateway/config/config_schema.py +5 -5
  292. claude_mpm/services/mcp_gateway/config/configuration.py +9 -6
  293. claude_mpm/services/mcp_gateway/core/__init__.py +10 -10
  294. claude_mpm/services/mcp_gateway/core/base.py +0 -3
  295. claude_mpm/services/mcp_gateway/core/interfaces.py +1 -38
  296. claude_mpm/services/mcp_gateway/core/process_pool.py +99 -93
  297. claude_mpm/services/mcp_gateway/core/singleton_manager.py +65 -62
  298. claude_mpm/services/mcp_gateway/core/startup_verification.py +75 -74
  299. claude_mpm/services/mcp_gateway/main.py +2 -1
  300. claude_mpm/services/mcp_gateway/registry/service_registry.py +5 -8
  301. claude_mpm/services/mcp_gateway/registry/tool_registry.py +1 -1
  302. claude_mpm/services/mcp_gateway/server/__init__.py +1 -1
  303. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +12 -19
  304. claude_mpm/services/mcp_gateway/server/stdio_handler.py +4 -3
  305. claude_mpm/services/mcp_gateway/server/stdio_server.py +79 -71
  306. claude_mpm/services/mcp_gateway/tools/__init__.py +2 -2
  307. claude_mpm/services/mcp_gateway/tools/base_adapter.py +5 -6
  308. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +13 -22
  309. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +79 -78
  310. claude_mpm/services/mcp_gateway/tools/hello_world.py +12 -14
  311. claude_mpm/services/mcp_gateway/tools/ticket_tools.py +42 -49
  312. claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +51 -55
  313. claude_mpm/services/memory/__init__.py +3 -3
  314. claude_mpm/services/memory/builder.py +3 -6
  315. claude_mpm/services/memory/cache/__init__.py +1 -1
  316. claude_mpm/services/memory/cache/shared_prompt_cache.py +3 -5
  317. claude_mpm/services/memory/cache/simple_cache.py +1 -1
  318. claude_mpm/services/memory/indexed_memory.py +5 -7
  319. claude_mpm/services/memory/optimizer.py +7 -10
  320. claude_mpm/services/memory/router.py +8 -9
  321. claude_mpm/services/memory_hook_service.py +48 -34
  322. claude_mpm/services/monitor_build_service.py +77 -73
  323. claude_mpm/services/port_manager.py +130 -108
  324. claude_mpm/services/project/analyzer.py +12 -10
  325. claude_mpm/services/project/registry.py +11 -11
  326. claude_mpm/services/recovery_manager.py +10 -19
  327. claude_mpm/services/response_tracker.py +0 -1
  328. claude_mpm/services/runner_configuration_service.py +19 -20
  329. claude_mpm/services/session_management_service.py +7 -11
  330. claude_mpm/services/shared/__init__.py +1 -1
  331. claude_mpm/services/shared/async_service_base.py +58 -50
  332. claude_mpm/services/shared/config_service_base.py +73 -67
  333. claude_mpm/services/shared/lifecycle_service_base.py +82 -78
  334. claude_mpm/services/shared/manager_base.py +94 -82
  335. claude_mpm/services/shared/service_factory.py +96 -98
  336. claude_mpm/services/socketio/__init__.py +3 -3
  337. claude_mpm/services/socketio/client_proxy.py +5 -5
  338. claude_mpm/services/socketio/event_normalizer.py +199 -181
  339. claude_mpm/services/socketio/handlers/__init__.py +3 -3
  340. claude_mpm/services/socketio/handlers/base.py +5 -4
  341. claude_mpm/services/socketio/handlers/connection.py +163 -136
  342. claude_mpm/services/socketio/handlers/file.py +13 -14
  343. claude_mpm/services/socketio/handlers/git.py +12 -7
  344. claude_mpm/services/socketio/handlers/hook.py +49 -44
  345. claude_mpm/services/socketio/handlers/memory.py +0 -1
  346. claude_mpm/services/socketio/handlers/project.py +0 -1
  347. claude_mpm/services/socketio/handlers/registry.py +37 -19
  348. claude_mpm/services/socketio/migration_utils.py +98 -84
  349. claude_mpm/services/socketio/server/__init__.py +1 -1
  350. claude_mpm/services/socketio/server/broadcaster.py +81 -87
  351. claude_mpm/services/socketio/server/core.py +65 -54
  352. claude_mpm/services/socketio/server/eventbus_integration.py +95 -56
  353. claude_mpm/services/socketio/server/main.py +64 -38
  354. claude_mpm/services/socketio_client_manager.py +10 -12
  355. claude_mpm/services/subprocess_launcher_service.py +4 -7
  356. claude_mpm/services/system_instructions_service.py +13 -14
  357. claude_mpm/services/ticket_manager.py +2 -2
  358. claude_mpm/services/utility_service.py +5 -13
  359. claude_mpm/services/version_control/__init__.py +16 -16
  360. claude_mpm/services/version_control/branch_strategy.py +5 -8
  361. claude_mpm/services/version_control/conflict_resolution.py +9 -23
  362. claude_mpm/services/version_control/git_operations.py +5 -7
  363. claude_mpm/services/version_control/semantic_versioning.py +16 -17
  364. claude_mpm/services/version_control/version_parser.py +13 -18
  365. claude_mpm/services/version_service.py +10 -11
  366. claude_mpm/storage/__init__.py +1 -1
  367. claude_mpm/storage/state_storage.py +22 -28
  368. claude_mpm/utils/__init__.py +6 -6
  369. claude_mpm/utils/agent_dependency_loader.py +47 -33
  370. claude_mpm/utils/config_manager.py +11 -14
  371. claude_mpm/utils/dependency_cache.py +1 -1
  372. claude_mpm/utils/dependency_manager.py +13 -17
  373. claude_mpm/utils/dependency_strategies.py +8 -10
  374. claude_mpm/utils/environment_context.py +3 -9
  375. claude_mpm/utils/error_handler.py +3 -13
  376. claude_mpm/utils/file_utils.py +1 -1
  377. claude_mpm/utils/path_operations.py +8 -12
  378. claude_mpm/utils/robust_installer.py +110 -33
  379. claude_mpm/utils/subprocess_utils.py +5 -6
  380. claude_mpm/validation/agent_validator.py +3 -6
  381. claude_mpm/validation/frontmatter_validator.py +1 -1
  382. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.3.dist-info}/METADATA +1 -1
  383. claude_mpm-4.1.3.dist-info/RECORD +528 -0
  384. claude_mpm/cli/commands/run_config_checker.py +0 -160
  385. claude_mpm-4.1.1.dist-info/RECORD +0 -494
  386. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.3.dist-info}/WHEEL +0 -0
  387. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.3.dist-info}/entry_points.txt +0 -0
  388. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.3.dist-info}/licenses/LICENSE +0 -0
  389. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.3.dist-info}/top_level.txt +0 -0
@@ -1,47 +1,22 @@
1
1
  """Claude runner with both exec and subprocess launch methods."""
2
2
 
3
- import json
4
3
  import os
5
- import subprocess
6
- import sys
7
- import time
8
- import uuid
9
- from datetime import datetime
10
4
  from pathlib import Path
11
- from typing import TYPE_CHECKING, Optional
12
-
13
- from claude_mpm.config.paths import paths
5
+ from typing import Optional
14
6
 
15
7
  # Core imports that don't cause circular dependencies
16
- from claude_mpm.core.config import Config
17
- from claude_mpm.core.container import ServiceLifetime, get_container
8
+ from claude_mpm.core.container import get_container
18
9
  from claude_mpm.core.interfaces import (
19
10
  AgentDeploymentInterface,
20
- HookServiceInterface,
21
- TicketManagerInterface,
22
11
  )
23
- from claude_mpm.core.logger import ProjectLogger, get_project_logger
24
12
  from claude_mpm.core.logging_config import (
25
13
  get_logger,
26
- log_operation,
27
- log_performance_context,
28
14
  )
29
15
  from claude_mpm.services.core.interfaces import (
30
- AgentCapabilitiesInterface,
31
- CommandHandlerInterface,
32
- MemoryHookInterface,
33
16
  RunnerConfigurationInterface,
34
- SessionManagementInterface,
35
- SubprocessLauncherInterface,
36
- SystemInstructionsInterface,
37
- UtilityServiceInterface,
38
- VersionServiceInterface,
39
17
  )
40
18
 
41
19
  # Type checking imports to avoid circular dependencies
42
- if TYPE_CHECKING:
43
- from claude_mpm.services.agents.deployment import AgentDeploymentService
44
- from claude_mpm.services.hook_service import HookService
45
20
 
46
21
 
47
22
  class ClaudeRunner:
@@ -125,9 +100,7 @@ class ClaudeRunner:
125
100
  try:
126
101
  self.deployment_service = container.get(AgentDeploymentInterface)
127
102
  except Exception as e:
128
- self.logger.error(
129
- f"Failed to resolve AgentDeploymentService", exc_info=True
130
- )
103
+ self.logger.error("Failed to resolve AgentDeploymentService", exc_info=True)
131
104
  raise RuntimeError(
132
105
  f"Agent deployment service initialization failed: {e}"
133
106
  ) from e
@@ -213,7 +186,7 @@ class ClaudeRunner:
213
186
  # Deploy output style early (before Claude Code launches)
214
187
  # This ensures the "Claude MPM" output style is active on startup
215
188
  self._deploy_output_style()
216
-
189
+
217
190
  # Create session log file using configuration service
218
191
  self.session_log_file = self.configuration_service.create_session_log_file(
219
192
  self.project_logger, self.log_level, config_data
@@ -260,15 +233,14 @@ class ClaudeRunner:
260
233
  # Set Claude environment
261
234
  self.deployment_service.set_claude_environment()
262
235
  return True
263
- else:
264
- self.logger.info("All agents already up to date")
265
- if self.project_logger:
266
- self.project_logger.log_system(
267
- "All agents already up to date",
268
- level="INFO",
269
- component="deployment",
270
- )
271
- return True
236
+ self.logger.info("All agents already up to date")
237
+ if self.project_logger:
238
+ self.project_logger.log_system(
239
+ "All agents already up to date",
240
+ level="INFO",
241
+ component="deployment",
242
+ )
243
+ return True
272
244
 
273
245
  except PermissionError as e:
274
246
  error_msg = f"Permission denied deploying agents to .claude/agents/: {e}"
@@ -366,15 +338,14 @@ class ClaudeRunner:
366
338
  self.logger.info(f"Updated {updated_count} agents in project")
367
339
 
368
340
  return True
369
- elif results.get("skipped", []):
341
+ if results.get("skipped", []):
370
342
  # Agents already exist and are current
371
343
  self.logger.debug(
372
344
  f"Project agents up to date: {len(results['skipped'])} agents"
373
345
  )
374
346
  return True
375
- else:
376
- self.logger.warning("No agents deployed to project")
377
- return False
347
+ self.logger.warning("No agents deployed to project")
348
+ return False
378
349
 
379
350
  except Exception as e:
380
351
  self.logger.error(f"Failed to ensure project agents: {e}")
@@ -502,8 +473,13 @@ class ClaudeRunner:
502
473
  if needs_update:
503
474
  # Build the agent markdown using the pre-initialized service and base agent data
504
475
  # Use template_builder service instead of removed _build_agent_markdown method
505
- agent_content = project_deployment.template_builder.build_agent_markdown(
506
- agent_name, json_file, base_agent_data, source_info="project"
476
+ agent_content = (
477
+ project_deployment.template_builder.build_agent_markdown(
478
+ agent_name,
479
+ json_file,
480
+ base_agent_data,
481
+ source_info="project",
482
+ )
507
483
  )
508
484
 
509
485
  # Mark as project agent
@@ -584,15 +560,13 @@ class ClaudeRunner:
584
560
  """
585
561
  if self.session_management_service:
586
562
  return self.session_management_service.run_oneshot_session(prompt, context)
587
- else:
588
- self.logger.error("Session management service not available")
589
- print("Error: Session management service not available")
590
- return False
563
+ self.logger.error("Session management service not available")
564
+ print("Error: Session management service not available")
565
+ return False
591
566
 
592
567
  def _extract_tickets(self, text: str):
593
568
  """Extract tickets from Claude's response (disabled - use claude-mpm tickets CLI)."""
594
569
  # Ticket extraction disabled - users should use claude-mpm tickets CLI commands
595
- pass
596
570
 
597
571
  def _load_system_instructions(self) -> Optional[str]:
598
572
  """Load and process system instructions.
@@ -601,12 +575,11 @@ class ClaudeRunner:
601
575
  """
602
576
  if self.system_instructions_service:
603
577
  return self.system_instructions_service.load_system_instructions()
604
- else:
605
- # Fallback if service is not available
606
- self.logger.warning(
607
- "System instructions service not available, using basic fallback"
608
- )
609
- return None
578
+ # Fallback if service is not available
579
+ self.logger.warning(
580
+ "System instructions service not available, using basic fallback"
581
+ )
582
+ return None
610
583
 
611
584
  def _process_base_pm_content(self, base_pm_content: str) -> str:
612
585
  """Process BASE_PM.md content with dynamic injections.
@@ -617,12 +590,11 @@ class ClaudeRunner:
617
590
  return self.system_instructions_service.process_base_pm_content(
618
591
  base_pm_content
619
592
  )
620
- else:
621
- # Fallback if service is not available
622
- self.logger.warning(
623
- "System instructions service not available for BASE_PM processing"
624
- )
625
- return base_pm_content
593
+ # Fallback if service is not available
594
+ self.logger.warning(
595
+ "System instructions service not available for BASE_PM processing"
596
+ )
597
+ return base_pm_content
626
598
 
627
599
  def _strip_metadata_comments(self, content: str) -> str:
628
600
  """Strip HTML metadata comments from content.
@@ -631,12 +603,11 @@ class ClaudeRunner:
631
603
  """
632
604
  if self.system_instructions_service:
633
605
  return self.system_instructions_service.strip_metadata_comments(content)
634
- else:
635
- # Fallback if service is not available
636
- self.logger.warning(
637
- "System instructions service not available for metadata stripping"
638
- )
639
- return content
606
+ # Fallback if service is not available
607
+ self.logger.warning(
608
+ "System instructions service not available for metadata stripping"
609
+ )
610
+ return content
640
611
 
641
612
  def _generate_deployed_agent_capabilities(self) -> str:
642
613
  """Generate agent capabilities from deployed agents.
@@ -647,20 +618,16 @@ class ClaudeRunner:
647
618
  return (
648
619
  self.agent_capabilities_service.generate_deployed_agent_capabilities()
649
620
  )
650
- else:
651
- # Fallback if service is not available
652
- self.logger.warning(
653
- "Agent capabilities service not available, using fallback"
654
- )
655
- return self._get_fallback_capabilities()
621
+ # Fallback if service is not available
622
+ self.logger.warning("Agent capabilities service not available, using fallback")
623
+ return self._get_fallback_capabilities()
656
624
 
657
625
  def _get_fallback_capabilities(self) -> str:
658
626
  """Return fallback agent capabilities when deployed agents can't be read."""
659
627
  # Delegate to the service if available, otherwise use basic fallback
660
628
  if self.agent_capabilities_service:
661
629
  return self.agent_capabilities_service._get_fallback_capabilities()
662
- else:
663
- return """
630
+ return """
664
631
  ## Available Agent Capabilities
665
632
 
666
633
  You have the following specialized agents available for delegation:
@@ -682,28 +649,24 @@ Use these agents to delegate specialized work via the Task tool.
682
649
  return self.system_instructions_service.create_system_prompt(
683
650
  self.system_instructions
684
651
  )
685
- else:
686
- # Fallback if service is not available
687
- if self.system_instructions:
688
- return self.system_instructions
689
- else:
690
- return create_simple_context()
652
+ # Fallback if service is not available
653
+ if self.system_instructions:
654
+ return self.system_instructions
655
+ return create_simple_context()
691
656
 
692
657
  def _contains_delegation(self, text: str) -> bool:
693
658
  """Check if text contains signs of agent delegation using the utility service."""
694
659
  if self.utility_service:
695
660
  return self.utility_service.contains_delegation(text)
696
- else:
697
- # Fallback if service not available
698
- return False
661
+ # Fallback if service not available
662
+ return False
699
663
 
700
664
  def _extract_agent_from_response(self, text: str) -> Optional[str]:
701
665
  """Try to extract agent name from delegation response using the utility service."""
702
666
  if self.utility_service:
703
667
  return self.utility_service.extract_agent_from_response(text)
704
- else:
705
- # Fallback if service not available
706
- return None
668
+ # Fallback if service not available
669
+ return None
707
670
 
708
671
  def _handle_mpm_command(self, prompt: str) -> bool:
709
672
  """Handle /mpm: commands using the command handler service.
@@ -712,10 +675,9 @@ Use these agents to delegate specialized work via the Task tool.
712
675
  """
713
676
  if self.command_handler_service:
714
677
  return self.command_handler_service.handle_mpm_command(prompt)
715
- else:
716
- # Fallback if service not available
717
- print("Command handler service not available")
718
- return False
678
+ # Fallback if service not available
679
+ print("Command handler service not available")
680
+ return False
719
681
 
720
682
  def _log_session_event(self, event_data: dict):
721
683
  """Log an event to the session log file using the utility service."""
@@ -732,23 +694,22 @@ Use these agents to delegate specialized work via the Task tool.
732
694
  """
733
695
  if self.version_service:
734
696
  return self.version_service.get_version()
735
- else:
736
- # Fallback if service not available
737
- return "v0.0.0"
697
+ # Fallback if service not available
698
+ return "v0.0.0"
738
699
 
739
700
  def _deploy_output_style(self) -> None:
740
701
  """Deploy the Claude MPM output style before Claude Code launches.
741
-
702
+
742
703
  This method ensures the output style is set to "Claude MPM" on startup
743
704
  by deploying the style file and updating Claude Code settings.
744
705
  Only works for Claude Code >= 1.0.83.
745
706
  """
746
707
  try:
747
708
  from claude_mpm.core.output_style_manager import OutputStyleManager
748
-
709
+
749
710
  # Create OutputStyleManager instance
750
711
  output_style_manager = OutputStyleManager()
751
-
712
+
752
713
  # Check if Claude Code supports output styles
753
714
  if not output_style_manager.supports_output_styles():
754
715
  self.logger.debug(
@@ -756,48 +717,59 @@ Use these agents to delegate specialized work via the Task tool.
756
717
  "does not support output styles (requires >= 1.0.83)"
757
718
  )
758
719
  return
759
-
720
+
760
721
  # Check if output style is already deployed and active
761
722
  settings_file = Path.home() / ".claude" / "settings.json"
762
723
  if settings_file.exists():
763
724
  try:
764
725
  import json
726
+
765
727
  settings = json.loads(settings_file.read_text())
766
728
  if settings.get("activeOutputStyle") == "claude-mpm":
767
729
  # Already active, check if file exists
768
- output_style_file = Path.home() / ".claude" / "output-styles" / "claude-mpm.md"
730
+ output_style_file = (
731
+ Path.home() / ".claude" / "output-styles" / "claude-mpm.md"
732
+ )
769
733
  if output_style_file.exists():
770
- self.logger.debug("Output style 'Claude MPM' already deployed and active")
734
+ self.logger.debug(
735
+ "Output style 'Claude MPM' already deployed and active"
736
+ )
771
737
  return
772
738
  except Exception:
773
739
  pass # Continue with deployment if we can't read settings
774
-
740
+
775
741
  # Read the OUTPUT_STYLE.md content if it exists
776
- output_style_path = Path(__file__).parent.parent / "agents" / "OUTPUT_STYLE.md"
777
-
742
+ output_style_path = (
743
+ Path(__file__).parent.parent / "agents" / "OUTPUT_STYLE.md"
744
+ )
745
+
778
746
  if output_style_path.exists():
779
747
  # Use existing OUTPUT_STYLE.md content
780
748
  output_style_content = output_style_path.read_text()
781
749
  self.logger.debug("Using existing OUTPUT_STYLE.md content")
782
750
  else:
783
751
  # Extract output style content from framework instructions
784
- output_style_content = output_style_manager.extract_output_style_content()
752
+ output_style_content = (
753
+ output_style_manager.extract_output_style_content()
754
+ )
785
755
  self.logger.debug("Extracted output style from framework instructions")
786
-
756
+
787
757
  # Deploy the output style
788
758
  deployed = output_style_manager.deploy_output_style(output_style_content)
789
-
759
+
790
760
  if deployed:
791
- self.logger.info("✅ Output style 'Claude MPM' deployed and activated on startup")
761
+ self.logger.info(
762
+ "✅ Output style 'Claude MPM' deployed and activated on startup"
763
+ )
792
764
  if self.project_logger:
793
765
  self.project_logger.log_system(
794
766
  "Output style 'Claude MPM' deployed and activated on startup",
795
767
  level="INFO",
796
- component="output_style"
768
+ component="output_style",
797
769
  )
798
770
  else:
799
771
  self.logger.warning("Failed to deploy output style")
800
-
772
+
801
773
  except ImportError as e:
802
774
  self.logger.warning(f"Could not import OutputStyleManager: {e}")
803
775
  except Exception as e:
@@ -806,8 +778,8 @@ Use these agents to delegate specialized work via the Task tool.
806
778
  if self.project_logger:
807
779
  self.project_logger.log_system(
808
780
  f"Output style deployment error: {e}",
809
- level="WARNING",
810
- component="output_style"
781
+ level="WARNING",
782
+ component="output_style",
811
783
  )
812
784
 
813
785
  def _launch_subprocess_interactive(self, cmd: list, env: dict):
claude_mpm/core/config.py CHANGED
@@ -37,12 +37,14 @@ class Config:
37
37
 
38
38
  _instance = None
39
39
  _initialized = False
40
- _success_logged = False # Class-level flag to track if success message was already logged
40
+ _success_logged = (
41
+ False # Class-level flag to track if success message was already logged
42
+ )
41
43
  _lock = threading.Lock() # Thread safety for singleton initialization
42
44
 
43
45
  def __new__(cls, *args, **kwargs):
44
46
  """Implement singleton pattern to ensure single configuration instance.
45
-
47
+
46
48
  WHY: Configuration was being loaded 11 times during startup, once for each service.
47
49
  This singleton pattern ensures configuration is loaded only once and reused.
48
50
  Thread-safe implementation prevents race conditions during concurrent initialization.
@@ -54,7 +56,9 @@ class Config:
54
56
  cls._instance = super().__new__(cls)
55
57
  logger.info("Creating new Config singleton instance")
56
58
  else:
57
- logger.debug("Reusing existing Config singleton instance (concurrent init)")
59
+ logger.debug(
60
+ "Reusing existing Config singleton instance (concurrent init)"
61
+ )
58
62
  else:
59
63
  logger.debug("Reusing existing Config singleton instance")
60
64
  return cls._instance
@@ -79,23 +83,25 @@ class Config:
79
83
  logger.debug("Config already initialized, skipping re-initialization")
80
84
  # If someone tries to load a different config file after initialization,
81
85
  # log a debug message but don't reload
82
- if config_file and str(config_file) != getattr(self, '_loaded_from', None):
86
+ if config_file and str(config_file) != getattr(self, "_loaded_from", None):
83
87
  logger.debug(
84
88
  f"Ignoring config_file parameter '{config_file}' - "
85
89
  f"configuration already loaded from '{getattr(self, '_loaded_from', 'defaults')}'"
86
90
  )
87
91
  return
88
-
92
+
89
93
  # Thread-safe initialization - acquire lock for ENTIRE initialization process
90
94
  with Config._lock:
91
95
  # Double-check pattern - check again inside the lock
92
96
  if Config._initialized:
93
- logger.debug("Config already initialized (concurrent), skipping re-initialization")
97
+ logger.debug(
98
+ "Config already initialized (concurrent), skipping re-initialization"
99
+ )
94
100
  return
95
-
101
+
96
102
  Config._initialized = True
97
103
  logger.info("Initializing Config singleton for the first time")
98
-
104
+
99
105
  # Initialize instance variables inside the lock to ensure thread safety
100
106
  self._config: Dict[str, Any] = {}
101
107
  self._env_prefix = env_prefix
@@ -121,7 +127,9 @@ class Config:
121
127
  if default_config.exists():
122
128
  self.load_file(default_config, is_initial_load=True)
123
129
  self._loaded_from = str(default_config)
124
- elif (alt_config := Path.cwd() / ".claude-mpm" / "configuration.yml").exists():
130
+ elif (
131
+ alt_config := Path.cwd() / ".claude-mpm" / "configuration.yml"
132
+ ).exists():
125
133
  # Also try .yml extension (using walrus operator for cleaner code)
126
134
  self.load_file(alt_config, is_initial_load=True)
127
135
  self._loaded_from = str(alt_config)
@@ -133,21 +141,27 @@ class Config:
133
141
  # Apply defaults
134
142
  self._apply_defaults()
135
143
 
136
- def load_file(self, file_path: Union[str, Path], is_initial_load: bool = True) -> None:
144
+ def load_file(
145
+ self, file_path: Union[str, Path], is_initial_load: bool = True
146
+ ) -> None:
137
147
  """Load configuration from file with enhanced error handling.
138
148
 
139
149
  WHY: Configuration loading failures can cause silent issues. We need
140
150
  to provide clear, actionable error messages to help users fix problems.
141
-
151
+
142
152
  Args:
143
153
  file_path: Path to the configuration file
144
154
  is_initial_load: Whether this is the initial configuration load (for logging control)
145
155
  """
146
156
  file_path = Path(file_path)
147
-
157
+
148
158
  # Check if we've already loaded from this exact file to prevent duplicate messages
149
- if hasattr(self, '_actual_loaded_file') and self._actual_loaded_file == str(file_path):
150
- logger.debug(f"Configuration already loaded from {file_path}, skipping reload")
159
+ if hasattr(self, "_actual_loaded_file") and self._actual_loaded_file == str(
160
+ file_path
161
+ ):
162
+ logger.debug(
163
+ f"Configuration already loaded from {file_path}, skipping reload"
164
+ )
151
165
  return
152
166
 
153
167
  if not file_path.exists():
@@ -177,7 +191,7 @@ class Config:
177
191
  self._config = self._config_mgr.merge_configs(self._config, file_config)
178
192
  # Track that we've successfully loaded from this file
179
193
  self._actual_loaded_file = str(file_path)
180
-
194
+
181
195
  # Only log success message once using class-level flag to avoid duplicate messages
182
196
  # Check if we should log success message (thread-safe for reads after initialization)
183
197
  if is_initial_load:
@@ -185,10 +199,14 @@ class Config:
185
199
  # Set flag IMMEDIATELY before logging to prevent any possibility of duplicate
186
200
  # messages. No lock needed here since we're already inside __init__ lock
187
201
  Config._success_logged = True
188
- logger.info(f"✓ Successfully loaded configuration from {file_path}")
202
+ logger.info(
203
+ f"✓ Successfully loaded configuration from {file_path}"
204
+ )
189
205
  else:
190
206
  # Configuration already successfully loaded before, just debug log
191
- logger.debug(f"Configuration already loaded, skipping success message for {file_path}")
207
+ logger.debug(
208
+ f"Configuration already loaded, skipping success message for {file_path}"
209
+ )
192
210
  else:
193
211
  # Not initial load (shouldn't happen in normal flow, but handle gracefully)
194
212
  logger.debug(f"Configuration reloaded from {file_path}")
@@ -225,7 +243,7 @@ class Config:
225
243
  logger.info("TIP: Validate your JSON at https://jsonlint.com/")
226
244
  self._config["_load_error"] = str(e)
227
245
 
228
- except (OSError, IOError, PermissionError) as e:
246
+ except (OSError, PermissionError) as e:
229
247
  raise FileOperationError(
230
248
  f"Failed to read configuration file: {e}",
231
249
  context={
@@ -285,15 +303,14 @@ class Config:
285
303
  # Boolean conversion
286
304
  if value.lower() in ("true", "yes", "1", "on"):
287
305
  return True
288
- elif value.lower() in ("false", "no", "0", "off"):
306
+ if value.lower() in ("false", "no", "0", "off"):
289
307
  return False
290
308
 
291
309
  # Numeric conversion
292
310
  try:
293
311
  if "." in value:
294
312
  return float(value)
295
- else:
296
- return int(value)
313
+ return int(value)
297
314
  except ValueError:
298
315
  pass
299
316
 
@@ -580,7 +597,7 @@ class Config:
580
597
 
581
598
  logger.info(f"Configuration saved to {file_path}")
582
599
 
583
- except (OSError, IOError, PermissionError) as e:
600
+ except (OSError, PermissionError) as e:
584
601
  raise FileOperationError(
585
602
  f"Failed to write configuration file: {e}",
586
603
  context={
@@ -809,7 +826,7 @@ class Config:
809
826
  if "enabled" in memory_config and not isinstance(
810
827
  memory_config["enabled"], bool
811
828
  ):
812
- errors.append(f"memory.enabled must be boolean")
829
+ errors.append("memory.enabled must be boolean")
813
830
 
814
831
  # Check limits
815
832
  limits = memory_config.get("limits", {})
@@ -850,7 +867,7 @@ class Config:
850
867
  """
851
868
  is_valid, errors, warnings = self.validate_configuration()
852
869
 
853
- status = {
870
+ return {
854
871
  "valid": is_valid,
855
872
  "errors": errors,
856
873
  "warnings": warnings,
@@ -862,16 +879,14 @@ class Config:
862
879
  "memory_enabled": self.get("memory.enabled", False),
863
880
  }
864
881
 
865
- return status
866
-
867
882
  def __repr__(self) -> str:
868
883
  """String representation of configuration."""
869
884
  return f"<Config({len(self._config)} keys)>"
870
-
885
+
871
886
  @classmethod
872
887
  def reset_singleton(cls):
873
888
  """Reset the singleton instance (mainly for testing purposes).
874
-
889
+
875
890
  WHY: During testing, we may need to reset the singleton to test different
876
891
  configurations. This method allows controlled reset of the singleton state.
877
892
  """
@@ -15,7 +15,6 @@ Aliases are stored in ~/.claude-mpm/config_aliases.json
15
15
 
16
16
  import json
17
17
  import logging
18
- import os
19
18
  from typing import Dict, List, Optional, Tuple
20
19
 
21
20
  from ..utils.config_manager import ConfigurationManager
@@ -27,26 +26,18 @@ logger = logging.getLogger(__name__)
27
26
  class ConfigAliasError(Exception):
28
27
  """Base exception for configuration alias errors."""
29
28
 
30
- pass
31
-
32
29
 
33
30
  class AliasNotFoundError(ConfigAliasError):
34
31
  """Raised when attempting to resolve a non-existent alias."""
35
32
 
36
- pass
37
-
38
33
 
39
34
  class DuplicateAliasError(ConfigAliasError):
40
35
  """Raised when attempting to create an alias that already exists."""
41
36
 
42
- pass
43
-
44
37
 
45
38
  class InvalidDirectoryError(ConfigAliasError):
46
39
  """Raised when a directory path is invalid or cannot be created."""
47
40
 
48
- pass
49
-
50
41
 
51
42
  class ConfigAliasManager:
52
43
  """