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,16 +14,18 @@ DESIGN DECISIONS:
|
|
|
14
14
|
import json
|
|
15
15
|
import os
|
|
16
16
|
from pathlib import Path
|
|
17
|
-
from typing import Any, Dict, Optional
|
|
18
17
|
|
|
19
18
|
import yaml
|
|
20
19
|
|
|
21
20
|
from ...agents.frontmatter_validator import FrontmatterValidator
|
|
22
21
|
from ...constants import AgentCommands
|
|
23
22
|
from ...core.agent_registry import AgentRegistryAdapter
|
|
24
|
-
from ...core.
|
|
23
|
+
from ...core.logger import get_logger
|
|
25
24
|
from ...core.shared.config_loader import ConfigLoader
|
|
26
|
-
from ..shared import
|
|
25
|
+
from ..shared import (
|
|
26
|
+
AgentCommand,
|
|
27
|
+
CommandResult,
|
|
28
|
+
)
|
|
27
29
|
from ..utils import get_agent_versions_display
|
|
28
30
|
|
|
29
31
|
|
|
@@ -40,7 +42,10 @@ class AgentsCommand(AgentCommand):
|
|
|
40
42
|
if self._deployment_service is None:
|
|
41
43
|
try:
|
|
42
44
|
from ...services import AgentDeploymentService
|
|
43
|
-
from ...services.agents.deployment.deployment_wrapper import
|
|
45
|
+
from ...services.agents.deployment.deployment_wrapper import (
|
|
46
|
+
DeploymentServiceWrapper,
|
|
47
|
+
)
|
|
48
|
+
|
|
44
49
|
base_service = AgentDeploymentService()
|
|
45
50
|
self._deployment_service = DeploymentServiceWrapper(base_service)
|
|
46
51
|
except ImportError:
|
|
@@ -56,14 +61,18 @@ class AgentsCommand(AgentCommand):
|
|
|
56
61
|
"""Execute the agent command."""
|
|
57
62
|
try:
|
|
58
63
|
# Handle default case (no subcommand)
|
|
59
|
-
if not hasattr(args,
|
|
64
|
+
if not hasattr(args, "agents_command") or not args.agents_command:
|
|
60
65
|
return self._show_agent_versions(args)
|
|
61
66
|
|
|
62
67
|
# Route to appropriate subcommand
|
|
63
68
|
command_map = {
|
|
64
69
|
AgentCommands.LIST.value: self._list_agents,
|
|
65
|
-
AgentCommands.DEPLOY.value: lambda a: self._deploy_agents(
|
|
66
|
-
|
|
70
|
+
AgentCommands.DEPLOY.value: lambda a: self._deploy_agents(
|
|
71
|
+
a, force=False
|
|
72
|
+
),
|
|
73
|
+
AgentCommands.FORCE_DEPLOY.value: lambda a: self._deploy_agents(
|
|
74
|
+
a, force=True
|
|
75
|
+
),
|
|
67
76
|
AgentCommands.CLEAN.value: self._clean_agents,
|
|
68
77
|
AgentCommands.VIEW.value: self._view_agent,
|
|
69
78
|
AgentCommands.FIX.value: self._fix_agents,
|
|
@@ -76,10 +85,11 @@ class AgentsCommand(AgentCommand):
|
|
|
76
85
|
|
|
77
86
|
if args.agents_command in command_map:
|
|
78
87
|
return command_map[args.agents_command](args)
|
|
79
|
-
|
|
80
|
-
|
|
88
|
+
return CommandResult.error_result(
|
|
89
|
+
f"Unknown agent command: {args.agents_command}"
|
|
90
|
+
)
|
|
81
91
|
|
|
82
|
-
except ImportError
|
|
92
|
+
except ImportError:
|
|
83
93
|
self.logger.error("Agent deployment service not available")
|
|
84
94
|
return CommandResult.error_result("Agent deployment service not available")
|
|
85
95
|
except Exception as e:
|
|
@@ -91,53 +101,58 @@ class AgentsCommand(AgentCommand):
|
|
|
91
101
|
try:
|
|
92
102
|
agent_versions = get_agent_versions_display()
|
|
93
103
|
|
|
94
|
-
output_format = getattr(args,
|
|
95
|
-
if output_format in [
|
|
104
|
+
output_format = getattr(args, "format", "text")
|
|
105
|
+
if output_format in ["json", "yaml"]:
|
|
96
106
|
# Parse the agent versions display into structured data
|
|
97
107
|
if agent_versions:
|
|
98
108
|
data = {"agent_versions": agent_versions, "has_agents": True}
|
|
99
|
-
return CommandResult.success_result(
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
109
|
+
return CommandResult.success_result(
|
|
110
|
+
"Agent versions retrieved", data=data
|
|
111
|
+
)
|
|
112
|
+
data = {
|
|
113
|
+
"agent_versions": None,
|
|
114
|
+
"has_agents": False,
|
|
115
|
+
"suggestion": "To deploy agents, run: claude-mpm --mpm:agents deploy",
|
|
116
|
+
}
|
|
117
|
+
return CommandResult.success_result(
|
|
118
|
+
"No deployed agents found", data=data
|
|
119
|
+
)
|
|
120
|
+
# Text output
|
|
121
|
+
if agent_versions:
|
|
122
|
+
print(agent_versions)
|
|
123
|
+
return CommandResult.success_result("Agent versions displayed")
|
|
124
|
+
print("No deployed agents found")
|
|
125
|
+
print("\nTo deploy agents, run: claude-mpm --mpm:agents deploy")
|
|
126
|
+
return CommandResult.success_result("No deployed agents found")
|
|
112
127
|
|
|
113
128
|
except Exception as e:
|
|
114
129
|
self.logger.error(f"Error getting agent versions: {e}", exc_info=True)
|
|
115
130
|
return CommandResult.error_result(f"Error getting agent versions: {e}")
|
|
116
131
|
|
|
117
|
-
|
|
118
132
|
def _list_agents(self, args) -> CommandResult:
|
|
119
133
|
"""List available or deployed agents."""
|
|
120
134
|
try:
|
|
121
|
-
output_format = getattr(args,
|
|
135
|
+
output_format = getattr(args, "format", "text")
|
|
122
136
|
|
|
123
137
|
if hasattr(args, "by_tier") and args.by_tier:
|
|
124
138
|
return self._list_agents_by_tier(args)
|
|
125
|
-
|
|
139
|
+
if getattr(args, "system", False):
|
|
126
140
|
return self._list_system_agents(args)
|
|
127
|
-
|
|
141
|
+
if getattr(args, "deployed", False):
|
|
128
142
|
return self._list_deployed_agents(args)
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
usage_msg = "Use --system to list system agents, --deployed to list deployed agents, or --by-tier to group by precedence"
|
|
143
|
+
# Default: show usage
|
|
144
|
+
usage_msg = "Use --system to list system agents, --deployed to list deployed agents, or --by-tier to group by precedence"
|
|
132
145
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
146
|
+
if output_format in ["json", "yaml"]:
|
|
147
|
+
return CommandResult.error_result(
|
|
148
|
+
"No list option specified",
|
|
149
|
+
data={
|
|
150
|
+
"usage": usage_msg,
|
|
151
|
+
"available_options": ["--system", "--deployed", "--by-tier"],
|
|
152
|
+
},
|
|
153
|
+
)
|
|
154
|
+
print(usage_msg)
|
|
155
|
+
return CommandResult.error_result("No list option specified")
|
|
141
156
|
|
|
142
157
|
except Exception as e:
|
|
143
158
|
self.logger.error(f"Error listing agents: {e}", exc_info=True)
|
|
@@ -147,31 +162,30 @@ class AgentsCommand(AgentCommand):
|
|
|
147
162
|
"""List available agent templates."""
|
|
148
163
|
try:
|
|
149
164
|
agents = self.deployment_service.list_available_agents()
|
|
150
|
-
output_format = getattr(args,
|
|
165
|
+
output_format = getattr(args, "format", "text")
|
|
151
166
|
|
|
152
|
-
if output_format in [
|
|
167
|
+
if output_format in ["json", "yaml"]:
|
|
153
168
|
return CommandResult.success_result(
|
|
154
169
|
f"Found {len(agents)} agent templates",
|
|
155
|
-
data={"agents": agents, "count": len(agents)}
|
|
170
|
+
data={"agents": agents, "count": len(agents)},
|
|
156
171
|
)
|
|
172
|
+
# Text output
|
|
173
|
+
print("Available Agent Templates:")
|
|
174
|
+
print("-" * 80)
|
|
175
|
+
if not agents:
|
|
176
|
+
print("No agent templates found")
|
|
157
177
|
else:
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
print(f"
|
|
166
|
-
|
|
167
|
-
print(f" Name: {agent['name']}")
|
|
168
|
-
if "description" in agent:
|
|
169
|
-
print(f" Description: {agent['description']}")
|
|
170
|
-
if "version" in agent:
|
|
171
|
-
print(f" Version: {agent['version']}")
|
|
172
|
-
print()
|
|
178
|
+
for agent in agents:
|
|
179
|
+
print(f"📄 {agent['file']}")
|
|
180
|
+
if "name" in agent:
|
|
181
|
+
print(f" Name: {agent['name']}")
|
|
182
|
+
if "description" in agent:
|
|
183
|
+
print(f" Description: {agent['description']}")
|
|
184
|
+
if "version" in agent:
|
|
185
|
+
print(f" Version: {agent['version']}")
|
|
186
|
+
print()
|
|
173
187
|
|
|
174
|
-
|
|
188
|
+
return CommandResult.success_result(f"Listed {len(agents)} agent templates")
|
|
175
189
|
|
|
176
190
|
except Exception as e:
|
|
177
191
|
self.logger.error(f"Error listing system agents: {e}", exc_info=True)
|
|
@@ -181,38 +195,39 @@ class AgentsCommand(AgentCommand):
|
|
|
181
195
|
"""List deployed agents."""
|
|
182
196
|
try:
|
|
183
197
|
verification = self.deployment_service.verify_deployment()
|
|
184
|
-
output_format = getattr(args,
|
|
198
|
+
output_format = getattr(args, "format", "text")
|
|
185
199
|
|
|
186
|
-
if output_format in [
|
|
200
|
+
if output_format in ["json", "yaml"]:
|
|
187
201
|
return CommandResult.success_result(
|
|
188
202
|
f"Found {len(verification['agents_found'])} deployed agents",
|
|
189
203
|
data={
|
|
190
204
|
"agents": verification["agents_found"],
|
|
191
205
|
"warnings": verification.get("warnings", []),
|
|
192
|
-
"count": len(verification["agents_found"])
|
|
193
|
-
}
|
|
206
|
+
"count": len(verification["agents_found"]),
|
|
207
|
+
},
|
|
194
208
|
)
|
|
209
|
+
# Text output
|
|
210
|
+
print("Deployed Agents:")
|
|
211
|
+
print("-" * 80)
|
|
212
|
+
if not verification["agents_found"]:
|
|
213
|
+
print("No deployed agents found")
|
|
195
214
|
else:
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
print(f"📄 {agent['file']}")
|
|
204
|
-
if "name" in agent:
|
|
205
|
-
print(f" Name: {agent['name']}")
|
|
206
|
-
if "path" in agent:
|
|
207
|
-
print(f" Path: {agent['path']}")
|
|
208
|
-
print()
|
|
215
|
+
for agent in verification["agents_found"]:
|
|
216
|
+
print(f"📄 {agent['file']}")
|
|
217
|
+
if "name" in agent:
|
|
218
|
+
print(f" Name: {agent['name']}")
|
|
219
|
+
if "path" in agent:
|
|
220
|
+
print(f" Path: {agent['path']}")
|
|
221
|
+
print()
|
|
209
222
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
223
|
+
if verification["warnings"]:
|
|
224
|
+
print("\nWarnings:")
|
|
225
|
+
for warning in verification["warnings"]:
|
|
226
|
+
print(f" ⚠️ {warning}")
|
|
214
227
|
|
|
215
|
-
|
|
228
|
+
return CommandResult.success_result(
|
|
229
|
+
f"Listed {len(verification['agents_found'])} deployed agents"
|
|
230
|
+
)
|
|
216
231
|
|
|
217
232
|
except Exception as e:
|
|
218
233
|
self.logger.error(f"Error listing deployed agents: {e}", exc_info=True)
|
|
@@ -222,28 +237,26 @@ class AgentsCommand(AgentCommand):
|
|
|
222
237
|
"""List agents grouped by tier/precedence."""
|
|
223
238
|
try:
|
|
224
239
|
agents_by_tier = self.deployment_service.list_agents_by_tier()
|
|
225
|
-
output_format = getattr(args,
|
|
240
|
+
output_format = getattr(args, "format", "text")
|
|
226
241
|
|
|
227
|
-
if output_format in [
|
|
242
|
+
if output_format in ["json", "yaml"]:
|
|
228
243
|
return CommandResult.success_result(
|
|
229
|
-
"Agents listed by tier",
|
|
230
|
-
data=agents_by_tier
|
|
244
|
+
"Agents listed by tier", data=agents_by_tier
|
|
231
245
|
)
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
print(" (none)")
|
|
246
|
+
# Text output
|
|
247
|
+
print("Agents by Tier/Precedence:")
|
|
248
|
+
print("=" * 50)
|
|
249
|
+
|
|
250
|
+
for tier, agents in agents_by_tier.items():
|
|
251
|
+
print(f"\n{tier.upper()}:")
|
|
252
|
+
print("-" * 20)
|
|
253
|
+
if agents:
|
|
254
|
+
for agent in agents:
|
|
255
|
+
print(f" • {agent}")
|
|
256
|
+
else:
|
|
257
|
+
print(" (none)")
|
|
245
258
|
|
|
246
|
-
|
|
259
|
+
return CommandResult.success_result("Agents listed by tier")
|
|
247
260
|
|
|
248
261
|
except Exception as e:
|
|
249
262
|
self.logger.error(f"Error listing agents by tier: {e}", exc_info=True)
|
|
@@ -259,29 +272,30 @@ class AgentsCommand(AgentCommand):
|
|
|
259
272
|
project_result = self.deployment_service.deploy_project_agents(force=force)
|
|
260
273
|
|
|
261
274
|
# Combine results
|
|
262
|
-
total_deployed = system_result.get(
|
|
275
|
+
total_deployed = system_result.get(
|
|
276
|
+
"deployed_count", 0
|
|
277
|
+
) + project_result.get("deployed_count", 0)
|
|
263
278
|
|
|
264
|
-
output_format = getattr(args,
|
|
265
|
-
if output_format in [
|
|
279
|
+
output_format = getattr(args, "format", "text")
|
|
280
|
+
if output_format in ["json", "yaml"]:
|
|
266
281
|
return CommandResult.success_result(
|
|
267
282
|
f"Deployed {total_deployed} agents",
|
|
268
283
|
data={
|
|
269
284
|
"system_agents": system_result,
|
|
270
285
|
"project_agents": project_result,
|
|
271
|
-
"total_deployed": total_deployed
|
|
272
|
-
}
|
|
286
|
+
"total_deployed": total_deployed,
|
|
287
|
+
},
|
|
273
288
|
)
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
print(f"✓ Deployed {project_result['deployed_count']} project agents")
|
|
289
|
+
# Text output
|
|
290
|
+
if system_result.get("deployed_count", 0) > 0:
|
|
291
|
+
print(f"✓ Deployed {system_result['deployed_count']} system agents")
|
|
292
|
+
if project_result.get("deployed_count", 0) > 0:
|
|
293
|
+
print(f"✓ Deployed {project_result['deployed_count']} project agents")
|
|
280
294
|
|
|
281
|
-
|
|
282
|
-
|
|
295
|
+
if total_deployed == 0:
|
|
296
|
+
print("No agents were deployed (all up to date)")
|
|
283
297
|
|
|
284
|
-
|
|
298
|
+
return CommandResult.success_result(f"Deployed {total_deployed} agents")
|
|
285
299
|
|
|
286
300
|
except Exception as e:
|
|
287
301
|
self.logger.error(f"Error deploying agents: {e}", exc_info=True)
|
|
@@ -292,21 +306,19 @@ class AgentsCommand(AgentCommand):
|
|
|
292
306
|
try:
|
|
293
307
|
result = self.deployment_service.clean_deployment()
|
|
294
308
|
|
|
295
|
-
output_format = getattr(args,
|
|
296
|
-
if output_format in [
|
|
309
|
+
output_format = getattr(args, "format", "text")
|
|
310
|
+
if output_format in ["json", "yaml"]:
|
|
297
311
|
return CommandResult.success_result(
|
|
298
|
-
f"Cleaned {result.get('cleaned_count', 0)} agents",
|
|
299
|
-
data=result
|
|
312
|
+
f"Cleaned {result.get('cleaned_count', 0)} agents", data=result
|
|
300
313
|
)
|
|
314
|
+
# Text output
|
|
315
|
+
cleaned_count = result.get("cleaned_count", 0)
|
|
316
|
+
if cleaned_count > 0:
|
|
317
|
+
print(f"✓ Cleaned {cleaned_count} deployed agents")
|
|
301
318
|
else:
|
|
302
|
-
|
|
303
|
-
cleaned_count = result.get('cleaned_count', 0)
|
|
304
|
-
if cleaned_count > 0:
|
|
305
|
-
print(f"✓ Cleaned {cleaned_count} deployed agents")
|
|
306
|
-
else:
|
|
307
|
-
print("No deployed agents to clean")
|
|
319
|
+
print("No deployed agents to clean")
|
|
308
320
|
|
|
309
|
-
|
|
321
|
+
return CommandResult.success_result(f"Cleaned {cleaned_count} agents")
|
|
310
322
|
|
|
311
323
|
except Exception as e:
|
|
312
324
|
self.logger.error(f"Error cleaning agents: {e}", exc_info=True)
|
|
@@ -315,27 +327,27 @@ class AgentsCommand(AgentCommand):
|
|
|
315
327
|
def _view_agent(self, args) -> CommandResult:
|
|
316
328
|
"""View details of a specific agent."""
|
|
317
329
|
try:
|
|
318
|
-
agent_name = getattr(args,
|
|
330
|
+
agent_name = getattr(args, "agent_name", None)
|
|
319
331
|
if not agent_name:
|
|
320
|
-
return CommandResult.error_result(
|
|
332
|
+
return CommandResult.error_result(
|
|
333
|
+
"Agent name is required for view command"
|
|
334
|
+
)
|
|
321
335
|
|
|
322
336
|
# Get agent details from deployment service
|
|
323
337
|
agent_details = self.deployment_service.get_agent_details(agent_name)
|
|
324
338
|
|
|
325
|
-
output_format = getattr(args,
|
|
326
|
-
if output_format in [
|
|
339
|
+
output_format = getattr(args, "format", "text")
|
|
340
|
+
if output_format in ["json", "yaml"]:
|
|
327
341
|
return CommandResult.success_result(
|
|
328
|
-
f"Agent details for {agent_name}",
|
|
329
|
-
data=agent_details
|
|
342
|
+
f"Agent details for {agent_name}", data=agent_details
|
|
330
343
|
)
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
print(f"{key}: {value}")
|
|
344
|
+
# Text output
|
|
345
|
+
print(f"Agent: {agent_name}")
|
|
346
|
+
print("-" * 40)
|
|
347
|
+
for key, value in agent_details.items():
|
|
348
|
+
print(f"{key}: {value}")
|
|
337
349
|
|
|
338
|
-
|
|
350
|
+
return CommandResult.success_result(f"Displayed details for {agent_name}")
|
|
339
351
|
|
|
340
352
|
except Exception as e:
|
|
341
353
|
self.logger.error(f"Error viewing agent: {e}", exc_info=True)
|
|
@@ -346,20 +358,18 @@ class AgentsCommand(AgentCommand):
|
|
|
346
358
|
try:
|
|
347
359
|
result = self.deployment_service.fix_deployment()
|
|
348
360
|
|
|
349
|
-
output_format = getattr(args,
|
|
350
|
-
if output_format in [
|
|
361
|
+
output_format = getattr(args, "format", "text")
|
|
362
|
+
if output_format in ["json", "yaml"]:
|
|
351
363
|
return CommandResult.success_result(
|
|
352
|
-
"Agent deployment fixed",
|
|
353
|
-
data=result
|
|
364
|
+
"Agent deployment fixed", data=result
|
|
354
365
|
)
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
print(f" - {fix}")
|
|
366
|
+
# Text output
|
|
367
|
+
print("✓ Agent deployment issues fixed")
|
|
368
|
+
if result.get("fixes_applied"):
|
|
369
|
+
for fix in result["fixes_applied"]:
|
|
370
|
+
print(f" - {fix}")
|
|
361
371
|
|
|
362
|
-
|
|
372
|
+
return CommandResult.success_result("Agent deployment fixed")
|
|
363
373
|
|
|
364
374
|
except Exception as e:
|
|
365
375
|
self.logger.error(f"Error fixing agents: {e}", exc_info=True)
|
|
@@ -370,24 +380,22 @@ class AgentsCommand(AgentCommand):
|
|
|
370
380
|
try:
|
|
371
381
|
result = self.deployment_service.check_dependencies()
|
|
372
382
|
|
|
373
|
-
output_format = getattr(args,
|
|
374
|
-
if output_format in [
|
|
383
|
+
output_format = getattr(args, "format", "text")
|
|
384
|
+
if output_format in ["json", "yaml"]:
|
|
375
385
|
return CommandResult.success_result(
|
|
376
|
-
"Dependency check completed",
|
|
377
|
-
data=result
|
|
386
|
+
"Dependency check completed", data=result
|
|
378
387
|
)
|
|
388
|
+
# Text output
|
|
389
|
+
print("Agent Dependencies Check:")
|
|
390
|
+
print("-" * 40)
|
|
391
|
+
if result.get("missing_dependencies"):
|
|
392
|
+
print("Missing dependencies:")
|
|
393
|
+
for dep in result["missing_dependencies"]:
|
|
394
|
+
print(f" - {dep}")
|
|
379
395
|
else:
|
|
380
|
-
|
|
381
|
-
print("Agent Dependencies Check:")
|
|
382
|
-
print("-" * 40)
|
|
383
|
-
if result.get('missing_dependencies'):
|
|
384
|
-
print("Missing dependencies:")
|
|
385
|
-
for dep in result['missing_dependencies']:
|
|
386
|
-
print(f" - {dep}")
|
|
387
|
-
else:
|
|
388
|
-
print("✓ All dependencies satisfied")
|
|
396
|
+
print("✓ All dependencies satisfied")
|
|
389
397
|
|
|
390
|
-
|
|
398
|
+
return CommandResult.success_result("Dependency check completed")
|
|
391
399
|
|
|
392
400
|
except Exception as e:
|
|
393
401
|
self.logger.error(f"Error checking dependencies: {e}", exc_info=True)
|
|
@@ -398,21 +406,22 @@ class AgentsCommand(AgentCommand):
|
|
|
398
406
|
try:
|
|
399
407
|
result = self.deployment_service.install_dependencies()
|
|
400
408
|
|
|
401
|
-
output_format = getattr(args,
|
|
402
|
-
if output_format in [
|
|
409
|
+
output_format = getattr(args, "format", "text")
|
|
410
|
+
if output_format in ["json", "yaml"]:
|
|
403
411
|
return CommandResult.success_result(
|
|
404
412
|
f"Installed {result.get('installed_count', 0)} dependencies",
|
|
405
|
-
data=result
|
|
413
|
+
data=result,
|
|
406
414
|
)
|
|
415
|
+
# Text output
|
|
416
|
+
installed_count = result.get("installed_count", 0)
|
|
417
|
+
if installed_count > 0:
|
|
418
|
+
print(f"✓ Installed {installed_count} dependencies")
|
|
407
419
|
else:
|
|
408
|
-
|
|
409
|
-
installed_count = result.get('installed_count', 0)
|
|
410
|
-
if installed_count > 0:
|
|
411
|
-
print(f"✓ Installed {installed_count} dependencies")
|
|
412
|
-
else:
|
|
413
|
-
print("No dependencies needed installation")
|
|
420
|
+
print("No dependencies needed installation")
|
|
414
421
|
|
|
415
|
-
|
|
422
|
+
return CommandResult.success_result(
|
|
423
|
+
f"Installed {installed_count} dependencies"
|
|
424
|
+
)
|
|
416
425
|
|
|
417
426
|
except Exception as e:
|
|
418
427
|
self.logger.error(f"Error installing dependencies: {e}", exc_info=True)
|
|
@@ -423,25 +432,26 @@ class AgentsCommand(AgentCommand):
|
|
|
423
432
|
try:
|
|
424
433
|
result = self.deployment_service.list_dependencies()
|
|
425
434
|
|
|
426
|
-
output_format = getattr(args,
|
|
427
|
-
if output_format in [
|
|
435
|
+
output_format = getattr(args, "format", "text")
|
|
436
|
+
if output_format in ["json", "yaml"]:
|
|
428
437
|
return CommandResult.success_result(
|
|
429
438
|
f"Found {len(result.get('dependencies', []))} dependencies",
|
|
430
|
-
data=result
|
|
439
|
+
data=result,
|
|
431
440
|
)
|
|
441
|
+
# Text output
|
|
442
|
+
dependencies = result.get("dependencies", [])
|
|
443
|
+
print("Agent Dependencies:")
|
|
444
|
+
print("-" * 40)
|
|
445
|
+
if dependencies:
|
|
446
|
+
for dep in dependencies:
|
|
447
|
+
status = "✓" if dep.get("installed") else "✗"
|
|
448
|
+
print(f"{status} {dep.get('name', 'Unknown')}")
|
|
432
449
|
else:
|
|
433
|
-
|
|
434
|
-
dependencies = result.get('dependencies', [])
|
|
435
|
-
print("Agent Dependencies:")
|
|
436
|
-
print("-" * 40)
|
|
437
|
-
if dependencies:
|
|
438
|
-
for dep in dependencies:
|
|
439
|
-
status = "✓" if dep.get('installed') else "✗"
|
|
440
|
-
print(f"{status} {dep.get('name', 'Unknown')}")
|
|
441
|
-
else:
|
|
442
|
-
print("No dependencies found")
|
|
450
|
+
print("No dependencies found")
|
|
443
451
|
|
|
444
|
-
|
|
452
|
+
return CommandResult.success_result(
|
|
453
|
+
f"Listed {len(dependencies)} dependencies"
|
|
454
|
+
)
|
|
445
455
|
|
|
446
456
|
except Exception as e:
|
|
447
457
|
self.logger.error(f"Error listing dependencies: {e}", exc_info=True)
|
|
@@ -452,34 +462,32 @@ class AgentsCommand(AgentCommand):
|
|
|
452
462
|
try:
|
|
453
463
|
result = self.deployment_service.fix_dependencies()
|
|
454
464
|
|
|
455
|
-
output_format = getattr(args,
|
|
456
|
-
if output_format in [
|
|
465
|
+
output_format = getattr(args, "format", "text")
|
|
466
|
+
if output_format in ["json", "yaml"]:
|
|
457
467
|
return CommandResult.success_result(
|
|
458
|
-
"Dependency issues fixed",
|
|
459
|
-
data=result
|
|
468
|
+
"Dependency issues fixed", data=result
|
|
460
469
|
)
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
print(f" - {fix}")
|
|
470
|
+
# Text output
|
|
471
|
+
print("✓ Agent dependency issues fixed")
|
|
472
|
+
if result.get("fixes_applied"):
|
|
473
|
+
for fix in result["fixes_applied"]:
|
|
474
|
+
print(f" - {fix}")
|
|
467
475
|
|
|
468
|
-
|
|
476
|
+
return CommandResult.success_result("Dependency issues fixed")
|
|
469
477
|
|
|
470
478
|
except Exception as e:
|
|
471
479
|
self.logger.error(f"Error fixing dependencies: {e}", exc_info=True)
|
|
472
480
|
return CommandResult.error_result(f"Error fixing dependencies: {e}")
|
|
473
|
-
|
|
481
|
+
|
|
474
482
|
def _cleanup_orphaned_agents(self, args) -> CommandResult:
|
|
475
483
|
"""Clean up orphaned agents that don't have templates."""
|
|
476
484
|
try:
|
|
477
485
|
from ...services.agents.deployment.multi_source_deployment_service import (
|
|
478
|
-
MultiSourceAgentDeploymentService
|
|
486
|
+
MultiSourceAgentDeploymentService,
|
|
479
487
|
)
|
|
480
|
-
|
|
488
|
+
|
|
481
489
|
# Determine agents directory
|
|
482
|
-
if hasattr(args,
|
|
490
|
+
if hasattr(args, "agents_dir") and args.agents_dir:
|
|
483
491
|
agents_dir = args.agents_dir
|
|
484
492
|
else:
|
|
485
493
|
# Check for project-level .claude/agents first
|
|
@@ -489,65 +497,65 @@ class AgentsCommand(AgentCommand):
|
|
|
489
497
|
else:
|
|
490
498
|
# Fall back to user home directory
|
|
491
499
|
agents_dir = Path.home() / ".claude" / "agents"
|
|
492
|
-
|
|
500
|
+
|
|
493
501
|
if not agents_dir.exists():
|
|
494
|
-
return CommandResult.success_result(
|
|
495
|
-
|
|
502
|
+
return CommandResult.success_result(
|
|
503
|
+
f"Agents directory not found: {agents_dir}"
|
|
504
|
+
)
|
|
505
|
+
|
|
496
506
|
# Initialize service
|
|
497
507
|
service = MultiSourceAgentDeploymentService()
|
|
498
|
-
|
|
508
|
+
|
|
499
509
|
# Determine if we're doing a dry run
|
|
500
|
-
dry_run = getattr(args,
|
|
501
|
-
if hasattr(args,
|
|
510
|
+
dry_run = getattr(args, "dry_run", True)
|
|
511
|
+
if hasattr(args, "force") and args.force:
|
|
502
512
|
dry_run = False
|
|
503
|
-
|
|
513
|
+
|
|
504
514
|
# Perform cleanup
|
|
505
515
|
results = service.cleanup_orphaned_agents(agents_dir, dry_run=dry_run)
|
|
506
|
-
|
|
507
|
-
output_format = getattr(args,
|
|
508
|
-
quiet = getattr(args,
|
|
509
|
-
|
|
510
|
-
if output_format in [
|
|
516
|
+
|
|
517
|
+
output_format = getattr(args, "format", "text")
|
|
518
|
+
quiet = getattr(args, "quiet", False)
|
|
519
|
+
|
|
520
|
+
if output_format in ["json", "yaml"]:
|
|
511
521
|
return CommandResult.success_result(
|
|
512
522
|
f"Found {len(results.get('orphaned', []))} orphaned agents",
|
|
513
|
-
data=results
|
|
523
|
+
data=results,
|
|
524
|
+
)
|
|
525
|
+
# Text output
|
|
526
|
+
if not results.get("orphaned"):
|
|
527
|
+
print("✅ No orphaned agents found")
|
|
528
|
+
return CommandResult.success_result("No orphaned agents found")
|
|
529
|
+
|
|
530
|
+
if not quiet:
|
|
531
|
+
print(f"\nFound {len(results['orphaned'])} orphaned agent(s):")
|
|
532
|
+
for orphan in results["orphaned"]:
|
|
533
|
+
print(f" - {orphan['name']} v{orphan['version']}")
|
|
534
|
+
|
|
535
|
+
if dry_run:
|
|
536
|
+
print(
|
|
537
|
+
f"\n📝 This was a dry run. Use --force to actually remove "
|
|
538
|
+
f"{len(results['orphaned'])} orphaned agent(s)"
|
|
514
539
|
)
|
|
515
540
|
else:
|
|
516
|
-
|
|
517
|
-
if not results.get("orphaned"):
|
|
518
|
-
print("✅ No orphaned agents found")
|
|
519
|
-
return CommandResult.success_result("No orphaned agents found")
|
|
520
|
-
|
|
521
|
-
if not quiet:
|
|
522
|
-
print(f"\nFound {len(results['orphaned'])} orphaned agent(s):")
|
|
523
|
-
for orphan in results["orphaned"]:
|
|
524
|
-
print(f" - {orphan['name']} v{orphan['version']}")
|
|
525
|
-
|
|
526
|
-
if dry_run:
|
|
541
|
+
if results.get("removed"):
|
|
527
542
|
print(
|
|
528
|
-
f"\n
|
|
529
|
-
f"{len(results['orphaned'])} orphaned agent(s)"
|
|
543
|
+
f"\n✅ Successfully removed {len(results['removed'])} orphaned agent(s)"
|
|
530
544
|
)
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
)
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
return CommandResult.success_result(
|
|
547
|
-
f"Cleanup {'preview' if dry_run else 'completed'}",
|
|
548
|
-
data=results
|
|
549
|
-
)
|
|
550
|
-
|
|
545
|
+
|
|
546
|
+
if results.get("errors"):
|
|
547
|
+
print(f"\n❌ Encountered {len(results['errors'])} error(s):")
|
|
548
|
+
for error in results["errors"]:
|
|
549
|
+
print(f" - {error}")
|
|
550
|
+
return CommandResult.error_result(
|
|
551
|
+
f"Cleanup completed with {len(results['errors'])} errors",
|
|
552
|
+
data=results,
|
|
553
|
+
)
|
|
554
|
+
|
|
555
|
+
return CommandResult.success_result(
|
|
556
|
+
f"Cleanup {'preview' if dry_run else 'completed'}", data=results
|
|
557
|
+
)
|
|
558
|
+
|
|
551
559
|
except Exception as e:
|
|
552
560
|
self.logger.error(f"Error during cleanup: {e}", exc_info=True)
|
|
553
561
|
return CommandResult.error_result(f"Error during cleanup: {e}")
|
|
@@ -563,7 +571,7 @@ def manage_agents(args):
|
|
|
563
571
|
result = command.execute(args)
|
|
564
572
|
|
|
565
573
|
# Print result if structured output format is requested
|
|
566
|
-
if hasattr(args,
|
|
574
|
+
if hasattr(args, "format") and args.format in ["json", "yaml"]:
|
|
567
575
|
command.print_result(result, args)
|
|
568
576
|
|
|
569
577
|
return result.exit_code
|
|
@@ -611,7 +619,7 @@ def _deploy_agents(args, deployment_service, force=False):
|
|
|
611
619
|
|
|
612
620
|
# Warn if commonly used agents are being excluded
|
|
613
621
|
common_agents = {"engineer", "qa", "security", "documentation"}
|
|
614
|
-
excluded_common =
|
|
622
|
+
excluded_common = {a.lower() for a in excluded_agents} & common_agents
|
|
615
623
|
if excluded_common:
|
|
616
624
|
print(
|
|
617
625
|
f"⚠️ Warning: Common agents are being excluded: {', '.join(excluded_common)}"
|
|
@@ -629,7 +637,6 @@ def _deploy_agents(args, deployment_service, force=False):
|
|
|
629
637
|
results = deployment_service.deploy_agents(None, force_rebuild=force, config=config)
|
|
630
638
|
|
|
631
639
|
# Also deploy project agents if they exist
|
|
632
|
-
import os
|
|
633
640
|
from pathlib import Path
|
|
634
641
|
|
|
635
642
|
# Use the user's working directory if available
|
|
@@ -700,7 +707,7 @@ def _deploy_agents(args, deployment_service, force=False):
|
|
|
700
707
|
env_vars = deployment_service.set_claude_environment(
|
|
701
708
|
args.target.parent if args.target else None
|
|
702
709
|
)
|
|
703
|
-
print(
|
|
710
|
+
print("\n✓ Set Claude environment variables:")
|
|
704
711
|
for key, value in env_vars.items():
|
|
705
712
|
print(f" - {key}={value}")
|
|
706
713
|
|
|
@@ -777,11 +784,11 @@ def _list_agents_by_tier():
|
|
|
777
784
|
else:
|
|
778
785
|
# Check paths to determine actual locations
|
|
779
786
|
if tier_key == "project":
|
|
780
|
-
print(
|
|
787
|
+
print(" Location: .claude-mpm/agents/ (in current project)")
|
|
781
788
|
elif tier_key == "user":
|
|
782
|
-
print(
|
|
789
|
+
print(" Location: ~/.claude-mpm/agents/")
|
|
783
790
|
else:
|
|
784
|
-
print(
|
|
791
|
+
print(" Location: Built-in framework agents")
|
|
785
792
|
|
|
786
793
|
print(f"\n Found {len(agents)} agent(s):\n")
|
|
787
794
|
|
|
@@ -863,7 +870,7 @@ def _view_agent(args):
|
|
|
863
870
|
print(f"❌ Agent file not found: {agent_path}")
|
|
864
871
|
return
|
|
865
872
|
|
|
866
|
-
with open(agent_path
|
|
873
|
+
with open(agent_path) as f:
|
|
867
874
|
content = f.read()
|
|
868
875
|
|
|
869
876
|
# Display agent information
|
|
@@ -872,7 +879,7 @@ def _view_agent(args):
|
|
|
872
879
|
print("=" * 80)
|
|
873
880
|
|
|
874
881
|
# Basic info
|
|
875
|
-
print(
|
|
882
|
+
print("\n📋 BASIC INFORMATION:")
|
|
876
883
|
print(f" Name: {agent.name}")
|
|
877
884
|
print(f" Type: {agent.type}")
|
|
878
885
|
print(f" Tier: {agent.tier.upper()}")
|
|
@@ -893,7 +900,7 @@ def _view_agent(args):
|
|
|
893
900
|
frontmatter_str = content[4:end_marker]
|
|
894
901
|
frontmatter = yaml.safe_load(frontmatter_str)
|
|
895
902
|
|
|
896
|
-
print(
|
|
903
|
+
print("\n📝 FRONTMATTER:")
|
|
897
904
|
for key, value in frontmatter.items():
|
|
898
905
|
if isinstance(value, list):
|
|
899
906
|
print(f" {key}: [{', '.join(str(v) for v in value)}]")
|
|
@@ -909,13 +916,11 @@ def _view_agent(args):
|
|
|
909
916
|
instructions = content[instructions_start:].strip()
|
|
910
917
|
|
|
911
918
|
if instructions:
|
|
912
|
-
print(
|
|
919
|
+
print("\n📖 INSTRUCTIONS PREVIEW (first 500 chars):")
|
|
913
920
|
print(" " + "-" * 76)
|
|
914
921
|
preview = instructions[:500]
|
|
915
922
|
if len(instructions) > 500:
|
|
916
|
-
preview += "...\n\n [Truncated - {:.1f}KB total]"
|
|
917
|
-
len(instructions) / 1024
|
|
918
|
-
)
|
|
923
|
+
preview += f"...\n\n [Truncated - {len(instructions) / 1024:.1f}KB total]"
|
|
919
924
|
|
|
920
925
|
for line in preview.split("\n"):
|
|
921
926
|
print(f" {line}")
|
|
@@ -923,7 +928,7 @@ def _view_agent(args):
|
|
|
923
928
|
except Exception as e:
|
|
924
929
|
print(f"\n⚠️ Could not parse frontmatter: {e}")
|
|
925
930
|
else:
|
|
926
|
-
print(
|
|
931
|
+
print("\n⚠️ No frontmatter found in agent file")
|
|
927
932
|
|
|
928
933
|
# File stats
|
|
929
934
|
import os
|
|
@@ -932,7 +937,7 @@ def _view_agent(args):
|
|
|
932
937
|
from datetime import datetime
|
|
933
938
|
|
|
934
939
|
modified = datetime.fromtimestamp(stat.st_mtime).strftime("%Y-%m-%d %H:%M:%S")
|
|
935
|
-
print(
|
|
940
|
+
print("\n📊 FILE STATS:")
|
|
936
941
|
print(f" Size: {stat.st_size:,} bytes")
|
|
937
942
|
print(f" Last modified: {modified}")
|
|
938
943
|
|
|
@@ -1058,7 +1063,7 @@ def _check_agent_dependencies(args):
|
|
|
1058
1063
|
"""
|
|
1059
1064
|
from ...utils.agent_dependency_loader import AgentDependencyLoader
|
|
1060
1065
|
|
|
1061
|
-
|
|
1066
|
+
getattr(args, "verbose", False)
|
|
1062
1067
|
specific_agent = getattr(args, "agent", None)
|
|
1063
1068
|
|
|
1064
1069
|
loader = AgentDependencyLoader(auto_install=False)
|
|
@@ -1093,7 +1098,6 @@ def _install_agent_dependencies(args):
|
|
|
1093
1098
|
Args:
|
|
1094
1099
|
args: Parsed command line arguments
|
|
1095
1100
|
"""
|
|
1096
|
-
import sys
|
|
1097
1101
|
|
|
1098
1102
|
from ...utils.agent_dependency_loader import AgentDependencyLoader
|
|
1099
1103
|
|
|
@@ -1160,7 +1164,6 @@ def _list_agent_dependencies(args):
|
|
|
1160
1164
|
Args:
|
|
1161
1165
|
args: Parsed command line arguments
|
|
1162
1166
|
"""
|
|
1163
|
-
import json
|
|
1164
1167
|
|
|
1165
1168
|
from ...utils.agent_dependency_loader import AgentDependencyLoader
|
|
1166
1169
|
|
|
@@ -1191,8 +1194,8 @@ def _list_agent_dependencies(args):
|
|
|
1191
1194
|
elif output_format == "json":
|
|
1192
1195
|
# Output JSON format
|
|
1193
1196
|
output = {
|
|
1194
|
-
"python": sorted(
|
|
1195
|
-
"system": sorted(
|
|
1197
|
+
"python": sorted(all_python_deps),
|
|
1198
|
+
"system": sorted(all_system_deps),
|
|
1196
1199
|
"agents": {},
|
|
1197
1200
|
}
|
|
1198
1201
|
for agent_id, deps in loader.agent_dependencies.items():
|