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
| @@ -0,0 +1,351 @@ | |
| 1 | 
            +
            """
         | 
| 2 | 
            +
            Agent Management Interfaces for Claude MPM Framework
         | 
| 3 | 
            +
            ===================================================
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            WHY: This module contains all interfaces related to agent management, deployment,
         | 
| 6 | 
            +
            capabilities, and discovery. These interfaces are grouped together because they
         | 
| 7 | 
            +
            all deal with agent lifecycle and operations.
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            DESIGN DECISION: Agent-related interfaces are separated from infrastructure
         | 
| 10 | 
            +
            because they represent domain-specific functionality rather than foundational
         | 
| 11 | 
            +
            framework services.
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            EXTRACTED FROM: services/core/interfaces.py (lines 198-875)
         | 
| 14 | 
            +
            - Agent registry and metadata
         | 
| 15 | 
            +
            - Agent deployment and capabilities
         | 
| 16 | 
            +
            - Agent system instructions and subprocess management
         | 
| 17 | 
            +
            """
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            from abc import ABC, abstractmethod
         | 
| 20 | 
            +
            from dataclasses import dataclass
         | 
| 21 | 
            +
            from pathlib import Path
         | 
| 22 | 
            +
            from typing import Any, Dict, List, Optional, Tuple
         | 
| 23 | 
            +
             | 
| 24 | 
            +
             | 
| 25 | 
            +
            # Agent registry interface
         | 
| 26 | 
            +
            @dataclass
         | 
| 27 | 
            +
            class AgentMetadata:
         | 
| 28 | 
            +
                """Enhanced agent metadata with specialization and model configuration support"""
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                name: str
         | 
| 31 | 
            +
                type: str
         | 
| 32 | 
            +
                path: str
         | 
| 33 | 
            +
                tier: str
         | 
| 34 | 
            +
                description: Optional[str] = None
         | 
| 35 | 
            +
                version: Optional[str] = None
         | 
| 36 | 
            +
                capabilities: List[str] = None
         | 
| 37 | 
            +
                specializations: List[str] = None
         | 
| 38 | 
            +
                frameworks: List[str] = None
         | 
| 39 | 
            +
                domains: List[str] = None
         | 
| 40 | 
            +
                roles: List[str] = None
         | 
| 41 | 
            +
                is_hybrid: bool = False
         | 
| 42 | 
            +
                validation_score: float = 0.0
         | 
| 43 | 
            +
                last_modified: Optional[float] = None
         | 
| 44 | 
            +
                # Model configuration fields
         | 
| 45 | 
            +
                preferred_model: Optional[str] = None
         | 
| 46 | 
            +
                model_config: Optional[Dict[str, Any]] = None
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                def __post_init__(self):
         | 
| 49 | 
            +
                    if self.capabilities is None:
         | 
| 50 | 
            +
                        self.capabilities = []
         | 
| 51 | 
            +
                    if self.specializations is None:
         | 
| 52 | 
            +
                        self.specializations = []
         | 
| 53 | 
            +
                    if self.frameworks is None:
         | 
| 54 | 
            +
                        self.frameworks = []
         | 
| 55 | 
            +
                    if self.domains is None:
         | 
| 56 | 
            +
                        self.domains = []
         | 
| 57 | 
            +
                    if self.roles is None:
         | 
| 58 | 
            +
                        self.roles = []
         | 
| 59 | 
            +
                    if self.model_config is None:
         | 
| 60 | 
            +
                        self.model_config = {}
         | 
| 61 | 
            +
             | 
| 62 | 
            +
             | 
| 63 | 
            +
            class IAgentRegistry(ABC):
         | 
| 64 | 
            +
                """Interface for agent discovery and management"""
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                @abstractmethod
         | 
| 67 | 
            +
                async def discover_agents(
         | 
| 68 | 
            +
                    self, force_refresh: bool = False
         | 
| 69 | 
            +
                ) -> Dict[str, AgentMetadata]:
         | 
| 70 | 
            +
                    """Discover all available agents"""
         | 
| 71 | 
            +
                    pass
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                @abstractmethod
         | 
| 74 | 
            +
                async def get_agent(self, agent_name: str) -> Optional[AgentMetadata]:
         | 
| 75 | 
            +
                    """Get specific agent metadata"""
         | 
| 76 | 
            +
                    pass
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                @abstractmethod
         | 
| 79 | 
            +
                async def list_agents(
         | 
| 80 | 
            +
                    self, agent_type: Optional[str] = None, tier: Optional[str] = None
         | 
| 81 | 
            +
                ) -> List[AgentMetadata]:
         | 
| 82 | 
            +
                    """List agents with optional filtering"""
         | 
| 83 | 
            +
                    pass
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                @abstractmethod
         | 
| 86 | 
            +
                async def get_specialized_agents(self, agent_type: str) -> List[AgentMetadata]:
         | 
| 87 | 
            +
                    """Get agents of a specific specialized type"""
         | 
