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
@@ -15,18 +15,18 @@ Key Features:
15
15
  - Dynamic prompt templates based on task complexity
16
16
 
17
17
  Usage:
18
- from claude_pm.agents.base_agent_loader import prepend_base_instructions
19
-
18
+ from claude_mpm.agents.base_agent_loader import prepend_base_instructions
19
+
20
20
  # Get agent prompt with base instructions prepended
21
- full_prompt = prepend_base_instructions(get_documentation_agent_prompt())
21
+ full_prompt = prepend_base_instructions(get_agent_prompt("documentation-agent"))
22
22
  """
23
23
 
24
24
  import json
25
25
  import logging
26
26
  import os
27
- from pathlib import Path
28
- from typing import Optional, Dict, Any
29
27
  from enum import Enum
28
+ from pathlib import Path
29
+ from typing import Any, Dict, Optional
30
30
 
31
31
  from claude_mpm.services.memory.cache.shared_prompt_cache import SharedPromptCache
32
32
 
@@ -36,14 +36,16 @@ logger = logging.getLogger(__name__)
36
36
  # Cache key for base agent instructions
37
37
  BASE_AGENT_CACHE_KEY = "base_agent:instructions"
38
38
 
39
+
39
40
  def _get_base_agent_file() -> Path:
40
41
  """Get the base agent file path."""
41
42
  # Check if we're running from a wheel installation
42
43
  try:
43
44
  import claude_mpm
45
+
44
46
  package_path = Path(claude_mpm.__file__).parent
45
47
  path_str = str(package_path.resolve())
46
- if 'site-packages' in path_str or 'dist-packages' in path_str:
48
+ if "site-packages" in path_str or "dist-packages" in path_str:
47
49
  # For wheel installations, check data directory
48
50
  data_base_agent = package_path / "data" / "agents" / "base_agent.json"
49
51
  if data_base_agent.exists():
@@ -51,13 +53,13 @@ def _get_base_agent_file() -> Path:
51
53
  return data_base_agent
52
54
  except Exception:
53
55
  pass
54
-
56
+
55
57
  # Use the base_agent.json in the agents directory
56
58
  base_agent_path = Path(__file__).parent / "base_agent.json"
57
59
  if base_agent_path.exists():
58
60
  logger.debug(f"Using base agent template: {base_agent_path}")
59
61
  return base_agent_path
60
-
62
+
61
63
  # Fallback error
62
64
  logger.error("Base agent template file not found")
63
65
  raise FileNotFoundError("base_agent.json not found in agents directory")
@@ -69,9 +71,10 @@ BASE_AGENT_FILE = _get_base_agent_file()
69
71
 
70
72
  class PromptTemplate(Enum):
71
73
  """Dynamic prompt template levels."""
72
- MINIMAL = "MINIMAL" # Core instructions only (~300 chars)
74
+
75
+ MINIMAL = "MINIMAL" # Core instructions only (~300 chars)
73
76
  STANDARD = "STANDARD" # Core + context + basic integration (~700 chars)
74
- FULL = "FULL" # All sections including escalation (~1500 chars)
77
+ FULL = "FULL" # All sections including escalation (~1500 chars)
75
78
 
76
79
 
77
80
  # Template section definitions
@@ -79,72 +82,60 @@ class PromptTemplate(Enum):
79
82
  TEMPLATE_SECTIONS = {
80
83
  "core_principles": {
81
84
  "templates": ["MINIMAL", "STANDARD", "FULL"],
82
- "content": "Core Agent Principles"
85
+ "content": "Core Agent Principles",
83
86
  },
84
87
  "communication_standards": {
85
88
  "templates": ["MINIMAL", "STANDARD", "FULL"],
86
- "content": "Communication Standards"
89
+ "content": "Communication Standards",
87
90
  },
88
91
  "test_protocols": {
89
92
  "templates": ["FULL"], # Moved to FULL only - not needed for most tasks
90
- "content": "Test Response Protocol"
93
+ "content": "Test Response Protocol",
91
94
  },
92
95
  "reporting_requirements": {
93
96
  "templates": ["STANDARD", "FULL"],
94
- "content": "Reporting Requirements"
95
- },
96
- "error_handling": {
97
- "templates": ["STANDARD", "FULL"],
98
- "content": "Error Handling"
99
- },
100
- "security_awareness": {
101
- "templates": ["FULL"],
102
- "content": "Security Awareness"
97
+ "content": "Reporting Requirements",
103
98
  },
99
+ "error_handling": {"templates": ["STANDARD", "FULL"], "content": "Error Handling"},
100
+ "security_awareness": {"templates": ["FULL"], "content": "Security Awareness"},
104
101
  "temporal_context": {
105
102
  "templates": ["FULL"], # Moved to FULL - not essential for STANDARD
106
- "content": "Temporal Context Integration"
107
- },
108
- "quality_standards": {
109
- "templates": ["FULL"],
110
- "content": "Quality Standards"
103
+ "content": "Temporal Context Integration",
111
104
  },
105
+ "quality_standards": {"templates": ["FULL"], "content": "Quality Standards"},
112
106
  "tool_usage": {
113
107
  "templates": ["FULL"], # Moved to FULL - agent-specific guidance suffices
114
- "content": "Tool Usage Guidelines"
108
+ "content": "Tool Usage Guidelines",
115
109
  },
116
110
  "collaboration_protocols": {
117
111
  "templates": ["STANDARD", "FULL"], # Keep for STANDARD - essential
118
- "content": "Collaboration Protocols"
112
+ "content": "Collaboration Protocols",
119
113
  },
120
114
  "cross_agent_dependencies": {
121
115
  "templates": ["FULL"], # Only needed for complex multi-agent tasks
122
- "content": "Cross-Agent Dependencies"
116
+ "content": "Cross-Agent Dependencies",
123
117
  },
124
118
  "performance_optimization": {
125
119
  "templates": ["FULL"],
126
- "content": "Performance Optimization"
127
- },
128
- "escalation_triggers": {
129
- "templates": ["FULL"],
130
- "content": "Escalation Triggers"
120
+ "content": "Performance Optimization",
131
121
  },
122
+ "escalation_triggers": {"templates": ["FULL"], "content": "Escalation Triggers"},
132
123
  "output_formatting": {
133
124
  "templates": ["FULL"], # Moved to FULL - basic formatting in STANDARD suffices
134
- "content": "Output Formatting Standards"
125
+ "content": "Output Formatting Standards",
135
126
  },
136
127
  "framework_integration": {
137
128
  "templates": ["FULL"],
138
- "content": "Framework Integration"
129
+ "content": "Framework Integration",
139
130
  },
140
131
  "constraints": {
141
132
  "templates": ["MINIMAL", "STANDARD", "FULL"],
142
- "content": "Universal Constraints"
133
+ "content": "Universal Constraints",
143
134
  },
144
135
  "success_criteria": {
145
136
  "templates": ["FULL"], # Moved to FULL - implicit for simpler tasks
146
- "content": "Success Criteria"
147
- }
137
+ "content": "Success Criteria",
138
+ },
148
139
  }
149
140
 
150
141
 
@@ -152,68 +143,81 @@ def load_base_agent_instructions(force_reload: bool = False) -> Optional[str]:
152
143
  """
