claude-mpm 3.9.11__py3-none-any.whl → 4.0.4__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 (434) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/__init__.py +2 -2
  3. claude_mpm/__main__.py +3 -2
  4. claude_mpm/agents/__init__.py +85 -79
  5. claude_mpm/agents/agent_loader.py +464 -1003
  6. claude_mpm/agents/agent_loader_integration.py +45 -45
  7. claude_mpm/agents/agents_metadata.py +29 -30
  8. claude_mpm/agents/async_agent_loader.py +156 -138
  9. claude_mpm/agents/base_agent.json +1 -1
  10. claude_mpm/agents/base_agent_loader.py +179 -151
  11. claude_mpm/agents/frontmatter_validator.py +229 -130
  12. claude_mpm/agents/schema/agent_schema.json +1 -1
  13. claude_mpm/agents/system_agent_config.py +213 -147
  14. claude_mpm/agents/templates/__init__.py +13 -13
  15. claude_mpm/agents/templates/code_analyzer.json +2 -2
  16. claude_mpm/agents/templates/data_engineer.json +1 -1
  17. claude_mpm/agents/templates/documentation.json +23 -11
  18. claude_mpm/agents/templates/engineer.json +22 -6
  19. claude_mpm/agents/templates/memory_manager.json +1 -1
  20. claude_mpm/agents/templates/ops.json +2 -2
  21. claude_mpm/agents/templates/project_organizer.json +1 -1
  22. claude_mpm/agents/templates/qa.json +1 -1
  23. claude_mpm/agents/templates/refactoring_engineer.json +222 -0
  24. claude_mpm/agents/templates/research.json +20 -14
  25. claude_mpm/agents/templates/security.json +1 -1
  26. claude_mpm/agents/templates/ticketing.json +2 -2
  27. claude_mpm/agents/templates/version_control.json +1 -1
  28. claude_mpm/agents/templates/web_qa.json +3 -1
  29. claude_mpm/agents/templates/web_ui.json +2 -2
  30. claude_mpm/cli/__init__.py +79 -51
  31. claude_mpm/cli/__main__.py +3 -2
  32. claude_mpm/cli/commands/__init__.py +20 -20
  33. claude_mpm/cli/commands/agents.py +279 -247
  34. claude_mpm/cli/commands/aggregate.py +138 -157
  35. claude_mpm/cli/commands/cleanup.py +147 -147
  36. claude_mpm/cli/commands/config.py +93 -76
  37. claude_mpm/cli/commands/info.py +17 -16
  38. claude_mpm/cli/commands/mcp.py +140 -905
  39. claude_mpm/cli/commands/mcp_command_router.py +139 -0
  40. claude_mpm/cli/commands/mcp_config_commands.py +20 -0
  41. claude_mpm/cli/commands/mcp_install_commands.py +20 -0
  42. claude_mpm/cli/commands/mcp_server_commands.py +175 -0
  43. claude_mpm/cli/commands/mcp_tool_commands.py +34 -0
  44. claude_mpm/cli/commands/memory.py +239 -203
  45. claude_mpm/cli/commands/monitor.py +330 -86
  46. claude_mpm/cli/commands/run.py +380 -429
  47. claude_mpm/cli/commands/run_config_checker.py +160 -0
  48. claude_mpm/cli/commands/socketio_monitor.py +235 -0
  49. claude_mpm/cli/commands/tickets.py +363 -220
  50. claude_mpm/cli/parser.py +24 -1156
  51. claude_mpm/cli/parsers/__init__.py +29 -0
  52. claude_mpm/cli/parsers/agents_parser.py +136 -0
  53. claude_mpm/cli/parsers/base_parser.py +331 -0
  54. claude_mpm/cli/parsers/config_parser.py +85 -0
  55. claude_mpm/cli/parsers/mcp_parser.py +152 -0
  56. claude_mpm/cli/parsers/memory_parser.py +138 -0
  57. claude_mpm/cli/parsers/monitor_parser.py +124 -0
  58. claude_mpm/cli/parsers/run_parser.py +147 -0
  59. claude_mpm/cli/parsers/tickets_parser.py +203 -0
  60. claude_mpm/cli/ticket_cli.py +7 -3
  61. claude_mpm/cli/utils.py +55 -37
  62. claude_mpm/cli_module/__init__.py +6 -6
  63. claude_mpm/cli_module/args.py +188 -140
  64. claude_mpm/cli_module/commands.py +79 -70
  65. claude_mpm/cli_module/migration_example.py +38 -60
  66. claude_mpm/config/__init__.py +32 -25
  67. claude_mpm/config/agent_config.py +151 -119
  68. claude_mpm/config/experimental_features.py +71 -73
  69. claude_mpm/config/paths.py +94 -208
  70. claude_mpm/config/socketio_config.py +84 -73
  71. claude_mpm/constants.py +35 -18
  72. claude_mpm/core/__init__.py +9 -6
  73. claude_mpm/core/agent_name_normalizer.py +68 -71
  74. claude_mpm/core/agent_registry.py +372 -521
  75. claude_mpm/core/agent_session_manager.py +74 -63
  76. claude_mpm/core/base_service.py +116 -87
  77. claude_mpm/core/cache.py +119 -153
  78. claude_mpm/core/claude_runner.py +425 -1120
  79. claude_mpm/core/config.py +263 -168
  80. claude_mpm/core/config_aliases.py +69 -61
  81. claude_mpm/core/config_constants.py +292 -0
  82. claude_mpm/core/constants.py +57 -99
  83. claude_mpm/core/container.py +211 -178
  84. claude_mpm/core/exceptions.py +233 -89
  85. claude_mpm/core/factories.py +92 -54
  86. claude_mpm/core/framework_loader.py +378 -220
  87. claude_mpm/core/hook_manager.py +198 -83
  88. claude_mpm/core/hook_performance_config.py +136 -0
  89. claude_mpm/core/injectable_service.py +61 -55
  90. claude_mpm/core/interactive_session.py +165 -155
  91. claude_mpm/core/interfaces.py +221 -195
  92. claude_mpm/core/lazy.py +96 -96
  93. claude_mpm/core/logger.py +133 -107
  94. claude_mpm/core/logging_config.py +185 -157
  95. claude_mpm/core/minimal_framework_loader.py +20 -15
  96. claude_mpm/core/mixins.py +30 -29
  97. claude_mpm/core/oneshot_session.py +215 -181
  98. claude_mpm/core/optimized_agent_loader.py +134 -138
  99. claude_mpm/core/optimized_startup.py +159 -157
  100. claude_mpm/core/pm_hook_interceptor.py +85 -72
  101. claude_mpm/core/service_registry.py +103 -101
  102. claude_mpm/core/session_manager.py +97 -87
  103. claude_mpm/core/socketio_pool.py +212 -158
  104. claude_mpm/core/tool_access_control.py +58 -51
  105. claude_mpm/core/types.py +46 -24
  106. claude_mpm/core/typing_utils.py +166 -82
  107. claude_mpm/core/unified_agent_registry.py +721 -0
  108. claude_mpm/core/unified_config.py +550 -0
  109. claude_mpm/core/unified_paths.py +549 -0
  110. claude_mpm/dashboard/index.html +1 -1
  111. claude_mpm/dashboard/open_dashboard.py +51 -17
  112. claude_mpm/dashboard/static/built/components/agent-inference.js +2 -0
  113. claude_mpm/dashboard/static/built/components/event-processor.js +2 -0
  114. claude_mpm/dashboard/static/built/components/event-viewer.js +2 -0
  115. claude_mpm/dashboard/static/built/components/export-manager.js +2 -0
  116. claude_mpm/dashboard/static/built/components/file-tool-tracker.js +2 -0
  117. claude_mpm/dashboard/static/built/components/hud-library-loader.js +2 -0
  118. claude_mpm/dashboard/static/built/components/hud-manager.js +2 -0
  119. claude_mpm/dashboard/static/built/components/hud-visualizer.js +2 -0
  120. claude_mpm/dashboard/static/built/components/module-viewer.js +2 -0
  121. claude_mpm/dashboard/static/built/components/session-manager.js +2 -0
  122. claude_mpm/dashboard/static/built/components/socket-manager.js +2 -0
  123. claude_mpm/dashboard/static/built/components/ui-state-manager.js +2 -0
  124. claude_mpm/dashboard/static/built/components/working-directory.js +2 -0
  125. claude_mpm/dashboard/static/built/dashboard.js +2 -0
  126. claude_mpm/dashboard/static/built/socket-client.js +2 -0
  127. claude_mpm/dashboard/static/css/dashboard.css +27 -8
  128. claude_mpm/dashboard/static/dist/components/agent-inference.js +2 -0
  129. claude_mpm/dashboard/static/dist/components/event-processor.js +2 -0
  130. claude_mpm/dashboard/static/dist/components/event-viewer.js +2 -0
  131. claude_mpm/dashboard/static/dist/components/export-manager.js +2 -0
  132. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +2 -0
  133. claude_mpm/dashboard/static/dist/components/hud-library-loader.js +2 -0
  134. claude_mpm/dashboard/static/dist/components/hud-manager.js +2 -0
  135. claude_mpm/dashboard/static/dist/components/hud-visualizer.js +2 -0
  136. claude_mpm/dashboard/static/dist/components/module-viewer.js +2 -0
  137. claude_mpm/dashboard/static/dist/components/session-manager.js +2 -0
  138. claude_mpm/dashboard/static/dist/components/socket-manager.js +2 -0
  139. claude_mpm/dashboard/static/dist/components/ui-state-manager.js +2 -0
  140. claude_mpm/dashboard/static/dist/components/working-directory.js +2 -0
  141. claude_mpm/dashboard/static/dist/dashboard.js +2 -0
  142. claude_mpm/dashboard/static/dist/socket-client.js +2 -0
  143. claude_mpm/dashboard/static/js/components/agent-inference.js +80 -76
  144. claude_mpm/dashboard/static/js/components/event-processor.js +71 -67
  145. claude_mpm/dashboard/static/js/components/event-viewer.js +93 -72
  146. claude_mpm/dashboard/static/js/components/export-manager.js +31 -28
  147. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +110 -96
  148. claude_mpm/dashboard/static/js/components/hud-library-loader.js +11 -11
  149. claude_mpm/dashboard/static/js/components/hud-manager.js +73 -73
  150. claude_mpm/dashboard/static/js/components/hud-visualizer.js +163 -163
  151. claude_mpm/dashboard/static/js/components/module-viewer.js +305 -233
  152. claude_mpm/dashboard/static/js/components/session-manager.js +32 -29
  153. claude_mpm/dashboard/static/js/components/socket-manager.js +27 -20
  154. claude_mpm/dashboard/static/js/components/ui-state-manager.js +21 -18
  155. claude_mpm/dashboard/static/js/components/working-directory.js +74 -71
  156. claude_mpm/dashboard/static/js/dashboard.js +178 -453
  157. claude_mpm/dashboard/static/js/extension-error-handler.js +164 -0
  158. claude_mpm/dashboard/static/js/socket-client.js +133 -53
  159. claude_mpm/dashboard/templates/index.html +40 -50
  160. claude_mpm/experimental/cli_enhancements.py +60 -58
  161. claude_mpm/generators/__init__.py +1 -1
  162. claude_mpm/generators/agent_profile_generator.py +75 -65
  163. claude_mpm/hooks/__init__.py +1 -1
  164. claude_mpm/hooks/base_hook.py +33 -28
  165. claude_mpm/hooks/claude_hooks/__init__.py +1 -1
  166. claude_mpm/hooks/claude_hooks/connection_pool.py +120 -0
  167. claude_mpm/hooks/claude_hooks/event_handlers.py +743 -0
  168. claude_mpm/hooks/claude_hooks/hook_handler.py +415 -1331
  169. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +4 -4
  170. claude_mpm/hooks/claude_hooks/memory_integration.py +221 -0
  171. claude_mpm/hooks/claude_hooks/response_tracking.py +348 -0
  172. claude_mpm/hooks/claude_hooks/tool_analysis.py +230 -0
  173. claude_mpm/hooks/memory_integration_hook.py +140 -100
  174. claude_mpm/hooks/tool_call_interceptor.py +89 -76
  175. claude_mpm/hooks/validation_hooks.py +57 -49
  176. claude_mpm/init.py +145 -121
  177. claude_mpm/models/__init__.py +9 -9
  178. claude_mpm/models/agent_definition.py +33 -23
  179. claude_mpm/models/agent_session.py +228 -200
  180. claude_mpm/scripts/__init__.py +1 -1
  181. claude_mpm/scripts/socketio_daemon.py +192 -75
  182. claude_mpm/scripts/socketio_server_manager.py +328 -0
  183. claude_mpm/scripts/start_activity_logging.py +25 -22
  184. claude_mpm/services/__init__.py +68 -43
  185. claude_mpm/services/agent_capabilities_service.py +271 -0
  186. claude_mpm/services/agents/__init__.py +23 -32
  187. claude_mpm/services/agents/deployment/__init__.py +3 -3
  188. claude_mpm/services/agents/deployment/agent_config_provider.py +310 -0
  189. claude_mpm/services/agents/deployment/agent_configuration_manager.py +359 -0
  190. claude_mpm/services/agents/deployment/agent_definition_factory.py +84 -0
  191. claude_mpm/services/agents/deployment/agent_deployment.py +415 -2113
  192. claude_mpm/services/agents/deployment/agent_discovery_service.py +387 -0
  193. claude_mpm/services/agents/deployment/agent_environment_manager.py +293 -0
  194. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +387 -0
  195. claude_mpm/services/agents/deployment/agent_format_converter.py +453 -0
  196. claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +161 -0
  197. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +345 -495
  198. claude_mpm/services/agents/deployment/agent_metrics_collector.py +279 -0
  199. claude_mpm/services/agents/deployment/agent_restore_handler.py +88 -0
  200. claude_mpm/services/agents/deployment/agent_template_builder.py +406 -0
  201. claude_mpm/services/agents/deployment/agent_validator.py +352 -0
  202. claude_mpm/services/agents/deployment/agent_version_manager.py +313 -0
  203. claude_mpm/services/agents/deployment/agent_versioning.py +6 -9
  204. claude_mpm/services/agents/deployment/agents_directory_resolver.py +79 -0
  205. claude_mpm/services/agents/deployment/async_agent_deployment.py +298 -234
  206. claude_mpm/services/agents/deployment/config/__init__.py +13 -0
  207. claude_mpm/services/agents/deployment/config/deployment_config.py +182 -0
  208. claude_mpm/services/agents/deployment/config/deployment_config_manager.py +200 -0
  209. claude_mpm/services/agents/deployment/deployment_config_loader.py +54 -0
  210. claude_mpm/services/agents/deployment/deployment_type_detector.py +124 -0
  211. claude_mpm/services/agents/deployment/facade/__init__.py +18 -0
  212. claude_mpm/services/agents/deployment/facade/async_deployment_executor.py +159 -0
  213. claude_mpm/services/agents/deployment/facade/deployment_executor.py +73 -0
  214. claude_mpm/services/agents/deployment/facade/deployment_facade.py +270 -0
  215. claude_mpm/services/agents/deployment/facade/sync_deployment_executor.py +178 -0
  216. claude_mpm/services/agents/deployment/interface_adapter.py +227 -0
  217. claude_mpm/services/agents/deployment/lifecycle_health_checker.py +85 -0
  218. claude_mpm/services/agents/deployment/lifecycle_performance_tracker.py +100 -0
  219. claude_mpm/services/agents/deployment/pipeline/__init__.py +32 -0
  220. claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +158 -0
  221. claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +159 -0
  222. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +169 -0
  223. claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +19 -0
  224. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +195 -0
  225. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +119 -0
  226. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +79 -0
  227. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +90 -0
  228. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +100 -0
  229. claude_mpm/services/agents/deployment/processors/__init__.py +15 -0
  230. claude_mpm/services/agents/deployment/processors/agent_deployment_context.py +98 -0
  231. claude_mpm/services/agents/deployment/processors/agent_deployment_result.py +235 -0
  232. claude_mpm/services/agents/deployment/processors/agent_processor.py +258 -0
  233. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +318 -0
  234. claude_mpm/services/agents/deployment/results/__init__.py +13 -0
  235. claude_mpm/services/agents/deployment/results/deployment_metrics.py +200 -0
  236. claude_mpm/services/agents/deployment/results/deployment_result_builder.py +249 -0
  237. claude_mpm/services/agents/deployment/strategies/__init__.py +25 -0
  238. claude_mpm/services/agents/deployment/strategies/base_strategy.py +119 -0
  239. claude_mpm/services/agents/deployment/strategies/project_strategy.py +150 -0
  240. claude_mpm/services/agents/deployment/strategies/strategy_selector.py +117 -0
  241. claude_mpm/services/agents/deployment/strategies/system_strategy.py +116 -0
  242. claude_mpm/services/agents/deployment/strategies/user_strategy.py +137 -0
  243. claude_mpm/services/agents/deployment/system_instructions_deployer.py +108 -0
  244. claude_mpm/services/agents/deployment/validation/__init__.py +19 -0
  245. claude_mpm/services/agents/deployment/validation/agent_validator.py +323 -0
  246. claude_mpm/services/agents/deployment/validation/deployment_validator.py +238 -0
  247. claude_mpm/services/agents/deployment/validation/template_validator.py +299 -0
  248. claude_mpm/services/agents/deployment/validation/validation_result.py +226 -0
  249. claude_mpm/services/agents/loading/__init__.py +2 -2
  250. claude_mpm/services/agents/loading/agent_profile_loader.py +259 -229
  251. claude_mpm/services/agents/loading/base_agent_manager.py +90 -81
  252. claude_mpm/services/agents/loading/framework_agent_loader.py +154 -129
  253. claude_mpm/services/agents/management/__init__.py +2 -2
  254. claude_mpm/services/agents/management/agent_capabilities_generator.py +72 -58
  255. claude_mpm/services/agents/management/agent_management_service.py +209 -156
  256. claude_mpm/services/agents/memory/__init__.py +9 -6
  257. claude_mpm/services/agents/memory/agent_memory_manager.py +218 -1152
  258. claude_mpm/services/agents/memory/agent_persistence_service.py +20 -16
  259. claude_mpm/services/agents/memory/analyzer.py +430 -0
  260. claude_mpm/services/agents/memory/content_manager.py +376 -0
  261. claude_mpm/services/agents/memory/template_generator.py +468 -0
  262. claude_mpm/services/agents/registry/__init__.py +7 -10
  263. claude_mpm/services/agents/registry/deployed_agent_discovery.py +122 -97
  264. claude_mpm/services/agents/registry/modification_tracker.py +351 -285
  265. claude_mpm/services/async_session_logger.py +187 -153
  266. claude_mpm/services/claude_session_logger.py +87 -72
  267. claude_mpm/services/command_handler_service.py +217 -0
  268. claude_mpm/services/communication/__init__.py +3 -2
  269. claude_mpm/services/core/__init__.py +50 -97
  270. claude_mpm/services/core/base.py +60 -53
  271. claude_mpm/services/core/interfaces/__init__.py +188 -0
  272. claude_mpm/services/core/interfaces/agent.py +351 -0
  273. claude_mpm/services/core/interfaces/communication.py +343 -0
  274. claude_mpm/services/core/interfaces/infrastructure.py +413 -0
  275. claude_mpm/services/core/interfaces/service.py +434 -0
  276. claude_mpm/services/core/interfaces.py +19 -944
  277. claude_mpm/services/event_aggregator.py +208 -170
  278. claude_mpm/services/exceptions.py +387 -308
  279. claude_mpm/services/framework_claude_md_generator/__init__.py +75 -79
  280. claude_mpm/services/framework_claude_md_generator/content_assembler.py +69 -60
  281. claude_mpm/services/framework_claude_md_generator/content_validator.py +65 -61
  282. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +68 -49
  283. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +34 -34
  284. claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +25 -22
  285. claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +10 -10
  286. claude_mpm/services/framework_claude_md_generator/section_generators/core_responsibilities.py +4 -3
  287. claude_mpm/services/framework_claude_md_generator/section_generators/delegation_constraints.py +4 -3
  288. claude_mpm/services/framework_claude_md_generator/section_generators/environment_config.py +4 -3
  289. claude_mpm/services/framework_claude_md_generator/section_generators/footer.py +6 -5
  290. claude_mpm/services/framework_claude_md_generator/section_generators/header.py +8 -7
  291. claude_mpm/services/framework_claude_md_generator/section_generators/orchestration_principles.py +4 -3
  292. claude_mpm/services/framework_claude_md_generator/section_generators/role_designation.py +6 -5
  293. claude_mpm/services/framework_claude_md_generator/section_generators/subprocess_validation.py +9 -8
  294. claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +4 -3
  295. claude_mpm/services/framework_claude_md_generator/section_generators/troubleshooting.py +5 -4
  296. claude_mpm/services/framework_claude_md_generator/section_manager.py +28 -27
  297. claude_mpm/services/framework_claude_md_generator/version_manager.py +30 -28
  298. claude_mpm/services/hook_service.py +106 -114
  299. claude_mpm/services/infrastructure/__init__.py +7 -5
  300. claude_mpm/services/infrastructure/context_preservation.py +233 -199
  301. claude_mpm/services/infrastructure/daemon_manager.py +279 -0
  302. claude_mpm/services/infrastructure/logging.py +83 -76
  303. claude_mpm/services/infrastructure/monitoring.py +547 -404
  304. claude_mpm/services/mcp_gateway/__init__.py +30 -13
  305. claude_mpm/services/mcp_gateway/config/__init__.py +2 -2
  306. claude_mpm/services/mcp_gateway/config/config_loader.py +61 -56
  307. claude_mpm/services/mcp_gateway/config/config_schema.py +50 -41
  308. claude_mpm/services/mcp_gateway/config/configuration.py +82 -75
  309. claude_mpm/services/mcp_gateway/core/__init__.py +13 -20
  310. claude_mpm/services/mcp_gateway/core/base.py +80 -67
  311. claude_mpm/services/mcp_gateway/core/exceptions.py +60 -46
  312. claude_mpm/services/mcp_gateway/core/interfaces.py +87 -84
  313. claude_mpm/services/mcp_gateway/main.py +287 -137
  314. claude_mpm/services/mcp_gateway/registry/__init__.py +1 -1
  315. claude_mpm/services/mcp_gateway/registry/service_registry.py +97 -94
  316. claude_mpm/services/mcp_gateway/registry/tool_registry.py +135 -126
  317. claude_mpm/services/mcp_gateway/server/__init__.py +2 -2
  318. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +105 -110
  319. claude_mpm/services/mcp_gateway/server/stdio_handler.py +105 -107
  320. claude_mpm/services/mcp_gateway/server/stdio_server.py +691 -0
  321. claude_mpm/services/mcp_gateway/tools/__init__.py +4 -2
  322. claude_mpm/services/mcp_gateway/tools/base_adapter.py +109 -119
  323. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +283 -215
  324. claude_mpm/services/mcp_gateway/tools/hello_world.py +122 -120
  325. claude_mpm/services/mcp_gateway/tools/ticket_tools.py +652 -0
  326. claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +606 -0
  327. claude_mpm/services/memory/__init__.py +2 -2
  328. claude_mpm/services/memory/builder.py +451 -362
  329. claude_mpm/services/memory/cache/__init__.py +2 -2
  330. claude_mpm/services/memory/cache/shared_prompt_cache.py +232 -194
  331. claude_mpm/services/memory/cache/simple_cache.py +107 -93
  332. claude_mpm/services/memory/indexed_memory.py +195 -193
  333. claude_mpm/services/memory/optimizer.py +267 -234
  334. claude_mpm/services/memory/router.py +571 -263
  335. claude_mpm/services/memory_hook_service.py +237 -0
  336. claude_mpm/services/port_manager.py +575 -0
  337. claude_mpm/services/project/__init__.py +3 -3
  338. claude_mpm/services/project/analyzer.py +451 -305
  339. claude_mpm/services/project/registry.py +262 -240
  340. claude_mpm/services/recovery_manager.py +287 -231
  341. claude_mpm/services/response_tracker.py +87 -67
  342. claude_mpm/services/runner_configuration_service.py +587 -0
  343. claude_mpm/services/session_management_service.py +304 -0
  344. claude_mpm/services/socketio/__init__.py +4 -4
  345. claude_mpm/services/socketio/client_proxy.py +174 -0
  346. claude_mpm/services/socketio/handlers/__init__.py +3 -3
  347. claude_mpm/services/socketio/handlers/base.py +44 -30
  348. claude_mpm/services/socketio/handlers/connection.py +166 -64
  349. claude_mpm/services/socketio/handlers/file.py +123 -108
  350. claude_mpm/services/socketio/handlers/git.py +607 -373
  351. claude_mpm/services/socketio/handlers/hook.py +185 -0
  352. claude_mpm/services/socketio/handlers/memory.py +4 -4
  353. claude_mpm/services/socketio/handlers/project.py +4 -4
  354. claude_mpm/services/socketio/handlers/registry.py +53 -38
  355. claude_mpm/services/socketio/server/__init__.py +18 -0
  356. claude_mpm/services/socketio/server/broadcaster.py +252 -0
  357. claude_mpm/services/socketio/server/core.py +399 -0
  358. claude_mpm/services/socketio/server/main.py +323 -0
  359. claude_mpm/services/socketio_client_manager.py +160 -133
  360. claude_mpm/services/socketio_server.py +36 -1885
  361. claude_mpm/services/subprocess_launcher_service.py +316 -0
  362. claude_mpm/services/system_instructions_service.py +258 -0
  363. claude_mpm/services/ticket_manager.py +19 -533
  364. claude_mpm/services/utility_service.py +285 -0
  365. claude_mpm/services/version_control/__init__.py +18 -21
  366. claude_mpm/services/version_control/branch_strategy.py +20 -10
  367. claude_mpm/services/version_control/conflict_resolution.py +37 -13
  368. claude_mpm/services/version_control/git_operations.py +52 -21
  369. claude_mpm/services/version_control/semantic_versioning.py +92 -53
  370. claude_mpm/services/version_control/version_parser.py +145 -125
  371. claude_mpm/services/version_service.py +270 -0
  372. claude_mpm/storage/__init__.py +2 -2
  373. claude_mpm/storage/state_storage.py +177 -181
  374. claude_mpm/ticket_wrapper.py +2 -2
  375. claude_mpm/utils/__init__.py +2 -2
  376. claude_mpm/utils/agent_dependency_loader.py +453 -243
  377. claude_mpm/utils/config_manager.py +157 -118
  378. claude_mpm/utils/console.py +1 -1
  379. claude_mpm/utils/dependency_cache.py +102 -107
  380. claude_mpm/utils/dependency_manager.py +52 -47
  381. claude_mpm/utils/dependency_strategies.py +131 -96
  382. claude_mpm/utils/environment_context.py +110 -102
  383. claude_mpm/utils/error_handler.py +75 -55
  384. claude_mpm/utils/file_utils.py +80 -67
  385. claude_mpm/utils/framework_detection.py +12 -11
  386. claude_mpm/utils/import_migration_example.py +12 -60
  387. claude_mpm/utils/imports.py +48 -45
  388. claude_mpm/utils/path_operations.py +100 -93
  389. claude_mpm/utils/robust_installer.py +172 -164
  390. claude_mpm/utils/session_logging.py +30 -23
  391. claude_mpm/utils/subprocess_utils.py +99 -61
  392. claude_mpm/validation/__init__.py +1 -1
  393. claude_mpm/validation/agent_validator.py +151 -111
  394. claude_mpm/validation/frontmatter_validator.py +92 -71
  395. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/METADATA +90 -22
  396. claude_mpm-4.0.4.dist-info/RECORD +417 -0
  397. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/entry_points.txt +1 -0
  398. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/licenses/LICENSE +1 -1
  399. claude_mpm/cli/commands/run_guarded.py +0 -511
  400. claude_mpm/config/memory_guardian_config.py +0 -325
  401. claude_mpm/config/memory_guardian_yaml.py +0 -335
  402. claude_mpm/core/config_paths.py +0 -150
  403. claude_mpm/core/memory_aware_runner.py +0 -353
  404. claude_mpm/dashboard/static/js/dashboard-original.js +0 -4134
  405. claude_mpm/deployment_paths.py +0 -261
  406. claude_mpm/hooks/claude_hooks/hook_handler_fixed.py +0 -454
  407. claude_mpm/models/state_models.py +0 -433
  408. claude_mpm/services/agent/__init__.py +0 -24
  409. claude_mpm/services/agent/deployment.py +0 -2548
  410. claude_mpm/services/agent/management.py +0 -598
  411. claude_mpm/services/agent/registry.py +0 -813
  412. claude_mpm/services/agents/registry/agent_registry.py +0 -813
  413. claude_mpm/services/communication/socketio.py +0 -1935
  414. claude_mpm/services/communication/websocket.py +0 -479
  415. claude_mpm/services/framework_claude_md_generator.py +0 -624
  416. claude_mpm/services/health_monitor.py +0 -893
  417. claude_mpm/services/infrastructure/graceful_degradation.py +0 -616
  418. claude_mpm/services/infrastructure/health_monitor.py +0 -775
  419. claude_mpm/services/infrastructure/memory_dashboard.py +0 -479
  420. claude_mpm/services/infrastructure/memory_guardian.py +0 -944
  421. claude_mpm/services/infrastructure/restart_protection.py +0 -642
  422. claude_mpm/services/infrastructure/state_manager.py +0 -774
  423. claude_mpm/services/mcp_gateway/manager.py +0 -334
  424. claude_mpm/services/optimized_hook_service.py +0 -542
  425. claude_mpm/services/project_analyzer.py +0 -864
  426. claude_mpm/services/project_registry.py +0 -608
  427. claude_mpm/services/standalone_socketio_server.py +0 -1300
  428. claude_mpm/services/ticket_manager_di.py +0 -318
  429. claude_mpm/services/ticketing_service_original.py +0 -510
  430. claude_mpm/utils/paths.py +0 -395
  431. claude_mpm/utils/platform_memory.py +0 -524
  432. claude_mpm-3.9.11.dist-info/RECORD +0 -306
  433. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/WHEEL +0 -0
  434. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/top_level.txt +0 -0
