claude-mpm 4.24.0__py3-none-any.whl → 5.4.41__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.
Potentially problematic release.
This version of claude-mpm might be problematic. Click here for more details.
- claude_mpm/VERSION +1 -1
- claude_mpm/__init__.py +4 -0
- claude_mpm/agents/BASE_AGENT.md +164 -0
- claude_mpm/agents/{OUTPUT_STYLE.md → CLAUDE_MPM_OUTPUT_STYLE.md} +3 -48
- claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +2002 -0
- claude_mpm/agents/MEMORY.md +1 -1
- claude_mpm/agents/PM_INSTRUCTIONS.md +735 -925
- claude_mpm/agents/WORKFLOW.md +5 -254
- claude_mpm/agents/__init__.py +6 -0
- claude_mpm/agents/agent_loader.py +14 -48
- claude_mpm/agents/base_agent.json +7 -4
- claude_mpm/agents/frontmatter_validator.py +71 -3
- claude_mpm/agents/templates/circuit-breakers.md +1391 -0
- claude_mpm/agents/templates/context-management-examples.md +544 -0
- claude_mpm/agents/templates/{pm_red_flags.md → pm-red-flags.md} +48 -0
- claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
- claude_mpm/agents/templates/research-gate-examples.md +669 -0
- claude_mpm/agents/templates/structured-questions-examples.md +615 -0
- claude_mpm/agents/templates/ticket-completeness-examples.md +139 -0
- claude_mpm/agents/templates/ticketing-examples.md +277 -0
- claude_mpm/cli/__init__.py +37 -2
- claude_mpm/cli/__main__.py +4 -0
- claude_mpm/cli/chrome_devtools_installer.py +175 -0
- claude_mpm/cli/commands/__init__.py +2 -0
- claude_mpm/cli/commands/agent_source.py +774 -0
- claude_mpm/cli/commands/agent_state_manager.py +180 -31
- claude_mpm/cli/commands/agents.py +1116 -55
- claude_mpm/cli/commands/agents_cleanup.py +210 -0
- claude_mpm/cli/commands/agents_discover.py +338 -0
- claude_mpm/cli/commands/aggregate.py +1 -1
- claude_mpm/cli/commands/analyze.py +3 -3
- claude_mpm/cli/commands/auto_configure.py +725 -242
- claude_mpm/cli/commands/config.py +95 -6
- claude_mpm/cli/commands/configure.py +1875 -46
- claude_mpm/cli/commands/configure_agent_display.py +29 -10
- claude_mpm/cli/commands/configure_navigation.py +63 -46
- claude_mpm/cli/commands/debug.py +12 -12
- claude_mpm/cli/commands/doctor.py +10 -2
- claude_mpm/cli/commands/hook_errors.py +277 -0
- claude_mpm/cli/commands/local_deploy.py +1 -4
- claude_mpm/cli/commands/mcp_install_commands.py +1 -1
- claude_mpm/cli/commands/mpm_init/core.py +229 -2
- claude_mpm/cli/commands/mpm_init/git_activity.py +10 -10
- claude_mpm/cli/commands/mpm_init/knowledge_extractor.py +481 -0
- claude_mpm/cli/commands/mpm_init/prompts.py +286 -6
- claude_mpm/cli/commands/postmortem.py +401 -0
- claude_mpm/cli/commands/profile.py +277 -0
- claude_mpm/cli/commands/run.py +123 -165
- claude_mpm/cli/commands/skill_source.py +694 -0
- claude_mpm/cli/commands/skills.py +782 -20
- claude_mpm/cli/commands/summarize.py +413 -0
- claude_mpm/cli/executor.py +96 -3
- claude_mpm/cli/interactive/agent_wizard.py +1030 -45
- claude_mpm/cli/parsers/agent_source_parser.py +171 -0
- claude_mpm/cli/parsers/agents_parser.py +307 -10
- claude_mpm/cli/parsers/auto_configure_parser.py +13 -138
- claude_mpm/cli/parsers/base_parser.py +65 -0
- claude_mpm/cli/parsers/config_parser.py +162 -39
- claude_mpm/cli/parsers/profile_parser.py +148 -0
- claude_mpm/cli/parsers/skill_source_parser.py +169 -0
- claude_mpm/cli/parsers/skills_parser.py +146 -0
- claude_mpm/cli/parsers/source_parser.py +138 -0
- claude_mpm/cli/startup.py +1280 -118
- claude_mpm/cli/startup_display.py +480 -0
- claude_mpm/cli/utils.py +1 -1
- claude_mpm/cli_module/commands.py +1 -1
- claude_mpm/commands/mpm-config.md +21 -134
- claude_mpm/commands/mpm-doctor.md +16 -20
- claude_mpm/commands/mpm-help.md +13 -283
- claude_mpm/commands/mpm-init.md +88 -489
- claude_mpm/commands/mpm-monitor.md +23 -401
- claude_mpm/commands/mpm-organize.md +72 -247
- claude_mpm/commands/mpm-postmortem.md +21 -0
- claude_mpm/commands/mpm-session-resume.md +30 -0
- claude_mpm/commands/mpm-status.md +13 -68
- claude_mpm/commands/mpm-ticket-view.md +109 -0
- claude_mpm/commands/mpm-version.md +13 -106
- claude_mpm/commands/mpm.md +10 -0
- claude_mpm/config/agent_presets.py +488 -0
- claude_mpm/config/agent_sources.py +352 -0
- claude_mpm/config/skill_presets.py +392 -0
- claude_mpm/config/skill_sources.py +590 -0
- claude_mpm/constants.py +13 -0
- claude_mpm/core/claude_runner.py +5 -34
- claude_mpm/core/config.py +15 -1
- claude_mpm/core/constants.py +1 -1
- claude_mpm/core/framework/__init__.py +3 -16
- claude_mpm/core/framework/formatters/content_formatter.py +3 -13
- claude_mpm/core/framework/loaders/agent_loader.py +8 -5
- claude_mpm/core/framework/loaders/file_loader.py +54 -101
- claude_mpm/core/framework/loaders/instruction_loader.py +66 -5
- claude_mpm/core/framework_loader.py +4 -2
- claude_mpm/core/hook_error_memory.py +381 -0
- claude_mpm/core/hook_manager.py +41 -2
- claude_mpm/core/interactive_session.py +91 -10
- claude_mpm/core/logger.py +16 -1
- claude_mpm/core/oneshot_session.py +71 -8
- claude_mpm/core/optimized_startup.py +59 -0
- claude_mpm/core/output_style_manager.py +173 -43
- claude_mpm/core/protocols/__init__.py +23 -0
- claude_mpm/core/protocols/runner_protocol.py +103 -0
- claude_mpm/core/protocols/session_protocol.py +131 -0
- claude_mpm/core/shared/config_loader.py +1 -1
- claude_mpm/core/shared/singleton_manager.py +11 -4
- claude_mpm/core/socketio_pool.py +3 -3
- claude_mpm/core/system_context.py +38 -0
- claude_mpm/core/unified_agent_registry.py +134 -16
- claude_mpm/core/unified_config.py +22 -0
- claude_mpm/dashboard/static/svelte-build/_app/env.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.B_FtCwCQ.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.Cl_eSA4x.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BgChzWQ1.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIXEwuWe.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWc5urbQ.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DMkZpdF2.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DjhvlsAc.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/N4qtv3Hx.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/uj46x2Wr.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.DTL5mJO-.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.DzuEhzqh.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/0.CAGBuiOw.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DFLC8jdE.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.DPvEihJJ.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -0
- claude_mpm/dashboard/static/svelte-build/favicon.svg +7 -0
- claude_mpm/dashboard/static/svelte-build/index.html +36 -0
- claude_mpm/experimental/cli_enhancements.py +1 -5
- claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/correlation_manager.py +60 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +214 -79
- claude_mpm/hooks/claude_hooks/hook_handler.py +155 -1
- claude_mpm/hooks/claude_hooks/installer.py +33 -10
- claude_mpm/hooks/claude_hooks/memory_integration.py +28 -0
- claude_mpm/hooks/claude_hooks/response_tracking.py +2 -3
- claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/connection_manager.py +30 -6
- claude_mpm/hooks/failure_learning/__init__.py +2 -8
- claude_mpm/hooks/failure_learning/failure_detection_hook.py +1 -6
- claude_mpm/hooks/failure_learning/fix_detection_hook.py +1 -6
- claude_mpm/hooks/failure_learning/learning_extraction_hook.py +1 -6
- claude_mpm/hooks/kuzu_response_hook.py +1 -5
- claude_mpm/hooks/memory_integration_hook.py +46 -1
- claude_mpm/init.py +63 -19
- claude_mpm/models/agent_definition.py +7 -0
- claude_mpm/models/git_repository.py +198 -0
- claude_mpm/scripts/claude-hook-handler.sh +60 -20
- claude_mpm/scripts/launch_monitor.py +93 -13
- claude_mpm/scripts/start_activity_logging.py +3 -1
- claude_mpm/services/agents/agent_builder.py +48 -12
- claude_mpm/services/agents/agent_preset_service.py +238 -0
- claude_mpm/services/agents/agent_recommendation_service.py +278 -0
- claude_mpm/services/agents/agent_review_service.py +280 -0
- claude_mpm/services/agents/agent_selection_service.py +484 -0
- claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
- claude_mpm/services/agents/cache_git_manager.py +621 -0
- claude_mpm/services/agents/deployment/agent_deployment.py +148 -2
- claude_mpm/services/agents/deployment/agent_discovery_service.py +104 -73
- claude_mpm/services/agents/deployment/agent_format_converter.py +1 -1
- claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +1 -5
- claude_mpm/services/agents/deployment/agent_metrics_collector.py +3 -3
- claude_mpm/services/agents/deployment/agent_restore_handler.py +1 -4
- claude_mpm/services/agents/deployment/agent_template_builder.py +238 -15
- claude_mpm/services/agents/deployment/agents_directory_resolver.py +101 -15
- claude_mpm/services/agents/deployment/async_agent_deployment.py +2 -1
- claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -3
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +422 -31
- claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +2 -2
- claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +1 -4
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +841 -0
- claude_mpm/services/agents/deployment/single_agent_deployer.py +2 -2
- claude_mpm/services/agents/deployment/system_instructions_deployer.py +168 -46
- claude_mpm/services/agents/deployment/validation/deployment_validator.py +2 -2
- claude_mpm/services/agents/git_source_manager.py +663 -0
- claude_mpm/services/agents/loading/base_agent_manager.py +1 -13
- claude_mpm/services/agents/loading/framework_agent_loader.py +9 -12
- claude_mpm/services/agents/local_template_manager.py +50 -10
- claude_mpm/services/agents/recommender.py +5 -3
- claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
- claude_mpm/services/agents/sources/__init__.py +13 -0
- claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
- claude_mpm/services/agents/sources/git_source_sync_service.py +1094 -0
- claude_mpm/services/agents/startup_sync.py +259 -0
- claude_mpm/services/agents/toolchain_detector.py +478 -0
- claude_mpm/services/analysis/__init__.py +35 -0
- claude_mpm/services/analysis/clone_detector.py +1030 -0
- claude_mpm/services/analysis/postmortem_reporter.py +474 -0
- claude_mpm/services/analysis/postmortem_service.py +765 -0
- claude_mpm/services/cli/session_pause_manager.py +1 -1
- claude_mpm/services/command_deployment_service.py +271 -6
- claude_mpm/services/core/base.py +7 -2
- claude_mpm/services/core/interfaces/__init__.py +1 -3
- claude_mpm/services/core/interfaces/health.py +1 -4
- claude_mpm/services/core/models/__init__.py +2 -11
- claude_mpm/services/diagnostics/checks/__init__.py +4 -0
- claude_mpm/services/diagnostics/checks/agent_check.py +2 -4
- claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
- claude_mpm/services/diagnostics/checks/instructions_check.py +1 -2
- claude_mpm/services/diagnostics/checks/mcp_check.py +0 -1
- claude_mpm/services/diagnostics/checks/mcp_services_check.py +7 -15
- claude_mpm/services/diagnostics/checks/monitor_check.py +0 -1
- claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
- claude_mpm/services/diagnostics/diagnostic_runner.py +9 -0
- claude_mpm/services/diagnostics/doctor_reporter.py +40 -10
- claude_mpm/services/event_bus/config.py +3 -1
- claude_mpm/services/event_bus/direct_relay.py +3 -3
- claude_mpm/services/events/consumers/logging.py +1 -2
- claude_mpm/services/git/__init__.py +21 -0
- claude_mpm/services/git/git_operations_service.py +579 -0
- claude_mpm/services/github/__init__.py +21 -0
- claude_mpm/services/github/github_cli_service.py +397 -0
- claude_mpm/services/infrastructure/monitoring/__init__.py +1 -5
- claude_mpm/services/infrastructure/monitoring/aggregator.py +1 -6
- claude_mpm/services/instructions/__init__.py +9 -0
- claude_mpm/services/instructions/instruction_cache_service.py +374 -0
- claude_mpm/services/local_ops/__init__.py +3 -13
- claude_mpm/services/local_ops/health_checks/__init__.py +1 -3
- claude_mpm/services/local_ops/health_manager.py +1 -4
- claude_mpm/services/local_ops/resource_monitor.py +1 -1
- claude_mpm/services/mcp_config_manager.py +75 -145
- claude_mpm/services/mcp_service_verifier.py +6 -3
- claude_mpm/services/model/model_router.py +1 -2
- claude_mpm/services/monitor/daemon.py +38 -11
- claude_mpm/services/monitor/daemon_manager.py +134 -21
- claude_mpm/services/monitor/management/lifecycle.py +8 -1
- claude_mpm/services/monitor/server.py +700 -24
- claude_mpm/services/pm_skills_deployer.py +676 -0
- claude_mpm/services/port_manager.py +1 -1
- claude_mpm/services/pr/__init__.py +14 -0
- claude_mpm/services/pr/pr_template_service.py +329 -0
- claude_mpm/services/profile_manager.py +331 -0
- claude_mpm/services/project/documentation_manager.py +2 -1
- claude_mpm/services/project/project_organizer.py +4 -0
- claude_mpm/services/project/toolchain_analyzer.py +3 -1
- claude_mpm/services/runner_configuration_service.py +16 -3
- claude_mpm/services/self_upgrade_service.py +120 -12
- claude_mpm/services/session_management_service.py +16 -4
- claude_mpm/services/skills/__init__.py +21 -0
- claude_mpm/services/skills/git_skill_source_manager.py +1297 -0
- claude_mpm/services/skills/selective_skill_deployer.py +704 -0
- claude_mpm/services/skills/skill_discovery_service.py +568 -0
- claude_mpm/services/skills/skill_to_agent_mapper.py +406 -0
- claude_mpm/services/skills_config.py +547 -0
- claude_mpm/services/skills_deployer.py +1072 -0
- claude_mpm/services/socketio/dashboard_server.py +1 -0
- claude_mpm/services/socketio/event_normalizer.py +51 -6
- claude_mpm/services/socketio/handlers/connection.py +1 -1
- claude_mpm/services/socketio/handlers/git.py +1 -1
- claude_mpm/services/socketio/server/core.py +387 -112
- claude_mpm/services/socketio/server/main.py +1 -3
- claude_mpm/services/system_instructions_service.py +1 -3
- claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +0 -3
- claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +0 -1
- claude_mpm/services/unified/deployment_strategies/vercel.py +1 -5
- claude_mpm/services/unified/unified_deployment.py +1 -5
- claude_mpm/services/version_control/conflict_resolution.py +6 -4
- claude_mpm/services/version_control/git_operations.py +103 -0
- claude_mpm/services/visualization/__init__.py +1 -5
- claude_mpm/services/visualization/mermaid_generator.py +2 -3
- claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +2 -2
- claude_mpm/skills/skill_manager.py +92 -3
- claude_mpm/skills/skills_registry.py +0 -1
- claude_mpm/templates/questions/__init__.py +38 -0
- claude_mpm/templates/questions/base.py +193 -0
- claude_mpm/templates/questions/pr_strategy.py +311 -0
- claude_mpm/templates/questions/project_init.py +385 -0
- claude_mpm/templates/questions/ticket_mgmt.py +394 -0
- claude_mpm/tools/__main__.py +8 -8
- claude_mpm/utils/agent_dependency_loader.py +91 -12
- claude_mpm/utils/agent_filters.py +261 -0
- claude_mpm/utils/dependency_cache.py +3 -1
- claude_mpm/utils/gitignore.py +244 -0
- claude_mpm/utils/migration.py +372 -0
- claude_mpm/utils/progress.py +387 -0
- claude_mpm/utils/robust_installer.py +49 -7
- claude_mpm/utils/structured_questions.py +619 -0
- {claude_mpm-4.24.0.dist-info → claude_mpm-5.4.41.dist-info}/METADATA +445 -122
- {claude_mpm-4.24.0.dist-info → claude_mpm-5.4.41.dist-info}/RECORD +298 -503
- claude_mpm-5.4.41.dist-info/entry_points.txt +5 -0
- claude_mpm-5.4.41.dist-info/licenses/LICENSE +94 -0
- claude_mpm-5.4.41.dist-info/licenses/LICENSE-FAQ.md +153 -0
- claude_mpm/agents/BASE_AGENT_TEMPLATE.md +0 -292
- claude_mpm/agents/BASE_DOCUMENTATION.md +0 -53
- claude_mpm/agents/BASE_OPS.md +0 -219
- claude_mpm/agents/BASE_PM.md +0 -468
- claude_mpm/agents/BASE_PROMPT_ENGINEER.md +0 -787
- claude_mpm/agents/BASE_QA.md +0 -167
- claude_mpm/agents/BASE_RESEARCH.md +0 -53
- claude_mpm/agents/base_agent_loader.py +0 -626
- claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -17
- claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +0 -3
- claude_mpm/agents/templates/agent-manager.json +0 -273
- claude_mpm/agents/templates/agentic-coder-optimizer.json +0 -248
- claude_mpm/agents/templates/api_qa.json +0 -183
- claude_mpm/agents/templates/circuit_breakers.md +0 -638
- claude_mpm/agents/templates/clerk-ops.json +0 -235
- claude_mpm/agents/templates/code_analyzer.json +0 -101
- claude_mpm/agents/templates/content-agent.json +0 -358
- claude_mpm/agents/templates/dart_engineer.json +0 -307
- claude_mpm/agents/templates/data_engineer.json +0 -225
- claude_mpm/agents/templates/documentation.json +0 -238
- claude_mpm/agents/templates/engineer.json +0 -210
- claude_mpm/agents/templates/gcp_ops_agent.json +0 -253
- claude_mpm/agents/templates/golang_engineer.json +0 -270
- claude_mpm/agents/templates/imagemagick.json +0 -264
- claude_mpm/agents/templates/java_engineer.json +0 -346
- claude_mpm/agents/templates/javascript_engineer_agent.json +0 -380
- claude_mpm/agents/templates/local_ops_agent.json +0 -1840
- claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +0 -39
- claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +0 -400
- claude_mpm/agents/templates/memory_manager.json +0 -158
- claude_mpm/agents/templates/nextjs_engineer.json +0 -285
- claude_mpm/agents/templates/ops.json +0 -185
- claude_mpm/agents/templates/php-engineer.json +0 -287
- claude_mpm/agents/templates/product_owner.json +0 -338
- claude_mpm/agents/templates/project_organizer.json +0 -144
- claude_mpm/agents/templates/prompt-engineer.json +0 -737
- claude_mpm/agents/templates/python_engineer.json +0 -387
- claude_mpm/agents/templates/qa.json +0 -243
- claude_mpm/agents/templates/react_engineer.json +0 -239
- claude_mpm/agents/templates/refactoring_engineer.json +0 -276
- claude_mpm/agents/templates/research.json +0 -188
- claude_mpm/agents/templates/ruby-engineer.json +0 -280
- claude_mpm/agents/templates/rust_engineer.json +0 -275
- claude_mpm/agents/templates/security.json +0 -202
- claude_mpm/agents/templates/svelte-engineer.json +0 -225
- claude_mpm/agents/templates/tauri_engineer.json +0 -274
- claude_mpm/agents/templates/ticketing.json +0 -178
- claude_mpm/agents/templates/typescript_engineer.json +0 -285
- claude_mpm/agents/templates/vercel_ops_agent.json +0 -412
- claude_mpm/agents/templates/version_control.json +0 -159
- claude_mpm/agents/templates/web_qa.json +0 -400
- claude_mpm/agents/templates/web_ui.json +0 -189
- claude_mpm/cli/commands/agents_detect.py +0 -380
- claude_mpm/cli/commands/agents_recommend.py +0 -309
- claude_mpm/cli/ticket_cli.py +0 -35
- claude_mpm/commands/mpm-agents-detect.md +0 -168
- claude_mpm/commands/mpm-agents-recommend.md +0 -214
- claude_mpm/commands/mpm-agents.md +0 -122
- claude_mpm/commands/mpm-auto-configure.md +0 -269
- claude_mpm/commands/mpm-resume.md +0 -372
- claude_mpm/commands/mpm-tickets.md +0 -151
- claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
- claude_mpm/dashboard/analysis_runner.py +0 -455
- claude_mpm/dashboard/index.html +0 -13
- claude_mpm/dashboard/open_dashboard.py +0 -66
- claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +0 -188
- claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +0 -156
- claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +0 -38
- claude_mpm/dashboard/react/components/shared/FilterBar.module.css +0 -92
- claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +0 -248
- claude_mpm/dashboard/static/archive/activity_dashboard_test.html +0 -61
- claude_mpm/dashboard/static/archive/test_activity_connection.html +0 -179
- claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +0 -68
- claude_mpm/dashboard/static/archive/test_dashboard.html +0 -409
- claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +0 -519
- claude_mpm/dashboard/static/archive/test_dashboard_verification.html +0 -181
- claude_mpm/dashboard/static/archive/test_file_data.html +0 -315
- claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +0 -243
- claude_mpm/dashboard/static/archive/test_file_tree_fix.html +0 -234
- claude_mpm/dashboard/static/archive/test_file_tree_rename.html +0 -117
- claude_mpm/dashboard/static/archive/test_file_tree_tab.html +0 -115
- claude_mpm/dashboard/static/archive/test_file_viewer.html +0 -224
- claude_mpm/dashboard/static/archive/test_final_activity.html +0 -220
- claude_mpm/dashboard/static/archive/test_tab_fix.html +0 -139
- claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +0 -1
- claude_mpm/dashboard/static/built/components/activity-tree.js +0 -2
- claude_mpm/dashboard/static/built/components/agent-hierarchy.js +0 -777
- claude_mpm/dashboard/static/built/components/agent-inference.js +0 -2
- claude_mpm/dashboard/static/built/components/build-tracker.js +0 -333
- claude_mpm/dashboard/static/built/components/code-simple.js +0 -857
- claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +0 -353
- claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +0 -235
- claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +0 -409
- claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +0 -435
- claude_mpm/dashboard/static/built/components/code-tree.js +0 -2
- claude_mpm/dashboard/static/built/components/code-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/connection-debug.js +0 -654
- claude_mpm/dashboard/static/built/components/diff-viewer.js +0 -891
- claude_mpm/dashboard/static/built/components/event-processor.js +0 -2
- claude_mpm/dashboard/static/built/components/event-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/export-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/file-change-tracker.js +0 -443
- claude_mpm/dashboard/static/built/components/file-change-viewer.js +0 -690
- claude_mpm/dashboard/static/built/components/file-tool-tracker.js +0 -2
- claude_mpm/dashboard/static/built/components/file-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/hud-library-loader.js +0 -2
- claude_mpm/dashboard/static/built/components/hud-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/hud-visualizer.js +0 -2
- claude_mpm/dashboard/static/built/components/module-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/nav-bar.js +0 -145
- claude_mpm/dashboard/static/built/components/page-structure.js +0 -429
- claude_mpm/dashboard/static/built/components/session-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/socket-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/ui-state-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/unified-data-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/working-directory.js +0 -2
- claude_mpm/dashboard/static/built/connection-manager.js +0 -536
- claude_mpm/dashboard/static/built/dashboard.js +0 -2
- claude_mpm/dashboard/static/built/extension-error-handler.js +0 -164
- claude_mpm/dashboard/static/built/react/events.js +0 -30
- claude_mpm/dashboard/static/built/shared/dom-helpers.js +0 -396
- claude_mpm/dashboard/static/built/shared/event-bus.js +0 -330
- claude_mpm/dashboard/static/built/shared/event-filter-service.js +0 -540
- claude_mpm/dashboard/static/built/shared/logger.js +0 -385
- claude_mpm/dashboard/static/built/shared/page-structure.js +0 -249
- claude_mpm/dashboard/static/built/shared/tooltip-service.js +0 -253
- claude_mpm/dashboard/static/built/socket-client.js +0 -2
- claude_mpm/dashboard/static/built/tab-isolation-fix.js +0 -185
- claude_mpm/dashboard/static/css/activity.css +0 -1958
- claude_mpm/dashboard/static/css/connection-status.css +0 -370
- claude_mpm/dashboard/static/css/dashboard.css +0 -4701
- claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +0 -1
- claude_mpm/dashboard/static/dist/components/activity-tree.js +0 -2
- claude_mpm/dashboard/static/dist/components/agent-inference.js +0 -2
- claude_mpm/dashboard/static/dist/components/code-tree.js +0 -2
- claude_mpm/dashboard/static/dist/components/code-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/event-processor.js +0 -2
- claude_mpm/dashboard/static/dist/components/event-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/export-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +0 -2
- claude_mpm/dashboard/static/dist/components/file-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-library-loader.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-visualizer.js +0 -2
- claude_mpm/dashboard/static/dist/components/module-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/session-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/socket-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/ui-state-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/working-directory.js +0 -2
- claude_mpm/dashboard/static/dist/dashboard.js +0 -2
- claude_mpm/dashboard/static/dist/react/events.js +0 -30
- claude_mpm/dashboard/static/dist/socket-client.js +0 -2
- claude_mpm/dashboard/static/events.html +0 -607
- claude_mpm/dashboard/static/index.html +0 -635
- claude_mpm/dashboard/static/js/components/activity-tree.js +0 -1871
- claude_mpm/dashboard/static/js/components/agent-hierarchy.js +0 -777
- claude_mpm/dashboard/static/js/components/agent-inference.js +0 -956
- claude_mpm/dashboard/static/js/components/build-tracker.js +0 -333
- claude_mpm/dashboard/static/js/components/code-simple.js +0 -857
- claude_mpm/dashboard/static/js/components/connection-debug.js +0 -654
- claude_mpm/dashboard/static/js/components/diff-viewer.js +0 -891
- claude_mpm/dashboard/static/js/components/event-processor.js +0 -542
- claude_mpm/dashboard/static/js/components/event-viewer.js +0 -1155
- claude_mpm/dashboard/static/js/components/export-manager.js +0 -368
- claude_mpm/dashboard/static/js/components/file-change-tracker.js +0 -443
- claude_mpm/dashboard/static/js/components/file-change-viewer.js +0 -690
- claude_mpm/dashboard/static/js/components/file-tool-tracker.js +0 -724
- claude_mpm/dashboard/static/js/components/file-viewer.js +0 -580
- claude_mpm/dashboard/static/js/components/hud-library-loader.js +0 -211
- claude_mpm/dashboard/static/js/components/hud-manager.js +0 -671
- claude_mpm/dashboard/static/js/components/hud-visualizer.js +0 -1718
- claude_mpm/dashboard/static/js/components/module-viewer.js +0 -2764
- claude_mpm/dashboard/static/js/components/session-manager.js +0 -579
- claude_mpm/dashboard/static/js/components/socket-manager.js +0 -368
- claude_mpm/dashboard/static/js/components/ui-state-manager.js +0 -749
- claude_mpm/dashboard/static/js/components/unified-data-viewer.js +0 -1824
- claude_mpm/dashboard/static/js/components/working-directory.js +0 -920
- claude_mpm/dashboard/static/js/connection-manager.js +0 -536
- claude_mpm/dashboard/static/js/dashboard.js +0 -1896
- claude_mpm/dashboard/static/js/extension-error-handler.js +0 -164
- claude_mpm/dashboard/static/js/shared/dom-helpers.js +0 -396
- claude_mpm/dashboard/static/js/shared/event-bus.js +0 -330
- claude_mpm/dashboard/static/js/shared/logger.js +0 -385
- claude_mpm/dashboard/static/js/shared/tooltip-service.js +0 -253
- claude_mpm/dashboard/static/js/socket-client.js +0 -1457
- claude_mpm/dashboard/static/js/stores/dashboard-store.js +0 -562
- claude_mpm/dashboard/static/js/tab-isolation-fix.js +0 -185
- claude_mpm/dashboard/static/legacy/activity.html +0 -736
- claude_mpm/dashboard/static/legacy/agents.html +0 -786
- claude_mpm/dashboard/static/legacy/files.html +0 -747
- claude_mpm/dashboard/static/legacy/tools.html +0 -831
- claude_mpm/dashboard/static/monitors.html +0 -431
- claude_mpm/dashboard/static/production/events.html +0 -659
- claude_mpm/dashboard/static/production/main.html +0 -698
- claude_mpm/dashboard/static/production/monitors.html +0 -483
- claude_mpm/dashboard/static/socket.io.min.js +0 -7
- claude_mpm/dashboard/static/socket.io.v4.8.1.backup.js +0 -7
- claude_mpm/dashboard/static/test-archive/dashboard.html +0 -635
- claude_mpm/dashboard/static/test-archive/debug-events.html +0 -147
- claude_mpm/dashboard/static/test-archive/test-navigation.html +0 -256
- claude_mpm/dashboard/static/test-archive/test-react-exports.html +0 -180
- claude_mpm/dashboard/static/test-archive/test_debug.html +0 -25
- claude_mpm/dashboard/templates/code_simple.html +0 -153
- claude_mpm/dashboard/templates/index.html +0 -606
- claude_mpm/dashboard/test_dashboard.html +0 -372
- claude_mpm/scripts/mcp_server.py +0 -75
- claude_mpm/scripts/mcp_wrapper.py +0 -39
- claude_mpm/services/mcp_gateway/__init__.py +0 -159
- claude_mpm/services/mcp_gateway/auto_configure.py +0 -369
- claude_mpm/services/mcp_gateway/config/__init__.py +0 -17
- claude_mpm/services/mcp_gateway/config/config_loader.py +0 -296
- claude_mpm/services/mcp_gateway/config/config_schema.py +0 -243
- claude_mpm/services/mcp_gateway/config/configuration.py +0 -429
- claude_mpm/services/mcp_gateway/core/__init__.py +0 -43
- claude_mpm/services/mcp_gateway/core/base.py +0 -312
- claude_mpm/services/mcp_gateway/core/exceptions.py +0 -253
- claude_mpm/services/mcp_gateway/core/interfaces.py +0 -443
- claude_mpm/services/mcp_gateway/core/process_pool.py +0 -971
- claude_mpm/services/mcp_gateway/core/singleton_manager.py +0 -315
- claude_mpm/services/mcp_gateway/core/startup_verification.py +0 -316
- claude_mpm/services/mcp_gateway/main.py +0 -589
- claude_mpm/services/mcp_gateway/registry/__init__.py +0 -12
- claude_mpm/services/mcp_gateway/registry/service_registry.py +0 -412
- claude_mpm/services/mcp_gateway/registry/tool_registry.py +0 -489
- claude_mpm/services/mcp_gateway/server/__init__.py +0 -15
- claude_mpm/services/mcp_gateway/server/mcp_gateway.py +0 -419
- claude_mpm/services/mcp_gateway/server/stdio_handler.py +0 -372
- claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -714
- claude_mpm/services/mcp_gateway/tools/__init__.py +0 -36
- claude_mpm/services/mcp_gateway/tools/base_adapter.py +0 -485
- claude_mpm/services/mcp_gateway/tools/document_summarizer.py +0 -789
- claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +0 -654
- claude_mpm/services/mcp_gateway/tools/health_check_tool.py +0 -456
- claude_mpm/services/mcp_gateway/tools/hello_world.py +0 -551
- claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +0 -551
- claude_mpm/services/mcp_gateway/utils/__init__.py +0 -14
- claude_mpm/services/mcp_gateway/utils/package_version_checker.py +0 -160
- claude_mpm/services/mcp_gateway/utils/update_preferences.py +0 -170
- claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +0 -79
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +0 -178
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +0 -577
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +0 -467
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +0 -537
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +0 -730
- claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +0 -112
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +0 -146
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +0 -412
- claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +0 -81
- claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +0 -362
- claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +0 -312
- claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +0 -152
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +0 -668
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +0 -587
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +0 -438
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +0 -391
- claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +0 -119
- claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +0 -148
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +0 -483
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +0 -452
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +0 -449
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +0 -411
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +0 -14
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +0 -58
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +0 -68
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +0 -69
- claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +0 -131
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +0 -325
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +0 -490
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +0 -425
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +0 -499
- claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +0 -86
- claude_mpm/skills/bundled/main/internal-comms/SKILL.md +0 -43
- claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +0 -47
- claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +0 -65
- claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +0 -30
- claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +0 -16
- claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +0 -160
- claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +0 -412
- claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +0 -602
- claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +0 -915
- claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +0 -916
- claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +0 -752
- claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +0 -1237
- claude_mpm/skills/bundled/main/skill-creator/SKILL.md +0 -189
- claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +0 -500
- claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +0 -464
- claude_mpm/skills/bundled/main/skill-creator/references/examples.md +0 -619
- claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +0 -437
- claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +0 -231
- claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +0 -170
- claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +0 -602
- claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +0 -821
- claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +0 -742
- claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +0 -726
- claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +0 -764
- claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +0 -831
- claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +0 -226
- claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +0 -901
- claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +0 -901
- claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +0 -775
- claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +0 -937
- claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +0 -770
- claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +0 -961
- claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +0 -119
- claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +0 -253
- claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +0 -145
- claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +0 -543
- claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +0 -741
- claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +0 -470
- claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +0 -458
- claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +0 -639
- claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +0 -140
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +0 -572
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +0 -411
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +0 -569
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +0 -695
- claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +0 -184
- claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +0 -459
- claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +0 -479
- claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +0 -687
- claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +0 -758
- claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +0 -868
- claude_mpm-4.24.0.dist-info/entry_points.txt +0 -10
- claude_mpm-4.24.0.dist-info/licenses/LICENSE +0 -21
- /claude_mpm/agents/templates/{git_file_tracking.md → git-file-tracking.md} +0 -0
- /claude_mpm/agents/templates/{pm_examples.md → pm-examples.md} +0 -0
- /claude_mpm/agents/templates/{response_format.md → response-format.md} +0 -0
- /claude_mpm/agents/templates/{validation_templates.md → validation-templates.md} +0 -0
- {claude_mpm-4.24.0.dist-info → claude_mpm-5.4.41.dist-info}/WHEEL +0 -0
- {claude_mpm-4.24.0.dist-info → claude_mpm-5.4.41.dist-info}/top_level.txt +0 -0
|
@@ -21,11 +21,9 @@ from ...services.cli.agent_dependency_service import AgentDependencyService
|
|
|
21
21
|
from ...services.cli.agent_listing_service import AgentListingService
|
|
22
22
|
from ...services.cli.agent_output_formatter import AgentOutputFormatter
|
|
23
23
|
from ...services.cli.agent_validation_service import AgentValidationService
|
|
24
|
-
from ..shared import
|
|
25
|
-
AgentCommand,
|
|
26
|
-
CommandResult,
|
|
27
|
-
)
|
|
24
|
+
from ..shared import AgentCommand, CommandResult
|
|
28
25
|
from ..utils import get_agent_versions_display
|
|
26
|
+
from .agents_cleanup import handle_agents_cleanup
|
|
29
27
|
|
|
30
28
|
|
|
31
29
|
def _is_structured_output(args) -> bool:
|
|
@@ -149,6 +147,7 @@ class AgentsCommand(AgentCommand):
|
|
|
149
147
|
"deps-install": self._install_agent_dependencies,
|
|
150
148
|
"deps-list": self._list_agent_dependencies,
|
|
151
149
|
"deps-fix": self._fix_agent_dependencies,
|
|
150
|
+
"cleanup": lambda a: self._handle_cleanup_command(a),
|
|
152
151
|
"cleanup-orphaned": self._cleanup_orphaned_agents,
|
|
153
152
|
# Local agent management commands
|
|
154
153
|
"create": self._create_local_agent,
|
|
@@ -156,9 +155,25 @@ class AgentsCommand(AgentCommand):
|
|
|
156
155
|
"delete": self._delete_local_agent,
|
|
157
156
|
"manage": self._manage_local_agents,
|
|
158
157
|
"configure": self._configure_deployment,
|
|
159
|
-
#
|
|
160
|
-
"
|
|
161
|
-
|
|
158
|
+
# Migration command (DEPRECATION support)
|
|
159
|
+
"migrate-to-project": self._migrate_to_project,
|
|
160
|
+
# Agent selection modes (Phase 3: 1M-382)
|
|
161
|
+
"deploy-minimal": self._deploy_minimal_configuration,
|
|
162
|
+
"deploy-auto": self._deploy_auto_configure,
|
|
163
|
+
# Agent source management (Phase 2: 1M-442)
|
|
164
|
+
"available": self._list_available_from_sources,
|
|
165
|
+
# Agent discovery with rich filtering (Phase 1: Discovery & Browsing)
|
|
166
|
+
"discover": self._discover_agents,
|
|
167
|
+
# NEW: Collection-based agent management
|
|
168
|
+
"list-collections": self._list_collections,
|
|
169
|
+
"deploy-collection": self._deploy_collection,
|
|
170
|
+
"list-by-collection": self._list_by_collection,
|
|
171
|
+
# Cache git management commands
|
|
172
|
+
"cache-status": self._cache_status,
|
|
173
|
+
"cache-pull": self._cache_pull,
|
|
174
|
+
"cache-push": self._cache_push,
|
|
175
|
+
"cache-sync": self._cache_sync,
|
|
176
|
+
"cache-commit": self._cache_commit,
|
|
162
177
|
}
|
|
163
178
|
|
|
164
179
|
if args.agents_command in command_map:
|
|
@@ -396,31 +411,210 @@ class AgentsCommand(AgentCommand):
|
|
|
396
411
|
self.logger.error(f"Error listing agents by tier: {e}", exc_info=True)
|
|
397
412
|
return CommandResult.error_result(f"Error listing agents by tier: {e}")
|
|
398
413
|
|
|
414
|
+
def _list_available_from_sources(self, args) -> CommandResult:
|
|
415
|
+
"""List available agents from all configured git sources.
|
|
416
|
+
|
|
417
|
+
This command shows agents discovered from configured agent sources
|
|
418
|
+
(Git repositories) after syncing their cache. Implements Phase 2 of 1M-442.
|
|
419
|
+
|
|
420
|
+
Args:
|
|
421
|
+
args: Command arguments with optional source filter and format
|
|
422
|
+
|
|
423
|
+
Returns:
|
|
424
|
+
CommandResult with agent list or error
|
|
425
|
+
"""
|
|
426
|
+
try:
|
|
427
|
+
from ...config.agent_sources import AgentSourceConfiguration
|
|
428
|
+
from ...services.agents.git_source_manager import GitSourceManager
|
|
429
|
+
|
|
430
|
+
# Load agent sources configuration
|
|
431
|
+
config = AgentSourceConfiguration.load()
|
|
432
|
+
enabled_repos = [r for r in config.repositories if r.enabled]
|
|
433
|
+
|
|
434
|
+
if not enabled_repos:
|
|
435
|
+
message = (
|
|
436
|
+
"No agent sources configured.\n\n"
|
|
437
|
+
"Configure sources with:\n"
|
|
438
|
+
" claude-mpm agent-source add <url>\n\n"
|
|
439
|
+
"Example:\n"
|
|
440
|
+
" claude-mpm agent-source add https://github.com/owner/repo/agents"
|
|
441
|
+
)
|
|
442
|
+
print(message)
|
|
443
|
+
return CommandResult.error_result("No agent sources configured")
|
|
444
|
+
|
|
445
|
+
# Initialize git source manager
|
|
446
|
+
manager = GitSourceManager()
|
|
447
|
+
|
|
448
|
+
# Sync all configured sources (with timeout)
|
|
449
|
+
self.logger.info(f"Syncing {len(enabled_repos)} agent sources...")
|
|
450
|
+
sync_results = {}
|
|
451
|
+
|
|
452
|
+
for repo in enabled_repos:
|
|
453
|
+
try:
|
|
454
|
+
result = manager.sync_repository(repo, force=False)
|
|
455
|
+
sync_results[repo.identifier] = result
|
|
456
|
+
except Exception as e:
|
|
457
|
+
self.logger.warning(f"Failed to sync {repo.identifier}: {e}")
|
|
458
|
+
sync_results[repo.identifier] = {"synced": False, "error": str(e)}
|
|
459
|
+
|
|
460
|
+
# Get source filter from args
|
|
461
|
+
source_filter = getattr(args, "source", None)
|
|
462
|
+
|
|
463
|
+
# List all cached agents
|
|
464
|
+
all_agents = manager.list_cached_agents(repo_identifier=source_filter)
|
|
465
|
+
|
|
466
|
+
if not all_agents:
|
|
467
|
+
message = "No agents found in configured sources."
|
|
468
|
+
if sync_results:
|
|
469
|
+
failed_count = sum(
|
|
470
|
+
1 for r in sync_results.values() if not r.get("synced")
|
|
471
|
+
)
|
|
472
|
+
if failed_count > 0:
|
|
473
|
+
message += f"\n\n{failed_count} source(s) failed to sync. Check logs for details."
|
|
474
|
+
print(message)
|
|
475
|
+
return CommandResult.success_result(message, data={"agents": []})
|
|
476
|
+
|
|
477
|
+
# Format output
|
|
478
|
+
output_format = getattr(args, "format", "table")
|
|
479
|
+
|
|
480
|
+
if output_format == "json":
|
|
481
|
+
import json
|
|
482
|
+
|
|
483
|
+
print(json.dumps(all_agents, indent=2))
|
|
484
|
+
elif output_format == "simple":
|
|
485
|
+
for agent in all_agents:
|
|
486
|
+
name = agent.get("metadata", {}).get(
|
|
487
|
+
"name", agent.get("agent_id", "unknown")
|
|
488
|
+
)
|
|
489
|
+
repo = agent.get("repository", "unknown")
|
|
490
|
+
print(f"{name} (from {repo})")
|
|
491
|
+
else: # table format
|
|
492
|
+
print(f"\n{'Agent Name':<30} {'Repository':<40} {'Version':<15}")
|
|
493
|
+
print("=" * 85)
|
|
494
|
+
for agent in all_agents:
|
|
495
|
+
name = agent.get("metadata", {}).get(
|
|
496
|
+
"name", agent.get("agent_id", "unknown")
|
|
497
|
+
)
|
|
498
|
+
repo = agent.get("repository", "unknown")
|
|
499
|
+
version = agent.get("version", "unknown")[:12]
|
|
500
|
+
print(f"{name:<30} {repo:<40} {version:<15}")
|
|
501
|
+
print(
|
|
502
|
+
f"\nTotal: {len(all_agents)} agents from {len(sync_results)} sources"
|
|
503
|
+
)
|
|
504
|
+
|
|
505
|
+
return CommandResult.success_result(
|
|
506
|
+
f"Listed {len(all_agents)} agents from sources",
|
|
507
|
+
data={"agents": all_agents, "sync_results": sync_results},
|
|
508
|
+
)
|
|
509
|
+
|
|
510
|
+
except Exception as e:
|
|
511
|
+
self.logger.error(f"Error listing available agents: {e}", exc_info=True)
|
|
512
|
+
return CommandResult.error_result(f"Error listing available agents: {e}")
|
|
513
|
+
|
|
514
|
+
def _discover_agents(self, args) -> CommandResult:
|
|
515
|
+
"""Discover agents with rich filtering capabilities.
|
|
516
|
+
|
|
517
|
+
This command extends the 'available' command by adding semantic filtering
|
|
518
|
+
based on AUTO-DEPLOY-INDEX.md categories. Users can filter by category,
|
|
519
|
+
language, framework, platform, and specialization.
|
|
520
|
+
|
|
521
|
+
Design Decision: Delegate to agents_discover.py module
|
|
522
|
+
|
|
523
|
+
Rationale: Keep CLI command logic separate from routing logic for better
|
|
524
|
+
testability and maintainability. The discover_command function handles
|
|
525
|
+
all the complex filtering and formatting logic.
|
|
526
|
+
|
|
527
|
+
Args:
|
|
528
|
+
args: Command arguments with filter options:
|
|
529
|
+
- source: Source repository filter
|
|
530
|
+
- category: Category filter (e.g., 'engineer/backend')
|
|
531
|
+
- language: Language filter (e.g., 'python')
|
|
532
|
+
- framework: Framework filter (e.g., 'react')
|
|
533
|
+
- platform: Platform filter (e.g., 'vercel')
|
|
534
|
+
- specialization: Specialization filter (e.g., 'data')
|
|
535
|
+
- format: Output format (table, json, simple)
|
|
536
|
+
- verbose: Show descriptions and metadata
|
|
537
|
+
|
|
538
|
+
Returns:
|
|
539
|
+
CommandResult with filtered agent list or error
|
|
540
|
+
|
|
541
|
+
Example:
|
|
542
|
+
>>> # Called via: claude-mpm agents discover --category engineer/backend
|
|
543
|
+
>>> _discover_agents(args)
|
|
544
|
+
CommandResult(success=True, message="Discovered 8 agents")
|
|
545
|
+
"""
|
|
546
|
+
try:
|
|
547
|
+
from .agents_discover import discover_command
|
|
548
|
+
|
|
549
|
+
# Call discover_command and convert exit code to CommandResult
|
|
550
|
+
exit_code = discover_command(args)
|
|
551
|
+
|
|
552
|
+
if exit_code == 0:
|
|
553
|
+
return CommandResult.success_result("Agent discovery complete")
|
|
554
|
+
return CommandResult.error_result("Agent discovery failed")
|
|
555
|
+
|
|
556
|
+
except Exception as e:
|
|
557
|
+
self.logger.error(f"Error discovering agents: {e}", exc_info=True)
|
|
558
|
+
return CommandResult.error_result(f"Error discovering agents: {e}")
|
|
559
|
+
|
|
399
560
|
def _deploy_agents(self, args, force=False) -> CommandResult:
|
|
400
|
-
"""Deploy
|
|
561
|
+
"""Deploy agents using two-phase sync: cache → deploy.
|
|
562
|
+
|
|
563
|
+
Phase 3 Integration (1M-486): Uses Git sync service for deployment.
|
|
564
|
+
- Phase 1: Sync agents to ~/.claude-mpm/cache/agents/ (if needed)
|
|
565
|
+
- Phase 2: Deploy from cache to project .claude-mpm/agents/
|
|
566
|
+
|
|
567
|
+
This replaces the old single-tier deployment with a multi-project
|
|
568
|
+
architecture where one cache serves multiple project deployments.
|
|
569
|
+
"""
|
|
401
570
|
try:
|
|
402
|
-
#
|
|
403
|
-
|
|
571
|
+
# Handle preset deployment (uses different path)
|
|
572
|
+
if hasattr(args, "preset") and args.preset:
|
|
573
|
+
return self._deploy_preset(args)
|
|
404
574
|
|
|
405
|
-
|
|
406
|
-
|
|
575
|
+
from ...services.agents.sources.git_source_sync_service import (
|
|
576
|
+
GitSourceSyncService,
|
|
577
|
+
)
|
|
407
578
|
|
|
408
|
-
#
|
|
579
|
+
# Initialize git sync service
|
|
580
|
+
git_sync = GitSourceSyncService()
|
|
581
|
+
project_dir = Path.cwd()
|
|
582
|
+
|
|
583
|
+
self.logger.info("Phase 1: Syncing agents to cache...")
|
|
584
|
+
|
|
585
|
+
# Sync to cache (downloads from GitHub if needed)
|
|
586
|
+
sync_result = git_sync.sync_repository(force=force)
|
|
587
|
+
|
|
588
|
+
if not sync_result.get("synced"):
|
|
589
|
+
error_msg = sync_result.get("error", "Unknown sync error")
|
|
590
|
+
self.logger.error(f"Sync failed: {error_msg}")
|
|
591
|
+
return CommandResult.error_result(f"Sync failed: {error_msg}")
|
|
592
|
+
|
|
593
|
+
self.logger.info(
|
|
594
|
+
f"Phase 1 complete: {sync_result.get('agent_count', 0)} agents in cache"
|
|
595
|
+
)
|
|
596
|
+
self.logger.info(f"Phase 2: Deploying agents to {project_dir}...")
|
|
597
|
+
|
|
598
|
+
# Deploy from cache to project directory
|
|
599
|
+
deploy_result = git_sync.deploy_agents_to_project(
|
|
600
|
+
project_dir=project_dir,
|
|
601
|
+
agent_list=None, # Deploy all cached agents
|
|
602
|
+
force=force,
|
|
603
|
+
)
|
|
604
|
+
|
|
605
|
+
# Format combined results for output
|
|
409
606
|
combined_result = {
|
|
410
|
-
"deployed_count":
|
|
411
|
-
+
|
|
412
|
-
"deployed":
|
|
413
|
-
|
|
414
|
-
"
|
|
415
|
-
|
|
416
|
-
"
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
+ project_result.get("errors", []),
|
|
422
|
-
"target_dir": system_result.get("target_dir")
|
|
423
|
-
or project_result.get("target_dir"),
|
|
607
|
+
"deployed_count": len(deploy_result.get("deployed", []))
|
|
608
|
+
+ len(deploy_result.get("updated", [])),
|
|
609
|
+
"deployed": deploy_result.get("deployed", []),
|
|
610
|
+
"updated": deploy_result.get("updated", []),
|
|
611
|
+
"skipped": deploy_result.get("skipped", []),
|
|
612
|
+
"errors": deploy_result.get("failed", []),
|
|
613
|
+
"target_dir": deploy_result.get("deployment_dir", ""),
|
|
614
|
+
"sync_info": {
|
|
615
|
+
"cached_agents": sync_result.get("agent_count", 0),
|
|
616
|
+
"cache_dir": sync_result.get("cache_dir", ""),
|
|
617
|
+
},
|
|
424
618
|
}
|
|
425
619
|
|
|
426
620
|
output_format = self._get_output_format(args)
|
|
@@ -431,12 +625,15 @@ class AgentsCommand(AgentCommand):
|
|
|
431
625
|
)
|
|
432
626
|
print(formatted)
|
|
433
627
|
|
|
628
|
+
success_count = len(deploy_result["deployed"]) + len(
|
|
629
|
+
deploy_result["updated"]
|
|
630
|
+
)
|
|
434
631
|
return CommandResult.success_result(
|
|
435
|
-
f"Deployed {
|
|
632
|
+
f"Deployed {success_count} agents from cache",
|
|
436
633
|
data={
|
|
437
|
-
"
|
|
438
|
-
"
|
|
439
|
-
"total_deployed":
|
|
634
|
+
"sync_result": sync_result,
|
|
635
|
+
"deploy_result": deploy_result,
|
|
636
|
+
"total_deployed": success_count,
|
|
440
637
|
},
|
|
441
638
|
)
|
|
442
639
|
|
|
@@ -444,6 +641,173 @@ class AgentsCommand(AgentCommand):
|
|
|
444
641
|
self.logger.error(f"Error deploying agents: {e}", exc_info=True)
|
|
445
642
|
return CommandResult.error_result(f"Error deploying agents: {e}")
|
|
446
643
|
|
|
644
|
+
def _deploy_preset(self, args) -> CommandResult:
|
|
645
|
+
"""Deploy agents by preset name.
|
|
646
|
+
|
|
647
|
+
This method implements Phase 2 of the agents/skills CLI redesign,
|
|
648
|
+
enabling preset-based deployment like:
|
|
649
|
+
claude-mpm agents deploy --preset python-dev
|
|
650
|
+
|
|
651
|
+
Args:
|
|
652
|
+
args: Command arguments with preset name and optional flags
|
|
653
|
+
|
|
654
|
+
Returns:
|
|
655
|
+
CommandResult with deployment status
|
|
656
|
+
"""
|
|
657
|
+
try:
|
|
658
|
+
from pathlib import Path
|
|
659
|
+
|
|
660
|
+
from ...config.agent_sources import AgentSourceConfiguration
|
|
661
|
+
from ...services.agents.agent_preset_service import AgentPresetService
|
|
662
|
+
from ...services.agents.git_source_manager import GitSourceManager
|
|
663
|
+
from ...services.agents.single_tier_deployment_service import (
|
|
664
|
+
SingleTierDeploymentService,
|
|
665
|
+
)
|
|
666
|
+
|
|
667
|
+
preset_name = args.preset
|
|
668
|
+
dry_run = getattr(args, "dry_run", False)
|
|
669
|
+
|
|
670
|
+
# Initialize services
|
|
671
|
+
config = AgentSourceConfiguration.load()
|
|
672
|
+
deployment_dir = Path.home() / ".claude" / "agents"
|
|
673
|
+
git_source_manager = GitSourceManager()
|
|
674
|
+
preset_service = AgentPresetService(git_source_manager)
|
|
675
|
+
deployment_service = SingleTierDeploymentService(config, deployment_dir)
|
|
676
|
+
|
|
677
|
+
# Validate preset
|
|
678
|
+
if not preset_service.validate_preset(preset_name):
|
|
679
|
+
available = preset_service.list_presets()
|
|
680
|
+
print(f"❌ Unknown preset: {preset_name}")
|
|
681
|
+
print("\n📚 Available presets:")
|
|
682
|
+
for preset in available:
|
|
683
|
+
print(
|
|
684
|
+
f" • {preset['name']}: {preset['description']} ({preset['agent_count']} agents)"
|
|
685
|
+
)
|
|
686
|
+
print(f" Use cases: {', '.join(preset['use_cases'])}")
|
|
687
|
+
return CommandResult.error_result(f"Unknown preset: {preset_name}")
|
|
688
|
+
|
|
689
|
+
# Resolve preset to agent list
|
|
690
|
+
print(f"\n🔍 Resolving preset: {preset_name}")
|
|
691
|
+
resolution = preset_service.resolve_agents(
|
|
692
|
+
preset_name, validate_availability=True
|
|
693
|
+
)
|
|
694
|
+
|
|
695
|
+
# Show preset info
|
|
696
|
+
preset_info = resolution["preset_info"]
|
|
697
|
+
print(f"\n🎯 Preset: {preset_info['description']}")
|
|
698
|
+
print(f" Agents: {preset_info['agent_count']}")
|
|
699
|
+
print(f" Use cases: {', '.join(preset_info['use_cases'])}")
|
|
700
|
+
|
|
701
|
+
# Show warnings for missing agents
|
|
702
|
+
if resolution["missing_agents"]:
|
|
703
|
+
print("\n⚠️ Missing agents (not found in configured sources):")
|
|
704
|
+
for agent_id in resolution["missing_agents"]:
|
|
705
|
+
print(f" • {agent_id}")
|
|
706
|
+
print("\n💡 These agents are not available in your configured sources.")
|
|
707
|
+
print(" Deployment will continue with available agents.")
|
|
708
|
+
|
|
709
|
+
# Show conflicts
|
|
710
|
+
if resolution["conflicts"]:
|
|
711
|
+
print("\n⚠️ Priority conflicts detected:")
|
|
712
|
+
for conflict in resolution["conflicts"]:
|
|
713
|
+
sources = ", ".join(conflict["sources"])
|
|
714
|
+
print(f" • {conflict['agent_id']} (found in: {sources})")
|
|
715
|
+
print(" Using highest priority source for each")
|
|
716
|
+
|
|
717
|
+
# Dry run mode
|
|
718
|
+
if dry_run:
|
|
719
|
+
print("\n🔍 DRY RUN: Preview agent deployment\n")
|
|
720
|
+
print("Agents to deploy:")
|
|
721
|
+
for agent in resolution["agents"]:
|
|
722
|
+
source = agent.get("source", "unknown")
|
|
723
|
+
print(f" ✓ {agent['agent_id']} (from {source})")
|
|
724
|
+
print(
|
|
725
|
+
"\n💡 This is a dry run. Run without --dry-run to actually deploy."
|
|
726
|
+
)
|
|
727
|
+
return CommandResult.success_result(
|
|
728
|
+
"Dry run complete",
|
|
729
|
+
data={
|
|
730
|
+
"preset": preset_name,
|
|
731
|
+
"agents": resolution["agents"],
|
|
732
|
+
"missing": resolution["missing_agents"],
|
|
733
|
+
},
|
|
734
|
+
)
|
|
735
|
+
|
|
736
|
+
# Deploy agents
|
|
737
|
+
print(f"\n📦 Deploying {len(resolution['agents'])} agents...")
|
|
738
|
+
deployed_count = 0
|
|
739
|
+
failed_count = 0
|
|
740
|
+
skipped_count = len(resolution["missing_agents"])
|
|
741
|
+
deployed_agents = []
|
|
742
|
+
failed_agents = []
|
|
743
|
+
|
|
744
|
+
for agent in resolution["agents"]:
|
|
745
|
+
agent_id = agent["agent_id"]
|
|
746
|
+
try:
|
|
747
|
+
# Deploy using single-tier deployment service
|
|
748
|
+
result = deployment_service.deploy_agent(
|
|
749
|
+
agent_id, source_repo=agent.get("source"), dry_run=False
|
|
750
|
+
)
|
|
751
|
+
|
|
752
|
+
if result.get("deployed"):
|
|
753
|
+
deployed_count += 1
|
|
754
|
+
deployed_agents.append(agent_id)
|
|
755
|
+
print(f" ✓ {agent_id}")
|
|
756
|
+
else:
|
|
757
|
+
failed_count += 1
|
|
758
|
+
failed_agents.append(
|
|
759
|
+
{
|
|
760
|
+
"agent_id": agent_id,
|
|
761
|
+
"error": result.get("error", "Unknown"),
|
|
762
|
+
}
|
|
763
|
+
)
|
|
764
|
+
print(f" ✗ {agent_id}: {result.get('error', 'Failed')}")
|
|
765
|
+
|
|
766
|
+
except Exception as e:
|
|
767
|
+
failed_count += 1
|
|
768
|
+
failed_agents.append({"agent_id": agent_id, "error": str(e)})
|
|
769
|
+
print(f" ✗ {agent_id}: {e}")
|
|
770
|
+
|
|
771
|
+
# Summary
|
|
772
|
+
print(f"\n{'=' * 60}")
|
|
773
|
+
print("📊 Deployment Summary")
|
|
774
|
+
print(f"{'=' * 60}")
|
|
775
|
+
print(f" ✅ Deployed: {deployed_count}")
|
|
776
|
+
print(f" ❌ Failed: {failed_count}")
|
|
777
|
+
print(f" ⏭️ Skipped: {skipped_count} (missing from sources)")
|
|
778
|
+
print(f"{'=' * 60}\n")
|
|
779
|
+
|
|
780
|
+
if failed_agents:
|
|
781
|
+
print("❌ Failed agents:")
|
|
782
|
+
for failure in failed_agents:
|
|
783
|
+
print(f" • {failure['agent_id']}: {failure['error']}")
|
|
784
|
+
print()
|
|
785
|
+
|
|
786
|
+
if deployed_count > 0:
|
|
787
|
+
print(f"✅ Successfully deployed {deployed_count} agents!")
|
|
788
|
+
return CommandResult.success_result(
|
|
789
|
+
f"Deployed {deployed_count} agents from preset '{preset_name}'",
|
|
790
|
+
data={
|
|
791
|
+
"preset": preset_name,
|
|
792
|
+
"deployed": deployed_agents,
|
|
793
|
+
"failed": failed_agents,
|
|
794
|
+
"skipped": resolution["missing_agents"],
|
|
795
|
+
},
|
|
796
|
+
)
|
|
797
|
+
return CommandResult.error_result(
|
|
798
|
+
f"No agents deployed from preset '{preset_name}'",
|
|
799
|
+
data={
|
|
800
|
+
"preset": preset_name,
|
|
801
|
+
"failed": failed_agents,
|
|
802
|
+
"skipped": resolution["missing_agents"],
|
|
803
|
+
},
|
|
804
|
+
)
|
|
805
|
+
|
|
806
|
+
except Exception as e:
|
|
807
|
+
self.logger.error(f"Error deploying preset: {e}", exc_info=True)
|
|
808
|
+
print(f"\n❌ Error deploying preset: {e}")
|
|
809
|
+
return CommandResult.error_result(f"Error deploying preset: {e}")
|
|
810
|
+
|
|
447
811
|
def _clean_agents(self, args) -> CommandResult:
|
|
448
812
|
"""Clean deployed agents."""
|
|
449
813
|
try:
|
|
@@ -904,6 +1268,16 @@ class AgentsCommand(AgentCommand):
|
|
|
904
1268
|
self.logger.error(f"Error fixing dependencies: {e}", exc_info=True)
|
|
905
1269
|
return CommandResult.error_result(f"Error fixing dependencies: {e}")
|
|
906
1270
|
|
|
1271
|
+
def _handle_cleanup_command(self, args) -> CommandResult:
|
|
1272
|
+
"""Handle cleanup command with proper result wrapping."""
|
|
1273
|
+
exit_code = handle_agents_cleanup(args)
|
|
1274
|
+
return CommandResult(
|
|
1275
|
+
success=exit_code == 0,
|
|
1276
|
+
message=(
|
|
1277
|
+
"Agent cleanup complete" if exit_code == 0 else "Agent cleanup failed"
|
|
1278
|
+
),
|
|
1279
|
+
)
|
|
1280
|
+
|
|
907
1281
|
def _cleanup_orphaned_agents(self, args) -> CommandResult:
|
|
908
1282
|
"""Clean up orphaned agents that don't have templates."""
|
|
909
1283
|
try:
|
|
@@ -1125,18 +1499,46 @@ class AgentsCommand(AgentCommand):
|
|
|
1125
1499
|
return CommandResult.error_result(f"Error deleting local agents: {e}")
|
|
1126
1500
|
|
|
1127
1501
|
def _manage_local_agents(self, args) -> CommandResult:
|
|
1128
|
-
"""
|
|
1502
|
+
"""Redirect to main configuration interface (DEPRECATED)."""
|
|
1129
1503
|
try:
|
|
1130
|
-
from
|
|
1504
|
+
from rich.console import Console
|
|
1505
|
+
from rich.prompt import Confirm
|
|
1131
1506
|
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1507
|
+
console = Console()
|
|
1508
|
+
|
|
1509
|
+
console.print(
|
|
1510
|
+
"\n[bold cyan]╭─────────────────────────────────────────╮[/bold cyan]"
|
|
1511
|
+
)
|
|
1512
|
+
console.print(
|
|
1513
|
+
"[bold cyan]│ Agent Management Has Moved! │[/bold cyan]"
|
|
1514
|
+
)
|
|
1515
|
+
console.print(
|
|
1516
|
+
"[bold cyan]╰─────────────────────────────────────────╯[/bold cyan]\n"
|
|
1517
|
+
)
|
|
1518
|
+
|
|
1519
|
+
console.print("For a better experience with integrated configuration:")
|
|
1520
|
+
console.print(" • Agent management")
|
|
1521
|
+
console.print(" • Skills management")
|
|
1522
|
+
console.print(" • Template editing")
|
|
1523
|
+
console.print(" • Behavior configuration")
|
|
1524
|
+
console.print(" • Startup settings\n")
|
|
1525
|
+
|
|
1526
|
+
console.print("Please use: [bold green]claude-mpm config[/bold green]\n")
|
|
1527
|
+
|
|
1528
|
+
if Confirm.ask("Launch configuration interface now?", default=True):
|
|
1529
|
+
# Import and run config command directly
|
|
1530
|
+
from claude_mpm.cli.commands.configure import ConfigureCommand
|
|
1531
|
+
|
|
1532
|
+
config_cmd = ConfigureCommand()
|
|
1533
|
+
return config_cmd.execute(args)
|
|
1534
|
+
console.print(
|
|
1535
|
+
"\n[dim]Run 'claude-mpm config' anytime to access agent management[/dim]"
|
|
1536
|
+
)
|
|
1537
|
+
return CommandResult.success_result("Redirected to config interface")
|
|
1136
1538
|
|
|
1137
1539
|
except Exception as e:
|
|
1138
|
-
self.logger.error(f"Error
|
|
1139
|
-
return CommandResult.error_result(f"Error
|
|
1540
|
+
self.logger.error(f"Error redirecting to config: {e}", exc_info=True)
|
|
1541
|
+
return CommandResult.error_result(f"Error redirecting to config: {e}")
|
|
1140
1542
|
|
|
1141
1543
|
def _configure_deployment(self, args) -> CommandResult:
|
|
1142
1544
|
"""Configure agent deployment settings."""
|
|
@@ -1420,33 +1822,692 @@ class AgentsCommand(AgentCommand):
|
|
|
1420
1822
|
f"Error in interactive configuration: {e}"
|
|
1421
1823
|
)
|
|
1422
1824
|
|
|
1423
|
-
def
|
|
1424
|
-
"""
|
|
1825
|
+
def _migrate_to_project(self, args) -> CommandResult:
|
|
1826
|
+
"""Migrate user-level agents to project-level.
|
|
1827
|
+
|
|
1828
|
+
DEPRECATION: User-level agents (~/.claude-mpm/agents/) are deprecated and
|
|
1829
|
+
will be removed in v5.0.0. This command migrates them to project-level
|
|
1830
|
+
(.claude-mpm/agents/) where they belong.
|
|
1831
|
+
|
|
1832
|
+
Args:
|
|
1833
|
+
args: Command arguments with dry_run and force flags
|
|
1834
|
+
|
|
1835
|
+
Returns:
|
|
1836
|
+
CommandResult with migration status
|
|
1837
|
+
"""
|
|
1838
|
+
import shutil
|
|
1839
|
+
|
|
1840
|
+
try:
|
|
1841
|
+
user_agents_dir = Path.home() / ".claude-mpm" / "agents"
|
|
1842
|
+
project_agents_dir = Path.cwd() / ".claude-mpm" / "agents"
|
|
1843
|
+
|
|
1844
|
+
dry_run = getattr(args, "dry_run", False)
|
|
1845
|
+
force = getattr(args, "force", False)
|
|
1846
|
+
|
|
1847
|
+
# Check if user agents directory exists
|
|
1848
|
+
if not user_agents_dir.exists():
|
|
1849
|
+
print("✅ No user-level agents found. Nothing to migrate.")
|
|
1850
|
+
return CommandResult.success_result("No user-level agents to migrate")
|
|
1851
|
+
|
|
1852
|
+
# Find all user agent files
|
|
1853
|
+
user_agent_files = list(user_agents_dir.glob("*.json")) + list(
|
|
1854
|
+
user_agents_dir.glob("*.md")
|
|
1855
|
+
)
|
|
1856
|
+
|
|
1857
|
+
if not user_agent_files:
|
|
1858
|
+
print("✅ No user-level agents found. Nothing to migrate.")
|
|
1859
|
+
return CommandResult.success_result("No user-level agents to migrate")
|
|
1860
|
+
|
|
1861
|
+
# Display what we found
|
|
1862
|
+
print(f"\n📦 Found {len(user_agent_files)} user-level agent(s) to migrate:")
|
|
1863
|
+
for agent_file in user_agent_files:
|
|
1864
|
+
print(f" - {agent_file.name}")
|
|
1865
|
+
|
|
1866
|
+
if dry_run:
|
|
1867
|
+
print("\n🔍 DRY RUN: Would migrate to:")
|
|
1868
|
+
print(f" → {project_agents_dir}")
|
|
1869
|
+
print("\nRun without --dry-run to perform the migration.")
|
|
1870
|
+
return CommandResult.success_result(
|
|
1871
|
+
"Dry run completed",
|
|
1872
|
+
data={
|
|
1873
|
+
"user_agents_found": len(user_agent_files),
|
|
1874
|
+
"target_directory": str(project_agents_dir),
|
|
1875
|
+
},
|
|
1876
|
+
)
|
|
1877
|
+
|
|
1878
|
+
# Create project agents directory
|
|
1879
|
+
project_agents_dir.mkdir(parents=True, exist_ok=True)
|
|
1880
|
+
|
|
1881
|
+
# Migrate agents
|
|
1882
|
+
migrated = 0
|
|
1883
|
+
skipped = 0
|
|
1884
|
+
errors = []
|
|
1885
|
+
|
|
1886
|
+
for agent_file in user_agent_files:
|
|
1887
|
+
target_file = project_agents_dir / agent_file.name
|
|
1888
|
+
|
|
1889
|
+
# Check for conflicts
|
|
1890
|
+
if target_file.exists() and not force:
|
|
1891
|
+
print(f"⚠️ Skipping {agent_file.name} (already exists in project)")
|
|
1892
|
+
print(" Use --force to overwrite existing agents")
|
|
1893
|
+
skipped += 1
|
|
1894
|
+
continue
|
|
1895
|
+
|
|
1896
|
+
try:
|
|
1897
|
+
# Copy agent to project directory
|
|
1898
|
+
shutil.copy2(agent_file, target_file)
|
|
1899
|
+
migrated += 1
|
|
1900
|
+
print(f"✅ Migrated {agent_file.name}")
|
|
1901
|
+
except Exception as e:
|
|
1902
|
+
error_msg = f"Failed to migrate {agent_file.name}: {e}"
|
|
1903
|
+
errors.append(error_msg)
|
|
1904
|
+
print(f"❌ {error_msg}")
|
|
1905
|
+
|
|
1906
|
+
# Summary
|
|
1907
|
+
print("\n📊 Migration Summary:")
|
|
1908
|
+
print(f" ✅ Migrated: {migrated}/{len(user_agent_files)}")
|
|
1909
|
+
if skipped > 0:
|
|
1910
|
+
print(f" ⏭️ Skipped: {skipped} (already exist)")
|
|
1911
|
+
if errors:
|
|
1912
|
+
print(f" ❌ Errors: {len(errors)}")
|
|
1913
|
+
|
|
1914
|
+
if migrated > 0:
|
|
1915
|
+
print(f"\n✅ Successfully migrated {migrated} agent(s) to:")
|
|
1916
|
+
print(f" {project_agents_dir}")
|
|
1917
|
+
print(
|
|
1918
|
+
"\n⚠️ IMPORTANT: Verify agents work correctly, then remove user-level agents:"
|
|
1919
|
+
)
|
|
1920
|
+
print(f" rm -rf {user_agents_dir}")
|
|
1921
|
+
print("\n💡 Why this change?")
|
|
1922
|
+
print(" - Project isolation: Each project has its own agents")
|
|
1923
|
+
print(" - Version control: Agents can be versioned with your code")
|
|
1924
|
+
print(" - Team consistency: Everyone uses the same agents")
|
|
1925
|
+
|
|
1926
|
+
return CommandResult.success_result(
|
|
1927
|
+
f"Migrated {migrated} agents",
|
|
1928
|
+
data={
|
|
1929
|
+
"migrated": migrated,
|
|
1930
|
+
"skipped": skipped,
|
|
1931
|
+
"errors": errors,
|
|
1932
|
+
"total": len(user_agent_files),
|
|
1933
|
+
},
|
|
1934
|
+
)
|
|
1935
|
+
|
|
1936
|
+
except Exception as e:
|
|
1937
|
+
self.logger.error(f"Error migrating agents: {e}", exc_info=True)
|
|
1938
|
+
return CommandResult.error_result(f"Error migrating agents: {e}")
|
|
1939
|
+
|
|
1940
|
+
def _deploy_minimal_configuration(self, args) -> CommandResult:
|
|
1941
|
+
"""Deploy minimal configuration (6 core agents).
|
|
1942
|
+
|
|
1943
|
+
Part of Phase 3 (1M-382): Agent Selection Modes.
|
|
1944
|
+
Deploy exactly 6 agents for basic Claude MPM workflow:
|
|
1945
|
+
engineer, documentation, qa, research, ops, ticketing.
|
|
1946
|
+
"""
|
|
1947
|
+
try:
|
|
1948
|
+
from ...config.agent_sources import AgentSourceConfiguration
|
|
1949
|
+
from ...services.agents.agent_selection_service import AgentSelectionService
|
|
1950
|
+
from ...services.agents.single_tier_deployment_service import (
|
|
1951
|
+
SingleTierDeploymentService,
|
|
1952
|
+
)
|
|
1953
|
+
|
|
1954
|
+
# Initialize services
|
|
1955
|
+
config = AgentSourceConfiguration.load()
|
|
1956
|
+
deployment_dir = Path.home() / ".claude" / "agents"
|
|
1957
|
+
deployment_service = SingleTierDeploymentService(config, deployment_dir)
|
|
1958
|
+
selection_service = AgentSelectionService(deployment_service)
|
|
1959
|
+
|
|
1960
|
+
# Get dry_run flag
|
|
1961
|
+
dry_run = getattr(args, "dry_run", False)
|
|
1962
|
+
|
|
1963
|
+
# Deploy minimal configuration
|
|
1964
|
+
print("🎯 Deploying minimal configuration (6 core agents)...")
|
|
1965
|
+
if dry_run:
|
|
1966
|
+
print("🔍 DRY RUN MODE - No agents will be deployed\n")
|
|
1967
|
+
|
|
1968
|
+
result = selection_service.deploy_minimal_configuration(dry_run=dry_run)
|
|
1969
|
+
|
|
1970
|
+
# Format output
|
|
1971
|
+
output_format = self._get_output_format(args)
|
|
1972
|
+
if self._is_structured_format(output_format):
|
|
1973
|
+
formatted = (
|
|
1974
|
+
self._formatter.format_as_json(result)
|
|
1975
|
+
if str(output_format).lower() == OutputFormat.JSON
|
|
1976
|
+
else self._formatter.format_as_yaml(result)
|
|
1977
|
+
)
|
|
1978
|
+
print(formatted)
|
|
1979
|
+
return CommandResult.success_result(
|
|
1980
|
+
f"Minimal configuration {result['status']}", data=result
|
|
1981
|
+
)
|
|
1982
|
+
|
|
1983
|
+
# Text output
|
|
1984
|
+
print(f"\n{'=' * 60}")
|
|
1985
|
+
print(f"Status: {result['status'].upper()}")
|
|
1986
|
+
print(f"Mode: {result['mode']}")
|
|
1987
|
+
print(f"{'=' * 60}")
|
|
1988
|
+
print(
|
|
1989
|
+
f"\n📊 Summary: {result['deployed_count']} deployed, "
|
|
1990
|
+
f"{result['failed_count']} failed, {result['missing_count']} missing"
|
|
1991
|
+
)
|
|
1992
|
+
|
|
1993
|
+
if result["deployed_agents"]:
|
|
1994
|
+
print(f"\n✅ Deployed agents ({len(result['deployed_agents'])}):")
|
|
1995
|
+
for agent in result["deployed_agents"]:
|
|
1996
|
+
print(f" • {agent}")
|
|
1997
|
+
|
|
1998
|
+
if result["failed_agents"]:
|
|
1999
|
+
print(f"\n❌ Failed agents ({len(result['failed_agents'])}):")
|
|
2000
|
+
for agent in result["failed_agents"]:
|
|
2001
|
+
print(f" • {agent}")
|
|
2002
|
+
|
|
2003
|
+
if result["missing_agents"]:
|
|
2004
|
+
print(f"\n⚠️ Missing agents ({len(result['missing_agents'])}):")
|
|
2005
|
+
for agent in result["missing_agents"]:
|
|
2006
|
+
print(f" • {agent}")
|
|
2007
|
+
print("\nThese agents are not available in configured sources.")
|
|
2008
|
+
|
|
2009
|
+
if dry_run:
|
|
2010
|
+
print(
|
|
2011
|
+
"\n💡 This was a dry run. Run without --dry-run to deploy agents."
|
|
2012
|
+
)
|
|
2013
|
+
|
|
2014
|
+
return CommandResult.success_result(
|
|
2015
|
+
f"Minimal configuration {result['status']}", data=result
|
|
2016
|
+
)
|
|
2017
|
+
|
|
2018
|
+
except Exception as e:
|
|
2019
|
+
self.logger.error(
|
|
2020
|
+
f"Error deploying minimal configuration: {e}", exc_info=True
|
|
2021
|
+
)
|
|
2022
|
+
return CommandResult.error_result(
|
|
2023
|
+
f"Error deploying minimal configuration: {e}"
|
|
2024
|
+
)
|
|
2025
|
+
|
|
2026
|
+
def _deploy_auto_configure(self, args) -> CommandResult:
|
|
2027
|
+
"""Auto-detect toolchain and deploy matching agents.
|
|
2028
|
+
|
|
2029
|
+
Part of Phase 3 (1M-382): Agent Selection Modes.
|
|
2030
|
+
Detect project toolchain (languages, frameworks, build tools) and
|
|
2031
|
+
deploy matching specialized agents.
|
|
2032
|
+
"""
|
|
2033
|
+
try:
|
|
2034
|
+
from ...config.agent_sources import AgentSourceConfiguration
|
|
2035
|
+
from ...services.agents.agent_selection_service import AgentSelectionService
|
|
2036
|
+
from ...services.agents.single_tier_deployment_service import (
|
|
2037
|
+
SingleTierDeploymentService,
|
|
2038
|
+
)
|
|
2039
|
+
|
|
2040
|
+
# Initialize services
|
|
2041
|
+
config = AgentSourceConfiguration.load()
|
|
2042
|
+
deployment_dir = Path.home() / ".claude" / "agents"
|
|
2043
|
+
deployment_service = SingleTierDeploymentService(config, deployment_dir)
|
|
2044
|
+
selection_service = AgentSelectionService(deployment_service)
|
|
2045
|
+
|
|
2046
|
+
# Get arguments
|
|
2047
|
+
project_path = getattr(args, "path", Path.cwd())
|
|
2048
|
+
dry_run = getattr(args, "dry_run", False)
|
|
2049
|
+
|
|
2050
|
+
# Deploy auto-configure
|
|
2051
|
+
print(f"🔍 Auto-detecting toolchain in {project_path}...")
|
|
2052
|
+
if dry_run:
|
|
2053
|
+
print("🔍 DRY RUN MODE - No agents will be deployed\n")
|
|
2054
|
+
|
|
2055
|
+
result = selection_service.deploy_auto_configure(
|
|
2056
|
+
project_path=project_path, dry_run=dry_run
|
|
2057
|
+
)
|
|
2058
|
+
|
|
2059
|
+
# Format output
|
|
2060
|
+
output_format = self._get_output_format(args)
|
|
2061
|
+
if self._is_structured_format(output_format):
|
|
2062
|
+
formatted = (
|
|
2063
|
+
self._formatter.format_as_json(result)
|
|
2064
|
+
if str(output_format).lower() == OutputFormat.JSON
|
|
2065
|
+
else self._formatter.format_as_yaml(result)
|
|
2066
|
+
)
|
|
2067
|
+
print(formatted)
|
|
2068
|
+
return CommandResult.success_result(
|
|
2069
|
+
f"Auto-configure {result['status']}", data=result
|
|
2070
|
+
)
|
|
2071
|
+
|
|
2072
|
+
# Text output
|
|
2073
|
+
print(f"\n{'=' * 60}")
|
|
2074
|
+
print(f"Status: {result['status'].upper()}")
|
|
2075
|
+
print(f"Mode: {result['mode']}")
|
|
2076
|
+
print(f"{'=' * 60}")
|
|
2077
|
+
|
|
2078
|
+
# Show detected toolchain
|
|
2079
|
+
toolchain = result.get("toolchain", {})
|
|
2080
|
+
print("\n🔧 Detected Toolchain:")
|
|
2081
|
+
if toolchain.get("languages"):
|
|
2082
|
+
print(f" Languages: {', '.join(toolchain['languages'])}")
|
|
2083
|
+
if toolchain.get("frameworks"):
|
|
2084
|
+
print(f" Frameworks: {', '.join(toolchain['frameworks'])}")
|
|
2085
|
+
if toolchain.get("build_tools"):
|
|
2086
|
+
print(f" Build Tools: {', '.join(toolchain['build_tools'])}")
|
|
2087
|
+
|
|
2088
|
+
if not any(toolchain.values()):
|
|
2089
|
+
print(" (No toolchain detected)")
|
|
2090
|
+
|
|
2091
|
+
# Show recommended agents
|
|
2092
|
+
recommended = result.get("recommended_agents", [])
|
|
2093
|
+
if recommended:
|
|
2094
|
+
print(f"\n🎯 Recommended agents ({len(recommended)}):")
|
|
2095
|
+
for agent in recommended:
|
|
2096
|
+
print(f" • {agent}")
|
|
2097
|
+
|
|
2098
|
+
# Show deployment summary
|
|
2099
|
+
print(
|
|
2100
|
+
f"\n📊 Summary: {result['deployed_count']} deployed, "
|
|
2101
|
+
f"{result['failed_count']} failed, {result['missing_count']} missing"
|
|
2102
|
+
)
|
|
2103
|
+
|
|
2104
|
+
if result.get("deployed_agents"):
|
|
2105
|
+
print(f"\n✅ Deployed agents ({len(result['deployed_agents'])}):")
|
|
2106
|
+
for agent in result["deployed_agents"]:
|
|
2107
|
+
print(f" • {agent}")
|
|
2108
|
+
|
|
2109
|
+
if result.get("failed_agents"):
|
|
2110
|
+
print(f"\n❌ Failed agents ({len(result['failed_agents'])}):")
|
|
2111
|
+
for agent in result["failed_agents"]:
|
|
2112
|
+
print(f" • {agent}")
|
|
2113
|
+
|
|
2114
|
+
if result.get("missing_agents"):
|
|
2115
|
+
print(f"\n⚠️ Missing agents ({len(result['missing_agents'])}):")
|
|
2116
|
+
for agent in result["missing_agents"]:
|
|
2117
|
+
print(f" • {agent}")
|
|
2118
|
+
print("\nThese agents are not available in configured sources.")
|
|
2119
|
+
|
|
2120
|
+
if dry_run:
|
|
2121
|
+
print(
|
|
2122
|
+
"\n💡 This was a dry run. Run without --dry-run to deploy agents."
|
|
2123
|
+
)
|
|
2124
|
+
|
|
2125
|
+
return CommandResult.success_result(
|
|
2126
|
+
f"Auto-configure {result['status']}", data=result
|
|
2127
|
+
)
|
|
2128
|
+
|
|
2129
|
+
except Exception as e:
|
|
2130
|
+
self.logger.error(f"Error in auto-configure: {e}", exc_info=True)
|
|
2131
|
+
return CommandResult.error_result(f"Error in auto-configure: {e}")
|
|
2132
|
+
|
|
2133
|
+
def _list_collections(self, args) -> CommandResult:
|
|
2134
|
+
"""List all available agent collections.
|
|
2135
|
+
|
|
2136
|
+
NEW: Shows all collections with agent counts and metadata.
|
|
2137
|
+
Enables discovery of available agent collections before deployment.
|
|
2138
|
+
"""
|
|
2139
|
+
try:
|
|
2140
|
+
from pathlib import Path
|
|
2141
|
+
|
|
2142
|
+
from ...services.agents.deployment.remote_agent_discovery_service import (
|
|
2143
|
+
RemoteAgentDiscoveryService,
|
|
2144
|
+
)
|
|
2145
|
+
|
|
2146
|
+
# Get remote agents cache directory
|
|
2147
|
+
cache_dir = Path.home() / ".claude-mpm" / "cache" / "agents"
|
|
2148
|
+
|
|
2149
|
+
if not cache_dir.exists():
|
|
2150
|
+
return CommandResult.error_result(
|
|
2151
|
+
"No remote agent collections found. Run 'claude-mpm agents deploy' first."
|
|
2152
|
+
)
|
|
2153
|
+
|
|
2154
|
+
# Use RemoteAgentDiscoveryService to list collections
|
|
2155
|
+
remote_service = RemoteAgentDiscoveryService(cache_dir)
|
|
2156
|
+
collections = remote_service.list_collections()
|
|
2157
|
+
|
|
2158
|
+
if not collections:
|
|
2159
|
+
return CommandResult.success_result(
|
|
2160
|
+
"No agent collections found in cache.", data={"collections": []}
|
|
2161
|
+
)
|
|
2162
|
+
|
|
2163
|
+
# Format output
|
|
2164
|
+
output_lines = ["Available Agent Collections:\n"]
|
|
2165
|
+
for collection in collections:
|
|
2166
|
+
output_lines.append(
|
|
2167
|
+
f" • {collection['collection_id']} ({collection['agent_count']} agents)"
|
|
2168
|
+
)
|
|
2169
|
+
|
|
2170
|
+
return CommandResult.success_result(
|
|
2171
|
+
"\n".join(output_lines), data={"collections": collections}
|
|
2172
|
+
)
|
|
2173
|
+
|
|
2174
|
+
except Exception as e:
|
|
2175
|
+
self.logger.error(f"Error listing collections: {e}", exc_info=True)
|
|
2176
|
+
return CommandResult.error_result(f"Error listing collections: {e}")
|
|
2177
|
+
|
|
2178
|
+
def _deploy_collection(self, args) -> CommandResult:
|
|
2179
|
+
"""Deploy all agents from a specific collection.
|
|
2180
|
+
|
|
2181
|
+
NEW: Enables bulk deployment of all agents from a named collection.
|
|
2182
|
+
Useful for deploying entire agent sets at once.
|
|
2183
|
+
"""
|
|
2184
|
+
try:
|
|
2185
|
+
from pathlib import Path
|
|
2186
|
+
|
|
2187
|
+
from ...services.agents.deployment.multi_source_deployment_service import (
|
|
2188
|
+
MultiSourceAgentDeploymentService,
|
|
2189
|
+
)
|
|
2190
|
+
|
|
2191
|
+
collection_id = args.collection_id
|
|
2192
|
+
|
|
2193
|
+
# Get agents from collection
|
|
2194
|
+
service = MultiSourceAgentDeploymentService()
|
|
2195
|
+
cache_dir = Path.home() / ".claude-mpm" / "cache" / "agents"
|
|
2196
|
+
agents = service.get_agents_by_collection(collection_id, cache_dir)
|
|
2197
|
+
|
|
2198
|
+
if not agents:
|
|
2199
|
+
return CommandResult.error_result(
|
|
2200
|
+
f"No agents found in collection '{collection_id}'"
|
|
2201
|
+
)
|
|
2202
|
+
|
|
2203
|
+
# Dry run mode
|
|
2204
|
+
if getattr(args, "dry_run", False):
|
|
2205
|
+
agent_names = [
|
|
2206
|
+
agent.get("metadata", {}).get("name", "Unknown") for agent in agents
|
|
2207
|
+
]
|
|
2208
|
+
output = f"Would deploy {len(agents)} agents from collection '{collection_id}':\n"
|
|
2209
|
+
for name in agent_names:
|
|
2210
|
+
output += f" • {name}\n"
|
|
2211
|
+
return CommandResult.success_result(
|
|
2212
|
+
output,
|
|
2213
|
+
data={"collection_id": collection_id, "agent_count": len(agents)},
|
|
2214
|
+
)
|
|
2215
|
+
|
|
2216
|
+
# Deploy agents
|
|
2217
|
+
# TODO: Implement actual deployment logic using deployment service
|
|
2218
|
+
# For now, show what would be deployed
|
|
2219
|
+
return CommandResult.success_result(
|
|
2220
|
+
f"Deployment of collection '{collection_id}' would deploy {len(agents)} agents.\n"
|
|
2221
|
+
f"(Full deployment implementation pending)",
|
|
2222
|
+
data={
|
|
2223
|
+
"collection_id": collection_id,
|
|
2224
|
+
"agent_count": len(agents),
|
|
2225
|
+
"status": "pending_implementation",
|
|
2226
|
+
},
|
|
2227
|
+
)
|
|
2228
|
+
|
|
2229
|
+
except Exception as e:
|
|
2230
|
+
self.logger.error(f"Error deploying collection: {e}", exc_info=True)
|
|
2231
|
+
return CommandResult.error_result(f"Error deploying collection: {e}")
|
|
2232
|
+
|
|
2233
|
+
def _list_by_collection(self, args) -> CommandResult:
|
|
2234
|
+
"""List agents from a specific collection.
|
|
1425
2235
|
|
|
1426
|
-
|
|
2236
|
+
NEW: Shows detailed information about agents in a collection.
|
|
2237
|
+
Supports multiple output formats (table, json, yaml).
|
|
1427
2238
|
"""
|
|
1428
2239
|
try:
|
|
1429
|
-
|
|
2240
|
+
import json as json_lib
|
|
2241
|
+
from pathlib import Path
|
|
2242
|
+
|
|
2243
|
+
from ...services.agents.deployment.multi_source_deployment_service import (
|
|
2244
|
+
MultiSourceAgentDeploymentService,
|
|
2245
|
+
)
|
|
2246
|
+
|
|
2247
|
+
collection_id = args.collection_id
|
|
2248
|
+
output_format = getattr(args, "format", "table")
|
|
2249
|
+
|
|
2250
|
+
# Get agents from collection
|
|
2251
|
+
service = MultiSourceAgentDeploymentService()
|
|
2252
|
+
cache_dir = Path.home() / ".claude-mpm" / "cache" / "agents"
|
|
2253
|
+
agents = service.get_agents_by_collection(collection_id, cache_dir)
|
|
2254
|
+
|
|
2255
|
+
if not agents:
|
|
2256
|
+
return CommandResult.error_result(
|
|
2257
|
+
f"No agents found in collection '{collection_id}'"
|
|
2258
|
+
)
|
|
2259
|
+
|
|
2260
|
+
# Format output based on requested format
|
|
2261
|
+
if output_format == "json":
|
|
2262
|
+
return CommandResult.success_result(
|
|
2263
|
+
json_lib.dumps(agents, indent=2),
|
|
2264
|
+
data={"collection_id": collection_id, "agents": agents},
|
|
2265
|
+
)
|
|
2266
|
+
if output_format == "yaml":
|
|
2267
|
+
try:
|
|
2268
|
+
import yaml
|
|
2269
|
+
|
|
2270
|
+
return CommandResult.success_result(
|
|
2271
|
+
yaml.dump(agents, default_flow_style=False),
|
|
2272
|
+
data={"collection_id": collection_id, "agents": agents},
|
|
2273
|
+
)
|
|
2274
|
+
except ImportError:
|
|
2275
|
+
return CommandResult.error_result(
|
|
2276
|
+
"YAML support not available (install PyYAML)"
|
|
2277
|
+
)
|
|
2278
|
+
|
|
2279
|
+
# Table format (default)
|
|
2280
|
+
output_lines = [f"Agents in collection '{collection_id}':\n"]
|
|
2281
|
+
for agent in agents:
|
|
2282
|
+
metadata = agent.get("metadata", {})
|
|
2283
|
+
name = metadata.get("name", "Unknown")
|
|
2284
|
+
description = metadata.get("description", "No description")
|
|
2285
|
+
version = agent.get("version", "unknown")
|
|
2286
|
+
output_lines.append(f" • {name} (v{version})")
|
|
2287
|
+
output_lines.append(f" {description}\n")
|
|
2288
|
+
|
|
2289
|
+
return CommandResult.success_result(
|
|
2290
|
+
"\n".join(output_lines),
|
|
2291
|
+
data={"collection_id": collection_id, "agent_count": len(agents)},
|
|
2292
|
+
)
|
|
1430
2293
|
|
|
1431
|
-
cmd = AgentsDetectCommand()
|
|
1432
|
-
return cmd.run(args)
|
|
1433
2294
|
except Exception as e:
|
|
1434
|
-
self.logger.error(f"Error
|
|
1435
|
-
return CommandResult.error_result(f"Error
|
|
2295
|
+
self.logger.error(f"Error listing collection agents: {e}", exc_info=True)
|
|
2296
|
+
return CommandResult.error_result(f"Error listing collection agents: {e}")
|
|
1436
2297
|
|
|
1437
|
-
def
|
|
1438
|
-
"""
|
|
2298
|
+
def _cache_status(self, args) -> CommandResult:
|
|
2299
|
+
"""Show git status of agent cache.
|
|
1439
2300
|
|
|
1440
|
-
|
|
2301
|
+
Displays current branch, uncommitted changes, unpushed commits, and
|
|
2302
|
+
remote URL for the agent cache repository.
|
|
1441
2303
|
"""
|
|
1442
2304
|
try:
|
|
1443
|
-
from .
|
|
2305
|
+
from ...services.agents.cache_git_manager import CacheGitManager
|
|
2306
|
+
|
|
2307
|
+
cache_dir = Path.home() / ".claude-mpm" / "cache" / "agents"
|
|
2308
|
+
manager = CacheGitManager(cache_dir)
|
|
2309
|
+
|
|
2310
|
+
if not manager.is_git_repo():
|
|
2311
|
+
print("❌ Cache is not a git repository")
|
|
2312
|
+
print(f"\nCache location: {cache_dir}")
|
|
2313
|
+
print(
|
|
2314
|
+
"\n💡 This is expected if you haven't cloned the agents repository."
|
|
2315
|
+
)
|
|
2316
|
+
print(" The cache will be managed via HTTP sync instead.")
|
|
2317
|
+
return CommandResult.error_result("Cache is not a git repository")
|
|
2318
|
+
|
|
2319
|
+
status = manager.get_status()
|
|
2320
|
+
output_format = self._get_output_format(args)
|
|
2321
|
+
|
|
2322
|
+
if self._is_structured_format(output_format):
|
|
2323
|
+
formatted = (
|
|
2324
|
+
self._formatter.format_as_json(status)
|
|
2325
|
+
if str(output_format).lower() == OutputFormat.JSON
|
|
2326
|
+
else self._formatter.format_as_yaml(status)
|
|
2327
|
+
)
|
|
2328
|
+
print(formatted)
|
|
2329
|
+
return CommandResult.success_result(
|
|
2330
|
+
"Cache status retrieved", data=status
|
|
2331
|
+
)
|
|
2332
|
+
|
|
2333
|
+
# Text output
|
|
2334
|
+
print(f"\n📁 Cache: {manager.repo_path}")
|
|
2335
|
+
print(f"🌿 Branch: {status.get('branch', 'unknown')}")
|
|
2336
|
+
|
|
2337
|
+
if status.get("remote_url"):
|
|
2338
|
+
print(f"🔗 Remote: {status['remote_url']}")
|
|
2339
|
+
|
|
2340
|
+
# Show sync status
|
|
2341
|
+
ahead = status.get("ahead", 0)
|
|
2342
|
+
behind = status.get("behind", 0)
|
|
2343
|
+
|
|
2344
|
+
if ahead > 0:
|
|
2345
|
+
print(f"📤 Ahead of remote: {ahead} commit(s)")
|
|
2346
|
+
if behind > 0:
|
|
2347
|
+
print(f"📥 Behind remote: {behind} commit(s)")
|
|
2348
|
+
|
|
2349
|
+
if ahead == 0 and behind == 0:
|
|
2350
|
+
print("✅ In sync with remote")
|
|
2351
|
+
|
|
2352
|
+
# Show uncommitted changes
|
|
2353
|
+
uncommitted = status.get("uncommitted", [])
|
|
2354
|
+
if uncommitted:
|
|
2355
|
+
print(f"\n⚠️ Uncommitted changes: {len(uncommitted)}")
|
|
2356
|
+
for file in uncommitted[:10]: # Show max 10 files
|
|
2357
|
+
print(f" - {file}")
|
|
2358
|
+
if len(uncommitted) > 10:
|
|
2359
|
+
print(f" ... and {len(uncommitted) - 10} more")
|
|
2360
|
+
else:
|
|
2361
|
+
print("\n✅ No uncommitted changes")
|
|
2362
|
+
|
|
2363
|
+
# Overall status
|
|
2364
|
+
if status.get("is_clean"):
|
|
2365
|
+
print("\n✨ Cache is clean and up-to-date")
|
|
2366
|
+
else:
|
|
2367
|
+
print("\n💡 Run 'claude-mpm agents cache-sync' to sync with remote")
|
|
2368
|
+
|
|
2369
|
+
return CommandResult.success_result("Cache status displayed", data=status)
|
|
2370
|
+
|
|
2371
|
+
except Exception as e:
|
|
2372
|
+
self.logger.error(f"Error getting cache status: {e}", exc_info=True)
|
|
2373
|
+
return CommandResult.error_result(f"Error getting cache status: {e}")
|
|
2374
|
+
|
|
2375
|
+
def _cache_pull(self, args) -> CommandResult:
|
|
2376
|
+
"""Pull latest agents from remote repository."""
|
|
2377
|
+
try:
|
|
2378
|
+
from ...services.agents.cache_git_manager import CacheGitManager
|
|
2379
|
+
|
|
2380
|
+
cache_dir = Path.home() / ".claude-mpm" / "cache" / "agents"
|
|
2381
|
+
manager = CacheGitManager(cache_dir)
|
|
2382
|
+
|
|
2383
|
+
if not manager.is_git_repo():
|
|
2384
|
+
print("❌ Cache is not a git repository")
|
|
2385
|
+
return CommandResult.error_result("Cache is not a git repository")
|
|
2386
|
+
|
|
2387
|
+
branch = getattr(args, "branch", "main")
|
|
2388
|
+
print(f"🔄 Pulling latest changes from {branch}...")
|
|
2389
|
+
|
|
2390
|
+
success, msg = manager.pull_latest(branch)
|
|
2391
|
+
|
|
2392
|
+
if success:
|
|
2393
|
+
print(f"✅ {msg}")
|
|
2394
|
+
return CommandResult.success_result(msg)
|
|
2395
|
+
print(f"❌ {msg}")
|
|
2396
|
+
return CommandResult.error_result(msg)
|
|
2397
|
+
|
|
2398
|
+
except Exception as e:
|
|
2399
|
+
self.logger.error(f"Error pulling cache: {e}", exc_info=True)
|
|
2400
|
+
return CommandResult.error_result(f"Error pulling cache: {e}")
|
|
2401
|
+
|
|
2402
|
+
def _cache_commit(self, args) -> CommandResult:
|
|
2403
|
+
"""Commit changes to cache repository."""
|
|
2404
|
+
try:
|
|
2405
|
+
from ...services.agents.cache_git_manager import CacheGitManager
|
|
2406
|
+
|
|
2407
|
+
cache_dir = Path.home() / ".claude-mpm" / "cache" / "agents"
|
|
2408
|
+
manager = CacheGitManager(cache_dir)
|
|
2409
|
+
|
|
2410
|
+
if not manager.is_git_repo():
|
|
2411
|
+
print("❌ Cache is not a git repository")
|
|
2412
|
+
return CommandResult.error_result("Cache is not a git repository")
|
|
2413
|
+
|
|
2414
|
+
# Get commit message from args
|
|
2415
|
+
message = getattr(args, "message", None)
|
|
2416
|
+
if not message:
|
|
2417
|
+
# Default message
|
|
2418
|
+
message = "feat: update agents from local development"
|
|
2419
|
+
|
|
2420
|
+
print("💾 Committing changes...")
|
|
2421
|
+
success, msg = manager.commit_changes(message)
|
|
2422
|
+
|
|
2423
|
+
if success:
|
|
2424
|
+
print(f"✅ {msg}")
|
|
2425
|
+
print(f"\n💡 Commit message: {message}")
|
|
2426
|
+
return CommandResult.success_result(msg)
|
|
2427
|
+
print(f"❌ {msg}")
|
|
2428
|
+
return CommandResult.error_result(msg)
|
|
2429
|
+
|
|
2430
|
+
except Exception as e:
|
|
2431
|
+
self.logger.error(f"Error committing cache changes: {e}", exc_info=True)
|
|
2432
|
+
return CommandResult.error_result(f"Error committing cache changes: {e}")
|
|
2433
|
+
|
|
2434
|
+
def _cache_push(self, args) -> CommandResult:
|
|
2435
|
+
"""Push local agent changes to remote."""
|
|
2436
|
+
try:
|
|
2437
|
+
from ...services.agents.cache_git_manager import CacheGitManager
|
|
2438
|
+
|
|
2439
|
+
cache_dir = Path.home() / ".claude-mpm" / "cache" / "agents"
|
|
2440
|
+
manager = CacheGitManager(cache_dir)
|
|
2441
|
+
|
|
2442
|
+
if not manager.is_git_repo():
|
|
2443
|
+
print("❌ Cache is not a git repository")
|
|
2444
|
+
return CommandResult.error_result("Cache is not a git repository")
|
|
2445
|
+
|
|
2446
|
+
# Check for uncommitted changes
|
|
2447
|
+
if manager.has_uncommitted_changes():
|
|
2448
|
+
print("⚠️ You have uncommitted changes.")
|
|
2449
|
+
print("\n💡 Commit changes first with:")
|
|
2450
|
+
print(" claude-mpm agents cache-commit --message 'your message'")
|
|
2451
|
+
|
|
2452
|
+
# Ask if user wants to commit first
|
|
2453
|
+
auto_commit = getattr(args, "auto_commit", False)
|
|
2454
|
+
if auto_commit:
|
|
2455
|
+
print("\n📝 Auto-committing changes...")
|
|
2456
|
+
success, msg = manager.commit_changes("feat: update agents")
|
|
2457
|
+
if not success:
|
|
2458
|
+
print(f"❌ Commit failed: {msg}")
|
|
2459
|
+
return CommandResult.error_result(f"Commit failed: {msg}")
|
|
2460
|
+
print(f"✅ {msg}")
|
|
2461
|
+
else:
|
|
2462
|
+
return CommandResult.error_result(
|
|
2463
|
+
"Uncommitted changes detected. Commit first or use --auto-commit"
|
|
2464
|
+
)
|
|
2465
|
+
|
|
2466
|
+
# Push changes
|
|
2467
|
+
branch = getattr(args, "branch", "main")
|
|
2468
|
+
print(f"📤 Pushing changes to {branch}...")
|
|
2469
|
+
|
|
2470
|
+
success, msg = manager.push_changes(branch)
|
|
2471
|
+
|
|
2472
|
+
if success:
|
|
2473
|
+
print(f"✅ {msg}")
|
|
2474
|
+
return CommandResult.success_result(msg)
|
|
2475
|
+
print(f"❌ {msg}")
|
|
2476
|
+
return CommandResult.error_result(msg)
|
|
2477
|
+
|
|
2478
|
+
except Exception as e:
|
|
2479
|
+
self.logger.error(f"Error pushing cache: {e}", exc_info=True)
|
|
2480
|
+
return CommandResult.error_result(f"Error pushing cache: {e}")
|
|
2481
|
+
|
|
2482
|
+
def _cache_sync(self, args) -> CommandResult:
|
|
2483
|
+
"""Full cache sync: pull, commit (if needed), push."""
|
|
2484
|
+
try:
|
|
2485
|
+
from ...services.agents.cache_git_manager import CacheGitManager
|
|
2486
|
+
|
|
2487
|
+
cache_dir = Path.home() / ".claude-mpm" / "cache" / "agents"
|
|
2488
|
+
manager = CacheGitManager(cache_dir)
|
|
2489
|
+
|
|
2490
|
+
if not manager.is_git_repo():
|
|
2491
|
+
print("❌ Cache is not a git repository")
|
|
2492
|
+
return CommandResult.error_result("Cache is not a git repository")
|
|
2493
|
+
|
|
2494
|
+
print("🔄 Syncing cache with remote...\n")
|
|
2495
|
+
|
|
2496
|
+
success, msg = manager.sync_with_remote()
|
|
2497
|
+
|
|
2498
|
+
# Print detailed sync message
|
|
2499
|
+
print(msg)
|
|
2500
|
+
|
|
2501
|
+
if success:
|
|
2502
|
+
print("\n✨ Cache sync complete!")
|
|
2503
|
+
return CommandResult.success_result("Cache synced successfully")
|
|
2504
|
+
|
|
2505
|
+
print("\n❌ Cache sync failed. See details above.")
|
|
2506
|
+
return CommandResult.error_result("Cache sync failed")
|
|
1444
2507
|
|
|
1445
|
-
cmd = AgentsRecommendCommand()
|
|
1446
|
-
return cmd.run(args)
|
|
1447
2508
|
except Exception as e:
|
|
1448
|
-
self.logger.error(f"Error
|
|
1449
|
-
return CommandResult.error_result(f"Error
|
|
2509
|
+
self.logger.error(f"Error syncing cache: {e}", exc_info=True)
|
|
2510
|
+
return CommandResult.error_result(f"Error syncing cache: {e}")
|
|
1450
2511
|
|
|
1451
2512
|
|
|
1452
2513
|
def manage_agents(args):
|