claude-mpm 5.4.21__py3-none-any.whl → 5.4.59__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/BASE_AGENT.md +164 -0
- claude_mpm/agents/BASE_ENGINEER.md +658 -0
- claude_mpm/agents/MEMORY.md +1 -1
- claude_mpm/agents/PM_INSTRUCTIONS.md +771 -1019
- claude_mpm/agents/WORKFLOW.md +5 -254
- claude_mpm/agents/agent_loader.py +1 -1
- claude_mpm/agents/base_agent.json +31 -0
- claude_mpm/agents/frontmatter_validator.py +2 -2
- claude_mpm/cli/commands/agent_state_manager.py +10 -10
- claude_mpm/cli/commands/agents.py +9 -9
- claude_mpm/cli/commands/auto_configure.py +4 -4
- claude_mpm/cli/commands/configure.py +1 -1
- claude_mpm/cli/commands/configure_agent_display.py +12 -0
- claude_mpm/cli/commands/mpm_init/core.py +72 -0
- claude_mpm/cli/commands/postmortem.py +1 -1
- claude_mpm/cli/commands/profile.py +276 -0
- claude_mpm/cli/commands/skills.py +14 -18
- claude_mpm/cli/executor.py +10 -0
- claude_mpm/cli/interactive/agent_wizard.py +2 -2
- claude_mpm/cli/parsers/base_parser.py +7 -0
- claude_mpm/cli/parsers/profile_parser.py +147 -0
- claude_mpm/cli/parsers/skills_parser.py +0 -6
- claude_mpm/cli/startup.py +506 -180
- claude_mpm/commands/mpm-config.md +13 -250
- claude_mpm/commands/mpm-doctor.md +9 -22
- claude_mpm/commands/mpm-help.md +5 -206
- claude_mpm/commands/mpm-init.md +81 -507
- claude_mpm/commands/mpm-monitor.md +15 -402
- claude_mpm/commands/mpm-organize.md +61 -441
- claude_mpm/commands/mpm-postmortem.md +6 -108
- claude_mpm/commands/mpm-session-resume.md +12 -363
- claude_mpm/commands/mpm-status.md +5 -69
- claude_mpm/commands/mpm-ticket-view.md +52 -495
- claude_mpm/commands/mpm-version.md +5 -107
- claude_mpm/core/config.py +2 -4
- claude_mpm/core/framework/loaders/agent_loader.py +1 -1
- claude_mpm/core/framework/loaders/instruction_loader.py +52 -11
- claude_mpm/core/optimized_startup.py +61 -0
- claude_mpm/core/shared/config_loader.py +3 -1
- claude_mpm/core/unified_agent_registry.py +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/env.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.DWzvg0-y.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.ThTw9_ym.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/4TdZjIqw.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/5shd3_w0.js +24 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B0uc0UOD.js +36 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7RN905-.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7xVLGWV.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BIF9m_hv.js +61 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BKjSRqUr.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BPYeabCQ.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/BSNlmTZj.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Be7GpZd6.js +7 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Bh0LDWpI.js +145 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BofRWZRR.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BovzEFCE.js +30 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C30mlcqg.js +165 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4B-KCzX.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4JcI4KD.js +122 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CBBdVcY8.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CDuw-vjf.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C_Usid8X.js +15 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cfqx1Qun.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CiIAseT4.js +128 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CmKTTxBW.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CnA0NrzZ.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cs_tUR18.js +24 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cu_Erd72.js +261 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CyWMqx4W.js +43 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzZX-COe.js +220 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzeYkLYB.js +65 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D3k0OPJN.js +4 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9lljYKQ.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DGkLK5U1.js +267 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DI7hHRFL.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DLVjFsZ3.js +139 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DUrLdbGD.js +89 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DVp1hx9R.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DY1XQ8fi.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DZX00Y4g.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Da0KfYnO.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DaimHw_p.js +68 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dfy6j1xT.js +323 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dhb8PKl3.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dle-35c7.js +64 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DmxopI1J.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DwBR2MJi.js +60 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/GYwsonyD.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Gi6I4Gst.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/NqQ1dWOy.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/RJiighC3.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Vzk33B_K.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/ZGh7QtNv.js +7 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bT1r9zLR.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bTOqqlTd.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/eNVUfhuA.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/iEWssX7S.js +162 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/sQeU3Y1z.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/uuIeMWc-.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.D6-I5TpK.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.NWzMBYRp.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/0.m1gL8KXf.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.CgNOuw-d.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.C0GcWctS.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -0
- claude_mpm/dashboard/static/svelte-build/favicon.svg +7 -0
- claude_mpm/dashboard/static/svelte-build/index.html +36 -0
- 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/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.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__/installer.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/__pycache__/tool_analysis.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/hook_handler.py +149 -1
- 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__/duplicate_detector.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 +26 -6
- claude_mpm/hooks/kuzu_memory_hook.py +5 -5
- claude_mpm/init.py +276 -0
- claude_mpm/models/git_repository.py +3 -3
- claude_mpm/scripts/start_activity_logging.py +0 -0
- claude_mpm/services/agents/agent_builder.py +3 -3
- claude_mpm/services/agents/cache_git_manager.py +6 -6
- claude_mpm/services/agents/deployment/agent_deployment.py +29 -7
- claude_mpm/services/agents/deployment/agent_discovery_service.py +4 -2
- claude_mpm/services/agents/deployment/agent_format_converter.py +25 -13
- claude_mpm/services/agents/deployment/agent_template_builder.py +31 -19
- claude_mpm/services/agents/deployment/agents_directory_resolver.py +2 -2
- claude_mpm/services/agents/deployment/async_agent_deployment.py +31 -27
- claude_mpm/services/agents/deployment/local_template_deployment.py +3 -1
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +169 -26
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +98 -75
- claude_mpm/services/agents/git_source_manager.py +23 -4
- claude_mpm/services/agents/recommender.py +5 -3
- claude_mpm/services/agents/single_tier_deployment_service.py +2 -2
- claude_mpm/services/agents/sources/git_source_sync_service.py +121 -10
- claude_mpm/services/agents/startup_sync.py +22 -2
- claude_mpm/services/diagnostics/checks/agent_check.py +2 -2
- claude_mpm/services/diagnostics/checks/agent_sources_check.py +1 -1
- claude_mpm/services/git/git_operations_service.py +8 -8
- claude_mpm/services/monitor/management/lifecycle.py +7 -1
- claude_mpm/services/monitor/server.py +473 -3
- claude_mpm/services/pm_skills_deployer.py +711 -0
- claude_mpm/services/profile_manager.py +337 -0
- claude_mpm/services/skills/git_skill_source_manager.py +148 -11
- claude_mpm/services/skills/selective_skill_deployer.py +97 -48
- claude_mpm/services/skills_deployer.py +161 -65
- claude_mpm/services/socketio/dashboard_server.py +1 -0
- claude_mpm/services/socketio/event_normalizer.py +37 -6
- claude_mpm/services/socketio/server/core.py +262 -123
- claude_mpm/skills/bundled/security-scanning.md +112 -0
- claude_mpm/skills/skill_manager.py +98 -3
- claude_mpm/templates/.pre-commit-config.yaml +112 -0
- claude_mpm/utils/agent_dependency_loader.py +14 -2
- claude_mpm/utils/agent_filters.py +1 -1
- claude_mpm/utils/migration.py +4 -4
- claude_mpm/utils/robust_installer.py +47 -3
- {claude_mpm-5.4.21.dist-info → claude_mpm-5.4.59.dist-info}/METADATA +7 -4
- {claude_mpm-5.4.21.dist-info → claude_mpm-5.4.59.dist-info}/RECORD +175 -81
- {claude_mpm-5.4.21.dist-info → claude_mpm-5.4.59.dist-info}/WHEEL +0 -0
- {claude_mpm-5.4.21.dist-info → claude_mpm-5.4.59.dist-info}/entry_points.txt +0 -0
- {claude_mpm-5.4.21.dist-info → claude_mpm-5.4.59.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-5.4.21.dist-info → claude_mpm-5.4.59.dist-info}/licenses/LICENSE-FAQ.md +0 -0
- {claude_mpm-5.4.21.dist-info → claude_mpm-5.4.59.dist-info}/top_level.txt +0 -0
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
4
|
from pathlib import Path
|
|
5
|
-
from typing import Dict, List, Optional
|
|
5
|
+
from typing import Any, Dict, List, Optional
|
|
6
|
+
|
|
7
|
+
import yaml
|
|
6
8
|
|
|
7
9
|
from claude_mpm.core.logging_utils import get_logger
|
|
8
10
|
|
|
@@ -56,12 +58,81 @@ class SkillManager:
|
|
|
56
58
|
if mapping_count > 0:
|
|
57
59
|
logger.info(f"Loaded skill mappings for {mapping_count} agents")
|
|
58
60
|
|
|
61
|
+
def _get_pm_skills(
|
|
62
|
+
self, project_dir: Optional[Path] = None
|
|
63
|
+
) -> List[Dict[str, Any]]:
|
|
64
|
+
"""Load PM skills from project's .claude-mpm/skills/pm/ directory.
|
|
65
|
+
|
|
66
|
+
PM skills are special required skills deployed per-project,
|
|
67
|
+
NOT fetched from the skills repository.
|
|
68
|
+
|
|
69
|
+
Args:
|
|
70
|
+
project_dir: Project directory. Defaults to current working directory.
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
List of PM skill dictionaries with metadata
|
|
74
|
+
"""
|
|
75
|
+
if project_dir is None:
|
|
76
|
+
project_dir = Path.cwd()
|
|
77
|
+
|
|
78
|
+
pm_skills_dir = project_dir / ".claude-mpm" / "skills" / "pm"
|
|
79
|
+
|
|
80
|
+
if not pm_skills_dir.exists():
|
|
81
|
+
logger.debug("PM skills directory not found")
|
|
82
|
+
return []
|
|
83
|
+
|
|
84
|
+
skills = []
|
|
85
|
+
for skill_dir in pm_skills_dir.iterdir():
|
|
86
|
+
if skill_dir.is_dir():
|
|
87
|
+
skill_file = skill_dir / "SKILL.md"
|
|
88
|
+
if skill_file.exists():
|
|
89
|
+
skill = self._load_pm_skill(skill_file)
|
|
90
|
+
if skill:
|
|
91
|
+
skills.append(skill)
|
|
92
|
+
|
|
93
|
+
if skills:
|
|
94
|
+
logger.debug(f"Loaded {len(skills)} PM skills from {pm_skills_dir}")
|
|
95
|
+
|
|
96
|
+
return skills
|
|
97
|
+
|
|
98
|
+
def _load_pm_skill(self, skill_file: Path) -> Optional[Dict[str, Any]]:
|
|
99
|
+
"""Load a single PM skill from SKILL.md file.
|
|
100
|
+
|
|
101
|
+
Args:
|
|
102
|
+
skill_file: Path to SKILL.md file
|
|
103
|
+
|
|
104
|
+
Returns:
|
|
105
|
+
Dictionary with skill metadata and content, or None if failed
|
|
106
|
+
"""
|
|
107
|
+
try:
|
|
108
|
+
content = skill_file.read_text(encoding="utf-8")
|
|
109
|
+
|
|
110
|
+
# Parse YAML frontmatter
|
|
111
|
+
if content.startswith("---"):
|
|
112
|
+
parts = content.split("---", 2)
|
|
113
|
+
if len(parts) >= 3:
|
|
114
|
+
metadata = yaml.safe_load(parts[1])
|
|
115
|
+
body = parts[2].strip()
|
|
116
|
+
|
|
117
|
+
return {
|
|
118
|
+
"name": metadata.get("name", skill_file.parent.name),
|
|
119
|
+
"version": metadata.get("version", "1.0.0"),
|
|
120
|
+
"description": metadata.get("description", ""),
|
|
121
|
+
"when_to_use": metadata.get("when_to_use", ""),
|
|
122
|
+
"content": body,
|
|
123
|
+
"is_pm_skill": True,
|
|
124
|
+
}
|
|
125
|
+
except Exception as e:
|
|
126
|
+
logger.warning(f"Failed to load PM skill {skill_file}: {e}")
|
|
127
|
+
|
|
128
|
+
return None
|
|
129
|
+
|
|
59
130
|
def get_agent_skills(self, agent_type: str) -> List[Skill]:
|
|
60
131
|
"""
|
|
61
|
-
Get all skills for an agent (bundled + discovered).
|
|
132
|
+
Get all skills for an agent (bundled + discovered + PM skills if PM agent).
|
|
62
133
|
|
|
63
134
|
Args:
|
|
64
|
-
agent_type: Agent type/ID (e.g., 'engineer', 'python_engineer')
|
|
135
|
+
agent_type: Agent type/ID (e.g., 'engineer', 'python_engineer', 'pm')
|
|
65
136
|
|
|
66
137
|
Returns:
|
|
67
138
|
List of Skill objects for this agent
|
|
@@ -86,6 +157,30 @@ class SkillManager:
|
|
|
86
157
|
if skill not in skills:
|
|
87
158
|
skills.append(skill)
|
|
88
159
|
|
|
160
|
+
# Add PM skills for PM agent only
|
|
161
|
+
if agent_type.lower() in ("pm", "project-manager", "project_manager"):
|
|
162
|
+
pm_skill_dicts = self._get_pm_skills()
|
|
163
|
+
for pm_skill_dict in pm_skill_dicts:
|
|
164
|
+
# Convert PM skill dict to Skill object
|
|
165
|
+
pm_skill = Skill(
|
|
166
|
+
name=pm_skill_dict["name"],
|
|
167
|
+
path=Path.cwd()
|
|
168
|
+
/ ".claude-mpm"
|
|
169
|
+
/ "skills"
|
|
170
|
+
/ "pm"
|
|
171
|
+
/ pm_skill_dict["name"],
|
|
172
|
+
content=pm_skill_dict["content"],
|
|
173
|
+
source="pm", # Special source type for PM skills
|
|
174
|
+
version=pm_skill_dict["version"],
|
|
175
|
+
skill_id=pm_skill_dict["name"],
|
|
176
|
+
description=pm_skill_dict["description"],
|
|
177
|
+
agent_types=["pm", "project-manager", "project_manager"],
|
|
178
|
+
)
|
|
179
|
+
skills.append(pm_skill)
|
|
180
|
+
|
|
181
|
+
if pm_skill_dicts:
|
|
182
|
+
logger.debug(f"Added {len(pm_skill_dicts)} PM skills for PM agent")
|
|
183
|
+
|
|
89
184
|
return skills
|
|
90
185
|
|
|
91
186
|
def enhance_agent_prompt(
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# Pre-commit hooks configuration for claude-mpm
|
|
2
|
+
# See https://pre-commit.com for more information
|
|
3
|
+
# See https://pre-commit.com/hooks.html for more hooks
|
|
4
|
+
|
|
5
|
+
repos:
|
|
6
|
+
# Standard pre-commit hooks
|
|
7
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
8
|
+
rev: v4.5.0
|
|
9
|
+
hooks:
|
|
10
|
+
- id: trailing-whitespace
|
|
11
|
+
exclude: ^(.*\.md|.*\.txt)$
|
|
12
|
+
- id: end-of-file-fixer
|
|
13
|
+
exclude: ^(.*\.md|.*\.txt)$
|
|
14
|
+
- id: check-yaml
|
|
15
|
+
args: ['--unsafe'] # Allow custom YAML tags
|
|
16
|
+
- id: check-json
|
|
17
|
+
- id: check-toml
|
|
18
|
+
- id: check-merge-conflict
|
|
19
|
+
- id: check-added-large-files
|
|
20
|
+
args: ['--maxkb=1000']
|
|
21
|
+
- id: check-case-conflict
|
|
22
|
+
- id: check-executables-have-shebangs
|
|
23
|
+
- id: check-shebang-scripts-are-executable
|
|
24
|
+
- id: mixed-line-ending
|
|
25
|
+
args: ['--fix=lf']
|
|
26
|
+
|
|
27
|
+
# Ruff - replaces black, isort, flake8, pyupgrade (10-200x faster)
|
|
28
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
29
|
+
rev: v0.8.4 # Use latest version
|
|
30
|
+
hooks:
|
|
31
|
+
# Run the linter
|
|
32
|
+
- id: ruff
|
|
33
|
+
args: [--fix]
|
|
34
|
+
# Run the formatter
|
|
35
|
+
- id: ruff-format
|
|
36
|
+
|
|
37
|
+
# Type checking with mypy
|
|
38
|
+
- repo: https://github.com/pre-commit/mirrors-mypy
|
|
39
|
+
rev: v1.8.0
|
|
40
|
+
hooks:
|
|
41
|
+
- id: mypy
|
|
42
|
+
additional_dependencies: [types-PyYAML, types-requests]
|
|
43
|
+
args: ['--config-file=mypy.ini']
|
|
44
|
+
exclude: ^(venv/|\.venv/|env/|\.env/|build/|dist/|\.git/|tests/.*\.py|scripts/.*\.py)
|
|
45
|
+
|
|
46
|
+
# Security scanning with bandit
|
|
47
|
+
- repo: https://github.com/pycqa/bandit
|
|
48
|
+
rev: 1.7.5
|
|
49
|
+
hooks:
|
|
50
|
+
- id: bandit
|
|
51
|
+
args: ['-r', '-f', 'json']
|
|
52
|
+
exclude: ^(venv/|\.venv/|env/|\.env/|build/|dist/|\.git/|tests/.*\.py)
|
|
53
|
+
|
|
54
|
+
# Secret detection with detect-secrets
|
|
55
|
+
- repo: https://github.com/Yelp/detect-secrets
|
|
56
|
+
rev: v1.5.0
|
|
57
|
+
hooks:
|
|
58
|
+
- id: detect-secrets
|
|
59
|
+
args: ['--baseline', '.secrets.baseline']
|
|
60
|
+
exclude: |
|
|
61
|
+
(?x)^(
|
|
62
|
+
venv/.*|
|
|
63
|
+
\.venv/.*|
|
|
64
|
+
node_modules/.*|
|
|
65
|
+
\.git/.*|
|
|
66
|
+
__pycache__/.*|
|
|
67
|
+
.*\.lock|
|
|
68
|
+
.*package-lock\.json|
|
|
69
|
+
.*\.pyc
|
|
70
|
+
)$
|
|
71
|
+
|
|
72
|
+
# Documentation linting
|
|
73
|
+
- repo: https://github.com/pycqa/doc8
|
|
74
|
+
rev: v1.1.1
|
|
75
|
+
hooks:
|
|
76
|
+
- id: doc8
|
|
77
|
+
args: ['--max-line-length=88']
|
|
78
|
+
files: \.rst$
|
|
79
|
+
|
|
80
|
+
# Commitizen for conventional commits
|
|
81
|
+
- repo: https://github.com/commitizen-tools/commitizen
|
|
82
|
+
rev: v3.13.0
|
|
83
|
+
hooks:
|
|
84
|
+
- id: commitizen
|
|
85
|
+
stages: [commit-msg]
|
|
86
|
+
|
|
87
|
+
# Configuration for specific file types
|
|
88
|
+
exclude: |
|
|
89
|
+
(?x)^(
|
|
90
|
+
venv/.*|
|
|
91
|
+
\.venv/.*|
|
|
92
|
+
env/.*|
|
|
93
|
+
\.env/.*|
|
|
94
|
+
build/.*|
|
|
95
|
+
dist/.*|
|
|
96
|
+
\.git/.*|
|
|
97
|
+
__pycache__/.*|
|
|
98
|
+
.*\.pyc|
|
|
99
|
+
.*\.pyo|
|
|
100
|
+
.*\.egg-info/.*|
|
|
101
|
+
\.coverage|
|
|
102
|
+
\.pytest_cache/.*|
|
|
103
|
+
\.mypy_cache/.*|
|
|
104
|
+
node_modules/.*|
|
|
105
|
+
\.DS_Store|
|
|
106
|
+
\.vscode/.*|
|
|
107
|
+
\.idea/.*
|
|
108
|
+
)$
|
|
109
|
+
|
|
110
|
+
# Global settings
|
|
111
|
+
default_stages: [pre-commit]
|
|
112
|
+
fail_fast: false
|
|
@@ -658,12 +658,24 @@ class AgentDependencyLoader:
|
|
|
658
658
|
"Robust installer not available, falling back to simple installation"
|
|
659
659
|
)
|
|
660
660
|
try:
|
|
661
|
-
cmd = [sys.executable, "-m", "pip", "install"]
|
|
662
|
-
|
|
663
661
|
# Check environment and add appropriate flags
|
|
664
662
|
import os
|
|
665
663
|
import sysconfig
|
|
666
664
|
|
|
665
|
+
# Check if in UV tool environment (no pip available)
|
|
666
|
+
uv_tool_dir = os.environ.get("UV_TOOL_DIR", "")
|
|
667
|
+
is_uv_tool = (
|
|
668
|
+
(uv_tool_dir and "claude-mpm" in uv_tool_dir)
|
|
669
|
+
or ".local/share/uv/tools/" in sys.executable
|
|
670
|
+
or "/uv/tools/" in sys.executable
|
|
671
|
+
)
|
|
672
|
+
|
|
673
|
+
if is_uv_tool:
|
|
674
|
+
cmd = ["uv", "pip", "install"]
|
|
675
|
+
logger.debug("Using 'uv pip install' for UV tool environment")
|
|
676
|
+
else:
|
|
677
|
+
cmd = [sys.executable, "-m", "pip", "install"]
|
|
678
|
+
|
|
667
679
|
# Check if in virtualenv
|
|
668
680
|
in_virtualenv = (
|
|
669
681
|
(hasattr(sys, "base_prefix") and sys.base_prefix != sys.prefix)
|
|
@@ -5,7 +5,7 @@ WHY: This module provides centralized filtering logic to remove non-deployable
|
|
|
5
5
|
agents (BASE_AGENT) and already-deployed agents from user-facing displays.
|
|
6
6
|
|
|
7
7
|
ARCHITECTURE:
|
|
8
|
-
- SOURCE: ~/.claude-mpm/cache/
|
|
8
|
+
- SOURCE: ~/.claude-mpm/cache/agents/ (git repository cache)
|
|
9
9
|
- DEPLOYMENT: .claude/agents/ (project-level deployment location)
|
|
10
10
|
|
|
11
11
|
DESIGN DECISIONS:
|
claude_mpm/utils/migration.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
WHY: Phase 3 of 1M-486 requires migrating from old single-tier deployment
|
|
4
4
|
(~/.claude/agents/, ~/.claude/skills/) to new two-phase architecture:
|
|
5
|
-
- Cache: ~/.claude-mpm/cache/
|
|
5
|
+
- Cache: ~/.claude-mpm/cache/agents/, ~/.claude-mpm/cache/skills/
|
|
6
6
|
- Deployment: .claude-mpm/agents/, .claude-mpm/skills/
|
|
7
7
|
|
|
8
8
|
DESIGN DECISIONS:
|
|
@@ -41,7 +41,7 @@ class MigrationUtility:
|
|
|
41
41
|
self.old_agent_dir = Path.home() / ".claude" / "agents"
|
|
42
42
|
self.old_skill_dir = Path.home() / ".claude" / "skills"
|
|
43
43
|
|
|
44
|
-
self.new_agent_cache = Path.home() / ".claude-mpm" / "cache" / "
|
|
44
|
+
self.new_agent_cache = Path.home() / ".claude-mpm" / "cache" / "agents"
|
|
45
45
|
self.new_skill_cache = Path.home() / ".claude-mpm" / "cache" / "skills"
|
|
46
46
|
|
|
47
47
|
def detect_old_locations(self) -> Dict[str, bool]:
|
|
@@ -80,7 +80,7 @@ class MigrationUtility:
|
|
|
80
80
|
def migrate_agents(
|
|
81
81
|
self, dry_run: bool = False, auto_confirm: bool = False
|
|
82
82
|
) -> Dict[str, any]:
|
|
83
|
-
"""Migrate agents from ~/.claude/agents/ to ~/.claude-mpm/cache/
|
|
83
|
+
"""Migrate agents from ~/.claude/agents/ to ~/.claude-mpm/cache/agents/.
|
|
84
84
|
|
|
85
85
|
Args:
|
|
86
86
|
dry_run: Preview migration without making changes
|
|
@@ -329,7 +329,7 @@ class MigrationUtility:
|
|
|
329
329
|
|
|
330
330
|
warning += "\nThe deployment architecture has changed:\n"
|
|
331
331
|
warning += " OLD: ~/.claude/agents/ (single-tier, global)\n"
|
|
332
|
-
warning += " NEW: ~/.claude-mpm/cache/
|
|
332
|
+
warning += " NEW: ~/.claude-mpm/cache/agents/ → .claude-mpm/agents/ (two-phase, per-project)\n\n"
|
|
333
333
|
|
|
334
334
|
warning += "To migrate:\n"
|
|
335
335
|
warning += " claude-mpm migrate\n\n"
|
|
@@ -82,6 +82,7 @@ class RobustPackageInstaller:
|
|
|
82
82
|
self.attempts: List[InstallAttempt] = []
|
|
83
83
|
self.success_cache: Dict[str, bool] = {}
|
|
84
84
|
self.in_virtualenv = self._check_virtualenv()
|
|
85
|
+
self.is_uv_tool = self._check_uv_tool_installation()
|
|
85
86
|
self.is_pep668_managed = self._check_pep668_managed()
|
|
86
87
|
self.pep668_warning_shown = False
|
|
87
88
|
|
|
@@ -261,6 +262,36 @@ class RobustPackageInstaller:
|
|
|
261
262
|
|
|
262
263
|
return False
|
|
263
264
|
|
|
265
|
+
def _check_uv_tool_installation(self) -> bool:
|
|
266
|
+
"""
|
|
267
|
+
Check if running in UV tool environment (no pip available).
|
|
268
|
+
|
|
269
|
+
WHY: UV tool environments don't have pip installed. The executable
|
|
270
|
+
path typically contains ".local/share/uv/tools/" and the UV_TOOL_DIR
|
|
271
|
+
environment variable is set. In such environments, we need to use
|
|
272
|
+
'uv pip' instead of 'python -m pip'.
|
|
273
|
+
|
|
274
|
+
Returns:
|
|
275
|
+
True if UV tool environment, False otherwise
|
|
276
|
+
"""
|
|
277
|
+
import os
|
|
278
|
+
|
|
279
|
+
# Check UV_TOOL_DIR environment variable
|
|
280
|
+
uv_tool_dir = os.environ.get("UV_TOOL_DIR", "")
|
|
281
|
+
if uv_tool_dir and "claude-mpm" in uv_tool_dir:
|
|
282
|
+
logger.debug(f"UV tool environment detected via UV_TOOL_DIR: {uv_tool_dir}")
|
|
283
|
+
return True
|
|
284
|
+
|
|
285
|
+
# Check executable path for UV tool patterns
|
|
286
|
+
executable = sys.executable
|
|
287
|
+
if ".local/share/uv/tools/" in executable or "/uv/tools/" in executable:
|
|
288
|
+
logger.debug(
|
|
289
|
+
f"UV tool environment detected via executable path: {executable}"
|
|
290
|
+
)
|
|
291
|
+
return True
|
|
292
|
+
|
|
293
|
+
return False
|
|
294
|
+
|
|
264
295
|
def _show_pep668_warning(self) -> None:
|
|
265
296
|
"""
|
|
266
297
|
Show warning about PEP 668 managed environment.
|
|
@@ -301,7 +332,12 @@ class RobustPackageInstaller:
|
|
|
301
332
|
Returns:
|
|
302
333
|
Command as list of arguments
|
|
303
334
|
"""
|
|
304
|
-
|
|
335
|
+
# UV tool environments don't have pip; use uv pip instead
|
|
336
|
+
if self.is_uv_tool:
|
|
337
|
+
base_cmd = ["uv", "pip", "install"]
|
|
338
|
+
logger.debug("Using 'uv pip install' for UV tool environment")
|
|
339
|
+
else:
|
|
340
|
+
base_cmd = [sys.executable, "-m", "pip", "install"]
|
|
305
341
|
|
|
306
342
|
# Determine appropriate flags based on environment
|
|
307
343
|
if self.in_virtualenv:
|
|
@@ -651,7 +687,12 @@ class RobustPackageInstaller:
|
|
|
651
687
|
Tuple of (success, error_message)
|
|
652
688
|
"""
|
|
653
689
|
try:
|
|
654
|
-
|
|
690
|
+
# UV tool environments don't have pip; use uv pip instead
|
|
691
|
+
if self.is_uv_tool:
|
|
692
|
+
cmd = ["uv", "pip", "install"]
|
|
693
|
+
logger.debug("Using 'uv pip install' for batch installation")
|
|
694
|
+
else:
|
|
695
|
+
cmd = [sys.executable, "-m", "pip", "install"]
|
|
655
696
|
|
|
656
697
|
# Add appropriate flags based on environment
|
|
657
698
|
if self.in_virtualenv:
|
|
@@ -702,7 +743,10 @@ class RobustPackageInstaller:
|
|
|
702
743
|
|
|
703
744
|
# Add environment status
|
|
704
745
|
lines.append("")
|
|
705
|
-
if self.
|
|
746
|
+
if self.is_uv_tool:
|
|
747
|
+
lines.append("✓ Environment: UV Tool Environment")
|
|
748
|
+
lines.append(" Using 'uv pip' command (pip not available)")
|
|
749
|
+
elif self.in_virtualenv:
|
|
706
750
|
lines.append("✓ Environment: Virtual Environment (isolated)")
|
|
707
751
|
lines.append(" No special pip flags needed")
|
|
708
752
|
elif self.is_pep668_managed:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: claude-mpm
|
|
3
|
-
Version: 5.4.
|
|
3
|
+
Version: 5.4.59
|
|
4
4
|
Summary: Claude Multi-Agent Project Manager - Orchestrate Claude with agent delegation and ticket tracking
|
|
5
5
|
Author-email: Bob Matsuoka <bob@matsuoka.com>
|
|
6
6
|
Maintainer: Claude MPM Team
|
|
@@ -49,7 +49,6 @@ Requires-Dist: rich>=13.0.0
|
|
|
49
49
|
Requires-Dist: questionary>=2.0.0
|
|
50
50
|
Requires-Dist: pyee>=13.0.0
|
|
51
51
|
Requires-Dist: pathspec>=0.11.0
|
|
52
|
-
Requires-Dist: kuzu-memory>=1.1.5
|
|
53
52
|
Provides-Extra: mcp
|
|
54
53
|
Requires-Dist: mcp>=0.1.0; extra == "mcp"
|
|
55
54
|
Requires-Dist: mcp-vector-search>=0.1.0; extra == "mcp"
|
|
@@ -101,6 +100,8 @@ Requires-Dist: pymongo>=4.5.0; extra == "data-processing"
|
|
|
101
100
|
Requires-Dist: redis>=5.0.0; extra == "data-processing"
|
|
102
101
|
Requires-Dist: beautifulsoup4>=4.12.0; extra == "data-processing"
|
|
103
102
|
Requires-Dist: jsonschema>=4.19.0; extra == "data-processing"
|
|
103
|
+
Provides-Extra: memory
|
|
104
|
+
Requires-Dist: kuzu-memory>=1.1.5; extra == "memory"
|
|
104
105
|
Dynamic: license-file
|
|
105
106
|
|
|
106
107
|
# Claude MPM - Multi-Agent Project Manager
|
|
@@ -387,12 +388,12 @@ claude-mpm verify
|
|
|
387
388
|
|
|
388
389
|
## Cache Management
|
|
389
390
|
|
|
390
|
-
Claude MPM maintains a local cache of agent templates at `~/.claude-mpm/cache/
|
|
391
|
+
Claude MPM maintains a local cache of agent templates at `~/.claude-mpm/cache/agents/`.
|
|
391
392
|
|
|
392
393
|
### Cache Structure
|
|
393
394
|
|
|
394
395
|
```
|
|
395
|
-
~/.claude-mpm/cache/
|
|
396
|
+
~/.claude-mpm/cache/agents/
|
|
396
397
|
└── bobmatnyc/
|
|
397
398
|
└── claude-mpm-agents/
|
|
398
399
|
├── .git/ # Git repository
|
|
@@ -400,6 +401,8 @@ Claude MPM maintains a local cache of agent templates at `~/.claude-mpm/cache/re
|
|
|
400
401
|
└── docs/
|
|
401
402
|
```
|
|
402
403
|
|
|
404
|
+
> **Note**: Prior to v5.4.23, agents were cached to `~/.claude-mpm/cache/remote-agents/`. This has been standardized to `~/.claude-mpm/cache/agents/`. Existing caches are automatically migrated.
|
|
405
|
+
|
|
403
406
|
### Git Workflow (Optional)
|
|
404
407
|
|
|
405
408
|
If your cache is a git repository, you can manage agents with git operations:
|