claude-mpm 5.4.3__py3-none-any.whl → 5.4.14__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/__init__.py +4 -0
- claude_mpm/agents/PM_INSTRUCTIONS.md +39 -0
- claude_mpm/agents/agent_loader.py +3 -27
- claude_mpm/cli/__main__.py +4 -0
- claude_mpm/cli/commands/auto_configure.py +210 -25
- claude_mpm/cli/commands/config.py +88 -2
- claude_mpm/cli/commands/configure.py +85 -43
- claude_mpm/cli/commands/configure_agent_display.py +3 -1
- claude_mpm/cli/commands/mpm_init/core.py +2 -45
- claude_mpm/cli/commands/skills.py +21 -2
- claude_mpm/cli/executor.py +3 -3
- claude_mpm/cli/parsers/config_parser.py +153 -83
- claude_mpm/cli/parsers/skills_parser.py +3 -2
- claude_mpm/cli/startup.py +273 -36
- claude_mpm/commands/mpm-config.md +266 -0
- claude_mpm/core/framework/formatters/content_formatter.py +3 -13
- claude_mpm/core/framework_loader.py +4 -2
- claude_mpm/core/logger.py +13 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +171 -76
- claude_mpm/hooks/claude_hooks/hook_handler.py +2 -0
- claude_mpm/hooks/claude_hooks/installer.py +33 -10
- claude_mpm/hooks/claude_hooks/memory_integration.py +26 -9
- claude_mpm/hooks/claude_hooks/response_tracking.py +2 -3
- claude_mpm/hooks/memory_integration_hook.py +46 -1
- claude_mpm/init.py +0 -19
- claude_mpm/scripts/claude-hook-handler.sh +58 -18
- claude_mpm/services/agents/agent_recommendation_service.py +6 -7
- claude_mpm/services/agents/agent_review_service.py +280 -0
- claude_mpm/services/agents/deployment/agent_discovery_service.py +2 -3
- claude_mpm/services/agents/deployment/agent_template_builder.py +1 -0
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +78 -9
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +13 -0
- claude_mpm/services/agents/git_source_manager.py +14 -0
- claude_mpm/services/agents/loading/base_agent_manager.py +1 -13
- claude_mpm/services/agents/toolchain_detector.py +6 -3
- claude_mpm/services/command_deployment_service.py +71 -8
- claude_mpm/services/git/git_operations_service.py +93 -8
- claude_mpm/services/self_upgrade_service.py +120 -12
- claude_mpm/services/skills/__init__.py +3 -0
- claude_mpm/services/skills/git_skill_source_manager.py +32 -2
- claude_mpm/services/skills/selective_skill_deployer.py +230 -0
- claude_mpm/services/skills/skill_to_agent_mapper.py +406 -0
- claude_mpm/services/skills_deployer.py +64 -3
- {claude_mpm-5.4.3.dist-info → claude_mpm-5.4.14.dist-info}/METADATA +47 -8
- {claude_mpm-5.4.3.dist-info → claude_mpm-5.4.14.dist-info}/RECORD +51 -70
- {claude_mpm-5.4.3.dist-info → claude_mpm-5.4.14.dist-info}/entry_points.txt +0 -3
- claude_mpm-5.4.14.dist-info/licenses/LICENSE +94 -0
- claude_mpm-5.4.14.dist-info/licenses/LICENSE-FAQ.md +153 -0
- claude_mpm/agents/BASE_AGENT_TEMPLATE.md +0 -292
- claude_mpm/agents/BASE_DOCUMENTATION.md +0 -53
- claude_mpm/agents/BASE_ENGINEER.md +0 -658
- claude_mpm/agents/BASE_OPS.md +0 -219
- claude_mpm/agents/BASE_PM.md +0 -480
- claude_mpm/agents/BASE_PROMPT_ENGINEER.md +0 -787
- claude_mpm/agents/BASE_QA.md +0 -167
- claude_mpm/agents/BASE_RESEARCH.md +0 -53
- claude_mpm/agents/base_agent.json +0 -31
- claude_mpm/agents/base_agent_loader.py +0 -601
- claude_mpm/cli/ticket_cli.py +0 -35
- claude_mpm/commands/mpm-config-view.md +0 -150
- claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-313.pyc +0 -0
- claude_mpm-5.4.3.dist-info/licenses/LICENSE +0 -21
- {claude_mpm-5.4.3.dist-info → claude_mpm-5.4.14.dist-info}/WHEEL +0 -0
- {claude_mpm-5.4.3.dist-info → claude_mpm-5.4.14.dist-info}/top_level.txt +0 -0
claude_mpm/cli/startup.py
CHANGED
|
@@ -14,6 +14,52 @@ import warnings
|
|
|
14
14
|
from pathlib import Path
|
|
15
15
|
|
|
16
16
|
|
|
17
|
+
def sync_hooks_on_startup(quiet: bool = False) -> bool:
|
|
18
|
+
"""Ensure hooks are up-to-date on startup.
|
|
19
|
+
|
|
20
|
+
WHY: Users can have stale hook configurations in settings.json that cause errors.
|
|
21
|
+
Reinstalling hooks ensures the hook format matches the current code.
|
|
22
|
+
|
|
23
|
+
DESIGN DECISION: Shows brief status message on success for user awareness.
|
|
24
|
+
Failures are logged but don't prevent startup to ensure claude-mpm remains functional.
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
quiet: If True, suppress all output (used internally)
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
bool: True if hooks were synced successfully, False otherwise
|
|
31
|
+
"""
|
|
32
|
+
try:
|
|
33
|
+
from ..hooks.claude_hooks.installer import HookInstaller
|
|
34
|
+
|
|
35
|
+
installer = HookInstaller()
|
|
36
|
+
|
|
37
|
+
# Show brief status (hooks sync is fast)
|
|
38
|
+
if not quiet:
|
|
39
|
+
print("Syncing Claude Code hooks...", end=" ", flush=True)
|
|
40
|
+
|
|
41
|
+
# Reinstall hooks (force=True ensures update)
|
|
42
|
+
success = installer.install_hooks(force=True)
|
|
43
|
+
|
|
44
|
+
if not quiet:
|
|
45
|
+
if success:
|
|
46
|
+
print("✓")
|
|
47
|
+
else:
|
|
48
|
+
print("(skipped)")
|
|
49
|
+
|
|
50
|
+
return success
|
|
51
|
+
|
|
52
|
+
except Exception as e:
|
|
53
|
+
if not quiet:
|
|
54
|
+
print("(error)")
|
|
55
|
+
# Log but don't fail startup
|
|
56
|
+
from ..core.logger import get_logger
|
|
57
|
+
|
|
58
|
+
logger = get_logger("startup")
|
|
59
|
+
logger.warning(f"Hook sync failed (non-fatal): {e}")
|
|
60
|
+
return False
|
|
61
|
+
|
|
62
|
+
|
|
17
63
|
def check_legacy_cache() -> None:
|
|
18
64
|
"""Check for legacy cache/agents/ directory and warn user.
|
|
19
65
|
|
|
@@ -294,6 +340,84 @@ def deploy_output_style_on_startup():
|
|
|
294
340
|
# Continue execution - output style deployment shouldn't block startup
|
|
295
341
|
|
|
296
342
|
|
|
343
|
+
def _cleanup_orphaned_agents(deploy_target: Path, deployed_agents: list[str]) -> int:
|
|
344
|
+
"""Remove agents that are managed by claude-mpm but no longer deployed.
|
|
345
|
+
|
|
346
|
+
WHY: When agent configurations change, old agents should be removed to avoid
|
|
347
|
+
confusion and stale agent references. Only removes claude-mpm managed agents,
|
|
348
|
+
leaving user-created agents untouched.
|
|
349
|
+
|
|
350
|
+
SAFETY: Only removes files with claude-mpm ownership markers in frontmatter.
|
|
351
|
+
Files without frontmatter or without ownership indicators are preserved.
|
|
352
|
+
|
|
353
|
+
Args:
|
|
354
|
+
deploy_target: Path to .claude/agents/ directory
|
|
355
|
+
deployed_agents: List of agent filenames that should remain
|
|
356
|
+
|
|
357
|
+
Returns:
|
|
358
|
+
Number of agents removed
|
|
359
|
+
"""
|
|
360
|
+
import re
|
|
361
|
+
|
|
362
|
+
import yaml
|
|
363
|
+
|
|
364
|
+
from ..core.logger import get_logger
|
|
365
|
+
|
|
366
|
+
logger = get_logger("cli")
|
|
367
|
+
removed_count = 0
|
|
368
|
+
deployed_set = set(deployed_agents)
|
|
369
|
+
|
|
370
|
+
if not deploy_target.exists():
|
|
371
|
+
return 0
|
|
372
|
+
|
|
373
|
+
# Scan all .md files in agents directory
|
|
374
|
+
for agent_file in deploy_target.glob("*.md"):
|
|
375
|
+
# Skip hidden files
|
|
376
|
+
if agent_file.name.startswith("."):
|
|
377
|
+
continue
|
|
378
|
+
|
|
379
|
+
# Skip if this agent should remain deployed
|
|
380
|
+
if agent_file.name in deployed_set:
|
|
381
|
+
continue
|
|
382
|
+
|
|
383
|
+
# Check if this is a claude-mpm managed agent
|
|
384
|
+
try:
|
|
385
|
+
content = agent_file.read_text(encoding="utf-8")
|
|
386
|
+
|
|
387
|
+
# Parse YAML frontmatter
|
|
388
|
+
if content.startswith("---"):
|
|
389
|
+
match = re.match(r"^---\n(.*?)\n---", content, re.DOTALL)
|
|
390
|
+
if match:
|
|
391
|
+
frontmatter = yaml.safe_load(match.group(1))
|
|
392
|
+
|
|
393
|
+
# Check ownership indicators
|
|
394
|
+
is_ours = False
|
|
395
|
+
if frontmatter:
|
|
396
|
+
author = frontmatter.get("author", "")
|
|
397
|
+
source = frontmatter.get("source", "")
|
|
398
|
+
agent_id = frontmatter.get("agent_id", "")
|
|
399
|
+
|
|
400
|
+
# It's ours if it has any of these markers
|
|
401
|
+
if (
|
|
402
|
+
"Claude MPM" in str(author)
|
|
403
|
+
or source == "remote"
|
|
404
|
+
or agent_id
|
|
405
|
+
):
|
|
406
|
+
is_ours = True
|
|
407
|
+
|
|
408
|
+
if is_ours:
|
|
409
|
+
# Safe to remove - it's our agent but not deployed
|
|
410
|
+
agent_file.unlink()
|
|
411
|
+
removed_count += 1
|
|
412
|
+
logger.info(f"Removed orphaned agent: {agent_file.name}")
|
|
413
|
+
|
|
414
|
+
except Exception as e:
|
|
415
|
+
logger.debug(f"Could not check agent {agent_file.name}: {e}")
|
|
416
|
+
# Don't remove if we can't verify ownership
|
|
417
|
+
|
|
418
|
+
return removed_count
|
|
419
|
+
|
|
420
|
+
|
|
297
421
|
def sync_remote_agents_on_startup():
|
|
298
422
|
"""
|
|
299
423
|
Synchronize agent templates from remote sources on startup.
|
|
@@ -309,7 +433,8 @@ def sync_remote_agents_on_startup():
|
|
|
309
433
|
Workflow:
|
|
310
434
|
1. Sync all enabled Git sources (download/cache files) - Phase 1 progress bar
|
|
311
435
|
2. Deploy agents to ~/.claude/agents/ - Phase 2 progress bar
|
|
312
|
-
3.
|
|
436
|
+
3. Cleanup orphaned agents (ours but no longer deployed) - Phase 3
|
|
437
|
+
4. Log deployment results
|
|
313
438
|
"""
|
|
314
439
|
# Check for legacy cache and warn user if found
|
|
315
440
|
check_legacy_cache()
|
|
@@ -408,14 +533,6 @@ def sync_remote_agents_on_startup():
|
|
|
408
533
|
agent_count = len(agent_files)
|
|
409
534
|
|
|
410
535
|
if agent_count > 0:
|
|
411
|
-
# Create progress bar for deployment phase
|
|
412
|
-
deploy_progress = ProgressBar(
|
|
413
|
-
total=agent_count,
|
|
414
|
-
prefix="Deploying agents",
|
|
415
|
-
show_percentage=True,
|
|
416
|
-
show_counter=True,
|
|
417
|
-
)
|
|
418
|
-
|
|
419
536
|
# Deploy agents to project-level directory where Claude Code expects them
|
|
420
537
|
deploy_target = Path.cwd() / ".claude" / "agents"
|
|
421
538
|
deployment_result = deployment_service.deploy_agents(
|
|
@@ -424,23 +541,80 @@ def sync_remote_agents_on_startup():
|
|
|
424
541
|
deployment_mode="update", # Version-aware updates
|
|
425
542
|
)
|
|
426
543
|
|
|
427
|
-
#
|
|
428
|
-
deploy_progress.update(agent_count)
|
|
429
|
-
|
|
430
|
-
# Finish deployment progress bar
|
|
544
|
+
# Get actual counts from deployment result (reflects configured agents)
|
|
431
545
|
deployed = len(deployment_result.get("deployed", []))
|
|
432
546
|
updated = len(deployment_result.get("updated", []))
|
|
433
547
|
skipped = len(deployment_result.get("skipped", []))
|
|
434
|
-
|
|
548
|
+
total_configured = deployed + updated + skipped
|
|
549
|
+
|
|
550
|
+
# FALLBACK: If deployment result doesn't track skipped agents (async path),
|
|
551
|
+
# count existing agents in target directory as "already deployed"
|
|
552
|
+
# This ensures accurate reporting when agents are already up-to-date
|
|
553
|
+
if total_configured == 0 and deploy_target.exists():
|
|
554
|
+
existing_agents = list(deploy_target.glob("*.md"))
|
|
555
|
+
# Filter out non-agent files (e.g., README.md, INSTRUCTIONS.md)
|
|
556
|
+
agent_count_in_target = len(
|
|
557
|
+
[
|
|
558
|
+
f
|
|
559
|
+
for f in existing_agents
|
|
560
|
+
if not f.name.startswith(("README", "INSTRUCTIONS"))
|
|
561
|
+
]
|
|
562
|
+
)
|
|
563
|
+
if agent_count_in_target > 0:
|
|
564
|
+
# All agents already deployed - count them as skipped
|
|
565
|
+
skipped = agent_count_in_target
|
|
566
|
+
total_configured = agent_count_in_target
|
|
435
567
|
|
|
436
|
-
#
|
|
568
|
+
# Create progress bar with actual configured agent count (not raw file count)
|
|
569
|
+
deploy_progress = ProgressBar(
|
|
570
|
+
total=total_configured if total_configured > 0 else 1,
|
|
571
|
+
prefix="Deploying agents",
|
|
572
|
+
show_percentage=True,
|
|
573
|
+
show_counter=True,
|
|
574
|
+
)
|
|
575
|
+
|
|
576
|
+
# Update progress bar to completion
|
|
577
|
+
deploy_progress.update(
|
|
578
|
+
total_configured if total_configured > 0 else 1
|
|
579
|
+
)
|
|
580
|
+
|
|
581
|
+
# Cleanup orphaned agents (ours but no longer deployed)
|
|
582
|
+
# Get list of deployed agent filenames (what should remain)
|
|
583
|
+
deployed_filenames = []
|
|
584
|
+
for agent_name in deployment_result.get("deployed", []):
|
|
585
|
+
deployed_filenames.append(f"{agent_name}.md")
|
|
586
|
+
for agent_name in deployment_result.get("updated", []):
|
|
587
|
+
deployed_filenames.append(f"{agent_name}.md")
|
|
588
|
+
for agent_name in deployment_result.get("skipped", []):
|
|
589
|
+
deployed_filenames.append(f"{agent_name}.md")
|
|
590
|
+
|
|
591
|
+
# Run cleanup and get count of removed agents
|
|
592
|
+
removed = _cleanup_orphaned_agents(
|
|
593
|
+
deploy_target, deployed_filenames
|
|
594
|
+
)
|
|
595
|
+
|
|
596
|
+
# Show total configured agents (deployed + updated + already existing)
|
|
597
|
+
# Include repo count for context and removed count if any
|
|
437
598
|
if deployed > 0 or updated > 0:
|
|
599
|
+
if removed > 0:
|
|
600
|
+
deploy_progress.finish(
|
|
601
|
+
f"Complete: {deployed} new, {updated} updated, {skipped} unchanged, "
|
|
602
|
+
f"{removed} removed ({total_configured} configured from {agent_count} in repo)"
|
|
603
|
+
)
|
|
604
|
+
else:
|
|
605
|
+
deploy_progress.finish(
|
|
606
|
+
f"Complete: {deployed} new, {updated} updated, {skipped} unchanged "
|
|
607
|
+
f"({total_configured} configured from {agent_count} in repo)"
|
|
608
|
+
)
|
|
609
|
+
elif removed > 0:
|
|
438
610
|
deploy_progress.finish(
|
|
439
|
-
f"Complete: {
|
|
611
|
+
f"Complete: {total_configured} agents ready - all unchanged, "
|
|
612
|
+
f"{removed} removed ({agent_count} available in repo)"
|
|
440
613
|
)
|
|
441
614
|
else:
|
|
442
615
|
deploy_progress.finish(
|
|
443
|
-
f"Complete: {
|
|
616
|
+
f"Complete: {total_configured} agents ready - all unchanged "
|
|
617
|
+
f"({agent_count} available in repo)"
|
|
444
618
|
)
|
|
445
619
|
|
|
446
620
|
# Display deployment errors to user (not just logs)
|
|
@@ -530,6 +704,8 @@ def sync_remote_skills_on_startup():
|
|
|
530
704
|
|
|
531
705
|
# Discover total file count across all sources
|
|
532
706
|
total_file_count = 0
|
|
707
|
+
total_skill_dirs = 0 # Count actual skill directories (folders with SKILL.md)
|
|
708
|
+
|
|
533
709
|
for source in enabled_sources:
|
|
534
710
|
try:
|
|
535
711
|
# Parse GitHub URL
|
|
@@ -553,15 +729,26 @@ def sync_remote_skills_on_startup():
|
|
|
553
729
|
]
|
|
554
730
|
total_file_count += len(relevant_files)
|
|
555
731
|
|
|
732
|
+
# Count skill directories (unique directories containing SKILL.md)
|
|
733
|
+
skill_dirs = set()
|
|
734
|
+
for f in all_files:
|
|
735
|
+
if f.endswith("/SKILL.md"):
|
|
736
|
+
# Extract directory path
|
|
737
|
+
skill_dir = "/".join(f.split("/")[:-1])
|
|
738
|
+
skill_dirs.add(skill_dir)
|
|
739
|
+
total_skill_dirs += len(skill_dirs)
|
|
740
|
+
|
|
556
741
|
except Exception as e:
|
|
557
742
|
logger.debug(f"Failed to discover files for {source.id}: {e}")
|
|
558
743
|
# Use estimate if discovery fails
|
|
559
744
|
total_file_count += 150
|
|
745
|
+
total_skill_dirs += 50 # Estimate ~50 skills
|
|
560
746
|
|
|
561
747
|
# Create progress bar for sync phase with actual file count
|
|
748
|
+
# Note: We sync files (md, json, etc.), but will deploy skill directories
|
|
562
749
|
sync_progress = ProgressBar(
|
|
563
750
|
total=total_file_count if total_file_count > 0 else 1,
|
|
564
|
-
prefix="Syncing
|
|
751
|
+
prefix="Syncing skill files",
|
|
565
752
|
show_percentage=True,
|
|
566
753
|
show_counter=True,
|
|
567
754
|
)
|
|
@@ -578,51 +765,96 @@ def sync_remote_skills_on_startup():
|
|
|
578
765
|
|
|
579
766
|
if cached > 0:
|
|
580
767
|
sync_progress.finish(
|
|
581
|
-
f"Complete: {downloaded} downloaded, {cached} cached ({total_files}
|
|
768
|
+
f"Complete: {downloaded} downloaded, {cached} cached ({total_files} files, {total_skill_dirs} skills)"
|
|
582
769
|
)
|
|
583
770
|
else:
|
|
584
771
|
# All new downloads (first sync)
|
|
585
|
-
sync_progress.finish(
|
|
772
|
+
sync_progress.finish(
|
|
773
|
+
f"Complete: {downloaded} files downloaded ({total_skill_dirs} skills)"
|
|
774
|
+
)
|
|
586
775
|
|
|
587
776
|
# Phase 2: Deploy skills to ~/.claude/skills/
|
|
588
777
|
# This flattens nested Git structure (e.g., collaboration/parallel-agents/SKILL.md)
|
|
589
778
|
# into flat deployment (e.g., collaboration-dispatching-parallel-agents/SKILL.md)
|
|
590
779
|
if results["synced_count"] > 0:
|
|
591
|
-
# Get
|
|
780
|
+
# Get required skills from deployed agents (selective deployment)
|
|
781
|
+
from ..services.skills.selective_skill_deployer import (
|
|
782
|
+
get_required_skills_from_agents,
|
|
783
|
+
)
|
|
784
|
+
|
|
785
|
+
agents_dir = Path.cwd() / ".claude" / "agents"
|
|
786
|
+
required_skills = get_required_skills_from_agents(agents_dir)
|
|
787
|
+
|
|
788
|
+
# Get all skills to determine counts
|
|
592
789
|
all_skills = manager.get_all_skills()
|
|
593
|
-
|
|
790
|
+
total_skill_count = len(all_skills)
|
|
594
791
|
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
)
|
|
792
|
+
# Determine skill count based on whether we have agent requirements
|
|
793
|
+
if required_skills:
|
|
794
|
+
# Selective deployment: only skills required by deployed agents
|
|
795
|
+
skill_count = len(required_skills)
|
|
796
|
+
else:
|
|
797
|
+
# No agent requirements found - deploy all skills
|
|
798
|
+
skill_count = total_skill_count
|
|
603
799
|
|
|
604
|
-
|
|
800
|
+
if skill_count > 0:
|
|
801
|
+
# Deploy skills with selective filter (if agent requirements exist)
|
|
605
802
|
# Deploy to project directory (like agents), not user directory
|
|
606
803
|
deployment_result = manager.deploy_skills(
|
|
607
804
|
target_dir=Path.cwd() / ".claude" / "skills",
|
|
608
805
|
force=False,
|
|
609
|
-
|
|
806
|
+
skill_filter=required_skills if required_skills else None,
|
|
610
807
|
)
|
|
611
808
|
|
|
612
|
-
#
|
|
809
|
+
# Get actual counts from deployment result
|
|
613
810
|
deployed = deployment_result.get("deployed_count", 0)
|
|
614
811
|
skipped = deployment_result.get("skipped_count", 0)
|
|
812
|
+
filtered = deployment_result.get("filtered_count", 0)
|
|
615
813
|
total_available = deployed + skipped
|
|
616
814
|
|
|
815
|
+
# Only show progress bar if there are skills to deploy
|
|
816
|
+
if total_available > 0:
|
|
817
|
+
deploy_progress = ProgressBar(
|
|
818
|
+
total=total_available,
|
|
819
|
+
prefix="Deploying skill directories",
|
|
820
|
+
show_percentage=True,
|
|
821
|
+
show_counter=True,
|
|
822
|
+
)
|
|
823
|
+
# Update progress bar to completion
|
|
824
|
+
deploy_progress.update(total_available)
|
|
825
|
+
else:
|
|
826
|
+
# No skills to deploy - create dummy progress for message only
|
|
827
|
+
deploy_progress = ProgressBar(
|
|
828
|
+
total=1,
|
|
829
|
+
prefix="Deploying skill directories",
|
|
830
|
+
show_percentage=False,
|
|
831
|
+
show_counter=False,
|
|
832
|
+
)
|
|
833
|
+
deploy_progress.update(1)
|
|
834
|
+
|
|
617
835
|
# Show total available skills (deployed + already existing)
|
|
618
|
-
#
|
|
836
|
+
# Include filtered count if selective deployment was used
|
|
837
|
+
# Note: total_skill_count is from the repo, total_available is what's deployed/needed
|
|
619
838
|
if deployed > 0:
|
|
839
|
+
if filtered > 0:
|
|
840
|
+
deploy_progress.finish(
|
|
841
|
+
f"Complete: {deployed} new, {skipped} unchanged "
|
|
842
|
+
f"({total_available} required by agents, {filtered} available in repo)"
|
|
843
|
+
)
|
|
844
|
+
else:
|
|
845
|
+
deploy_progress.finish(
|
|
846
|
+
f"Complete: {deployed} new, {skipped} unchanged "
|
|
847
|
+
f"({total_available} skills deployed from {total_skill_count} in repo)"
|
|
848
|
+
)
|
|
849
|
+
elif filtered > 0:
|
|
850
|
+
# Skills filtered means agents require fewer skills than available
|
|
620
851
|
deploy_progress.finish(
|
|
621
|
-
f"
|
|
852
|
+
f"Agents require no skills ({total_skill_count} available in repo)"
|
|
622
853
|
)
|
|
623
854
|
else:
|
|
624
855
|
deploy_progress.finish(
|
|
625
|
-
f"Complete: {total_available} skills
|
|
856
|
+
f"Complete: {total_available} skills deployed for agents "
|
|
857
|
+
f"({total_skill_count} available in repo)"
|
|
626
858
|
)
|
|
627
859
|
|
|
628
860
|
# Log deployment errors if any
|
|
@@ -663,6 +895,11 @@ def run_background_services():
|
|
|
663
895
|
file creation in project .claude/ directories.
|
|
664
896
|
See: SystemInstructionsDeployer and agent_deployment.py line 504-509
|
|
665
897
|
"""
|
|
898
|
+
# Sync hooks early to ensure up-to-date configuration
|
|
899
|
+
# RATIONALE: Hooks should be synced before other services to fix stale configs
|
|
900
|
+
# This is fast (<100ms) and non-blocking, so it doesn't delay startup
|
|
901
|
+
sync_hooks_on_startup() # Shows "Syncing Claude Code hooks... ✓"
|
|
902
|
+
|
|
666
903
|
initialize_project_registry()
|
|
667
904
|
check_mcp_auto_configuration()
|
|
668
905
|
verify_mcp_gateway_startup()
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
---
|
|
2
|
+
namespace: mpm/config
|
|
3
|
+
command: config
|
|
4
|
+
aliases: [mpm-config]
|
|
5
|
+
migration_target: /mpm/config
|
|
6
|
+
category: config
|
|
7
|
+
deprecated_aliases: [mpm-config-view]
|
|
8
|
+
description: Unified configuration management with auto-detection and manual viewing
|
|
9
|
+
---
|
|
10
|
+
# Unified configuration management
|
|
11
|
+
|
|
12
|
+
Manage Claude MPM configuration with auto-detection, manual viewing, validation, and status checks.
|
|
13
|
+
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
/mpm-config [subcommand] [options]
|
|
18
|
+
/mpm-config # No args = auto (detect + recommend + preview)
|
|
19
|
+
/mpm-config view # Show current config
|
|
20
|
+
/mpm-config auto # Auto-configure: detect → recommend → deploy (with confirmation)
|
|
21
|
+
/mpm-config auto --yes # Auto-deploy without confirmation
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Description
|
|
25
|
+
|
|
26
|
+
This unified command provides comprehensive configuration management:
|
|
27
|
+
|
|
28
|
+
1. **Auto-configuration** (default): Detect toolchain and recommend agents/skills
|
|
29
|
+
2. **Manual viewing**: Display current configuration settings
|
|
30
|
+
3. **Validation**: Ensure configuration correctness
|
|
31
|
+
4. **Status checks**: Show system health
|
|
32
|
+
|
|
33
|
+
## Subcommands
|
|
34
|
+
|
|
35
|
+
### Auto-Configure (Default)
|
|
36
|
+
|
|
37
|
+
Automatically detect project toolchain and configure appropriate agents and skills.
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
/mpm-config # Preview recommendations (default)
|
|
41
|
+
/mpm-config auto # Same as no args - detect and preview
|
|
42
|
+
/mpm-config auto --yes # Auto-deploy without confirmation
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**What it does:**
|
|
46
|
+
1. Scans project to detect programming languages, frameworks, and tools
|
|
47
|
+
2. Recommends agents for your stack (e.g., fastapi-engineer, react-engineer)
|
|
48
|
+
3. Recommends skills based on agent types
|
|
49
|
+
4. Shows preview of what will be configured
|
|
50
|
+
5. Deploys with confirmation (unless `--yes` is used)
|
|
51
|
+
|
|
52
|
+
**Options:**
|
|
53
|
+
- `--yes`: Automatically deploy without prompting
|
|
54
|
+
- `--preview`: Show recommendations without deploying (default when no args)
|
|
55
|
+
- `--min-confidence FLOAT`: Minimum confidence threshold (default: 0.8)
|
|
56
|
+
- `--agents-only`: Only configure agents, skip skills
|
|
57
|
+
- `--skills-only`: Only configure skills, skip agents
|
|
58
|
+
- `--json`: Output results in JSON format
|
|
59
|
+
|
|
60
|
+
**Examples:**
|
|
61
|
+
```
|
|
62
|
+
/mpm-config # Preview auto-configuration
|
|
63
|
+
/mpm-config auto # Same as above
|
|
64
|
+
/mpm-config auto --yes # Deploy automatically
|
|
65
|
+
/mpm-config auto --min-confidence 0.7 # Lower threshold
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**Detection Capabilities:**
|
|
69
|
+
|
|
70
|
+
**Languages:**
|
|
71
|
+
- Python (CPython, PyPy)
|
|
72
|
+
- JavaScript/TypeScript (Node.js, Deno, Bun)
|
|
73
|
+
- Rust, Go, Java
|
|
74
|
+
|
|
75
|
+
**Python Frameworks:**
|
|
76
|
+
- FastAPI, Flask, Django, Starlette, Pyramid
|
|
77
|
+
|
|
78
|
+
**JavaScript/TypeScript Frameworks:**
|
|
79
|
+
- Next.js, React, Vue, Svelte, Angular
|
|
80
|
+
- Express, Nest.js, Fastify
|
|
81
|
+
|
|
82
|
+
**Testing Tools:**
|
|
83
|
+
- pytest, unittest (Python)
|
|
84
|
+
- Jest, Vitest (JavaScript)
|
|
85
|
+
- Playwright, Cypress (Browser)
|
|
86
|
+
|
|
87
|
+
**Example Output:**
|
|
88
|
+
```
|
|
89
|
+
📊 Detected Toolchain:
|
|
90
|
+
✓ Python 3.11 (100% confidence)
|
|
91
|
+
✓ FastAPI 0.104.0 (95% confidence)
|
|
92
|
+
✓ pytest 7.4.0 (90% confidence)
|
|
93
|
+
|
|
94
|
+
🤖 Recommended Agents:
|
|
95
|
+
✓ fastapi-engineer (95% confidence)
|
|
96
|
+
Reason: FastAPI framework detected
|
|
97
|
+
✓ python-engineer (90% confidence)
|
|
98
|
+
Reason: Python project support
|
|
99
|
+
✓ api-qa (85% confidence)
|
|
100
|
+
Reason: API testing and validation
|
|
101
|
+
|
|
102
|
+
🎯 Recommended Skills:
|
|
103
|
+
✓ toolchains-python-frameworks-fastapi
|
|
104
|
+
✓ toolchains-python-testing-pytest
|
|
105
|
+
✓ toolchains-universal-api-testing
|
|
106
|
+
|
|
107
|
+
Deploy 3 agent(s) and 3 skill(s)? (y/n/s for select):
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### View Configuration
|
|
111
|
+
|
|
112
|
+
Display current configuration settings.
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
/mpm-config view [--section SECTION] [--format FORMAT] [--show-defaults]
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Options:**
|
|
119
|
+
- `--section SECTION`: Specific configuration section to view
|
|
120
|
+
- `--format FORMAT`: Output format (yaml, json, table)
|
|
121
|
+
- `--show-defaults`: Include default values in output
|
|
122
|
+
|
|
123
|
+
**Examples:**
|
|
124
|
+
```
|
|
125
|
+
/mpm-config view
|
|
126
|
+
/mpm-config view --section agents --format json
|
|
127
|
+
/mpm-config view --show-defaults
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Validate Configuration
|
|
131
|
+
|
|
132
|
+
Validate configuration files for correctness and completeness.
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
/mpm-config validate [--config-file PATH] [--strict] [--fix]
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**Options:**
|
|
139
|
+
- `--config-file PATH`: Validate specific config file (default: all)
|
|
140
|
+
- `--strict`: Use strict validation rules
|
|
141
|
+
- `--fix`: Attempt to fix validation errors automatically
|
|
142
|
+
|
|
143
|
+
**Example:**
|
|
144
|
+
```
|
|
145
|
+
/mpm-config validate --strict
|
|
146
|
+
/mpm-config validate --config-file .claude/config.yaml --fix
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**Expected Output:**
|
|
150
|
+
```
|
|
151
|
+
Validating configuration files...
|
|
152
|
+
|
|
153
|
+
✓ .claude/config.yaml: Valid
|
|
154
|
+
✓ .claude/agents/config.yaml: Valid
|
|
155
|
+
✓ Configuration schema: Valid
|
|
156
|
+
|
|
157
|
+
Configuration is valid and ready to use.
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Configuration Status
|
|
161
|
+
|
|
162
|
+
Show configuration health and status.
|
|
163
|
+
|
|
164
|
+
```
|
|
165
|
+
/mpm-config status [--verbose]
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
**Options:**
|
|
169
|
+
- `--verbose`: Show detailed status information
|
|
170
|
+
|
|
171
|
+
**Example:**
|
|
172
|
+
```
|
|
173
|
+
/mpm-config status --verbose
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
**Expected Output:**
|
|
177
|
+
```
|
|
178
|
+
Configuration Status
|
|
179
|
+
====================
|
|
180
|
+
|
|
181
|
+
Files Found: 2
|
|
182
|
+
✓ .claude/config.yaml
|
|
183
|
+
✓ .claude/agents/config.yaml
|
|
184
|
+
|
|
185
|
+
Validation: Passed
|
|
186
|
+
Schema Version: 4.5
|
|
187
|
+
Last Modified: 2025-01-15 14:30:22
|
|
188
|
+
|
|
189
|
+
Active Settings:
|
|
190
|
+
- WebSocket Port: 8765
|
|
191
|
+
- Agent Deploy Mode: project
|
|
192
|
+
- Logging Level: INFO
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## Implementation
|
|
196
|
+
|
|
197
|
+
This command executes:
|
|
198
|
+
```bash
|
|
199
|
+
claude-mpm config [subcommand] [options]
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
The slash command passes through to the actual CLI configuration management system.
|
|
203
|
+
|
|
204
|
+
## Configuration Categories
|
|
205
|
+
|
|
206
|
+
Configuration is organized into sections:
|
|
207
|
+
|
|
208
|
+
- **agents**: Agent deployment and management settings
|
|
209
|
+
- **memory**: Memory system configuration
|
|
210
|
+
- **websocket**: WebSocket server settings (port, host)
|
|
211
|
+
- **hooks**: Hook service configuration
|
|
212
|
+
- **logging**: Logging levels and output
|
|
213
|
+
- **tickets**: Ticket tracking settings
|
|
214
|
+
- **monitor**: Dashboard and monitoring settings
|
|
215
|
+
|
|
216
|
+
## Workflow Examples
|
|
217
|
+
|
|
218
|
+
### Quick Start (New Project)
|
|
219
|
+
```
|
|
220
|
+
/mpm-config # Preview recommendations
|
|
221
|
+
# Review output, then:
|
|
222
|
+
/mpm-config auto --yes # Deploy recommended agents and skills
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### Check Current State
|
|
226
|
+
```
|
|
227
|
+
/mpm-config view # See current settings
|
|
228
|
+
/mpm-config status # Verify health
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Validate After Manual Edits
|
|
232
|
+
```
|
|
233
|
+
/mpm-config validate --strict
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Reconfigure After Stack Changes
|
|
237
|
+
```
|
|
238
|
+
/mpm-config auto --force # Re-run auto-detection
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
## Default Configuration Fallback
|
|
242
|
+
|
|
243
|
+
When auto-configuration cannot detect your project's toolchain, it falls back to sensible defaults:
|
|
244
|
+
|
|
245
|
+
**Default Agents** (moderate confidence 0.7):
|
|
246
|
+
- engineer (general-purpose)
|
|
247
|
+
- research (code exploration)
|
|
248
|
+
- qa (testing)
|
|
249
|
+
- ops (infrastructure)
|
|
250
|
+
- documentation (technical writing)
|
|
251
|
+
|
|
252
|
+
**Disable defaults:**
|
|
253
|
+
Edit `.claude-mpm/config/agent_capabilities.yaml`:
|
|
254
|
+
```yaml
|
|
255
|
+
default_configuration:
|
|
256
|
+
enabled: false # Disable default fallback
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## Related Commands
|
|
260
|
+
|
|
261
|
+
- `/mpm-status`: Show overall system status
|
|
262
|
+
- `/mpm-doctor`: Diagnose configuration issues
|
|
263
|
+
- `/mpm-init`: Initialize project configuration
|
|
264
|
+
- `/mpm-agents`: Manually manage agents
|
|
265
|
+
- `/mpm-agents-detect`: View detected toolchain only
|
|
266
|
+
- `/mpm-agents-recommend`: Show recommendations only
|