claude-mpm 4.21.3__py3-none-any.whl → 5.0.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/BASE_PM.md +12 -0
- claude_mpm/agents/OUTPUT_STYLE.md +3 -48
- claude_mpm/agents/PM_INSTRUCTIONS.md +632 -334
- claude_mpm/agents/WORKFLOW.md +75 -2
- claude_mpm/agents/__init__.py +6 -0
- claude_mpm/agents/agent_loader.py +1 -4
- claude_mpm/agents/base_agent.json +6 -3
- claude_mpm/agents/frontmatter_validator.py +1 -1
- claude_mpm/agents/templates/{circuit_breakers.md → circuit-breakers.md} +370 -3
- claude_mpm/agents/templates/context-management-examples.md +544 -0
- claude_mpm/agents/templates/{pm_red_flags.md → pm-red-flags.md} +89 -19
- 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 +38 -2
- claude_mpm/cli/commands/agent_source.py +774 -0
- claude_mpm/cli/commands/agent_state_manager.py +125 -20
- claude_mpm/cli/commands/agents.py +684 -13
- 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 +2 -6
- claude_mpm/cli/commands/cleanup.py +1 -1
- claude_mpm/cli/commands/config.py +7 -4
- claude_mpm/cli/commands/configure.py +478 -44
- claude_mpm/cli/commands/configure_agent_display.py +4 -4
- 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 +50 -2
- claude_mpm/cli/commands/mpm_init/git_activity.py +10 -10
- claude_mpm/cli/commands/mpm_init/prompts.py +6 -6
- claude_mpm/cli/commands/run.py +124 -128
- claude_mpm/cli/commands/skill_source.py +694 -0
- claude_mpm/cli/commands/skills.py +435 -1
- claude_mpm/cli/executor.py +78 -3
- claude_mpm/cli/interactive/agent_wizard.py +919 -41
- claude_mpm/cli/parsers/agent_source_parser.py +171 -0
- claude_mpm/cli/parsers/agents_parser.py +173 -4
- claude_mpm/cli/parsers/base_parser.py +49 -0
- claude_mpm/cli/parsers/config_parser.py +96 -43
- claude_mpm/cli/parsers/skill_source_parser.py +169 -0
- claude_mpm/cli/parsers/skills_parser.py +138 -0
- claude_mpm/cli/parsers/source_parser.py +138 -0
- claude_mpm/cli/startup.py +499 -84
- 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-auto-configure.md → mpm-agents-auto-configure.md} +9 -0
- claude_mpm/commands/mpm-agents-detect.md +9 -0
- claude_mpm/commands/{mpm-agents.md → mpm-agents-list.md} +9 -0
- claude_mpm/commands/mpm-agents-recommend.md +9 -0
- claude_mpm/commands/{mpm-config.md → mpm-config-view.md} +9 -0
- claude_mpm/commands/mpm-doctor.md +9 -0
- claude_mpm/commands/mpm-help.md +11 -2
- claude_mpm/commands/mpm-init.md +27 -2
- claude_mpm/commands/mpm-monitor.md +9 -0
- claude_mpm/commands/{mpm-resume.md → mpm-session-resume.md} +9 -0
- claude_mpm/commands/mpm-status.md +9 -0
- claude_mpm/commands/{mpm-organize.md → mpm-ticket-organize.md} +9 -0
- claude_mpm/commands/mpm-ticket-view.md +552 -0
- claude_mpm/commands/mpm-version.md +9 -0
- claude_mpm/commands/mpm.md +10 -0
- claude_mpm/config/agent_presets.py +258 -0
- claude_mpm/config/agent_sources.py +325 -0
- claude_mpm/config/skill_sources.py +590 -0
- claude_mpm/constants.py +12 -0
- claude_mpm/core/api_validator.py +1 -1
- claude_mpm/core/claude_runner.py +17 -10
- claude_mpm/core/config.py +24 -0
- claude_mpm/core/constants.py +1 -1
- claude_mpm/core/framework/__init__.py +3 -16
- claude_mpm/core/framework/loaders/instruction_loader.py +25 -5
- claude_mpm/core/framework/processors/metadata_processor.py +1 -1
- claude_mpm/core/hook_error_memory.py +381 -0
- claude_mpm/core/hook_manager.py +41 -2
- claude_mpm/core/interactive_session.py +112 -5
- claude_mpm/core/logger.py +3 -1
- claude_mpm/core/oneshot_session.py +94 -4
- claude_mpm/dashboard/static/css/activity.css +69 -69
- claude_mpm/dashboard/static/css/connection-status.css +10 -10
- claude_mpm/dashboard/static/css/dashboard.css +15 -15
- claude_mpm/dashboard/static/js/components/activity-tree.js +178 -178
- claude_mpm/dashboard/static/js/components/agent-hierarchy.js +101 -101
- claude_mpm/dashboard/static/js/components/agent-inference.js +31 -31
- claude_mpm/dashboard/static/js/components/build-tracker.js +59 -59
- claude_mpm/dashboard/static/js/components/code-simple.js +107 -107
- claude_mpm/dashboard/static/js/components/connection-debug.js +101 -101
- claude_mpm/dashboard/static/js/components/diff-viewer.js +113 -113
- claude_mpm/dashboard/static/js/components/event-viewer.js +12 -12
- claude_mpm/dashboard/static/js/components/file-change-tracker.js +57 -57
- claude_mpm/dashboard/static/js/components/file-change-viewer.js +74 -74
- claude_mpm/dashboard/static/js/components/file-tool-tracker.js +6 -6
- claude_mpm/dashboard/static/js/components/file-viewer.js +42 -42
- claude_mpm/dashboard/static/js/components/module-viewer.js +27 -27
- claude_mpm/dashboard/static/js/components/session-manager.js +14 -14
- claude_mpm/dashboard/static/js/components/socket-manager.js +1 -1
- claude_mpm/dashboard/static/js/components/ui-state-manager.js +14 -14
- claude_mpm/dashboard/static/js/components/unified-data-viewer.js +110 -110
- claude_mpm/dashboard/static/js/components/working-directory.js +8 -8
- claude_mpm/dashboard/static/js/connection-manager.js +76 -76
- claude_mpm/dashboard/static/js/dashboard.js +76 -58
- claude_mpm/dashboard/static/js/extension-error-handler.js +22 -22
- claude_mpm/dashboard/static/js/socket-client.js +138 -121
- claude_mpm/dashboard/templates/code_simple.html +23 -23
- claude_mpm/dashboard/templates/index.html +18 -18
- claude_mpm/experimental/cli_enhancements.py +1 -5
- claude_mpm/hooks/claude_hooks/event_handlers.py +3 -1
- claude_mpm/hooks/claude_hooks/hook_handler.py +24 -7
- claude_mpm/hooks/claude_hooks/installer.py +45 -0
- 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/templates/pre_tool_use_simple.py +78 -0
- claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
- claude_mpm/models/git_repository.py +198 -0
- claude_mpm/scripts/claude-hook-handler.sh +3 -3
- claude_mpm/scripts/start_activity_logging.py +3 -1
- claude_mpm/services/agents/agent_builder.py +45 -9
- claude_mpm/services/agents/agent_preset_service.py +238 -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/deployment/agent_deployment.py +126 -2
- claude_mpm/services/agents/deployment/agent_discovery_service.py +105 -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 +236 -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 +115 -15
- 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 +363 -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 +629 -0
- 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/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 +1055 -0
- claude_mpm/services/agents/startup_sync.py +239 -0
- claude_mpm/services/agents/toolchain_detector.py +474 -0
- claude_mpm/services/cli/session_pause_manager.py +1 -1
- claude_mpm/services/cli/unified_dashboard_manager.py +1 -1
- claude_mpm/services/command_deployment_service.py +92 -1
- 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 +0 -2
- 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/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/direct_relay.py +3 -3
- claude_mpm/services/event_bus/event_bus.py +36 -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 +494 -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/infrastructure/monitoring/resources.py +1 -1
- 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/process_manager.py +1 -1
- claude_mpm/services/local_ops/resource_monitor.py +2 -2
- claude_mpm/services/mcp_gateway/config/configuration.py +1 -1
- claude_mpm/services/mcp_gateway/server/mcp_gateway.py +1 -6
- claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -2
- claude_mpm/services/mcp_gateway/tools/document_summarizer.py +1 -1
- claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +6 -2
- claude_mpm/services/memory/optimizer.py +1 -1
- claude_mpm/services/model/model_router.py +8 -9
- claude_mpm/services/monitor/daemon.py +1 -1
- claude_mpm/services/monitor/server.py +2 -2
- claude_mpm/services/native_agent_converter.py +356 -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/project/documentation_manager.py +2 -1
- claude_mpm/services/project/toolchain_analyzer.py +3 -1
- claude_mpm/services/runner_configuration_service.py +1 -0
- claude_mpm/services/self_upgrade_service.py +165 -7
- claude_mpm/services/skills/__init__.py +18 -0
- claude_mpm/services/skills/git_skill_source_manager.py +1169 -0
- claude_mpm/services/skills/skill_discovery_service.py +568 -0
- claude_mpm/services/skills_config.py +547 -0
- claude_mpm/services/skills_deployer.py +955 -0
- claude_mpm/services/socketio/handlers/connection.py +1 -1
- claude_mpm/services/socketio/handlers/git.py +2 -2
- claude_mpm/services/socketio/server/core.py +1 -4
- 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/cloud_strategies.py +1 -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/visualization/__init__.py +1 -5
- claude_mpm/services/visualization/mermaid_generator.py +2 -3
- claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
- claude_mpm/skills/bundled/performance-profiling.md +6 -0
- claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +2 -2
- 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/tools/code_tree_analyzer/analysis.py +1 -1
- claude_mpm/utils/agent_dependency_loader.py +80 -13
- claude_mpm/utils/dependency_cache.py +3 -1
- claude_mpm/utils/gitignore.py +241 -0
- claude_mpm/utils/log_cleanup.py +3 -3
- claude_mpm/utils/progress.py +383 -0
- claude_mpm/utils/robust_installer.py +3 -5
- claude_mpm/utils/structured_questions.py +619 -0
- {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/METADATA +429 -59
- {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/RECORD +252 -425
- 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 -180
- 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 -211
- 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/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 -140
- 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 -242
- claude_mpm/agents/templates/react_engineer.json +0 -238
- 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/ticketing.json +0 -177
- 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 -157
- claude_mpm/agents/templates/web_qa.json +0 -399
- claude_mpm/agents/templates/web_ui.json +0 -189
- claude_mpm/commands/mpm-tickets.md +0 -102
- claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
- 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/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/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/stores/dashboard-store.js +0 -562
- 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/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/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/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.21.3.dist-info → claude_mpm-5.0.2.dist-info}/WHEEL +0 -0
- {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/top_level.txt +0 -0
|
@@ -8,7 +8,7 @@ import json
|
|
|
8
8
|
import re
|
|
9
9
|
import sys
|
|
10
10
|
from pathlib import Path
|
|
11
|
-
from typing import Any, Dict, Optional, Tuple
|
|
11
|
+
from typing import Any, Dict, List, Optional, Tuple
|
|
12
12
|
|
|
13
13
|
from claude_mpm.core.logging_config import get_logger
|
|
14
14
|
from claude_mpm.services.agents.local_template_manager import (
|
|
@@ -20,13 +20,33 @@ logger = get_logger(__name__)
|
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
class AgentWizard:
|
|
23
|
-
"""
|
|
23
|
+
"""
|
|
24
|
+
Interactive wizard for agent creation and management.
|
|
25
|
+
|
|
26
|
+
DEPRECATED: This interface has been superseded by the unified
|
|
27
|
+
configuration interface. Please use 'claude-mpm config' instead.
|
|
28
|
+
|
|
29
|
+
This class is retained for backward compatibility but will be
|
|
30
|
+
removed in a future version.
|
|
31
|
+
"""
|
|
24
32
|
|
|
25
33
|
def __init__(self):
|
|
26
34
|
"""Initialize the agent wizard."""
|
|
27
35
|
self.manager = LocalAgentTemplateManager()
|
|
28
36
|
self.logger = logger
|
|
29
37
|
|
|
38
|
+
# Initialize remote discovery services
|
|
39
|
+
try:
|
|
40
|
+
from claude_mpm.services.agents.git_source_manager import GitSourceManager
|
|
41
|
+
|
|
42
|
+
self.source_manager = GitSourceManager()
|
|
43
|
+
self.discovery_enabled = True
|
|
44
|
+
self.logger.debug("Remote agent discovery enabled")
|
|
45
|
+
except Exception as e:
|
|
46
|
+
self.logger.warning(f"Failed to initialize remote discovery: {e}")
|
|
47
|
+
self.source_manager = None
|
|
48
|
+
self.discovery_enabled = False
|
|
49
|
+
|
|
30
50
|
def run_interactive_create(self) -> Tuple[bool, str]:
|
|
31
51
|
"""Run interactive agent creation wizard.
|
|
32
52
|
|
|
@@ -55,7 +75,7 @@ class AgentWizard:
|
|
|
55
75
|
model = self._get_model_choice()
|
|
56
76
|
|
|
57
77
|
# Step 5: Inheritance Option
|
|
58
|
-
parent_agent,
|
|
78
|
+
parent_agent, _base_template = self._get_inheritance_option()
|
|
59
79
|
|
|
60
80
|
# Step 6: Capabilities Configuration
|
|
61
81
|
capabilities = self._get_capabilities_configuration()
|
|
@@ -117,6 +137,77 @@ class AgentWizard:
|
|
|
117
137
|
self.logger.error(error_msg, exc_info=True)
|
|
118
138
|
return False, error_msg
|
|
119
139
|
|
|
140
|
+
def _merge_agent_sources(self) -> List[Dict[str, Any]]:
|
|
141
|
+
"""
|
|
142
|
+
Merge agents from all sources with precedence: local > discovered.
|
|
143
|
+
|
|
144
|
+
Returns list of agents with metadata:
|
|
145
|
+
{
|
|
146
|
+
"agent_id": "engineer/backend/python-engineer",
|
|
147
|
+
"name": "Python Engineer",
|
|
148
|
+
"description": "...",
|
|
149
|
+
"source_type": "system" | "project",
|
|
150
|
+
"source_identifier": "bobmatnyc/claude-mpm-agents",
|
|
151
|
+
"category": "engineer/backend",
|
|
152
|
+
"deployed": True | False,
|
|
153
|
+
"path": "/path/to/agent.md"
|
|
154
|
+
}
|
|
155
|
+
"""
|
|
156
|
+
agents = {}
|
|
157
|
+
|
|
158
|
+
# Get discovered agents (system/user sources)
|
|
159
|
+
if self.discovery_enabled and self.source_manager:
|
|
160
|
+
try:
|
|
161
|
+
discovered = self.source_manager.list_cached_agents()
|
|
162
|
+
self.logger.debug(f"Discovered {len(discovered)} remote agents")
|
|
163
|
+
|
|
164
|
+
for agent in discovered:
|
|
165
|
+
agent_id = agent.get("agent_id", "")
|
|
166
|
+
if not agent_id:
|
|
167
|
+
continue
|
|
168
|
+
|
|
169
|
+
# Extract metadata
|
|
170
|
+
metadata = agent.get("metadata", {})
|
|
171
|
+
agents[agent_id] = {
|
|
172
|
+
"agent_id": agent_id,
|
|
173
|
+
"name": metadata.get("name", agent_id),
|
|
174
|
+
"description": metadata.get("description", ""),
|
|
175
|
+
"source_type": "system",
|
|
176
|
+
"source_identifier": agent.get("source", "unknown"),
|
|
177
|
+
"category": agent.get("category", ""),
|
|
178
|
+
"deployed": False, # Will be updated below
|
|
179
|
+
"path": agent.get("path", agent.get("source_file", "")),
|
|
180
|
+
}
|
|
181
|
+
except Exception as e:
|
|
182
|
+
self.logger.warning(f"Failed to discover remote agents: {e}")
|
|
183
|
+
|
|
184
|
+
# Get local agents (project-level, highest precedence)
|
|
185
|
+
local_templates = self.manager.list_local_templates()
|
|
186
|
+
for template in local_templates:
|
|
187
|
+
agent_id = template.agent_id
|
|
188
|
+
agents[agent_id] = {
|
|
189
|
+
"agent_id": agent_id,
|
|
190
|
+
"name": template.metadata.get("name", agent_id),
|
|
191
|
+
"description": template.metadata.get("description", ""),
|
|
192
|
+
"source_type": "project",
|
|
193
|
+
"source_identifier": "local",
|
|
194
|
+
"category": template.metadata.get("category", ""),
|
|
195
|
+
"deployed": True, # Local templates are deployed
|
|
196
|
+
"path": str(self._get_template_path(template)),
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
# Check deployment status for discovered agents
|
|
200
|
+
deployed_dir = Path.cwd() / ".claude" / "agents"
|
|
201
|
+
if deployed_dir.exists():
|
|
202
|
+
for agent_id, agent_data in agents.items():
|
|
203
|
+
deployed_file = deployed_dir / f"{agent_id.replace('/', '-')}.md"
|
|
204
|
+
# Also check hierarchical path
|
|
205
|
+
deployed_file_alt = deployed_dir / f"{agent_id.split('/')[-1]}.md"
|
|
206
|
+
if deployed_file.exists() or deployed_file_alt.exists():
|
|
207
|
+
agent_data["deployed"] = True
|
|
208
|
+
|
|
209
|
+
return list(agents.values())
|
|
210
|
+
|
|
120
211
|
def run_interactive_manage(self) -> Tuple[bool, str]:
|
|
121
212
|
"""Run interactive agent management menu.
|
|
122
213
|
|
|
@@ -125,15 +216,17 @@ class AgentWizard:
|
|
|
125
216
|
"""
|
|
126
217
|
try:
|
|
127
218
|
while True:
|
|
128
|
-
#
|
|
129
|
-
|
|
219
|
+
# Get merged agents from all sources
|
|
220
|
+
all_agents = self._merge_agent_sources()
|
|
130
221
|
|
|
131
222
|
print("\n" + "=" * 60)
|
|
132
223
|
print("🔧 Agent Management Menu")
|
|
133
224
|
print("=" * 60)
|
|
134
225
|
|
|
135
|
-
if not
|
|
136
|
-
print(
|
|
226
|
+
if not all_agents:
|
|
227
|
+
print(
|
|
228
|
+
"\n📭 No agents found. Configure sources with 'claude-mpm agents discover'"
|
|
229
|
+
)
|
|
137
230
|
print("\n1. Create new agent")
|
|
138
231
|
print("2. Import agents")
|
|
139
232
|
print("3. Exit")
|
|
@@ -148,21 +241,44 @@ class AgentWizard:
|
|
|
148
241
|
return True, "Management menu exited"
|
|
149
242
|
print("❌ Invalid choice. Please try again.")
|
|
150
243
|
continue
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
244
|
+
|
|
245
|
+
# Show existing agents in a table
|
|
246
|
+
print(f"\n📋 Found {len(all_agents)} agent(s):\n")
|
|
247
|
+
print(
|
|
248
|
+
f"{'#':<4} {'Agent ID':<40} {'Name':<25} {'Source':<20} {'Status':<10}"
|
|
249
|
+
)
|
|
250
|
+
print("-" * 105)
|
|
251
|
+
|
|
252
|
+
for i, agent in enumerate(all_agents, 1):
|
|
253
|
+
agent_id = agent["agent_id"]
|
|
254
|
+
name = (
|
|
255
|
+
agent["name"][:24] if len(agent["name"]) > 24 else agent["name"]
|
|
256
|
+
)
|
|
257
|
+
source_label = (
|
|
258
|
+
f"[{agent['source_type']}] {agent['source_identifier']}"[:19]
|
|
259
|
+
)
|
|
260
|
+
status = "✓ Deployed" if agent["deployed"] else "Available"
|
|
261
|
+
|
|
155
262
|
print(
|
|
156
|
-
f"
|
|
263
|
+
f"{i:<4} {agent_id:<40} {name:<25} {source_label:<20} {status:<10}"
|
|
157
264
|
)
|
|
158
265
|
|
|
159
|
-
|
|
160
|
-
print(f"{len(
|
|
161
|
-
print(f"{len(
|
|
162
|
-
print(f"{len(
|
|
163
|
-
print(f"{len(
|
|
266
|
+
# Enhanced menu options
|
|
267
|
+
print(f"\n{len(all_agents) + 1}. Deploy agent")
|
|
268
|
+
print(f"{len(all_agents) + 2}. Create new agent")
|
|
269
|
+
print(f"{len(all_agents) + 3}. Delete agent(s)")
|
|
270
|
+
print(f"{len(all_agents) + 4}. Import agents")
|
|
271
|
+
print(f"{len(all_agents) + 5}. Export all agents")
|
|
272
|
+
if self.discovery_enabled:
|
|
273
|
+
print(f"{len(all_agents) + 6}. Browse & filter agents")
|
|
274
|
+
print(f"{len(all_agents) + 7}. Deploy preset")
|
|
275
|
+
print(f"{len(all_agents) + 8}. Manage agent sources")
|
|
276
|
+
print(f"{len(all_agents) + 9}. Exit")
|
|
277
|
+
max_choice = len(all_agents) + 9
|
|
278
|
+
else:
|
|
279
|
+
print(f"{len(all_agents) + 6}. Exit")
|
|
280
|
+
max_choice = len(all_agents) + 6
|
|
164
281
|
|
|
165
|
-
max_choice = len(templates) + 5
|
|
166
282
|
choice = input(f"\nSelect option [1-{max_choice}]: ").strip()
|
|
167
283
|
|
|
168
284
|
try:
|
|
@@ -171,37 +287,46 @@ class AgentWizard:
|
|
|
171
287
|
print("❌ Invalid choice. Please enter a number.")
|
|
172
288
|
continue
|
|
173
289
|
|
|
174
|
-
if 1 <= choice_num <= len(
|
|
175
|
-
#
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
290
|
+
if 1 <= choice_num <= len(all_agents):
|
|
291
|
+
# View agent details
|
|
292
|
+
selected_agent = all_agents[choice_num - 1]
|
|
293
|
+
self._show_agent_details(selected_agent)
|
|
294
|
+
continue
|
|
295
|
+
if choice_num == len(all_agents) + 1:
|
|
296
|
+
self._deploy_agent_interactive(all_agents)
|
|
297
|
+
elif choice_num == len(all_agents) + 2:
|
|
298
|
+
_, message = self.run_interactive_create()
|
|
182
299
|
if message:
|
|
183
|
-
# Message already has emoji from the function
|
|
184
300
|
print(f"\n{message}")
|
|
185
|
-
continue
|
|
186
|
-
elif choice_num == len(
|
|
187
|
-
|
|
301
|
+
continue
|
|
302
|
+
elif choice_num == len(all_agents) + 3:
|
|
303
|
+
local_templates = self.manager.list_local_templates()
|
|
304
|
+
_, message = self._interactive_delete_menu(local_templates)
|
|
188
305
|
if message:
|
|
189
|
-
# Message already has emoji from the function
|
|
190
306
|
print(f"\n{message}")
|
|
191
|
-
continue
|
|
192
|
-
elif choice_num == len(
|
|
193
|
-
|
|
307
|
+
continue
|
|
308
|
+
elif choice_num == len(all_agents) + 4:
|
|
309
|
+
_, message = self._interactive_import()
|
|
194
310
|
if message:
|
|
195
|
-
# Message already has emoji from the function
|
|
196
311
|
print(f"\n{message}")
|
|
197
|
-
continue
|
|
198
|
-
elif choice_num == len(
|
|
199
|
-
|
|
312
|
+
continue
|
|
313
|
+
elif choice_num == len(all_agents) + 5:
|
|
314
|
+
_success, message = self._interactive_export()
|
|
200
315
|
if message:
|
|
201
|
-
# Message already has emoji from the function
|
|
202
316
|
print(f"\n{message}")
|
|
203
|
-
continue
|
|
204
|
-
elif choice_num == len(
|
|
317
|
+
continue
|
|
318
|
+
elif choice_num == len(all_agents) + 6 and self.discovery_enabled:
|
|
319
|
+
self._browse_agents_interactive()
|
|
320
|
+
continue
|
|
321
|
+
elif choice_num == len(all_agents) + 7 and self.discovery_enabled:
|
|
322
|
+
self._deploy_preset_interactive()
|
|
323
|
+
continue
|
|
324
|
+
elif choice_num == len(all_agents) + 8 and self.discovery_enabled:
|
|
325
|
+
self._manage_sources_interactive()
|
|
326
|
+
continue
|
|
327
|
+
elif (choice_num == len(all_agents) + 9 and self.discovery_enabled) or (
|
|
328
|
+
choice_num == len(all_agents) + 6 and not self.discovery_enabled
|
|
329
|
+
):
|
|
205
330
|
return True, "Management menu exited"
|
|
206
331
|
else:
|
|
207
332
|
print("❌ Invalid choice. Please try again.")
|
|
@@ -919,6 +1044,759 @@ class AgentWizard:
|
|
|
919
1044
|
|
|
920
1045
|
return len(results["successful"]) > 0, message.strip()
|
|
921
1046
|
|
|
1047
|
+
def _show_agent_details(self, agent: Dict[str, Any]) -> None:
|
|
1048
|
+
"""Show detailed information about an agent.
|
|
1049
|
+
|
|
1050
|
+
Args:
|
|
1051
|
+
agent: Agent metadata dictionary
|
|
1052
|
+
"""
|
|
1053
|
+
print("\n" + "=" * 60)
|
|
1054
|
+
print(f"📄 Agent Details: {agent['agent_id']}")
|
|
1055
|
+
print("=" * 60)
|
|
1056
|
+
print(f"Name: {agent['name']}")
|
|
1057
|
+
print(f"Category: {agent['category'] or 'N/A'}")
|
|
1058
|
+
print(f"Source: [{agent['source_type']}] {agent['source_identifier']}")
|
|
1059
|
+
print(f"Status: {'✓ Deployed' if agent['deployed'] else 'Available'}")
|
|
1060
|
+
print(f"Path: {agent['path']}")
|
|
1061
|
+
|
|
1062
|
+
if agent["description"]:
|
|
1063
|
+
print("\nDescription:")
|
|
1064
|
+
print(
|
|
1065
|
+
f" {agent['description'][:200]}{'...' if len(agent['description']) > 200 else ''}"
|
|
1066
|
+
)
|
|
1067
|
+
|
|
1068
|
+
input("\nPress Enter to continue...")
|
|
1069
|
+
|
|
1070
|
+
def _deploy_agent_interactive(self, available_agents: List[Dict[str, Any]]):
|
|
1071
|
+
"""Interactive agent deployment.
|
|
1072
|
+
|
|
1073
|
+
Args:
|
|
1074
|
+
available_agents: List of all available agents
|
|
1075
|
+
"""
|
|
1076
|
+
# Filter to non-deployed agents
|
|
1077
|
+
deployable = [a for a in available_agents if not a["deployed"]]
|
|
1078
|
+
|
|
1079
|
+
if not deployable:
|
|
1080
|
+
print("\n✅ All agents are already deployed!")
|
|
1081
|
+
input("\nPress Enter to continue...")
|
|
1082
|
+
return
|
|
1083
|
+
|
|
1084
|
+
print("\n" + "=" * 60)
|
|
1085
|
+
print("📦 Deploy Agent")
|
|
1086
|
+
print("=" * 60)
|
|
1087
|
+
print(f"\n{len(deployable)} agent(s) available to deploy:\n")
|
|
1088
|
+
|
|
1089
|
+
for i, agent in enumerate(deployable, 1):
|
|
1090
|
+
print(f" {i}. {agent['agent_id']}")
|
|
1091
|
+
print(
|
|
1092
|
+
f" {agent['description'][:60]}{'...' if len(agent['description']) > 60 else ''}"
|
|
1093
|
+
)
|
|
1094
|
+
|
|
1095
|
+
choice = input("\nEnter agent number (or 'c' to cancel): ").strip()
|
|
1096
|
+
if choice.lower() == "c":
|
|
1097
|
+
return
|
|
1098
|
+
|
|
1099
|
+
try:
|
|
1100
|
+
idx = int(choice) - 1
|
|
1101
|
+
if idx < 0 or idx >= len(deployable):
|
|
1102
|
+
print("❌ Invalid selection")
|
|
1103
|
+
input("\nPress Enter to continue...")
|
|
1104
|
+
return
|
|
1105
|
+
|
|
1106
|
+
agent = deployable[idx]
|
|
1107
|
+
|
|
1108
|
+
# Deploy agent using deployment service
|
|
1109
|
+
print(f"\n🚀 Deploying {agent['agent_id']}...")
|
|
1110
|
+
|
|
1111
|
+
try:
|
|
1112
|
+
# Use SingleAgentDeployer for deployment
|
|
1113
|
+
from claude_mpm.services.agents.deployment.agent_template_builder import (
|
|
1114
|
+
AgentTemplateBuilder,
|
|
1115
|
+
)
|
|
1116
|
+
from claude_mpm.services.agents.deployment.agent_version_manager import (
|
|
1117
|
+
AgentVersionManager,
|
|
1118
|
+
)
|
|
1119
|
+
from claude_mpm.services.agents.deployment.deployment_results_manager import (
|
|
1120
|
+
DeploymentResultsManager,
|
|
1121
|
+
)
|
|
1122
|
+
from claude_mpm.services.agents.deployment.single_agent_deployer import (
|
|
1123
|
+
SingleAgentDeployer,
|
|
1124
|
+
)
|
|
1125
|
+
|
|
1126
|
+
# Initialize deployment services
|
|
1127
|
+
template_builder = AgentTemplateBuilder()
|
|
1128
|
+
version_manager = AgentVersionManager()
|
|
1129
|
+
results_manager = DeploymentResultsManager(self.logger)
|
|
1130
|
+
deployer = SingleAgentDeployer(
|
|
1131
|
+
template_builder=template_builder,
|
|
1132
|
+
version_manager=version_manager,
|
|
1133
|
+
results_manager=results_manager,
|
|
1134
|
+
logger=self.logger,
|
|
1135
|
+
)
|
|
1136
|
+
|
|
1137
|
+
# Prepare deployment parameters
|
|
1138
|
+
template_path = Path(agent["path"])
|
|
1139
|
+
target_dir = Path.cwd() / ".claude" / "agents"
|
|
1140
|
+
|
|
1141
|
+
# Find base_agent.json in multiple possible locations
|
|
1142
|
+
base_agent_candidates = [
|
|
1143
|
+
Path.home()
|
|
1144
|
+
/ ".claude-mpm"
|
|
1145
|
+
/ "agents"
|
|
1146
|
+
/ "templates"
|
|
1147
|
+
/ "base_agent.json",
|
|
1148
|
+
Path.home() / ".claude-mpm" / "cache" / "base_agent.json",
|
|
1149
|
+
Path(__file__).parent.parent.parent
|
|
1150
|
+
/ "agents"
|
|
1151
|
+
/ "templates"
|
|
1152
|
+
/ "base_agent.json",
|
|
1153
|
+
]
|
|
1154
|
+
base_agent_path = None
|
|
1155
|
+
for candidate in base_agent_candidates:
|
|
1156
|
+
if candidate.exists():
|
|
1157
|
+
base_agent_path = candidate
|
|
1158
|
+
break
|
|
1159
|
+
|
|
1160
|
+
if not base_agent_path:
|
|
1161
|
+
base_agent_path = base_agent_candidates[
|
|
1162
|
+
0
|
|
1163
|
+
] # Use default even if not exists
|
|
1164
|
+
|
|
1165
|
+
# Deploy the agent
|
|
1166
|
+
success = deployer.deploy_agent(
|
|
1167
|
+
agent_name=agent["agent_id"],
|
|
1168
|
+
templates_dir=template_path.parent,
|
|
1169
|
+
target_dir=target_dir,
|
|
1170
|
+
base_agent_path=base_agent_path,
|
|
1171
|
+
force_rebuild=True,
|
|
1172
|
+
working_directory=Path.cwd(),
|
|
1173
|
+
)
|
|
1174
|
+
|
|
1175
|
+
if success:
|
|
1176
|
+
print(f"\n✅ Successfully deployed {agent['agent_id']}")
|
|
1177
|
+
else:
|
|
1178
|
+
print(f"\n❌ Failed to deploy {agent['agent_id']}")
|
|
1179
|
+
|
|
1180
|
+
except Exception as e:
|
|
1181
|
+
self.logger.error(f"Deployment failed: {e}", exc_info=True)
|
|
1182
|
+
print(f"\n❌ Deployment error: {e}")
|
|
1183
|
+
|
|
1184
|
+
input("\nPress Enter to continue...")
|
|
1185
|
+
|
|
1186
|
+
except ValueError:
|
|
1187
|
+
print("❌ Invalid selection")
|
|
1188
|
+
input("\nPress Enter to continue...")
|
|
1189
|
+
except Exception as e:
|
|
1190
|
+
self.logger.error(f"Deployment error: {e}", exc_info=True)
|
|
1191
|
+
print(f"\n❌ Error: {e}")
|
|
1192
|
+
input("\nPress Enter to continue...")
|
|
1193
|
+
|
|
1194
|
+
def _browse_agents_interactive(self):
|
|
1195
|
+
"""Interactive agent browsing with filters."""
|
|
1196
|
+
if not self.discovery_enabled or not self.source_manager:
|
|
1197
|
+
print("\n❌ Discovery service not available")
|
|
1198
|
+
input("\nPress Enter to continue...")
|
|
1199
|
+
return
|
|
1200
|
+
|
|
1201
|
+
while True:
|
|
1202
|
+
print("\n" + "=" * 60)
|
|
1203
|
+
print("🔍 Browse & Filter Agents")
|
|
1204
|
+
print("=" * 60)
|
|
1205
|
+
|
|
1206
|
+
# Show filter menu
|
|
1207
|
+
print("\n[bold]Filter by:[/bold]")
|
|
1208
|
+
print(" [1] Category (engineer/backend, qa, ops, etc.)")
|
|
1209
|
+
print(" [2] Language (python, typescript, rust, etc.)")
|
|
1210
|
+
print(" [3] Framework (react, nextjs, flask, etc.)")
|
|
1211
|
+
print(" [4] Show all agents")
|
|
1212
|
+
print(" [b] Back to main menu")
|
|
1213
|
+
|
|
1214
|
+
choice = input("\nSelect filter option: ").strip()
|
|
1215
|
+
|
|
1216
|
+
if choice == "b":
|
|
1217
|
+
break
|
|
1218
|
+
|
|
1219
|
+
filtered_agents = []
|
|
1220
|
+
filter_description = ""
|
|
1221
|
+
|
|
1222
|
+
if choice == "1":
|
|
1223
|
+
# Category filtering
|
|
1224
|
+
categories = [
|
|
1225
|
+
"engineer/backend",
|
|
1226
|
+
"engineer/frontend",
|
|
1227
|
+
"qa",
|
|
1228
|
+
"ops",
|
|
1229
|
+
"documentation",
|
|
1230
|
+
"universal",
|
|
1231
|
+
]
|
|
1232
|
+
print("\n[bold]Available categories:[/bold]")
|
|
1233
|
+
for idx, cat in enumerate(categories, 1):
|
|
1234
|
+
print(f" {idx}. {cat}")
|
|
1235
|
+
|
|
1236
|
+
cat_choice = input("\nSelect category number: ").strip()
|
|
1237
|
+
try:
|
|
1238
|
+
category = categories[int(cat_choice) - 1]
|
|
1239
|
+
all_agents = self._merge_agent_sources()
|
|
1240
|
+
filtered_agents = [
|
|
1241
|
+
a
|
|
1242
|
+
for a in all_agents
|
|
1243
|
+
if a.get("category", "").startswith(category)
|
|
1244
|
+
]
|
|
1245
|
+
filter_description = f"Category: {category}"
|
|
1246
|
+
except (ValueError, IndexError):
|
|
1247
|
+
print("❌ Invalid selection")
|
|
1248
|
+
input("\nPress Enter to continue...")
|
|
1249
|
+
continue
|
|
1250
|
+
|
|
1251
|
+
elif choice == "2":
|
|
1252
|
+
# Language filtering (using AUTO-DEPLOY-INDEX if available)
|
|
1253
|
+
language = input(
|
|
1254
|
+
"\nEnter language (python, typescript, rust, go, etc.): "
|
|
1255
|
+
).strip()
|
|
1256
|
+
|
|
1257
|
+
try:
|
|
1258
|
+
# Find AUTO-DEPLOY-INDEX.md in agent repository
|
|
1259
|
+
from claude_mpm.services.agents.auto_deploy_index_parser import (
|
|
1260
|
+
AutoDeployIndexParser,
|
|
1261
|
+
)
|
|
1262
|
+
|
|
1263
|
+
index_path = (
|
|
1264
|
+
Path.home()
|
|
1265
|
+
/ ".claude-mpm"
|
|
1266
|
+
/ "cache"
|
|
1267
|
+
/ "remote-agents"
|
|
1268
|
+
/ "bobmatnyc"
|
|
1269
|
+
/ "claude-mpm-agents"
|
|
1270
|
+
/ "AUTO-DEPLOY-INDEX.md"
|
|
1271
|
+
)
|
|
1272
|
+
if not index_path.exists():
|
|
1273
|
+
print(
|
|
1274
|
+
f"[yellow]Could not find AUTO-DEPLOY-INDEX.md at: {index_path}[/yellow]"
|
|
1275
|
+
)
|
|
1276
|
+
input("\nPress Enter to continue...")
|
|
1277
|
+
continue
|
|
1278
|
+
|
|
1279
|
+
parser = AutoDeployIndexParser(index_path)
|
|
1280
|
+
lang_agents = parser.get_agents_by_language(language.lower())
|
|
1281
|
+
|
|
1282
|
+
# Get full agent details from discovery
|
|
1283
|
+
all_agents = self._merge_agent_sources()
|
|
1284
|
+
agent_ids = lang_agents.get("core", []) + lang_agents.get(
|
|
1285
|
+
"optional", []
|
|
1286
|
+
)
|
|
1287
|
+
filtered_agents = [
|
|
1288
|
+
a for a in all_agents if a["agent_id"] in agent_ids
|
|
1289
|
+
]
|
|
1290
|
+
filter_description = f"Language: {language}"
|
|
1291
|
+
except Exception as e:
|
|
1292
|
+
self.logger.error(f"Language filter error: {e}", exc_info=True)
|
|
1293
|
+
print(f"[yellow]Could not filter by language: {e}[/yellow]")
|
|
1294
|
+
input("\nPress Enter to continue...")
|
|
1295
|
+
continue
|
|
1296
|
+
|
|
1297
|
+
elif choice == "3":
|
|
1298
|
+
# Framework filtering
|
|
1299
|
+
framework = input(
|
|
1300
|
+
"\nEnter framework (react, nextjs, flask, django, etc.): "
|
|
1301
|
+
).strip()
|
|
1302
|
+
|
|
1303
|
+
try:
|
|
1304
|
+
from claude_mpm.services.agents.auto_deploy_index_parser import (
|
|
1305
|
+
AutoDeployIndexParser,
|
|
1306
|
+
)
|
|
1307
|
+
|
|
1308
|
+
index_path = (
|
|
1309
|
+
Path.home()
|
|
1310
|
+
/ ".claude-mpm"
|
|
1311
|
+
/ "cache"
|
|
1312
|
+
/ "remote-agents"
|
|
1313
|
+
/ "bobmatnyc"
|
|
1314
|
+
/ "claude-mpm-agents"
|
|
1315
|
+
/ "AUTO-DEPLOY-INDEX.md"
|
|
1316
|
+
)
|
|
1317
|
+
if not index_path.exists():
|
|
1318
|
+
print(
|
|
1319
|
+
f"[yellow]Could not find AUTO-DEPLOY-INDEX.md at: {index_path}[/yellow]"
|
|
1320
|
+
)
|
|
1321
|
+
input("\nPress Enter to continue...")
|
|
1322
|
+
continue
|
|
1323
|
+
|
|
1324
|
+
parser = AutoDeployIndexParser(index_path)
|
|
1325
|
+
framework_agent_ids = parser.get_agents_by_framework(
|
|
1326
|
+
framework.lower()
|
|
1327
|
+
)
|
|
1328
|
+
|
|
1329
|
+
all_agents = self._merge_agent_sources()
|
|
1330
|
+
filtered_agents = [
|
|
1331
|
+
a for a in all_agents if a["agent_id"] in framework_agent_ids
|
|
1332
|
+
]
|
|
1333
|
+
filter_description = f"Framework: {framework}"
|
|
1334
|
+
except Exception as e:
|
|
1335
|
+
self.logger.error(f"Framework filter error: {e}", exc_info=True)
|
|
1336
|
+
print(f"[yellow]Could not filter by framework: {e}[/yellow]")
|
|
1337
|
+
input("\nPress Enter to continue...")
|
|
1338
|
+
continue
|
|
1339
|
+
|
|
1340
|
+
elif choice == "4":
|
|
1341
|
+
# Show all agents
|
|
1342
|
+
filtered_agents = self._merge_agent_sources()
|
|
1343
|
+
filter_description = "All agents"
|
|
1344
|
+
else:
|
|
1345
|
+
print("❌ Invalid choice")
|
|
1346
|
+
input("\nPress Enter to continue...")
|
|
1347
|
+
continue
|
|
1348
|
+
|
|
1349
|
+
# Display filtered results
|
|
1350
|
+
print("\n" + "=" * 60)
|
|
1351
|
+
print(f"📋 {filter_description} ({len(filtered_agents)} agents)")
|
|
1352
|
+
print("=" * 60)
|
|
1353
|
+
|
|
1354
|
+
if not filtered_agents:
|
|
1355
|
+
print("\n[yellow]No agents found matching filter[/yellow]")
|
|
1356
|
+
else:
|
|
1357
|
+
print(f"\n{'#':<4} {'Agent ID':<40} {'Name':<25} {'Status':<12}")
|
|
1358
|
+
print("-" * 85)
|
|
1359
|
+
|
|
1360
|
+
for idx, agent in enumerate(filtered_agents, 1):
|
|
1361
|
+
agent_id = (
|
|
1362
|
+
agent["agent_id"][:39]
|
|
1363
|
+
if len(agent["agent_id"]) > 39
|
|
1364
|
+
else agent["agent_id"]
|
|
1365
|
+
)
|
|
1366
|
+
name = (
|
|
1367
|
+
agent["name"][:24] if len(agent["name"]) > 24 else agent["name"]
|
|
1368
|
+
)
|
|
1369
|
+
status = "✓ Deployed" if agent.get("deployed") else "Available"
|
|
1370
|
+
print(f"{idx:<4} {agent_id:<40} {name:<25} {status:<12}")
|
|
1371
|
+
|
|
1372
|
+
print("\n[bold]Actions:[/bold]")
|
|
1373
|
+
print(" [d] Deploy agent from this list")
|
|
1374
|
+
print(" [v] View agent details")
|
|
1375
|
+
print(" [n] New filter")
|
|
1376
|
+
print(" [b] Back to main menu")
|
|
1377
|
+
|
|
1378
|
+
action = input("\nSelect action: ").strip()
|
|
1379
|
+
|
|
1380
|
+
if action == "b":
|
|
1381
|
+
break
|
|
1382
|
+
if action == "n":
|
|
1383
|
+
continue
|
|
1384
|
+
if action == "d":
|
|
1385
|
+
self._deploy_from_filtered_list(filtered_agents)
|
|
1386
|
+
elif action == "v":
|
|
1387
|
+
self._view_from_filtered_list(filtered_agents)
|
|
1388
|
+
else:
|
|
1389
|
+
print("❌ Invalid choice")
|
|
1390
|
+
input("\nPress Enter to continue...")
|
|
1391
|
+
|
|
1392
|
+
def _deploy_from_filtered_list(self, agents: List[Dict[str, Any]]):
|
|
1393
|
+
"""Deploy an agent from a filtered list.
|
|
1394
|
+
|
|
1395
|
+
Args:
|
|
1396
|
+
agents: List of agent dictionaries with metadata
|
|
1397
|
+
"""
|
|
1398
|
+
if not agents:
|
|
1399
|
+
print("\n[yellow]No agents in list[/yellow]")
|
|
1400
|
+
input("\nPress Enter to continue...")
|
|
1401
|
+
return
|
|
1402
|
+
|
|
1403
|
+
deployable = [a for a in agents if not a.get("deployed")]
|
|
1404
|
+
|
|
1405
|
+
if not deployable:
|
|
1406
|
+
print("\n[yellow]All agents in this list are already deployed[/yellow]")
|
|
1407
|
+
input("\nPress Enter to continue...")
|
|
1408
|
+
return
|
|
1409
|
+
|
|
1410
|
+
agent_num = input(
|
|
1411
|
+
f"\nEnter agent number to deploy (1-{len(agents)}) or 'c' to cancel: "
|
|
1412
|
+
).strip()
|
|
1413
|
+
if agent_num.lower() == "c":
|
|
1414
|
+
return
|
|
1415
|
+
|
|
1416
|
+
try:
|
|
1417
|
+
idx = int(agent_num) - 1
|
|
1418
|
+
if idx < 0 or idx >= len(agents):
|
|
1419
|
+
print("❌ Invalid agent number")
|
|
1420
|
+
input("\nPress Enter to continue...")
|
|
1421
|
+
return
|
|
1422
|
+
|
|
1423
|
+
agent = agents[idx]
|
|
1424
|
+
|
|
1425
|
+
if agent.get("deployed"):
|
|
1426
|
+
print(f"\n[yellow]{agent['agent_id']} is already deployed[/yellow]")
|
|
1427
|
+
else:
|
|
1428
|
+
print(f"\n🚀 Deploying {agent['agent_id']}...")
|
|
1429
|
+
|
|
1430
|
+
from claude_mpm.services.agents.deployment.agent_template_builder import (
|
|
1431
|
+
AgentTemplateBuilder,
|
|
1432
|
+
)
|
|
1433
|
+
from claude_mpm.services.agents.deployment.agent_version_manager import (
|
|
1434
|
+
AgentVersionManager,
|
|
1435
|
+
)
|
|
1436
|
+
from claude_mpm.services.agents.deployment.deployment_results_manager import (
|
|
1437
|
+
DeploymentResultsManager,
|
|
1438
|
+
)
|
|
1439
|
+
from claude_mpm.services.agents.deployment.single_agent_deployer import (
|
|
1440
|
+
SingleAgentDeployer,
|
|
1441
|
+
)
|
|
1442
|
+
|
|
1443
|
+
# Initialize deployment services
|
|
1444
|
+
template_builder = AgentTemplateBuilder()
|
|
1445
|
+
version_manager = AgentVersionManager()
|
|
1446
|
+
results_manager = DeploymentResultsManager(self.logger)
|
|
1447
|
+
deployer = SingleAgentDeployer(
|
|
1448
|
+
template_builder=template_builder,
|
|
1449
|
+
version_manager=version_manager,
|
|
1450
|
+
results_manager=results_manager,
|
|
1451
|
+
logger=self.logger,
|
|
1452
|
+
)
|
|
1453
|
+
|
|
1454
|
+
# Prepare deployment parameters
|
|
1455
|
+
template_path = Path(agent["path"])
|
|
1456
|
+
target_dir = Path.cwd() / ".claude" / "agents"
|
|
1457
|
+
|
|
1458
|
+
# Find base_agent.json in multiple possible locations
|
|
1459
|
+
base_agent_candidates = [
|
|
1460
|
+
Path.home()
|
|
1461
|
+
/ ".claude-mpm"
|
|
1462
|
+
/ "agents"
|
|
1463
|
+
/ "templates"
|
|
1464
|
+
/ "base_agent.json",
|
|
1465
|
+
Path.home() / ".claude-mpm" / "cache" / "base_agent.json",
|
|
1466
|
+
Path(__file__).parent.parent.parent
|
|
1467
|
+
/ "agents"
|
|
1468
|
+
/ "templates"
|
|
1469
|
+
/ "base_agent.json",
|
|
1470
|
+
]
|
|
1471
|
+
base_agent_path = None
|
|
1472
|
+
for candidate in base_agent_candidates:
|
|
1473
|
+
if candidate.exists():
|
|
1474
|
+
base_agent_path = candidate
|
|
1475
|
+
break
|
|
1476
|
+
|
|
1477
|
+
if not base_agent_path:
|
|
1478
|
+
base_agent_path = base_agent_candidates[
|
|
1479
|
+
0
|
|
1480
|
+
] # Use default even if not exists
|
|
1481
|
+
|
|
1482
|
+
# Deploy the agent
|
|
1483
|
+
success = deployer.deploy_agent(
|
|
1484
|
+
agent_name=agent["agent_id"],
|
|
1485
|
+
templates_dir=template_path.parent,
|
|
1486
|
+
target_dir=target_dir,
|
|
1487
|
+
base_agent_path=base_agent_path,
|
|
1488
|
+
force_rebuild=True,
|
|
1489
|
+
working_directory=Path.cwd(),
|
|
1490
|
+
)
|
|
1491
|
+
|
|
1492
|
+
if success:
|
|
1493
|
+
print(f"[green]✓ Successfully deployed {agent['agent_id']}[/green]")
|
|
1494
|
+
else:
|
|
1495
|
+
print(f"[red]✗ Failed to deploy {agent['agent_id']}[/red]")
|
|
1496
|
+
|
|
1497
|
+
input("\nPress Enter to continue...")
|
|
1498
|
+
except ValueError:
|
|
1499
|
+
print("❌ Invalid agent number")
|
|
1500
|
+
input("\nPress Enter to continue...")
|
|
1501
|
+
except Exception as e:
|
|
1502
|
+
self.logger.error(f"Deployment error: {e}", exc_info=True)
|
|
1503
|
+
print(f"❌ Deployment error: {e}")
|
|
1504
|
+
input("\nPress Enter to continue...")
|
|
1505
|
+
|
|
1506
|
+
def _view_from_filtered_list(self, agents: List[Dict[str, Any]]):
|
|
1507
|
+
"""View details of an agent from filtered list.
|
|
1508
|
+
|
|
1509
|
+
Args:
|
|
1510
|
+
agents: List of agent dictionaries with metadata
|
|
1511
|
+
"""
|
|
1512
|
+
if not agents:
|
|
1513
|
+
print("\n[yellow]No agents in list[/yellow]")
|
|
1514
|
+
input("\nPress Enter to continue...")
|
|
1515
|
+
return
|
|
1516
|
+
|
|
1517
|
+
agent_num = input(
|
|
1518
|
+
f"\nEnter agent number to view (1-{len(agents)}) or 'c' to cancel: "
|
|
1519
|
+
).strip()
|
|
1520
|
+
if agent_num.lower() == "c":
|
|
1521
|
+
return
|
|
1522
|
+
|
|
1523
|
+
try:
|
|
1524
|
+
idx = int(agent_num) - 1
|
|
1525
|
+
if idx < 0 or idx >= len(agents):
|
|
1526
|
+
print("❌ Invalid agent number")
|
|
1527
|
+
input("\nPress Enter to continue...")
|
|
1528
|
+
return
|
|
1529
|
+
|
|
1530
|
+
agent = agents[idx]
|
|
1531
|
+
self._show_agent_details(agent)
|
|
1532
|
+
except ValueError:
|
|
1533
|
+
print("❌ Invalid agent number")
|
|
1534
|
+
input("\nPress Enter to continue...")
|
|
1535
|
+
|
|
1536
|
+
def _deploy_preset_interactive(self):
|
|
1537
|
+
"""Interactive preset deployment with preview and confirmation."""
|
|
1538
|
+
from claude_mpm.services.agents.agent_preset_service import AgentPresetService
|
|
1539
|
+
|
|
1540
|
+
if not self.source_manager:
|
|
1541
|
+
print("\n❌ Source manager not available")
|
|
1542
|
+
input("\nPress Enter to continue...")
|
|
1543
|
+
return
|
|
1544
|
+
|
|
1545
|
+
preset_service = AgentPresetService(self.source_manager)
|
|
1546
|
+
|
|
1547
|
+
while True:
|
|
1548
|
+
print("\n" + "=" * 60)
|
|
1549
|
+
print("📦 Deploy Agent Preset")
|
|
1550
|
+
print("=" * 60)
|
|
1551
|
+
|
|
1552
|
+
# List available presets
|
|
1553
|
+
presets = preset_service.list_presets()
|
|
1554
|
+
|
|
1555
|
+
print(f"\n{len(presets)} preset(s) available:\n")
|
|
1556
|
+
print(f"{'#':<4} {'Preset':<20} {'Agents':<10} {'Description':<50}")
|
|
1557
|
+
print("-" * 90)
|
|
1558
|
+
|
|
1559
|
+
for idx, preset in enumerate(presets, 1):
|
|
1560
|
+
description = (
|
|
1561
|
+
preset["description"][:48] + "..."
|
|
1562
|
+
if len(preset["description"]) > 50
|
|
1563
|
+
else preset["description"]
|
|
1564
|
+
)
|
|
1565
|
+
print(
|
|
1566
|
+
f"{idx:<4} {preset['name']:<20} {len(preset.get('agents', [])):<10} {description:<50}"
|
|
1567
|
+
)
|
|
1568
|
+
|
|
1569
|
+
print("\n[bold]Actions:[/bold]")
|
|
1570
|
+
print(" [1-11] Select preset number")
|
|
1571
|
+
print(" [b] Back to main menu")
|
|
1572
|
+
|
|
1573
|
+
choice = input("\nSelect preset number or action: ").strip()
|
|
1574
|
+
|
|
1575
|
+
if choice.lower() == "b":
|
|
1576
|
+
break
|
|
1577
|
+
|
|
1578
|
+
try:
|
|
1579
|
+
idx = int(choice) - 1
|
|
1580
|
+
if idx < 0 or idx >= len(presets):
|
|
1581
|
+
raise ValueError("Out of range")
|
|
1582
|
+
|
|
1583
|
+
preset_name = presets[idx]["name"]
|
|
1584
|
+
|
|
1585
|
+
# Show preset details
|
|
1586
|
+
print("\n" + "=" * 60)
|
|
1587
|
+
print(f"📦 Preset: {preset_name}")
|
|
1588
|
+
print("=" * 60)
|
|
1589
|
+
print(f"\n[bold]Description:[/bold] {presets[idx]['description']}\n")
|
|
1590
|
+
|
|
1591
|
+
# Resolve preset
|
|
1592
|
+
print("🔍 Resolving preset agents...")
|
|
1593
|
+
resolution = preset_service.resolve_agents(
|
|
1594
|
+
preset_name, validate_availability=True
|
|
1595
|
+
)
|
|
1596
|
+
|
|
1597
|
+
if resolution.get("missing_agents"):
|
|
1598
|
+
print(
|
|
1599
|
+
f"\n⚠️ [red]Missing agents ({len(resolution['missing_agents'])}):[/red]"
|
|
1600
|
+
)
|
|
1601
|
+
for agent_id in resolution["missing_agents"]:
|
|
1602
|
+
print(f" • {agent_id}")
|
|
1603
|
+
print("\n[yellow]Cannot deploy preset with missing agents[/yellow]")
|
|
1604
|
+
input("\nPress Enter to continue...")
|
|
1605
|
+
continue
|
|
1606
|
+
|
|
1607
|
+
# Show agents to deploy
|
|
1608
|
+
agents = resolution.get("agents", [])
|
|
1609
|
+
print(f"\n[bold]Agents to deploy ({len(agents)}):[/bold]\n")
|
|
1610
|
+
|
|
1611
|
+
print(f"{'Agent ID':<40} {'Name':<25} {'Source':<25}")
|
|
1612
|
+
print("-" * 95)
|
|
1613
|
+
|
|
1614
|
+
for agent in agents:
|
|
1615
|
+
# Get agent metadata
|
|
1616
|
+
agent_metadata = agent.get("metadata", {})
|
|
1617
|
+
agent_meta_data = agent_metadata.get("metadata", {})
|
|
1618
|
+
|
|
1619
|
+
agent_id = (
|
|
1620
|
+
agent.get("agent_id", "")[:39]
|
|
1621
|
+
if len(agent.get("agent_id", "")) > 39
|
|
1622
|
+
else agent.get("agent_id", "")
|
|
1623
|
+
)
|
|
1624
|
+
name = (
|
|
1625
|
+
agent_meta_data.get("name", "")[:24]
|
|
1626
|
+
if len(agent_meta_data.get("name", "")) > 24
|
|
1627
|
+
else agent_meta_data.get("name", "")
|
|
1628
|
+
)
|
|
1629
|
+
source = (
|
|
1630
|
+
agent.get("source", "unknown")[:24]
|
|
1631
|
+
if len(agent.get("source", "unknown")) > 24
|
|
1632
|
+
else agent.get("source", "unknown")
|
|
1633
|
+
)
|
|
1634
|
+
|
|
1635
|
+
print(f"{agent_id:<40} {name:<25} {source:<25}")
|
|
1636
|
+
|
|
1637
|
+
# Confirm deployment
|
|
1638
|
+
print("\n[bold]Options:[/bold]")
|
|
1639
|
+
print(" [y] Deploy all agents")
|
|
1640
|
+
print(" [n] Cancel")
|
|
1641
|
+
|
|
1642
|
+
confirm = input("\nProceed with deployment? ").strip()
|
|
1643
|
+
|
|
1644
|
+
if confirm.lower() == "y":
|
|
1645
|
+
print(f"\n🚀 Deploying preset '{preset_name}'...\n")
|
|
1646
|
+
|
|
1647
|
+
from claude_mpm.services.agents.deployment.agent_template_builder import (
|
|
1648
|
+
AgentTemplateBuilder,
|
|
1649
|
+
)
|
|
1650
|
+
from claude_mpm.services.agents.deployment.agent_version_manager import (
|
|
1651
|
+
AgentVersionManager,
|
|
1652
|
+
)
|
|
1653
|
+
from claude_mpm.services.agents.deployment.deployment_results_manager import (
|
|
1654
|
+
DeploymentResultsManager,
|
|
1655
|
+
)
|
|
1656
|
+
from claude_mpm.services.agents.deployment.single_agent_deployer import (
|
|
1657
|
+
SingleAgentDeployer,
|
|
1658
|
+
)
|
|
1659
|
+
|
|
1660
|
+
# Initialize deployment services once for all agents
|
|
1661
|
+
template_builder = AgentTemplateBuilder()
|
|
1662
|
+
version_manager = AgentVersionManager()
|
|
1663
|
+
results_manager = DeploymentResultsManager(self.logger)
|
|
1664
|
+
deployer = SingleAgentDeployer(
|
|
1665
|
+
template_builder=template_builder,
|
|
1666
|
+
version_manager=version_manager,
|
|
1667
|
+
results_manager=results_manager,
|
|
1668
|
+
logger=self.logger,
|
|
1669
|
+
)
|
|
1670
|
+
|
|
1671
|
+
target_dir = Path.cwd() / ".claude" / "agents"
|
|
1672
|
+
|
|
1673
|
+
# Find base_agent.json
|
|
1674
|
+
base_agent_candidates = [
|
|
1675
|
+
Path.home()
|
|
1676
|
+
/ ".claude-mpm"
|
|
1677
|
+
/ "agents"
|
|
1678
|
+
/ "templates"
|
|
1679
|
+
/ "base_agent.json",
|
|
1680
|
+
Path.home() / ".claude-mpm" / "cache" / "base_agent.json",
|
|
1681
|
+
Path(__file__).parent.parent.parent
|
|
1682
|
+
/ "agents"
|
|
1683
|
+
/ "templates"
|
|
1684
|
+
/ "base_agent.json",
|
|
1685
|
+
]
|
|
1686
|
+
base_agent_path = None
|
|
1687
|
+
for candidate in base_agent_candidates:
|
|
1688
|
+
if candidate.exists():
|
|
1689
|
+
base_agent_path = candidate
|
|
1690
|
+
break
|
|
1691
|
+
|
|
1692
|
+
if not base_agent_path:
|
|
1693
|
+
base_agent_path = base_agent_candidates[0]
|
|
1694
|
+
|
|
1695
|
+
deployed = 0
|
|
1696
|
+
failed = 0
|
|
1697
|
+
|
|
1698
|
+
for agent in agents:
|
|
1699
|
+
agent_id = agent["agent_id"]
|
|
1700
|
+
agent_metadata = agent.get("metadata", {})
|
|
1701
|
+
agent_path = agent_metadata.get(
|
|
1702
|
+
"path", agent_metadata.get("source_file", "")
|
|
1703
|
+
)
|
|
1704
|
+
|
|
1705
|
+
if not agent_path:
|
|
1706
|
+
print(f" Deploying {agent_id}... [red]✗ (no path)[/red]")
|
|
1707
|
+
failed += 1
|
|
1708
|
+
continue
|
|
1709
|
+
|
|
1710
|
+
print(f" Deploying {agent_id}...", end=" ", flush=True)
|
|
1711
|
+
|
|
1712
|
+
try:
|
|
1713
|
+
template_path = Path(agent_path)
|
|
1714
|
+
success = deployer.deploy_agent(
|
|
1715
|
+
agent_name=agent_id,
|
|
1716
|
+
templates_dir=template_path.parent,
|
|
1717
|
+
target_dir=target_dir,
|
|
1718
|
+
base_agent_path=base_agent_path,
|
|
1719
|
+
force_rebuild=True,
|
|
1720
|
+
working_directory=Path.cwd(),
|
|
1721
|
+
)
|
|
1722
|
+
|
|
1723
|
+
if success:
|
|
1724
|
+
print("[green]✓[/green]")
|
|
1725
|
+
deployed += 1
|
|
1726
|
+
else:
|
|
1727
|
+
print("[red]✗[/red]")
|
|
1728
|
+
failed += 1
|
|
1729
|
+
except Exception as e:
|
|
1730
|
+
print(f"[red]✗ ({e})[/red]")
|
|
1731
|
+
self.logger.error(
|
|
1732
|
+
f"Failed to deploy {agent_id}: {e}", exc_info=True
|
|
1733
|
+
)
|
|
1734
|
+
failed += 1
|
|
1735
|
+
|
|
1736
|
+
print("\n[bold]Summary:[/bold]")
|
|
1737
|
+
print(f" • Deployed: {deployed}")
|
|
1738
|
+
print(f" • Failed: {failed}")
|
|
1739
|
+
print(f" • Total: {len(agents)}")
|
|
1740
|
+
|
|
1741
|
+
if failed == 0:
|
|
1742
|
+
print(
|
|
1743
|
+
f"\n[green]✓ Preset '{preset_name}' deployed successfully![/green]"
|
|
1744
|
+
)
|
|
1745
|
+
else:
|
|
1746
|
+
print(
|
|
1747
|
+
f"\n[yellow]⚠ Preset deployed with {failed} failures[/yellow]"
|
|
1748
|
+
)
|
|
1749
|
+
|
|
1750
|
+
input("\nPress Enter to continue...")
|
|
1751
|
+
break
|
|
1752
|
+
|
|
1753
|
+
except (ValueError, IndexError):
|
|
1754
|
+
print("❌ Invalid preset selection")
|
|
1755
|
+
input("\nPress Enter to continue...")
|
|
1756
|
+
except Exception as e:
|
|
1757
|
+
self.logger.error(f"Preset deployment error: {e}", exc_info=True)
|
|
1758
|
+
print(f"❌ Error: {e}")
|
|
1759
|
+
input("\nPress Enter to continue...")
|
|
1760
|
+
|
|
1761
|
+
def _manage_sources_interactive(self):
|
|
1762
|
+
"""Interactive source management."""
|
|
1763
|
+
if not self.discovery_enabled or not self.source_manager:
|
|
1764
|
+
print("\n❌ Source manager not available")
|
|
1765
|
+
input("\nPress Enter to continue...")
|
|
1766
|
+
return
|
|
1767
|
+
|
|
1768
|
+
print("\n" + "=" * 60)
|
|
1769
|
+
print("🔗 Manage Agent Sources")
|
|
1770
|
+
print("=" * 60)
|
|
1771
|
+
|
|
1772
|
+
try:
|
|
1773
|
+
from claude_mpm.config.agent_sources import AgentSourceConfiguration
|
|
1774
|
+
|
|
1775
|
+
config = AgentSourceConfiguration()
|
|
1776
|
+
sources = config.list_sources()
|
|
1777
|
+
|
|
1778
|
+
if not sources:
|
|
1779
|
+
print("\n📭 No sources configured.")
|
|
1780
|
+
else:
|
|
1781
|
+
print(f"\n{len(sources)} source(s) configured:\n")
|
|
1782
|
+
print(f"{'Source':<40} {'Priority':<10} {'Status':<10}")
|
|
1783
|
+
print("-" * 60)
|
|
1784
|
+
|
|
1785
|
+
for source in sources:
|
|
1786
|
+
identifier = source.get("identifier", "unknown")[:39]
|
|
1787
|
+
priority = str(source.get("priority", 100))
|
|
1788
|
+
status = "✓ Active" if source.get("enabled", True) else "Disabled"
|
|
1789
|
+
print(f"{identifier:<40} {priority:<10} {status:<10}")
|
|
1790
|
+
|
|
1791
|
+
print("\n💡 Use 'claude-mpm agent-source' command to add/remove sources")
|
|
1792
|
+
print("💡 Use 'claude-mpm agents discover' command to refresh agent cache")
|
|
1793
|
+
|
|
1794
|
+
except Exception as e:
|
|
1795
|
+
self.logger.error(f"Failed to list sources: {e}", exc_info=True)
|
|
1796
|
+
print(f"\n❌ Error: {e}")
|
|
1797
|
+
|
|
1798
|
+
input("\nPress Enter to continue...")
|
|
1799
|
+
|
|
922
1800
|
|
|
923
1801
|
def run_interactive_agent_wizard() -> int:
|
|
924
1802
|
"""Entry point for interactive agent wizard.
|