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
@@ -0,0 +1,2 @@
1
+ import{S as e,U as t}from"./socket-client.js";import{E as n,a as i}from"./components/event-viewer.js";import{M as o}from"./components/module-viewer.js";import{S as s}from"./components/session-manager.js";import{A as r}from"./components/agent-inference.js";import{E as a}from"./components/export-manager.js";import{W as l}from"./components/working-directory.js";import{F as c}from"./components/file-tool-tracker.js";class d{constructor(){this.eventViewer=null,this.moduleViewer=null,this.sessionManager=null,this.socketManager=null,this.agentInference=null,this.uiStateManager=null,this.eventProcessor=null,this.exportManager=null,this.workingDirectoryManager=null,this.fileToolTracker=null,this.init()}init(){console.log("Initializing refactored Claude MPM Dashboard..."),this.initializeSocketManager(),this.initializeCoreComponents(),this.initializeAgentInference(),this.initializeUIStateManager(),this.initializeWorkingDirectoryManager(),this.initializeFileToolTracker(),this.initializeEventProcessor(),this.initializeExportManager(),this.setupModuleInteractions(),this.initializeFromURL(),console.log("Claude MPM Dashboard initialized successfully")}initializeSocketManager(){this.socketManager=new e,this.socketManager.setupConnectionControls(),this.socketClient=this.socketManager.getSocketClient(),window.socketClient=this.socketClient}initializeCoreComponents(){this.eventViewer=new n("events-list",this.socketClient),this.moduleViewer=new o,this.sessionManager=new s(this.socketClient),window.eventViewer=this.eventViewer,window.moduleViewer=this.moduleViewer,window.sessionManager=this.sessionManager}initializeAgentInference(){this.agentInference=new r(this.eventViewer),this.agentInference.initialize()}initializeUIStateManager(){this.uiStateManager=new t,this.setupTabFilters()}initializeWorkingDirectoryManager(){this.workingDirectoryManager=new l(this.socketManager)}initializeFileToolTracker(){this.fileToolTracker=new c(this.agentInference,this.workingDirectoryManager)}initializeEventProcessor(){this.eventProcessor=new i(this.eventViewer,this.agentInference)}initializeExportManager(){this.exportManager=new a(this.eventViewer)}setupModuleInteractions(){this.socketManager.onEventUpdate(e=>{this.fileToolTracker.updateFileOperations(e),this.fileToolTracker.updateToolCalls(e),this.agentInference.processAgentInference(),"events"===this.uiStateManager.getCurrentTab()&&this.exportManager.scrollListToBottom("events-list"),this.renderCurrentTab()}),this.socketManager.onConnectionStatusChange((e,t)=>{"connected"===t&&this.workingDirectoryManager.updateGitBranch(this.workingDirectoryManager.getCurrentWorkingDir())}),document.addEventListener("tabChanged",e=>{this.renderCurrentTab(),this.uiStateManager.updateTabNavigationItems()}),document.addEventListener("eventsClearing",()=>{this.fileToolTracker.clear(),this.agentInference.initialize()}),document.addEventListener("showCardDetails",e=>{this.showCardDetails(e.detail.tabName,e.detail.index)}),document.addEventListener("sessionFilterChanged",e=>{console.log("Session filter changed, re-rendering current tab:",this.uiStateManager.getCurrentTab()),this.renderCurrentTab()})}setupTabFilters(){const e=document.getElementById("agents-search-input"),t=document.getElementById("agents-type-filter");e&&e.addEventListener("input",()=>{"agents"===this.uiStateManager.getCurrentTab()&&this.renderCurrentTab()}),t&&t.addEventListener("change",()=>{"agents"===this.uiStateManager.getCurrentTab()&&this.renderCurrentTab()});const n=document.getElementById("tools-search-input"),i=document.getElementById("tools-type-filter");n&&n.addEventListener("input",()=>{"tools"===this.uiStateManager.getCurrentTab()&&this.renderCurrentTab()}),i&&i.addEventListener("change",()=>{"tools"===this.uiStateManager.getCurrentTab()&&this.renderCurrentTab()});const o=document.getElementById("files-search-input"),s=document.getElementById("files-type-filter");o&&o.addEventListener("input",()=>{"files"===this.uiStateManager.getCurrentTab()&&this.renderCurrentTab()}),s&&s.addEventListener("change",()=>{"files"===this.uiStateManager.getCurrentTab()&&this.renderCurrentTab()})}initializeFromURL(){const e=new URLSearchParams(window.location.search);this.socketManager.initializeFromURL(e)}renderCurrentTab(){const e=this.uiStateManager.getCurrentTab();switch(e){case"events":break;case"agents":this.renderAgents();break;case"tools":this.renderTools();break;case"files":this.renderFiles()}this.uiStateManager.getSelectedCard().tab===e&&this.uiStateManager.updateCardSelectionUI(),this.uiStateManager.updateUnifiedSelectionUI()}renderAgents(){const e=document.getElementById("agents-list");if(!e)return;this.agentInference.processAgentInference();const t=this.eventProcessor.getFilteredEventsForTab("agents"),n=this.eventProcessor.generateAgentHTML(t);e.innerHTML=n,this.exportManager.scrollListToBottom("agents-list");const i=this.agentInference.getUniqueAgentInstances();this.updateAgentsFilterDropdowns(i)}renderTools(){const e=document.getElementById("tools-list");if(!e)return;const t=this.fileToolTracker.getToolCalls(),n=Array.from(t.entries()),i=this.eventProcessor.getUniqueToolInstances(n),o=this.eventProcessor.generateToolHTML(i);e.innerHTML=o,this.exportManager.scrollListToBottom("tools-list"),this.updateToolsFilterDropdowns(i)}renderFiles(){const e=document.getElementById("files-list");if(!e)return;const t=this.fileToolTracker.getFileOperations(),n=Array.from(t.entries()),i=this.eventProcessor.getUniqueFileInstances(n),o=this.eventProcessor.generateFileHTML(i);e.innerHTML=o,this.exportManager.scrollListToBottom("files-list"),this.updateFilesFilterDropdowns(n)}updateAgentsFilterDropdowns(e){const t=new Set;e.forEach(e=>{e.agentName&&"Unknown"!==e.agentName&&t.add(e.agentName)});const n=Array.from(t).filter(e=>e&&""!==e.trim());this.populateFilterDropdown("agents-type-filter",n,"All Agent Types"),n.length>0?console.log("Agent types found for filter:",n):console.log("No agent types found for filter. Instances:",e.length)}updateToolsFilterDropdowns(e){const t=[...new Set(e.map(([e,t])=>t.tool_name))].filter(e=>e);this.populateFilterDropdown("tools-type-filter",t,"All Tools")}updateFilesFilterDropdowns(e){const t=[...new Set(e.flatMap(([e,t])=>t.operations.map(e=>e.operation)))].filter(e=>e);this.populateFilterDropdown("files-type-filter",t,"All Operations")}populateFilterDropdown(e,t,n="All"){const i=document.getElementById(e);if(!i)return;const o=i.value,s=t.sort((e,t)=>e.localeCompare(t));i.innerHTML=`<option value="">${n}</option>`,s.forEach(e=>{const t=document.createElement("option");t.value=e,t.textContent=e,i.appendChild(t)}),o&&s.includes(o)&&(i.value=o)}showCardDetails(e,t){switch(e){case"events":this.eventViewer&&this.eventViewer.showEventDetails(t);break;case"agents":this.showAgentDetailsByIndex(t);break;case"tools":this.showToolDetailsByIndex(t);break;case"files":this.showFileDetailsByIndex(t)}}showAgentDetailsByIndex(e){const t=this.eventProcessor.getFilteredEventsForTab("agents");if(!t||!Array.isArray(t)||e<0||e>=t.length)return void console.warn("Dashboard: Invalid agent index or events array");const n=this.eventProcessor.applyAgentsFilters([t[e]]);if(n.length>0&&this.moduleViewer&&"function"==typeof this.moduleViewer.showAgentEvent){const t=n[0];this.moduleViewer.showAgentEvent(t,e)}}showAgentInstanceDetails(e){const t=this.agentInference.getPMDelegations().get(e);if(!t){const t=this.agentInference.getUniqueAgentInstances().find(t=>t.id===e);return t?void this.showImpliedAgentDetails(t):void console.error("Agent instance not found:",e)}this.moduleViewer&&"function"==typeof this.moduleViewer.showAgentInstance?this.moduleViewer.showAgentInstance(t):console.log("Agent Instance Details:",{id:e,agentName:t.agentName,type:"PM Delegation",eventCount:t.agentEvents.length,startTime:t.timestamp,pmCall:t.pmCall})}showImpliedAgentDetails(e){this.moduleViewer&&"function"==typeof this.moduleViewer.showImpliedAgent?this.moduleViewer.showImpliedAgent(e):console.log("Implied Agent Details:",{id:e.id,agentName:e.agentName,type:"Implied PM Delegation",eventCount:e.eventCount,startTime:e.timestamp,note:"No explicit PM call found - inferred from agent activity"})}showToolDetailsByIndex(e){const t=this.fileToolTracker.getToolCalls(),n=Array.from(t.entries()),i=this.eventProcessor.applyToolCallFilters(n);if(e>=0&&e<i.length){const[t]=i[e];this.showToolCallDetails(t)}}showFileDetailsByIndex(e){const t=this.fileToolTracker.getFileOperations();let n=Array.from(t.entries());if(n=this.eventProcessor.applyFilesFilters(n),e>=0&&e<n.length){const[t]=n[e];this.showFileDetails(t)}}showToolCallDetails(e){const t=this.fileToolTracker.getToolCall(e);t&&this.moduleViewer&&this.moduleViewer.showToolCall(t,e)}showFileDetails(e){const t=this.fileToolTracker.getFileOperationsForFile(e);t&&this.moduleViewer&&this.moduleViewer.showFileOperations(t,e)}switchTab(e){this.uiStateManager.switchTab(e)}selectCard(e,t,n,i){this.uiStateManager.selectCard(e,t,n,i)}clearEvents(){this.exportManager.clearEvents()}exportEvents(){this.exportManager.exportEvents()}clearSelection(){this.uiStateManager.clearSelection(),this.eventViewer&&this.eventViewer.clearSelection(),this.moduleViewer&&this.moduleViewer.clear()}get currentWorkingDir(){return this.workingDirectoryManager.getCurrentWorkingDir()}set currentWorkingDir(e){this.workingDirectoryManager.setWorkingDirectory(e)}get currentTab(){return this.uiStateManager.getCurrentTab()}get selectedCard(){return this.uiStateManager.getSelectedCard()}get fileOperations(){return this.fileToolTracker.getFileOperations()}get toolCalls(){return this.fileToolTracker.getToolCalls()}get tabNavigation(){return this.uiStateManager?this.uiStateManager.tabNavigation:null}}function g(){const e=document.createElement("div");return e.id="file-viewer-modal",e.className="modal file-viewer-modal",e.innerHTML='\n <div class="modal-content file-viewer-content">\n <div class="file-viewer-header">\n <h2 class="file-viewer-title">\n <span class="file-viewer-icon">📄</span>\n <span class="file-viewer-title-text">File Viewer</span>\n </h2>\n <div class="file-viewer-meta">\n <span class="file-viewer-file-path"></span>\n <span class="file-viewer-file-size"></span>\n </div>\n <button class="file-viewer-close" onclick="hideFileViewerModal()">\n <span>&times;</span>\n </button>\n </div>\n <div class="file-viewer-body">\n <div class="file-viewer-loading">\n <div class="loading-spinner"></div>\n <span>Loading file content...</span>\n </div>\n <div class="file-viewer-error" style="display: none;">\n <div class="error-icon">⚠️</div>\n <div class="error-message"></div>\n <div class="error-suggestions"></div>\n </div>\n <div class="file-viewer-content-area" style="display: none;">\n <div class="file-viewer-toolbar">\n <div class="file-viewer-info">\n <span class="file-extension"></span>\n <span class="file-encoding"></span>\n </div>\n <div class="file-viewer-actions">\n <button class="file-content-copy" onclick="copyFileContent()">\n 📋 Copy\n </button>\n </div>\n </div>\n <div class="file-viewer-scroll-wrapper">\n <pre class="file-content-display"><code class="file-content-code"></code></pre>\n </div>\n </div>\n </div>\n </div>\n ',e.addEventListener("click",t=>{t.target===e&&hideFileViewerModal()}),document.addEventListener("keydown",t=>{"Escape"===t.key&&"flex"===e.style.display&&hideFileViewerModal()}),e}async function f(e,t,n){const i=e.querySelector(".file-viewer-file-path"),o=e.querySelector(".file-viewer-file-size");i.textContent=t,o.textContent="",e.querySelector(".file-viewer-loading").style.display="flex",e.querySelector(".file-viewer-error").style.display="none",e.querySelector(".file-viewer-content-area").style.display="none";try{const i=window.socket||window.dashboard?.socketClient?.socket;if(!i)throw new Error("No socket connection available");const o=new Promise((e,n)=>{const o=s=>{s.file_path===t&&(i.off("file_content_response",o),s.success?e(s):n(new Error(s.error||"Failed to read file")))};i.on("file_content_response",o),setTimeout(()=>{i.off("file_content_response",o),n(new Error("Request timeout"))},1e4)});i.emit("read_file",{file_path:t,working_dir:n}),console.log("📄 File viewer request sent:",{filePath:t,workingDir:n});const s=await o;console.log("📦 File content received:",s),e.querySelector(".file-viewer-loading").style.display="none",function(e,t){console.log("📝 displayFileContent called with:",t);const n=e.querySelector(".file-viewer-content-area"),i=e.querySelector(".file-extension"),o=e.querySelector(".file-encoding"),s=e.querySelector(".file-viewer-file-size"),r=e.querySelector(".file-content-code");i&&(i.textContent=`Type: ${t.extension||"unknown"}`);o&&(o.textContent=`Encoding: ${t.encoding||"unknown"}`);s&&(s.textContent=`Size: ${function(e){if(!e)return"0 B";const t=1024,n=["B","KB","MB","GB"],i=Math.floor(Math.log(e)/Math.log(t));return parseFloat((e/Math.pow(t,i)).toFixed(2))+" "+n[i]}(t.file_size)}`);if(r&&t.content){console.log("💡 Setting file content, length:",t.content.length),r.innerHTML=function(e,t){const n=e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");switch(t){case".js":case".jsx":case".ts":case".tsx":return function(e){return p(e.replace(/\b(function|const|let|var|if|else|for|while|return|import|export|class|extends)\b/g,'<span class="keyword">$1</span>').replace(/(\/\*[\s\S]*?\*\/|\/\/.*)/g,'<span class="comment">$1</span>').replace(/('[^']*'|"[^"]*"|`[^`]*`)/g,'<span class="string">$1</span>').replace(/\b(\d+)\b/g,'<span class="number">$1</span>'))}(n);case".py":return function(e){return p(e.replace(/\b(def|class|if|elif|else|for|while|return|import|from|as|try|except|finally|with)\b/g,'<span class="keyword">$1</span>').replace(/(#.*)/g,'<span class="comment">$1</span>').replace(/('[^']*'|"[^"]*"|"""[\s\S]*?""")/g,'<span class="string">$1</span>').replace(/\b(\d+)\b/g,'<span class="number">$1</span>'))}(n);case".json":return function(e){return p(e.replace(/("[\w\s]*")\s*:/g,'<span class="property">$1</span>:').replace(/:\s*(".*?")/g,': <span class="string">$1</span>').replace(/:\s*(\d+)/g,': <span class="number">$1</span>').replace(/:\s*(true|false|null)/g,': <span class="keyword">$1</span>'))}(n);case".css":return function(e){return p(e.replace(/([.#]?[\w-]+)\s*\{/g,'<span class="selector">$1</span> {').replace(/([\w-]+)\s*:/g,'<span class="property">$1</span>:').replace(/:\s*([^;]+);/g,': <span class="value">$1</span>;').replace(/(\/\*[\s\S]*?\*\/)/g,'<span class="comment">$1</span>'))}(n);case".html":case".htm":return function(e){return p(e.replace(/(&lt;\/?[\w-]+)/g,'<span class="tag">$1</span>').replace(/([\w-]+)=(['"][^'"]*['"])/g,'<span class="attribute">$1</span>=<span class="string">$2</span>').replace(/(&lt;!--[\s\S]*?--&gt;)/g,'<span class="comment">$1</span>'))}(n);case".md":case".markdown":return function(e){return p(e.replace(/^(#{1,6})\s+(.*)$/gm,'<span class="header">$1</span> <span class="header-text">$2</span>').replace(/\*\*(.*?)\*\*/g,'<span class="bold">**$1**</span>').replace(/\*(.*?)\*/g,'<span class="italic">*$1*</span>').replace(/`([^`]+)`/g,'<span class="code">`$1`</span>').replace(/^\s*[-*+]\s+(.*)$/gm,'<span class="list-marker">•</span> $1'))}(n);default:return p(n)}}(t.content,t.extension);const n=e.querySelector(".file-viewer-scroll-wrapper");n&&setTimeout(()=>{const t=e.querySelector(".modal-content"),i=e.querySelector(".file-viewer-header"),o=e.querySelector(".file-viewer-toolbar"),s=t?.offsetHeight||0,r=i?.offsetHeight||0,a=o?.offsetHeight||0,l=s-r-a-40;console.log("🎯 Setting file viewer scroll height:",{modalHeight:s,headerHeight:r,toolbarHeight:a,availableHeight:l}),n.style.maxHeight=`${l}px`,n.style.overflowY="auto"},50)}else console.warn("⚠️ Missing codeElement or file content");n&&(n.style.display="block",console.log("✅ File content area displayed"))}(e,s)}catch(s){console.error("❌ Failed to fetch file content:",s),e.querySelector(".file-viewer-loading").style.display="none";let i=s.message||"Unknown error occurred",o=[];s.message.includes("No socket connection")?(i="Failed to connect to the monitoring server",o=["Check if the monitoring server is running","Verify the socket connection in the dashboard","Try refreshing the page and reconnecting"]):s.message.includes("timeout")?(i="Request timed out",o=["The file may be too large to load quickly","Check your network connection","Try again in a few moments"]):s.message.includes("File does not exist")?(i="File not found",o=["The file may have been moved or deleted","Check the file path spelling","Refresh the file list to see current files"]):s.message.includes("Access denied")&&(i="Access denied",o=["The file is outside the allowed directories","File access is restricted for security reasons"]),function(e,t){const n=e.querySelector(".file-viewer-error"),i=e.querySelector(".error-message"),o=e.querySelector(".error-suggestions");let s=t.error||"Unknown error occurred";i.innerHTML=`\n <div class="error-main">${s}</div>\n ${t.file_path?`<div class="error-file">File: ${t.file_path}</div>`:""}\n ${t.working_dir?`<div class="error-dir">Working directory: ${t.working_dir}</div>`:""}\n `,t.suggestions&&t.suggestions.length>0?o.innerHTML=`\n <h4>Suggestions:</h4>\n <ul>\n ${t.suggestions.map(e=>`<li>${e}</li>`).join("")}\n </ul>\n `:o.innerHTML="";console.log("📋 Displaying file viewer error:",{originalError:t.error,processedMessage:s,suggestions:t.suggestions}),n.style.display="block"}(e,{error:i,file_path:t,working_dir:n,suggestions:o})}}function p(e){return e.split("\n").map((e,t)=>`<span class="line-number">${String(t+1).padStart(3," ")}</span> ${e||" "}`).join("\n")}function h(e,t){const n=e.querySelector(".git-diff-error"),i=e.querySelector(".error-message"),o=e.querySelector(".error-suggestions");let s=t.error||"Unknown error occurred",r=!1;if(s.includes("not tracked by git")?(s="📝 This file is not tracked by git yet",r=!0):s.includes("No git history found")&&(s="📋 No git history available for this file"),i.innerHTML=`\n <div class="error-main">${s}</div>\n ${t.file_path?`<div class="error-file">File: ${t.file_path}</div>`:""}\n ${t.working_dir?`<div class="error-dir">Working directory: ${t.working_dir}</div>`:""}\n `,t.suggestions&&t.suggestions.length>0){const e=r?"How to track this file:":"Suggestions:";o.innerHTML=`\n <h4>${e}</h4>\n <ul>\n ${t.suggestions.map(e=>`<li>${e}</li>`).join("")}\n </ul>\n `}else o.innerHTML="";console.log("📋 Displaying git diff error:",{originalError:t.error,processedMessage:s,isUntracked:r,suggestions:t.suggestions}),n.style.display="block"}window.clearEvents=function(){window.dashboard&&window.dashboard.clearEvents()},window.exportEvents=function(){window.dashboard&&window.dashboard.exportEvents()},window.clearSelection=function(){window.dashboard&&window.dashboard.clearSelection()},window.switchTab=function(e){window.dashboard&&window.dashboard.switchTab(e)},window.showFileViewerModal=function(e,t){!t&&window.dashboard&&window.dashboard.currentWorkingDir&&(t=window.dashboard.currentWorkingDir);let n=document.getElementById("file-viewer-modal");n||(n=g(),document.body.appendChild(n)),f(n,e,t),n.style.display="flex",document.body.style.overflow="hidden"},window.hideFileViewerModal=function(){const e=document.getElementById("file-viewer-modal");e&&(e.style.display="none",document.body.style.overflow="")},window.copyFileContent=function(){const e=document.getElementById("file-viewer-modal");if(!e)return;const t=e.querySelector(".file-content-code");if(!t)return;const n=t.textContent;if(navigator.clipboard&&navigator.clipboard.writeText)navigator.clipboard.writeText(n).then(()=>{const t=e.querySelector(".file-content-copy"),n=t.textContent;t.textContent="✅ Copied!",setTimeout(()=>{t.textContent=n},2e3)}).catch(e=>{console.error("Failed to copy text:",e)});else{const t=document.createElement("textarea");t.value=n,document.body.appendChild(t),t.select(),document.execCommand("copy"),document.body.removeChild(t);const i=e.querySelector(".file-content-copy"),o=i.textContent;i.textContent="✅ Copied!",setTimeout(()=>{i.textContent=o},2e3)}},window.showGitDiffModal=function(e,t,n){!n&&window.dashboard&&window.dashboard.currentWorkingDir&&(n=window.dashboard.currentWorkingDir);let i=document.getElementById("git-diff-modal");i||(i=function(){const e=document.createElement("div");return e.id="git-diff-modal",e.className="modal git-diff-modal",e.innerHTML='\n <div class="modal-content git-diff-content">\n <div class="git-diff-header">\n <h2 class="git-diff-title">\n <span class="git-diff-icon">📋</span>\n <span class="git-diff-title-text">Git Diff</span>\n </h2>\n <div class="git-diff-meta">\n <span class="git-diff-file-path"></span>\n <span class="git-diff-timestamp"></span>\n </div>\n <button class="git-diff-close" onclick="hideGitDiffModal()">\n <span>&times;</span>\n </button>\n </div>\n <div class="git-diff-body">\n <div class="git-diff-loading">\n <div class="loading-spinner"></div>\n <span>Loading git diff...</span>\n </div>\n <div class="git-diff-error" style="display: none;">\n <div class="error-icon">⚠️</div>\n <div class="error-message"></div>\n <div class="error-suggestions"></div>\n </div>\n <div class="git-diff-content-area" style="display: none;">\n <div class="git-diff-toolbar">\n <div class="git-diff-info">\n <span class="commit-hash"></span>\n <span class="diff-method"></span>\n </div>\n <div class="git-diff-actions">\n <button class="git-diff-copy" onclick="copyGitDiff()">\n 📋 Copy\n </button>\n </div>\n </div>\n <div class="git-diff-scroll-wrapper">\n <pre class="git-diff-display"><code class="git-diff-code"></code></pre>\n </div>\n </div>\n </div>\n </div>\n ',e.addEventListener("click",t=>{t.target===e&&hideGitDiffModal()}),document.addEventListener("keydown",t=>{"Escape"===t.key&&"flex"===e.style.display&&hideGitDiffModal()}),e}(),document.body.appendChild(i)),async function(e,t,n,i){const o=e.querySelector(".git-diff-file-path"),s=e.querySelector(".git-diff-timestamp");o.textContent=t,s.textContent=n?new Date(n).toLocaleString():"Latest",e.querySelector(".git-diff-loading").style.display="flex",e.querySelector(".git-diff-error").style.display="none",e.querySelector(".git-diff-content-area").style.display="none";try{let o=8765;if(window.dashboard&&window.dashboard.socketClient&&window.dashboard.socketClient.port)o=window.dashboard.socketClient.port;else{const e=document.getElementById("port-input");e&&e.value&&(o=e.value)}const s=new URLSearchParams({file:t});n&&s.append("timestamp",n),i&&s.append("working_dir",i);const a=`http://localhost:${o}/api/git-diff?${s}`;console.log("🌐 Making git diff request to:",a),console.log("📋 Git diff request parameters:",{filePath:t,timestamp:n,workingDir:i,urlParams:s.toString()});try{const e=await fetch(`http://localhost:${o}/health`,{method:"GET",headers:{Accept:"application/json","Content-Type":"application/json"},mode:"cors"});if(!e.ok)throw new Error(`Server health check failed: ${e.status} ${e.statusText}`);console.log("✅ Server health check passed")}catch(r){throw new Error(`Cannot reach server at localhost:${o}. Health check failed: ${r.message}`)}const l=await fetch(a,{method:"GET",headers:{Accept:"application/json","Content-Type":"application/json"},mode:"cors"});if(!l.ok)throw new Error(`HTTP ${l.status}: ${l.statusText}`);const c=await l.json();console.log("📦 Git diff response:",c),e.querySelector(".git-diff-loading").style.display="none",c.success?(console.log("📊 Displaying successful git diff"),function(e,t){console.log("📝 displayGitDiff called with:",t);const n=e.querySelector(".git-diff-content-area"),i=e.querySelector(".commit-hash"),o=e.querySelector(".diff-method"),s=e.querySelector(".git-diff-code");console.log("🔍 Elements found:",{contentArea:!!n,commitHashElement:!!i,methodElement:!!o,codeElement:!!s}),i&&(i.textContent=`Commit: ${t.commit_hash}`);o&&(o.textContent=`Method: ${t.method}`);if(s&&t.diff){console.log("💡 Setting diff content, length:",t.diff.length),s.innerHTML=t.diff.split("\n").map(e=>{const t=e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");return e.startsWith("+++")||e.startsWith("---")?`<span class="diff-header">${t}</span>`:e.startsWith("@@")?`<span class="diff-meta">${t}</span>`:e.startsWith("+")?`<span class="diff-addition">${t}</span>`:e.startsWith("-")?`<span class="diff-deletion">${t}</span>`:e.startsWith("commit ")||e.startsWith("Author:")||e.startsWith("Date:")?`<span class="diff-header">${t}</span>`:`<span class="diff-context">${t}</span>`}).join("\n");const n=e.querySelector(".git-diff-scroll-wrapper");n&&setTimeout(()=>{const t=e.querySelector(".modal-content"),i=e.querySelector(".git-diff-header"),o=e.querySelector(".git-diff-toolbar"),s=t?.offsetHeight||0,r=i?.offsetHeight||0,a=o?.offsetHeight||0,l=s-r-a-40;console.log("🎯 Setting explicit scroll height:",{modalHeight:s,headerHeight:r,toolbarHeight:a,availableHeight:l}),n.style.maxHeight=`${l}px`,n.style.overflowY="auto"},50)}else console.warn("⚠️ Missing codeElement or diff data");n&&(n.style.display="block",console.log("✅ Content area displayed"))}(e,c)):(console.log("⚠️ Displaying git diff error:",c),h(e,c))}catch(a){console.error("❌ Failed to fetch git diff:",a),console.error("Error details:",{name:a.name,message:a.message,stack:a.stack,filePath:t,timestamp:n,workingDir:i}),e.querySelector(".git-diff-loading").style.display="none";let o=`Network error: ${a.message}`,s=[];a.message.includes("Failed to fetch")?(o="Failed to connect to the monitoring server",s=["Check if the monitoring server is running on port 8765","Verify the port configuration in the dashboard","Check browser console for CORS or network errors","Try refreshing the page and reconnecting"]):a.message.includes("health check failed")?(o=a.message,s=["The server may be starting up - try again in a few seconds","Check if another process is using port 8765","Restart the claude-mpm monitoring server"]):a.message.includes("HTTP")&&(o=`Server error: ${a.message}`,s=["The server encountered an internal error","Check the server logs for more details","Try with a different file or working directory"]),h(e,{error:o,file_path:t,working_dir:i,suggestions:s,debug_info:{error_type:a.name,original_message:a.message,port:window.dashboard?.socketClient?.port||document.getElementById("port-input")?.value||"8765",timestamp:(new Date).toISOString()}})}}(i,e,t,n),i.style.display="flex",document.body.style.overflow="hidden"},window.hideGitDiffModal=function(){const e=document.getElementById("git-diff-modal");e&&(e.style.display="none",document.body.style.overflow="")},window.copyGitDiff=function(){const e=document.getElementById("git-diff-modal");if(!e)return;const t=e.querySelector(".git-diff-code");if(!t)return;const n=t.textContent;if(navigator.clipboard&&navigator.clipboard.writeText)navigator.clipboard.writeText(n).then(()=>{const t=e.querySelector(".git-diff-copy"),n=t.textContent;t.textContent="✅ Copied!",setTimeout(()=>{t.textContent=n},2e3)}).catch(e=>{console.error("Failed to copy text:",e)});else{const t=document.createElement("textarea");t.value=n,document.body.appendChild(t),t.select(),document.execCommand("copy"),document.body.removeChild(t);const i=e.querySelector(".git-diff-copy"),o=i.textContent;i.textContent="✅ Copied!",setTimeout(()=>{i.textContent=o},2e3)}},window.showFileViewerModal=function(e){let t="";window.dashboard&&window.dashboard.currentWorkingDir&&(t=window.dashboard.currentWorkingDir);let n=document.getElementById("file-viewer-modal");n||(n=g(),document.body.appendChild(n)),f(n,e,t),n.style.display="flex",document.body.style.overflow="hidden"},window.hideFileViewerModal=function(){const e=document.getElementById("file-viewer-modal");e&&(e.style.display="none",document.body.style.overflow="")},window.copyFileContent=function(){const e=document.getElementById("file-viewer-modal");if(!e)return;const t=e.querySelector(".file-content-code");if(!t)return;const n=t.textContent;if(navigator.clipboard&&navigator.clipboard.writeText)navigator.clipboard.writeText(n).then(()=>{const t=e.querySelector(".file-content-copy"),n=t.textContent;t.textContent="✅ Copied!",setTimeout(()=>{t.textContent=n},2e3)}).catch(e=>{console.error("Failed to copy text:",e)});else{const t=document.createElement("textarea");t.value=n,document.body.appendChild(t),t.select(),document.execCommand("copy"),document.body.removeChild(t);const i=e.querySelector(".file-content-copy"),o=i.textContent;i.textContent="✅ Copied!",setTimeout(()=>{i.textContent=o},2e3)}},window.showAgentInstanceDetails=function(e){window.dashboard&&"function"==typeof window.dashboard.showAgentInstanceDetails?window.dashboard.showAgentInstanceDetails(e):console.error("Dashboard not available or method not found")},document.addEventListener("DOMContentLoaded",function(){window.dashboard=new d,console.log("Dashboard loaded and initialized")});
2
+ //# sourceMappingURL=dashboard.js.map
@@ -0,0 +1,2 @@
1
+ const t=window.io;class e{constructor(){this.socket=null,this.port=null,this.connectionCallbacks={connect:[],disconnect:[],error:[],event:[]},this.isConnected=!1,this.isConnecting=!1,this.events=[],this.sessions=new Map,this.currentSessionId=null,this.startStatusCheckFallback()}connect(t="8765"){this.port=t;const e=`http://localhost:${t}`;if(this.socket&&(this.socket.connected||this.socket.connecting))return console.log("Already connected or connecting, disconnecting first..."),this.socket.disconnect(),void setTimeout(()=>this.doConnect(e),100);this.doConnect(e)}doConnect(e){if(console.log(`Connecting to Socket.IO server at ${e}`),void 0===t)return console.error("Socket.IO library not loaded! Make sure socket.io.min.js is loaded before this script."),void this.notifyConnectionStatus("Socket.IO library not loaded","error");this.isConnecting=!0,this.notifyConnectionStatus("Connecting...","connecting"),this.socket=t(e,{autoConnect:!0,reconnection:!0,reconnectionDelay:1e3,reconnectionDelayMax:1e4,maxReconnectionAttempts:10,timeout:1e4,forceNew:!0,transports:["websocket","polling"]}),this.setupSocketHandlers()}setupSocketHandlers(){this.socket.on("connect",()=>{console.log("Connected to Socket.IO server"),this.isConnected=!0,this.isConnecting=!1,this.notifyConnectionStatus("Connected","connected"),this.connectionCallbacks.connect.forEach(t=>t(this.socket.id)),this.requestStatus()}),this.socket.on("disconnect",t=>{console.log("Disconnected from server:",t),this.isConnected=!1,this.isConnecting=!1,this.notifyConnectionStatus(`Disconnected: ${t}`,"disconnected"),this.connectionCallbacks.disconnect.forEach(e=>e(t))}),this.socket.on("connect_error",t=>{console.error("Connection error:",t),this.isConnecting=!1;const e=t.message||t.description||"Unknown error";this.notifyConnectionStatus(`Connection Error: ${e}`,"disconnected"),this.addEvent({type:"connection.error",timestamp:(new Date).toISOString(),data:{error:e,url:this.socket.io.uri}}),this.connectionCallbacks.error.forEach(t=>t(e))}),this.socket.on("claude_event",t=>{const e=this.transformEvent(t);this.addEvent(e)}),this.socket.on("session.started",t=>{this.addEvent({type:"session",subtype:"started",timestamp:(new Date).toISOString(),data:t})}),this.socket.on("session.ended",t=>{this.addEvent({type:"session",subtype:"ended",timestamp:(new Date).toISOString(),data:t})}),this.socket.on("claude.request",t=>{this.addEvent({type:"claude",subtype:"request",timestamp:(new Date).toISOString(),data:t})}),this.socket.on("claude.response",t=>{this.addEvent({type:"claude",subtype:"response",timestamp:(new Date).toISOString(),data:t})}),this.socket.on("agent.loaded",t=>{this.addEvent({type:"agent",subtype:"loaded",timestamp:(new Date).toISOString(),data:t})}),this.socket.on("agent.executed",t=>{this.addEvent({type:"agent",subtype:"executed",timestamp:(new Date).toISOString(),data:t})}),this.socket.on("hook.pre",t=>{this.addEvent({type:"hook",subtype:"pre",timestamp:(new Date).toISOString(),data:t})}),this.socket.on("hook.post",t=>{this.addEvent({type:"hook",subtype:"post",timestamp:(new Date).toISOString(),data:t})}),this.socket.on("todo.updated",t=>{this.addEvent({type:"todo",subtype:"updated",timestamp:(new Date).toISOString(),data:t})}),this.socket.on("memory.operation",t=>{this.addEvent({type:"memory",subtype:"operation",timestamp:(new Date).toISOString(),data:t})}),this.socket.on("log.entry",t=>{this.addEvent({type:"log",subtype:"entry",timestamp:(new Date).toISOString(),data:t})}),this.socket.on("history",t=>{console.log("Received event history:",t),t&&Array.isArray(t.events)?(console.log(`Processing ${t.events.length} historical events (${t.count} sent, ${t.total_available} total available)`),t.events.forEach(t=>{const e=this.transformEvent(t);this.addEvent(e,!1)}),this.notifyEventUpdate(),console.log(`Event history loaded: ${t.events.length} events added to dashboard`)):Array.isArray(t)&&(console.log("Received legacy event history format:",t.length,"events"),t.forEach(t=>{const e=this.transformEvent(t);this.addEvent(e,!1)}),this.notifyEventUpdate())}),this.socket.on("system.status",t=>{console.log("Received system status:",t),t.sessions&&this.updateSessions(t.sessions),t.current_session&&(this.currentSessionId=t.current_session)})}disconnect(){this.socket&&(this.socket.disconnect(),this.socket=null),this.port=null,this.isConnected=!1,this.isConnecting=!1}requestStatus(){this.socket&&this.socket.connected&&(console.log("Requesting server status..."),this.socket.emit("request.status"))}requestHistory(t={}){if(this.socket&&this.socket.connected){const e={limit:t.limit||50,event_types:t.event_types||[]};console.log("Requesting event history...",e),this.socket.emit("get_history",e)}else console.warn("Cannot request history: not connected to server")}addEvent(t,e=!0){if(t.timestamp||(t.timestamp=(new Date).toISOString()),t.id||(t.id=Date.now()+Math.random()),this.events.push(t),t.data&&t.data.session_id){const e=t.data.session_id;this.sessions.has(e)||this.sessions.set(e,{id:e,startTime:t.timestamp,lastActivity:t.timestamp,eventCount:0});const n=this.sessions.get(e);n.lastActivity=t.timestamp,n.eventCount++}e&&this.notifyEventUpdate()}updateSessions(t){Array.isArray(t)&&t.forEach(t=>{this.sessions.set(t.id,t)})}clearEvents(){this.events=[],this.sessions.clear(),this.notifyEventUpdate()}refreshHistory(t={}){this.clearEvents(),this.requestHistory(t)}getEventsBySession(t=null){return t?this.events.filter(e=>e.data&&e.data.session_id===t):this.events}onConnection(t,e){this.connectionCallbacks[t]&&this.connectionCallbacks[t].push(e)}onEventUpdate(t){this.connectionCallbacks.event.push(t)}notifyConnectionStatus(t,e){console.log(`SocketClient: Connection status changed to '${t}' (${e})`),this.updateConnectionStatusDOM(t,e),document.dispatchEvent(new CustomEvent("socketConnectionStatus",{detail:{status:t,type:e}}))}updateConnectionStatusDOM(t,e){const n=document.getElementById("connection-status");n?(n.innerHTML=`<span>●</span> ${t}`,n.className=`status-badge status-${e}`,console.log(`SocketClient: Direct DOM update - status: '${t}' (${e})`)):console.warn("SocketClient: Could not find connection-status element in DOM")}notifyEventUpdate(){this.connectionCallbacks.event.forEach(t=>t(this.events,this.sessions)),document.dispatchEvent(new CustomEvent("socketEventUpdate",{detail:{events:this.events,sessions:this.sessions}}))}getConnectionState(){return{isConnected:this.isConnected,isConnecting:this.isConnecting,socketId:this.socket?this.socket.id:null}}transformEvent(t){if(!t)return t;let e={...t};if(!t.type&&t.event){const n=t.event;"TestStart"===n||"TestEnd"===n?(e.type="test",e.subtype=n.toLowerCase().replace("test","")):"SubagentStart"===n||"SubagentStop"===n?(e.type="subagent",e.subtype=n.toLowerCase().replace("subagent","")):"ToolCall"===n?(e.type="tool",e.subtype="call"):"UserPrompt"===n?(e.type="hook",e.subtype="user_prompt"):(e.type="system",e.subtype=n.toLowerCase()),delete e.event}else if(t.type){const n=t.type;if(n.startsWith("hook.")){const t=n.substring(5);e.type="hook",e.subtype=t}else if(n.includes(".")){const[t,...s]=n.split(".");e.type=t,e.subtype=s.join(".")}}else e.type="unknown",e.subtype="";return t.data&&"object"==typeof t.data&&(Object.keys(t.data).forEach(n=>{e[n]=t.data[n]}),e.data=t.data),"hook"!==e.type||"pre_tool"!==e.subtype&&"post_tool"!==e.subtype||console.log("Transformed tool event:",{type:e.type,subtype:e.subtype,tool_name:e.tool_name,has_data:!!e.data,keys:Object.keys(e).filter(t=>"data"!==t)}),e}getState(){return{events:this.events,sessions:this.sessions,currentSessionId:this.currentSessionId}}startStatusCheckFallback(){setInterval(()=>{this.checkAndUpdateStatus()},2e3),"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{setTimeout(()=>this.checkAndUpdateStatus(),100)}):setTimeout(()=>this.checkAndUpdateStatus(),100)}checkAndUpdateStatus(){let t="Disconnected",e="disconnected";this.socket&&(this.socket.connected?(t="Connected",e="connected",this.isConnected=!0,this.isConnecting=!1):this.socket.connecting||this.isConnecting?(t="Connecting...",e="connecting",this.isConnected=!1):(t="Disconnected",e="disconnected",this.isConnected=!1,this.isConnecting=!1));const n=document.getElementById("connection-status");if(n){const s=n.textContent.replace("●","").trim(),o=n.className,i=`status-badge status-${e}`;s===t&&o===i||(console.log(`SocketClient: Fallback update - was '${s}' (${o}), now '${t}' (${i})`),this.updateConnectionStatusDOM(t,e))}}}window.SocketClient=e;class n{constructor(){this.socketClient=null,this.connectionCallbacks=new Set,this.eventUpdateCallbacks=new Set,this.socketClient=new e,window.socketClient=this.socketClient,this.setupSocketEventHandlers(),setTimeout(()=>{this.updateInitialConnectionStatus()},100),console.log("Socket manager initialized")}setupSocketEventHandlers(){document.addEventListener("socketConnectionStatus",t=>{console.log(`SocketManager: Processing connection status update: ${t.detail.status} (${t.detail.type})`),this.handleConnectionStatusChange(t.detail.status,t.detail.type),this.connectionCallbacks.forEach(e=>{try{e(t.detail.status,t.detail.type)}catch(n){console.error("Error in connection callback:",n)}})}),this.socketClient&&this.socketClient.onEventUpdate(t=>{this.eventUpdateCallbacks.forEach(e=>{try{e(t)}catch(n){console.error("Error in event update callback:",n)}})})}handleConnectionStatusChange(t,e){this.updateConnectionStatus(t,e),"connected"===e&&this.socketClient&&this.socketClient.socket&&this.setupGitBranchListener()}updateInitialConnectionStatus(){console.log("SocketManager: Updating initial connection status"),this.socketClient&&"function"==typeof this.socketClient.checkAndUpdateStatus?(console.log("SocketManager: Using socket client checkAndUpdateStatus method"),this.socketClient.checkAndUpdateStatus()):this.socketClient&&this.socketClient.socket?(console.log("SocketManager: Checking socket state directly",{connected:this.socketClient.socket.connected,connecting:this.socketClient.socket.connecting,isConnecting:this.socketClient.isConnecting,isConnected:this.socketClient.isConnected}),this.socketClient.socket.connected?(console.log("SocketManager: Socket is already connected, updating status"),this.updateConnectionStatus("Connected","connected")):this.socketClient.isConnecting||this.socketClient.socket.connecting?(console.log("SocketManager: Socket is connecting, updating status"),this.updateConnectionStatus("Connecting...","connecting")):(console.log("SocketManager: Socket is disconnected, updating status"),this.updateConnectionStatus("Disconnected","disconnected"))):(console.log("SocketManager: No socket client or socket found, setting disconnected status"),this.updateConnectionStatus("Disconnected","disconnected")),setTimeout(()=>{console.log("SocketManager: Secondary status check after 1 second"),this.socketClient&&this.socketClient.socket&&this.socketClient.socket.connected&&(console.log("SocketManager: Socket connected in secondary check, updating status"),this.updateConnectionStatus("Connected","connected"))},1e3)}setupGitBranchListener(){this.socketClient.socket.off("git_branch_response"),this.socketClient.socket.on("git_branch_response",t=>{if(t.success){const e=document.getElementById("footer-git-branch");e&&(e.textContent=t.branch||"unknown"),e&&(e.style.display="inline")}else console.error("Git branch request failed:",t.error)})}updateConnectionStatus(t,e){const n=document.getElementById("connection-status");if(n){if(n.querySelector("span")){const e="●";n.innerHTML=`<span>${e}</span> ${t}`}else n.textContent=t;n.className=`status-badge status-${e}`,console.log(`SocketManager: UI updated - status: '${t}' (${e})`)}else console.error("SocketManager: Could not find connection-status element in DOM")}connect(t){this.socketClient&&this.socketClient.connect(t)}disconnect(){this.socketClient&&this.socketClient.disconnect()}isConnected(){return this.socketClient&&this.socketClient.isConnected}isConnecting(){return this.socketClient&&this.socketClient.isConnecting}getSocketClient(){return this.socketClient}getSocket(){return this.socketClient?this.socketClient.socket:null}onConnectionStatusChange(t){this.connectionCallbacks.add(t)}offConnectionStatusChange(t){this.connectionCallbacks.delete(t)}onEventUpdate(t){this.eventUpdateCallbacks.add(t)}offEventUpdate(t){this.eventUpdateCallbacks.delete(t)}toggleConnectionControls(){const t=document.getElementById("connection-controls-row"),e=document.getElementById("connection-toggle-btn");if(t&&e){t.classList.contains("show")?(t.classList.remove("show"),t.style.display="none",e.textContent="Connection Settings"):(t.classList.add("show"),t.style.display="block",e.textContent="Hide Settings")}}setupConnectionControls(){const t=document.getElementById("connect-btn"),e=document.getElementById("disconnect-btn"),n=document.getElementById("connection-toggle-btn");t&&t.addEventListener("click",()=>{const t=document.getElementById("port-input").value||8765;this.connect(t)}),e&&e.addEventListener("click",()=>{this.disconnect()}),n&&n.addEventListener("click",()=>{this.toggleConnectionControls()})}initializeFromURL(t){const e=t.get("port"),n=document.getElementById("port-input");let s=e;s||"http:"!==window.location.protocol||(s=window.location.port||"8765"),s||(s=n?.value||"8765"),n&&(n.value=s);!("false"!==t.get("connect"))||this.isConnected()||this.isConnecting()||this.connect(s)}}class s{constructor(){this.currentTab="events",this.autoScroll=!0,this.selectedCard={tab:null,index:null,type:null,data:null},this.tabNavigation={events:{selectedIndex:-1,items:[]},agents:{selectedIndex:-1,items:[]},tools:{selectedIndex:-1,items:[]},files:{selectedIndex:-1,items:[]}},this.setupEventHandlers(),console.log("UI state manager initialized")}setupEventHandlers(){this.setupTabNavigation(),this.setupUnifiedKeyboardNavigation()}setupTabNavigation(){document.querySelectorAll(".tab-button").forEach(t=>{t.addEventListener("click",()=>{const e=this.getTabNameFromButton(t);this.switchTab(e)})})}setupUnifiedKeyboardNavigation(){document.addEventListener("keydown",t=>{document.activeElement&&["INPUT","TEXTAREA","SELECT"].includes(document.activeElement.tagName)||("ArrowUp"===t.key||"ArrowDown"===t.key?(t.preventDefault(),this.handleUnifiedArrowNavigation("ArrowDown"===t.key?1:-1)):"Enter"===t.key?(t.preventDefault(),this.handleUnifiedEnterKey()):"Escape"===t.key&&this.clearUnifiedSelection())})}getTabNameFromButton(t){const e=t.textContent.toLowerCase();return e.includes("events")?"events":e.includes("agents")?"agents":e.includes("tools")?"tools":e.includes("files")?"files":"events"}switchTab(t){console.log(`[DEBUG] switchTab called with tabName: ${t}`);const e=this.currentTab;this.currentTab=t,document.querySelectorAll(".tab-button").forEach(e=>{e.classList.remove("active"),this.getTabNameFromButton(e)===t&&e.classList.add("active")}),document.querySelectorAll(".tab-content").forEach(t=>{t.classList.remove("active")});const n=document.getElementById(`${t}-tab`);n&&n.classList.add("active"),this.clearUnifiedSelection(),document.dispatchEvent(new CustomEvent("tabChanged",{detail:{newTab:t,previousTab:e}})),setTimeout(()=>{this.autoScroll&&this.scrollCurrentTabToBottom()},100)}handleUnifiedArrowNavigation(t){const e=this.tabNavigation[this.currentTab];if(!e)return;let n=e.selectedIndex+t;0!==e.items.length&&(n<0?n=e.items.length-1:n>=e.items.length&&(n=0),this.selectCardByIndex(this.currentTab,n))}handleUnifiedEnterKey(){const t=this.tabNavigation[this.currentTab];if(!t||-1===t.selectedIndex)return;const e=t.items[t.selectedIndex];e&&e.onclick&&e.onclick()}clearUnifiedSelection(){Object.keys(this.tabNavigation).forEach(t=>{this.tabNavigation[t].selectedIndex=-1}),this.clearCardSelection()}updateTabNavigationItems(){const t=this.tabNavigation[this.currentTab];if(!t)return;let e;switch(this.currentTab){case"events":e="#events-list .event-item";break;case"agents":e="#agents-list .event-item";break;case"tools":e="#tools-list .event-item";break;case"files":e="#files-list .event-item"}e&&(t.items=Array.from(document.querySelectorAll(e)))}selectCardByIndex(t,e){const n=this.tabNavigation[t];if(!n||e<0||e>=n.items.length)return;n.selectedIndex=e,this.updateUnifiedSelectionUI();n.items[e]&&this.selectCard(t,e,this.getCardType(t),e),this.showCardDetails(t,e)}updateUnifiedSelectionUI(){document.querySelectorAll(".event-item.keyboard-selected").forEach(t=>{t.classList.remove("keyboard-selected")});const t=this.tabNavigation[this.currentTab];t&&-1!==t.selectedIndex&&t.items[t.selectedIndex]&&t.items[t.selectedIndex].classList.add("keyboard-selected")}showCardDetails(t,e){document.dispatchEvent(new CustomEvent("showCardDetails",{detail:{tabName:t,index:e}}))}selectCard(t,e,n,s){this.clearCardSelection(),this.selectedCard={tab:t,index:e,type:n,data:s},this.updateCardSelectionUI(),console.log("Card selected:",this.selectedCard)}clearCardSelection(){document.querySelectorAll(".event-item.selected, .file-item.selected").forEach(t=>{t.classList.remove("selected")}),this.selectedCard={tab:null,index:null,type:null,data:null}}updateCardSelectionUI(){if(!this.selectedCard.tab||null===this.selectedCard.index)return;let t;switch(this.selectedCard.tab){case"events":t=document.getElementById("events-list");break;case"agents":t=document.getElementById("agents-list");break;case"tools":t=document.getElementById("tools-list");break;case"files":t=document.getElementById("files-list")}if(t){const e=t.querySelectorAll(".event-item, .file-item");e[this.selectedCard.index]&&e[this.selectedCard.index].classList.add("selected")}}getCardType(t){switch(t){case"events":return"event";case"agents":return"agent";case"tools":return"tool";case"files":return"file";default:return"unknown"}}scrollCurrentTabToBottom(){const t=`${this.currentTab}-list`,e=document.getElementById(t);e&&this.autoScroll&&(e.scrollTop=e.scrollHeight)}clearSelection(){this.clearCardSelection(),this.clearUnifiedSelection()}getCurrentTab(){return this.currentTab}getSelectedCard(){return{...this.selectedCard}}getTabNavigation(){return{...this.tabNavigation}}setAutoScroll(t){this.autoScroll=t}getAutoScroll(){return this.autoScroll}}export{n as S,s as U};
2
+ //# sourceMappingURL=socket-client.js.map
@@ -1,13 +1,13 @@
1
1
  /**
2
2
  * Agent Inference Module
3
- *
3
+ *
4
4
  * Handles agent inference and processing logic for determining whether events
5
5
  * originate from the main agent or subagents based on event patterns and context.
6
- *
6
+ *
7
7
  * WHY: Separated from main dashboard to isolate complex agent inference logic
8
8
  * that analyzes event patterns to determine agent context. This provides better
9
9
  * maintainability and testability for a critical feature.
10
- *
10
+ *
11
11
  * DESIGN DECISION: This module maintains its own state for inference tracking
12
12
  * but relies on the event viewer for source data, keeping clear separation of
13
13
  * concerns while enabling delegation context tracking across events.
@@ -15,7 +15,7 @@
15
15
  class AgentInference {
16
16
  constructor(eventViewer) {
17
17
  this.eventViewer = eventViewer;
18
-
18
+
19
19
  // Agent inference state tracking
20
20
  this.state = {
21
21
  // Track current subagent delegation context
@@ -29,7 +29,7 @@ class AgentInference {
29
29
  // Map of agent events to their PM delegation
30
30
  agentToDelegation: new Map() // agent_name -> delegation_id
31
31
  };
32
-
32
+
33
33
  console.log('Agent inference system initialized');
34
34
  }
35
35
 
@@ -60,12 +60,12 @@ class AgentInference {
60
60
  const eventType = event.hook_event_name || data.hook_event_name || event.type || '';
61
61
  const subtype = event.subtype || data.subtype || '';
62
62
  const toolName = event.tool_name || data.tool_name || '';
63
-
63
+
64
64
  // Debug logging for first few events to understand structure
65
65
  if (Math.random() < 0.1) {
66
66
  console.log('Agent inference debug:', {
67
- eventType,
68
- toolName,
67
+ eventType,
68
+ toolName,
69
69
  hasData: !!event.data,
70
70
  dataKeys: Object.keys(data),
71
71
  eventKeys: Object.keys(event),
@@ -73,7 +73,7 @@ class AgentInference {
73
73
  subagentType: event.subagent_type || data.subagent_type
74
74
  });
75
75
  }
76
-
76
+
77
77
  // Direct event detection (highest confidence) - from design doc
78
78
  if (eventType === 'SubagentStop' || subtype === 'subagent_stop') {
79
79
  const agentName = this.extractAgentNameFromEvent(event);
@@ -92,7 +92,7 @@ class AgentInference {
92
92
  reason: 'SubagentStop event'
93
93
  };
94
94
  }
95
-
95
+
96
96
  if (eventType === 'Stop' || subtype === 'stop') {
97
97
  return {
98
98
  type: 'main_agent',
@@ -101,7 +101,7 @@ class AgentInference {
101
101
  reason: 'Stop event'
102
102
  };
103
103
  }
104
-
104
+
105
105
  // Tool-based detection (high confidence) - from design doc
106
106
  if (toolName === 'Task') {
107
107
  const agentName = this.extractSubagentTypeFromTask(event);
@@ -120,7 +120,7 @@ class AgentInference {
120
120
  };
121
121
  }
122
122
  }
123
-
123
+
124
124
  // Hook event pattern analysis (high confidence)
125
125
  if (eventType === 'PreToolUse' && toolName === 'Task') {
126
126
  const agentName = this.extractSubagentTypeFromTask(event);
@@ -133,7 +133,7 @@ class AgentInference {
133
133
  };
134
134
  }
135
135
  }
136
-
136
+
137
137
  // Session pattern analysis (medium confidence) - from design doc
138
138
  if (sessionId) {
139
139
  const sessionLower = sessionId.toLowerCase();
@@ -146,11 +146,11 @@ class AgentInference {
146
146
  };
147
147
  }
148
148
  }
149
-
149
+
150
150
  // Agent type field analysis - check multiple possible locations
151
151
  const agentType = event.agent_type || data.agent_type || event.agent_id || data.agent_id;
152
152
  const subagentType = event.subagent_type || data.subagent_type;
153
-
153
+
154
154
  if (subagentType && subagentType !== 'unknown') {
155
155
  return {
156
156
  type: 'subagent',
@@ -159,7 +159,7 @@ class AgentInference {
159
159
  reason: 'subagent_type field'
160
160
  };
161
161
  }
162
-
162
+
163
163
  if (agentType && agentType !== 'unknown' && agentType !== 'main') {
164
164
  return {
165
165
  type: 'subagent',
@@ -168,7 +168,7 @@ class AgentInference {
168
168
  reason: 'agent_type field'
169
169
  };
170
170
  }
171
-
171
+
172
172
  // Check for delegation_details from hook handler
173
173
  if (data.delegation_details?.agent_type) {
174
174
  return {
@@ -178,12 +178,12 @@ class AgentInference {
178
178
  reason: 'delegation_details'
179
179
  };
180
180
  }
181
-
181
+
182
182
  // Check if this looks like a Hook event from Socket.IO
183
183
  if (event.type && event.type.startsWith('hook.')) {
184
184
  // Extract the hook type
185
185
  const hookType = event.type.replace('hook.', '');
186
-
186
+
187
187
  // Handle SubagentStart events
188
188
  if (hookType === 'subagent_start' || (data.hook_event_name === 'SubagentStart')) {
189
189
  const rawAgentName = data.agent_type || data.agent_id || 'Subagent';
@@ -199,7 +199,7 @@ class AgentInference {
199
199
  reason: 'Socket.IO hook SubagentStart'
200
200
  };
201
201
  }
202
-
202
+
203
203
  // Handle SubagentStop events
204
204
  if (hookType === 'subagent_stop' || (data.hook_event_name === 'SubagentStop')) {
205
205
  const rawAgentName = data.agent_type || data.agent_id || 'Subagent';
@@ -211,7 +211,7 @@ class AgentInference {
211
211
  };
212
212
  }
213
213
  }
214
-
214
+
215
215
  // Default to main agent (from design doc)
216
216
  return {
217
217
  type: 'main_agent',
@@ -228,7 +228,7 @@ class AgentInference {
228
228
  */
229
229
  normalizeAgentName(agentName) {
230
230
  if (!agentName) return 'Unknown';
231
-
231
+
232
232
  // Agent name mapping from raw format to display format
233
233
  const agentNameMap = {
234
234
  'engineer': 'Engineer Agent',
@@ -242,13 +242,13 @@ class AgentInference {
242
242
  'test_integration': 'Test Integration Agent',
243
243
  'pm': 'PM Agent'
244
244
  };
245
-
245
+
246
246
  // Check if we have a direct mapping
247
247
  const normalized = agentNameMap[agentName.toLowerCase()];
248
248
  if (normalized) {
249
249
  return normalized;
250
250
  }
251
-
251
+
252
252
  // If no direct mapping, apply basic formatting:
253
253
  // Convert underscore to space, capitalize words, and add "Agent" if not present
254
254
  let formatted = agentName
@@ -256,12 +256,12 @@ class AgentInference {
256
256
  .split(' ')
257
257
  .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
258
258
  .join(' ');
259
-
259
+
260
260
  // Add "Agent" suffix if not already present
261
261
  if (!formatted.toLowerCase().includes('agent')) {
262
262
  formatted += ' Agent';
263
263
  }
264
-
264
+
265
265
  return formatted;
266
266
  }
267
267
 
@@ -272,7 +272,7 @@ class AgentInference {
272
272
  */
273
273
  extractSubagentTypeFromTask(event) {
274
274
  let rawAgentName = null;
275
-
275
+
276
276
  // Check tool_parameters directly
277
277
  if (event.tool_parameters?.subagent_type) {
278
278
  rawAgentName = event.tool_parameters.subagent_type;
@@ -289,7 +289,7 @@ class AgentInference {
289
289
  else if (event.tool_input?.subagent_type) {
290
290
  rawAgentName = event.tool_input.subagent_type;
291
291
  }
292
-
292
+
293
293
  // Normalize the agent name before returning
294
294
  return rawAgentName ? this.normalizeAgentName(rawAgentName) : null;
295
295
  }
@@ -302,13 +302,13 @@ class AgentInference {
302
302
  extractAgentNameFromEvent(event) {
303
303
  // Priority order based on reliability from design doc
304
304
  const data = event.data || {};
305
-
305
+
306
306
  // 1. Task tool subagent_type (highest priority)
307
307
  if (event.tool_name === 'Task' || data.tool_name === 'Task') {
308
308
  const taskAgent = this.extractSubagentTypeFromTask(event);
309
309
  if (taskAgent) return taskAgent;
310
310
  }
311
-
311
+
312
312
  // 2. Direct subagent_type field
313
313
  if (event.subagent_type && event.subagent_type !== 'unknown') {
314
314
  return this.normalizeAgentName(event.subagent_type);
@@ -316,12 +316,12 @@ class AgentInference {
316
316
  if (data.subagent_type && data.subagent_type !== 'unknown') {
317
317
  return this.normalizeAgentName(data.subagent_type);
318
318
  }
319
-
319
+
320
320
  // 2.5. Check delegation_details
321
321
  if (data.delegation_details?.agent_type && data.delegation_details.agent_type !== 'unknown') {
322
322
  return this.normalizeAgentName(data.delegation_details.agent_type);
323
323
  }
324
-
324
+
325
325
  // 3. Agent type fields (but not 'main' or 'unknown')
326
326
  if (event.agent_type && !['main', 'unknown'].includes(event.agent_type)) {
327
327
  return this.normalizeAgentName(event.agent_type);
@@ -329,7 +329,7 @@ class AgentInference {
329
329
  if (data.agent_type && !['main', 'unknown'].includes(data.agent_type)) {
330
330
  return this.normalizeAgentName(data.agent_type);
331
331
  }
332
-
332
+
333
333
  // 4. Agent ID field as fallback
334
334
  if (event.agent_id && !['main', 'unknown'].includes(event.agent_id)) {
335
335
  return this.normalizeAgentName(event.agent_id);
@@ -337,16 +337,16 @@ class AgentInference {
337
337
  if (data.agent_id && !['main', 'unknown'].includes(data.agent_id)) {
338
338
  return this.normalizeAgentName(data.agent_id);
339
339
  }
340
-
340
+
341
341
  // 5. Other fallbacks
342
342
  if (event.agent && event.agent !== 'unknown') {
343
343
  return this.normalizeAgentName(event.agent);
344
344
  }
345
-
345
+
346
346
  if (event.name && event.name !== 'unknown') {
347
347
  return this.normalizeAgentName(event.name);
348
348
  }
349
-
349
+
350
350
  // Default fallback
351
351
  return 'Unknown';
352
352
  }
@@ -357,37 +357,37 @@ class AgentInference {
357
357
  */
358
358
  processAgentInference() {
359
359
  const events = this.eventViewer.events;
360
-
360
+
361
361
  // Reset inference state
362
362
  this.state.currentDelegation = null;
363
363
  this.state.sessionAgents.clear();
364
364
  this.state.eventAgentMap.clear();
365
365
  this.state.pmDelegations.clear();
366
366
  this.state.agentToDelegation.clear();
367
-
367
+
368
368
  console.log('Processing agent inference for', events.length, 'events');
369
-
369
+
370
370
  // Early return if no events
371
371
  if (!events || events.length === 0) {
372
372
  console.log('No events to process for agent inference');
373
373
  return;
374
374
  }
375
-
375
+
376
376
  // Process events chronologically to track delegation context
377
377
  events.forEach((event, index) => {
378
378
  let finalAgent; // Declare outside try-catch to ensure scope availability
379
-
379
+
380
380
  try {
381
381
  const inference = this.inferAgentFromEvent(event);
382
382
  const sessionId = event.session_id || event.data?.session_id || 'default';
383
-
383
+
384
384
  // Determine agent for this event based on context
385
385
  finalAgent = inference;
386
-
386
+
387
387
  // If we're in a delegation context and this event doesn't have high confidence agent info,
388
388
  // inherit from delegation context
389
- if (this.state.currentDelegation &&
390
- inference.confidence === 'default' &&
389
+ if (this.state.currentDelegation &&
390
+ inference.confidence === 'default' &&
391
391
  sessionId === this.state.currentDelegation.sessionId) {
392
392
  finalAgent = {
393
393
  type: 'subagent',
@@ -396,7 +396,7 @@ class AgentInference {
396
396
  reason: 'inherited from delegation context'
397
397
  };
398
398
  }
399
-
399
+
400
400
  // Track delegation boundaries and PM delegations
401
401
  if (event.tool_name === 'Task' && inference.type === 'subagent') {
402
402
  // Start of subagent delegation - create PM delegation entry
@@ -411,10 +411,10 @@ class AgentInference {
411
411
  timestamp: event.timestamp,
412
412
  agentEvents: [] // Collect all events from this agent
413
413
  };
414
-
414
+
415
415
  this.state.pmDelegations.set(delegationId, pmDelegation);
416
416
  this.state.agentToDelegation.set(inference.agentName, delegationId);
417
-
417
+
418
418
  this.state.currentDelegation = {
419
419
  agentName: inference.agentName,
420
420
  sessionId: sessionId,
@@ -427,18 +427,18 @@ class AgentInference {
427
427
  // End of subagent delegation
428
428
  if (this.state.currentDelegation) {
429
429
  this.state.currentDelegation.endIndex = index;
430
-
430
+
431
431
  // Update PM delegation end point
432
432
  const pmDelegation = this.state.pmDelegations.get(this.state.currentDelegation.delegationId);
433
433
  if (pmDelegation) {
434
434
  pmDelegation.endIndex = index;
435
435
  }
436
-
436
+
437
437
  console.log('Delegation ended:', this.state.currentDelegation);
438
438
  this.state.currentDelegation = null;
439
439
  }
440
440
  }
441
-
441
+
442
442
  // Track events within PM delegation context
443
443
  if (this.state.currentDelegation && finalAgent.type === 'subagent') {
444
444
  const pmDelegation = this.state.pmDelegations.get(this.state.currentDelegation.delegationId);
@@ -450,13 +450,13 @@ class AgentInference {
450
450
  });
451
451
  }
452
452
  }
453
-
453
+
454
454
  // Store the inference result
455
455
  this.state.eventAgentMap.set(index, finalAgent);
456
-
456
+
457
457
  // Update session agent tracking
458
458
  this.state.sessionAgents.set(sessionId, finalAgent);
459
-
459
+
460
460
  // Debug first few inferences
461
461
  if (index < 5) {
462
462
  console.log(`Event ${index} agent inference:`, {
@@ -470,7 +470,7 @@ class AgentInference {
470
470
  }
471
471
  } catch (error) {
472
472
  console.error(`Error processing event ${index} for agent inference:`, error);
473
-
473
+
474
474
  // Set a default finalAgent if not already set due to error
475
475
  if (!finalAgent) {
476
476
  finalAgent = {
@@ -480,12 +480,12 @@ class AgentInference {
480
480
  reason: 'error during processing'
481
481
  };
482
482
  }
483
-
483
+
484
484
  // Store the default inference for this event
485
485
  this.state.eventAgentMap.set(index, finalAgent);
486
486
  }
487
487
  });
488
-
488
+
489
489
  console.log('Agent inference processing complete. Results:', {
490
490
  total_events: events.length,
491
491
  inferred_agents: this.state.eventAgentMap.size,
@@ -511,24 +511,24 @@ class AgentInference {
511
511
  */
512
512
  getInferredAgentForEvent(event) {
513
513
  const events = this.eventViewer.events;
514
-
514
+
515
515
  // Try to find by exact reference first
516
516
  let eventIndex = events.indexOf(event);
517
-
517
+
518
518
  // If exact match fails, try to find by timestamp or session_id + timestamp
519
519
  if (eventIndex === -1 && event.timestamp) {
520
- eventIndex = events.findIndex(e =>
521
- e.timestamp === event.timestamp &&
520
+ eventIndex = events.findIndex(e =>
521
+ e.timestamp === event.timestamp &&
522
522
  e.session_id === event.session_id
523
523
  );
524
524
  }
525
-
525
+
526
526
  // If we still can't find it, perform inline inference
527
527
  if (eventIndex === -1) {
528
528
  console.log('Agent inference: Could not find event in events array, performing inline inference');
529
529
  return this.inferAgentFromEvent(event);
530
530
  }
531
-
531
+
532
532
  // Get cached inference or perform new inference
533
533
  let inference = this.getInferredAgent(eventIndex);
534
534
  if (!inference) {
@@ -536,7 +536,7 @@ class AgentInference {
536
536
  // Cache the result
537
537
  this.state.eventAgentMap.set(eventIndex, inference);
538
538
  }
539
-
539
+
540
540
  return inference;
541
541
  }
542
542
 
@@ -587,11 +587,11 @@ class AgentInference {
587
587
  */
588
588
  getUniqueAgentInstances() {
589
589
  const agentMap = new Map(); // agentName -> consolidated data
590
-
590
+
591
591
  // Consolidate all PM delegations by agent name
592
592
  for (const [delegationId, delegation] of this.state.pmDelegations) {
593
593
  const agentName = delegation.agentName;
594
-
594
+
595
595
  if (!agentMap.has(agentName)) {
596
596
  // First delegation for this agent type
597
597
  agentMap.set(agentName, {
@@ -607,7 +607,7 @@ class AgentInference {
607
607
  delegationCount: 1
608
608
  });
609
609
  }
610
-
610
+
611
611
  // Add this delegation to the consolidated agent
612
612
  const agent = agentMap.get(agentName);
613
613
  agent.delegations.push({
@@ -619,14 +619,14 @@ class AgentInference {
619
619
  endIndex: delegation.endIndex,
620
620
  events: delegation.agentEvents
621
621
  });
622
-
622
+
623
623
  if (delegation.pmCall) {
624
624
  agent.pmCalls.push(delegation.pmCall);
625
625
  }
626
-
626
+
627
627
  // Merge events from all delegations
628
628
  agent.allEvents = agent.allEvents.concat(delegation.agentEvents);
629
-
629
+
630
630
  // Update consolidated metadata
631
631
  if (new Date(delegation.timestamp) < new Date(agent.firstTimestamp)) {
632
632
  agent.firstTimestamp = delegation.timestamp;
@@ -634,11 +634,11 @@ class AgentInference {
634
634
  if (new Date(delegation.timestamp) > new Date(agent.lastTimestamp)) {
635
635
  agent.lastTimestamp = delegation.timestamp;
636
636
  }
637
-
637
+
638
638
  agent.totalEventCount += delegation.agentEvents.length;
639
639
  agent.delegationCount++;
640
640
  }
641
-
641
+
642
642
  // Handle agents that appear without explicit PM delegation (implied PM)
643
643
  const events = this.eventViewer.events;
644
644
  for (let index = 0; index < events.length; index++) {
@@ -676,11 +676,11 @@ class AgentInference {
676
676
  });
677
677
  }
678
678
  }
679
-
679
+
680
680
  // Convert map to array and sort by first appearance (timestamp)
681
681
  const uniqueInstances = Array.from(agentMap.values())
682
682
  .sort((a, b) => new Date(a.firstTimestamp) - new Date(b.firstTimestamp));
683
-
683
+
684
684
  console.log('Consolidated unique agents:', {
685
685
  total_unique_agents: uniqueInstances.length,
686
686
  agents: uniqueInstances.map(agent => ({
@@ -689,7 +689,11 @@ class AgentInference {
689
689
  totalEvents: agent.totalEventCount
690
690
  }))
691
691
  });
692
-
692
+
693
693
  return uniqueInstances;
694
694
  }
695
- }
695
+ }
696
+
697
+ // ES6 Module export
698
+ export { AgentInference };
699
+ export default AgentInference;