claude-mpm 3.9.11__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 (419) 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 +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 +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 +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 -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 +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 +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/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 +233 -199
  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 +30 -13
  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 +13 -20
  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 +87 -84
  298. claude_mpm/services/mcp_gateway/main.py +287 -137
  299. claude_mpm/services/mcp_gateway/registry/__init__.py +1 -1
  300. claude_mpm/services/mcp_gateway/registry/service_registry.py +97 -94
  301. claude_mpm/services/mcp_gateway/registry/tool_registry.py +135 -126
  302. claude_mpm/services/mcp_gateway/server/__init__.py +2 -2
  303. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +105 -110
  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 +109 -119
  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 +19 -533
  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 +2 -2
  358. claude_mpm/storage/state_storage.py +177 -181
  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.11.dist-info → claude_mpm-4.0.3.dist-info}/METADATA +27 -1
  381. claude_mpm-4.0.3.dist-info/RECORD +402 -0
  382. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.3.dist-info}/entry_points.txt +1 -0
  383. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.3.dist-info}/licenses/LICENSE +1 -1
  384. claude_mpm/cli/commands/run_guarded.py +0 -511
  385. claude_mpm/config/memory_guardian_config.py +0 -325
  386. claude_mpm/config/memory_guardian_yaml.py +0 -335
  387. claude_mpm/core/config_paths.py +0 -150
  388. claude_mpm/core/memory_aware_runner.py +0 -353
  389. claude_mpm/dashboard/static/js/dashboard-original.js +0 -4134
  390. claude_mpm/deployment_paths.py +0 -261
  391. claude_mpm/hooks/claude_hooks/hook_handler_fixed.py +0 -454
  392. claude_mpm/models/state_models.py +0 -433
  393. claude_mpm/services/agent/__init__.py +0 -24
  394. claude_mpm/services/agent/deployment.py +0 -2548
  395. claude_mpm/services/agent/management.py +0 -598
  396. claude_mpm/services/agent/registry.py +0 -813
  397. claude_mpm/services/agents/registry/agent_registry.py +0 -813
  398. claude_mpm/services/communication/socketio.py +0 -1935
  399. claude_mpm/services/communication/websocket.py +0 -479
  400. claude_mpm/services/framework_claude_md_generator.py +0 -624
  401. claude_mpm/services/health_monitor.py +0 -893
  402. claude_mpm/services/infrastructure/graceful_degradation.py +0 -616
  403. claude_mpm/services/infrastructure/health_monitor.py +0 -775
  404. claude_mpm/services/infrastructure/memory_dashboard.py +0 -479
  405. claude_mpm/services/infrastructure/memory_guardian.py +0 -944
  406. claude_mpm/services/infrastructure/restart_protection.py +0 -642
  407. claude_mpm/services/infrastructure/state_manager.py +0 -774
  408. claude_mpm/services/mcp_gateway/manager.py +0 -334
  409. claude_mpm/services/optimized_hook_service.py +0 -542
  410. claude_mpm/services/project_analyzer.py +0 -864
  411. claude_mpm/services/project_registry.py +0 -608
  412. claude_mpm/services/standalone_socketio_server.py +0 -1300
  413. claude_mpm/services/ticket_manager_di.py +0 -318
  414. claude_mpm/services/ticketing_service_original.py +0 -510
  415. claude_mpm/utils/paths.py +0 -395
  416. claude_mpm/utils/platform_memory.py +0 -524
  417. claude_mpm-3.9.11.dist-info/RECORD +0 -306
  418. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.3.dist-info}/WHEEL +0 -0
  419. {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.3.dist-info}/top_level.txt +0 -0
