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
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""Daemon configuration for MPM Commander.
|
|
2
|
+
|
|
3
|
+
This module defines configuration structures for the Commander daemon,
|
|
4
|
+
including server settings, resource limits, and persistence options.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class DaemonConfig:
|
|
13
|
+
"""Configuration for Commander daemon.
|
|
14
|
+
|
|
15
|
+
Attributes:
|
|
16
|
+
host: API server bind address
|
|
17
|
+
port: API server port (default: 8766 from NetworkPorts.COMMANDER_DEFAULT)
|
|
18
|
+
log_level: Logging level (DEBUG, INFO, WARNING, ERROR)
|
|
19
|
+
state_dir: Directory for state persistence
|
|
20
|
+
max_projects: Maximum concurrent projects
|
|
21
|
+
healthcheck_interval: Healthcheck interval in seconds
|
|
22
|
+
save_interval: State persistence interval in seconds
|
|
23
|
+
poll_interval: Event polling interval in seconds
|
|
24
|
+
summarize_responses: Whether to use LLM to summarize instance responses
|
|
25
|
+
|
|
26
|
+
Example:
|
|
27
|
+
>>> config = DaemonConfig(port=8766, log_level="DEBUG")
|
|
28
|
+
>>> config.state_dir
|
|
29
|
+
PosixPath('/Users/user/.claude-mpm/commander')
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
host: str = "127.0.0.1"
|
|
33
|
+
port: int = 8766 # Default commander port (from network_config.NetworkPorts.COMMANDER_DEFAULT)
|
|
34
|
+
log_level: str = "INFO"
|
|
35
|
+
state_dir: Path = Path.home() / ".claude-mpm" / "commander"
|
|
36
|
+
max_projects: int = 10
|
|
37
|
+
healthcheck_interval: int = 30
|
|
38
|
+
save_interval: int = 30
|
|
39
|
+
poll_interval: float = 2.0
|
|
40
|
+
summarize_responses: bool = True
|
|
41
|
+
|
|
42
|
+
def __post_init__(self):
|
|
43
|
+
"""Ensure state_dir is a Path object and create if needed."""
|
|
44
|
+
if isinstance(self.state_dir, str):
|
|
45
|
+
self.state_dir = Path(self.state_dir)
|
|
46
|
+
|
|
47
|
+
# Expand user home directory
|
|
48
|
+
self.state_dir = self.state_dir.expanduser()
|
|
49
|
+
|
|
50
|
+
# Create state directory if it doesn't exist
|
|
51
|
+
self.state_dir.mkdir(parents=True, exist_ok=True)
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"""Project configuration loading for MPM Commander.
|
|
2
|
+
|
|
3
|
+
This module handles loading configuration from a project's .claude-mpm/
|
|
4
|
+
directory, including YAML config files and directory structure validation.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import logging
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import Any, Dict, Optional
|
|
10
|
+
|
|
11
|
+
import yaml
|
|
12
|
+
|
|
13
|
+
logger = logging.getLogger(__name__)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def load_project_config(project_path: str) -> Optional[Dict[str, Any]]:
|
|
17
|
+
"""Load configuration from project's .claude-mpm/ directory.
|
|
18
|
+
|
|
19
|
+
Looks for:
|
|
20
|
+
- .claude-mpm/configuration.yaml (main config file)
|
|
21
|
+
- .claude-mpm/agents/ (directory exists check)
|
|
22
|
+
- .claude-mpm/skills/ (directory exists check)
|
|
23
|
+
- .claude-mpm/memories/ (directory exists check)
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
project_path: Absolute path to project directory
|
|
27
|
+
|
|
28
|
+
Returns:
|
|
29
|
+
Dict with config data and directory flags, or None if no config found.
|
|
30
|
+
Example structure:
|
|
31
|
+
{
|
|
32
|
+
'configuration': {...}, # Parsed YAML config
|
|
33
|
+
'has_agents': True,
|
|
34
|
+
'has_skills': False,
|
|
35
|
+
'has_memories': True,
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
Raises:
|
|
39
|
+
yaml.YAMLError: If configuration.yaml is malformed
|
|
40
|
+
|
|
41
|
+
Example:
|
|
42
|
+
>>> config = load_project_config("/Users/masa/Projects/my-app")
|
|
43
|
+
>>> if config:
|
|
44
|
+
... print(f"Agents dir: {config['has_agents']}")
|
|
45
|
+
... print(f"Config: {config.get('configuration', {})}")
|
|
46
|
+
Agents dir: True
|
|
47
|
+
Config: {'default_adapter': 'linear', ...}
|
|
48
|
+
"""
|
|
49
|
+
proj_path = Path(project_path)
|
|
50
|
+
config_dir = proj_path / ".claude-mpm"
|
|
51
|
+
|
|
52
|
+
# Check if .claude-mpm/ directory exists
|
|
53
|
+
if not config_dir.exists() or not config_dir.is_dir():
|
|
54
|
+
logger.debug("No .claude-mpm/ directory found in project: %s", project_path)
|
|
55
|
+
return None
|
|
56
|
+
|
|
57
|
+
logger.info("Loading configuration from %s", config_dir)
|
|
58
|
+
|
|
59
|
+
result: Dict[str, Any] = {
|
|
60
|
+
"configuration": {},
|
|
61
|
+
"has_agents": False,
|
|
62
|
+
"has_skills": False,
|
|
63
|
+
"has_memories": False,
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
# Load configuration.yaml if present
|
|
67
|
+
config_file = config_dir / "configuration.yaml"
|
|
68
|
+
if config_file.exists() and config_file.is_file():
|
|
69
|
+
try:
|
|
70
|
+
with open(config_file, encoding="utf-8") as f:
|
|
71
|
+
config_data = yaml.safe_load(f)
|
|
72
|
+
result["configuration"] = config_data or {}
|
|
73
|
+
logger.info(
|
|
74
|
+
"Loaded configuration.yaml with %d top-level keys",
|
|
75
|
+
len(result["configuration"]),
|
|
76
|
+
)
|
|
77
|
+
except yaml.YAMLError as e:
|
|
78
|
+
logger.error(
|
|
79
|
+
"Failed to parse configuration.yaml in %s: %s",
|
|
80
|
+
config_dir,
|
|
81
|
+
e,
|
|
82
|
+
)
|
|
83
|
+
raise
|
|
84
|
+
except Exception as e:
|
|
85
|
+
logger.warning(
|
|
86
|
+
"Failed to read configuration.yaml in %s: %s",
|
|
87
|
+
config_dir,
|
|
88
|
+
e,
|
|
89
|
+
)
|
|
90
|
+
# Continue with empty config
|
|
91
|
+
|
|
92
|
+
# Check for subdirectories
|
|
93
|
+
agents_dir = config_dir / "agents"
|
|
94
|
+
result["has_agents"] = agents_dir.exists() and agents_dir.is_dir()
|
|
95
|
+
if result["has_agents"]:
|
|
96
|
+
logger.debug("Found agents directory: %s", agents_dir)
|
|
97
|
+
|
|
98
|
+
skills_dir = config_dir / "skills"
|
|
99
|
+
result["has_skills"] = skills_dir.exists() and skills_dir.is_dir()
|
|
100
|
+
if result["has_skills"]:
|
|
101
|
+
logger.debug("Found skills directory: %s", skills_dir)
|
|
102
|
+
|
|
103
|
+
memories_dir = config_dir / "memories"
|
|
104
|
+
result["has_memories"] = memories_dir.exists() and memories_dir.is_dir()
|
|
105
|
+
if result["has_memories"]:
|
|
106
|
+
logger.debug("Found memories directory: %s", memories_dir)
|
|
107
|
+
|
|
108
|
+
logger.info(
|
|
109
|
+
"Project config loaded: agents=%s, skills=%s, memories=%s",
|
|
110
|
+
result["has_agents"],
|
|
111
|
+
result["has_skills"],
|
|
112
|
+
result["has_memories"],
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
return result
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""Core coordination components for MPM Commander.
|
|
2
|
+
|
|
3
|
+
This module provides core components that coordinate between different
|
|
4
|
+
subsystems like events, work execution, and session management.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .block_manager import BlockManager
|
|
8
|
+
from .response_manager import ResponseManager, ResponseRoute
|
|
9
|
+
|
|
10
|
+
__all__ = ["BlockManager", "ResponseManager", "ResponseRoute"]
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
"""BlockManager for coordinating work blocking with events.
|
|
2
|
+
|
|
3
|
+
This module provides BlockManager which automatically blocks/unblocks
|
|
4
|
+
work items based on blocking event detection and resolution.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import logging
|
|
8
|
+
from typing import Dict, List, Optional, Set
|
|
9
|
+
|
|
10
|
+
from ..events.manager import EventManager
|
|
11
|
+
from ..models.events import Event
|
|
12
|
+
from ..models.work import WorkState
|
|
13
|
+
from ..work.executor import WorkExecutor
|
|
14
|
+
from ..work.queue import WorkQueue
|
|
15
|
+
|
|
16
|
+
logger = logging.getLogger(__name__)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class BlockManager:
|
|
20
|
+
"""Coordinates blocking events with work execution.
|
|
21
|
+
|
|
22
|
+
Monitors blocking events and automatically blocks/unblocks work items
|
|
23
|
+
based on event lifecycle. Tracks event-to-work relationships for precise
|
|
24
|
+
unblocking when events are resolved.
|
|
25
|
+
|
|
26
|
+
Attributes:
|
|
27
|
+
event_manager: EventManager for querying blocking events
|
|
28
|
+
work_queues: Dict mapping project_id -> WorkQueue
|
|
29
|
+
work_executors: Dict mapping project_id -> WorkExecutor
|
|
30
|
+
|
|
31
|
+
Example:
|
|
32
|
+
>>> manager = BlockManager(event_manager, work_queues, work_executors)
|
|
33
|
+
>>> blocked = await manager.check_and_block(event)
|
|
34
|
+
>>> unblocked = await manager.check_and_unblock(event_id)
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
def __init__(
|
|
38
|
+
self,
|
|
39
|
+
event_manager: EventManager,
|
|
40
|
+
work_queues: Dict[str, WorkQueue],
|
|
41
|
+
work_executors: Dict[str, WorkExecutor],
|
|
42
|
+
):
|
|
43
|
+
"""Initialize BlockManager.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
event_manager: EventManager instance
|
|
47
|
+
work_queues: Dict mapping project_id -> WorkQueue
|
|
48
|
+
work_executors: Dict mapping project_id -> WorkExecutor
|
|
49
|
+
|
|
50
|
+
Raises:
|
|
51
|
+
ValueError: If any required parameter is None
|
|
52
|
+
"""
|
|
53
|
+
if event_manager is None:
|
|
54
|
+
raise ValueError("EventManager cannot be None")
|
|
55
|
+
if work_queues is None:
|
|
56
|
+
raise ValueError("work_queues cannot be None")
|
|
57
|
+
if work_executors is None:
|
|
58
|
+
raise ValueError("work_executors cannot be None")
|
|
59
|
+
|
|
60
|
+
self.event_manager = event_manager
|
|
61
|
+
self.work_queues = work_queues
|
|
62
|
+
self.work_executors = work_executors
|
|
63
|
+
|
|
64
|
+
# Track event-to-work mapping: event_id -> set of work_ids
|
|
65
|
+
self._event_work_mapping: Dict[str, Set[str]] = {}
|
|
66
|
+
|
|
67
|
+
logger.debug("BlockManager initialized")
|
|
68
|
+
|
|
69
|
+
async def check_and_block(self, event: Event) -> List[str]:
|
|
70
|
+
"""Check if event is blocking and block affected work.
|
|
71
|
+
|
|
72
|
+
When a blocking event is detected:
|
|
73
|
+
1. Determine blocking scope (project or all)
|
|
74
|
+
2. Find all in-progress work items in scope
|
|
75
|
+
3. Block each work item via WorkExecutor
|
|
76
|
+
4. Track event-to-work mapping for later unblocking
|
|
77
|
+
|
|
78
|
+
Args:
|
|
79
|
+
event: Event to check for blocking
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
List of work item IDs that were blocked
|
|
83
|
+
|
|
84
|
+
Example:
|
|
85
|
+
>>> event = Event(type=EventType.ERROR, ...)
|
|
86
|
+
>>> blocked = await manager.check_and_block(event)
|
|
87
|
+
>>> print(f"Blocked {len(blocked)} work items")
|
|
88
|
+
"""
|
|
89
|
+
if not event.is_blocking:
|
|
90
|
+
logger.debug("Event %s is not blocking, no action needed", event.id)
|
|
91
|
+
return []
|
|
92
|
+
|
|
93
|
+
logger.info(
|
|
94
|
+
"Processing blocking event %s (scope: %s): %s",
|
|
95
|
+
event.id,
|
|
96
|
+
event.blocking_scope,
|
|
97
|
+
event.title,
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
blocked_work_ids = []
|
|
101
|
+
|
|
102
|
+
# Determine which projects to block based on scope
|
|
103
|
+
if event.blocking_scope == "all":
|
|
104
|
+
# Block all projects
|
|
105
|
+
target_projects = list(self.work_queues.keys())
|
|
106
|
+
logger.info("Event %s blocks ALL projects", event.id)
|
|
107
|
+
elif event.blocking_scope == "project":
|
|
108
|
+
# Block only this project
|
|
109
|
+
target_projects = [event.project_id]
|
|
110
|
+
logger.info("Event %s blocks project %s only", event.id, event.project_id)
|
|
111
|
+
else:
|
|
112
|
+
logger.warning(
|
|
113
|
+
"Unknown blocking scope '%s' for event %s",
|
|
114
|
+
event.blocking_scope,
|
|
115
|
+
event.id,
|
|
116
|
+
)
|
|
117
|
+
return []
|
|
118
|
+
|
|
119
|
+
# Block in-progress work in target projects
|
|
120
|
+
for project_id in target_projects:
|
|
121
|
+
queue = self.work_queues.get(project_id)
|
|
122
|
+
if not queue:
|
|
123
|
+
logger.debug("No work queue for project %s", project_id)
|
|
124
|
+
continue
|
|
125
|
+
|
|
126
|
+
executor = self.work_executors.get(project_id)
|
|
127
|
+
if not executor:
|
|
128
|
+
logger.debug("No work executor for project %s", project_id)
|
|
129
|
+
continue
|
|
130
|
+
|
|
131
|
+
# Get in-progress work items
|
|
132
|
+
in_progress = queue.list(WorkState.IN_PROGRESS)
|
|
133
|
+
|
|
134
|
+
for work_item in in_progress:
|
|
135
|
+
# Block the work item
|
|
136
|
+
block_reason = f"Event {event.id}: {event.title}"
|
|
137
|
+
success = await executor.handle_block(work_item.id, block_reason)
|
|
138
|
+
|
|
139
|
+
if success:
|
|
140
|
+
blocked_work_ids.append(work_item.id)
|
|
141
|
+
logger.info(
|
|
142
|
+
"Blocked work item %s for project %s: %s",
|
|
143
|
+
work_item.id,
|
|
144
|
+
project_id,
|
|
145
|
+
block_reason,
|
|
146
|
+
)
|
|
147
|
+
else:
|
|
148
|
+
logger.warning(
|
|
149
|
+
"Failed to block work item %s for project %s",
|
|
150
|
+
work_item.id,
|
|
151
|
+
project_id,
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
# Track event-to-work mapping
|
|
155
|
+
if blocked_work_ids:
|
|
156
|
+
self._event_work_mapping[event.id] = set(blocked_work_ids)
|
|
157
|
+
logger.info(
|
|
158
|
+
"Event %s blocked %d work items: %s",
|
|
159
|
+
event.id,
|
|
160
|
+
len(blocked_work_ids),
|
|
161
|
+
blocked_work_ids,
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
return blocked_work_ids
|
|
165
|
+
|
|
166
|
+
async def check_and_unblock(self, event_id: str) -> List[str]:
|
|
167
|
+
"""Unblock work items when event is resolved.
|
|
168
|
+
|
|
169
|
+
When a blocking event is resolved:
|
|
170
|
+
1. Look up which work items were blocked by this event
|
|
171
|
+
2. Unblock each work item via WorkExecutor
|
|
172
|
+
3. Remove event-to-work mapping
|
|
173
|
+
|
|
174
|
+
Args:
|
|
175
|
+
event_id: ID of resolved event
|
|
176
|
+
|
|
177
|
+
Returns:
|
|
178
|
+
List of work item IDs that were unblocked
|
|
179
|
+
|
|
180
|
+
Example:
|
|
181
|
+
>>> unblocked = await manager.check_and_unblock("evt_123")
|
|
182
|
+
>>> print(f"Unblocked {len(unblocked)} work items")
|
|
183
|
+
"""
|
|
184
|
+
# Get work items blocked by this event
|
|
185
|
+
work_ids = self._event_work_mapping.pop(event_id, set())
|
|
186
|
+
|
|
187
|
+
if not work_ids:
|
|
188
|
+
logger.debug("No work items blocked by event %s", event_id)
|
|
189
|
+
return []
|
|
190
|
+
|
|
191
|
+
logger.info(
|
|
192
|
+
"Unblocking %d work items for resolved event %s", len(work_ids), event_id
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
unblocked_work_ids = []
|
|
196
|
+
|
|
197
|
+
# Unblock each work item
|
|
198
|
+
for work_id in work_ids:
|
|
199
|
+
# Find which project this work belongs to
|
|
200
|
+
project_id = self._find_work_project(work_id)
|
|
201
|
+
if not project_id:
|
|
202
|
+
logger.warning("Cannot find project for work item %s", work_id)
|
|
203
|
+
continue
|
|
204
|
+
|
|
205
|
+
executor = self.work_executors.get(project_id)
|
|
206
|
+
if not executor:
|
|
207
|
+
logger.warning("No executor for project %s", project_id)
|
|
208
|
+
continue
|
|
209
|
+
|
|
210
|
+
# Unblock the work item
|
|
211
|
+
success = await executor.handle_unblock(work_id)
|
|
212
|
+
|
|
213
|
+
if success:
|
|
214
|
+
unblocked_work_ids.append(work_id)
|
|
215
|
+
logger.info("Unblocked work item %s", work_id)
|
|
216
|
+
else:
|
|
217
|
+
logger.warning("Failed to unblock work item %s", work_id)
|
|
218
|
+
|
|
219
|
+
return unblocked_work_ids
|
|
220
|
+
|
|
221
|
+
def _find_work_project(self, work_id: str) -> Optional[str]:
|
|
222
|
+
"""Find which project a work item belongs to.
|
|
223
|
+
|
|
224
|
+
Args:
|
|
225
|
+
work_id: Work item ID to search for
|
|
226
|
+
|
|
227
|
+
Returns:
|
|
228
|
+
Project ID if found, None otherwise
|
|
229
|
+
"""
|
|
230
|
+
for project_id, queue in self.work_queues.items():
|
|
231
|
+
work_item = queue.get(work_id)
|
|
232
|
+
if work_item:
|
|
233
|
+
return project_id
|
|
234
|
+
return None
|
|
235
|
+
|
|
236
|
+
def get_blocked_work(self, event_id: str) -> Set[str]:
|
|
237
|
+
"""Get work items blocked by a specific event.
|
|
238
|
+
|
|
239
|
+
Args:
|
|
240
|
+
event_id: Event ID to check
|
|
241
|
+
|
|
242
|
+
Returns:
|
|
243
|
+
Set of work item IDs blocked by this event
|
|
244
|
+
|
|
245
|
+
Example:
|
|
246
|
+
>>> work_ids = manager.get_blocked_work("evt_123")
|
|
247
|
+
"""
|
|
248
|
+
return self._event_work_mapping.get(event_id, set()).copy()
|
|
249
|
+
|
|
250
|
+
def get_blocking_events(self, work_id: str) -> List[str]:
|
|
251
|
+
"""Get events that are blocking a specific work item.
|
|
252
|
+
|
|
253
|
+
Args:
|
|
254
|
+
work_id: Work item ID to check
|
|
255
|
+
|
|
256
|
+
Returns:
|
|
257
|
+
List of event IDs blocking this work item
|
|
258
|
+
|
|
259
|
+
Example:
|
|
260
|
+
>>> events = manager.get_blocking_events("work-123")
|
|
261
|
+
"""
|
|
262
|
+
blocking_events = []
|
|
263
|
+
for event_id, work_ids in self._event_work_mapping.items():
|
|
264
|
+
if work_id in work_ids:
|
|
265
|
+
blocking_events.append(event_id)
|
|
266
|
+
return blocking_events
|
|
267
|
+
|
|
268
|
+
def is_work_blocked(self, work_id: str) -> bool:
|
|
269
|
+
"""Check if a work item is currently blocked.
|
|
270
|
+
|
|
271
|
+
Args:
|
|
272
|
+
work_id: Work item ID to check
|
|
273
|
+
|
|
274
|
+
Returns:
|
|
275
|
+
True if work item is blocked by any event, False otherwise
|
|
276
|
+
|
|
277
|
+
Example:
|
|
278
|
+
>>> if manager.is_work_blocked("work-123"):
|
|
279
|
+
... print("Work is blocked")
|
|
280
|
+
"""
|
|
281
|
+
return len(self.get_blocking_events(work_id)) > 0
|
|
282
|
+
|
|
283
|
+
def clear_project_mappings(self, project_id: str) -> int:
|
|
284
|
+
"""Clear all event-work mappings for a project.
|
|
285
|
+
|
|
286
|
+
Called when a project is shut down or reset.
|
|
287
|
+
|
|
288
|
+
Args:
|
|
289
|
+
project_id: Project ID to clear
|
|
290
|
+
|
|
291
|
+
Returns:
|
|
292
|
+
Number of work items that had mappings removed
|
|
293
|
+
|
|
294
|
+
Example:
|
|
295
|
+
>>> count = manager.clear_project_mappings("proj_123")
|
|
296
|
+
"""
|
|
297
|
+
queue = self.work_queues.get(project_id)
|
|
298
|
+
if not queue:
|
|
299
|
+
return 0
|
|
300
|
+
|
|
301
|
+
# Get all work IDs for this project
|
|
302
|
+
all_work = queue.list()
|
|
303
|
+
project_work_ids = {w.id for w in all_work}
|
|
304
|
+
|
|
305
|
+
removed_count = 0
|
|
306
|
+
|
|
307
|
+
# Remove work items from event mappings
|
|
308
|
+
for event_id in list(self._event_work_mapping.keys()):
|
|
309
|
+
work_ids = self._event_work_mapping[event_id]
|
|
310
|
+
original_len = len(work_ids)
|
|
311
|
+
|
|
312
|
+
# Remove project work items
|
|
313
|
+
work_ids.difference_update(project_work_ids)
|
|
314
|
+
|
|
315
|
+
removed_count += original_len - len(work_ids)
|
|
316
|
+
|
|
317
|
+
# Remove empty mappings
|
|
318
|
+
if not work_ids:
|
|
319
|
+
del self._event_work_mapping[event_id]
|
|
320
|
+
|
|
321
|
+
logger.info(
|
|
322
|
+
"Cleared %d work item mappings for project %s", removed_count, project_id
|
|
323
|
+
)
|
|
324
|
+
|
|
325
|
+
return removed_count
|