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
|
@@ -21,19 +21,29 @@ from claude_mpm.core.logging_config import get_logger
|
|
|
21
21
|
|
|
22
22
|
from .agent_discovery_service import AgentDiscoveryService
|
|
23
23
|
from .agent_version_manager import AgentVersionManager
|
|
24
|
+
from .remote_agent_discovery_service import RemoteAgentDiscoveryService
|
|
24
25
|
|
|
25
26
|
|
|
26
27
|
class MultiSourceAgentDeploymentService:
|
|
27
28
|
"""Service for deploying agents from multiple sources with version comparison.
|
|
28
29
|
|
|
29
30
|
This service ensures that the highest version of each agent is deployed,
|
|
30
|
-
regardless of whether it comes from system templates, project agents,
|
|
31
|
-
user agents.
|
|
31
|
+
regardless of whether it comes from system templates, project agents,
|
|
32
|
+
user agents, or remote agents.
|
|
33
|
+
|
|
34
|
+
4-Tier Agent Discovery:
|
|
35
|
+
1. System templates (lowest priority) - Built-in agents
|
|
36
|
+
2. User agents (DEPRECATED) - User-level customizations (~/.claude-mpm/agents/)
|
|
37
|
+
3. Remote agents - Agents cached from GitHub
|
|
38
|
+
4. Project agents (highest priority) - Project-specific customizations
|
|
32
39
|
|
|
33
40
|
WHY: The current system processes agents from a single source at a time,
|
|
34
41
|
which can result in lower version agents being deployed if they exist in
|
|
35
42
|
a higher priority source. This service fixes that by comparing versions
|
|
36
43
|
across all sources.
|
|
44
|
+
|
|
45
|
+
DEPRECATION: User-level agents (~/.claude-mpm/agents/) are deprecated and
|
|
46
|
+
will be removed in v5.0.0. Use project-level agents instead.
|
|
37
47
|
"""
|
|
38
48
|
|
|
39
49
|
def __init__(self):
|
|
@@ -46,18 +56,30 @@ class MultiSourceAgentDeploymentService:
|
|
|
46
56
|
system_templates_dir: Optional[Path] = None,
|
|
47
57
|
project_agents_dir: Optional[Path] = None,
|
|
48
58
|
user_agents_dir: Optional[Path] = None,
|
|
59
|
+
remote_agents_dir: Optional[Path] = None,
|
|
49
60
|
working_directory: Optional[Path] = None,
|
|
50
61
|
) -> Dict[str, List[Dict[str, Any]]]:
|
|
51
|
-
"""Discover agents from all
|
|
62
|
+
"""Discover agents from all 4 tiers (system, user, remote, project).
|
|
63
|
+
|
|
64
|
+
Priority hierarchy (highest to lowest):
|
|
65
|
+
4. Project agents - Highest priority, project-specific customizations
|
|
66
|
+
3. Remote agents - GitHub-synced agents from cache
|
|
67
|
+
2. User agents - DEPRECATED, user-level customizations
|
|
68
|
+
1. System templates - Lowest priority, built-in agents
|
|
52
69
|
|
|
53
70
|
Args:
|
|
54
71
|
system_templates_dir: Directory containing system agent templates
|
|
55
72
|
project_agents_dir: Directory containing project-specific agents
|
|
56
|
-
user_agents_dir: Directory containing user custom agents
|
|
73
|
+
user_agents_dir: Directory containing user custom agents (DEPRECATED)
|
|
74
|
+
remote_agents_dir: Directory containing cached remote agents
|
|
57
75
|
working_directory: Current working directory for finding project agents
|
|
58
76
|
|
|
59
77
|
Returns:
|
|
60
78
|
Dictionary mapping agent names to list of agent info from different sources
|
|
79
|
+
|
|
80
|
+
Deprecation Warning:
|
|
81
|
+
User-level agents are deprecated and will show a warning if found.
|
|
82
|
+
Use 'claude-mpm agents migrate-to-project' to migrate them.
|
|
61
83
|
"""
|
|
62
84
|
agents_by_name = {}
|
|
63
85
|
|
|
@@ -80,24 +102,53 @@ class MultiSourceAgentDeploymentService:
|
|
|
80
102
|
if not user_agents_dir.exists():
|
|
81
103
|
user_agents_dir = None
|
|
82
104
|
|
|
83
|
-
|
|
105
|
+
if not remote_agents_dir:
|
|
106
|
+
# Check for remote agents in cache directory
|
|
107
|
+
cache_dir = Path.home() / ".claude-mpm" / "cache"
|
|
108
|
+
remote_agents_dir = cache_dir / "remote-agents"
|
|
109
|
+
if not remote_agents_dir.exists():
|
|
110
|
+
remote_agents_dir = None
|
|
111
|
+
|
|
112
|
+
# Discover agents from each source in priority order
|
|
113
|
+
# Note: We process in reverse priority order (system first) and build up the dictionary
|
|
114
|
+
# The select_highest_version_agents() method will handle the actual prioritization
|
|
84
115
|
sources = [
|
|
85
116
|
("system", system_templates_dir),
|
|
86
|
-
("project", project_agents_dir),
|
|
87
117
|
("user", user_agents_dir),
|
|
118
|
+
("remote", remote_agents_dir),
|
|
119
|
+
("project", project_agents_dir),
|
|
88
120
|
]
|
|
89
121
|
|
|
122
|
+
# Track if we found user agents for deprecation warning
|
|
123
|
+
user_agents_found = False
|
|
124
|
+
|
|
90
125
|
for source_name, source_dir in sources:
|
|
91
126
|
if source_dir and source_dir.exists():
|
|
92
127
|
self.logger.debug(
|
|
93
128
|
f"Discovering agents from {source_name} source: {source_dir}"
|
|
94
129
|
)
|
|
95
|
-
|
|
96
|
-
#
|
|
97
|
-
|
|
130
|
+
|
|
131
|
+
# Use appropriate discovery service based on source type
|
|
132
|
+
if source_name == "remote":
|
|
133
|
+
# Remote agents are Markdown, use RemoteAgentDiscoveryService
|
|
134
|
+
remote_service = RemoteAgentDiscoveryService(source_dir)
|
|
135
|
+
agents = remote_service.discover_remote_agents()
|
|
136
|
+
else:
|
|
137
|
+
# Other sources are JSON, use AgentDiscoveryService
|
|
138
|
+
discovery_service = AgentDiscoveryService(source_dir)
|
|
139
|
+
# Pass log_discovery=False to avoid duplicate logging
|
|
140
|
+
agents = discovery_service.list_available_agents(
|
|
141
|
+
log_discovery=False
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
# Track user agents for deprecation warning
|
|
145
|
+
if source_name == "user" and agents:
|
|
146
|
+
user_agents_found = True
|
|
98
147
|
|
|
99
148
|
for agent_info in agents:
|
|
100
|
-
agent_name = agent_info.get("name")
|
|
149
|
+
agent_name = agent_info.get("name") or agent_info.get(
|
|
150
|
+
"metadata", {}
|
|
151
|
+
).get("name")
|
|
101
152
|
if not agent_name:
|
|
102
153
|
continue
|
|
103
154
|
|
|
@@ -116,6 +167,26 @@ class MultiSourceAgentDeploymentService:
|
|
|
116
167
|
f"Discovered {len(agents)} {source_name} agent templates from {source_dir.name}"
|
|
117
168
|
)
|
|
118
169
|
|
|
170
|
+
# Show deprecation warning if user agents found
|
|
171
|
+
if user_agents_found:
|
|
172
|
+
self.logger.warning(
|
|
173
|
+
"\n"
|
|
174
|
+
"⚠️ DEPRECATION WARNING: User-level agents found in ~/.claude-mpm/agents/\n"
|
|
175
|
+
" User-level agent deployment is deprecated and will be removed in v5.0.0\n"
|
|
176
|
+
"\n"
|
|
177
|
+
" Why this change?\n"
|
|
178
|
+
" - Project isolation: Agents should be project-specific\n"
|
|
179
|
+
" - Version control: Project agents can be versioned with your code\n"
|
|
180
|
+
" - Team consistency: All team members use the same agents\n"
|
|
181
|
+
"\n"
|
|
182
|
+
" Migration:\n"
|
|
183
|
+
" 1. Run: claude-mpm agents migrate-to-project\n"
|
|
184
|
+
" 2. Verify agents work in .claude-mpm/agents/\n"
|
|
185
|
+
" 3. Remove: rm -rf ~/.claude-mpm/agents/\n"
|
|
186
|
+
"\n"
|
|
187
|
+
" Learn more: https://docs.claude-mpm.dev/agents/migration\n"
|
|
188
|
+
)
|
|
189
|
+
|
|
119
190
|
return agents_by_name
|
|
120
191
|
|
|
121
192
|
def select_highest_version_agents(
|
|
@@ -226,17 +297,19 @@ class MultiSourceAgentDeploymentService:
|
|
|
226
297
|
system_templates_dir: Optional[Path] = None,
|
|
227
298
|
project_agents_dir: Optional[Path] = None,
|
|
228
299
|
user_agents_dir: Optional[Path] = None,
|
|
300
|
+
remote_agents_dir: Optional[Path] = None,
|
|
229
301
|
working_directory: Optional[Path] = None,
|
|
230
302
|
excluded_agents: Optional[List[str]] = None,
|
|
231
303
|
config: Optional[Config] = None,
|
|
232
304
|
cleanup_outdated: bool = True,
|
|
233
305
|
) -> Tuple[Dict[str, Path], Dict[str, str], Dict[str, Any]]:
|
|
234
|
-
"""Get the highest version agents from all
|
|
306
|
+
"""Get the highest version agents from all 4 tiers for deployment.
|
|
235
307
|
|
|
236
308
|
Args:
|
|
237
309
|
system_templates_dir: Directory containing system agent templates
|
|
238
310
|
project_agents_dir: Directory containing project-specific agents
|
|
239
|
-
user_agents_dir: Directory containing user custom agents
|
|
311
|
+
user_agents_dir: Directory containing user custom agents (DEPRECATED)
|
|
312
|
+
remote_agents_dir: Directory containing cached remote agents
|
|
240
313
|
working_directory: Current working directory for finding project agents
|
|
241
314
|
excluded_agents: List of agent names to exclude from deployment
|
|
242
315
|
config: Configuration object for additional filtering
|
|
@@ -248,11 +321,12 @@ class MultiSourceAgentDeploymentService:
|
|
|
248
321
|
- Dictionary mapping agent names to their source
|
|
249
322
|
- Dictionary with cleanup results (removed, preserved, errors)
|
|
250
323
|
"""
|
|
251
|
-
# Discover all available agents
|
|
324
|
+
# Discover all available agents from 4 tiers
|
|
252
325
|
agents_by_name = self.discover_agents_from_all_sources(
|
|
253
326
|
system_templates_dir=system_templates_dir,
|
|
254
327
|
project_agents_dir=project_agents_dir,
|
|
255
328
|
user_agents_dir=user_agents_dir,
|
|
329
|
+
remote_agents_dir=remote_agents_dir,
|
|
256
330
|
working_directory=working_directory,
|
|
257
331
|
)
|
|
258
332
|
|
|
@@ -300,7 +374,21 @@ class MultiSourceAgentDeploymentService:
|
|
|
300
374
|
agent_sources = {}
|
|
301
375
|
|
|
302
376
|
for agent_name, agent_info in selected_agents.items():
|
|
303
|
-
|
|
377
|
+
# Defensive: Try multiple path fields for backward compatibility (ticket 1M-480)
|
|
378
|
+
# Priority: 'path' -> 'file_path' -> 'source_file'
|
|
379
|
+
path_str = (
|
|
380
|
+
agent_info.get("path")
|
|
381
|
+
or agent_info.get("file_path")
|
|
382
|
+
or agent_info.get("source_file")
|
|
383
|
+
)
|
|
384
|
+
|
|
385
|
+
if not path_str:
|
|
386
|
+
self.logger.warning(
|
|
387
|
+
f"Agent '{agent_name}' missing path information (no 'path', 'file_path', or 'source_file' field)"
|
|
388
|
+
)
|
|
389
|
+
continue
|
|
390
|
+
|
|
391
|
+
template_path = Path(path_str)
|
|
304
392
|
if template_path.exists():
|
|
305
393
|
# Use the file stem as the key for consistency
|
|
306
394
|
file_stem = template_path.stem
|
|
@@ -371,8 +459,20 @@ class MultiSourceAgentDeploymentService:
|
|
|
371
459
|
if agent_info["source"] != "user":
|
|
372
460
|
continue
|
|
373
461
|
|
|
462
|
+
# Defensive: Get path from agent_info (ticket 1M-480)
|
|
463
|
+
path_str = (
|
|
464
|
+
agent_info.get("path")
|
|
465
|
+
or agent_info.get("file_path")
|
|
466
|
+
or agent_info.get("source_file")
|
|
467
|
+
)
|
|
468
|
+
if not path_str:
|
|
469
|
+
self.logger.warning(
|
|
470
|
+
f"User agent '{agent_name}' missing path information, skipping cleanup"
|
|
471
|
+
)
|
|
472
|
+
continue
|
|
473
|
+
|
|
374
474
|
# Safety check - ensure path is within user agents directory
|
|
375
|
-
user_agent_path = Path(
|
|
475
|
+
user_agent_path = Path(path_str)
|
|
376
476
|
try:
|
|
377
477
|
# Resolve paths to compare them safely
|
|
378
478
|
resolved_user_path = user_agent_path.resolve()
|
|
@@ -51,11 +51,11 @@ class DeploymentPipelineExecutor:
|
|
|
51
51
|
try:
|
|
52
52
|
# Check if step should be executed
|
|
53
53
|
if not step.should_execute(context):
|
|
54
|
-
self.logger.info(f"Skipping step {i+1}/{len(steps)}: {step.name}")
|
|
54
|
+
self.logger.info(f"Skipping step {i + 1}/{len(steps)}: {step.name}")
|
|
55
55
|
skipped_steps.append(step.name)
|
|
56
56
|
continue
|
|
57
57
|
|
|
58
|
-
self.logger.info(f"Executing step {i+1}/{len(steps)}: {step.name}")
|
|
58
|
+
self.logger.info(f"Executing step {i + 1}/{len(steps)}: {step.name}")
|
|
59
59
|
|
|
60
60
|
# Execute the step
|
|
61
61
|
result = step.execute(context)
|
|
@@ -9,10 +9,7 @@ from claude_mpm.core.logger import get_logger
|
|
|
9
9
|
|
|
10
10
|
from .config import DeploymentConfigManager
|
|
11
11
|
from .facade import DeploymentFacade
|
|
12
|
-
from .pipeline import
|
|
13
|
-
DeploymentPipelineBuilder,
|
|
14
|
-
DeploymentPipelineExecutor,
|
|
15
|
-
)
|
|
12
|
+
from .pipeline import DeploymentPipelineBuilder, DeploymentPipelineExecutor
|
|
16
13
|
from .results import DeploymentResultBuilder
|
|
17
14
|
|
|
18
15
|
# Import refactored components
|
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
"""Service for discovering and converting remote Markdown agents to JSON format.
|
|
2
|
+
|
|
3
|
+
This service handles the 4th tier of agent discovery: remote agents cached from GitHub.
|
|
4
|
+
Remote agents are stored as Markdown files with YAML frontmatter and need to be converted
|
|
5
|
+
to the JSON template format expected by the deployment system.
|
|
6
|
+
|
|
7
|
+
WHY: Remote agents from GitHub are cached as Markdown but the deployment system expects
|
|
8
|
+
JSON templates. This service bridges that gap and integrates remote agents into the
|
|
9
|
+
multi-tier discovery system.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import json
|
|
13
|
+
import re
|
|
14
|
+
from dataclasses import dataclass
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
from typing import Any, Dict, List, Optional
|
|
17
|
+
|
|
18
|
+
from claude_mpm.core.logging_config import get_logger
|
|
19
|
+
|
|
20
|
+
logger = get_logger(__name__)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@dataclass
|
|
24
|
+
class RemoteAgentMetadata:
|
|
25
|
+
"""Metadata extracted from remote agent Markdown file."""
|
|
26
|
+
|
|
27
|
+
name: str
|
|
28
|
+
description: str
|
|
29
|
+
model: str
|
|
30
|
+
routing_keywords: List[str]
|
|
31
|
+
routing_paths: List[str]
|
|
32
|
+
routing_priority: int
|
|
33
|
+
source_file: Path
|
|
34
|
+
version: str # SHA-256 hash from cache metadata
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class RemoteAgentDiscoveryService:
|
|
38
|
+
"""Discovers and converts remote Markdown agents to JSON format.
|
|
39
|
+
|
|
40
|
+
Remote agents are discovered from the cache directory (~/.claude-mpm/cache/remote-agents/)
|
|
41
|
+
where they are stored as Markdown files. This service:
|
|
42
|
+
1. Discovers all *.md files in the remote agents cache
|
|
43
|
+
2. Parses Markdown frontmatter and content to extract metadata
|
|
44
|
+
3. Converts to JSON template format for deployment
|
|
45
|
+
4. Retrieves version (SHA-256 hash) from cache metadata
|
|
46
|
+
|
|
47
|
+
Design Decision: Markdown Parsing Strategy
|
|
48
|
+
- Use regex for simple frontmatter extraction (fast, no dependencies)
|
|
49
|
+
- Parse key-value pairs from Configuration section
|
|
50
|
+
- Extract routing info from Routing section
|
|
51
|
+
- Fallback to sensible defaults when sections are missing
|
|
52
|
+
|
|
53
|
+
Trade-offs:
|
|
54
|
+
- Performance: Regex parsing is fast for our simple format
|
|
55
|
+
- Maintainability: Clear regex patterns are easy to understand
|
|
56
|
+
- Flexibility: Supports optional sections with defaults
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
def __init__(self, remote_agents_dir: Path):
|
|
60
|
+
"""Initialize the remote agent discovery service.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
remote_agents_dir: Directory containing cached remote agent Markdown files
|
|
64
|
+
"""
|
|
65
|
+
self.remote_agents_dir = remote_agents_dir
|
|
66
|
+
self.logger = get_logger(__name__)
|
|
67
|
+
|
|
68
|
+
def _generate_hierarchical_id(self, file_path: Path) -> str:
|
|
69
|
+
"""Generate hierarchical agent ID from file path.
|
|
70
|
+
|
|
71
|
+
Converts file path relative to agents subdirectory into hierarchical ID.
|
|
72
|
+
|
|
73
|
+
Design Decision: Path-based IDs for hierarchy preservation
|
|
74
|
+
|
|
75
|
+
Rationale: Agent IDs must reflect directory hierarchy to enable:
|
|
76
|
+
- Category-based filtering (engineer/backend/python-engineer)
|
|
77
|
+
- Preset matching against AUTO-DEPLOY-INDEX.md
|
|
78
|
+
- Multi-level organization without name collisions
|
|
79
|
+
|
|
80
|
+
Bug #4 Fix: Calculate relative to /agents/ subdirectory, not repository root
|
|
81
|
+
This ensures agent IDs are based on their position within the agents directory.
|
|
82
|
+
|
|
83
|
+
Example:
|
|
84
|
+
Input: /cache/bobmatnyc/claude-mpm-agents/agents/engineer/backend/python-engineer.md
|
|
85
|
+
Root: /cache/bobmatnyc/claude-mpm-agents/agents
|
|
86
|
+
Output: engineer/backend/python-engineer
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
file_path: Absolute path to agent Markdown file
|
|
90
|
+
|
|
91
|
+
Returns:
|
|
92
|
+
Hierarchical agent ID with forward slashes
|
|
93
|
+
"""
|
|
94
|
+
try:
|
|
95
|
+
# Calculate relative to /agents/ subdirectory (Bug #4 fix)
|
|
96
|
+
agents_dir = self.remote_agents_dir / "agents"
|
|
97
|
+
relative_path = file_path.relative_to(agents_dir)
|
|
98
|
+
|
|
99
|
+
# Remove .md extension and convert to forward slashes
|
|
100
|
+
return str(relative_path.with_suffix("")).replace("\\", "/")
|
|
101
|
+
except ValueError:
|
|
102
|
+
# File is not under agents subdirectory, fall back to filename
|
|
103
|
+
self.logger.warning(
|
|
104
|
+
f"File {file_path} not under agents directory, using filename"
|
|
105
|
+
)
|
|
106
|
+
return file_path.stem
|
|
107
|
+
|
|
108
|
+
def _detect_category_from_path(self, file_path: Path) -> str:
|
|
109
|
+
"""Detect category from file path hierarchy.
|
|
110
|
+
|
|
111
|
+
Extracts category from directory structure. Category is the path
|
|
112
|
+
from agents subdirectory to the file, excluding the filename.
|
|
113
|
+
|
|
114
|
+
Bug #4 Fix: Calculate relative to /agents/ subdirectory, not repository root
|
|
115
|
+
This ensures categories are based on agent organization within /agents/.
|
|
116
|
+
|
|
117
|
+
Example:
|
|
118
|
+
Input: /cache/bobmatnyc/claude-mpm-agents/agents/engineer/backend/python-engineer.md
|
|
119
|
+
Root: /cache/bobmatnyc/claude-mpm-agents/agents
|
|
120
|
+
Output: engineer/backend
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
file_path: Absolute path to agent Markdown file
|
|
124
|
+
|
|
125
|
+
Returns:
|
|
126
|
+
Category path with forward slashes, or "universal" if in root
|
|
127
|
+
"""
|
|
128
|
+
try:
|
|
129
|
+
# Calculate relative to /agents/ subdirectory (Bug #4 fix)
|
|
130
|
+
agents_dir = self.remote_agents_dir / "agents"
|
|
131
|
+
relative_path = file_path.relative_to(agents_dir)
|
|
132
|
+
parts = relative_path.parts[:-1] # Exclude filename
|
|
133
|
+
return "/".join(parts) if parts else "universal"
|
|
134
|
+
except ValueError:
|
|
135
|
+
return "universal"
|
|
136
|
+
|
|
137
|
+
def discover_remote_agents(self) -> List[Dict[str, Any]]:
|
|
138
|
+
"""Discover all remote agents from cache directory.
|
|
139
|
+
|
|
140
|
+
Scans the remote agents directory for *.md files recursively and converts each
|
|
141
|
+
to JSON template format. Skips files that can't be parsed.
|
|
142
|
+
|
|
143
|
+
Bug #4 Fix: Only scan /agents/ subdirectory, not entire repository
|
|
144
|
+
This prevents README.md, CHANGELOG.md, etc. from being treated as agents.
|
|
145
|
+
|
|
146
|
+
Returns:
|
|
147
|
+
List of agent dictionaries in JSON template format
|
|
148
|
+
|
|
149
|
+
Example:
|
|
150
|
+
>>> service = RemoteAgentDiscoveryService(Path("~/.claude-mpm/cache/remote-agents"))
|
|
151
|
+
>>> agents = service.discover_remote_agents()
|
|
152
|
+
>>> len(agents)
|
|
153
|
+
5
|
|
154
|
+
>>> agents[0]['name']
|
|
155
|
+
'Security Scanner Agent'
|
|
156
|
+
"""
|
|
157
|
+
agents = []
|
|
158
|
+
|
|
159
|
+
if not self.remote_agents_dir.exists():
|
|
160
|
+
self.logger.debug(
|
|
161
|
+
f"Remote agents directory does not exist: {self.remote_agents_dir}"
|
|
162
|
+
)
|
|
163
|
+
return agents
|
|
164
|
+
|
|
165
|
+
# Bug #4 Fix: Only scan /agents/ subdirectory, not entire repository
|
|
166
|
+
# This prevents non-agent files (README.md, CHANGELOG.md, etc.) from polluting results
|
|
167
|
+
agents_dir = self.remote_agents_dir / "agents"
|
|
168
|
+
|
|
169
|
+
if not agents_dir.exists():
|
|
170
|
+
self.logger.warning(
|
|
171
|
+
f"Agents subdirectory not found: {agents_dir}. "
|
|
172
|
+
f"Expected agents to be in /agents/ subdirectory."
|
|
173
|
+
)
|
|
174
|
+
return agents
|
|
175
|
+
|
|
176
|
+
# Find all Markdown files recursively in /agents/ subdirectory only
|
|
177
|
+
md_files = list(agents_dir.rglob("*.md"))
|
|
178
|
+
self.logger.debug(f"Found {len(md_files)} Markdown files in {agents_dir}")
|
|
179
|
+
|
|
180
|
+
for md_file in md_files:
|
|
181
|
+
try:
|
|
182
|
+
agent_dict = self._parse_markdown_agent(md_file)
|
|
183
|
+
if agent_dict:
|
|
184
|
+
agents.append(agent_dict)
|
|
185
|
+
self.logger.debug(
|
|
186
|
+
f"Successfully parsed remote agent: {md_file.name}"
|
|
187
|
+
)
|
|
188
|
+
else:
|
|
189
|
+
self.logger.warning(
|
|
190
|
+
f"Failed to parse remote agent (no name found): {md_file.name}"
|
|
191
|
+
)
|
|
192
|
+
except Exception as e:
|
|
193
|
+
self.logger.warning(f"Failed to parse remote agent {md_file.name}: {e}")
|
|
194
|
+
|
|
195
|
+
self.logger.info(
|
|
196
|
+
f"Discovered {len(agents)} remote agents from {self.remote_agents_dir.name}"
|
|
197
|
+
)
|
|
198
|
+
return agents
|
|
199
|
+
|
|
200
|
+
def _parse_markdown_agent(self, md_file: Path) -> Optional[Dict[str, Any]]:
|
|
201
|
+
"""Parse Markdown agent file and convert to JSON template format.
|
|
202
|
+
|
|
203
|
+
Expected Markdown format:
|
|
204
|
+
```markdown
|
|
205
|
+
# Agent Name
|
|
206
|
+
|
|
207
|
+
Description paragraph (first paragraph after heading)
|
|
208
|
+
|
|
209
|
+
## Configuration
|
|
210
|
+
- Model: sonnet
|
|
211
|
+
- Priority: 100
|
|
212
|
+
|
|
213
|
+
## Routing
|
|
214
|
+
- Keywords: keyword1, keyword2
|
|
215
|
+
- Paths: /path1/, /path2/
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Args:
|
|
219
|
+
md_file: Path to Markdown agent file
|
|
220
|
+
|
|
221
|
+
Returns:
|
|
222
|
+
Agent dictionary in JSON template format, or None if parsing fails
|
|
223
|
+
|
|
224
|
+
Error Handling:
|
|
225
|
+
- Returns None if agent name (first heading) is missing
|
|
226
|
+
- Uses defaults for missing sections (model=sonnet, priority=50)
|
|
227
|
+
- Empty routing keywords/paths if Routing section missing
|
|
228
|
+
"""
|
|
229
|
+
try:
|
|
230
|
+
content = md_file.read_text(encoding="utf-8")
|
|
231
|
+
except Exception as e:
|
|
232
|
+
self.logger.error(f"Failed to read file {md_file}: {e}")
|
|
233
|
+
return None
|
|
234
|
+
|
|
235
|
+
# Extract agent name from first heading
|
|
236
|
+
name_match = re.search(r"^#\s+(.+?)$", content, re.MULTILINE)
|
|
237
|
+
if not name_match:
|
|
238
|
+
self.logger.debug(f"No agent name heading found in {md_file.name}")
|
|
239
|
+
return None
|
|
240
|
+
name = name_match.group(1).strip()
|
|
241
|
+
|
|
242
|
+
# Extract description (first paragraph after heading, before next heading)
|
|
243
|
+
desc_match = re.search(
|
|
244
|
+
r"^#.+?\n\n(.+?)(?:\n\n##|\Z)", content, re.DOTALL | re.MULTILINE
|
|
245
|
+
)
|
|
246
|
+
description = desc_match.group(1).strip() if desc_match else ""
|
|
247
|
+
|
|
248
|
+
# Extract model from Configuration section
|
|
249
|
+
model_match = re.search(r"Model:\s*(\w+)", content, re.IGNORECASE)
|
|
250
|
+
model = model_match.group(1) if model_match else "sonnet"
|
|
251
|
+
|
|
252
|
+
# Extract priority from Configuration section
|
|
253
|
+
priority_match = re.search(r"Priority:\s*(\d+)", content, re.IGNORECASE)
|
|
254
|
+
priority = int(priority_match.group(1)) if priority_match else 50
|
|
255
|
+
|
|
256
|
+
# Extract routing keywords
|
|
257
|
+
keywords_match = re.search(r"Keywords:\s*(.+?)(?:\n|$)", content, re.IGNORECASE)
|
|
258
|
+
keywords = []
|
|
259
|
+
if keywords_match:
|
|
260
|
+
keywords = [k.strip() for k in keywords_match.group(1).split(",")]
|
|
261
|
+
|
|
262
|
+
# Extract routing paths
|
|
263
|
+
paths_match = re.search(r"Paths:\s*(.+?)(?:\n|$)", content, re.IGNORECASE)
|
|
264
|
+
paths = []
|
|
265
|
+
if paths_match:
|
|
266
|
+
paths = [p.strip() for p in paths_match.group(1).split(",")]
|
|
267
|
+
|
|
268
|
+
# Get version (SHA-256 hash) from cache metadata
|
|
269
|
+
version = self._get_agent_version(md_file)
|
|
270
|
+
|
|
271
|
+
# Bug #3 fix: Generate hierarchical agent_id from file path
|
|
272
|
+
# This preserves directory structure for category filtering and preset matching
|
|
273
|
+
agent_id = self._generate_hierarchical_id(md_file)
|
|
274
|
+
|
|
275
|
+
# Bug #1 fix: Detect category from directory path
|
|
276
|
+
category = self._detect_category_from_path(md_file)
|
|
277
|
+
|
|
278
|
+
# Convert to JSON template format and return
|
|
279
|
+
# IMPORTANT: Include 'path' field for compatibility with deployment validation (ticket 1M-480)
|
|
280
|
+
# Git-sourced agents must have 'path' field to match structure from AgentDiscoveryService
|
|
281
|
+
return {
|
|
282
|
+
"agent_id": agent_id,
|
|
283
|
+
"metadata": {
|
|
284
|
+
"name": name,
|
|
285
|
+
"description": description,
|
|
286
|
+
"version": version,
|
|
287
|
+
"author": "remote", # Mark as remote agent
|
|
288
|
+
"category": category, # Use detected category from path
|
|
289
|
+
},
|
|
290
|
+
"model": model,
|
|
291
|
+
"source": "remote", # Mark as remote agent
|
|
292
|
+
"source_file": str(md_file),
|
|
293
|
+
"path": str(
|
|
294
|
+
md_file
|
|
295
|
+
), # Add 'path' field for deployment compatibility (1M-480)
|
|
296
|
+
"file_path": str(md_file), # Keep for backward compatibility
|
|
297
|
+
"version": version, # Include at root level for version comparison
|
|
298
|
+
"category": category, # Add category at root level for filtering
|
|
299
|
+
"routing": {"keywords": keywords, "paths": paths, "priority": priority},
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
def _get_agent_version(self, md_file: Path) -> str:
|
|
303
|
+
"""Get version (SHA-256 hash) from cache metadata.
|
|
304
|
+
|
|
305
|
+
Looks for corresponding .meta.json file in cache directory that contains
|
|
306
|
+
the SHA-256 hash of the agent content.
|
|
307
|
+
|
|
308
|
+
Args:
|
|
309
|
+
md_file: Path to Markdown agent file
|
|
310
|
+
|
|
311
|
+
Returns:
|
|
312
|
+
SHA-256 hash from metadata, or 'unknown' if not found
|
|
313
|
+
|
|
314
|
+
Example metadata file:
|
|
315
|
+
{
|
|
316
|
+
"content_hash": "abc123...",
|
|
317
|
+
"etag": "W/\"abc123\"",
|
|
318
|
+
"last_modified": "2025-11-30T10:00:00Z"
|
|
319
|
+
}
|
|
320
|
+
"""
|
|
321
|
+
# Look for .meta.json file
|
|
322
|
+
meta_file = md_file.with_suffix(".md.meta.json")
|
|
323
|
+
|
|
324
|
+
if not meta_file.exists():
|
|
325
|
+
self.logger.debug(f"No metadata file found for {md_file.name}")
|
|
326
|
+
return "unknown"
|
|
327
|
+
|
|
328
|
+
try:
|
|
329
|
+
meta_data = json.loads(meta_file.read_text(encoding="utf-8"))
|
|
330
|
+
content_hash = meta_data.get("content_hash", "unknown")
|
|
331
|
+
self.logger.debug(
|
|
332
|
+
f"Retrieved version {content_hash[:8]}... for {md_file.name}"
|
|
333
|
+
)
|
|
334
|
+
return content_hash
|
|
335
|
+
except Exception as e:
|
|
336
|
+
self.logger.warning(f"Failed to read metadata for {md_file.name}: {e}")
|
|
337
|
+
return "unknown"
|
|
338
|
+
|
|
339
|
+
def get_remote_agent_metadata(
|
|
340
|
+
self, agent_name: str
|
|
341
|
+
) -> Optional[RemoteAgentMetadata]:
|
|
342
|
+
"""Get metadata for a specific remote agent.
|
|
343
|
+
|
|
344
|
+
Args:
|
|
345
|
+
agent_name: Name of the agent to retrieve
|
|
346
|
+
|
|
347
|
+
Returns:
|
|
348
|
+
RemoteAgentMetadata if found, None otherwise
|
|
349
|
+
"""
|
|
350
|
+
for md_file in self.remote_agents_dir.glob("*.md"):
|
|
351
|
+
agent_dict = self._parse_markdown_agent(md_file)
|
|
352
|
+
if agent_dict and agent_dict["metadata"]["name"] == agent_name:
|
|
353
|
+
return RemoteAgentMetadata(
|
|
354
|
+
name=agent_dict["metadata"]["name"],
|
|
355
|
+
description=agent_dict["metadata"]["description"],
|
|
356
|
+
model=agent_dict["model"],
|
|
357
|
+
routing_keywords=agent_dict["routing"]["keywords"],
|
|
358
|
+
routing_paths=agent_dict["routing"]["paths"],
|
|
359
|
+
routing_priority=agent_dict["routing"]["priority"],
|
|
360
|
+
source_file=Path(agent_dict["source_file"]),
|
|
361
|
+
version=agent_dict["version"],
|
|
362
|
+
)
|
|
363
|
+
return None
|
|
@@ -200,8 +200,8 @@ class SingleAgentDeployer:
|
|
|
200
200
|
- Enables selective agent management in projects
|
|
201
201
|
"""
|
|
202
202
|
try:
|
|
203
|
-
# Find the template file
|
|
204
|
-
template_file = templates_dir / f"{agent_name}.
|
|
203
|
+
# Find the template file (templates migrated to .md in v4.26.0+)
|
|
204
|
+
template_file = templates_dir / f"{agent_name}.md"
|
|
205
205
|
if not template_file.exists():
|
|
206
206
|
self.logger.error(f"Agent template not found: {agent_name}")
|
|
207
207
|
return False
|