claude-mpm 5.4.85__py3-none-any.whl → 5.6.76__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.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/CLAUDE_MPM_OUTPUT_STYLE.md +8 -5
- claude_mpm/agents/{CLAUDE_MPM_FOUNDERS_OUTPUT_STYLE.md → CLAUDE_MPM_RESEARCH_OUTPUT_STYLE.md} +14 -6
- claude_mpm/agents/PM_INSTRUCTIONS.md +109 -706
- 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/commands/autotodos.py +566 -0
- claude_mpm/cli/commands/commander.py +216 -0
- 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 +2 -2
- claude_mpm/cli/commands/oauth.py +481 -0
- claude_mpm/cli/commands/run.py +35 -3
- claude_mpm/cli/commands/skill_source.py +51 -2
- claude_mpm/cli/commands/skills.py +5 -3
- claude_mpm/cli/executor.py +128 -16
- claude_mpm/cli/helpers.py +1 -1
- claude_mpm/cli/parsers/base_parser.py +84 -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/run_parser.py +10 -0
- claude_mpm/cli/parsers/skill_source_parser.py +4 -0
- claude_mpm/cli/parsers/skills_parser.py +5 -0
- claude_mpm/cli/startup.py +345 -40
- claude_mpm/cli/startup_display.py +76 -7
- claude_mpm/cli/startup_logging.py +2 -2
- claude_mpm/cli/startup_migrations.py +236 -0
- 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 +124 -0
- claude_mpm/commander/chat/repl.py +1957 -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 +868 -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 +5 -0
- claude_mpm/core/claude_runner.py +152 -0
- 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 +5 -4
- 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/output_style_manager.py +52 -12
- claude_mpm/core/socketio_pool.py +47 -15
- claude_mpm/core/unified_config.py +10 -6
- claude_mpm/core/unified_paths.py +68 -80
- 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/{Cs_tUR18.js → 1WZnGYqX.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CDuw-vjf.js → 67pF3qNn.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{bTOqqlTd.js → 6RxdMKe4.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DwBR2MJi.js → 8cZrfX0h.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{ZGh7QtNv.js → 9a6T2nm-.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{D9lljYKQ.js → B443AUzu.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{RJiighC3.js → B8AwtY2H.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{uuIeMWc-.js → BF15LAsF.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{D3k0OPJN.js → BRcwIQNr.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CyWMqx4W.js → BV6nKitt.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CiIAseT4.js → BViJ8lZt.js} +5 -5
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CBBdVcY8.js → BcQ-Q0FE.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{BovzEFCE.js → Bpyvgze_.js} +1 -1
- 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/{eNVUfhuA.js → C3rbW_a-.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{GYwsonyD.js → C8WYN38h.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{BIF9m_hv.js → C9I8FlXH.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{B0uc0UOD.js → CIQcWgO2.js} +3 -3
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Be7GpZd6.js → CIctN7YN.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Bh0LDWpI.js → CKrS_JZW.js} +2 -2
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DUrLdbGD.js → CR6P9C4A.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{B7xVLGWV.js → CRRR9MD_.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRcR2DqT.js +334 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Dhb8PKl3.js → CSXtMOf0.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{BPYeabCQ.js → CT-sbxSk.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{sQeU3Y1z.js → CWm6DJsp.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CnA0NrzZ.js → CpqQ1Kzn.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{C4B-KCzX.js → D2nGpDRe.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DGkLK5U1.js → D9iCMida.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{BofRWZRR.js → D9ykgMoY.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DmxopI1J.js → DL2Ldur1.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{C30mlcqg.js → DPfltzjH.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Vzk33B_K.js → DR8nis88.js} +2 -2
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DI7hHRFL.js → DUliQN2b.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{C4JcI4KD.js → DXlhR01x.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{bT1r9zLR.js → D_lyTybS.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DZX00Y4g.js → DngoTTgh.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CzZX-COe.js → DqkmHtDC.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{B7RN905-.js → DsDh8EYs.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DLVjFsZ3.js → DypDmXgd.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{iEWssX7S.js → IPYC-LnN.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JTLiF7dt.js +24 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DaimHw_p.js → JpevfAFt.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DY1XQ8fi.js → R8CEIRAd.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Dle-35c7.js → Zxy7qc-l.js} +2 -2
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/q9Hm6zAU.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{C_Usid8X.js → qtd3IeO4.js} +2 -2
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CzeYkLYB.js → ulBFON_C.js} +2 -2
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Cfqx1Qun.js → wQVh1CoA.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/{app.D6-I5TpK.js → app.Dr7t0z2J.js} +2 -2
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.BGhZHUS3.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/{0.m1gL8KXf.js → 0.RgBboRvH.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/{1.CgNOuw-d.js → 1.DG-KkbDf.js} +1 -1
- 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 +9 -9
- 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/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/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/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 +22 -15
- 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/remote_agent_discovery_service.py +3 -0
- 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/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 -2
- claude_mpm/services/monitor/server.py +111 -16
- claude_mpm/services/pm_skills_deployer.py +261 -87
- claude_mpm/services/skills/git_skill_source_manager.py +130 -10
- claude_mpm/services/skills/selective_skill_deployer.py +142 -16
- claude_mpm/services/skills/skill_discovery_service.py +74 -4
- claude_mpm/services/skills_deployer.py +31 -5
- 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/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-circuit-breaker-enforcement/SKILL.md +476 -0
- claude_mpm/skills/bundled/pm/mpm-config/SKILL.md +29 -0
- claude_mpm/skills/bundled/pm/mpm-doctor/SKILL.md +53 -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-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/{pm-teaching-mode → mpm-teaching-mode}/SKILL.md +2 -2
- claude_mpm/skills/bundled/pm/mpm-ticket-view/SKILL.md +110 -0
- claude_mpm/skills/bundled/pm/mpm-tool-usage-guide/SKILL.md +386 -0
- claude_mpm/skills/bundled/pm/mpm-version/SKILL.md +21 -0
- claude_mpm/skills/registry.py +295 -90
- claude_mpm/skills/skill_manager.py +4 -4
- claude_mpm-5.6.76.dist-info/METADATA +416 -0
- {claude_mpm-5.4.85.dist-info → claude_mpm-5.6.76.dist-info}/RECORD +312 -175
- {claude_mpm-5.4.85.dist-info → claude_mpm-5.6.76.dist-info}/WHEEL +1 -1
- {claude_mpm-5.4.85.dist-info → claude_mpm-5.6.76.dist-info}/entry_points.txt +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.DWzvg0-y.css +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.ThTw9_ym.css +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/4TdZjIqw.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/5shd3_w0.js +0 -24
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BKjSRqUr.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Da0KfYnO.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dfy6j1xT.js +0 -323
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.NWzMBYRp.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.C0GcWctS.js +0 -1
- claude_mpm-5.4.85.dist-info/METADATA +0 -1023
- /claude_mpm/skills/bundled/pm/{pm-bug-reporting/pm-bug-reporting.md → mpm-bug-reporting/SKILL.md} +0 -0
- /claude_mpm/skills/bundled/pm/{pm-delegation-patterns → mpm-delegation-patterns}/SKILL.md +0 -0
- /claude_mpm/skills/bundled/pm/{pm-git-file-tracking → mpm-git-file-tracking}/SKILL.md +0 -0
- /claude_mpm/skills/bundled/pm/{pm-pr-workflow → mpm-pr-workflow}/SKILL.md +0 -0
- /claude_mpm/skills/bundled/pm/{pm-ticketing-integration → mpm-ticketing-integration}/SKILL.md +0 -0
- /claude_mpm/skills/bundled/pm/{pm-verification-protocols → mpm-verification-protocols}/SKILL.md +0 -0
- {claude_mpm-5.4.85.dist-info → claude_mpm-5.6.76.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-5.4.85.dist-info → claude_mpm-5.6.76.dist-info}/licenses/LICENSE-FAQ.md +0 -0
- {claude_mpm-5.4.85.dist-info → claude_mpm-5.6.76.dist-info}/top_level.txt +0 -0
|
@@ -76,6 +76,10 @@ def add_skill_source_subparser(subparsers) -> argparse.ArgumentParser:
|
|
|
76
76
|
dest="skip_test",
|
|
77
77
|
help="Skip immediate testing (not recommended)",
|
|
78
78
|
)
|
|
79
|
+
add_parser.add_argument(
|
|
80
|
+
"--token",
|
|
81
|
+
help="GitHub token or env var reference (e.g., ghp_xxx or $PRIVATE_TOKEN)",
|
|
82
|
+
)
|
|
79
83
|
|
|
80
84
|
# Remove repository
|
|
81
85
|
remove_parser = skill_source_subparsers.add_parser(
|
|
@@ -167,6 +167,11 @@ def add_skills_subparser(subparsers) -> argparse.ArgumentParser:
|
|
|
167
167
|
action="store_true",
|
|
168
168
|
help="Force redeployment of already deployed skills",
|
|
169
169
|
)
|
|
170
|
+
deploy_github_parser.add_argument(
|
|
171
|
+
"--all",
|
|
172
|
+
action="store_true",
|
|
173
|
+
help="Deploy all available skills, not just agent-referenced ones",
|
|
174
|
+
)
|
|
170
175
|
|
|
171
176
|
# List available GitHub skills
|
|
172
177
|
list_available_parser = skills_subparsers.add_parser(
|
claude_mpm/cli/startup.py
CHANGED
|
@@ -13,6 +13,49 @@ import sys
|
|
|
13
13
|
from pathlib import Path
|
|
14
14
|
|
|
15
15
|
|
|
16
|
+
def cleanup_user_level_hooks() -> bool:
|
|
17
|
+
"""Remove stale user-level hooks directory.
|
|
18
|
+
|
|
19
|
+
WHY: claude-mpm previously deployed hooks to ~/.claude/hooks/claude-mpm/
|
|
20
|
+
(user-level). This is now deprecated in favor of project-level hooks
|
|
21
|
+
configured in .claude/settings.local.json. Stale user-level hooks can
|
|
22
|
+
cause conflicts and confusion.
|
|
23
|
+
|
|
24
|
+
DESIGN DECISION: Runs early in startup, before project hook sync.
|
|
25
|
+
Non-blocking - failures are logged at debug level but don't prevent startup.
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
bool: True if hooks were cleaned up, False if none found or cleanup failed
|
|
29
|
+
"""
|
|
30
|
+
import shutil
|
|
31
|
+
|
|
32
|
+
user_hooks_dir = Path.home() / ".claude" / "hooks" / "claude-mpm"
|
|
33
|
+
|
|
34
|
+
if not user_hooks_dir.exists():
|
|
35
|
+
return False
|
|
36
|
+
|
|
37
|
+
try:
|
|
38
|
+
from ..core.logger import get_logger
|
|
39
|
+
|
|
40
|
+
logger = get_logger("startup")
|
|
41
|
+
logger.debug(f"Removing stale user-level hooks directory: {user_hooks_dir}")
|
|
42
|
+
|
|
43
|
+
shutil.rmtree(user_hooks_dir)
|
|
44
|
+
|
|
45
|
+
logger.debug("User-level hooks cleanup complete")
|
|
46
|
+
return True
|
|
47
|
+
except Exception as e:
|
|
48
|
+
# Non-critical - log but don't fail startup
|
|
49
|
+
try:
|
|
50
|
+
from ..core.logger import get_logger
|
|
51
|
+
|
|
52
|
+
logger = get_logger("startup")
|
|
53
|
+
logger.debug(f"Failed to cleanup user-level hooks (non-fatal): {e}")
|
|
54
|
+
except Exception: # nosec B110
|
|
55
|
+
pass # Avoid any errors in error handling
|
|
56
|
+
return False
|
|
57
|
+
|
|
58
|
+
|
|
16
59
|
def sync_hooks_on_startup(quiet: bool = False) -> bool:
|
|
17
60
|
"""Ensure hooks are up-to-date on startup.
|
|
18
61
|
|
|
@@ -20,7 +63,12 @@ def sync_hooks_on_startup(quiet: bool = False) -> bool:
|
|
|
20
63
|
Reinstalling hooks ensures the hook format matches the current code.
|
|
21
64
|
|
|
22
65
|
DESIGN DECISION: Shows brief status message on success for user awareness.
|
|
23
|
-
Failures are logged but don't prevent startup to ensure claude-mpm
|
|
66
|
+
Failures are logged but don't prevent startup to ensure claude-mpm
|
|
67
|
+
remains functional.
|
|
68
|
+
|
|
69
|
+
Workflow:
|
|
70
|
+
1. Cleanup stale user-level hooks (~/.claude/hooks/claude-mpm/)
|
|
71
|
+
2. Reinstall project-level hooks to .claude/settings.local.json
|
|
24
72
|
|
|
25
73
|
Args:
|
|
26
74
|
quiet: If True, suppress all output (used internally)
|
|
@@ -28,28 +76,45 @@ def sync_hooks_on_startup(quiet: bool = False) -> bool:
|
|
|
28
76
|
Returns:
|
|
29
77
|
bool: True if hooks were synced successfully, False otherwise
|
|
30
78
|
"""
|
|
79
|
+
is_tty = not quiet and sys.stdout.isatty()
|
|
80
|
+
|
|
81
|
+
# Step 1: Cleanup stale user-level hooks first
|
|
82
|
+
if is_tty:
|
|
83
|
+
print("Cleaning user-level hooks...", end=" ", flush=True)
|
|
84
|
+
|
|
85
|
+
cleaned = cleanup_user_level_hooks()
|
|
86
|
+
|
|
87
|
+
if is_tty:
|
|
88
|
+
if cleaned:
|
|
89
|
+
print("✓")
|
|
90
|
+
else:
|
|
91
|
+
print("(none found)")
|
|
92
|
+
|
|
93
|
+
# Step 2: Install project-level hooks
|
|
31
94
|
try:
|
|
32
95
|
from ..hooks.claude_hooks.installer import HookInstaller
|
|
33
96
|
|
|
34
97
|
installer = HookInstaller()
|
|
35
98
|
|
|
36
99
|
# Show brief status (hooks sync is fast)
|
|
37
|
-
if
|
|
38
|
-
print("
|
|
100
|
+
if is_tty:
|
|
101
|
+
print("Installing project hooks...", end=" ", flush=True)
|
|
39
102
|
|
|
40
103
|
# Reinstall hooks (force=True ensures update)
|
|
41
104
|
success = installer.install_hooks(force=True)
|
|
42
105
|
|
|
43
|
-
if
|
|
106
|
+
if is_tty:
|
|
44
107
|
if success:
|
|
45
|
-
|
|
108
|
+
# Count hooks from settings file
|
|
109
|
+
hook_count = _count_installed_hooks(installer.settings_file)
|
|
110
|
+
print(f"{hook_count} hooks configured ✓")
|
|
46
111
|
else:
|
|
47
112
|
print("(skipped)")
|
|
48
113
|
|
|
49
114
|
return success
|
|
50
115
|
|
|
51
116
|
except Exception as e:
|
|
52
|
-
if
|
|
117
|
+
if is_tty:
|
|
53
118
|
print("(error)")
|
|
54
119
|
# Log but don't fail startup
|
|
55
120
|
from ..core.logger import get_logger
|
|
@@ -59,6 +124,30 @@ def sync_hooks_on_startup(quiet: bool = False) -> bool:
|
|
|
59
124
|
return False
|
|
60
125
|
|
|
61
126
|
|
|
127
|
+
def _count_installed_hooks(settings_file: Path) -> int:
|
|
128
|
+
"""Count the number of hook event types configured in settings.
|
|
129
|
+
|
|
130
|
+
Args:
|
|
131
|
+
settings_file: Path to the settings.local.json file
|
|
132
|
+
|
|
133
|
+
Returns:
|
|
134
|
+
int: Number of hook event types configured (e.g., 7 for all events)
|
|
135
|
+
"""
|
|
136
|
+
import json
|
|
137
|
+
|
|
138
|
+
try:
|
|
139
|
+
if not settings_file.exists():
|
|
140
|
+
return 0
|
|
141
|
+
|
|
142
|
+
with settings_file.open() as f:
|
|
143
|
+
settings = json.load(f)
|
|
144
|
+
|
|
145
|
+
hooks = settings.get("hooks", {})
|
|
146
|
+
return len(hooks)
|
|
147
|
+
except Exception:
|
|
148
|
+
return 0
|
|
149
|
+
|
|
150
|
+
|
|
62
151
|
def cleanup_legacy_agent_cache() -> None:
|
|
63
152
|
"""Remove legacy hierarchical agent cache directories.
|
|
64
153
|
|
|
@@ -161,7 +250,25 @@ def setup_early_environment(argv):
|
|
|
161
250
|
# CRITICAL: Suppress ALL logging by default
|
|
162
251
|
# This catches all loggers (claude_mpm.*, service.*, framework_loader, etc.)
|
|
163
252
|
# This will be overridden by setup_mcp_server_logging() based on user preference
|
|
164
|
-
logging.getLogger()
|
|
253
|
+
root_logger = logging.getLogger()
|
|
254
|
+
root_logger.setLevel(logging.CRITICAL + 1) # Root logger catches everything
|
|
255
|
+
root_logger.handlers = [] # Remove any handlers
|
|
256
|
+
|
|
257
|
+
# Also suppress common module loggers explicitly to prevent handler leakage
|
|
258
|
+
for logger_name in [
|
|
259
|
+
"claude_mpm",
|
|
260
|
+
"path_resolver",
|
|
261
|
+
"file_loader",
|
|
262
|
+
"framework_loader",
|
|
263
|
+
"service",
|
|
264
|
+
"instruction_loader",
|
|
265
|
+
"agent_loader",
|
|
266
|
+
"startup",
|
|
267
|
+
]:
|
|
268
|
+
module_logger = logging.getLogger(logger_name)
|
|
269
|
+
module_logger.setLevel(logging.CRITICAL + 1)
|
|
270
|
+
module_logger.handlers = []
|
|
271
|
+
module_logger.propagate = False
|
|
165
272
|
|
|
166
273
|
# Process argv
|
|
167
274
|
if argv is None:
|
|
@@ -178,9 +285,15 @@ def should_skip_background_services(args, processed_argv):
|
|
|
178
285
|
"""
|
|
179
286
|
Determine if background services should be skipped for this command.
|
|
180
287
|
|
|
181
|
-
WHY: Some commands (help, version, configure, doctor) don't need
|
|
288
|
+
WHY: Some commands (help, version, configure, doctor, oauth) don't need
|
|
182
289
|
background services and should start faster.
|
|
183
290
|
|
|
291
|
+
NOTE: Headless mode with --resume skips background services because:
|
|
292
|
+
- Each claude-mpm call is a NEW process (orchestrators like Vibe Kanban)
|
|
293
|
+
- First message (no --resume): Run full init (hooks, agents, skills)
|
|
294
|
+
- Follow-up messages (with --resume): Skip init to avoid latency
|
|
295
|
+
- Hooks/agents/skills are already deployed from the first message
|
|
296
|
+
|
|
184
297
|
Args:
|
|
185
298
|
args: Parsed arguments
|
|
186
299
|
processed_argv: Processed command line arguments
|
|
@@ -188,10 +301,30 @@ def should_skip_background_services(args, processed_argv):
|
|
|
188
301
|
Returns:
|
|
189
302
|
bool: True if background services should be skipped
|
|
190
303
|
"""
|
|
304
|
+
# Headless mode with --resume: skip init for follow-up messages
|
|
305
|
+
# Each orchestrator call is a new process, so we need to skip init
|
|
306
|
+
# on follow-ups to avoid re-running hooks/agents/skills sync every time
|
|
307
|
+
is_headless = getattr(args, "headless", False)
|
|
308
|
+
has_resume = getattr(args, "resume", False) or "--resume" in (processed_argv or [])
|
|
309
|
+
|
|
310
|
+
if is_headless and has_resume:
|
|
311
|
+
return True
|
|
312
|
+
|
|
191
313
|
skip_commands = ["--version", "-v", "--help", "-h"]
|
|
192
314
|
return any(cmd in (processed_argv or sys.argv[1:]) for cmd in skip_commands) or (
|
|
193
315
|
hasattr(args, "command")
|
|
194
|
-
and args.command
|
|
316
|
+
and args.command
|
|
317
|
+
in [
|
|
318
|
+
"info",
|
|
319
|
+
"doctor",
|
|
320
|
+
"config",
|
|
321
|
+
"mcp",
|
|
322
|
+
"configure",
|
|
323
|
+
"hook-errors",
|
|
324
|
+
"autotodos",
|
|
325
|
+
"commander",
|
|
326
|
+
"oauth",
|
|
327
|
+
]
|
|
195
328
|
)
|
|
196
329
|
|
|
197
330
|
|
|
@@ -252,11 +385,13 @@ def deploy_bundled_skills():
|
|
|
252
385
|
if deployment_result.get("deployed"):
|
|
253
386
|
# Show simple feedback for deployed skills
|
|
254
387
|
deployed_count = len(deployment_result["deployed"])
|
|
255
|
-
|
|
388
|
+
if sys.stdout.isatty():
|
|
389
|
+
print(f"✓ Bundled skills ready ({deployed_count} deployed)", flush=True)
|
|
256
390
|
logger.info(f"Skills: Deployed {deployed_count} skill(s)")
|
|
257
391
|
elif not deployment_result.get("errors"):
|
|
258
392
|
# No deployment needed, skills already present
|
|
259
|
-
|
|
393
|
+
if sys.stdout.isatty():
|
|
394
|
+
print("✓ Bundled skills ready", flush=True)
|
|
260
395
|
|
|
261
396
|
if deployment_result.get("errors"):
|
|
262
397
|
logger.warning(
|
|
@@ -290,7 +425,8 @@ def discover_and_link_runtime_skills():
|
|
|
290
425
|
|
|
291
426
|
discover_skills()
|
|
292
427
|
# Show simple success feedback
|
|
293
|
-
|
|
428
|
+
if sys.stdout.isatty():
|
|
429
|
+
print("✓ Runtime skills linked", flush=True)
|
|
294
430
|
except Exception as e:
|
|
295
431
|
# Import logger here to avoid circular imports
|
|
296
432
|
from ..core.logger import get_logger
|
|
@@ -315,7 +451,7 @@ def deploy_output_style_on_startup():
|
|
|
315
451
|
Deploys all styles:
|
|
316
452
|
- claude-mpm.md (professional mode)
|
|
317
453
|
- claude-mpm-teacher.md (teaching mode)
|
|
318
|
-
- claude-mpm-
|
|
454
|
+
- claude-mpm-research.md (research mode - for codebase analysis)
|
|
319
455
|
"""
|
|
320
456
|
try:
|
|
321
457
|
from ..core.output_style_manager import OutputStyleManager
|
|
@@ -345,7 +481,8 @@ def deploy_output_style_on_startup():
|
|
|
345
481
|
|
|
346
482
|
if all_up_to_date:
|
|
347
483
|
# Show feedback that output styles are ready
|
|
348
|
-
|
|
484
|
+
if sys.stdout.isatty():
|
|
485
|
+
print("✓ Output styles ready", flush=True)
|
|
349
486
|
return
|
|
350
487
|
|
|
351
488
|
# Deploy all styles using the manager
|
|
@@ -355,7 +492,8 @@ def deploy_output_style_on_startup():
|
|
|
355
492
|
deployed_count = sum(1 for success in results.values() if success)
|
|
356
493
|
|
|
357
494
|
if deployed_count > 0:
|
|
358
|
-
|
|
495
|
+
if sys.stdout.isatty():
|
|
496
|
+
print(f"✓ Output styles deployed ({deployed_count} styles)", flush=True)
|
|
359
497
|
else:
|
|
360
498
|
# Deployment failed - log but don't fail startup
|
|
361
499
|
from ..core.logger import get_logger
|
|
@@ -450,6 +588,94 @@ def _cleanup_orphaned_agents(deploy_target: Path, deployed_agents: list[str]) ->
|
|
|
450
588
|
return removed_count
|
|
451
589
|
|
|
452
590
|
|
|
591
|
+
def _save_deployment_state_after_reconciliation(
|
|
592
|
+
agent_result, project_path: Path
|
|
593
|
+
) -> None:
|
|
594
|
+
"""Save deployment state after reconciliation to prevent duplicate deployment.
|
|
595
|
+
|
|
596
|
+
WHY: After perform_startup_reconciliation() deploys agents to .claude/agents/,
|
|
597
|
+
we need to save a deployment state file so that ClaudeRunner.setup_agents()
|
|
598
|
+
can detect agents are already deployed and skip redundant deployment.
|
|
599
|
+
|
|
600
|
+
This prevents the "✓ Deployed 31 native agents" duplicate deployment that
|
|
601
|
+
occurs when setup_agents() doesn't know reconciliation already ran.
|
|
602
|
+
|
|
603
|
+
Args:
|
|
604
|
+
agent_result: DeploymentResult from perform_startup_reconciliation()
|
|
605
|
+
project_path: Project root directory
|
|
606
|
+
|
|
607
|
+
DESIGN DECISION: Use same state file format as ClaudeRunner._save_deployment_state()
|
|
608
|
+
Located at: .claude-mpm/cache/deployment_state.json
|
|
609
|
+
|
|
610
|
+
State file format:
|
|
611
|
+
{
|
|
612
|
+
"version": "5.6.13",
|
|
613
|
+
"agent_count": 15,
|
|
614
|
+
"deployment_hash": "sha256:...",
|
|
615
|
+
"deployed_at": 1234567890.123
|
|
616
|
+
}
|
|
617
|
+
"""
|
|
618
|
+
import hashlib
|
|
619
|
+
import json
|
|
620
|
+
import time
|
|
621
|
+
|
|
622
|
+
from ..core.logger import get_logger
|
|
623
|
+
|
|
624
|
+
logger = get_logger("cli")
|
|
625
|
+
|
|
626
|
+
try:
|
|
627
|
+
# Get version from package
|
|
628
|
+
from claude_mpm import __version__
|
|
629
|
+
|
|
630
|
+
# Path to state file (matches ClaudeRunner._get_deployment_state_path())
|
|
631
|
+
state_file = project_path / ".claude-mpm" / "cache" / "deployment_state.json"
|
|
632
|
+
agents_dir = project_path / ".claude" / "agents"
|
|
633
|
+
|
|
634
|
+
# Count deployed agents
|
|
635
|
+
if agents_dir.exists():
|
|
636
|
+
agent_count = len(list(agents_dir.glob("*.md")))
|
|
637
|
+
else:
|
|
638
|
+
agent_count = 0
|
|
639
|
+
|
|
640
|
+
# Calculate deployment hash (matches ClaudeRunner._calculate_deployment_hash())
|
|
641
|
+
# CRITICAL: Must match exact hash algorithm used in ClaudeRunner
|
|
642
|
+
# Hashes filename + file content (not mtime) for consistency
|
|
643
|
+
deployment_hash = ""
|
|
644
|
+
if agents_dir.exists():
|
|
645
|
+
agent_files = sorted(agents_dir.glob("*.md"))
|
|
646
|
+
hash_obj = hashlib.sha256()
|
|
647
|
+
for agent_file in agent_files:
|
|
648
|
+
# Include filename and content in hash (matches ClaudeRunner)
|
|
649
|
+
hash_obj.update(agent_file.name.encode())
|
|
650
|
+
try:
|
|
651
|
+
hash_obj.update(agent_file.read_bytes())
|
|
652
|
+
except Exception as e:
|
|
653
|
+
logger.debug(f"Error reading {agent_file} for hash: {e}")
|
|
654
|
+
|
|
655
|
+
deployment_hash = hash_obj.hexdigest()
|
|
656
|
+
|
|
657
|
+
# Create state data
|
|
658
|
+
state_data = {
|
|
659
|
+
"version": __version__,
|
|
660
|
+
"agent_count": agent_count,
|
|
661
|
+
"deployment_hash": deployment_hash,
|
|
662
|
+
"deployed_at": time.time(),
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
# Ensure directory exists
|
|
666
|
+
state_file.parent.mkdir(parents=True, exist_ok=True)
|
|
667
|
+
|
|
668
|
+
# Write state file
|
|
669
|
+
state_file.write_text(json.dumps(state_data, indent=2))
|
|
670
|
+
logger.debug(
|
|
671
|
+
f"Saved deployment state after reconciliation: {agent_count} agents"
|
|
672
|
+
)
|
|
673
|
+
|
|
674
|
+
except Exception as e:
|
|
675
|
+
# Non-critical error - log but don't fail startup
|
|
676
|
+
logger.debug(f"Failed to save deployment state: {e}")
|
|
677
|
+
|
|
678
|
+
|
|
453
679
|
def sync_remote_agents_on_startup(force_sync: bool = False):
|
|
454
680
|
"""
|
|
455
681
|
Synchronize agent templates from remote sources on startup.
|
|
@@ -612,6 +838,12 @@ def sync_remote_agents_on_startup(force_sync: bool = False):
|
|
|
612
838
|
)
|
|
613
839
|
print(" Run with --verbose for detailed error information.\n")
|
|
614
840
|
|
|
841
|
+
# Save deployment state to prevent duplicate deployment in ClaudeRunner
|
|
842
|
+
# This ensures setup_agents() skips deployment since we already reconciled
|
|
843
|
+
_save_deployment_state_after_reconciliation(
|
|
844
|
+
agent_result=agent_result, project_path=project_path
|
|
845
|
+
)
|
|
846
|
+
|
|
615
847
|
except Exception as e:
|
|
616
848
|
# Deployment failure shouldn't block startup
|
|
617
849
|
from ..core.logger import get_logger
|
|
@@ -1139,33 +1371,74 @@ def show_skill_summary():
|
|
|
1139
1371
|
|
|
1140
1372
|
|
|
1141
1373
|
def verify_and_show_pm_skills():
|
|
1142
|
-
"""Verify PM skills and display status.
|
|
1374
|
+
"""Verify PM skills and display status with enhanced validation.
|
|
1143
1375
|
|
|
1144
|
-
WHY: PM skills are
|
|
1145
|
-
|
|
1376
|
+
WHY: PM skills are CRITICAL for PM agent operation. PM must KNOW if
|
|
1377
|
+
framework knowledge is unavailable at startup. Enhanced validation
|
|
1378
|
+
checks all required skills exist, are not corrupted, and auto-repairs
|
|
1379
|
+
if needed.
|
|
1380
|
+
|
|
1381
|
+
Shows deployment status:
|
|
1382
|
+
- "✓ PM skills: 8/8 verified" if all required skills are valid
|
|
1383
|
+
- "⚠ PM skills: 2 missing, auto-repairing..." if issues detected
|
|
1384
|
+
- Non-blocking but visible warning if auto-repair fails
|
|
1146
1385
|
"""
|
|
1147
1386
|
try:
|
|
1148
1387
|
from pathlib import Path
|
|
1149
1388
|
|
|
1150
|
-
from ..services.pm_skills_deployer import
|
|
1389
|
+
from ..services.pm_skills_deployer import (
|
|
1390
|
+
REQUIRED_PM_SKILLS,
|
|
1391
|
+
PMSkillsDeployerService,
|
|
1392
|
+
)
|
|
1151
1393
|
|
|
1152
1394
|
deployer = PMSkillsDeployerService()
|
|
1153
1395
|
project_dir = Path.cwd()
|
|
1154
1396
|
|
|
1155
|
-
|
|
1397
|
+
# Verify with auto-repair enabled
|
|
1398
|
+
result = deployer.verify_pm_skills(project_dir, auto_repair=True)
|
|
1156
1399
|
|
|
1157
1400
|
if result.verified:
|
|
1158
|
-
# Show verified status
|
|
1159
|
-
|
|
1401
|
+
# Show verified status with count
|
|
1402
|
+
total_required = len(REQUIRED_PM_SKILLS)
|
|
1403
|
+
if sys.stdout.isatty():
|
|
1404
|
+
print(
|
|
1405
|
+
f"✓ PM skills: {total_required}/{total_required} verified",
|
|
1406
|
+
flush=True,
|
|
1407
|
+
)
|
|
1160
1408
|
else:
|
|
1161
|
-
#
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1409
|
+
# Show warning with details
|
|
1410
|
+
missing_count = len(result.missing_skills)
|
|
1411
|
+
corrupted_count = len(result.corrupted_skills)
|
|
1412
|
+
|
|
1413
|
+
# Build status message
|
|
1414
|
+
issues = []
|
|
1415
|
+
if missing_count > 0:
|
|
1416
|
+
issues.append(f"{missing_count} missing")
|
|
1417
|
+
if corrupted_count > 0:
|
|
1418
|
+
issues.append(f"{corrupted_count} corrupted")
|
|
1419
|
+
|
|
1420
|
+
status = ", ".join(issues)
|
|
1421
|
+
|
|
1422
|
+
# Check if auto-repair was attempted
|
|
1423
|
+
if "Auto-repaired" in result.message:
|
|
1424
|
+
# Auto-repair succeeded
|
|
1425
|
+
total_required = len(REQUIRED_PM_SKILLS)
|
|
1426
|
+
if sys.stdout.isatty():
|
|
1427
|
+
print(
|
|
1428
|
+
f"✓ PM skills: {total_required}/{total_required} verified (auto-repaired)",
|
|
1429
|
+
flush=True,
|
|
1430
|
+
)
|
|
1167
1431
|
else:
|
|
1168
|
-
|
|
1432
|
+
# Auto-repair failed or not attempted
|
|
1433
|
+
if sys.stdout.isatty():
|
|
1434
|
+
print(f"⚠ PM skills: {status}", flush=True)
|
|
1435
|
+
|
|
1436
|
+
# Log warnings for debugging
|
|
1437
|
+
from ..core.logger import get_logger
|
|
1438
|
+
|
|
1439
|
+
logger = get_logger("cli")
|
|
1440
|
+
for warning in result.warnings:
|
|
1441
|
+
logger.warning(f"PM skills: {warning}")
|
|
1169
1442
|
|
|
1170
1443
|
except ImportError:
|
|
1171
1444
|
# PM skills deployer not available - skip silently
|
|
@@ -1218,6 +1491,28 @@ def auto_install_chrome_devtools_on_startup():
|
|
|
1218
1491
|
# Continue execution - chrome-devtools installation failure shouldn't block startup
|
|
1219
1492
|
|
|
1220
1493
|
|
|
1494
|
+
def sync_deployment_on_startup(force_sync: bool = False) -> None:
|
|
1495
|
+
"""Consolidated deployment block: hooks + agents.
|
|
1496
|
+
|
|
1497
|
+
WHY: Groups all deployment tasks into a single logical block for clarity.
|
|
1498
|
+
This ensures hooks and agents are deployed together before other services.
|
|
1499
|
+
|
|
1500
|
+
Order:
|
|
1501
|
+
1. Hook cleanup (remove ~/.claude/hooks/claude-mpm/)
|
|
1502
|
+
2. Hook reinstall (update .claude/settings.local.json)
|
|
1503
|
+
3. Agent sync from remote Git sources
|
|
1504
|
+
|
|
1505
|
+
Args:
|
|
1506
|
+
force_sync: Force download even if cache is fresh (bypasses ETag).
|
|
1507
|
+
"""
|
|
1508
|
+
# Step 1-2: Hooks (cleanup + reinstall handled by sync_hooks_on_startup)
|
|
1509
|
+
sync_hooks_on_startup() # Shows "Syncing Claude Code hooks... ✓"
|
|
1510
|
+
|
|
1511
|
+
# Step 3: Agents from remote sources
|
|
1512
|
+
sync_remote_agents_on_startup(force_sync=force_sync)
|
|
1513
|
+
show_agent_summary() # Display agent counts after deployment
|
|
1514
|
+
|
|
1515
|
+
|
|
1221
1516
|
def run_background_services(force_sync: bool = False):
|
|
1222
1517
|
"""
|
|
1223
1518
|
Initialize all background services on startup.
|
|
@@ -1233,19 +1528,21 @@ def run_background_services(force_sync: bool = False):
|
|
|
1233
1528
|
Args:
|
|
1234
1529
|
force_sync: Force download even if cache is fresh (bypasses ETag).
|
|
1235
1530
|
"""
|
|
1236
|
-
#
|
|
1237
|
-
#
|
|
1238
|
-
|
|
1239
|
-
|
|
1531
|
+
# Run startup migrations FIRST (before any sync operations)
|
|
1532
|
+
# These fix configuration issues from previous versions
|
|
1533
|
+
from .startup_migrations import run_migrations
|
|
1534
|
+
|
|
1535
|
+
run_migrations()
|
|
1536
|
+
|
|
1537
|
+
# Consolidated deployment block: hooks + agents
|
|
1538
|
+
# RATIONALE: Hooks and agents are deployed together before other services
|
|
1539
|
+
# This ensures the deployment phase is complete before configuration checks
|
|
1540
|
+
sync_deployment_on_startup(force_sync=force_sync)
|
|
1240
1541
|
|
|
1241
1542
|
initialize_project_registry()
|
|
1242
1543
|
check_mcp_auto_configuration()
|
|
1243
1544
|
verify_mcp_gateway_startup()
|
|
1244
1545
|
check_for_updates_async()
|
|
1245
|
-
sync_remote_agents_on_startup(
|
|
1246
|
-
force_sync=force_sync
|
|
1247
|
-
) # Sync agents from remote sources
|
|
1248
|
-
show_agent_summary() # Display agent counts after deployment
|
|
1249
1546
|
|
|
1250
1547
|
# Skills deployment order (precedence: remote > bundled)
|
|
1251
1548
|
# 1. Deploy bundled skills first (base layer from package)
|
|
@@ -1357,7 +1654,9 @@ def check_mcp_auto_configuration():
|
|
|
1357
1654
|
from ..services.mcp_gateway.auto_configure import check_and_configure_mcp
|
|
1358
1655
|
|
|
1359
1656
|
# Show progress feedback - this operation can take 10+ seconds
|
|
1360
|
-
|
|
1657
|
+
# Only show progress message in TTY mode to avoid interfering with Claude Code's status display
|
|
1658
|
+
if sys.stdout.isatty():
|
|
1659
|
+
print("Checking MCP configuration...", end="", flush=True)
|
|
1361
1660
|
|
|
1362
1661
|
# This function handles all the logic:
|
|
1363
1662
|
# - Checks if already configured
|
|
@@ -1368,11 +1667,17 @@ def check_mcp_auto_configuration():
|
|
|
1368
1667
|
check_and_configure_mcp()
|
|
1369
1668
|
|
|
1370
1669
|
# Clear the "Checking..." message by overwriting with spaces
|
|
1371
|
-
|
|
1670
|
+
# Only use carriage return clearing if stdout is a real TTY
|
|
1671
|
+
if sys.stdout.isatty():
|
|
1672
|
+
print("\r" + " " * 30 + "\r", end="", flush=True)
|
|
1673
|
+
# In non-TTY mode, don't print anything - the "Checking..." message will just remain on its line
|
|
1372
1674
|
|
|
1373
1675
|
except Exception as e:
|
|
1374
1676
|
# Clear progress message on error
|
|
1375
|
-
|
|
1677
|
+
# Only use carriage return clearing if stdout is a real TTY
|
|
1678
|
+
if sys.stdout.isatty():
|
|
1679
|
+
print("\r" + " " * 30 + "\r", end="", flush=True)
|
|
1680
|
+
# In non-TTY mode, don't print anything - the "Checking..." message will just remain on its line
|
|
1376
1681
|
|
|
1377
1682
|
# Non-critical - log but don't fail
|
|
1378
1683
|
from ..core.logger import get_logger
|