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
@@ -14,24 +14,20 @@ WHY this approach:
14
14
  """
15
15
 
16
16
  import asyncio
17
+ import importlib.metadata
17
18
  import json
18
- import logging
19
19
  import socket
20
- import sys
21
20
  import threading
22
21
  import time
23
22
  from datetime import datetime
24
- from typing import Dict, Any, Optional, List, Tuple
25
- import importlib.metadata
26
- from claude_mpm.core.constants import (
27
- NetworkConfig,
28
- TimeoutConfig,
29
- PerformanceConfig
30
- )
23
+ from typing import Any, Dict, List, Optional, Tuple
24
+
25
+ from claude_mpm.core.constants import NetworkConfig, PerformanceConfig, TimeoutConfig
31
26
 
32
27
  try:
33
28
  import requests
34
29
  import socketio
30
+
35
31
  DEPENDENCIES_AVAILABLE = True
36
32
  except ImportError:
37
33
  DEPENDENCIES_AVAILABLE = False
@@ -42,7 +38,7 @@ from ..core.logger import get_logger
42
38
 
43
39
  # Get claude-mpm version for compatibility checking
44
40
  try:
45
- CLAUDE_MPM_VERSION = importlib.metadata.version('claude-mpm')
41
+ CLAUDE_MPM_VERSION = importlib.metadata.version("claude-mpm")
46
42
  except Exception:
47
43
  # Fallback for development
48
44
  CLAUDE_MPM_VERSION = "0.7.0-dev"
@@ -50,7 +46,7 @@ except Exception:
50
46
 
51
47
  class ServerInfo:
52
48
  """Information about a detected Socket.IO server."""
53
-
49
+
54
50
  def __init__(self, host: str, port: int, response_data: Dict[str, Any]):
55
51
  self.host = host
56
52
  self.port = port
@@ -58,24 +54,30 @@ class ServerInfo:
58
54
  self.server_id = response_data.get("server_id", "unknown")
59
55
  self.socketio_version = response_data.get("socketio_version", "unknown")
60
56
  self.features = response_data.get("features", [])
61
- self.supported_client_versions = response_data.get("supported_client_versions", [])
57
+ self.supported_client_versions = response_data.get(
58
+ "supported_client_versions", []
59
+ )
62
60
  self.compatibility_matrix = response_data.get("compatibility_matrix", {})
63
61
  self.detected_at = datetime.utcnow()
64
-
62
+
65
63
  @property
66
64
  def url(self) -> str:
67
65
  return f"http://{self.host}:{self.port}"
68
-
69
- def is_compatible(self, client_version: str = CLAUDE_MPM_VERSION) -> Tuple[bool, List[str]]:
66
+
67
+ def is_compatible(
68
+ self, client_version: str = CLAUDE_MPM_VERSION
69
+ ) -> Tuple[bool, List[str]]:
70
70
  """Check if this server is compatible with the client version."""
71
71
  warnings = []
72
-
72
+
73
73
  try:
74
74
  # Simple version comparison - in production use proper semver
75
75
  if client_version >= "0.7.0":
76
76
  return True, warnings
77
77
  else:
78
- warnings.append(f"Client version {client_version} may not be fully supported")
78
+ warnings.append(
79
+ f"Client version {client_version} may not be fully supported"
80
+ )
79
81
  return False, warnings
80
82
  except Exception as e:
81
83
  warnings.append(f"Could not parse version: {e}")
@@ -84,43 +86,45 @@ class ServerInfo:
84
86
 
85
87
  class SocketIOClientManager:
86
88
  """Manages Socket.IO client connections with server discovery and compatibility checking."""
87
-
89
+
88
90
  def __init__(self, client_version: str = CLAUDE_MPM_VERSION):
89
91
  self.client_version = client_version
90
92
  self.logger = get_logger("socketio_client_manager")
91
-
93
+
92
94
  # Connection state
93
95
  self.current_server: Optional[ServerInfo] = None
94
96
  self.client: Optional[socketio.AsyncClient] = None
95
97
  self.connected = False
96
98
  self.connection_thread: Optional[threading.Thread] = None
97
99
  self.running = False
98
-
100
+
99
101
  # Server discovery
100
102
  self.known_servers: Dict[str, ServerInfo] = {}
101
103
  self.last_discovery = None
102
-
104
+
103
105
  if not DEPENDENCIES_AVAILABLE:
104
106
  self.logger.warning("Socket.IO client dependencies not available")
105
-
106
- def discover_servers(self, ports: List[int] = None, hosts: List[str] = None) -> List[ServerInfo]:
107
+
108
+ def discover_servers(
109
+ self, ports: List[int] = None, hosts: List[str] = None
110
+ ) -> List[ServerInfo]:
107
111
  """Discover available Socket.IO servers.
