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
@@ -18,9 +18,7 @@ DESIGN DECISIONS:
18
18
 
19
19
  import asyncio
20
20
  import json
21
- import subprocess
22
21
  from datetime import datetime
23
- from typing import Any, Dict, List, Optional
24
22
 
25
23
  from claude_mpm.services.mcp_gateway.core.interfaces import (
26
24
  MCPToolDefinition,
@@ -106,7 +104,7 @@ class TicketCreateTool(BaseToolAdapter):
106
104
  if "priority" in params:
107
105
  cmd.extend(["--priority", params["priority"]])
108
106
 
109
- if "tags" in params and params["tags"]:
107
+ if params.get("tags"):
110
108
  # aitrackdown uses --tag for tags (singular)
111
109
  for tag in params["tags"]:
112
110
  cmd.extend(["--tag", tag])
@@ -152,15 +150,14 @@ class TicketCreateTool(BaseToolAdapter):
152
150
  execution_time=execution_time,
153
151
  metadata={"tool": "ticket_create", "operation": "create"},
154
152
  )
155
- else:
156
- error_msg = stderr.decode() if stderr else stdout.decode()
157
- self._update_metrics(False, execution_time)
153
+ error_msg = stderr.decode() if stderr else stdout.decode()
154
+ self._update_metrics(False, execution_time)
158
155
 
159
- return MCPToolResult(
160
- success=False,
161
- error=f"Failed to create ticket: {error_msg}",
162
- execution_time=execution_time,
163
- )
156
+ return MCPToolResult(
157
+ success=False,
158
+ error=f"Failed to create ticket: {error_msg}",
159
+ execution_time=execution_time,
160
+ )
164
161
 
165
162
  except Exception as e:
166
163
  execution_time = (datetime.now() - start_time).total_seconds()
@@ -168,7 +165,7 @@ class TicketCreateTool(BaseToolAdapter):
168
165
 
169
166
  return MCPToolResult(
170
167
  success=False,
171
- error=f"Ticket creation failed: {str(e)}",
168
+ error=f"Ticket creation failed: {e!s}",
172
169
  execution_time=execution_time,
173
170
  )
174
171
 
@@ -278,15 +275,14 @@ class TicketListTool(BaseToolAdapter):
278
275
  "count": len(tickets) if isinstance(tickets, list) else 1,
279
276
  },
280
277
  )
281
- else:
282
- error_msg = stderr.decode() if stderr else stdout.decode()
283
- self._update_metrics(False, execution_time)
278
+ error_msg = stderr.decode() if stderr else stdout.decode()
279
+ self._update_metrics(False, execution_time)
284
280
 
285
- return MCPToolResult(
286
- success=False,
287
- error=f"Failed to list tickets: {error_msg}",
288
- execution_time=execution_time,
289
- )
281
+ return MCPToolResult(
282
+ success=False,
283
+ error=f"Failed to list tickets: {error_msg}",
284
+ execution_time=execution_time,
285
+ )
290
286
 
291
287
  except Exception as e:
292
288
  execution_time = (datetime.now() - start_time).total_seconds()
@@ -294,7 +290,7 @@ class TicketListTool(BaseToolAdapter):
294
290
 
295
291
  return MCPToolResult(
296
292
  success=False,
297
- error=f"Ticket listing failed: {str(e)}",
293
+ error=f"Ticket listing failed: {e!s}",
298
294
  execution_time=execution_time,
299
295
  )
300
296
 
@@ -408,15 +404,14 @@ class TicketUpdateTool(BaseToolAdapter):
408
404
  execution_time=execution_time,
409
405
  metadata={"tool": "ticket_update", "operation": "update"},
410
406
  )
411
- else:
412
- error_msg = stderr.decode() if stderr else stdout.decode()
413
- self._update_metrics(False, execution_time)
407
+ error_msg = stderr.decode() if stderr else stdout.decode()
408
+ self._update_metrics(False, execution_time)
414
409
 
415
- return MCPToolResult(
416
- success=False,
417
- error=f"Failed to update ticket: {error_msg}",
418
- execution_time=execution_time,
419
- )
410
+ return MCPToolResult(
411
+ success=False,
412
+ error=f"Failed to update ticket: {error_msg}",
413
+ execution_time=execution_time,
414
+ )
420
415
 
421
416
  except Exception as e:
422
417
  execution_time = (datetime.now() - start_time).total_seconds()
@@ -424,7 +419,7 @@ class TicketUpdateTool(BaseToolAdapter):
424
419
 
