claude-mpm 5.4.14__py3-none-any.whl → 5.4.36__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/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +1 -1
- claude_mpm/agents/MEMORY.md +1 -1
- claude_mpm/agents/PM_INSTRUCTIONS.md +363 -817
- 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/cli/chrome_devtools_installer.py +175 -0
- claude_mpm/cli/commands/agent_state_manager.py +10 -10
- claude_mpm/cli/commands/agents.py +9 -40
- claude_mpm/cli/commands/auto_configure.py +4 -4
- claude_mpm/cli/commands/configure.py +1 -1
- claude_mpm/cli/commands/postmortem.py +1 -1
- claude_mpm/cli/commands/skills.py +193 -187
- claude_mpm/cli/interactive/agent_wizard.py +2 -2
- claude_mpm/cli/parsers/agents_parser.py +0 -9
- claude_mpm/cli/parsers/auto_configure_parser.py +0 -138
- claude_mpm/cli/startup.py +330 -78
- claude_mpm/commands/mpm-config.md +1 -2
- claude_mpm/commands/mpm-help.md +14 -95
- claude_mpm/commands/mpm-organize.md +350 -153
- 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/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.B_FtCwCQ.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.Cl_eSA4x.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BgChzWQ1.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIXEwuWe.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWc5urbQ.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DMkZpdF2.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DjhvlsAc.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/N4qtv3Hx.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/uj46x2Wr.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.DTL5mJO-.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.DzuEhzqh.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/0.CAGBuiOw.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DFLC8jdE.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.DPvEihJJ.js +10 -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/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/event_handlers.py +5 -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.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/models/git_repository.py +3 -3
- claude_mpm/scripts/start_activity_logging.py +0 -0
- claude_mpm/services/agents/cache_git_manager.py +6 -6
- claude_mpm/services/agents/deployment/agent_deployment.py +7 -7
- claude_mpm/services/agents/deployment/agent_discovery_service.py +2 -2
- claude_mpm/services/agents/deployment/agent_template_builder.py +2 -2
- claude_mpm/services/agents/deployment/agents_directory_resolver.py +2 -2
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +20 -22
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +55 -53
- claude_mpm/services/agents/git_source_manager.py +2 -2
- 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 +5 -5
- claude_mpm/services/agents/startup_sync.py +22 -2
- claude_mpm/services/command_deployment_service.py +10 -0
- 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/server.py +473 -3
- claude_mpm/services/skills/selective_skill_deployer.py +475 -1
- claude_mpm/services/skills_deployer.py +62 -6
- 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/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.14.dist-info → claude_mpm-5.4.36.dist-info}/METADATA +5 -3
- {claude_mpm-5.4.14.dist-info → claude_mpm-5.4.36.dist-info}/RECORD +96 -66
- claude_mpm/cli/commands/agents_detect.py +0 -380
- claude_mpm/cli/commands/agents_recommend.py +0 -309
- claude_mpm/commands/mpm-agents-auto-configure.md +0 -278
- claude_mpm/commands/mpm-agents-detect.md +0 -177
- claude_mpm/commands/mpm-agents-list.md +0 -131
- claude_mpm/commands/mpm-agents-recommend.md +0 -223
- {claude_mpm-5.4.14.dist-info → claude_mpm-5.4.36.dist-info}/WHEEL +0 -0
- {claude_mpm-5.4.14.dist-info → claude_mpm-5.4.36.dist-info}/entry_points.txt +0 -0
- {claude_mpm-5.4.14.dist-info → claude_mpm-5.4.36.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-5.4.14.dist-info → claude_mpm-5.4.36.dist-info}/licenses/LICENSE-FAQ.md +0 -0
- {claude_mpm-5.4.14.dist-info → claude_mpm-5.4.36.dist-info}/top_level.txt +0 -0
|
@@ -42,7 +42,7 @@ class RemoteAgentMetadata:
|
|
|
42
42
|
class RemoteAgentDiscoveryService:
|
|
43
43
|
"""Discovers and converts remote Markdown agents to JSON format.
|
|
44
44
|
|
|
45
|
-
Remote agents are discovered from the cache directory (~/.claude-mpm/cache/
|
|
45
|
+
Remote agents are discovered from the cache directory (~/.claude-mpm/cache/agents/)
|
|
46
46
|
where they are stored as Markdown files. This service:
|
|
47
47
|
1. Discovers all *.md files in the remote agents cache
|
|
48
48
|
2. Parses Markdown frontmatter and content to extract metadata
|
|
@@ -61,20 +61,20 @@ class RemoteAgentDiscoveryService:
|
|
|
61
61
|
- Flexibility: Supports optional sections with defaults
|
|
62
62
|
"""
|
|
63
63
|
|
|
64
|
-
def __init__(self,
|
|
64
|
+
def __init__(self, agents_cache_dir: Path):
|
|
65
65
|
"""Initialize the remote agent discovery service.
|
|
66
66
|
|
|
67
67
|
Args:
|
|
68
|
-
|
|
68
|
+
agents_cache_dir: Directory containing cached agent Markdown files
|
|
69
69
|
"""
|
|
70
|
-
self.
|
|
70
|
+
self.agents_cache_dir = agents_cache_dir
|
|
71
71
|
self.logger = get_logger(__name__)
|
|
72
72
|
|
|
73
73
|
def _extract_collection_id_from_path(self, file_path: Path) -> Optional[str]:
|
|
74
74
|
"""Extract collection_id from repository path structure.
|
|
75
75
|
|
|
76
76
|
Collection ID is derived from the repository path structure:
|
|
77
|
-
~/.claude-mpm/cache/
|
|
77
|
+
~/.claude-mpm/cache/agents/{owner}/{repo}/agents/...
|
|
78
78
|
|
|
79
79
|
Args:
|
|
80
80
|
file_path: Absolute path to agent Markdown file
|
|
@@ -83,28 +83,29 @@ class RemoteAgentDiscoveryService:
|
|
|
83
83
|
Collection ID in format "owner/repo-name" or None if not found
|
|
84
84
|
|
|
85
85
|
Example:
|
|
86
|
-
Input: ~/.claude-mpm/cache/
|
|
86
|
+
Input: ~/.claude-mpm/cache/agents/bobmatnyc/claude-mpm-agents/agents/pm.md
|
|
87
87
|
Output: "bobmatnyc/claude-mpm-agents"
|
|
88
88
|
"""
|
|
89
89
|
try:
|
|
90
|
-
# Find "
|
|
90
|
+
# Find "agents" cache directory in the path (looking for .claude-mpm/cache/agents)
|
|
91
91
|
path_parts = file_path.parts
|
|
92
|
-
|
|
92
|
+
agents_cache_idx = -1
|
|
93
93
|
|
|
94
94
|
for i, part in enumerate(path_parts):
|
|
95
|
-
|
|
96
|
-
|
|
95
|
+
# Look for cache/agents pattern
|
|
96
|
+
if part == "agents" and i > 0 and path_parts[i - 1] == "cache":
|
|
97
|
+
agents_cache_idx = i
|
|
97
98
|
break
|
|
98
99
|
|
|
99
|
-
if
|
|
100
|
+
if agents_cache_idx == -1 or agents_cache_idx + 2 >= len(path_parts):
|
|
100
101
|
self.logger.debug(
|
|
101
102
|
f"Could not extract collection_id from path: {file_path}"
|
|
102
103
|
)
|
|
103
104
|
return None
|
|
104
105
|
|
|
105
|
-
# Extract owner and repo (next two parts after "
|
|
106
|
-
owner = path_parts[
|
|
107
|
-
repo = path_parts[
|
|
106
|
+
# Extract owner and repo (next two parts after "cache/agents")
|
|
107
|
+
owner = path_parts[agents_cache_idx + 1]
|
|
108
|
+
repo = path_parts[agents_cache_idx + 2]
|
|
108
109
|
|
|
109
110
|
collection_id = f"{owner}/{repo}"
|
|
110
111
|
self.logger.debug(f"Extracted collection_id: {collection_id}")
|
|
@@ -128,25 +129,26 @@ class RemoteAgentDiscoveryService:
|
|
|
128
129
|
Relative path from repo root, or None if not found
|
|
129
130
|
|
|
130
131
|
Example:
|
|
131
|
-
Input: ~/.claude-mpm/cache/
|
|
132
|
+
Input: ~/.claude-mpm/cache/agents/bobmatnyc/claude-mpm-agents/agents/pm.md
|
|
132
133
|
Output: "agents/pm.md"
|
|
133
134
|
"""
|
|
134
135
|
try:
|
|
135
|
-
# Find "
|
|
136
|
+
# Find "agents" cache directory in the path
|
|
136
137
|
path_parts = file_path.parts
|
|
137
|
-
|
|
138
|
+
agents_cache_idx = -1
|
|
138
139
|
|
|
139
140
|
for i, part in enumerate(path_parts):
|
|
140
|
-
|
|
141
|
-
|
|
141
|
+
# Look for cache/agents pattern
|
|
142
|
+
if part == "agents" and i > 0 and path_parts[i - 1] == "cache":
|
|
143
|
+
agents_cache_idx = i
|
|
142
144
|
break
|
|
143
145
|
|
|
144
|
-
if
|
|
146
|
+
if agents_cache_idx == -1 or agents_cache_idx + 3 >= len(path_parts):
|
|
145
147
|
return None
|
|
146
148
|
|
|
147
149
|
# Path after owner/repo is the source path
|
|
148
|
-
#
|
|
149
|
-
repo_root_idx =
|
|
150
|
+
# cache/agents/{owner}/{repo}/{source_path}
|
|
151
|
+
repo_root_idx = agents_cache_idx + 3
|
|
150
152
|
source_parts = path_parts[repo_root_idx:]
|
|
151
153
|
|
|
152
154
|
return "/".join(source_parts)
|
|
@@ -273,7 +275,7 @@ class RemoteAgentDiscoveryService:
|
|
|
273
275
|
|
|
274
276
|
Supports both cache structures:
|
|
275
277
|
1. Git repo: Calculate relative to /agents/ subdirectory
|
|
276
|
-
2. Flattened cache: Calculate relative to
|
|
278
|
+
2. Flattened cache: Calculate relative to agents_cache_dir directly
|
|
277
279
|
|
|
278
280
|
Example (Git repo):
|
|
279
281
|
Input: /cache/bobmatnyc/claude-mpm-agents/agents/engineer/backend/python-engineer.md
|
|
@@ -281,8 +283,8 @@ class RemoteAgentDiscoveryService:
|
|
|
281
283
|
Output: engineer/backend/python-engineer
|
|
282
284
|
|
|
283
285
|
Example (Flattened cache):
|
|
284
|
-
Input: /cache/
|
|
285
|
-
Root: /cache/
|
|
286
|
+
Input: /cache/agents/engineer/python-engineer.md
|
|
287
|
+
Root: /cache/agents
|
|
286
288
|
Output: engineer/python-engineer
|
|
287
289
|
|
|
288
290
|
Args:
|
|
@@ -293,7 +295,7 @@ class RemoteAgentDiscoveryService:
|
|
|
293
295
|
"""
|
|
294
296
|
try:
|
|
295
297
|
# Try git repo structure first: /agents/ subdirectory
|
|
296
|
-
agents_dir = self.
|
|
298
|
+
agents_dir = self.agents_cache_dir / "agents"
|
|
297
299
|
if agents_dir.exists():
|
|
298
300
|
try:
|
|
299
301
|
relative_path = file_path.relative_to(agents_dir)
|
|
@@ -301,12 +303,12 @@ class RemoteAgentDiscoveryService:
|
|
|
301
303
|
except ValueError:
|
|
302
304
|
pass # Not under agents_dir, try flattened structure
|
|
303
305
|
|
|
304
|
-
# Try flattened cache structure: calculate relative to
|
|
306
|
+
# Try flattened cache structure: calculate relative to agents_cache_dir
|
|
305
307
|
try:
|
|
306
|
-
relative_path = file_path.relative_to(self.
|
|
308
|
+
relative_path = file_path.relative_to(self.agents_cache_dir)
|
|
307
309
|
return str(relative_path.with_suffix("")).replace("\\", "/")
|
|
308
310
|
except ValueError:
|
|
309
|
-
pass # Not under
|
|
311
|
+
pass # Not under agents_cache_dir either
|
|
310
312
|
|
|
311
313
|
# Fall back to filename
|
|
312
314
|
self.logger.warning(
|
|
@@ -327,7 +329,7 @@ class RemoteAgentDiscoveryService:
|
|
|
327
329
|
|
|
328
330
|
Supports both cache structures:
|
|
329
331
|
1. Git repo: Calculate relative to /agents/ subdirectory
|
|
330
|
-
2. Flattened cache: Calculate relative to
|
|
332
|
+
2. Flattened cache: Calculate relative to agents_cache_dir directly
|
|
331
333
|
|
|
332
334
|
Example (Git repo):
|
|
333
335
|
Input: /cache/bobmatnyc/claude-mpm-agents/agents/engineer/backend/python-engineer.md
|
|
@@ -335,8 +337,8 @@ class RemoteAgentDiscoveryService:
|
|
|
335
337
|
Output: engineer/backend
|
|
336
338
|
|
|
337
339
|
Example (Flattened cache):
|
|
338
|
-
Input: /cache/
|
|
339
|
-
Root: /cache/
|
|
340
|
+
Input: /cache/agents/engineer/python-engineer.md
|
|
341
|
+
Root: /cache/agents
|
|
340
342
|
Output: engineer
|
|
341
343
|
|
|
342
344
|
Args:
|
|
@@ -347,7 +349,7 @@ class RemoteAgentDiscoveryService:
|
|
|
347
349
|
"""
|
|
348
350
|
try:
|
|
349
351
|
# Try git repo structure first: /agents/ subdirectory
|
|
350
|
-
agents_dir = self.
|
|
352
|
+
agents_dir = self.agents_cache_dir / "agents"
|
|
351
353
|
if agents_dir.exists():
|
|
352
354
|
try:
|
|
353
355
|
relative_path = file_path.relative_to(agents_dir)
|
|
@@ -356,13 +358,13 @@ class RemoteAgentDiscoveryService:
|
|
|
356
358
|
except ValueError:
|
|
357
359
|
pass # Not under agents_dir, try flattened structure
|
|
358
360
|
|
|
359
|
-
# Try flattened cache structure: calculate relative to
|
|
361
|
+
# Try flattened cache structure: calculate relative to agents_cache_dir
|
|
360
362
|
try:
|
|
361
|
-
relative_path = file_path.relative_to(self.
|
|
363
|
+
relative_path = file_path.relative_to(self.agents_cache_dir)
|
|
362
364
|
parts = relative_path.parts[:-1] # Exclude filename
|
|
363
365
|
return "/".join(parts) if parts else "universal"
|
|
364
366
|
except ValueError:
|
|
365
|
-
pass # Not under
|
|
367
|
+
pass # Not under agents_cache_dir either
|
|
366
368
|
|
|
367
369
|
return "universal"
|
|
368
370
|
except Exception:
|
|
@@ -385,7 +387,7 @@ class RemoteAgentDiscoveryService:
|
|
|
385
387
|
List of agent dictionaries in JSON template format
|
|
386
388
|
|
|
387
389
|
Example:
|
|
388
|
-
>>> service = RemoteAgentDiscoveryService(Path("~/.claude-mpm/cache/
|
|
390
|
+
>>> service = RemoteAgentDiscoveryService(Path("~/.claude-mpm/cache/agents"))
|
|
389
391
|
>>> agents = service.discover_remote_agents()
|
|
390
392
|
>>> len(agents)
|
|
391
393
|
5
|
|
@@ -394,9 +396,9 @@ class RemoteAgentDiscoveryService:
|
|
|
394
396
|
"""
|
|
395
397
|
agents = []
|
|
396
398
|
|
|
397
|
-
if not self.
|
|
399
|
+
if not self.agents_cache_dir.exists():
|
|
398
400
|
self.logger.debug(
|
|
399
|
-
f"
|
|
401
|
+
f"Agents cache directory does not exist: {self.agents_cache_dir}"
|
|
400
402
|
)
|
|
401
403
|
return agents
|
|
402
404
|
|
|
@@ -406,8 +408,8 @@ class RemoteAgentDiscoveryService:
|
|
|
406
408
|
# 3. Flattened cache: {path}/ - directly contains category directories (legacy)
|
|
407
409
|
|
|
408
410
|
# Priority 1: Check for dist/agents/ (built output with BASE-AGENT composition)
|
|
409
|
-
dist_agents_dir = self.
|
|
410
|
-
agents_dir = self.
|
|
411
|
+
dist_agents_dir = self.agents_cache_dir / "dist" / "agents"
|
|
412
|
+
agents_dir = self.agents_cache_dir / "agents"
|
|
411
413
|
|
|
412
414
|
if dist_agents_dir.exists():
|
|
413
415
|
# PREFERRED: Use built agents from dist/agents/
|
|
@@ -431,18 +433,18 @@ class RemoteAgentDiscoveryService:
|
|
|
431
433
|
"documentation",
|
|
432
434
|
]
|
|
433
435
|
has_categories = any(
|
|
434
|
-
(self.
|
|
436
|
+
(self.agents_cache_dir / cat).exists() for cat in category_dirs
|
|
435
437
|
)
|
|
436
438
|
|
|
437
439
|
if has_categories:
|
|
438
440
|
self.logger.debug(
|
|
439
|
-
f"Using flattened cache structure: {self.
|
|
441
|
+
f"Using flattened cache structure: {self.agents_cache_dir}"
|
|
440
442
|
)
|
|
441
|
-
scan_dir = self.
|
|
443
|
+
scan_dir = self.agents_cache_dir
|
|
442
444
|
else:
|
|
443
445
|
self.logger.warning(
|
|
444
446
|
f"No agent directories found. Checked: {dist_agents_dir}, {agents_dir}, "
|
|
445
|
-
f"and category directories in {self.
|
|
447
|
+
f"and category directories in {self.agents_cache_dir}. "
|
|
446
448
|
f"Expected agents in /dist/agents/, /agents/, or category directories."
|
|
447
449
|
)
|
|
448
450
|
return agents
|
|
@@ -482,16 +484,16 @@ class RemoteAgentDiscoveryService:
|
|
|
482
484
|
|
|
483
485
|
# In flattened cache mode, also exclude files from git repository subdirectories
|
|
484
486
|
# (files under directories that contain .git folder)
|
|
485
|
-
if scan_dir == self.
|
|
487
|
+
if scan_dir == self.agents_cache_dir:
|
|
486
488
|
filtered_files = []
|
|
487
489
|
for f in md_files:
|
|
488
490
|
# Check if this file is inside a git repository (has .git in path)
|
|
489
|
-
# Git repos are at {
|
|
490
|
-
path_parts = f.relative_to(self.
|
|
491
|
+
# Git repos are at {agents_cache_dir}/{owner}/{repo}/.git
|
|
492
|
+
path_parts = f.relative_to(self.agents_cache_dir).parts
|
|
491
493
|
if len(path_parts) >= 2:
|
|
492
494
|
# Check if this looks like a git repo path (owner/repo)
|
|
493
495
|
potential_repo = (
|
|
494
|
-
self.
|
|
496
|
+
self.agents_cache_dir / path_parts[0] / path_parts[1]
|
|
495
497
|
)
|
|
496
498
|
if (potential_repo / ".git").exists():
|
|
497
499
|
# This file is in a git repo, skip it (we'll handle git repos separately)
|
|
@@ -518,7 +520,7 @@ class RemoteAgentDiscoveryService:
|
|
|
518
520
|
self.logger.warning(f"Failed to parse remote agent {md_file.name}: {e}")
|
|
519
521
|
|
|
520
522
|
self.logger.info(
|
|
521
|
-
f"Discovered {len(agents)} remote agents from {self.
|
|
523
|
+
f"Discovered {len(agents)} remote agents from {self.agents_cache_dir.name}"
|
|
522
524
|
)
|
|
523
525
|
return agents
|
|
524
526
|
|
|
@@ -735,7 +737,7 @@ class RemoteAgentDiscoveryService:
|
|
|
735
737
|
RemoteAgentMetadata if found, None otherwise
|
|
736
738
|
"""
|
|
737
739
|
# Bug #4 fix: Search in /agents/ subdirectory, not root directory
|
|
738
|
-
agents_dir = self.
|
|
740
|
+
agents_dir = self.agents_cache_dir / "agents"
|
|
739
741
|
if not agents_dir.exists():
|
|
740
742
|
return None
|
|
741
743
|
|
|
@@ -767,7 +769,7 @@ class RemoteAgentDiscoveryService:
|
|
|
767
769
|
List of agent dictionaries from the specified collection
|
|
768
770
|
|
|
769
771
|
Example:
|
|
770
|
-
>>> service = RemoteAgentDiscoveryService(Path("~/.claude-mpm/cache/
|
|
772
|
+
>>> service = RemoteAgentDiscoveryService(Path("~/.claude-mpm/cache/agents"))
|
|
771
773
|
>>> agents = service.get_agents_by_collection("bobmatnyc/claude-mpm-agents")
|
|
772
774
|
>>> len(agents)
|
|
773
775
|
45
|
|
@@ -795,7 +797,7 @@ class RemoteAgentDiscoveryService:
|
|
|
795
797
|
- agents: List of agent IDs in collection
|
|
796
798
|
|
|
797
799
|
Example:
|
|
798
|
-
>>> service = RemoteAgentDiscoveryService(Path("~/.claude-mpm/cache/
|
|
800
|
+
>>> service = RemoteAgentDiscoveryService(Path("~/.claude-mpm/cache/agents"))
|
|
799
801
|
>>> collections = service.list_collections()
|
|
800
802
|
>>> collections
|
|
801
803
|
[
|
|
@@ -50,10 +50,10 @@ class GitSourceManager:
|
|
|
50
50
|
|
|
51
51
|
Args:
|
|
52
52
|
cache_root: Root directory for repository caches.
|
|
53
|
-
Defaults to ~/.claude-mpm/cache/
|
|
53
|
+
Defaults to ~/.claude-mpm/cache/agents/
|
|
54
54
|
"""
|
|
55
55
|
if cache_root is None:
|
|
56
|
-
cache_root = Path.home() / ".claude-mpm" / "cache" / "
|
|
56
|
+
cache_root = Path.home() / ".claude-mpm" / "cache" / "agents"
|
|
57
57
|
|
|
58
58
|
self.cache_root = cache_root
|
|
59
59
|
self.cache_root.mkdir(parents=True, exist_ok=True)
|
|
@@ -226,9 +226,11 @@ class AgentRecommenderService(BaseService, IAgentRecommender):
|
|
|
226
226
|
if max_agents is not None:
|
|
227
227
|
recommendations = recommendations[:max_agents]
|
|
228
228
|
|
|
229
|
-
# Check if
|
|
230
|
-
if not recommendations
|
|
231
|
-
self.logger.info(
|
|
229
|
+
# Check if we have no recommendations (any reason: unknown language, low scores, etc.)
|
|
230
|
+
if not recommendations:
|
|
231
|
+
self.logger.info(
|
|
232
|
+
f"No agents scored above threshold for {toolchain.primary_language}; using defaults"
|
|
233
|
+
)
|
|
232
234
|
|
|
233
235
|
# Get default configuration
|
|
234
236
|
default_config = self._capabilities_config.get("default_configuration", {})
|
|
@@ -78,14 +78,14 @@ class SingleTierDeploymentService:
|
|
|
78
78
|
config: Agent source configuration with repositories
|
|
79
79
|
deployment_dir: Target deployment directory (.claude/agents/)
|
|
80
80
|
cache_root: Cache root for repositories
|
|
81
|
-
(defaults to ~/.claude-mpm/cache/
|
|
81
|
+
(defaults to ~/.claude-mpm/cache/agents/)
|
|
82
82
|
"""
|
|
83
83
|
self.config = config
|
|
84
84
|
self.deployment_dir = deployment_dir
|
|
85
85
|
self.deployment_dir.mkdir(parents=True, exist_ok=True)
|
|
86
86
|
|
|
87
87
|
if cache_root is None:
|
|
88
|
-
cache_root = Path.home() / ".claude-mpm" / "cache" / "
|
|
88
|
+
cache_root = Path.home() / ".claude-mpm" / "cache" / "agents"
|
|
89
89
|
|
|
90
90
|
self.cache_root = cache_root
|
|
91
91
|
self.git_source_manager = GitSourceManager(cache_root)
|
|
@@ -188,10 +188,10 @@ class GitSourceSyncService:
|
|
|
188
188
|
|
|
189
189
|
Args:
|
|
190
190
|
source_url: Base URL for raw files (without trailing slash)
|
|
191
|
-
cache_dir: Local cache directory (defaults to ~/.claude-mpm/cache/
|
|
191
|
+
cache_dir: Local cache directory (defaults to ~/.claude-mpm/cache/agents/)
|
|
192
192
|
source_id: Unique identifier for this source (for multi-source support)
|
|
193
193
|
|
|
194
|
-
Design Decision: Cache to ~/.claude-mpm/cache/
|
|
194
|
+
Design Decision: Cache to ~/.claude-mpm/cache/agents/ (canonical location)
|
|
195
195
|
|
|
196
196
|
Rationale: Separates cached repository structure from deployed agents.
|
|
197
197
|
This allows preserving nested directory structure in cache while
|
|
@@ -207,13 +207,13 @@ class GitSourceSyncService:
|
|
|
207
207
|
self.source_url = source_url.rstrip("/")
|
|
208
208
|
self.source_id = source_id
|
|
209
209
|
|
|
210
|
-
# Setup cache directory (canonical: ~/.claude-mpm/cache/
|
|
210
|
+
# Setup cache directory (canonical: ~/.claude-mpm/cache/agents/)
|
|
211
211
|
if cache_dir:
|
|
212
212
|
self.cache_dir = Path(cache_dir)
|
|
213
213
|
else:
|
|
214
|
-
# Default to ~/.claude-mpm/cache/
|
|
214
|
+
# Default to ~/.claude-mpm/cache/agents/ (canonical cache location)
|
|
215
215
|
home = Path.home()
|
|
216
|
-
self.cache_dir = home / ".claude-mpm" / "cache" / "
|
|
216
|
+
self.cache_dir = home / ".claude-mpm" / "cache" / "agents"
|
|
217
217
|
|
|
218
218
|
self.cache_dir.mkdir(parents=True, exist_ok=True)
|
|
219
219
|
|
|
@@ -110,6 +110,26 @@ def sync_agents_on_startup(config: Optional[Dict[str, Any]] = None) -> Dict[str,
|
|
|
110
110
|
else:
|
|
111
111
|
cache_dir = None # Will use default
|
|
112
112
|
|
|
113
|
+
# Check for old cache directory names and provide migration guidance
|
|
114
|
+
# This handles users upgrading from older versions
|
|
115
|
+
old_cache_paths = [
|
|
116
|
+
Path.home() / ".claude-mpm" / "cache" / "remote-agents",
|
|
117
|
+
]
|
|
118
|
+
new_cache_dir = Path.home() / ".claude-mpm" / "cache" / "agents"
|
|
119
|
+
|
|
120
|
+
for old_cache in old_cache_paths:
|
|
121
|
+
if old_cache.exists() and not new_cache_dir.exists():
|
|
122
|
+
logger.warning(f"Found old cache directory: {old_cache}")
|
|
123
|
+
logger.warning(
|
|
124
|
+
"The cache directory location has changed to: ~/.claude-mpm/cache/agents"
|
|
125
|
+
)
|
|
126
|
+
logger.warning("To migrate your existing cache, run:")
|
|
127
|
+
logger.warning(f" mv {old_cache} {new_cache_dir}")
|
|
128
|
+
logger.info(
|
|
129
|
+
"Agents will be re-synced to the new cache location automatically."
|
|
130
|
+
)
|
|
131
|
+
break # Only show warning once
|
|
132
|
+
|
|
113
133
|
# Sync each enabled source
|
|
114
134
|
for source_config in sources:
|
|
115
135
|
try:
|
|
@@ -217,7 +237,7 @@ def get_sync_status() -> Dict[str, Any]:
|
|
|
217
237
|
"enabled": agent_sync_config.get("enabled", True),
|
|
218
238
|
"sources_configured": len(enabled_sources),
|
|
219
239
|
"cache_dir": agent_sync_config.get(
|
|
220
|
-
"cache_dir", "~/.claude-mpm/cache/
|
|
240
|
+
"cache_dir", "~/.claude-mpm/cache/agents"
|
|
221
241
|
),
|
|
222
242
|
}
|
|
223
243
|
|
|
@@ -233,7 +253,7 @@ def get_sync_status() -> Dict[str, Any]:
|
|
|
233
253
|
return {
|
|
234
254
|
"enabled": False,
|
|
235
255
|
"sources_configured": 0,
|
|
236
|
-
"cache_dir": "~/.claude-mpm/cache/
|
|
256
|
+
"cache_dir": "~/.claude-mpm/cache/agents",
|
|
237
257
|
"last_sync": None,
|
|
238
258
|
"error": str(e),
|
|
239
259
|
}
|
|
@@ -26,6 +26,11 @@ class CommandDeploymentService(BaseService):
|
|
|
26
26
|
"mpm-config-view.md", # Replaced by mpm-config.md
|
|
27
27
|
"mpm-resume.md", # Replaced by mpm-session-resume.md
|
|
28
28
|
"mpm-ticket.md", # Replaced by mpm-ticket-view.md
|
|
29
|
+
# Removed - consolidated into /mpm-configure
|
|
30
|
+
"mpm-agents-list.md", # Consolidated into /mpm-configure
|
|
31
|
+
"mpm-agents-detect.md", # Consolidated into /mpm-configure
|
|
32
|
+
"mpm-agents-auto-configure.md", # Consolidated into /mpm-configure
|
|
33
|
+
"mpm-agents-recommend.md", # Consolidated into /mpm-configure
|
|
29
34
|
]
|
|
30
35
|
|
|
31
36
|
def __init__(self):
|
|
@@ -317,6 +322,11 @@ class CommandDeploymentService(BaseService):
|
|
|
317
322
|
"mpm-config-view.md": "mpm-config.md",
|
|
318
323
|
"mpm-resume.md": "mpm-session-resume.md",
|
|
319
324
|
"mpm-ticket.md": "mpm-ticket-view.md",
|
|
325
|
+
# Removed commands - consolidated into /mpm-configure
|
|
326
|
+
"mpm-agents-list.md": "mpm-configure (use /mpm-configure)",
|
|
327
|
+
"mpm-agents-detect.md": "mpm-configure (use /mpm-configure)",
|
|
328
|
+
"mpm-agents-auto-configure.md": "mpm-configure (use /mpm-configure)",
|
|
329
|
+
"mpm-agents-recommend.md": "mpm-configure (use /mpm-configure)",
|
|
320
330
|
}
|
|
321
331
|
|
|
322
332
|
for deprecated_cmd in self.DEPRECATED_COMMANDS:
|
|
@@ -66,9 +66,9 @@ class AgentCheck(BaseDiagnosticCheck):
|
|
|
66
66
|
|
|
67
67
|
if deployed_count == 0:
|
|
68
68
|
status = ValidationSeverity.ERROR
|
|
69
|
-
message = f"No agents deployed (0/{available_count}
|
|
69
|
+
message = f"No agents deployed (0/{available_count} cached)"
|
|
70
70
|
fix_command = "claude-mpm agents deploy"
|
|
71
|
-
fix_description = "Deploy all
|
|
71
|
+
fix_description = "Deploy all cached agents"
|
|
72
72
|
elif deployed_count < available_count:
|
|
73
73
|
status = ValidationSeverity.WARNING
|
|
74
74
|
message = f"{deployed_count}/{available_count} agents deployed"
|
|
@@ -432,7 +432,7 @@ class AgentSourcesCheck(BaseDiagnosticCheck):
|
|
|
432
432
|
|
|
433
433
|
def _check_cache_directory(self) -> DiagnosticResult:
|
|
434
434
|
"""Check cache directory health."""
|
|
435
|
-
cache_dir = Path.home() / ".claude-mpm" / "cache" / "
|
|
435
|
+
cache_dir = Path.home() / ".claude-mpm" / "cache" / "agents"
|
|
436
436
|
|
|
437
437
|
if not cache_dir.exists():
|
|
438
438
|
return DiagnosticResult(
|
|
@@ -12,10 +12,10 @@ Design Decisions:
|
|
|
12
12
|
|
|
13
13
|
Example:
|
|
14
14
|
>>> service = GitOperationsService()
|
|
15
|
-
>>> success = service.create_branch(Path("~/.claude-mpm/cache/
|
|
15
|
+
>>> success = service.create_branch(Path("~/.claude-mpm/cache/agents"), "improve/research-memory")
|
|
16
16
|
>>> if success:
|
|
17
|
-
... service.stage_files(Path("~/.claude-mpm/cache/
|
|
18
|
-
... service.commit(Path("~/.claude-mpm/cache/
|
|
17
|
+
... service.stage_files(Path("~/.claude-mpm/cache/agents"), ["agents/research.md"])
|
|
18
|
+
... service.commit(Path("~/.claude-mpm/cache/agents"), "feat: improve research agent memory handling")
|
|
19
19
|
"""
|
|
20
20
|
|
|
21
21
|
import logging
|
|
@@ -68,7 +68,7 @@ class GitOperationsService:
|
|
|
68
68
|
|
|
69
69
|
Example:
|
|
70
70
|
>>> service = GitOperationsService()
|
|
71
|
-
>>> service.is_git_repo(Path("~/.claude-mpm/cache/
|
|
71
|
+
>>> service.is_git_repo(Path("~/.claude-mpm/cache/agents"))
|
|
72
72
|
True
|
|
73
73
|
"""
|
|
74
74
|
try:
|
|
@@ -150,7 +150,7 @@ class GitOperationsService:
|
|
|
150
150
|
Example:
|
|
151
151
|
>>> service = GitOperationsService()
|
|
152
152
|
>>> service.create_and_checkout_branch(
|
|
153
|
-
... Path("~/.claude-mpm/cache/
|
|
153
|
+
... Path("~/.claude-mpm/cache/agents"),
|
|
154
154
|
... "improve/research-memory",
|
|
155
155
|
... "main"
|
|
156
156
|
... )
|
|
@@ -245,7 +245,7 @@ class GitOperationsService:
|
|
|
245
245
|
Example:
|
|
246
246
|
>>> service = GitOperationsService()
|
|
247
247
|
>>> service.commit(
|
|
248
|
-
... Path("~/.claude-mpm/cache/
|
|
248
|
+
... Path("~/.claude-mpm/cache/agents"),
|
|
249
249
|
... "feat(agent): improve research agent memory handling\\n\\n- Add hard limit of 5 files"
|
|
250
250
|
... )
|
|
251
251
|
True
|
|
@@ -289,7 +289,7 @@ class GitOperationsService:
|
|
|
289
289
|
|
|
290
290
|
Example:
|
|
291
291
|
>>> service = GitOperationsService()
|
|
292
|
-
>>> service.push(Path("~/.claude-mpm/cache/
|
|
292
|
+
>>> service.push(Path("~/.claude-mpm/cache/agents"), "improve/research-memory")
|
|
293
293
|
True
|
|
294
294
|
"""
|
|
295
295
|
self._validate_repo(repo_path)
|
|
@@ -489,7 +489,7 @@ class GitOperationsService:
|
|
|
489
489
|
|
|
490
490
|
Example:
|
|
491
491
|
>>> service = GitOperationsService()
|
|
492
|
-
>>> valid, msg = service.validate_repo(Path("~/.claude-mpm/cache/
|
|
492
|
+
>>> valid, msg = service.validate_repo(Path("~/.claude-mpm/cache/agents"))
|
|
493
493
|
>>> if not valid:
|
|
494
494
|
... print(f"Repository invalid: {msg}")
|
|
495
495
|
"""
|