claude-mpm 4.24.0__py3-none-any.whl → 5.4.41__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of claude-mpm might be problematic. Click here for more details.
- claude_mpm/VERSION +1 -1
- claude_mpm/__init__.py +4 -0
- claude_mpm/agents/BASE_AGENT.md +164 -0
- claude_mpm/agents/{OUTPUT_STYLE.md → CLAUDE_MPM_OUTPUT_STYLE.md} +3 -48
- claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +2002 -0
- claude_mpm/agents/MEMORY.md +1 -1
- claude_mpm/agents/PM_INSTRUCTIONS.md +735 -925
- claude_mpm/agents/WORKFLOW.md +5 -254
- claude_mpm/agents/__init__.py +6 -0
- claude_mpm/agents/agent_loader.py +14 -48
- claude_mpm/agents/base_agent.json +7 -4
- claude_mpm/agents/frontmatter_validator.py +71 -3
- claude_mpm/agents/templates/circuit-breakers.md +1391 -0
- claude_mpm/agents/templates/context-management-examples.md +544 -0
- claude_mpm/agents/templates/{pm_red_flags.md → pm-red-flags.md} +48 -0
- claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
- claude_mpm/agents/templates/research-gate-examples.md +669 -0
- claude_mpm/agents/templates/structured-questions-examples.md +615 -0
- claude_mpm/agents/templates/ticket-completeness-examples.md +139 -0
- claude_mpm/agents/templates/ticketing-examples.md +277 -0
- claude_mpm/cli/__init__.py +37 -2
- claude_mpm/cli/__main__.py +4 -0
- claude_mpm/cli/chrome_devtools_installer.py +175 -0
- claude_mpm/cli/commands/__init__.py +2 -0
- claude_mpm/cli/commands/agent_source.py +774 -0
- claude_mpm/cli/commands/agent_state_manager.py +180 -31
- claude_mpm/cli/commands/agents.py +1116 -55
- claude_mpm/cli/commands/agents_cleanup.py +210 -0
- claude_mpm/cli/commands/agents_discover.py +338 -0
- claude_mpm/cli/commands/aggregate.py +1 -1
- claude_mpm/cli/commands/analyze.py +3 -3
- claude_mpm/cli/commands/auto_configure.py +725 -242
- claude_mpm/cli/commands/config.py +95 -6
- claude_mpm/cli/commands/configure.py +1875 -46
- claude_mpm/cli/commands/configure_agent_display.py +29 -10
- claude_mpm/cli/commands/configure_navigation.py +63 -46
- claude_mpm/cli/commands/debug.py +12 -12
- claude_mpm/cli/commands/doctor.py +10 -2
- claude_mpm/cli/commands/hook_errors.py +277 -0
- claude_mpm/cli/commands/local_deploy.py +1 -4
- claude_mpm/cli/commands/mcp_install_commands.py +1 -1
- claude_mpm/cli/commands/mpm_init/core.py +229 -2
- claude_mpm/cli/commands/mpm_init/git_activity.py +10 -10
- claude_mpm/cli/commands/mpm_init/knowledge_extractor.py +481 -0
- claude_mpm/cli/commands/mpm_init/prompts.py +286 -6
- claude_mpm/cli/commands/postmortem.py +401 -0
- claude_mpm/cli/commands/profile.py +277 -0
- claude_mpm/cli/commands/run.py +123 -165
- claude_mpm/cli/commands/skill_source.py +694 -0
- claude_mpm/cli/commands/skills.py +782 -20
- claude_mpm/cli/commands/summarize.py +413 -0
- claude_mpm/cli/executor.py +96 -3
- claude_mpm/cli/interactive/agent_wizard.py +1030 -45
- claude_mpm/cli/parsers/agent_source_parser.py +171 -0
- claude_mpm/cli/parsers/agents_parser.py +307 -10
- claude_mpm/cli/parsers/auto_configure_parser.py +13 -138
- claude_mpm/cli/parsers/base_parser.py +65 -0
- claude_mpm/cli/parsers/config_parser.py +162 -39
- claude_mpm/cli/parsers/profile_parser.py +148 -0
- claude_mpm/cli/parsers/skill_source_parser.py +169 -0
- claude_mpm/cli/parsers/skills_parser.py +146 -0
- claude_mpm/cli/parsers/source_parser.py +138 -0
- claude_mpm/cli/startup.py +1280 -118
- claude_mpm/cli/startup_display.py +480 -0
- claude_mpm/cli/utils.py +1 -1
- claude_mpm/cli_module/commands.py +1 -1
- claude_mpm/commands/mpm-config.md +21 -134
- claude_mpm/commands/mpm-doctor.md +16 -20
- claude_mpm/commands/mpm-help.md +13 -283
- claude_mpm/commands/mpm-init.md +88 -489
- claude_mpm/commands/mpm-monitor.md +23 -401
- claude_mpm/commands/mpm-organize.md +72 -247
- claude_mpm/commands/mpm-postmortem.md +21 -0
- claude_mpm/commands/mpm-session-resume.md +30 -0
- claude_mpm/commands/mpm-status.md +13 -68
- claude_mpm/commands/mpm-ticket-view.md +109 -0
- claude_mpm/commands/mpm-version.md +13 -106
- claude_mpm/commands/mpm.md +10 -0
- claude_mpm/config/agent_presets.py +488 -0
- claude_mpm/config/agent_sources.py +352 -0
- claude_mpm/config/skill_presets.py +392 -0
- claude_mpm/config/skill_sources.py +590 -0
- claude_mpm/constants.py +13 -0
- claude_mpm/core/claude_runner.py +5 -34
- claude_mpm/core/config.py +15 -1
- claude_mpm/core/constants.py +1 -1
- claude_mpm/core/framework/__init__.py +3 -16
- claude_mpm/core/framework/formatters/content_formatter.py +3 -13
- claude_mpm/core/framework/loaders/agent_loader.py +8 -5
- claude_mpm/core/framework/loaders/file_loader.py +54 -101
- claude_mpm/core/framework/loaders/instruction_loader.py +66 -5
- claude_mpm/core/framework_loader.py +4 -2
- claude_mpm/core/hook_error_memory.py +381 -0
- claude_mpm/core/hook_manager.py +41 -2
- claude_mpm/core/interactive_session.py +91 -10
- claude_mpm/core/logger.py +16 -1
- claude_mpm/core/oneshot_session.py +71 -8
- claude_mpm/core/optimized_startup.py +59 -0
- claude_mpm/core/output_style_manager.py +173 -43
- claude_mpm/core/protocols/__init__.py +23 -0
- claude_mpm/core/protocols/runner_protocol.py +103 -0
- claude_mpm/core/protocols/session_protocol.py +131 -0
- claude_mpm/core/shared/config_loader.py +1 -1
- claude_mpm/core/shared/singleton_manager.py +11 -4
- claude_mpm/core/socketio_pool.py +3 -3
- claude_mpm/core/system_context.py +38 -0
- claude_mpm/core/unified_agent_registry.py +134 -16
- claude_mpm/core/unified_config.py +22 -0
- claude_mpm/dashboard/static/svelte-build/_app/env.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.B_FtCwCQ.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.Cl_eSA4x.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BgChzWQ1.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIXEwuWe.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWc5urbQ.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DMkZpdF2.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DjhvlsAc.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/N4qtv3Hx.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/uj46x2Wr.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.DTL5mJO-.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.DzuEhzqh.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/0.CAGBuiOw.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DFLC8jdE.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.DPvEihJJ.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -0
- claude_mpm/dashboard/static/svelte-build/favicon.svg +7 -0
- claude_mpm/dashboard/static/svelte-build/index.html +36 -0
- claude_mpm/experimental/cli_enhancements.py +1 -5
- claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/correlation_manager.py +60 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +214 -79
- claude_mpm/hooks/claude_hooks/hook_handler.py +155 -1
- claude_mpm/hooks/claude_hooks/installer.py +33 -10
- claude_mpm/hooks/claude_hooks/memory_integration.py +28 -0
- claude_mpm/hooks/claude_hooks/response_tracking.py +2 -3
- claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/connection_manager.py +30 -6
- claude_mpm/hooks/failure_learning/__init__.py +2 -8
- claude_mpm/hooks/failure_learning/failure_detection_hook.py +1 -6
- claude_mpm/hooks/failure_learning/fix_detection_hook.py +1 -6
- claude_mpm/hooks/failure_learning/learning_extraction_hook.py +1 -6
- claude_mpm/hooks/kuzu_response_hook.py +1 -5
- claude_mpm/hooks/memory_integration_hook.py +46 -1
- claude_mpm/init.py +63 -19
- claude_mpm/models/agent_definition.py +7 -0
- claude_mpm/models/git_repository.py +198 -0
- claude_mpm/scripts/claude-hook-handler.sh +60 -20
- claude_mpm/scripts/launch_monitor.py +93 -13
- claude_mpm/scripts/start_activity_logging.py +3 -1
- claude_mpm/services/agents/agent_builder.py +48 -12
- claude_mpm/services/agents/agent_preset_service.py +238 -0
- claude_mpm/services/agents/agent_recommendation_service.py +278 -0
- claude_mpm/services/agents/agent_review_service.py +280 -0
- claude_mpm/services/agents/agent_selection_service.py +484 -0
- claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
- claude_mpm/services/agents/cache_git_manager.py +621 -0
- claude_mpm/services/agents/deployment/agent_deployment.py +148 -2
- claude_mpm/services/agents/deployment/agent_discovery_service.py +104 -73
- claude_mpm/services/agents/deployment/agent_format_converter.py +1 -1
- claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +1 -5
- claude_mpm/services/agents/deployment/agent_metrics_collector.py +3 -3
- claude_mpm/services/agents/deployment/agent_restore_handler.py +1 -4
- claude_mpm/services/agents/deployment/agent_template_builder.py +238 -15
- claude_mpm/services/agents/deployment/agents_directory_resolver.py +101 -15
- claude_mpm/services/agents/deployment/async_agent_deployment.py +2 -1
- claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -3
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +422 -31
- claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +2 -2
- claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +1 -4
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +841 -0
- claude_mpm/services/agents/deployment/single_agent_deployer.py +2 -2
- claude_mpm/services/agents/deployment/system_instructions_deployer.py +168 -46
- claude_mpm/services/agents/deployment/validation/deployment_validator.py +2 -2
- claude_mpm/services/agents/git_source_manager.py +663 -0
- claude_mpm/services/agents/loading/base_agent_manager.py +1 -13
- claude_mpm/services/agents/loading/framework_agent_loader.py +9 -12
- claude_mpm/services/agents/local_template_manager.py +50 -10
- claude_mpm/services/agents/recommender.py +5 -3
- claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
- claude_mpm/services/agents/sources/__init__.py +13 -0
- claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
- claude_mpm/services/agents/sources/git_source_sync_service.py +1094 -0
- claude_mpm/services/agents/startup_sync.py +259 -0
- claude_mpm/services/agents/toolchain_detector.py +478 -0
- claude_mpm/services/analysis/__init__.py +35 -0
- claude_mpm/services/analysis/clone_detector.py +1030 -0
- claude_mpm/services/analysis/postmortem_reporter.py +474 -0
- claude_mpm/services/analysis/postmortem_service.py +765 -0
- claude_mpm/services/cli/session_pause_manager.py +1 -1
- claude_mpm/services/command_deployment_service.py +271 -6
- claude_mpm/services/core/base.py +7 -2
- claude_mpm/services/core/interfaces/__init__.py +1 -3
- claude_mpm/services/core/interfaces/health.py +1 -4
- claude_mpm/services/core/models/__init__.py +2 -11
- claude_mpm/services/diagnostics/checks/__init__.py +4 -0
- claude_mpm/services/diagnostics/checks/agent_check.py +2 -4
- claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
- claude_mpm/services/diagnostics/checks/instructions_check.py +1 -2
- claude_mpm/services/diagnostics/checks/mcp_check.py +0 -1
- claude_mpm/services/diagnostics/checks/mcp_services_check.py +7 -15
- claude_mpm/services/diagnostics/checks/monitor_check.py +0 -1
- claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
- claude_mpm/services/diagnostics/diagnostic_runner.py +9 -0
- claude_mpm/services/diagnostics/doctor_reporter.py +40 -10
- claude_mpm/services/event_bus/config.py +3 -1
- claude_mpm/services/event_bus/direct_relay.py +3 -3
- claude_mpm/services/events/consumers/logging.py +1 -2
- claude_mpm/services/git/__init__.py +21 -0
- claude_mpm/services/git/git_operations_service.py +579 -0
- claude_mpm/services/github/__init__.py +21 -0
- claude_mpm/services/github/github_cli_service.py +397 -0
- claude_mpm/services/infrastructure/monitoring/__init__.py +1 -5
- claude_mpm/services/infrastructure/monitoring/aggregator.py +1 -6
- claude_mpm/services/instructions/__init__.py +9 -0
- claude_mpm/services/instructions/instruction_cache_service.py +374 -0
- claude_mpm/services/local_ops/__init__.py +3 -13
- claude_mpm/services/local_ops/health_checks/__init__.py +1 -3
- claude_mpm/services/local_ops/health_manager.py +1 -4
- claude_mpm/services/local_ops/resource_monitor.py +1 -1
- claude_mpm/services/mcp_config_manager.py +75 -145
- claude_mpm/services/mcp_service_verifier.py +6 -3
- claude_mpm/services/model/model_router.py +1 -2
- claude_mpm/services/monitor/daemon.py +38 -11
- claude_mpm/services/monitor/daemon_manager.py +134 -21
- claude_mpm/services/monitor/management/lifecycle.py +8 -1
- claude_mpm/services/monitor/server.py +700 -24
- claude_mpm/services/pm_skills_deployer.py +676 -0
- claude_mpm/services/port_manager.py +1 -1
- claude_mpm/services/pr/__init__.py +14 -0
- claude_mpm/services/pr/pr_template_service.py +329 -0
- claude_mpm/services/profile_manager.py +331 -0
- claude_mpm/services/project/documentation_manager.py +2 -1
- claude_mpm/services/project/project_organizer.py +4 -0
- claude_mpm/services/project/toolchain_analyzer.py +3 -1
- claude_mpm/services/runner_configuration_service.py +16 -3
- claude_mpm/services/self_upgrade_service.py +120 -12
- claude_mpm/services/session_management_service.py +16 -4
- claude_mpm/services/skills/__init__.py +21 -0
- claude_mpm/services/skills/git_skill_source_manager.py +1297 -0
- claude_mpm/services/skills/selective_skill_deployer.py +704 -0
- claude_mpm/services/skills/skill_discovery_service.py +568 -0
- claude_mpm/services/skills/skill_to_agent_mapper.py +406 -0
- claude_mpm/services/skills_config.py +547 -0
- claude_mpm/services/skills_deployer.py +1072 -0
- claude_mpm/services/socketio/dashboard_server.py +1 -0
- claude_mpm/services/socketio/event_normalizer.py +51 -6
- claude_mpm/services/socketio/handlers/connection.py +1 -1
- claude_mpm/services/socketio/handlers/git.py +1 -1
- claude_mpm/services/socketio/server/core.py +387 -112
- claude_mpm/services/socketio/server/main.py +1 -3
- claude_mpm/services/system_instructions_service.py +1 -3
- claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +0 -3
- claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +0 -1
- claude_mpm/services/unified/deployment_strategies/vercel.py +1 -5
- claude_mpm/services/unified/unified_deployment.py +1 -5
- claude_mpm/services/version_control/conflict_resolution.py +6 -4
- claude_mpm/services/version_control/git_operations.py +103 -0
- claude_mpm/services/visualization/__init__.py +1 -5
- claude_mpm/services/visualization/mermaid_generator.py +2 -3
- claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +2 -2
- claude_mpm/skills/skill_manager.py +92 -3
- claude_mpm/skills/skills_registry.py +0 -1
- claude_mpm/templates/questions/__init__.py +38 -0
- claude_mpm/templates/questions/base.py +193 -0
- claude_mpm/templates/questions/pr_strategy.py +311 -0
- claude_mpm/templates/questions/project_init.py +385 -0
- claude_mpm/templates/questions/ticket_mgmt.py +394 -0
- claude_mpm/tools/__main__.py +8 -8
- claude_mpm/utils/agent_dependency_loader.py +91 -12
- claude_mpm/utils/agent_filters.py +261 -0
- claude_mpm/utils/dependency_cache.py +3 -1
- claude_mpm/utils/gitignore.py +244 -0
- claude_mpm/utils/migration.py +372 -0
- claude_mpm/utils/progress.py +387 -0
- claude_mpm/utils/robust_installer.py +49 -7
- claude_mpm/utils/structured_questions.py +619 -0
- {claude_mpm-4.24.0.dist-info → claude_mpm-5.4.41.dist-info}/METADATA +445 -122
- {claude_mpm-4.24.0.dist-info → claude_mpm-5.4.41.dist-info}/RECORD +298 -503
- claude_mpm-5.4.41.dist-info/entry_points.txt +5 -0
- claude_mpm-5.4.41.dist-info/licenses/LICENSE +94 -0
- claude_mpm-5.4.41.dist-info/licenses/LICENSE-FAQ.md +153 -0
- claude_mpm/agents/BASE_AGENT_TEMPLATE.md +0 -292
- claude_mpm/agents/BASE_DOCUMENTATION.md +0 -53
- claude_mpm/agents/BASE_OPS.md +0 -219
- claude_mpm/agents/BASE_PM.md +0 -468
- claude_mpm/agents/BASE_PROMPT_ENGINEER.md +0 -787
- claude_mpm/agents/BASE_QA.md +0 -167
- claude_mpm/agents/BASE_RESEARCH.md +0 -53
- claude_mpm/agents/base_agent_loader.py +0 -626
- claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -17
- claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +0 -3
- claude_mpm/agents/templates/agent-manager.json +0 -273
- claude_mpm/agents/templates/agentic-coder-optimizer.json +0 -248
- claude_mpm/agents/templates/api_qa.json +0 -183
- claude_mpm/agents/templates/circuit_breakers.md +0 -638
- claude_mpm/agents/templates/clerk-ops.json +0 -235
- claude_mpm/agents/templates/code_analyzer.json +0 -101
- claude_mpm/agents/templates/content-agent.json +0 -358
- claude_mpm/agents/templates/dart_engineer.json +0 -307
- claude_mpm/agents/templates/data_engineer.json +0 -225
- claude_mpm/agents/templates/documentation.json +0 -238
- claude_mpm/agents/templates/engineer.json +0 -210
- claude_mpm/agents/templates/gcp_ops_agent.json +0 -253
- claude_mpm/agents/templates/golang_engineer.json +0 -270
- claude_mpm/agents/templates/imagemagick.json +0 -264
- claude_mpm/agents/templates/java_engineer.json +0 -346
- claude_mpm/agents/templates/javascript_engineer_agent.json +0 -380
- claude_mpm/agents/templates/local_ops_agent.json +0 -1840
- claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +0 -39
- claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +0 -400
- claude_mpm/agents/templates/memory_manager.json +0 -158
- claude_mpm/agents/templates/nextjs_engineer.json +0 -285
- claude_mpm/agents/templates/ops.json +0 -185
- claude_mpm/agents/templates/php-engineer.json +0 -287
- claude_mpm/agents/templates/product_owner.json +0 -338
- claude_mpm/agents/templates/project_organizer.json +0 -144
- claude_mpm/agents/templates/prompt-engineer.json +0 -737
- claude_mpm/agents/templates/python_engineer.json +0 -387
- claude_mpm/agents/templates/qa.json +0 -243
- claude_mpm/agents/templates/react_engineer.json +0 -239
- claude_mpm/agents/templates/refactoring_engineer.json +0 -276
- claude_mpm/agents/templates/research.json +0 -188
- claude_mpm/agents/templates/ruby-engineer.json +0 -280
- claude_mpm/agents/templates/rust_engineer.json +0 -275
- claude_mpm/agents/templates/security.json +0 -202
- claude_mpm/agents/templates/svelte-engineer.json +0 -225
- claude_mpm/agents/templates/tauri_engineer.json +0 -274
- claude_mpm/agents/templates/ticketing.json +0 -178
- claude_mpm/agents/templates/typescript_engineer.json +0 -285
- claude_mpm/agents/templates/vercel_ops_agent.json +0 -412
- claude_mpm/agents/templates/version_control.json +0 -159
- claude_mpm/agents/templates/web_qa.json +0 -400
- claude_mpm/agents/templates/web_ui.json +0 -189
- claude_mpm/cli/commands/agents_detect.py +0 -380
- claude_mpm/cli/commands/agents_recommend.py +0 -309
- claude_mpm/cli/ticket_cli.py +0 -35
- claude_mpm/commands/mpm-agents-detect.md +0 -168
- claude_mpm/commands/mpm-agents-recommend.md +0 -214
- claude_mpm/commands/mpm-agents.md +0 -122
- claude_mpm/commands/mpm-auto-configure.md +0 -269
- claude_mpm/commands/mpm-resume.md +0 -372
- claude_mpm/commands/mpm-tickets.md +0 -151
- claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
- claude_mpm/dashboard/analysis_runner.py +0 -455
- claude_mpm/dashboard/index.html +0 -13
- claude_mpm/dashboard/open_dashboard.py +0 -66
- claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +0 -188
- claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +0 -156
- claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +0 -38
- claude_mpm/dashboard/react/components/shared/FilterBar.module.css +0 -92
- claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +0 -248
- claude_mpm/dashboard/static/archive/activity_dashboard_test.html +0 -61
- claude_mpm/dashboard/static/archive/test_activity_connection.html +0 -179
- claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +0 -68
- claude_mpm/dashboard/static/archive/test_dashboard.html +0 -409
- claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +0 -519
- claude_mpm/dashboard/static/archive/test_dashboard_verification.html +0 -181
- claude_mpm/dashboard/static/archive/test_file_data.html +0 -315
- claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +0 -243
- claude_mpm/dashboard/static/archive/test_file_tree_fix.html +0 -234
- claude_mpm/dashboard/static/archive/test_file_tree_rename.html +0 -117
- claude_mpm/dashboard/static/archive/test_file_tree_tab.html +0 -115
- claude_mpm/dashboard/static/archive/test_file_viewer.html +0 -224
- claude_mpm/dashboard/static/archive/test_final_activity.html +0 -220
- claude_mpm/dashboard/static/archive/test_tab_fix.html +0 -139
- claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +0 -1
- claude_mpm/dashboard/static/built/components/activity-tree.js +0 -2
- claude_mpm/dashboard/static/built/components/agent-hierarchy.js +0 -777
- claude_mpm/dashboard/static/built/components/agent-inference.js +0 -2
- claude_mpm/dashboard/static/built/components/build-tracker.js +0 -333
- claude_mpm/dashboard/static/built/components/code-simple.js +0 -857
- claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +0 -353
- claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +0 -235
- claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +0 -409
- claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +0 -435
- claude_mpm/dashboard/static/built/components/code-tree.js +0 -2
- claude_mpm/dashboard/static/built/components/code-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/connection-debug.js +0 -654
- claude_mpm/dashboard/static/built/components/diff-viewer.js +0 -891
- claude_mpm/dashboard/static/built/components/event-processor.js +0 -2
- claude_mpm/dashboard/static/built/components/event-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/export-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/file-change-tracker.js +0 -443
- claude_mpm/dashboard/static/built/components/file-change-viewer.js +0 -690
- claude_mpm/dashboard/static/built/components/file-tool-tracker.js +0 -2
- claude_mpm/dashboard/static/built/components/file-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/hud-library-loader.js +0 -2
- claude_mpm/dashboard/static/built/components/hud-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/hud-visualizer.js +0 -2
- claude_mpm/dashboard/static/built/components/module-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/nav-bar.js +0 -145
- claude_mpm/dashboard/static/built/components/page-structure.js +0 -429
- claude_mpm/dashboard/static/built/components/session-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/socket-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/ui-state-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/unified-data-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/working-directory.js +0 -2
- claude_mpm/dashboard/static/built/connection-manager.js +0 -536
- claude_mpm/dashboard/static/built/dashboard.js +0 -2
- claude_mpm/dashboard/static/built/extension-error-handler.js +0 -164
- claude_mpm/dashboard/static/built/react/events.js +0 -30
- claude_mpm/dashboard/static/built/shared/dom-helpers.js +0 -396
- claude_mpm/dashboard/static/built/shared/event-bus.js +0 -330
- claude_mpm/dashboard/static/built/shared/event-filter-service.js +0 -540
- claude_mpm/dashboard/static/built/shared/logger.js +0 -385
- claude_mpm/dashboard/static/built/shared/page-structure.js +0 -249
- claude_mpm/dashboard/static/built/shared/tooltip-service.js +0 -253
- claude_mpm/dashboard/static/built/socket-client.js +0 -2
- claude_mpm/dashboard/static/built/tab-isolation-fix.js +0 -185
- claude_mpm/dashboard/static/css/activity.css +0 -1958
- claude_mpm/dashboard/static/css/connection-status.css +0 -370
- claude_mpm/dashboard/static/css/dashboard.css +0 -4701
- claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +0 -1
- claude_mpm/dashboard/static/dist/components/activity-tree.js +0 -2
- claude_mpm/dashboard/static/dist/components/agent-inference.js +0 -2
- claude_mpm/dashboard/static/dist/components/code-tree.js +0 -2
- claude_mpm/dashboard/static/dist/components/code-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/event-processor.js +0 -2
- claude_mpm/dashboard/static/dist/components/event-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/export-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +0 -2
- claude_mpm/dashboard/static/dist/components/file-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-library-loader.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-visualizer.js +0 -2
- claude_mpm/dashboard/static/dist/components/module-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/session-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/socket-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/ui-state-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/working-directory.js +0 -2
- claude_mpm/dashboard/static/dist/dashboard.js +0 -2
- claude_mpm/dashboard/static/dist/react/events.js +0 -30
- claude_mpm/dashboard/static/dist/socket-client.js +0 -2
- claude_mpm/dashboard/static/events.html +0 -607
- claude_mpm/dashboard/static/index.html +0 -635
- claude_mpm/dashboard/static/js/components/activity-tree.js +0 -1871
- claude_mpm/dashboard/static/js/components/agent-hierarchy.js +0 -777
- claude_mpm/dashboard/static/js/components/agent-inference.js +0 -956
- claude_mpm/dashboard/static/js/components/build-tracker.js +0 -333
- claude_mpm/dashboard/static/js/components/code-simple.js +0 -857
- claude_mpm/dashboard/static/js/components/connection-debug.js +0 -654
- claude_mpm/dashboard/static/js/components/diff-viewer.js +0 -891
- claude_mpm/dashboard/static/js/components/event-processor.js +0 -542
- claude_mpm/dashboard/static/js/components/event-viewer.js +0 -1155
- claude_mpm/dashboard/static/js/components/export-manager.js +0 -368
- claude_mpm/dashboard/static/js/components/file-change-tracker.js +0 -443
- claude_mpm/dashboard/static/js/components/file-change-viewer.js +0 -690
- claude_mpm/dashboard/static/js/components/file-tool-tracker.js +0 -724
- claude_mpm/dashboard/static/js/components/file-viewer.js +0 -580
- claude_mpm/dashboard/static/js/components/hud-library-loader.js +0 -211
- claude_mpm/dashboard/static/js/components/hud-manager.js +0 -671
- claude_mpm/dashboard/static/js/components/hud-visualizer.js +0 -1718
- claude_mpm/dashboard/static/js/components/module-viewer.js +0 -2764
- claude_mpm/dashboard/static/js/components/session-manager.js +0 -579
- claude_mpm/dashboard/static/js/components/socket-manager.js +0 -368
- claude_mpm/dashboard/static/js/components/ui-state-manager.js +0 -749
- claude_mpm/dashboard/static/js/components/unified-data-viewer.js +0 -1824
- claude_mpm/dashboard/static/js/components/working-directory.js +0 -920
- claude_mpm/dashboard/static/js/connection-manager.js +0 -536
- claude_mpm/dashboard/static/js/dashboard.js +0 -1896
- claude_mpm/dashboard/static/js/extension-error-handler.js +0 -164
- claude_mpm/dashboard/static/js/shared/dom-helpers.js +0 -396
- claude_mpm/dashboard/static/js/shared/event-bus.js +0 -330
- claude_mpm/dashboard/static/js/shared/logger.js +0 -385
- claude_mpm/dashboard/static/js/shared/tooltip-service.js +0 -253
- claude_mpm/dashboard/static/js/socket-client.js +0 -1457
- claude_mpm/dashboard/static/js/stores/dashboard-store.js +0 -562
- claude_mpm/dashboard/static/js/tab-isolation-fix.js +0 -185
- claude_mpm/dashboard/static/legacy/activity.html +0 -736
- claude_mpm/dashboard/static/legacy/agents.html +0 -786
- claude_mpm/dashboard/static/legacy/files.html +0 -747
- claude_mpm/dashboard/static/legacy/tools.html +0 -831
- claude_mpm/dashboard/static/monitors.html +0 -431
- claude_mpm/dashboard/static/production/events.html +0 -659
- claude_mpm/dashboard/static/production/main.html +0 -698
- claude_mpm/dashboard/static/production/monitors.html +0 -483
- claude_mpm/dashboard/static/socket.io.min.js +0 -7
- claude_mpm/dashboard/static/socket.io.v4.8.1.backup.js +0 -7
- claude_mpm/dashboard/static/test-archive/dashboard.html +0 -635
- claude_mpm/dashboard/static/test-archive/debug-events.html +0 -147
- claude_mpm/dashboard/static/test-archive/test-navigation.html +0 -256
- claude_mpm/dashboard/static/test-archive/test-react-exports.html +0 -180
- claude_mpm/dashboard/static/test-archive/test_debug.html +0 -25
- claude_mpm/dashboard/templates/code_simple.html +0 -153
- claude_mpm/dashboard/templates/index.html +0 -606
- claude_mpm/dashboard/test_dashboard.html +0 -372
- claude_mpm/scripts/mcp_server.py +0 -75
- claude_mpm/scripts/mcp_wrapper.py +0 -39
- claude_mpm/services/mcp_gateway/__init__.py +0 -159
- claude_mpm/services/mcp_gateway/auto_configure.py +0 -369
- claude_mpm/services/mcp_gateway/config/__init__.py +0 -17
- claude_mpm/services/mcp_gateway/config/config_loader.py +0 -296
- claude_mpm/services/mcp_gateway/config/config_schema.py +0 -243
- claude_mpm/services/mcp_gateway/config/configuration.py +0 -429
- claude_mpm/services/mcp_gateway/core/__init__.py +0 -43
- claude_mpm/services/mcp_gateway/core/base.py +0 -312
- claude_mpm/services/mcp_gateway/core/exceptions.py +0 -253
- claude_mpm/services/mcp_gateway/core/interfaces.py +0 -443
- claude_mpm/services/mcp_gateway/core/process_pool.py +0 -971
- claude_mpm/services/mcp_gateway/core/singleton_manager.py +0 -315
- claude_mpm/services/mcp_gateway/core/startup_verification.py +0 -316
- claude_mpm/services/mcp_gateway/main.py +0 -589
- claude_mpm/services/mcp_gateway/registry/__init__.py +0 -12
- claude_mpm/services/mcp_gateway/registry/service_registry.py +0 -412
- claude_mpm/services/mcp_gateway/registry/tool_registry.py +0 -489
- claude_mpm/services/mcp_gateway/server/__init__.py +0 -15
- claude_mpm/services/mcp_gateway/server/mcp_gateway.py +0 -419
- claude_mpm/services/mcp_gateway/server/stdio_handler.py +0 -372
- claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -714
- claude_mpm/services/mcp_gateway/tools/__init__.py +0 -36
- claude_mpm/services/mcp_gateway/tools/base_adapter.py +0 -485
- claude_mpm/services/mcp_gateway/tools/document_summarizer.py +0 -789
- claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +0 -654
- claude_mpm/services/mcp_gateway/tools/health_check_tool.py +0 -456
- claude_mpm/services/mcp_gateway/tools/hello_world.py +0 -551
- claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +0 -551
- claude_mpm/services/mcp_gateway/utils/__init__.py +0 -14
- claude_mpm/services/mcp_gateway/utils/package_version_checker.py +0 -160
- claude_mpm/services/mcp_gateway/utils/update_preferences.py +0 -170
- claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +0 -79
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +0 -178
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +0 -577
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +0 -467
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +0 -537
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +0 -730
- claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +0 -112
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +0 -146
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +0 -412
- claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +0 -81
- claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +0 -362
- claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +0 -312
- claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +0 -152
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +0 -668
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +0 -587
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +0 -438
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +0 -391
- claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +0 -119
- claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +0 -148
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +0 -483
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +0 -452
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +0 -449
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +0 -411
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +0 -14
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +0 -58
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +0 -68
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +0 -69
- claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +0 -131
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +0 -325
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +0 -490
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +0 -425
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +0 -499
- claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +0 -86
- claude_mpm/skills/bundled/main/internal-comms/SKILL.md +0 -43
- claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +0 -47
- claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +0 -65
- claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +0 -30
- claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +0 -16
- claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +0 -160
- claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +0 -412
- claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +0 -602
- claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +0 -915
- claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +0 -916
- claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +0 -752
- claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +0 -1237
- claude_mpm/skills/bundled/main/skill-creator/SKILL.md +0 -189
- claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +0 -500
- claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +0 -464
- claude_mpm/skills/bundled/main/skill-creator/references/examples.md +0 -619
- claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +0 -437
- claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +0 -231
- claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +0 -170
- claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +0 -602
- claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +0 -821
- claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +0 -742
- claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +0 -726
- claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +0 -764
- claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +0 -831
- claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +0 -226
- claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +0 -901
- claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +0 -901
- claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +0 -775
- claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +0 -937
- claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +0 -770
- claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +0 -961
- claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +0 -119
- claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +0 -253
- claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +0 -145
- claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +0 -543
- claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +0 -741
- claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +0 -470
- claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +0 -458
- claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +0 -639
- claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +0 -140
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +0 -572
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +0 -411
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +0 -569
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +0 -695
- claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +0 -184
- claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +0 -459
- claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +0 -479
- claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +0 -687
- claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +0 -758
- claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +0 -868
- claude_mpm-4.24.0.dist-info/entry_points.txt +0 -10
- claude_mpm-4.24.0.dist-info/licenses/LICENSE +0 -21
- /claude_mpm/agents/templates/{git_file_tracking.md → git-file-tracking.md} +0 -0
- /claude_mpm/agents/templates/{pm_examples.md → pm-examples.md} +0 -0
- /claude_mpm/agents/templates/{response_format.md → response-format.md} +0 -0
- /claude_mpm/agents/templates/{validation_templates.md → validation-templates.md} +0 -0
- {claude_mpm-4.24.0.dist-info → claude_mpm-5.4.41.dist-info}/WHEEL +0 -0
- {claude_mpm-4.24.0.dist-info → claude_mpm-5.4.41.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,663 @@
|
|
|
1
|
+
"""Git source manager for multi-repository agent sync and discovery."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from datetime import datetime, timezone
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Any, Dict, List, Optional
|
|
7
|
+
|
|
8
|
+
from claude_mpm.models.git_repository import GitRepository
|
|
9
|
+
from claude_mpm.services.agents.deployment.remote_agent_discovery_service import (
|
|
10
|
+
RemoteAgentDiscoveryService,
|
|
11
|
+
)
|
|
12
|
+
from claude_mpm.services.agents.sources.git_source_sync_service import (
|
|
13
|
+
GitSourceSyncService,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
logger = logging.getLogger(__name__)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class GitSourceManager:
|
|
20
|
+
"""Manages Git repository sources for agents.
|
|
21
|
+
|
|
22
|
+
This service coordinates syncing and discovery across multiple Git repositories.
|
|
23
|
+
It handles:
|
|
24
|
+
- Multi-repository sync with priority resolution
|
|
25
|
+
- ETag-based incremental updates
|
|
26
|
+
- Agent discovery from cached repositories
|
|
27
|
+
- Priority-based agent resolution (lower priority = higher precedence)
|
|
28
|
+
|
|
29
|
+
Design Decision: Composition over inheritance
|
|
30
|
+
|
|
31
|
+
Rationale: GitSourceManager composes GitSourceSyncService and
|
|
32
|
+
RemoteAgentDiscoveryService rather than inheriting. This provides
|
|
33
|
+
better separation of concerns and makes it easier to test each
|
|
34
|
+
component independently.
|
|
35
|
+
|
|
36
|
+
Trade-offs:
|
|
37
|
+
- Flexibility: Easy to swap implementations or mock for testing
|
|
38
|
+
- Complexity: Slightly more code than inheritance
|
|
39
|
+
- Maintainability: Clear boundaries between sync and discovery
|
|
40
|
+
|
|
41
|
+
Example:
|
|
42
|
+
>>> manager = GitSourceManager()
|
|
43
|
+
>>> repo = GitRepository(url="https://github.com/owner/repo")
|
|
44
|
+
>>> result = manager.sync_repository(repo)
|
|
45
|
+
>>> agents = manager.list_cached_agents()
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
def __init__(self, cache_root: Optional[Path] = None):
|
|
49
|
+
"""Initialize Git source manager.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
cache_root: Root directory for repository caches.
|
|
53
|
+
Defaults to ~/.claude-mpm/cache/agents/
|
|
54
|
+
"""
|
|
55
|
+
if cache_root is None:
|
|
56
|
+
cache_root = Path.home() / ".claude-mpm" / "cache" / "agents"
|
|
57
|
+
|
|
58
|
+
self.cache_root = cache_root
|
|
59
|
+
self.cache_root.mkdir(parents=True, exist_ok=True)
|
|
60
|
+
|
|
61
|
+
# Bug #2 fix: Store repository metadata for source attribution
|
|
62
|
+
# Maps repo_identifier -> {priority, url, ...}
|
|
63
|
+
self._repo_metadata: Dict[str, Dict[str, Any]] = {}
|
|
64
|
+
|
|
65
|
+
logger.info(f"GitSourceManager initialized with cache: {self.cache_root}")
|
|
66
|
+
|
|
67
|
+
def sync_repository(
|
|
68
|
+
self, repo: GitRepository, force: bool = False, show_progress: bool = True
|
|
69
|
+
) -> Dict[str, Any]:
|
|
70
|
+
"""
|
|
71
|
+
Sync a single repository from Git.
|
|
72
|
+
|
|
73
|
+
This method:
|
|
74
|
+
1. Creates a GitSourceSyncService for the repository
|
|
75
|
+
2. Syncs agents using ETag-based caching (unless force=True)
|
|
76
|
+
3. Discovers agents in the cached directory
|
|
77
|
+
4. Returns sync results with metadata
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
repo: GitRepository to sync
|
|
81
|
+
force: Force sync even if cache is fresh (bypasses ETag)
|
|
82
|
+
show_progress: Show ASCII progress bar during sync (default: True)
|
|
83
|
+
|
|
84
|
+
Returns:
|
|
85
|
+
Dictionary with sync results:
|
|
86
|
+
{
|
|
87
|
+
"synced": bool, # Overall success
|
|
88
|
+
"etag": str, # HTTP ETag from sync
|
|
89
|
+
"files_updated": int, # Files downloaded
|
|
90
|
+
"files_added": int, # New files
|
|
91
|
+
"files_removed": int, # Deleted files
|
|
92
|
+
"files_cached": int, # Cache hits (304)
|
|
93
|
+
"agents_discovered": List[str], # Agent names found
|
|
94
|
+
"timestamp": str, # ISO timestamp
|
|
95
|
+
"error": str # Error message (if failed)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
Example:
|
|
99
|
+
>>> repo = GitRepository(url="https://github.com/owner/repo")
|
|
100
|
+
>>> result = manager.sync_repository(repo)
|
|
101
|
+
>>> if result["synced"]:
|
|
102
|
+
... print(f"Synced {result['files_updated']} files")
|
|
103
|
+
"""
|
|
104
|
+
logger.info(f"Syncing repository: {repo.identifier}")
|
|
105
|
+
|
|
106
|
+
# Bug #2 fix: Store repository metadata for later source attribution
|
|
107
|
+
self._repo_metadata[repo.identifier] = {
|
|
108
|
+
"priority": repo.priority,
|
|
109
|
+
"url": repo.url,
|
|
110
|
+
"subdirectory": repo.subdirectory,
|
|
111
|
+
"enabled": repo.enabled,
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
try:
|
|
115
|
+
# Build source URL for raw GitHub content
|
|
116
|
+
# Format: https://raw.githubusercontent.com/owner/repo/main/subdirectory
|
|
117
|
+
owner, repo_name = repo._parse_github_url(repo.url)
|
|
118
|
+
branch = "main" # TODO: Make configurable
|
|
119
|
+
|
|
120
|
+
if repo.subdirectory:
|
|
121
|
+
subdirectory = repo.subdirectory.strip("/")
|
|
122
|
+
source_url = f"https://raw.githubusercontent.com/{owner}/{repo_name}/{branch}/{subdirectory}"
|
|
123
|
+
else:
|
|
124
|
+
source_url = (
|
|
125
|
+
f"https://raw.githubusercontent.com/{owner}/{repo_name}/{branch}"
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
# Initialize sync service
|
|
129
|
+
sync_service = GitSourceSyncService(
|
|
130
|
+
source_url=source_url,
|
|
131
|
+
cache_dir=repo.cache_path,
|
|
132
|
+
source_id=repo.identifier,
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
# Sync agents with progress bar
|
|
136
|
+
sync_results = sync_service.sync_agents(
|
|
137
|
+
force_refresh=force, show_progress=show_progress
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
# Discover agents in cache
|
|
141
|
+
discovery_service = RemoteAgentDiscoveryService(repo.cache_path)
|
|
142
|
+
discovered_agents = discovery_service.discover_remote_agents()
|
|
143
|
+
|
|
144
|
+
# Build result
|
|
145
|
+
result = {
|
|
146
|
+
"synced": True,
|
|
147
|
+
"files_updated": sync_results.get("total_downloaded", 0),
|
|
148
|
+
"files_added": len(sync_results.get("synced", [])),
|
|
149
|
+
"files_removed": 0, # TODO: Track deletions
|
|
150
|
+
"files_cached": sync_results.get("cache_hits", 0),
|
|
151
|
+
"agents_discovered": [
|
|
152
|
+
agent.get("metadata", {}).get(
|
|
153
|
+
"name", agent.get("agent_id", "unknown")
|
|
154
|
+
)
|
|
155
|
+
for agent in discovered_agents
|
|
156
|
+
],
|
|
157
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
logger.info(
|
|
161
|
+
f"Sync complete: {result['files_updated']} updated, "
|
|
162
|
+
f"{result['files_cached']} cached, "
|
|
163
|
+
f"{len(result['agents_discovered'])} agents"
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
return result
|
|
167
|
+
|
|
168
|
+
except Exception as e:
|
|
169
|
+
logger.error(f"Failed to sync {repo.identifier}: {e}")
|
|
170
|
+
return {
|
|
171
|
+
"synced": False,
|
|
172
|
+
"error": str(e),
|
|
173
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
def sync_all_repositories(
|
|
177
|
+
self,
|
|
178
|
+
repos: List[GitRepository],
|
|
179
|
+
force: bool = False,
|
|
180
|
+
show_progress: bool = True,
|
|
181
|
+
) -> Dict[str, Dict[str, Any]]:
|
|
182
|
+
"""Sync multiple repositories.
|
|
183
|
+
|
|
184
|
+
Syncs repositories in priority order (lower priority first).
|
|
185
|
+
Individual failures don't stop overall sync.
|
|
186
|
+
|
|
187
|
+
Args:
|
|
188
|
+
repos: List of repositories to sync
|
|
189
|
+
force: Force sync even if cache is fresh
|
|
190
|
+
show_progress: Show ASCII progress bar during sync (default: True)
|
|
191
|
+
|
|
192
|
+
Returns:
|
|
193
|
+
Dictionary mapping repository identifier to sync results:
|
|
194
|
+
{
|
|
195
|
+
"owner/repo/subdir": {...},
|
|
196
|
+
"owner/repo2": {...}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
Example:
|
|
200
|
+
>>> repos = [
|
|
201
|
+
... GitRepository(url="https://github.com/owner/repo1", priority=100),
|
|
202
|
+
... GitRepository(url="https://github.com/owner/repo2", priority=50)
|
|
203
|
+
... ]
|
|
204
|
+
>>> results = manager.sync_all_repositories(repos)
|
|
205
|
+
>>> for repo_id, result in results.items():
|
|
206
|
+
... print(f"{repo_id}: {'✓' if result['synced'] else '✗'}")
|
|
207
|
+
"""
|
|
208
|
+
logger.info(f"Syncing {len(repos)} repositories")
|
|
209
|
+
|
|
210
|
+
# Sort by priority (lower = higher precedence)
|
|
211
|
+
sorted_repos = sorted(repos, key=lambda r: r.priority)
|
|
212
|
+
|
|
213
|
+
results = {}
|
|
214
|
+
|
|
215
|
+
for repo in sorted_repos:
|
|
216
|
+
# Skip disabled repositories
|
|
217
|
+
if not repo.enabled:
|
|
218
|
+
logger.debug(f"Skipping disabled repository: {repo.identifier}")
|
|
219
|
+
continue
|
|
220
|
+
|
|
221
|
+
try:
|
|
222
|
+
result = self.sync_repository(
|
|
223
|
+
repo, force=force, show_progress=show_progress
|
|
224
|
+
)
|
|
225
|
+
results[repo.identifier] = result
|
|
226
|
+
|
|
227
|
+
except Exception as e:
|
|
228
|
+
logger.error(f"Exception syncing {repo.identifier}: {e}")
|
|
229
|
+
results[repo.identifier] = {"synced": False, "error": str(e)}
|
|
230
|
+
|
|
231
|
+
logger.info(
|
|
232
|
+
f"Sync complete: {sum(1 for r in results.values() if r.get('synced'))} "
|
|
233
|
+
f"succeeded, {sum(1 for r in results.values() if not r.get('synced'))} failed"
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
return results
|
|
237
|
+
|
|
238
|
+
def _ensure_metadata_loaded(self) -> None:
|
|
239
|
+
"""Load repository metadata from configuration if not already loaded.
|
|
240
|
+
|
|
241
|
+
Bug #2 fix: Ensures repository metadata (priority, URL) is available
|
|
242
|
+
for source attribution even when list_cached_agents() is called
|
|
243
|
+
without prior sync_repository() calls.
|
|
244
|
+
|
|
245
|
+
Attempts to load from AgentSourceConfiguration and populates
|
|
246
|
+
_repo_metadata dictionary with priority and URL for each repository.
|
|
247
|
+
"""
|
|
248
|
+
# Skip if metadata already populated
|
|
249
|
+
if self._repo_metadata:
|
|
250
|
+
return
|
|
251
|
+
|
|
252
|
+
try:
|
|
253
|
+
from ...config.agent_sources import AgentSourceConfiguration
|
|
254
|
+
|
|
255
|
+
config = AgentSourceConfiguration()
|
|
256
|
+
sources = config.list_sources()
|
|
257
|
+
|
|
258
|
+
for source in sources:
|
|
259
|
+
# Source dict has: identifier, url, subdirectory, enabled, priority
|
|
260
|
+
self._repo_metadata[source["identifier"]] = {
|
|
261
|
+
"priority": source.get("priority", 100),
|
|
262
|
+
"url": source.get("url", ""),
|
|
263
|
+
"subdirectory": source.get("subdirectory"),
|
|
264
|
+
"enabled": source.get("enabled", True),
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
logger.debug(f"Loaded metadata for {len(self._repo_metadata)} repositories")
|
|
268
|
+
|
|
269
|
+
except Exception as e:
|
|
270
|
+
logger.warning(f"Failed to load repository metadata from config: {e}")
|
|
271
|
+
# Continue with empty metadata - will use defaults in _discover_agents_in_directory
|
|
272
|
+
|
|
273
|
+
def list_cached_agents(
|
|
274
|
+
self, repo_identifier: Optional[str] = None
|
|
275
|
+
) -> List[Dict[str, Any]]:
|
|
276
|
+
"""List all cached agents, optionally filtered by repository.
|
|
277
|
+
|
|
278
|
+
Scans cache directories for agent markdown files and returns
|
|
279
|
+
metadata for each discovered agent with source attribution.
|
|
280
|
+
|
|
281
|
+
Bug #2 fix: Enriches agents with repository metadata (priority, URL)
|
|
282
|
+
from stored configuration or attempts to load from config file.
|
|
283
|
+
|
|
284
|
+
Args:
|
|
285
|
+
repo_identifier: Optional repository filter (e.g., "owner/repo/agents")
|
|
286
|
+
|
|
287
|
+
Returns:
|
|
288
|
+
List of agent metadata dictionaries:
|
|
289
|
+
[
|
|
290
|
+
{
|
|
291
|
+
"name": "engineer",
|
|
292
|
+
"version": "2.5.0",
|
|
293
|
+
"path": "/cache/owner/repo/agents/engineer.md",
|
|
294
|
+
"repository": "owner/repo/agents",
|
|
295
|
+
"source": {
|
|
296
|
+
"identifier": "owner/repo/agents",
|
|
297
|
+
"priority": 100,
|
|
298
|
+
"url": "https://github.com/owner/repo"
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
]
|
|
302
|
+
|
|
303
|
+
Example:
|
|
304
|
+
>>> agents = manager.list_cached_agents()
|
|
305
|
+
>>> for agent in agents:
|
|
306
|
+
... print(f"{agent['name']} v{agent['version']} from {agent['repository']}")
|
|
307
|
+
"""
|
|
308
|
+
logger.debug(
|
|
309
|
+
f"[DEBUG] list_cached_agents START: repo_identifier={repo_identifier}"
|
|
310
|
+
)
|
|
311
|
+
|
|
312
|
+
# Bug #2 fix: Load metadata from config if not already loaded
|
|
313
|
+
logger.debug("[DEBUG] Calling _ensure_metadata_loaded()")
|
|
314
|
+
self._ensure_metadata_loaded()
|
|
315
|
+
logger.debug("[DEBUG] Metadata loaded successfully")
|
|
316
|
+
|
|
317
|
+
agents = []
|
|
318
|
+
|
|
319
|
+
# If repo_identifier specified, only scan that repository
|
|
320
|
+
if repo_identifier:
|
|
321
|
+
# Parse identifier to find cache path
|
|
322
|
+
parts = repo_identifier.split("/")
|
|
323
|
+
if len(parts) >= 2:
|
|
324
|
+
cache_path = self.cache_root / "/".join(parts)
|
|
325
|
+
|
|
326
|
+
if cache_path.exists():
|
|
327
|
+
metadata = self._repo_metadata.get(repo_identifier, {})
|
|
328
|
+
agents.extend(
|
|
329
|
+
self._discover_agents_in_directory(
|
|
330
|
+
cache_path, repo_identifier, metadata
|
|
331
|
+
)
|
|
332
|
+
)
|
|
333
|
+
else:
|
|
334
|
+
# Scan all cached repositories
|
|
335
|
+
logger.debug("[DEBUG] Scanning all cached repositories")
|
|
336
|
+
if not self.cache_root.exists():
|
|
337
|
+
logger.debug(f"[DEBUG] Cache root doesn't exist: {self.cache_root}")
|
|
338
|
+
return []
|
|
339
|
+
|
|
340
|
+
# Walk cache directory structure
|
|
341
|
+
logger.debug(f"[DEBUG] Walking cache root: {self.cache_root}")
|
|
342
|
+
|
|
343
|
+
# Known legacy category directories to skip (flat cache structure)
|
|
344
|
+
LEGACY_CATEGORIES = {
|
|
345
|
+
"universal",
|
|
346
|
+
"engineer",
|
|
347
|
+
"ops",
|
|
348
|
+
"qa",
|
|
349
|
+
"security",
|
|
350
|
+
"documentation",
|
|
351
|
+
"claude-mpm",
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
# Repositories that are NOT agent repositories (should be excluded from agent discovery)
|
|
355
|
+
# These contain skills, documentation, or other non-agent content
|
|
356
|
+
EXCLUDED_REPOSITORIES = {
|
|
357
|
+
"claude-mpm-skills", # Skills repository, not agents
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
for owner_dir in self.cache_root.iterdir():
|
|
361
|
+
if not owner_dir.is_dir():
|
|
362
|
+
continue
|
|
363
|
+
|
|
364
|
+
# Skip legacy category directories (they're not GitHub owners)
|
|
365
|
+
if owner_dir.name.lower() in LEGACY_CATEGORIES:
|
|
366
|
+
logger.debug(
|
|
367
|
+
f"[DEBUG] Skipping legacy category directory: {owner_dir.name}"
|
|
368
|
+
)
|
|
369
|
+
continue
|
|
370
|
+
|
|
371
|
+
logger.debug(f"[DEBUG] Processing owner_dir: {owner_dir.name}")
|
|
372
|
+
|
|
373
|
+
for repo_dir in owner_dir.iterdir():
|
|
374
|
+
if not repo_dir.is_dir():
|
|
375
|
+
continue
|
|
376
|
+
|
|
377
|
+
# Skip excluded repositories (e.g., skills repos are not agent repos)
|
|
378
|
+
if repo_dir.name in EXCLUDED_REPOSITORIES:
|
|
379
|
+
logger.debug(
|
|
380
|
+
f"[DEBUG] Skipping excluded repository: {repo_dir.name}"
|
|
381
|
+
)
|
|
382
|
+
continue
|
|
383
|
+
|
|
384
|
+
logger.debug(f"[DEBUG] Processing repo_dir: {repo_dir.name}")
|
|
385
|
+
|
|
386
|
+
# Bug #5 fix: Don't iterate subdirectories - RemoteAgentDiscoveryService
|
|
387
|
+
# now handles the /agents/ subdirectory internally (Bug #4 fix).
|
|
388
|
+
# Iterating subdirectories caused it to treat /agents/ hierarchy as
|
|
389
|
+
# separate repositories (engineer/backend, ops/tooling, etc.)
|
|
390
|
+
repo_id = f"{owner_dir.name}/{repo_dir.name}"
|
|
391
|
+
metadata = self._repo_metadata.get(repo_id, {})
|
|
392
|
+
logger.debug(f"[DEBUG] Discovering agents in repo root: {repo_id}")
|
|
393
|
+
agents.extend(
|
|
394
|
+
self._discover_agents_in_directory(repo_dir, repo_id, metadata)
|
|
395
|
+
)
|
|
396
|
+
logger.debug(f"[DEBUG] Found {len(agents)} agents so far")
|
|
397
|
+
|
|
398
|
+
logger.debug(f"[DEBUG] list_cached_agents COMPLETE: {len(agents)} total agents")
|
|
399
|
+
return agents
|
|
400
|
+
|
|
401
|
+
def _discover_agents_in_directory(
|
|
402
|
+
self,
|
|
403
|
+
directory: Path,
|
|
404
|
+
repo_identifier: str,
|
|
405
|
+
repo_metadata: Optional[Dict[str, Any]] = None,
|
|
406
|
+
) -> List[Dict[str, Any]]:
|
|
407
|
+
"""Discover agents in a specific directory with source attribution.
|
|
408
|
+
|
|
409
|
+
Bug #2 fix: Enriches agent metadata with source information including
|
|
410
|
+
repository identifier, priority, and URL for proper attribution.
|
|
411
|
+
|
|
412
|
+
Args:
|
|
413
|
+
directory: Directory to scan
|
|
414
|
+
repo_identifier: Repository identifier for metadata
|
|
415
|
+
repo_metadata: Optional repository metadata (priority, URL, etc.)
|
|
416
|
+
|
|
417
|
+
Returns:
|
|
418
|
+
List of agent metadata dictionaries with source attribution
|
|
419
|
+
"""
|
|
420
|
+
try:
|
|
421
|
+
discovery_service = RemoteAgentDiscoveryService(directory)
|
|
422
|
+
discovered = discovery_service.discover_remote_agents()
|
|
423
|
+
|
|
424
|
+
# Default metadata if not provided
|
|
425
|
+
if repo_metadata is None:
|
|
426
|
+
repo_metadata = {}
|
|
427
|
+
|
|
428
|
+
# Bug #2 fix: Enrich each agent with proper source attribution
|
|
429
|
+
for agent in discovered:
|
|
430
|
+
agent["repository"] = repo_identifier
|
|
431
|
+
|
|
432
|
+
# Add source attribution at root level for CLI compatibility
|
|
433
|
+
# source: repository identifier string
|
|
434
|
+
# priority: numeric priority from config
|
|
435
|
+
# source_url: full GitHub URL for reference
|
|
436
|
+
if "source" not in agent or agent["source"] == "remote":
|
|
437
|
+
agent["source"] = repo_identifier
|
|
438
|
+
agent["priority"] = repo_metadata.get("priority", 100)
|
|
439
|
+
agent["source_url"] = repo_metadata.get("url", "")
|
|
440
|
+
|
|
441
|
+
return discovered
|
|
442
|
+
|
|
443
|
+
except Exception as e:
|
|
444
|
+
logger.warning(f"Failed to discover agents in {directory}: {e}")
|
|
445
|
+
return []
|
|
446
|
+
|
|
447
|
+
def get_agent_path(
|
|
448
|
+
self, agent_name: str, repo_identifier: Optional[str] = None
|
|
449
|
+
) -> Optional[Path]:
|
|
450
|
+
"""Get cached path for a specific agent.
|
|
451
|
+
|
|
452
|
+
Args:
|
|
453
|
+
agent_name: Agent name (without .md extension)
|
|
454
|
+
repo_identifier: Optional repository filter
|
|
455
|
+
|
|
456
|
+
Returns:
|
|
457
|
+
Path to cached agent file, or None if not found
|
|
458
|
+
|
|
459
|
+
Example:
|
|
460
|
+
>>> path = manager.get_agent_path("engineer")
|
|
461
|
+
>>> if path:
|
|
462
|
+
... print(f"Found: {path}")
|
|
463
|
+
"""
|
|
464
|
+
agents = self.list_cached_agents(repo_identifier)
|
|
465
|
+
|
|
466
|
+
for agent in agents:
|
|
467
|
+
# Agent dict has metadata.name or agent_id
|
|
468
|
+
name = agent.get("metadata", {}).get("name", "")
|
|
469
|
+
agent_id = agent.get("agent_id", "")
|
|
470
|
+
|
|
471
|
+
if name.lower().replace(" ", "-") == agent_name or agent_id == agent_name:
|
|
472
|
+
return Path(agent.get("source_file", ""))
|
|
473
|
+
|
|
474
|
+
return None
|
|
475
|
+
|
|
476
|
+
def list_cached_agents_with_filters(
|
|
477
|
+
self,
|
|
478
|
+
repo_identifier: Optional[str] = None,
|
|
479
|
+
filters: Optional[Dict[str, Any]] = None,
|
|
480
|
+
) -> List[Dict[str, Any]]:
|
|
481
|
+
"""List cached agents with optional filters.
|
|
482
|
+
|
|
483
|
+
This method extends list_cached_agents() by adding semantic filtering
|
|
484
|
+
based on AUTO-DEPLOY-INDEX.md categories. Filters are applied using
|
|
485
|
+
the AutoDeployIndexParser to match agents by category, language,
|
|
486
|
+
framework, platform, or specialization.
|
|
487
|
+
|
|
488
|
+
Design Decision: Filter at application layer, not database layer
|
|
489
|
+
|
|
490
|
+
Rationale: Agent discovery is file-based (no database), so filtering
|
|
491
|
+
happens in-memory after discovery. For the expected dataset size
|
|
492
|
+
(100-1000 agents), this performs well (~10-50ms).
|
|
493
|
+
|
|
494
|
+
Trade-offs:
|
|
495
|
+
- Simplicity: No query optimization needed, straightforward logic
|
|
496
|
+
- Performance: Fast enough for CLI use case (< 100ms)
|
|
497
|
+
- Scalability: May need optimization for 10K+ agents
|
|
498
|
+
|
|
499
|
+
Args:
|
|
500
|
+
repo_identifier: Filter by specific repository
|
|
501
|
+
filters: Dict with optional keys:
|
|
502
|
+
- category: str (e.g., "engineer/backend", "qa")
|
|
503
|
+
- language: str (e.g., "python", "javascript")
|
|
504
|
+
- framework: str (e.g., "react", "nextjs")
|
|
505
|
+
- platform: str (e.g., "vercel", "gcp")
|
|
506
|
+
- specialization: str (e.g., "data", "security")
|
|
507
|
+
|
|
508
|
+
Returns:
|
|
509
|
+
List of agent definitions with metadata:
|
|
510
|
+
[
|
|
511
|
+
{
|
|
512
|
+
"agent_id": "engineer/backend/python-engineer",
|
|
513
|
+
"name": "Python Engineer",
|
|
514
|
+
"version": "1.2.0",
|
|
515
|
+
"description": "...",
|
|
516
|
+
"source": "bobmatnyc/claude-mpm-agents",
|
|
517
|
+
"priority": 100,
|
|
518
|
+
"category": "engineer/backend",
|
|
519
|
+
"metadata": {...}
|
|
520
|
+
}
|
|
521
|
+
]
|
|
522
|
+
|
|
523
|
+
Example:
|
|
524
|
+
>>> # Filter by category
|
|
525
|
+
>>> agents = manager.list_cached_agents_with_filters(
|
|
526
|
+
... filters={"category": "engineer/backend"}
|
|
527
|
+
... )
|
|
528
|
+
>>> for agent in agents:
|
|
529
|
+
... print(f"{agent['agent_id']} from {agent['source']}")
|
|
530
|
+
|
|
531
|
+
>>> # Filter by language
|
|
532
|
+
>>> agents = manager.list_cached_agents_with_filters(
|
|
533
|
+
... filters={"language": "python"}
|
|
534
|
+
... )
|
|
535
|
+
|
|
536
|
+
>>> # Multiple filters
|
|
537
|
+
>>> agents = manager.list_cached_agents_with_filters(
|
|
538
|
+
... filters={"category": "engineer/frontend", "framework": "react"}
|
|
539
|
+
... )
|
|
540
|
+
"""
|
|
541
|
+
# Get all cached agents
|
|
542
|
+
all_agents = self.list_cached_agents(repo_identifier)
|
|
543
|
+
|
|
544
|
+
# If no filters, return all agents
|
|
545
|
+
if not filters:
|
|
546
|
+
return all_agents
|
|
547
|
+
|
|
548
|
+
# Load AUTO-DEPLOY-INDEX.md parser
|
|
549
|
+
from .auto_deploy_index_parser import AutoDeployIndexParser
|
|
550
|
+
|
|
551
|
+
# Find AUTO-DEPLOY-INDEX.md in bobmatnyc/claude-mpm-agents cache
|
|
552
|
+
index_path = (
|
|
553
|
+
self.cache_root / "bobmatnyc" / "claude-mpm-agents" / "AUTO-DEPLOY-INDEX.md"
|
|
554
|
+
)
|
|
555
|
+
|
|
556
|
+
if not index_path.exists():
|
|
557
|
+
logger.warning(f"AUTO-DEPLOY-INDEX.md not found at: {index_path}")
|
|
558
|
+
logger.warning("Filtering by category/language/framework unavailable")
|
|
559
|
+
# Return all agents if index not found
|
|
560
|
+
return all_agents
|
|
561
|
+
|
|
562
|
+
parser = AutoDeployIndexParser(index_path)
|
|
563
|
+
|
|
564
|
+
# Build set of matching agent IDs based on filters
|
|
565
|
+
matching_agent_ids = set()
|
|
566
|
+
|
|
567
|
+
# Filter by category
|
|
568
|
+
if "category" in filters:
|
|
569
|
+
category = filters["category"]
|
|
570
|
+
category_agents = parser.get_agents_by_category(category)
|
|
571
|
+
matching_agent_ids.update(category_agents)
|
|
572
|
+
logger.debug(
|
|
573
|
+
f"Category '{category}': {len(category_agents)} matching agents"
|
|
574
|
+
)
|
|
575
|
+
|
|
576
|
+
# Filter by language
|
|
577
|
+
if "language" in filters:
|
|
578
|
+
language = filters["language"]
|
|
579
|
+
lang_agents = parser.get_agents_by_language(language)
|
|
580
|
+
lang_agent_ids = lang_agents.get("core", []) + lang_agents.get(
|
|
581
|
+
"optional", []
|
|
582
|
+
)
|
|
583
|
+
if matching_agent_ids:
|
|
584
|
+
# Intersection with previous filters
|
|
585
|
+
matching_agent_ids &= set(lang_agent_ids)
|
|
586
|
+
else:
|
|
587
|
+
matching_agent_ids.update(lang_agent_ids)
|
|
588
|
+
logger.debug(
|
|
589
|
+
f"Language '{language}': {len(lang_agent_ids)} matching agents"
|
|
590
|
+
)
|
|
591
|
+
|
|
592
|
+
# Filter by framework
|
|
593
|
+
if "framework" in filters:
|
|
594
|
+
framework = filters["framework"]
|
|
595
|
+
framework_agents = parser.get_agents_by_framework(framework)
|
|
596
|
+
if matching_agent_ids:
|
|
597
|
+
# Intersection with previous filters
|
|
598
|
+
matching_agent_ids &= set(framework_agents)
|
|
599
|
+
else:
|
|
600
|
+
matching_agent_ids.update(framework_agents)
|
|
601
|
+
logger.debug(
|
|
602
|
+
f"Framework '{framework}': {len(framework_agents)} matching agents"
|
|
603
|
+
)
|
|
604
|
+
|
|
605
|
+
# Filter by platform
|
|
606
|
+
if "platform" in filters:
|
|
607
|
+
platform = filters["platform"]
|
|
608
|
+
platform_agents = parser.get_agents_by_platform(platform)
|
|
609
|
+
if matching_agent_ids:
|
|
610
|
+
# Intersection with previous filters
|
|
611
|
+
matching_agent_ids &= set(platform_agents)
|
|
612
|
+
else:
|
|
613
|
+
matching_agent_ids.update(platform_agents)
|
|
614
|
+
logger.debug(
|
|
615
|
+
f"Platform '{platform}': {len(platform_agents)} matching agents"
|
|
616
|
+
)
|
|
617
|
+
|
|
618
|
+
# Filter by specialization
|
|
619
|
+
if "specialization" in filters:
|
|
620
|
+
specialization = filters["specialization"]
|
|
621
|
+
spec_agents = parser.get_agents_by_specialization(specialization)
|
|
622
|
+
if matching_agent_ids:
|
|
623
|
+
# Intersection with previous filters
|
|
624
|
+
matching_agent_ids &= set(spec_agents)
|
|
625
|
+
else:
|
|
626
|
+
matching_agent_ids.update(spec_agents)
|
|
627
|
+
logger.debug(
|
|
628
|
+
f"Specialization '{specialization}': {len(spec_agents)} matching agents"
|
|
629
|
+
)
|
|
630
|
+
|
|
631
|
+
# Filter all_agents to only include matching IDs
|
|
632
|
+
filtered_agents = []
|
|
633
|
+
|
|
634
|
+
for agent in all_agents:
|
|
635
|
+
# Extract agent_id from metadata or infer from path
|
|
636
|
+
agent_id = agent.get("agent_id")
|
|
637
|
+
|
|
638
|
+
if not agent_id:
|
|
639
|
+
# Try to infer from metadata.name or source_file
|
|
640
|
+
name = agent.get("metadata", {}).get("name", "")
|
|
641
|
+
if name:
|
|
642
|
+
agent_id = name.lower().replace(" ", "-")
|
|
643
|
+
|
|
644
|
+
# Check if agent matches filter
|
|
645
|
+
if agent_id in matching_agent_ids:
|
|
646
|
+
# Add source attribution
|
|
647
|
+
agent["source"] = agent.get("repository", "unknown")
|
|
648
|
+
|
|
649
|
+
# Add category if not present
|
|
650
|
+
if "category" not in agent and "/" in agent_id:
|
|
651
|
+
agent["category"] = agent_id.rsplit("/", 1)[0]
|
|
652
|
+
|
|
653
|
+
filtered_agents.append(agent)
|
|
654
|
+
|
|
655
|
+
logger.info(
|
|
656
|
+
f"Filtered {len(filtered_agents)} agents from {len(all_agents)} total"
|
|
657
|
+
)
|
|
658
|
+
|
|
659
|
+
return filtered_agents
|
|
660
|
+
|
|
661
|
+
def __repr__(self) -> str:
|
|
662
|
+
"""Return string representation."""
|
|
663
|
+
return f"GitSourceManager(cache_root='{self.cache_root}')"
|
|
@@ -13,9 +13,6 @@ from enum import Enum
|
|
|
13
13
|
from pathlib import Path
|
|
14
14
|
from typing import Any, Dict, List, Optional
|
|
15
15
|
|
|
16
|
-
# Lazy import for base_agent_loader to reduce initialization overhead
|
|
17
|
-
# base_agent_loader adds ~500ms to import time
|
|
18
|
-
# from claude_mpm.agents.base_agent_loader import clear_base_agent_cache
|
|
19
16
|
from claude_mpm.core.logging_utils import get_logger
|
|
20
17
|
from claude_mpm.services.memory.cache.shared_prompt_cache import SharedPromptCache
|
|
21
18
|
from claude_mpm.services.shared import ConfigServiceBase
|
|
@@ -23,13 +20,6 @@ from claude_mpm.services.shared import ConfigServiceBase
|
|
|
23
20
|
logger = get_logger(__name__)
|
|
24
21
|
|
|
25
22
|
|
|
26
|
-
def _get_clear_base_agent_cache():
|
|
27
|
-
"""Lazy loader for clear_base_agent_cache function."""
|
|
28
|
-
from claude_mpm.agents.base_agent_loader import clear_base_agent_cache
|
|
29
|
-
|
|
30
|
-
return clear_base_agent_cache
|
|
31
|
-
|
|
32
|
-
|
|
33
23
|
class BaseAgentSection(str, Enum):
|
|
34
24
|
"""Base agent markdown sections."""
|
|
35
25
|
|
|
@@ -143,9 +133,7 @@ class BaseAgentManager(ConfigServiceBase):
|
|
|
143
133
|
content = self._structure_to_markdown(current)
|
|
144
134
|
self.base_agent_path.write_text(content, encoding="utf-8")
|
|
145
135
|
|
|
146
|
-
# Clear
|
|
147
|
-
clear_base_agent_cache = _get_clear_base_agent_cache()
|
|
148
|
-
clear_base_agent_cache()
|
|
136
|
+
# Clear cache
|
|
149
137
|
self.cache.invalidate("base_agent:instructions")
|
|
150
138
|
|
|
151
139
|
logger.info("Base agent updated successfully")
|