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
@@ -1,92 +1,95 @@
1
1
  """Tool call interceptor for claude-mpm hook system."""
2
2
 
3
3
  import asyncio
4
- import json
5
- from typing import Dict, Any, Optional, List
6
- from datetime import datetime
7
4
  from collections import defaultdict
5
+ from datetime import datetime
6
+ from typing import Any, Dict, List, Optional
8
7
 
9
- from claude_mpm.hooks.base_hook import BaseHook, HookContext, HookType, HookResult
10
8
  from claude_mpm.core.logger import get_logger
9
+ from claude_mpm.hooks.base_hook import BaseHook, HookContext, HookResult, HookType
11
10
 
12
11
  logger = get_logger(__name__)
13
12
 
14
13
 
15
14
  class SimpleHookRunner:
16
15
  """Simple hook runner for direct hook execution."""
17
-
16
+
18
17
  def __init__(self):
19
18
  """Initialize the simple hook runner."""
20
19
  self._hooks: Dict[HookType, List[BaseHook]] = defaultdict(list)
21
20
  self._hook_instances: Dict[str, BaseHook] = {}
22
-
21
+
23
22
  def register_hook(self, hook: BaseHook, hook_type: Optional[HookType] = None):
24
23
  """Register a hook instance."""
25
24
  if hook_type is None:
26
25
  hook_type = HookType.CUSTOM
27
-
26
+
28
27
  if hook.name in self._hook_instances:
29
28
  # Remove old instance
30
29
  for hook_list in self._hooks.values():
31
30
  if self._hook_instances[hook.name] in hook_list:
32
31
  hook_list.remove(self._hook_instances[hook.name])
33
-
32
+
34
33
  self._hooks[hook_type].append(hook)
35
34
  self._hook_instances[hook.name] = hook
36
35
  self._hooks[hook_type].sort() # Sort by priority
37
-
36
+
38
37
  async def run_hooks(self, context: HookContext) -> List[Dict[str, Any]]:
39
38
  """Run all hooks for the given context."""
40
39
  hooks = [h for h in self._hooks[context.hook_type] if h.enabled]
41
40
  results = []
42
-
41
+
43
42
  for hook in hooks:
44
43
  try:
45
44
  if hook.validate(context):
46
45
  result = hook.execute(context)
47
- results.append({
48
- 'hook_name': hook.name,
49
- 'success': result.success,
50
- 'data': result.data,
51
- 'error': result.error,
52
- 'modified': result.modified,
53
- 'metadata': result.metadata
54
- })
55
-
46
+ results.append(
47
+ {
48
+ "hook_name": hook.name,
49
+ "success": result.success,
50
+ "data": result.data,
51
+ "error": result.error,
52
+ "modified": result.modified,
53
+ "metadata": result.metadata,
54
+ }
55
+ )
56
+
56
57
  # Update context if modified
57
58
  if result.modified and result.data:
58
59
  context.data.update(result.data)
59
60
  except Exception as e:
60
61
  logger.error(f"Hook '{hook.name}' execution failed: {e}")
61
- results.append({
62
- 'hook_name': hook.name,
63
- 'success': False,
64
- 'error': str(e)
65
- })
66
-
62
+ results.append(
63
+ {"hook_name": hook.name, "success": False, "error": str(e)}
64
+ )
65
+
67
66
  return results
68
67
 
69
68
 
70
69
  class ToolCallInterceptor:
71
70
  """Intercepts and processes tool calls through the hook system."""
72
-
71
+
73
72
  def __init__(self, hook_runner: Optional[SimpleHookRunner] = None):
74
73
  """Initialize the tool call interceptor.
75
-
74
+
76
75
  Args:
77
76
  hook_runner: Optional hook runner instance. If not provided, creates a new one.
78
77
  """
79
78
  self.hook_runner = hook_runner or SimpleHookRunner()