425
420
  return MCPToolResult(
426
421
  success=False,
427
- error=f"Ticket update failed: {str(e)}",
422
+ error=f"Ticket update failed: {e!s}",
428
423
  execution_time=execution_time,
429
424
  )
430
425
 
@@ -513,15 +508,14 @@ class TicketViewTool(BaseToolAdapter):
513
508
  "ticket_id": ticket_id,
514
509
  },
515
510
  )
516
- else:
517
- error_msg = stderr.decode() if stderr else stdout.decode()
518
- self._update_metrics(False, execution_time)
511
+ error_msg = stderr.decode() if stderr else stdout.decode()
512
+ self._update_metrics(False, execution_time)
519
513
 
520
- return MCPToolResult(
521
- success=False,
522
- error=f"Failed to view ticket: {error_msg}",
523
- execution_time=execution_time,
524
- )
514
+ return MCPToolResult(
515
+ success=False,
516
+ error=f"Failed to view ticket: {error_msg}",
517
+ execution_time=execution_time,
518
+ )
525
519
 
526
520
  except Exception as e:
527
521
  execution_time = (datetime.now() - start_time).total_seconds()
@@ -529,7 +523,7 @@ class TicketViewTool(BaseToolAdapter):
529
523
 
530
524
  return MCPToolResult(
531
525
  success=False,
532
- error=f"Ticket view failed: {str(e)}",
526
+ error=f"Ticket view failed: {e!s}",
533
527
  execution_time=execution_time,
534
528
  )
535
529
 
@@ -621,15 +615,14 @@ class TicketSearchTool(BaseToolAdapter):
621
615
  "query": query,
622
616
  },
623
617
  )
624
- else:
625
- error_msg = stderr.decode() if stderr else stdout.decode()
626
- self._update_metrics(False, execution_time)
618
+ error_msg = stderr.decode() if stderr else stdout.decode()
619
+ self._update_metrics(False, execution_time)
627
620
 
628
- return MCPToolResult(
629
- success=False,
630
- error=f"Failed to search tickets: {error_msg}",
631
- execution_time=execution_time,
632
- )
621
+ return MCPToolResult(
622
+ success=False,
623
+ error=f"Failed to search tickets: {error_msg}",
624
+ execution_time=execution_time,
625
+ )
633
626
 
634
627
  except Exception as e:
635
628
  execution_time = (datetime.now() - start_time).total_seconds()
@@ -637,7 +630,7 @@ class TicketSearchTool(BaseToolAdapter):
637
630
 
638
631
  return MCPToolResult(
639
632
  success=False,
640
- error=f"Ticket search failed: {str(e)}",
633
+ error=f"Ticket search failed: {e!s}",
641
634
  execution_time=execution_time,
642
635
  )
643
636
 
@@ -646,7 +639,7 @@ class TicketSearchTool(BaseToolAdapter):
646
639
  __all__ = [
647
640
  "TicketCreateTool",
648
641
  "TicketListTool",
642
+ "TicketSearchTool",
649
643
  "TicketUpdateTool",
650
644
  "TicketViewTool",
651
- "TicketSearchTool",
652
645
  ]
@@ -21,9 +21,8 @@ DESIGN DECISIONS:
21
21
  import asyncio
22
22
  import json
23
23
  import re
24
- import subprocess
25
24
  from datetime import datetime
26
- from typing import Any, Dict, List, Optional
25
+ from typing import Any, Dict, Optional
27
26
 
