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.
Potentially problematic release.
This version of claude-mpm might be problematic. Click here for more details.
- 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
claude_mpm/core/claude_runner.py
CHANGED
|
@@ -1,44 +1,33 @@
|
|
|
1
1
|
"""Claude runner with both exec and subprocess launch methods."""
|
|
2
2
|
|
|
3
|
-
import json
|
|
4
3
|
import os
|
|
5
|
-
import subprocess
|
|
6
|
-
import sys
|
|
7
|
-
import time
|
|
8
|
-
from datetime import datetime
|
|
9
4
|
from pathlib import Path
|
|
10
5
|
from typing import Optional
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
except ImportError:
|
|
20
|
-
from claude_mpm.services.agent_deployment import AgentDeploymentService
|
|
21
|
-
from claude_mpm.services.ticket_manager import TicketManager
|
|
22
|
-
from claude_mpm.services.hook_service import HookService
|
|
23
|
-
from claude_mpm.core.config import Config
|
|
24
|
-
from claude_mpm.core.logger import get_logger, get_project_logger, ProjectLogger
|
|
6
|
+
|
|
7
|
+
# Core imports that don't cause circular dependencies
|
|
8
|
+
from claude_mpm.core.container import get_container
|
|
9
|
+
from claude_mpm.core.interfaces import AgentDeploymentInterface
|
|
10
|
+
from claude_mpm.core.logging_config import get_logger
|
|
11
|
+
from claude_mpm.services.core.interfaces import RunnerConfigurationInterface
|
|
12
|
+
|
|
13
|
+
# Type checking imports to avoid circular dependencies
|
|
25
14
|
|
|
26
15
|
|
|
27
16
|
class ClaudeRunner:
|
|
28
17
|
"""
|
|
29
18
|
Claude runner that replaces the entire orchestrator system.
|
|
30
|
-
|
|
19
|
+
|
|
31
20
|
This does exactly what we need:
|
|
32
21
|
1. Deploy native agents to .claude/agents/
|
|
33
22
|
2. Run Claude CLI with either exec or subprocess
|
|
34
23
|
3. Extract tickets if needed
|
|
35
24
|
4. Handle both interactive and non-interactive modes
|
|
36
|
-
|
|
25
|
+
|
|
37
26
|
Supports two launch methods:
|
|
38
27
|
- exec: Replace current process (default for backward compatibility)
|
|
39
28
|
- subprocess: Launch as child process for more control
|
|
40
29
|
"""
|
|
41
|
-
|
|
30
|
+
|
|
42
31
|
def __init__(
|
|
43
32
|
self,
|
|
44
33
|
enable_tickets: bool = True,
|
|
@@ -46,984 +35,775 @@ class ClaudeRunner:
|
|
|
46
35
|
claude_args: Optional[list] = None,
|
|
47
36
|
launch_method: str = "exec", # "exec" or "subprocess"
|
|
48
37
|
enable_websocket: bool = False,
|
|
49
|
-
websocket_port: int = 8765
|
|
38
|
+
websocket_port: int = 8765,
|
|
39
|
+
use_native_agents: bool = False, # Use --agents flag instead of file deployment
|
|
50
40
|
):
|
|
51
|
-
"""Initialize the Claude runner.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
self.
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
41
|
+
"""Initialize the Claude runner.
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
enable_tickets: Enable ticket extraction (deprecated)
|
|
45
|
+
log_level: Logging level
|
|
46
|
+
claude_args: Additional arguments for Claude CLI
|
|
47
|
+
launch_method: "exec" or "subprocess" launch mode
|
|
48
|
+
enable_websocket: Enable WebSocket server
|
|
49
|
+
websocket_port: WebSocket server port
|
|
50
|
+
use_native_agents: Use --agents CLI flag instead of .claude/agents/ deployment
|
|
51
|
+
"""
|
|
52
|
+
self.logger = get_logger(__name__)
|
|
53
|
+
|
|
54
|
+
# Initialize configuration service
|
|
55
|
+
container = get_container()
|
|
56
|
+
if not container.is_registered(RunnerConfigurationInterface):
|
|
57
|
+
from claude_mpm.services.runner_configuration_service import (
|
|
58
|
+
RunnerConfigurationService,
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
container.register_singleton(
|
|
62
|
+
RunnerConfigurationInterface, RunnerConfigurationService
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
try:
|
|
66
|
+
self.configuration_service = container.get(RunnerConfigurationInterface)
|
|
67
|
+
except Exception as e:
|
|
68
|
+
self.logger.error(
|
|
69
|
+
"Failed to initialize configuration service", exc_info=True
|
|
70
|
+
)
|
|
71
|
+
raise RuntimeError(
|
|
72
|
+
f"Configuration service initialization failed: {e}"
|
|
73
|
+
) from e
|
|
74
|
+
|
|
75
|
+
# Initialize configuration using the service
|
|
76
|
+
config_data = self.configuration_service.initialize_configuration(
|
|
77
|
+
enable_tickets=enable_tickets,
|
|
78
|
+
log_level=log_level,
|
|
79
|
+
claude_args=claude_args,
|
|
80
|
+
launch_method=launch_method,
|
|
81
|
+
enable_websocket=enable_websocket,
|
|
82
|
+
websocket_port=websocket_port,
|
|
83
|
+
use_native_agents=use_native_agents,
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
# Set configuration attributes
|
|
87
|
+
self.enable_tickets = config_data["enable_tickets"]
|
|
88
|
+
self.log_level = config_data["log_level"]
|
|
89
|
+
self.claude_args = config_data["claude_args"]
|
|
90
|
+
self.launch_method = config_data["launch_method"]
|
|
91
|
+
self.enable_websocket = config_data["enable_websocket"]
|
|
92
|
+
self.websocket_port = config_data["websocket_port"]
|
|
93
|
+
self.use_native_agents = config_data.get("use_native_agents", False)
|
|
94
|
+
self.config = config_data["config"]
|
|
95
|
+
|
|
96
|
+
# Initialize project logger using the service
|
|
97
|
+
self.project_logger = self.configuration_service.initialize_project_logger(
|
|
98
|
+
self.log_level
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
# Initialize services using dependency injection and configuration service
|
|
102
|
+
user_working_dir = self.configuration_service.get_user_working_directory()
|
|
103
|
+
|
|
104
|
+
# Register core services
|
|
105
|
+
self.configuration_service.register_core_services(container, user_working_dir)
|
|
106
|
+
|
|
107
|
+
try:
|
|
108
|
+
self.deployment_service = container.get(AgentDeploymentInterface)
|
|
109
|
+
except Exception as e:
|
|
110
|
+
self.logger.error("Failed to resolve AgentDeploymentService", exc_info=True)
|
|
111
|
+
raise RuntimeError(
|
|
112
|
+
f"Agent deployment service initialization failed: {e}"
|
|
113
|
+
) from e
|
|
114
|
+
|
|
115
|
+
# Ticket manager disabled - use claude-mpm tickets CLI commands instead
|
|
116
|
+
self.ticket_manager = None
|
|
117
|
+
self.enable_tickets = False
|
|
118
|
+
|
|
119
|
+
# Initialize response logger using configuration service
|
|
120
|
+
self.response_logger = self.configuration_service.initialize_response_logger(
|
|
121
|
+
self.config, self.project_logger
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
# Initialize hook service using configuration service
|
|
125
|
+
self.hook_service = self.configuration_service.register_hook_service(
|
|
126
|
+
container, self.config
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
# Initialize memory hook service using configuration service
|
|
130
|
+
self.memory_hook_service = (
|
|
131
|
+
self.configuration_service.register_memory_hook_service(
|
|
132
|
+
container, self.hook_service
|
|
133
|
+
)
|
|
134
|
+
)
|
|
135
|
+
if self.memory_hook_service:
|
|
136
|
+
self.memory_hook_service.register_memory_hooks()
|
|
137
|
+
|
|
138
|
+
# Initialize agent capabilities service using configuration service
|
|
139
|
+
self.agent_capabilities_service = (
|
|
140
|
+
self.configuration_service.register_agent_capabilities_service(container)
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
# Initialize system instructions service using configuration service
|
|
144
|
+
self.system_instructions_service = (
|
|
145
|
+
self.configuration_service.register_system_instructions_service(
|
|
146
|
+
container, self.agent_capabilities_service
|
|
147
|
+
)
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
# Initialize Socket.IO server reference first
|
|
151
|
+
self.websocket_server = None
|
|
152
|
+
|
|
153
|
+
# Initialize subprocess launcher service using configuration service
|
|
154
|
+
self.subprocess_launcher_service = (
|
|
155
|
+
self.configuration_service.register_subprocess_launcher_service(
|
|
156
|
+
container, self.project_logger, self.websocket_server
|
|
157
|
+
)
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
# Initialize version service using configuration service
|
|
161
|
+
self.version_service = self.configuration_service.register_version_service(
|
|
162
|
+
container
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
# Initialize command handler service using configuration service
|
|
166
|
+
self.command_handler_service = (
|
|
167
|
+
self.configuration_service.register_command_handler_service(
|
|
168
|
+
container, self.project_logger
|
|
169
|
+
)
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
# Initialize session management service using configuration service
|
|
173
|
+
# Note: This must be done after other services are initialized since it depends on the runner
|
|
174
|
+
self.session_management_service = (
|
|
175
|
+
self.configuration_service.register_session_management_service(
|
|
176
|
+
container, self
|
|
177
|
+
)
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
# Initialize utility service using configuration service
|
|
181
|
+
self.utility_service = self.configuration_service.register_utility_service(
|
|
182
|
+
container
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
# Load system instructions using the service
|
|
186
|
+
if self.system_instructions_service:
|
|
187
|
+
self.system_instructions = (
|
|
188
|
+
self.system_instructions_service.load_system_instructions()
|
|
189
|
+
)
|
|
190
|
+
else:
|
|
191
|
+
self.system_instructions = self._load_system_instructions()
|
|
192
|
+
|
|
193
|
+
# Deploy output style early (before Claude Code launches)
|
|
194
|
+
# This ensures the "Claude MPM" output style is active on startup
|
|
195
|
+
self._deploy_output_style()
|
|
196
|
+
|
|
197
|
+
# Create session log file using configuration service
|
|
198
|
+
self.session_log_file = self.configuration_service.create_session_log_file(
|
|
199
|
+
self.project_logger, self.log_level, config_data
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
# Log session start event if we have a session log file
|
|
203
|
+
if self.session_log_file:
|
|
204
|
+
self._log_session_event(
|
|
205
|
+
{
|
|
98
206
|
"event": "session_start",
|
|
99
207
|
"runner": "ClaudeRunner",
|
|
100
|
-
"enable_tickets": enable_tickets,
|
|
101
|
-
"log_level": log_level,
|
|
102
|
-
"launch_method": launch_method
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
# Initialize Socket.IO server reference
|
|
108
|
-
self.websocket_server = None
|
|
109
|
-
|
|
208
|
+
"enable_tickets": self.enable_tickets,
|
|
209
|
+
"log_level": self.log_level,
|
|
210
|
+
"launch_method": self.launch_method,
|
|
211
|
+
}
|
|
212
|
+
)
|
|
213
|
+
|
|
110
214
|
def setup_agents(self) -> bool:
|
|
111
215
|
"""Deploy native agents to .claude/agents/."""
|
|
112
216
|
try:
|
|
113
217
|
if self.project_logger:
|
|
114
218
|
self.project_logger.log_system(
|
|
115
|
-
"Starting agent deployment",
|
|
116
|
-
level="INFO",
|
|
117
|
-
component="deployment"
|
|
219
|
+
"Starting agent deployment", level="INFO", component="deployment"
|
|
118
220
|
)
|
|
119
|
-
|
|
221
|
+
|
|
120
222
|
results = self.deployment_service.deploy_agents()
|
|
121
|
-
|
|
223
|
+
|
|
122
224
|
if results["deployed"] or results.get("updated", []):
|
|
123
|
-
deployed_count = len(results[
|
|
124
|
-
updated_count = len(results.get(
|
|
125
|
-
|
|
225
|
+
deployed_count = len(results["deployed"])
|
|
226
|
+
updated_count = len(results.get("updated", []))
|
|
227
|
+
|
|
126
228
|
if deployed_count > 0:
|
|
127
229
|
print(f"✓ Deployed {deployed_count} native agents")
|
|
128
230
|
if updated_count > 0:
|
|
129
231
|
print(f"✓ Updated {updated_count} agents")
|
|
130
|
-
|
|
232
|
+
|
|
131
233
|
if self.project_logger:
|
|
132
234
|
self.project_logger.log_system(
|
|
133
235
|
f"Agent deployment successful: {deployed_count} deployed, {updated_count} updated",
|
|
134
236
|
level="INFO",
|
|
135
|
-
component="deployment"
|
|
237
|
+
component="deployment",
|
|
136
238
|
)
|
|
137
|
-
|
|
239
|
+
|
|
138
240
|
# Set Claude environment
|
|
139
241
|
self.deployment_service.set_claude_environment()
|
|
140
242
|
return True
|
|
141
|
-
|
|
142
|
-
self.logger.info("All agents already up to date")
|
|
143
|
-
if self.project_logger:
|
|
144
|
-
self.project_logger.log_system(
|
|
145
|
-
"All agents already up to date",
|
|
146
|
-
level="INFO",
|
|
147
|
-
component="deployment"
|
|
148
|
-
)
|
|
149
|
-
return True
|
|
150
|
-
|
|
151
|
-
except Exception as e:
|
|
152
|
-
self.logger.error(f"Agent deployment failed: {e}")
|
|
153
|
-
print(f"⚠️ Agent deployment failed: {e}")
|
|
243
|
+
self.logger.info("All agents already up to date")
|
|
154
244
|
if self.project_logger:
|
|
155
245
|
self.project_logger.log_system(
|
|
156
|
-
|
|
157
|
-
level="
|
|
158
|
-
component="deployment"
|
|
246
|
+
"All agents already up to date",
|
|
247
|
+
level="INFO",
|
|
248
|
+
component="deployment",
|
|
249
|
+
)
|
|
250
|
+
return True
|
|
251
|
+
|
|
252
|
+
except PermissionError as e:
|
|
253
|
+
error_msg = f"Permission denied deploying agents to .claude/agents/: {e}"
|
|
254
|
+
self.logger.error(error_msg)
|
|
255
|
+
print(f"❌ {error_msg}")
|
|
256
|
+
print(
|
|
257
|
+
"💡 Try running with appropriate permissions or check directory ownership"
|
|
258
|
+
)
|
|
259
|
+
if self.project_logger:
|
|
260
|
+
self.project_logger.log_system(
|
|
261
|
+
error_msg, level="ERROR", component="deployment"
|
|
159
262
|
)
|
|
160
263
|
return False
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
self.websocket_server.start()
|
|
171
|
-
self.logger.info("Connected to Socket.IO monitoring server")
|
|
172
|
-
|
|
173
|
-
# Generate session ID
|
|
174
|
-
session_id = str(uuid.uuid4())
|
|
175
|
-
working_dir = os.getcwd()
|
|
176
|
-
|
|
177
|
-
# Notify session start
|
|
178
|
-
self.websocket_server.session_started(
|
|
179
|
-
session_id=session_id,
|
|
180
|
-
launch_method=self.launch_method,
|
|
181
|
-
working_dir=working_dir
|
|
264
|
+
|
|
265
|
+
except FileNotFoundError as e:
|
|
266
|
+
error_msg = f"Agent files not found: {e}"
|
|
267
|
+
self.logger.error(error_msg)
|
|
268
|
+
print(f"❌ {error_msg}")
|
|
269
|
+
print("💡 Ensure claude-mpm is properly installed")
|
|
270
|
+
if self.project_logger:
|
|
271
|
+
self.project_logger.log_system(
|
|
272
|
+
error_msg, level="ERROR", component="deployment"
|
|
182
273
|
)
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
self.project_logger
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
if self.claude_args:
|
|
219
|
-
cmd.extend(self.claude_args)
|
|
220
|
-
|
|
221
|
-
# Add system instructions if available
|
|
222
|
-
system_prompt = self._create_system_prompt()
|
|
223
|
-
if system_prompt and system_prompt != create_simple_context():
|
|
224
|
-
cmd.extend(["--append-system-prompt", system_prompt])
|
|
225
|
-
|
|
226
|
-
# Run interactive Claude directly
|
|
274
|
+
return False
|
|
275
|
+
|
|
276
|
+
except ImportError as e:
|
|
277
|
+
error_msg = f"Missing required module for agent deployment: {e}"
|
|
278
|
+
self.logger.error(error_msg)
|
|
279
|
+
print(f"⚠️ {error_msg}")
|
|
280
|
+
print("💡 Some agent features may be limited")
|
|
281
|
+
if self.project_logger:
|
|
282
|
+
self.project_logger.log_system(
|
|
283
|
+
error_msg, level="WARNING", component="deployment"
|
|
284
|
+
)
|
|
285
|
+
return False
|
|
286
|
+
|
|
287
|
+
except Exception as e:
|
|
288
|
+
error_msg = f"Unexpected error during agent deployment: {e}"
|
|
289
|
+
self.logger.error(error_msg)
|
|
290
|
+
print(f"⚠️ {error_msg}")
|
|
291
|
+
if self.project_logger:
|
|
292
|
+
self.project_logger.log_system(
|
|
293
|
+
error_msg, level="ERROR", component="deployment"
|
|
294
|
+
)
|
|
295
|
+
# Continue without agents rather than failing completely
|
|
296
|
+
return False
|
|
297
|
+
|
|
298
|
+
def ensure_project_agents(self) -> bool:
|
|
299
|
+
"""Ensure system agents are available in the project directory.
|
|
300
|
+
|
|
301
|
+
Deploys system agents to project's .claude/agents/ directory
|
|
302
|
+
if they don't exist or are outdated. This ensures agents are
|
|
303
|
+
available for Claude Code to use. Project-specific JSON templates
|
|
304
|
+
should be placed in .claude-mpm/agents/.
|
|
305
|
+
|
|
306
|
+
Returns:
|
|
307
|
+
bool: True if agents are available, False on error
|
|
308
|
+
"""
|
|
227
309
|
try:
|
|
228
|
-
# Use
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
# Set the correct working directory for Claude Code
|
|
241
|
-
# If CLAUDE_MPM_USER_PWD is set, use that as the working directory
|
|
242
|
-
if 'CLAUDE_MPM_USER_PWD' in clean_env:
|
|
243
|
-
user_pwd = clean_env['CLAUDE_MPM_USER_PWD']
|
|
244
|
-
clean_env['CLAUDE_WORKSPACE'] = user_pwd
|
|
245
|
-
# Also change to that directory before launching Claude
|
|
246
|
-
try:
|
|
247
|
-
os.chdir(user_pwd)
|
|
248
|
-
self.logger.info(f"Changed working directory to: {user_pwd}")
|
|
249
|
-
except Exception as e:
|
|
250
|
-
self.logger.warning(f"Could not change to user directory {user_pwd}: {e}")
|
|
251
|
-
|
|
252
|
-
print("Launching Claude...")
|
|
253
|
-
|
|
310
|
+
# Use the correct user directory, not the framework directory
|
|
311
|
+
if "CLAUDE_MPM_USER_PWD" in os.environ:
|
|
312
|
+
project_dir = Path(os.environ["CLAUDE_MPM_USER_PWD"])
|
|
313
|
+
else:
|
|
314
|
+
project_dir = Path.cwd()
|
|
315
|
+
|
|
316
|
+
project_agents_dir = project_dir / ".claude-mpm" / "agents"
|
|
317
|
+
|
|
318
|
+
# Create directory if it doesn't exist
|
|
319
|
+
project_agents_dir.mkdir(parents=True, exist_ok=True)
|
|
320
|
+
|
|
254
321
|
if self.project_logger:
|
|
255
322
|
self.project_logger.log_system(
|
|
256
|
-
f"
|
|
323
|
+
f"Ensuring agents are available in project: {project_agents_dir}",
|
|
257
324
|
level="INFO",
|
|
258
|
-
component="
|
|
325
|
+
component="deployment",
|
|
259
326
|
)
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
327
|
+
|
|
328
|
+
# Deploy agents to project's .claude/agents directory (not .claude-mpm)
|
|
329
|
+
# This ensures all system agents are deployed regardless of version
|
|
330
|
+
# .claude-mpm/agents/ should only contain JSON source templates
|
|
331
|
+
# .claude/agents/ should contain the built MD files for Claude Code
|
|
332
|
+
results = self.deployment_service.deploy_agents(
|
|
333
|
+
target_dir=project_dir / ".claude",
|
|
334
|
+
force_rebuild=False,
|
|
335
|
+
deployment_mode="project",
|
|
336
|
+
)
|
|
337
|
+
|
|
338
|
+
if results["deployed"] or results.get("updated", []):
|
|
339
|
+
deployed_count = len(results["deployed"])
|
|
340
|
+
updated_count = len(results.get("updated", []))
|
|
341
|
+
|
|
342
|
+
if deployed_count > 0:
|
|
343
|
+
self.logger.info(f"Deployed {deployed_count} agents to project")
|
|
344
|
+
if updated_count > 0:
|
|
345
|
+
self.logger.info(f"Updated {updated_count} agents in project")
|
|
346
|
+
|
|
347
|
+
return True
|
|
348
|
+
if results.get("skipped", []):
|
|
349
|
+
# Agents already exist and are current
|
|
350
|
+
self.logger.debug(
|
|
351
|
+
f"Project agents up to date: {len(results['skipped'])} agents"
|
|
271
352
|
)
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
else:
|
|
277
|
-
# Default to exec for backward compatibility
|
|
278
|
-
if self.websocket_server:
|
|
279
|
-
# Notify before exec (we won't be able to after)
|
|
280
|
-
self.websocket_server.claude_status_changed(
|
|
281
|
-
status="running",
|
|
282
|
-
message="Claude process started (exec mode)"
|
|
283
|
-
)
|
|
284
|
-
os.execvpe(cmd[0], cmd, clean_env)
|
|
285
|
-
|
|
353
|
+
return True
|
|
354
|
+
self.logger.warning("No agents deployed to project")
|
|
355
|
+
return False
|
|
356
|
+
|
|
286
357
|
except Exception as e:
|
|
287
|
-
|
|
358
|
+
self.logger.error(f"Failed to ensure project agents: {e}")
|
|
288
359
|
if self.project_logger:
|
|
289
360
|
self.project_logger.log_system(
|
|
290
|
-
f"Failed to
|
|
361
|
+
f"Failed to ensure project agents: {e}",
|
|
291
362
|
level="ERROR",
|
|
292
|
-
component="
|
|
293
|
-
)
|
|
294
|
-
self._log_session_event({
|
|
295
|
-
"event": "interactive_launch_failed",
|
|
296
|
-
"error": str(e),
|
|
297
|
-
"exception_type": type(e).__name__
|
|
298
|
-
})
|
|
299
|
-
|
|
300
|
-
# Notify WebSocket clients of error
|
|
301
|
-
if self.websocket_server:
|
|
302
|
-
self.websocket_server.claude_status_changed(
|
|
303
|
-
status="error",
|
|
304
|
-
message=f"Failed to launch Claude: {e}"
|
|
363
|
+
component="deployment",
|
|
305
364
|
)
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
self.project_logger.log_system(
|
|
324
|
-
f"Fallback launch failed: {fallback_error}",
|
|
325
|
-
level="ERROR",
|
|
326
|
-
component="session"
|
|
327
|
-
)
|
|
328
|
-
self._log_session_event({
|
|
329
|
-
"event": "interactive_fallback_failed",
|
|
330
|
-
"error": str(fallback_error),
|
|
331
|
-
"exception_type": type(fallback_error).__name__
|
|
332
|
-
})
|
|
333
|
-
|
|
334
|
-
def run_oneshot(self, prompt: str, context: Optional[str] = None) -> bool:
|
|
335
|
-
"""Run Claude with a single prompt and return success status."""
|
|
336
|
-
start_time = time.time()
|
|
337
|
-
|
|
338
|
-
# Connect to Socket.IO server if enabled
|
|
339
|
-
if self.enable_websocket:
|
|
340
|
-
try:
|
|
341
|
-
# Use Socket.IO client proxy to connect to monitoring server
|
|
342
|
-
from claude_mpm.services.socketio_server import SocketIOClientProxy
|
|
343
|
-
self.websocket_server = SocketIOClientProxy(port=self.websocket_port)
|
|
344
|
-
self.websocket_server.start()
|
|
345
|
-
self.logger.info("Connected to Socket.IO monitoring server")
|
|
346
|
-
|
|
347
|
-
# Generate session ID
|
|
348
|
-
session_id = str(uuid.uuid4())
|
|
349
|
-
working_dir = os.getcwd()
|
|
350
|
-
|
|
351
|
-
# Notify session start
|
|
352
|
-
self.websocket_server.session_started(
|
|
353
|
-
session_id=session_id,
|
|
354
|
-
launch_method="oneshot",
|
|
355
|
-
working_dir=working_dir
|
|
356
|
-
)
|
|
357
|
-
except Exception as e:
|
|
358
|
-
self.logger.warning(f"Failed to connect to Socket.IO server: {e}")
|
|
359
|
-
self.websocket_server = None
|
|
360
|
-
|
|
361
|
-
# Check for /mpm: commands
|
|
362
|
-
if prompt.strip().startswith("/mpm:"):
|
|
363
|
-
return self._handle_mpm_command(prompt.strip())
|
|
364
|
-
|
|
365
|
-
if self.project_logger:
|
|
366
|
-
self.project_logger.log_system(
|
|
367
|
-
f"Starting non-interactive session with prompt: {prompt[:100]}",
|
|
368
|
-
level="INFO",
|
|
369
|
-
component="session"
|
|
370
|
-
)
|
|
371
|
-
|
|
372
|
-
# Setup agents
|
|
373
|
-
if not self.setup_agents():
|
|
374
|
-
print("Continuing without native agents...")
|
|
375
|
-
|
|
376
|
-
# Combine context and prompt
|
|
377
|
-
full_prompt = prompt
|
|
378
|
-
if context:
|
|
379
|
-
full_prompt = f"{context}\n\n{prompt}"
|
|
380
|
-
|
|
381
|
-
# Build command with system instructions
|
|
382
|
-
cmd = [
|
|
383
|
-
"claude",
|
|
384
|
-
"--model", "opus",
|
|
385
|
-
"--dangerously-skip-permissions"
|
|
386
|
-
]
|
|
387
|
-
|
|
388
|
-
# Add any custom Claude arguments
|
|
389
|
-
if self.claude_args:
|
|
390
|
-
cmd.extend(self.claude_args)
|
|
391
|
-
|
|
392
|
-
# Add print and prompt
|
|
393
|
-
cmd.extend(["--print", full_prompt])
|
|
394
|
-
|
|
395
|
-
# Add system instructions if available
|
|
396
|
-
system_prompt = self._create_system_prompt()
|
|
397
|
-
if system_prompt and system_prompt != create_simple_context():
|
|
398
|
-
# Insert system prompt before the user prompt
|
|
399
|
-
cmd.insert(-2, "--append-system-prompt")
|
|
400
|
-
cmd.insert(-2, system_prompt)
|
|
401
|
-
|
|
365
|
+
return False
|
|
366
|
+
|
|
367
|
+
def deploy_project_agents_to_claude(self) -> bool:
|
|
368
|
+
"""Deploy project agents from .claude-mpm/agents/ to .claude/agents/.
|
|
369
|
+
|
|
370
|
+
This method handles the deployment of project-specific agents (JSON format)
|
|
371
|
+
from the project's agents directory to Claude's agent directory.
|
|
372
|
+
Project agents take precedence over system agents.
|
|
373
|
+
|
|
374
|
+
WHY: Project agents allow teams to define custom, project-specific agents
|
|
375
|
+
that override system agents. These are stored in JSON format in
|
|
376
|
+
.claude-mpm/agents/ and need to be deployed to .claude/agents/
|
|
377
|
+
as MD files for Claude to use them.
|
|
378
|
+
|
|
379
|
+
Returns:
|
|
380
|
+
bool: True if deployment successful or no agents to deploy, False on error
|
|
381
|
+
"""
|
|
402
382
|
try:
|
|
403
|
-
#
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
# Set the correct working directory for Claude Code
|
|
407
|
-
if 'CLAUDE_MPM_USER_PWD' in env:
|
|
408
|
-
user_pwd = env['CLAUDE_MPM_USER_PWD']
|
|
409
|
-
env['CLAUDE_WORKSPACE'] = user_pwd
|
|
410
|
-
# Change to that directory before running Claude
|
|
411
|
-
try:
|
|
412
|
-
original_cwd = os.getcwd()
|
|
413
|
-
os.chdir(user_pwd)
|
|
414
|
-
self.logger.info(f"Changed working directory to: {user_pwd}")
|
|
415
|
-
except Exception as e:
|
|
416
|
-
self.logger.warning(f"Could not change to user directory {user_pwd}: {e}")
|
|
417
|
-
original_cwd = None
|
|
383
|
+
# Use the correct user directory, not the framework directory
|
|
384
|
+
if "CLAUDE_MPM_USER_PWD" in os.environ:
|
|
385
|
+
project_dir = Path(os.environ["CLAUDE_MPM_USER_PWD"])
|
|
418
386
|
else:
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
387
|
+
project_dir = Path.cwd()
|
|
388
|
+
|
|
389
|
+
project_agents_dir = project_dir / ".claude-mpm" / "agents"
|
|
390
|
+
claude_agents_dir = project_dir / ".claude" / "agents"
|
|
391
|
+
|
|
392
|
+
# Check if project agents directory exists
|
|
393
|
+
if not project_agents_dir.exists():
|
|
394
|
+
self.logger.debug("No project agents directory found")
|
|
395
|
+
return True # Not an error - just no project agents
|
|
396
|
+
|
|
397
|
+
# Get JSON agent files from agents directory
|
|
398
|
+
json_files = list(project_agents_dir.glob("*.json"))
|
|
399
|
+
if not json_files:
|
|
400
|
+
self.logger.debug("No JSON agents in project")
|
|
401
|
+
return True
|
|
402
|
+
|
|
403
|
+
# Create .claude/agents directory if needed
|
|
404
|
+
claude_agents_dir.mkdir(parents=True, exist_ok=True)
|
|
405
|
+
|
|
406
|
+
self.logger.info(
|
|
407
|
+
f"Deploying {len(json_files)} project agents to .claude/agents/"
|
|
408
|
+
)
|
|
422
409
|
if self.project_logger:
|
|
423
410
|
self.project_logger.log_system(
|
|
424
|
-
"
|
|
411
|
+
f"Deploying project agents from {project_agents_dir} to {claude_agents_dir}",
|
|
425
412
|
level="INFO",
|
|
426
|
-
component="
|
|
427
|
-
)
|
|
428
|
-
|
|
429
|
-
# Notify WebSocket clients
|
|
430
|
-
if self.websocket_server:
|
|
431
|
-
self.websocket_server.claude_status_changed(
|
|
432
|
-
status="running",
|
|
433
|
-
message="Executing Claude oneshot command"
|
|
413
|
+
component="deployment",
|
|
434
414
|
)
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
415
|
+
|
|
416
|
+
deployed_count = 0
|
|
417
|
+
updated_count = 0
|
|
418
|
+
errors = []
|
|
419
|
+
|
|
420
|
+
# Deploy each JSON agent
|
|
421
|
+
# CRITICAL: PM (Project Manager) must NEVER be deployed as it's the main Claude instance
|
|
422
|
+
EXCLUDED_AGENTS = {"pm", "project_manager"}
|
|
423
|
+
|
|
424
|
+
# Initialize deployment service with proper base agent path
|
|
425
|
+
# Use the existing deployment service's base agent path if available
|
|
426
|
+
base_agent_path = project_agents_dir / "base_agent.json"
|
|
427
|
+
if not base_agent_path.exists():
|
|
428
|
+
# Fall back to system base agent
|
|
429
|
+
base_agent_path = self.deployment_service.base_agent_path
|
|
430
|
+
|
|
431
|
+
# Lazy import to avoid circular dependencies
|
|
432
|
+
from claude_mpm.services.agents.deployment import AgentDeploymentService
|
|
433
|
+
|
|
434
|
+
# Create a single deployment service instance for all agents
|
|
435
|
+
project_deployment = AgentDeploymentService(
|
|
436
|
+
templates_dir=project_agents_dir,
|
|
437
|
+
base_agent_path=base_agent_path,
|
|
438
|
+
working_directory=project_dir, # Pass the project directory
|
|
439
|
+
)
|
|
440
|
+
|
|
441
|
+
# Load base agent data once
|
|
442
|
+
base_agent_data = {}
|
|
443
|
+
if base_agent_path and base_agent_path.exists():
|
|
440
444
|
try:
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
# Log successful completion
|
|
456
|
-
self.project_logger.log_system(
|
|
457
|
-
f"Non-interactive session completed successfully in {execution_time:.2f}s",
|
|
458
|
-
level="INFO",
|
|
459
|
-
component="session"
|
|
460
|
-
)
|
|
461
|
-
|
|
462
|
-
# Log session event
|
|
463
|
-
self._log_session_event({
|
|
464
|
-
"event": "session_complete",
|
|
465
|
-
"success": True,
|
|
466
|
-
"execution_time": execution_time,
|
|
467
|
-
"response_length": len(response)
|
|
468
|
-
})
|
|
469
|
-
|
|
470
|
-
# Log agent invocation if we detect delegation patterns
|
|
471
|
-
if self._contains_delegation(response):
|
|
472
|
-
self.project_logger.log_system(
|
|
473
|
-
"Detected potential agent delegation in response",
|
|
474
|
-
level="INFO",
|
|
475
|
-
component="delegation"
|
|
445
|
+
import json
|
|
446
|
+
|
|
447
|
+
base_agent_data = json.loads(base_agent_path.read_text())
|
|
448
|
+
except Exception as e:
|
|
449
|
+
self.logger.warning(f"Could not load base agent: {e}")
|
|
450
|
+
|
|
451
|
+
for json_file in json_files:
|
|
452
|
+
try:
|
|
453
|
+
agent_name = json_file.stem
|
|
454
|
+
|
|
455
|
+
# Skip PM agent - it's the main Claude instance, not a subagent
|
|
456
|
+
if agent_name.lower() in EXCLUDED_AGENTS:
|
|
457
|
+
self.logger.info(
|
|
458
|
+
f"Skipping {agent_name} (PM is the main Claude instance)"
|
|
476
459
|
)
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
#
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
460
|
+
continue
|
|
461
|
+
|
|
462
|
+
target_file = claude_agents_dir / f"{agent_name}.md"
|
|
463
|
+
|
|
464
|
+
# Check if agent needs update
|
|
465
|
+
needs_update = True
|
|
466
|
+
if target_file.exists():
|
|
467
|
+
# Check if it's a project agent (has project marker)
|
|
468
|
+
existing_content = target_file.read_text()
|
|
469
|
+
if (
|
|
470
|
+
"author: claude-mpm-project" in existing_content
|
|
471
|
+
or "source: project" in existing_content
|
|
472
|
+
) and target_file.stat().st_mtime >= json_file.stat().st_mtime:
|
|
473
|
+
needs_update = False
|
|
474
|
+
self.logger.debug(
|
|
475
|
+
f"Project agent {agent_name} is up to date"
|
|
476
|
+
)
|
|
477
|
+
|
|
478
|
+
if needs_update:
|
|
479
|
+
# Build the agent markdown using the pre-initialized service and base agent data
|
|
480
|
+
# Use template_builder service instead of removed _build_agent_markdown method
|
|
481
|
+
agent_content = (
|
|
482
|
+
project_deployment.template_builder.build_agent_markdown(
|
|
483
|
+
agent_name,
|
|
484
|
+
json_file,
|
|
485
|
+
base_agent_data,
|
|
486
|
+
source_info="project",
|
|
487
|
+
)
|
|
488
|
+
)
|
|
489
|
+
|
|
490
|
+
# Mark as project agent
|
|
491
|
+
agent_content = agent_content.replace(
|
|
492
|
+
"author: claude-mpm", "author: claude-mpm-project"
|
|
493
|
+
)
|
|
494
|
+
|
|
495
|
+
# Write the agent file
|
|
496
|
+
is_update = target_file.exists()
|
|
497
|
+
target_file.write_text(agent_content)
|
|
498
|
+
|
|
499
|
+
if is_update:
|
|
500
|
+
updated_count += 1
|
|
501
|
+
self.logger.info(f"Updated project agent: {agent_name}")
|
|
502
|
+
else:
|
|
503
|
+
deployed_count += 1
|
|
504
|
+
self.logger.info(f"Deployed project agent: {agent_name}")
|
|
505
|
+
|
|
506
|
+
except Exception as e:
|
|
507
|
+
error_msg = f"Failed to deploy project agent {json_file.name}: {e}"
|
|
508
|
+
self.logger.error(error_msg)
|
|
509
|
+
errors.append(error_msg)
|
|
510
|
+
|
|
511
|
+
# Report results
|
|
512
|
+
if deployed_count > 0 or updated_count > 0:
|
|
513
|
+
print(
|
|
514
|
+
f"✓ Deployed {deployed_count} project agents, updated {updated_count}"
|
|
515
|
+
)
|
|
512
516
|
if self.project_logger:
|
|
513
517
|
self.project_logger.log_system(
|
|
514
|
-
f"
|
|
515
|
-
level="
|
|
516
|
-
component="
|
|
518
|
+
f"Project agent deployment: {deployed_count} deployed, {updated_count} updated",
|
|
519
|
+
level="INFO",
|
|
520
|
+
component="deployment",
|
|
517
521
|
)
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
"return_code": result.returncode
|
|
523
|
-
})
|
|
524
|
-
|
|
522
|
+
|
|
523
|
+
if errors:
|
|
524
|
+
for error in errors:
|
|
525
|
+
print(f"⚠️ {error}")
|
|
525
526
|
return False
|
|
526
|
-
|
|
527
|
+
|
|
528
|
+
return True
|
|
529
|
+
|
|
527
530
|
except Exception as e:
|
|
528
|
-
|
|
529
|
-
|
|
531
|
+
error_msg = f"Failed to deploy project agents: {e}"
|
|
532
|
+
self.logger.error(error_msg)
|
|
533
|
+
print(f"⚠️ {error_msg}")
|
|
530
534
|
if self.project_logger:
|
|
531
535
|
self.project_logger.log_system(
|
|
532
|
-
|
|
533
|
-
level="ERROR",
|
|
534
|
-
component="session"
|
|
536
|
+
error_msg, level="ERROR", component="deployment"
|
|
535
537
|
)
|
|
536
|
-
self._log_session_event({
|
|
537
|
-
"event": "session_exception",
|
|
538
|
-
"success": False,
|
|
539
|
-
"exception": str(e),
|
|
540
|
-
"exception_type": type(e).__name__
|
|
541
|
-
})
|
|
542
|
-
|
|
543
538
|
return False
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
539
|
+
|
|
540
|
+
def run_interactive(self, initial_context: Optional[str] = None):
|
|
541
|
+
"""Run Claude in interactive mode using the session management service.
|
|
542
|
+
|
|
543
|
+
Delegates to the SessionManagementService for session orchestration.
|
|
544
|
+
|
|
545
|
+
Args:
|
|
546
|
+
initial_context: Optional initial context to pass to Claude
|
|
547
|
+
"""
|
|
548
|
+
if self.session_management_service:
|
|
549
|
+
self.session_management_service.run_interactive_session(initial_context)
|
|
550
|
+
else:
|
|
551
|
+
self.logger.error("Session management service not available")
|
|
552
|
+
print("Error: Session management service not available")
|
|
553
|
+
|
|
554
|
+
def run_oneshot(self, prompt: str, context: Optional[str] = None) -> bool:
|
|
555
|
+
"""Run Claude with a single prompt using the session management service.
|
|
556
|
+
|
|
557
|
+
Delegates to the SessionManagementService for session orchestration.
|
|
558
|
+
|
|
559
|
+
Args:
|
|
560
|
+
prompt: The command or prompt to execute
|
|
561
|
+
context: Optional context to prepend to the prompt
|
|
562
|
+
|
|
563
|
+
Returns:
|
|
564
|
+
bool: True if successful, False otherwise
|
|
565
|
+
"""
|
|
566
|
+
if self.session_management_service:
|
|
567
|
+
return self.session_management_service.run_oneshot_session(prompt, context)
|
|
568
|
+
self.logger.error("Session management service not available")
|
|
569
|
+
print("Error: Session management service not available")
|
|
570
|
+
return False
|
|
571
|
+
|
|
566
572
|
def _extract_tickets(self, text: str):
|
|
567
|
-
"""Extract tickets from Claude's response."""
|
|
568
|
-
|
|
569
|
-
return
|
|
570
|
-
|
|
571
|
-
try:
|
|
572
|
-
# Use the ticket manager's extraction logic if available
|
|
573
|
-
if hasattr(self.ticket_manager, 'extract_tickets_from_text'):
|
|
574
|
-
tickets = self.ticket_manager.extract_tickets_from_text(text)
|
|
575
|
-
if tickets:
|
|
576
|
-
print(f"\n📋 Extracted {len(tickets)} tickets")
|
|
577
|
-
for ticket in tickets[:3]: # Show first 3
|
|
578
|
-
print(f" - [{ticket.get('id', 'N/A')}] {ticket.get('title', 'No title')}")
|
|
579
|
-
if len(tickets) > 3:
|
|
580
|
-
print(f" ... and {len(tickets) - 3} more")
|
|
581
|
-
else:
|
|
582
|
-
self.logger.debug("Ticket extraction method not available")
|
|
583
|
-
except Exception as e:
|
|
584
|
-
self.logger.debug(f"Ticket extraction failed: {e}")
|
|
573
|
+
"""Extract tickets from Claude's response (disabled - use claude-mpm tickets CLI)."""
|
|
574
|
+
# Ticket extraction disabled - users should use claude-mpm tickets CLI commands
|
|
585
575
|
|
|
586
576
|
def _load_system_instructions(self) -> Optional[str]:
|
|
587
|
-
"""Load and process system instructions
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
dynamic agent capabilities in the PM's system instructions.
|
|
577
|
+
"""Load and process system instructions.
|
|
578
|
+
|
|
579
|
+
Delegates to the SystemInstructionsService for loading and processing.
|
|
591
580
|
"""
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
581
|
+
if self.system_instructions_service:
|
|
582
|
+
return self.system_instructions_service.load_system_instructions()
|
|
583
|
+
# Fallback if service is not available
|
|
584
|
+
self.logger.warning(
|
|
585
|
+
"System instructions service not available, using basic fallback"
|
|
586
|
+
)
|
|
587
|
+
return None
|
|
588
|
+
|
|
589
|
+
def _process_base_pm_content(self, base_pm_content: str) -> str:
|
|
590
|
+
"""Process BASE_PM.md content with dynamic injections.
|
|
591
|
+
|
|
592
|
+
Delegates to the SystemInstructionsService for processing.
|
|
593
|
+
"""
|
|
594
|
+
if self.system_instructions_service:
|
|
595
|
+
return self.system_instructions_service.process_base_pm_content(
|
|
596
|
+
base_pm_content
|
|
597
|
+
)
|
|
598
|
+
# Fallback if service is not available
|
|
599
|
+
self.logger.warning(
|
|
600
|
+
"System instructions service not available for BASE_PM processing"
|
|
601
|
+
)
|
|
602
|
+
return base_pm_content
|
|
603
|
+
|
|
604
|
+
def _strip_metadata_comments(self, content: str) -> str:
|
|
605
|
+
"""Strip HTML metadata comments from content.
|
|
606
|
+
|
|
607
|
+
Delegates to the SystemInstructionsService for processing.
|
|
608
|
+
"""
|
|
609
|
+
if self.system_instructions_service:
|
|
610
|
+
return self.system_instructions_service.strip_metadata_comments(content)
|
|
611
|
+
# Fallback if service is not available
|
|
612
|
+
self.logger.warning(
|
|
613
|
+
"System instructions service not available for metadata stripping"
|
|
614
|
+
)
|
|
615
|
+
return content
|
|
616
|
+
|
|
617
|
+
def _generate_deployed_agent_capabilities(self) -> str:
|
|
618
|
+
"""Generate agent capabilities from deployed agents.
|
|
619
|
+
|
|
620
|
+
Delegates to the AgentCapabilitiesService for agent discovery and formatting.
|
|
621
|
+
"""
|
|
622
|
+
if self.agent_capabilities_service:
|
|
623
|
+
return (
|
|
624
|
+
self.agent_capabilities_service.generate_deployed_agent_capabilities()
|
|
625
|
+
)
|
|
626
|
+
# Fallback if service is not available
|
|
627
|
+
self.logger.warning("Agent capabilities service not available, using fallback")
|
|
628
|
+
return self._get_fallback_capabilities()
|
|
629
|
+
|
|
630
|
+
def _get_fallback_capabilities(self) -> str:
|
|
631
|
+
"""Return fallback agent capabilities when deployed agents can't be read."""
|
|
632
|
+
# Delegate to the service if available, otherwise use basic fallback
|
|
633
|
+
if self.agent_capabilities_service:
|
|
634
|
+
return self.agent_capabilities_service._get_fallback_capabilities()
|
|
635
|
+
return """
|
|
636
|
+
## Available Agent Capabilities
|
|
637
|
+
|
|
638
|
+
You have the following specialized agents available for delegation:
|
|
639
|
+
|
|
640
|
+
- **Engineer Agent**: Code implementation and development
|
|
641
|
+
- **Research Agent**: Investigation and analysis
|
|
642
|
+
- **QA Agent**: Testing and quality assurance
|
|
643
|
+
- **Documentation Agent**: Documentation creation and maintenance
|
|
644
|
+
|
|
645
|
+
Use these agents to delegate specialized work via the Task tool.
|
|
646
|
+
"""
|
|
621
647
|
|
|
622
648
|
def _create_system_prompt(self) -> str:
|
|
623
|
-
"""Create the complete system prompt including instructions.
|
|
649
|
+
"""Create the complete system prompt including instructions.
|
|
650
|
+
|
|
651
|
+
Delegates to the SystemInstructionsService for prompt creation.
|
|
652
|
+
"""
|
|
653
|
+
if self.system_instructions_service:
|
|
654
|
+
return self.system_instructions_service.create_system_prompt(
|
|
655
|
+
self.system_instructions
|
|
656
|
+
)
|
|
657
|
+
# Fallback if service is not available
|
|
624
658
|
if self.system_instructions:
|
|
625
659
|
return self.system_instructions
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
return create_simple_context()
|
|
629
|
-
|
|
660
|
+
return create_simple_context()
|
|
661
|
+
|
|
630
662
|
def _contains_delegation(self, text: str) -> bool:
|
|
631
|
-
"""Check if text contains signs of agent delegation."""
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
"asking the",
|
|
638
|
-
"engineer agent",
|
|
639
|
-
"qa agent",
|
|
640
|
-
"documentation agent",
|
|
641
|
-
"research agent",
|
|
642
|
-
"security agent",
|
|
643
|
-
"ops agent",
|
|
644
|
-
"version_control agent",
|
|
645
|
-
"data_engineer agent"
|
|
646
|
-
]
|
|
647
|
-
|
|
648
|
-
text_lower = text.lower()
|
|
649
|
-
return any(pattern.lower() in text_lower for pattern in delegation_patterns)
|
|
650
|
-
|
|
663
|
+
"""Check if text contains signs of agent delegation using the utility service."""
|
|
664
|
+
if self.utility_service:
|
|
665
|
+
return self.utility_service.contains_delegation(text)
|
|
666
|
+
# Fallback if service not available
|
|
667
|
+
return False
|
|
668
|
+
|
|
651
669
|
def _extract_agent_from_response(self, text: str) -> Optional[str]:
|
|
652
|
-
"""Try to extract agent name from delegation response."""
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
# Pattern 1: subagent_type="agent_name"
|
|
657
|
-
match = re.search(r'subagent_type=["\']([^"\']*)["\'\)]', text)
|
|
658
|
-
if match:
|
|
659
|
-
return match.group(1)
|
|
660
|
-
|
|
661
|
-
# Pattern 2: "engineer agent" etc
|
|
662
|
-
agent_names = [
|
|
663
|
-
"engineer", "qa", "documentation", "research",
|
|
664
|
-
"security", "ops", "version_control", "data_engineer"
|
|
665
|
-
]
|
|
666
|
-
text_lower = text.lower()
|
|
667
|
-
for agent in agent_names:
|
|
668
|
-
if f"{agent} agent" in text_lower or f"agent: {agent}" in text_lower:
|
|
669
|
-
return agent
|
|
670
|
-
|
|
670
|
+
"""Try to extract agent name from delegation response using the utility service."""
|
|
671
|
+
if self.utility_service:
|
|
672
|
+
return self.utility_service.extract_agent_from_response(text)
|
|
673
|
+
# Fallback if service not available
|
|
671
674
|
return None
|
|
672
|
-
|
|
675
|
+
|
|
673
676
|
def _handle_mpm_command(self, prompt: str) -> bool:
|
|
674
|
-
"""Handle /mpm: commands
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
command = parts[0]
|
|
685
|
-
args = parts[1:]
|
|
686
|
-
|
|
687
|
-
# Handle commands
|
|
688
|
-
if command == "test":
|
|
689
|
-
print("Hello World")
|
|
690
|
-
if self.project_logger:
|
|
691
|
-
self.project_logger.log_system(
|
|
692
|
-
"Executed /mpm:test command",
|
|
693
|
-
level="INFO",
|
|
694
|
-
component="command"
|
|
695
|
-
)
|
|
696
|
-
return True
|
|
697
|
-
elif command == "agents":
|
|
698
|
-
# Handle agents command - display deployed agent versions
|
|
699
|
-
# WHY: This provides users with a quick way to check deployed agent versions
|
|
700
|
-
# directly from within Claude Code, maintaining consistency with CLI behavior
|
|
701
|
-
try:
|
|
702
|
-
from claude_mpm.cli import _get_agent_versions_display
|
|
703
|
-
agent_versions = _get_agent_versions_display()
|
|
704
|
-
if agent_versions:
|
|
705
|
-
print(agent_versions)
|
|
706
|
-
else:
|
|
707
|
-
print("No deployed agents found")
|
|
708
|
-
print("\nTo deploy agents, run: claude-mpm --mpm:agents deploy")
|
|
709
|
-
|
|
710
|
-
if self.project_logger:
|
|
711
|
-
self.project_logger.log_system(
|
|
712
|
-
"Executed /mpm:agents command",
|
|
713
|
-
level="INFO",
|
|
714
|
-
component="command"
|
|
715
|
-
)
|
|
716
|
-
return True
|
|
717
|
-
except Exception as e:
|
|
718
|
-
print(f"Error getting agent versions: {e}")
|
|
719
|
-
return False
|
|
720
|
-
else:
|
|
721
|
-
print(f"Unknown command: {command}")
|
|
722
|
-
print("Available commands: test, agents")
|
|
723
|
-
return True
|
|
724
|
-
|
|
725
|
-
except Exception as e:
|
|
726
|
-
print(f"Error executing command: {e}")
|
|
727
|
-
if self.project_logger:
|
|
728
|
-
self.project_logger.log_system(
|
|
729
|
-
f"Failed to execute /mpm: command: {e}",
|
|
730
|
-
level="ERROR",
|
|
731
|
-
component="command"
|
|
732
|
-
)
|
|
733
|
-
return False
|
|
734
|
-
|
|
677
|
+
"""Handle /mpm: commands using the command handler service.
|
|
678
|
+
|
|
679
|
+
Delegates to the CommandHandlerService for command processing.
|
|
680
|
+
"""
|
|
681
|
+
if self.command_handler_service:
|
|
682
|
+
return self.command_handler_service.handle_mpm_command(prompt)
|
|
683
|
+
# Fallback if service not available
|
|
684
|
+
print("Command handler service not available")
|
|
685
|
+
return False
|
|
686
|
+
|
|
735
687
|
def _log_session_event(self, event_data: dict):
|
|
736
|
-
"""Log an event to the session log file."""
|
|
737
|
-
if self.
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
with open(self.session_log_file, 'a') as f:
|
|
745
|
-
f.write(json.dumps(log_entry) + '\n')
|
|
746
|
-
except Exception as e:
|
|
747
|
-
self.logger.debug(f"Failed to log session event: {e}")
|
|
748
|
-
|
|
688
|
+
"""Log an event to the session log file using the utility service."""
|
|
689
|
+
if self.utility_service:
|
|
690
|
+
self.utility_service.log_session_event(self.session_log_file, event_data)
|
|
691
|
+
else:
|
|
692
|
+
# Fallback if service not available
|
|
693
|
+
self.logger.debug("Utility service not available for session logging")
|
|
694
|
+
|
|
749
695
|
def _get_version(self) -> str:
|
|
696
|
+
"""Get version string using the version service.
|
|
697
|
+
|
|
698
|
+
Delegates to the VersionService for version detection and formatting.
|
|
750
699
|
"""
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
Returns version string formatted as "vX.Y.Z"
|
|
764
|
-
"""
|
|
765
|
-
version = "0.0.0"
|
|
766
|
-
method_used = "default"
|
|
767
|
-
|
|
768
|
-
# Method 1: Try package import (fastest, most common)
|
|
769
|
-
try:
|
|
770
|
-
from claude_mpm import __version__
|
|
771
|
-
version = __version__
|
|
772
|
-
method_used = "package_import"
|
|
773
|
-
self.logger.debug(f"Version obtained via package import: {version}")
|
|
774
|
-
except ImportError as e:
|
|
775
|
-
self.logger.debug(f"Package import failed: {e}")
|
|
776
|
-
except Exception as e:
|
|
777
|
-
self.logger.warning(f"Unexpected error in package import: {e}")
|
|
778
|
-
|
|
779
|
-
# Method 2: Try importlib.metadata (standard for installed packages)
|
|
780
|
-
if version == "0.0.0":
|
|
781
|
-
try:
|
|
782
|
-
import importlib.metadata
|
|
783
|
-
version = importlib.metadata.version('claude-mpm')
|
|
784
|
-
method_used = "importlib_metadata"
|
|
785
|
-
self.logger.debug(f"Version obtained via importlib.metadata: {version}")
|
|
786
|
-
except importlib.metadata.PackageNotFoundError:
|
|
787
|
-
self.logger.debug("Package not found in importlib.metadata (likely development install)")
|
|
788
|
-
except ImportError:
|
|
789
|
-
self.logger.debug("importlib.metadata not available (Python < 3.8)")
|
|
790
|
-
except Exception as e:
|
|
791
|
-
self.logger.warning(f"Unexpected error in importlib.metadata: {e}")
|
|
792
|
-
|
|
793
|
-
# Method 3: Try reading VERSION file directly (development fallback)
|
|
794
|
-
if version == "0.0.0":
|
|
795
|
-
try:
|
|
796
|
-
# Calculate path relative to this file
|
|
797
|
-
version_file = Path(__file__).parent.parent.parent.parent / "VERSION"
|
|
798
|
-
if version_file.exists():
|
|
799
|
-
version = version_file.read_text().strip()
|
|
800
|
-
method_used = "version_file"
|
|
801
|
-
self.logger.debug(f"Version obtained via VERSION file: {version}")
|
|
802
|
-
else:
|
|
803
|
-
self.logger.debug(f"VERSION file not found at: {version_file}")
|
|
804
|
-
except Exception as e:
|
|
805
|
-
self.logger.warning(f"Failed to read VERSION file: {e}")
|
|
806
|
-
|
|
807
|
-
# Log final result
|
|
808
|
-
if version == "0.0.0":
|
|
809
|
-
self.logger.error(
|
|
810
|
-
"All version detection methods failed. This indicates a packaging or installation issue."
|
|
811
|
-
)
|
|
812
|
-
else:
|
|
813
|
-
self.logger.debug(f"Final version: {version} (method: {method_used})")
|
|
814
|
-
|
|
815
|
-
return f"v{version}"
|
|
816
|
-
|
|
817
|
-
def _register_memory_hooks(self):
|
|
818
|
-
"""Register memory integration hooks with the hook service.
|
|
819
|
-
|
|
820
|
-
WHY: This activates the memory system by registering hooks that automatically
|
|
821
|
-
inject agent memory before delegation and extract learnings after delegation.
|
|
822
|
-
This is the critical connection point between the memory system and the CLI.
|
|
823
|
-
|
|
824
|
-
DESIGN DECISION: We register hooks here instead of in __init__ to ensure
|
|
825
|
-
all services are initialized first. Hooks are only registered if the memory
|
|
826
|
-
system is enabled in configuration.
|
|
700
|
+
if self.version_service:
|
|
701
|
+
return self.version_service.get_version()
|
|
702
|
+
# Fallback if service not available
|
|
703
|
+
return "v0.0.0"
|
|
704
|
+
|
|
705
|
+
def _deploy_output_style(self) -> None:
|
|
706
|
+
"""Deploy the Claude MPM output style before Claude Code launches.
|
|
707
|
+
|
|
708
|
+
This method ensures the output style is set to "Claude MPM" on startup
|
|
709
|
+
by deploying the style file and updating Claude Code settings.
|
|
710
|
+
Only works for Claude Code >= 1.0.83.
|
|
827
711
|
"""
|
|
828
712
|
try:
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
713
|
+
from claude_mpm.core.output_style_manager import OutputStyleManager
|
|
714
|
+
|
|
715
|
+
# Create OutputStyleManager instance
|
|
716
|
+
output_style_manager = OutputStyleManager()
|
|
717
|
+
|
|
718
|
+
# Check if Claude Code supports output styles
|
|
719
|
+
if not output_style_manager.supports_output_styles():
|
|
720
|
+
self.logger.debug(
|
|
721
|
+
f"Claude Code version {output_style_manager.claude_version or 'unknown'} "
|
|
722
|
+
"does not support output styles (requires >= 1.0.83)"
|
|
723
|
+
)
|
|
832
724
|
return
|
|
833
|
-
|
|
834
|
-
#
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
725
|
+
|
|
726
|
+
# Check if output style is already deployed and active
|
|
727
|
+
settings_file = Path.home() / ".claude" / "settings.json"
|
|
728
|
+
if settings_file.exists():
|
|
729
|
+
try:
|
|
730
|
+
import json
|
|
731
|
+
|
|
732
|
+
settings = json.loads(settings_file.read_text())
|
|
733
|
+
if settings.get("activeOutputStyle") == "claude-mpm":
|
|
734
|
+
# Already active, check if file exists
|
|
735
|
+
output_style_file = (
|
|
736
|
+
Path.home() / ".claude" / "output-styles" / "claude-mpm.md"
|
|
737
|
+
)
|
|
738
|
+
if output_style_file.exists():
|
|
739
|
+
self.logger.debug(
|
|
740
|
+
"Output style 'Claude MPM' already deployed and active"
|
|
741
|
+
)
|
|
742
|
+
return
|
|
743
|
+
except Exception:
|
|
744
|
+
pass # Continue with deployment if we can't read settings
|
|
745
|
+
|
|
746
|
+
# Read the OUTPUT_STYLE.md content if it exists
|
|
747
|
+
output_style_path = (
|
|
748
|
+
Path(__file__).parent.parent / "agents" / "OUTPUT_STYLE.md"
|
|
838
749
|
)
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
self.logger.info(f"✅ Registered memory pre-delegation hook (priority: {pre_hook.priority})")
|
|
845
|
-
else:
|
|
846
|
-
self.logger.warning("❌ Failed to register memory pre-delegation hook")
|
|
847
|
-
|
|
848
|
-
# Register post-delegation hook if auto-learning is enabled
|
|
849
|
-
if self.config.get('memory.auto_learning', True): # Default to True now
|
|
850
|
-
post_hook = MemoryPostDelegationHook(self.config)
|
|
851
|
-
success = self.hook_service.register_hook(post_hook)
|
|
852
|
-
if success:
|
|
853
|
-
self.logger.info(f"✅ Registered memory post-delegation hook (priority: {post_hook.priority})")
|
|
854
|
-
else:
|
|
855
|
-
self.logger.warning("❌ Failed to register memory post-delegation hook")
|
|
750
|
+
|
|
751
|
+
if output_style_path.exists():
|
|
752
|
+
# Use existing OUTPUT_STYLE.md content
|
|
753
|
+
output_style_content = output_style_path.read_text()
|
|
754
|
+
self.logger.debug("Using existing OUTPUT_STYLE.md content")
|
|
856
755
|
else:
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
hooks = self.hook_service.list_hooks()
|
|
861
|
-
pre_count = len(hooks.get('pre_delegation', []))
|
|
862
|
-
post_count = len(hooks.get('post_delegation', []))
|
|
863
|
-
self.logger.info(f"📋 Hook Service initialized: {pre_count} pre-delegation, {post_count} post-delegation hooks")
|
|
864
|
-
|
|
865
|
-
except Exception as e:
|
|
866
|
-
self.logger.error(f"❌ Failed to register memory hooks: {e}")
|
|
867
|
-
# Don't fail the entire initialization - memory system is optional
|
|
868
|
-
|
|
869
|
-
def _launch_subprocess_interactive(self, cmd: list, env: dict):
|
|
870
|
-
"""Launch Claude as a subprocess with PTY for interactive mode."""
|
|
871
|
-
import pty
|
|
872
|
-
import select
|
|
873
|
-
import termios
|
|
874
|
-
import tty
|
|
875
|
-
import signal
|
|
876
|
-
|
|
877
|
-
# Save original terminal settings
|
|
878
|
-
original_tty = None
|
|
879
|
-
if sys.stdin.isatty():
|
|
880
|
-
original_tty = termios.tcgetattr(sys.stdin)
|
|
881
|
-
|
|
882
|
-
# Create PTY
|
|
883
|
-
master_fd, slave_fd = pty.openpty()
|
|
884
|
-
|
|
885
|
-
try:
|
|
886
|
-
# Start Claude process
|
|
887
|
-
process = subprocess.Popen(
|
|
888
|
-
cmd,
|
|
889
|
-
stdin=slave_fd,
|
|
890
|
-
stdout=slave_fd,
|
|
891
|
-
stderr=slave_fd,
|
|
892
|
-
env=env
|
|
893
|
-
)
|
|
894
|
-
|
|
895
|
-
# Close slave in parent
|
|
896
|
-
os.close(slave_fd)
|
|
897
|
-
|
|
898
|
-
if self.project_logger:
|
|
899
|
-
self.project_logger.log_system(
|
|
900
|
-
f"Claude subprocess started with PID {process.pid}",
|
|
901
|
-
level="INFO",
|
|
902
|
-
component="subprocess"
|
|
756
|
+
# Extract output style content from framework instructions
|
|
757
|
+
output_style_content = (
|
|
758
|
+
output_style_manager.extract_output_style_content()
|
|
903
759
|
)
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
760
|
+
self.logger.debug("Extracted output style from framework instructions")
|
|
761
|
+
|
|
762
|
+
# Deploy the output style
|
|
763
|
+
deployed = output_style_manager.deploy_output_style(output_style_content)
|
|
764
|
+
|
|
765
|
+
if deployed:
|
|
766
|
+
self.logger.info(
|
|
767
|
+
"✅ Output style 'Claude MPM' deployed and activated on startup"
|
|
911
768
|
)
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
while True:
|
|
927
|
-
# Check if process is still running
|
|
928
|
-
if process.poll() is not None:
|
|
929
|
-
break
|
|
930
|
-
|
|
931
|
-
# Check for data from Claude or stdin
|
|
932
|
-
r, _, _ = select.select([master_fd, sys.stdin], [], [], 0)
|
|
933
|
-
|
|
934
|
-
if master_fd in r:
|
|
935
|
-
try:
|
|
936
|
-
data = os.read(master_fd, 4096)
|
|
937
|
-
if data:
|
|
938
|
-
os.write(sys.stdout.fileno(), data)
|
|
939
|
-
# Broadcast output to WebSocket clients
|
|
940
|
-
if self.websocket_server:
|
|
941
|
-
try:
|
|
942
|
-
# Decode and send
|
|
943
|
-
output = data.decode('utf-8', errors='replace')
|
|
944
|
-
self.websocket_server.claude_output(output, "stdout")
|
|
945
|
-
except Exception as e:
|
|
946
|
-
self.logger.debug(f"Failed to broadcast output: {e}")
|
|
947
|
-
else:
|
|
948
|
-
break # EOF
|
|
949
|
-
except OSError:
|
|
950
|
-
break
|
|
951
|
-
|
|
952
|
-
if sys.stdin in r:
|
|
953
|
-
try:
|
|
954
|
-
data = os.read(sys.stdin.fileno(), 4096)
|
|
955
|
-
if data:
|
|
956
|
-
os.write(master_fd, data)
|
|
957
|
-
except OSError:
|
|
958
|
-
break
|
|
959
|
-
|
|
960
|
-
# Wait for process to complete
|
|
961
|
-
process.wait()
|
|
962
|
-
|
|
769
|
+
if self.project_logger:
|
|
770
|
+
self.project_logger.log_system(
|
|
771
|
+
"Output style 'Claude MPM' deployed and activated on startup",
|
|
772
|
+
level="INFO",
|
|
773
|
+
component="output_style",
|
|
774
|
+
)
|
|
775
|
+
else:
|
|
776
|
+
self.logger.warning("Failed to deploy output style")
|
|
777
|
+
|
|
778
|
+
except ImportError as e:
|
|
779
|
+
self.logger.warning(f"Could not import OutputStyleManager: {e}")
|
|
780
|
+
except Exception as e:
|
|
781
|
+
# Don't fail startup if output style deployment fails
|
|
782
|
+
self.logger.warning(f"Error deploying output style: {e}")
|
|
963
783
|
if self.project_logger:
|
|
964
784
|
self.project_logger.log_system(
|
|
965
|
-
f"
|
|
966
|
-
level="
|
|
967
|
-
component="
|
|
968
|
-
)
|
|
969
|
-
|
|
970
|
-
# Notify WebSocket clients
|
|
971
|
-
if self.websocket_server:
|
|
972
|
-
self.websocket_server.claude_status_changed(
|
|
973
|
-
status="stopped",
|
|
974
|
-
message=f"Claude subprocess exited with code {process.returncode}"
|
|
785
|
+
f"Output style deployment error: {e}",
|
|
786
|
+
level="WARNING",
|
|
787
|
+
component="output_style",
|
|
975
788
|
)
|
|
976
|
-
|
|
977
|
-
finally:
|
|
978
|
-
# Restore terminal
|
|
979
|
-
if original_tty and sys.stdin.isatty():
|
|
980
|
-
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, original_tty)
|
|
981
|
-
|
|
982
|
-
# Close PTY
|
|
983
|
-
try:
|
|
984
|
-
os.close(master_fd)
|
|
985
|
-
except:
|
|
986
|
-
pass
|
|
987
|
-
|
|
988
|
-
# Ensure process is terminated
|
|
989
|
-
if 'process' in locals() and process.poll() is None:
|
|
990
|
-
process.terminate()
|
|
991
|
-
try:
|
|
992
|
-
process.wait(timeout=2)
|
|
993
|
-
except subprocess.TimeoutExpired:
|
|
994
|
-
process.kill()
|
|
995
|
-
process.wait()
|
|
996
|
-
|
|
997
|
-
# End WebSocket session if in subprocess mode
|
|
998
|
-
if self.websocket_server:
|
|
999
|
-
self.websocket_server.session_ended()
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
def create_simple_context() -> str:
|
|
1003
|
-
"""Create basic context for Claude."""
|
|
1004
|
-
return """You are Claude Code running in Claude MPM (Multi-Agent Project Manager).
|
|
1005
|
-
|
|
1006
|
-
You have access to native subagents via the Task tool with subagent_type parameter:
|
|
1007
|
-
- engineer: For coding, implementation, and technical tasks
|
|
1008
|
-
- qa: For testing, validation, and quality assurance
|
|
1009
|
-
- documentation: For docs, guides, and explanations
|
|
1010
|
-
- research: For investigation and analysis
|
|
1011
|
-
- security: For security-related tasks
|
|
1012
|
-
- ops: For deployment and infrastructure
|
|
1013
|
-
- version-control: For git and version management
|
|
1014
|
-
- data-engineer: For data processing and APIs
|
|
1015
|
-
|
|
1016
|
-
Use these agents by calling: Task(description="task description", subagent_type="agent_name")
|
|
1017
789
|
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
- Lowercase format: "research", "engineer", "qa", "version-control", "data-engineer"
|
|
790
|
+
def _launch_subprocess_interactive(self, cmd: list, env: dict):
|
|
791
|
+
"""Launch Claude as a subprocess with PTY for interactive mode.
|
|
1021
792
|
|
|
1022
|
-
|
|
1023
|
-
|
|
793
|
+
Delegates to the SubprocessLauncherService for subprocess management.
|
|
794
|
+
"""
|
|
795
|
+
if self.subprocess_launcher_service:
|
|
796
|
+
self.subprocess_launcher_service.launch_subprocess_interactive(cmd, env)
|
|
797
|
+
else:
|
|
798
|
+
# Fallback if service is not available
|
|
799
|
+
self.logger.warning(
|
|
800
|
+
"Subprocess launcher service not available, cannot launch subprocess"
|
|
801
|
+
)
|
|
802
|
+
raise RuntimeError("Subprocess launcher service not available")
|
|
1024
803
|
|
|
1025
|
-
Work efficiently and delegate appropriately to subagents when needed."""
|
|
1026
804
|
|
|
805
|
+
# Moved to claude_mpm.core.system_context to avoid circular imports
|
|
806
|
+
from claude_mpm.core.system_context import create_simple_context
|
|
1027
807
|
|
|
1028
808
|
# Backward compatibility alias
|
|
1029
809
|
SimpleClaudeRunner = ClaudeRunner
|
|
@@ -1043,4 +823,4 @@ def run_claude_oneshot(prompt: str, context: Optional[str] = None) -> bool:
|
|
|
1043
823
|
runner = ClaudeRunner()
|
|
1044
824
|
if context is None:
|
|
1045
825
|
context = create_simple_context()
|
|
1046
|
-
return runner.run_oneshot(prompt, context)
|
|
826
|
+
return runner.run_oneshot(prompt, context)
|