claude-mpm 4.24.0__py3-none-any.whl → 5.0.9__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/agents/BASE_PM.md +12 -0
- claude_mpm/agents/OUTPUT_STYLE.md +3 -48
- claude_mpm/agents/PM_INSTRUCTIONS.md +721 -911
- claude_mpm/agents/PM_INSTRUCTIONS_TEACH.md +1322 -0
- claude_mpm/agents/WORKFLOW.md +4 -4
- 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/base_agent_loader.py +10 -35
- 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} +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 +38 -2
- 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 +188 -30
- claude_mpm/cli/commands/agents.py +959 -36
- 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/config.py +7 -4
- claude_mpm/cli/commands/configure.py +769 -45
- 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 +49 -1
- 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/postmortem.py +401 -0
- claude_mpm/cli/commands/run.py +123 -165
- claude_mpm/cli/commands/skill_source.py +694 -0
- claude_mpm/cli/commands/skills.py +757 -20
- claude_mpm/cli/executor.py +78 -3
- claude_mpm/cli/interactive/agent_wizard.py +955 -45
- claude_mpm/cli/parsers/agent_source_parser.py +171 -0
- claude_mpm/cli/parsers/agents_parser.py +256 -4
- claude_mpm/cli/parsers/base_parser.py +53 -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 +145 -0
- claude_mpm/cli/parsers/source_parser.py +138 -0
- claude_mpm/cli/startup.py +538 -106
- 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 +14 -2
- claude_mpm/commands/mpm-init.md +27 -2
- claude_mpm/commands/mpm-monitor.md +9 -0
- claude_mpm/commands/mpm-postmortem.md +123 -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 +488 -0
- claude_mpm/config/agent_sources.py +325 -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 +16 -0
- claude_mpm/core/constants.py +1 -1
- claude_mpm/core/framework/__init__.py +3 -16
- claude_mpm/core/framework/loaders/file_loader.py +54 -101
- claude_mpm/core/framework/loaders/instruction_loader.py +25 -5
- 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 +3 -1
- claude_mpm/core/oneshot_session.py +71 -8
- 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/singleton_manager.py +11 -4
- claude_mpm/core/system_context.py +38 -0
- 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/__pycache__/__init__.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +3 -1
- claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-313.pyc +0 -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/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/cache_git_manager.py +621 -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 +1087 -0
- claude_mpm/services/agents/startup_sync.py +239 -0
- claude_mpm/services/agents/toolchain_detector.py +474 -0
- claude_mpm/services/analysis/__init__.py +25 -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 +200 -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 +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/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/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 +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/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_gateway/config/configuration.py +1 -1
- claude_mpm/services/mcp_gateway/core/process_pool.py +22 -16
- 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/kuzu_memory_service.py +6 -2
- claude_mpm/services/mcp_service_verifier.py +6 -3
- claude_mpm/services/model/model_router.py +1 -2
- claude_mpm/services/monitor/daemon.py +29 -9
- claude_mpm/services/monitor/daemon_manager.py +96 -19
- claude_mpm/services/monitor/server.py +2 -2
- 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 +16 -3
- claude_mpm/services/session_management_service.py +16 -4
- 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 +1 -1
- 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/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/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/utils/agent_dependency_loader.py +77 -10
- claude_mpm/utils/agent_filters.py +288 -0
- claude_mpm/utils/dependency_cache.py +3 -1
- claude_mpm/utils/gitignore.py +241 -0
- claude_mpm/utils/migration.py +372 -0
- claude_mpm/utils/progress.py +387 -0
- claude_mpm/utils/robust_installer.py +2 -4
- claude_mpm/utils/structured_questions.py +619 -0
- {claude_mpm-4.24.0.dist-info → claude_mpm-5.0.9.dist-info}/METADATA +396 -43
- {claude_mpm-4.24.0.dist-info → claude_mpm-5.0.9.dist-info}/RECORD +268 -422
- 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/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/commands/mpm-tickets.md +0 -151
- 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.24.0.dist-info → claude_mpm-5.0.9.dist-info}/WHEEL +0 -0
- {claude_mpm-4.24.0.dist-info → claude_mpm-5.0.9.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.24.0.dist-info → claude_mpm-5.0.9.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.24.0.dist-info → claude_mpm-5.0.9.dist-info}/top_level.txt +0 -0
|
@@ -8,25 +8,59 @@ 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
|
+
|
|
13
|
+
import questionary
|
|
14
|
+
from questionary import Style
|
|
12
15
|
|
|
13
16
|
from claude_mpm.core.logging_config import get_logger
|
|
14
17
|
from claude_mpm.services.agents.local_template_manager import (
|
|
15
18
|
LocalAgentTemplate,
|
|
16
19
|
LocalAgentTemplateManager,
|
|
17
20
|
)
|
|
21
|
+
from claude_mpm.utils.agent_filters import apply_all_filters
|
|
18
22
|
|
|
19
23
|
logger = get_logger(__name__)
|
|
20
24
|
|
|
25
|
+
# Questionary style matching Rich cyan theme (consistent with configure.py)
|
|
26
|
+
QUESTIONARY_STYLE = Style(
|
|
27
|
+
[
|
|
28
|
+
("selected", "fg:cyan bold"),
|
|
29
|
+
("pointer", "fg:cyan bold"),
|
|
30
|
+
("highlighted", "fg:cyan"),
|
|
31
|
+
("question", "fg:cyan bold"),
|
|
32
|
+
]
|
|
33
|
+
)
|
|
34
|
+
|
|
21
35
|
|
|
22
36
|
class AgentWizard:
|
|
23
|
-
"""
|
|
37
|
+
"""
|
|
38
|
+
Interactive wizard for agent creation and management.
|
|
39
|
+
|
|
40
|
+
DEPRECATED: This interface has been superseded by the unified
|
|
41
|
+
configuration interface. Please use 'claude-mpm config' instead.
|
|
42
|
+
|
|
43
|
+
This class is retained for backward compatibility but will be
|
|
44
|
+
removed in a future version.
|
|
45
|
+
"""
|
|
24
46
|
|
|
25
47
|
def __init__(self):
|
|
26
48
|
"""Initialize the agent wizard."""
|
|
27
49
|
self.manager = LocalAgentTemplateManager()
|
|
28
50
|
self.logger = logger
|
|
29
51
|
|
|
52
|
+
# Initialize remote discovery services
|
|
53
|
+
try:
|
|
54
|
+
from claude_mpm.services.agents.git_source_manager import GitSourceManager
|
|
55
|
+
|
|
56
|
+
self.source_manager = GitSourceManager()
|
|
57
|
+
self.discovery_enabled = True
|
|
58
|
+
self.logger.debug("Remote agent discovery enabled")
|
|
59
|
+
except Exception as e:
|
|
60
|
+
self.logger.warning(f"Failed to initialize remote discovery: {e}")
|
|
61
|
+
self.source_manager = None
|
|
62
|
+
self.discovery_enabled = False
|
|
63
|
+
|
|
30
64
|
def run_interactive_create(self) -> Tuple[bool, str]:
|
|
31
65
|
"""Run interactive agent creation wizard.
|
|
32
66
|
|
|
@@ -117,6 +151,80 @@ class AgentWizard:
|
|
|
117
151
|
self.logger.error(error_msg, exc_info=True)
|
|
118
152
|
return False, error_msg
|
|
119
153
|
|
|
154
|
+
def _merge_agent_sources(self) -> List[Dict[str, Any]]:
|
|
155
|
+
"""
|
|
156
|
+
Merge agents from all sources with precedence: local > discovered.
|
|
157
|
+
|
|
158
|
+
Returns list of agents with metadata:
|
|
159
|
+
{
|
|
160
|
+
"agent_id": "engineer/backend/python-engineer",
|
|
161
|
+
"name": "Python Engineer",
|
|
162
|
+
"description": "...",
|
|
163
|
+
"source_type": "system" | "project",
|
|
164
|
+
"source_identifier": "bobmatnyc/claude-mpm-agents",
|
|
165
|
+
"category": "engineer/backend",
|
|
166
|
+
"deployed": True | False,
|
|
167
|
+
"path": "/path/to/agent.md"
|
|
168
|
+
}
|
|
169
|
+
"""
|
|
170
|
+
agents = {}
|
|
171
|
+
|
|
172
|
+
# Get discovered agents (system/user sources)
|
|
173
|
+
if self.discovery_enabled and self.source_manager:
|
|
174
|
+
try:
|
|
175
|
+
discovered = self.source_manager.list_cached_agents()
|
|
176
|
+
self.logger.debug(f"Discovered {len(discovered)} remote agents")
|
|
177
|
+
|
|
178
|
+
for agent in discovered:
|
|
179
|
+
agent_id = agent.get("agent_id", "")
|
|
180
|
+
if not agent_id:
|
|
181
|
+
continue
|
|
182
|
+
|
|
183
|
+
# Extract metadata
|
|
184
|
+
metadata = agent.get("metadata", {})
|
|
185
|
+
agents[agent_id] = {
|
|
186
|
+
"agent_id": agent_id,
|
|
187
|
+
"name": metadata.get("name", agent_id),
|
|
188
|
+
"description": metadata.get("description", ""),
|
|
189
|
+
"source_type": "system",
|
|
190
|
+
"source_identifier": agent.get("source", "unknown"),
|
|
191
|
+
"category": agent.get("category", ""),
|
|
192
|
+
"deployed": False, # Will be updated below
|
|
193
|
+
"path": agent.get("path", agent.get("source_file", "")),
|
|
194
|
+
}
|
|
195
|
+
except Exception as e:
|
|
196
|
+
self.logger.warning(f"Failed to discover remote agents: {e}")
|
|
197
|
+
|
|
198
|
+
# Get local agents (project-level, highest precedence)
|
|
199
|
+
local_templates = self.manager.list_local_templates()
|
|
200
|
+
for template in local_templates:
|
|
201
|
+
agent_id = template.agent_id
|
|
202
|
+
agents[agent_id] = {
|
|
203
|
+
"agent_id": agent_id,
|
|
204
|
+
"name": template.metadata.get("name", agent_id),
|
|
205
|
+
"description": template.metadata.get("description", ""),
|
|
206
|
+
"source_type": "project",
|
|
207
|
+
"source_identifier": "local",
|
|
208
|
+
"category": template.metadata.get("category", ""),
|
|
209
|
+
"deployed": True, # Local templates are deployed
|
|
210
|
+
"path": str(self._get_template_path(template)),
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
# Check deployment status for discovered agents
|
|
214
|
+
deployed_dir = Path.cwd() / ".claude" / "agents"
|
|
215
|
+
if deployed_dir.exists():
|
|
216
|
+
for agent_id, agent_data in agents.items():
|
|
217
|
+
deployed_file = deployed_dir / f"{agent_id.replace('/', '-')}.md"
|
|
218
|
+
# Also check hierarchical path
|
|
219
|
+
deployed_file_alt = deployed_dir / f"{agent_id.split('/')[-1]}.md"
|
|
220
|
+
if deployed_file.exists() or deployed_file_alt.exists():
|
|
221
|
+
agent_data["deployed"] = True
|
|
222
|
+
|
|
223
|
+
# Filter BASE_AGENT from all agent lists (1M-502 Phase 1)
|
|
224
|
+
# BASE_AGENT is a build tool, not a deployable agent
|
|
225
|
+
agent_list = list(agents.values())
|
|
226
|
+
return apply_all_filters(agent_list, filter_base=True, filter_deployed=False)
|
|
227
|
+
|
|
120
228
|
def run_interactive_manage(self) -> Tuple[bool, str]:
|
|
121
229
|
"""Run interactive agent management menu.
|
|
122
230
|
|
|
@@ -125,15 +233,17 @@ class AgentWizard:
|
|
|
125
233
|
"""
|
|
126
234
|
try:
|
|
127
235
|
while True:
|
|
128
|
-
#
|
|
129
|
-
|
|
236
|
+
# Get merged agents from all sources
|
|
237
|
+
all_agents = self._merge_agent_sources()
|
|
130
238
|
|
|
131
239
|
print("\n" + "=" * 60)
|
|
132
240
|
print("🔧 Agent Management Menu")
|
|
133
241
|
print("=" * 60)
|
|
134
242
|
|
|
135
|
-
if not
|
|
136
|
-
print(
|
|
243
|
+
if not all_agents:
|
|
244
|
+
print(
|
|
245
|
+
"\n📭 No agents found. Configure sources with 'claude-mpm agents discover'"
|
|
246
|
+
)
|
|
137
247
|
print("\n1. Create new agent")
|
|
138
248
|
print("2. Import agents")
|
|
139
249
|
print("3. Exit")
|
|
@@ -148,60 +258,104 @@ class AgentWizard:
|
|
|
148
258
|
return True, "Management menu exited"
|
|
149
259
|
print("❌ Invalid choice. Please try again.")
|
|
150
260
|
continue
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
261
|
+
|
|
262
|
+
# Show existing agents in a table
|
|
263
|
+
print(f"\n📋 Found {len(all_agents)} agent(s):\n")
|
|
264
|
+
print(
|
|
265
|
+
f"{'#':<4} {'Agent ID':<40} {'Name':<25} {'Source':<20} {'Status':<10}"
|
|
266
|
+
)
|
|
267
|
+
print("-" * 105)
|
|
268
|
+
|
|
269
|
+
for i, agent in enumerate(all_agents, 1):
|
|
270
|
+
agent_id = agent["agent_id"]
|
|
271
|
+
name = (
|
|
272
|
+
agent["name"][:24] if len(agent["name"]) > 24 else agent["name"]
|
|
273
|
+
)
|
|
274
|
+
source_label = (
|
|
275
|
+
f"[{agent['source_type']}] {agent['source_identifier']}"[:19]
|
|
276
|
+
)
|
|
277
|
+
status = "✓ Deployed" if agent["deployed"] else "Available"
|
|
278
|
+
|
|
155
279
|
print(
|
|
156
|
-
f"
|
|
280
|
+
f"{i:<4} {agent_id:<40} {name:<25} {source_label:<20} {status:<10}"
|
|
157
281
|
)
|
|
158
282
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
print(f"{len(templates) + 3}. Import agents")
|
|
162
|
-
print(f"{len(templates) + 4}. Export all agents")
|
|
163
|
-
print(f"{len(templates) + 5}. Exit")
|
|
283
|
+
# Build menu choices with arrow-key navigation
|
|
284
|
+
menu_choices = []
|
|
164
285
|
|
|
165
|
-
|
|
166
|
-
|
|
286
|
+
# Add agent viewing options (1-N)
|
|
287
|
+
for i, agent in enumerate(all_agents, 1):
|
|
288
|
+
menu_choices.append(f"{i}. View agent: {agent['agent_id']}")
|
|
167
289
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
290
|
+
# Add action options
|
|
291
|
+
menu_choices.append(f"{len(all_agents) + 1}. Deploy agent")
|
|
292
|
+
menu_choices.append(f"{len(all_agents) + 2}. Create new agent")
|
|
293
|
+
menu_choices.append(f"{len(all_agents) + 3}. Delete agent(s)")
|
|
294
|
+
menu_choices.append(f"{len(all_agents) + 4}. Import agents")
|
|
295
|
+
menu_choices.append(f"{len(all_agents) + 5}. Export all agents")
|
|
296
|
+
|
|
297
|
+
if self.discovery_enabled:
|
|
298
|
+
menu_choices.append(
|
|
299
|
+
f"{len(all_agents) + 6}. Browse & filter agents"
|
|
300
|
+
)
|
|
301
|
+
menu_choices.append(f"{len(all_agents) + 7}. Deploy preset")
|
|
302
|
+
menu_choices.append(f"{len(all_agents) + 8}. Manage agent sources")
|
|
303
|
+
menu_choices.append(f"{len(all_agents) + 9}. Exit")
|
|
304
|
+
exit_num = len(all_agents) + 9
|
|
305
|
+
else:
|
|
306
|
+
menu_choices.append(f"{len(all_agents) + 6}. Exit")
|
|
307
|
+
exit_num = len(all_agents) + 6
|
|
308
|
+
|
|
309
|
+
choice = questionary.select(
|
|
310
|
+
"Agent Management Menu:",
|
|
311
|
+
choices=menu_choices,
|
|
312
|
+
style=QUESTIONARY_STYLE,
|
|
313
|
+
).ask()
|
|
314
|
+
|
|
315
|
+
if not choice: # User pressed Esc
|
|
316
|
+
return True, "Management menu exited"
|
|
173
317
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
318
|
+
# Parse choice number from "N. Description" format
|
|
319
|
+
choice_num = int(choice.split(".")[0])
|
|
320
|
+
|
|
321
|
+
if 1 <= choice_num <= len(all_agents):
|
|
322
|
+
# View agent details
|
|
323
|
+
selected_agent = all_agents[choice_num - 1]
|
|
324
|
+
self._show_agent_details(selected_agent)
|
|
325
|
+
continue
|
|
326
|
+
if choice_num == len(all_agents) + 1:
|
|
327
|
+
self._deploy_agent_interactive(all_agents)
|
|
328
|
+
elif choice_num == len(all_agents) + 2:
|
|
329
|
+
_, message = self.run_interactive_create()
|
|
182
330
|
if message:
|
|
183
|
-
# Message already has emoji from the function
|
|
184
331
|
print(f"\n{message}")
|
|
185
|
-
continue
|
|
186
|
-
elif choice_num == len(
|
|
187
|
-
|
|
332
|
+
continue
|
|
333
|
+
elif choice_num == len(all_agents) + 3:
|
|
334
|
+
local_templates = self.manager.list_local_templates()
|
|
335
|
+
_, message = self._interactive_delete_menu(local_templates)
|
|
188
336
|
if message:
|
|
189
|
-
# Message already has emoji from the function
|
|
190
337
|
print(f"\n{message}")
|
|
191
|
-
continue
|
|
192
|
-
elif choice_num == len(
|
|
193
|
-
|
|
338
|
+
continue
|
|
339
|
+
elif choice_num == len(all_agents) + 4:
|
|
340
|
+
_, message = self._interactive_import()
|
|
194
341
|
if message:
|
|
195
|
-
# Message already has emoji from the function
|
|
196
342
|
print(f"\n{message}")
|
|
197
|
-
continue
|
|
198
|
-
elif choice_num == len(
|
|
343
|
+
continue
|
|
344
|
+
elif choice_num == len(all_agents) + 5:
|
|
199
345
|
_success, message = self._interactive_export()
|
|
200
346
|
if message:
|
|
201
|
-
# Message already has emoji from the function
|
|
202
347
|
print(f"\n{message}")
|
|
203
|
-
continue
|
|
204
|
-
elif choice_num == len(
|
|
348
|
+
continue
|
|
349
|
+
elif choice_num == len(all_agents) + 6 and self.discovery_enabled:
|
|
350
|
+
self._browse_agents_interactive()
|
|
351
|
+
continue
|
|
352
|
+
elif choice_num == len(all_agents) + 7 and self.discovery_enabled:
|
|
353
|
+
self._deploy_preset_interactive()
|
|
354
|
+
continue
|
|
355
|
+
elif choice_num == len(all_agents) + 8 and self.discovery_enabled:
|
|
356
|
+
self._manage_sources_interactive()
|
|
357
|
+
continue
|
|
358
|
+
elif choice_num == exit_num:
|
|
205
359
|
return True, "Management menu exited"
|
|
206
360
|
else:
|
|
207
361
|
print("❌ Invalid choice. Please try again.")
|
|
@@ -919,6 +1073,762 @@ class AgentWizard:
|
|
|
919
1073
|
|
|
920
1074
|
return len(results["successful"]) > 0, message.strip()
|
|
921
1075
|
|
|
1076
|
+
def _show_agent_details(self, agent: Dict[str, Any]) -> None:
|
|
1077
|
+
"""Show detailed information about an agent.
|
|
1078
|
+
|
|
1079
|
+
Args:
|
|
1080
|
+
agent: Agent metadata dictionary
|
|
1081
|
+
"""
|
|
1082
|
+
print("\n" + "=" * 60)
|
|
1083
|
+
print(f"📄 Agent Details: {agent['agent_id']}")
|
|
1084
|
+
print("=" * 60)
|
|
1085
|
+
print(f"Name: {agent['name']}")
|
|
1086
|
+
print(f"Category: {agent['category'] or 'N/A'}")
|
|
1087
|
+
print(f"Source: [{agent['source_type']}] {agent['source_identifier']}")
|
|
1088
|
+
print(f"Status: {'✓ Deployed' if agent['deployed'] else 'Available'}")
|
|
1089
|
+
print(f"Path: {agent['path']}")
|
|
1090
|
+
|
|
1091
|
+
if agent["description"]:
|
|
1092
|
+
print("\nDescription:")
|
|
1093
|
+
print(
|
|
1094
|
+
f" {agent['description'][:200]}{'...' if len(agent['description']) > 200 else ''}"
|
|
1095
|
+
)
|
|
1096
|
+
|
|
1097
|
+
input("\nPress Enter to continue...")
|
|
1098
|
+
|
|
1099
|
+
def _deploy_agent_interactive(self, available_agents: List[Dict[str, Any]]):
|
|
1100
|
+
"""Interactive agent deployment.
|
|
1101
|
+
|
|
1102
|
+
Args:
|
|
1103
|
+
available_agents: List of all available agents
|
|
1104
|
+
"""
|
|
1105
|
+
# Filter to non-deployed agents using improved detection (1M-502 Phase 1)
|
|
1106
|
+
# This checks both .claude-mpm/agents/ and .claude/agents/
|
|
1107
|
+
deployable = apply_all_filters(
|
|
1108
|
+
available_agents, filter_base=True, filter_deployed=True
|
|
1109
|
+
)
|
|
1110
|
+
|
|
1111
|
+
if not deployable:
|
|
1112
|
+
print("\n✅ All agents are already deployed!")
|
|
1113
|
+
input("\nPress Enter to continue...")
|
|
1114
|
+
return
|
|
1115
|
+
|
|
1116
|
+
print("\n" + "=" * 60)
|
|
1117
|
+
print("📦 Deploy Agent")
|
|
1118
|
+
print("=" * 60)
|
|
1119
|
+
print(f"\n{len(deployable)} agent(s) available to deploy:\n")
|
|
1120
|
+
|
|
1121
|
+
# Build agent selection choices with arrow-key navigation
|
|
1122
|
+
agent_choices = [
|
|
1123
|
+
f"{i}. {agent['agent_id']} - {agent['description'][:60]}{'...' if len(agent['description']) > 60 else ''}"
|
|
1124
|
+
for i, agent in enumerate(deployable, 1)
|
|
1125
|
+
]
|
|
1126
|
+
|
|
1127
|
+
choice = questionary.select(
|
|
1128
|
+
"Select agent to deploy:", choices=agent_choices, style=QUESTIONARY_STYLE
|
|
1129
|
+
).ask()
|
|
1130
|
+
|
|
1131
|
+
if not choice: # User pressed Esc
|
|
1132
|
+
return
|
|
1133
|
+
|
|
1134
|
+
# Parse agent index from "N. agent_id - description" format
|
|
1135
|
+
idx = int(choice.split(".")[0]) - 1
|
|
1136
|
+
agent = deployable[idx]
|
|
1137
|
+
|
|
1138
|
+
# Deploy agent using deployment service
|
|
1139
|
+
print(f"\n🚀 Deploying {agent['agent_id']}...")
|
|
1140
|
+
|
|
1141
|
+
try:
|
|
1142
|
+
# Use SingleAgentDeployer for deployment
|
|
1143
|
+
from claude_mpm.services.agents.deployment.agent_template_builder import (
|
|
1144
|
+
AgentTemplateBuilder,
|
|
1145
|
+
)
|
|
1146
|
+
from claude_mpm.services.agents.deployment.agent_version_manager import (
|
|
1147
|
+
AgentVersionManager,
|
|
1148
|
+
)
|
|
1149
|
+
from claude_mpm.services.agents.deployment.deployment_results_manager import (
|
|
1150
|
+
DeploymentResultsManager,
|
|
1151
|
+
)
|
|
1152
|
+
from claude_mpm.services.agents.deployment.single_agent_deployer import (
|
|
1153
|
+
SingleAgentDeployer,
|
|
1154
|
+
)
|
|
1155
|
+
|
|
1156
|
+
# Initialize deployment services
|
|
1157
|
+
template_builder = AgentTemplateBuilder()
|
|
1158
|
+
version_manager = AgentVersionManager()
|
|
1159
|
+
results_manager = DeploymentResultsManager(self.logger)
|
|
1160
|
+
deployer = SingleAgentDeployer(
|
|
1161
|
+
template_builder=template_builder,
|
|
1162
|
+
version_manager=version_manager,
|
|
1163
|
+
results_manager=results_manager,
|
|
1164
|
+
logger=self.logger,
|
|
1165
|
+
)
|
|
1166
|
+
|
|
1167
|
+
# Prepare deployment parameters
|
|
1168
|
+
template_path = Path(agent["path"])
|
|
1169
|
+
target_dir = Path.cwd() / ".claude" / "agents"
|
|
1170
|
+
|
|
1171
|
+
# Find base_agent.json in multiple possible locations
|
|
1172
|
+
base_agent_candidates = [
|
|
1173
|
+
Path.home()
|
|
1174
|
+
/ ".claude-mpm"
|
|
1175
|
+
/ "agents"
|
|
1176
|
+
/ "templates"
|
|
1177
|
+
/ "base_agent.json",
|
|
1178
|
+
Path.home() / ".claude-mpm" / "cache" / "base_agent.json",
|
|
1179
|
+
Path(__file__).parent.parent.parent
|
|
1180
|
+
/ "agents"
|
|
1181
|
+
/ "templates"
|
|
1182
|
+
/ "base_agent.json",
|
|
1183
|
+
]
|
|
1184
|
+
base_agent_path = None
|
|
1185
|
+
for candidate in base_agent_candidates:
|
|
1186
|
+
if candidate.exists():
|
|
1187
|
+
base_agent_path = candidate
|
|
1188
|
+
break
|
|
1189
|
+
|
|
1190
|
+
if not base_agent_path:
|
|
1191
|
+
base_agent_path = base_agent_candidates[
|
|
1192
|
+
0
|
|
1193
|
+
] # Use default even if not exists
|
|
1194
|
+
|
|
1195
|
+
# Deploy the agent
|
|
1196
|
+
success = deployer.deploy_agent(
|
|
1197
|
+
agent_name=agent["agent_id"],
|
|
1198
|
+
templates_dir=template_path.parent,
|
|
1199
|
+
target_dir=target_dir,
|
|
1200
|
+
base_agent_path=base_agent_path,
|
|
1201
|
+
force_rebuild=True,
|
|
1202
|
+
working_directory=Path.cwd(),
|
|
1203
|
+
)
|
|
1204
|
+
|
|
1205
|
+
if success:
|
|
1206
|
+
print(f"\n✅ Successfully deployed {agent['agent_id']}")
|
|
1207
|
+
else:
|
|
1208
|
+
print(f"\n❌ Failed to deploy {agent['agent_id']}")
|
|
1209
|
+
|
|
1210
|
+
except Exception as e:
|
|
1211
|
+
self.logger.error(f"Deployment failed: {e}", exc_info=True)
|
|
1212
|
+
print(f"\n❌ Deployment error: {e}")
|
|
1213
|
+
|
|
1214
|
+
input("\nPress Enter to continue...")
|
|
1215
|
+
|
|
1216
|
+
def _browse_agents_interactive(self):
|
|
1217
|
+
"""Interactive agent browsing with filters."""
|
|
1218
|
+
if not self.discovery_enabled or not self.source_manager:
|
|
1219
|
+
print("\n❌ Discovery service not available")
|
|
1220
|
+
input("\nPress Enter to continue...")
|
|
1221
|
+
return
|
|
1222
|
+
|
|
1223
|
+
while True:
|
|
1224
|
+
print("\n" + "=" * 60)
|
|
1225
|
+
print("🔍 Browse & Filter Agents")
|
|
1226
|
+
print("=" * 60)
|
|
1227
|
+
|
|
1228
|
+
# Show filter menu with arrow-key navigation
|
|
1229
|
+
print("\n[bold]Filter by:[/bold]")
|
|
1230
|
+
|
|
1231
|
+
filter_choices = [
|
|
1232
|
+
"1. Category (engineer/backend, qa, ops, etc.)",
|
|
1233
|
+
"2. Language (python, typescript, rust, etc.)",
|
|
1234
|
+
"3. Framework (react, nextjs, flask, etc.)",
|
|
1235
|
+
"4. Show all agents",
|
|
1236
|
+
"← Back to main menu",
|
|
1237
|
+
]
|
|
1238
|
+
|
|
1239
|
+
choice = questionary.select(
|
|
1240
|
+
"Browse & Filter Agents:",
|
|
1241
|
+
choices=filter_choices,
|
|
1242
|
+
style=QUESTIONARY_STYLE,
|
|
1243
|
+
).ask()
|
|
1244
|
+
|
|
1245
|
+
if not choice or "Back" in choice:
|
|
1246
|
+
break
|
|
1247
|
+
|
|
1248
|
+
# Parse choice number if it starts with a digit
|
|
1249
|
+
if choice[0].isdigit():
|
|
1250
|
+
choice_num = choice.split(".")[0]
|
|
1251
|
+
else:
|
|
1252
|
+
break
|
|
1253
|
+
|
|
1254
|
+
filtered_agents = []
|
|
1255
|
+
filter_description = ""
|
|
1256
|
+
|
|
1257
|
+
if choice_num == "1":
|
|
1258
|
+
# Category filtering with arrow-key navigation
|
|
1259
|
+
categories = [
|
|
1260
|
+
"engineer/backend",
|
|
1261
|
+
"engineer/frontend",
|
|
1262
|
+
"qa",
|
|
1263
|
+
"ops",
|
|
1264
|
+
"documentation",
|
|
1265
|
+
"universal",
|
|
1266
|
+
]
|
|
1267
|
+
|
|
1268
|
+
cat_choices = [f"{idx}. {cat}" for idx, cat in enumerate(categories, 1)]
|
|
1269
|
+
|
|
1270
|
+
cat_choice = questionary.select(
|
|
1271
|
+
"Select category:", choices=cat_choices, style=QUESTIONARY_STYLE
|
|
1272
|
+
).ask()
|
|
1273
|
+
|
|
1274
|
+
if not cat_choice: # User pressed Esc
|
|
1275
|
+
continue
|
|
1276
|
+
|
|
1277
|
+
# Parse category from "N. category" format
|
|
1278
|
+
cat_idx = int(cat_choice.split(".")[0]) - 1
|
|
1279
|
+
category = categories[cat_idx]
|
|
1280
|
+
all_agents = self._merge_agent_sources()
|
|
1281
|
+
filtered_agents = [
|
|
1282
|
+
a for a in all_agents if a.get("category", "").startswith(category)
|
|
1283
|
+
]
|
|
1284
|
+
filter_description = f"Category: {category}"
|
|
1285
|
+
|
|
1286
|
+
elif choice_num == "2":
|
|
1287
|
+
# Language filtering (using AUTO-DEPLOY-INDEX if available)
|
|
1288
|
+
language = input(
|
|
1289
|
+
"\nEnter language (python, typescript, rust, go, etc.): "
|
|
1290
|
+
).strip()
|
|
1291
|
+
|
|
1292
|
+
try:
|
|
1293
|
+
# Find AUTO-DEPLOY-INDEX.md in agent repository
|
|
1294
|
+
from claude_mpm.services.agents.auto_deploy_index_parser import (
|
|
1295
|
+
AutoDeployIndexParser,
|
|
1296
|
+
)
|
|
1297
|
+
|
|
1298
|
+
index_path = (
|
|
1299
|
+
Path.home()
|
|
1300
|
+
/ ".claude-mpm"
|
|
1301
|
+
/ "cache"
|
|
1302
|
+
/ "remote-agents"
|
|
1303
|
+
/ "bobmatnyc"
|
|
1304
|
+
/ "claude-mpm-agents"
|
|
1305
|
+
/ "AUTO-DEPLOY-INDEX.md"
|
|
1306
|
+
)
|
|
1307
|
+
if not index_path.exists():
|
|
1308
|
+
print(
|
|
1309
|
+
f"[yellow]Could not find AUTO-DEPLOY-INDEX.md at: {index_path}[/yellow]"
|
|
1310
|
+
)
|
|
1311
|
+
input("\nPress Enter to continue...")
|
|
1312
|
+
continue
|
|
1313
|
+
|
|
1314
|
+
parser = AutoDeployIndexParser(index_path)
|
|
1315
|
+
lang_agents = parser.get_agents_by_language(language.lower())
|
|
1316
|
+
|
|
1317
|
+
# Get full agent details from discovery
|
|
1318
|
+
all_agents = self._merge_agent_sources()
|
|
1319
|
+
agent_ids = lang_agents.get("core", []) + lang_agents.get(
|
|
1320
|
+
"optional", []
|
|
1321
|
+
)
|
|
1322
|
+
filtered_agents = [
|
|
1323
|
+
a for a in all_agents if a["agent_id"] in agent_ids
|
|
1324
|
+
]
|
|
1325
|
+
filter_description = f"Language: {language}"
|
|
1326
|
+
except Exception as e:
|
|
1327
|
+
self.logger.error(f"Language filter error: {e}", exc_info=True)
|
|
1328
|
+
print(f"[yellow]Could not filter by language: {e}[/yellow]")
|
|
1329
|
+
input("\nPress Enter to continue...")
|
|
1330
|
+
continue
|
|
1331
|
+
|
|
1332
|
+
elif choice_num == "3":
|
|
1333
|
+
# Framework filtering
|
|
1334
|
+
framework = input(
|
|
1335
|
+
"\nEnter framework (react, nextjs, flask, django, etc.): "
|
|
1336
|
+
).strip()
|
|
1337
|
+
|
|
1338
|
+
try:
|
|
1339
|
+
from claude_mpm.services.agents.auto_deploy_index_parser import (
|
|
1340
|
+
AutoDeployIndexParser,
|
|
1341
|
+
)
|
|
1342
|
+
|
|
1343
|
+
index_path = (
|
|
1344
|
+
Path.home()
|
|
1345
|
+
/ ".claude-mpm"
|
|
1346
|
+
/ "cache"
|
|
1347
|
+
/ "remote-agents"
|
|
1348
|
+
/ "bobmatnyc"
|
|
1349
|
+
/ "claude-mpm-agents"
|
|
1350
|
+
/ "AUTO-DEPLOY-INDEX.md"
|
|
1351
|
+
)
|
|
1352
|
+
if not index_path.exists():
|
|
1353
|
+
print(
|
|
1354
|
+
f"[yellow]Could not find AUTO-DEPLOY-INDEX.md at: {index_path}[/yellow]"
|
|
1355
|
+
)
|
|
1356
|
+
input("\nPress Enter to continue...")
|
|
1357
|
+
continue
|
|
1358
|
+
|
|
1359
|
+
parser = AutoDeployIndexParser(index_path)
|
|
1360
|
+
framework_agent_ids = parser.get_agents_by_framework(
|
|
1361
|
+
framework.lower()
|
|
1362
|
+
)
|
|
1363
|
+
|
|
1364
|
+
all_agents = self._merge_agent_sources()
|
|
1365
|
+
filtered_agents = [
|
|
1366
|
+
a for a in all_agents if a["agent_id"] in framework_agent_ids
|
|
1367
|
+
]
|
|
1368
|
+
filter_description = f"Framework: {framework}"
|
|
1369
|
+
except Exception as e:
|
|
1370
|
+
self.logger.error(f"Framework filter error: {e}", exc_info=True)
|
|
1371
|
+
print(f"[yellow]Could not filter by framework: {e}[/yellow]")
|
|
1372
|
+
input("\nPress Enter to continue...")
|
|
1373
|
+
continue
|
|
1374
|
+
|
|
1375
|
+
elif choice_num == "4":
|
|
1376
|
+
# Show all agents
|
|
1377
|
+
filtered_agents = self._merge_agent_sources()
|
|
1378
|
+
filter_description = "All agents"
|
|
1379
|
+
else:
|
|
1380
|
+
print("❌ Invalid choice")
|
|
1381
|
+
input("\nPress Enter to continue...")
|
|
1382
|
+
continue
|
|
1383
|
+
|
|
1384
|
+
# Display filtered results
|
|
1385
|
+
print("\n" + "=" * 60)
|
|
1386
|
+
print(f"📋 {filter_description} ({len(filtered_agents)} agents)")
|
|
1387
|
+
print("=" * 60)
|
|
1388
|
+
|
|
1389
|
+
if not filtered_agents:
|
|
1390
|
+
print("\n[yellow]No agents found matching filter[/yellow]")
|
|
1391
|
+
else:
|
|
1392
|
+
print(f"\n{'#':<4} {'Agent ID':<40} {'Name':<25} {'Status':<12}")
|
|
1393
|
+
print("-" * 85)
|
|
1394
|
+
|
|
1395
|
+
for idx, agent in enumerate(filtered_agents, 1):
|
|
1396
|
+
agent_id = (
|
|
1397
|
+
agent["agent_id"][:39]
|
|
1398
|
+
if len(agent["agent_id"]) > 39
|
|
1399
|
+
else agent["agent_id"]
|
|
1400
|
+
)
|
|
1401
|
+
name = (
|
|
1402
|
+
agent["name"][:24] if len(agent["name"]) > 24 else agent["name"]
|
|
1403
|
+
)
|
|
1404
|
+
status = "✓ Deployed" if agent.get("deployed") else "Available"
|
|
1405
|
+
print(f"{idx:<4} {agent_id:<40} {name:<25} {status:<12}")
|
|
1406
|
+
|
|
1407
|
+
print("\n[bold]Actions:[/bold]")
|
|
1408
|
+
print(" [d] Deploy agent from this list")
|
|
1409
|
+
print(" [v] View agent details")
|
|
1410
|
+
print(" [n] New filter")
|
|
1411
|
+
print(" [b] Back to main menu")
|
|
1412
|
+
|
|
1413
|
+
action = input("\nSelect action: ").strip()
|
|
1414
|
+
|
|
1415
|
+
if action == "b":
|
|
1416
|
+
break
|
|
1417
|
+
if action == "n":
|
|
1418
|
+
continue
|
|
1419
|
+
if action == "d":
|
|
1420
|
+
self._deploy_from_filtered_list(filtered_agents)
|
|
1421
|
+
elif action == "v":
|
|
1422
|
+
self._view_from_filtered_list(filtered_agents)
|
|
1423
|
+
else:
|
|
1424
|
+
print("❌ Invalid choice")
|
|
1425
|
+
input("\nPress Enter to continue...")
|
|
1426
|
+
|
|
1427
|
+
def _deploy_from_filtered_list(self, agents: List[Dict[str, Any]]):
|
|
1428
|
+
"""Deploy an agent from a filtered list.
|
|
1429
|
+
|
|
1430
|
+
Args:
|
|
1431
|
+
agents: List of agent dictionaries with metadata
|
|
1432
|
+
"""
|
|
1433
|
+
if not agents:
|
|
1434
|
+
print("\n[yellow]No agents in list[/yellow]")
|
|
1435
|
+
input("\nPress Enter to continue...")
|
|
1436
|
+
return
|
|
1437
|
+
|
|
1438
|
+
deployable = [a for a in agents if not a.get("deployed")]
|
|
1439
|
+
|
|
1440
|
+
if not deployable:
|
|
1441
|
+
print("\n[yellow]All agents in this list are already deployed[/yellow]")
|
|
1442
|
+
input("\nPress Enter to continue...")
|
|
1443
|
+
return
|
|
1444
|
+
|
|
1445
|
+
# Build agent selection choices
|
|
1446
|
+
agent_choices = [
|
|
1447
|
+
f"{i}. {agent['agent_id']}" for i, agent in enumerate(agents, 1)
|
|
1448
|
+
]
|
|
1449
|
+
|
|
1450
|
+
agent_choice = questionary.select(
|
|
1451
|
+
"Select agent to deploy:", choices=agent_choices, style=QUESTIONARY_STYLE
|
|
1452
|
+
).ask()
|
|
1453
|
+
|
|
1454
|
+
if not agent_choice: # User pressed Esc
|
|
1455
|
+
return
|
|
1456
|
+
|
|
1457
|
+
# Parse agent index from "N. agent_id" format
|
|
1458
|
+
idx = int(agent_choice.split(".")[0]) - 1
|
|
1459
|
+
agent = agents[idx]
|
|
1460
|
+
|
|
1461
|
+
if agent.get("deployed"):
|
|
1462
|
+
print(f"\n[yellow]{agent['agent_id']} is already deployed[/yellow]")
|
|
1463
|
+
else:
|
|
1464
|
+
print(f"\n🚀 Deploying {agent['agent_id']}...")
|
|
1465
|
+
|
|
1466
|
+
try:
|
|
1467
|
+
from claude_mpm.services.agents.deployment.agent_template_builder import (
|
|
1468
|
+
AgentTemplateBuilder,
|
|
1469
|
+
)
|
|
1470
|
+
from claude_mpm.services.agents.deployment.agent_version_manager import (
|
|
1471
|
+
AgentVersionManager,
|
|
1472
|
+
)
|
|
1473
|
+
from claude_mpm.services.agents.deployment.deployment_results_manager import (
|
|
1474
|
+
DeploymentResultsManager,
|
|
1475
|
+
)
|
|
1476
|
+
from claude_mpm.services.agents.deployment.single_agent_deployer import (
|
|
1477
|
+
SingleAgentDeployer,
|
|
1478
|
+
)
|
|
1479
|
+
|
|
1480
|
+
# Initialize deployment services
|
|
1481
|
+
template_builder = AgentTemplateBuilder()
|
|
1482
|
+
version_manager = AgentVersionManager()
|
|
1483
|
+
results_manager = DeploymentResultsManager(self.logger)
|
|
1484
|
+
deployer = SingleAgentDeployer(
|
|
1485
|
+
template_builder=template_builder,
|
|
1486
|
+
version_manager=version_manager,
|
|
1487
|
+
results_manager=results_manager,
|
|
1488
|
+
logger=self.logger,
|
|
1489
|
+
)
|
|
1490
|
+
|
|
1491
|
+
# Prepare deployment parameters
|
|
1492
|
+
template_path = Path(agent["path"])
|
|
1493
|
+
target_dir = Path.cwd() / ".claude" / "agents"
|
|
1494
|
+
|
|
1495
|
+
# Find base_agent.json in multiple possible locations
|
|
1496
|
+
base_agent_candidates = [
|
|
1497
|
+
Path.home()
|
|
1498
|
+
/ ".claude-mpm"
|
|
1499
|
+
/ "agents"
|
|
1500
|
+
/ "templates"
|
|
1501
|
+
/ "base_agent.json",
|
|
1502
|
+
Path.home() / ".claude-mpm" / "cache" / "base_agent.json",
|
|
1503
|
+
Path(__file__).parent.parent.parent
|
|
1504
|
+
/ "agents"
|
|
1505
|
+
/ "templates"
|
|
1506
|
+
/ "base_agent.json",
|
|
1507
|
+
]
|
|
1508
|
+
base_agent_path = None
|
|
1509
|
+
for candidate in base_agent_candidates:
|
|
1510
|
+
if candidate.exists():
|
|
1511
|
+
base_agent_path = candidate
|
|
1512
|
+
break
|
|
1513
|
+
|
|
1514
|
+
if not base_agent_path:
|
|
1515
|
+
base_agent_path = base_agent_candidates[
|
|
1516
|
+
0
|
|
1517
|
+
] # Use default even if not exists
|
|
1518
|
+
|
|
1519
|
+
# Deploy the agent
|
|
1520
|
+
success = deployer.deploy_agent(
|
|
1521
|
+
agent_name=agent["agent_id"],
|
|
1522
|
+
templates_dir=template_path.parent,
|
|
1523
|
+
target_dir=target_dir,
|
|
1524
|
+
base_agent_path=base_agent_path,
|
|
1525
|
+
force_rebuild=True,
|
|
1526
|
+
working_directory=Path.cwd(),
|
|
1527
|
+
)
|
|
1528
|
+
|
|
1529
|
+
if success:
|
|
1530
|
+
print(f"[green]✓ Successfully deployed {agent['agent_id']}[/green]")
|
|
1531
|
+
else:
|
|
1532
|
+
print(f"[red]✗ Failed to deploy {agent['agent_id']}[/red]")
|
|
1533
|
+
|
|
1534
|
+
except Exception as e:
|
|
1535
|
+
self.logger.error(f"Deployment error: {e}", exc_info=True)
|
|
1536
|
+
print(f"❌ Deployment error: {e}")
|
|
1537
|
+
|
|
1538
|
+
input("\nPress Enter to continue...")
|
|
1539
|
+
|
|
1540
|
+
def _view_from_filtered_list(self, agents: List[Dict[str, Any]]):
|
|
1541
|
+
"""View details of an agent from filtered list.
|
|
1542
|
+
|
|
1543
|
+
Args:
|
|
1544
|
+
agents: List of agent dictionaries with metadata
|
|
1545
|
+
"""
|
|
1546
|
+
if not agents:
|
|
1547
|
+
print("\n[yellow]No agents in list[/yellow]")
|
|
1548
|
+
input("\nPress Enter to continue...")
|
|
1549
|
+
return
|
|
1550
|
+
|
|
1551
|
+
# Build agent selection choices
|
|
1552
|
+
agent_choices = [
|
|
1553
|
+
f"{i}. {agent['agent_id']}" for i, agent in enumerate(agents, 1)
|
|
1554
|
+
]
|
|
1555
|
+
|
|
1556
|
+
agent_choice = questionary.select(
|
|
1557
|
+
"Select agent to view:", choices=agent_choices, style=QUESTIONARY_STYLE
|
|
1558
|
+
).ask()
|
|
1559
|
+
|
|
1560
|
+
if not agent_choice: # User pressed Esc
|
|
1561
|
+
return
|
|
1562
|
+
|
|
1563
|
+
# Parse agent index from "N. agent_id" format
|
|
1564
|
+
idx = int(agent_choice.split(".")[0]) - 1
|
|
1565
|
+
agent = agents[idx]
|
|
1566
|
+
self._show_agent_details(agent)
|
|
1567
|
+
|
|
1568
|
+
def _deploy_preset_interactive(self):
|
|
1569
|
+
"""Interactive preset deployment with preview and confirmation."""
|
|
1570
|
+
from claude_mpm.services.agents.agent_preset_service import AgentPresetService
|
|
1571
|
+
|
|
1572
|
+
if not self.source_manager:
|
|
1573
|
+
print("\n❌ Source manager not available")
|
|
1574
|
+
input("\nPress Enter to continue...")
|
|
1575
|
+
return
|
|
1576
|
+
|
|
1577
|
+
preset_service = AgentPresetService(self.source_manager)
|
|
1578
|
+
|
|
1579
|
+
while True:
|
|
1580
|
+
print("\n" + "=" * 60)
|
|
1581
|
+
print("📦 Deploy Agent Preset")
|
|
1582
|
+
print("=" * 60)
|
|
1583
|
+
|
|
1584
|
+
# List available presets
|
|
1585
|
+
presets = preset_service.list_presets()
|
|
1586
|
+
|
|
1587
|
+
print(f"\n{len(presets)} preset(s) available:\n")
|
|
1588
|
+
print(f"{'#':<4} {'Preset':<20} {'Agents':<10} {'Description':<50}")
|
|
1589
|
+
print("-" * 90)
|
|
1590
|
+
|
|
1591
|
+
for idx, preset in enumerate(presets, 1):
|
|
1592
|
+
description = (
|
|
1593
|
+
preset["description"][:48] + "..."
|
|
1594
|
+
if len(preset["description"]) > 50
|
|
1595
|
+
else preset["description"]
|
|
1596
|
+
)
|
|
1597
|
+
print(
|
|
1598
|
+
f"{idx:<4} {preset['name']:<20} {len(preset.get('agents', [])):<10} {description:<50}"
|
|
1599
|
+
)
|
|
1600
|
+
|
|
1601
|
+
print("\n[bold]Actions:[/bold]")
|
|
1602
|
+
print(" [1-11] Select preset number")
|
|
1603
|
+
print(" [b] Back to main menu")
|
|
1604
|
+
|
|
1605
|
+
choice = input("\nSelect preset number or action: ").strip()
|
|
1606
|
+
|
|
1607
|
+
if choice.lower() == "b":
|
|
1608
|
+
break
|
|
1609
|
+
|
|
1610
|
+
try:
|
|
1611
|
+
idx = int(choice) - 1
|
|
1612
|
+
if idx < 0 or idx >= len(presets):
|
|
1613
|
+
raise ValueError("Out of range")
|
|
1614
|
+
|
|
1615
|
+
preset_name = presets[idx]["name"]
|
|
1616
|
+
|
|
1617
|
+
# Show preset details
|
|
1618
|
+
print("\n" + "=" * 60)
|
|
1619
|
+
print(f"📦 Preset: {preset_name}")
|
|
1620
|
+
print("=" * 60)
|
|
1621
|
+
print(f"\n[bold]Description:[/bold] {presets[idx]['description']}\n")
|
|
1622
|
+
|
|
1623
|
+
# Resolve preset
|
|
1624
|
+
print("🔍 Resolving preset agents...")
|
|
1625
|
+
resolution = preset_service.resolve_agents(
|
|
1626
|
+
preset_name, validate_availability=True
|
|
1627
|
+
)
|
|
1628
|
+
|
|
1629
|
+
if resolution.get("missing_agents"):
|
|
1630
|
+
print(
|
|
1631
|
+
f"\n⚠️ [red]Missing agents ({len(resolution['missing_agents'])}):[/red]"
|
|
1632
|
+
)
|
|
1633
|
+
for agent_id in resolution["missing_agents"]:
|
|
1634
|
+
print(f" • {agent_id}")
|
|
1635
|
+
print("\n[yellow]Cannot deploy preset with missing agents[/yellow]")
|
|
1636
|
+
input("\nPress Enter to continue...")
|
|
1637
|
+
continue
|
|
1638
|
+
|
|
1639
|
+
# Show agents to deploy
|
|
1640
|
+
agents = resolution.get("agents", [])
|
|
1641
|
+
print(f"\n[bold]Agents to deploy ({len(agents)}):[/bold]\n")
|
|
1642
|
+
|
|
1643
|
+
print(f"{'Agent ID':<40} {'Name':<25} {'Source':<25}")
|
|
1644
|
+
print("-" * 95)
|
|
1645
|
+
|
|
1646
|
+
for agent in agents:
|
|
1647
|
+
# Get agent metadata
|
|
1648
|
+
agent_metadata = agent.get("metadata", {})
|
|
1649
|
+
agent_meta_data = agent_metadata.get("metadata", {})
|
|
1650
|
+
|
|
1651
|
+
agent_id = (
|
|
1652
|
+
agent.get("agent_id", "")[:39]
|
|
1653
|
+
if len(agent.get("agent_id", "")) > 39
|
|
1654
|
+
else agent.get("agent_id", "")
|
|
1655
|
+
)
|
|
1656
|
+
name = (
|
|
1657
|
+
agent_meta_data.get("name", "")[:24]
|
|
1658
|
+
if len(agent_meta_data.get("name", "")) > 24
|
|
1659
|
+
else agent_meta_data.get("name", "")
|
|
1660
|
+
)
|
|
1661
|
+
source = (
|
|
1662
|
+
agent.get("source", "unknown")[:24]
|
|
1663
|
+
if len(agent.get("source", "unknown")) > 24
|
|
1664
|
+
else agent.get("source", "unknown")
|
|
1665
|
+
)
|
|
1666
|
+
|
|
1667
|
+
print(f"{agent_id:<40} {name:<25} {source:<25}")
|
|
1668
|
+
|
|
1669
|
+
# Confirm deployment
|
|
1670
|
+
print("\n[bold]Options:[/bold]")
|
|
1671
|
+
print(" [y] Deploy all agents")
|
|
1672
|
+
print(" [n] Cancel")
|
|
1673
|
+
|
|
1674
|
+
confirm = input("\nProceed with deployment? ").strip()
|
|
1675
|
+
|
|
1676
|
+
if confirm.lower() == "y":
|
|
1677
|
+
print(f"\n🚀 Deploying preset '{preset_name}'...\n")
|
|
1678
|
+
|
|
1679
|
+
from claude_mpm.services.agents.deployment.agent_template_builder import (
|
|
1680
|
+
AgentTemplateBuilder,
|
|
1681
|
+
)
|
|
1682
|
+
from claude_mpm.services.agents.deployment.agent_version_manager import (
|
|
1683
|
+
AgentVersionManager,
|
|
1684
|
+
)
|
|
1685
|
+
from claude_mpm.services.agents.deployment.deployment_results_manager import (
|
|
1686
|
+
DeploymentResultsManager,
|
|
1687
|
+
)
|
|
1688
|
+
from claude_mpm.services.agents.deployment.single_agent_deployer import (
|
|
1689
|
+
SingleAgentDeployer,
|
|
1690
|
+
)
|
|
1691
|
+
|
|
1692
|
+
# Initialize deployment services once for all agents
|
|
1693
|
+
template_builder = AgentTemplateBuilder()
|
|
1694
|
+
version_manager = AgentVersionManager()
|
|
1695
|
+
results_manager = DeploymentResultsManager(self.logger)
|
|
1696
|
+
deployer = SingleAgentDeployer(
|
|
1697
|
+
template_builder=template_builder,
|
|
1698
|
+
version_manager=version_manager,
|
|
1699
|
+
results_manager=results_manager,
|
|
1700
|
+
logger=self.logger,
|
|
1701
|
+
)
|
|
1702
|
+
|
|
1703
|
+
target_dir = Path.cwd() / ".claude" / "agents"
|
|
1704
|
+
|
|
1705
|
+
# Find base_agent.json
|
|
1706
|
+
base_agent_candidates = [
|
|
1707
|
+
Path.home()
|
|
1708
|
+
/ ".claude-mpm"
|
|
1709
|
+
/ "agents"
|
|
1710
|
+
/ "templates"
|
|
1711
|
+
/ "base_agent.json",
|
|
1712
|
+
Path.home() / ".claude-mpm" / "cache" / "base_agent.json",
|
|
1713
|
+
Path(__file__).parent.parent.parent
|
|
1714
|
+
/ "agents"
|
|
1715
|
+
/ "templates"
|
|
1716
|
+
/ "base_agent.json",
|
|
1717
|
+
]
|
|
1718
|
+
base_agent_path = None
|
|
1719
|
+
for candidate in base_agent_candidates:
|
|
1720
|
+
if candidate.exists():
|
|
1721
|
+
base_agent_path = candidate
|
|
1722
|
+
break
|
|
1723
|
+
|
|
1724
|
+
if not base_agent_path:
|
|
1725
|
+
base_agent_path = base_agent_candidates[0]
|
|
1726
|
+
|
|
1727
|
+
deployed = 0
|
|
1728
|
+
failed = 0
|
|
1729
|
+
|
|
1730
|
+
for agent in agents:
|
|
1731
|
+
agent_id = agent["agent_id"]
|
|
1732
|
+
agent_metadata = agent.get("metadata", {})
|
|
1733
|
+
agent_path = agent_metadata.get(
|
|
1734
|
+
"path", agent_metadata.get("source_file", "")
|
|
1735
|
+
)
|
|
1736
|
+
|
|
1737
|
+
if not agent_path:
|
|
1738
|
+
print(f" Deploying {agent_id}... [red]✗ (no path)[/red]")
|
|
1739
|
+
failed += 1
|
|
1740
|
+
continue
|
|
1741
|
+
|
|
1742
|
+
print(f" Deploying {agent_id}...", end=" ", flush=True)
|
|
1743
|
+
|
|
1744
|
+
try:
|
|
1745
|
+
template_path = Path(agent_path)
|
|
1746
|
+
success = deployer.deploy_agent(
|
|
1747
|
+
agent_name=agent_id,
|
|
1748
|
+
templates_dir=template_path.parent,
|
|
1749
|
+
target_dir=target_dir,
|
|
1750
|
+
base_agent_path=base_agent_path,
|
|
1751
|
+
force_rebuild=True,
|
|
1752
|
+
working_directory=Path.cwd(),
|
|
1753
|
+
)
|
|
1754
|
+
|
|
1755
|
+
if success:
|
|
1756
|
+
print("[green]✓[/green]")
|
|
1757
|
+
deployed += 1
|
|
1758
|
+
else:
|
|
1759
|
+
print("[red]✗[/red]")
|
|
1760
|
+
failed += 1
|
|
1761
|
+
except Exception as e:
|
|
1762
|
+
print(f"[red]✗ ({e})[/red]")
|
|
1763
|
+
self.logger.error(
|
|
1764
|
+
f"Failed to deploy {agent_id}: {e}", exc_info=True
|
|
1765
|
+
)
|
|
1766
|
+
failed += 1
|
|
1767
|
+
|
|
1768
|
+
print("\n[bold]Summary:[/bold]")
|
|
1769
|
+
print(f" • Deployed: {deployed}")
|
|
1770
|
+
print(f" • Failed: {failed}")
|
|
1771
|
+
print(f" • Total: {len(agents)}")
|
|
1772
|
+
|
|
1773
|
+
if failed == 0:
|
|
1774
|
+
print(
|
|
1775
|
+
f"\n[green]✓ Preset '{preset_name}' deployed successfully![/green]"
|
|
1776
|
+
)
|
|
1777
|
+
else:
|
|
1778
|
+
print(
|
|
1779
|
+
f"\n[yellow]⚠ Preset deployed with {failed} failures[/yellow]"
|
|
1780
|
+
)
|
|
1781
|
+
|
|
1782
|
+
input("\nPress Enter to continue...")
|
|
1783
|
+
break
|
|
1784
|
+
|
|
1785
|
+
except (ValueError, IndexError):
|
|
1786
|
+
print("❌ Invalid preset selection")
|
|
1787
|
+
input("\nPress Enter to continue...")
|
|
1788
|
+
except Exception as e:
|
|
1789
|
+
self.logger.error(f"Preset deployment error: {e}", exc_info=True)
|
|
1790
|
+
print(f"❌ Error: {e}")
|
|
1791
|
+
input("\nPress Enter to continue...")
|
|
1792
|
+
|
|
1793
|
+
def _manage_sources_interactive(self):
|
|
1794
|
+
"""Interactive source management."""
|
|
1795
|
+
if not self.discovery_enabled or not self.source_manager:
|
|
1796
|
+
print("\n❌ Source manager not available")
|
|
1797
|
+
input("\nPress Enter to continue...")
|
|
1798
|
+
return
|
|
1799
|
+
|
|
1800
|
+
print("\n" + "=" * 60)
|
|
1801
|
+
print("🔗 Manage Agent Sources")
|
|
1802
|
+
print("=" * 60)
|
|
1803
|
+
|
|
1804
|
+
try:
|
|
1805
|
+
from claude_mpm.config.agent_sources import AgentSourceConfiguration
|
|
1806
|
+
|
|
1807
|
+
config = AgentSourceConfiguration()
|
|
1808
|
+
sources = config.list_sources()
|
|
1809
|
+
|
|
1810
|
+
if not sources:
|
|
1811
|
+
print("\n📭 No sources configured.")
|
|
1812
|
+
else:
|
|
1813
|
+
print(f"\n{len(sources)} source(s) configured:\n")
|
|
1814
|
+
print(f"{'Source':<40} {'Priority':<10} {'Status':<10}")
|
|
1815
|
+
print("-" * 60)
|
|
1816
|
+
|
|
1817
|
+
for source in sources:
|
|
1818
|
+
identifier = source.get("identifier", "unknown")[:39]
|
|
1819
|
+
priority = str(source.get("priority", 100))
|
|
1820
|
+
status = "✓ Active" if source.get("enabled", True) else "Disabled"
|
|
1821
|
+
print(f"{identifier:<40} {priority:<10} {status:<10}")
|
|
1822
|
+
|
|
1823
|
+
print("\n💡 Use 'claude-mpm agent-source' command to add/remove sources")
|
|
1824
|
+
print("💡 Use 'claude-mpm agents discover' command to refresh agent cache")
|
|
1825
|
+
|
|
1826
|
+
except Exception as e:
|
|
1827
|
+
self.logger.error(f"Failed to list sources: {e}", exc_info=True)
|
|
1828
|
+
print(f"\n❌ Error: {e}")
|
|
1829
|
+
|
|
1830
|
+
input("\nPress Enter to continue...")
|
|
1831
|
+
|
|
922
1832
|
|
|
923
1833
|
def run_interactive_agent_wizard() -> int:
|
|
924
1834
|
"""Entry point for interactive agent wizard.
|