153
144
  Load base agent instructions from base_agent.json with caching.
154
145
  Conditionally includes test-mode instructions based on CLAUDE_PM_TEST_MODE.
155
-
146
+
156
147
  Args:
157
148
  force_reload: Force reload from file, bypassing cache
158
-
149
+
159
150
  Returns:
160
151
  str: Base agent instructions content, or None if file not found
161
152
  """
162
153
  try:
163
154
  # Check if we're in test mode
164
- test_mode = os.environ.get('CLAUDE_PM_TEST_MODE', '').lower() in ['true', '1', 'yes']
165
-
155
+ test_mode = os.environ.get("CLAUDE_PM_TEST_MODE", "").lower() in [
156
+ "true",
157
+ "1",
158
+ "yes",
159
+ ]
160
+
166
161
  # Get cache instance
167
162
  cache = SharedPromptCache.get_instance()
168
-
163
+
169
164
  # Different cache keys for test mode vs normal mode
170
165
  cache_key = f"{BASE_AGENT_CACHE_KEY}:{'test' if test_mode else 'normal'}"
171
-
166
+
172
167
  # Check cache first (unless force reload)
173
168
  if not force_reload:
174
169
  cached_content = cache.get(cache_key)
175
170
  if cached_content is not None:
176
- logger.debug(f"Base agent instructions loaded from cache (test_mode={test_mode})")
171
+ logger.debug(
172
+ f"Base agent instructions loaded from cache (test_mode={test_mode})"
173
+ )
177
174
  return str(cached_content)
178
-
175
+
179
176
  # Get fresh base agent file path
180
177
  base_agent_file = _get_base_agent_file()
181
-
178
+
182
179
  # Load from file
183
180
  if not base_agent_file.exists():
184
181
  logger.warning(f"Base agent instructions file not found: {base_agent_file}")
185
182
  return None
186
-
183
+
187
184
  logger.debug(f"Loading base agent instructions from: {base_agent_file}")
188
-
185
+
189
186
  # Load JSON and extract instructions
190
- with open(base_agent_file, 'r', encoding='utf-8') as f:
187
+ with open(base_agent_file, "r", encoding="utf-8") as f:
191
188
  base_agent_data = json.load(f)
192
-
189
+
193
190
  # Extract instructions from the JSON structure
194
- if 'narrative_fields' in base_agent_data and 'instructions' in base_agent_data['narrative_fields']:
195
- content = base_agent_data['narrative_fields']['instructions']
191
+ if (
192
+ "narrative_fields" in base_agent_data
193
+ and "instructions" in base_agent_data["narrative_fields"]
194
+ ):
195
+ content = base_agent_data["narrative_fields"]["instructions"]
196
196
  else:
197
197
  # Fallback for older format
198
- content = base_agent_data.get('instructions', '')
199
-
198
+ content = base_agent_data.get("instructions", "")
199
+
200
200
  if not content:
201
201
  logger.error("No instructions found in base agent JSON")
202
202
  return None
203
-
203
+
204
204
  # If NOT in test mode, remove test-specific instructions to save context
205
205
  if not test_mode:
206
206
  content = _remove_test_mode_instructions(content)
207
207
  logger.debug("Test-mode instructions removed (not in test mode)")
208
208
  else:
209
- logger.info("Test-mode instructions included (CLAUDE_PM_TEST_MODE is enabled)")
210
-
209
+ logger.info(
210
+ "Test-mode instructions included (CLAUDE_PM_TEST_MODE is enabled)"
211
+ )
212
+
211
213
  # Cache the content with 1 hour TTL
212
214
  cache.set(cache_key, content, ttl=3600)
213
- logger.debug(f"Base agent instructions cached successfully (test_mode={test_mode})")
214
-
215
+ logger.debug(
216
+ f"Base agent instructions cached successfully (test_mode={test_mode})"
217
+ )
218
+
215
219
  return content
216
-
220
+
217
221
  except Exception as e:
218
222
  logger.error(f"Error loading base agent instructions: {e}")
219
223
  return None
@@ -222,36 +226,39 @@ def load_base_agent_instructions(force_reload: bool = False) -> Optional[str]:
222
226
  def _remove_test_mode_instructions(content: str) -> str:
223
227
  """