108
-
112
+
109
113
  Args:
110
114
  ports: List of ports to check (default: [8765, 8766, 8767])
111
115
  hosts: List of hosts to check (default: ['localhost', '127.0.0.1'])
112
-
116
+
113
117
  Returns:
114
118
  List of discovered server info objects
115
119
  """
116
120
  if not DEPENDENCIES_AVAILABLE:
117
121
  return []
118
-
122
+
119
123
  ports = ports or [8765, 8766, 8767]
120
- hosts = hosts or ['localhost', '127.0.0.1']
121
-
124
+ hosts = hosts or ["localhost", "127.0.0.1"]
125
+
122
126
  discovered = []
123
-
127
+
124
128
  for host in hosts:
125
129
  for port in ports:
126
130
  try:
@@ -129,102 +133,112 @@ class SocketIOClientManager:
129
133
  s.settimeout(0.5)
130
134
  if s.connect_ex((host, port)) != 0:
131
135
  continue
132
-
136
+
133
137
  # Try to get server version info
134
138
  try:
135
139
  response = requests.get(
136
140
  f"http://{host}:{port}/version",
137
- timeout=TimeoutConfig.QUICK_TIMEOUT
141
+ timeout=TimeoutConfig.QUICK_TIMEOUT,
138
142
  )
139
143
  if response.status_code == 200:
140
144
  data = response.json()
141
145
  server_info = ServerInfo(host, port, data)
142
146
  discovered.append(server_info)
143
-
147
+
144
148
  server_key = f"{host}:{port}"
145
149
  self.known_servers[server_key] = server_info
146
-
147
- self.logger.info(f"🔍 Discovered server: {server_info.server_id} "
148
- f"v{server_info.server_version} at {server_info.url}")
149
-
150
+
151
+ self.logger.info(
152
+ f"🔍 Discovered server: {server_info.server_id} "
153
+ f"v{server_info.server_version} at {server_info.url}"
154
+ )
155
+
150
156
  except requests.RequestException:
151
157
  # Not a standalone server, might be another service
152
158
  continue
153
-
159
+
154
160
  except Exception as e:
155
161
  self.logger.debug(f"Error checking {host}:{port}: {e}")
156
162
  continue
157
-
163
+
158
164
  self.last_discovery = datetime.utcnow()
159
165
  return discovered
160
-
161
- def find_best_server(self, discovered_servers: List[ServerInfo] = None) -> Optional[ServerInfo]:
166
+
167
+ def find_best_server(
168
+ self, discovered_servers: List[ServerInfo] = None
169
+ ) -> Optional[ServerInfo]:
162
170
  """Find the best compatible server from discovered servers."""
163
171
  if discovered_servers is None:
164
172
  discovered_servers = self.discover_servers()
165
-
173
+
166
174
  if not discovered_servers:
167
175
  return None
168
-
176
+
169
177
  # Score servers based on compatibility and features
170
178
  scored_servers = []
171
-
179
+
172
180
  for server in discovered_servers:
173
181
  compatible, warnings = server.is_compatible(self.client_version)
174
-
182
+
175
183
  if not compatible:
176
- self.logger.debug(f"Server {server.server_id} not compatible: {warnings}")
184
+ self.logger.debug(
185
+ f"Server {server.server_id} not compatible: {warnings}"
186
+ )
177
187
  continue
178
-
188
+
179
189
  # Simple scoring: newer versions and more features get higher scores
180
190
  score = 0
181
-
191
+
182
192
  # Version scoring (basic semantic versioning)
183
193
  try:
184
- version_parts = server.server_version.split('.')
194
+ version_parts = server.server_version.split(".")
185
195
  score += int(version_parts[0]) * PerformanceConfig.VERSION_SCORE_MAJOR
186
196
  score += int(version_parts[1]) * PerformanceConfig.VERSION_SCORE_MINOR
187
197
  score += int(version_parts[2]) * PerformanceConfig.VERSION_SCORE_PATCH
188
198
  except (ValueError, IndexError):
189
199
  pass
190
-
200
+
191
201
  # Feature scoring
192
202
  score += len(server.features) * 5
193
-
203
+
194
204
  scored_servers.append((score, server))
195
-
205
+
196
206
  if not scored_servers:
197
207
  self.logger.warning("No compatible servers found")
198
208
  return None
199
-
209
+
200
210
  # Return highest scored server
201
211
  scored_servers.sort(key=lambda x: x[0], reverse=True)
202
212
  best_server = scored_servers[0][1]
203
-
204
- self.logger.info(f"🎯 Selected best server: {best_server.server_id} "
205
- f"v{best_server.server_version} at {best_server.url}")
206
-
213
+
214
+ self.logger.info(
215
+ f"🎯 Selected best server: {best_server.server_id} "
216
+ f"v{best_server.server_version} at {best_server.url}"
217
+ )
218
+
207
219
  return best_server
208
-
220
+
209
221
  async def connect_to_server(self, server_info: ServerInfo) -> bool:
210
222
  """Connect to a specific server with compatibility verification."""
211
223
  if not DEPENDENCIES_AVAILABLE:
212
224
  return False
213
-
225
+
214
226
  try:
215
227
  # Perform compatibility check via HTTP first
216
228
  compat_response = requests.post(
217
229
  f"{server_info.url}/compatibility",
218
230
  json={"client_version": self.client_version},
219
- timeout=TimeoutConfig.FILE_OPERATION_TIMEOUT
231
+ timeout=TimeoutConfig.FILE_OPERATION_TIMEOUT,
220
232
  )
221
-
233
+
222
234
  if compat_response.status_code == 200:
223
235
  compatibility = compat_response.json()
224
236
  if not compatibility.get("compatible", False):
225
- self.logger.error(f"Server {server_info.server_id} rejected client version {self.client_version}")
237
+ self.logger.error(
238
+ f"Server {server_info.server_id} rejected client version {self.client_version}"
239
+ )
226
240
  return False
227
-
241
+
228
242
  # Create Socket.IO client
229
243
  self.client = socketio.AsyncClient(
230
244
  reconnection=True,
@@ -233,26 +247,28 @@ class SocketIOClientManager:
233
247
  reconnection_delay_max=5,
234
248
  randomization_factor=0.5,
235
249
  logger=False,
236
- engineio_logger=False
250
+ engineio_logger=False,
237
251
  )
238
-
252
+
239
253
  # Setup event handlers
240
254
  self._setup_client_event_handlers()
241
-
255
+
242
256
  # Connect with authentication
243
257
  auth = {
244
258
  "claude_mpm_version": self.client_version,
245
- "client_id": f"claude-mpm-{time.time()}"
259
+ "client_id": f"claude-mpm-{time.time()}",
246
260
  }
247
-
261
+
248
262
  await self.client.connect(server_info.url, auth=auth)
249
-
263
+
250
264
  self.current_server = server_info
251
265
  self.connected = True
252
-
253
- self.logger.info(f"✅ Connected to server {server_info.server_id} at {server_info.url}")
266
+
267
+ self.logger.info(
268
+ f"✅ Connected to server {server_info.server_id} at {server_info.url}"
269
+ )
254
270
  return True
255
-
271
+
256
272
  except Exception as e:
257
273
  self.logger.error(f"❌ Failed to connect to server {server_info.url}: {e}")
258
274
  if self.client:
@@ -262,79 +278,85 @@ class SocketIOClientManager:
262
278
  pass
263
279
  self.client = None
264
280
  return False
265
-
281
+
266
282
  def _setup_client_event_handlers(self):
267
283
  """Setup event handlers for the Socket.IO client."""
268
-
284
+
269
285
  @self.client.event
270
286
  async def connect():
271
287
  self.logger.info("🔗 Socket.IO client connected")
272
288
  self.connected = True
273
-
289
+
274
290
  @self.client.event
275
291
  async def disconnect():
276
292
  self.logger.info("🔌 Socket.IO client disconnected")
277
293
  self.connected = False
278
-
294
+
279
295
  @self.client.event
280
296
  async def connection_ack(data):
281
297
  self.logger.info("🤝 Received connection acknowledgment")
282
298
  compatibility = data.get("compatibility", {})
283
299
  if not compatibility.get("compatible", True):
284
- self.logger.warning(f"⚠️ Server compatibility warning: {compatibility.get('warnings', [])}")
285
-
300
+ self.logger.warning(
301
+ f"⚠️ Server compatibility warning: {compatibility.get('warnings', [])}"
302
+ )
303
+
286
304
  @self.client.event
287
305
  async def compatibility_warning(data):
288
306
  self.logger.warning(f"⚠️ Server compatibility warning: {data}")
289
-
307
+
290
308
  @self.client.event
291
309
  async def server_status(data):
292
- self.logger.debug(f"📊 Server status: {data.get('clients_connected', 0)} clients")
293
-
310
+ self.logger.debug(
311
+ f"📊 Server status: {data.get('clients_connected', 0)} clients"
312
+ )
313
+
294
314
  @self.client.event
295
315
  async def claude_event(data):
296
316
  """Handle events broadcasted from other clients."""
297
317
  event_type = data.get("type", "unknown")
298
318
  self.logger.debug(f"📥 Received claude_event: {event_type}")
299
-
319
+
300
320
  async def emit_event(self, event_type: str, data: Dict[str, Any]) -> bool:
301
321
  """Emit an event to the connected server."""
302
322
  if not self.connected or not self.client:
303
323
  return False
304
-
324
+
305
325
  try:
306
326
  event_data = {
307
327
  "type": event_type,
308
328
  "timestamp": datetime.utcnow().isoformat() + "Z",
309
329
  "data": data,
310
- "client_version": self.client_version
330
+ "client_version": self.client_version,
311
331
  }
312
-
313
- await self.client.emit('claude_event', event_data)
332
+
333
+ await self.client.emit("claude_event", event_data)
314
334
  self.logger.debug(f"📤 Emitted event: {event_type}")
315
335
  return True
316
-
336
+
317
337
  except Exception as e:
318
338
  self.logger.error(f"❌ Failed to emit event {event_type}: {e}")
319
339
  return False
320
-
340
+
321
341
  def start_connection_manager(self):
322
342
  """Start the connection manager in a background thread."""
323
343
  if self.running:
324
344
  return
325
-
345
+
326
346
  self.running = True
327
- self.connection_thread = threading.Thread(target=self._run_connection_manager, daemon=True)
347
+ self.connection_thread = threading.Thread(
348
+ target=self._run_connection_manager, daemon=True
349
+ )
328
350
  self.connection_thread.start()
329
351
  self.logger.info("🚀 Connection manager started")
330
-
352
+
331
353
  def stop_connection_manager(self):
332
354
  """Stop the connection manager."""
333
355
  self.running = False
334
-
356
+
335
357
  if self.connection_thread:
336
358
  self.connection_thread.join(timeout=TimeoutConfig.THREAD_JOIN_TIMEOUT)
337
-
359
+
338
360
  if self.client and self.connected:
339
361
  try:
340
362
  # Disconnect from server
@@ -343,64 +365,70 @@ class SocketIOClientManager:
343
365
  loop.close()
344
366
  except Exception as e:
345
367
  self.logger.error(f"Error disconnecting client: {e}")
346
-
368
+
347
369
  self.logger.info("🛑 Connection manager stopped")
348
-
370
+
349
371
  def _run_connection_manager(self):
350
372
  """Run the connection manager loop."""
351
373
  loop = asyncio.new_event_loop()
352
374
  asyncio.set_event_loop(loop)
353
-
375
+
354
376
  try:
355
377
  loop.run_until_complete(self._connection_manager_loop())
356
378
  except Exception as e:
357
379
  self.logger.error(f"Connection manager error: {e}")
358
380
  finally:
359
381
  loop.close()
360
-
382
+
361
383
  async def _connection_manager_loop(self):
362
384
  """Main connection manager loop."""
363
385
  connection_attempts = 0
364
386
  max_connection_attempts = 3
365
-
387
+
366
388
  while self.running:
367
389
  try:
368
390
  if not self.connected:
369
391
  if connection_attempts < max_connection_attempts:
370
392
  # Try to find and connect to a server
371
393
  best_server = self.find_best_server()
372
-
394
+
373
395
  if best_server:
374
396
  success = await self.connect_to_server(best_server)
375
397
  if success:
376
- connection_attempts = 0 # Reset on successful connection
398
+ connection_attempts = (
399
+ 0 # Reset on successful connection
400
+ )
377
401
  else:
378
402
  connection_attempts += 1
379
403
  else:
380
- self.logger.info("📡 No Socket.IO servers found, will retry...")
404
+ self.logger.info(
405
+ "📡 No Socket.IO servers found, will retry..."
406
+ )
381
407
  connection_attempts += 1
382
408
  else:
383
409
  # Too many failed attempts, wait longer
384
- self.logger.warning(f"⏳ Max connection attempts reached, waiting 30s...")
410
+ self.logger.warning(
411
+ f"⏳ Max connection attempts reached, waiting 30s..."
412
+ )
385
413
  await asyncio.sleep(30)
386
414
  connection_attempts = 0 # Reset after longer wait
387
-
415
+
388
416
  # Periodic health check
389
417
  if self.connected and self.client:
390
418
  try:
391
- await self.client.emit('ping')
419
+ await self.client.emit("ping")
392
420
  except Exception as e:
393
421
  self.logger.warning(f"Health check failed: {e}")
394
422
  self.connected = False
395
-
423
+
396
424
  await asyncio.sleep(5) # Check every 5 seconds
397
-
425
+
398
426
  except Exception as e:
399
427
  self.logger.error(f"Error in connection manager loop: {e}")
400
428
  await asyncio.sleep(5)
401
-
429
+
402
430
  # Compatibility methods for existing WebSocket server interface
403
-
431
+
404
432
  def broadcast_event(self, event_type: str, data: Dict[str, Any]):
405
433
  """Legacy compatibility method for broadcasting events."""
406
434
  if self.connected:
@@ -411,41 +439,40 @@ class SocketIOClientManager:
411
439
  loop.close()
412
440
  except Exception as e:
413
441
  self.logger.error(f"Error broadcasting event {event_type}: {e}")
414
-
442
+
415
443
  def session_started(self, session_id: str, launch_method: str, working_dir: str):
416
444
  """Compatibility method for session start events."""
417
- self.broadcast_event("session.start", {
418
- "session_id": session_id,
419
- "launch_method": launch_method,
420
- "working_directory": working_dir
421
- })
422
-
445
+ self.broadcast_event(
446
+ "session.start",
447
+ {
448
+ "session_id": session_id,
449
+ "launch_method": launch_method,
450
+ "working_directory": working_dir,
451
+ },
452
+ )
453
+
423
454
  def session_ended(self):
424
455
  """Compatibility method for session end events."""
425
456
  self.broadcast_event("session.end", {})
426
-
427
- def claude_status_changed(self, status: str, pid: Optional[int] = None, message: str = ""):
457
+
458
+ def claude_status_changed(
459
+ self, status: str, pid: Optional[int] = None, message: str = ""
460
+ ):
428
461
  """Compatibility method for Claude status events."""
429
- self.broadcast_event("claude.status", {
430
- "status": status,
431
- "pid": pid,
432
- "message": message
433
- })
434
-
462
+ self.broadcast_event(
463
+ "claude.status", {"status": status, "pid": pid, "message": message}
464
+ )
465
+
435
466
  def agent_delegated(self, agent: str, task: str, status: str = "started"):
436
467
  """Compatibility method for agent delegation events."""
437
- self.broadcast_event("agent.delegation", {
438
- "agent": agent,
439
- "task": task,
440
- "status": status
441
- })
442
-
468
+ self.broadcast_event(
469
+ "agent.delegation", {"agent": agent, "task": task, "status": status}
470
+ )
471
+
443
472
  def todo_updated(self, todos: List[Dict[str, Any]]):
444
473
  """Compatibility method for todo update events."""
445
- self.broadcast_event("todo.update", {
446
- "todos": todos
447
- })
448
-
474
+ self.broadcast_event("todo.update", {"todos": todos})
475
+
449
476
  @property
450
477
  def running_status(self) -> bool:
451
478
  """Compatibility property."""
@@ -476,4 +503,4 @@ def stop_client_manager():
476
503
  global _client_manager
477
504
  if _client_manager:
478
505
  _client_manager.stop_connection_manager()
479
- _client_manager = None
506
+ _client_manager = None