@@ -19,43 +19,44 @@ This is a consolidated version combining all functionality from the previous
19
19
  multi-file implementation for better maintainability.
20
20
  """
21
21
 
22
- import os
23
- import json
24
- import logging
25
22
  import asyncio
26
23
  import hashlib
24
+ import json
25
+ import logging
26
+ import os
27
27
  from dataclasses import dataclass, field
28
28
  from datetime import datetime
29
29
  from enum import Enum
30
30
  from pathlib import Path
31
- from typing import Dict, List, Optional, Any, Tuple, Union, Set
31
+ from typing import Any, Dict, List, Optional, Set, Tuple, Union
32
32
 
33
33
  import yaml
34
34
 
35
35
  from claude_mpm.core.base_service import BaseService
36
36
  from claude_mpm.core.config import Config
37
- from claude_mpm.core.config_paths import ConfigPaths
38
- from claude_mpm.services.memory.cache.shared_prompt_cache import SharedPromptCache
37
+ from claude_mpm.core.unified_paths import get_path_manager
39
38
  from claude_mpm.services.agents.registry import AgentRegistry
39
+ from claude_mpm.services.memory.cache.shared_prompt_cache import SharedPromptCache
40
40
  from claude_mpm.utils.path_operations import path_ops
41
41
 
42
-
43
42
  logger = logging.getLogger(__name__)
44
43
 
45
-
46
44
  # ============================================================================
47
45
  # Data Models
48
46
  # ============================================================================
49
47
 
48
+
50
49
  class ProfileTier(Enum):
51
50
  """Agent profile hierarchy tiers with precedence order."""
51
+
52
52
  PROJECT = "project" # Highest precedence - project-specific agents
53
- USER = "user" # Medium precedence - user-level agents
54
- SYSTEM = "system" # Lowest precedence - framework/built-in agents
53
+ USER = "user" # Medium precedence - user-level agents
54
+ SYSTEM = "system" # Lowest precedence - framework/built-in agents
55
55
 
56
56
 
57
57
  class ProfileStatus(Enum):
58
58
  """Profile loading status."""
59
+
59
60
  LOADED = "loaded"
60
61
  ERROR = "error"
61
62
  NOT_FOUND = "not_found"
@@ -65,6 +66,7 @@ class ProfileStatus(Enum):
65
66
  @dataclass
66
67
  class ImprovedPrompt:
67
68
  """Improved prompt data structure."""
69
+
68
70
  prompt_id: str
69
71
  agent_name: str
70
72
  version: str
@@ -78,6 +80,7 @@ class ImprovedPrompt:
78
80
  @dataclass
79
81
  class AgentProfile:
80
82
  """Complete agent profile with hierarchy information."""
83
+
81
84
  name: str
82
85
  role: str
83
86
  description: str
@@ -98,57 +101,60 @@ class AgentProfile:
98
101
  # Main Service Class
99
102
  # ============================================================================
100
103
 
104
+
101
105
  class AgentProfileLoader(BaseService):
102
106
  """