224
228
  Remove test-mode specific instructions from base agent content.
225
-
229
+
226
230
  This removes the "Standard Test Response Protocol"
227
231
  sections to save context when not in test mode.
228
-
232
+
229
233
  Args:
230
234
  content: Full base agent instructions content
231
-
235
+
232
236
  Returns:
233
237
  str: Content with test-mode instructions removed
234
238
  """
235
- lines = content.split('\n')
239
+ lines = content.split("\n")
236
240
  filtered_lines = []
237
241
  skip_section = False
238
-
242
+
239
243
  i = 0
240
244
  while i < len(lines):
241
245
  line = lines[i]
242
-
246
+
243
247
  # Check if we're entering the test response protocol section
244
- if line.strip() == '## Standard Test Response Protocol':
248
+ if line.strip() == "## Standard Test Response Protocol":
245
249
  skip_section = True
246
250
  i += 1
247
251
  continue
248
-
252
+
249
253
  # Check if we're in the test section and need to continue skipping
250
254
  if skip_section:
251
255
  # Check if we've reached a section that's NOT part of test protocol
252
256
  # This includes any heading that's not a subsection of the test protocol
253
- if (line.startswith('####') or line.startswith('###') or line.startswith('##')) and \
254
- 'Standard Test Response Protocol' not in line:
257
+ if (
258
+ line.startswith("####")
259
+ or line.startswith("###")
260
+ or line.startswith("##")
261
+ ) and "Standard Test Response Protocol" not in line:
255
262
  skip_section = False
256
263
  # Don't skip this line - it's the start of a new section
257
264
  filtered_lines.append(line)
@@ -260,45 +267,47 @@ def _remove_test_mode_instructions(content: str) -> str:
260
267
  # Skip this line as we're still in test section
261
268
  i += 1
262
269
  continue
263
-
270
+
264
271
  # Not in test section, keep the line
265
272
  filtered_lines.append(line)
266
273
  i += 1
267
-
274
+
268
275
  # Join back and clean up extra blank lines
269
- result = '\n'.join(filtered_lines)
270
-
276
+ result = "\n".join(filtered_lines)
277
+
271
278
  # Replace multiple consecutive newlines with double newlines
272
- while '\n\n\n' in result:
273
- result = result.replace('\n\n\n', '\n\n')
274
-
279
+ while "\n\n\n" in result:
280
+ result = result.replace("\n\n\n", "\n\n")
281
+
275
282
  return result.strip()
276
283
 
277
284
 
278
285
  def _build_dynamic_prompt(content: str, template: PromptTemplate) -> str:
279
286
  """
