claude-mpm 3.4.10__py3-none-any.whl → 5.4.55__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_OUTPUT_STYLE.md +290 -0
- claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +2002 -0
- claude_mpm/agents/MEMORY.md +72 -0
- claude_mpm/agents/PM_INSTRUCTIONS.md +1402 -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 +90 -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 +2503 -168
- claude_mpm/cli/commands/agents_cleanup.py +210 -0
- claude_mpm/cli/commands/agents_discover.py +338 -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 +2654 -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 +1246 -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 +297 -0
- claude_mpm/cli/helpers.py +105 -0
- claude_mpm/cli/interactive/__init__.py +21 -0
- claude_mpm/cli/interactive/agent_wizard.py +1947 -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 +644 -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 +1743 -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 +132 -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 +483 -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 +570 -0
- claude_mpm/core/unified_paths.py +941 -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/__pycache__/__init__.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/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/__pycache__/__init__.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/connection_manager.py +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 +1369 -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_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/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 +1202 -0
- claude_mpm/services/agents/startup_sync.py +259 -0
- claude_mpm/services/agents/toolchain_detector.py +478 -0
- claude_mpm/services/analysis/__init__.py +35 -0
- claude_mpm/services/analysis/clone_detector.py +1030 -0
- claude_mpm/services/analysis/postmortem_reporter.py +474 -0
- claude_mpm/services/analysis/postmortem_service.py +765 -0
- claude_mpm/services/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 +707 -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 +1324 -0
- claude_mpm/services/skills/selective_skill_deployer.py +744 -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/database-migration.md +199 -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/scripts/validate_env.py +576 -0
- claude_mpm/skills/bundled/json-data-handling.md +223 -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/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/refactoring-patterns.md +180 -0
- claude_mpm/skills/bundled/security-scanning.md +439 -0
- claude_mpm/skills/bundled/systematic-debugging.md +473 -0
- claude_mpm/skills/bundled/test-driven-development.md +378 -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/scripts/with_server.py +129 -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 +1090 -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 +823 -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.55.dist-info/METADATA +999 -0
- claude_mpm-5.4.55.dist-info/RECORD +868 -0
- {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.55.dist-info}/entry_points.txt +1 -3
- claude_mpm-5.4.55.dist-info/licenses/LICENSE +94 -0
- claude_mpm-5.4.55.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.55.dist-info}/WHEEL +0 -0
- {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.55.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,1037 @@
|
|
|
1
|
+
"""Agent deployment service for Claude Code native subagents.
|
|
2
|
+
|
|
3
|
+
This service handles the complete lifecycle of agent deployment:
|
|
4
|
+
1. Building agent YAML files from JSON templates
|
|
5
|
+
2. Managing versioning and updates
|
|
6
|
+
3. Deploying to Claude Code's .claude/agents directory
|
|
7
|
+
4. Environment configuration for agent discovery
|
|
8
|
+
5. Deployment verification and cleanup
|
|
9
|
+
|
|
10
|
+
OPERATIONAL CONSIDERATIONS:
|
|
11
|
+
- Deployment is idempotent - safe to run multiple times
|
|
12
|
+
- Version checking prevents unnecessary rebuilds (saves I/O)
|
|
13
|
+
- Supports force rebuild for troubleshooting
|
|
14
|
+
- Maintains backward compatibility with legacy versions
|
|
15
|
+
- Handles migration from old serial versioning to semantic versioning
|
|
16
|
+
|
|
17
|
+
MONITORING:
|
|
18
|
+
- Check logs for deployment status and errors
|
|
19
|
+
- Monitor disk space in .claude/agents directory
|
|
20
|
+
- Track version migration progress
|
|
21
|
+
- Verify agent discovery after deployment
|
|
22
|
+
|
|
23
|
+
ROLLBACK PROCEDURES:
|
|
24
|
+
- Keep backups of .claude/agents before major updates
|
|
25
|
+
- Use clean_deployment() to remove system agents
|
|
26
|
+
- User-created agents are preserved during cleanup
|
|
27
|
+
- Version tracking allows targeted rollbacks
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
import time
|
|
31
|
+
from pathlib import Path
|
|
32
|
+
from typing import Any, Dict, List, Optional, Tuple
|
|
33
|
+
|
|
34
|
+
from claude_mpm.config.agent_sources import AgentSourceConfiguration
|
|
35
|
+
from claude_mpm.config.paths import paths
|
|
36
|
+
from claude_mpm.constants import Paths
|
|
37
|
+
from claude_mpm.core.config import Config
|
|
38
|
+
from claude_mpm.core.exceptions import AgentDeploymentError
|
|
39
|
+
from claude_mpm.core.interfaces import AgentDeploymentInterface
|
|
40
|
+
from claude_mpm.services.shared import ConfigServiceBase
|
|
41
|
+
|
|
42
|
+
# Import git source management for remote agent sync
|
|
43
|
+
from ..git_source_manager import GitSourceManager
|
|
44
|
+
from .agent_configuration_manager import AgentConfigurationManager
|
|
45
|
+
from .agent_discovery_service import AgentDiscoveryService
|
|
46
|
+
from .agent_environment_manager import AgentEnvironmentManager
|
|
47
|
+
from .agent_filesystem_manager import AgentFileSystemManager
|
|
48
|
+
from .agent_format_converter import AgentFormatConverter
|
|
49
|
+
from .agent_metrics_collector import AgentMetricsCollector
|
|
50
|
+
from .agent_template_builder import AgentTemplateBuilder
|
|
51
|
+
from .agent_validator import AgentValidator
|
|
52
|
+
from .agent_version_manager import AgentVersionManager
|
|
53
|
+
from .base_agent_locator import BaseAgentLocator
|
|
54
|
+
from .deployment_results_manager import DeploymentResultsManager
|
|
55
|
+
from .multi_source_deployment_service import MultiSourceAgentDeploymentService
|
|
56
|
+
from .single_agent_deployer import SingleAgentDeployer
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class AgentDeploymentService(ConfigServiceBase, AgentDeploymentInterface):
|
|
60
|
+
"""Service for deploying Claude Code native agents.
|
|
61
|
+
|
|
62
|
+
METRICS COLLECTION OPPORTUNITIES:
|
|
63
|
+
This service could collect valuable deployment metrics including:
|
|
64
|
+
- Agent deployment frequency and success rates
|
|
65
|
+
- Template validation performance
|
|
66
|
+
- Version migration patterns
|
|
67
|
+
- Deployment duration by agent type
|
|
68
|
+
- Cache hit rates for agent templates
|
|
69
|
+
- Resource usage during deployment (memory, CPU)
|
|
70
|
+
- Agent file sizes and complexity metrics
|
|
71
|
+
- Deployment failure reasons and patterns
|
|
72
|
+
|
|
73
|
+
DEPLOYMENT PIPELINE:
|
|
74
|
+
1. Initialize with template and base agent paths
|
|
75
|
+
2. Load base agent configuration (shared settings)
|
|
76
|
+
3. Iterate through agent templates
|
|
77
|
+
4. Check version and update requirements
|
|
78
|
+
5. Build YAML files with proper formatting
|
|
79
|
+
6. Deploy to target directory
|
|
80
|
+
7. Set environment variables for discovery
|
|
81
|
+
8. Verify deployment success
|
|
82
|
+
|
|
83
|
+
ENVIRONMENT REQUIREMENTS:
|
|
84
|
+
- Write access to .claude/agents directory
|
|
85
|
+
- Python 3.8+ for pathlib and typing features
|
|
86
|
+
- JSON parsing for template files
|
|
87
|
+
- YAML generation capabilities
|
|
88
|
+
"""
|
|
89
|
+
|
|
90
|
+
def __init__(
|
|
91
|
+
self,
|
|
92
|
+
templates_dir: Optional[Path] = None,
|
|
93
|
+
base_agent_path: Optional[Path] = None,
|
|
94
|
+
working_directory: Optional[Path] = None,
|
|
95
|
+
config: Optional[Config] = None,
|
|
96
|
+
):
|
|
97
|
+
"""
|
|
98
|
+
Initialize agent deployment service.
|
|
99
|
+
|
|
100
|
+
Args:
|
|
101
|
+
templates_dir: Directory containing agent JSON files
|
|
102
|
+
base_agent_path: Path to base_agent.md file
|
|
103
|
+
working_directory: User's working directory (for project agents)
|
|
104
|
+
config: Configuration instance
|
|
105
|
+
|
|
106
|
+
METRICS OPPORTUNITY: Track initialization performance:
|
|
107
|
+
- Template directory scan time
|
|
108
|
+
- Base agent loading time
|
|
109
|
+
- Initial validation overhead
|
|
110
|
+
"""
|
|
111
|
+
# Initialize base class with configuration
|
|
112
|
+
super().__init__("agent_deployment", config=config)
|
|
113
|
+
|
|
114
|
+
# Initialize template builder service
|
|
115
|
+
self.template_builder = AgentTemplateBuilder()
|
|
116
|
+
|
|
117
|
+
# Initialize version manager service
|
|
118
|
+
self.version_manager = AgentVersionManager()
|
|
119
|
+
|
|
120
|
+
# Initialize metrics collector service
|
|
121
|
+
self.metrics_collector = AgentMetricsCollector()
|
|
122
|
+
|
|
123
|
+
# Initialize environment manager service
|
|
124
|
+
self.environment_manager = AgentEnvironmentManager()
|
|
125
|
+
|
|
126
|
+
# Initialize validator service
|
|
127
|
+
self.validator = AgentValidator()
|
|
128
|
+
|
|
129
|
+
# Initialize base agent locator service
|
|
130
|
+
self.base_agent_locator = BaseAgentLocator(self.logger)
|
|
131
|
+
|
|
132
|
+
# Initialize deployment results manager
|
|
133
|
+
self.results_manager = DeploymentResultsManager(self.logger)
|
|
134
|
+
|
|
135
|
+
# Initialize single agent deployer
|
|
136
|
+
self.single_agent_deployer = SingleAgentDeployer(
|
|
137
|
+
self.template_builder,
|
|
138
|
+
self.version_manager,
|
|
139
|
+
self.results_manager,
|
|
140
|
+
self.logger,
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
# Initialize filesystem manager service
|
|
144
|
+
self.filesystem_manager = AgentFileSystemManager()
|
|
145
|
+
|
|
146
|
+
# Determine the actual working directory using configuration
|
|
147
|
+
# Priority: param > config > environment > current directory
|
|
148
|
+
self.working_directory = self.get_config_value(
|
|
149
|
+
"working_directory",
|
|
150
|
+
default=working_directory or Path.cwd(),
|
|
151
|
+
config_type=Path,
|
|
152
|
+
)
|
|
153
|
+
self.logger.info(f"Working directory for deployment: {self.working_directory}")
|
|
154
|
+
|
|
155
|
+
# Find templates directory using configuration
|
|
156
|
+
# Priority: param > config > default paths
|
|
157
|
+
self.templates_dir = self.get_config_value(
|
|
158
|
+
"templates_dir",
|
|
159
|
+
default=templates_dir or paths.agents_dir / "templates",
|
|
160
|
+
config_type=Path,
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
# Initialize discovery service (after templates_dir is set)
|
|
164
|
+
self.discovery_service = AgentDiscoveryService(self.templates_dir)
|
|
165
|
+
|
|
166
|
+
# Initialize multi-source deployment service for version comparison
|
|
167
|
+
self.multi_source_service = MultiSourceAgentDeploymentService()
|
|
168
|
+
|
|
169
|
+
# Find base agent file using configuration
|
|
170
|
+
# Priority: param > config > search
|
|
171
|
+
configured_base_agent = self.get_config_value(
|
|
172
|
+
"base_agent_path", config_type=Path
|
|
173
|
+
)
|
|
174
|
+
if base_agent_path:
|
|
175
|
+
self.base_agent_path = Path(base_agent_path)
|
|
176
|
+
elif configured_base_agent:
|
|
177
|
+
self.base_agent_path = configured_base_agent
|
|
178
|
+
else:
|
|
179
|
+
# Priority-based search for base_agent.json
|
|
180
|
+
self.base_agent_path = self.base_agent_locator.find_base_agent_file(
|
|
181
|
+
paths.agents_dir
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
# Initialize configuration manager (after base_agent_path is set)
|
|
185
|
+
self.configuration_manager = AgentConfigurationManager(self.base_agent_path)
|
|
186
|
+
|
|
187
|
+
# Initialize format converter service
|
|
188
|
+
self.format_converter = AgentFormatConverter()
|
|
189
|
+
|
|
190
|
+
# Initialize git source manager for remote agent sync
|
|
191
|
+
self.git_source_manager = GitSourceManager()
|
|
192
|
+
self.agent_source_config = AgentSourceConfiguration.load()
|
|
193
|
+
|
|
194
|
+
self.logger.info(f"Templates directory: {self.templates_dir}")
|
|
195
|
+
self.logger.info(f"Base agent path: {self.base_agent_path}")
|
|
196
|
+
|
|
197
|
+
def _sync_remote_agent_sources(self, timeout_seconds: int = 30) -> Dict[str, Any]:
|
|
198
|
+
"""Sync git-based agent sources before deployment.
|
|
199
|
+
|
|
200
|
+
This method follows the skills system pattern: sync configured git repositories
|
|
201
|
+
to cache before discovery. Network failures are logged but don't block deployment.
|
|
202
|
+
|
|
203
|
+
Args:
|
|
204
|
+
timeout_seconds: Timeout for git operations (default: 30 seconds)
|
|
205
|
+
|
|
206
|
+
Returns:
|
|
207
|
+
Dictionary with sync results:
|
|
208
|
+
{
|
|
209
|
+
"synced_count": int,
|
|
210
|
+
"failed_count": int,
|
|
211
|
+
"repositories": Dict[str, Dict], # repo_id -> sync result
|
|
212
|
+
"duration_ms": float
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
Error Handling:
|
|
216
|
+
- Network failures: Logged as warnings, sync continues
|
|
217
|
+
- Invalid repos: Logged as errors, sync continues
|
|
218
|
+
- Timeout: Individual repo timeouts don't stop overall sync
|
|
219
|
+
- Missing cache dir: Created automatically
|
|
220
|
+
"""
|
|
221
|
+
import time
|
|
222
|
+
|
|
223
|
+
start_time = time.time()
|
|
224
|
+
|
|
225
|
+
results = {
|
|
226
|
+
"synced_count": 0,
|
|
227
|
+
"failed_count": 0,
|
|
228
|
+
"repositories": {},
|
|
229
|
+
"duration_ms": 0,
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
# Load agent sources configuration
|
|
233
|
+
try:
|
|
234
|
+
config = AgentSourceConfiguration.load()
|
|
235
|
+
enabled_repos = [r for r in config.repositories if r.enabled]
|
|
236
|
+
|
|
237
|
+
if not enabled_repos:
|
|
238
|
+
self.logger.debug("No enabled agent sources configured")
|
|
239
|
+
return results
|
|
240
|
+
|
|
241
|
+
self.logger.info(f"Syncing {len(enabled_repos)} agent git sources...")
|
|
242
|
+
|
|
243
|
+
# Sync each enabled repository
|
|
244
|
+
for repo in enabled_repos:
|
|
245
|
+
repo_id = repo.identifier
|
|
246
|
+
try:
|
|
247
|
+
# Sync with timeout (individual repo sync)
|
|
248
|
+
# NOTE: show_progress=False to avoid duplicate progress bars
|
|
249
|
+
# (startup sync already showed progress to user)
|
|
250
|
+
sync_result = self.git_source_manager.sync_repository(
|
|
251
|
+
repo,
|
|
252
|
+
force=False, # Use ETag-based caching
|
|
253
|
+
show_progress=False, # Suppress progress (startup already synced)
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
results["repositories"][repo_id] = sync_result
|
|
257
|
+
|
|
258
|
+
if sync_result.get("synced"):
|
|
259
|
+
results["synced_count"] += 1
|
|
260
|
+
agents_discovered = sync_result.get("agents_discovered", [])
|
|
261
|
+
self.logger.info(
|
|
262
|
+
f"Synced {repo_id}: {sync_result.get('files_updated', 0)} files, "
|
|
263
|
+
f"{len(agents_discovered)} agents"
|
|
264
|
+
)
|
|
265
|
+
else:
|
|
266
|
+
results["failed_count"] += 1
|
|
267
|
+
error = sync_result.get("error", "Unknown error")
|
|
268
|
+
self.logger.warning(f"Failed to sync {repo_id}: {error}")
|
|
269
|
+
|
|
270
|
+
except Exception as e:
|
|
271
|
+
# Don't let individual repo failures stop deployment
|
|
272
|
+
results["failed_count"] += 1
|
|
273
|
+
results["repositories"][repo_id] = {
|
|
274
|
+
"synced": False,
|
|
275
|
+
"error": str(e),
|
|
276
|
+
}
|
|
277
|
+
self.logger.warning(f"Exception syncing {repo_id}: {e}")
|
|
278
|
+
|
|
279
|
+
except Exception as e:
|
|
280
|
+
# Configuration loading failure - log but don't crash
|
|
281
|
+
self.logger.warning(f"Failed to load agent sources config: {e}")
|
|
282
|
+
results["failed_count"] = -1 # Indicates config failure
|
|
283
|
+
|
|
284
|
+
results["duration_ms"] = (time.time() - start_time) * 1000
|
|
285
|
+
|
|
286
|
+
if results["synced_count"] > 0:
|
|
287
|
+
self.logger.info(
|
|
288
|
+
f"Agent source sync complete: {results['synced_count']} succeeded, "
|
|
289
|
+
f"{results['failed_count']} failed ({results['duration_ms']:.0f}ms)"
|
|
290
|
+
)
|
|
291
|
+
|
|
292
|
+
return results
|
|
293
|
+
|
|
294
|
+
def deploy_agents(
|
|
295
|
+
self,
|
|
296
|
+
target_dir: Optional[Path] = None,
|
|
297
|
+
force_rebuild: bool = False,
|
|
298
|
+
deployment_mode: str = "update",
|
|
299
|
+
config: Optional[Config] = None,
|
|
300
|
+
use_async: bool = False,
|
|
301
|
+
) -> Dict[str, Any]:
|
|
302
|
+
"""
|
|
303
|
+
Build and deploy agents by combining base_agent.md with templates.
|
|
304
|
+
Also deploys system instructions for PM framework.
|
|
305
|
+
|
|
306
|
+
DEPLOYMENT MODES:
|
|
307
|
+
- "update": Normal update mode - skip agents with matching versions (default)
|
|
308
|
+
- "project": Project deployment mode - always deploy all agents regardless of version
|
|
309
|
+
|
|
310
|
+
CONFIGURATION:
|
|
311
|
+
The config parameter or default configuration is used to determine:
|
|
312
|
+
- Which agents to exclude from deployment
|
|
313
|
+
- Case sensitivity for agent name matching
|
|
314
|
+
- Whether to exclude agent dependencies
|
|
315
|
+
|
|
316
|
+
METRICS COLLECTED:
|
|
317
|
+
- Deployment start/end timestamps
|
|
318
|
+
- Individual agent deployment durations
|
|
319
|
+
- Success/failure rates by agent type
|
|
320
|
+
- Version migration statistics
|
|
321
|
+
- Template validation performance
|
|
322
|
+
- Error type frequencies
|
|
323
|
+
|
|
324
|
+
OPERATIONAL FLOW:
|
|
325
|
+
0. Validates and repairs broken frontmatter in existing agents (Step 0)
|
|
326
|
+
1. Validates target directory (creates if needed)
|
|
327
|
+
2. Loads base agent configuration
|
|
328
|
+
3. Discovers all agent templates
|
|
329
|
+
4. For each agent:
|
|
330
|
+
- Checks if update needed (version comparison)
|
|
331
|
+
- Builds YAML configuration
|
|
332
|
+
- Writes to target directory
|
|
333
|
+
- Tracks deployment status
|
|
334
|
+
|
|
335
|
+
PERFORMANCE CONSIDERATIONS:
|
|
336
|
+
- Skips unchanged agents (version-based caching)
|
|
337
|
+
- Batch processes all agents in single pass
|
|
338
|
+
- Minimal file I/O with in-memory building
|
|
339
|
+
- Parallel-safe (no shared state mutations)
|
|
340
|
+
|
|
341
|
+
ERROR HANDLING:
|
|
342
|
+
- Continues deployment on individual agent failures
|
|
343
|
+
- Collects all errors for reporting
|
|
344
|
+
- Logs detailed error context
|
|
345
|
+
- Returns comprehensive results dict
|
|
346
|
+
|
|
347
|
+
MONITORING POINTS:
|
|
348
|
+
- Track total deployment time
|
|
349
|
+
- Monitor skipped vs updated vs new agents
|
|
350
|
+
- Check error rates and patterns
|
|
351
|
+
- Verify migration completion
|
|
352
|
+
|
|
353
|
+
Args:
|
|
354
|
+
target_dir: Target directory for agents (default: .claude/agents/)
|
|
355
|
+
force_rebuild: Force rebuild even if agents exist (useful for troubleshooting)
|
|
356
|
+
deployment_mode: "update" for version-aware updates, "project" for always deploy
|
|
357
|
+
config: Optional configuration object (loads default if not provided)
|
|
358
|
+
use_async: Use async operations for 50-70% faster deployment (default: True)
|
|
359
|
+
|
|
360
|
+
Returns:
|
|
361
|
+
Dictionary with deployment results:
|
|
362
|
+
- target_dir: Deployment location
|
|
363
|
+
- deployed: List of newly deployed agents
|
|
364
|
+
- updated: List of updated agents
|
|
365
|
+
- migrated: List of agents migrated to new version format
|
|
366
|
+
- skipped: List of unchanged agents
|
|
367
|
+
- errors: List of deployment errors
|
|
368
|
+
- total: Total number of agents processed
|
|
369
|
+
- repaired: List of agents with repaired frontmatter
|
|
370
|
+
"""
|
|
371
|
+
# METRICS: Record deployment start time for performance tracking
|
|
372
|
+
deployment_start_time = time.time()
|
|
373
|
+
|
|
374
|
+
# PHASE 2 (1M-442): Sync git-based agent sources before deployment
|
|
375
|
+
# This ensures remote agents from configured sources are cached and discoverable
|
|
376
|
+
sync_results = self._sync_remote_agent_sources()
|
|
377
|
+
|
|
378
|
+
# Try async deployment for better performance if requested
|
|
379
|
+
if use_async:
|
|
380
|
+
async_results = self._try_async_deployment(
|
|
381
|
+
target_dir=target_dir,
|
|
382
|
+
force_rebuild=force_rebuild,
|
|
383
|
+
config=config,
|
|
384
|
+
deployment_start_time=deployment_start_time,
|
|
385
|
+
)
|
|
386
|
+
if async_results is not None:
|
|
387
|
+
return async_results
|
|
388
|
+
|
|
389
|
+
# Continue with synchronous deployment
|
|
390
|
+
self.logger.info("Using synchronous deployment")
|
|
391
|
+
|
|
392
|
+
# Load and process configuration
|
|
393
|
+
config, excluded_agents = self._load_deployment_config(config)
|
|
394
|
+
|
|
395
|
+
# Determine target agents directory
|
|
396
|
+
agents_dir = self._determine_agents_directory(target_dir)
|
|
397
|
+
|
|
398
|
+
# Initialize results dictionary
|
|
399
|
+
results = self.results_manager.initialize_deployment_results(
|
|
400
|
+
agents_dir, deployment_start_time
|
|
401
|
+
)
|
|
402
|
+
|
|
403
|
+
# Add git source sync results to deployment results
|
|
404
|
+
if (
|
|
405
|
+
sync_results.get("synced_count", 0) > 0
|
|
406
|
+
or sync_results.get("failed_count", 0) > 0
|
|
407
|
+
):
|
|
408
|
+
results["remote_sources"] = sync_results
|
|
409
|
+
|
|
410
|
+
try:
|
|
411
|
+
# Create agents directory if needed
|
|
412
|
+
agents_dir.mkdir(parents=True, exist_ok=True)
|
|
413
|
+
|
|
414
|
+
# STEP 0: Validate and repair broken frontmatter in existing agents
|
|
415
|
+
self._repair_existing_agents(agents_dir, results)
|
|
416
|
+
|
|
417
|
+
# Log deployment source tier
|
|
418
|
+
source_tier = self.base_agent_locator.determine_source_tier(
|
|
419
|
+
self.templates_dir
|
|
420
|
+
)
|
|
421
|
+
self.logger.info(
|
|
422
|
+
f"Building and deploying {source_tier} agents to: {agents_dir}"
|
|
423
|
+
)
|
|
424
|
+
|
|
425
|
+
# Note: System instructions are now loaded directly by SimpleClaudeRunner
|
|
426
|
+
|
|
427
|
+
# Check if templates directory exists
|
|
428
|
+
if not self.templates_dir.exists():
|
|
429
|
+
error_msg = f"Agents directory not found: {self.templates_dir}"
|
|
430
|
+
self.logger.error(error_msg)
|
|
431
|
+
results["errors"].append(error_msg)
|
|
432
|
+
return results
|
|
433
|
+
|
|
434
|
+
# Convert any existing YAML files to MD format
|
|
435
|
+
conversion_results = self._convert_yaml_to_md(agents_dir)
|
|
436
|
+
results["converted"] = conversion_results.get("converted", [])
|
|
437
|
+
|
|
438
|
+
# Load base agent content
|
|
439
|
+
base_agent_data, base_agent_version = self._load_base_agent()
|
|
440
|
+
|
|
441
|
+
# Check if we should use multi-source deployment
|
|
442
|
+
use_multi_source = self._should_use_multi_source_deployment(deployment_mode)
|
|
443
|
+
|
|
444
|
+
if use_multi_source:
|
|
445
|
+
# Use multi-source deployment to get highest version agents
|
|
446
|
+
template_files, agent_sources, cleanup_results = (
|
|
447
|
+
self._get_multi_source_templates(
|
|
448
|
+
excluded_agents, config, agents_dir, force_rebuild
|
|
449
|
+
)
|
|
450
|
+
)
|
|
451
|
+
results["total"] = len(template_files)
|
|
452
|
+
results["multi_source"] = True
|
|
453
|
+
results["agent_sources"] = agent_sources
|
|
454
|
+
results["cleanup"] = cleanup_results
|
|
455
|
+
|
|
456
|
+
# Log cleanup results if any agents were removed
|
|
457
|
+
if cleanup_results.get("removed"):
|
|
458
|
+
self.logger.info(
|
|
459
|
+
f"Cleaned up {len(cleanup_results['removed'])} outdated user agents"
|
|
460
|
+
)
|
|
461
|
+
for removed in cleanup_results["removed"]:
|
|
462
|
+
self.logger.debug(
|
|
463
|
+
f" - Removed: {removed['name']} v{removed['version']} ({removed['reason']})"
|
|
464
|
+
)
|
|
465
|
+
else:
|
|
466
|
+
# Get and filter template files from single source
|
|
467
|
+
template_files = self._get_filtered_templates(excluded_agents, config)
|
|
468
|
+
results["total"] = len(template_files)
|
|
469
|
+
agent_sources = {}
|
|
470
|
+
|
|
471
|
+
# Deploy each agent template
|
|
472
|
+
for template_file in template_files:
|
|
473
|
+
template_file_path = (
|
|
474
|
+
template_file
|
|
475
|
+
if isinstance(template_file, Path)
|
|
476
|
+
else Path(template_file)
|
|
477
|
+
)
|
|
478
|
+
agent_name = template_file_path.stem
|
|
479
|
+
|
|
480
|
+
# Get source info for this agent (agent_sources now uses file stems as keys)
|
|
481
|
+
source_info = (
|
|
482
|
+
agent_sources.get(agent_name, "unknown")
|
|
483
|
+
if agent_sources
|
|
484
|
+
else "single"
|
|
485
|
+
)
|
|
486
|
+
|
|
487
|
+
# When using multi-source deployment, we've already determined which
|
|
488
|
+
# agents need updates. Don't re-check versions in single_agent_deployer.
|
|
489
|
+
# This prevents the issue where multi-source says "deploying 9 agents"
|
|
490
|
+
# but then all get skipped due to redundant version checks.
|
|
491
|
+
skip_version_check = use_multi_source and not force_rebuild
|
|
492
|
+
|
|
493
|
+
self.single_agent_deployer.deploy_single_agent(
|
|
494
|
+
template_file=template_file_path,
|
|
495
|
+
agents_dir=agents_dir,
|
|
496
|
+
base_agent_data=base_agent_data,
|
|
497
|
+
base_agent_version=base_agent_version,
|
|
498
|
+
force_rebuild=force_rebuild or skip_version_check,
|
|
499
|
+
deployment_mode=deployment_mode,
|
|
500
|
+
results=results,
|
|
501
|
+
source_info=source_info,
|
|
502
|
+
)
|
|
503
|
+
|
|
504
|
+
# CRITICAL: System instructions deployment disabled to prevent automatic file creation
|
|
505
|
+
# The system should NEVER automatically write INSTRUCTIONS.md, MEMORY.md, WORKFLOW.md
|
|
506
|
+
# to .claude/ directory. These files should only be created when explicitly requested
|
|
507
|
+
# by the user through agent-manager commands.
|
|
508
|
+
# See deploy_system_instructions_explicit() for manual deployment.
|
|
509
|
+
# self._deploy_system_instructions(agents_dir, force_rebuild, results)
|
|
510
|
+
|
|
511
|
+
self.logger.info(
|
|
512
|
+
f"Deployed {len(results['deployed'])} agents, "
|
|
513
|
+
f"updated {len(results['updated'])}, "
|
|
514
|
+
f"migrated {len(results['migrated'])}, "
|
|
515
|
+
f"converted {len(results['converted'])} YAML files, "
|
|
516
|
+
f"repaired {len(results['repaired'])} frontmatter, "
|
|
517
|
+
f"skipped {len(results['skipped'])}, "
|
|
518
|
+
f"errors: {len(results['errors'])}"
|
|
519
|
+
)
|
|
520
|
+
|
|
521
|
+
except AgentDeploymentError as e:
|
|
522
|
+
# Custom error with context already formatted
|
|
523
|
+
self.logger.error(str(e))
|
|
524
|
+
results["errors"].append(str(e))
|
|
525
|
+
except Exception as e:
|
|
526
|
+
# Wrap unexpected errors
|
|
527
|
+
error_msg = f"Agent deployment failed: {e}"
|
|
528
|
+
self.logger.error(error_msg)
|
|
529
|
+
results["errors"].append(error_msg)
|
|
530
|
+
|
|
531
|
+
# METRICS: Track deployment failure
|
|
532
|
+
self.results_manager.update_deployment_metrics(False, type(e).__name__)
|
|
533
|
+
|
|
534
|
+
# METRICS: Calculate final deployment metrics
|
|
535
|
+
self.results_manager.finalize_results(results, deployment_start_time)
|
|
536
|
+
|
|
537
|
+
# METRICS: Update rolling averages and statistics
|
|
538
|
+
deployment_duration = results["metrics"].get("duration_ms", 0)
|
|
539
|
+
self.metrics_collector.update_deployment_metrics(deployment_duration, results)
|
|
540
|
+
|
|
541
|
+
return results
|
|
542
|
+
|
|
543
|
+
def get_deployment_metrics(self) -> Dict[str, Any]:
|
|
544
|
+
"""Get current deployment metrics."""
|
|
545
|
+
return self.results_manager.get_deployment_metrics()
|
|
546
|
+
|
|
547
|
+
def reset_metrics(self) -> None:
|
|
548
|
+
"""Reset deployment metrics."""
|
|
549
|
+
return self.results_manager.reset_metrics()
|
|
550
|
+
|
|
551
|
+
def set_claude_environment(
|
|
552
|
+
self, config_dir: Optional[Path] = None
|
|
553
|
+
) -> Dict[str, str]:
|
|
554
|
+
"""Set Claude environment variables for agent discovery."""
|
|
555
|
+
if not config_dir:
|
|
556
|
+
config_dir = self.working_directory / Paths.CLAUDE_CONFIG_DIR.value
|
|
557
|
+
return self.environment_manager.set_claude_environment(config_dir)
|
|
558
|
+
|
|
559
|
+
def verify_deployment(self, config_dir: Optional[Path] = None) -> Dict[str, Any]:
|
|
560
|
+
"""Verify agent deployment and Claude configuration."""
|
|
561
|
+
if not config_dir:
|
|
562
|
+
config_dir = self.working_directory / ".claude"
|
|
563
|
+
return self.validator.verify_deployment(config_dir)
|
|
564
|
+
|
|
565
|
+
def deploy_agent(
|
|
566
|
+
self, agent_name: str, target_dir: Path, force_rebuild: bool = False
|
|
567
|
+
) -> bool:
|
|
568
|
+
"""
|
|
569
|
+
Deploy a single agent to the specified directory.
|
|
570
|
+
|
|
571
|
+
Args:
|
|
572
|
+
agent_name: Name of the agent to deploy
|
|
573
|
+
target_dir: Target directory for deployment (Path object)
|
|
574
|
+
force_rebuild: Whether to force rebuild even if version is current
|
|
575
|
+
|
|
576
|
+
Returns:
|
|
577
|
+
True if deployment was successful, False otherwise
|
|
578
|
+
|
|
579
|
+
WHY: Single agent deployment because:
|
|
580
|
+
- Users may want to deploy specific agents only
|
|
581
|
+
- Reduces deployment time for targeted updates
|
|
582
|
+
- Enables selective agent management in projects
|
|
583
|
+
|
|
584
|
+
FIXED: Method now correctly handles all internal calls to:
|
|
585
|
+
- _check_agent_needs_update (with 3 arguments)
|
|
586
|
+
- _build_agent_markdown (with 3 arguments including base_agent_data)
|
|
587
|
+
- Properly loads base_agent_data before building agent content
|
|
588
|
+
"""
|
|
589
|
+
try:
|
|
590
|
+
return self.single_agent_deployer.deploy_agent(
|
|
591
|
+
agent_name,
|
|
592
|
+
self.templates_dir,
|
|
593
|
+
target_dir,
|
|
594
|
+
self.base_agent_path,
|
|
595
|
+
force_rebuild,
|
|
596
|
+
self.working_directory,
|
|
597
|
+
)
|
|
598
|
+
|
|
599
|
+
except AgentDeploymentError:
|
|
600
|
+
# Re-raise our custom exceptions
|
|
601
|
+
raise
|
|
602
|
+
except Exception as e:
|
|
603
|
+
# Wrap generic exceptions with context
|
|
604
|
+
raise AgentDeploymentError(
|
|
605
|
+
f"Failed to deploy agent {agent_name}",
|
|
606
|
+
context={"agent_name": agent_name, "error": str(e)},
|
|
607
|
+
) from e
|
|
608
|
+
|
|
609
|
+
def list_available_agents(self) -> List[Dict[str, Any]]:
|
|
610
|
+
"""List available agent templates."""
|
|
611
|
+
return self.discovery_service.list_available_agents()
|
|
612
|
+
|
|
613
|
+
def clean_deployment(self, config_dir: Optional[Path] = None) -> Dict[str, Any]:
|
|
614
|
+
"""Clean up deployed agents."""
|
|
615
|
+
if not config_dir:
|
|
616
|
+
config_dir = self.working_directory / ".claude"
|
|
617
|
+
return self.filesystem_manager.clean_deployment(config_dir)
|
|
618
|
+
|
|
619
|
+
def _get_agent_tools(self, agent_name: str, metadata: Dict[str, Any]) -> List[str]:
|
|
620
|
+
"""Get appropriate tools for an agent based on its type."""
|
|
621
|
+
from .agent_config_provider import AgentConfigProvider
|
|
622
|
+
|
|
623
|
+
return AgentConfigProvider.get_agent_tools(agent_name, metadata)
|
|
624
|
+
|
|
625
|
+
def _get_agent_specific_config(self, agent_name: str) -> Dict[str, Any]:
|
|
626
|
+
"""Get agent-specific configuration based on agent type."""
|
|
627
|
+
from .agent_config_provider import AgentConfigProvider
|
|
628
|
+
|
|
629
|
+
return AgentConfigProvider.get_agent_specific_config(agent_name)
|
|
630
|
+
|
|
631
|
+
def _deploy_system_instructions(
|
|
632
|
+
self, target_dir: Path, force_rebuild: bool, results: Dict[str, Any]
|
|
633
|
+
) -> None:
|
|
634
|
+
"""Deploy system instructions and framework files for PM framework."""
|
|
635
|
+
from .system_instructions_deployer import SystemInstructionsDeployer
|
|
636
|
+
|
|
637
|
+
deployer = SystemInstructionsDeployer(self.logger, self.working_directory)
|
|
638
|
+
deployer.deploy_system_instructions(target_dir, force_rebuild, results)
|
|
639
|
+
|
|
640
|
+
def deploy_system_instructions_explicit(
|
|
641
|
+
self, target_dir: Optional[Path] = None, force_rebuild: bool = False
|
|
642
|
+
) -> Dict[str, Any]:
|
|
643
|
+
"""
|
|
644
|
+
Explicitly deploy system instructions when requested by user.
|
|
645
|
+
|
|
646
|
+
This method should ONLY be called when the user explicitly requests
|
|
647
|
+
deployment of system instructions through agent-manager commands.
|
|
648
|
+
It will deploy INSTRUCTIONS.md, MEMORY.md, and WORKFLOW.md to .claude/
|
|
649
|
+
directory in the project.
|
|
650
|
+
|
|
651
|
+
Args:
|
|
652
|
+
target_dir: Target directory for deployment (ignored - always uses .claude/)
|
|
653
|
+
force_rebuild: Force rebuild even if files exist
|
|
654
|
+
|
|
655
|
+
Returns:
|
|
656
|
+
Dict with deployment results
|
|
657
|
+
"""
|
|
658
|
+
results = {
|
|
659
|
+
"deployed": [],
|
|
660
|
+
"updated": [],
|
|
661
|
+
"skipped": [],
|
|
662
|
+
"errors": [],
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
try:
|
|
666
|
+
# Always use project's .claude directory
|
|
667
|
+
target_dir = self.working_directory / ".claude"
|
|
668
|
+
|
|
669
|
+
# Ensure directory exists
|
|
670
|
+
target_dir.mkdir(parents=True, exist_ok=True)
|
|
671
|
+
|
|
672
|
+
# Deploy using the deployer (targeting .claude/)
|
|
673
|
+
from .system_instructions_deployer import SystemInstructionsDeployer
|
|
674
|
+
|
|
675
|
+
deployer = SystemInstructionsDeployer(self.logger, self.working_directory)
|
|
676
|
+
|
|
677
|
+
# Deploy to .claude directory
|
|
678
|
+
deployer.deploy_system_instructions(target_dir, force_rebuild, results)
|
|
679
|
+
|
|
680
|
+
self.logger.info(
|
|
681
|
+
f"Explicitly deployed system instructions to {target_dir}: "
|
|
682
|
+
f"deployed={len(results['deployed'])}, "
|
|
683
|
+
f"updated={len(results['updated'])}, "
|
|
684
|
+
f"skipped={len(results['skipped'])}"
|
|
685
|
+
)
|
|
686
|
+
|
|
687
|
+
except Exception as e:
|
|
688
|
+
error_msg = f"Failed to deploy system instructions: {e}"
|
|
689
|
+
self.logger.error(error_msg)
|
|
690
|
+
results["errors"].append(error_msg)
|
|
691
|
+
|
|
692
|
+
return results
|
|
693
|
+
|
|
694
|
+
def _convert_yaml_to_md(self, target_dir: Path) -> Dict[str, Any]:
|
|
695
|
+
"""Convert existing YAML agent files to MD format with YAML frontmatter."""
|
|
696
|
+
return self.format_converter.convert_yaml_to_md(target_dir)
|
|
697
|
+
|
|
698
|
+
def _convert_yaml_content_to_md(self, yaml_content: str, agent_name: str) -> str:
|
|
699
|
+
"""Convert YAML agent content to MD format with YAML frontmatter."""
|
|
700
|
+
return self.format_converter.convert_yaml_content_to_md(
|
|
701
|
+
yaml_content, agent_name
|
|
702
|
+
)
|
|
703
|
+
|
|
704
|
+
def _extract_yaml_field(self, yaml_content: str, field_name: str) -> str:
|
|
705
|
+
"""Extract a field value from YAML content."""
|
|
706
|
+
return self.format_converter.extract_yaml_field(yaml_content, field_name)
|
|
707
|
+
|
|
708
|
+
def _try_async_deployment(
|
|
709
|
+
self,
|
|
710
|
+
target_dir: Optional[Path],
|
|
711
|
+
force_rebuild: bool,
|
|
712
|
+
config: Optional[Config],
|
|
713
|
+
deployment_start_time: float,
|
|
714
|
+
) -> Optional[Dict[str, Any]]:
|
|
715
|
+
"""
|
|
716
|
+
Try to use async deployment for better performance.
|
|
717
|
+
|
|
718
|
+
WHY: Async deployment is 50-70% faster than synchronous deployment
|
|
719
|
+
by using concurrent operations for file I/O and processing.
|
|
720
|
+
|
|
721
|
+
Args:
|
|
722
|
+
target_dir: Target directory for deployment
|
|
723
|
+
force_rebuild: Whether to force rebuild
|
|
724
|
+
config: Configuration object
|
|
725
|
+
deployment_start_time: Start time for metrics
|
|
726
|
+
|
|
727
|
+
Returns:
|
|
728
|
+
Deployment results if successful, None if async not available
|
|
729
|
+
"""
|
|
730
|
+
try:
|
|
731
|
+
from .async_agent_deployment import deploy_agents_async_wrapper
|
|
732
|
+
|
|
733
|
+
self.logger.info("Using async deployment for improved performance")
|
|
734
|
+
|
|
735
|
+
# Run async deployment
|
|
736
|
+
results = deploy_agents_async_wrapper(
|
|
737
|
+
templates_dir=self.templates_dir,
|
|
738
|
+
base_agent_path=self.base_agent_path,
|
|
739
|
+
working_directory=self.working_directory,
|
|
740
|
+
target_dir=target_dir,
|
|
741
|
+
force_rebuild=force_rebuild,
|
|
742
|
+
config=config,
|
|
743
|
+
)
|
|
744
|
+
|
|
745
|
+
# Add metrics about async vs sync
|
|
746
|
+
if "metrics" in results:
|
|
747
|
+
results["metrics"]["deployment_method"] = "async"
|
|
748
|
+
duration_ms = results["metrics"].get("duration_ms", 0)
|
|
749
|
+
self.logger.info(f"Async deployment completed in {duration_ms:.1f}ms")
|
|
750
|
+
|
|
751
|
+
# Update internal metrics
|
|
752
|
+
self.results_manager.update_deployment_metrics(
|
|
753
|
+
not results.get("errors")
|
|
754
|
+
)
|
|
755
|
+
|
|
756
|
+
return results
|
|
757
|
+
|
|
758
|
+
except ImportError:
|
|
759
|
+
self.logger.warning("Async deployment not available, falling back to sync")
|
|
760
|
+
return None
|
|
761
|
+
except Exception as e:
|
|
762
|
+
self.logger.warning(f"Async deployment failed, falling back to sync: {e}")
|
|
763
|
+
return None
|
|
764
|
+
|
|
765
|
+
def _load_deployment_config(self, config: Optional[Config]) -> tuple:
|
|
766
|
+
"""Load and process deployment configuration."""
|
|
767
|
+
from .deployment_config_loader import DeploymentConfigLoader
|
|
768
|
+
|
|
769
|
+
loader = DeploymentConfigLoader(self.logger)
|
|
770
|
+
return loader.load_deployment_config(config)
|
|
771
|
+
|
|
772
|
+
def _determine_agents_directory(self, target_dir: Optional[Path]) -> Path:
|
|
773
|
+
"""Determine the correct agents directory based on input."""
|
|
774
|
+
from .agents_directory_resolver import AgentsDirectoryResolver
|
|
775
|
+
|
|
776
|
+
resolver = AgentsDirectoryResolver(self.working_directory)
|
|
777
|
+
return resolver.determine_agents_directory(target_dir)
|
|
778
|
+
|
|
779
|
+
def _repair_existing_agents(
|
|
780
|
+
self, agents_dir: Path, results: Dict[str, Any]
|
|
781
|
+
) -> None:
|
|
782
|
+
"""
|
|
783
|
+
Validate and repair broken frontmatter in existing agents.
|
|
784
|
+
|
|
785
|
+
WHY: Ensures all existing agents have valid YAML frontmatter
|
|
786
|
+
before deployment, preventing runtime errors in Claude Code.
|
|
787
|
+
|
|
788
|
+
Args:
|
|
789
|
+
agents_dir: Directory containing agent files
|
|
790
|
+
results: Results dictionary to update
|
|
791
|
+
"""
|
|
792
|
+
repair_results = self._validate_and_repair_existing_agents(agents_dir)
|
|
793
|
+
if repair_results["repaired"]:
|
|
794
|
+
results["repaired"] = repair_results["repaired"]
|
|
795
|
+
self.logger.info(
|
|
796
|
+
f"Repaired frontmatter in {len(repair_results['repaired'])} existing agents"
|
|
797
|
+
)
|
|
798
|
+
for agent_name in repair_results["repaired"]:
|
|
799
|
+
self.logger.debug(f" - Repaired: {agent_name}")
|
|
800
|
+
|
|
801
|
+
def _load_base_agent(self) -> tuple:
|
|
802
|
+
"""Load base agent content and version."""
|
|
803
|
+
return self.configuration_manager.load_base_agent()
|
|
804
|
+
|
|
805
|
+
def _get_filtered_templates(self, excluded_agents: list, config: Config) -> list:
|
|
806
|
+
"""Get and filter template files based on exclusion rules."""
|
|
807
|
+
filter_non_mpm = config.get("agent_deployment.filter_non_mpm_agents", True)
|
|
808
|
+
return self.discovery_service.get_filtered_templates(
|
|
809
|
+
excluded_agents, config, filter_non_mpm
|
|
810
|
+
)
|
|
811
|
+
|
|
812
|
+
def _validate_and_repair_existing_agents(self, agents_dir: Path) -> Dict[str, Any]:
|
|
813
|
+
"""Validate and repair broken frontmatter in existing agent files."""
|
|
814
|
+
from .agent_frontmatter_validator import AgentFrontmatterValidator
|
|
815
|
+
|
|
816
|
+
validator = AgentFrontmatterValidator(self.logger)
|
|
817
|
+
return validator.validate_and_repair_existing_agents(agents_dir)
|
|
818
|
+
|
|
819
|
+
def _should_use_multi_source_deployment(self, deployment_mode: str) -> bool:
|
|
820
|
+
"""Determine if multi-source deployment should be used.
|
|
821
|
+
|
|
822
|
+
WHY: Multi-source deployment ensures the highest version wins,
|
|
823
|
+
but we may want to preserve backward compatibility in some modes.
|
|
824
|
+
|
|
825
|
+
Args:
|
|
826
|
+
deployment_mode: Current deployment mode
|
|
827
|
+
|
|
828
|
+
Returns:
|
|
829
|
+
True if multi-source deployment should be used
|
|
830
|
+
"""
|
|
831
|
+
# Always use multi-source for update mode to get highest versions
|
|
832
|
+
if deployment_mode == "update":
|
|
833
|
+
return True
|
|
834
|
+
|
|
835
|
+
# For project mode, also use multi-source to ensure highest version wins
|
|
836
|
+
# This is the key change - project mode should also compare versions
|
|
837
|
+
return deployment_mode == "project"
|
|
838
|
+
|
|
839
|
+
def _get_multi_source_templates(
|
|
840
|
+
self,
|
|
841
|
+
excluded_agents: List[str],
|
|
842
|
+
config: Config,
|
|
843
|
+
agents_dir: Path,
|
|
844
|
+
force_rebuild: bool = False,
|
|
845
|
+
) -> Tuple[List[Path], Dict[str, str], Dict[str, Any]]:
|
|
846
|
+
"""Get agent templates from multiple sources with version comparison.
|
|
847
|
+
|
|
848
|
+
WHY: This method uses the multi-source service to discover agents
|
|
849
|
+
from all available sources and select the highest version of each.
|
|
850
|
+
|
|
851
|
+
Args:
|
|
852
|
+
excluded_agents: List of agents to exclude
|
|
853
|
+
config: Configuration object
|
|
854
|
+
agents_dir: Target deployment directory
|
|
855
|
+
force_rebuild: Whether to force rebuild
|
|
856
|
+
|
|
857
|
+
Returns:
|
|
858
|
+
Tuple of (template_files, agent_sources, cleanup_results)
|
|
859
|
+
"""
|
|
860
|
+
# Determine source directories
|
|
861
|
+
system_templates_dir = self.templates_dir
|
|
862
|
+
project_agents_dir = None
|
|
863
|
+
user_agents_dir = None
|
|
864
|
+
|
|
865
|
+
# Check for project agents
|
|
866
|
+
if self.working_directory:
|
|
867
|
+
potential_project_dir = self.working_directory / ".claude-mpm" / "agents"
|
|
868
|
+
if potential_project_dir.exists():
|
|
869
|
+
project_agents_dir = potential_project_dir
|
|
870
|
+
self.logger.info(f"Found project agents at: {project_agents_dir}")
|
|
871
|
+
|
|
872
|
+
# Check for user agents (DEPRECATED)
|
|
873
|
+
user_home = Path.home()
|
|
874
|
+
potential_user_dir = user_home / ".claude-mpm" / "agents"
|
|
875
|
+
if potential_user_dir.exists():
|
|
876
|
+
user_agents_dir = potential_user_dir
|
|
877
|
+
self.logger.info(f"Found user agents at: {user_agents_dir}")
|
|
878
|
+
|
|
879
|
+
# Check for agents cache (from Git sources)
|
|
880
|
+
agents_cache_dir = None
|
|
881
|
+
cache_dir = user_home / ".claude-mpm" / "cache"
|
|
882
|
+
potential_cache_dir = cache_dir / "agents"
|
|
883
|
+
if potential_cache_dir.exists():
|
|
884
|
+
agents_cache_dir = potential_cache_dir
|
|
885
|
+
self.logger.info(f"Found agents cache at: {agents_cache_dir}")
|
|
886
|
+
|
|
887
|
+
# Get agents with version comparison and cleanup (4-tier discovery)
|
|
888
|
+
agents_to_deploy, agent_sources, cleanup_results = (
|
|
889
|
+
self.multi_source_service.get_agents_for_deployment(
|
|
890
|
+
system_templates_dir=system_templates_dir,
|
|
891
|
+
project_agents_dir=project_agents_dir,
|
|
892
|
+
user_agents_dir=user_agents_dir,
|
|
893
|
+
agents_cache_dir=agents_cache_dir, # NEW: 4th tier
|
|
894
|
+
working_directory=self.working_directory,
|
|
895
|
+
excluded_agents=excluded_agents,
|
|
896
|
+
config=config,
|
|
897
|
+
cleanup_outdated=True, # Enable cleanup by default
|
|
898
|
+
)
|
|
899
|
+
)
|
|
900
|
+
|
|
901
|
+
# Keep track of all enabled agents before filtering (for cleanup)
|
|
902
|
+
all_enabled_agents = agents_to_deploy.copy()
|
|
903
|
+
|
|
904
|
+
# Compare with deployed versions if agents directory exists
|
|
905
|
+
if agents_dir.exists():
|
|
906
|
+
comparison_results = self.multi_source_service.compare_deployed_versions(
|
|
907
|
+
deployed_agents_dir=agents_dir,
|
|
908
|
+
agents_to_deploy=agents_to_deploy,
|
|
909
|
+
agent_sources=agent_sources,
|
|
910
|
+
)
|
|
911
|
+
|
|
912
|
+
# Filter agents based on comparison results (unless force_rebuild is set)
|
|
913
|
+
if not force_rebuild:
|
|
914
|
+
# Only deploy agents that need updates or are new
|
|
915
|
+
agents_needing_update = set(comparison_results.get("needs_update", []))
|
|
916
|
+
|
|
917
|
+
# Extract agent names from new_agents list (which contains dicts)
|
|
918
|
+
new_agent_names = [
|
|
919
|
+
agent["name"] if isinstance(agent, dict) else agent
|
|
920
|
+
for agent in comparison_results.get("new_agents", [])
|
|
921
|
+
]
|
|
922
|
+
agents_needing_update.update(new_agent_names)
|
|
923
|
+
|
|
924
|
+
# Filter agents_to_deploy to only include those needing updates
|
|
925
|
+
filtered_agents = {
|
|
926
|
+
name: path
|
|
927
|
+
for name, path in agents_to_deploy.items()
|
|
928
|
+
if name in agents_needing_update
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
# Only log upgrade messages if we're actually going to deploy them
|
|
932
|
+
if filtered_agents and comparison_results.get("version_upgrades"):
|
|
933
|
+
# Filter upgrades to only those actually being deployed
|
|
934
|
+
deployed_upgrades = [
|
|
935
|
+
upgrade
|
|
936
|
+
for upgrade in comparison_results["version_upgrades"]
|
|
937
|
+
if upgrade["name"] in filtered_agents
|
|
938
|
+
]
|
|
939
|
+
|
|
940
|
+
if deployed_upgrades:
|
|
941
|
+
self.logger.info(
|
|
942
|
+
f"Deploying {len(deployed_upgrades)} agent upgrade(s):"
|
|
943
|
+
)
|
|
944
|
+
for upgrade in deployed_upgrades:
|
|
945
|
+
self.logger.info(
|
|
946
|
+
f" Upgrading: {upgrade['name']} "
|
|
947
|
+
f"{upgrade['deployed_version']} -> {upgrade['new_version']} "
|
|
948
|
+
f"(from {upgrade['source']})"
|
|
949
|
+
)
|
|
950
|
+
|
|
951
|
+
agents_to_deploy = filtered_agents
|
|
952
|
+
|
|
953
|
+
# Don't log this redundant message - we already logged the upgrades above
|
|
954
|
+
# The "Deploying X agent upgrade(s)" message is sufficient
|
|
955
|
+
if not agents_to_deploy:
|
|
956
|
+
self.logger.debug(
|
|
957
|
+
f"All {len(comparison_results.get('up_to_date', []))} agents are up to date"
|
|
958
|
+
)
|
|
959
|
+
|
|
960
|
+
# Cleanup excluded agents (remove agents not in deployment list)
|
|
961
|
+
# CRITICAL: Use all_enabled_agents (before filtering for updates) to preserve up-to-date agents
|
|
962
|
+
# Bug fix (1M-XXX): Previously used filtered agents_to_deploy which could be empty,
|
|
963
|
+
# causing all agents to be removed when everything was up-to-date
|
|
964
|
+
exclusion_cleanup_results = self.multi_source_service.cleanup_excluded_agents(
|
|
965
|
+
deployed_agents_dir=agents_dir,
|
|
966
|
+
agents_to_deploy=all_enabled_agents,
|
|
967
|
+
)
|
|
968
|
+
|
|
969
|
+
# Add exclusion cleanup results to main cleanup results
|
|
970
|
+
if exclusion_cleanup_results.get("removed"):
|
|
971
|
+
cleanup_results.setdefault("excluded_removed", []).extend(
|
|
972
|
+
exclusion_cleanup_results["removed"]
|
|
973
|
+
)
|
|
974
|
+
self.logger.info(
|
|
975
|
+
f"Removed {len(exclusion_cleanup_results['removed'])} excluded agents: "
|
|
976
|
+
f"{', '.join(exclusion_cleanup_results['removed'])}"
|
|
977
|
+
)
|
|
978
|
+
|
|
979
|
+
# Convert to list of Path objects
|
|
980
|
+
template_files = list(agents_to_deploy.values())
|
|
981
|
+
|
|
982
|
+
return template_files, agent_sources, cleanup_results
|
|
983
|
+
|
|
984
|
+
# ================================================================================
|
|
985
|
+
# Interface Adapter Methods
|
|
986
|
+
# ================================================================================
|
|
987
|
+
# These methods adapt the existing implementation to comply with AgentDeploymentInterface
|
|
988
|
+
|
|
989
|
+
def validate_agent(self, agent_path: Path) -> tuple[bool, List[str]]:
|
|
990
|
+
"""Validate agent configuration and structure.
|
|
991
|
+
|
|
992
|
+
WHY: This adapter method provides interface compliance while leveraging
|
|
993
|
+
the existing validation logic in _check_agent_needs_update and other methods.
|
|
994
|
+
|
|
995
|
+
Args:
|
|
996
|
+
agent_path: Path to agent configuration file
|
|
997
|
+
|
|
998
|
+
Returns:
|
|
999
|
+
Tuple of (is_valid, list_of_errors)
|
|
1000
|
+
"""
|
|
1001
|
+
errors = []
|
|
1002
|
+
|
|
1003
|
+
try:
|
|
1004
|
+
if not agent_path.exists():
|
|
1005
|
+
return False, [f"Agent file not found: {agent_path}"]
|
|
1006
|
+
|
|
1007
|
+
content = agent_path.read_text()
|
|
1008
|
+
|
|
1009
|
+
# Check YAML frontmatter format
|
|
1010
|
+
if not content.startswith("---"):
|
|
1011
|
+
errors.append("Missing YAML frontmatter")
|
|
1012
|
+
|
|
1013
|
+
# Extract and validate version
|
|
1014
|
+
import re
|
|
1015
|
+
|
|
1016
|
+
version_match = re.search(
|
|
1017
|
+
r'^version:\s*["\']?(.+?)["\']?$', content, re.MULTILINE
|
|
1018
|
+
)
|
|
1019
|
+
if not version_match:
|
|
1020
|
+
errors.append("Missing version field in frontmatter")
|
|
1021
|
+
|
|
1022
|
+
# Check for required fields
|
|
1023
|
+
required_fields = ["name", "description", "tools"]
|
|
1024
|
+
for field in required_fields:
|
|
1025
|
+
field_match = re.search(rf"^{field}:\s*.+$", content, re.MULTILINE)
|
|
1026
|
+
if not field_match:
|
|
1027
|
+
errors.append(f"Missing required field: {field}")
|
|
1028
|
+
|
|
1029
|
+
# If no errors, validation passed
|
|
1030
|
+
return len(errors) == 0, errors
|
|
1031
|
+
|
|
1032
|
+
except Exception as e:
|
|
1033
|
+
return False, [f"Validation error: {e!s}"]
|
|
1034
|
+
|
|
1035
|
+
def get_deployment_status(self) -> Dict[str, Any]:
|
|
1036
|
+
"""Get current deployment status and metrics."""
|
|
1037
|
+
return self.metrics_collector.get_deployment_status()
|