claude-mpm 5.4.41__py3-none-any.whl → 5.6.72__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of claude-mpm might be problematic. Click here for more details.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/CLAUDE_MPM_OUTPUT_STYLE.md +66 -241
- claude_mpm/agents/CLAUDE_MPM_RESEARCH_OUTPUT_STYLE.md +413 -0
- claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +109 -1925
- claude_mpm/agents/PM_INSTRUCTIONS.md +161 -298
- claude_mpm/agents/WORKFLOW.md +2 -0
- claude_mpm/agents/templates/circuit-breakers.md +26 -17
- claude_mpm/auth/__init__.py +35 -0
- claude_mpm/auth/callback_server.py +328 -0
- claude_mpm/auth/models.py +104 -0
- claude_mpm/auth/oauth_manager.py +266 -0
- claude_mpm/auth/providers/__init__.py +12 -0
- claude_mpm/auth/providers/base.py +165 -0
- claude_mpm/auth/providers/google.py +261 -0
- claude_mpm/auth/token_storage.py +252 -0
- claude_mpm/cli/__init__.py +5 -1
- claude_mpm/cli/commands/agents.py +2 -4
- claude_mpm/cli/commands/agents_reconcile.py +197 -0
- claude_mpm/cli/commands/autotodos.py +566 -0
- claude_mpm/cli/commands/commander.py +216 -0
- claude_mpm/cli/commands/configure.py +620 -21
- claude_mpm/cli/commands/configure_agent_display.py +3 -1
- claude_mpm/cli/commands/hook_errors.py +60 -60
- claude_mpm/cli/commands/mcp.py +29 -17
- claude_mpm/cli/commands/mcp_command_router.py +39 -0
- claude_mpm/cli/commands/mcp_service_commands.py +304 -0
- claude_mpm/cli/commands/monitor.py +2 -2
- claude_mpm/cli/commands/mpm_init/core.py +15 -8
- claude_mpm/cli/commands/oauth.py +481 -0
- claude_mpm/cli/commands/profile.py +9 -10
- claude_mpm/cli/commands/run.py +35 -3
- claude_mpm/cli/commands/skill_source.py +51 -2
- claude_mpm/cli/commands/skills.py +182 -32
- claude_mpm/cli/executor.py +129 -16
- claude_mpm/cli/helpers.py +1 -1
- claude_mpm/cli/interactive/__init__.py +10 -0
- claude_mpm/cli/interactive/agent_wizard.py +30 -50
- claude_mpm/cli/interactive/questionary_styles.py +65 -0
- claude_mpm/cli/interactive/skill_selector.py +481 -0
- claude_mpm/cli/parsers/base_parser.py +89 -1
- claude_mpm/cli/parsers/commander_parser.py +116 -0
- claude_mpm/cli/parsers/mcp_parser.py +79 -0
- claude_mpm/cli/parsers/oauth_parser.py +165 -0
- claude_mpm/cli/parsers/profile_parser.py +0 -1
- claude_mpm/cli/parsers/run_parser.py +10 -0
- claude_mpm/cli/parsers/skill_source_parser.py +4 -0
- claude_mpm/cli/parsers/skills_parser.py +2 -3
- claude_mpm/cli/startup.py +662 -524
- claude_mpm/cli/startup_display.py +76 -7
- claude_mpm/cli/startup_logging.py +2 -2
- claude_mpm/cli/utils.py +7 -3
- claude_mpm/commander/__init__.py +78 -0
- claude_mpm/commander/adapters/__init__.py +60 -0
- claude_mpm/commander/adapters/auggie.py +260 -0
- claude_mpm/commander/adapters/base.py +288 -0
- claude_mpm/commander/adapters/claude_code.py +392 -0
- claude_mpm/commander/adapters/codex.py +237 -0
- claude_mpm/commander/adapters/communication.py +366 -0
- claude_mpm/commander/adapters/example_usage.py +310 -0
- claude_mpm/commander/adapters/mpm.py +389 -0
- claude_mpm/commander/adapters/registry.py +204 -0
- claude_mpm/commander/api/__init__.py +16 -0
- claude_mpm/commander/api/app.py +121 -0
- claude_mpm/commander/api/errors.py +133 -0
- claude_mpm/commander/api/routes/__init__.py +8 -0
- claude_mpm/commander/api/routes/events.py +184 -0
- claude_mpm/commander/api/routes/inbox.py +171 -0
- claude_mpm/commander/api/routes/messages.py +148 -0
- claude_mpm/commander/api/routes/projects.py +271 -0
- claude_mpm/commander/api/routes/sessions.py +226 -0
- claude_mpm/commander/api/routes/work.py +296 -0
- claude_mpm/commander/api/schemas.py +186 -0
- claude_mpm/commander/chat/__init__.py +7 -0
- claude_mpm/commander/chat/cli.py +149 -0
- claude_mpm/commander/chat/commands.py +122 -0
- claude_mpm/commander/chat/repl.py +1821 -0
- claude_mpm/commander/config.py +51 -0
- claude_mpm/commander/config_loader.py +115 -0
- claude_mpm/commander/core/__init__.py +10 -0
- claude_mpm/commander/core/block_manager.py +325 -0
- claude_mpm/commander/core/response_manager.py +323 -0
- claude_mpm/commander/daemon.py +603 -0
- claude_mpm/commander/env_loader.py +59 -0
- claude_mpm/commander/events/__init__.py +26 -0
- claude_mpm/commander/events/manager.py +392 -0
- claude_mpm/commander/frameworks/__init__.py +12 -0
- claude_mpm/commander/frameworks/base.py +233 -0
- claude_mpm/commander/frameworks/claude_code.py +58 -0
- claude_mpm/commander/frameworks/mpm.py +57 -0
- claude_mpm/commander/git/__init__.py +5 -0
- claude_mpm/commander/git/worktree_manager.py +212 -0
- claude_mpm/commander/inbox/__init__.py +16 -0
- claude_mpm/commander/inbox/dedup.py +128 -0
- claude_mpm/commander/inbox/inbox.py +224 -0
- claude_mpm/commander/inbox/models.py +70 -0
- claude_mpm/commander/instance_manager.py +865 -0
- claude_mpm/commander/llm/__init__.py +6 -0
- claude_mpm/commander/llm/openrouter_client.py +167 -0
- claude_mpm/commander/llm/summarizer.py +70 -0
- claude_mpm/commander/memory/__init__.py +45 -0
- claude_mpm/commander/memory/compression.py +347 -0
- claude_mpm/commander/memory/embeddings.py +230 -0
- claude_mpm/commander/memory/entities.py +310 -0
- claude_mpm/commander/memory/example_usage.py +290 -0
- claude_mpm/commander/memory/integration.py +325 -0
- claude_mpm/commander/memory/search.py +381 -0
- claude_mpm/commander/memory/store.py +657 -0
- claude_mpm/commander/models/__init__.py +18 -0
- claude_mpm/commander/models/events.py +127 -0
- claude_mpm/commander/models/project.py +162 -0
- claude_mpm/commander/models/work.py +214 -0
- claude_mpm/commander/parsing/__init__.py +20 -0
- claude_mpm/commander/parsing/extractor.py +132 -0
- claude_mpm/commander/parsing/output_parser.py +270 -0
- claude_mpm/commander/parsing/patterns.py +100 -0
- claude_mpm/commander/persistence/__init__.py +11 -0
- claude_mpm/commander/persistence/event_store.py +274 -0
- claude_mpm/commander/persistence/state_store.py +403 -0
- claude_mpm/commander/persistence/work_store.py +164 -0
- claude_mpm/commander/polling/__init__.py +13 -0
- claude_mpm/commander/polling/event_detector.py +104 -0
- claude_mpm/commander/polling/output_buffer.py +49 -0
- claude_mpm/commander/polling/output_poller.py +153 -0
- claude_mpm/commander/project_session.py +268 -0
- claude_mpm/commander/proxy/__init__.py +12 -0
- claude_mpm/commander/proxy/formatter.py +89 -0
- claude_mpm/commander/proxy/output_handler.py +191 -0
- claude_mpm/commander/proxy/relay.py +155 -0
- claude_mpm/commander/registry.py +410 -0
- claude_mpm/commander/runtime/__init__.py +10 -0
- claude_mpm/commander/runtime/executor.py +191 -0
- claude_mpm/commander/runtime/monitor.py +346 -0
- claude_mpm/commander/session/__init__.py +6 -0
- claude_mpm/commander/session/context.py +81 -0
- claude_mpm/commander/session/manager.py +59 -0
- claude_mpm/commander/tmux_orchestrator.py +362 -0
- claude_mpm/commander/web/__init__.py +1 -0
- claude_mpm/commander/work/__init__.py +30 -0
- claude_mpm/commander/work/executor.py +207 -0
- claude_mpm/commander/work/queue.py +405 -0
- claude_mpm/commander/workflow/__init__.py +27 -0
- claude_mpm/commander/workflow/event_handler.py +241 -0
- claude_mpm/commander/workflow/notifier.py +146 -0
- claude_mpm/commands/mpm-config.md +8 -0
- claude_mpm/commands/mpm-doctor.md +8 -0
- claude_mpm/commands/mpm-help.md +8 -0
- claude_mpm/commands/mpm-init.md +8 -0
- claude_mpm/commands/mpm-monitor.md +8 -0
- claude_mpm/commands/mpm-organize.md +8 -0
- claude_mpm/commands/mpm-postmortem.md +8 -0
- claude_mpm/commands/mpm-session-resume.md +9 -1
- claude_mpm/commands/mpm-status.md +8 -0
- claude_mpm/commands/mpm-ticket-view.md +8 -0
- claude_mpm/commands/mpm-version.md +8 -0
- claude_mpm/commands/mpm.md +8 -0
- claude_mpm/config/agent_presets.py +8 -7
- claude_mpm/config/skill_sources.py +16 -0
- claude_mpm/constants.py +6 -0
- claude_mpm/core/claude_runner.py +154 -2
- claude_mpm/core/config.py +35 -22
- claude_mpm/core/config_constants.py +74 -9
- claude_mpm/core/constants.py +56 -12
- claude_mpm/core/hook_manager.py +53 -4
- claude_mpm/core/interactive_session.py +12 -11
- claude_mpm/core/logger.py +26 -9
- claude_mpm/core/logging_utils.py +39 -13
- claude_mpm/core/network_config.py +148 -0
- claude_mpm/core/oneshot_session.py +7 -6
- claude_mpm/core/optimized_startup.py +3 -1
- claude_mpm/core/output_style_manager.py +66 -18
- claude_mpm/core/shared/config_loader.py +3 -1
- claude_mpm/core/socketio_pool.py +47 -15
- claude_mpm/core/unified_config.py +54 -8
- claude_mpm/core/unified_paths.py +95 -90
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.C33zOoyM.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.CW1J-YuA.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/1WZnGYqX.js +24 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/67pF3qNn.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/6RxdMKe4.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/8cZrfX0h.js +60 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/9a6T2nm-.js +7 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B443AUzu.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B8AwtY2H.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BF15LAsF.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BQaXIfA_.js +331 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BRcwIQNr.js +4 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{uj46x2Wr.js → BSNlmTZj.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BV6nKitt.js +43 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BViJ8lZt.js +128 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BcQ-Q0FE.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Bpyvgze_.js +30 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BzTRqg-z.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C0Fr8dve.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C3rbW_a-.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C8WYN38h.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C9I8FlXH.js +61 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIQcWgO2.js +36 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIctN7YN.js +7 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CKrS_JZW.js +145 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CR6P9C4A.js +89 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRRR9MD_.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRcR2DqT.js +334 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CSXtMOf0.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CT-sbxSk.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWm6DJsp.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CmKTTxBW.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CpqQ1Kzn.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cu_Erd72.js +261 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D2nGpDRe.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9iCMida.js +267 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9ykgMoY.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DL2Ldur1.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DPfltzjH.js +165 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{N4qtv3Hx.js → DR8nis88.js} +2 -2
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DUliQN2b.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DVp1hx9R.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DXlhR01x.js +122 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D_lyTybS.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DngoTTgh.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DqkmHtDC.js +220 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DsDh8EYs.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DypDmXgd.js +139 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Gi6I4Gst.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/IPYC-LnN.js +162 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JTLiF7dt.js +24 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JpevfAFt.js +68 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DjhvlsAc.js → NqQ1dWOy.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/R8CEIRAd.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Zxy7qc-l.js +64 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/q9Hm6zAU.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/qtd3IeO4.js +15 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/ulBFON_C.js +65 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/wQVh1CoA.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.Dr7t0z2J.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.BGhZHUS3.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/{0.CAGBuiOw.js → 0.RgBboRvH.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DG-KkbDf.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.D_jnf-x6.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -1
- claude_mpm/dashboard/static/svelte-build/index.html +11 -11
- claude_mpm/dashboard-svelte/node_modules/katex/src/fonts/generate_fonts.py +58 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_tfms.py +114 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_ttfs.py +122 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/format_json.py +28 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/parse_tfm.py +211 -0
- claude_mpm/experimental/cli_enhancements.py +2 -1
- claude_mpm/hooks/claude_hooks/INTEGRATION_EXAMPLE.md +243 -0
- claude_mpm/hooks/claude_hooks/README_AUTO_PAUSE.md +403 -0
- claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/auto_pause_handler.py +485 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +466 -136
- claude_mpm/hooks/claude_hooks/hook_handler.py +204 -104
- claude_mpm/hooks/claude_hooks/hook_wrapper.sh +6 -11
- claude_mpm/hooks/claude_hooks/installer.py +291 -59
- claude_mpm/hooks/claude_hooks/memory_integration.py +52 -32
- claude_mpm/hooks/claude_hooks/response_tracking.py +43 -60
- claude_mpm/hooks/claude_hooks/services/__init__.py +21 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/container.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/protocols.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/connection_manager.py +41 -26
- claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +38 -105
- claude_mpm/hooks/claude_hooks/services/container.py +326 -0
- claude_mpm/hooks/claude_hooks/services/protocols.py +328 -0
- claude_mpm/hooks/claude_hooks/services/state_manager.py +25 -38
- claude_mpm/hooks/claude_hooks/services/subagent_processor.py +75 -77
- claude_mpm/hooks/kuzu_memory_hook.py +5 -5
- claude_mpm/hooks/session_resume_hook.py +89 -1
- claude_mpm/hooks/templates/pre_tool_use_simple.py +6 -6
- claude_mpm/hooks/templates/pre_tool_use_template.py +16 -8
- claude_mpm/init.py +224 -4
- claude_mpm/mcp/__init__.py +9 -0
- claude_mpm/mcp/google_workspace_server.py +610 -0
- claude_mpm/scripts/claude-hook-handler.sh +46 -19
- claude_mpm/services/agents/agent_recommendation_service.py +8 -8
- claude_mpm/services/agents/agent_selection_service.py +2 -2
- claude_mpm/services/agents/cache_git_manager.py +1 -1
- claude_mpm/services/agents/deployment/agent_discovery_service.py +3 -1
- claude_mpm/services/agents/deployment/agent_format_converter.py +25 -13
- claude_mpm/services/agents/deployment/agent_template_builder.py +37 -17
- claude_mpm/services/agents/deployment/async_agent_deployment.py +31 -27
- claude_mpm/services/agents/deployment/deployment_reconciler.py +577 -0
- claude_mpm/services/agents/deployment/local_template_deployment.py +3 -1
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +36 -8
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +50 -26
- claude_mpm/services/agents/deployment/startup_reconciliation.py +138 -0
- claude_mpm/services/agents/git_source_manager.py +21 -2
- claude_mpm/services/agents/loading/framework_agent_loader.py +75 -2
- claude_mpm/services/agents/single_tier_deployment_service.py +4 -4
- claude_mpm/services/agents/sources/git_source_sync_service.py +116 -5
- claude_mpm/services/agents/startup_sync.py +5 -2
- claude_mpm/services/cli/__init__.py +3 -0
- claude_mpm/services/cli/incremental_pause_manager.py +561 -0
- claude_mpm/services/cli/session_resume_helper.py +10 -2
- claude_mpm/services/command_deployment_service.py +44 -26
- claude_mpm/services/delegation_detector.py +175 -0
- claude_mpm/services/diagnostics/checks/agent_sources_check.py +30 -0
- claude_mpm/services/diagnostics/checks/configuration_check.py +24 -0
- claude_mpm/services/diagnostics/checks/installation_check.py +22 -0
- claude_mpm/services/diagnostics/checks/mcp_services_check.py +23 -0
- claude_mpm/services/diagnostics/doctor_reporter.py +31 -1
- claude_mpm/services/diagnostics/models.py +14 -1
- claude_mpm/services/event_log.py +325 -0
- claude_mpm/services/hook_installer_service.py +77 -8
- claude_mpm/services/infrastructure/__init__.py +4 -0
- claude_mpm/services/infrastructure/context_usage_tracker.py +291 -0
- claude_mpm/services/infrastructure/resume_log_generator.py +24 -5
- claude_mpm/services/mcp_config_manager.py +99 -19
- claude_mpm/services/mcp_service_registry.py +294 -0
- claude_mpm/services/monitor/daemon_manager.py +15 -4
- claude_mpm/services/monitor/management/lifecycle.py +8 -3
- claude_mpm/services/monitor/server.py +111 -16
- claude_mpm/services/pm_skills_deployer.py +302 -94
- claude_mpm/services/profile_manager.py +10 -4
- claude_mpm/services/skills/git_skill_source_manager.py +192 -29
- claude_mpm/services/skills/selective_skill_deployer.py +211 -46
- claude_mpm/services/skills/skill_discovery_service.py +74 -4
- claude_mpm/services/skills_deployer.py +192 -70
- claude_mpm/services/socketio/handlers/hook.py +14 -7
- claude_mpm/services/socketio/server/main.py +12 -4
- claude_mpm/skills/__init__.py +2 -1
- claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
- claude_mpm/skills/bundled/collaboration/git-worktrees.md +317 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
- claude_mpm/skills/bundled/collaboration/stacked-prs.md +251 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/INTEGRATION.md +611 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/README.md +596 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/SKILL.md +260 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/examples/nextjs-env-structure.md +315 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/frameworks.md +436 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/security.md +433 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/synchronization.md +452 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/troubleshooting.md +404 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/validation.md +420 -0
- claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
- claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
- claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
- claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
- claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
- claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
- claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
- claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
- claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
- claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
- claude_mpm/skills/bundled/pm/mpm/SKILL.md +38 -0
- claude_mpm/skills/bundled/pm/mpm-agent-update-workflow/SKILL.md +75 -0
- claude_mpm/skills/bundled/pm/mpm-bug-reporting/SKILL.md +248 -0
- claude_mpm/skills/bundled/pm/mpm-circuit-breaker-enforcement/SKILL.md +476 -0
- claude_mpm/skills/bundled/pm/mpm-config/SKILL.md +29 -0
- claude_mpm/skills/bundled/pm/mpm-delegation-patterns/SKILL.md +167 -0
- claude_mpm/skills/bundled/pm/mpm-doctor/SKILL.md +53 -0
- claude_mpm/skills/bundled/pm/mpm-git-file-tracking/SKILL.md +113 -0
- claude_mpm/skills/bundled/pm/mpm-help/SKILL.md +35 -0
- claude_mpm/skills/bundled/pm/mpm-init/SKILL.md +125 -0
- claude_mpm/skills/bundled/pm/mpm-monitor/SKILL.md +32 -0
- claude_mpm/skills/bundled/pm/mpm-organize/SKILL.md +121 -0
- claude_mpm/skills/bundled/pm/mpm-postmortem/SKILL.md +22 -0
- claude_mpm/skills/bundled/pm/mpm-pr-workflow/SKILL.md +124 -0
- claude_mpm/skills/bundled/pm/mpm-session-management/SKILL.md +312 -0
- claude_mpm/skills/bundled/pm/mpm-session-pause/SKILL.md +170 -0
- claude_mpm/skills/bundled/pm/mpm-session-resume/SKILL.md +31 -0
- claude_mpm/skills/bundled/pm/mpm-status/SKILL.md +37 -0
- claude_mpm/skills/bundled/pm/mpm-teaching-mode/SKILL.md +657 -0
- claude_mpm/skills/bundled/pm/mpm-ticket-view/SKILL.md +110 -0
- claude_mpm/skills/bundled/pm/mpm-ticketing-integration/SKILL.md +154 -0
- claude_mpm/skills/bundled/pm/mpm-tool-usage-guide/SKILL.md +386 -0
- claude_mpm/skills/bundled/pm/mpm-verification-protocols/SKILL.md +198 -0
- claude_mpm/skills/bundled/pm/mpm-version/SKILL.md +21 -0
- claude_mpm/skills/bundled/react/flexlayout-react.md +742 -0
- claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
- claude_mpm/skills/bundled/security-scanning.md +112 -0
- claude_mpm/skills/bundled/tauri/tauri-async-patterns.md +495 -0
- claude_mpm/skills/bundled/tauri/tauri-build-deploy.md +599 -0
- claude_mpm/skills/bundled/tauri/tauri-command-patterns.md +535 -0
- claude_mpm/skills/bundled/tauri/tauri-error-handling.md +613 -0
- claude_mpm/skills/bundled/tauri/tauri-event-system.md +648 -0
- claude_mpm/skills/bundled/tauri/tauri-file-system.md +673 -0
- claude_mpm/skills/bundled/tauri/tauri-frontend-integration.md +767 -0
- claude_mpm/skills/bundled/tauri/tauri-performance.md +669 -0
- claude_mpm/skills/bundled/tauri/tauri-state-management.md +573 -0
- claude_mpm/skills/bundled/tauri/tauri-testing.md +384 -0
- claude_mpm/skills/bundled/tauri/tauri-window-management.md +628 -0
- claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
- claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
- claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/SKILL.md +458 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/examples/example-inspection-report.md +411 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/assertion-quality.md +317 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/inspection-checklist.md +270 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/red-flags.md +436 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
- claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
- claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
- claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
- claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
- claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
- claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
- claude_mpm/skills/registry.py +295 -90
- claude_mpm/skills/skill_manager.py +29 -23
- claude_mpm/templates/.pre-commit-config.yaml +112 -0
- claude_mpm/utils/agent_dependency_loader.py +103 -4
- claude_mpm/utils/robust_installer.py +45 -24
- claude_mpm-5.6.72.dist-info/METADATA +416 -0
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.72.dist-info}/RECORD +477 -159
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.72.dist-info}/WHEEL +1 -1
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.72.dist-info}/entry_points.txt +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.B_FtCwCQ.css +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.Cl_eSA4x.css +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BgChzWQ1.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIXEwuWe.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWc5urbQ.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DMkZpdF2.js +0 -2
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.DTL5mJO-.js +0 -2
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.DzuEhzqh.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DFLC8jdE.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.DPvEihJJ.js +0 -10
- claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager.cpython-311.pyc +0 -0
- claude_mpm-5.4.41.dist-info/METADATA +0 -998
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.72.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.72.dist-info}/licenses/LICENSE-FAQ.md +0 -0
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.72.dist-info}/top_level.txt +0 -0
|
@@ -28,7 +28,7 @@ References:
|
|
|
28
28
|
import json
|
|
29
29
|
import platform
|
|
30
30
|
import shutil
|
|
31
|
-
import subprocess
|
|
31
|
+
import subprocess # nosec B404 - subprocess needed for safe git operations
|
|
32
32
|
from pathlib import Path
|
|
33
33
|
from typing import Any, Dict, List, Optional
|
|
34
34
|
|
|
@@ -174,44 +174,93 @@ class SkillsDeployerService(LoggerMixin):
|
|
|
174
174
|
if selective:
|
|
175
175
|
# Auto-detect project root if not provided
|
|
176
176
|
if project_root is None:
|
|
177
|
-
# Try to find project root by looking for .claude directory
|
|
177
|
+
# Try to find project root by looking for .claude-mpm directory
|
|
178
178
|
# Start from current directory and walk up
|
|
179
179
|
current = Path.cwd()
|
|
180
180
|
while current != current.parent:
|
|
181
|
-
if (current / ".claude").exists():
|
|
181
|
+
if (current / ".claude-mpm").exists():
|
|
182
182
|
project_root = current
|
|
183
183
|
break
|
|
184
184
|
current = current.parent
|
|
185
185
|
|
|
186
|
+
# Read skills from configuration.yaml instead of agent frontmatter
|
|
186
187
|
if project_root:
|
|
187
|
-
|
|
188
|
+
config_path = Path(project_root) / ".claude-mpm" / "configuration.yaml"
|
|
188
189
|
else:
|
|
189
|
-
# Fallback to current directory's
|
|
190
|
-
|
|
190
|
+
# Fallback to current directory's configuration
|
|
191
|
+
config_path = Path.cwd() / ".claude-mpm" / "configuration.yaml"
|
|
191
192
|
|
|
192
193
|
from claude_mpm.services.skills.selective_skill_deployer import (
|
|
193
194
|
get_required_skills_from_agents,
|
|
195
|
+
get_skills_to_deploy,
|
|
196
|
+
save_agent_skills_to_config,
|
|
194
197
|
)
|
|
195
198
|
|
|
196
|
-
|
|
199
|
+
# Check if agent_referenced is empty and needs to be populated
|
|
200
|
+
required_skill_names, source = get_skills_to_deploy(config_path)
|
|
201
|
+
|
|
202
|
+
if not required_skill_names and project_root:
|
|
203
|
+
# agent_referenced is empty, scan deployed agents to populate it
|
|
204
|
+
agents_dir = Path(project_root) / ".claude" / "agents"
|
|
205
|
+
if agents_dir.exists():
|
|
206
|
+
self.logger.info(
|
|
207
|
+
"agent_referenced is empty in configuration.yaml, scanning deployed agents..."
|
|
208
|
+
)
|
|
209
|
+
agent_skills = get_required_skills_from_agents(agents_dir)
|
|
210
|
+
if agent_skills:
|
|
211
|
+
save_agent_skills_to_config(list(agent_skills), config_path)
|
|
212
|
+
self.logger.info(
|
|
213
|
+
f"Populated agent_referenced with {len(agent_skills)} skills from deployed agents"
|
|
214
|
+
)
|
|
215
|
+
# Re-read configuration after update
|
|
216
|
+
required_skill_names, source = get_skills_to_deploy(config_path)
|
|
217
|
+
else:
|
|
218
|
+
self.logger.warning(
|
|
219
|
+
"No skills found in deployed agents - configuration.yaml remains empty"
|
|
220
|
+
)
|
|
221
|
+
else:
|
|
222
|
+
self.logger.warning(
|
|
223
|
+
f"Agents directory not found at {agents_dir} - cannot scan for skills"
|
|
224
|
+
)
|
|
197
225
|
|
|
198
226
|
if required_skill_names:
|
|
227
|
+
# Convert required_skill_names to a set for O(1) lookup
|
|
228
|
+
required_set = set(required_skill_names)
|
|
229
|
+
|
|
199
230
|
# Filter to only required skills
|
|
200
|
-
# Match on
|
|
231
|
+
# Match on: 'name', 'skill_id', or normalized 'source_path'
|
|
232
|
+
# source_path example: "universal/web/api-design-patterns/SKILL.md"
|
|
233
|
+
# normalized: "universal-web-api-design-patterns"
|
|
234
|
+
def skill_matches_requirement(skill):
|
|
235
|
+
# Check basic name and skill_id
|
|
236
|
+
if skill.get("name") in required_set:
|
|
237
|
+
return True
|
|
238
|
+
if skill.get("skill_id") in required_set:
|
|
239
|
+
return True
|
|
240
|
+
|
|
241
|
+
# Check normalized source_path
|
|
242
|
+
source_path = skill.get("source_path", "")
|
|
243
|
+
if source_path:
|
|
244
|
+
# Remove /SKILL.md suffix and replace / with -
|
|
245
|
+
normalized = source_path.replace("/SKILL.md", "").replace(
|
|
246
|
+
"/", "-"
|
|
247
|
+
)
|
|
248
|
+
if normalized in required_set:
|
|
249
|
+
return True
|
|
250
|
+
|
|
251
|
+
return False
|
|
252
|
+
|
|
201
253
|
filtered_skills = [
|
|
202
|
-
s
|
|
203
|
-
for s in filtered_skills
|
|
204
|
-
if s.get("name") in required_skill_names
|
|
205
|
-
or s.get("skill_id") in required_skill_names
|
|
254
|
+
s for s in filtered_skills if skill_matches_requirement(s)
|
|
206
255
|
]
|
|
207
256
|
|
|
208
257
|
self.logger.info(
|
|
209
258
|
f"Selective deployment: {len(filtered_skills)}/{total_available} skills "
|
|
210
|
-
f"(
|
|
259
|
+
f"(source: {source})"
|
|
211
260
|
)
|
|
212
261
|
else:
|
|
213
262
|
self.logger.warning(
|
|
214
|
-
f"No skills found in
|
|
263
|
+
f"No skills found in configuration at {config_path}. "
|
|
215
264
|
f"Deploying all {total_available} skills."
|
|
216
265
|
)
|
|
217
266
|
else:
|
|
@@ -224,12 +273,19 @@ class SkillsDeployerService(LoggerMixin):
|
|
|
224
273
|
skipped = []
|
|
225
274
|
errors = []
|
|
226
275
|
|
|
227
|
-
# Extract skill names for cleanup (needed regardless of deployment outcome)
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
if isinstance(skill, dict) and "name" in skill
|
|
232
|
-
|
|
276
|
+
# Extract normalized skill names for cleanup (needed regardless of deployment outcome)
|
|
277
|
+
# Must match the names used during deployment (normalized from source_path)
|
|
278
|
+
filtered_skills_names = []
|
|
279
|
+
for skill in filtered_skills:
|
|
280
|
+
if isinstance(skill, dict) and "name" in skill:
|
|
281
|
+
source_path = skill.get("source_path", "")
|
|
282
|
+
if source_path:
|
|
283
|
+
# Normalize: "universal/web/api-design-patterns/SKILL.md" -> "universal-web-api-design-patterns"
|
|
284
|
+
normalized = source_path.replace("/SKILL.md", "").replace("/", "-")
|
|
285
|
+
filtered_skills_names.append(normalized)
|
|
286
|
+
else:
|
|
287
|
+
# Fallback to skill name
|
|
288
|
+
filtered_skills_names.append(skill["name"])
|
|
233
289
|
|
|
234
290
|
for skill in filtered_skills:
|
|
235
291
|
try:
|
|
@@ -243,9 +299,25 @@ class SkillsDeployerService(LoggerMixin):
|
|
|
243
299
|
skill, skills_data["temp_dir"], collection_name, force=force
|
|
244
300
|
)
|
|
245
301
|
if result["deployed"]:
|
|
246
|
-
|
|
302
|
+
# Use normalized name for reporting
|
|
303
|
+
source_path = skill.get("source_path", "")
|
|
304
|
+
if source_path:
|
|
305
|
+
normalized = source_path.replace("/SKILL.md", "").replace(
|
|
306
|
+
"/", "-"
|
|
307
|
+
)
|
|
308
|
+
deployed.append(normalized)
|
|
309
|
+
else:
|
|
310
|
+
deployed.append(skill["name"])
|
|
247
311
|
elif result["skipped"]:
|
|
248
|
-
|
|
312
|
+
# Use normalized name for reporting
|
|
313
|
+
source_path = skill.get("source_path", "")
|
|
314
|
+
if source_path:
|
|
315
|
+
normalized = source_path.replace("/SKILL.md", "").replace(
|
|
316
|
+
"/", "-"
|
|
317
|
+
)
|
|
318
|
+
skipped.append(normalized)
|
|
319
|
+
else:
|
|
320
|
+
skipped.append(skill["name"])
|
|
249
321
|
if result["error"]:
|
|
250
322
|
errors.append(result["error"])
|
|
251
323
|
except Exception as e:
|
|
@@ -257,9 +329,9 @@ class SkillsDeployerService(LoggerMixin):
|
|
|
257
329
|
self.logger.error(f"Failed to deploy {skill_name}: {e}")
|
|
258
330
|
errors.append(f"{skill_name}: {e}")
|
|
259
331
|
|
|
260
|
-
# Step 5: Cleanup orphaned skills (
|
|
332
|
+
# Step 5: Cleanup orphaned skills (always run in selective mode)
|
|
261
333
|
cleanup_result = {"removed_count": 0, "removed_skills": []}
|
|
262
|
-
if selective
|
|
334
|
+
if selective:
|
|
263
335
|
# Get the set of skills that should remain deployed
|
|
264
336
|
# This is the union of what we just deployed and what was already there
|
|
265
337
|
try:
|
|
@@ -267,7 +339,8 @@ class SkillsDeployerService(LoggerMixin):
|
|
|
267
339
|
cleanup_orphan_skills,
|
|
268
340
|
)
|
|
269
341
|
|
|
270
|
-
#
|
|
342
|
+
# Cleanup orphaned skills not referenced by agents
|
|
343
|
+
# This runs even if nothing new was deployed to remove stale skills
|
|
271
344
|
cleanup_result = cleanup_orphan_skills(
|
|
272
345
|
self.CLAUDE_SKILLS_DIR, set(filtered_skills_names)
|
|
273
346
|
)
|
|
@@ -580,7 +653,7 @@ class SkillsDeployerService(LoggerMixin):
|
|
|
580
653
|
f"Updating existing collection '{collection_name}' at {target_dir}"
|
|
581
654
|
)
|
|
582
655
|
try:
|
|
583
|
-
result = subprocess.run(
|
|
656
|
+
result = subprocess.run( # nosec B603 B607 - Safe: hardcoded git command
|
|
584
657
|
["git", "pull"],
|
|
585
658
|
cwd=target_dir,
|
|
586
659
|
capture_output=True,
|
|
@@ -611,7 +684,7 @@ class SkillsDeployerService(LoggerMixin):
|
|
|
611
684
|
f"Installing new collection '{collection_name}' to {target_dir}"
|
|
612
685
|
)
|
|
613
686
|
try:
|
|
614
|
-
result = subprocess.run(
|
|
687
|
+
result = subprocess.run( # nosec B603 B607 - Safe: hardcoded git command
|
|
615
688
|
["git", "clone", repo_url, str(target_dir)],
|
|
616
689
|
capture_output=True,
|
|
617
690
|
text=True,
|
|
@@ -700,6 +773,32 @@ class SkillsDeployerService(LoggerMixin):
|
|
|
700
773
|
if isinstance(skills_data, dict):
|
|
701
774
|
flat_skills = []
|
|
702
775
|
|
|
776
|
+
# Define valid top-level categories
|
|
777
|
+
VALID_CATEGORIES = {"universal", "toolchains"}
|
|
778
|
+
|
|
779
|
+
# Check for unknown categories and warn user
|
|
780
|
+
unknown_categories = set(skills_data.keys()) - VALID_CATEGORIES
|
|
781
|
+
if unknown_categories:
|
|
782
|
+
# Count skills in unknown categories
|
|
783
|
+
skipped_count = 0
|
|
784
|
+
for cat in unknown_categories:
|
|
785
|
+
cat_data = skills_data.get(cat, [])
|
|
786
|
+
if isinstance(cat_data, list):
|
|
787
|
+
skipped_count += len(cat_data)
|
|
788
|
+
elif isinstance(cat_data, dict):
|
|
789
|
+
# If it's a dict like toolchains, count nested skills
|
|
790
|
+
for skills_list in cat_data.values():
|
|
791
|
+
if isinstance(skills_list, list):
|
|
792
|
+
skipped_count += len(skills_list)
|
|
793
|
+
|
|
794
|
+
self.logger.warning(
|
|
795
|
+
f"Unknown categories in manifest will be skipped: "
|
|
796
|
+
f"{', '.join(sorted(unknown_categories))} ({skipped_count} skills)"
|
|
797
|
+
)
|
|
798
|
+
self.logger.info(
|
|
799
|
+
f"Valid top-level categories: {', '.join(sorted(VALID_CATEGORIES))}"
|
|
800
|
+
)
|
|
801
|
+
|
|
703
802
|
# Add universal skills
|
|
704
803
|
universal_skills = skills_data.get("universal", [])
|
|
705
804
|
if isinstance(universal_skills, list):
|
|
@@ -804,55 +903,76 @@ class SkillsDeployerService(LoggerMixin):
|
|
|
804
903
|
Dict with deployed, skipped, error flags
|
|
805
904
|
"""
|
|
806
905
|
skill_name = skill["name"]
|
|
807
|
-
|
|
906
|
+
|
|
907
|
+
# Use normalized source_path for both target directory and deployment tracking
|
|
908
|
+
# This ensures consistency with configuration.yaml skill names
|
|
909
|
+
source_path = skill.get("source_path", "")
|
|
910
|
+
if source_path:
|
|
911
|
+
# Normalize: "universal/web/api-design-patterns/SKILL.md" -> "universal-web-api-design-patterns"
|
|
912
|
+
normalized_name = source_path.replace("/SKILL.md", "").replace("/", "-")
|
|
913
|
+
target_dir = self.CLAUDE_SKILLS_DIR / normalized_name
|
|
914
|
+
else:
|
|
915
|
+
# Fallback to skill name if no source_path
|
|
916
|
+
target_dir = self.CLAUDE_SKILLS_DIR / skill_name
|
|
808
917
|
|
|
809
918
|
# Check if already deployed
|
|
810
919
|
if target_dir.exists() and not force:
|
|
811
920
|
self.logger.debug(f"Skipped {skill_name} (already deployed)")
|
|
812
921
|
return {"deployed": False, "skipped": True, "error": None}
|
|
813
922
|
|
|
814
|
-
# Find skill source
|
|
815
|
-
|
|
816
|
-
# OR: collection_dir / universal / skill-name
|
|
817
|
-
# OR: collection_dir / toolchains / toolchain-name / skill-name
|
|
923
|
+
# Find skill source using source_path from manifest
|
|
924
|
+
source_dir = None
|
|
818
925
|
|
|
819
|
-
|
|
820
|
-
|
|
926
|
+
if source_path:
|
|
927
|
+
# Direct lookup using source_path (most reliable)
|
|
928
|
+
# Example: "universal/web/api-design-patterns/SKILL.md" -> "universal/web/api-design-patterns"
|
|
929
|
+
skill_dir_path = source_path.replace("/SKILL.md", "")
|
|
930
|
+
potential_source = collection_dir / skill_dir_path
|
|
931
|
+
if potential_source.exists():
|
|
932
|
+
source_dir = potential_source
|
|
933
|
+
else:
|
|
934
|
+
self.logger.debug(
|
|
935
|
+
f"Source path {skill_dir_path} not found, trying fallback search"
|
|
936
|
+
)
|
|
821
937
|
|
|
822
|
-
#
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
search_paths
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
for cat_dir in skills_base.iterdir():
|
|
849
|
-
if not cat_dir.is_dir():
|
|
850
|
-
continue
|
|
851
|
-
potential = cat_dir / skill_name
|
|
852
|
-
if potential.exists():
|
|
853
|
-
source_dir = potential
|
|
938
|
+
# Fallback: search using old logic (for backward compatibility)
|
|
939
|
+
if not source_dir:
|
|
940
|
+
skills_base = collection_dir / "skills"
|
|
941
|
+
category = skill.get("category", "")
|
|
942
|
+
|
|
943
|
+
# Try multiple possible locations
|
|
944
|
+
search_paths = []
|
|
945
|
+
|
|
946
|
+
# Try category-based path
|
|
947
|
+
if category and skills_base.exists():
|
|
948
|
+
search_paths.append(skills_base / category / skill_name)
|
|
949
|
+
|
|
950
|
+
# Try universal/toolchains structure
|
|
951
|
+
if (collection_dir / "universal").exists():
|
|
952
|
+
search_paths.append(collection_dir / "universal" / skill_name)
|
|
953
|
+
|
|
954
|
+
if (collection_dir / "toolchains").exists():
|
|
955
|
+
toolchain_dir = collection_dir / "toolchains"
|
|
956
|
+
for tc in toolchain_dir.iterdir():
|
|
957
|
+
if tc.is_dir():
|
|
958
|
+
search_paths.append(tc / skill_name)
|
|
959
|
+
|
|
960
|
+
# Search in all possible locations
|
|
961
|
+
for path in search_paths:
|
|
962
|
+
if path.exists():
|
|
963
|
+
source_dir = path
|
|
854
964
|
break
|
|
855
965
|
|
|
966
|
+
# Final fallback: search recursively for skill in skills directory
|
|
967
|
+
if not source_dir and skills_base.exists():
|
|
968
|
+
for cat_dir in skills_base.iterdir():
|
|
969
|
+
if not cat_dir.is_dir():
|
|
970
|
+
continue
|
|
971
|
+
potential = cat_dir / skill_name
|
|
972
|
+
if potential.exists():
|
|
973
|
+
source_dir = potential
|
|
974
|
+
break
|
|
975
|
+
|
|
856
976
|
if not source_dir or not source_dir.exists():
|
|
857
977
|
return {
|
|
858
978
|
"deployed": False,
|
|
@@ -887,12 +1007,14 @@ class SkillsDeployerService(LoggerMixin):
|
|
|
887
1007
|
# NOTE: We use copy instead of symlink to maintain Claude Code compatibility
|
|
888
1008
|
shutil.copytree(source_dir, target_dir)
|
|
889
1009
|
|
|
890
|
-
# Track deployment in index
|
|
1010
|
+
# Track deployment in index using normalized name
|
|
891
1011
|
from claude_mpm.services.skills.selective_skill_deployer import (
|
|
892
1012
|
track_deployed_skill,
|
|
893
1013
|
)
|
|
894
1014
|
|
|
895
|
-
|
|
1015
|
+
# Use normalized name for tracking (matches configuration.yaml format)
|
|
1016
|
+
track_name = normalized_name if source_path else skill_name
|
|
1017
|
+
track_deployed_skill(self.CLAUDE_SKILLS_DIR, track_name, collection_name)
|
|
896
1018
|
|
|
897
1019
|
self.logger.debug(
|
|
898
1020
|
f"Deployed {skill_name} from {source_dir} to {target_dir}"
|
|
@@ -926,12 +1048,12 @@ class SkillsDeployerService(LoggerMixin):
|
|
|
926
1048
|
"""
|
|
927
1049
|
try:
|
|
928
1050
|
if platform.system() == "Windows":
|
|
929
|
-
result = subprocess.run(
|
|
1051
|
+
result = subprocess.run( # nosec B603 B607 - Safe: hardcoded tasklist command
|
|
930
1052
|
["tasklist"], check=False, capture_output=True, text=True, timeout=5
|
|
931
1053
|
)
|
|
932
1054
|
return "claude" in result.stdout.lower()
|
|
933
1055
|
# macOS and Linux
|
|
934
|
-
result = subprocess.run(
|
|
1056
|
+
result = subprocess.run( # nosec B603 B607 - Safe: hardcoded ps command
|
|
935
1057
|
["ps", "aux"], check=False, capture_output=True, text=True, timeout=5
|
|
936
1058
|
)
|
|
937
1059
|
# Look for "Claude Code" or "claude-code" process
|
|
@@ -118,7 +118,8 @@ class HookEventHandler(BaseEventHandler):
|
|
|
118
118
|
self.server.active_sessions[session_id] = {
|
|
119
119
|
"session_id": session_id,
|
|
120
120
|
"start_time": datetime.now(timezone.utc).isoformat(),
|
|
121
|
-
"
|
|
121
|
+
"current_agent": agent_type, # Current active agent
|
|
122
|
+
"agents": [agent_type], # All agents used in this session
|
|
122
123
|
"status": ServiceState.RUNNING,
|
|
123
124
|
"prompt": data.get("prompt", "")[:100], # First 100 chars
|
|
124
125
|
"last_activity": datetime.now(timezone.utc).isoformat(),
|
|
@@ -169,7 +170,8 @@ class HookEventHandler(BaseEventHandler):
|
|
|
169
170
|
self.server.active_sessions[session_id] = {
|
|
170
171
|
"session_id": session_id,
|
|
171
172
|
"start_time": datetime.now(timezone.utc).isoformat(),
|
|
172
|
-
"
|
|
173
|
+
"current_agent": "pm", # Current active agent
|
|
174
|
+
"agents": ["pm"], # All agents used in this session
|
|
173
175
|
"status": ServiceState.RUNNING,
|
|
174
176
|
"prompt": data.get("prompt_text", "")[:100],
|
|
175
177
|
"working_directory": data.get("working_directory", ""),
|
|
@@ -200,11 +202,16 @@ class HookEventHandler(BaseEventHandler):
|
|
|
200
202
|
# Update session with new agent
|
|
201
203
|
if hasattr(self.server, "active_sessions"):
|
|
202
204
|
if session_id in self.server.active_sessions:
|
|
203
|
-
self.server.active_sessions[session_id]
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
205
|
+
session = self.server.active_sessions[session_id]
|
|
206
|
+
session["current_agent"] = agent_type
|
|
207
|
+
session["status"] = "delegated"
|
|
208
|
+
session["last_activity"] = datetime.now(timezone.utc).isoformat()
|
|
209
|
+
|
|
210
|
+
# Add to agents list if not already present
|
|
211
|
+
if "agents" not in session:
|
|
212
|
+
session["agents"] = []
|
|
213
|
+
if agent_type not in session["agents"]:
|
|
214
|
+
session["agents"].append(agent_type)
|
|
208
215
|
|
|
209
216
|
self.logger.debug(
|
|
210
217
|
f"Updated session delegation: session={session_id[:8]}..., agent={agent_type}"
|
|
@@ -383,7 +383,8 @@ class SocketIOServer(SocketIOServiceInterface):
|
|
|
383
383
|
self.active_sessions[session_id] = {
|
|
384
384
|
"session_id": session_id,
|
|
385
385
|
"start_time": datetime.now(timezone.utc).isoformat(),
|
|
386
|
-
"
|
|
386
|
+
"current_agent": "pm", # Current active agent
|
|
387
|
+
"agents": ["pm"], # All agents used in this session
|
|
387
388
|
"status": ServiceState.RUNNING,
|
|
388
389
|
"launch_method": launch_method,
|
|
389
390
|
"working_dir": working_dir,
|
|
@@ -419,8 +420,15 @@ class SocketIOServer(SocketIOServiceInterface):
|
|
|
419
420
|
"""Notify agent delegation."""
|
|
420
421
|
# Update active session with current agent
|
|
421
422
|
if self.session_id and self.session_id in self.active_sessions:
|
|
422
|
-
self.active_sessions[self.session_id]
|
|
423
|
-
|
|
423
|
+
session = self.active_sessions[self.session_id]
|
|
424
|
+
session["current_agent"] = agent
|
|
425
|
+
session["status"] = status
|
|
426
|
+
|
|
427
|
+
# Add to agents list if not already present
|
|
428
|
+
if "agents" not in session:
|
|
429
|
+
session["agents"] = []
|
|
430
|
+
if agent not in session["agents"]:
|
|
431
|
+
session["agents"].append(agent)
|
|
424
432
|
|
|
425
433
|
if self.broadcaster:
|
|
426
434
|
self.broadcaster.agent_delegated(agent, task, status)
|
|
@@ -480,7 +488,7 @@ class SocketIOServer(SocketIOServiceInterface):
|
|
|
480
488
|
start_time = datetime.fromisoformat(session_data["start_time"])
|
|
481
489
|
if start_time.timestamp() < cutoff_time:
|
|
482
490
|
sessions_to_remove.append(session_id)
|
|
483
|
-
except Exception:
|
|
491
|
+
except Exception: # nosec B110 - Silently skip malformed timestamps
|
|
484
492
|
pass
|
|
485
493
|
|
|
486
494
|
for session_id in sessions_to_remove:
|
claude_mpm/skills/__init__.py
CHANGED
|
@@ -24,7 +24,7 @@ Legacy System (maintained for compatibility):
|
|
|
24
24
|
from .agent_skills_injector import AgentSkillsInjector
|
|
25
25
|
|
|
26
26
|
# Legacy System (maintained for compatibility)
|
|
27
|
-
from .registry import Skill, SkillsRegistry, get_registry
|
|
27
|
+
from .registry import Skill, SkillsRegistry, get_registry, validate_agentskills_spec
|
|
28
28
|
from .skill_manager import SkillManager
|
|
29
29
|
from .skills_registry import SkillsRegistry as SkillsRegistryHelper
|
|
30
30
|
from .skills_service import SkillsService
|
|
@@ -39,4 +39,5 @@ __all__ = [
|
|
|
39
39
|
# New Skills Integration System
|
|
40
40
|
"SkillsService",
|
|
41
41
|
"get_registry",
|
|
42
|
+
"validate_agentskills_spec",
|
|
42
43
|
]
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Brainstorming Ideas Into Designs
|
|
3
|
+
description: Interactive idea refinement using Socratic method to develop fully-formed designs
|
|
4
|
+
when_to_use: when partner describes any feature or project idea, before writing code or implementation plans
|
|
5
|
+
version: 2.2.0
|
|
6
|
+
progressive_disclosure:
|
|
7
|
+
level: 1
|
|
8
|
+
references: []
|
|
9
|
+
note: Already optimal at 75 lines - intentionally compact, no references needed
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Brainstorming Ideas Into Designs
|
|
13
|
+
|
|
14
|
+
## Overview
|
|
15
|
+
|
|
16
|
+
Transform rough ideas into fully-formed designs through structured questioning and alternative exploration.
|
|
17
|
+
|
|
18
|
+
**Core principle:** Ask questions to understand, explore alternatives, present design incrementally for validation.
|
|
19
|
+
|
|
20
|
+
**Announce at start:** "I'm using the Brainstorming skill to refine your idea into a design."
|
|
21
|
+
|
|
22
|
+
## The Process
|
|
23
|
+
|
|
24
|
+
### Phase 1: Understanding
|
|
25
|
+
- Check current project state in working directory
|
|
26
|
+
- Ask ONE question at a time to refine the idea
|
|
27
|
+
- Prefer multiple choice when possible
|
|
28
|
+
- Gather: Purpose, constraints, success criteria
|
|
29
|
+
|
|
30
|
+
### Phase 2: Exploration
|
|
31
|
+
- Propose 2-3 different approaches
|
|
32
|
+
- For each: Core architecture, trade-offs, complexity assessment
|
|
33
|
+
- Ask your human partner which approach resonates
|
|
34
|
+
|
|
35
|
+
### Phase 3: Design Presentation
|
|
36
|
+
- Present in 200-300 word sections
|
|
37
|
+
- Cover: Architecture, components, data flow, error handling, testing
|
|
38
|
+
- Ask after each section: "Does this look right so far?"
|
|
39
|
+
|
|
40
|
+
### Phase 4: Worktree Setup (for implementation)
|
|
41
|
+
When design is approved and implementation will follow:
|
|
42
|
+
- Announce: "I'm using the Using Git Worktrees skill to set up an isolated workspace."
|
|
43
|
+
- Switch to skills/collaboration/using-git-worktrees
|
|
44
|
+
- Follow that skill's process for directory selection, safety verification, and setup
|
|
45
|
+
- Return here when worktree ready
|
|
46
|
+
|
|
47
|
+
### Phase 5: Planning Handoff
|
|
48
|
+
Ask: "Ready to create the implementation plan?"
|
|
49
|
+
|
|
50
|
+
When your human partner confirms (any affirmative response):
|
|
51
|
+
- Announce: "I'm using the Writing Plans skill to create the implementation plan."
|
|
52
|
+
- Switch to skills/collaboration/writing-plans skill
|
|
53
|
+
- Create detailed plan in the worktree
|
|
54
|
+
|
|
55
|
+
## When to Revisit Earlier Phases
|
|
56
|
+
|
|
57
|
+
**You can and should go backward when:**
|
|
58
|
+
- Partner reveals new constraint during Phase 2 or 3 → Return to Phase 1 to understand it
|
|
59
|
+
- Validation shows fundamental gap in requirements → Return to Phase 1
|
|
60
|
+
- Partner questions approach during Phase 3 → Return to Phase 2 to explore alternatives
|
|
61
|
+
- Something doesn't make sense → Go back and clarify
|
|
62
|
+
|
|
63
|
+
**Don't force forward linearly** when going backward would give better results.
|
|
64
|
+
|
|
65
|
+
## Related Skills
|
|
66
|
+
|
|
67
|
+
**During exploration:**
|
|
68
|
+
- When approaches have genuine trade-offs: skills/architecture/preserving-productive-tensions
|
|
69
|
+
|
|
70
|
+
**Before proposing changes to existing code:**
|
|
71
|
+
- Understand why it exists: skills/research/tracing-knowledge-lineages
|
|
72
|
+
|
|
73
|
+
## Remember
|
|
74
|
+
- One question per message during Phase 1
|
|
75
|
+
- Apply YAGNI ruthlessly
|
|
76
|
+
- Explore 2-3 alternatives before settling
|
|
77
|
+
- Present incrementally, validate as you go
|
|
78
|
+
- Go backward when needed - flexibility > rigid progression
|
|
79
|
+
- Announce skill usage at start
|