103
107
  Comprehensive agent profile loading service with enhanced prompt integration.
104
-
108
+
105
109
  This consolidated version combines all functionality from the previous
106
110
  multi-file implementation into a single, maintainable module.
107
111
  """
108
-
112
+
109
113
  def __init__(self, config: Optional[Config] = None):
110
114
  """Initialize the agent profile loader."""
111
115
  super().__init__(name="agent_profile_loader", config=config)
112
-
116
+
113
117
  # Core configuration
114
118
  self.working_directory = Path(os.getcwd())
115
119
  self.framework_path = self._detect_framework_path()
116
120
  self.user_home = Path.home()
117
-
121
+
118
122
  # Tier paths configuration
119
123
  self.tier_paths = {
120
- ProfileTier.PROJECT: self.working_directory / 'agents',
121
- ProfileTier.USER: ConfigPaths.get_user_agents_dir(),
122
- ProfileTier.SYSTEM: Path(__file__).parent.parent / 'agents' / 'templates'
124
+ ProfileTier.PROJECT: self.working_directory / "agents",
125
+ ProfileTier.USER: get_path_manager().get_user_agents_dir(),
126
+ ProfileTier.SYSTEM: Path(__file__).parent.parent / "agents" / "templates",
123
127
  }
124
-
128
+
125
129
  # Remove None values
126
130
  self.tier_paths = {k: v for k, v in self.tier_paths.items() if v is not None}
127
-
131
+
128
132
  # Profile cache
129
133
  self.profile_cache: Dict[str, AgentProfile] = {}
130
134
  self.cache_ttl = 3600 # 1 hour
131
-
135
+
132
136
  # Service integrations
133
137
  self.shared_cache: Optional[SharedPromptCache] = None
134
138
  self.agent_registry: Optional[AgentRegistry] = None
135
-
139
+
136
140
  # Improved prompts storage
137
- self.improved_prompts_path = ConfigPaths.get_user_config_dir() / 'improved_prompts'
141
+ self.improved_prompts_path = (
142
+ get_path_manager().get_user_config_dir() / "improved_prompts"
143
+ )
138
144
  self.improved_prompts_path.mkdir(parents=True, exist_ok=True)
139
-
145
+
140
146
  # Performance tracking
141
147
  self.load_metrics: Dict[str, float] = {}
142
-
148
+
143
149
  logger.info(f"AgentProfileLoader initialized successfully")
144
150
  logger.info(f" Working directory: {self.working_directory}")
145
151
  logger.info(f" Framework path: {self.framework_path}")
146
152
  logger.info(f" Tier paths: {list(self.tier_paths.keys())}")
147
-
153
+
148
154
  async def _initialize(self) -> None:
149
155
  """Initialize the service and its integrations."""
150
156
  logger.info("Initializing AgentProfileLoader service...")
151
-
157
+
152
158
  # Initialize service integrations
153
159
  try:
154
160
  self.shared_cache = SharedPromptCache.get_instance()
@@ -156,114 +162,122 @@ class AgentProfileLoader(BaseService):
156
162
  logger.info("Successfully initialized service integrations")
157
163
  except Exception as e:
158
164
  logger.warning(f"Failed to initialize some integrations: {e}")
159
-
165
+
160
166
  # Discover and cache initial profiles
161
167
  await self._discover_all_profiles()
162
-
168
+
163
169
  logger.info("AgentProfileLoader service initialized successfully")
164
-
170
+
165
171
  async def _cleanup(self) -> None:
166
172
  """Cleanup service resources."""
167
173
  logger.info("Cleaning up AgentProfileLoader service...")
168
-
174
+
169
175
  # Clear caches
170
176
  self.profile_cache.clear()
171
-
177
+
172
178
  # Save any pending improved prompts
173
179
  await self._save_improved_prompts()
174
-
180
+
175
181
  logger.info("AgentProfileLoader service cleaned up")
176
-
182
+
177
183
  async def _health_check(self) -> Dict[str, bool]:
178
184
  """Perform service health checks."""
179
185
  checks = {}
180
-
186
+
181
187
  try:
182
188
  # Check tier paths
183
189
  checks["tier_paths_accessible"] = all(
184
190
  path.exists() for path in self.tier_paths.values()
185
191
  )
186
-
192
+
187
193
  # Check service integrations
188
194
  checks["shared_cache_integration"] = self.shared_cache is not None
189
195
  checks["agent_registry_integration"] = self.agent_registry is not None
190
-
196
+
191
197
  # Check profile discovery
192
198
  profile_count = len(self.profile_cache)
193
199
  checks["profiles_loaded"] = profile_count > 0
194
-
200
+
195
201
  # Check improved prompts storage
196
202
  checks["improved_prompts_storage"] = self.improved_prompts_path.exists()
197
-
203
+
198
204
  except Exception as e:
199
205
  logger.error(f"Health check failed: {e}")
200
206
  checks["health_check_error"] = False
201
-
207
+
202
208
  return checks
203
-
209
+
204
210
  # ========================================================================
205
211
  # Core Profile Loading
206
212
  # ========================================================================
207
-
208
- async def load_agent_profile(self, agent_name: str,
209
- use_cache: bool = True) -> Optional[AgentProfile]:
213
+
214
+ async def load_agent_profile(
215
+ self, agent_name: str, use_cache: bool = True
216
+ ) -> Optional[AgentProfile]:
210
217
  """
