claude-mpm 5.4.41__py3-none-any.whl → 5.6.23__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of claude-mpm might be problematic. Click here for more details.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/CLAUDE_MPM_OUTPUT_STYLE.md +66 -241
- claude_mpm/agents/CLAUDE_MPM_RESEARCH_OUTPUT_STYLE.md +413 -0
- claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +109 -1925
- claude_mpm/agents/PM_INSTRUCTIONS.md +161 -298
- claude_mpm/agents/WORKFLOW.md +2 -0
- claude_mpm/agents/templates/circuit-breakers.md +26 -17
- claude_mpm/cli/__init__.py +5 -1
- claude_mpm/cli/commands/agents.py +2 -4
- claude_mpm/cli/commands/agents_reconcile.py +197 -0
- claude_mpm/cli/commands/autotodos.py +566 -0
- claude_mpm/cli/commands/commander.py +216 -0
- claude_mpm/cli/commands/configure.py +620 -21
- claude_mpm/cli/commands/configure_agent_display.py +3 -1
- claude_mpm/cli/commands/hook_errors.py +60 -60
- claude_mpm/cli/commands/monitor.py +2 -2
- claude_mpm/cli/commands/mpm_init/core.py +15 -8
- claude_mpm/cli/commands/profile.py +9 -10
- claude_mpm/cli/commands/run.py +35 -3
- claude_mpm/cli/commands/skill_source.py +51 -2
- claude_mpm/cli/commands/skills.py +182 -32
- claude_mpm/cli/executor.py +120 -16
- claude_mpm/cli/interactive/__init__.py +10 -0
- claude_mpm/cli/interactive/agent_wizard.py +30 -50
- claude_mpm/cli/interactive/questionary_styles.py +65 -0
- claude_mpm/cli/interactive/skill_selector.py +481 -0
- claude_mpm/cli/parsers/base_parser.py +76 -1
- claude_mpm/cli/parsers/commander_parser.py +116 -0
- claude_mpm/cli/parsers/profile_parser.py +0 -1
- claude_mpm/cli/parsers/run_parser.py +10 -0
- claude_mpm/cli/parsers/skill_source_parser.py +4 -0
- claude_mpm/cli/parsers/skills_parser.py +2 -3
- claude_mpm/cli/startup.py +527 -506
- claude_mpm/cli/startup_display.py +74 -6
- claude_mpm/cli/startup_logging.py +2 -2
- claude_mpm/cli/utils.py +7 -3
- claude_mpm/commander/__init__.py +78 -0
- claude_mpm/commander/adapters/__init__.py +60 -0
- claude_mpm/commander/adapters/auggie.py +260 -0
- claude_mpm/commander/adapters/base.py +288 -0
- claude_mpm/commander/adapters/claude_code.py +392 -0
- claude_mpm/commander/adapters/codex.py +237 -0
- claude_mpm/commander/adapters/communication.py +366 -0
- claude_mpm/commander/adapters/example_usage.py +310 -0
- claude_mpm/commander/adapters/mpm.py +389 -0
- claude_mpm/commander/adapters/registry.py +204 -0
- claude_mpm/commander/api/__init__.py +16 -0
- claude_mpm/commander/api/app.py +121 -0
- claude_mpm/commander/api/errors.py +133 -0
- claude_mpm/commander/api/routes/__init__.py +8 -0
- claude_mpm/commander/api/routes/events.py +184 -0
- claude_mpm/commander/api/routes/inbox.py +171 -0
- claude_mpm/commander/api/routes/messages.py +148 -0
- claude_mpm/commander/api/routes/projects.py +271 -0
- claude_mpm/commander/api/routes/sessions.py +226 -0
- claude_mpm/commander/api/routes/work.py +296 -0
- claude_mpm/commander/api/schemas.py +186 -0
- claude_mpm/commander/chat/__init__.py +7 -0
- claude_mpm/commander/chat/cli.py +146 -0
- claude_mpm/commander/chat/commands.py +96 -0
- claude_mpm/commander/chat/repl.py +310 -0
- claude_mpm/commander/config.py +51 -0
- claude_mpm/commander/config_loader.py +115 -0
- claude_mpm/commander/core/__init__.py +10 -0
- claude_mpm/commander/core/block_manager.py +325 -0
- claude_mpm/commander/core/response_manager.py +323 -0
- claude_mpm/commander/daemon.py +603 -0
- claude_mpm/commander/env_loader.py +59 -0
- claude_mpm/commander/events/__init__.py +26 -0
- claude_mpm/commander/events/manager.py +332 -0
- claude_mpm/commander/frameworks/__init__.py +12 -0
- claude_mpm/commander/frameworks/base.py +146 -0
- claude_mpm/commander/frameworks/claude_code.py +58 -0
- claude_mpm/commander/frameworks/mpm.py +62 -0
- claude_mpm/commander/inbox/__init__.py +16 -0
- claude_mpm/commander/inbox/dedup.py +128 -0
- claude_mpm/commander/inbox/inbox.py +224 -0
- claude_mpm/commander/inbox/models.py +70 -0
- claude_mpm/commander/instance_manager.py +450 -0
- claude_mpm/commander/llm/__init__.py +6 -0
- claude_mpm/commander/llm/openrouter_client.py +167 -0
- claude_mpm/commander/llm/summarizer.py +70 -0
- claude_mpm/commander/memory/__init__.py +45 -0
- claude_mpm/commander/memory/compression.py +347 -0
- claude_mpm/commander/memory/embeddings.py +230 -0
- claude_mpm/commander/memory/entities.py +310 -0
- claude_mpm/commander/memory/example_usage.py +290 -0
- claude_mpm/commander/memory/integration.py +325 -0
- claude_mpm/commander/memory/search.py +381 -0
- claude_mpm/commander/memory/store.py +657 -0
- claude_mpm/commander/models/__init__.py +18 -0
- claude_mpm/commander/models/events.py +121 -0
- claude_mpm/commander/models/project.py +162 -0
- claude_mpm/commander/models/work.py +214 -0
- claude_mpm/commander/parsing/__init__.py +20 -0
- claude_mpm/commander/parsing/extractor.py +132 -0
- claude_mpm/commander/parsing/output_parser.py +270 -0
- claude_mpm/commander/parsing/patterns.py +100 -0
- claude_mpm/commander/persistence/__init__.py +11 -0
- claude_mpm/commander/persistence/event_store.py +274 -0
- claude_mpm/commander/persistence/state_store.py +309 -0
- claude_mpm/commander/persistence/work_store.py +164 -0
- claude_mpm/commander/polling/__init__.py +13 -0
- claude_mpm/commander/polling/event_detector.py +104 -0
- claude_mpm/commander/polling/output_buffer.py +49 -0
- claude_mpm/commander/polling/output_poller.py +153 -0
- claude_mpm/commander/project_session.py +268 -0
- claude_mpm/commander/proxy/__init__.py +12 -0
- claude_mpm/commander/proxy/formatter.py +89 -0
- claude_mpm/commander/proxy/output_handler.py +191 -0
- claude_mpm/commander/proxy/relay.py +155 -0
- claude_mpm/commander/registry.py +410 -0
- claude_mpm/commander/runtime/__init__.py +10 -0
- claude_mpm/commander/runtime/executor.py +191 -0
- claude_mpm/commander/runtime/monitor.py +346 -0
- claude_mpm/commander/session/__init__.py +6 -0
- claude_mpm/commander/session/context.py +81 -0
- claude_mpm/commander/session/manager.py +59 -0
- claude_mpm/commander/tmux_orchestrator.py +361 -0
- claude_mpm/commander/web/__init__.py +1 -0
- claude_mpm/commander/work/__init__.py +30 -0
- claude_mpm/commander/work/executor.py +207 -0
- claude_mpm/commander/work/queue.py +405 -0
- claude_mpm/commander/workflow/__init__.py +27 -0
- claude_mpm/commander/workflow/event_handler.py +241 -0
- claude_mpm/commander/workflow/notifier.py +146 -0
- claude_mpm/commands/mpm-config.md +8 -0
- claude_mpm/commands/mpm-doctor.md +8 -0
- claude_mpm/commands/mpm-help.md +8 -0
- claude_mpm/commands/mpm-init.md +8 -0
- claude_mpm/commands/mpm-monitor.md +8 -0
- claude_mpm/commands/mpm-organize.md +8 -0
- claude_mpm/commands/mpm-postmortem.md +8 -0
- claude_mpm/commands/mpm-session-resume.md +9 -1
- claude_mpm/commands/mpm-status.md +8 -0
- claude_mpm/commands/mpm-ticket-view.md +8 -0
- claude_mpm/commands/mpm-version.md +8 -0
- claude_mpm/commands/mpm.md +8 -0
- claude_mpm/config/agent_presets.py +8 -7
- claude_mpm/config/skill_sources.py +16 -0
- claude_mpm/constants.py +1 -0
- claude_mpm/core/claude_runner.py +154 -2
- claude_mpm/core/config.py +35 -22
- claude_mpm/core/config_constants.py +74 -9
- claude_mpm/core/constants.py +56 -12
- claude_mpm/core/hook_manager.py +51 -3
- claude_mpm/core/interactive_session.py +12 -11
- claude_mpm/core/logger.py +26 -9
- claude_mpm/core/logging_utils.py +35 -11
- claude_mpm/core/network_config.py +148 -0
- claude_mpm/core/oneshot_session.py +7 -6
- claude_mpm/core/optimized_startup.py +3 -1
- claude_mpm/core/output_style_manager.py +63 -18
- claude_mpm/core/shared/config_loader.py +3 -1
- claude_mpm/core/socketio_pool.py +13 -5
- claude_mpm/core/unified_config.py +54 -8
- claude_mpm/core/unified_paths.py +95 -90
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.C33zOoyM.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.CW1J-YuA.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/1WZnGYqX.js +24 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/67pF3qNn.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/6RxdMKe4.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/8cZrfX0h.js +60 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/9a6T2nm-.js +7 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B443AUzu.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B8AwtY2H.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BF15LAsF.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/BRcwIQNr.js +4 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{uj46x2Wr.js → BSNlmTZj.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BV6nKitt.js +43 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BViJ8lZt.js +128 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BcQ-Q0FE.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Bpyvgze_.js +30 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BzTRqg-z.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C0Fr8dve.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C3rbW_a-.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C8WYN38h.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C9I8FlXH.js +61 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIQcWgO2.js +36 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIctN7YN.js +7 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CKrS_JZW.js +145 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CR6P9C4A.js +89 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRRR9MD_.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRcR2DqT.js +334 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CSXtMOf0.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CT-sbxSk.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWm6DJsp.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CmKTTxBW.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CpqQ1Kzn.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cu_Erd72.js +261 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D2nGpDRe.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9iCMida.js +267 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9ykgMoY.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DL2Ldur1.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DPfltzjH.js +165 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{N4qtv3Hx.js → DR8nis88.js} +2 -2
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DUliQN2b.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DVp1hx9R.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DXlhR01x.js +122 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D_lyTybS.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DngoTTgh.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DqkmHtDC.js +220 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DsDh8EYs.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DypDmXgd.js +139 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Gi6I4Gst.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/IPYC-LnN.js +162 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JTLiF7dt.js +24 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JpevfAFt.js +68 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DjhvlsAc.js → NqQ1dWOy.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/R8CEIRAd.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Zxy7qc-l.js +64 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/q9Hm6zAU.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/qtd3IeO4.js +15 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/ulBFON_C.js +65 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/wQVh1CoA.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.Dr7t0z2J.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.BGhZHUS3.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/{0.CAGBuiOw.js → 0.RgBboRvH.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DG-KkbDf.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.D_jnf-x6.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -1
- claude_mpm/dashboard/static/svelte-build/index.html +11 -11
- 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/cli_enhancements.py +2 -1
- claude_mpm/hooks/claude_hooks/INTEGRATION_EXAMPLE.md +243 -0
- claude_mpm/hooks/claude_hooks/README_AUTO_PAUSE.md +403 -0
- claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.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__/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/auto_pause_handler.py +485 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +305 -87
- claude_mpm/hooks/claude_hooks/hook_handler.py +106 -89
- claude_mpm/hooks/claude_hooks/hook_wrapper.sh +6 -11
- claude_mpm/hooks/claude_hooks/installer.py +116 -8
- claude_mpm/hooks/claude_hooks/memory_integration.py +51 -31
- claude_mpm/hooks/claude_hooks/response_tracking.py +42 -59
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.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 +39 -24
- claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +36 -103
- claude_mpm/hooks/claude_hooks/services/state_manager.py +23 -36
- claude_mpm/hooks/claude_hooks/services/subagent_processor.py +73 -75
- claude_mpm/hooks/kuzu_memory_hook.py +5 -5
- claude_mpm/hooks/session_resume_hook.py +89 -1
- claude_mpm/hooks/templates/pre_tool_use_template.py +10 -2
- claude_mpm/init.py +215 -2
- claude_mpm/scripts/claude-hook-handler.sh +43 -16
- claude_mpm/services/agents/agent_recommendation_service.py +8 -8
- claude_mpm/services/agents/agent_selection_service.py +2 -2
- claude_mpm/services/agents/cache_git_manager.py +1 -1
- claude_mpm/services/agents/deployment/agent_discovery_service.py +3 -1
- claude_mpm/services/agents/deployment/agent_format_converter.py +25 -13
- claude_mpm/services/agents/deployment/agent_template_builder.py +37 -17
- claude_mpm/services/agents/deployment/async_agent_deployment.py +31 -27
- claude_mpm/services/agents/deployment/deployment_reconciler.py +577 -0
- claude_mpm/services/agents/deployment/local_template_deployment.py +3 -1
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +36 -8
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +50 -26
- claude_mpm/services/agents/deployment/startup_reconciliation.py +138 -0
- claude_mpm/services/agents/git_source_manager.py +21 -2
- claude_mpm/services/agents/loading/framework_agent_loader.py +75 -2
- claude_mpm/services/agents/single_tier_deployment_service.py +4 -4
- claude_mpm/services/agents/sources/git_source_sync_service.py +116 -5
- claude_mpm/services/agents/startup_sync.py +5 -2
- claude_mpm/services/cli/__init__.py +3 -0
- claude_mpm/services/cli/incremental_pause_manager.py +561 -0
- claude_mpm/services/cli/session_resume_helper.py +10 -2
- claude_mpm/services/delegation_detector.py +175 -0
- claude_mpm/services/diagnostics/checks/agent_sources_check.py +30 -0
- claude_mpm/services/diagnostics/checks/configuration_check.py +24 -0
- claude_mpm/services/diagnostics/checks/installation_check.py +22 -0
- claude_mpm/services/diagnostics/checks/mcp_services_check.py +23 -0
- claude_mpm/services/diagnostics/doctor_reporter.py +31 -1
- claude_mpm/services/diagnostics/models.py +14 -1
- claude_mpm/services/event_log.py +325 -0
- claude_mpm/services/infrastructure/__init__.py +4 -0
- claude_mpm/services/infrastructure/context_usage_tracker.py +291 -0
- claude_mpm/services/infrastructure/resume_log_generator.py +24 -5
- claude_mpm/services/monitor/daemon_manager.py +15 -4
- claude_mpm/services/monitor/management/lifecycle.py +8 -3
- claude_mpm/services/monitor/server.py +106 -16
- claude_mpm/services/pm_skills_deployer.py +302 -94
- claude_mpm/services/profile_manager.py +10 -4
- claude_mpm/services/skills/git_skill_source_manager.py +192 -29
- claude_mpm/services/skills/selective_skill_deployer.py +211 -46
- claude_mpm/services/skills/skill_discovery_service.py +74 -4
- claude_mpm/services/skills_deployer.py +192 -70
- claude_mpm/services/socketio/handlers/hook.py +14 -7
- claude_mpm/services/socketio/server/main.py +12 -4
- claude_mpm/skills/__init__.py +2 -1
- claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
- claude_mpm/skills/bundled/collaboration/git-worktrees.md +317 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
- claude_mpm/skills/bundled/collaboration/stacked-prs.md +251 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/INTEGRATION.md +611 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/README.md +596 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/SKILL.md +260 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/examples/nextjs-env-structure.md +315 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/frameworks.md +436 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/security.md +433 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/synchronization.md +452 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/troubleshooting.md +404 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/validation.md +420 -0
- claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
- claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
- claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
- claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
- claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
- claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
- claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
- claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
- claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
- claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
- claude_mpm/skills/bundled/pm/mpm/SKILL.md +38 -0
- claude_mpm/skills/bundled/pm/mpm-agent-update-workflow/SKILL.md +75 -0
- claude_mpm/skills/bundled/pm/mpm-bug-reporting/SKILL.md +248 -0
- claude_mpm/skills/bundled/pm/mpm-circuit-breaker-enforcement/SKILL.md +476 -0
- claude_mpm/skills/bundled/pm/mpm-config/SKILL.md +29 -0
- claude_mpm/skills/bundled/pm/mpm-delegation-patterns/SKILL.md +167 -0
- claude_mpm/skills/bundled/pm/mpm-doctor/SKILL.md +53 -0
- claude_mpm/skills/bundled/pm/mpm-git-file-tracking/SKILL.md +113 -0
- claude_mpm/skills/bundled/pm/mpm-help/SKILL.md +35 -0
- claude_mpm/skills/bundled/pm/mpm-init/SKILL.md +125 -0
- claude_mpm/skills/bundled/pm/mpm-monitor/SKILL.md +32 -0
- claude_mpm/skills/bundled/pm/mpm-organize/SKILL.md +121 -0
- claude_mpm/skills/bundled/pm/mpm-postmortem/SKILL.md +22 -0
- claude_mpm/skills/bundled/pm/mpm-pr-workflow/SKILL.md +124 -0
- claude_mpm/skills/bundled/pm/mpm-session-management/SKILL.md +312 -0
- claude_mpm/skills/bundled/pm/mpm-session-pause/SKILL.md +170 -0
- claude_mpm/skills/bundled/pm/mpm-session-resume/SKILL.md +31 -0
- claude_mpm/skills/bundled/pm/mpm-status/SKILL.md +37 -0
- claude_mpm/skills/bundled/pm/mpm-teaching-mode/SKILL.md +657 -0
- claude_mpm/skills/bundled/pm/mpm-ticket-view/SKILL.md +110 -0
- claude_mpm/skills/bundled/pm/mpm-ticketing-integration/SKILL.md +154 -0
- claude_mpm/skills/bundled/pm/mpm-tool-usage-guide/SKILL.md +386 -0
- claude_mpm/skills/bundled/pm/mpm-verification-protocols/SKILL.md +198 -0
- claude_mpm/skills/bundled/pm/mpm-version/SKILL.md +21 -0
- claude_mpm/skills/bundled/react/flexlayout-react.md +742 -0
- claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
- claude_mpm/skills/bundled/security-scanning.md +112 -0
- claude_mpm/skills/bundled/tauri/tauri-async-patterns.md +495 -0
- claude_mpm/skills/bundled/tauri/tauri-build-deploy.md +599 -0
- claude_mpm/skills/bundled/tauri/tauri-command-patterns.md +535 -0
- claude_mpm/skills/bundled/tauri/tauri-error-handling.md +613 -0
- claude_mpm/skills/bundled/tauri/tauri-event-system.md +648 -0
- claude_mpm/skills/bundled/tauri/tauri-file-system.md +673 -0
- claude_mpm/skills/bundled/tauri/tauri-frontend-integration.md +767 -0
- claude_mpm/skills/bundled/tauri/tauri-performance.md +669 -0
- claude_mpm/skills/bundled/tauri/tauri-state-management.md +573 -0
- claude_mpm/skills/bundled/tauri/tauri-testing.md +384 -0
- claude_mpm/skills/bundled/tauri/tauri-window-management.md +628 -0
- claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
- claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
- claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/SKILL.md +458 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/examples/example-inspection-report.md +411 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/assertion-quality.md +317 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/inspection-checklist.md +270 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/red-flags.md +436 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
- claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
- claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
- claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
- claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
- claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
- claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
- claude_mpm/skills/registry.py +295 -90
- claude_mpm/skills/skill_manager.py +29 -23
- claude_mpm/templates/.pre-commit-config.yaml +112 -0
- claude_mpm/utils/agent_dependency_loader.py +103 -4
- claude_mpm/utils/robust_installer.py +45 -24
- claude_mpm-5.6.23.dist-info/METADATA +393 -0
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.23.dist-info}/RECORD +447 -149
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.B_FtCwCQ.css +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.Cl_eSA4x.css +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BgChzWQ1.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIXEwuWe.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWc5urbQ.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DMkZpdF2.js +0 -2
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.DTL5mJO-.js +0 -2
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.DzuEhzqh.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DFLC8jdE.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.DPvEihJJ.js +0 -10
- claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager.cpython-311.pyc +0 -0
- claude_mpm-5.4.41.dist-info/METADATA +0 -998
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.23.dist-info}/WHEEL +0 -0
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.23.dist-info}/entry_points.txt +0 -0
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.23.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.23.dist-info}/licenses/LICENSE-FAQ.md +0 -0
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.23.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
"""Example usage of multi-runtime adapter architecture.
|
|
2
|
+
|
|
3
|
+
This module demonstrates how to use the adapter registry and
|
|
4
|
+
individual adapters for different AI coding runtimes.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import logging
|
|
8
|
+
from typing import Optional
|
|
9
|
+
|
|
10
|
+
from claude_mpm.commander.adapters import (
|
|
11
|
+
AdapterRegistry,
|
|
12
|
+
AuggieAdapter,
|
|
13
|
+
ClaudeCodeAdapter,
|
|
14
|
+
CodexAdapter,
|
|
15
|
+
MPMAdapter,
|
|
16
|
+
RuntimeAdapter,
|
|
17
|
+
RuntimeCapability,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
# Configure logging
|
|
21
|
+
logging.basicConfig(
|
|
22
|
+
level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
|
23
|
+
)
|
|
24
|
+
logger = logging.getLogger(__name__)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def example_registry_usage() -> None:
|
|
28
|
+
"""Demonstrate adapter registry usage."""
|
|
29
|
+
print("\n" + "=" * 60)
|
|
30
|
+
print("ADAPTER REGISTRY USAGE")
|
|
31
|
+
print("=" * 60 + "\n")
|
|
32
|
+
|
|
33
|
+
# List all registered adapters
|
|
34
|
+
registered = AdapterRegistry.list_registered()
|
|
35
|
+
print(f"Registered adapters: {registered}")
|
|
36
|
+
|
|
37
|
+
# Detect available runtimes on system
|
|
38
|
+
available = AdapterRegistry.detect_available()
|
|
39
|
+
print(f"Available runtimes: {available}")
|
|
40
|
+
|
|
41
|
+
# Get default adapter (best available)
|
|
42
|
+
default_adapter = AdapterRegistry.get_default()
|
|
43
|
+
if default_adapter:
|
|
44
|
+
print(f"\nDefault adapter: {default_adapter.name}")
|
|
45
|
+
print(f"Capabilities: {default_adapter.capabilities}")
|
|
46
|
+
else:
|
|
47
|
+
print("\nNo adapters available on this system")
|
|
48
|
+
|
|
49
|
+
# Get specific adapter
|
|
50
|
+
mpm_adapter = AdapterRegistry.get("mpm")
|
|
51
|
+
if mpm_adapter:
|
|
52
|
+
print(f"\nMPM adapter available: {mpm_adapter.name}")
|
|
53
|
+
else:
|
|
54
|
+
print("\nMPM adapter not available")
|
|
55
|
+
|
|
56
|
+
# Check if specific runtime is available
|
|
57
|
+
if AdapterRegistry.is_available("claude-code"):
|
|
58
|
+
print("\nClaude Code is available")
|
|
59
|
+
else:
|
|
60
|
+
print("\nClaude Code is NOT available")
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def example_adapter_capabilities() -> None:
|
|
64
|
+
"""Demonstrate checking adapter capabilities."""
|
|
65
|
+
print("\n" + "=" * 60)
|
|
66
|
+
print("ADAPTER CAPABILITIES")
|
|
67
|
+
print("=" * 60 + "\n")
|
|
68
|
+
|
|
69
|
+
adapters = [
|
|
70
|
+
ClaudeCodeAdapter(),
|
|
71
|
+
AuggieAdapter(),
|
|
72
|
+
CodexAdapter(),
|
|
73
|
+
MPMAdapter(),
|
|
74
|
+
]
|
|
75
|
+
|
|
76
|
+
for adapter in adapters:
|
|
77
|
+
print(f"\n{adapter.name.upper()} Adapter:")
|
|
78
|
+
print(
|
|
79
|
+
f" Command: {adapter.runtime_info.command if adapter.runtime_info else 'N/A'}"
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
# Check for specific capabilities
|
|
83
|
+
info = adapter.runtime_info
|
|
84
|
+
if info:
|
|
85
|
+
print(f" Supports agents: {info.supports_agents}")
|
|
86
|
+
print(f" Instruction file: {info.instruction_file or 'None'}")
|
|
87
|
+
|
|
88
|
+
# Check for advanced features
|
|
89
|
+
if RuntimeCapability.AGENT_DELEGATION in info.capabilities:
|
|
90
|
+
print(" ✓ Agent delegation supported")
|
|
91
|
+
else:
|
|
92
|
+
print(" ✗ Agent delegation NOT supported")
|
|
93
|
+
|
|
94
|
+
if RuntimeCapability.HOOKS in info.capabilities:
|
|
95
|
+
print(" ✓ Lifecycle hooks supported")
|
|
96
|
+
else:
|
|
97
|
+
print(" ✗ Lifecycle hooks NOT supported")
|
|
98
|
+
|
|
99
|
+
if RuntimeCapability.MCP_TOOLS in info.capabilities:
|
|
100
|
+
print(" ✓ MCP tools supported")
|
|
101
|
+
else:
|
|
102
|
+
print(" ✗ MCP tools NOT supported")
|
|
103
|
+
|
|
104
|
+
if RuntimeCapability.SKILLS in info.capabilities:
|
|
105
|
+
print(" ✓ Skills supported")
|
|
106
|
+
else:
|
|
107
|
+
print(" ✗ Skills NOT supported")
|
|
108
|
+
|
|
109
|
+
if RuntimeCapability.MONITOR in info.capabilities:
|
|
110
|
+
print(" ✓ Real-time monitoring supported")
|
|
111
|
+
else:
|
|
112
|
+
print(" ✗ Real-time monitoring NOT supported")
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def example_build_commands() -> None:
|
|
116
|
+
"""Demonstrate building launch commands."""
|
|
117
|
+
print("\n" + "=" * 60)
|
|
118
|
+
print("BUILD LAUNCH COMMANDS")
|
|
119
|
+
print("=" * 60 + "\n")
|
|
120
|
+
|
|
121
|
+
project_path = "/home/user/my-project"
|
|
122
|
+
agent_prompt = "You are a Python expert specializing in FastAPI and async code."
|
|
123
|
+
|
|
124
|
+
adapters = [
|
|
125
|
+
ClaudeCodeAdapter(),
|
|
126
|
+
AuggieAdapter(),
|
|
127
|
+
CodexAdapter(),
|
|
128
|
+
MPMAdapter(),
|
|
129
|
+
]
|
|
130
|
+
|
|
131
|
+
for adapter in adapters:
|
|
132
|
+
print(f"\n{adapter.name.upper()}:")
|
|
133
|
+
|
|
134
|
+
# Basic launch command
|
|
135
|
+
cmd = adapter.build_launch_command(project_path)
|
|
136
|
+
print(f" Basic: {cmd}")
|
|
137
|
+
|
|
138
|
+
# With agent prompt
|
|
139
|
+
cmd_with_prompt = adapter.build_launch_command(project_path, agent_prompt)
|
|
140
|
+
print(f" With prompt: {cmd_with_prompt}")
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def example_inject_instructions() -> None:
|
|
144
|
+
"""Demonstrate injecting custom instructions."""
|
|
145
|
+
print("\n" + "=" * 60)
|
|
146
|
+
print("INJECT CUSTOM INSTRUCTIONS")
|
|
147
|
+
print("=" * 60 + "\n")
|
|
148
|
+
|
|
149
|
+
instructions = """You are a senior Python engineer.
|
|
150
|
+
Follow PEP 8 strictly.
|
|
151
|
+
Write comprehensive tests for all code.
|
|
152
|
+
Use type hints everywhere."""
|
|
153
|
+
|
|
154
|
+
adapters = [
|
|
155
|
+
ClaudeCodeAdapter(),
|
|
156
|
+
AuggieAdapter(),
|
|
157
|
+
CodexAdapter(),
|
|
158
|
+
MPMAdapter(),
|
|
159
|
+
]
|
|
160
|
+
|
|
161
|
+
for adapter in adapters:
|
|
162
|
+
print(f"\n{adapter.name.upper()}:")
|
|
163
|
+
|
|
164
|
+
cmd = adapter.inject_instructions(instructions)
|
|
165
|
+
if cmd:
|
|
166
|
+
print(f" Command: {cmd}")
|
|
167
|
+
else:
|
|
168
|
+
print(" Not supported")
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def example_inject_agent_context() -> None:
|
|
172
|
+
"""Demonstrate injecting agent context."""
|
|
173
|
+
print("\n" + "=" * 60)
|
|
174
|
+
print("INJECT AGENT CONTEXT")
|
|
175
|
+
print("=" * 60 + "\n")
|
|
176
|
+
|
|
177
|
+
agent_id = "eng-001"
|
|
178
|
+
context = {
|
|
179
|
+
"role": "Engineer",
|
|
180
|
+
"specialty": "Backend Python",
|
|
181
|
+
"task": "Implement API endpoints",
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
adapters = [
|
|
185
|
+
ClaudeCodeAdapter(),
|
|
186
|
+
AuggieAdapter(),
|
|
187
|
+
CodexAdapter(),
|
|
188
|
+
MPMAdapter(),
|
|
189
|
+
]
|
|
190
|
+
|
|
191
|
+
for adapter in adapters:
|
|
192
|
+
print(f"\n{adapter.name.upper()}:")
|
|
193
|
+
|
|
194
|
+
cmd = adapter.inject_agent_context(agent_id, context)
|
|
195
|
+
if cmd:
|
|
196
|
+
print(f" Command: {cmd[:100]}...")
|
|
197
|
+
else:
|
|
198
|
+
print(" Not supported")
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def example_parse_response() -> None:
|
|
202
|
+
"""Demonstrate parsing runtime output."""
|
|
203
|
+
print("\n" + "=" * 60)
|
|
204
|
+
print("PARSE RUNTIME OUTPUT")
|
|
205
|
+
print("=" * 60 + "\n")
|
|
206
|
+
|
|
207
|
+
# Simulate different output scenarios
|
|
208
|
+
outputs = {
|
|
209
|
+
"idle": "File created successfully.\n> ",
|
|
210
|
+
"error": "Error: File not found: config.py\n> ",
|
|
211
|
+
"question": "Should I proceed with the changes? (y/n)?",
|
|
212
|
+
"processing": "Processing your request...",
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
adapter = ClaudeCodeAdapter()
|
|
216
|
+
|
|
217
|
+
for scenario, output in outputs.items():
|
|
218
|
+
print(f"\n{scenario.upper()}:")
|
|
219
|
+
parsed = adapter.parse_response(output)
|
|
220
|
+
print(f" Content: {parsed.content[:50]}...")
|
|
221
|
+
print(f" Is complete: {parsed.is_complete}")
|
|
222
|
+
print(f" Is error: {parsed.is_error}")
|
|
223
|
+
print(f" Is question: {parsed.is_question}")
|
|
224
|
+
if parsed.error_message:
|
|
225
|
+
print(f" Error message: {parsed.error_message}")
|
|
226
|
+
if parsed.question_text:
|
|
227
|
+
print(f" Question: {parsed.question_text}")
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
def example_runtime_selection() -> None:
|
|
231
|
+
"""Demonstrate selecting runtime based on requirements."""
|
|
232
|
+
print("\n" + "=" * 60)
|
|
233
|
+
print("RUNTIME SELECTION LOGIC")
|
|
234
|
+
print("=" * 60 + "\n")
|
|
235
|
+
|
|
236
|
+
def select_runtime(
|
|
237
|
+
needs_agents: bool = False, needs_mcp: bool = False
|
|
238
|
+
) -> Optional[RuntimeAdapter]:
|
|
239
|
+
"""Select appropriate runtime based on requirements."""
|
|
240
|
+
# Get all available adapters
|
|
241
|
+
available = AdapterRegistry.detect_available()
|
|
242
|
+
|
|
243
|
+
# Filter by requirements
|
|
244
|
+
for name in available:
|
|
245
|
+
adapter = AdapterRegistry.get(name)
|
|
246
|
+
if not adapter or not adapter.runtime_info:
|
|
247
|
+
continue
|
|
248
|
+
|
|
249
|
+
info = adapter.runtime_info
|
|
250
|
+
|
|
251
|
+
# Check agent requirement
|
|
252
|
+
if needs_agents and not info.supports_agents:
|
|
253
|
+
continue
|
|
254
|
+
|
|
255
|
+
# Check MCP requirement
|
|
256
|
+
if needs_mcp and RuntimeCapability.MCP_TOOLS not in info.capabilities:
|
|
257
|
+
continue
|
|
258
|
+
|
|
259
|
+
# Found suitable runtime
|
|
260
|
+
return adapter
|
|
261
|
+
|
|
262
|
+
return None
|
|
263
|
+
|
|
264
|
+
# Example 1: Need agent delegation
|
|
265
|
+
print("Requirement: Agent delegation")
|
|
266
|
+
adapter = select_runtime(needs_agents=True)
|
|
267
|
+
if adapter:
|
|
268
|
+
print(f" Selected: {adapter.name}")
|
|
269
|
+
else:
|
|
270
|
+
print(" No suitable runtime found")
|
|
271
|
+
|
|
272
|
+
# Example 2: Need MCP tools
|
|
273
|
+
print("\nRequirement: MCP tools")
|
|
274
|
+
adapter = select_runtime(needs_mcp=True)
|
|
275
|
+
if adapter:
|
|
276
|
+
print(f" Selected: {adapter.name}")
|
|
277
|
+
else:
|
|
278
|
+
print(" No suitable runtime found")
|
|
279
|
+
|
|
280
|
+
# Example 3: Need both
|
|
281
|
+
print("\nRequirement: Agent delegation + MCP tools")
|
|
282
|
+
adapter = select_runtime(needs_agents=True, needs_mcp=True)
|
|
283
|
+
if adapter:
|
|
284
|
+
print(f" Selected: {adapter.name}")
|
|
285
|
+
else:
|
|
286
|
+
print(" No suitable runtime found")
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
def main() -> None:
|
|
290
|
+
"""Run all examples."""
|
|
291
|
+
print("\n" + "#" * 60)
|
|
292
|
+
print("# MULTI-RUNTIME ADAPTER ARCHITECTURE EXAMPLES")
|
|
293
|
+
print("#" * 60)
|
|
294
|
+
|
|
295
|
+
# Run all examples
|
|
296
|
+
example_registry_usage()
|
|
297
|
+
example_adapter_capabilities()
|
|
298
|
+
example_build_commands()
|
|
299
|
+
example_inject_instructions()
|
|
300
|
+
example_inject_agent_context()
|
|
301
|
+
example_parse_response()
|
|
302
|
+
example_runtime_selection()
|
|
303
|
+
|
|
304
|
+
print("\n" + "#" * 60)
|
|
305
|
+
print("# EXAMPLES COMPLETE")
|
|
306
|
+
print("#" * 60 + "\n")
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
if __name__ == "__main__":
|
|
310
|
+
main()
|
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
"""MPM (Multi-agent Project Manager) runtime adapter.
|
|
2
|
+
|
|
3
|
+
This module implements the RuntimeAdapter interface for MPM,
|
|
4
|
+
providing full support for agent delegation, hooks, skills, and monitoring.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import json
|
|
8
|
+
import logging
|
|
9
|
+
import re
|
|
10
|
+
import shlex
|
|
11
|
+
from typing import List, Optional, Set
|
|
12
|
+
|
|
13
|
+
from .base import (
|
|
14
|
+
Capability,
|
|
15
|
+
ParsedResponse,
|
|
16
|
+
RuntimeAdapter,
|
|
17
|
+
RuntimeCapability,
|
|
18
|
+
RuntimeInfo,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
logger = logging.getLogger(__name__)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class MPMAdapter(RuntimeAdapter):
|
|
25
|
+
"""Adapter for MPM (Multi-agent Project Manager).
|
|
26
|
+
|
|
27
|
+
MPM extends Claude Code with multi-agent orchestration, lifecycle hooks,
|
|
28
|
+
skills, real-time monitoring, and advanced project management capabilities.
|
|
29
|
+
|
|
30
|
+
Features:
|
|
31
|
+
- Agent delegation and sub-agent spawning
|
|
32
|
+
- Lifecycle hooks (pre/post task, pre/post commit, etc.)
|
|
33
|
+
- Loadable skills for specialized tasks
|
|
34
|
+
- Real-time monitoring dashboard
|
|
35
|
+
- Custom instructions via CLAUDE.md
|
|
36
|
+
- MCP server integration
|
|
37
|
+
- Git workflow automation
|
|
38
|
+
|
|
39
|
+
Example:
|
|
40
|
+
>>> adapter = MPMAdapter()
|
|
41
|
+
>>> cmd = adapter.build_launch_command("/home/user/project")
|
|
42
|
+
>>> # Inject agent context
|
|
43
|
+
>>> ctx_cmd = adapter.inject_agent_context("eng-001", {"role": "Engineer"})
|
|
44
|
+
>>> # Check capabilities
|
|
45
|
+
>>> info = adapter.runtime_info
|
|
46
|
+
>>> if RuntimeCapability.AGENT_DELEGATION in info.capabilities:
|
|
47
|
+
... print("Supports agent delegation")
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
# Idle detection patterns (inherits from Claude Code)
|
|
51
|
+
IDLE_PATTERNS = [
|
|
52
|
+
r"^>\s*$", # Simple prompt
|
|
53
|
+
r"claude>\s*$", # Named prompt
|
|
54
|
+
r"╭─+╮", # Box drawing
|
|
55
|
+
r"What would you like",
|
|
56
|
+
r"How can I help",
|
|
57
|
+
]
|
|
58
|
+
|
|
59
|
+
# MPM-specific patterns
|
|
60
|
+
MPM_PATTERNS = [
|
|
61
|
+
r"\[MPM\]", # MPM prefix
|
|
62
|
+
r"Agent spawned:",
|
|
63
|
+
r"Delegating to agent:",
|
|
64
|
+
r"Hook triggered:",
|
|
65
|
+
r"Skill loaded:",
|
|
66
|
+
]
|
|
67
|
+
|
|
68
|
+
# Error patterns
|
|
69
|
+
ERROR_PATTERNS = [
|
|
70
|
+
r"Error:",
|
|
71
|
+
r"Failed:",
|
|
72
|
+
r"Exception:",
|
|
73
|
+
r"Permission denied",
|
|
74
|
+
r"not found",
|
|
75
|
+
r"Traceback \(most recent call last\)",
|
|
76
|
+
r"FATAL:",
|
|
77
|
+
r"✗",
|
|
78
|
+
r"command not found",
|
|
79
|
+
r"cannot access",
|
|
80
|
+
r"Agent error:",
|
|
81
|
+
r"Hook failed:",
|
|
82
|
+
]
|
|
83
|
+
|
|
84
|
+
# Question patterns
|
|
85
|
+
QUESTION_PATTERNS = [
|
|
86
|
+
r"Which option",
|
|
87
|
+
r"Should I proceed",
|
|
88
|
+
r"Please choose",
|
|
89
|
+
r"\(y/n\)\?",
|
|
90
|
+
r"Are you sure",
|
|
91
|
+
r"Do you want",
|
|
92
|
+
r"\[Y/n\]",
|
|
93
|
+
r"\[yes/no\]",
|
|
94
|
+
r"Select an option",
|
|
95
|
+
r"Choose from",
|
|
96
|
+
r"Delegate to which agent",
|
|
97
|
+
]
|
|
98
|
+
|
|
99
|
+
# ANSI escape code pattern
|
|
100
|
+
ANSI_ESCAPE = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])")
|
|
101
|
+
|
|
102
|
+
@property
|
|
103
|
+
def name(self) -> str:
|
|
104
|
+
"""Return the runtime identifier."""
|
|
105
|
+
return "mpm"
|
|
106
|
+
|
|
107
|
+
@property
|
|
108
|
+
def capabilities(self) -> Set[Capability]:
|
|
109
|
+
"""Return the set of capabilities supported by MPM."""
|
|
110
|
+
return {
|
|
111
|
+
Capability.TOOL_USE,
|
|
112
|
+
Capability.FILE_EDIT,
|
|
113
|
+
Capability.FILE_CREATE,
|
|
114
|
+
Capability.GIT_OPERATIONS,
|
|
115
|
+
Capability.SHELL_COMMANDS,
|
|
116
|
+
Capability.WEB_SEARCH,
|
|
117
|
+
Capability.COMPLEX_REASONING,
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
@property
|
|
121
|
+
def runtime_info(self) -> RuntimeInfo:
|
|
122
|
+
"""Return detailed runtime information.
|
|
123
|
+
|
|
124
|
+
MPM has the most comprehensive capabilities of all runtimes.
|
|
125
|
+
"""
|
|
126
|
+
return RuntimeInfo(
|
|
127
|
+
name="mpm",
|
|
128
|
+
version=None, # Could parse from mpm --version
|
|
129
|
+
capabilities={
|
|
130
|
+
RuntimeCapability.FILE_READ,
|
|
131
|
+
RuntimeCapability.FILE_EDIT,
|
|
132
|
+
RuntimeCapability.FILE_CREATE,
|
|
133
|
+
RuntimeCapability.BASH_EXECUTION,
|
|
134
|
+
RuntimeCapability.GIT_OPERATIONS,
|
|
135
|
+
RuntimeCapability.TOOL_USE,
|
|
136
|
+
RuntimeCapability.AGENT_DELEGATION, # Key MPM feature
|
|
137
|
+
RuntimeCapability.HOOKS, # Lifecycle hooks
|
|
138
|
+
RuntimeCapability.INSTRUCTIONS, # CLAUDE.md
|
|
139
|
+
RuntimeCapability.MCP_TOOLS, # MCP integration
|
|
140
|
+
RuntimeCapability.SKILLS, # Loadable skills
|
|
141
|
+
RuntimeCapability.MONITOR, # Real-time monitoring
|
|
142
|
+
RuntimeCapability.WEB_SEARCH,
|
|
143
|
+
RuntimeCapability.COMPLEX_REASONING,
|
|
144
|
+
},
|
|
145
|
+
command="claude", # MPM uses claude CLI with MPM config
|
|
146
|
+
supports_agents=True, # Full agent support
|
|
147
|
+
instruction_file="CLAUDE.md",
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
def build_launch_command(
|
|
151
|
+
self, project_path: str, agent_prompt: Optional[str] = None
|
|
152
|
+
) -> str:
|
|
153
|
+
"""Generate shell command to start MPM.
|
|
154
|
+
|
|
155
|
+
Args:
|
|
156
|
+
project_path: Absolute path to the project directory
|
|
157
|
+
agent_prompt: Optional system prompt to configure agent
|
|
158
|
+
|
|
159
|
+
Returns:
|
|
160
|
+
Shell command string ready to execute
|
|
161
|
+
|
|
162
|
+
Example:
|
|
163
|
+
>>> adapter = MPMAdapter()
|
|
164
|
+
>>> adapter.build_launch_command("/home/user/project")
|
|
165
|
+
"cd '/home/user/project' && claude --dangerously-skip-permissions"
|
|
166
|
+
"""
|
|
167
|
+
quoted_path = shlex.quote(project_path)
|
|
168
|
+
cmd = f"cd {quoted_path} && claude"
|
|
169
|
+
|
|
170
|
+
if agent_prompt:
|
|
171
|
+
quoted_prompt = shlex.quote(agent_prompt)
|
|
172
|
+
cmd += f" --system-prompt {quoted_prompt}"
|
|
173
|
+
|
|
174
|
+
# Skip permissions for automated operation
|
|
175
|
+
cmd += " --dangerously-skip-permissions"
|
|
176
|
+
|
|
177
|
+
logger.debug(f"Built MPM launch command: {cmd}")
|
|
178
|
+
return cmd
|
|
179
|
+
|
|
180
|
+
def format_input(self, message: str) -> str:
|
|
181
|
+
"""Prepare message for MPM's input format."""
|
|
182
|
+
formatted = message.strip()
|
|
183
|
+
logger.debug(f"Formatted input: {formatted[:100]}...")
|
|
184
|
+
return formatted
|
|
185
|
+
|
|
186
|
+
def strip_ansi(self, text: str) -> str:
|
|
187
|
+
"""Remove ANSI escape codes from text."""
|
|
188
|
+
return self.ANSI_ESCAPE.sub("", text)
|
|
189
|
+
|
|
190
|
+
def detect_idle(self, output: str) -> bool:
|
|
191
|
+
"""Recognize when MPM is waiting for input."""
|
|
192
|
+
if not output:
|
|
193
|
+
return False
|
|
194
|
+
|
|
195
|
+
clean = self.strip_ansi(output)
|
|
196
|
+
lines = clean.strip().split("\n")
|
|
197
|
+
|
|
198
|
+
if not lines:
|
|
199
|
+
return False
|
|
200
|
+
|
|
201
|
+
last_line = lines[-1].strip()
|
|
202
|
+
|
|
203
|
+
for pattern in self.IDLE_PATTERNS:
|
|
204
|
+
if re.search(pattern, last_line):
|
|
205
|
+
logger.debug(f"Detected idle state with pattern: {pattern}")
|
|
206
|
+
return True
|
|
207
|
+
|
|
208
|
+
return False
|
|
209
|
+
|
|
210
|
+
def detect_error(self, output: str) -> Optional[str]:
|
|
211
|
+
"""Recognize error states and extract error message."""
|
|
212
|
+
clean = self.strip_ansi(output)
|
|
213
|
+
|
|
214
|
+
for pattern in self.ERROR_PATTERNS:
|
|
215
|
+
match = re.search(pattern, clean, re.IGNORECASE)
|
|
216
|
+
if match:
|
|
217
|
+
for line in clean.split("\n"):
|
|
218
|
+
if re.search(pattern, line, re.IGNORECASE):
|
|
219
|
+
error_msg = line.strip()
|
|
220
|
+
logger.warning(f"Detected error: {error_msg}")
|
|
221
|
+
return error_msg
|
|
222
|
+
|
|
223
|
+
return None
|
|
224
|
+
|
|
225
|
+
def detect_question(
|
|
226
|
+
self, output: str
|
|
227
|
+
) -> tuple[bool, Optional[str], Optional[List[str]]]:
|
|
228
|
+
"""Detect if MPM is asking a question."""
|
|
229
|
+
clean = self.strip_ansi(output)
|
|
230
|
+
|
|
231
|
+
for pattern in self.QUESTION_PATTERNS:
|
|
232
|
+
if re.search(pattern, clean, re.IGNORECASE):
|
|
233
|
+
lines = clean.strip().split("\n")
|
|
234
|
+
question = None
|
|
235
|
+
options = []
|
|
236
|
+
|
|
237
|
+
for line in lines:
|
|
238
|
+
if re.search(pattern, line, re.IGNORECASE):
|
|
239
|
+
question = line.strip()
|
|
240
|
+
|
|
241
|
+
# Look for numbered options
|
|
242
|
+
opt_match = re.match(r"^\s*(\d+)[.):]\s*(.+)$", line)
|
|
243
|
+
if opt_match:
|
|
244
|
+
options.append(opt_match.group(2).strip())
|
|
245
|
+
|
|
246
|
+
logger.debug(
|
|
247
|
+
f"Detected question: {question}, options: {options if options else 'none'}"
|
|
248
|
+
)
|
|
249
|
+
return True, question, options if options else None
|
|
250
|
+
|
|
251
|
+
return False, None, None
|
|
252
|
+
|
|
253
|
+
def parse_response(self, output: str) -> ParsedResponse:
|
|
254
|
+
"""Extract meaningful content from MPM output."""
|
|
255
|
+
if not output:
|
|
256
|
+
return ParsedResponse(
|
|
257
|
+
content="",
|
|
258
|
+
is_complete=False,
|
|
259
|
+
is_error=False,
|
|
260
|
+
is_question=False,
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
clean = self.strip_ansi(output)
|
|
264
|
+
error_msg = self.detect_error(output)
|
|
265
|
+
is_question, question_text, options = self.detect_question(output)
|
|
266
|
+
is_complete = self.detect_idle(output)
|
|
267
|
+
|
|
268
|
+
response = ParsedResponse(
|
|
269
|
+
content=clean,
|
|
270
|
+
is_complete=is_complete,
|
|
271
|
+
is_error=error_msg is not None,
|
|
272
|
+
error_message=error_msg,
|
|
273
|
+
is_question=is_question,
|
|
274
|
+
question_text=question_text,
|
|
275
|
+
options=options,
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
logger.debug(
|
|
279
|
+
f"Parsed response: complete={is_complete}, error={error_msg is not None}, "
|
|
280
|
+
f"question={is_question}"
|
|
281
|
+
)
|
|
282
|
+
|
|
283
|
+
return response
|
|
284
|
+
|
|
285
|
+
def inject_instructions(self, instructions: str) -> Optional[str]:
|
|
286
|
+
"""Return command to inject custom instructions.
|
|
287
|
+
|
|
288
|
+
MPM uses CLAUDE.md for custom instructions.
|
|
289
|
+
|
|
290
|
+
Args:
|
|
291
|
+
instructions: Instructions text to inject
|
|
292
|
+
|
|
293
|
+
Returns:
|
|
294
|
+
Command to write CLAUDE.md file
|
|
295
|
+
|
|
296
|
+
Example:
|
|
297
|
+
>>> adapter = MPMAdapter()
|
|
298
|
+
>>> cmd = adapter.inject_instructions("You are a Python expert")
|
|
299
|
+
>>> print(cmd)
|
|
300
|
+
echo '...' > CLAUDE.md
|
|
301
|
+
"""
|
|
302
|
+
# Write to CLAUDE.md
|
|
303
|
+
escaped = instructions.replace("'", "'\\''")
|
|
304
|
+
return f"echo '{escaped}' > CLAUDE.md"
|
|
305
|
+
|
|
306
|
+
def inject_agent_context(self, agent_id: str, context: dict) -> Optional[str]:
|
|
307
|
+
"""Return command to inject agent context.
|
|
308
|
+
|
|
309
|
+
MPM supports agent context injection via special command.
|
|
310
|
+
|
|
311
|
+
Args:
|
|
312
|
+
agent_id: Unique identifier for agent
|
|
313
|
+
context: Context dictionary with agent metadata
|
|
314
|
+
|
|
315
|
+
Returns:
|
|
316
|
+
Command to inject agent context
|
|
317
|
+
|
|
318
|
+
Example:
|
|
319
|
+
>>> adapter = MPMAdapter()
|
|
320
|
+
>>> cmd = adapter.inject_agent_context("eng-001", {"role": "Engineer"})
|
|
321
|
+
>>> # Command would set MPM_AGENT_ID and MPM_AGENT_CONTEXT env vars
|
|
322
|
+
"""
|
|
323
|
+
# Serialize context to JSON
|
|
324
|
+
context_json = json.dumps(context)
|
|
325
|
+
escaped_json = context_json.replace("'", "'\\''")
|
|
326
|
+
|
|
327
|
+
# Set environment variables for MPM agent context
|
|
328
|
+
# MPM runtime can read these to understand agent identity
|
|
329
|
+
cmd = f"export MPM_AGENT_ID='{agent_id}' && export MPM_AGENT_CONTEXT='{escaped_json}'"
|
|
330
|
+
|
|
331
|
+
logger.debug(f"Built agent context injection command for {agent_id}")
|
|
332
|
+
return cmd
|
|
333
|
+
|
|
334
|
+
def detect_agent_spawn(self, output: str) -> Optional[dict]:
|
|
335
|
+
"""Detect if MPM has spawned a new agent.
|
|
336
|
+
|
|
337
|
+
Args:
|
|
338
|
+
output: Raw output from MPM
|
|
339
|
+
|
|
340
|
+
Returns:
|
|
341
|
+
Dict with agent info if spawn detected, None otherwise
|
|
342
|
+
|
|
343
|
+
Example:
|
|
344
|
+
>>> adapter = MPMAdapter()
|
|
345
|
+
>>> info = adapter.detect_agent_spawn("[MPM] Agent spawned: eng-001 (Engineer)")
|
|
346
|
+
>>> if info:
|
|
347
|
+
... print(info['agent_id'])
|
|
348
|
+
'eng-001'
|
|
349
|
+
"""
|
|
350
|
+
clean = self.strip_ansi(output)
|
|
351
|
+
|
|
352
|
+
# Pattern: [MPM] Agent spawned: <agent_id> (<role>)
|
|
353
|
+
match = re.search(r"\[MPM\] Agent spawned: (\S+) \(([^)]+)\)", clean)
|
|
354
|
+
if match:
|
|
355
|
+
agent_id = match.group(1)
|
|
356
|
+
role = match.group(2)
|
|
357
|
+
|
|
358
|
+
logger.info(f"Detected agent spawn: {agent_id} ({role})")
|
|
359
|
+
return {"agent_id": agent_id, "role": role}
|
|
360
|
+
|
|
361
|
+
return None
|
|
362
|
+
|
|
363
|
+
def detect_hook_trigger(self, output: str) -> Optional[dict]:
|
|
364
|
+
"""Detect if a lifecycle hook was triggered.
|
|
365
|
+
|
|
366
|
+
Args:
|
|
367
|
+
output: Raw output from MPM
|
|
368
|
+
|
|
369
|
+
Returns:
|
|
370
|
+
Dict with hook info if trigger detected, None otherwise
|
|
371
|
+
|
|
372
|
+
Example:
|
|
373
|
+
>>> adapter = MPMAdapter()
|
|
374
|
+
>>> info = adapter.detect_hook_trigger("[MPM] Hook triggered: pre-commit")
|
|
375
|
+
>>> if info:
|
|
376
|
+
... print(info['hook_name'])
|
|
377
|
+
'pre-commit'
|
|
378
|
+
"""
|
|
379
|
+
clean = self.strip_ansi(output)
|
|
380
|
+
|
|
381
|
+
# Pattern: [MPM] Hook triggered: <hook_name>
|
|
382
|
+
match = re.search(r"\[MPM\] Hook triggered: (\S+)", clean)
|
|
383
|
+
if match:
|
|
384
|
+
hook_name = match.group(1)
|
|
385
|
+
|
|
386
|
+
logger.info(f"Detected hook trigger: {hook_name}")
|
|
387
|
+
return {"hook_name": hook_name}
|
|
388
|
+
|
|
389
|
+
return None
|