claude-mpm 5.4.41__py3-none-any.whl → 5.6.23__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of claude-mpm might be problematic. Click here for more details.
- claude_mpm/VERSION +1 -1
- claude_mpm/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/cli/__init__.py +5 -1
- claude_mpm/cli/commands/agents.py +2 -4
- claude_mpm/cli/commands/agents_reconcile.py +197 -0
- claude_mpm/cli/commands/autotodos.py +566 -0
- claude_mpm/cli/commands/commander.py +216 -0
- claude_mpm/cli/commands/configure.py +620 -21
- claude_mpm/cli/commands/configure_agent_display.py +3 -1
- claude_mpm/cli/commands/hook_errors.py +60 -60
- claude_mpm/cli/commands/monitor.py +2 -2
- claude_mpm/cli/commands/mpm_init/core.py +15 -8
- claude_mpm/cli/commands/profile.py +9 -10
- claude_mpm/cli/commands/run.py +35 -3
- claude_mpm/cli/commands/skill_source.py +51 -2
- claude_mpm/cli/commands/skills.py +182 -32
- claude_mpm/cli/executor.py +120 -16
- claude_mpm/cli/interactive/__init__.py +10 -0
- claude_mpm/cli/interactive/agent_wizard.py +30 -50
- claude_mpm/cli/interactive/questionary_styles.py +65 -0
- claude_mpm/cli/interactive/skill_selector.py +481 -0
- claude_mpm/cli/parsers/base_parser.py +76 -1
- claude_mpm/cli/parsers/commander_parser.py +116 -0
- claude_mpm/cli/parsers/profile_parser.py +0 -1
- claude_mpm/cli/parsers/run_parser.py +10 -0
- claude_mpm/cli/parsers/skill_source_parser.py +4 -0
- claude_mpm/cli/parsers/skills_parser.py +2 -3
- claude_mpm/cli/startup.py +527 -506
- claude_mpm/cli/startup_display.py +74 -6
- claude_mpm/cli/startup_logging.py +2 -2
- claude_mpm/cli/utils.py +7 -3
- claude_mpm/commander/__init__.py +78 -0
- claude_mpm/commander/adapters/__init__.py +60 -0
- claude_mpm/commander/adapters/auggie.py +260 -0
- claude_mpm/commander/adapters/base.py +288 -0
- claude_mpm/commander/adapters/claude_code.py +392 -0
- claude_mpm/commander/adapters/codex.py +237 -0
- claude_mpm/commander/adapters/communication.py +366 -0
- claude_mpm/commander/adapters/example_usage.py +310 -0
- claude_mpm/commander/adapters/mpm.py +389 -0
- claude_mpm/commander/adapters/registry.py +204 -0
- claude_mpm/commander/api/__init__.py +16 -0
- claude_mpm/commander/api/app.py +121 -0
- claude_mpm/commander/api/errors.py +133 -0
- claude_mpm/commander/api/routes/__init__.py +8 -0
- claude_mpm/commander/api/routes/events.py +184 -0
- claude_mpm/commander/api/routes/inbox.py +171 -0
- claude_mpm/commander/api/routes/messages.py +148 -0
- claude_mpm/commander/api/routes/projects.py +271 -0
- claude_mpm/commander/api/routes/sessions.py +226 -0
- claude_mpm/commander/api/routes/work.py +296 -0
- claude_mpm/commander/api/schemas.py +186 -0
- claude_mpm/commander/chat/__init__.py +7 -0
- claude_mpm/commander/chat/cli.py +146 -0
- claude_mpm/commander/chat/commands.py +96 -0
- claude_mpm/commander/chat/repl.py +310 -0
- claude_mpm/commander/config.py +51 -0
- claude_mpm/commander/config_loader.py +115 -0
- claude_mpm/commander/core/__init__.py +10 -0
- claude_mpm/commander/core/block_manager.py +325 -0
- claude_mpm/commander/core/response_manager.py +323 -0
- claude_mpm/commander/daemon.py +603 -0
- claude_mpm/commander/env_loader.py +59 -0
- claude_mpm/commander/events/__init__.py +26 -0
- claude_mpm/commander/events/manager.py +332 -0
- claude_mpm/commander/frameworks/__init__.py +12 -0
- claude_mpm/commander/frameworks/base.py +146 -0
- claude_mpm/commander/frameworks/claude_code.py +58 -0
- claude_mpm/commander/frameworks/mpm.py +62 -0
- claude_mpm/commander/inbox/__init__.py +16 -0
- claude_mpm/commander/inbox/dedup.py +128 -0
- claude_mpm/commander/inbox/inbox.py +224 -0
- claude_mpm/commander/inbox/models.py +70 -0
- claude_mpm/commander/instance_manager.py +450 -0
- claude_mpm/commander/llm/__init__.py +6 -0
- claude_mpm/commander/llm/openrouter_client.py +167 -0
- claude_mpm/commander/llm/summarizer.py +70 -0
- claude_mpm/commander/memory/__init__.py +45 -0
- claude_mpm/commander/memory/compression.py +347 -0
- claude_mpm/commander/memory/embeddings.py +230 -0
- claude_mpm/commander/memory/entities.py +310 -0
- claude_mpm/commander/memory/example_usage.py +290 -0
- claude_mpm/commander/memory/integration.py +325 -0
- claude_mpm/commander/memory/search.py +381 -0
- claude_mpm/commander/memory/store.py +657 -0
- claude_mpm/commander/models/__init__.py +18 -0
- claude_mpm/commander/models/events.py +121 -0
- claude_mpm/commander/models/project.py +162 -0
- claude_mpm/commander/models/work.py +214 -0
- claude_mpm/commander/parsing/__init__.py +20 -0
- claude_mpm/commander/parsing/extractor.py +132 -0
- claude_mpm/commander/parsing/output_parser.py +270 -0
- claude_mpm/commander/parsing/patterns.py +100 -0
- claude_mpm/commander/persistence/__init__.py +11 -0
- claude_mpm/commander/persistence/event_store.py +274 -0
- claude_mpm/commander/persistence/state_store.py +309 -0
- claude_mpm/commander/persistence/work_store.py +164 -0
- claude_mpm/commander/polling/__init__.py +13 -0
- claude_mpm/commander/polling/event_detector.py +104 -0
- claude_mpm/commander/polling/output_buffer.py +49 -0
- claude_mpm/commander/polling/output_poller.py +153 -0
- claude_mpm/commander/project_session.py +268 -0
- claude_mpm/commander/proxy/__init__.py +12 -0
- claude_mpm/commander/proxy/formatter.py +89 -0
- claude_mpm/commander/proxy/output_handler.py +191 -0
- claude_mpm/commander/proxy/relay.py +155 -0
- claude_mpm/commander/registry.py +410 -0
- claude_mpm/commander/runtime/__init__.py +10 -0
- claude_mpm/commander/runtime/executor.py +191 -0
- claude_mpm/commander/runtime/monitor.py +346 -0
- claude_mpm/commander/session/__init__.py +6 -0
- claude_mpm/commander/session/context.py +81 -0
- claude_mpm/commander/session/manager.py +59 -0
- claude_mpm/commander/tmux_orchestrator.py +361 -0
- claude_mpm/commander/web/__init__.py +1 -0
- claude_mpm/commander/work/__init__.py +30 -0
- claude_mpm/commander/work/executor.py +207 -0
- claude_mpm/commander/work/queue.py +405 -0
- claude_mpm/commander/workflow/__init__.py +27 -0
- claude_mpm/commander/workflow/event_handler.py +241 -0
- claude_mpm/commander/workflow/notifier.py +146 -0
- claude_mpm/commands/mpm-config.md +8 -0
- claude_mpm/commands/mpm-doctor.md +8 -0
- claude_mpm/commands/mpm-help.md +8 -0
- claude_mpm/commands/mpm-init.md +8 -0
- claude_mpm/commands/mpm-monitor.md +8 -0
- claude_mpm/commands/mpm-organize.md +8 -0
- claude_mpm/commands/mpm-postmortem.md +8 -0
- claude_mpm/commands/mpm-session-resume.md +9 -1
- claude_mpm/commands/mpm-status.md +8 -0
- claude_mpm/commands/mpm-ticket-view.md +8 -0
- claude_mpm/commands/mpm-version.md +8 -0
- claude_mpm/commands/mpm.md +8 -0
- claude_mpm/config/agent_presets.py +8 -7
- claude_mpm/config/skill_sources.py +16 -0
- claude_mpm/constants.py +1 -0
- claude_mpm/core/claude_runner.py +154 -2
- claude_mpm/core/config.py +35 -22
- claude_mpm/core/config_constants.py +74 -9
- claude_mpm/core/constants.py +56 -12
- claude_mpm/core/hook_manager.py +51 -3
- claude_mpm/core/interactive_session.py +12 -11
- claude_mpm/core/logger.py +26 -9
- claude_mpm/core/logging_utils.py +35 -11
- 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 +63 -18
- claude_mpm/core/shared/config_loader.py +3 -1
- claude_mpm/core/socketio_pool.py +13 -5
- 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 +305 -87
- claude_mpm/hooks/claude_hooks/hook_handler.py +106 -89
- claude_mpm/hooks/claude_hooks/hook_wrapper.sh +6 -11
- claude_mpm/hooks/claude_hooks/installer.py +116 -8
- claude_mpm/hooks/claude_hooks/memory_integration.py +51 -31
- claude_mpm/hooks/claude_hooks/response_tracking.py +42 -59
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.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 +39 -24
- claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +36 -103
- claude_mpm/hooks/claude_hooks/services/state_manager.py +23 -36
- claude_mpm/hooks/claude_hooks/services/subagent_processor.py +73 -75
- claude_mpm/hooks/kuzu_memory_hook.py +5 -5
- claude_mpm/hooks/session_resume_hook.py +89 -1
- claude_mpm/hooks/templates/pre_tool_use_template.py +10 -2
- claude_mpm/init.py +215 -2
- claude_mpm/scripts/claude-hook-handler.sh +43 -16
- 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/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/infrastructure/__init__.py +4 -0
- claude_mpm/services/infrastructure/context_usage_tracker.py +291 -0
- claude_mpm/services/infrastructure/resume_log_generator.py +24 -5
- claude_mpm/services/monitor/daemon_manager.py +15 -4
- claude_mpm/services/monitor/management/lifecycle.py +8 -3
- claude_mpm/services/monitor/server.py +106 -16
- claude_mpm/services/pm_skills_deployer.py +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.23.dist-info/METADATA +393 -0
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.23.dist-info}/RECORD +447 -149
- 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.23.dist-info}/WHEEL +0 -0
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.23.dist-info}/entry_points.txt +0 -0
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.23.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.23.dist-info}/licenses/LICENSE-FAQ.md +0 -0
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.23.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
"""EventManager for MPM Commander inbox system.
|
|
2
|
+
|
|
3
|
+
Manages event lifecycle, inbox queries, and project event tracking.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import logging
|
|
7
|
+
import threading
|
|
8
|
+
import uuid
|
|
9
|
+
from datetime import datetime, timezone
|
|
10
|
+
from typing import Any, Dict, List, Optional
|
|
11
|
+
|
|
12
|
+
from ..models.events import (
|
|
13
|
+
DEFAULT_PRIORITIES,
|
|
14
|
+
Event,
|
|
15
|
+
EventPriority,
|
|
16
|
+
EventStatus,
|
|
17
|
+
EventType,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
logger = logging.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class EventManager:
|
|
24
|
+
"""Manages event lifecycle and inbox queries.
|
|
25
|
+
|
|
26
|
+
Thread-safe event storage with support for:
|
|
27
|
+
- Creating events with automatic priority assignment
|
|
28
|
+
- Querying pending events by project or globally
|
|
29
|
+
- Inbox sorting by priority then timestamp
|
|
30
|
+
- Responding to, acknowledging, or dismissing events
|
|
31
|
+
- Detecting blocking events
|
|
32
|
+
- Clearing project events
|
|
33
|
+
|
|
34
|
+
Example:
|
|
35
|
+
manager = EventManager()
|
|
36
|
+
event = manager.create(
|
|
37
|
+
project_id="proj_123",
|
|
38
|
+
event_type=EventType.DECISION_NEEDED,
|
|
39
|
+
title="Choose deployment target",
|
|
40
|
+
options=["staging", "production"]
|
|
41
|
+
)
|
|
42
|
+
inbox = manager.get_inbox()
|
|
43
|
+
manager.respond(event.id, "staging")
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
def __init__(self) -> None:
|
|
47
|
+
"""Initialize empty event storage."""
|
|
48
|
+
self._events: Dict[str, Event] = {}
|
|
49
|
+
self._project_index: Dict[str, List[str]] = {} # project_id -> event_ids
|
|
50
|
+
self._lock = threading.RLock()
|
|
51
|
+
|
|
52
|
+
def create(
|
|
53
|
+
self,
|
|
54
|
+
project_id: str,
|
|
55
|
+
event_type: EventType,
|
|
56
|
+
title: str,
|
|
57
|
+
content: str = "",
|
|
58
|
+
session_id: Optional[str] = None,
|
|
59
|
+
priority: Optional[EventPriority] = None,
|
|
60
|
+
options: Optional[List[str]] = None,
|
|
61
|
+
context: Optional[Dict[str, Any]] = None,
|
|
62
|
+
) -> Event:
|
|
63
|
+
"""Create and queue a new event.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
project_id: ID of project raising this event
|
|
67
|
+
event_type: Type of event
|
|
68
|
+
title: Short summary
|
|
69
|
+
content: Detailed description
|
|
70
|
+
session_id: Optional session ID
|
|
71
|
+
priority: Optional priority (uses default if not specified)
|
|
72
|
+
options: For DECISION_NEEDED, list of choices
|
|
73
|
+
context: Additional structured data
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
The created Event
|
|
77
|
+
|
|
78
|
+
Example:
|
|
79
|
+
event = manager.create(
|
|
80
|
+
project_id="proj_123",
|
|
81
|
+
event_type=EventType.ERROR,
|
|
82
|
+
title="Database connection failed",
|
|
83
|
+
content="Could not connect to postgres://..."
|
|
84
|
+
)
|
|
85
|
+
"""
|
|
86
|
+
with self._lock:
|
|
87
|
+
event_id = f"evt_{uuid.uuid4().hex[:12]}"
|
|
88
|
+
|
|
89
|
+
# Use default priority if not specified
|
|
90
|
+
if priority is None:
|
|
91
|
+
priority = DEFAULT_PRIORITIES.get(event_type, EventPriority.NORMAL)
|
|
92
|
+
|
|
93
|
+
event = Event(
|
|
94
|
+
id=event_id,
|
|
95
|
+
project_id=project_id,
|
|
96
|
+
session_id=session_id,
|
|
97
|
+
type=event_type,
|
|
98
|
+
priority=priority,
|
|
99
|
+
title=title,
|
|
100
|
+
content=content,
|
|
101
|
+
context=context or {},
|
|
102
|
+
options=options,
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
self._events[event_id] = event
|
|
106
|
+
|
|
107
|
+
# Index by project
|
|
108
|
+
if project_id not in self._project_index:
|
|
109
|
+
self._project_index[project_id] = []
|
|
110
|
+
self._project_index[project_id].append(event_id)
|
|
111
|
+
|
|
112
|
+
logger.info("Created event %s: [%s] %s", event_id, event_type.value, title)
|
|
113
|
+
return event
|
|
114
|
+
|
|
115
|
+
def add_event(self, event: Event) -> None:
|
|
116
|
+
"""Add existing event to manager (for loading from persistence).
|
|
117
|
+
|
|
118
|
+
Args:
|
|
119
|
+
event: Event instance to add
|
|
120
|
+
|
|
121
|
+
Example:
|
|
122
|
+
# Load events from disk and add to manager
|
|
123
|
+
for event in loaded_events:
|
|
124
|
+
manager.add_event(event)
|
|
125
|
+
"""
|
|
126
|
+
with self._lock:
|
|
127
|
+
self._events[event.id] = event
|
|
128
|
+
|
|
129
|
+
# Index by project
|
|
130
|
+
if event.project_id not in self._project_index:
|
|
131
|
+
self._project_index[event.project_id] = []
|
|
132
|
+
if event.id not in self._project_index[event.project_id]:
|
|
133
|
+
self._project_index[event.project_id].append(event.id)
|
|
134
|
+
|
|
135
|
+
logger.debug("Added event %s to manager", event.id)
|
|
136
|
+
|
|
137
|
+
def get(self, event_id: str) -> Optional[Event]:
|
|
138
|
+
"""Get event by ID.
|
|
139
|
+
|
|
140
|
+
Args:
|
|
141
|
+
event_id: Unique event identifier
|
|
142
|
+
|
|
143
|
+
Returns:
|
|
144
|
+
Event if found, None otherwise
|
|
145
|
+
"""
|
|
146
|
+
return self._events.get(event_id)
|
|
147
|
+
|
|
148
|
+
def get_pending(self, project_id: Optional[str] = None) -> List[Event]:
|
|
149
|
+
"""Get all pending events, optionally filtered by project.
|
|
150
|
+
|
|
151
|
+
Args:
|
|
152
|
+
project_id: If provided, only return events for this project
|
|
153
|
+
|
|
154
|
+
Returns:
|
|
155
|
+
List of pending events (unsorted)
|
|
156
|
+
|
|
157
|
+
Example:
|
|
158
|
+
# Get all pending events
|
|
159
|
+
all_pending = manager.get_pending()
|
|
160
|
+
|
|
161
|
+
# Get pending events for one project
|
|
162
|
+
project_pending = manager.get_pending("proj_123")
|
|
163
|
+
"""
|
|
164
|
+
with self._lock:
|
|
165
|
+
if project_id:
|
|
166
|
+
event_ids = self._project_index.get(project_id, [])
|
|
167
|
+
events = [self._events[eid] for eid in event_ids if eid in self._events]
|
|
168
|
+
else:
|
|
169
|
+
events = list(self._events.values())
|
|
170
|
+
|
|
171
|
+
return [e for e in events if e.status == EventStatus.PENDING]
|
|
172
|
+
|
|
173
|
+
def get_inbox(self, limit: int = 50) -> List[Event]:
|
|
174
|
+
"""Get events for inbox, sorted by priority then time.
|
|
175
|
+
|
|
176
|
+
Sorting order:
|
|
177
|
+
1. Priority: CRITICAL > HIGH > NORMAL > LOW > INFO
|
|
178
|
+
2. Within same priority: oldest first (created_at ascending)
|
|
179
|
+
|
|
180
|
+
Args:
|
|
181
|
+
limit: Maximum number of events to return
|
|
182
|
+
|
|
183
|
+
Returns:
|
|
184
|
+
Sorted list of pending events, limited to `limit` items
|
|
185
|
+
|
|
186
|
+
Example:
|
|
187
|
+
inbox = manager.get_inbox(limit=20)
|
|
188
|
+
for event in inbox:
|
|
189
|
+
print(f"{event.priority.value}: {event.title}")
|
|
190
|
+
"""
|
|
191
|
+
with self._lock:
|
|
192
|
+
pending = [
|
|
193
|
+
e for e in self._events.values() if e.status == EventStatus.PENDING
|
|
194
|
+
]
|
|
195
|
+
|
|
196
|
+
# Sort by priority (CRITICAL first) then by created_at (oldest first)
|
|
197
|
+
priority_order = [
|
|
198
|
+
EventPriority.CRITICAL,
|
|
199
|
+
EventPriority.HIGH,
|
|
200
|
+
EventPriority.NORMAL,
|
|
201
|
+
EventPriority.LOW,
|
|
202
|
+
EventPriority.INFO,
|
|
203
|
+
]
|
|
204
|
+
|
|
205
|
+
def sort_key(event: Event) -> tuple[int, datetime]:
|
|
206
|
+
pri_idx = (
|
|
207
|
+
priority_order.index(event.priority)
|
|
208
|
+
if event.priority in priority_order
|
|
209
|
+
else 99
|
|
210
|
+
)
|
|
211
|
+
return (pri_idx, event.created_at)
|
|
212
|
+
|
|
213
|
+
sorted_events = sorted(pending, key=sort_key)
|
|
214
|
+
return sorted_events[:limit]
|
|
215
|
+
|
|
216
|
+
def respond(self, event_id: str, response: str) -> Event:
|
|
217
|
+
"""Record response to event and mark as resolved.
|
|
218
|
+
|
|
219
|
+
Args:
|
|
220
|
+
event_id: ID of event to respond to
|
|
221
|
+
response: User's response text
|
|
222
|
+
|
|
223
|
+
Returns:
|
|
224
|
+
The updated Event
|
|
225
|
+
|
|
226
|
+
Raises:
|
|
227
|
+
KeyError: If event_id not found
|
|
228
|
+
|
|
229
|
+
Example:
|
|
230
|
+
event = manager.respond("evt_abc123", "Deploy to staging")
|
|
231
|
+
"""
|
|
232
|
+
with self._lock:
|
|
233
|
+
event = self._events.get(event_id)
|
|
234
|
+
if not event:
|
|
235
|
+
raise KeyError(f"Event not found: {event_id}")
|
|
236
|
+
|
|
237
|
+
event.response = response
|
|
238
|
+
event.responded_at = datetime.now(timezone.utc)
|
|
239
|
+
event.status = EventStatus.RESOLVED
|
|
240
|
+
|
|
241
|
+
logger.info("Responded to event %s: %s", event_id, response[:50])
|
|
242
|
+
return event
|
|
243
|
+
|
|
244
|
+
def dismiss(self, event_id: str) -> Event:
|
|
245
|
+
"""Mark event as dismissed without providing a response.
|
|
246
|
+
|
|
247
|
+
Args:
|
|
248
|
+
event_id: ID of event to dismiss
|
|
249
|
+
|
|
250
|
+
Returns:
|
|
251
|
+
The updated Event
|
|
252
|
+
|
|
253
|
+
Raises:
|
|
254
|
+
KeyError: If event_id not found
|
|
255
|
+
|
|
256
|
+
Example:
|
|
257
|
+
manager.dismiss("evt_abc123")
|
|
258
|
+
"""
|
|
259
|
+
with self._lock:
|
|
260
|
+
event = self._events.get(event_id)
|
|
261
|
+
if not event:
|
|
262
|
+
raise KeyError(f"Event not found: {event_id}")
|
|
263
|
+
|
|
264
|
+
event.status = EventStatus.DISMISSED
|
|
265
|
+
|
|
266
|
+
logger.info("Dismissed event %s", event_id)
|
|
267
|
+
return event
|
|
268
|
+
|
|
269
|
+
def acknowledge(self, event_id: str) -> Event:
|
|
270
|
+
"""Mark event as seen but not resolved yet.
|
|
271
|
+
|
|
272
|
+
Args:
|
|
273
|
+
event_id: ID of event to acknowledge
|
|
274
|
+
|
|
275
|
+
Returns:
|
|
276
|
+
The updated Event
|
|
277
|
+
|
|
278
|
+
Raises:
|
|
279
|
+
KeyError: If event_id not found
|
|
280
|
+
|
|
281
|
+
Example:
|
|
282
|
+
manager.acknowledge("evt_abc123")
|
|
283
|
+
"""
|
|
284
|
+
with self._lock:
|
|
285
|
+
event = self._events.get(event_id)
|
|
286
|
+
if not event:
|
|
287
|
+
raise KeyError(f"Event not found: {event_id}")
|
|
288
|
+
|
|
289
|
+
event.status = EventStatus.ACKNOWLEDGED
|
|
290
|
+
|
|
291
|
+
logger.info("Acknowledged event %s", event_id)
|
|
292
|
+
return event
|
|
293
|
+
|
|
294
|
+
def get_blocking_events(self, project_id: Optional[str] = None) -> List[Event]:
|
|
295
|
+
"""Get events that are blocking progress.
|
|
296
|
+
|
|
297
|
+
Args:
|
|
298
|
+
project_id: If provided, include project-scoped blocking events
|
|
299
|
+
for this project. Always includes global blocking events.
|
|
300
|
+
|
|
301
|
+
Returns:
|
|
302
|
+
List of blocking events
|
|
303
|
+
|
|
304
|
+
Example:
|
|
305
|
+
# Get all blocking events (global scope only)
|
|
306
|
+
blockers = manager.get_blocking_events()
|
|
307
|
+
|
|
308
|
+
# Get blocking events for specific project (global + project scope)
|
|
309
|
+
blockers = manager.get_blocking_events("proj_123")
|
|
310
|
+
"""
|
|
311
|
+
with self._lock:
|
|
312
|
+
pending = self.get_pending(project_id)
|
|
313
|
+
return [e for e in pending if e.is_blocking]
|
|
314
|
+
|
|
315
|
+
def clear_project_events(self, project_id: str) -> int:
|
|
316
|
+
"""Clear all events for a project.
|
|
317
|
+
|
|
318
|
+
Args:
|
|
319
|
+
project_id: ID of project whose events should be cleared
|
|
320
|
+
|
|
321
|
+
Returns:
|
|
322
|
+
Number of events removed
|
|
323
|
+
|
|
324
|
+
Example:
|
|
325
|
+
removed = manager.clear_project_events("proj_123")
|
|
326
|
+
print(f"Cleared {removed} events")
|
|
327
|
+
"""
|
|
328
|
+
with self._lock:
|
|
329
|
+
event_ids = self._project_index.pop(project_id, [])
|
|
330
|
+
for eid in event_ids:
|
|
331
|
+
self._events.pop(eid, None)
|
|
332
|
+
return len(event_ids)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""Framework abstractions for AI coding assistants."""
|
|
2
|
+
|
|
3
|
+
from .base import BaseFramework, InstanceInfo
|
|
4
|
+
from .claude_code import ClaudeCodeFramework
|
|
5
|
+
from .mpm import MPMFramework
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
"BaseFramework",
|
|
9
|
+
"ClaudeCodeFramework",
|
|
10
|
+
"InstanceInfo",
|
|
11
|
+
"MPMFramework",
|
|
12
|
+
]
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"""Base framework abstraction for different AI coding assistants."""
|
|
2
|
+
|
|
3
|
+
import subprocess # nosec B404 - Required for git operations
|
|
4
|
+
from abc import ABC, abstractmethod
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Optional
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dataclass
|
|
11
|
+
class InstanceInfo:
|
|
12
|
+
"""Information about a running framework instance.
|
|
13
|
+
|
|
14
|
+
Attributes:
|
|
15
|
+
name: Instance name (e.g., "myapp")
|
|
16
|
+
project_path: Path to project directory
|
|
17
|
+
framework: Framework identifier (e.g., "cc", "mpm")
|
|
18
|
+
tmux_session: Tmux session name
|
|
19
|
+
pane_target: Tmux pane target (e.g., "%1")
|
|
20
|
+
git_branch: Current git branch if project is a git repo
|
|
21
|
+
git_status: Git status summary if project is a git repo
|
|
22
|
+
connected: Whether instance has an active adapter connection
|
|
23
|
+
|
|
24
|
+
Example:
|
|
25
|
+
>>> info = InstanceInfo(
|
|
26
|
+
... name="myapp",
|
|
27
|
+
... project_path=Path("/Users/user/myapp"),
|
|
28
|
+
... framework="cc",
|
|
29
|
+
... tmux_session="mpm-commander",
|
|
30
|
+
... pane_target="%1",
|
|
31
|
+
... git_branch="main",
|
|
32
|
+
... git_status="clean",
|
|
33
|
+
... connected=True
|
|
34
|
+
... )
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
name: str
|
|
38
|
+
project_path: Path
|
|
39
|
+
framework: str
|
|
40
|
+
tmux_session: str
|
|
41
|
+
pane_target: str
|
|
42
|
+
git_branch: Optional[str] = None
|
|
43
|
+
git_status: Optional[str] = None
|
|
44
|
+
connected: bool = False
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class BaseFramework(ABC):
|
|
48
|
+
"""Base class for AI coding assistant frameworks.
|
|
49
|
+
|
|
50
|
+
A framework represents a specific AI coding tool (Claude Code, Claude MPM, etc.)
|
|
51
|
+
that can be launched in a project directory via tmux.
|
|
52
|
+
|
|
53
|
+
Attributes:
|
|
54
|
+
name: Short identifier (e.g., "cc", "mpm")
|
|
55
|
+
display_name: Human-readable name (e.g., "Claude Code", "Claude MPM")
|
|
56
|
+
command: The command to run (e.g., "claude")
|
|
57
|
+
|
|
58
|
+
Example:
|
|
59
|
+
>>> class MyFramework(BaseFramework):
|
|
60
|
+
... name = "my"
|
|
61
|
+
... display_name = "My Framework"
|
|
62
|
+
... command = "my-command"
|
|
63
|
+
...
|
|
64
|
+
... def get_startup_command(self, project_path: Path) -> str:
|
|
65
|
+
... return f"cd {project_path} && my-command"
|
|
66
|
+
...
|
|
67
|
+
... def is_available(self) -> bool:
|
|
68
|
+
... return True
|
|
69
|
+
"""
|
|
70
|
+
|
|
71
|
+
name: str # "cc", "mpm", etc.
|
|
72
|
+
display_name: str # "Claude Code", "Claude MPM", etc.
|
|
73
|
+
command: str # The command to run
|
|
74
|
+
|
|
75
|
+
@abstractmethod
|
|
76
|
+
def get_startup_command(self, project_path: Path) -> str:
|
|
77
|
+
"""Get the command to start this framework in a project.
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
project_path: Path to the project directory
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
Shell command string to start the framework
|
|
84
|
+
|
|
85
|
+
Example:
|
|
86
|
+
>>> framework = ClaudeCodeFramework()
|
|
87
|
+
>>> framework.get_startup_command(Path("/Users/user/myapp"))
|
|
88
|
+
"cd /Users/user/myapp && claude"
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
@abstractmethod
|
|
92
|
+
def is_available(self) -> bool:
|
|
93
|
+
"""Check if this framework is installed/available.
|
|
94
|
+
|
|
95
|
+
Returns:
|
|
96
|
+
True if the framework command is available on the system
|
|
97
|
+
|
|
98
|
+
Example:
|
|
99
|
+
>>> framework = ClaudeCodeFramework()
|
|
100
|
+
>>> framework.is_available()
|
|
101
|
+
True
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
def get_git_info(self, project_path: Path) -> tuple[Optional[str], Optional[str]]:
|
|
105
|
+
"""Get git branch and status for project.
|
|
106
|
+
|
|
107
|
+
Args:
|
|
108
|
+
project_path: Path to the project directory
|
|
109
|
+
|
|
110
|
+
Returns:
|
|
111
|
+
Tuple of (branch, status) where:
|
|
112
|
+
- branch: Current git branch name or None if not a git repo
|
|
113
|
+
- status: "clean" if no changes, "dirty" if changes, or None if not a git repo
|
|
114
|
+
|
|
115
|
+
Example:
|
|
116
|
+
>>> framework = ClaudeCodeFramework()
|
|
117
|
+
>>> branch, status = framework.get_git_info(Path("/Users/user/myapp"))
|
|
118
|
+
>>> print(branch, status)
|
|
119
|
+
main clean
|
|
120
|
+
"""
|
|
121
|
+
if not (project_path / ".git").exists():
|
|
122
|
+
return None, None
|
|
123
|
+
|
|
124
|
+
try:
|
|
125
|
+
# Get current branch
|
|
126
|
+
result = subprocess.run( # nosec B603, B607 - Controlled git command
|
|
127
|
+
["git", "-C", str(project_path), "rev-parse", "--abbrev-ref", "HEAD"],
|
|
128
|
+
capture_output=True,
|
|
129
|
+
text=True,
|
|
130
|
+
check=True,
|
|
131
|
+
)
|
|
132
|
+
branch = result.stdout.strip()
|
|
133
|
+
|
|
134
|
+
# Check if working directory is clean
|
|
135
|
+
result = subprocess.run( # nosec B603, B607 - Controlled git command
|
|
136
|
+
["git", "-C", str(project_path), "status", "--porcelain"],
|
|
137
|
+
capture_output=True,
|
|
138
|
+
text=True,
|
|
139
|
+
check=True,
|
|
140
|
+
)
|
|
141
|
+
status = "clean" if not result.stdout.strip() else "dirty"
|
|
142
|
+
|
|
143
|
+
return branch, status
|
|
144
|
+
|
|
145
|
+
except (subprocess.CalledProcessError, FileNotFoundError):
|
|
146
|
+
return None, None
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"""Claude Code (cc) framework implementation."""
|
|
2
|
+
|
|
3
|
+
import shlex
|
|
4
|
+
import shutil
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from .base import BaseFramework
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ClaudeCodeFramework(BaseFramework):
|
|
11
|
+
"""Claude Code CLI framework.
|
|
12
|
+
|
|
13
|
+
This framework launches the standard Claude Code CLI in a project directory.
|
|
14
|
+
It uses the 'claude' command with appropriate flags for automated operation.
|
|
15
|
+
|
|
16
|
+
Example:
|
|
17
|
+
>>> framework = ClaudeCodeFramework()
|
|
18
|
+
>>> framework.name
|
|
19
|
+
'cc'
|
|
20
|
+
>>> framework.is_available()
|
|
21
|
+
True
|
|
22
|
+
>>> framework.get_startup_command(Path("/Users/user/myapp"))
|
|
23
|
+
"cd '/Users/user/myapp' && claude --dangerously-skip-permissions"
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
name = "cc"
|
|
27
|
+
display_name = "Claude Code"
|
|
28
|
+
command = "claude"
|
|
29
|
+
|
|
30
|
+
def get_startup_command(self, project_path: Path) -> str:
|
|
31
|
+
"""Get the command to start Claude Code in a project.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
project_path: Path to the project directory
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
Shell command string to start Claude Code
|
|
38
|
+
|
|
39
|
+
Example:
|
|
40
|
+
>>> framework = ClaudeCodeFramework()
|
|
41
|
+
>>> framework.get_startup_command(Path("/Users/user/myapp"))
|
|
42
|
+
"cd '/Users/user/myapp' && claude --dangerously-skip-permissions"
|
|
43
|
+
"""
|
|
44
|
+
quoted_path = shlex.quote(str(project_path))
|
|
45
|
+
return f"cd {quoted_path} && claude --dangerously-skip-permissions"
|
|
46
|
+
|
|
47
|
+
def is_available(self) -> bool:
|
|
48
|
+
"""Check if 'claude' command is available.
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
True if 'claude' command exists in PATH
|
|
52
|
+
|
|
53
|
+
Example:
|
|
54
|
+
>>> framework = ClaudeCodeFramework()
|
|
55
|
+
>>> framework.is_available()
|
|
56
|
+
True
|
|
57
|
+
"""
|
|
58
|
+
return shutil.which("claude") is not None
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"""Claude MPM framework implementation."""
|
|
2
|
+
|
|
3
|
+
import shlex
|
|
4
|
+
import shutil
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from .base import BaseFramework
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class MPMFramework(BaseFramework):
|
|
11
|
+
"""Claude MPM framework.
|
|
12
|
+
|
|
13
|
+
This framework launches Claude with MPM agent loading via CLAUDE.md.
|
|
14
|
+
It uses the same 'claude' command as Claude Code, but relies on CLAUDE.md
|
|
15
|
+
in the project to load the MPM agent system.
|
|
16
|
+
|
|
17
|
+
Example:
|
|
18
|
+
>>> framework = MPMFramework()
|
|
19
|
+
>>> framework.name
|
|
20
|
+
'mpm'
|
|
21
|
+
>>> framework.is_available()
|
|
22
|
+
True
|
|
23
|
+
>>> framework.get_startup_command(Path("/Users/user/myapp"))
|
|
24
|
+
"cd '/Users/user/myapp' && claude --dangerously-skip-permissions"
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
name = "mpm"
|
|
28
|
+
display_name = "Claude MPM"
|
|
29
|
+
command = "claude" # Uses claude with MPM agent loading
|
|
30
|
+
|
|
31
|
+
def get_startup_command(self, project_path: Path) -> str:
|
|
32
|
+
"""Get the command to start Claude MPM in a project.
|
|
33
|
+
|
|
34
|
+
The MPM framework uses the standard 'claude' command, but expects
|
|
35
|
+
a CLAUDE.md file in the project to load the MPM agent system.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
project_path: Path to the project directory
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
Shell command string to start Claude with MPM
|
|
42
|
+
|
|
43
|
+
Example:
|
|
44
|
+
>>> framework = MPMFramework()
|
|
45
|
+
>>> framework.get_startup_command(Path("/Users/user/myapp"))
|
|
46
|
+
"cd '/Users/user/myapp' && claude --dangerously-skip-permissions"
|
|
47
|
+
"""
|
|
48
|
+
quoted_path = shlex.quote(str(project_path))
|
|
49
|
+
return f"cd {quoted_path} && claude --dangerously-skip-permissions"
|
|
50
|
+
|
|
51
|
+
def is_available(self) -> bool:
|
|
52
|
+
"""Check if 'claude' command is available.
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
True if 'claude' command exists in PATH
|
|
56
|
+
|
|
57
|
+
Example:
|
|
58
|
+
>>> framework = MPMFramework()
|
|
59
|
+
>>> framework.is_available()
|
|
60
|
+
True
|
|
61
|
+
"""
|
|
62
|
+
return shutil.which("claude") is not None
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Inbox system for MPM Commander.
|
|
2
|
+
|
|
3
|
+
Provides centralized event aggregation and display.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from .dedup import DedupEntry, EventDeduplicator
|
|
7
|
+
from .inbox import Inbox, InboxCounts
|
|
8
|
+
from .models import InboxItem
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"DedupEntry",
|
|
12
|
+
"EventDeduplicator",
|
|
13
|
+
"Inbox",
|
|
14
|
+
"InboxCounts",
|
|
15
|
+
"InboxItem",
|
|
16
|
+
]
|