211
218
  Load agent profile with three-tier hierarchy precedence.
212
-
219
+
213
220
  Args:
214
221
  agent_name: Name of the agent to load
215
222
  use_cache: Whether to use cached profile if available
216
-
223
+
217
224
  Returns:
218
225
  AgentProfile or None if not found
219
226
  """
220
227
  start_time = asyncio.get_event_loop().time()
221
-
228
+
222
229
  # Check cache first
223
230
  if use_cache and agent_name in self.profile_cache:
224
231
  profile = self.profile_cache[agent_name]
225
232
  if (datetime.now() - profile.loaded_at).seconds < self.cache_ttl:
226
- self.load_metrics[f"{agent_name}_cache_hit"] = asyncio.get_event_loop().time() - start_time
233
+ self.load_metrics[f"{agent_name}_cache_hit"] = (
234
+ asyncio.get_event_loop().time() - start_time
235
+ )
227
236
  return profile
228
-
237
+
229
238
  # Load profile with tier precedence
230
239
  profile = await self._load_profile_with_precedence(agent_name)
231
-
240
+
232
241
  if profile:
233
242
  # Load improved prompts
234
243
  profile.improved_prompts = await self._load_improved_prompts(agent_name)
235
-
244
+
236
245
  # Cache the profile
237
246
  self.profile_cache[agent_name] = profile
238
-
247
+
239
248
  # Update metrics
240
- self.load_metrics[f"{agent_name}_load_time"] = asyncio.get_event_loop().time() - start_time
241
-
249
+ self.load_metrics[f"{agent_name}_load_time"] = (
250
+ asyncio.get_event_loop().time() - start_time
251
+ )
252
+
242
253
  # Integrate with SharedPromptCache if available
243
254
  if self.shared_cache and profile.status == ProfileStatus.LOADED:
244
255
  cache_key = f"agent_profile_{agent_name}"
245
256
  await self.shared_cache.set_cached_result(cache_key, profile)
246
257
  profile.cache_key = cache_key
247
-
258
+
248
259
  return profile
249
-
250
- async def _load_profile_with_precedence(self, agent_name: str) -> Optional[AgentProfile]:
260
+
261
+ async def _load_profile_with_precedence(
262
+ self, agent_name: str
263
+ ) -> Optional[AgentProfile]:
251
264
  """Load profile following tier precedence: Project → User → System."""
252
265
  for tier in [ProfileTier.PROJECT, ProfileTier.USER, ProfileTier.SYSTEM]:
253
266
  if tier not in self.tier_paths:
254
267
  continue
255
-
268
+
256
269
  profile = await self._load_profile_from_tier(agent_name, tier)
257
270
  if profile and profile.status == ProfileStatus.LOADED:
258
271
  return profile
259
-
272
+
260
273
  return None
261
-
262
- async def _load_profile_from_tier(self, agent_name: str,
263
- tier: ProfileTier) -> Optional[AgentProfile]:
274
+
275
+ async def _load_profile_from_tier(
276
+ self, agent_name: str, tier: ProfileTier
277
+ ) -> Optional[AgentProfile]:
264
278
  """Load profile from specific tier."""
265
279
  tier_path = self.tier_paths[tier]
266
-
280
+
267
281
  # Try different file formats and naming conventions
268
282
  # Check .md files first (Claude Code format), then fall back to YAML/JSON
269
283
  possible_files = [
@@ -280,380 +294,396 @@ class AgentProfileLoader(BaseService):
280
294
  tier_path / f"{agent_name}-agent.yml",
281
295
  tier_path / f"{agent_name}-agent.json",
282
296
  ]
283
-
297
+
284
298
  for file_path in possible_files:
285
299
  if file_path.exists():
286
300
  return await self._parse_profile_file(file_path, tier)
287
-
301
+
288
302
  return None
289
-
290
- async def _parse_profile_file(self, file_path: Path,
291
- tier: ProfileTier) -> Optional[AgentProfile]:
303
+
304
+ async def _parse_profile_file(
305
+ self, file_path: Path, tier: ProfileTier
306
+ ) -> Optional[AgentProfile]:
292
307
  """Parse agent profile from file."""
293
308
  try:
294
309
  # Read file content
295
310
  content = file_path.read_text()
296
-
311
+
297
312
  # Parse based on file extension
298
- if file_path.suffix == '.md':
313
+ if file_path.suffix == ".md":
299
314
  # Parse markdown with YAML frontmatter
300
315
  data, instructions = self._parse_markdown_with_frontmatter(content)
301
- elif file_path.suffix in ['.yaml', '.yml']:
316
+ elif file_path.suffix in [".yaml", ".yml"]:
302
317
  data = yaml.safe_load(content)
303
- instructions = data.get('instructions', '')
304
- elif file_path.suffix == '.json':
318
+ instructions = data.get("instructions", "")
319
+ elif file_path.suffix == ".json":
305
320
  data = json.loads(content)
306
- instructions = data.get('instructions', '')
321
+ instructions = data.get("instructions", "")
307
322
  else:
308
323
  # Try to parse as YAML first, then JSON
309
324
  try:
310
325
  data = yaml.safe_load(content)
311
- instructions = data.get('instructions', '')
326
+ instructions = data.get("instructions", "")
312
327
  except:
313
328
  data = json.loads(content)
314
- instructions = data.get('instructions', '')
315
-
329
+ instructions = data.get("instructions", "")
330
+
316
331
  # Create profile
317
332
  profile = AgentProfile(
318
- name=data.get('name', file_path.stem),
319
- role=data.get('role', 'agent'),
320
- description=data.get('description', ''),
333
+ name=data.get("name", file_path.stem),
334
+ role=data.get("role", "agent"),
335
+ description=data.get("description", ""),
321
336
  tier=tier,
322
337
  source_path=str(file_path),
323
338
  instructions=instructions,
324
- capabilities=data.get('capabilities', []),
325
- constraints=data.get('constraints', []),
326
- metadata=data.get('metadata', {}),
327
- status=ProfileStatus.LOADED
339
+ capabilities=data.get("capabilities", []),
340
+ constraints=data.get("constraints", []),
341
+ metadata=data.get("metadata", {}),
342
+ status=ProfileStatus.LOADED,
328
343
  )
329
-
344
+
330
345
  return profile
331
-
346
+
332
347
  except Exception as e:
333
348
  logger.error(f"Error parsing profile {file_path}: {e}")
334
349
  return AgentProfile(
335
350
  name=file_path.stem,
336
- role='error',
337
- description='Failed to load profile',
351
+ role="error",
352
+ description="Failed to load profile",
338
353
  tier=tier,
339
354
  source_path=str(file_path),
340
355
  status=ProfileStatus.ERROR,
341
- error=str(e)
356
+ error=str(e),
342
357
  )
343
-
344
- def _parse_markdown_with_frontmatter(self, content: str) -> Tuple[Dict[str, Any], str]:
358
+
359
+ def _parse_markdown_with_frontmatter(
360
+ self, content: str
361
+ ) -> Tuple[Dict[str, Any], str]:
345
362
  """
