claude-mpm 3.9.11__py3-none-any.whl → 4.0.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (434) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/__init__.py +2 -2
  3. claude_mpm/__main__.py +3 -2
  4. claude_mpm/agents/__init__.py +85 -79
  5. claude_mpm/agents/agent_loader.py +464 -1003
  6. claude_mpm/agents/agent_loader_integration.py +45 -45
  7. claude_mpm/agents/agents_metadata.py +29 -30
  8. claude_mpm/agents/async_agent_loader.py +156 -138
  9. claude_mpm/agents/base_agent.json +1 -1
  10. claude_mpm/agents/base_agent_loader.py +179 -151
  11. claude_mpm/agents/frontmatter_validator.py +229 -130
  12. claude_mpm/agents/schema/agent_schema.json +1 -1
  13. claude_mpm/agents/system_agent_config.py +213 -147
  14. claude_mpm/agents/templates/__init__.py +13 -13
  15. claude_mpm/agents/templates/code_analyzer.json +2 -2
  16. claude_mpm/agents/templates/data_engineer.json +1 -1
  17. claude_mpm/agents/templates/documentation.json +23 -11
  18. claude_mpm/agents/templates/engineer.json +22 -6
  19. claude_mpm/agents/templates/memory_manager.json +1 -1
  20. claude_mpm/agents/templates/ops.json +2 -2
  21. claude_mpm/agents/templates/project_organizer.json +1 -1
  22. claude_mpm/agents/templates/qa.json +1 -1
  23. claude_mpm/agents/templates/refactoring_engineer.json +222 -0
  24. claude_mpm/agents/templates/research.json +20 -14
  25. claude_mpm/agents/templates/security.json +1 -1
  26. claude_mpm/agents/templates/ticketing.json +2 -2
  27. claude_mpm/agents/templates/version_control.json +1 -1
  28. claude_mpm/agents/templates/web_qa.json +3 -1
  29. claude_mpm/agents/templates/web_ui.json +2 -2
  30. claude_mpm/cli/__init__.py +79 -51
  31. claude_mpm/cli/__main__.py +3 -2
  32. claude_mpm/cli/commands/__init__.py +20 -20
  33. claude_mpm/cli/commands/agents.py +279 -247
  34. claude_mpm/cli/commands/aggregate.py +138 -157
  35. claude_mpm/cli/commands/cleanup.py +147 -147
  36. claude_mpm/cli/commands/config.py +93 -76
  37. claude_mpm/cli/commands/info.py +17 -16
  38. claude_mpm/cli/commands/mcp.py +140 -905
  39. claude_mpm/cli/commands/mcp_command_router.py +139 -0
  40. claude_mpm/cli/commands/mcp_config_commands.py +20 -0
  41. claude_mpm/cli/commands/mcp_install_commands.py +20 -0
  42. claude_mpm/cli/commands/mcp_server_commands.py +175 -0
  43. claude_mpm/cli/commands/mcp_tool_commands.py +34 -0
  44. claude_mpm/cli/commands/memory.py +239 -203
  45. claude_mpm/cli/commands/monitor.py +330 -86
  46. claude_mpm/cli/commands/run.py +380 -429
  47. claude_mpm/cli/commands/run_config_checker.py +160 -0
  48. claude_mpm/cli/commands/socketio_monitor.py +235 -0
  49. claude_mpm/cli/commands/tickets.py +363 -220
  50. claude_mpm/cli/parser.py +24 -1156
  51. claude_mpm/cli/parsers/__init__.py +29 -0
  52. claude_mpm/cli/parsers/agents_parser.py +136 -0
  53. claude_mpm/cli/parsers/base_parser.py +331 -0
  54. claude_mpm/cli/parsers/config_parser.py +85 -0
  55. claude_mpm/cli/parsers/mcp_parser.py +152 -0
  56. claude_mpm/cli/parsers/memory_parser.py +138 -0
  57. claude_mpm/cli/parsers/monitor_parser.py +124 -0
  58. claude_mpm/cli/parsers/run_parser.py +147 -0
  59. claude_mpm/cli/parsers/tickets_parser.py +203 -0
  60. claude_mpm/cli/ticket_cli.py +7 -3
  61. claude_mpm/cli/utils.py +55 -37
  62. claude_mpm/cli_module/__init__.py +6 -6
  63. claude_mpm/cli_module/args.py +188 -140
  64. claude_mpm/cli_module/commands.py +79 -70
  65. claude_mpm/cli_module/migration_example.py +38 -60
  66. claude_mpm/config/__init__.py +32 -25
  67. claude_mpm/config/agent_config.py +151 -119
  68. claude_mpm/config/experimental_features.py +71 -73
  69. claude_mpm/config/paths.py +94 -208
  70. claude_mpm/config/socketio_config.py +84 -73
  71. claude_mpm/constants.py +35 -18
  72. claude_mpm/core/__init__.py +9 -6
  73. claude_mpm/core/agent_name_normalizer.py +68 -71
  74. claude_mpm/core/agent_registry.py +372 -521
  75. claude_mpm/core/agent_session_manager.py +74 -63
  76. claude_mpm/core/base_service.py +116 -87
  77. claude_mpm/core/cache.py +119 -153
  78. claude_mpm/core/claude_runner.py +425 -1120
  79. claude_mpm/core/config.py +263 -168
  80. claude_mpm/core/config_aliases.py +69 -61
  81. claude_mpm/core/config_constants.py +292 -0
  82. claude_mpm/core/constants.py +57 -99
  83. claude_mpm/core/container.py +211 -178
  84. claude_mpm/core/exceptions.py +233 -89
  85. claude_mpm/core/factories.py +92 -54
  86. claude_mpm/core/framework_loader.py +378 -220
  87. claude_mpm/core/hook_manager.py +198 -83
  88. claude_mpm/core/hook_performance_config.py +136 -0
  89. claude_mpm/core/injectable_service.py +61 -55
  90. claude_mpm/core/interactive_session.py +165 -155
  91. claude_mpm/core/interfaces.py +221 -195
  92. claude_mpm/core/lazy.py +96 -96
  93. claude_mpm/core/logger.py +133 -107
  94. claude_mpm/core/logging_config.py +185 -157
  95. claude_mpm/core/minimal_framework_loader.py +20 -15
  96. claude_mpm/core/mixins.py +30 -29
  97. claude_mpm/core/oneshot_session.py +215 -181
  98. claude_mpm/core/optimized_agent_loader.py +134 -138
  99. claude_mpm/core/optimized_startup.py +159 -157
  100. claude_mpm/core/pm_hook_interceptor.py +85 -72
  101. claude_mpm/core/service_registry.py +103 -101
  102. claude_mpm/core/session_manager.py +97 -87
  103. claude_mpm/core/socketio_pool.py +212 -158
  104. claude_mpm/core/tool_access_control.py +58 -51
  105. claude_mpm/core/types.py +46 -24
  106. claude_mpm/core/typing_utils.py +166 -82
  107. claude_mpm/core/unified_agent_registry.py +721 -0
  108. claude_mpm/core/unified_config.py +550 -0
  109. claude_mpm/core/unified_paths.py +549 -0
  110. claude_mpm/dashboard/index.html +1 -1
  111. claude_mpm/dashboard/open_dashboard.py +51 -17
  112. claude_mpm/dashboard/static/built/components/agent-inference.js +2 -0
  113. claude_mpm/dashboard/static/built/components/event-processor.js +2 -0
  114. claude_mpm/dashboard/static/built/components/event-viewer.js +2 -0
  115. claude_mpm/dashboard/static/built/components/export-manager.js +2 -0
  116. claude_mpm/dashboard/static/built/components/file-tool-tracker.js +2 -0
  117. claude_mpm/dashboard/static/built/components/hud-library-loader.js +2 -0
  118. claude_mpm/dashboard/static/built/components/hud-manager.js +2 -0
  119. claude_mpm/dashboard/static/built/components/hud-visualizer.js +2 -0
  120. claude_mpm/dashboard/static/built/components/module-viewer.js +2 -0
  121. claude_mpm/dashboard/static/built/components/session-manager.js +2 -0
  122. claude_mpm/dashboard/static/built/components/socket-manager.js +2 -0
  123. claude_mpm/dashboard/static/built/components/ui-state-manager.js +2 -0
  124. claude_mpm/dashboard/static/built/components/working-directory.js +2 -0
  125. claude_mpm/dashboard/static/built/dashboard.js +2 -0
  126. claude_mpm/dashboard/static/built/socket-client.js +2 -0
  127. claude_mpm/dashboard/static/css/dashboard.css +27 -8
  128. claude_mpm/dashboard/static/dist/components/agent-inference.js +2 -0
  129. claude_mpm/dashboard/static/dist/components/event-processor.js +2 -0
  130. claude_mpm/dashboard/static/dist/components/event-viewer.js +2 -0
  131. claude_mpm/dashboard/static/dist/components/export-manager.js +2 -0
  132. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +2 -0
  133. claude_mpm/dashboard/static/dist/components/hud-library-loader.js +2 -0
  134. claude_mpm/dashboard/static/dist/components/hud-manager.js +2 -0
  135. claude_mpm/dashboard/static/dist/components/hud-visualizer.js +2 -0
  136. claude_mpm/dashboard/static/dist/components/module-viewer.js +2 -0
  137. claude_mpm/dashboard/static/dist/components/session-manager.js +2 -0
  138. claude_mpm/dashboard/static/dist/components/socket-manager.js +2 -0
  139. claude_mpm/dashboard/static/dist/components/ui-state-manager.js +2 -0
  140. claude_mpm/dashboard/static/dist/components/working-directory.js +2 -0
  141. claude_mpm/dashboard/static/dist/dashboard.js +2 -0
  142. claude_mpm/dashboard/static/dist/socket-client.js +2 -0
  143. claude_mpm/dashboard/static/js/components/agent-inference.js +80 -76
  144. claude_mpm/dashboard/static/js/components/event-processor.js +71 -67
  145. claude_mpm/dashboard/static/js/components/event-viewer.js +93 -72
  146. claude_mpm/dashboard/static/js/components/export-manager.js +31 -28
  147. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +110 -96
  148. claude_mpm/dashboard/static/js/components/hud-library-loader.js +11 -11
  149. claude_mpm/dashboard/static/js/components/hud-manager.js +73 -73
  150. claude_mpm/dashboard/static/js/components/hud-visualizer.js +163 -163
  151. claude_mpm/dashboard/static/js/components/module-viewer.js +305 -233
  152. claude_mpm/dashboard/static/js/components/session-manager.js +32 -29
  153. claude_mpm/dashboard/static/js/components/socket-manager.js +27 -20
  154. claude_mpm/dashboard/static/js/components/ui-state-manager.js +21 -18
  155. claude_mpm/dashboard/static/js/components/working-directory.js +74 -71
  156. claude_mpm/dashboard/static/js/dashboard.js +178 -453
  157. claude_mpm/dashboard/static/js/extension-error-handler.js +164 -0
  158. claude_mpm/dashboard/static/js/socket-client.js +133 -53
  159. claude_mpm/dashboard/templates/index.html +40 -50
  160. claude_mpm/experimental/cli_enhancements.py +60 -58
  161. claude_mpm/generators/__init__.py +1 -1
  162. claude_mpm/generators/agent_profile_generator.py +75 -65
  163. claude_mpm/hooks/__init__.py +1 -1
  164. claude_mpm/hooks/base_hook.py +33 -28
  165. claude_mpm/hooks/claude_hooks/__init__.py +1 -1
  166. claude_mpm/hooks/claude_hooks/connection_pool.py +120 -0
  167. claude_mpm/hooks/claude_hooks/event_handlers.py +743 -0
  168. claude_mpm/hooks/claude_hooks/hook_handler.py +415 -1331
  169. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +4 -4
  170. claude_mpm/hooks/claude_hooks/memory_integration.py +221 -0
  171. claude_mpm/hooks/claude_hooks/response_tracking.py +348 -0
  172. claude_mpm/hooks/claude_hooks/tool_analysis.py +230 -0
  173. claude_mpm/hooks/memory_integration_hook.py +140 -100
  174. claude_mpm/hooks/tool_call_interceptor.py +89 -76
  175. claude_mpm/hooks/validation_hooks.py +57 -49
  176. claude_mpm/init.py +145 -121
  177. claude_mpm/models/__init__.py +9 -9
  178. claude_mpm/models/agent_definition.py +33 -23
  179. claude_mpm/models/agent_session.py +228 -200
  180. claude_mpm/scripts/__init__.py +1 -1
  181. claude_mpm/scripts/socketio_daemon.py +192 -75
  182. claude_mpm/scripts/socketio_server_manager.py +328 -0
  183. claude_mpm/scripts/start_activity_logging.py +25 -22
  184. claude_mpm/services/__init__.py +68 -43
  185. claude_mpm/services/agent_capabilities_service.py +271 -0
  186. claude_mpm/services/agents/__init__.py +23 -32
  187. claude_mpm/services/agents/deployment/__init__.py +3 -3
  188. claude_mpm/services/agents/deployment/agent_config_provider.py +310 -0
  189. claude_mpm/services/agents/deployment/agent_configuration_manager.py +359 -0
  190. claude_mpm/services/agents/deployment/agent_definition_factory.py +84 -0
  191. claude_mpm/services/agents/deployment/agent_deployment.py +415 -2113
  192. claude_mpm/services/agents/deployment/agent_discovery_service.py +387 -0
  193. claude_mpm/services/agents/deployment/agent_environment_manager.py +293 -0
  194. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +387 -0
  195. claude_mpm/services/agents/deployment/agent_format_converter.py +453 -0
  196. claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +161 -0
  197. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +345 -495
  198. claude_mpm/services/agents/deployment/agent_metrics_collector.py +279 -0
  199. claude_mpm/services/agents/deployment/agent_restore_handler.py +88 -0
  200. claude_mpm/services/agents/deployment/agent_template_builder.py +406 -0
  201. claude_mpm/services/agents/deployment/agent_validator.py +352 -0
  202. claude_mpm/services/agents/deployment/agent_version_manager.py +313 -0
  203. claude_mpm/services/agents/deployment/agent_versioning.py +6 -9
  204. claude_mpm/services/agents/deployment/agents_directory_resolver.py +79 -0
  205. claude_mpm/services/agents/deployment/async_agent_deployment.py +298 -234
  206. claude_mpm/services/agents/deployment/config/__init__.py +13 -0
  207. claude_mpm/services/agents/deployment/config/deployment_config.py +182 -0
  208. claude_mpm/services/agents/deployment/config/deployment_config_manager.py +200 -0
  209. claude_mpm/services/agents/deployment/deployment_config_loader.py +54 -0
  210. claude_mpm/services/agents/deployment/deployment_type_detector.py +124 -0
  211. claude_mpm/services/agents/deployment/facade/__init__.py +18 -0
  212. claude_mpm/services/agents/deployment/facade/async_deployment_executor.py +159 -0
  213. claude_mpm/services/agents/deployment/facade/deployment_executor.py +73 -0
  214. claude_mpm/services/agents/deployment/facade/deployment_facade.py +270 -0
  215. claude_mpm/services/agents/deployment/facade/sync_deployment_executor.py +178 -0
  216. claude_mpm/services/agents/deployment/interface_adapter.py +227 -0
  217. claude_mpm/services/agents/deployment/lifecycle_health_checker.py +85 -0
  218. claude_mpm/services/agents/deployment/lifecycle_performance_tracker.py +100 -0
  219. claude_mpm/services/agents/deployment/pipeline/__init__.py +32 -0
  220. claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +158 -0
  221. claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +159 -0
  222. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +169 -0
  223. claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +19 -0
  224. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +195 -0
  225. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +119 -0
  226. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +79 -0
  227. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +90 -0
  228. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +100 -0
  229. claude_mpm/services/agents/deployment/processors/__init__.py +15 -0
  230. claude_mpm/services/agents/deployment/processors/agent_deployment_context.py +98 -0
  231. claude_mpm/services/agents/deployment/processors/agent_deployment_result.py +235 -0
  232. claude_mpm/services/agents/deployment/processors/agent_processor.py +258 -0
  233. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +318 -0
  234. claude_mpm/services/agents/deployment/results/__init__.py +13 -0
  235. claude_mpm/services/agents/deployment/results/deployment_metrics.py +200 -0
  236. claude_mpm/services/agents/deployment/results/deployment_result_builder.py +249 -0
  237. claude_mpm/services/agents/deployment/strategies/__init__.py +25 -0
  238. claude_mpm/services/agents/deployment/strategies/base_strategy.py +119 -0
  239. claude_mpm/services/agents/deployment/strategies/project_strategy.py +150 -0
  240. claude_mpm/services/agents/deployment/strategies/strategy_selector.py +117 -0
  241. claude_mpm/services/agents/deployment/strategies/system_strategy.py +116 -0
  242. claude_mpm/services/agents/deployment/strategies/user_strategy.py +137 -0
  243. claude_mpm/services/agents/deployment/system_instructions_deployer.py +108 -0
  244. claude_mpm/services/agents/deployment/validation/__init__.py +19 -0
  245. claude_mpm/services/agents/deployment/validation/agent_validator.py +323 -0
  246. claude_mpm/services/agents/deployment/validation/deployment_validator.py +238 -0
  247. claude_mpm/services/agents/deployment/validation/template_validator.py +299 -0
  248. claude_mpm/services/agents/deployment/validation/validation_result.py +226 -0
  249. claude_mpm/services/agents/loading/__init__.py +2 -2
  250. claude_mpm/services/agents/loading/agent_profile_loader.py +259 -229
  251. claude_mpm/services/agents/loading/base_agent_manager.py +90 -81
  252. claude_mpm/services/agents/loading/framework_agent_loader.py +154 -129
  253. claude_mpm/services/agents/management/__init__.py +2 -2
  254. claude_mpm/services/agents/management/agent_capabilities_generator.py +72 -58
  255. claude_mpm/services/agents/management/agent_management_service.py +209 -156
  256. claude_mpm/services/agents/memory/__init__.py +9 -6
  257. claude_mpm/services/agents/memory/agent_memory_manager.py +218 -1152
  258. claude_mpm/services/agents/memory/agent_persistence_service.py +20 -16
  259. claude_mpm/services/agents/memory/analyzer.py +430 -0
  260. claude_mpm/services/agents/memory/content_manager.py +376 -0
  261. claude_mpm/services/agents/memory/template_generator.py +468 -0
  262. claude_mpm/services/agents/registry/__init__.py +7 -10
  263. claude_mpm/services/agents/registry/deployed_agent_discovery.py +122 -97
  264. claude_mpm/services/agents/registry/modification_tracker.py +351 -285
  265. claude_mpm/services/async_session_logger.py +187 -153
  266. claude_mpm/services/claude_session_logger.py +87 -72
  267. claude_mpm/services/command_handler_service.py +217 -0
  268. claude_mpm/services/communication/__init__.py +3 -2
  269. claude_mpm/services/core/__init__.py +50 -97
  270. claude_mpm/services/core/base.py +60 -53
  271. claude_mpm/services/core/interfaces/__init__.py +188 -0
  272. claude_mpm/services/core/interfaces/agent.py +351 -0
  273. claude_mpm/services/core/interfaces/communication.py +343 -0
  274. claude_mpm/services/core/interfaces/infrastructure.py +413 -0
  275. claude_mpm/services/core/interfaces/service.py +434 -0
  276. claude_mpm/services/core/interfaces.py +19 -944
  277. claude_mpm/services/event_aggregator.py +208 -170
  278. claude_mpm/services/exceptions.py +387 -308
  279. claude_mpm/services/framework_claude_md_generator/__init__.py +75 -79
  280. claude_mpm/services/framework_claude_md_generator/content_assembler.py +69 -60
  281. claude_mpm/services/framework_claude_md_generator/content_validator.py +65 -61
  282. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +68 -49
  283. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +34 -34
  284. claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +25 -22
  285. claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +10 -10
  286. claude_mpm/services/framework_claude_md_generator/section_generators/core_responsibilities.py +4 -3
  287. claude_mpm/services/framework_claude_md_generator/section_generators/delegation_constraints.py +4 -3
  288. claude_mpm/services/framework_claude_md_generator/section_generators/environment_config.py +4 -3
  289. claude_mpm/services/framework_claude_md_generator/section_generators/footer.py +6 -5
  290. claude_mpm/services/framework_claude_md_generator/section_generators/header.py +8 -7
  291. claude_mpm/services/framework_claude_md_generator/section_generators/orchestration_principles.py +4 -3
  292. claude_mpm/services/framework_claude_md_generator/section_generators/role_designation.py +6 -5
  293. claude_mpm/services/framework_claude_md_generator/section_generators/subprocess_validation.py +9 -8
  294. claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +4 -3
  295. claude_mpm/services/framework_claude_md_generator/section_generators/troubleshooting.py +5 -4
  296. claude_mpm/services/framework_claude_md_generator/section_manager.py +28 -27
  297. claude_mpm/services/framework_claude_md_generator/version_manager.py +30 -28
  298. claude_mpm/services/hook_service.py +106 -114
  299. claude_mpm/services/infrastructure/__init__.py +7 -5
  300. claude_mpm/services/infrastructure/context_preservation.py +233 -199
  301. claude_mpm/services/infrastructure/daemon_manager.py +279 -0
  302. claude_mpm/services/infrastructure/logging.py +83 -76
  303. claude_mpm/services/infrastructure/monitoring.py +547 -404
  304. claude_mpm/services/mcp_gateway/__init__.py +30 -13
  305. claude_mpm/services/mcp_gateway/config/__init__.py +2 -2
  306. claude_mpm/services/mcp_gateway/config/config_loader.py +61 -56
  307. claude_mpm/services/mcp_gateway/config/config_schema.py +50 -41
  308. claude_mpm/services/mcp_gateway/config/configuration.py +82 -75
  309. claude_mpm/services/mcp_gateway/core/__init__.py +13 -20
  310. claude_mpm/services/mcp_gateway/core/base.py +80 -67
  311. claude_mpm/services/mcp_gateway/core/exceptions.py +60 -46
  312. claude_mpm/services/mcp_gateway/core/interfaces.py +87 -84
  313. claude_mpm/services/mcp_gateway/main.py +287 -137
  314. claude_mpm/services/mcp_gateway/registry/__init__.py +1 -1
  315. claude_mpm/services/mcp_gateway/registry/service_registry.py +97 -94
  316. claude_mpm/services/mcp_gateway/registry/tool_registry.py +135 -126
  317. claude_mpm/services/mcp_gateway/server/__init__.py +2 -2
  318. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +105 -110
  319. claude_mpm/services/mcp_gateway/server/stdio_handler.py +105 -107
  320. claude_mpm/services/mcp_gateway/server/stdio_server.py +691 -0
  321. claude_mpm/services/mcp_gateway/tools/__init__.py +4 -2
  322. claude_mpm/services/mcp_gateway/tools/base_adapter.py +109 -119
  323. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +283 -215
  324. claude_mpm/services/mcp_gateway/tools/hello_world.py +122 -120
  325. claude_mpm/services/mcp_gateway/tools/ticket_tools.py +652 -0
  326. claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +606 -0
  327. claude_mpm/services/memory/__init__.py +2 -2
  328. claude_mpm/services/memory/builder.py +451 -362
  329. claude_mpm/services/memory/cache/__init__.py +2 -2
  330. claude_mpm/services/memory/cache/shared_prompt_cache.py +232 -194
  331. claude_mpm/services/memory/cache/simple_cache.py +107 -93
  332. claude_mpm/services/memory/indexed_memory.py +195 -193
  333. claude_mpm/services/memory/optimizer.py +267 -234
  334. claude_mpm/services/memory/router.py +571 -263
  335. claude_mpm/services/memory_hook_service.py +237 -0
  336. claude_mpm/services/port_manager.py +575 -0
  337. claude_mpm/services/project/__init__.py +3 -3
  338. claude_mpm/services/project/analyzer.py +451 -305
  339. claude_mpm/services/project/registry.py +262 -240
  340. claude_mpm/services/recovery_manager.py +287 -231
  341. claude_mpm/services/response_tracker.py +87 -67
  342. claude_mpm/services/runner_configuration_service.py +587 -0
  343. claude_mpm/services/session_management_service.py +304 -0
  344. claude_mpm/services/socketio/__init__.py +4 -4
  345. claude_mpm/services/socketio/client_proxy.py +174 -0
  346. claude_mpm/services/socketio/handlers/__init__.py +3 -3
  347. claude_mpm/services/socketio/handlers/base.py +44 -30
  348. claude_mpm/services/socketio/handlers/connection.py +166 -64
  349. claude_mpm/services/socketio/handlers/file.py +123 -108
  350. claude_mpm/services/socketio/handlers/git.py +607 -373
  351. claude_mpm/services/socketio/handlers/hook.py +185 -0
  352. claude_mpm/services/socketio/handlers/memory.py +4 -4
  353. claude_mpm/services/socketio/handlers/project.py +4 -4
  354. claude_mpm/services/socketio/handlers/registry.py +53 -38
  355. claude_mpm/services/socketio/server/__init__.py +18 -0
  356. claude_mpm/services/socketio/server/broadcaster.py +252 -0
  357. claude_mpm/services/socketio/server/core.py +399 -0
  358. claude_mpm/services/socketio/server/main.py +323 -0
  359. claude_mpm/services/socketio_client_manager.py +160 -133
  360. claude_mpm/services/socketio_server.py +36 -1885
  361. claude_mpm/services/subprocess_launcher_service.py +316 -0
  362. claude_mpm/services/system_instructions_service.py +258 -0
  363. claude_mpm/services/ticket_manager.py +19 -533
  364. claude_mpm/services/utility_service.py +285 -0
  365. claude_mpm/services/version_control/__init__.py +18 -21
  366. claude_mpm/services/version_control/branch_strategy.py +20 -10
  367. claude_mpm/services/version_control/conflict_resolution.py +37 -13
  368. claude_mpm/services/version_control/git_operations.py +52 -21
  369. claude_mpm/services/version_control/semantic_versioning.py +92 -53
  370. claude_mpm/services/version_control/version_parser.py +145 -125
  371. claude_mpm/services/version_service.py +270 -0
  372. claude_mpm/storage/__init__.py +2 -2
  373. claude_mpm/storage/state_storage.py +177 -181
  374. claude_mpm/ticket_wrapper.py +2 -2
  375. claude_mpm/utils/__init__.py +2 -2
  376. claude_mpm/utils/agent_dependency_loader.py +453 -243
  377. claude_mpm/utils/config_manager.py +157 -118
  378. claude_mpm/utils/console.py +1 -1
  379. claude_mpm/utils/dependency_cache.py +102 -107
  380. claude_mpm/utils/dependency_manager.py +52 -47
  381. claude_mpm/utils/dependency_strategies.py +131 -96
  382. claude_mpm/utils/environment_context.py +110 -102
  383. claude_mpm/utils/error_handler.py +75 -55
  384. claude_mpm/utils/file_utils.py +80 -67
  385. claude_mpm/utils/framework_detection.py +12 -11
  386. claude_mpm/utils/import_migration_example.py +12 -60
  387. claude_mpm/utils/imports.py +48 -45
  388. claude_mpm/utils/path_operations.py +100 -93
  389. claude_mpm/utils/robust_installer.py +172 -164
  390. claude_mpm/utils/session_logging.py +30 -23
  391. claude_mpm/utils/subprocess_utils.py +99 -61
  392. claude_mpm/validation/__init__.py +1 -1
  393. claude_mpm/validation/agent_validator.py +151 -111
  394. claude_mpm/validation/frontmatter_validator.py +92 -71
  395. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/METADATA +90 -22
  396. claude_mpm-4.0.4.dist-info/RECORD +417 -0
  397. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/entry_points.txt +1 -0
  398. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/licenses/LICENSE +1 -1
  399. claude_mpm/cli/commands/run_guarded.py +0 -511
  400. claude_mpm/config/memory_guardian_config.py +0 -325
  401. claude_mpm/config/memory_guardian_yaml.py +0 -335
  402. claude_mpm/core/config_paths.py +0 -150
  403. claude_mpm/core/memory_aware_runner.py +0 -353
  404. claude_mpm/dashboard/static/js/dashboard-original.js +0 -4134
  405. claude_mpm/deployment_paths.py +0 -261
  406. claude_mpm/hooks/claude_hooks/hook_handler_fixed.py +0 -454
  407. claude_mpm/models/state_models.py +0 -433
  408. claude_mpm/services/agent/__init__.py +0 -24
  409. claude_mpm/services/agent/deployment.py +0 -2548
  410. claude_mpm/services/agent/management.py +0 -598
  411. claude_mpm/services/agent/registry.py +0 -813
  412. claude_mpm/services/agents/registry/agent_registry.py +0 -813
  413. claude_mpm/services/communication/socketio.py +0 -1935
  414. claude_mpm/services/communication/websocket.py +0 -479
  415. claude_mpm/services/framework_claude_md_generator.py +0 -624
  416. claude_mpm/services/health_monitor.py +0 -893
  417. claude_mpm/services/infrastructure/graceful_degradation.py +0 -616
  418. claude_mpm/services/infrastructure/health_monitor.py +0 -775
  419. claude_mpm/services/infrastructure/memory_dashboard.py +0 -479
  420. claude_mpm/services/infrastructure/memory_guardian.py +0 -944
  421. claude_mpm/services/infrastructure/restart_protection.py +0 -642
  422. claude_mpm/services/infrastructure/state_manager.py +0 -774
  423. claude_mpm/services/mcp_gateway/manager.py +0 -334
  424. claude_mpm/services/optimized_hook_service.py +0 -542
  425. claude_mpm/services/project_analyzer.py +0 -864
  426. claude_mpm/services/project_registry.py +0 -608
  427. claude_mpm/services/standalone_socketio_server.py +0 -1300
  428. claude_mpm/services/ticket_manager_di.py +0 -318
  429. claude_mpm/services/ticketing_service_original.py +0 -510
  430. claude_mpm/utils/paths.py +0 -395
  431. claude_mpm/utils/platform_memory.py +0 -524
  432. claude_mpm-3.9.11.dist-info/RECORD +0 -306
  433. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/WHEEL +0 -0
  434. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,164 @@