280
287
  Build a dynamic prompt based on the template level.
281
-
288
+
282
289
  Args:
283
290
  content: Full base agent content
284
291
  template: Template level to use
285
-
292
+
286
293
  Returns:
287
294
  str: Filtered content based on template
288
295
  """
289
296
  if template == PromptTemplate.FULL:
290
297
  # Return full content for FULL template
291
298
  return content
292
-
299
+
293
300
  # Parse content into sections
294
301
  sections = _parse_content_sections(content)
295
-
302
+
296
303
  # Build prompt based on template sections
297
304
  filtered_lines = []
298
305
  filtered_lines.append("# Base Agent Instructions\n")
299
306
  filtered_lines.append("## 🤖 Agent Framework Context\n")
300
- filtered_lines.append("You are operating as a specialized agent within the Claude PM Framework. You have been delegated a specific task by the PM Orchestrator and must complete it according to your specialized role and authority.\n")
301
-
307
+ filtered_lines.append(
308
+ "You are operating as a specialized agent within the Claude PM Framework. You have been delegated a specific task by the PM Orchestrator and must complete it according to your specialized role and authority.\n"
309
+ )
310
+
302
311
  # Add sections based on template
303
312
  template_name = template.value
304
313
  for section_key, section_config in TEMPLATE_SECTIONS.items():
@@ -307,101 +316,111 @@ def _build_dynamic_prompt(content: str, template: PromptTemplate) -> str:
307
316
  assert isinstance(section_name, str), "Section name must be string"
308
317
  if section_name in sections:
309
318
  filtered_lines.append(sections[section_name])
310
-
319
+
311
320
  # Clean up multiple newlines
312
- result = '\n'.join(filtered_lines)
313
- while '\n\n\n' in result:
314
- result = result.replace('\n\n\n', '\n\n')
315
-
321
+ result = "\n".join(filtered_lines)
322
+ while "\n\n\n" in result:
323
+ result = result.replace("\n\n\n", "\n\n")
324
+
316
325
  return result.strip()
317
326
 
318
327
 
319
328
  def _parse_content_sections(content: str) -> Dict[str, str]:
320
329
  """
321
330
  Parse content into named sections.
322
-
331
+
323
332
  Args:
324
333
  content: Full content to parse
325
-
334
+
326
335
  Returns:
327
336
  Dict mapping section names to their content
