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,79 @@
1
+ """Configuration loading step for deployment pipeline."""
2
+
3
+ import time
4
+
5
+ from claude_mpm.core.config import Config
6
+
7
+ from .base_step import BaseDeploymentStep, StepResult, StepStatus
8
+
9
+
10
+ class ConfigurationLoadStep(BaseDeploymentStep):
11
+ """Step to load and process deployment configuration."""
12
+
13
+ def __init__(self):
14
+ super().__init__(
15
+ name="Configuration Loading",
16
+ description="Load and process deployment configuration settings",
17
+ )
18
+
19
+ def execute(self, context) -> StepResult:
20
+ """Execute configuration loading step.
21
+
22
+ Args:
23
+ context: Pipeline context
24
+
25
+ Returns:
26
+ Result of configuration loading
27
+ """
28
+ start_time = time.time()
29
+
30
+ try:
31
+ # Load configuration if not provided
32
+ if context.config is None:
33
+ self.logger.debug("Loading default configuration")
34
+ context.config = Config()
35
+
36
+ # Extract excluded agents
37
+ context.excluded_agents = context.config.get(
38
+ "agent_deployment.excluded_agents", []
39
+ )
40
+
41
+ # Extract case sensitivity setting
42
+ context.case_sensitive_exclusion = context.config.get(
43
+ "agent_deployment.case_sensitive_exclusion", True
44
+ )
45
+
46
+ # Log configuration details
47
+ self.logger.info(
48
+ f"Loaded configuration with {len(context.excluded_agents)} excluded agents"
49
+ )
50
+ if context.excluded_agents:
51
+ self.logger.debug(f"Excluded agents: {context.excluded_agents}")
52
+
53
+ execution_time = time.time() - start_time
54
+ context.step_timings[self.name] = execution_time
55
+
56
+ return StepResult(
57
+ status=StepStatus.SUCCESS,
58
+ message=f"Configuration loaded successfully in {execution_time:.3f}s",
59
+ execution_time=execution_time,
60
+ )
61
+
62
+ except Exception as e:
63
+ execution_time = time.time() - start_time
64
+ context.step_timings[self.name] = execution_time
65
+
66
+ error_msg = f"Failed to load configuration: {str(e)}"
67
+ self.logger.error(error_msg)
68
+ context.add_error(error_msg)
69
+
70
+ return StepResult(
71
+ status=StepStatus.FAILURE,
72
+ message=error_msg,
73
+ error=e,
74
+ execution_time=execution_time,
75
+ )
76
+
77
+ def can_continue_on_failure(self) -> bool:
78
+ """Configuration loading failure should stop the pipeline."""
79
+ return False
@@ -0,0 +1,90 @@
1
+ """Target directory setup step for deployment pipeline."""
2
+
3
+ import time
4
+ from pathlib import Path
5
+
6
+ from .base_step import BaseDeploymentStep, StepResult, StepStatus
7
+
8
+
9
+ class TargetDirectorySetupStep(BaseDeploymentStep):
10
+ """Step to determine and setup the target directory for deployment."""
11
+
12
+ def __init__(self):
13
+ super().__init__(
14
+ name="Target Directory Setup",
15
+ description="Determine and create the target directory for agent deployment",
16
+ )
17
+
18
+ def execute(self, context) -> StepResult:
19
+ """Execute target directory setup step.
20
+
21
+ Args:
22
+ context: Pipeline context
23
+
24
+ Returns:
25
+ Result of target directory setup
26
+ """
27
+ start_time = time.time()
28
+
29
+ try:
30
+ # Use strategy to determine target directory
31
+ if context.strategy:
32
+ context.actual_target_dir = context.strategy.determine_target_directory(
33
+ context # Pass the context which has the DeploymentContext interface
34
+ )
35
+ else:
36
+ # Fallback logic if no strategy is set
37
+ if context.target_dir:
38
+ context.actual_target_dir = context.target_dir
39
+ else:
40
+ # Default to user's home .claude/agents directory
41
+ context.actual_target_dir = Path.home() / ".claude" / "agents"
42
+
43
+ # Create target directory if it doesn't exist
44
+ context.actual_target_dir.mkdir(parents=True, exist_ok=True)
45
+
46
+ # Verify directory is writable
47
+ test_file = context.actual_target_dir / ".write_test"
48
+ try:
49
+ test_file.write_text("test")
50
+ test_file.unlink()
51
+ except Exception as e:
52
+ raise PermissionError(
53
+ f"Target directory is not writable: {context.actual_target_dir}"
54
+ )
55
+
56
+ self.logger.info(f"Target directory set up: {context.actual_target_dir}")
57
+
58
+ execution_time = time.time() - start_time
59
+ context.step_timings[self.name] = execution_time
60
+
61
+ return StepResult(
62
+ status=StepStatus.SUCCESS,
63
+ message=f"Target directory set up at {context.actual_target_dir} in {execution_time:.3f}s",
64
+ execution_time=execution_time,
65
+ )
66
+
67
+ except Exception as e:
68
+ execution_time = time.time() - start_time
69
+ context.step_timings[self.name] = execution_time
70
+
71
+ error_msg = f"Failed to set up target directory: {str(e)}"
72
+ self.logger.error(error_msg)
73
+ context.add_error(error_msg)
74
+
75
+ return StepResult(
76
+ status=StepStatus.FAILURE,
77
+ message=error_msg,
78
+ error=e,
79
+ execution_time=execution_time,
80
+ )
81
+
82
+ def can_continue_on_failure(self) -> bool:
83
+ """Target directory setup failure should stop the pipeline."""
84
+ return False
85
+
86
+ def get_dependencies(self) -> list:
87
+ """This step depends on configuration loading."""
88
+ from .configuration_step import ConfigurationLoadStep
89
+
90
+ return [ConfigurationLoadStep]
@@ -0,0 +1,100 @@
1
+ """Validation step for deployment pipeline."""
2
+
3
+ import time
4
+
5
+ from claude_mpm.services.agents.deployment.validation import DeploymentValidator
6
+
7
+ from .base_step import BaseDeploymentStep, StepResult, StepStatus
8
+
9
+
10
+ class ValidationStep(BaseDeploymentStep):
11
+ """Step to validate deployment context and templates."""
12
+
13
+ def __init__(self):
14
+ super().__init__(
15
+ name="Validation",
16
+ description="Validate deployment environment, templates, and configuration",
17
+ )
18
+ self.validator = DeploymentValidator()
19
+
20
+ def execute(self, context) -> StepResult:
21
+ """Execute validation step.
22
+
23
+ Args:
24
+ context: Pipeline context
25
+
26
+ Returns:
27
+ Result of validation
28
+ """
29
+ start_time = time.time()
30
+
31
+ try:
32
+ # Validate deployment context
33
+ validation_result = self.validator.validate_deployment_context(context)
34
+
35
+ # Update context with validation results
36
+ if not validation_result.is_valid:
37
+ for error in validation_result.errors:
38
+ context.add_error(str(error))
39
+
40
+ for warning in validation_result.warnings:
41
+ context.add_warning(str(warning))
42
+
43
+ # Store validation metadata
44
+ context.results["validation"] = validation_result.to_dict()
45
+
46
+ # Calculate execution time
47
+ execution_time = time.time() - start_time
48
+ context.step_timings[self.name] = execution_time
49
+
50
+ # Determine step status
51
+ if not validation_result.is_valid:
52
+ status = StepStatus.FAILURE
53
+ message = f"Validation failed with {validation_result.error_count} errors in {execution_time:.3f}s"
54
+ elif validation_result.has_warnings:
55
+ status = StepStatus.WARNING
56
+ message = f"Validation completed with {validation_result.warning_count} warnings in {execution_time:.3f}s"
57
+ else:
58
+ status = StepStatus.SUCCESS
59
+ message = f"Validation passed successfully in {execution_time:.3f}s"
60
+
61
+ self.logger.info(message)
62
+
63
+ return StepResult(
64
+ status=status, message=message, execution_time=execution_time
65
+ )
66
+
67
+ except Exception as e:
68
+ execution_time = time.time() - start_time
69
+ context.step_timings[self.name] = execution_time
70
+
71
+ error_msg = f"Validation step failed: {str(e)}"
72
+ self.logger.error(error_msg, exc_info=True)
73
+ context.add_error(error_msg)
74
+
75
+ return StepResult(
76
+ status=StepStatus.FAILURE,
77
+ message=error_msg,
78
+ error=e,
79
+ execution_time=execution_time,
80
+ )
81
+
82
+ def can_continue_on_failure(self) -> bool:
83
+ """Validation failures should stop the pipeline.
84
+
85
+ If validation fails, it's not safe to continue with deployment.
86
+
87
+ Returns:
88
+ False - stop pipeline on validation failure
89
+ """
90
+ return False
91
+
92
+ def get_dependencies(self) -> list:
93
+ """This step depends on target directory setup.
94
+
95
+ Returns:
96
+ List of required step classes
97
+ """
98
+ from .target_directory_step import TargetDirectorySetupStep
99
+
100
+ return [TargetDirectorySetupStep]
@@ -0,0 +1,15 @@
1
+ """Agent processing components for deployment.
2
+
3
+ This module provides classes for processing individual agents during deployment,
4
+ including building, validation, and deployment logic.
5
+ """
6
+
7
+ from .agent_deployment_context import AgentDeploymentContext
8
+ from .agent_deployment_result import AgentDeploymentResult
9
+ from .agent_processor import AgentProcessor
10
+
11
+ __all__ = [
12
+ "AgentProcessor",
13
+ "AgentDeploymentContext",
14
+ "AgentDeploymentResult",
15
+ ]
@@ -0,0 +1,98 @@
1
+ """Agent deployment context for individual agent processing."""
2
+
3
+ from dataclasses import dataclass
4
+ from pathlib import Path
5
+ from typing import Any, Dict, Optional
6
+
7
+
8
+ @dataclass
9
+ class AgentDeploymentContext:
10
+ """Context for deploying a single agent.
11
+
12
+ This context contains all the information needed to process
13
+ and deploy a single agent template.
14
+ """
15
+
16
+ # Agent identification
17
+ agent_name: str
18
+ template_file: Path
19
+ target_file: Path
20
+
21
+ # Deployment configuration
22
+ force_rebuild: bool = False
23
+ deployment_mode: str = "update"
24
+
25
+ # Base agent data
26
+ base_agent_data: Optional[Dict[str, Any]] = None
27
+ base_agent_version: Optional[tuple] = None
28
+
29
+ # Target directory
30
+ agents_dir: Path = None
31
+
32
+ # Processing flags
33
+ validate_before_deployment: bool = True
34
+ collect_metrics: bool = True
35
+
36
+ def __post_init__(self):
37
+ """Post-initialization validation."""
38
+ if self.agents_dir is None and self.target_file:
39
+ self.agents_dir = self.target_file.parent
40
+
41
+ if self.agent_name is None and self.template_file:
42
+ self.agent_name = self.template_file.stem
43
+
44
+ if self.target_file is None and self.agents_dir and self.agent_name:
45
+ self.target_file = self.agents_dir / f"{self.agent_name}.md"
46
+
47
+ @classmethod
48
+ def from_template_file(
49
+ cls,
50
+ template_file: Path,
51
+ agents_dir: Path,
52
+ base_agent_data: Dict[str, Any],
53
+ base_agent_version: tuple,
54
+ force_rebuild: bool = False,
55
+ deployment_mode: str = "update",
56
+ ) -> "AgentDeploymentContext":
57
+ """Create context from template file.
58
+
59
+ Args:
60
+ template_file: Agent template file
61
+ agents_dir: Target agents directory
62
+ base_agent_data: Base agent data
63
+ base_agent_version: Base agent version
64
+ force_rebuild: Whether to force rebuild
65
+ deployment_mode: Deployment mode
66
+
67
+ Returns:
68
+ AgentDeploymentContext instance
69
+ """
70
+ agent_name = template_file.stem
71
+ target_file = agents_dir / f"{agent_name}.md"
72
+
73
+ return cls(
74
+ agent_name=agent_name,
75
+ template_file=template_file,
76
+ target_file=target_file,
77
+ force_rebuild=force_rebuild,
78
+ deployment_mode=deployment_mode,
79
+ base_agent_data=base_agent_data,
80
+ base_agent_version=base_agent_version,
81
+ agents_dir=agents_dir,
82
+ )
83
+
84
+ def is_update(self) -> bool:
85
+ """Check if this is an update (target file exists).
86
+
87
+ Returns:
88
+ True if target file exists
89
+ """
90
+ return self.target_file.exists()
91
+
92
+ def is_project_deployment(self) -> bool:
93
+ """Check if this is a project deployment.
94
+
95
+ Returns:
96
+ True if deployment mode is project
97
+ """
98
+ return self.deployment_mode == "project"
@@ -0,0 +1,235 @@
1
+ """Agent deployment result for individual agent processing."""
2
+
3
+ from dataclasses import dataclass, field
4
+ from enum import Enum
5
+ from pathlib import Path
6
+ from typing import Any, Dict, Optional
7
+
8
+
9
+ class AgentDeploymentStatus(Enum):
10
+ """Status of agent deployment."""
11
+
12
+ DEPLOYED = "deployed"
13
+ UPDATED = "updated"
14
+ MIGRATED = "migrated"
15
+ SKIPPED = "skipped"
16
+ FAILED = "failed"
17
+
18
+
19
+ @dataclass
20
+ class AgentDeploymentResult:
21
+ """Result of deploying a single agent.
22
+
23
+ This class encapsulates the result of processing and deploying
24
+ a single agent template.
25
+ """
26
+
27
+ # Agent identification
28
+ agent_name: str
29
+ template_file: Path
30
+ target_file: Path
31
+
32
+ # Deployment status
33
+ status: AgentDeploymentStatus
34
+
35
+ # Timing information
36
+ deployment_time_ms: float = 0.0
37
+ start_time: Optional[float] = None
38
+ end_time: Optional[float] = None
39
+
40
+ # Status details
41
+ reason: Optional[str] = None
42
+ error_message: Optional[str] = None
43
+
44
+ # Flags
45
+ was_update: bool = False
46
+ was_migration: bool = False
47
+ was_skipped: bool = False
48
+
49
+ # Additional metadata
50
+ metadata: Dict[str, Any] = field(default_factory=dict)
51
+
52
+ @classmethod
53
+ def deployed(
54
+ cls,
55
+ agent_name: str,
56
+ template_file: Path,
57
+ target_file: Path,
58
+ deployment_time_ms: float = 0.0,
59
+ ) -> "AgentDeploymentResult":
60
+ """Create a deployed result.
61
+
62
+ Args:
63
+ agent_name: Name of the agent
64
+ template_file: Template file path
65
+ target_file: Target file path
66
+ deployment_time_ms: Deployment time in milliseconds
67
+
68
+ Returns:
69
+ AgentDeploymentResult with deployed status
70
+ """
71
+ return cls(
72
+ agent_name=agent_name,
73
+ template_file=template_file,
74
+ target_file=target_file,
75
+ status=AgentDeploymentStatus.DEPLOYED,
76
+ deployment_time_ms=deployment_time_ms,
77
+ )
78
+
79
+ @classmethod
80
+ def updated(
81
+ cls,
82
+ agent_name: str,
83
+ template_file: Path,
84
+ target_file: Path,
85
+ deployment_time_ms: float = 0.0,
86
+ reason: Optional[str] = None,
87
+ ) -> "AgentDeploymentResult":
88
+ """Create an updated result.
89
+
90
+ Args:
91
+ agent_name: Name of the agent
92
+ template_file: Template file path
93
+ target_file: Target file path
94
+ deployment_time_ms: Deployment time in milliseconds
95
+ reason: Reason for update
96
+
97
+ Returns:
98
+ AgentDeploymentResult with updated status
99
+ """
100
+ return cls(
101
+ agent_name=agent_name,
102
+ template_file=template_file,
103
+ target_file=target_file,
104
+ status=AgentDeploymentStatus.UPDATED,
105
+ deployment_time_ms=deployment_time_ms,
106
+ reason=reason,
107
+ was_update=True,
108
+ )
109
+
110
+ @classmethod
111
+ def migrated(
112
+ cls,
113
+ agent_name: str,
114
+ template_file: Path,
115
+ target_file: Path,
116
+ deployment_time_ms: float = 0.0,
117
+ reason: Optional[str] = None,
118
+ ) -> "AgentDeploymentResult":
119
+ """Create a migrated result.
120
+
121
+ Args:
122
+ agent_name: Name of the agent
123
+ template_file: Template file path
124
+ target_file: Target file path
125
+ deployment_time_ms: Deployment time in milliseconds
126
+ reason: Reason for migration
127
+
128
+ Returns:
129
+ AgentDeploymentResult with migrated status
130
+ """
131
+ return cls(
132
+ agent_name=agent_name,
133
+ template_file=template_file,
134
+ target_file=target_file,
135
+ status=AgentDeploymentStatus.MIGRATED,
136
+ deployment_time_ms=deployment_time_ms,
137
+ reason=reason,
138
+ was_migration=True,
139
+ )
140
+
141
+ @classmethod
142
+ def skipped(
143
+ cls,
144
+ agent_name: str,
145
+ template_file: Path,
146
+ target_file: Path,
147
+ reason: Optional[str] = None,
148
+ ) -> "AgentDeploymentResult":
149
+ """Create a skipped result.
150
+
151
+ Args:
152
+ agent_name: Name of the agent
153
+ template_file: Template file path
154
+ target_file: Target file path
155
+ reason: Reason for skipping
156
+
157
+ Returns:
158
+ AgentDeploymentResult with skipped status
159
+ """
160
+ return cls(
161
+ agent_name=agent_name,
162
+ template_file=template_file,
163
+ target_file=target_file,
164
+ status=AgentDeploymentStatus.SKIPPED,
165
+ reason=reason,
166
+ was_skipped=True,
167
+ )
168
+
169
+ @classmethod
170
+ def failed(
171
+ cls,
172
+ agent_name: str,
173
+ template_file: Path,
174
+ target_file: Path,
175
+ error_message: str,
176
+ deployment_time_ms: float = 0.0,
177
+ ) -> "AgentDeploymentResult":
178
+ """Create a failed result.
179
+
180
+ Args:
181
+ agent_name: Name of the agent
182
+ template_file: Template file path
183
+ target_file: Target file path
184
+ error_message: Error message
185
+ deployment_time_ms: Deployment time in milliseconds
186
+
187
+ Returns:
188
+ AgentDeploymentResult with failed status
189
+ """
190
+ return cls(
191
+ agent_name=agent_name,
192
+ template_file=template_file,
193
+ target_file=target_file,
194
+ status=AgentDeploymentStatus.FAILED,
195
+ deployment_time_ms=deployment_time_ms,
196
+ error_message=error_message,
197
+ )
198
+
199
+ def to_dict(self) -> Dict[str, Any]:
200
+ """Convert result to dictionary.
201
+
202
+ Returns:
203
+ Dictionary representation of the result
204
+ """
205
+ result = {
206
+ "name": self.agent_name,
207
+ "template": str(self.template_file),
208
+ "target": str(self.target_file),
209
+ "status": self.status.value,
210
+ "deployment_time_ms": self.deployment_time_ms,
211
+ }
212
+
213
+ if self.reason:
214
+ result["reason"] = self.reason
215
+
216
+ if self.error_message:
217
+ result["error"] = self.error_message
218
+
219
+ if self.metadata:
220
+ result["metadata"] = self.metadata
221
+
222
+ return result
223
+
224
+ def is_successful(self) -> bool:
225
+ """Check if deployment was successful.
226
+
227
+ Returns:
228
+ True if status is deployed, updated, migrated, or skipped
229
+ """
230
+ return self.status in [
231
+ AgentDeploymentStatus.DEPLOYED,
232
+ AgentDeploymentStatus.UPDATED,
233
+ AgentDeploymentStatus.MIGRATED,
234
+ AgentDeploymentStatus.SKIPPED,
235
+ ]