1
+ /**
2
+ * Browser Extension Error Handler
3
+ *
4
+ * WHY: Browser extensions (like password managers, ad blockers, etc.) often inject
5
+ * scripts that use Chrome's message passing API. When these extensions have bugs
6
+ * or async handlers that don't properly respond, they generate console errors.
7
+ *
8
+ * This module prevents those external errors from affecting our dashboard and
9
+ * provides clean error handling for known browser extension issues.
10
+ *
11
+ * DESIGN DECISION: Rather than trying to fix third-party extension bugs, we:
12
+ * 1. Detect and suppress known harmless extension errors
13
+ * 2. Log them separately for debugging if needed
14
+ * 3. Ensure our dashboard remains functional regardless of extension conflicts
15
+ */
16
+
17
+ class ExtensionErrorHandler {
18
+ constructor() {
19
+ this.extensionErrors = [];
20
+ this.suppressedPatterns = [
21
+ // Chrome extension message passing error
22
+ /listener indicated an asynchronous response.*message channel closed/i,
23
+ // Other common extension errors
24
+ /Extension context invalidated/i,
25
+ /Unchecked runtime\.lastError/i,
26
+ /Cannot access contents of url.*Extension/i,
27
+ /Blocked a frame with origin.*from accessing a cross-origin frame/i
28
+ ];
29
+
30
+ this.setupErrorHandling();
31
+ }
32
+
33
+ /**
34
+ * Set up global error handling to catch and suppress extension errors
35
+ */
36
+ setupErrorHandling() {
37
+ // Store original console.error
38
+ const originalConsoleError = console.error;
39
+
40
+ // Override console.error to filter extension errors
41
+ console.error = (...args) => {
42
+ const errorString = args.join(' ');
43
+
44
+ // Check if this is a known extension error
45
+ if (this.isExtensionError(errorString)) {
46
+ // Log to our internal list for debugging
47
+ this.extensionErrors.push({
48
+ timestamp: new Date().toISOString(),
49
+ error: errorString,
50
+ suppressed: true
51
+ });
52
+
53
+ // Optionally log with a prefix if debug mode is enabled
54
+ if (window.DEBUG_EXTENSION_ERRORS) {
55
+ originalConsoleError.call(console, '[SUPPRESSED EXTENSION ERROR]:', ...args);
56
+ }
57
+
58
+ // Don't propagate the error
59
+ return;
60
+ }
61
+
62
+ // Pass through non-extension errors
63
+ originalConsoleError.call(console, ...args);
64
+ };
65
+
66
+ // Handle uncaught promise rejections that might come from extensions
67
+ window.addEventListener('unhandledrejection', (event) => {
68
+ const errorString = event.reason?.toString() || '';
69
+
70
+ if (this.isExtensionError(errorString)) {
71
+ // Prevent the default error handling
72
+ event.preventDefault();
73
+
74
+ this.extensionErrors.push({
75
+ timestamp: new Date().toISOString(),
76
+ error: errorString,
77
+ type: 'unhandled_rejection',
78
+ suppressed: true
79
+ });
80
+
81
+ if (window.DEBUG_EXTENSION_ERRORS) {
82
+ console.warn('[SUPPRESSED EXTENSION REJECTION]:', event.reason);
83
+ }
84
+ }
85
+ });
86
+
87
+ // Add a global message event listener with proper error handling
88
+ // This prevents our app from being affected by misbehaving extensions
89
+ window.addEventListener('message', (event) => {
90
+ // Only process messages from our own origin
91
+ if (event.origin !== window.location.origin) {
92
+ return;
93
+ }
94
+
95
+ // Add timeout protection for any async operations
96
+ if (event.data && event.data.requiresResponse) {
97
+ const timeoutId = setTimeout(() => {
98
+ console.warn('Message handler timeout - no response sent');
99
+ }, 5000);
100
+
101
+ // Clear timeout when response is sent
102
+ if (event.ports && event.ports[0]) {
103
+ const originalPostMessage = event.ports[0].postMessage;
104
+ event.ports[0].postMessage = function(...args) {
105
+ clearTimeout(timeoutId);
106
+ return originalPostMessage.apply(this, args);
107
+ };
108
+ }
109
+ }
110
+ });
111
+ }
112
+
113
+ /**
114
+ * Check if an error string matches known extension error patterns
115
+ * @param {string} errorString - The error message to check
116
+ * @returns {boolean} - True if this is a known extension error
117
+ */
118
+ isExtensionError(errorString) {
119
+ return this.suppressedPatterns.some(pattern => pattern.test(errorString));
120
+ }
121
+
122
+ /**
123
+ * Get suppressed extension errors for debugging
124
+ * @returns {Array} - List of suppressed errors
125
+ */
126
+ getSuppressedErrors() {
127
+ return this.extensionErrors;
128
+ }
129
+
130
+ /**
131
+ * Clear the suppressed errors list
132
+ */
133
+ clearSuppressedErrors() {
134
+ this.extensionErrors = [];
135
+ }
136
+
137
+ /**
138
+ * Enable or disable debug logging of extension errors
139
+ * @param {boolean} enabled - Whether to enable debug logging
140
+ */
141
+ setDebugMode(enabled) {
142
+ window.DEBUG_EXTENSION_ERRORS = enabled;
143
+
144
+ if (enabled) {
145
+ console.log('Extension error debug mode enabled. Suppressed errors will be logged with [SUPPRESSED] prefix.');
146
+ console.log('Current suppressed errors:', this.getSuppressedErrors());
147
+ } else {
148
+ console.log('Extension error debug mode disabled. Extension errors will be silently suppressed.');
149
+ }
150
+ }
151
+ }
152
+
153
+ // Create and export singleton instance
154
+ const extensionErrorHandler = new ExtensionErrorHandler();
155
+
156
+ // Add to window for debugging access
157
+ window.extensionErrorHandler = extensionErrorHandler;
158
+
159
+ // Export for ES6 modules
160
+ export { ExtensionErrorHandler, extensionErrorHandler };
161
+ export default extensionErrorHandler;
162
+
163
+ // Log initialization
164
+ console.log('Extension error handler initialized. Use window.extensionErrorHandler.setDebugMode(true) to see suppressed errors.');
@@ -3,6 +3,9 @@
3
3
  * Handles WebSocket connections and event processing