| 88 | 
            +
                    pass
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                @abstractmethod
         | 
| 91 | 
            +
                async def refresh_agent_cache(self) -> None:
         | 
| 92 | 
            +
                    """Refresh the agent metadata cache"""
         | 
| 93 | 
            +
                    pass
         | 
| 94 | 
            +
             | 
| 95 | 
            +
             | 
| 96 | 
            +
            # Agent deployment interface
         | 
| 97 | 
            +
            class AgentDeploymentInterface(ABC):
         | 
| 98 | 
            +
                """Interface for agent deployment operations.
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                WHY: Agent deployment needs to be decoupled from concrete implementations
         | 
| 101 | 
            +
                to enable different deployment strategies (local, remote, containerized).
         | 
| 102 | 
            +
                This interface ensures consistency across different deployment backends.
         | 
| 103 | 
            +
             | 
| 104 | 
            +
                DESIGN DECISION: Methods return deployment status/results to enable
         | 
| 105 | 
            +
                proper error handling and rollback operations when deployments fail.
         | 
| 106 | 
            +
                """
         | 
| 107 | 
            +
             | 
| 108 | 
            +
                @abstractmethod
         | 
| 109 | 
            +
                def deploy_agents(
         | 
| 110 | 
            +
                    self, force: bool = False, include_all: bool = False
         | 
| 111 | 
            +
                ) -> Dict[str, Any]:
         | 
| 112 | 
            +
                    """Deploy agents to target environment.
         | 
| 113 | 
            +
             | 
| 114 | 
            +
                    Args:
         | 
| 115 | 
            +
                        force: Force deployment even if agents already exist
         | 
| 116 | 
            +
                        include_all: Include all agents, ignoring exclusion lists
         | 
| 117 | 
            +
             | 
| 118 | 
            +
                    Returns:
         | 
| 119 | 
            +
                        Dictionary with deployment results and status
         | 
| 120 | 
            +
                    """
         | 
| 121 | 
            +
                    pass
         | 
| 122 | 
            +
             | 
| 123 | 
            +
                @abstractmethod
         | 
| 124 | 
            +
                def validate_agent(self, agent_path: Path) -> Tuple[bool, List[str]]:
         | 
| 125 | 
            +
                    """Validate agent configuration and structure.
         | 
| 126 | 
            +
             | 
| 127 | 
            +
                    Args:
         | 
| 128 | 
            +
                        agent_path: Path to agent configuration file
         | 
| 129 | 
            +
             | 
| 130 | 
            +
                    Returns:
         | 
| 131 | 
            +
                        Tuple of (is_valid, list_of_errors)
         | 
| 132 | 
            +
                    """
         | 
| 133 | 
            +
                    pass
         | 
| 134 | 
            +
             | 
| 135 | 
            +
                @abstractmethod
         | 
| 136 | 
            +
                def get_deployment_status(self, agent_name: str) -> Dict[str, Any]:
         | 
| 137 | 
            +
                    """Get deployment status for a specific agent.
         | 
| 138 | 
            +
             | 
| 139 | 
            +
                    Args:
         | 
| 140 | 
            +
                        agent_name: Name of the agent
         | 
| 141 | 
            +
             | 
| 142 | 
            +
                    Returns:
         | 
| 143 | 
            +
                        Dictionary with deployment status information
         | 
| 144 | 
            +
                    """
         | 
| 145 | 
            +
                    pass
         | 
| 146 | 
            +
             | 
| 147 | 
            +
             | 
| 148 | 
            +
            # Agent capabilities interface
         | 
| 149 | 
            +
            class AgentCapabilitiesInterface(ABC):
         | 
| 150 | 
            +
                """Interface for agent capabilities discovery and generation.
         | 
| 151 | 
            +
             | 
| 152 | 
            +
                WHY: Agent capabilities need to be discovered from multiple sources
         | 
| 153 | 
            +
                (system, user, project) and formatted for Claude. This interface
         | 
| 154 | 
            +
                abstracts the discovery and formatting logic to enable different
         | 
| 155 | 
            +
                agent discovery strategies and capability formats.
         | 
| 156 | 
            +
             | 
| 157 | 
            +
                DESIGN DECISION: Returns formatted strings ready for Claude consumption
         | 
| 158 | 
            +
                to minimize processing overhead in the main execution path.
         | 
| 159 | 
            +
                """
         | 
| 160 | 
            +
             | 
| 161 | 
            +
                @abstractmethod
         | 
| 162 | 
            +
                def generate_agent_capabilities(self, agent_type: str = "general") -> str:
         | 
| 163 | 
            +
                    """Generate formatted agent capabilities for Claude.
         | 
| 164 | 
            +
             | 
| 165 | 
            +
                    Args:
         | 
| 166 | 
            +
                        agent_type: Type of agent to generate capabilities for
         | 
| 167 | 
            +
             | 
| 168 | 
            +
                    Returns:
         | 
| 169 | 
            +
                        Formatted capabilities string for Claude consumption
         | 
| 170 | 
            +
                    """
         | 
