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
|
@@ -7,12 +7,21 @@ Claude Code hook events.
|
|
|
7
7
|
|
|
8
8
|
import os
|
|
9
9
|
import re
|
|
10
|
-
import subprocess
|
|
11
|
-
import
|
|
10
|
+
import subprocess # nosec B404 - subprocess used for safe claude CLI version checking only
|
|
11
|
+
import uuid
|
|
12
12
|
from datetime import datetime, timezone
|
|
13
13
|
from pathlib import Path
|
|
14
14
|
from typing import Optional
|
|
15
15
|
|
|
16
|
+
# Import _log helper to avoid stderr writes (which cause hook errors)
|
|
17
|
+
try:
|
|
18
|
+
from .hook_handler import _log
|
|
19
|
+
except ImportError:
|
|
20
|
+
# Fallback for direct execution
|
|
21
|
+
def _log(message: str) -> None:
|
|
22
|
+
"""Fallback logger when hook_handler not available."""
|
|
23
|
+
|
|
24
|
+
|
|
16
25
|
# Import tool analysis with fallback for direct execution
|
|
17
26
|
try:
|
|
18
27
|
# Try relative import first (when imported as module)
|
|
@@ -33,8 +42,8 @@ except ImportError:
|
|
|
33
42
|
extract_tool_results,
|
|
34
43
|
)
|
|
35
44
|
|
|
36
|
-
# Debug mode
|
|
37
|
-
DEBUG = os.environ.get("CLAUDE_MPM_HOOK_DEBUG", "
|
|
45
|
+
# Debug mode - MUST match hook_handler.py default (false) to prevent stderr writes
|
|
46
|
+
DEBUG = os.environ.get("CLAUDE_MPM_HOOK_DEBUG", "false").lower() == "true"
|
|
38
47
|
|
|
39
48
|
# Import constants for configuration
|
|
40
49
|
try:
|
|
@@ -94,22 +103,37 @@ class EventHandlers:
|
|
|
94
103
|
}
|
|
95
104
|
|
|
96
105
|
# Store prompt for comprehensive response tracking if enabled
|
|
97
|
-
|
|
98
|
-
self.hook_handler
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
"
|
|
107
|
-
|
|
106
|
+
try:
|
|
107
|
+
rtm = getattr(self.hook_handler, "response_tracking_manager", None)
|
|
108
|
+
if (
|
|
109
|
+
rtm
|
|
110
|
+
and getattr(rtm, "response_tracking_enabled", False)
|
|
111
|
+
and getattr(rtm, "track_all_interactions", False)
|
|
112
|
+
):
|
|
113
|
+
session_id = event.get("session_id", "")
|
|
114
|
+
if session_id:
|
|
115
|
+
pending_prompts = getattr(self.hook_handler, "pending_prompts", {})
|
|
116
|
+
pending_prompts[session_id] = {
|
|
117
|
+
"prompt": prompt,
|
|
118
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
119
|
+
"working_directory": working_dir,
|
|
120
|
+
}
|
|
121
|
+
if DEBUG:
|
|
122
|
+
_log(
|
|
123
|
+
f"Stored prompt for comprehensive tracking: session {session_id[:8]}..."
|
|
124
|
+
)
|
|
125
|
+
except Exception: # nosec B110
|
|
126
|
+
# Response tracking is optional - silently continue if it fails
|
|
127
|
+
pass
|
|
128
|
+
|
|
129
|
+
# Record user message for auto-pause if active
|
|
130
|
+
auto_pause = getattr(self.hook_handler, "auto_pause_handler", None)
|
|
131
|
+
if auto_pause and auto_pause.is_pause_active():
|
|
132
|
+
try:
|
|
133
|
+
auto_pause.on_user_message(prompt)
|
|
134
|
+
except Exception as e:
|
|
108
135
|
if DEBUG:
|
|
109
|
-
|
|
110
|
-
f"Stored prompt for comprehensive tracking: session {session_id[:8]}...",
|
|
111
|
-
file=sys.stderr,
|
|
112
|
-
)
|
|
136
|
+
_log(f"Auto-pause user message recording error: {e}")
|
|
113
137
|
|
|
114
138
|
# Emit normalized event (namespace no longer needed with normalized events)
|
|
115
139
|
self.hook_handler._emit_socketio_event("", "user_prompt", prompt_data)
|
|
@@ -125,15 +149,15 @@ class EventHandlers:
|
|
|
125
149
|
# Enhanced debug logging for session correlation
|
|
126
150
|
session_id = event.get("session_id", "")
|
|
127
151
|
if DEBUG:
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
file=sys.stderr,
|
|
131
|
-
)
|
|
132
|
-
print(f" - event keys: {list(event.keys())}", file=sys.stderr)
|
|
152
|
+
_log(f" - session_id: {session_id[:16] if session_id else 'None'}...")
|
|
153
|
+
_log(f" - event keys: {list(event.keys())}")
|
|
133
154
|
|
|
134
155
|
tool_name = event.get("tool_name", "")
|
|
135
156
|
tool_input = event.get("tool_input", {})
|
|
136
157
|
|
|
158
|
+
# Generate unique tool call ID for correlation with post_tool event
|
|
159
|
+
tool_call_id = str(uuid.uuid4())
|
|
160
|
+
|
|
137
161
|
# Extract key parameters based on tool type
|
|
138
162
|
tool_params = extract_tool_parameters(tool_name, tool_input)
|
|
139
163
|
|
|
@@ -144,6 +168,8 @@ class EventHandlers:
|
|
|
144
168
|
working_dir = event.get("cwd", "")
|
|
145
169
|
git_branch = self._get_git_branch(working_dir) if working_dir else "Unknown"
|
|
146
170
|
|
|
171
|
+
timestamp = datetime.now(timezone.utc).isoformat()
|
|
172
|
+
|
|
147
173
|
pre_tool_data = {
|
|
148
174
|
"tool_name": tool_name,
|
|
149
175
|
"operation_type": operation_type,
|
|
@@ -151,21 +177,57 @@ class EventHandlers:
|
|
|
151
177
|
"session_id": event.get("session_id", ""),
|
|
152
178
|
"working_directory": working_dir,
|
|
153
179
|
"git_branch": git_branch,
|
|
154
|
-
"timestamp":
|
|
180
|
+
"timestamp": timestamp,
|
|
155
181
|
"parameter_count": len(tool_input) if isinstance(tool_input, dict) else 0,
|
|
156
182
|
"is_file_operation": tool_name
|
|
157
183
|
in ["Write", "Edit", "MultiEdit", "Read", "LS", "Glob"],
|
|
158
184
|
"is_execution": tool_name in ["Bash", "NotebookEdit"],
|
|
159
185
|
"is_delegation": tool_name == "Task",
|
|
160
186
|
"security_risk": assess_security_risk(tool_name, tool_input),
|
|
187
|
+
"correlation_id": tool_call_id, # Add correlation_id for pre/post correlation
|
|
161
188
|
}
|
|
162
189
|
|
|
190
|
+
# Store tool_call_id using CorrelationManager for cross-process retrieval
|
|
191
|
+
if session_id:
|
|
192
|
+
from .correlation_manager import CorrelationManager
|
|
193
|
+
|
|
194
|
+
CorrelationManager.store(session_id, tool_call_id, tool_name)
|
|
195
|
+
if DEBUG:
|
|
196
|
+
_log(
|
|
197
|
+
f" - Generated tool_call_id: {tool_call_id[:8]}... for session {session_id[:8]}..."
|
|
198
|
+
)
|
|
199
|
+
|
|
163
200
|
# Add delegation-specific data if this is a Task tool
|
|
164
201
|
if tool_name == "Task" and isinstance(tool_input, dict):
|
|
165
202
|
self._handle_task_delegation(tool_input, pre_tool_data, session_id)
|
|
166
203
|
|
|
204
|
+
# Record tool call for auto-pause if active
|
|
205
|
+
auto_pause = getattr(self.hook_handler, "auto_pause_handler", None)
|
|
206
|
+
if auto_pause and auto_pause.is_pause_active():
|
|
207
|
+
try:
|
|
208
|
+
auto_pause.on_tool_call(tool_name, tool_input)
|
|
209
|
+
except Exception as e:
|
|
210
|
+
if DEBUG:
|
|
211
|
+
_log(f"Auto-pause tool recording error: {e}")
|
|
212
|
+
|
|
167
213
|
self.hook_handler._emit_socketio_event("", "pre_tool", pre_tool_data)
|
|
168
214
|
|
|
215
|
+
# Handle TodoWrite specially - emit dedicated todo_updated event
|
|
216
|
+
# WHY: Frontend expects todo_updated events for dashboard display
|
|
217
|
+
# The broadcaster.todo_updated() method exists but was never called
|
|
218
|
+
if tool_name == "TodoWrite" and tool_params.get("todos"):
|
|
219
|
+
todo_data = {
|
|
220
|
+
"todos": tool_params["todos"],
|
|
221
|
+
"total_count": len(tool_params["todos"]),
|
|
222
|
+
"session_id": session_id,
|
|
223
|
+
"timestamp": timestamp,
|
|
224
|
+
}
|
|
225
|
+
self.hook_handler._emit_socketio_event("", "todo_updated", todo_data)
|
|
226
|
+
if DEBUG:
|
|
227
|
+
_log(
|
|
228
|
+
f" - Emitted todo_updated event with {len(tool_params['todos'])} todos for session {session_id[:8]}..."
|
|
229
|
+
)
|
|
230
|
+
|
|
169
231
|
def _handle_task_delegation(
|
|
170
232
|
self, tool_input: dict, pre_tool_data: dict, session_id: str
|
|
171
233
|
):
|
|
@@ -204,12 +266,9 @@ class EventHandlers:
|
|
|
204
266
|
|
|
205
267
|
# Track this delegation for SubagentStop correlation and response tracking
|
|
206
268
|
if DEBUG:
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
)
|
|
211
|
-
print(f" - agent_type: {agent_type}", file=sys.stderr)
|
|
212
|
-
print(f" - raw_agent_type: {raw_agent_type}", file=sys.stderr)
|
|
269
|
+
_log(f" - session_id: {session_id[:16] if session_id else 'None'}...")
|
|
270
|
+
_log(f" - agent_type: {agent_type}")
|
|
271
|
+
_log(f" - raw_agent_type: {raw_agent_type}")
|
|
213
272
|
|
|
214
273
|
if session_id and agent_type != "unknown":
|
|
215
274
|
# Prepare request data for response tracking correlation
|
|
@@ -221,27 +280,27 @@ class EventHandlers:
|
|
|
221
280
|
self.hook_handler._track_delegation(session_id, agent_type, request_data)
|
|
222
281
|
|
|
223
282
|
if DEBUG:
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
)
|
|
229
|
-
print(
|
|
230
|
-
f" - delegation_requests size: {len(self.hook_handler.delegation_requests)}",
|
|
231
|
-
file=sys.stderr,
|
|
283
|
+
_log(" - Delegation tracked successfully")
|
|
284
|
+
_log(f" - Request data keys: {list(request_data.keys())}")
|
|
285
|
+
delegation_requests = getattr(
|
|
286
|
+
self.hook_handler, "delegation_requests", {}
|
|
232
287
|
)
|
|
288
|
+
_log(f" - delegation_requests size: {len(delegation_requests)}")
|
|
233
289
|
|
|
234
290
|
# Log important delegations for debugging
|
|
235
291
|
if DEBUG or agent_type in ["research", "engineer", "qa", "documentation"]:
|
|
236
|
-
|
|
237
|
-
f"Hook handler: Task delegation started - agent: '{agent_type}', session: '{session_id}'"
|
|
238
|
-
file=sys.stderr,
|
|
292
|
+
_log(
|
|
293
|
+
f"Hook handler: Task delegation started - agent: '{agent_type}', session: '{session_id}'"
|
|
239
294
|
)
|
|
240
295
|
|
|
241
296
|
# Trigger memory pre-delegation hook
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
297
|
+
try:
|
|
298
|
+
mhm = getattr(self.hook_handler, "memory_hook_manager", None)
|
|
299
|
+
if mhm and hasattr(mhm, "trigger_pre_delegation_hook"):
|
|
300
|
+
mhm.trigger_pre_delegation_hook(agent_type, tool_input, session_id)
|
|
301
|
+
except Exception: # nosec B110
|
|
302
|
+
# Memory hooks are optional
|
|
303
|
+
pass
|
|
245
304
|
|
|
246
305
|
# Emit a subagent_start event for better tracking
|
|
247
306
|
subagent_start_data = {
|
|
@@ -301,10 +360,10 @@ class EventHandlers:
|
|
|
301
360
|
)
|
|
302
361
|
|
|
303
362
|
if DEBUG:
|
|
304
|
-
|
|
363
|
+
_log(f" - Agent prompt logged for {agent_type}")
|
|
305
364
|
except Exception as e:
|
|
306
365
|
if DEBUG:
|
|
307
|
-
|
|
366
|
+
_log(f" - Could not log agent prompt: {e}")
|
|
308
367
|
|
|
309
368
|
def _get_git_branch(self, working_dir: Optional[str] = None) -> str:
|
|
310
369
|
"""Get git branch for the given directory with caching."""
|
|
@@ -332,7 +391,7 @@ class EventHandlers:
|
|
|
332
391
|
os.chdir(working_dir)
|
|
333
392
|
|
|
334
393
|
# Run git command to get current branch
|
|
335
|
-
result = subprocess.run(
|
|
394
|
+
result = subprocess.run( # nosec B603 B607
|
|
336
395
|
["git", "branch", "--show-current"],
|
|
337
396
|
capture_output=True,
|
|
338
397
|
text=True,
|
|
@@ -375,6 +434,7 @@ class EventHandlers:
|
|
|
375
434
|
"""
|
|
376
435
|
tool_name = event.get("tool_name", "")
|
|
377
436
|
exit_code = event.get("exit_code", 0)
|
|
437
|
+
session_id = event.get("session_id", "")
|
|
378
438
|
|
|
379
439
|
# Extract result data
|
|
380
440
|
result_data = extract_tool_results(event)
|
|
@@ -386,6 +446,15 @@ class EventHandlers:
|
|
|
386
446
|
working_dir = event.get("cwd", "")
|
|
387
447
|
git_branch = self._get_git_branch(working_dir) if working_dir else "Unknown"
|
|
388
448
|
|
|
449
|
+
# Retrieve tool_call_id using CorrelationManager for cross-process correlation
|
|
450
|
+
from .correlation_manager import CorrelationManager
|
|
451
|
+
|
|
452
|
+
tool_call_id = CorrelationManager.retrieve(session_id) if session_id else None
|
|
453
|
+
if DEBUG and tool_call_id:
|
|
454
|
+
_log(
|
|
455
|
+
f" - Retrieved tool_call_id: {tool_call_id[:8]}... for session {session_id[:8]}..."
|
|
456
|
+
)
|
|
457
|
+
|
|
389
458
|
post_tool_data = {
|
|
390
459
|
"tool_name": tool_name,
|
|
391
460
|
"exit_code": exit_code,
|
|
@@ -399,7 +468,7 @@ class EventHandlers:
|
|
|
399
468
|
),
|
|
400
469
|
"duration_ms": duration,
|
|
401
470
|
"result_summary": result_data,
|
|
402
|
-
"session_id":
|
|
471
|
+
"session_id": session_id,
|
|
403
472
|
"working_directory": working_dir,
|
|
404
473
|
"git_branch": git_branch,
|
|
405
474
|
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
@@ -412,20 +481,42 @@ class EventHandlers:
|
|
|
412
481
|
),
|
|
413
482
|
}
|
|
414
483
|
|
|
484
|
+
# Include full output for file operations (Read, Edit, Write)
|
|
485
|
+
# so frontend can display file content
|
|
486
|
+
if tool_name in ("Read", "Edit", "Write", "Grep", "Glob") and "output" in event:
|
|
487
|
+
post_tool_data["output"] = event["output"]
|
|
488
|
+
|
|
489
|
+
# Add correlation_id if available for correlation with pre_tool
|
|
490
|
+
if tool_call_id:
|
|
491
|
+
post_tool_data["correlation_id"] = tool_call_id
|
|
492
|
+
|
|
415
493
|
# Handle Task delegation completion for memory hooks and response tracking
|
|
416
494
|
if tool_name == "Task":
|
|
417
495
|
session_id = event.get("session_id", "")
|
|
418
496
|
agent_type = self.hook_handler._get_delegation_agent_type(session_id)
|
|
419
497
|
|
|
420
498
|
# Trigger memory post-delegation hook
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
499
|
+
try:
|
|
500
|
+
mhm = getattr(self.hook_handler, "memory_hook_manager", None)
|
|
501
|
+
if mhm and hasattr(mhm, "trigger_post_delegation_hook"):
|
|
502
|
+
mhm.trigger_post_delegation_hook(agent_type, event, session_id)
|
|
503
|
+
except Exception: # nosec B110
|
|
504
|
+
# Memory hooks are optional
|
|
505
|
+
pass
|
|
424
506
|
|
|
425
507
|
# Track agent response if response tracking is enabled
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
508
|
+
try:
|
|
509
|
+
rtm = getattr(self.hook_handler, "response_tracking_manager", None)
|
|
510
|
+
if rtm and hasattr(rtm, "track_agent_response"):
|
|
511
|
+
delegation_requests = getattr(
|
|
512
|
+
self.hook_handler, "delegation_requests", {}
|
|
513
|
+
)
|
|
514
|
+
rtm.track_agent_response(
|
|
515
|
+
session_id, agent_type, event, delegation_requests
|
|
516
|
+
)
|
|
517
|
+
except Exception: # nosec B110
|
|
518
|
+
# Response tracking is optional
|
|
519
|
+
pass
|
|
429
520
|
|
|
430
521
|
self.hook_handler._emit_socketio_event("", "post_tool", post_tool_data)
|
|
431
522
|
|
|
@@ -485,10 +576,64 @@ class EventHandlers:
|
|
|
485
576
|
if DEBUG:
|
|
486
577
|
self._log_stop_event_debug(event, session_id, metadata)
|
|
487
578
|
|
|
579
|
+
# Auto-pause integration (independent of response tracking)
|
|
580
|
+
# WHY HERE: Auto-pause must work even when response_tracking is disabled
|
|
581
|
+
# Extract usage data directly from event and trigger auto-pause if thresholds crossed
|
|
582
|
+
if "usage" in event:
|
|
583
|
+
auto_pause = getattr(self.hook_handler, "auto_pause_handler", None)
|
|
584
|
+
if auto_pause:
|
|
585
|
+
try:
|
|
586
|
+
usage_data = event["usage"]
|
|
587
|
+
metadata["usage"] = {
|
|
588
|
+
"input_tokens": usage_data.get("input_tokens", 0),
|
|
589
|
+
"output_tokens": usage_data.get("output_tokens", 0),
|
|
590
|
+
"cache_creation_input_tokens": usage_data.get(
|
|
591
|
+
"cache_creation_input_tokens", 0
|
|
592
|
+
),
|
|
593
|
+
"cache_read_input_tokens": usage_data.get(
|
|
594
|
+
"cache_read_input_tokens", 0
|
|
595
|
+
),
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
threshold_crossed = auto_pause.on_usage_update(metadata["usage"])
|
|
599
|
+
if threshold_crossed:
|
|
600
|
+
warning = auto_pause.emit_threshold_warning(threshold_crossed)
|
|
601
|
+
# CRITICAL: Never write to stderr unconditionally - causes hook errors
|
|
602
|
+
# Use _log() instead which only writes to file if DEBUG=true
|
|
603
|
+
from . import _log
|
|
604
|
+
|
|
605
|
+
_log(f"⚠️ Auto-pause threshold crossed: {warning}")
|
|
606
|
+
|
|
607
|
+
if DEBUG:
|
|
608
|
+
_log(
|
|
609
|
+
f" - Auto-pause threshold crossed: {threshold_crossed}"
|
|
610
|
+
)
|
|
611
|
+
except Exception as e:
|
|
612
|
+
if DEBUG:
|
|
613
|
+
_log(f"Auto-pause error in handle_stop_fast: {e}")
|
|
614
|
+
|
|
615
|
+
# Finalize pause session if active
|
|
616
|
+
try:
|
|
617
|
+
if auto_pause.is_pause_active():
|
|
618
|
+
session_file = auto_pause.on_session_end()
|
|
619
|
+
if session_file:
|
|
620
|
+
if DEBUG:
|
|
621
|
+
_log(
|
|
622
|
+
f"✅ Auto-pause session finalized: {session_file.name}"
|
|
623
|
+
)
|
|
624
|
+
except Exception as e:
|
|
625
|
+
if DEBUG:
|
|
626
|
+
_log(f"❌ Failed to finalize auto-pause session: {e}")
|
|
627
|
+
|
|
488
628
|
# Track response if enabled
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
629
|
+
try:
|
|
630
|
+
rtm = getattr(self.hook_handler, "response_tracking_manager", None)
|
|
631
|
+
if rtm and hasattr(rtm, "track_stop_response"):
|
|
632
|
+
pending_prompts = getattr(self.hook_handler, "pending_prompts", {})
|
|
633
|
+
rtm.track_stop_response(event, session_id, metadata, pending_prompts)
|
|
634
|
+
except Exception: # nosec B110
|
|
635
|
+
# Response tracking is optional
|
|
636
|
+
pass
|
|
492
637
|
|
|
493
638
|
# Emit stop event to Socket.IO
|
|
494
639
|
self._emit_stop_event(event, session_id, metadata)
|
|
@@ -511,21 +656,24 @@ class EventHandlers:
|
|
|
511
656
|
self, event: dict, session_id: str, metadata: dict
|
|
512
657
|
) -> None:
|
|
513
658
|
"""Log debug information for stop events."""
|
|
659
|
+
try:
|
|
660
|
+
rtm = getattr(self.hook_handler, "response_tracking_manager", None)
|
|
661
|
+
tracking_enabled = (
|
|
662
|
+
getattr(rtm, "response_tracking_enabled", False) if rtm else False
|
|
663
|
+
)
|
|
664
|
+
tracker_exists = (
|
|
665
|
+
getattr(rtm, "response_tracker", None) is not None if rtm else False
|
|
666
|
+
)
|
|
514
667
|
|
|
515
|
-
|
|
516
|
-
f" -
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
)
|
|
523
|
-
|
|
524
|
-
f" - session_id: {session_id[:8] if session_id else 'None'}...",
|
|
525
|
-
file=sys.stderr,
|
|
526
|
-
)
|
|
527
|
-
print(f" - reason: {metadata['reason']}", file=sys.stderr)
|
|
528
|
-
print(f" - stop_type: {metadata['stop_type']}", file=sys.stderr)
|
|
668
|
+
_log(f" - response_tracking_enabled: {tracking_enabled}")
|
|
669
|
+
_log(f" - response_tracker exists: {tracker_exists}")
|
|
670
|
+
except Exception: # nosec B110
|
|
671
|
+
# If debug logging fails, just skip it
|
|
672
|
+
pass
|
|
673
|
+
|
|
674
|
+
_log(f" - session_id: {session_id[:8] if session_id else 'None'}...")
|
|
675
|
+
_log(f" - reason: {metadata['reason']}")
|
|
676
|
+
_log(f" - stop_type: {metadata['stop_type']}")
|
|
529
677
|
|
|
530
678
|
def _emit_stop_event(self, event: dict, session_id: str, metadata: dict) -> None:
|
|
531
679
|
"""Emit stop event data to Socket.IO."""
|
|
@@ -567,25 +715,29 @@ class EventHandlers:
|
|
|
567
715
|
git_branch: str,
|
|
568
716
|
):
|
|
569
717
|
"""Handle response tracking for subagent stop events with fuzzy matching."""
|
|
570
|
-
|
|
571
|
-
self.hook_handler
|
|
572
|
-
|
|
573
|
-
|
|
718
|
+
try:
|
|
719
|
+
rtm = getattr(self.hook_handler, "response_tracking_manager", None)
|
|
720
|
+
if not (
|
|
721
|
+
rtm
|
|
722
|
+
and getattr(rtm, "response_tracking_enabled", False)
|
|
723
|
+
and getattr(rtm, "response_tracker", None)
|
|
724
|
+
):
|
|
725
|
+
return
|
|
726
|
+
except Exception:
|
|
727
|
+
# Response tracking is optional
|
|
574
728
|
return
|
|
575
729
|
|
|
576
730
|
try:
|
|
577
731
|
# Get the original request data (with fuzzy matching fallback)
|
|
578
|
-
|
|
732
|
+
delegation_requests = getattr(self.hook_handler, "delegation_requests", {})
|
|
733
|
+
request_info = delegation_requests.get(session_id) # nosec B113
|
|
579
734
|
|
|
580
735
|
# If exact match fails, try partial matching
|
|
581
736
|
if not request_info and session_id:
|
|
582
737
|
if DEBUG:
|
|
583
|
-
|
|
584
|
-
f" - Trying fuzzy match for session {session_id[:16]}...",
|
|
585
|
-
file=sys.stderr,
|
|
586
|
-
)
|
|
738
|
+
_log(f" - Trying fuzzy match for session {session_id[:16]}...")
|
|
587
739
|
# Try to find a session that matches the first 8-16 characters
|
|
588
|
-
for stored_sid in list(
|
|
740
|
+
for stored_sid in list(delegation_requests.keys()):
|
|
589
741
|
if (
|
|
590
742
|
stored_sid.startswith(session_id[:8])
|
|
591
743
|
or session_id.startswith(stored_sid[:8])
|
|
@@ -596,21 +748,14 @@ class EventHandlers:
|
|
|
596
748
|
)
|
|
597
749
|
):
|
|
598
750
|
if DEBUG:
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
file=sys.stderr,
|
|
602
|
-
)
|
|
603
|
-
request_info = self.hook_handler.delegation_requests.get(
|
|
604
|
-
stored_sid
|
|
605
|
-
)
|
|
751
|
+
_log(f" - ✅ Fuzzy match found: {stored_sid[:16]}...")
|
|
752
|
+
request_info = delegation_requests.get(stored_sid) # nosec B113
|
|
606
753
|
# Update the key to use the current session_id for consistency
|
|
607
754
|
if request_info:
|
|
608
|
-
|
|
609
|
-
request_info
|
|
610
|
-
)
|
|
755
|
+
delegation_requests[session_id] = request_info
|
|
611
756
|
# Optionally remove the old key to avoid duplicates
|
|
612
757
|
if stored_sid != session_id:
|
|
613
|
-
del
|
|
758
|
+
del delegation_requests[stored_sid]
|
|
614
759
|
break
|
|
615
760
|
|
|
616
761
|
if request_info:
|
|
@@ -658,35 +803,39 @@ class EventHandlers:
|
|
|
658
803
|
)
|
|
659
804
|
|
|
660
805
|
# Track the response
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
response=response_text,
|
|
665
|
-
session_id=session_id,
|
|
666
|
-
metadata=metadata,
|
|
806
|
+
rtm = getattr(self.hook_handler, "response_tracking_manager", None)
|
|
807
|
+
response_tracker = (
|
|
808
|
+
getattr(rtm, "response_tracker", None) if rtm else None
|
|
667
809
|
)
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
810
|
+
if response_tracker and hasattr(response_tracker, "track_response"):
|
|
811
|
+
file_path = response_tracker.track_response(
|
|
812
|
+
agent_name=agent_type,
|
|
813
|
+
request=full_request,
|
|
814
|
+
response=response_text,
|
|
815
|
+
session_id=session_id,
|
|
816
|
+
metadata=metadata,
|
|
673
817
|
)
|
|
674
818
|
|
|
819
|
+
if file_path and DEBUG:
|
|
820
|
+
_log(
|
|
821
|
+
f"✅ Tracked {agent_type} agent response on SubagentStop: {file_path.name}"
|
|
822
|
+
)
|
|
823
|
+
|
|
675
824
|
# Clean up the request data
|
|
676
|
-
|
|
677
|
-
|
|
825
|
+
delegation_requests = getattr(
|
|
826
|
+
self.hook_handler, "delegation_requests", {}
|
|
827
|
+
)
|
|
828
|
+
if session_id in delegation_requests:
|
|
829
|
+
del delegation_requests[session_id]
|
|
678
830
|
|
|
679
831
|
elif DEBUG:
|
|
680
|
-
|
|
681
|
-
f"No request data for SubagentStop session {session_id[:8]}..., agent: {agent_type}"
|
|
682
|
-
file=sys.stderr,
|
|
832
|
+
_log(
|
|
833
|
+
f"No request data for SubagentStop session {session_id[:8]}..., agent: {agent_type}"
|
|
683
834
|
)
|
|
684
835
|
|
|
685
836
|
except Exception as e:
|
|
686
837
|
if DEBUG:
|
|
687
|
-
|
|
688
|
-
f"❌ Failed to track response on SubagentStop: {e}", file=sys.stderr
|
|
689
|
-
)
|
|
838
|
+
_log(f"❌ Failed to track response on SubagentStop: {e}")
|
|
690
839
|
|
|
691
840
|
def handle_assistant_response(self, event):
|
|
692
841
|
"""Handle assistant response events for comprehensive response tracking.
|
|
@@ -696,11 +845,24 @@ class EventHandlers:
|
|
|
696
845
|
- Captures response content and metadata for analysis
|
|
697
846
|
- Enables tracking of conversation flow and response patterns
|
|
698
847
|
- Essential for comprehensive monitoring of Claude interactions
|
|
848
|
+
- Scans for delegation anti-patterns and creates autotodos
|
|
699
849
|
"""
|
|
700
850
|
# Track the response for logging
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
851
|
+
try:
|
|
852
|
+
rtm = getattr(self.hook_handler, "response_tracking_manager", None)
|
|
853
|
+
if rtm and hasattr(rtm, "track_assistant_response"):
|
|
854
|
+
pending_prompts = getattr(self.hook_handler, "pending_prompts", {})
|
|
855
|
+
rtm.track_assistant_response(event, pending_prompts)
|
|
856
|
+
except Exception: # nosec B110
|
|
857
|
+
# Response tracking is optional
|
|
858
|
+
pass
|
|
859
|
+
|
|
860
|
+
# Scan response for delegation anti-patterns and create autotodos
|
|
861
|
+
try:
|
|
862
|
+
self._scan_for_delegation_patterns(event)
|
|
863
|
+
except Exception as e: # nosec B110
|
|
864
|
+
if DEBUG:
|
|
865
|
+
_log(f"Delegation scanning error: {e}")
|
|
704
866
|
|
|
705
867
|
# Get working directory and git branch
|
|
706
868
|
working_dir = event.get("cwd", "")
|
|
@@ -730,26 +892,215 @@ class EventHandlers:
|
|
|
730
892
|
}
|
|
731
893
|
|
|
732
894
|
# Check if this is a response to a tracked prompt
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
895
|
+
try:
|
|
896
|
+
pending_prompts = getattr(self.hook_handler, "pending_prompts", {})
|
|
897
|
+
if session_id in pending_prompts:
|
|
898
|
+
prompt_data = pending_prompts[session_id]
|
|
899
|
+
assistant_response_data["original_prompt"] = prompt_data.get(
|
|
900
|
+
"prompt", ""
|
|
901
|
+
)[:200]
|
|
902
|
+
assistant_response_data["prompt_timestamp"] = prompt_data.get(
|
|
903
|
+
"timestamp", ""
|
|
904
|
+
)
|
|
905
|
+
assistant_response_data["is_tracked_response"] = True
|
|
906
|
+
else:
|
|
907
|
+
assistant_response_data["is_tracked_response"] = False
|
|
908
|
+
except Exception:
|
|
909
|
+
# If prompt lookup fails, just mark as not tracked
|
|
743
910
|
assistant_response_data["is_tracked_response"] = False
|
|
744
911
|
|
|
745
912
|
# Debug logging
|
|
746
913
|
if DEBUG:
|
|
747
|
-
|
|
748
|
-
f"Hook handler: Processing AssistantResponse - session: '{session_id}', response_length: {len(response_text)}"
|
|
749
|
-
file=sys.stderr,
|
|
914
|
+
_log(
|
|
915
|
+
f"Hook handler: Processing AssistantResponse - session: '{session_id}', response_length: {len(response_text)}"
|
|
750
916
|
)
|
|
751
917
|
|
|
918
|
+
# Record assistant response for auto-pause if active
|
|
919
|
+
auto_pause = getattr(self.hook_handler, "auto_pause_handler", None)
|
|
920
|
+
if auto_pause and auto_pause.is_pause_active():
|
|
921
|
+
try:
|
|
922
|
+
# Summarize response to first 200 chars
|
|
923
|
+
summary = (
|
|
924
|
+
response_text[:200] + "..."
|
|
925
|
+
if len(response_text) > 200
|
|
926
|
+
else response_text
|
|
927
|
+
)
|
|
928
|
+
auto_pause.on_assistant_response(summary)
|
|
929
|
+
except Exception as e:
|
|
930
|
+
if DEBUG:
|
|
931
|
+
_log(f"Auto-pause response recording error: {e}")
|
|
932
|
+
|
|
752
933
|
# Emit normalized event
|
|
753
934
|
self.hook_handler._emit_socketio_event(
|
|
754
935
|
"", "assistant_response", assistant_response_data
|
|
755
936
|
)
|
|
937
|
+
|
|
938
|
+
def handle_session_start_fast(self, event):
|
|
939
|
+
"""Handle session start events for tracking conversation sessions.
|
|
940
|
+
|
|
941
|
+
WHY track session starts:
|
|
942
|
+
- Provides visibility into new conversation sessions
|
|
943
|
+
- Enables tracking of session lifecycle and duration
|
|
944
|
+
- Useful for monitoring concurrent sessions and resource usage
|
|
945
|
+
- Auto-inject pending autotodos if enabled in config
|
|
946
|
+
"""
|
|
947
|
+
session_id = event.get("session_id", "")
|
|
948
|
+
working_dir = event.get("cwd", "")
|
|
949
|
+
git_branch = self._get_git_branch(working_dir) if working_dir else "Unknown"
|
|
950
|
+
|
|
951
|
+
session_start_data = {
|
|
952
|
+
"session_id": session_id,
|
|
953
|
+
"working_directory": working_dir,
|
|
954
|
+
"git_branch": git_branch,
|
|
955
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
956
|
+
"hook_event_name": "SessionStart",
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
# Auto-inject pending autotodos if enabled
|
|
960
|
+
try:
|
|
961
|
+
from pathlib import Path
|
|
962
|
+
|
|
963
|
+
from claude_mpm.cli.commands.autotodos import get_pending_todos
|
|
964
|
+
from claude_mpm.core.config import Config
|
|
965
|
+
|
|
966
|
+
config = Config()
|
|
967
|
+
auto_inject_enabled = config.get("autotodos.auto_inject_on_startup", True)
|
|
968
|
+
max_todos = config.get("autotodos.max_todos_per_session", 10)
|
|
969
|
+
|
|
970
|
+
if auto_inject_enabled:
|
|
971
|
+
# Pass working directory from event to avoid Path.cwd() issues
|
|
972
|
+
working_dir_param = None
|
|
973
|
+
if working_dir:
|
|
974
|
+
working_dir_param = Path(working_dir)
|
|
975
|
+
|
|
976
|
+
pending_todos = get_pending_todos(
|
|
977
|
+
max_todos=max_todos, working_dir=working_dir_param
|
|
978
|
+
)
|
|
979
|
+
if pending_todos:
|
|
980
|
+
session_start_data["pending_autotodos"] = pending_todos
|
|
981
|
+
session_start_data["autotodos_count"] = len(pending_todos)
|
|
982
|
+
_log(f" - Auto-injected {len(pending_todos)} pending autotodos")
|
|
983
|
+
except Exception as e: # nosec B110
|
|
984
|
+
# Auto-injection is optional - continue if it fails
|
|
985
|
+
_log(f" - Failed to auto-inject autotodos: {e}")
|
|
986
|
+
|
|
987
|
+
# Debug logging
|
|
988
|
+
_log(f"Hook handler: Processing SessionStart - session: '{session_id}'")
|
|
989
|
+
|
|
990
|
+
# Emit normalized event
|
|
991
|
+
self.hook_handler._emit_socketio_event("", "session_start", session_start_data)
|
|
992
|
+
|
|
993
|
+
def handle_subagent_start_fast(self, event):
|
|
994
|
+
"""Handle SubagentStart events with proper agent type extraction.
|
|
995
|
+
|
|
996
|
+
WHY separate from SessionStart:
|
|
997
|
+
- SubagentStart contains agent-specific information
|
|
998
|
+
- Frontend needs agent_type to create distinct agent nodes
|
|
999
|
+
- Multiple engineers should show as separate nodes in hierarchy
|
|
1000
|
+
- Research agents must appear in the agent hierarchy
|
|
1001
|
+
|
|
1002
|
+
Unlike SessionStart, SubagentStart events contain agent-specific
|
|
1003
|
+
information that must be preserved and emitted to the dashboard.
|
|
1004
|
+
"""
|
|
1005
|
+
session_id = event.get("session_id", "")
|
|
1006
|
+
|
|
1007
|
+
# Extract agent type from event - Claude provides this in SubagentStart
|
|
1008
|
+
# Try multiple possible field names for compatibility
|
|
1009
|
+
agent_type = event.get("agent_type") or event.get("subagent_type") or "unknown"
|
|
1010
|
+
|
|
1011
|
+
# Generate unique agent ID combining type and session
|
|
1012
|
+
agent_id = event.get("agent_id", f"{agent_type}_{session_id[:8]}")
|
|
1013
|
+
|
|
1014
|
+
# Get working directory and git branch
|
|
1015
|
+
working_dir = event.get("cwd", "")
|
|
1016
|
+
git_branch = self._get_git_branch(working_dir) if working_dir else "Unknown"
|
|
1017
|
+
|
|
1018
|
+
# Build subagent start data with all required fields
|
|
1019
|
+
subagent_start_data = {
|
|
1020
|
+
"session_id": session_id,
|
|
1021
|
+
"agent_type": agent_type,
|
|
1022
|
+
"agent_id": agent_id,
|
|
1023
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
1024
|
+
"hook_event_name": "SubagentStart", # Preserve correct hook name
|
|
1025
|
+
"working_directory": working_dir,
|
|
1026
|
+
"git_branch": git_branch,
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
# Debug logging
|
|
1030
|
+
if DEBUG:
|
|
1031
|
+
_log(
|
|
1032
|
+
f"Hook handler: SubagentStart - agent_type='{agent_type}', agent_id='{agent_id}', session_id='{session_id[:16]}...'"
|
|
1033
|
+
)
|
|
1034
|
+
|
|
1035
|
+
# Emit to /hook namespace as subagent_start (NOT session_start!)
|
|
1036
|
+
self.hook_handler._emit_socketio_event(
|
|
1037
|
+
"", "subagent_start", subagent_start_data
|
|
1038
|
+
)
|
|
1039
|
+
|
|
1040
|
+
def _scan_for_delegation_patterns(self, event):
|
|
1041
|
+
"""Scan assistant response for delegation anti-patterns.
|
|
1042
|
+
|
|
1043
|
+
WHY this is needed:
|
|
1044
|
+
- Detect when PM asks user to do something manually instead of delegating
|
|
1045
|
+
- Flag PM behavior violations for immediate correction
|
|
1046
|
+
- Enforce delegation principle in PM workflow
|
|
1047
|
+
- Help PM recognize delegation opportunities
|
|
1048
|
+
|
|
1049
|
+
This method scans the assistant's response text for patterns like:
|
|
1050
|
+
- "Make sure .env.local is in your .gitignore"
|
|
1051
|
+
- "You'll need to run npm install"
|
|
1052
|
+
- "Please run the tests manually"
|
|
1053
|
+
|
|
1054
|
+
When patterns are detected, PM violations are logged as errors/warnings
|
|
1055
|
+
that should be corrected immediately, NOT as todos to delegate.
|
|
1056
|
+
|
|
1057
|
+
DESIGN DECISION: pm.violation vs autotodo.delegation
|
|
1058
|
+
- Delegation patterns = PM doing something WRONG → pm.violation (error)
|
|
1059
|
+
- Script failures = Something BROKEN → autotodo.error (todo)
|
|
1060
|
+
"""
|
|
1061
|
+
# Only scan if delegation detector is available
|
|
1062
|
+
try:
|
|
1063
|
+
from claude_mpm.services.delegation_detector import get_delegation_detector
|
|
1064
|
+
from claude_mpm.services.event_log import get_event_log
|
|
1065
|
+
except ImportError:
|
|
1066
|
+
if DEBUG:
|
|
1067
|
+
_log("Delegation detector or event log not available")
|
|
1068
|
+
return
|
|
1069
|
+
|
|
1070
|
+
response_text = event.get("response", "")
|
|
1071
|
+
if not response_text:
|
|
1072
|
+
return
|
|
1073
|
+
|
|
1074
|
+
# Get the delegation detector
|
|
1075
|
+
detector = get_delegation_detector()
|
|
1076
|
+
|
|
1077
|
+
# Detect delegation patterns
|
|
1078
|
+
detections = detector.detect_user_delegation(response_text)
|
|
1079
|
+
|
|
1080
|
+
if not detections:
|
|
1081
|
+
return # No patterns detected
|
|
1082
|
+
|
|
1083
|
+
# Get event log for violation recording
|
|
1084
|
+
event_log = get_event_log()
|
|
1085
|
+
|
|
1086
|
+
# Create PM violation events (NOT autotodos)
|
|
1087
|
+
for detection in detections:
|
|
1088
|
+
# Create event log entry as pm.violation
|
|
1089
|
+
event_log.append_event(
|
|
1090
|
+
event_type="pm.violation",
|
|
1091
|
+
payload={
|
|
1092
|
+
"violation_type": "delegation_anti_pattern",
|
|
1093
|
+
"pattern_type": detection["pattern_type"],
|
|
1094
|
+
"original_text": detection["original_text"],
|
|
1095
|
+
"suggested_action": detection["suggested_todo"],
|
|
1096
|
+
"action": detection["action"],
|
|
1097
|
+
"session_id": event.get("session_id", ""),
|
|
1098
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
1099
|
+
"severity": "warning", # Not critical, but should be fixed
|
|
1100
|
+
"message": f"PM asked user to do something manually: {detection['original_text'][:80]}...",
|
|
1101
|
+
},
|
|
1102
|
+
status="pending",
|
|
1103
|
+
)
|
|
1104
|
+
|
|
1105
|
+
if DEBUG:
|
|
1106
|
+
_log(f"⚠️ PM violation detected: {detection['original_text'][:60]}...")
|