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
|
@@ -13,9 +13,9 @@ from .agent_versioning import AgentVersionManager
|
|
|
13
13
|
__all__ = [
|
|
14
14
|
"AgentDeploymentService",
|
|
15
15
|
"AgentLifecycleManager",
|
|
16
|
-
"LifecycleState",
|
|
17
|
-
"LifecycleOperation",
|
|
18
16
|
"AgentLifecycleRecord",
|
|
19
|
-
"LifecycleOperationResult",
|
|
20
17
|
"AgentVersionManager",
|
|
18
|
+
"LifecycleOperation",
|
|
19
|
+
"LifecycleOperationResult",
|
|
20
|
+
"LifecycleState",
|
|
21
21
|
]
|
|
@@ -38,18 +38,18 @@ class AgentConfigProvider:
|
|
|
38
38
|
|
|
39
39
|
# Agent-specific tools
|
|
40
40
|
agent_tools = {
|
|
41
|
-
"engineer": base_tools
|
|
42
|
-
"qa": base_tools
|
|
43
|
-
"documentation": base_tools
|
|
44
|
-
"research": base_tools
|
|
45
|
-
"security": base_tools
|
|
46
|
-
"ops": base_tools
|
|
47
|
-
"data_engineer": base_tools
|
|
48
|
-
"version_control": base_tools
|
|
41
|
+
"engineer": [*base_tools, "Bash", "WebSearch", "WebFetch"],
|
|
42
|
+
"qa": [*base_tools, "Bash", "WebSearch"],
|
|
43
|
+
"documentation": [*base_tools, "WebSearch", "WebFetch"],
|
|
44
|
+
"research": [*base_tools, "WebSearch", "WebFetch", "Bash"],
|
|
45
|
+
"security": [*base_tools, "Bash", "WebSearch", "Grep"],
|
|
46
|
+
"ops": [*base_tools, "Bash", "WebSearch"],
|
|
47
|
+
"data_engineer": [*base_tools, "Bash", "WebSearch"],
|
|
48
|
+
"version_control": [*base_tools, "Bash"],
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
# Return specific tools or default set
|
|
52
|
-
return agent_tools.get(agent_name, base_tools
|
|
52
|
+
return agent_tools.get(agent_name, [*base_tools, "Bash", "WebSearch"])
|
|
53
53
|
|
|
54
54
|
@staticmethod
|
|
55
55
|
def get_agent_specific_config(agent_name: str) -> Dict[str, Any]:
|
|
@@ -8,7 +8,6 @@ maintainability and testability.
|
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
import json
|
|
11
|
-
import logging
|
|
12
11
|
from pathlib import Path
|
|
13
12
|
from typing import Any, Dict, List, Optional, Tuple
|
|
14
13
|
|
|
@@ -114,26 +113,26 @@ class AgentConfigurationManager:
|
|
|
114
113
|
# Agent-specific tools based on name patterns
|
|
115
114
|
agent_tools = {
|
|
116
115
|
# Security agents
|
|
117
|
-
"security": base_tools
|
|
118
|
-
"sec": base_tools
|
|
116
|
+
"security": [*base_tools, "SecurityScan", "VulnerabilityCheck"],
|
|
117
|
+
"sec": [*base_tools, "SecurityScan", "VulnerabilityCheck"],
|
|
119
118
|
# QA and testing agents
|
|
120
|
-
"qa": base_tools
|
|
121
|
-
"test": base_tools
|
|
122
|
-
"testing": base_tools
|
|
119
|
+
"qa": [*base_tools, "TestRunner", "CodeAnalysis"],
|
|
120
|
+
"test": [*base_tools, "TestRunner", "CodeAnalysis"],
|
|
121
|
+
"testing": [*base_tools, "TestRunner", "CodeAnalysis"],
|
|
123
122
|
# Documentation agents
|
|
124
|
-
"doc": base_tools
|
|
125
|
-
"docs": base_tools
|
|
126
|
-
"documentation": base_tools
|
|
123
|
+
"doc": [*base_tools, "DocumentGenerator", "MarkdownProcessor"],
|
|
124
|
+
"docs": [*base_tools, "DocumentGenerator", "MarkdownProcessor"],
|
|
125
|
+
"documentation": [*base_tools, "DocumentGenerator", "MarkdownProcessor"],
|
|
127
126
|
# Data processing agents
|
|
128
|
-
"data": base_tools
|
|
129
|
-
"analytics": base_tools
|
|
127
|
+
"data": [*base_tools, "DataProcessor", "CSVHandler"],
|
|
128
|
+
"analytics": [*base_tools, "DataProcessor", "CSVHandler"],
|
|
130
129
|
# Operations agents
|
|
131
|
-
"ops": base_tools
|
|
132
|
-
"operations": base_tools
|
|
133
|
-
"monitor": base_tools
|
|
130
|
+
"ops": [*base_tools, "SystemMonitor", "LogAnalyzer"],
|
|
131
|
+
"operations": [*base_tools, "SystemMonitor", "LogAnalyzer"],
|
|
132
|
+
"monitor": [*base_tools, "SystemMonitor", "LogAnalyzer"],
|
|
134
133
|
# Research agents
|
|
135
|
-
"research": base_tools
|
|
136
|
-
"analysis": base_tools
|
|
134
|
+
"research": [*base_tools, "WebSearch", "DataCollector"],
|
|
135
|
+
"analysis": [*base_tools, "WebSearch", "DataCollector"],
|
|
137
136
|
}
|
|
138
137
|
|
|
139
138
|
# Check agent name for tool assignment
|
|
@@ -150,7 +149,7 @@ class AgentConfigurationManager:
|
|
|
150
149
|
return agent_tools[spec_lower]
|
|
151
150
|
|
|
152
151
|
# Return default tools with web search and bash
|
|
153
|
-
return base_tools
|
|
152
|
+
return [*base_tools, "Bash", "WebSearch"]
|
|
154
153
|
|
|
155
154
|
def get_agent_specific_config(self, agent_name: str) -> Dict[str, Any]:
|
|
156
155
|
"""
|
|
@@ -348,9 +347,9 @@ class AgentConfigurationManager:
|
|
|
348
347
|
base_agent_data, base_agent_version = self.load_base_agent()
|
|
349
348
|
|
|
350
349
|
return {
|
|
351
|
-
"base_agent_path":
|
|
352
|
-
|
|
353
|
-
|
|
350
|
+
"base_agent_path": (
|
|
351
|
+
str(self.base_agent_path) if self.base_agent_path else None
|
|
352
|
+
),
|
|
354
353
|
"base_agent_loaded": self._base_agent_cache is not None,
|
|
355
354
|
"base_agent_version": base_agent_version,
|
|
356
355
|
"base_agent_name": base_agent_data.get("name", "unknown"),
|
|
@@ -4,8 +4,6 @@ This module provides factory functionality for creating AgentDefinition objects
|
|
|
4
4
|
from lifecycle manager parameters. Extracted to reduce complexity.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
-
from typing import Any
|
|
8
|
-
|
|
9
7
|
from claude_mpm.core.enums import AgentType, ModificationTier
|
|
10
8
|
from claude_mpm.models.agent_definition import (
|
|
11
9
|
AgentDefinition,
|
|
@@ -64,7 +62,7 @@ class AgentDefinitionFactory:
|
|
|
64
62
|
)
|
|
65
63
|
|
|
66
64
|
# Create minimal definition
|
|
67
|
-
|
|
65
|
+
return AgentDefinition(
|
|
68
66
|
name=agent_name,
|
|
69
67
|
title=agent_name.replace("-", " ").title(),
|
|
70
68
|
file_path="", # Will be set by AgentManager
|
|
@@ -80,5 +78,3 @@ class AgentDefinitionFactory:
|
|
|
80
78
|
tools_commands="",
|
|
81
79
|
raw_content=agent_content,
|
|
82
80
|
)
|
|
83
|
-
|
|
84
|
-
return definition
|
|
@@ -27,24 +27,16 @@ ROLLBACK PROCEDURES:
|
|
|
27
27
|
- Version tracking allows targeted rollbacks
|
|
28
28
|
"""
|
|
29
29
|
|
|
30
|
-
import logging
|
|
31
30
|
import os
|
|
32
|
-
import shutil
|
|
33
31
|
import time
|
|
34
32
|
from pathlib import Path
|
|
35
33
|
from typing import Any, Dict, List, Optional, Tuple
|
|
36
34
|
|
|
37
35
|
from claude_mpm.config.paths import paths
|
|
38
|
-
from claude_mpm.constants import
|
|
36
|
+
from claude_mpm.constants import Paths
|
|
39
37
|
from claude_mpm.core.config import Config
|
|
40
|
-
from claude_mpm.core.constants import ResourceLimits, SystemLimits, TimeoutConfig
|
|
41
38
|
from claude_mpm.core.exceptions import AgentDeploymentError
|
|
42
39
|
from claude_mpm.core.interfaces import AgentDeploymentInterface
|
|
43
|
-
from claude_mpm.core.logging_config import (
|
|
44
|
-
get_logger,
|
|
45
|
-
log_operation,
|
|
46
|
-
log_performance_context,
|
|
47
|
-
)
|
|
48
40
|
from claude_mpm.services.shared import ConfigServiceBase
|
|
49
41
|
|
|
50
42
|
from .agent_configuration_manager import AgentConfigurationManager
|
|
@@ -148,7 +140,7 @@ class AgentDeploymentService(ConfigServiceBase, AgentDeploymentInterface):
|
|
|
148
140
|
self.working_directory = self.get_config_value(
|
|
149
141
|
"working_directory",
|
|
150
142
|
default=working_directory or Path.cwd(),
|
|
151
|
-
config_type=Path
|
|
143
|
+
config_type=Path,
|
|
152
144
|
)
|
|
153
145
|
self.logger.info(f"Working directory for deployment: {self.working_directory}")
|
|
154
146
|
|
|
@@ -157,18 +149,20 @@ class AgentDeploymentService(ConfigServiceBase, AgentDeploymentInterface):
|
|
|
157
149
|
self.templates_dir = self.get_config_value(
|
|
158
150
|
"templates_dir",
|
|
159
151
|
default=templates_dir or paths.agents_dir / "templates",
|
|
160
|
-
config_type=Path
|
|
152
|
+
config_type=Path,
|
|
161
153
|
)
|
|
162
154
|
|
|
163
155
|
# Initialize discovery service (after templates_dir is set)
|
|
164
156
|
self.discovery_service = AgentDiscoveryService(self.templates_dir)
|
|
165
|
-
|
|
157
|
+
|
|
166
158
|
# Initialize multi-source deployment service for version comparison
|
|
167
159
|
self.multi_source_service = MultiSourceAgentDeploymentService()
|
|
168
160
|
|
|
169
161
|
# Find base agent file using configuration
|
|
170
162
|
# Priority: param > config > search
|
|
171
|
-
configured_base_agent = self.get_config_value(
|
|
163
|
+
configured_base_agent = self.get_config_value(
|
|
164
|
+
"base_agent_path", config_type=Path
|
|
165
|
+
)
|
|
172
166
|
if base_agent_path:
|
|
173
167
|
self.base_agent_path = Path(base_agent_path)
|
|
174
168
|
elif configured_base_agent:
|
|
@@ -185,14 +179,14 @@ class AgentDeploymentService(ConfigServiceBase, AgentDeploymentInterface):
|
|
|
185
179
|
|
|
186
180
|
self.logger.info(f"Templates directory: {self.templates_dir}")
|
|
187
181
|
self.logger.info(f"Base agent path: {self.base_agent_path}")
|
|
188
|
-
|
|
182
|
+
|
|
189
183
|
def _find_base_agent_file(self) -> Path:
|
|
190
184
|
"""Find base agent file with priority-based search.
|
|
191
|
-
|
|
185
|
+
|
|
192
186
|
Priority order:
|
|
193
187
|
1. Environment variable override (CLAUDE_MPM_BASE_AGENT_PATH)
|
|
194
188
|
2. Current working directory (for local development)
|
|
195
|
-
3. Known development locations
|
|
189
|
+
3. Known development locations
|
|
196
190
|
4. User override location (~/.claude/agents/)
|
|
197
191
|
5. Framework agents directory (from paths)
|
|
198
192
|
"""
|
|
@@ -201,49 +195,68 @@ class AgentDeploymentService(ConfigServiceBase, AgentDeploymentInterface):
|
|
|
201
195
|
if env_path:
|
|
202
196
|
env_base_agent = Path(env_path)
|
|
203
197
|
if env_base_agent.exists():
|
|
204
|
-
self.logger.info(
|
|
198
|
+
self.logger.info(
|
|
199
|
+
f"Using environment variable base_agent: {env_base_agent}"
|
|
200
|
+
)
|
|
205
201
|
return env_base_agent
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
202
|
+
self.logger.warning(
|
|
203
|
+
f"CLAUDE_MPM_BASE_AGENT_PATH set but file doesn't exist: {env_base_agent}"
|
|
204
|
+
)
|
|
205
|
+
|
|
209
206
|
# Priority 1: Check current working directory for local development
|
|
210
207
|
cwd = Path.cwd()
|
|
211
208
|
cwd_base_agent = cwd / "src" / "claude_mpm" / "agents" / "base_agent.json"
|
|
212
209
|
if cwd_base_agent.exists():
|
|
213
|
-
self.logger.info(
|
|
210
|
+
self.logger.info(
|
|
211
|
+
f"Using local development base_agent from cwd: {cwd_base_agent}"
|
|
212
|
+
)
|
|
214
213
|
return cwd_base_agent
|
|
215
|
-
|
|
214
|
+
|
|
216
215
|
# Priority 2: Check known development locations
|
|
217
216
|
known_dev_paths = [
|
|
218
|
-
Path(
|
|
219
|
-
|
|
220
|
-
|
|
217
|
+
Path(
|
|
218
|
+
"/Users/masa/Projects/claude-mpm/src/claude_mpm/agents/base_agent.json"
|
|
219
|
+
),
|
|
220
|
+
Path.home()
|
|
221
|
+
/ "Projects"
|
|
222
|
+
/ "claude-mpm"
|
|
223
|
+
/ "src"
|
|
224
|
+
/ "claude_mpm"
|
|
225
|
+
/ "agents"
|
|
226
|
+
/ "base_agent.json",
|
|
227
|
+
Path.home()
|
|
228
|
+
/ "projects"
|
|
229
|
+
/ "claude-mpm"
|
|
230
|
+
/ "src"
|
|
231
|
+
/ "claude_mpm"
|
|
232
|
+
/ "agents"
|
|
233
|
+
/ "base_agent.json",
|
|
221
234
|
]
|
|
222
|
-
|
|
235
|
+
|
|
223
236
|
for dev_path in known_dev_paths:
|
|
224
237
|
if dev_path.exists():
|
|
225
238
|
self.logger.info(f"Using development base_agent: {dev_path}")
|
|
226
239
|
return dev_path
|
|
227
|
-
|
|
240
|
+
|
|
228
241
|
# Priority 3: Check user override location
|
|
229
242
|
user_base_agent = Path.home() / ".claude" / "agents" / "base_agent.json"
|
|
230
243
|
if user_base_agent.exists():
|
|
231
244
|
self.logger.info(f"Using user override base_agent: {user_base_agent}")
|
|
232
245
|
return user_base_agent
|
|
233
|
-
|
|
246
|
+
|
|
234
247
|
# Priority 4: Use framework agents directory (fallback)
|
|
235
248
|
framework_base_agent = paths.agents_dir / "base_agent.json"
|
|
236
249
|
if framework_base_agent.exists():
|
|
237
250
|
self.logger.info(f"Using framework base_agent: {framework_base_agent}")
|
|
238
251
|
return framework_base_agent
|
|
239
|
-
|
|
252
|
+
|
|
240
253
|
# If still not found, log all searched locations and raise error
|
|
241
254
|
self.logger.error("Base agent file not found in any location:")
|
|
242
255
|
self.logger.error(f" 1. CWD: {cwd_base_agent}")
|
|
243
256
|
self.logger.error(f" 2. Dev paths: {known_dev_paths}")
|
|
244
257
|
self.logger.error(f" 3. User: {user_base_agent}")
|
|
245
258
|
self.logger.error(f" 4. Framework: {framework_base_agent}")
|
|
246
|
-
|
|
259
|
+
|
|
247
260
|
# Final fallback to framework path even if it doesn't exist
|
|
248
261
|
# (will fail later with better error message)
|
|
249
262
|
return framework_base_agent
|
|
@@ -382,17 +395,19 @@ class AgentDeploymentService(ConfigServiceBase, AgentDeploymentInterface):
|
|
|
382
395
|
|
|
383
396
|
# Check if we should use multi-source deployment
|
|
384
397
|
use_multi_source = self._should_use_multi_source_deployment(deployment_mode)
|
|
385
|
-
|
|
398
|
+
|
|
386
399
|
if use_multi_source:
|
|
387
400
|
# Use multi-source deployment to get highest version agents
|
|
388
|
-
template_files, agent_sources, cleanup_results =
|
|
389
|
-
|
|
401
|
+
template_files, agent_sources, cleanup_results = (
|
|
402
|
+
self._get_multi_source_templates(
|
|
403
|
+
excluded_agents, config, agents_dir, force_rebuild
|
|
404
|
+
)
|
|
390
405
|
)
|
|
391
406
|
results["total"] = len(template_files)
|
|
392
407
|
results["multi_source"] = True
|
|
393
408
|
results["agent_sources"] = agent_sources
|
|
394
409
|
results["cleanup"] = cleanup_results
|
|
395
|
-
|
|
410
|
+
|
|
396
411
|
# Log cleanup results if any agents were removed
|
|
397
412
|
if cleanup_results.get("removed"):
|
|
398
413
|
self.logger.info(
|
|
@@ -410,12 +425,20 @@ class AgentDeploymentService(ConfigServiceBase, AgentDeploymentInterface):
|
|
|
410
425
|
|
|
411
426
|
# Deploy each agent template
|
|
412
427
|
for template_file in template_files:
|
|
413
|
-
template_file_path =
|
|
428
|
+
template_file_path = (
|
|
429
|
+
template_file
|
|
430
|
+
if isinstance(template_file, Path)
|
|
431
|
+
else Path(template_file)
|
|
432
|
+
)
|
|
414
433
|
agent_name = template_file_path.stem
|
|
415
|
-
|
|
434
|
+
|
|
416
435
|
# Get source info for this agent (agent_sources now uses file stems as keys)
|
|
417
|
-
source_info =
|
|
418
|
-
|
|
436
|
+
source_info = (
|
|
437
|
+
agent_sources.get(agent_name, "unknown")
|
|
438
|
+
if agent_sources
|
|
439
|
+
else "single"
|
|
440
|
+
)
|
|
441
|
+
|
|
419
442
|
self._deploy_single_agent(
|
|
420
443
|
template_file=template_file_path,
|
|
421
444
|
agents_dir=agents_dir,
|
|
@@ -558,8 +581,7 @@ class AgentDeploymentService(ConfigServiceBase, AgentDeploymentInterface):
|
|
|
558
581
|
if not needs_update:
|
|
559
582
|
self.logger.info(f"Agent {agent_name} is up to date")
|
|
560
583
|
return True
|
|
561
|
-
|
|
562
|
-
self.logger.info(f"Updating agent {agent_name}: {reason}")
|
|
584
|
+
self.logger.info(f"Updating agent {agent_name}: {reason}")
|
|
563
585
|
|
|
564
586
|
# Load base agent data for building
|
|
565
587
|
base_agent_data = {}
|
|
@@ -628,25 +650,23 @@ class AgentDeploymentService(ConfigServiceBase, AgentDeploymentInterface):
|
|
|
628
650
|
from .system_instructions_deployer import SystemInstructionsDeployer
|
|
629
651
|
|
|
630
652
|
deployer = SystemInstructionsDeployer(self.logger, self.working_directory)
|
|
631
|
-
deployer.deploy_system_instructions(
|
|
632
|
-
target_dir, force_rebuild, results
|
|
633
|
-
)
|
|
653
|
+
deployer.deploy_system_instructions(target_dir, force_rebuild, results)
|
|
634
654
|
|
|
635
655
|
def deploy_system_instructions_explicit(
|
|
636
656
|
self, target_dir: Optional[Path] = None, force_rebuild: bool = False
|
|
637
657
|
) -> Dict[str, Any]:
|
|
638
658
|
"""
|
|
639
659
|
Explicitly deploy system instructions when requested by user.
|
|
640
|
-
|
|
660
|
+
|
|
641
661
|
This method should ONLY be called when the user explicitly requests
|
|
642
662
|
deployment of system instructions through agent-manager commands.
|
|
643
663
|
It will deploy INSTRUCTIONS.md, MEMORY.md, and WORKFLOW.md to .claude/
|
|
644
664
|
directory in the project.
|
|
645
|
-
|
|
665
|
+
|
|
646
666
|
Args:
|
|
647
667
|
target_dir: Target directory for deployment (ignored - always uses .claude/)
|
|
648
668
|
force_rebuild: Force rebuild even if files exist
|
|
649
|
-
|
|
669
|
+
|
|
650
670
|
Returns:
|
|
651
671
|
Dict with deployment results
|
|
652
672
|
"""
|
|
@@ -656,35 +676,34 @@ class AgentDeploymentService(ConfigServiceBase, AgentDeploymentInterface):
|
|
|
656
676
|
"skipped": [],
|
|
657
677
|
"errors": [],
|
|
658
678
|
}
|
|
659
|
-
|
|
679
|
+
|
|
660
680
|
try:
|
|
661
681
|
# Always use project's .claude directory
|
|
662
682
|
target_dir = self.working_directory / ".claude"
|
|
663
|
-
|
|
683
|
+
|
|
664
684
|
# Ensure directory exists
|
|
665
685
|
target_dir.mkdir(parents=True, exist_ok=True)
|
|
666
|
-
|
|
686
|
+
|
|
667
687
|
# Deploy using the deployer (targeting .claude/)
|
|
668
688
|
from .system_instructions_deployer import SystemInstructionsDeployer
|
|
689
|
+
|
|
669
690
|
deployer = SystemInstructionsDeployer(self.logger, self.working_directory)
|
|
670
|
-
|
|
691
|
+
|
|
671
692
|
# Deploy to .claude directory
|
|
672
|
-
deployer.deploy_system_instructions(
|
|
673
|
-
|
|
674
|
-
)
|
|
675
|
-
|
|
693
|
+
deployer.deploy_system_instructions(target_dir, force_rebuild, results)
|
|
694
|
+
|
|
676
695
|
self.logger.info(
|
|
677
696
|
f"Explicitly deployed system instructions to {target_dir}: "
|
|
678
697
|
f"deployed={len(results['deployed'])}, "
|
|
679
698
|
f"updated={len(results['updated'])}, "
|
|
680
699
|
f"skipped={len(results['skipped'])}"
|
|
681
700
|
)
|
|
682
|
-
|
|
701
|
+
|
|
683
702
|
except Exception as e:
|
|
684
703
|
error_msg = f"Failed to deploy system instructions: {e}"
|
|
685
704
|
self.logger.error(error_msg)
|
|
686
705
|
results["errors"].append(error_msg)
|
|
687
|
-
|
|
706
|
+
|
|
688
707
|
return results
|
|
689
708
|
|
|
690
709
|
def _convert_yaml_to_md(self, target_dir: Path) -> Dict[str, Any]:
|
|
@@ -774,7 +793,6 @@ class AgentDeploymentService(ConfigServiceBase, AgentDeploymentInterface):
|
|
|
774
793
|
resolver = AgentsDirectoryResolver(self.working_directory)
|
|
775
794
|
return resolver.determine_agents_directory(target_dir)
|
|
776
795
|
|
|
777
|
-
|
|
778
796
|
def _initialize_deployment_results(
|
|
779
797
|
self, agents_dir: Path, deployment_start_time: float
|
|
780
798
|
) -> Dict[str, Any]:
|
|
@@ -1053,74 +1071,77 @@ class AgentDeploymentService(ConfigServiceBase, AgentDeploymentInterface):
|
|
|
1053
1071
|
|
|
1054
1072
|
validator = AgentFrontmatterValidator(self.logger)
|
|
1055
1073
|
return validator.validate_and_repair_existing_agents(agents_dir)
|
|
1056
|
-
|
|
1074
|
+
|
|
1057
1075
|
def _determine_agent_source(self, template_path: Path) -> str:
|
|
1058
1076
|
"""Determine the source of an agent from its template path.
|
|
1059
|
-
|
|
1077
|
+
|
|
1060
1078
|
WHY: When deploying single agents, we need to track their source
|
|
1061
1079
|
for proper version management and debugging.
|
|
1062
|
-
|
|
1080
|
+
|
|
1063
1081
|
Args:
|
|
1064
1082
|
template_path: Path to the agent template
|
|
1065
|
-
|
|
1083
|
+
|
|
1066
1084
|
Returns:
|
|
1067
1085
|
Source string (system/project/user/unknown)
|
|
1068
1086
|
"""
|
|
1069
1087
|
template_str = str(template_path.resolve())
|
|
1070
|
-
|
|
1088
|
+
|
|
1071
1089
|
# Check if it's a system template
|
|
1072
|
-
if
|
|
1090
|
+
if (
|
|
1091
|
+
"/claude_mpm/agents/templates/" in template_str
|
|
1092
|
+
or "/src/claude_mpm/agents/templates/" in template_str
|
|
1093
|
+
):
|
|
1073
1094
|
return "system"
|
|
1074
|
-
|
|
1095
|
+
|
|
1075
1096
|
# Check if it's a project agent
|
|
1076
1097
|
if "/.claude-mpm/agents/" in template_str:
|
|
1077
1098
|
# Check if it's in the current working directory
|
|
1078
1099
|
if str(self.working_directory) in template_str:
|
|
1079
1100
|
return "project"
|
|
1080
1101
|
# Check if it's in user home
|
|
1081
|
-
|
|
1102
|
+
if str(Path.home()) in template_str:
|
|
1082
1103
|
return "user"
|
|
1083
|
-
|
|
1104
|
+
|
|
1084
1105
|
return "unknown"
|
|
1085
|
-
|
|
1106
|
+
|
|
1086
1107
|
def _should_use_multi_source_deployment(self, deployment_mode: str) -> bool:
|
|
1087
1108
|
"""Determine if multi-source deployment should be used.
|
|
1088
|
-
|
|
1109
|
+
|
|
1089
1110
|
WHY: Multi-source deployment ensures the highest version wins,
|
|
1090
1111
|
but we may want to preserve backward compatibility in some modes.
|
|
1091
|
-
|
|
1112
|
+
|
|
1092
1113
|
Args:
|
|
1093
1114
|
deployment_mode: Current deployment mode
|
|
1094
|
-
|
|
1115
|
+
|
|
1095
1116
|
Returns:
|
|
1096
1117
|
True if multi-source deployment should be used
|
|
1097
1118
|
"""
|
|
1098
1119
|
# Always use multi-source for update mode to get highest versions
|
|
1099
1120
|
if deployment_mode == "update":
|
|
1100
1121
|
return True
|
|
1101
|
-
|
|
1122
|
+
|
|
1102
1123
|
# For project mode, also use multi-source to ensure highest version wins
|
|
1103
1124
|
# This is the key change - project mode should also compare versions
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
return False
|
|
1108
|
-
|
|
1125
|
+
return deployment_mode == "project"
|
|
1126
|
+
|
|
1109
1127
|
def _get_multi_source_templates(
|
|
1110
|
-
self,
|
|
1111
|
-
|
|
1128
|
+
self,
|
|
1129
|
+
excluded_agents: List[str],
|
|
1130
|
+
config: Config,
|
|
1131
|
+
agents_dir: Path,
|
|
1132
|
+
force_rebuild: bool = False,
|
|
1112
1133
|
) -> Tuple[List[Path], Dict[str, str], Dict[str, Any]]:
|
|
1113
1134
|
"""Get agent templates from multiple sources with version comparison.
|
|
1114
|
-
|
|
1135
|
+
|
|
1115
1136
|
WHY: This method uses the multi-source service to discover agents
|
|
1116
1137
|
from all available sources and select the highest version of each.
|
|
1117
|
-
|
|
1138
|
+
|
|
1118
1139
|
Args:
|
|
1119
1140
|
excluded_agents: List of agents to exclude
|
|
1120
1141
|
config: Configuration object
|
|
1121
1142
|
agents_dir: Target deployment directory
|
|
1122
1143
|
force_rebuild: Whether to force rebuild
|
|
1123
|
-
|
|
1144
|
+
|
|
1124
1145
|
Returns:
|
|
1125
1146
|
Tuple of (template_files, agent_sources, cleanup_results)
|
|
1126
1147
|
"""
|
|
@@ -1128,70 +1149,79 @@ class AgentDeploymentService(ConfigServiceBase, AgentDeploymentInterface):
|
|
|
1128
1149
|
system_templates_dir = self.templates_dir
|
|
1129
1150
|
project_agents_dir = None
|
|
1130
1151
|
user_agents_dir = None
|
|
1131
|
-
|
|
1152
|
+
|
|
1132
1153
|
# Check for project agents
|
|
1133
1154
|
if self.working_directory:
|
|
1134
1155
|
potential_project_dir = self.working_directory / ".claude-mpm" / "agents"
|
|
1135
1156
|
if potential_project_dir.exists():
|
|
1136
1157
|
project_agents_dir = potential_project_dir
|
|
1137
1158
|
self.logger.info(f"Found project agents at: {project_agents_dir}")
|
|
1138
|
-
|
|
1159
|
+
|
|
1139
1160
|
# Check for user agents
|
|
1140
1161
|
user_home = Path.home()
|
|
1141
1162
|
potential_user_dir = user_home / ".claude-mpm" / "agents"
|
|
1142
1163
|
if potential_user_dir.exists():
|
|
1143
1164
|
user_agents_dir = potential_user_dir
|
|
1144
1165
|
self.logger.info(f"Found user agents at: {user_agents_dir}")
|
|
1145
|
-
|
|
1166
|
+
|
|
1146
1167
|
# Get agents with version comparison and cleanup
|
|
1147
|
-
agents_to_deploy, agent_sources, cleanup_results =
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1168
|
+
agents_to_deploy, agent_sources, cleanup_results = (
|
|
1169
|
+
self.multi_source_service.get_agents_for_deployment(
|
|
1170
|
+
system_templates_dir=system_templates_dir,
|
|
1171
|
+
project_agents_dir=project_agents_dir,
|
|
1172
|
+
user_agents_dir=user_agents_dir,
|
|
1173
|
+
working_directory=self.working_directory,
|
|
1174
|
+
excluded_agents=excluded_agents,
|
|
1175
|
+
config=config,
|
|
1176
|
+
cleanup_outdated=True, # Enable cleanup by default
|
|
1177
|
+
)
|
|
1155
1178
|
)
|
|
1156
|
-
|
|
1179
|
+
|
|
1157
1180
|
# Compare with deployed versions if agents directory exists
|
|
1158
1181
|
if agents_dir.exists():
|
|
1159
1182
|
comparison_results = self.multi_source_service.compare_deployed_versions(
|
|
1160
1183
|
deployed_agents_dir=agents_dir,
|
|
1161
1184
|
agents_to_deploy=agents_to_deploy,
|
|
1162
|
-
agent_sources=agent_sources
|
|
1185
|
+
agent_sources=agent_sources,
|
|
1163
1186
|
)
|
|
1164
|
-
|
|
1187
|
+
|
|
1165
1188
|
# Log version upgrades and source changes
|
|
1166
1189
|
if comparison_results.get("version_upgrades"):
|
|
1167
|
-
self.logger.info(
|
|
1190
|
+
self.logger.info(
|
|
1191
|
+
f"Version upgrades available for {len(comparison_results['version_upgrades'])} agents"
|
|
1192
|
+
)
|
|
1168
1193
|
if comparison_results.get("source_changes"):
|
|
1169
|
-
self.logger.info(
|
|
1170
|
-
|
|
1194
|
+
self.logger.info(
|
|
1195
|
+
f"Source changes for {len(comparison_results['source_changes'])} agents"
|
|
1196
|
+
)
|
|
1197
|
+
|
|
1171
1198
|
# Filter agents based on comparison results (unless force_rebuild is set)
|
|
1172
1199
|
if not force_rebuild:
|
|
1173
1200
|
# Only deploy agents that need updates or are new
|
|
1174
1201
|
agents_needing_update = set(comparison_results.get("needs_update", []))
|
|
1175
|
-
|
|
1202
|
+
|
|
1176
1203
|
# Extract agent names from new_agents list (which contains dicts)
|
|
1177
1204
|
new_agent_names = [
|
|
1178
1205
|
agent["name"] if isinstance(agent, dict) else agent
|
|
1179
1206
|
for agent in comparison_results.get("new_agents", [])
|
|
1180
1207
|
]
|
|
1181
1208
|
agents_needing_update.update(new_agent_names)
|
|
1182
|
-
|
|
1209
|
+
|
|
1183
1210
|
# Filter agents_to_deploy to only include those needing updates
|
|
1184
1211
|
filtered_agents = {
|
|
1185
|
-
name: path
|
|
1212
|
+
name: path
|
|
1213
|
+
for name, path in agents_to_deploy.items()
|
|
1186
1214
|
if name in agents_needing_update
|
|
1187
1215
|
}
|
|
1188
1216
|
agents_to_deploy = filtered_agents
|
|
1189
|
-
|
|
1190
|
-
self.logger.info(
|
|
1191
|
-
|
|
1217
|
+
|
|
1218
|
+
self.logger.info(
|
|
1219
|
+
f"Filtered to {len(agents_to_deploy)} agents needing deployment"
|
|
1220
|
+
)
|
|
1221
|
+
|
|
1192
1222
|
# Convert to list of Path objects
|
|
1193
1223
|
template_files = list(agents_to_deploy.values())
|
|
1194
|
-
|
|
1224
|
+
|
|
1195
1225
|
return template_files, agent_sources, cleanup_results
|
|
1196
1226
|
|
|
1197
1227
|
# ================================================================================
|
|
@@ -1243,7 +1273,7 @@ class AgentDeploymentService(ConfigServiceBase, AgentDeploymentInterface):
|
|
|
1243
1273
|
return len(errors) == 0, errors
|
|
1244
1274
|
|
|
1245
1275
|
except Exception as e:
|
|
1246
|
-
return False, [f"Validation error: {
|
|
1276
|
+
return False, [f"Validation error: {e!s}"]
|
|
1247
1277
|
|
|
1248
1278
|
def get_deployment_status(self) -> Dict[str, Any]:
|
|
1249
1279
|
"""Get current deployment status and metrics."""
|