4
4
  */
5
5
 
6
+ // Access the global io from window object in ES6 module context
7
+ const io = window.io;
8
+
6
9
  class SocketClient {
7
10
  constructor() {
8
11
  this.socket = null;
@@ -13,16 +16,16 @@ class SocketClient {
13
16
  error: [],
14
17
  event: []
15
18
  };
16
-
19
+
17
20
  // Connection state
18
21
  this.isConnected = false;
19
22
  this.isConnecting = false;
20
-
23
+
21
24
  // Event processing
22
25
  this.events = [];
23
26
  this.sessions = new Map();
24
27
  this.currentSessionId = null;
25
-
28
+
26
29
  // Start periodic status check as fallback mechanism
27
30
  this.startStatusCheckFallback();
28
31
  }
@@ -35,7 +38,7 @@ class SocketClient {
35
38
  // Store the port for later use
36
39
  this.port = port;
37
40
  const url = `http://localhost:${port}`;
38
-
41
+
39
42
  // Prevent multiple simultaneous connections
40
43
  if (this.socket && (this.socket.connected || this.socket.connecting)) {
41
44
  console.log('Already connected or connecting, disconnecting first...');
@@ -44,7 +47,7 @@ class SocketClient {
44
47
  setTimeout(() => this.doConnect(url), 100);
45
48
  return;
46
49
  }
47
-
50
+
48
51
  this.doConnect(url);
49
52
  }
50
53
 
@@ -54,9 +57,17 @@ class SocketClient {
54
57
  */
55
58
  doConnect(url) {
56
59
  console.log(`Connecting to Socket.IO server at ${url}`);
60
+
61
+ // Check if io is available
62
+ if (typeof io === 'undefined') {
63
+ console.error('Socket.IO library not loaded! Make sure socket.io.min.js is loaded before this script.');
64
+ this.notifyConnectionStatus('Socket.IO library not loaded', 'error');
65
+ return;
66
+ }
67
+
57
68
  this.isConnecting = true;
58
69
  this.notifyConnectionStatus('Connecting...', 'connecting');
59
-
70
+
60
71
  this.socket = io(url, {
61
72
  autoConnect: true,
62
73
  reconnection: true,
@@ -67,7 +78,7 @@ class SocketClient {
67
78
  forceNew: true,
68
79
  transports: ['websocket', 'polling']
69
80
  });
70
-
81
+
71
82
  this.setupSocketHandlers();
72
83
  }
73
84
 
@@ -80,55 +91,55 @@ class SocketClient {
80
91
  this.isConnected = true;
81
92
  this.isConnecting = false;
82
93
  this.notifyConnectionStatus('Connected', 'connected');
83
-
94
+
84
95
  // Emit connect callback
85
- this.connectionCallbacks.connect.forEach(callback =>
96
+ this.connectionCallbacks.connect.forEach(callback =>
86
97
  callback(this.socket.id)
87
98
  );
88
-
99
+
89
100
  this.requestStatus();
90
101
  // History is now automatically sent by server on connection
91
102
  // No need to explicitly request it
92
103
  });
93
-
104
+
94
105
  this.socket.on('disconnect', (reason) => {
95
106
  console.log('Disconnected from server:', reason);
96
107
  this.isConnected = false;
97
108
  this.isConnecting = false;
98
109
  this.notifyConnectionStatus(`Disconnected: ${reason}`, 'disconnected');
99
-
110
+
100
111
  // Emit disconnect callback
101
- this.connectionCallbacks.disconnect.forEach(callback =>
112
+ this.connectionCallbacks.disconnect.forEach(callback =>
102
113
  callback(reason)
103
114
  );
104
115
  });
105
-
116
+
106
117
  this.socket.on('connect_error', (error) => {
107
118
  console.error('Connection error:', error);
108
119
  this.isConnecting = false;
109
120
  const errorMsg = error.message || error.description || 'Unknown error';
110
121
  this.notifyConnectionStatus(`Connection Error: ${errorMsg}`, 'disconnected');
111
-
122
+
112
123
  // Add error event
113
124
  this.addEvent({
114
125
  type: 'connection.error',
115
126
  timestamp: new Date().toISOString(),
116
127
  data: { error: errorMsg, url: this.socket.io.uri }
117
128
  });
118
-
129
+
119
130
  // Emit error callback
120
- this.connectionCallbacks.error.forEach(callback =>
131
+ this.connectionCallbacks.error.forEach(callback =>
121
132
  callback(errorMsg)
122
133
  );
123
134
  });
124
135
 
125
136
  // Primary event handler - this is what the server actually emits
126
137
  this.socket.on('claude_event', (data) => {
127
- console.log('Received claude_event:', data);
128
-
138
+ // console.log('Received claude_event:', data);
139
+
129
140
  // Transform event to match expected format
130
141
  const transformedEvent = this.transformEvent(data);
131
- console.log('Transformed event:', transformedEvent);
142
+ // console.log('Transformed event:', transformedEvent);
132
143
  this.addEvent(transformedEvent);
133
144
  });
134
145
 
@@ -310,7 +321,7 @@ class SocketClient {
310
321
  this.sessions.clear();
311
322
  this.notifyEventUpdate();
312
323
  }
313
-
324
+
314
325
  /**
315
326
  * Clear events and request fresh history from server
316
327
  * @param {Object} options - History request options (same as requestHistory)
@@ -329,7 +340,7 @@ class SocketClient {
329
340
  if (!sessionId) {
330
341
  return this.events;
331
342
  }
332
- return this.events.filter(event =>
343
+ return this.events.filter(event =>
333
344
  event.data && event.data.session_id === sessionId
334
345
  );
335
346
  }
@@ -360,10 +371,10 @@ class SocketClient {
360
371
  */
361
372
  notifyConnectionStatus(status, type) {
362
373
  console.log(`SocketClient: Connection status changed to '${status}' (${type})`);
363
-
374
+
364
375
  // Direct DOM update - immediate and reliable
365
376
  this.updateConnectionStatusDOM(status, type);
366
-
377
+
367
378
  // Also dispatch custom event for other modules
368
379
  document.dispatchEvent(new CustomEvent('socketConnectionStatus', {
369
380
  detail: { status, type }
@@ -380,10 +391,10 @@ class SocketClient {
380
391
  if (statusElement) {
381
392
  // Update the text content while preserving the indicator span
382
393
  statusElement.innerHTML = `<span>●</span> ${status}`;
383
-
394
+
384
395
  // Update the CSS class for styling
385
396
  statusElement.className = `status-badge status-${type}`;
386
-
397
+
387
398
  console.log(`SocketClient: Direct DOM update - status: '${status}' (${type})`);
388
399
  } else {
389
400
  console.warn('SocketClient: Could not find connection-status element in DOM');
@@ -394,10 +405,10 @@ class SocketClient {
394
405
  * Notify event update
395
406
  */
396
407
  notifyEventUpdate() {
397
- this.connectionCallbacks.event.forEach(callback =>
408
+ this.connectionCallbacks.event.forEach(callback =>
398
409
  callback(this.events, this.sessions)
399
410
  );
400
-
411
+
401
412
  // Also dispatch custom event
402
413
  document.dispatchEvent(new CustomEvent('socketEventUpdate', {
403
414
  detail: { events: this.events, sessions: this.sessions }
@@ -422,39 +433,104 @@ class SocketClient {
422
433
  * @returns {Object} Transformed event
423
434
  */
424
435
  transformEvent(eventData) {
425
- // Handle the actual event structure sent from hook_handler.py:
426
- // { type: 'hook.pre_tool', timestamp: '...', data: { tool_name: '...', agent_type: '...', etc } }
427
-
428
- if (!eventData || !eventData.type) {
429
- return eventData; // Return as-is if malformed
436
+ // Handle multiple event structures:
437
+ // 1. Hook events: { type: 'hook.pre_tool', timestamp: '...', data: {...} }
438
+ // 2. Legacy events: { event: 'TestStart', timestamp: '...', ... }
439
+ // 3. Standard events: { type: 'session', subtype: 'started', ... }
440
+
441
+ if (!eventData) {
442
+ return eventData; // Return as-is if null/undefined
430
443
  }
431
444
 
432
- const type = eventData.type;
433
445
  let transformedEvent = { ...eventData };
434
446
 
435
- // Transform 'hook.subtype' format to separate type and subtype
436
- if (type.startsWith('hook.')) {
437
- const subtype = type.substring(5); // Remove 'hook.' prefix
438
- transformedEvent.type = 'hook';
439
- transformedEvent.subtype = subtype;
447
+ // Handle legacy format with 'event' field but no 'type'
448
+ if (!eventData.type && eventData.event) {
449
+ // Map common event names to proper type/subtype
450
+ const eventName = eventData.event;
451
+
452
+ // Check for known event patterns
453
+ if (eventName === 'TestStart' || eventName === 'TestEnd') {
454
+ transformedEvent.type = 'test';
455
+ transformedEvent.subtype = eventName.toLowerCase().replace('test', '');
456
+ } else if (eventName === 'SubagentStart' || eventName === 'SubagentStop') {
457
+ transformedEvent.type = 'subagent';
458
+ transformedEvent.subtype = eventName.toLowerCase().replace('subagent', '');
459
+ } else if (eventName === 'ToolCall') {
460
+ transformedEvent.type = 'tool';
461
+ transformedEvent.subtype = 'call';
462
+ } else if (eventName === 'UserPrompt') {
463
+ transformedEvent.type = 'hook';
464
+ transformedEvent.subtype = 'user_prompt';
465
+ } else {
466
+ // Generic fallback for unknown event names
467
+ transformedEvent.type = 'system';
468
+ transformedEvent.subtype = eventName.toLowerCase();
469
+ }
470
+
471
+ // Remove the 'event' field to avoid confusion
472
+ delete transformedEvent.event;
473
+ }
474
+ // Handle standard format with 'type' field
475
+ else if (eventData.type) {
476
+ const type = eventData.type;
477
+
478
+ // Transform 'hook.subtype' format to separate type and subtype
479
+ if (type.startsWith('hook.')) {
480
+ const subtype = type.substring(5); // Remove 'hook.' prefix
481
+ transformedEvent.type = 'hook';
482
+ transformedEvent.subtype = subtype;
483
+ }
484
+ // Transform other dotted types like 'session.started' -> type: 'session', subtype: 'started'
485
+ else if (type.includes('.')) {
486
+ const [mainType, ...subtypeParts] = type.split('.');
487
+ transformedEvent.type = mainType;
488
+ transformedEvent.subtype = subtypeParts.join('.');
489
+ }
440
490
  }
441
- // Transform other dotted types like 'session.started' -> type: 'session', subtype: 'started'
442
- else if (type.includes('.')) {
443
- const [mainType, ...subtypeParts] = type.split('.');
444
- transformedEvent.type = mainType;
445
- transformedEvent.subtype = subtypeParts.join('.');
491
+ // If no type and no event field, mark as unknown
492
+ else {
493
+ transformedEvent.type = 'unknown';
494
+ transformedEvent.subtype = '';
495
+ }
496
+
497
+ // Store original event name for display purposes (before any transformation)
498
+ if (!eventData.type && eventData.event) {
499
+ transformedEvent.originalEventName = eventData.event;
500
+ } else if (eventData.type) {
501
+ transformedEvent.originalEventName = eventData.type;
446
502
  }
447
503
 
448
504
  // Extract and flatten data fields to top level for dashboard compatibility
449
505
  // The dashboard expects fields like tool_name, agent_type, etc. at the top level
450
506
  if (eventData.data && typeof eventData.data === 'object') {
451
- // Copy all data fields to the top level
507
+ // Protected fields that should never be overwritten by data fields
508
+ const protectedFields = ['type', 'subtype', 'timestamp', 'id', 'event', 'event_type', 'originalEventName'];
509
+
510
+ // Copy all data fields to the top level, except protected ones
452
511
  Object.keys(eventData.data).forEach(key => {
453
- // Only copy if the key doesn't already exist at top level
454
- if (!(key in transformedEvent)) {
512
+ // Only copy if not a protected field
513
+ if (!protectedFields.includes(key)) {
455
514
  transformedEvent[key] = eventData.data[key];
515
+ } else {
516
+ // Log warning if data field would overwrite a protected field
517
+ console.warn(`Protected field '${key}' in data object was not copied to top level to preserve event structure`);
456
518
  }
457
519
  });
520
+
521
+ // Keep the original data object for backward compatibility
522
+ transformedEvent.data = eventData.data;
523
+ }
524
+
525
+ // Debug logging for tool events
526
+ if (transformedEvent.type === 'hook' && (transformedEvent.subtype === 'pre_tool' || transformedEvent.subtype === 'post_tool')) {
527
+ console.log('Transformed tool event:', {
528
+ type: transformedEvent.type,
529
+ subtype: transformedEvent.subtype,
530
+ tool_name: transformedEvent.tool_name,
531
+ has_data: !!transformedEvent.data,
532
+ keys: Object.keys(transformedEvent).filter(k => k !== 'data')
533
+ });
458
534
  }
459
535
 
460
536
  return transformedEvent;
@@ -481,7 +557,7 @@ class SocketClient {
481
557
  setInterval(() => {
482
558
  this.checkAndUpdateStatus();
483
559
  }, 2000);
484
-
560
+
485
561
  // Initial check after DOM is ready
486
562
  if (document.readyState === 'loading') {
487
563
  document.addEventListener('DOMContentLoaded', () => {
@@ -498,7 +574,7 @@ class SocketClient {
498
574
  checkAndUpdateStatus() {
499
575
  let actualStatus = 'Disconnected';
500
576
  let actualType = 'disconnected';
501
-
577
+
502
578
  if (this.socket) {
503
579
  if (this.socket.connected) {
504
580
  actualStatus = 'Connected';
@@ -516,14 +592,14 @@ class SocketClient {
516
592
  this.isConnecting = false;
517
593
  }
518
594
  }
519
-
595
+
520
596
  // Check if UI needs updating
521
597
  const statusElement = document.getElementById('connection-status');
522
598
  if (statusElement) {
523
599
  const currentText = statusElement.textContent.replace('●', '').trim();
524
600
  const currentClass = statusElement.className;
525
601
  const expectedClass = `status-badge status-${actualType}`;
526
-
602
+
527
603
  // Update if status text or class doesn't match
528
604
  if (currentText !== actualStatus || currentClass !== expectedClass) {
529
605
  console.log(`SocketClient: Fallback update - was '${currentText}' (${currentClass}), now '${actualStatus}' (${expectedClass})`);
@@ -533,5 +609,9 @@ class SocketClient {
533
609
  }
534
610
  }
535
611
 
536
- // Export for use in other modules
537
- window.SocketClient = SocketClient;
612
+ // ES6 Module export
613
+ export { SocketClient };
614
+ export default SocketClient;
615
+
616
+ // Backward compatibility - keep window export for non-module usage
617
+ window.SocketClient = SocketClient;