claude-mpm 5.0.9__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/__init__.py +4 -0
- claude_mpm/agents/BASE_AGENT.md +164 -0
- claude_mpm/agents/CLAUDE_MPM_OUTPUT_STYLE.md +115 -0
- claude_mpm/agents/CLAUDE_MPM_RESEARCH_OUTPUT_STYLE.md +413 -0
- claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +186 -0
- claude_mpm/agents/MEMORY.md +1 -1
- claude_mpm/agents/PM_INSTRUCTIONS.md +479 -616
- claude_mpm/agents/WORKFLOW.md +6 -253
- claude_mpm/agents/agent_loader.py +13 -44
- claude_mpm/agents/base_agent.json +1 -1
- claude_mpm/agents/frontmatter_validator.py +70 -2
- claude_mpm/agents/templates/circuit-breakers.md +457 -62
- claude_mpm/cli/__init__.py +5 -2
- claude_mpm/cli/__main__.py +4 -0
- claude_mpm/cli/chrome_devtools_installer.py +175 -0
- claude_mpm/cli/commands/agent_state_manager.py +18 -27
- claude_mpm/cli/commands/agents.py +177 -41
- claude_mpm/cli/commands/agents_reconcile.py +197 -0
- claude_mpm/cli/commands/auto_configure.py +723 -236
- claude_mpm/cli/commands/autotodos.py +566 -0
- claude_mpm/cli/commands/commander.py +216 -0
- claude_mpm/cli/commands/config.py +88 -2
- claude_mpm/cli/commands/configure.py +1874 -170
- claude_mpm/cli/commands/configure_agent_display.py +27 -6
- 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 +232 -46
- claude_mpm/cli/commands/mpm_init/knowledge_extractor.py +481 -0
- claude_mpm/cli/commands/mpm_init/prompts.py +280 -0
- claude_mpm/cli/commands/postmortem.py +1 -1
- claude_mpm/cli/commands/profile.py +276 -0
- claude_mpm/cli/commands/run.py +35 -3
- claude_mpm/cli/commands/skill_source.py +51 -2
- claude_mpm/cli/commands/skills.py +379 -204
- claude_mpm/cli/commands/summarize.py +413 -0
- claude_mpm/cli/executor.py +141 -19
- claude_mpm/cli/interactive/__init__.py +10 -0
- claude_mpm/cli/interactive/agent_wizard.py +115 -60
- claude_mpm/cli/interactive/questionary_styles.py +65 -0
- claude_mpm/cli/interactive/skill_selector.py +481 -0
- claude_mpm/cli/parsers/agents_parser.py +54 -9
- claude_mpm/cli/parsers/auto_configure_parser.py +13 -138
- claude_mpm/cli/parsers/base_parser.py +88 -1
- claude_mpm/cli/parsers/commander_parser.py +116 -0
- claude_mpm/cli/parsers/config_parser.py +153 -83
- claude_mpm/cli/parsers/profile_parser.py +147 -0
- 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 +1 -1
- claude_mpm/cli/startup.py +1017 -266
- 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 +36 -0
- claude_mpm/commands/mpm-doctor.md +16 -21
- claude_mpm/commands/mpm-help.md +12 -286
- claude_mpm/commands/mpm-init.md +88 -506
- claude_mpm/commands/mpm-monitor.md +22 -401
- claude_mpm/commands/mpm-organize.md +128 -0
- claude_mpm/commands/mpm-postmortem.md +13 -107
- claude_mpm/commands/mpm-session-resume.md +20 -363
- claude_mpm/commands/mpm-status.md +13 -69
- claude_mpm/commands/mpm-ticket-view.md +60 -495
- claude_mpm/commands/mpm-version.md +13 -107
- claude_mpm/commands/mpm.md +8 -0
- claude_mpm/config/agent_presets.py +8 -7
- claude_mpm/config/agent_sources.py +27 -0
- 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 +37 -26
- claude_mpm/core/config_constants.py +74 -9
- claude_mpm/core/constants.py +56 -12
- claude_mpm/core/framework/formatters/content_formatter.py +3 -13
- claude_mpm/core/framework/loaders/agent_loader.py +8 -5
- claude_mpm/core/framework/loaders/instruction_loader.py +52 -11
- claude_mpm/core/framework_loader.py +4 -2
- claude_mpm/core/hook_manager.py +51 -3
- claude_mpm/core/interactive_session.py +12 -11
- claude_mpm/core/logger.py +39 -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 +61 -0
- claude_mpm/core/output_style_manager.py +219 -44
- claude_mpm/core/shared/config_loader.py +3 -1
- claude_mpm/core/socketio_pool.py +16 -8
- claude_mpm/core/unified_agent_registry.py +134 -16
- claude_mpm/core/unified_config.py +76 -8
- claude_mpm/core/unified_paths.py +95 -90
- claude_mpm/dashboard/static/svelte-build/_app/env.js +1 -0
- 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/BSNlmTZj.js +1 -0
- 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/DR8nis88.js +2 -0
- 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/NqQ1dWOy.js +1 -0
- 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.RgBboRvH.js +1 -0
- 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 -0
- claude_mpm/dashboard/static/svelte-build/favicon.svg +7 -0
- claude_mpm/dashboard/static/svelte-build/index.html +36 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/fonts/generate_fonts.py +58 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_tfms.py +114 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_ttfs.py +122 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/format_json.py +28 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/parse_tfm.py +211 -0
- claude_mpm/experimental/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__/__init__.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/auto_pause_handler.py +485 -0
- claude_mpm/hooks/claude_hooks/correlation_manager.py +60 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +479 -128
- claude_mpm/hooks/claude_hooks/hook_handler.py +254 -83
- claude_mpm/hooks/claude_hooks/hook_wrapper.sh +6 -11
- claude_mpm/hooks/claude_hooks/installer.py +149 -18
- claude_mpm/hooks/claude_hooks/memory_integration.py +67 -19
- claude_mpm/hooks/claude_hooks/response_tracking.py +44 -62
- claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/connection_manager.py +69 -30
- 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/memory_integration_hook.py +46 -1
- claude_mpm/hooks/session_resume_hook.py +89 -1
- claude_mpm/hooks/templates/pre_tool_use_template.py +10 -2
- claude_mpm/init.py +276 -19
- claude_mpm/models/agent_definition.py +7 -0
- claude_mpm/models/git_repository.py +3 -3
- claude_mpm/scripts/claude-hook-handler.sh +87 -20
- claude_mpm/scripts/launch_monitor.py +93 -13
- claude_mpm/scripts/start_activity_logging.py +0 -0
- claude_mpm/services/agents/agent_builder.py +3 -3
- claude_mpm/services/agents/agent_recommendation_service.py +278 -0
- claude_mpm/services/agents/agent_review_service.py +280 -0
- claude_mpm/services/agents/agent_selection_service.py +2 -2
- claude_mpm/services/agents/cache_git_manager.py +7 -7
- claude_mpm/services/agents/deployment/agent_deployment.py +29 -7
- claude_mpm/services/agents/deployment/agent_discovery_service.py +6 -5
- claude_mpm/services/agents/deployment/agent_format_converter.py +25 -13
- claude_mpm/services/agents/deployment/agent_template_builder.py +42 -20
- claude_mpm/services/agents/deployment/agents_directory_resolver.py +2 -2
- 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 +348 -29
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +570 -68
- claude_mpm/services/agents/deployment/startup_reconciliation.py +138 -0
- claude_mpm/services/agents/git_source_manager.py +57 -4
- claude_mpm/services/agents/loading/base_agent_manager.py +1 -13
- claude_mpm/services/agents/loading/framework_agent_loader.py +75 -2
- claude_mpm/services/agents/recommender.py +5 -3
- claude_mpm/services/agents/single_tier_deployment_service.py +6 -6
- claude_mpm/services/agents/sources/git_source_sync_service.py +129 -11
- claude_mpm/services/agents/startup_sync.py +27 -4
- claude_mpm/services/agents/toolchain_detector.py +10 -6
- claude_mpm/services/analysis/__init__.py +11 -1
- claude_mpm/services/analysis/clone_detector.py +1030 -0
- 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 +81 -10
- claude_mpm/services/delegation_detector.py +175 -0
- claude_mpm/services/diagnostics/checks/agent_check.py +2 -2
- claude_mpm/services/diagnostics/checks/agent_sources_check.py +31 -1
- 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_bus/config.py +3 -1
- claude_mpm/services/event_log.py +325 -0
- claude_mpm/services/git/git_operations_service.py +101 -16
- 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.py +9 -2
- claude_mpm/services/monitor/daemon_manager.py +54 -7
- claude_mpm/services/monitor/management/lifecycle.py +15 -3
- claude_mpm/services/monitor/server.py +796 -30
- claude_mpm/services/pm_skills_deployer.py +884 -0
- claude_mpm/services/profile_manager.py +337 -0
- claude_mpm/services/project/project_organizer.py +4 -0
- claude_mpm/services/self_upgrade_service.py +120 -12
- claude_mpm/services/skills/__init__.py +3 -0
- claude_mpm/services/skills/git_skill_source_manager.py +303 -12
- claude_mpm/services/skills/selective_skill_deployer.py +869 -0
- claude_mpm/services/skills/skill_discovery_service.py +74 -4
- claude_mpm/services/skills/skill_to_agent_mapper.py +406 -0
- claude_mpm/services/skills_deployer.py +294 -55
- claude_mpm/services/socketio/dashboard_server.py +1 -0
- claude_mpm/services/socketio/event_normalizer.py +51 -6
- claude_mpm/services/socketio/handlers/hook.py +14 -7
- claude_mpm/services/socketio/server/core.py +386 -108
- claude_mpm/services/socketio/server/main.py +12 -4
- claude_mpm/services/version_control/git_operations.py +103 -0
- 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 +98 -3
- claude_mpm/templates/.pre-commit-config.yaml +112 -0
- claude_mpm/utils/agent_dependency_loader.py +115 -4
- claude_mpm/utils/agent_filters.py +17 -44
- claude_mpm/utils/gitignore.py +3 -0
- claude_mpm/utils/migration.py +4 -4
- claude_mpm/utils/robust_installer.py +86 -21
- claude_mpm-5.6.23.dist-info/METADATA +393 -0
- {claude_mpm-5.0.9.dist-info → claude_mpm-5.6.23.dist-info}/RECORD +508 -261
- claude_mpm-5.6.23.dist-info/entry_points.txt +5 -0
- claude_mpm-5.6.23.dist-info/licenses/LICENSE +94 -0
- claude_mpm-5.6.23.dist-info/licenses/LICENSE-FAQ.md +153 -0
- claude_mpm/agents/BASE_AGENT_TEMPLATE.md +0 -292
- claude_mpm/agents/BASE_DOCUMENTATION.md +0 -53
- claude_mpm/agents/BASE_OPS.md +0 -219
- claude_mpm/agents/BASE_PM.md +0 -480
- claude_mpm/agents/BASE_PROMPT_ENGINEER.md +0 -787
- claude_mpm/agents/BASE_QA.md +0 -167
- claude_mpm/agents/BASE_RESEARCH.md +0 -53
- claude_mpm/agents/OUTPUT_STYLE.md +0 -290
- claude_mpm/agents/PM_INSTRUCTIONS_TEACH.md +0 -1322
- claude_mpm/agents/base_agent_loader.py +0 -601
- claude_mpm/cli/commands/agents_detect.py +0 -380
- claude_mpm/cli/commands/agents_recommend.py +0 -309
- claude_mpm/cli/ticket_cli.py +0 -35
- claude_mpm/commands/mpm-agents-auto-configure.md +0 -278
- claude_mpm/commands/mpm-agents-detect.md +0 -177
- claude_mpm/commands/mpm-agents-list.md +0 -131
- claude_mpm/commands/mpm-agents-recommend.md +0 -223
- claude_mpm/commands/mpm-config-view.md +0 -150
- claude_mpm/commands/mpm-ticket-organize.md +0 -304
- claude_mpm/dashboard/analysis_runner.py +0 -455
- claude_mpm/dashboard/index.html +0 -13
- claude_mpm/dashboard/open_dashboard.py +0 -66
- claude_mpm/dashboard/static/css/activity.css +0 -1958
- claude_mpm/dashboard/static/css/connection-status.css +0 -370
- claude_mpm/dashboard/static/css/dashboard.css +0 -4701
- claude_mpm/dashboard/static/js/components/activity-tree.js +0 -1871
- claude_mpm/dashboard/static/js/components/agent-hierarchy.js +0 -777
- claude_mpm/dashboard/static/js/components/agent-inference.js +0 -956
- claude_mpm/dashboard/static/js/components/build-tracker.js +0 -333
- claude_mpm/dashboard/static/js/components/code-simple.js +0 -857
- claude_mpm/dashboard/static/js/components/connection-debug.js +0 -654
- claude_mpm/dashboard/static/js/components/diff-viewer.js +0 -891
- claude_mpm/dashboard/static/js/components/event-processor.js +0 -542
- claude_mpm/dashboard/static/js/components/event-viewer.js +0 -1155
- claude_mpm/dashboard/static/js/components/export-manager.js +0 -368
- claude_mpm/dashboard/static/js/components/file-change-tracker.js +0 -443
- claude_mpm/dashboard/static/js/components/file-change-viewer.js +0 -690
- claude_mpm/dashboard/static/js/components/file-tool-tracker.js +0 -724
- claude_mpm/dashboard/static/js/components/file-viewer.js +0 -580
- claude_mpm/dashboard/static/js/components/hud-library-loader.js +0 -211
- claude_mpm/dashboard/static/js/components/hud-manager.js +0 -671
- claude_mpm/dashboard/static/js/components/hud-visualizer.js +0 -1718
- claude_mpm/dashboard/static/js/components/module-viewer.js +0 -2764
- claude_mpm/dashboard/static/js/components/session-manager.js +0 -579
- claude_mpm/dashboard/static/js/components/socket-manager.js +0 -368
- claude_mpm/dashboard/static/js/components/ui-state-manager.js +0 -749
- claude_mpm/dashboard/static/js/components/unified-data-viewer.js +0 -1824
- claude_mpm/dashboard/static/js/components/working-directory.js +0 -920
- claude_mpm/dashboard/static/js/connection-manager.js +0 -536
- claude_mpm/dashboard/static/js/dashboard.js +0 -1914
- claude_mpm/dashboard/static/js/extension-error-handler.js +0 -164
- claude_mpm/dashboard/static/js/socket-client.js +0 -1474
- claude_mpm/dashboard/static/js/tab-isolation-fix.js +0 -185
- claude_mpm/dashboard/static/socket.io.min.js +0 -7
- claude_mpm/dashboard/static/socket.io.v4.8.1.backup.js +0 -7
- claude_mpm/dashboard/templates/code_simple.html +0 -153
- claude_mpm/dashboard/templates/index.html +0 -606
- claude_mpm/dashboard/test_dashboard.html +0 -372
- claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-313.pyc +0 -0
- claude_mpm/scripts/mcp_server.py +0 -75
- claude_mpm/scripts/mcp_wrapper.py +0 -39
- claude_mpm/services/mcp_gateway/__init__.py +0 -159
- claude_mpm/services/mcp_gateway/auto_configure.py +0 -369
- claude_mpm/services/mcp_gateway/config/__init__.py +0 -17
- claude_mpm/services/mcp_gateway/config/config_loader.py +0 -296
- claude_mpm/services/mcp_gateway/config/config_schema.py +0 -243
- claude_mpm/services/mcp_gateway/config/configuration.py +0 -429
- claude_mpm/services/mcp_gateway/core/__init__.py +0 -43
- claude_mpm/services/mcp_gateway/core/base.py +0 -312
- claude_mpm/services/mcp_gateway/core/exceptions.py +0 -253
- claude_mpm/services/mcp_gateway/core/interfaces.py +0 -443
- claude_mpm/services/mcp_gateway/core/process_pool.py +0 -977
- claude_mpm/services/mcp_gateway/core/singleton_manager.py +0 -315
- claude_mpm/services/mcp_gateway/core/startup_verification.py +0 -316
- claude_mpm/services/mcp_gateway/main.py +0 -589
- claude_mpm/services/mcp_gateway/registry/__init__.py +0 -12
- claude_mpm/services/mcp_gateway/registry/service_registry.py +0 -412
- claude_mpm/services/mcp_gateway/registry/tool_registry.py +0 -489
- claude_mpm/services/mcp_gateway/server/__init__.py +0 -15
- claude_mpm/services/mcp_gateway/server/mcp_gateway.py +0 -414
- claude_mpm/services/mcp_gateway/server/stdio_handler.py +0 -372
- claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -712
- claude_mpm/services/mcp_gateway/tools/__init__.py +0 -36
- claude_mpm/services/mcp_gateway/tools/base_adapter.py +0 -485
- claude_mpm/services/mcp_gateway/tools/document_summarizer.py +0 -789
- claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +0 -654
- claude_mpm/services/mcp_gateway/tools/health_check_tool.py +0 -456
- claude_mpm/services/mcp_gateway/tools/hello_world.py +0 -551
- claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +0 -555
- claude_mpm/services/mcp_gateway/utils/__init__.py +0 -14
- claude_mpm/services/mcp_gateway/utils/package_version_checker.py +0 -160
- claude_mpm/services/mcp_gateway/utils/update_preferences.py +0 -170
- claude_mpm-5.0.9.dist-info/METADATA +0 -1028
- claude_mpm-5.0.9.dist-info/entry_points.txt +0 -10
- claude_mpm-5.0.9.dist-info/licenses/LICENSE +0 -21
- {claude_mpm-5.0.9.dist-info → claude_mpm-5.6.23.dist-info}/WHEEL +0 -0
- {claude_mpm-5.0.9.dist-info → claude_mpm-5.6.23.dist-info}/top_level.txt +0 -0
|
@@ -22,7 +22,7 @@ import os
|
|
|
22
22
|
import re
|
|
23
23
|
import select
|
|
24
24
|
import signal
|
|
25
|
-
import subprocess
|
|
25
|
+
import subprocess # nosec B404
|
|
26
26
|
import sys
|
|
27
27
|
import threading
|
|
28
28
|
from datetime import datetime, timezone
|
|
@@ -31,6 +31,7 @@ from typing import Optional, Tuple
|
|
|
31
31
|
# Import extracted modules with fallback for direct execution
|
|
32
32
|
try:
|
|
33
33
|
# Try relative imports first (when imported as module)
|
|
34
|
+
from .auto_pause_handler import AutoPauseHandler
|
|
34
35
|
from .event_handlers import EventHandlers
|
|
35
36
|
from .memory_integration import MemoryHookManager
|
|
36
37
|
from .response_tracking import ResponseTrackingManager
|
|
@@ -47,6 +48,7 @@ except ImportError:
|
|
|
47
48
|
# Add parent directory to path
|
|
48
49
|
sys.path.insert(0, str(Path(__file__).parent))
|
|
49
50
|
|
|
51
|
+
from auto_pause_handler import AutoPauseHandler
|
|
50
52
|
from event_handlers import EventHandlers
|
|
51
53
|
from memory_integration import MemoryHookManager
|
|
52
54
|
from response_tracking import ResponseTrackingManager
|
|
@@ -60,14 +62,31 @@ except ImportError:
|
|
|
60
62
|
"""
|
|
61
63
|
Debug mode configuration for hook processing.
|
|
62
64
|
|
|
63
|
-
WHY
|
|
64
|
-
|
|
65
|
-
|
|
65
|
+
WHY disabled by default: Production users should see clean output without debug noise.
|
|
66
|
+
Hook errors appear less confusing when debug output is minimal.
|
|
67
|
+
Development and debugging can enable via CLAUDE_MPM_HOOK_DEBUG=true.
|
|
66
68
|
|
|
67
69
|
Performance Impact: Debug logging adds ~5-10% overhead but provides crucial
|
|
68
|
-
visibility into event flow, timing, and error conditions.
|
|
70
|
+
visibility into event flow, timing, and error conditions when enabled.
|
|
69
71
|
"""
|
|
70
|
-
DEBUG = os.environ.get("CLAUDE_MPM_HOOK_DEBUG", "
|
|
72
|
+
DEBUG = os.environ.get("CLAUDE_MPM_HOOK_DEBUG", "false").lower() == "true"
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _log(message: str) -> None:
|
|
76
|
+
"""Log message to file if DEBUG enabled. Never write to stderr.
|
|
77
|
+
|
|
78
|
+
WHY: Claude Code interprets ANY stderr output as a hook error.
|
|
79
|
+
Writing to stderr causes confusing "hook error" messages even for debug logs.
|
|
80
|
+
|
|
81
|
+
This helper ensures all debug output goes to a log file instead.
|
|
82
|
+
"""
|
|
83
|
+
if DEBUG:
|
|
84
|
+
try:
|
|
85
|
+
with open("/tmp/claude-mpm-hook.log", "a") as f: # nosec B108
|
|
86
|
+
f.write(f"[{datetime.now(timezone.utc).isoformat()}] {message}\n")
|
|
87
|
+
except Exception: # nosec B110 - intentional silent failure
|
|
88
|
+
pass # Never disrupt hook execution
|
|
89
|
+
|
|
71
90
|
|
|
72
91
|
"""
|
|
73
92
|
Conditional imports with graceful fallbacks for testing and modularity.
|
|
@@ -109,6 +128,8 @@ WHY version checking:
|
|
|
109
128
|
Security: Version checking prevents execution on incompatible environments.
|
|
110
129
|
"""
|
|
111
130
|
MIN_CLAUDE_VERSION = "1.0.92"
|
|
131
|
+
# Minimum version for user-invocable skills support
|
|
132
|
+
MIN_SKILLS_VERSION = "2.1.3"
|
|
112
133
|
|
|
113
134
|
|
|
114
135
|
def check_claude_version() -> Tuple[bool, Optional[str]]:
|
|
@@ -153,7 +174,7 @@ def check_claude_version() -> Tuple[bool, Optional[str]]:
|
|
|
153
174
|
"""
|
|
154
175
|
try:
|
|
155
176
|
# Try to detect Claude Code version
|
|
156
|
-
result = subprocess.run(
|
|
177
|
+
result = subprocess.run( # nosec B603 B607 - Safe: hardcoded claude CLI with --version flag, no user input
|
|
157
178
|
["claude", "--version"],
|
|
158
179
|
capture_output=True,
|
|
159
180
|
text=True,
|
|
@@ -184,22 +205,17 @@ def check_claude_version() -> Tuple[bool, Optional[str]]:
|
|
|
184
205
|
req_part = required[i] if i < len(required) else 0
|
|
185
206
|
|
|
186
207
|
if curr_part < req_part:
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
file=sys.stderr,
|
|
192
|
-
)
|
|
208
|
+
_log(
|
|
209
|
+
f"⚠️ Claude Code {version} does not support matcher-based hooks "
|
|
210
|
+
f"(requires {MIN_CLAUDE_VERSION}+). Hook monitoring disabled."
|
|
211
|
+
)
|
|
193
212
|
return False, version
|
|
194
213
|
if curr_part > req_part:
|
|
195
214
|
return True, version
|
|
196
215
|
|
|
197
216
|
return True, version
|
|
198
217
|
except Exception as e:
|
|
199
|
-
|
|
200
|
-
print(
|
|
201
|
-
f"Warning: Could not detect Claude Code version: {e}", file=sys.stderr
|
|
202
|
-
)
|
|
218
|
+
_log(f"Warning: Could not detect Claude Code version: {e}")
|
|
203
219
|
|
|
204
220
|
return False, None
|
|
205
221
|
|
|
@@ -230,8 +246,21 @@ class ClaudeHookHandler:
|
|
|
230
246
|
self.state_manager, self.response_tracking_manager, self.connection_manager
|
|
231
247
|
)
|
|
232
248
|
|
|
249
|
+
# Initialize auto-pause handler
|
|
250
|
+
try:
|
|
251
|
+
self.auto_pause_handler = AutoPauseHandler()
|
|
252
|
+
# Pass reference to ResponseTrackingManager so it can call auto_pause
|
|
253
|
+
if hasattr(self, "response_tracking_manager"):
|
|
254
|
+
self.response_tracking_manager.auto_pause_handler = (
|
|
255
|
+
self.auto_pause_handler
|
|
256
|
+
)
|
|
257
|
+
except Exception as e:
|
|
258
|
+
self.auto_pause_handler = None
|
|
259
|
+
_log(f"Auto-pause initialization failed: {e}")
|
|
260
|
+
|
|
233
261
|
# Backward compatibility properties for tests
|
|
234
|
-
|
|
262
|
+
# Note: HTTP-based connection manager doesn't use connection_pool
|
|
263
|
+
self.connection_pool = None # Deprecated: No longer needed with HTTP emission
|
|
235
264
|
|
|
236
265
|
# Expose state manager properties for backward compatibility
|
|
237
266
|
self.active_delegations = self.state_manager.active_delegations
|
|
@@ -260,8 +289,7 @@ class ClaudeHookHandler:
|
|
|
260
289
|
def timeout_handler(signum, frame):
|
|
261
290
|
"""Handle timeout by forcing exit."""
|
|
262
291
|
nonlocal _continue_sent
|
|
263
|
-
|
|
264
|
-
print(f"Hook handler timeout (pid: {os.getpid()})", file=sys.stderr)
|
|
292
|
+
_log(f"Hook handler timeout (pid: {os.getpid()})")
|
|
265
293
|
if not _continue_sent:
|
|
266
294
|
self._continue_execution()
|
|
267
295
|
_continue_sent = True
|
|
@@ -282,11 +310,9 @@ class ClaudeHookHandler:
|
|
|
282
310
|
|
|
283
311
|
# Check for duplicate events (same event within 100ms)
|
|
284
312
|
if self.duplicate_detector.is_duplicate(event):
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
file=sys.stderr,
|
|
289
|
-
)
|
|
313
|
+
_log(
|
|
314
|
+
f"[{datetime.now(timezone.utc).isoformat()}] Skipping duplicate event: {event.get('hook_event_name', 'unknown')} (PID: {os.getpid()})"
|
|
315
|
+
)
|
|
290
316
|
# Still need to output continue for this invocation
|
|
291
317
|
if not _continue_sent:
|
|
292
318
|
self._continue_execution()
|
|
@@ -294,21 +320,21 @@ class ClaudeHookHandler:
|
|
|
294
320
|
return
|
|
295
321
|
|
|
296
322
|
# Debug: Log that we're processing an event
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
file=sys.stderr,
|
|
302
|
-
)
|
|
323
|
+
hook_type = event.get("hook_event_name", "unknown")
|
|
324
|
+
_log(
|
|
325
|
+
f"\n[{datetime.now(timezone.utc).isoformat()}] Processing hook event: {hook_type} (PID: {os.getpid()})"
|
|
326
|
+
)
|
|
303
327
|
|
|
304
328
|
# Perform periodic cleanup if needed
|
|
305
329
|
if self.state_manager.increment_events_processed():
|
|
306
330
|
self.state_manager.cleanup_old_entries()
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
331
|
+
# Also cleanup old correlation files
|
|
332
|
+
from .correlation_manager import CorrelationManager
|
|
333
|
+
|
|
334
|
+
CorrelationManager.cleanup_old()
|
|
335
|
+
_log(
|
|
336
|
+
f"🧹 Performed cleanup after {self.state_manager.events_processed} events"
|
|
337
|
+
)
|
|
312
338
|
|
|
313
339
|
# Route event to appropriate handler
|
|
314
340
|
# Handlers can optionally return modified input for PreToolUse events
|
|
@@ -348,8 +374,7 @@ class ClaudeHookHandler:
|
|
|
348
374
|
ready, _, _ = select.select([sys.stdin], [], [], 1.0)
|
|
349
375
|
if not ready:
|
|
350
376
|
# No data available within timeout
|
|
351
|
-
|
|
352
|
-
print("No hook event data received within timeout", file=sys.stderr)
|
|
377
|
+
_log("No hook event data received within timeout")
|
|
353
378
|
return None
|
|
354
379
|
|
|
355
380
|
# Data is available, read it
|
|
@@ -360,21 +385,16 @@ class ClaudeHookHandler:
|
|
|
360
385
|
|
|
361
386
|
parsed = json.loads(event_data)
|
|
362
387
|
# Debug: Log the actual event format we receive
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
for key in ["hook_event_name", "event", "type", "event_type"]:
|
|
368
|
-
if key in parsed:
|
|
369
|
-
print(f" {key} = '{parsed[key]}'", file=sys.stderr)
|
|
388
|
+
_log(f"Received event with keys: {list(parsed.keys())}")
|
|
389
|
+
for key in ["hook_event_name", "event", "type", "event_type"]:
|
|
390
|
+
if key in parsed:
|
|
391
|
+
_log(f" {key} = '{parsed[key]}'")
|
|
370
392
|
return parsed
|
|
371
393
|
except (json.JSONDecodeError, ValueError) as e:
|
|
372
|
-
|
|
373
|
-
print(f"Failed to parse hook event: {e}", file=sys.stderr)
|
|
394
|
+
_log(f"Failed to parse hook event: {e}")
|
|
374
395
|
return None
|
|
375
396
|
except Exception as e:
|
|
376
|
-
|
|
377
|
-
print(f"Error reading hook event: {e}", file=sys.stderr)
|
|
397
|
+
_log(f"Error reading hook event: {e}")
|
|
378
398
|
return None
|
|
379
399
|
|
|
380
400
|
def _route_event(self, event: dict) -> Optional[dict]:
|
|
@@ -390,6 +410,8 @@ class ClaudeHookHandler:
|
|
|
390
410
|
Returns:
|
|
391
411
|
Modified input for PreToolUse events (v2.0.30+), None otherwise
|
|
392
412
|
"""
|
|
413
|
+
import time
|
|
414
|
+
|
|
393
415
|
# Try multiple field names for compatibility
|
|
394
416
|
hook_type = (
|
|
395
417
|
event.get("hook_event_name")
|
|
@@ -401,9 +423,9 @@ class ClaudeHookHandler:
|
|
|
401
423
|
)
|
|
402
424
|
|
|
403
425
|
# Log the actual event structure for debugging
|
|
404
|
-
if
|
|
405
|
-
|
|
406
|
-
|
|
426
|
+
if hook_type == "unknown":
|
|
427
|
+
_log(f"Unknown event format, keys: {list(event.keys())}")
|
|
428
|
+
_log(f"Event sample: {str(event)[:200]}")
|
|
407
429
|
|
|
408
430
|
# Map event types to handlers
|
|
409
431
|
event_handlers = {
|
|
@@ -413,21 +435,47 @@ class ClaudeHookHandler:
|
|
|
413
435
|
"Notification": self.event_handlers.handle_notification_fast,
|
|
414
436
|
"Stop": self.event_handlers.handle_stop_fast,
|
|
415
437
|
"SubagentStop": self.event_handlers.handle_subagent_stop_fast,
|
|
438
|
+
"SubagentStart": self.event_handlers.handle_subagent_start_fast,
|
|
439
|
+
"SessionStart": self.event_handlers.handle_session_start_fast,
|
|
416
440
|
"AssistantResponse": self.event_handlers.handle_assistant_response,
|
|
417
441
|
}
|
|
418
442
|
|
|
419
443
|
# Call appropriate handler if exists
|
|
420
444
|
handler = event_handlers.get(hook_type)
|
|
421
445
|
if handler:
|
|
446
|
+
# Track execution timing for hook emission
|
|
447
|
+
start_time = time.time()
|
|
448
|
+
success = False
|
|
449
|
+
error_message = None
|
|
450
|
+
result = None
|
|
451
|
+
|
|
422
452
|
try:
|
|
423
453
|
# Handlers can optionally return modified input
|
|
424
454
|
result = handler(event)
|
|
455
|
+
success = True
|
|
425
456
|
# Only PreToolUse handlers should return modified input
|
|
426
457
|
if hook_type == "PreToolUse" and result is not None:
|
|
427
|
-
|
|
458
|
+
return_value = result
|
|
459
|
+
else:
|
|
460
|
+
return_value = None
|
|
428
461
|
except Exception as e:
|
|
429
|
-
|
|
430
|
-
|
|
462
|
+
error_message = str(e)
|
|
463
|
+
return_value = None
|
|
464
|
+
_log(f"Error handling {hook_type}: {e}")
|
|
465
|
+
finally:
|
|
466
|
+
# Calculate duration
|
|
467
|
+
duration_ms = int((time.time() - start_time) * 1000)
|
|
468
|
+
|
|
469
|
+
# Emit hook execution event
|
|
470
|
+
self._emit_hook_execution_event(
|
|
471
|
+
hook_type=hook_type,
|
|
472
|
+
event=event,
|
|
473
|
+
success=success,
|
|
474
|
+
duration_ms=duration_ms,
|
|
475
|
+
error_message=error_message,
|
|
476
|
+
)
|
|
477
|
+
|
|
478
|
+
return return_value
|
|
431
479
|
|
|
432
480
|
return None
|
|
433
481
|
|
|
@@ -447,9 +495,12 @@ class ClaudeHookHandler:
|
|
|
447
495
|
"""
|
|
448
496
|
if modified_input is not None:
|
|
449
497
|
# Claude Code v2.0.30+ supports modifying PreToolUse tool inputs
|
|
450
|
-
print(
|
|
498
|
+
print(
|
|
499
|
+
json.dumps({"action": "continue", "tool_input": modified_input}),
|
|
500
|
+
flush=True,
|
|
501
|
+
)
|
|
451
502
|
else:
|
|
452
|
-
print(json.dumps({"action": "continue"}))
|
|
503
|
+
print(json.dumps({"action": "continue"}), flush=True)
|
|
453
504
|
|
|
454
505
|
# Delegation methods for compatibility with event_handlers
|
|
455
506
|
def _track_delegation(self, session_id: str, agent_type: str, request_data=None):
|
|
@@ -472,14 +523,142 @@ class ClaudeHookHandler:
|
|
|
472
523
|
"""Generate event key through duplicate detector (backward compatibility)."""
|
|
473
524
|
return self.duplicate_detector.generate_event_key(event)
|
|
474
525
|
|
|
526
|
+
def _emit_hook_execution_event(
|
|
527
|
+
self,
|
|
528
|
+
hook_type: str,
|
|
529
|
+
event: dict,
|
|
530
|
+
success: bool,
|
|
531
|
+
duration_ms: int,
|
|
532
|
+
error_message: Optional[str] = None,
|
|
533
|
+
):
|
|
534
|
+
"""Emit a structured JSON event for hook execution.
|
|
535
|
+
|
|
536
|
+
This emits a normalized event following the claude_event schema to provide
|
|
537
|
+
visibility into hook processing, timing, and success/failure status.
|
|
538
|
+
|
|
539
|
+
Args:
|
|
540
|
+
hook_type: The type of hook that executed (e.g., "UserPromptSubmit", "PreToolUse")
|
|
541
|
+
event: The original hook event data
|
|
542
|
+
success: Whether the hook executed successfully
|
|
543
|
+
duration_ms: How long the hook took to execute in milliseconds
|
|
544
|
+
error_message: Optional error message if the hook failed
|
|
545
|
+
"""
|
|
546
|
+
# Generate a human-readable summary based on hook type
|
|
547
|
+
summary = self._generate_hook_summary(hook_type, event, success)
|
|
548
|
+
|
|
549
|
+
# Extract common fields
|
|
550
|
+
session_id = event.get("session_id", "")
|
|
551
|
+
working_dir = event.get("cwd", "")
|
|
552
|
+
|
|
553
|
+
# Build hook execution data
|
|
554
|
+
hook_data = {
|
|
555
|
+
"hook_name": hook_type,
|
|
556
|
+
"hook_type": hook_type, # Actual hook type (PreToolUse, UserPromptSubmit, etc.)
|
|
557
|
+
"hook_event_type": hook_type, # Additional field for clarity
|
|
558
|
+
"session_id": session_id,
|
|
559
|
+
"working_directory": working_dir,
|
|
560
|
+
"success": success,
|
|
561
|
+
"duration_ms": duration_ms,
|
|
562
|
+
"result_summary": summary,
|
|
563
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
564
|
+
"source": "claude_hook_handler", # Explicit source identification
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
# Add error information if present
|
|
568
|
+
if error_message:
|
|
569
|
+
hook_data["error_message"] = error_message
|
|
570
|
+
|
|
571
|
+
# Add hook-specific context
|
|
572
|
+
if hook_type == "PreToolUse":
|
|
573
|
+
hook_data["tool_name"] = event.get("tool_name", "")
|
|
574
|
+
elif hook_type == "PostToolUse":
|
|
575
|
+
hook_data["tool_name"] = event.get("tool_name", "")
|
|
576
|
+
hook_data["exit_code"] = event.get("exit_code", 0)
|
|
577
|
+
elif hook_type == "UserPromptSubmit":
|
|
578
|
+
prompt = event.get("prompt", "")
|
|
579
|
+
hook_data["prompt_preview"] = prompt[:100] if len(prompt) > 100 else prompt
|
|
580
|
+
hook_data["prompt_length"] = len(prompt)
|
|
581
|
+
elif hook_type == "SubagentStop":
|
|
582
|
+
hook_data["agent_type"] = event.get("agent_type", "unknown")
|
|
583
|
+
hook_data["reason"] = event.get("reason", "unknown")
|
|
584
|
+
|
|
585
|
+
# Emit through connection manager with proper structure
|
|
586
|
+
# This uses the existing event infrastructure
|
|
587
|
+
self._emit_socketio_event("", "hook_execution", hook_data)
|
|
588
|
+
|
|
589
|
+
_log(
|
|
590
|
+
f"📊 Hook execution event: {hook_type} - {duration_ms}ms - {'✅' if success else '❌'}"
|
|
591
|
+
)
|
|
592
|
+
|
|
593
|
+
def _generate_hook_summary(self, hook_type: str, event: dict, success: bool) -> str:
|
|
594
|
+
"""Generate a human-readable summary of what the hook did.
|
|
595
|
+
|
|
596
|
+
Args:
|
|
597
|
+
hook_type: The type of hook
|
|
598
|
+
event: The hook event data
|
|
599
|
+
success: Whether the hook executed successfully
|
|
600
|
+
|
|
601
|
+
Returns:
|
|
602
|
+
A brief description of what happened
|
|
603
|
+
"""
|
|
604
|
+
if not success:
|
|
605
|
+
return f"Hook {hook_type} failed during processing"
|
|
606
|
+
|
|
607
|
+
# Generate hook-specific summaries
|
|
608
|
+
if hook_type == "UserPromptSubmit":
|
|
609
|
+
prompt = event.get("prompt", "")
|
|
610
|
+
if prompt.startswith("/"):
|
|
611
|
+
return f"Processed command: {prompt.split()[0]}"
|
|
612
|
+
return f"Processed user prompt ({len(prompt)} chars)"
|
|
613
|
+
|
|
614
|
+
if hook_type == "PreToolUse":
|
|
615
|
+
tool_name = event.get("tool_name", "unknown")
|
|
616
|
+
return f"Pre-processing tool call: {tool_name}"
|
|
617
|
+
|
|
618
|
+
if hook_type == "PostToolUse":
|
|
619
|
+
tool_name = event.get("tool_name", "unknown")
|
|
620
|
+
exit_code = event.get("exit_code", 0)
|
|
621
|
+
status = "success" if exit_code == 0 else "failed"
|
|
622
|
+
return f"Completed tool call: {tool_name} ({status})"
|
|
623
|
+
|
|
624
|
+
if hook_type == "SubagentStop":
|
|
625
|
+
agent_type = event.get("agent_type", "unknown")
|
|
626
|
+
reason = event.get("reason", "unknown")
|
|
627
|
+
return f"Subagent {agent_type} stopped: {reason}"
|
|
628
|
+
|
|
629
|
+
if hook_type == "SessionStart":
|
|
630
|
+
return "New session started"
|
|
631
|
+
|
|
632
|
+
if hook_type == "Stop":
|
|
633
|
+
reason = event.get("reason", "unknown")
|
|
634
|
+
return f"Session stopped: {reason}"
|
|
635
|
+
|
|
636
|
+
if hook_type == "Notification":
|
|
637
|
+
notification_type = event.get("notification_type", "unknown")
|
|
638
|
+
return f"Notification received: {notification_type}"
|
|
639
|
+
|
|
640
|
+
if hook_type == "AssistantResponse":
|
|
641
|
+
response_len = len(event.get("response", ""))
|
|
642
|
+
return f"Assistant response generated ({response_len} chars)"
|
|
643
|
+
|
|
644
|
+
# Default summary
|
|
645
|
+
return f"Hook {hook_type} processed successfully"
|
|
646
|
+
|
|
475
647
|
def __del__(self):
|
|
476
648
|
"""Cleanup on handler destruction."""
|
|
649
|
+
# Finalize any active auto-pause session
|
|
650
|
+
if hasattr(self, "auto_pause_handler") and self.auto_pause_handler:
|
|
651
|
+
try:
|
|
652
|
+
self.auto_pause_handler.on_session_end()
|
|
653
|
+
except Exception:
|
|
654
|
+
pass # nosec B110 - Intentionally ignore cleanup errors during handler destruction
|
|
655
|
+
|
|
477
656
|
# Clean up connection manager if it exists
|
|
478
657
|
if hasattr(self, "connection_manager") and self.connection_manager:
|
|
479
658
|
try:
|
|
480
659
|
self.connection_manager.cleanup()
|
|
481
660
|
except Exception:
|
|
482
|
-
pass #
|
|
661
|
+
pass # nosec B110 - Intentionally ignore cleanup errors during handler destruction
|
|
483
662
|
|
|
484
663
|
|
|
485
664
|
def main():
|
|
@@ -492,25 +671,18 @@ def main():
|
|
|
492
671
|
if not is_compatible:
|
|
493
672
|
# Version incompatible - just continue without processing
|
|
494
673
|
# This prevents errors on older Claude Code versions
|
|
495
|
-
if
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
file=sys.stderr,
|
|
499
|
-
)
|
|
500
|
-
print(json.dumps({"action": "continue"}))
|
|
674
|
+
if version:
|
|
675
|
+
_log(f"Skipping hook processing due to version incompatibility ({version})")
|
|
676
|
+
print(json.dumps({"action": "continue"}), flush=True)
|
|
501
677
|
sys.exit(0)
|
|
502
678
|
|
|
503
679
|
def cleanup_handler(signum=None, frame=None):
|
|
504
680
|
"""Cleanup handler for signals and exit."""
|
|
505
681
|
nonlocal _continue_printed
|
|
506
|
-
|
|
507
|
-
print(
|
|
508
|
-
f"Hook handler cleanup (pid: {os.getpid()}, signal: {signum})",
|
|
509
|
-
file=sys.stderr,
|
|
510
|
-
)
|
|
682
|
+
_log(f"Hook handler cleanup (pid: {os.getpid()}, signal: {signum})")
|
|
511
683
|
# Only output continue if we haven't already (i.e., if interrupted by signal)
|
|
512
684
|
if signum is not None and not _continue_printed:
|
|
513
|
-
print(json.dumps({"action": "continue"}))
|
|
685
|
+
print(json.dumps({"action": "continue"}), flush=True)
|
|
514
686
|
_continue_printed = True
|
|
515
687
|
sys.exit(0)
|
|
516
688
|
|
|
@@ -524,15 +696,10 @@ def main():
|
|
|
524
696
|
with _handler_lock:
|
|
525
697
|
if _global_handler is None:
|
|
526
698
|
_global_handler = ClaudeHookHandler()
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
)
|
|
532
|
-
elif DEBUG:
|
|
533
|
-
print(
|
|
534
|
-
f"♻️ Reusing existing ClaudeHookHandler singleton (pid: {os.getpid()})",
|
|
535
|
-
file=sys.stderr,
|
|
699
|
+
_log(f"✅ Created new ClaudeHookHandler singleton (pid: {os.getpid()})")
|
|
700
|
+
else:
|
|
701
|
+
_log(
|
|
702
|
+
f"♻️ Reusing existing ClaudeHookHandler singleton (pid: {os.getpid()})"
|
|
536
703
|
)
|
|
537
704
|
|
|
538
705
|
handler = _global_handler
|
|
@@ -548,13 +715,17 @@ def main():
|
|
|
548
715
|
except Exception as e:
|
|
549
716
|
# Only output continue if not already printed
|
|
550
717
|
if not _continue_printed:
|
|
551
|
-
print(json.dumps({"action": "continue"}))
|
|
718
|
+
print(json.dumps({"action": "continue"}), flush=True)
|
|
552
719
|
_continue_printed = True
|
|
553
720
|
# Log error for debugging
|
|
554
|
-
|
|
555
|
-
print(f"Hook handler error: {e}", file=sys.stderr)
|
|
721
|
+
_log(f"Hook handler error: {e}")
|
|
556
722
|
sys.exit(0) # Exit cleanly even on error
|
|
557
723
|
|
|
558
724
|
|
|
559
725
|
if __name__ == "__main__":
|
|
560
|
-
|
|
726
|
+
try:
|
|
727
|
+
main()
|
|
728
|
+
except Exception:
|
|
729
|
+
# Catastrophic failure (import error, etc.) - always output valid JSON
|
|
730
|
+
print(json.dumps({"action": "continue"}), flush=True)
|
|
731
|
+
sys.exit(0)
|
|
@@ -48,15 +48,10 @@ echo "[$(date -u +%Y-%m-%dT%H:%M:%S.%3NZ)] PYTHONPATH: $PYTHONPATH" >> /tmp/hook
|
|
|
48
48
|
echo "[$(date -u +%Y-%m-%dT%H:%M:%S.%3NZ)] Running: $PYTHON_CMD -m claude_mpm.hooks.claude_hooks.hook_handler" >> /tmp/hook-wrapper.log
|
|
49
49
|
echo "[$(date -u +%Y-%m-%dT%H:%M:%S.%3NZ)] SOCKETIO_PORT: $CLAUDE_MPM_SOCKETIO_PORT" >> /tmp/hook-wrapper.log
|
|
50
50
|
|
|
51
|
-
# Run the Python hook handler as a module
|
|
52
|
-
#
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
echo '{"action": "continue"}'
|
|
56
|
-
# Log the error for debugging
|
|
57
|
-
echo "[$(date -u +%Y-%m-%dT%H:%M:%S.%3NZ)] Hook handler failed, see /tmp/hook-error.log" >> /tmp/hook-wrapper.log
|
|
58
|
-
exit 0
|
|
59
|
-
fi
|
|
51
|
+
# Run the Python hook handler as a module
|
|
52
|
+
# Python handler is responsible for ALL stdout output (including error fallback)
|
|
53
|
+
# Redirect stderr to log file for debugging
|
|
54
|
+
"$PYTHON_CMD" -m claude_mpm.hooks.claude_hooks.hook_handler "$@" 2>/tmp/hook-error.log
|
|
60
55
|
|
|
61
|
-
#
|
|
62
|
-
exit
|
|
56
|
+
# Exit with Python's exit code (should always be 0)
|
|
57
|
+
exit $?
|