346
363
  Parse markdown file with YAML frontmatter.
347
-
364
+
348
365
  Args:
349
366
  content: Markdown content with YAML frontmatter
350
-
367
+
351
368
  Returns:
352
369
  Tuple of (frontmatter_data, markdown_content)
353
370
  """
354
371
  import re
355
-
372
+
356
373
  # Check if content starts with YAML frontmatter
357
- if not content.strip().startswith('---'):
374
+ if not content.strip().startswith("---"):
358
375
  # No frontmatter, treat entire content as instructions
359
- return {'name': 'unknown', 'description': 'No frontmatter found'}, content
360
-
376
+ return {"name": "unknown", "description": "No frontmatter found"}, content
377
+
361
378
  # Split frontmatter and content
362
- parts = re.split(r'^---\s*$', content, 2, re.MULTILINE)
363
-
379
+ parts = re.split(r"^---\s*$", content, 2, re.MULTILINE)
380
+
364
381
  if len(parts) < 3:
365
382
  # Invalid frontmatter structure
366
- return {'name': 'unknown', 'description': 'Invalid frontmatter'}, content
367
-
383
+ return {"name": "unknown", "description": "Invalid frontmatter"}, content
384
+
368
385
  # Parse YAML frontmatter
369
386
  frontmatter_text = parts[1].strip()
370
387
  markdown_content = parts[2].strip()
371
-
388
+
372
389
  try:
373
390
  frontmatter_data = yaml.safe_load(frontmatter_text)
374
391
  if not isinstance(frontmatter_data, dict):
375
- frontmatter_data = {'name': 'unknown', 'description': 'Invalid frontmatter format'}
392
+ frontmatter_data = {
393
+ "name": "unknown",
394
+ "description": "Invalid frontmatter format",
395
+ }
376
396
  except Exception as e:
377
397
  logger.error(f"Error parsing YAML frontmatter: {e}")
378
- frontmatter_data = {'name': 'unknown', 'description': f'YAML parse error: {e}'}
379
-
398
+ frontmatter_data = {
399
+ "name": "unknown",
400
+ "description": f"YAML parse error: {e}",
401
+ }
402
+
380
403
  return frontmatter_data, markdown_content
381
-
404
+
382
405
  # ========================================================================
383
406
  # Profile Discovery
384
407
  # ========================================================================
385
-
408
+
386
409
  async def _discover_all_profiles(self) -> Dict[ProfileTier, List[str]]:
387
410
  """Discover all available agent profiles across tiers."""
388
411
  discovered = {}
389
-
412
+
390
413
  for tier, tier_path in self.tier_paths.items():
391
414
  if not tier_path.exists():
392
415
  continue
393
-
416
+
394
417
  agents = []
395
418
  # Check for .md files (Claude Code format) and YAML/JSON files
396
- file_patterns = ['*.md', '*.yaml', '*.yml', '*.json']
419
+ file_patterns = ["*.md", "*.yaml", "*.yml", "*.json"]
397
420
  for pattern in file_patterns:
398
421
  for file_path in tier_path.glob(pattern):
399
422
  agent_name = file_path.stem
400
423
  # Remove common suffixes
401
- if agent_name.endswith('_agent'):
424
+ if agent_name.endswith("_agent"):
402
425
  agent_name = agent_name[:-6]
403
- elif agent_name.endswith('-agent'):
426
+ elif agent_name.endswith("-agent"):
404
427
  agent_name = agent_name[:-6]
405
-
428
+
406
429
  if agent_name not in agents:
407
430
  agents.append(agent_name)
408
-
431
+
409
432
  discovered[tier] = agents
410
433
  logger.debug(f"Discovered {len(agents)} agents in {tier.value} tier")
411
-
434
+
412
435
  return discovered
413
-
414
- async def get_available_agents(self, tier: Optional[ProfileTier] = None) -> List[str]:
436
+
437
+ async def get_available_agents(
438
+ self, tier: Optional[ProfileTier] = None
439
+ ) -> List[str]:
415
440
  """Get list of available agents, optionally filtered by tier."""
416
441
  discovered = await self._discover_all_profiles()
417
-
442
+
418
443
  if tier:
419
444
  return discovered.get(tier, [])
420
-
445
+
421
446
  # Combine all tiers, removing duplicates
422
447
  all_agents = set()
423
448
  for agents in discovered.values():
424
449
  all_agents.update(agents)
425
-
450
+
426
451
  return sorted(list(all_agents))
427
-
452
+
428
453
  # ========================================================================
429
454
  # Improved Prompts Management
430
455
  # ========================================================================
431
-
456
+
432
457
  async def _load_improved_prompts(self, agent_name: str) -> List[ImprovedPrompt]:
433
458
  """Load improved prompts for an agent."""
434
459
  prompts = []
435
460
  prompt_file = self.improved_prompts_path / f"{agent_name}_prompts.json"
436
-
461
+
437
462
  if prompt_file.exists():
438
463
  try:
439
- with open(prompt_file, 'r') as f:
464
+ with open(prompt_file, "r") as f:
440
465
  data = json.load(f)
441
466
  for prompt_data in data:
442
467
  prompt = ImprovedPrompt(
443
- prompt_id=prompt_data['prompt_id'],
444
- agent_name=prompt_data['agent_name'],
445
- version=prompt_data['version'],
446
- content=prompt_data['content'],
447
- metrics=prompt_data.get('metrics', {}),
448
- metadata=prompt_data.get('metadata', {}),
449
- created_at=datetime.fromisoformat(prompt_data['created_at']),
450
- validated=prompt_data.get('validated', False)
468
+ prompt_id=prompt_data["prompt_id"],
469
+ agent_name=prompt_data["agent_name"],
470
+ version=prompt_data["version"],
471
+ content=prompt_data["content"],
472
+ metrics=prompt_data.get("metrics", {}),
473
+ metadata=prompt_data.get("metadata", {}),
474
+ created_at=datetime.fromisoformat(
475
+ prompt_data["created_at"]
476
+ ),
477
+ validated=prompt_data.get("validated", False),
451
478
  )
452
479
  prompts.append(prompt)
453
480
  except Exception as e:
454
481
  logger.error(f"Error loading improved prompts for {agent_name}: {e}")
455
-
482
+
456
483
  return prompts
457
-
458
- async def save_improved_prompt(self, agent_name: str,
459
- prompt: ImprovedPrompt) -> bool:
484
+
485
+ async def save_improved_prompt(
486
+ self, agent_name: str, prompt: ImprovedPrompt
487
+ ) -> bool:
460
488
  """Save an improved prompt for an agent."""
461
489
  try:
462
490
  # Load existing prompts
463
491
  prompts = await self._load_improved_prompts(agent_name)
464
-
492
+
465
493
  # Add or update prompt
466
494
  existing_idx = None
467
495
  for idx, existing in enumerate(prompts):
468
496
  if existing.prompt_id == prompt.prompt_id:
469
497
  existing_idx = idx
470
498
  break
471
-
499
+
472
500
  if existing_idx is not None:
473
501
  prompts[existing_idx] = prompt
474
502
  else:
475
503
  prompts.append(prompt)
476
-
504
+
477
505
  # Save to file
478
506
  prompt_file = self.improved_prompts_path / f"{agent_name}_prompts.json"
479
- with open(prompt_file, 'w') as f:
480
- json.dump([
481
- {
482
- 'prompt_id': p.prompt_id,
483
- 'agent_name': p.agent_name,
484
- 'version': p.version,
485
- 'content': p.content,
486
- 'metrics': p.metrics,
487
- 'metadata': p.metadata,
488
- 'created_at': p.created_at.isoformat(),
489
- 'validated': p.validated
490
- }
491
- for p in prompts
492
- ], f, indent=2)
493
-
507
+ with open(prompt_file, "w") as f:
508
+ json.dump(
509
+ [
510
+ {
511
+ "prompt_id": p.prompt_id,
512
+ "agent_name": p.agent_name,
513
+ "version": p.version,
514
+ "content": p.content,
515
+ "metrics": p.metrics,
516
+ "metadata": p.metadata,
517
+ "created_at": p.created_at.isoformat(),
518
+ "validated": p.validated,
519
+ }
520
+ for p in prompts
521
+ ],
522
+ f,
523
+ indent=2,
524
+ )
525
+
494
526
  return True
495
-
527
+
496
528
  except Exception as e:
497
529
  logger.error(f"Error saving improved prompt: {e}")
498
530
  return False
499
-
531
+
500
532
  async def _save_improved_prompts(self) -> None:
501
533
  """Save all pending improved prompts."""
502
534
  for agent_name, profile in self.profile_cache.items():
503
535
  if profile.improved_prompts:
504
536
  for prompt in profile.improved_prompts:
505
537
  await self.save_improved_prompt(agent_name, prompt)
506
-
538
+
507
539
  # ========================================================================
508
540
  # Task Integration
509
541
  # ========================================================================
510
-
511
- async def enhance_task_creation(self, agent_name: str,
512
- task_params: Dict[str, Any]) -> Dict[str, Any]:
542
+
543
+ async def enhance_task_creation(
544
+ self, agent_name: str, task_params: Dict[str, Any]
545
+ ) -> Dict[str, Any]:
513
546
  """