28
27
  from claude_mpm.services.mcp_gateway.core.interfaces import (
29
28
  MCPToolDefinition,
@@ -191,7 +190,9 @@ class UnifiedTicketTool(BaseToolAdapter):
191
190
 
192
191
  return await handler(invocation.parameters)
193
192
 
194
- def _validate_parameters(self, operation: str, params: Dict[str, Any]) -> Optional[str]:
193
+ def _validate_parameters(
194
+ self, operation: str, params: Dict[str, Any]
195
+ ) -> Optional[str]:
195
196
  """
196
197
  Validate parameters based on the operation type.
197
198
 
@@ -209,26 +210,26 @@ class UnifiedTicketTool(BaseToolAdapter):
209
210
  return "'title' parameter is required for create operation"
210
211
  if params["type"] not in ["task", "issue", "epic"]:
211
212
  return f"Invalid type '{params['type']}'. Must be 'task', 'issue', or 'epic'"
212
-
213
+
213
214
  elif operation == "update":
214
215
  if "ticket_id" not in params:
215
216
  return "'ticket_id' parameter is required for update operation"
216
-
217
+
217
218
  elif operation == "view":
218
219
  if "ticket_id" not in params:
219
220
  return "'ticket_id' parameter is required for view operation"
220
-
221
+
221
222
  elif operation == "search":
222
223
  if "query" not in params:
223
224
  return "'query' parameter is required for search operation"
224
-
225
+
225
226
  elif operation == "list":
226
227
  # List operation has no required parameters beyond operation itself
227
228
  pass
228
-
229
+
229
230
  else:
230
231
  return f"Unknown operation: {operation}"
231
-
232
+
232
233
  return None
233
234
 
234
235
  async def _handle_create(self, params: Dict[str, Any]) -> MCPToolResult:
@@ -254,7 +255,7 @@ class UnifiedTicketTool(BaseToolAdapter):
254
255
  if "priority" in params:
255
256
  cmd.extend(["--priority", params["priority"]])
256
257
 
257
- if "tags" in params and params["tags"]:
258
+ if params.get("tags"):
258
259
  for tag in params["tags"]:
259
260
  cmd.extend(["--tag", tag])
260
261
 
@@ -294,15 +295,14 @@ class UnifiedTicketTool(BaseToolAdapter):
294
295
  execution_time=execution_time,
295
296
  metadata={"tool": "ticket", "operation": "create"},
296
297
  )
297
- else:
298
- error_msg = stderr.decode() if stderr else stdout.decode()
299
- self._update_metrics(False, execution_time)
298
+ error_msg = stderr.decode() if stderr else stdout.decode()
299
+ self._update_metrics(False, execution_time)
300
300
 
301
- return MCPToolResult(
302
- success=False,
303
- error=f"Failed to create ticket: {error_msg}",
304
- execution_time=execution_time,
305
- )
301
+ return MCPToolResult(
302
+ success=False,
303
+ error=f"Failed to create ticket: {error_msg}",
304
+ execution_time=execution_time,
305
+ )
306
306
 
307
307
  except Exception as e:
308
308
  execution_time = (datetime.now() - start_time).total_seconds()
@@ -310,7 +310,7 @@ class UnifiedTicketTool(BaseToolAdapter):
310
310
 
311
311
  return MCPToolResult(
312
312
  success=False,
313
- error=f"Ticket creation failed: {str(e)}",
313
+ error=f"Ticket creation failed: {e!s}",
314
314
  execution_time=execution_time,
315
315
  )
316
316
 
@@ -365,15 +365,14 @@ class UnifiedTicketTool(BaseToolAdapter):
365
365
  "count": len(tickets) if isinstance(tickets, list) else 1,
366
366
  },
367
367
  )
368
- else:
369
- error_msg = stderr.decode() if stderr else stdout.decode()
370
- self._update_metrics(False, execution_time)
368
+ error_msg = stderr.decode() if stderr else stdout.decode()
369
+ self._update_metrics(False, execution_time)
371
370
 
372
- return MCPToolResult(
373
- success=False,
374
- error=f"Failed to list tickets: {error_msg}",
375
- execution_time=execution_time,
376
- )
371
+ return MCPToolResult(
372
+ success=False,
373
+ error=f"Failed to list tickets: {error_msg}",
374
+ execution_time=execution_time,
375
+ )
377
376
 
378
377
  except Exception as e:
379
378
  execution_time = (datetime.now() - start_time).total_seconds()
@@ -381,7 +380,7 @@ class UnifiedTicketTool(BaseToolAdapter):
381
380
 
382
381
  return MCPToolResult(
383
382
  success=False,
384
- error=f"Ticket listing failed: {str(e)}",
383
+ error=f"Ticket listing failed: {e!s}",
385
384
  execution_time=execution_time,
386
385
  )
387
386
 
@@ -444,15 +443,14 @@ class UnifiedTicketTool(BaseToolAdapter):
444
443
  execution_time=execution_time,
445
444
  metadata={"tool": "ticket", "operation": "update"},
446
445
  )
447
- else:
448
- error_msg = stderr.decode() if stderr else stdout.decode()
449
- self._update_metrics(False, execution_time)
446
+ error_msg = stderr.decode() if stderr else stdout.decode()
447
+ self._update_metrics(False, execution_time)
450
448
 
451
- return MCPToolResult(
452
- success=False,
453
- error=f"Failed to update ticket: {error_msg}",
454
- execution_time=execution_time,
455
- )
449
+ return MCPToolResult(
450
+ success=False,
451
+ error=f"Failed to update ticket: {error_msg}",
452
+ execution_time=execution_time,
453
+ )
456
454
 
457
455
  except Exception as e:
458
456
  execution_time = (datetime.now() - start_time).total_seconds()
@@ -460,7 +458,7 @@ class UnifiedTicketTool(BaseToolAdapter):
460
458
 
461
459
  return MCPToolResult(
462
460
  success=False,
463
- error=f"Ticket update failed: {str(e)}",
461
+ error=f"Ticket update failed: {e!s}",
464
462
  execution_time=execution_time,
465
463
  )
466
464
 
@@ -514,15 +512,14 @@ class UnifiedTicketTool(BaseToolAdapter):
514
512
  "ticket_id": ticket_id,
515
513
  },
516
514
  )
517
- else:
518
- error_msg = stderr.decode() if stderr else stdout.decode()
519
- self._update_metrics(False, execution_time)
515
+ error_msg = stderr.decode() if stderr else stdout.decode()
516
+ self._update_metrics(False, execution_time)
520
517
 
521
- return MCPToolResult(
522
- success=False,
523
- error=f"Failed to view ticket: {error_msg}",
524
- execution_time=execution_time,
525
- )
518
+ return MCPToolResult(
519
+ success=False,
520
+ error=f"Failed to view ticket: {error_msg}",
521
+ execution_time=execution_time,
522
+ )
526
523
 
527
524
  except Exception as e:
528
525
  execution_time = (datetime.now() - start_time).total_seconds()
@@ -530,7 +527,7 @@ class UnifiedTicketTool(BaseToolAdapter):
530
527
 
531
528
  return MCPToolResult(
532
529
  success=False,
533
- error=f"Ticket view failed: {str(e)}",
530
+ error=f"Ticket view failed: {e!s}",
534
531
  execution_time=execution_time,
535
532
  )
536
533
 
@@ -581,15 +578,14 @@ class UnifiedTicketTool(BaseToolAdapter):
581
578
  execution_time=execution_time,
582
579
  metadata={"tool": "ticket", "operation": "search", "query": query},
583
580
  )
584
- else:
585
- error_msg = stderr.decode() if stderr else stdout.decode()
586
- self._update_metrics(False, execution_time)
581
+ error_msg = stderr.decode() if stderr else stdout.decode()
582
+ self._update_metrics(False, execution_time)
587
583
 
588
- return MCPToolResult(
589
- success=False,
590
- error=f"Failed to search tickets: {error_msg}",
591
- execution_time=execution_time,
592
- )
584
+ return MCPToolResult(
585
+ success=False,
586
+ error=f"Failed to search tickets: {error_msg}",
587
+ execution_time=execution_time,
588
+ )
593
589
 
594
590
  except Exception as e:
595
591
  execution_time = (datetime.now() - start_time).total_seconds()
@@ -597,7 +593,7 @@ class UnifiedTicketTool(BaseToolAdapter):
597
593
 
598
594
  return MCPToolResult(
599
595
  success=False,
600
- error=f"Ticket search failed: {str(e)}",
596
+ error=f"Ticket search failed: {e!s}",
601
597
  execution_time=execution_time,
602
598
  )
603
599
 
@@ -7,13 +7,13 @@ This module provides memory management services including:
7
7
  """
8
8
 
9
9
  from .builder import MemoryBuilder
10
+ from .indexed_memory import IndexedMemoryService
10
11
  from .optimizer import MemoryOptimizer
11
12
  from .router import MemoryRouter
12
- from .indexed_memory import IndexedMemoryService
13
13
 
14
14
  __all__ = [
15
+ "IndexedMemoryService",
15
16
  "MemoryBuilder",
16
- "MemoryRouter",
17
17
  "MemoryOptimizer",
18
- "IndexedMemoryService",
18
+ "MemoryRouter",
19
19
  ]
@@ -26,7 +26,7 @@ import os
26
26
  import re
27
27
  from datetime import datetime
28
28
  from pathlib import Path
29
- from typing import Any, Dict, List, Optional, Tuple
29
+ from typing import Any, Dict, List, Optional
30
30
 
31
31
  from claude_mpm.core.config import Config
32
32
  from claude_mpm.core.mixins import LoggerMixin
@@ -410,7 +410,7 @@ class MemoryBuilder(LoggerMixin):
410
410
 
411
411
  except Exception as e:
412
412
  result["items_skipped"] += 1
413
- result["errors"].append(f"Error processing item: {str(e)}")
413
+ result["errors"].append(f"Error processing item: {e!s}")
414
414
 
415
415
  # Convert set to list
416
416
  result["sections_updated"] = list(result["sections_updated"])
@@ -878,10 +878,7 @@ class MemoryBuilder(LoggerMixin):
878
878
  "as mentioned",
879
879
  "for more info",
880
880
  ]
