claude-mpm 3.9.11__py3-none-any.whl → 4.0.4__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 +1 -1
- 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 +2 -2
- 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 +79 -51
- claude_mpm/cli/__main__.py +3 -2
- claude_mpm/cli/commands/__init__.py +20 -20
- 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 +140 -905
- 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 +330 -86
- 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 +363 -220
- claude_mpm/cli/parser.py +24 -1156
- 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 +124 -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 +71 -73
- claude_mpm/config/paths.py +94 -208
- claude_mpm/config/socketio_config.py +84 -73
- claude_mpm/constants.py +35 -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/built/components/agent-inference.js +2 -0
- claude_mpm/dashboard/static/built/components/event-processor.js +2 -0
- claude_mpm/dashboard/static/built/components/event-viewer.js +2 -0
- claude_mpm/dashboard/static/built/components/export-manager.js +2 -0
- claude_mpm/dashboard/static/built/components/file-tool-tracker.js +2 -0
- claude_mpm/dashboard/static/built/components/hud-library-loader.js +2 -0
- claude_mpm/dashboard/static/built/components/hud-manager.js +2 -0
- claude_mpm/dashboard/static/built/components/hud-visualizer.js +2 -0
- claude_mpm/dashboard/static/built/components/module-viewer.js +2 -0
- claude_mpm/dashboard/static/built/components/session-manager.js +2 -0
- claude_mpm/dashboard/static/built/components/socket-manager.js +2 -0
- claude_mpm/dashboard/static/built/components/ui-state-manager.js +2 -0
- claude_mpm/dashboard/static/built/components/working-directory.js +2 -0
- claude_mpm/dashboard/static/built/dashboard.js +2 -0
- claude_mpm/dashboard/static/built/socket-client.js +2 -0
- 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 +93 -72
- claude_mpm/dashboard/static/js/components/export-manager.js +31 -28
- claude_mpm/dashboard/static/js/components/file-tool-tracker.js +110 -96
- 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 +133 -53
- 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 +233 -199
- 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 +30 -13
- 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 +13 -20
- 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 +87 -84
- claude_mpm/services/mcp_gateway/main.py +287 -137
- claude_mpm/services/mcp_gateway/registry/__init__.py +1 -1
- claude_mpm/services/mcp_gateway/registry/service_registry.py +97 -94
- claude_mpm/services/mcp_gateway/registry/tool_registry.py +135 -126
- claude_mpm/services/mcp_gateway/server/__init__.py +2 -2
- claude_mpm/services/mcp_gateway/server/mcp_gateway.py +105 -110
- 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 +109 -119
- 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 +575 -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 +166 -64
- 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 +185 -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 +19 -533
- 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 +2 -2
- claude_mpm/storage/state_storage.py +177 -181
- 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.11.dist-info → claude_mpm-4.0.4.dist-info}/METADATA +90 -22
- claude_mpm-4.0.4.dist-info/RECORD +417 -0
- {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/entry_points.txt +1 -0
- {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/licenses/LICENSE +1 -1
- claude_mpm/cli/commands/run_guarded.py +0 -511
- claude_mpm/config/memory_guardian_config.py +0 -325
- claude_mpm/config/memory_guardian_yaml.py +0 -335
- claude_mpm/core/config_paths.py +0 -150
- claude_mpm/core/memory_aware_runner.py +0 -353
- 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/graceful_degradation.py +0 -616
- claude_mpm/services/infrastructure/health_monitor.py +0 -775
- claude_mpm/services/infrastructure/memory_dashboard.py +0 -479
- claude_mpm/services/infrastructure/memory_guardian.py +0 -944
- claude_mpm/services/infrastructure/restart_protection.py +0 -642
- claude_mpm/services/infrastructure/state_manager.py +0 -774
- claude_mpm/services/mcp_gateway/manager.py +0 -334
- 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.11.dist-info/RECORD +0 -306
- {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/WHEEL +0 -0
- {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/top_level.txt +0 -0
| @@ -9,7 +9,7 @@ class SessionManager { | |
| 9 9 | 
             
                    this.sessions = new Map();
         | 
| 10 10 | 
             
                    this.currentSessionId = null;
         | 
| 11 11 | 
             
                    this.selectedSessionId = '';
         | 
| 12 | 
            -
             | 
| 12 | 
            +
             | 
| 13 13 | 
             
                    this.init();
         | 
| 14 14 | 
             
                }
         | 
| 15 15 |  | 
| @@ -32,7 +32,7 @@ class SessionManager { | |
| 32 32 | 
             
                        sessionSelect.addEventListener('change', (e) => {
         | 
| 33 33 | 
             
                            this.selectedSessionId = e.target.value;
         | 
| 34 34 | 
             
                            this.onSessionFilterChanged();
         | 
| 35 | 
            -
             | 
| 35 | 
            +
             | 
| 36 36 | 
             
                            // Load working directory for this session
         | 
| 37 37 | 
             
                            if (window.dashboard && window.dashboard.loadWorkingDirectoryForSession) {
         | 
| 38 38 | 
             
                                window.dashboard.loadWorkingDirectoryForSession(e.target.value);
         | 
| @@ -93,12 +93,12 @@ class SessionManager { | |
| 93 93 | 
             
                        sortedSessions.forEach(session => {
         | 
| 94 94 | 
             
                            const option = document.createElement('option');
         | 
| 95 95 | 
             
                            option.value = session.id;
         | 
| 96 | 
            -
             | 
| 96 | 
            +
             | 
| 97 97 | 
             
                            // Format session display text
         | 
| 98 98 | 
             
                            const startTime = new Date(session.startTime || session.last_activity).toLocaleString();
         | 
| 99 99 | 
             
                            const eventCount = session.eventCount || session.event_count || 0;
         | 
| 100 100 | 
             
                            const isActive = session.id === this.currentSessionId;
         | 
| 101 | 
            -
             | 
| 101 | 
            +
             | 
| 102 102 | 
             
                            option.textContent = `${session.id.substring(0, 8)}... (${eventCount} events, ${startTime})${isActive ? ' [ACTIVE]' : ''}`;
         | 
| 103 103 | 
             
                            sessionSelect.appendChild(option);
         | 
| 104 104 | 
             
                        });
         | 
| @@ -136,7 +136,7 @@ class SessionManager { | |
| 136 136 | 
             
                    document.dispatchEvent(new CustomEvent('sessionFilterChanged', {
         | 
| 137 137 | 
             
                        detail: { sessionId: this.selectedSessionId }
         | 
| 138 138 | 
             
                    }));
         | 
| 139 | 
            -
             | 
| 139 | 
            +
             | 
| 140 140 | 
             
                    // Also dispatch sessionChanged for backward compatibility with other components
         | 
| 141 141 | 
             
                    document.dispatchEvent(new CustomEvent('sessionChanged', {
         | 
| 142 142 | 
             
                        detail: { sessionId: this.selectedSessionId }
         | 
| @@ -160,7 +160,7 @@ class SessionManager { | |
| 160 160 | 
             
                 */
         | 
| 161 161 | 
             
                updateFooterInfo() {
         | 
| 162 162 | 
             
                    console.log('[SESSION-DEBUG] updateFooterInfo called, selectedSessionId:', this.selectedSessionId);
         | 
| 163 | 
            -
             | 
| 163 | 
            +
             | 
| 164 164 | 
             
                    const footerSessionEl = document.getElementById('footer-session');
         | 
| 165 165 | 
             
                    const footerWorkingDirEl = document.getElementById('footer-working-dir');
         | 
| 166 166 | 
             
                    const footerGitBranchEl = document.getElementById('footer-git-branch');
         | 
| @@ -173,14 +173,14 @@ class SessionManager { | |
| 173 173 | 
             
                    let sessionInfo = 'All Sessions';
         | 
| 174 174 | 
             
                    let workingDir = window.dashboard?.workingDirectoryManager?.getDefaultWorkingDir() || process?.cwd?.() || '/Users/masa/Projects/claude-mpm';
         | 
| 175 175 | 
             
                    let gitBranch = 'Unknown';
         | 
| 176 | 
            -
             | 
| 176 | 
            +
             | 
| 177 177 | 
             
                    console.log('[SESSION-DEBUG] Initial values - sessionInfo:', sessionInfo, 'workingDir:', workingDir, 'gitBranch:', gitBranch);
         | 
| 178 178 |  | 
| 179 179 | 
             
                    if (this.selectedSessionId === 'current') {
         | 
| 180 | 
            -
                        sessionInfo = this.currentSessionId ? | 
| 181 | 
            -
                            `Current: ${this.currentSessionId.substring(0, 8)}...` : | 
| 180 | 
            +
                        sessionInfo = this.currentSessionId ?
         | 
| 181 | 
            +
                            `Current: ${this.currentSessionId.substring(0, 8)}...` :
         | 
| 182 182 | 
             
                            'Current: None';
         | 
| 183 | 
            -
             | 
| 183 | 
            +
             | 
| 184 184 | 
             
                        // For current session, try to extract info from recent events
         | 
| 185 185 | 
             
                        if (this.currentSessionId) {
         | 
| 186 186 | 
             
                            const sessionData = this.extractSessionInfoFromEvents(this.currentSessionId);
         | 
| @@ -193,7 +193,7 @@ class SessionManager { | |
| 193 193 | 
             
                            sessionInfo = `${this.selectedSessionId.substring(0, 8)}...`;
         | 
| 194 194 | 
             
                            workingDir = session.working_directory || session.workingDirectory || '';
         | 
| 195 195 | 
             
                            gitBranch = session.git_branch || session.gitBranch || '';
         | 
| 196 | 
            -
             | 
| 196 | 
            +
             | 
| 197 197 | 
             
                            // If session doesn't have these values, extract from events
         | 
| 198 198 | 
             
                            if (!workingDir || !gitBranch) {
         | 
| 199 199 | 
             
                                const sessionData = this.extractSessionInfoFromEvents(this.selectedSessionId);
         | 
| @@ -204,7 +204,7 @@ class SessionManager { | |
| 204 204 | 
             
                    }
         | 
| 205 205 |  | 
| 206 206 | 
             
                    console.log('[SESSION-DEBUG] Final values before setting footer - sessionInfo:', sessionInfo, 'workingDir:', workingDir, 'gitBranch:', gitBranch);
         | 
| 207 | 
            -
             | 
| 207 | 
            +
             | 
| 208 208 | 
             
                    footerSessionEl.textContent = sessionInfo;
         | 
| 209 209 | 
             
                    if (footerWorkingDirEl) {
         | 
| 210 210 | 
             
                        console.log('[SESSION-DEBUG] Setting footer working dir to:', workingDir);
         | 
| @@ -235,9 +235,9 @@ class SessionManager { | |
| 235 235 | 
             
                    const socketClient = this.socketClient;
         | 
| 236 236 | 
             
                    if (socketClient && socketClient.events) {
         | 
| 237 237 | 
             
                        console.log(`[DEBUG] Total events available: ${socketClient.events.length}`);
         | 
| 238 | 
            -
             | 
| 238 | 
            +
             | 
| 239 239 | 
             
                        // Look for session start events or recent events with this session ID
         | 
| 240 | 
            -
                        const sessionEvents = socketClient.events.filter(event => | 
| 240 | 
            +
                        const sessionEvents = socketClient.events.filter(event =>
         | 
| 241 241 | 
             
                            event.data && event.data.session_id === sessionId
         | 
| 242 242 | 
             
                        );
         | 
| 243 243 |  | 
| @@ -246,7 +246,7 @@ class SessionManager { | |
| 246 246 | 
             
                        // Log a few sample events to see their structure
         | 
| 247 247 | 
             
                        if (sessionEvents.length > 0) {
         | 
| 248 248 | 
             
                            console.log(`[DEBUG] Sample events for session ${sessionId}:`);
         | 
| 249 | 
            -
             | 
| 249 | 
            +
             | 
| 250 250 | 
             
                            // Show first 3 events
         | 
| 251 251 | 
             
                            sessionEvents.slice(0, 3).forEach((event, index) => {
         | 
| 252 252 | 
             
                                console.log(`[DEBUG] Event ${index + 1}:`, {
         | 
| @@ -276,7 +276,7 @@ class SessionManager { | |
| 276 276 | 
             
                            const event = sessionEvents[i];
         | 
| 277 277 | 
             
                            if (event.data) {
         | 
| 278 278 | 
             
                                console.log(`[DEBUG] Examining event ${i} data:`, event.data);
         | 
| 279 | 
            -
             | 
| 279 | 
            +
             | 
| 280 280 | 
             
                                // Check for working directory info
         | 
| 281 281 | 
             
                                if (!workingDir) {
         | 
| 282 282 | 
             
                                    if (event.data.working_directory) {
         | 
| @@ -295,13 +295,13 @@ class SessionManager { | |
| 295 295 | 
             
                                if (!gitBranch) {
         | 
| 296 296 | 
             
                                    const possibleBranchFields = [
         | 
| 297 297 | 
             
                                        'git_branch',
         | 
| 298 | 
            -
                                        'gitBranch', | 
| 298 | 
            +
                                        'gitBranch',
         | 
| 299 299 | 
             
                                        'branch',
         | 
| 300 300 | 
             
                                        'git.branch',
         | 
| 301 301 | 
             
                                        'vcs_branch',
         | 
| 302 302 | 
             
                                        'current_branch'
         | 
| 303 303 | 
             
                                    ];
         | 
| 304 | 
            -
             | 
| 304 | 
            +
             | 
| 305 305 | 
             
                                    for (const field of possibleBranchFields) {
         | 
| 306 306 | 
             
                                        if (event.data[field]) {
         | 
| 307 307 | 
             
                                            gitBranch = event.data[field];
         | 
| @@ -309,7 +309,7 @@ class SessionManager { | |
| 309 309 | 
             
                                            break;
         | 
| 310 310 | 
             
                                        }
         | 
| 311 311 | 
             
                                    }
         | 
| 312 | 
            -
             | 
| 312 | 
            +
             | 
| 313 313 | 
             
                                    // Check nested locations
         | 
| 314 314 | 
             
                                    if (!gitBranch) {
         | 
| 315 315 | 
             
                                        if (event.data.instance_info) {
         | 
| @@ -322,7 +322,7 @@ class SessionManager { | |
| 322 322 | 
             
                                                }
         | 
| 323 323 | 
             
                                            }
         | 
| 324 324 | 
             
                                        }
         | 
| 325 | 
            -
             | 
| 325 | 
            +
             | 
| 326 326 | 
             
                                        if (!gitBranch && event.data.git) {
         | 
| 327 327 | 
             
                                            console.log(`[DEBUG] Checking git object:`, event.data.git);
         | 
| 328 328 | 
             
                                            if (event.data.git.branch) {
         | 
| @@ -364,7 +364,7 @@ class SessionManager { | |
| 364 364 | 
             
                 */
         | 
| 365 365 | 
             
                addSession(sessionData) {
         | 
| 366 366 | 
             
                    if (!sessionData.id) return;
         | 
| 367 | 
            -
             | 
| 367 | 
            +
             | 
| 368 368 | 
             
                    const existingSession = this.sessions.get(sessionData.id);
         | 
| 369 369 | 
             
                    if (existingSession) {
         | 
| 370 370 | 
             
                        // Update existing session
         | 
| @@ -382,7 +382,7 @@ class SessionManager { | |
| 382 382 | 
             
                            ...sessionData
         | 
| 383 383 | 
             
                        });
         | 
| 384 384 | 
             
                    }
         | 
| 385 | 
            -
             | 
| 385 | 
            +
             | 
| 386 386 | 
             
                    this.updateSessionSelect();
         | 
| 387 387 | 
             
                }
         | 
| 388 388 |  | 
| @@ -393,7 +393,7 @@ class SessionManager { | |
| 393 393 | 
             
                removeSession(sessionId) {
         | 
| 394 394 | 
             
                    if (this.sessions.has(sessionId)) {
         | 
| 395 395 | 
             
                        this.sessions.delete(sessionId);
         | 
| 396 | 
            -
             | 
| 396 | 
            +
             | 
| 397 397 | 
             
                        // If the removed session was selected, reset to all sessions
         | 
| 398 398 | 
             
                        if (this.selectedSessionId === sessionId) {
         | 
| 399 399 | 
             
                            this.selectedSessionId = '';
         | 
| @@ -403,7 +403,7 @@ class SessionManager { | |
| 403 403 | 
             
                            }
         | 
| 404 404 | 
             
                            this.onSessionFilterChanged();
         | 
| 405 405 | 
             
                        }
         | 
| 406 | 
            -
             | 
| 406 | 
            +
             | 
| 407 407 | 
             
                        this.updateSessionSelect();
         | 
| 408 408 | 
             
                    }
         | 
| 409 409 | 
             
                }
         | 
| @@ -475,15 +475,15 @@ class SessionManager { | |
| 475 475 | 
             
                            this.sessions.set(id, sessionData);
         | 
| 476 476 | 
             
                        });
         | 
| 477 477 | 
             
                    }
         | 
| 478 | 
            -
             | 
| 478 | 
            +
             | 
| 479 479 | 
             
                    if (data.currentSessionId) {
         | 
| 480 480 | 
             
                        this.currentSessionId = data.currentSessionId;
         | 
| 481 481 | 
             
                    }
         | 
| 482 | 
            -
             | 
| 482 | 
            +
             | 
| 483 483 | 
             
                    if (data.selectedSessionId !== undefined) {
         | 
| 484 484 | 
             
                        this.selectedSessionId = data.selectedSessionId;
         | 
| 485 485 | 
             
                    }
         | 
| 486 | 
            -
             | 
| 486 | 
            +
             | 
| 487 487 | 
             
                    this.updateSessionSelect();
         | 
| 488 488 | 
             
                    this.updateFooterInfo();
         | 
| 489 489 | 
             
                }
         | 
| @@ -501,7 +501,7 @@ class SessionManager { | |
| 501 501 | 
             
                    const allEvents = this.socketClient.events || [];
         | 
| 502 502 | 
             
                    return allEvents.filter(event => {
         | 
| 503 503 | 
             
                        // Check for session ID in various possible locations
         | 
| 504 | 
            -
                        const eventSessionId = event.session_id || | 
| 504 | 
            +
                        const eventSessionId = event.session_id ||
         | 
| 505 505 | 
             
                                             (event.data && event.data.session_id) ||
         | 
| 506 506 | 
             
                                             null;
         | 
| 507 507 | 
             
                        return eventSessionId === sessionId;
         | 
| @@ -517,4 +517,7 @@ window.refreshSessions = function() { | |
| 517 517 | 
             
            };
         | 
| 518 518 |  | 
| 519 519 | 
             
            // Export for global use
         | 
| 520 | 
            -
            window.SessionManager = SessionManager;
         | 
| 520 | 
            +
            window.SessionManager = SessionManager;
         | 
| 521 | 
            +
            // ES6 Module export
         | 
| 522 | 
            +
            export { SessionManager };
         | 
| 523 | 
            +
            export default SessionManager;
         | 
| @@ -1,36 +1,39 @@ | |
| 1 1 | 
             
            /**
         | 
| 2 2 | 
             
             * Socket Manager Module
         | 
| 3 | 
            -
             * | 
| 3 | 
            +
             *
         | 
| 4 4 | 
             
             * Handles all socket connection management, event dispatching, and connection state.
         | 
| 5 5 | 
             
             * Provides a centralized interface for socket operations across the dashboard.
         | 
| 6 | 
            -
             * | 
| 6 | 
            +
             *
         | 
| 7 7 | 
             
             * WHY: Extracted from main dashboard to centralize socket connection logic and
         | 
| 8 8 | 
             
             * provide better separation of concerns. This allows for easier testing and
         | 
| 9 9 | 
             
             * maintenance of connection handling code.
         | 
| 10 | 
            -
             * | 
| 10 | 
            +
             *
         | 
| 11 11 | 
             
             * DESIGN DECISION: Acts as a wrapper around SocketClient to provide dashboard-specific
         | 
| 12 12 | 
             
             * connection management while maintaining the existing SocketClient interface.
         | 
| 13 13 | 
             
             * Uses event dispatching to notify other modules of connection state changes.
         | 
| 14 14 | 
             
             */
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            // Import SocketClient (assuming it will be converted to ES6 modules too)
         | 
| 17 | 
            +
            import { SocketClient } from '../socket-client.js';
         | 
| 15 18 | 
             
            class SocketManager {
         | 
| 16 19 | 
             
                constructor() {
         | 
| 17 20 | 
             
                    this.socketClient = null;
         | 
| 18 21 | 
             
                    this.connectionCallbacks = new Set();
         | 
| 19 22 | 
             
                    this.eventUpdateCallbacks = new Set();
         | 
| 20 | 
            -
             | 
| 23 | 
            +
             | 
| 21 24 | 
             
                    // Initialize socket client
         | 
| 22 25 | 
             
                    this.socketClient = new SocketClient();
         | 
| 23 | 
            -
             | 
| 26 | 
            +
             | 
| 24 27 | 
             
                    // Make socketClient globally available (for backward compatibility)
         | 
| 25 28 | 
             
                    window.socketClient = this.socketClient;
         | 
| 26 | 
            -
             | 
| 29 | 
            +
             | 
| 27 30 | 
             
                    this.setupSocketEventHandlers();
         | 
| 28 | 
            -
             | 
| 31 | 
            +
             | 
| 29 32 | 
             
                    // Force initial status update after a short delay to ensure DOM is ready
         | 
| 30 33 | 
             
                    setTimeout(() => {
         | 
| 31 34 | 
             
                        this.updateInitialConnectionStatus();
         | 
| 32 35 | 
             
                    }, 100);
         | 
| 33 | 
            -
             | 
| 36 | 
            +
             | 
| 34 37 | 
             
                    console.log('Socket manager initialized');
         | 
| 35 38 | 
             
                }
         | 
| 36 39 |  | 
| @@ -42,7 +45,7 @@ class SocketManager { | |
| 42 45 | 
             
                    document.addEventListener('socketConnectionStatus', (e) => {
         | 
| 43 46 | 
             
                        console.log(`SocketManager: Processing connection status update: ${e.detail.status} (${e.detail.type})`);
         | 
| 44 47 | 
             
                        this.handleConnectionStatusChange(e.detail.status, e.detail.type);
         | 
| 45 | 
            -
             | 
| 48 | 
            +
             | 
| 46 49 | 
             
                        // Notify all registered callbacks
         | 
| 47 50 | 
             
                        this.connectionCallbacks.forEach(callback => {
         | 
| 48 51 | 
             
                            try {
         | 
| @@ -75,7 +78,7 @@ class SocketManager { | |
| 75 78 | 
             
                 */
         | 
| 76 79 | 
             
                handleConnectionStatusChange(status, type) {
         | 
| 77 80 | 
             
                    this.updateConnectionStatus(status, type);
         | 
| 78 | 
            -
             | 
| 81 | 
            +
             | 
| 79 82 | 
             
                    // Set up git branch listener when connected
         | 
| 80 83 | 
             
                    if (type === 'connected' && this.socketClient && this.socketClient.socket) {
         | 
| 81 84 | 
             
                        this.setupGitBranchListener();
         | 
| @@ -87,7 +90,7 @@ class SocketManager { | |
| 87 90 | 
             
                 */
         | 
| 88 91 | 
             
                updateInitialConnectionStatus() {
         | 
| 89 92 | 
             
                    console.log('SocketManager: Updating initial connection status');
         | 
| 90 | 
            -
             | 
| 93 | 
            +
             | 
| 91 94 | 
             
                    // Force status check on socket client (uses fallback mechanism)
         | 
| 92 95 | 
             
                    if (this.socketClient && typeof this.socketClient.checkAndUpdateStatus === 'function') {
         | 
| 93 96 | 
             
                        console.log('SocketManager: Using socket client checkAndUpdateStatus method');
         | 
| @@ -99,7 +102,7 @@ class SocketManager { | |
| 99 102 | 
             
                            isConnecting: this.socketClient.isConnecting,
         | 
| 100 103 | 
             
                            isConnected: this.socketClient.isConnected
         | 
| 101 104 | 
             
                        });
         | 
| 102 | 
            -
             | 
| 105 | 
            +
             | 
| 103 106 | 
             
                        if (this.socketClient.socket.connected) {
         | 
| 104 107 | 
             
                            console.log('SocketManager: Socket is already connected, updating status');
         | 
| 105 108 | 
             
                            this.updateConnectionStatus('Connected', 'connected');
         | 
| @@ -114,7 +117,7 @@ class SocketManager { | |
| 114 117 | 
             
                        console.log('SocketManager: No socket client or socket found, setting disconnected status');
         | 
| 115 118 | 
             
                        this.updateConnectionStatus('Disconnected', 'disconnected');
         | 
| 116 119 | 
             
                    }
         | 
| 117 | 
            -
             | 
| 120 | 
            +
             | 
| 118 121 | 
             
                    // Additional fallback - check again after a longer delay in case connection is still establishing
         | 
| 119 122 | 
             
                    setTimeout(() => {
         | 
| 120 123 | 
             
                        console.log('SocketManager: Secondary status check after 1 second');
         | 
| @@ -131,7 +134,7 @@ class SocketManager { | |
| 131 134 | 
             
                setupGitBranchListener() {
         | 
| 132 135 | 
             
                    // Remove any existing listener first
         | 
| 133 136 | 
             
                    this.socketClient.socket.off('git_branch_response');
         | 
| 134 | 
            -
             | 
| 137 | 
            +
             | 
| 135 138 | 
             
                    // Add the listener
         | 
| 136 139 | 
             
                    this.socketClient.socket.on('git_branch_response', (data) => {
         | 
| 137 140 | 
             
                        if (data.success) {
         | 
| @@ -166,7 +169,7 @@ class SocketManager { | |
| 166 169 | 
             
                            // If no span, just update text content
         | 
| 167 170 | 
             
                            statusElement.textContent = status;
         | 
| 168 171 | 
             
                        }
         | 
| 169 | 
            -
             | 
| 172 | 
            +
             | 
| 170 173 | 
             
                        statusElement.className = `status-badge status-${type}`;
         | 
| 171 174 | 
             
                        console.log(`SocketManager: UI updated - status: '${status}' (${type})`);
         | 
| 172 175 | 
             
                    } else {
         | 
| @@ -263,10 +266,10 @@ class SocketManager { | |
| 263 266 | 
             
                toggleConnectionControls() {
         | 
| 264 267 | 
             
                    const controlsRow = document.getElementById('connection-controls-row');
         | 
| 265 268 | 
             
                    const toggleBtn = document.getElementById('connection-toggle-btn');
         | 
| 266 | 
            -
             | 
| 269 | 
            +
             | 
| 267 270 | 
             
                    if (controlsRow && toggleBtn) {
         | 
| 268 271 | 
             
                        const isVisible = controlsRow.classList.contains('show');
         | 
| 269 | 
            -
             | 
| 272 | 
            +
             | 
| 270 273 | 
             
                        if (isVisible) {
         | 
| 271 274 | 
             
                            controlsRow.classList.remove('show');
         | 
| 272 275 | 
             
                            controlsRow.style.display = 'none';
         | 
| @@ -315,7 +318,7 @@ class SocketManager { | |
| 315 318 | 
             
                initializeFromURL(params) {
         | 
| 316 319 | 
             
                    const port = params.get('port');
         | 
| 317 320 | 
             
                    const portInput = document.getElementById('port-input');
         | 
| 318 | 
            -
             | 
| 321 | 
            +
             | 
| 319 322 | 
             
                    // Determine the port to use:
         | 
| 320 323 | 
             
                    // 1. URL parameter 'port'
         | 
| 321 324 | 
             
                    // 2. Current page port (if served via HTTP)
         | 
| @@ -328,7 +331,7 @@ class SocketManager { | |
| 328 331 | 
             
                    if (!connectPort) {
         | 
| 329 332 | 
             
                        connectPort = portInput?.value || '8765';
         | 
| 330 333 | 
             
                    }
         | 
| 331 | 
            -
             | 
| 334 | 
            +
             | 
| 332 335 | 
             
                    // Update the port input field with the determined port
         | 
| 333 336 | 
             
                    if (portInput) {
         | 
| 334 337 | 
             
                        portInput.value = connectPort;
         | 
| @@ -340,4 +343,8 @@ class SocketManager { | |
| 340 343 | 
             
                        this.connect(connectPort);
         | 
| 341 344 | 
             
                    }
         | 
| 342 345 | 
             
                }
         | 
| 343 | 
            -
            }
         | 
| 346 | 
            +
            }
         | 
| 347 | 
            +
             | 
| 348 | 
            +
            // ES6 Module export
         | 
| 349 | 
            +
            export { SocketManager };
         | 
| 350 | 
            +
            export default SocketManager;
         | 
| @@ -1,13 +1,13 @@ | |
| 1 1 | 
             
            /**
         | 
| 2 2 | 
             
             * UI State Manager Module
         | 
| 3 | 
            -
             * | 
| 3 | 
            +
             *
         | 
| 4 4 | 
             
             * Manages UI state including tab switching, card selection, keyboard navigation,
         | 
| 5 5 | 
             
             * and visual feedback across the dashboard interface.
         | 
| 6 | 
            -
             * | 
| 6 | 
            +
             *
         | 
| 7 7 | 
             
             * WHY: Extracted from main dashboard to centralize UI state management and
         | 
| 8 8 | 
             
             * provide better separation between business logic and UI state. This makes
         | 
| 9 9 | 
             
             * the UI behavior more predictable and easier to test.
         | 
| 10 | 
            -
             * | 
| 10 | 
            +
             *
         | 
| 11 11 | 
             
             * DESIGN DECISION: Maintains centralized state for current tab, selected cards,
         | 
| 12 12 | 
             
             * and navigation context while providing a clean API for other modules to
         | 
| 13 13 | 
             
             * interact with UI state changes.
         | 
| @@ -16,10 +16,10 @@ class UIStateManager { | |
| 16 16 | 
             
                constructor() {
         | 
| 17 17 | 
             
                    // Current active tab
         | 
| 18 18 | 
             
                    this.currentTab = 'events';
         | 
| 19 | 
            -
             | 
| 19 | 
            +
             | 
| 20 20 | 
             
                    // Auto-scroll behavior
         | 
| 21 21 | 
             
                    this.autoScroll = true;
         | 
| 22 | 
            -
             | 
| 22 | 
            +
             | 
| 23 23 | 
             
                    // Selection state - tracks the currently selected card across all tabs
         | 
| 24 24 | 
             
                    this.selectedCard = {
         | 
| 25 25 | 
             
                        tab: null,        // which tab the selection is in
         | 
| @@ -27,7 +27,7 @@ class UIStateManager { | |
| 27 27 | 
             
                        type: null,       // 'event', 'agent', 'tool', 'file'
         | 
| 28 28 | 
             
                        data: null        // the actual data object
         | 
| 29 29 | 
             
                    };
         | 
| 30 | 
            -
             | 
| 30 | 
            +
             | 
| 31 31 | 
             
                    // Navigation state for each tab
         | 
| 32 32 | 
             
                    this.tabNavigation = {
         | 
| 33 33 | 
             
                        events: { selectedIndex: -1, items: [] },
         | 
| @@ -67,7 +67,7 @@ class UIStateManager { | |
| 67 67 | 
             
                setupUnifiedKeyboardNavigation() {
         | 
| 68 68 | 
             
                    document.addEventListener('keydown', (e) => {
         | 
| 69 69 | 
             
                        // Only handle if not in an input field
         | 
| 70 | 
            -
                        if (document.activeElement && | 
| 70 | 
            +
                        if (document.activeElement &&
         | 
| 71 71 | 
             
                            ['INPUT', 'TEXTAREA', 'SELECT'].includes(document.activeElement.tagName)) {
         | 
| 72 72 | 
             
                            return;
         | 
| 73 73 | 
             
                        }
         | 
| @@ -130,7 +130,7 @@ class UIStateManager { | |
| 130 130 |  | 
| 131 131 | 
             
                    // Trigger tab change event for other modules
         | 
| 132 132 | 
             
                    document.dispatchEvent(new CustomEvent('tabChanged', {
         | 
| 133 | 
            -
                        detail: { | 
| 133 | 
            +
                        detail: {
         | 
| 134 134 | 
             
                            newTab: tabName,
         | 
| 135 135 | 
             
                            previousTab: previousTab
         | 
| 136 136 | 
             
                        }
         | 
| @@ -153,10 +153,10 @@ class UIStateManager { | |
| 153 153 | 
             
                    if (!tabNav) return;
         | 
| 154 154 |  | 
| 155 155 | 
             
                    let newIndex = tabNav.selectedIndex + direction;
         | 
| 156 | 
            -
             | 
| 156 | 
            +
             | 
| 157 157 | 
             
                    // Handle bounds
         | 
| 158 158 | 
             
                    if (tabNav.items.length === 0) return;
         | 
| 159 | 
            -
             | 
| 159 | 
            +
             | 
| 160 160 | 
             
                    if (newIndex < 0) {
         | 
| 161 161 | 
             
                        newIndex = tabNav.items.length - 1;
         | 
| 162 162 | 
             
                    } else if (newIndex >= tabNav.items.length) {
         | 
| @@ -187,7 +187,7 @@ class UIStateManager { | |
| 187 187 | 
             
                    Object.keys(this.tabNavigation).forEach(tabName => {
         | 
| 188 188 | 
             
                        this.tabNavigation[tabName].selectedIndex = -1;
         | 
| 189 189 | 
             
                    });
         | 
| 190 | 
            -
             | 
| 190 | 
            +
             | 
| 191 191 | 
             
                    // Clear card selection
         | 
| 192 192 | 
             
                    this.clearCardSelection();
         | 
| 193 193 | 
             
                }
         | 
| @@ -232,7 +232,7 @@ class UIStateManager { | |
| 232 232 |  | 
| 233 233 | 
             
                    // Update navigation state
         | 
| 234 234 | 
             
                    tabNav.selectedIndex = index;
         | 
| 235 | 
            -
             | 
| 235 | 
            +
             | 
| 236 236 | 
             
                    // Update visual selection
         | 
| 237 237 | 
             
                    this.updateUnifiedSelectionUI();
         | 
| 238 238 |  | 
| @@ -288,7 +288,7 @@ class UIStateManager { | |
| 288 288 | 
             
                selectCard(tabName, index, type, data) {
         | 
| 289 289 | 
             
                    // Clear previous selection
         | 
| 290 290 | 
             
                    this.clearCardSelection();
         | 
| 291 | 
            -
             | 
| 291 | 
            +
             | 
| 292 292 | 
             
                    // Update selection state
         | 
| 293 293 | 
             
                    this.selectedCard = {
         | 
| 294 294 | 
             
                        tab: tabName,
         | 
| @@ -298,7 +298,7 @@ class UIStateManager { | |
| 298 298 | 
             
                    };
         | 
| 299 299 |  | 
| 300 300 | 
             
                    this.updateCardSelectionUI();
         | 
| 301 | 
            -
             | 
| 301 | 
            +
             | 
| 302 302 | 
             
                    console.log('Card selected:', this.selectedCard);
         | 
| 303 303 | 
             
                }
         | 
| 304 304 |  | 
| @@ -310,7 +310,7 @@ class UIStateManager { | |
| 310 310 | 
             
                    document.querySelectorAll('.event-item.selected, .file-item.selected').forEach(el => {
         | 
| 311 311 | 
             
                        el.classList.remove('selected');
         | 
| 312 312 | 
             
                    });
         | 
| 313 | 
            -
             | 
| 313 | 
            +
             | 
| 314 314 | 
             
                    // Reset selection state
         | 
| 315 315 | 
             
                    this.selectedCard = {
         | 
| 316 316 | 
             
                        tab: null,
         | 
| @@ -325,7 +325,7 @@ class UIStateManager { | |
| 325 325 | 
             
                 */
         | 
| 326 326 | 
             
                updateCardSelectionUI() {
         | 
| 327 327 | 
             
                    if (!this.selectedCard.tab || this.selectedCard.index === null) return;
         | 
| 328 | 
            -
             | 
| 328 | 
            +
             | 
| 329 329 | 
             
                    // Get the list container for the selected tab
         | 
| 330 330 | 
             
                    let listContainer;
         | 
| 331 331 | 
             
                    switch (this.selectedCard.tab) {
         | 
| @@ -342,7 +342,7 @@ class UIStateManager { | |
| 342 342 | 
             
                            listContainer = document.getElementById('files-list');
         | 
| 343 343 | 
             
                            break;
         | 
| 344 344 | 
             
                    }
         | 
| 345 | 
            -
             | 
| 345 | 
            +
             | 
| 346 346 | 
             
                    if (listContainer) {
         | 
| 347 347 | 
             
                        const items = listContainer.querySelectorAll('.event-item, .file-item');
         | 
| 348 348 | 
             
                        if (items[this.selectedCard.index]) {
         | 
| @@ -424,4 +424,7 @@ class UIStateManager { | |
| 424 424 | 
             
                getAutoScroll() {
         | 
| 425 425 | 
             
                    return this.autoScroll;
         | 
| 426 426 | 
             
                }
         | 
| 427 | 
            -
            }
         | 
| 427 | 
            +
            }
         | 
| 428 | 
            +
            // ES6 Module export
         | 
| 429 | 
            +
            export { UIStateManager };
         | 
| 430 | 
            +
            export default UIStateManager;
         |