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.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/BASE_PM.md +12 -0
- claude_mpm/agents/OUTPUT_STYLE.md +3 -48
- claude_mpm/agents/PM_INSTRUCTIONS.md +632 -334
- claude_mpm/agents/WORKFLOW.md +75 -2
- claude_mpm/agents/__init__.py +6 -0
- claude_mpm/agents/agent_loader.py +1 -4
- claude_mpm/agents/base_agent.json +6 -3
- claude_mpm/agents/frontmatter_validator.py +1 -1
- claude_mpm/agents/templates/{circuit_breakers.md → circuit-breakers.md} +370 -3
- claude_mpm/agents/templates/context-management-examples.md +544 -0
- claude_mpm/agents/templates/{pm_red_flags.md → pm-red-flags.md} +89 -19
- claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
- claude_mpm/agents/templates/research-gate-examples.md +669 -0
- claude_mpm/agents/templates/structured-questions-examples.md +615 -0
- claude_mpm/agents/templates/ticket-completeness-examples.md +139 -0
- claude_mpm/agents/templates/ticketing-examples.md +277 -0
- claude_mpm/cli/__init__.py +38 -2
- claude_mpm/cli/commands/agent_source.py +774 -0
- claude_mpm/cli/commands/agent_state_manager.py +125 -20
- claude_mpm/cli/commands/agents.py +684 -13
- claude_mpm/cli/commands/agents_cleanup.py +210 -0
- claude_mpm/cli/commands/agents_discover.py +338 -0
- claude_mpm/cli/commands/aggregate.py +1 -1
- claude_mpm/cli/commands/analyze.py +3 -3
- claude_mpm/cli/commands/auto_configure.py +2 -6
- claude_mpm/cli/commands/cleanup.py +1 -1
- claude_mpm/cli/commands/config.py +7 -4
- claude_mpm/cli/commands/configure.py +478 -44
- claude_mpm/cli/commands/configure_agent_display.py +4 -4
- claude_mpm/cli/commands/configure_navigation.py +63 -46
- claude_mpm/cli/commands/debug.py +12 -12
- claude_mpm/cli/commands/doctor.py +10 -2
- claude_mpm/cli/commands/hook_errors.py +277 -0
- claude_mpm/cli/commands/local_deploy.py +1 -4
- claude_mpm/cli/commands/mcp_install_commands.py +1 -1
- claude_mpm/cli/commands/mpm_init/core.py +50 -2
- claude_mpm/cli/commands/mpm_init/git_activity.py +10 -10
- claude_mpm/cli/commands/mpm_init/prompts.py +6 -6
- claude_mpm/cli/commands/run.py +124 -128
- claude_mpm/cli/commands/skill_source.py +694 -0
- claude_mpm/cli/commands/skills.py +435 -1
- claude_mpm/cli/executor.py +78 -3
- claude_mpm/cli/interactive/agent_wizard.py +919 -41
- claude_mpm/cli/parsers/agent_source_parser.py +171 -0
- claude_mpm/cli/parsers/agents_parser.py +173 -4
- claude_mpm/cli/parsers/base_parser.py +49 -0
- claude_mpm/cli/parsers/config_parser.py +96 -43
- claude_mpm/cli/parsers/skill_source_parser.py +169 -0
- claude_mpm/cli/parsers/skills_parser.py +138 -0
- claude_mpm/cli/parsers/source_parser.py +138 -0
- claude_mpm/cli/startup.py +499 -84
- claude_mpm/cli/startup_display.py +480 -0
- claude_mpm/cli/utils.py +1 -1
- claude_mpm/cli_module/commands.py +1 -1
- claude_mpm/commands/{mpm-auto-configure.md → mpm-agents-auto-configure.md} +9 -0
- claude_mpm/commands/mpm-agents-detect.md +9 -0
- claude_mpm/commands/{mpm-agents.md → mpm-agents-list.md} +9 -0
- claude_mpm/commands/mpm-agents-recommend.md +9 -0
- claude_mpm/commands/{mpm-config.md → mpm-config-view.md} +9 -0
- claude_mpm/commands/mpm-doctor.md +9 -0
- claude_mpm/commands/mpm-help.md +11 -2
- claude_mpm/commands/mpm-init.md +27 -2
- claude_mpm/commands/mpm-monitor.md +9 -0
- claude_mpm/commands/{mpm-resume.md → mpm-session-resume.md} +9 -0
- claude_mpm/commands/mpm-status.md +9 -0
- claude_mpm/commands/{mpm-organize.md → mpm-ticket-organize.md} +9 -0
- claude_mpm/commands/mpm-ticket-view.md +552 -0
- claude_mpm/commands/mpm-version.md +9 -0
- claude_mpm/commands/mpm.md +10 -0
- claude_mpm/config/agent_presets.py +258 -0
- claude_mpm/config/agent_sources.py +325 -0
- claude_mpm/config/skill_sources.py +590 -0
- claude_mpm/constants.py +12 -0
- claude_mpm/core/api_validator.py +1 -1
- claude_mpm/core/claude_runner.py +17 -10
- claude_mpm/core/config.py +24 -0
- claude_mpm/core/constants.py +1 -1
- claude_mpm/core/framework/__init__.py +3 -16
- claude_mpm/core/framework/loaders/instruction_loader.py +25 -5
- claude_mpm/core/framework/processors/metadata_processor.py +1 -1
- claude_mpm/core/hook_error_memory.py +381 -0
- claude_mpm/core/hook_manager.py +41 -2
- claude_mpm/core/interactive_session.py +112 -5
- claude_mpm/core/logger.py +3 -1
- claude_mpm/core/oneshot_session.py +94 -4
- claude_mpm/dashboard/static/css/activity.css +69 -69
- claude_mpm/dashboard/static/css/connection-status.css +10 -10
- claude_mpm/dashboard/static/css/dashboard.css +15 -15
- claude_mpm/dashboard/static/js/components/activity-tree.js +178 -178
- claude_mpm/dashboard/static/js/components/agent-hierarchy.js +101 -101
- claude_mpm/dashboard/static/js/components/agent-inference.js +31 -31
- claude_mpm/dashboard/static/js/components/build-tracker.js +59 -59
- claude_mpm/dashboard/static/js/components/code-simple.js +107 -107
- claude_mpm/dashboard/static/js/components/connection-debug.js +101 -101
- claude_mpm/dashboard/static/js/components/diff-viewer.js +113 -113
- claude_mpm/dashboard/static/js/components/event-viewer.js +12 -12
- claude_mpm/dashboard/static/js/components/file-change-tracker.js +57 -57
- claude_mpm/dashboard/static/js/components/file-change-viewer.js +74 -74
- claude_mpm/dashboard/static/js/components/file-tool-tracker.js +6 -6
- claude_mpm/dashboard/static/js/components/file-viewer.js +42 -42
- claude_mpm/dashboard/static/js/components/module-viewer.js +27 -27
- claude_mpm/dashboard/static/js/components/session-manager.js +14 -14
- claude_mpm/dashboard/static/js/components/socket-manager.js +1 -1
- claude_mpm/dashboard/static/js/components/ui-state-manager.js +14 -14
- claude_mpm/dashboard/static/js/components/unified-data-viewer.js +110 -110
- claude_mpm/dashboard/static/js/components/working-directory.js +8 -8
- claude_mpm/dashboard/static/js/connection-manager.js +76 -76
- claude_mpm/dashboard/static/js/dashboard.js +76 -58
- claude_mpm/dashboard/static/js/extension-error-handler.js +22 -22
- claude_mpm/dashboard/static/js/socket-client.js +138 -121
- claude_mpm/dashboard/templates/code_simple.html +23 -23
- claude_mpm/dashboard/templates/index.html +18 -18
- claude_mpm/experimental/cli_enhancements.py +1 -5
- claude_mpm/hooks/claude_hooks/event_handlers.py +3 -1
- claude_mpm/hooks/claude_hooks/hook_handler.py +24 -7
- claude_mpm/hooks/claude_hooks/installer.py +45 -0
- claude_mpm/hooks/failure_learning/__init__.py +2 -8
- claude_mpm/hooks/failure_learning/failure_detection_hook.py +1 -6
- claude_mpm/hooks/failure_learning/fix_detection_hook.py +1 -6
- claude_mpm/hooks/failure_learning/learning_extraction_hook.py +1 -6
- claude_mpm/hooks/kuzu_response_hook.py +1 -5
- claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
- claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
- claude_mpm/models/git_repository.py +198 -0
- claude_mpm/scripts/claude-hook-handler.sh +3 -3
- claude_mpm/scripts/start_activity_logging.py +3 -1
- claude_mpm/services/agents/agent_builder.py +45 -9
- claude_mpm/services/agents/agent_preset_service.py +238 -0
- claude_mpm/services/agents/agent_selection_service.py +484 -0
- claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
- claude_mpm/services/agents/deployment/agent_deployment.py +126 -2
- claude_mpm/services/agents/deployment/agent_discovery_service.py +105 -73
- claude_mpm/services/agents/deployment/agent_format_converter.py +1 -1
- claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +1 -5
- claude_mpm/services/agents/deployment/agent_metrics_collector.py +3 -3
- claude_mpm/services/agents/deployment/agent_restore_handler.py +1 -4
- claude_mpm/services/agents/deployment/agent_template_builder.py +236 -15
- claude_mpm/services/agents/deployment/agents_directory_resolver.py +101 -15
- claude_mpm/services/agents/deployment/async_agent_deployment.py +2 -1
- claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -3
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +115 -15
- claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +2 -2
- claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +1 -4
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +363 -0
- claude_mpm/services/agents/deployment/single_agent_deployer.py +2 -2
- claude_mpm/services/agents/deployment/system_instructions_deployer.py +168 -46
- claude_mpm/services/agents/deployment/validation/deployment_validator.py +2 -2
- claude_mpm/services/agents/git_source_manager.py +629 -0
- claude_mpm/services/agents/loading/framework_agent_loader.py +9 -12
- claude_mpm/services/agents/local_template_manager.py +50 -10
- claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
- claude_mpm/services/agents/sources/__init__.py +13 -0
- claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
- claude_mpm/services/agents/sources/git_source_sync_service.py +1055 -0
- claude_mpm/services/agents/startup_sync.py +239 -0
- claude_mpm/services/agents/toolchain_detector.py +474 -0
- claude_mpm/services/cli/session_pause_manager.py +1 -1
- claude_mpm/services/cli/unified_dashboard_manager.py +1 -1
- claude_mpm/services/command_deployment_service.py +92 -1
- claude_mpm/services/core/interfaces/__init__.py +1 -3
- claude_mpm/services/core/interfaces/health.py +1 -4
- claude_mpm/services/core/models/__init__.py +2 -11
- claude_mpm/services/diagnostics/checks/__init__.py +4 -0
- claude_mpm/services/diagnostics/checks/agent_check.py +0 -2
- claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
- claude_mpm/services/diagnostics/checks/instructions_check.py +1 -2
- claude_mpm/services/diagnostics/checks/mcp_check.py +0 -1
- claude_mpm/services/diagnostics/checks/monitor_check.py +0 -1
- claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
- claude_mpm/services/diagnostics/diagnostic_runner.py +9 -0
- claude_mpm/services/diagnostics/doctor_reporter.py +40 -10
- claude_mpm/services/event_bus/direct_relay.py +3 -3
- claude_mpm/services/event_bus/event_bus.py +36 -3
- claude_mpm/services/events/consumers/logging.py +1 -2
- claude_mpm/services/git/__init__.py +21 -0
- claude_mpm/services/git/git_operations_service.py +494 -0
- claude_mpm/services/github/__init__.py +21 -0
- claude_mpm/services/github/github_cli_service.py +397 -0
- claude_mpm/services/infrastructure/monitoring/__init__.py +1 -5
- claude_mpm/services/infrastructure/monitoring/aggregator.py +1 -6
- claude_mpm/services/infrastructure/monitoring/resources.py +1 -1
- claude_mpm/services/instructions/__init__.py +9 -0
- claude_mpm/services/instructions/instruction_cache_service.py +374 -0
- claude_mpm/services/local_ops/__init__.py +3 -13
- claude_mpm/services/local_ops/health_checks/__init__.py +1 -3
- claude_mpm/services/local_ops/health_manager.py +1 -4
- claude_mpm/services/local_ops/process_manager.py +1 -1
- claude_mpm/services/local_ops/resource_monitor.py +2 -2
- claude_mpm/services/mcp_gateway/config/configuration.py +1 -1
- claude_mpm/services/mcp_gateway/server/mcp_gateway.py +1 -6
- claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -2
- claude_mpm/services/mcp_gateway/tools/document_summarizer.py +1 -1
- claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +6 -2
- claude_mpm/services/memory/optimizer.py +1 -1
- claude_mpm/services/model/model_router.py +8 -9
- claude_mpm/services/monitor/daemon.py +1 -1
- claude_mpm/services/monitor/server.py +2 -2
- claude_mpm/services/native_agent_converter.py +356 -0
- claude_mpm/services/port_manager.py +1 -1
- claude_mpm/services/pr/__init__.py +14 -0
- claude_mpm/services/pr/pr_template_service.py +329 -0
- claude_mpm/services/project/documentation_manager.py +2 -1
- claude_mpm/services/project/toolchain_analyzer.py +3 -1
- claude_mpm/services/runner_configuration_service.py +1 -0
- claude_mpm/services/self_upgrade_service.py +165 -7
- claude_mpm/services/skills/__init__.py +18 -0
- claude_mpm/services/skills/git_skill_source_manager.py +1169 -0
- claude_mpm/services/skills/skill_discovery_service.py +568 -0
- claude_mpm/services/skills_config.py +547 -0
- claude_mpm/services/skills_deployer.py +955 -0
- claude_mpm/services/socketio/handlers/connection.py +1 -1
- claude_mpm/services/socketio/handlers/git.py +2 -2
- claude_mpm/services/socketio/server/core.py +1 -4
- claude_mpm/services/socketio/server/main.py +1 -3
- claude_mpm/services/system_instructions_service.py +1 -3
- claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +0 -3
- claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +0 -1
- claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +1 -1
- claude_mpm/services/unified/deployment_strategies/vercel.py +1 -5
- claude_mpm/services/unified/unified_deployment.py +1 -5
- claude_mpm/services/version_control/conflict_resolution.py +6 -4
- claude_mpm/services/visualization/__init__.py +1 -5
- claude_mpm/services/visualization/mermaid_generator.py +2 -3
- claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
- claude_mpm/skills/bundled/performance-profiling.md +6 -0
- claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +2 -2
- claude_mpm/skills/skills_registry.py +0 -1
- claude_mpm/templates/questions/__init__.py +38 -0
- claude_mpm/templates/questions/base.py +193 -0
- claude_mpm/templates/questions/pr_strategy.py +311 -0
- claude_mpm/templates/questions/project_init.py +385 -0
- claude_mpm/templates/questions/ticket_mgmt.py +394 -0
- claude_mpm/tools/__main__.py +8 -8
- claude_mpm/tools/code_tree_analyzer/analysis.py +1 -1
- claude_mpm/utils/agent_dependency_loader.py +80 -13
- claude_mpm/utils/dependency_cache.py +3 -1
- claude_mpm/utils/gitignore.py +241 -0
- claude_mpm/utils/log_cleanup.py +3 -3
- claude_mpm/utils/progress.py +383 -0
- claude_mpm/utils/robust_installer.py +3 -5
- claude_mpm/utils/structured_questions.py +619 -0
- {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/METADATA +429 -59
- {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/RECORD +252 -425
- claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -17
- claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +0 -3
- claude_mpm/agents/templates/agent-manager.json +0 -273
- claude_mpm/agents/templates/agentic-coder-optimizer.json +0 -248
- claude_mpm/agents/templates/api_qa.json +0 -180
- claude_mpm/agents/templates/clerk-ops.json +0 -235
- claude_mpm/agents/templates/code_analyzer.json +0 -101
- claude_mpm/agents/templates/content-agent.json +0 -358
- claude_mpm/agents/templates/dart_engineer.json +0 -307
- claude_mpm/agents/templates/data_engineer.json +0 -225
- claude_mpm/agents/templates/documentation.json +0 -211
- claude_mpm/agents/templates/engineer.json +0 -210
- claude_mpm/agents/templates/gcp_ops_agent.json +0 -253
- claude_mpm/agents/templates/golang_engineer.json +0 -270
- claude_mpm/agents/templates/imagemagick.json +0 -264
- claude_mpm/agents/templates/java_engineer.json +0 -346
- claude_mpm/agents/templates/local_ops_agent.json +0 -1840
- claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +0 -39
- claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +0 -400
- claude_mpm/agents/templates/memory_manager.json +0 -158
- claude_mpm/agents/templates/nextjs_engineer.json +0 -285
- claude_mpm/agents/templates/ops.json +0 -185
- claude_mpm/agents/templates/php-engineer.json +0 -287
- claude_mpm/agents/templates/product_owner.json +0 -338
- claude_mpm/agents/templates/project_organizer.json +0 -140
- claude_mpm/agents/templates/prompt-engineer.json +0 -737
- claude_mpm/agents/templates/python_engineer.json +0 -387
- claude_mpm/agents/templates/qa.json +0 -242
- claude_mpm/agents/templates/react_engineer.json +0 -238
- claude_mpm/agents/templates/refactoring_engineer.json +0 -276
- claude_mpm/agents/templates/research.json +0 -188
- claude_mpm/agents/templates/ruby-engineer.json +0 -280
- claude_mpm/agents/templates/rust_engineer.json +0 -275
- claude_mpm/agents/templates/security.json +0 -202
- claude_mpm/agents/templates/svelte-engineer.json +0 -225
- claude_mpm/agents/templates/ticketing.json +0 -177
- claude_mpm/agents/templates/typescript_engineer.json +0 -285
- claude_mpm/agents/templates/vercel_ops_agent.json +0 -412
- claude_mpm/agents/templates/version_control.json +0 -157
- claude_mpm/agents/templates/web_qa.json +0 -399
- claude_mpm/agents/templates/web_ui.json +0 -189
- claude_mpm/commands/mpm-tickets.md +0 -102
- claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
- claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +0 -188
- claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +0 -156
- claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +0 -38
- claude_mpm/dashboard/react/components/shared/FilterBar.module.css +0 -92
- claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +0 -248
- claude_mpm/dashboard/static/archive/activity_dashboard_test.html +0 -61
- claude_mpm/dashboard/static/archive/test_activity_connection.html +0 -179
- claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +0 -68
- claude_mpm/dashboard/static/archive/test_dashboard.html +0 -409
- claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +0 -519
- claude_mpm/dashboard/static/archive/test_dashboard_verification.html +0 -181
- claude_mpm/dashboard/static/archive/test_file_data.html +0 -315
- claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +0 -243
- claude_mpm/dashboard/static/archive/test_file_tree_fix.html +0 -234
- claude_mpm/dashboard/static/archive/test_file_tree_rename.html +0 -117
- claude_mpm/dashboard/static/archive/test_file_tree_tab.html +0 -115
- claude_mpm/dashboard/static/archive/test_file_viewer.html +0 -224
- claude_mpm/dashboard/static/archive/test_final_activity.html +0 -220
- claude_mpm/dashboard/static/archive/test_tab_fix.html +0 -139
- claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +0 -1
- claude_mpm/dashboard/static/built/components/activity-tree.js +0 -2
- claude_mpm/dashboard/static/built/components/agent-hierarchy.js +0 -777
- claude_mpm/dashboard/static/built/components/agent-inference.js +0 -2
- claude_mpm/dashboard/static/built/components/build-tracker.js +0 -333
- claude_mpm/dashboard/static/built/components/code-simple.js +0 -857
- claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +0 -353
- claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +0 -235
- claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +0 -409
- claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +0 -435
- claude_mpm/dashboard/static/built/components/code-tree.js +0 -2
- claude_mpm/dashboard/static/built/components/code-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/connection-debug.js +0 -654
- claude_mpm/dashboard/static/built/components/diff-viewer.js +0 -891
- claude_mpm/dashboard/static/built/components/event-processor.js +0 -2
- claude_mpm/dashboard/static/built/components/event-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/export-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/file-change-tracker.js +0 -443
- claude_mpm/dashboard/static/built/components/file-change-viewer.js +0 -690
- claude_mpm/dashboard/static/built/components/file-tool-tracker.js +0 -2
- claude_mpm/dashboard/static/built/components/file-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/hud-library-loader.js +0 -2
- claude_mpm/dashboard/static/built/components/hud-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/hud-visualizer.js +0 -2
- claude_mpm/dashboard/static/built/components/module-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/nav-bar.js +0 -145
- claude_mpm/dashboard/static/built/components/page-structure.js +0 -429
- claude_mpm/dashboard/static/built/components/session-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/socket-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/ui-state-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/unified-data-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/working-directory.js +0 -2
- claude_mpm/dashboard/static/built/connection-manager.js +0 -536
- claude_mpm/dashboard/static/built/dashboard.js +0 -2
- claude_mpm/dashboard/static/built/extension-error-handler.js +0 -164
- claude_mpm/dashboard/static/built/react/events.js +0 -30
- claude_mpm/dashboard/static/built/shared/dom-helpers.js +0 -396
- claude_mpm/dashboard/static/built/shared/event-bus.js +0 -330
- claude_mpm/dashboard/static/built/shared/event-filter-service.js +0 -540
- claude_mpm/dashboard/static/built/shared/logger.js +0 -385
- claude_mpm/dashboard/static/built/shared/page-structure.js +0 -249
- claude_mpm/dashboard/static/built/shared/tooltip-service.js +0 -253
- claude_mpm/dashboard/static/built/socket-client.js +0 -2
- claude_mpm/dashboard/static/built/tab-isolation-fix.js +0 -185
- claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +0 -1
- claude_mpm/dashboard/static/dist/components/activity-tree.js +0 -2
- claude_mpm/dashboard/static/dist/components/agent-inference.js +0 -2
- claude_mpm/dashboard/static/dist/components/code-tree.js +0 -2
- claude_mpm/dashboard/static/dist/components/code-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/event-processor.js +0 -2
- claude_mpm/dashboard/static/dist/components/event-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/export-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +0 -2
- claude_mpm/dashboard/static/dist/components/file-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-library-loader.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-visualizer.js +0 -2
- claude_mpm/dashboard/static/dist/components/module-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/session-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/socket-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/ui-state-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/working-directory.js +0 -2
- claude_mpm/dashboard/static/dist/dashboard.js +0 -2
- claude_mpm/dashboard/static/dist/react/events.js +0 -30
- claude_mpm/dashboard/static/dist/socket-client.js +0 -2
- claude_mpm/dashboard/static/events.html +0 -607
- claude_mpm/dashboard/static/index.html +0 -635
- claude_mpm/dashboard/static/js/shared/dom-helpers.js +0 -396
- claude_mpm/dashboard/static/js/shared/event-bus.js +0 -330
- claude_mpm/dashboard/static/js/shared/logger.js +0 -385
- claude_mpm/dashboard/static/js/shared/tooltip-service.js +0 -253
- claude_mpm/dashboard/static/js/stores/dashboard-store.js +0 -562
- claude_mpm/dashboard/static/legacy/activity.html +0 -736
- claude_mpm/dashboard/static/legacy/agents.html +0 -786
- claude_mpm/dashboard/static/legacy/files.html +0 -747
- claude_mpm/dashboard/static/legacy/tools.html +0 -831
- claude_mpm/dashboard/static/monitors.html +0 -431
- claude_mpm/dashboard/static/production/events.html +0 -659
- claude_mpm/dashboard/static/production/main.html +0 -698
- claude_mpm/dashboard/static/production/monitors.html +0 -483
- claude_mpm/dashboard/static/test-archive/dashboard.html +0 -635
- claude_mpm/dashboard/static/test-archive/debug-events.html +0 -147
- claude_mpm/dashboard/static/test-archive/test-navigation.html +0 -256
- claude_mpm/dashboard/static/test-archive/test-react-exports.html +0 -180
- claude_mpm/dashboard/static/test-archive/test_debug.html +0 -25
- claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +0 -79
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +0 -178
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +0 -577
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +0 -467
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +0 -537
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +0 -730
- claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +0 -112
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +0 -146
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +0 -412
- claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +0 -81
- claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +0 -362
- claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +0 -312
- claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +0 -152
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +0 -668
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +0 -587
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +0 -438
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +0 -391
- claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +0 -119
- claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +0 -148
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +0 -483
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +0 -452
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +0 -449
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +0 -411
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +0 -14
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +0 -58
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +0 -68
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +0 -69
- claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +0 -131
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +0 -325
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +0 -490
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +0 -425
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +0 -499
- claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +0 -86
- claude_mpm/skills/bundled/main/internal-comms/SKILL.md +0 -43
- claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +0 -47
- claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +0 -65
- claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +0 -30
- claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +0 -16
- claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +0 -160
- claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +0 -412
- claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +0 -602
- claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +0 -915
- claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +0 -916
- claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +0 -752
- claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +0 -1237
- claude_mpm/skills/bundled/main/skill-creator/SKILL.md +0 -189
- claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +0 -500
- claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +0 -464
- claude_mpm/skills/bundled/main/skill-creator/references/examples.md +0 -619
- claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +0 -437
- claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +0 -231
- claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +0 -170
- claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +0 -602
- claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +0 -821
- claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +0 -742
- claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +0 -726
- claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +0 -764
- claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +0 -831
- claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +0 -226
- claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +0 -901
- claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +0 -901
- claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +0 -775
- claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +0 -937
- claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +0 -770
- claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +0 -961
- claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +0 -119
- claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +0 -253
- claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +0 -145
- claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +0 -543
- claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +0 -741
- claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +0 -470
- claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +0 -458
- claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +0 -639
- claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +0 -140
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +0 -572
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +0 -411
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +0 -569
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +0 -695
- claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +0 -184
- claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +0 -459
- claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +0 -479
- claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +0 -687
- claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +0 -758
- claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +0 -868
- /claude_mpm/agents/templates/{git_file_tracking.md → git-file-tracking.md} +0 -0
- /claude_mpm/agents/templates/{pm_examples.md → pm-examples.md} +0 -0
- /claude_mpm/agents/templates/{response_format.md → response-format.md} +0 -0
- /claude_mpm/agents/templates/{validation_templates.md → validation-templates.md} +0 -0
- {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/WHEEL +0 -0
- {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/licenses/LICENSE +0 -0
- {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,"&").replace(/</g,"<").replace(/>/g,">");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
|