| 171 | 
            +
                    pass
         | 
| 172 | 
            +
             | 
| 173 | 
            +
             | 
| 174 | 
            +
            # System instructions interface
         | 
| 175 | 
            +
            class SystemInstructionsInterface(ABC):
         | 
| 176 | 
            +
                """Interface for system instructions loading and processing.
         | 
| 177 | 
            +
             | 
| 178 | 
            +
                WHY: System instructions need to be loaded from multiple sources
         | 
| 179 | 
            +
                (project, framework) with template processing and metadata stripping.
         | 
| 180 | 
            +
                This interface abstracts the loading and processing logic to enable
         | 
| 181 | 
            +
                different instruction sources and processing strategies.
         | 
| 182 | 
            +
             | 
| 183 | 
            +
                DESIGN DECISION: Provides both raw and processed instruction methods
         | 
| 184 | 
            +
                to support different use cases and enable caching of processed results.
         | 
| 185 | 
            +
                """
         | 
| 186 | 
            +
             | 
| 187 | 
            +
                @abstractmethod
         | 
| 188 | 
            +
                def load_system_instructions(self, instruction_type: str = "default") -> str:
         | 
| 189 | 
            +
                    """Load and process system instructions.
         | 
| 190 | 
            +
             | 
| 191 | 
            +
                    Args:
         | 
| 192 | 
            +
                        instruction_type: Type of instructions to load
         | 
| 193 | 
            +
             | 
| 194 | 
            +
                    Returns:
         | 
| 195 | 
            +
                        Processed system instructions string
         | 
| 196 | 
            +
                    """
         | 
| 197 | 
            +
                    pass
         | 
| 198 | 
            +
             | 
| 199 | 
            +
                @abstractmethod
         | 
| 200 | 
            +
                def get_available_instruction_types(self) -> List[str]:
         | 
| 201 | 
            +
                    """Get list of available instruction types.
         | 
| 202 | 
            +
             | 
| 203 | 
            +
                    Returns:
         | 
| 204 | 
            +
                        List of available instruction type names
         | 
| 205 | 
            +
                    """
         | 
| 206 | 
            +
                    pass
         | 
| 207 | 
            +
             | 
| 208 | 
            +
                @abstractmethod
         | 
| 209 | 
            +
                def validate_instructions(self, instructions: str) -> Tuple[bool, List[str]]:
         | 
| 210 | 
            +
                    """Validate system instructions format and content.
         | 
| 211 | 
            +
             | 
| 212 | 
            +
                    Args:
         | 
| 213 | 
            +
                        instructions: Instructions content to validate
         | 
| 214 | 
            +
             | 
| 215 | 
            +
                    Returns:
         | 
| 216 | 
            +
                        Tuple of (is_valid, list_of_errors)
         | 
| 217 | 
            +
                    """
         | 
| 218 | 
            +
                    pass
         | 
| 219 | 
            +
             | 
| 220 | 
            +
             | 
| 221 | 
            +
            # Subprocess launcher interface
         | 
| 222 | 
            +
            class SubprocessLauncherInterface(ABC):
         | 
| 223 | 
            +
                """Interface for subprocess launching and PTY management.
         | 
| 224 | 
            +
             | 
| 225 | 
            +
                WHY: Subprocess launching involves complex PTY management, signal handling,
         | 
| 226 | 
            +
                and I/O coordination. This interface abstracts the subprocess launching
         | 
| 227 | 
            +
                logic to enable different launching strategies and improve testability.
         | 
| 228 | 
            +
             | 
| 229 | 
            +
                DESIGN DECISION: Provides both synchronous and asynchronous launch methods
         | 
| 230 | 
            +
                to support different execution contexts and performance requirements.
         | 
| 231 | 
            +
                """
         | 
| 232 | 
            +
             | 
| 233 | 
            +
                @abstractmethod
         | 
| 234 | 
            +
                def launch_subprocess(self, command: List[str], **kwargs) -> Dict[str, Any]:
         | 
| 235 | 
            +
                    """Launch a subprocess with PTY support.
         | 
| 236 | 
            +
             | 
| 237 | 
            +
                    Args:
         | 
| 238 | 
            +
                        command: Command and arguments to execute
         | 
| 239 | 
            +
                        **kwargs: Additional subprocess options
         | 
| 240 | 
            +
             | 
| 241 | 
            +
                    Returns:
         | 
| 242 | 
            +
                        Dictionary with subprocess information and handles
         | 
| 243 | 
            +
                    """
         | 
| 244 | 
            +
                    pass
         | 
| 245 | 
            +
             | 
| 246 | 
            +
                @abstractmethod
         | 
| 247 | 
            +
                async def launch_subprocess_async(
         | 
| 248 | 
            +
                    self, command: List[str], **kwargs
         | 
| 249 | 
            +
                ) -> Dict[str, Any]:
         | 
