claude-mpm 5.4.48__py3-none-any.whl → 5.6.34__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 +119 -689
- 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 +171 -17
- 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 +5 -0
- claude_mpm/cli/startup.py +544 -511
- 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 +39 -13
- 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 +66 -18
- claude_mpm/core/shared/config_loader.py +3 -1
- claude_mpm/core/socketio_pool.py +47 -15
- 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 +527 -136
- claude_mpm/hooks/claude_hooks/hook_handler.py +170 -104
- claude_mpm/hooks/claude_hooks/hook_wrapper.sh +6 -11
- claude_mpm/hooks/claude_hooks/installer.py +206 -36
- claude_mpm/hooks/claude_hooks/memory_integration.py +52 -32
- claude_mpm/hooks/claude_hooks/response_tracking.py +43 -60
- claude_mpm/hooks/claude_hooks/services/__init__.py +21 -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__/container.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/protocols.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 +41 -26
- claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +38 -105
- claude_mpm/hooks/claude_hooks/services/container.py +310 -0
- claude_mpm/hooks/claude_hooks/services/protocols.py +328 -0
- claude_mpm/hooks/claude_hooks/services/state_manager.py +25 -38
- claude_mpm/hooks/claude_hooks/services/subagent_processor.py +75 -77
- claude_mpm/hooks/session_resume_hook.py +89 -1
- claude_mpm/hooks/templates/pre_tool_use_simple.py +6 -6
- claude_mpm/hooks/templates/pre_tool_use_template.py +16 -8
- claude_mpm/init.py +215 -2
- claude_mpm/scripts/claude-hook-handler.sh +46 -19
- claude_mpm/scripts/start_activity_logging.py +0 -0
- 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 +8 -6
- claude_mpm/services/agents/deployment/agent_template_builder.py +14 -4
- claude_mpm/services/agents/deployment/deployment_reconciler.py +577 -0
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +4 -4
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +4 -1
- claude_mpm/services/agents/deployment/startup_reconciliation.py +138 -0
- claude_mpm/services/agents/git_source_manager.py +6 -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 +10 -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/command_deployment_service.py +44 -26
- 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/hook_installer_service.py +77 -8
- 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 +267 -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 +188 -67
- 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.34.dist-info/METADATA +393 -0
- {claude_mpm-5.4.48.dist-info → claude_mpm-5.6.34.dist-info}/RECORD +453 -151
- 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.48.dist-info/METADATA +0 -999
- {claude_mpm-5.4.48.dist-info → claude_mpm-5.6.34.dist-info}/WHEEL +0 -0
- {claude_mpm-5.4.48.dist-info → claude_mpm-5.6.34.dist-info}/entry_points.txt +0 -0
- {claude_mpm-5.4.48.dist-info → claude_mpm-5.6.34.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-5.4.48.dist-info → claude_mpm-5.6.34.dist-info}/licenses/LICENSE-FAQ.md +0 -0
- {claude_mpm-5.4.48.dist-info → claude_mpm-5.6.34.dist-info}/top_level.txt +0 -0
|
@@ -10,12 +10,10 @@ import os
|
|
|
10
10
|
import re
|
|
11
11
|
import shutil
|
|
12
12
|
import stat
|
|
13
|
-
import subprocess
|
|
13
|
+
import subprocess # nosec B404 - Safe: only uses hardcoded 'claude' CLI command, no user input
|
|
14
14
|
from pathlib import Path
|
|
15
15
|
from typing import Dict, List, Optional, Tuple
|
|
16
16
|
|
|
17
|
-
from ...core.logger import get_logger
|
|
18
|
-
|
|
19
17
|
|
|
20
18
|
class HookInstaller:
|
|
21
19
|
"""Manages installation and configuration of Claude MPM hooks."""
|
|
@@ -151,7 +149,7 @@ main() {
|
|
|
151
149
|
if [ "${CLAUDE_MPM_HOOK_DEBUG}" = "true" ]; then
|
|
152
150
|
echo "[$(date -u +%Y-%m-%dT%H:%M:%S.%3NZ)] Claude MPM not found, continuing..." >> /tmp/claude-mpm-hook.log
|
|
153
151
|
fi
|
|
154
|
-
echo '{"
|
|
152
|
+
echo '{"continue": true}'
|
|
155
153
|
exit 0
|
|
156
154
|
fi
|
|
157
155
|
|
|
@@ -178,7 +176,7 @@ main() {
|
|
|
178
176
|
echo "[$(date -u +%Y-%m-%dT%H:%M:%S.%3NZ)] Hook handler failed, see /tmp/claude-mpm-hook-error.log" >> /tmp/claude-mpm-hook.log
|
|
179
177
|
echo "[$(date -u +%Y-%m-%dT%H:%M:%S.%3NZ)] Error: $(cat /tmp/claude-mpm-hook-error.log 2>/dev/null | head -5)" >> /tmp/claude-mpm-hook.log
|
|
180
178
|
fi
|
|
181
|
-
echo '{"
|
|
179
|
+
echo '{"continue": true}'
|
|
182
180
|
exit 0
|
|
183
181
|
fi
|
|
184
182
|
|
|
@@ -194,14 +192,25 @@ main "$@"
|
|
|
194
192
|
MIN_CLAUDE_VERSION = "1.0.92"
|
|
195
193
|
# Minimum version for PreToolUse input modification support
|
|
196
194
|
MIN_PRETOOL_MODIFY_VERSION = "2.0.30"
|
|
195
|
+
# Minimum version for user-invocable skills support
|
|
196
|
+
MIN_SKILLS_VERSION = "2.1.3"
|
|
197
197
|
|
|
198
198
|
def __init__(self):
|
|
199
199
|
"""Initialize the hook installer."""
|
|
200
|
-
|
|
201
|
-
|
|
200
|
+
# Use __name__ directly to avoid double prefix
|
|
201
|
+
# __name__ is already 'claude_mpm.hooks.claude_hooks.installer'
|
|
202
|
+
# get_logger() adds 'claude_mpm.' prefix, causing duplicate
|
|
203
|
+
import logging
|
|
204
|
+
|
|
205
|
+
self.logger = logging.getLogger(__name__)
|
|
206
|
+
# Use project-level paths, NEVER global ~/.claude/settings.json
|
|
207
|
+
# This ensures hooks are scoped to the current project only
|
|
208
|
+
self.project_root = Path.cwd()
|
|
209
|
+
self.claude_dir = self.project_root / ".claude"
|
|
202
210
|
self.hooks_dir = self.claude_dir / "hooks" # Kept for backward compatibility
|
|
203
|
-
# Use settings.json for
|
|
204
|
-
|
|
211
|
+
# Use settings.local.json for project-level hook settings
|
|
212
|
+
# Claude Code reads project-level settings from .claude/settings.local.json
|
|
213
|
+
self.settings_file = self.claude_dir / "settings.local.json"
|
|
205
214
|
# There is no legacy settings file - this was a bug where both pointed to same file
|
|
206
215
|
# Setting to None to disable cleanup that was deleting freshly installed hooks
|
|
207
216
|
self.old_settings_file = None
|
|
@@ -220,7 +229,7 @@ main "$@"
|
|
|
220
229
|
|
|
221
230
|
try:
|
|
222
231
|
# Run claude --version command
|
|
223
|
-
result = subprocess.run(
|
|
232
|
+
result = subprocess.run( # nosec B607 B603 - Safe: hardcoded command, no user input
|
|
224
233
|
["claude", "--version"],
|
|
225
234
|
capture_output=True,
|
|
226
235
|
text=True,
|
|
@@ -331,6 +340,53 @@ main "$@"
|
|
|
331
340
|
|
|
332
341
|
return True
|
|
333
342
|
|
|
343
|
+
def _version_meets_minimum(self, version: str, min_version: str) -> bool:
|
|
344
|
+
"""Check if a version meets minimum requirements.
|
|
345
|
+
|
|
346
|
+
Args:
|
|
347
|
+
version: Current version string (e.g., "2.1.3")
|
|
348
|
+
min_version: Minimum required version string (e.g., "2.1.3")
|
|
349
|
+
|
|
350
|
+
Returns:
|
|
351
|
+
True if version meets or exceeds minimum, False otherwise
|
|
352
|
+
"""
|
|
353
|
+
|
|
354
|
+
def parse_version(v: str) -> List[int]:
|
|
355
|
+
"""Parse semantic version string to list of integers."""
|
|
356
|
+
try:
|
|
357
|
+
return [int(x) for x in v.split(".")]
|
|
358
|
+
except (ValueError, AttributeError):
|
|
359
|
+
return [0]
|
|
360
|
+
|
|
361
|
+
current = parse_version(version)
|
|
362
|
+
required = parse_version(min_version)
|
|
363
|
+
|
|
364
|
+
# Compare versions
|
|
365
|
+
for i in range(max(len(current), len(required))):
|
|
366
|
+
curr_part = current[i] if i < len(current) else 0
|
|
367
|
+
req_part = required[i] if i < len(required) else 0
|
|
368
|
+
|
|
369
|
+
if curr_part < req_part:
|
|
370
|
+
return False
|
|
371
|
+
if curr_part > req_part:
|
|
372
|
+
return True
|
|
373
|
+
|
|
374
|
+
return True
|
|
375
|
+
|
|
376
|
+
def supports_user_invocable_skills(self) -> bool:
|
|
377
|
+
"""Check if Claude Code version supports user-invocable skills.
|
|
378
|
+
|
|
379
|
+
User-invocable skills were added in Claude Code v2.1.3.
|
|
380
|
+
This feature allows users to invoke skills via slash commands.
|
|
381
|
+
|
|
382
|
+
Returns:
|
|
383
|
+
True if version supports user-invocable skills, False otherwise
|
|
384
|
+
"""
|
|
385
|
+
version = self.get_claude_version()
|
|
386
|
+
if not version:
|
|
387
|
+
return False
|
|
388
|
+
return self._version_meets_minimum(version, self.MIN_SKILLS_VERSION)
|
|
389
|
+
|
|
334
390
|
def get_hook_script_path(self) -> Path:
|
|
335
391
|
"""Get the path to the hook handler script based on installation method.
|
|
336
392
|
|
|
@@ -485,6 +541,44 @@ main "$@"
|
|
|
485
541
|
except Exception as e:
|
|
486
542
|
self.logger.warning(f"Could not clean up old settings file: {e}")
|
|
487
543
|
|
|
544
|
+
def _fix_status_line(self, settings: Dict) -> None:
|
|
545
|
+
"""Fix statusLine command to handle both output style schema formats.
|
|
546
|
+
|
|
547
|
+
The statusLine command receives input in different formats:
|
|
548
|
+
- Newer format: {"activeOutputStyle": "Claude MPM", ...}
|
|
549
|
+
- Older format: {"output_style": {"name": "Claude MPM"}, ...}
|
|
550
|
+
|
|
551
|
+
This method ensures the jq expression checks both locations.
|
|
552
|
+
|
|
553
|
+
Args:
|
|
554
|
+
settings: The settings dictionary to update
|
|
555
|
+
"""
|
|
556
|
+
if "statusLine" not in settings:
|
|
557
|
+
return
|
|
558
|
+
|
|
559
|
+
status_line = settings.get("statusLine", {})
|
|
560
|
+
if "command" not in status_line:
|
|
561
|
+
return
|
|
562
|
+
|
|
563
|
+
command = status_line["command"]
|
|
564
|
+
|
|
565
|
+
# Pattern to match: '.output_style.name // "default"'
|
|
566
|
+
# We need to update it to: '.output_style.name // .activeOutputStyle // "default"'
|
|
567
|
+
old_pattern = r'\.output_style\.name\s*//\s*"default"'
|
|
568
|
+
new_pattern = '.output_style.name // .activeOutputStyle // "default"'
|
|
569
|
+
|
|
570
|
+
# Check if the command needs updating
|
|
571
|
+
if re.search(old_pattern, command) and ".activeOutputStyle" not in command:
|
|
572
|
+
updated_command = re.sub(old_pattern, new_pattern, command)
|
|
573
|
+
settings["statusLine"]["command"] = updated_command
|
|
574
|
+
self.logger.info(
|
|
575
|
+
"Fixed statusLine command to handle both output style schemas"
|
|
576
|
+
)
|
|
577
|
+
else:
|
|
578
|
+
self.logger.debug(
|
|
579
|
+
"StatusLine command already supports both schemas or not present"
|
|
580
|
+
)
|
|
581
|
+
|
|
488
582
|
def _update_claude_settings(self, hook_script_path: Path) -> None:
|
|
489
583
|
"""Update Claude settings to use the installed hook."""
|
|
490
584
|
self.logger.info("Updating Claude settings...")
|
|
@@ -511,40 +605,101 @@ main "$@"
|
|
|
511
605
|
# Hook configuration for each event type
|
|
512
606
|
hook_command = {"type": "command", "command": str(hook_script_path.absolute())}
|
|
513
607
|
|
|
608
|
+
def is_our_hook(cmd: dict) -> bool:
|
|
609
|
+
"""Check if a hook command belongs to claude-mpm."""
|
|
610
|
+
if cmd.get("type") != "command":
|
|
611
|
+
return False
|
|
612
|
+
command = cmd.get("command", "")
|
|
613
|
+
return "claude-hook-handler.sh" in command or command.endswith(
|
|
614
|
+
"claude-mpm-hook.sh"
|
|
615
|
+
)
|
|
616
|
+
|
|
617
|
+
def merge_hooks_for_event(
|
|
618
|
+
existing_hooks: list, new_hook_command: dict, use_matcher: bool = True
|
|
619
|
+
) -> list:
|
|
620
|
+
"""Merge new hook command into existing hooks without duplication.
|
|
621
|
+
|
|
622
|
+
Args:
|
|
623
|
+
existing_hooks: Current hooks configuration for an event type
|
|
624
|
+
new_hook_command: The claude-mpm hook command to add
|
|
625
|
+
use_matcher: Whether to include matcher: "*" in the config
|
|
626
|
+
|
|
627
|
+
Returns:
|
|
628
|
+
Updated hooks list with our hook merged in
|
|
629
|
+
"""
|
|
630
|
+
# Check if our hook already exists in any existing hook config
|
|
631
|
+
our_hook_exists = False
|
|
632
|
+
|
|
633
|
+
for hook_config in existing_hooks:
|
|
634
|
+
if "hooks" in hook_config and isinstance(hook_config["hooks"], list):
|
|
635
|
+
for hook in hook_config["hooks"]:
|
|
636
|
+
if is_our_hook(hook):
|
|
637
|
+
# Update existing hook command path (in case it changed)
|
|
638
|
+
hook["command"] = new_hook_command["command"]
|
|
639
|
+
our_hook_exists = True
|
|
640
|
+
break
|
|
641
|
+
if our_hook_exists:
|
|
642
|
+
break
|
|
643
|
+
|
|
644
|
+
if our_hook_exists:
|
|
645
|
+
# Our hook already exists, just return the updated list
|
|
646
|
+
return existing_hooks
|
|
647
|
+
|
|
648
|
+
# Our hook doesn't exist - need to add it
|
|
649
|
+
# Strategy: Add our hook to the first "*" matcher config, or create new config
|
|
650
|
+
added = False
|
|
651
|
+
|
|
652
|
+
for hook_config in existing_hooks:
|
|
653
|
+
# Check if this config has matcher: "*" (or no matcher for simple events)
|
|
654
|
+
matcher = hook_config.get("matcher")
|
|
655
|
+
if matcher == "*" or (not use_matcher and matcher is None):
|
|
656
|
+
# Add our hook to this config's hooks array
|
|
657
|
+
if "hooks" not in hook_config:
|
|
658
|
+
hook_config["hooks"] = []
|
|
659
|
+
hook_config["hooks"].append(new_hook_command)
|
|
660
|
+
added = True
|
|
661
|
+
break
|
|
662
|
+
|
|
663
|
+
if not added:
|
|
664
|
+
# No suitable config found, create a new one
|
|
665
|
+
if use_matcher:
|
|
666
|
+
new_config = {"matcher": "*", "hooks": [new_hook_command]}
|
|
667
|
+
else:
|
|
668
|
+
new_config = {"hooks": [new_hook_command]}
|
|
669
|
+
existing_hooks.append(new_config)
|
|
670
|
+
|
|
671
|
+
return existing_hooks
|
|
672
|
+
|
|
514
673
|
# Tool-related events need a matcher string
|
|
515
674
|
tool_events = ["PreToolUse", "PostToolUse"]
|
|
516
675
|
for event_type in tool_events:
|
|
517
|
-
settings["hooks"]
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
}
|
|
522
|
-
]
|
|
676
|
+
existing = settings["hooks"].get(event_type, [])
|
|
677
|
+
settings["hooks"][event_type] = merge_hooks_for_event(
|
|
678
|
+
existing, hook_command, use_matcher=True
|
|
679
|
+
)
|
|
523
680
|
|
|
524
681
|
# Simple events (no subtypes, no matcher needed)
|
|
525
682
|
simple_events = ["Stop", "SubagentStop", "SubagentStart"]
|
|
526
683
|
for event_type in simple_events:
|
|
527
|
-
settings["hooks"]
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
]
|
|
684
|
+
existing = settings["hooks"].get(event_type, [])
|
|
685
|
+
settings["hooks"][event_type] = merge_hooks_for_event(
|
|
686
|
+
existing, hook_command, use_matcher=False
|
|
687
|
+
)
|
|
532
688
|
|
|
533
689
|
# SessionStart needs matcher for subtypes (startup, resume)
|
|
534
|
-
settings["hooks"]
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
}
|
|
539
|
-
]
|
|
690
|
+
existing = settings["hooks"].get("SessionStart", [])
|
|
691
|
+
settings["hooks"]["SessionStart"] = merge_hooks_for_event(
|
|
692
|
+
existing, hook_command, use_matcher=True
|
|
693
|
+
)
|
|
540
694
|
|
|
541
695
|
# UserPromptSubmit needs matcher for potential subtypes
|
|
542
|
-
settings["hooks"]
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
696
|
+
existing = settings["hooks"].get("UserPromptSubmit", [])
|
|
697
|
+
settings["hooks"]["UserPromptSubmit"] = merge_hooks_for_event(
|
|
698
|
+
existing, hook_command, use_matcher=True
|
|
699
|
+
)
|
|
700
|
+
|
|
701
|
+
# Fix statusLine command to handle both output style schemas
|
|
702
|
+
self._fix_status_line(settings)
|
|
548
703
|
|
|
549
704
|
# Write settings to settings.json
|
|
550
705
|
with self.settings_file.open("w") as f:
|
|
@@ -556,7 +711,22 @@ main "$@"
|
|
|
556
711
|
self._cleanup_old_settings()
|
|
557
712
|
|
|
558
713
|
def _install_commands(self) -> None:
|
|
559
|
-
"""Install custom commands for Claude Code.
|
|
714
|
+
"""Install custom commands for Claude Code.
|
|
715
|
+
|
|
716
|
+
For Claude Code >= 2.1.3, commands are deployed as skills via PMSkillsDeployerService.
|
|
717
|
+
This method provides backward compatibility for older versions.
|
|
718
|
+
"""
|
|
719
|
+
# Check if skills-based commands are supported
|
|
720
|
+
if self.supports_user_invocable_skills():
|
|
721
|
+
self.logger.info(
|
|
722
|
+
"Claude Code >= 2.1.3 detected. Commands deployed as skills - "
|
|
723
|
+
"skipping legacy command installation."
|
|
724
|
+
)
|
|
725
|
+
return
|
|
726
|
+
|
|
727
|
+
# Legacy installation for older Claude Code versions
|
|
728
|
+
self.logger.info("Installing legacy commands for Claude Code < 2.1.3")
|
|
729
|
+
|
|
560
730
|
# Find commands directory using proper resource resolution
|
|
561
731
|
try:
|
|
562
732
|
from ...core.unified_paths import get_package_resource_path
|
|
@@ -782,7 +952,7 @@ main "$@"
|
|
|
782
952
|
if "hooks" in settings:
|
|
783
953
|
status["configured_events"] = list(settings["hooks"].keys())
|
|
784
954
|
configured_in_local = True
|
|
785
|
-
except Exception:
|
|
955
|
+
except Exception: # nosec B110 - Intentional: ignore errors reading settings file
|
|
786
956
|
pass
|
|
787
957
|
|
|
788
958
|
# Also check old settings file
|
|
@@ -796,7 +966,7 @@ main "$@"
|
|
|
796
966
|
status["warning"] = (
|
|
797
967
|
"Hooks found in settings.local.json but Claude Code reads from settings.json"
|
|
798
968
|
)
|
|
799
|
-
except Exception:
|
|
969
|
+
except Exception: # nosec B110 - Intentional: ignore errors reading old settings file
|
|
800
970
|
pass
|
|
801
971
|
|
|
802
972
|
status["settings_location"] = (
|
|
@@ -7,39 +7,67 @@ including pre and post delegation hooks.
|
|
|
7
7
|
|
|
8
8
|
import logging
|
|
9
9
|
import os
|
|
10
|
-
import
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
# Try to import _log from hook_handler, fall back to no-op
|
|
13
|
+
try:
|
|
14
|
+
from claude_mpm.hooks.claude_hooks.hook_handler import _log
|
|
15
|
+
except ImportError:
|
|
16
|
+
|
|
17
|
+
def _log(msg: str) -> None:
|
|
18
|
+
pass # Silent fallback
|
|
19
|
+
|
|
11
20
|
|
|
12
21
|
# Install-type-aware logging configuration BEFORE kuzu-memory imports
|
|
13
22
|
# This overrides kuzu-memory's WARNING-level basicConfig (fixes 1M-445)
|
|
14
|
-
# but respects production install silence
|
|
23
|
+
# but respects production install silence AND startup suppression
|
|
15
24
|
try:
|
|
16
25
|
from claude_mpm.core.unified_paths import DeploymentContext, PathContext
|
|
17
26
|
|
|
18
27
|
context = PathContext.detect_deployment_context()
|
|
19
28
|
|
|
29
|
+
# CRITICAL: Check if root logger is already suppressed (CRITICAL+1 from startup.py)
|
|
30
|
+
# If so, don't call basicConfig as it will reset the level to INFO
|
|
31
|
+
root_logger = logging.getLogger()
|
|
32
|
+
is_suppressed = root_logger.level > logging.CRITICAL # CRITICAL+1 = 51
|
|
33
|
+
|
|
20
34
|
# Only configure verbose logging for development/editable installs
|
|
21
|
-
#
|
|
22
|
-
if context in (
|
|
35
|
+
# AND if logging isn't already suppressed by startup.py
|
|
36
|
+
if not is_suppressed and context in (
|
|
37
|
+
DeploymentContext.DEVELOPMENT,
|
|
38
|
+
DeploymentContext.EDITABLE_INSTALL,
|
|
39
|
+
):
|
|
40
|
+
# Write logs to file instead of stderr to avoid hook errors
|
|
41
|
+
log_dir = Path.home() / ".claude-mpm"
|
|
42
|
+
log_dir.mkdir(parents=True, exist_ok=True)
|
|
43
|
+
log_file = log_dir / "hooks.log"
|
|
23
44
|
logging.basicConfig(
|
|
24
45
|
level=logging.INFO,
|
|
25
46
|
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
|
26
47
|
force=True, # Python 3.8+ - reconfigures root logger
|
|
27
|
-
|
|
48
|
+
filename=str(log_file),
|
|
28
49
|
)
|
|
29
50
|
except ImportError:
|
|
30
|
-
# Fallback: if unified_paths not available,
|
|
31
|
-
|
|
32
|
-
logging.
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
51
|
+
# Fallback: if unified_paths not available, check suppression before configuring
|
|
52
|
+
root_logger = logging.getLogger()
|
|
53
|
+
is_suppressed = root_logger.level > logging.CRITICAL
|
|
54
|
+
|
|
55
|
+
if not is_suppressed:
|
|
56
|
+
# Write logs to file instead of stderr to avoid hook errors
|
|
57
|
+
log_dir = Path.home() / ".claude-mpm"
|
|
58
|
+
log_dir.mkdir(parents=True, exist_ok=True)
|
|
59
|
+
log_file = log_dir / "hooks.log"
|
|
60
|
+
logging.basicConfig(
|
|
61
|
+
level=logging.INFO,
|
|
62
|
+
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
|
63
|
+
force=True,
|
|
64
|
+
filename=str(log_file),
|
|
65
|
+
)
|
|
38
66
|
from datetime import datetime, timezone
|
|
39
67
|
from typing import Optional
|
|
40
68
|
|
|
41
69
|
# Debug mode
|
|
42
|
-
DEBUG = os.environ.get("CLAUDE_MPM_HOOK_DEBUG", "
|
|
70
|
+
DEBUG = os.environ.get("CLAUDE_MPM_HOOK_DEBUG", "false").lower() == "true"
|
|
43
71
|
|
|
44
72
|
# Memory hooks integration
|
|
45
73
|
MEMORY_HOOKS_AVAILABLE = False
|
|
@@ -60,7 +88,7 @@ try:
|
|
|
60
88
|
except Exception as e:
|
|
61
89
|
# Catch all exceptions to prevent any import errors from breaking the handler
|
|
62
90
|
if DEBUG:
|
|
63
|
-
|
|
91
|
+
_log(f"Memory hooks not available: {e}")
|
|
64
92
|
MEMORY_HOOKS_AVAILABLE = False
|
|
65
93
|
|
|
66
94
|
|
|
@@ -94,10 +122,7 @@ class MemoryHookManager:
|
|
|
94
122
|
# Only initialize if memory system is enabled
|
|
95
123
|
if not config.get("memory.enabled", True):
|
|
96
124
|
if DEBUG:
|
|
97
|
-
|
|
98
|
-
"Memory system disabled - skipping hook initialization",
|
|
99
|
-
file=sys.stderr,
|
|
100
|
-
)
|
|
125
|
+
_log("Memory system disabled - skipping hook initialization")
|
|
101
126
|
return
|
|
102
127
|
|
|
103
128
|
# Initialize pre-delegation hook for memory injection
|
|
@@ -115,14 +140,11 @@ class MemoryHookManager:
|
|
|
115
140
|
hooks_info.append("pre-delegation")
|
|
116
141
|
if self.post_delegation_hook:
|
|
117
142
|
hooks_info.append("post-delegation")
|
|
118
|
-
|
|
119
|
-
f"✅ Memory hooks initialized: {', '.join(hooks_info)}",
|
|
120
|
-
file=sys.stderr,
|
|
121
|
-
)
|
|
143
|
+
_log(f"✅ Memory hooks initialized: {', '.join(hooks_info)}")
|
|
122
144
|
|
|
123
145
|
except Exception as e:
|
|
124
146
|
if DEBUG:
|
|
125
|
-
|
|
147
|
+
_log(f"❌ Failed to initialize memory hooks: {e}")
|
|
126
148
|
# Don't fail the entire handler - memory system is optional
|
|
127
149
|
|
|
128
150
|
def trigger_pre_delegation_hook(
|
|
@@ -171,14 +193,13 @@ class MemoryHookManager:
|
|
|
171
193
|
|
|
172
194
|
if DEBUG:
|
|
173
195
|
memory_size = len(memory_section.encode("utf-8"))
|
|
174
|
-
|
|
175
|
-
f"✅ Injected {memory_size} bytes of memory for agent '{agent_type}'"
|
|
176
|
-
file=sys.stderr,
|
|
196
|
+
_log(
|
|
197
|
+
f"✅ Injected {memory_size} bytes of memory for agent '{agent_type}'"
|
|
177
198
|
)
|
|
178
199
|
|
|
179
200
|
except Exception as e:
|
|
180
201
|
if DEBUG:
|
|
181
|
-
|
|
202
|
+
_log(f"❌ Memory pre-delegation hook failed: {e}")
|
|
182
203
|
# Don't fail the delegation - memory is optional
|
|
183
204
|
|
|
184
205
|
def trigger_post_delegation_hook(
|
|
@@ -238,12 +259,11 @@ class MemoryHookManager:
|
|
|
238
259
|
if result.success and result.metadata:
|
|
239
260
|
learnings_extracted = result.metadata.get("learnings_extracted", 0)
|
|
240
261
|
if learnings_extracted > 0 and DEBUG:
|
|
241
|
-
|
|
242
|
-
f"✅ Extracted {learnings_extracted} learnings for agent '{agent_type}'"
|
|
243
|
-
file=sys.stderr,
|
|
262
|
+
_log(
|
|
263
|
+
f"✅ Extracted {learnings_extracted} learnings for agent '{agent_type}'"
|
|
244
264
|
)
|
|
245
265
|
|
|
246
266
|
except Exception as e:
|
|
247
267
|
if DEBUG:
|
|
248
|
-
|
|
268
|
+
_log(f"❌ Memory post-delegation hook failed: {e}")
|
|
249
269
|
# Don't fail the delegation result - memory is optional
|