claude-mpm 3.9.9__py3-none-any.whl → 4.0.3__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/__init__.py +2 -2
- claude_mpm/__main__.py +3 -2
- claude_mpm/agents/__init__.py +85 -79
- claude_mpm/agents/agent_loader.py +464 -1003
- claude_mpm/agents/agent_loader_integration.py +45 -45
- claude_mpm/agents/agents_metadata.py +29 -30
- claude_mpm/agents/async_agent_loader.py +156 -138
- claude_mpm/agents/base_agent.json +1 -1
- claude_mpm/agents/base_agent_loader.py +179 -151
- claude_mpm/agents/frontmatter_validator.py +229 -130
- claude_mpm/agents/schema/agent_schema.json +1 -1
- claude_mpm/agents/system_agent_config.py +213 -147
- claude_mpm/agents/templates/__init__.py +13 -13
- claude_mpm/agents/templates/code_analyzer.json +2 -2
- claude_mpm/agents/templates/data_engineer.json +1 -1
- claude_mpm/agents/templates/documentation.json +23 -11
- claude_mpm/agents/templates/engineer.json +22 -6
- claude_mpm/agents/templates/memory_manager.json +155 -0
- claude_mpm/agents/templates/ops.json +2 -2
- claude_mpm/agents/templates/project_organizer.json +1 -1
- claude_mpm/agents/templates/qa.json +1 -1
- claude_mpm/agents/templates/refactoring_engineer.json +222 -0
- claude_mpm/agents/templates/research.json +20 -14
- claude_mpm/agents/templates/security.json +1 -1
- claude_mpm/agents/templates/ticketing.json +1 -1
- claude_mpm/agents/templates/version_control.json +1 -1
- claude_mpm/agents/templates/web_qa.json +3 -1
- claude_mpm/agents/templates/web_ui.json +2 -2
- claude_mpm/cli/__init__.py +90 -49
- claude_mpm/cli/__main__.py +3 -2
- claude_mpm/cli/commands/__init__.py +21 -18
- claude_mpm/cli/commands/agents.py +279 -247
- claude_mpm/cli/commands/aggregate.py +138 -157
- claude_mpm/cli/commands/cleanup.py +147 -147
- claude_mpm/cli/commands/config.py +93 -76
- claude_mpm/cli/commands/info.py +17 -16
- claude_mpm/cli/commands/mcp.py +143 -762
- claude_mpm/cli/commands/mcp_command_router.py +139 -0
- claude_mpm/cli/commands/mcp_config_commands.py +20 -0
- claude_mpm/cli/commands/mcp_install_commands.py +20 -0
- claude_mpm/cli/commands/mcp_server_commands.py +175 -0
- claude_mpm/cli/commands/mcp_tool_commands.py +34 -0
- claude_mpm/cli/commands/memory.py +239 -203
- claude_mpm/cli/commands/monitor.py +203 -81
- claude_mpm/cli/commands/run.py +380 -429
- claude_mpm/cli/commands/run_config_checker.py +160 -0
- claude_mpm/cli/commands/socketio_monitor.py +235 -0
- claude_mpm/cli/commands/tickets.py +305 -197
- claude_mpm/cli/parser.py +24 -1150
- claude_mpm/cli/parsers/__init__.py +29 -0
- claude_mpm/cli/parsers/agents_parser.py +136 -0
- claude_mpm/cli/parsers/base_parser.py +331 -0
- claude_mpm/cli/parsers/config_parser.py +85 -0
- claude_mpm/cli/parsers/mcp_parser.py +152 -0
- claude_mpm/cli/parsers/memory_parser.py +138 -0
- claude_mpm/cli/parsers/monitor_parser.py +104 -0
- claude_mpm/cli/parsers/run_parser.py +147 -0
- claude_mpm/cli/parsers/tickets_parser.py +203 -0
- claude_mpm/cli/ticket_cli.py +7 -3
- claude_mpm/cli/utils.py +55 -37
- claude_mpm/cli_module/__init__.py +6 -6
- claude_mpm/cli_module/args.py +188 -140
- claude_mpm/cli_module/commands.py +79 -70
- claude_mpm/cli_module/migration_example.py +38 -60
- claude_mpm/config/__init__.py +32 -25
- claude_mpm/config/agent_config.py +151 -119
- claude_mpm/config/experimental_features.py +217 -0
- claude_mpm/config/paths.py +94 -208
- claude_mpm/config/socketio_config.py +84 -73
- claude_mpm/constants.py +36 -18
- claude_mpm/core/__init__.py +9 -6
- claude_mpm/core/agent_name_normalizer.py +68 -71
- claude_mpm/core/agent_registry.py +372 -521
- claude_mpm/core/agent_session_manager.py +74 -63
- claude_mpm/core/base_service.py +116 -87
- claude_mpm/core/cache.py +119 -153
- claude_mpm/core/claude_runner.py +425 -1120
- claude_mpm/core/config.py +263 -168
- claude_mpm/core/config_aliases.py +69 -61
- claude_mpm/core/config_constants.py +292 -0
- claude_mpm/core/constants.py +57 -99
- claude_mpm/core/container.py +211 -178
- claude_mpm/core/exceptions.py +233 -89
- claude_mpm/core/factories.py +92 -54
- claude_mpm/core/framework_loader.py +378 -220
- claude_mpm/core/hook_manager.py +198 -83
- claude_mpm/core/hook_performance_config.py +136 -0
- claude_mpm/core/injectable_service.py +61 -55
- claude_mpm/core/interactive_session.py +165 -155
- claude_mpm/core/interfaces.py +221 -195
- claude_mpm/core/lazy.py +96 -96
- claude_mpm/core/logger.py +133 -107
- claude_mpm/core/logging_config.py +185 -157
- claude_mpm/core/minimal_framework_loader.py +20 -15
- claude_mpm/core/mixins.py +30 -29
- claude_mpm/core/oneshot_session.py +215 -181
- claude_mpm/core/optimized_agent_loader.py +134 -138
- claude_mpm/core/optimized_startup.py +159 -157
- claude_mpm/core/pm_hook_interceptor.py +85 -72
- claude_mpm/core/service_registry.py +103 -101
- claude_mpm/core/session_manager.py +97 -87
- claude_mpm/core/socketio_pool.py +212 -158
- claude_mpm/core/tool_access_control.py +58 -51
- claude_mpm/core/types.py +46 -24
- claude_mpm/core/typing_utils.py +166 -82
- claude_mpm/core/unified_agent_registry.py +721 -0
- claude_mpm/core/unified_config.py +550 -0
- claude_mpm/core/unified_paths.py +549 -0
- claude_mpm/dashboard/index.html +1 -1
- claude_mpm/dashboard/open_dashboard.py +51 -17
- claude_mpm/dashboard/static/css/dashboard.css +27 -8
- claude_mpm/dashboard/static/dist/components/agent-inference.js +2 -0
- claude_mpm/dashboard/static/dist/components/event-processor.js +2 -0
- claude_mpm/dashboard/static/dist/components/event-viewer.js +2 -0
- claude_mpm/dashboard/static/dist/components/export-manager.js +2 -0
- claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +2 -0
- claude_mpm/dashboard/static/dist/components/hud-library-loader.js +2 -0
- claude_mpm/dashboard/static/dist/components/hud-manager.js +2 -0
- claude_mpm/dashboard/static/dist/components/hud-visualizer.js +2 -0
- claude_mpm/dashboard/static/dist/components/module-viewer.js +2 -0
- claude_mpm/dashboard/static/dist/components/session-manager.js +2 -0
- claude_mpm/dashboard/static/dist/components/socket-manager.js +2 -0
- claude_mpm/dashboard/static/dist/components/ui-state-manager.js +2 -0
- claude_mpm/dashboard/static/dist/components/working-directory.js +2 -0
- claude_mpm/dashboard/static/dist/dashboard.js +2 -0
- claude_mpm/dashboard/static/dist/socket-client.js +2 -0
- claude_mpm/dashboard/static/js/components/agent-inference.js +80 -76
- claude_mpm/dashboard/static/js/components/event-processor.js +71 -67
- claude_mpm/dashboard/static/js/components/event-viewer.js +74 -70
- claude_mpm/dashboard/static/js/components/export-manager.js +31 -28
- claude_mpm/dashboard/static/js/components/file-tool-tracker.js +106 -92
- claude_mpm/dashboard/static/js/components/hud-library-loader.js +11 -11
- claude_mpm/dashboard/static/js/components/hud-manager.js +73 -73
- claude_mpm/dashboard/static/js/components/hud-visualizer.js +163 -163
- claude_mpm/dashboard/static/js/components/module-viewer.js +305 -233
- claude_mpm/dashboard/static/js/components/session-manager.js +32 -29
- claude_mpm/dashboard/static/js/components/socket-manager.js +27 -20
- claude_mpm/dashboard/static/js/components/ui-state-manager.js +21 -18
- claude_mpm/dashboard/static/js/components/working-directory.js +74 -71
- claude_mpm/dashboard/static/js/dashboard.js +178 -453
- claude_mpm/dashboard/static/js/extension-error-handler.js +164 -0
- claude_mpm/dashboard/static/js/socket-client.js +120 -54
- claude_mpm/dashboard/templates/index.html +40 -50
- claude_mpm/experimental/cli_enhancements.py +60 -58
- claude_mpm/generators/__init__.py +1 -1
- claude_mpm/generators/agent_profile_generator.py +75 -65
- claude_mpm/hooks/__init__.py +1 -1
- claude_mpm/hooks/base_hook.py +33 -28
- claude_mpm/hooks/claude_hooks/__init__.py +1 -1
- claude_mpm/hooks/claude_hooks/connection_pool.py +120 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +743 -0
- claude_mpm/hooks/claude_hooks/hook_handler.py +415 -1331
- claude_mpm/hooks/claude_hooks/hook_wrapper.sh +4 -4
- claude_mpm/hooks/claude_hooks/memory_integration.py +221 -0
- claude_mpm/hooks/claude_hooks/response_tracking.py +348 -0
- claude_mpm/hooks/claude_hooks/tool_analysis.py +230 -0
- claude_mpm/hooks/memory_integration_hook.py +140 -100
- claude_mpm/hooks/tool_call_interceptor.py +89 -76
- claude_mpm/hooks/validation_hooks.py +57 -49
- claude_mpm/init.py +145 -121
- claude_mpm/models/__init__.py +9 -9
- claude_mpm/models/agent_definition.py +33 -23
- claude_mpm/models/agent_session.py +228 -200
- claude_mpm/scripts/__init__.py +1 -1
- claude_mpm/scripts/socketio_daemon.py +192 -75
- claude_mpm/scripts/socketio_server_manager.py +328 -0
- claude_mpm/scripts/start_activity_logging.py +25 -22
- claude_mpm/services/__init__.py +68 -43
- claude_mpm/services/agent_capabilities_service.py +271 -0
- claude_mpm/services/agents/__init__.py +23 -32
- claude_mpm/services/agents/deployment/__init__.py +3 -3
- claude_mpm/services/agents/deployment/agent_config_provider.py +310 -0
- claude_mpm/services/agents/deployment/agent_configuration_manager.py +359 -0
- claude_mpm/services/agents/deployment/agent_definition_factory.py +84 -0
- claude_mpm/services/agents/deployment/agent_deployment.py +415 -2113
- claude_mpm/services/agents/deployment/agent_discovery_service.py +387 -0
- claude_mpm/services/agents/deployment/agent_environment_manager.py +293 -0
- claude_mpm/services/agents/deployment/agent_filesystem_manager.py +387 -0
- claude_mpm/services/agents/deployment/agent_format_converter.py +453 -0
- claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +161 -0
- claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +345 -495
- claude_mpm/services/agents/deployment/agent_metrics_collector.py +279 -0
- claude_mpm/services/agents/deployment/agent_restore_handler.py +88 -0
- claude_mpm/services/agents/deployment/agent_template_builder.py +406 -0
- claude_mpm/services/agents/deployment/agent_validator.py +352 -0
- claude_mpm/services/agents/deployment/agent_version_manager.py +313 -0
- claude_mpm/services/agents/deployment/agent_versioning.py +6 -9
- claude_mpm/services/agents/deployment/agents_directory_resolver.py +79 -0
- claude_mpm/services/agents/deployment/async_agent_deployment.py +298 -234
- claude_mpm/services/agents/deployment/config/__init__.py +13 -0
- claude_mpm/services/agents/deployment/config/deployment_config.py +182 -0
- claude_mpm/services/agents/deployment/config/deployment_config_manager.py +200 -0
- claude_mpm/services/agents/deployment/deployment_config_loader.py +54 -0
- claude_mpm/services/agents/deployment/deployment_type_detector.py +124 -0
- claude_mpm/services/agents/deployment/facade/__init__.py +18 -0
- claude_mpm/services/agents/deployment/facade/async_deployment_executor.py +159 -0
- claude_mpm/services/agents/deployment/facade/deployment_executor.py +73 -0
- claude_mpm/services/agents/deployment/facade/deployment_facade.py +270 -0
- claude_mpm/services/agents/deployment/facade/sync_deployment_executor.py +178 -0
- claude_mpm/services/agents/deployment/interface_adapter.py +227 -0
- claude_mpm/services/agents/deployment/lifecycle_health_checker.py +85 -0
- claude_mpm/services/agents/deployment/lifecycle_performance_tracker.py +100 -0
- claude_mpm/services/agents/deployment/pipeline/__init__.py +32 -0
- claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +158 -0
- claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +159 -0
- claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +169 -0
- claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +19 -0
- claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +195 -0
- claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +119 -0
- claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +79 -0
- claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +90 -0
- claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +100 -0
- claude_mpm/services/agents/deployment/processors/__init__.py +15 -0
- claude_mpm/services/agents/deployment/processors/agent_deployment_context.py +98 -0
- claude_mpm/services/agents/deployment/processors/agent_deployment_result.py +235 -0
- claude_mpm/services/agents/deployment/processors/agent_processor.py +258 -0
- claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +318 -0
- claude_mpm/services/agents/deployment/results/__init__.py +13 -0
- claude_mpm/services/agents/deployment/results/deployment_metrics.py +200 -0
- claude_mpm/services/agents/deployment/results/deployment_result_builder.py +249 -0
- claude_mpm/services/agents/deployment/strategies/__init__.py +25 -0
- claude_mpm/services/agents/deployment/strategies/base_strategy.py +119 -0
- claude_mpm/services/agents/deployment/strategies/project_strategy.py +150 -0
- claude_mpm/services/agents/deployment/strategies/strategy_selector.py +117 -0
- claude_mpm/services/agents/deployment/strategies/system_strategy.py +116 -0
- claude_mpm/services/agents/deployment/strategies/user_strategy.py +137 -0
- claude_mpm/services/agents/deployment/system_instructions_deployer.py +108 -0
- claude_mpm/services/agents/deployment/validation/__init__.py +19 -0
- claude_mpm/services/agents/deployment/validation/agent_validator.py +323 -0
- claude_mpm/services/agents/deployment/validation/deployment_validator.py +238 -0
- claude_mpm/services/agents/deployment/validation/template_validator.py +299 -0
- claude_mpm/services/agents/deployment/validation/validation_result.py +226 -0
- claude_mpm/services/agents/loading/__init__.py +2 -2
- claude_mpm/services/agents/loading/agent_profile_loader.py +259 -229
- claude_mpm/services/agents/loading/base_agent_manager.py +90 -81
- claude_mpm/services/agents/loading/framework_agent_loader.py +154 -129
- claude_mpm/services/agents/management/__init__.py +2 -2
- claude_mpm/services/agents/management/agent_capabilities_generator.py +72 -58
- claude_mpm/services/agents/management/agent_management_service.py +209 -156
- claude_mpm/services/agents/memory/__init__.py +9 -6
- claude_mpm/services/agents/memory/agent_memory_manager.py +218 -1152
- claude_mpm/services/agents/memory/agent_persistence_service.py +20 -16
- claude_mpm/services/agents/memory/analyzer.py +430 -0
- claude_mpm/services/agents/memory/content_manager.py +376 -0
- claude_mpm/services/agents/memory/template_generator.py +468 -0
- claude_mpm/services/agents/registry/__init__.py +7 -10
- claude_mpm/services/agents/registry/deployed_agent_discovery.py +122 -97
- claude_mpm/services/agents/registry/modification_tracker.py +351 -285
- claude_mpm/services/async_session_logger.py +187 -153
- claude_mpm/services/claude_session_logger.py +87 -72
- claude_mpm/services/command_handler_service.py +217 -0
- claude_mpm/services/communication/__init__.py +3 -2
- claude_mpm/services/core/__init__.py +50 -97
- claude_mpm/services/core/base.py +60 -53
- claude_mpm/services/core/interfaces/__init__.py +188 -0
- claude_mpm/services/core/interfaces/agent.py +351 -0
- claude_mpm/services/core/interfaces/communication.py +343 -0
- claude_mpm/services/core/interfaces/infrastructure.py +413 -0
- claude_mpm/services/core/interfaces/service.py +434 -0
- claude_mpm/services/core/interfaces.py +19 -944
- claude_mpm/services/event_aggregator.py +208 -170
- claude_mpm/services/exceptions.py +387 -308
- claude_mpm/services/framework_claude_md_generator/__init__.py +75 -79
- claude_mpm/services/framework_claude_md_generator/content_assembler.py +69 -60
- claude_mpm/services/framework_claude_md_generator/content_validator.py +65 -61
- claude_mpm/services/framework_claude_md_generator/deployment_manager.py +68 -49
- claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +34 -34
- claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +25 -22
- claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +10 -10
- claude_mpm/services/framework_claude_md_generator/section_generators/core_responsibilities.py +4 -3
- claude_mpm/services/framework_claude_md_generator/section_generators/delegation_constraints.py +4 -3
- claude_mpm/services/framework_claude_md_generator/section_generators/environment_config.py +4 -3
- claude_mpm/services/framework_claude_md_generator/section_generators/footer.py +6 -5
- claude_mpm/services/framework_claude_md_generator/section_generators/header.py +8 -7
- claude_mpm/services/framework_claude_md_generator/section_generators/orchestration_principles.py +4 -3
- claude_mpm/services/framework_claude_md_generator/section_generators/role_designation.py +6 -5
- claude_mpm/services/framework_claude_md_generator/section_generators/subprocess_validation.py +9 -8
- claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +4 -3
- claude_mpm/services/framework_claude_md_generator/section_generators/troubleshooting.py +5 -4
- claude_mpm/services/framework_claude_md_generator/section_manager.py +28 -27
- claude_mpm/services/framework_claude_md_generator/version_manager.py +30 -28
- claude_mpm/services/hook_service.py +106 -114
- claude_mpm/services/infrastructure/__init__.py +7 -5
- claude_mpm/services/infrastructure/context_preservation.py +571 -0
- claude_mpm/services/infrastructure/daemon_manager.py +279 -0
- claude_mpm/services/infrastructure/logging.py +83 -76
- claude_mpm/services/infrastructure/monitoring.py +547 -404
- claude_mpm/services/mcp_gateway/__init__.py +40 -23
- claude_mpm/services/mcp_gateway/config/__init__.py +2 -2
- claude_mpm/services/mcp_gateway/config/config_loader.py +61 -56
- claude_mpm/services/mcp_gateway/config/config_schema.py +50 -41
- claude_mpm/services/mcp_gateway/config/configuration.py +82 -75
- claude_mpm/services/mcp_gateway/core/__init__.py +14 -21
- claude_mpm/services/mcp_gateway/core/base.py +80 -67
- claude_mpm/services/mcp_gateway/core/exceptions.py +60 -46
- claude_mpm/services/mcp_gateway/core/interfaces.py +97 -93
- claude_mpm/services/mcp_gateway/main.py +307 -127
- claude_mpm/services/mcp_gateway/registry/__init__.py +1 -1
- claude_mpm/services/mcp_gateway/registry/service_registry.py +100 -101
- claude_mpm/services/mcp_gateway/registry/tool_registry.py +135 -126
- claude_mpm/services/mcp_gateway/server/__init__.py +4 -4
- claude_mpm/services/mcp_gateway/server/{mcp_server.py → mcp_gateway.py} +149 -153
- claude_mpm/services/mcp_gateway/server/stdio_handler.py +105 -107
- claude_mpm/services/mcp_gateway/server/stdio_server.py +691 -0
- claude_mpm/services/mcp_gateway/tools/__init__.py +4 -2
- claude_mpm/services/mcp_gateway/tools/base_adapter.py +110 -121
- claude_mpm/services/mcp_gateway/tools/document_summarizer.py +283 -215
- claude_mpm/services/mcp_gateway/tools/hello_world.py +122 -120
- claude_mpm/services/mcp_gateway/tools/ticket_tools.py +652 -0
- claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +606 -0
- claude_mpm/services/memory/__init__.py +2 -2
- claude_mpm/services/memory/builder.py +451 -362
- claude_mpm/services/memory/cache/__init__.py +2 -2
- claude_mpm/services/memory/cache/shared_prompt_cache.py +232 -194
- claude_mpm/services/memory/cache/simple_cache.py +107 -93
- claude_mpm/services/memory/indexed_memory.py +195 -193
- claude_mpm/services/memory/optimizer.py +267 -234
- claude_mpm/services/memory/router.py +571 -263
- claude_mpm/services/memory_hook_service.py +237 -0
- claude_mpm/services/port_manager.py +223 -0
- claude_mpm/services/project/__init__.py +3 -3
- claude_mpm/services/project/analyzer.py +451 -305
- claude_mpm/services/project/registry.py +262 -240
- claude_mpm/services/recovery_manager.py +287 -231
- claude_mpm/services/response_tracker.py +87 -67
- claude_mpm/services/runner_configuration_service.py +587 -0
- claude_mpm/services/session_management_service.py +304 -0
- claude_mpm/services/socketio/__init__.py +4 -4
- claude_mpm/services/socketio/client_proxy.py +174 -0
- claude_mpm/services/socketio/handlers/__init__.py +3 -3
- claude_mpm/services/socketio/handlers/base.py +44 -30
- claude_mpm/services/socketio/handlers/connection.py +145 -65
- claude_mpm/services/socketio/handlers/file.py +123 -108
- claude_mpm/services/socketio/handlers/git.py +607 -373
- claude_mpm/services/socketio/handlers/hook.py +170 -0
- claude_mpm/services/socketio/handlers/memory.py +4 -4
- claude_mpm/services/socketio/handlers/project.py +4 -4
- claude_mpm/services/socketio/handlers/registry.py +53 -38
- claude_mpm/services/socketio/server/__init__.py +18 -0
- claude_mpm/services/socketio/server/broadcaster.py +252 -0
- claude_mpm/services/socketio/server/core.py +399 -0
- claude_mpm/services/socketio/server/main.py +323 -0
- claude_mpm/services/socketio_client_manager.py +160 -133
- claude_mpm/services/socketio_server.py +36 -1885
- claude_mpm/services/subprocess_launcher_service.py +316 -0
- claude_mpm/services/system_instructions_service.py +258 -0
- claude_mpm/services/ticket_manager.py +20 -534
- claude_mpm/services/utility_service.py +285 -0
- claude_mpm/services/version_control/__init__.py +18 -21
- claude_mpm/services/version_control/branch_strategy.py +20 -10
- claude_mpm/services/version_control/conflict_resolution.py +37 -13
- claude_mpm/services/version_control/git_operations.py +52 -21
- claude_mpm/services/version_control/semantic_versioning.py +92 -53
- claude_mpm/services/version_control/version_parser.py +145 -125
- claude_mpm/services/version_service.py +270 -0
- claude_mpm/storage/__init__.py +9 -0
- claude_mpm/storage/state_storage.py +552 -0
- claude_mpm/ticket_wrapper.py +2 -2
- claude_mpm/utils/__init__.py +2 -2
- claude_mpm/utils/agent_dependency_loader.py +453 -243
- claude_mpm/utils/config_manager.py +157 -118
- claude_mpm/utils/console.py +1 -1
- claude_mpm/utils/dependency_cache.py +102 -107
- claude_mpm/utils/dependency_manager.py +52 -47
- claude_mpm/utils/dependency_strategies.py +131 -96
- claude_mpm/utils/environment_context.py +110 -102
- claude_mpm/utils/error_handler.py +75 -55
- claude_mpm/utils/file_utils.py +80 -67
- claude_mpm/utils/framework_detection.py +12 -11
- claude_mpm/utils/import_migration_example.py +12 -60
- claude_mpm/utils/imports.py +48 -45
- claude_mpm/utils/path_operations.py +100 -93
- claude_mpm/utils/robust_installer.py +172 -164
- claude_mpm/utils/session_logging.py +30 -23
- claude_mpm/utils/subprocess_utils.py +99 -61
- claude_mpm/validation/__init__.py +1 -1
- claude_mpm/validation/agent_validator.py +151 -111
- claude_mpm/validation/frontmatter_validator.py +92 -71
- {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/METADATA +51 -2
- claude_mpm-4.0.3.dist-info/RECORD +402 -0
- {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/entry_points.txt +1 -0
- {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/licenses/LICENSE +1 -1
- claude_mpm/config/memory_guardian_config.py +0 -325
- claude_mpm/core/config_paths.py +0 -150
- claude_mpm/dashboard/static/js/dashboard-original.js +0 -4134
- claude_mpm/deployment_paths.py +0 -261
- claude_mpm/hooks/claude_hooks/hook_handler_fixed.py +0 -454
- claude_mpm/models/state_models.py +0 -433
- claude_mpm/services/agent/__init__.py +0 -24
- claude_mpm/services/agent/deployment.py +0 -2548
- claude_mpm/services/agent/management.py +0 -598
- claude_mpm/services/agent/registry.py +0 -813
- claude_mpm/services/agents/registry/agent_registry.py +0 -813
- claude_mpm/services/communication/socketio.py +0 -1935
- claude_mpm/services/communication/websocket.py +0 -479
- claude_mpm/services/framework_claude_md_generator.py +0 -624
- claude_mpm/services/health_monitor.py +0 -893
- claude_mpm/services/infrastructure/memory_guardian.py +0 -770
- claude_mpm/services/mcp_gateway/server/mcp_server_simple.py +0 -444
- claude_mpm/services/optimized_hook_service.py +0 -542
- claude_mpm/services/project_analyzer.py +0 -864
- claude_mpm/services/project_registry.py +0 -608
- claude_mpm/services/standalone_socketio_server.py +0 -1300
- claude_mpm/services/ticket_manager_di.py +0 -318
- claude_mpm/services/ticketing_service_original.py +0 -510
- claude_mpm/utils/paths.py +0 -395
- claude_mpm/utils/platform_memory.py +0 -524
- claude_mpm-3.9.9.dist-info/RECORD +0 -293
- {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/WHEEL +0 -0
- {claude_mpm-3.9.9.dist-info → claude_mpm-4.0.3.dist-info}/top_level.txt +0 -0
| @@ -0,0 +1,164 @@ | |
| 1 | 
            +
            /**
         | 
| 2 | 
            +
             * Browser Extension Error Handler
         | 
| 3 | 
            +
             * 
         | 
| 4 | 
            +
             * WHY: Browser extensions (like password managers, ad blockers, etc.) often inject
         | 
| 5 | 
            +
             * scripts that use Chrome's message passing API. When these extensions have bugs
         | 
| 6 | 
            +
             * or async handlers that don't properly respond, they generate console errors.
         | 
| 7 | 
            +
             * 
         | 
| 8 | 
            +
             * This module prevents those external errors from affecting our dashboard and
         | 
| 9 | 
            +
             * provides clean error handling for known browser extension issues.
         | 
| 10 | 
            +
             * 
         | 
| 11 | 
            +
             * DESIGN DECISION: Rather than trying to fix third-party extension bugs, we:
         | 
| 12 | 
            +
             * 1. Detect and suppress known harmless extension errors
         | 
| 13 | 
            +
             * 2. Log them separately for debugging if needed
         | 
| 14 | 
            +
             * 3. Ensure our dashboard remains functional regardless of extension conflicts
         | 
| 15 | 
            +
             */
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            class ExtensionErrorHandler {
         | 
| 18 | 
            +
                constructor() {
         | 
| 19 | 
            +
                    this.extensionErrors = [];
         | 
| 20 | 
            +
                    this.suppressedPatterns = [
         | 
| 21 | 
            +
                        // Chrome extension message passing error
         | 
| 22 | 
            +
                        /listener indicated an asynchronous response.*message channel closed/i,
         | 
| 23 | 
            +
                        // Other common extension errors
         | 
| 24 | 
            +
                        /Extension context invalidated/i,
         | 
| 25 | 
            +
                        /Unchecked runtime\.lastError/i,
         | 
| 26 | 
            +
                        /Cannot access contents of url.*Extension/i,
         | 
| 27 | 
            +
                        /Blocked a frame with origin.*from accessing a cross-origin frame/i
         | 
| 28 | 
            +
                    ];
         | 
| 29 | 
            +
                    
         | 
| 30 | 
            +
                    this.setupErrorHandling();
         | 
| 31 | 
            +
                }
         | 
| 32 | 
            +
                
         | 
| 33 | 
            +
                /**
         | 
| 34 | 
            +
                 * Set up global error handling to catch and suppress extension errors
         | 
| 35 | 
            +
                 */
         | 
| 36 | 
            +
                setupErrorHandling() {
         | 
| 37 | 
            +
                    // Store original console.error
         | 
| 38 | 
            +
                    const originalConsoleError = console.error;
         | 
| 39 | 
            +
                    
         | 
| 40 | 
            +
                    // Override console.error to filter extension errors
         | 
| 41 | 
            +
                    console.error = (...args) => {
         | 
| 42 | 
            +
                        const errorString = args.join(' ');
         | 
| 43 | 
            +
                        
         | 
| 44 | 
            +
                        // Check if this is a known extension error
         | 
| 45 | 
            +
                        if (this.isExtensionError(errorString)) {
         | 
| 46 | 
            +
                            // Log to our internal list for debugging
         | 
| 47 | 
            +
                            this.extensionErrors.push({
         | 
| 48 | 
            +
                                timestamp: new Date().toISOString(),
         | 
| 49 | 
            +
                                error: errorString,
         | 
| 50 | 
            +
                                suppressed: true
         | 
| 51 | 
            +
                            });
         | 
| 52 | 
            +
                            
         | 
| 53 | 
            +
                            // Optionally log with a prefix if debug mode is enabled
         | 
| 54 | 
            +
                            if (window.DEBUG_EXTENSION_ERRORS) {
         | 
| 55 | 
            +
                                originalConsoleError.call(console, '[SUPPRESSED EXTENSION ERROR]:', ...args);
         | 
| 56 | 
            +
                            }
         | 
| 57 | 
            +
                            
         | 
| 58 | 
            +
                            // Don't propagate the error
         | 
| 59 | 
            +
                            return;
         | 
| 60 | 
            +
                        }
         | 
| 61 | 
            +
                        
         | 
| 62 | 
            +
                        // Pass through non-extension errors
         | 
| 63 | 
            +
                        originalConsoleError.call(console, ...args);
         | 
| 64 | 
            +
                    };
         | 
| 65 | 
            +
                    
         | 
| 66 | 
            +
                    // Handle uncaught promise rejections that might come from extensions
         | 
| 67 | 
            +
                    window.addEventListener('unhandledrejection', (event) => {
         | 
| 68 | 
            +
                        const errorString = event.reason?.toString() || '';
         | 
| 69 | 
            +
                        
         | 
| 70 | 
            +
                        if (this.isExtensionError(errorString)) {
         | 
| 71 | 
            +
                            // Prevent the default error handling
         | 
| 72 | 
            +
                            event.preventDefault();
         | 
| 73 | 
            +
                            
         | 
| 74 | 
            +
                            this.extensionErrors.push({
         | 
| 75 | 
            +
                                timestamp: new Date().toISOString(),
         | 
| 76 | 
            +
                                error: errorString,
         | 
| 77 | 
            +
                                type: 'unhandled_rejection',
         | 
| 78 | 
            +
                                suppressed: true
         | 
| 79 | 
            +
                            });
         | 
| 80 | 
            +
                            
         | 
| 81 | 
            +
                            if (window.DEBUG_EXTENSION_ERRORS) {
         | 
| 82 | 
            +
                                console.warn('[SUPPRESSED EXTENSION REJECTION]:', event.reason);
         | 
| 83 | 
            +
                            }
         | 
| 84 | 
            +
                        }
         | 
| 85 | 
            +
                    });
         | 
| 86 | 
            +
                    
         | 
| 87 | 
            +
                    // Add a global message event listener with proper error handling
         | 
| 88 | 
            +
                    // This prevents our app from being affected by misbehaving extensions
         | 
| 89 | 
            +
                    window.addEventListener('message', (event) => {
         | 
| 90 | 
            +
                        // Only process messages from our own origin
         | 
| 91 | 
            +
                        if (event.origin !== window.location.origin) {
         | 
| 92 | 
            +
                            return;
         | 
| 93 | 
            +
                        }
         | 
| 94 | 
            +
                        
         | 
| 95 | 
            +
                        // Add timeout protection for any async operations
         | 
| 96 | 
            +
                        if (event.data && event.data.requiresResponse) {
         | 
| 97 | 
            +
                            const timeoutId = setTimeout(() => {
         | 
| 98 | 
            +
                                console.warn('Message handler timeout - no response sent');
         | 
| 99 | 
            +
                            }, 5000);
         | 
| 100 | 
            +
                            
         | 
| 101 | 
            +
                            // Clear timeout when response is sent
         | 
| 102 | 
            +
                            if (event.ports && event.ports[0]) {
         | 
| 103 | 
            +
                                const originalPostMessage = event.ports[0].postMessage;
         | 
| 104 | 
            +
                                event.ports[0].postMessage = function(...args) {
         | 
| 105 | 
            +
                                    clearTimeout(timeoutId);
         | 
| 106 | 
            +
                                    return originalPostMessage.apply(this, args);
         | 
| 107 | 
            +
                                };
         | 
| 108 | 
            +
                            }
         | 
| 109 | 
            +
                        }
         | 
| 110 | 
            +
                    });
         | 
| 111 | 
            +
                }
         | 
| 112 | 
            +
                
         | 
| 113 | 
            +
                /**
         | 
| 114 | 
            +
                 * Check if an error string matches known extension error patterns
         | 
| 115 | 
            +
                 * @param {string} errorString - The error message to check
         | 
| 116 | 
            +
                 * @returns {boolean} - True if this is a known extension error
         | 
| 117 | 
            +
                 */
         | 
| 118 | 
            +
                isExtensionError(errorString) {
         | 
| 119 | 
            +
                    return this.suppressedPatterns.some(pattern => pattern.test(errorString));
         | 
| 120 | 
            +
                }
         | 
| 121 | 
            +
                
         | 
| 122 | 
            +
                /**
         | 
| 123 | 
            +
                 * Get suppressed extension errors for debugging
         | 
| 124 | 
            +
                 * @returns {Array} - List of suppressed errors
         | 
| 125 | 
            +
                 */
         | 
| 126 | 
            +
                getSuppressedErrors() {
         | 
| 127 | 
            +
                    return this.extensionErrors;
         | 
| 128 | 
            +
                }
         | 
| 129 | 
            +
                
         | 
| 130 | 
            +
                /**
         | 
| 131 | 
            +
                 * Clear the suppressed errors list
         | 
| 132 | 
            +
                 */
         | 
| 133 | 
            +
                clearSuppressedErrors() {
         | 
| 134 | 
            +
                    this.extensionErrors = [];
         | 
| 135 | 
            +
                }
         | 
| 136 | 
            +
                
         | 
| 137 | 
            +
                /**
         | 
| 138 | 
            +
                 * Enable or disable debug logging of extension errors
         | 
| 139 | 
            +
                 * @param {boolean} enabled - Whether to enable debug logging
         | 
| 140 | 
            +
                 */
         | 
| 141 | 
            +
                setDebugMode(enabled) {
         | 
| 142 | 
            +
                    window.DEBUG_EXTENSION_ERRORS = enabled;
         | 
| 143 | 
            +
                    
         | 
| 144 | 
            +
                    if (enabled) {
         | 
| 145 | 
            +
                        console.log('Extension error debug mode enabled. Suppressed errors will be logged with [SUPPRESSED] prefix.');
         | 
| 146 | 
            +
                        console.log('Current suppressed errors:', this.getSuppressedErrors());
         | 
| 147 | 
            +
                    } else {
         | 
| 148 | 
            +
                        console.log('Extension error debug mode disabled. Extension errors will be silently suppressed.');
         | 
| 149 | 
            +
                    }
         | 
| 150 | 
            +
                }
         | 
| 151 | 
            +
            }
         | 
| 152 | 
            +
             | 
| 153 | 
            +
            // Create and export singleton instance
         | 
| 154 | 
            +
            const extensionErrorHandler = new ExtensionErrorHandler();
         | 
| 155 | 
            +
             | 
| 156 | 
            +
            // Add to window for debugging access
         | 
| 157 | 
            +
            window.extensionErrorHandler = extensionErrorHandler;
         | 
| 158 | 
            +
             | 
| 159 | 
            +
            // Export for ES6 modules
         | 
| 160 | 
            +
            export { ExtensionErrorHandler, extensionErrorHandler };
         | 
| 161 | 
            +
            export default extensionErrorHandler;
         | 
| 162 | 
            +
             | 
| 163 | 
            +
            // Log initialization
         | 
| 164 | 
            +
            console.log('Extension error handler initialized. Use window.extensionErrorHandler.setDebugMode(true) to see suppressed errors.');
         | 
| @@ -3,6 +3,9 @@ | |
| 3 3 | 
             
             * Handles WebSocket connections and event processing
         | 
| 4 4 | 
             
             */
         | 
| 5 5 |  | 
| 6 | 
            +
            // Access the global io from window object in ES6 module context
         | 
| 7 | 
            +
            const io = window.io;
         | 
| 8 | 
            +
             | 
| 6 9 | 
             
            class SocketClient {
         | 
| 7 10 | 
             
                constructor() {
         | 
| 8 11 | 
             
                    this.socket = null;
         | 
| @@ -13,16 +16,16 @@ class SocketClient { | |
| 13 16 | 
             
                        error: [],
         | 
| 14 17 | 
             
                        event: []
         | 
| 15 18 | 
             
                    };
         | 
| 16 | 
            -
             | 
| 19 | 
            +
             | 
| 17 20 | 
             
                    // Connection state
         | 
| 18 21 | 
             
                    this.isConnected = false;
         | 
| 19 22 | 
             
                    this.isConnecting = false;
         | 
| 20 | 
            -
             | 
| 23 | 
            +
             | 
| 21 24 | 
             
                    // Event processing
         | 
| 22 25 | 
             
                    this.events = [];
         | 
| 23 26 | 
             
                    this.sessions = new Map();
         | 
| 24 27 | 
             
                    this.currentSessionId = null;
         | 
| 25 | 
            -
             | 
| 28 | 
            +
             | 
| 26 29 | 
             
                    // Start periodic status check as fallback mechanism
         | 
| 27 30 | 
             
                    this.startStatusCheckFallback();
         | 
| 28 31 | 
             
                }
         | 
| @@ -35,7 +38,7 @@ class SocketClient { | |
| 35 38 | 
             
                    // Store the port for later use
         | 
| 36 39 | 
             
                    this.port = port;
         | 
| 37 40 | 
             
                    const url = `http://localhost:${port}`;
         | 
| 38 | 
            -
             | 
| 41 | 
            +
             | 
| 39 42 | 
             
                    // Prevent multiple simultaneous connections
         | 
| 40 43 | 
             
                    if (this.socket && (this.socket.connected || this.socket.connecting)) {
         | 
| 41 44 | 
             
                        console.log('Already connected or connecting, disconnecting first...');
         | 
| @@ -44,7 +47,7 @@ class SocketClient { | |
| 44 47 | 
             
                        setTimeout(() => this.doConnect(url), 100);
         | 
| 45 48 | 
             
                        return;
         | 
| 46 49 | 
             
                    }
         | 
| 47 | 
            -
             | 
| 50 | 
            +
             | 
| 48 51 | 
             
                    this.doConnect(url);
         | 
| 49 52 | 
             
                }
         | 
| 50 53 |  | 
| @@ -54,9 +57,17 @@ class SocketClient { | |
| 54 57 | 
             
                 */
         | 
| 55 58 | 
             
                doConnect(url) {
         | 
| 56 59 | 
             
                    console.log(`Connecting to Socket.IO server at ${url}`);
         | 
| 60 | 
            +
                    
         | 
| 61 | 
            +
                    // Check if io is available
         | 
| 62 | 
            +
                    if (typeof io === 'undefined') {
         | 
| 63 | 
            +
                        console.error('Socket.IO library not loaded! Make sure socket.io.min.js is loaded before this script.');
         | 
| 64 | 
            +
                        this.notifyConnectionStatus('Socket.IO library not loaded', 'error');
         | 
| 65 | 
            +
                        return;
         | 
| 66 | 
            +
                    }
         | 
| 67 | 
            +
                    
         | 
| 57 68 | 
             
                    this.isConnecting = true;
         | 
| 58 69 | 
             
                    this.notifyConnectionStatus('Connecting...', 'connecting');
         | 
| 59 | 
            -
             | 
| 70 | 
            +
             | 
| 60 71 | 
             
                    this.socket = io(url, {
         | 
| 61 72 | 
             
                        autoConnect: true,
         | 
| 62 73 | 
             
                        reconnection: true,
         | 
| @@ -67,7 +78,7 @@ class SocketClient { | |
| 67 78 | 
             
                        forceNew: true,
         | 
| 68 79 | 
             
                        transports: ['websocket', 'polling']
         | 
| 69 80 | 
             
                    });
         | 
| 70 | 
            -
             | 
| 81 | 
            +
             | 
| 71 82 | 
             
                    this.setupSocketHandlers();
         | 
| 72 83 | 
             
                }
         | 
| 73 84 |  | 
| @@ -80,55 +91,55 @@ class SocketClient { | |
| 80 91 | 
             
                        this.isConnected = true;
         | 
| 81 92 | 
             
                        this.isConnecting = false;
         | 
| 82 93 | 
             
                        this.notifyConnectionStatus('Connected', 'connected');
         | 
| 83 | 
            -
             | 
| 94 | 
            +
             | 
| 84 95 | 
             
                        // Emit connect callback
         | 
| 85 | 
            -
                        this.connectionCallbacks.connect.forEach(callback => | 
| 96 | 
            +
                        this.connectionCallbacks.connect.forEach(callback =>
         | 
| 86 97 | 
             
                            callback(this.socket.id)
         | 
| 87 98 | 
             
                        );
         | 
| 88 | 
            -
             | 
| 99 | 
            +
             | 
| 89 100 | 
             
                        this.requestStatus();
         | 
| 90 101 | 
             
                        // History is now automatically sent by server on connection
         | 
| 91 102 | 
             
                        // No need to explicitly request it
         | 
| 92 103 | 
             
                    });
         | 
| 93 | 
            -
             | 
| 104 | 
            +
             | 
| 94 105 | 
             
                    this.socket.on('disconnect', (reason) => {
         | 
| 95 106 | 
             
                        console.log('Disconnected from server:', reason);
         | 
| 96 107 | 
             
                        this.isConnected = false;
         | 
| 97 108 | 
             
                        this.isConnecting = false;
         | 
| 98 109 | 
             
                        this.notifyConnectionStatus(`Disconnected: ${reason}`, 'disconnected');
         | 
| 99 | 
            -
             | 
| 110 | 
            +
             | 
| 100 111 | 
             
                        // Emit disconnect callback
         | 
| 101 | 
            -
                        this.connectionCallbacks.disconnect.forEach(callback => | 
| 112 | 
            +
                        this.connectionCallbacks.disconnect.forEach(callback =>
         | 
| 102 113 | 
             
                            callback(reason)
         | 
| 103 114 | 
             
                        );
         | 
| 104 115 | 
             
                    });
         | 
| 105 | 
            -
             | 
| 116 | 
            +
             | 
| 106 117 | 
             
                    this.socket.on('connect_error', (error) => {
         | 
| 107 118 | 
             
                        console.error('Connection error:', error);
         | 
| 108 119 | 
             
                        this.isConnecting = false;
         | 
| 109 120 | 
             
                        const errorMsg = error.message || error.description || 'Unknown error';
         | 
| 110 121 | 
             
                        this.notifyConnectionStatus(`Connection Error: ${errorMsg}`, 'disconnected');
         | 
| 111 | 
            -
             | 
| 122 | 
            +
             | 
| 112 123 | 
             
                        // Add error event
         | 
| 113 124 | 
             
                        this.addEvent({
         | 
| 114 125 | 
             
                            type: 'connection.error',
         | 
| 115 126 | 
             
                            timestamp: new Date().toISOString(),
         | 
| 116 127 | 
             
                            data: { error: errorMsg, url: this.socket.io.uri }
         | 
| 117 128 | 
             
                        });
         | 
| 118 | 
            -
             | 
| 129 | 
            +
             | 
| 119 130 | 
             
                        // Emit error callback
         | 
| 120 | 
            -
                        this.connectionCallbacks.error.forEach(callback => | 
| 131 | 
            +
                        this.connectionCallbacks.error.forEach(callback =>
         | 
| 121 132 | 
             
                            callback(errorMsg)
         | 
| 122 133 | 
             
                        );
         | 
| 123 134 | 
             
                    });
         | 
| 124 135 |  | 
| 125 136 | 
             
                    // Primary event handler - this is what the server actually emits
         | 
| 126 137 | 
             
                    this.socket.on('claude_event', (data) => {
         | 
| 127 | 
            -
                        console.log('Received claude_event:', data);
         | 
| 128 | 
            -
             | 
| 138 | 
            +
                        // console.log('Received claude_event:', data);
         | 
| 139 | 
            +
             | 
| 129 140 | 
             
                        // Transform event to match expected format
         | 
| 130 141 | 
             
                        const transformedEvent = this.transformEvent(data);
         | 
| 131 | 
            -
                        console.log('Transformed event:', transformedEvent);
         | 
| 142 | 
            +
                        // console.log('Transformed event:', transformedEvent);
         | 
| 132 143 | 
             
                        this.addEvent(transformedEvent);
         | 
| 133 144 | 
             
                    });
         | 
| 134 145 |  | 
| @@ -310,7 +321,7 @@ class SocketClient { | |
| 310 321 | 
             
                    this.sessions.clear();
         | 
| 311 322 | 
             
                    this.notifyEventUpdate();
         | 
| 312 323 | 
             
                }
         | 
| 313 | 
            -
             | 
| 324 | 
            +
             | 
| 314 325 | 
             
                /**
         | 
| 315 326 | 
             
                 * Clear events and request fresh history from server
         | 
| 316 327 | 
             
                 * @param {Object} options - History request options (same as requestHistory)
         | 
| @@ -329,7 +340,7 @@ class SocketClient { | |
| 329 340 | 
             
                    if (!sessionId) {
         | 
| 330 341 | 
             
                        return this.events;
         | 
| 331 342 | 
             
                    }
         | 
| 332 | 
            -
                    return this.events.filter(event => | 
| 343 | 
            +
                    return this.events.filter(event =>
         | 
| 333 344 | 
             
                        event.data && event.data.session_id === sessionId
         | 
| 334 345 | 
             
                    );
         | 
| 335 346 | 
             
                }
         | 
| @@ -360,10 +371,10 @@ class SocketClient { | |
| 360 371 | 
             
                 */
         | 
| 361 372 | 
             
                notifyConnectionStatus(status, type) {
         | 
| 362 373 | 
             
                    console.log(`SocketClient: Connection status changed to '${status}' (${type})`);
         | 
| 363 | 
            -
             | 
| 374 | 
            +
             | 
| 364 375 | 
             
                    // Direct DOM update - immediate and reliable
         | 
| 365 376 | 
             
                    this.updateConnectionStatusDOM(status, type);
         | 
| 366 | 
            -
             | 
| 377 | 
            +
             | 
| 367 378 | 
             
                    // Also dispatch custom event for other modules
         | 
| 368 379 | 
             
                    document.dispatchEvent(new CustomEvent('socketConnectionStatus', {
         | 
| 369 380 | 
             
                        detail: { status, type }
         | 
| @@ -380,10 +391,10 @@ class SocketClient { | |
| 380 391 | 
             
                    if (statusElement) {
         | 
| 381 392 | 
             
                        // Update the text content while preserving the indicator span
         | 
| 382 393 | 
             
                        statusElement.innerHTML = `<span>●</span> ${status}`;
         | 
| 383 | 
            -
             | 
| 394 | 
            +
             | 
| 384 395 | 
             
                        // Update the CSS class for styling
         | 
| 385 396 | 
             
                        statusElement.className = `status-badge status-${type}`;
         | 
| 386 | 
            -
             | 
| 397 | 
            +
             | 
| 387 398 | 
             
                        console.log(`SocketClient: Direct DOM update - status: '${status}' (${type})`);
         | 
| 388 399 | 
             
                    } else {
         | 
| 389 400 | 
             
                        console.warn('SocketClient: Could not find connection-status element in DOM');
         | 
| @@ -394,10 +405,10 @@ class SocketClient { | |
| 394 405 | 
             
                 * Notify event update
         | 
| 395 406 | 
             
                 */
         | 
| 396 407 | 
             
                notifyEventUpdate() {
         | 
| 397 | 
            -
                    this.connectionCallbacks.event.forEach(callback => | 
| 408 | 
            +
                    this.connectionCallbacks.event.forEach(callback =>
         | 
| 398 409 | 
             
                        callback(this.events, this.sessions)
         | 
| 399 410 | 
             
                    );
         | 
| 400 | 
            -
             | 
| 411 | 
            +
             | 
| 401 412 | 
             
                    // Also dispatch custom event
         | 
| 402 413 | 
             
                    document.dispatchEvent(new CustomEvent('socketEventUpdate', {
         | 
| 403 414 | 
             
                        detail: { events: this.events, sessions: this.sessions }
         | 
| @@ -422,27 +433,65 @@ class SocketClient { | |
| 422 433 | 
             
                 * @returns {Object} Transformed event
         | 
| 423 434 | 
             
                 */
         | 
| 424 435 | 
             
                transformEvent(eventData) {
         | 
| 425 | 
            -
                    // Handle  | 
| 426 | 
            -
                    // { type: 'hook.pre_tool', timestamp: '...', data: { | 
| 427 | 
            -
                    
         | 
| 428 | 
            -
                     | 
| 429 | 
            -
             | 
| 436 | 
            +
                    // Handle multiple event structures:
         | 
| 437 | 
            +
                    // 1. Hook events: { type: 'hook.pre_tool', timestamp: '...', data: {...} }
         | 
| 438 | 
            +
                    // 2. Legacy events: { event: 'TestStart', timestamp: '...', ... }
         | 
| 439 | 
            +
                    // 3. Standard events: { type: 'session', subtype: 'started', ... }
         | 
| 440 | 
            +
             | 
| 441 | 
            +
                    if (!eventData) {
         | 
| 442 | 
            +
                        return eventData; // Return as-is if null/undefined
         | 
| 430 443 | 
             
                    }
         | 
| 431 444 |  | 
| 432 | 
            -
                    const type = eventData.type;
         | 
| 433 445 | 
             
                    let transformedEvent = { ...eventData };
         | 
| 434 446 |  | 
| 435 | 
            -
                    //  | 
| 436 | 
            -
                    if (type. | 
| 437 | 
            -
                         | 
| 438 | 
            -
                         | 
| 439 | 
            -
                         | 
| 447 | 
            +
                    // Handle legacy format with 'event' field but no 'type'
         | 
| 448 | 
            +
                    if (!eventData.type && eventData.event) {
         | 
| 449 | 
            +
                        // Map common event names to proper type/subtype
         | 
| 450 | 
            +
                        const eventName = eventData.event;
         | 
| 451 | 
            +
                        
         | 
| 452 | 
            +
                        // Check for known event patterns
         | 
| 453 | 
            +
                        if (eventName === 'TestStart' || eventName === 'TestEnd') {
         | 
| 454 | 
            +
                            transformedEvent.type = 'test';
         | 
| 455 | 
            +
                            transformedEvent.subtype = eventName.toLowerCase().replace('test', '');
         | 
| 456 | 
            +
                        } else if (eventName === 'SubagentStart' || eventName === 'SubagentStop') {
         | 
| 457 | 
            +
                            transformedEvent.type = 'subagent';
         | 
| 458 | 
            +
                            transformedEvent.subtype = eventName.toLowerCase().replace('subagent', '');
         | 
| 459 | 
            +
                        } else if (eventName === 'ToolCall') {
         | 
| 460 | 
            +
                            transformedEvent.type = 'tool';
         | 
| 461 | 
            +
                            transformedEvent.subtype = 'call';
         | 
| 462 | 
            +
                        } else if (eventName === 'UserPrompt') {
         | 
| 463 | 
            +
                            transformedEvent.type = 'hook';
         | 
| 464 | 
            +
                            transformedEvent.subtype = 'user_prompt';
         | 
| 465 | 
            +
                        } else {
         | 
| 466 | 
            +
                            // Generic fallback for unknown event names
         | 
| 467 | 
            +
                            transformedEvent.type = 'system';
         | 
| 468 | 
            +
                            transformedEvent.subtype = eventName.toLowerCase();
         | 
| 469 | 
            +
                        }
         | 
| 470 | 
            +
                        
         | 
| 471 | 
            +
                        // Remove the 'event' field to avoid confusion
         | 
| 472 | 
            +
                        delete transformedEvent.event;
         | 
| 440 473 | 
             
                    }
         | 
| 441 | 
            -
                    //  | 
| 442 | 
            -
                    else if (type | 
| 443 | 
            -
                        const  | 
| 444 | 
            -
                         | 
| 445 | 
            -
                         | 
| 474 | 
            +
                    // Handle standard format with 'type' field
         | 
| 475 | 
            +
                    else if (eventData.type) {
         | 
| 476 | 
            +
                        const type = eventData.type;
         | 
| 477 | 
            +
                        
         | 
| 478 | 
            +
                        // Transform 'hook.subtype' format to separate type and subtype
         | 
| 479 | 
            +
                        if (type.startsWith('hook.')) {
         | 
| 480 | 
            +
                            const subtype = type.substring(5); // Remove 'hook.' prefix
         | 
| 481 | 
            +
                            transformedEvent.type = 'hook';
         | 
| 482 | 
            +
                            transformedEvent.subtype = subtype;
         | 
| 483 | 
            +
                        }
         | 
| 484 | 
            +
                        // Transform other dotted types like 'session.started' -> type: 'session', subtype: 'started'
         | 
| 485 | 
            +
                        else if (type.includes('.')) {
         | 
| 486 | 
            +
                            const [mainType, ...subtypeParts] = type.split('.');
         | 
| 487 | 
            +
                            transformedEvent.type = mainType;
         | 
| 488 | 
            +
                            transformedEvent.subtype = subtypeParts.join('.');
         | 
| 489 | 
            +
                        }
         | 
| 490 | 
            +
                    }
         | 
| 491 | 
            +
                    // If no type and no event field, mark as unknown
         | 
| 492 | 
            +
                    else {
         | 
| 493 | 
            +
                        transformedEvent.type = 'unknown';
         | 
| 494 | 
            +
                        transformedEvent.subtype = '';
         | 
| 446 495 | 
             
                    }
         | 
| 447 496 |  | 
| 448 497 | 
             
                    // Extract and flatten data fields to top level for dashboard compatibility
         | 
| @@ -450,10 +499,23 @@ class SocketClient { | |
| 450 499 | 
             
                    if (eventData.data && typeof eventData.data === 'object') {
         | 
| 451 500 | 
             
                        // Copy all data fields to the top level
         | 
| 452 501 | 
             
                        Object.keys(eventData.data).forEach(key => {
         | 
| 453 | 
            -
                            //  | 
| 454 | 
            -
                             | 
| 455 | 
            -
             | 
| 456 | 
            -
             | 
| 502 | 
            +
                            // Always copy data fields to ensure dashboard gets them
         | 
| 503 | 
            +
                            // This overwrites any existing values to ensure data fields take precedence
         | 
| 504 | 
            +
                            transformedEvent[key] = eventData.data[key];
         | 
| 505 | 
            +
                        });
         | 
| 506 | 
            +
                        
         | 
| 507 | 
            +
                        // Keep the original data object for backward compatibility
         | 
| 508 | 
            +
                        transformedEvent.data = eventData.data;
         | 
| 509 | 
            +
                    }
         | 
| 510 | 
            +
             | 
| 511 | 
            +
                    // Debug logging for tool events
         | 
| 512 | 
            +
                    if (transformedEvent.type === 'hook' && (transformedEvent.subtype === 'pre_tool' || transformedEvent.subtype === 'post_tool')) {
         | 
| 513 | 
            +
                        console.log('Transformed tool event:', {
         | 
| 514 | 
            +
                            type: transformedEvent.type,
         | 
| 515 | 
            +
                            subtype: transformedEvent.subtype,
         | 
| 516 | 
            +
                            tool_name: transformedEvent.tool_name,
         | 
| 517 | 
            +
                            has_data: !!transformedEvent.data,
         | 
| 518 | 
            +
                            keys: Object.keys(transformedEvent).filter(k => k !== 'data')
         | 
| 457 519 | 
             
                        });
         | 
| 458 520 | 
             
                    }
         | 
| 459 521 |  | 
| @@ -481,7 +543,7 @@ class SocketClient { | |
| 481 543 | 
             
                    setInterval(() => {
         | 
| 482 544 | 
             
                        this.checkAndUpdateStatus();
         | 
| 483 545 | 
             
                    }, 2000);
         | 
| 484 | 
            -
             | 
| 546 | 
            +
             | 
| 485 547 | 
             
                    // Initial check after DOM is ready
         | 
| 486 548 | 
             
                    if (document.readyState === 'loading') {
         | 
| 487 549 | 
             
                        document.addEventListener('DOMContentLoaded', () => {
         | 
| @@ -498,7 +560,7 @@ class SocketClient { | |
| 498 560 | 
             
                checkAndUpdateStatus() {
         | 
| 499 561 | 
             
                    let actualStatus = 'Disconnected';
         | 
| 500 562 | 
             
                    let actualType = 'disconnected';
         | 
| 501 | 
            -
             | 
| 563 | 
            +
             | 
| 502 564 | 
             
                    if (this.socket) {
         | 
| 503 565 | 
             
                        if (this.socket.connected) {
         | 
| 504 566 | 
             
                            actualStatus = 'Connected';
         | 
| @@ -516,14 +578,14 @@ class SocketClient { | |
| 516 578 | 
             
                            this.isConnecting = false;
         | 
| 517 579 | 
             
                        }
         | 
| 518 580 | 
             
                    }
         | 
| 519 | 
            -
             | 
| 581 | 
            +
             | 
| 520 582 | 
             
                    // Check if UI needs updating
         | 
| 521 583 | 
             
                    const statusElement = document.getElementById('connection-status');
         | 
| 522 584 | 
             
                    if (statusElement) {
         | 
| 523 585 | 
             
                        const currentText = statusElement.textContent.replace('●', '').trim();
         | 
| 524 586 | 
             
                        const currentClass = statusElement.className;
         | 
| 525 587 | 
             
                        const expectedClass = `status-badge status-${actualType}`;
         | 
| 526 | 
            -
             | 
| 588 | 
            +
             | 
| 527 589 | 
             
                        // Update if status text or class doesn't match
         | 
| 528 590 | 
             
                        if (currentText !== actualStatus || currentClass !== expectedClass) {
         | 
| 529 591 | 
             
                            console.log(`SocketClient: Fallback update - was '${currentText}' (${currentClass}), now '${actualStatus}' (${expectedClass})`);
         | 
| @@ -533,5 +595,9 @@ class SocketClient { | |
| 533 595 | 
             
                }
         | 
| 534 596 | 
             
            }
         | 
| 535 597 |  | 
| 536 | 
            -
            //  | 
| 537 | 
            -
             | 
| 598 | 
            +
            // ES6 Module export
         | 
| 599 | 
            +
            export { SocketClient };
         | 
| 600 | 
            +
            export default SocketClient;
         | 
| 601 | 
            +
             | 
| 602 | 
            +
            // Backward compatibility - keep window export for non-module usage
         | 
| 603 | 
            +
            window.SocketClient = SocketClient;
         |