| 250 | 
            +
                    """Launch a subprocess asynchronously with PTY support.
         | 
| 251 | 
            +
             | 
| 252 | 
            +
                    Args:
         | 
| 253 | 
            +
                        command: Command and arguments to execute
         | 
| 254 | 
            +
                        **kwargs: Additional subprocess options
         | 
| 255 | 
            +
             | 
| 256 | 
            +
                    Returns:
         | 
| 257 | 
            +
                        Dictionary with subprocess information and handles
         | 
| 258 | 
            +
                    """
         | 
| 259 | 
            +
                    pass
         | 
| 260 | 
            +
             | 
| 261 | 
            +
                @abstractmethod
         | 
| 262 | 
            +
                def terminate_subprocess(self, process_id: str) -> bool:
         | 
| 263 | 
            +
                    """Terminate a running subprocess.
         | 
| 264 | 
            +
             | 
| 265 | 
            +
                    Args:
         | 
| 266 | 
            +
                        process_id: ID of the process to terminate
         | 
| 267 | 
            +
             | 
| 268 | 
            +
                    Returns:
         | 
| 269 | 
            +
                        True if termination successful
         | 
| 270 | 
            +
                    """
         | 
| 271 | 
            +
                    pass
         | 
| 272 | 
            +
             | 
| 273 | 
            +
                @abstractmethod
         | 
| 274 | 
            +
                def get_subprocess_status(self, process_id: str) -> Dict[str, Any]:
         | 
| 275 | 
            +
                    """Get status of a running subprocess.
         | 
| 276 | 
            +
             | 
| 277 | 
            +
                    Args:
         | 
| 278 | 
            +
                        process_id: ID of the process
         | 
| 279 | 
            +
             | 
| 280 | 
            +
                    Returns:
         | 
| 281 | 
            +
                        Dictionary with process status information
         | 
| 282 | 
            +
                    """
         | 
| 283 | 
            +
                    pass
         | 
| 284 | 
            +
             | 
| 285 | 
            +
             | 
| 286 | 
            +
            # Runner configuration interface
         | 
| 287 | 
            +
            class RunnerConfigurationInterface(ABC):
         | 
| 288 | 
            +
                """Interface for runner configuration and initialization.
         | 
| 289 | 
            +
             | 
| 290 | 
            +
                WHY: ClaudeRunner initialization involves complex service registration,
         | 
| 291 | 
            +
                configuration loading, and logger setup. This interface abstracts the
         | 
| 292 | 
            +
                configuration logic to enable different configuration strategies and
         | 
| 293 | 
            +
                improve testability.
         | 
| 294 | 
            +
             | 
| 295 | 
            +
                DESIGN DECISION: Separates configuration loading from service registration
         | 
| 296 | 
            +
                to enable independent testing and different configuration sources.
         | 
| 297 | 
            +
                """
         | 
| 298 | 
            +
             | 
| 299 | 
            +
                @abstractmethod
         | 
| 300 | 
            +
                def initialize_runner(self, config: Dict[str, Any]) -> Dict[str, Any]:
         | 
| 301 | 
            +
                    """Initialize runner with configuration.
         | 
| 302 | 
            +
             | 
| 303 | 
            +
                    Args:
         | 
| 304 | 
            +
                        config: Configuration dictionary
         | 
| 305 | 
            +
             | 
| 306 | 
            +
                    Returns:
         | 
| 307 | 
            +
                        Dictionary with initialization results
         | 
| 308 | 
            +
                    """
         | 
| 309 | 
            +
                    pass
         | 
| 310 | 
            +
             | 
| 311 | 
            +
                @abstractmethod
         | 
| 312 | 
            +
                def register_services(self, service_container) -> None:
         | 
| 313 | 
            +
                    """Register services with the dependency injection container.
         | 
| 314 | 
            +
             | 
| 315 | 
            +
                    Args:
         | 
| 316 | 
            +
                        service_container: Service container for registration
         | 
| 317 | 
            +
                    """
         | 
| 318 | 
            +
                    pass
         | 
| 319 | 
            +
             | 
| 320 | 
            +
                @abstractmethod
         | 
| 321 | 
            +
                def load_configuration(self, config_path: Optional[Path] = None) -> Dict[str, Any]:
         | 
| 322 | 
            +
                    """Load configuration from file or defaults.
         | 
| 323 | 
            +
             | 
| 324 | 
            +
                    Args:
         | 
| 325 | 
            +
                        config_path: Optional path to configuration file
         | 
| 326 | 
            +
             | 
| 327 | 
            +
                    Returns:
         | 
| 328 | 
            +
                        Loaded configuration dictionary
         | 
| 329 | 
            +
                    """
         | 
| 330 | 
            +
                    pass
         | 
| 331 | 
            +
             | 
| 332 | 
            +
                @abstractmethod
         | 
| 333 | 
            +
                def validate_configuration(self, config: Dict[str, Any]) -> Tuple[bool, List[str]]:
         | 