328
337
  """
329
338
  sections = {}
330
339
  current_section = None
331
340
  current_content = []
332
-
333
- lines = content.split('\n')
334
-
341
+
342
+ lines = content.split("\n")
343
+
335
344
  for line in lines:
336
345
  # Check if this is a section header
337
- if line.startswith('### '):
346
+ if line.startswith("### "):
338
347
  # Save previous section if exists
339
348
  if current_section:
340
- sections[current_section] = '\n'.join(current_content)
349
+ sections[current_section] = "\n".join(current_content)
341
350
  current_content = []
342
-
351
+
343
352
  # Extract section name
344
353
  current_section = line[4:].strip()
345
354
  current_content.append(line)
346
-
347
- elif line.startswith('## ') and 'Agent Framework Context' not in line:
355
+
356
+ elif line.startswith("## ") and "Agent Framework Context" not in line:
348
357
  # Handle ## level sections (skip the main header)
349
358
  if current_section:
350
- sections[current_section] = '\n'.join(current_content)
359
+ sections[current_section] = "\n".join(current_content)
351
360
  current_content = []
352
-
361
+
353
362
  current_section = line[3:].strip()
354
363
  current_content.append(line)
355
-
356
- elif line.startswith('#### '):
364
+
365
+ elif line.startswith("#### "):
357
366
  # Handle #### level subsections
358
367
  if current_section:
359
368
  # Check for PM Orchestrator Integration vs PM Workflow Integration
360
369
  subsection_name = line[5:].strip()
361
- if subsection_name in ["PM Orchestrator Integration", "PM Workflow Integration"]:
370
+ if subsection_name in [
371
+ "PM Orchestrator Integration",
372
+ "PM Workflow Integration",
373
+ ]:
362
374
  # Merge these redundant sections under "Collaboration Protocols"
363
375
  if current_section != "Collaboration Protocols":
364
376
  current_section = "PM Integration"
365
377
  current_content.append(line)
366
-
378
+
367
379
  elif current_section:
368
380
  current_content.append(line)
369
-
381
+
370
382
  # Save final section
371
383
  if current_section and current_content:
372
- sections[current_section] = '\n'.join(current_content)
373
-
384
+ sections[current_section] = "\n".join(current_content)
385
+
374
386
  # Merge redundant PM sections if both exist
375
- if "PM Orchestrator Integration" in sections and "PM Workflow Integration" in sections:
387
+ if (
388
+ "PM Orchestrator Integration" in sections
389
+ and "PM Workflow Integration" in sections
390
+ ):
376
391
  # Combine into single PM Integration section
377
392
  sections["PM Integration"] = (
378
- "#### PM Integration\n" +
379
- sections["PM Orchestrator Integration"].replace("#### PM Orchestrator Integration", "").strip() +
380
- "\n\n" +
381
- sections["PM Workflow Integration"].replace("#### PM Workflow Integration", "").strip()
393
+ "#### PM Integration\n"
394
+ + sections["PM Orchestrator Integration"]
395
+ .replace("#### PM Orchestrator Integration", "")
396
+ .strip()
397
+ + "\n\n"
398
+ + sections["PM Workflow Integration"]
399
+ .replace("#### PM Workflow Integration", "")
400
+ .strip()
382
401
  )
383
402
  # Remove redundant sections
384
403
  del sections["PM Orchestrator Integration"]
385
404
  del sections["PM Workflow Integration"]
386
-
405
+
387
406
  return sections
388
407
 
389
408
 
390
409
  def prepend_base_instructions(
391
- agent_prompt: str,
410
+ agent_prompt: str,
392
411
  separator: str = "\n\n---\n\n",
393
412
  template: Optional[PromptTemplate] = None,
394
- complexity_score: Optional[int] = None
413
+ complexity_score: Optional[int] = None,
395
414
  ) -> str:
396
415
  """
397
416
  Prepend base agent instructions to an agent-specific prompt.
398
-
417
+
399
418
  Args:
400
419
  agent_prompt: The agent-specific prompt to prepend to
401
420
  separator: String to separate base instructions from agent prompt
402
421
  template: Optional template level to use (auto-selected if not provided)
403
422
  complexity_score: Optional complexity score for template selection
404
-
423
+
405
424
  Returns:
406
425
  str: Combined prompt with base instructions prepended
