claude-mpm 4.1.6__py3-none-any.whl โ 4.24.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of claude-mpm might be problematic. Click here for more details.
- claude_mpm/BUILD_NUMBER +1 -1
- claude_mpm/VERSION +1 -1
- claude_mpm/__init__.py +20 -5
- claude_mpm/agents/BASE_AGENT_TEMPLATE.md +118 -0
- claude_mpm/agents/BASE_DOCUMENTATION.md +53 -0
- claude_mpm/agents/BASE_ENGINEER.md +658 -0
- claude_mpm/agents/BASE_OPS.md +219 -0
- claude_mpm/agents/BASE_PM.md +431 -214
- claude_mpm/agents/BASE_PROMPT_ENGINEER.md +787 -0
- claude_mpm/agents/BASE_QA.md +167 -0
- claude_mpm/agents/BASE_RESEARCH.md +53 -0
- claude_mpm/agents/MEMORY.md +3 -0
- claude_mpm/agents/OUTPUT_STYLE.md +335 -0
- claude_mpm/agents/PM_INSTRUCTIONS.md +1159 -0
- claude_mpm/agents/WORKFLOW.md +355 -187
- claude_mpm/agents/agent_loader.py +40 -10
- claude_mpm/agents/agent_loader_integration.py +3 -2
- claude_mpm/agents/agents_metadata.py +57 -0
- claude_mpm/agents/async_agent_loader.py +3 -3
- claude_mpm/agents/base_agent_loader.py +11 -9
- claude_mpm/agents/frontmatter_validator.py +291 -251
- claude_mpm/agents/system_agent_config.py +3 -2
- claude_mpm/agents/templates/.claude-mpm/memories/README.md +17 -0
- claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +3 -0
- claude_mpm/agents/templates/README.md +465 -0
- claude_mpm/agents/templates/agent-manager.json +267 -18
- claude_mpm/agents/templates/agentic-coder-optimizer.json +248 -0
- claude_mpm/agents/templates/api_qa.json +16 -4
- claude_mpm/agents/templates/circuit_breakers.md +638 -0
- claude_mpm/agents/templates/clerk-ops.json +235 -0
- claude_mpm/agents/templates/code_analyzer.json +25 -9
- claude_mpm/agents/templates/content-agent.json +358 -0
- claude_mpm/agents/templates/dart_engineer.json +307 -0
- claude_mpm/agents/templates/data_engineer.json +87 -14
- claude_mpm/agents/templates/documentation.json +76 -13
- claude_mpm/agents/templates/engineer.json +44 -10
- claude_mpm/agents/templates/gcp_ops_agent.json +253 -0
- claude_mpm/agents/templates/git_file_tracking.md +584 -0
- claude_mpm/agents/templates/golang_engineer.json +270 -0
- claude_mpm/agents/templates/imagemagick.json +5 -2
- claude_mpm/agents/templates/java_engineer.json +346 -0
- claude_mpm/agents/templates/javascript_engineer_agent.json +380 -0
- claude_mpm/agents/templates/local_ops_agent.json +1840 -0
- claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +39 -0
- claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +400 -0
- claude_mpm/agents/templates/memory_manager.json +6 -3
- claude_mpm/agents/templates/nextjs_engineer.json +285 -0
- claude_mpm/agents/templates/ops.json +27 -8
- claude_mpm/agents/templates/php-engineer.json +287 -0
- claude_mpm/agents/templates/pm_examples.md +474 -0
- claude_mpm/agents/templates/pm_red_flags.md +262 -0
- claude_mpm/agents/templates/product_owner.json +338 -0
- claude_mpm/agents/templates/project_organizer.json +19 -5
- claude_mpm/agents/templates/prompt-engineer.json +737 -0
- claude_mpm/agents/templates/python_engineer.json +387 -0
- claude_mpm/agents/templates/qa.json +26 -6
- claude_mpm/agents/templates/react_engineer.json +239 -0
- claude_mpm/agents/templates/refactoring_engineer.json +15 -5
- claude_mpm/agents/templates/research.json +47 -22
- claude_mpm/agents/templates/response_format.md +583 -0
- claude_mpm/agents/templates/ruby-engineer.json +280 -0
- claude_mpm/agents/templates/rust_engineer.json +275 -0
- claude_mpm/agents/templates/security.json +59 -10
- claude_mpm/agents/templates/svelte-engineer.json +225 -0
- claude_mpm/agents/templates/tauri_engineer.json +274 -0
- claude_mpm/agents/templates/ticketing.json +16 -7
- claude_mpm/agents/templates/typescript_engineer.json +285 -0
- claude_mpm/agents/templates/validation_templates.md +312 -0
- claude_mpm/agents/templates/vercel_ops_agent.json +164 -33
- claude_mpm/agents/templates/version_control.json +16 -4
- claude_mpm/agents/templates/web_qa.json +243 -21
- claude_mpm/agents/templates/web_ui.json +18 -5
- claude_mpm/cli/__init__.py +38 -363
- claude_mpm/cli/commands/__init__.py +8 -0
- claude_mpm/cli/commands/agent_manager.py +675 -20
- claude_mpm/cli/commands/agent_state_manager.py +186 -0
- claude_mpm/cli/commands/agents.py +722 -150
- claude_mpm/cli/commands/agents_detect.py +380 -0
- claude_mpm/cli/commands/agents_recommend.py +309 -0
- claude_mpm/cli/commands/aggregate.py +10 -6
- claude_mpm/cli/commands/analyze.py +553 -0
- claude_mpm/cli/commands/analyze_code.py +528 -0
- claude_mpm/cli/commands/auto_configure.py +570 -0
- claude_mpm/cli/commands/cleanup.py +12 -12
- claude_mpm/cli/commands/config.py +47 -13
- claude_mpm/cli/commands/configure.py +488 -884
- claude_mpm/cli/commands/configure_agent_display.py +261 -0
- claude_mpm/cli/commands/configure_behavior_manager.py +204 -0
- claude_mpm/cli/commands/configure_hook_manager.py +225 -0
- claude_mpm/cli/commands/configure_models.py +18 -0
- claude_mpm/cli/commands/configure_navigation.py +167 -0
- claude_mpm/cli/commands/configure_paths.py +104 -0
- claude_mpm/cli/commands/configure_persistence.py +254 -0
- claude_mpm/cli/commands/configure_startup_manager.py +646 -0
- claude_mpm/cli/commands/configure_template_editor.py +497 -0
- claude_mpm/cli/commands/configure_validators.py +73 -0
- claude_mpm/cli/commands/dashboard.py +286 -0
- claude_mpm/cli/commands/debug.py +1386 -0
- claude_mpm/cli/commands/doctor.py +43 -7
- claude_mpm/cli/commands/info.py +3 -4
- claude_mpm/cli/commands/local_deploy.py +537 -0
- claude_mpm/cli/commands/mcp.py +17 -10
- claude_mpm/cli/commands/mcp_command_router.py +11 -0
- claude_mpm/cli/commands/mcp_config.py +154 -0
- claude_mpm/cli/commands/mcp_external_commands.py +249 -0
- claude_mpm/cli/commands/mcp_install_commands.py +101 -32
- claude_mpm/cli/commands/mcp_pipx_config.py +2 -2
- claude_mpm/cli/commands/mcp_setup_external.py +868 -0
- claude_mpm/cli/commands/memory.py +55 -21
- claude_mpm/cli/commands/monitor.py +168 -617
- claude_mpm/cli/commands/mpm_init/__init__.py +73 -0
- claude_mpm/cli/commands/mpm_init/core.py +525 -0
- claude_mpm/cli/commands/mpm_init/display.py +341 -0
- claude_mpm/cli/commands/mpm_init/git_activity.py +427 -0
- claude_mpm/cli/commands/mpm_init/modes.py +397 -0
- claude_mpm/cli/commands/mpm_init/prompts.py +442 -0
- claude_mpm/cli/commands/mpm_init_cli.py +396 -0
- claude_mpm/cli/commands/mpm_init_handler.py +195 -0
- claude_mpm/cli/commands/run.py +169 -42
- claude_mpm/cli/commands/search.py +458 -0
- claude_mpm/cli/commands/skills.py +488 -0
- claude_mpm/cli/commands/uninstall.py +176 -0
- claude_mpm/cli/commands/upgrade.py +152 -0
- claude_mpm/cli/commands/verify.py +119 -0
- claude_mpm/cli/executor.py +204 -0
- claude_mpm/cli/helpers.py +105 -0
- claude_mpm/cli/interactive/__init__.py +21 -0
- claude_mpm/cli/interactive/agent_wizard.py +962 -0
- claude_mpm/cli/interactive/skills_wizard.py +491 -0
- claude_mpm/cli/parser.py +79 -2
- claude_mpm/cli/parsers/__init__.py +7 -1
- claude_mpm/cli/parsers/agent_manager_parser.py +161 -1
- claude_mpm/cli/parsers/agents_parser.py +116 -0
- claude_mpm/cli/parsers/analyze_code_parser.py +170 -0
- claude_mpm/cli/parsers/analyze_parser.py +135 -0
- claude_mpm/cli/parsers/auto_configure_parser.py +245 -0
- claude_mpm/cli/parsers/base_parser.py +187 -3
- claude_mpm/cli/parsers/configure_parser.py +34 -15
- claude_mpm/cli/parsers/dashboard_parser.py +113 -0
- claude_mpm/cli/parsers/debug_parser.py +319 -0
- claude_mpm/cli/parsers/local_deploy_parser.py +227 -0
- claude_mpm/cli/parsers/mcp_parser.py +15 -0
- claude_mpm/cli/parsers/monitor_parser.py +12 -2
- claude_mpm/cli/parsers/mpm_init_parser.py +311 -0
- claude_mpm/cli/parsers/run_parser.py +5 -0
- claude_mpm/cli/parsers/search_parser.py +245 -0
- claude_mpm/cli/parsers/skills_parser.py +137 -0
- claude_mpm/cli/shared/argument_patterns.py +20 -13
- claude_mpm/cli/shared/base_command.py +2 -2
- claude_mpm/cli/shared/output_formatters.py +28 -19
- claude_mpm/cli/startup.py +562 -0
- claude_mpm/cli/startup_logging.py +179 -13
- claude_mpm/cli/utils.py +53 -2
- claude_mpm/commands/__init__.py +14 -0
- claude_mpm/commands/mpm-agents-detect.md +168 -0
- claude_mpm/commands/mpm-agents-recommend.md +214 -0
- claude_mpm/commands/mpm-agents.md +122 -0
- claude_mpm/commands/mpm-auto-configure.md +269 -0
- claude_mpm/commands/mpm-config.md +141 -0
- claude_mpm/commands/mpm-doctor.md +24 -0
- claude_mpm/commands/mpm-help.md +290 -0
- claude_mpm/commands/mpm-init.md +521 -0
- claude_mpm/commands/mpm-monitor.md +409 -0
- claude_mpm/commands/mpm-organize.md +295 -0
- claude_mpm/commands/mpm-resume.md +372 -0
- claude_mpm/commands/mpm-status.md +75 -0
- claude_mpm/commands/mpm-tickets.md +151 -0
- claude_mpm/commands/mpm-version.md +113 -0
- claude_mpm/commands/mpm.md +21 -0
- claude_mpm/config/agent_config.py +4 -4
- claude_mpm/config/experimental_features.py +7 -7
- claude_mpm/config/model_config.py +428 -0
- claude_mpm/config/paths.py +3 -2
- claude_mpm/config/socketio_config.py +36 -7
- claude_mpm/constants.py +27 -1
- claude_mpm/core/__init__.py +53 -17
- claude_mpm/core/agent_name_normalizer.py +3 -2
- claude_mpm/core/agent_registry.py +2 -2
- claude_mpm/core/agent_session_manager.py +10 -10
- claude_mpm/core/api_validator.py +330 -0
- claude_mpm/core/base_service.py +33 -23
- claude_mpm/core/cache.py +9 -9
- claude_mpm/core/claude_runner.py +19 -8
- claude_mpm/core/config.py +103 -8
- claude_mpm/core/config_aliases.py +7 -6
- claude_mpm/core/constants.py +65 -0
- claude_mpm/core/container.py +11 -5
- claude_mpm/core/enums.py +452 -0
- claude_mpm/core/error_handler.py +623 -0
- claude_mpm/core/factories.py +1 -1
- claude_mpm/core/file_utils.py +764 -0
- claude_mpm/core/framework/__init__.py +38 -0
- claude_mpm/core/framework/formatters/__init__.py +11 -0
- claude_mpm/core/framework/formatters/capability_generator.py +367 -0
- claude_mpm/core/framework/formatters/content_formatter.py +288 -0
- claude_mpm/core/framework/formatters/context_generator.py +185 -0
- claude_mpm/core/framework/loaders/__init__.py +13 -0
- claude_mpm/core/framework/loaders/agent_loader.py +210 -0
- claude_mpm/core/framework/loaders/file_loader.py +223 -0
- claude_mpm/core/framework/loaders/instruction_loader.py +161 -0
- claude_mpm/core/framework/loaders/packaged_loader.py +232 -0
- claude_mpm/core/framework/processors/__init__.py +11 -0
- claude_mpm/core/framework/processors/memory_processor.py +230 -0
- claude_mpm/core/framework/processors/metadata_processor.py +146 -0
- claude_mpm/core/framework/processors/template_processor.py +244 -0
- claude_mpm/core/framework_loader.py +323 -1491
- claude_mpm/core/hook_manager.py +8 -6
- claude_mpm/core/injectable_service.py +11 -8
- claude_mpm/core/instruction_reinforcement_hook.py +267 -0
- claude_mpm/core/interactive_session.py +55 -8
- claude_mpm/core/interfaces.py +56 -1
- claude_mpm/core/lazy.py +3 -3
- claude_mpm/core/log_manager.py +100 -28
- claude_mpm/core/logger.py +19 -14
- claude_mpm/core/logging_config.py +6 -2
- claude_mpm/core/logging_utils.py +520 -0
- claude_mpm/core/oneshot_session.py +51 -7
- claude_mpm/core/optimized_agent_loader.py +9 -9
- claude_mpm/core/optimized_startup.py +1 -1
- claude_mpm/core/output_style_manager.py +12 -192
- claude_mpm/core/pm_hook_interceptor.py +118 -15
- claude_mpm/core/service_registry.py +7 -3
- claude_mpm/core/session_manager.py +14 -12
- claude_mpm/core/shared/config_loader.py +1 -1
- claude_mpm/core/socketio_pool.py +15 -15
- claude_mpm/core/tool_access_control.py +3 -2
- claude_mpm/core/types.py +4 -11
- claude_mpm/core/typing_utils.py +7 -6
- claude_mpm/core/unified_agent_registry.py +116 -12
- claude_mpm/core/unified_config.py +6 -6
- claude_mpm/core/unified_paths.py +23 -20
- claude_mpm/dashboard/.claude-mpm/socketio-instances.json +1 -0
- claude_mpm/dashboard/__init__.py +12 -0
- claude_mpm/dashboard/analysis_runner.py +455 -0
- claude_mpm/dashboard/api/simple_directory.py +261 -0
- claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +188 -0
- claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +156 -0
- claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +38 -0
- claude_mpm/dashboard/react/components/shared/FilterBar.module.css +92 -0
- claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +248 -0
- claude_mpm/dashboard/static/archive/activity_dashboard_test.html +61 -0
- claude_mpm/dashboard/static/archive/test_activity_connection.html +179 -0
- claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +68 -0
- claude_mpm/dashboard/static/archive/test_dashboard.html +409 -0
- claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +519 -0
- claude_mpm/dashboard/static/archive/test_dashboard_verification.html +181 -0
- claude_mpm/dashboard/static/archive/test_file_data.html +315 -0
- claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +243 -0
- claude_mpm/dashboard/static/archive/test_file_tree_fix.html +234 -0
- claude_mpm/dashboard/static/archive/test_file_tree_rename.html +117 -0
- claude_mpm/dashboard/static/archive/test_file_tree_tab.html +115 -0
- claude_mpm/dashboard/static/archive/test_file_viewer.html +224 -0
- claude_mpm/dashboard/static/archive/test_final_activity.html +220 -0
- claude_mpm/dashboard/static/archive/test_tab_fix.html +139 -0
- claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +1 -0
- claude_mpm/dashboard/static/built/components/activity-tree.js +2 -0
- claude_mpm/dashboard/static/built/components/agent-hierarchy.js +777 -0
- claude_mpm/dashboard/static/built/components/agent-inference.js +1 -1
- claude_mpm/dashboard/static/built/components/build-tracker.js +333 -0
- claude_mpm/dashboard/static/built/components/code-simple.js +857 -0
- claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +353 -0
- claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +235 -0
- claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +409 -0
- claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +435 -0
- claude_mpm/dashboard/static/built/components/code-tree.js +2 -0
- claude_mpm/dashboard/static/built/components/code-viewer.js +2 -0
- claude_mpm/dashboard/static/built/components/connection-debug.js +654 -0
- claude_mpm/dashboard/static/built/components/diff-viewer.js +891 -0
- claude_mpm/dashboard/static/built/components/event-processor.js +1 -1
- claude_mpm/dashboard/static/built/components/event-viewer.js +1 -1
- claude_mpm/dashboard/static/built/components/export-manager.js +1 -1
- claude_mpm/dashboard/static/built/components/file-change-tracker.js +443 -0
- claude_mpm/dashboard/static/built/components/file-change-viewer.js +690 -0
- claude_mpm/dashboard/static/built/components/file-tool-tracker.js +1 -1
- claude_mpm/dashboard/static/built/components/file-viewer.js +2 -0
- claude_mpm/dashboard/static/built/components/module-viewer.js +1 -1
- claude_mpm/dashboard/static/built/components/nav-bar.js +145 -0
- claude_mpm/dashboard/static/built/components/page-structure.js +429 -0
- claude_mpm/dashboard/static/built/components/session-manager.js +1 -1
- claude_mpm/dashboard/static/built/components/unified-data-viewer.js +2 -0
- claude_mpm/dashboard/static/built/components/working-directory.js +1 -1
- claude_mpm/dashboard/static/built/connection-manager.js +536 -0
- claude_mpm/dashboard/static/built/dashboard.js +1 -1
- claude_mpm/dashboard/static/built/extension-error-handler.js +164 -0
- claude_mpm/dashboard/static/built/react/events.js +30 -0
- claude_mpm/dashboard/static/built/shared/dom-helpers.js +396 -0
- claude_mpm/dashboard/static/built/shared/event-bus.js +330 -0
- claude_mpm/dashboard/static/built/shared/event-filter-service.js +540 -0
- claude_mpm/dashboard/static/built/shared/logger.js +385 -0
- claude_mpm/dashboard/static/built/shared/page-structure.js +249 -0
- claude_mpm/dashboard/static/built/shared/tooltip-service.js +253 -0
- claude_mpm/dashboard/static/built/socket-client.js +1 -1
- claude_mpm/dashboard/static/built/tab-isolation-fix.js +185 -0
- claude_mpm/dashboard/static/css/activity.css +1958 -0
- claude_mpm/dashboard/static/css/dashboard.css +1413 -72
- claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +1 -0
- claude_mpm/dashboard/static/dist/components/activity-tree.js +2 -0
- claude_mpm/dashboard/static/dist/components/agent-inference.js +1 -1
- claude_mpm/dashboard/static/dist/components/code-tree.js +2 -0
- claude_mpm/dashboard/static/dist/components/code-viewer.js +2 -0
- claude_mpm/dashboard/static/dist/components/event-processor.js +1 -1
- claude_mpm/dashboard/static/dist/components/event-viewer.js +1 -1
- claude_mpm/dashboard/static/dist/components/export-manager.js +1 -1
- claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +1 -1
- claude_mpm/dashboard/static/dist/components/file-viewer.js +2 -0
- claude_mpm/dashboard/static/dist/components/module-viewer.js +1 -1
- claude_mpm/dashboard/static/dist/components/session-manager.js +1 -1
- claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +2 -0
- claude_mpm/dashboard/static/dist/components/working-directory.js +1 -1
- claude_mpm/dashboard/static/dist/dashboard.js +1 -1
- claude_mpm/dashboard/static/dist/react/events.js +30 -0
- claude_mpm/dashboard/static/dist/socket-client.js +1 -1
- claude_mpm/dashboard/static/events.html +607 -0
- claude_mpm/dashboard/static/index.html +635 -0
- claude_mpm/dashboard/static/js/components/activity-tree.js +1871 -0
- claude_mpm/dashboard/static/js/components/agent-hierarchy.js +4 -1
- claude_mpm/dashboard/static/js/components/agent-inference.js +3 -0
- claude_mpm/dashboard/static/js/components/build-tracker.js +23 -13
- claude_mpm/dashboard/static/js/components/code-simple.js +857 -0
- claude_mpm/dashboard/static/js/components/diff-viewer.js +891 -0
- claude_mpm/dashboard/static/js/components/event-processor.js +3 -107
- claude_mpm/dashboard/static/js/components/event-viewer.js +98 -11
- claude_mpm/dashboard/static/js/components/export-manager.js +3 -0
- claude_mpm/dashboard/static/js/components/file-change-tracker.js +443 -0
- claude_mpm/dashboard/static/js/components/file-change-viewer.js +690 -0
- claude_mpm/dashboard/static/js/components/file-tool-tracker.js +30 -10
- claude_mpm/dashboard/static/js/components/file-viewer.js +580 -0
- claude_mpm/dashboard/static/js/components/module-viewer.js +68 -205
- claude_mpm/dashboard/static/js/components/session-manager.js +46 -10
- claude_mpm/dashboard/static/js/components/socket-manager.js +16 -0
- claude_mpm/dashboard/static/js/components/ui-state-manager.js +359 -40
- claude_mpm/dashboard/static/js/components/unified-data-viewer.js +1824 -0
- claude_mpm/dashboard/static/js/components/working-directory.js +61 -10
- claude_mpm/dashboard/static/js/connection-manager.js +1 -1
- claude_mpm/dashboard/static/js/dashboard.js +523 -622
- claude_mpm/dashboard/static/js/shared/dom-helpers.js +396 -0
- claude_mpm/dashboard/static/js/shared/event-bus.js +330 -0
- claude_mpm/dashboard/static/js/shared/logger.js +385 -0
- claude_mpm/dashboard/static/js/shared/tooltip-service.js +253 -0
- claude_mpm/dashboard/static/js/socket-client.js +549 -62
- claude_mpm/dashboard/static/js/stores/dashboard-store.js +562 -0
- claude_mpm/dashboard/static/js/tab-isolation-fix.js +185 -0
- claude_mpm/dashboard/static/legacy/activity.html +736 -0
- claude_mpm/dashboard/static/legacy/agents.html +786 -0
- claude_mpm/dashboard/static/legacy/files.html +747 -0
- claude_mpm/dashboard/static/legacy/tools.html +831 -0
- claude_mpm/dashboard/static/monitors.html +431 -0
- claude_mpm/dashboard/static/production/events.html +659 -0
- claude_mpm/dashboard/static/production/main.html +698 -0
- claude_mpm/dashboard/static/production/monitors.html +483 -0
- claude_mpm/dashboard/static/socket.io.min.js +7 -0
- claude_mpm/dashboard/static/socket.io.v4.8.1.backup.js +7 -0
- claude_mpm/dashboard/static/test-archive/dashboard.html +635 -0
- claude_mpm/dashboard/static/test-archive/debug-events.html +147 -0
- claude_mpm/dashboard/static/test-archive/test-navigation.html +256 -0
- claude_mpm/dashboard/static/test-archive/test-react-exports.html +180 -0
- claude_mpm/dashboard/static/test-archive/test_debug.html +25 -0
- claude_mpm/dashboard/templates/code_simple.html +153 -0
- claude_mpm/dashboard/templates/index.html +267 -9
- claude_mpm/experimental/__init__.py +10 -0
- claude_mpm/experimental/cli_enhancements.py +4 -2
- claude_mpm/generators/agent_profile_generator.py +5 -3
- claude_mpm/hooks/__init__.py +37 -1
- claude_mpm/hooks/base_hook.py +5 -4
- claude_mpm/hooks/claude_hooks/connection_pool.py +4 -4
- claude_mpm/hooks/claude_hooks/event_handlers.py +21 -18
- claude_mpm/hooks/claude_hooks/hook_handler.py +209 -25
- claude_mpm/hooks/claude_hooks/installer.py +783 -0
- claude_mpm/hooks/claude_hooks/memory_integration.py +3 -3
- claude_mpm/hooks/claude_hooks/response_tracking.py +57 -17
- claude_mpm/hooks/claude_hooks/services/connection_manager.py +64 -49
- claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +140 -76
- claude_mpm/hooks/claude_hooks/services/state_manager.py +11 -9
- claude_mpm/hooks/claude_hooks/services/subagent_processor.py +3 -3
- claude_mpm/hooks/failure_learning/__init__.py +60 -0
- claude_mpm/hooks/failure_learning/failure_detection_hook.py +235 -0
- claude_mpm/hooks/failure_learning/fix_detection_hook.py +217 -0
- claude_mpm/hooks/failure_learning/learning_extraction_hook.py +286 -0
- claude_mpm/hooks/instruction_reinforcement.py +301 -0
- claude_mpm/hooks/kuzu_enrichment_hook.py +263 -0
- claude_mpm/hooks/kuzu_memory_hook.py +386 -0
- claude_mpm/hooks/kuzu_response_hook.py +183 -0
- claude_mpm/hooks/memory_integration_hook.py +1 -1
- claude_mpm/hooks/session_resume_hook.py +121 -0
- claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
- claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
- claude_mpm/hooks/tool_call_interceptor.py +8 -5
- claude_mpm/hooks/validation_hooks.py +3 -3
- claude_mpm/init.py +23 -4
- claude_mpm/models/agent_session.py +8 -6
- claude_mpm/models/resume_log.py +340 -0
- claude_mpm/schemas/__init__.py +12 -0
- claude_mpm/scripts/claude-hook-handler.sh +187 -0
- claude_mpm/scripts/launch_monitor.py +85 -0
- claude_mpm/scripts/mcp_server.py +3 -5
- claude_mpm/scripts/mpm_doctor.py +3 -2
- claude_mpm/scripts/socketio_daemon.py +156 -396
- claude_mpm/services/__init__.py +144 -160
- claude_mpm/services/agents/__init__.py +18 -5
- claude_mpm/services/agents/agent_builder.py +13 -11
- claude_mpm/services/agents/auto_config_manager.py +796 -0
- claude_mpm/services/agents/deployment/agent_config_provider.py +127 -27
- claude_mpm/services/agents/deployment/agent_configuration_manager.py +1 -1
- claude_mpm/services/agents/deployment/agent_deployment.py +38 -15
- claude_mpm/services/agents/deployment/agent_discovery_service.py +125 -7
- claude_mpm/services/agents/deployment/agent_filesystem_manager.py +5 -5
- claude_mpm/services/agents/deployment/agent_format_converter.py +56 -12
- claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +4 -2
- claude_mpm/services/agents/deployment/agent_operation_service.py +2 -2
- claude_mpm/services/agents/deployment/agent_record_service.py +5 -6
- claude_mpm/services/agents/deployment/agent_state_service.py +2 -2
- claude_mpm/services/agents/deployment/agent_template_builder.py +722 -37
- claude_mpm/services/agents/deployment/agent_validator.py +31 -7
- claude_mpm/services/agents/deployment/agent_version_manager.py +9 -1
- claude_mpm/services/agents/deployment/agent_versioning.py +1 -1
- claude_mpm/services/agents/deployment/async_agent_deployment.py +1 -1
- claude_mpm/services/agents/deployment/deployment_config_loader.py +131 -7
- claude_mpm/services/agents/deployment/deployment_type_detector.py +10 -14
- claude_mpm/services/agents/deployment/deployment_wrapper.py +58 -0
- claude_mpm/services/agents/deployment/interface_adapter.py +3 -2
- claude_mpm/services/agents/deployment/local_template_deployment.py +360 -0
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +134 -38
- claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +8 -7
- claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +7 -16
- claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +4 -3
- claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +7 -5
- claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +6 -5
- claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +9 -6
- claude_mpm/services/agents/deployment/system_instructions_deployer.py +9 -6
- claude_mpm/services/agents/deployment/validation/__init__.py +3 -1
- claude_mpm/services/agents/deployment/validation/template_validator.py +64 -44
- claude_mpm/services/agents/deployment/validation/validation_result.py +1 -9
- claude_mpm/services/agents/loading/agent_profile_loader.py +10 -9
- claude_mpm/services/agents/loading/base_agent_manager.py +16 -6
- claude_mpm/services/agents/loading/framework_agent_loader.py +2 -2
- claude_mpm/services/agents/local_template_manager.py +744 -0
- claude_mpm/services/agents/management/agent_capabilities_generator.py +3 -2
- claude_mpm/services/agents/management/agent_management_service.py +5 -5
- claude_mpm/services/agents/memory/agent_memory_manager.py +32 -29
- claude_mpm/services/agents/memory/content_manager.py +17 -9
- claude_mpm/services/agents/memory/memory_categorization_service.py +4 -2
- claude_mpm/services/agents/memory/memory_file_service.py +32 -6
- claude_mpm/services/agents/memory/memory_format_service.py +7 -7
- claude_mpm/services/agents/memory/memory_limits_service.py +4 -2
- claude_mpm/services/agents/memory/template_generator.py +3 -3
- claude_mpm/services/agents/observers.py +547 -0
- claude_mpm/services/agents/recommender.py +615 -0
- claude_mpm/services/agents/registry/deployed_agent_discovery.py +3 -3
- claude_mpm/services/agents/registry/modification_tracker.py +30 -19
- claude_mpm/services/async_session_logger.py +141 -98
- claude_mpm/services/claude_session_logger.py +82 -74
- claude_mpm/services/cli/agent_cleanup_service.py +6 -5
- claude_mpm/services/cli/agent_dependency_service.py +1 -1
- claude_mpm/services/cli/agent_listing_service.py +5 -5
- claude_mpm/services/cli/agent_validation_service.py +6 -5
- claude_mpm/services/cli/memory_crud_service.py +12 -7
- claude_mpm/services/cli/memory_output_formatter.py +2 -2
- claude_mpm/services/cli/resume_service.py +617 -0
- claude_mpm/services/cli/session_manager.py +104 -13
- claude_mpm/services/cli/session_pause_manager.py +504 -0
- claude_mpm/services/cli/session_resume_helper.py +372 -0
- claude_mpm/services/cli/startup_checker.py +13 -21
- claude_mpm/services/cli/unified_dashboard_manager.py +439 -0
- claude_mpm/services/command_deployment_service.py +17 -9
- claude_mpm/services/command_handler_service.py +11 -5
- claude_mpm/services/core/__init__.py +33 -1
- claude_mpm/services/core/base.py +26 -11
- claude_mpm/services/core/cache_manager.py +1 -3
- claude_mpm/services/core/interfaces/__init__.py +90 -3
- claude_mpm/services/core/interfaces/agent.py +184 -0
- claude_mpm/services/core/interfaces/health.py +172 -0
- claude_mpm/services/core/interfaces/model.py +281 -0
- claude_mpm/services/core/interfaces/process.py +372 -0
- claude_mpm/services/core/interfaces/project.py +121 -0
- claude_mpm/services/core/interfaces/restart.py +307 -0
- claude_mpm/services/core/interfaces/stability.py +260 -0
- claude_mpm/services/core/interfaces.py +56 -1
- claude_mpm/services/core/memory_manager.py +92 -47
- claude_mpm/services/core/models/__init__.py +79 -0
- claude_mpm/services/core/models/agent_config.py +384 -0
- claude_mpm/services/core/models/health.py +162 -0
- claude_mpm/services/core/models/process.py +239 -0
- claude_mpm/services/core/models/restart.py +302 -0
- claude_mpm/services/core/models/stability.py +264 -0
- claude_mpm/services/core/models/toolchain.py +306 -0
- claude_mpm/services/core/path_resolver.py +37 -18
- claude_mpm/services/core/service_container.py +2 -2
- claude_mpm/services/diagnostics/__init__.py +2 -2
- claude_mpm/services/diagnostics/checks/__init__.py +4 -2
- claude_mpm/services/diagnostics/checks/agent_check.py +30 -32
- claude_mpm/services/diagnostics/checks/claude_code_check.py +270 -0
- claude_mpm/services/diagnostics/checks/common_issues_check.py +28 -27
- claude_mpm/services/diagnostics/checks/configuration_check.py +26 -25
- claude_mpm/services/diagnostics/checks/filesystem_check.py +18 -17
- claude_mpm/services/diagnostics/checks/installation_check.py +165 -60
- claude_mpm/services/diagnostics/checks/instructions_check.py +22 -24
- claude_mpm/services/diagnostics/checks/mcp_check.py +57 -43
- claude_mpm/services/diagnostics/checks/mcp_services_check.py +1066 -0
- claude_mpm/services/diagnostics/checks/monitor_check.py +24 -23
- claude_mpm/services/diagnostics/checks/startup_log_check.py +14 -11
- claude_mpm/services/diagnostics/diagnostic_runner.py +22 -13
- claude_mpm/services/diagnostics/doctor_reporter.py +275 -47
- claude_mpm/services/diagnostics/models.py +37 -21
- claude_mpm/services/event_aggregator.py +5 -3
- claude_mpm/services/event_bus/direct_relay.py +152 -13
- claude_mpm/services/event_bus/event_bus.py +51 -9
- claude_mpm/services/event_bus/relay.py +33 -14
- claude_mpm/services/events/consumers/dead_letter.py +7 -5
- claude_mpm/services/events/core.py +5 -6
- claude_mpm/services/events/producers/hook.py +6 -6
- claude_mpm/services/events/producers/system.py +8 -8
- claude_mpm/services/exceptions.py +5 -5
- claude_mpm/services/framework_claude_md_generator/__init__.py +1 -1
- claude_mpm/services/framework_claude_md_generator/content_assembler.py +5 -5
- claude_mpm/services/framework_claude_md_generator/content_validator.py +2 -2
- claude_mpm/services/framework_claude_md_generator/deployment_manager.py +3 -3
- claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +2 -2
- claude_mpm/services/framework_claude_md_generator/version_manager.py +1 -1
- claude_mpm/services/hook_installer_service.py +506 -0
- claude_mpm/services/hook_service.py +5 -6
- claude_mpm/services/infrastructure/context_preservation.py +13 -11
- claude_mpm/services/infrastructure/daemon_manager.py +9 -9
- claude_mpm/services/infrastructure/logging.py +2 -2
- claude_mpm/services/infrastructure/monitoring/__init__.py +12 -12
- claude_mpm/services/infrastructure/monitoring/aggregator.py +12 -12
- claude_mpm/services/infrastructure/monitoring/base.py +5 -13
- claude_mpm/services/infrastructure/monitoring/network.py +7 -6
- claude_mpm/services/infrastructure/monitoring/process.py +13 -12
- claude_mpm/services/infrastructure/monitoring/resources.py +8 -7
- claude_mpm/services/infrastructure/monitoring/service.py +16 -15
- claude_mpm/services/infrastructure/monitoring.py +12 -12
- claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
- claude_mpm/services/local_ops/__init__.py +165 -0
- claude_mpm/services/local_ops/crash_detector.py +257 -0
- claude_mpm/services/local_ops/health_checks/__init__.py +28 -0
- claude_mpm/services/local_ops/health_checks/http_check.py +224 -0
- claude_mpm/services/local_ops/health_checks/process_check.py +236 -0
- claude_mpm/services/local_ops/health_checks/resource_check.py +255 -0
- claude_mpm/services/local_ops/health_manager.py +430 -0
- claude_mpm/services/local_ops/log_monitor.py +396 -0
- claude_mpm/services/local_ops/memory_leak_detector.py +294 -0
- claude_mpm/services/local_ops/process_manager.py +595 -0
- claude_mpm/services/local_ops/resource_monitor.py +331 -0
- claude_mpm/services/local_ops/restart_manager.py +401 -0
- claude_mpm/services/local_ops/restart_policy.py +387 -0
- claude_mpm/services/local_ops/state_manager.py +372 -0
- claude_mpm/services/local_ops/unified_manager.py +600 -0
- claude_mpm/services/mcp_config_manager.py +1612 -0
- claude_mpm/services/mcp_gateway/__init__.py +97 -93
- claude_mpm/services/mcp_gateway/auto_configure.py +43 -38
- claude_mpm/services/mcp_gateway/config/config_loader.py +3 -3
- claude_mpm/services/mcp_gateway/config/configuration.py +23 -4
- claude_mpm/services/mcp_gateway/core/__init__.py +1 -2
- claude_mpm/services/mcp_gateway/core/base.py +20 -33
- claude_mpm/services/mcp_gateway/core/process_pool.py +585 -31
- claude_mpm/services/mcp_gateway/core/singleton_manager.py +2 -2
- claude_mpm/services/mcp_gateway/core/startup_verification.py +3 -3
- claude_mpm/services/mcp_gateway/main.py +90 -15
- claude_mpm/services/mcp_gateway/registry/service_registry.py +4 -2
- claude_mpm/services/mcp_gateway/registry/tool_registry.py +12 -9
- claude_mpm/services/mcp_gateway/server/mcp_gateway.py +4 -4
- claude_mpm/services/mcp_gateway/server/stdio_server.py +9 -15
- claude_mpm/services/mcp_gateway/tools/__init__.py +14 -2
- claude_mpm/services/mcp_gateway/tools/base_adapter.py +15 -15
- claude_mpm/services/mcp_gateway/tools/document_summarizer.py +10 -9
- claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +654 -0
- claude_mpm/services/mcp_gateway/tools/health_check_tool.py +36 -34
- claude_mpm/services/mcp_gateway/tools/hello_world.py +8 -8
- claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +551 -0
- claude_mpm/services/mcp_gateway/utils/__init__.py +14 -0
- claude_mpm/services/mcp_gateway/utils/package_version_checker.py +160 -0
- claude_mpm/services/mcp_gateway/utils/update_preferences.py +170 -0
- claude_mpm/services/mcp_service_verifier.py +729 -0
- claude_mpm/services/memory/builder.py +9 -8
- claude_mpm/services/memory/cache/shared_prompt_cache.py +2 -1
- claude_mpm/services/memory/cache/simple_cache.py +2 -2
- claude_mpm/services/memory/failure_tracker.py +578 -0
- claude_mpm/services/memory/indexed_memory.py +8 -8
- claude_mpm/services/memory/optimizer.py +8 -9
- claude_mpm/services/memory/router.py +3 -3
- claude_mpm/services/memory_hook_service.py +165 -4
- claude_mpm/services/model/__init__.py +147 -0
- claude_mpm/services/model/base_provider.py +365 -0
- claude_mpm/services/model/claude_provider.py +412 -0
- claude_mpm/services/model/model_router.py +453 -0
- claude_mpm/services/model/ollama_provider.py +415 -0
- claude_mpm/services/monitor/__init__.py +20 -0
- claude_mpm/services/monitor/daemon.py +671 -0
- claude_mpm/services/monitor/daemon_manager.py +963 -0
- claude_mpm/services/monitor/event_emitter.py +350 -0
- claude_mpm/services/monitor/handlers/__init__.py +21 -0
- claude_mpm/services/monitor/handlers/code_analysis.py +332 -0
- claude_mpm/services/monitor/handlers/dashboard.py +299 -0
- claude_mpm/services/monitor/handlers/file.py +264 -0
- claude_mpm/services/monitor/handlers/hooks.py +512 -0
- claude_mpm/services/monitor/management/__init__.py +18 -0
- claude_mpm/services/monitor/management/health.py +124 -0
- claude_mpm/services/monitor/management/lifecycle.py +724 -0
- claude_mpm/services/monitor/server.py +817 -0
- claude_mpm/services/monitor_build_service.py +2 -2
- claude_mpm/services/native_agent_converter.py +356 -0
- claude_mpm/services/orphan_detection.py +786 -0
- claude_mpm/services/port_manager.py +2 -2
- claude_mpm/services/project/__init__.py +23 -0
- claude_mpm/services/project/analyzer.py +3 -3
- claude_mpm/services/project/architecture_analyzer.py +6 -6
- claude_mpm/services/project/archive_manager.py +1045 -0
- claude_mpm/services/project/dependency_analyzer.py +8 -8
- claude_mpm/services/project/detection_strategies.py +719 -0
- claude_mpm/services/project/documentation_manager.py +553 -0
- claude_mpm/services/project/enhanced_analyzer.py +572 -0
- claude_mpm/services/project/language_analyzer.py +3 -3
- claude_mpm/services/project/metrics_collector.py +7 -10
- claude_mpm/services/project/project_organizer.py +1005 -0
- claude_mpm/services/project/registry.py +13 -7
- claude_mpm/services/project/toolchain_analyzer.py +581 -0
- claude_mpm/services/project_port_allocator.py +596 -0
- claude_mpm/services/response_tracker.py +21 -10
- claude_mpm/services/runner_configuration_service.py +1 -0
- claude_mpm/services/self_upgrade_service.py +500 -0
- claude_mpm/services/session_management_service.py +7 -5
- claude_mpm/services/session_manager.py +380 -0
- claude_mpm/services/shared/__init__.py +2 -1
- claude_mpm/services/shared/async_service_base.py +16 -27
- claude_mpm/services/shared/config_service_base.py +17 -14
- claude_mpm/services/shared/lifecycle_service_base.py +1 -14
- claude_mpm/services/shared/service_factory.py +8 -5
- claude_mpm/services/socketio/client_proxy.py +60 -5
- claude_mpm/services/socketio/dashboard_server.py +361 -0
- claude_mpm/services/socketio/event_normalizer.py +74 -6
- claude_mpm/services/socketio/handlers/__init__.py +5 -0
- claude_mpm/services/socketio/handlers/base.py +2 -2
- claude_mpm/services/socketio/handlers/code_analysis.py +682 -0
- claude_mpm/services/socketio/handlers/connection.py +21 -40
- claude_mpm/services/socketio/handlers/connection_handler.py +16 -28
- claude_mpm/services/socketio/handlers/file.py +46 -10
- claude_mpm/services/socketio/handlers/git.py +8 -8
- claude_mpm/services/socketio/handlers/hook.py +29 -17
- claude_mpm/services/socketio/handlers/registry.py +4 -0
- claude_mpm/services/socketio/monitor_client.py +364 -0
- claude_mpm/services/socketio/server/broadcaster.py +9 -7
- claude_mpm/services/socketio/server/connection_manager.py +131 -68
- claude_mpm/services/socketio/server/core.py +275 -22
- claude_mpm/services/socketio/server/eventbus_integration.py +20 -14
- claude_mpm/services/socketio/server/main.py +99 -29
- claude_mpm/services/socketio_client_manager.py +4 -4
- claude_mpm/services/subprocess_launcher_service.py +19 -15
- claude_mpm/services/system_instructions_service.py +2 -2
- claude_mpm/services/ticket_services/formatter_service.py +1 -1
- claude_mpm/services/ticket_services/validation_service.py +5 -5
- claude_mpm/services/unified/__init__.py +65 -0
- claude_mpm/services/unified/analyzer_strategies/__init__.py +44 -0
- claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +518 -0
- claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +680 -0
- claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +903 -0
- claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +746 -0
- claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +733 -0
- claude_mpm/services/unified/config_strategies/__init__.py +175 -0
- claude_mpm/services/unified/config_strategies/config_schema.py +731 -0
- claude_mpm/services/unified/config_strategies/context_strategy.py +747 -0
- claude_mpm/services/unified/config_strategies/error_handling_strategy.py +1005 -0
- claude_mpm/services/unified/config_strategies/file_loader_strategy.py +881 -0
- claude_mpm/services/unified/config_strategies/unified_config_service.py +823 -0
- claude_mpm/services/unified/config_strategies/validation_strategy.py +1148 -0
- claude_mpm/services/unified/deployment_strategies/__init__.py +97 -0
- claude_mpm/services/unified/deployment_strategies/base.py +553 -0
- claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +573 -0
- claude_mpm/services/unified/deployment_strategies/local.py +607 -0
- claude_mpm/services/unified/deployment_strategies/utils.py +667 -0
- claude_mpm/services/unified/deployment_strategies/vercel.py +475 -0
- claude_mpm/services/unified/interfaces.py +475 -0
- claude_mpm/services/unified/migration.py +509 -0
- claude_mpm/services/unified/strategies.py +534 -0
- claude_mpm/services/unified/unified_analyzer.py +542 -0
- claude_mpm/services/unified/unified_config.py +691 -0
- claude_mpm/services/unified/unified_deployment.py +470 -0
- claude_mpm/services/utility_service.py +6 -3
- claude_mpm/services/version_control/branch_strategy.py +2 -2
- claude_mpm/services/version_control/conflict_resolution.py +8 -4
- claude_mpm/services/version_control/git_operations.py +26 -24
- claude_mpm/services/version_control/semantic_versioning.py +14 -14
- claude_mpm/services/version_control/version_parser.py +14 -11
- claude_mpm/services/version_service.py +104 -1
- claude_mpm/services/visualization/__init__.py +19 -0
- claude_mpm/services/visualization/mermaid_generator.py +938 -0
- claude_mpm/skills/__init__.py +42 -0
- claude_mpm/skills/agent_skills_injector.py +324 -0
- claude_mpm/skills/bundled/LICENSE_ATTRIBUTIONS.md +79 -0
- claude_mpm/skills/bundled/__init__.py +6 -0
- claude_mpm/skills/bundled/api-documentation.md +393 -0
- claude_mpm/skills/bundled/async-testing.md +571 -0
- claude_mpm/skills/bundled/code-review.md +143 -0
- claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
- claude_mpm/skills/bundled/database-migration.md +199 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
- claude_mpm/skills/bundled/docker-containerization.md +194 -0
- claude_mpm/skills/bundled/express-local-dev.md +1429 -0
- claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
- claude_mpm/skills/bundled/git-workflow.md +414 -0
- claude_mpm/skills/bundled/imagemagick.md +204 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
- claude_mpm/skills/bundled/json-data-handling.md +223 -0
- claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
- claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
- claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
- claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +157 -0
- claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +425 -0
- claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
- claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
- claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
- claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
- claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
- claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +303 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +113 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +72 -0
- claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
- claude_mpm/skills/bundled/pdf.md +141 -0
- claude_mpm/skills/bundled/performance-profiling.md +573 -0
- claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
- claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
- claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
- claude_mpm/skills/bundled/security-scanning.md +327 -0
- claude_mpm/skills/bundled/systematic-debugging.md +473 -0
- claude_mpm/skills/bundled/test-driven-development.md +378 -0
- claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
- claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
- claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
- claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
- claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +35 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +44 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +34 -0
- claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
- claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
- claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +129 -0
- claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
- claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
- claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
- claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
- claude_mpm/skills/bundled/xlsx.md +157 -0
- claude_mpm/skills/registry.py +286 -0
- claude_mpm/skills/skill_manager.py +310 -0
- claude_mpm/skills/skills_registry.py +348 -0
- claude_mpm/skills/skills_service.py +739 -0
- claude_mpm/storage/state_storage.py +31 -31
- claude_mpm/tools/__init__.py +10 -0
- claude_mpm/tools/__main__.py +208 -0
- claude_mpm/tools/code_tree_analyzer/__init__.py +45 -0
- claude_mpm/tools/code_tree_analyzer/analysis.py +299 -0
- claude_mpm/tools/code_tree_analyzer/cache.py +131 -0
- claude_mpm/tools/code_tree_analyzer/core.py +380 -0
- claude_mpm/tools/code_tree_analyzer/discovery.py +403 -0
- claude_mpm/tools/code_tree_analyzer/events.py +168 -0
- claude_mpm/tools/code_tree_analyzer/gitignore.py +308 -0
- claude_mpm/tools/code_tree_analyzer/models.py +39 -0
- claude_mpm/tools/code_tree_analyzer/multilang_analyzer.py +224 -0
- claude_mpm/tools/code_tree_analyzer/python_analyzer.py +284 -0
- claude_mpm/tools/code_tree_builder.py +631 -0
- claude_mpm/tools/code_tree_events.py +420 -0
- claude_mpm/tools/socketio_debug.py +671 -0
- claude_mpm/utils/agent_dependency_loader.py +108 -27
- claude_mpm/utils/common.py +544 -0
- claude_mpm/utils/config_manager.py +12 -6
- claude_mpm/utils/database_connector.py +298 -0
- claude_mpm/utils/dependency_cache.py +2 -2
- claude_mpm/utils/dependency_strategies.py +15 -10
- claude_mpm/utils/display_helper.py +260 -0
- claude_mpm/utils/environment_context.py +4 -3
- claude_mpm/utils/error_handler.py +5 -3
- claude_mpm/utils/file_utils.py +13 -14
- claude_mpm/utils/git_analyzer.py +407 -0
- claude_mpm/utils/log_cleanup.py +627 -0
- claude_mpm/utils/path_operations.py +7 -4
- claude_mpm/utils/robust_installer.py +133 -24
- claude_mpm/utils/session_logging.py +2 -2
- claude_mpm/utils/subprocess_utils.py +9 -8
- claude_mpm/validation/agent_validator.py +6 -6
- claude_mpm/validation/frontmatter_validator.py +6 -6
- claude_mpm-4.24.0.dist-info/METADATA +675 -0
- claude_mpm-4.24.0.dist-info/RECORD +1018 -0
- {claude_mpm-4.1.6.dist-info โ claude_mpm-4.24.0.dist-info}/entry_points.txt +1 -0
- claude_mpm/agents/INSTRUCTIONS.md +0 -237
- claude_mpm/agents/schema/agent_schema.json +0 -314
- claude_mpm/agents/templates/agent-manager.md +0 -304
- claude_mpm/cli/commands/configure_tui.py +0 -1921
- claude_mpm/cli/commands/socketio_monitor.py +0 -233
- claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +0 -425
- claude_mpm/hooks/claude_hooks/hook_handler_original.py +0 -1040
- claude_mpm/hooks/claude_hooks/hook_handler_refactored.py +0 -347
- claude_mpm/scripts/socketio_daemon_hardened.py +0 -937
- claude_mpm/scripts/socketio_server_manager.py +0 -349
- claude_mpm/services/agents/deployment/agent_lifecycle_manager_refactored.py +0 -575
- claude_mpm/services/cli/dashboard_launcher.py +0 -424
- claude_mpm/services/cli/socketio_manager.py +0 -498
- claude_mpm/services/diagnostics/checks/claude_desktop_check.py +0 -286
- claude_mpm/services/mcp_gateway/tools/ticket_tools.py +0 -645
- claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +0 -602
- claude_mpm/services/project/analyzer_refactored.py +0 -450
- claude_mpm-4.1.6.dist-info/METADATA +0 -325
- claude_mpm-4.1.6.dist-info/RECORD +0 -550
- {claude_mpm-4.1.6.dist-info โ claude_mpm-4.24.0.dist-info}/WHEEL +0 -0
- {claude_mpm-4.1.6.dist-info โ claude_mpm-4.24.0.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.1.6.dist-info โ claude_mpm-4.24.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
._dataInspector_9ek2f_1{background:#0000004d;border-radius:6px;border:1px solid rgba(255,255,255,.1);overflow:hidden}._inspectorHeader_9ek2f_8{display:flex;gap:10px;padding:10px;background:#ffffff0d;border-bottom:1px solid rgba(255,255,255,.1);align-items:center}._searchInput_9ek2f_17{flex:1;padding:8px 12px;background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-radius:4px;color:#fff;font-size:12px}._searchInput_9ek2f_17::placeholder{color:#ffffff80}._actions_9ek2f_31{display:flex;gap:8px}._actionButton_9ek2f_36{padding:6px 12px;background:#ffffff1a;border:none;border-radius:4px;color:#fff;font-size:11px;cursor:pointer;transition:background .2s}._actionButton_9ek2f_36:hover{background:#fff3}._treeContainer_9ek2f_51{overflow-y:auto;padding:10px;font-family:Courier New,monospace;font-size:13px;line-height:1.4}._treeNode_9ek2f_59{margin-bottom:2px}._nodeHeader_9ek2f_63{display:flex;align-items:center;gap:6px;padding:2px 4px;cursor:pointer;border-radius:3px;transition:background .2s}._nodeHeader_9ek2f_63:hover{background:#ffffff0d}._expandIcon_9ek2f_77{color:#94a3b8;font-size:10px;transition:transform .2s;cursor:pointer;user-select:none;width:12px;display:inline-block}._expandIcon_9ek2f_77._expanded_9ek2f_87{transform:rotate(90deg)}._leafIcon_9ek2f_91{color:#94a3b8;font-size:8px;width:12px;display:inline-block;text-align:center}._nodeKey_9ek2f_99{color:#60a5fa;font-weight:500}._nodeValue_9ek2f_104{margin-left:6px;word-break:break-all}._nodeValue_9ek2f_104._string_9ek2f_109{color:#86efac}._nodeValue_9ek2f_104._number_9ek2f_113{color:#fbbf24}._nodeValue_9ek2f_104._boolean_9ek2f_117{color:#a78bfa}._nodeValue_9ek2f_104._null_9ek2f_121,._nodeValue_9ek2f_104._undefined_9ek2f_122{color:#f87171;font-style:italic}._nodeValue_9ek2f_104._object_9ek2f_127,._nodeValue_9ek2f_104._array_9ek2f_128{color:#94a3b8;font-style:italic}._copyButton_9ek2f_133{margin-left:auto;background:none;border:none;color:#ffffff80;cursor:pointer;padding:2px;font-size:10px;opacity:0;transition:opacity .2s}._nodeHeader_9ek2f_63:hover ._copyButton_9ek2f_133{opacity:1}._copyButton_9ek2f_133:hover{color:#fffc}._nodeChildren_9ek2f_153{border-left:1px solid rgba(255,255,255,.1);margin-left:6px}._highlight_9ek2f_158{background:#fbbf244d;color:#fbbf24;padding:1px 2px;border-radius:2px}._noData_9ek2f_165{text-align:center;color:#ffffff80;padding:20px;font-style:italic}._treeContainer_9ek2f_51::-webkit-scrollbar{width:6px}._treeContainer_9ek2f_51::-webkit-scrollbar-track{background:#ffffff0d}._treeContainer_9ek2f_51::-webkit-scrollbar-thumb{background:#fff3;border-radius:3px}._treeContainer_9ek2f_51::-webkit-scrollbar-thumb:hover{background:#ffffff4d}._eventsContainer_3k2sj_1{background:#ffffff0d;backdrop-filter:blur(10px);border-radius:12px;border:1px solid rgba(255,255,255,.1);overflow:hidden;flex:1;display:flex;flex-direction:column;min-height:0}._eventsHeader_3k2sj_13{padding:15px 20px;background:#ffffff0d;border-bottom:1px solid rgba(255,255,255,.1);display:flex;justify-content:space-between;align-items:center}._eventsTitle_3k2sj_22{font-weight:600;font-size:16px}._eventsInfo_3k2sj_27{font-size:12px;color:#fff9}._eventsList_3k2sj_32{flex:1;position:relative;min-height:300px}._eventItem_3k2sj_38{padding:12px 20px;border-bottom:1px solid rgba(255,255,255,.05);transition:background .2s;cursor:pointer;font-family:Courier New,monospace;font-size:13px;position:relative;animation:_slideIn_3k2sj_1 .3s ease}@keyframes _slideIn_3k2sj_1{0%{opacity:0;transform:translate(-20px)}to{opacity:1;transform:translate(0)}}._eventItem_3k2sj_38:hover{background:#ffffff0d}._eventItem_3k2sj_38._expanded_3k2sj_64{background:#ffffff14}._eventHeader_3k2sj_68{width:100%}._eventHeaderRow_3k2sj_72{display:flex;gap:10px;align-items:center;margin-bottom:5px}._eventType_3k2sj_79{padding:3px 8px;border-radius:10px;font-size:11px;font-weight:600;text-transform:uppercase}._eventType_3k2sj_79._agent_3k2sj_87{background:#a78bfa33;color:#a78bfa}._eventType_3k2sj_79._tool_3k2sj_92{background:#60a5fa33;color:#60a5fa}._eventType_3k2sj_79._file_3k2sj_97{background:#fbbf2433;color:#fbbf24}._eventType_3k2sj_79._session_3k2sj_102{background:#4ade8033;color:#4ade80}._eventType_3k2sj_79._error_3k2sj_107{background:#f8717133;color:#f87171}._eventType_3k2sj_79._info_3k2sj_112{background:#86efac33;color:#86efac}._eventTime_3k2sj_117{font-size:11px;color:#ffffff80}._sourceIndicator_3k2sj_122{font-size:10px;color:#fff6;font-style:italic}._eventPreview_3k2sj_128{color:#ffffffb3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}._eventDetails_3k2sj_136{margin-top:10px;padding:10px;background:#0003;border-radius:6px}._noEvents_3k2sj_143{text-align:center;padding:60px 20px;color:#ffffff80}._noEvents_3k2sj_143 h3{margin-bottom:10px;font-size:18px}._noEvents_3k2sj_143 p{font-size:14px}._controlsPanel_wgq69_1{background:#ffffff0d;backdrop-filter:blur(10px);border:1px solid rgba(255,255,255,.1);border-radius:10px;padding:15px;margin-bottom:20px;display:flex;gap:15px;align-items:center;flex-wrap:wrap}._controlGroup_wgq69_14{display:flex;align-items:center;gap:10px}._controlLabel_wgq69_20{font-size:14px;color:#94a3b8}._btn_wgq69_25{padding:10px 20px;background:linear-gradient(135deg,#10b981,#06b6d4);border:none;border-radius:8px;color:#fff;cursor:pointer;font-size:14px;transition:transform .2s,box-shadow .2s}._btn_wgq69_25:hover{transform:translateY(-2px);box-shadow:0 5px 15px #10b98166}._btn_wgq69_25._secondary_wgq69_41{background:#ffffff1a}._btn_wgq69_25._danger_wgq69_45{background:linear-gradient(135deg,#ef4444,#dc2626)}._searchBox_wgq69_49{flex:1;min-width:200px;padding:10px 15px;background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-radius:8px;color:#fff;font-size:14px}._searchBox_wgq69_49::placeholder{color:#ffffff80}._filterSelect_wgq69_64{padding:10px 15px;background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-radius:8px;color:#fff;font-size:14px;cursor:pointer}._filterSelect_wgq69_64 option{background:#0f172a}._checkboxLabel_wgq69_78{display:flex;align-items:center;gap:8px;padding:10px 15px;background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-radius:8px;cursor:pointer;font-size:14px}._checkboxLabel_wgq69_78 input{cursor:pointer}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{U as e}from"./unified-data-viewer.js";class t{constructor(){this.container=null,this.events=[],this.processedEventIds=new Set,this.sessions=new Map,this.currentSession=null,this.selectedSessionFilter="all",this.timeRange="30min",this.searchTerm="",this.initialized=!1,this.expandedSessions=new Set,this.expandedAgents=new Set,this.expandedTools=new Set,this.selectedItem=null,this.sessionFilterInitialized=!1,this.renderTreeDebounced=this.debounce(()=>this.renderTree(),100)}debounce(e,t){let s;return function(...n){clearTimeout(s),s=setTimeout(()=>{clearTimeout(s),e(...n)},t)}}initialize(){if(console.log("ActivityTree.initialize() called, initialized:",this.initialized),this.initialized)return void console.log("Activity tree already initialized, skipping");if(this.container=document.getElementById("activity-tree-container"),!this.container&&(this.container=document.getElementById("activity-tree"),!this.container))return void console.error("Activity tree container not found in DOM");const e=document.getElementById("activity-tab");if(e){if(!e.classList.contains("active"))return console.log("Activity tab not active, initializing but deferring render"),this.setupControls(),this.subscribeToEvents(),void(this.initialized=!0);this.setupControls(),this.createLinearTreeView(),this.subscribeToEvents(),this.initialized=!0,console.log("Activity tree initialization complete")}else console.error("Activity tab panel (#activity-tab) not found in DOM")}forceShow(){console.log("ActivityTree.forceShow() called"),this.container||(this.container=document.getElementById("activity-tree-container")||document.getElementById("activity-tree"),this.container)?(this.createLinearTreeView(),this.renderTree()):console.error("Cannot find activity tree container")}renderWhenVisible(){if(console.log("ActivityTree.renderWhenVisible() called"),!this.initialized)return console.log("Not initialized yet, calling initialize..."),void this.initialize();this.createLinearTreeView(),this.renderTree()}setupControls(){const e=document.getElementById("time-range");e&&e.addEventListener("change",e=>{this.timeRange=e.target.value,console.log(`ActivityTree: Time range changed to: ${this.timeRange}`),this.renderTree()}),document.addEventListener("sessionFilterChanged",e=>{this.selectedSessionFilter=e.detail.sessionId||"all",console.log(`ActivityTree: Session filter changed to: ${this.selectedSessionFilter} (from SessionManager)`),this.renderTree()}),document.addEventListener("sessionChanged",e=>{this.selectedSessionFilter=e.detail.sessionId||"all",console.log(`ActivityTree: Session changed to: ${this.selectedSessionFilter} (from SessionManager - backward compat)`),this.renderTree()}),setTimeout(()=>{if(window.sessionManager&&!this.sessionFilterInitialized){const e=window.sessionManager.getCurrentFilter();e!==this.selectedSessionFilter&&(this.selectedSessionFilter=e||"all",console.log(`ActivityTree: Initialized with current session filter: ${this.selectedSessionFilter}`),this.sessionFilterInitialized=!0,this.renderTree())}},100);const t=document.getElementById("expand-all");t&&t.addEventListener("click",()=>this.expandAllSessions());const s=document.getElementById("collapse-all");s&&s.addEventListener("click",()=>this.collapseAllSessions());const n=document.getElementById("reset-zoom");n&&(n.style.display="inline-block",n.addEventListener("click",()=>this.resetZoom()));const o=document.getElementById("activity-search");o&&o.addEventListener("input",e=>{this.searchTerm=e.target.value.toLowerCase(),this.renderTree()})}createLinearTreeView(){console.log("Creating linear tree view"),this.container.innerHTML="";const e=document.createElement("div");e.id="linear-tree",e.className="linear-tree",this.container.appendChild(e),console.log("Linear tree view created")}subscribeToEvents(){if(!window.socketClient)return console.warn("Socket client not available for activity tree"),void setTimeout(()=>this.subscribeToEvents(),1e3);console.log("ActivityTree: Setting up event subscription"),window.socketClient.onEventUpdate((e,t)=>{console.log(`ActivityTree: onEventUpdate called with ${e.length} total events and ${t.size} sessions`);for(const[n,o]of t.entries())if(this.sessions.has(n)){const e=this.sessions.get(n);e.timestamp=new Date(o.lastActivity||o.startTime||e.timestamp),e.eventCount=o.eventCount,e.status=o.status||e.status,e.working_directory=o.working_directory||e.working_directory,e.git_branch=o.git_branch||e.git_branch}else{const e={id:n,timestamp:new Date(o.lastActivity||o.startTime||new Date),expanded:this.expandedSessions.has(n)||!0,agents:new Map,todos:[],userInstructions:[],tools:[],toolsMap:new Map,status:"active",currentTodoTool:null,working_directory:o.working_directory,git_branch:o.git_branch,eventCount:o.eventCount};this.sessions.set(n,e)}const s=e.filter(e=>{const t=e.id||`${e.type}-${e.timestamp}-${Math.random()}`;return!this.processedEventIds.has(t)});s.length>0&&(console.log(`ActivityTree: Processing ${s.length} new events`,s),s.forEach(e=>{const t=e.id||`${e.type}-${e.timestamp}-${Math.random()}`;this.processedEventIds.add(t),this.processEvent(e)})),this.events=[...e],this.renderTreeDebounced(),console.log("ActivityTree: Sessions after sync with socket client:",Array.from(this.sessions.entries()))});const e=window.socketClient?.getState();if(e&&e.events.length>0){console.log(`ActivityTree: Loading existing data - ${e.events.length} events, ${e.sessions.size} sessions`);for(const[s,n]of e.sessions.entries())if(!this.sessions.has(s)){const e={id:s,timestamp:new Date(n.lastActivity||n.startTime||new Date),expanded:this.expandedSessions.has(s)||!0,agents:new Map,todos:[],userInstructions:[],tools:[],toolsMap:new Map,status:"active",currentTodoTool:null,working_directory:n.working_directory,git_branch:n.git_branch,eventCount:n.eventCount};this.sessions.set(s,e)}const t=e.events.filter(e=>{const t=e.id||`${e.type}-${e.timestamp}-${Math.random()}`;return!this.processedEventIds.has(t)});t.length>0&&(console.log(`ActivityTree: Processing ${t.length} unprocessed events from initial load`),t.forEach(e=>{const t=e.id||`${e.type}-${e.timestamp}-${Math.random()}`;this.processedEventIds.add(t),this.processEvent(e)})),this.events=[...e.events],this.renderTree(),console.log("ActivityTree: Initial sessions state:",Array.from(this.sessions.entries()))}else console.log("ActivityTree: No existing events found"),this.events=[],this.sessions.clear(),this.renderTree()}processEvent(e){if(!e)return void console.log("ActivityTree: Ignoring null event");let t,s=this.getEventType(e);if(!s)return;console.log(`ActivityTree: Processing event: ${s}`,e),e.timestamp?(t=new Date(e.timestamp),isNaN(t.getTime())&&(console.warn("ActivityTree: Invalid timestamp, using current time:",e.timestamp),t=new Date)):(console.warn("ActivityTree: No timestamp found, using current time"),t=new Date);const n=e.session_id||e.data?.session_id;if(!n)return void console.log(`ActivityTree: Skipping event without session_id: ${s}`);if(!this.sessions.has(n))return void console.warn(`ActivityTree: Session ${n} not found in authoritative sessions - skipping event`);const o=this.sessions.get(n);switch(s){case"Start":this.currentSession=o;break;case"user_prompt":this.processUserInstruction(e,o);break;case"TodoWrite":break;case"SubagentStart":this.processSubagentStart(e,o);break;case"SubagentStop":this.processSubagentStop(e,o);break;case"PreToolUse":this.processToolUse(e,o);break;case"PostToolUse":this.updateToolStatus(e,o,"completed")}this.updateStats()}getEventType(e){if(e.hook_event_name)return e.hook_event_name;if("hook"===e.type&&e.subtype){return{pre_tool:"PreToolUse",post_tool:"PostToolUse",subagent_start:"SubagentStart",subagent_stop:"SubagentStop",todo_write:"TodoWrite"}[e.subtype]}if("todo"===e.type&&"updated"===e.subtype)return"TodoWrite";if("subagent"===e.type){if("started"===e.subtype)return"SubagentStart";if("stopped"===e.subtype)return"SubagentStop"}return"start"===e.type?"Start":"user_prompt"===e.type||"user_prompt"===e.subtype?"user_prompt":null}processUserInstruction(e,t){const s=e.prompt_text||e.data?.prompt_text||e.prompt||"";if(!s)return;const n={id:`instruction-${t.id}-${Date.now()}`,text:s,preview:s.length>100?s.substring(0,100)+"...":s,timestamp:e.timestamp||(new Date).toISOString(),type:"user_instruction"};if(t.agents.size>0){console.log("ActivityTree: New user prompt detected, collapsing previous agents");for(let e of t.agents.values())"active"===e.status&&(e.status="completed"),this.expandedAgents.delete(e.id)}t.currentActiveAgent=null,t.userInstructions.push(n),t.userInstructions.length>5&&(t.userInstructions=t.userInstructions.slice(-5))}processTodoWrite(e,t){let s=e.todos||e.data?.todos||e.data||[];if(s&&"object"==typeof s&&s.todos&&(s=s.todos),!Array.isArray(s)||0===s.length)return;t.currentTodos=s.map(t=>({content:t.content,activeForm:t.activeForm,status:t.status,timestamp:e.timestamp}));let n=t.currentActiveAgent;if(!n){const e=this.getAllAgents(t).filter(e=>"active"===e.status||"in_progress"===e.status).sort((e,t)=>new Date(t.timestamp)-new Date(e.timestamp));if(e.length>0)n=e[0];else{const e=this.getAllAgents(t),s=e.find(e=>e.isPM);s?n=s:e.length>0&&(n=e[0])}}if(n){n.todoWritesMap||(n.todoWritesMap=new Map),n.todoWrites||(n.todoWrites=[]);const t=n.todoWritesMap.get("TodoWrite");if(t)t.todos=s,t.timestamp=e.timestamp,t.updateCount=(t.updateCount||1)+1;else{const t={id:`todowrite-${n.id}-${Date.now()}`,name:"TodoWrite",type:"todowrite",icon:"๐",timestamp:e.timestamp,status:"completed",todos:s,params:{todos:s},updateCount:1};n.todoWritesMap.set("TodoWrite",t),n.todoWrites=[t]}n.currentTodos=s}else{t.todoWrites||(t.todoWrites=[]),t.todoWritesMap||(t.todoWritesMap=new Map);const n=t.todoWritesMap.get("TodoWrite");if(n)n.todos=s,n.timestamp=e.timestamp,n.updateCount=(n.updateCount||1)+1;else{const n={id:`todowrite-session-${Date.now()}`,name:"TodoWrite",type:"todowrite",icon:"๐",timestamp:e.timestamp,status:"completed",todos:s,updateCount:1};t.todoWritesMap.set("TodoWrite",n),t.todoWrites=[n]}}}processSubagentStart(e,t){const s=e.agent_name||e.data?.agent_name||e.data?.agent_type||e.agent_type||e.agent||"unknown",n=e.session_id||e.data?.session_id,o=e.parent_agent||e.data?.parent_agent,i=`${s}-${n||"no-session"}`;let a=null;let r;if(a=this.getAllAgents(t).find(e=>e.name===s&&e.sessionId===n&&"active"===e.status),a)r=a,r.timestamp=e.timestamp,r.instanceCount=(r.instanceCount||1)+1,this.expandedAgents.add(r.id);else{if(r={id:`agent-${i}-${Date.now()}`,name:s,type:"agent",icon:this.getAgentIcon(s),timestamp:e.timestamp,status:"active",tools:[],subagents:new Map,sessionId:n,parentAgent:o,isPM:"pm"===s.toLowerCase()||s.toLowerCase().includes("project manager"),instanceCount:1,toolsMap:new Map},o){let e=null;for(let[s,n]of t.agents.entries())if(n.sessionId===o||n.name===o){e=n;break}e?(e.subagents||(e.subagents=new Map),e.subagents.set(r.id,r)):t.agents.set(r.id,r)}else t.agents.set(r.id,r);this.expandedAgents.add(r.id)}t.currentActiveAgent=r}processSubagentStop(e,t){const s=e.session_id||e.data?.session_id;if(s&&t.agents.has(s)){t.agents.get(s).status="completed"}}processToolUse(e,t){const s=e.tool_name||e.data?.tool_name||e.tool||e.data?.tool||"unknown",n=e.tool_parameters||e.data?.tool_parameters||e.parameters||e.data?.parameters||{},o=e.session_id||e.data?.session_id;let i=t.currentActiveAgent;if(!i){const e=this.getAllAgents(t);i=e.find(e=>e.sessionId===o)||e.find(e=>"active"===e.status)||e[0]}if(i){i.toolsMap||(i.toolsMap=new Map),i.tools||(i.tools=[]);const t=this.getToolKey(s,n);let o=i.toolsMap.get(t);if(o)o.params=n,o.timestamp=e.timestamp,o.status="in_progress",o.eventId=e.id,o.callCount=(o.callCount||1)+1,i.currentTool=o;else{const o={id:`tool-${i.id}-${s}-${Date.now()}`,name:s,type:"tool",icon:this.getToolIcon(s),timestamp:e.timestamp,status:"in_progress",params:n,eventId:e.id,callCount:1,createdAt:e.timestamp};"Task"===s&&n.subagent_type&&(o.isSubagentTask=!0,o.subagentType=n.subagent_type),i.toolsMap.set(t,o),"TodoWrite"===s?i.tools.unshift(o):i.tools.push(o),i.currentTool=o}}else{t.tools||(t.tools=[]),t.toolsMap||(t.toolsMap=new Map);const o=this.getToolKey(s,n);let i=t.toolsMap.get(o);if(i)i.params=n,i.timestamp=e.timestamp,i.status="in_progress",i.eventId=e.id,i.callCount=(i.callCount||1)+1,t.currentTool=i;else{const i={id:`tool-session-${s}-${Date.now()}`,name:s,type:"tool",icon:this.getToolIcon(s),timestamp:e.timestamp,status:"in_progress",params:n,eventId:e.id,callCount:1,createdAt:e.timestamp};t.toolsMap.set(o,i),"TodoWrite"===s?t.tools.unshift(i):t.tools.push(i),t.currentTool=i}}}getToolKey(e,t){if("TodoWrite"===e)return"TodoWrite";let s=e;return"Edit"!==e&&"Write"!==e&&"Read"!==e||t.file_path&&(s+=`-${t.file_path}`),"Grep"!==e&&"Glob"!==e||!t.pattern||(s+=`-${t.pattern.substring(0,20)}`),s}updateToolStatus(e,t,s){const n=e.tool_name||e.data?.tool_name||e.tool||"unknown",o=e.tool_parameters||e.data?.tool_parameters||e.parameters||e.data?.parameters||{},i=e.session_id||e.data?.session_id,a=this.getToolKey(n,o);let r=t.currentActiveAgent;if(!r){const e=this.getAllAgents(t);r=e.find(e=>e.sessionId===i)||e.find(e=>"active"===e.status)}if(r&&r.toolsMap){const t=r.toolsMap.get(a);if(t)return t.status=s,t.completedAt=e.timestamp,(e.data?.result||e.result)&&(t.result=e.data?.result||e.result),void(e.data?.duration_ms&&(t.duration=e.data.duration_ms))}if(t.toolsMap){const n=t.toolsMap.get(a);if(n)return n.status=s,n.completedAt=e.timestamp,(e.data?.result||e.result)&&(n.result=e.data?.result||e.result),void(e.data?.duration_ms&&(n.duration=e.data.duration_ms))}console.log(`ActivityTree: Could not find tool to update status for ${n} with key ${a} (event ${e.id})`)}renderTree(){const e=document.getElementById("linear-tree");if(!e)return;e.innerHTML="";const t=Array.from(this.sessions.values()).sort((e,t)=>new Date(t.timestamp)-new Date(e.timestamp));for(let s of t){if("all"!==this.selectedSessionFilter&&this.selectedSessionFilter!==s.id)continue;const t=this.createSessionElement(s);e.appendChild(t)}}createSessionElement(e){const t=this.expandedSessions.has(e.id)||e.expanded;let s;try{const t=e.timestamp instanceof Date?e.timestamp:new Date(e.timestamp);isNaN(t.getTime())?(s="Invalid Date",console.warn("ActivityTree: Invalid session timestamp:",e.timestamp)):s=t.toLocaleString()}catch(l){s="Invalid Date",console.error("ActivityTree: Error formatting session timestamp:",l,e.timestamp)}const n=document.createElement("div");n.className="tree-node session",n.dataset.sessionId=e.id;const o=t?"โผ":"โถ",i=this.getAllAgents(e).length,a=e.currentTodos?e.currentTodos.length:0,r=e.userInstructions?e.userInstructions.length:0;return console.log(`ActivityTree: Rendering session ${e.id}: ${i} agents, ${r} instructions, ${a} todos at ${s}`),n.innerHTML=`\n <div class="tree-node-content" onclick="window.activityTreeInstance.toggleSession('${e.id}')">\n <span class="tree-expand-icon">${o}</span>\n <span class="tree-icon">๐ฏ</span>\n <span class="tree-label">PM Session</span>\n <span class="tree-meta">${s} โข ${i} agent(s) โข ${r} instruction(s) โข ${a} todo(s)</span>\n </div>\n <div class="tree-children" style="display: ${t?"block":"none"}">\n ${this.renderSessionContent(e)}\n </div>\n `,n}renderSessionContent(e){let t="";if(e.userInstructions&&e.userInstructions.length>0)for(let n of e.userInstructions.slice(-3))t+=this.renderUserInstructionElement(n,1);if(e.tools&&e.tools.length>0)for(let n of e.tools)t+=this.renderToolElement(n,1);const s=Array.from(e.agents.values()).sort((e,t)=>new Date(t.timestamp)-new Date(e.timestamp));for(let n of s)t+=this.renderAgentElement(n,1);return t}renderUserInstructionElement(e,t){return`\n <div class="tree-node user-instruction ${this.selectedItem&&"instruction"===this.selectedItem.type&&this.selectedItem.data.id===e.id?"selected":""}" data-level="${t}">\n <div class="tree-node-content">\n <span class="tree-expand-icon"></span>\n <span class="tree-icon">๐ฌ</span>\n <span class="tree-label clickable" onclick="window.activityTreeInstance.selectItem(${this.escapeJson(e)}, 'instruction', event)">User: "${this.escapeHtml(e.preview)}"</span>\n <span class="tree-status status-active">instruction</span>\n </div>\n </div>\n `}renderTodoChecklistElement(e,t){const s=`checklist-${Date.now()}`,n=!1!==this.expandedTools.has(s),o=n?"โผ":"โถ";let i=0,a=0;e.forEach(e=>{"completed"===e.status?i++:"in_progress"===e.status&&a++});let r="";r=a>0?`${a} in progress, ${i} completed`:i===e.length&&e.length>0?`All ${e.length} completed`:`${e.length} todo(s)`;let l=`\n <div class="tree-node todo-checklist" data-level="${t}">\n <div class="tree-node-content">\n <span class="tree-expand-icon" onclick="window.activityTreeInstance.toggleTodoChecklist('${s}'); event.stopPropagation();">${o}</span>\n <span class="tree-icon">โ๏ธ</span>\n <span class="tree-label">TODOs</span>\n <span class="tree-params">${r}</span>\n <span class="tree-status status-active">checklist</span>\n </div>\n `;if(n){l+='<div class="tree-children">';for(let s of e){const e=this.getCheckboxIcon(s.status),n=`status-${s.status}`,o="in_progress"===s.status?s.activeForm:s.content;l+=`\n <div class="tree-node todo-item ${n}" data-level="${t+1}">\n <div class="tree-node-content">\n <span class="tree-expand-icon"></span>\n <span class="tree-icon">${e}</span>\n <span class="tree-label">${this.escapeHtml(o)}</span>\n <span class="tree-status ${n}">${s.status.replace("_"," ")}</span>\n </div>\n </div>\n `}l+="</div>"}return l+="</div>",l}renderAgentElement(e,t){const s="active"===e.status?"status-active":"status-completed",n=this.expandedAgents.has(e.id),o=e.tools&&e.tools.length>0,i=e.subagents&&e.subagents.size>0,a=o||i,r=a?n?"โผ":"โถ":"",l=this.selectedItem&&"agent"===this.selectedItem.type&&this.selectedItem.data.id===e.id?"selected":"",c=e.instanceCount>1?` (${e.instanceCount}x)`:"";let d="";if(!n&&a){const t=[];if(e.currentTodos&&e.currentTodos.length>0){const s=e.currentTodos.find(e=>"in_progress"===e.status);s&&t.push(`๐ ${s.activeForm||s.content}`)}e.currentTool&&t.push(`${e.currentTool.icon} ${e.currentTool.name}`),t.length>0&&(d=` โข ${t.join(" โข ")}`)}let p=`\n <div class="tree-node agent ${s} ${l}" data-level="${t}">\n <div class="tree-node-content">\n ${r?`<span class="tree-expand-icon" onclick="window.activityTreeInstance.toggleAgent('${e.id}'); event.stopPropagation();">${r}</span>`:'<span class="tree-expand-icon"></span>'}\n <span class="tree-icon">${e.icon}</span>\n <span class="tree-label clickable" onclick="window.activityTreeInstance.selectItem(${this.escapeJson(e)}, 'agent', event)">${e.name}${c}${d}</span>\n <span class="tree-status ${s}">${e.status}</span>\n </div>\n `;if(a&&n){if(p+='<div class="tree-children">',o)for(let s of e.tools)p+=this.renderToolElement(s,t+1);if(i){const s=Array.from(e.subagents.values());for(let e of s)p+=this.renderAgentElement(e,t+1)}p+="</div>"}return p+="</div>",p}renderToolElement(e,t){const s=`status-${e.status}`,n=this.getToolParams(e),o=this.selectedItem&&"tool"===this.selectedItem.type&&this.selectedItem.data.id===e.id?"selected":"",i=this.getToolStatusIcon(e.status),a=this.getToolStatusLabel(e.status),r=e.callCount>1?` (${e.callCount} calls)`:"";return`\n <div class="tree-node tool ${s} ${o}" data-level="${t}">\n <div class="tree-node-content">\n <span class="tree-expand-icon"></span>\n <span class="tree-icon">${e.icon}</span>\n <span class="tree-status-icon">${i}</span>\n <span class="tree-label clickable" onclick="window.activityTreeInstance.selectItem(${this.escapeJson(e)}, 'tool', event)">${e.name}${r}</span>\n <span class="tree-params">${n}</span>\n <span class="tree-status ${s}">${a}</span>\n </div>\n </div>\n `}getToolParams(e){if(!e.params)return"";if("Read"===e.name&&e.params.file_path)return e.params.file_path;if("Edit"===e.name&&e.params.file_path)return e.params.file_path;if("Write"===e.name&&e.params.file_path)return e.params.file_path;if("Bash"===e.name&&e.params.command){const t=e.params.command;return t.length>50?t.substring(0,50)+"...":t}return"WebFetch"===e.name&&e.params.url?e.params.url:""}getStatusIcon(e){return{pending:"โธ๏ธ",in_progress:"๐",completed:"โ
"}[e]||"โ"}getCheckboxIcon(e){return{pending:"โณ",in_progress:"๐",completed:"โ
"}[e]||"โ"}getAgentIcon(e){return{engineer:"๐ท",research:"๐ฌ",qa:"๐งช",ops:"โ๏ธ",pm:"๐",architect:"๐๏ธ","project manager":"๐"}[e.toLowerCase()]||"๐ค"}getAllAgents(e){const t=[],s=e=>{if(e)for(let n of e.values())t.push(n),n.subagents&&n.subagents.size>0&&s(n.subagents)};return s(e.agents),t}renderTodoWriteElement(e,t){const s=e.id,n=this.expandedTools.has(s),o=n?"โผ":"โถ",i=e.todos||[];let a=0,r=0;i.forEach(e=>{"completed"===e.status?a++:"in_progress"===e.status&&r++});const l=i.find(e=>"in_progress"===e.status),c=l?` โข ๐ ${l.activeForm||l.content}`:"";let d="";d=r>0?`${r} in progress, ${a}/${i.length} done`:a===i.length&&i.length>0?`All ${i.length} completed โ
`:`${a}/${i.length} done`;let p=`\n <div class="tree-node todowrite ${l?"has-active":""}" data-level="${t}">\n <div class="tree-node-content">\n <span class="tree-expand-icon" onclick="window.activityTreeInstance.toggleTodoWrite('${s}'); event.stopPropagation();">${o}</span>\n <span class="tree-icon">๐</span>\n <span class="tree-label">TodoWrite${e.updateCount>1?` (${e.updateCount} updates)`:""}${n?"":c}</span>\n <span class="tree-params">${d}</span>\n <span class="tree-status status-active">todos</span>\n </div>\n `;if(n&&i.length>0){p+='<div class="tree-children">';for(let e of i){const s=this.getCheckboxIcon(e.status),n=`status-${e.status}`,o="in_progress"===e.status?e.activeForm:e.content;p+=`\n <div class="tree-node todo-item ${n} ${e===l?"current-active":""}" data-level="${t+1}">\n <div class="tree-node-content">\n <span class="tree-expand-icon"></span>\n <span class="tree-icon">${s}</span>\n <span class="tree-label">${this.escapeHtml(o)}</span>\n <span class="tree-status ${n}">${e.status.replace("_"," ")}</span>\n </div>\n </div>\n `}p+="</div>"}return p+="</div>",p}toggleTodoWrite(e){this.expandedTools.has(e)?this.expandedTools.delete(e):this.expandedTools.add(e),this.renderTree()}getToolIcon(e){return{read:"๐๏ธ",write:"โ๏ธ",edit:"โ๏ธ",bash:"๐ป",webfetch:"๐",grep:"๐",glob:"๐",todowrite:"๐"}[e.toLowerCase()]||"๐ง"}getToolStatusIcon(e){return{in_progress:"โณ",completed:"โ
",failed:"โ",error:"โ",pending:"โธ๏ธ",active:"๐"}[e]||"โ"}getToolStatusLabel(e){return{in_progress:"in progress",completed:"completed",failed:"failed",error:"error",pending:"pending",active:"active"}[e]||e}toggleSession(e){this.expandedSessions.has(e)?this.expandedSessions.delete(e):this.expandedSessions.add(e);const t=this.sessions.get(e);t&&(t.expanded=this.expandedSessions.has(e)),this.renderTree()}expandAllSessions(){for(let e of this.sessions.keys()){this.expandedSessions.add(e);const t=this.sessions.get(e);t&&(t.expanded=!0)}this.renderTree()}collapseAllSessions(){this.expandedSessions.clear();for(let e of this.sessions.values())e.expanded=!1;this.renderTree()}updateStats(){const e=this.countTotalNodes(),t=this.countActiveNodes(),s=this.calculateMaxDepth(),n=document.getElementById("node-count"),o=document.getElementById("active-count"),i=document.getElementById("tree-depth");n&&(n.textContent=e),o&&(o.textContent=t),i&&(i.textContent=s),console.log(`ActivityTree: Stats updated - Nodes: ${e}, Active: ${t}, Depth: ${s}`)}countTotalNodes(){let e=0;for(let t of this.sessions.values()){e+=1,e+=t.agents.size,t.userInstructions&&(e+=t.userInstructions.length),t.todos&&(e+=t.todos.length),t.tools&&(e+=t.tools.length);for(let s of t.agents.values())s.tools&&(e+=s.tools.length)}return e}countActiveNodes(){let e=0;for(let t of this.sessions.values()){if("active"===t.status&&e++,t.todos)for(let s of t.todos)"in_progress"===s.status&&e++;if(t.tools)for(let s of t.tools)"in_progress"===s.status&&e++;for(let s of t.agents.values())if("active"===s.status&&e++,s.tools)for(let t of s.tools)"in_progress"===t.status&&e++}return e}calculateMaxDepth(){let e=0;for(let t of this.sessions.values()){let s=1;t.userInstructions&&t.userInstructions.length>0&&(s=Math.max(s,2)),t.todos&&t.todos.length>0&&(s=Math.max(s,3)),t.tools&&t.tools.length>0&&(s=Math.max(s,2));for(let e of t.agents.values())e.tools&&e.tools.length>0&&(s=Math.max(s,3));e=Math.max(e,s)}return e}toggleAgent(e){this.expandedAgents.has(e)?this.expandedAgents.delete(e):this.expandedAgents.add(e),this.renderTree()}toggleTool(e){console.log("Tool expansion is disabled. Tools now show data in the left pane when clicked.")}toggleTodoChecklist(e){this.expandedTools.has(e)?this.expandedTools.delete(e):this.expandedTools.add(e),this.renderTree()}renderPinnedTodosElement(e,t){const s=`pinned-todos-${Date.now()}`,n=!1!==this.expandedTools.has(s),o=n?"โผ":"โถ",i=e.todos||[];let a=0,r=0;i.forEach(e=>{"completed"===e.status?a++:"in_progress"===e.status&&r++});let l="";l=r>0?`${r} in progress, ${a} completed`:a===i.length&&i.length>0?`All ${i.length} completed`:`${i.length} todo(s)`;let c=`\n <div class="tree-node pinned-todos" data-level="${t}">\n <div class="tree-node-content">\n <span class="tree-expand-icon" onclick="window.activityTreeInstance.toggleTodoChecklist('${s}'); event.stopPropagation();">${o}</span>\n <span class="tree-icon">๐</span>\n <span class="tree-label">Pinned TODOs</span>\n <span class="tree-params">${l}</span>\n <span class="tree-status status-active">pinned</span>\n </div>\n `;if(n){c+='<div class="tree-children">';for(let e of i){const s=this.getCheckboxIcon(e.status),n=`status-${e.status}`,o="in_progress"===e.status?e.activeForm:e.content;c+=`\n <div class="tree-node todo-item ${n}" data-level="${t+1}">\n <div class="tree-node-content">\n <span class="tree-expand-icon"></span>\n <span class="tree-icon">${s}</span>\n <span class="tree-label">${this.escapeHtml(o)}</span>\n <span class="tree-status ${n}">${e.status.replace("_"," ")}</span>\n </div>\n </div>\n `}c+="</div>"}return c+="</div>",c}selectItem(e,t,s){s&&s.stopPropagation(),this.selectedItem={data:e,type:t},this.displayItemData(e,t),this.renderTree()}displayItemData(t,s){this.unifiedViewer||(this.unifiedViewer=new e("module-data-content")),this.unifiedViewer.display(t,s);const n=document.querySelector(".module-data-header h5");if(n){const e={agent:"๐ค",tool:"๐ง",instruction:"๐ฌ",session:"๐ฏ",todo:"๐"}[s]||"๐",o=t.name||t.agentName||t.tool_name||"Item";n.textContent=`${e} ${s}: ${o}`}}escapeHtml(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}resetZoom(){this.svg&&this.zoom&&this.svg.transition().duration(this.duration).call(this.zoom.transform,d3.zoomIdentity)}escapeJson(e){return JSON.stringify(e).replace(/'/g,"'").replace(/"/g,""")}}window.ActivityTree=t;const s=()=>{let e=null;const s=()=>{e||(console.log("Creating new Activity Tree instance..."),e=new t,window.activityTreeInstance=e,window.activityTree=()=>e),setTimeout(()=>{console.log("Attempting to initialize Activity Tree visualization..."),e.initialize()},100)};document.addEventListener("tabChanged",t=>{t.detail&&"activity"===t.detail.newTab&&(console.log("Tab changed to activity, initializing tree..."),s(),e&&setTimeout(()=>{e.renderWhenVisible(),e.forceShow()},150))});const n=document.querySelector(".tab-button.active");n&&"activity"===n.getAttribute("data-tab")&&(console.log("Activity tab is active on load, initializing tree..."),s());const o=document.getElementById("activity-tab");o&&o.classList.contains("active")&&(console.log("Activity panel is active on load, initializing tree..."),e||s())};"loading"===document.readyState?document.addEventListener("DOMContentLoaded",s):s();
|
|
2
|
+
//# sourceMappingURL=activity-tree.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
class e{constructor(e){this.eventViewer=e,this.state={currentDelegation:null,sessionAgents:new Map,eventAgentMap:new Map,pmDelegations:new Map,agentToDelegation:new Map,orphanSubagents:new Map,subagentStartEvents:new Map},console.log("Agent inference system initialized")}initialize(){this.state={currentDelegation:null,sessionAgents:new Map,eventAgentMap:new Map,pmDelegations:new Map,agentToDelegation:new Map,orphanSubagents:new Map,subagentStartEvents:new Map}}inferAgentFromEvent(e){const t=e.data||{},n=e.session_id||t.session_id||"unknown",a=e.hook_event_name||t.hook_event_name||e.type||"",s=e.subtype||t.subtype||"",i=e.tool_name||t.tool_name||"";if(Math.random()<.1&&console.log("Agent inference debug:",{eventType:a,toolName:i,hasData:!!e.data,dataKeys:Object.keys(t),eventKeys:Object.keys(e),agentType:e.agent_type||t.agent_type,subagentType:e.subagent_type||t.subagent_type}),"SubagentStop"===a||"subagent_stop"===s){const i=this.extractAgentNameFromEvent(e);return console.log("SubagentStop event detected:",{agentName:i,sessionId:n,eventType:a,subtype:s,rawAgentType:e.agent_type||t.agent_type}),{type:"subagent",confidence:"definitive",agentName:i,reason:"SubagentStop event"}}if("Stop"===a||"stop"===s)return{type:"main_agent",confidence:"definitive",agentName:"PM",reason:"Stop event"};if("Task"===i){const t=this.extractSubagentTypeFromTask(e);if(t)return console.log("Task delegation detected:",{agentName:t,sessionId:n,eventType:a}),{type:"subagent",confidence:"high",agentName:t,reason:"Task tool with subagent_type"}}if("PreToolUse"===a&&"Task"===i){const t=this.extractSubagentTypeFromTask(e);if(t)return{type:"subagent",confidence:"high",agentName:t,reason:"PreToolUse Task delegation"}}{const e=n.toLowerCase();if(["subagent","task","agent-"].some(t=>e.includes(t)))return{type:"subagent",confidence:"medium",agentName:"Subagent",reason:"Session ID pattern"}}const o=e.agent_type||t.agent_type||e.agent_id||t.agent_id,g=e.subagent_type||t.subagent_type;if(g&&"unknown"!==g)return{type:"subagent",confidence:"high",agentName:this.normalizeAgentName(g),reason:"subagent_type field"};if(o&&"unknown"!==o&&"main"!==o)return{type:"subagent",confidence:"medium",agentName:this.normalizeAgentName(o),reason:"agent_type field"};if(t.delegation_details?.agent_type)return{type:"subagent",confidence:"high",agentName:this.normalizeAgentName(t.delegation_details.agent_type),reason:"delegation_details"};if(e.type&&e.type.startsWith("hook.")){const a=e.type.replace("hook.","");if("subagent_start"===a||"SubagentStart"===t.hook_event_name){const e=t.agent_type||t.agent_id||"Subagent";return console.log("SubagentStart event from Socket.IO:",{agentName:e,sessionId:n,hookType:a}),{type:"subagent",confidence:"definitive",agentName:this.normalizeAgentName(e),reason:"Socket.IO hook SubagentStart"}}if("subagent_stop"===a||"SubagentStop"===t.hook_event_name){const e=t.agent_type||t.agent_id||"Subagent";return{type:"subagent",confidence:"high",agentName:this.normalizeAgentName(e),reason:"Socket.IO hook SubagentStop"}}}return{type:"main_agent",confidence:"default",agentName:"PM",reason:"default classification"}}normalizeAgentName(e){if(!e)return"Unknown";const t={engineer:"Engineer Agent",research:"Research Agent",qa:"QA Agent",documentation:"Documentation Agent",security:"Security Agent",ops:"Ops Agent",version_control:"Version Control Agent",data_engineer:"Data Engineer Agent",test_integration:"Test Integration Agent",pm:"PM Agent"}[e.toLowerCase()];if(t)return t;let n=e.replace(/_/g," ").split(" ").map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join(" ");return n.toLowerCase().includes("agent")||(n+=" Agent"),n}extractSubagentTypeFromTask(e){let t=null;return e.tool_parameters?.subagent_type?t=e.tool_parameters.subagent_type:e.data?.tool_parameters?.subagent_type?t=e.data.tool_parameters.subagent_type:e.data?.delegation_details?.agent_type?t=e.data.delegation_details.agent_type:e.tool_input?.subagent_type&&(t=e.tool_input.subagent_type),t?this.normalizeAgentName(t):null}extractAgentNameFromEvent(e){const t=e.data||{};if("Task"===e.tool_name||"Task"===t.tool_name){const t=this.extractSubagentTypeFromTask(e);if(t)return t}return e.subagent_type&&"unknown"!==e.subagent_type?this.normalizeAgentName(e.subagent_type):t.subagent_type&&"unknown"!==t.subagent_type?this.normalizeAgentName(t.subagent_type):t.delegation_details?.agent_type&&"unknown"!==t.delegation_details.agent_type?this.normalizeAgentName(t.delegation_details.agent_type):e.agent_type&&!["main","unknown"].includes(e.agent_type)?this.normalizeAgentName(e.agent_type):t.agent_type&&!["main","unknown"].includes(t.agent_type)?this.normalizeAgentName(t.agent_type):e.agent_id&&!["main","unknown"].includes(e.agent_id)?this.normalizeAgentName(e.agent_id):t.agent_id&&!["main","unknown"].includes(t.agent_id)?this.normalizeAgentName(t.agent_id):e.agent&&"unknown"!==e.agent?this.normalizeAgentName(e.agent):e.name&&"unknown"!==e.name?this.normalizeAgentName(e.name):"Unknown"}processAgentInference(){const e=this.eventViewer.events;this.state.currentDelegation=null,this.state.sessionAgents.clear(),this.state.eventAgentMap.clear(),this.state.pmDelegations.clear(),this.state.agentToDelegation.clear(),this.state.orphanSubagents.clear(),this.state.subagentStartEvents.clear(),console.log("Processing agent inference for",e.length,"events"),e&&0!==e.length?(e.forEach((e,t)=>{let n;try{const a=this.inferAgentFromEvent(e),s=e.session_id||e.data?.session_id||"default";n=a,this.state.currentDelegation&&"default"===a.confidence&&s===this.state.currentDelegation.sessionId&&(n={type:"subagent",confidence:"inherited",agentName:this.state.currentDelegation.agentName,reason:"inherited from delegation context"});const i=e.hook_event_name||e.data?.hook_event_name||"";if(("SubagentStart"===i||"hook.subagent_start"===e.type||"subagent_start"===e.subtype)&&"subagent"===a.type&&(this.state.subagentStartEvents.has(a.agentName)||this.state.subagentStartEvents.set(a.agentName,[]),this.state.subagentStartEvents.get(a.agentName).push({eventIndex:t,event:e,timestamp:e.timestamp,sessionId:s})),"Task"===e.tool_name&&"subagent"===a.type){const n=`pm_${s}_${t}_${a.agentName}`,i={id:n,agentName:a.agentName,sessionId:s,startIndex:t,endIndex:null,pmCall:e,timestamp:e.timestamp,agentEvents:[]};this.state.pmDelegations.set(n,i),this.state.agentToDelegation.set(a.agentName,n),this.state.currentDelegation={agentName:a.agentName,sessionId:s,startIndex:t,endIndex:null,delegationId:n},console.log("Delegation started:",this.state.currentDelegation)}else if("definitive"===a.confidence&&"SubagentStop event"===a.reason&&this.state.currentDelegation){this.state.currentDelegation.endIndex=t;const e=this.state.pmDelegations.get(this.state.currentDelegation.delegationId);e&&(e.endIndex=t),console.log("Delegation ended:",this.state.currentDelegation),this.state.currentDelegation=null}if(this.state.currentDelegation&&"subagent"===n.type){const a=this.state.pmDelegations.get(this.state.currentDelegation.delegationId);a&&a.agentEvents.push({eventIndex:t,event:e,inference:n})}this.state.eventAgentMap.set(t,n),this.state.sessionAgents.set(s,n),t<5&&console.log(`Event ${t} agent inference:`,{event_type:e.type||e.hook_event_name,subtype:e.subtype,tool_name:e.tool_name,inference:n,hasData:!!e.data,agentType:e.agent_type||e.data?.agent_type})}catch(a){console.error(`Error processing event ${t} for agent inference:`,a),n||(n={type:"main_agent",confidence:"error",agentName:"PM",reason:"error during processing"}),this.state.eventAgentMap.set(t,n)}}),this.identifyOrphanSubagents(e),console.log("Agent inference processing complete. Results:",{total_events:e.length,inferred_agents:this.state.eventAgentMap.size,unique_sessions:this.state.sessionAgents.size,pm_delegations:this.state.pmDelegations.size,agent_to_delegation_mappings:this.state.agentToDelegation.size,orphan_subagents:this.state.orphanSubagents.size})):console.log("No events to process for agent inference")}getInferredAgent(e){return this.state.eventAgentMap.get(e)||null}getInferredAgentForEvent(e){const t=this.eventViewer.events;let n=t.indexOf(e);if(-1===n&&e.timestamp&&(n=t.findIndex(t=>t.timestamp===e.timestamp&&t.session_id===e.session_id)),-1===n)return console.log("Agent inference: Could not find event in events array, performing inline inference"),this.inferAgentFromEvent(e);let a=this.getInferredAgent(n);return a||(a=this.inferAgentFromEvent(e),this.state.eventAgentMap.set(n,a)),a}getCurrentDelegation(){return this.state.currentDelegation}getSessionAgents(){return this.state.sessionAgents}getEventAgentMap(){return this.state.eventAgentMap}getPMDelegations(){return this.state.pmDelegations}getAgentToDelegationMap(){return this.state.agentToDelegation}buildDelegationHierarchy(){const e=this.getPMDelegations(),t=this.eventViewer.events,n={mainPM:{type:"pm",name:"PM",delegations:[],ownEvents:[],totalEvents:0},impliedPM:{type:"pm_implied",name:"Implied PM",delegations:[],ownEvents:[],totalEvents:0}};for(const[s,i]of e)n.mainPM.delegations.push({id:s,agentName:i.agentName,taskContext:this.extractTaskContext(i.pmCall),events:i.agentEvents,startTime:i.timestamp,endTime:i.endIndex?t[i.endIndex]?.timestamp:null,status:i.endIndex?"completed":"active"}),n.mainPM.totalEvents+=i.agentEvents.length;t.forEach((e,t)=>{const a=this.getInferredAgent(t);a&&"main_agent"===a.type&&(n.mainPM.ownEvents.push({eventIndex:t,event:e}),n.mainPM.totalEvents++)});const a=new Map;t.forEach((t,n)=>{const s=this.getInferredAgent(n);if(s&&"subagent"===s.type){let i=!0;for(const[t,a]of e)if(a.agentEvents.some(e=>e.eventIndex===n)){i=!1;break}if(i){const e=s.agentName;a.has(e)||a.set(e,[]),a.get(e).push({eventIndex:n,event:t,inference:s})}}});for(const[s,i]of a)n.impliedPM.delegations.push({id:`implied_${s}`,agentName:s,taskContext:"No explicit PM delegation",events:i,startTime:i[0].event.timestamp,endTime:i[i.length-1].event.timestamp,status:"completed"}),n.impliedPM.totalEvents+=i.length;return n}extractTaskContext(e){if(!e)return"Unknown task";const t=e.tool_parameters||e.data?.tool_parameters||{};return t.task||t.request||t.description||"Task delegation"}identifyOrphanSubagents(e){for(const[t,n]of this.state.subagentStartEvents)for(const a of n){const n=a.eventIndex,s=new Date(a.timestamp).getTime();let i=!1;for(let a=Math.max(0,n-20);a<n;a++){const n=e[a];if(!n)continue;const o=s-new Date(n.timestamp).getTime();if("Task"===n.tool_name&&o>=0&&o<1e4){const e=this.state.eventAgentMap.get(a);if(e&&e.agentName===t){i=!0;break}}}i||this.state.orphanSubagents.set(n,{agentName:t,timestamp:a.timestamp,sessionId:a.sessionId,event:a.event,groupingKey:null})}this.groupOrphanSubagents(5e3)}groupOrphanSubagents(e){const t=Array.from(this.state.orphanSubagents.values()).sort((e,t)=>new Date(e.timestamp)-new Date(t.timestamp));let n=null,a=null;for(const s of t){const t=new Date(s.timestamp).getTime();(!n||a&&t-a>e)&&(n=`implied_pm_${s.sessionId}_${t}`),s.groupingKey=n,a=t}}isOrphanSubagent(e){return this.state.orphanSubagents.has(e)}getOrphanContext(e){return this.state.orphanSubagents.get(e)||null}getOrphanGroups(){const e=new Map;for(const t of this.state.orphanSubagents.values()){const n=t.groupingKey;e.has(n)||e.set(n,[]),e.get(n).push(t)}return e}getUniqueAgentInstances(){const e=new Map;for(const[a,s]of this.state.pmDelegations){const t=s.agentName;e.has(t)||e.set(t,{id:`consolidated_${t}`,type:"consolidated_agent",agentName:t,delegations:[],pmCalls:[],allEvents:[],firstTimestamp:s.timestamp,lastTimestamp:s.timestamp,totalEventCount:s.agentEvents.length,delegationCount:1});const n=e.get(t);n.delegations.push({id:a,pmCall:s.pmCall,timestamp:s.timestamp,eventCount:s.agentEvents.length,startIndex:s.startIndex,endIndex:s.endIndex,events:s.agentEvents}),s.pmCall&&n.pmCalls.push(s.pmCall),n.allEvents=n.allEvents.concat(s.agentEvents),new Date(s.timestamp)<new Date(n.firstTimestamp)&&(n.firstTimestamp=s.timestamp),new Date(s.timestamp)>new Date(n.lastTimestamp)&&(n.lastTimestamp=s.timestamp),n.totalEventCount+=s.agentEvents.length,n.delegationCount++}const t=this.eventViewer.events;for(let a=0;a<t.length;a++){const n=this.getInferredAgent(a);n&&"subagent"===n.type&&!e.has(n.agentName)&&e.set(n.agentName,{id:`consolidated_${n.agentName}`,type:"consolidated_agent",agentName:n.agentName,delegations:[{id:`implied_pm_${n.agentName}_${a}`,pmCall:null,timestamp:t[a].timestamp,eventCount:1,startIndex:a,endIndex:null,events:[{eventIndex:a,event:t[a],inference:n}]}],pmCalls:[],allEvents:[{eventIndex:a,event:t[a],inference:n}],firstTimestamp:t[a].timestamp,lastTimestamp:t[a].timestamp,totalEventCount:1,delegationCount:1,isImplied:!0})}const n=Array.from(e.values()).sort((e,t)=>new Date(e.firstTimestamp)-new Date(t.firstTimestamp));return console.log("Consolidated unique agents:",{total_unique_agents:n.length,agents:n.map(e=>({name:e.agentName,delegations:e.delegationCount,totalEvents:e.totalEventCount}))}),n}}export{e as A};
|
|
1
|
+
window.AgentInference=class{constructor(e){this.eventViewer=e,this.state={currentDelegation:null,sessionAgents:new Map,eventAgentMap:new Map,pmDelegations:new Map,agentToDelegation:new Map,orphanSubagents:new Map,subagentStartEvents:new Map},console.log("Agent inference system initialized")}initialize(){this.state={currentDelegation:null,sessionAgents:new Map,eventAgentMap:new Map,pmDelegations:new Map,agentToDelegation:new Map,orphanSubagents:new Map,subagentStartEvents:new Map}}inferAgentFromEvent(e){const t=e.data||{},n=e.session_id||t.session_id||"unknown",a=e.hook_event_name||t.hook_event_name||e.type||"",s=e.subtype||t.subtype||"",i=e.tool_name||t.tool_name||"";if(Math.random()<.1&&console.log("Agent inference debug:",{eventType:a,toolName:i,hasData:!!e.data,dataKeys:Object.keys(t),eventKeys:Object.keys(e),agentType:e.agent_type||t.agent_type,subagentType:e.subagent_type||t.subagent_type}),"SubagentStop"===a||"subagent_stop"===s){const i=this.extractAgentNameFromEvent(e);return console.log("SubagentStop event detected:",{agentName:i,sessionId:n,eventType:a,subtype:s,rawAgentType:e.agent_type||t.agent_type}),{type:"subagent",confidence:"definitive",agentName:i,reason:"SubagentStop event"}}if("Stop"===a||"stop"===s)return{type:"main_agent",confidence:"definitive",agentName:"PM",reason:"Stop event"};if("Task"===i){const t=this.extractSubagentTypeFromTask(e);if(t)return console.log("Task delegation detected:",{agentName:t,sessionId:n,eventType:a}),{type:"subagent",confidence:"high",agentName:t,reason:"Task tool with subagent_type"}}if("PreToolUse"===a&&"Task"===i){const t=this.extractSubagentTypeFromTask(e);if(t)return{type:"subagent",confidence:"high",agentName:t,reason:"PreToolUse Task delegation"}}{const e=n.toLowerCase();if(["subagent","task","agent-"].some(t=>e.includes(t)))return{type:"subagent",confidence:"medium",agentName:"Subagent",reason:"Session ID pattern"}}const o=e.agent_type||t.agent_type||e.agent_id||t.agent_id,g=e.subagent_type||t.subagent_type;if(g&&"unknown"!==g)return{type:"subagent",confidence:"high",agentName:this.normalizeAgentName(g),reason:"subagent_type field"};if(o&&"unknown"!==o&&"main"!==o)return{type:"subagent",confidence:"medium",agentName:this.normalizeAgentName(o),reason:"agent_type field"};if(t.delegation_details?.agent_type)return{type:"subagent",confidence:"high",agentName:this.normalizeAgentName(t.delegation_details.agent_type),reason:"delegation_details"};if(e.type&&e.type.startsWith("hook.")){const a=e.type.replace("hook.","");if("subagent_start"===a||"SubagentStart"===t.hook_event_name){const e=t.agent_type||t.agent_id||"Subagent";return console.log("SubagentStart event from Socket.IO:",{agentName:e,sessionId:n,hookType:a}),{type:"subagent",confidence:"definitive",agentName:this.normalizeAgentName(e),reason:"Socket.IO hook SubagentStart"}}if("subagent_stop"===a||"SubagentStop"===t.hook_event_name){const e=t.agent_type||t.agent_id||"Subagent";return{type:"subagent",confidence:"high",agentName:this.normalizeAgentName(e),reason:"Socket.IO hook SubagentStop"}}}return{type:"main_agent",confidence:"default",agentName:"PM",reason:"default classification"}}normalizeAgentName(e){if(!e)return"Unknown";const t={engineer:"Engineer Agent",research:"Research Agent",qa:"QA Agent",documentation:"Documentation Agent",security:"Security Agent",ops:"Ops Agent",version_control:"Version Control Agent",data_engineer:"Data Engineer Agent",test_integration:"Test Integration Agent",pm:"PM Agent"}[e.toLowerCase()];if(t)return t;let n=e.replace(/_/g," ").split(" ").map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join(" ");return n.toLowerCase().includes("agent")||(n+=" Agent"),n}extractSubagentTypeFromTask(e){let t=null;return e.tool_parameters?.subagent_type?t=e.tool_parameters.subagent_type:e.data?.tool_parameters?.subagent_type?t=e.data.tool_parameters.subagent_type:e.data?.delegation_details?.agent_type?t=e.data.delegation_details.agent_type:e.tool_input?.subagent_type&&(t=e.tool_input.subagent_type),t?this.normalizeAgentName(t):null}extractAgentNameFromEvent(e){const t=e.data||{};if("Task"===e.tool_name||"Task"===t.tool_name){const t=this.extractSubagentTypeFromTask(e);if(t)return t}return e.subagent_type&&"unknown"!==e.subagent_type?this.normalizeAgentName(e.subagent_type):t.subagent_type&&"unknown"!==t.subagent_type?this.normalizeAgentName(t.subagent_type):t.delegation_details?.agent_type&&"unknown"!==t.delegation_details.agent_type?this.normalizeAgentName(t.delegation_details.agent_type):e.agent_type&&!["main","unknown"].includes(e.agent_type)?this.normalizeAgentName(e.agent_type):t.agent_type&&!["main","unknown"].includes(t.agent_type)?this.normalizeAgentName(t.agent_type):e.agent_id&&!["main","unknown"].includes(e.agent_id)?this.normalizeAgentName(e.agent_id):t.agent_id&&!["main","unknown"].includes(t.agent_id)?this.normalizeAgentName(t.agent_id):e.agent&&"unknown"!==e.agent?this.normalizeAgentName(e.agent):e.name&&"unknown"!==e.name?this.normalizeAgentName(e.name):"Unknown"}processAgentInference(){const e=this.eventViewer.events;this.state.currentDelegation=null,this.state.sessionAgents.clear(),this.state.eventAgentMap.clear(),this.state.pmDelegations.clear(),this.state.agentToDelegation.clear(),this.state.orphanSubagents.clear(),this.state.subagentStartEvents.clear(),console.log("Processing agent inference for",e.length,"events"),e&&0!==e.length?(e.forEach((e,t)=>{let n;try{const a=this.inferAgentFromEvent(e),s=e.session_id||e.data?.session_id||"default";n=a,this.state.currentDelegation&&"default"===a.confidence&&s===this.state.currentDelegation.sessionId&&(n={type:"subagent",confidence:"inherited",agentName:this.state.currentDelegation.agentName,reason:"inherited from delegation context"});const i=e.hook_event_name||e.data?.hook_event_name||"";if(("SubagentStart"===i||"hook.subagent_start"===e.type||"subagent_start"===e.subtype)&&"subagent"===a.type&&(this.state.subagentStartEvents.has(a.agentName)||this.state.subagentStartEvents.set(a.agentName,[]),this.state.subagentStartEvents.get(a.agentName).push({eventIndex:t,event:e,timestamp:e.timestamp,sessionId:s})),"Task"===e.tool_name&&"subagent"===a.type){const n=`pm_${s}_${t}_${a.agentName}`,i={id:n,agentName:a.agentName,sessionId:s,startIndex:t,endIndex:null,pmCall:e,timestamp:e.timestamp,agentEvents:[]};this.state.pmDelegations.set(n,i),this.state.agentToDelegation.set(a.agentName,n),this.state.currentDelegation={agentName:a.agentName,sessionId:s,startIndex:t,endIndex:null,delegationId:n},console.log("Delegation started:",this.state.currentDelegation)}else if("definitive"===a.confidence&&"SubagentStop event"===a.reason&&this.state.currentDelegation){this.state.currentDelegation.endIndex=t;const e=this.state.pmDelegations.get(this.state.currentDelegation.delegationId);e&&(e.endIndex=t),console.log("Delegation ended:",this.state.currentDelegation),this.state.currentDelegation=null}if(this.state.currentDelegation&&"subagent"===n.type){const a=this.state.pmDelegations.get(this.state.currentDelegation.delegationId);a&&a.agentEvents.push({eventIndex:t,event:e,inference:n})}this.state.eventAgentMap.set(t,n),this.state.sessionAgents.set(s,n),t<5&&console.log(`Event ${t} agent inference:`,{event_type:e.type||e.hook_event_name,subtype:e.subtype,tool_name:e.tool_name,inference:n,hasData:!!e.data,agentType:e.agent_type||e.data?.agent_type})}catch(a){console.error(`Error processing event ${t} for agent inference:`,a),n||(n={type:"main_agent",confidence:"error",agentName:"PM",reason:"error during processing"}),this.state.eventAgentMap.set(t,n)}}),this.identifyOrphanSubagents(e),console.log("Agent inference processing complete. Results:",{total_events:e.length,inferred_agents:this.state.eventAgentMap.size,unique_sessions:this.state.sessionAgents.size,pm_delegations:this.state.pmDelegations.size,agent_to_delegation_mappings:this.state.agentToDelegation.size,orphan_subagents:this.state.orphanSubagents.size})):console.log("No events to process for agent inference")}getInferredAgent(e){return this.state.eventAgentMap.get(e)||null}getInferredAgentForEvent(e){const t=this.eventViewer.events;let n=t.indexOf(e);if(-1===n&&e.timestamp&&(n=t.findIndex(t=>t.timestamp===e.timestamp&&t.session_id===e.session_id)),-1===n)return console.log("Agent inference: Could not find event in events array, performing inline inference"),this.inferAgentFromEvent(e);let a=this.getInferredAgent(n);return a||(a=this.inferAgentFromEvent(e),this.state.eventAgentMap.set(n,a)),a}getCurrentDelegation(){return this.state.currentDelegation}getSessionAgents(){return this.state.sessionAgents}getEventAgentMap(){return this.state.eventAgentMap}getPMDelegations(){return this.state.pmDelegations}getAgentToDelegationMap(){return this.state.agentToDelegation}buildDelegationHierarchy(){const e=this.getPMDelegations(),t=this.eventViewer.events,n={mainPM:{type:"pm",name:"PM",delegations:[],ownEvents:[],totalEvents:0},impliedPM:{type:"pm_implied",name:"Implied PM",delegations:[],ownEvents:[],totalEvents:0}};for(const[s,i]of e)n.mainPM.delegations.push({id:s,agentName:i.agentName,taskContext:this.extractTaskContext(i.pmCall),events:i.agentEvents,startTime:i.timestamp,endTime:i.endIndex?t[i.endIndex]?.timestamp:null,status:i.endIndex?"completed":"active"}),n.mainPM.totalEvents+=i.agentEvents.length;t.forEach((e,t)=>{const a=this.getInferredAgent(t);a&&"main_agent"===a.type&&(n.mainPM.ownEvents.push({eventIndex:t,event:e}),n.mainPM.totalEvents++)});const a=new Map;t.forEach((t,n)=>{const s=this.getInferredAgent(n);if(s&&"subagent"===s.type){let i=!0;for(const[t,a]of e)if(a.agentEvents.some(e=>e.eventIndex===n)){i=!1;break}if(i){const e=s.agentName;a.has(e)||a.set(e,[]),a.get(e).push({eventIndex:n,event:t,inference:s})}}});for(const[s,i]of a)n.impliedPM.delegations.push({id:`implied_${s}`,agentName:s,taskContext:"No explicit PM delegation",events:i,startTime:i[0].event.timestamp,endTime:i[i.length-1].event.timestamp,status:"completed"}),n.impliedPM.totalEvents+=i.length;return n}extractTaskContext(e){if(!e)return"Unknown task";const t=e.tool_parameters||e.data?.tool_parameters||{};return t.task||t.request||t.description||"Task delegation"}identifyOrphanSubagents(e){for(const[t,n]of this.state.subagentStartEvents)for(const a of n){const n=a.eventIndex,s=new Date(a.timestamp).getTime();let i=!1;for(let a=Math.max(0,n-20);a<n;a++){const n=e[a];if(!n)continue;const o=s-new Date(n.timestamp).getTime();if("Task"===n.tool_name&&o>=0&&o<1e4){const e=this.state.eventAgentMap.get(a);if(e&&e.agentName===t){i=!0;break}}}i||this.state.orphanSubagents.set(n,{agentName:t,timestamp:a.timestamp,sessionId:a.sessionId,event:a.event,groupingKey:null})}this.groupOrphanSubagents(5e3)}groupOrphanSubagents(e){const t=Array.from(this.state.orphanSubagents.values()).sort((e,t)=>new Date(e.timestamp)-new Date(t.timestamp));let n=null,a=null;for(const s of t){const t=new Date(s.timestamp).getTime();(!n||a&&t-a>e)&&(n=`implied_pm_${s.sessionId}_${t}`),s.groupingKey=n,a=t}}isOrphanSubagent(e){return this.state.orphanSubagents.has(e)}getOrphanContext(e){return this.state.orphanSubagents.get(e)||null}getOrphanGroups(){const e=new Map;for(const t of this.state.orphanSubagents.values()){const n=t.groupingKey;e.has(n)||e.set(n,[]),e.get(n).push(t)}return e}getUniqueAgentInstances(){const e=new Map;for(const[a,s]of this.state.pmDelegations){const t=s.agentName;e.has(t)||e.set(t,{id:`consolidated_${t}`,type:"consolidated_agent",agentName:t,delegations:[],pmCalls:[],allEvents:[],firstTimestamp:s.timestamp,lastTimestamp:s.timestamp,totalEventCount:s.agentEvents.length,delegationCount:1});const n=e.get(t);n.delegations.push({id:a,pmCall:s.pmCall,timestamp:s.timestamp,eventCount:s.agentEvents.length,startIndex:s.startIndex,endIndex:s.endIndex,events:s.agentEvents}),s.pmCall&&n.pmCalls.push(s.pmCall),n.allEvents=n.allEvents.concat(s.agentEvents),new Date(s.timestamp)<new Date(n.firstTimestamp)&&(n.firstTimestamp=s.timestamp),new Date(s.timestamp)>new Date(n.lastTimestamp)&&(n.lastTimestamp=s.timestamp),n.totalEventCount+=s.agentEvents.length,n.delegationCount++}const t=this.eventViewer.events;for(let a=0;a<t.length;a++){const n=this.getInferredAgent(a);n&&"subagent"===n.type&&!e.has(n.agentName)&&e.set(n.agentName,{id:`consolidated_${n.agentName}`,type:"consolidated_agent",agentName:n.agentName,delegations:[{id:`implied_pm_${n.agentName}_${a}`,pmCall:null,timestamp:t[a].timestamp,eventCount:1,startIndex:a,endIndex:null,events:[{eventIndex:a,event:t[a],inference:n}]}],pmCalls:[],allEvents:[{eventIndex:a,event:t[a],inference:n}],firstTimestamp:t[a].timestamp,lastTimestamp:t[a].timestamp,totalEventCount:1,delegationCount:1,isImplied:!0})}const n=Array.from(e.values()).sort((e,t)=>new Date(e.firstTimestamp)-new Date(t.firstTimestamp));return console.log("Consolidated unique agents:",{total_unique_agents:n.length,agents:n.map(e=>({name:e.agentName,delegations:e.delegationCount,totalEvents:e.totalEventCount}))}),n}};
|
|
2
2
|
//# sourceMappingURL=agent-inference.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
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
|
|
@@ -0,0 +1,2 @@
|
|
|
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
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{E as e,E as r}from"./event-viewer.js";export{e as EventProcessor,r as default};
|
|
2
2
|
//# sourceMappingURL=event-processor.js.map
|