claude-mpm 4.24.0__py3-none-any.whl → 5.0.9__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.

Potentially problematic release.


This version of claude-mpm might be problematic. Click here for more details.

Files changed (502) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_PM.md +12 -0
  3. claude_mpm/agents/OUTPUT_STYLE.md +3 -48
  4. claude_mpm/agents/PM_INSTRUCTIONS.md +721 -911
  5. claude_mpm/agents/PM_INSTRUCTIONS_TEACH.md +1322 -0
  6. claude_mpm/agents/WORKFLOW.md +4 -4
  7. claude_mpm/agents/__init__.py +6 -0
  8. claude_mpm/agents/agent_loader.py +1 -4
  9. claude_mpm/agents/base_agent.json +6 -3
  10. claude_mpm/agents/base_agent_loader.py +10 -35
  11. claude_mpm/agents/frontmatter_validator.py +1 -1
  12. claude_mpm/agents/templates/{circuit_breakers.md → circuit-breakers.md} +370 -3
  13. claude_mpm/agents/templates/context-management-examples.md +544 -0
  14. claude_mpm/agents/templates/{pm_red_flags.md → pm-red-flags.md} +48 -0
  15. claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
  16. claude_mpm/agents/templates/research-gate-examples.md +669 -0
  17. claude_mpm/agents/templates/structured-questions-examples.md +615 -0
  18. claude_mpm/agents/templates/ticket-completeness-examples.md +139 -0
  19. claude_mpm/agents/templates/ticketing-examples.md +277 -0
  20. claude_mpm/cli/__init__.py +38 -2
  21. claude_mpm/cli/commands/__init__.py +2 -0
  22. claude_mpm/cli/commands/agent_source.py +774 -0
  23. claude_mpm/cli/commands/agent_state_manager.py +188 -30
  24. claude_mpm/cli/commands/agents.py +959 -36
  25. claude_mpm/cli/commands/agents_cleanup.py +210 -0
  26. claude_mpm/cli/commands/agents_discover.py +338 -0
  27. claude_mpm/cli/commands/aggregate.py +1 -1
  28. claude_mpm/cli/commands/analyze.py +3 -3
  29. claude_mpm/cli/commands/auto_configure.py +2 -6
  30. claude_mpm/cli/commands/config.py +7 -4
  31. claude_mpm/cli/commands/configure.py +769 -45
  32. claude_mpm/cli/commands/configure_agent_display.py +4 -4
  33. claude_mpm/cli/commands/configure_navigation.py +63 -46
  34. claude_mpm/cli/commands/debug.py +12 -12
  35. claude_mpm/cli/commands/doctor.py +10 -2
  36. claude_mpm/cli/commands/hook_errors.py +277 -0
  37. claude_mpm/cli/commands/local_deploy.py +1 -4
  38. claude_mpm/cli/commands/mcp_install_commands.py +1 -1
  39. claude_mpm/cli/commands/mpm_init/core.py +49 -1
  40. claude_mpm/cli/commands/mpm_init/git_activity.py +10 -10
  41. claude_mpm/cli/commands/mpm_init/prompts.py +6 -6
  42. claude_mpm/cli/commands/postmortem.py +401 -0
  43. claude_mpm/cli/commands/run.py +123 -165
  44. claude_mpm/cli/commands/skill_source.py +694 -0
  45. claude_mpm/cli/commands/skills.py +757 -20
  46. claude_mpm/cli/executor.py +78 -3
  47. claude_mpm/cli/interactive/agent_wizard.py +955 -45
  48. claude_mpm/cli/parsers/agent_source_parser.py +171 -0
  49. claude_mpm/cli/parsers/agents_parser.py +256 -4
  50. claude_mpm/cli/parsers/base_parser.py +53 -0
  51. claude_mpm/cli/parsers/config_parser.py +96 -43
  52. claude_mpm/cli/parsers/skill_source_parser.py +169 -0
  53. claude_mpm/cli/parsers/skills_parser.py +145 -0
  54. claude_mpm/cli/parsers/source_parser.py +138 -0
  55. claude_mpm/cli/startup.py +538 -106
  56. claude_mpm/cli/startup_display.py +480 -0
  57. claude_mpm/cli/utils.py +1 -1
  58. claude_mpm/cli_module/commands.py +1 -1
  59. claude_mpm/commands/{mpm-auto-configure.md → mpm-agents-auto-configure.md} +9 -0
  60. claude_mpm/commands/mpm-agents-detect.md +9 -0
  61. claude_mpm/commands/{mpm-agents.md → mpm-agents-list.md} +9 -0
  62. claude_mpm/commands/mpm-agents-recommend.md +9 -0
  63. claude_mpm/commands/{mpm-config.md → mpm-config-view.md} +9 -0
  64. claude_mpm/commands/mpm-doctor.md +9 -0
  65. claude_mpm/commands/mpm-help.md +14 -2
  66. claude_mpm/commands/mpm-init.md +27 -2
  67. claude_mpm/commands/mpm-monitor.md +9 -0
  68. claude_mpm/commands/mpm-postmortem.md +123 -0
  69. claude_mpm/commands/{mpm-resume.md → mpm-session-resume.md} +9 -0
  70. claude_mpm/commands/mpm-status.md +9 -0
  71. claude_mpm/commands/{mpm-organize.md → mpm-ticket-organize.md} +9 -0
  72. claude_mpm/commands/mpm-ticket-view.md +552 -0
  73. claude_mpm/commands/mpm-version.md +9 -0
  74. claude_mpm/commands/mpm.md +10 -0
  75. claude_mpm/config/agent_presets.py +488 -0
  76. claude_mpm/config/agent_sources.py +325 -0
  77. claude_mpm/config/skill_presets.py +392 -0
  78. claude_mpm/config/skill_sources.py +590 -0
  79. claude_mpm/constants.py +13 -0
  80. claude_mpm/core/claude_runner.py +5 -34
  81. claude_mpm/core/config.py +16 -0
  82. claude_mpm/core/constants.py +1 -1
  83. claude_mpm/core/framework/__init__.py +3 -16
  84. claude_mpm/core/framework/loaders/file_loader.py +54 -101
  85. claude_mpm/core/framework/loaders/instruction_loader.py +25 -5
  86. claude_mpm/core/hook_error_memory.py +381 -0
  87. claude_mpm/core/hook_manager.py +41 -2
  88. claude_mpm/core/interactive_session.py +91 -10
  89. claude_mpm/core/logger.py +3 -1
  90. claude_mpm/core/oneshot_session.py +71 -8
  91. claude_mpm/core/protocols/__init__.py +23 -0
  92. claude_mpm/core/protocols/runner_protocol.py +103 -0
  93. claude_mpm/core/protocols/session_protocol.py +131 -0
  94. claude_mpm/core/shared/singleton_manager.py +11 -4
  95. claude_mpm/core/system_context.py +38 -0
  96. claude_mpm/dashboard/static/css/activity.css +69 -69
  97. claude_mpm/dashboard/static/css/connection-status.css +10 -10
  98. claude_mpm/dashboard/static/css/dashboard.css +15 -15
  99. claude_mpm/dashboard/static/js/components/activity-tree.js +178 -178
  100. claude_mpm/dashboard/static/js/components/agent-hierarchy.js +101 -101
  101. claude_mpm/dashboard/static/js/components/agent-inference.js +31 -31
  102. claude_mpm/dashboard/static/js/components/build-tracker.js +59 -59
  103. claude_mpm/dashboard/static/js/components/code-simple.js +107 -107
  104. claude_mpm/dashboard/static/js/components/connection-debug.js +101 -101
  105. claude_mpm/dashboard/static/js/components/diff-viewer.js +113 -113
  106. claude_mpm/dashboard/static/js/components/event-viewer.js +12 -12
  107. claude_mpm/dashboard/static/js/components/file-change-tracker.js +57 -57
  108. claude_mpm/dashboard/static/js/components/file-change-viewer.js +74 -74
  109. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +6 -6
  110. claude_mpm/dashboard/static/js/components/file-viewer.js +42 -42
  111. claude_mpm/dashboard/static/js/components/module-viewer.js +27 -27
  112. claude_mpm/dashboard/static/js/components/session-manager.js +14 -14
  113. claude_mpm/dashboard/static/js/components/socket-manager.js +1 -1
  114. claude_mpm/dashboard/static/js/components/ui-state-manager.js +14 -14
  115. claude_mpm/dashboard/static/js/components/unified-data-viewer.js +110 -110
  116. claude_mpm/dashboard/static/js/components/working-directory.js +8 -8
  117. claude_mpm/dashboard/static/js/connection-manager.js +76 -76
  118. claude_mpm/dashboard/static/js/dashboard.js +76 -58
  119. claude_mpm/dashboard/static/js/extension-error-handler.js +22 -22
  120. claude_mpm/dashboard/static/js/socket-client.js +138 -121
  121. claude_mpm/dashboard/templates/code_simple.html +23 -23
  122. claude_mpm/dashboard/templates/index.html +18 -18
  123. claude_mpm/experimental/cli_enhancements.py +1 -5
  124. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-313.pyc +0 -0
  125. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-313.pyc +0 -0
  126. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-313.pyc +0 -0
  127. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-313.pyc +0 -0
  128. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-313.pyc +0 -0
  129. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-313.pyc +0 -0
  130. claude_mpm/hooks/claude_hooks/event_handlers.py +3 -1
  131. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-313.pyc +0 -0
  132. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-313.pyc +0 -0
  133. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-313.pyc +0 -0
  134. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-313.pyc +0 -0
  135. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-313.pyc +0 -0
  136. claude_mpm/hooks/failure_learning/__init__.py +2 -8
  137. claude_mpm/hooks/failure_learning/failure_detection_hook.py +1 -6
  138. claude_mpm/hooks/failure_learning/fix_detection_hook.py +1 -6
  139. claude_mpm/hooks/failure_learning/learning_extraction_hook.py +1 -6
  140. claude_mpm/hooks/kuzu_response_hook.py +1 -5
  141. claude_mpm/models/git_repository.py +198 -0
  142. claude_mpm/scripts/claude-hook-handler.sh +3 -3
  143. claude_mpm/scripts/start_activity_logging.py +3 -1
  144. claude_mpm/services/agents/agent_builder.py +45 -9
  145. claude_mpm/services/agents/agent_preset_service.py +238 -0
  146. claude_mpm/services/agents/agent_selection_service.py +484 -0
  147. claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
  148. claude_mpm/services/agents/cache_git_manager.py +621 -0
  149. claude_mpm/services/agents/deployment/agent_deployment.py +126 -2
  150. claude_mpm/services/agents/deployment/agent_discovery_service.py +105 -73
  151. claude_mpm/services/agents/deployment/agent_format_converter.py +1 -1
  152. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +1 -5
  153. claude_mpm/services/agents/deployment/agent_metrics_collector.py +3 -3
  154. claude_mpm/services/agents/deployment/agent_restore_handler.py +1 -4
  155. claude_mpm/services/agents/deployment/agent_template_builder.py +236 -15
  156. claude_mpm/services/agents/deployment/agents_directory_resolver.py +101 -15
  157. claude_mpm/services/agents/deployment/async_agent_deployment.py +2 -1
  158. claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -3
  159. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +115 -15
  160. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +2 -2
  161. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +1 -4
  162. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +363 -0
  163. claude_mpm/services/agents/deployment/single_agent_deployer.py +2 -2
  164. claude_mpm/services/agents/deployment/system_instructions_deployer.py +168 -46
  165. claude_mpm/services/agents/deployment/validation/deployment_validator.py +2 -2
  166. claude_mpm/services/agents/git_source_manager.py +629 -0
  167. claude_mpm/services/agents/loading/framework_agent_loader.py +9 -12
  168. claude_mpm/services/agents/local_template_manager.py +50 -10
  169. claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
  170. claude_mpm/services/agents/sources/__init__.py +13 -0
  171. claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
  172. claude_mpm/services/agents/sources/git_source_sync_service.py +1087 -0
  173. claude_mpm/services/agents/startup_sync.py +239 -0
  174. claude_mpm/services/agents/toolchain_detector.py +474 -0
  175. claude_mpm/services/analysis/__init__.py +25 -0
  176. claude_mpm/services/analysis/postmortem_reporter.py +474 -0
  177. claude_mpm/services/analysis/postmortem_service.py +765 -0
  178. claude_mpm/services/cli/session_pause_manager.py +1 -1
  179. claude_mpm/services/command_deployment_service.py +200 -6
  180. claude_mpm/services/core/base.py +7 -2
  181. claude_mpm/services/core/interfaces/__init__.py +1 -3
  182. claude_mpm/services/core/interfaces/health.py +1 -4
  183. claude_mpm/services/core/models/__init__.py +2 -11
  184. claude_mpm/services/diagnostics/checks/__init__.py +4 -0
  185. claude_mpm/services/diagnostics/checks/agent_check.py +0 -2
  186. claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
  187. claude_mpm/services/diagnostics/checks/instructions_check.py +1 -2
  188. claude_mpm/services/diagnostics/checks/mcp_check.py +0 -1
  189. claude_mpm/services/diagnostics/checks/mcp_services_check.py +7 -15
  190. claude_mpm/services/diagnostics/checks/monitor_check.py +0 -1
  191. claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
  192. claude_mpm/services/diagnostics/diagnostic_runner.py +9 -0
  193. claude_mpm/services/diagnostics/doctor_reporter.py +40 -10
  194. claude_mpm/services/event_bus/direct_relay.py +3 -3
  195. claude_mpm/services/events/consumers/logging.py +1 -2
  196. claude_mpm/services/git/__init__.py +21 -0
  197. claude_mpm/services/git/git_operations_service.py +494 -0
  198. claude_mpm/services/github/__init__.py +21 -0
  199. claude_mpm/services/github/github_cli_service.py +397 -0
  200. claude_mpm/services/infrastructure/monitoring/__init__.py +1 -5
  201. claude_mpm/services/infrastructure/monitoring/aggregator.py +1 -6
  202. claude_mpm/services/instructions/__init__.py +9 -0
  203. claude_mpm/services/instructions/instruction_cache_service.py +374 -0
  204. claude_mpm/services/local_ops/__init__.py +3 -13
  205. claude_mpm/services/local_ops/health_checks/__init__.py +1 -3
  206. claude_mpm/services/local_ops/health_manager.py +1 -4
  207. claude_mpm/services/local_ops/resource_monitor.py +1 -1
  208. claude_mpm/services/mcp_config_manager.py +75 -145
  209. claude_mpm/services/mcp_gateway/config/configuration.py +1 -1
  210. claude_mpm/services/mcp_gateway/core/process_pool.py +22 -16
  211. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +1 -6
  212. claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -2
  213. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +6 -2
  214. claude_mpm/services/mcp_service_verifier.py +6 -3
  215. claude_mpm/services/model/model_router.py +1 -2
  216. claude_mpm/services/monitor/daemon.py +29 -9
  217. claude_mpm/services/monitor/daemon_manager.py +96 -19
  218. claude_mpm/services/monitor/server.py +2 -2
  219. claude_mpm/services/port_manager.py +1 -1
  220. claude_mpm/services/pr/__init__.py +14 -0
  221. claude_mpm/services/pr/pr_template_service.py +329 -0
  222. claude_mpm/services/project/documentation_manager.py +2 -1
  223. claude_mpm/services/project/toolchain_analyzer.py +3 -1
  224. claude_mpm/services/runner_configuration_service.py +16 -3
  225. claude_mpm/services/session_management_service.py +16 -4
  226. claude_mpm/services/skills/__init__.py +18 -0
  227. claude_mpm/services/skills/git_skill_source_manager.py +1169 -0
  228. claude_mpm/services/skills/skill_discovery_service.py +568 -0
  229. claude_mpm/services/skills_config.py +547 -0
  230. claude_mpm/services/skills_deployer.py +955 -0
  231. claude_mpm/services/socketio/handlers/connection.py +1 -1
  232. claude_mpm/services/socketio/handlers/git.py +1 -1
  233. claude_mpm/services/socketio/server/core.py +1 -4
  234. claude_mpm/services/socketio/server/main.py +1 -3
  235. claude_mpm/services/system_instructions_service.py +1 -3
  236. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +0 -3
  237. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +0 -1
  238. claude_mpm/services/unified/deployment_strategies/vercel.py +1 -5
  239. claude_mpm/services/unified/unified_deployment.py +1 -5
  240. claude_mpm/services/version_control/conflict_resolution.py +6 -4
  241. claude_mpm/services/visualization/__init__.py +1 -5
  242. claude_mpm/services/visualization/mermaid_generator.py +2 -3
  243. claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +2 -2
  244. claude_mpm/skills/skills_registry.py +0 -1
  245. claude_mpm/templates/questions/__init__.py +38 -0
  246. claude_mpm/templates/questions/base.py +193 -0
  247. claude_mpm/templates/questions/pr_strategy.py +311 -0
  248. claude_mpm/templates/questions/project_init.py +385 -0
  249. claude_mpm/templates/questions/ticket_mgmt.py +394 -0
  250. claude_mpm/tools/__main__.py +8 -8
  251. claude_mpm/utils/agent_dependency_loader.py +77 -10
  252. claude_mpm/utils/agent_filters.py +288 -0
  253. claude_mpm/utils/dependency_cache.py +3 -1
  254. claude_mpm/utils/gitignore.py +241 -0
  255. claude_mpm/utils/migration.py +372 -0
  256. claude_mpm/utils/progress.py +387 -0
  257. claude_mpm/utils/robust_installer.py +2 -4
  258. claude_mpm/utils/structured_questions.py +619 -0
  259. {claude_mpm-4.24.0.dist-info → claude_mpm-5.0.9.dist-info}/METADATA +396 -43
  260. {claude_mpm-4.24.0.dist-info → claude_mpm-5.0.9.dist-info}/RECORD +268 -422
  261. claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -17
  262. claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +0 -3
  263. claude_mpm/agents/templates/agent-manager.json +0 -273
  264. claude_mpm/agents/templates/agentic-coder-optimizer.json +0 -248
  265. claude_mpm/agents/templates/api_qa.json +0 -183
  266. claude_mpm/agents/templates/clerk-ops.json +0 -235
  267. claude_mpm/agents/templates/code_analyzer.json +0 -101
  268. claude_mpm/agents/templates/content-agent.json +0 -358
  269. claude_mpm/agents/templates/dart_engineer.json +0 -307
  270. claude_mpm/agents/templates/data_engineer.json +0 -225
  271. claude_mpm/agents/templates/documentation.json +0 -238
  272. claude_mpm/agents/templates/engineer.json +0 -210
  273. claude_mpm/agents/templates/gcp_ops_agent.json +0 -253
  274. claude_mpm/agents/templates/golang_engineer.json +0 -270
  275. claude_mpm/agents/templates/imagemagick.json +0 -264
  276. claude_mpm/agents/templates/java_engineer.json +0 -346
  277. claude_mpm/agents/templates/javascript_engineer_agent.json +0 -380
  278. claude_mpm/agents/templates/local_ops_agent.json +0 -1840
  279. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +0 -39
  280. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +0 -400
  281. claude_mpm/agents/templates/memory_manager.json +0 -158
  282. claude_mpm/agents/templates/nextjs_engineer.json +0 -285
  283. claude_mpm/agents/templates/ops.json +0 -185
  284. claude_mpm/agents/templates/php-engineer.json +0 -287
  285. claude_mpm/agents/templates/product_owner.json +0 -338
  286. claude_mpm/agents/templates/project_organizer.json +0 -144
  287. claude_mpm/agents/templates/prompt-engineer.json +0 -737
  288. claude_mpm/agents/templates/python_engineer.json +0 -387
  289. claude_mpm/agents/templates/qa.json +0 -243
  290. claude_mpm/agents/templates/react_engineer.json +0 -239
  291. claude_mpm/agents/templates/refactoring_engineer.json +0 -276
  292. claude_mpm/agents/templates/research.json +0 -188
  293. claude_mpm/agents/templates/ruby-engineer.json +0 -280
  294. claude_mpm/agents/templates/rust_engineer.json +0 -275
  295. claude_mpm/agents/templates/security.json +0 -202
  296. claude_mpm/agents/templates/svelte-engineer.json +0 -225
  297. claude_mpm/agents/templates/tauri_engineer.json +0 -274
  298. claude_mpm/agents/templates/ticketing.json +0 -178
  299. claude_mpm/agents/templates/typescript_engineer.json +0 -285
  300. claude_mpm/agents/templates/vercel_ops_agent.json +0 -412
  301. claude_mpm/agents/templates/version_control.json +0 -159
  302. claude_mpm/agents/templates/web_qa.json +0 -400
  303. claude_mpm/agents/templates/web_ui.json +0 -189
  304. claude_mpm/commands/mpm-tickets.md +0 -151
  305. claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
  306. claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +0 -188
  307. claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +0 -156
  308. claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +0 -38
  309. claude_mpm/dashboard/react/components/shared/FilterBar.module.css +0 -92
  310. claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +0 -248
  311. claude_mpm/dashboard/static/archive/activity_dashboard_test.html +0 -61
  312. claude_mpm/dashboard/static/archive/test_activity_connection.html +0 -179
  313. claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +0 -68
  314. claude_mpm/dashboard/static/archive/test_dashboard.html +0 -409
  315. claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +0 -519
  316. claude_mpm/dashboard/static/archive/test_dashboard_verification.html +0 -181
  317. claude_mpm/dashboard/static/archive/test_file_data.html +0 -315
  318. claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +0 -243
  319. claude_mpm/dashboard/static/archive/test_file_tree_fix.html +0 -234
  320. claude_mpm/dashboard/static/archive/test_file_tree_rename.html +0 -117
  321. claude_mpm/dashboard/static/archive/test_file_tree_tab.html +0 -115
  322. claude_mpm/dashboard/static/archive/test_file_viewer.html +0 -224
  323. claude_mpm/dashboard/static/archive/test_final_activity.html +0 -220
  324. claude_mpm/dashboard/static/archive/test_tab_fix.html +0 -139
  325. claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +0 -1
  326. claude_mpm/dashboard/static/built/components/activity-tree.js +0 -2
  327. claude_mpm/dashboard/static/built/components/agent-hierarchy.js +0 -777
  328. claude_mpm/dashboard/static/built/components/agent-inference.js +0 -2
  329. claude_mpm/dashboard/static/built/components/build-tracker.js +0 -333
  330. claude_mpm/dashboard/static/built/components/code-simple.js +0 -857
  331. claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +0 -353
  332. claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +0 -235
  333. claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +0 -409
  334. claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +0 -435
  335. claude_mpm/dashboard/static/built/components/code-tree.js +0 -2
  336. claude_mpm/dashboard/static/built/components/code-viewer.js +0 -2
  337. claude_mpm/dashboard/static/built/components/connection-debug.js +0 -654
  338. claude_mpm/dashboard/static/built/components/diff-viewer.js +0 -891
  339. claude_mpm/dashboard/static/built/components/event-processor.js +0 -2
  340. claude_mpm/dashboard/static/built/components/event-viewer.js +0 -2
  341. claude_mpm/dashboard/static/built/components/export-manager.js +0 -2
  342. claude_mpm/dashboard/static/built/components/file-change-tracker.js +0 -443
  343. claude_mpm/dashboard/static/built/components/file-change-viewer.js +0 -690
  344. claude_mpm/dashboard/static/built/components/file-tool-tracker.js +0 -2
  345. claude_mpm/dashboard/static/built/components/file-viewer.js +0 -2
  346. claude_mpm/dashboard/static/built/components/hud-library-loader.js +0 -2
  347. claude_mpm/dashboard/static/built/components/hud-manager.js +0 -2
  348. claude_mpm/dashboard/static/built/components/hud-visualizer.js +0 -2
  349. claude_mpm/dashboard/static/built/components/module-viewer.js +0 -2
  350. claude_mpm/dashboard/static/built/components/nav-bar.js +0 -145
  351. claude_mpm/dashboard/static/built/components/page-structure.js +0 -429
  352. claude_mpm/dashboard/static/built/components/session-manager.js +0 -2
  353. claude_mpm/dashboard/static/built/components/socket-manager.js +0 -2
  354. claude_mpm/dashboard/static/built/components/ui-state-manager.js +0 -2
  355. claude_mpm/dashboard/static/built/components/unified-data-viewer.js +0 -2
  356. claude_mpm/dashboard/static/built/components/working-directory.js +0 -2
  357. claude_mpm/dashboard/static/built/connection-manager.js +0 -536
  358. claude_mpm/dashboard/static/built/dashboard.js +0 -2
  359. claude_mpm/dashboard/static/built/extension-error-handler.js +0 -164
  360. claude_mpm/dashboard/static/built/react/events.js +0 -30
  361. claude_mpm/dashboard/static/built/shared/dom-helpers.js +0 -396
  362. claude_mpm/dashboard/static/built/shared/event-bus.js +0 -330
  363. claude_mpm/dashboard/static/built/shared/event-filter-service.js +0 -540
  364. claude_mpm/dashboard/static/built/shared/logger.js +0 -385
  365. claude_mpm/dashboard/static/built/shared/page-structure.js +0 -249
  366. claude_mpm/dashboard/static/built/shared/tooltip-service.js +0 -253
  367. claude_mpm/dashboard/static/built/socket-client.js +0 -2
  368. claude_mpm/dashboard/static/built/tab-isolation-fix.js +0 -185
  369. claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +0 -1
  370. claude_mpm/dashboard/static/dist/components/activity-tree.js +0 -2
  371. claude_mpm/dashboard/static/dist/components/agent-inference.js +0 -2
  372. claude_mpm/dashboard/static/dist/components/code-tree.js +0 -2
  373. claude_mpm/dashboard/static/dist/components/code-viewer.js +0 -2
  374. claude_mpm/dashboard/static/dist/components/event-processor.js +0 -2
  375. claude_mpm/dashboard/static/dist/components/event-viewer.js +0 -2
  376. claude_mpm/dashboard/static/dist/components/export-manager.js +0 -2
  377. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +0 -2
  378. claude_mpm/dashboard/static/dist/components/file-viewer.js +0 -2
  379. claude_mpm/dashboard/static/dist/components/hud-library-loader.js +0 -2
  380. claude_mpm/dashboard/static/dist/components/hud-manager.js +0 -2
  381. claude_mpm/dashboard/static/dist/components/hud-visualizer.js +0 -2
  382. claude_mpm/dashboard/static/dist/components/module-viewer.js +0 -2
  383. claude_mpm/dashboard/static/dist/components/session-manager.js +0 -2
  384. claude_mpm/dashboard/static/dist/components/socket-manager.js +0 -2
  385. claude_mpm/dashboard/static/dist/components/ui-state-manager.js +0 -2
  386. claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +0 -2
  387. claude_mpm/dashboard/static/dist/components/working-directory.js +0 -2
  388. claude_mpm/dashboard/static/dist/dashboard.js +0 -2
  389. claude_mpm/dashboard/static/dist/react/events.js +0 -30
  390. claude_mpm/dashboard/static/dist/socket-client.js +0 -2
  391. claude_mpm/dashboard/static/events.html +0 -607
  392. claude_mpm/dashboard/static/index.html +0 -635
  393. claude_mpm/dashboard/static/js/shared/dom-helpers.js +0 -396
  394. claude_mpm/dashboard/static/js/shared/event-bus.js +0 -330
  395. claude_mpm/dashboard/static/js/shared/logger.js +0 -385
  396. claude_mpm/dashboard/static/js/shared/tooltip-service.js +0 -253
  397. claude_mpm/dashboard/static/js/stores/dashboard-store.js +0 -562
  398. claude_mpm/dashboard/static/legacy/activity.html +0 -736
  399. claude_mpm/dashboard/static/legacy/agents.html +0 -786
  400. claude_mpm/dashboard/static/legacy/files.html +0 -747
  401. claude_mpm/dashboard/static/legacy/tools.html +0 -831
  402. claude_mpm/dashboard/static/monitors.html +0 -431
  403. claude_mpm/dashboard/static/production/events.html +0 -659
  404. claude_mpm/dashboard/static/production/main.html +0 -698
  405. claude_mpm/dashboard/static/production/monitors.html +0 -483
  406. claude_mpm/dashboard/static/test-archive/dashboard.html +0 -635
  407. claude_mpm/dashboard/static/test-archive/debug-events.html +0 -147
  408. claude_mpm/dashboard/static/test-archive/test-navigation.html +0 -256
  409. claude_mpm/dashboard/static/test-archive/test-react-exports.html +0 -180
  410. claude_mpm/dashboard/static/test-archive/test_debug.html +0 -25
  411. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +0 -79
  412. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +0 -178
  413. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +0 -577
  414. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +0 -467
  415. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +0 -537
  416. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +0 -730
  417. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +0 -112
  418. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +0 -146
  419. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +0 -412
  420. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +0 -81
  421. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +0 -362
  422. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +0 -312
  423. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +0 -152
  424. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +0 -668
  425. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +0 -587
  426. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +0 -438
  427. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +0 -391
  428. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +0 -119
  429. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +0 -148
  430. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +0 -483
  431. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +0 -452
  432. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +0 -449
  433. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +0 -411
  434. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +0 -14
  435. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +0 -58
  436. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +0 -68
  437. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +0 -69
  438. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +0 -131
  439. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +0 -325
  440. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +0 -490
  441. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +0 -425
  442. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +0 -499
  443. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +0 -86
  444. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +0 -43
  445. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +0 -47
  446. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +0 -65
  447. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +0 -30
  448. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +0 -16
  449. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +0 -160
  450. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +0 -412
  451. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +0 -602
  452. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +0 -915
  453. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +0 -916
  454. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +0 -752
  455. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +0 -1237
  456. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +0 -189
  457. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +0 -500
  458. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +0 -464
  459. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +0 -619
  460. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +0 -437
  461. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +0 -231
  462. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +0 -170
  463. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +0 -602
  464. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +0 -821
  465. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +0 -742
  466. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +0 -726
  467. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +0 -764
  468. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +0 -831
  469. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +0 -226
  470. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +0 -901
  471. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +0 -901
  472. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +0 -775
  473. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +0 -937
  474. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +0 -770
  475. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +0 -961
  476. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +0 -119
  477. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +0 -253
  478. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +0 -145
  479. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +0 -543
  480. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +0 -741
  481. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +0 -470
  482. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +0 -458
  483. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +0 -639
  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/SKILL.md +0 -184
  490. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +0 -459
  491. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +0 -479
  492. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +0 -687
  493. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +0 -758
  494. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +0 -868
  495. /claude_mpm/agents/templates/{git_file_tracking.md → git-file-tracking.md} +0 -0
  496. /claude_mpm/agents/templates/{pm_examples.md → pm-examples.md} +0 -0
  497. /claude_mpm/agents/templates/{response_format.md → response-format.md} +0 -0
  498. /claude_mpm/agents/templates/{validation_templates.md → validation-templates.md} +0 -0
  499. {claude_mpm-4.24.0.dist-info → claude_mpm-5.0.9.dist-info}/WHEEL +0 -0
  500. {claude_mpm-4.24.0.dist-info → claude_mpm-5.0.9.dist-info}/entry_points.txt +0 -0
  501. {claude_mpm-4.24.0.dist-info → claude_mpm-5.0.9.dist-info}/licenses/LICENSE +0 -0
  502. {claude_mpm-4.24.0.dist-info → claude_mpm-5.0.9.dist-info}/top_level.txt +0 -0
