claude-mpm 4.21.3__py3-none-any.whl → 5.0.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/BASE_PM.md +12 -0
- claude_mpm/agents/OUTPUT_STYLE.md +3 -48
- claude_mpm/agents/PM_INSTRUCTIONS.md +632 -334
- claude_mpm/agents/WORKFLOW.md +75 -2
- claude_mpm/agents/__init__.py +6 -0
- claude_mpm/agents/agent_loader.py +1 -4
- claude_mpm/agents/base_agent.json +6 -3
- claude_mpm/agents/frontmatter_validator.py +1 -1
- claude_mpm/agents/templates/{circuit_breakers.md → circuit-breakers.md} +370 -3
- claude_mpm/agents/templates/context-management-examples.md +544 -0
- claude_mpm/agents/templates/{pm_red_flags.md → pm-red-flags.md} +89 -19
- claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
- claude_mpm/agents/templates/research-gate-examples.md +669 -0
- claude_mpm/agents/templates/structured-questions-examples.md +615 -0
- claude_mpm/agents/templates/ticket-completeness-examples.md +139 -0
- claude_mpm/agents/templates/ticketing-examples.md +277 -0
- claude_mpm/cli/__init__.py +38 -2
- claude_mpm/cli/commands/agent_source.py +774 -0
- claude_mpm/cli/commands/agent_state_manager.py +125 -20
- claude_mpm/cli/commands/agents.py +684 -13
- claude_mpm/cli/commands/agents_cleanup.py +210 -0
- claude_mpm/cli/commands/agents_discover.py +338 -0
- claude_mpm/cli/commands/aggregate.py +1 -1
- claude_mpm/cli/commands/analyze.py +3 -3
- claude_mpm/cli/commands/auto_configure.py +2 -6
- claude_mpm/cli/commands/cleanup.py +1 -1
- claude_mpm/cli/commands/config.py +7 -4
- claude_mpm/cli/commands/configure.py +478 -44
- claude_mpm/cli/commands/configure_agent_display.py +4 -4
- claude_mpm/cli/commands/configure_navigation.py +63 -46
- claude_mpm/cli/commands/debug.py +12 -12
- claude_mpm/cli/commands/doctor.py +10 -2
- claude_mpm/cli/commands/hook_errors.py +277 -0
- claude_mpm/cli/commands/local_deploy.py +1 -4
- claude_mpm/cli/commands/mcp_install_commands.py +1 -1
- claude_mpm/cli/commands/mpm_init/core.py +50 -2
- claude_mpm/cli/commands/mpm_init/git_activity.py +10 -10
- claude_mpm/cli/commands/mpm_init/prompts.py +6 -6
- claude_mpm/cli/commands/run.py +124 -128
- claude_mpm/cli/commands/skill_source.py +694 -0
- claude_mpm/cli/commands/skills.py +435 -1
- claude_mpm/cli/executor.py +78 -3
- claude_mpm/cli/interactive/agent_wizard.py +919 -41
- claude_mpm/cli/parsers/agent_source_parser.py +171 -0
- claude_mpm/cli/parsers/agents_parser.py +173 -4
- claude_mpm/cli/parsers/base_parser.py +49 -0
- claude_mpm/cli/parsers/config_parser.py +96 -43
- claude_mpm/cli/parsers/skill_source_parser.py +169 -0
- claude_mpm/cli/parsers/skills_parser.py +138 -0
- claude_mpm/cli/parsers/source_parser.py +138 -0
- claude_mpm/cli/startup.py +499 -84
- claude_mpm/cli/startup_display.py +480 -0
- claude_mpm/cli/utils.py +1 -1
- claude_mpm/cli_module/commands.py +1 -1
- claude_mpm/commands/{mpm-auto-configure.md → mpm-agents-auto-configure.md} +9 -0
- claude_mpm/commands/mpm-agents-detect.md +9 -0
- claude_mpm/commands/{mpm-agents.md → mpm-agents-list.md} +9 -0
- claude_mpm/commands/mpm-agents-recommend.md +9 -0
- claude_mpm/commands/{mpm-config.md → mpm-config-view.md} +9 -0
- claude_mpm/commands/mpm-doctor.md +9 -0
- claude_mpm/commands/mpm-help.md +11 -2
- claude_mpm/commands/mpm-init.md +27 -2
- claude_mpm/commands/mpm-monitor.md +9 -0
- claude_mpm/commands/{mpm-resume.md → mpm-session-resume.md} +9 -0
- claude_mpm/commands/mpm-status.md +9 -0
- claude_mpm/commands/{mpm-organize.md → mpm-ticket-organize.md} +9 -0
- claude_mpm/commands/mpm-ticket-view.md +552 -0
- claude_mpm/commands/mpm-version.md +9 -0
- claude_mpm/commands/mpm.md +10 -0
- claude_mpm/config/agent_presets.py +258 -0
- claude_mpm/config/agent_sources.py +325 -0
- claude_mpm/config/skill_sources.py +590 -0
- claude_mpm/constants.py +12 -0
- claude_mpm/core/api_validator.py +1 -1
- claude_mpm/core/claude_runner.py +17 -10
- claude_mpm/core/config.py +24 -0
- claude_mpm/core/constants.py +1 -1
- claude_mpm/core/framework/__init__.py +3 -16
- claude_mpm/core/framework/loaders/instruction_loader.py +25 -5
- claude_mpm/core/framework/processors/metadata_processor.py +1 -1
- claude_mpm/core/hook_error_memory.py +381 -0
- claude_mpm/core/hook_manager.py +41 -2
- claude_mpm/core/interactive_session.py +112 -5
- claude_mpm/core/logger.py +3 -1
- claude_mpm/core/oneshot_session.py +94 -4
- claude_mpm/dashboard/static/css/activity.css +69 -69
- claude_mpm/dashboard/static/css/connection-status.css +10 -10
- claude_mpm/dashboard/static/css/dashboard.css +15 -15
- claude_mpm/dashboard/static/js/components/activity-tree.js +178 -178
- claude_mpm/dashboard/static/js/components/agent-hierarchy.js +101 -101
- claude_mpm/dashboard/static/js/components/agent-inference.js +31 -31
- claude_mpm/dashboard/static/js/components/build-tracker.js +59 -59
- claude_mpm/dashboard/static/js/components/code-simple.js +107 -107
- claude_mpm/dashboard/static/js/components/connection-debug.js +101 -101
- claude_mpm/dashboard/static/js/components/diff-viewer.js +113 -113
- claude_mpm/dashboard/static/js/components/event-viewer.js +12 -12
- claude_mpm/dashboard/static/js/components/file-change-tracker.js +57 -57
- claude_mpm/dashboard/static/js/components/file-change-viewer.js +74 -74
- claude_mpm/dashboard/static/js/components/file-tool-tracker.js +6 -6
- claude_mpm/dashboard/static/js/components/file-viewer.js +42 -42
- claude_mpm/dashboard/static/js/components/module-viewer.js +27 -27
- claude_mpm/dashboard/static/js/components/session-manager.js +14 -14
- claude_mpm/dashboard/static/js/components/socket-manager.js +1 -1
- claude_mpm/dashboard/static/js/components/ui-state-manager.js +14 -14
- claude_mpm/dashboard/static/js/components/unified-data-viewer.js +110 -110
- claude_mpm/dashboard/static/js/components/working-directory.js +8 -8
- claude_mpm/dashboard/static/js/connection-manager.js +76 -76
- claude_mpm/dashboard/static/js/dashboard.js +76 -58
- claude_mpm/dashboard/static/js/extension-error-handler.js +22 -22
- claude_mpm/dashboard/static/js/socket-client.js +138 -121
- claude_mpm/dashboard/templates/code_simple.html +23 -23
- claude_mpm/dashboard/templates/index.html +18 -18
- claude_mpm/experimental/cli_enhancements.py +1 -5
- claude_mpm/hooks/claude_hooks/event_handlers.py +3 -1
- claude_mpm/hooks/claude_hooks/hook_handler.py +24 -7
- claude_mpm/hooks/claude_hooks/installer.py +45 -0
- claude_mpm/hooks/failure_learning/__init__.py +2 -8
- claude_mpm/hooks/failure_learning/failure_detection_hook.py +1 -6
- claude_mpm/hooks/failure_learning/fix_detection_hook.py +1 -6
- claude_mpm/hooks/failure_learning/learning_extraction_hook.py +1 -6
- claude_mpm/hooks/kuzu_response_hook.py +1 -5
- claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
- claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
- claude_mpm/models/git_repository.py +198 -0
- claude_mpm/scripts/claude-hook-handler.sh +3 -3
- claude_mpm/scripts/start_activity_logging.py +3 -1
- claude_mpm/services/agents/agent_builder.py +45 -9
- claude_mpm/services/agents/agent_preset_service.py +238 -0
- claude_mpm/services/agents/agent_selection_service.py +484 -0
- claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
- claude_mpm/services/agents/deployment/agent_deployment.py +126 -2
- claude_mpm/services/agents/deployment/agent_discovery_service.py +105 -73
- claude_mpm/services/agents/deployment/agent_format_converter.py +1 -1
- claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +1 -5
- claude_mpm/services/agents/deployment/agent_metrics_collector.py +3 -3
- claude_mpm/services/agents/deployment/agent_restore_handler.py +1 -4
- claude_mpm/services/agents/deployment/agent_template_builder.py +236 -15
- claude_mpm/services/agents/deployment/agents_directory_resolver.py +101 -15
- claude_mpm/services/agents/deployment/async_agent_deployment.py +2 -1
- claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -3
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +115 -15
- claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +2 -2
- claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +1 -4
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +363 -0
- claude_mpm/services/agents/deployment/single_agent_deployer.py +2 -2
- claude_mpm/services/agents/deployment/system_instructions_deployer.py +168 -46
- claude_mpm/services/agents/deployment/validation/deployment_validator.py +2 -2
- claude_mpm/services/agents/git_source_manager.py +629 -0
- claude_mpm/services/agents/loading/framework_agent_loader.py +9 -12
- claude_mpm/services/agents/local_template_manager.py +50 -10
- claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
- claude_mpm/services/agents/sources/__init__.py +13 -0
- claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
- claude_mpm/services/agents/sources/git_source_sync_service.py +1055 -0
- claude_mpm/services/agents/startup_sync.py +239 -0
- claude_mpm/services/agents/toolchain_detector.py +474 -0
- claude_mpm/services/cli/session_pause_manager.py +1 -1
- claude_mpm/services/cli/unified_dashboard_manager.py +1 -1
- claude_mpm/services/command_deployment_service.py +92 -1
- claude_mpm/services/core/interfaces/__init__.py +1 -3
- claude_mpm/services/core/interfaces/health.py +1 -4
- claude_mpm/services/core/models/__init__.py +2 -11
- claude_mpm/services/diagnostics/checks/__init__.py +4 -0
- claude_mpm/services/diagnostics/checks/agent_check.py +0 -2
- claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
- claude_mpm/services/diagnostics/checks/instructions_check.py +1 -2
- claude_mpm/services/diagnostics/checks/mcp_check.py +0 -1
- claude_mpm/services/diagnostics/checks/monitor_check.py +0 -1
- claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
- claude_mpm/services/diagnostics/diagnostic_runner.py +9 -0
- claude_mpm/services/diagnostics/doctor_reporter.py +40 -10
- claude_mpm/services/event_bus/direct_relay.py +3 -3
- claude_mpm/services/event_bus/event_bus.py +36 -3
- claude_mpm/services/events/consumers/logging.py +1 -2
- claude_mpm/services/git/__init__.py +21 -0
- claude_mpm/services/git/git_operations_service.py +494 -0
- claude_mpm/services/github/__init__.py +21 -0
- claude_mpm/services/github/github_cli_service.py +397 -0
- claude_mpm/services/infrastructure/monitoring/__init__.py +1 -5
- claude_mpm/services/infrastructure/monitoring/aggregator.py +1 -6
- claude_mpm/services/infrastructure/monitoring/resources.py +1 -1
- claude_mpm/services/instructions/__init__.py +9 -0
- claude_mpm/services/instructions/instruction_cache_service.py +374 -0
- claude_mpm/services/local_ops/__init__.py +3 -13
- claude_mpm/services/local_ops/health_checks/__init__.py +1 -3
- claude_mpm/services/local_ops/health_manager.py +1 -4
- claude_mpm/services/local_ops/process_manager.py +1 -1
- claude_mpm/services/local_ops/resource_monitor.py +2 -2
- claude_mpm/services/mcp_gateway/config/configuration.py +1 -1
- claude_mpm/services/mcp_gateway/server/mcp_gateway.py +1 -6
- claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -2
- claude_mpm/services/mcp_gateway/tools/document_summarizer.py +1 -1
- claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +6 -2
- claude_mpm/services/memory/optimizer.py +1 -1
- claude_mpm/services/model/model_router.py +8 -9
- claude_mpm/services/monitor/daemon.py +1 -1
- claude_mpm/services/monitor/server.py +2 -2
- claude_mpm/services/native_agent_converter.py +356 -0
- claude_mpm/services/port_manager.py +1 -1
- claude_mpm/services/pr/__init__.py +14 -0
- claude_mpm/services/pr/pr_template_service.py +329 -0
- claude_mpm/services/project/documentation_manager.py +2 -1
- claude_mpm/services/project/toolchain_analyzer.py +3 -1
- claude_mpm/services/runner_configuration_service.py +1 -0
- claude_mpm/services/self_upgrade_service.py +165 -7
- claude_mpm/services/skills/__init__.py +18 -0
- claude_mpm/services/skills/git_skill_source_manager.py +1169 -0
- claude_mpm/services/skills/skill_discovery_service.py +568 -0
- claude_mpm/services/skills_config.py +547 -0
- claude_mpm/services/skills_deployer.py +955 -0
- claude_mpm/services/socketio/handlers/connection.py +1 -1
- claude_mpm/services/socketio/handlers/git.py +2 -2
- claude_mpm/services/socketio/server/core.py +1 -4
- claude_mpm/services/socketio/server/main.py +1 -3
- claude_mpm/services/system_instructions_service.py +1 -3
- claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +0 -3
- claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +0 -1
- claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +1 -1
- claude_mpm/services/unified/deployment_strategies/vercel.py +1 -5
- claude_mpm/services/unified/unified_deployment.py +1 -5
- claude_mpm/services/version_control/conflict_resolution.py +6 -4
- claude_mpm/services/visualization/__init__.py +1 -5
- claude_mpm/services/visualization/mermaid_generator.py +2 -3
- claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
- claude_mpm/skills/bundled/performance-profiling.md +6 -0
- claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +2 -2
- claude_mpm/skills/skills_registry.py +0 -1
- claude_mpm/templates/questions/__init__.py +38 -0
- claude_mpm/templates/questions/base.py +193 -0
- claude_mpm/templates/questions/pr_strategy.py +311 -0
- claude_mpm/templates/questions/project_init.py +385 -0
- claude_mpm/templates/questions/ticket_mgmt.py +394 -0
- claude_mpm/tools/__main__.py +8 -8
- claude_mpm/tools/code_tree_analyzer/analysis.py +1 -1
- claude_mpm/utils/agent_dependency_loader.py +80 -13
- claude_mpm/utils/dependency_cache.py +3 -1
- claude_mpm/utils/gitignore.py +241 -0
- claude_mpm/utils/log_cleanup.py +3 -3
- claude_mpm/utils/progress.py +383 -0
- claude_mpm/utils/robust_installer.py +3 -5
- claude_mpm/utils/structured_questions.py +619 -0
- {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/METADATA +429 -59
- {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/RECORD +252 -425
- claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -17
- claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +0 -3
- claude_mpm/agents/templates/agent-manager.json +0 -273
- claude_mpm/agents/templates/agentic-coder-optimizer.json +0 -248
- claude_mpm/agents/templates/api_qa.json +0 -180
- claude_mpm/agents/templates/clerk-ops.json +0 -235
- claude_mpm/agents/templates/code_analyzer.json +0 -101
- claude_mpm/agents/templates/content-agent.json +0 -358
- claude_mpm/agents/templates/dart_engineer.json +0 -307
- claude_mpm/agents/templates/data_engineer.json +0 -225
- claude_mpm/agents/templates/documentation.json +0 -211
- claude_mpm/agents/templates/engineer.json +0 -210
- claude_mpm/agents/templates/gcp_ops_agent.json +0 -253
- claude_mpm/agents/templates/golang_engineer.json +0 -270
- claude_mpm/agents/templates/imagemagick.json +0 -264
- claude_mpm/agents/templates/java_engineer.json +0 -346
- claude_mpm/agents/templates/local_ops_agent.json +0 -1840
- claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +0 -39
- claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +0 -400
- claude_mpm/agents/templates/memory_manager.json +0 -158
- claude_mpm/agents/templates/nextjs_engineer.json +0 -285
- claude_mpm/agents/templates/ops.json +0 -185
- claude_mpm/agents/templates/php-engineer.json +0 -287
- claude_mpm/agents/templates/product_owner.json +0 -338
- claude_mpm/agents/templates/project_organizer.json +0 -140
- claude_mpm/agents/templates/prompt-engineer.json +0 -737
- claude_mpm/agents/templates/python_engineer.json +0 -387
- claude_mpm/agents/templates/qa.json +0 -242
- claude_mpm/agents/templates/react_engineer.json +0 -238
- claude_mpm/agents/templates/refactoring_engineer.json +0 -276
- claude_mpm/agents/templates/research.json +0 -188
- claude_mpm/agents/templates/ruby-engineer.json +0 -280
- claude_mpm/agents/templates/rust_engineer.json +0 -275
- claude_mpm/agents/templates/security.json +0 -202
- claude_mpm/agents/templates/svelte-engineer.json +0 -225
- claude_mpm/agents/templates/ticketing.json +0 -177
- claude_mpm/agents/templates/typescript_engineer.json +0 -285
- claude_mpm/agents/templates/vercel_ops_agent.json +0 -412
- claude_mpm/agents/templates/version_control.json +0 -157
- claude_mpm/agents/templates/web_qa.json +0 -399
- claude_mpm/agents/templates/web_ui.json +0 -189
- claude_mpm/commands/mpm-tickets.md +0 -102
- claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
- claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +0 -188
- claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +0 -156
- claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +0 -38
- claude_mpm/dashboard/react/components/shared/FilterBar.module.css +0 -92
- claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +0 -248
- claude_mpm/dashboard/static/archive/activity_dashboard_test.html +0 -61
- claude_mpm/dashboard/static/archive/test_activity_connection.html +0 -179
- claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +0 -68
- claude_mpm/dashboard/static/archive/test_dashboard.html +0 -409
- claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +0 -519
- claude_mpm/dashboard/static/archive/test_dashboard_verification.html +0 -181
- claude_mpm/dashboard/static/archive/test_file_data.html +0 -315
- claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +0 -243
- claude_mpm/dashboard/static/archive/test_file_tree_fix.html +0 -234
- claude_mpm/dashboard/static/archive/test_file_tree_rename.html +0 -117
- claude_mpm/dashboard/static/archive/test_file_tree_tab.html +0 -115
- claude_mpm/dashboard/static/archive/test_file_viewer.html +0 -224
- claude_mpm/dashboard/static/archive/test_final_activity.html +0 -220
- claude_mpm/dashboard/static/archive/test_tab_fix.html +0 -139
- claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +0 -1
- claude_mpm/dashboard/static/built/components/activity-tree.js +0 -2
- claude_mpm/dashboard/static/built/components/agent-hierarchy.js +0 -777
- claude_mpm/dashboard/static/built/components/agent-inference.js +0 -2
- claude_mpm/dashboard/static/built/components/build-tracker.js +0 -333
- claude_mpm/dashboard/static/built/components/code-simple.js +0 -857
- claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +0 -353
- claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +0 -235
- claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +0 -409
- claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +0 -435
- claude_mpm/dashboard/static/built/components/code-tree.js +0 -2
- claude_mpm/dashboard/static/built/components/code-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/connection-debug.js +0 -654
- claude_mpm/dashboard/static/built/components/diff-viewer.js +0 -891
- claude_mpm/dashboard/static/built/components/event-processor.js +0 -2
- claude_mpm/dashboard/static/built/components/event-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/export-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/file-change-tracker.js +0 -443
- claude_mpm/dashboard/static/built/components/file-change-viewer.js +0 -690
- claude_mpm/dashboard/static/built/components/file-tool-tracker.js +0 -2
- claude_mpm/dashboard/static/built/components/file-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/hud-library-loader.js +0 -2
- claude_mpm/dashboard/static/built/components/hud-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/hud-visualizer.js +0 -2
- claude_mpm/dashboard/static/built/components/module-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/nav-bar.js +0 -145
- claude_mpm/dashboard/static/built/components/page-structure.js +0 -429
- claude_mpm/dashboard/static/built/components/session-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/socket-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/ui-state-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/unified-data-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/working-directory.js +0 -2
- claude_mpm/dashboard/static/built/connection-manager.js +0 -536
- claude_mpm/dashboard/static/built/dashboard.js +0 -2
- claude_mpm/dashboard/static/built/extension-error-handler.js +0 -164
- claude_mpm/dashboard/static/built/react/events.js +0 -30
- claude_mpm/dashboard/static/built/shared/dom-helpers.js +0 -396
- claude_mpm/dashboard/static/built/shared/event-bus.js +0 -330
- claude_mpm/dashboard/static/built/shared/event-filter-service.js +0 -540
- claude_mpm/dashboard/static/built/shared/logger.js +0 -385
- claude_mpm/dashboard/static/built/shared/page-structure.js +0 -249
- claude_mpm/dashboard/static/built/shared/tooltip-service.js +0 -253
- claude_mpm/dashboard/static/built/socket-client.js +0 -2
- claude_mpm/dashboard/static/built/tab-isolation-fix.js +0 -185
- claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +0 -1
- claude_mpm/dashboard/static/dist/components/activity-tree.js +0 -2
- claude_mpm/dashboard/static/dist/components/agent-inference.js +0 -2
- claude_mpm/dashboard/static/dist/components/code-tree.js +0 -2
- claude_mpm/dashboard/static/dist/components/code-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/event-processor.js +0 -2
- claude_mpm/dashboard/static/dist/components/event-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/export-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +0 -2
- claude_mpm/dashboard/static/dist/components/file-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-library-loader.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-visualizer.js +0 -2
- claude_mpm/dashboard/static/dist/components/module-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/session-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/socket-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/ui-state-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/working-directory.js +0 -2
- claude_mpm/dashboard/static/dist/dashboard.js +0 -2
- claude_mpm/dashboard/static/dist/react/events.js +0 -30
- claude_mpm/dashboard/static/dist/socket-client.js +0 -2
- claude_mpm/dashboard/static/events.html +0 -607
- claude_mpm/dashboard/static/index.html +0 -635
- claude_mpm/dashboard/static/js/shared/dom-helpers.js +0 -396
- claude_mpm/dashboard/static/js/shared/event-bus.js +0 -330
- claude_mpm/dashboard/static/js/shared/logger.js +0 -385
- claude_mpm/dashboard/static/js/shared/tooltip-service.js +0 -253
- claude_mpm/dashboard/static/js/stores/dashboard-store.js +0 -562
- claude_mpm/dashboard/static/legacy/activity.html +0 -736
- claude_mpm/dashboard/static/legacy/agents.html +0 -786
- claude_mpm/dashboard/static/legacy/files.html +0 -747
- claude_mpm/dashboard/static/legacy/tools.html +0 -831
- claude_mpm/dashboard/static/monitors.html +0 -431
- claude_mpm/dashboard/static/production/events.html +0 -659
- claude_mpm/dashboard/static/production/main.html +0 -698
- claude_mpm/dashboard/static/production/monitors.html +0 -483
- claude_mpm/dashboard/static/test-archive/dashboard.html +0 -635
- claude_mpm/dashboard/static/test-archive/debug-events.html +0 -147
- claude_mpm/dashboard/static/test-archive/test-navigation.html +0 -256
- claude_mpm/dashboard/static/test-archive/test-react-exports.html +0 -180
- claude_mpm/dashboard/static/test-archive/test_debug.html +0 -25
- claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +0 -79
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +0 -178
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +0 -577
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +0 -467
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +0 -537
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +0 -730
- claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +0 -112
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +0 -146
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +0 -412
- claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +0 -81
- claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +0 -362
- claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +0 -312
- claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +0 -152
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +0 -668
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +0 -587
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +0 -438
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +0 -391
- claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +0 -119
- claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +0 -148
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +0 -483
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +0 -452
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +0 -449
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +0 -411
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +0 -14
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +0 -58
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +0 -68
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +0 -69
- claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +0 -131
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +0 -325
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +0 -490
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +0 -425
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +0 -499
- claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +0 -86
- claude_mpm/skills/bundled/main/internal-comms/SKILL.md +0 -43
- claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +0 -47
- claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +0 -65
- claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +0 -30
- claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +0 -16
- claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +0 -160
- claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +0 -412
- claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +0 -602
- claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +0 -915
- claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +0 -916
- claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +0 -752
- claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +0 -1237
- claude_mpm/skills/bundled/main/skill-creator/SKILL.md +0 -189
- claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +0 -500
- claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +0 -464
- claude_mpm/skills/bundled/main/skill-creator/references/examples.md +0 -619
- claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +0 -437
- claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +0 -231
- claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +0 -170
- claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +0 -602
- claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +0 -821
- claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +0 -742
- claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +0 -726
- claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +0 -764
- claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +0 -831
- claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +0 -226
- claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +0 -901
- claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +0 -901
- claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +0 -775
- claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +0 -937
- claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +0 -770
- claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +0 -961
- claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +0 -119
- claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +0 -253
- claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +0 -145
- claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +0 -543
- claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +0 -741
- claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +0 -470
- claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +0 -458
- claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +0 -639
- claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +0 -140
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +0 -572
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +0 -411
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +0 -569
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +0 -695
- claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +0 -184
- claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +0 -459
- claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +0 -479
- claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +0 -687
- claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +0 -758
- claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +0 -868
- /claude_mpm/agents/templates/{git_file_tracking.md → git-file-tracking.md} +0 -0
- /claude_mpm/agents/templates/{pm_examples.md → pm-examples.md} +0 -0
- /claude_mpm/agents/templates/{response_format.md → response-format.md} +0 -0
- /claude_mpm/agents/templates/{validation_templates.md → validation-templates.md} +0 -0
- {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/WHEEL +0 -0
- {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/top_level.txt +0 -0
|
@@ -1,536 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Enhanced Connection Manager for Dashboard
|
|
3
|
-
*
|
|
4
|
-
* Provides robust connection management with:
|
|
5
|
-
* - Persistent client ID across reconnections
|
|
6
|
-
* - Event sequence tracking and replay
|
|
7
|
-
* - Exponential backoff for reconnection
|
|
8
|
-
* - Connection health monitoring
|
|
9
|
-
* - Visual status indicators
|
|
10
|
-
* - Local event buffering
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
class EnhancedConnectionManager {
|
|
14
|
-
constructor(socketClient) {
|
|
15
|
-
this.socketClient = socketClient;
|
|
16
|
-
this.socket = null;
|
|
17
|
-
this.clientId = this.loadClientId();
|
|
18
|
-
this.lastSequence = this.loadLastSequence();
|
|
19
|
-
this.connectionState = 'disconnected';
|
|
20
|
-
this.connectionQuality = 1.0;
|
|
21
|
-
this.reconnectAttempts = 0;
|
|
22
|
-
this.maxReconnectAttempts = 10;
|
|
23
|
-
this.baseReconnectDelay = 1000; // 1 second
|
|
24
|
-
this.maxReconnectDelay = 30000; // 30 seconds
|
|
25
|
-
this.heartbeatInterval = 30000; // 30 seconds
|
|
26
|
-
this.heartbeatTimer = null;
|
|
27
|
-
this.pingTimer = null;
|
|
28
|
-
this.lastPingTime = null;
|
|
29
|
-
this.lastPongTime = null;
|
|
30
|
-
this.missedHeartbeats = 0;
|
|
31
|
-
this.maxMissedHeartbeats = 3;
|
|
32
|
-
|
|
33
|
-
// Event buffering for offline mode
|
|
34
|
-
this.eventBuffer = [];
|
|
35
|
-
this.maxEventBuffer = 100;
|
|
36
|
-
|
|
37
|
-
// Connection metrics
|
|
38
|
-
this.metrics = {
|
|
39
|
-
connectTime: null,
|
|
40
|
-
disconnectTime: null,
|
|
41
|
-
totalConnections: 0,
|
|
42
|
-
totalReconnections: 0,
|
|
43
|
-
totalEvents: 0,
|
|
44
|
-
eventsAcked: 0,
|
|
45
|
-
lastActivity: null
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
// Status update callbacks
|
|
49
|
-
this.statusCallbacks = new Set();
|
|
50
|
-
this.qualityCallbacks = new Set();
|
|
51
|
-
|
|
52
|
-
// Initialize
|
|
53
|
-
this.setupEventHandlers();
|
|
54
|
-
this.startHealthMonitoring();
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Load or generate client ID for persistent identification
|
|
59
|
-
*/
|
|
60
|
-
loadClientId() {
|
|
61
|
-
let clientId = localStorage.getItem('claude_mpm_client_id');
|
|
62
|
-
if (!clientId) {
|
|
63
|
-
clientId = 'client_' + Math.random().toString(36).substr(2, 9);
|
|
64
|
-
localStorage.setItem('claude_mpm_client_id', clientId);
|
|
65
|
-
}
|
|
66
|
-
return clientId;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Load last received event sequence for replay
|
|
71
|
-
*/
|
|
72
|
-
loadLastSequence() {
|
|
73
|
-
const sequence = localStorage.getItem('claude_mpm_last_sequence');
|
|
74
|
-
return sequence ? parseInt(sequence, 10) : 0;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Save last received event sequence
|
|
79
|
-
*/
|
|
80
|
-
saveLastSequence(sequence) {
|
|
81
|
-
this.lastSequence = sequence;
|
|
82
|
-
localStorage.setItem('claude_mpm_last_sequence', sequence.toString());
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Connect with enhanced options and authentication
|
|
87
|
-
*/
|
|
88
|
-
connect(port = '8765') {
|
|
89
|
-
const url = `http://localhost:${port}`;
|
|
90
|
-
|
|
91
|
-
console.log(`[ConnectionManager] Connecting to ${url} with client ID: ${this.clientId}`);
|
|
92
|
-
this.updateConnectionState('connecting');
|
|
93
|
-
|
|
94
|
-
// Create socket with enhanced options
|
|
95
|
-
this.socket = io(url, {
|
|
96
|
-
auth: {
|
|
97
|
-
client_id: this.clientId,
|
|
98
|
-
last_sequence: this.lastSequence
|
|
99
|
-
},
|
|
100
|
-
reconnection: true,
|
|
101
|
-
reconnectionDelay: this.calculateReconnectDelay(),
|
|
102
|
-
reconnectionDelayMax: this.maxReconnectDelay,
|
|
103
|
-
reconnectionAttempts: this.maxReconnectAttempts,
|
|
104
|
-
timeout: 20000,
|
|
105
|
-
transports: ['websocket', 'polling'],
|
|
106
|
-
pingInterval: 25000,
|
|
107
|
-
pingTimeout: 20000
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
this.setupSocketHandlers();
|
|
111
|
-
this.socketClient.socket = this.socket;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Calculate exponential backoff delay for reconnection
|
|
116
|
-
*/
|
|
117
|
-
calculateReconnectDelay() {
|
|
118
|
-
const delay = Math.min(
|
|
119
|
-
this.baseReconnectDelay * Math.pow(2, this.reconnectAttempts),
|
|
120
|
-
this.maxReconnectDelay
|
|
121
|
-
);
|
|
122
|
-
return delay + Math.random() * 1000; // Add jitter
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Setup socket event handlers
|
|
127
|
-
*/
|
|
128
|
-
setupSocketHandlers() {
|
|
129
|
-
if (!this.socket) return;
|
|
130
|
-
|
|
131
|
-
// Connection established
|
|
132
|
-
this.socket.on('connection_established', (data) => {
|
|
133
|
-
console.log('[ConnectionManager] Connection established:', data);
|
|
134
|
-
this.clientId = data.client_id;
|
|
135
|
-
this.metrics.connectTime = Date.now();
|
|
136
|
-
this.metrics.totalConnections++;
|
|
137
|
-
this.reconnectAttempts = 0;
|
|
138
|
-
this.missedHeartbeats = 0;
|
|
139
|
-
this.updateConnectionState('connected');
|
|
140
|
-
this.startHeartbeat();
|
|
141
|
-
|
|
142
|
-
// Flush buffered events if any
|
|
143
|
-
this.flushEventBuffer();
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
// Event replay after reconnection
|
|
147
|
-
this.socket.on('event_replay', (data) => {
|
|
148
|
-
console.log(`[ConnectionManager] Replaying ${data.count} events from sequence ${data.from_sequence}`);
|
|
149
|
-
|
|
150
|
-
if (data.events && data.events.length > 0) {
|
|
151
|
-
data.events.forEach(event => {
|
|
152
|
-
// Update sequence
|
|
153
|
-
if (event.sequence) {
|
|
154
|
-
this.saveLastSequence(event.sequence);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// Process replayed event
|
|
158
|
-
this.socketClient.handleEvent('claude_event', event);
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
this.showNotification(`Replayed ${data.count} missed events`, 'info');
|
|
162
|
-
}
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
// Normal event with sequence tracking
|
|
166
|
-
this.socket.on('claude_event', (event) => {
|
|
167
|
-
if (event.sequence) {
|
|
168
|
-
this.saveLastSequence(event.sequence);
|
|
169
|
-
|
|
170
|
-
// Send acknowledgment
|
|
171
|
-
this.socket.emit('acknowledge_event', {
|
|
172
|
-
sequence: event.sequence
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
this.metrics.eventsAcked++;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
this.metrics.totalEvents++;
|
|
179
|
-
this.metrics.lastActivity = Date.now();
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
// Heartbeat response
|
|
183
|
-
this.socket.on('heartbeat_response', (data) => {
|
|
184
|
-
this.missedHeartbeats = 0;
|
|
185
|
-
this.updateConnectionQuality(1.0);
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
// Pong response
|
|
189
|
-
this.socket.on('pong', (data) => {
|
|
190
|
-
this.lastPongTime = Date.now();
|
|
191
|
-
const latency = this.lastPongTime - this.lastPingTime;
|
|
192
|
-
this.updateLatency(latency);
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
// Connection stats response
|
|
196
|
-
this.socket.on('connection_stats', (data) => {
|
|
197
|
-
console.log('[ConnectionManager] Connection stats:', data);
|
|
198
|
-
if (data.connection) {
|
|
199
|
-
this.updateConnectionQuality(data.connection.quality);
|
|
200
|
-
}
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
// Standard Socket.IO events
|
|
204
|
-
this.socket.on('connect', () => {
|
|
205
|
-
console.log('[ConnectionManager] Socket connected');
|
|
206
|
-
if (this.metrics.disconnectTime) {
|
|
207
|
-
const downtime = Date.now() - this.metrics.disconnectTime;
|
|
208
|
-
console.log(`[ConnectionManager] Reconnected after ${(downtime / 1000).toFixed(1)}s`);
|
|
209
|
-
this.metrics.totalReconnections++;
|
|
210
|
-
}
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
this.socket.on('disconnect', (reason) => {
|
|
214
|
-
console.log('[ConnectionManager] Socket disconnected:', reason);
|
|
215
|
-
this.metrics.disconnectTime = Date.now();
|
|
216
|
-
this.updateConnectionState('disconnected');
|
|
217
|
-
this.stopHeartbeat();
|
|
218
|
-
|
|
219
|
-
// Handle different disconnect reasons
|
|
220
|
-
if (reason === 'io server disconnect') {
|
|
221
|
-
// Server initiated disconnect
|
|
222
|
-
this.showNotification('Server disconnected the connection', 'warning');
|
|
223
|
-
} else if (reason === 'ping timeout') {
|
|
224
|
-
// Connection timeout
|
|
225
|
-
this.showNotification('Connection timeout - attempting to reconnect', 'warning');
|
|
226
|
-
}
|
|
227
|
-
});
|
|
228
|
-
|
|
229
|
-
this.socket.on('connect_error', (error) => {
|
|
230
|
-
console.error('[ConnectionManager] Connection error:', error.message);
|
|
231
|
-
this.reconnectAttempts++;
|
|
232
|
-
|
|
233
|
-
if (this.reconnectAttempts >= this.maxReconnectAttempts) {
|
|
234
|
-
this.updateConnectionState('failed');
|
|
235
|
-
this.showNotification('Failed to connect after multiple attempts', 'error');
|
|
236
|
-
} else {
|
|
237
|
-
const delay = this.calculateReconnectDelay();
|
|
238
|
-
this.showNotification(
|
|
239
|
-
`Connection failed, retrying in ${(delay / 1000).toFixed(1)}s...`,
|
|
240
|
-
'warning'
|
|
241
|
-
);
|
|
242
|
-
}
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
this.socket.on('reconnect', (attemptNumber) => {
|
|
246
|
-
console.log(`[ConnectionManager] Reconnected after ${attemptNumber} attempts`);
|
|
247
|
-
this.showNotification('Reconnected successfully', 'success');
|
|
248
|
-
|
|
249
|
-
// Request event replay
|
|
250
|
-
this.socket.emit('request_replay', {
|
|
251
|
-
last_sequence: this.lastSequence
|
|
252
|
-
});
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
this.socket.on('reconnect_attempt', (attemptNumber) => {
|
|
256
|
-
console.log(`[ConnectionManager] Reconnection attempt ${attemptNumber}`);
|
|
257
|
-
this.updateConnectionState('reconnecting');
|
|
258
|
-
});
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
* Start heartbeat monitoring
|
|
263
|
-
*/
|
|
264
|
-
startHeartbeat() {
|
|
265
|
-
this.stopHeartbeat();
|
|
266
|
-
|
|
267
|
-
this.heartbeatTimer = setInterval(() => {
|
|
268
|
-
if (this.socket && this.socket.connected) {
|
|
269
|
-
this.socket.emit('heartbeat');
|
|
270
|
-
this.missedHeartbeats++;
|
|
271
|
-
|
|
272
|
-
if (this.missedHeartbeats >= this.maxMissedHeartbeats) {
|
|
273
|
-
console.warn('[ConnectionManager] Too many missed heartbeats, connection may be stale');
|
|
274
|
-
this.updateConnectionQuality(0.3);
|
|
275
|
-
this.updateConnectionState('stale');
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
}, this.heartbeatInterval);
|
|
279
|
-
|
|
280
|
-
// Also start ping monitoring for latency
|
|
281
|
-
this.pingTimer = setInterval(() => {
|
|
282
|
-
if (this.socket && this.socket.connected) {
|
|
283
|
-
this.lastPingTime = Date.now();
|
|
284
|
-
this.socket.emit('ping');
|
|
285
|
-
}
|
|
286
|
-
}, 10000); // Every 10 seconds
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
/**
|
|
290
|
-
* Stop heartbeat monitoring
|
|
291
|
-
*/
|
|
292
|
-
stopHeartbeat() {
|
|
293
|
-
if (this.heartbeatTimer) {
|
|
294
|
-
clearInterval(this.heartbeatTimer);
|
|
295
|
-
this.heartbeatTimer = null;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
if (this.pingTimer) {
|
|
299
|
-
clearInterval(this.pingTimer);
|
|
300
|
-
this.pingTimer = null;
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
/**
|
|
305
|
-
* Start health monitoring
|
|
306
|
-
*/
|
|
307
|
-
startHealthMonitoring() {
|
|
308
|
-
// Periodic connection stats request
|
|
309
|
-
setInterval(() => {
|
|
310
|
-
if (this.socket && this.socket.connected) {
|
|
311
|
-
this.socket.emit('get_connection_stats');
|
|
312
|
-
}
|
|
313
|
-
}, 60000); // Every minute
|
|
314
|
-
|
|
315
|
-
// Activity timeout detection
|
|
316
|
-
setInterval(() => {
|
|
317
|
-
if (this.connectionState === 'connected' && this.metrics.lastActivity) {
|
|
318
|
-
const timeSinceActivity = Date.now() - this.metrics.lastActivity;
|
|
319
|
-
if (timeSinceActivity > 120000) { // 2 minutes
|
|
320
|
-
console.warn('[ConnectionManager] No activity for 2 minutes');
|
|
321
|
-
this.updateConnectionQuality(0.5);
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
}, 30000); // Check every 30 seconds
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
/**
|
|
328
|
-
* Update connection state and notify listeners
|
|
329
|
-
*/
|
|
330
|
-
updateConnectionState(state) {
|
|
331
|
-
const previousState = this.connectionState;
|
|
332
|
-
this.connectionState = state;
|
|
333
|
-
|
|
334
|
-
if (previousState !== state) {
|
|
335
|
-
console.log(`[ConnectionManager] State change: ${previousState} -> ${state}`);
|
|
336
|
-
|
|
337
|
-
// Update UI
|
|
338
|
-
this.updateConnectionUI(state);
|
|
339
|
-
|
|
340
|
-
// Notify callbacks
|
|
341
|
-
this.statusCallbacks.forEach(callback => {
|
|
342
|
-
try {
|
|
343
|
-
callback(state, previousState);
|
|
344
|
-
} catch (error) {
|
|
345
|
-
console.error('Error in status callback:', error);
|
|
346
|
-
}
|
|
347
|
-
});
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
/**
|
|
352
|
-
* Update connection quality score
|
|
353
|
-
*/
|
|
354
|
-
updateConnectionQuality(quality) {
|
|
355
|
-
this.connectionQuality = Math.max(0, Math.min(1, quality));
|
|
356
|
-
|
|
357
|
-
// Notify callbacks
|
|
358
|
-
this.qualityCallbacks.forEach(callback => {
|
|
359
|
-
try {
|
|
360
|
-
callback(this.connectionQuality);
|
|
361
|
-
} catch (error) {
|
|
362
|
-
console.error('Error in quality callback:', error);
|
|
363
|
-
}
|
|
364
|
-
});
|
|
365
|
-
|
|
366
|
-
// Update UI indicator
|
|
367
|
-
this.updateQualityUI(this.connectionQuality);
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
/**
|
|
371
|
-
* Update latency display
|
|
372
|
-
*/
|
|
373
|
-
updateLatency(latency) {
|
|
374
|
-
const latencyElement = document.getElementById('connection-latency');
|
|
375
|
-
if (latencyElement) {
|
|
376
|
-
latencyElement.textContent = `${latency}ms`;
|
|
377
|
-
|
|
378
|
-
// Color code based on latency
|
|
379
|
-
if (latency < 50) {
|
|
380
|
-
latencyElement.className = 'latency-good';
|
|
381
|
-
} else if (latency < 150) {
|
|
382
|
-
latencyElement.className = 'latency-moderate';
|
|
383
|
-
} else {
|
|
384
|
-
latencyElement.className = 'latency-poor';
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
/**
|
|
390
|
-
* Update connection UI based on state
|
|
391
|
-
*/
|
|
392
|
-
updateConnectionUI(state) {
|
|
393
|
-
const statusElement = document.getElementById('connection-status');
|
|
394
|
-
if (!statusElement) return;
|
|
395
|
-
|
|
396
|
-
const stateConfig = {
|
|
397
|
-
'connecting': { text: 'Connecting...', class: 'status-connecting', icon: '⟳' },
|
|
398
|
-
'connected': { text: 'Connected', class: 'status-connected', icon: '●' },
|
|
399
|
-
'reconnecting': { text: 'Reconnecting...', class: 'status-reconnecting', icon: '⟳' },
|
|
400
|
-
'disconnected': { text: 'Disconnected', class: 'status-disconnected', icon: '●' },
|
|
401
|
-
'stale': { text: 'Connection Stale', class: 'status-stale', icon: '⚠' },
|
|
402
|
-
'failed': { text: 'Connection Failed', class: 'status-failed', icon: '✕' }
|
|
403
|
-
};
|
|
404
|
-
|
|
405
|
-
const config = stateConfig[state] || stateConfig['disconnected'];
|
|
406
|
-
statusElement.innerHTML = `<span>${config.icon}</span> ${config.text}`;
|
|
407
|
-
statusElement.className = `status-badge ${config.class}`;
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
/**
|
|
411
|
-
* Update connection quality UI
|
|
412
|
-
*/
|
|
413
|
-
updateQualityUI(quality) {
|
|
414
|
-
const qualityElement = document.getElementById('connection-quality');
|
|
415
|
-
if (!qualityElement) return;
|
|
416
|
-
|
|
417
|
-
const percentage = Math.round(quality * 100);
|
|
418
|
-
let qualityClass = 'quality-good';
|
|
419
|
-
let qualityText = 'Excellent';
|
|
420
|
-
|
|
421
|
-
if (quality < 0.3) {
|
|
422
|
-
qualityClass = 'quality-poor';
|
|
423
|
-
qualityText = 'Poor';
|
|
424
|
-
} else if (quality < 0.7) {
|
|
425
|
-
qualityClass = 'quality-moderate';
|
|
426
|
-
qualityText = 'Fair';
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
qualityElement.innerHTML = `
|
|
430
|
-
<div class="quality-bar ${qualityClass}">
|
|
431
|
-
<div class="quality-fill" style="width: ${percentage}%"></div>
|
|
432
|
-
</div>
|
|
433
|
-
<span class="quality-text">${qualityText} (${percentage}%)</span>
|
|
434
|
-
`;
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
/**
|
|
438
|
-
* Buffer events when disconnected
|
|
439
|
-
*/
|
|
440
|
-
bufferEvent(event) {
|
|
441
|
-
if (this.eventBuffer.length >= this.maxEventBuffer) {
|
|
442
|
-
this.eventBuffer.shift(); // Remove oldest
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
this.eventBuffer.push({
|
|
446
|
-
...event,
|
|
447
|
-
buffered_at: Date.now()
|
|
448
|
-
});
|
|
449
|
-
|
|
450
|
-
// Save to localStorage for persistence
|
|
451
|
-
localStorage.setItem('claude_mpm_event_buffer', JSON.stringify(this.eventBuffer));
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
/**
|
|
455
|
-
* Flush buffered events after reconnection
|
|
456
|
-
*/
|
|
457
|
-
flushEventBuffer() {
|
|
458
|
-
if (this.eventBuffer.length === 0) return;
|
|
459
|
-
|
|
460
|
-
console.log(`[ConnectionManager] Flushing ${this.eventBuffer.length} buffered events`);
|
|
461
|
-
|
|
462
|
-
// Process buffered events
|
|
463
|
-
this.eventBuffer.forEach(event => {
|
|
464
|
-
this.socketClient.handleEvent('claude_event', event);
|
|
465
|
-
});
|
|
466
|
-
|
|
467
|
-
// Clear buffer
|
|
468
|
-
this.eventBuffer = [];
|
|
469
|
-
localStorage.removeItem('claude_mpm_event_buffer');
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
/**
|
|
473
|
-
* Show notification to user
|
|
474
|
-
*/
|
|
475
|
-
showNotification(message, type = 'info') {
|
|
476
|
-
const notificationArea = document.getElementById('connection-notifications');
|
|
477
|
-
if (!notificationArea) return;
|
|
478
|
-
|
|
479
|
-
const notification = document.createElement('div');
|
|
480
|
-
notification.className = `notification notification-${type}`;
|
|
481
|
-
notification.textContent = message;
|
|
482
|
-
|
|
483
|
-
notificationArea.appendChild(notification);
|
|
484
|
-
|
|
485
|
-
// Auto-remove after 5 seconds
|
|
486
|
-
setTimeout(() => {
|
|
487
|
-
notification.style.opacity = '0';
|
|
488
|
-
setTimeout(() => notification.remove(), 300);
|
|
489
|
-
}, 5000);
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
/**
|
|
493
|
-
* Register status change callback
|
|
494
|
-
*/
|
|
495
|
-
onStatusChange(callback) {
|
|
496
|
-
this.statusCallbacks.add(callback);
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
/**
|
|
500
|
-
* Register quality change callback
|
|
501
|
-
*/
|
|
502
|
-
onQualityChange(callback) {
|
|
503
|
-
this.qualityCallbacks.add(callback);
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
/**
|
|
507
|
-
* Get connection metrics
|
|
508
|
-
*/
|
|
509
|
-
getMetrics() {
|
|
510
|
-
return {
|
|
511
|
-
...this.metrics,
|
|
512
|
-
connectionState: this.connectionState,
|
|
513
|
-
connectionQuality: this.connectionQuality,
|
|
514
|
-
clientId: this.clientId,
|
|
515
|
-
lastSequence: this.lastSequence,
|
|
516
|
-
bufferedEvents: this.eventBuffer.length
|
|
517
|
-
};
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
/**
|
|
521
|
-
* Disconnect and cleanup
|
|
522
|
-
*/
|
|
523
|
-
disconnect() {
|
|
524
|
-
this.stopHeartbeat();
|
|
525
|
-
|
|
526
|
-
if (this.socket) {
|
|
527
|
-
this.socket.disconnect();
|
|
528
|
-
this.socket = null;
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
this.updateConnectionState('disconnected');
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
// Export for use in other modules
|
|
536
|
-
export { EnhancedConnectionManager };
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
class e{constructor(){this.eventViewer=null,this.moduleViewer=null,this.sessionManager=null,this.activityTreeRetryCount=0,this.maxRetryAttempts=10,this.socketManager=null,this.agentInference=null,this.agentHierarchy=null,this.uiStateManager=null,this.eventProcessor=null,this.exportManager=null,this.workingDirectoryManager=null,this.fileToolTracker=null,this.buildTracker=null,this.init()}init(){console.log("Initializing refactored Claude MPM Dashboard...");try{this.fetchServerConfig(),this.initializeSocketManager(),this.initializeCoreComponents(),this.initializeBuildTracker(),this.initializeAgentInference(),this.initializeAgentHierarchy(),this.initializeUIStateManager(),this.initializeWorkingDirectoryManager(),this.initializeFileToolTracker(),this.initializeEventProcessor(),this.initializeExportManager(),this.setupModuleInteractions(),this.initializeFromURL(),console.log("Claude MPM Dashboard initialized successfully")}catch(e){throw console.error("Error during dashboard initialization:",e),e}}fetchServerConfig(){fetch("/api/config").then(e=>e.json()).then(e=>{window.dashboardConfig=e;const t=document.getElementById("working-dir-path");t&&e.workingDirectory&&(t.textContent=e.workingDirectory);const n=document.getElementById("footer-git-branch");n&&e.gitBranch&&(n.textContent=e.gitBranch),console.log("Dashboard configuration loaded:",e)}).catch(e=>{console.warn("Failed to fetch server config:",e),window.dashboardConfig={workingDirectory:".",gitBranch:"Unknown"}})}validateInitialization(){const e=[{name:"socketManager",component:this.socketManager},{name:"eventViewer",component:this.eventViewer},{name:"agentHierarchy",component:this.agentHierarchy}].filter(e=>!e.component);e.length>0&&console.warn("Missing critical components:",e.map(e=>e.name))}postInit(){try{this.agentHierarchy&&(window.dashboard.agentHierarchy=this.agentHierarchy),this.validateInitialization()}catch(e){console.error("Error in dashboard postInit:",e)}}initializeSocketManager(){this.socketManager=new SocketManager,this.socketManager.setupConnectionControls(),this.socketClient=this.socketManager.getSocketClient(),window.socketClient=this.socketClient}initializeCoreComponents(){this.eventViewer=new EventViewer("events-list",this.socketClient),setTimeout(()=>{this.eventViewer&&this.eventViewer.updateMetrics&&(this.eventViewer.updateMetrics(),console.log("Initial metrics update triggered"))},100),setTimeout(()=>{this.eventViewer&&this.eventViewer.updateMetrics&&(this.eventViewer.updateMetrics(),console.log("Initial metrics update triggered"))},100),this.moduleViewer=new ModuleViewer,this.sessionManager=new SessionManager(this.socketClient),window.eventViewer=this.eventViewer,window.moduleViewer=this.moduleViewer,window.sessionManager=this.sessionManager}initializeBuildTracker(){this.buildTracker=new BuildTracker,this.buildTracker.setSocketClient(this.socketClient);const e=()=>{const t=document.querySelector(".header-title");t?(this.buildTracker.mount(t),console.log("BuildTracker mounted successfully")):(console.warn("Header-title element not found for build tracker, will retry"),setTimeout(e,100))};e(),window.buildTracker=this.buildTracker}initializeAgentInference(){this.agentInference=new AgentInference(this.eventViewer),this.agentInference.initialize()}initializeAgentHierarchy(){try{this.agentHierarchy=new AgentHierarchy(this.agentInference,this.eventViewer)}catch(e){console.error("Failed to initialize agent hierarchy:",e),this.agentHierarchy={render:()=>'<div class="error">Agent hierarchy unavailable</div>',expandAllNodes:()=>{},collapseAllNodes:()=>{},updateWithNewEvents:()=>{}}}}initializeUIStateManager(){this.uiStateManager=new UIStateManager,this.setupTabFilters()}initializeWorkingDirectoryManager(){this.workingDirectoryManager=new WorkingDirectoryManager(this.socketManager)}initializeFileToolTracker(){this.fileToolTracker=new FileToolTracker(this.agentInference,this.workingDirectoryManager)}initializeEventProcessor(){this.eventProcessor=new EventProcessor(this.eventViewer,this.agentInference)}initializeExportManager(){this.exportManager=new ExportManager(this.eventViewer)}setupModuleInteractions(){this.socketManager.onEventUpdate(e=>{this.eventViewer&&this.eventViewer.updateMetrics&&this.eventViewer.updateMetrics(),this.eventViewer&&this.eventViewer.updateMetrics&&this.eventViewer.updateMetrics(),console.log("[Dashboard] Processing event update with",e.length,"events"),e.length>0&&console.log("[Dashboard] Sample event structure:",{first_event:e[0],has_tool_events:e.some(e=>e.tool_name||e.data&&e.data.tool_name),hook_events:e.filter(e=>"hook"===e.type).length,tool_subtypes:e.filter(e=>"pre_tool"===e.subtype||"post_tool"===e.subtype).length}),this.fileToolTracker.updateFileOperations(e),this.fileToolTracker.updateToolCalls(e);const t=this.fileToolTracker.getFileOperations(),n=this.fileToolTracker.getToolCalls();console.log("[Dashboard] After update - File operations:",t.size,"Tool calls:",n.size),this.agentInference.processAgentInference(),window.CodeViewer&&"function"==typeof window.CodeViewer.refreshFromFileToolTracker&&setTimeout(()=>{window.CodeViewer.refreshFromFileToolTracker()},50),this.agentHierarchy.updateWithNewEvents(e),"events"===this.uiStateManager.getCurrentTab()&&this.exportManager.scrollListToBottom("events-list"),this.renderCurrentTab()}),this.socketManager.onConnectionStatusChange((e,t)=>{"connected"===t&&this.workingDirectoryManager.updateGitBranch(this.workingDirectoryManager.getCurrentWorkingDir())}),document.addEventListener("tabChanged",e=>{this.renderCurrentTab(),this.uiStateManager.updateTabNavigationItems()}),document.addEventListener("eventsClearing",()=>{this.fileToolTracker.clear(),this.agentInference.initialize()}),document.addEventListener("showCardDetails",e=>{this.showCardDetails(e.detail.tabName,e.detail.index)}),document.addEventListener("sessionFilterChanged",e=>{this.renderCurrentTab()})}setupTabFilters(){const e=document.getElementById("agents-search-input"),t=document.getElementById("agents-type-filter");e&&e.addEventListener("input",()=>{"agents"===this.uiStateManager.getCurrentTab()&&this.renderCurrentTab()}),t&&t.addEventListener("change",()=>{"agents"===this.uiStateManager.getCurrentTab()&&this.renderCurrentTab()});const n=document.getElementById("tools-search-input"),i=document.getElementById("tools-type-filter");n&&n.addEventListener("input",()=>{"tools"===this.uiStateManager.getCurrentTab()&&this.renderCurrentTab()}),i&&i.addEventListener("change",()=>{"tools"===this.uiStateManager.getCurrentTab()&&this.renderCurrentTab()});const o=document.getElementById("files-search-input"),r=document.getElementById("files-type-filter");o&&o.addEventListener("input",()=>{"files"===this.uiStateManager.getCurrentTab()&&this.renderCurrentTab()}),r&&r.addEventListener("change",()=>{"files"===this.uiStateManager.getCurrentTab()&&this.renderCurrentTab()})}initializeFromURL(){const e=new URLSearchParams(window.location.search);this.socketManager.initializeFromURL(e)}renderCurrentTab(){const e=this.uiStateManager.getCurrentTab();switch(e){case"events":break;case"claude-tree":window.CodeViewer&&"function"==typeof window.CodeViewer.show&&window.CodeViewer.show();break;case"activity":if(window.ActivityTree&&"function"==typeof window.ActivityTree)this.activityTreeRetryCount=0,window.activityTreeInstance||(window.activityTreeInstance=new window.ActivityTree),window.activityTreeInstance&&(window.activityTreeInstance.initialized||window.activityTreeInstance.initialize(),"function"==typeof window.activityTreeInstance.renderWhenVisible&&window.activityTreeInstance.renderWhenVisible(),"function"==typeof window.activityTreeInstance.forceShow&&window.activityTreeInstance.forceShow());else if(window.activityTree&&"function"==typeof window.activityTree){const e=window.activityTree();e&&("function"==typeof e.renderWhenVisible&&e.renderWhenVisible(),"function"==typeof e.forceShow&&e.forceShow())}else if(this.activityTreeRetryCount<this.maxRetryAttempts)this.activityTreeRetryCount++,console.warn(`Activity tree component not available, retrying in 100ms... (attempt ${this.activityTreeRetryCount}/${this.maxRetryAttempts})`),setTimeout(()=>{"activity"===this.uiStateManager.getCurrentTab()&&this.renderCurrentTab()},100);else{console.error("Maximum retry attempts reached for ActivityTree initialization. Giving up.");const e=document.getElementById("activity-tree-container")||document.getElementById("activity-tree");e&&(e.innerHTML='<div class="error-message">⚠️ Activity Tree failed to load. Please refresh the page.</div>')}break;case"agents":this.renderAgents();break;case"tools":this.renderTools();break;case"files":this.renderFiles()}this.uiStateManager.getSelectedCard().tab===e&&this.uiStateManager.updateCardSelectionUI(),this.uiStateManager.updateUnifiedSelectionUI()}renderAgents(){const e=document.getElementById("agents-list");if(!e)return;const t=document.getElementById("agents-search-input")?.value||"",n=document.getElementById("agents-type-filter")?.value||"",i=this.renderAgentsFlat(t,n);e.innerHTML=i,this.removeHierarchyControls();const o=this.agentInference.getUniqueAgentInstances();this.updateAgentsFilterDropdowns(o)}removeHierarchyControls(){const e=document.getElementById("hierarchy-controls");e&&e.remove()}renderAgentsFlat(e,t){const n=this.eventViewer.events;if(!n||0===n.length)return'<div class="no-events">No agent events found...</div>';this.agentInference.processAgentInference();const i=this.agentInference.getEventAgentMap(),o=[];if(n.forEach((n,r)=>{const s=i.get(r);if(s&&("subagent"===s.type||"main_agent"===s.type)){let i=!0;if(e){const t=e.toLowerCase();i=i&&(s.agentName.toLowerCase().includes(t)||n.tool_name&&n.tool_name.toLowerCase().includes(t)||n.data&&JSON.stringify(n.data).toLowerCase().includes(t))}t&&(i=i&&s.agentName.includes(t)),i&&o.push({event:n,inference:s,index:r,timestamp:new Date(n.timestamp)})}}),0===o.length)return'<div class="no-events">No agent events match the current filters...</div>';return`<div class="agent-events-flat">${o.map((e,t)=>{const{event:n,inference:i,index:o,timestamp:r}=e;let s="Activity",a="📋",l="";if("SubagentStart"===n.event_type)s="Started",a="🟢",l="Agent session began";else if("SubagentStop"===n.event_type)s="Stopped",a="🔴",l="Agent session ended";else if(n.tool_name&&(s=`Tool: ${n.tool_name}`,a=this.getToolIcon(n.tool_name),n.data&&n.data.tool_parameters)){const e=n.data.tool_parameters;e.file_path?l=e.file_path:e.command?l=e.command.substring(0,50)+(e.command.length>50?"...":""):e.pattern?l=`pattern="${e.pattern}"`:e.query&&(l=`query="${e.query}"`)}let c="completed";return"SubagentStart"===n.event_type?c="active":n.data&&n.data.error&&(c="error"),`\n <div class="agent-event-item" data-index="${t}" onclick="window.dashboard.showCardDetails('agents', ${o})">\n <div class="agent-event-header">\n <div class="agent-event-time">${this.formatTimestamp(r)}</div>\n <div class="agent-event-agent">\n ${this.getAgentIcon(i.agentName)} ${i.agentName}\n </div>\n <div class="agent-event-action">\n ${a} ${s}\n </div>\n <div class="agent-event-status status-${c}">\n ${this.getStatusIcon(c)}\n </div>\n </div>\n ${l?`<div class="agent-event-details">${this.escapeHtml(l)}</div>`:""}\n </div>\n `}).join("")}</div>`}getAgentIcon(e){return{PM:"🎯","Engineer Agent":"🔧","Research Agent":"🔍","QA Agent":"✅","Documentation Agent":"📝","Security Agent":"🔒","Ops Agent":"⚙️","Version Control Agent":"📦","Data Engineer Agent":"💾","Test Integration Agent":"🧪"}[e]||"🤖"}getToolIcon(e){return{Read:"📖",Write:"✏️",Edit:"📝",Bash:"💻",Grep:"🔍",Glob:"📂",LS:"📁",Task:"📋"}[e]||"🔧"}getStatusIcon(e){return{active:"🟢",completed:"✅",error:"❌",pending:"🟡"}[e]||"❓"}formatTimestamp(e){return e.toLocaleTimeString("en-US",{hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1})}escapeHtml(e){if(!e)return"";const t=document.createElement("div");return t.textContent=e,t.innerHTML}renderTools(){const e=document.getElementById("tools-list");if(!e)return;const t=this.fileToolTracker.getToolCalls(),n=Array.from(t.entries()),i=this.eventProcessor.getUniqueToolInstances(n),o=this.eventProcessor.generateToolHTML(i);e.innerHTML=o,this.exportManager.scrollListToBottom("tools-list"),this.updateToolsFilterDropdowns(i)}renderFiles(){const e=document.getElementById("files-list");if(!e)return;const t=this.fileToolTracker.getFileOperations(),n=Array.from(t.entries());console.log("[renderFiles] File operations map size:",t.size),console.log("[renderFiles] Files array:",n);const i=this.eventProcessor.getUniqueFileInstances(n),o=this.eventProcessor.generateFileHTML(i);0===n.length?e.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>':e.innerHTML=o,this.exportManager.scrollListToBottom("files-list"),this.updateFilesFilterDropdowns(n)}updateAgentsFilterDropdowns(e){const t=new Set;e.forEach(e=>{e.agentName&&"Unknown"!==e.agentName&&t.add(e.agentName)});const n=Array.from(t).filter(e=>e&&""!==e.trim());this.populateFilterDropdown("agents-type-filter",n,"All Agent Types")}updateToolsFilterDropdowns(e){const t=[...new Set(e.map(([e,t])=>t.tool_name))].filter(e=>e);this.populateFilterDropdown("tools-type-filter",t,"All Tools")}updateFilesFilterDropdowns(e){const t=[...new Set(e.flatMap(([e,t])=>t.operations.map(e=>e.operation)))].filter(e=>e);this.populateFilterDropdown("files-type-filter",t,"All Operations")}populateFilterDropdown(e,t,n="All"){const i=document.getElementById(e);if(!i)return;const o=i.value,r=t.sort((e,t)=>e.localeCompare(t));i.innerHTML=`<option value="">${n}</option>`,r.forEach(e=>{const t=document.createElement("option");t.value=e,t.textContent=e,i.appendChild(t)}),o&&r.includes(o)&&(i.value=o)}showCardDetails(e,t){switch(e){case"events":this.eventViewer&&this.eventViewer.showEventDetails(t);break;case"agents":this.showAgentDetailsByIndex(t);break;case"tools":this.showToolDetailsByIndex(t);break;case"files":this.showFileDetailsByIndex(t)}}showAgentDetailsByIndex(e){const t=this.eventProcessor.getFilteredEventsForTab("agents");if(!t||!Array.isArray(t)||e<0||e>=t.length)return void console.warn("Dashboard: Invalid agent index or events array");const n=this.eventProcessor.applyAgentsFilters([t[e]]);if(n.length>0&&this.moduleViewer&&"function"==typeof this.moduleViewer.showAgentEvent){const t=n[0];this.moduleViewer.showAgentEvent(t,e)}}showAgentInstanceDetails(e){const t=this.agentInference.getPMDelegations().get(e);if(!t){const t=this.agentInference.getUniqueAgentInstances().find(t=>t.id===e);return t?void this.showImpliedAgentDetails(t):void console.error("Agent instance not found:",e)}this.moduleViewer&&"function"==typeof this.moduleViewer.showAgentInstance?this.moduleViewer.showAgentInstance(t):console.log("Agent Instance Details:",{id:e,agentName:t.agentName,type:"PM Delegation",eventCount:t.agentEvents.length,startTime:t.timestamp,pmCall:t.pmCall})}showImpliedAgentDetails(e){this.moduleViewer&&"function"==typeof this.moduleViewer.showImpliedAgent?this.moduleViewer.showImpliedAgent(e):console.log("Implied Agent Details:",{id:e.id,agentName:e.agentName,type:"Implied PM Delegation",eventCount:e.eventCount,startTime:e.timestamp,note:"No explicit PM call found - inferred from agent activity"})}showToolDetailsByIndex(e){const t=this.fileToolTracker.getToolCalls(),n=Array.from(t.entries()),i=this.eventProcessor.applyToolCallFilters(n);if(e>=0&&e<i.length){const[t]=i[e];this.showToolCallDetails(t)}}showFileDetailsByIndex(e){const t=this.fileToolTracker.getFileOperations();let n=Array.from(t.entries());if(n=this.eventProcessor.applyFilesFilters(n),e>=0&&e<n.length){const[t]=n[e];this.showFileDetails(t)}}showToolCallDetails(e){const t=this.fileToolTracker.getToolCall(e);t&&this.moduleViewer&&this.moduleViewer.showToolCall(t,e)}showFileDetails(e){const t=this.fileToolTracker.getFileOperationsForFile(e);t&&this.moduleViewer&&this.moduleViewer.showFileOperations(t,e)}switchTab(e){this.uiStateManager.switchTab(e)}selectCard(e,t,n,i){this.uiStateManager.selectCard(e,t,n,i)}clearEvents(){this.exportManager.clearEvents()}exportEvents(){this.exportManager.exportEvents()}clearSelection(){this.uiStateManager.clearSelection(),this.eventViewer&&this.eventViewer.clearSelection(),this.moduleViewer&&this.moduleViewer.clear()}get currentWorkingDir(){return this.workingDirectoryManager.getCurrentWorkingDir()}set currentWorkingDir(e){this.workingDirectoryManager.setWorkingDirectory(e)}get currentTab(){return this.uiStateManager.getCurrentTab()}get selectedCard(){return this.uiStateManager.getSelectedCard()}get fileOperations(){return this.fileToolTracker.getFileOperations()}get toolCalls(){return this.fileToolTracker.getToolCalls()}get tabNavigation(){return this.uiStateManager?this.uiStateManager.tabNavigation:null}}async function t(e,t,i){const o=e.querySelector(".file-viewer-file-path"),r=e.querySelector(".file-viewer-file-size");o&&(o.textContent=t),r&&(r.textContent="");const s=e.querySelector(".file-viewer-loading"),a=e.querySelector(".file-viewer-error"),l=e.querySelector(".file-viewer-content-area");s&&(s.style.display="flex"),a&&(a.style.display="none"),l&&(l.style.display="none");try{const o=window.socket||window.dashboard?.socketClient?.socket||window.socketClient?.socket;if(console.log("[FileViewer] Socket search results:",{"window.socket":!!window.socket,"window.socket.connected":window.socket?.connected,"dashboard.socketClient.socket":!!window.dashboard?.socketClient?.socket,"dashboard.socketClient.socket.connected":window.dashboard?.socketClient?.socket?.connected,"window.socketClient.socket":!!window.socketClient?.socket,"window.socketClient.socket.connected":window.socketClient?.socket?.connected}),!o)throw new Error("No socket connection available. Please ensure the dashboard is connected.");o.connected||console.warn("[FileViewer] Socket found but not connected, attempting to use anyway..."),console.log("[FileViewer] Socket found, setting up listener for file_content_response");const r=new Promise((e,n)=>{const i=r=>{console.log("[FileViewer] Received file_content_response:",r),r.file_path===t&&(o.off("file_content_response",i),r.success?(console.log("[FileViewer] File content loaded successfully"),e(r)):(console.error("[FileViewer] File read failed:",r.error),n(new Error(r.error||"Failed to read file"))))};o.on("file_content_response",i),console.log("[FileViewer] Listener registered for file_content_response"),setTimeout(()=>{o.off("file_content_response",i),console.error("[FileViewer] Request timeout after 10 seconds"),n(new Error("Request timeout - server did not respond"))},1e4)}),s={file_path:t,working_dir:i};console.log("[FileViewer] Emitting read_file event with data:",s),o.emit("read_file",s);const a=await r,l=e.querySelector(".file-viewer-loading");l&&(l.style.display="none"),function(e,t){const i=e.querySelector(".file-viewer-content-area"),o=e.querySelector(".file-extension"),r=e.querySelector(".file-encoding"),s=e.querySelector(".file-viewer-file-size"),a=e.querySelector(".file-content-code");o&&(o.textContent=`Type: ${t.extension||"unknown"}`);r&&(r.textContent=`Encoding: ${t.encoding||"unknown"}`);s&&(s.textContent=`Size: ${function(e){if(!e)return"0 B";const t=1024,n=["B","KB","MB","GB"],i=Math.floor(Math.log(e)/Math.log(t));return parseFloat((e/Math.pow(t,i)).toFixed(2))+" "+n[i]}(t.file_size)}`);if(a&&t.content){a.innerHTML=function(e,t){const i=e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">");switch(t){case".js":case".jsx":case".ts":case".tsx":return function(e){return n(e.replace(/\b(function|const|let|var|if|else|for|while|return|import|export|class|extends)\b/g,'<span class="keyword">$1</span>').replace(/(\/\*[\s\S]*?\*\/|\/\/.*)/g,'<span class="comment">$1</span>').replace(/('[^']*'|"[^"]*"|`[^`]*`)/g,'<span class="string">$1</span>').replace(/\b(\d+)\b/g,'<span class="number">$1</span>'))}(i);case".py":return function(e){return n(e.replace(/\b(def|class|if|elif|else|for|while|return|import|from|as|try|except|finally|with)\b/g,'<span class="keyword">$1</span>').replace(/(#.*)/g,'<span class="comment">$1</span>').replace(/('[^']*'|"[^"]*"|"""[\s\S]*?""")/g,'<span class="string">$1</span>').replace(/\b(\d+)\b/g,'<span class="number">$1</span>'))}(i);case".json":return function(e){return n(e.replace(/("[\w\s]*")\s*:/g,'<span class="property">$1</span>:').replace(/:\s*(".*?")/g,': <span class="string">$1</span>').replace(/:\s*(\d+)/g,': <span class="number">$1</span>').replace(/:\s*(true|false|null)/g,': <span class="keyword">$1</span>'))}(i);case".css":return function(e){return n(e.replace(/([.#]?[\w-]+)\s*\{/g,'<span class="selector">$1</span> {').replace(/([\w-]+)\s*:/g,'<span class="property">$1</span>:').replace(/:\s*([^;]+);/g,': <span class="value">$1</span>;').replace(/(\/\*[\s\S]*?\*\/)/g,'<span class="comment">$1</span>'))}(i);case".html":case".htm":return function(e){return n(e.replace(/(<\/?[\w-]+)/g,'<span class="tag">$1</span>').replace(/([\w-]+)=(['"][^'"]*['"])/g,'<span class="attribute">$1</span>=<span class="string">$2</span>').replace(/(<!--[\s\S]*?-->)/g,'<span class="comment">$1</span>'))}(i);case".md":case".markdown":return function(e){return n(e.replace(/^(#{1,6})\s+(.*)$/gm,'<span class="header">$1</span> <span class="header-text">$2</span>').replace(/\*\*(.*?)\*\*/g,'<span class="bold">**$1**</span>').replace(/\*(.*?)\*/g,'<span class="italic">*$1*</span>').replace(/`([^`]+)`/g,'<span class="code">`$1`</span>').replace(/^\s*[-*+]\s+(.*)$/gm,'<span class="list-marker">•</span> $1'))}(i);default:return n(i)}}(t.content,t.extension);const i=e.querySelector(".file-viewer-scroll-wrapper");i&&setTimeout(()=>{const t=e.querySelector(".modal-content"),n=e.querySelector(".file-viewer-header"),o=e.querySelector(".file-viewer-toolbar"),r=(t?.offsetHeight||0)-(n?.offsetHeight||0)-(o?.offsetHeight||0)-40;i.style.maxHeight=`${r}px`,i.style.overflowY="auto"},50)}else console.warn("⚠️ Missing codeElement or file content");i&&(i.style.display="block")}(e,a)}catch(c){console.error("❌ Failed to fetch file content:",c);const n=e.querySelector(".file-viewer-loading");n&&(n.style.display="none");let o=c.message||"Unknown error occurred",r=[];c.message.includes("No socket connection")?(o="Failed to connect to the monitoring server",r=["Check if the monitoring server is running","Verify the socket connection in the dashboard","Try refreshing the page and reconnecting"]):c.message.includes("timeout")?(o="Request timed out",r=["The file may be too large to load quickly","Check your network connection","Try again in a few moments"]):c.message.includes("File does not exist")?(o="File not found",r=["The file may have been moved or deleted","Check the file path spelling","Refresh the file list to see current files"]):c.message.includes("Access denied")&&(o="Access denied",r=["The file is outside the allowed directories","File access is restricted for security reasons"]),function(e,t){const n=e.querySelector(".file-viewer-error"),i=e.querySelector(".error-message"),o=e.querySelector(".error-suggestions");let r=t.error||"Unknown error occurred";i&&(i.innerHTML=`\n <div class="error-main">${r}</div>\n ${t.file_path?`<div class="error-file">File: ${t.file_path}</div>`:""}\n ${t.working_dir?`<div class="error-dir">Working directory: ${t.working_dir}</div>`:""}\n `);o&&(t.suggestions&&t.suggestions.length>0?o.innerHTML=`\n <h4>Suggestions:</h4>\n <ul>\n ${t.suggestions.map(e=>`<li>${e}</li>`).join("")}\n </ul>\n `:o.innerHTML="");console.log("📋 Displaying file viewer error:",{originalError:t.error,processedMessage:r,suggestions:t.suggestions}),n&&(n.style.display="block")}(e,{error:o,file_path:t,working_dir:i,suggestions:r})}}function n(e){return e.split("\n").map((e,t)=>`<span class="line-number">${String(t+1).padStart(3," ")}</span> ${e||" "}`).join("\n")}function i(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}window.clearEvents=function(){window.dashboard&&window.dashboard.clearEvents()},window.exportEvents=function(){window.dashboard&&window.dashboard.exportEvents()},window.clearSelection=function(){window.dashboard&&window.dashboard.clearSelection()},window.switchTab=function(e){window.dashboard&&window.dashboard.switchTab(e)},window.copyFileContent=function(){const e=document.getElementById("file-viewer-modal");if(!e)return;const t=e.querySelector(".file-content-code");if(!t)return;const n=t.textContent;if(navigator.clipboard&&navigator.clipboard.writeText)navigator.clipboard.writeText(n).then(()=>{const t=e.querySelector(".file-content-copy");if(t){const e=t.textContent;t.textContent="✅ Copied!",setTimeout(()=>{t.textContent=e},2e3)}}).catch(e=>{console.error("Failed to copy text:",e)});else{const t=document.createElement("textarea");t.value=n,document.body.appendChild(t),t.select(),document.execCommand("copy"),document.body.removeChild(t);const i=e.querySelector(".file-content-copy");if(i){const e=i.textContent;i.textContent="✅ Copied!",setTimeout(()=>{i.textContent=e},2e3)}}},window.showFileViewerModal=async function(e){console.log("[FileViewer] Opening file:",e);let n="";window.dashboard&&window.dashboard.currentWorkingDir&&(n=window.dashboard.currentWorkingDir,console.log("[FileViewer] Using working directory:",n));let i=document.getElementById("file-viewer-modal");i||(console.log("[FileViewer] Creating new modal"),i=function(){const e=document.createElement("div");return e.id="file-viewer-modal",e.className="modal file-viewer-modal",e.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 ',e.addEventListener("click",t=>{t.target===e&&hideFileViewerModal()}),document.addEventListener("keydown",t=>{"Escape"===t.key&&"flex"===e.style.display&&hideFileViewerModal()}),e}(),document.body.appendChild(i),await new Promise(e=>setTimeout(e,10))),i.style.display="flex",document.body.style.overflow="hidden",t(i,e,n).catch(e=>{console.error("Error updating file viewer modal:",e),function(e,t){const n=e.querySelector(".file-viewer-error"),i=e.querySelector(".error-message"),o=e.querySelector(".error-suggestions"),r=e.querySelector(".file-viewer-loading"),s=e.querySelector(".file-viewer-content-area");r&&(r.style.display="none");s&&(s.style.display="none");n&&(n.style.display="flex");let a=t.error||"Unknown error occurred";a.includes("not found")?a="📁 File not found or not accessible":a.includes("permission")?a="🔒 Permission denied accessing this file":a.includes("too large")?a="📏 File is too large to display":a.includes("socket connection")?a="🔌 Not connected to the server. Please check your connection.":a.includes("timeout")?a="⏱️ Request timed out. The server may be busy or unresponsive.":a.includes("📁")||a.includes("🔒")||a.includes("📏")||(a=`⚠️ ${a}`);i&&(i.textContent=a);o&&(t.suggestions&&t.suggestions.length>0?o.innerHTML=`\n <h4>Suggestions:</h4>\n <ul>\n ${t.suggestions.map(e=>`<li>${e}</li>`).join("")}\n </ul>\n `:o.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 ");console.log("📋 Displaying file content error:",{originalError:t.error,processedMessage:a,suggestions:t.suggestions}),n&&(n.style.display="block")}(i,{error:e.message})})},window.hideFileViewerModal=function(){const e=document.getElementById("file-viewer-modal");e&&(e.style.display="none",document.body.style.overflow="")},window.copyFileContent=function(){const e=document.getElementById("file-viewer-modal");if(!e)return;const t=e.querySelector(".file-content-code");if(!t)return;const n=t.textContent;if(navigator.clipboard&&navigator.clipboard.writeText)navigator.clipboard.writeText(n).then(()=>{const t=e.querySelector(".file-content-copy");if(t){const e=t.textContent;t.textContent="✅ Copied!",setTimeout(()=>{t.textContent=e},2e3)}}).catch(e=>{console.error("Failed to copy text:",e)});else{const t=document.createElement("textarea");t.value=n,document.body.appendChild(t),t.select(),document.execCommand("copy"),document.body.removeChild(t);const i=e.querySelector(".file-content-copy");if(i){const e=i.textContent;i.textContent="✅ Copied!",setTimeout(()=>{i.textContent=e},2e3)}}},window.showSearchViewerModal=function(e,t){let n=document.getElementById("search-viewer-modal");n||(n=function(){const e=document.createElement("div");return e.id="search-viewer-modal",e.className="modal search-viewer-modal",e.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 ',e.addEventListener("click",t=>{t.target===e&&hideSearchViewerModal()}),document.addEventListener("keydown",t=>{"Escape"===t.key&&"flex"===e.style.display&&hideSearchViewerModal()}),e}(),document.body.appendChild(n)),function(e,t,n){const o=e.querySelector(".search-params-display"),r=e.querySelector(".search-results-display");o&&t&&(o.textContent=JSON.stringify(t,null,2));if(r&&n){let e="";"string"==typeof n?e=`<pre class="search-results-text">${i(n)}</pre>`:Array.isArray(n)?(e='<ul class="search-results-list">',n.forEach(t=>{e+="object"==typeof t?`<li><pre>${JSON.stringify(t,null,2)}</pre></li>`:`<li>${i(String(t))}</li>`}),e+="</ul>"):e="object"==typeof n?`<pre class="search-results-json">${JSON.stringify(n,null,2)}</pre>`:`<div class="search-results-text">${i(String(n))}</div>`,r.innerHTML=e}}(n,e,t),n.style.display="flex",document.body.style.overflow="hidden"},window.hideSearchViewerModal=function(){const e=document.getElementById("search-viewer-modal");e&&(e.style.display="none",document.body.style.overflow="")},window.showAgentInstanceDetails=function(e){window.dashboard&&"function"==typeof window.dashboard.showAgentInstanceDetails?window.dashboard.showAgentInstanceDetails(e):console.error("Dashboard not available or method not found")},document.addEventListener("DOMContentLoaded",function(){try{window.dashboard=new e,window.dashboard&&"function"==typeof window.dashboard.postInit&&window.dashboard.postInit(),console.log("Dashboard loaded and initialized successfully"),document.dispatchEvent(new CustomEvent("dashboardReady",{detail:{dashboard:window.dashboard}}))}catch(t){console.error("Failed to initialize dashboard:",t),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;">${t.message}</pre>\n </div>\n `}});
|
|
2
|
-
//# sourceMappingURL=dashboard.js.map
|