| 334 | 
            +
                    """Validate configuration structure and values.
         | 
| 335 | 
            +
             | 
| 336 | 
            +
                    Args:
         | 
| 337 | 
            +
                        config: Configuration to validate
         | 
| 338 | 
            +
             | 
| 339 | 
            +
                    Returns:
         | 
| 340 | 
            +
                        Tuple of (is_valid, list_of_errors)
         | 
| 341 | 
            +
                    """
         | 
| 342 | 
            +
                    pass
         | 
| 343 | 
            +
             | 
| 344 | 
            +
                @abstractmethod
         | 
| 345 | 
            +
                def setup_logging(self, config: Dict[str, Any]) -> None:
         | 
| 346 | 
            +
                    """Setup logging configuration.
         | 
| 347 | 
            +
             | 
| 348 | 
            +
                    Args:
         | 
| 349 | 
            +
                        config: Logging configuration
         | 
| 350 | 
            +
                    """
         | 
| 351 | 
            +
                    pass
         | 
| @@ -0,0 +1,343 @@ | |
| 1 | 
            +
            """
         | 
| 2 | 
            +
            Communication and External Service Interfaces for Claude MPM Framework
         | 
| 3 | 
            +
            ======================================================================
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            WHY: This module contains interfaces for external communication including
         | 
| 6 | 
            +
            WebSocket/SocketIO services, project analysis, and ticket management.
         | 
| 7 | 
            +
            These are grouped together because they handle external interactions.
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            DESIGN DECISION: Communication interfaces are separated because they deal
         | 
| 10 | 
            +
            with external systems and protocols, requiring different error handling
         | 
| 11 | 
            +
            and reliability patterns than internal services.
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            EXTRACTED FROM: services/core/interfaces.py (lines 1195-1397)
         | 
| 14 | 
            +
            - WebSocket/SocketIO communication
         | 
| 15 | 
            +
            - Project analysis
         | 
| 16 | 
            +
            - Ticket management
         | 
| 17 | 
            +
            """
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            from abc import ABC, abstractmethod
         | 
| 20 | 
            +
            from pathlib import Path
         | 
| 21 | 
            +
            from typing import Any, Dict, List, Optional
         | 
| 22 | 
            +
             | 
| 23 | 
            +
             | 
| 24 | 
            +
            # WebSocket/SocketIO service interface
         | 
| 25 | 
            +
            class SocketIOServiceInterface(ABC):
         | 
| 26 | 
            +
                """Interface for WebSocket communication.
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                WHY: Real-time communication is essential for monitoring and interactive
         | 
| 29 | 
            +
                features. This interface abstracts WebSocket/SocketIO implementation to
         | 
| 30 | 
            +
                enable different transport mechanisms and fallback strategies.
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                DESIGN DECISION: Provides both broadcasting and targeted messaging to
         | 
| 33 | 
            +
                support different communication patterns and enable efficient updates.
         | 
| 34 | 
            +
                """
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                @abstractmethod
         | 
| 37 | 
            +
                def start_sync(self) -> None:
         | 
| 38 | 
            +
                    """Start the WebSocket server synchronously."""
         | 
| 39 | 
            +
                    pass
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                @abstractmethod
         | 
| 42 | 
            +
                def stop_sync(self) -> None:
         | 
| 43 | 
            +
                    """Stop the WebSocket server synchronously."""
         | 
| 44 | 
            +
                    pass
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                @abstractmethod
         | 
| 47 | 
            +
                def broadcast_event(self, event_type: str, data: Dict[str, Any]) -> None:
         | 
| 48 | 
            +
                    """Broadcast an event to all connected clients.
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                    Args:
         | 
| 51 | 
            +
                        event_type: Type of event to broadcast
         | 
| 52 | 
            +
                        data: Event data to send
         | 
| 53 | 
            +
                    """
         | 
| 54 | 
            +
                    pass
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                @abstractmethod
         | 
| 57 | 
            +
                def send_to_client(
         | 
| 58 | 
            +
                    self, client_id: str, event_type: str, data: Dict[str, Any]
         | 
| 59 | 
            +
                ) -> bool:
         | 
| 60 | 
            +
                    """Send an event to a specific client.
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                    Args:
         | 
| 63 | 
            +
                        client_id: ID of the target client
         | 
| 64 | 
            +
                        event_type: Type of event to send
         | 
| 65 | 
            +
                        data: Event data to send
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                    Returns:
         | 
| 68 | 
            +
                        True if message sent successfully
         | 
| 69 | 
            +
                    """
         | 
| 70 | 
            +
                    pass
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                @abstractmethod
         | 
| 73 | 
            +
                def get_connection_count(self) -> int:
         | 
| 74 | 
            +
                    """Get number of connected clients.
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                    Returns:
         | 
| 77 | 
            +
                        Number of connected clients
         | 
| 78 | 
            +
                    """
         | 
| 79 | 
            +
                    pass
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                @abstractmethod
         | 
| 82 | 
            +
                def is_running(self) -> bool:
         | 
| 83 | 
            +
                    """Check if server is running.
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                    Returns:
         | 
| 86 | 
            +
                        True if server is active
         | 
| 87 | 
            +
                    """
         | 
| 88 | 
            +
                    pass
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                @abstractmethod
         | 
| 91 | 
            +
                def session_started(
         | 
| 92 | 
            +
                    self, session_id: str, launch_method: str, working_dir: str
         | 
| 93 | 
            +
                ) -> None:
         | 
| 94 | 
            +
                    """Notify that a session has started.
         | 
| 95 | 
            +
             | 
| 96 | 
            +
                    Args:
         | 
| 97 | 
            +
                        session_id: ID of the started session
         | 
| 98 | 
            +
                        launch_method: Method used to launch the session
         | 
| 99 | 
            +
                        working_dir: Working directory of the session
         | 
| 100 | 
            +
                    """
         | 
| 101 | 
            +
                    pass
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                @abstractmethod
         | 
| 104 | 
            +
                def session_ended(self) -> None:
         | 
| 105 | 
            +
                    """Notify that a session has ended."""
         | 
| 106 | 
            +
                    pass
         | 
| 107 | 
            +
             | 
| 108 | 
            +
                @abstractmethod
         | 
| 109 | 
            +
                def claude_status_changed(
         | 
| 110 | 
            +
                    self, status: str, pid: Optional[int] = None, message: str = ""
         | 
| 111 | 
            +
                ) -> None:
         | 
| 112 | 
            +
                    """Notify Claude status change.
         | 
| 113 | 
            +
             | 
| 114 | 
            +
                    Args:
         | 
| 115 | 
            +
                        status: New status of Claude
         | 
| 116 | 
            +
                        pid: Process ID if applicable
         | 
| 117 | 
            +
                        message: Optional status message
         | 
| 118 | 
            +
                    """
         | 
| 119 | 
            +
                    pass
         | 
| 120 | 
            +
             | 
| 121 | 
            +
                @abstractmethod
         | 
| 122 | 
            +
                def agent_delegated(self, agent: str, task: str, status: str = "started") -> None:
         | 
| 123 | 
            +
                    """Notify agent delegation.
         | 
| 124 | 
            +
             | 
| 125 | 
            +
                    Args:
         | 
| 126 | 
            +
                        agent: Name of the delegated agent
         | 
| 127 | 
            +
                        task: Task assigned to the agent
         | 
| 128 | 
            +
                        status: Status of the delegation
         | 
| 129 | 
            +
                    """
         | 
| 130 | 
            +
                    pass
         | 
| 131 | 
            +
             | 
| 132 | 
            +
                @abstractmethod
         | 
| 133 | 
            +
                def todo_updated(self, todos: List[Dict[str, Any]]) -> None:
         | 
| 134 | 
            +
                    """Notify todo list update.
         | 
| 135 | 
            +
             | 
| 136 | 
            +
                    Args:
         | 
| 137 | 
            +
                        todos: Updated list of todo items
         | 
| 138 | 
            +
                    """
         | 
| 139 | 
            +
                    pass
         | 
| 140 | 
            +
             | 
| 141 | 
            +
             | 
| 142 | 
            +
            # Project analyzer interface
         | 
| 143 | 
            +
            class ProjectAnalyzerInterface(ABC):
         | 
| 144 | 
            +
                """Interface for project analysis operations.
         | 
| 145 | 
            +
             | 
| 146 | 
            +
                WHY: Understanding project structure and characteristics is essential for
         | 
| 147 | 
            +
                context-aware agent behavior. This interface abstracts project analysis
         | 
| 148 | 
            +
                to support different project types and structures.
         | 
| 149 | 
            +
             | 
| 150 | 
            +
                DESIGN DECISION: Analysis methods return structured data to enable caching
         | 
| 151 | 
            +
                and incremental updates when project structure changes.
         | 
| 152 | 
            +
                """
         | 
| 153 | 
            +
             | 
| 154 | 
            +
                @abstractmethod
         | 
| 155 | 
            +
                def analyze_project(self, project_path: Path) -> Dict[str, Any]:
         | 
| 156 | 
            +
                    """Analyze project structure and characteristics.
         | 
| 157 | 
            +
             | 
| 158 | 
            +
                    Args:
         | 
| 159 | 
            +
                        project_path: Path to the project root
         | 
| 160 | 
            +
             | 
| 161 | 
            +
                    Returns:
         | 
| 162 | 
            +
                        Dictionary with project analysis results
         | 
| 163 | 
            +
                    """
         | 
| 164 | 
            +
                    pass
         | 
| 165 | 
            +
             | 
| 166 | 
            +
                @abstractmethod
         | 
| 167 | 
            +
                def detect_technology_stack(self) -> List[str]:
         | 
| 168 | 
            +
                    """Detect technologies used in the project.
         | 
| 169 | 
            +
             | 
| 170 | 
            +
                    Returns:
         | 
| 171 | 
            +
                        List of detected technologies
         | 
| 172 | 
            +
                    """
         | 
| 173 | 
            +
                    pass
         | 
| 174 | 
            +
             | 
| 175 | 
            +
                @abstractmethod
         | 
| 176 | 
            +
                def analyze_code_patterns(self) -> Dict[str, Any]:
         | 
| 177 | 
            +
                    """Analyze code patterns and conventions.
         | 
| 178 | 
            +
             | 
| 179 | 
            +
                    Returns:
         | 
| 180 | 
            +
                        Dictionary of pattern analysis results
         | 
| 181 | 
            +
                    """
         | 
| 182 | 
            +
                    pass
         | 
| 183 | 
            +
             | 
| 184 | 
            +
                @abstractmethod
         | 
| 185 | 
            +
                def get_project_structure(self) -> Dict[str, Any]:
         | 
| 186 | 
            +
                    """Get project directory structure analysis.
         | 
| 187 | 
            +
             | 
| 188 | 
            +
                    Returns:
         | 
| 189 | 
            +
                        Dictionary representing project structure
         | 
| 190 | 
            +
                    """
         | 
| 191 | 
            +
                    pass
         | 
| 192 | 
            +
             | 
| 193 | 
            +
                @abstractmethod
         | 
| 194 | 
            +
                def identify_entry_points(self) -> List[Path]:
         | 
| 195 | 
            +
                    """Identify project entry points.
         | 
| 196 | 
            +
             | 
| 197 | 
            +
                    Returns:
         | 
| 198 | 
            +
                        List of entry point paths
         | 
| 199 | 
            +
                    """
         | 
| 200 | 
            +
                    pass
         | 
| 201 | 
            +
             | 
| 202 | 
            +
                @abstractmethod
         | 
| 203 | 
            +
                def get_dependencies(self) -> Dict[str, List[str]]:
         | 
| 204 | 
            +
                    """Get project dependencies by type.
         | 
| 205 | 
            +
             | 
| 206 | 
            +
                    Returns:
         | 
| 207 | 
            +
                        Dictionary mapping dependency types to lists of dependencies
         | 
| 208 | 
            +
                    """
         | 
| 209 | 
            +
                    pass
         | 
| 210 | 
            +
             | 
| 211 | 
            +
                @abstractmethod
         | 
| 212 | 
            +
                def analyze_test_coverage(self) -> Dict[str, Any]:
         | 
| 213 | 
            +
                    """Analyze test coverage if available.
         | 
| 214 | 
            +
             | 
| 215 | 
            +
                    Returns:
         | 
| 216 | 
            +
                        Dictionary with test coverage information
         | 
| 217 | 
            +
                    """
         | 
| 218 | 
            +
                    pass
         | 
| 219 | 
            +
             | 
| 220 | 
            +
                @abstractmethod
         | 
| 221 | 
            +
                def get_build_configuration(self) -> Dict[str, Any]:
         | 
| 222 | 
            +
                    """Get build configuration information.
         | 
| 223 | 
            +
             | 
| 224 | 
            +
                    Returns:
         | 
| 225 | 
            +
                        Dictionary with build configuration details
         | 
| 226 | 
            +
                    """
         | 
| 227 | 
            +
                    pass
         | 
| 228 | 
            +
             | 
| 229 | 
            +
             | 
| 230 | 
            +
            # Ticket manager interface
         | 
| 231 | 
            +
            class TicketManagerInterface(ABC):
         | 
| 232 | 
            +
                """Interface for ticket management operations.
         | 
| 233 | 
            +
             | 
| 234 | 
            +
                WHY: Ticket management provides work tracking and organization. This
         | 
| 235 | 
            +
                interface abstracts ticket operations to support different backend
         | 
| 236 | 
            +
                systems (file-based, API-based, database).
         | 
| 237 | 
            +
             | 
| 238 | 
            +
                DESIGN DECISION: Ticket operations return success/failure status to enable
         | 
| 239 | 
            +
                proper error handling and fallback strategies when ticket systems are unavailable.
         | 
| 240 | 
            +
                """
         | 
| 241 | 
            +
             | 
| 242 | 
            +
                @abstractmethod
         | 
| 243 | 
            +
                def create_ticket(
         | 
| 244 | 
            +
                    self, title: str, description: str, priority: str = "medium"
         | 
| 245 | 
            +
                ) -> str:
         | 
| 246 | 
            +
                    """Create a new ticket.
         | 
| 247 | 
            +
             | 
| 248 | 
            +
                    Args:
         | 
| 249 | 
            +
                        title: Ticket title
         | 
| 250 | 
            +
                        description: Ticket description
         | 
| 251 | 
            +
                        priority: Ticket priority level
         | 
| 252 | 
            +
             | 
| 253 | 
            +
                    Returns:
         | 
| 254 | 
            +
                        Ticket ID
         | 
| 255 | 
            +
                    """
         | 
| 256 | 
            +
                    pass
         | 
| 257 | 
            +
             | 
