claude-mpm 4.1.0__py3-none-any.whl → 4.1.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- claude_mpm/BUILD_NUMBER +1 -1
- claude_mpm/VERSION +1 -1
- claude_mpm/__main__.py +1 -1
- claude_mpm/agents/BASE_PM.md +74 -46
- claude_mpm/agents/INSTRUCTIONS.md +11 -153
- claude_mpm/agents/WORKFLOW.md +61 -321
- claude_mpm/agents/__init__.py +11 -11
- claude_mpm/agents/agent_loader.py +23 -20
- claude_mpm/agents/agent_loader_integration.py +1 -1
- claude_mpm/agents/agents_metadata.py +27 -0
- claude_mpm/agents/async_agent_loader.py +5 -8
- claude_mpm/agents/base_agent_loader.py +36 -25
- claude_mpm/agents/frontmatter_validator.py +6 -6
- claude_mpm/agents/schema/agent_schema.json +1 -1
- claude_mpm/agents/system_agent_config.py +9 -9
- claude_mpm/agents/templates/api_qa.json +47 -2
- claude_mpm/agents/templates/imagemagick.json +256 -0
- claude_mpm/agents/templates/qa.json +41 -2
- claude_mpm/agents/templates/ticketing.json +5 -5
- claude_mpm/agents/templates/web_qa.json +133 -58
- claude_mpm/agents/templates/web_ui.json +3 -3
- claude_mpm/cli/__init__.py +51 -46
- claude_mpm/cli/__main__.py +1 -1
- claude_mpm/cli/commands/__init__.py +10 -12
- claude_mpm/cli/commands/agent_manager.py +186 -181
- claude_mpm/cli/commands/agents.py +271 -268
- claude_mpm/cli/commands/aggregate.py +30 -29
- claude_mpm/cli/commands/cleanup.py +50 -44
- claude_mpm/cli/commands/cleanup_orphaned_agents.py +25 -25
- claude_mpm/cli/commands/config.py +162 -127
- claude_mpm/cli/commands/doctor.py +52 -62
- claude_mpm/cli/commands/info.py +37 -25
- claude_mpm/cli/commands/mcp.py +3 -7
- claude_mpm/cli/commands/mcp_command_router.py +14 -18
- claude_mpm/cli/commands/mcp_install_commands.py +28 -23
- claude_mpm/cli/commands/mcp_pipx_config.py +58 -49
- claude_mpm/cli/commands/mcp_server_commands.py +23 -17
- claude_mpm/cli/commands/memory.py +192 -141
- claude_mpm/cli/commands/monitor.py +117 -88
- claude_mpm/cli/commands/run.py +120 -84
- claude_mpm/cli/commands/run_config_checker.py +4 -5
- claude_mpm/cli/commands/socketio_monitor.py +17 -19
- claude_mpm/cli/commands/tickets.py +92 -92
- claude_mpm/cli/parser.py +1 -5
- claude_mpm/cli/parsers/__init__.py +1 -1
- claude_mpm/cli/parsers/agent_manager_parser.py +50 -98
- claude_mpm/cli/parsers/agents_parser.py +2 -3
- claude_mpm/cli/parsers/base_parser.py +7 -5
- claude_mpm/cli/parsers/mcp_parser.py +4 -2
- claude_mpm/cli/parsers/monitor_parser.py +26 -18
- claude_mpm/cli/shared/__init__.py +10 -10
- claude_mpm/cli/shared/argument_patterns.py +57 -71
- claude_mpm/cli/shared/base_command.py +61 -53
- claude_mpm/cli/shared/error_handling.py +62 -58
- claude_mpm/cli/shared/output_formatters.py +78 -77
- claude_mpm/cli/startup_logging.py +204 -172
- claude_mpm/cli/utils.py +10 -11
- claude_mpm/cli_module/__init__.py +1 -1
- claude_mpm/cli_module/args.py +1 -1
- claude_mpm/cli_module/migration_example.py +5 -5
- claude_mpm/config/__init__.py +9 -9
- claude_mpm/config/agent_config.py +15 -14
- claude_mpm/config/experimental_features.py +4 -4
- claude_mpm/config/paths.py +0 -1
- claude_mpm/config/socketio_config.py +5 -6
- claude_mpm/constants.py +1 -2
- claude_mpm/core/__init__.py +8 -8
- claude_mpm/core/agent_name_normalizer.py +1 -1
- claude_mpm/core/agent_registry.py +20 -23
- claude_mpm/core/agent_session_manager.py +3 -3
- claude_mpm/core/base_service.py +7 -15
- claude_mpm/core/cache.py +4 -6
- claude_mpm/core/claude_runner.py +85 -113
- claude_mpm/core/config.py +43 -28
- claude_mpm/core/config_aliases.py +0 -9
- claude_mpm/core/config_constants.py +52 -30
- claude_mpm/core/constants.py +0 -1
- claude_mpm/core/container.py +18 -27
- claude_mpm/core/exceptions.py +2 -2
- claude_mpm/core/factories.py +10 -12
- claude_mpm/core/framework_loader.py +581 -280
- claude_mpm/core/hook_manager.py +26 -22
- claude_mpm/core/hook_performance_config.py +58 -47
- claude_mpm/core/injectable_service.py +1 -1
- claude_mpm/core/interactive_session.py +61 -152
- claude_mpm/core/interfaces.py +1 -100
- claude_mpm/core/lazy.py +5 -5
- claude_mpm/core/log_manager.py +587 -0
- claude_mpm/core/logger.py +125 -8
- claude_mpm/core/logging_config.py +15 -15
- claude_mpm/core/minimal_framework_loader.py +5 -8
- claude_mpm/core/oneshot_session.py +15 -33
- claude_mpm/core/optimized_agent_loader.py +4 -6
- claude_mpm/core/optimized_startup.py +2 -1
- claude_mpm/core/output_style_manager.py +147 -106
- claude_mpm/core/pm_hook_interceptor.py +0 -1
- claude_mpm/core/service_registry.py +11 -8
- claude_mpm/core/session_manager.py +1 -2
- claude_mpm/core/shared/__init__.py +1 -1
- claude_mpm/core/shared/config_loader.py +101 -97
- claude_mpm/core/shared/path_resolver.py +72 -68
- claude_mpm/core/shared/singleton_manager.py +56 -50
- claude_mpm/core/socketio_pool.py +26 -6
- claude_mpm/core/tool_access_control.py +4 -5
- claude_mpm/core/typing_utils.py +50 -59
- claude_mpm/core/unified_agent_registry.py +14 -19
- claude_mpm/core/unified_config.py +4 -6
- claude_mpm/core/unified_paths.py +197 -109
- claude_mpm/dashboard/open_dashboard.py +2 -4
- claude_mpm/experimental/cli_enhancements.py +51 -36
- claude_mpm/generators/agent_profile_generator.py +2 -4
- claude_mpm/hooks/base_hook.py +1 -2
- claude_mpm/hooks/claude_hooks/connection_pool.py +72 -26
- claude_mpm/hooks/claude_hooks/event_handlers.py +93 -38
- claude_mpm/hooks/claude_hooks/hook_handler.py +130 -76
- claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +104 -77
- claude_mpm/hooks/claude_hooks/memory_integration.py +2 -4
- claude_mpm/hooks/claude_hooks/response_tracking.py +15 -11
- claude_mpm/hooks/claude_hooks/tool_analysis.py +12 -18
- claude_mpm/hooks/memory_integration_hook.py +5 -5
- claude_mpm/hooks/tool_call_interceptor.py +1 -1
- claude_mpm/hooks/validation_hooks.py +4 -4
- claude_mpm/init.py +4 -9
- claude_mpm/models/__init__.py +2 -2
- claude_mpm/models/agent_session.py +11 -14
- claude_mpm/scripts/mcp_server.py +20 -11
- claude_mpm/scripts/mcp_wrapper.py +5 -5
- claude_mpm/scripts/mpm_doctor.py +321 -0
- claude_mpm/scripts/socketio_daemon.py +28 -25
- claude_mpm/scripts/socketio_daemon_hardened.py +298 -258
- claude_mpm/scripts/socketio_server_manager.py +116 -95
- claude_mpm/services/__init__.py +49 -49
- claude_mpm/services/agent_capabilities_service.py +12 -18
- claude_mpm/services/agents/__init__.py +22 -22
- claude_mpm/services/agents/agent_builder.py +140 -119
- claude_mpm/services/agents/deployment/__init__.py +3 -3
- claude_mpm/services/agents/deployment/agent_config_provider.py +9 -9
- claude_mpm/services/agents/deployment/agent_configuration_manager.py +19 -20
- claude_mpm/services/agents/deployment/agent_definition_factory.py +1 -5
- claude_mpm/services/agents/deployment/agent_deployment.py +136 -106
- claude_mpm/services/agents/deployment/agent_discovery_service.py +4 -8
- claude_mpm/services/agents/deployment/agent_environment_manager.py +2 -7
- claude_mpm/services/agents/deployment/agent_filesystem_manager.py +6 -10
- claude_mpm/services/agents/deployment/agent_format_converter.py +11 -15
- claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +2 -3
- claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +5 -5
- claude_mpm/services/agents/deployment/agent_metrics_collector.py +13 -19
- claude_mpm/services/agents/deployment/agent_restore_handler.py +0 -1
- claude_mpm/services/agents/deployment/agent_template_builder.py +26 -35
- claude_mpm/services/agents/deployment/agent_validator.py +0 -1
- claude_mpm/services/agents/deployment/agent_version_manager.py +7 -9
- claude_mpm/services/agents/deployment/agent_versioning.py +3 -3
- claude_mpm/services/agents/deployment/agents_directory_resolver.py +6 -7
- claude_mpm/services/agents/deployment/async_agent_deployment.py +51 -38
- claude_mpm/services/agents/deployment/config/__init__.py +1 -1
- claude_mpm/services/agents/deployment/config/deployment_config.py +7 -8
- claude_mpm/services/agents/deployment/deployment_type_detector.py +1 -1
- claude_mpm/services/agents/deployment/deployment_wrapper.py +18 -18
- claude_mpm/services/agents/deployment/facade/__init__.py +1 -1
- claude_mpm/services/agents/deployment/facade/deployment_executor.py +0 -3
- claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -4
- claude_mpm/services/agents/deployment/interface_adapter.py +5 -7
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +345 -276
- claude_mpm/services/agents/deployment/pipeline/__init__.py +2 -2
- claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +1 -1
- claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +6 -4
- claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +3 -3
- claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +2 -2
- claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +14 -13
- claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +0 -1
- claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +1 -1
- claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +8 -9
- claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +1 -1
- claude_mpm/services/agents/deployment/processors/__init__.py +1 -1
- claude_mpm/services/agents/deployment/processors/agent_processor.py +20 -16
- claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +5 -12
- claude_mpm/services/agents/deployment/results/__init__.py +1 -1
- claude_mpm/services/agents/deployment/results/deployment_result_builder.py +1 -1
- claude_mpm/services/agents/deployment/strategies/__init__.py +2 -2
- claude_mpm/services/agents/deployment/strategies/base_strategy.py +1 -7
- claude_mpm/services/agents/deployment/strategies/project_strategy.py +1 -4
- claude_mpm/services/agents/deployment/strategies/system_strategy.py +2 -3
- claude_mpm/services/agents/deployment/strategies/user_strategy.py +3 -7
- claude_mpm/services/agents/deployment/validation/__init__.py +1 -1
- claude_mpm/services/agents/deployment/validation/agent_validator.py +1 -1
- claude_mpm/services/agents/deployment/validation/template_validator.py +2 -2
- claude_mpm/services/agents/deployment/validation/validation_result.py +2 -6
- claude_mpm/services/agents/loading/__init__.py +1 -1
- claude_mpm/services/agents/loading/agent_profile_loader.py +6 -12
- claude_mpm/services/agents/loading/base_agent_manager.py +5 -5
- claude_mpm/services/agents/loading/framework_agent_loader.py +2 -4
- claude_mpm/services/agents/management/__init__.py +1 -1
- claude_mpm/services/agents/management/agent_capabilities_generator.py +1 -3
- claude_mpm/services/agents/management/agent_management_service.py +5 -9
- claude_mpm/services/agents/memory/__init__.py +4 -4
- claude_mpm/services/agents/memory/agent_memory_manager.py +280 -160
- claude_mpm/services/agents/memory/agent_persistence_service.py +0 -2
- claude_mpm/services/agents/memory/content_manager.py +44 -38
- claude_mpm/services/agents/memory/template_generator.py +4 -6
- claude_mpm/services/agents/registry/__init__.py +10 -6
- claude_mpm/services/agents/registry/deployed_agent_discovery.py +30 -27
- claude_mpm/services/agents/registry/modification_tracker.py +3 -6
- claude_mpm/services/async_session_logger.py +1 -2
- claude_mpm/services/claude_session_logger.py +1 -2
- claude_mpm/services/command_deployment_service.py +173 -0
- claude_mpm/services/command_handler_service.py +20 -22
- claude_mpm/services/core/__init__.py +25 -25
- claude_mpm/services/core/base.py +0 -5
- claude_mpm/services/core/interfaces/__init__.py +32 -32
- claude_mpm/services/core/interfaces/agent.py +0 -21
- claude_mpm/services/core/interfaces/communication.py +0 -27
- claude_mpm/services/core/interfaces/infrastructure.py +0 -56
- claude_mpm/services/core/interfaces/service.py +0 -29
- claude_mpm/services/diagnostics/__init__.py +1 -1
- claude_mpm/services/diagnostics/checks/__init__.py +6 -6
- claude_mpm/services/diagnostics/checks/agent_check.py +89 -80
- claude_mpm/services/diagnostics/checks/base_check.py +12 -16
- claude_mpm/services/diagnostics/checks/claude_desktop_check.py +84 -81
- claude_mpm/services/diagnostics/checks/common_issues_check.py +99 -91
- claude_mpm/services/diagnostics/checks/configuration_check.py +82 -77
- claude_mpm/services/diagnostics/checks/filesystem_check.py +67 -68
- claude_mpm/services/diagnostics/checks/installation_check.py +254 -94
- claude_mpm/services/diagnostics/checks/mcp_check.py +90 -88
- claude_mpm/services/diagnostics/checks/monitor_check.py +75 -76
- claude_mpm/services/diagnostics/checks/startup_log_check.py +67 -73
- claude_mpm/services/diagnostics/diagnostic_runner.py +67 -59
- claude_mpm/services/diagnostics/doctor_reporter.py +107 -70
- claude_mpm/services/diagnostics/models.py +21 -19
- claude_mpm/services/event_aggregator.py +10 -17
- claude_mpm/services/event_bus/__init__.py +1 -1
- claude_mpm/services/event_bus/config.py +54 -35
- claude_mpm/services/event_bus/event_bus.py +76 -71
- claude_mpm/services/event_bus/relay.py +74 -64
- claude_mpm/services/events/__init__.py +11 -11
- claude_mpm/services/events/consumers/__init__.py +3 -3
- claude_mpm/services/events/consumers/dead_letter.py +71 -63
- claude_mpm/services/events/consumers/logging.py +39 -37
- claude_mpm/services/events/consumers/metrics.py +56 -57
- claude_mpm/services/events/consumers/socketio.py +82 -81
- claude_mpm/services/events/core.py +110 -99
- claude_mpm/services/events/interfaces.py +56 -72
- claude_mpm/services/events/producers/__init__.py +1 -1
- claude_mpm/services/events/producers/hook.py +38 -38
- claude_mpm/services/events/producers/system.py +46 -44
- claude_mpm/services/exceptions.py +81 -80
- claude_mpm/services/framework_claude_md_generator/__init__.py +2 -4
- claude_mpm/services/framework_claude_md_generator/content_assembler.py +3 -5
- claude_mpm/services/framework_claude_md_generator/content_validator.py +1 -1
- claude_mpm/services/framework_claude_md_generator/deployment_manager.py +4 -4
- claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +0 -1
- claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +0 -2
- claude_mpm/services/framework_claude_md_generator/version_manager.py +4 -5
- claude_mpm/services/hook_service.py +6 -9
- claude_mpm/services/infrastructure/__init__.py +1 -1
- claude_mpm/services/infrastructure/context_preservation.py +8 -12
- claude_mpm/services/infrastructure/monitoring.py +21 -23
- claude_mpm/services/mcp_gateway/__init__.py +37 -37
- claude_mpm/services/mcp_gateway/auto_configure.py +95 -103
- claude_mpm/services/mcp_gateway/config/__init__.py +1 -1
- claude_mpm/services/mcp_gateway/config/config_loader.py +23 -25
- claude_mpm/services/mcp_gateway/config/config_schema.py +5 -5
- claude_mpm/services/mcp_gateway/config/configuration.py +9 -6
- claude_mpm/services/mcp_gateway/core/__init__.py +10 -10
- claude_mpm/services/mcp_gateway/core/base.py +0 -3
- claude_mpm/services/mcp_gateway/core/interfaces.py +1 -38
- claude_mpm/services/mcp_gateway/core/process_pool.py +99 -93
- claude_mpm/services/mcp_gateway/core/singleton_manager.py +65 -62
- claude_mpm/services/mcp_gateway/core/startup_verification.py +75 -74
- claude_mpm/services/mcp_gateway/main.py +2 -1
- claude_mpm/services/mcp_gateway/registry/service_registry.py +5 -8
- claude_mpm/services/mcp_gateway/registry/tool_registry.py +1 -1
- claude_mpm/services/mcp_gateway/server/__init__.py +1 -1
- claude_mpm/services/mcp_gateway/server/mcp_gateway.py +12 -19
- claude_mpm/services/mcp_gateway/server/stdio_handler.py +4 -3
- claude_mpm/services/mcp_gateway/server/stdio_server.py +79 -71
- claude_mpm/services/mcp_gateway/tools/__init__.py +2 -2
- claude_mpm/services/mcp_gateway/tools/base_adapter.py +5 -6
- claude_mpm/services/mcp_gateway/tools/document_summarizer.py +13 -22
- claude_mpm/services/mcp_gateway/tools/health_check_tool.py +79 -78
- claude_mpm/services/mcp_gateway/tools/hello_world.py +12 -14
- claude_mpm/services/mcp_gateway/tools/ticket_tools.py +42 -49
- claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +51 -55
- claude_mpm/services/memory/__init__.py +3 -3
- claude_mpm/services/memory/builder.py +3 -6
- claude_mpm/services/memory/cache/__init__.py +1 -1
- claude_mpm/services/memory/cache/shared_prompt_cache.py +3 -5
- claude_mpm/services/memory/cache/simple_cache.py +1 -1
- claude_mpm/services/memory/indexed_memory.py +5 -7
- claude_mpm/services/memory/optimizer.py +7 -10
- claude_mpm/services/memory/router.py +8 -9
- claude_mpm/services/memory_hook_service.py +48 -34
- claude_mpm/services/monitor_build_service.py +77 -73
- claude_mpm/services/port_manager.py +130 -108
- claude_mpm/services/project/analyzer.py +12 -10
- claude_mpm/services/project/registry.py +11 -11
- claude_mpm/services/recovery_manager.py +10 -19
- claude_mpm/services/response_tracker.py +0 -1
- claude_mpm/services/runner_configuration_service.py +19 -20
- claude_mpm/services/session_management_service.py +7 -11
- claude_mpm/services/shared/__init__.py +1 -1
- claude_mpm/services/shared/async_service_base.py +58 -50
- claude_mpm/services/shared/config_service_base.py +73 -67
- claude_mpm/services/shared/lifecycle_service_base.py +82 -78
- claude_mpm/services/shared/manager_base.py +94 -82
- claude_mpm/services/shared/service_factory.py +96 -98
- claude_mpm/services/socketio/__init__.py +3 -3
- claude_mpm/services/socketio/client_proxy.py +5 -5
- claude_mpm/services/socketio/event_normalizer.py +199 -181
- claude_mpm/services/socketio/handlers/__init__.py +3 -3
- claude_mpm/services/socketio/handlers/base.py +5 -4
- claude_mpm/services/socketio/handlers/connection.py +163 -136
- claude_mpm/services/socketio/handlers/file.py +13 -14
- claude_mpm/services/socketio/handlers/git.py +12 -7
- claude_mpm/services/socketio/handlers/hook.py +49 -44
- claude_mpm/services/socketio/handlers/memory.py +0 -1
- claude_mpm/services/socketio/handlers/project.py +0 -1
- claude_mpm/services/socketio/handlers/registry.py +37 -19
- claude_mpm/services/socketio/migration_utils.py +98 -84
- claude_mpm/services/socketio/server/__init__.py +1 -1
- claude_mpm/services/socketio/server/broadcaster.py +81 -87
- claude_mpm/services/socketio/server/core.py +65 -54
- claude_mpm/services/socketio/server/eventbus_integration.py +95 -56
- claude_mpm/services/socketio/server/main.py +64 -38
- claude_mpm/services/socketio_client_manager.py +10 -12
- claude_mpm/services/subprocess_launcher_service.py +4 -7
- claude_mpm/services/system_instructions_service.py +13 -14
- claude_mpm/services/ticket_manager.py +2 -2
- claude_mpm/services/utility_service.py +5 -13
- claude_mpm/services/version_control/__init__.py +16 -16
- claude_mpm/services/version_control/branch_strategy.py +5 -8
- claude_mpm/services/version_control/conflict_resolution.py +9 -23
- claude_mpm/services/version_control/git_operations.py +5 -7
- claude_mpm/services/version_control/semantic_versioning.py +16 -17
- claude_mpm/services/version_control/version_parser.py +13 -18
- claude_mpm/services/version_service.py +10 -11
- claude_mpm/storage/__init__.py +1 -1
- claude_mpm/storage/state_storage.py +22 -28
- claude_mpm/utils/__init__.py +6 -6
- claude_mpm/utils/agent_dependency_loader.py +47 -33
- claude_mpm/utils/config_manager.py +11 -14
- claude_mpm/utils/dependency_cache.py +1 -1
- claude_mpm/utils/dependency_manager.py +13 -17
- claude_mpm/utils/dependency_strategies.py +8 -10
- claude_mpm/utils/environment_context.py +3 -9
- claude_mpm/utils/error_handler.py +3 -13
- claude_mpm/utils/file_utils.py +1 -1
- claude_mpm/utils/path_operations.py +8 -12
- claude_mpm/utils/robust_installer.py +110 -33
- claude_mpm/utils/subprocess_utils.py +5 -6
- claude_mpm/validation/agent_validator.py +3 -6
- claude_mpm/validation/frontmatter_validator.py +1 -1
- {claude_mpm-4.1.0.dist-info → claude_mpm-4.1.2.dist-info}/METADATA +1 -1
- claude_mpm-4.1.2.dist-info/RECORD +498 -0
- claude_mpm-4.1.0.dist-info/RECORD +0 -494
- {claude_mpm-4.1.0.dist-info → claude_mpm-4.1.2.dist-info}/WHEEL +0 -0
- {claude_mpm-4.1.0.dist-info → claude_mpm-4.1.2.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.1.0.dist-info → claude_mpm-4.1.2.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.1.0.dist-info → claude_mpm-4.1.2.dist-info}/top_level.txt +0 -0
|
@@ -14,22 +14,22 @@ from ..logger import get_logger
|
|
|
14
14
|
@dataclass
|
|
15
15
|
class ConfigPattern:
|
|
16
16
|
"""Configuration loading pattern definition."""
|
|
17
|
-
|
|
17
|
+
|
|
18
18
|
# File patterns to search for
|
|
19
19
|
filenames: List[str]
|
|
20
|
-
|
|
20
|
+
|
|
21
21
|
# Search paths (relative to working directory)
|
|
22
22
|
search_paths: List[str]
|
|
23
|
-
|
|
23
|
+
|
|
24
24
|
# Environment variable prefix
|
|
25
25
|
env_prefix: Optional[str] = None
|
|
26
|
-
|
|
26
|
+
|
|
27
27
|
# Default values
|
|
28
28
|
defaults: Optional[Dict[str, Any]] = None
|
|
29
|
-
|
|
29
|
+
|
|
30
30
|
# Required configuration keys
|
|
31
31
|
required_keys: Optional[List[str]] = None
|
|
32
|
-
|
|
32
|
+
|
|
33
33
|
# Configuration section name
|
|
34
34
|
section: Optional[str] = None
|
|
35
35
|
|
|
@@ -37,87 +37,77 @@ class ConfigPattern:
|
|
|
37
37
|
class ConfigLoader:
|
|
38
38
|
"""
|
|
39
39
|
Centralized configuration loading utility.
|
|
40
|
-
|
|
40
|
+
|
|
41
41
|
Reduces duplication by providing standard patterns for:
|
|
42
42
|
- Configuration file discovery
|
|
43
43
|
- Environment variable loading
|
|
44
44
|
- Default value management
|
|
45
45
|
- Configuration validation
|
|
46
46
|
"""
|
|
47
|
-
|
|
47
|
+
|
|
48
48
|
# Standard configuration patterns
|
|
49
49
|
AGENT_CONFIG = ConfigPattern(
|
|
50
50
|
filenames=[".agent.yaml", ".agent.yml", "agent.yaml", "agent.yml"],
|
|
51
51
|
search_paths=[".", ".claude-mpm", "agents"],
|
|
52
52
|
env_prefix="CLAUDE_MPM_AGENT_",
|
|
53
|
-
defaults={
|
|
54
|
-
|
|
55
|
-
"max_retries": 3,
|
|
56
|
-
"log_level": "INFO"
|
|
57
|
-
},
|
|
58
|
-
required_keys=["name", "model"]
|
|
53
|
+
defaults={"timeout": 30, "max_retries": 3, "log_level": "INFO"},
|
|
54
|
+
required_keys=["name", "model"],
|
|
59
55
|
)
|
|
60
|
-
|
|
56
|
+
|
|
61
57
|
MEMORY_CONFIG = ConfigPattern(
|
|
62
58
|
filenames=[".memory.yaml", ".memory.yml", "memory.yaml", "memory.yml"],
|
|
63
59
|
search_paths=[".", ".claude-mpm", "memories"],
|
|
64
60
|
env_prefix="CLAUDE_MPM_MEMORY_",
|
|
65
|
-
defaults={
|
|
66
|
-
"max_entries": 1000,
|
|
67
|
-
"cleanup_interval": 3600,
|
|
68
|
-
"compression": True
|
|
69
|
-
}
|
|
61
|
+
defaults={"max_entries": 1000, "cleanup_interval": 3600, "compression": True},
|
|
70
62
|
)
|
|
71
|
-
|
|
63
|
+
|
|
72
64
|
SERVICE_CONFIG = ConfigPattern(
|
|
73
65
|
filenames=[".service.yaml", ".service.yml", "service.yaml", "service.yml"],
|
|
74
66
|
search_paths=[".", ".claude-mpm", "config"],
|
|
75
67
|
env_prefix="CLAUDE_MPM_SERVICE_",
|
|
76
|
-
defaults={
|
|
77
|
-
"enabled": True,
|
|
78
|
-
"auto_start": False,
|
|
79
|
-
"health_check_interval": 60
|
|
80
|
-
}
|
|
68
|
+
defaults={"enabled": True, "auto_start": False, "health_check_interval": 60},
|
|
81
69
|
)
|
|
82
|
-
|
|
83
|
-
def __init__(self, working_dir: Union[str, Path] = None):
|
|
70
|
+
|
|
71
|
+
def __init__(self, working_dir: Optional[Union[str, Path]] = None):
|
|
84
72
|
"""
|
|
85
73
|
Initialize config loader.
|
|
86
|
-
|
|
74
|
+
|
|
87
75
|
Args:
|
|
88
76
|
working_dir: Working directory for relative paths
|
|
89
77
|
"""
|
|
90
78
|
self.working_dir = Path(working_dir) if working_dir else Path.cwd()
|
|
91
79
|
self.logger = get_logger("config_loader")
|
|
92
80
|
self._cache: Dict[str, Config] = {}
|
|
93
|
-
|
|
94
|
-
def load_config(
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
81
|
+
|
|
82
|
+
def load_config(
|
|
83
|
+
self,
|
|
84
|
+
pattern: ConfigPattern,
|
|
85
|
+
cache_key: Optional[str] = None,
|
|
86
|
+
force_reload: bool = False,
|
|
87
|
+
) -> Config:
|
|
98
88
|
"""
|
|
99
89
|
Load configuration using a pattern.
|
|
100
|
-
|
|
90
|
+
|
|
101
91
|
Args:
|
|
102
92
|
pattern: Configuration pattern to use
|
|
103
93
|
cache_key: Optional cache key (defaults to pattern hash)
|
|
104
94
|
force_reload: Force reload even if cached
|
|
105
|
-
|
|
95
|
+
|
|
106
96
|
Returns:
|
|
107
97
|
Loaded configuration
|
|
108
98
|
"""
|
|
109
99
|
# Generate cache key if not provided
|
|
110
100
|
if cache_key is None:
|
|
111
101
|
cache_key = self._generate_cache_key(pattern)
|
|
112
|
-
|
|
102
|
+
|
|
113
103
|
# Check cache
|
|
114
104
|
if not force_reload and cache_key in self._cache:
|
|
115
105
|
self.logger.debug(f"Using cached config: {cache_key}")
|
|
116
106
|
return self._cache[cache_key]
|
|
117
|
-
|
|
107
|
+
|
|
118
108
|
# Start with defaults
|
|
119
109
|
config_data = pattern.defaults.copy() if pattern.defaults else {}
|
|
120
|
-
|
|
110
|
+
|
|
121
111
|
# Load from files
|
|
122
112
|
config_file = self._find_config_file(pattern)
|
|
123
113
|
if config_file:
|
|
@@ -126,27 +116,29 @@ class ConfigLoader:
|
|
|
126
116
|
file_config = file_config.get(pattern.section, {})
|
|
127
117
|
config_data.update(file_config)
|
|
128
118
|
self.logger.info(f"Loaded config from: {config_file}")
|
|
129
|
-
|
|
119
|
+
|
|
130
120
|
# Load from environment
|
|
131
121
|
if pattern.env_prefix:
|
|
132
122
|
env_config = self._load_env_config(pattern.env_prefix)
|
|
133
123
|
config_data.update(env_config)
|
|
134
124
|
if env_config:
|
|
135
|
-
self.logger.debug(
|
|
136
|
-
|
|
125
|
+
self.logger.debug(
|
|
126
|
+
f"Loaded {len(env_config)} env vars with prefix {pattern.env_prefix}"
|
|
127
|
+
)
|
|
128
|
+
|
|
137
129
|
# Create config instance
|
|
138
130
|
config = Config(config_data)
|
|
139
|
-
|
|
131
|
+
|
|
140
132
|
# Validate required keys
|
|
141
133
|
if pattern.required_keys:
|
|
142
134
|
self._validate_required_keys(config, pattern.required_keys)
|
|
143
|
-
|
|
135
|
+
|
|
144
136
|
# Cache the result
|
|
145
137
|
self._cache[cache_key] = config
|
|
146
|
-
|
|
138
|
+
|
|
147
139
|
return config
|
|
148
|
-
|
|
149
|
-
def load_agent_config(self, agent_dir: Union[str, Path] = None) -> Config:
|
|
140
|
+
|
|
141
|
+
def load_agent_config(self, agent_dir: Optional[Union[str, Path]] = None) -> Config:
|
|
150
142
|
"""Load agent configuration."""
|
|
151
143
|
pattern = self.AGENT_CONFIG
|
|
152
144
|
if agent_dir:
|
|
@@ -156,22 +148,31 @@ class ConfigLoader:
|
|
|
156
148
|
search_paths=[str(agent_dir)],
|
|
157
149
|
env_prefix=pattern.env_prefix,
|
|
158
150
|
defaults=pattern.defaults,
|
|
159
|
-
required_keys=pattern.required_keys
|
|
151
|
+
required_keys=pattern.required_keys,
|
|
160
152
|
)
|
|
161
|
-
|
|
153
|
+
|
|
162
154
|
return self.load_config(pattern, cache_key=f"agent_{agent_dir}")
|
|
163
155
|
|
|
164
156
|
def load_main_config(self) -> Config:
|
|
165
157
|
"""Load main application configuration."""
|
|
166
158
|
pattern = ConfigPattern(
|
|
167
|
-
filenames=[
|
|
159
|
+
filenames=[
|
|
160
|
+
"claude-mpm.yaml",
|
|
161
|
+
"claude-mpm.yml",
|
|
162
|
+
".claude-mpm.yaml",
|
|
163
|
+
".claude-mpm.yml",
|
|
164
|
+
"config.yaml",
|
|
165
|
+
"config.yml",
|
|
166
|
+
],
|
|
168
167
|
search_paths=["~/.config/claude-mpm", ".", "./config", "/etc/claude-mpm"],
|
|
169
168
|
env_prefix="CLAUDE_MPM_",
|
|
170
|
-
defaults={}
|
|
169
|
+
defaults={},
|
|
171
170
|
)
|
|
172
171
|
return self.load_config(pattern, cache_key="main_config")
|
|
173
172
|
|
|
174
|
-
def load_memory_config(
|
|
173
|
+
def load_memory_config(
|
|
174
|
+
self, memory_dir: Optional[Union[str, Path]] = None
|
|
175
|
+
) -> Config:
|
|
175
176
|
"""Load memory configuration."""
|
|
176
177
|
pattern = self.MEMORY_CONFIG
|
|
177
178
|
if memory_dir:
|
|
@@ -179,130 +180,133 @@ class ConfigLoader:
|
|
|
179
180
|
filenames=pattern.filenames,
|
|
180
181
|
search_paths=[str(memory_dir)],
|
|
181
182
|
env_prefix=pattern.env_prefix,
|
|
182
|
-
defaults=pattern.defaults
|
|
183
|
+
defaults=pattern.defaults,
|
|
183
184
|
)
|
|
184
|
-
|
|
185
|
+
|
|
185
186
|
return self.load_config(pattern, cache_key=f"memory_{memory_dir}")
|
|
186
|
-
|
|
187
|
-
def load_service_config(
|
|
187
|
+
|
|
188
|
+
def load_service_config(
|
|
189
|
+
self, service_name: str, config_dir: Optional[Union[str, Path]] = None
|
|
190
|
+
) -> Config:
|
|
188
191
|
"""Load service configuration."""
|
|
189
192
|
pattern = self.SERVICE_CONFIG
|
|
190
|
-
|
|
193
|
+
|
|
191
194
|
# Add service-specific filenames
|
|
192
195
|
service_filenames = [
|
|
193
196
|
f".{service_name}.yaml",
|
|
194
|
-
f".{service_name}.yml",
|
|
197
|
+
f".{service_name}.yml",
|
|
195
198
|
f"{service_name}.yaml",
|
|
196
|
-
f"{service_name}.yml"
|
|
199
|
+
f"{service_name}.yml",
|
|
197
200
|
]
|
|
198
|
-
|
|
201
|
+
|
|
199
202
|
pattern = ConfigPattern(
|
|
200
203
|
filenames=service_filenames + pattern.filenames,
|
|
201
204
|
search_paths=[str(config_dir)] if config_dir else pattern.search_paths,
|
|
202
205
|
env_prefix=f"CLAUDE_MPM_{service_name.upper()}_",
|
|
203
206
|
defaults=pattern.defaults,
|
|
204
|
-
section=service_name
|
|
207
|
+
section=service_name,
|
|
205
208
|
)
|
|
206
|
-
|
|
209
|
+
|
|
207
210
|
return self.load_config(pattern, cache_key=f"service_{service_name}")
|
|
208
|
-
|
|
211
|
+
|
|
209
212
|
def _find_config_file(self, pattern: ConfigPattern) -> Optional[Path]:
|
|
210
213
|
"""Find configuration file using pattern."""
|
|
211
214
|
for search_path in pattern.search_paths:
|
|
212
215
|
search_dir = self.working_dir / search_path
|
|
213
216
|
if not search_dir.exists():
|
|
214
217
|
continue
|
|
215
|
-
|
|
218
|
+
|
|
216
219
|
for filename in pattern.filenames:
|
|
217
220
|
config_file = search_dir / filename
|
|
218
221
|
if config_file.exists() and config_file.is_file():
|
|
219
222
|
return config_file
|
|
220
|
-
|
|
223
|
+
|
|
221
224
|
return None
|
|
222
|
-
|
|
225
|
+
|
|
223
226
|
def _load_config_file(self, config_file: Path) -> Dict[str, Any]:
|
|
224
227
|
"""Load configuration from file."""
|
|
225
228
|
try:
|
|
226
229
|
import yaml
|
|
227
|
-
|
|
228
|
-
with open(config_file
|
|
229
|
-
if config_file.suffix.lower() in (
|
|
230
|
+
|
|
231
|
+
with open(config_file) as f:
|
|
232
|
+
if config_file.suffix.lower() in (".yaml", ".yml"):
|
|
230
233
|
return yaml.safe_load(f) or {}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
234
|
+
# Try JSON as fallback
|
|
235
|
+
import json
|
|
236
|
+
|
|
237
|
+
f.seek(0)
|
|
238
|
+
return json.load(f)
|
|
239
|
+
|
|
237
240
|
except Exception as e:
|
|
238
241
|
self.logger.error(f"Failed to load config file {config_file}: {e}")
|
|
239
242
|
return {}
|
|
240
|
-
|
|
243
|
+
|
|
241
244
|
def _load_env_config(self, prefix: str) -> Dict[str, Any]:
|
|
242
245
|
"""Load configuration from environment variables."""
|
|
243
246
|
config = {}
|
|
244
|
-
|
|
247
|
+
|
|
245
248
|
for key, value in os.environ.items():
|
|
246
249
|
if key.startswith(prefix):
|
|
247
250
|
# Convert env var name to config key
|
|
248
|
-
config_key = key[len(prefix):].lower().replace(
|
|
249
|
-
|
|
251
|
+
config_key = key[len(prefix) :].lower().replace("_", ".")
|
|
252
|
+
|
|
250
253
|
# Try to parse value
|
|
251
254
|
parsed_value = self._parse_env_value(value)
|
|
252
255
|
config[config_key] = parsed_value
|
|
253
|
-
|
|
256
|
+
|
|
254
257
|
return config
|
|
255
|
-
|
|
258
|
+
|
|
256
259
|
def _parse_env_value(self, value: str) -> Any:
|
|
257
260
|
"""Parse environment variable value."""
|
|
258
261
|
# Try boolean
|
|
259
|
-
if value.lower() in (
|
|
260
|
-
return value.lower() ==
|
|
261
|
-
|
|
262
|
+
if value.lower() in ("true", "false"):
|
|
263
|
+
return value.lower() == "true"
|
|
264
|
+
|
|
262
265
|
# Try integer
|
|
263
266
|
try:
|
|
264
267
|
return int(value)
|
|
265
268
|
except ValueError:
|
|
266
269
|
pass
|
|
267
|
-
|
|
270
|
+
|
|
268
271
|
# Try float
|
|
269
272
|
try:
|
|
270
273
|
return float(value)
|
|
271
274
|
except ValueError:
|
|
272
275
|
pass
|
|
273
|
-
|
|
276
|
+
|
|
274
277
|
# Try JSON
|
|
275
278
|
try:
|
|
276
279
|
import json
|
|
280
|
+
|
|
277
281
|
return json.loads(value)
|
|
278
282
|
except (json.JSONDecodeError, ValueError):
|
|
279
283
|
pass
|
|
280
|
-
|
|
284
|
+
|
|
281
285
|
# Return as string
|
|
282
286
|
return value
|
|
283
|
-
|
|
287
|
+
|
|
284
288
|
def _validate_required_keys(self, config: Config, required_keys: List[str]) -> None:
|
|
285
289
|
"""Validate that required keys are present."""
|
|
286
290
|
missing_keys = []
|
|
287
|
-
|
|
291
|
+
|
|
288
292
|
for key in required_keys:
|
|
289
293
|
if config.get(key) is None:
|
|
290
294
|
missing_keys.append(key)
|
|
291
|
-
|
|
295
|
+
|
|
292
296
|
if missing_keys:
|
|
293
297
|
raise ValueError(f"Missing required configuration keys: {missing_keys}")
|
|
294
|
-
|
|
298
|
+
|
|
295
299
|
def _generate_cache_key(self, pattern: ConfigPattern) -> str:
|
|
296
300
|
"""Generate cache key for pattern."""
|
|
297
301
|
import hashlib
|
|
298
|
-
|
|
302
|
+
|
|
299
303
|
# Create a string representation of the pattern
|
|
300
304
|
pattern_str = f"{pattern.filenames}_{pattern.search_paths}_{pattern.env_prefix}"
|
|
301
|
-
|
|
305
|
+
|
|
302
306
|
# Generate hash
|
|
303
307
|
return hashlib.md5(pattern_str.encode()).hexdigest()[:8]
|
|
304
|
-
|
|
305
|
-
def clear_cache(self, cache_key: str = None) -> None:
|
|
308
|
+
|
|
309
|
+
def clear_cache(self, cache_key: Optional[str] = None) -> None:
|
|
306
310
|
"""Clear configuration cache."""
|
|
307
311
|
if cache_key:
|
|
308
312
|
self._cache.pop(cache_key, None)
|
|
@@ -310,11 +314,11 @@ class ConfigLoader:
|
|
|
310
314
|
else:
|
|
311
315
|
self._cache.clear()
|
|
312
316
|
self.logger.debug("Cleared all config cache")
|
|
313
|
-
|
|
317
|
+
|
|
314
318
|
def get_cache_info(self) -> Dict[str, Any]:
|
|
315
319
|
"""Get cache information."""
|
|
316
320
|
return {
|
|
317
321
|
"cached_configs": len(self._cache),
|
|
318
322
|
"cache_keys": list(self._cache.keys()),
|
|
319
|
-
"working_dir": str(self.working_dir)
|
|
323
|
+
"working_dir": str(self.working_dir),
|
|
320
324
|
}
|