claude-mpm 5.4.41__py3-none-any.whl → 5.6.72__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of claude-mpm might be problematic. Click here for more details.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/CLAUDE_MPM_OUTPUT_STYLE.md +66 -241
- claude_mpm/agents/CLAUDE_MPM_RESEARCH_OUTPUT_STYLE.md +413 -0
- claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +109 -1925
- claude_mpm/agents/PM_INSTRUCTIONS.md +161 -298
- claude_mpm/agents/WORKFLOW.md +2 -0
- claude_mpm/agents/templates/circuit-breakers.md +26 -17
- claude_mpm/auth/__init__.py +35 -0
- claude_mpm/auth/callback_server.py +328 -0
- claude_mpm/auth/models.py +104 -0
- claude_mpm/auth/oauth_manager.py +266 -0
- claude_mpm/auth/providers/__init__.py +12 -0
- claude_mpm/auth/providers/base.py +165 -0
- claude_mpm/auth/providers/google.py +261 -0
- claude_mpm/auth/token_storage.py +252 -0
- claude_mpm/cli/__init__.py +5 -1
- claude_mpm/cli/commands/agents.py +2 -4
- claude_mpm/cli/commands/agents_reconcile.py +197 -0
- claude_mpm/cli/commands/autotodos.py +566 -0
- claude_mpm/cli/commands/commander.py +216 -0
- claude_mpm/cli/commands/configure.py +620 -21
- claude_mpm/cli/commands/configure_agent_display.py +3 -1
- claude_mpm/cli/commands/hook_errors.py +60 -60
- claude_mpm/cli/commands/mcp.py +29 -17
- claude_mpm/cli/commands/mcp_command_router.py +39 -0
- claude_mpm/cli/commands/mcp_service_commands.py +304 -0
- claude_mpm/cli/commands/monitor.py +2 -2
- claude_mpm/cli/commands/mpm_init/core.py +15 -8
- claude_mpm/cli/commands/oauth.py +481 -0
- claude_mpm/cli/commands/profile.py +9 -10
- claude_mpm/cli/commands/run.py +35 -3
- claude_mpm/cli/commands/skill_source.py +51 -2
- claude_mpm/cli/commands/skills.py +182 -32
- claude_mpm/cli/executor.py +129 -16
- claude_mpm/cli/helpers.py +1 -1
- claude_mpm/cli/interactive/__init__.py +10 -0
- claude_mpm/cli/interactive/agent_wizard.py +30 -50
- claude_mpm/cli/interactive/questionary_styles.py +65 -0
- claude_mpm/cli/interactive/skill_selector.py +481 -0
- claude_mpm/cli/parsers/base_parser.py +89 -1
- claude_mpm/cli/parsers/commander_parser.py +116 -0
- claude_mpm/cli/parsers/mcp_parser.py +79 -0
- claude_mpm/cli/parsers/oauth_parser.py +165 -0
- claude_mpm/cli/parsers/profile_parser.py +0 -1
- claude_mpm/cli/parsers/run_parser.py +10 -0
- claude_mpm/cli/parsers/skill_source_parser.py +4 -0
- claude_mpm/cli/parsers/skills_parser.py +2 -3
- claude_mpm/cli/startup.py +662 -524
- claude_mpm/cli/startup_display.py +76 -7
- 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 +149 -0
- claude_mpm/commander/chat/commands.py +122 -0
- claude_mpm/commander/chat/repl.py +1821 -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 +392 -0
- claude_mpm/commander/frameworks/__init__.py +12 -0
- claude_mpm/commander/frameworks/base.py +233 -0
- claude_mpm/commander/frameworks/claude_code.py +58 -0
- claude_mpm/commander/frameworks/mpm.py +57 -0
- claude_mpm/commander/git/__init__.py +5 -0
- claude_mpm/commander/git/worktree_manager.py +212 -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 +865 -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 +127 -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 +403 -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 +362 -0
- claude_mpm/commander/web/__init__.py +1 -0
- claude_mpm/commander/work/__init__.py +30 -0
- claude_mpm/commander/work/executor.py +207 -0
- claude_mpm/commander/work/queue.py +405 -0
- claude_mpm/commander/workflow/__init__.py +27 -0
- claude_mpm/commander/workflow/event_handler.py +241 -0
- claude_mpm/commander/workflow/notifier.py +146 -0
- claude_mpm/commands/mpm-config.md +8 -0
- claude_mpm/commands/mpm-doctor.md +8 -0
- claude_mpm/commands/mpm-help.md +8 -0
- claude_mpm/commands/mpm-init.md +8 -0
- claude_mpm/commands/mpm-monitor.md +8 -0
- claude_mpm/commands/mpm-organize.md +8 -0
- claude_mpm/commands/mpm-postmortem.md +8 -0
- claude_mpm/commands/mpm-session-resume.md +9 -1
- claude_mpm/commands/mpm-status.md +8 -0
- claude_mpm/commands/mpm-ticket-view.md +8 -0
- claude_mpm/commands/mpm-version.md +8 -0
- claude_mpm/commands/mpm.md +8 -0
- claude_mpm/config/agent_presets.py +8 -7
- claude_mpm/config/skill_sources.py +16 -0
- claude_mpm/constants.py +6 -0
- claude_mpm/core/claude_runner.py +154 -2
- claude_mpm/core/config.py +35 -22
- claude_mpm/core/config_constants.py +74 -9
- claude_mpm/core/constants.py +56 -12
- claude_mpm/core/hook_manager.py +53 -4
- claude_mpm/core/interactive_session.py +12 -11
- claude_mpm/core/logger.py +26 -9
- claude_mpm/core/logging_utils.py +39 -13
- claude_mpm/core/network_config.py +148 -0
- claude_mpm/core/oneshot_session.py +7 -6
- claude_mpm/core/optimized_startup.py +3 -1
- claude_mpm/core/output_style_manager.py +66 -18
- claude_mpm/core/shared/config_loader.py +3 -1
- claude_mpm/core/socketio_pool.py +47 -15
- claude_mpm/core/unified_config.py +54 -8
- claude_mpm/core/unified_paths.py +95 -90
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.C33zOoyM.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.CW1J-YuA.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/1WZnGYqX.js +24 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/67pF3qNn.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/6RxdMKe4.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/8cZrfX0h.js +60 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/9a6T2nm-.js +7 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B443AUzu.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B8AwtY2H.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BF15LAsF.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BQaXIfA_.js +331 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BRcwIQNr.js +4 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{uj46x2Wr.js → BSNlmTZj.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BV6nKitt.js +43 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BViJ8lZt.js +128 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BcQ-Q0FE.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Bpyvgze_.js +30 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BzTRqg-z.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C0Fr8dve.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C3rbW_a-.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C8WYN38h.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C9I8FlXH.js +61 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIQcWgO2.js +36 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIctN7YN.js +7 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CKrS_JZW.js +145 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CR6P9C4A.js +89 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRRR9MD_.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRcR2DqT.js +334 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CSXtMOf0.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CT-sbxSk.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWm6DJsp.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CmKTTxBW.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CpqQ1Kzn.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cu_Erd72.js +261 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D2nGpDRe.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9iCMida.js +267 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9ykgMoY.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DL2Ldur1.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DPfltzjH.js +165 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{N4qtv3Hx.js → DR8nis88.js} +2 -2
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DUliQN2b.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DVp1hx9R.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DXlhR01x.js +122 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D_lyTybS.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DngoTTgh.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DqkmHtDC.js +220 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DsDh8EYs.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DypDmXgd.js +139 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Gi6I4Gst.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/IPYC-LnN.js +162 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JTLiF7dt.js +24 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JpevfAFt.js +68 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DjhvlsAc.js → NqQ1dWOy.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/R8CEIRAd.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Zxy7qc-l.js +64 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/q9Hm6zAU.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/qtd3IeO4.js +15 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/ulBFON_C.js +65 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/wQVh1CoA.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.Dr7t0z2J.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.BGhZHUS3.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/{0.CAGBuiOw.js → 0.RgBboRvH.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DG-KkbDf.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.D_jnf-x6.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -1
- claude_mpm/dashboard/static/svelte-build/index.html +11 -11
- claude_mpm/dashboard-svelte/node_modules/katex/src/fonts/generate_fonts.py +58 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_tfms.py +114 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_ttfs.py +122 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/format_json.py +28 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/parse_tfm.py +211 -0
- claude_mpm/experimental/cli_enhancements.py +2 -1
- claude_mpm/hooks/claude_hooks/INTEGRATION_EXAMPLE.md +243 -0
- claude_mpm/hooks/claude_hooks/README_AUTO_PAUSE.md +403 -0
- claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/auto_pause_handler.py +485 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +466 -136
- claude_mpm/hooks/claude_hooks/hook_handler.py +204 -104
- claude_mpm/hooks/claude_hooks/hook_wrapper.sh +6 -11
- claude_mpm/hooks/claude_hooks/installer.py +291 -59
- claude_mpm/hooks/claude_hooks/memory_integration.py +52 -32
- claude_mpm/hooks/claude_hooks/response_tracking.py +43 -60
- claude_mpm/hooks/claude_hooks/services/__init__.py +21 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/container.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/protocols.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/connection_manager.py +41 -26
- claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +38 -105
- claude_mpm/hooks/claude_hooks/services/container.py +326 -0
- claude_mpm/hooks/claude_hooks/services/protocols.py +328 -0
- claude_mpm/hooks/claude_hooks/services/state_manager.py +25 -38
- claude_mpm/hooks/claude_hooks/services/subagent_processor.py +75 -77
- claude_mpm/hooks/kuzu_memory_hook.py +5 -5
- claude_mpm/hooks/session_resume_hook.py +89 -1
- claude_mpm/hooks/templates/pre_tool_use_simple.py +6 -6
- claude_mpm/hooks/templates/pre_tool_use_template.py +16 -8
- claude_mpm/init.py +224 -4
- claude_mpm/mcp/__init__.py +9 -0
- claude_mpm/mcp/google_workspace_server.py +610 -0
- claude_mpm/scripts/claude-hook-handler.sh +46 -19
- claude_mpm/services/agents/agent_recommendation_service.py +8 -8
- claude_mpm/services/agents/agent_selection_service.py +2 -2
- claude_mpm/services/agents/cache_git_manager.py +1 -1
- claude_mpm/services/agents/deployment/agent_discovery_service.py +3 -1
- claude_mpm/services/agents/deployment/agent_format_converter.py +25 -13
- claude_mpm/services/agents/deployment/agent_template_builder.py +37 -17
- claude_mpm/services/agents/deployment/async_agent_deployment.py +31 -27
- claude_mpm/services/agents/deployment/deployment_reconciler.py +577 -0
- claude_mpm/services/agents/deployment/local_template_deployment.py +3 -1
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +36 -8
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +50 -26
- claude_mpm/services/agents/deployment/startup_reconciliation.py +138 -0
- claude_mpm/services/agents/git_source_manager.py +21 -2
- claude_mpm/services/agents/loading/framework_agent_loader.py +75 -2
- claude_mpm/services/agents/single_tier_deployment_service.py +4 -4
- claude_mpm/services/agents/sources/git_source_sync_service.py +116 -5
- claude_mpm/services/agents/startup_sync.py +5 -2
- claude_mpm/services/cli/__init__.py +3 -0
- claude_mpm/services/cli/incremental_pause_manager.py +561 -0
- claude_mpm/services/cli/session_resume_helper.py +10 -2
- claude_mpm/services/command_deployment_service.py +44 -26
- claude_mpm/services/delegation_detector.py +175 -0
- claude_mpm/services/diagnostics/checks/agent_sources_check.py +30 -0
- claude_mpm/services/diagnostics/checks/configuration_check.py +24 -0
- claude_mpm/services/diagnostics/checks/installation_check.py +22 -0
- claude_mpm/services/diagnostics/checks/mcp_services_check.py +23 -0
- claude_mpm/services/diagnostics/doctor_reporter.py +31 -1
- claude_mpm/services/diagnostics/models.py +14 -1
- claude_mpm/services/event_log.py +325 -0
- claude_mpm/services/hook_installer_service.py +77 -8
- claude_mpm/services/infrastructure/__init__.py +4 -0
- claude_mpm/services/infrastructure/context_usage_tracker.py +291 -0
- claude_mpm/services/infrastructure/resume_log_generator.py +24 -5
- claude_mpm/services/mcp_config_manager.py +99 -19
- claude_mpm/services/mcp_service_registry.py +294 -0
- claude_mpm/services/monitor/daemon_manager.py +15 -4
- claude_mpm/services/monitor/management/lifecycle.py +8 -3
- claude_mpm/services/monitor/server.py +111 -16
- claude_mpm/services/pm_skills_deployer.py +302 -94
- claude_mpm/services/profile_manager.py +10 -4
- claude_mpm/services/skills/git_skill_source_manager.py +192 -29
- claude_mpm/services/skills/selective_skill_deployer.py +211 -46
- claude_mpm/services/skills/skill_discovery_service.py +74 -4
- claude_mpm/services/skills_deployer.py +192 -70
- claude_mpm/services/socketio/handlers/hook.py +14 -7
- claude_mpm/services/socketio/server/main.py +12 -4
- claude_mpm/skills/__init__.py +2 -1
- claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
- claude_mpm/skills/bundled/collaboration/git-worktrees.md +317 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
- claude_mpm/skills/bundled/collaboration/stacked-prs.md +251 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/INTEGRATION.md +611 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/README.md +596 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/SKILL.md +260 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/examples/nextjs-env-structure.md +315 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/frameworks.md +436 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/security.md +433 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/synchronization.md +452 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/troubleshooting.md +404 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/validation.md +420 -0
- claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
- claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
- claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
- claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
- claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
- claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
- claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
- claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
- claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
- claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
- claude_mpm/skills/bundled/pm/mpm/SKILL.md +38 -0
- claude_mpm/skills/bundled/pm/mpm-agent-update-workflow/SKILL.md +75 -0
- claude_mpm/skills/bundled/pm/mpm-bug-reporting/SKILL.md +248 -0
- claude_mpm/skills/bundled/pm/mpm-circuit-breaker-enforcement/SKILL.md +476 -0
- claude_mpm/skills/bundled/pm/mpm-config/SKILL.md +29 -0
- claude_mpm/skills/bundled/pm/mpm-delegation-patterns/SKILL.md +167 -0
- claude_mpm/skills/bundled/pm/mpm-doctor/SKILL.md +53 -0
- claude_mpm/skills/bundled/pm/mpm-git-file-tracking/SKILL.md +113 -0
- claude_mpm/skills/bundled/pm/mpm-help/SKILL.md +35 -0
- claude_mpm/skills/bundled/pm/mpm-init/SKILL.md +125 -0
- claude_mpm/skills/bundled/pm/mpm-monitor/SKILL.md +32 -0
- claude_mpm/skills/bundled/pm/mpm-organize/SKILL.md +121 -0
- claude_mpm/skills/bundled/pm/mpm-postmortem/SKILL.md +22 -0
- claude_mpm/skills/bundled/pm/mpm-pr-workflow/SKILL.md +124 -0
- claude_mpm/skills/bundled/pm/mpm-session-management/SKILL.md +312 -0
- claude_mpm/skills/bundled/pm/mpm-session-pause/SKILL.md +170 -0
- claude_mpm/skills/bundled/pm/mpm-session-resume/SKILL.md +31 -0
- claude_mpm/skills/bundled/pm/mpm-status/SKILL.md +37 -0
- claude_mpm/skills/bundled/pm/mpm-teaching-mode/SKILL.md +657 -0
- claude_mpm/skills/bundled/pm/mpm-ticket-view/SKILL.md +110 -0
- claude_mpm/skills/bundled/pm/mpm-ticketing-integration/SKILL.md +154 -0
- claude_mpm/skills/bundled/pm/mpm-tool-usage-guide/SKILL.md +386 -0
- claude_mpm/skills/bundled/pm/mpm-verification-protocols/SKILL.md +198 -0
- claude_mpm/skills/bundled/pm/mpm-version/SKILL.md +21 -0
- claude_mpm/skills/bundled/react/flexlayout-react.md +742 -0
- claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
- claude_mpm/skills/bundled/security-scanning.md +112 -0
- claude_mpm/skills/bundled/tauri/tauri-async-patterns.md +495 -0
- claude_mpm/skills/bundled/tauri/tauri-build-deploy.md +599 -0
- claude_mpm/skills/bundled/tauri/tauri-command-patterns.md +535 -0
- claude_mpm/skills/bundled/tauri/tauri-error-handling.md +613 -0
- claude_mpm/skills/bundled/tauri/tauri-event-system.md +648 -0
- claude_mpm/skills/bundled/tauri/tauri-file-system.md +673 -0
- claude_mpm/skills/bundled/tauri/tauri-frontend-integration.md +767 -0
- claude_mpm/skills/bundled/tauri/tauri-performance.md +669 -0
- claude_mpm/skills/bundled/tauri/tauri-state-management.md +573 -0
- claude_mpm/skills/bundled/tauri/tauri-testing.md +384 -0
- claude_mpm/skills/bundled/tauri/tauri-window-management.md +628 -0
- claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
- claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
- claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/SKILL.md +458 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/examples/example-inspection-report.md +411 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/assertion-quality.md +317 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/inspection-checklist.md +270 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/red-flags.md +436 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
- claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
- claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
- claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
- claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
- claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
- claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
- claude_mpm/skills/registry.py +295 -90
- claude_mpm/skills/skill_manager.py +29 -23
- claude_mpm/templates/.pre-commit-config.yaml +112 -0
- claude_mpm/utils/agent_dependency_loader.py +103 -4
- claude_mpm/utils/robust_installer.py +45 -24
- claude_mpm-5.6.72.dist-info/METADATA +416 -0
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.72.dist-info}/RECORD +477 -159
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.72.dist-info}/WHEEL +1 -1
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.72.dist-info}/entry_points.txt +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.B_FtCwCQ.css +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.Cl_eSA4x.css +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BgChzWQ1.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIXEwuWe.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWc5urbQ.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DMkZpdF2.js +0 -2
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.DTL5mJO-.js +0 -2
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.DzuEhzqh.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DFLC8jdE.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.DPvEihJJ.js +0 -10
- claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager.cpython-311.pyc +0 -0
- claude_mpm-5.4.41.dist-info/METADATA +0 -998
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.72.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.72.dist-info}/licenses/LICENSE-FAQ.md +0 -0
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.72.dist-info}/top_level.txt +0 -0
|
@@ -10,12 +10,10 @@ import os
|
|
|
10
10
|
import re
|
|
11
11
|
import shutil
|
|
12
12
|
import stat
|
|
13
|
-
import subprocess
|
|
13
|
+
import subprocess # nosec B404 - Safe: only uses hardcoded 'claude' CLI command, no user input
|
|
14
14
|
from pathlib import Path
|
|
15
15
|
from typing import Dict, List, Optional, Tuple
|
|
16
16
|
|
|
17
|
-
from ...core.logger import get_logger
|
|
18
|
-
|
|
19
17
|
|
|
20
18
|
class HookInstaller:
|
|
21
19
|
"""Manages installation and configuration of Claude MPM hooks."""
|
|
@@ -151,7 +149,7 @@ main() {
|
|
|
151
149
|
if [ "${CLAUDE_MPM_HOOK_DEBUG}" = "true" ]; then
|
|
152
150
|
echo "[$(date -u +%Y-%m-%dT%H:%M:%S.%3NZ)] Claude MPM not found, continuing..." >> /tmp/claude-mpm-hook.log
|
|
153
151
|
fi
|
|
154
|
-
echo '{"
|
|
152
|
+
echo '{"continue": true}'
|
|
155
153
|
exit 0
|
|
156
154
|
fi
|
|
157
155
|
|
|
@@ -178,7 +176,7 @@ main() {
|
|
|
178
176
|
echo "[$(date -u +%Y-%m-%dT%H:%M:%S.%3NZ)] Hook handler failed, see /tmp/claude-mpm-hook-error.log" >> /tmp/claude-mpm-hook.log
|
|
179
177
|
echo "[$(date -u +%Y-%m-%dT%H:%M:%S.%3NZ)] Error: $(cat /tmp/claude-mpm-hook-error.log 2>/dev/null | head -5)" >> /tmp/claude-mpm-hook.log
|
|
180
178
|
fi
|
|
181
|
-
echo '{"
|
|
179
|
+
echo '{"continue": true}'
|
|
182
180
|
exit 0
|
|
183
181
|
fi
|
|
184
182
|
|
|
@@ -194,14 +192,25 @@ main "$@"
|
|
|
194
192
|
MIN_CLAUDE_VERSION = "1.0.92"
|
|
195
193
|
# Minimum version for PreToolUse input modification support
|
|
196
194
|
MIN_PRETOOL_MODIFY_VERSION = "2.0.30"
|
|
195
|
+
# Minimum version for user-invocable skills support
|
|
196
|
+
MIN_SKILLS_VERSION = "2.1.3"
|
|
197
197
|
|
|
198
198
|
def __init__(self):
|
|
199
199
|
"""Initialize the hook installer."""
|
|
200
|
-
|
|
201
|
-
|
|
200
|
+
# Use __name__ directly to avoid double prefix
|
|
201
|
+
# __name__ is already 'claude_mpm.hooks.claude_hooks.installer'
|
|
202
|
+
# get_logger() adds 'claude_mpm.' prefix, causing duplicate
|
|
203
|
+
import logging
|
|
204
|
+
|
|
205
|
+
self.logger = logging.getLogger(__name__)
|
|
206
|
+
# Use project-level paths, NEVER global ~/.claude/settings.json
|
|
207
|
+
# This ensures hooks are scoped to the current project only
|
|
208
|
+
self.project_root = Path.cwd()
|
|
209
|
+
self.claude_dir = self.project_root / ".claude"
|
|
202
210
|
self.hooks_dir = self.claude_dir / "hooks" # Kept for backward compatibility
|
|
203
|
-
# Use settings.json for
|
|
204
|
-
|
|
211
|
+
# Use settings.local.json for project-level hook settings
|
|
212
|
+
# Claude Code reads project-level settings from .claude/settings.local.json
|
|
213
|
+
self.settings_file = self.claude_dir / "settings.local.json"
|
|
205
214
|
# There is no legacy settings file - this was a bug where both pointed to same file
|
|
206
215
|
# Setting to None to disable cleanup that was deleting freshly installed hooks
|
|
207
216
|
self.old_settings_file = None
|
|
@@ -220,7 +229,7 @@ main "$@"
|
|
|
220
229
|
|
|
221
230
|
try:
|
|
222
231
|
# Run claude --version command
|
|
223
|
-
result = subprocess.run(
|
|
232
|
+
result = subprocess.run( # nosec B607 B603 - Safe: hardcoded command, no user input
|
|
224
233
|
["claude", "--version"],
|
|
225
234
|
capture_output=True,
|
|
226
235
|
text=True,
|
|
@@ -331,8 +340,82 @@ main "$@"
|
|
|
331
340
|
|
|
332
341
|
return True
|
|
333
342
|
|
|
334
|
-
def
|
|
335
|
-
"""
|
|
343
|
+
def _version_meets_minimum(self, version: str, min_version: str) -> bool:
|
|
344
|
+
"""Check if a version meets minimum requirements.
|
|
345
|
+
|
|
346
|
+
Args:
|
|
347
|
+
version: Current version string (e.g., "2.1.3")
|
|
348
|
+
min_version: Minimum required version string (e.g., "2.1.3")
|
|
349
|
+
|
|
350
|
+
Returns:
|
|
351
|
+
True if version meets or exceeds minimum, False otherwise
|
|
352
|
+
"""
|
|
353
|
+
|
|
354
|
+
def parse_version(v: str) -> List[int]:
|
|
355
|
+
"""Parse semantic version string to list of integers."""
|
|
356
|
+
try:
|
|
357
|
+
return [int(x) for x in v.split(".")]
|
|
358
|
+
except (ValueError, AttributeError):
|
|
359
|
+
return [0]
|
|
360
|
+
|
|
361
|
+
current = parse_version(version)
|
|
362
|
+
required = parse_version(min_version)
|
|
363
|
+
|
|
364
|
+
# Compare versions
|
|
365
|
+
for i in range(max(len(current), len(required))):
|
|
366
|
+
curr_part = current[i] if i < len(current) else 0
|
|
367
|
+
req_part = required[i] if i < len(required) else 0
|
|
368
|
+
|
|
369
|
+
if curr_part < req_part:
|
|
370
|
+
return False
|
|
371
|
+
if curr_part > req_part:
|
|
372
|
+
return True
|
|
373
|
+
|
|
374
|
+
return True
|
|
375
|
+
|
|
376
|
+
def supports_user_invocable_skills(self) -> bool:
|
|
377
|
+
"""Check if Claude Code version supports user-invocable skills.
|
|
378
|
+
|
|
379
|
+
User-invocable skills were added in Claude Code v2.1.3.
|
|
380
|
+
This feature allows users to invoke skills via slash commands.
|
|
381
|
+
|
|
382
|
+
Returns:
|
|
383
|
+
True if version supports user-invocable skills, False otherwise
|
|
384
|
+
"""
|
|
385
|
+
version = self.get_claude_version()
|
|
386
|
+
if not version:
|
|
387
|
+
return False
|
|
388
|
+
return self._version_meets_minimum(version, self.MIN_SKILLS_VERSION)
|
|
389
|
+
|
|
390
|
+
def get_hook_command(self) -> str:
|
|
391
|
+
"""Get the hook command based on installation method.
|
|
392
|
+
|
|
393
|
+
Priority order:
|
|
394
|
+
1. claude-hook entry point (uv tool install, pipx install, pip install)
|
|
395
|
+
2. Fallback to bash script (development installs)
|
|
396
|
+
|
|
397
|
+
Returns:
|
|
398
|
+
Command string for the hook handler (either 'claude-hook' or path to bash script)
|
|
399
|
+
|
|
400
|
+
Raises:
|
|
401
|
+
FileNotFoundError: If no hook handler can be found
|
|
402
|
+
"""
|
|
403
|
+
# Check if claude-hook entry point is available in PATH
|
|
404
|
+
claude_hook_path = shutil.which("claude-hook")
|
|
405
|
+
if claude_hook_path:
|
|
406
|
+
self.logger.info(f"Using claude-hook entry point: {claude_hook_path}")
|
|
407
|
+
return "claude-hook"
|
|
408
|
+
|
|
409
|
+
# Fallback to bash script for development installs
|
|
410
|
+
script_path = self._get_hook_script_path()
|
|
411
|
+
self.logger.info(f"Using fallback bash script: {script_path}")
|
|
412
|
+
return str(script_path.absolute())
|
|
413
|
+
|
|
414
|
+
def _get_hook_script_path(self) -> Path:
|
|
415
|
+
"""Get the path to the fallback bash hook handler script.
|
|
416
|
+
|
|
417
|
+
This is used when the claude-hook entry point is not available
|
|
418
|
+
(e.g., development installs without uv tool install).
|
|
336
419
|
|
|
337
420
|
Returns:
|
|
338
421
|
Path to the claude-hook-handler.sh script
|
|
@@ -385,6 +468,19 @@ main "$@"
|
|
|
385
468
|
|
|
386
469
|
raise FileNotFoundError(f"Hook handler script not found at {script_path}")
|
|
387
470
|
|
|
471
|
+
def get_hook_script_path(self) -> Path:
|
|
472
|
+
"""Get the path to the hook handler script based on installation method.
|
|
473
|
+
|
|
474
|
+
DEPRECATED: Use get_hook_command() instead for proper entry point support.
|
|
475
|
+
|
|
476
|
+
Returns:
|
|
477
|
+
Path to the claude-hook-handler.sh script
|
|
478
|
+
|
|
479
|
+
Raises:
|
|
480
|
+
FileNotFoundError: If the script cannot be found
|
|
481
|
+
"""
|
|
482
|
+
return self._get_hook_script_path()
|
|
483
|
+
|
|
388
484
|
def install_hooks(self, force: bool = False) -> bool:
|
|
389
485
|
"""
|
|
390
486
|
Install Claude MPM hooks.
|
|
@@ -417,18 +513,16 @@ main "$@"
|
|
|
417
513
|
# Create Claude directory (hooks_dir no longer needed)
|
|
418
514
|
self.claude_dir.mkdir(exist_ok=True)
|
|
419
515
|
|
|
420
|
-
# Get the
|
|
516
|
+
# Get the hook command (either claude-hook entry point or fallback bash script)
|
|
421
517
|
try:
|
|
422
|
-
|
|
423
|
-
self.logger.info(
|
|
424
|
-
f"Using deployment-root hook script: {hook_script_path}"
|
|
425
|
-
)
|
|
518
|
+
hook_command = self.get_hook_command()
|
|
519
|
+
self.logger.info(f"Using hook command: {hook_command}")
|
|
426
520
|
except FileNotFoundError as e:
|
|
427
|
-
self.logger.error(f"Failed to locate hook
|
|
521
|
+
self.logger.error(f"Failed to locate hook handler: {e}")
|
|
428
522
|
return False
|
|
429
523
|
|
|
430
|
-
# Update Claude settings to use
|
|
431
|
-
self._update_claude_settings(
|
|
524
|
+
# Update Claude settings to use the hook command
|
|
525
|
+
self._update_claude_settings(hook_command)
|
|
432
526
|
|
|
433
527
|
# Install commands if available
|
|
434
528
|
self._install_commands()
|
|
@@ -485,8 +579,50 @@ main "$@"
|
|
|
485
579
|
except Exception as e:
|
|
486
580
|
self.logger.warning(f"Could not clean up old settings file: {e}")
|
|
487
581
|
|
|
488
|
-
def
|
|
489
|
-
"""
|
|
582
|
+
def _fix_status_line(self, settings: Dict) -> None:
|
|
583
|
+
"""Fix statusLine command to handle both output style schema formats.
|
|
584
|
+
|
|
585
|
+
The statusLine command receives input in different formats:
|
|
586
|
+
- Newer format: {"activeOutputStyle": "Claude MPM", ...}
|
|
587
|
+
- Older format: {"output_style": {"name": "Claude MPM"}, ...}
|
|
588
|
+
|
|
589
|
+
This method ensures the jq expression checks both locations.
|
|
590
|
+
|
|
591
|
+
Args:
|
|
592
|
+
settings: The settings dictionary to update
|
|
593
|
+
"""
|
|
594
|
+
if "statusLine" not in settings:
|
|
595
|
+
return
|
|
596
|
+
|
|
597
|
+
status_line = settings.get("statusLine", {})
|
|
598
|
+
if "command" not in status_line:
|
|
599
|
+
return
|
|
600
|
+
|
|
601
|
+
command = status_line["command"]
|
|
602
|
+
|
|
603
|
+
# Pattern to match: '.output_style.name // "default"'
|
|
604
|
+
# We need to update it to: '.output_style.name // .activeOutputStyle // "default"'
|
|
605
|
+
old_pattern = r'\.output_style\.name\s*//\s*"default"'
|
|
606
|
+
new_pattern = '.output_style.name // .activeOutputStyle // "default"'
|
|
607
|
+
|
|
608
|
+
# Check if the command needs updating
|
|
609
|
+
if re.search(old_pattern, command) and ".activeOutputStyle" not in command:
|
|
610
|
+
updated_command = re.sub(old_pattern, new_pattern, command)
|
|
611
|
+
settings["statusLine"]["command"] = updated_command
|
|
612
|
+
self.logger.info(
|
|
613
|
+
"Fixed statusLine command to handle both output style schemas"
|
|
614
|
+
)
|
|
615
|
+
else:
|
|
616
|
+
self.logger.debug(
|
|
617
|
+
"StatusLine command already supports both schemas or not present"
|
|
618
|
+
)
|
|
619
|
+
|
|
620
|
+
def _update_claude_settings(self, hook_cmd: str) -> None:
|
|
621
|
+
"""Update Claude settings to use the installed hook.
|
|
622
|
+
|
|
623
|
+
Args:
|
|
624
|
+
hook_cmd: The hook command to use (either 'claude-hook' or path to bash script)
|
|
625
|
+
"""
|
|
490
626
|
self.logger.info("Updating Claude settings...")
|
|
491
627
|
|
|
492
628
|
# Load existing settings.json or create new
|
|
@@ -509,42 +645,107 @@ main "$@"
|
|
|
509
645
|
settings["hooks"] = {}
|
|
510
646
|
|
|
511
647
|
# Hook configuration for each event type
|
|
512
|
-
hook_command = {"type": "command", "command":
|
|
648
|
+
hook_command = {"type": "command", "command": hook_cmd}
|
|
649
|
+
|
|
650
|
+
def is_our_hook(cmd: dict) -> bool:
|
|
651
|
+
"""Check if a hook command belongs to claude-mpm."""
|
|
652
|
+
if cmd.get("type") != "command":
|
|
653
|
+
return False
|
|
654
|
+
command = cmd.get("command", "")
|
|
655
|
+
# Match claude-hook entry point or bash script fallback
|
|
656
|
+
return (
|
|
657
|
+
command == "claude-hook"
|
|
658
|
+
or "claude-hook-handler.sh" in command
|
|
659
|
+
or command.endswith("claude-mpm-hook.sh")
|
|
660
|
+
)
|
|
661
|
+
|
|
662
|
+
def merge_hooks_for_event(
|
|
663
|
+
existing_hooks: list, new_hook_command: dict, use_matcher: bool = True
|
|
664
|
+
) -> list:
|
|
665
|
+
"""Merge new hook command into existing hooks without duplication.
|
|
666
|
+
|
|
667
|
+
Args:
|
|
668
|
+
existing_hooks: Current hooks configuration for an event type
|
|
669
|
+
new_hook_command: The claude-mpm hook command to add
|
|
670
|
+
use_matcher: Whether to include matcher: "*" in the config
|
|
671
|
+
|
|
672
|
+
Returns:
|
|
673
|
+
Updated hooks list with our hook merged in
|
|
674
|
+
"""
|
|
675
|
+
# Check if our hook already exists in any existing hook config
|
|
676
|
+
our_hook_exists = False
|
|
677
|
+
|
|
678
|
+
for hook_config in existing_hooks:
|
|
679
|
+
if "hooks" in hook_config and isinstance(hook_config["hooks"], list):
|
|
680
|
+
for hook in hook_config["hooks"]:
|
|
681
|
+
if is_our_hook(hook):
|
|
682
|
+
# Update existing hook command path (in case it changed)
|
|
683
|
+
hook["command"] = new_hook_command["command"]
|
|
684
|
+
our_hook_exists = True
|
|
685
|
+
break
|
|
686
|
+
if our_hook_exists:
|
|
687
|
+
break
|
|
688
|
+
|
|
689
|
+
if our_hook_exists:
|
|
690
|
+
# Our hook already exists, just return the updated list
|
|
691
|
+
return existing_hooks
|
|
692
|
+
|
|
693
|
+
# Our hook doesn't exist - need to add it
|
|
694
|
+
# Strategy: Add our hook to the first "*" matcher config, or create new config
|
|
695
|
+
added = False
|
|
696
|
+
|
|
697
|
+
for hook_config in existing_hooks:
|
|
698
|
+
# Check if this config has matcher: "*" (or no matcher for simple events)
|
|
699
|
+
matcher = hook_config.get("matcher")
|
|
700
|
+
if matcher == "*" or (not use_matcher and matcher is None):
|
|
701
|
+
# Add our hook to this config's hooks array
|
|
702
|
+
if "hooks" not in hook_config:
|
|
703
|
+
hook_config["hooks"] = []
|
|
704
|
+
hook_config["hooks"].append(new_hook_command)
|
|
705
|
+
added = True
|
|
706
|
+
break
|
|
707
|
+
|
|
708
|
+
if not added:
|
|
709
|
+
# No suitable config found, create a new one
|
|
710
|
+
if use_matcher:
|
|
711
|
+
new_config = {"matcher": "*", "hooks": [new_hook_command]}
|
|
712
|
+
else:
|
|
713
|
+
new_config = {"hooks": [new_hook_command]}
|
|
714
|
+
existing_hooks.append(new_config)
|
|
715
|
+
|
|
716
|
+
return existing_hooks
|
|
513
717
|
|
|
514
718
|
# Tool-related events need a matcher string
|
|
515
719
|
tool_events = ["PreToolUse", "PostToolUse"]
|
|
516
720
|
for event_type in tool_events:
|
|
517
|
-
settings["hooks"]
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
}
|
|
522
|
-
]
|
|
721
|
+
existing = settings["hooks"].get(event_type, [])
|
|
722
|
+
settings["hooks"][event_type] = merge_hooks_for_event(
|
|
723
|
+
existing, hook_command, use_matcher=True
|
|
724
|
+
)
|
|
523
725
|
|
|
524
726
|
# Simple events (no subtypes, no matcher needed)
|
|
525
|
-
|
|
727
|
+
# Note: SubagentStart is NOT a valid Claude Code event (only SubagentStop is)
|
|
728
|
+
simple_events = ["Stop", "SubagentStop"]
|
|
526
729
|
for event_type in simple_events:
|
|
527
|
-
settings["hooks"]
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
]
|
|
730
|
+
existing = settings["hooks"].get(event_type, [])
|
|
731
|
+
settings["hooks"][event_type] = merge_hooks_for_event(
|
|
732
|
+
existing, hook_command, use_matcher=False
|
|
733
|
+
)
|
|
532
734
|
|
|
533
735
|
# SessionStart needs matcher for subtypes (startup, resume)
|
|
534
|
-
settings["hooks"]
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
}
|
|
539
|
-
]
|
|
736
|
+
existing = settings["hooks"].get("SessionStart", [])
|
|
737
|
+
settings["hooks"]["SessionStart"] = merge_hooks_for_event(
|
|
738
|
+
existing, hook_command, use_matcher=True
|
|
739
|
+
)
|
|
540
740
|
|
|
541
741
|
# UserPromptSubmit needs matcher for potential subtypes
|
|
542
|
-
settings["hooks"]
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
742
|
+
existing = settings["hooks"].get("UserPromptSubmit", [])
|
|
743
|
+
settings["hooks"]["UserPromptSubmit"] = merge_hooks_for_event(
|
|
744
|
+
existing, hook_command, use_matcher=True
|
|
745
|
+
)
|
|
746
|
+
|
|
747
|
+
# Fix statusLine command to handle both output style schemas
|
|
748
|
+
self._fix_status_line(settings)
|
|
548
749
|
|
|
549
750
|
# Write settings to settings.json
|
|
550
751
|
with self.settings_file.open("w") as f:
|
|
@@ -556,7 +757,22 @@ main "$@"
|
|
|
556
757
|
self._cleanup_old_settings()
|
|
557
758
|
|
|
558
759
|
def _install_commands(self) -> None:
|
|
559
|
-
"""Install custom commands for Claude Code.
|
|
760
|
+
"""Install custom commands for Claude Code.
|
|
761
|
+
|
|
762
|
+
For Claude Code >= 2.1.3, commands are deployed as skills via PMSkillsDeployerService.
|
|
763
|
+
This method provides backward compatibility for older versions.
|
|
764
|
+
"""
|
|
765
|
+
# Check if skills-based commands are supported
|
|
766
|
+
if self.supports_user_invocable_skills():
|
|
767
|
+
self.logger.info(
|
|
768
|
+
"Claude Code >= 2.1.3 detected. Commands deployed as skills - "
|
|
769
|
+
"skipping legacy command installation."
|
|
770
|
+
)
|
|
771
|
+
return
|
|
772
|
+
|
|
773
|
+
# Legacy installation for older Claude Code versions
|
|
774
|
+
self.logger.info("Installing legacy commands for Claude Code < 2.1.3")
|
|
775
|
+
|
|
560
776
|
# Find commands directory using proper resource resolution
|
|
561
777
|
try:
|
|
562
778
|
from ...core.unified_paths import get_package_resource_path
|
|
@@ -628,10 +844,10 @@ main "$@"
|
|
|
628
844
|
issues.append("No hooks configured in Claude settings")
|
|
629
845
|
else:
|
|
630
846
|
# Check for required event types
|
|
847
|
+
# Note: SubagentStart is NOT a valid Claude Code event
|
|
631
848
|
required_events = [
|
|
632
849
|
"Stop",
|
|
633
850
|
"SubagentStop",
|
|
634
|
-
"SubagentStart",
|
|
635
851
|
"PreToolUse",
|
|
636
852
|
"PostToolUse",
|
|
637
853
|
]
|
|
@@ -697,7 +913,8 @@ main "$@"
|
|
|
697
913
|
):
|
|
698
914
|
cmd = hook_cmd.get("command", "")
|
|
699
915
|
if (
|
|
700
|
-
"claude-hook
|
|
916
|
+
cmd == "claude-hook"
|
|
917
|
+
or "claude-hook-handler.sh" in cmd
|
|
701
918
|
or cmd.endswith("claude-mpm-hook.sh")
|
|
702
919
|
):
|
|
703
920
|
is_claude_mpm = True
|
|
@@ -742,27 +959,42 @@ main "$@"
|
|
|
742
959
|
|
|
743
960
|
is_valid, issues = self.verify_hooks()
|
|
744
961
|
|
|
745
|
-
# Try to get
|
|
962
|
+
# Try to get hook command (entry point or fallback script)
|
|
963
|
+
hook_command = None
|
|
964
|
+
using_entry_point = False
|
|
746
965
|
try:
|
|
747
|
-
|
|
966
|
+
hook_command = self.get_hook_command()
|
|
967
|
+
using_entry_point = hook_command == "claude-hook"
|
|
968
|
+
except FileNotFoundError:
|
|
969
|
+
hook_command = None
|
|
970
|
+
|
|
971
|
+
# For backward compatibility, also try to get the script path
|
|
972
|
+
hook_script_str = None
|
|
973
|
+
script_exists = False
|
|
974
|
+
try:
|
|
975
|
+
hook_script_path = self._get_hook_script_path()
|
|
748
976
|
hook_script_str = str(hook_script_path)
|
|
749
977
|
script_exists = hook_script_path.exists()
|
|
750
978
|
except FileNotFoundError:
|
|
751
|
-
|
|
752
|
-
script_exists = False
|
|
979
|
+
pass
|
|
753
980
|
|
|
754
981
|
status = {
|
|
755
|
-
"installed":
|
|
982
|
+
"installed": (hook_command is not None or script_exists)
|
|
983
|
+
and self.settings_file.exists(),
|
|
756
984
|
"valid": is_valid,
|
|
757
985
|
"issues": issues,
|
|
758
|
-
"
|
|
986
|
+
"hook_command": hook_command,
|
|
987
|
+
"hook_script": hook_script_str, # Kept for backward compatibility
|
|
988
|
+
"using_entry_point": using_entry_point,
|
|
759
989
|
"settings_file": (
|
|
760
990
|
str(self.settings_file) if self.settings_file.exists() else None
|
|
761
991
|
),
|
|
762
992
|
"claude_version": claude_version,
|
|
763
993
|
"version_compatible": is_compatible,
|
|
764
994
|
"version_message": version_message,
|
|
765
|
-
"deployment_type": "
|
|
995
|
+
"deployment_type": "entry-point"
|
|
996
|
+
if using_entry_point
|
|
997
|
+
else "deployment-root",
|
|
766
998
|
"pretool_modify_supported": pretool_modify_supported, # v2.0.30+ feature
|
|
767
999
|
"pretool_modify_message": (
|
|
768
1000
|
f"PreToolUse input modification supported (v{claude_version})"
|
|
@@ -782,7 +1014,7 @@ main "$@"
|
|
|
782
1014
|
if "hooks" in settings:
|
|
783
1015
|
status["configured_events"] = list(settings["hooks"].keys())
|
|
784
1016
|
configured_in_local = True
|
|
785
|
-
except Exception:
|
|
1017
|
+
except Exception: # nosec B110 - Intentional: ignore errors reading settings file
|
|
786
1018
|
pass
|
|
787
1019
|
|
|
788
1020
|
# Also check old settings file
|
|
@@ -796,7 +1028,7 @@ main "$@"
|
|
|
796
1028
|
status["warning"] = (
|
|
797
1029
|
"Hooks found in settings.local.json but Claude Code reads from settings.json"
|
|
798
1030
|
)
|
|
799
|
-
except Exception:
|
|
1031
|
+
except Exception: # nosec B110 - Intentional: ignore errors reading old settings file
|
|
800
1032
|
pass
|
|
801
1033
|
|
|
802
1034
|
status["settings_location"] = (
|
|
@@ -7,39 +7,67 @@ including pre and post delegation hooks.
|
|
|
7
7
|
|
|
8
8
|
import logging
|
|
9
9
|
import os
|
|
10
|
-
import
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
# Try to import _log from hook_handler, fall back to no-op
|
|
13
|
+
try:
|
|
14
|
+
from claude_mpm.hooks.claude_hooks.hook_handler import _log
|
|
15
|
+
except ImportError:
|
|
16
|
+
|
|
17
|
+
def _log(msg: str) -> None:
|
|
18
|
+
pass # Silent fallback
|
|
19
|
+
|
|
11
20
|
|
|
12
21
|
# Install-type-aware logging configuration BEFORE kuzu-memory imports
|
|
13
22
|
# This overrides kuzu-memory's WARNING-level basicConfig (fixes 1M-445)
|
|
14
|
-
# but respects production install silence
|
|
23
|
+
# but respects production install silence AND startup suppression
|
|
15
24
|
try:
|
|
16
25
|
from claude_mpm.core.unified_paths import DeploymentContext, PathContext
|
|
17
26
|
|
|
18
27
|
context = PathContext.detect_deployment_context()
|
|
19
28
|
|
|
29
|
+
# CRITICAL: Check if root logger is already suppressed (CRITICAL+1 from startup.py)
|
|
30
|
+
# If so, don't call basicConfig as it will reset the level to INFO
|
|
31
|
+
root_logger = logging.getLogger()
|
|
32
|
+
is_suppressed = root_logger.level > logging.CRITICAL # CRITICAL+1 = 51
|
|
33
|
+
|
|
20
34
|
# Only configure verbose logging for development/editable installs
|
|
21
|
-
#
|
|
22
|
-
if context in (
|
|
35
|
+
# AND if logging isn't already suppressed by startup.py
|
|
36
|
+
if not is_suppressed and context in (
|
|
37
|
+
DeploymentContext.DEVELOPMENT,
|
|
38
|
+
DeploymentContext.EDITABLE_INSTALL,
|
|
39
|
+
):
|
|
40
|
+
# Write logs to file instead of stderr to avoid hook errors
|
|
41
|
+
log_dir = Path.home() / ".claude-mpm"
|
|
42
|
+
log_dir.mkdir(parents=True, exist_ok=True)
|
|
43
|
+
log_file = log_dir / "hooks.log"
|
|
23
44
|
logging.basicConfig(
|
|
24
45
|
level=logging.INFO,
|
|
25
46
|
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
|
26
47
|
force=True, # Python 3.8+ - reconfigures root logger
|
|
27
|
-
|
|
48
|
+
filename=str(log_file),
|
|
28
49
|
)
|
|
29
50
|
except ImportError:
|
|
30
|
-
# Fallback: if unified_paths not available,
|
|
31
|
-
|
|
32
|
-
logging.
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
51
|
+
# Fallback: if unified_paths not available, check suppression before configuring
|
|
52
|
+
root_logger = logging.getLogger()
|
|
53
|
+
is_suppressed = root_logger.level > logging.CRITICAL
|
|
54
|
+
|
|
55
|
+
if not is_suppressed:
|
|
56
|
+
# Write logs to file instead of stderr to avoid hook errors
|
|
57
|
+
log_dir = Path.home() / ".claude-mpm"
|
|
58
|
+
log_dir.mkdir(parents=True, exist_ok=True)
|
|
59
|
+
log_file = log_dir / "hooks.log"
|
|
60
|
+
logging.basicConfig(
|
|
61
|
+
level=logging.INFO,
|
|
62
|
+
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
|
63
|
+
force=True,
|
|
64
|
+
filename=str(log_file),
|
|
65
|
+
)
|
|
38
66
|
from datetime import datetime, timezone
|
|
39
67
|
from typing import Optional
|
|
40
68
|
|
|
41
69
|
# Debug mode
|
|
42
|
-
DEBUG = os.environ.get("CLAUDE_MPM_HOOK_DEBUG", "
|
|
70
|
+
DEBUG = os.environ.get("CLAUDE_MPM_HOOK_DEBUG", "false").lower() == "true"
|
|
43
71
|
|
|
44
72
|
# Memory hooks integration
|
|
45
73
|
MEMORY_HOOKS_AVAILABLE = False
|
|
@@ -60,7 +88,7 @@ try:
|
|
|
60
88
|
except Exception as e:
|
|
61
89
|
# Catch all exceptions to prevent any import errors from breaking the handler
|
|
62
90
|
if DEBUG:
|
|
63
|
-
|
|
91
|
+
_log(f"Memory hooks not available: {e}")
|
|
64
92
|
MEMORY_HOOKS_AVAILABLE = False
|
|
65
93
|
|
|
66
94
|
|
|
@@ -94,10 +122,7 @@ class MemoryHookManager:
|
|
|
94
122
|
# Only initialize if memory system is enabled
|
|
95
123
|
if not config.get("memory.enabled", True):
|
|
96
124
|
if DEBUG:
|
|
97
|
-
|
|
98
|
-
"Memory system disabled - skipping hook initialization",
|
|
99
|
-
file=sys.stderr,
|
|
100
|
-
)
|
|
125
|
+
_log("Memory system disabled - skipping hook initialization")
|
|
101
126
|
return
|
|
102
127
|
|
|
103
128
|
# Initialize pre-delegation hook for memory injection
|
|
@@ -115,14 +140,11 @@ class MemoryHookManager:
|
|
|
115
140
|
hooks_info.append("pre-delegation")
|
|
116
141
|
if self.post_delegation_hook:
|
|
117
142
|
hooks_info.append("post-delegation")
|
|
118
|
-
|
|
119
|
-
f"✅ Memory hooks initialized: {', '.join(hooks_info)}",
|
|
120
|
-
file=sys.stderr,
|
|
121
|
-
)
|
|
143
|
+
_log(f"✅ Memory hooks initialized: {', '.join(hooks_info)}")
|
|
122
144
|
|
|
123
145
|
except Exception as e:
|
|
124
146
|
if DEBUG:
|
|
125
|
-
|
|
147
|
+
_log(f"❌ Failed to initialize memory hooks: {e}")
|
|
126
148
|
# Don't fail the entire handler - memory system is optional
|
|
127
149
|
|
|
128
150
|
def trigger_pre_delegation_hook(
|
|
@@ -171,14 +193,13 @@ class MemoryHookManager:
|
|
|
171
193
|
|
|
172
194
|
if DEBUG:
|
|
173
195
|
memory_size = len(memory_section.encode("utf-8"))
|
|
174
|
-
|
|
175
|
-
f"✅ Injected {memory_size} bytes of memory for agent '{agent_type}'"
|
|
176
|
-
file=sys.stderr,
|
|
196
|
+
_log(
|
|
197
|
+
f"✅ Injected {memory_size} bytes of memory for agent '{agent_type}'"
|
|
177
198
|
)
|
|
178
199
|
|
|
179
200
|
except Exception as e:
|
|
180
201
|
if DEBUG:
|
|
181
|
-
|
|
202
|
+
_log(f"❌ Memory pre-delegation hook failed: {e}")
|
|
182
203
|
# Don't fail the delegation - memory is optional
|
|
183
204
|
|
|
184
205
|
def trigger_post_delegation_hook(
|
|
@@ -238,12 +259,11 @@ class MemoryHookManager:
|
|
|
238
259
|
if result.success and result.metadata:
|
|
239
260
|
learnings_extracted = result.metadata.get("learnings_extracted", 0)
|
|
240
261
|
if learnings_extracted > 0 and DEBUG:
|
|
241
|
-
|
|
242
|
-
f"✅ Extracted {learnings_extracted} learnings for agent '{agent_type}'"
|
|
243
|
-
file=sys.stderr,
|
|
262
|
+
_log(
|
|
263
|
+
f"✅ Extracted {learnings_extracted} learnings for agent '{agent_type}'"
|
|
244
264
|
)
|
|
245
265
|
|
|
246
266
|
except Exception as e:
|
|
247
267
|
if DEBUG:
|
|
248
|
-
|
|
268
|
+
_log(f"❌ Memory post-delegation hook failed: {e}")
|
|
249
269
|
# Don't fail the delegation result - memory is optional
|