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.

Files changed (176) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_AGENT.md +164 -0
  3. claude_mpm/agents/BASE_ENGINEER.md +658 -0
  4. claude_mpm/agents/MEMORY.md +1 -1
  5. claude_mpm/agents/PM_INSTRUCTIONS.md +771 -1019
  6. claude_mpm/agents/WORKFLOW.md +5 -254
  7. claude_mpm/agents/agent_loader.py +1 -1
  8. claude_mpm/agents/base_agent.json +31 -0
  9. claude_mpm/agents/frontmatter_validator.py +2 -2
  10. claude_mpm/cli/commands/agent_state_manager.py +10 -10
  11. claude_mpm/cli/commands/agents.py +9 -9
  12. claude_mpm/cli/commands/auto_configure.py +4 -4
  13. claude_mpm/cli/commands/configure.py +1 -1
  14. claude_mpm/cli/commands/configure_agent_display.py +12 -0
  15. claude_mpm/cli/commands/mpm_init/core.py +72 -0
  16. claude_mpm/cli/commands/postmortem.py +1 -1
  17. claude_mpm/cli/commands/profile.py +276 -0
  18. claude_mpm/cli/commands/skills.py +14 -18
  19. claude_mpm/cli/executor.py +10 -0
  20. claude_mpm/cli/interactive/agent_wizard.py +2 -2
  21. claude_mpm/cli/parsers/base_parser.py +7 -0
  22. claude_mpm/cli/parsers/profile_parser.py +147 -0
  23. claude_mpm/cli/parsers/skills_parser.py +0 -6
  24. claude_mpm/cli/startup.py +506 -180
  25. claude_mpm/commands/mpm-config.md +13 -250
  26. claude_mpm/commands/mpm-doctor.md +9 -22
  27. claude_mpm/commands/mpm-help.md +5 -206
  28. claude_mpm/commands/mpm-init.md +81 -507
  29. claude_mpm/commands/mpm-monitor.md +15 -402
  30. claude_mpm/commands/mpm-organize.md +61 -441
  31. claude_mpm/commands/mpm-postmortem.md +6 -108
  32. claude_mpm/commands/mpm-session-resume.md +12 -363
  33. claude_mpm/commands/mpm-status.md +5 -69
  34. claude_mpm/commands/mpm-ticket-view.md +52 -495
  35. claude_mpm/commands/mpm-version.md +5 -107
  36. claude_mpm/core/config.py +2 -4
  37. claude_mpm/core/framework/loaders/agent_loader.py +1 -1
  38. claude_mpm/core/framework/loaders/instruction_loader.py +52 -11
  39. claude_mpm/core/optimized_startup.py +61 -0
  40. claude_mpm/core/shared/config_loader.py +3 -1
  41. claude_mpm/core/unified_agent_registry.py +1 -1
  42. claude_mpm/dashboard/static/svelte-build/_app/env.js +1 -0
  43. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.DWzvg0-y.css +1 -0
  44. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.ThTw9_ym.css +1 -0
  45. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/4TdZjIqw.js +1 -0
  46. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/5shd3_w0.js +24 -0
  47. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B0uc0UOD.js +36 -0
  48. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7RN905-.js +1 -0
  49. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7xVLGWV.js +2 -0
  50. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BIF9m_hv.js +61 -0
  51. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BKjSRqUr.js +1 -0
  52. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BPYeabCQ.js +1 -0
  53. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BQaXIfA_.js +331 -0
  54. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BSNlmTZj.js +1 -0
  55. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Be7GpZd6.js +7 -0
  56. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Bh0LDWpI.js +145 -0
  57. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BofRWZRR.js +10 -0
  58. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BovzEFCE.js +30 -0
  59. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C30mlcqg.js +165 -0
  60. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4B-KCzX.js +1 -0
  61. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4JcI4KD.js +122 -0
  62. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CBBdVcY8.js +1 -0
  63. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CDuw-vjf.js +1 -0
  64. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C_Usid8X.js +15 -0
  65. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cfqx1Qun.js +10 -0
  66. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CiIAseT4.js +128 -0
  67. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CmKTTxBW.js +1 -0
  68. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CnA0NrzZ.js +1 -0
  69. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cs_tUR18.js +24 -0
  70. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cu_Erd72.js +261 -0
  71. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CyWMqx4W.js +43 -0
  72. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzZX-COe.js +220 -0
  73. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzeYkLYB.js +65 -0
  74. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D3k0OPJN.js +4 -0
  75. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9lljYKQ.js +1 -0
  76. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DGkLK5U1.js +267 -0
  77. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DI7hHRFL.js +1 -0
  78. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DLVjFsZ3.js +139 -0
  79. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DUrLdbGD.js +89 -0
  80. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DVp1hx9R.js +1 -0
  81. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DY1XQ8fi.js +2 -0
  82. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DZX00Y4g.js +1 -0
  83. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Da0KfYnO.js +1 -0
  84. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DaimHw_p.js +68 -0
  85. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dfy6j1xT.js +323 -0
  86. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dhb8PKl3.js +1 -0
  87. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dle-35c7.js +64 -0
  88. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DmxopI1J.js +1 -0
  89. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DwBR2MJi.js +60 -0
  90. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/GYwsonyD.js +1 -0
  91. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Gi6I4Gst.js +1 -0
  92. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/NqQ1dWOy.js +1 -0
  93. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/RJiighC3.js +1 -0
  94. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Vzk33B_K.js +2 -0
  95. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/ZGh7QtNv.js +7 -0
  96. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bT1r9zLR.js +1 -0
  97. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bTOqqlTd.js +1 -0
  98. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/eNVUfhuA.js +1 -0
  99. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/iEWssX7S.js +162 -0
  100. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/sQeU3Y1z.js +1 -0
  101. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/uuIeMWc-.js +1 -0
  102. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.D6-I5TpK.js +2 -0
  103. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.NWzMBYRp.js +1 -0
  104. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/0.m1gL8KXf.js +1 -0
  105. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.CgNOuw-d.js +1 -0
  106. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.C0GcWctS.js +1 -0
  107. claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -0
  108. claude_mpm/dashboard/static/svelte-build/favicon.svg +7 -0
  109. claude_mpm/dashboard/static/svelte-build/index.html +36 -0
  110. claude_mpm/dashboard-svelte/node_modules/katex/src/fonts/generate_fonts.py +58 -0
  111. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_tfms.py +114 -0
  112. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_ttfs.py +122 -0
  113. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/format_json.py +28 -0
  114. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/parse_tfm.py +211 -0
  115. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc +0 -0
  116. claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc +0 -0
  117. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
  118. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
  119. claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
  120. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
  121. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
  122. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-311.pyc +0 -0
  123. claude_mpm/hooks/claude_hooks/hook_handler.py +149 -1
  124. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
  125. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
  126. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-311.pyc +0 -0
  127. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
  128. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
  129. claude_mpm/hooks/claude_hooks/services/connection_manager.py +26 -6
  130. claude_mpm/hooks/kuzu_memory_hook.py +5 -5
  131. claude_mpm/init.py +276 -0
  132. claude_mpm/models/git_repository.py +3 -3
  133. claude_mpm/scripts/start_activity_logging.py +0 -0
  134. claude_mpm/services/agents/agent_builder.py +3 -3
  135. claude_mpm/services/agents/cache_git_manager.py +6 -6
  136. claude_mpm/services/agents/deployment/agent_deployment.py +29 -7
  137. claude_mpm/services/agents/deployment/agent_discovery_service.py +4 -2
  138. claude_mpm/services/agents/deployment/agent_format_converter.py +25 -13
  139. claude_mpm/services/agents/deployment/agent_template_builder.py +31 -19
  140. claude_mpm/services/agents/deployment/agents_directory_resolver.py +2 -2
  141. claude_mpm/services/agents/deployment/async_agent_deployment.py +31 -27
  142. claude_mpm/services/agents/deployment/local_template_deployment.py +3 -1
  143. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +169 -26
  144. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +98 -75
  145. claude_mpm/services/agents/git_source_manager.py +23 -4
  146. claude_mpm/services/agents/recommender.py +5 -3
  147. claude_mpm/services/agents/single_tier_deployment_service.py +2 -2
  148. claude_mpm/services/agents/sources/git_source_sync_service.py +121 -10
  149. claude_mpm/services/agents/startup_sync.py +22 -2
  150. claude_mpm/services/diagnostics/checks/agent_check.py +2 -2
  151. claude_mpm/services/diagnostics/checks/agent_sources_check.py +1 -1
  152. claude_mpm/services/git/git_operations_service.py +8 -8
  153. claude_mpm/services/monitor/management/lifecycle.py +7 -1
  154. claude_mpm/services/monitor/server.py +473 -3
  155. claude_mpm/services/pm_skills_deployer.py +711 -0
  156. claude_mpm/services/profile_manager.py +337 -0
  157. claude_mpm/services/skills/git_skill_source_manager.py +148 -11
  158. claude_mpm/services/skills/selective_skill_deployer.py +97 -48
  159. claude_mpm/services/skills_deployer.py +161 -65
  160. claude_mpm/services/socketio/dashboard_server.py +1 -0
  161. claude_mpm/services/socketio/event_normalizer.py +37 -6
  162. claude_mpm/services/socketio/server/core.py +262 -123
  163. claude_mpm/skills/bundled/security-scanning.md +112 -0
  164. claude_mpm/skills/skill_manager.py +98 -3
  165. claude_mpm/templates/.pre-commit-config.yaml +112 -0
  166. claude_mpm/utils/agent_dependency_loader.py +14 -2
  167. claude_mpm/utils/agent_filters.py +1 -1
  168. claude_mpm/utils/migration.py +4 -4
  169. claude_mpm/utils/robust_installer.py +47 -3
  170. {claude_mpm-5.4.21.dist-info → claude_mpm-5.4.59.dist-info}/METADATA +7 -4
  171. {claude_mpm-5.4.21.dist-info → claude_mpm-5.4.59.dist-info}/RECORD +175 -81
  172. {claude_mpm-5.4.21.dist-info → claude_mpm-5.4.59.dist-info}/WHEEL +0 -0
  173. {claude_mpm-5.4.21.dist-info → claude_mpm-5.4.59.dist-info}/entry_points.txt +0 -0
  174. {claude_mpm-5.4.21.dist-info → claude_mpm-5.4.59.dist-info}/licenses/LICENSE +0 -0
  175. {claude_mpm-5.4.21.dist-info → claude_mpm-5.4.59.dist-info}/licenses/LICENSE-FAQ.md +0 -0
  176. {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/remote-agents/ (git repository 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:
@@ -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/remote-agents/, ~/.claude-mpm/cache/skills/
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" / "remote-agents"
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/remote-agents/.
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/remote-agents/ → .claude-mpm/agents/ (two-phase, per-project)\n\n"
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
- base_cmd = [sys.executable, "-m", "pip", "install"]
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
- cmd = [sys.executable, "-m", "pip", "install"]
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.in_virtualenv:
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.21
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/remote-agents/`.
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/remote-agents/
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: