claude-mpm 4.25.10__py3-none-any.whl → 5.1.8__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 (507) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_PM.md +12 -0
  3. claude_mpm/agents/PM_INSTRUCTIONS.md +1055 -2230
  4. claude_mpm/agents/PM_INSTRUCTIONS_TEACH.md +1322 -0
  5. claude_mpm/agents/WORKFLOW.md +4 -4
  6. claude_mpm/agents/__init__.py +6 -0
  7. claude_mpm/agents/agent_loader.py +1 -4
  8. claude_mpm/agents/base_agent_loader.py +10 -35
  9. claude_mpm/agents/templates/{circuit_breakers.md → circuit-breakers.md} +576 -66
  10. claude_mpm/agents/templates/context-management-examples.md +544 -0
  11. claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
  12. claude_mpm/agents/templates/research-gate-examples.md +669 -0
  13. claude_mpm/agents/templates/structured-questions-examples.md +615 -0
  14. claude_mpm/agents/templates/ticket-completeness-examples.md +139 -0
  15. claude_mpm/agents/templates/ticketing-examples.md +277 -0
  16. claude_mpm/cli/__init__.py +28 -3
  17. claude_mpm/cli/commands/__init__.py +2 -0
  18. claude_mpm/cli/commands/agent_source.py +774 -0
  19. claude_mpm/cli/commands/agent_state_manager.py +188 -30
  20. claude_mpm/cli/commands/agents.py +959 -36
  21. claude_mpm/cli/commands/agents_cleanup.py +210 -0
  22. claude_mpm/cli/commands/agents_discover.py +338 -0
  23. claude_mpm/cli/commands/auto_configure.py +537 -239
  24. claude_mpm/cli/commands/config.py +7 -4
  25. claude_mpm/cli/commands/configure.py +924 -45
  26. claude_mpm/cli/commands/configure_navigation.py +63 -46
  27. claude_mpm/cli/commands/doctor.py +10 -2
  28. claude_mpm/cli/commands/local_deploy.py +1 -4
  29. claude_mpm/cli/commands/postmortem.py +401 -0
  30. claude_mpm/cli/commands/run.py +1 -39
  31. claude_mpm/cli/commands/skill_source.py +694 -0
  32. claude_mpm/cli/commands/skills.py +322 -19
  33. claude_mpm/cli/executor.py +22 -3
  34. claude_mpm/cli/interactive/agent_wizard.py +1028 -43
  35. claude_mpm/cli/parsers/agent_source_parser.py +171 -0
  36. claude_mpm/cli/parsers/agents_parser.py +256 -4
  37. claude_mpm/cli/parsers/auto_configure_parser.py +13 -0
  38. claude_mpm/cli/parsers/base_parser.py +25 -0
  39. claude_mpm/cli/parsers/config_parser.py +96 -43
  40. claude_mpm/cli/parsers/skill_source_parser.py +169 -0
  41. claude_mpm/cli/parsers/skills_parser.py +7 -0
  42. claude_mpm/cli/parsers/source_parser.py +138 -0
  43. claude_mpm/cli/startup.py +456 -103
  44. claude_mpm/cli/startup_display.py +4 -4
  45. claude_mpm/commands/{mpm-auto-configure.md → mpm-agents-auto-configure.md} +9 -0
  46. claude_mpm/commands/mpm-agents-detect.md +9 -0
  47. claude_mpm/commands/{mpm-agents.md → mpm-agents-list.md} +9 -0
  48. claude_mpm/commands/mpm-agents-recommend.md +9 -0
  49. claude_mpm/commands/{mpm-config.md → mpm-config-view.md} +9 -0
  50. claude_mpm/commands/mpm-doctor.md +9 -0
  51. claude_mpm/commands/mpm-help.md +14 -2
  52. claude_mpm/commands/mpm-init.md +9 -0
  53. claude_mpm/commands/mpm-monitor.md +9 -0
  54. claude_mpm/commands/mpm-postmortem.md +123 -0
  55. claude_mpm/commands/{mpm-resume.md → mpm-session-resume.md} +9 -0
  56. claude_mpm/commands/mpm-status.md +9 -0
  57. claude_mpm/commands/{mpm-organize.md → mpm-ticket-organize.md} +9 -0
  58. claude_mpm/commands/mpm-ticket-view.md +552 -0
  59. claude_mpm/commands/mpm-version.md +9 -0
  60. claude_mpm/commands/mpm.md +10 -0
  61. claude_mpm/config/agent_presets.py +488 -0
  62. claude_mpm/config/agent_sources.py +325 -0
  63. claude_mpm/config/skill_presets.py +392 -0
  64. claude_mpm/config/skill_sources.py +590 -0
  65. claude_mpm/constants.py +1 -0
  66. claude_mpm/core/claude_runner.py +5 -34
  67. claude_mpm/core/config.py +16 -0
  68. claude_mpm/core/framework/__init__.py +3 -16
  69. claude_mpm/core/framework/loaders/file_loader.py +54 -101
  70. claude_mpm/core/framework/loaders/instruction_loader.py +25 -5
  71. claude_mpm/core/interactive_session.py +83 -7
  72. claude_mpm/core/oneshot_session.py +71 -8
  73. claude_mpm/core/protocols/__init__.py +23 -0
  74. claude_mpm/core/protocols/runner_protocol.py +103 -0
  75. claude_mpm/core/protocols/session_protocol.py +131 -0
  76. claude_mpm/core/shared/singleton_manager.py +11 -4
  77. claude_mpm/core/system_context.py +38 -0
  78. claude_mpm/core/unified_config.py +22 -0
  79. claude_mpm/experimental/cli_enhancements.py +1 -5
  80. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-313.pyc +0 -0
  81. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-313.pyc +0 -0
  82. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-313.pyc +0 -0
  83. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-313.pyc +0 -0
  84. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-313.pyc +0 -0
  85. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-313.pyc +0 -0
  86. claude_mpm/hooks/claude_hooks/memory_integration.py +12 -1
  87. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-313.pyc +0 -0
  88. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-313.pyc +0 -0
  89. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-313.pyc +0 -0
  90. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-313.pyc +0 -0
  91. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-313.pyc +0 -0
  92. claude_mpm/hooks/failure_learning/__init__.py +2 -8
  93. claude_mpm/hooks/failure_learning/failure_detection_hook.py +1 -6
  94. claude_mpm/hooks/failure_learning/fix_detection_hook.py +1 -6
  95. claude_mpm/hooks/failure_learning/learning_extraction_hook.py +1 -6
  96. claude_mpm/hooks/kuzu_response_hook.py +1 -5
  97. claude_mpm/models/git_repository.py +198 -0
  98. claude_mpm/services/agents/agent_builder.py +45 -9
  99. claude_mpm/services/agents/agent_preset_service.py +238 -0
  100. claude_mpm/services/agents/agent_selection_service.py +484 -0
  101. claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
  102. claude_mpm/services/agents/cache_git_manager.py +621 -0
  103. claude_mpm/services/agents/deployment/agent_deployment.py +126 -2
  104. claude_mpm/services/agents/deployment/agent_discovery_service.py +105 -73
  105. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +1 -5
  106. claude_mpm/services/agents/deployment/agent_restore_handler.py +1 -4
  107. claude_mpm/services/agents/deployment/agent_template_builder.py +236 -15
  108. claude_mpm/services/agents/deployment/agents_directory_resolver.py +101 -15
  109. claude_mpm/services/agents/deployment/async_agent_deployment.py +2 -1
  110. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +115 -15
  111. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +1 -4
  112. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +363 -0
  113. claude_mpm/services/agents/deployment/single_agent_deployer.py +2 -2
  114. claude_mpm/services/agents/deployment/system_instructions_deployer.py +168 -46
  115. claude_mpm/services/agents/deployment/validation/deployment_validator.py +2 -2
  116. claude_mpm/services/agents/git_source_manager.py +629 -0
  117. claude_mpm/services/agents/loading/framework_agent_loader.py +1 -4
  118. claude_mpm/services/agents/local_template_manager.py +47 -9
  119. claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
  120. claude_mpm/services/agents/sources/__init__.py +13 -0
  121. claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
  122. claude_mpm/services/agents/sources/git_source_sync_service.py +1087 -0
  123. claude_mpm/services/agents/startup_sync.py +239 -0
  124. claude_mpm/services/agents/toolchain_detector.py +474 -0
  125. claude_mpm/services/analysis/__init__.py +25 -0
  126. claude_mpm/services/analysis/postmortem_reporter.py +474 -0
  127. claude_mpm/services/analysis/postmortem_service.py +765 -0
  128. claude_mpm/services/command_deployment_service.py +200 -6
  129. claude_mpm/services/core/base.py +7 -2
  130. claude_mpm/services/core/interfaces/__init__.py +1 -3
  131. claude_mpm/services/core/interfaces/health.py +1 -4
  132. claude_mpm/services/core/models/__init__.py +2 -11
  133. claude_mpm/services/diagnostics/checks/__init__.py +4 -0
  134. claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
  135. claude_mpm/services/diagnostics/checks/mcp_services_check.py +7 -15
  136. claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
  137. claude_mpm/services/diagnostics/diagnostic_runner.py +9 -0
  138. claude_mpm/services/diagnostics/doctor_reporter.py +34 -6
  139. claude_mpm/services/git/__init__.py +21 -0
  140. claude_mpm/services/git/git_operations_service.py +494 -0
  141. claude_mpm/services/github/__init__.py +21 -0
  142. claude_mpm/services/github/github_cli_service.py +397 -0
  143. claude_mpm/services/infrastructure/monitoring/__init__.py +1 -5
  144. claude_mpm/services/infrastructure/monitoring/aggregator.py +1 -6
  145. claude_mpm/services/instructions/__init__.py +9 -0
  146. claude_mpm/services/instructions/instruction_cache_service.py +374 -0
  147. claude_mpm/services/local_ops/__init__.py +3 -13
  148. claude_mpm/services/local_ops/health_checks/__init__.py +1 -3
  149. claude_mpm/services/local_ops/health_manager.py +1 -4
  150. claude_mpm/services/mcp_config_manager.py +75 -145
  151. claude_mpm/services/mcp_gateway/core/process_pool.py +22 -16
  152. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +1 -6
  153. claude_mpm/services/mcp_service_verifier.py +6 -3
  154. claude_mpm/services/monitor/daemon.py +28 -8
  155. claude_mpm/services/monitor/daemon_manager.py +96 -19
  156. claude_mpm/services/pr/__init__.py +14 -0
  157. claude_mpm/services/pr/pr_template_service.py +329 -0
  158. claude_mpm/services/project/project_organizer.py +4 -0
  159. claude_mpm/services/runner_configuration_service.py +16 -3
  160. claude_mpm/services/session_management_service.py +16 -4
  161. claude_mpm/services/skills/__init__.py +18 -0
  162. claude_mpm/services/skills/git_skill_source_manager.py +1169 -0
  163. claude_mpm/services/skills/skill_discovery_service.py +568 -0
  164. claude_mpm/services/socketio/server/core.py +1 -4
  165. claude_mpm/services/socketio/server/main.py +1 -3
  166. claude_mpm/services/unified/deployment_strategies/vercel.py +1 -5
  167. claude_mpm/services/unified/unified_deployment.py +1 -5
  168. claude_mpm/services/visualization/__init__.py +1 -5
  169. claude_mpm/templates/questions/__init__.py +2 -7
  170. claude_mpm/templates/questions/pr_strategy.py +1 -4
  171. claude_mpm/templates/questions/project_init.py +1 -4
  172. claude_mpm/templates/questions/ticket_mgmt.py +1 -4
  173. claude_mpm/utils/agent_dependency_loader.py +77 -10
  174. claude_mpm/utils/agent_filters.py +288 -0
  175. claude_mpm/utils/gitignore.py +3 -0
  176. claude_mpm/utils/migration.py +372 -0
  177. claude_mpm/utils/progress.py +387 -0
  178. {claude_mpm-4.25.10.dist-info → claude_mpm-5.1.8.dist-info}/METADATA +356 -112
  179. {claude_mpm-4.25.10.dist-info → claude_mpm-5.1.8.dist-info}/RECORD +188 -439
  180. claude_mpm/agents/templates/agent-manager.json +0 -273
  181. claude_mpm/agents/templates/agentic-coder-optimizer.json +0 -248
  182. claude_mpm/agents/templates/api_qa.json +0 -183
  183. claude_mpm/agents/templates/clerk-ops.json +0 -235
  184. claude_mpm/agents/templates/code_analyzer.json +0 -101
  185. claude_mpm/agents/templates/content-agent.json +0 -358
  186. claude_mpm/agents/templates/dart_engineer.json +0 -307
  187. claude_mpm/agents/templates/data_engineer.json +0 -225
  188. claude_mpm/agents/templates/documentation.json +0 -238
  189. claude_mpm/agents/templates/engineer.json +0 -210
  190. claude_mpm/agents/templates/gcp_ops_agent.json +0 -253
  191. claude_mpm/agents/templates/golang_engineer.json +0 -270
  192. claude_mpm/agents/templates/imagemagick.json +0 -264
  193. claude_mpm/agents/templates/java_engineer.json +0 -346
  194. claude_mpm/agents/templates/javascript_engineer_agent.json +0 -380
  195. claude_mpm/agents/templates/local_ops_agent.json +0 -1840
  196. claude_mpm/agents/templates/memory_manager.json +0 -158
  197. claude_mpm/agents/templates/nextjs_engineer.json +0 -285
  198. claude_mpm/agents/templates/ops.json +0 -185
  199. claude_mpm/agents/templates/php-engineer.json +0 -287
  200. claude_mpm/agents/templates/product_owner.json +0 -338
  201. claude_mpm/agents/templates/project_organizer.json +0 -144
  202. claude_mpm/agents/templates/prompt-engineer.json +0 -737
  203. claude_mpm/agents/templates/python_engineer.json +0 -387
  204. claude_mpm/agents/templates/qa.json +0 -243
  205. claude_mpm/agents/templates/react_engineer.json +0 -239
  206. claude_mpm/agents/templates/refactoring_engineer.json +0 -276
  207. claude_mpm/agents/templates/research.json +0 -258
  208. claude_mpm/agents/templates/ruby-engineer.json +0 -280
  209. claude_mpm/agents/templates/rust_engineer.json +0 -275
  210. claude_mpm/agents/templates/security.json +0 -202
  211. claude_mpm/agents/templates/svelte-engineer.json +0 -225
  212. claude_mpm/agents/templates/tauri_engineer.json +0 -274
  213. claude_mpm/agents/templates/ticketing.json +0 -181
  214. claude_mpm/agents/templates/typescript_engineer.json +0 -285
  215. claude_mpm/agents/templates/vercel_ops_agent.json +0 -412
  216. claude_mpm/agents/templates/version_control.json +0 -159
  217. claude_mpm/agents/templates/web_qa.json +0 -400
  218. claude_mpm/agents/templates/web_ui.json +0 -189
  219. claude_mpm/cli/README.md +0 -253
  220. claude_mpm/cli/commands/mcp_install_commands.py.backup +0 -284
  221. claude_mpm/cli/commands/mpm_init/README.md +0 -365
  222. claude_mpm/cli_module/refactoring_guide.md +0 -253
  223. claude_mpm/commands/mpm-tickets.md +0 -151
  224. claude_mpm/config/agent_capabilities.yaml +0 -658
  225. claude_mpm/config/async_logging_config.yaml +0 -145
  226. claude_mpm/core/.claude-mpm/logs/hooks_20250730.log +0 -34
  227. claude_mpm/d2/.gitignore +0 -22
  228. claude_mpm/d2/ARCHITECTURE_COMPARISON.md +0 -273
  229. claude_mpm/d2/FLASK_INTEGRATION.md +0 -156
  230. claude_mpm/d2/IMPLEMENTATION_SUMMARY.md +0 -452
  231. claude_mpm/d2/QUICKSTART.md +0 -186
  232. claude_mpm/d2/README.md +0 -232
  233. claude_mpm/d2/STORE_FIX_SUMMARY.md +0 -167
  234. claude_mpm/d2/SVELTE5_STORES_GUIDE.md +0 -180
  235. claude_mpm/d2/TESTING.md +0 -288
  236. claude_mpm/d2/index.html +0 -118
  237. claude_mpm/d2/package.json +0 -19
  238. claude_mpm/d2/src/App.svelte +0 -110
  239. claude_mpm/d2/src/components/Header.svelte +0 -153
  240. claude_mpm/d2/src/components/MainContent.svelte +0 -74
  241. claude_mpm/d2/src/components/Sidebar.svelte +0 -85
  242. claude_mpm/d2/src/components/tabs/EventsTab.svelte +0 -326
  243. claude_mpm/d2/src/lib/socketio.js +0 -144
  244. claude_mpm/d2/src/main.js +0 -7
  245. claude_mpm/d2/src/stores/events.js +0 -114
  246. claude_mpm/d2/src/stores/socket.js +0 -108
  247. claude_mpm/d2/src/stores/theme.js +0 -65
  248. claude_mpm/d2/svelte.config.js +0 -12
  249. claude_mpm/d2/vite.config.js +0 -15
  250. claude_mpm/dashboard/.claude-mpm/memories/README.md +0 -36
  251. claude_mpm/dashboard/BUILD_NUMBER +0 -1
  252. claude_mpm/dashboard/README.md +0 -121
  253. claude_mpm/dashboard/VERSION +0 -1
  254. claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +0 -188
  255. claude_mpm/dashboard/react/components/DataInspector/DataInspector.tsx +0 -273
  256. claude_mpm/dashboard/react/components/ErrorBoundary.tsx +0 -75
  257. claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +0 -156
  258. claude_mpm/dashboard/react/components/EventViewer/EventViewer.tsx +0 -141
  259. claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +0 -38
  260. claude_mpm/dashboard/react/components/shared/ConnectionStatus.tsx +0 -36
  261. claude_mpm/dashboard/react/components/shared/FilterBar.module.css +0 -92
  262. claude_mpm/dashboard/react/components/shared/FilterBar.tsx +0 -89
  263. claude_mpm/dashboard/react/contexts/DashboardContext.tsx +0 -215
  264. claude_mpm/dashboard/react/entries/events.tsx +0 -165
  265. claude_mpm/dashboard/react/hooks/useEvents.ts +0 -191
  266. claude_mpm/dashboard/react/hooks/useSocket.ts +0 -225
  267. claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +0 -248
  268. claude_mpm/dashboard/static/built/REFACTORING_SUMMARY.md +0 -170
  269. claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +0 -1
  270. claude_mpm/dashboard/static/built/components/activity-tree.js +0 -2
  271. claude_mpm/dashboard/static/built/components/activity-tree.js.map +0 -1
  272. claude_mpm/dashboard/static/built/components/agent-hierarchy.js +0 -777
  273. claude_mpm/dashboard/static/built/components/agent-inference.js +0 -2
  274. claude_mpm/dashboard/static/built/components/agent-inference.js.map +0 -1
  275. claude_mpm/dashboard/static/built/components/build-tracker.js +0 -333
  276. claude_mpm/dashboard/static/built/components/code-simple.js +0 -857
  277. claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +0 -353
  278. claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +0 -235
  279. claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +0 -409
  280. claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +0 -435
  281. claude_mpm/dashboard/static/built/components/code-tree.js +0 -2
  282. claude_mpm/dashboard/static/built/components/code-tree.js.map +0 -1
  283. claude_mpm/dashboard/static/built/components/code-viewer.js +0 -2
  284. claude_mpm/dashboard/static/built/components/code-viewer.js.map +0 -1
  285. claude_mpm/dashboard/static/built/components/connection-debug.js +0 -654
  286. claude_mpm/dashboard/static/built/components/diff-viewer.js +0 -891
  287. claude_mpm/dashboard/static/built/components/event-processor.js +0 -2
  288. claude_mpm/dashboard/static/built/components/event-processor.js.map +0 -1
  289. claude_mpm/dashboard/static/built/components/event-viewer.js +0 -2
  290. claude_mpm/dashboard/static/built/components/event-viewer.js.map +0 -1
  291. claude_mpm/dashboard/static/built/components/export-manager.js +0 -2
  292. claude_mpm/dashboard/static/built/components/export-manager.js.map +0 -1
  293. claude_mpm/dashboard/static/built/components/file-change-tracker.js +0 -443
  294. claude_mpm/dashboard/static/built/components/file-change-viewer.js +0 -690
  295. claude_mpm/dashboard/static/built/components/file-tool-tracker.js +0 -2
  296. claude_mpm/dashboard/static/built/components/file-tool-tracker.js.map +0 -1
  297. claude_mpm/dashboard/static/built/components/file-viewer.js +0 -2
  298. claude_mpm/dashboard/static/built/components/file-viewer.js.map +0 -1
  299. claude_mpm/dashboard/static/built/components/hud-library-loader.js +0 -2
  300. claude_mpm/dashboard/static/built/components/hud-library-loader.js.map +0 -1
  301. claude_mpm/dashboard/static/built/components/hud-manager.js +0 -2
  302. claude_mpm/dashboard/static/built/components/hud-manager.js.map +0 -1
  303. claude_mpm/dashboard/static/built/components/hud-visualizer.js +0 -2
  304. claude_mpm/dashboard/static/built/components/hud-visualizer.js.map +0 -1
  305. claude_mpm/dashboard/static/built/components/module-viewer.js +0 -2
  306. claude_mpm/dashboard/static/built/components/module-viewer.js.map +0 -1
  307. claude_mpm/dashboard/static/built/components/nav-bar.js +0 -145
  308. claude_mpm/dashboard/static/built/components/page-structure.js +0 -429
  309. claude_mpm/dashboard/static/built/components/session-manager.js +0 -2
  310. claude_mpm/dashboard/static/built/components/session-manager.js.map +0 -1
  311. claude_mpm/dashboard/static/built/components/socket-manager.js +0 -2
  312. claude_mpm/dashboard/static/built/components/socket-manager.js.map +0 -1
  313. claude_mpm/dashboard/static/built/components/ui-state-manager.js +0 -2
  314. claude_mpm/dashboard/static/built/components/ui-state-manager.js.map +0 -1
  315. claude_mpm/dashboard/static/built/components/unified-data-viewer.js +0 -2
  316. claude_mpm/dashboard/static/built/components/unified-data-viewer.js.map +0 -1
  317. claude_mpm/dashboard/static/built/components/working-directory.js +0 -2
  318. claude_mpm/dashboard/static/built/components/working-directory.js.map +0 -1
  319. claude_mpm/dashboard/static/built/connection-manager.js +0 -536
  320. claude_mpm/dashboard/static/built/dashboard.js +0 -2
  321. claude_mpm/dashboard/static/built/dashboard.js.map +0 -1
  322. claude_mpm/dashboard/static/built/extension-error-handler.js +0 -164
  323. claude_mpm/dashboard/static/built/react/events.js +0 -30
  324. claude_mpm/dashboard/static/built/react/events.js.map +0 -1
  325. claude_mpm/dashboard/static/built/shared/dom-helpers.js +0 -396
  326. claude_mpm/dashboard/static/built/shared/event-bus.js +0 -330
  327. claude_mpm/dashboard/static/built/shared/event-filter-service.js +0 -540
  328. claude_mpm/dashboard/static/built/shared/logger.js +0 -385
  329. claude_mpm/dashboard/static/built/shared/page-structure.js +0 -249
  330. claude_mpm/dashboard/static/built/shared/tooltip-service.js +0 -253
  331. claude_mpm/dashboard/static/built/socket-client.js +0 -2
  332. claude_mpm/dashboard/static/built/socket-client.js.map +0 -1
  333. claude_mpm/dashboard/static/built/tab-isolation-fix.js +0 -185
  334. claude_mpm/dashboard/static/events.html +0 -607
  335. claude_mpm/dashboard/static/index.html +0 -635
  336. claude_mpm/dashboard/static/js/REFACTORING_SUMMARY.md +0 -170
  337. claude_mpm/dashboard/static/js/shared/dom-helpers.js +0 -396
  338. claude_mpm/dashboard/static/js/shared/event-bus.js +0 -330
  339. claude_mpm/dashboard/static/js/shared/logger.js +0 -385
  340. claude_mpm/dashboard/static/js/shared/tooltip-service.js +0 -253
  341. claude_mpm/dashboard/static/js/stores/dashboard-store.js +0 -562
  342. claude_mpm/dashboard/static/legacy/activity.html +0 -736
  343. claude_mpm/dashboard/static/legacy/agents.html +0 -786
  344. claude_mpm/dashboard/static/legacy/files.html +0 -747
  345. claude_mpm/dashboard/static/legacy/tools.html +0 -831
  346. claude_mpm/dashboard/static/monitors.html +0 -431
  347. claude_mpm/dashboard/static/navigation-test-results.md +0 -118
  348. claude_mpm/dashboard/static/production/events.html +0 -659
  349. claude_mpm/dashboard/static/production/main.html +0 -698
  350. claude_mpm/dashboard/static/production/monitors.html +0 -483
  351. claude_mpm/dashboard/static/test-archive/dashboard.html +0 -635
  352. claude_mpm/dashboard/static/test-archive/debug-events.html +0 -147
  353. claude_mpm/dashboard/static/test-archive/test-navigation.html +0 -256
  354. claude_mpm/dashboard/static/test-archive/test-react-exports.html +0 -180
  355. claude_mpm/dashboard/templates/.claude-mpm/memories/README.md +0 -36
  356. claude_mpm/dashboard/templates/.claude-mpm/memories/engineer_agent.md +0 -39
  357. claude_mpm/dashboard/templates/.claude-mpm/memories/version_control_agent.md +0 -38
  358. claude_mpm/hooks/README.md +0 -143
  359. claude_mpm/hooks/templates/README.md +0 -180
  360. claude_mpm/hooks/templates/settings.json.example +0 -147
  361. claude_mpm/schemas/agent_schema.json +0 -596
  362. claude_mpm/schemas/frontmatter_schema.json +0 -165
  363. claude_mpm/services/event_bus/README.md +0 -244
  364. claude_mpm/services/events/README.md +0 -303
  365. claude_mpm/services/framework_claude_md_generator/README.md +0 -119
  366. claude_mpm/services/mcp_gateway/README.md +0 -185
  367. claude_mpm/services/socketio/handlers/connection.py.backup +0 -217
  368. claude_mpm/services/socketio/handlers/hook.py.backup +0 -154
  369. claude_mpm/services/static/.gitkeep +0 -2
  370. claude_mpm/services/version_control/VERSION +0 -1
  371. claude_mpm/skills/bundled/.gitkeep +0 -2
  372. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +0 -79
  373. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +0 -178
  374. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +0 -577
  375. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +0 -467
  376. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +0 -537
  377. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +0 -730
  378. claude_mpm/skills/bundled/collaboration/git-worktrees.md +0 -317
  379. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +0 -112
  380. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +0 -146
  381. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +0 -412
  382. claude_mpm/skills/bundled/collaboration/stacked-prs.md +0 -251
  383. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +0 -81
  384. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +0 -362
  385. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +0 -312
  386. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +0 -152
  387. claude_mpm/skills/bundled/debugging/root-cause-tracing/find-polluter.sh +0 -63
  388. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +0 -668
  389. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +0 -587
  390. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +0 -438
  391. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +0 -391
  392. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +0 -119
  393. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +0 -148
  394. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +0 -483
  395. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +0 -452
  396. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +0 -449
  397. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +0 -411
  398. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +0 -14
  399. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +0 -58
  400. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +0 -68
  401. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +0 -69
  402. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +0 -131
  403. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +0 -325
  404. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +0 -490
  405. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +0 -425
  406. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +0 -499
  407. claude_mpm/skills/bundled/infrastructure/env-manager/INTEGRATION.md +0 -611
  408. claude_mpm/skills/bundled/infrastructure/env-manager/README.md +0 -596
  409. claude_mpm/skills/bundled/infrastructure/env-manager/SKILL.md +0 -260
  410. claude_mpm/skills/bundled/infrastructure/env-manager/examples/nextjs-env-structure.md +0 -315
  411. claude_mpm/skills/bundled/infrastructure/env-manager/references/frameworks.md +0 -436
  412. claude_mpm/skills/bundled/infrastructure/env-manager/references/security.md +0 -433
  413. claude_mpm/skills/bundled/infrastructure/env-manager/references/synchronization.md +0 -452
  414. claude_mpm/skills/bundled/infrastructure/env-manager/references/troubleshooting.md +0 -404
  415. claude_mpm/skills/bundled/infrastructure/env-manager/references/validation.md +0 -420
  416. claude_mpm/skills/bundled/main/artifacts-builder/LICENSE.txt +0 -202
  417. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +0 -86
  418. claude_mpm/skills/bundled/main/artifacts-builder/scripts/bundle-artifact.sh +0 -54
  419. claude_mpm/skills/bundled/main/artifacts-builder/scripts/init-artifact.sh +0 -322
  420. claude_mpm/skills/bundled/main/artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
  421. claude_mpm/skills/bundled/main/internal-comms/LICENSE.txt +0 -202
  422. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +0 -43
  423. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +0 -47
  424. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +0 -65
  425. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +0 -30
  426. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +0 -16
  427. claude_mpm/skills/bundled/main/mcp-builder/LICENSE.txt +0 -202
  428. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +0 -160
  429. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +0 -412
  430. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +0 -602
  431. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +0 -915
  432. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +0 -916
  433. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +0 -752
  434. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +0 -1237
  435. claude_mpm/skills/bundled/main/mcp-builder/scripts/example_evaluation.xml +0 -22
  436. claude_mpm/skills/bundled/main/mcp-builder/scripts/requirements.txt +0 -2
  437. claude_mpm/skills/bundled/main/skill-creator/LICENSE.txt +0 -202
  438. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +0 -189
  439. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +0 -500
  440. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +0 -464
  441. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +0 -619
  442. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +0 -437
  443. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +0 -231
  444. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +0 -170
  445. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +0 -602
  446. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +0 -821
  447. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +0 -742
  448. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +0 -726
  449. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +0 -764
  450. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +0 -831
  451. claude_mpm/skills/bundled/react/flexlayout-react.md +0 -742
  452. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +0 -226
  453. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +0 -901
  454. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +0 -901
  455. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +0 -775
  456. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +0 -937
  457. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +0 -770
  458. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +0 -961
  459. claude_mpm/skills/bundled/tauri/tauri-async-patterns.md +0 -495
  460. claude_mpm/skills/bundled/tauri/tauri-build-deploy.md +0 -599
  461. claude_mpm/skills/bundled/tauri/tauri-command-patterns.md +0 -535
  462. claude_mpm/skills/bundled/tauri/tauri-error-handling.md +0 -613
  463. claude_mpm/skills/bundled/tauri/tauri-event-system.md +0 -648
  464. claude_mpm/skills/bundled/tauri/tauri-file-system.md +0 -673
  465. claude_mpm/skills/bundled/tauri/tauri-frontend-integration.md +0 -767
  466. claude_mpm/skills/bundled/tauri/tauri-performance.md +0 -669
  467. claude_mpm/skills/bundled/tauri/tauri-state-management.md +0 -573
  468. claude_mpm/skills/bundled/tauri/tauri-testing.md +0 -384
  469. claude_mpm/skills/bundled/tauri/tauri-window-management.md +0 -628
  470. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +0 -119
  471. claude_mpm/skills/bundled/testing/condition-based-waiting/example.ts +0 -158
  472. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +0 -253
  473. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +0 -145
  474. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +0 -543
  475. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +0 -741
  476. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +0 -470
  477. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +0 -458
  478. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +0 -639
  479. claude_mpm/skills/bundled/testing/test-quality-inspector/SKILL.md +0 -458
  480. claude_mpm/skills/bundled/testing/test-quality-inspector/examples/example-inspection-report.md +0 -411
  481. claude_mpm/skills/bundled/testing/test-quality-inspector/references/assertion-quality.md +0 -317
  482. claude_mpm/skills/bundled/testing/test-quality-inspector/references/inspection-checklist.md +0 -270
  483. claude_mpm/skills/bundled/testing/test-quality-inspector/references/red-flags.md +0 -436
  484. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +0 -140
  485. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +0 -572
  486. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +0 -411
  487. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +0 -569
  488. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +0 -695
  489. claude_mpm/skills/bundled/testing/webapp-testing/LICENSE.txt +0 -202
  490. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +0 -184
  491. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +0 -459
  492. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +0 -479
  493. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +0 -687
  494. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +0 -758
  495. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +0 -868
  496. claude_mpm/templates/questions/EXAMPLES.md +0 -501
  497. claude_mpm/tools/README_SOCKETIO_DEBUG.md +0 -224
  498. claude_mpm/tools/code_tree_analyzer/README.md +0 -64
  499. /claude_mpm/agents/templates/{git_file_tracking.md → git-file-tracking.md} +0 -0
  500. /claude_mpm/agents/templates/{pm_examples.md → pm-examples.md} +0 -0
  501. /claude_mpm/agents/templates/{pm_red_flags.md → pm-red-flags.md} +0 -0
  502. /claude_mpm/agents/templates/{response_format.md → response-format.md} +0 -0
  503. /claude_mpm/agents/templates/{validation_templates.md → validation-templates.md} +0 -0
  504. {claude_mpm-4.25.10.dist-info → claude_mpm-5.1.8.dist-info}/WHEEL +0 -0
  505. {claude_mpm-4.25.10.dist-info → claude_mpm-5.1.8.dist-info}/entry_points.txt +0 -0
  506. {claude_mpm-4.25.10.dist-info → claude_mpm-5.1.8.dist-info}/licenses/LICENSE +0 -0
  507. {claude_mpm-4.25.10.dist-info → claude_mpm-5.1.8.dist-info}/top_level.txt +0 -0
