claude-mpm 4.16.0__py3-none-any.whl → 4.25.10__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/VERSION +1 -1
- claude_mpm/agents/BASE_ENGINEER.md +286 -0
- claude_mpm/agents/BASE_PM.md +272 -23
- claude_mpm/agents/OUTPUT_STYLE.md +3 -48
- claude_mpm/agents/PM_INSTRUCTIONS.md +1821 -32
- claude_mpm/agents/WORKFLOW.md +75 -2
- claude_mpm/agents/agent_loader.py +4 -4
- claude_mpm/agents/base_agent.json +6 -3
- claude_mpm/agents/frontmatter_validator.py +1 -1
- claude_mpm/agents/templates/api_qa.json +5 -2
- claude_mpm/agents/templates/circuit_breakers.md +108 -2
- claude_mpm/agents/templates/documentation.json +33 -6
- claude_mpm/agents/templates/engineer.json +5 -1
- claude_mpm/agents/templates/javascript_engineer_agent.json +380 -0
- claude_mpm/agents/templates/php-engineer.json +10 -4
- claude_mpm/agents/templates/pm_red_flags.md +89 -19
- claude_mpm/agents/templates/project_organizer.json +7 -3
- claude_mpm/agents/templates/python_engineer.json +8 -3
- claude_mpm/agents/templates/qa.json +2 -1
- claude_mpm/agents/templates/react_engineer.json +1 -0
- claude_mpm/agents/templates/research.json +82 -12
- claude_mpm/agents/templates/rust_engineer.json +12 -7
- claude_mpm/agents/templates/security.json +4 -4
- claude_mpm/agents/templates/svelte-engineer.json +225 -0
- claude_mpm/agents/templates/tauri_engineer.json +274 -0
- claude_mpm/agents/templates/ticketing.json +10 -6
- claude_mpm/agents/templates/version_control.json +4 -2
- claude_mpm/agents/templates/web_qa.json +2 -1
- claude_mpm/cli/README.md +253 -0
- claude_mpm/cli/__init__.py +11 -1
- claude_mpm/cli/commands/__init__.py +2 -0
- claude_mpm/cli/commands/aggregate.py +1 -1
- claude_mpm/cli/commands/analyze.py +3 -3
- claude_mpm/cli/commands/cleanup.py +1 -1
- claude_mpm/cli/commands/configure_agent_display.py +4 -4
- claude_mpm/cli/commands/debug.py +12 -12
- claude_mpm/cli/commands/hook_errors.py +277 -0
- claude_mpm/cli/commands/mcp_install_commands.py +1 -1
- claude_mpm/cli/commands/mcp_install_commands.py.backup +284 -0
- claude_mpm/cli/commands/mpm_init/README.md +365 -0
- claude_mpm/cli/commands/mpm_init/__init__.py +73 -0
- claude_mpm/cli/commands/mpm_init/core.py +573 -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 +67 -1
- claude_mpm/cli/commands/run.py +124 -128
- claude_mpm/cli/commands/skills.py +922 -0
- claude_mpm/cli/executor.py +58 -0
- claude_mpm/cli/interactive/agent_wizard.py +5 -5
- claude_mpm/cli/parsers/base_parser.py +35 -0
- claude_mpm/cli/parsers/mpm_init_parser.py +42 -0
- claude_mpm/cli/parsers/skills_parser.py +275 -0
- claude_mpm/cli/startup.py +168 -8
- claude_mpm/cli/startup_display.py +480 -0
- claude_mpm/cli/utils.py +1 -1
- claude_mpm/cli_module/commands.py +1 -1
- claude_mpm/cli_module/refactoring_guide.md +253 -0
- claude_mpm/commands/mpm-auto-configure.md +52 -0
- claude_mpm/commands/mpm-help.md +6 -0
- claude_mpm/commands/mpm-init.md +130 -8
- claude_mpm/commands/mpm-resume.md +372 -0
- claude_mpm/commands/mpm-tickets.md +56 -7
- claude_mpm/commands/mpm-version.md +113 -0
- claude_mpm/commands/mpm.md +2 -0
- claude_mpm/config/agent_capabilities.yaml +658 -0
- claude_mpm/config/agent_config.py +2 -2
- claude_mpm/config/async_logging_config.yaml +145 -0
- claude_mpm/constants.py +24 -0
- claude_mpm/core/.claude-mpm/logs/hooks_20250730.log +34 -0
- claude_mpm/core/api_validator.py +1 -1
- claude_mpm/core/claude_runner.py +14 -1
- claude_mpm/core/config.py +50 -0
- claude_mpm/core/constants.py +1 -1
- claude_mpm/core/factories.py +1 -1
- claude_mpm/core/framework/processors/metadata_processor.py +1 -1
- claude_mpm/core/hook_error_memory.py +381 -0
- claude_mpm/core/hook_manager.py +41 -2
- claude_mpm/core/interactive_session.py +48 -3
- claude_mpm/core/interfaces.py +56 -1
- claude_mpm/core/logger.py +3 -1
- claude_mpm/core/oneshot_session.py +39 -0
- claude_mpm/core/optimized_agent_loader.py +3 -3
- claude_mpm/d2/.gitignore +22 -0
- claude_mpm/d2/ARCHITECTURE_COMPARISON.md +273 -0
- claude_mpm/d2/FLASK_INTEGRATION.md +156 -0
- claude_mpm/d2/IMPLEMENTATION_SUMMARY.md +452 -0
- claude_mpm/d2/QUICKSTART.md +186 -0
- claude_mpm/d2/README.md +232 -0
- claude_mpm/d2/STORE_FIX_SUMMARY.md +167 -0
- claude_mpm/d2/SVELTE5_STORES_GUIDE.md +180 -0
- claude_mpm/d2/TESTING.md +288 -0
- claude_mpm/d2/index.html +118 -0
- claude_mpm/d2/package.json +19 -0
- claude_mpm/d2/src/App.svelte +110 -0
- claude_mpm/d2/src/components/Header.svelte +153 -0
- claude_mpm/d2/src/components/MainContent.svelte +74 -0
- claude_mpm/d2/src/components/Sidebar.svelte +85 -0
- claude_mpm/d2/src/components/tabs/EventsTab.svelte +326 -0
- claude_mpm/d2/src/lib/socketio.js +144 -0
- claude_mpm/d2/src/main.js +7 -0
- claude_mpm/d2/src/stores/events.js +114 -0
- claude_mpm/d2/src/stores/socket.js +108 -0
- claude_mpm/d2/src/stores/theme.js +65 -0
- claude_mpm/d2/svelte.config.js +12 -0
- claude_mpm/d2/vite.config.js +15 -0
- claude_mpm/dashboard/.claude-mpm/memories/README.md +36 -0
- claude_mpm/dashboard/BUILD_NUMBER +1 -0
- claude_mpm/dashboard/README.md +121 -0
- claude_mpm/dashboard/VERSION +1 -0
- claude_mpm/dashboard/react/components/DataInspector/DataInspector.tsx +273 -0
- claude_mpm/dashboard/react/components/ErrorBoundary.tsx +75 -0
- claude_mpm/dashboard/react/components/EventViewer/EventViewer.tsx +141 -0
- claude_mpm/dashboard/react/components/shared/ConnectionStatus.tsx +36 -0
- claude_mpm/dashboard/react/components/shared/FilterBar.tsx +89 -0
- claude_mpm/dashboard/react/contexts/DashboardContext.tsx +215 -0
- claude_mpm/dashboard/react/entries/events.tsx +165 -0
- claude_mpm/dashboard/react/hooks/useEvents.ts +191 -0
- claude_mpm/dashboard/react/hooks/useSocket.ts +225 -0
- claude_mpm/dashboard/static/built/REFACTORING_SUMMARY.md +170 -0
- claude_mpm/dashboard/static/built/components/activity-tree.js.map +1 -0
- claude_mpm/dashboard/static/built/components/agent-hierarchy.js +101 -101
- claude_mpm/dashboard/static/built/components/agent-inference.js.map +1 -0
- claude_mpm/dashboard/static/built/components/build-tracker.js +59 -59
- claude_mpm/dashboard/static/built/components/code-simple.js +107 -107
- claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +29 -29
- claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +24 -24
- claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +27 -27
- claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +25 -25
- claude_mpm/dashboard/static/built/components/code-tree.js.map +1 -0
- claude_mpm/dashboard/static/built/components/code-viewer.js.map +1 -0
- claude_mpm/dashboard/static/built/components/connection-debug.js +101 -101
- claude_mpm/dashboard/static/built/components/diff-viewer.js +113 -113
- claude_mpm/dashboard/static/built/components/event-processor.js.map +1 -0
- claude_mpm/dashboard/static/built/components/event-viewer.js.map +1 -0
- claude_mpm/dashboard/static/built/components/export-manager.js.map +1 -0
- claude_mpm/dashboard/static/built/components/file-change-tracker.js +57 -57
- claude_mpm/dashboard/static/built/components/file-change-viewer.js +74 -74
- claude_mpm/dashboard/static/built/components/file-tool-tracker.js.map +1 -0
- claude_mpm/dashboard/static/built/components/file-viewer.js.map +1 -0
- claude_mpm/dashboard/static/built/components/hud-library-loader.js.map +1 -0
- claude_mpm/dashboard/static/built/components/hud-manager.js.map +1 -0
- claude_mpm/dashboard/static/built/components/hud-visualizer.js.map +1 -0
- claude_mpm/dashboard/static/built/components/module-viewer.js.map +1 -0
- claude_mpm/dashboard/static/built/components/session-manager.js.map +1 -0
- claude_mpm/dashboard/static/built/components/socket-manager.js.map +1 -0
- claude_mpm/dashboard/static/built/components/ui-state-manager.js.map +1 -0
- claude_mpm/dashboard/static/built/components/unified-data-viewer.js.map +1 -0
- claude_mpm/dashboard/static/built/components/working-directory.js.map +1 -0
- claude_mpm/dashboard/static/built/connection-manager.js +76 -76
- claude_mpm/dashboard/static/built/dashboard.js.map +1 -0
- claude_mpm/dashboard/static/built/extension-error-handler.js +22 -22
- claude_mpm/dashboard/static/built/react/events.js.map +1 -0
- claude_mpm/dashboard/static/built/shared/dom-helpers.js +9 -9
- claude_mpm/dashboard/static/built/shared/event-bus.js +5 -5
- claude_mpm/dashboard/static/built/shared/logger.js +16 -16
- claude_mpm/dashboard/static/built/shared/tooltip-service.js +6 -6
- claude_mpm/dashboard/static/built/socket-client.js.map +1 -0
- claude_mpm/dashboard/static/css/activity.css +69 -69
- claude_mpm/dashboard/static/css/connection-status.css +10 -10
- claude_mpm/dashboard/static/css/dashboard.css +15 -15
- claude_mpm/dashboard/static/index.html +22 -22
- claude_mpm/dashboard/static/js/REFACTORING_SUMMARY.md +170 -0
- claude_mpm/dashboard/static/js/components/activity-tree.js +178 -178
- claude_mpm/dashboard/static/js/components/agent-hierarchy.js +101 -101
- claude_mpm/dashboard/static/js/components/agent-inference.js +31 -31
- claude_mpm/dashboard/static/js/components/build-tracker.js +59 -59
- claude_mpm/dashboard/static/js/components/code-simple.js +107 -107
- claude_mpm/dashboard/static/js/components/connection-debug.js +101 -101
- claude_mpm/dashboard/static/js/components/diff-viewer.js +113 -113
- claude_mpm/dashboard/static/js/components/event-viewer.js +12 -12
- claude_mpm/dashboard/static/js/components/file-change-tracker.js +57 -57
- claude_mpm/dashboard/static/js/components/file-change-viewer.js +74 -74
- claude_mpm/dashboard/static/js/components/file-tool-tracker.js +6 -6
- claude_mpm/dashboard/static/js/components/file-viewer.js +42 -42
- claude_mpm/dashboard/static/js/components/module-viewer.js +27 -27
- claude_mpm/dashboard/static/js/components/session-manager.js +14 -14
- claude_mpm/dashboard/static/js/components/socket-manager.js +1 -1
- claude_mpm/dashboard/static/js/components/ui-state-manager.js +14 -14
- claude_mpm/dashboard/static/js/components/unified-data-viewer.js +110 -110
- claude_mpm/dashboard/static/js/components/working-directory.js +8 -8
- claude_mpm/dashboard/static/js/connection-manager.js +76 -76
- claude_mpm/dashboard/static/js/dashboard.js +76 -58
- claude_mpm/dashboard/static/js/extension-error-handler.js +22 -22
- claude_mpm/dashboard/static/js/shared/dom-helpers.js +9 -9
- claude_mpm/dashboard/static/js/shared/event-bus.js +5 -5
- claude_mpm/dashboard/static/js/shared/logger.js +16 -16
- claude_mpm/dashboard/static/js/shared/tooltip-service.js +6 -6
- claude_mpm/dashboard/static/js/socket-client.js +138 -121
- claude_mpm/dashboard/static/navigation-test-results.md +118 -0
- claude_mpm/dashboard/static/production/main.html +21 -21
- claude_mpm/dashboard/static/test-archive/dashboard.html +22 -22
- claude_mpm/dashboard/templates/.claude-mpm/memories/README.md +36 -0
- claude_mpm/dashboard/templates/.claude-mpm/memories/engineer_agent.md +39 -0
- claude_mpm/dashboard/templates/.claude-mpm/memories/version_control_agent.md +38 -0
- claude_mpm/dashboard/templates/code_simple.html +23 -23
- claude_mpm/dashboard/templates/index.html +18 -18
- claude_mpm/hooks/README.md +143 -0
- claude_mpm/hooks/__init__.py +8 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +3 -1
- claude_mpm/hooks/claude_hooks/hook_handler.py +24 -7
- claude_mpm/hooks/claude_hooks/installer.py +45 -0
- claude_mpm/hooks/claude_hooks/response_tracking.py +35 -1
- claude_mpm/hooks/session_resume_hook.py +121 -0
- claude_mpm/hooks/templates/README.md +180 -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/templates/settings.json.example +147 -0
- claude_mpm/models/resume_log.py +340 -0
- claude_mpm/schemas/agent_schema.json +596 -0
- claude_mpm/schemas/frontmatter_schema.json +165 -0
- claude_mpm/scripts/claude-hook-handler.sh +3 -3
- claude_mpm/scripts/start_activity_logging.py +3 -1
- claude_mpm/services/agents/auto_config_manager.py +1 -1
- claude_mpm/services/agents/deployment/agent_configuration_manager.py +1 -1
- claude_mpm/services/agents/deployment/agent_format_converter.py +1 -1
- claude_mpm/services/agents/deployment/agent_metrics_collector.py +3 -3
- claude_mpm/services/agents/deployment/agent_record_service.py +1 -1
- claude_mpm/services/agents/deployment/agent_validator.py +17 -1
- claude_mpm/services/agents/deployment/async_agent_deployment.py +1 -1
- claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -3
- claude_mpm/services/agents/deployment/local_template_deployment.py +1 -1
- claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +2 -2
- claude_mpm/services/agents/loading/framework_agent_loader.py +8 -8
- claude_mpm/services/agents/local_template_manager.py +4 -2
- claude_mpm/services/agents/recommender.py +47 -0
- claude_mpm/services/cli/resume_service.py +617 -0
- claude_mpm/services/cli/session_manager.py +87 -0
- claude_mpm/services/cli/session_pause_manager.py +504 -0
- claude_mpm/services/cli/session_resume_helper.py +372 -0
- claude_mpm/services/cli/unified_dashboard_manager.py +1 -1
- claude_mpm/services/core/base.py +26 -11
- claude_mpm/services/core/interfaces.py +56 -1
- claude_mpm/services/core/models/agent_config.py +3 -0
- claude_mpm/services/core/models/process.py +4 -0
- claude_mpm/services/core/path_resolver.py +1 -1
- claude_mpm/services/diagnostics/checks/agent_check.py +0 -2
- claude_mpm/services/diagnostics/checks/instructions_check.py +1 -2
- claude_mpm/services/diagnostics/checks/mcp_check.py +0 -1
- claude_mpm/services/diagnostics/checks/monitor_check.py +0 -1
- claude_mpm/services/diagnostics/doctor_reporter.py +6 -4
- claude_mpm/services/diagnostics/models.py +21 -0
- claude_mpm/services/event_bus/README.md +244 -0
- claude_mpm/services/event_bus/direct_relay.py +3 -3
- claude_mpm/services/event_bus/event_bus.py +36 -3
- claude_mpm/services/event_bus/relay.py +23 -7
- claude_mpm/services/events/README.md +303 -0
- claude_mpm/services/events/consumers/logging.py +1 -2
- claude_mpm/services/framework_claude_md_generator/README.md +119 -0
- claude_mpm/services/infrastructure/monitoring/resources.py +1 -1
- claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
- claude_mpm/services/local_ops/__init__.py +2 -0
- claude_mpm/services/local_ops/process_manager.py +1 -1
- claude_mpm/services/local_ops/resource_monitor.py +2 -2
- claude_mpm/services/mcp_config_manager.py +7 -131
- claude_mpm/services/mcp_gateway/README.md +185 -0
- claude_mpm/services/mcp_gateway/auto_configure.py +31 -25
- claude_mpm/services/mcp_gateway/config/configuration.py +1 -1
- claude_mpm/services/mcp_gateway/core/process_pool.py +19 -10
- claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -2
- claude_mpm/services/mcp_gateway/tools/document_summarizer.py +1 -1
- claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +26 -21
- claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +6 -2
- claude_mpm/services/memory/failure_tracker.py +19 -4
- claude_mpm/services/memory/optimizer.py +1 -1
- claude_mpm/services/model/model_router.py +8 -9
- claude_mpm/services/monitor/daemon.py +1 -1
- claude_mpm/services/monitor/server.py +2 -2
- claude_mpm/services/native_agent_converter.py +356 -0
- claude_mpm/services/port_manager.py +1 -1
- claude_mpm/services/project/documentation_manager.py +2 -1
- claude_mpm/services/project/toolchain_analyzer.py +3 -1
- claude_mpm/services/runner_configuration_service.py +1 -0
- claude_mpm/services/self_upgrade_service.py +165 -7
- claude_mpm/services/session_manager.py +205 -1
- claude_mpm/services/skills_config.py +547 -0
- claude_mpm/services/skills_deployer.py +955 -0
- claude_mpm/services/socketio/handlers/connection.py +1 -1
- claude_mpm/services/socketio/handlers/connection.py.backup +217 -0
- claude_mpm/services/socketio/handlers/git.py +2 -2
- claude_mpm/services/socketio/handlers/hook.py.backup +154 -0
- claude_mpm/services/static/.gitkeep +2 -0
- claude_mpm/services/system_instructions_service.py +1 -3
- claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +0 -3
- claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +0 -1
- claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +1 -1
- claude_mpm/services/unified/deployment_strategies/local.py +1 -1
- claude_mpm/services/version_control/VERSION +1 -0
- claude_mpm/services/version_control/conflict_resolution.py +6 -4
- claude_mpm/services/version_service.py +104 -1
- claude_mpm/services/visualization/mermaid_generator.py +2 -3
- claude_mpm/skills/__init__.py +21 -0
- claude_mpm/skills/agent_skills_injector.py +324 -0
- claude_mpm/skills/bundled/.gitkeep +2 -0
- claude_mpm/skills/bundled/LICENSE_ATTRIBUTIONS.md +79 -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/git-worktrees.md +317 -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/stacked-prs.md +251 -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/find-polluter.sh +63 -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/INTEGRATION.md +611 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/README.md +596 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/SKILL.md +260 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/examples/nextjs-env-structure.md +315 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/frameworks.md +436 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/security.md +433 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/synchronization.md +452 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/troubleshooting.md +404 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/validation.md +420 -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/LICENSE.txt +202 -0
- claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
- claude_mpm/skills/bundled/main/artifacts-builder/scripts/bundle-artifact.sh +54 -0
- claude_mpm/skills/bundled/main/artifacts-builder/scripts/init-artifact.sh +322 -0
- claude_mpm/skills/bundled/main/artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
- claude_mpm/skills/bundled/main/internal-comms/LICENSE.txt +202 -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/LICENSE.txt +202 -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/mcp-builder/scripts/example_evaluation.xml +22 -0
- claude_mpm/skills/bundled/main/mcp-builder/scripts/requirements.txt +2 -0
- claude_mpm/skills/bundled/main/skill-creator/LICENSE.txt +202 -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/react/flexlayout-react.md +742 -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/tauri/tauri-async-patterns.md +495 -0
- claude_mpm/skills/bundled/tauri/tauri-build-deploy.md +599 -0
- claude_mpm/skills/bundled/tauri/tauri-command-patterns.md +535 -0
- claude_mpm/skills/bundled/tauri/tauri-error-handling.md +613 -0
- claude_mpm/skills/bundled/tauri/tauri-event-system.md +648 -0
- claude_mpm/skills/bundled/tauri/tauri-file-system.md +673 -0
- claude_mpm/skills/bundled/tauri/tauri-frontend-integration.md +767 -0
- claude_mpm/skills/bundled/tauri/tauri-performance.md +669 -0
- claude_mpm/skills/bundled/tauri/tauri-state-management.md +573 -0
- claude_mpm/skills/bundled/tauri/tauri-testing.md +384 -0
- claude_mpm/skills/bundled/tauri/tauri-window-management.md +628 -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/example.ts +158 -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/test-quality-inspector/SKILL.md +458 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/examples/example-inspection-report.md +411 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/assertion-quality.md +317 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/inspection-checklist.md +270 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/red-flags.md +436 -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/LICENSE.txt +202 -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 +97 -9
- claude_mpm/skills/skills_registry.py +347 -0
- claude_mpm/skills/skills_service.py +739 -0
- claude_mpm/templates/questions/EXAMPLES.md +501 -0
- claude_mpm/templates/questions/__init__.py +43 -0
- claude_mpm/templates/questions/base.py +193 -0
- claude_mpm/templates/questions/pr_strategy.py +314 -0
- claude_mpm/templates/questions/project_init.py +388 -0
- claude_mpm/templates/questions/ticket_mgmt.py +397 -0
- claude_mpm/tools/README_SOCKETIO_DEBUG.md +224 -0
- claude_mpm/tools/__main__.py +8 -8
- claude_mpm/tools/code_tree_analyzer/README.md +64 -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/utils/agent_dependency_loader.py +5 -5
- claude_mpm/utils/dependency_cache.py +3 -1
- claude_mpm/utils/gitignore.py +241 -0
- claude_mpm/utils/log_cleanup.py +3 -3
- claude_mpm/utils/robust_installer.py +3 -5
- claude_mpm/utils/structured_questions.py +619 -0
- claude_mpm-4.25.10.dist-info/METADATA +789 -0
- {claude_mpm-4.16.0.dist-info → claude_mpm-4.25.10.dist-info}/RECORD +485 -240
- claude_mpm/agents/INSTRUCTIONS_OLD_DEPRECATED.md +0 -602
- claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -17
- claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +0 -3
- claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +0 -39
- claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +0 -400
- claude_mpm/cli/commands/mpm_init.py +0 -2008
- claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
- claude_mpm/dashboard/static/archive/activity_dashboard_test.html +0 -61
- claude_mpm/dashboard/static/archive/test_activity_connection.html +0 -179
- claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +0 -68
- claude_mpm/dashboard/static/archive/test_dashboard.html +0 -409
- claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +0 -519
- claude_mpm/dashboard/static/archive/test_dashboard_verification.html +0 -181
- claude_mpm/dashboard/static/archive/test_file_data.html +0 -315
- claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +0 -243
- claude_mpm/dashboard/static/archive/test_file_tree_fix.html +0 -234
- claude_mpm/dashboard/static/archive/test_file_tree_rename.html +0 -117
- claude_mpm/dashboard/static/archive/test_file_tree_tab.html +0 -115
- claude_mpm/dashboard/static/archive/test_file_viewer.html +0 -224
- claude_mpm/dashboard/static/archive/test_final_activity.html +0 -220
- claude_mpm/dashboard/static/archive/test_tab_fix.html +0 -139
- claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +0 -1
- claude_mpm/dashboard/static/dist/components/activity-tree.js +0 -2
- claude_mpm/dashboard/static/dist/components/agent-inference.js +0 -2
- claude_mpm/dashboard/static/dist/components/code-tree.js +0 -2
- claude_mpm/dashboard/static/dist/components/code-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/event-processor.js +0 -2
- claude_mpm/dashboard/static/dist/components/event-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/export-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +0 -2
- claude_mpm/dashboard/static/dist/components/file-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-library-loader.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-visualizer.js +0 -2
- claude_mpm/dashboard/static/dist/components/module-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/session-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/socket-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/ui-state-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/working-directory.js +0 -2
- claude_mpm/dashboard/static/dist/dashboard.js +0 -2
- claude_mpm/dashboard/static/dist/react/events.js +0 -30
- claude_mpm/dashboard/static/dist/socket-client.js +0 -2
- claude_mpm/dashboard/static/test-archive/test_debug.html +0 -25
- claude_mpm/tools/code_tree_analyzer.py +0 -1825
- claude_mpm-4.16.0.dist-info/METADATA +0 -453
- {claude_mpm-4.16.0.dist-info → claude_mpm-4.25.10.dist-info}/WHEEL +0 -0
- {claude_mpm-4.16.0.dist-info → claude_mpm-4.25.10.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.16.0.dist-info → claude_mpm-4.25.10.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.16.0.dist-info → claude_mpm-4.25.10.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard.js","sources":["../js/dashboard.js"],"sourcesContent":["/**\n * Refactored Dashboard Coordinator\n *\n * Main coordinator class that orchestrates all dashboard modules while maintaining\n * backward compatibility with the original dashboard interface.\n *\n * WHY: This refactored version breaks down the monolithic 4,133-line dashboard\n * into manageable, focused modules while preserving all existing functionality.\n * Each module handles a specific concern, improving maintainability and testability.\n *\n * DESIGN DECISION: Acts as a thin coordinator layer that initializes modules,\n * manages inter-module communication through events, and provides backward\n * compatibility for existing code that depends on the dashboard interface.\n */\n\n// NOTE: Components are loaded as ES6 modules via index.html\n// They expose their classes globally for backward compatibility\n// Commenting out ES6 imports to avoid module resolution errors\n\n// import { SocketManager } from './components/socket-manager.js';\n// import { EventViewer } from './components/event-viewer.js';\n// import { ModuleViewer } from './components/module-viewer.js';\n// import { SessionManager } from './components/session-manager.js';\n// import { AgentInference } from './components/agent-inference.js';\n// import { AgentHierarchy } from './components/agent-hierarchy.js';\n// import { UIStateManager } from './components/ui-state-manager.js';\n// import { EventProcessor } from './components/event-processor.js';\n// import { ExportManager } from './components/export-manager.js';\n// import { WorkingDirectoryManager } from './components/working-directory.js';\n// import { FileToolTracker } from './components/file-tool-tracker.js';\n// import { BuildTracker } from './components/build-tracker.js';\n// import { UnifiedDataViewer } from './components/unified-data-viewer.js';\n\nclass Dashboard {\n constructor() {\n // Core components (existing)\n this.eventViewer = null;\n this.moduleViewer = null;\n this.sessionManager = null;\n \n // Retry prevention\n this.activityTreeRetryCount = 0;\n this.maxRetryAttempts = 10;\n\n // New modular components\n this.socketManager = null;\n this.agentInference = null;\n this.agentHierarchy = null;\n this.uiStateManager = null;\n this.eventProcessor = null;\n this.exportManager = null;\n this.workingDirectoryManager = null;\n this.fileToolTracker = null;\n this.buildTracker = null;\n\n // Initialize the dashboard\n this.init();\n }\n\n /**\n * Initialize the dashboard and all modules\n */\n init() {\n console.log('Initializing refactored Claude MPM Dashboard...');\n\n try {\n // Fetch server configuration first\n this.fetchServerConfig();\n \n // Initialize modules in dependency order\n this.initializeSocketManager();\n this.initializeCoreComponents();\n this.initializeBuildTracker();\n this.initializeAgentInference();\n this.initializeAgentHierarchy();\n this.initializeUIStateManager();\n this.initializeWorkingDirectoryManager();\n this.initializeFileToolTracker();\n this.initializeEventProcessor();\n this.initializeExportManager();\n\n // Set up inter-module communication\n this.setupModuleInteractions();\n\n // Initialize from URL parameters\n this.initializeFromURL();\n\n console.log('Claude MPM Dashboard initialized successfully');\n } catch (error) {\n console.error('Error during dashboard initialization:', error);\n // Re-throw to be caught by DOMContentLoaded handler\n throw error;\n }\n }\n \n /**\n * Fetch server configuration for dashboard initialization\n */\n fetchServerConfig() {\n fetch('/api/config')\n .then(response => response.json())\n .then(config => {\n // Store config globally for other components\n window.dashboardConfig = config;\n \n // Update initial UI elements if they exist\n const workingDirEl = document.getElementById('working-dir-path');\n if (workingDirEl && config.workingDirectory) {\n workingDirEl.textContent = config.workingDirectory;\n }\n \n const gitBranchEl = document.getElementById('footer-git-branch');\n if (gitBranchEl && config.gitBranch) {\n gitBranchEl.textContent = config.gitBranch;\n }\n \n console.log('Dashboard configuration loaded:', config);\n })\n .catch(error => {\n console.warn('Failed to fetch server config:', error);\n // Set default config as fallback\n window.dashboardConfig = {\n workingDirectory: '.',\n gitBranch: 'Unknown'\n };\n });\n }\n \n /**\n * Validate that all critical components are initialized\n * WHY: Ensures dashboard is in a valid state after initialization\n */\n validateInitialization() {\n const criticalComponents = [\n { name: 'socketManager', component: this.socketManager },\n { name: 'eventViewer', component: this.eventViewer },\n { name: 'agentHierarchy', component: this.agentHierarchy }\n ];\n \n const missing = criticalComponents.filter(c => !c.component);\n if (missing.length > 0) {\n console.warn('Missing critical components:', missing.map(c => c.name));\n }\n }\n\n /**\n * Post-initialization setup that requires window.dashboard to be set\n * WHY: Some components need to reference window.dashboard but it's not available\n * during constructor execution. This method is called after the Dashboard instance\n * is assigned to window.dashboard, ensuring proper initialization order.\n * \n * DESIGN DECISION: Separate post-init phase prevents \"cannot read property of undefined\"\n * errors when components try to access window.dashboard during construction.\n */\n postInit() {\n try {\n // Set global reference for agent hierarchy after dashboard is available\n if (this.agentHierarchy) {\n window.dashboard.agentHierarchy = this.agentHierarchy;\n }\n \n // Initialize any other components that need window.dashboard\n this.validateInitialization();\n } catch (error) {\n console.error('Error in dashboard postInit:', error);\n // Continue execution - non-critical error\n }\n }\n\n /**\n * Initialize socket manager\n */\n initializeSocketManager() {\n this.socketManager = new SocketManager();\n\n // Set up connection controls\n this.socketManager.setupConnectionControls();\n\n // Backward compatibility\n this.socketClient = this.socketManager.getSocketClient();\n window.socketClient = this.socketClient;\n }\n\n /**\n * Initialize core existing components\n */\n initializeCoreComponents() {\n // Initialize existing components with socket client\n this.eventViewer = new EventViewer('events-list', this.socketClient);\n this.moduleViewer = new ModuleViewer();\n this.sessionManager = new SessionManager(this.socketClient);\n\n // Backward compatibility\n window.eventViewer = this.eventViewer;\n window.moduleViewer = this.moduleViewer;\n window.sessionManager = this.sessionManager;\n }\n\n /**\n * Initialize build tracker\n */\n initializeBuildTracker() {\n this.buildTracker = new BuildTracker();\n \n // Set the socket client for receiving updates\n this.buildTracker.setSocketClient(this.socketClient);\n \n // Mount to header with retry logic for DOM readiness\n const mountBuildTracker = () => {\n const headerTitle = document.querySelector('.header-title');\n if (headerTitle) {\n // Insert after the title and status badge\n this.buildTracker.mount(headerTitle);\n console.log('BuildTracker mounted successfully');\n } else {\n console.warn('Header-title element not found for build tracker, will retry');\n // Retry after a short delay if DOM is still being constructed\n setTimeout(mountBuildTracker, 100);\n }\n };\n \n // Try to mount immediately, with retry logic if needed\n mountBuildTracker();\n \n // Make available globally for debugging\n window.buildTracker = this.buildTracker;\n }\n\n /**\n * Initialize agent inference system\n */\n initializeAgentInference() {\n this.agentInference = new AgentInference(this.eventViewer);\n this.agentInference.initialize();\n }\n \n /**\n * Initialize agent hierarchy component\n * WHY: Creates the agent hierarchy visualization component but defers global\n * reference setting to postInit() to avoid initialization order issues.\n */\n initializeAgentHierarchy() {\n try {\n this.agentHierarchy = new AgentHierarchy(this.agentInference, this.eventViewer);\n // Global reference will be set in postInit() after window.dashboard exists\n } catch (error) {\n console.error('Failed to initialize agent hierarchy:', error);\n // Create a stub to prevent further errors\n this.agentHierarchy = {\n render: () => '<div class=\"error\">Agent hierarchy unavailable</div>',\n expandAllNodes: () => {},\n collapseAllNodes: () => {},\n updateWithNewEvents: () => {}\n };\n }\n }\n\n /**\n * Initialize UI state manager\n */\n initializeUIStateManager() {\n this.uiStateManager = new UIStateManager();\n this.setupTabFilters(); // Set up filters after UI state manager\n }\n\n /**\n * Initialize working directory manager\n */\n initializeWorkingDirectoryManager() {\n this.workingDirectoryManager = new WorkingDirectoryManager(this.socketManager);\n }\n\n /**\n * Initialize file-tool tracker\n */\n initializeFileToolTracker() {\n this.fileToolTracker = new FileToolTracker(this.agentInference, this.workingDirectoryManager);\n }\n\n /**\n * Initialize event processor\n */\n initializeEventProcessor() {\n this.eventProcessor = new EventProcessor(this.eventViewer, this.agentInference);\n }\n\n\n /**\n * Initialize export manager\n */\n initializeExportManager() {\n this.exportManager = new ExportManager(this.eventViewer);\n }\n\n /**\n * Set up interactions between modules\n */\n setupModuleInteractions() {\n // Socket events to update file operations and tool calls\n this.socketManager.onEventUpdate((events) => {\n console.log('[Dashboard] Processing event update with', events.length, 'events');\n\n // Debug: Log some sample events to see their structure\n if (events.length > 0) {\n console.log('[Dashboard] Sample event structure:', {\n first_event: events[0],\n has_tool_events: events.some(e => e.tool_name || (e.data && e.data.tool_name)),\n hook_events: events.filter(e => e.type === 'hook').length,\n tool_subtypes: events.filter(e => e.subtype === 'pre_tool' || e.subtype === 'post_tool').length\n });\n }\n\n this.fileToolTracker.updateFileOperations(events);\n this.fileToolTracker.updateToolCalls(events);\n\n // Debug: Check what was tracked\n const fileOps = this.fileToolTracker.getFileOperations();\n const toolCalls = this.fileToolTracker.getToolCalls();\n console.log('[Dashboard] After update - File operations:', fileOps.size, 'Tool calls:', toolCalls.size);\n\n // Process agent inference for new events\n this.agentInference.processAgentInference();\n\n // Notify CodeViewer that file operations have been updated\n // This ensures File Tree tab shows the same data as Files tab\n if (window.CodeViewer && typeof window.CodeViewer.refreshFromFileToolTracker === 'function') {\n setTimeout(() => {\n window.CodeViewer.refreshFromFileToolTracker();\n }, 50);\n }\n\n // Update agent hierarchy with new events\n this.agentHierarchy.updateWithNewEvents(events);\n\n // Auto-scroll events list if on events tab\n if (this.uiStateManager.getCurrentTab() === 'events') {\n this.exportManager.scrollListToBottom('events-list');\n }\n\n // Re-render current tab\n this.renderCurrentTab();\n });\n\n // Connection status changes\n this.socketManager.onConnectionStatusChange((status, type) => {\n // Set up git branch listener when connected\n if (type === 'connected') {\n this.workingDirectoryManager.updateGitBranch(\n this.workingDirectoryManager.getCurrentWorkingDir()\n );\n }\n });\n\n // Tab changes\n document.addEventListener('tabChanged', (e) => {\n this.renderCurrentTab();\n this.uiStateManager.updateTabNavigationItems();\n });\n\n // Events clearing\n document.addEventListener('eventsClearing', () => {\n this.fileToolTracker.clear();\n this.agentInference.initialize();\n });\n\n // Card details requests\n document.addEventListener('showCardDetails', (e) => {\n this.showCardDetails(e.detail.tabName, e.detail.index);\n });\n\n // Session changes\n document.addEventListener('sessionFilterChanged', (e) => {\n this.renderCurrentTab();\n });\n }\n\n /**\n * Set up tab filters\n */\n setupTabFilters() {\n // Agents tab filters\n const agentsSearchInput = document.getElementById('agents-search-input');\n const agentsTypeFilter = document.getElementById('agents-type-filter');\n\n if (agentsSearchInput) {\n agentsSearchInput.addEventListener('input', () => {\n if (this.uiStateManager.getCurrentTab() === 'agents') this.renderCurrentTab();\n });\n }\n\n if (agentsTypeFilter) {\n agentsTypeFilter.addEventListener('change', () => {\n if (this.uiStateManager.getCurrentTab() === 'agents') this.renderCurrentTab();\n });\n }\n\n // Tools tab filters\n const toolsSearchInput = document.getElementById('tools-search-input');\n const toolsTypeFilter = document.getElementById('tools-type-filter');\n\n if (toolsSearchInput) {\n toolsSearchInput.addEventListener('input', () => {\n if (this.uiStateManager.getCurrentTab() === 'tools') this.renderCurrentTab();\n });\n }\n\n if (toolsTypeFilter) {\n toolsTypeFilter.addEventListener('change', () => {\n if (this.uiStateManager.getCurrentTab() === 'tools') this.renderCurrentTab();\n });\n }\n\n // Files tab filters\n const filesSearchInput = document.getElementById('files-search-input');\n const filesTypeFilter = document.getElementById('files-type-filter');\n\n if (filesSearchInput) {\n filesSearchInput.addEventListener('input', () => {\n if (this.uiStateManager.getCurrentTab() === 'files') this.renderCurrentTab();\n });\n }\n\n if (filesTypeFilter) {\n filesTypeFilter.addEventListener('change', () => {\n if (this.uiStateManager.getCurrentTab() === 'files') this.renderCurrentTab();\n });\n }\n }\n\n /**\n * Initialize from URL parameters\n */\n initializeFromURL() {\n const params = new URLSearchParams(window.location.search);\n this.socketManager.initializeFromURL(params);\n }\n\n /**\n * Render current tab content\n */\n renderCurrentTab() {\n const currentTab = this.uiStateManager.getCurrentTab();\n\n switch (currentTab) {\n case 'events':\n // Events tab is handled by EventViewer\n break;\n case 'claude-tree':\n // File Tree tab - trigger CodeViewer rendering\n if (window.CodeViewer && typeof window.CodeViewer.show === 'function') {\n window.CodeViewer.show();\n }\n break;\n case 'activity':\n // Trigger Activity tab rendering through the component\n // Check if ActivityTree class is available (from built module)\n if (window.ActivityTree && typeof window.ActivityTree === 'function') {\n // Reset retry count on successful load\n this.activityTreeRetryCount = 0;\n \n // Create or get instance\n if (!window.activityTreeInstance) {\n window.activityTreeInstance = new window.ActivityTree();\n }\n \n // Initialize if needed and render\n if (window.activityTreeInstance) {\n if (!window.activityTreeInstance.initialized) {\n window.activityTreeInstance.initialize();\n }\n \n if (typeof window.activityTreeInstance.renderWhenVisible === 'function') {\n window.activityTreeInstance.renderWhenVisible();\n }\n \n // Force show to ensure the tree is visible\n if (typeof window.activityTreeInstance.forceShow === 'function') {\n window.activityTreeInstance.forceShow();\n }\n }\n } else if (window.activityTree && typeof window.activityTree === 'function') {\n // Fallback to legacy approach if available\n const activityTreeInstance = window.activityTree();\n if (activityTreeInstance) {\n if (typeof activityTreeInstance.renderWhenVisible === 'function') {\n activityTreeInstance.renderWhenVisible();\n }\n if (typeof activityTreeInstance.forceShow === 'function') {\n activityTreeInstance.forceShow();\n }\n }\n } else {\n // Module not loaded yet, retry after a delay (with retry limit)\n if (this.activityTreeRetryCount < this.maxRetryAttempts) {\n this.activityTreeRetryCount++;\n console.warn(`Activity tree component not available, retrying in 100ms... (attempt ${this.activityTreeRetryCount}/${this.maxRetryAttempts})`);\n setTimeout(() => {\n if (this.uiStateManager.getCurrentTab() === 'activity') {\n this.renderCurrentTab();\n }\n }, 100);\n } else {\n console.error('Maximum retry attempts reached for ActivityTree initialization. Giving up.');\n const activityContainer = document.getElementById('activity-tree-container') || document.getElementById('activity-tree');\n if (activityContainer) {\n activityContainer.innerHTML = '<div class=\"error-message\">⚠️ Activity Tree failed to load. Please refresh the page.</div>';\n }\n }\n }\n break;\n case 'agents':\n this.renderAgents();\n break;\n case 'tools':\n this.renderTools();\n break;\n case 'files':\n this.renderFiles();\n break;\n }\n\n // Update selection UI if we have a selected card\n const selectedCard = this.uiStateManager.getSelectedCard();\n if (selectedCard.tab === currentTab) {\n this.uiStateManager.updateCardSelectionUI();\n }\n\n // Update unified selection UI to maintain consistency\n this.uiStateManager.updateUnifiedSelectionUI();\n }\n\n /**\n * Render agents tab with flat chronological view\n */\n renderAgents() {\n const agentsList = document.getElementById('agents-list');\n if (!agentsList) return;\n \n // Get filter values\n const searchText = document.getElementById('agents-search-input')?.value || '';\n const agentType = document.getElementById('agents-type-filter')?.value || '';\n \n // Generate flat HTML\n const flatHTML = this.renderAgentsFlat(searchText, agentType);\n agentsList.innerHTML = flatHTML;\n \n // Remove hierarchy controls if they exist\n this.removeHierarchyControls();\n \n // Update filter dropdowns with available agent types\n const uniqueInstances = this.agentInference.getUniqueAgentInstances();\n this.updateAgentsFilterDropdowns(uniqueInstances);\n }\n \n /**\n * Remove hierarchy control buttons (flat view doesn't need them)\n */\n removeHierarchyControls() {\n const existingControls = document.getElementById('hierarchy-controls');\n if (existingControls) {\n existingControls.remove();\n }\n }\n \n /**\n * Render agents as a flat chronological list\n * @param {string} searchText - Search filter\n * @param {string} agentType - Agent type filter \n * @returns {string} HTML for flat agent list\n */\n renderAgentsFlat(searchText, agentType) {\n const events = this.eventViewer.events;\n if (!events || events.length === 0) {\n return '<div class=\"no-events\">No agent events found...</div>';\n }\n \n // Process agent inference to get agent mappings\n this.agentInference.processAgentInference();\n const eventAgentMap = this.agentInference.getEventAgentMap();\n \n // Collect all agent events with metadata\n const agentEvents = [];\n events.forEach((event, index) => {\n const inference = eventAgentMap.get(index);\n if (inference && (inference.type === 'subagent' || inference.type === 'main_agent')) {\n // Apply filters\n let includeEvent = true;\n \n if (searchText) {\n const searchLower = searchText.toLowerCase();\n includeEvent = includeEvent && (\n inference.agentName.toLowerCase().includes(searchLower) ||\n (event.tool_name && event.tool_name.toLowerCase().includes(searchLower)) ||\n (event.data && JSON.stringify(event.data).toLowerCase().includes(searchLower))\n );\n }\n \n if (agentType) {\n includeEvent = includeEvent && inference.agentName.includes(agentType);\n }\n \n if (includeEvent) {\n agentEvents.push({\n event,\n inference,\n index,\n timestamp: new Date(event.timestamp)\n });\n }\n }\n });\n \n if (agentEvents.length === 0) {\n return '<div class=\"no-events\">No agent events match the current filters...</div>';\n }\n \n // Generate HTML for each event\n const html = agentEvents.map((item, listIndex) => {\n const { event, inference, index, timestamp } = item;\n \n // Determine action/tool\n let action = 'Activity';\n let actionIcon = '📋';\n let details = '';\n \n if (event.event_type === 'SubagentStart') {\n action = 'Started';\n actionIcon = '🟢';\n details = 'Agent session began';\n } else if (event.event_type === 'SubagentStop') {\n action = 'Stopped';\n actionIcon = '🔴';\n details = 'Agent session ended';\n } else if (event.tool_name) {\n action = `Tool: ${event.tool_name}`;\n actionIcon = this.getToolIcon(event.tool_name);\n \n // Add tool parameters as details\n if (event.data && event.data.tool_parameters) {\n const params = event.data.tool_parameters;\n if (params.file_path) {\n details = params.file_path;\n } else if (params.command) {\n details = params.command.substring(0, 50) + (params.command.length > 50 ? '...' : '');\n } else if (params.pattern) {\n details = `pattern=\"${params.pattern}\"`;\n } else if (params.query) {\n details = `query=\"${params.query}\"`;\n }\n }\n }\n \n // Status based on event type\n let status = 'completed';\n if (event.event_type === 'SubagentStart') {\n status = 'active';\n } else if (event.data && event.data.error) {\n status = 'error';\n }\n \n return `\n <div class=\"agent-event-item\" data-index=\"${listIndex}\" onclick=\"window.dashboard.showCardDetails('agents', ${index})\">\n <div class=\"agent-event-header\">\n <div class=\"agent-event-time\">${this.formatTimestamp(timestamp)}</div>\n <div class=\"agent-event-agent\">\n ${this.getAgentIcon(inference.agentName)} ${inference.agentName}\n </div>\n <div class=\"agent-event-action\">\n ${actionIcon} ${action}\n </div>\n <div class=\"agent-event-status status-${status}\">\n ${this.getStatusIcon(status)}\n </div>\n </div>\n ${details ? `<div class=\"agent-event-details\">${this.escapeHtml(details)}</div>` : ''}\n </div>\n `;\n }).join('');\n \n return `<div class=\"agent-events-flat\">${html}</div>`;\n }\n \n /**\n * Get icon for agent type\n */\n getAgentIcon(agentName) {\n const agentIcons = {\n 'PM': '🎯',\n 'Engineer Agent': '🔧',\n 'Research Agent': '🔍', \n 'QA Agent': '✅',\n 'Documentation Agent': '📝',\n 'Security Agent': '🔒',\n 'Ops Agent': '⚙️',\n 'Version Control Agent': '📦',\n 'Data Engineer Agent': '💾',\n 'Test Integration Agent': '🧪'\n };\n return agentIcons[agentName] || '🤖';\n }\n \n /**\n * Get icon for tool\n */\n getToolIcon(toolName) {\n const toolIcons = {\n 'Read': '📖',\n 'Write': '✏️',\n 'Edit': '📝',\n 'Bash': '💻',\n 'Grep': '🔍',\n 'Glob': '📂',\n 'LS': '📁',\n 'Task': '📋'\n };\n return toolIcons[toolName] || '🔧';\n }\n \n /**\n * Get icon for status\n */\n getStatusIcon(status) {\n const statusIcons = {\n 'active': '🟢',\n 'completed': '✅',\n 'error': '❌',\n 'pending': '🟡'\n };\n return statusIcons[status] || '❓';\n }\n \n /**\n * Format timestamp for display\n */\n formatTimestamp(timestamp) {\n return timestamp.toLocaleTimeString('en-US', {\n hour: '2-digit',\n minute: '2-digit', \n second: '2-digit',\n hour12: false\n });\n }\n \n /**\n * Escape HTML for safe display\n */\n escapeHtml(text) {\n if (!text) return '';\n const div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML;\n }\n\n /**\n * Render tools tab with unique instance view (one row per unique tool call)\n */\n renderTools() {\n const toolsList = document.getElementById('tools-list');\n if (!toolsList) return;\n\n const toolCalls = this.fileToolTracker.getToolCalls();\n const toolCallsArray = Array.from(toolCalls.entries());\n const uniqueToolInstances = this.eventProcessor.getUniqueToolInstances(toolCallsArray);\n const toolHTML = this.eventProcessor.generateToolHTML(uniqueToolInstances);\n\n toolsList.innerHTML = toolHTML;\n this.exportManager.scrollListToBottom('tools-list');\n\n // Update filter dropdowns\n this.updateToolsFilterDropdowns(uniqueToolInstances);\n }\n\n /**\n * Render files tab with unique instance view (one row per unique file)\n */\n renderFiles() {\n const filesList = document.getElementById('files-list');\n if (!filesList) return;\n\n const fileOperations = this.fileToolTracker.getFileOperations();\n const filesArray = Array.from(fileOperations.entries());\n\n console.log('[renderFiles] File operations map size:', fileOperations.size);\n console.log('[renderFiles] Files array:', filesArray);\n\n const uniqueFileInstances = this.eventProcessor.getUniqueFileInstances(filesArray);\n const fileHTML = this.eventProcessor.generateFileHTML(uniqueFileInstances);\n\n if (filesArray.length === 0) {\n filesList.innerHTML = '<div class=\"empty-state\">No file operations tracked yet. File operations will appear here when tools like Read, Write, Edit, or Grep are used.</div>';\n } else {\n filesList.innerHTML = fileHTML;\n }\n\n this.exportManager.scrollListToBottom('files-list');\n\n // Update filter dropdowns\n this.updateFilesFilterDropdowns(filesArray);\n }\n\n /**\n * Update agents filter dropdowns for unique instances\n */\n updateAgentsFilterDropdowns(uniqueInstances) {\n const agentTypes = new Set();\n\n // uniqueInstances is already an array of unique agent instances\n uniqueInstances.forEach(instance => {\n if (instance.agentName && instance.agentName !== 'Unknown') {\n agentTypes.add(instance.agentName);\n }\n });\n\n const sortedTypes = Array.from(agentTypes).filter(type => type && type.trim() !== '');\n this.populateFilterDropdown('agents-type-filter', sortedTypes, 'All Agent Types');\n\n // Agent filter types populated\n }\n\n /**\n * Update tools filter dropdowns\n */\n updateToolsFilterDropdowns(toolCallsArray) {\n const toolNames = [...new Set(toolCallsArray.map(([key, toolCall]) => toolCall.tool_name))]\n .filter(name => name);\n\n this.populateFilterDropdown('tools-type-filter', toolNames, 'All Tools');\n }\n\n /**\n * Update files filter dropdowns\n */\n updateFilesFilterDropdowns(filesArray) {\n const operations = [...new Set(filesArray.flatMap(([path, data]) =>\n data.operations.map(op => op.operation)\n ))].filter(op => op);\n\n this.populateFilterDropdown('files-type-filter', operations, 'All Operations');\n }\n\n /**\n * Populate filter dropdown with values\n */\n populateFilterDropdown(selectId, values, allOption = 'All') {\n const select = document.getElementById(selectId);\n if (!select) return;\n\n const currentValue = select.value;\n const sortedValues = values.sort((a, b) => a.localeCompare(b));\n\n // Clear existing options except the first \"All\" option\n select.innerHTML = `<option value=\"\">${allOption}</option>`;\n\n // Add sorted values\n sortedValues.forEach(value => {\n const option = document.createElement('option');\n option.value = value;\n option.textContent = value;\n select.appendChild(option);\n });\n\n // Restore previous selection if it still exists\n if (currentValue && sortedValues.includes(currentValue)) {\n select.value = currentValue;\n }\n }\n\n /**\n * Show card details for specified tab and index\n */\n showCardDetails(tabName, index) {\n switch (tabName) {\n case 'events':\n if (this.eventViewer) {\n this.eventViewer.showEventDetails(index);\n }\n break;\n case 'agents':\n this.showAgentDetailsByIndex(index);\n break;\n case 'tools':\n this.showToolDetailsByIndex(index);\n break;\n case 'files':\n this.showFileDetailsByIndex(index);\n break;\n }\n }\n\n /**\n * Show agent details by index\n */\n showAgentDetailsByIndex(index) {\n const events = this.eventProcessor.getFilteredEventsForTab('agents');\n\n // Defensive checks\n if (!events || !Array.isArray(events) || index < 0 || index >= events.length) {\n console.warn('Dashboard: Invalid agent index or events array');\n return;\n }\n\n const filteredSingleEvent = this.eventProcessor.applyAgentsFilters([events[index]]);\n\n if (filteredSingleEvent.length > 0 && this.moduleViewer &&\n typeof this.moduleViewer.showAgentEvent === 'function') {\n const event = filteredSingleEvent[0];\n this.moduleViewer.showAgentEvent(event, index);\n }\n }\n\n /**\n * Show agent instance details for unique instance view\n * @param {string} instanceId - Agent instance ID\n */\n showAgentInstanceDetails(instanceId) {\n const pmDelegations = this.agentInference.getPMDelegations();\n const instance = pmDelegations.get(instanceId);\n\n if (!instance) {\n // Check if it's an implied delegation\n const uniqueInstances = this.agentInference.getUniqueAgentInstances();\n const impliedInstance = uniqueInstances.find(inst => inst.id === instanceId);\n\n if (!impliedInstance) {\n console.error('Agent instance not found:', instanceId);\n return;\n }\n\n // For implied instances, show basic info\n this.showImpliedAgentDetails(impliedInstance);\n return;\n }\n\n // Show full PM delegation details\n if (this.moduleViewer && typeof this.moduleViewer.showAgentInstance === 'function') {\n this.moduleViewer.showAgentInstance(instance);\n } else {\n // Fallback: show in console or basic modal\n console.log('Agent Instance Details:', {\n id: instanceId,\n agentName: instance.agentName,\n type: 'PM Delegation',\n eventCount: instance.agentEvents.length,\n startTime: instance.timestamp,\n pmCall: instance.pmCall\n });\n }\n }\n\n /**\n * Show implied agent details (agents without explicit PM delegation)\n * @param {Object} impliedInstance - Implied agent instance\n */\n showImpliedAgentDetails(impliedInstance) {\n if (this.moduleViewer && typeof this.moduleViewer.showImpliedAgent === 'function') {\n this.moduleViewer.showImpliedAgent(impliedInstance);\n } else {\n // Fallback: show in console or basic modal\n console.log('Implied Agent Details:', {\n id: impliedInstance.id,\n agentName: impliedInstance.agentName,\n type: 'Implied PM Delegation',\n eventCount: impliedInstance.eventCount,\n startTime: impliedInstance.timestamp,\n note: 'No explicit PM call found - inferred from agent activity'\n });\n }\n }\n\n /**\n * Show tool details by index\n */\n showToolDetailsByIndex(index) {\n const toolCalls = this.fileToolTracker.getToolCalls();\n const toolCallsArray = Array.from(toolCalls.entries());\n const filteredToolCalls = this.eventProcessor.applyToolCallFilters(toolCallsArray);\n\n if (index >= 0 && index < filteredToolCalls.length) {\n const [toolCallKey] = filteredToolCalls[index];\n this.showToolCallDetails(toolCallKey);\n }\n }\n\n /**\n * Show file details by index\n */\n showFileDetailsByIndex(index) {\n const fileOperations = this.fileToolTracker.getFileOperations();\n let filesArray = Array.from(fileOperations.entries());\n filesArray = this.eventProcessor.applyFilesFilters(filesArray);\n\n if (index >= 0 && index < filesArray.length) {\n const [filePath] = filesArray[index];\n this.showFileDetails(filePath);\n }\n }\n\n /**\n * Show tool call details\n */\n showToolCallDetails(toolCallKey) {\n const toolCall = this.fileToolTracker.getToolCall(toolCallKey);\n if (toolCall && this.moduleViewer) {\n this.moduleViewer.showToolCall(toolCall, toolCallKey);\n }\n }\n\n /**\n * Show file details\n */\n showFileDetails(filePath) {\n const fileData = this.fileToolTracker.getFileOperationsForFile(filePath);\n if (fileData && this.moduleViewer) {\n this.moduleViewer.showFileOperations(fileData, filePath);\n }\n }\n\n // ====================================\n // BACKWARD COMPATIBILITY METHODS\n // ====================================\n\n /**\n * Switch tab (backward compatibility)\n */\n switchTab(tabName) {\n this.uiStateManager.switchTab(tabName);\n }\n\n /**\n * Select card (backward compatibility)\n */\n selectCard(tabName, index, type, data) {\n this.uiStateManager.selectCard(tabName, index, type, data);\n }\n\n /**\n * Clear events (backward compatibility)\n */\n clearEvents() {\n this.exportManager.clearEvents();\n }\n\n /**\n * Export events (backward compatibility)\n */\n exportEvents() {\n this.exportManager.exportEvents();\n }\n\n /**\n * Clear selection (backward compatibility)\n */\n clearSelection() {\n this.uiStateManager.clearSelection();\n if (this.eventViewer) {\n this.eventViewer.clearSelection();\n }\n if (this.moduleViewer) {\n this.moduleViewer.clear();\n }\n }\n\n\n /**\n * Get current working directory (backward compatibility)\n */\n get currentWorkingDir() {\n return this.workingDirectoryManager.getCurrentWorkingDir();\n }\n\n /**\n * Set current working directory (backward compatibility)\n */\n set currentWorkingDir(dir) {\n this.workingDirectoryManager.setWorkingDirectory(dir);\n }\n\n /**\n * Get current tab (backward compatibility)\n */\n get currentTab() {\n return this.uiStateManager.getCurrentTab();\n }\n\n /**\n * Get selected card (backward compatibility)\n */\n get selectedCard() {\n return this.uiStateManager.getSelectedCard();\n }\n\n /**\n * Get file operations (backward compatibility)\n */\n get fileOperations() {\n return this.fileToolTracker.getFileOperations();\n }\n\n /**\n * Get tool calls (backward compatibility)\n */\n get toolCalls() {\n return this.fileToolTracker.getToolCalls();\n }\n\n\n /**\n * Get tab navigation state (backward compatibility)\n */\n get tabNavigation() {\n return this.uiStateManager ? this.uiStateManager.tabNavigation : null;\n }\n}\n\n// Global functions for backward compatibility\nwindow.clearEvents = function() {\n if (window.dashboard) {\n window.dashboard.clearEvents();\n }\n};\n\nwindow.exportEvents = function() {\n if (window.dashboard) {\n window.dashboard.exportEvents();\n }\n};\n\nwindow.clearSelection = function() {\n if (window.dashboard) {\n window.dashboard.clearSelection();\n }\n};\n\nwindow.switchTab = function(tabName) {\n if (window.dashboard) {\n window.dashboard.switchTab(tabName);\n }\n};\n\n// File Viewer Modal Functions - Removed broken duplicate (using the one at line 1505)\n\nwindow.copyFileContent = function() {\n const modal = document.getElementById('file-viewer-modal');\n if (!modal) return;\n\n const codeElement = modal.querySelector('.file-content-code');\n if (!codeElement) return;\n\n const text = codeElement.textContent;\n\n if (navigator.clipboard && navigator.clipboard.writeText) {\n navigator.clipboard.writeText(text).then(() => {\n // Show brief feedback\n const button = modal.querySelector('.file-content-copy');\n if (button) {\n const originalText = button.textContent;\n button.textContent = '✅ Copied!';\n setTimeout(() => {\n button.textContent = originalText;\n }, 2000);\n }\n }).catch(err => {\n console.error('Failed to copy text:', err);\n });\n } else {\n // Fallback for older browsers\n const textarea = document.createElement('textarea');\n textarea.value = text;\n document.body.appendChild(textarea);\n textarea.select();\n document.execCommand('copy');\n document.body.removeChild(textarea);\n\n const button = modal.querySelector('.file-content-copy');\n if (button) {\n const originalText = button.textContent;\n button.textContent = '✅ Copied!';\n setTimeout(() => {\n button.textContent = originalText;\n }, 2000);\n }\n }\n};\n\nfunction createFileViewerModal() {\n const modal = document.createElement('div');\n modal.id = 'file-viewer-modal';\n modal.className = 'modal file-viewer-modal';\n\n modal.innerHTML = `\n <div class=\"modal-content file-viewer-content\">\n <div class=\"file-viewer-header\">\n <h2 class=\"file-viewer-title\">\n <span class=\"file-viewer-icon\">📄</span>\n <span class=\"file-viewer-title-text\">File Viewer</span>\n </h2>\n <div class=\"file-viewer-meta\">\n <span class=\"file-viewer-file-path\"></span>\n <span class=\"file-viewer-file-size\"></span>\n </div>\n <button class=\"file-viewer-close\" onclick=\"hideFileViewerModal()\">\n <span>×</span>\n </button>\n </div>\n <div class=\"file-viewer-body\">\n <div class=\"file-viewer-loading\">\n <div class=\"loading-spinner\"></div>\n <span>Loading file content...</span>\n </div>\n <div class=\"file-viewer-error\" style=\"display: none;\">\n <div class=\"error-icon\">⚠️</div>\n <div class=\"error-message\"></div>\n <div class=\"error-suggestions\"></div>\n </div>\n <div class=\"file-viewer-content-area\" style=\"display: none;\">\n <div class=\"file-viewer-toolbar\">\n <div class=\"file-viewer-info\">\n <span class=\"file-extension\"></span>\n <span class=\"file-encoding\"></span>\n </div>\n <div class=\"file-viewer-actions\">\n <button class=\"file-content-copy\" onclick=\"copyFileContent()\">\n 📋 Copy\n </button>\n </div>\n </div>\n <div class=\"file-viewer-scroll-wrapper\">\n <pre class=\"file-content-display\"><code class=\"file-content-code\"></code></pre>\n </div>\n </div>\n </div>\n </div>\n `;\n\n // Close modal when clicking outside\n modal.addEventListener('click', (e) => {\n if (e.target === modal) {\n hideFileViewerModal();\n }\n });\n\n // Close modal with Escape key\n document.addEventListener('keydown', (e) => {\n if (e.key === 'Escape' && modal.style.display === 'flex') {\n hideFileViewerModal();\n }\n });\n\n return modal;\n}\n\nasync function updateFileViewerModal(modal, filePath, workingDir) {\n // Update header info\n const filePathElement = modal.querySelector('.file-viewer-file-path');\n const fileSizeElement = modal.querySelector('.file-viewer-file-size');\n\n if (filePathElement) {\n filePathElement.textContent = filePath;\n }\n if (fileSizeElement) {\n fileSizeElement.textContent = '';\n }\n\n // Show loading state\n const loadingElement = modal.querySelector('.file-viewer-loading');\n const errorElement = modal.querySelector('.file-viewer-error');\n const contentArea = modal.querySelector('.file-viewer-content-area');\n \n if (loadingElement) {\n loadingElement.style.display = 'flex';\n }\n if (errorElement) {\n errorElement.style.display = 'none';\n }\n if (contentArea) {\n contentArea.style.display = 'none';\n }\n\n try {\n // Get the Socket.IO client\n const socket = window.socket || window.dashboard?.socketClient?.socket || window.socketClient?.socket;\n \n console.log('[FileViewer] Socket search results:', {\n 'window.socket': !!window.socket,\n 'window.socket.connected': window.socket?.connected,\n 'dashboard.socketClient.socket': !!window.dashboard?.socketClient?.socket,\n 'dashboard.socketClient.socket.connected': window.dashboard?.socketClient?.socket?.connected,\n 'window.socketClient.socket': !!window.socketClient?.socket,\n 'window.socketClient.socket.connected': window.socketClient?.socket?.connected\n });\n \n if (!socket) {\n throw new Error('No socket connection available. Please ensure the dashboard is connected.');\n }\n \n if (!socket.connected) {\n console.warn('[FileViewer] Socket found but not connected, attempting to use anyway...');\n }\n \n console.log('[FileViewer] Socket found, setting up listener for file_content_response');\n\n // Set up one-time listener for file content response\n const responsePromise = new Promise((resolve, reject) => {\n const responseHandler = (data) => {\n console.log('[FileViewer] Received file_content_response:', data);\n if (data.file_path === filePath) {\n socket.off('file_content_response', responseHandler);\n if (data.success) {\n console.log('[FileViewer] File content loaded successfully');\n resolve(data);\n } else {\n console.error('[FileViewer] File read failed:', data.error);\n reject(new Error(data.error || 'Failed to read file'));\n }\n }\n };\n\n socket.on('file_content_response', responseHandler);\n console.log('[FileViewer] Listener registered for file_content_response');\n\n // Timeout after 10 seconds\n setTimeout(() => {\n socket.off('file_content_response', responseHandler);\n console.error('[FileViewer] Request timeout after 10 seconds');\n reject(new Error('Request timeout - server did not respond'));\n }, 10000);\n });\n\n // Send file read request\n const requestData = {\n file_path: filePath,\n working_dir: workingDir\n };\n console.log('[FileViewer] Emitting read_file event with data:', requestData);\n socket.emit('read_file', requestData);\n\n // File viewer request sent\n\n // Wait for response\n const result = await responsePromise;\n // File content received successfully\n\n // Hide loading\n const loadingEl = modal.querySelector('.file-viewer-loading');\n if (loadingEl) {\n loadingEl.style.display = 'none';\n }\n\n // Show successful content\n displayFileContent(modal, result);\n\n } catch (error) {\n console.error('❌ Failed to fetch file content:', error);\n\n const loadingEl2 = modal.querySelector('.file-viewer-loading');\n if (loadingEl2) {\n loadingEl2.style.display = 'none';\n }\n\n // Create detailed error message\n let errorMessage = error.message || 'Unknown error occurred';\n let suggestions = [];\n\n if (error.message.includes('No socket connection')) {\n errorMessage = 'Failed to connect to the monitoring server';\n suggestions = [\n 'Check if the monitoring server is running',\n 'Verify the socket connection in the dashboard',\n 'Try refreshing the page and reconnecting'\n ];\n } else if (error.message.includes('timeout')) {\n errorMessage = 'Request timed out';\n suggestions = [\n 'The file may be too large to load quickly',\n 'Check your network connection',\n 'Try again in a few moments'\n ];\n } else if (error.message.includes('File does not exist')) {\n errorMessage = 'File not found';\n suggestions = [\n 'The file may have been moved or deleted',\n 'Check the file path spelling',\n 'Refresh the file list to see current files'\n ];\n } else if (error.message.includes('Access denied')) {\n errorMessage = 'Access denied';\n suggestions = [\n 'The file is outside the allowed directories',\n 'File access is restricted for security reasons'\n ];\n }\n\n displayFileError(modal, {\n error: errorMessage,\n file_path: filePath,\n working_dir: workingDir,\n suggestions: suggestions\n });\n }\n}\n\nfunction displayFileContent(modal, result) {\n // Display file content in modal\n const contentArea = modal.querySelector('.file-viewer-content-area');\n const extensionElement = modal.querySelector('.file-extension');\n const encodingElement = modal.querySelector('.file-encoding');\n const fileSizeElement = modal.querySelector('.file-viewer-file-size');\n const codeElement = modal.querySelector('.file-content-code');\n\n // Update metadata\n if (extensionElement) extensionElement.textContent = `Type: ${result.extension || 'unknown'}`;\n if (encodingElement) encodingElement.textContent = `Encoding: ${result.encoding || 'unknown'}`;\n if (fileSizeElement) fileSizeElement.textContent = `Size: ${formatFileSize(result.file_size)}`;\n\n // Update content with basic syntax highlighting\n if (codeElement && result.content) {\n // Setting file content\n codeElement.innerHTML = highlightCode(result.content, result.extension);\n\n // Force scrolling to work by setting explicit heights\n const wrapper = modal.querySelector('.file-viewer-scroll-wrapper');\n if (wrapper) {\n // Give it a moment for content to render\n setTimeout(() => {\n const modalContent = modal.querySelector('.modal-content');\n const header = modal.querySelector('.file-viewer-header');\n const toolbar = modal.querySelector('.file-viewer-toolbar');\n\n const modalHeight = modalContent?.offsetHeight || 0;\n const headerHeight = header?.offsetHeight || 0;\n const toolbarHeight = toolbar?.offsetHeight || 0;\n\n const availableHeight = modalHeight - headerHeight - toolbarHeight - 40; // 40px for padding\n\n // Setting file viewer scroll height\n\n wrapper.style.maxHeight = `${availableHeight}px`;\n wrapper.style.overflowY = 'auto';\n }, 50);\n }\n } else {\n console.warn('⚠️ Missing codeElement or file content');\n }\n\n // Show content area\n if (contentArea) {\n contentArea.style.display = 'block';\n // File content area displayed\n }\n}\n\nfunction displayFileError(modal, result) {\n const errorArea = modal.querySelector('.file-viewer-error');\n const messageElement = modal.querySelector('.error-message');\n const suggestionsElement = modal.querySelector('.error-suggestions');\n\n let errorMessage = result.error || 'Unknown error occurred';\n\n if (messageElement) {\n messageElement.innerHTML = `\n <div class=\"error-main\">${errorMessage}</div>\n ${result.file_path ? `<div class=\"error-file\">File: ${result.file_path}</div>` : ''}\n ${result.working_dir ? `<div class=\"error-dir\">Working directory: ${result.working_dir}</div>` : ''}\n `;\n }\n\n if (suggestionsElement) {\n if (result.suggestions && result.suggestions.length > 0) {\n suggestionsElement.innerHTML = `\n <h4>Suggestions:</h4>\n <ul>\n ${result.suggestions.map(s => `<li>${s}</li>`).join('')}\n </ul>\n `;\n } else {\n suggestionsElement.innerHTML = '';\n }\n }\n\n console.log('📋 Displaying file viewer error:', {\n originalError: result.error,\n processedMessage: errorMessage,\n suggestions: result.suggestions\n });\n\n if (errorArea) {\n errorArea.style.display = 'block';\n }\n}\n\nfunction highlightCode(code, extension) {\n /**\n * Apply basic syntax highlighting to code content\n * WHY: Provides basic highlighting for common file types to improve readability.\n * This is a simple implementation that can be enhanced with full syntax highlighting\n * libraries like highlight.js or Prism.js if needed.\n */\n\n // Escape HTML entities first\n const escaped = code\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>');\n\n // Basic highlighting based on file extension\n switch (extension) {\n case '.js':\n case '.jsx':\n case '.ts':\n case '.tsx':\n return highlightJavaScript(escaped);\n case '.py':\n return highlightPython(escaped);\n case '.json':\n return highlightJSON(escaped);\n case '.css':\n return highlightCSS(escaped);\n case '.html':\n case '.htm':\n return highlightHTML(escaped);\n case '.md':\n case '.markdown':\n return highlightMarkdown(escaped);\n default:\n // Return with line numbers for plain text\n return addLineNumbers(escaped);\n }\n}\n\nfunction highlightJavaScript(code) {\n return addLineNumbers(code\n .replace(/\\b(function|const|let|var|if|else|for|while|return|import|export|class|extends)\\b/g, '<span class=\"keyword\">$1</span>')\n .replace(/(\\/\\*[\\s\\S]*?\\*\\/|\\/\\/.*)/g, '<span class=\"comment\">$1</span>')\n .replace(/('[^']*'|\"[^\"]*\"|`[^`]*`)/g, '<span class=\"string\">$1</span>')\n .replace(/\\b(\\d+)\\b/g, '<span class=\"number\">$1</span>'));\n}\n\nfunction highlightPython(code) {\n return addLineNumbers(code\n .replace(/\\b(def|class|if|elif|else|for|while|return|import|from|as|try|except|finally|with)\\b/g, '<span class=\"keyword\">$1</span>')\n .replace(/(#.*)/g, '<span class=\"comment\">$1</span>')\n .replace(/('[^']*'|\"[^\"]*\"|\"\"\"[\\s\\S]*?\"\"\")/g, '<span class=\"string\">$1</span>')\n .replace(/\\b(\\d+)\\b/g, '<span class=\"number\">$1</span>'));\n}\n\nfunction highlightJSON(code) {\n return addLineNumbers(code\n .replace(/(\"[\\w\\s]*\")\\s*:/g, '<span class=\"property\">$1</span>:')\n .replace(/:\\s*(\".*?\")/g, ': <span class=\"string\">$1</span>')\n .replace(/:\\s*(\\d+)/g, ': <span class=\"number\">$1</span>')\n .replace(/:\\s*(true|false|null)/g, ': <span class=\"keyword\">$1</span>'));\n}\n\nfunction highlightCSS(code) {\n return addLineNumbers(code\n .replace(/([.#]?[\\w-]+)\\s*\\{/g, '<span class=\"selector\">$1</span> {')\n .replace(/([\\w-]+)\\s*:/g, '<span class=\"property\">$1</span>:')\n .replace(/:\\s*([^;]+);/g, ': <span class=\"value\">$1</span>;')\n .replace(/(\\/\\*[\\s\\S]*?\\*\\/)/g, '<span class=\"comment\">$1</span>'));\n}\n\nfunction highlightHTML(code) {\n return addLineNumbers(code\n .replace(/(<\\/?[\\w-]+)/g, '<span class=\"tag\">$1</span>')\n .replace(/([\\w-]+)=(['\"][^'\"]*['\"])/g, '<span class=\"attribute\">$1</span>=<span class=\"string\">$2</span>')\n .replace(/(<!--[\\s\\S]*?-->)/g, '<span class=\"comment\">$1</span>'));\n}\n\nfunction highlightMarkdown(code) {\n return addLineNumbers(code\n .replace(/^(#{1,6})\\s+(.*)$/gm, '<span class=\"header\">$1</span> <span class=\"header-text\">$2</span>')\n .replace(/\\*\\*(.*?)\\*\\*/g, '<span class=\"bold\">**$1**</span>')\n .replace(/\\*(.*?)\\*/g, '<span class=\"italic\">*$1*</span>')\n .replace(/`([^`]+)`/g, '<span class=\"code\">`$1`</span>')\n .replace(/^\\s*[-*+]\\s+(.*)$/gm, '<span class=\"list-marker\">•</span> $1'));\n}\n\nfunction addLineNumbers(code) {\n const lines = code.split('\\n');\n return lines.map((line, index) =>\n `<span class=\"line-number\">${String(index + 1).padStart(3, ' ')}</span> ${line || ' '}`\n ).join('\\n');\n}\n\nfunction formatFileSize(bytes) {\n if (!bytes) return '0 B';\n const k = 1024;\n const sizes = ['B', 'KB', 'MB', 'GB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\n}\n\n// File Viewer Modal Functions\nwindow.showFileViewerModal = async function(filePath) {\n console.log('[FileViewer] Opening file:', filePath);\n \n // Use the dashboard's current working directory\n let workingDir = '';\n if (window.dashboard && window.dashboard.currentWorkingDir) {\n workingDir = window.dashboard.currentWorkingDir;\n console.log('[FileViewer] Using working directory:', workingDir);\n }\n\n // Create modal if it doesn't exist\n let modal = document.getElementById('file-viewer-modal');\n if (!modal) {\n console.log('[FileViewer] Creating new modal');\n modal = createFileViewerModal();\n document.body.appendChild(modal);\n\n // Small delay to ensure DOM is fully updated\n await new Promise(resolve => setTimeout(resolve, 10));\n }\n\n // Show the modal as flex container first (ensures proper rendering)\n modal.style.display = 'flex';\n document.body.style.overflow = 'hidden'; // Prevent background scrolling\n\n // Update modal content\n updateFileViewerModal(modal, filePath, workingDir).catch(error => {\n console.error('Error updating file viewer modal:', error);\n // Show error in the modal\n displayFileContentError(modal, { error: error.message });\n });\n};\n\nwindow.hideFileViewerModal = function() {\n const modal = document.getElementById('file-viewer-modal');\n if (modal) {\n modal.style.display = 'none';\n document.body.style.overflow = ''; // Restore background scrolling\n }\n};\n\nwindow.copyFileContent = function() {\n const modal = document.getElementById('file-viewer-modal');\n if (!modal) return;\n\n const codeElement = modal.querySelector('.file-content-code');\n if (!codeElement) return;\n\n const text = codeElement.textContent;\n\n if (navigator.clipboard && navigator.clipboard.writeText) {\n navigator.clipboard.writeText(text).then(() => {\n // Show brief feedback\n const button = modal.querySelector('.file-content-copy');\n if (button) {\n const originalText = button.textContent;\n button.textContent = '✅ Copied!';\n setTimeout(() => {\n button.textContent = originalText;\n }, 2000);\n }\n }).catch(err => {\n console.error('Failed to copy text:', err);\n });\n } else {\n // Fallback for older browsers\n const textarea = document.createElement('textarea');\n textarea.value = text;\n document.body.appendChild(textarea);\n textarea.select();\n document.execCommand('copy');\n document.body.removeChild(textarea);\n\n const button = modal.querySelector('.file-content-copy');\n if (button) {\n const originalText = button.textContent;\n button.textContent = '✅ Copied!';\n setTimeout(() => {\n button.textContent = originalText;\n }, 2000);\n }\n }\n};\n\n\n\n\nfunction displayFileContentError(modal, result) {\n const errorArea = modal.querySelector('.file-viewer-error');\n const messageElement = modal.querySelector('.error-message');\n const suggestionsElement = modal.querySelector('.error-suggestions');\n const loadingElement = modal.querySelector('.file-viewer-loading');\n const contentArea = modal.querySelector('.file-viewer-content-area');\n \n // Hide loading and content areas, show error\n if (loadingElement) {\n loadingElement.style.display = 'none';\n }\n if (contentArea) {\n contentArea.style.display = 'none';\n }\n if (errorArea) {\n errorArea.style.display = 'flex';\n }\n\n // Create user-friendly error messages\n let errorMessage = result.error || 'Unknown error occurred';\n\n if (errorMessage.includes('not found')) {\n errorMessage = '📁 File not found or not accessible';\n } else if (errorMessage.includes('permission')) {\n errorMessage = '🔒 Permission denied accessing this file';\n } else if (errorMessage.includes('too large')) {\n errorMessage = '📏 File is too large to display';\n } else if (errorMessage.includes('socket connection')) {\n errorMessage = '🔌 Not connected to the server. Please check your connection.';\n } else if (errorMessage.includes('timeout')) {\n errorMessage = '⏱️ Request timed out. The server may be busy or unresponsive.';\n } else if (!errorMessage.includes('📁') && !errorMessage.includes('🔒') && !errorMessage.includes('📏')) {\n errorMessage = `⚠️ ${errorMessage}`;\n }\n\n if (messageElement) {\n messageElement.textContent = errorMessage;\n }\n\n // Add suggestions if available\n if (suggestionsElement) {\n if (result.suggestions && result.suggestions.length > 0) {\n suggestionsElement.innerHTML = `\n <h4>Suggestions:</h4>\n <ul>\n ${result.suggestions.map(suggestion => `<li>${suggestion}</li>`).join('')}\n </ul>\n `;\n } else {\n suggestionsElement.innerHTML = `\n <h4>Try:</h4>\n <ul>\n <li>Check if the file exists and is readable</li>\n <li>Verify file permissions</li>\n <li>Ensure the monitoring server has access to this file</li>\n </ul>\n `;\n }\n }\n\n console.log('📋 Displaying file content error:', {\n originalError: result.error,\n processedMessage: errorMessage,\n suggestions: result.suggestions\n });\n\n if (errorArea) {\n errorArea.style.display = 'block';\n }\n}\n\n// Search Viewer Modal Functions\nwindow.showSearchViewerModal = function(searchParams, searchResults) {\n // Create modal if it doesn't exist\n let modal = document.getElementById('search-viewer-modal');\n if (!modal) {\n modal = createSearchViewerModal();\n document.body.appendChild(modal);\n }\n\n // Update modal content\n updateSearchViewerModal(modal, searchParams, searchResults);\n\n // Show the modal as flex container\n modal.style.display = 'flex';\n document.body.style.overflow = 'hidden'; // Prevent background scrolling\n};\n\nwindow.hideSearchViewerModal = function() {\n const modal = document.getElementById('search-viewer-modal');\n if (modal) {\n modal.style.display = 'none';\n document.body.style.overflow = ''; // Restore background scrolling\n }\n};\n\nfunction createSearchViewerModal() {\n const modal = document.createElement('div');\n modal.id = 'search-viewer-modal';\n modal.className = 'modal search-viewer-modal';\n\n modal.innerHTML = `\n <div class=\"modal-content search-viewer-content\">\n <div class=\"search-viewer-header\">\n <h2 class=\"search-viewer-title\">\n <span class=\"search-viewer-icon\">🔍</span>\n <span class=\"search-viewer-title-text\">Search Results</span>\n </h2>\n <button class=\"search-viewer-close\" onclick=\"hideSearchViewerModal()\">\n <span>×</span>\n </button>\n </div>\n <div class=\"search-viewer-body\">\n <div class=\"search-params-section\">\n <h3>Search Parameters</h3>\n <pre class=\"search-params-display\"></pre>\n </div>\n <div class=\"search-results-section\">\n <h3>Search Results</h3>\n <div class=\"search-results-display\"></div>\n </div>\n </div>\n </div>\n `;\n\n // Close modal when clicking outside\n modal.addEventListener('click', (e) => {\n if (e.target === modal) {\n hideSearchViewerModal();\n }\n });\n\n // Close modal on Escape key\n document.addEventListener('keydown', (e) => {\n if (e.key === 'Escape' && modal.style.display === 'flex') {\n hideSearchViewerModal();\n }\n });\n\n return modal;\n}\n\nfunction updateSearchViewerModal(modal, searchParams, searchResults) {\n const paramsDisplay = modal.querySelector('.search-params-display');\n const resultsDisplay = modal.querySelector('.search-results-display');\n\n // Display search parameters in formatted JSON\n if (paramsDisplay && searchParams) {\n paramsDisplay.textContent = JSON.stringify(searchParams, null, 2);\n }\n\n // Display search results\n if (resultsDisplay && searchResults) {\n let resultsHTML = '';\n \n if (typeof searchResults === 'string') {\n // If results are a string, display as preformatted text\n resultsHTML = `<pre class=\"search-results-text\">${escapeHtml(searchResults)}</pre>`;\n } else if (Array.isArray(searchResults)) {\n // If results are an array, display as a list\n resultsHTML = '<ul class=\"search-results-list\">';\n searchResults.forEach(result => {\n if (typeof result === 'object') {\n resultsHTML += `<li><pre>${JSON.stringify(result, null, 2)}</pre></li>`;\n } else {\n resultsHTML += `<li>${escapeHtml(String(result))}</li>`;\n }\n });\n resultsHTML += '</ul>';\n } else if (typeof searchResults === 'object') {\n // If results are an object, display as formatted JSON\n resultsHTML = `<pre class=\"search-results-json\">${JSON.stringify(searchResults, null, 2)}</pre>`;\n } else {\n // Fallback: display as text\n resultsHTML = `<div class=\"search-results-text\">${escapeHtml(String(searchResults))}</div>`;\n }\n \n resultsDisplay.innerHTML = resultsHTML;\n }\n}\n\nfunction escapeHtml(text) {\n const div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML;\n}\n\n// Global window functions for backward compatibility\nwindow.showAgentInstanceDetails = function(instanceId) {\n if (window.dashboard && typeof window.dashboard.showAgentInstanceDetails === 'function') {\n window.dashboard.showAgentInstanceDetails(instanceId);\n } else {\n console.error('Dashboard not available or method not found');\n }\n};\n\n// Initialize dashboard when page loads\ndocument.addEventListener('DOMContentLoaded', function() {\n try {\n // Create dashboard instance\n window.dashboard = new Dashboard();\n \n // Call post-initialization setup that requires window.dashboard\n // This must happen after window.dashboard is set\n if (window.dashboard && typeof window.dashboard.postInit === 'function') {\n window.dashboard.postInit();\n }\n \n console.log('Dashboard loaded and initialized successfully');\n \n // Dispatch custom event to signal dashboard ready\n document.dispatchEvent(new CustomEvent('dashboardReady', {\n detail: { dashboard: window.dashboard }\n }));\n } catch (error) {\n console.error('Failed to initialize dashboard:', error);\n // Show user-friendly error message\n document.body.innerHTML = `\n <div style=\"padding: 20px; font-family: sans-serif;\">\n <h1>Dashboard Initialization Error</h1>\n <p>The dashboard failed to load properly. Please refresh the page or check the console for details.</p>\n <pre style=\"background: #f5f5f5; padding: 10px; border-radius: 4px;\">${error.message}</pre>\n </div>\n `;\n }\n});\n\n// ES6 Module export\nexport { Dashboard };\nexport default Dashboard;\n"],"names":["Dashboard","constructor","this","eventViewer","moduleViewer","sessionManager","activityTreeRetryCount","maxRetryAttempts","socketManager","agentInference","agentHierarchy","uiStateManager","eventProcessor","exportManager","workingDirectoryManager","fileToolTracker","buildTracker","init","console","log","fetchServerConfig","initializeSocketManager","initializeCoreComponents","initializeBuildTracker","initializeAgentInference","initializeAgentHierarchy","initializeUIStateManager","initializeWorkingDirectoryManager","initializeFileToolTracker","initializeEventProcessor","initializeExportManager","setupModuleInteractions","initializeFromURL","error","fetch","then","response","json","config","window","dashboardConfig","workingDirEl","document","getElementById","workingDirectory","textContent","gitBranchEl","gitBranch","catch","warn","validateInitialization","missing","name","component","filter","c","length","map","postInit","dashboard","SocketManager","setupConnectionControls","socketClient","getSocketClient","EventViewer","ModuleViewer","SessionManager","BuildTracker","setSocketClient","mountBuildTracker","headerTitle","querySelector","mount","setTimeout","AgentInference","initialize","AgentHierarchy","render","expandAllNodes","collapseAllNodes","updateWithNewEvents","UIStateManager","setupTabFilters","WorkingDirectoryManager","FileToolTracker","EventProcessor","ExportManager","onEventUpdate","events","first_event","has_tool_events","some","e","tool_name","data","hook_events","type","tool_subtypes","subtype","updateFileOperations","updateToolCalls","fileOps","getFileOperations","toolCalls","getToolCalls","size","processAgentInference","CodeViewer","refreshFromFileToolTracker","getCurrentTab","scrollListToBottom","renderCurrentTab","onConnectionStatusChange","status","updateGitBranch","getCurrentWorkingDir","addEventListener","updateTabNavigationItems","clear","showCardDetails","detail","tabName","index","agentsSearchInput","agentsTypeFilter","toolsSearchInput","toolsTypeFilter","filesSearchInput","filesTypeFilter","params","URLSearchParams","location","search","currentTab","show","ActivityTree","activityTreeInstance","initialized","renderWhenVisible","forceShow","activityTree","activityContainer","innerHTML","renderAgents","renderTools","renderFiles","getSelectedCard","tab","updateCardSelectionUI","updateUnifiedSelectionUI","agentsList","searchText","value","agentType","flatHTML","renderAgentsFlat","removeHierarchyControls","uniqueInstances","getUniqueAgentInstances","updateAgentsFilterDropdowns","existingControls","remove","eventAgentMap","getEventAgentMap","agentEvents","forEach","event","inference","get","includeEvent","searchLower","toLowerCase","agentName","includes","JSON","stringify","push","timestamp","Date","item","listIndex","action","actionIcon","details","event_type","getToolIcon","tool_parameters","file_path","command","substring","pattern","query","formatTimestamp","getAgentIcon","getStatusIcon","escapeHtml","join","PM","toolName","Read","Write","Edit","Bash","Grep","Glob","LS","Task","active","completed","pending","toLocaleTimeString","hour","minute","second","hour12","text","div","createElement","toolsList","toolCallsArray","Array","from","entries","uniqueToolInstances","getUniqueToolInstances","toolHTML","generateToolHTML","updateToolsFilterDropdowns","filesList","fileOperations","filesArray","uniqueFileInstances","getUniqueFileInstances","fileHTML","generateFileHTML","updateFilesFilterDropdowns","agentTypes","Set","instance","add","sortedTypes","trim","populateFilterDropdown","toolNames","key","toolCall","operations","flatMap","path","op","operation","selectId","values","allOption","select","currentValue","sortedValues","sort","a","b","localeCompare","option","appendChild","showEventDetails","showAgentDetailsByIndex","showToolDetailsByIndex","showFileDetailsByIndex","getFilteredEventsForTab","isArray","filteredSingleEvent","applyAgentsFilters","showAgentEvent","showAgentInstanceDetails","instanceId","getPMDelegations","impliedInstance","find","inst","id","showImpliedAgentDetails","showAgentInstance","eventCount","startTime","pmCall","showImpliedAgent","note","filteredToolCalls","applyToolCallFilters","toolCallKey","showToolCallDetails","applyFilesFilters","filePath","showFileDetails","getToolCall","showToolCall","fileData","getFileOperationsForFile","showFileOperations","switchTab","selectCard","clearEvents","exportEvents","clearSelection","currentWorkingDir","dir","setWorkingDirectory","selectedCard","tabNavigation","async","updateFileViewerModal","modal","workingDir","filePathElement","fileSizeElement","loadingElement","errorElement","contentArea","style","display","socket","connected","Error","responsePromise","Promise","resolve","reject","responseHandler","off","success","on","requestData","working_dir","emit","result","loadingEl","extensionElement","encodingElement","codeElement","extension","encoding","bytes","k","sizes","i","Math","floor","parseFloat","pow","toFixed","formatFileSize","file_size","content","code","escaped","replace","addLineNumbers","highlightJavaScript","highlightPython","highlightJSON","highlightCSS","highlightHTML","highlightMarkdown","highlightCode","wrapper","modalContent","header","toolbar","availableHeight","offsetHeight","maxHeight","overflowY","displayFileContent","loadingEl2","errorMessage","message","suggestions","errorArea","messageElement","suggestionsElement","s","originalError","processedMessage","displayFileError","split","line","String","padStart","copyFileContent","navigator","clipboard","writeText","button","originalText","err","textarea","body","execCommand","removeChild","showFileViewerModal","className","target","hideFileViewerModal","createFileViewerModal","overflow","suggestion","displayFileContentError","showSearchViewerModal","searchParams","searchResults","hideSearchViewerModal","createSearchViewerModal","paramsDisplay","resultsDisplay","resultsHTML","updateSearchViewerModal","dispatchEvent","CustomEvent"],"mappings":"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"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Browser Extension Error Handler
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* WHY: Browser extensions (like password managers, ad blockers, etc.) often inject
|
|
5
5
|
* scripts that use Chrome's message passing API. When these extensions have bugs
|
|
6
6
|
* or async handlers that don't properly respond, they generate console errors.
|
|
7
|
-
*
|
|
7
|
+
*
|
|
8
8
|
* This module prevents those external errors from affecting our dashboard and
|
|
9
9
|
* provides clean error handling for known browser extension issues.
|
|
10
|
-
*
|
|
10
|
+
*
|
|
11
11
|
* DESIGN DECISION: Rather than trying to fix third-party extension bugs, we:
|
|
12
12
|
* 1. Detect and suppress known harmless extension errors
|
|
13
13
|
* 2. Log them separately for debugging if needed
|
|
@@ -26,21 +26,21 @@ class ExtensionErrorHandler {
|
|
|
26
26
|
/Cannot access contents of url.*Extension/i,
|
|
27
27
|
/Blocked a frame with origin.*from accessing a cross-origin frame/i
|
|
28
28
|
];
|
|
29
|
-
|
|
29
|
+
|
|
30
30
|
this.setupErrorHandling();
|
|
31
31
|
}
|
|
32
|
-
|
|
32
|
+
|
|
33
33
|
/**
|
|
34
34
|
* Set up global error handling to catch and suppress extension errors
|
|
35
35
|
*/
|
|
36
36
|
setupErrorHandling() {
|
|
37
37
|
// Store original console.error
|
|
38
38
|
const originalConsoleError = console.error;
|
|
39
|
-
|
|
39
|
+
|
|
40
40
|
// Override console.error to filter extension errors
|
|
41
41
|
console.error = (...args) => {
|
|
42
42
|
const errorString = args.join(' ');
|
|
43
|
-
|
|
43
|
+
|
|
44
44
|
// Check if this is a known extension error
|
|
45
45
|
if (this.isExtensionError(errorString)) {
|
|
46
46
|
// Log to our internal list for debugging
|
|
@@ -49,41 +49,41 @@ class ExtensionErrorHandler {
|
|
|
49
49
|
error: errorString,
|
|
50
50
|
suppressed: true
|
|
51
51
|
});
|
|
52
|
-
|
|
52
|
+
|
|
53
53
|
// Optionally log with a prefix if debug mode is enabled
|
|
54
54
|
if (window.DEBUG_EXTENSION_ERRORS) {
|
|
55
55
|
originalConsoleError.call(console, '[SUPPRESSED EXTENSION ERROR]:', ...args);
|
|
56
56
|
}
|
|
57
|
-
|
|
57
|
+
|
|
58
58
|
// Don't propagate the error
|
|
59
59
|
return;
|
|
60
60
|
}
|
|
61
|
-
|
|
61
|
+
|
|
62
62
|
// Pass through non-extension errors
|
|
63
63
|
originalConsoleError.call(console, ...args);
|
|
64
64
|
};
|
|
65
|
-
|
|
65
|
+
|
|
66
66
|
// Handle uncaught promise rejections that might come from extensions
|
|
67
67
|
window.addEventListener('unhandledrejection', (event) => {
|
|
68
68
|
const errorString = event.reason?.toString() || '';
|
|
69
|
-
|
|
69
|
+
|
|
70
70
|
if (this.isExtensionError(errorString)) {
|
|
71
71
|
// Prevent the default error handling
|
|
72
72
|
event.preventDefault();
|
|
73
|
-
|
|
73
|
+
|
|
74
74
|
this.extensionErrors.push({
|
|
75
75
|
timestamp: new Date().toISOString(),
|
|
76
76
|
error: errorString,
|
|
77
77
|
type: 'unhandled_rejection',
|
|
78
78
|
suppressed: true
|
|
79
79
|
});
|
|
80
|
-
|
|
80
|
+
|
|
81
81
|
if (window.DEBUG_EXTENSION_ERRORS) {
|
|
82
82
|
console.warn('[SUPPRESSED EXTENSION REJECTION]:', event.reason);
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
});
|
|
86
|
-
|
|
86
|
+
|
|
87
87
|
// Add a global message event listener with proper error handling
|
|
88
88
|
// This prevents our app from being affected by misbehaving extensions
|
|
89
89
|
window.addEventListener('message', (event) => {
|
|
@@ -91,13 +91,13 @@ class ExtensionErrorHandler {
|
|
|
91
91
|
if (event.origin !== window.location.origin) {
|
|
92
92
|
return;
|
|
93
93
|
}
|
|
94
|
-
|
|
94
|
+
|
|
95
95
|
// Add timeout protection for any async operations
|
|
96
96
|
if (event.data && event.data.requiresResponse) {
|
|
97
97
|
const timeoutId = setTimeout(() => {
|
|
98
98
|
console.warn('Message handler timeout - no response sent');
|
|
99
99
|
}, 5000);
|
|
100
|
-
|
|
100
|
+
|
|
101
101
|
// Clear timeout when response is sent
|
|
102
102
|
if (event.ports && event.ports[0]) {
|
|
103
103
|
const originalPostMessage = event.ports[0].postMessage;
|
|
@@ -109,7 +109,7 @@ class ExtensionErrorHandler {
|
|
|
109
109
|
}
|
|
110
110
|
});
|
|
111
111
|
}
|
|
112
|
-
|
|
112
|
+
|
|
113
113
|
/**
|
|
114
114
|
* Check if an error string matches known extension error patterns
|
|
115
115
|
* @param {string} errorString - The error message to check
|
|
@@ -118,7 +118,7 @@ class ExtensionErrorHandler {
|
|
|
118
118
|
isExtensionError(errorString) {
|
|
119
119
|
return this.suppressedPatterns.some(pattern => pattern.test(errorString));
|
|
120
120
|
}
|
|
121
|
-
|
|
121
|
+
|
|
122
122
|
/**
|
|
123
123
|
* Get suppressed extension errors for debugging
|
|
124
124
|
* @returns {Array} - List of suppressed errors
|
|
@@ -126,21 +126,21 @@ class ExtensionErrorHandler {
|
|
|
126
126
|
getSuppressedErrors() {
|
|
127
127
|
return this.extensionErrors;
|
|
128
128
|
}
|
|
129
|
-
|
|
129
|
+
|
|
130
130
|
/**
|
|
131
131
|
* Clear the suppressed errors list
|
|
132
132
|
*/
|
|
133
133
|
clearSuppressedErrors() {
|
|
134
134
|
this.extensionErrors = [];
|
|
135
135
|
}
|
|
136
|
-
|
|
136
|
+
|
|
137
137
|
/**
|
|
138
138
|
* Enable or disable debug logging of extension errors
|
|
139
139
|
* @param {boolean} enabled - Whether to enable debug logging
|
|
140
140
|
*/
|
|
141
141
|
setDebugMode(enabled) {
|
|
142
142
|
window.DEBUG_EXTENSION_ERRORS = enabled;
|
|
143
|
-
|
|
143
|
+
|
|
144
144
|
if (enabled) {
|
|
145
145
|
console.log('Extension error debug mode enabled. Suppressed errors will be logged with [SUPPRESSED] prefix.');
|
|
146
146
|
console.log('Current suppressed errors:', this.getSuppressedErrors());
|