@@ -1,253 +0,0 @@
1
- /**
2
- * Unified Tooltip Service
3
- *
4
- * Provides a consistent tooltip implementation for all dashboard components.
5
- * Supports different tooltip types and behaviors.
6
- *
7
- * @module tooltip-service
8
- */
9
-
10
- class TooltipService {
11
- constructor() {
12
- this.tooltips = new Map();
13
- this.defaultOptions = {
14
- className: 'dashboard-tooltip',
15
- duration: 200,
16
- offset: { x: 10, y: -28 },
17
- hideDelay: 500
18
- };
19
- }
20
-
21
- /**
22
- * Create a new tooltip instance
23
- * @param {string} id - Unique identifier for the tooltip
24
- * @param {Object} options - Configuration options
25
- * @returns {Object} Tooltip instance
26
- */
27
- create(id, options = {}) {
28
- const config = { ...this.defaultOptions, ...options };
29
-
30
- // Check if tooltip already exists
31
- if (this.tooltips.has(id)) {
32
- return this.tooltips.get(id);
33
- }
34
-
35
- // Create tooltip element
36
- const tooltip = d3.select('body').append('div')
37
- .attr('class', config.className)
38
- .style('opacity', 0)
39
- .style('position', 'absolute')
40
- .style('pointer-events', 'none')
41
- .style('background', 'rgba(0, 0, 0, 0.8)')
42
- .style('color', '#fff')
43
- .style('padding', '8px 12px')
44
- .style('border-radius', '4px')
45
- .style('font-size', '12px')
46
- .style('font-family', 'system-ui, -apple-system, sans-serif')
47
- .style('z-index', '10000');
48
-
49
- const instance = {
50
- element: tooltip,
51
- config,
52
- show: (event, content) => this.show(tooltip, event, content, config),
53
- hide: () => this.hide(tooltip, config),
54
- update: (content) => this.update(tooltip, content),
55
- destroy: () => this.destroy(id)
56
- };
57
-
58
- this.tooltips.set(id, instance);
59
- return instance;
60
- }
61
-
62
- /**
63
- * Show a tooltip
64
- * @param {Object} tooltip - D3 selection of tooltip element
65
- * @param {Event} event - Mouse event
66
- * @param {string|Array|Object} content - Content to display
67
- * @param {Object} config - Configuration options
68
- */
69
- show(tooltip, event, content, config) {
70
- // Cancel any pending hide transition
71
- tooltip.interrupt();
72
-
73
- // Format content
74
- const html = this.formatContent(content);
75
-
76
- tooltip.html(html)
77
- .style('left', (event.pageX + config.offset.x) + 'px')
78
- .style('top', (event.pageY + config.offset.y) + 'px');
79
-
80
- tooltip.transition()
81
- .duration(config.duration)
82
- .style('opacity', 0.9);
83
-
84
- // Ensure tooltip stays within viewport
85
- this.adjustPosition(tooltip, event, config);
86
- }
87
-
88
- /**
89
- * Hide a tooltip
90
- * @param {Object} tooltip - D3 selection of tooltip element
91
- * @param {Object} config - Configuration options
92
- */
93
- hide(tooltip, config) {
94
- tooltip.transition()
95
- .duration(config.hideDelay)
96
- .style('opacity', 0);
97
- }
98
-
99
- /**
100
- * Update tooltip content without changing position
101
- * @param {Object} tooltip - D3 selection of tooltip element
102
- * @param {string|Array|Object} content - New content
103
- */
104
- update(tooltip, content) {
105
- const html = this.formatContent(content);
106
- tooltip.html(html);
107
- }
108
-
109
- /**
110
- * Format content for display
111
- * @param {string|Array|Object} content - Content to format
112
- * @returns {string} HTML string
113
- */
114
- formatContent(content) {
115
- if (typeof content === 'string') {
116
- return content;
117
- }
118
-
119
- if (Array.isArray(content)) {
120
- return content.join('<br>');
121
- }
122
-
123
- if (typeof content === 'object' && content !== null) {
124
- const lines = [];
125
-
126
- // Handle title
127
- if (content.title) {
128
- lines.push(`<strong>${this.escapeHtml(content.title)}</strong>`);
129
- }
130
-
131
- // Handle fields
132
- if (content.fields) {
133
- for (const [key, value] of Object.entries(content.fields)) {
134
- if (value !== undefined && value !== null) {
135
- lines.push(`${this.escapeHtml(key)}: ${this.escapeHtml(String(value))}`);
136
- }
137
- }
138
- }
139
-
140
- // Handle description
141
- if (content.description) {
142
- lines.push(`<em>${this.escapeHtml(content.description)}</em>`);
143
- }
144
-
145
- // Handle raw HTML (trusted content only)
146
- if (content.html) {
147
- lines.push(content.html);
148
- }
149
-
150
- return lines.join('<br>');
151
- }
152
-
153
- return String(content);
154
- }
155
-
156
- /**
157
- * Adjust tooltip position to stay within viewport
158
- * @param {Object} tooltip - D3 selection of tooltip element
159
- * @param {Event} event - Mouse event
160
- * @param {Object} config - Configuration options
161
- */
162
- adjustPosition(tooltip, event, config) {
163
- const node = tooltip.node();
164
- if (!node) return;
165
-
166
- const rect = node.getBoundingClientRect();
167
- const viewportWidth = window.innerWidth;
168
- const viewportHeight = window.innerHeight;
169
-
170
- let left = event.pageX + config.offset.x;
171
- let top = event.pageY + config.offset.y;
172
-
173
- // Adjust horizontal position
174
- if (rect.right > viewportWidth) {
175
- left = event.pageX - rect.width - config.offset.x;
176
- }
177
-
178
- // Adjust vertical position
179
- if (rect.bottom > viewportHeight) {
180
- top = event.pageY - rect.height - Math.abs(config.offset.y);
181
- }
182
-
183
- tooltip
184
- .style('left', left + 'px')
185
- .style('top', top + 'px');
186
- }
187
-
188
- /**
189
- * Destroy a tooltip instance
190
- * @param {string} id - Tooltip identifier
191
- */
192
- destroy(id) {
193
- const instance = this.tooltips.get(id);
194
- if (instance) {
195
- instance.element.remove();
196
- this.tooltips.delete(id);
197
- }
198
- }
199
-
200
- /**
201
- * Destroy all tooltips
202
- */
203
- destroyAll() {
204
- for (const [id] of this.tooltips) {
205
- this.destroy(id);
206
- }
207
- }
208
-
209
- /**
210
- * Escape HTML special characters
211
- * @param {string} text - Text to escape
212
- * @returns {string} Escaped text
213
- */
214
- escapeHtml(text) {
215
- const div = document.createElement('div');
216
- div.textContent = text;
217
- return div.innerHTML;
218
- }
219
-
220
- /**
221
- * Create a simple tooltip helper for basic use cases
222
- * @param {string} selector - CSS selector for target elements
223
- * @param {Function} contentFn - Function to generate content from data
224
- * @param {Object} options - Configuration options
225
- */
226
- attachToElements(selector, contentFn, options = {}) {
227
- const id = `tooltip-${selector.replace(/[^a-zA-Z0-9]/g, '-')}`;
228
- const tooltip = this.create(id, options);
229
-
230
- d3.selectAll(selector)
231
- .on('mouseenter', function(event, d) {
232
- const content = contentFn(d, this);
233
- tooltip.show(event, content);
234
- })
235
- .on('mouseleave', function() {
236
- tooltip.hide();
237
- });
238
-
239
- return tooltip;
240
- }
241
- }
242
-
243
- // Export as singleton
244
- const tooltipService = new TooltipService();
245
-
246
- // Support both module and global usage
247
- if (typeof module !== 'undefined' && module.exports) {
248
- module.exports = tooltipService;
249
- } else if (typeof define === 'function' && define.amd) {
250
- define([], () => tooltipService);
251
- } else {
252
- window.tooltipService = tooltipService;
253
- }
@@ -1,2 +0,0 @@
1
- const e=window.io;class t{constructor(){this.socket=null,this.port=null,this.connectionCallbacks={connect:[],disconnect:[],error:[],event:[]},this.eventSchema={required:["source","type","subtype","timestamp","data"],optional:["event","session_id"]},this.isConnected=!1,this.isConnecting=!1,this.lastConnectTime=null,this.disconnectTime=null,this.events=[],this.sessions=new Map,this.currentSessionId=null,this.eventQueue=[],this.maxQueueSize=100,this.retryAttempts=0,this.maxRetryAttempts=5,this.retryDelays=[1e3,2e3,3e3,4e3,5e3],this.pendingEmissions=new Map,this.lastPingTime=null,this.lastPongTime=null,this.pingTimeout=12e4,this.healthCheckInterval=null,this.startStatusCheckFallback(),this.startHealthMonitoring()}connect(e="8765"){this.port=e;const t=`http://localhost:${e}`;if(this.socket&&(this.socket.connected||this.socket.connecting))return console.log("Already connected or connecting, disconnecting first..."),this.socket.disconnect(),void setTimeout(()=>this.doConnect(t),100);this.doConnect(t)}doConnect(t){if(console.log(`Connecting to Socket.IO server at ${t}`),void 0===e)return console.error("Socket.IO library not loaded! Make sure socket.io.min.js is loaded before this script."),void this.notifyConnectionStatus("Socket.IO library not loaded","error");this.isConnecting=!0,this.notifyConnectionStatus("Connecting...","connecting"),this.socket=e(t,{autoConnect:!0,reconnection:!0,reconnectionDelay:1e3,reconnectionDelayMax:1e4,reconnectionAttempts:10,timeout:3e4,forceNew:!0,transports:["websocket","polling"]}),this.setupSocketHandlers()}setupSocketHandlers(){this.socket.on("connect",()=>{console.log("Connected to Socket.IO server");const e=this.isConnected;if(this.isConnected=!0,this.isConnecting=!1,this.lastConnectTime=Date.now(),this.retryAttempts=0,this.disconnectTime&&!1===e){const e=(Date.now()-this.disconnectTime)/1e3;console.log(`Reconnected after ${e.toFixed(1)}s downtime`),this.flushEventQueue()}this.notifyConnectionStatus("Connected","connected"),window.socket=this.socket,console.log("SocketClient: Exposed socket globally as window.socket"),this.connectionCallbacks.connect.forEach(e=>e(this.socket.id)),this.requestStatus()}),this.socket.on("disconnect",e=>{const t={reason:e,timestamp:(new Date).toISOString(),wasConnected:this.isConnected,uptimeSeconds:this.lastConnectTime?((Date.now()-this.lastConnectTime)/1e3).toFixed(1):0,lastPing:this.lastPingTime?((Date.now()-this.lastPingTime)/1e3).toFixed(1)+"s ago":"never",lastPong:this.lastPongTime?((Date.now()-this.lastPongTime)/1e3).toFixed(1)+"s ago":"never"};console.log("Disconnected from server:",t),this.isConnected=!1,this.isConnecting=!1,this.disconnectTime=Date.now(),this.notifyConnectionStatus(`Disconnected: ${e}`,"disconnected"),this.connectionCallbacks.disconnect.forEach(t=>t(e));["transport close","ping timeout","transport error","io server disconnect"].includes(e)?(console.log(`Auto-reconnect triggered for reason: ${e}`),this.scheduleReconnect()):"io client disconnect"===e?console.log("Client-initiated disconnect, not auto-reconnecting"):(console.log(`Unknown disconnect reason: ${e}, attempting reconnect anyway`),this.scheduleReconnect())}),this.socket.on("connect_error",e=>{console.error("Connection error:",e),this.isConnecting=!1;const t=e.message||e.description||"Unknown error";this.notifyConnectionStatus(`Connection Error: ${t}`,"disconnected"),this.addEvent({type:"connection.error",timestamp:(new Date).toISOString(),data:{error:t,url:this.socket.io.uri,retry_attempt:this.retryAttempts}}),this.connectionCallbacks.error.forEach(e=>e(t)),this.scheduleReconnect()}),this.socket.on("claude_event",e=>{console.log("Received claude_event:",e);const t=this.validateEventSchema(e);if(!t)return void console.warn("Invalid event schema received:",e);t.type&&t.type.startsWith("code:")&&console.log("Code analysis event received via claude_event, adding to events list for troubleshooting:",t.type);const n=this.transformEvent(t);console.log("Transformed event:",n),this.addEvent(n)}),this.socket.on("ping",e=>{this.lastPingTime=Date.now(),this.socket.emit("pong",{timestamp:e.timestamp,client_time:Date.now()})}),this.socket.on("pong",e=>{this.lastPongTime=Date.now()}),this.socket.on("heartbeat",e=>{console.log("🫀 Received server heartbeat:",e),this.addEvent({type:"system",subtype:"heartbeat",timestamp:e.timestamp||(new Date).toISOString(),data:e}),this.lastPingTime=Date.now(),console.log(`Server heartbeat #${e.heartbeat_number}: ${e.server_uptime_formatted} uptime, ${e.connected_clients} clients connected`)}),this.socket.on("session.started",e=>{this.addEvent({type:"session",subtype:"started",timestamp:(new Date).toISOString(),data:e})}),this.socket.on("session.ended",e=>{this.addEvent({type:"session",subtype:"ended",timestamp:(new Date).toISOString(),data:e})}),this.socket.on("claude.request",e=>{this.addEvent({type:"claude",subtype:"request",timestamp:(new Date).toISOString(),data:e})}),this.socket.on("claude.response",e=>{this.addEvent({type:"claude",subtype:"response",timestamp:(new Date).toISOString(),data:e})}),this.socket.on("agent.loaded",e=>{this.addEvent({type:"agent",subtype:"loaded",timestamp:(new Date).toISOString(),data:e})}),this.socket.on("agent.executed",e=>{this.addEvent({type:"agent",subtype:"executed",timestamp:(new Date).toISOString(),data:e})}),this.socket.on("todo.updated",e=>{this.addEvent({type:"todo",subtype:"updated",timestamp:(new Date).toISOString(),data:e})}),this.socket.on("memory.operation",e=>{this.addEvent({type:"memory",subtype:"operation",timestamp:(new Date).toISOString(),data:e})}),this.socket.on("log.entry",e=>{this.addEvent({type:"log",subtype:"entry",timestamp:(new Date).toISOString(),data:e})}),this.socket.on("code:analysis:queued",e=>{console.log("Code analysis queued event received, adding to events list for troubleshooting"),this.addEvent({type:"code",subtype:"analysis:queued",timestamp:(new Date).toISOString(),data:e})}),this.socket.on("code:analysis:accepted",e=>{console.log("Code analysis accepted event received, adding to events list for troubleshooting"),this.addEvent({type:"code",subtype:"analysis:accepted",timestamp:(new Date).toISOString(),data:e})}),this.socket.on("code:analysis:start",e=>{console.log("Code analysis start event received, adding to events list for troubleshooting"),this.addEvent({type:"code",subtype:"analysis:start",timestamp:(new Date).toISOString(),data:e})}),this.socket.on("code:analysis:complete",e=>{console.log("Code analysis complete event received, adding to events list for troubleshooting"),this.addEvent({type:"code",subtype:"analysis:complete",timestamp:(new Date).toISOString(),data:e})}),this.socket.on("code:analysis:error",e=>{console.log("Code analysis error event received, adding to events list for troubleshooting"),this.addEvent({type:"code",subtype:"analysis:error",timestamp:(new Date).toISOString(),data:e})}),this.socket.on("code:file:start",e=>{console.log("Code file start event received, adding to events list for troubleshooting"),this.addEvent({type:"code",subtype:"file:start",timestamp:(new Date).toISOString(),data:e})}),this.socket.on("code:node:found",e=>{console.log("Code node found event received, adding to events list for troubleshooting"),this.addEvent({type:"code",subtype:"node:found",timestamp:(new Date).toISOString(),data:e})}),this.socket.on("code:analysis:progress",e=>{console.log("Code analysis progress event received, adding to events list for troubleshooting"),this.addEvent({type:"code",subtype:"analysis:progress",timestamp:(new Date).toISOString(),data:e})}),this.socket.on("history",e=>{console.log("Received event history:",e),e&&Array.isArray(e.events)?(console.log(`Processing ${e.events.length} historical events (${e.count} sent, ${e.total_available} total available)`),e.events.forEach(e=>{const t=this.transformEvent(e);this.addEvent(t,!1)}),this.notifyEventUpdate(),console.log(`Event history loaded: ${e.events.length} events added to dashboard`)):Array.isArray(e)&&(console.log("Received legacy event history format:",e.length,"events"),e.forEach(e=>{const t=this.transformEvent(e);this.addEvent(t,!1)}),this.notifyEventUpdate())}),this.socket.on("system.status",e=>{console.log("Received system status:",e),e.sessions&&this.updateSessions(e.sessions),e.current_session&&(this.currentSessionId=e.current_session)})}disconnect(){this.socket&&(this.socket.disconnect(),this.socket=null),this.port=null,this.isConnected=!1,this.isConnecting=!1}emitWithRetry(e,t=null,n={}){const{maxRetries:o=3,retryDelays:s=[1e3,2e3,4e3],onSuccess:i=null,onFailure:a=null}=n,c=`${e}_${Date.now()}_${Math.random()}`,l=(n=0)=>{if(this.socket&&this.socket.connected)try{this.socket.emit(e,t),console.log(`Emitted ${e} successfully`),this.pendingEmissions.delete(c),i&&i()}catch(r){if(console.error(`Failed to emit ${e} (attempt ${n+1}):`,r),n<o-1){const o=s[n]||s[s.length-1];console.log(`Retrying ${e} in ${o}ms...`),this.pendingEmissions.set(c,{event:e,data:t,attemptNum:n+1,scheduledTime:Date.now()+o}),setTimeout(()=>l(n+1),o)}else console.error(`Failed to emit ${e} after ${o} attempts`),this.pendingEmissions.delete(c),a&&a("max_retries_exceeded")}else 0===n&&(this.queueEvent(e,t),console.log(`Queued ${e} for later emission (disconnected)`),a&&a("disconnected"))};l()}queueEvent(e,t){if(this.eventQueue.length>=this.maxQueueSize){const e=this.eventQueue.shift();console.warn(`Event queue full, dropped oldest event: ${e.event}`)}this.eventQueue.push({event:e,data:t,timestamp:Date.now()})}flushEventQueue(){if(0===this.eventQueue.length)return;console.log(`Flushing ${this.eventQueue.length} queued events...`);const e=[...this.eventQueue];this.eventQueue=[],e.forEach((e,t)=>{setTimeout(()=>{this.socket&&this.socket.connected&&(this.socket.emit(e.event,e.data),console.log(`Flushed queued event: ${e.event}`))},100*t)})}scheduleReconnect(){if(this.retryAttempts>=this.maxRetryAttempts)return console.log("Max reconnection attempts reached, stopping auto-reconnect"),void this.notifyConnectionStatus("Reconnection failed","disconnected");const e=this.retryDelays[this.retryAttempts]||this.retryDelays[this.retryDelays.length-1];this.retryAttempts++,console.log(`Scheduling reconnect attempt ${this.retryAttempts}/${this.maxRetryAttempts} in ${e}ms...`),this.notifyConnectionStatus(`Reconnecting in ${e/1e3}s...`,"connecting"),setTimeout(()=>{!this.isConnected&&this.port&&(console.log(`Attempting reconnection ${this.retryAttempts}/${this.maxRetryAttempts}...`),this.connect(this.port))},e)}requestStatus(){this.socket&&this.socket.connected&&(console.log("Requesting server status..."),this.emitWithRetry("request.status",null,{maxRetries:2,retryDelays:[500,1e3]}))}requestHistory(e={}){if(this.socket&&this.socket.connected){const t={limit:e.limit||50,event_types:e.event_types||[]};console.log("Requesting event history...",t),this.emitWithRetry("get_history",t,{maxRetries:3,retryDelays:[1e3,2e3,3e3],onFailure:e=>{console.error(`Failed to request history: ${e}`)}})}else console.warn("Cannot request history: not connected to server")}addEvent(e,t=!0){if(e.timestamp||(e.timestamp=(new Date).toISOString()),e.id||(e.id=Date.now()+Math.random()),this.events.push(e),e.data&&e.data.session_id){const t=e.data.session_id;this.sessions.has(t)||this.sessions.set(t,{id:t,startTime:e.timestamp,lastActivity:e.timestamp,eventCount:0,working_directory:null,git_branch:null});const n=this.sessions.get(t);n.lastActivity=e.timestamp,n.eventCount++;const o=[e.data.cwd,e.data.working_directory,e.data.working_dir,e.data.workingDirectory,e.data.instance_info?.working_dir,e.data.instance_info?.working_directory,e.data.instance_info?.cwd,e.cwd,e.working_directory,e.working_dir];for(const e of o)if(e&&"string"==typeof e&&e.trim()){n.working_directory=e,console.log(`[SOCKET-CLIENT] Found working directory for session ${t}:`,e);break}e.data.git_branch?n.git_branch=e.data.git_branch:e.data.instance_info&&e.data.instance_info.git_branch&&(n.git_branch=e.data.instance_info.git_branch)}t&&this.notifyEventUpdate()}updateSessions(e){Array.isArray(e)&&e.forEach(e=>{this.sessions.set(e.id,e)})}clearEvents(){this.events=[],this.sessions.clear(),this.notifyEventUpdate()}refreshHistory(e={}){this.clearEvents(),this.requestHistory(e)}getEventsBySession(e=null){return e?this.events.filter(t=>t.data&&t.data.session_id===e):this.events}onConnection(e,t){this.connectionCallbacks[e]&&this.connectionCallbacks[e].push(t)}onEventUpdate(e){this.connectionCallbacks.event.push(e)}on(e,t){if(this.socket)return this.socket.on(e,t);console.warn(`Cannot subscribe to '${e}': socket not initialized`)}off(e,t){if(this.socket)return this.socket.off(e,t);console.warn(`Cannot unsubscribe from '${e}': socket not initialized`)}notifyConnectionStatus(e,t){console.log(`SocketClient: Connection status changed to '${e}' (${t})`),this.updateConnectionStatusDOM(e,t),window.eventViewer&&window.eventViewer.updateMetrics&&window.eventViewer.updateMetrics(),document.dispatchEvent(new CustomEvent("socketConnectionStatus",{detail:{status:e,type:t}}))}updateConnectionStatusDOM(e,t){const n=document.getElementById("connection-status");n?(n.innerHTML=`<span>●</span> ${e}`,n.className=`status-badge status-${t}`,console.log(`SocketClient: Direct DOM update - status: '${e}' (${t})`)):console.warn("SocketClient: Could not find connection-status element in DOM")}notifyEventUpdate(){this.connectionCallbacks.event.forEach(e=>e(this.events,this.sessions)),document.dispatchEvent(new CustomEvent("socketEventUpdate",{detail:{events:this.events,sessions:this.sessions}}))}getConnectionState(){return{isConnected:this.isConnected,isConnecting:this.isConnecting,socketId:this.socket?this.socket.id:null}}validateEventSchema(e){if(!e||"object"!=typeof e)return console.warn("Event data is not an object:",e),null;const t={...e};return t.source||(t.source="system"),t.type||(t.event?t.type=t.event:t.type="unknown"),t.subtype||(t.subtype="generic"),t.timestamp||(t.timestamp=(new Date).toISOString()),t.data||(t.data={}),t.data&&"object"!=typeof t.data&&(t.data={value:t.data}),console.log("Validated event:",t),t}transformEvent(e){if(!e)return e;let t={...e};if(e.type&&e.subtype&&!e.type.includes(".")&&!e.type.includes(":"))t.originalEventName||("generic"===e.subtype||e.type===e.subtype?t.originalEventName=e.type:t.originalEventName=`${e.type}.${e.subtype}`);else if(!e.type&&e.event){const n=e.event;"TestStart"===n||"TestEnd"===n?(t.type="test",t.subtype=n.toLowerCase().replace("test","")):"SubagentStart"===n||"SubagentStop"===n?(t.type="subagent",t.subtype=n.toLowerCase().replace("subagent","")):"ToolCall"===n?(t.type="tool",t.subtype="call"):"UserPrompt"===n?(t.type="hook",t.subtype="user_prompt"):(t.type="unknown",t.subtype=n.toLowerCase(),t.type===t.subtype&&(t.subtype="event")),delete t.event,t.originalEventName=n}else if(e.type){const n=e.type;if(n.startsWith("hook.")){const e=n.substring(5);t.type="hook",t.subtype=e,t.originalEventName=n}else if(n.startsWith("code:")){t.type="code";const e=n.substring(5);t.subtype=e.replace(/:/g,"_"),t.originalEventName=n}else if(n.includes(".")){const[e,...o]=n.split(".");t.type=e,t.subtype=o.join("."),t.originalEventName=n}else if(n.includes(":")){const e=n.split(":",2);t.type=e[0],t.subtype=e.length>1?e[1].replace(/:/g,"_"):"generic",t.originalEventName=n}else e.subtype||(t.subtype="generic",t.originalEventName=n)}else t.type="unknown",t.subtype="",t.originalEventName="unknown";if(e.data&&"object"==typeof e.data){const n=["type","subtype","timestamp","id","event","event_type","originalEventName"];Object.keys(e.data).forEach(o=>{n.includes(o)?"timestamp"!==o&&console.debug(`Protected field '${o}' in data object was not copied to top level to preserve event structure`):"tool_parameters"===o&&"object"==typeof e.data[o]?t[o]=JSON.parse(JSON.stringify(e.data[o])):t[o]=e.data[o]}),t.data=e.data}if("hook"===t.type?"pre_tool"===t.subtype?t.hook_event_name="PreToolUse":"post_tool"===t.subtype?t.hook_event_name="PostToolUse":"subagent_start"===t.subtype?t.hook_event_name="SubagentStart":"subagent_stop"===t.subtype?t.hook_event_name="SubagentStop":"todo_write"===t.subtype?t.hook_event_name="TodoWrite":"start"===t.subtype?t.hook_event_name="Start":"stop"===t.subtype&&(t.hook_event_name="Stop"):"subagent"===t.type?"start"===t.subtype?t.hook_event_name="SubagentStart":"stop"===t.subtype&&(t.hook_event_name="SubagentStop"):"todo"===t.type&&"updated"===t.subtype&&(t.hook_event_name="TodoWrite"),"hook"===t.type&&("pre_tool"===t.subtype||"post_tool"===t.subtype)){console.log("Transformed tool event:",{type:t.type,subtype:t.subtype,hook_event_name:t.hook_event_name,tool_name:t.tool_name,has_tool_parameters:!!t.tool_parameters,tool_parameters:t.tool_parameters,has_data:!!t.data,keys:Object.keys(t).filter(e=>"data"!==e)});["Read","Write","Edit","MultiEdit","NotebookEdit"].includes(t.tool_name)&&console.log("File tool event details:",{tool_name:t.tool_name,file_path:t.tool_parameters?.file_path,path:t.tool_parameters?.path,notebook_path:t.tool_parameters?.notebook_path,full_parameters:t.tool_parameters})}return t}getState(){return{events:this.events,sessions:this.sessions,currentSessionId:this.currentSessionId}}startHealthMonitoring(){this.healthCheckInterval=setInterval(()=>{if(this.isConnected&&this.lastPingTime){const e=Date.now()-this.lastPingTime;e>this.pingTimeout&&(console.warn(`No ping from server for ${e/1e3}s, connection may be stale`),this.socket&&(console.log("Forcing reconnection due to stale connection..."),this.socket.disconnect(),setTimeout(()=>{this.port&&this.connect(this.port)},1e3)))}},1e4)}stopHealthMonitoring(){this.healthCheckInterval&&(clearInterval(this.healthCheckInterval),this.healthCheckInterval=null)}startStatusCheckFallback(){setInterval(()=>{this.checkAndUpdateStatus()},2e3),"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{setTimeout(()=>this.checkAndUpdateStatus(),100)}):setTimeout(()=>this.checkAndUpdateStatus(),100)}checkAndUpdateStatus(){let e="Disconnected",t="disconnected";this.socket&&(this.socket.connected?(e="Connected",t="connected",this.isConnected=!0,this.isConnecting=!1):this.socket.connecting||this.isConnecting?(e="Connecting...",t="connecting",this.isConnected=!1):(e="Disconnected",t="disconnected",this.isConnected=!1,this.isConnecting=!1));const n=document.getElementById("connection-status");if(n){const o=n.textContent.replace("●","").trim(),s=n.className,i=`status-badge status-${t}`;o===e&&s===i||(console.log(`SocketClient: Fallback update - was '${o}' (${s}), now '${e}' (${i})`),this.updateConnectionStatusDOM(e,t),window.eventViewer&&window.eventViewer.updateMetrics&&window.eventViewer.updateMetrics())}}destroy(){this.stopHealthMonitoring(),this.socket&&(this.socket.disconnect(),this.socket=null),this.eventQueue=[],this.pendingEmissions.clear()}getConnectionMetrics(){return{isConnected:this.isConnected,uptime:this.lastConnectTime?(Date.now()-this.lastConnectTime)/1e3:0,lastPing:this.lastPingTime?(Date.now()-this.lastPingTime)/1e3:null,queuedEvents:this.eventQueue.length,pendingEmissions:this.pendingEmissions.size,retryAttempts:this.retryAttempts}}}window.SocketClient=t;class n{constructor(){this.socketClient=null,this.connectionCallbacks=new Set,this.eventUpdateCallbacks=new Set,this.socketClient=new t,window.socketClient=this.socketClient,this.setupSocketEventHandlers(),setTimeout(()=>{this.updateInitialConnectionStatus()},100),console.log("Socket manager initialized")}setupSocketEventHandlers(){document.addEventListener("socketConnectionStatus",e=>{console.log(`SocketManager: Processing connection status update: ${e.detail.status} (${e.detail.type})`),this.handleConnectionStatusChange(e.detail.status,e.detail.type),this.connectionCallbacks.forEach(t=>{try{t(e.detail.status,e.detail.type)}catch(n){console.error("Error in connection callback:",n)}})}),this.socketClient&&this.socketClient.onEventUpdate(e=>{this.eventUpdateCallbacks.forEach(t=>{try{t(e)}catch(n){console.error("Error in event update callback:",n)}})})}handleConnectionStatusChange(e,t){this.updateConnectionStatus(e,t),"connected"===t&&this.socketClient&&this.socketClient.socket&&(window.socket=this.socketClient.socket,console.log("SocketManager: Exposed socket globally as window.socket"),this.setupGitBranchListener())}updateInitialConnectionStatus(){console.log("SocketManager: Updating initial connection status"),this.socketClient&&"function"==typeof this.socketClient.checkAndUpdateStatus?(console.log("SocketManager: Using socket client checkAndUpdateStatus method"),this.socketClient.checkAndUpdateStatus()):this.socketClient&&this.socketClient.socket?(console.log("SocketManager: Checking socket state directly",{connected:this.socketClient.socket.connected,connecting:this.socketClient.socket.connecting,isConnecting:this.socketClient.isConnecting,isConnected:this.socketClient.isConnected}),this.socketClient.socket.connected?(console.log("SocketManager: Socket is already connected, updating status"),window.socket=this.socketClient.socket,console.log("SocketManager: Exposed socket globally as window.socket"),this.updateConnectionStatus("Connected","connected")):this.socketClient.isConnecting||this.socketClient.socket.connecting?(console.log("SocketManager: Socket is connecting, updating status"),this.updateConnectionStatus("Connecting...","connecting")):(console.log("SocketManager: Socket is disconnected, updating status"),this.updateConnectionStatus("Disconnected","disconnected"))):(console.log("SocketManager: No socket client or socket found, setting disconnected status"),this.updateConnectionStatus("Disconnected","disconnected")),setTimeout(()=>{console.log("SocketManager: Secondary status check after 1 second"),this.socketClient&&this.socketClient.socket&&this.socketClient.socket.connected&&(console.log("SocketManager: Socket connected in secondary check, updating status"),window.socket||(window.socket=this.socketClient.socket,console.log("SocketManager: Exposed socket globally as window.socket (secondary check)")),this.updateConnectionStatus("Connected","connected"))},1e3)}setupGitBranchListener(){this.socketClient.socket.off("git_branch_response"),this.socketClient.socket.on("git_branch_response",e=>{if(e.success){const t=document.getElementById("footer-git-branch");t&&(t.textContent=e.branch||"unknown"),t&&(t.style.display="inline")}else console.error("Git branch request failed:",e.error)})}updateConnectionStatus(e,t){const n=document.getElementById("connection-status");if(n){if(n.querySelector("span")){const t="●";n.innerHTML=`<span>${t}</span> ${e}`}else n.textContent=e;n.className=`status-badge status-${t}`,console.log(`SocketManager: UI updated - status: '${e}' (${t})`)}else console.error("SocketManager: Could not find connection-status element in DOM")}connect(e){this.socketClient&&this.socketClient.connect(e)}disconnect(){this.socketClient&&this.socketClient.disconnect()}isConnected(){return this.socketClient&&this.socketClient.isConnected}isConnecting(){return this.socketClient&&this.socketClient.isConnecting}getSocketClient(){return this.socketClient}getSocket(){return this.socketClient?this.socketClient.socket:null}onConnectionStatusChange(e){this.connectionCallbacks.add(e)}offConnectionStatusChange(e){this.connectionCallbacks.delete(e)}onEventUpdate(e){this.eventUpdateCallbacks.add(e)}offEventUpdate(e){this.eventUpdateCallbacks.delete(e)}toggleConnectionControls(){const e=document.getElementById("connection-controls-row"),t=document.getElementById("connection-toggle-btn");if(e&&t){e.classList.contains("show")?(e.classList.remove("show"),e.style.display="none",t.textContent="Connection Settings"):(e.classList.add("show"),e.style.display="block",t.textContent="Hide Settings")}}setupConnectionControls(){const e=document.getElementById("connect-btn"),t=document.getElementById("disconnect-btn"),n=document.getElementById("connection-toggle-btn");e&&e.addEventListener("click",()=>{const e=document.getElementById("port-input").value||8765;this.connect(e)}),t&&t.addEventListener("click",()=>{this.disconnect()}),n&&n.addEventListener("click",()=>{this.toggleConnectionControls()})}initializeFromURL(e){const t=e.get("port"),n=document.getElementById("port-input");let o=t;o||"http:"!==window.location.protocol||(o=window.location.port||"8765"),o||(o=n?.value||"8765"),n&&(n.value=o);!("false"!==e.get("connect"))||this.isConnected()||this.isConnecting()||(console.log(`SocketManager: Auto-connecting to port ${o}`),this.connect(o))}}window.SocketManager=n;class o{constructor(){this._switching=!1,this.hashToTab={"#events":"events","#agents":"agents","#tools":"tools","#files":"files","#activity":"activity","#file_tree":"claude-tree","":"events"},this.tabToHash={events:"#events",agents:"#agents",tools:"#tools",files:"#files",activity:"#activity","claude-tree":"#file_tree"},this.currentTab=this.getTabFromHash(),this.autoScroll=!0,this.selectedCard={tab:null,index:null,type:null,data:null},this.tabNavigation={events:{selectedIndex:-1,items:[]},agents:{selectedIndex:-1,items:[]},tools:{selectedIndex:-1,items:[]},files:{selectedIndex:-1,items:[]}},this.setupEventHandlers(),console.log("UI state manager initialized with hash navigation"),this.handleHashChange()}getTabFromHash(){const e=window.location.hash||"";return this.hashToTab[e]||"events"}setupEventHandlers(){this.setupHashNavigation(),this.setupTabClickHandlers(),this.setupUnifiedKeyboardNavigation()}setupHashNavigation(){window.addEventListener("hashchange",e=>{console.log("[Hash Navigation] Hash changed from",new URL(e.oldURL).hash,"to",window.location.hash),this.handleHashChange()}),document.addEventListener("DOMContentLoaded",()=>{console.log("[Hash Navigation] Initial hash:",window.location.hash),this.handleHashChange()})}handleHashChange(){const e=window.location.hash||"";console.log("[Hash Navigation] DETAILED DEBUG:"),console.log("[Hash Navigation] - Current hash:",e),console.log("[Hash Navigation] - hashToTab mapping:",this.hashToTab),console.log("[Hash Navigation] - Direct lookup result:",this.hashToTab[e]),console.log("[Hash Navigation] - Is hash in mapping?",e in this.hashToTab),console.log("[Hash Navigation] - Hash length:",e.length),console.log("[Hash Navigation] - Hash char codes:",e.split("").map(e=>e.charCodeAt(0)));const t=this.hashToTab[e]||"events";console.log("[Hash Navigation] Final resolved tab name:",t),"claude-tree"!==t&&"#file_tree"!==e||(console.log("[UIStateManager] FILE TREE TAB SELECTED via hash:",e),console.log("[UIStateManager] Tab name resolved to:",t)),this.switchTab(t,!1)}setupTabNavigation(){console.log("[Hash Navigation] setupTabNavigation is deprecated - using hash navigation instead")}setupTabClickHandlers(){document.querySelectorAll(".tab-button").forEach(e=>{e.addEventListener("click",e=>{console.log("[UIStateManager] Tab button clicked:",e.target);const t=this.getTabNameFromButton(e.target);console.log("[UIStateManager] Resolved tab name:",t),t&&setTimeout(()=>{const e=this.tabToHash[t];window.location.hash!==e&&e&&(console.log("[UIStateManager] Hash not updated, forcing update:",e),window.location.hash=e)},10)})}),console.log("[UIStateManager] Tab click handlers set up for",document.querySelectorAll(".tab-button").length,"buttons")}setupUnifiedKeyboardNavigation(){document.addEventListener("keydown",e=>{document.activeElement&&["INPUT","TEXTAREA","SELECT"].includes(document.activeElement.tagName)||("ArrowUp"===e.key||"ArrowDown"===e.key?(e.preventDefault(),this.handleUnifiedArrowNavigation("ArrowDown"===e.key?1:-1)):"Enter"===e.key?(e.preventDefault(),this.handleUnifiedEnterKey()):"Escape"===e.key&&this.clearUnifiedSelection())})}getTabNameFromButton(e){console.log("[getTabNameFromButton] DEBUG: button object:",e),console.log("[getTabNameFromButton] DEBUG: button.nodeType:",e.nodeType),console.log("[getTabNameFromButton] DEBUG: button.tagName:",e.tagName);let t=e;e&&e.closest&&e.closest(".tab-button")&&(t=e.closest(".tab-button"),console.log("[getTabNameFromButton] DEBUG: Used closest() to find actual button"));const n=t?t.getAttribute("data-tab"):null;if(console.log("[getTabNameFromButton] DEBUG: data-tab attribute:",n),console.log("[getTabNameFromButton] DEBUG: dataTab truthy:",!!n),"claude-tree"===n)return console.log("[getTabNameFromButton] DEBUG: Found claude-tree data-tab, returning it"),"claude-tree";if(n)return console.log("[getTabNameFromButton] DEBUG: Returning dataTab:",n),n;const o=t?t.textContent.toLowerCase():"";return console.log("[getTabNameFromButton] DEBUG: text content:",o),console.log("[getTabNameFromButton] DEBUG: text includes file tree:",o.includes("file tree")),console.log("[getTabNameFromButton] DEBUG: text includes events:",o.includes("events")),o.includes("file tree")||o.includes("📝")?(console.log("[getTabNameFromButton] DEBUG: Matched file tree, returning claude-tree"),"claude-tree"):o.includes("activity")||o.includes("🌳")?"activity":o.includes("agents")||o.includes("🤖")?"agents":o.includes("tools")||o.includes("🔧")?"tools":o.includes("files")||o.includes("📁")?"files":o.includes("code")?"code":o.includes("sessions")?"sessions":o.includes("system")?"system":(o.includes("events")||o.includes("📊")||console.log("[getTabNameFromButton] DEBUG: No match, falling back to events"),"events")}switchTab(e,t=!0){if(this._switching)return console.log(`[UIStateManager] Tab switch already in progress, queuing: ${e}`),void setTimeout(()=>this.switchTab(e,t),50);this._switching=!0,console.log(`[UIStateManager] BULLETPROOF switchTab: ${e}, updateHash: ${t}`);try{if("claude-tree"===e&&(console.log("[UIStateManager] SWITCHING TO FILE TREE TAB"),console.log("[UIStateManager] Current tab before switch:",this.currentTab)),t&&this.tabToHash[e]){const t=this.tabToHash[e];if(window.location.hash!==t)return console.log(`[UIStateManager] Updating hash to: ${t}`),this._switching=!1,void(window.location.hash=t)}const n=this.currentTab;this.currentTab=e,this._removeAllActiveStates(),this._setActiveTab(e),this._showTabContent(e),this._validateTabState(e),this.clearUnifiedSelection(),document.dispatchEvent(new CustomEvent("tabChanged",{detail:{newTab:e,previousTab:n}})),setTimeout(()=>{this.autoScroll&&this.scrollCurrentTabToBottom(),"claude-tree"===e&&window.CodeViewer&&(window.CodeViewer.renderContent?window.CodeViewer.renderContent():window.CodeViewer.show())},100)}finally{setTimeout(()=>{this._switching=!1},200)}}_removeAllActiveStates(){document.querySelectorAll(".tab-button").forEach(e=>{e.classList.remove("active"),e.style.removeProperty("border-bottom"),e.style.removeProperty("color")}),document.querySelectorAll(".tab-content").forEach(e=>{e.classList.remove("active"),e.style.removeProperty("display"),"events-tab"!==e.id&&this._cleanLeakedEventContent(e)}),console.log("[UIStateManager] NUCLEAR: All active states removed")}_setActiveTab(e){const t=document.querySelector(`[data-tab="${e}"]`);t?(t.classList.add("active"),console.log(`[UIStateManager] Set active: ${e}`)):console.error(`[UIStateManager] Could not find tab button for: ${e}`)}_showTabContent(e){const t=document.getElementById(`${e}-tab`);t?(t.classList.add("active"),console.log(`[UIStateManager] Showing content: ${e}-tab`),"claude-tree"===e&&this._prepareFileTreeContent(t)):console.error(`[UIStateManager] Could not find content for: ${e}`)}_cleanLeakedEventContent(e){const t=e.querySelectorAll(".event-item");t.length>0&&(console.warn(`[UIStateManager] Found ${t.length} leaked event items in ${e.id}, removing...`),t.forEach(e=>e.remove()));const n=e.querySelectorAll("#events-list, .events-list");n.length>0&&(console.warn(`[UIStateManager] Found leaked events-list in ${e.id}, removing...`),n.forEach(e=>e.remove()))}_prepareFileTreeContent(e){const t=document.getElementById("claude-tree-container");t&&(this._cleanLeakedEventContent(t),t.setAttribute("data-owner","code-viewer"),t.setAttribute("data-component","CodeViewer"),console.log("[UIStateManager] File Tree container prepared"))}_validateTabState(e){setTimeout(()=>{const t=document.querySelectorAll(".tab-button.active"),n=document.querySelectorAll(".tab-content.active");1!==t.length&&(console.error(`[UIStateManager] VALIDATION FAILED: Expected 1 active tab, found ${t.length}`),t.forEach((e,t)=>{console.error(` - Active tab ${t+1}: ${e.textContent.trim()} (${e.getAttribute("data-tab")})`)}),this._removeAllActiveStates(),this._setActiveTab(e)),1!==n.length&&(console.error(`[UIStateManager] VALIDATION FAILED: Expected 1 active content, found ${n.length}`),n.forEach((e,t)=>{console.error(` - Active content ${t+1}: ${e.id}`)}),this._removeAllActiveStates(),this._showTabContent(e)),console.log(`[UIStateManager] Tab state validated for: ${e}`)},50)}handleUnifiedArrowNavigation(e){const t=this.tabNavigation[this.currentTab];if(!t)return;let n=t.selectedIndex+e;0!==t.items.length&&(n<0?n=t.items.length-1:n>=t.items.length&&(n=0),this.selectCardByIndex(this.currentTab,n))}handleUnifiedEnterKey(){const e=this.tabNavigation[this.currentTab];if(!e||-1===e.selectedIndex)return;const t=e.items[e.selectedIndex];t&&t.onclick&&t.onclick()}clearUnifiedSelection(){Object.keys(this.tabNavigation).forEach(e=>{this.tabNavigation[e].selectedIndex=-1}),this.clearCardSelection()}updateTabNavigationItems(){const e=this.tabNavigation[this.currentTab];if(!e)return;let t;switch(this.currentTab){case"events":t="#events-list .event-item";break;case"agents":t="#agents-list .event-item";break;case"tools":t="#tools-list .event-item";break;case"files":t="#files-list .event-item"}t&&(e.items=Array.from(document.querySelectorAll(t)))}selectCardByIndex(e,t){const n=this.tabNavigation[e];if(!n||t<0||t>=n.items.length)return;n.selectedIndex=t,this.updateUnifiedSelectionUI();n.items[t]&&this.selectCard(e,t,this.getCardType(e),t),this.showCardDetails(e,t)}updateUnifiedSelectionUI(){document.querySelectorAll(".event-item.keyboard-selected").forEach(e=>{e.classList.remove("keyboard-selected")});const e=this.tabNavigation[this.currentTab];e&&-1!==e.selectedIndex&&e.items[e.selectedIndex]&&e.items[e.selectedIndex].classList.add("keyboard-selected")}showCardDetails(e,t){document.dispatchEvent(new CustomEvent("showCardDetails",{detail:{tabName:e,index:t}}))}selectCard(e,t,n,o){this.clearCardSelection(),this.selectedCard={tab:e,index:t,type:n,data:o},this.updateCardSelectionUI(),console.log("Card selected:",this.selectedCard)}clearCardSelection(){document.querySelectorAll(".event-item.selected, .file-item.selected").forEach(e=>{e.classList.remove("selected")}),this.selectedCard={tab:null,index:null,type:null,data:null}}updateCardSelectionUI(){if(!this.selectedCard.tab||null===this.selectedCard.index)return;let e;switch(this.selectedCard.tab){case"events":e=document.getElementById("events-list");break;case"agents":e=document.getElementById("agents-list");break;case"tools":e=document.getElementById("tools-list");break;case"files":e=document.getElementById("files-list")}if(e){const t=e.querySelectorAll(".event-item, .file-item");t[this.selectedCard.index]&&t[this.selectedCard.index].classList.add("selected")}}getCardType(e){switch(e){case"events":return"event";case"agents":return"agent";case"tools":return"tool";case"files":return"file";default:return"unknown"}}scrollCurrentTabToBottom(){const e=`${this.currentTab}-list`,t=document.getElementById(e);t&&this.autoScroll&&(t.scrollTop=t.scrollHeight)}clearSelection(){this.clearCardSelection(),this.clearUnifiedSelection()}getCurrentTab(){return this.currentTab}getSelectedCard(){return{...this.selectedCard}}getTabNavigation(){return{...this.tabNavigation}}setAutoScroll(e){this.autoScroll=e}getAutoScroll(){return this.autoScroll}}window.UIStateManager=o;export{n as S,o as U};
2
- //# sourceMappingURL=socket-client.js.map
@@ -1,185 +0,0 @@
1
- /**
2
- * BULLETPROOF FILE TREE TAB ISOLATION FIX
3
- *
4
- * This is a surgical fix to resolve the File Tree tab isolation issue
5
- * without requiring changes to the complex build system or existing dashboard.
6
- *
7
- * This script can be loaded independently and will override any existing
8
- * problematic tab switching behavior.
9
- */
10
-
11
- console.log('[TAB-FIX] Bulletproof File Tree tab isolation fix loaded');
12
-
13
- // Wait for DOM to be ready
14
- function whenReady(callback) {
15
- if (document.readyState === 'loading') {
16
- document.addEventListener('DOMContentLoaded', callback);
17
- } else {
18
- callback();
19
- }
20
- }
21
-
22
- function implementTabFix() {
23
- console.log('[TAB-FIX] Implementing bulletproof tab switching...');
24
-
25
- let tabSwitchingInProgress = false;
26
-
27
- function switchToTab(tabName) {
28
- if (tabSwitchingInProgress) {
29
- console.log('[TAB-FIX] Tab switching already in progress, queuing...');
30
- setTimeout(() => switchToTab(tabName), 100);
31
- return;
32
- }
33
-
34
- tabSwitchingInProgress = true;
35
- console.log(`[TAB-FIX] Switching to tab: ${tabName}`);
36
-
37
- try {
38
- // STEP 1: Remove ALL active states
39
- document.querySelectorAll('.tab-button').forEach(btn => {
40
- btn.classList.remove('active');
41
- });
42
-
43
- document.querySelectorAll('.tab-content').forEach(content => {
44
- content.classList.remove('active');
45
- });
46
-
47
- // STEP 2: Add active to the correct tab button
48
- const targetButton = document.querySelector(`[data-tab="${tabName}"]`);
49
- if (targetButton) {
50
- targetButton.classList.add('active');
51
- console.log(`[TAB-FIX] Activated tab button: ${tabName}`);
52
- } else {
53
- console.warn(`[TAB-FIX] Tab button not found: ${tabName}`);
54
- }
55
-
56
- // STEP 3: Add active to the correct content
57
- const targetContent = document.getElementById(`${tabName}-tab`);
58
- if (targetContent) {
59
- targetContent.classList.add('active');
60
- console.log(`[TAB-FIX] Activated tab content: ${tabName}-tab`);
61
-
62
- // STEP 4: Special handling for File Tree
63
- if (tabName === 'claude-tree') {
64
- // Ensure File Tree content is clean
65
- const eventsInFileTree = targetContent.querySelectorAll('.event-item');
66
- if (eventsInFileTree.length > 0) {
67
- console.warn(`[TAB-FIX] Found ${eventsInFileTree.length} event items in File Tree, removing...`);
68
- eventsInFileTree.forEach(item => item.remove());
69
- }
70
-
71
- // Trigger CodeViewer if available
72
- if (window.CodeViewer && typeof window.CodeViewer.show === 'function') {
73
- setTimeout(() => {
74
- window.CodeViewer.show();
75
- }, 100);
76
- }
77
- }
78
- } else {
79
- console.warn(`[TAB-FIX] Tab content not found: ${tabName}-tab`);
80
- }
81
-
82
- } finally {
83
- setTimeout(() => {
84
- tabSwitchingInProgress = false;
85
- }, 200);
86
- }
87
- }
88
-
89
- // Override any existing tab switching
90
- function setupTabClickHandlers() {
91
- console.log('[TAB-FIX] Setting up click handlers...');
92
-
93
- document.querySelectorAll('.tab-button').forEach(button => {
94
- // Remove any existing listeners by cloning the element
95
- const newButton = button.cloneNode(true);
96
- button.parentNode.replaceChild(newButton, button);
97
-
98
- // Add our handler
99
- newButton.addEventListener('click', function(e) {
100
- e.preventDefault();
101
- e.stopPropagation();
102
-
103
- const tabName = this.getAttribute('data-tab');
104
- if (tabName) {
105
- console.log(`[TAB-FIX] Tab clicked: ${tabName}`);
106
- switchToTab(tabName);
107
-
108
- // Update hash
109
- const hashMap = {
110
- 'events': '#events',
111
- 'agents': '#agents',
112
- 'tools': '#tools',
113
- 'files': '#files',
114
- 'activity': '#activity',
115
- 'claude-tree': '#file_tree'
116
- };
117
- if (hashMap[tabName]) {
118
- history.replaceState(null, null, hashMap[tabName]);
119
- }
120
- } else {
121
- console.warn('[TAB-FIX] No data-tab attribute found on button');
122
- }
123
- });
124
- });
125
-
126
- console.log(`[TAB-FIX] Set up handlers for ${document.querySelectorAll('.tab-button').length} tab buttons`);
127
- }
128
-
129
- // Handle hash navigation
130
- function handleHashNavigation() {
131
- const hash = window.location.hash;
132
- const hashToTab = {
133
- '#events': 'events',
134
- '#agents': 'agents',
135
- '#tools': 'tools',
136
- '#files': 'files',
137
- '#activity': 'activity',
138
- '#file_tree': 'claude-tree',
139
- '': 'events'
140
- };
141
-
142
- const tabName = hashToTab[hash] || 'events';
143
- console.log(`[TAB-FIX] Hash navigation: ${hash} -> ${tabName}`);
144
- switchToTab(tabName);
145
- }
146
-
147
- // Wait for tabs to be available
148
- function waitForTabsAndSetup() {
149
- const tabs = document.querySelectorAll('.tab-button');
150
- if (tabs.length > 0) {
151
- console.log(`[TAB-FIX] Found ${tabs.length} tabs, setting up handlers...`);
152
- setupTabClickHandlers();
153
-
154
- // Set up hash navigation
155
- window.addEventListener('hashchange', handleHashNavigation);
156
-
157
- // Handle initial hash
158
- setTimeout(handleHashNavigation, 100);
159
-
160
- console.log('[TAB-FIX] Bulletproof tab fix fully activated!');
161
- } else {
162
- console.log('[TAB-FIX] Tabs not ready yet, retrying in 500ms...');
163
- setTimeout(waitForTabsAndSetup, 500);
164
- }
165
- }
166
-
167
- // Start the setup process
168
- waitForTabsAndSetup();
169
- }
170
-
171
- // Export functions for global access
172
- window.TabFix = {
173
- implement: implementTabFix,
174
- switchToTab: function(tabName) {
175
- // This will be available after implementTabFix is called
176
- const event = new CustomEvent('tabfix-switch', { detail: { tabName } });
177
- document.dispatchEvent(event);
178
- }
179
- };
180
-
181
- // Auto-implement when ready
182
- whenReady(() => {
183
- console.log('[TAB-FIX] DOM ready, waiting 3 seconds for other scripts to load...');
184
- setTimeout(implementTabFix, 3000);
185
- });
@@ -1 +0,0 @@
1
- ._dataInspector_9ek2f_1{background:#0000004d;border-radius:6px;border:1px solid rgba(255,255,255,.1);overflow:hidden}._inspectorHeader_9ek2f_8{display:flex;gap:10px;padding:10px;background:#ffffff0d;border-bottom:1px solid rgba(255,255,255,.1);align-items:center}._searchInput_9ek2f_17{flex:1;padding:8px 12px;background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-radius:4px;color:#fff;font-size:12px}._searchInput_9ek2f_17::placeholder{color:#ffffff80}._actions_9ek2f_31{display:flex;gap:8px}._actionButton_9ek2f_36{padding:6px 12px;background:#ffffff1a;border:none;border-radius:4px;color:#fff;font-size:11px;cursor:pointer;transition:background .2s}._actionButton_9ek2f_36:hover{background:#fff3}._treeContainer_9ek2f_51{overflow-y:auto;padding:10px;font-family:Courier New,monospace;font-size:13px;line-height:1.4}._treeNode_9ek2f_59{margin-bottom:2px}._nodeHeader_9ek2f_63{display:flex;align-items:center;gap:6px;padding:2px 4px;cursor:pointer;border-radius:3px;transition:background .2s}._nodeHeader_9ek2f_63:hover{background:#ffffff0d}._expandIcon_9ek2f_77{color:#94a3b8;font-size:10px;transition:transform .2s;cursor:pointer;user-select:none;width:12px;display:inline-block}._expandIcon_9ek2f_77._expanded_9ek2f_87{transform:rotate(90deg)}._leafIcon_9ek2f_91{color:#94a3b8;font-size:8px;width:12px;display:inline-block;text-align:center}._nodeKey_9ek2f_99{color:#60a5fa;font-weight:500}._nodeValue_9ek2f_104{margin-left:6px;word-break:break-all}._nodeValue_9ek2f_104._string_9ek2f_109{color:#86efac}._nodeValue_9ek2f_104._number_9ek2f_113{color:#fbbf24}._nodeValue_9ek2f_104._boolean_9ek2f_117{color:#a78bfa}._nodeValue_9ek2f_104._null_9ek2f_121,._nodeValue_9ek2f_104._undefined_9ek2f_122{color:#f87171;font-style:italic}._nodeValue_9ek2f_104._object_9ek2f_127,._nodeValue_9ek2f_104._array_9ek2f_128{color:#94a3b8;font-style:italic}._copyButton_9ek2f_133{margin-left:auto;background:none;border:none;color:#ffffff80;cursor:pointer;padding:2px;font-size:10px;opacity:0;transition:opacity .2s}._nodeHeader_9ek2f_63:hover ._copyButton_9ek2f_133{opacity:1}._copyButton_9ek2f_133:hover{color:#fffc}._nodeChildren_9ek2f_153{border-left:1px solid rgba(255,255,255,.1);margin-left:6px}._highlight_9ek2f_158{background:#fbbf244d;color:#fbbf24;padding:1px 2px;border-radius:2px}._noData_9ek2f_165{text-align:center;color:#ffffff80;padding:20px;font-style:italic}._treeContainer_9ek2f_51::-webkit-scrollbar{width:6px}._treeContainer_9ek2f_51::-webkit-scrollbar-track{background:#ffffff0d}._treeContainer_9ek2f_51::-webkit-scrollbar-thumb{background:#fff3;border-radius:3px}._treeContainer_9ek2f_51::-webkit-scrollbar-thumb:hover{background:#ffffff4d}._eventsContainer_3k2sj_1{background:#ffffff0d;backdrop-filter:blur(10px);border-radius:12px;border:1px solid rgba(255,255,255,.1);overflow:hidden;flex:1;display:flex;flex-direction:column;min-height:0}._eventsHeader_3k2sj_13{padding:15px 20px;background:#ffffff0d;border-bottom:1px solid rgba(255,255,255,.1);display:flex;justify-content:space-between;align-items:center}._eventsTitle_3k2sj_22{font-weight:600;font-size:16px}._eventsInfo_3k2sj_27{font-size:12px;color:#fff9}._eventsList_3k2sj_32{flex:1;position:relative;min-height:300px}._eventItem_3k2sj_38{padding:12px 20px;border-bottom:1px solid rgba(255,255,255,.05);transition:background .2s;cursor:pointer;font-family:Courier New,monospace;font-size:13px;position:relative;animation:_slideIn_3k2sj_1 .3s ease}@keyframes _slideIn_3k2sj_1{0%{opacity:0;transform:translate(-20px)}to{opacity:1;transform:translate(0)}}._eventItem_3k2sj_38:hover{background:#ffffff0d}._eventItem_3k2sj_38._expanded_3k2sj_64{background:#ffffff14}._eventHeader_3k2sj_68{width:100%}._eventHeaderRow_3k2sj_72{display:flex;gap:10px;align-items:center;margin-bottom:5px}._eventType_3k2sj_79{padding:3px 8px;border-radius:10px;font-size:11px;font-weight:600;text-transform:uppercase}._eventType_3k2sj_79._agent_3k2sj_87{background:#a78bfa33;color:#a78bfa}._eventType_3k2sj_79._tool_3k2sj_92{background:#60a5fa33;color:#60a5fa}._eventType_3k2sj_79._file_3k2sj_97{background:#fbbf2433;color:#fbbf24}._eventType_3k2sj_79._session_3k2sj_102{background:#4ade8033;color:#4ade80}._eventType_3k2sj_79._error_3k2sj_107{background:#f8717133;color:#f87171}._eventType_3k2sj_79._info_3k2sj_112{background:#86efac33;color:#86efac}._eventTime_3k2sj_117{font-size:11px;color:#ffffff80}._sourceIndicator_3k2sj_122{font-size:10px;color:#fff6;font-style:italic}._eventPreview_3k2sj_128{color:#ffffffb3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}._eventDetails_3k2sj_136{margin-top:10px;padding:10px;background:#0003;border-radius:6px}._noEvents_3k2sj_143{text-align:center;padding:60px 20px;color:#ffffff80}._noEvents_3k2sj_143 h3{margin-bottom:10px;font-size:18px}._noEvents_3k2sj_143 p{font-size:14px}._controlsPanel_wgq69_1{background:#ffffff0d;backdrop-filter:blur(10px);border:1px solid rgba(255,255,255,.1);border-radius:10px;padding:15px;margin-bottom:20px;display:flex;gap:15px;align-items:center;flex-wrap:wrap}._controlGroup_wgq69_14{display:flex;align-items:center;gap:10px}._controlLabel_wgq69_20{font-size:14px;color:#94a3b8}._btn_wgq69_25{padding:10px 20px;background:linear-gradient(135deg,#10b981,#06b6d4);border:none;border-radius:8px;color:#fff;cursor:pointer;font-size:14px;transition:transform .2s,box-shadow .2s}._btn_wgq69_25:hover{transform:translateY(-2px);box-shadow:0 5px 15px #10b98166}._btn_wgq69_25._secondary_wgq69_41{background:#ffffff1a}._btn_wgq69_25._danger_wgq69_45{background:linear-gradient(135deg,#ef4444,#dc2626)}._searchBox_wgq69_49{flex:1;min-width:200px;padding:10px 15px;background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-radius:8px;color:#fff;font-size:14px}._searchBox_wgq69_49::placeholder{color:#ffffff80}._filterSelect_wgq69_64{padding:10px 15px;background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-radius:8px;color:#fff;font-size:14px;cursor:pointer}._filterSelect_wgq69_64 option{background:#0f172a}._checkboxLabel_wgq69_78{display:flex;align-items:center;gap:8px;padding:10px 15px;background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-radius:8px;cursor:pointer;font-size:14px}._checkboxLabel_wgq69_78 input{cursor:pointer}
@@ -1,2 +0,0 @@
1
- import{U as e}from"./unified-data-viewer.js";class t{constructor(){this.container=null,this.events=[],this.processedEventIds=new Set,this.sessions=new Map,this.currentSession=null,this.selectedSessionFilter="all",this.timeRange="30min",this.searchTerm="",this.initialized=!1,this.expandedSessions=new Set,this.expandedAgents=new Set,this.expandedTools=new Set,this.selectedItem=null,this.sessionFilterInitialized=!1,this.renderTreeDebounced=this.debounce(()=>this.renderTree(),100)}debounce(e,t){let s;return function(...n){clearTimeout(s),s=setTimeout(()=>{clearTimeout(s),e(...n)},t)}}initialize(){if(console.log("ActivityTree.initialize() called, initialized:",this.initialized),this.initialized)return void console.log("Activity tree already initialized, skipping");if(this.container=document.getElementById("activity-tree-container"),!this.container&&(this.container=document.getElementById("activity-tree"),!this.container))return void console.error("Activity tree container not found in DOM");const e=document.getElementById("activity-tab");if(e){if(!e.classList.contains("active"))return console.log("Activity tab not active, initializing but deferring render"),this.setupControls(),this.subscribeToEvents(),void(this.initialized=!0);this.setupControls(),this.createLinearTreeView(),this.subscribeToEvents(),this.initialized=!0,console.log("Activity tree initialization complete")}else console.error("Activity tab panel (#activity-tab) not found in DOM")}forceShow(){console.log("ActivityTree.forceShow() called"),this.container||(this.container=document.getElementById("activity-tree-container")||document.getElementById("activity-tree"),this.container)?(this.createLinearTreeView(),this.renderTree()):console.error("Cannot find activity tree container")}renderWhenVisible(){if(console.log("ActivityTree.renderWhenVisible() called"),!this.initialized)return console.log("Not initialized yet, calling initialize..."),void this.initialize();this.createLinearTreeView(),this.renderTree()}setupControls(){const e=document.getElementById("time-range");e&&e.addEventListener("change",e=>{this.timeRange=e.target.value,console.log(`ActivityTree: Time range changed to: ${this.timeRange}`),this.renderTree()}),document.addEventListener("sessionFilterChanged",e=>{this.selectedSessionFilter=e.detail.sessionId||"all",console.log(`ActivityTree: Session filter changed to: ${this.selectedSessionFilter} (from SessionManager)`),this.renderTree()}),document.addEventListener("sessionChanged",e=>{this.selectedSessionFilter=e.detail.sessionId||"all",console.log(`ActivityTree: Session changed to: ${this.selectedSessionFilter} (from SessionManager - backward compat)`),this.renderTree()}),setTimeout(()=>{if(window.sessionManager&&!this.sessionFilterInitialized){const e=window.sessionManager.getCurrentFilter();e!==this.selectedSessionFilter&&(this.selectedSessionFilter=e||"all",console.log(`ActivityTree: Initialized with current session filter: ${this.selectedSessionFilter}`),this.sessionFilterInitialized=!0,this.renderTree())}},100);const t=document.getElementById("expand-all");t&&t.addEventListener("click",()=>this.expandAllSessions());const s=document.getElementById("collapse-all");s&&s.addEventListener("click",()=>this.collapseAllSessions());const n=document.getElementById("reset-zoom");n&&(n.style.display="inline-block",n.addEventListener("click",()=>this.resetZoom()));const o=document.getElementById("activity-search");o&&o.addEventListener("input",e=>{this.searchTerm=e.target.value.toLowerCase(),this.renderTree()})}createLinearTreeView(){console.log("Creating linear tree view"),this.container.innerHTML="";const e=document.createElement("div");e.id="linear-tree",e.className="linear-tree",this.container.appendChild(e),console.log("Linear tree view created")}subscribeToEvents(){if(!window.socketClient)return console.warn("Socket client not available for activity tree"),void setTimeout(()=>this.subscribeToEvents(),1e3);console.log("ActivityTree: Setting up event subscription"),window.socketClient.onEventUpdate((e,t)=>{console.log(`ActivityTree: onEventUpdate called with ${e.length} total events and ${t.size} sessions`);for(const[n,o]of t.entries())if(this.sessions.has(n)){const e=this.sessions.get(n);e.timestamp=new Date(o.lastActivity||o.startTime||e.timestamp),e.eventCount=o.eventCount,e.status=o.status||e.status,e.working_directory=o.working_directory||e.working_directory,e.git_branch=o.git_branch||e.git_branch}else{const e={id:n,timestamp:new Date(o.lastActivity||o.startTime||new Date),expanded:this.expandedSessions.has(n)||!0,agents:new Map,todos:[],userInstructions:[],tools:[],toolsMap:new Map,status:"active",currentTodoTool:null,working_directory:o.working_directory,git_branch:o.git_branch,eventCount:o.eventCount};this.sessions.set(n,e)}const s=e.filter(e=>{const t=e.id||`${e.type}-${e.timestamp}-${Math.random()}`;return!this.processedEventIds.has(t)});s.length>0&&(console.log(`ActivityTree: Processing ${s.length} new events`,s),s.forEach(e=>{const t=e.id||`${e.type}-${e.timestamp}-${Math.random()}`;this.processedEventIds.add(t),this.processEvent(e)})),this.events=[...e],this.renderTreeDebounced(),console.log("ActivityTree: Sessions after sync with socket client:",Array.from(this.sessions.entries()))});const e=window.socketClient?.getState();if(e&&e.events.length>0){console.log(`ActivityTree: Loading existing data - ${e.events.length} events, ${e.sessions.size} sessions`);for(const[s,n]of e.sessions.entries())if(!this.sessions.has(s)){const e={id:s,timestamp:new Date(n.lastActivity||n.startTime||new Date),expanded:this.expandedSessions.has(s)||!0,agents:new Map,todos:[],userInstructions:[],tools:[],toolsMap:new Map,status:"active",currentTodoTool:null,working_directory:n.working_directory,git_branch:n.git_branch,eventCount:n.eventCount};this.sessions.set(s,e)}const t=e.events.filter(e=>{const t=e.id||`${e.type}-${e.timestamp}-${Math.random()}`;return!this.processedEventIds.has(t)});t.length>0&&(console.log(`ActivityTree: Processing ${t.length} unprocessed events from initial load`),t.forEach(e=>{const t=e.id||`${e.type}-${e.timestamp}-${Math.random()}`;this.processedEventIds.add(t),this.processEvent(e)})),this.events=[...e.events],this.renderTree(),console.log("ActivityTree: Initial sessions state:",Array.from(this.sessions.entries()))}else console.log("ActivityTree: No existing events found"),this.events=[],this.sessions.clear(),this.renderTree()}processEvent(e){if(!e)return void console.log("ActivityTree: Ignoring null event");let t,s=this.getEventType(e);if(!s)return;console.log(`ActivityTree: Processing event: ${s}`,e),e.timestamp?(t=new Date(e.timestamp),isNaN(t.getTime())&&(console.warn("ActivityTree: Invalid timestamp, using current time:",e.timestamp),t=new Date)):(console.warn("ActivityTree: No timestamp found, using current time"),t=new Date);const n=e.session_id||e.data?.session_id;if(!n)return void console.log(`ActivityTree: Skipping event without session_id: ${s}`);if(!this.sessions.has(n))return void console.warn(`ActivityTree: Session ${n} not found in authoritative sessions - skipping event`);const o=this.sessions.get(n);switch(s){case"Start":this.currentSession=o;break;case"user_prompt":this.processUserInstruction(e,o);break;case"TodoWrite":break;case"SubagentStart":this.processSubagentStart(e,o);break;case"SubagentStop":this.processSubagentStop(e,o);break;case"PreToolUse":this.processToolUse(e,o);break;case"PostToolUse":this.updateToolStatus(e,o,"completed")}this.updateStats()}getEventType(e){if(e.hook_event_name)return e.hook_event_name;if("hook"===e.type&&e.subtype){return{pre_tool:"PreToolUse",post_tool:"PostToolUse",subagent_start:"SubagentStart",subagent_stop:"SubagentStop",todo_write:"TodoWrite"}[e.subtype]}if("todo"===e.type&&"updated"===e.subtype)return"TodoWrite";if("subagent"===e.type){if("started"===e.subtype)return"SubagentStart";if("stopped"===e.subtype)return"SubagentStop"}return"start"===e.type?"Start":"user_prompt"===e.type||"user_prompt"===e.subtype?"user_prompt":null}processUserInstruction(e,t){const s=e.prompt_text||e.data?.prompt_text||e.prompt||"";if(!s)return;const n={id:`instruction-${t.id}-${Date.now()}`,text:s,preview:s.length>100?s.substring(0,100)+"...":s,timestamp:e.timestamp||(new Date).toISOString(),type:"user_instruction"};if(t.agents.size>0){console.log("ActivityTree: New user prompt detected, collapsing previous agents");for(let e of t.agents.values())"active"===e.status&&(e.status="completed"),this.expandedAgents.delete(e.id)}t.currentActiveAgent=null,t.userInstructions.push(n),t.userInstructions.length>5&&(t.userInstructions=t.userInstructions.slice(-5))}processTodoWrite(e,t){let s=e.todos||e.data?.todos||e.data||[];if(s&&"object"==typeof s&&s.todos&&(s=s.todos),!Array.isArray(s)||0===s.length)return;t.currentTodos=s.map(t=>({content:t.content,activeForm:t.activeForm,status:t.status,timestamp:e.timestamp}));let n=t.currentActiveAgent;if(!n){const e=this.getAllAgents(t).filter(e=>"active"===e.status||"in_progress"===e.status).sort((e,t)=>new Date(t.timestamp)-new Date(e.timestamp));if(e.length>0)n=e[0];else{const e=this.getAllAgents(t),s=e.find(e=>e.isPM);s?n=s:e.length>0&&(n=e[0])}}if(n){n.todoWritesMap||(n.todoWritesMap=new Map),n.todoWrites||(n.todoWrites=[]);const t=n.todoWritesMap.get("TodoWrite");if(t)t.todos=s,t.timestamp=e.timestamp,t.updateCount=(t.updateCount||1)+1;else{const t={id:`todowrite-${n.id}-${Date.now()}`,name:"TodoWrite",type:"todowrite",icon:"📝",timestamp:e.timestamp,status:"completed",todos:s,params:{todos:s},updateCount:1};n.todoWritesMap.set("TodoWrite",t),n.todoWrites=[t]}n.currentTodos=s}else{t.todoWrites||(t.todoWrites=[]),t.todoWritesMap||(t.todoWritesMap=new Map);const n=t.todoWritesMap.get("TodoWrite");if(n)n.todos=s,n.timestamp=e.timestamp,n.updateCount=(n.updateCount||1)+1;else{const n={id:`todowrite-session-${Date.now()}`,name:"TodoWrite",type:"todowrite",icon:"📝",timestamp:e.timestamp,status:"completed",todos:s,updateCount:1};t.todoWritesMap.set("TodoWrite",n),t.todoWrites=[n]}}}processSubagentStart(e,t){const s=e.agent_name||e.data?.agent_name||e.data?.agent_type||e.agent_type||e.agent||"unknown",n=e.session_id||e.data?.session_id,o=e.parent_agent||e.data?.parent_agent,i=`${s}-${n||"no-session"}`;let a=null;let r;if(a=this.getAllAgents(t).find(e=>e.name===s&&e.sessionId===n&&"active"===e.status),a)r=a,r.timestamp=e.timestamp,r.instanceCount=(r.instanceCount||1)+1,this.expandedAgents.add(r.id);else{if(r={id:`agent-${i}-${Date.now()}`,name:s,type:"agent",icon:this.getAgentIcon(s),timestamp:e.timestamp,status:"active",tools:[],subagents:new Map,sessionId:n,parentAgent:o,isPM:"pm"===s.toLowerCase()||s.toLowerCase().includes("project manager"),instanceCount:1,toolsMap:new Map},o){let e=null;for(let[s,n]of t.agents.entries())if(n.sessionId===o||n.name===o){e=n;break}e?(e.subagents||(e.subagents=new Map),e.subagents.set(r.id,r)):t.agents.set(r.id,r)}else t.agents.set(r.id,r);this.expandedAgents.add(r.id)}t.currentActiveAgent=r}processSubagentStop(e,t){const s=e.session_id||e.data?.session_id;if(s&&t.agents.has(s)){t.agents.get(s).status="completed"}}processToolUse(e,t){const s=e.tool_name||e.data?.tool_name||e.tool||e.data?.tool||"unknown",n=e.tool_parameters||e.data?.tool_parameters||e.parameters||e.data?.parameters||{},o=e.session_id||e.data?.session_id;let i=t.currentActiveAgent;if(!i){const e=this.getAllAgents(t);i=e.find(e=>e.sessionId===o)||e.find(e=>"active"===e.status)||e[0]}if(i){i.toolsMap||(i.toolsMap=new Map),i.tools||(i.tools=[]);const t=this.getToolKey(s,n);let o=i.toolsMap.get(t);if(o)o.params=n,o.timestamp=e.timestamp,o.status="in_progress",o.eventId=e.id,o.callCount=(o.callCount||1)+1,i.currentTool=o;else{const o={id:`tool-${i.id}-${s}-${Date.now()}`,name:s,type:"tool",icon:this.getToolIcon(s),timestamp:e.timestamp,status:"in_progress",params:n,eventId:e.id,callCount:1,createdAt:e.timestamp};"Task"===s&&n.subagent_type&&(o.isSubagentTask=!0,o.subagentType=n.subagent_type),i.toolsMap.set(t,o),"TodoWrite"===s?i.tools.unshift(o):i.tools.push(o),i.currentTool=o}}else{t.tools||(t.tools=[]),t.toolsMap||(t.toolsMap=new Map);const o=this.getToolKey(s,n);let i=t.toolsMap.get(o);if(i)i.params=n,i.timestamp=e.timestamp,i.status="in_progress",i.eventId=e.id,i.callCount=(i.callCount||1)+1,t.currentTool=i;else{const i={id:`tool-session-${s}-${Date.now()}`,name:s,type:"tool",icon:this.getToolIcon(s),timestamp:e.timestamp,status:"in_progress",params:n,eventId:e.id,callCount:1,createdAt:e.timestamp};t.toolsMap.set(o,i),"TodoWrite"===s?t.tools.unshift(i):t.tools.push(i),t.currentTool=i}}}getToolKey(e,t){if("TodoWrite"===e)return"TodoWrite";let s=e;return"Edit"!==e&&"Write"!==e&&"Read"!==e||t.file_path&&(s+=`-${t.file_path}`),"Grep"!==e&&"Glob"!==e||!t.pattern||(s+=`-${t.pattern.substring(0,20)}`),s}updateToolStatus(e,t,s){const n=e.tool_name||e.data?.tool_name||e.tool||"unknown",o=e.tool_parameters||e.data?.tool_parameters||e.parameters||e.data?.parameters||{},i=e.session_id||e.data?.session_id,a=this.getToolKey(n,o);let r=t.currentActiveAgent;if(!r){const e=this.getAllAgents(t);r=e.find(e=>e.sessionId===i)||e.find(e=>"active"===e.status)}if(r&&r.toolsMap){const t=r.toolsMap.get(a);if(t)return t.status=s,t.completedAt=e.timestamp,(e.data?.result||e.result)&&(t.result=e.data?.result||e.result),void(e.data?.duration_ms&&(t.duration=e.data.duration_ms))}if(t.toolsMap){const n=t.toolsMap.get(a);if(n)return n.status=s,n.completedAt=e.timestamp,(e.data?.result||e.result)&&(n.result=e.data?.result||e.result),void(e.data?.duration_ms&&(n.duration=e.data.duration_ms))}console.log(`ActivityTree: Could not find tool to update status for ${n} with key ${a} (event ${e.id})`)}renderTree(){const e=document.getElementById("linear-tree");if(!e)return;e.innerHTML="";const t=Array.from(this.sessions.values()).sort((e,t)=>new Date(t.timestamp)-new Date(e.timestamp));for(let s of t){if("all"!==this.selectedSessionFilter&&this.selectedSessionFilter!==s.id)continue;const t=this.createSessionElement(s);e.appendChild(t)}}createSessionElement(e){const t=this.expandedSessions.has(e.id)||e.expanded;let s;try{const t=e.timestamp instanceof Date?e.timestamp:new Date(e.timestamp);isNaN(t.getTime())?(s="Invalid Date",console.warn("ActivityTree: Invalid session timestamp:",e.timestamp)):s=t.toLocaleString()}catch(l){s="Invalid Date",console.error("ActivityTree: Error formatting session timestamp:",l,e.timestamp)}const n=document.createElement("div");n.className="tree-node session",n.dataset.sessionId=e.id;const o=t?"▼":"▶",i=this.getAllAgents(e).length,a=e.currentTodos?e.currentTodos.length:0,r=e.userInstructions?e.userInstructions.length:0;return console.log(`ActivityTree: Rendering session ${e.id}: ${i} agents, ${r} instructions, ${a} todos at ${s}`),n.innerHTML=`\n <div class="tree-node-content" onclick="window.activityTreeInstance.toggleSession('${e.id}')">\n <span class="tree-expand-icon">${o}</span>\n <span class="tree-icon">🎯</span>\n <span class="tree-label">PM Session</span>\n <span class="tree-meta">${s} • ${i} agent(s) • ${r} instruction(s) • ${a} todo(s)</span>\n </div>\n <div class="tree-children" style="display: ${t?"block":"none"}">\n ${this.renderSessionContent(e)}\n </div>\n `,n}renderSessionContent(e){let t="";if(e.userInstructions&&e.userInstructions.length>0)for(let n of e.userInstructions.slice(-3))t+=this.renderUserInstructionElement(n,1);if(e.tools&&e.tools.length>0)for(let n of e.tools)t+=this.renderToolElement(n,1);const s=Array.from(e.agents.values()).sort((e,t)=>new Date(t.timestamp)-new Date(e.timestamp));for(let n of s)t+=this.renderAgentElement(n,1);return t}renderUserInstructionElement(e,t){return`\n <div class="tree-node user-instruction ${this.selectedItem&&"instruction"===this.selectedItem.type&&this.selectedItem.data.id===e.id?"selected":""}" data-level="${t}">\n <div class="tree-node-content">\n <span class="tree-expand-icon"></span>\n <span class="tree-icon">💬</span>\n <span class="tree-label clickable" onclick="window.activityTreeInstance.selectItem(${this.escapeJson(e)}, 'instruction', event)">User: "${this.escapeHtml(e.preview)}"</span>\n <span class="tree-status status-active">instruction</span>\n </div>\n </div>\n `}renderTodoChecklistElement(e,t){const s=`checklist-${Date.now()}`,n=!1!==this.expandedTools.has(s),o=n?"▼":"▶";let i=0,a=0;e.forEach(e=>{"completed"===e.status?i++:"in_progress"===e.status&&a++});let r="";r=a>0?`${a} in progress, ${i} completed`:i===e.length&&e.length>0?`All ${e.length} completed`:`${e.length} todo(s)`;let l=`\n <div class="tree-node todo-checklist" data-level="${t}">\n <div class="tree-node-content">\n <span class="tree-expand-icon" onclick="window.activityTreeInstance.toggleTodoChecklist('${s}'); event.stopPropagation();">${o}</span>\n <span class="tree-icon">☑️</span>\n <span class="tree-label">TODOs</span>\n <span class="tree-params">${r}</span>\n <span class="tree-status status-active">checklist</span>\n </div>\n `;if(n){l+='<div class="tree-children">';for(let s of e){const e=this.getCheckboxIcon(s.status),n=`status-${s.status}`,o="in_progress"===s.status?s.activeForm:s.content;l+=`\n <div class="tree-node todo-item ${n}" data-level="${t+1}">\n <div class="tree-node-content">\n <span class="tree-expand-icon"></span>\n <span class="tree-icon">${e}</span>\n <span class="tree-label">${this.escapeHtml(o)}</span>\n <span class="tree-status ${n}">${s.status.replace("_"," ")}</span>\n </div>\n </div>\n `}l+="</div>"}return l+="</div>",l}renderAgentElement(e,t){const s="active"===e.status?"status-active":"status-completed",n=this.expandedAgents.has(e.id),o=e.tools&&e.tools.length>0,i=e.subagents&&e.subagents.size>0,a=o||i,r=a?n?"▼":"▶":"",l=this.selectedItem&&"agent"===this.selectedItem.type&&this.selectedItem.data.id===e.id?"selected":"",c=e.instanceCount>1?` (${e.instanceCount}x)`:"";let d="";if(!n&&a){const t=[];if(e.currentTodos&&e.currentTodos.length>0){const s=e.currentTodos.find(e=>"in_progress"===e.status);s&&t.push(`📝 ${s.activeForm||s.content}`)}e.currentTool&&t.push(`${e.currentTool.icon} ${e.currentTool.name}`),t.length>0&&(d=` • ${t.join(" • ")}`)}let p=`\n <div class="tree-node agent ${s} ${l}" data-level="${t}">\n <div class="tree-node-content">\n ${r?`<span class="tree-expand-icon" onclick="window.activityTreeInstance.toggleAgent('${e.id}'); event.stopPropagation();">${r}</span>`:'<span class="tree-expand-icon"></span>'}\n <span class="tree-icon">${e.icon}</span>\n <span class="tree-label clickable" onclick="window.activityTreeInstance.selectItem(${this.escapeJson(e)}, 'agent', event)">${e.name}${c}${d}</span>\n <span class="tree-status ${s}">${e.status}</span>\n </div>\n `;if(a&&n){if(p+='<div class="tree-children">',o)for(let s of e.tools)p+=this.renderToolElement(s,t+1);if(i){const s=Array.from(e.subagents.values());for(let e of s)p+=this.renderAgentElement(e,t+1)}p+="</div>"}return p+="</div>",p}renderToolElement(e,t){const s=`status-${e.status}`,n=this.getToolParams(e),o=this.selectedItem&&"tool"===this.selectedItem.type&&this.selectedItem.data.id===e.id?"selected":"",i=this.getToolStatusIcon(e.status),a=this.getToolStatusLabel(e.status),r=e.callCount>1?` (${e.callCount} calls)`:"";return`\n <div class="tree-node tool ${s} ${o}" data-level="${t}">\n <div class="tree-node-content">\n <span class="tree-expand-icon"></span>\n <span class="tree-icon">${e.icon}</span>\n <span class="tree-status-icon">${i}</span>\n <span class="tree-label clickable" onclick="window.activityTreeInstance.selectItem(${this.escapeJson(e)}, 'tool', event)">${e.name}${r}</span>\n <span class="tree-params">${n}</span>\n <span class="tree-status ${s}">${a}</span>\n </div>\n </div>\n `}getToolParams(e){if(!e.params)return"";if("Read"===e.name&&e.params.file_path)return e.params.file_path;if("Edit"===e.name&&e.params.file_path)return e.params.file_path;if("Write"===e.name&&e.params.file_path)return e.params.file_path;if("Bash"===e.name&&e.params.command){const t=e.params.command;return t.length>50?t.substring(0,50)+"...":t}return"WebFetch"===e.name&&e.params.url?e.params.url:""}getStatusIcon(e){return{pending:"⏸️",in_progress:"🔄",completed:"✅"}[e]||"❓"}getCheckboxIcon(e){return{pending:"⏳",in_progress:"🔄",completed:"✅"}[e]||"❓"}getAgentIcon(e){return{engineer:"👷",research:"🔬",qa:"🧪",ops:"⚙️",pm:"📊",architect:"🏗️","project manager":"📊"}[e.toLowerCase()]||"🤖"}getAllAgents(e){const t=[],s=e=>{if(e)for(let n of e.values())t.push(n),n.subagents&&n.subagents.size>0&&s(n.subagents)};return s(e.agents),t}renderTodoWriteElement(e,t){const s=e.id,n=this.expandedTools.has(s),o=n?"▼":"▶",i=e.todos||[];let a=0,r=0;i.forEach(e=>{"completed"===e.status?a++:"in_progress"===e.status&&r++});const l=i.find(e=>"in_progress"===e.status),c=l?` • 🔄 ${l.activeForm||l.content}`:"";let d="";d=r>0?`${r} in progress, ${a}/${i.length} done`:a===i.length&&i.length>0?`All ${i.length} completed ✅`:`${a}/${i.length} done`;let p=`\n <div class="tree-node todowrite ${l?"has-active":""}" data-level="${t}">\n <div class="tree-node-content">\n <span class="tree-expand-icon" onclick="window.activityTreeInstance.toggleTodoWrite('${s}'); event.stopPropagation();">${o}</span>\n <span class="tree-icon">📝</span>\n <span class="tree-label">TodoWrite${e.updateCount>1?` (${e.updateCount} updates)`:""}${n?"":c}</span>\n <span class="tree-params">${d}</span>\n <span class="tree-status status-active">todos</span>\n </div>\n `;if(n&&i.length>0){p+='<div class="tree-children">';for(let e of i){const s=this.getCheckboxIcon(e.status),n=`status-${e.status}`,o="in_progress"===e.status?e.activeForm:e.content;p+=`\n <div class="tree-node todo-item ${n} ${e===l?"current-active":""}" data-level="${t+1}">\n <div class="tree-node-content">\n <span class="tree-expand-icon"></span>\n <span class="tree-icon">${s}</span>\n <span class="tree-label">${this.escapeHtml(o)}</span>\n <span class="tree-status ${n}">${e.status.replace("_"," ")}</span>\n </div>\n </div>\n `}p+="</div>"}return p+="</div>",p}toggleTodoWrite(e){this.expandedTools.has(e)?this.expandedTools.delete(e):this.expandedTools.add(e),this.renderTree()}getToolIcon(e){return{read:"👁️",write:"✍️",edit:"✏️",bash:"💻",webfetch:"🌐",grep:"🔍",glob:"📂",todowrite:"📝"}[e.toLowerCase()]||"🔧"}getToolStatusIcon(e){return{in_progress:"⏳",completed:"✅",failed:"❌",error:"❌",pending:"⏸️",active:"🔄"}[e]||"❓"}getToolStatusLabel(e){return{in_progress:"in progress",completed:"completed",failed:"failed",error:"error",pending:"pending",active:"active"}[e]||e}toggleSession(e){this.expandedSessions.has(e)?this.expandedSessions.delete(e):this.expandedSessions.add(e);const t=this.sessions.get(e);t&&(t.expanded=this.expandedSessions.has(e)),this.renderTree()}expandAllSessions(){for(let e of this.sessions.keys()){this.expandedSessions.add(e);const t=this.sessions.get(e);t&&(t.expanded=!0)}this.renderTree()}collapseAllSessions(){this.expandedSessions.clear();for(let e of this.sessions.values())e.expanded=!1;this.renderTree()}updateStats(){const e=this.countTotalNodes(),t=this.countActiveNodes(),s=this.calculateMaxDepth(),n=document.getElementById("node-count"),o=document.getElementById("active-count"),i=document.getElementById("tree-depth");n&&(n.textContent=e),o&&(o.textContent=t),i&&(i.textContent=s),console.log(`ActivityTree: Stats updated - Nodes: ${e}, Active: ${t}, Depth: ${s}`)}countTotalNodes(){let e=0;for(let t of this.sessions.values()){e+=1,e+=t.agents.size,t.userInstructions&&(e+=t.userInstructions.length),t.todos&&(e+=t.todos.length),t.tools&&(e+=t.tools.length);for(let s of t.agents.values())s.tools&&(e+=s.tools.length)}return e}countActiveNodes(){let e=0;for(let t of this.sessions.values()){if("active"===t.status&&e++,t.todos)for(let s of t.todos)"in_progress"===s.status&&e++;if(t.tools)for(let s of t.tools)"in_progress"===s.status&&e++;for(let s of t.agents.values())if("active"===s.status&&e++,s.tools)for(let t of s.tools)"in_progress"===t.status&&e++}return e}calculateMaxDepth(){let e=0;for(let t of this.sessions.values()){let s=1;t.userInstructions&&t.userInstructions.length>0&&(s=Math.max(s,2)),t.todos&&t.todos.length>0&&(s=Math.max(s,3)),t.tools&&t.tools.length>0&&(s=Math.max(s,2));for(let e of t.agents.values())e.tools&&e.tools.length>0&&(s=Math.max(s,3));e=Math.max(e,s)}return e}toggleAgent(e){this.expandedAgents.has(e)?this.expandedAgents.delete(e):this.expandedAgents.add(e),this.renderTree()}toggleTool(e){console.log("Tool expansion is disabled. Tools now show data in the left pane when clicked.")}toggleTodoChecklist(e){this.expandedTools.has(e)?this.expandedTools.delete(e):this.expandedTools.add(e),this.renderTree()}renderPinnedTodosElement(e,t){const s=`pinned-todos-${Date.now()}`,n=!1!==this.expandedTools.has(s),o=n?"▼":"▶",i=e.todos||[];let a=0,r=0;i.forEach(e=>{"completed"===e.status?a++:"in_progress"===e.status&&r++});let l="";l=r>0?`${r} in progress, ${a} completed`:a===i.length&&i.length>0?`All ${i.length} completed`:`${i.length} todo(s)`;let c=`\n <div class="tree-node pinned-todos" data-level="${t}">\n <div class="tree-node-content">\n <span class="tree-expand-icon" onclick="window.activityTreeInstance.toggleTodoChecklist('${s}'); event.stopPropagation();">${o}</span>\n <span class="tree-icon">📌</span>\n <span class="tree-label">Pinned TODOs</span>\n <span class="tree-params">${l}</span>\n <span class="tree-status status-active">pinned</span>\n </div>\n `;if(n){c+='<div class="tree-children">';for(let e of i){const s=this.getCheckboxIcon(e.status),n=`status-${e.status}`,o="in_progress"===e.status?e.activeForm:e.content;c+=`\n <div class="tree-node todo-item ${n}" data-level="${t+1}">\n <div class="tree-node-content">\n <span class="tree-expand-icon"></span>\n <span class="tree-icon">${s}</span>\n <span class="tree-label">${this.escapeHtml(o)}</span>\n <span class="tree-status ${n}">${e.status.replace("_"," ")}</span>\n </div>\n </div>\n `}c+="</div>"}return c+="</div>",c}selectItem(e,t,s){s&&s.stopPropagation(),this.selectedItem={data:e,type:t},this.displayItemData(e,t),this.renderTree()}displayItemData(t,s){this.unifiedViewer||(this.unifiedViewer=new e("module-data-content")),this.unifiedViewer.display(t,s);const n=document.querySelector(".module-data-header h5");if(n){const e={agent:"🤖",tool:"🔧",instruction:"💬",session:"🎯",todo:"📝"}[s]||"📊",o=t.name||t.agentName||t.tool_name||"Item";n.textContent=`${e} ${s}: ${o}`}}escapeHtml(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}resetZoom(){this.svg&&this.zoom&&this.svg.transition().duration(this.duration).call(this.zoom.transform,d3.zoomIdentity)}escapeJson(e){return JSON.stringify(e).replace(/'/g,"&apos;").replace(/"/g,"&quot;")}}window.ActivityTree=t;const s=()=>{let e=null;const s=()=>{e||(console.log("Creating new Activity Tree instance..."),e=new t,window.activityTreeInstance=e,window.activityTree=()=>e),setTimeout(()=>{console.log("Attempting to initialize Activity Tree visualization..."),e.initialize()},100)};document.addEventListener("tabChanged",t=>{t.detail&&"activity"===t.detail.newTab&&(console.log("Tab changed to activity, initializing tree..."),s(),e&&setTimeout(()=>{e.renderWhenVisible(),e.forceShow()},150))});const n=document.querySelector(".tab-button.active");n&&"activity"===n.getAttribute("data-tab")&&(console.log("Activity tab is active on load, initializing tree..."),s());const o=document.getElementById("activity-tab");o&&o.classList.contains("active")&&(console.log("Activity panel is active on load, initializing tree..."),e||s())};"loading"===document.readyState?document.addEventListener("DOMContentLoaded",s):s();
2
- //# sourceMappingURL=activity-tree.js.map