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
@@ -12,7 +12,7 @@ class HUDVisualizer {
12
12
  this.librariesLoaded = false;
13
13
  this.loadingPromise = null;
14
14
  this.pendingEvents = []; // Store events received before libraries are loaded
15
-
15
+
16
16
  // Layout configuration
17
17
  this.layoutConfig = {
18
18
  name: 'dagre',
@@ -24,7 +24,7 @@ class HUDVisualizer {
24
24
  rankSep: 100,
25
25
  nodeSep: 80
26
26
  };
27
-
27
+
28
28
  // Node type configurations
29
29
  this.nodeTypes = {
30
30
  PM: {
@@ -76,7 +76,7 @@ class HUDVisualizer {
76
76
 
77
77
  // Setup basic event handlers (not library-dependent)
78
78
  this.setupBasicEventHandlers();
79
-
79
+
80
80
  console.log('HUD Visualizer initialized (libraries will load lazily)');
81
81
  return true;
82
82
  }
@@ -107,7 +107,7 @@ class HUDVisualizer {
107
107
  try {
108
108
  console.log('[HUD-VISUALIZER-DEBUG] _performLazyLoading() called');
109
109
  console.log('[HUD-VISUALIZER-DEBUG] Loading HUD visualization libraries...');
110
-
110
+
111
111
  // Show loading indicator
112
112
  this.showLoadingIndicator();
113
113
 
@@ -140,15 +140,15 @@ class HUDVisualizer {
140
140
  // Initialize Cytoscape instance
141
141
  console.log('[HUD-VISUALIZER-DEBUG] Initializing Cytoscape...');
142
142
  this.initializeCytoscape();
143
-
143
+
144
144
  // Setup library-dependent event handlers
145
145
  console.log('[HUD-VISUALIZER-DEBUG] Setting up Cytoscape event handlers...');
146
146
  this.setupCytoscapeEventHandlers();
147
-
147
+
148
148
  // Process any pending events
149
149
  console.log('[HUD-VISUALIZER-DEBUG] Processing pending events...');
150
150
  this.processPendingEvents();
151
-
151
+
152
152
  // Hide loading indicator
153
153
  this.hideLoadingIndicator();
154
154
 
@@ -178,19 +178,19 @@ class HUDVisualizer {
178
178
  if (typeof window.cytoscape !== 'undefined' && typeof window.cytoscapeDagre !== 'undefined') {
179
179
  window.cytoscape.use(window.cytoscapeDagre);
180
180
  }
181
-
181
+
182
182
  this.cy = window.cytoscape({
183
183
  container: this.container,
184
-
184
+
185
185
  elements: [],
186
-
186
+
187
187
  // Enable user interaction
188
188
  userZoomingEnabled: true,
189
189
  userPanningEnabled: true,
190
190
  boxSelectionEnabled: false,
191
191
  autoungrabify: false,
192
192
  autounselectify: false,
193
-
193
+
194
194
  style: [
195
195
  // Node styles
196
196
  {
@@ -212,7 +212,7 @@ class HUDVisualizer {
212
212
  'text-max-width': '100px'
213
213
  }
214
214
  },
215
-
215
+
216
216
  // Edge styles
217
217
  {
218
218
  selector: 'edge',
@@ -225,7 +225,7 @@ class HUDVisualizer {
225
225
  'arrow-scale': 1.2
226
226
  }
227
227
  },
228
-
228
+
229
229
  // Node type specific styles
230
230
  {
231
231
  selector: '.pm-node',
@@ -235,7 +235,7 @@ class HUDVisualizer {
235
235
  'shape': 'rectangle'
236
236
  }
237
237
  },
238
-
238
+
239
239
  {
240
240
  selector: '.agent-node',
241
241
  style: {
@@ -244,7 +244,7 @@ class HUDVisualizer {
244
244
  'shape': 'ellipse'
245
245
  }
246
246
  },
247
-
247
+
248
248
  {
249
249
  selector: '.tool-node',
250
250
  style: {
@@ -253,7 +253,7 @@ class HUDVisualizer {
253
253
  'shape': 'diamond'
254
254
  }
255
255
  },
256
-
256
+
257
257
  {
258
258
  selector: '.todo-node',
259
259
  style: {
@@ -262,7 +262,7 @@ class HUDVisualizer {
262
262
  'shape': 'triangle'
263
263
  }
264
264
  },
265
-
265
+
266
266
  // Hover effects
267
267
  {
268
268
  selector: 'node:active',
@@ -272,7 +272,7 @@ class HUDVisualizer {
272
272
  }
273
273
  }
274
274
  ],
275
-
275
+
276
276
  layout: this.layoutConfig
277
277
  });
278
278
 
@@ -291,7 +291,7 @@ class HUDVisualizer {
291
291
  this.resetLayout();
292
292
  });
293
293
  }
294
-
294
+
295
295
  // Center view button
296
296
  const centerBtn = document.getElementById('hud-center-view');
297
297
  if (centerBtn) {
@@ -317,7 +317,7 @@ class HUDVisualizer {
317
317
  const node = evt.target;
318
318
  const data = node.data();
319
319
  console.log('[HUD-VISUALIZER-DEBUG] Node clicked:', data);
320
-
320
+
321
321
  // Highlight connected nodes
322
322
  this.highlightConnectedNodes(node);
323
323
  });
@@ -330,7 +330,7 @@ class HUDVisualizer {
330
330
  this.cy.nodes().style({
331
331
  'opacity': 1
332
332
  });
333
-
333
+
334
334
  this.cy.edges().style({
335
335
  'opacity': 1
336
336
  });
@@ -360,7 +360,7 @@ class HUDVisualizer {
360
360
  this.ensureContainerResize();
361
361
  }
362
362
  });
363
-
363
+
364
364
  if (this.container) {
365
365
  resizeObserver.observe(this.container);
366
366
  }
@@ -391,11 +391,11 @@ class HUDVisualizer {
391
391
  // Only proceed if container is visible
392
392
  if (containerRect.width > 0 && containerRect.height > 0) {
393
393
  console.log('[HUD-VISUALIZER-DEBUG] Container is visible, resizing Cytoscape...');
394
-
394
+
395
395
  try {
396
396
  // Force Cytoscape to resize
397
397
  this.cy.resize();
398
-
398
+
399
399
  // Log Cytoscape elements
400
400
  const nodeCount = this.cy.nodes().length;
401
401
  const edgeCount = this.cy.edges().length;
@@ -403,7 +403,7 @@ class HUDVisualizer {
403
403
  nodes: nodeCount,
404
404
  edges: edgeCount
405
405
  });
406
-
406
+
407
407
  // If we have nodes, fit and run layout
408
408
  if (nodeCount > 0) {
409
409
  console.log('[HUD-VISUALIZER-DEBUG] Running fit and layout...');
@@ -412,7 +412,7 @@ class HUDVisualizer {
412
412
  } else {
413
413
  console.log('[HUD-VISUALIZER-DEBUG] No nodes to display');
414
414
  }
415
-
415
+
416
416
  } catch (error) {
417
417
  console.error('[HUD-VISUALIZER-DEBUG] Error during resize:', error);
418
418
  }
@@ -432,7 +432,7 @@ class HUDVisualizer {
432
432
  this.container.style.cursor = 'default';
433
433
  this.container.style.userSelect = 'none';
434
434
  this.container.style.touchAction = 'manipulation';
435
-
435
+
436
436
  // Remove any overlapping elements that might block events
437
437
  const parent = this.container.parentElement;
438
438
  if (parent) {
@@ -449,36 +449,36 @@ class HUDVisualizer {
449
449
  async activate() {
450
450
  console.log('[HUD-VISUALIZER-DEBUG] activate() called');
451
451
  this.isActive = true;
452
-
452
+
453
453
  try {
454
454
  console.log('[HUD-VISUALIZER-DEBUG] Loading libraries and initializing...');
455
455
  // Load libraries if not already loaded
456
456
  await this.loadLibrariesAndInitialize();
457
-
457
+
458
458
  console.log('[HUD-VISUALIZER-DEBUG] Libraries loaded, cy exists:', !!this.cy);
459
-
459
+
460
460
  // If Cytoscape was destroyed during clearing, recreate it
461
461
  if (!this.cy) {
462
462
  console.log('[HUD-VISUALIZER-DEBUG] Cytoscape instance missing, recreating...');
463
463
  this.initializeCytoscape();
464
464
  this.setupCytoscapeEventHandlers();
465
465
  }
466
-
466
+
467
467
  if (this.cy) {
468
468
  // Wait for container to be visible, then trigger resize and fit
469
469
  console.log('[HUD-VISUALIZER-DEBUG] Triggering resize and fit...');
470
-
470
+
471
471
  // Multiple resize attempts to ensure container visibility
472
472
  setTimeout(() => {
473
473
  console.log('[HUD-VISUALIZER-DEBUG] First resize attempt...');
474
474
  this.ensureContainerResize();
475
475
  }, 50);
476
-
476
+
477
477
  setTimeout(() => {
478
478
  console.log('[HUD-VISUALIZER-DEBUG] Second resize attempt...');
479
479
  this.ensureContainerResize();
480
480
  }, 200);
481
-
481
+
482
482
  setTimeout(() => {
483
483
  console.log('[HUD-VISUALIZER-DEBUG] Final resize attempt...');
484
484
  this.ensureContainerResize();
@@ -506,11 +506,11 @@ class HUDVisualizer {
506
506
  processPendingEvents() {
507
507
  if (this.pendingEvents.length > 0) {
508
508
  console.log(`Processing ${this.pendingEvents.length} pending events`);
509
-
509
+
510
510
  for (const event of this.pendingEvents) {
511
511
  this._processEventInternal(event);
512
512
  }
513
-
513
+
514
514
  this.pendingEvents = [];
515
515
  }
516
516
  }
@@ -522,19 +522,19 @@ class HUDVisualizer {
522
522
  */
523
523
  processExistingEvents(events) {
524
524
  console.log(`[HUD-VISUALIZER-DEBUG] processExistingEvents called with ${events ? events.length : 0} events`);
525
-
525
+
526
526
  if (!events) {
527
527
  console.error('[HUD-VISUALIZER-DEBUG] No events provided to processExistingEvents');
528
528
  return;
529
529
  }
530
-
530
+
531
531
  if (!Array.isArray(events)) {
532
532
  console.error('[HUD-VISUALIZER-DEBUG] Events is not an array:', typeof events);
533
533
  return;
534
534
  }
535
-
535
+
536
536
  console.log(`[HUD-VISUALIZER-DEBUG] Libraries loaded: ${this.librariesLoaded}, Cytoscape available: ${!!this.cy}`);
537
-
537
+
538
538
  if (!this.librariesLoaded || !this.cy) {
539
539
  console.warn('[HUD-VISUALIZER-DEBUG] HUD libraries not loaded, cannot process existing events');
540
540
  console.log(`[HUD-VISUALIZER-DEBUG] Storing ${events.length} events as pending`);
@@ -543,7 +543,7 @@ class HUDVisualizer {
543
543
  }
544
544
 
545
545
  console.log(`[HUD-VISUALIZER-DEBUG] 🏗️ Building HUD tree structure from ${events.length} historical events`);
546
-
546
+
547
547
  // Log sample events to understand structure
548
548
  if (events.length > 0) {
549
549
  console.log('[HUD-VISUALIZER-DEBUG] Sample events:');
@@ -559,22 +559,22 @@ class HUDVisualizer {
559
559
  });
560
560
  });
561
561
  }
562
-
562
+
563
563
  // Clear any existing visualization
564
564
  this.clear();
565
-
565
+
566
566
  // Group events by session to build proper hierarchies
567
567
  const sessionGroups = this.groupEventsBySession(events);
568
-
568
+
569
569
  // Process each session group to build trees
570
570
  Object.entries(sessionGroups).forEach(([sessionId, sessionEvents]) => {
571
571
  console.log(` 📂 Processing session ${sessionId}: ${sessionEvents.length} events`);
572
572
  this.buildSessionTree(sessionId, sessionEvents);
573
573
  });
574
-
574
+
575
575
  // Run final layout to organize the complete visualization
576
576
  this.runLayout();
577
-
577
+
578
578
  console.log(`✅ HUD tree structure built successfully`);
579
579
  }
580
580
 
@@ -585,7 +585,7 @@ class HUDVisualizer {
585
585
  */
586
586
  groupEventsBySession(events) {
587
587
  const sessionGroups = {};
588
-
588
+
589
589
  events.forEach(event => {
590
590
  const sessionId = event.session_id || event.data?.session_id || 'unknown';
591
591
  if (!sessionGroups[sessionId]) {
@@ -593,7 +593,7 @@ class HUDVisualizer {
593
593
  }
594
594
  sessionGroups[sessionId].push(event);
595
595
  });
596
-
596
+
597
597
  return sessionGroups;
598
598
  }
599
599
 
@@ -604,21 +604,21 @@ class HUDVisualizer {
604
604
  */
605
605
  buildSessionTree(sessionId, sessionEvents) {
606
606
  console.log(`[HUD-VISUALIZER-DEBUG] Building session tree for ${sessionId} with ${sessionEvents.length} events`);
607
-
607
+
608
608
  const sessionNodes = new Map(); // Track nodes created for this session
609
609
  let sessionRootNode = null;
610
-
610
+
611
611
  // Sort events chronologically within the session
612
612
  const sortedEvents = sessionEvents.sort((a, b) => {
613
613
  return new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime();
614
614
  });
615
-
615
+
616
616
  console.log(`[HUD-VISUALIZER-DEBUG] Sorted ${sortedEvents.length} events chronologically`);
617
-
617
+
618
618
  sortedEvents.forEach((event, index) => {
619
619
  const nodeData = this.createNodeFromEvent(event, sessionId);
620
620
  if (!nodeData) return;
621
-
621
+
622
622
  // Add the node to visualization
623
623
  this.addNode(nodeData.id, nodeData.type, nodeData.label, {
624
624
  sessionId: sessionId,
@@ -626,18 +626,18 @@ class HUDVisualizer {
626
626
  eventData: event,
627
627
  isSessionRoot: nodeData.isSessionRoot
628
628
  });
629
-
629
+
630
630
  sessionNodes.set(nodeData.id, {
631
631
  ...nodeData,
632
632
  event: event,
633
633
  index: index
634
634
  });
635
-
635
+
636
636
  // Track session root node
637
637
  if (nodeData.isSessionRoot && !sessionRootNode) {
638
638
  sessionRootNode = nodeData.id;
639
639
  }
640
-
640
+
641
641
  // Create relationships based on event context
642
642
  this.createHierarchicalRelationships(nodeData.id, event, sessionNodes, sessionRootNode);
643
643
  });
@@ -653,15 +653,15 @@ class HUDVisualizer {
653
653
  const eventType = event.hook_event_name || event.type || '';
654
654
  const subtype = event.subtype || '';
655
655
  const timestamp = new Date(event.timestamp || Date.now());
656
-
656
+
657
657
  console.log(`[HUD-VISUALIZER-DEBUG] Creating node from event: ${eventType}/${subtype} for session ${sessionId}`);
658
-
658
+
659
659
  let nodeId, nodeType, label, isSessionRoot = false;
660
-
660
+
661
661
  // Generate a unique timestamp-based ID suffix
662
662
  const timestampId = timestamp.getTime();
663
663
  const randomSuffix = Math.random().toString(36).substring(2, 7);
664
-
664
+
665
665
  // Determine node type and create appropriate visualization
666
666
  if (eventType === 'session' && subtype === 'started') {
667
667
  // Session root node
@@ -669,20 +669,20 @@ class HUDVisualizer {
669
669
  label = `Session ${sessionId.substring(0, 8)}...`;
670
670
  nodeId = `session-${sessionId.replace(/[^a-zA-Z0-9]/g, '')}`;
671
671
  isSessionRoot = true;
672
-
672
+
673
673
  } else if (eventType === 'hook' && subtype === 'user_prompt') {
674
674
  // User prompts are major workflow nodes
675
675
  nodeType = 'PM';
676
676
  const promptPreview = event.data?.prompt_preview || 'User Prompt';
677
677
  label = promptPreview.length > 20 ? promptPreview.substring(0, 20) + '...' : promptPreview;
678
678
  nodeId = `user-prompt-${timestampId}-${randomSuffix}`;
679
-
679
+
680
680
  } else if (eventType === 'hook' && subtype === 'claude_response') {
681
681
  // Claude responses
682
682
  nodeType = 'PM';
683
683
  label = 'Claude Response';
684
684
  nodeId = `claude-response-${timestampId}-${randomSuffix}`;
685
-
685
+
686
686
  } else if (eventType === 'hook' && subtype === 'pre_tool') {
687
687
  // Tool calls - pre hook
688
688
  nodeType = 'TOOL';
@@ -691,7 +691,7 @@ class HUDVisualizer {
691
691
  const cleanToolName = toolName.replace(/[^a-zA-Z0-9]/g, '');
692
692
  label = `${toolName}`;
693
693
  nodeId = `tool-${cleanToolName}-${timestampId}-${randomSuffix}`;
694
-
694
+
695
695
  } else if (eventType === 'agent' || event.data?.agent_type) {
696
696
  // Agent operations
697
697
  nodeType = 'AGENT';
@@ -700,17 +700,17 @@ class HUDVisualizer {
700
700
  const cleanAgentName = agentName.replace(/[^a-zA-Z0-9]/g, '');
701
701
  label = agentName;
702
702
  nodeId = `agent-${cleanAgentName}-${timestampId}-${randomSuffix}`;
703
-
703
+
704
704
  } else if (eventType === 'todo' || subtype.includes('todo')) {
705
705
  // Todo operations
706
706
  nodeType = 'TODO';
707
707
  label = 'Todo Update';
708
708
  nodeId = `todo-${timestampId}-${randomSuffix}`;
709
-
709
+
710
710
  } else if (eventType === 'hook' && subtype === 'notification') {
711
711
  // Skip notifications for cleaner visualization
712
712
  return null;
713
-
713
+
714
714
  } else if (eventType === 'log') {
715
715
  // Skip log events for cleaner visualization unless they're errors
716
716
  const level = event.data?.level || 'info';
@@ -720,7 +720,7 @@ class HUDVisualizer {
720
720
  nodeType = 'PM';
721
721
  label = `${level.toUpperCase()} Log`;
722
722
  nodeId = `log-${level}-${timestampId}-${randomSuffix}`;
723
-
723
+
724
724
  } else {
725
725
  // Generic event node
726
726
  nodeType = 'PM';
@@ -728,7 +728,7 @@ class HUDVisualizer {
728
728
  label = eventType || 'Event';
729
729
  nodeId = `generic-${cleanEventType}-${timestampId}-${randomSuffix}`;
730
730
  }
731
-
731
+
732
732
  return {
733
733
  id: nodeId,
734
734
  type: nodeType,
@@ -747,40 +747,40 @@ class HUDVisualizer {
747
747
  createHierarchicalRelationships(nodeId, event, sessionNodes, sessionRootNode) {
748
748
  const eventType = event.hook_event_name || event.type || '';
749
749
  const subtype = event.subtype || '';
750
-
750
+
751
751
  // Find appropriate parent node based on event context
752
752
  let parentNodeId = null;
753
-
753
+
754
754
  if (eventType === 'session' && subtype === 'started') {
755
755
  // Session start nodes have no parent
756
756
  return;
757
-
757
+
758
758
  } else if (eventType === 'hook' && subtype === 'pre_tool') {
759
759
  // Tool calls should connect to the most recent user prompt or agent
760
760
  parentNodeId = this.findRecentParentNode(sessionNodes, ['user-prompt', 'agent'], nodeId);
761
-
761
+
762
762
  } else if (eventType === 'hook' && subtype === 'claude_response') {
763
763
  // Claude responses should connect to user prompts
764
764
  parentNodeId = this.findRecentParentNode(sessionNodes, ['user-prompt'], nodeId);
765
-
765
+
766
766
  } else if (eventType === 'agent') {
767
767
  // Agents should connect to user prompts or other agents (delegation)
768
768
  parentNodeId = this.findRecentParentNode(sessionNodes, ['user-prompt', 'agent'], nodeId);
769
-
769
+
770
770
  } else if (eventType === 'todo') {
771
771
  // Todos should connect to agents or user prompts
772
772
  parentNodeId = this.findRecentParentNode(sessionNodes, ['agent', 'user-prompt'], nodeId);
773
-
773
+
774
774
  } else {
775
775
  // Default: connect to most recent significant node
776
776
  parentNodeId = this.findRecentParentNode(sessionNodes, ['user-prompt', 'agent', 'session'], nodeId);
777
777
  }
778
-
778
+
779
779
  // If no specific parent found, connect to session root
780
780
  if (!parentNodeId && sessionRootNode && nodeId !== sessionRootNode) {
781
781
  parentNodeId = sessionRootNode;
782
782
  }
783
-
783
+
784
784
  // Create the edge if parent exists
785
785
  if (parentNodeId && parentNodeId !== nodeId) {
786
786
  this.addEdge(parentNodeId, nodeId);
@@ -796,10 +796,10 @@ class HUDVisualizer {
796
796
  */
797
797
  findRecentParentNode(sessionNodes, nodeTypes, currentNodeId) {
798
798
  const nodeEntries = Array.from(sessionNodes.entries()).reverse(); // Most recent first
799
-
799
+
800
800
  for (const [nodeId, nodeData] of nodeEntries) {
801
801
  if (nodeId === currentNodeId) continue; // Skip current node
802
-
802
+
803
803
  // Check if this node matches any of the desired parent types
804
804
  for (const typePrefix of nodeTypes) {
805
805
  if (nodeId.startsWith(typePrefix)) {
@@ -807,7 +807,7 @@ class HUDVisualizer {
807
807
  }
808
808
  }
809
809
  }
810
-
810
+
811
811
  return null;
812
812
  }
813
813
 
@@ -817,7 +817,7 @@ class HUDVisualizer {
817
817
  */
818
818
  processEvent(event) {
819
819
  if (!this.isActive) return;
820
-
820
+
821
821
  // If libraries aren't loaded yet, store the event for later processing
822
822
  if (!this.librariesLoaded || !this.cy) {
823
823
  this.pendingEvents.push(event);
@@ -835,12 +835,12 @@ class HUDVisualizer {
835
835
  const eventType = event.hook_event_name || event.type || '';
836
836
  const sessionId = event.session_id || 'unknown';
837
837
  const timestamp = new Date(event.timestamp || Date.now());
838
-
838
+
839
839
  // Create a unique node ID based on event type and data
840
840
  let nodeId = `${eventType}-${timestamp.getTime()}`;
841
841
  let nodeType = 'PM';
842
842
  let label = eventType;
843
-
843
+
844
844
  // Determine node type based on event
845
845
  if (eventType.includes('tool_call')) {
846
846
  nodeType = 'TOOL';
@@ -861,14 +861,14 @@ class HUDVisualizer {
861
861
  label = eventType.includes('user_prompt') ? 'User Prompt' : 'Claude Response';
862
862
  nodeId = `pm-${label.replace(' ', '')}-${timestamp.getTime()}`;
863
863
  }
864
-
864
+
865
865
  // Add the node
866
866
  this.addNode(nodeId, nodeType, label, {
867
867
  sessionId: sessionId,
868
868
  timestamp: timestamp.toISOString(),
869
869
  eventData: event
870
870
  });
871
-
871
+
872
872
  // Add edges based on relationships
873
873
  this.createEventRelationships(nodeId, event);
874
874
  }
@@ -882,12 +882,12 @@ class HUDVisualizer {
882
882
  */
883
883
  addNode(id, type, label, data = {}) {
884
884
  console.log(`[HUD-VISUALIZER-DEBUG] Adding node: ${id} (${type}) - ${label}`);
885
-
885
+
886
886
  if (this.nodes.has(id)) {
887
887
  console.log(`[HUD-VISUALIZER-DEBUG] Node ${id} already exists, skipping`);
888
888
  return; // Node already exists
889
889
  }
890
-
890
+
891
891
  const nodeType = this.nodeTypes[type] || this.nodeTypes.PM;
892
892
  const nodeData = {
893
893
  id: id,
@@ -900,16 +900,16 @@ class HUDVisualizer {
900
900
  height: nodeType.height,
901
901
  ...data
902
902
  };
903
-
903
+
904
904
  this.nodes.set(id, nodeData);
905
-
905
+
906
906
  if (this.cy) {
907
907
  const element = {
908
908
  group: 'nodes',
909
909
  data: nodeData,
910
910
  classes: `${type.toLowerCase()}-node`
911
911
  };
912
-
912
+
913
913
  console.log(`[HUD-VISUALIZER-DEBUG] Adding node element to Cytoscape:`, element);
914
914
  this.cy.add(element);
915
915
  console.log(`[HUD-VISUALIZER-DEBUG] Node added successfully. Total nodes in cy: ${this.cy.nodes().length}`);
@@ -938,7 +938,7 @@ class HUDVisualizer {
938
938
  if (!edgeId) {
939
939
  edgeId = `edge-${sourceId}-to-${targetId}`;
940
940
  }
941
-
941
+
942
942
  if (this.cy) {
943
943
  // Check if edge already exists
944
944
  const existingEdge = this.cy.getElementById(edgeId);
@@ -950,12 +950,12 @@ class HUDVisualizer {
950
950
  // Check if nodes exist
951
951
  const sourceNode = this.cy.getElementById(sourceId);
952
952
  const targetNode = this.cy.getElementById(targetId);
953
-
953
+
954
954
  if (sourceNode.length === 0) {
955
955
  console.warn(`[HUD-VISUALIZER-DEBUG] Source node ${sourceId} does not exist, cannot create edge`);
956
956
  return;
957
957
  }
958
-
958
+
959
959
  if (targetNode.length === 0) {
960
960
  console.warn(`[HUD-VISUALIZER-DEBUG] Target node ${targetId} does not exist, cannot create edge`);
961
961
  return;
@@ -970,9 +970,9 @@ class HUDVisualizer {
970
970
  ...data
971
971
  }
972
972
  };
973
-
973
+
974
974
  console.log(`[HUD-VISUALIZER-DEBUG] Adding edge element to Cytoscape:`, element);
975
-
975
+
976
976
  try {
977
977
  this.cy.add(element);
978
978
  console.log(`[HUD-VISUALIZER-DEBUG] Edge added successfully. Total edges in cy: ${this.cy.edges().length}`);
@@ -992,10 +992,10 @@ class HUDVisualizer {
992
992
  createEventRelationships(nodeId, event) {
993
993
  const eventType = event.hook_event_name || event.type || '';
994
994
  const sessionId = event.session_id || 'unknown';
995
-
995
+
996
996
  // Find parent nodes based on event relationships
997
997
  const allNodeEntries = Array.from(this.nodes.entries());
998
-
998
+
999
999
  // Tool call relationships
1000
1000
  if (eventType.includes('tool_call') && event.data?.tool_name) {
1001
1001
  // Connect tool calls to their invoking agent/PM nodes
@@ -1005,7 +1005,7 @@ class HUDVisualizer {
1005
1005
  return;
1006
1006
  }
1007
1007
  }
1008
-
1008
+
1009
1009
  // Agent delegation relationships
1010
1010
  if (eventType.includes('agent') || event.data?.agent_name) {
1011
1011
  // Connect agents to PM nodes
@@ -1015,7 +1015,7 @@ class HUDVisualizer {
1015
1015
  return;
1016
1016
  }
1017
1017
  }
1018
-
1018
+
1019
1019
  // Todo relationships - connect to agent or PM nodes
1020
1020
  if (eventType.includes('todo')) {
1021
1021
  const parentNode = this.findParentNode(sessionId, ['AGENT', 'PM']);
@@ -1024,11 +1024,11 @@ class HUDVisualizer {
1024
1024
  return;
1025
1025
  }
1026
1026
  }
1027
-
1027
+
1028
1028
  // Default sequential relationship
1029
1029
  const allNodes = Array.from(this.nodes.keys());
1030
1030
  const currentIndex = allNodes.indexOf(nodeId);
1031
-
1031
+
1032
1032
  if (currentIndex > 0) {
1033
1033
  const previousNodeId = allNodes[currentIndex - 1];
1034
1034
  this.addEdge(previousNodeId, nodeId);
@@ -1043,13 +1043,13 @@ class HUDVisualizer {
1043
1043
  */
1044
1044
  findParentNode(sessionId, nodeTypes) {
1045
1045
  const nodeEntries = Array.from(this.nodes.entries()).reverse(); // Start from most recent
1046
-
1046
+
1047
1047
  for (const [nodeId, nodeData] of nodeEntries) {
1048
1048
  if (nodeData.sessionId === sessionId && nodeTypes.includes(nodeData.type)) {
1049
1049
  return nodeId;
1050
1050
  }
1051
1051
  }
1052
-
1052
+
1053
1053
  return null;
1054
1054
  }
1055
1055
 
@@ -1064,11 +1064,11 @@ class HUDVisualizer {
1064
1064
  this.cy.nodes().style({
1065
1065
  'opacity': 0.3
1066
1066
  });
1067
-
1067
+
1068
1068
  this.cy.edges().style({
1069
1069
  'opacity': 0.2
1070
1070
  });
1071
-
1071
+
1072
1072
  // Highlight selected node and its neighborhood
1073
1073
  const neighborhood = node.neighborhood();
1074
1074
  node.style('opacity', 1);
@@ -1103,7 +1103,7 @@ class HUDVisualizer {
1103
1103
  const nodeCount = this.cy.nodes().length;
1104
1104
  const edgeCount = this.cy.edges().length;
1105
1105
  console.log(`[HUD-VISUALIZER-DEBUG] Running layout with ${nodeCount} nodes and ${edgeCount} edges`);
1106
-
1106
+
1107
1107
  // Check container dimensions before layout
1108
1108
  if (this.container) {
1109
1109
  const rect = this.container.getBoundingClientRect();
@@ -1114,9 +1114,9 @@ class HUDVisualizer {
1114
1114
  offsetHeight: this.container.offsetHeight
1115
1115
  });
1116
1116
  }
1117
-
1117
+
1118
1118
  const layout = this.cy.layout(this.layoutConfig);
1119
-
1119
+
1120
1120
  // Listen for layout completion
1121
1121
  layout.on('layoutstop', () => {
1122
1122
  console.log(`[HUD-VISUALIZER-DEBUG] Layout completed. Final node positions:`);
@@ -1126,7 +1126,7 @@ class HUDVisualizer {
1126
1126
  console.log(`[HUD-VISUALIZER-DEBUG] Node ${index + 1}: ${data.label} at (${position.x.toFixed(1)}, ${position.y.toFixed(1)})`);
1127
1127
  });
1128
1128
  });
1129
-
1129
+
1130
1130
  layout.run();
1131
1131
  } else {
1132
1132
  console.log(`[HUD-VISUALIZER-DEBUG] Skipping layout - not active or no Cytoscape instance`);
@@ -1244,7 +1244,7 @@ class HUDVisualizer {
1244
1244
  pendingEventCount: this.pendingEvents.length,
1245
1245
  hasHUDLibraryLoader: !!window.HUDLibraryLoader
1246
1246
  });
1247
-
1247
+
1248
1248
  // Test container
1249
1249
  if (this.container) {
1250
1250
  console.log('[HUD-VISUALIZER-DEBUG] Container info:', {
@@ -1255,7 +1255,7 @@ class HUDVisualizer {
1255
1255
  innerHTML: this.container.innerHTML ? 'has content' : 'empty'
1256
1256
  });
1257
1257
  }
1258
-
1258
+
1259
1259
  // Test library availability
1260
1260
  console.log('[HUD-VISUALIZER-DEBUG] Library availability:', {
1261
1261
  cytoscape: typeof window.cytoscape,
@@ -1263,7 +1263,7 @@ class HUDVisualizer {
1263
1263
  cytoscapeDagre: typeof window.cytoscapeDagre,
1264
1264
  HUDLibraryLoader: typeof window.HUDLibraryLoader
1265
1265
  });
1266
-
1266
+
1267
1267
  return {
1268
1268
  isActive: this.isActive,
1269
1269
  librariesLoaded: this.librariesLoaded,
@@ -1280,7 +1280,7 @@ class HUDVisualizer {
1280
1280
  console.log('[HUD-BLANK-SCREEN-DEBUG] =================================');
1281
1281
  console.log('[HUD-BLANK-SCREEN-DEBUG] COMPREHENSIVE BLANK SCREEN DEBUG');
1282
1282
  console.log('[HUD-BLANK-SCREEN-DEBUG] =================================');
1283
-
1283
+
1284
1284
  // 1. Check basic state
1285
1285
  const basicState = {
1286
1286
  isActive: this.isActive,
@@ -1291,19 +1291,19 @@ class HUDVisualizer {
1291
1291
  cytoscapeElementCount: this.cy ? this.cy.elements().length : 0
1292
1292
  };
1293
1293
  console.log('[HUD-BLANK-SCREEN-DEBUG] 1. Basic State:', basicState);
1294
-
1294
+
1295
1295
  // 2. Check container visibility and dimensions
1296
1296
  if (this.container) {
1297
1297
  const containerInfo = this.getContainerDebugInfo();
1298
1298
  console.log('[HUD-BLANK-SCREEN-DEBUG] 2. Container Info:', containerInfo);
1299
-
1299
+
1300
1300
  // Add background color to verify container is visible
1301
1301
  this.debugAddContainerBackground();
1302
1302
  } else {
1303
1303
  console.error('[HUD-BLANK-SCREEN-DEBUG] 2. Container not found!');
1304
1304
  return false;
1305
1305
  }
1306
-
1306
+
1307
1307
  // 3. Check Cytoscape state
1308
1308
  if (this.cy) {
1309
1309
  const cytoscapeInfo = this.getCytoscapeDebugInfo();
@@ -1312,22 +1312,22 @@ class HUDVisualizer {
1312
1312
  console.error('[HUD-BLANK-SCREEN-DEBUG] 3. Cytoscape instance not found!');
1313
1313
  return false;
1314
1314
  }
1315
-
1315
+
1316
1316
  // 4. Check node positions
1317
1317
  this.debugNodePositions();
1318
-
1318
+
1319
1319
  // 5. Try manual rendering triggers
1320
1320
  this.debugManualRenderingTriggers();
1321
-
1321
+
1322
1322
  // 6. Add test nodes if none exist
1323
1323
  if (this.cy && this.cy.nodes().length === 0) {
1324
1324
  console.log('[HUD-BLANK-SCREEN-DEBUG] 6. No nodes found, adding test nodes...');
1325
1325
  this.debugAddTestNodes();
1326
1326
  }
1327
-
1327
+
1328
1328
  // 7. Force zoom fit
1329
1329
  this.debugForceZoomFit();
1330
-
1330
+
1331
1331
  console.log('[HUD-BLANK-SCREEN-DEBUG] Debug complete. Check visual results.');
1332
1332
  return true;
1333
1333
  }
@@ -1338,7 +1338,7 @@ class HUDVisualizer {
1338
1338
  getContainerDebugInfo() {
1339
1339
  const rect = this.container.getBoundingClientRect();
1340
1340
  const computed = window.getComputedStyle(this.container);
1341
-
1341
+
1342
1342
  return {
1343
1343
  id: this.container.id,
1344
1344
  className: this.container.className,
@@ -1389,7 +1389,7 @@ class HUDVisualizer {
1389
1389
  const zoom = this.cy.zoom();
1390
1390
  const pan = this.cy.pan();
1391
1391
  const viewport = this.cy.viewport();
1392
-
1392
+
1393
1393
  return {
1394
1394
  // Elements
1395
1395
  nodeCount: this.cy.nodes().length,
@@ -1421,20 +1421,20 @@ class HUDVisualizer {
1421
1421
  console.log('[HUD-BLANK-SCREEN-DEBUG] 4. No nodes to check positions');
1422
1422
  return;
1423
1423
  }
1424
-
1424
+
1425
1425
  console.log('[HUD-BLANK-SCREEN-DEBUG] 4. Node Positions:');
1426
1426
  const nodes = this.cy.nodes();
1427
1427
  const extent = this.cy.extent();
1428
1428
  const viewport = this.cy.viewport();
1429
-
1429
+
1430
1430
  console.log('[HUD-BLANK-SCREEN-DEBUG] Viewport extent:', extent);
1431
1431
  console.log('[HUD-BLANK-SCREEN-DEBUG] Current viewport:', viewport);
1432
-
1432
+
1433
1433
  nodes.forEach((node, index) => {
1434
1434
  const position = node.position();
1435
1435
  const data = node.data();
1436
1436
  const boundingBox = node.boundingBox();
1437
-
1437
+
1438
1438
  console.log(`[HUD-BLANK-SCREEN-DEBUG] Node ${index + 1}:`, {
1439
1439
  id: data.id,
1440
1440
  label: data.label,
@@ -1468,31 +1468,31 @@ class HUDVisualizer {
1468
1468
  console.log('[HUD-BLANK-SCREEN-DEBUG] 5. No Cytoscape instance for manual rendering');
1469
1469
  return;
1470
1470
  }
1471
-
1471
+
1472
1472
  console.log('[HUD-BLANK-SCREEN-DEBUG] 5. Triggering manual rendering operations...');
1473
-
1473
+
1474
1474
  try {
1475
1475
  // Force resize
1476
1476
  console.log('[HUD-BLANK-SCREEN-DEBUG] - Forcing resize...');
1477
1477
  this.cy.resize();
1478
-
1478
+
1479
1479
  // Force redraw
1480
1480
  console.log('[HUD-BLANK-SCREEN-DEBUG] - Forcing redraw...');
1481
1481
  this.cy.forceRender();
1482
-
1482
+
1483
1483
  // Force layout
1484
1484
  if (this.cy.nodes().length > 0) {
1485
1485
  console.log('[HUD-BLANK-SCREEN-DEBUG] - Running layout...');
1486
1486
  this.cy.layout(this.layoutConfig).run();
1487
1487
  }
1488
-
1488
+
1489
1489
  // Force viewport update
1490
1490
  console.log('[HUD-BLANK-SCREEN-DEBUG] - Updating viewport...');
1491
1491
  this.cy.viewport({
1492
1492
  zoom: this.cy.zoom(),
1493
1493
  pan: this.cy.pan()
1494
1494
  });
1495
-
1495
+
1496
1496
  console.log('[HUD-BLANK-SCREEN-DEBUG] Manual rendering triggers completed');
1497
1497
  } catch (error) {
1498
1498
  console.error('[HUD-BLANK-SCREEN-DEBUG] Error during manual rendering:', error);
@@ -1504,13 +1504,13 @@ class HUDVisualizer {
1504
1504
  */
1505
1505
  debugAddTestNodes() {
1506
1506
  if (!this.cy) return;
1507
-
1507
+
1508
1508
  console.log('[HUD-BLANK-SCREEN-DEBUG] Adding test nodes...');
1509
-
1509
+
1510
1510
  try {
1511
1511
  // Clear existing elements
1512
1512
  this.cy.elements().remove();
1513
-
1513
+
1514
1514
  // Add test nodes
1515
1515
  const testNodes = [
1516
1516
  {
@@ -1553,7 +1553,7 @@ class HUDVisualizer {
1553
1553
  classes: 'todo-node'
1554
1554
  }
1555
1555
  ];
1556
-
1556
+
1557
1557
  // Add test edges
1558
1558
  const testEdges = [
1559
1559
  {
@@ -1573,21 +1573,21 @@ class HUDVisualizer {
1573
1573
  }
1574
1574
  }
1575
1575
  ];
1576
-
1576
+
1577
1577
  // Add elements to Cytoscape
1578
1578
  this.cy.add(testNodes);
1579
1579
  this.cy.add(testEdges);
1580
-
1580
+
1581
1581
  console.log('[HUD-BLANK-SCREEN-DEBUG] Added 3 test nodes and 2 test edges');
1582
-
1582
+
1583
1583
  // Update our internal nodes map
1584
1584
  testNodes.forEach(nodeElement => {
1585
1585
  this.nodes.set(nodeElement.data.id, nodeElement.data);
1586
1586
  });
1587
-
1587
+
1588
1588
  // Run layout
1589
1589
  this.runLayout();
1590
-
1590
+
1591
1591
  } catch (error) {
1592
1592
  console.error('[HUD-BLANK-SCREEN-DEBUG] Error adding test nodes:', error);
1593
1593
  }
@@ -1598,50 +1598,50 @@ class HUDVisualizer {
1598
1598
  */
1599
1599
  debugForceZoomFit() {
1600
1600
  if (!this.cy) return;
1601
-
1601
+
1602
1602
  console.log('[HUD-BLANK-SCREEN-DEBUG] 7. Forcing zoom fit...');
1603
-
1603
+
1604
1604
  const attemptZoomFit = (attemptNumber) => {
1605
1605
  try {
1606
1606
  console.log(`[HUD-BLANK-SCREEN-DEBUG] Zoom fit attempt ${attemptNumber}...`);
1607
-
1607
+
1608
1608
  // Get current state before fit
1609
1609
  const beforeZoom = this.cy.zoom();
1610
1610
  const beforePan = this.cy.pan();
1611
1611
  const elements = this.cy.elements();
1612
-
1612
+
1613
1613
  console.log('[HUD-BLANK-SCREEN-DEBUG] Before fit:', {
1614
1614
  zoom: beforeZoom,
1615
1615
  pan: beforePan,
1616
1616
  elementCount: elements.length
1617
1617
  });
1618
-
1618
+
1619
1619
  if (elements.length > 0) {
1620
1620
  // Try fit with specific options
1621
1621
  this.cy.fit(elements, 50); // 50px padding
1622
-
1622
+
1623
1623
  // Get state after fit
1624
1624
  const afterZoom = this.cy.zoom();
1625
1625
  const afterPan = this.cy.pan();
1626
-
1626
+
1627
1627
  console.log('[HUD-BLANK-SCREEN-DEBUG] After fit:', {
1628
1628
  zoom: afterZoom,
1629
1629
  pan: afterPan,
1630
1630
  changed: beforeZoom !== afterZoom || beforePan.x !== afterPan.x || beforePan.y !== afterPan.y
1631
1631
  });
1632
-
1632
+
1633
1633
  // Force center
1634
1634
  this.cy.center(elements);
1635
-
1635
+
1636
1636
  } else {
1637
1637
  console.log('[HUD-BLANK-SCREEN-DEBUG] No elements to fit');
1638
1638
  }
1639
-
1639
+
1640
1640
  } catch (error) {
1641
1641
  console.error(`[HUD-BLANK-SCREEN-DEBUG] Zoom fit attempt ${attemptNumber} failed:`, error);
1642
1642
  }
1643
1643
  };
1644
-
1644
+
1645
1645
  // Multiple attempts with delays
1646
1646
  attemptZoomFit(1);
1647
1647
  setTimeout(() => attemptZoomFit(2), 100);
@@ -1657,13 +1657,13 @@ class HUDVisualizer {
1657
1657
  console.log('[HUD-CANVAS-TEST] No Cytoscape instance');
1658
1658
  return false;
1659
1659
  }
1660
-
1660
+
1661
1661
  console.log('[HUD-CANVAS-TEST] Testing Cytoscape canvas rendering...');
1662
-
1662
+
1663
1663
  try {
1664
1664
  // Clear everything
1665
1665
  this.cy.elements().remove();
1666
-
1666
+
1667
1667
  // Add a single, simple node at center
1668
1668
  this.cy.add({
1669
1669
  group: 'nodes',
@@ -1678,18 +1678,18 @@ class HUDVisualizer {
1678
1678
  },
1679
1679
  position: { x: 200, y: 200 } // Fixed position
1680
1680
  });
1681
-
1681
+
1682
1682
  // Force immediate render
1683
1683
  this.cy.forceRender();
1684
-
1684
+
1685
1685
  // Zoom to fit this single node
1686
1686
  this.cy.fit(this.cy.$('#canvas-test'), 50);
1687
-
1687
+
1688
1688
  console.log('[HUD-CANVAS-TEST] Canvas test node added and positioned');
1689
1689
  console.log('[HUD-CANVAS-TEST] If you see a red rectangle with "CANVAS TEST", rendering works!');
1690
-
1690
+
1691
1691
  return true;
1692
-
1692
+
1693
1693
  } catch (error) {
1694
1694
  console.error('[HUD-CANVAS-TEST] Canvas test failed:', error);
1695
1695
  return false;
@@ -1715,4 +1715,4 @@ class HUDVisualizer {
1715
1715
  }
1716
1716
 
1717
1717
  // Export for use in dashboard
1718
- window.HUDVisualizer = HUDVisualizer;
1718
+ window.HUDVisualizer = HUDVisualizer;