claude-mpm 4.21.3__py3-none-any.whl → 5.0.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (484) 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 +632 -334
  5. claude_mpm/agents/WORKFLOW.md +75 -2
  6. claude_mpm/agents/__init__.py +6 -0
  7. claude_mpm/agents/agent_loader.py +1 -4
  8. claude_mpm/agents/base_agent.json +6 -3
  9. claude_mpm/agents/frontmatter_validator.py +1 -1
  10. claude_mpm/agents/templates/{circuit_breakers.md → circuit-breakers.md} +370 -3
  11. claude_mpm/agents/templates/context-management-examples.md +544 -0
  12. claude_mpm/agents/templates/{pm_red_flags.md → pm-red-flags.md} +89 -19
  13. claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
  14. claude_mpm/agents/templates/research-gate-examples.md +669 -0
  15. claude_mpm/agents/templates/structured-questions-examples.md +615 -0
  16. claude_mpm/agents/templates/ticket-completeness-examples.md +139 -0
  17. claude_mpm/agents/templates/ticketing-examples.md +277 -0
  18. claude_mpm/cli/__init__.py +38 -2
  19. claude_mpm/cli/commands/agent_source.py +774 -0
  20. claude_mpm/cli/commands/agent_state_manager.py +125 -20
  21. claude_mpm/cli/commands/agents.py +684 -13
  22. claude_mpm/cli/commands/agents_cleanup.py +210 -0
  23. claude_mpm/cli/commands/agents_discover.py +338 -0
  24. claude_mpm/cli/commands/aggregate.py +1 -1
  25. claude_mpm/cli/commands/analyze.py +3 -3
  26. claude_mpm/cli/commands/auto_configure.py +2 -6
  27. claude_mpm/cli/commands/cleanup.py +1 -1
  28. claude_mpm/cli/commands/config.py +7 -4
  29. claude_mpm/cli/commands/configure.py +478 -44
  30. claude_mpm/cli/commands/configure_agent_display.py +4 -4
  31. claude_mpm/cli/commands/configure_navigation.py +63 -46
  32. claude_mpm/cli/commands/debug.py +12 -12
  33. claude_mpm/cli/commands/doctor.py +10 -2
  34. claude_mpm/cli/commands/hook_errors.py +277 -0
  35. claude_mpm/cli/commands/local_deploy.py +1 -4
  36. claude_mpm/cli/commands/mcp_install_commands.py +1 -1
  37. claude_mpm/cli/commands/mpm_init/core.py +50 -2
  38. claude_mpm/cli/commands/mpm_init/git_activity.py +10 -10
  39. claude_mpm/cli/commands/mpm_init/prompts.py +6 -6
  40. claude_mpm/cli/commands/run.py +124 -128
  41. claude_mpm/cli/commands/skill_source.py +694 -0
  42. claude_mpm/cli/commands/skills.py +435 -1
  43. claude_mpm/cli/executor.py +78 -3
  44. claude_mpm/cli/interactive/agent_wizard.py +919 -41
  45. claude_mpm/cli/parsers/agent_source_parser.py +171 -0
  46. claude_mpm/cli/parsers/agents_parser.py +173 -4
  47. claude_mpm/cli/parsers/base_parser.py +49 -0
  48. claude_mpm/cli/parsers/config_parser.py +96 -43
  49. claude_mpm/cli/parsers/skill_source_parser.py +169 -0
  50. claude_mpm/cli/parsers/skills_parser.py +138 -0
  51. claude_mpm/cli/parsers/source_parser.py +138 -0
  52. claude_mpm/cli/startup.py +499 -84
  53. claude_mpm/cli/startup_display.py +480 -0
  54. claude_mpm/cli/utils.py +1 -1
  55. claude_mpm/cli_module/commands.py +1 -1
  56. claude_mpm/commands/{mpm-auto-configure.md → mpm-agents-auto-configure.md} +9 -0
  57. claude_mpm/commands/mpm-agents-detect.md +9 -0
  58. claude_mpm/commands/{mpm-agents.md → mpm-agents-list.md} +9 -0
  59. claude_mpm/commands/mpm-agents-recommend.md +9 -0
  60. claude_mpm/commands/{mpm-config.md → mpm-config-view.md} +9 -0
  61. claude_mpm/commands/mpm-doctor.md +9 -0
  62. claude_mpm/commands/mpm-help.md +11 -2
  63. claude_mpm/commands/mpm-init.md +27 -2
  64. claude_mpm/commands/mpm-monitor.md +9 -0
  65. claude_mpm/commands/{mpm-resume.md → mpm-session-resume.md} +9 -0
  66. claude_mpm/commands/mpm-status.md +9 -0
  67. claude_mpm/commands/{mpm-organize.md → mpm-ticket-organize.md} +9 -0
  68. claude_mpm/commands/mpm-ticket-view.md +552 -0
  69. claude_mpm/commands/mpm-version.md +9 -0
  70. claude_mpm/commands/mpm.md +10 -0
  71. claude_mpm/config/agent_presets.py +258 -0
  72. claude_mpm/config/agent_sources.py +325 -0
  73. claude_mpm/config/skill_sources.py +590 -0
  74. claude_mpm/constants.py +12 -0
  75. claude_mpm/core/api_validator.py +1 -1
  76. claude_mpm/core/claude_runner.py +17 -10
  77. claude_mpm/core/config.py +24 -0
  78. claude_mpm/core/constants.py +1 -1
  79. claude_mpm/core/framework/__init__.py +3 -16
  80. claude_mpm/core/framework/loaders/instruction_loader.py +25 -5
  81. claude_mpm/core/framework/processors/metadata_processor.py +1 -1
  82. claude_mpm/core/hook_error_memory.py +381 -0
  83. claude_mpm/core/hook_manager.py +41 -2
  84. claude_mpm/core/interactive_session.py +112 -5
  85. claude_mpm/core/logger.py +3 -1
  86. claude_mpm/core/oneshot_session.py +94 -4
  87. claude_mpm/dashboard/static/css/activity.css +69 -69
  88. claude_mpm/dashboard/static/css/connection-status.css +10 -10
  89. claude_mpm/dashboard/static/css/dashboard.css +15 -15
  90. claude_mpm/dashboard/static/js/components/activity-tree.js +178 -178
  91. claude_mpm/dashboard/static/js/components/agent-hierarchy.js +101 -101
  92. claude_mpm/dashboard/static/js/components/agent-inference.js +31 -31
  93. claude_mpm/dashboard/static/js/components/build-tracker.js +59 -59
  94. claude_mpm/dashboard/static/js/components/code-simple.js +107 -107
  95. claude_mpm/dashboard/static/js/components/connection-debug.js +101 -101
  96. claude_mpm/dashboard/static/js/components/diff-viewer.js +113 -113
  97. claude_mpm/dashboard/static/js/components/event-viewer.js +12 -12
  98. claude_mpm/dashboard/static/js/components/file-change-tracker.js +57 -57
  99. claude_mpm/dashboard/static/js/components/file-change-viewer.js +74 -74
  100. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +6 -6
  101. claude_mpm/dashboard/static/js/components/file-viewer.js +42 -42
  102. claude_mpm/dashboard/static/js/components/module-viewer.js +27 -27
  103. claude_mpm/dashboard/static/js/components/session-manager.js +14 -14
  104. claude_mpm/dashboard/static/js/components/socket-manager.js +1 -1
  105. claude_mpm/dashboard/static/js/components/ui-state-manager.js +14 -14
  106. claude_mpm/dashboard/static/js/components/unified-data-viewer.js +110 -110
  107. claude_mpm/dashboard/static/js/components/working-directory.js +8 -8
  108. claude_mpm/dashboard/static/js/connection-manager.js +76 -76
  109. claude_mpm/dashboard/static/js/dashboard.js +76 -58
  110. claude_mpm/dashboard/static/js/extension-error-handler.js +22 -22
  111. claude_mpm/dashboard/static/js/socket-client.js +138 -121
  112. claude_mpm/dashboard/templates/code_simple.html +23 -23
  113. claude_mpm/dashboard/templates/index.html +18 -18
  114. claude_mpm/experimental/cli_enhancements.py +1 -5
  115. claude_mpm/hooks/claude_hooks/event_handlers.py +3 -1
  116. claude_mpm/hooks/claude_hooks/hook_handler.py +24 -7
  117. claude_mpm/hooks/claude_hooks/installer.py +45 -0
  118. claude_mpm/hooks/failure_learning/__init__.py +2 -8
  119. claude_mpm/hooks/failure_learning/failure_detection_hook.py +1 -6
  120. claude_mpm/hooks/failure_learning/fix_detection_hook.py +1 -6
  121. claude_mpm/hooks/failure_learning/learning_extraction_hook.py +1 -6
  122. claude_mpm/hooks/kuzu_response_hook.py +1 -5
  123. claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
  124. claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
  125. claude_mpm/models/git_repository.py +198 -0
  126. claude_mpm/scripts/claude-hook-handler.sh +3 -3
  127. claude_mpm/scripts/start_activity_logging.py +3 -1
  128. claude_mpm/services/agents/agent_builder.py +45 -9
  129. claude_mpm/services/agents/agent_preset_service.py +238 -0
  130. claude_mpm/services/agents/agent_selection_service.py +484 -0
  131. claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
  132. claude_mpm/services/agents/deployment/agent_deployment.py +126 -2
  133. claude_mpm/services/agents/deployment/agent_discovery_service.py +105 -73
  134. claude_mpm/services/agents/deployment/agent_format_converter.py +1 -1
  135. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +1 -5
  136. claude_mpm/services/agents/deployment/agent_metrics_collector.py +3 -3
  137. claude_mpm/services/agents/deployment/agent_restore_handler.py +1 -4
  138. claude_mpm/services/agents/deployment/agent_template_builder.py +236 -15
  139. claude_mpm/services/agents/deployment/agents_directory_resolver.py +101 -15
  140. claude_mpm/services/agents/deployment/async_agent_deployment.py +2 -1
  141. claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -3
  142. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +115 -15
  143. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +2 -2
  144. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +1 -4
  145. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +363 -0
  146. claude_mpm/services/agents/deployment/single_agent_deployer.py +2 -2
  147. claude_mpm/services/agents/deployment/system_instructions_deployer.py +168 -46
  148. claude_mpm/services/agents/deployment/validation/deployment_validator.py +2 -2
  149. claude_mpm/services/agents/git_source_manager.py +629 -0
  150. claude_mpm/services/agents/loading/framework_agent_loader.py +9 -12
  151. claude_mpm/services/agents/local_template_manager.py +50 -10
  152. claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
  153. claude_mpm/services/agents/sources/__init__.py +13 -0
  154. claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
  155. claude_mpm/services/agents/sources/git_source_sync_service.py +1055 -0
  156. claude_mpm/services/agents/startup_sync.py +239 -0
  157. claude_mpm/services/agents/toolchain_detector.py +474 -0
  158. claude_mpm/services/cli/session_pause_manager.py +1 -1
  159. claude_mpm/services/cli/unified_dashboard_manager.py +1 -1
  160. claude_mpm/services/command_deployment_service.py +92 -1
  161. claude_mpm/services/core/interfaces/__init__.py +1 -3
  162. claude_mpm/services/core/interfaces/health.py +1 -4
  163. claude_mpm/services/core/models/__init__.py +2 -11
  164. claude_mpm/services/diagnostics/checks/__init__.py +4 -0
  165. claude_mpm/services/diagnostics/checks/agent_check.py +0 -2
  166. claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
  167. claude_mpm/services/diagnostics/checks/instructions_check.py +1 -2
  168. claude_mpm/services/diagnostics/checks/mcp_check.py +0 -1
  169. claude_mpm/services/diagnostics/checks/monitor_check.py +0 -1
  170. claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
  171. claude_mpm/services/diagnostics/diagnostic_runner.py +9 -0
  172. claude_mpm/services/diagnostics/doctor_reporter.py +40 -10
  173. claude_mpm/services/event_bus/direct_relay.py +3 -3
  174. claude_mpm/services/event_bus/event_bus.py +36 -3
  175. claude_mpm/services/events/consumers/logging.py +1 -2
  176. claude_mpm/services/git/__init__.py +21 -0
  177. claude_mpm/services/git/git_operations_service.py +494 -0
  178. claude_mpm/services/github/__init__.py +21 -0
  179. claude_mpm/services/github/github_cli_service.py +397 -0
  180. claude_mpm/services/infrastructure/monitoring/__init__.py +1 -5
  181. claude_mpm/services/infrastructure/monitoring/aggregator.py +1 -6
  182. claude_mpm/services/infrastructure/monitoring/resources.py +1 -1
  183. claude_mpm/services/instructions/__init__.py +9 -0
  184. claude_mpm/services/instructions/instruction_cache_service.py +374 -0
  185. claude_mpm/services/local_ops/__init__.py +3 -13
  186. claude_mpm/services/local_ops/health_checks/__init__.py +1 -3
  187. claude_mpm/services/local_ops/health_manager.py +1 -4
  188. claude_mpm/services/local_ops/process_manager.py +1 -1
  189. claude_mpm/services/local_ops/resource_monitor.py +2 -2
  190. claude_mpm/services/mcp_gateway/config/configuration.py +1 -1
  191. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +1 -6
  192. claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -2
  193. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +1 -1
  194. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +6 -2
  195. claude_mpm/services/memory/optimizer.py +1 -1
  196. claude_mpm/services/model/model_router.py +8 -9
  197. claude_mpm/services/monitor/daemon.py +1 -1
  198. claude_mpm/services/monitor/server.py +2 -2
  199. claude_mpm/services/native_agent_converter.py +356 -0
  200. claude_mpm/services/port_manager.py +1 -1
  201. claude_mpm/services/pr/__init__.py +14 -0
  202. claude_mpm/services/pr/pr_template_service.py +329 -0
  203. claude_mpm/services/project/documentation_manager.py +2 -1
  204. claude_mpm/services/project/toolchain_analyzer.py +3 -1
  205. claude_mpm/services/runner_configuration_service.py +1 -0
  206. claude_mpm/services/self_upgrade_service.py +165 -7
  207. claude_mpm/services/skills/__init__.py +18 -0
  208. claude_mpm/services/skills/git_skill_source_manager.py +1169 -0
  209. claude_mpm/services/skills/skill_discovery_service.py +568 -0
  210. claude_mpm/services/skills_config.py +547 -0
  211. claude_mpm/services/skills_deployer.py +955 -0
  212. claude_mpm/services/socketio/handlers/connection.py +1 -1
  213. claude_mpm/services/socketio/handlers/git.py +2 -2
  214. claude_mpm/services/socketio/server/core.py +1 -4
  215. claude_mpm/services/socketio/server/main.py +1 -3
  216. claude_mpm/services/system_instructions_service.py +1 -3
  217. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +0 -3
  218. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +0 -1
  219. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +1 -1
  220. claude_mpm/services/unified/deployment_strategies/vercel.py +1 -5
  221. claude_mpm/services/unified/unified_deployment.py +1 -5
  222. claude_mpm/services/version_control/conflict_resolution.py +6 -4
  223. claude_mpm/services/visualization/__init__.py +1 -5
  224. claude_mpm/services/visualization/mermaid_generator.py +2 -3
  225. claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
  226. claude_mpm/skills/bundled/performance-profiling.md +6 -0
  227. claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +2 -2
  228. claude_mpm/skills/skills_registry.py +0 -1
  229. claude_mpm/templates/questions/__init__.py +38 -0
  230. claude_mpm/templates/questions/base.py +193 -0
  231. claude_mpm/templates/questions/pr_strategy.py +311 -0
  232. claude_mpm/templates/questions/project_init.py +385 -0
  233. claude_mpm/templates/questions/ticket_mgmt.py +394 -0
  234. claude_mpm/tools/__main__.py +8 -8
  235. claude_mpm/tools/code_tree_analyzer/analysis.py +1 -1
  236. claude_mpm/utils/agent_dependency_loader.py +80 -13
  237. claude_mpm/utils/dependency_cache.py +3 -1
  238. claude_mpm/utils/gitignore.py +241 -0
  239. claude_mpm/utils/log_cleanup.py +3 -3
  240. claude_mpm/utils/progress.py +383 -0
  241. claude_mpm/utils/robust_installer.py +3 -5
  242. claude_mpm/utils/structured_questions.py +619 -0
  243. {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/METADATA +429 -59
  244. {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/RECORD +252 -425
  245. claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -17
  246. claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +0 -3
  247. claude_mpm/agents/templates/agent-manager.json +0 -273
  248. claude_mpm/agents/templates/agentic-coder-optimizer.json +0 -248
  249. claude_mpm/agents/templates/api_qa.json +0 -180
  250. claude_mpm/agents/templates/clerk-ops.json +0 -235
  251. claude_mpm/agents/templates/code_analyzer.json +0 -101
  252. claude_mpm/agents/templates/content-agent.json +0 -358
  253. claude_mpm/agents/templates/dart_engineer.json +0 -307
  254. claude_mpm/agents/templates/data_engineer.json +0 -225
  255. claude_mpm/agents/templates/documentation.json +0 -211
  256. claude_mpm/agents/templates/engineer.json +0 -210
  257. claude_mpm/agents/templates/gcp_ops_agent.json +0 -253
  258. claude_mpm/agents/templates/golang_engineer.json +0 -270
  259. claude_mpm/agents/templates/imagemagick.json +0 -264
  260. claude_mpm/agents/templates/java_engineer.json +0 -346
  261. claude_mpm/agents/templates/local_ops_agent.json +0 -1840
  262. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +0 -39
  263. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +0 -400
  264. claude_mpm/agents/templates/memory_manager.json +0 -158
  265. claude_mpm/agents/templates/nextjs_engineer.json +0 -285
  266. claude_mpm/agents/templates/ops.json +0 -185
  267. claude_mpm/agents/templates/php-engineer.json +0 -287
  268. claude_mpm/agents/templates/product_owner.json +0 -338
  269. claude_mpm/agents/templates/project_organizer.json +0 -140
  270. claude_mpm/agents/templates/prompt-engineer.json +0 -737
  271. claude_mpm/agents/templates/python_engineer.json +0 -387
  272. claude_mpm/agents/templates/qa.json +0 -242
  273. claude_mpm/agents/templates/react_engineer.json +0 -238
  274. claude_mpm/agents/templates/refactoring_engineer.json +0 -276
  275. claude_mpm/agents/templates/research.json +0 -188
  276. claude_mpm/agents/templates/ruby-engineer.json +0 -280
  277. claude_mpm/agents/templates/rust_engineer.json +0 -275
  278. claude_mpm/agents/templates/security.json +0 -202
  279. claude_mpm/agents/templates/svelte-engineer.json +0 -225
  280. claude_mpm/agents/templates/ticketing.json +0 -177
  281. claude_mpm/agents/templates/typescript_engineer.json +0 -285
  282. claude_mpm/agents/templates/vercel_ops_agent.json +0 -412
  283. claude_mpm/agents/templates/version_control.json +0 -157
  284. claude_mpm/agents/templates/web_qa.json +0 -399
  285. claude_mpm/agents/templates/web_ui.json +0 -189
  286. claude_mpm/commands/mpm-tickets.md +0 -102
  287. claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
  288. claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +0 -188
  289. claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +0 -156
  290. claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +0 -38
  291. claude_mpm/dashboard/react/components/shared/FilterBar.module.css +0 -92
  292. claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +0 -248
  293. claude_mpm/dashboard/static/archive/activity_dashboard_test.html +0 -61
  294. claude_mpm/dashboard/static/archive/test_activity_connection.html +0 -179
  295. claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +0 -68
  296. claude_mpm/dashboard/static/archive/test_dashboard.html +0 -409
  297. claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +0 -519
  298. claude_mpm/dashboard/static/archive/test_dashboard_verification.html +0 -181
  299. claude_mpm/dashboard/static/archive/test_file_data.html +0 -315
  300. claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +0 -243
  301. claude_mpm/dashboard/static/archive/test_file_tree_fix.html +0 -234
  302. claude_mpm/dashboard/static/archive/test_file_tree_rename.html +0 -117
  303. claude_mpm/dashboard/static/archive/test_file_tree_tab.html +0 -115
  304. claude_mpm/dashboard/static/archive/test_file_viewer.html +0 -224
  305. claude_mpm/dashboard/static/archive/test_final_activity.html +0 -220
  306. claude_mpm/dashboard/static/archive/test_tab_fix.html +0 -139
  307. claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +0 -1
  308. claude_mpm/dashboard/static/built/components/activity-tree.js +0 -2
  309. claude_mpm/dashboard/static/built/components/agent-hierarchy.js +0 -777
  310. claude_mpm/dashboard/static/built/components/agent-inference.js +0 -2
  311. claude_mpm/dashboard/static/built/components/build-tracker.js +0 -333
  312. claude_mpm/dashboard/static/built/components/code-simple.js +0 -857
  313. claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +0 -353
  314. claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +0 -235
  315. claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +0 -409
  316. claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +0 -435
  317. claude_mpm/dashboard/static/built/components/code-tree.js +0 -2
  318. claude_mpm/dashboard/static/built/components/code-viewer.js +0 -2
  319. claude_mpm/dashboard/static/built/components/connection-debug.js +0 -654
  320. claude_mpm/dashboard/static/built/components/diff-viewer.js +0 -891
  321. claude_mpm/dashboard/static/built/components/event-processor.js +0 -2
  322. claude_mpm/dashboard/static/built/components/event-viewer.js +0 -2
  323. claude_mpm/dashboard/static/built/components/export-manager.js +0 -2
  324. claude_mpm/dashboard/static/built/components/file-change-tracker.js +0 -443
  325. claude_mpm/dashboard/static/built/components/file-change-viewer.js +0 -690
  326. claude_mpm/dashboard/static/built/components/file-tool-tracker.js +0 -2
  327. claude_mpm/dashboard/static/built/components/file-viewer.js +0 -2
  328. claude_mpm/dashboard/static/built/components/hud-library-loader.js +0 -2
  329. claude_mpm/dashboard/static/built/components/hud-manager.js +0 -2
  330. claude_mpm/dashboard/static/built/components/hud-visualizer.js +0 -2
  331. claude_mpm/dashboard/static/built/components/module-viewer.js +0 -2
  332. claude_mpm/dashboard/static/built/components/nav-bar.js +0 -145
  333. claude_mpm/dashboard/static/built/components/page-structure.js +0 -429
  334. claude_mpm/dashboard/static/built/components/session-manager.js +0 -2
  335. claude_mpm/dashboard/static/built/components/socket-manager.js +0 -2
  336. claude_mpm/dashboard/static/built/components/ui-state-manager.js +0 -2
  337. claude_mpm/dashboard/static/built/components/unified-data-viewer.js +0 -2
  338. claude_mpm/dashboard/static/built/components/working-directory.js +0 -2
  339. claude_mpm/dashboard/static/built/connection-manager.js +0 -536
  340. claude_mpm/dashboard/static/built/dashboard.js +0 -2
  341. claude_mpm/dashboard/static/built/extension-error-handler.js +0 -164
  342. claude_mpm/dashboard/static/built/react/events.js +0 -30
  343. claude_mpm/dashboard/static/built/shared/dom-helpers.js +0 -396
  344. claude_mpm/dashboard/static/built/shared/event-bus.js +0 -330
  345. claude_mpm/dashboard/static/built/shared/event-filter-service.js +0 -540
  346. claude_mpm/dashboard/static/built/shared/logger.js +0 -385
  347. claude_mpm/dashboard/static/built/shared/page-structure.js +0 -249
  348. claude_mpm/dashboard/static/built/shared/tooltip-service.js +0 -253
  349. claude_mpm/dashboard/static/built/socket-client.js +0 -2
  350. claude_mpm/dashboard/static/built/tab-isolation-fix.js +0 -185
  351. claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +0 -1
  352. claude_mpm/dashboard/static/dist/components/activity-tree.js +0 -2
  353. claude_mpm/dashboard/static/dist/components/agent-inference.js +0 -2
  354. claude_mpm/dashboard/static/dist/components/code-tree.js +0 -2
  355. claude_mpm/dashboard/static/dist/components/code-viewer.js +0 -2
  356. claude_mpm/dashboard/static/dist/components/event-processor.js +0 -2
  357. claude_mpm/dashboard/static/dist/components/event-viewer.js +0 -2
  358. claude_mpm/dashboard/static/dist/components/export-manager.js +0 -2
  359. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +0 -2
  360. claude_mpm/dashboard/static/dist/components/file-viewer.js +0 -2
  361. claude_mpm/dashboard/static/dist/components/hud-library-loader.js +0 -2
  362. claude_mpm/dashboard/static/dist/components/hud-manager.js +0 -2
  363. claude_mpm/dashboard/static/dist/components/hud-visualizer.js +0 -2
  364. claude_mpm/dashboard/static/dist/components/module-viewer.js +0 -2
  365. claude_mpm/dashboard/static/dist/components/session-manager.js +0 -2
  366. claude_mpm/dashboard/static/dist/components/socket-manager.js +0 -2
  367. claude_mpm/dashboard/static/dist/components/ui-state-manager.js +0 -2
  368. claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +0 -2
  369. claude_mpm/dashboard/static/dist/components/working-directory.js +0 -2
  370. claude_mpm/dashboard/static/dist/dashboard.js +0 -2
  371. claude_mpm/dashboard/static/dist/react/events.js +0 -30
  372. claude_mpm/dashboard/static/dist/socket-client.js +0 -2
  373. claude_mpm/dashboard/static/events.html +0 -607
  374. claude_mpm/dashboard/static/index.html +0 -635
  375. claude_mpm/dashboard/static/js/shared/dom-helpers.js +0 -396
  376. claude_mpm/dashboard/static/js/shared/event-bus.js +0 -330
  377. claude_mpm/dashboard/static/js/shared/logger.js +0 -385
  378. claude_mpm/dashboard/static/js/shared/tooltip-service.js +0 -253
  379. claude_mpm/dashboard/static/js/stores/dashboard-store.js +0 -562
  380. claude_mpm/dashboard/static/legacy/activity.html +0 -736
  381. claude_mpm/dashboard/static/legacy/agents.html +0 -786
  382. claude_mpm/dashboard/static/legacy/files.html +0 -747
  383. claude_mpm/dashboard/static/legacy/tools.html +0 -831
  384. claude_mpm/dashboard/static/monitors.html +0 -431
  385. claude_mpm/dashboard/static/production/events.html +0 -659
  386. claude_mpm/dashboard/static/production/main.html +0 -698
  387. claude_mpm/dashboard/static/production/monitors.html +0 -483
  388. claude_mpm/dashboard/static/test-archive/dashboard.html +0 -635
  389. claude_mpm/dashboard/static/test-archive/debug-events.html +0 -147
  390. claude_mpm/dashboard/static/test-archive/test-navigation.html +0 -256
  391. claude_mpm/dashboard/static/test-archive/test-react-exports.html +0 -180
  392. claude_mpm/dashboard/static/test-archive/test_debug.html +0 -25
  393. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +0 -79
  394. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +0 -178
  395. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +0 -577
  396. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +0 -467
  397. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +0 -537
  398. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +0 -730
  399. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +0 -112
  400. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +0 -146
  401. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +0 -412
  402. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +0 -81
  403. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +0 -362
  404. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +0 -312
  405. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +0 -152
  406. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +0 -668
  407. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +0 -587
  408. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +0 -438
  409. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +0 -391
  410. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +0 -119
  411. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +0 -148
  412. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +0 -483
  413. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +0 -452
  414. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +0 -449
  415. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +0 -411
  416. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +0 -14
  417. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +0 -58
  418. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +0 -68
  419. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +0 -69
  420. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +0 -131
  421. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +0 -325
  422. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +0 -490
  423. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +0 -425
  424. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +0 -499
  425. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +0 -86
  426. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +0 -43
  427. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +0 -47
  428. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +0 -65
  429. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +0 -30
  430. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +0 -16
  431. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +0 -160
  432. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +0 -412
  433. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +0 -602
  434. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +0 -915
  435. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +0 -916
  436. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +0 -752
  437. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +0 -1237
  438. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +0 -189
  439. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +0 -500
  440. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +0 -464
  441. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +0 -619
  442. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +0 -437
  443. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +0 -231
  444. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +0 -170
  445. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +0 -602
  446. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +0 -821
  447. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +0 -742
  448. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +0 -726
  449. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +0 -764
  450. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +0 -831
  451. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +0 -226
  452. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +0 -901
  453. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +0 -901
  454. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +0 -775
  455. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +0 -937
  456. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +0 -770
  457. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +0 -961
  458. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +0 -119
  459. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +0 -253
  460. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +0 -145
  461. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +0 -543
  462. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +0 -741
  463. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +0 -470
  464. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +0 -458
  465. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +0 -639
  466. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +0 -140
  467. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +0 -572
  468. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +0 -411
  469. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +0 -569
  470. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +0 -695
  471. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +0 -184
  472. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +0 -459
  473. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +0 -479
  474. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +0 -687
  475. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +0 -758
  476. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +0 -868
  477. /claude_mpm/agents/templates/{git_file_tracking.md → git-file-tracking.md} +0 -0
  478. /claude_mpm/agents/templates/{pm_examples.md → pm-examples.md} +0 -0
  479. /claude_mpm/agents/templates/{response_format.md → response-format.md} +0 -0
  480. /claude_mpm/agents/templates/{validation_templates.md → validation-templates.md} +0 -0
  481. {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/WHEEL +0 -0
  482. {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/entry_points.txt +0 -0
  483. {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/licenses/LICENSE +0 -0
  484. {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/top_level.txt +0 -0
@@ -1,2 +0,0 @@
1
- class e{constructor(){this.tooltipService=window.tooltipService||null,this.domHelpers=window.domHelpers||null,this.eventBus=window.eventBus||null,this.logger=window.logger?window.logger.createComponentLogger("CodeTree"):console,this.treeUtils=window.treeUtils||null,this.treeConstants=window.treeConstants||{},this.treeSearch=window.treeSearch||null,this.treeBreadcrumb=window.treeBreadcrumb||null,this.container=null,this.svg=null,this.treeData=null,this.root=null,this.treeLayout=null,this.treeGroup=null,this.nodes=new Map,this.stats={files:0,classes:0,functions:0,methods:0,lines:0},this.isRadialLayout=!1,this.margin=this.treeConstants.DEFAULT_MARGIN||{top:20,right:20,bottom:20,left:20},this.width=(this.treeConstants.DEFAULT_WIDTH||960)-this.margin.left-this.margin.right,this.height=(this.treeConstants.DEFAULT_HEIGHT||600)-this.margin.top-this.margin.bottom,this.radius=Math.min(this.width,this.height)/2,this.nodeId=0,this.duration=this.treeConstants.ANIMATION_DURATION||750,this.languageFilter="all",this.searchTerm="",this.tooltip=null,this.initialized=!1,this.analyzing=!1,this.selectedNode=null,this.socket=null,this.autoDiscovered=!1,this.zoom=null,this.structuredDataContent=null,this.selectedASTItem=null,this.activeNode=null,this.loadingNodes=new Set,this.bulkLoadMode=!1,this.expandedPaths=new Set,this.focusedNode=null,this.horizontalNodes=new Set,this.centralSpine=new Set,this.onNodeClick=this.onNodeClick.bind(this),this.showTooltip=this.showTooltip.bind(this),this.hideTooltip=this.hideTooltip.bind(this)}initialize(){if(this.initialized)return;if(this.container=document.getElementById("code-tree-container"),!this.container)return void console.error("Code tree container not found");const e=document.getElementById("code-tab");if(!e)return void console.error("Code tab panel not found");const t=this.getWorkingDirectory();if(!t||"Loading..."===t||"Not selected"===t)return this.showNoWorkingDirectoryMessage(),void(this.initialized=!0);this.setupControls(),this.initializeTreeData(),this.subscribeToEvents(),this.initializeStructuredData();document.getElementById("breadcrumb-content")&&!this.analyzing&&this.updateActivityTicker("Loading project structure...","info"),e.classList.contains("active")&&(this.createVisualization(),this.root&&this.svg&&this.update(this.root),this.autoDiscoverRootLevel()),this.initialized=!0}renderWhenVisible(){const e=this.getWorkingDirectory();e&&"Loading..."!==e&&"Not selected"!==e?(this.removeNoWorkingDirectoryMessage(),this.initialized?(this.svg?this.root&&this.svg&&this.update(this.root):(this.createVisualization(),this.svg&&this.treeGroup&&this.update(this.root)),this.autoDiscovered||this.autoDiscoverRootLevel()):this.initialize()):this.showNoWorkingDirectoryMessage()}setupControls(){const e=document.getElementById("language-filter");e&&e.addEventListener("change",e=>{this.languageFilter=e.target.value,this.filterTree()});const t=document.getElementById("code-search");t&&t.addEventListener("input",e=>{this.searchTerm=e.target.value.toLowerCase(),this.filterTree()});const o=document.getElementById("code-toggle-legend");o&&o.addEventListener("click",()=>this.toggleLegend()),document.addEventListener("workingDirectoryChanged",e=>{this.onWorkingDirectoryChanged(e.detail.directory)})}onWorkingDirectoryChanged(e){if(!e||"Loading..."===e||"Not selected"===e)return this.showNoWorkingDirectoryMessage(),this.autoDiscovered=!1,this.analyzing=!1,this.nodes.clear(),this.loadingNodes.clear(),this.stats={files:0,classes:0,functions:0,methods:0,lines:0},void this.updateStats();this.removeNoWorkingDirectoryMessage(),this.autoDiscovered=!1,this.analyzing=!1,this.nodes.clear(),this.loadingNodes.clear(),this.stats={files:0,classes:0,functions:0,methods:0,lines:0},this.initializeTreeData(),this.svg&&this.update(this.root);const t=document.getElementById("code-tab");t&&t.classList.contains("active")&&this.autoDiscoverRootLevel(),this.updateStats()}showLoading(){let e=document.getElementById("code-tree-loading");if(!e){const t=document.getElementById("code-tree-container");t&&(e=document.createElement("div"),e.id="code-tree-loading",e.innerHTML='\n <div class="code-tree-spinner"></div>\n <div class="code-tree-loading-text">Analyzing code structure...</div>\n ',t.appendChild(e))}e&&e.classList.remove("hidden")}hideLoading(){const e=document.getElementById("code-tree-loading");e&&e.classList.add("hidden")}createVisualization(){if("undefined"==typeof d3)return void console.error("D3.js is not loaded");const e=d3.select("#code-tree-container");if(e.selectAll("*").remove(),this.addTreeControls(),!e||!e.node())return void console.error("Code tree container not found");const t=e.node(),o=t.clientWidth||960,n=t.clientHeight||600;this.width=o-this.margin.left-this.margin.right,this.height=n-this.margin.top-this.margin.bottom,this.radius=Math.min(this.width,this.height)/2,this.svg=e.append("svg").attr("width",o).attr("height",n);const i=o/2,s=n/2;this.isRadialLayout?this.treeGroup=this.svg.append("g").attr("transform",`translate(${i},${s})`):this.treeGroup=this.svg.append("g").attr("transform",`translate(${this.margin.left+100},${s})`),this.isRadialLayout?this.treeLayout=d3.cluster().size([2*Math.PI,this.radius-100]).separation((e,t)=>{if(e.parent==t.parent){const t=Math.max(1,4-e.depth),o=e.parent&&e.parent.children?.length||1,n=o>5?2:o>3?1.5:1,i=1+.2*e.depth;return t*n/(e.depth||1)*i}return 4/(e.depth||1)}):this.treeLayout=d3.tree().nodeSize([30,200]).separation((e,t)=>e.parent==t.parent?1:1.5),this.zoom=d3.zoom().scaleExtent([.1,3]).on("zoom",e=>{this.treeGroup.attr("transform",e.transform),this.adjustTextSizeForZoom(e.transform.k),this.updateZoomLevel(e.transform.k)}),this.svg.call(this.zoom),this.addZoomKeyboardShortcuts(),console.log("[CodeTree] Zoom and pan functionality enabled"),this.addVisualizationControls(),this.tooltip=d3.select("body").append("div").attr("class","code-tree-tooltip").style("opacity",0).style("position","absolute").style("background","rgba(0, 0, 0, 0.8)").style("color","white").style("padding","8px").style("border-radius","4px").style("font-size","12px").style("pointer-events","none")}clearD3Visualization(){this.treeGroup&&(this.treeGroup.selectAll("g.node").remove(),this.treeGroup.selectAll("path.link").remove()),this.nodeId=0}initializeTreeData(){const e=this.getWorkingDirectory();this.treeData={name:"Project Root",path:e||".",type:"root",isDirectory:!0,children:[],loaded:!1,expanded:!0,hasChildren:!0,isRoot:!0},"undefined"!=typeof d3&&(this.root=d3.hierarchy(this.treeData),this.root.x0=this.height/2,this.root.y0=0)}subscribeToEvents(){if(!this.socket)if(window.socket&&window.socket.connected)console.log("[CodeTree] Using existing global socket"),this.socket=window.socket,this.setupEventHandlers();else if(window.dashboard?.socketClient?.socket&&window.dashboard.socketClient.socket.connected)console.log("[CodeTree] Using dashboard socket"),this.socket=window.dashboard.socketClient.socket,this.setupEventHandlers();else if(window.socketClient?.socket&&window.socketClient.socket.connected)console.log("[CodeTree] Using socketClient socket"),this.socket=window.socketClient.socket,this.setupEventHandlers();else if(window.io){console.log("[CodeTree] Creating new socket connection");try{this.socket=io("/"),this.socket.on("connect",()=>{console.log("[CodeTree] Socket connected successfully"),this.setupEventHandlers()}),this.socket.on("disconnect",()=>{console.log("[CodeTree] Socket disconnected")}),this.socket.on("connect_error",e=>{console.error("[CodeTree] Socket connection error:",e)})}catch(e){console.error("[CodeTree] Failed to create socket connection:",e)}}else console.error("[CodeTree] Socket.IO not available - cannot subscribe to events")}autoDiscoverRootLevel(){if(this.autoDiscovered||this.analyzing)return;this.updateActivityTicker("🔍 Discovering project structure...","info");const e=this.getWorkingDirectory();if(!e||"Loading..."===e||"Not selected"===e)return console.warn("Cannot auto-discover: no working directory set"),void this.showNoWorkingDirectoryMessage();if(!e.startsWith("/")&&!e.match(/^[A-Z]:\\/))return console.error("Working directory is not absolute:",e),void this.showNotification("Invalid working directory path","error");this.autoDiscovered=!0,this.analyzing=!0,this.nodes.clear(),this.loadingNodes.clear(),this.stats={files:0,classes:0,functions:0,methods:0,lines:0},this.socket&&!this.socket.hasListeners("code:node:found")&&this.setupEventHandlers(),this.showLoading();const t=e.split("/").pop()||"Project Root";this.updateBreadcrumb(`Discovering structure in ${t}...`,"info"),console.log(`🚀 [ROOT DISCOVERY] Using REST API for root: ${e}`);const o=`${window.location.origin}/api/directory?path=${encodeURIComponent(e)}`;fetch(o).then(e=>{if(!e.ok)throw new Error(`HTTP ${e.status}: ${e.statusText}`);return e.json()}).then(e=>{if(console.log("✅ [ROOT DISCOVERY] REST API response:",e),e.contents&&Array.isArray(e.contents)){this.treeData.children=e.contents.map(e=>({name:e.name,path:e.path,type:e.type||(e.is_directory?"directory":"file"),size:e.size,hasChildren:e.is_directory,children:[],loaded:!1})),this.treeData.loaded=!0,"undefined"!=typeof d3&&(this.root=d3.hierarchy(this.treeData),this.root.x0=this.height/2,this.root.y0=0,this.root.children&&this.root.children.forEach(e=>{e._children=null})),this.svg&&this.update(this.root);const t=e.contents.filter(e=>!e.is_directory).length,o=e.contents.filter(e=>e.is_directory).length;this.stats.files=t,this.updateStats(),this.updateBreadcrumb(`📁 Found ${o} directories and ${t} files`,"success"),this.updateActivityTicker(`📁 Found ${o} directories and ${t} files`,"success"),this.addEventToDisplay(`📁 Loaded ${e.contents.length} items from project root`,"info")}this.analyzing=!1,this.hideLoading()}).catch(t=>{if(console.error("[ROOT DISCOVERY] Error:",t),this.analyzing=!1,this.hideLoading(),this.showNotification(`Failed to load directory: ${t.message}`,"error"),this.socket){console.log("[ROOT DISCOVERY] Falling back to WebSocket");const t={path:e,depth:"top_level",languages:this.getSelectedLanguages(),ignore_patterns:document.getElementById("ignore-patterns")?.value||"",request_id:`discover_${Date.now()}`};this.socket.emit("code:discover:top_level",t)}}),this.updateStats()}analyzeCode(){this.analyzing||this.autoDiscoverRootLevel()}cancelAnalysis(){this.analyzing=!1,this.hideLoading(),this.loadingNodes.clear(),this.socket&&this.socket.emit("code:analysis:cancel")}addTreeControls(){const e=d3.select("#code-tree-container");e.select(".tree-controls-toolbar").remove();const t=e.append("div").attr("class","tree-controls-toolbar");t.append("button").attr("class","tree-control-btn").attr("title","Expand all loaded directories").text("⊞").on("click",()=>this.expandAll()),t.append("button").attr("class","tree-control-btn").attr("title","Collapse all directories").text("⊟").on("click",()=>this.collapseAll()),t.append("button").attr("class","tree-control-btn").attr("id","bulk-load-toggle").attr("title","Toggle bulk loading (load 2 levels at once)").text("↕").on("click",()=>this.toggleBulkLoad()),t.append("button").attr("class","tree-control-btn").attr("title","Toggle between radial and linear layouts").text("◎").on("click",()=>this.toggleLayout()),t.append("button").attr("class","tree-control-btn").attr("title","Zoom in").text("🔍+").on("click",()=>this.zoomIn()),t.append("button").attr("class","tree-control-btn").attr("title","Zoom out").text("🔍-").on("click",()=>this.zoomOut()),t.append("button").attr("class","tree-control-btn").attr("title","Reset zoom to fit tree").text("⌂").on("click",()=>this.resetZoom()),t.append("span").attr("class","zoom-level-display").attr("id","zoom-level-display").text("100%").style("margin-left","8px").style("font-size","11px").style("color","#718096"),t.append("input").attr("class","tree-control-btn").attr("type","text").attr("placeholder","Search...").attr("title","Search for files and directories").style("width","120px").style("text-align","left").on("input",e=>this.searchTree(e.target.value)).on("keydown",e=>{"Escape"===e.key&&(e.target.value="",this.searchTree(""))})}addBreadcrumb(){const e=d3.select("#code-tree-container");e.select(".tree-breadcrumb").remove();e.append("div").attr("class","tree-breadcrumb").append("div").attr("class","breadcrumb-path").attr("id","tree-breadcrumb-path"),this.updateBreadcrumbPath("/")}updateBreadcrumbPath(e){const t=d3.select("#tree-breadcrumb-path");t.selectAll("*").remove();const o=this.getWorkingDirectory();if(!o||"Loading..."===o||"Not selected"===o)return void t.text("No project selected");const n="/"===e?[o.split("/").pop()||"Root"]:e.split("/").filter(e=>e.length>0);n.forEach((e,o)=>{o>0&&t.append("span").attr("class","breadcrumb-separator").text("/"),t.append("span").attr("class",o===n.length-1?"breadcrumb-segment current":"breadcrumb-segment").text(e).on("click",()=>{if(o<n.length-1){const e=n.slice(0,o+1).join("/");this.navigateToPath(e)}})})}expandAll(){if(!this.root)return;const e=t=>{"directory"!==t.data.type&&"root"!==t.data.type&&!t.data.isDirectory||!0!==t.data.loaded||t._children&&(t.children=t._children,t._children=null,t.data.expanded=!0),t.children&&t.children.forEach(e)};e(this.root),this.update(this.root),this.showNotification("Expanded all loaded directories","success")}collapseAll(){if(!this.root)return;const e=t=>{("directory"===t.data.type||"root"===t.data.type||t.data.isDirectory)&&t.children&&(t._children=t.children,t.children=null,t.data.expanded=!1),t._children&&t._children.forEach(e)};e(this.root),this.update(this.root),this.showNotification("Collapsed all directories","info")}toggleBulkLoad(){this.bulkLoadMode=!this.bulkLoadMode;const e=d3.select("#bulk-load-toggle");this.bulkLoadMode?(e.classed("active",!0),this.showNotification("Bulk load enabled - will load 2 levels deep","info")):(e.classed("active",!1),this.showNotification("Bulk load disabled - load 1 level at a time","info"))}navigateToPath(e){this.showNotification(`Navigating to: ${e}`,"info")}searchTree(e){if(!this.root||!this.treeGroup)return;const t=e.toLowerCase().trim();if(this.treeGroup.selectAll(".code-node").classed("search-match",!1),!t)return;const o=[],n=e=>{const i=(e.data.name||"").toLowerCase(),s=(e.data.path||"").toLowerCase();(i.includes(t)||s.includes(t))&&o.push(e),e.children&&e.children.forEach(n),e._children&&e._children.forEach(n)};n(this.root),o.length>0?(this.treeGroup.selectAll(".code-node").data(),o.forEach(e=>{this.treeGroup.selectAll(".code-node").filter(t=>t.data.path===e.data.path).classed("search-match",!0),this.expandPathToNode(e)}),this.showNotification(`Found ${o.length} matches`,"success")):this.showNotification("No matches found","info")}expandPathToNode(e){const t=[];let o=e.parent;for(;o&&o!==this.root;)t.unshift(o),o=o.parent;t.forEach(e=>{"directory"===e.data.type&&e._children&&(e.children=e._children,e._children=null,e.data.expanded=!0)}),t.length>0&&this.update(this.root)}createEventsDisplay(){let e=document.getElementById("analysis-events");if(!e){const t=document.getElementById("code-tree-container");t&&(e=document.createElement("div"),e.id="analysis-events",e.className="analysis-events",e.style.display="none",t.appendChild(e))}}clearEventsDisplay(){const e=document.getElementById("analysis-events");e&&(e.innerHTML="",e.style.display="block")}addEventToDisplay(e,t="info"){const o=document.getElementById("analysis-events");if(o){const n=document.createElement("div");n.className="analysis-event",n.style.borderLeftColor="warning"===t?"#f59e0b":"error"===t?"#ef4444":"#3b82f6";const i=(new Date).toLocaleTimeString();n.innerHTML=`<span style="color: #718096;">[${i}]</span> ${e}`,o.appendChild(n),o.scrollTop=o.scrollHeight}}setupEventHandlers(){this.socket&&(this.socket.on("code:analysis:accepted",e=>this.onAnalysisAccepted(e)),this.socket.on("code:analysis:queued",e=>this.onAnalysisQueued(e)),this.socket.on("code:analysis:start",e=>this.onAnalysisStart(e)),this.socket.on("code:analysis:complete",e=>this.onAnalysisComplete(e)),this.socket.on("code:analysis:cancelled",e=>this.onAnalysisCancelled(e)),this.socket.on("code:analysis:error",e=>this.onAnalysisError(e)),this.socket.on("code:top_level:discovered",e=>this.onTopLevelDiscovered(e)),this.socket.on("code:directory:discovered",e=>this.onDirectoryDiscovered(e)),this.socket.on("code:file:discovered",e=>this.onFileDiscovered(e)),this.socket.on("code:file:analyzed",e=>{console.log("📨 [SOCKET] Received code:file:analyzed event"),this.onFileAnalyzed(e)}),this.socket.on("code:node:found",e=>this.onNodeFound(e)),this.socket.on("code:analysis:progress",e=>this.onProgressUpdate(e)),this.socket.on("code:analysis:error",e=>{console.error("❌ [FILE ANALYSIS] Analysis error:",e),this.showNotification(`Analysis error: ${e.error||"Unknown error"}`,"error")}),this.socket.on("error",e=>{console.error("❌ [SOCKET] Socket error:",e)}),this.socket.on("connect",()=>{console.log("✅ [SOCKET] Connected to server, analysis service should be available"),this.connectionStable=!0}),this.socket.on("disconnect",()=>{console.log("❌ [SOCKET] Disconnected from server - disabling AST analysis"),this.connectionStable=!1,this.analysisTimeouts&&(this.analysisTimeouts.forEach((e,t)=>{clearTimeout(e),this.loadingNodes.delete(t)}),this.analysisTimeouts.clear())}),this.socket.on("code:directory:contents",e=>{if(e.path){let t=e.path;const o=this.getWorkingDirectory();o&&t.startsWith(o)&&(t=t.substring(o.length).replace(/^\//,""),t||(t="."));const n=this.findNodeByPath(t);if(n&&e.children){const o=this.findD3NodeByPath(t);if(o&&this.loadingNodes.has(t)&&(this.removeLoadingPulse(o),this.loadingNodes.delete(t),console.log("🎯 [SUBDIRECTORY LOADING] Successfully completed and removed from loading set:",t)),n.children=e.children.map(e=>{let o;if("."===t||""===t)o=e.name||e.path;else{const n=e.name||e.path;o=`${t}/${n}`}return{...e,path:o,loaded:"directory"!==e.type&&void 0,analyzed:"file"!==e.type&&void 0,expanded:!1,children:[]}}),n.loaded=!0,n.expanded=!0,this.root&&this.svg){const e=this.root;this.root=d3.hierarchy(this.treeData),this.root.x0=this.height/2,this.root.y0=0,this.preserveExpansionState(e,this.root);const o=this.findD3NodeByPath(t);o&&o.children&&o.children.length>0&&(o._children=null,o.data.expanded=!0,console.log("✅ [D3 UPDATE] Node expanded after loading:",t)),this.update(o||this.root)}e.stats&&(this.stats.files+=e.stats.files||0,this.stats.directories+=e.stats.directories||0,this.updateStats()),this.updateBreadcrumb(`Loaded ${e.path}`,"success"),this.hideLoading()}}}),this.socket.on("code:top_level:discovered",e=>{e.items&&Array.isArray(e.items)&&(this.treeData.children=e.items.map(e=>({name:e.name,path:e.path,type:e.type,language:"file"===e.type?this.detectLanguage(e.path):void 0,size:e.size,lines:e.lines,loaded:"directory"!==e.type&&void 0,analyzed:"file"!==e.type&&void 0,expanded:!1,children:[]})),this.treeData.loaded=!0,e.stats&&(this.stats={...this.stats,...e.stats},this.updateStats()),"undefined"!=typeof d3&&(this.clearD3Visualization(),this.root=d3.hierarchy(this.treeData),this.root.x0=this.height/2,this.root.y0=0,this.svg&&this.update(this.root)),this.analyzing=!1,this.hideLoading(),this.updateBreadcrumb(`Discovered ${e.items.length} root items`,"success"),this.showNotification(`Found ${e.items.length} items in project root`,"success"))}))}onAnalysisStart(e){this.analyzing=!0;const t=e.message||"Starting code analysis...";this.updateActivityTicker("🚀 Starting analysis...","info"),this.updateBreadcrumb(t,"info"),this.addEventToDisplay(`🚀 ${t}`,"info"),this.treeData&&0!==this.treeData.children.length||this.initializeTreeData(),this.stats={files:0,classes:0,functions:0,methods:0,lines:0},this.updateStats()}onTopLevelDiscovered(e){this.updateActivityTicker(`📁 Discovered ${(e.items||[]).length} top-level items`,"success"),this.addEventToDisplay(`📁 Found ${(e.items||[]).length} top-level items in project root`,"info");const t=this.getWorkingDirectory(),o=this.findNodeByPath(t);console.log(`🔎 Looking for root node with path "${t}", found:`,o?{name:o.name,path:o.path,currentChildren:o.children?o.children.length:0}:"NOT FOUND"),o&&e.items?(console.log("🌳 Populating root node with children"),o.children=e.items.map(e=>{const t=this.getWorkingDirectory(),o=t?`${t}/${e.name}`.replace(/\/+/g,"/"):e.name;return console.log(` Adding child: ${e.name} with path: ${o}`),{name:e.name,path:o,type:e.type,loaded:"directory"!==e.type&&void 0,analyzed:"file"!==e.type&&void 0,expanded:!1,children:"directory"===e.type?[]:void 0,size:e.size,has_code:e.has_code}}),o.loaded=!0,o.expanded=!0,this.root&&this.svg&&(this.root.data===this.treeData?(console.log("📊 Updating existing D3 tree structure"),this.root.children=o.children.map(e=>{const t=d3.hierarchy(e);return t.parent=this.root,t.depth=1,t}),this.root._children=null,this.root.data.expanded=!0):(console.log("🔄 Recreating D3 tree structure"),this.root=d3.hierarchy(this.treeData),this.root.x0=this.height/2,this.root.y0=0),this.update(this.root)),this.hideLoading(),this.updateBreadcrumb(`Discovered ${e.items.length} items`,"success"),this.showNotification(`Found ${e.items.length} top-level items`,"success")):(console.error("❌ Could not find root node to populate"),this.showNotification("Failed to populate root directory","error")),this.analyzing=!1}onDirectoryDiscovered(e){console.log("🔴 [RAW DATA] Exact data received from backend:",e),console.log("🔴 [RAW DATA] Data type:",typeof e),console.log("🔴 [RAW DATA] Data keys:",Object.keys(e)),console.log("🔴 [RAW DATA] Children field:",e.children),console.log("🔴 [RAW DATA] Children type:",typeof e.children),console.log("🔴 [RAW DATA] Is children array?:",Array.isArray(e.children)),console.log("🔴 [RAW DATA] Children length:",e.children?e.children.length:"undefined"),this.updateActivityTicker(`📁 Discovered: ${e.name||"directory"}`),this.addEventToDisplay(`📁 Found ${(e.children||[]).length} items in: ${e.name||e.path}`,"info"),console.log("✅ [SUBDIRECTORY LOADING] Received directory discovery response:",{path:e.path,name:e.name,childrenCount:(e.children||[]).length,children:(e.children||[]).map(e=>({name:e.name,type:e.type})),workingDir:this.getWorkingDirectory(),fullEventData:e});let t=e.path;const o=this.getWorkingDirectory();o&&t.startsWith(o)&&(t=t.substring(o.length).replace(/^\//,""),t||(t=".")),console.log("🔎 Searching for node with path:",t);const n=this.findNodeByPath(t);if(console.log("🔍 Node search result:",{searchPath:t,nodeFound:!!n,nodeName:n?.name,nodePath:n?.path,nodeChildren:n?.children?.length,dataHasChildren:!!e.children,dataChildrenLength:e.children?.length}),n||(console.warn("Node not found! Logging all paths in tree:"),this.logAllPaths(this.treeData)),n){if(console.log("📦 Node found, checking children:",{nodeFound:!0,dataHasChildren:"children"in e,dataChildrenIsArray:Array.isArray(e.children),dataChildrenLength:e.children?.length,dataChildrenValue:e.children}),e.children){console.log(`📂 Updating node ${n.name} with ${e.children.length} children`),n.children=e.children.map(e=>{let o;if("."===t||""===t)o=e.name||e.path;else{const n=e.name||e.path;o=`${t}/${n}`}return{name:e.name,path:o,type:e.type,loaded:"directory"!==e.type&&void 0,analyzed:"file"!==e.type&&void 0,expanded:!1,children:"directory"===e.type?[]:void 0,size:e.size,has_code:e.has_code}}),n.loaded=!0,n.expanded=!0;const o=this.findD3NodeByPath(t);if(o&&this.loadingNodes.has(t)&&(this.removeLoadingPulse(o),this.loadingNodes.delete(t),console.log("🎯 [SUBDIRECTORY LOADING] Successfully completed and removed from loading set (hierarchy update):",t)),this.root&&this.svg){const e=this.root;this.root=d3.hierarchy(this.treeData),this.root.x0=this.height/2,this.root.y0=0,this.preserveExpansionState(e,this.root);const o=this.findD3NodeByPath(t);o&&(o.children&&o.children.length>0?(o._children=null,o.data.expanded=!0,console.log("✅ [D3 UPDATE] Node expanded with children:",{path:t,d3ChildrenCount:o.children.length,dataChildrenCount:o.data.children?o.data.children.length:0,childPaths:o.children.map(e=>e.data.path)})):!o.children&&o.data.children&&o.data.children.length>0&&console.error("⚠️ [D3 UPDATE] Data has children but D3 node does not!",{path:t,dataChildren:o.data.children})),this.update(o||this.root)}0===n.children.length?(this.updateBreadcrumb(`Empty directory: ${n.name}`,"info"),this.showNotification(`Directory "${n.name}" is empty`,"info")):(this.updateBreadcrumb(`Loaded ${n.children.length} items from ${n.name}`,"success"),this.showNotification(`Loaded ${n.children.length} items from "${n.name}"`,"success"))}else console.error("❌ No children data received for directory:",{path:t,dataKeys:Object.keys(e),fullData:e}),this.updateBreadcrumb(`Error loading ${n.name}`,"error"),this.showNotification("Failed to load directory contents","error");this.updateStats()}else if(n){if(n&&!e.children){console.warn("⚠️ [SUBDIRECTORY LOADING] Directory response has no children:",{path:e.path,searchPath:t,nodeExists:!!n,dataKeys:Object.keys(e),fullData:e});const o=e.path?e.path.split("/").filter(e=>e):[];if(1===o.length||e.forceAdd){const t={name:e.name||o[o.length-1]||"Unknown",path:e.path,type:"directory",children:[],loaded:!1,expanded:!1,stats:e.stats||{}};this.addNodeToTree(t,e.parent||""),this.updateBreadcrumb(`Discovered: ${e.path}`,"info")}}}else console.error("❌ [SUBDIRECTORY LOADING] Node not found for path:",{searchPath:t,originalPath:e.path,workingDir:this.getWorkingDirectory(),allTreePaths:this.getAllTreePaths(this.treeData)}),this.showNotification(`Could not find directory "${t}" in tree`,"error"),this.logAllPaths(this.treeData)}onFileDiscovered(e){const t=e.name||(e.path?e.path.split("/").pop():"file");this.updateActivityTicker(`📄 Found: ${t}`),this.addEventToDisplay(`📄 Discovered: ${e.path||"Unknown file"}`,"info");const o=e.path?e.path.split("/").filter(e=>e):[],n=o.slice(0,-1).join("/"),i={name:e.name||o[o.length-1]||"Unknown",path:e.path,type:"file",language:e.language||this.detectLanguage(e.path),size:e.size||0,lines:e.lines||0,children:[],analyzed:!1};this.addNodeToTree(i,n),this.stats.files++,this.updateStats(),this.updateBreadcrumb(`Found: ${e.path}`,"info")}onFileAnalyzed(e){if(console.log("✅ [FILE ANALYSIS] Received analysis result:",{path:e.path,elements:e.elements?e.elements.length:0,complexity:e.complexity,lines:e.lines,stats:e.stats,elementsDetail:e.elements,fullData:e}),e.elements&&e.elements.length>0){console.log("🔍 [AST ELEMENTS] Found elements:",e.elements.map(e=>({name:e.name,type:e.type,line:e.line,methods:e.methods?e.methods.length:0})));const t=e.path.split("/").pop(),o=this.getElementCounts(e.elements),n=this.formatElementSummary(o);this.showNotification(`${t} - ${n}`,"success"),this.updateBreadcrumb(`${t} - AST parsed: ${n}`,"success")}else{const t=e.path.split("/").pop();console.log("⚠️ [AST ELEMENTS] No elements found in analysis result");const o=this.getFileTypeDescription(t);this.showNotification(`${t} - No structural elements to display in tree`,"info"),this.updateBreadcrumb(`${t} - ${o} analyzed, content not suitable for tree view`,"info")}this.analysisTimeouts&&this.analysisTimeouts.has(e.path)&&(clearTimeout(this.analysisTimeouts.get(e.path)),this.analysisTimeouts.delete(e.path),console.log("⏰ [FILE ANALYSIS] Cleared timeout for:",e.path));const t=this.findD3NodeByPath(e.path);if(t&&this.loadingNodes.has(e.path)&&(this.removeLoadingPulse(t),this.loadingNodes.delete(e.path)),e.path){const t=e.path.split("/").pop();this.updateActivityTicker(`🔍 Analyzed: ${t}`)}const o=this.findNodeByPath(e.path);if(o){if(console.log("🔍 [FILE NODE] Found file node for:",e.path),o.analyzed=!0,o.complexity=e.complexity||0,o.lines=e.lines||0,e.elements&&Array.isArray(e.elements)){const t=e.elements.map(t=>({name:t.name,type:t.type.toLowerCase(),path:`${e.path}#${t.name}`,line:t.line,complexity:t.complexity||1,docstring:t.docstring||"",children:t.methods?t.methods.map(o=>({name:o.name,type:"method",path:`${e.path}#${t.name}.${o.name}`,line:o.line,complexity:o.complexity||1,docstring:o.docstring||""})):[]}));o.children=t,console.log("✅ [FILE NODE] Added children to file node:",{filePath:e.path,childrenCount:t.length,children:t.map(e=>({name:e.name,type:e.type}))}),this.autoExpandFileWithAST(e.path,o)}else console.log("⚠️ [FILE NODE] No elements to add as children");if(e.stats&&(this.stats.classes+=e.stats.classes||0,this.stats.functions+=e.stats.functions||0,this.stats.methods+=e.stats.methods||0,this.stats.lines+=e.stats.lines||0),this.updateStats(),this.root&&o.children&&o.children.length>0){console.log("🔄 [FILE NODE] Recreating D3 hierarchy to include AST children");const t=this.root;this.root=d3.hierarchy(this.treeData),this.root.x0=this.height/2,this.root.y0=0,this.preserveExpansionState(t,this.root);const o=this.findD3NodeByPath(e.path);o&&o.children&&o.children.length>0&&(o._children=null,o.data.expanded=!0,console.log("✅ [FILE NODE] File node expanded to show AST children:",{path:e.path,childrenCount:o.children.length,childNames:o.children.map(e=>e.data.name)})),this.update(this.root)}else this.root&&this.update(this.root);this.updateBreadcrumb(`Analyzed: ${e.path}`,"success")}else console.error("❌ [FILE NODE] Could not find file node for path:",e.path)}onNodeFound(e){const t="class"===e.type?"🏛️":"function"===e.type?"⚡":"method"===e.type?"🔧":"📦";this.addEventToDisplay(`${t} Found ${e.type||"node"}: ${e.name||"Unknown"}`);const o={name:e.name||"Unknown",type:(e.type||"unknown").toLowerCase(),path:e.path||"",line:e.line||0,complexity:e.complexity||1,docstring:e.docstring||""};o.type={class:"class",function:"function",method:"method",module:"module",file:"file",directory:"directory"}[o.type]||o.type;let n="";if(e.parent_path)n=e.parent_path;else if(e.file_path)n=e.file_path;else if(o.path.includes("/")){const e=o.path.split("/");e.pop(),n=e.join("/")}switch(o.type){case"class":this.stats.classes++;break;case"function":this.stats.functions++;break;case"method":this.stats.methods++;break;case"file":this.stats.files++}this.addNodeToTree(o,n),this.updateStats();const i=o.type.charAt(0).toUpperCase()+o.type.slice(1);this.updateBreadcrumb(`Found ${i}: ${o.name}`,"info")}onProgressUpdate(e){const t=e.progress||0,o=e.message||`Processing... ${t}%`;this.updateBreadcrumb(o,"info");const n=document.querySelector(".code-tree-progress");n&&(n.style.width=`${t}%`)}onAnalysisComplete(e){this.analyzing=!1,this.hideLoading(),this.updateActivityTicker("✅ Ready","success"),this.addEventToDisplay("✅ Analysis complete!","success"),this.root&&this.svg&&this.update(this.root),e.stats&&(this.stats={...this.stats,...e.stats},this.updateStats());const t=e.message||`Analysis complete: ${this.stats.files} files, ${this.stats.classes} classes, ${this.stats.functions} functions`;this.updateBreadcrumb(t,"success"),this.showNotification(t,"success")}onAnalysisError(e){this.analyzing=!1,this.hideLoading(),this.loadingNodes.clear();const t=e.message||e.error||"Analysis failed";this.updateBreadcrumb(t,"error"),this.showNotification(t,"error")}onAnalysisAccepted(e){const t=e.message||"Analysis request accepted";this.updateBreadcrumb(t,"info")}onAnalysisQueued(e){const t=`Analysis queued (position ${e.position||0})`;this.updateBreadcrumb(t,"warning"),this.showNotification(t,"info")}onInfoEvent(e){e.type&&e.type.startsWith("discovery.")?"discovery.start"===e.type?this.updateBreadcrumb(e.message,"info"):"discovery.complete"===e.type?(this.updateBreadcrumb(e.message,"success"),e.stats):"discovery.directory"!==e.type&&"discovery.file"!==e.type||this.updateBreadcrumb(e.message,"info"):e.type&&e.type.startsWith("analysis.")?"analysis.start"===e.type?this.updateBreadcrumb(e.message,"info"):"analysis.complete"===e.type?(this.updateBreadcrumb(e.message,"success"),e.stats&&(e.stats.classes,e.stats.functions,e.stats.methods)):("analysis.class"===e.type||"analysis.function"===e.type||"analysis.method"===e.type||"analysis.parse"===e.type)&&this.updateBreadcrumb(e.message,"info"):e.type&&e.type.startsWith("filter.")?(window.debugMode||this.showFilterEvents)&&(console.debug("[FILTER]",e.type,e.path,e.reason),this.showFilterEvents&&this.updateBreadcrumb(e.message,"warning")):e.type&&e.type.startsWith("cache.")&&("cache.hit"===e.type?(console.debug("[CACHE HIT]",e.file),this.showCacheEvents&&this.updateBreadcrumb(e.message,"info")):"cache.miss"===e.type&&console.debug("[CACHE MISS]",e.file)),this.eventLogEnabled&&e.message&&this.addEventToDisplay(e)}addEventToDisplay(e){this.recentEvents||(this.recentEvents=[]),this.recentEvents.unshift({timestamp:e.timestamp||(new Date).toISOString(),type:e.type,message:e.message,data:e}),this.recentEvents.length>100&&this.recentEvents.pop()}onAnalysisCancelled(e){this.analyzing=!1,this.hideLoading(),this.loadingNodes.clear();const t=e.message||"Analysis cancelled";this.updateBreadcrumb(t,"warning")}showNotification(e,t="info"){const o=document.createElement("div");o.className=`code-tree-notification ${t}`,o.textContent=e;const n=document.getElementById("code-tree-container");n&&(o.style.position="absolute",o.style.top="10px",o.style.right="10px",o.style.zIndex="1000",n.style.position&&"static"!==n.style.position||(n.style.position="relative"),n.appendChild(o),setTimeout(()=>{o.style.animation="slideOutRight 0.3s ease",setTimeout(()=>o.remove(),300)},3e3))}addNodeToTree(e,t=""){if(e.path&&e.path.startsWith("/"))return void console.error("Absolute path detected in node, skipping:",e.path);if(t&&t.startsWith("/"))return void console.error("Absolute path detected in parent, skipping:",t);let o=this.treeData;if(t&&(o=this.findNodeByPath(t),!o))return console.warn("Parent node not found, skipping node creation:",t),void console.warn("Attempted to add node:",e);const n=o.children?.find(t=>t.path===e.path||t.name===e.name&&t.type===e.type);n?Object.assign(n,e):(o.children||(o.children=[]),e.children||(e.children=[]),o.children.push(e),this.nodes.set(e.path,e),this.root&&this.svg&&(this.root=d3.hierarchy(this.treeData),this.root.x0=this.height/2,this.root.y0=0,(this.nodes.size<1e3||this.nodes.size%100==0)&&this.update(this.root)))}findNodeByPath(e,t=null){if(t||(t=this.treeData,console.log("🔍 [SUBDIRECTORY LOADING] Starting search for path:",e)),t.path===e)return console.log("✅ [SUBDIRECTORY LOADING] Found node for path:",e),t;if(t.children)for(const o of t.children){const t=this.findNodeByPath(e,o);if(t)return t}return t.parent||t!==this.treeData||console.warn("❌ [SUBDIRECTORY LOADING] Path not found in tree:",e),null}logAllPaths(e,t=""){if(console.log(`${t}${e.path} (${e.name})`),e.children)for(const o of e.children)this.logAllPaths(o,t+" ")}getAllTreePaths(e){const t=[e.path];if(e.children)for(const o of e.children)t.push(...this.getAllTreePaths(o));return t}findD3NodeByPath(e){return this.root?this.root.descendants().find(t=>t.data.path===e):null}preserveExpansionState(e,t){if(!e||!t)return;const o=new Map;e.descendants().forEach(e=>{(e.data.expanded||e.children&&!e._children)&&o.set(e.data.path,!0)}),t.descendants().forEach(e=>{o.has(e.data.path)&&(e.children=e._children||e.children,e._children=null,e.data.expanded=!0)})}updateStats(){const e={"stats-files":this.stats.files,"stats-classes":this.stats.classes,"stats-functions":this.stats.functions,"stats-methods":this.stats.methods};for(const[o,n]of Object.entries(e)){const e=document.getElementById(o);e&&(e.textContent=n.toLocaleString())}const t=document.getElementById("code-progress-text");if(t){const e=this.analyzing?`Analyzing... ${this.stats.files} files processed`:`Ready - ${this.stats.files} files in tree`;t.textContent=e}}updateBreadcrumb(e,t="info"){const o=document.getElementById("breadcrumb-content");o&&(o.textContent=e,o.className=`breadcrumb-${t}`)}async analyzeFileHTTP(e,t,o){console.log("🌐 [HTTP FALLBACK] Analyzing file via HTTP:",e),console.log("🌐 [HTTP FALLBACK] File name:",t);try{const o=this.createMockAnalysisData(e,t);console.log("🌐 [HTTP FALLBACK] Created mock data:",o),setTimeout(()=>{console.log("✅ [HTTP FALLBACK] Mock analysis complete for:",t),console.log("✅ [HTTP FALLBACK] Calling onFileAnalyzed with:",o),this.onFileAnalyzed(o)},1e3)}catch(n){console.error("❌ [HTTP FALLBACK] Analysis failed:",n),this.showNotification(`Analysis failed: ${n.message}`,"error"),this.loadingNodes.delete(e),this.removeLoadingPulse(o)}}createMockAnalysisData(e,t){const o=t.split(".").pop()?.toLowerCase();console.log("🔍 [MOCK DATA] Creating mock data for file:",t,"extension:",o);let n=[];return n="py"===o?[{name:"ExampleClass",type:"class",line:10,complexity:3,docstring:"Example class for demonstration",methods:[{name:"__init__",type:"method",line:12,complexity:1},{name:"example_method",type:"method",line:18,complexity:2}]},{name:"example_function",type:"function",line:25,complexity:2,docstring:"Example function"}]:"js"===o||"ts"===o?[{name:"ExampleClass",type:"class",line:5,complexity:2,methods:[{name:"constructor",type:"method",line:6,complexity:1},{name:"exampleMethod",type:"method",line:10,complexity:2}]},{name:"exampleFunction",type:"function",line:20,complexity:1}]:[{name:"mock_element",type:"function",line:1,complexity:1,docstring:`Mock element for ${t}`}],console.log("🔍 [MOCK DATA] Created elements:",n),{path:e,elements:n,complexity:n.reduce((e,t)=>e+(t.complexity||1),0),lines:50,stats:{classes:n.filter(e=>"class"===e.type).length,functions:n.filter(e=>"function"===e.type).length,methods:n.reduce((e,t)=>e+(t.methods?t.methods.length:0),0),lines:50}}}getSelectedLanguages(){const e=[],t=document.querySelectorAll(".language-checkbox:checked");return console.log("🔍 [LANGUAGE] Found checkboxes:",t.length),console.log("🔍 [LANGUAGE] All language checkboxes:",document.querySelectorAll(".language-checkbox").length),t.forEach(t=>{console.log("🔍 [LANGUAGE] Checked language:",t.value),e.push(t.value)}),0===e.length&&(console.warn("⚠️ [LANGUAGE] No languages selected, using defaults"),e.push("python","javascript","typescript"),document.querySelectorAll(".language-checkbox").forEach(e=>{["python","javascript","typescript"].includes(e.value)&&(e.checked=!0,console.log("✅ [LANGUAGE] Auto-checked:",e.value))})),e}detectLanguage(e){return{py:"python",js:"javascript",ts:"typescript",jsx:"javascript",tsx:"typescript",java:"java",cpp:"cpp",c:"c",cs:"csharp",rb:"ruby",go:"go",rs:"rust",php:"php",swift:"swift",kt:"kotlin",scala:"scala",r:"r",sh:"bash",ps1:"powershell"}[e.split(".").pop().toLowerCase()]||"unknown"}addVisualizationControls(){const e=this.svg.append("g").attr("class","viz-controls").attr("transform","translate(10, 10)").append("g").attr("class","layout-toggle").style("cursor","pointer").on("click",()=>this.toggleLayout());e.append("rect").attr("width",120).attr("height",30).attr("rx",5).attr("fill","#3b82f6").attr("opacity",.8),e.append("text").attr("x",60).attr("y",20).attr("text-anchor","middle").attr("fill","white").style("font-size","12px").text(this.isRadialLayout?"Switch to Linear":"Switch to Radial")}toggleLayout(){this.isRadialLayout=!this.isRadialLayout,this.createVisualization(),this.root&&this.update(this.root),this.showNotification(this.isRadialLayout?"Switched to radial layout":"Switched to linear layout","info")}radialPoint(e,t){return[(t=+t)*Math.cos(e-=Math.PI/2),t*Math.sin(e)]}applySingletonHorizontalLayout(e){this.isRadialLayout||(this.horizontalNodes.clear(),this.centralSpine.clear(),this.identifyCentralSpine(e),this.centralSpine.forEach(e=>{this.horizontalNodes.add(e)}),console.log("🎯 [SPINE] Central spine nodes:",Array.from(this.centralSpine)),console.log("📝 [TEXT] Horizontal text nodes:",Array.from(this.horizontalNodes)))}identifyCentralSpine(e){if(!e||0===e.length)return;const t=e.find(e=>0===e.depth);if(!t)return void console.warn("🎯 [SPINE] No root node found!");this.centralSpine.add(t.data.path),console.log(`🎯 [SPINE] Starting spine with root: ${t.data.name} (${t.data.path})`);let o=t;for(;o&&o.children&&o.children.length>0;){const e=this.selectMainChild(o.children);if(!e)break;this.centralSpine.add(e.data.path),console.log(`🎯 [SPINE] Adding to spine: ${e.data.name}`),o=e}}selectMainChild(e){if(!e||0===e.length)return null;if(1===e.length)return e[0];const t=e.filter(e=>this.isNodeDirectory(e));return 1===t.length||t.length>0?t[0]:e[0]}findSingletonChains(e){const t=[],o=new Set;return e.forEach(e=>{if(!o.has(e)&&e.children&&1===e.children.length){const n=[e];let i=e.children[0];for(console.log(`🔍 [CHAIN] Starting singleton chain with: ${e.data.name} (depth: ${e.depth})`);i&&i.children&&1===i.children.length;)n.push(i),o.add(i),console.log(`🔍 [CHAIN] Adding to chain: ${i.data.name} (depth: ${i.depth})`),i=i.children[0];i&&(n.push(i),o.add(i),console.log(`🔍 [CHAIN] Final node in chain: ${i.data.name} (depth: ${i.depth})`)),n.length>=2?(console.log("✅ [CHAIN] Created horizontal chain:",n.map(e=>e.data.name)),t.push(n),o.add(e)):console.log(`❌ [CHAIN] Chain too short (${n.length}), skipping`)}}),t}layoutChainHorizontally(e){if(e.length<2)return;const t=150,o=e[0],n=o.x,i=o.y;if(2===e.length){const t=i;o.y=t-75,e[1].y=t+75,e[1].x=n}else{const o=i-(e.length-1)*t/2;e.forEach((e,i)=>{e.y=o+i*t,e.x=n})}e.forEach(e=>{this.horizontalNodes.add(e.data.path),console.log(`📝 [TEXT] Marking node for horizontal text: ${e.data.name} (${e.data.path})`)}),console.log(`🔄 [LAYOUT] Horizontal chain of ${e.length} nodes:`,e.map(e=>({name:e.data.name,vertical:e.x,horizontal:e.y}))),console.log("📝 [TEXT] Total horizontal nodes:",Array.from(this.horizontalNodes))}update(e){if(!this.treeLayout||!this.treeGroup||!e)return;const t=this.treeLayout(this.root),o=t.descendants(),n=t.descendants().slice(1);this.applySingletonHorizontalLayout(o),this.isRadialLayout&&o.forEach(e=>{void 0===e.x0&&(e.x0=e.x,e.y0=e.y)});const i=this.treeGroup.selectAll("g.node").data(o,e=>e.id||(e.id=++this.nodeId)),s=i.enter().append("g").attr("class",e=>{let t=["node","code-node"];return this.isNodeDirectory(e)?(t.push("directory"),!0===e.data.loaded&&e.children&&t.push("expanded"),"loading"===e.data.loaded&&t.push("loading"),e.data.children&&0===e.data.children.length&&t.push("empty")):"file"===e.data.type&&t.push("file"),t.join(" ")}).attr("transform",t=>{if(this.isRadialLayout){const[t,o]=this.radialPoint(e.x0||0,e.y0||0);return`translate(${t},${o})`}return`translate(${e.y0},${e.x0})`}).on("click",(e,t)=>{console.log("🔴 [G-ELEMENT] Click on node group element!",{nodeName:t?.data?.name,nodePath:t?.data?.path,eventTarget:e.target.tagName,thisContext:this,hasOnNodeClick:"function"==typeof this.onNodeClick}),this.onNodeClick(e,t)});s.append("circle").attr("class","node-circle").attr("r",1e-6).style("fill",e=>this.getNodeColor(e)).style("stroke",e=>this.getNodeStrokeColor(e)).style("stroke-width",e=>this.isNodeDirectory(e)?2:1.5).style("cursor",e=>e.data&&("root"===e.data.type||e.data.isRoot||0===e.depth)?"default":"pointer").on("click",(e,t)=>{console.log("🔵 [CIRCLE] Click on circle element!",{nodeName:t?.data?.name,nodePath:t?.data?.path,hasOnNodeClick:"function"==typeof this.onNodeClick}),this.onNodeClick(e,t)}).on("mouseover",this.showTooltip).on("mouseout",this.hideTooltip),s.filter(e=>this.isNodeDirectory(e)).append("text").attr("class","expand-icon").attr("x",0).attr("y",0).attr("text-anchor","middle").attr("dominant-baseline","central").text(e=>"loading"===e.data.loaded?"⟳":!0===e.data.loaded&&e.children?"▼":"▶").style("font-size","10px").style("pointer-events","none"),s.append("text").attr("class",e=>{const t="node-label";return 0===e.depth?(console.log(`📝 [TEXT] ✅ Adding horizontal-text class to root: ${e.data.name}`),`${t} horizontal-text`):t}).attr("dy",".35em").attr("x",e=>this.isRadialLayout?0:0===e.depth||this.horizontalNodes.has(e.data.path)?(console.log(`📝 [TEXT] ✅ HORIZONTAL positioning for: ${e.data.name} (depth: ${e.depth}, path: ${e.data.path})`),console.log(`📝 [TEXT] ✅ Root check: depth === 0 = ${0===e.depth}`),console.log(`📝 [TEXT] ✅ Horizontal set check: ${this.horizontalNodes.has(e.data.path)}`),0):(console.log(`📝 [TEXT] Positioning vertical text for: ${e.data.name} (depth: ${e.depth}, path: ${e.data.path})`),e.children||e._children?-13:13)).attr("y",e=>0===e.depth||this.horizontalNodes.has(e.data.path)?-20:0).attr("text-anchor",e=>this.isRadialLayout?"start":0===e.depth||this.horizontalNodes.has(e.data.path)?"middle":e.children||e._children?"end":"start").text(e=>{const t=e.data.name||"";return t.length>20?t.substring(0,17)+"...":t}).style("fill-opacity",1e-6).style("font-size","12px").style("font-family",'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif').style("text-shadow","1px 1px 2px rgba(255,255,255,0.8), -1px -1px 2px rgba(255,255,255,0.8)").style("writing-mode",e=>0===e.depth?(console.log(`📝 [TEXT] ✅ Setting horizontal writing-mode for root: ${e.data.name}`),"horizontal-tb"):null).style("text-orientation",e=>0===e.depth?(console.log(`📝 [TEXT] ✅ Setting mixed text-orientation for root: ${e.data.name}`),"mixed"):null).on("click",(e,t)=>{console.log("📝 [LABEL] Click on text label!",{nodeName:t?.data?.name,nodePath:t?.data?.path,hasOnNodeClick:"function"==typeof this.onNodeClick}),this.onNodeClick(e,t)}).style("cursor",e=>e.data&&("root"===e.data.type||e.data.isRoot||0===e.depth)?"default":"pointer"),s.filter(e=>!this.isNodeDirectory(e)).append("text").attr("class","node-icon").attr("dy",".35em").attr("x",0).attr("text-anchor","middle").text(e=>this.getNodeIcon(e)).style("font-size","10px").style("fill","white").on("click",this.onNodeClick).style("cursor","pointer"),s.filter(e=>this.isNodeDirectory(e)&&e.data.children).append("text").attr("class","item-count-badge").attr("x",12).attr("y",-8).attr("text-anchor","middle").text(e=>{const t=e.data.children?e.data.children.length:0;return t>0?t:""}).style("font-size","9px").style("opacity",.7).on("click",this.onNodeClick).style("cursor","pointer");const a=s.merge(i);a.on("click",(e,t)=>{console.log("🟡 [NODE-UPDATE] Click on updated node!",{nodeName:t?.data?.name,nodePath:t?.data?.path,hasOnNodeClick:"function"==typeof this.onNodeClick,thisContext:this}),this.onNodeClick(e,t)}),a.selectAll("circle").on("click",this.onNodeClick),a.selectAll("text").on("click",this.onNodeClick),a.transition().duration(this.duration).attr("transform",e=>{if(this.isRadialLayout){const[t,o]=this.radialPoint(e.x,e.y);return`translate(${t},${o})`}return`translate(${e.y},${e.x})`}),a.attr("class",e=>{let t=["node","code-node"];return this.isNodeDirectory(e)?(t.push("directory"),!0===e.data.loaded&&e.children&&t.push("expanded"),"loading"===e.data.loaded&&t.push("loading"),e.data.children&&0===e.data.children.length&&t.push("empty")):"file"===e.data.type&&t.push("file"),t.join(" ")}),a.select("circle.node-circle").attr("r",e=>this.isNodeDirectory(e)?10:8).style("fill",e=>this.getNodeColor(e)),a.select(".expand-icon").text(e=>"loading"===e.data.loaded?"⟳":!0===e.data.loaded&&e.children?"▼":"▶"),a.select(".item-count-badge").text(e=>{if(!this.isNodeDirectory(e))return"";const t=e.data.children?e.data.children.length:0;return t>0?t:""}).style("stroke",e=>this.getNodeStrokeColor(e)).attr("cursor","pointer");const r=this.isRadialLayout,l=this.horizontalNodes;a.select("text.node-label").style("fill-opacity",1).style("fill","#333").each(function(e){const t=d3.select(this);if(r){const o=180*e.x/Math.PI-90;o>90||o<-90?t.attr("transform",`rotate(${o+180})`).attr("x",-15).attr("text-anchor","end").attr("dy",".35em"):t.attr("transform",`rotate(${o})`).attr("x",15).attr("text-anchor","start").attr("dy",".35em")}else{0===e.depth||l.has(e.data.path)?t.attr("transform",null).attr("x",0).attr("y",-20).attr("text-anchor","middle").attr("dy",".35em"):t.attr("transform",null).attr("x",e.children||e._children?-13:13).attr("y",0).attr("text-anchor",e.children||e._children?"end":"start").attr("dy",".35em")}});const d=i.exit().transition().duration(this.duration).attr("transform",t=>{if(this.isRadialLayout){const[t,o]=this.radialPoint(e.x,e.y);return`translate(${t},${o})`}return`translate(${e.y},${e.x})`}).remove();d.select("circle").attr("r",1e-6),d.select("text.node-label").style("fill-opacity",1e-6),d.select("text.node-icon").style("fill-opacity",1e-6);const c=this.treeGroup.selectAll("path.link").data(n,e=>e.id);if(c.enter().insert("path","g").attr("class","link").attr("d",t=>{const o={x:e.x0,y:e.y0};return this.isRadialLayout?this.radialDiagonal(o,o):this.diagonal(o,o)}).style("fill","none").style("stroke","#ccc").style("stroke-width",2).merge(c).transition().duration(this.duration).attr("d",e=>this.isRadialLayout?this.radialDiagonal(e,e.parent):this.diagonal(e,e.parent)),c.exit().transition().duration(this.duration).attr("d",t=>{const o={x:e.x,y:e.y};return this.isRadialLayout?this.radialDiagonal(o,o):this.diagonal(o,o)}).remove(),o.forEach(e=>{e.x0=e.x,e.y0=e.y}),this.zoom){const e=d3.zoomTransform(this.svg.node());1!==e.k&&this.adjustTextSizeForZoom(e.k)}}centerOnNode(e){console.log("[CodeTree] centerOnNode called but disabled - no centering will occur")}centerOnNodeRadial(e){console.log("[CodeTree] centerOnNodeRadial called but disabled - no centering will occur")}highlightActiveNode(e){const t=this.treeGroup.selectAll("circle.node-circle");t.classed("active",!1).classed("parent-context",!1),t.transition().duration(300).attr("r",8).style("stroke",null).style("stroke-width",null).style("opacity",null),this.treeGroup.selectAll("text.node-label").style("font-weight","normal").style("font-size","12px");const o=this.treeGroup.selectAll("g.node").filter(t=>t===e).select("circle.node-circle");o.classed("active",!0),o.transition().duration(300).attr("r",20).style("stroke","#3b82f6").style("stroke-width",5).style("filter","drop-shadow(0 0 15px rgba(59, 130, 246, 0.6))"),this.treeGroup.selectAll("g.node").filter(t=>t===e).select("text.node-label").style("font-weight","bold").style("font-size","14px"),this.activeNode=e}addLoadingPulse(e){const t=this.treeGroup.selectAll("g.node").filter(t=>t===e).select("circle.node-circle");this.loadingNodes.add(e.data.path),t.classed("loading-pulse",!0),t.style("fill","#fb923c");const o=()=>{this.loadingNodes.has(e.data.path)&&t.transition().duration(600).attr("r",14).style("opacity",.6).transition().duration(600).attr("r",10).style("opacity",1).on("end",()=>{this.loadingNodes.has(e.data.path)&&o()})};o()}removeLoadingPulse(e){const t=this.treeGroup.selectAll("g.node").filter(t=>t===e).select("circle.node-circle");t.classed("loading-pulse",!1),t.interrupt().transition().duration(300).attr("r",this.activeNode===e?20:8).style("opacity",1).style("fill",e=>this.getNodeColor(e))}showWithParent(e){if(!e.parent)return;const t=this.treeGroup.selectAll("g.node").filter(t=>t===e.parent).select("circle.node-circle");t.classed("parent-context",!0),t.style("stroke","#10b981").style("stroke-width",3).style("opacity",.8)}onNodeClick(e,t){const o=Date.now()+Math.random();if(console.log(`🖱️🖱️🖱️ [NODE CLICK] onNodeClick method called! (ID: ${o}):`,{thisContext:this,isBound:"CodeTree"===this.constructor.name,name:t?.data?.name,path:t?.data?.path,type:t?.data?.type,loaded:t?.data?.loaded,hasChildren:!(!t?.children&&!t?._children),dataChildren:t?.data?.children?.length||0,loadingNodesSize:this.loadingNodes?this.loadingNodes.size:"undefined"}),this.updateStructuredData(t),e)try{"function"==typeof e.stopPropagation&&e.stopPropagation()}catch(i){console.error("[CodeTree] ERROR calling stopPropagation:",i)}if(!t)return void console.error("[CodeTree] ERROR: d is null/undefined, cannot continue");if(t.data&&("root"===t.data.type||t.data.isRoot||0===t.depth))return void console.log("🚫 [ROOT CLICK] Ignoring click on root node:",t.data.name);if(!t.data)return void console.error("[CodeTree] ERROR: d.data is null/undefined, cannot continue");try{"function"==typeof this.highlightActiveNode?this.highlightActiveNode(t):console.error("[CodeTree] highlightActiveNode is not a function!")}catch(i){console.error("[CodeTree] ERROR during highlightActiveNode:",i,i.stack)}try{"function"==typeof this.showWithParent?this.showWithParent(t):console.error("[CodeTree] showWithParent is not a function!")}catch(i){console.error("[CodeTree] ERROR during showWithParent:",i,i.stack)}if(this.isNodeDirectory(t)&&!t.data.loaded)try{"function"==typeof this.addLoadingPulse?this.addLoadingPulse(t):console.error("[CodeTree] addLoadingPulse is not a function!")}catch(i){console.error("[CodeTree] ERROR during addLoadingPulse:",i,i.stack)}const n=this.getSelectedLanguages();console.log("🔍 [LANGUAGE] Selected languages:",n);document.getElementById("ignore-patterns");if(console.log("🔍 [LOAD CHECK]",{type:t.data.type,loaded:t.data.loaded,loadedType:typeof t.data.loaded,isDirectory:"directory"===t.data.type||"root"===t.data.type,notLoaded:!t.data.loaded,shouldLoad:("directory"===t.data.type||"root"===t.data.type)&&!t.data.loaded}),"directory"!==t.data.type&&"root"!==t.data.type&&!t.data.isDirectory||t.data.loaded)if("file"===t.data.type){if(console.log("📄 [FILE CLICK] File clicked:",{fileName:t.data.name,filePath:t.data.path,analyzed:t.data.analyzed}),this.displayFileInDataViewer(t),!t.data.analyzed){const e=this.detectLanguage(t.data.path);if(console.log("🔍 [FILE ANALYSIS] Language check:",{fileName:t.data.name,filePath:t.data.path,detectedLanguage:e,selectedLanguages:n,isLanguageSelected:n.includes(e),shouldAnalyze:n.includes(e)||"unknown"===e}),!n.includes(e)&&"unknown"!==e)return void console.warn("⚠️ [FILE ANALYSIS] Skipping AST analysis for file:",{fileName:t.data.name,detectedLanguage:e,selectedLanguages:n,reason:`${e} not in selected languages`})}this.addLoadingPulse(t),t.data.analyzed="loading";const o=this.ensureFullPath(t.data.path);setTimeout(()=>{if(console.log("🚀 [FILE ANALYSIS] Sending analysis request:",{fileName:t.data.name,originalPath:t.data.path,fullPath:o,hasSocket:!!this.socket,socketConnected:this.socket?.connected}),this.socket&&this.socket.connected){console.log("📡 [FILE ANALYSIS] Using SocketIO for analysis:",{event:"code:analyze:file",path:o,socketConnected:this.socket.connected,socketId:this.socket.id}),this.socket.emit("code:analyze:file",{path:o});const n=setTimeout(()=>{console.warn("⏰ [FILE ANALYSIS] SocketIO timeout, trying HTTP fallback for:",o),this.analyzeFileHTTP(o,t.data.name,d3.select(e.target.closest("g")))},5e3);this.analysisTimeouts||(this.analysisTimeouts=new Map),this.analysisTimeouts.set(o,n),this.updateBreadcrumb(`Analyzing ${t.data.name}...`,"info"),this.showNotification(`Analyzing: ${t.data.name}`,"info")}else console.log("🔄 [FILE ANALYSIS] SocketIO unavailable, using HTTP fallback"),this.updateBreadcrumb(`Analyzing ${t.data.name}...`,"info"),this.showNotification(`Analyzing: ${t.data.name}`,"info"),this.analyzeFileHTTP(o,t.data.name,d3.select(e.target.closest("g")))},100)}else if(this.isNodeDirectory(t)&&!0===t.data.loaded){if(t.children)t._children=t.children,t.children=null,t.data.expanded=!1;else if(t._children)t.children=t._children,t._children=null,t.data.expanded=!0;else if(t.data.children&&t.data.children.length>0){this.root=d3.hierarchy(this.treeData);const e=this.findD3NodeByPath(t.data.path);e&&(e.children=e._children||e.children,e._children=null,e.data.expanded=!0)}this.update(this.root)}else(t.children||t._children)&&(t.children?(t._children=t.children,t.children=null,t.data.expanded=!1):(t.children=t._children,t._children=null,t.data.expanded=!0),this.update(t));else{console.log("✅ [SUBDIRECTORY LOADING] Load check passed, proceeding with loading logic"),console.log("🔍 [SUBDIRECTORY LOADING] Initial loading state:",{loadingNodesSize:this.loadingNodes?this.loadingNodes.size:"undefined",loadingNodesContent:Array.from(this.loadingNodes||[])});try{console.log("🔍 [SUBDIRECTORY LOADING] Checking for duplicates:",{path:t.data.path,pathType:typeof t.data.path,loadingNodesType:typeof this.loadingNodes,loadingNodesSize:this.loadingNodes?this.loadingNodes.size:"undefined",hasMethod:this.loadingNodes&&"function"==typeof this.loadingNodes.has});const e=this.loadingNodes&&this.loadingNodes.has(t.data.path);console.log("🔍 [SUBDIRECTORY LOADING] Duplicate check result:",{isDuplicate:e,loadingNodesContent:Array.from(this.loadingNodes||[]),pathBeingChecked:t.data.path}),e&&(console.warn("⚠️ [SUBDIRECTORY LOADING] Duplicate request detected, but proceeding anyway:",{path:t.data.path,name:t.data.name,loadingNodesSize:this.loadingNodes.size,loadingNodesContent:Array.from(this.loadingNodes),pathInSet:this.loadingNodes.has(t.data.path)}),this.loadingNodes.delete(t.data.path),console.log("🧹 [SUBDIRECTORY LOADING] Removed duplicate entry, proceeding with fresh request")),console.log("✅ [SUBDIRECTORY LOADING] No duplicate request, proceeding to mark as loading"),t.data.loaded="loading",this.loadingNodes.add(t.data.path);const o=this.ensureFullPath(t.data.path);console.log("🚀 [SUBDIRECTORY LOADING] Attempting to load:",{originalPath:t.data.path,fullPath:o,nodeType:t.data.type,loaded:t.data.loaded,hasSocket:!!this.socket,workingDir:this.getWorkingDirectory()});setTimeout(()=>{console.log("📡 [SUBDIRECTORY LOADING] Using REST API for directory:",{originalPath:t.data.path,fullPath:o,apiUrl:`${window.location.origin}/api/directory?path=${encodeURIComponent(o)}`,loadingNodesSize:this.loadingNodes.size,loadingNodesContent:Array.from(this.loadingNodes)});const e=`${window.location.origin}/api/directory?path=${encodeURIComponent(o)}`;if(fetch(e).then(e=>{if(!e.ok)throw new Error(`HTTP ${e.status}: ${e.statusText}`);return e.json()}).then(e=>{console.log("✅ [SUBDIRECTORY LOADING] REST API response:",{data:e,pathToDelete:t.data.path,loadingNodesBefore:Array.from(this.loadingNodes)});const o=this.loadingNodes.delete(t.data.path);t.data.loaded=!0,console.log("🧹 [SUBDIRECTORY LOADING] Cleanup result:",{pathDeleted:t.data.path,wasDeleted:o,loadingNodesAfter:Array.from(this.loadingNodes)});const n=this.findD3NodeByPath(t.data.path);if(n&&this.removeLoadingPulse(n),e.exists&&e.is_directory&&e.contents){const o=this.findNodeByPath(t.data.path);if(o){if(console.log("🔧 [SUBDIRECTORY LOADING] Creating children with paths:",e.contents.map(e=>({name:e.name,path:e.path}))),o.children=e.contents.map(e=>({name:e.name,path:e.path,type:e.is_directory?"directory":"file",loaded:!e.is_directory&&void 0,analyzed:!!e.is_directory&&void 0,expanded:!1,children:e.is_directory?[]:void 0})),o.loaded=!0,o.expanded=!0,this.root&&this.svg){const o=this.root;this.root=d3.hierarchy(this.treeData),this.root.x0=this.height/2,this.root.y0=0,this.preserveExpansionState(o,this.root);const n=this.findD3NodeByPath(t.data.path);n&&n.children&&n.children.length>0&&(n._children=null,n.data.expanded=!0),this.update(n||this.root),n&&e.contents.length>0&&setTimeout(()=>{this.focusOnDirectory(n)},500)}this.updateBreadcrumb(`Loaded ${e.contents.length} items`,"success"),this.showNotification(`Loaded ${e.contents.length} items from ${t.data.name}`,"success")}}else this.showNotification(`Directory ${t.data.name} is empty or inaccessible`,"warning")}).catch(e=>{console.error("❌ [SUBDIRECTORY LOADING] REST API error:",{error:e.message,stack:e.stack,pathToDelete:t.data.path,loadingNodesBefore:Array.from(this.loadingNodes)});const o=this.loadingNodes.delete(t.data.path);t.data.loaded=!1,console.log("🧹 [SUBDIRECTORY LOADING] Error cleanup:",{pathDeleted:t.data.path,wasDeleted:o,loadingNodesAfter:Array.from(this.loadingNodes)});const n=this.findD3NodeByPath(t.data.path);n&&this.removeLoadingPulse(n),this.showNotification(`Failed to load ${t.data.name}: ${e.message}`,"error")}),this.updateBreadcrumb(`Loading ${t.data.name}...`,"info"),this.showNotification(`Loading directory: ${t.data.name}`,"info"),!window.fetch){console.error("❌ [SUBDIRECTORY LOADING] No WebSocket connection available!"),this.showNotification("Cannot load directory: No connection","error"),this.loadingNodes.delete(t.data.path);const e=this.findD3NodeByPath(t.data.path);e&&this.removeLoadingPulse(e),t.data.loaded=!1}},100)}catch(i){console.error("❌ [SUBDIRECTORY LOADING] Error in directory loading logic:",{error:i.message,stack:i.stack,path:t.data.path,nodeData:t.data}),this.showNotification(`Error loading directory: ${i.message}`,"error")}}this.selectedNode=t;try{this.highlightNode(t)}catch(i){console.error("[CodeTree] ERROR during highlightNode:",i)}}ensureFullPath(e){if(console.log("🔗 ensureFullPath called with:",e),!e)return e;if(e.startsWith("/"))return console.log(" → Already absolute, returning:",e),e;const t=this.getWorkingDirectory();if(console.log(" → Working directory:",t),!t)return console.log(" → No working directory, returning original:",e),e;if("."===e)return console.log(" → Root path detected, returning working dir:",t),t;if(e===t)return console.log(" → Path equals working directory, returning:",t),t;const o=`${t}/${e}`.replace(/\/+/g,"/");return console.log(" → Combining with working dir, result:",o),o}highlightNode(e){this.treeGroup.selectAll("circle.node-circle").style("stroke-width",2).classed("selected",!1),this.treeGroup.selectAll("circle.node-circle").filter(t=>t===e).style("stroke-width",4).classed("selected",!0)}diagonal(e,t){return`M ${e.y} ${e.x}\n C ${(e.y+t.y)/2} ${e.x},\n ${(e.y+t.y)/2} ${t.x},\n ${t.y} ${t.x}`}radialDiagonal(e,t){return d3.linkRadial().angle(e=>e.x).radius(e=>e.y)({source:e,target:t})}isNodeDirectory(e){const t=e.data||e;return"directory"===t.type||"root"===t.type||!0===t.isDirectory}getNodeColor(e){const t=e.data.type,o=e.data.complexity||1,n={root:"#6B7280",directory:"#3B82F6",file:"#10B981",module:"#8B5CF6",class:"#F59E0B",function:"#EF4444",method:"#EC4899"}[t]||"#6B7280";return o>10?d3.color(n).darker(.5):o>5?d3.color(n).darker(.25):n}getNodeStrokeColor(e){return"loading"===e.data.loaded||"loading"===e.data.analyzed?"#FCD34D":this.isNodeDirectory(e)&&!e.data.loaded?"#94A3B8":"file"!==e.data.type||e.data.analyzed?this.getNodeColor(e):"#CBD5E1"}getNodeIcon(e){return{root:"📦",directory:"📁",file:"📄",module:"📦",class:"C",function:"ƒ",method:"m"}[e.data.type]||"•"}showTooltip(e,t){if(!this.tooltip)return;const o=[];o.push(`<strong>${t.data.name}</strong>`),o.push(`Type: ${t.data.type}`),t.data.language&&o.push(`Language: ${t.data.language}`),t.data.complexity&&o.push(`Complexity: ${t.data.complexity}`),t.data.lines&&o.push(`Lines: ${t.data.lines}`),t.data.path&&o.push(`Path: ${t.data.path}`),this.isNodeDirectory(t)&&!t.data.loaded?o.push("<em>Click to explore contents</em>"):"file"!==t.data.type||t.data.analyzed||o.push("<em>Click to analyze file</em>"),this.tooltip.transition().duration(200).style("opacity",.9),this.tooltip.html(o.join("<br>")).style("left",e.pageX+10+"px").style("top",e.pageY-28+"px")}hideTooltip(){this.tooltip&&this.tooltip.transition().duration(500).style("opacity",0)}filterTree(){this.root&&(this.root.descendants().forEach(e=>{e.data._hidden=!1,"all"!==this.languageFilter&&"file"===e.data.type&&e.data.language!==this.languageFilter&&(e.data._hidden=!0),this.searchTerm&&(e.data.name.toLowerCase().includes(this.searchTerm)||(e.data._hidden=!0))}),this.update(this.root))}expandAll(){if(!this.root)return;const e=t=>{t._children&&(t.children=t._children,t._children=null),t.children&&t.children.forEach(e)};e(this.root),this.update(this.root),this.showNotification("All nodes expanded","info")}collapseAll(){if(!this.root)return;const e=t=>{t.children&&(t._children=t.children,t.children=null),t._children&&t._children.forEach(e)};this.root.children?.forEach(e),this.update(this.root),this.showNotification("All nodes collapsed","info")}focusOnDirectory(e){if(!e||"directory"!==e.data.type)return;console.log("🎯 [FOCUS] Focusing on directory:",e.data.path),this.focusedNode=e;const t={...e.data,name:`📁 ${e.data.name}`,children:e.data.children||[]},o=d3.hierarchy(t);o.x0=this.height/2,o.y0=0,this.originalRoot||(this.originalRoot=this.root),this.root=o,this.update(this.root),d3.select("#code-tree-container").classed("focused",!0),this.updateBreadcrumb(`Focused on: ${e.data.name}`,"info"),this.showNotification(`Focused on directory: ${e.data.name}`,"info"),this.addBackButton()}unfocusDirectory(){this.originalRoot&&(console.log("🔙 [FOCUS] Returning to full tree view"),this.root=this.originalRoot,this.originalRoot=null,this.focusedNode=null,this.update(this.root),d3.select("#code-tree-container").classed("focused",!1),this.removeBackButton(),this.updateBreadcrumb("Full tree view restored","success"),this.showNotification("Returned to full tree view","success"))}addBackButton(){d3.select("#tree-back-button").remove();const e=d3.select(".tree-controls-toolbar");e.empty()||e.insert("button",":first-child").attr("id","tree-back-button").attr("class","tree-control-btn back-btn").attr("title","Return to full tree view").text("← Back").on("click",()=>this.unfocusDirectory())}removeBackButton(){d3.select("#tree-back-button").remove()}resetZoom(){if(!this.svg||!this.zoom)return;const e=this.treeGroup.node().getBBox(),t=this.width,o=this.height,n=e.width,i=e.height,s=e.x+n/2,a=e.y+i/2;if(0===n||0===i)return;const r=.9*Math.min(t/n,o/i),l=[t/2-r*s,o/2-r*a];this.svg.transition().duration(750).call(this.zoom.transform,d3.zoomIdentity.translate(l[0],l[1]).scale(r)),this.showNotification("Zoom reset to fit tree","info")}zoomIn(){this.svg&&this.zoom&&this.svg.transition().duration(300).call(this.zoom.scaleBy,1.5)}zoomOut(){this.svg&&this.zoom&&this.svg.transition().duration(300).call(this.zoom.scaleBy,1/1.5)}updateZoomLevel(e){const t=document.getElementById("zoom-level-display");t&&(t.textContent=`${Math.round(100*e)}%`)}adjustTextSizeForZoom(e){if(!this.treeGroup)return;const t=1/e;this.treeGroup.selectAll("text").style("font-size",12*t+"px").attr("transform",function(){const e=(d3.select(this).attr("transform")||"").replace(/scale\([^)]*\)/g,"").trim();return e?`${e} scale(${t})`:`scale(${t})`}),this.treeGroup.selectAll(".expand-icon").style("font-size",12*t+"px").attr("transform",function(){const e=(d3.select(this).attr("transform")||"").replace(/scale\([^)]*\)/g,"").trim();return e?`${e} scale(${t})`:`scale(${t})`}),this.treeGroup.selectAll(".item-count-badge").style("font-size",10*t+"px").attr("transform",function(){const e=(d3.select(this).attr("transform")||"").replace(/scale\([^)]*\)/g,"").trim();return e?`${e} scale(${t})`:`scale(${t})`})}addZoomKeyboardShortcuts(){document.addEventListener("keydown",e=>{const t=document.getElementById("code-tab");if(t&&t.classList.contains("active")&&"INPUT"!==e.target.tagName&&"TEXTAREA"!==e.target.tagName&&(e.ctrlKey||e.metaKey))switch(e.key){case"=":case"+":e.preventDefault(),this.zoomIn();break;case"-":e.preventDefault(),this.zoomOut();break;case"0":e.preventDefault(),this.resetZoom()}})}isSourceFile(e){if(!e)return!1;return[".py",".js",".ts",".jsx",".tsx",".java",".cpp",".c",".h",".cs",".php",".rb",".go",".rs",".swift"].some(t=>e.toLowerCase().endsWith(t))}async showSourceViewer(e){if(console.log("📄 [SOURCE VIEWER] Starting showSourceViewer for:",e.data.path),console.log(" Node type:",e.data.type),console.log(" Content element available:",!!this.structuredDataContent),!this.structuredDataContent)return void console.error("❌ [SOURCE VIEWER] No content element to display source in!");const t=document.createElement("div");t.className="source-viewer",console.log("📦 [SOURCE VIEWER] Created source viewer container");const o=document.createElement("div");o.className="source-viewer-header",o.innerHTML=`\n <span>📄 ${e.data.name||"Source File"}</span>\n <div class="source-viewer-controls">\n <button class="source-control-btn" id="expand-all-source" title="Expand all">⬇</button>\n <button class="source-control-btn" id="collapse-all-source" title="Collapse all">⬆</button>\n </div>\n `;const n=document.createElement("div");n.className="source-viewer-content",n.id="source-viewer-content",t.appendChild(o),t.appendChild(n),console.log("🔨 [SOURCE VIEWER] Appending source viewer to content element..."),this.structuredDataContent.appendChild(t),console.log("✅ [SOURCE VIEWER] Source viewer added to DOM"),console.log(" Content element children count:",this.structuredDataContent.children.length),console.log(" Content element HTML preview:",this.structuredDataContent.innerHTML.substring(0,200)+"..."),document.getElementById("expand-all-source")?.addEventListener("click",()=>this.expandAllSource()),document.getElementById("collapse-all-source")?.addEventListener("click",()=>this.collapseAllSource());try{await this.loadSourceContent(e,n)}catch(i){console.error("Failed to load source content:",i),n.innerHTML='\n <div class="ast-data-placeholder">\n <div class="ast-placeholder-icon">❌</div>\n <div class="ast-placeholder-text">Failed to load source file</div>\n </div>\n '}}focusOnNode(e){console.log("[CodeTree] focusOnNode called but disabled - no focusing will occur")}getNodePath(e){const t=[];let o=e;for(;o;)o.data&&o.data.name&&t.unshift(o.data.name),o=o.parent;return t.join(" / ")}toggleLegend(){const e=document.getElementById("tree-legend");e&&("none"===e.style.display?e.style.display="block":e.style.display="none")}getWorkingDirectory(){if(window.dashboard&&window.dashboard.workingDirectoryManager)return window.dashboard.workingDirectoryManager.getCurrentWorkingDir();const e=document.getElementById("working-dir-path");if(e){const t=e.textContent.trim();if(t&&"Loading..."!==t&&"Not selected"!==t)return t}return null}showNoWorkingDirectoryMessage(){const e=document.getElementById("code-tree-container");if(!e)return;this.removeNoWorkingDirectoryMessage(),this.hideLoading();const t=document.createElement("div");t.id="no-working-dir-message",t.className="no-working-dir-message",t.innerHTML='\n <div class="message-icon">📁</div>\n <h3>No Working Directory Selected</h3>\n <p>Please select a working directory from the top menu to analyze code.</p>\n <button id="select-working-dir-btn" class="btn btn-primary">\n Select Working Directory\n </button>\n ',t.style.cssText="\n text-align: center;\n padding: 40px;\n color: #666;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n ";const o=t.querySelector(".message-icon");o&&(o.style.cssText="font-size: 48px; margin-bottom: 16px; opacity: 0.5;");const n=t.querySelector("h3");n&&(n.style.cssText="margin: 16px 0; color: #333; font-size: 20px;");const i=t.querySelector("p");i&&(i.style.cssText="margin: 16px 0; color: #666; font-size: 14px;");const s=t.querySelector("button");s&&(s.style.cssText="\n margin-top: 20px;\n padding: 10px 20px;\n background: #3b82f6;\n color: white;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n font-size: 14px;\n transition: background 0.2s;\n ",s.addEventListener("mouseenter",()=>{s.style.background="#2563eb"}),s.addEventListener("mouseleave",()=>{s.style.background="#3b82f6"}),s.addEventListener("click",()=>{const e=document.getElementById("change-dir-btn");e?e.click():window.dashboard&&window.dashboard.workingDirectoryManager&&window.dashboard.workingDirectoryManager.showChangeDirDialog()})),e.appendChild(t),this.updateBreadcrumb("Please select a working directory","warning")}removeNoWorkingDirectoryMessage(){const e=document.getElementById("no-working-dir-message");e&&e.remove()}clearLoadingState(){console.log("🧹 [DEBUG] Clearing loading state:",{loadingNodesBefore:Array.from(this.loadingNodes),size:this.loadingNodes.size}),this.loadingNodes.clear(),this.resetLoadingFlags(this.treeData),console.log("✅ [DEBUG] Loading state cleared"),this.showNotification("Loading state cleared","info")}resetLoadingFlags(e){"loading"===e.loaded&&(e.loaded=!1),e.children&&e.children.forEach(e=>this.resetLoadingFlags(e))}exportTree(){const e={timestamp:(new Date).toISOString(),workingDirectory:this.getWorkingDirectory(),stats:this.stats,tree:this.treeData},t=new Blob([JSON.stringify(e,null,2)],{type:"application/json"}),o=URL.createObjectURL(t),n=document.createElement("a");n.href=o,n.download=`code-tree-${Date.now()}.json`,n.click(),URL.revokeObjectURL(o),this.showNotification("Tree exported successfully","success")}updateActivityTicker(e,t="info"){const o=document.getElementById("breadcrumb-content");if(o){const n="info"===t&&e.includes("...")?"⟳ ":"";o.innerHTML=`${n}${e}`,o.className=`breadcrumb-${t}`}}updateTicker(e,t="info"){const o=document.getElementById("code-tree-ticker");o&&(o.textContent=e,o.className=`ticker ticker-${t}`,"error"!==t&&setTimeout(()=>{o.style.opacity="0",setTimeout(()=>{o.style.opacity="1",o.textContent=""},300)},5e3))}initializeStructuredData(){if(console.log("🔄 [CODE TREE] Initializing structured data integration..."),this.structuredDataContent=document.getElementById("module-data-content"),!this.structuredDataContent)return console.warn("⏳ [CODE TREE] Structured data element not found yet, retrying in 500ms..."),void setTimeout(()=>{if(this.structuredDataContent=document.getElementById("module-data-content"),this.structuredDataContent)console.log("✅ [CODE TREE] Structured data integration initialized on retry"),console.log(" Target element:",this.structuredDataContent),console.log(" Parent element:",this.structuredDataContent.parentElement);else{console.error("❌ [CODE TREE] Structured data content element (#module-data-content) not found after retry!"),console.log("[CODE TREE] Checking DOM for available elements...");const e=document.querySelectorAll('[id*="module"], [id*="data"]');console.log(`[CODE TREE] Found ${e.length} elements with "module" or "data" in ID:`),e.forEach(e=>{console.log(` - #${e.id} (class: ${e.className}, parent: ${e.parentElement?.id||"no-parent"})`)});const t=document.querySelector(".module-viewer");if(t){console.log("[CODE TREE] Module viewer found, checking children...");const e=t.querySelector("#module-data-content");e?(console.log("[CODE TREE] Found module-data-content via query selector!"),this.structuredDataContent=e):console.log("[CODE TREE] Module data content not found in module viewer")}}},500);console.log("✅ [CODE TREE] Structured data integration initialized immediately"),console.log(" Target element:",this.structuredDataContent),console.log(" Parent element:",this.structuredDataContent.parentElement)}updateStructuredData(e){if(console.log("📝 [STRUCTURED DATA] updateStructuredData called"),!this.structuredDataContent)if(console.warn("⚠️ [STRUCTURED DATA] Content element not available, trying to find it..."),this.structuredDataContent=document.getElementById("module-data-content"),this.structuredDataContent)console.log("✅ [STRUCTURED DATA] Found element on retry");else{console.error("❌ [STRUCTURED DATA] Cannot find module-data-content element!");const e=document.querySelector(".module-viewer");if(!e)return void console.error("❌ [STRUCTURED DATA] Module viewer not found either, aborting update");if(this.structuredDataContent=e.querySelector("#module-data-content"),!this.structuredDataContent)return void console.error("❌ [STRUCTURED DATA] Still cannot find element, aborting update");console.log("✅ [STRUCTURED DATA] Found element via module-viewer query")}if(console.log("🔍 [STRUCTURED DATA] Updating with node:",{name:e?.data?.name,type:e?.data?.type,path:e?.data?.path,hasChildren:!(!e?.children&&!e?._children),dataChildren:e?.data?.children?.length||0,contentElement:this.structuredDataContent}),this.structuredDataContent.innerHTML="",console.log("🧹 [STRUCTURED DATA] Cleared previous content"),"file"===e.data.type&&this.isSourceFile(e.data.path))this.showSourceViewer(e);else{const t=e.children||e._children||[],o=e.data.children||[];t.length>0||o.length>0?this.showASTNodeChildren(e):"file"===e.data.type&&e.data.analyzed?this.showASTFileDetails(e):this.showASTNodeDetails(e)}}showASTNodeChildren(e){const t=e.children||e._children||[],o=e.data.children||[],n=t.length>0?t:o;if(0===n.length)return void this.showASTEmptyState("No children found");const i=document.createElement("div");i.className="structured-view-header",i.innerHTML=`<h4>${this.getNodeIcon(e.data.type)} ${e.data.name||"Node"} - Children (${n.length})</h4>`,this.structuredDataContent.appendChild(i),n.forEach((e,t)=>{const o=e.data||e,n=this.createASTDataViewerItem(o,t);this.structuredDataContent.appendChild(n)})}showASTFileDetails(e){const t=document.createElement("div");t.className="structured-view-header",t.innerHTML=`<h4>${this.getNodeIcon(e.data.type)} ${e.data.name||"File"} - Details</h4>`,this.structuredDataContent.appendChild(t);const o=[];e.data.language&&o.push({label:"Language",value:e.data.language}),e.data.lines&&o.push({label:"Lines",value:e.data.lines}),void 0!==e.data.complexity&&o.push({label:"Complexity",value:e.data.complexity}),e.data.size&&o.push({label:"Size",value:this.formatFileSize(e.data.size)}),0!==o.length?o.forEach((e,t)=>{const o=this.createASTDetailItem(e,t);this.structuredDataContent.appendChild(o)}):this.showASTEmptyState("No details available")}showASTNodeDetails(e){const t=document.createElement("div");t.className="structured-view-header",t.innerHTML=`<h4>${this.getNodeIcon(e.data.type)} ${e.data.name||"Node"} - Details</h4>`,this.structuredDataContent.appendChild(t);const o=[];o.push({label:"Type",value:e.data.type||"unknown"}),o.push({label:"Path",value:e.data.path||"unknown"}),e.data.line&&o.push({label:"Line",value:e.data.line}),o.forEach((e,t)=>{const o=this.createASTDetailItem(e,t);this.structuredDataContent.appendChild(o)})}createASTDataViewerItem(e,t){const o=document.createElement("div");o.className="ast-data-viewer-item",o.dataset.index=t;const n=document.createElement("div");n.className="ast-data-item-header";const i=document.createElement("div");i.className="ast-data-item-name",i.innerHTML=`${this.getNodeIcon(e.type)} ${e.name||"Unknown"}`;const s=document.createElement("div");s.className=`ast-data-item-type ${e.type||"unknown"}`,s.textContent=e.type||"unknown",n.appendChild(i),n.appendChild(s);const a=document.createElement("div");a.className="ast-data-item-details";const r=[];if(e.line&&r.push(`<span class="ast-data-item-line">Line ${e.line}</span>`),void 0!==e.complexity){const t=this.getComplexityLevel(e.complexity);r.push(`<span class="ast-data-item-complexity">\n <span class="ast-complexity-indicator ${t}"></span>\n Complexity: ${e.complexity}\n </span>`)}return e.docstring&&r.push(`<div style="margin-top: 4px; font-style: italic;">${e.docstring}</div>`),a.innerHTML=r.join(" "),o.appendChild(n),o.appendChild(a),o.addEventListener("click",()=>{this.selectASTDataViewerItem(o)}),o}createASTDetailItem(e,t){const o=document.createElement("div");o.className="ast-data-viewer-item",o.dataset.index=t;const n=document.createElement("div");n.className="ast-data-item-header";const i=document.createElement("div");i.className="ast-data-item-name",i.textContent=e.label;const s=document.createElement("div");return s.className="ast-data-item-details",s.textContent=e.value,n.appendChild(i),o.appendChild(n),o.appendChild(s),o}showASTEmptyState(e){this.structuredDataContent.innerHTML=`\n <div class="ast-data-placeholder">\n <div class="ast-placeholder-icon">📭</div>\n <div class="ast-placeholder-text">${e}</div>\n </div>\n `}selectASTDataViewerItem(e){const t=this.structuredDataContent.querySelector(".ast-data-viewer-item.selected");t&&t.classList.remove("selected"),e.classList.add("selected"),this.selectedASTItem=e}getNodeIcon(e){return{directory:"📁",file:"📄",class:"🏛️",function:"⚡",method:"🔧",variable:"📦",import:"📥",module:"📦"}[e]||"📄"}getComplexityLevel(e){return e<=5?"low":e<=10?"medium":"high"}formatFileSize(e){if(0===e)return"0 B";const t=Math.floor(Math.log(e)/Math.log(1024));return parseFloat((e/Math.pow(1024,t)).toFixed(1))+" "+["B","KB","MB","GB"][t]}async loadSourceContent(e,t){const o=await this.readSourceFile(e.data.path);if(!o)throw new Error("Could not read source file");const n=e.data.children||[];this.renderSourceWithAST(o,n,t,e)}async readSourceFile(e){try{console.log("📖 [SOURCE READER] Reading file:",e);const t=await fetch(`/api/file/read?path=${encodeURIComponent(e)}`);if(!t.ok){const o=await t.json();return console.error("Failed to read file:",o),this.generatePlaceholderSource(e)}const o=await t.json();return console.log("📖 [SOURCE READER] Read",o.lines,"lines from",o.name),o.content}catch(t){return console.error("Failed to read source file:",t),this.generatePlaceholderSource(e)}}generatePlaceholderSource(e){const t=e.split("/").pop();return t.endsWith(".py")?`"""\n${t}\nGenerated placeholder content for demonstration\n"""\n\nimport os\nimport sys\nfrom typing import List, Dict, Optional\n\nclass ExampleClass:\n """Example class with methods."""\n\n def __init__(self, name: str):\n """Initialize the example class."""\n self.name = name\n self.data = {}\n\n def process_data(self, items: List[str]) -> Dict[str, int]:\n """Process a list of items and return counts."""\n result = {}\n for item in items:\n result[item] = result.get(item, 0) + 1\n return result\n\n def get_summary(self) -> str:\n """Get a summary of the processed data."""\n if not self.data:\n return "No data processed"\n return f"Processed {len(self.data)} items"\n\ndef main():\n """Main function."""\n example = ExampleClass("demo")\n items = ["a", "b", "a", "c", "b", "a"]\n result = example.process_data(items)\n print(example.get_summary())\n return result\n\nif __name__ == "__main__":\n main()\n`:`// ${t}\n// Generated placeholder content for demonstration\n\nclass ExampleClass {\n constructor(name) {\n this.name = name;\n this.data = {};\n }\n\n processData(items) {\n const result = {};\n for (const item of items) {\n result[item] = (result[item] || 0) + 1;\n }\n return result;\n }\n\n getSummary() {\n if (Object.keys(this.data).length === 0) {\n return "No data processed";\n }\n return \`Processed \${Object.keys(this.data).length} items\`;\n }\n}\n\nfunction main() {\n const example = new ExampleClass("demo");\n const items = ["a", "b", "a", "c", "b", "a"];\n const result = example.processData(items);\n console.log(example.getSummary());\n return result;\n}\n\nmain();\n`}renderSourceWithAST(e,t,o,n){const i=e.split("\n"),s=this.createASTLineMap(t);console.log("🎨 [SOURCE RENDERER] Rendering source with AST:",{lines:i.length,astElements:t.length,astMap:Object.keys(s).length}),i.forEach((e,t)=>{const i=t+1,a=this.createSourceLine(e,i,s[i],n);o.appendChild(a)}),this.currentSourceContainer=o,this.currentASTElements=t}createASTLineMap(e){const t={};return e.forEach(e=>{e.line&&(t[e.line]||(t[e.line]=[]),t[e.line].push(e))}),t}createSourceLine(e,t,o,n){const i=document.createElement("div");i.className="source-line",i.dataset.lineNumber=t;const s=o&&o.length>0;s&&(i.classList.add("ast-element"),i.dataset.astElements=JSON.stringify(o));const a=this.isCollapsibleLine(e,o);a&&i.classList.add("collapsible");const r=document.createElement("span");r.className="line-number",r.textContent=t;const l=document.createElement("span");l.className="collapse-indicator",a?(l.classList.add("expanded"),l.addEventListener("click",e=>{e.stopPropagation(),this.toggleSourceSection(i)})):l.classList.add("none");const d=document.createElement("span");return d.className="line-content",d.innerHTML=this.applySyntaxHighlighting(e),s&&i.addEventListener("click",()=>{this.onSourceLineClick(i,o,n)}),i.appendChild(r),i.appendChild(l),i.appendChild(d),i}isCollapsibleLine(e,t){const o=e.trim();return!!(o.startsWith("def ")||o.startsWith("class ")||o.startsWith("async def "))||(!!(o.includes("function ")||o.includes("class ")||o.includes("=> {")||o.match(/^\s*\w+\s*\([^)]*\)\s*{/))||!!t&&t.some(e=>"function"===e.type||"class"===e.type||"method"===e.type||"FunctionDef"===e.type||"ClassDef"===e.type))}applySyntaxHighlighting(e,t="text"){let o=e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");const n=[];if("json"===t||this.currentFilePath?.endsWith(".json")){const e=/"([^"]+)"(?=\s*:)/g;let t;for(;null!==(t=e.exec(o));)n.push({start:t.index,end:t.index+t[0].length,replacement:`<span class="json-key">${t[0]}</span>`});const i=/:\s*"([^"]*)"/g;for(;null!==(t=i.exec(o));){const e=t[0].indexOf('"');n.push({start:t.index+e,end:t.index+t[0].length,replacement:`<span class="string">"${t[1]}"</span>`})}const s=/:\s*(-?\d+\.?\d*)/g;for(;null!==(t=s.exec(o));){const e=t[0].indexOf(t[1]);n.push({start:t.index+e,end:t.index+t[0].length,replacement:`<span class="number">${t[1]}</span>`})}const a=/\b(true|false|null)\b/g;for(;null!==(t=a.exec(o));)n.push({start:t.index,end:t.index+t[0].length,replacement:`<span class="literal">${t[0]}</span>`})}else{const e=/\b(def|class|import|from|if|else|elif|for|while|try|except|finally|with|as|return|yield|lambda|async|await|function|const|let|var|catch|export)\b/g;let t;for(;null!==(t=e.exec(o));)n.push({start:t.index,end:t.index+t[0].length,replacement:`<span class="keyword">${t[0]}</span>`});const i=/(["'`])([^"'`]*?)\1/g;for(;null!==(t=i.exec(o));)n.push({start:t.index,end:t.index+t[0].length,replacement:`<span class="string">${t[0]}</span>`});const s=/(#.*$|\/\/.*$)/gm;for(;null!==(t=s.exec(o));)n.push({start:t.index,end:t.index+t[0].length,replacement:`<span class="comment">${t[0]}</span>`})}n.sort((e,t)=>t.start-e.start);for(const i of n){const e=o.substring(0,i.start),t=o.substring(i.end);(!e.includes("<span")||e.lastIndexOf("</span>")>e.lastIndexOf("<span"))&&(o=e+i.replacement+t)}return o}toggleSourceSection(e){e.querySelector(".collapse-indicator").classList.contains("expanded")?this.collapseSourceSection(e):this.expandSourceSection(e)}collapseSourceSection(e){const t=e.querySelector(".collapse-indicator");t.classList.remove("expanded"),t.classList.add("collapsed"),parseInt(e.dataset.lineNumber);const o=e.parentElement,n=Array.from(o.children);let i=n.indexOf(e)+1;const s=this.getLineIndentation(e.querySelector(".line-content").textContent);for(;i<n.length;){const e=n[i],t=e.querySelector(".line-content").textContent,o=this.getLineIndentation(t);if(t.trim()&&o<=s)break;e.classList.add("collapsed-content"),i++}const a=document.createElement("div");a.className="source-line collapsed-placeholder",a.innerHTML='\n <span class="line-number"></span>\n <span class="collapse-indicator none"></span>\n <span class="line-content"> ... (collapsed)</span>\n ',e.insertAdjacentElement("afterend",a)}expandSourceSection(e){const t=e.querySelector(".collapse-indicator");t.classList.remove("collapsed"),t.classList.add("expanded");const o=e.parentElement;Array.from(o.children).forEach(e=>{e.classList.contains("collapsed-content")&&e.classList.remove("collapsed-content")});const n=e.nextElementSibling;n&&n.classList.contains("collapsed-placeholder")&&n.remove()}getLineIndentation(e){const t=e.match(/^(\s*)/);return t?t[1].length:0}autoExpandFileWithAST(e,t){if(console.log("🌳 [AST EXPANSION] Auto-expanding file with AST:",{filePath:e,hasChildren:!!(t&&t.children&&t.children.length>0)}),!t||!t.children||0===t.children.length)return void console.log("⚠️ [AST EXPANSION] No children to expand");if(!this.findD3NodeByPath(e))return void console.log("⚠️ [AST EXPANSION] D3 node not found for path:",e);this.root=d3.hierarchy(this.treeData);const o=this.findD3NodeByPath(e);if(o&&(o._children||o.children&&0===o.children.length)){o.children=o._children||o.children,o._children=null,o.data.expanded=!0,console.log("✅ [AST EXPANSION] Expanded file node to show AST elements:",{filePath:e,childrenCount:o.children?o.children.length:0}),this.update(this.root);const t=e.split("/").pop(),n=o.children?o.children.length:0;this.showNotification(`📊 ${t} - AST tree expanded with ${n} elements`,"success"),this.updateBreadcrumb(`${t} - Code structure visible in tree`,"success")}}displayFileInDataViewer(e){console.log("📊 [DATA VIEWER] Displaying file in data viewer:",{fileName:e.data.name,filePath:e.data.path,fileType:e.data.type});const t={file_path:e.data.path,name:e.data.name,type:"file",size:e.data.size||0,extension:this.getFileExtension(e.data.path),language:this.detectLanguage(e.data.path),operations:[{operation:"view",timestamp:(new Date).toISOString(),source:"code_tree_click"}],metadata:{clicked_from:"code_tree",node_type:e.data.type,has_ast:e.data.analyzed||!1,tree_path:this.getNodePath(e)}};window.unifiedDataViewer?(window.unifiedDataViewer.display(t,"file_operation"),console.log("✅ [DATA VIEWER] File data displayed in unified viewer")):console.warn("⚠️ [DATA VIEWER] UnifiedDataViewer not available");const o=document.querySelector(".module-data-header h5");if(o){const t=e.data.name,n=this.getFileIcon(e.data.path);o.innerHTML=`${n} File: ${t}`}setTimeout(()=>{this.offerFileViewerOption(e)},1e3)}offerFileViewerOption(e){if(!this.isTextFile(e.data.path))return;const t=e.data.name,o=document.createElement("div");o.className="file-viewer-offer",o.innerHTML=`\n <div class="offer-content">\n <span class="offer-text">📄 ${t} loaded in data viewer</span>\n <button class="offer-button" onclick="this.parentElement.parentElement.remove(); window.showFileViewerModal && window.showFileViewerModal('${e.data.path}')">\n 🔍 Open Full Viewer\n </button>\n <button class="offer-close" onclick="this.parentElement.parentElement.remove()">×</button>\n </div>\n `,o.style.cssText="\n position: fixed;\n top: 20px;\n right: 20px;\n background: #f8fafc;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n padding: 12px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n z-index: 1000;\n max-width: 300px;\n font-size: 14px;\n ";const n=document.createElement("style");n.textContent="\n .offer-content {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n .offer-text {\n flex: 1;\n color: #4a5568;\n }\n .offer-button {\n background: #4299e1;\n color: white;\n border: none;\n border-radius: 4px;\n padding: 4px 8px;\n font-size: 12px;\n cursor: pointer;\n transition: background 0.2s;\n }\n .offer-button:hover {\n background: #3182ce;\n }\n .offer-close {\n background: none;\n border: none;\n color: #a0aec0;\n cursor: pointer;\n font-size: 16px;\n padding: 0;\n width: 20px;\n height: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .offer-close:hover {\n color: #718096;\n }\n ",document.head.appendChild(n),document.body.appendChild(o),setTimeout(()=>{o.parentElement&&o.remove()},5e3)}isTextFile(e){if(!e)return!1;const t=this.getFileExtension(e),o=["py","js","ts","jsx","tsx","html","css","json","md","txt","yml","yaml","xml","sql","sh","bash","dockerfile","makefile","gitignore","readme","cfg","conf","ini","toml","lock"];return o.includes(t)||o.includes(e.toLowerCase().split("/").pop())}getNodePath(e){const t=[];let o=e;for(;o;)o.data&&o.data.name&&t.unshift(o.data.name),o=o.parent;return t.join(" > ")}getFileExtension(e){if(!e)return"";const t=e.split(".");return t.length>1?t.pop().toLowerCase():""}getFileTypeDescription(e){if(!e)return"File";const t=this.getFileExtension(e),o=e.toLowerCase();if(o.endsWith("__init__.py"))return"Python package initialization";if("makefile"===o)return"Build configuration";if(o.includes("config")||o.includes("settings"))return"Configuration file";if(o.includes("test")||o.includes("spec"))return"Test file";return{py:"Python file",js:"JavaScript file",ts:"TypeScript file",jsx:"React component",tsx:"React TypeScript component",html:"HTML document",css:"Stylesheet",json:"JSON data",md:"Markdown document",txt:"Text file",yml:"YAML configuration",yaml:"YAML configuration",xml:"XML document",sql:"SQL script",sh:"Shell script",bash:"Bash script",toml:"TOML configuration",ini:"INI configuration"}[t]||"File"}getElementCounts(e){const t={classes:0,functions:0,methods:0,total:e.length};return e.forEach(e=>{"class"===e.type?(t.classes++,e.methods&&(t.methods+=e.methods.length)):"function"===e.type&&t.functions++}),t}formatElementSummary(e){const t=[];return e.classes>0&&t.push(`${e.classes} class${1!==e.classes?"es":""}`),e.functions>0&&t.push(`${e.functions} function${1!==e.functions?"s":""}`),e.methods>0&&t.push(`${e.methods} method${1!==e.methods?"s":""}`),0===t.length?"Structural elements for tree view":1===t.length?t[0]+" found":2===t.length?t.join(" and ")+" found":t.slice(0,-1).join(", ")+", and "+t[t.length-1]+" found"}getFileIcon(e){if(!e)return"📄";const t={py:"🐍",js:"📜",ts:"📘",jsx:"⚛️",tsx:"⚛️",html:"🌐",css:"🎨",json:"📋",md:"📝",txt:"📄",yml:"⚙️",yaml:"⚙️",xml:"📰",sql:"🗃️",sh:"🐚",bash:"🐚",dockerfile:"🐳",makefile:"🔨",gitignore:"🚫",readme:"📖"};return t[this.getFileExtension(e)]||t[e.toLowerCase().split("/").pop()]||"📄"}onSourceLineClick(e,t,o){console.log("🎯 [SOURCE LINE CLICK] Line clicked:",{line:e.dataset.lineNumber,astElements:t.length}),this.highlightSourceLine(e),t.length>0&&this.showASTElementDetails(t[0],o),e.classList.contains("collapsible")&&this.toggleSourceSection(e)}highlightSourceLine(e){if(this.currentSourceContainer){this.currentSourceContainer.querySelectorAll(".source-line").forEach(e=>e.classList.remove("highlighted"))}e.classList.add("highlighted")}showASTElementDetails(e,t){console.log("📋 [AST DETAILS] Showing details for:",e)}expandAllSource(){if(!this.currentSourceContainer)return;this.currentSourceContainer.querySelectorAll(".source-line.collapsible").forEach(e=>{e.querySelector(".collapse-indicator").classList.contains("collapsed")&&this.expandSourceSection(e)})}collapseAllSource(){if(!this.currentSourceContainer)return;this.currentSourceContainer.querySelectorAll(".source-line.collapsible").forEach(e=>{e.querySelector(".collapse-indicator").classList.contains("expanded")&&this.collapseSourceSection(e)})}}window.CodeTree=e,document.addEventListener("DOMContentLoaded",()=>{document.getElementById("code-tree-container")&&(window.codeTree=new e,window.debugCodeTree={clearLoadingState:()=>window.codeTree?.clearLoadingState(),showLoadingNodes:()=>(console.log("Current loading nodes:",Array.from(window.codeTree?.loadingNodes||[])),Array.from(window.codeTree?.loadingNodes||[])),resetTree:()=>{window.codeTree&&(window.codeTree.clearLoadingState(),window.codeTree.initializeTreeData(),console.log("Tree reset complete"))},focusOnPath:e=>{if(window.codeTree){const t=window.codeTree.findD3NodeByPath(e);t?(window.codeTree.focusOnDirectory(t),console.log("Focused on:",e)):console.log("Node not found:",e)}},unfocus:()=>window.codeTree?.unfocusDirectory()},document.addEventListener("click",e=>{e.target.matches('[data-tab="code"]')&&setTimeout(()=>{window.codeTree&&!window.codeTree.initialized?window.codeTree.initialize():window.codeTree&&window.codeTree.renderWhenVisible()},100)}))});
2
- //# sourceMappingURL=code-tree.js.map
@@ -1,2 +0,0 @@
1
- class e{constructor(){this.container=null,this.svg=null,this.initialized=!1,this.fileActivity=new Map,this.sessions=new Map,this.currentSession=null,this.treeData=null,this.d3Tree=null,this.d3Root=null,this.selectedNode=null,this.width=800,this.height=600,this.nodeRadius=5,this.renderInProgress=!1,this.containerObserver=null}initialize(){if(console.log("[CodeViewer] initialize() called"),this.initialized)console.log("[CodeViewer] Already initialized, skipping");else{console.log("[CodeViewer] Starting initialization...");try{this.setupContainer(),console.log("[CodeViewer] Container setup complete"),this.setupEventHandlers(),console.log("[CodeViewer] Event handlers setup complete"),this.subscribeToEvents(),console.log("[CodeViewer] Event subscription complete"),this.processExistingEvents(),console.log("[CodeViewer] Existing events processed"),this.initialized=!0,console.log("[CodeViewer] Initialization complete!")}catch(e){throw console.error("[CodeViewer] Error during initialization:",e),e}}}setupContainer(){const e=document.getElementById("claude-tree-container");e?(this.container=e,this.renderInterface()):console.error("File Tree container not found")}renderInterface(){if(!this.container)return void console.error("[CodeViewer] Container not found, cannot render interface");if(this.renderInProgress)return;const e=this.container.querySelector(".activity-tree-wrapper");this.container.querySelector(".file-tree-empty-state");const t=this.container.querySelector("#claude-activity-tree-svg");if(e&&t)return;this.renderInProgress=!0,this.containerObserver&&this.containerObserver.disconnect(),this.container.innerHTML="",this.container.innerHTML='\n <div class="activity-tree-wrapper" style="height: 100%; display: flex; flex-direction: column;">\n <div class="activity-controls" style="padding: 10px; border-bottom: 1px solid #ddd; background: #f9f9f9; display: flex; align-items: center; gap: 10px;">\n <button id="claude-expand-all-btn" class="control-btn" style="padding: 4px 8px; font-size: 0.9em;">Expand All</button>\n <button id="claude-collapse-all-btn" class="control-btn" style="padding: 4px 8px; font-size: 0.9em;">Collapse All</button>\n <button id="claude-reset-zoom-btn" class="control-btn" style="padding: 4px 8px; font-size: 0.9em;">Reset Zoom</button>\n <div class="stats" id="claude-tree-stats" style="margin-left: auto; font-size: 0.9em; color: #666;"></div>\n </div>\n <div class="tree-container" id="claude-tree-svg-container" style="flex: 1; overflow: hidden; position: relative; background: white;">\n <svg id="claude-activity-tree-svg" style="width: 100%; height: 100%;"></svg>\n </div>\n <div class="legend" style="padding: 5px 10px; border-top: 1px solid #ddd; background: #f9f9f9; font-size: 0.85em; display: flex; gap: 15px;">\n <span class="legend-item"><span style="color: #4CAF50;">●</span> File</span>\n <span class="legend-item"><span style="color: #2196F3;">●</span> Class</span>\n <span class="legend-item"><span style="color: #FF9800;">●</span> Function</span>\n <span class="legend-item"><span style="color: #9C27B0;">●</span> Method</span>\n <span class="legend-item"><span style="color: #F44336;">◆</span> Edited</span>\n <span class="legend-item"><span style="color: #4CAF50;">○</span> Viewed</span>\n </div>\n </div>\n ';const i=document.getElementById("claude-tree-svg-container");if(i){const e=i.getBoundingClientRect();this.width=e.width||800,this.height=e.height||600}this.renderInProgress=!1,this.containerObserver&&this.container&&this.containerObserver.observe(this.container,{childList:!0,subtree:!1})}renderContent(){this._showInternal()}show(){this._showInternal()}_showInternal(){console.log("[CodeViewer] _showInternal() called");const e=document.getElementById("claude-tree-container");if(!e)return void console.error("[CodeViewer] File Tree container not found!");console.log("[CodeViewer] Found container, current HTML length:",e.innerHTML.length),console.log("[CodeViewer] Container children:",e.children.length),this.refreshFromFileToolTracker();let t=!1;if(["#events-list",".events-list",".event-item",".no-events",'[id*="event"]','[class*="event"]'].forEach(i=>{const s=e.querySelectorAll(i);s.length>0&&(console.warn(`[CodeViewer] Found ${s.length} foreign elements matching '${i}', removing...`),s.forEach(e=>e.remove()),t=!0)}),t&&(console.warn("[CodeViewer] Foreign content removed, clearing container completely for fresh start"),e.innerHTML=""),e.setAttribute("data-owner","code-viewer"),e.setAttribute("data-tab-reserved","claude-tree"),e.setAttribute("data-component","CodeViewer"),this.container&&this.container===e||(this.container=e),this.initialized){const e=this.container.querySelector(".activity-tree-wrapper"),t=this.container.querySelector(".file-tree-empty-state");e||t||this.renderInterface()}else this.initialize();this.containerObserver||this.protectContainer(),this.setupControlHandlers();const i=document.getElementById("session-select");i&&(this.currentSession=i.value||null),this.buildTreeData(),this.renderTree(),this.updateStats()}protectContainer(){const e=document.getElementById("claude-tree-container");if(!e)return;this.containerObserver&&this.containerObserver.disconnect();let t=!1;this.containerObserver=new MutationObserver(i=>{for(const n of i){for(const i of n.addedNodes)if(i.nodeType===Node.ELEMENT_NODE){const n=i;if(n.classList?.contains("event-item")||n.classList?.contains("events-list")||n.classList?.contains("no-events")||"events-list"===n.id||"agents-list"===n.id||"tools-list"===n.id||"files-list"===n.id||n.textContent&&(n.textContent.includes("[hook]")||n.textContent.includes("hook.user_prompt")||n.textContent.includes("hook.pre_tool")||n.textContent.includes("hook.post_tool")||n.textContent.includes("Connect to Socket.IO")||n.textContent.includes("No events")||n.textContent.includes("No agent events")||n.textContent.includes("No tool events")||n.textContent.includes("No file operations"))||"DIV"===n.tagName&&!n.classList?.contains("activity-tree-wrapper")&&!n.classList?.contains("file-tree-empty-state")&&!n.classList?.contains("activity-controls")&&!n.classList?.contains("tree-container")&&!n.classList?.contains("legend")&&!n.classList?.contains("stats")&&!n.id?.startsWith("claude-")){try{i.remove()}catch(s){console.warn("[CodeViewer] Failed to remove unwanted node:",s)}t||this.renderInProgress||(t=!0,setTimeout(()=>{t=!1,e.querySelector(".activity-tree-wrapper")||e.querySelector(".file-tree-empty-state")||(this.renderInterface(),this.setupControlHandlers(),this.buildTreeData(),this.renderTree())},50))}}if("childList"===n.type&&n.removedNodes.length>0)for(const e of n.removedNodes)if(e.nodeType===Node.ELEMENT_NODE){const i=e;(i.classList?.contains("activity-tree-wrapper")||i.classList?.contains("file-tree-empty-state"))&&(t||this.renderInProgress||(t=!0,setTimeout(()=>{t=!1,this.renderInterface(),this.setupControlHandlers(),this.buildTreeData(),this.renderTree()},50)))}}}),this.containerObserver.observe(e,{childList:!0,subtree:!1})}setupControlHandlers(){const e=document.getElementById("session-select");e&&!e.hasAttribute("data-tree-listener")&&(e.setAttribute("data-tree-listener","true"),e.addEventListener("change",e=>{this.currentSession=e.target.value||null,this.isTabActive()&&(this.buildTreeData(),this.renderTree(),this.updateStats())}));const t=document.getElementById("claude-expand-all-btn");t&&!t.hasAttribute("data-listener")&&(t.setAttribute("data-listener","true"),t.addEventListener("click",()=>{this.expandAllNodes()}));const i=document.getElementById("claude-collapse-all-btn");i&&!i.hasAttribute("data-listener")&&(i.setAttribute("data-listener","true"),i.addEventListener("click",()=>{this.collapseAllNodes()}));const s=document.getElementById("claude-reset-zoom-btn");s&&!s.hasAttribute("data-listener")&&(s.setAttribute("data-listener","true"),s.addEventListener("click",()=>{this.resetZoom()}))}setupEventHandlers(){}subscribeToEvents(){window.socket&&(window.socket.on("claude_event",e=>{(this.isFileOperationEvent(e)||this.isDirectFileEvent(e))&&setTimeout(()=>{this.refreshFromFileToolTracker(),this.isTabActive()&&(this.buildTreeData(),this.renderTree(),this.updateStats())},100)}),window.socket.on("file:read",e=>{this.handleDirectFileEvent("Read",e)}),window.socket.on("file:write",e=>{this.handleDirectFileEvent("Write",e)}),window.socket.on("file:edit",e=>{this.handleDirectFileEvent("Edit",e)})),window.eventBus&&window.eventBus.on("claude_event",e=>{(this.isFileOperationEvent(e)||this.isDirectFileEvent(e))&&(this.processClaudeEvent(e),this.isTabActive()&&(this.buildTreeData(),this.renderTree(),this.updateStats()))})}isTabActive(){const e=document.getElementById("claude-tree-tab");return e&&e.classList.contains("active")}processExistingEvents(){if(console.log("[CodeViewer] processExistingEvents called"),window.dashboard&&window.dashboard.fileToolTracker)this.refreshFromFileToolTracker();else if(window.dashboard&&window.dashboard.eventStore){const e=window.dashboard.eventStore.getAllEvents();console.log("[CodeViewer] Fallback to eventStore, total events:",e.length);let t=0,i=0;e.forEach(e=>{"hook"===e.type&&console.log("[CodeViewer] Hook event:",{subtype:e.subtype,tool_name:e.data?.tool_name,timestamp:e.timestamp}),this.isFileOperationEvent(e)&&(t++,console.log("[CodeViewer] Found file operation event:",e),this.processClaudeEvent(e),i++)}),console.log("[CodeViewer] processExistingEvents summary:",{totalEvents:e.length,fileOperations:t,processed:i,currentFileActivitySize:this.fileActivity.size})}else console.log("[CodeViewer] No dashboard or eventStore available")}isFileOperationEvent(e){if("hook"===e.type&&("pre_tool"===e.subtype||"post_tool"===e.subtype)&&e.data&&e.data.tool_name){return["Read","Write","Edit","MultiEdit","NotebookEdit"].includes(e.data.tool_name)}return!1}isDirectFileEvent(e){return!!("file_operation"===e.type||e.tool&&["Read","Write","Edit","MultiEdit","NotebookEdit"].includes(e.tool))}handleDirectFileEvent(e,t){const i={type:"file_operation",tool:e,data:{tool_name:e,tool_parameters:t.parameters||t,tool_output:t.output||null,session_id:t.session_id||this.currentSession,working_directory:t.working_directory||"/"},timestamp:t.timestamp||(new Date).toISOString()};this.processClaudeEvent(i),this.isTabActive()&&(this.buildTreeData(),this.renderTree(),this.updateStats())}isFileOperation(e){return["Read","Write","Edit","MultiEdit","NotebookEdit"].includes(e.tool_name)}processClaudeEvent(e){if(!this.isFileOperationEvent(e)&&!this.isDirectFileEvent(e))return;let t,i,s,n,o,r,a;if(this.isFileOperationEvent(e)){const a=e.data||{};t=a.tool_name,i=a.tool_parameters||{},s=a.tool_output,n=e.timestamp||(new Date).toISOString(),o=e.session_id||a.session_id,r=a.working_directory||"/"}else if(this.isDirectFileEvent(e)){const a=e.data||e;t=e.tool||a.tool_name,i=a.tool_parameters||a.parameters||{},s=a.tool_output||a.output,n=e.timestamp||a.timestamp||(new Date).toISOString(),o=e.session_id||a.session_id,r=a.working_directory||"/"}a=i.file_path||i.notebook_path,this.processFileOperation({tool_name:t,tool_parameters:i,tool_output:s,timestamp:n,session_id:o,working_directory:r,filePath:a})}processEvent(e){if(!this.isFileOperation(e))return;const{tool_name:t,tool_parameters:i,tool_output:s,timestamp:n,session_id:o,working_directory:r}=e,a=i?.file_path||i?.notebook_path;this.processFileOperation({tool_name:t,tool_parameters:i,tool_output:s,timestamp:n,session_id:o,working_directory:r,filePath:a})}processFileOperation({tool_name:e,tool_parameters:t,tool_output:i,timestamp:s,session_id:n,working_directory:o,filePath:r}){if(!r)return;n&&!this.sessions.has(n)&&(this.sessions.set(n,{id:n,working_directory:o||"/",files:new Set}),this.updateSessionList()),this.fileActivity.has(r)||this.fileActivity.set(r,{path:r,operations:[],sessions:new Set,working_directories:new Set,lastContent:null,astPaths:[]});const a=this.fileActivity.get(r);if(a.operations.push({type:e,timestamp:s,parameters:t,output:i,session_id:n}),n){a.sessions.add(n);const e=this.sessions.get(n);e&&e.files.add(r)}if(o&&a.working_directories.add(o),"Write"===e&&t.content)a.lastContent=t.content,a.astPaths=this.extractASTPaths(t.content,r);else if("Read"===e&&i?.content)a.lastContent=i.content,a.astPaths=this.extractASTPaths(i.content,r);else if("Edit"===e&&a.lastContent){const e=t.old_string,i=t.new_string;e&&i&&(a.lastContent=a.lastContent.replace(e,i),a.astPaths=this.extractASTPaths(a.lastContent,r))}}extractASTPaths(e,t){if(!e||"string"!=typeof e)return[];const i=t.split(".").pop()?.toLowerCase(),s=[];if("py"===i){const t=/^class\s+(\w+)/gm,i=/^def\s+(\w+)/gm,n=/^\s{4,}def\s+(\w+)/gm;let o;for(;null!==(o=t.exec(e));)s.push({name:o[1],type:"class"});for(;null!==(o=i.exec(e));)s.push({name:o[1],type:"function"});for(;null!==(o=n.exec(e));)s.some(e=>e.name===o[1])||s.push({name:o[1],type:"method"})}else if("js"===i||"jsx"===i||"ts"===i||"tsx"===i){const t=/class\s+(\w+)/g,i=/function\s+(\w+)/g,n=/const\s+(\w+)\s*=\s*\([^)]*\)\s*=>/g;let o;for(;null!==(o=t.exec(e));)s.push({name:o[1],type:"class"});for(;null!==(o=i.exec(e));)s.push({name:o[1],type:"function"});for(;null!==(o=n.exec(e));)s.push({name:o[1],type:"function"})}return s}buildTreeData(){const e={name:`Session: ${(this.currentSession||"current-session").substring(0,8)+"..."}`,type:"root",children:[]};if(!this.fileActivity||0===this.fileActivity.size)return e.children.push({name:"(No file operations yet)",type:"placeholder",children:[]}),this.treeData=e,void console.log("[CodeViewer] Built minimal tree with session root");const t=new Map;for(const[i,s]of this.fileActivity.entries()){if(this.currentSession&&!s.sessions.has(this.currentSession))continue;const e=Array.from(s.working_directories)[0]||"/";t.has(e)||t.set(e,{name:e.split("/").pop()||e,path:e,type:"directory",children:[]});const n=i.split("/").pop(),o=s.operations.some(e=>"Edit"===e.type||"Write"===e.type),r={name:n,path:i,type:"file",edited:o,operations:s.operations.length,children:[]};s.astPaths.length>0&&s.astPaths.forEach(e=>{r.children.push({name:e.name,type:e.type,path:`${i}#${e.name}`,children:[]})}),t.get(e).children.push(r)}e.children=Array.from(t.values()),1===e.children.length&&"/"===e.children[0].path&&(e.children=e.children[0].children),this.treeData=e}renderTree(){if(!this.treeData||!this.container)return;const e=document.getElementById("claude-activity-tree-svg");if(!e)return void console.warn("[CodeViewer] SVG element not found, skipping tree render");const t=d3.select(e);if(t.empty())return void console.warn("[CodeViewer] D3 could not select SVG element");t.selectAll("*").remove();const i=document.getElementById("claude-tree-svg-container");if(i){const e=i.getBoundingClientRect();this.width=e.width||800,this.height=e.height||600}const s=t.append("g"),n=d3.zoom().scaleExtent([.1,4]).on("zoom",e=>{s.attr("transform",e.transform)});t.call(n);const o=d3.tree().size([this.height-100,this.width-200]);this.d3Root=d3.hierarchy(this.treeData),o(this.d3Root),s.selectAll(".link").data(this.d3Root.links()).enter().append("path").attr("class","link").attr("d",d3.linkHorizontal().x(e=>e.y+100).y(e=>e.x+50)).style("fill","none").style("stroke","#ccc").style("stroke-width",1);const r=s.selectAll(".node").data(this.d3Root.descendants()).enter().append("g").attr("class","node").attr("transform",e=>`translate(${e.y+100},${e.x+50})`);r.append("circle").attr("r",this.nodeRadius).style("fill",e=>this.getNodeColor(e.data)).style("stroke",e=>e.data.edited?"#F44336":"#999").style("stroke-width",e=>e.data.edited?2:1).style("cursor","pointer").on("click",(e,t)=>this.handleNodeClick(e,t)),r.append("text").attr("dy",".35em").attr("x",e=>e.children?-10:10).style("text-anchor",e=>e.children?"end":"start").style("font-size","12px").style("cursor","pointer").text(e=>e.data.name).on("click",(e,t)=>this.handleNodeClick(e,t)),this.d3Tree={svg:t,g:s,zoom:n}}getNodeColor(e){switch(e.type){case"root":return"#666";case"directory":return"#FFC107";case"file":return"#4CAF50";case"class":return"#2196F3";case"function":return"#FF9800";case"method":return"#9C27B0";default:return"#999"}}handleNodeClick(e,t){e.stopPropagation(),t.children?(t._children=t.children,t.children=null):t._children&&(t.children=t._children,t._children=null),this.renderTree(),this.selectedNode=t,"file"===t.data.type&&this.fileActivity.has(t.data.path)&&this.showFileDetails(t.data.path)}showFileDetails(e){const t=this.fileActivity.get(e);if(!t)return;const i=document.getElementById("module-data-content");if(!i)return;const s=document.querySelector(".module-data-header h5");s&&(s.innerHTML=`📄 ${e.split("/").pop()}`);let n='<div style="padding: 10px; overflow-y: auto; height: 100%;">';n+='<div style="margin-bottom: 15px;">',n+=`<strong>File Path:</strong> ${e}<br>`,n+=`<strong>Operations:</strong> ${t.operations.length}<br>`,n+=`<strong>Sessions:</strong> ${t.sessions.size}`,n+="</div>",n+='<div style="margin-bottom: 15px;"><strong>Operations Timeline:</strong></div>',t.operations.forEach((e,t)=>{const i=new Date(e.timestamp).toLocaleTimeString();n+=`<div style="margin-bottom: 10px; padding: 8px; background: #f5f5f5; border-left: 3px solid ${this.getOperationColor(e.type)};">`,n+=`<div><strong>${e.type}</strong> at ${i}</div>`,"Edit"===e.type&&e.parameters&&(n+='<div style="margin-top: 5px; font-size: 0.9em;">',n+=`<div style="color: #d32f2f;">- ${this.escapeHtml(e.parameters.old_string||"").substring(0,100)}</div>`,n+=`<div style="color: #388e3c;">+ ${this.escapeHtml(e.parameters.new_string||"").substring(0,100)}</div>`,n+="</div>"),n+="</div>"}),t.astPaths.length>0&&(n+='<div style="margin-top: 15px;"><strong>AST Structure:</strong></div>',n+='<ul style="list-style: none; padding-left: 10px;">',t.astPaths.forEach(e=>{const t="class"===e.type?"🔷":"function"===e.type?"🔶":"🔸";n+=`<li>${t} ${e.name} (${e.type})</li>`}),n+="</ul>"),n+="</div>",i.innerHTML=n}getOperationColor(e){switch(e){case"Write":return"#4CAF50";case"Edit":return"#FF9800";case"Read":return"#2196F3";default:return"#999"}}escapeHtml(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}expandAllNodes(){this.d3Root&&(this.d3Root.descendants().forEach(e=>{e._children&&(e.children=e._children,e._children=null)}),this.renderTree())}collapseAllNodes(){this.d3Root&&(this.d3Root.descendants().forEach(e=>{e.children&&e.depth>0&&(e._children=e.children,e.children=null)}),this.renderTree())}resetZoom(){this.d3Tree&&this.d3Tree.svg.transition().duration(750).call(this.d3Tree.zoom.transform,d3.zoomIdentity)}updateSessionList(){const e=document.getElementById("session-select");if(!e)return;const t=e.value;for(;e.options.length>1;)e.remove(1);for(const[i,s]of this.sessions.entries()){let t=!1;for(let s=0;s<e.options.length;s++)if(e.options[s].value===i){t=!0;break}if(!t){const t=document.createElement("option");t.value=i,t.textContent=`Session ${i.substring(0,8)}... (${s.files.size} files)`,e.appendChild(t)}}t&&(e.value=t)}updateStats(){const e=document.getElementById("claude-tree-stats");if(!e)return;const t=this.currentSession?Array.from(this.fileActivity.values()).filter(e=>e.sessions.has(this.currentSession)).length:this.fileActivity.size,i=this.currentSession?Array.from(this.fileActivity.values()).filter(e=>e.sessions.has(this.currentSession)).reduce((e,t)=>e+t.operations.length,0):Array.from(this.fileActivity.values()).reduce((e,t)=>e+t.operations.length,0);e.textContent=`Files: ${t} | Operations: ${i} | Sessions: ${this.sessions.size}`}refreshFromFileToolTracker(){if(!window.dashboard||!window.dashboard.fileToolTracker)return void console.log("[CodeViewer] FileToolTracker not available");const e=window.dashboard.fileToolTracker.getFileOperations();console.log("[CodeViewer] Refreshing from FileToolTracker:",e.size,"files"),this.fileActivity.clear(),this.sessions.clear();const t="current-session";this.sessions.set(t,{id:t,startTime:(new Date).toISOString(),files:new Set}),this.currentSession=t,e.forEach((e,i)=>{this.sessions.get(t).files.add(i);const s=e.operations[0];e.operations[e.operations.length-1],this.fileActivity.set(i,{path:i,firstAccess:s?s.timestamp:e.lastOperation,lastAccess:e.lastOperation,accessCount:e.operations.length,operations:e.operations.map(e=>({type:e.operation,timestamp:e.timestamp,agent:e.agent})),workingDirectory:s?s.workingDirectory:null,astNodes:[],content:null})}),console.log("[CodeViewer] File activity refreshed:",this.fileActivity.size,"files")}}try{window.CodeViewer=new e,console.log("[CodeViewer] Instance created successfully")}catch(t){console.error("[CodeViewer] FAILED TO CREATE INSTANCE:",t)}if("loading"===document.readyState)document.addEventListener("DOMContentLoaded",()=>{console.log("[CodeViewer] DOMContentLoaded - attempting initialization");try{window.CodeViewer.initialize();const e=document.getElementById("claude-tree-tab");e&&e.classList.contains("active")&&setTimeout(()=>window.CodeViewer.show(),100)}catch(t){console.error("[CodeViewer] FAILED TO INITIALIZE:",t)}});else{console.log("[CodeViewer] DOM already loaded - initializing immediately");try{window.CodeViewer.initialize();const e=document.getElementById("claude-tree-tab");e&&e.classList.contains("active")&&(console.log("[CodeViewer] File Tree tab is active, showing in 100ms"),setTimeout(()=>window.CodeViewer.show(),100))}catch(t){console.error("[CodeViewer] FAILED TO INITIALIZE:",t)}}document.addEventListener("tabChanged",e=>{e.detail&&"claude-tree"===e.detail.newTab&&setTimeout(()=>window.CodeViewer.show(),50)}),setInterval(()=>{const e=document.getElementById("claude-tree-tab"),t=document.getElementById("claude-tree-container");e&&e.classList.contains("active")&&t&&!t.querySelector(".activity-tree-wrapper")&&!t.querySelector(".file-tree-empty-state")&&window.CodeViewer.show()},5e3);
2
- //# sourceMappingURL=code-viewer.js.map