514
547
  Enhance Task Tool subprocess creation with agent profile data.
515
-
548
+
516
549
  Args:
517
550
  agent_name: Name of the agent
518
551
  task_params: Original task parameters
519
-
552
+
520
553
  Returns:
521
554
  Enhanced task parameters
522
555
  """
523
556
  profile = await self.load_agent_profile(agent_name)
524
-
557
+
525
558
  if not profile:
526
559
  logger.warning(f"No profile found for agent {agent_name}")
527
560
  return task_params
528
-
561
+
529
562
  # Enhance with profile data
530
563
  enhanced = task_params.copy()
531
-
564
+
532
565
  # Add agent metadata
533
- enhanced['agent_metadata'] = {
534
- 'name': profile.name,
535
- 'role': profile.role,
536
- 'tier': profile.tier.value,
537
- 'capabilities': profile.capabilities,
538
- 'constraints': profile.constraints
566
+ enhanced["agent_metadata"] = {
567
+ "name": profile.name,
568
+ "role": profile.role,
569
+ "tier": profile.tier.value,
570
+ "capabilities": profile.capabilities,
571
+ "constraints": profile.constraints,
539
572
  }
540
-
573
+
541
574
  # Add improved prompts if available
542
575
  if profile.improved_prompts:
543
576
  best_prompt = max(
544
- profile.improved_prompts,
545
- key=lambda p: p.metrics.get('success_rate', 0)
577
+ profile.improved_prompts, key=lambda p: p.metrics.get("success_rate", 0)
546
578
  )
547
- enhanced['improved_prompt'] = {
548
- 'content': best_prompt.content,
549
- 'version': best_prompt.version,
550
- 'metrics': best_prompt.metrics
579
+ enhanced["improved_prompt"] = {
580
+ "content": best_prompt.content,
581
+ "version": best_prompt.version,
582
+ "metrics": best_prompt.metrics,
551
583
  }
552
-
584
+
553
585
  # Add custom instructions if available
554
586
  if profile.instructions:
555
- enhanced['additional_instructions'] = profile.instructions
556
-
587
+ enhanced["additional_instructions"] = profile.instructions
588
+
557
589
  return enhanced
558
-
590
+
559
591
  # ========================================================================
560
592
  # Metrics and Validation
561
593
  # ========================================================================
562
-
594
+
563
595
  async def validate_profile(self, agent_name: str) -> Dict[str, Any]:
564
596
  """Validate agent profile structure and content."""
565
597
  profile = await self.load_agent_profile(agent_name)
566
-
598
+
567
599
  if not profile:
568
- return {'valid': False, 'error': 'Profile not found'}
569
-
570
- validation_results = {
571
- 'valid': True,
572
- 'warnings': [],
573
- 'errors': []
574
- }
575
-
600
+ return {"valid": False, "error": "Profile not found"}
601
+
602
+ validation_results = {"valid": True, "warnings": [], "errors": []}
603
+
576
604
  # Check required fields
577
605
  if not profile.name:
578
- validation_results['errors'].append('Missing agent name')
579
- validation_results['valid'] = False
580
-
606
+ validation_results["errors"].append("Missing agent name")
607
+ validation_results["valid"] = False
608
+
581
609
  if not profile.role:
582
- validation_results['errors'].append('Missing agent role')
583
- validation_results['valid'] = False
584
-
610
+ validation_results["errors"].append("Missing agent role")
611
+ validation_results["valid"] = False
612
+
585
613
  # Check profile completeness
586
614
  if not profile.description:
587
- validation_results['warnings'].append('Missing agent description')
588
-
615
+ validation_results["warnings"].append("Missing agent description")
616
+
589
617
  if not profile.capabilities:
590
- validation_results['warnings'].append('No capabilities defined')
591
-
618
+ validation_results["warnings"].append("No capabilities defined")
619
+
592
620
  if not profile.constraints:
593
- validation_results['warnings'].append('No constraints defined')
594
-
621
+ validation_results["warnings"].append("No constraints defined")
622
+
595
623
  # Validate improved prompts
596
624
  for prompt in profile.improved_prompts:
597
625
  if not prompt.validated:
598
- validation_results['warnings'].append(
599
- f'Unvalidated prompt: {prompt.prompt_id}'
626
+ validation_results["warnings"].append(
627
+ f"Unvalidated prompt: {prompt.prompt_id}"
600
628
  )
601
-
629
+
602
630
  return validation_results
603
-
631
+
604
632
  async def get_profile_metrics(self) -> Dict[str, Any]:
605
633
  """Get comprehensive profile loading metrics."""
606
634
  metrics = {
607
- 'cache_size': len(self.profile_cache),
608
- 'load_metrics': self.load_metrics,
609
- 'tier_stats': {}
635
+ "cache_size": len(self.profile_cache),
636
+ "load_metrics": self.load_metrics,
637
+ "tier_stats": {},
610
638
  }
611
-
639
+
612
640
  # Count profiles by tier
613
641
  for profile in self.profile_cache.values():
614
642
  tier = profile.tier.value
615
- metrics['tier_stats'][tier] = metrics['tier_stats'].get(tier, 0) + 1
616
-
643
+ metrics["tier_stats"][tier] = metrics["tier_stats"].get(tier, 0) + 1
644
+
617
645
  # Calculate average load times
618
646
  if self.load_metrics:
619
- load_times = [v for k, v in self.load_metrics.items() if k.endswith('_load_time')]
647
+ load_times = [
648
+ v for k, v in self.load_metrics.items() if k.endswith("_load_time")
649
+ ]
620
650
  if load_times:
621
- metrics['avg_load_time'] = sum(load_times) / len(load_times)
622
-
651
+ metrics["avg_load_time"] = sum(load_times) / len(load_times)
652
+
623
653
  # Count improved prompts
624
654
  total_prompts = sum(
625
655
  len(p.improved_prompts) for p in self.profile_cache.values()
626
656
  )
627
- metrics['total_improved_prompts'] = total_prompts
628
-
657
+ metrics["total_improved_prompts"] = total_prompts
658
+
629
659
  return metrics
630
-
660
+
631
661
  # ========================================================================
632
662
  # Utility Methods
633
663
  # ========================================================================
634
-
664
+
635
665
  def _detect_framework_path(self) -> Optional[Path]:
636
666
  """Detect the framework path for system-level agents."""
637
667
  possible_paths = [
638
- self.working_directory / 'framework',
639
- self.working_directory / 'src' / 'claude_mpm' / 'framework',
640
- Path(__file__).parent.parent / 'framework'
668
+ self.working_directory / "framework",
669
+ self.working_directory / "src" / "claude_mpm" / "framework",
670
+ Path(__file__).parent.parent / "framework",
641
671
  ]
642
-
672
+
643
673
  for path in possible_paths:
644
- if path.exists() and (path / 'agent-roles').exists():
674
+ if path.exists() and (path / "agent-roles").exists():
645
675
  return path
646
-
676
+
647
677
  return None
648
-
678
+
649
679
  def invalidate_cache(self, agent_name: Optional[str] = None) -> None:
650
680
  """Invalidate profile cache."""
651
681
  if agent_name:
652
682
  self.profile_cache.pop(agent_name, None)
653
683
  else:
654
684
  self.profile_cache.clear()
655
-
685
+
656
686
  async def reload_profile(self, agent_name: str) -> Optional[AgentProfile]:
657
687
  """Force reload of agent profile, bypassing cache."""
658
688
  self.invalidate_cache(agent_name)
659
- return await self.load_agent_profile(agent_name, use_cache=False)
689
+ return await self.load_agent_profile(agent_name, use_cache=False)