@@ -1,2 +0,0 @@
1
- window.FileToolTracker=class{constructor(e,t){this.agentInference=e,this.workingDirectoryManager=t,this.fileOperations=new Map,this.toolCalls=new Map,console.log("File-tool tracker initialized")}updateFileOperations(e){this.fileOperations.clear(),console.log("updateFileOperations - processing",e.length,"events");const t=new Map;let o=0;e.forEach((e,a)=>{const s=this.isFileOperation(e);if(s&&o++,a<5&&console.log(`Event ${a}:`,{type:e.type,subtype:e.subtype,tool_name:e.tool_name,tool_parameters:e.tool_parameters,isFileOp:s}),s){const o=e.tool_name||e.data&&e.data.tool_name,a=e.session_id||e.data&&e.data.session_id||"unknown",s=`${a}_${o}_${Math.floor(new Date(e.timestamp).getTime()/1e3)}`;t.has(s)||t.set(s,{pre_event:null,post_event:null,tool_name:o,session_id:a});const n=t.get(s);"pre_tool"===e.subtype||"hook"===e.type&&e.subtype&&!e.subtype.includes("post")?n.pre_event=e:("post_tool"===e.subtype||e.subtype&&e.subtype.includes("post")||(n.pre_event=e),n.post_event=e)}}),console.log("updateFileOperations - found",o,"file operations in",t.size,"event pairs"),t.forEach((e,t)=>{const o=this.extractFilePathFromPair(e);if(o){console.log("File operation detected for:",o,"from pair:",t),this.fileOperations.has(o)||this.fileOperations.set(o,{path:o,operations:[],lastOperation:null});const a=this.fileOperations.get(o),s=this.getFileOperationFromPair(e),n=e.post_event?.timestamp||e.pre_event?.timestamp,r=this.extractAgentFromPair(e),i=this.workingDirectoryManager.extractWorkingDirectoryFromPair(e);a.operations.push({operation:s,timestamp:n,agent:r.name,confidence:r.confidence,sessionId:e.session_id,details:this.getFileOperationDetailsFromPair(e),workingDirectory:i}),a.lastOperation=n}else console.log("No file path found for pair:",t,e)}),console.log("updateFileOperations - final result:",this.fileOperations.size,"file operations"),this.fileOperations.size>0&&console.log("File operations map:",Array.from(this.fileOperations.entries()))}updateToolCalls(e){this.toolCalls.clear(),console.log("updateToolCalls - processing",e.length,"events");const t=[],o=[];let a=0;e.forEach((e,s)=>{const n=this.isToolOperation(e);n&&a++,s<5&&console.log(`Tool Event ${s}:`,{type:e.type,subtype:e.subtype,tool_name:e.tool_name,tool_parameters:e.tool_parameters,isToolOp:n}),n&&("pre_tool"===e.subtype||"hook"===e.type&&e.subtype&&!e.subtype.includes("post")?t.push(e):("post_tool"===e.subtype||e.subtype&&e.subtype.includes("post")||t.push(e),o.push(e)))}),console.log("updateToolCalls - found",a,"tool operations:",t.length,"pre_tool,",o.length,"post_tool");const s=new Map,n=new Set;t.forEach((e,t)=>{const a=e.tool_name||e.data&&e.data.tool_name,r=e.session_id||e.data&&e.data.session_id||"unknown",i=new Date(e.timestamp).getTime(),l=`${r}_${a}_${t}_${i}`,p={pre_event:e,post_event:null,tool_name:a,session_id:r,operation_type:e.operation_type||"tool_execution",timestamp:e.timestamp,duration_ms:null,success:null,exit_code:null,result_summary:null,agent_type:null,agent_confidence:null},c=this.extractAgentFromEvent(e);p.agent_type=c.name,p.agent_confidence=c.confidence;let _=-1,m=-1;if(o.forEach((t,o)=>{if(n.has(o))return;const s=t.tool_name||t.data&&t.data.tool_name,l=t.session_id||t.data&&t.data.session_id||"unknown";if(s!==a||l!==r)return;const p=new Date(t.timestamp).getTime(),c=Math.abs(p-i);let u=0;p>=i-1e3&&c<=3e5&&(u=1e3-c/1e3,this.compareToolParameters(e,t)&&(u+=500),e.working_directory&&t.working_directory&&e.working_directory===t.working_directory&&(u+=100)),u>m&&(m=u,_=o)}),_>=0&&m>0){const t=o[_];p.post_event=t,p.duration_ms=t.duration_ms,p.success=t.success,p.exit_code=t.exit_code,p.result_summary=t.result_summary,n.add(_),console.log(`Paired pre_tool ${a} at ${e.timestamp} with post_tool at ${t.timestamp} (score: ${m})`)}else console.log(`No matching post_tool found for ${a} at ${e.timestamp} (still running or orphaned)`);s.set(l,p)}),o.forEach((e,t)=>{if(n.has(t))return;const o=e.tool_name||e.data&&e.data.tool_name;console.log("Orphaned post_tool event found:",o,"at",e.timestamp);const a=e.session_id||e.data&&e.data.session_id||"unknown",r=`orphaned_${a}_${o}_${t}_${new Date(e.timestamp).getTime()}`,i={pre_event:null,post_event:e,tool_name:o,session_id:a,operation_type:"tool_execution",timestamp:e.timestamp,duration_ms:e.duration_ms,success:e.success,exit_code:e.exit_code,result_summary:e.result_summary,agent_type:null,agent_confidence:null},l=this.extractAgentFromEvent(e);i.agent_type=l.name,i.agent_confidence=l.confidence,s.set(r,i)}),this.toolCalls=s,console.log("updateToolCalls - final result:",this.toolCalls.size,"tool calls"),this.toolCalls.size>0&&console.log("Tool calls map keys:",Array.from(this.toolCalls.keys()))}isToolOperation(e){const t=e.tool_name||e.data&&e.data.tool_name,o=["hook","tool_use","tool","agent","response"].includes(e.type)||e.type&&e.type.includes("tool"),a="pre_tool"===e.subtype||"post_tool"===e.subtype||e.subtype&&"string"==typeof e.subtype&&e.subtype.includes("tool")||"tool_use"===e.type||"tool"===e.type;return t&&(o||a)}isFileOperation(e){let t=e.tool_name||e.data&&e.data.tool_name||"";if(!t)return!1;t=t.toLowerCase();const o=e.tool_parameters||e.data&&e.data.tool_parameters;if("bash"===t&&o){if((o.command||"").match(/\b(cat|less|more|head|tail|touch|mv|cp|rm|mkdir|ls|find)\b/))return!0}return["read","write","edit","grep","multiedit","glob","ls","bash","notebookedit"].includes(t)}extractFilePath(e){const t=e.tool_name||e.data&&e.data.tool_name;if(["Read","Write","Edit","MultiEdit","NotebookEdit"].includes(t)&&console.log("Extracting file path from event:",{tool_name:t,has_tool_parameters_top:!!e.tool_parameters,has_tool_parameters_data:!(!e.data||!e.data.tool_parameters),tool_parameters:e.tool_parameters,data_tool_parameters:e.data?.tool_parameters}),e.tool_parameters?.file_path)return e.tool_parameters.file_path;if(e.tool_parameters?.path)return e.tool_parameters.path;if(e.tool_parameters?.notebook_path)return e.tool_parameters.notebook_path;if(e.data?.tool_parameters?.file_path)return e.data.tool_parameters.file_path;if(e.data?.tool_parameters?.path)return e.data.tool_parameters.path;if(e.data?.tool_parameters?.notebook_path)return e.data.tool_parameters.notebook_path;if(e.file_path)return e.file_path;if(e.path)return e.path;if("glob"===e.tool_name?.toLowerCase()&&e.tool_parameters?.pattern)return`[glob] ${e.tool_parameters.pattern}`;if("bash"===e.tool_name?.toLowerCase()&&e.tool_parameters?.command){const t=e.tool_parameters.command,o=t.match(/(?:cat|less|more|head|tail|touch|mv|cp|rm|mkdir|ls|find|echo.*>|sed|awk|grep)(?:\s+-[a-zA-Z0-9]+)*(?:\s+[0-9]+)*\s+([^\s;|&]+)/);if(o&&o[1]){const e=o[1];if(e.startsWith("-")){const e=t.match(/(?:cat|less|more|head|tail|touch|mv|cp|rm|mkdir|ls|find|echo.*>|sed|awk|grep)(?:\s+-[^\s]+)*\s+([^-][^\s;|&]*)/);if(e&&e[1])return e[1]}return e}}return null}extractFilePathFromPair(e){let t=null;return e.pre_event&&(t=this.extractFilePath(e.pre_event)),!t&&e.post_event&&(t=this.extractFilePath(e.post_event)),t}getFileOperation(e){if(!e.tool_name)return"unknown";const t=e.tool_name.toLowerCase();switch(t){case"read":return"read";case"write":return"write";case"edit":case"multiedit":case"notebookedit":return"edit";case"grep":case"glob":return"search";case"ls":return"list";case"bash":const o=e.tool_parameters?.command||"";return o.match(/\b(cat|less|more|head|tail)\b/)?"read":o.match(/\b(touch|echo.*>|tee)\b/)?"write":o.match(/\b(sed|awk)\b/)?"edit":o.match(/\b(grep|find)\b/)?"search":o.match(/\b(ls|dir)\b/)?"list":o.match(/\b(mv|cp)\b/)?"copy/move":o.match(/\b(rm|rmdir)\b/)?"delete":o.match(/\b(mkdir)\b/)?"create":"bash";default:return t}}getFileOperationFromPair(e){return e.pre_event?this.getFileOperation(e.pre_event):e.post_event?this.getFileOperation(e.post_event):"unknown"}extractAgentFromPair(e){const t=e.pre_event||e.post_event;if(t&&this.agentInference){const e=this.agentInference.getInferredAgentForEvent(t);if(e)return{name:e.agentName||"Unknown",confidence:e.confidence||"unknown"}}return{name:t?.agent_type||t?.subagent_type||e.pre_event?.agent_type||e.post_event?.agent_type||"PM",confidence:"direct"}}getFileOperationDetailsFromPair(e){const t={};if(e.pre_event){const o=e.pre_event.tool_parameters||e.pre_event.data?.tool_parameters||{};t.parameters=o,t.tool_input=e.pre_event.tool_input}return e.post_event&&(t.result=e.post_event.result,t.success=e.post_event.success,t.error=e.post_event.error,t.exit_code=e.post_event.exit_code,t.duration_ms=e.post_event.duration_ms),t}getFileOperations(){return this.fileOperations}getToolCalls(){return this.toolCalls}getToolCallsArray(){return Array.from(this.toolCalls.entries())}getFileOperationsForFile(e){return this.fileOperations.get(e)||null}getToolCall(e){return this.toolCalls.get(e)||null}clear(){this.fileOperations.clear(),this.toolCalls.clear(),console.log("File-tool tracker cleared")}getStatistics(){return{fileOperations:this.fileOperations.size,toolCalls:this.toolCalls.size,uniqueFiles:this.fileOperations.size,totalFileOperations:Array.from(this.fileOperations.values()).reduce((e,t)=>e+t.operations.length,0)}}compareToolParameters(e,t){const o=e.tool_parameters||e.data?.tool_parameters||{},a=t.tool_parameters||t.data?.tool_parameters||{};if(0===Object.keys(o).length&&0===Object.keys(a).length)return!1;let s=0,n=0;if(["file_path","path","pattern","command","notebook_path"].forEach(e=>{const t=o[e],r=a[e];void 0===t&&void 0===r||(n++,t===r&&s++)}),n>0)return s/n>=.8;const r=Object.keys(o).sort(),i=Object.keys(a).sort();if(0===r.length&&0===i.length)return!1;if(r.length===i.length){return r.filter(e=>i.includes(e)).length>=Math.max(1,.5*r.length)}return!1}extractAgentFromEvent(e){if(this.agentInference){const t=this.agentInference.getInferredAgentForEvent(e);if(t)return{name:t.agentName||"Unknown",confidence:t.confidence||"unknown"}}return{name:e.agent_type||e.subagent_type||e.data?.agent_type||e.data?.subagent_type||"PM",confidence:"direct"}}};
2
- //# sourceMappingURL=file-tool-tracker.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"file-tool-tracker.js","sources":["../../js/components/file-tool-tracker.js"],"sourcesContent":["/**\n * File and Tool Tracker Module\n *\n * Tracks file operations and tool calls by pairing pre/post events and maintaining\n * organized collections for the files and tools tabs. Provides analysis of\n * tool execution patterns and file operation history.\n *\n * WHY: Extracted from main dashboard to isolate complex event pairing logic\n * that groups related events into meaningful operations. This provides better\n * maintainability for the intricate logic of matching tool events with their results.\n *\n * DESIGN DECISION: Uses intelligent correlation strategy for tool calls that:\n * - Separates pre_tool and post_tool events first\n * - Correlates based on temporal proximity, parameter similarity, and context\n * - Handles timing differences between pre/post events (tools can run for minutes)\n * - Prevents duplicate tool entries by ensuring each tool call appears once\n * - Supports both paired and orphaned events for comprehensive tracking\n */\nclass FileToolTracker {\n constructor(agentInference, workingDirectoryManager) {\n this.agentInference = agentInference;\n this.workingDirectoryManager = workingDirectoryManager;\n\n // File tracking for files tab\n this.fileOperations = new Map(); // Map of file paths to operations\n\n // Tool call tracking for tools tab\n this.toolCalls = new Map(); // Map of tool call keys to paired pre/post events\n\n console.log('File-tool tracker initialized');\n }\n\n /**\n * Update file operations from events\n * @param {Array} events - Events to process\n */\n updateFileOperations(events) {\n // Clear existing data\n this.fileOperations.clear();\n\n console.log('updateFileOperations - processing', events.length, 'events');\n\n // Group events by session and timestamp to match pre/post pairs\n const eventPairs = new Map(); // Key: session_id + timestamp + tool_name\n let fileOperationCount = 0;\n\n // First pass: collect all tool events and group them\n events.forEach((event, index) => {\n const isFileOp = this.isFileOperation(event);\n if (isFileOp) fileOperationCount++;\n\n if (index < 5) { // Debug first 5 events with more detail\n console.log(`Event ${index}:`, {\n type: event.type,\n subtype: event.subtype,\n tool_name: event.tool_name,\n tool_parameters: event.tool_parameters,\n isFileOp: isFileOp\n });\n }\n\n if (isFileOp) {\n const toolName = event.tool_name || (event.data && event.data.tool_name);\n const sessionId = event.session_id || (event.data && event.data.session_id) || 'unknown';\n const eventKey = `${sessionId}_${toolName}_${Math.floor(new Date(event.timestamp).getTime() / 1000)}`; // Group by second\n\n if (!eventPairs.has(eventKey)) {\n eventPairs.set(eventKey, {\n pre_event: null,\n post_event: null,\n tool_name: toolName,\n session_id: sessionId\n });\n }\n\n const pair = eventPairs.get(eventKey);\n if (event.subtype === 'pre_tool' || (event.type === 'hook' && event.subtype && !event.subtype.includes('post'))) {\n pair.pre_event = event;\n } else if (event.subtype === 'post_tool' || (event.subtype && event.subtype.includes('post'))) {\n pair.post_event = event;\n } else {\n // For events without clear pre/post distinction, treat as both\n pair.pre_event = event;\n pair.post_event = event;\n }\n }\n });\n\n console.log('updateFileOperations - found', fileOperationCount, 'file operations in', eventPairs.size, 'event pairs');\n\n // Second pass: extract file paths and operations from paired events\n eventPairs.forEach((pair, key) => {\n const filePath = this.extractFilePathFromPair(pair);\n\n if (filePath) {\n console.log('File operation detected for:', filePath, 'from pair:', key);\n\n if (!this.fileOperations.has(filePath)) {\n this.fileOperations.set(filePath, {\n path: filePath,\n operations: [],\n lastOperation: null\n });\n }\n\n const fileData = this.fileOperations.get(filePath);\n const operation = this.getFileOperationFromPair(pair);\n const timestamp = pair.post_event?.timestamp || pair.pre_event?.timestamp;\n\n const agentInfo = this.extractAgentFromPair(pair);\n const workingDirectory = this.workingDirectoryManager.extractWorkingDirectoryFromPair(pair);\n\n fileData.operations.push({\n operation: operation,\n timestamp: timestamp,\n agent: agentInfo.name,\n confidence: agentInfo.confidence,\n sessionId: pair.session_id,\n details: this.getFileOperationDetailsFromPair(pair),\n workingDirectory: workingDirectory\n });\n fileData.lastOperation = timestamp;\n } else {\n console.log('No file path found for pair:', key, pair);\n }\n });\n\n console.log('updateFileOperations - final result:', this.fileOperations.size, 'file operations');\n if (this.fileOperations.size > 0) {\n console.log('File operations map:', Array.from(this.fileOperations.entries()));\n }\n }\n\n /**\n * Update tool calls from events - pairs pre/post tool events into complete tool calls\n * @param {Array} events - Events to process\n */\n updateToolCalls(events) {\n // Clear existing data\n this.toolCalls.clear();\n\n console.log('updateToolCalls - processing', events.length, 'events');\n\n // Improved correlation strategy: collect events first, then correlate intelligently\n const preToolEvents = [];\n const postToolEvents = [];\n let toolOperationCount = 0;\n\n // First pass: separate pre_tool and post_tool events\n events.forEach((event, index) => {\n const isToolOp = this.isToolOperation(event);\n if (isToolOp) toolOperationCount++;\n\n if (index < 5) { // Debug first 5 events with more detail\n console.log(`Tool Event ${index}:`, {\n type: event.type,\n subtype: event.subtype,\n tool_name: event.tool_name,\n tool_parameters: event.tool_parameters,\n isToolOp: isToolOp\n });\n }\n\n if (isToolOp) {\n if (event.subtype === 'pre_tool' || (event.type === 'hook' && event.subtype && !event.subtype.includes('post'))) {\n preToolEvents.push(event);\n } else if (event.subtype === 'post_tool' || (event.subtype && event.subtype.includes('post'))) {\n postToolEvents.push(event);\n } else {\n // For events without clear pre/post distinction, treat as standalone\n preToolEvents.push(event);\n postToolEvents.push(event);\n }\n }\n });\n\n console.log('updateToolCalls - found', toolOperationCount, 'tool operations:', preToolEvents.length, 'pre_tool,', postToolEvents.length, 'post_tool');\n\n // Second pass: correlate pre_tool events with post_tool events\n const toolCallPairs = new Map();\n const usedPostEvents = new Set();\n\n preToolEvents.forEach((preEvent, preIndex) => {\n const toolName = preEvent.tool_name || (preEvent.data && preEvent.data.tool_name);\n const sessionId = preEvent.session_id || (preEvent.data && preEvent.data.session_id) || 'unknown';\n const preTimestamp = new Date(preEvent.timestamp).getTime();\n\n // Create a base pair for this pre_tool event\n const pairKey = `${sessionId}_${toolName}_${preIndex}_${preTimestamp}`;\n const pair = {\n pre_event: preEvent,\n post_event: null,\n tool_name: toolName,\n session_id: sessionId,\n operation_type: preEvent.operation_type || 'tool_execution',\n timestamp: preEvent.timestamp,\n duration_ms: null,\n success: null,\n exit_code: null,\n result_summary: null,\n agent_type: null,\n agent_confidence: null\n };\n\n // Get agent info from pre_event\n const agentInfo = this.extractAgentFromEvent(preEvent);\n pair.agent_type = agentInfo.name;\n pair.agent_confidence = agentInfo.confidence;\n\n // Try to find matching post_tool event\n let bestMatchIndex = -1;\n let bestMatchScore = -1;\n const maxTimeDiffMs = 300000; // 5 minutes max time difference\n\n postToolEvents.forEach((postEvent, postIndex) => {\n // Skip already used post events\n if (usedPostEvents.has(postIndex)) return;\n\n // Must match tool name and session\n const postToolName = postEvent.tool_name || (postEvent.data && postEvent.data.tool_name);\n const postSessionId = postEvent.session_id || (postEvent.data && postEvent.data.session_id) || 'unknown';\n if (postToolName !== toolName || postSessionId !== sessionId) return;\n\n const postTimestamp = new Date(postEvent.timestamp).getTime();\n const timeDiff = Math.abs(postTimestamp - preTimestamp);\n\n // Post event should generally come after pre event (or very close)\n const isTemporallyValid = postTimestamp >= preTimestamp - 1000; // Allow 1s clock skew\n\n // Calculate correlation score (higher is better)\n let score = 0;\n if (isTemporallyValid && timeDiff <= maxTimeDiffMs) {\n score = 1000 - (timeDiff / 1000); // Prefer closer timestamps\n\n // Boost score for parameter similarity (if available)\n if (this.compareToolParameters(preEvent, postEvent)) {\n score += 500;\n }\n\n // Boost score for same working directory\n if (preEvent.working_directory && postEvent.working_directory &&\n preEvent.working_directory === postEvent.working_directory) {\n score += 100;\n }\n }\n\n if (score > bestMatchScore) {\n bestMatchScore = score;\n bestMatchIndex = postIndex;\n }\n });\n\n // If we found a good match, pair them\n if (bestMatchIndex >= 0 && bestMatchScore > 0) {\n const postEvent = postToolEvents[bestMatchIndex];\n pair.post_event = postEvent;\n pair.duration_ms = postEvent.duration_ms;\n pair.success = postEvent.success;\n pair.exit_code = postEvent.exit_code;\n pair.result_summary = postEvent.result_summary;\n\n usedPostEvents.add(bestMatchIndex);\n console.log(`Paired pre_tool ${toolName} at ${preEvent.timestamp} with post_tool at ${postEvent.timestamp} (score: ${bestMatchScore})`);\n } else {\n console.log(`No matching post_tool found for ${toolName} at ${preEvent.timestamp} (still running or orphaned)`);\n }\n\n toolCallPairs.set(pairKey, pair);\n });\n\n // Third pass: handle any orphaned post_tool events (shouldn't happen but be safe)\n postToolEvents.forEach((postEvent, postIndex) => {\n if (usedPostEvents.has(postIndex)) return;\n\n const toolName = postEvent.tool_name || (postEvent.data && postEvent.data.tool_name);\n console.log('Orphaned post_tool event found:', toolName, 'at', postEvent.timestamp);\n\n const sessionId = postEvent.session_id || (postEvent.data && postEvent.data.session_id) || 'unknown';\n const postTimestamp = new Date(postEvent.timestamp).getTime();\n\n const pairKey = `orphaned_${sessionId}_${toolName}_${postIndex}_${postTimestamp}`;\n const pair = {\n pre_event: null,\n post_event: postEvent,\n tool_name: toolName,\n session_id: sessionId,\n operation_type: 'tool_execution',\n timestamp: postEvent.timestamp,\n duration_ms: postEvent.duration_ms,\n success: postEvent.success,\n exit_code: postEvent.exit_code,\n result_summary: postEvent.result_summary,\n agent_type: null,\n agent_confidence: null\n };\n\n const agentInfo = this.extractAgentFromEvent(postEvent);\n pair.agent_type = agentInfo.name;\n pair.agent_confidence = agentInfo.confidence;\n\n toolCallPairs.set(pairKey, pair);\n });\n\n // Store the correlated tool calls\n this.toolCalls = toolCallPairs;\n\n console.log('updateToolCalls - final result:', this.toolCalls.size, 'tool calls');\n if (this.toolCalls.size > 0) {\n console.log('Tool calls map keys:', Array.from(this.toolCalls.keys()));\n }\n }\n\n /**\n * Check if event is a tool operation\n * @param {Object} event - Event to check\n * @returns {boolean} - True if tool operation\n */\n isToolOperation(event) {\n // Tool operations have tool_name - be more inclusive about event types\n // Check both top-level and data.tool_name for compatibility\n const hasToolName = event.tool_name || (event.data && event.data.tool_name);\n\n // Accept multiple event types that might contain tool operations\n const validEventTypes = ['hook', 'tool_use', 'tool', 'agent', 'response'];\n const isValidEventType = validEventTypes.includes(event.type) ||\n (event.type && event.type.includes('tool'));\n\n // Check for tool-related subtypes or any indication this is a tool operation\n const isToolSubtype = event.subtype === 'pre_tool' ||\n event.subtype === 'post_tool' ||\n (event.subtype && typeof event.subtype === 'string' && event.subtype.includes('tool')) ||\n event.type === 'tool_use' ||\n event.type === 'tool';\n\n // If it has a tool_name and either a valid event type or tool subtype, it's a tool operation\n return hasToolName && (isValidEventType || isToolSubtype);\n }\n\n /**\n * Check if event is a file operation\n * @param {Object} event - Event to check\n * @returns {boolean} - True if file operation\n */\n isFileOperation(event) {\n // File operations are events with file-related tools - be more inclusive\n // Check both top-level and data for tool_name\n let toolName = event.tool_name || (event.data && event.data.tool_name) || '';\n\n // If no tool name, not a file operation\n if (!toolName) {\n return false;\n }\n\n toolName = toolName.toLowerCase();\n\n // Check case-insensitively since tool names can come in different cases\n const fileTools = ['read', 'write', 'edit', 'grep', 'multiedit', 'glob', 'ls', 'bash', 'notebookedit'];\n\n // Get tool parameters from either location\n const toolParams = event.tool_parameters || (event.data && event.data.tool_parameters);\n\n // Also check if Bash commands involve file operations\n if (toolName === 'bash' && toolParams) {\n const command = toolParams.command || '';\n // Check for common file operations in bash commands\n if (command.match(/\\b(cat|less|more|head|tail|touch|mv|cp|rm|mkdir|ls|find)\\b/)) {\n return true;\n }\n }\n\n // If it's a file tool, it's a file operation regardless of event type\n return fileTools.includes(toolName);\n }\n\n /**\n * Extract file path from event\n * @param {Object} event - Event to extract from\n * @returns {string|null} - File path or null\n */\n extractFilePath(event) {\n // Debug logging for file path extraction\n const fileTools = ['Read', 'Write', 'Edit', 'MultiEdit', 'NotebookEdit'];\n const toolName = event.tool_name || (event.data && event.data.tool_name);\n \n if (fileTools.includes(toolName)) {\n console.log('Extracting file path from event:', {\n tool_name: toolName,\n has_tool_parameters_top: !!event.tool_parameters,\n has_tool_parameters_data: !!(event.data && event.data.tool_parameters),\n tool_parameters: event.tool_parameters,\n data_tool_parameters: event.data?.tool_parameters\n });\n }\n \n // Try various locations where file path might be stored\n // Check top-level tool_parameters first (after transformation)\n if (event.tool_parameters?.file_path) return event.tool_parameters.file_path;\n if (event.tool_parameters?.path) return event.tool_parameters.path;\n if (event.tool_parameters?.notebook_path) return event.tool_parameters.notebook_path;\n \n // Check in data object as fallback\n if (event.data?.tool_parameters?.file_path) return event.data.tool_parameters.file_path;\n if (event.data?.tool_parameters?.path) return event.data.tool_parameters.path;\n if (event.data?.tool_parameters?.notebook_path) return event.data.tool_parameters.notebook_path;\n if (event.file_path) return event.file_path;\n if (event.path) return event.path;\n\n // For Glob tool, use the pattern as a pseudo-path\n if (event.tool_name?.toLowerCase() === 'glob' && event.tool_parameters?.pattern) {\n return `[glob] ${event.tool_parameters.pattern}`;\n }\n\n // For Bash commands, try to extract file paths from the command\n if (event.tool_name?.toLowerCase() === 'bash' && event.tool_parameters?.command) {\n const command = event.tool_parameters.command;\n \n // Enhanced regex to handle commands with flags\n // Match command followed by optional flags (starting with -) and then the file path\n // Patterns to handle:\n // 1. tail -50 /path/to/file\n // 2. head -n 100 /path/to/file \n // 3. cat /path/to/file\n // 4. grep -r \"pattern\" /path/to/file\n const fileMatch = command.match(/(?:cat|less|more|head|tail|touch|mv|cp|rm|mkdir|ls|find|echo.*>|sed|awk|grep)(?:\\s+-[a-zA-Z0-9]+)*(?:\\s+[0-9]+)*\\s+([^\\s;|&]+)/);\n \n // If first match might be a flag, try a more specific pattern\n if (fileMatch && fileMatch[1]) {\n const possiblePath = fileMatch[1];\n // Check if it's actually a flag (starts with -)\n if (possiblePath.startsWith('-')) {\n // Try alternative pattern that skips all flags\n const altMatch = command.match(/(?:cat|less|more|head|tail|touch|mv|cp|rm|mkdir|ls|find|echo.*>|sed|awk|grep)(?:\\s+-[^\\s]+)*\\s+([^-][^\\s;|&]*)/);\n if (altMatch && altMatch[1]) {\n return altMatch[1];\n }\n }\n return possiblePath;\n }\n }\n\n return null;\n }\n\n /**\n * Extract file path from event pair\n * @param {Object} pair - Event pair object\n * @returns {string|null} - File path or null\n */\n extractFilePathFromPair(pair) {\n // Try pre_event first, then post_event\n let filePath = null;\n\n if (pair.pre_event) {\n filePath = this.extractFilePath(pair.pre_event);\n }\n\n if (!filePath && pair.post_event) {\n filePath = this.extractFilePath(pair.post_event);\n }\n\n return filePath;\n }\n\n /**\n * Get file operation type from event\n * @param {Object} event - Event to analyze\n * @returns {string} - Operation type\n */\n getFileOperation(event) {\n if (!event.tool_name) return 'unknown';\n\n const toolName = event.tool_name.toLowerCase();\n switch (toolName) {\n case 'read': return 'read';\n case 'write': return 'write';\n case 'edit': return 'edit';\n case 'multiedit': return 'edit';\n case 'notebookedit': return 'edit';\n case 'grep': return 'search';\n case 'glob': return 'search';\n case 'ls': return 'list';\n case 'bash':\n // Check bash command for file operation type\n const command = event.tool_parameters?.command || '';\n if (command.match(/\\b(cat|less|more|head|tail)\\b/)) return 'read';\n if (command.match(/\\b(touch|echo.*>|tee)\\b/)) return 'write';\n if (command.match(/\\b(sed|awk)\\b/)) return 'edit';\n if (command.match(/\\b(grep|find)\\b/)) return 'search';\n if (command.match(/\\b(ls|dir)\\b/)) return 'list';\n if (command.match(/\\b(mv|cp)\\b/)) return 'copy/move';\n if (command.match(/\\b(rm|rmdir)\\b/)) return 'delete';\n if (command.match(/\\b(mkdir)\\b/)) return 'create';\n return 'bash';\n default: return toolName;\n }\n }\n\n /**\n * Get file operation from event pair\n * @param {Object} pair - Event pair object\n * @returns {string} - Operation type\n */\n getFileOperationFromPair(pair) {\n // Try pre_event first, then post_event\n if (pair.pre_event) {\n return this.getFileOperation(pair.pre_event);\n }\n\n if (pair.post_event) {\n return this.getFileOperation(pair.post_event);\n }\n\n return 'unknown';\n }\n\n /**\n * Extract agent information from event pair\n * @param {Object} pair - Event pair object\n * @returns {Object} - Agent info with name and confidence\n */\n extractAgentFromPair(pair) {\n // Try to get agent info from inference system first\n const event = pair.pre_event || pair.post_event;\n if (event && this.agentInference) {\n const inference = this.agentInference.getInferredAgentForEvent(event);\n if (inference) {\n return {\n name: inference.agentName || 'Unknown',\n confidence: inference.confidence || 'unknown'\n };\n }\n }\n\n // Fallback to direct event properties\n const agentName = event?.agent_type || event?.subagent_type ||\n pair.pre_event?.agent_type || pair.post_event?.agent_type || 'PM';\n\n return {\n name: agentName,\n confidence: 'direct'\n };\n }\n\n /**\n * Get detailed operation information from event pair\n * @param {Object} pair - Event pair object\n * @returns {Object} - Operation details\n */\n getFileOperationDetailsFromPair(pair) {\n const details = {};\n\n // Extract details from pre_event (parameters)\n if (pair.pre_event) {\n const params = pair.pre_event.tool_parameters || pair.pre_event.data?.tool_parameters || {};\n details.parameters = params;\n details.tool_input = pair.pre_event.tool_input;\n }\n\n // Extract details from post_event (results)\n if (pair.post_event) {\n details.result = pair.post_event.result;\n details.success = pair.post_event.success;\n details.error = pair.post_event.error;\n details.exit_code = pair.post_event.exit_code;\n details.duration_ms = pair.post_event.duration_ms;\n }\n\n return details;\n }\n\n /**\n * Get file operations map\n * @returns {Map} - File operations map\n */\n getFileOperations() {\n return this.fileOperations;\n }\n\n /**\n * Get tool calls map\n * @returns {Map} - Tool calls map\n */\n getToolCalls() {\n return this.toolCalls;\n }\n\n /**\n * Get tool calls as array for unique instance view\n * Each entry represents a unique tool call instance\n * @returns {Array} - Array of [key, toolCall] pairs\n */\n getToolCallsArray() {\n return Array.from(this.toolCalls.entries());\n }\n\n /**\n * Get file operations for a specific file\n * @param {string} filePath - File path\n * @returns {Object|null} - File operations data or null\n */\n getFileOperationsForFile(filePath) {\n return this.fileOperations.get(filePath) || null;\n }\n\n /**\n * Get tool call by key\n * @param {string} key - Tool call key\n * @returns {Object|null} - Tool call data or null\n */\n getToolCall(key) {\n return this.toolCalls.get(key) || null;\n }\n\n /**\n * Clear all tracking data\n */\n clear() {\n this.fileOperations.clear();\n this.toolCalls.clear();\n console.log('File-tool tracker cleared');\n }\n\n /**\n * Get statistics about tracked operations\n * @returns {Object} - Statistics\n */\n getStatistics() {\n return {\n fileOperations: this.fileOperations.size,\n toolCalls: this.toolCalls.size,\n uniqueFiles: this.fileOperations.size,\n totalFileOperations: Array.from(this.fileOperations.values())\n .reduce((sum, data) => sum + data.operations.length, 0)\n };\n }\n\n /**\n * Compare tool parameters between pre_tool and post_tool events\n * to determine if they're likely from the same tool call\n * @param {Object} preEvent - Pre-tool event\n * @param {Object} postEvent - Post-tool event\n * @returns {boolean} - True if parameters suggest same tool call\n */\n compareToolParameters(preEvent, postEvent) {\n // Extract parameters from both events\n const preParams = preEvent.tool_parameters || preEvent.data?.tool_parameters || {};\n const postParams = postEvent.tool_parameters || postEvent.data?.tool_parameters || {};\n\n // If no parameters in either event, can't compare meaningfully\n if (Object.keys(preParams).length === 0 && Object.keys(postParams).length === 0) {\n return false; // No boost for empty parameters\n }\n\n // Compare key parameters that are likely to be the same\n const importantParams = ['file_path', 'path', 'pattern', 'command', 'notebook_path'];\n let matchedParams = 0;\n let totalComparableParams = 0;\n\n importantParams.forEach(param => {\n const preValue = preParams[param];\n const postValue = postParams[param];\n\n if (preValue !== undefined || postValue !== undefined) {\n totalComparableParams++;\n if (preValue === postValue) {\n matchedParams++;\n }\n }\n });\n\n // If we found comparable parameters, check if most match\n if (totalComparableParams > 0) {\n return (matchedParams / totalComparableParams) >= 0.8; // 80% parameter match threshold\n }\n\n // If no important parameters to compare, check if the parameter structure is similar\n const preKeys = Object.keys(preParams).sort();\n const postKeys = Object.keys(postParams).sort();\n\n if (preKeys.length === 0 && postKeys.length === 0) {\n return false;\n }\n\n // Simple structural similarity check\n if (preKeys.length === postKeys.length) {\n const keyMatches = preKeys.filter(key => postKeys.includes(key)).length;\n return keyMatches >= Math.max(1, preKeys.length * 0.5); // At least 50% key overlap\n }\n\n return false;\n }\n\n /**\n * Extract agent information from event using inference system\n * @param {Object} event - Event to extract agent from\n * @returns {Object} - Agent info with name and confidence\n */\n extractAgentFromEvent(event) {\n if (this.agentInference) {\n const inference = this.agentInference.getInferredAgentForEvent(event);\n if (inference) {\n return {\n name: inference.agentName || 'Unknown',\n confidence: inference.confidence || 'unknown'\n };\n }\n }\n\n // Fallback to direct event properties\n const agentName = event.agent_type || event.subagent_type ||\n event.data?.agent_type || event.data?.subagent_type || 'PM';\n\n return {\n name: agentName,\n confidence: 'direct'\n };\n }\n}\n// ES6 Module export\nexport { FileToolTracker };\nexport default FileToolTracker;\n\n// Make FileToolTracker globally available for dist/dashboard.js\nwindow.FileToolTracker = FileToolTracker;\n"],"names":["window","FileToolTracker","constructor","agentInference","workingDirectoryManager","this","fileOperations","Map","toolCalls","console","log","updateFileOperations","events","clear","length","eventPairs","fileOperationCount","forEach","event","index","isFileOp","isFileOperation","type","subtype","tool_name","tool_parameters","toolName","data","sessionId","session_id","eventKey","Math","floor","Date","timestamp","getTime","has","set","pre_event","post_event","pair","get","includes","size","key","filePath","extractFilePathFromPair","path","operations","lastOperation","fileData","operation","getFileOperationFromPair","agentInfo","extractAgentFromPair","workingDirectory","extractWorkingDirectoryFromPair","push","agent","name","confidence","details","getFileOperationDetailsFromPair","Array","from","entries","updateToolCalls","preToolEvents","postToolEvents","toolOperationCount","isToolOp","isToolOperation","toolCallPairs","usedPostEvents","Set","preEvent","preIndex","preTimestamp","pairKey","operation_type","duration_ms","success","exit_code","result_summary","agent_type","agent_confidence","extractAgentFromEvent","bestMatchIndex","bestMatchScore","postEvent","postIndex","postToolName","postSessionId","postTimestamp","timeDiff","abs","score","compareToolParameters","working_directory","add","keys","hasToolName","isValidEventType","isToolSubtype","toLowerCase","toolParams","command","match","extractFilePath","has_tool_parameters_top","has_tool_parameters_data","data_tool_parameters","file_path","notebook_path","pattern","fileMatch","possiblePath","startsWith","altMatch","getFileOperation","inference","getInferredAgentForEvent","agentName","subagent_type","params","parameters","tool_input","result","error","getFileOperations","getToolCalls","getToolCallsArray","getFileOperationsForFile","getToolCall","getStatistics","uniqueFiles","totalFileOperations","values","reduce","sum","preParams","postParams","Object","matchedParams","totalComparableParams","param","preValue","postValue","preKeys","sort","postKeys","filter","max"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- const e=new class{constructor(){this.modal=null,this.currentFile=null,this.initialized=!1,this.contentCache=new Map}initialize(){this.initialized||(this.createModal(),this.setupEventHandlers(),this.initialized=!0,console.log("File viewer initialized"))}createModal(){if(document.body.insertAdjacentHTML("beforeend",'\n <div class="file-viewer-modal" id="file-viewer-modal">\n <div class="file-viewer-content">\n <div class="file-viewer-header">\n <h2>📄 File Viewer</h2>\n <button class="file-viewer-close" id="file-viewer-close">×</button>\n </div>\n <div class="file-viewer-path" id="file-viewer-path">\n Loading...\n </div>\n <div class="file-viewer-body">\n <pre class="file-viewer-code" id="file-viewer-code">\n <code id="file-viewer-code-content">Loading file content...</code>\n </pre>\n </div>\n <div class="file-viewer-footer">\n <div class="file-viewer-info">\n <span id="file-viewer-type">Type: --</span>\n <span id="file-viewer-lines">Lines: --</span>\n <span id="file-viewer-size">Size: --</span>\n </div>\n <button class="file-viewer-copy" id="file-viewer-copy">📋 Copy</button>\n </div>\n </div>\n </div>\n '),this.modal=document.getElementById("file-viewer-modal"),!document.getElementById("file-viewer-styles")){const e="\n <style id=\"file-viewer-styles\">\n .file-viewer-modal {\n display: none;\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: rgba(0, 0, 0, 0.7);\n z-index: 10000;\n animation: fadeIn 0.2s;\n }\n\n .file-viewer-modal.show {\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .file-viewer-content {\n background: #1e1e1e;\n border-radius: 8px;\n width: 90%;\n max-width: 1200px;\n height: 80%;\n display: flex;\n flex-direction: column;\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);\n }\n\n .file-viewer-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 15px 20px;\n background: #2d2d30;\n border-radius: 8px 8px 0 0;\n border-bottom: 1px solid #3e3e42;\n }\n\n .file-viewer-header h2 {\n margin: 0;\n color: #cccccc;\n font-size: 18px;\n }\n\n .file-viewer-close {\n background: none;\n border: none;\n color: #999;\n font-size: 24px;\n cursor: pointer;\n padding: 0;\n width: 30px;\n height: 30px;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .file-viewer-close:hover {\n color: #fff;\n }\n\n .file-viewer-path {\n padding: 10px 20px;\n background: #252526;\n color: #8b8b8b;\n font-family: 'Consolas', 'Monaco', monospace;\n font-size: 12px;\n border-bottom: 1px solid #3e3e42;\n word-break: break-all;\n }\n\n .file-viewer-body {\n flex: 1;\n overflow: auto;\n padding: 20px;\n background: #1e1e1e;\n }\n\n .file-viewer-code {\n margin: 0;\n padding: 0;\n background: transparent;\n overflow: visible;\n }\n\n .file-viewer-code code {\n font-family: 'Consolas', 'Monaco', 'Courier New', monospace;\n font-size: 13px;\n line-height: 1.5;\n color: #d4d4d4;\n white-space: pre;\n display: block;\n }\n\n .file-viewer-footer {\n padding: 15px 20px;\n background: #2d2d30;\n border-top: 1px solid #3e3e42;\n display: flex;\n justify-content: space-between;\n align-items: center;\n border-radius: 0 0 8px 8px;\n }\n\n .file-viewer-info {\n display: flex;\n gap: 20px;\n color: #8b8b8b;\n font-size: 12px;\n }\n\n .file-viewer-copy {\n background: #0e639c;\n color: white;\n border: none;\n padding: 6px 12px;\n border-radius: 4px;\n cursor: pointer;\n font-size: 12px;\n }\n\n .file-viewer-copy:hover {\n background: #1177bb;\n }\n\n .file-viewer-copy.copied {\n background: #4ec9b0;\n }\n\n .file-viewer-error {\n color: #f48771;\n padding: 20px;\n text-align: center;\n }\n\n @keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n }\n </style>\n ";document.head.insertAdjacentHTML("beforeend",e)}}setupEventHandlers(){document.getElementById("file-viewer-close").addEventListener("click",()=>{this.hide()}),this.modal.addEventListener("click",e=>{e.target===this.modal&&this.hide()}),document.addEventListener("keydown",e=>{"Escape"===e.key&&this.modal.classList.contains("show")&&this.hide()}),document.getElementById("file-viewer-copy").addEventListener("click",()=>{this.copyContent()})}async show(e){console.log("[FileViewer] show() called with path:",e),console.log("[FileViewer] initialized:",this.initialized),this.initialized||(console.log("[FileViewer] Not initialized, initializing now..."),this.initialize()),this.currentFile=e,this.modal.classList.add("show"),document.getElementById("file-viewer-path").textContent=e,console.log("[FileViewer] Modal shown, loading file content..."),await this.loadFileContent(e)}hide(){this.modal.classList.remove("show"),this.currentFile=null}async loadFileContent(e){const n=document.getElementById("file-viewer-code-content");if(console.log("[FileViewer] loadFileContent called with path:",e),this.contentCache.has(e))return console.log("[FileViewer] Using cached content for:",e),void this.displayContent(this.contentCache.get(e));n.textContent="Loading file content...";try{if(!window.socket||!window.socket.connected)throw console.error("[FileViewer] No Socket.IO connection available"),new Error("No socket connection available. Please ensure the dashboard is connected to the monitoring server.");{console.log("[FileViewer] Using Socket.IO to load file:",e);const n=new Promise((n,i)=>{const t=setTimeout(()=>{console.error("[FileViewer] Socket.IO request timed out for:",e),i(new Error("Socket.IO request timed out"))},1e4);window.socket.once("file_content_response",e=>{clearTimeout(t),console.log("[FileViewer] Received file_content_response:",e),n(e)}),console.log("[FileViewer] Emitting read_file event with data:",{file_path:e,working_dir:window.workingDirectory||"/",max_size:5242880}),window.socket.emit("read_file",{file_path:e,working_dir:window.workingDirectory||"/",max_size:5242880})}),i=await n;if(!i.success||void 0===i.content)throw console.error("[FileViewer] Server returned error:",i.error),new Error(i.error||"Failed to load file content");console.log("[FileViewer] Successfully loaded file content, caching..."),this.contentCache.set(e,i.content),this.displayContent(i.content),this.updateFileInfo(i)}}catch(i){console.error("[FileViewer] Error loading file:",i),console.error("[FileViewer] Error stack:",i.stack),this.displayError(e,i.message)}}displayContent(e){const n=document.getElementById("file-viewer-code-content");n.textContent=e||"(Empty file)";const i=e?e.split("\n").length:0;document.getElementById("file-viewer-lines").textContent=`Lines: ${i}`;const t=e?new Blob([e]).size:0;document.getElementById("file-viewer-size").textContent=`Size: ${this.formatFileSize(t)}`;const o=this.detectFileType(this.currentFile);if(document.getElementById("file-viewer-type").textContent=`Type: ${o}`,window.Prism){const e=this.detectLanguage(this.currentFile);n.className=`language-${e}`,Prism.highlightElement(n)}}displayError(e,n){const i=`\n <div class="file-viewer-error">\n ⚠️ File content loading is not yet implemented\n \n File path: ${e}\n \n The file viewing functionality requires:\n 1. A server-side /api/file endpoint\n 2. Proper file reading permissions\n 3. Security validation for file access\n \n Error: ${n}\n \n This feature will be available once the backend API is implemented.\n </div>\n `;document.getElementById("file-viewer-code-content").innerHTML=i,document.getElementById("file-viewer-lines").textContent="Lines: --",document.getElementById("file-viewer-size").textContent="Size: --",document.getElementById("file-viewer-type").textContent="Type: --"}updateFileInfo(e){void 0!==e.lines&&(document.getElementById("file-viewer-lines").textContent=`Lines: ${e.lines}`),void 0!==e.size&&(document.getElementById("file-viewer-size").textContent=`Size: ${this.formatFileSize(e.size)}`),e.type&&(document.getElementById("file-viewer-type").textContent=`Type: ${e.type}`)}formatFileSize(e){if(0===e)return"0 Bytes";const n=Math.floor(Math.log(e)/Math.log(1024));return Math.round(e/Math.pow(1024,n)*100)/100+" "+["Bytes","KB","MB","GB"][n]}detectFileType(e){if(!e)return"Unknown";const n=e.split(".").pop()?.toLowerCase();return{py:"Python",js:"JavaScript",ts:"TypeScript",jsx:"React JSX",tsx:"React TSX",html:"HTML",css:"CSS",json:"JSON",xml:"XML",yaml:"YAML",yml:"YAML",md:"Markdown",txt:"Text",sh:"Shell Script",bash:"Bash Script",sql:"SQL",go:"Go",rs:"Rust",java:"Java",cpp:"C++",c:"C",cs:"C#",rb:"Ruby",php:"PHP"}[n]||"Text"}detectLanguage(e){if(!e)return"plaintext";const n=e.split(".").pop()?.toLowerCase();return{py:"python",js:"javascript",ts:"typescript",jsx:"jsx",tsx:"tsx",html:"html",css:"css",json:"json",xml:"xml",yaml:"yaml",yml:"yaml",md:"markdown",sh:"bash",bash:"bash",sql:"sql",go:"go",rs:"rust",java:"java",cpp:"cpp",c:"c",cs:"csharp",rb:"ruby",php:"php"}[n]||"plaintext"}async copyContent(){const e=document.getElementById("file-viewer-code-content"),n=document.getElementById("file-viewer-copy"),i=e.textContent;try{await navigator.clipboard.writeText(i);const e=n.textContent;n.textContent="✅ Copied!",n.classList.add("copied"),setTimeout(()=>{n.textContent=e,n.classList.remove("copied")},2e3)}catch(t){console.error("Failed to copy:",t),alert("Failed to copy content to clipboard")}}};window.showFileViewerModal||(window.showFileViewerModal=n=>{console.log("[FileViewer] showFileViewerModal called with path:",n),e.show(n)}),window.fileViewerInstance=e,"undefined"!=typeof window&&(window.FileViewer=e,"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{e.initialize()}):e.initialize());
2
- //# sourceMappingURL=file-viewer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"file-viewer.js","sources":["../../js/components/file-viewer.js"],"sourcesContent":["/**\n * File Viewer Component\n * \n * A simple file content viewer that displays file contents in a modal window.\n * This component handles file loading via HTTP requests and displays the content\n * with basic syntax highlighting support.\n */\n\nclass FileViewer {\n constructor() {\n this.modal = null;\n this.currentFile = null;\n this.initialized = false;\n this.contentCache = new Map();\n }\n\n /**\n * Initialize the file viewer\n */\n initialize() {\n if (this.initialized) {\n return;\n }\n\n this.createModal();\n this.setupEventHandlers();\n \n this.initialized = true;\n console.log('File viewer initialized');\n }\n\n /**\n * Create modal DOM structure\n */\n createModal() {\n const modalHtml = `\n <div class=\"file-viewer-modal\" id=\"file-viewer-modal\">\n <div class=\"file-viewer-content\">\n <div class=\"file-viewer-header\">\n <h2>📄 File Viewer</h2>\n <button class=\"file-viewer-close\" id=\"file-viewer-close\">×</button>\n </div>\n <div class=\"file-viewer-path\" id=\"file-viewer-path\">\n Loading...\n </div>\n <div class=\"file-viewer-body\">\n <pre class=\"file-viewer-code\" id=\"file-viewer-code\">\n <code id=\"file-viewer-code-content\">Loading file content...</code>\n </pre>\n </div>\n <div class=\"file-viewer-footer\">\n <div class=\"file-viewer-info\">\n <span id=\"file-viewer-type\">Type: --</span>\n <span id=\"file-viewer-lines\">Lines: --</span>\n <span id=\"file-viewer-size\">Size: --</span>\n </div>\n <button class=\"file-viewer-copy\" id=\"file-viewer-copy\">📋 Copy</button>\n </div>\n </div>\n </div>\n `;\n\n // Add modal to body\n document.body.insertAdjacentHTML('beforeend', modalHtml);\n this.modal = document.getElementById('file-viewer-modal');\n\n // Add styles if not already present\n if (!document.getElementById('file-viewer-styles')) {\n const styles = `\n <style id=\"file-viewer-styles\">\n .file-viewer-modal {\n display: none;\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: rgba(0, 0, 0, 0.7);\n z-index: 10000;\n animation: fadeIn 0.2s;\n }\n\n .file-viewer-modal.show {\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .file-viewer-content {\n background: #1e1e1e;\n border-radius: 8px;\n width: 90%;\n max-width: 1200px;\n height: 80%;\n display: flex;\n flex-direction: column;\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);\n }\n\n .file-viewer-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 15px 20px;\n background: #2d2d30;\n border-radius: 8px 8px 0 0;\n border-bottom: 1px solid #3e3e42;\n }\n\n .file-viewer-header h2 {\n margin: 0;\n color: #cccccc;\n font-size: 18px;\n }\n\n .file-viewer-close {\n background: none;\n border: none;\n color: #999;\n font-size: 24px;\n cursor: pointer;\n padding: 0;\n width: 30px;\n height: 30px;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .file-viewer-close:hover {\n color: #fff;\n }\n\n .file-viewer-path {\n padding: 10px 20px;\n background: #252526;\n color: #8b8b8b;\n font-family: 'Consolas', 'Monaco', monospace;\n font-size: 12px;\n border-bottom: 1px solid #3e3e42;\n word-break: break-all;\n }\n\n .file-viewer-body {\n flex: 1;\n overflow: auto;\n padding: 20px;\n background: #1e1e1e;\n }\n\n .file-viewer-code {\n margin: 0;\n padding: 0;\n background: transparent;\n overflow: visible;\n }\n\n .file-viewer-code code {\n font-family: 'Consolas', 'Monaco', 'Courier New', monospace;\n font-size: 13px;\n line-height: 1.5;\n color: #d4d4d4;\n white-space: pre;\n display: block;\n }\n\n .file-viewer-footer {\n padding: 15px 20px;\n background: #2d2d30;\n border-top: 1px solid #3e3e42;\n display: flex;\n justify-content: space-between;\n align-items: center;\n border-radius: 0 0 8px 8px;\n }\n\n .file-viewer-info {\n display: flex;\n gap: 20px;\n color: #8b8b8b;\n font-size: 12px;\n }\n\n .file-viewer-copy {\n background: #0e639c;\n color: white;\n border: none;\n padding: 6px 12px;\n border-radius: 4px;\n cursor: pointer;\n font-size: 12px;\n }\n\n .file-viewer-copy:hover {\n background: #1177bb;\n }\n\n .file-viewer-copy.copied {\n background: #4ec9b0;\n }\n\n .file-viewer-error {\n color: #f48771;\n padding: 20px;\n text-align: center;\n }\n\n @keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n }\n </style>\n `;\n document.head.insertAdjacentHTML('beforeend', styles);\n }\n }\n\n /**\n * Setup event handlers\n */\n setupEventHandlers() {\n // Close button\n document.getElementById('file-viewer-close').addEventListener('click', () => {\n this.hide();\n });\n\n // Close on backdrop click\n this.modal.addEventListener('click', (e) => {\n if (e.target === this.modal) {\n this.hide();\n }\n });\n\n // Close on ESC key\n document.addEventListener('keydown', (e) => {\n if (e.key === 'Escape' && this.modal.classList.contains('show')) {\n this.hide();\n }\n });\n\n // Copy button\n document.getElementById('file-viewer-copy').addEventListener('click', () => {\n this.copyContent();\n });\n }\n\n /**\n * Show the file viewer with file content\n */\n async show(filePath) {\n console.log('[FileViewer] show() called with path:', filePath);\n console.log('[FileViewer] initialized:', this.initialized);\n \n if (!this.initialized) {\n console.log('[FileViewer] Not initialized, initializing now...');\n this.initialize();\n }\n\n this.currentFile = filePath;\n this.modal.classList.add('show');\n \n // Update path\n document.getElementById('file-viewer-path').textContent = filePath;\n \n console.log('[FileViewer] Modal shown, loading file content...');\n // Load file content\n await this.loadFileContent(filePath);\n }\n\n /**\n * Hide the file viewer\n */\n hide() {\n this.modal.classList.remove('show');\n this.currentFile = null;\n }\n\n /**\n * Load file content\n */\n async loadFileContent(filePath) {\n const codeContent = document.getElementById('file-viewer-code-content');\n \n console.log('[FileViewer] loadFileContent called with path:', filePath);\n \n // Check cache first\n if (this.contentCache.has(filePath)) {\n console.log('[FileViewer] Using cached content for:', filePath);\n this.displayContent(this.contentCache.get(filePath));\n return;\n }\n \n // Show loading state\n codeContent.textContent = 'Loading file content...';\n \n try {\n // Check if we have a socket connection available\n if (window.socket && window.socket.connected) {\n console.log('[FileViewer] Using Socket.IO to load file:', filePath);\n \n // Create a promise to wait for the response\n const responsePromise = new Promise((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n console.error('[FileViewer] Socket.IO request timed out for:', filePath);\n reject(new Error('Socket.IO request timed out'));\n }, 10000); // 10 second timeout\n \n // Set up one-time listener for the response\n window.socket.once('file_content_response', (data) => {\n clearTimeout(timeoutId);\n console.log('[FileViewer] Received file_content_response:', data);\n resolve(data);\n });\n \n // Emit the read_file event\n console.log('[FileViewer] Emitting read_file event with data:', {\n file_path: filePath,\n working_dir: window.workingDirectory || '/',\n max_size: 5 * 1024 * 1024 // 5MB limit\n });\n \n window.socket.emit('read_file', {\n file_path: filePath,\n working_dir: window.workingDirectory || '/',\n max_size: 5 * 1024 * 1024 // 5MB limit\n });\n });\n \n // Wait for the response\n const data = await responsePromise;\n \n if (data.success && data.content !== undefined) {\n console.log('[FileViewer] Successfully loaded file content, caching...');\n // Cache the content\n this.contentCache.set(filePath, data.content);\n \n // Display the content\n this.displayContent(data.content);\n \n // Update file info\n this.updateFileInfo(data);\n } else {\n console.error('[FileViewer] Server returned error:', data.error);\n throw new Error(data.error || 'Failed to load file content');\n }\n } else {\n console.error('[FileViewer] No Socket.IO connection available');\n throw new Error('No socket connection available. Please ensure the dashboard is connected to the monitoring server.');\n }\n } catch (error) {\n console.error('[FileViewer] Error loading file:', error);\n console.error('[FileViewer] Error stack:', error.stack);\n \n // If API fails, show error message with helpful information\n this.displayError(filePath, error.message);\n }\n }\n\n /**\n * Display file content\n */\n displayContent(content) {\n const codeContent = document.getElementById('file-viewer-code-content');\n \n // Set the content\n codeContent.textContent = content || '(Empty file)';\n \n // Update line count\n const lines = content ? content.split('\\n').length : 0;\n document.getElementById('file-viewer-lines').textContent = `Lines: ${lines}`;\n \n // Update file size\n const size = content ? new Blob([content]).size : 0;\n document.getElementById('file-viewer-size').textContent = `Size: ${this.formatFileSize(size)}`;\n \n // Detect and set file type\n const fileType = this.detectFileType(this.currentFile);\n document.getElementById('file-viewer-type').textContent = `Type: ${fileType}`;\n \n // Apply syntax highlighting if Prism is available\n if (window.Prism) {\n const language = this.detectLanguage(this.currentFile);\n codeContent.className = `language-${language}`;\n Prism.highlightElement(codeContent);\n }\n }\n\n /**\n * Display error message\n */\n displayError(filePath, errorMessage) {\n const codeContent = document.getElementById('file-viewer-code-content');\n \n // For now, show a helpful message since the API endpoint doesn't exist yet\n const errorHtml = `\n <div class=\"file-viewer-error\">\n ⚠️ File content loading is not yet implemented\n \n File path: ${filePath}\n \n The file viewing functionality requires:\n 1. A server-side /api/file endpoint\n 2. Proper file reading permissions\n 3. Security validation for file access\n \n Error: ${errorMessage}\n \n This feature will be available once the backend API is implemented.\n </div>\n `;\n \n codeContent.innerHTML = errorHtml;\n \n // Update info\n document.getElementById('file-viewer-lines').textContent = 'Lines: --';\n document.getElementById('file-viewer-size').textContent = 'Size: --';\n document.getElementById('file-viewer-type').textContent = 'Type: --';\n }\n\n /**\n * Update file info\n */\n updateFileInfo(data) {\n if (data.lines !== undefined) {\n document.getElementById('file-viewer-lines').textContent = `Lines: ${data.lines}`;\n }\n \n if (data.size !== undefined) {\n document.getElementById('file-viewer-size').textContent = `Size: ${this.formatFileSize(data.size)}`;\n }\n \n if (data.type) {\n document.getElementById('file-viewer-type').textContent = `Type: ${data.type}`;\n }\n }\n\n /**\n * Format file size for display\n */\n formatFileSize(bytes) {\n if (bytes === 0) return '0 Bytes';\n \n const k = 1024;\n const sizes = ['Bytes', 'KB', 'MB', 'GB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n \n return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i];\n }\n\n /**\n * Detect file type from path\n */\n detectFileType(path) {\n if (!path) return 'Unknown';\n \n const ext = path.split('.').pop()?.toLowerCase();\n const typeMap = {\n 'py': 'Python',\n 'js': 'JavaScript',\n 'ts': 'TypeScript',\n 'jsx': 'React JSX',\n 'tsx': 'React TSX',\n 'html': 'HTML',\n 'css': 'CSS',\n 'json': 'JSON',\n 'xml': 'XML',\n 'yaml': 'YAML',\n 'yml': 'YAML',\n 'md': 'Markdown',\n 'txt': 'Text',\n 'sh': 'Shell Script',\n 'bash': 'Bash Script',\n 'sql': 'SQL',\n 'go': 'Go',\n 'rs': 'Rust',\n 'java': 'Java',\n 'cpp': 'C++',\n 'c': 'C',\n 'cs': 'C#',\n 'rb': 'Ruby',\n 'php': 'PHP'\n };\n \n return typeMap[ext] || 'Text';\n }\n\n /**\n * Detect language for syntax highlighting\n */\n detectLanguage(path) {\n if (!path) return 'plaintext';\n \n const ext = path.split('.').pop()?.toLowerCase();\n const languageMap = {\n 'py': 'python',\n 'js': 'javascript',\n 'ts': 'typescript',\n 'jsx': 'jsx',\n 'tsx': 'tsx',\n 'html': 'html',\n 'css': 'css',\n 'json': 'json',\n 'xml': 'xml',\n 'yaml': 'yaml',\n 'yml': 'yaml',\n 'md': 'markdown',\n 'sh': 'bash',\n 'bash': 'bash',\n 'sql': 'sql',\n 'go': 'go',\n 'rs': 'rust',\n 'java': 'java',\n 'cpp': 'cpp',\n 'c': 'c',\n 'cs': 'csharp',\n 'rb': 'ruby',\n 'php': 'php'\n };\n \n return languageMap[ext] || 'plaintext';\n }\n\n /**\n * Copy file content to clipboard\n */\n async copyContent() {\n const codeContent = document.getElementById('file-viewer-code-content');\n const button = document.getElementById('file-viewer-copy');\n const content = codeContent.textContent;\n \n try {\n await navigator.clipboard.writeText(content);\n \n // Show feedback\n const originalText = button.textContent;\n button.textContent = '✅ Copied!';\n button.classList.add('copied');\n \n setTimeout(() => {\n button.textContent = originalText;\n button.classList.remove('copied');\n }, 2000);\n } catch (err) {\n console.error('Failed to copy:', err);\n alert('Failed to copy content to clipboard');\n }\n }\n}\n\n// Create singleton instance\nconst fileViewer = new FileViewer();\n\n// Create global function for easy access\n// Only set if not already defined by dashboard.js\nif (!window.showFileViewerModal) {\n window.showFileViewerModal = (filePath) => {\n console.log('[FileViewer] showFileViewerModal called with path:', filePath);\n fileViewer.show(filePath);\n };\n}\n\n// Expose the singleton for debugging\nwindow.fileViewerInstance = fileViewer;\n\n// Export for use in other modules\nif (typeof window !== 'undefined') {\n window.FileViewer = fileViewer;\n \n // Initialize when DOM is ready\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', () => {\n fileViewer.initialize();\n });\n } else {\n // DOM is already loaded\n fileViewer.initialize();\n }\n}\n\nexport default fileViewer;"],"names":["fileViewer","constructor","this","modal","currentFile","initialized","contentCache","Map","initialize","createModal","setupEventHandlers","console","log","document","body","insertAdjacentHTML","getElementById","styles","head","addEventListener","hide","e","target","key","classList","contains","copyContent","show","filePath","add","textContent","loadFileContent","remove","codeContent","has","displayContent","get","window","socket","connected","error","Error","responsePromise","Promise","resolve","reject","timeoutId","setTimeout","once","data","clearTimeout","file_path","working_dir","workingDirectory","max_size","emit","success","content","set","updateFileInfo","stack","displayError","message","lines","split","length","size","Blob","formatFileSize","fileType","detectFileType","Prism","language","detectLanguage","className","highlightElement","errorMessage","errorHtml","innerHTML","type","bytes","i","Math","floor","round","pow","path","ext","pop","toLowerCase","py","js","ts","jsx","tsx","html","css","json","xml","yaml","yml","md","txt","sh","bash","sql","go","rs","java","cpp","c","cs","rb","php","button","navigator","clipboard","writeText","originalText","err","alert","showFileViewerModal","fileViewerInstance","FileViewer","readyState"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- window.HUDLibraryLoader=new class{constructor(){this.loadedLibraries=new Set,this.loadingPromises=new Map,this.loadingCallbacks=new Map,this.libraries=[{name:"cytoscape",url:"https://unpkg.com/cytoscape@3.26.0/dist/cytoscape.min.js",globalCheck:()=>void 0!==window.cytoscape,dependencies:[]},{name:"dagre",url:"https://unpkg.com/dagre@0.8.5/dist/dagre.min.js",globalCheck:()=>void 0!==window.dagre,dependencies:[]},{name:"cytoscape-dagre",url:"https://unpkg.com/cytoscape-dagre@2.5.0/cytoscape-dagre.js",globalCheck:()=>void 0!==window.cytoscapeDagre,dependencies:["cytoscape","dagre"]}]}loadLibrary(e){if(e.globalCheck())return this.loadedLibraries.add(e.name),Promise.resolve();if(this.loadingPromises.has(e.name))return this.loadingPromises.get(e.name);console.log(`Loading library: ${e.name} from ${e.url}`);const r=new Promise((r,a)=>{const i=document.createElement("script");i.src=e.url,i.async=!0,i.onload=()=>{if(e.globalCheck())console.log(`Successfully loaded library: ${e.name}`),this.loadedLibraries.add(e.name),this.loadingPromises.delete(e.name),r();else{const r=new Error(`Library ${e.name} failed global check after loading`);console.error(r),this.loadingPromises.delete(e.name),a(r)}},i.onerror=()=>{const r=new Error(`Failed to load library: ${e.name} from ${e.url}`);console.error(r),this.loadingPromises.delete(e.name),a(r)},document.head.appendChild(i)});return this.loadingPromises.set(e.name,r),r}async loadDependencies(e){const r=e.map(e=>{const r=this.libraries.find(r=>r.name===e);if(!r)throw new Error(`Dependency ${e} not found in library configuration`);return this.loadLibraryWithDependencies(r)});return Promise.all(r)}async loadLibraryWithDependencies(e){return e.dependencies.length>0&&await this.loadDependencies(e.dependencies),this.loadLibrary(e)}async loadHUDLibraries(e=null){console.log("Starting HUD libraries loading...");try{for(let a=0;a<this.libraries.length;a++){const r=this.libraries[a];e&&e({library:r.name,current:a+1,total:this.libraries.length,message:`Loading ${r.name}...`}),await this.loadLibraryWithDependencies(r)}const r=this.libraries.filter(e=>!e.globalCheck());if(r.length>0)throw new Error(`Failed to load libraries: ${r.map(e=>e.name).join(", ")}`);return console.log("All HUD libraries loaded successfully"),e&&e({library:"complete",current:this.libraries.length,total:this.libraries.length,message:"All libraries loaded successfully"}),!0}catch(r){throw console.error("Failed to load HUD libraries:",r),e&&e({library:"error",current:0,total:this.libraries.length,message:`Error: ${r.message}`,error:r}),r}}areLibrariesLoaded(){return this.libraries.every(e=>e.globalCheck())}getLoadingStatus(){return{loaded:Array.from(this.loadedLibraries),loading:Array.from(this.loadingPromises.keys()),total:this.libraries.length,allLoaded:this.areLibrariesLoaded()}}reset(){this.loadedLibraries.clear(),this.loadingPromises.clear(),this.loadingCallbacks.clear()}};
2
- //# sourceMappingURL=hud-library-loader.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"hud-library-loader.js","sources":["../../js/components/hud-library-loader.js"],"sourcesContent":["/**\n * HUD Library Loader\n * Handles lazy loading of Cytoscape.js and its dependencies with proper loading order\n */\n\nclass HUDLibraryLoader {\n constructor() {\n this.loadedLibraries = new Set();\n this.loadingPromises = new Map();\n this.loadingCallbacks = new Map();\n\n // Define library configurations with proper loading order\n this.libraries = [\n {\n name: 'cytoscape',\n url: 'https://unpkg.com/cytoscape@3.26.0/dist/cytoscape.min.js',\n globalCheck: () => typeof window.cytoscape !== 'undefined',\n dependencies: []\n },\n {\n name: 'dagre',\n url: 'https://unpkg.com/dagre@0.8.5/dist/dagre.min.js',\n globalCheck: () => typeof window.dagre !== 'undefined',\n dependencies: []\n },\n {\n name: 'cytoscape-dagre',\n url: 'https://unpkg.com/cytoscape-dagre@2.5.0/cytoscape-dagre.js',\n globalCheck: () => typeof window.cytoscapeDagre !== 'undefined',\n dependencies: ['cytoscape', 'dagre']\n }\n ];\n }\n\n /**\n * Load a single library via script tag\n * @param {Object} library - Library configuration object\n * @returns {Promise} - Promise that resolves when library is loaded\n */\n loadLibrary(library) {\n // Check if already loaded\n if (library.globalCheck()) {\n this.loadedLibraries.add(library.name);\n return Promise.resolve();\n }\n\n // Check if already loading\n if (this.loadingPromises.has(library.name)) {\n return this.loadingPromises.get(library.name);\n }\n\n console.log(`Loading library: ${library.name} from ${library.url}`);\n\n const promise = new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.src = library.url;\n script.async = true;\n\n script.onload = () => {\n if (library.globalCheck()) {\n console.log(`Successfully loaded library: ${library.name}`);\n this.loadedLibraries.add(library.name);\n this.loadingPromises.delete(library.name);\n resolve();\n } else {\n const error = new Error(`Library ${library.name} failed global check after loading`);\n console.error(error);\n this.loadingPromises.delete(library.name);\n reject(error);\n }\n };\n\n script.onerror = () => {\n const error = new Error(`Failed to load library: ${library.name} from ${library.url}`);\n console.error(error);\n this.loadingPromises.delete(library.name);\n reject(error);\n };\n\n document.head.appendChild(script);\n });\n\n this.loadingPromises.set(library.name, promise);\n return promise;\n }\n\n /**\n * Load dependencies for a library\n * @param {Array} dependencies - Array of dependency names\n * @returns {Promise} - Promise that resolves when all dependencies are loaded\n */\n async loadDependencies(dependencies) {\n const dependencyPromises = dependencies.map(depName => {\n const depLibrary = this.libraries.find(lib => lib.name === depName);\n if (!depLibrary) {\n throw new Error(`Dependency ${depName} not found in library configuration`);\n }\n return this.loadLibraryWithDependencies(depLibrary);\n });\n\n return Promise.all(dependencyPromises);\n }\n\n /**\n * Load a library and all its dependencies\n * @param {Object} library - Library configuration object\n * @returns {Promise} - Promise that resolves when library and dependencies are loaded\n */\n async loadLibraryWithDependencies(library) {\n // Load dependencies first\n if (library.dependencies.length > 0) {\n await this.loadDependencies(library.dependencies);\n }\n\n // Then load the library itself\n return this.loadLibrary(library);\n }\n\n /**\n * Load all HUD visualization libraries in correct order\n * @param {Function} onProgress - Optional progress callback\n * @returns {Promise} - Promise that resolves when all libraries are loaded\n */\n async loadHUDLibraries(onProgress = null) {\n console.log('Starting HUD libraries loading...');\n\n try {\n // Load libraries in dependency order\n for (let i = 0; i < this.libraries.length; i++) {\n const library = this.libraries[i];\n\n if (onProgress) {\n onProgress({\n library: library.name,\n current: i + 1,\n total: this.libraries.length,\n message: `Loading ${library.name}...`\n });\n }\n\n await this.loadLibraryWithDependencies(library);\n }\n\n // Verify all libraries are loaded\n const missingLibraries = this.libraries.filter(lib => !lib.globalCheck());\n if (missingLibraries.length > 0) {\n throw new Error(`Failed to load libraries: ${missingLibraries.map(lib => lib.name).join(', ')}`);\n }\n\n console.log('All HUD libraries loaded successfully');\n\n if (onProgress) {\n onProgress({\n library: 'complete',\n current: this.libraries.length,\n total: this.libraries.length,\n message: 'All libraries loaded successfully'\n });\n }\n\n return true;\n } catch (error) {\n console.error('Failed to load HUD libraries:', error);\n\n if (onProgress) {\n onProgress({\n library: 'error',\n current: 0,\n total: this.libraries.length,\n message: `Error: ${error.message}`,\n error: error\n });\n }\n\n throw error;\n }\n }\n\n /**\n * Check if all HUD libraries are loaded\n * @returns {boolean} - True if all libraries are loaded\n */\n areLibrariesLoaded() {\n return this.libraries.every(lib => lib.globalCheck());\n }\n\n /**\n * Get loading status for all libraries\n * @returns {Object} - Status object with library loading states\n */\n getLoadingStatus() {\n return {\n loaded: Array.from(this.loadedLibraries),\n loading: Array.from(this.loadingPromises.keys()),\n total: this.libraries.length,\n allLoaded: this.areLibrariesLoaded()\n };\n }\n\n /**\n * Reset loader state (for testing purposes)\n */\n reset() {\n this.loadedLibraries.clear();\n this.loadingPromises.clear();\n this.loadingCallbacks.clear();\n }\n}\n\n// Create singleton instance\nwindow.HUDLibraryLoader = new HUDLibraryLoader();\n"],"names":["window","HUDLibraryLoader","constructor","this","loadedLibraries","Set","loadingPromises","Map","loadingCallbacks","libraries","name","url","globalCheck","cytoscape","dependencies","dagre","cytoscapeDagre","loadLibrary","library","add","Promise","resolve","has","get","console","log","promise","reject","script","document","createElement","src","async","onload","delete","error","Error","onerror","head","appendChild","set","loadDependencies","dependencyPromises","map","depName","depLibrary","find","lib","loadLibraryWithDependencies","all","length","loadHUDLibraries","onProgress","i","current","total","message","missingLibraries","filter","join","areLibrariesLoaded","every","getLoadingStatus","loaded","Array","from","loading","keys","allLoaded","reset","clear"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- window.HUDVisualizer=class{constructor(){this.cy=null,this.container=null,this.nodes=new Map,this.isActive=!1,this.librariesLoaded=!1,this.loadingPromise=null,this.pendingEvents=[],this.layoutConfig={name:"dagre",rankDir:"TB",animate:!0,animationDuration:500,fit:!0,padding:30,rankSep:100,nodeSep:80},this.nodeTypes={PM:{color:"#48bb78",shape:"rectangle",width:120,height:40,icon:"👤"},AGENT:{color:"#9f7aea",shape:"ellipse",width:100,height:60,icon:"🤖"},TOOL:{color:"#4299e1",shape:"diamond",width:80,height:50,icon:"🔧"},TODO:{color:"#e53e3e",shape:"triangle",width:70,height:40,icon:"📝"}}}initialize(){return this.container=document.getElementById("hud-cytoscape"),this.container?(this.container.style.pointerEvents="auto",this.container.style.cursor="default",this.container.style.position="relative",this.container.style.zIndex="1",this.setupBasicEventHandlers(),console.log("HUD Visualizer initialized (libraries will load lazily)"),!0):(console.error("HUD container not found"),!1)}async loadLibrariesAndInitialize(){return this.librariesLoaded&&this.cy?Promise.resolve():(this.loadingPromise||(this.loadingPromise=this._performLazyLoading()),this.loadingPromise)}async _performLazyLoading(){try{if(console.log("[HUD-VISUALIZER-DEBUG] _performLazyLoading() called"),console.log("[HUD-VISUALIZER-DEBUG] Loading HUD visualization libraries..."),this.showLoadingIndicator(),!window.HUDLibraryLoader)throw new Error("HUD Library Loader not available");if(console.log("[HUD-VISUALIZER-DEBUG] HUD Library Loader found, loading libraries..."),await window.HUDLibraryLoader.loadHUDLibraries(e=>{console.log("[HUD-VISUALIZER-DEBUG] Loading progress:",e),this.updateLoadingProgress(e)}),console.log("[HUD-VISUALIZER-DEBUG] Verifying libraries are loaded..."),void 0===window.cytoscape)throw new Error("Cytoscape.js not loaded");if(void 0===window.dagre)throw new Error("Dagre not loaded");if(void 0===window.cytoscapeDagre)throw new Error("Cytoscape-dagre not loaded");return console.log("[HUD-VISUALIZER-DEBUG] All HUD libraries loaded successfully"),this.librariesLoaded=!0,console.log("[HUD-VISUALIZER-DEBUG] Initializing Cytoscape..."),this.initializeCytoscape(),console.log("[HUD-VISUALIZER-DEBUG] Setting up Cytoscape event handlers..."),this.setupCytoscapeEventHandlers(),console.log("[HUD-VISUALIZER-DEBUG] Processing pending events..."),this.processPendingEvents(),this.hideLoadingIndicator(),console.log("[HUD-VISUALIZER-DEBUG] HUD Visualizer fully initialized with lazy loading"),!0}catch(e){throw console.error("[HUD-VISUALIZER-DEBUG] Failed to load HUD libraries:",e),console.error("[HUD-VISUALIZER-DEBUG] Error stack:",e.stack),this.showLoadingError(e.message),this.librariesLoaded=!1,this.loadingPromise=null,e}}initializeCytoscape(){this.librariesLoaded&&window.cytoscape?(void 0!==window.cytoscape&&void 0!==window.cytoscapeDagre&&window.cytoscape.use(window.cytoscapeDagre),this.cy=window.cytoscape({container:this.container,elements:[],userZoomingEnabled:!0,userPanningEnabled:!0,boxSelectionEnabled:!1,autoungrabify:!1,autounselectify:!1,style:[{selector:"node",style:{"background-color":"data(color)","border-color":"data(borderColor)","border-width":2,color:"#ffffff",label:"data(label)","text-valign":"center","text-halign":"center","font-size":"12px","font-weight":"bold",width:"data(width)",height:"data(height)",shape:"data(shape)","text-wrap":"wrap","text-max-width":"100px"}},{selector:"edge",style:{width:2,"line-color":"#718096","target-arrow-color":"#718096","target-arrow-shape":"triangle","curve-style":"bezier","arrow-scale":1.2}},{selector:".pm-node",style:{"background-color":"#48bb78","border-color":"#38a169",shape:"rectangle"}},{selector:".agent-node",style:{"background-color":"#9f7aea","border-color":"#805ad5",shape:"ellipse"}},{selector:".tool-node",style:{"background-color":"#4299e1","border-color":"#3182ce",shape:"diamond"}},{selector:".todo-node",style:{"background-color":"#e53e3e","border-color":"#c53030",shape:"triangle"}},{selector:"node:active",style:{"overlay-opacity":.2,"overlay-color":"#000000"}}],layout:this.layoutConfig}),this.setupResizeHandler()):console.error("Cannot initialize Cytoscape: libraries not loaded")}setupBasicEventHandlers(){const e=document.getElementById("hud-reset-layout");e&&e.addEventListener("click",()=>{this.resetLayout()});const t=document.getElementById("hud-center-view");t&&t.addEventListener("click",()=>{this.centerView()})}setupCytoscapeEventHandlers(){this.cy?(console.log("[HUD-VISUALIZER-DEBUG] Setting up Cytoscape event handlers..."),this.cy.on("tap","node",e=>{const t=e.target,o=t.data();console.log("[HUD-VISUALIZER-DEBUG] Node clicked:",o),this.highlightConnectedNodes(t)}),this.cy.on("tap",e=>{e.target===this.cy&&(console.log("[HUD-VISUALIZER-DEBUG] Background clicked - resetting highlights"),this.cy.nodes().style({opacity:1}),this.cy.edges().style({opacity:1}))}),this.cy.on("mouseover","node",e=>{e.target.style("opacity",.8)}),this.cy.on("mouseout","node",e=>{e.target.style("opacity",1)}),console.log("[HUD-VISUALIZER-DEBUG] Cytoscape event handlers set up successfully")):console.warn("[HUD-VISUALIZER-DEBUG] Cannot setup Cytoscape event handlers: no cy instance")}setupResizeHandler(){const e=new ResizeObserver(()=>{this.cy&&this.isActive&&this.ensureContainerResize()});this.container&&e.observe(this.container)}ensureContainerResize(){if(!this.cy||!this.container)return void console.log("[HUD-VISUALIZER-DEBUG] Cannot resize: missing cy or container");this.ensureContainerInteractivity();const e=this.container.getBoundingClientRect();if(console.log("[HUD-VISUALIZER-DEBUG] Container dimensions:",{width:e.width,height:e.height,offsetWidth:this.container.offsetWidth,offsetHeight:this.container.offsetHeight,isVisible:e.width>0&&e.height>0}),e.width>0&&e.height>0){console.log("[HUD-VISUALIZER-DEBUG] Container is visible, resizing Cytoscape...");try{this.cy.resize();const e=this.cy.nodes().length,t=this.cy.edges().length;console.log("[HUD-VISUALIZER-DEBUG] Cytoscape elements after resize:",{nodes:e,edges:t}),e>0?(console.log("[HUD-VISUALIZER-DEBUG] Running fit and layout..."),this.cy.fit(),this.runLayout()):console.log("[HUD-VISUALIZER-DEBUG] No nodes to display")}catch(t){console.error("[HUD-VISUALIZER-DEBUG] Error during resize:",t)}}else console.log("[HUD-VISUALIZER-DEBUG] Container not visible yet, skipping resize")}ensureContainerInteractivity(){if(!this.container)return;this.container.style.pointerEvents="auto",this.container.style.cursor="default",this.container.style.userSelect="none",this.container.style.touchAction="manipulation";const e=this.container.parentElement;e&&(e.style.pointerEvents="auto",e.style.position="relative"),console.log("[HUD-VISUALIZER-DEBUG] Container interactivity ensured")}async activate(){console.log("[HUD-VISUALIZER-DEBUG] activate() called"),this.isActive=!0;try{console.log("[HUD-VISUALIZER-DEBUG] Loading libraries and initializing..."),await this.loadLibrariesAndInitialize(),console.log("[HUD-VISUALIZER-DEBUG] Libraries loaded, cy exists:",!!this.cy),this.cy||(console.log("[HUD-VISUALIZER-DEBUG] Cytoscape instance missing, recreating..."),this.initializeCytoscape(),this.setupCytoscapeEventHandlers()),this.cy&&(console.log("[HUD-VISUALIZER-DEBUG] Triggering resize and fit..."),setTimeout(()=>{console.log("[HUD-VISUALIZER-DEBUG] First resize attempt..."),this.ensureContainerResize()},50),setTimeout(()=>{console.log("[HUD-VISUALIZER-DEBUG] Second resize attempt..."),this.ensureContainerResize()},200),setTimeout(()=>{console.log("[HUD-VISUALIZER-DEBUG] Final resize attempt..."),this.ensureContainerResize()},500)),console.log("[HUD-VISUALIZER-DEBUG] activate() completed successfully")}catch(e){throw console.error("[HUD-VISUALIZER-DEBUG] Failed to activate HUD:",e),console.error("[HUD-VISUALIZER-DEBUG] Error stack:",e.stack),e}}deactivate(){this.isActive=!1}processPendingEvents(){if(this.pendingEvents.length>0){console.log(`Processing ${this.pendingEvents.length} pending events`);for(const e of this.pendingEvents)this._processEventInternal(e);this.pendingEvents=[]}}processExistingEvents(e){if(console.log(`[HUD-VISUALIZER-DEBUG] processExistingEvents called with ${e?e.length:0} events`),!e)return void console.error("[HUD-VISUALIZER-DEBUG] No events provided to processExistingEvents");if(!Array.isArray(e))return void console.error("[HUD-VISUALIZER-DEBUG] Events is not an array:",typeof e);if(console.log(`[HUD-VISUALIZER-DEBUG] Libraries loaded: ${this.librariesLoaded}, Cytoscape available: ${!!this.cy}`),!this.librariesLoaded||!this.cy)return console.warn("[HUD-VISUALIZER-DEBUG] HUD libraries not loaded, cannot process existing events"),console.log(`[HUD-VISUALIZER-DEBUG] Storing ${e.length} events as pending`),void(this.pendingEvents=[...e]);console.log(`[HUD-VISUALIZER-DEBUG] 🏗️ Building HUD tree structure from ${e.length} historical events`),e.length>0&&(console.log("[HUD-VISUALIZER-DEBUG] Sample events:"),e.slice(0,3).forEach((e,t)=>{console.log(`[HUD-VISUALIZER-DEBUG] Event ${t+1}:`,{timestamp:e.timestamp,hook_event_name:e.hook_event_name,type:e.type,subtype:e.subtype,session_id:e.session_id,data_session_id:e.data?.session_id,data_keys:e.data?Object.keys(e.data):"no data"})})),this.clear();const t=this.groupEventsBySession(e);Object.entries(t).forEach(([e,t])=>{console.log(` 📂 Processing session ${e}: ${t.length} events`),this.buildSessionTree(e,t)}),this.runLayout(),console.log("✅ HUD tree structure built successfully")}groupEventsBySession(e){const t={};return e.forEach(e=>{const o=e.session_id||e.data?.session_id||"unknown";t[o]||(t[o]=[]),t[o].push(e)}),t}buildSessionTree(e,t){console.log(`[HUD-VISUALIZER-DEBUG] Building session tree for ${e} with ${t.length} events`);const o=new Map;let n=null;const s=t.sort((e,t)=>new Date(e.timestamp).getTime()-new Date(t.timestamp).getTime());console.log(`[HUD-VISUALIZER-DEBUG] Sorted ${s.length} events chronologically`),s.forEach((t,s)=>{const i=this.createNodeFromEvent(t,e);i&&(this.addNode(i.id,i.type,i.label,{sessionId:e,timestamp:t.timestamp,eventData:t,isSessionRoot:i.isSessionRoot}),o.set(i.id,{...i,event:t,index:s}),i.isSessionRoot&&!n&&(n=i.id),this.createHierarchicalRelationships(i.id,t,o,n))})}createNodeFromEvent(e,t){const o=e.hook_event_name||e.type||"",n=e.subtype||"",s=new Date(e.timestamp||Date.now());console.log(`[HUD-VISUALIZER-DEBUG] Creating node from event: ${o}/${n} for session ${t}`);let i,r,a,l=!1;const c=s.getTime(),d=Math.random().toString(36).substring(2,7);if("session"===o&&"started"===n)r="PM",a=`Session ${t.substring(0,8)}...`,i=`session-${t.replace(/[^a-zA-Z0-9]/g,"")}`,l=!0;else if("hook"===o&&"user_prompt"===n){r="PM";const t=e.data?.prompt_preview||"User Prompt";a=t.length>20?t.substring(0,20)+"...":t,i=`user-prompt-${c}-${d}`}else if("hook"===o&&"claude_response"===n)r="PM",a="Claude Response",i=`claude-response-${c}-${d}`;else if("hook"===o&&"pre_tool"===n){r="TOOL";const t=e.data?.tool_name||"Unknown Tool",o=t.replace(/[^a-zA-Z0-9]/g,"");a=`${t}`,i=`tool-${o}-${c}-${d}`}else if("agent"===o||e.data?.agent_type){r="AGENT";const t=e.data?.agent_type||e.data?.agent_name||"Agent",o=t.replace(/[^a-zA-Z0-9]/g,"");a=t,i=`agent-${o}-${c}-${d}`}else if("todo"===o||n.includes("todo"))r="TODO",a="Todo Update",i=`todo-${c}-${d}`;else{if("hook"===o&&"notification"===n)return null;if("log"===o){const t=e.data?.level||"info";if(!["error","critical"].includes(t))return null;r="PM",a=`${t.toUpperCase()} Log`,i=`log-${t}-${c}-${d}`}else{r="PM";const e=o.replace(/[^a-zA-Z0-9]/g,"")||"Event";a=o||"Event",i=`generic-${e}-${c}-${d}`}}return{id:i,type:r,label:a,isSessionRoot:l}}createHierarchicalRelationships(e,t,o,n){const s=t.hook_event_name||t.type||"",i=t.subtype||"";let r=null;"session"===s&&"started"===i||(r="hook"===s&&"pre_tool"===i?this.findRecentParentNode(o,["user-prompt","agent"],e):"hook"===s&&"claude_response"===i?this.findRecentParentNode(o,["user-prompt"],e):"agent"===s?this.findRecentParentNode(o,["user-prompt","agent"],e):"todo"===s?this.findRecentParentNode(o,["agent","user-prompt"],e):this.findRecentParentNode(o,["user-prompt","agent","session"],e),!r&&n&&e!==n&&(r=n),r&&r!==e&&this.addEdge(r,e))}findRecentParentNode(e,t,o){const n=Array.from(e.entries()).reverse();for(const[s,i]of n)if(s!==o)for(const e of t)if(s.startsWith(e))return s;return null}processEvent(e){this.isActive&&(this.librariesLoaded&&this.cy?this._processEventInternal(e):this.pendingEvents.push(e))}_processEventInternal(e){const t=e.hook_event_name||e.type||"",o=e.session_id||"unknown",n=new Date(e.timestamp||Date.now());let s=`${t}-${n.getTime()}`,i="PM",r=t;if(t.includes("tool_call")){i="TOOL";const t=e.data?.tool_name||"Unknown Tool";r=t,s=`tool-${t}-${n.getTime()}`}else if(t.includes("agent")){i="AGENT";const t=e.data?.agent_name||"Agent";r=t,s=`agent-${t}-${n.getTime()}`}else t.includes("todo")?(i="TODO",r="Todo List",s=`todo-${n.getTime()}`):(t.includes("user_prompt")||t.includes("claude_response"))&&(i="PM",r=t.includes("user_prompt")?"User Prompt":"Claude Response",s=`pm-${r.replace(" ","")}-${n.getTime()}`);this.addNode(s,i,r,{sessionId:o,timestamp:n.toISOString(),eventData:e}),this.createEventRelationships(s,e)}addNode(e,t,o,n={}){if(console.log(`[HUD-VISUALIZER-DEBUG] Adding node: ${e} (${t}) - ${o}`),this.nodes.has(e))return void console.log(`[HUD-VISUALIZER-DEBUG] Node ${e} already exists, skipping`);const s=this.nodeTypes[t]||this.nodeTypes.PM,i={id:e,label:`${s.icon} ${o}`,type:t,color:s.color,borderColor:this.darkenColor(s.color,20),shape:s.shape,width:s.width,height:s.height,...n};if(this.nodes.set(e,i),this.cy){const e={group:"nodes",data:i,classes:`${t.toLowerCase()}-node`};console.log("[HUD-VISUALIZER-DEBUG] Adding node element to Cytoscape:",e),this.cy.add(e),console.log(`[HUD-VISUALIZER-DEBUG] Node added successfully. Total nodes in cy: ${this.cy.nodes().length}`),this.runLayout()}}addEdge(e,t,o=null,n={}){if(e&&t)if(e!==t){if(o||(o=`edge-${e}-to-${t}`),this.cy){if(this.cy.getElementById(o).length>0)return void console.log(`[HUD-VISUALIZER-DEBUG] Edge ${o} already exists, skipping`);const i=this.cy.getElementById(e),r=this.cy.getElementById(t);if(0===i.length)return void console.warn(`[HUD-VISUALIZER-DEBUG] Source node ${e} does not exist, cannot create edge`);if(0===r.length)return void console.warn(`[HUD-VISUALIZER-DEBUG] Target node ${t} does not exist, cannot create edge`);const a={group:"edges",data:{id:o,source:e,target:t,...n}};console.log("[HUD-VISUALIZER-DEBUG] Adding edge element to Cytoscape:",a);try{this.cy.add(a),console.log(`[HUD-VISUALIZER-DEBUG] Edge added successfully. Total edges in cy: ${this.cy.edges().length}`),this.runLayout()}catch(s){console.error(`[HUD-VISUALIZER-DEBUG] Failed to add edge ${o}:`,s),console.error("[HUD-VISUALIZER-DEBUG] Element details:",a)}}}else console.warn(`[HUD-VISUALIZER-DEBUG] Cannot create self-loop edge from ${e} to itself`);else console.warn(`[HUD-VISUALIZER-DEBUG] Cannot create edge: missing source (${e}) or target (${t})`)}createEventRelationships(e,t){const o=t.hook_event_name||t.type||"",n=t.session_id||"unknown";if(Array.from(this.nodes.entries()),o.includes("tool_call")&&t.data?.tool_name){const t=this.findParentNode(n,["PM","AGENT"]);if(t)return void this.addEdge(t,e)}if(o.includes("agent")||t.data?.agent_name){const t=this.findParentNode(n,["PM"]);if(t)return void this.addEdge(t,e)}if(o.includes("todo")){const t=this.findParentNode(n,["AGENT","PM"]);if(t)return void this.addEdge(t,e)}const s=Array.from(this.nodes.keys()),i=s.indexOf(e);if(i>0){const t=s[i-1];this.addEdge(t,e)}}findParentNode(e,t){const o=Array.from(this.nodes.entries()).reverse();for(const[n,s]of o)if(s.sessionId===e&&t.includes(s.type))return n;return null}highlightConnectedNodes(e){if(!this.cy)return;this.cy.nodes().style({opacity:.3}),this.cy.edges().style({opacity:.2});const t=e.neighborhood();e.style("opacity",1),t.style("opacity",1)}resetLayout(){this.cy&&this.cy.layout(this.layoutConfig).run()}centerView(){this.cy&&(this.cy.fit(),this.cy.center())}runLayout(){if(console.log(`[HUD-VISUALIZER-DEBUG] runLayout called - isActive: ${this.isActive}, cy exists: ${!!this.cy}`),this.cy&&this.isActive){const e=this.cy.nodes().length,t=this.cy.edges().length;if(console.log(`[HUD-VISUALIZER-DEBUG] Running layout with ${e} nodes and ${t} edges`),this.container){const e=this.container.getBoundingClientRect();console.log("[HUD-VISUALIZER-DEBUG] Container dimensions before layout:",{width:e.width,height:e.height,offsetWidth:this.container.offsetWidth,offsetHeight:this.container.offsetHeight})}const o=this.cy.layout(this.layoutConfig);o.on("layoutstop",()=>{console.log("[HUD-VISUALIZER-DEBUG] Layout completed. Final node positions:"),this.cy.nodes().forEach((e,t)=>{const o=e.position(),n=e.data();console.log(`[HUD-VISUALIZER-DEBUG] Node ${t+1}: ${n.label} at (${o.x.toFixed(1)}, ${o.y.toFixed(1)})`)})}),o.run()}else console.log("[HUD-VISUALIZER-DEBUG] Skipping layout - not active or no Cytoscape instance")}clear(){if(console.log(`[HUD-VISUALIZER-DEBUG] Clearing HUD: ${this.nodes.size} nodes, ${this.pendingEvents.length} pending events`),this.nodes.clear(),this.pendingEvents=[],this.cy){const o=this.cy.elements().length;try{this.cy.elements().remove(),console.log(`[HUD-VISUALIZER-DEBUG] Removed ${o} Cytoscape elements`)}catch(e){console.error("[HUD-VISUALIZER-DEBUG] Error clearing Cytoscape elements:",e);try{this.cy.destroy(),this.cy=null,console.log("[HUD-VISUALIZER-DEBUG] Destroyed Cytoscape instance due to clear error")}catch(t){console.error("[HUD-VISUALIZER-DEBUG] Error destroying Cytoscape:",t)}}}}showLoadingIndicator(){this.container&&(this.container.innerHTML='\n <div class="hud-loading-container">\n <div class="hud-loading-spinner"></div>\n <div class="hud-loading-text">Loading HUD visualization libraries...</div>\n <div class="hud-loading-progress" id="hud-loading-progress"></div>\n </div>\n ')}updateLoadingProgress(e){const t=document.getElementById("hud-loading-progress");t&&(e.error?t.innerHTML=`<span class="hud-error">❌ ${e.message}</span>`:t.innerHTML=`\n <div class="hud-progress-bar">\n <div class="hud-progress-fill" style="width: ${e.current/e.total*100}%"></div>\n </div>\n <div class="hud-progress-text">${e.message} (${e.current}/${e.total})</div>\n `)}hideLoadingIndicator(){this.container&&(this.container.innerHTML="")}showLoadingError(e){this.container&&(this.container.innerHTML=`\n <div class="hud-error-container">\n <div class="hud-error-icon">⚠️</div>\n <div class="hud-error-text">Failed to load HUD libraries</div>\n <div class="hud-error-message">${e}</div>\n <button class="hud-retry-button" onclick="window.hudVisualizer && window.hudVisualizer.retryLoading()">\n Retry Loading\n </button>\n </div>\n `)}retryLoading(){this.librariesLoaded=!1,this.loadingPromise=null,this.activate()}debugTest(){return console.log("[HUD-VISUALIZER-DEBUG] debugTest() called manually"),console.log("[HUD-VISUALIZER-DEBUG] Current state:",{isActive:this.isActive,librariesLoaded:this.librariesLoaded,hasCy:!!this.cy,hasContainer:!!this.container,nodeCount:this.nodes.size,pendingEventCount:this.pendingEvents.length,hasHUDLibraryLoader:!!window.HUDLibraryLoader}),this.container&&console.log("[HUD-VISUALIZER-DEBUG] Container info:",{id:this.container.id,className:this.container.className,offsetWidth:this.container.offsetWidth,offsetHeight:this.container.offsetHeight,innerHTML:this.container.innerHTML?"has content":"empty"}),console.log("[HUD-VISUALIZER-DEBUG] Library availability:",{cytoscape:typeof window.cytoscape,dagre:typeof window.dagre,cytoscapeDagre:typeof window.cytoscapeDagre,HUDLibraryLoader:typeof window.HUDLibraryLoader}),{isActive:this.isActive,librariesLoaded:this.librariesLoaded,hasCy:!!this.cy,containerFound:!!this.container}}debugBlankScreen(){console.log("[HUD-BLANK-SCREEN-DEBUG] ================================="),console.log("[HUD-BLANK-SCREEN-DEBUG] COMPREHENSIVE BLANK SCREEN DEBUG"),console.log("[HUD-BLANK-SCREEN-DEBUG] =================================");const e={isActive:this.isActive,librariesLoaded:this.librariesLoaded,hasCy:!!this.cy,hasContainer:!!this.container,nodeCount:this.nodes.size,cytoscapeElementCount:this.cy?this.cy.elements().length:0};if(console.log("[HUD-BLANK-SCREEN-DEBUG] 1. Basic State:",e),!this.container)return console.error("[HUD-BLANK-SCREEN-DEBUG] 2. Container not found!"),!1;{const e=this.getContainerDebugInfo();console.log("[HUD-BLANK-SCREEN-DEBUG] 2. Container Info:",e),this.debugAddContainerBackground()}if(!this.cy)return console.error("[HUD-BLANK-SCREEN-DEBUG] 3. Cytoscape instance not found!"),!1;{const e=this.getCytoscapeDebugInfo();console.log("[HUD-BLANK-SCREEN-DEBUG] 3. Cytoscape Info:",e)}return this.debugNodePositions(),this.debugManualRenderingTriggers(),this.cy&&0===this.cy.nodes().length&&(console.log("[HUD-BLANK-SCREEN-DEBUG] 6. No nodes found, adding test nodes..."),this.debugAddTestNodes()),this.debugForceZoomFit(),console.log("[HUD-BLANK-SCREEN-DEBUG] Debug complete. Check visual results."),!0}getContainerDebugInfo(){const e=this.container.getBoundingClientRect(),t=window.getComputedStyle(this.container);return{id:this.container.id,className:this.container.className,offsetWidth:this.container.offsetWidth,offsetHeight:this.container.offsetHeight,clientWidth:this.container.clientWidth,clientHeight:this.container.clientHeight,scrollWidth:this.container.scrollWidth,scrollHeight:this.container.scrollHeight,boundingRect:{width:e.width,height:e.height,top:e.top,left:e.left,bottom:e.bottom,right:e.right},computedStyles:{display:t.display,visibility:t.visibility,opacity:t.opacity,position:t.position,overflow:t.overflow,zIndex:t.zIndex,backgroundColor:t.backgroundColor,transform:t.transform},isVisible:e.width>0&&e.height>0&&"none"!==t.display&&"hidden"!==t.visibility,parentElement:this.container.parentElement?{tagName:this.container.parentElement.tagName,className:this.container.parentElement.className,offsetWidth:this.container.parentElement.offsetWidth,offsetHeight:this.container.parentElement.offsetHeight}:null}}getCytoscapeDebugInfo(){const e=this.cy.extent(),t=this.cy.zoom(),o=this.cy.pan(),n=this.cy.viewport();return{nodeCount:this.cy.nodes().length,edgeCount:this.cy.edges().length,elementCount:this.cy.elements().length,zoom:t,pan:o,extent:e,viewport:n,containerWidth:this.cy.width(),containerHeight:this.cy.height(),isInitialized:void 0!==this.cy.scratch("_cytoscape-initialized"),renderer:this.cy.renderer()?{name:this.cy.renderer().name,options:this.cy.renderer().options}:null}}debugNodePositions(){if(!this.cy||0===this.cy.nodes().length)return void console.log("[HUD-BLANK-SCREEN-DEBUG] 4. No nodes to check positions");console.log("[HUD-BLANK-SCREEN-DEBUG] 4. Node Positions:");const e=this.cy.nodes(),t=this.cy.extent(),o=this.cy.viewport();console.log("[HUD-BLANK-SCREEN-DEBUG] Viewport extent:",t),console.log("[HUD-BLANK-SCREEN-DEBUG] Current viewport:",o),e.forEach((e,t)=>{const o=e.position(),n=e.data(),s=e.boundingBox();console.log(`[HUD-BLANK-SCREEN-DEBUG] Node ${t+1}:`,{id:n.id,label:n.label,position:o,boundingBox:s,isVisible:e.visible(),opacity:e.style("opacity"),width:e.style("width"),height:e.style("height")})})}debugAddContainerBackground(){this.container&&(this.container.style.backgroundColor="#ff000020",this.container.style.border="2px solid #ff0000",this.container.style.minHeight="400px",console.log("[HUD-BLANK-SCREEN-DEBUG] Added red background and border to container for visibility test"))}debugManualRenderingTriggers(){if(this.cy){console.log("[HUD-BLANK-SCREEN-DEBUG] 5. Triggering manual rendering operations...");try{console.log("[HUD-BLANK-SCREEN-DEBUG] - Forcing resize..."),this.cy.resize(),console.log("[HUD-BLANK-SCREEN-DEBUG] - Forcing redraw..."),this.cy.forceRender(),this.cy.nodes().length>0&&(console.log("[HUD-BLANK-SCREEN-DEBUG] - Running layout..."),this.cy.layout(this.layoutConfig).run()),console.log("[HUD-BLANK-SCREEN-DEBUG] - Updating viewport..."),this.cy.viewport({zoom:this.cy.zoom(),pan:this.cy.pan()}),console.log("[HUD-BLANK-SCREEN-DEBUG] Manual rendering triggers completed")}catch(e){console.error("[HUD-BLANK-SCREEN-DEBUG] Error during manual rendering:",e)}}else console.log("[HUD-BLANK-SCREEN-DEBUG] 5. No Cytoscape instance for manual rendering")}debugAddTestNodes(){if(this.cy){console.log("[HUD-BLANK-SCREEN-DEBUG] Adding test nodes...");try{this.cy.elements().remove();const e=[{group:"nodes",data:{id:"test-node-1",label:"🤖 Test Node 1",color:"#48bb78",borderColor:"#38a169",shape:"rectangle",width:120,height:40},classes:"pm-node"},{group:"nodes",data:{id:"test-node-2",label:"🔧 Test Node 2",color:"#4299e1",borderColor:"#3182ce",shape:"diamond",width:80,height:50},classes:"tool-node"},{group:"nodes",data:{id:"test-node-3",label:"📝 Test Node 3",color:"#e53e3e",borderColor:"#c53030",shape:"triangle",width:70,height:40},classes:"todo-node"}],t=[{group:"edges",data:{id:"test-edge-1",source:"test-node-1",target:"test-node-2"}},{group:"edges",data:{id:"test-edge-2",source:"test-node-2",target:"test-node-3"}}];this.cy.add(e),this.cy.add(t),console.log("[HUD-BLANK-SCREEN-DEBUG] Added 3 test nodes and 2 test edges"),e.forEach(e=>{this.nodes.set(e.data.id,e.data)}),this.runLayout()}catch(e){console.error("[HUD-BLANK-SCREEN-DEBUG] Error adding test nodes:",e)}}}debugForceZoomFit(){if(!this.cy)return;console.log("[HUD-BLANK-SCREEN-DEBUG] 7. Forcing zoom fit...");const e=e=>{try{console.log(`[HUD-BLANK-SCREEN-DEBUG] Zoom fit attempt ${e}...`);const t=this.cy.zoom(),o=this.cy.pan(),n=this.cy.elements();if(console.log("[HUD-BLANK-SCREEN-DEBUG] Before fit:",{zoom:t,pan:o,elementCount:n.length}),n.length>0){this.cy.fit(n,50);const e=this.cy.zoom(),s=this.cy.pan();console.log("[HUD-BLANK-SCREEN-DEBUG] After fit:",{zoom:e,pan:s,changed:t!==e||o.x!==s.x||o.y!==s.y}),this.cy.center(n)}else console.log("[HUD-BLANK-SCREEN-DEBUG] No elements to fit")}catch(t){console.error(`[HUD-BLANK-SCREEN-DEBUG] Zoom fit attempt ${e} failed:`,t)}};e(1),setTimeout(()=>e(2),100),setTimeout(()=>e(3),500),setTimeout(()=>e(4),1e3)}debugDrawSimpleShape(){if(!this.cy)return console.log("[HUD-CANVAS-TEST] No Cytoscape instance"),!1;console.log("[HUD-CANVAS-TEST] Testing Cytoscape canvas rendering...");try{return this.cy.elements().remove(),this.cy.add({group:"nodes",data:{id:"canvas-test",label:"✅ CANVAS TEST",color:"#ff0000",borderColor:"#000000",width:200,height:100,shape:"rectangle"},position:{x:200,y:200}}),this.cy.forceRender(),this.cy.fit(this.cy.$("#canvas-test"),50),console.log("[HUD-CANVAS-TEST] Canvas test node added and positioned"),console.log('[HUD-CANVAS-TEST] If you see a red rectangle with "CANVAS TEST", rendering works!'),!0}catch(e){return console.error("[HUD-CANVAS-TEST] Canvas test failed:",e),!1}}darkenColor(e,t){const o=parseInt(e.replace("#",""),16),n=Math.round(2.55*t),s=(o>>16)-n,i=(o>>8&255)-n,r=(255&o)-n;return"#"+(16777216+65536*(s<255?s<1?0:s:255)+256*(i<255?i<1?0:i:255)+(r<255?r<1?0:r:255)).toString(16).slice(1)}};
2
- //# sourceMappingURL=hud-manager.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"hud-manager.js","sources":["../../js/components/hud-visualizer.js"],"sourcesContent":["/**\n * HUD Visualizer Component\n * Manages the Cytoscape.js tree visualization for the HUD mode with lazy loading\n */\n\nclass HUDVisualizer {\n constructor() {\n this.cy = null;\n this.container = null;\n this.nodes = new Map(); // Map of node IDs to node data\n this.isActive = false;\n this.librariesLoaded = false;\n this.loadingPromise = null;\n this.pendingEvents = []; // Store events received before libraries are loaded\n\n // Layout configuration\n this.layoutConfig = {\n name: 'dagre',\n rankDir: 'TB', // Top to bottom\n animate: true,\n animationDuration: 500,\n fit: true,\n padding: 30,\n rankSep: 100,\n nodeSep: 80\n };\n\n // Node type configurations\n this.nodeTypes = {\n PM: {\n color: '#48bb78',\n shape: 'rectangle',\n width: 120,\n height: 40,\n icon: '👤'\n },\n AGENT: {\n color: '#9f7aea',\n shape: 'ellipse',\n width: 100,\n height: 60,\n icon: '🤖'\n },\n TOOL: {\n color: '#4299e1',\n shape: 'diamond',\n width: 80,\n height: 50,\n icon: '🔧'\n },\n TODO: {\n color: '#e53e3e',\n shape: 'triangle',\n width: 70,\n height: 40,\n icon: '📝'\n }\n };\n }\n\n /**\n * Initialize the HUD visualizer (called at startup)\n */\n initialize() {\n this.container = document.getElementById('hud-cytoscape');\n if (!this.container) {\n console.error('HUD container not found');\n return false;\n }\n\n // Ensure container has proper attributes for interaction\n this.container.style.pointerEvents = 'auto';\n this.container.style.cursor = 'default';\n this.container.style.position = 'relative';\n this.container.style.zIndex = '1';\n\n // Setup basic event handlers (not library-dependent)\n this.setupBasicEventHandlers();\n\n console.log('HUD Visualizer initialized (libraries will load lazily)');\n return true;\n }\n\n /**\n * Load libraries and initialize Cytoscape when HUD is first activated\n * @returns {Promise} - Promise that resolves when libraries are loaded and Cytoscape is initialized\n */\n async loadLibrariesAndInitialize() {\n if (this.librariesLoaded && this.cy) {\n return Promise.resolve();\n }\n\n // If already loading, return the existing promise\n if (this.loadingPromise) {\n return this.loadingPromise;\n }\n\n this.loadingPromise = this._performLazyLoading();\n return this.loadingPromise;\n }\n\n /**\n * Perform the actual lazy loading process\n * @private\n */\n async _performLazyLoading() {\n try {\n console.log('[HUD-VISUALIZER-DEBUG] _performLazyLoading() called');\n console.log('[HUD-VISUALIZER-DEBUG] Loading HUD visualization libraries...');\n\n // Show loading indicator\n this.showLoadingIndicator();\n\n // Load libraries using the HUD library loader\n if (!window.HUDLibraryLoader) {\n throw new Error('HUD Library Loader not available');\n }\n\n console.log('[HUD-VISUALIZER-DEBUG] HUD Library Loader found, loading libraries...');\n await window.HUDLibraryLoader.loadHUDLibraries((progress) => {\n console.log('[HUD-VISUALIZER-DEBUG] Loading progress:', progress);\n this.updateLoadingProgress(progress);\n });\n\n // Verify libraries are available\n console.log('[HUD-VISUALIZER-DEBUG] Verifying libraries are loaded...');\n if (typeof window.cytoscape === 'undefined') {\n throw new Error('Cytoscape.js not loaded');\n }\n if (typeof window.dagre === 'undefined') {\n throw new Error('Dagre not loaded');\n }\n if (typeof window.cytoscapeDagre === 'undefined') {\n throw new Error('Cytoscape-dagre not loaded');\n }\n\n console.log('[HUD-VISUALIZER-DEBUG] All HUD libraries loaded successfully');\n this.librariesLoaded = true;\n\n // Initialize Cytoscape instance\n console.log('[HUD-VISUALIZER-DEBUG] Initializing Cytoscape...');\n this.initializeCytoscape();\n\n // Setup library-dependent event handlers\n console.log('[HUD-VISUALIZER-DEBUG] Setting up Cytoscape event handlers...');\n this.setupCytoscapeEventHandlers();\n\n // Process any pending events\n console.log('[HUD-VISUALIZER-DEBUG] Processing pending events...');\n this.processPendingEvents();\n\n // Hide loading indicator\n this.hideLoadingIndicator();\n\n console.log('[HUD-VISUALIZER-DEBUG] HUD Visualizer fully initialized with lazy loading');\n return true;\n\n } catch (error) {\n console.error('[HUD-VISUALIZER-DEBUG] Failed to load HUD libraries:', error);\n console.error('[HUD-VISUALIZER-DEBUG] Error stack:', error.stack);\n this.showLoadingError(error.message);\n this.librariesLoaded = false;\n this.loadingPromise = null;\n throw error;\n }\n }\n\n /**\n * Initialize Cytoscape.js instance (called after libraries are loaded)\n */\n initializeCytoscape() {\n if (!this.librariesLoaded || !window.cytoscape) {\n console.error('Cannot initialize Cytoscape: libraries not loaded');\n return;\n }\n\n // Register dagre extension for hierarchical layouts\n if (typeof window.cytoscape !== 'undefined' && typeof window.cytoscapeDagre !== 'undefined') {\n window.cytoscape.use(window.cytoscapeDagre);\n }\n\n this.cy = window.cytoscape({\n container: this.container,\n\n elements: [],\n\n // Enable user interaction\n userZoomingEnabled: true,\n userPanningEnabled: true,\n boxSelectionEnabled: false,\n autoungrabify: false,\n autounselectify: false,\n\n style: [\n // Node styles\n {\n selector: 'node',\n style: {\n 'background-color': 'data(color)',\n 'border-color': 'data(borderColor)',\n 'border-width': 2,\n 'color': '#ffffff',\n 'label': 'data(label)',\n 'text-valign': 'center',\n 'text-halign': 'center',\n 'font-size': '12px',\n 'font-weight': 'bold',\n 'width': 'data(width)',\n 'height': 'data(height)',\n 'shape': 'data(shape)',\n 'text-wrap': 'wrap',\n 'text-max-width': '100px'\n }\n },\n\n // Edge styles\n {\n selector: 'edge',\n style: {\n 'width': 2,\n 'line-color': '#718096',\n 'target-arrow-color': '#718096',\n 'target-arrow-shape': 'triangle',\n 'curve-style': 'bezier',\n 'arrow-scale': 1.2\n }\n },\n\n // Node type specific styles\n {\n selector: '.pm-node',\n style: {\n 'background-color': '#48bb78',\n 'border-color': '#38a169',\n 'shape': 'rectangle'\n }\n },\n\n {\n selector: '.agent-node',\n style: {\n 'background-color': '#9f7aea',\n 'border-color': '#805ad5',\n 'shape': 'ellipse'\n }\n },\n\n {\n selector: '.tool-node',\n style: {\n 'background-color': '#4299e1',\n 'border-color': '#3182ce',\n 'shape': 'diamond'\n }\n },\n\n {\n selector: '.todo-node',\n style: {\n 'background-color': '#e53e3e',\n 'border-color': '#c53030',\n 'shape': 'triangle'\n }\n },\n\n // Hover effects\n {\n selector: 'node:active',\n style: {\n 'overlay-opacity': 0.2,\n 'overlay-color': '#000000'\n }\n }\n ],\n\n layout: this.layoutConfig\n });\n\n // Setup resize handler\n this.setupResizeHandler();\n }\n\n /**\n * Setup basic event handlers (not dependent on libraries)\n */\n setupBasicEventHandlers() {\n // Reset layout button\n const resetBtn = document.getElementById('hud-reset-layout');\n if (resetBtn) {\n resetBtn.addEventListener('click', () => {\n this.resetLayout();\n });\n }\n\n // Center view button\n const centerBtn = document.getElementById('hud-center-view');\n if (centerBtn) {\n centerBtn.addEventListener('click', () => {\n this.centerView();\n });\n }\n }\n\n /**\n * Setup Cytoscape-dependent event handlers (called after libraries are loaded)\n */\n setupCytoscapeEventHandlers() {\n if (!this.cy) {\n console.warn('[HUD-VISUALIZER-DEBUG] Cannot setup Cytoscape event handlers: no cy instance');\n return;\n }\n\n console.log('[HUD-VISUALIZER-DEBUG] Setting up Cytoscape event handlers...');\n\n // Node click events\n this.cy.on('tap', 'node', (evt) => {\n const node = evt.target;\n const data = node.data();\n console.log('[HUD-VISUALIZER-DEBUG] Node clicked:', data);\n\n // Highlight connected nodes\n this.highlightConnectedNodes(node);\n });\n\n // Background click events\n this.cy.on('tap', (evt) => {\n if (evt.target === this.cy) {\n console.log('[HUD-VISUALIZER-DEBUG] Background clicked - resetting highlights');\n // Reset all node styles\n this.cy.nodes().style({\n 'opacity': 1\n });\n\n this.cy.edges().style({\n 'opacity': 1\n });\n }\n });\n\n // Mouse events for debugging\n this.cy.on('mouseover', 'node', (evt) => {\n const node = evt.target;\n node.style('opacity', 0.8);\n });\n\n this.cy.on('mouseout', 'node', (evt) => {\n const node = evt.target;\n node.style('opacity', 1);\n });\n\n console.log('[HUD-VISUALIZER-DEBUG] Cytoscape event handlers set up successfully');\n }\n\n /**\n * Setup resize handler for container\n */\n setupResizeHandler() {\n const resizeObserver = new ResizeObserver(() => {\n if (this.cy && this.isActive) {\n this.ensureContainerResize();\n }\n });\n\n if (this.container) {\n resizeObserver.observe(this.container);\n }\n }\n\n /**\n * Ensure container is properly resized and visible\n */\n ensureContainerResize() {\n if (!this.cy || !this.container) {\n console.log('[HUD-VISUALIZER-DEBUG] Cannot resize: missing cy or container');\n return;\n }\n\n // Ensure container can receive events\n this.ensureContainerInteractivity();\n\n // Log container dimensions\n const containerRect = this.container.getBoundingClientRect();\n console.log('[HUD-VISUALIZER-DEBUG] Container dimensions:', {\n width: containerRect.width,\n height: containerRect.height,\n offsetWidth: this.container.offsetWidth,\n offsetHeight: this.container.offsetHeight,\n isVisible: containerRect.width > 0 && containerRect.height > 0\n });\n\n // Only proceed if container is visible\n if (containerRect.width > 0 && containerRect.height > 0) {\n console.log('[HUD-VISUALIZER-DEBUG] Container is visible, resizing Cytoscape...');\n\n try {\n // Force Cytoscape to resize\n this.cy.resize();\n\n // Log Cytoscape elements\n const nodeCount = this.cy.nodes().length;\n const edgeCount = this.cy.edges().length;\n console.log('[HUD-VISUALIZER-DEBUG] Cytoscape elements after resize:', {\n nodes: nodeCount,\n edges: edgeCount\n });\n\n // If we have nodes, fit and run layout\n if (nodeCount > 0) {\n console.log('[HUD-VISUALIZER-DEBUG] Running fit and layout...');\n this.cy.fit();\n this.runLayout();\n } else {\n console.log('[HUD-VISUALIZER-DEBUG] No nodes to display');\n }\n\n } catch (error) {\n console.error('[HUD-VISUALIZER-DEBUG] Error during resize:', error);\n }\n } else {\n console.log('[HUD-VISUALIZER-DEBUG] Container not visible yet, skipping resize');\n }\n }\n\n /**\n * Ensure container can receive mouse and touch events\n */\n ensureContainerInteractivity() {\n if (!this.container) return;\n\n // Force container to be interactive\n this.container.style.pointerEvents = 'auto';\n this.container.style.cursor = 'default';\n this.container.style.userSelect = 'none';\n this.container.style.touchAction = 'manipulation';\n\n // Remove any overlapping elements that might block events\n const parent = this.container.parentElement;\n if (parent) {\n parent.style.pointerEvents = 'auto';\n parent.style.position = 'relative';\n }\n\n console.log('[HUD-VISUALIZER-DEBUG] Container interactivity ensured');\n }\n\n /**\n * Activate the HUD visualizer (triggers lazy loading if needed)\n */\n async activate() {\n console.log('[HUD-VISUALIZER-DEBUG] activate() called');\n this.isActive = true;\n\n try {\n console.log('[HUD-VISUALIZER-DEBUG] Loading libraries and initializing...');\n // Load libraries if not already loaded\n await this.loadLibrariesAndInitialize();\n\n console.log('[HUD-VISUALIZER-DEBUG] Libraries loaded, cy exists:', !!this.cy);\n\n // If Cytoscape was destroyed during clearing, recreate it\n if (!this.cy) {\n console.log('[HUD-VISUALIZER-DEBUG] Cytoscape instance missing, recreating...');\n this.initializeCytoscape();\n this.setupCytoscapeEventHandlers();\n }\n\n if (this.cy) {\n // Wait for container to be visible, then trigger resize and fit\n console.log('[HUD-VISUALIZER-DEBUG] Triggering resize and fit...');\n\n // Multiple resize attempts to ensure container visibility\n setTimeout(() => {\n console.log('[HUD-VISUALIZER-DEBUG] First resize attempt...');\n this.ensureContainerResize();\n }, 50);\n\n setTimeout(() => {\n console.log('[HUD-VISUALIZER-DEBUG] Second resize attempt...');\n this.ensureContainerResize();\n }, 200);\n\n setTimeout(() => {\n console.log('[HUD-VISUALIZER-DEBUG] Final resize attempt...');\n this.ensureContainerResize();\n }, 500);\n }\n console.log('[HUD-VISUALIZER-DEBUG] activate() completed successfully');\n } catch (error) {\n console.error('[HUD-VISUALIZER-DEBUG] Failed to activate HUD:', error);\n console.error('[HUD-VISUALIZER-DEBUG] Error stack:', error.stack);\n // Keep isActive true so user can retry\n throw error; // Re-throw so the promise rejects properly\n }\n }\n\n /**\n * Deactivate the HUD visualizer\n */\n deactivate() {\n this.isActive = false;\n }\n\n /**\n * Process pending events that were received before libraries loaded\n */\n processPendingEvents() {\n if (this.pendingEvents.length > 0) {\n console.log(`Processing ${this.pendingEvents.length} pending events`);\n\n for (const event of this.pendingEvents) {\n this._processEventInternal(event);\n }\n\n this.pendingEvents = [];\n }\n }\n\n /**\n * Process existing events from dashboard when HUD is activated\n * This builds the complete tree structure from historical events\n * @param {Array} events - Array of sorted historical events\n */\n processExistingEvents(events) {\n console.log(`[HUD-VISUALIZER-DEBUG] processExistingEvents called with ${events ? events.length : 0} events`);\n\n if (!events) {\n console.error('[HUD-VISUALIZER-DEBUG] No events provided to processExistingEvents');\n return;\n }\n\n if (!Array.isArray(events)) {\n console.error('[HUD-VISUALIZER-DEBUG] Events is not an array:', typeof events);\n return;\n }\n\n console.log(`[HUD-VISUALIZER-DEBUG] Libraries loaded: ${this.librariesLoaded}, Cytoscape available: ${!!this.cy}`);\n\n if (!this.librariesLoaded || !this.cy) {\n console.warn('[HUD-VISUALIZER-DEBUG] HUD libraries not loaded, cannot process existing events');\n console.log(`[HUD-VISUALIZER-DEBUG] Storing ${events.length} events as pending`);\n this.pendingEvents = [...events];\n return;\n }\n\n console.log(`[HUD-VISUALIZER-DEBUG] 🏗️ Building HUD tree structure from ${events.length} historical events`);\n\n // Log sample events to understand structure\n if (events.length > 0) {\n console.log('[HUD-VISUALIZER-DEBUG] Sample events:');\n events.slice(0, 3).forEach((event, i) => {\n console.log(`[HUD-VISUALIZER-DEBUG] Event ${i + 1}:`, {\n timestamp: event.timestamp,\n hook_event_name: event.hook_event_name,\n type: event.type,\n subtype: event.subtype,\n session_id: event.session_id,\n data_session_id: event.data?.session_id,\n data_keys: event.data ? Object.keys(event.data) : 'no data'\n });\n });\n }\n\n // Clear any existing visualization\n this.clear();\n\n // Group events by session to build proper hierarchies\n const sessionGroups = this.groupEventsBySession(events);\n\n // Process each session group to build trees\n Object.entries(sessionGroups).forEach(([sessionId, sessionEvents]) => {\n console.log(` 📂 Processing session ${sessionId}: ${sessionEvents.length} events`);\n this.buildSessionTree(sessionId, sessionEvents);\n });\n\n // Run final layout to organize the complete visualization\n this.runLayout();\n\n console.log(`✅ HUD tree structure built successfully`);\n }\n\n /**\n * Group events by session ID for hierarchical processing\n * @param {Array} events - Array of events\n * @returns {Object} Object with session IDs as keys and event arrays as values\n */\n groupEventsBySession(events) {\n const sessionGroups = {};\n\n events.forEach(event => {\n const sessionId = event.session_id || event.data?.session_id || 'unknown';\n if (!sessionGroups[sessionId]) {\n sessionGroups[sessionId] = [];\n }\n sessionGroups[sessionId].push(event);\n });\n\n return sessionGroups;\n }\n\n /**\n * Build a tree structure for a specific session\n * @param {string} sessionId - Session identifier\n * @param {Array} sessionEvents - Events for this session\n */\n buildSessionTree(sessionId, sessionEvents) {\n console.log(`[HUD-VISUALIZER-DEBUG] Building session tree for ${sessionId} with ${sessionEvents.length} events`);\n\n const sessionNodes = new Map(); // Track nodes created for this session\n let sessionRootNode = null;\n\n // Sort events chronologically within the session\n const sortedEvents = sessionEvents.sort((a, b) => {\n return new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime();\n });\n\n console.log(`[HUD-VISUALIZER-DEBUG] Sorted ${sortedEvents.length} events chronologically`);\n\n sortedEvents.forEach((event, index) => {\n const nodeData = this.createNodeFromEvent(event, sessionId);\n if (!nodeData) return;\n\n // Add the node to visualization\n this.addNode(nodeData.id, nodeData.type, nodeData.label, {\n sessionId: sessionId,\n timestamp: event.timestamp,\n eventData: event,\n isSessionRoot: nodeData.isSessionRoot\n });\n\n sessionNodes.set(nodeData.id, {\n ...nodeData,\n event: event,\n index: index\n });\n\n // Track session root node\n if (nodeData.isSessionRoot && !sessionRootNode) {\n sessionRootNode = nodeData.id;\n }\n\n // Create relationships based on event context\n this.createHierarchicalRelationships(nodeData.id, event, sessionNodes, sessionRootNode);\n });\n }\n\n /**\n * Create node data from an event\n * @param {Object} event - Event object\n * @param {string} sessionId - Session ID\n * @returns {Object|null} Node data or null if event should be skipped\n */\n createNodeFromEvent(event, sessionId) {\n const eventType = event.hook_event_name || event.type || '';\n const subtype = event.subtype || '';\n const timestamp = new Date(event.timestamp || Date.now());\n\n console.log(`[HUD-VISUALIZER-DEBUG] Creating node from event: ${eventType}/${subtype} for session ${sessionId}`);\n\n let nodeId, nodeType, label, isSessionRoot = false;\n\n // Generate a unique timestamp-based ID suffix\n const timestampId = timestamp.getTime();\n const randomSuffix = Math.random().toString(36).substring(2, 7);\n\n // Determine node type and create appropriate visualization\n if (eventType === 'session' && subtype === 'started') {\n // Session root node\n nodeType = 'PM';\n label = `Session ${sessionId.substring(0, 8)}...`;\n nodeId = `session-${sessionId.replace(/[^a-zA-Z0-9]/g, '')}`;\n isSessionRoot = true;\n\n } else if (eventType === 'hook' && subtype === 'user_prompt') {\n // User prompts are major workflow nodes\n nodeType = 'PM';\n const promptPreview = event.data?.prompt_preview || 'User Prompt';\n label = promptPreview.length > 20 ? promptPreview.substring(0, 20) + '...' : promptPreview;\n nodeId = `user-prompt-${timestampId}-${randomSuffix}`;\n\n } else if (eventType === 'hook' && subtype === 'claude_response') {\n // Claude responses\n nodeType = 'PM';\n label = 'Claude Response';\n nodeId = `claude-response-${timestampId}-${randomSuffix}`;\n\n } else if (eventType === 'hook' && subtype === 'pre_tool') {\n // Tool calls - pre hook\n nodeType = 'TOOL';\n const toolName = event.data?.tool_name || 'Unknown Tool';\n // Clean tool name for ID\n const cleanToolName = toolName.replace(/[^a-zA-Z0-9]/g, '');\n label = `${toolName}`;\n nodeId = `tool-${cleanToolName}-${timestampId}-${randomSuffix}`;\n\n } else if (eventType === 'agent' || event.data?.agent_type) {\n // Agent operations\n nodeType = 'AGENT';\n const agentName = event.data?.agent_type || event.data?.agent_name || 'Agent';\n // Clean agent name for ID\n const cleanAgentName = agentName.replace(/[^a-zA-Z0-9]/g, '');\n label = agentName;\n nodeId = `agent-${cleanAgentName}-${timestampId}-${randomSuffix}`;\n\n } else if (eventType === 'todo' || subtype.includes('todo')) {\n // Todo operations\n nodeType = 'TODO';\n label = 'Todo Update';\n nodeId = `todo-${timestampId}-${randomSuffix}`;\n\n } else if (eventType === 'hook' && subtype === 'notification') {\n // Skip notifications for cleaner visualization\n return null;\n\n } else if (eventType === 'log') {\n // Skip log events for cleaner visualization unless they're errors\n const level = event.data?.level || 'info';\n if (!['error', 'critical'].includes(level)) {\n return null;\n }\n nodeType = 'PM';\n label = `${level.toUpperCase()} Log`;\n nodeId = `log-${level}-${timestampId}-${randomSuffix}`;\n\n } else {\n // Generic event node\n nodeType = 'PM';\n const cleanEventType = eventType.replace(/[^a-zA-Z0-9]/g, '') || 'Event';\n label = eventType || 'Event';\n nodeId = `generic-${cleanEventType}-${timestampId}-${randomSuffix}`;\n }\n\n return {\n id: nodeId,\n type: nodeType,\n label: label,\n isSessionRoot: isSessionRoot\n };\n }\n\n /**\n * Create hierarchical relationships between nodes based on event context\n * @param {string} nodeId - Current node ID\n * @param {Object} event - Current event\n * @param {Map} sessionNodes - Map of all nodes in this session\n * @param {string} sessionRootNode - Root node ID for this session\n */\n createHierarchicalRelationships(nodeId, event, sessionNodes, sessionRootNode) {\n const eventType = event.hook_event_name || event.type || '';\n const subtype = event.subtype || '';\n\n // Find appropriate parent node based on event context\n let parentNodeId = null;\n\n if (eventType === 'session' && subtype === 'started') {\n // Session start nodes have no parent\n return;\n\n } else if (eventType === 'hook' && subtype === 'pre_tool') {\n // Tool calls should connect to the most recent user prompt or agent\n parentNodeId = this.findRecentParentNode(sessionNodes, ['user-prompt', 'agent'], nodeId);\n\n } else if (eventType === 'hook' && subtype === 'claude_response') {\n // Claude responses should connect to user prompts\n parentNodeId = this.findRecentParentNode(sessionNodes, ['user-prompt'], nodeId);\n\n } else if (eventType === 'agent') {\n // Agents should connect to user prompts or other agents (delegation)\n parentNodeId = this.findRecentParentNode(sessionNodes, ['user-prompt', 'agent'], nodeId);\n\n } else if (eventType === 'todo') {\n // Todos should connect to agents or user prompts\n parentNodeId = this.findRecentParentNode(sessionNodes, ['agent', 'user-prompt'], nodeId);\n\n } else {\n // Default: connect to most recent significant node\n parentNodeId = this.findRecentParentNode(sessionNodes, ['user-prompt', 'agent', 'session'], nodeId);\n }\n\n // If no specific parent found, connect to session root\n if (!parentNodeId && sessionRootNode && nodeId !== sessionRootNode) {\n parentNodeId = sessionRootNode;\n }\n\n // Create the edge if parent exists\n if (parentNodeId && parentNodeId !== nodeId) {\n this.addEdge(parentNodeId, nodeId);\n }\n }\n\n /**\n * Find the most recent parent node of specified types\n * @param {Map} sessionNodes - Map of session nodes\n * @param {Array} nodeTypes - Array of node type prefixes to search for\n * @param {string} currentNodeId - Current node ID to exclude from search\n * @returns {string|null} Parent node ID or null\n */\n findRecentParentNode(sessionNodes, nodeTypes, currentNodeId) {\n const nodeEntries = Array.from(sessionNodes.entries()).reverse(); // Most recent first\n\n for (const [nodeId, nodeData] of nodeEntries) {\n if (nodeId === currentNodeId) continue; // Skip current node\n\n // Check if this node matches any of the desired parent types\n for (const typePrefix of nodeTypes) {\n if (nodeId.startsWith(typePrefix)) {\n return nodeId;\n }\n }\n }\n\n return null;\n }\n\n /**\n * Process a socket event and add appropriate nodes/edges\n * @param {Object} event - Socket event data\n */\n processEvent(event) {\n if (!this.isActive) return;\n\n // If libraries aren't loaded yet, store the event for later processing\n if (!this.librariesLoaded || !this.cy) {\n this.pendingEvents.push(event);\n return;\n }\n\n this._processEventInternal(event);\n }\n\n /**\n * Internal event processing (assumes libraries are loaded)\n * @private\n */\n _processEventInternal(event) {\n const eventType = event.hook_event_name || event.type || '';\n const sessionId = event.session_id || 'unknown';\n const timestamp = new Date(event.timestamp || Date.now());\n\n // Create a unique node ID based on event type and data\n let nodeId = `${eventType}-${timestamp.getTime()}`;\n let nodeType = 'PM';\n let label = eventType;\n\n // Determine node type based on event\n if (eventType.includes('tool_call')) {\n nodeType = 'TOOL';\n const toolName = event.data?.tool_name || 'Unknown Tool';\n label = toolName;\n nodeId = `tool-${toolName}-${timestamp.getTime()}`;\n } else if (eventType.includes('agent')) {\n nodeType = 'AGENT';\n const agentName = event.data?.agent_name || 'Agent';\n label = agentName;\n nodeId = `agent-${agentName}-${timestamp.getTime()}`;\n } else if (eventType.includes('todo')) {\n nodeType = 'TODO';\n label = 'Todo List';\n nodeId = `todo-${timestamp.getTime()}`;\n } else if (eventType.includes('user_prompt') || eventType.includes('claude_response')) {\n nodeType = 'PM';\n label = eventType.includes('user_prompt') ? 'User Prompt' : 'Claude Response';\n nodeId = `pm-${label.replace(' ', '')}-${timestamp.getTime()}`;\n }\n\n // Add the node\n this.addNode(nodeId, nodeType, label, {\n sessionId: sessionId,\n timestamp: timestamp.toISOString(),\n eventData: event\n });\n\n // Add edges based on relationships\n this.createEventRelationships(nodeId, event);\n }\n\n /**\n * Add a node to the visualization\n * @param {string} id - Unique node identifier\n * @param {string} type - Node type (PM, AGENT, TOOL, TODO)\n * @param {string} label - Node label\n * @param {Object} data - Additional node data\n */\n addNode(id, type, label, data = {}) {\n console.log(`[HUD-VISUALIZER-DEBUG] Adding node: ${id} (${type}) - ${label}`);\n\n if (this.nodes.has(id)) {\n console.log(`[HUD-VISUALIZER-DEBUG] Node ${id} already exists, skipping`);\n return; // Node already exists\n }\n\n const nodeType = this.nodeTypes[type] || this.nodeTypes.PM;\n const nodeData = {\n id: id,\n label: `${nodeType.icon} ${label}`,\n type: type,\n color: nodeType.color,\n borderColor: this.darkenColor(nodeType.color, 20),\n shape: nodeType.shape,\n width: nodeType.width,\n height: nodeType.height,\n ...data\n };\n\n this.nodes.set(id, nodeData);\n\n if (this.cy) {\n const element = {\n group: 'nodes',\n data: nodeData,\n classes: `${type.toLowerCase()}-node`\n };\n\n console.log(`[HUD-VISUALIZER-DEBUG] Adding node element to Cytoscape:`, element);\n this.cy.add(element);\n console.log(`[HUD-VISUALIZER-DEBUG] Node added successfully. Total nodes in cy: ${this.cy.nodes().length}`);\n this.runLayout();\n }\n }\n\n /**\n * Add an edge between two nodes\n * @param {string} sourceId - Source node ID\n * @param {string} targetId - Target node ID\n * @param {string} edgeId - Unique edge identifier\n * @param {Object} data - Additional edge data\n */\n addEdge(sourceId, targetId, edgeId = null, data = {}) {\n if (!sourceId || !targetId) {\n console.warn(`[HUD-VISUALIZER-DEBUG] Cannot create edge: missing source (${sourceId}) or target (${targetId})`);\n return;\n }\n\n if (sourceId === targetId) {\n console.warn(`[HUD-VISUALIZER-DEBUG] Cannot create self-loop edge from ${sourceId} to itself`);\n return;\n }\n\n if (!edgeId) {\n edgeId = `edge-${sourceId}-to-${targetId}`;\n }\n\n if (this.cy) {\n // Check if edge already exists\n const existingEdge = this.cy.getElementById(edgeId);\n if (existingEdge.length > 0) {\n console.log(`[HUD-VISUALIZER-DEBUG] Edge ${edgeId} already exists, skipping`);\n return;\n }\n\n // Check if nodes exist\n const sourceNode = this.cy.getElementById(sourceId);\n const targetNode = this.cy.getElementById(targetId);\n\n if (sourceNode.length === 0) {\n console.warn(`[HUD-VISUALIZER-DEBUG] Source node ${sourceId} does not exist, cannot create edge`);\n return;\n }\n\n if (targetNode.length === 0) {\n console.warn(`[HUD-VISUALIZER-DEBUG] Target node ${targetId} does not exist, cannot create edge`);\n return;\n }\n\n const element = {\n group: 'edges',\n data: {\n id: edgeId,\n source: sourceId,\n target: targetId,\n ...data\n }\n };\n\n console.log(`[HUD-VISUALIZER-DEBUG] Adding edge element to Cytoscape:`, element);\n\n try {\n this.cy.add(element);\n console.log(`[HUD-VISUALIZER-DEBUG] Edge added successfully. Total edges in cy: ${this.cy.edges().length}`);\n this.runLayout();\n } catch (error) {\n console.error(`[HUD-VISUALIZER-DEBUG] Failed to add edge ${edgeId}:`, error);\n console.error(`[HUD-VISUALIZER-DEBUG] Element details:`, element);\n }\n }\n }\n\n /**\n * Create relationships between events\n * @param {string} nodeId - Current node ID\n * @param {Object} event - Event data\n */\n createEventRelationships(nodeId, event) {\n const eventType = event.hook_event_name || event.type || '';\n const sessionId = event.session_id || 'unknown';\n\n // Find parent nodes based on event relationships\n const allNodeEntries = Array.from(this.nodes.entries());\n\n // Tool call relationships\n if (eventType.includes('tool_call') && event.data?.tool_name) {\n // Connect tool calls to their invoking agent/PM nodes\n const parentNode = this.findParentNode(sessionId, ['PM', 'AGENT']);\n if (parentNode) {\n this.addEdge(parentNode, nodeId);\n return;\n }\n }\n\n // Agent delegation relationships\n if (eventType.includes('agent') || event.data?.agent_name) {\n // Connect agents to PM nodes\n const pmNode = this.findParentNode(sessionId, ['PM']);\n if (pmNode) {\n this.addEdge(pmNode, nodeId);\n return;\n }\n }\n\n // Todo relationships - connect to agent or PM nodes\n if (eventType.includes('todo')) {\n const parentNode = this.findParentNode(sessionId, ['AGENT', 'PM']);\n if (parentNode) {\n this.addEdge(parentNode, nodeId);\n return;\n }\n }\n\n // Default sequential relationship\n const allNodes = Array.from(this.nodes.keys());\n const currentIndex = allNodes.indexOf(nodeId);\n\n if (currentIndex > 0) {\n const previousNodeId = allNodes[currentIndex - 1];\n this.addEdge(previousNodeId, nodeId);\n }\n }\n\n /**\n * Find a parent node of specific types for the same session\n * @param {string} sessionId - Session ID\n * @param {Array} nodeTypes - Array of node types to search for\n * @returns {string|null} - Parent node ID or null\n */\n findParentNode(sessionId, nodeTypes) {\n const nodeEntries = Array.from(this.nodes.entries()).reverse(); // Start from most recent\n\n for (const [nodeId, nodeData] of nodeEntries) {\n if (nodeData.sessionId === sessionId && nodeTypes.includes(nodeData.type)) {\n return nodeId;\n }\n }\n\n return null;\n }\n\n /**\n * Highlight connected nodes\n * @param {Object} node - Cytoscape node object\n */\n highlightConnectedNodes(node) {\n if (!this.cy) return;\n\n // Reset all node styles\n this.cy.nodes().style({\n 'opacity': 0.3\n });\n\n this.cy.edges().style({\n 'opacity': 0.2\n });\n\n // Highlight selected node and its neighborhood\n const neighborhood = node.neighborhood();\n node.style('opacity', 1);\n neighborhood.style('opacity', 1);\n }\n\n /**\n * Reset layout\n */\n resetLayout() {\n if (this.cy) {\n this.cy.layout(this.layoutConfig).run();\n }\n }\n\n /**\n * Center view\n */\n centerView() {\n if (this.cy) {\n this.cy.fit();\n this.cy.center();\n }\n }\n\n /**\n * Run layout animation\n */\n runLayout() {\n console.log(`[HUD-VISUALIZER-DEBUG] runLayout called - isActive: ${this.isActive}, cy exists: ${!!this.cy}`);\n if (this.cy && this.isActive) {\n const nodeCount = this.cy.nodes().length;\n const edgeCount = this.cy.edges().length;\n console.log(`[HUD-VISUALIZER-DEBUG] Running layout with ${nodeCount} nodes and ${edgeCount} edges`);\n\n // Check container dimensions before layout\n if (this.container) {\n const rect = this.container.getBoundingClientRect();\n console.log(`[HUD-VISUALIZER-DEBUG] Container dimensions before layout:`, {\n width: rect.width,\n height: rect.height,\n offsetWidth: this.container.offsetWidth,\n offsetHeight: this.container.offsetHeight\n });\n }\n\n const layout = this.cy.layout(this.layoutConfig);\n\n // Listen for layout completion\n layout.on('layoutstop', () => {\n console.log(`[HUD-VISUALIZER-DEBUG] Layout completed. Final node positions:`);\n this.cy.nodes().forEach((node, index) => {\n const position = node.position();\n const data = node.data();\n console.log(`[HUD-VISUALIZER-DEBUG] Node ${index + 1}: ${data.label} at (${position.x.toFixed(1)}, ${position.y.toFixed(1)})`);\n });\n });\n\n layout.run();\n } else {\n console.log(`[HUD-VISUALIZER-DEBUG] Skipping layout - not active or no Cytoscape instance`);\n }\n }\n\n /**\n * Clear all nodes and edges\n */\n clear() {\n console.log(`[HUD-VISUALIZER-DEBUG] Clearing HUD: ${this.nodes.size} nodes, ${this.pendingEvents.length} pending events`);\n this.nodes.clear();\n this.pendingEvents = [];\n if (this.cy) {\n const elementCount = this.cy.elements().length;\n try {\n this.cy.elements().remove();\n console.log(`[HUD-VISUALIZER-DEBUG] Removed ${elementCount} Cytoscape elements`);\n } catch (error) {\n console.error(`[HUD-VISUALIZER-DEBUG] Error clearing Cytoscape elements:`, error);\n // Try to destroy and recreate if clearing fails\n try {\n this.cy.destroy();\n this.cy = null;\n console.log(`[HUD-VISUALIZER-DEBUG] Destroyed Cytoscape instance due to clear error`);\n } catch (destroyError) {\n console.error(`[HUD-VISUALIZER-DEBUG] Error destroying Cytoscape:`, destroyError);\n }\n }\n }\n }\n\n /**\n * Show loading indicator\n */\n showLoadingIndicator() {\n if (this.container) {\n this.container.innerHTML = `\n <div class=\"hud-loading-container\">\n <div class=\"hud-loading-spinner\"></div>\n <div class=\"hud-loading-text\">Loading HUD visualization libraries...</div>\n <div class=\"hud-loading-progress\" id=\"hud-loading-progress\"></div>\n </div>\n `;\n }\n }\n\n /**\n * Update loading progress\n */\n updateLoadingProgress(progress) {\n const progressElement = document.getElementById('hud-loading-progress');\n if (progressElement) {\n if (progress.error) {\n progressElement.innerHTML = `<span class=\"hud-error\">❌ ${progress.message}</span>`;\n } else {\n progressElement.innerHTML = `\n <div class=\"hud-progress-bar\">\n <div class=\"hud-progress-fill\" style=\"width: ${(progress.current / progress.total) * 100}%\"></div>\n </div>\n <div class=\"hud-progress-text\">${progress.message} (${progress.current}/${progress.total})</div>\n `;\n }\n }\n }\n\n /**\n * Hide loading indicator\n */\n hideLoadingIndicator() {\n if (this.container) {\n this.container.innerHTML = '';\n }\n }\n\n /**\n * Show loading error\n */\n showLoadingError(message) {\n if (this.container) {\n this.container.innerHTML = `\n <div class=\"hud-error-container\">\n <div class=\"hud-error-icon\">⚠️</div>\n <div class=\"hud-error-text\">Failed to load HUD libraries</div>\n <div class=\"hud-error-message\">${message}</div>\n <button class=\"hud-retry-button\" onclick=\"window.hudVisualizer && window.hudVisualizer.retryLoading()\">\n Retry Loading\n </button>\n </div>\n `;\n }\n }\n\n /**\n * Retry loading libraries (called from error UI)\n */\n retryLoading() {\n this.librariesLoaded = false;\n this.loadingPromise = null;\n this.activate();\n }\n\n /**\n * Debug method to manually test HUD visualizer\n * Can be called from browser console: window.hudVisualizer.debugTest()\n */\n debugTest() {\n console.log('[HUD-VISUALIZER-DEBUG] debugTest() called manually');\n console.log('[HUD-VISUALIZER-DEBUG] Current state:', {\n isActive: this.isActive,\n librariesLoaded: this.librariesLoaded,\n hasCy: !!this.cy,\n hasContainer: !!this.container,\n nodeCount: this.nodes.size,\n pendingEventCount: this.pendingEvents.length,\n hasHUDLibraryLoader: !!window.HUDLibraryLoader\n });\n\n // Test container\n if (this.container) {\n console.log('[HUD-VISUALIZER-DEBUG] Container info:', {\n id: this.container.id,\n className: this.container.className,\n offsetWidth: this.container.offsetWidth,\n offsetHeight: this.container.offsetHeight,\n innerHTML: this.container.innerHTML ? 'has content' : 'empty'\n });\n }\n\n // Test library availability\n console.log('[HUD-VISUALIZER-DEBUG] Library availability:', {\n cytoscape: typeof window.cytoscape,\n dagre: typeof window.dagre,\n cytoscapeDagre: typeof window.cytoscapeDagre,\n HUDLibraryLoader: typeof window.HUDLibraryLoader\n });\n\n return {\n isActive: this.isActive,\n librariesLoaded: this.librariesLoaded,\n hasCy: !!this.cy,\n containerFound: !!this.container\n };\n }\n\n /**\n * Comprehensive debug method to identify blank screen issues\n * Can be called from browser console: window.hudVisualizer.debugBlankScreen()\n */\n debugBlankScreen() {\n console.log('[HUD-BLANK-SCREEN-DEBUG] =================================');\n console.log('[HUD-BLANK-SCREEN-DEBUG] COMPREHENSIVE BLANK SCREEN DEBUG');\n console.log('[HUD-BLANK-SCREEN-DEBUG] =================================');\n\n // 1. Check basic state\n const basicState = {\n isActive: this.isActive,\n librariesLoaded: this.librariesLoaded,\n hasCy: !!this.cy,\n hasContainer: !!this.container,\n nodeCount: this.nodes.size,\n cytoscapeElementCount: this.cy ? this.cy.elements().length : 0\n };\n console.log('[HUD-BLANK-SCREEN-DEBUG] 1. Basic State:', basicState);\n\n // 2. Check container visibility and dimensions\n if (this.container) {\n const containerInfo = this.getContainerDebugInfo();\n console.log('[HUD-BLANK-SCREEN-DEBUG] 2. Container Info:', containerInfo);\n\n // Add background color to verify container is visible\n this.debugAddContainerBackground();\n } else {\n console.error('[HUD-BLANK-SCREEN-DEBUG] 2. Container not found!');\n return false;\n }\n\n // 3. Check Cytoscape state\n if (this.cy) {\n const cytoscapeInfo = this.getCytoscapeDebugInfo();\n console.log('[HUD-BLANK-SCREEN-DEBUG] 3. Cytoscape Info:', cytoscapeInfo);\n } else {\n console.error('[HUD-BLANK-SCREEN-DEBUG] 3. Cytoscape instance not found!');\n return false;\n }\n\n // 4. Check node positions\n this.debugNodePositions();\n\n // 5. Try manual rendering triggers\n this.debugManualRenderingTriggers();\n\n // 6. Add test nodes if none exist\n if (this.cy && this.cy.nodes().length === 0) {\n console.log('[HUD-BLANK-SCREEN-DEBUG] 6. No nodes found, adding test nodes...');\n this.debugAddTestNodes();\n }\n\n // 7. Force zoom fit\n this.debugForceZoomFit();\n\n console.log('[HUD-BLANK-SCREEN-DEBUG] Debug complete. Check visual results.');\n return true;\n }\n\n /**\n * Get comprehensive container debug information\n */\n getContainerDebugInfo() {\n const rect = this.container.getBoundingClientRect();\n const computed = window.getComputedStyle(this.container);\n\n return {\n id: this.container.id,\n className: this.container.className,\n // Dimensions\n offsetWidth: this.container.offsetWidth,\n offsetHeight: this.container.offsetHeight,\n clientWidth: this.container.clientWidth,\n clientHeight: this.container.clientHeight,\n scrollWidth: this.container.scrollWidth,\n scrollHeight: this.container.scrollHeight,\n // Bounding rect\n boundingRect: {\n width: rect.width,\n height: rect.height,\n top: rect.top,\n left: rect.left,\n bottom: rect.bottom,\n right: rect.right\n },\n // Computed styles that affect visibility\n computedStyles: {\n display: computed.display,\n visibility: computed.visibility,\n opacity: computed.opacity,\n position: computed.position,\n overflow: computed.overflow,\n zIndex: computed.zIndex,\n backgroundColor: computed.backgroundColor,\n transform: computed.transform\n },\n // Check if visible\n isVisible: rect.width > 0 && rect.height > 0 && computed.display !== 'none' && computed.visibility !== 'hidden',\n // Parent info\n parentElement: this.container.parentElement ? {\n tagName: this.container.parentElement.tagName,\n className: this.container.parentElement.className,\n offsetWidth: this.container.parentElement.offsetWidth,\n offsetHeight: this.container.parentElement.offsetHeight\n } : null\n };\n }\n\n /**\n * Get comprehensive Cytoscape debug information\n */\n getCytoscapeDebugInfo() {\n const extent = this.cy.extent();\n const zoom = this.cy.zoom();\n const pan = this.cy.pan();\n const viewport = this.cy.viewport();\n\n return {\n // Elements\n nodeCount: this.cy.nodes().length,\n edgeCount: this.cy.edges().length,\n elementCount: this.cy.elements().length,\n // Viewport\n zoom: zoom,\n pan: pan,\n extent: extent,\n viewport: viewport,\n // Container\n containerWidth: this.cy.width(),\n containerHeight: this.cy.height(),\n // Check if initialized\n isInitialized: this.cy.scratch('_cytoscape-initialized') !== undefined,\n // Renderer info\n renderer: this.cy.renderer() ? {\n name: this.cy.renderer().name,\n options: this.cy.renderer().options\n } : null\n };\n }\n\n /**\n * Debug node positions to check if they're outside viewport\n */\n debugNodePositions() {\n if (!this.cy || this.cy.nodes().length === 0) {\n console.log('[HUD-BLANK-SCREEN-DEBUG] 4. No nodes to check positions');\n return;\n }\n\n console.log('[HUD-BLANK-SCREEN-DEBUG] 4. Node Positions:');\n const nodes = this.cy.nodes();\n const extent = this.cy.extent();\n const viewport = this.cy.viewport();\n\n console.log('[HUD-BLANK-SCREEN-DEBUG] Viewport extent:', extent);\n console.log('[HUD-BLANK-SCREEN-DEBUG] Current viewport:', viewport);\n\n nodes.forEach((node, index) => {\n const position = node.position();\n const data = node.data();\n const boundingBox = node.boundingBox();\n\n console.log(`[HUD-BLANK-SCREEN-DEBUG] Node ${index + 1}:`, {\n id: data.id,\n label: data.label,\n position: position,\n boundingBox: boundingBox,\n isVisible: node.visible(),\n opacity: node.style('opacity'),\n width: node.style('width'),\n height: node.style('height')\n });\n });\n }\n\n /**\n * Add background color to container to verify it's visible\n */\n debugAddContainerBackground() {\n if (this.container) {\n this.container.style.backgroundColor = '#ff000020'; // Light red background\n this.container.style.border = '2px solid #ff0000'; // Red border\n this.container.style.minHeight = '400px'; // Ensure minimum height\n console.log('[HUD-BLANK-SCREEN-DEBUG] Added red background and border to container for visibility test');\n }\n }\n\n /**\n * Manual rendering triggers to force Cytoscape to render\n */\n debugManualRenderingTriggers() {\n if (!this.cy) {\n console.log('[HUD-BLANK-SCREEN-DEBUG] 5. No Cytoscape instance for manual rendering');\n return;\n }\n\n console.log('[HUD-BLANK-SCREEN-DEBUG] 5. Triggering manual rendering operations...');\n\n try {\n // Force resize\n console.log('[HUD-BLANK-SCREEN-DEBUG] - Forcing resize...');\n this.cy.resize();\n\n // Force redraw\n console.log('[HUD-BLANK-SCREEN-DEBUG] - Forcing redraw...');\n this.cy.forceRender();\n\n // Force layout\n if (this.cy.nodes().length > 0) {\n console.log('[HUD-BLANK-SCREEN-DEBUG] - Running layout...');\n this.cy.layout(this.layoutConfig).run();\n }\n\n // Force viewport update\n console.log('[HUD-BLANK-SCREEN-DEBUG] - Updating viewport...');\n this.cy.viewport({\n zoom: this.cy.zoom(),\n pan: this.cy.pan()\n });\n\n console.log('[HUD-BLANK-SCREEN-DEBUG] Manual rendering triggers completed');\n } catch (error) {\n console.error('[HUD-BLANK-SCREEN-DEBUG] Error during manual rendering:', error);\n }\n }\n\n /**\n * Add test nodes to verify Cytoscape is working\n */\n debugAddTestNodes() {\n if (!this.cy) return;\n\n console.log('[HUD-BLANK-SCREEN-DEBUG] Adding test nodes...');\n\n try {\n // Clear existing elements\n this.cy.elements().remove();\n\n // Add test nodes\n const testNodes = [\n {\n group: 'nodes',\n data: {\n id: 'test-node-1',\n label: '🤖 Test Node 1',\n color: '#48bb78',\n borderColor: '#38a169',\n shape: 'rectangle',\n width: 120,\n height: 40\n },\n classes: 'pm-node'\n },\n {\n group: 'nodes',\n data: {\n id: 'test-node-2',\n label: '🔧 Test Node 2',\n color: '#4299e1',\n borderColor: '#3182ce',\n shape: 'diamond',\n width: 80,\n height: 50\n },\n classes: 'tool-node'\n },\n {\n group: 'nodes',\n data: {\n id: 'test-node-3',\n label: '📝 Test Node 3',\n color: '#e53e3e',\n borderColor: '#c53030',\n shape: 'triangle',\n width: 70,\n height: 40\n },\n classes: 'todo-node'\n }\n ];\n\n // Add test edges\n const testEdges = [\n {\n group: 'edges',\n data: {\n id: 'test-edge-1',\n source: 'test-node-1',\n target: 'test-node-2'\n }\n },\n {\n group: 'edges',\n data: {\n id: 'test-edge-2',\n source: 'test-node-2',\n target: 'test-node-3'\n }\n }\n ];\n\n // Add elements to Cytoscape\n this.cy.add(testNodes);\n this.cy.add(testEdges);\n\n console.log('[HUD-BLANK-SCREEN-DEBUG] Added 3 test nodes and 2 test edges');\n\n // Update our internal nodes map\n testNodes.forEach(nodeElement => {\n this.nodes.set(nodeElement.data.id, nodeElement.data);\n });\n\n // Run layout\n this.runLayout();\n\n } catch (error) {\n console.error('[HUD-BLANK-SCREEN-DEBUG] Error adding test nodes:', error);\n }\n }\n\n /**\n * Force zoom fit after layout with multiple attempts\n */\n debugForceZoomFit() {\n if (!this.cy) return;\n\n console.log('[HUD-BLANK-SCREEN-DEBUG] 7. Forcing zoom fit...');\n\n const attemptZoomFit = (attemptNumber) => {\n try {\n console.log(`[HUD-BLANK-SCREEN-DEBUG] Zoom fit attempt ${attemptNumber}...`);\n\n // Get current state before fit\n const beforeZoom = this.cy.zoom();\n const beforePan = this.cy.pan();\n const elements = this.cy.elements();\n\n console.log('[HUD-BLANK-SCREEN-DEBUG] Before fit:', {\n zoom: beforeZoom,\n pan: beforePan,\n elementCount: elements.length\n });\n\n if (elements.length > 0) {\n // Try fit with specific options\n this.cy.fit(elements, 50); // 50px padding\n\n // Get state after fit\n const afterZoom = this.cy.zoom();\n const afterPan = this.cy.pan();\n\n console.log('[HUD-BLANK-SCREEN-DEBUG] After fit:', {\n zoom: afterZoom,\n pan: afterPan,\n changed: beforeZoom !== afterZoom || beforePan.x !== afterPan.x || beforePan.y !== afterPan.y\n });\n\n // Force center\n this.cy.center(elements);\n\n } else {\n console.log('[HUD-BLANK-SCREEN-DEBUG] No elements to fit');\n }\n\n } catch (error) {\n console.error(`[HUD-BLANK-SCREEN-DEBUG] Zoom fit attempt ${attemptNumber} failed:`, error);\n }\n };\n\n // Multiple attempts with delays\n attemptZoomFit(1);\n setTimeout(() => attemptZoomFit(2), 100);\n setTimeout(() => attemptZoomFit(3), 500);\n setTimeout(() => attemptZoomFit(4), 1000);\n }\n\n /**\n * Quick test to draw a simple shape to verify Cytoscape canvas is working\n */\n debugDrawSimpleShape() {\n if (!this.cy) {\n console.log('[HUD-CANVAS-TEST] No Cytoscape instance');\n return false;\n }\n\n console.log('[HUD-CANVAS-TEST] Testing Cytoscape canvas rendering...');\n\n try {\n // Clear everything\n this.cy.elements().remove();\n\n // Add a single, simple node at center\n this.cy.add({\n group: 'nodes',\n data: {\n id: 'canvas-test',\n label: '✅ CANVAS TEST',\n color: '#ff0000',\n borderColor: '#000000',\n width: 200,\n height: 100,\n shape: 'rectangle'\n },\n position: { x: 200, y: 200 } // Fixed position\n });\n\n // Force immediate render\n this.cy.forceRender();\n\n // Zoom to fit this single node\n this.cy.fit(this.cy.$('#canvas-test'), 50);\n\n console.log('[HUD-CANVAS-TEST] Canvas test node added and positioned');\n console.log('[HUD-CANVAS-TEST] If you see a red rectangle with \"CANVAS TEST\", rendering works!');\n\n return true;\n\n } catch (error) {\n console.error('[HUD-CANVAS-TEST] Canvas test failed:', error);\n return false;\n }\n }\n\n /**\n * Utility function to darken a color\n * @param {string} color - Hex color\n * @param {number} percent - Percentage to darken\n * @returns {string} - Darkened hex color\n */\n darkenColor(color, percent) {\n const num = parseInt(color.replace(\"#\", \"\"), 16);\n const amt = Math.round(2.55 * percent);\n const R = (num >> 16) - amt;\n const G = (num >> 8 & 0x00FF) - amt;\n const B = (num & 0x0000FF) - amt;\n return \"#\" + (0x1000000 + (R < 255 ? R < 1 ? 0 : R : 255) * 0x10000 +\n (G < 255 ? G < 1 ? 0 : G : 255) * 0x100 +\n (B < 255 ? B < 1 ? 0 : B : 255)).toString(16).slice(1);\n }\n}\n\n// Export for use in dashboard\nwindow.HUDVisualizer = HUDVisualizer;\n"],"names":["window","HUDVisualizer","constructor","this","cy","container","nodes","Map","isActive","librariesLoaded","loadingPromise","pendingEvents","layoutConfig","name","rankDir","animate","animationDuration","fit","padding","rankSep","nodeSep","nodeTypes","PM","color","shape","width","height","icon","AGENT","TOOL","TODO","initialize","document","getElementById","style","pointerEvents","cursor","position","zIndex","setupBasicEventHandlers","console","log","error","loadLibrariesAndInitialize","Promise","resolve","_performLazyLoading","showLoadingIndicator","HUDLibraryLoader","Error","loadHUDLibraries","progress","updateLoadingProgress","cytoscape","dagre","cytoscapeDagre","initializeCytoscape","setupCytoscapeEventHandlers","processPendingEvents","hideLoadingIndicator","stack","showLoadingError","message","use","elements","userZoomingEnabled","userPanningEnabled","boxSelectionEnabled","autoungrabify","autounselectify","selector","label","layout","setupResizeHandler","resetBtn","addEventListener","resetLayout","centerBtn","centerView","on","evt","node","target","data","highlightConnectedNodes","opacity","edges","warn","resizeObserver","ResizeObserver","ensureContainerResize","observe","ensureContainerInteractivity","containerRect","getBoundingClientRect","offsetWidth","offsetHeight","isVisible","resize","nodeCount","length","edgeCount","runLayout","userSelect","touchAction","parent","parentElement","activate","setTimeout","deactivate","event","_processEventInternal","processExistingEvents","events","Array","isArray","slice","forEach","i","timestamp","hook_event_name","type","subtype","session_id","data_session_id","data_keys","Object","keys","clear","sessionGroups","groupEventsBySession","entries","sessionId","sessionEvents","buildSessionTree","push","sessionNodes","sessionRootNode","sortedEvents","sort","a","b","Date","getTime","index","nodeData","createNodeFromEvent","addNode","id","eventData","isSessionRoot","set","createHierarchicalRelationships","eventType","now","nodeId","nodeType","timestampId","randomSuffix","Math","random","toString","substring","replace","promptPreview","prompt_preview","toolName","tool_name","cleanToolName","agent_type","agentName","agent_name","cleanAgentName","includes","level","toUpperCase","cleanEventType","parentNodeId","findRecentParentNode","addEdge","currentNodeId","nodeEntries","from","reverse","typePrefix","startsWith","processEvent","toISOString","createEventRelationships","has","borderColor","darkenColor","element","group","classes","toLowerCase","add","sourceId","targetId","edgeId","sourceNode","targetNode","source","parentNode","findParentNode","pmNode","allNodes","currentIndex","indexOf","previousNodeId","neighborhood","run","center","rect","x","toFixed","y","size","elementCount","remove","destroy","destroyError","innerHTML","progressElement","current","total","retryLoading","debugTest","hasCy","hasContainer","pendingEventCount","hasHUDLibraryLoader","className","containerFound","debugBlankScreen","basicState","cytoscapeElementCount","containerInfo","getContainerDebugInfo","debugAddContainerBackground","cytoscapeInfo","getCytoscapeDebugInfo","debugNodePositions","debugManualRenderingTriggers","debugAddTestNodes","debugForceZoomFit","computed","getComputedStyle","clientWidth","clientHeight","scrollWidth","scrollHeight","boundingRect","top","left","bottom","right","computedStyles","display","visibility","overflow","backgroundColor","transform","tagName","extent","zoom","pan","viewport","containerWidth","containerHeight","isInitialized","scratch","renderer","options","boundingBox","visible","border","minHeight","forceRender","testNodes","testEdges","nodeElement","attemptZoomFit","attemptNumber","beforeZoom","beforePan","afterZoom","afterPan","changed","debugDrawSimpleShape","$","percent","num","parseInt","amt","round","R","G","B"],"mappings":"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"}