claude-mpm 3.4.10__py3-none-any.whl → 5.4.85__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/BUILD_NUMBER +1 -0
- claude_mpm/VERSION +1 -0
- claude_mpm/__init__.py +50 -12
- claude_mpm/__main__.py +7 -2
- claude_mpm/agents/BASE_AGENT.md +164 -0
- claude_mpm/agents/BASE_ENGINEER.md +658 -0
- claude_mpm/agents/CLAUDE_MPM_FOUNDERS_OUTPUT_STYLE.md +405 -0
- claude_mpm/agents/CLAUDE_MPM_OUTPUT_STYLE.md +112 -0
- claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +186 -0
- claude_mpm/agents/MEMORY.md +72 -0
- claude_mpm/agents/PM_INSTRUCTIONS.md +1429 -0
- claude_mpm/agents/WORKFLOW.md +111 -0
- claude_mpm/agents/__init__.py +92 -80
- claude_mpm/agents/agent-template.yaml +83 -0
- claude_mpm/agents/agent_loader.py +560 -745
- claude_mpm/agents/agent_loader_integration.py +53 -55
- claude_mpm/agents/agents_metadata.py +186 -27
- claude_mpm/agents/async_agent_loader.py +436 -0
- claude_mpm/agents/base_agent.json +8 -4
- claude_mpm/agents/frontmatter_validator.py +754 -0
- claude_mpm/agents/system_agent_config.py +222 -155
- claude_mpm/agents/templates/README.md +465 -0
- claude_mpm/agents/templates/__init__.py +17 -13
- claude_mpm/agents/templates/circuit-breakers.md +1391 -0
- claude_mpm/agents/templates/context-management-examples.md +544 -0
- claude_mpm/agents/templates/git-file-tracking.md +584 -0
- claude_mpm/agents/templates/pm-examples.md +474 -0
- claude_mpm/agents/templates/pm-red-flags.md +310 -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/response-format.md +583 -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/agents/templates/validation-templates.md +312 -0
- claude_mpm/cli/__init__.py +94 -128
- claude_mpm/cli/__main__.py +33 -0
- claude_mpm/cli/chrome_devtools_installer.py +175 -0
- claude_mpm/cli/commands/__init__.py +36 -12
- claude_mpm/cli/commands/agent_manager.py +1403 -0
- claude_mpm/cli/commands/agent_source.py +774 -0
- claude_mpm/cli/commands/agent_state_manager.py +335 -0
- claude_mpm/cli/commands/agents.py +2501 -168
- claude_mpm/cli/commands/agents_cleanup.py +210 -0
- claude_mpm/cli/commands/agents_discover.py +338 -0
- claude_mpm/cli/commands/agents_reconcile.py +197 -0
- claude_mpm/cli/commands/aggregate.py +540 -0
- claude_mpm/cli/commands/analyze.py +553 -0
- claude_mpm/cli/commands/analyze_code.py +528 -0
- claude_mpm/cli/commands/auto_configure.py +1053 -0
- claude_mpm/cli/commands/cleanup.py +588 -0
- claude_mpm/cli/commands/cleanup_orphaned_agents.py +150 -0
- claude_mpm/cli/commands/config.py +586 -0
- claude_mpm/cli/commands/configure.py +3253 -0
- claude_mpm/cli/commands/configure_agent_display.py +282 -0
- claude_mpm/cli/commands/configure_behavior_manager.py +204 -0
- claude_mpm/cli/commands/configure_hook_manager.py +225 -0
- claude_mpm/cli/commands/configure_models.py +18 -0
- claude_mpm/cli/commands/configure_navigation.py +184 -0
- claude_mpm/cli/commands/configure_paths.py +104 -0
- claude_mpm/cli/commands/configure_persistence.py +254 -0
- claude_mpm/cli/commands/configure_startup_manager.py +646 -0
- claude_mpm/cli/commands/configure_template_editor.py +497 -0
- claude_mpm/cli/commands/configure_validators.py +73 -0
- claude_mpm/cli/commands/dashboard.py +286 -0
- claude_mpm/cli/commands/debug.py +1386 -0
- claude_mpm/cli/commands/doctor.py +243 -0
- claude_mpm/cli/commands/hook_errors.py +277 -0
- claude_mpm/cli/commands/info.py +195 -74
- claude_mpm/cli/commands/local_deploy.py +534 -0
- claude_mpm/cli/commands/mcp.py +205 -0
- claude_mpm/cli/commands/mcp_command_router.py +161 -0
- claude_mpm/cli/commands/mcp_config.py +154 -0
- claude_mpm/cli/commands/mcp_config_commands.py +20 -0
- claude_mpm/cli/commands/mcp_external_commands.py +249 -0
- claude_mpm/cli/commands/mcp_install_commands.py +346 -0
- claude_mpm/cli/commands/mcp_pipx_config.py +208 -0
- claude_mpm/cli/commands/mcp_server_commands.py +155 -0
- claude_mpm/cli/commands/mcp_setup_external.py +868 -0
- claude_mpm/cli/commands/mcp_tool_commands.py +34 -0
- claude_mpm/cli/commands/memory.py +585 -846
- claude_mpm/cli/commands/monitor.py +228 -310
- claude_mpm/cli/commands/mpm_init/__init__.py +73 -0
- claude_mpm/cli/commands/mpm_init/core.py +759 -0
- claude_mpm/cli/commands/mpm_init/display.py +341 -0
- claude_mpm/cli/commands/mpm_init/git_activity.py +427 -0
- claude_mpm/cli/commands/mpm_init/knowledge_extractor.py +481 -0
- claude_mpm/cli/commands/mpm_init/modes.py +397 -0
- claude_mpm/cli/commands/mpm_init/prompts.py +722 -0
- claude_mpm/cli/commands/mpm_init_cli.py +396 -0
- claude_mpm/cli/commands/mpm_init_handler.py +195 -0
- claude_mpm/cli/commands/postmortem.py +401 -0
- claude_mpm/cli/commands/profile.py +276 -0
- claude_mpm/cli/commands/run.py +910 -488
- claude_mpm/cli/commands/search.py +458 -0
- claude_mpm/cli/commands/skill_source.py +694 -0
- claude_mpm/cli/commands/skills.py +1398 -0
- claude_mpm/cli/commands/summarize.py +413 -0
- claude_mpm/cli/commands/tickets.py +536 -53
- claude_mpm/cli/commands/uninstall.py +176 -0
- claude_mpm/cli/commands/upgrade.py +152 -0
- claude_mpm/cli/commands/verify.py +119 -0
- claude_mpm/cli/executor.py +298 -0
- claude_mpm/cli/helpers.py +105 -0
- claude_mpm/cli/interactive/__init__.py +31 -0
- claude_mpm/cli/interactive/agent_wizard.py +1927 -0
- claude_mpm/cli/interactive/questionary_styles.py +65 -0
- claude_mpm/cli/interactive/skill_selector.py +481 -0
- claude_mpm/cli/interactive/skills_wizard.py +491 -0
- claude_mpm/cli/parser.py +87 -563
- claude_mpm/cli/parsers/__init__.py +35 -0
- claude_mpm/cli/parsers/agent_manager_parser.py +393 -0
- claude_mpm/cli/parsers/agent_source_parser.py +171 -0
- claude_mpm/cli/parsers/agents_parser.py +575 -0
- claude_mpm/cli/parsers/analyze_code_parser.py +170 -0
- claude_mpm/cli/parsers/analyze_parser.py +135 -0
- claude_mpm/cli/parsers/auto_configure_parser.py +120 -0
- claude_mpm/cli/parsers/base_parser.py +649 -0
- claude_mpm/cli/parsers/config_parser.py +208 -0
- claude_mpm/cli/parsers/configure_parser.py +138 -0
- claude_mpm/cli/parsers/dashboard_parser.py +113 -0
- claude_mpm/cli/parsers/debug_parser.py +319 -0
- claude_mpm/cli/parsers/local_deploy_parser.py +227 -0
- claude_mpm/cli/parsers/mcp_parser.py +195 -0
- claude_mpm/cli/parsers/memory_parser.py +138 -0
- claude_mpm/cli/parsers/monitor_parser.py +142 -0
- claude_mpm/cli/parsers/mpm_init_parser.py +311 -0
- claude_mpm/cli/parsers/profile_parser.py +147 -0
- claude_mpm/cli/parsers/run_parser.py +157 -0
- claude_mpm/cli/parsers/search_parser.py +245 -0
- claude_mpm/cli/parsers/skill_source_parser.py +169 -0
- claude_mpm/cli/parsers/skills_parser.py +277 -0
- claude_mpm/cli/parsers/source_parser.py +138 -0
- claude_mpm/cli/parsers/tickets_parser.py +203 -0
- claude_mpm/cli/shared/__init__.py +40 -0
- claude_mpm/cli/shared/argument_patterns.py +205 -0
- claude_mpm/cli/shared/base_command.py +242 -0
- claude_mpm/cli/shared/error_handling.py +242 -0
- claude_mpm/cli/shared/output_formatters.py +241 -0
- claude_mpm/cli/startup.py +1578 -0
- claude_mpm/cli/startup_display.py +480 -0
- claude_mpm/cli/startup_logging.py +839 -0
- claude_mpm/cli/utils.py +136 -47
- claude_mpm/cli_module/__init__.py +6 -6
- claude_mpm/cli_module/args.py +188 -140
- claude_mpm/cli_module/commands.py +79 -70
- claude_mpm/cli_module/migration_example.py +42 -64
- claude_mpm/commands/__init__.py +14 -0
- claude_mpm/commands/mpm-config.md +28 -0
- claude_mpm/commands/mpm-doctor.md +20 -0
- claude_mpm/commands/mpm-help.md +20 -0
- claude_mpm/commands/mpm-init.md +120 -0
- claude_mpm/commands/mpm-monitor.md +31 -0
- claude_mpm/commands/mpm-organize.md +120 -0
- claude_mpm/commands/mpm-postmortem.md +21 -0
- claude_mpm/commands/mpm-session-resume.md +30 -0
- claude_mpm/commands/mpm-status.md +20 -0
- claude_mpm/commands/mpm-ticket-view.md +109 -0
- claude_mpm/commands/mpm-version.md +20 -0
- claude_mpm/commands/mpm.md +31 -0
- claude_mpm/config/__init__.py +42 -2
- claude_mpm/config/agent_config.py +402 -0
- claude_mpm/config/agent_presets.py +488 -0
- claude_mpm/config/agent_sources.py +352 -0
- claude_mpm/config/experimental_features.py +217 -0
- claude_mpm/config/model_config.py +428 -0
- claude_mpm/config/paths.py +258 -0
- claude_mpm/config/skill_presets.py +392 -0
- claude_mpm/config/skill_sources.py +590 -0
- claude_mpm/config/socketio_config.py +125 -83
- claude_mpm/constants.py +133 -22
- claude_mpm/core/__init__.py +62 -36
- claude_mpm/core/agent_name_normalizer.py +71 -73
- claude_mpm/core/agent_registry.py +385 -492
- claude_mpm/core/agent_session_manager.py +81 -70
- claude_mpm/core/api_validator.py +330 -0
- claude_mpm/core/base_service.py +159 -122
- claude_mpm/core/cache.py +560 -0
- claude_mpm/core/claude_runner.py +696 -916
- claude_mpm/core/config.py +613 -122
- claude_mpm/core/config_aliases.py +74 -73
- claude_mpm/core/config_constants.py +314 -0
- claude_mpm/core/constants.py +361 -0
- claude_mpm/core/container.py +646 -104
- claude_mpm/core/enums.py +452 -0
- claude_mpm/core/error_handler.py +623 -0
- claude_mpm/core/exceptions.py +536 -0
- claude_mpm/core/factories.py +105 -109
- claude_mpm/core/file_utils.py +764 -0
- claude_mpm/core/framework/__init__.py +25 -0
- claude_mpm/core/framework/formatters/__init__.py +11 -0
- claude_mpm/core/framework/formatters/capability_generator.py +367 -0
- claude_mpm/core/framework/formatters/content_formatter.py +278 -0
- claude_mpm/core/framework/formatters/context_generator.py +185 -0
- claude_mpm/core/framework/loaders/__init__.py +13 -0
- claude_mpm/core/framework/loaders/agent_loader.py +213 -0
- claude_mpm/core/framework/loaders/file_loader.py +176 -0
- claude_mpm/core/framework/loaders/instruction_loader.py +222 -0
- claude_mpm/core/framework/loaders/packaged_loader.py +232 -0
- claude_mpm/core/framework/processors/__init__.py +11 -0
- claude_mpm/core/framework/processors/memory_processor.py +230 -0
- claude_mpm/core/framework/processors/metadata_processor.py +146 -0
- claude_mpm/core/framework/processors/template_processor.py +244 -0
- claude_mpm/core/framework_loader.py +485 -414
- claude_mpm/core/hook_error_memory.py +381 -0
- claude_mpm/core/hook_manager.py +246 -86
- claude_mpm/core/hook_performance_config.py +147 -0
- claude_mpm/core/injectable_service.py +72 -63
- claude_mpm/core/instruction_reinforcement_hook.py +267 -0
- claude_mpm/core/interactive_session.py +670 -0
- claude_mpm/core/interfaces.py +570 -164
- claude_mpm/core/lazy.py +467 -0
- claude_mpm/core/log_manager.py +707 -0
- claude_mpm/core/logger.py +295 -134
- claude_mpm/core/logging_config.py +474 -0
- claude_mpm/core/logging_utils.py +520 -0
- claude_mpm/core/minimal_framework_loader.py +24 -22
- claude_mpm/core/mixins.py +30 -29
- claude_mpm/core/oneshot_session.py +594 -0
- claude_mpm/core/optimized_agent_loader.py +479 -0
- claude_mpm/core/optimized_startup.py +554 -0
- claude_mpm/core/output_style_manager.py +491 -0
- claude_mpm/core/pm_hook_interceptor.py +197 -82
- 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/service_registry.py +153 -116
- claude_mpm/core/session_manager.py +179 -64
- claude_mpm/core/shared/__init__.py +17 -0
- claude_mpm/core/shared/config_loader.py +326 -0
- claude_mpm/core/shared/path_resolver.py +281 -0
- claude_mpm/core/shared/singleton_manager.py +221 -0
- claude_mpm/core/socketio_pool.py +400 -137
- claude_mpm/core/system_context.py +38 -0
- claude_mpm/core/tool_access_control.py +64 -57
- claude_mpm/core/types.py +307 -0
- claude_mpm/core/typing_utils.py +553 -0
- claude_mpm/core/unified_agent_registry.py +969 -0
- claude_mpm/core/unified_config.py +612 -0
- claude_mpm/core/unified_paths.py +958 -0
- claude_mpm/dashboard/__init__.py +12 -0
- claude_mpm/dashboard/api/simple_directory.py +261 -0
- claude_mpm/dashboard/static/svelte-build/_app/env.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.DWzvg0-y.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.ThTw9_ym.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/4TdZjIqw.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/5shd3_w0.js +24 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B0uc0UOD.js +36 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7RN905-.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7xVLGWV.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BIF9m_hv.js +61 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BKjSRqUr.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BPYeabCQ.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BQaXIfA_.js +331 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BSNlmTZj.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Be7GpZd6.js +7 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Bh0LDWpI.js +145 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BofRWZRR.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BovzEFCE.js +30 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C30mlcqg.js +165 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4B-KCzX.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4JcI4KD.js +122 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CBBdVcY8.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CDuw-vjf.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C_Usid8X.js +15 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cfqx1Qun.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CiIAseT4.js +128 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CmKTTxBW.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CnA0NrzZ.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cs_tUR18.js +24 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cu_Erd72.js +261 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CyWMqx4W.js +43 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzZX-COe.js +220 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzeYkLYB.js +65 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D3k0OPJN.js +4 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9lljYKQ.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DGkLK5U1.js +267 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DI7hHRFL.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DLVjFsZ3.js +139 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DUrLdbGD.js +89 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DVp1hx9R.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DY1XQ8fi.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DZX00Y4g.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Da0KfYnO.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DaimHw_p.js +68 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dfy6j1xT.js +323 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dhb8PKl3.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dle-35c7.js +64 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DmxopI1J.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DwBR2MJi.js +60 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/GYwsonyD.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Gi6I4Gst.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/NqQ1dWOy.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/RJiighC3.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Vzk33B_K.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/ZGh7QtNv.js +7 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bT1r9zLR.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bTOqqlTd.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/eNVUfhuA.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/iEWssX7S.js +162 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/sQeU3Y1z.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/uuIeMWc-.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.D6-I5TpK.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.NWzMBYRp.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/0.m1gL8KXf.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.CgNOuw-d.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.C0GcWctS.js +1 -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/dashboard-svelte/node_modules/katex/src/fonts/generate_fonts.py +58 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_tfms.py +114 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_ttfs.py +122 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/format_json.py +28 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/parse_tfm.py +211 -0
- claude_mpm/experimental/__init__.py +10 -0
- claude_mpm/experimental/cli_enhancements.py +104 -89
- claude_mpm/generators/__init__.py +1 -1
- claude_mpm/generators/agent_profile_generator.py +76 -66
- claude_mpm/hooks/__init__.py +37 -1
- claude_mpm/hooks/base_hook.py +37 -32
- claude_mpm/hooks/claude_hooks/__init__.py +1 -1
- claude_mpm/hooks/claude_hooks/connection_pool.py +250 -0
- claude_mpm/hooks/claude_hooks/correlation_manager.py +60 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +888 -0
- claude_mpm/hooks/claude_hooks/hook_handler.py +652 -875
- claude_mpm/hooks/claude_hooks/hook_wrapper.sh +10 -7
- claude_mpm/hooks/claude_hooks/installer.py +806 -0
- claude_mpm/hooks/claude_hooks/memory_integration.py +249 -0
- claude_mpm/hooks/claude_hooks/response_tracking.py +412 -0
- claude_mpm/hooks/claude_hooks/services/__init__.py +15 -0
- claude_mpm/hooks/claude_hooks/services/connection_manager.py +229 -0
- claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +254 -0
- claude_mpm/hooks/claude_hooks/services/duplicate_detector.py +106 -0
- claude_mpm/hooks/claude_hooks/services/state_manager.py +284 -0
- claude_mpm/hooks/claude_hooks/services/subagent_processor.py +374 -0
- claude_mpm/hooks/claude_hooks/tool_analysis.py +224 -0
- claude_mpm/hooks/failure_learning/__init__.py +54 -0
- claude_mpm/hooks/failure_learning/failure_detection_hook.py +230 -0
- claude_mpm/hooks/failure_learning/fix_detection_hook.py +212 -0
- claude_mpm/hooks/failure_learning/learning_extraction_hook.py +281 -0
- claude_mpm/hooks/instruction_reinforcement.py +301 -0
- claude_mpm/hooks/kuzu_enrichment_hook.py +263 -0
- claude_mpm/hooks/kuzu_memory_hook.py +386 -0
- claude_mpm/hooks/kuzu_response_hook.py +179 -0
- claude_mpm/hooks/memory_integration_hook.py +201 -107
- claude_mpm/hooks/session_resume_hook.py +121 -0
- claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
- claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
- claude_mpm/hooks/tool_call_interceptor.py +92 -76
- claude_mpm/hooks/validation_hooks.py +62 -54
- claude_mpm/init.py +518 -83
- claude_mpm/models/__init__.py +9 -9
- claude_mpm/models/agent_definition.py +40 -23
- claude_mpm/models/agent_session.py +538 -0
- claude_mpm/models/git_repository.py +198 -0
- claude_mpm/models/resume_log.py +340 -0
- claude_mpm/schemas/__init__.py +12 -0
- claude_mpm/scripts/__init__.py +15 -0
- claude_mpm/scripts/claude-hook-handler.sh +227 -0
- claude_mpm/scripts/launch_monitor.py +165 -0
- claude_mpm/scripts/mpm_doctor.py +322 -0
- claude_mpm/scripts/socketio_daemon.py +189 -200
- claude_mpm/scripts/start_activity_logging.py +91 -0
- claude_mpm/services/__init__.py +208 -39
- claude_mpm/services/agent_capabilities_service.py +266 -0
- claude_mpm/services/agents/__init__.py +89 -0
- claude_mpm/services/agents/agent_builder.py +514 -0
- 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_config_manager.py +796 -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/__init__.py +21 -0
- claude_mpm/services/agents/deployment/agent_config_provider.py +410 -0
- claude_mpm/services/agents/deployment/agent_configuration_manager.py +358 -0
- claude_mpm/services/agents/deployment/agent_definition_factory.py +80 -0
- claude_mpm/services/agents/deployment/agent_deployment.py +1037 -0
- claude_mpm/services/agents/deployment/agent_discovery_service.py +546 -0
- claude_mpm/services/agents/deployment/agent_environment_manager.py +288 -0
- claude_mpm/services/agents/deployment/agent_filesystem_manager.py +383 -0
- claude_mpm/services/agents/deployment/agent_format_converter.py +505 -0
- claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +160 -0
- claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +957 -0
- claude_mpm/services/agents/deployment/agent_metrics_collector.py +273 -0
- claude_mpm/services/agents/deployment/agent_operation_service.py +573 -0
- claude_mpm/services/agents/deployment/agent_record_service.py +418 -0
- claude_mpm/services/agents/deployment/agent_restore_handler.py +84 -0
- claude_mpm/services/agents/deployment/agent_state_service.py +381 -0
- claude_mpm/services/agents/deployment/agent_template_builder.py +1377 -0
- claude_mpm/services/agents/deployment/agent_validator.py +376 -0
- claude_mpm/services/agents/deployment/agent_version_manager.py +322 -0
- claude_mpm/services/{agent_versioning.py → agents/deployment/agent_versioning.py} +10 -13
- claude_mpm/services/agents/deployment/agents_directory_resolver.py +149 -0
- claude_mpm/services/agents/deployment/async_agent_deployment.py +768 -0
- claude_mpm/services/agents/deployment/base_agent_locator.py +132 -0
- claude_mpm/services/agents/deployment/config/__init__.py +13 -0
- claude_mpm/services/agents/deployment/config/deployment_config.py +181 -0
- claude_mpm/services/agents/deployment/config/deployment_config_manager.py +200 -0
- claude_mpm/services/agents/deployment/deployment_config_loader.py +178 -0
- claude_mpm/services/agents/deployment/deployment_reconciler.py +577 -0
- claude_mpm/services/agents/deployment/deployment_results_manager.py +185 -0
- claude_mpm/services/agents/deployment/deployment_type_detector.py +120 -0
- claude_mpm/services/agents/deployment/deployment_wrapper.py +129 -0
- claude_mpm/services/agents/deployment/facade/__init__.py +18 -0
- claude_mpm/services/agents/deployment/facade/async_deployment_executor.py +159 -0
- claude_mpm/services/agents/deployment/facade/deployment_executor.py +70 -0
- claude_mpm/services/agents/deployment/facade/deployment_facade.py +269 -0
- claude_mpm/services/agents/deployment/facade/sync_deployment_executor.py +178 -0
- claude_mpm/services/agents/deployment/interface_adapter.py +226 -0
- claude_mpm/services/agents/deployment/lifecycle_health_checker.py +85 -0
- claude_mpm/services/agents/deployment/lifecycle_performance_tracker.py +100 -0
- claude_mpm/services/agents/deployment/local_template_deployment.py +362 -0
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +1478 -0
- claude_mpm/services/agents/deployment/pipeline/__init__.py +32 -0
- claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +158 -0
- claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +162 -0
- claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +169 -0
- claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +19 -0
- claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +240 -0
- claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +110 -0
- claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +80 -0
- claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +92 -0
- claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +101 -0
- claude_mpm/services/agents/deployment/processors/__init__.py +15 -0
- claude_mpm/services/agents/deployment/processors/agent_deployment_context.py +102 -0
- claude_mpm/services/agents/deployment/processors/agent_deployment_result.py +235 -0
- claude_mpm/services/agents/deployment/processors/agent_processor.py +269 -0
- claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +311 -0
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +862 -0
- claude_mpm/services/agents/deployment/results/__init__.py +13 -0
- claude_mpm/services/agents/deployment/results/deployment_metrics.py +200 -0
- claude_mpm/services/agents/deployment/results/deployment_result_builder.py +249 -0
- claude_mpm/services/agents/deployment/single_agent_deployer.py +315 -0
- claude_mpm/services/agents/deployment/startup_reconciliation.py +138 -0
- claude_mpm/services/agents/deployment/strategies/__init__.py +25 -0
- claude_mpm/services/agents/deployment/strategies/base_strategy.py +113 -0
- claude_mpm/services/agents/deployment/strategies/project_strategy.py +148 -0
- claude_mpm/services/agents/deployment/strategies/strategy_selector.py +117 -0
- claude_mpm/services/agents/deployment/strategies/system_strategy.py +131 -0
- claude_mpm/services/agents/deployment/strategies/user_strategy.py +130 -0
- claude_mpm/services/agents/deployment/system_instructions_deployer.py +228 -0
- claude_mpm/services/agents/deployment/validation/__init__.py +21 -0
- claude_mpm/services/agents/deployment/validation/agent_validator.py +323 -0
- claude_mpm/services/agents/deployment/validation/deployment_validator.py +238 -0
- claude_mpm/services/agents/deployment/validation/template_validator.py +319 -0
- claude_mpm/services/agents/deployment/validation/validation_result.py +214 -0
- claude_mpm/services/agents/git_source_manager.py +682 -0
- claude_mpm/services/agents/loading/__init__.py +11 -0
- claude_mpm/services/{agent_profile_loader.py → agents/loading/agent_profile_loader.py} +306 -228
- claude_mpm/services/{base_agent_manager.py → agents/loading/base_agent_manager.py} +106 -91
- claude_mpm/services/agents/loading/framework_agent_loader.py +433 -0
- claude_mpm/services/agents/local_template_manager.py +784 -0
- claude_mpm/services/agents/management/__init__.py +9 -0
- claude_mpm/services/{agent_capabilities_generator.py → agents/management/agent_capabilities_generator.py} +92 -69
- claude_mpm/services/{agent_management_service.py → agents/management/agent_management_service.py} +219 -168
- claude_mpm/services/agents/memory/__init__.py +22 -0
- claude_mpm/services/agents/memory/agent_memory_manager.py +784 -0
- claude_mpm/services/{agent_persistence_service.py → agents/memory/agent_persistence_service.py} +20 -18
- claude_mpm/services/agents/memory/content_manager.py +470 -0
- claude_mpm/services/agents/memory/memory_categorization_service.py +167 -0
- claude_mpm/services/agents/memory/memory_file_service.py +129 -0
- claude_mpm/services/agents/memory/memory_format_service.py +201 -0
- claude_mpm/services/agents/memory/memory_limits_service.py +101 -0
- claude_mpm/services/agents/memory/template_generator.py +83 -0
- claude_mpm/services/agents/observers.py +547 -0
- claude_mpm/services/agents/recommender.py +617 -0
- claude_mpm/services/agents/registry/__init__.py +30 -0
- claude_mpm/services/agents/registry/deployed_agent_discovery.py +273 -0
- claude_mpm/services/{agent_modification_tracker.py → agents/registry/modification_tracker.py} +370 -295
- 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 +1205 -0
- claude_mpm/services/agents/startup_sync.py +262 -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/async_session_logger.py +665 -0
- claude_mpm/services/claude_session_logger.py +321 -0
- claude_mpm/services/cli/__init__.py +18 -0
- claude_mpm/services/cli/agent_cleanup_service.py +408 -0
- claude_mpm/services/cli/agent_dependency_service.py +395 -0
- claude_mpm/services/cli/agent_listing_service.py +463 -0
- claude_mpm/services/cli/agent_output_formatter.py +605 -0
- claude_mpm/services/cli/agent_validation_service.py +590 -0
- claude_mpm/services/cli/memory_crud_service.py +622 -0
- claude_mpm/services/cli/memory_output_formatter.py +604 -0
- claude_mpm/services/cli/resume_service.py +617 -0
- claude_mpm/services/cli/session_manager.py +604 -0
- claude_mpm/services/cli/session_pause_manager.py +504 -0
- claude_mpm/services/cli/session_resume_helper.py +372 -0
- claude_mpm/services/cli/startup_checker.py +362 -0
- claude_mpm/services/cli/unified_dashboard_manager.py +439 -0
- claude_mpm/services/command_deployment_service.py +446 -0
- claude_mpm/services/command_handler_service.py +221 -0
- claude_mpm/services/communication/__init__.py +22 -0
- claude_mpm/services/core/__init__.py +108 -0
- claude_mpm/services/core/base.py +269 -0
- claude_mpm/services/core/cache_manager.py +309 -0
- claude_mpm/services/core/interfaces/__init__.py +273 -0
- claude_mpm/services/core/interfaces/agent.py +514 -0
- claude_mpm/services/core/interfaces/communication.py +316 -0
- claude_mpm/services/core/interfaces/health.py +169 -0
- claude_mpm/services/core/interfaces/infrastructure.py +357 -0
- claude_mpm/services/core/interfaces/model.py +281 -0
- claude_mpm/services/core/interfaces/process.py +372 -0
- claude_mpm/services/core/interfaces/project.py +121 -0
- claude_mpm/services/core/interfaces/restart.py +307 -0
- claude_mpm/services/core/interfaces/service.py +405 -0
- claude_mpm/services/core/interfaces/stability.py +260 -0
- claude_mpm/services/core/interfaces.py +81 -0
- claude_mpm/services/core/memory_manager.py +682 -0
- claude_mpm/services/core/models/__init__.py +70 -0
- claude_mpm/services/core/models/agent_config.py +384 -0
- claude_mpm/services/core/models/health.py +162 -0
- claude_mpm/services/core/models/process.py +239 -0
- claude_mpm/services/core/models/restart.py +302 -0
- claude_mpm/services/core/models/stability.py +264 -0
- claude_mpm/services/core/models/toolchain.py +306 -0
- claude_mpm/services/core/path_resolver.py +517 -0
- claude_mpm/services/core/service_container.py +520 -0
- claude_mpm/services/core/service_interfaces.py +436 -0
- claude_mpm/services/diagnostics/__init__.py +18 -0
- claude_mpm/services/diagnostics/checks/__init__.py +38 -0
- claude_mpm/services/diagnostics/checks/agent_check.py +370 -0
- claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
- claude_mpm/services/diagnostics/checks/base_check.py +60 -0
- claude_mpm/services/diagnostics/checks/claude_code_check.py +270 -0
- claude_mpm/services/diagnostics/checks/common_issues_check.py +363 -0
- claude_mpm/services/diagnostics/checks/configuration_check.py +306 -0
- claude_mpm/services/diagnostics/checks/filesystem_check.py +233 -0
- claude_mpm/services/diagnostics/checks/installation_check.py +520 -0
- claude_mpm/services/diagnostics/checks/instructions_check.py +415 -0
- claude_mpm/services/diagnostics/checks/mcp_check.py +330 -0
- claude_mpm/services/diagnostics/checks/mcp_services_check.py +1058 -0
- claude_mpm/services/diagnostics/checks/monitor_check.py +281 -0
- claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
- claude_mpm/services/diagnostics/checks/startup_log_check.py +319 -0
- claude_mpm/services/diagnostics/diagnostic_runner.py +286 -0
- claude_mpm/services/diagnostics/doctor_reporter.py +578 -0
- claude_mpm/services/diagnostics/models.py +138 -0
- claude_mpm/services/event_aggregator.py +582 -0
- claude_mpm/services/event_bus/__init__.py +18 -0
- claude_mpm/services/event_bus/config.py +186 -0
- claude_mpm/services/event_bus/direct_relay.py +312 -0
- claude_mpm/services/event_bus/event_bus.py +396 -0
- claude_mpm/services/event_bus/relay.py +326 -0
- claude_mpm/services/events/__init__.py +44 -0
- claude_mpm/services/events/consumers/__init__.py +18 -0
- claude_mpm/services/events/consumers/dead_letter.py +306 -0
- claude_mpm/services/events/consumers/logging.py +184 -0
- claude_mpm/services/events/consumers/metrics.py +241 -0
- claude_mpm/services/events/consumers/socketio.py +377 -0
- claude_mpm/services/events/core.py +480 -0
- claude_mpm/services/events/interfaces.py +214 -0
- claude_mpm/services/events/producers/__init__.py +14 -0
- claude_mpm/services/events/producers/hook.py +269 -0
- claude_mpm/services/events/producers/system.py +329 -0
- claude_mpm/services/exceptions.py +433 -353
- claude_mpm/services/framework_claude_md_generator/__init__.py +81 -80
- claude_mpm/services/framework_claude_md_generator/content_assembler.py +74 -67
- claude_mpm/services/framework_claude_md_generator/content_validator.py +66 -62
- claude_mpm/services/framework_claude_md_generator/deployment_manager.py +82 -60
- claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +36 -37
- claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +41 -40
- claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +15 -15
- claude_mpm/services/framework_claude_md_generator/section_generators/core_responsibilities.py +5 -4
- claude_mpm/services/framework_claude_md_generator/section_generators/delegation_constraints.py +4 -3
- claude_mpm/services/framework_claude_md_generator/section_generators/environment_config.py +4 -3
- claude_mpm/services/framework_claude_md_generator/section_generators/footer.py +6 -5
- claude_mpm/services/framework_claude_md_generator/section_generators/header.py +8 -7
- claude_mpm/services/framework_claude_md_generator/section_generators/orchestration_principles.py +5 -4
- claude_mpm/services/framework_claude_md_generator/section_generators/role_designation.py +6 -5
- claude_mpm/services/framework_claude_md_generator/section_generators/subprocess_validation.py +9 -8
- claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +26 -30
- claude_mpm/services/framework_claude_md_generator/section_generators/troubleshooting.py +6 -5
- claude_mpm/services/framework_claude_md_generator/section_manager.py +28 -27
- claude_mpm/services/framework_claude_md_generator/version_manager.py +31 -30
- 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/hook_installer_service.py +506 -0
- claude_mpm/services/hook_service.py +159 -111
- claude_mpm/services/infrastructure/__init__.py +52 -0
- claude_mpm/services/infrastructure/context_preservation.py +569 -0
- claude_mpm/services/infrastructure/daemon_manager.py +279 -0
- claude_mpm/services/infrastructure/logging.py +209 -0
- claude_mpm/services/infrastructure/monitoring/__init__.py +39 -0
- claude_mpm/services/infrastructure/monitoring/aggregator.py +432 -0
- claude_mpm/services/infrastructure/monitoring/base.py +122 -0
- claude_mpm/services/infrastructure/monitoring/legacy.py +203 -0
- claude_mpm/services/infrastructure/monitoring/network.py +219 -0
- claude_mpm/services/infrastructure/monitoring/process.py +343 -0
- claude_mpm/services/infrastructure/monitoring/resources.py +244 -0
- claude_mpm/services/infrastructure/monitoring/service.py +368 -0
- claude_mpm/services/infrastructure/monitoring.py +71 -0
- claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
- 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 +155 -0
- claude_mpm/services/local_ops/crash_detector.py +257 -0
- claude_mpm/services/local_ops/health_checks/__init__.py +26 -0
- claude_mpm/services/local_ops/health_checks/http_check.py +224 -0
- claude_mpm/services/local_ops/health_checks/process_check.py +236 -0
- claude_mpm/services/local_ops/health_checks/resource_check.py +255 -0
- claude_mpm/services/local_ops/health_manager.py +427 -0
- claude_mpm/services/local_ops/log_monitor.py +396 -0
- claude_mpm/services/local_ops/memory_leak_detector.py +294 -0
- claude_mpm/services/local_ops/process_manager.py +595 -0
- claude_mpm/services/local_ops/resource_monitor.py +331 -0
- claude_mpm/services/local_ops/restart_manager.py +401 -0
- claude_mpm/services/local_ops/restart_policy.py +387 -0
- claude_mpm/services/local_ops/state_manager.py +372 -0
- claude_mpm/services/local_ops/unified_manager.py +600 -0
- claude_mpm/services/mcp_config_manager.py +1542 -0
- claude_mpm/services/mcp_service_verifier.py +732 -0
- claude_mpm/services/memory/__init__.py +19 -0
- claude_mpm/services/{memory_builder.py → memory/builder.py} +465 -373
- claude_mpm/services/memory/cache/__init__.py +14 -0
- claude_mpm/services/{shared_prompt_cache.py → memory/cache/shared_prompt_cache.py} +237 -200
- claude_mpm/services/memory/cache/simple_cache.py +331 -0
- claude_mpm/services/memory/failure_tracker.py +578 -0
- claude_mpm/services/memory/indexed_memory.py +648 -0
- claude_mpm/services/{memory_optimizer.py → memory/optimizer.py} +272 -243
- claude_mpm/services/memory/router.py +951 -0
- claude_mpm/services/memory_hook_service.py +470 -0
- claude_mpm/services/model/__init__.py +147 -0
- claude_mpm/services/model/base_provider.py +365 -0
- claude_mpm/services/model/claude_provider.py +412 -0
- claude_mpm/services/model/model_router.py +452 -0
- claude_mpm/services/model/ollama_provider.py +415 -0
- claude_mpm/services/monitor/__init__.py +20 -0
- claude_mpm/services/monitor/daemon.py +698 -0
- claude_mpm/services/monitor/daemon_manager.py +1076 -0
- claude_mpm/services/monitor/event_emitter.py +350 -0
- claude_mpm/services/monitor/handlers/__init__.py +21 -0
- claude_mpm/services/monitor/handlers/code_analysis.py +332 -0
- claude_mpm/services/monitor/handlers/dashboard.py +299 -0
- claude_mpm/services/monitor/handlers/file.py +264 -0
- claude_mpm/services/monitor/handlers/hooks.py +512 -0
- claude_mpm/services/monitor/management/__init__.py +18 -0
- claude_mpm/services/monitor/management/health.py +124 -0
- claude_mpm/services/monitor/management/lifecycle.py +730 -0
- claude_mpm/services/monitor/server.py +1493 -0
- claude_mpm/services/monitor_build_service.py +349 -0
- claude_mpm/services/native_agent_converter.py +356 -0
- claude_mpm/services/orphan_detection.py +786 -0
- claude_mpm/services/pm_skills_deployer.py +711 -0
- claude_mpm/services/port_manager.py +597 -0
- claude_mpm/services/pr/__init__.py +14 -0
- claude_mpm/services/pr/pr_template_service.py +329 -0
- claude_mpm/services/profile_manager.py +337 -0
- claude_mpm/services/project/__init__.py +44 -0
- claude_mpm/services/{project_analyzer.py → project/analyzer.py} +541 -291
- claude_mpm/services/project/analyzer_v2.py +566 -0
- claude_mpm/services/project/architecture_analyzer.py +461 -0
- claude_mpm/services/project/archive_manager.py +1045 -0
- claude_mpm/services/project/dependency_analyzer.py +462 -0
- claude_mpm/services/project/detection_strategies.py +719 -0
- claude_mpm/services/project/documentation_manager.py +554 -0
- claude_mpm/services/project/enhanced_analyzer.py +572 -0
- claude_mpm/services/project/language_analyzer.py +265 -0
- claude_mpm/services/project/metrics_collector.py +407 -0
- claude_mpm/services/project/project_organizer.py +1009 -0
- claude_mpm/services/project/registry.py +636 -0
- claude_mpm/services/project/toolchain_analyzer.py +583 -0
- claude_mpm/services/project_port_allocator.py +596 -0
- claude_mpm/services/recovery_manager.py +293 -240
- claude_mpm/services/response_tracker.py +267 -0
- claude_mpm/services/runner_configuration_service.py +605 -0
- claude_mpm/services/self_upgrade_service.py +608 -0
- claude_mpm/services/session_management_service.py +314 -0
- claude_mpm/services/session_manager.py +380 -0
- claude_mpm/services/shared/__init__.py +21 -0
- claude_mpm/services/shared/async_service_base.py +216 -0
- claude_mpm/services/shared/config_service_base.py +301 -0
- claude_mpm/services/shared/lifecycle_service_base.py +308 -0
- claude_mpm/services/shared/manager_base.py +315 -0
- claude_mpm/services/shared/service_factory.py +309 -0
- claude_mpm/services/skills/__init__.py +21 -0
- claude_mpm/services/skills/git_skill_source_manager.py +1340 -0
- claude_mpm/services/skills/selective_skill_deployer.py +743 -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 +1168 -0
- claude_mpm/services/socketio/__init__.py +25 -0
- claude_mpm/services/socketio/client_proxy.py +229 -0
- claude_mpm/services/socketio/dashboard_server.py +362 -0
- claude_mpm/services/socketio/event_normalizer.py +798 -0
- claude_mpm/services/socketio/handlers/__init__.py +30 -0
- claude_mpm/services/socketio/handlers/base.py +136 -0
- claude_mpm/services/socketio/handlers/code_analysis.py +682 -0
- claude_mpm/services/socketio/handlers/connection.py +643 -0
- claude_mpm/services/socketio/handlers/connection_handler.py +333 -0
- claude_mpm/services/socketio/handlers/file.py +263 -0
- claude_mpm/services/socketio/handlers/git.py +962 -0
- claude_mpm/services/socketio/handlers/hook.py +211 -0
- claude_mpm/services/socketio/handlers/memory.py +26 -0
- claude_mpm/services/socketio/handlers/project.py +24 -0
- claude_mpm/services/socketio/handlers/registry.py +214 -0
- claude_mpm/services/socketio/migration_utils.py +343 -0
- claude_mpm/services/socketio/monitor_client.py +364 -0
- claude_mpm/services/socketio/server/__init__.py +18 -0
- claude_mpm/services/socketio/server/broadcaster.py +569 -0
- claude_mpm/services/socketio/server/connection_manager.py +579 -0
- claude_mpm/services/socketio/server/core.py +1079 -0
- claude_mpm/services/socketio/server/eventbus_integration.py +245 -0
- claude_mpm/services/socketio/server/main.py +501 -0
- claude_mpm/services/socketio_client_manager.py +173 -143
- claude_mpm/services/socketio_server.py +38 -1657
- claude_mpm/services/subprocess_launcher_service.py +322 -0
- claude_mpm/services/system_instructions_service.py +270 -0
- claude_mpm/services/ticket_manager.py +25 -209
- claude_mpm/services/ticket_services/__init__.py +26 -0
- claude_mpm/services/ticket_services/crud_service.py +328 -0
- claude_mpm/services/ticket_services/formatter_service.py +290 -0
- claude_mpm/services/ticket_services/search_service.py +324 -0
- claude_mpm/services/ticket_services/validation_service.py +303 -0
- claude_mpm/services/ticket_services/workflow_service.py +244 -0
- claude_mpm/services/unified/__init__.py +65 -0
- claude_mpm/services/unified/analyzer_strategies/__init__.py +44 -0
- claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +518 -0
- claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +680 -0
- claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +900 -0
- claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +745 -0
- claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +733 -0
- claude_mpm/services/unified/config_strategies/__init__.py +175 -0
- claude_mpm/services/unified/config_strategies/config_schema.py +731 -0
- claude_mpm/services/unified/config_strategies/context_strategy.py +747 -0
- claude_mpm/services/unified/config_strategies/error_handling_strategy.py +1005 -0
- claude_mpm/services/unified/config_strategies/file_loader_strategy.py +881 -0
- claude_mpm/services/unified/config_strategies/unified_config_service.py +823 -0
- claude_mpm/services/unified/config_strategies/validation_strategy.py +1148 -0
- claude_mpm/services/unified/deployment_strategies/__init__.py +97 -0
- claude_mpm/services/unified/deployment_strategies/base.py +553 -0
- claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +573 -0
- claude_mpm/services/unified/deployment_strategies/local.py +607 -0
- claude_mpm/services/unified/deployment_strategies/utils.py +667 -0
- claude_mpm/services/unified/deployment_strategies/vercel.py +471 -0
- claude_mpm/services/unified/interfaces.py +475 -0
- claude_mpm/services/unified/migration.py +509 -0
- claude_mpm/services/unified/strategies.py +534 -0
- claude_mpm/services/unified/unified_analyzer.py +542 -0
- claude_mpm/services/unified/unified_config.py +691 -0
- claude_mpm/services/unified/unified_deployment.py +466 -0
- claude_mpm/services/utility_service.py +280 -0
- claude_mpm/services/version_control/__init__.py +34 -37
- claude_mpm/services/version_control/branch_strategy.py +26 -17
- claude_mpm/services/version_control/conflict_resolution.py +52 -36
- claude_mpm/services/version_control/git_operations.py +183 -49
- claude_mpm/services/version_control/semantic_versioning.py +172 -61
- claude_mpm/services/version_control/version_parser.py +546 -0
- claude_mpm/services/version_service.py +379 -0
- claude_mpm/services/visualization/__init__.py +15 -0
- claude_mpm/services/visualization/mermaid_generator.py +937 -0
- claude_mpm/skills/__init__.py +42 -0
- claude_mpm/skills/agent_skills_injector.py +324 -0
- claude_mpm/skills/bundled/LICENSE_ATTRIBUTIONS.md +79 -0
- claude_mpm/skills/bundled/__init__.py +6 -0
- claude_mpm/skills/bundled/api-documentation.md +393 -0
- claude_mpm/skills/bundled/async-testing.md +571 -0
- claude_mpm/skills/bundled/code-review.md +143 -0
- claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
- claude_mpm/skills/bundled/collaboration/git-worktrees.md +317 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
- claude_mpm/skills/bundled/collaboration/stacked-prs.md +251 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
- claude_mpm/skills/bundled/database-migration.md +199 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
- claude_mpm/skills/bundled/docker-containerization.md +194 -0
- claude_mpm/skills/bundled/express-local-dev.md +1429 -0
- claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
- claude_mpm/skills/bundled/git-workflow.md +414 -0
- claude_mpm/skills/bundled/imagemagick.md +204 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/INTEGRATION.md +611 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/README.md +596 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/SKILL.md +260 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/examples/nextjs-env-structure.md +315 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/frameworks.md +436 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/security.md +433 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/synchronization.md +452 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/troubleshooting.md +404 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/validation.md +420 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
- claude_mpm/skills/bundled/json-data-handling.md +223 -0
- claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
- claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
- claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
- claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +157 -0
- claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +425 -0
- claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
- claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
- claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
- claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
- claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
- claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +303 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +113 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +72 -0
- claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
- claude_mpm/skills/bundled/pdf.md +141 -0
- claude_mpm/skills/bundled/performance-profiling.md +573 -0
- claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
- claude_mpm/skills/bundled/pm/pm-bug-reporting/pm-bug-reporting.md +248 -0
- claude_mpm/skills/bundled/pm/pm-delegation-patterns/SKILL.md +167 -0
- claude_mpm/skills/bundled/pm/pm-git-file-tracking/SKILL.md +113 -0
- claude_mpm/skills/bundled/pm/pm-pr-workflow/SKILL.md +124 -0
- claude_mpm/skills/bundled/pm/pm-teaching-mode/SKILL.md +657 -0
- claude_mpm/skills/bundled/pm/pm-ticketing-integration/SKILL.md +154 -0
- claude_mpm/skills/bundled/pm/pm-verification-protocols/SKILL.md +198 -0
- claude_mpm/skills/bundled/react/flexlayout-react.md +742 -0
- claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
- claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
- claude_mpm/skills/bundled/security-scanning.md +439 -0
- claude_mpm/skills/bundled/systematic-debugging.md +473 -0
- claude_mpm/skills/bundled/tauri/tauri-async-patterns.md +495 -0
- claude_mpm/skills/bundled/tauri/tauri-build-deploy.md +599 -0
- claude_mpm/skills/bundled/tauri/tauri-command-patterns.md +535 -0
- claude_mpm/skills/bundled/tauri/tauri-error-handling.md +613 -0
- claude_mpm/skills/bundled/tauri/tauri-event-system.md +648 -0
- claude_mpm/skills/bundled/tauri/tauri-file-system.md +673 -0
- claude_mpm/skills/bundled/tauri/tauri-frontend-integration.md +767 -0
- claude_mpm/skills/bundled/tauri/tauri-performance.md +669 -0
- claude_mpm/skills/bundled/tauri/tauri-state-management.md +573 -0
- claude_mpm/skills/bundled/tauri/tauri-testing.md +384 -0
- claude_mpm/skills/bundled/tauri/tauri-window-management.md +628 -0
- claude_mpm/skills/bundled/test-driven-development.md +378 -0
- claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
- claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
- claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/SKILL.md +458 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/examples/example-inspection-report.md +411 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/assertion-quality.md +317 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/inspection-checklist.md +270 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/red-flags.md +436 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
- claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
- claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +35 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +44 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +34 -0
- claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
- claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
- claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +129 -0
- claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
- claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
- claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
- claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
- claude_mpm/skills/bundled/xlsx.md +157 -0
- claude_mpm/skills/registry.py +286 -0
- claude_mpm/skills/skill_manager.py +405 -0
- claude_mpm/skills/skills_registry.py +347 -0
- claude_mpm/skills/skills_service.py +739 -0
- claude_mpm/storage/__init__.py +9 -0
- claude_mpm/storage/state_storage.py +546 -0
- claude_mpm/templates/.pre-commit-config.yaml +112 -0
- 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/ticket_wrapper.py +2 -2
- claude_mpm/tools/__init__.py +10 -0
- claude_mpm/tools/__main__.py +208 -0
- claude_mpm/tools/code_tree_analyzer/__init__.py +45 -0
- claude_mpm/tools/code_tree_analyzer/analysis.py +299 -0
- claude_mpm/tools/code_tree_analyzer/cache.py +131 -0
- claude_mpm/tools/code_tree_analyzer/core.py +380 -0
- claude_mpm/tools/code_tree_analyzer/discovery.py +403 -0
- claude_mpm/tools/code_tree_analyzer/events.py +168 -0
- claude_mpm/tools/code_tree_analyzer/gitignore.py +308 -0
- claude_mpm/tools/code_tree_analyzer/models.py +39 -0
- claude_mpm/tools/code_tree_analyzer/multilang_analyzer.py +224 -0
- claude_mpm/tools/code_tree_analyzer/python_analyzer.py +284 -0
- claude_mpm/tools/code_tree_builder.py +631 -0
- claude_mpm/tools/code_tree_events.py +420 -0
- claude_mpm/tools/socketio_debug.py +671 -0
- claude_mpm/utils/__init__.py +8 -8
- claude_mpm/utils/agent_dependency_loader.py +1189 -0
- claude_mpm/utils/agent_filters.py +261 -0
- claude_mpm/utils/common.py +544 -0
- claude_mpm/utils/config_manager.py +168 -126
- claude_mpm/utils/console.py +11 -0
- claude_mpm/utils/database_connector.py +298 -0
- claude_mpm/utils/dependency_cache.py +373 -0
- claude_mpm/utils/dependency_manager.py +60 -59
- claude_mpm/utils/dependency_strategies.py +381 -0
- claude_mpm/utils/display_helper.py +260 -0
- claude_mpm/utils/environment_context.py +313 -0
- claude_mpm/utils/error_handler.py +78 -66
- claude_mpm/utils/file_utils.py +305 -0
- claude_mpm/utils/framework_detection.py +12 -11
- claude_mpm/utils/git_analyzer.py +407 -0
- claude_mpm/utils/gitignore.py +244 -0
- claude_mpm/utils/import_migration_example.py +12 -60
- claude_mpm/utils/imports.py +48 -45
- claude_mpm/utils/log_cleanup.py +627 -0
- claude_mpm/utils/migration.py +372 -0
- claude_mpm/utils/path_operations.py +110 -104
- claude_mpm/utils/progress.py +387 -0
- claude_mpm/utils/robust_installer.py +844 -0
- claude_mpm/utils/session_logging.py +121 -0
- claude_mpm/utils/structured_questions.py +619 -0
- claude_mpm/utils/subprocess_utils.py +343 -0
- claude_mpm/validation/__init__.py +1 -1
- claude_mpm/validation/agent_validator.py +214 -108
- claude_mpm/validation/frontmatter_validator.py +252 -0
- claude_mpm-5.4.85.dist-info/METADATA +1023 -0
- claude_mpm-5.4.85.dist-info/RECORD +980 -0
- {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.85.dist-info}/entry_points.txt +1 -3
- claude_mpm-5.4.85.dist-info/licenses/LICENSE +94 -0
- claude_mpm-5.4.85.dist-info/licenses/LICENSE-FAQ.md +153 -0
- claude_mpm/agents/BASE_AGENT_TEMPLATE.md +0 -88
- claude_mpm/agents/INSTRUCTIONS.md +0 -352
- claude_mpm/agents/backups/INSTRUCTIONS.md +0 -352
- claude_mpm/agents/base_agent_loader.py +0 -529
- claude_mpm/agents/schema/agent_schema.json +0 -314
- claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -36
- claude_mpm/agents/templates/backup/data_engineer_agent_20250726_234551.json +0 -46
- claude_mpm/agents/templates/backup/documentation_agent_20250726_234551.json +0 -45
- claude_mpm/agents/templates/backup/engineer_agent_20250726_234551.json +0 -49
- claude_mpm/agents/templates/backup/ops_agent_20250726_234551.json +0 -46
- claude_mpm/agents/templates/backup/qa_agent_20250726_234551.json +0 -45
- claude_mpm/agents/templates/backup/research_agent_20250726_234551.json +0 -49
- claude_mpm/agents/templates/backup/security_agent_20250726_234551.json +0 -46
- claude_mpm/agents/templates/backup/version_control_agent_20250726_234551.json +0 -46
- claude_mpm/agents/templates/data_engineer.json +0 -110
- claude_mpm/agents/templates/documentation.json +0 -109
- claude_mpm/agents/templates/engineer.json +0 -113
- claude_mpm/agents/templates/ops.json +0 -109
- claude_mpm/agents/templates/pm.json +0 -25
- claude_mpm/agents/templates/qa.json +0 -111
- claude_mpm/agents/templates/research.json +0 -65
- claude_mpm/agents/templates/security.json +0 -113
- claude_mpm/agents/templates/test_integration.json +0 -112
- claude_mpm/agents/templates/version_control.json +0 -107
- claude_mpm/cli/commands/ui.py +0 -57
- claude_mpm/core/simple_runner.py +0 -1046
- claude_mpm/dashboard/open_dashboard.py +0 -34
- claude_mpm/deployment_paths.py +0 -261
- claude_mpm/hooks/builtin/__init__.py +0 -1
- claude_mpm/hooks/builtin/logging_hook_example.py +0 -165
- claude_mpm/hooks/builtin/memory_hooks_example.py +0 -67
- claude_mpm/hooks/builtin/mpm_command_hook.py +0 -125
- claude_mpm/hooks/builtin/post_delegation_hook_example.py +0 -124
- claude_mpm/hooks/builtin/pre_delegation_hook_example.py +0 -125
- claude_mpm/hooks/builtin/submit_hook_example.py +0 -100
- claude_mpm/hooks/builtin/ticket_extraction_hook_example.py +0 -237
- claude_mpm/hooks/builtin/todo_agent_prefix_hook.py +0 -240
- claude_mpm/hooks/builtin/workflow_start_hook.py +0 -181
- claude_mpm/orchestration/__init__.py +0 -6
- claude_mpm/orchestration/archive/direct_orchestrator.py +0 -195
- claude_mpm/orchestration/archive/factory.py +0 -215
- claude_mpm/orchestration/archive/hook_enabled_orchestrator.py +0 -188
- claude_mpm/orchestration/archive/hook_integration_example.py +0 -178
- claude_mpm/orchestration/archive/interactive_subprocess_orchestrator.py +0 -826
- claude_mpm/orchestration/archive/orchestrator.py +0 -501
- claude_mpm/orchestration/archive/pexpect_orchestrator.py +0 -252
- claude_mpm/orchestration/archive/pty_orchestrator.py +0 -270
- claude_mpm/orchestration/archive/simple_orchestrator.py +0 -82
- claude_mpm/orchestration/archive/subprocess_orchestrator.py +0 -801
- claude_mpm/orchestration/archive/system_prompt_orchestrator.py +0 -278
- claude_mpm/orchestration/archive/wrapper_orchestrator.py +0 -187
- claude_mpm/schemas/workflow_validator.py +0 -411
- claude_mpm/services/agent_deployment.py +0 -1534
- claude_mpm/services/agent_lifecycle_manager.py +0 -1169
- claude_mpm/services/agent_memory_manager.py +0 -1415
- claude_mpm/services/agent_registry.py +0 -676
- claude_mpm/services/deployed_agent_discovery.py +0 -226
- claude_mpm/services/framework_agent_loader.py +0 -337
- claude_mpm/services/framework_claude_md_generator.py +0 -621
- claude_mpm/services/health_monitor.py +0 -892
- claude_mpm/services/memory_router.py +0 -538
- claude_mpm/services/parent_directory_manager/__init__.py +0 -577
- claude_mpm/services/parent_directory_manager/backup_manager.py +0 -258
- claude_mpm/services/parent_directory_manager/config_manager.py +0 -210
- claude_mpm/services/parent_directory_manager/deduplication_manager.py +0 -279
- claude_mpm/services/parent_directory_manager/framework_protector.py +0 -143
- claude_mpm/services/parent_directory_manager/operations.py +0 -186
- claude_mpm/services/parent_directory_manager/state_manager.py +0 -624
- claude_mpm/services/parent_directory_manager/template_deployer.py +0 -579
- claude_mpm/services/parent_directory_manager/validation_manager.py +0 -378
- claude_mpm/services/parent_directory_manager/version_control_helper.py +0 -339
- claude_mpm/services/parent_directory_manager/version_manager.py +0 -222
- claude_mpm/services/standalone_socketio_server.py +0 -1300
- claude_mpm/services/ticket_manager_di.py +0 -318
- claude_mpm/services/ticketing_service_original.py +0 -508
- claude_mpm/ui/__init__.py +0 -1
- claude_mpm/ui/rich_terminal_ui.py +0 -295
- claude_mpm/ui/terminal_ui.py +0 -328
- claude_mpm/utils/paths.py +0 -289
- claude_mpm-3.4.10.dist-info/METADATA +0 -183
- claude_mpm-3.4.10.dist-info/RECORD +0 -201
- claude_mpm-3.4.10.dist-info/licenses/LICENSE +0 -21
- {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.85.dist-info}/WHEEL +0 -0
- {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.85.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,862 @@
|
|
|
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
|
+
import yaml
|
|
19
|
+
|
|
20
|
+
from claude_mpm.core.logging_config import get_logger
|
|
21
|
+
|
|
22
|
+
logger = get_logger(__name__)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@dataclass
|
|
26
|
+
class RemoteAgentMetadata:
|
|
27
|
+
"""Metadata extracted from remote agent Markdown file."""
|
|
28
|
+
|
|
29
|
+
name: str
|
|
30
|
+
description: str
|
|
31
|
+
model: str
|
|
32
|
+
routing_keywords: List[str]
|
|
33
|
+
routing_paths: List[str]
|
|
34
|
+
routing_priority: int
|
|
35
|
+
source_file: Path
|
|
36
|
+
version: str # SHA-256 hash from cache metadata
|
|
37
|
+
collection_id: Optional[str] = None # Format: owner/repo-name
|
|
38
|
+
source_path: Optional[str] = None # Relative path in repo
|
|
39
|
+
canonical_id: Optional[str] = None # Format: collection_id:agent_id
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class RemoteAgentDiscoveryService:
|
|
43
|
+
"""Discovers and converts remote Markdown agents to JSON format.
|
|
44
|
+
|
|
45
|
+
Remote agents are discovered from the cache directory (~/.claude-mpm/cache/agents/)
|
|
46
|
+
where they are stored as Markdown files. This service:
|
|
47
|
+
1. Discovers all *.md files in the remote agents cache
|
|
48
|
+
2. Parses Markdown frontmatter and content to extract metadata
|
|
49
|
+
3. Converts to JSON template format for deployment
|
|
50
|
+
4. Retrieves version (SHA-256 hash) from cache metadata
|
|
51
|
+
|
|
52
|
+
Design Decision: Markdown Parsing Strategy
|
|
53
|
+
- Use regex for simple frontmatter extraction (fast, no dependencies)
|
|
54
|
+
- Parse key-value pairs from Configuration section
|
|
55
|
+
- Extract routing info from Routing section
|
|
56
|
+
- Fallback to sensible defaults when sections are missing
|
|
57
|
+
|
|
58
|
+
Trade-offs:
|
|
59
|
+
- Performance: Regex parsing is fast for our simple format
|
|
60
|
+
- Maintainability: Clear regex patterns are easy to understand
|
|
61
|
+
- Flexibility: Supports optional sections with defaults
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
def __init__(self, agents_cache_dir: Path):
|
|
65
|
+
"""Initialize the remote agent discovery service.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
agents_cache_dir: Directory containing cached agent Markdown files
|
|
69
|
+
"""
|
|
70
|
+
self.agents_cache_dir = agents_cache_dir
|
|
71
|
+
self.logger = get_logger(__name__)
|
|
72
|
+
|
|
73
|
+
def _extract_collection_id_from_path(self, file_path: Path) -> Optional[str]:
|
|
74
|
+
"""Extract collection_id from repository path structure.
|
|
75
|
+
|
|
76
|
+
Collection ID is derived from the repository path structure:
|
|
77
|
+
~/.claude-mpm/cache/agents/{owner}/{repo}/agents/...
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
file_path: Absolute path to agent Markdown file
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
Collection ID in format "owner/repo-name" or None if not found
|
|
84
|
+
|
|
85
|
+
Example:
|
|
86
|
+
Input: ~/.claude-mpm/cache/agents/bobmatnyc/claude-mpm-agents/agents/pm.md
|
|
87
|
+
Output: "bobmatnyc/claude-mpm-agents"
|
|
88
|
+
"""
|
|
89
|
+
try:
|
|
90
|
+
# Find "agents" cache directory in the path (looking for .claude-mpm/cache/agents)
|
|
91
|
+
path_parts = file_path.parts
|
|
92
|
+
agents_cache_idx = -1
|
|
93
|
+
|
|
94
|
+
for i, part in enumerate(path_parts):
|
|
95
|
+
# Look for cache/agents pattern
|
|
96
|
+
if part == "agents" and i > 0 and path_parts[i - 1] == "cache":
|
|
97
|
+
agents_cache_idx = i
|
|
98
|
+
break
|
|
99
|
+
|
|
100
|
+
if agents_cache_idx == -1 or agents_cache_idx + 2 >= len(path_parts):
|
|
101
|
+
self.logger.debug(
|
|
102
|
+
f"Could not extract collection_id from path: {file_path}"
|
|
103
|
+
)
|
|
104
|
+
return None
|
|
105
|
+
|
|
106
|
+
# Extract owner and repo (next two parts after "cache/agents")
|
|
107
|
+
owner = path_parts[agents_cache_idx + 1]
|
|
108
|
+
repo = path_parts[agents_cache_idx + 2]
|
|
109
|
+
|
|
110
|
+
collection_id = f"{owner}/{repo}"
|
|
111
|
+
self.logger.debug(f"Extracted collection_id: {collection_id}")
|
|
112
|
+
return collection_id
|
|
113
|
+
|
|
114
|
+
except Exception as e:
|
|
115
|
+
self.logger.warning(
|
|
116
|
+
f"Failed to extract collection_id from {file_path}: {e}"
|
|
117
|
+
)
|
|
118
|
+
return None
|
|
119
|
+
|
|
120
|
+
def _extract_source_path_from_file(self, file_path: Path) -> Optional[str]:
|
|
121
|
+
"""Extract relative source path within repository.
|
|
122
|
+
|
|
123
|
+
Source path is relative to the repository root (not the agents subdirectory).
|
|
124
|
+
|
|
125
|
+
Args:
|
|
126
|
+
file_path: Absolute path to agent Markdown file
|
|
127
|
+
|
|
128
|
+
Returns:
|
|
129
|
+
Relative path from repo root, or None if not found
|
|
130
|
+
|
|
131
|
+
Example:
|
|
132
|
+
Input: ~/.claude-mpm/cache/agents/bobmatnyc/claude-mpm-agents/agents/pm.md
|
|
133
|
+
Output: "agents/pm.md"
|
|
134
|
+
"""
|
|
135
|
+
try:
|
|
136
|
+
# Find "agents" cache directory in the path
|
|
137
|
+
path_parts = file_path.parts
|
|
138
|
+
agents_cache_idx = -1
|
|
139
|
+
|
|
140
|
+
for i, part in enumerate(path_parts):
|
|
141
|
+
# Look for cache/agents pattern
|
|
142
|
+
if part == "agents" and i > 0 and path_parts[i - 1] == "cache":
|
|
143
|
+
agents_cache_idx = i
|
|
144
|
+
break
|
|
145
|
+
|
|
146
|
+
if agents_cache_idx == -1 or agents_cache_idx + 3 >= len(path_parts):
|
|
147
|
+
return None
|
|
148
|
+
|
|
149
|
+
# Path after owner/repo is the source path
|
|
150
|
+
# cache/agents/{owner}/{repo}/{source_path}
|
|
151
|
+
repo_root_idx = agents_cache_idx + 3
|
|
152
|
+
source_parts = path_parts[repo_root_idx:]
|
|
153
|
+
|
|
154
|
+
return "/".join(source_parts)
|
|
155
|
+
|
|
156
|
+
except Exception as e:
|
|
157
|
+
self.logger.warning(f"Failed to extract source_path from {file_path}: {e}")
|
|
158
|
+
return None
|
|
159
|
+
|
|
160
|
+
def _parse_yaml_frontmatter(self, content: str) -> Optional[Dict[str, Any]]:
|
|
161
|
+
"""Parse YAML frontmatter from Markdown content.
|
|
162
|
+
|
|
163
|
+
Extracts YAML frontmatter delimited by --- markers at the start of the file.
|
|
164
|
+
Uses a tolerant approach: attempts full YAML parsing first, falls back to
|
|
165
|
+
simple key-value extraction for malformed YAML.
|
|
166
|
+
|
|
167
|
+
Design Decision: Tolerant YAML Parsing
|
|
168
|
+
|
|
169
|
+
Rationale: Some agent markdown files have malformed YAML (incorrect indentation
|
|
170
|
+
in nested structures). Rather than failing completely, we:
|
|
171
|
+
1. Try full YAML parsing first (handles well-formed YAML)
|
|
172
|
+
2. Fall back to regex extraction for critical fields (agent_id, name, etc.)
|
|
173
|
+
3. Log warnings but continue processing
|
|
174
|
+
|
|
175
|
+
This ensures we can still extract agent_id even if complex nested structures
|
|
176
|
+
(like template_changelog) have indentation issues.
|
|
177
|
+
|
|
178
|
+
Args:
|
|
179
|
+
content: Full Markdown file content
|
|
180
|
+
|
|
181
|
+
Returns:
|
|
182
|
+
Dictionary of parsed YAML frontmatter, or None if not found
|
|
183
|
+
|
|
184
|
+
Example:
|
|
185
|
+
Input:
|
|
186
|
+
---
|
|
187
|
+
agent_id: python-engineer
|
|
188
|
+
name: Python Engineer
|
|
189
|
+
version: 2.3.0
|
|
190
|
+
---
|
|
191
|
+
# Agent content...
|
|
192
|
+
|
|
193
|
+
Output:
|
|
194
|
+
{"agent_id": "python-engineer", "name": "Python Engineer", "version": "2.3.0"}
|
|
195
|
+
"""
|
|
196
|
+
try:
|
|
197
|
+
# Check if content starts with YAML frontmatter
|
|
198
|
+
if not content.startswith("---"):
|
|
199
|
+
self.logger.debug("No YAML frontmatter found (doesn't start with ---)")
|
|
200
|
+
return None
|
|
201
|
+
|
|
202
|
+
# Extract frontmatter content between --- markers
|
|
203
|
+
frontmatter_match = re.match(r"^---\n(.*?)\n---\s*\n", content, re.DOTALL)
|
|
204
|
+
if not frontmatter_match:
|
|
205
|
+
self.logger.debug("No closing --- marker found for YAML frontmatter")
|
|
206
|
+
return None
|
|
207
|
+
|
|
208
|
+
yaml_content = frontmatter_match.group(1)
|
|
209
|
+
|
|
210
|
+
# Try full YAML parsing first
|
|
211
|
+
try:
|
|
212
|
+
parsed = yaml.safe_load(yaml_content)
|
|
213
|
+
if isinstance(parsed, dict):
|
|
214
|
+
return parsed
|
|
215
|
+
self.logger.warning(
|
|
216
|
+
f"YAML frontmatter is not a dictionary: {type(parsed)}"
|
|
217
|
+
)
|
|
218
|
+
except yaml.YAMLError as e:
|
|
219
|
+
# Malformed YAML (e.g., indentation errors) - fall back to regex extraction
|
|
220
|
+
self.logger.debug(
|
|
221
|
+
f"Full YAML parse failed, using fallback extraction: {e}"
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
# Extract key fields using regex (tolerant of malformed nested structures)
|
|
225
|
+
result = {}
|
|
226
|
+
|
|
227
|
+
# Extract simple key-value pairs (no nested structures)
|
|
228
|
+
simple_keys = [
|
|
229
|
+
"agent_id",
|
|
230
|
+
"name",
|
|
231
|
+
"description",
|
|
232
|
+
"version",
|
|
233
|
+
"model",
|
|
234
|
+
"agent_type",
|
|
235
|
+
"category",
|
|
236
|
+
"author",
|
|
237
|
+
"schema_version",
|
|
238
|
+
]
|
|
239
|
+
|
|
240
|
+
for key in simple_keys:
|
|
241
|
+
# Match key: value on a line (not indented, so it's top-level)
|
|
242
|
+
pattern = rf"^{key}:\s*(.+?)$"
|
|
243
|
+
match = re.search(pattern, yaml_content, re.MULTILINE)
|
|
244
|
+
if match:
|
|
245
|
+
value = match.group(1).strip()
|
|
246
|
+
# Remove quotes if present
|
|
247
|
+
if value.startswith(("'", '"')) and value.endswith(("'", '"')):
|
|
248
|
+
value = value[1:-1]
|
|
249
|
+
result[key] = value
|
|
250
|
+
|
|
251
|
+
if result:
|
|
252
|
+
self.logger.debug(
|
|
253
|
+
f"Extracted {len(result)} fields using fallback method"
|
|
254
|
+
)
|
|
255
|
+
return result
|
|
256
|
+
return None
|
|
257
|
+
|
|
258
|
+
except Exception as e:
|
|
259
|
+
self.logger.warning(f"Unexpected error parsing frontmatter: {e}")
|
|
260
|
+
return None
|
|
261
|
+
|
|
262
|
+
return None
|
|
263
|
+
|
|
264
|
+
def _generate_hierarchical_id(self, file_path: Path) -> str:
|
|
265
|
+
"""Generate hierarchical agent ID from file path.
|
|
266
|
+
|
|
267
|
+
Converts file path relative to agents subdirectory into hierarchical ID.
|
|
268
|
+
|
|
269
|
+
Design Decision: Path-based IDs for hierarchy preservation
|
|
270
|
+
|
|
271
|
+
Rationale: Agent IDs must reflect directory hierarchy to enable:
|
|
272
|
+
- Category-based filtering (engineer/backend/python-engineer)
|
|
273
|
+
- Preset matching against AUTO-DEPLOY-INDEX.md
|
|
274
|
+
- Multi-level organization without name collisions
|
|
275
|
+
|
|
276
|
+
Supports both cache structures:
|
|
277
|
+
1. Git repo: Calculate relative to /agents/ subdirectory
|
|
278
|
+
2. Flattened cache: Calculate relative to agents_cache_dir directly
|
|
279
|
+
|
|
280
|
+
Example (Git repo):
|
|
281
|
+
Input: /cache/bobmatnyc/claude-mpm-agents/agents/engineer/backend/python-engineer.md
|
|
282
|
+
Root: /cache/bobmatnyc/claude-mpm-agents/agents
|
|
283
|
+
Output: engineer/backend/python-engineer
|
|
284
|
+
|
|
285
|
+
Example (Flattened cache):
|
|
286
|
+
Input: /cache/agents/engineer/python-engineer.md
|
|
287
|
+
Root: /cache/agents
|
|
288
|
+
Output: engineer/python-engineer
|
|
289
|
+
|
|
290
|
+
Args:
|
|
291
|
+
file_path: Absolute path to agent Markdown file
|
|
292
|
+
|
|
293
|
+
Returns:
|
|
294
|
+
Hierarchical agent ID with forward slashes
|
|
295
|
+
"""
|
|
296
|
+
try:
|
|
297
|
+
# Try git repo structure first: /agents/ subdirectory
|
|
298
|
+
agents_dir = self.agents_cache_dir / "agents"
|
|
299
|
+
if agents_dir.exists():
|
|
300
|
+
try:
|
|
301
|
+
relative_path = file_path.relative_to(agents_dir)
|
|
302
|
+
return str(relative_path.with_suffix("")).replace("\\", "/")
|
|
303
|
+
except ValueError:
|
|
304
|
+
pass # Not under agents_dir, try flattened structure
|
|
305
|
+
|
|
306
|
+
# Try flattened cache structure: calculate relative to agents_cache_dir
|
|
307
|
+
try:
|
|
308
|
+
relative_path = file_path.relative_to(self.agents_cache_dir)
|
|
309
|
+
return str(relative_path.with_suffix("")).replace("\\", "/")
|
|
310
|
+
except ValueError:
|
|
311
|
+
pass # Not under agents_cache_dir either
|
|
312
|
+
|
|
313
|
+
# Fall back to filename
|
|
314
|
+
self.logger.warning(
|
|
315
|
+
f"File {file_path} not under expected directories, using filename"
|
|
316
|
+
)
|
|
317
|
+
return file_path.stem
|
|
318
|
+
except Exception as e:
|
|
319
|
+
self.logger.warning(
|
|
320
|
+
f"Error generating hierarchical ID for {file_path}: {e}"
|
|
321
|
+
)
|
|
322
|
+
return file_path.stem
|
|
323
|
+
|
|
324
|
+
def _detect_category_from_path(self, file_path: Path) -> str:
|
|
325
|
+
"""Detect category from file path hierarchy.
|
|
326
|
+
|
|
327
|
+
Extracts category from directory structure. Category is the path
|
|
328
|
+
from agents subdirectory to the file, excluding the filename.
|
|
329
|
+
|
|
330
|
+
Supports both cache structures:
|
|
331
|
+
1. Git repo: Calculate relative to /agents/ subdirectory
|
|
332
|
+
2. Flattened cache: Calculate relative to agents_cache_dir directly
|
|
333
|
+
|
|
334
|
+
Example (Git repo):
|
|
335
|
+
Input: /cache/bobmatnyc/claude-mpm-agents/agents/engineer/backend/python-engineer.md
|
|
336
|
+
Root: /cache/bobmatnyc/claude-mpm-agents/agents
|
|
337
|
+
Output: engineer/backend
|
|
338
|
+
|
|
339
|
+
Example (Flattened cache):
|
|
340
|
+
Input: /cache/agents/engineer/python-engineer.md
|
|
341
|
+
Root: /cache/agents
|
|
342
|
+
Output: engineer
|
|
343
|
+
|
|
344
|
+
Args:
|
|
345
|
+
file_path: Absolute path to agent Markdown file
|
|
346
|
+
|
|
347
|
+
Returns:
|
|
348
|
+
Category path with forward slashes, or "universal" if in root
|
|
349
|
+
"""
|
|
350
|
+
try:
|
|
351
|
+
# Try git repo structure first: /agents/ subdirectory
|
|
352
|
+
agents_dir = self.agents_cache_dir / "agents"
|
|
353
|
+
if agents_dir.exists():
|
|
354
|
+
try:
|
|
355
|
+
relative_path = file_path.relative_to(agents_dir)
|
|
356
|
+
parts = relative_path.parts[:-1] # Exclude filename
|
|
357
|
+
return "/".join(parts) if parts else "universal"
|
|
358
|
+
except ValueError:
|
|
359
|
+
pass # Not under agents_dir, try flattened structure
|
|
360
|
+
|
|
361
|
+
# Try flattened cache structure: calculate relative to agents_cache_dir
|
|
362
|
+
try:
|
|
363
|
+
relative_path = file_path.relative_to(self.agents_cache_dir)
|
|
364
|
+
parts = relative_path.parts[:-1] # Exclude filename
|
|
365
|
+
return "/".join(parts) if parts else "universal"
|
|
366
|
+
except ValueError:
|
|
367
|
+
pass # Not under agents_cache_dir either
|
|
368
|
+
|
|
369
|
+
return "universal"
|
|
370
|
+
except Exception:
|
|
371
|
+
return "universal"
|
|
372
|
+
|
|
373
|
+
def discover_remote_agents(self) -> List[Dict[str, Any]]:
|
|
374
|
+
"""Discover all remote agents from cache directory.
|
|
375
|
+
|
|
376
|
+
Scans the remote agents directory for *.md files recursively and converts each
|
|
377
|
+
to JSON template format. Skips files that can't be parsed.
|
|
378
|
+
|
|
379
|
+
Supports two cache structures:
|
|
380
|
+
1. Git repo path: {path}/agents/ - has /agents/ subdirectory
|
|
381
|
+
2. Flattened cache: {path}/ - directly contains category directories
|
|
382
|
+
|
|
383
|
+
Bug #4 Fix: Only scan /agents/ subdirectory when it exists to prevent
|
|
384
|
+
README.md, CHANGELOG.md, etc. from being treated as agents.
|
|
385
|
+
|
|
386
|
+
Returns:
|
|
387
|
+
List of agent dictionaries in JSON template format
|
|
388
|
+
|
|
389
|
+
Example:
|
|
390
|
+
>>> service = RemoteAgentDiscoveryService(Path("~/.claude-mpm/cache/agents"))
|
|
391
|
+
>>> agents = service.discover_remote_agents()
|
|
392
|
+
>>> len(agents)
|
|
393
|
+
5
|
|
394
|
+
>>> agents[0]['name']
|
|
395
|
+
'Security Scanner Agent'
|
|
396
|
+
"""
|
|
397
|
+
agents = []
|
|
398
|
+
|
|
399
|
+
if not self.agents_cache_dir.exists():
|
|
400
|
+
self.logger.debug(
|
|
401
|
+
f"Agents cache directory does not exist: {self.agents_cache_dir}"
|
|
402
|
+
)
|
|
403
|
+
return agents
|
|
404
|
+
|
|
405
|
+
# Support four cache structures (PRIORITY ORDER):
|
|
406
|
+
# 1. Built output: {path}/dist/agents/ - PREFERRED (built with BASE-AGENT composition)
|
|
407
|
+
# 2. Git repo path: {path}/agents/ - source files (fallback)
|
|
408
|
+
# 3. Owner/repo structure: {path}/{owner}/{repo}/agents/ - GitHub sync structure
|
|
409
|
+
# 4. Flattened cache: {path}/ - directly contains category directories (legacy)
|
|
410
|
+
|
|
411
|
+
# Priority 1: Check for dist/agents/ (built output with BASE-AGENT composition)
|
|
412
|
+
dist_agents_dir = self.agents_cache_dir / "dist" / "agents"
|
|
413
|
+
agents_dir = self.agents_cache_dir / "agents"
|
|
414
|
+
|
|
415
|
+
if dist_agents_dir.exists():
|
|
416
|
+
# PREFERRED: Use built agents from dist/agents/
|
|
417
|
+
# These have BASE-AGENT.md files properly composed by build-agent.py
|
|
418
|
+
self.logger.debug(f"Using built agents from dist: {dist_agents_dir}")
|
|
419
|
+
scan_dir = dist_agents_dir
|
|
420
|
+
elif agents_dir.exists():
|
|
421
|
+
# FALLBACK: Git repo structure - scan /agents/ subdirectory (source files)
|
|
422
|
+
# This path is used when dist/agents/ hasn't been built yet
|
|
423
|
+
self.logger.debug(f"Using source agents (no dist/ found): {agents_dir}")
|
|
424
|
+
scan_dir = agents_dir
|
|
425
|
+
else:
|
|
426
|
+
# Priority 3: Check for {owner}/{repo}/agents/ structure (GitHub sync)
|
|
427
|
+
# e.g., ~/.claude-mpm/cache/agents/bobmatnyc/claude-mpm-agents/agents/
|
|
428
|
+
owner_repo_agents_dir = None
|
|
429
|
+
for owner_dir in self.agents_cache_dir.iterdir():
|
|
430
|
+
if owner_dir.is_dir() and not owner_dir.name.startswith("."):
|
|
431
|
+
for repo_dir in owner_dir.iterdir():
|
|
432
|
+
if repo_dir.is_dir():
|
|
433
|
+
potential_agents = repo_dir / "agents"
|
|
434
|
+
if potential_agents.exists():
|
|
435
|
+
owner_repo_agents_dir = potential_agents
|
|
436
|
+
self.logger.debug(
|
|
437
|
+
f"Using GitHub sync structure: {owner_repo_agents_dir}"
|
|
438
|
+
)
|
|
439
|
+
break
|
|
440
|
+
if owner_repo_agents_dir:
|
|
441
|
+
break
|
|
442
|
+
|
|
443
|
+
if owner_repo_agents_dir:
|
|
444
|
+
scan_dir = owner_repo_agents_dir
|
|
445
|
+
else:
|
|
446
|
+
# LEGACY: Flattened cache structure - scan root directly
|
|
447
|
+
# Check if this looks like the flattened cache (has category subdirectories)
|
|
448
|
+
category_dirs = [
|
|
449
|
+
"universal",
|
|
450
|
+
"engineer",
|
|
451
|
+
"ops",
|
|
452
|
+
"qa",
|
|
453
|
+
"security",
|
|
454
|
+
"documentation",
|
|
455
|
+
]
|
|
456
|
+
has_categories = any(
|
|
457
|
+
(self.agents_cache_dir / cat).exists() for cat in category_dirs
|
|
458
|
+
)
|
|
459
|
+
|
|
460
|
+
if has_categories:
|
|
461
|
+
self.logger.debug(
|
|
462
|
+
f"Using flattened cache structure: {self.agents_cache_dir}"
|
|
463
|
+
)
|
|
464
|
+
scan_dir = self.agents_cache_dir
|
|
465
|
+
else:
|
|
466
|
+
self.logger.warning(
|
|
467
|
+
f"No agent directories found. Checked: {dist_agents_dir}, {agents_dir}, "
|
|
468
|
+
f"owner/repo/agents/ structure, and category directories in {self.agents_cache_dir}. "
|
|
469
|
+
"Expected agents in /dist/agents/, /agents/, owner/repo/agents/, or category directories."
|
|
470
|
+
)
|
|
471
|
+
return agents
|
|
472
|
+
|
|
473
|
+
# Find all Markdown files recursively
|
|
474
|
+
md_files = list(scan_dir.rglob("*.md"))
|
|
475
|
+
|
|
476
|
+
# Filter out non-agent files and git repository files
|
|
477
|
+
excluded_files = {
|
|
478
|
+
"README.md",
|
|
479
|
+
"CHANGELOG.md",
|
|
480
|
+
"CONTRIBUTING.md",
|
|
481
|
+
"LICENSE.md",
|
|
482
|
+
"BASE-AGENT.md",
|
|
483
|
+
"SUMMARY.md",
|
|
484
|
+
"IMPLEMENTATION-SUMMARY.md",
|
|
485
|
+
"REFACTORING_REPORT.md",
|
|
486
|
+
"REORGANIZATION-PLAN.md",
|
|
487
|
+
"AUTO-DEPLOY-INDEX.md",
|
|
488
|
+
"PHASE1_COMPLETE.md",
|
|
489
|
+
"AGENTS.md",
|
|
490
|
+
# Skill-related files (should not be treated as agents)
|
|
491
|
+
"SKILL.md",
|
|
492
|
+
"SKILLS.md",
|
|
493
|
+
"skill-template.md",
|
|
494
|
+
}
|
|
495
|
+
md_files = [f for f in md_files if f.name not in excluded_files]
|
|
496
|
+
|
|
497
|
+
# Filter out files from skills-related directories
|
|
498
|
+
# Skills are not agents and should not be discovered here
|
|
499
|
+
excluded_directory_patterns = {"references", "examples", "claude-mpm-skills"}
|
|
500
|
+
md_files = [
|
|
501
|
+
f
|
|
502
|
+
for f in md_files
|
|
503
|
+
if not any(excluded in f.parts for excluded in excluded_directory_patterns)
|
|
504
|
+
]
|
|
505
|
+
|
|
506
|
+
# In flattened cache mode, also exclude files from git repository subdirectories
|
|
507
|
+
# (files under directories that contain .git folder)
|
|
508
|
+
if scan_dir == self.agents_cache_dir:
|
|
509
|
+
filtered_files = []
|
|
510
|
+
for f in md_files:
|
|
511
|
+
# Check if this file is inside a git repository (has .git in path)
|
|
512
|
+
# Git repos are at {agents_cache_dir}/{owner}/{repo}/.git
|
|
513
|
+
path_parts = f.relative_to(self.agents_cache_dir).parts
|
|
514
|
+
if len(path_parts) >= 2:
|
|
515
|
+
# Check if this looks like a git repo path (owner/repo)
|
|
516
|
+
potential_repo = (
|
|
517
|
+
self.agents_cache_dir / path_parts[0] / path_parts[1]
|
|
518
|
+
)
|
|
519
|
+
if (potential_repo / ".git").exists():
|
|
520
|
+
# This file is in a git repo, skip it (we'll handle git repos separately)
|
|
521
|
+
self.logger.debug(f"Skipping file in git repo: {f}")
|
|
522
|
+
continue
|
|
523
|
+
filtered_files.append(f)
|
|
524
|
+
md_files = filtered_files
|
|
525
|
+
|
|
526
|
+
self.logger.debug(f"Found {len(md_files)} Markdown files in {scan_dir}")
|
|
527
|
+
|
|
528
|
+
for md_file in md_files:
|
|
529
|
+
try:
|
|
530
|
+
agent_dict = self._parse_markdown_agent(md_file)
|
|
531
|
+
if agent_dict:
|
|
532
|
+
agents.append(agent_dict)
|
|
533
|
+
self.logger.debug(
|
|
534
|
+
f"Successfully parsed remote agent: {md_file.name}"
|
|
535
|
+
)
|
|
536
|
+
else:
|
|
537
|
+
self.logger.warning(
|
|
538
|
+
f"Failed to parse remote agent (no name found): {md_file.name}"
|
|
539
|
+
)
|
|
540
|
+
except Exception as e:
|
|
541
|
+
self.logger.warning(f"Failed to parse remote agent {md_file.name}: {e}")
|
|
542
|
+
|
|
543
|
+
self.logger.info(
|
|
544
|
+
f"Discovered {len(agents)} remote agents from {self.agents_cache_dir.name}"
|
|
545
|
+
)
|
|
546
|
+
return agents
|
|
547
|
+
|
|
548
|
+
def _parse_markdown_agent(self, md_file: Path) -> Optional[Dict[str, Any]]:
|
|
549
|
+
"""Parse Markdown agent file and convert to JSON template format.
|
|
550
|
+
|
|
551
|
+
Expected Markdown format with YAML frontmatter:
|
|
552
|
+
```markdown
|
|
553
|
+
---
|
|
554
|
+
agent_id: python-engineer
|
|
555
|
+
name: Python Engineer
|
|
556
|
+
version: 2.3.0
|
|
557
|
+
model: sonnet
|
|
558
|
+
---
|
|
559
|
+
# Agent Name
|
|
560
|
+
|
|
561
|
+
Description paragraph (first paragraph after heading)
|
|
562
|
+
|
|
563
|
+
## Configuration
|
|
564
|
+
- Model: sonnet
|
|
565
|
+
- Priority: 100
|
|
566
|
+
|
|
567
|
+
## Routing
|
|
568
|
+
- Keywords: keyword1, keyword2
|
|
569
|
+
- Paths: /path1/, /path2/
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
Agent ID Priority (Mismatch Fix):
|
|
573
|
+
1. Use agent_id from YAML frontmatter if present (e.g., "python-engineer")
|
|
574
|
+
2. Fall back to leaf filename if no YAML frontmatter (e.g., "python-engineer.md" -> "python-engineer")
|
|
575
|
+
3. Store hierarchical path separately as category_path for categorization
|
|
576
|
+
|
|
577
|
+
Args:
|
|
578
|
+
md_file: Path to Markdown agent file
|
|
579
|
+
|
|
580
|
+
Returns:
|
|
581
|
+
Agent dictionary in JSON template format, or None if parsing fails
|
|
582
|
+
|
|
583
|
+
Error Handling:
|
|
584
|
+
- Returns None if agent name (first heading) is missing
|
|
585
|
+
- Uses defaults for missing sections (model=sonnet, priority=50)
|
|
586
|
+
- Empty routing keywords/paths if Routing section missing
|
|
587
|
+
"""
|
|
588
|
+
try:
|
|
589
|
+
content = md_file.read_text(encoding="utf-8")
|
|
590
|
+
except Exception as e:
|
|
591
|
+
self.logger.error(f"Failed to read file {md_file}: {e}")
|
|
592
|
+
return None
|
|
593
|
+
|
|
594
|
+
# MISMATCH FIX: Parse YAML frontmatter to extract agent_id
|
|
595
|
+
frontmatter = self._parse_yaml_frontmatter(content)
|
|
596
|
+
|
|
597
|
+
# MISMATCH FIX: Use agent_id from YAML frontmatter if present, otherwise fall back to filename
|
|
598
|
+
if frontmatter and "agent_id" in frontmatter:
|
|
599
|
+
agent_id = frontmatter["agent_id"]
|
|
600
|
+
self.logger.debug(f"Using agent_id from YAML frontmatter: {agent_id}")
|
|
601
|
+
else:
|
|
602
|
+
# Fallback: Use leaf filename without extension
|
|
603
|
+
agent_id = md_file.stem
|
|
604
|
+
self.logger.debug(f"No agent_id in YAML, using filename: {agent_id}")
|
|
605
|
+
|
|
606
|
+
# Store hierarchical path separately for categorization (not as primary ID)
|
|
607
|
+
hierarchical_path = self._generate_hierarchical_id(md_file)
|
|
608
|
+
|
|
609
|
+
# Extract agent name - prioritize frontmatter over markdown heading
|
|
610
|
+
# Frontmatter is intentional metadata, headings may be arbitrary content
|
|
611
|
+
if frontmatter and "name" in frontmatter:
|
|
612
|
+
name = frontmatter["name"]
|
|
613
|
+
else:
|
|
614
|
+
# Fallback to first heading or filename
|
|
615
|
+
name_match = re.search(r"^#\s+(.+?)$", content, re.MULTILINE)
|
|
616
|
+
if name_match:
|
|
617
|
+
name = name_match.group(1).strip()
|
|
618
|
+
else:
|
|
619
|
+
# Last resort: derive from filename
|
|
620
|
+
name = md_file.stem.replace("-", " ").replace("_", " ").title()
|
|
621
|
+
|
|
622
|
+
# Extract description - prioritize frontmatter over markdown content
|
|
623
|
+
# Frontmatter is intentional metadata, paragraphs may be arbitrary content
|
|
624
|
+
if frontmatter and "description" in frontmatter:
|
|
625
|
+
description = frontmatter["description"]
|
|
626
|
+
else:
|
|
627
|
+
# Fallback to first paragraph after heading
|
|
628
|
+
desc_match = re.search(
|
|
629
|
+
r"^#.+?\n\n(.+?)(?:\n\n##|\Z)", content, re.DOTALL | re.MULTILINE
|
|
630
|
+
)
|
|
631
|
+
if desc_match:
|
|
632
|
+
description = desc_match.group(1).strip()
|
|
633
|
+
else:
|
|
634
|
+
description = ""
|
|
635
|
+
|
|
636
|
+
# Extract model from YAML frontmatter or Configuration section
|
|
637
|
+
if frontmatter and "model" in frontmatter:
|
|
638
|
+
model = frontmatter["model"]
|
|
639
|
+
else:
|
|
640
|
+
model_match = re.search(r"Model:\s*(\w+)", content, re.IGNORECASE)
|
|
641
|
+
model = model_match.group(1) if model_match else "sonnet"
|
|
642
|
+
|
|
643
|
+
# Extract priority from Configuration section
|
|
644
|
+
priority_match = re.search(r"Priority:\s*(\d+)", content, re.IGNORECASE)
|
|
645
|
+
priority = int(priority_match.group(1)) if priority_match else 50
|
|
646
|
+
|
|
647
|
+
# Extract routing keywords
|
|
648
|
+
keywords_match = re.search(r"Keywords:\s*(.+?)(?:\n|$)", content, re.IGNORECASE)
|
|
649
|
+
keywords = []
|
|
650
|
+
if keywords_match:
|
|
651
|
+
keywords = [k.strip() for k in keywords_match.group(1).split(",")]
|
|
652
|
+
|
|
653
|
+
# Extract routing paths
|
|
654
|
+
paths_match = re.search(r"Paths:\s*(.+?)(?:\n|$)", content, re.IGNORECASE)
|
|
655
|
+
paths = []
|
|
656
|
+
if paths_match:
|
|
657
|
+
paths = [p.strip() for p in paths_match.group(1).split(",")]
|
|
658
|
+
|
|
659
|
+
# Get version (SHA-256 hash) from cache metadata or YAML frontmatter
|
|
660
|
+
if frontmatter and "version" in frontmatter:
|
|
661
|
+
version = frontmatter["version"]
|
|
662
|
+
else:
|
|
663
|
+
version = self._get_agent_version(md_file)
|
|
664
|
+
|
|
665
|
+
# Bug #1 fix: Detect category from directory path
|
|
666
|
+
category = self._detect_category_from_path(md_file)
|
|
667
|
+
|
|
668
|
+
# NEW: Extract collection metadata from path
|
|
669
|
+
collection_id = self._extract_collection_id_from_path(md_file)
|
|
670
|
+
source_path = self._extract_source_path_from_file(md_file)
|
|
671
|
+
|
|
672
|
+
# NEW: Generate canonical_id (collection_id:agent_id)
|
|
673
|
+
# Use leaf agent_id (not hierarchical path) for canonical_id
|
|
674
|
+
if collection_id:
|
|
675
|
+
canonical_id = f"{collection_id}:{agent_id}"
|
|
676
|
+
else:
|
|
677
|
+
# Fallback for legacy agents without collection
|
|
678
|
+
canonical_id = f"legacy:{agent_id}"
|
|
679
|
+
|
|
680
|
+
# Convert to JSON template format and return
|
|
681
|
+
# IMPORTANT: Include 'path' field for compatibility with deployment validation (ticket 1M-480)
|
|
682
|
+
# Git-sourced agents must have 'path' field to match structure from AgentDiscoveryService
|
|
683
|
+
return {
|
|
684
|
+
"agent_id": agent_id, # MISMATCH FIX: Use leaf name from YAML, not hierarchical path
|
|
685
|
+
"hierarchical_path": hierarchical_path, # Store hierarchical path separately
|
|
686
|
+
"canonical_id": canonical_id, # NEW: Primary matching key (uses leaf agent_id)
|
|
687
|
+
"collection_id": collection_id, # NEW: Collection identifier
|
|
688
|
+
"source_path": source_path, # NEW: Path within repository
|
|
689
|
+
"metadata": {
|
|
690
|
+
"name": name,
|
|
691
|
+
"description": description,
|
|
692
|
+
"version": version,
|
|
693
|
+
"author": "remote", # Mark as remote agent
|
|
694
|
+
"category": category, # Use detected category from path
|
|
695
|
+
"hierarchical_path": hierarchical_path, # For categorization/filtering
|
|
696
|
+
"collection_id": collection_id, # NEW: Also in metadata
|
|
697
|
+
"source_path": source_path, # NEW: Also in metadata
|
|
698
|
+
"canonical_id": canonical_id, # NEW: Also in metadata
|
|
699
|
+
},
|
|
700
|
+
"model": model,
|
|
701
|
+
"source": "remote", # Mark as remote agent
|
|
702
|
+
"source_file": str(md_file),
|
|
703
|
+
"path": str(
|
|
704
|
+
md_file
|
|
705
|
+
), # Add 'path' field for deployment compatibility (1M-480)
|
|
706
|
+
"file_path": str(md_file), # Keep for backward compatibility
|
|
707
|
+
"version": version, # Include at root level for version comparison
|
|
708
|
+
"category": category, # Add category at root level for filtering
|
|
709
|
+
"routing": {"keywords": keywords, "paths": paths, "priority": priority},
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
def _get_agent_version(self, md_file: Path) -> str:
|
|
713
|
+
"""Get version (SHA-256 hash) from cache metadata.
|
|
714
|
+
|
|
715
|
+
Looks for corresponding .meta.json file in cache directory that contains
|
|
716
|
+
the SHA-256 hash of the agent content.
|
|
717
|
+
|
|
718
|
+
Args:
|
|
719
|
+
md_file: Path to Markdown agent file
|
|
720
|
+
|
|
721
|
+
Returns:
|
|
722
|
+
SHA-256 hash from metadata, or 'unknown' if not found
|
|
723
|
+
|
|
724
|
+
Example metadata file:
|
|
725
|
+
{
|
|
726
|
+
"content_hash": "abc123...",
|
|
727
|
+
"etag": "W/\"abc123\"",
|
|
728
|
+
"last_modified": "2025-11-30T10:00:00Z"
|
|
729
|
+
}
|
|
730
|
+
"""
|
|
731
|
+
# Look for .meta.json file
|
|
732
|
+
meta_file = md_file.with_suffix(".md.meta.json")
|
|
733
|
+
|
|
734
|
+
if not meta_file.exists():
|
|
735
|
+
self.logger.debug(f"No metadata file found for {md_file.name}")
|
|
736
|
+
return "unknown"
|
|
737
|
+
|
|
738
|
+
try:
|
|
739
|
+
meta_data = json.loads(meta_file.read_text(encoding="utf-8"))
|
|
740
|
+
content_hash = meta_data.get("content_hash", "unknown")
|
|
741
|
+
self.logger.debug(
|
|
742
|
+
f"Retrieved version {content_hash[:8]}... for {md_file.name}"
|
|
743
|
+
)
|
|
744
|
+
return content_hash
|
|
745
|
+
except Exception as e:
|
|
746
|
+
self.logger.warning(f"Failed to read metadata for {md_file.name}: {e}")
|
|
747
|
+
return "unknown"
|
|
748
|
+
|
|
749
|
+
def get_remote_agent_metadata(
|
|
750
|
+
self, agent_name: str
|
|
751
|
+
) -> Optional[RemoteAgentMetadata]:
|
|
752
|
+
"""Get metadata for a specific remote agent.
|
|
753
|
+
|
|
754
|
+
Args:
|
|
755
|
+
agent_name: Name of the agent to retrieve
|
|
756
|
+
|
|
757
|
+
Returns:
|
|
758
|
+
RemoteAgentMetadata if found, None otherwise
|
|
759
|
+
"""
|
|
760
|
+
# Bug #4 fix: Search in /agents/ subdirectory, not root directory
|
|
761
|
+
agents_dir = self.agents_cache_dir / "agents"
|
|
762
|
+
if not agents_dir.exists():
|
|
763
|
+
return None
|
|
764
|
+
|
|
765
|
+
for md_file in agents_dir.rglob("*.md"):
|
|
766
|
+
agent_dict = self._parse_markdown_agent(md_file)
|
|
767
|
+
if agent_dict and agent_dict["metadata"]["name"] == agent_name:
|
|
768
|
+
return RemoteAgentMetadata(
|
|
769
|
+
name=agent_dict["metadata"]["name"],
|
|
770
|
+
description=agent_dict["metadata"]["description"],
|
|
771
|
+
model=agent_dict["model"],
|
|
772
|
+
routing_keywords=agent_dict["routing"]["keywords"],
|
|
773
|
+
routing_paths=agent_dict["routing"]["paths"],
|
|
774
|
+
routing_priority=agent_dict["routing"]["priority"],
|
|
775
|
+
source_file=Path(agent_dict["source_file"]),
|
|
776
|
+
version=agent_dict["version"],
|
|
777
|
+
collection_id=agent_dict.get("collection_id"),
|
|
778
|
+
source_path=agent_dict.get("source_path"),
|
|
779
|
+
canonical_id=agent_dict.get("canonical_id"),
|
|
780
|
+
)
|
|
781
|
+
return None
|
|
782
|
+
|
|
783
|
+
def get_agents_by_collection(self, collection_id: str) -> List[Dict[str, Any]]:
|
|
784
|
+
"""Get all agents belonging to a specific collection.
|
|
785
|
+
|
|
786
|
+
Args:
|
|
787
|
+
collection_id: Collection identifier in format "owner/repo-name"
|
|
788
|
+
|
|
789
|
+
Returns:
|
|
790
|
+
List of agent dictionaries from the specified collection
|
|
791
|
+
|
|
792
|
+
Example:
|
|
793
|
+
>>> service = RemoteAgentDiscoveryService(Path("~/.claude-mpm/cache/agents"))
|
|
794
|
+
>>> agents = service.get_agents_by_collection("bobmatnyc/claude-mpm-agents")
|
|
795
|
+
>>> len(agents)
|
|
796
|
+
45
|
|
797
|
+
"""
|
|
798
|
+
all_agents = self.discover_remote_agents()
|
|
799
|
+
|
|
800
|
+
# Filter by collection_id
|
|
801
|
+
collection_agents = [
|
|
802
|
+
agent for agent in all_agents if agent.get("collection_id") == collection_id
|
|
803
|
+
]
|
|
804
|
+
|
|
805
|
+
self.logger.info(
|
|
806
|
+
f"Found {len(collection_agents)} agents in collection '{collection_id}'"
|
|
807
|
+
)
|
|
808
|
+
|
|
809
|
+
return collection_agents
|
|
810
|
+
|
|
811
|
+
def list_collections(self) -> List[Dict[str, Any]]:
|
|
812
|
+
"""List all available collections with agent counts.
|
|
813
|
+
|
|
814
|
+
Returns:
|
|
815
|
+
List of collection info dictionaries with:
|
|
816
|
+
- collection_id: Collection identifier
|
|
817
|
+
- agent_count: Number of agents in collection
|
|
818
|
+
- agents: List of agent IDs in collection
|
|
819
|
+
|
|
820
|
+
Example:
|
|
821
|
+
>>> service = RemoteAgentDiscoveryService(Path("~/.claude-mpm/cache/agents"))
|
|
822
|
+
>>> collections = service.list_collections()
|
|
823
|
+
>>> collections
|
|
824
|
+
[
|
|
825
|
+
{
|
|
826
|
+
"collection_id": "bobmatnyc/claude-mpm-agents",
|
|
827
|
+
"agent_count": 45,
|
|
828
|
+
"agents": ["pm", "engineer", "qa", ...]
|
|
829
|
+
}
|
|
830
|
+
]
|
|
831
|
+
"""
|
|
832
|
+
all_agents = self.discover_remote_agents()
|
|
833
|
+
|
|
834
|
+
# Group by collection_id
|
|
835
|
+
collections_map: Dict[str, List[str]] = {}
|
|
836
|
+
|
|
837
|
+
for agent in all_agents:
|
|
838
|
+
collection_id = agent.get("collection_id")
|
|
839
|
+
if not collection_id:
|
|
840
|
+
# Skip agents without collection (legacy)
|
|
841
|
+
continue
|
|
842
|
+
|
|
843
|
+
if collection_id not in collections_map:
|
|
844
|
+
collections_map[collection_id] = []
|
|
845
|
+
|
|
846
|
+
agent_id = agent.get("agent_id", agent.get("metadata", {}).get("name"))
|
|
847
|
+
if agent_id:
|
|
848
|
+
collections_map[collection_id].append(agent_id)
|
|
849
|
+
|
|
850
|
+
# Convert to list format
|
|
851
|
+
collections = [
|
|
852
|
+
{
|
|
853
|
+
"collection_id": coll_id,
|
|
854
|
+
"agent_count": len(agent_ids),
|
|
855
|
+
"agents": sorted(agent_ids),
|
|
856
|
+
}
|
|
857
|
+
for coll_id, agent_ids in collections_map.items()
|
|
858
|
+
]
|
|
859
|
+
|
|
860
|
+
self.logger.info(f"Found {len(collections)} collections")
|
|
861
|
+
|
|
862
|
+
return collections
|