881
- if any(phrase in content.lower() for phrase in generic_phrases):
882
- return False
883
-
884
- return True
881
+ return not any(phrase in content.lower() for phrase in generic_phrases)
885
882
 
886
883
  def _deduplicate_extracted_items(
887
884
  self, items: List[Dict[str, Any]]
@@ -9,6 +9,6 @@ from .shared_prompt_cache import SharedPromptCache
9
9
  from .simple_cache import SimpleCacheService
10
10
 
11
11
  __all__ = [
12
- "SimpleCacheService",
13
12
  "SharedPromptCache",
13
+ "SimpleCacheService",
14
14
  ]
@@ -41,15 +41,13 @@ import asyncio
41
41
  import json
42
42
  import threading
43
43
  import time
44
- import weakref
45
44
  from collections import OrderedDict
46
45
  from dataclasses import dataclass, field
47
- from datetime import datetime, timedelta
48
46
  from functools import wraps
49
47
  from threading import RLock
50
- from typing import Any, Dict, List, Optional, Set, Tuple, Union
48
+ from typing import Any, Dict, List, Optional, Set
51
49
 
52
- from claude_mpm.core.base_service import BaseService, ServiceHealth, ServiceMetrics
50
+ from claude_mpm.core.base_service import BaseService
53
51
 
54
52
 
55
53
  @dataclass
@@ -429,7 +427,7 @@ class SharedPromptCache(BaseService):
429
427
  with self._cache_lock:
430
428
  keys_to_remove = []
431
429
 
432
- for key in self._cache.keys():
430
+ for key in self._cache:
433
431
  if fnmatch.fnmatch(key, pattern):
434
432
  keys_to_remove.append(key)
435
433
 
@@ -229,7 +229,7 @@ class SimpleCacheService(ICacheService):
229
229
  with self.lock:
230
230
  keys_to_delete = []
231
231
 
232
- for key in self.cache.keys():
232
+ for key in self.cache:
233
233
  if fnmatch.fnmatch(key, pattern):
234
234
  keys_to_delete.append(key)
235
235
 
@@ -18,17 +18,15 @@ WHY indexed memory:
18
18
 
19
19
  import bisect
20
20
  import hashlib
21
- import mmap
22
- import os
23
21
  import pickle
24
22
  import re
25
23
  import time
26
24
  from collections import Counter, defaultdict
27
25
  from dataclasses import dataclass, field
28
26
  from datetime import datetime, timedelta
29
- from typing import Any, Dict, List, Optional, Set, Tuple, Union
27
+ from typing import Any, Dict, List, Optional, Set, Tuple
30
28
 
31
- from ...core.cache import FileSystemCache, get_file_cache
29
+ from ...core.cache import get_file_cache
32
30
  from ...core.logger import get_logger
33
31
 
34
32
 
@@ -256,7 +254,7 @@ class BTreeIndex:
256
254
  self.index = [(k, id) for k, id in self.index if id != entry_id]
257
255
 
258
256
  def range_search(
259
- self, min_key: Any = None, max_key: Any = None, limit: int = None
257
+ self, min_key: Any = None, max_key: Any = None, limit: Optional[int] = None
260
258
  ) -> List[str]:
261
259
  """Search for entries in key range.
262
260
 
@@ -366,8 +364,8 @@ class IndexedMemoryService:
366
364
  agent_id: str,
367
365
  content: str,
368
366
  category: str = "general",
369
- tags: List[str] = None,
370
- metadata: Dict[str, Any] = None,
367
+ tags: Optional[List[str]] = None,
368
+ metadata: Optional[Dict[str, Any]] = None,
371
369
  ) -> str:
372
370
  """Add a new memory entry.
373
371
 
@@ -27,7 +27,7 @@ import re
27
27
  from datetime import datetime
28
28
  from difflib import SequenceMatcher
29
29
  from pathlib import Path
30
- from typing import Any, Dict, List, Optional, Set, Tuple
30
+ from typing import Any, Dict, List, Optional, Tuple
31
31
 
32
32
  from claude_mpm.core.config import Config
33
33
  from claude_mpm.core.mixins import LoggerMixin
@@ -260,8 +260,7 @@ class MemoryOptimizer(LoggerMixin):
260
260
  try:
261
261
  if agent_id:
262
262
  return self._analyze_single_agent(agent_id)
263
- else:
264
- return self._analyze_all_agents()
263
+ return self._analyze_all_agents()
265
264
 
266
265
  except Exception as e:
267
266
  self.logger.error(f"Error analyzing optimization opportunities: {e}")
@@ -324,7 +323,7 @@ class MemoryOptimizer(LoggerMixin):
324
323
  stripped = line.strip()
325
324
  if stripped.startswith("- "):
326
325
  bullet_points.append(line)
327
- elif stripped.startswith("## ") or stripped.startswith("<!--"):
326
+ elif stripped.startswith(("## ", "<!--")):
328
327
  header_lines.append(line)
329
328
  else:
330
329
  other_lines.append(line)
@@ -533,28 +532,26 @@ class MemoryOptimizer(LoggerMixin):
533
532
  # Add ordered sections
534
533
  for section_name in section_order:
535
534
  if section_name in sections and section_name != "header":
536
- if content_lines and not content_lines[-1].strip() == "":
535
+ if content_lines and content_lines[-1].strip() != "":
537
536
  content_lines.append("") # Add spacing
538
537
  content_lines.extend(sections[section_name])
539
538
 
540
539
  # Add any remaining sections not in the order
541
540
  for section_name, section_content in sections.items():
542
541
  if section_name not in section_order and section_name != "header":
543
- if content_lines and not content_lines[-1].strip() == "":
542
+ if content_lines and content_lines[-1].strip() != "":
544
543
  content_lines.append("")
545
544
  content_lines.extend(section_content)
546
545
 
547
546
  # Update timestamp
548
547
  content = "\n".join(content_lines)
549
548
  timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
550
- content = re.sub(
549
+ return re.sub(
551
550
  r"<!-- Last Updated: .+ \| Auto-updated by: .+ -->",
552
551
  f"<!-- Last Updated: {timestamp} | Auto-updated by: optimizer -->",
553
552
  content,
554
553
  )
555
554
 
556
- return content
557
-
558
555
  def _create_backup(self, memory_file: Path) -> Path:
559
556
  """Create backup of memory file before optimization.
560
557
 
@@ -601,7 +598,7 @@ class MemoryOptimizer(LoggerMixin):
601
598
  "agent_id": agent_id,
602
599
  "file_size": len(content),
603
600
  "sections": len(
604
- [s for s in sections if not s.lower() in ["header", "metadata"]]
601
+ [s for s in sections if s.lower() not in ["header", "metadata"]]
605
602
  ),
606
603
  "opportunities": [],
607
604
  }
@@ -586,9 +586,9 @@ class MemoryRouter(LoggerMixin):
586
586
  "expected_agent": expected,
587
587
  "actual_agent": routing_result["target_agent"],
588
588
  "confidence": routing_result["confidence"],
589
- "correct": expected == routing_result["target_agent"]
590
- if expected
591
- else None,
589
+ "correct": (
590
+ expected == routing_result["target_agent"] if expected else None
591
+ ),
592
592
  "reasoning": routing_result["reasoning"],
593
593
  }
594
594
 
@@ -781,17 +781,16 @@ class MemoryRouter(LoggerMixin):
781
781
  # Simple heuristics for section selection
782
782
  if "mistake" in content or "error" in content or "avoid" in content:
783
783
  return "Common Mistakes to Avoid"
784
- elif "pattern" in content or "architecture" in content:
784
+ if "pattern" in content or "architecture" in content:
785
785
  return (
786
786
  sections[0] if sections else "Recent Learnings"
787
787
  ) # First section is usually patterns
788
- elif "guideline" in content or "standard" in content:
788
+ if "guideline" in content or "standard" in content:
789
789
  return "Implementation Guidelines"
790
- elif "context" in content or "current" in content:
790
+ if "context" in content or "current" in content:
791
791
  return "Current Technical Context"
792
- else:
793
- # Default to first available section or Recent Learnings
794
- return sections[0] if sections else "Recent Learnings"
792
+ # Default to first available section or Recent Learnings
793
+ return sections[0] if sections else "Recent Learnings"
795
794
 
796
795
  def _build_reasoning(
797
796
  self,