| 258 | 
            +
                @abstractmethod
         | 
| 259 | 
            +
                def get_ticket(self, ticket_id: str) -> Optional[Dict[str, Any]]:
         | 
| 260 | 
            +
                    """Get ticket by ID.
         | 
| 261 | 
            +
             | 
| 262 | 
            +
                    Args:
         | 
| 263 | 
            +
                        ticket_id: ID of ticket to retrieve
         | 
| 264 | 
            +
             | 
| 265 | 
            +
                    Returns:
         | 
| 266 | 
            +
                        Ticket data or None if not found
         | 
| 267 | 
            +
                    """
         | 
| 268 | 
            +
                    pass
         | 
| 269 | 
            +
             | 
| 270 | 
            +
                @abstractmethod
         | 
| 271 | 
            +
                def update_ticket(self, ticket_id: str, updates: Dict[str, Any]) -> bool:
         | 
| 272 | 
            +
                    """Update ticket information.
         | 
| 273 | 
            +
             | 
| 274 | 
            +
                    Args:
         | 
| 275 | 
            +
                        ticket_id: ID of ticket to update
         | 
| 276 | 
            +
                        updates: Dictionary of fields to update
         | 
| 277 | 
            +
             | 
| 278 | 
            +
                    Returns:
         | 
| 279 | 
            +
                        True if update successful
         | 
| 280 | 
            +
                    """
         | 
| 281 | 
            +
                    pass
         | 
| 282 | 
            +
             | 
| 283 | 
            +
                @abstractmethod
         | 
| 284 | 
            +
                def list_tickets(
         | 
| 285 | 
            +
                    self, status: Optional[str] = None, priority: Optional[str] = None
         | 
| 286 | 
            +
                ) -> List[Dict[str, Any]]:
         | 
| 287 | 
            +
                    """List tickets with optional filtering.
         | 
| 288 | 
            +
             | 
| 289 | 
            +
                    Args:
         | 
| 290 | 
            +
                        status: Optional status filter
         | 
| 291 | 
            +
                        priority: Optional priority filter
         | 
| 292 | 
            +
             | 
| 293 | 
            +
                    Returns:
         | 
| 294 | 
            +
                        List of ticket data
         | 
| 295 | 
            +
                    """
         | 
| 296 | 
            +
                    pass
         | 
| 297 | 
            +
             | 
| 298 | 
            +
                @abstractmethod
         | 
| 299 | 
            +
                def assign_ticket(self, ticket_id: str, assignee: str) -> bool:
         | 
| 300 | 
            +
                    """Assign ticket to a user.
         | 
| 301 | 
            +
             | 
| 302 | 
            +
                    Args:
         | 
| 303 | 
            +
                        ticket_id: ID of ticket to assign
         | 
| 304 | 
            +
                        assignee: User to assign ticket to
         | 
| 305 | 
            +
             | 
| 306 | 
            +
                    Returns:
         | 
| 307 | 
            +
                        True if assignment successful
         | 
| 308 | 
            +
                    """
         | 
| 309 | 
            +
                    pass
         | 
| 310 | 
            +
             | 
| 311 | 
            +
                @abstractmethod
         | 
| 312 | 
            +
                def close_ticket(self, ticket_id: str, resolution: Optional[str] = None) -> bool:
         | 
| 313 | 
            +
                    """Close a ticket.
         | 
| 314 | 
            +
             | 
| 315 | 
            +
                    Args:
         | 
| 316 | 
            +
                        ticket_id: ID of ticket to close
         | 
| 317 | 
            +
                        resolution: Optional resolution description
         | 
| 318 | 
            +
             | 
| 319 | 
            +
                    Returns:
         | 
| 320 | 
            +
                        True if close successful
         | 
| 321 | 
            +
                    """
         | 
| 322 | 
            +
                    pass
         | 
| 323 | 
            +
             | 
| 324 | 
            +
                @abstractmethod
         | 
| 325 | 
            +
                def search_tickets(self, query: str) -> List[Dict[str, Any]]:
         | 
| 326 | 
            +
                    """Search tickets by query.
         | 
| 327 | 
            +
             | 
| 328 | 
            +
                    Args:
         | 
| 329 | 
            +
                        query: Search query string
         | 
| 330 | 
            +
             | 
| 331 | 
            +
                    Returns:
         | 
| 332 | 
            +
                        List of matching ticket data
         | 
| 333 | 
            +
                    """
         | 
| 334 | 
            +
                    pass
         | 
| 335 | 
            +
             | 
| 336 | 
            +
                @abstractmethod
         | 
| 337 | 
            +
                def get_ticket_statistics(self) -> Dict[str, Any]:
         | 
| 338 | 
            +
                    """Get ticket statistics.
         | 
| 339 | 
            +
             | 
| 340 | 
            +
                    Returns:
         | 
| 341 | 
            +
                        Dictionary with ticket statistics
         | 
| 342 | 
            +
                    """
         | 
| 343 | 
            +
                    pass
         |