claude-mpm 4.24.0__py3-none-any.whl → 5.4.41__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/__init__.py +4 -0
- claude_mpm/agents/BASE_AGENT.md +164 -0
- claude_mpm/agents/{OUTPUT_STYLE.md → CLAUDE_MPM_OUTPUT_STYLE.md} +3 -48
- claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +2002 -0
- claude_mpm/agents/MEMORY.md +1 -1
- claude_mpm/agents/PM_INSTRUCTIONS.md +735 -925
- claude_mpm/agents/WORKFLOW.md +5 -254
- claude_mpm/agents/__init__.py +6 -0
- claude_mpm/agents/agent_loader.py +14 -48
- claude_mpm/agents/base_agent.json +7 -4
- claude_mpm/agents/frontmatter_validator.py +71 -3
- claude_mpm/agents/templates/circuit-breakers.md +1391 -0
- claude_mpm/agents/templates/context-management-examples.md +544 -0
- claude_mpm/agents/templates/{pm_red_flags.md → pm-red-flags.md} +48 -0
- 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 +37 -2
- claude_mpm/cli/__main__.py +4 -0
- claude_mpm/cli/chrome_devtools_installer.py +175 -0
- claude_mpm/cli/commands/__init__.py +2 -0
- claude_mpm/cli/commands/agent_source.py +774 -0
- claude_mpm/cli/commands/agent_state_manager.py +180 -31
- claude_mpm/cli/commands/agents.py +1116 -55
- 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 +725 -242
- claude_mpm/cli/commands/config.py +95 -6
- claude_mpm/cli/commands/configure.py +1875 -46
- claude_mpm/cli/commands/configure_agent_display.py +29 -10
- 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 +229 -2
- claude_mpm/cli/commands/mpm_init/git_activity.py +10 -10
- claude_mpm/cli/commands/mpm_init/knowledge_extractor.py +481 -0
- claude_mpm/cli/commands/mpm_init/prompts.py +286 -6
- claude_mpm/cli/commands/postmortem.py +401 -0
- claude_mpm/cli/commands/profile.py +277 -0
- claude_mpm/cli/commands/run.py +123 -165
- claude_mpm/cli/commands/skill_source.py +694 -0
- claude_mpm/cli/commands/skills.py +782 -20
- claude_mpm/cli/commands/summarize.py +413 -0
- claude_mpm/cli/executor.py +96 -3
- claude_mpm/cli/interactive/agent_wizard.py +1030 -45
- claude_mpm/cli/parsers/agent_source_parser.py +171 -0
- claude_mpm/cli/parsers/agents_parser.py +307 -10
- claude_mpm/cli/parsers/auto_configure_parser.py +13 -138
- claude_mpm/cli/parsers/base_parser.py +65 -0
- claude_mpm/cli/parsers/config_parser.py +162 -39
- claude_mpm/cli/parsers/profile_parser.py +148 -0
- claude_mpm/cli/parsers/skill_source_parser.py +169 -0
- claude_mpm/cli/parsers/skills_parser.py +146 -0
- claude_mpm/cli/parsers/source_parser.py +138 -0
- claude_mpm/cli/startup.py +1280 -118
- 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-config.md +21 -134
- claude_mpm/commands/mpm-doctor.md +16 -20
- claude_mpm/commands/mpm-help.md +13 -283
- claude_mpm/commands/mpm-init.md +88 -489
- claude_mpm/commands/mpm-monitor.md +23 -401
- claude_mpm/commands/mpm-organize.md +72 -247
- claude_mpm/commands/mpm-postmortem.md +21 -0
- claude_mpm/commands/mpm-session-resume.md +30 -0
- claude_mpm/commands/mpm-status.md +13 -68
- claude_mpm/commands/mpm-ticket-view.md +109 -0
- claude_mpm/commands/mpm-version.md +13 -106
- claude_mpm/commands/mpm.md +10 -0
- claude_mpm/config/agent_presets.py +488 -0
- claude_mpm/config/agent_sources.py +352 -0
- claude_mpm/config/skill_presets.py +392 -0
- claude_mpm/config/skill_sources.py +590 -0
- claude_mpm/constants.py +13 -0
- claude_mpm/core/claude_runner.py +5 -34
- claude_mpm/core/config.py +15 -1
- claude_mpm/core/constants.py +1 -1
- claude_mpm/core/framework/__init__.py +3 -16
- claude_mpm/core/framework/formatters/content_formatter.py +3 -13
- claude_mpm/core/framework/loaders/agent_loader.py +8 -5
- claude_mpm/core/framework/loaders/file_loader.py +54 -101
- claude_mpm/core/framework/loaders/instruction_loader.py +66 -5
- claude_mpm/core/framework_loader.py +4 -2
- claude_mpm/core/hook_error_memory.py +381 -0
- claude_mpm/core/hook_manager.py +41 -2
- claude_mpm/core/interactive_session.py +91 -10
- claude_mpm/core/logger.py +16 -1
- claude_mpm/core/oneshot_session.py +71 -8
- claude_mpm/core/optimized_startup.py +59 -0
- claude_mpm/core/output_style_manager.py +173 -43
- claude_mpm/core/protocols/__init__.py +23 -0
- claude_mpm/core/protocols/runner_protocol.py +103 -0
- claude_mpm/core/protocols/session_protocol.py +131 -0
- claude_mpm/core/shared/config_loader.py +1 -1
- claude_mpm/core/shared/singleton_manager.py +11 -4
- claude_mpm/core/socketio_pool.py +3 -3
- claude_mpm/core/system_context.py +38 -0
- claude_mpm/core/unified_agent_registry.py +134 -16
- claude_mpm/core/unified_config.py +22 -0
- claude_mpm/dashboard/static/svelte-build/_app/env.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.B_FtCwCQ.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.Cl_eSA4x.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BgChzWQ1.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIXEwuWe.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWc5urbQ.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DMkZpdF2.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DjhvlsAc.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/N4qtv3Hx.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/uj46x2Wr.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.DTL5mJO-.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.DzuEhzqh.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/0.CAGBuiOw.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DFLC8jdE.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.DPvEihJJ.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -0
- claude_mpm/dashboard/static/svelte-build/favicon.svg +7 -0
- claude_mpm/dashboard/static/svelte-build/index.html +36 -0
- claude_mpm/experimental/cli_enhancements.py +1 -5
- claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/correlation_manager.py +60 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +214 -79
- claude_mpm/hooks/claude_hooks/hook_handler.py +155 -1
- claude_mpm/hooks/claude_hooks/installer.py +33 -10
- claude_mpm/hooks/claude_hooks/memory_integration.py +28 -0
- claude_mpm/hooks/claude_hooks/response_tracking.py +2 -3
- claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/connection_manager.py +30 -6
- 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/memory_integration_hook.py +46 -1
- claude_mpm/init.py +63 -19
- claude_mpm/models/agent_definition.py +7 -0
- claude_mpm/models/git_repository.py +198 -0
- claude_mpm/scripts/claude-hook-handler.sh +60 -20
- claude_mpm/scripts/launch_monitor.py +93 -13
- claude_mpm/scripts/start_activity_logging.py +3 -1
- claude_mpm/services/agents/agent_builder.py +48 -12
- claude_mpm/services/agents/agent_preset_service.py +238 -0
- claude_mpm/services/agents/agent_recommendation_service.py +278 -0
- claude_mpm/services/agents/agent_review_service.py +280 -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/cache_git_manager.py +621 -0
- claude_mpm/services/agents/deployment/agent_deployment.py +148 -2
- claude_mpm/services/agents/deployment/agent_discovery_service.py +104 -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 +238 -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 +422 -31
- 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 +841 -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 +663 -0
- claude_mpm/services/agents/loading/base_agent_manager.py +1 -13
- 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/recommender.py +5 -3
- 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 +1094 -0
- claude_mpm/services/agents/startup_sync.py +259 -0
- claude_mpm/services/agents/toolchain_detector.py +478 -0
- claude_mpm/services/analysis/__init__.py +35 -0
- claude_mpm/services/analysis/clone_detector.py +1030 -0
- claude_mpm/services/analysis/postmortem_reporter.py +474 -0
- claude_mpm/services/analysis/postmortem_service.py +765 -0
- claude_mpm/services/cli/session_pause_manager.py +1 -1
- claude_mpm/services/command_deployment_service.py +271 -6
- claude_mpm/services/core/base.py +7 -2
- 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 +2 -4
- 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/mcp_services_check.py +7 -15
- 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/config.py +3 -1
- claude_mpm/services/event_bus/direct_relay.py +3 -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 +579 -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/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/resource_monitor.py +1 -1
- claude_mpm/services/mcp_config_manager.py +75 -145
- claude_mpm/services/mcp_service_verifier.py +6 -3
- claude_mpm/services/model/model_router.py +1 -2
- claude_mpm/services/monitor/daemon.py +38 -11
- claude_mpm/services/monitor/daemon_manager.py +134 -21
- claude_mpm/services/monitor/management/lifecycle.py +8 -1
- claude_mpm/services/monitor/server.py +700 -24
- claude_mpm/services/pm_skills_deployer.py +676 -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/profile_manager.py +331 -0
- claude_mpm/services/project/documentation_manager.py +2 -1
- claude_mpm/services/project/project_organizer.py +4 -0
- claude_mpm/services/project/toolchain_analyzer.py +3 -1
- claude_mpm/services/runner_configuration_service.py +16 -3
- claude_mpm/services/self_upgrade_service.py +120 -12
- claude_mpm/services/session_management_service.py +16 -4
- claude_mpm/services/skills/__init__.py +21 -0
- claude_mpm/services/skills/git_skill_source_manager.py +1297 -0
- claude_mpm/services/skills/selective_skill_deployer.py +704 -0
- claude_mpm/services/skills/skill_discovery_service.py +568 -0
- claude_mpm/services/skills/skill_to_agent_mapper.py +406 -0
- claude_mpm/services/skills_config.py +547 -0
- claude_mpm/services/skills_deployer.py +1072 -0
- claude_mpm/services/socketio/dashboard_server.py +1 -0
- claude_mpm/services/socketio/event_normalizer.py +51 -6
- claude_mpm/services/socketio/handlers/connection.py +1 -1
- claude_mpm/services/socketio/handlers/git.py +1 -1
- claude_mpm/services/socketio/server/core.py +387 -112
- 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/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/version_control/git_operations.py +103 -0
- claude_mpm/services/visualization/__init__.py +1 -5
- claude_mpm/services/visualization/mermaid_generator.py +2 -3
- claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +2 -2
- claude_mpm/skills/skill_manager.py +92 -3
- 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/utils/agent_dependency_loader.py +91 -12
- claude_mpm/utils/agent_filters.py +261 -0
- claude_mpm/utils/dependency_cache.py +3 -1
- claude_mpm/utils/gitignore.py +244 -0
- claude_mpm/utils/migration.py +372 -0
- claude_mpm/utils/progress.py +387 -0
- claude_mpm/utils/robust_installer.py +49 -7
- claude_mpm/utils/structured_questions.py +619 -0
- {claude_mpm-4.24.0.dist-info → claude_mpm-5.4.41.dist-info}/METADATA +445 -122
- {claude_mpm-4.24.0.dist-info → claude_mpm-5.4.41.dist-info}/RECORD +298 -503
- claude_mpm-5.4.41.dist-info/entry_points.txt +5 -0
- claude_mpm-5.4.41.dist-info/licenses/LICENSE +94 -0
- claude_mpm-5.4.41.dist-info/licenses/LICENSE-FAQ.md +153 -0
- claude_mpm/agents/BASE_AGENT_TEMPLATE.md +0 -292
- claude_mpm/agents/BASE_DOCUMENTATION.md +0 -53
- claude_mpm/agents/BASE_OPS.md +0 -219
- claude_mpm/agents/BASE_PM.md +0 -468
- claude_mpm/agents/BASE_PROMPT_ENGINEER.md +0 -787
- claude_mpm/agents/BASE_QA.md +0 -167
- claude_mpm/agents/BASE_RESEARCH.md +0 -53
- claude_mpm/agents/base_agent_loader.py +0 -626
- 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 -183
- claude_mpm/agents/templates/circuit_breakers.md +0 -638
- 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 -238
- 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/javascript_engineer_agent.json +0 -380
- 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 -144
- 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 -243
- claude_mpm/agents/templates/react_engineer.json +0 -239
- 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/tauri_engineer.json +0 -274
- claude_mpm/agents/templates/ticketing.json +0 -178
- 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 -159
- claude_mpm/agents/templates/web_qa.json +0 -400
- claude_mpm/agents/templates/web_ui.json +0 -189
- claude_mpm/cli/commands/agents_detect.py +0 -380
- claude_mpm/cli/commands/agents_recommend.py +0 -309
- claude_mpm/cli/ticket_cli.py +0 -35
- claude_mpm/commands/mpm-agents-detect.md +0 -168
- claude_mpm/commands/mpm-agents-recommend.md +0 -214
- claude_mpm/commands/mpm-agents.md +0 -122
- claude_mpm/commands/mpm-auto-configure.md +0 -269
- claude_mpm/commands/mpm-resume.md +0 -372
- claude_mpm/commands/mpm-tickets.md +0 -151
- claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
- claude_mpm/dashboard/analysis_runner.py +0 -455
- claude_mpm/dashboard/index.html +0 -13
- claude_mpm/dashboard/open_dashboard.py +0 -66
- 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/css/activity.css +0 -1958
- claude_mpm/dashboard/static/css/connection-status.css +0 -370
- claude_mpm/dashboard/static/css/dashboard.css +0 -4701
- 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/components/activity-tree.js +0 -1871
- claude_mpm/dashboard/static/js/components/agent-hierarchy.js +0 -777
- claude_mpm/dashboard/static/js/components/agent-inference.js +0 -956
- claude_mpm/dashboard/static/js/components/build-tracker.js +0 -333
- claude_mpm/dashboard/static/js/components/code-simple.js +0 -857
- claude_mpm/dashboard/static/js/components/connection-debug.js +0 -654
- claude_mpm/dashboard/static/js/components/diff-viewer.js +0 -891
- claude_mpm/dashboard/static/js/components/event-processor.js +0 -542
- claude_mpm/dashboard/static/js/components/event-viewer.js +0 -1155
- claude_mpm/dashboard/static/js/components/export-manager.js +0 -368
- claude_mpm/dashboard/static/js/components/file-change-tracker.js +0 -443
- claude_mpm/dashboard/static/js/components/file-change-viewer.js +0 -690
- claude_mpm/dashboard/static/js/components/file-tool-tracker.js +0 -724
- claude_mpm/dashboard/static/js/components/file-viewer.js +0 -580
- claude_mpm/dashboard/static/js/components/hud-library-loader.js +0 -211
- claude_mpm/dashboard/static/js/components/hud-manager.js +0 -671
- claude_mpm/dashboard/static/js/components/hud-visualizer.js +0 -1718
- claude_mpm/dashboard/static/js/components/module-viewer.js +0 -2764
- claude_mpm/dashboard/static/js/components/session-manager.js +0 -579
- claude_mpm/dashboard/static/js/components/socket-manager.js +0 -368
- claude_mpm/dashboard/static/js/components/ui-state-manager.js +0 -749
- claude_mpm/dashboard/static/js/components/unified-data-viewer.js +0 -1824
- claude_mpm/dashboard/static/js/components/working-directory.js +0 -920
- claude_mpm/dashboard/static/js/connection-manager.js +0 -536
- claude_mpm/dashboard/static/js/dashboard.js +0 -1896
- claude_mpm/dashboard/static/js/extension-error-handler.js +0 -164
- 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/socket-client.js +0 -1457
- claude_mpm/dashboard/static/js/stores/dashboard-store.js +0 -562
- claude_mpm/dashboard/static/js/tab-isolation-fix.js +0 -185
- 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/socket.io.min.js +0 -7
- claude_mpm/dashboard/static/socket.io.v4.8.1.backup.js +0 -7
- 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/dashboard/templates/code_simple.html +0 -153
- claude_mpm/dashboard/templates/index.html +0 -606
- claude_mpm/dashboard/test_dashboard.html +0 -372
- claude_mpm/scripts/mcp_server.py +0 -75
- claude_mpm/scripts/mcp_wrapper.py +0 -39
- claude_mpm/services/mcp_gateway/__init__.py +0 -159
- claude_mpm/services/mcp_gateway/auto_configure.py +0 -369
- claude_mpm/services/mcp_gateway/config/__init__.py +0 -17
- claude_mpm/services/mcp_gateway/config/config_loader.py +0 -296
- claude_mpm/services/mcp_gateway/config/config_schema.py +0 -243
- claude_mpm/services/mcp_gateway/config/configuration.py +0 -429
- claude_mpm/services/mcp_gateway/core/__init__.py +0 -43
- claude_mpm/services/mcp_gateway/core/base.py +0 -312
- claude_mpm/services/mcp_gateway/core/exceptions.py +0 -253
- claude_mpm/services/mcp_gateway/core/interfaces.py +0 -443
- claude_mpm/services/mcp_gateway/core/process_pool.py +0 -971
- claude_mpm/services/mcp_gateway/core/singleton_manager.py +0 -315
- claude_mpm/services/mcp_gateway/core/startup_verification.py +0 -316
- claude_mpm/services/mcp_gateway/main.py +0 -589
- claude_mpm/services/mcp_gateway/registry/__init__.py +0 -12
- claude_mpm/services/mcp_gateway/registry/service_registry.py +0 -412
- claude_mpm/services/mcp_gateway/registry/tool_registry.py +0 -489
- claude_mpm/services/mcp_gateway/server/__init__.py +0 -15
- claude_mpm/services/mcp_gateway/server/mcp_gateway.py +0 -419
- claude_mpm/services/mcp_gateway/server/stdio_handler.py +0 -372
- claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -714
- claude_mpm/services/mcp_gateway/tools/__init__.py +0 -36
- claude_mpm/services/mcp_gateway/tools/base_adapter.py +0 -485
- claude_mpm/services/mcp_gateway/tools/document_summarizer.py +0 -789
- claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +0 -654
- claude_mpm/services/mcp_gateway/tools/health_check_tool.py +0 -456
- claude_mpm/services/mcp_gateway/tools/hello_world.py +0 -551
- claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +0 -551
- claude_mpm/services/mcp_gateway/utils/__init__.py +0 -14
- claude_mpm/services/mcp_gateway/utils/package_version_checker.py +0 -160
- claude_mpm/services/mcp_gateway/utils/update_preferences.py +0 -170
- 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-4.24.0.dist-info/entry_points.txt +0 -10
- claude_mpm-4.24.0.dist-info/licenses/LICENSE +0 -21
- /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.24.0.dist-info → claude_mpm-5.4.41.dist-info}/WHEEL +0 -0
- {claude_mpm-4.24.0.dist-info → claude_mpm-5.4.41.dist-info}/top_level.txt +0 -0
|
@@ -1,1155 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Event Viewer Component
|
|
3
|
-
* Handles event display, filtering, and selection
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
class EventViewer {
|
|
7
|
-
constructor(containerId, socketClient) {
|
|
8
|
-
this.container = document.getElementById(containerId);
|
|
9
|
-
this.socketClient = socketClient;
|
|
10
|
-
|
|
11
|
-
// State
|
|
12
|
-
this.events = [];
|
|
13
|
-
this.filteredEvents = [];
|
|
14
|
-
this.selectedEventIndex = -1;
|
|
15
|
-
this.filteredEventElements = [];
|
|
16
|
-
this.autoScroll = true;
|
|
17
|
-
|
|
18
|
-
// Filters
|
|
19
|
-
this.searchFilter = '';
|
|
20
|
-
this.typeFilter = '';
|
|
21
|
-
this.sessionFilter = '';
|
|
22
|
-
|
|
23
|
-
// Event type tracking
|
|
24
|
-
this.eventTypeCount = {};
|
|
25
|
-
this.availableEventTypes = new Set();
|
|
26
|
-
this.errorCount = 0;
|
|
27
|
-
this.eventsThisMinute = 0;
|
|
28
|
-
this.lastMinute = new Date().getMinutes();
|
|
29
|
-
|
|
30
|
-
this.init();
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Initialize the event viewer
|
|
35
|
-
*/
|
|
36
|
-
init() {
|
|
37
|
-
this.setupEventHandlers();
|
|
38
|
-
this.setupKeyboardNavigation();
|
|
39
|
-
|
|
40
|
-
// Subscribe to socket events
|
|
41
|
-
this.socketClient.onEventUpdate((events, sessions) => {
|
|
42
|
-
// Ensure we always have a valid events array
|
|
43
|
-
this.events = Array.isArray(events) ? events : [];
|
|
44
|
-
console.log('[EventViewer] Events updated - received:', this.events.length);
|
|
45
|
-
|
|
46
|
-
// Update debug metrics
|
|
47
|
-
const debugReceivedEl = document.getElementById('debug-events-received');
|
|
48
|
-
if (debugReceivedEl) {
|
|
49
|
-
debugReceivedEl.textContent = this.events.length;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
this.updateDisplay();
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Setup event handlers for UI controls
|
|
58
|
-
*/
|
|
59
|
-
setupEventHandlers() {
|
|
60
|
-
// Search input
|
|
61
|
-
const searchInput = document.getElementById('events-search-input');
|
|
62
|
-
if (searchInput) {
|
|
63
|
-
searchInput.addEventListener('input', (e) => {
|
|
64
|
-
this.searchFilter = e.target.value.toLowerCase();
|
|
65
|
-
this.applyFilters();
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// Type filter
|
|
70
|
-
const typeFilter = document.getElementById('events-type-filter');
|
|
71
|
-
if (typeFilter) {
|
|
72
|
-
typeFilter.addEventListener('change', (e) => {
|
|
73
|
-
this.typeFilter = e.target.value;
|
|
74
|
-
this.applyFilters();
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Setup keyboard navigation for events
|
|
81
|
-
* Note: This is now handled by the unified Dashboard navigation system
|
|
82
|
-
*/
|
|
83
|
-
setupKeyboardNavigation() {
|
|
84
|
-
// Keyboard navigation is now handled by Dashboard.setupUnifiedKeyboardNavigation()
|
|
85
|
-
// This method is kept for backward compatibility but does nothing
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Handle arrow key navigation
|
|
90
|
-
* @param {number} direction - Direction: 1 for down, -1 for up
|
|
91
|
-
*/
|
|
92
|
-
handleArrowNavigation(direction) {
|
|
93
|
-
if (this.filteredEventElements.length === 0) return;
|
|
94
|
-
|
|
95
|
-
// Calculate new index
|
|
96
|
-
let newIndex = this.selectedEventIndex + direction;
|
|
97
|
-
|
|
98
|
-
// Wrap around
|
|
99
|
-
if (newIndex >= this.filteredEventElements.length) {
|
|
100
|
-
newIndex = 0;
|
|
101
|
-
} else if (newIndex < 0) {
|
|
102
|
-
newIndex = this.filteredEventElements.length - 1;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
this.showEventDetails(newIndex);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Apply filters to events
|
|
110
|
-
*/
|
|
111
|
-
applyFilters() {
|
|
112
|
-
// Defensive check to ensure events array exists
|
|
113
|
-
if (!this.events || !Array.isArray(this.events)) {
|
|
114
|
-
console.warn('EventViewer: events array is not initialized, using empty array');
|
|
115
|
-
this.events = [];
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
this.filteredEvents = this.events.filter(event => {
|
|
119
|
-
// NO AUTOMATIC FILTERING - All events are shown by default for complete visibility
|
|
120
|
-
// Users can apply their own filters using the search and type filter controls
|
|
121
|
-
|
|
122
|
-
// User-controlled search filter
|
|
123
|
-
if (this.searchFilter) {
|
|
124
|
-
const searchableText = [
|
|
125
|
-
event.type || '',
|
|
126
|
-
event.subtype || '',
|
|
127
|
-
JSON.stringify(event.data || {})
|
|
128
|
-
].join(' ').toLowerCase();
|
|
129
|
-
|
|
130
|
-
if (!searchableText.includes(this.searchFilter)) {
|
|
131
|
-
return false;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// User-controlled type filter - handles full hook types (like "hook.user_prompt") and main types
|
|
136
|
-
if (this.typeFilter) {
|
|
137
|
-
// Use the same logic as formatEventType to get the full event type
|
|
138
|
-
const eventType = event.type && event.type.trim() !== '' ? event.type : '';
|
|
139
|
-
const fullEventType = event.subtype && eventType ? `${eventType}.${event.subtype}` : eventType;
|
|
140
|
-
if (fullEventType !== this.typeFilter) {
|
|
141
|
-
return false;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// User-controlled session filter
|
|
146
|
-
if (this.sessionFilter && this.sessionFilter !== '') {
|
|
147
|
-
if (!event.data || event.data.session_id !== this.sessionFilter) {
|
|
148
|
-
return false;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// Allow all events through unless filtered by user controls
|
|
153
|
-
return true;
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
this.renderEvents();
|
|
157
|
-
this.updateMetrics();
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Update available event types and populate dropdown
|
|
162
|
-
*/
|
|
163
|
-
updateEventTypeDropdown() {
|
|
164
|
-
const dropdown = document.getElementById('events-type-filter');
|
|
165
|
-
if (!dropdown) return;
|
|
166
|
-
|
|
167
|
-
// Extract unique event types from current events
|
|
168
|
-
// Use the same logic as formatEventType to get full event type names
|
|
169
|
-
const eventTypes = new Set();
|
|
170
|
-
// Defensive check to ensure events array exists
|
|
171
|
-
if (!this.events || !Array.isArray(this.events)) {
|
|
172
|
-
console.warn('EventViewer: events array is not initialized in updateEventTypeDropdown');
|
|
173
|
-
this.events = [];
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
this.events.forEach(event => {
|
|
177
|
-
if (event.type && event.type.trim() !== '') {
|
|
178
|
-
// Combine type and subtype if subtype exists, otherwise just use type
|
|
179
|
-
const fullType = event.subtype ? `${event.type}.${event.subtype}` : event.type;
|
|
180
|
-
eventTypes.add(fullType);
|
|
181
|
-
}
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
// Check if event types have changed
|
|
185
|
-
const currentTypes = Array.from(eventTypes).sort();
|
|
186
|
-
const previousTypes = Array.from(this.availableEventTypes).sort();
|
|
187
|
-
|
|
188
|
-
if (JSON.stringify(currentTypes) === JSON.stringify(previousTypes)) {
|
|
189
|
-
return; // No change needed
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// Update our tracking
|
|
193
|
-
this.availableEventTypes = eventTypes;
|
|
194
|
-
|
|
195
|
-
// Store the current selection
|
|
196
|
-
const currentSelection = dropdown.value;
|
|
197
|
-
|
|
198
|
-
// Clear existing options except "All Events"
|
|
199
|
-
dropdown.innerHTML = '<option value="">All Events</option>';
|
|
200
|
-
|
|
201
|
-
// Add new options sorted alphabetically
|
|
202
|
-
const sortedTypes = Array.from(eventTypes).sort();
|
|
203
|
-
sortedTypes.forEach(type => {
|
|
204
|
-
const option = document.createElement('option');
|
|
205
|
-
option.value = type;
|
|
206
|
-
option.textContent = type;
|
|
207
|
-
dropdown.appendChild(option);
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
// Restore selection if it still exists
|
|
211
|
-
if (currentSelection && eventTypes.has(currentSelection)) {
|
|
212
|
-
dropdown.value = currentSelection;
|
|
213
|
-
} else if (currentSelection && !eventTypes.has(currentSelection)) {
|
|
214
|
-
// If the previously selected type no longer exists, clear the filter
|
|
215
|
-
dropdown.value = '';
|
|
216
|
-
this.typeFilter = '';
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* Update the display with current events
|
|
222
|
-
*/
|
|
223
|
-
updateDisplay() {
|
|
224
|
-
this.updateEventTypeDropdown();
|
|
225
|
-
this.applyFilters();
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
/**
|
|
229
|
-
* Render events in the UI
|
|
230
|
-
*/
|
|
231
|
-
renderEvents() {
|
|
232
|
-
// CRITICAL FIX: Use the container passed to constructor, not hardcoded events-list
|
|
233
|
-
// This prevents events from being rendered in the wrong tab
|
|
234
|
-
const eventsList = this.container;
|
|
235
|
-
if (!eventsList) {
|
|
236
|
-
console.warn('[EventViewer] Container not found, skipping render');
|
|
237
|
-
return;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
// SAFETY: Basic check to ensure we're rendering to the correct container
|
|
241
|
-
if (eventsList.id !== 'events-list') {
|
|
242
|
-
console.error('[EventViewer] CRITICAL: Attempting to render to wrong container:', eventsList.id);
|
|
243
|
-
return;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
// Check if events tab exists and render regardless of active state
|
|
247
|
-
// This allows events to be pre-rendered when tab becomes active
|
|
248
|
-
const eventsTab = document.getElementById('events-tab');
|
|
249
|
-
if (!eventsTab) {
|
|
250
|
-
console.warn('[EventViewer] Events tab not found in DOM');
|
|
251
|
-
return;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
console.log('[EventViewer] Rendering events - count:', this.filteredEvents.length);
|
|
255
|
-
|
|
256
|
-
// Check if user is at bottom BEFORE rendering (for autoscroll decision)
|
|
257
|
-
const wasAtBottom = (eventsList.scrollTop + eventsList.clientHeight >= eventsList.scrollHeight - 10);
|
|
258
|
-
|
|
259
|
-
if (this.filteredEvents.length === 0) {
|
|
260
|
-
eventsList.innerHTML = `
|
|
261
|
-
<div class="no-events">
|
|
262
|
-
${this.events.length === 0 ?
|
|
263
|
-
'Connect to Socket.IO server to see events...' :
|
|
264
|
-
'No events match current filters...'}
|
|
265
|
-
</div>
|
|
266
|
-
`;
|
|
267
|
-
this.filteredEventElements = [];
|
|
268
|
-
return;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
const html = this.filteredEvents.map((event, index) => {
|
|
272
|
-
const timestamp = new Date(event.timestamp).toLocaleTimeString();
|
|
273
|
-
const eventClass = event.type ? `event-${event.type}` : 'event-default';
|
|
274
|
-
const isSelected = index === this.selectedEventIndex;
|
|
275
|
-
|
|
276
|
-
// Get main content and timestamp separately
|
|
277
|
-
const mainContent = this.formatSingleRowEventContent(event);
|
|
278
|
-
|
|
279
|
-
// Check if this is an Edit/MultiEdit tool event and add diff viewer
|
|
280
|
-
const diffViewer = this.createInlineEditDiffViewer(event, index);
|
|
281
|
-
|
|
282
|
-
return `
|
|
283
|
-
<div class="event-item single-row ${eventClass} ${isSelected ? 'selected' : ''}"
|
|
284
|
-
onclick="eventViewer.showEventDetails(${index})"
|
|
285
|
-
data-index="${index}">
|
|
286
|
-
<span class="event-single-row-content">
|
|
287
|
-
<span class="event-content-main">${mainContent}</span>
|
|
288
|
-
<span class="event-timestamp">${timestamp}</span>
|
|
289
|
-
</span>
|
|
290
|
-
${diffViewer}
|
|
291
|
-
</div>
|
|
292
|
-
`;
|
|
293
|
-
}).join('');
|
|
294
|
-
|
|
295
|
-
eventsList.innerHTML = html;
|
|
296
|
-
|
|
297
|
-
// Update filtered elements reference
|
|
298
|
-
this.filteredEventElements = Array.from(eventsList.querySelectorAll('.event-item'));
|
|
299
|
-
|
|
300
|
-
console.log('[EventViewer] Events rendered - filtered:', this.filteredEvents.length, 'elements:', this.filteredEventElements.length);
|
|
301
|
-
|
|
302
|
-
// Update debug metrics
|
|
303
|
-
const debugRenderedEl = document.getElementById('debug-events-rendered');
|
|
304
|
-
if (debugRenderedEl) {
|
|
305
|
-
debugRenderedEl.textContent = this.filteredEvents.length;
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
// Update Dashboard navigation items if we're in the events tab
|
|
309
|
-
if (window.dashboard && window.dashboard.currentTab === 'events' &&
|
|
310
|
-
window.dashboard.tabNavigation && window.dashboard.tabNavigation.events) {
|
|
311
|
-
window.dashboard.tabNavigation.events.items = this.filteredEventElements;
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
// Auto-scroll only if user was already at bottom before rendering
|
|
315
|
-
if (this.filteredEvents.length > 0 && wasAtBottom && this.autoScroll) {
|
|
316
|
-
// Use requestAnimationFrame to ensure DOM has updated
|
|
317
|
-
requestAnimationFrame(() => {
|
|
318
|
-
eventsList.scrollTop = eventsList.scrollHeight;
|
|
319
|
-
});
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
/**
|
|
324
|
-
* Format event type for display
|
|
325
|
-
* @param {Object} event - Event object
|
|
326
|
-
* @returns {string} Formatted event type
|
|
327
|
-
*/
|
|
328
|
-
formatEventType(event) {
|
|
329
|
-
// If we have type and subtype, use them
|
|
330
|
-
if (event.type && event.subtype) {
|
|
331
|
-
// Check if type and subtype are identical or subtype is 'generic' to prevent redundant display
|
|
332
|
-
if (event.type === event.subtype || event.subtype === 'generic') {
|
|
333
|
-
return event.type;
|
|
334
|
-
}
|
|
335
|
-
return `${event.type}.${event.subtype}`;
|
|
336
|
-
}
|
|
337
|
-
// If we have just type, use it
|
|
338
|
-
if (event.type) {
|
|
339
|
-
return event.type;
|
|
340
|
-
}
|
|
341
|
-
// If we have originalEventName (from transformation), use it as fallback
|
|
342
|
-
if (event.originalEventName) {
|
|
343
|
-
return event.originalEventName;
|
|
344
|
-
}
|
|
345
|
-
// Last resort fallback
|
|
346
|
-
return 'unknown';
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
/**
|
|
350
|
-
* Format event data for display
|
|
351
|
-
* @param {Object} event - Event object
|
|
352
|
-
* @returns {string} Formatted event data
|
|
353
|
-
*/
|
|
354
|
-
formatEventData(event) {
|
|
355
|
-
if (!event.data) return 'No data';
|
|
356
|
-
|
|
357
|
-
// Special formatting for different event types
|
|
358
|
-
switch (event.type) {
|
|
359
|
-
case 'session':
|
|
360
|
-
return this.formatSessionEvent(event);
|
|
361
|
-
case 'claude':
|
|
362
|
-
return this.formatClaudeEvent(event);
|
|
363
|
-
case 'agent':
|
|
364
|
-
return this.formatAgentEvent(event);
|
|
365
|
-
case 'hook':
|
|
366
|
-
return this.formatHookEvent(event);
|
|
367
|
-
case 'todo':
|
|
368
|
-
return this.formatTodoEvent(event);
|
|
369
|
-
case 'memory':
|
|
370
|
-
return this.formatMemoryEvent(event);
|
|
371
|
-
case 'log':
|
|
372
|
-
return this.formatLogEvent(event);
|
|
373
|
-
case 'code':
|
|
374
|
-
return this.formatCodeEvent(event);
|
|
375
|
-
default:
|
|
376
|
-
return this.formatGenericEvent(event);
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
/**
|
|
381
|
-
* Format session event data
|
|
382
|
-
*/
|
|
383
|
-
formatSessionEvent(event) {
|
|
384
|
-
const data = event.data;
|
|
385
|
-
if (event.subtype === 'started') {
|
|
386
|
-
return `<strong>Session started:</strong> ${data.session_id || 'Unknown'}`;
|
|
387
|
-
} else if (event.subtype === 'ended') {
|
|
388
|
-
return `<strong>Session ended:</strong> ${data.session_id || 'Unknown'}`;
|
|
389
|
-
}
|
|
390
|
-
return `<strong>Session:</strong> ${JSON.stringify(data)}`;
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
/**
|
|
394
|
-
* Format Claude event data
|
|
395
|
-
*/
|
|
396
|
-
formatClaudeEvent(event) {
|
|
397
|
-
const data = event.data;
|
|
398
|
-
if (event.subtype === 'request') {
|
|
399
|
-
const prompt = data.prompt || data.message || '';
|
|
400
|
-
const truncated = prompt.length > 100 ? prompt.substring(0, 100) + '...' : prompt;
|
|
401
|
-
return `<strong>Request:</strong> ${truncated}`;
|
|
402
|
-
} else if (event.subtype === 'response') {
|
|
403
|
-
const response = data.response || data.content || '';
|
|
404
|
-
const truncated = response.length > 100 ? response.substring(0, 100) + '...' : response;
|
|
405
|
-
return `<strong>Response:</strong> ${truncated}`;
|
|
406
|
-
}
|
|
407
|
-
return `<strong>Claude:</strong> ${JSON.stringify(data)}`;
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
/**
|
|
411
|
-
* Format agent event data
|
|
412
|
-
*/
|
|
413
|
-
formatAgentEvent(event) {
|
|
414
|
-
const data = event.data;
|
|
415
|
-
if (event.subtype === 'loaded') {
|
|
416
|
-
return `<strong>Agent loaded:</strong> ${data.agent_type || data.name || 'Unknown'}`;
|
|
417
|
-
} else if (event.subtype === 'executed') {
|
|
418
|
-
return `<strong>Agent executed:</strong> ${data.agent_type || data.name || 'Unknown'}`;
|
|
419
|
-
}
|
|
420
|
-
return `<strong>Agent:</strong> ${JSON.stringify(data)}`;
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
/**
|
|
424
|
-
* Format hook event data
|
|
425
|
-
*/
|
|
426
|
-
formatHookEvent(event) {
|
|
427
|
-
const data = event.data;
|
|
428
|
-
const eventType = data.event_type || event.subtype || 'unknown';
|
|
429
|
-
|
|
430
|
-
// Format based on specific hook event type
|
|
431
|
-
switch (eventType) {
|
|
432
|
-
case 'user_prompt':
|
|
433
|
-
const prompt = data.prompt_text || data.prompt_preview || '';
|
|
434
|
-
const truncated = prompt.length > 80 ? prompt.substring(0, 80) + '...' : prompt;
|
|
435
|
-
return `<strong>User Prompt:</strong> ${truncated || 'No prompt text'}`;
|
|
436
|
-
|
|
437
|
-
case 'pre_tool':
|
|
438
|
-
const toolName = data.tool_name || 'Unknown tool';
|
|
439
|
-
const operation = data.operation_type || 'operation';
|
|
440
|
-
return `<strong>Pre-Tool (${operation}):</strong> ${toolName}`;
|
|
441
|
-
|
|
442
|
-
case 'post_tool':
|
|
443
|
-
const postToolName = data.tool_name || 'Unknown tool';
|
|
444
|
-
const status = data.success ? 'success' : data.status || 'failed';
|
|
445
|
-
const duration = data.duration_ms ? ` (${data.duration_ms}ms)` : '';
|
|
446
|
-
return `<strong>Post-Tool (${status}):</strong> ${postToolName}${duration}`;
|
|
447
|
-
|
|
448
|
-
case 'notification':
|
|
449
|
-
const notifType = data.notification_type || 'notification';
|
|
450
|
-
const message = data.message_preview || data.message || 'No message';
|
|
451
|
-
return `<strong>Notification (${notifType}):</strong> ${message}`;
|
|
452
|
-
|
|
453
|
-
case 'stop':
|
|
454
|
-
const reason = data.reason || 'unknown';
|
|
455
|
-
const stopType = data.stop_type || 'normal';
|
|
456
|
-
return `<strong>Stop (${stopType}):</strong> ${reason}`;
|
|
457
|
-
|
|
458
|
-
case 'subagent_start':
|
|
459
|
-
// Try multiple locations for agent type
|
|
460
|
-
const startAgentType = data.agent_type || data.agent || data.subagent_type || 'Unknown';
|
|
461
|
-
const startPrompt = data.prompt || data.description || data.task || 'No description';
|
|
462
|
-
const startTruncated = startPrompt.length > 60 ? startPrompt.substring(0, 60) + '...' : startPrompt;
|
|
463
|
-
// Format with proper agent type display
|
|
464
|
-
const startAgentDisplay = this.formatAgentType(startAgentType);
|
|
465
|
-
return `<strong>Subagent Start (${startAgentDisplay}):</strong> ${startTruncated}`;
|
|
466
|
-
|
|
467
|
-
case 'subagent_stop':
|
|
468
|
-
// Try multiple locations for agent type
|
|
469
|
-
const agentType = data.agent_type || data.agent || data.subagent_type || 'Unknown';
|
|
470
|
-
const stopReason = data.reason || data.stop_reason || 'completed';
|
|
471
|
-
// Format with proper agent type display
|
|
472
|
-
const stopAgentDisplay = this.formatAgentType(agentType);
|
|
473
|
-
// Include task completion status if available
|
|
474
|
-
const isCompleted = data.structured_response?.task_completed;
|
|
475
|
-
const completionStatus = isCompleted !== undefined ? (isCompleted ? ' ✓' : ' ✗') : '';
|
|
476
|
-
return `<strong>Subagent Stop (${stopAgentDisplay})${completionStatus}:</strong> ${stopReason}`;
|
|
477
|
-
|
|
478
|
-
default:
|
|
479
|
-
// Fallback to original logic for unknown hook types
|
|
480
|
-
const hookName = data.hook_name || data.name || data.event_type || 'Unknown';
|
|
481
|
-
const phase = event.subtype || eventType;
|
|
482
|
-
return `<strong>Hook ${phase}:</strong> ${hookName}`;
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
/**
|
|
487
|
-
* Format todo event data
|
|
488
|
-
*/
|
|
489
|
-
formatTodoEvent(event) {
|
|
490
|
-
const data = event.data;
|
|
491
|
-
if (data.todos && Array.isArray(data.todos)) {
|
|
492
|
-
const count = data.todos.length;
|
|
493
|
-
return `<strong>Todo updated:</strong> ${count} item${count !== 1 ? 's' : ''}`;
|
|
494
|
-
}
|
|
495
|
-
return `<strong>Todo:</strong> ${JSON.stringify(data)}`;
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
/**
|
|
499
|
-
* Format memory event data
|
|
500
|
-
*/
|
|
501
|
-
formatMemoryEvent(event) {
|
|
502
|
-
const data = event.data;
|
|
503
|
-
const operation = data.operation || 'unknown';
|
|
504
|
-
return `<strong>Memory ${operation}:</strong> ${data.key || 'Unknown key'}`;
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
/**
|
|
508
|
-
* Format log event data
|
|
509
|
-
*/
|
|
510
|
-
formatLogEvent(event) {
|
|
511
|
-
const data = event.data;
|
|
512
|
-
const level = data.level || 'info';
|
|
513
|
-
const message = data.message || '';
|
|
514
|
-
const truncated = message.length > 80 ? message.substring(0, 80) + '...' : message;
|
|
515
|
-
return `<strong>[${level.toUpperCase()}]</strong> ${truncated}`;
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
/**
|
|
519
|
-
* Format code analysis event data
|
|
520
|
-
*/
|
|
521
|
-
formatCodeEvent(event) {
|
|
522
|
-
const data = event.data || {};
|
|
523
|
-
|
|
524
|
-
// Handle different code event subtypes
|
|
525
|
-
if (event.subtype === 'progress') {
|
|
526
|
-
const message = data.message || 'Processing...';
|
|
527
|
-
const percentage = data.percentage;
|
|
528
|
-
if (percentage !== undefined) {
|
|
529
|
-
return `<strong>Progress:</strong> ${message} (${Math.round(percentage)}%)`;
|
|
530
|
-
}
|
|
531
|
-
return `<strong>Progress:</strong> ${message}`;
|
|
532
|
-
} else if (event.subtype === 'analysis:queued') {
|
|
533
|
-
return `<strong>Queued:</strong> Analysis for ${data.path || 'Unknown path'}`;
|
|
534
|
-
} else if (event.subtype === 'analysis:start') {
|
|
535
|
-
return `<strong>Started:</strong> Analyzing ${data.path || 'Unknown path'}`;
|
|
536
|
-
} else if (event.subtype === 'analysis:complete') {
|
|
537
|
-
const duration = data.duration ? ` (${data.duration.toFixed(2)}s)` : '';
|
|
538
|
-
return `<strong>Complete:</strong> Analysis finished${duration}`;
|
|
539
|
-
} else if (event.subtype === 'analysis:error') {
|
|
540
|
-
return `<strong>Error:</strong> ${data.message || 'Analysis failed'}`;
|
|
541
|
-
} else if (event.subtype === 'analysis:cancelled') {
|
|
542
|
-
return `<strong>Cancelled:</strong> Analysis stopped for ${data.path || 'Unknown path'}`;
|
|
543
|
-
} else if (event.subtype === 'file:start') {
|
|
544
|
-
return `<strong>File:</strong> Processing ${data.file || 'Unknown file'}`;
|
|
545
|
-
} else if (event.subtype === 'file:complete') {
|
|
546
|
-
const nodes = data.nodes_count !== undefined ? ` (${data.nodes_count} nodes)` : '';
|
|
547
|
-
return `<strong>File done:</strong> ${data.file || 'Unknown file'}${nodes}`;
|
|
548
|
-
} else if (event.subtype === 'node:found') {
|
|
549
|
-
return `<strong>Node:</strong> Found ${data.node_type || 'element'} "${data.name || 'unnamed'}"`;
|
|
550
|
-
} else if (event.subtype === 'error') {
|
|
551
|
-
return `<strong>Error:</strong> ${data.error || 'Unknown error'} in ${data.file || 'file'}`;
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
// Generic fallback for code events
|
|
555
|
-
const json = JSON.stringify(data);
|
|
556
|
-
return `<strong>Code:</strong> ${json.length > 100 ? json.substring(0, 100) + '...' : json}`;
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
/**
|
|
560
|
-
* Format generic event data
|
|
561
|
-
*/
|
|
562
|
-
formatGenericEvent(event) {
|
|
563
|
-
const data = event.data;
|
|
564
|
-
if (typeof data === 'string') {
|
|
565
|
-
return data.length > 100 ? data.substring(0, 100) + '...' : data;
|
|
566
|
-
}
|
|
567
|
-
return JSON.stringify(data);
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
/**
|
|
571
|
-
* Format agent type for display with proper capitalization
|
|
572
|
-
* @param {string} agentType - The raw agent type string
|
|
573
|
-
* @returns {string} Formatted agent type for display
|
|
574
|
-
*/
|
|
575
|
-
formatAgentType(agentType) {
|
|
576
|
-
// Handle common agent type patterns
|
|
577
|
-
const agentTypeMap = {
|
|
578
|
-
'research': 'Research',
|
|
579
|
-
'architect': 'Architect',
|
|
580
|
-
'engineer': 'Engineer',
|
|
581
|
-
'qa': 'QA',
|
|
582
|
-
'pm': 'PM',
|
|
583
|
-
'project_manager': 'PM',
|
|
584
|
-
'research_agent': 'Research',
|
|
585
|
-
'architect_agent': 'Architect',
|
|
586
|
-
'engineer_agent': 'Engineer',
|
|
587
|
-
'qa_agent': 'QA',
|
|
588
|
-
'unknown': 'Unknown'
|
|
589
|
-
};
|
|
590
|
-
|
|
591
|
-
// Try to find a match in the map (case-insensitive)
|
|
592
|
-
const lowerType = (agentType || 'unknown').toLowerCase();
|
|
593
|
-
if (agentTypeMap[lowerType]) {
|
|
594
|
-
return agentTypeMap[lowerType];
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
// If not in map, try to extract the agent name from patterns like "Research Agent" or "research_agent"
|
|
598
|
-
const match = agentType.match(/^(\w+)(?:_agent|Agent)?$/i);
|
|
599
|
-
if (match && match[1]) {
|
|
600
|
-
// Capitalize first letter
|
|
601
|
-
return match[1].charAt(0).toUpperCase() + match[1].slice(1).toLowerCase();
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
// Fallback: just capitalize first letter of whatever we have
|
|
605
|
-
return agentType.charAt(0).toUpperCase() + agentType.slice(1);
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
/**
|
|
609
|
-
* Format event content for single-row display (without timestamp)
|
|
610
|
-
* Format: "{type}.{subtype}" followed by data details
|
|
611
|
-
* @param {Object} event - Event object
|
|
612
|
-
* @returns {string} Formatted single-row event content string
|
|
613
|
-
*/
|
|
614
|
-
formatSingleRowEventContent(event) {
|
|
615
|
-
const eventType = this.formatEventType(event);
|
|
616
|
-
const data = event.data || {};
|
|
617
|
-
|
|
618
|
-
// Include source if it's not the default 'system' source
|
|
619
|
-
const sourcePrefix = event.source && event.source !== 'system' ? `[${event.source}] ` : '';
|
|
620
|
-
|
|
621
|
-
// Extract meaningful details from the data package for different event types
|
|
622
|
-
let dataDetails = '';
|
|
623
|
-
|
|
624
|
-
switch (event.type) {
|
|
625
|
-
case 'hook':
|
|
626
|
-
// Hook events: show tool name and operation details
|
|
627
|
-
const toolName = event.tool_name || data.tool_name || 'Unknown';
|
|
628
|
-
const hookType = event.subtype || 'Unknown';
|
|
629
|
-
|
|
630
|
-
// Format specific hook types
|
|
631
|
-
if (hookType === 'pre_tool' || hookType === 'post_tool') {
|
|
632
|
-
const operation = data.operation_type || '';
|
|
633
|
-
const status = hookType === 'post_tool' && data.success !== undefined
|
|
634
|
-
? (data.success ? '✓' : '✗')
|
|
635
|
-
: '';
|
|
636
|
-
dataDetails = `${toolName}${operation ? ` (${operation})` : ''}${status ? ` ${status}` : ''}`;
|
|
637
|
-
} else if (hookType === 'user_prompt') {
|
|
638
|
-
const prompt = data.prompt_text || data.prompt_preview || '';
|
|
639
|
-
const truncated = prompt.length > 60 ? prompt.substring(0, 60) + '...' : prompt;
|
|
640
|
-
dataDetails = truncated || 'No prompt text';
|
|
641
|
-
} else if (hookType === 'subagent_start') {
|
|
642
|
-
// Enhanced agent type detection
|
|
643
|
-
const agentType = data.agent_type || data.agent || data.subagent_type || 'Unknown';
|
|
644
|
-
const agentDisplay = this.formatAgentType(agentType);
|
|
645
|
-
const prompt = data.prompt || data.description || data.task || '';
|
|
646
|
-
const truncated = prompt.length > 40 ? prompt.substring(0, 40) + '...' : prompt;
|
|
647
|
-
dataDetails = truncated ? `${agentDisplay} - ${truncated}` : agentDisplay;
|
|
648
|
-
} else if (hookType === 'subagent_stop') {
|
|
649
|
-
// Enhanced agent type detection for subagent_stop
|
|
650
|
-
const agentType = data.agent_type || data.agent || data.subagent_type || 'Unknown';
|
|
651
|
-
const agentDisplay = this.formatAgentType(agentType);
|
|
652
|
-
const reason = data.reason || data.stop_reason || 'completed';
|
|
653
|
-
const isCompleted = data.structured_response?.task_completed;
|
|
654
|
-
const status = isCompleted !== undefined ? (isCompleted ? '✓' : '✗') : '';
|
|
655
|
-
dataDetails = `${agentDisplay}${status ? ' ' + status : ''} - ${reason}`;
|
|
656
|
-
} else if (hookType === 'stop') {
|
|
657
|
-
const reason = data.reason || 'completed';
|
|
658
|
-
const stopType = data.stop_type || 'normal';
|
|
659
|
-
dataDetails = `${stopType} - ${reason}`;
|
|
660
|
-
} else {
|
|
661
|
-
dataDetails = toolName;
|
|
662
|
-
}
|
|
663
|
-
break;
|
|
664
|
-
|
|
665
|
-
case 'agent':
|
|
666
|
-
// Agent events: show agent name and status
|
|
667
|
-
const agentName = event.subagent_type || data.subagent_type || 'PM';
|
|
668
|
-
const status = data.status || '';
|
|
669
|
-
dataDetails = `${agentName}${status ? ` - ${status}` : ''}`;
|
|
670
|
-
break;
|
|
671
|
-
|
|
672
|
-
case 'todo':
|
|
673
|
-
// Todo events: show item count and status changes
|
|
674
|
-
if (data.todos && Array.isArray(data.todos)) {
|
|
675
|
-
const count = data.todos.length;
|
|
676
|
-
const completed = data.todos.filter(t => t.status === 'completed').length;
|
|
677
|
-
const inProgress = data.todos.filter(t => t.status === 'in_progress').length;
|
|
678
|
-
dataDetails = `${count} items (${completed} completed, ${inProgress} in progress)`;
|
|
679
|
-
} else {
|
|
680
|
-
dataDetails = 'Todo update';
|
|
681
|
-
}
|
|
682
|
-
break;
|
|
683
|
-
|
|
684
|
-
case 'memory':
|
|
685
|
-
// Memory events: show operation and key
|
|
686
|
-
const operation = data.operation || 'unknown';
|
|
687
|
-
const key = data.key || 'unknown';
|
|
688
|
-
const value = data.value ? ` = ${JSON.stringify(data.value).substring(0, 30)}...` : '';
|
|
689
|
-
dataDetails = `${operation}: ${key}${value}`;
|
|
690
|
-
break;
|
|
691
|
-
|
|
692
|
-
case 'session':
|
|
693
|
-
// Session events: show session ID
|
|
694
|
-
const sessionId = data.session_id || 'unknown';
|
|
695
|
-
dataDetails = `ID: ${sessionId}`;
|
|
696
|
-
break;
|
|
697
|
-
|
|
698
|
-
case 'claude':
|
|
699
|
-
// Claude events: show request/response preview
|
|
700
|
-
if (event.subtype === 'request') {
|
|
701
|
-
const prompt = data.prompt || data.message || '';
|
|
702
|
-
const truncated = prompt.length > 60 ? prompt.substring(0, 60) + '...' : prompt;
|
|
703
|
-
dataDetails = truncated || 'Empty request';
|
|
704
|
-
} else if (event.subtype === 'response') {
|
|
705
|
-
const response = data.response || data.content || '';
|
|
706
|
-
const truncated = response.length > 60 ? response.substring(0, 60) + '...' : response;
|
|
707
|
-
dataDetails = truncated || 'Empty response';
|
|
708
|
-
} else {
|
|
709
|
-
dataDetails = data.message || 'Claude interaction';
|
|
710
|
-
}
|
|
711
|
-
break;
|
|
712
|
-
|
|
713
|
-
case 'log':
|
|
714
|
-
// Log events: show log level and message
|
|
715
|
-
const level = data.level || 'info';
|
|
716
|
-
const message = data.message || '';
|
|
717
|
-
const truncated = message.length > 60 ? message.substring(0, 60) + '...' : message;
|
|
718
|
-
dataDetails = `[${level.toUpperCase()}] ${truncated}`;
|
|
719
|
-
break;
|
|
720
|
-
|
|
721
|
-
case 'test':
|
|
722
|
-
// Test events: show test name or details
|
|
723
|
-
const testName = data.test_name || data.name || 'Test';
|
|
724
|
-
dataDetails = testName;
|
|
725
|
-
break;
|
|
726
|
-
|
|
727
|
-
default:
|
|
728
|
-
// Generic events: show any available data
|
|
729
|
-
if (typeof data === 'string') {
|
|
730
|
-
dataDetails = data.length > 60 ? data.substring(0, 60) + '...' : data;
|
|
731
|
-
} else if (data.message) {
|
|
732
|
-
dataDetails = data.message.length > 60 ? data.message.substring(0, 60) + '...' : data.message;
|
|
733
|
-
} else if (data.name) {
|
|
734
|
-
dataDetails = data.name;
|
|
735
|
-
} else if (Object.keys(data).length > 0) {
|
|
736
|
-
// Show first meaningful field from data
|
|
737
|
-
const firstKey = Object.keys(data).find(k => !['timestamp', 'id'].includes(k));
|
|
738
|
-
if (firstKey) {
|
|
739
|
-
const value = data[firstKey];
|
|
740
|
-
dataDetails = `${firstKey}: ${typeof value === 'object' ? JSON.stringify(value).substring(0, 40) + '...' : value}`;
|
|
741
|
-
}
|
|
742
|
-
}
|
|
743
|
-
break;
|
|
744
|
-
}
|
|
745
|
-
|
|
746
|
-
// Return formatted string: "[source] {type}.{subtype} - {data details}"
|
|
747
|
-
// The eventType already contains the type.subtype format from formatEventType()
|
|
748
|
-
const fullType = `${sourcePrefix}${eventType}`;
|
|
749
|
-
return dataDetails ? `${fullType} - ${dataDetails}` : fullType;
|
|
750
|
-
}
|
|
751
|
-
|
|
752
|
-
/**
|
|
753
|
-
* Get display name for hook types
|
|
754
|
-
* @param {string} hookType - Hook subtype
|
|
755
|
-
* @param {Object} data - Event data
|
|
756
|
-
* @returns {string} Display name
|
|
757
|
-
*/
|
|
758
|
-
getHookDisplayName(hookType, data) {
|
|
759
|
-
const hookNames = {
|
|
760
|
-
'pre_tool': 'Pre-Tool',
|
|
761
|
-
'post_tool': 'Post-Tool',
|
|
762
|
-
'user_prompt': 'User-Prompt',
|
|
763
|
-
'stop': 'Stop',
|
|
764
|
-
'subagent_start': 'Subagent-Start',
|
|
765
|
-
'subagent_stop': 'Subagent-Stop',
|
|
766
|
-
'notification': 'Notification'
|
|
767
|
-
};
|
|
768
|
-
|
|
769
|
-
// Handle non-string hookType safely
|
|
770
|
-
if (hookNames[hookType]) {
|
|
771
|
-
return hookNames[hookType];
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
// Convert to string and handle null/undefined
|
|
775
|
-
const typeStr = String(hookType || 'unknown');
|
|
776
|
-
return typeStr.replace(/_/g, ' ');
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
/**
|
|
780
|
-
* Get event category for display
|
|
781
|
-
* @param {Object} event - Event object
|
|
782
|
-
* @returns {string} Category
|
|
783
|
-
*/
|
|
784
|
-
getEventCategory(event) {
|
|
785
|
-
const data = event.data || {};
|
|
786
|
-
const toolName = event.tool_name || data.tool_name || '';
|
|
787
|
-
|
|
788
|
-
// Categorize based on tool type
|
|
789
|
-
if (['Read', 'Write', 'Edit', 'MultiEdit'].includes(toolName)) {
|
|
790
|
-
return 'file_operations';
|
|
791
|
-
} else if (['Bash', 'grep', 'Glob'].includes(toolName)) {
|
|
792
|
-
return 'system_operations';
|
|
793
|
-
} else if (toolName === 'TodoWrite') {
|
|
794
|
-
return 'task_management';
|
|
795
|
-
} else if (toolName === 'Task') {
|
|
796
|
-
return 'agent_delegation';
|
|
797
|
-
} else if (event.subtype === 'subagent_start' || event.subtype === 'subagent_stop') {
|
|
798
|
-
return 'agent_delegation';
|
|
799
|
-
} else if (event.subtype === 'stop') {
|
|
800
|
-
return 'session_control';
|
|
801
|
-
}
|
|
802
|
-
|
|
803
|
-
return 'general';
|
|
804
|
-
}
|
|
805
|
-
|
|
806
|
-
/**
|
|
807
|
-
* Show event details and update selection
|
|
808
|
-
* @param {number} index - Index of event to show
|
|
809
|
-
*/
|
|
810
|
-
showEventDetails(index) {
|
|
811
|
-
// Defensive checks
|
|
812
|
-
if (!this.filteredEvents || !Array.isArray(this.filteredEvents)) {
|
|
813
|
-
console.warn('EventViewer: filteredEvents array is not initialized');
|
|
814
|
-
return;
|
|
815
|
-
}
|
|
816
|
-
if (index < 0 || index >= this.filteredEvents.length) return;
|
|
817
|
-
|
|
818
|
-
// Update selection
|
|
819
|
-
this.selectedEventIndex = index;
|
|
820
|
-
|
|
821
|
-
// Get the selected event
|
|
822
|
-
const event = this.filteredEvents[index];
|
|
823
|
-
|
|
824
|
-
// Coordinate with Dashboard unified navigation system
|
|
825
|
-
if (window.dashboard) {
|
|
826
|
-
// Update the dashboard's navigation state for events tab
|
|
827
|
-
if (window.dashboard.tabNavigation && window.dashboard.tabNavigation.events) {
|
|
828
|
-
window.dashboard.tabNavigation.events.selectedIndex = index;
|
|
829
|
-
}
|
|
830
|
-
if (window.dashboard.selectCard) {
|
|
831
|
-
window.dashboard.selectCard('events', index, 'event', event);
|
|
832
|
-
}
|
|
833
|
-
}
|
|
834
|
-
|
|
835
|
-
// Update visual selection (this will be handled by Dashboard.updateCardSelectionUI())
|
|
836
|
-
this.filteredEventElements.forEach((el, i) => {
|
|
837
|
-
el.classList.toggle('selected', i === index);
|
|
838
|
-
});
|
|
839
|
-
|
|
840
|
-
// Notify other components about selection
|
|
841
|
-
document.dispatchEvent(new CustomEvent('eventSelected', {
|
|
842
|
-
detail: { event, index }
|
|
843
|
-
}));
|
|
844
|
-
|
|
845
|
-
// Scroll to selected event if not visible
|
|
846
|
-
const selectedElement = this.filteredEventElements[index];
|
|
847
|
-
if (selectedElement) {
|
|
848
|
-
selectedElement.scrollIntoView({
|
|
849
|
-
behavior: 'smooth',
|
|
850
|
-
block: 'nearest'
|
|
851
|
-
});
|
|
852
|
-
}
|
|
853
|
-
}
|
|
854
|
-
|
|
855
|
-
/**
|
|
856
|
-
* Clear event selection
|
|
857
|
-
*/
|
|
858
|
-
clearSelection() {
|
|
859
|
-
this.selectedEventIndex = -1;
|
|
860
|
-
this.filteredEventElements.forEach(el => {
|
|
861
|
-
el.classList.remove('selected');
|
|
862
|
-
});
|
|
863
|
-
|
|
864
|
-
// Coordinate with Dashboard unified navigation system
|
|
865
|
-
if (window.dashboard) {
|
|
866
|
-
if (window.dashboard.tabNavigation && window.dashboard.tabNavigation.events) {
|
|
867
|
-
window.dashboard.tabNavigation.events.selectedIndex = -1;
|
|
868
|
-
}
|
|
869
|
-
if (window.dashboard.clearCardSelection) {
|
|
870
|
-
window.dashboard.clearCardSelection();
|
|
871
|
-
}
|
|
872
|
-
}
|
|
873
|
-
|
|
874
|
-
// Notify other components
|
|
875
|
-
document.dispatchEvent(new CustomEvent('eventSelectionCleared'));
|
|
876
|
-
}
|
|
877
|
-
|
|
878
|
-
/**
|
|
879
|
-
* Update metrics display
|
|
880
|
-
*/
|
|
881
|
-
updateMetrics() {
|
|
882
|
-
// Update event type counts
|
|
883
|
-
this.eventTypeCount = {};
|
|
884
|
-
this.errorCount = 0;
|
|
885
|
-
|
|
886
|
-
// Defensive check to ensure events array exists
|
|
887
|
-
if (!this.events || !Array.isArray(this.events)) {
|
|
888
|
-
console.warn('EventViewer: events array is not initialized in updateMetrics');
|
|
889
|
-
this.events = [];
|
|
890
|
-
}
|
|
891
|
-
|
|
892
|
-
this.events.forEach(event => {
|
|
893
|
-
const type = event.type || 'unknown';
|
|
894
|
-
this.eventTypeCount[type] = (this.eventTypeCount[type] || 0) + 1;
|
|
895
|
-
|
|
896
|
-
if (event.type === 'log' &&
|
|
897
|
-
event.data &&
|
|
898
|
-
['error', 'critical'].includes(event.data.level)) {
|
|
899
|
-
this.errorCount++;
|
|
900
|
-
}
|
|
901
|
-
});
|
|
902
|
-
|
|
903
|
-
// Update events per minute
|
|
904
|
-
const currentMinute = new Date().getMinutes();
|
|
905
|
-
if (currentMinute !== this.lastMinute) {
|
|
906
|
-
this.lastMinute = currentMinute;
|
|
907
|
-
this.eventsThisMinute = 0;
|
|
908
|
-
}
|
|
909
|
-
|
|
910
|
-
// Count events in the last minute
|
|
911
|
-
const oneMinuteAgo = new Date(Date.now() - 60000);
|
|
912
|
-
this.eventsThisMinute = this.events.filter(event =>
|
|
913
|
-
new Date(event.timestamp) > oneMinuteAgo
|
|
914
|
-
).length;
|
|
915
|
-
|
|
916
|
-
// Update UI
|
|
917
|
-
this.updateMetricsUI();
|
|
918
|
-
}
|
|
919
|
-
|
|
920
|
-
/**
|
|
921
|
-
* Update metrics in the UI
|
|
922
|
-
*/
|
|
923
|
-
updateMetricsUI() {
|
|
924
|
-
const totalEventsEl = document.getElementById('total-events');
|
|
925
|
-
const eventsPerMinuteEl = document.getElementById('events-per-minute');
|
|
926
|
-
const uniqueTypesEl = document.getElementById('unique-types');
|
|
927
|
-
const errorCountEl = document.getElementById('error-count');
|
|
928
|
-
|
|
929
|
-
if (totalEventsEl) totalEventsEl.textContent = this.events.length;
|
|
930
|
-
if (eventsPerMinuteEl) eventsPerMinuteEl.textContent = this.eventsThisMinute;
|
|
931
|
-
if (uniqueTypesEl) uniqueTypesEl.textContent = Object.keys(this.eventTypeCount).length;
|
|
932
|
-
if (errorCountEl) errorCountEl.textContent = this.errorCount;
|
|
933
|
-
}
|
|
934
|
-
|
|
935
|
-
/**
|
|
936
|
-
* Export events to JSON
|
|
937
|
-
*/
|
|
938
|
-
exportEvents() {
|
|
939
|
-
const dataStr = JSON.stringify(this.filteredEvents, null, 2);
|
|
940
|
-
const dataBlob = new Blob([dataStr], { type: 'application/json' });
|
|
941
|
-
const url = URL.createObjectURL(dataBlob);
|
|
942
|
-
|
|
943
|
-
const link = document.createElement('a');
|
|
944
|
-
link.href = url;
|
|
945
|
-
link.download = `claude-mpm-events-${new Date().toISOString().split('T')[0]}.json`;
|
|
946
|
-
link.click();
|
|
947
|
-
|
|
948
|
-
URL.revokeObjectURL(url);
|
|
949
|
-
}
|
|
950
|
-
|
|
951
|
-
/**
|
|
952
|
-
* Clear all events
|
|
953
|
-
*/
|
|
954
|
-
clearEvents() {
|
|
955
|
-
this.socketClient.clearEvents();
|
|
956
|
-
this.selectedEventIndex = -1;
|
|
957
|
-
this.updateDisplay();
|
|
958
|
-
}
|
|
959
|
-
|
|
960
|
-
/**
|
|
961
|
-
* Set session filter
|
|
962
|
-
* @param {string} sessionId - Session ID to filter by
|
|
963
|
-
*/
|
|
964
|
-
setSessionFilter(sessionId) {
|
|
965
|
-
this.sessionFilter = sessionId;
|
|
966
|
-
this.applyFilters();
|
|
967
|
-
}
|
|
968
|
-
|
|
969
|
-
/**
|
|
970
|
-
* Get current filter state
|
|
971
|
-
* @returns {Object} Current filters
|
|
972
|
-
*/
|
|
973
|
-
getFilters() {
|
|
974
|
-
return {
|
|
975
|
-
search: this.searchFilter,
|
|
976
|
-
type: this.typeFilter,
|
|
977
|
-
session: this.sessionFilter
|
|
978
|
-
};
|
|
979
|
-
}
|
|
980
|
-
|
|
981
|
-
/**
|
|
982
|
-
* Get filtered events (used by HUD and other components)
|
|
983
|
-
* @returns {Array} Array of filtered events
|
|
984
|
-
*/
|
|
985
|
-
getFilteredEvents() {
|
|
986
|
-
return this.filteredEvents;
|
|
987
|
-
}
|
|
988
|
-
|
|
989
|
-
/**
|
|
990
|
-
* Get all events (unfiltered, used by HUD for complete visualization)
|
|
991
|
-
* @returns {Array} Array of all events
|
|
992
|
-
*/
|
|
993
|
-
getAllEvents() {
|
|
994
|
-
return this.events;
|
|
995
|
-
}
|
|
996
|
-
|
|
997
|
-
/**
|
|
998
|
-
* Create inline diff viewer for Edit/MultiEdit tool events
|
|
999
|
-
* WHY: Provides immediate visibility of file changes without needing to open modals
|
|
1000
|
-
* DESIGN DECISION: Shows inline diffs only for Edit/MultiEdit events to avoid clutter
|
|
1001
|
-
* @param {Object} event - Event object
|
|
1002
|
-
* @param {number} index - Event index for unique IDs
|
|
1003
|
-
* @returns {string} HTML for inline diff viewer
|
|
1004
|
-
*/
|
|
1005
|
-
createInlineEditDiffViewer(event, index) {
|
|
1006
|
-
const data = event.data || {};
|
|
1007
|
-
const toolName = event.tool_name || data.tool_name || '';
|
|
1008
|
-
|
|
1009
|
-
// Only show for Edit and MultiEdit tools
|
|
1010
|
-
if (!['Edit', 'MultiEdit'].includes(toolName)) {
|
|
1011
|
-
return '';
|
|
1012
|
-
}
|
|
1013
|
-
|
|
1014
|
-
// Extract edit parameters based on tool type
|
|
1015
|
-
let edits = [];
|
|
1016
|
-
if (toolName === 'Edit') {
|
|
1017
|
-
// Single edit
|
|
1018
|
-
const parameters = event.tool_parameters || data.tool_parameters || {};
|
|
1019
|
-
if (parameters.old_string && parameters.new_string) {
|
|
1020
|
-
edits.push({
|
|
1021
|
-
old_string: parameters.old_string,
|
|
1022
|
-
new_string: parameters.new_string,
|
|
1023
|
-
file_path: parameters.file_path || 'unknown'
|
|
1024
|
-
});
|
|
1025
|
-
}
|
|
1026
|
-
} else if (toolName === 'MultiEdit') {
|
|
1027
|
-
// Multiple edits
|
|
1028
|
-
const parameters = event.tool_parameters || data.tool_parameters || {};
|
|
1029
|
-
if (parameters.edits && Array.isArray(parameters.edits)) {
|
|
1030
|
-
edits = parameters.edits.map(edit => ({
|
|
1031
|
-
...edit,
|
|
1032
|
-
file_path: parameters.file_path || 'unknown'
|
|
1033
|
-
}));
|
|
1034
|
-
}
|
|
1035
|
-
}
|
|
1036
|
-
|
|
1037
|
-
if (edits.length === 0) {
|
|
1038
|
-
return '';
|
|
1039
|
-
}
|
|
1040
|
-
|
|
1041
|
-
// Create collapsible diff section
|
|
1042
|
-
const diffId = `edit-diff-${index}`;
|
|
1043
|
-
const isMultiEdit = edits.length > 1;
|
|
1044
|
-
|
|
1045
|
-
let diffContent = '';
|
|
1046
|
-
edits.forEach((edit, editIndex) => {
|
|
1047
|
-
const editId = `${diffId}-${editIndex}`;
|
|
1048
|
-
const diffHtml = this.createDiffHtml(edit.old_string, edit.new_string);
|
|
1049
|
-
|
|
1050
|
-
diffContent += `
|
|
1051
|
-
<div class="edit-diff-section">
|
|
1052
|
-
${isMultiEdit ? `<div class="edit-diff-header">Edit ${editIndex + 1}</div>` : ''}
|
|
1053
|
-
<div class="diff-content">${diffHtml}</div>
|
|
1054
|
-
</div>
|
|
1055
|
-
`;
|
|
1056
|
-
});
|
|
1057
|
-
|
|
1058
|
-
return `
|
|
1059
|
-
<div class="inline-edit-diff-viewer">
|
|
1060
|
-
<div class="diff-toggle-header" onclick="eventViewer.toggleEditDiff('${diffId}', event)">
|
|
1061
|
-
<span class="diff-toggle-icon">📋</span>
|
|
1062
|
-
<span class="diff-toggle-text">Show ${isMultiEdit ? edits.length + ' edits' : 'edit'}</span>
|
|
1063
|
-
<span class="diff-toggle-arrow">▼</span>
|
|
1064
|
-
</div>
|
|
1065
|
-
<div id="${diffId}" class="diff-content-container" style="display: none;">
|
|
1066
|
-
${diffContent}
|
|
1067
|
-
</div>
|
|
1068
|
-
</div>
|
|
1069
|
-
`;
|
|
1070
|
-
}
|
|
1071
|
-
|
|
1072
|
-
/**
|
|
1073
|
-
* Create HTML diff visualization
|
|
1074
|
-
* WHY: Provides clear visual representation of text changes similar to git diff
|
|
1075
|
-
* @param {string} oldText - Original text
|
|
1076
|
-
* @param {string} newText - Modified text
|
|
1077
|
-
* @returns {string} HTML diff content
|
|
1078
|
-
*/
|
|
1079
|
-
createDiffHtml(oldText, newText) {
|
|
1080
|
-
// Simple line-by-line diff implementation
|
|
1081
|
-
const oldLines = oldText.split('\n');
|
|
1082
|
-
const newLines = newText.split('\n');
|
|
1083
|
-
|
|
1084
|
-
let diffHtml = '';
|
|
1085
|
-
let i = 0, j = 0;
|
|
1086
|
-
|
|
1087
|
-
// Simple diff algorithm - can be enhanced with proper diff library if needed
|
|
1088
|
-
while (i < oldLines.length || j < newLines.length) {
|
|
1089
|
-
const oldLine = i < oldLines.length ? oldLines[i] : null;
|
|
1090
|
-
const newLine = j < newLines.length ? newLines[j] : null;
|
|
1091
|
-
|
|
1092
|
-
if (oldLine === null) {
|
|
1093
|
-
// New line added
|
|
1094
|
-
diffHtml += `<div class="diff-line diff-added">+ ${this.escapeHtml(newLine)}</div>`;
|
|
1095
|
-
j++;
|
|
1096
|
-
} else if (newLine === null) {
|
|
1097
|
-
// Old line removed
|
|
1098
|
-
diffHtml += `<div class="diff-line diff-removed">- ${this.escapeHtml(oldLine)}</div>`;
|
|
1099
|
-
i++;
|
|
1100
|
-
} else if (oldLine === newLine) {
|
|
1101
|
-
// Lines are the same
|
|
1102
|
-
diffHtml += `<div class="diff-line diff-unchanged"> ${this.escapeHtml(oldLine)}</div>`;
|
|
1103
|
-
i++;
|
|
1104
|
-
j++;
|
|
1105
|
-
} else {
|
|
1106
|
-
// Lines are different - show both
|
|
1107
|
-
diffHtml += `<div class="diff-line diff-removed">- ${this.escapeHtml(oldLine)}</div>`;
|
|
1108
|
-
diffHtml += `<div class="diff-line diff-added">+ ${this.escapeHtml(newLine)}</div>`;
|
|
1109
|
-
i++;
|
|
1110
|
-
j++;
|
|
1111
|
-
}
|
|
1112
|
-
}
|
|
1113
|
-
|
|
1114
|
-
return `<div class="diff-container">${diffHtml}</div>`;
|
|
1115
|
-
}
|
|
1116
|
-
|
|
1117
|
-
/**
|
|
1118
|
-
* Toggle edit diff visibility
|
|
1119
|
-
* @param {string} diffId - Diff container ID
|
|
1120
|
-
* @param {Event} event - Click event
|
|
1121
|
-
*/
|
|
1122
|
-
toggleEditDiff(diffId, event) {
|
|
1123
|
-
// Prevent event bubbling to parent event item
|
|
1124
|
-
event.stopPropagation();
|
|
1125
|
-
|
|
1126
|
-
const diffContainer = document.getElementById(diffId);
|
|
1127
|
-
const arrow = event.currentTarget.querySelector('.diff-toggle-arrow');
|
|
1128
|
-
|
|
1129
|
-
if (diffContainer) {
|
|
1130
|
-
const isVisible = diffContainer.style.display !== 'none';
|
|
1131
|
-
diffContainer.style.display = isVisible ? 'none' : 'block';
|
|
1132
|
-
if (arrow) {
|
|
1133
|
-
arrow.textContent = isVisible ? '▼' : '▲';
|
|
1134
|
-
}
|
|
1135
|
-
}
|
|
1136
|
-
}
|
|
1137
|
-
|
|
1138
|
-
/**
|
|
1139
|
-
* Escape HTML characters for safe display
|
|
1140
|
-
* @param {string} text - Text to escape
|
|
1141
|
-
* @returns {string} Escaped text
|
|
1142
|
-
*/
|
|
1143
|
-
escapeHtml(text) {
|
|
1144
|
-
const div = document.createElement('div');
|
|
1145
|
-
div.textContent = text;
|
|
1146
|
-
return div.innerHTML;
|
|
1147
|
-
}
|
|
1148
|
-
}
|
|
1149
|
-
|
|
1150
|
-
// ES6 Module export
|
|
1151
|
-
export { EventViewer };
|
|
1152
|
-
export default EventViewer;
|
|
1153
|
-
|
|
1154
|
-
// Backward compatibility - keep window export for non-module usage
|
|
1155
|
-
window.EventViewer = EventViewer;
|