80
-
81
- async def intercept_tool_call(self, tool_name: str, parameters: Dict[str, Any],
82
- metadata: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
79
+
80
+ async def intercept_tool_call(
81
+ self,
82
+ tool_name: str,
83
+ parameters: Dict[str, Any],
84
+ metadata: Optional[Dict[str, Any]] = None,
85
+ ) -> Dict[str, Any]:
83
86
  """Intercept a tool call and run it through the hook system.
84
-
87
+
85
88
  Args:
86
89
  tool_name: Name of the tool being called
87
90
  parameters: Parameters being passed to the tool
88
91
  metadata: Optional metadata for the tool call
89
-
92
+
90
93
  Returns:
91
94
  Dict containing:
92
95
  - allowed: Whether the tool call should proceed
@@ -98,45 +101,51 @@ class ToolCallInterceptor:
98
101
  context = HookContext(
99
102
  hook_type=HookType.CUSTOM,
100
103
  data={
101
- 'tool_name': tool_name,
102
- 'parameters': parameters.copy() # Copy to avoid modifying original
104
+ "tool_name": tool_name,
105
+ "parameters": parameters.copy(), # Copy to avoid modifying original
103
106
  },
104
107
  metadata=metadata or {},
105
- timestamp=datetime.now()
108
+ timestamp=datetime.now(),
106
109
  )
107
-
110
+
108
111
  # Run hooks
109
112
  results = await self.hook_runner.run_hooks(context)
110
-
113
+
111
114
  # Process results
112
115
  allowed = True
113
116
  modified_params = parameters
114
117
  errors = []
115
118
  hook_metadata = {}
116
-
119
+
117
120
  for result in results:
118
- if not result.get('success', True):
121
+ if not result.get("success", True):
119
122
  allowed = False
120
- if result.get('error'):
121
- errors.append(f"[{result.get('hook_name', 'Unknown')}] {result.get('error')}")
122
-
123
- if result.get('modified') and result.get('data'):
123
+ if result.get("error"):
124
+ errors.append(
125
+ f"[{result.get('hook_name', 'Unknown')}] {result.get('error')}"
126
+ )
127
+
128
+ if result.get("modified") and result.get("data"):
124
129
  # Update parameters if modified
125
- if 'parameters' in result.get('data', {}):
126
- modified_params = result['data']['parameters']
127
-
128
- if result.get('metadata'):
129
- hook_metadata.update(result['metadata'])
130
-
130
+ if "parameters" in result.get("data", {}):
131
+ modified_params = result["data"]["parameters"]
132
+
133
+ if result.get("metadata"):
134
+ hook_metadata.update(result["metadata"])
135
+
131
136
  return {
132
- 'allowed': allowed,
133
- 'parameters': modified_params,
134
- 'error': '\n'.join(errors) if errors else None,
135
- 'metadata': hook_metadata
137
+ "allowed": allowed,
138
+ "parameters": modified_params,
139
+ "error": "\n".join(errors) if errors else None,
140
+ "metadata": hook_metadata,
136
141
  }
137
-
138
- def intercept_tool_call_sync(self, tool_name: str, parameters: Dict[str, Any],
139
- metadata: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
142
+
143
+ def intercept_tool_call_sync(
144
+ self,
145
+ tool_name: str,
146
+ parameters: Dict[str, Any],
147
+ metadata: Optional[Dict[str, Any]] = None,
148
+ ) -> Dict[str, Any]:
140
149
  """Synchronous version of intercept_tool_call."""
141
150
  loop = asyncio.new_event_loop()
142
151
  asyncio.set_event_loop(loop)
@@ -150,55 +159,59 @@ class ToolCallInterceptor:
150
159
 
151
160
  class ToolCallHookIntegration:
152
161
  """Integration helper for adding tool call interception to existing systems."""
153
-
162
+
154
163
  @staticmethod
155
164
  def wrap_tool_executor(original_executor, interceptor: ToolCallInterceptor):
156
165
  """Wrap an existing tool executor with hook interception.
157
-
166
+
158
167
  Args:
159
168
  original_executor: The original tool execution function
160
169
  interceptor: The tool call interceptor instance
161
-
170
+
162
171
  Returns:
163
172
  Wrapped executor function
164
173
  """
165
- async def wrapped_executor(tool_name: str, parameters: Dict[str, Any], **kwargs):
174
+
175
+ async def wrapped_executor(
176
+ tool_name: str, parameters: Dict[str, Any], **kwargs
177
+ ):
166
178
  # Intercept the tool call
167
179
  interception_result = await interceptor.intercept_tool_call(
168
- tool_name, parameters, kwargs.get('metadata')
180
+ tool_name, parameters, kwargs.get("metadata")
169
181
  )
170
-
182
+
171
183
  # Check if allowed
172
- if not interception_result['allowed']:
184
+ if not interception_result["allowed"]:
173
185
  raise ValueError(f"Tool call blocked: {interception_result['error']}")
174
-
186
+
175
187
  # Execute with potentially modified parameters
176
188
  return await original_executor(
177
- tool_name,
178
- interception_result['parameters'],
179
- **kwargs
189
+ tool_name, interception_result["parameters"], **kwargs
180
190
  )
181
-
191
+
182
192
  return wrapped_executor
183
-
193
+
184
194
  @staticmethod
185
- def create_tool_call_validator(valid_tools: List[str], interceptor: ToolCallInterceptor):
195
+ def create_tool_call_validator(
196
+ valid_tools: List[str], interceptor: ToolCallInterceptor
197
+ ):
186
198
  """Create a tool call validator that uses the hook system.
187
-
199
+
188
200
  Args:
189
201
  valid_tools: List of valid tool names
190
202
  interceptor: The tool call interceptor instance
191
-
203
+
192
204
  Returns:
193
205
  Validator function
194
206
  """
207
+
195
208
  def validator(tool_name: str, parameters: Dict[str, Any]) -> bool:
196
209
  # Basic validation
197
210
  if tool_name not in valid_tools:
198
211
  return False
199
-
212
+
200
213
  # Hook-based validation
201
214
  result = interceptor.intercept_tool_call_sync(tool_name, parameters)
202
- return result['allowed']
203
-
204
- return validator
215
+ return result["allowed"]
216
+
217
+ return validator
@@ -1,3 +1,5 @@
1
+ from pathlib import Path
2
+
1
3
  """
2
4
  Validation hooks for claude-mpm operations.
3
5
 
@@ -5,8 +7,8 @@ Inspired by awesome-claude-code's pre-push validation approach.
5
7
  """
6
8
 
7
9
  import logging
8
- from typing import Dict, Any, List, Optional, Callable
9
- from pathlib import Path
10
+ from typing import Any, Callable, Dict, List, Optional
11
+
10
12
  import yaml
11
13
 
12
14
  from claude_mpm.validation import AgentValidator, ValidationResult
@@ -16,93 +18,97 @@ logger = logging.getLogger(__name__)
16
18
 
17
19
  class ValidationHooks:
18
20
  """Manages validation hooks for various operations."""
19
-
21
+
20
22
  def __init__(self):
21
23
  """Initialize validation hooks."""
22
24
  self.pre_load_hooks: List[Callable] = []
23
25
  self.post_load_hooks: List[Callable] = []
24
26
  self.pre_execute_hooks: List[Callable] = []
25
27
  self.validator = AgentValidator()
26
-
28
+
27
29
  def register_pre_load_hook(self, hook: Callable) -> None:
28
30
  """Register a hook to run before loading an agent."""
29
31
  self.pre_load_hooks.append(hook)
30
-
32
+
31
33
  def register_post_load_hook(self, hook: Callable) -> None:
32
34
  """Register a hook to run after loading an agent."""
33
35
  self.post_load_hooks.append(hook)
34
-
36
+
35
37
  def register_pre_execute_hook(self, hook: Callable) -> None:
36
38
  """Register a hook to run before executing an agent."""
37
39
  self.pre_execute_hooks.append(hook)
38
-
40
+
39
41
  async def run_pre_load_validation(self, profile_path: Path) -> ValidationResult:
40
42
  """Run validation before loading an agent profile."""
41
43
  logger.info(f"Running pre-load validation for {profile_path}")
42
-
44
+
43
45
  # Run basic file validation
44
46
  if not profile_path.exists():
45
47
  result = ValidationResult(is_valid=False)
46
48
  result.errors.append(f"Profile file not found: {profile_path}")
47
49
  return result
48
-
50
+
49
51
  # Validate profile structure
50
52
  result = self.validator.validate_profile(profile_path)
51
-
53
+
52
54
  # Run custom pre-load hooks
53
55
  for hook in self.pre_load_hooks:
54
56
  try:
55
57
  hook_result = await hook(profile_path)
56
- if hasattr(hook_result, 'errors'):
58
+ if hasattr(hook_result, "errors"):
57
59
  result.errors.extend(hook_result.errors)
58
60
  if hook_result.errors:
59
61
  result.is_valid = False
60
62
  except Exception as e:
61
63
  logger.error(f"Pre-load hook failed: {e}")
62
64
  result.warnings.append(f"Pre-load hook failed: {str(e)}")
63
-
65
+
64
66
  return result
65
-
66
- async def run_post_load_validation(self, agent_config: Dict[str, Any]) -> ValidationResult:
67
+
68
+ async def run_post_load_validation(
69
+ self, agent_config: Dict[str, Any]
70
+ ) -> ValidationResult:
67
71
  """Run validation after loading an agent."""
68
72
  result = ValidationResult(is_valid=True)
69
-
73
+
70
74
  # Run custom post-load hooks
71
75
  for hook in self.post_load_hooks:
72
76
  try:
73
77
  hook_result = await hook(agent_config)
74
- if hasattr(hook_result, 'warnings'):
78
+ if hasattr(hook_result, "warnings"):
75
79
  result.warnings.extend(hook_result.warnings)
76
80
  except Exception as e:
77
81
  logger.error(f"Post-load hook failed: {e}")
78
82
  result.warnings.append(f"Post-load hook failed: {str(e)}")
79
-
83
+
80
84
  return result
81
-
82
- async def run_pre_execute_validation(self, agent_name: str, task: str) -> ValidationResult:
85
+
86
+ async def run_pre_execute_validation(
87
+ self, agent_name: str, task: str
88
+ ) -> ValidationResult:
83
89
  """Run validation before executing an agent task."""
84
90
  result = ValidationResult(is_valid=True)
85
-
91
+
86
92
  # Validate task format
87
93
  if not task or not task.strip():
88
94
  result.errors.append("Task cannot be empty")
89
95
  result.is_valid = False
90
-
96
+
91
97
  # Check task length
92
98
  if len(task) > 10000:
93
99
  result.warnings.append("Task is very long, consider breaking it down")
94
-
100
+
95
101
  # Run custom pre-execute hooks
96
102
  for hook in self.pre_execute_hooks:
97
103
  try:
98
104
  hook_result = await hook(agent_name, task)
99
- if hasattr(hook_result, 'errors') and hook_result.errors:
105
+ if hasattr(hook_result, "errors") and hook_result.errors:
100
106
  result.errors.extend(hook_result.errors)
101
107
  result.is_valid = False
102
108
  except Exception as e:
103
109
  logger.error(f"Pre-execute hook failed: {e}")
104
110
  result.warnings.append(f"Pre-execute hook failed: {str(e)}")
105
-
111
+
106
112
  return result
107
113
 
108
114
 
@@ -110,72 +116,74 @@ class ValidationHooks:
110
116
  async def validate_agent_dependencies(profile_path: Path) -> ValidationResult:
111
117
  """Validate that agent dependencies are available."""
112
118
  result = ValidationResult(is_valid=True)
113
-
119
+
114
120
  try:
115
- with open(profile_path, 'r') as f:
121
+ with open(profile_path, "r") as f:
116
122
  profile_data = yaml.safe_load(f)
117
-
123
+
118
124
  # Check for circular dependencies
119
- agents = profile_data.get('agents', [])
125
+ agents = profile_data.get("agents", [])
120
126
  for agent in agents:
121
- dependencies = agent.get('dependencies', [])
127
+ dependencies = agent.get("dependencies", [])
122
128
  # Simple check - in real implementation would need graph analysis
123
- if agent['name'] in dependencies:
129
+ if agent["name"] in dependencies:
124
130
  result.errors.append(f"Agent '{agent['name']}' has circular dependency")
125
131
  result.is_valid = False
126
-
132
+
127
133
  except Exception as e:
128
134
  result.warnings.append(f"Could not check dependencies: {e}")
129
-
135
+
130
136
  return result
131
137
 
132
138
 
133
139
  async def validate_security_constraints(agent_name: str, task: str) -> ValidationResult:
134
140
  """Validate security constraints before execution."""
135
141
  result = ValidationResult(is_valid=True)
136
-
142
+
137
143
  # Check for potential security issues in task
138
144
  dangerous_patterns = [
139
- 'rm -rf /',
140
- 'sudo rm',
141
- 'format c:',
142
- '__import__',
143
- 'eval(',
144
- 'exec(',
145
+ "rm -rf /",
146
+ "sudo rm",
147
+ "format c:",
148
+ "__import__",
149
+ "eval(",
150
+ "exec(",
145
151
  ]
146
-
152
+
147
153
  task_lower = task.lower()
148
154
  for pattern in dangerous_patterns:
149
155
  if pattern in task_lower:
150
156
  result.errors.append(f"Potentially dangerous pattern detected: {pattern}")
151
157
  result.is_valid = False
152
-
158
+
153
159
  return result
154
160
 
155
161
 
156
162
  class ValidationError(Exception):
157
163
  """Raised when validation fails."""
158
-
159
- def __init__(self, message: str, validation_result: Optional[ValidationResult] = None):
164
+
165
+ def __init__(
166
+ self, message: str, validation_result: Optional[ValidationResult] = None
167
+ ):
160
168
  """Initialize validation error."""
161
169
  super().__init__(message)
162
170
  self.validation_result = validation_result
163
-
171
+
164
172
  def get_detailed_message(self) -> str:
165
173
  """Get detailed error message including validation results."""
166
174
  if not self.validation_result:
167
175
  return str(self)
168
-
176
+
169
177
  lines = [str(self)]
170
-
178
+
171
179
  if self.validation_result.errors:
172
180
  lines.append("\nErrors:")
173
181
  for error in self.validation_result.errors:
174
182
  lines.append(f" - {error}")
175
-
183
+
176
184
  if self.validation_result.warnings:
177
185
  lines.append("\nWarnings:")
178
186
  for warning in self.validation_result.warnings:
179
187
  lines.append(f" - {warning}")
180
-
181
- return '\n'.join(lines)
188
+
189
+ return "\n".join(lines)