407
426
  """
@@ -417,49 +436,59 @@ def prepend_base_instructions(
417
436
  else:
418
437
  # Default to STANDARD if no complexity info
419
438
  template = PromptTemplate.STANDARD
420
-
439
+
421
440
  # Check if we're in test mode - always use FULL template for tests
422
- test_mode = os.environ.get('CLAUDE_PM_TEST_MODE', '').lower() in ['true', '1', 'yes']
441
+ test_mode = os.environ.get("CLAUDE_PM_TEST_MODE", "").lower() in [
442
+ "true",
443
+ "1",
444
+ "yes",
445
+ ]
423
446
  if test_mode:
424
447
  template = PromptTemplate.FULL
425
-
448
+
426
449
  # Get cache instance
427
450
  cache = SharedPromptCache.get_instance()
428
-
451
+
429
452
  # Different cache keys for different templates and test mode
430
- cache_key = f"{BASE_AGENT_CACHE_KEY}:{template.value}:{'test' if test_mode else 'normal'}"
431
-
453
+ cache_key = (
454
+ f"{BASE_AGENT_CACHE_KEY}:{template.value}:{'test' if test_mode else 'normal'}"
455
+ )
456
+
432
457
  # Check cache first
433
458
  cached_content = cache.get(cache_key)
434
459
  if cached_content is not None:
435
- logger.debug(f"Base agent instructions loaded from cache (template={template.value}, test_mode={test_mode})")
460
+ logger.debug(
461
+ f"Base agent instructions loaded from cache (template={template.value}, test_mode={test_mode})"
462
+ )
436
463
  base_instructions = cached_content
437
464
  else:
438
465
  # Load full content
439
466
  full_content = load_base_agent_instructions()
440
-
467
+
441
468
  # If no base instructions, return original prompt
442
469
  if not full_content:
443
470
  logger.warning("No base instructions available, returning original prompt")
444
471
  return agent_prompt
445
-
472
+
446
473
  # Build dynamic prompt based on template
447
474
  base_instructions = _build_dynamic_prompt(full_content, template)
448
-
475
+
449
476
  # Cache the filtered content
450
477
  cache.set(cache_key, base_instructions, ttl=3600)
451
- logger.debug(f"Dynamic base agent instructions cached (template={template.value})")
452
-
478
+ logger.debug(
479
+ f"Dynamic base agent instructions cached (template={template.value})"
480
+ )
481
+
453
482
  # Log template selection
454
483
  if complexity_score is not None:
455
484
  logger.info(
456
485
  f"Using {template.value} prompt template "
457
486
  f"(complexity_score={complexity_score}, size={len(base_instructions)} chars)"
458
487
  )
459
-
488
+
460
489
  # Combine base instructions with agent prompt
461
490
  combined_prompt = f"{base_instructions}{separator}{agent_prompt}"
462
-
491
+
463
492
  return combined_prompt
464
493
 
465
494
 
@@ -469,14 +498,14 @@ def clear_base_agent_cache() -> None:
469
498
  cache = SharedPromptCache.get_instance()
470
499
  # Clear caches for all template levels and modes
471
500
  for template in PromptTemplate:
472
- for mode in ['normal', 'test']:
501
+ for mode in ["normal", "test"]:
473
502
  cache_key = f"{BASE_AGENT_CACHE_KEY}:{template.value}:{mode}"
474
503
  cache.invalidate(cache_key)
475
-
504
+
476
505
  # Also clear the old-style caches for backward compatibility
477
506
  cache.invalidate(f"{BASE_AGENT_CACHE_KEY}:normal")
478
507
  cache.invalidate(f"{BASE_AGENT_CACHE_KEY}:test")
479
-
508
+
480
509
  logger.debug("Base agent cache cleared (all templates and modes)")
481
510
  except Exception as e:
482
511
  logger.error(f"Error clearing base agent cache: {e}")
@@ -490,7 +519,7 @@ def get_base_agent_path() -> Path:
490
519
  def validate_base_agent_file() -> bool:
491
520
  """
492
521
  Validate that base agent file exists and is readable.
493
-
522
+
494
523
  Returns:
495
524
  bool: True if file exists and is readable, False otherwise
496
525
  """
@@ -498,15 +527,15 @@ def validate_base_agent_file() -> bool:
498
527
  if not BASE_AGENT_FILE.exists():
499
528
  logger.error(f"Base agent file does not exist: {BASE_AGENT_FILE}")
500
529
  return False
501
-
530
+
502
531
  if not BASE_AGENT_FILE.is_file():
503
532
  logger.error(f"Base agent path is not a file: {BASE_AGENT_FILE}")
504
533
  return False
505
-
534
+
506
535
  # Try to read the file
507
- BASE_AGENT_FILE.read_text(encoding='utf-8')
536
+ BASE_AGENT_FILE.read_text(encoding="utf-8")
508
537
  return True
509
-
538
+
510
539
  except Exception as e:
511
540
  logger.error(f"Base agent file validation failed: {e}")
512
541
  return False
@@ -516,14 +545,13 @@ def validate_base_agent_file() -> bool:
516
545
  if not validate_base_agent_file():
517
546
  logger.warning("Base agent file validation failed during module import")
518
547
 
519
-
520
548
  # Export key components
521
549
  __all__ = [
522
- 'prepend_base_instructions',
523
- 'load_base_agent_instructions',
524
- 'clear_base_agent_cache',
525
- 'get_base_agent_path',
526
- 'validate_base_agent_file',
527
- 'PromptTemplate',
528
- 'TEMPLATE_SECTIONS'
529
- ]
550
+ "prepend_base_instructions",
551
+ "load_base_agent_instructions",
552
+ "clear_base_agent_cache",
553
+ "get_base_agent_path",
554
+ "validate_base_agent_file",
555
+ "PromptTemplate",
556
+ "TEMPLATE_SECTIONS",
557
+ ]