claude-mpm 3.9.9__py3-none-any.whl → 4.0.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (411) 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 +155 -0
  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 +1 -1
  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 +90 -49
  31. claude_mpm/cli/__main__.py +3 -2
  32. claude_mpm/cli/commands/__init__.py +21 -18
  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 +143 -762
  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 +203 -81
  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 +305 -197
  50. claude_mpm/cli/parser.py +24 -1150
  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 +104 -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 +217 -0
  69. claude_mpm/config/paths.py +94 -208
  70. claude_mpm/config/socketio_config.py +84 -73
  71. claude_mpm/constants.py +36 -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/css/dashboard.css +27 -8
  113. claude_mpm/dashboard/static/dist/components/agent-inference.js +2 -0
  114. claude_mpm/dashboard/static/dist/components/event-processor.js +2 -0
  115. claude_mpm/dashboard/static/dist/components/event-viewer.js +2 -0
  116. claude_mpm/dashboard/static/dist/components/export-manager.js +2 -0
  117. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +2 -0
  118. claude_mpm/dashboard/static/dist/components/hud-library-loader.js +2 -0
  119. claude_mpm/dashboard/static/dist/components/hud-manager.js +2 -0
  120. claude_mpm/dashboard/static/dist/components/hud-visualizer.js +2 -0
  121. claude_mpm/dashboard/static/dist/components/module-viewer.js +2 -0
  122. claude_mpm/dashboard/static/dist/components/session-manager.js +2 -0
  123. claude_mpm/dashboard/static/dist/components/socket-manager.js +2 -0
  124. claude_mpm/dashboard/static/dist/components/ui-state-manager.js +2 -0
  125. claude_mpm/dashboard/static/dist/components/working-directory.js +2 -0
  126. claude_mpm/dashboard/static/dist/dashboard.js +2 -0
  127. claude_mpm/dashboard/static/dist/socket-client.js +2 -0
  128. claude_mpm/dashboard/static/js/components/agent-inference.js +80 -76
  129. claude_mpm/dashboard/static/js/components/event-processor.js +71 -67
  130. claude_mpm/dashboard/static/js/components/event-viewer.js +74 -70
  131. claude_mpm/dashboard/static/js/components/export-manager.js +31 -28
  132. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +106 -92
  133. claude_mpm/dashboard/static/js/components/hud-library-loader.js +11 -11
  134. claude_mpm/dashboard/static/js/components/hud-manager.js +73 -73
  135. claude_mpm/dashboard/static/js/components/hud-visualizer.js +163 -163
  136. claude_mpm/dashboard/static/js/components/module-viewer.js +305 -233
  137. claude_mpm/dashboard/static/js/components/session-manager.js +32 -29
  138. claude_mpm/dashboard/static/js/components/socket-manager.js +27 -20
  139. claude_mpm/dashboard/static/js/components/ui-state-manager.js +21 -18
  140. claude_mpm/dashboard/static/js/components/working-directory.js +74 -71
  141. claude_mpm/dashboard/static/js/dashboard.js +178 -453
  142. claude_mpm/dashboard/static/js/extension-error-handler.js +164 -0
  143. claude_mpm/dashboard/static/js/socket-client.js +120 -54
  144. claude_mpm/dashboard/templates/index.html +40 -50
  145. claude_mpm/experimental/cli_enhancements.py +60 -58
  146. claude_mpm/generators/__init__.py +1 -1
  147. claude_mpm/generators/agent_profile_generator.py +75 -65
  148. claude_mpm/hooks/__init__.py +1 -1
  149. claude_mpm/hooks/base_hook.py +33 -28
  150. claude_mpm/hooks/claude_hooks/__init__.py +1 -1
  151. claude_mpm/hooks/claude_hooks/connection_pool.py +120 -0
  152. claude_mpm/hooks/claude_hooks/event_handlers.py +743 -0
  153. claude_mpm/hooks/claude_hooks/hook_handler.py +415 -1331
  154. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +4 -4
  155. claude_mpm/hooks/claude_hooks/memory_integration.py +221 -0
  156. claude_mpm/hooks/claude_hooks/response_tracking.py +348 -0
  157. claude_mpm/hooks/claude_hooks/tool_analysis.py +230 -0
  158. claude_mpm/hooks/memory_integration_hook.py +140 -100
  159. claude_mpm/hooks/tool_call_interceptor.py +89 -76
  160. claude_mpm/hooks/validation_hooks.py +57 -49
  161. claude_mpm/init.py +145 -121
  162. claude_mpm/models/__init__.py +9 -9
  163. claude_mpm/models/agent_definition.py +33 -23
  164. claude_mpm/models/agent_session.py +228 -200
  165. claude_mpm/scripts/__init__.py +1 -1
  166. claude_mpm/scripts/socketio_daemon.py +192 -75
  167. claude_mpm/scripts/socketio_server_manager.py +328 -0
  168. claude_mpm/scripts/start_activity_logging.py +25 -22
  169. claude_mpm/services/__init__.py +68 -43
  170. claude_mpm/services/agent_capabilities_service.py +271 -0
  171. claude_mpm/services/agents/__init__.py +23 -32
  172. claude_mpm/services/agents/deployment/__init__.py +3 -3
  173. claude_mpm/services/agents/deployment/agent_config_provider.py +310 -0
  174. claude_mpm/services/agents/deployment/agent_configuration_manager.py +359 -0
  175. claude_mpm/services/agents/deployment/agent_definition_factory.py +84 -0
  176. claude_mpm/services/agents/deployment/agent_deployment.py +415 -2113
  177. claude_mpm/services/agents/deployment/agent_discovery_service.py +387 -0
  178. claude_mpm/services/agents/deployment/agent_environment_manager.py +293 -0
  179. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +387 -0
  180. claude_mpm/services/agents/deployment/agent_format_converter.py +453 -0
  181. claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +161 -0
  182. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +345 -495
  183. claude_mpm/services/agents/deployment/agent_metrics_collector.py +279 -0
  184. claude_mpm/services/agents/deployment/agent_restore_handler.py +88 -0
  185. claude_mpm/services/agents/deployment/agent_template_builder.py +406 -0
  186. claude_mpm/services/agents/deployment/agent_validator.py +352 -0
  187. claude_mpm/services/agents/deployment/agent_version_manager.py +313 -0
  188. claude_mpm/services/agents/deployment/agent_versioning.py +6 -9
  189. claude_mpm/services/agents/deployment/agents_directory_resolver.py +79 -0
  190. claude_mpm/services/agents/deployment/async_agent_deployment.py +298 -234
  191. claude_mpm/services/agents/deployment/config/__init__.py +13 -0
  192. claude_mpm/services/agents/deployment/config/deployment_config.py +182 -0
  193. claude_mpm/services/agents/deployment/config/deployment_config_manager.py +200 -0
  194. claude_mpm/services/agents/deployment/deployment_config_loader.py +54 -0
  195. claude_mpm/services/agents/deployment/deployment_type_detector.py +124 -0
  196. claude_mpm/services/agents/deployment/facade/__init__.py +18 -0
  197. claude_mpm/services/agents/deployment/facade/async_deployment_executor.py +159 -0
  198. claude_mpm/services/agents/deployment/facade/deployment_executor.py +73 -0
  199. claude_mpm/services/agents/deployment/facade/deployment_facade.py +270 -0
  200. claude_mpm/services/agents/deployment/facade/sync_deployment_executor.py +178 -0
  201. claude_mpm/services/agents/deployment/interface_adapter.py +227 -0
  202. claude_mpm/services/agents/deployment/lifecycle_health_checker.py +85 -0
  203. claude_mpm/services/agents/deployment/lifecycle_performance_tracker.py +100 -0
  204. claude_mpm/services/agents/deployment/pipeline/__init__.py +32 -0
  205. claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +158 -0
  206. claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +159 -0
  207. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +169 -0
  208. claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +19 -0
  209. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +195 -0
  210. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +119 -0
  211. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +79 -0
  212. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +90 -0
  213. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +100 -0
  214. claude_mpm/services/agents/deployment/processors/__init__.py +15 -0
  215. claude_mpm/services/agents/deployment/processors/agent_deployment_context.py +98 -0
  216. claude_mpm/services/agents/deployment/processors/agent_deployment_result.py +235 -0
  217. claude_mpm/services/agents/deployment/processors/agent_processor.py +258 -0
  218. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +318 -0
  219. claude_mpm/services/agents/deployment/results/__init__.py +13 -0
  220. claude_mpm/services/agents/deployment/results/deployment_metrics.py +200 -0
  221. claude_mpm/services/agents/deployment/results/deployment_result_builder.py +249 -0
  222. claude_mpm/services/agents/deployment/strategies/__init__.py +25 -0
  223. claude_mpm/services/agents/deployment/strategies/base_strategy.py +119 -0
  224. claude_mpm/services/agents/deployment/strategies/project_strategy.py +150 -0
  225. claude_mpm/services/agents/deployment/strategies/strategy_selector.py +117 -0
  226. claude_mpm/services/agents/deployment/strategies/system_strategy.py +116 -0
  227. claude_mpm/services/agents/deployment/strategies/user_strategy.py +137 -0
  228. claude_mpm/services/agents/deployment/system_instructions_deployer.py +108 -0
  229. claude_mpm/services/agents/deployment/validation/__init__.py +19 -0
  230. claude_mpm/services/agents/deployment/validation/agent_validator.py +323 -0
  231. claude_mpm/services/agents/deployment/validation/deployment_validator.py +238 -0
  232. claude_mpm/services/agents/deployment/validation/template_validator.py +299 -0
  233. claude_mpm/services/agents/deployment/validation/validation_result.py +226 -0
  234. claude_mpm/services/agents/loading/__init__.py +2 -2
  235. claude_mpm/services/agents/loading/agent_profile_loader.py +259 -229
  236. claude_mpm/services/agents/loading/base_agent_manager.py +90 -81
  237. claude_mpm/services/agents/loading/framework_agent_loader.py +154 -129
  238. claude_mpm/services/agents/management/__init__.py +2 -2
  239. claude_mpm/services/agents/management/agent_capabilities_generator.py +72 -58
  240. claude_mpm/services/agents/management/agent_management_service.py +209 -156
  241. claude_mpm/services/agents/memory/__init__.py +9 -6
  242. claude_mpm/services/agents/memory/agent_memory_manager.py +218 -1152
  243. claude_mpm/services/agents/memory/agent_persistence_service.py +20 -16
  244. claude_mpm/services/agents/memory/analyzer.py +430 -0
  245. claude_mpm/services/agents/memory/content_manager.py +376 -0
  246. claude_mpm/services/agents/memory/template_generator.py +468 -0
  247. claude_mpm/services/agents/registry/__init__.py +7 -10
  248. claude_mpm/services/agents/registry/deployed_agent_discovery.py +122 -97
  249. claude_mpm/services/agents/registry/modification_tracker.py +351 -285
  250. claude_mpm/services/async_session_logger.py +187 -153
  251. claude_mpm/services/claude_session_logger.py +87 -72
  252. claude_mpm/services/command_handler_service.py +217 -0
  253. claude_mpm/services/communication/__init__.py +3 -2
  254. claude_mpm/services/core/__init__.py +50 -97
  255. claude_mpm/services/core/base.py +60 -53
  256. claude_mpm/services/core/interfaces/__init__.py +188 -0
  257. claude_mpm/services/core/interfaces/agent.py +351 -0
  258. claude_mpm/services/core/interfaces/communication.py +343 -0
  259. claude_mpm/services/core/interfaces/infrastructure.py +413 -0
  260. claude_mpm/services/core/interfaces/service.py +434 -0
  261. claude_mpm/services/core/interfaces.py +19 -944
  262. claude_mpm/services/event_aggregator.py +208 -170
  263. claude_mpm/services/exceptions.py +387 -308
  264. claude_mpm/services/framework_claude_md_generator/__init__.py +75 -79
  265. claude_mpm/services/framework_claude_md_generator/content_assembler.py +69 -60
  266. claude_mpm/services/framework_claude_md_generator/content_validator.py +65 -61
  267. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +68 -49
  268. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +34 -34
  269. claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +25 -22
  270. claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +10 -10
  271. claude_mpm/services/framework_claude_md_generator/section_generators/core_responsibilities.py +4 -3
  272. claude_mpm/services/framework_claude_md_generator/section_generators/delegation_constraints.py +4 -3
  273. claude_mpm/services/framework_claude_md_generator/section_generators/environment_config.py +4 -3
  274. claude_mpm/services/framework_claude_md_generator/section_generators/footer.py +6 -5
  275. claude_mpm/services/framework_claude_md_generator/section_generators/header.py +8 -7
  276. claude_mpm/services/framework_claude_md_generator/section_generators/orchestration_principles.py +4 -3
  277. claude_mpm/services/framework_claude_md_generator/section_generators/role_designation.py +6 -5
  278. claude_mpm/services/framework_claude_md_generator/section_generators/subprocess_validation.py +9 -8
  279. claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +4 -3
  280. claude_mpm/services/framework_claude_md_generator/section_generators/troubleshooting.py +5 -4
  281. claude_mpm/services/framework_claude_md_generator/section_manager.py +28 -27
  282. claude_mpm/services/framework_claude_md_generator/version_manager.py +30 -28
  283. claude_mpm/services/hook_service.py +106 -114
  284. claude_mpm/services/infrastructure/__init__.py +7 -5
  285. claude_mpm/services/infrastructure/context_preservation.py +571 -0
  286. claude_mpm/services/infrastructure/daemon_manager.py +279 -0
  287. claude_mpm/services/infrastructure/logging.py +83 -76
  288. claude_mpm/services/infrastructure/monitoring.py +547 -404
  289. claude_mpm/services/mcp_gateway/__init__.py +40 -23
  290. claude_mpm/services/mcp_gateway/config/__init__.py +2 -2
  291. claude_mpm/services/mcp_gateway/config/config_loader.py +61 -56
  292. claude_mpm/services/mcp_gateway/config/config_schema.py +50 -41
  293. claude_mpm/services/mcp_gateway/config/configuration.py +82 -75
  294. claude_mpm/services/mcp_gateway/core/__init__.py +14 -21
  295. claude_mpm/services/mcp_gateway/core/base.py +80 -67
  296. claude_mpm/services/mcp_gateway/core/exceptions.py +60 -46
  297. claude_mpm/services/mcp_gateway/core/interfaces.py +97 -93
  298. claude_mpm/services/mcp_gateway/main.py +307 -127
  299. claude_mpm/services/mcp_gateway/registry/__init__.py +1 -1
  300. claude_mpm/services/mcp_gateway/registry/service_registry.py +100 -101
  301. claude_mpm/services/mcp_gateway/registry/tool_registry.py +135 -126
  302. claude_mpm/services/mcp_gateway/server/__init__.py +4 -4
  303. claude_mpm/services/mcp_gateway/server/{mcp_server.py → mcp_gateway.py} +149 -153
  304. claude_mpm/services/mcp_gateway/server/stdio_handler.py +105 -107
  305. claude_mpm/services/mcp_gateway/server/stdio_server.py +691 -0
  306. claude_mpm/services/mcp_gateway/tools/__init__.py +4 -2
  307. claude_mpm/services/mcp_gateway/tools/base_adapter.py +110 -121
  308. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +283 -215
  309. claude_mpm/services/mcp_gateway/tools/hello_world.py +122 -120
  310. claude_mpm/services/mcp_gateway/tools/ticket_tools.py +652 -0
  311. claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +606 -0
  312. claude_mpm/services/memory/__init__.py +2 -2
  313. claude_mpm/services/memory/builder.py +451 -362
  314. claude_mpm/services/memory/cache/__init__.py +2 -2
  315. claude_mpm/services/memory/cache/shared_prompt_cache.py +232 -194
  316. claude_mpm/services/memory/cache/simple_cache.py +107 -93
  317. claude_mpm/services/memory/indexed_memory.py +195 -193
  318. claude_mpm/services/memory/optimizer.py +267 -234
  319. claude_mpm/services/memory/router.py +571 -263
  320. claude_mpm/services/memory_hook_service.py +237 -0
  321. claude_mpm/services/port_manager.py +223 -0
  322. claude_mpm/services/project/__init__.py +3 -3
  323. claude_mpm/services/project/analyzer.py +451 -305
  324. claude_mpm/services/project/registry.py +262 -240
  325. claude_mpm/services/recovery_manager.py +287 -231
  326. claude_mpm/services/response_tracker.py +87 -67
  327. claude_mpm/services/runner_configuration_service.py +587 -0
  328. claude_mpm/services/session_management_service.py +304 -0
  329. claude_mpm/services/socketio/__init__.py +4 -4
  330. claude_mpm/services/socketio/client_proxy.py +174 -0
  331. claude_mpm/services/socketio/handlers/__init__.py +3 -3
  332. claude_mpm/services/socketio/handlers/base.py +44 -30
  333. claude_mpm/services/socketio/handlers/connection.py +145 -65
  334. claude_mpm/services/socketio/handlers/file.py +123 -108
  335. claude_mpm/services/socketio/handlers/git.py +607 -373
  336. claude_mpm/services/socketio/handlers/hook.py +170 -0
  337. claude_mpm/services/socketio/handlers/memory.py +4 -4
  338. claude_mpm/services/socketio/handlers/project.py +4 -4
  339. claude_mpm/services/socketio/handlers/registry.py +53 -38
  340. claude_mpm/services/socketio/server/__init__.py +18 -0
  341. claude_mpm/services/socketio/server/broadcaster.py +252 -0
  342. claude_mpm/services/socketio/server/core.py +399 -0
  343. claude_mpm/services/socketio/server/main.py +323 -0
  344. claude_mpm/services/socketio_client_manager.py +160 -133
  345. claude_mpm/services/socketio_server.py +36 -1885
  346. claude_mpm/services/subprocess_launcher_service.py +316 -0
  347. claude_mpm/services/system_instructions_service.py +258 -0
  348. claude_mpm/services/ticket_manager.py +20 -534
  349. claude_mpm/services/utility_service.py +285 -0
  350. claude_mpm/services/version_control/__init__.py +18 -21
  351. claude_mpm/services/version_control/branch_strategy.py +20 -10
  352. claude_mpm/services/version_control/conflict_resolution.py +37 -13
  353. claude_mpm/services/version_control/git_operations.py +52 -21
  354. claude_mpm/services/version_control/semantic_versioning.py +92 -53
  355. claude_mpm/services/version_control/version_parser.py +145 -125
  356. claude_mpm/services/version_service.py +270 -0
  357. claude_mpm/storage/__init__.py +9 -0
  358. claude_mpm/storage/state_storage.py +552 -0
  359. claude_mpm/ticket_wrapper.py +2 -2
  360. claude_mpm/utils/__init__.py +2 -2
  361. claude_mpm/utils/agent_dependency_loader.py +453 -243
  362. claude_mpm/utils/config_manager.py +157 -118
  363. claude_mpm/utils/console.py +1 -1
  364. claude_mpm/utils/dependency_cache.py +102 -107
  365. claude_mpm/utils/dependency_manager.py +52 -47
  366. claude_mpm/utils/dependency_strategies.py +131 -96
  367. claude_mpm/utils/environment_context.py +110 -102
  368. claude_mpm/utils/error_handler.py +75 -55
  369. claude_mpm/utils/file_utils.py +80 -67
  370. claude_mpm/utils/framework_detection.py +12 -11
  371. claude_mpm/utils/import_migration_example.py +12 -60
  372. claude_mpm/utils/imports.py +48 -45
  373. claude_mpm/utils/path_operations.py +100 -93
  374. claude_mpm/utils/robust_installer.py +172 -164
  375. claude_mpm/utils/session_logging.py +30 -23
  376. claude_mpm/utils/subprocess_utils.py +99 -61
  377. claude_mpm/validation/__init__.py +1 -1
  378. claude_mpm/validation/agent_validator.py +151 -111
  379. claude_mpm/validation/frontmatter_validator.py +92 -71
  380. {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/METADATA +51 -2
  381. claude_mpm-4.0.3.dist-info/RECORD +402 -0
  382. {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/entry_points.txt +1 -0
  383. {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/licenses/LICENSE +1 -1
  384. claude_mpm/config/memory_guardian_config.py +0 -325
  385. claude_mpm/core/config_paths.py +0 -150
  386. claude_mpm/dashboard/static/js/dashboard-original.js +0 -4134
  387. claude_mpm/deployment_paths.py +0 -261
  388. claude_mpm/hooks/claude_hooks/hook_handler_fixed.py +0 -454
  389. claude_mpm/models/state_models.py +0 -433
  390. claude_mpm/services/agent/__init__.py +0 -24
  391. claude_mpm/services/agent/deployment.py +0 -2548
  392. claude_mpm/services/agent/management.py +0 -598
  393. claude_mpm/services/agent/registry.py +0 -813
  394. claude_mpm/services/agents/registry/agent_registry.py +0 -813
  395. claude_mpm/services/communication/socketio.py +0 -1935
  396. claude_mpm/services/communication/websocket.py +0 -479
  397. claude_mpm/services/framework_claude_md_generator.py +0 -624
  398. claude_mpm/services/health_monitor.py +0 -893
  399. claude_mpm/services/infrastructure/memory_guardian.py +0 -770
  400. claude_mpm/services/mcp_gateway/server/mcp_server_simple.py +0 -444
  401. claude_mpm/services/optimized_hook_service.py +0 -542
  402. claude_mpm/services/project_analyzer.py +0 -864
  403. claude_mpm/services/project_registry.py +0 -608
  404. claude_mpm/services/standalone_socketio_server.py +0 -1300
  405. claude_mpm/services/ticket_manager_di.py +0 -318
  406. claude_mpm/services/ticketing_service_original.py +0 -510
  407. claude_mpm/utils/paths.py +0 -395
  408. claude_mpm/utils/platform_memory.py +0 -524
  409. claude_mpm-3.9.9.dist-info/RECORD +0 -293
  410. {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/WHEEL +0 -0
  411. {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,159 @@
1
+ """Pipeline context for deployment operations."""
2
+
3
+ from dataclasses import dataclass, field
4
+ from pathlib import Path
5
+ from typing import Any, Dict, List, Optional
6
+
7
+ from claude_mpm.core.config import Config
8
+
9
+ from ..strategies.base_strategy import BaseDeploymentStrategy
10
+
11
+
12
+ @dataclass
13
+ class PipelineContext:
14
+ """Context object that flows through the deployment pipeline.
15
+
16
+ This context contains all the data needed for deployment and is
17
+ passed between pipeline steps. Each step can read from and modify
18
+ the context as needed.
19
+ """
20
+
21
+ # Input parameters
22
+ target_dir: Optional[Path] = None
23
+ force_rebuild: bool = False
24
+ deployment_mode: str = "update"
25
+ config: Optional[Config] = None
26
+ use_async: bool = False
27
+ working_directory: Optional[Path] = None
28
+ templates_dir: Optional[Path] = None
29
+ base_agent_path: Optional[Path] = None
30
+
31
+ # Strategy and execution context
32
+ strategy: Optional[BaseDeploymentStrategy] = None
33
+ actual_target_dir: Optional[Path] = None
34
+ actual_templates_dir: Optional[Path] = None
35
+ actual_base_agent_path: Optional[Path] = None
36
+
37
+ # Configuration and exclusions
38
+ excluded_agents: List[str] = field(default_factory=list)
39
+ case_sensitive_exclusion: bool = True
40
+
41
+ # Template and agent data
42
+ template_files: List[Path] = field(default_factory=list)
43
+ base_agent_data: Optional[Dict[str, Any]] = None
44
+ base_agent_version: Optional[tuple] = None
45
+
46
+ # Deployment results
47
+ results: Dict[str, Any] = field(default_factory=dict)
48
+
49
+ # Metrics and timing
50
+ deployment_start_time: Optional[float] = None
51
+ step_timings: Dict[str, float] = field(default_factory=dict)
52
+
53
+ # Error handling
54
+ errors: List[str] = field(default_factory=list)
55
+ warnings: List[str] = field(default_factory=list)
56
+
57
+ # Step control flags
58
+ should_deploy_system_instructions: bool = True
59
+ should_collect_metrics: bool = True
60
+ should_repair_existing_agents: bool = True
61
+
62
+ def add_error(self, error: str) -> None:
63
+ """Add an error to the context.
64
+
65
+ Args:
66
+ error: Error message to add
67
+ """
68
+ self.errors.append(error)
69
+ if "errors" not in self.results:
70
+ self.results["errors"] = []
71
+ self.results["errors"].append(error)
72
+
73
+ def add_warning(self, warning: str) -> None:
74
+ """Add a warning to the context.
75
+
76
+ Args:
77
+ warning: Warning message to add
78
+ """
79
+ self.warnings.append(warning)
80
+ if "warnings" not in self.results:
81
+ self.results["warnings"] = []
82
+ self.results["warnings"].append(warning)
83
+
84
+ def has_errors(self) -> bool:
85
+ """Check if there are any errors in the context.
86
+
87
+ Returns:
88
+ True if there are errors
89
+ """
90
+ return len(self.errors) > 0
91
+
92
+ def get_error_count(self) -> int:
93
+ """Get the number of errors.
94
+
95
+ Returns:
96
+ Number of errors
97
+ """
98
+ return len(self.errors)
99
+
100
+ def get_warning_count(self) -> int:
101
+ """Get the number of warnings.
102
+
103
+ Returns:
104
+ Number of warnings
105
+ """
106
+ return len(self.warnings)
107
+
108
+ def initialize_results(self) -> None:
109
+ """Initialize the results dictionary with default structure."""
110
+ if not self.results:
111
+ self.results = {
112
+ "target_dir": str(self.actual_target_dir)
113
+ if self.actual_target_dir
114
+ else "",
115
+ "deployed": [],
116
+ "updated": [],
117
+ "migrated": [],
118
+ "skipped": [],
119
+ "errors": [],
120
+ "warnings": [],
121
+ "repaired": [],
122
+ "total": 0,
123
+ "deployment_time": 0.0,
124
+ "strategy_used": self.strategy.name if self.strategy else "Unknown",
125
+ }
126
+
127
+ def finalize_results(self, end_time: float) -> Dict[str, Any]:
128
+ """Finalize the results dictionary.
129
+
130
+ Args:
131
+ end_time: End time of deployment
132
+
133
+ Returns:
134
+ Final results dictionary
135
+ """
136
+ if self.deployment_start_time:
137
+ self.results["deployment_time"] = end_time - self.deployment_start_time
138
+
139
+ # Add step timings if available
140
+ if self.step_timings:
141
+ self.results["step_timings"] = self.step_timings.copy()
142
+
143
+ # Ensure all required fields are present
144
+ for field in [
145
+ "deployed",
146
+ "updated",
147
+ "migrated",
148
+ "skipped",
149
+ "errors",
150
+ "warnings",
151
+ "repaired",
152
+ ]:
153
+ if field not in self.results:
154
+ self.results[field] = []
155
+
156
+ if "total" not in self.results:
157
+ self.results["total"] = len(self.template_files)
158
+
159
+ return self.results.copy()
@@ -0,0 +1,169 @@
1
+ """Pipeline executor for running deployment pipelines."""
2
+
3
+ import time
4
+ from typing import Any, Dict, List
5
+
6
+ from claude_mpm.core.logger import get_logger
7
+
8
+ from .pipeline_context import PipelineContext
9
+ from .steps.base_step import BaseDeploymentStep, StepResult, StepStatus
10
+
11
+
12
+ class DeploymentPipelineExecutor:
13
+ """Executor for running deployment pipelines.
14
+
15
+ This executor runs a series of deployment steps in order,
16
+ handling errors and collecting results.
17
+ """
18
+
19
+ def __init__(self):
20
+ """Initialize the pipeline executor."""
21
+ self.logger = get_logger(__name__)
22
+
23
+ def execute(
24
+ self, steps: List[BaseDeploymentStep], context: PipelineContext
25
+ ) -> Dict[str, Any]:
26
+ """Execute a deployment pipeline.
27
+
28
+ Args:
29
+ steps: List of deployment steps to execute
30
+ context: Pipeline context containing deployment data
31
+
32
+ Returns:
33
+ Dictionary with execution results
34
+ """
35
+ self.logger.info(f"Starting deployment pipeline with {len(steps)} steps")
36
+
37
+ # Initialize context
38
+ if context.deployment_start_time is None:
39
+ context.deployment_start_time = time.time()
40
+
41
+ context.initialize_results()
42
+
43
+ # Execute steps
44
+ executed_steps = []
45
+ failed_steps = []
46
+ skipped_steps = []
47
+
48
+ for i, step in enumerate(steps):
49
+ step_start_time = time.time()
50
+
51
+ try:
52
+ # Check if step should be executed
53
+ if not step.should_execute(context):
54
+ self.logger.info(f"Skipping step {i+1}/{len(steps)}: {step.name}")
55
+ skipped_steps.append(step.name)
56
+ continue
57
+
58
+ self.logger.info(f"Executing step {i+1}/{len(steps)}: {step.name}")
59
+
60
+ # Execute the step
61
+ result = step.execute(context)
62
+
63
+ # Log result
64
+ if result.is_success:
65
+ self.logger.info(f"Step completed successfully: {step.name}")
66
+ executed_steps.append(step.name)
67
+ elif result.is_warning:
68
+ self.logger.warning(
69
+ f"Step completed with warnings: {step.name} - {result.message}"
70
+ )
71
+ executed_steps.append(step.name)
72
+ elif result.is_failure:
73
+ self.logger.error(f"Step failed: {step.name} - {result.message}")
74
+ failed_steps.append(step.name)
75
+
76
+ # Check if we can continue
77
+ if not step.can_continue_on_failure():
78
+ self.logger.error(
79
+ f"Critical step failed, stopping pipeline: {step.name}"
80
+ )
81
+ break
82
+ elif result.is_skipped:
83
+ self.logger.info(
84
+ f"Step was skipped: {step.name} - {result.message}"
85
+ )
86
+ skipped_steps.append(step.name)
87
+
88
+ # Record timing
89
+ step_execution_time = time.time() - step_start_time
90
+ context.step_timings[step.name] = step_execution_time
91
+
92
+ except Exception as e:
93
+ step_execution_time = time.time() - step_start_time
94
+ context.step_timings[step.name] = step_execution_time
95
+
96
+ error_msg = f"Unexpected error in step {step.name}: {str(e)}"
97
+ self.logger.error(error_msg, exc_info=True)
98
+ context.add_error(error_msg)
99
+ failed_steps.append(step.name)
100
+
101
+ # Check if we can continue
102
+ if not step.can_continue_on_failure():
103
+ self.logger.error(
104
+ f"Critical step failed with exception, stopping pipeline: {step.name}"
105
+ )
106
+ break
107
+
108
+ # Finalize results
109
+ end_time = time.time()
110
+ final_results = context.finalize_results(end_time)
111
+
112
+ # Add pipeline execution metadata
113
+ final_results.update(
114
+ {
115
+ "pipeline_execution": {
116
+ "total_steps": len(steps),
117
+ "executed_steps": executed_steps,
118
+ "failed_steps": failed_steps,
119
+ "skipped_steps": skipped_steps,
120
+ "success": len(failed_steps) == 0,
121
+ "total_execution_time": end_time - context.deployment_start_time,
122
+ }
123
+ }
124
+ )
125
+
126
+ # Log final results
127
+ if len(failed_steps) == 0:
128
+ self.logger.info(
129
+ f"Pipeline completed successfully in {final_results['deployment_time']:.3f}s"
130
+ )
131
+ else:
132
+ self.logger.error(
133
+ f"Pipeline completed with {len(failed_steps)} failed steps"
134
+ )
135
+
136
+ return final_results
137
+
138
+ def validate_pipeline(self, steps: List[BaseDeploymentStep]) -> List[str]:
139
+ """Validate a pipeline before execution.
140
+
141
+ Args:
142
+ steps: List of deployment steps to validate
143
+
144
+ Returns:
145
+ List of validation errors (empty if valid)
146
+ """
147
+ errors = []
148
+
149
+ if not steps:
150
+ errors.append("Pipeline cannot be empty")
151
+ return errors
152
+
153
+ # Check for duplicate step names
154
+ step_names = [step.name for step in steps]
155
+ duplicates = set([name for name in step_names if step_names.count(name) > 1])
156
+ if duplicates:
157
+ errors.append(f"Duplicate step names found: {duplicates}")
158
+
159
+ # Validate dependencies (simplified check)
160
+ for step in steps:
161
+ dependencies = step.get_dependencies()
162
+ for dep_class in dependencies:
163
+ # Check if any step in the pipeline is of the required type
164
+ if not any(isinstance(s, dep_class) for s in steps):
165
+ errors.append(
166
+ f"Step {step.name} requires {dep_class.__name__} but it's not in the pipeline"
167
+ )
168
+
169
+ return errors
@@ -0,0 +1,19 @@
1
+ """Deployment pipeline steps.
2
+
3
+ This module contains all the individual steps that make up the
4
+ deployment pipeline. Each step is responsible for a specific
5
+ part of the deployment process.
6
+ """
7
+
8
+ from .agent_processing_step import AgentProcessingStep
9
+ from .base_step import BaseDeploymentStep, StepResult
10
+ from .configuration_step import ConfigurationLoadStep
11
+ from .target_directory_step import TargetDirectorySetupStep
12
+
13
+ __all__ = [
14
+ "BaseDeploymentStep",
15
+ "StepResult",
16
+ "ConfigurationLoadStep",
17
+ "TargetDirectorySetupStep",
18
+ "AgentProcessingStep",
19
+ ]
@@ -0,0 +1,195 @@
1
+ """Agent processing step for deployment pipeline."""
2
+
3
+ import time
4
+
5
+ from claude_mpm.services.agents.deployment.processors import (
6
+ AgentDeploymentContext,
7
+ AgentDeploymentResult,
8
+ AgentProcessor,
9
+ )
10
+
11
+ from .base_step import BaseDeploymentStep, StepResult, StepStatus
12
+
13
+
14
+ class AgentProcessingStep(BaseDeploymentStep):
15
+ """Step to process and deploy individual agents."""
16
+
17
+ def __init__(self, template_builder, version_manager):
18
+ super().__init__(
19
+ name="Agent Processing",
20
+ description="Process and deploy individual agent templates",
21
+ )
22
+ self.processor = AgentProcessor(template_builder, version_manager)
23
+
24
+ def execute(self, context) -> StepResult:
25
+ """Execute agent processing step.
26
+
27
+ Args:
28
+ context: Pipeline context
29
+
30
+ Returns:
31
+ Result of agent processing
32
+ """
33
+ start_time = time.time()
34
+
35
+ try:
36
+ if not context.template_files:
37
+ self.logger.warning("No template files to process")
38
+ return StepResult(
39
+ status=StepStatus.SKIPPED,
40
+ message="No template files found to process",
41
+ execution_time=time.time() - start_time,
42
+ )
43
+
44
+ # Initialize results tracking
45
+ processed_count = 0
46
+ failed_count = 0
47
+
48
+ # Process each template file
49
+ for template_file in context.template_files:
50
+ try:
51
+ # Create agent deployment context
52
+ agent_context = AgentDeploymentContext.from_template_file(
53
+ template_file=template_file,
54
+ agents_dir=context.actual_target_dir,
55
+ base_agent_data=context.base_agent_data or {},
56
+ base_agent_version=context.base_agent_version or (1, 0, 0),
57
+ force_rebuild=context.force_rebuild,
58
+ deployment_mode=context.deployment_mode,
59
+ )
60
+
61
+ # Validate agent if requested
62
+ if context.should_repair_existing_agents:
63
+ if not self.processor.validate_agent(agent_context):
64
+ self.logger.warning(
65
+ f"Agent validation failed: {agent_context.agent_name}"
66
+ )
67
+ context.add_warning(
68
+ f"Agent validation failed: {agent_context.agent_name}"
69
+ )
70
+ failed_count += 1
71
+ continue
72
+
73
+ # Process the agent
74
+ result = self.processor.process_agent(agent_context)
75
+
76
+ # Update context results based on outcome
77
+ self._update_context_with_result(context, result)
78
+
79
+ if result.is_successful():
80
+ processed_count += 1
81
+ else:
82
+ failed_count += 1
83
+
84
+ except Exception as e:
85
+ error_msg = (
86
+ f"Failed to process agent {template_file.stem}: {str(e)}"
87
+ )
88
+ self.logger.error(error_msg, exc_info=True)
89
+ context.add_error(error_msg)
90
+ failed_count += 1
91
+
92
+ # Calculate execution time
93
+ execution_time = time.time() - start_time
94
+ context.step_timings[self.name] = execution_time
95
+
96
+ # Determine step status
97
+ if failed_count == 0:
98
+ status = StepStatus.SUCCESS
99
+ message = f"Successfully processed {processed_count} agents in {execution_time:.3f}s"
100
+ elif processed_count > 0:
101
+ status = StepStatus.WARNING
102
+ message = f"Processed {processed_count} agents with {failed_count} failures in {execution_time:.3f}s"
103
+ else:
104
+ status = StepStatus.FAILURE
105
+ message = f"Failed to process any agents ({failed_count} failures) in {execution_time:.3f}s"
106
+
107
+ self.logger.info(message)
108
+
109
+ return StepResult(
110
+ status=status, message=message, execution_time=execution_time
111
+ )
112
+
113
+ except Exception as e:
114
+ execution_time = time.time() - start_time
115
+ context.step_timings[self.name] = execution_time
116
+
117
+ error_msg = f"Agent processing step failed: {str(e)}"
118
+ self.logger.error(error_msg, exc_info=True)
119
+ context.add_error(error_msg)
120
+
121
+ return StepResult(
122
+ status=StepStatus.FAILURE,
123
+ message=error_msg,
124
+ error=e,
125
+ execution_time=execution_time,
126
+ )
127
+
128
+ def _update_context_with_result(
129
+ self, context, result: AgentDeploymentResult
130
+ ) -> None:
131
+ """Update pipeline context with agent deployment result.
132
+
133
+ Args:
134
+ context: Pipeline context
135
+ result: Agent deployment result
136
+ """
137
+ # Ensure results structure exists
138
+ if "deployed" not in context.results:
139
+ context.results["deployed"] = []
140
+ if "updated" not in context.results:
141
+ context.results["updated"] = []
142
+ if "migrated" not in context.results:
143
+ context.results["migrated"] = []
144
+ if "skipped" not in context.results:
145
+ context.results["skipped"] = []
146
+ if "errors" not in context.results:
147
+ context.results["errors"] = []
148
+
149
+ # Add result to appropriate list
150
+ result_dict = result.to_dict()
151
+
152
+ if result.status.value == "deployed":
153
+ context.results["deployed"].append(result_dict)
154
+ elif result.status.value == "updated":
155
+ context.results["updated"].append(result_dict)
156
+ elif result.status.value == "migrated":
157
+ context.results["migrated"].append(result_dict)
158
+ elif result.status.value == "skipped":
159
+ context.results["skipped"].append(result.agent_name)
160
+ elif result.status.value == "failed":
161
+ context.results["errors"].append(
162
+ result.error_message or f"Failed to deploy {result.agent_name}"
163
+ )
164
+
165
+ def should_execute(self, context) -> bool:
166
+ """Check if this step should be executed.
167
+
168
+ Args:
169
+ context: Pipeline context
170
+
171
+ Returns:
172
+ True if there are template files to process
173
+ """
174
+ return bool(context.template_files)
175
+
176
+ def can_continue_on_failure(self) -> bool:
177
+ """Agent processing failures should not stop the pipeline.
178
+
179
+ Individual agent failures are tracked but don't prevent
180
+ other agents from being processed.
181
+
182
+ Returns:
183
+ True - continue on failure
184
+ """
185
+ return True
186
+
187
+ def get_dependencies(self) -> list:
188
+ """This step depends on target directory setup.
189
+
190
+ Returns:
191
+ List of required step classes
192
+ """
193
+ from .target_directory_step import TargetDirectorySetupStep
194
+
195
+ return [TargetDirectorySetupStep]
@@ -0,0 +1,119 @@
1
+ """Base deployment step interface."""
2
+
3
+ from abc import ABC, abstractmethod
4
+ from dataclasses import dataclass
5
+ from enum import Enum
6
+
7
+ from claude_mpm.core.logger import get_logger
8
+
9
+
10
+ class StepStatus(Enum):
11
+ """Status of a pipeline step execution."""
12
+
13
+ SUCCESS = "success"
14
+ FAILURE = "failure"
15
+ SKIPPED = "skipped"
16
+ WARNING = "warning"
17
+
18
+
19
+ @dataclass
20
+ class StepResult:
21
+ """Result of executing a pipeline step."""
22
+
23
+ status: StepStatus
24
+ message: Optional[str] = None
25
+ error: Optional[Exception] = None
26
+ execution_time: Optional[float] = None
27
+
28
+ @property
29
+ def is_success(self) -> bool:
30
+ """Check if the step was successful."""
31
+ return self.status == StepStatus.SUCCESS
32
+
33
+ @property
34
+ def is_failure(self) -> bool:
35
+ """Check if the step failed."""
36
+ return self.status == StepStatus.FAILURE
37
+
38
+ @property
39
+ def is_skipped(self) -> bool:
40
+ """Check if the step was skipped."""
41
+ return self.status == StepStatus.SKIPPED
42
+
43
+ @property
44
+ def is_warning(self) -> bool:
45
+ """Check if the step completed with warnings."""
46
+ return self.status == StepStatus.WARNING
47
+
48
+
49
+ class BaseDeploymentStep(ABC):
50
+ """Base class for all deployment pipeline steps.
51
+
52
+ Each step in the deployment pipeline should inherit from this class
53
+ and implement the execute method. Steps can read from and modify
54
+ the pipeline context as needed.
55
+ """
56
+
57
+ def __init__(self, name: str, description: str = ""):
58
+ """Initialize the deployment step.
59
+
60
+ Args:
61
+ name: Human-readable name for this step
62
+ description: Optional description of what this step does
63
+ """
64
+ self.name = name
65
+ self.description = description
66
+ self.logger = get_logger(f"{__name__}.{self.__class__.__name__}")
67
+
68
+ @abstractmethod
69
+ def execute(self, context) -> StepResult:
70
+ """Execute this deployment step.
71
+
72
+ Args:
73
+ context: Pipeline context containing deployment data
74
+
75
+ Returns:
76
+ Result of executing this step
77
+ """
78
+ pass
79
+
80
+ def should_execute(self, context) -> bool:
81
+ """Check if this step should be executed.
82
+
83
+ Override this method to add conditional execution logic.
84
+
85
+ Args:
86
+ context: Pipeline context
87
+
88
+ Returns:
89
+ True if this step should be executed
90
+ """
91
+ return True
92
+
93
+ def can_continue_on_failure(self) -> bool:
94
+ """Check if pipeline can continue if this step fails.
95
+
96
+ Override this method for steps that are not critical.
97
+
98
+ Returns:
99
+ True if pipeline can continue after this step fails
100
+ """
101
+ return False
102
+
103
+ def get_dependencies(self) -> list:
104
+ """Get list of step classes this step depends on.
105
+
106
+ Override this method to specify dependencies.
107
+
108
+ Returns:
109
+ List of step classes that must execute before this step
110
+ """
111
+ return []
112
+
113
+ def __str__(self) -> str:
114
+ """String representation of the step."""
115
+ return f"{self.name}"
116
+
117
+ def __repr__(self) -> str:
118
+ """Detailed string representation of the step."""
119
+ return f"{self.__class__.__name__}(name='{self.name}', description='{self.description}')"