@@ -7,26 +7,26 @@ class EventViewer {
7
7
  constructor(containerId, socketClient) {
8
8
  this.container = document.getElementById(containerId);
9
9
  this.socketClient = socketClient;
10
-
10
+
11
11
  // State
12
12
  this.events = [];
13
13
  this.filteredEvents = [];
14
14
  this.selectedEventIndex = -1;
15
15
  this.filteredEventElements = [];
16
16
  this.autoScroll = true;
17
-
17
+
18
18
  // Filters
19
19
  this.searchFilter = '';
20
20
  this.typeFilter = '';
21
21
  this.sessionFilter = '';
22
-
22
+
23
23
  // Event type tracking
24
24
  this.eventTypeCount = {};
25
25
  this.availableEventTypes = new Set();
26
26
  this.errorCount = 0;
27
27
  this.eventsThisMinute = 0;
28
28
  this.lastMinute = new Date().getMinutes();
29
-
29
+
30
30
  this.init();
31
31
  }
32
32
 
@@ -36,7 +36,7 @@ class EventViewer {
36
36
  init() {
37
37
  this.setupEventHandlers();
38
38
  this.setupKeyboardNavigation();
39
-
39
+
40
40
  // Subscribe to socket events
41
41
  this.socketClient.onEventUpdate((events, sessions) => {
42
42
  // Ensure we always have a valid events array
@@ -87,7 +87,7 @@ class EventViewer {
87
87
 
88
88
  // Calculate new index
89
89
  let newIndex = this.selectedEventIndex + direction;
90
-
90
+
91
91
  // Wrap around
92
92
  if (newIndex >= this.filteredEventElements.length) {
93
93
  newIndex = 0;
@@ -107,7 +107,7 @@ class EventViewer {
107
107
  console.warn('EventViewer: events array is not initialized, using empty array');
108
108
  this.events = [];
109
109
  }
110
-
110
+
111
111
  this.filteredEvents = this.events.filter(event => {
112
112
  // Search filter
113
113
  if (this.searchFilter) {
@@ -116,7 +116,7 @@ class EventViewer {
116
116
  event.subtype || '',
117
117
  JSON.stringify(event.data || {})
118
118
  ].join(' ').toLowerCase();
119
-
119
+
120
120
  if (!searchableText.includes(this.searchFilter)) {
121
121
  return false;
122
122
  }
@@ -161,7 +161,7 @@ class EventViewer {
161
161
  console.warn('EventViewer: events array is not initialized in updateEventTypeDropdown');
162
162
  this.events = [];
163
163
  }
164
-
164
+
165
165
  this.events.forEach(event => {
166
166
  if (event.type && event.type.trim() !== '') {
167
167
  // Combine type and subtype if subtype exists, otherwise just use type
@@ -173,7 +173,7 @@ class EventViewer {
173
173
  // Check if event types have changed
174
174
  const currentTypes = Array.from(eventTypes).sort();
175
175
  const previousTypes = Array.from(this.availableEventTypes).sort();
176
-
176
+
177
177
  if (JSON.stringify(currentTypes) === JSON.stringify(previousTypes)) {
178
178
  return; // No change needed
179
179
  }
@@ -224,8 +224,8 @@ class EventViewer {
224
224
  if (this.filteredEvents.length === 0) {
225
225
  eventsList.innerHTML = `
226
226
  <div class="no-events">
227
- ${this.events.length === 0 ?
228
- 'Connect to Socket.IO server to see events...' :
227
+ ${this.events.length === 0 ?
228
+ 'Connect to Socket.IO server to see events...' :
229
229
  'No events match current filters...'}
230
230
  </div>
231
231
  `;
@@ -237,16 +237,16 @@ class EventViewer {
237
237
  const timestamp = new Date(event.timestamp).toLocaleTimeString();
238
238
  const eventClass = event.type ? `event-${event.type}` : 'event-default';
239
239
  const isSelected = index === this.selectedEventIndex;
240
-
240
+
241
241
  // Get main content and timestamp separately
242
242
  const mainContent = this.formatSingleRowEventContent(event);
243
-
243
+
244
244
  // Check if this is an Edit/MultiEdit tool event and add diff viewer
245
245
  const diffViewer = this.createInlineEditDiffViewer(event, index);
246
-
246
+
247
247
  return `
248
- <div class="event-item single-row ${eventClass} ${isSelected ? 'selected' : ''}"
249
- onclick="eventViewer.showEventDetails(${index})"
248
+ <div class="event-item single-row ${eventClass} ${isSelected ? 'selected' : ''}"
249
+ onclick="eventViewer.showEventDetails(${index})"
250
250
  data-index="${index}">
251
251
  <span class="event-single-row-content">
252
252
  <span class="event-content-main">${mainContent}</span>
@@ -258,12 +258,12 @@ class EventViewer {
258
258
  }).join('');
259
259
 
260
260
  eventsList.innerHTML = html;
261
-
261
+
262
262
  // Update filtered elements reference
263
263
  this.filteredEventElements = Array.from(eventsList.querySelectorAll('.event-item'));
264
264
 
265
265
  // Update Dashboard navigation items if we're in the events tab
266
- if (window.dashboard && window.dashboard.currentTab === 'events' &&
266
+ if (window.dashboard && window.dashboard.currentTab === 'events' &&
267
267
  window.dashboard.tabNavigation && window.dashboard.tabNavigation.events) {
268
268
  window.dashboard.tabNavigation.events.items = this.filteredEventElements;
269
269
  }
@@ -364,40 +364,40 @@ class EventViewer {
364
364
  formatHookEvent(event) {
365
365
  const data = event.data;
366
366
  const eventType = data.event_type || event.subtype || 'unknown';
367
-
367
+
368
368
  // Format based on specific hook event type
369
369
  switch (eventType) {
370
370
  case 'user_prompt':
371
371
  const prompt = data.prompt_text || data.prompt_preview || '';
372
372
  const truncated = prompt.length > 80 ? prompt.substring(0, 80) + '...' : prompt;
373
373
  return `<strong>User Prompt:</strong> ${truncated || 'No prompt text'}`;
374
-
374
+
375
375
  case 'pre_tool':
376
376
  const toolName = data.tool_name || 'Unknown tool';
377
377
  const operation = data.operation_type || 'operation';
378
378
  return `<strong>Pre-Tool (${operation}):</strong> ${toolName}`;
379
-
379
+
380
380
  case 'post_tool':
381
381
  const postToolName = data.tool_name || 'Unknown tool';
382
382
  const status = data.success ? 'success' : data.status || 'failed';
383
383
  const duration = data.duration_ms ? ` (${data.duration_ms}ms)` : '';
384
384
  return `<strong>Post-Tool (${status}):</strong> ${postToolName}${duration}`;
385
-
385
+
386
386
  case 'notification':
387
387
  const notifType = data.notification_type || 'notification';
388
388
  const message = data.message_preview || data.message || 'No message';
389
389
  return `<strong>Notification (${notifType}):</strong> ${message}`;
390
-
390
+
391
391
  case 'stop':
392
392
  const reason = data.reason || 'unknown';
393
393
  const stopType = data.stop_type || 'normal';
394
394
  return `<strong>Stop (${stopType}):</strong> ${reason}`;
395
-
395
+
396
396
  case 'subagent_stop':
397
397
  const agentType = data.agent_type || 'unknown agent';
398
398
  const stopReason = data.reason || 'unknown';
399
399
  return `<strong>Subagent Stop (${agentType}):</strong> ${stopReason}`;
400
-
400
+
401
401
  default:
402
402
  // Fallback to original logic for unknown hook types
403
403
  const hookName = data.hook_name || data.name || data.event_type || 'Unknown';
@@ -458,12 +458,12 @@ class EventViewer {
458
458
  formatSingleRowEventContent(event) {
459
459
  const eventType = this.formatEventType(event);
460
460
  const data = event.data || {};
461
-
461
+
462
462
  // Extract event details for different event types
463
463
  let eventDetails = '';
464
464
  let category = '';
465
465
  let action = '';
466
-
466
+
467
467
  switch (event.type) {
468
468
  case 'hook':
469
469
  // Hook events: extract tool name and hook type
@@ -473,7 +473,7 @@ class EventViewer {
473
473
  category = this.getEventCategory(event);
474
474
  eventDetails = `${hookDisplayName} (${category}): ${toolName}`;
475
475
  break;
476
-
476
+
477
477
  case 'agent':
478
478
  // Agent events
479
479
  const agentName = event.subagent_type || data.subagent_type || 'PM';
@@ -481,14 +481,14 @@ class EventViewer {
481
481
  category = 'agent_operations';
482
482
  eventDetails = `${agentName} ${agentAction}`;
483
483
  break;
484
-
484
+
485
485
  case 'todo':
486
486
  // Todo events
487
487
  const todoCount = data.todos ? data.todos.length : 0;
488
488
  category = 'task_management';
489
489
  eventDetails = `TodoWrite (${todoCount} items)`;
490
490
  break;
491
-
491
+
492
492
  case 'memory':
493
493
  // Memory events
494
494
  const operation = data.operation || 'unknown';
@@ -496,28 +496,28 @@ class EventViewer {
496
496
  category = 'memory_operations';
497
497
  eventDetails = `${operation} ${key}`;
498
498
  break;
499
-
499
+
500
500
  case 'session':
501
501
  // Session events
502
502
  const sessionAction = event.subtype || 'unknown';
503
503
  category = 'session_management';
504
504
  eventDetails = `Session ${sessionAction}`;
505
505
  break;
506
-
506
+
507
507
  case 'claude':
508
508
  // Claude events
509
509
  const claudeAction = event.subtype || 'interaction';
510
510
  category = 'claude_interactions';
511
511
  eventDetails = `Claude ${claudeAction}`;
512
512
  break;
513
-
513
+
514
514
  default:
515
515
  // Generic events
516
516
  category = 'general';
517
517
  eventDetails = event.type || 'Unknown Event';
518
518
  break;
519
519
  }
520
-
520
+
521
521
  // Return formatted string: "type.subtype DisplayName (category): Details"
522
522
  return `${eventType} ${eventDetails}`;
523
523
  }
@@ -537,7 +537,7 @@ class EventViewer {
537
537
  'subagent_stop': 'Subagent-Stop',
538
538
  'notification': 'Notification'
539
539
  };
540
-
540
+
541
541
  return hookNames[hookType] || hookType.replace('_', '-');
542
542
  }
543
543
 
@@ -549,7 +549,7 @@ class EventViewer {
549
549
  getEventCategory(event) {
550
550
  const data = event.data || {};
551
551
  const toolName = event.tool_name || data.tool_name || '';
552
-
552
+
553
553
  // Categorize based on tool type
554
554
  if (['Read', 'Write', 'Edit', 'MultiEdit'].includes(toolName)) {
555
555
  return 'file_operations';
@@ -562,7 +562,7 @@ class EventViewer {
562
562
  } else if (event.subtype === 'stop' || event.subtype === 'subagent_stop') {
563
563
  return 'session_control';
564
564
  }
565
-
565
+
566
566
  return 'general';
567
567
  }
568
568
 
@@ -580,10 +580,10 @@ class EventViewer {
580
580
 
581
581
  // Update selection
582
582
  this.selectedEventIndex = index;
583
-
583
+
584
584
  // Get the selected event
585
585
  const event = this.filteredEvents[index];
586
-
586
+
587
587
  // Coordinate with Dashboard unified navigation system
588
588
  if (window.dashboard) {
589
589
  // Update the dashboard's navigation state for events tab
@@ -594,12 +594,12 @@ class EventViewer {
594
594
  window.dashboard.selectCard('events', index, 'event', event);
595
595
  }
596
596
  }
597
-
597
+
598
598
  // Update visual selection (this will be handled by Dashboard.updateCardSelectionUI())
599
599
  this.filteredEventElements.forEach((el, i) => {
600
600
  el.classList.toggle('selected', i === index);
601
601
  });
602
-
602
+
603
603
  // Notify other components about selection
604
604
  document.dispatchEvent(new CustomEvent('eventSelected', {
605
605
  detail: { event, index }
@@ -608,9 +608,9 @@ class EventViewer {
608
608
  // Scroll to selected event if not visible
609
609
  const selectedElement = this.filteredEventElements[index];
610
610
  if (selectedElement) {
611
- selectedElement.scrollIntoView({
612
- behavior: 'smooth',
613
- block: 'nearest'
611
+ selectedElement.scrollIntoView({
612
+ behavior: 'smooth',
613
+ block: 'nearest'
614
614
  });
615
615
  }
616
616
  }
@@ -623,7 +623,7 @@ class EventViewer {
623
623
  this.filteredEventElements.forEach(el => {
624
624
  el.classList.remove('selected');
625
625
  });
626
-
626
+
627
627
  // Coordinate with Dashboard unified navigation system
628
628
  if (window.dashboard) {
629
629
  if (window.dashboard.tabNavigation && window.dashboard.tabNavigation.events) {
@@ -633,7 +633,7 @@ class EventViewer {
633
633
  window.dashboard.clearCardSelection();
634
634
  }
635
635
  }
636
-
636
+
637
637
  // Notify other components
638
638
  document.dispatchEvent(new CustomEvent('eventSelectionCleared'));
639
639
  }
@@ -645,19 +645,19 @@ class EventViewer {
645
645
  // Update event type counts
646
646
  this.eventTypeCount = {};
647
647
  this.errorCount = 0;
648
-
648
+
649
649
  // Defensive check to ensure events array exists
650
650
  if (!this.events || !Array.isArray(this.events)) {
651
651
  console.warn('EventViewer: events array is not initialized in updateMetrics');
652
652
  this.events = [];
653
653
  }
654
-
654
+
655
655
  this.events.forEach(event => {
656
656
  const type = event.type || 'unknown';
657
657
  this.eventTypeCount[type] = (this.eventTypeCount[type] || 0) + 1;
658
-
659
- if (event.type === 'log' &&
660
- event.data &&
658
+
659
+ if (event.type === 'log' &&
660
+ event.data &&
661
661
  ['error', 'critical'].includes(event.data.level)) {
662
662
  this.errorCount++;
663
663
  }
@@ -672,7 +672,7 @@ class EventViewer {
672
672
 
673
673
  // Count events in the last minute
674
674
  const oneMinuteAgo = new Date(Date.now() - 60000);
675
- this.eventsThisMinute = this.events.filter(event =>
675
+ this.eventsThisMinute = this.events.filter(event =>
676
676
  new Date(event.timestamp) > oneMinuteAgo
677
677
  ).length;
678
678
 
@@ -702,12 +702,12 @@ class EventViewer {
702
702
  const dataStr = JSON.stringify(this.filteredEvents, null, 2);
703
703
  const dataBlob = new Blob([dataStr], { type: 'application/json' });
704
704
  const url = URL.createObjectURL(dataBlob);
705
-
705
+
706
706
  const link = document.createElement('a');
707
707
  link.href = url;
708
708
  link.download = `claude-mpm-events-${new Date().toISOString().split('T')[0]}.json`;
709
709
  link.click();
710
-
710
+
711
711
  URL.revokeObjectURL(url);
712
712
  }
713
713
 
@@ -768,12 +768,12 @@ class EventViewer {
768
768
  createInlineEditDiffViewer(event, index) {
769
769
  const data = event.data || {};
770
770
  const toolName = event.tool_name || data.tool_name || '';
771
-
771
+
772
772
  // Only show for Edit and MultiEdit tools
773
773
  if (!['Edit', 'MultiEdit'].includes(toolName)) {
774
774
  return '';
775
775
  }
776
-
776
+
777
777
  // Extract edit parameters based on tool type
778
778
  let edits = [];
779
779
  if (toolName === 'Edit') {
@@ -796,20 +796,20 @@ class EventViewer {
796
796
  }));
797
797
  }
798
798
  }
799
-
799
+
800
800
  if (edits.length === 0) {
801
801
  return '';
802
802
  }
803
-
803
+
804
804
  // Create collapsible diff section
805
805
  const diffId = `edit-diff-${index}`;
806
806
  const isMultiEdit = edits.length > 1;
807
-
807
+
808
808
  let diffContent = '';
809
809
  edits.forEach((edit, editIndex) => {
810
810
  const editId = `${diffId}-${editIndex}`;
811
811
  const diffHtml = this.createDiffHtml(edit.old_string, edit.new_string);
812
-
812
+
813
813
  diffContent += `
814
814
  <div class="edit-diff-section">
815
815
  ${isMultiEdit ? `<div class="edit-diff-header">Edit ${editIndex + 1}</div>` : ''}
@@ -817,7 +817,7 @@ class EventViewer {
817
817
  </div>
818
818
  `;
819
819
  });
820
-
820
+
821
821
  return `
822
822
  <div class="inline-edit-diff-viewer">
823
823
  <div class="diff-toggle-header" onclick="eventViewer.toggleEditDiff('${diffId}', event)">
@@ -843,15 +843,15 @@ class EventViewer {
843
843
  // Simple line-by-line diff implementation
844
844
  const oldLines = oldText.split('\n');
845
845
  const newLines = newText.split('\n');
846
-
846
+
847
847
  let diffHtml = '';
848
848
  let i = 0, j = 0;
849
-
849
+
850
850
  // Simple diff algorithm - can be enhanced with proper diff library if needed
851
851
  while (i < oldLines.length || j < newLines.length) {
852
852
  const oldLine = i < oldLines.length ? oldLines[i] : null;
853
853
  const newLine = j < newLines.length ? newLines[j] : null;
854
-
854
+
855
855
  if (oldLine === null) {
856
856
  // New line added
857
857
  diffHtml += `<div class="diff-line diff-added">+ ${this.escapeHtml(newLine)}</div>`;
@@ -873,7 +873,7 @@ class EventViewer {
873
873
  j++;
874
874
  }
875
875
  }
876
-
876
+
877
877
  return `<div class="diff-container">${diffHtml}</div>`;
878
878
  }
879
879
 
@@ -885,10 +885,10 @@ class EventViewer {
885
885
  toggleEditDiff(diffId, event) {
886
886
  // Prevent event bubbling to parent event item
887
887
  event.stopPropagation();
888
-
888
+
889
889
  const diffContainer = document.getElementById(diffId);
890
890
  const arrow = event.currentTarget.querySelector('.diff-toggle-arrow');
891
-
891
+
892
892
  if (diffContainer) {
893
893
  const isVisible = diffContainer.style.display !== 'none';
894
894
  diffContainer.style.display = isVisible ? 'none' : 'block';
@@ -910,5 +910,9 @@ class EventViewer {
910
910
  }
911
911
  }
912
912
 
913
- // Export for global use
914
- window.EventViewer = EventViewer;
913
+ // ES6 Module export
914
+ export { EventViewer };
915
+ export default EventViewer;
916
+
917
+ // Backward compatibility - keep window export for non-module usage
918
+ window.EventViewer = EventViewer;
@@ -1,13 +1,13 @@
1
1
  /**
2
2
  * Export Manager Module
3
- *
3
+ *
4
4
  * Handles export functionality and utility functions for the dashboard.
5
5
  * Provides data export capabilities and common utility functions used across modules.
6
- *
6
+ *
7
7
  * WHY: Extracted from main dashboard to centralize export logic and utility functions
8
8
  * that don't belong to specific functional areas. This provides a clean place for
9
9
  * shared utilities while keeping export logic organized and testable.
10
- *
10
+ *
11
11
  * DESIGN DECISION: Combines export functionality with general utilities to avoid
12
12
  * creating too many small modules while keeping related functionality together.
13
13
  * Provides both data export and UI utility functions.
@@ -16,7 +16,7 @@ class ExportManager {
16
16
  constructor(eventViewer) {
17
17
  this.eventViewer = eventViewer;
18
18
  this.setupEventHandlers();
19
-
19
+
20
20
  console.log('Export manager initialized');
21
21
  }
22
22
 
@@ -26,13 +26,13 @@ class ExportManager {
26
26
  setupEventHandlers() {
27
27
  const clearBtn = document.querySelector('button[onclick="clearEvents()"]');
28
28
  const exportBtn = document.getElementById('export-btn');
29
-
29
+
30
30
  if (clearBtn) {
31
31
  clearBtn.addEventListener('click', () => {
32
32
  this.clearEvents();
33
33
  });
34
34
  }
35
-
35
+
36
36
  if (exportBtn) {
37
37
  exportBtn.addEventListener('click', () => {
38
38
  this.exportEvents();
@@ -59,15 +59,15 @@ class ExportManager {
59
59
  clearEvents() {
60
60
  // Dispatch event to notify other modules
61
61
  document.dispatchEvent(new CustomEvent('eventsClearing'));
62
-
62
+
63
63
  // Clear events from event viewer
64
64
  if (this.eventViewer) {
65
65
  this.eventViewer.clearEvents();
66
66
  }
67
-
67
+
68
68
  // Dispatch event to notify clearing is complete
69
69
  document.dispatchEvent(new CustomEvent('eventsCleared'));
70
-
70
+
71
71
  console.log('Events cleared');
72
72
  }
73
73
 
@@ -86,7 +86,7 @@ class ExportManager {
86
86
  } = options;
87
87
 
88
88
  const eventsToExport = events || (this.eventViewer ? this.eventViewer.events : []);
89
-
89
+
90
90
  if (eventsToExport.length === 0) {
91
91
  console.warn('No events to export');
92
92
  return;
@@ -106,19 +106,19 @@ class ExportManager {
106
106
  mimeType = 'application/json';
107
107
  fileExtension = '.json';
108
108
  break;
109
-
109
+
110
110
  case 'csv':
111
111
  content = this.convertEventsToCSV(eventsToExport);
112
112
  mimeType = 'text/csv';
113
113
  fileExtension = '.csv';
114
114
  break;
115
-
115
+
116
116
  case 'txt':
117
117
  content = this.convertEventsToText(eventsToExport);
118
118
  mimeType = 'text/plain';
119
119
  fileExtension = '.txt';
120
120
  break;
121
-
121
+
122
122
  default:
123
123
  console.error('Unsupported export format:', format);
124
124
  return;
@@ -137,7 +137,7 @@ class ExportManager {
137
137
 
138
138
  // Define CSV headers
139
139
  const headers = ['timestamp', 'type', 'subtype', 'tool_name', 'agent_type', 'session_id', 'data'];
140
-
140
+
141
141
  // Convert events to CSV rows
142
142
  const rows = events.map(event => {
143
143
  return [
@@ -173,15 +173,15 @@ class ExportManager {
173
173
  const subtype = event.subtype ? ` (${event.subtype})` : '';
174
174
  const toolName = event.tool_name ? ` - Tool: ${event.tool_name}` : '';
175
175
  const agentType = event.agent_type ? ` - Agent: ${event.agent_type}` : '';
176
-
176
+
177
177
  let content = `Event ${index + 1}: ${type}${subtype}${toolName}${agentType}\n`;
178
178
  content += ` Time: ${timestamp}\n`;
179
179
  content += ` Session: ${event.session_id || 'Unknown'}\n`;
180
-
180
+
181
181
  if (event.data && Object.keys(event.data).length > 0) {
182
182
  content += ` Data: ${JSON.stringify(event.data, null, 2)}\n`;
183
183
  }
184
-
184
+
185
185
  return content;
186
186
  }).join('\n' + '='.repeat(80) + '\n');
187
187
  }
@@ -196,19 +196,19 @@ class ExportManager {
196
196
  try {
197
197
  const blob = new Blob([content], { type: mimeType });
198
198
  const url = window.URL.createObjectURL(blob);
199
-
199
+
200
200
  const link = document.createElement('a');
201
201
  link.href = url;
202
202
  link.download = filename;
203
203
  link.style.display = 'none';
204
-
204
+
205
205
  document.body.appendChild(link);
206
206
  link.click();
207
207
  document.body.removeChild(link);
208
-
208
+
209
209
  // Clean up the URL object
210
210
  window.URL.revokeObjectURL(url);
211
-
211
+
212
212
  console.log(`File exported: ${filename}`);
213
213
  } catch (error) {
214
214
  console.error('Failed to export file:', error);
@@ -226,13 +226,13 @@ class ExportManager {
226
226
  */
227
227
  formatTimestamp(timestamp) {
228
228
  if (!timestamp) return 'Unknown time';
229
-
229
+
230
230
  try {
231
231
  const date = new Date(timestamp);
232
232
  if (isNaN(date.getTime())) {
233
233
  return 'Invalid time';
234
234
  }
235
-
235
+
236
236
  return date.toLocaleTimeString('en-US', {
237
237
  hour12: false,
238
238
  hour: '2-digit',
@@ -252,13 +252,13 @@ class ExportManager {
252
252
  */
253
253
  formatFullTimestamp(timestamp) {
254
254
  if (!timestamp) return 'Unknown time';
255
-
255
+
256
256
  try {
257
257
  const date = new Date(timestamp);
258
258
  if (isNaN(date.getTime())) {
259
259
  return 'Invalid time';
260
260
  }
261
-
261
+
262
262
  return date.toLocaleString('en-US', {
263
263
  year: 'numeric',
264
264
  month: '2-digit',
@@ -280,12 +280,12 @@ class ExportManager {
280
280
  */
281
281
  scrollListToBottom(listId) {
282
282
  console.log(`[DEBUG] scrollListToBottom called with listId: ${listId}`);
283
-
283
+
284
284
  // Use setTimeout to ensure DOM updates are completed
285
285
  setTimeout(() => {
286
286
  const listElement = document.getElementById(listId);
287
287
  console.log(`[DEBUG] Element found for ${listId}:`, listElement);
288
-
288
+
289
289
  if (listElement) {
290
290
  console.log(`[DEBUG] Scrolling ${listId} - scrollHeight: ${listElement.scrollHeight}, scrollTop before: ${listElement.scrollTop}`);
291
291
  listElement.scrollTop = listElement.scrollHeight;
@@ -359,4 +359,7 @@ class ExportManager {
359
359
  }
360
360
  return obj;
361
361
  }
362
- }
362
+ }
363
+ // ES6 Module export
364
+ export { ExportManager };
365
+ export default ExportManager;