claude-mpm 5.4.3__py3-none-any.whl → 5.4.21__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/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +1 -1
- claude_mpm/agents/PM_INSTRUCTIONS.md +166 -21
- claude_mpm/agents/agent_loader.py +3 -27
- claude_mpm/cli/__main__.py +4 -0
- claude_mpm/cli/chrome_devtools_installer.py +175 -0
- claude_mpm/cli/commands/agents.py +0 -31
- 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 +214 -189
- claude_mpm/cli/executor.py +3 -3
- claude_mpm/cli/parsers/agents_parser.py +0 -9
- claude_mpm/cli/parsers/auto_configure_parser.py +0 -138
- claude_mpm/cli/parsers/config_parser.py +153 -83
- claude_mpm/cli/parsers/skills_parser.py +3 -2
- claude_mpm/cli/startup.py +490 -41
- claude_mpm/commands/mpm-config.md +265 -0
- claude_mpm/commands/mpm-help.md +14 -95
- claude_mpm/commands/mpm-organize.md +350 -153
- 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 +176 -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/scripts/start_activity_logging.py +0 -0
- 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 +81 -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 +704 -0
- claude_mpm/services/skills/skill_to_agent_mapper.py +406 -0
- claude_mpm/services/skills_deployer.py +126 -9
- {claude_mpm-5.4.3.dist-info → claude_mpm-5.4.21.dist-info}/METADATA +47 -8
- {claude_mpm-5.4.3.dist-info → claude_mpm-5.4.21.dist-info}/RECORD +58 -82
- {claude_mpm-5.4.3.dist-info → claude_mpm-5.4.21.dist-info}/entry_points.txt +0 -3
- claude_mpm-5.4.21.dist-info/licenses/LICENSE +94 -0
- claude_mpm-5.4.21.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/commands/agents_detect.py +0 -380
- claude_mpm/cli/commands/agents_recommend.py +0 -309
- claude_mpm/cli/ticket_cli.py +0 -35
- 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/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.21.dist-info}/WHEEL +0 -0
- {claude_mpm-5.4.3.dist-info → claude_mpm-5.4.21.dist-info}/top_level.txt +0 -0
|
@@ -537,7 +537,7 @@ class SkillsManagementCommand(BaseCommand):
|
|
|
537
537
|
toolchain = getattr(args, "toolchain", None)
|
|
538
538
|
categories = getattr(args, "categories", None)
|
|
539
539
|
force = getattr(args, "force", False)
|
|
540
|
-
all_skills = getattr(args, "
|
|
540
|
+
all_skills = getattr(args, "all_skills", False)
|
|
541
541
|
|
|
542
542
|
if collection:
|
|
543
543
|
console.print(
|
|
@@ -554,17 +554,36 @@ class SkillsManagementCommand(BaseCommand):
|
|
|
554
554
|
"[yellow]No toolchain specified. Use --toolchain to filter by language,[/yellow]"
|
|
555
555
|
)
|
|
556
556
|
console.print(
|
|
557
|
-
"[yellow]or --all to deploy all available skills.[/yellow]\n"
|
|
557
|
+
"[yellow]or --all-skills to deploy all available skills (not just agent-referenced).[/yellow]\n"
|
|
558
558
|
)
|
|
559
559
|
|
|
560
|
+
# Selective deployment is enabled by default (deploy only agent-referenced skills)
|
|
561
|
+
# Use --all-skills to disable selective mode
|
|
560
562
|
result = self.skills_deployer.deploy_skills(
|
|
561
563
|
collection=collection,
|
|
562
564
|
toolchain=toolchain,
|
|
563
565
|
categories=categories,
|
|
564
566
|
force=force,
|
|
567
|
+
selective=not all_skills, # Disable selective mode if --all-skills is set
|
|
565
568
|
)
|
|
566
569
|
|
|
567
570
|
# Display results
|
|
571
|
+
# Show selective mode summary
|
|
572
|
+
if result.get("selective_mode"):
|
|
573
|
+
total_available = result.get("total_available", 0)
|
|
574
|
+
deployed_count = result["deployed_count"]
|
|
575
|
+
console.print(
|
|
576
|
+
f"[cyan]📌 Selective deployment: {deployed_count} agent-referenced skills "
|
|
577
|
+
f"(out of {total_available} available)[/cyan]"
|
|
578
|
+
)
|
|
579
|
+
console.print(
|
|
580
|
+
"[dim]Use --all-skills to deploy all available skills[/dim]\n"
|
|
581
|
+
)
|
|
582
|
+
else:
|
|
583
|
+
console.print(
|
|
584
|
+
"[cyan]📦 Deploying all available skills (selective mode disabled)[/cyan]\n"
|
|
585
|
+
)
|
|
586
|
+
|
|
568
587
|
if result["deployed_count"] > 0:
|
|
569
588
|
console.print(
|
|
570
589
|
f"[green]✓ Deployed {result['deployed_count']} skill(s):[/green]"
|
|
@@ -953,23 +972,37 @@ class SkillsManagementCommand(BaseCommand):
|
|
|
953
972
|
console.print(f"[red]Unexpected error: {e}[/red]")
|
|
954
973
|
|
|
955
974
|
def _configure_skills(self, args) -> CommandResult:
|
|
956
|
-
"""Interactive skills configuration
|
|
975
|
+
"""Interactive skills configuration using configuration.yaml.
|
|
957
976
|
|
|
958
977
|
Provides checkbox-based selection interface matching agents configure UX:
|
|
959
|
-
-
|
|
960
|
-
-
|
|
961
|
-
-
|
|
962
|
-
-
|
|
963
|
-
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
978
|
+
- Shows current mode (user_defined vs agent_referenced)
|
|
979
|
+
- If agent mode: shows agent-scanned skills
|
|
980
|
+
- Allows switching to user_defined mode and selecting skills
|
|
981
|
+
- Can reset to agent mode (clears user_defined)
|
|
982
|
+
- Saves selections to configuration.yaml
|
|
983
|
+
|
|
984
|
+
Configuration structure:
|
|
985
|
+
```yaml
|
|
986
|
+
skills:
|
|
987
|
+
agent_referenced: # Auto-populated from agent scan (read-only)
|
|
988
|
+
- systematic-debugging
|
|
989
|
+
- typescript-core
|
|
990
|
+
user_defined: # User override - if set, ONLY these are deployed
|
|
991
|
+
[] # Empty = use agent_referenced
|
|
992
|
+
```
|
|
967
993
|
"""
|
|
968
994
|
try:
|
|
995
|
+
from pathlib import Path
|
|
996
|
+
|
|
969
997
|
import questionary
|
|
998
|
+
import yaml
|
|
970
999
|
from questionary import Choice, Style
|
|
971
1000
|
from rich.prompt import Prompt
|
|
972
1001
|
|
|
1002
|
+
from ...services.skills.selective_skill_deployer import (
|
|
1003
|
+
get_skills_to_deploy,
|
|
1004
|
+
)
|
|
1005
|
+
|
|
973
1006
|
# Questionary style (matching agents configure)
|
|
974
1007
|
QUESTIONARY_STYLE = Style(
|
|
975
1008
|
[
|
|
@@ -994,203 +1027,197 @@ class SkillsManagementCommand(BaseCommand):
|
|
|
994
1027
|
]
|
|
995
1028
|
)
|
|
996
1029
|
|
|
997
|
-
console.print("\n[bold cyan]
|
|
998
|
-
console.print(
|
|
999
|
-
"[dim]Select skills to install/uninstall using checkboxes[/dim]"
|
|
1000
|
-
)
|
|
1001
|
-
console.print("[dim]● = Installed, ○ = Available[/dim]\n")
|
|
1030
|
+
console.print("\n[bold cyan]Skills Configuration Manager[/bold cyan]\n")
|
|
1002
1031
|
|
|
1003
|
-
#
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
skill["name"] for skill in deployed_result.get("skills", [])
|
|
1007
|
-
}
|
|
1032
|
+
# Load current configuration
|
|
1033
|
+
project_config_path = Path.cwd() / ".claude-mpm" / "configuration.yaml"
|
|
1034
|
+
skills_to_deploy, current_mode = get_skills_to_deploy(project_config_path)
|
|
1008
1035
|
|
|
1009
|
-
#
|
|
1010
|
-
console.print("[
|
|
1011
|
-
|
|
1036
|
+
# Display current mode and skill count
|
|
1037
|
+
console.print(f"[bold]Current Mode:[/bold] [cyan]{current_mode}[/cyan]")
|
|
1038
|
+
console.print(
|
|
1039
|
+
f"[bold]Active Skills:[/bold] {len(skills_to_deploy)} skills\n"
|
|
1040
|
+
)
|
|
1012
1041
|
|
|
1013
|
-
if
|
|
1014
|
-
console.print(
|
|
1015
|
-
|
|
1016
|
-
|
|
1042
|
+
if current_mode == "agent_referenced":
|
|
1043
|
+
console.print(
|
|
1044
|
+
"[dim]Agent mode: Skills are auto-detected from deployed agents[/dim]"
|
|
1045
|
+
)
|
|
1046
|
+
console.print(
|
|
1047
|
+
"[dim]Switch to user mode to manually select skills[/dim]\n"
|
|
1017
1048
|
)
|
|
1049
|
+
else:
|
|
1050
|
+
console.print(
|
|
1051
|
+
"[dim]User mode: You've manually selected which skills to deploy[/dim]"
|
|
1052
|
+
)
|
|
1053
|
+
console.print("[dim]Reset to agent mode to use auto-detection[/dim]\n")
|
|
1054
|
+
|
|
1055
|
+
# Offer mode switching
|
|
1056
|
+
action_choices = [
|
|
1057
|
+
Choice("View current skills", value="view"),
|
|
1058
|
+
Choice("Switch to user mode (manual selection)", value="switch_user"),
|
|
1059
|
+
Choice("Reset to agent mode (auto-detection)", value="reset_agent"),
|
|
1060
|
+
Choice("Cancel", value="cancel"),
|
|
1061
|
+
]
|
|
1062
|
+
|
|
1063
|
+
action = questionary.select(
|
|
1064
|
+
"What would you like to do?",
|
|
1065
|
+
choices=action_choices,
|
|
1066
|
+
style=QUESTIONARY_STYLE,
|
|
1067
|
+
).ask()
|
|
1068
|
+
|
|
1069
|
+
if action == "cancel" or action is None:
|
|
1070
|
+
console.print("[yellow]Configuration cancelled[/yellow]")
|
|
1071
|
+
return CommandResult(success=True, exit_code=0)
|
|
1018
1072
|
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
for skill in
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
}
|
|
1028
|
-
all_skills.append(skill_info)
|
|
1029
|
-
|
|
1030
|
-
# Sort by deployed status (deployed first), then by name
|
|
1031
|
-
all_skills.sort(key=lambda s: (not s["is_deployed"], s["name"]))
|
|
1032
|
-
|
|
1033
|
-
# Build checkbox choices with pre-selection
|
|
1034
|
-
# Loop to allow adjusting selection
|
|
1035
|
-
while True:
|
|
1036
|
-
skill_choices = []
|
|
1037
|
-
skill_map = {} # For lookup after selection
|
|
1038
|
-
|
|
1039
|
-
for skill in all_skills:
|
|
1040
|
-
skill_name = skill["name"]
|
|
1041
|
-
category = skill["category"]
|
|
1042
|
-
is_deployed = skill["is_deployed"]
|
|
1043
|
-
|
|
1044
|
-
# Simple format: "skill-name (category)"
|
|
1045
|
-
# Checkbox state (checked/unchecked) indicates installed status
|
|
1046
|
-
choice_text = f"{skill_name} ({category})"
|
|
1047
|
-
|
|
1048
|
-
# Pre-select if deployed
|
|
1049
|
-
choice = Choice(
|
|
1050
|
-
title=choice_text, value=skill_name, checked=is_deployed
|
|
1051
|
-
)
|
|
1073
|
+
if action == "view":
|
|
1074
|
+
# Display current skills
|
|
1075
|
+
console.print("\n[bold]Current Skills:[/bold]\n")
|
|
1076
|
+
for skill in sorted(skills_to_deploy):
|
|
1077
|
+
console.print(f" • {skill}")
|
|
1078
|
+
console.print()
|
|
1079
|
+
Prompt.ask("\nPress Enter to continue")
|
|
1080
|
+
return CommandResult(success=True, exit_code=0)
|
|
1052
1081
|
|
|
1053
|
-
|
|
1054
|
-
|
|
1082
|
+
if action == "reset_agent":
|
|
1083
|
+
# Reset to agent mode by clearing user_defined
|
|
1084
|
+
with open(project_config_path, encoding="utf-8") as f:
|
|
1085
|
+
config = yaml.safe_load(f) or {}
|
|
1055
1086
|
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
"Select skills (Space to toggle, Enter to confirm):",
|
|
1059
|
-
choices=skill_choices,
|
|
1060
|
-
style=QUESTIONARY_STYLE,
|
|
1061
|
-
).ask()
|
|
1087
|
+
if "skills" not in config:
|
|
1088
|
+
config["skills"] = {}
|
|
1062
1089
|
|
|
1063
|
-
|
|
1064
|
-
# User cancelled (Ctrl+C)
|
|
1065
|
-
console.print("[yellow]Skills configuration cancelled[/yellow]")
|
|
1066
|
-
return CommandResult(success=True, exit_code=0)
|
|
1090
|
+
config["skills"]["user_defined"] = []
|
|
1067
1091
|
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
to_remove = []
|
|
1092
|
+
with open(project_config_path, "w", encoding="utf-8") as f:
|
|
1093
|
+
yaml.dump(config, f, default_flow_style=False, sort_keys=False)
|
|
1071
1094
|
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1095
|
+
console.print(
|
|
1096
|
+
"\n[green]✓ Reset to agent mode - skills will be auto-detected from agents[/green]\n"
|
|
1097
|
+
)
|
|
1098
|
+
Prompt.ask("\nPress Enter to continue")
|
|
1099
|
+
return CommandResult(success=True, exit_code=0)
|
|
1076
1100
|
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1101
|
+
# Switch to user mode - manual skill selection
|
|
1102
|
+
if action == "switch_user":
|
|
1103
|
+
console.print(
|
|
1104
|
+
"\n[bold cyan]Switching to User Mode - Manual Skill Selection[/bold cyan]\n"
|
|
1105
|
+
)
|
|
1106
|
+
console.print("[dim]Fetching available skills from GitHub...[/dim]\n")
|
|
1081
1107
|
|
|
1082
|
-
#
|
|
1083
|
-
|
|
1084
|
-
if to_install:
|
|
1085
|
-
console.print(
|
|
1086
|
-
f"\n[green]✓ Install ({len(to_install)} skills):[/green]"
|
|
1087
|
-
)
|
|
1088
|
-
for skill in to_install:
|
|
1089
|
-
console.print(f" • {skill}")
|
|
1108
|
+
# Get available skills
|
|
1109
|
+
available_result = self.skills_deployer.list_available_skills()
|
|
1090
1110
|
|
|
1091
|
-
if
|
|
1092
|
-
console.print(
|
|
1093
|
-
|
|
1111
|
+
if available_result.get("error"):
|
|
1112
|
+
console.print(f"[red]Error: {available_result['error']}[/red]")
|
|
1113
|
+
return CommandResult(
|
|
1114
|
+
success=False, message=available_result["error"], exit_code=1
|
|
1094
1115
|
)
|
|
1095
|
-
for skill in to_remove:
|
|
1096
|
-
console.print(f" • {skill}")
|
|
1097
1116
|
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1117
|
+
# Flatten skills by category
|
|
1118
|
+
all_skills = []
|
|
1119
|
+
for category, skills in available_result.get("by_category", {}).items():
|
|
1120
|
+
for skill in skills:
|
|
1121
|
+
skill_name = skill.get("name", "unknown")
|
|
1122
|
+
is_currently_selected = skill_name in skills_to_deploy
|
|
1123
|
+
skill_info = {
|
|
1124
|
+
"name": skill_name,
|
|
1125
|
+
"category": category,
|
|
1126
|
+
"is_selected": is_currently_selected,
|
|
1127
|
+
}
|
|
1128
|
+
all_skills.append(skill_info)
|
|
1129
|
+
|
|
1130
|
+
# Sort by selection status (selected first), then by name
|
|
1131
|
+
all_skills.sort(key=lambda s: (not s["is_selected"], s["name"]))
|
|
1132
|
+
|
|
1133
|
+
# Build checkbox choices
|
|
1134
|
+
while True:
|
|
1135
|
+
skill_choices = []
|
|
1136
|
+
|
|
1137
|
+
for skill in all_skills:
|
|
1138
|
+
skill_name = skill["name"]
|
|
1139
|
+
category = skill["category"]
|
|
1140
|
+
is_selected = skill["is_selected"]
|
|
1141
|
+
|
|
1142
|
+
# Format: "skill-name (category)"
|
|
1143
|
+
choice_text = f"{skill_name} ({category})"
|
|
1144
|
+
|
|
1145
|
+
# Pre-select if currently in skills_to_deploy
|
|
1146
|
+
choice = Choice(
|
|
1147
|
+
title=choice_text, value=skill_name, checked=is_selected
|
|
1148
|
+
)
|
|
1102
1149
|
|
|
1103
|
-
|
|
1150
|
+
skill_choices.append(choice)
|
|
1151
|
+
|
|
1152
|
+
# Display checkbox selection
|
|
1153
|
+
selected_skills = questionary.checkbox(
|
|
1154
|
+
"Select skills (Space to toggle, Enter to confirm):",
|
|
1155
|
+
choices=skill_choices,
|
|
1156
|
+
style=QUESTIONARY_STYLE,
|
|
1157
|
+
).ask()
|
|
1158
|
+
|
|
1159
|
+
if selected_skills is None:
|
|
1160
|
+
# User cancelled (Ctrl+C)
|
|
1161
|
+
console.print("[yellow]Skills configuration cancelled[/yellow]")
|
|
1162
|
+
return CommandResult(success=True, exit_code=0)
|
|
1163
|
+
|
|
1164
|
+
# Show summary
|
|
1165
|
+
console.print("\n[bold]Selected Skills:[/bold]")
|
|
1166
|
+
console.print(f" {len(selected_skills)} skills selected\n")
|
|
1167
|
+
|
|
1168
|
+
if selected_skills:
|
|
1169
|
+
for skill in sorted(selected_skills):
|
|
1170
|
+
console.print(f" • {skill}")
|
|
1171
|
+
console.print()
|
|
1172
|
+
|
|
1173
|
+
# Ask user to confirm, adjust, or cancel
|
|
1174
|
+
confirm_action = questionary.select(
|
|
1175
|
+
"\nWhat would you like to do?",
|
|
1176
|
+
choices=[
|
|
1177
|
+
Choice("Save to configuration", value="apply"),
|
|
1178
|
+
Choice("Adjust selection", value="adjust"),
|
|
1179
|
+
Choice("Cancel", value="cancel"),
|
|
1180
|
+
],
|
|
1181
|
+
default="apply",
|
|
1182
|
+
style=QUESTIONARY_STYLE,
|
|
1183
|
+
).ask()
|
|
1184
|
+
|
|
1185
|
+
if confirm_action == "cancel":
|
|
1186
|
+
console.print("[yellow]Configuration cancelled[/yellow]")
|
|
1187
|
+
Prompt.ask("\nPress Enter to continue")
|
|
1188
|
+
return CommandResult(success=True, exit_code=0)
|
|
1189
|
+
|
|
1190
|
+
if confirm_action == "adjust":
|
|
1191
|
+
# Update selection state and loop back
|
|
1192
|
+
for skill in all_skills:
|
|
1193
|
+
skill["is_selected"] = skill["name"] in selected_skills
|
|
1194
|
+
console.print("\n[dim]Adjusting selection...[/dim]\n")
|
|
1195
|
+
continue
|
|
1196
|
+
|
|
1197
|
+
# Save to configuration.yaml
|
|
1198
|
+
with open(project_config_path, encoding="utf-8") as f:
|
|
1199
|
+
config = yaml.safe_load(f) or {}
|
|
1200
|
+
|
|
1201
|
+
if "skills" not in config:
|
|
1202
|
+
config["skills"] = {}
|
|
1203
|
+
|
|
1204
|
+
config["skills"]["user_defined"] = sorted(selected_skills)
|
|
1205
|
+
|
|
1206
|
+
with open(project_config_path, "w", encoding="utf-8") as f:
|
|
1207
|
+
yaml.dump(config, f, default_flow_style=False, sort_keys=False)
|
|
1104
1208
|
|
|
1105
|
-
# Ask user to confirm, adjust, or cancel
|
|
1106
|
-
action = questionary.select(
|
|
1107
|
-
"\nWhat would you like to do?",
|
|
1108
|
-
choices=[
|
|
1109
|
-
Choice("Apply these changes", value="apply"),
|
|
1110
|
-
Choice("Adjust selection", value="adjust"),
|
|
1111
|
-
Choice("Cancel", value="cancel"),
|
|
1112
|
-
],
|
|
1113
|
-
default="apply",
|
|
1114
|
-
style=QUESTIONARY_STYLE,
|
|
1115
|
-
).ask()
|
|
1116
|
-
|
|
1117
|
-
if action == "cancel":
|
|
1118
|
-
console.print("[yellow]Changes cancelled[/yellow]")
|
|
1119
|
-
Prompt.ask("\nPress Enter to continue")
|
|
1120
|
-
return CommandResult(success=True, exit_code=0)
|
|
1121
|
-
if action == "adjust":
|
|
1122
|
-
# Loop back to skill selection
|
|
1123
|
-
console.print("\n[dim]Adjusting selection...[/dim]\n")
|
|
1124
|
-
continue
|
|
1125
|
-
|
|
1126
|
-
# Apply changes
|
|
1127
|
-
success = True
|
|
1128
|
-
errors = []
|
|
1129
|
-
|
|
1130
|
-
# Install skills
|
|
1131
|
-
if to_install:
|
|
1132
|
-
console.print("\n[bold cyan]Installing skills...[/bold cyan]\n")
|
|
1133
|
-
for skill_name in to_install:
|
|
1134
|
-
try:
|
|
1135
|
-
# Deploy single skill
|
|
1136
|
-
result = self.skills_deployer.deploy_skills(
|
|
1137
|
-
skill_names=[skill_name], force=False
|
|
1138
|
-
)
|
|
1139
|
-
|
|
1140
|
-
if result.get("errors"):
|
|
1141
|
-
errors.extend(result["errors"])
|
|
1142
|
-
success = False
|
|
1143
|
-
else:
|
|
1144
|
-
console.print(
|
|
1145
|
-
f"[green]✓ Installed: {skill_name}[/green]"
|
|
1146
|
-
)
|
|
1147
|
-
except Exception as e:
|
|
1148
|
-
errors.append(f"Failed to install {skill_name}: {e}")
|
|
1149
|
-
success = False
|
|
1150
|
-
|
|
1151
|
-
# Remove skills
|
|
1152
|
-
if to_remove:
|
|
1153
|
-
console.print("\n[bold yellow]Removing skills...[/bold yellow]\n")
|
|
1154
|
-
for skill_name in to_remove:
|
|
1155
|
-
try:
|
|
1156
|
-
# Remove single skill
|
|
1157
|
-
result = self.skills_deployer.remove_skills(
|
|
1158
|
-
skill_names=[skill_name]
|
|
1159
|
-
)
|
|
1160
|
-
|
|
1161
|
-
if result.get("errors"):
|
|
1162
|
-
errors.extend(result["errors"])
|
|
1163
|
-
success = False
|
|
1164
|
-
else:
|
|
1165
|
-
console.print(
|
|
1166
|
-
f"[yellow]✗ Removed: {skill_name}[/yellow]"
|
|
1167
|
-
)
|
|
1168
|
-
except Exception as e:
|
|
1169
|
-
errors.append(f"Failed to remove {skill_name}: {e}")
|
|
1170
|
-
success = False
|
|
1171
|
-
|
|
1172
|
-
# Show errors if any
|
|
1173
|
-
if errors:
|
|
1174
|
-
console.print(f"\n[red]✗ {len(errors)} error(s):[/red]")
|
|
1175
|
-
for error in errors:
|
|
1176
|
-
console.print(f" • {error}")
|
|
1177
|
-
|
|
1178
|
-
# Show restart instructions
|
|
1179
|
-
if success and (to_install or to_remove):
|
|
1180
1209
|
console.print(
|
|
1181
|
-
"\n[
|
|
1210
|
+
f"\n[green]✓ Saved {len(selected_skills)} skills to user_defined mode[/green]"
|
|
1182
1211
|
)
|
|
1183
|
-
console.print(
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
Prompt.ask("\nPress Enter to continue")
|
|
1212
|
+
console.print(
|
|
1213
|
+
"[yellow]⚠️ Important:[/yellow] Run [cyan]claude-mpm init[/cyan] to deploy these skills\n"
|
|
1214
|
+
)
|
|
1215
|
+
Prompt.ask("\nPress Enter to continue")
|
|
1188
1216
|
|
|
1189
|
-
|
|
1190
|
-
|
|
1217
|
+
# Exit the loop after successful save
|
|
1218
|
+
break
|
|
1191
1219
|
|
|
1192
|
-
|
|
1193
|
-
return CommandResult(success=success, exit_code=exit_code)
|
|
1220
|
+
return CommandResult(success=True, exit_code=0)
|
|
1194
1221
|
|
|
1195
1222
|
except Exception as e:
|
|
1196
1223
|
console.print(f"[red]Error in skills configuration: {e}[/red]")
|
|
@@ -1199,8 +1226,6 @@ class SkillsManagementCommand(BaseCommand):
|
|
|
1199
1226
|
console.print(f"[dim]{traceback.format_exc()}[/dim]")
|
|
1200
1227
|
return CommandResult(success=False, message=str(e), exit_code=1)
|
|
1201
1228
|
|
|
1202
|
-
return CommandResult(success=False, message=str(e), exit_code=1)
|
|
1203
|
-
|
|
1204
1229
|
|
|
1205
1230
|
def manage_skills(args) -> int:
|
|
1206
1231
|
"""
|
claude_mpm/cli/executor.py
CHANGED
|
@@ -24,6 +24,7 @@ from .commands import (
|
|
|
24
24
|
show_info,
|
|
25
25
|
)
|
|
26
26
|
from .commands.analyze_code import manage_analyze_code
|
|
27
|
+
from .commands.config import manage_config
|
|
27
28
|
from .commands.dashboard import manage_dashboard
|
|
28
29
|
from .commands.skills import manage_skills
|
|
29
30
|
from .commands.upgrade import upgrade
|
|
@@ -236,9 +237,8 @@ def execute_command(command: str, args) -> int:
|
|
|
236
237
|
CLICommands.MEMORY.value: manage_memory,
|
|
237
238
|
CLICommands.MONITOR.value: manage_monitor,
|
|
238
239
|
CLICommands.DASHBOARD.value: manage_dashboard,
|
|
239
|
-
# Configuration management commands
|
|
240
|
-
#
|
|
241
|
-
CLICommands.CONFIG.value: manage_configure, # Alias to configure
|
|
240
|
+
# Configuration management commands
|
|
241
|
+
CLICommands.CONFIG.value: manage_config, # Unified config with subcommands
|
|
242
242
|
CLICommands.CONFIGURE.value: manage_configure, # Interactive configuration TUI
|
|
243
243
|
CLICommands.AGGREGATE.value: aggregate_command,
|
|
244
244
|
CLICommands.ANALYZE_CODE.value: manage_analyze_code,
|
|
@@ -406,15 +406,6 @@ Available commands:
|
|
|
406
406
|
help="Show descriptions and metadata for each agent",
|
|
407
407
|
)
|
|
408
408
|
|
|
409
|
-
# Auto-configuration commands (TSK-0054 Phase 5)
|
|
410
|
-
from .auto_configure_parser import (
|
|
411
|
-
add_agents_detect_subparser,
|
|
412
|
-
add_agents_recommend_subparser,
|
|
413
|
-
)
|
|
414
|
-
|
|
415
|
-
add_agents_detect_subparser(agents_subparsers)
|
|
416
|
-
add_agents_recommend_subparser(agents_subparsers)
|
|
417
|
-
|
|
418
409
|
# Phase 3: Agent Selection Modes (single-tier deployment)
|
|
419
410
|
# Minimal configuration - deploy 6 core agents
|
|
420
411
|
deploy_minimal_parser = agents_subparsers.add_parser(
|
|
@@ -118,141 +118,3 @@ Examples:
|
|
|
118
118
|
)
|
|
119
119
|
|
|
120
120
|
return auto_configure_parser
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
def add_agents_detect_subparser(agents_subparsers) -> argparse.ArgumentParser:
|
|
124
|
-
"""
|
|
125
|
-
Add the agents detect subparser for toolchain detection.
|
|
126
|
-
|
|
127
|
-
WHY: Allows users to see what toolchain is detected without making changes,
|
|
128
|
-
useful for debugging and verification.
|
|
129
|
-
|
|
130
|
-
Args:
|
|
131
|
-
agents_subparsers: The agents subparsers object
|
|
132
|
-
|
|
133
|
-
Returns:
|
|
134
|
-
The configured detect subparser
|
|
135
|
-
"""
|
|
136
|
-
detect_parser = agents_subparsers.add_parser(
|
|
137
|
-
"detect",
|
|
138
|
-
help="Detect project toolchain without deploying",
|
|
139
|
-
description="""
|
|
140
|
-
Detect and display project toolchain without making any changes.
|
|
141
|
-
|
|
142
|
-
This command analyzes your project to detect:
|
|
143
|
-
• Programming languages and versions
|
|
144
|
-
• Frameworks and libraries
|
|
145
|
-
• Deployment targets and platforms
|
|
146
|
-
|
|
147
|
-
Useful for debugging toolchain detection and verifying what would be
|
|
148
|
-
detected before running auto-configure.
|
|
149
|
-
""",
|
|
150
|
-
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
151
|
-
epilog="""
|
|
152
|
-
Examples:
|
|
153
|
-
# Detect toolchain in current directory
|
|
154
|
-
claude-mpm agents detect
|
|
155
|
-
|
|
156
|
-
# Detect with verbose output showing evidence
|
|
157
|
-
claude-mpm agents detect --verbose
|
|
158
|
-
|
|
159
|
-
# JSON output for scripting
|
|
160
|
-
claude-mpm agents detect --json
|
|
161
|
-
|
|
162
|
-
# Detect specific project
|
|
163
|
-
claude-mpm agents detect --project-path /path/to/project
|
|
164
|
-
""",
|
|
165
|
-
)
|
|
166
|
-
add_common_arguments(detect_parser)
|
|
167
|
-
|
|
168
|
-
detect_parser.add_argument(
|
|
169
|
-
"--project-path",
|
|
170
|
-
type=Path,
|
|
171
|
-
metavar="PATH",
|
|
172
|
-
help="Project path to analyze (default: current directory)",
|
|
173
|
-
)
|
|
174
|
-
|
|
175
|
-
return detect_parser
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
def add_agents_recommend_subparser(
|
|
179
|
-
agents_subparsers,
|
|
180
|
-
) -> argparse.ArgumentParser:
|
|
181
|
-
"""
|
|
182
|
-
Add the agents recommend subparser for agent recommendations.
|
|
183
|
-
|
|
184
|
-
WHY: Allows users to see what agents would be recommended without deploying,
|
|
185
|
-
useful for reviewing recommendations before committing to deployment.
|
|
186
|
-
|
|
187
|
-
Args:
|
|
188
|
-
agents_subparsers: The agents subparsers object
|
|
189
|
-
|
|
190
|
-
Returns:
|
|
191
|
-
The configured recommend subparser
|
|
192
|
-
"""
|
|
193
|
-
recommend_parser = agents_subparsers.add_parser(
|
|
194
|
-
"recommend",
|
|
195
|
-
help="Show recommended agents without deploying",
|
|
196
|
-
description="""
|
|
197
|
-
Show recommended agents based on project toolchain without deploying.
|
|
198
|
-
|
|
199
|
-
This command analyzes your project toolchain and recommends appropriate
|
|
200
|
-
agents with detailed reasoning for each recommendation. No changes are
|
|
201
|
-
made to your project.
|
|
202
|
-
|
|
203
|
-
Useful for:
|
|
204
|
-
• Reviewing recommendations before deployment
|
|
205
|
-
• Understanding why agents are recommended
|
|
206
|
-
• Adjusting confidence thresholds
|
|
207
|
-
""",
|
|
208
|
-
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
209
|
-
epilog="""
|
|
210
|
-
Examples:
|
|
211
|
-
# Show recommendations with reasoning
|
|
212
|
-
claude-mpm agents recommend
|
|
213
|
-
|
|
214
|
-
# Require 90% confidence for recommendations
|
|
215
|
-
claude-mpm agents recommend --min-confidence 0.9
|
|
216
|
-
|
|
217
|
-
# JSON output for scripting
|
|
218
|
-
claude-mpm agents recommend --json
|
|
219
|
-
|
|
220
|
-
# Hide detailed reasoning
|
|
221
|
-
claude-mpm agents recommend --no-reasoning
|
|
222
|
-
|
|
223
|
-
# Recommend for specific project
|
|
224
|
-
claude-mpm agents recommend --project-path /path/to/project
|
|
225
|
-
""",
|
|
226
|
-
)
|
|
227
|
-
add_common_arguments(recommend_parser)
|
|
228
|
-
|
|
229
|
-
recommend_parser.add_argument(
|
|
230
|
-
"--project-path",
|
|
231
|
-
type=Path,
|
|
232
|
-
metavar="PATH",
|
|
233
|
-
help="Project path to analyze (default: current directory)",
|
|
234
|
-
)
|
|
235
|
-
|
|
236
|
-
recommend_parser.add_argument(
|
|
237
|
-
"--min-confidence",
|
|
238
|
-
type=float,
|
|
239
|
-
default=0.8,
|
|
240
|
-
metavar="FLOAT",
|
|
241
|
-
help="Minimum confidence threshold for recommendations (0.0-1.0, default: 0.8)",
|
|
242
|
-
)
|
|
243
|
-
|
|
244
|
-
recommend_parser.add_argument(
|
|
245
|
-
"--show-reasoning",
|
|
246
|
-
action="store_true",
|
|
247
|
-
default=True,
|
|
248
|
-
help="Show detailed reasoning for recommendations (default)",
|
|
249
|
-
)
|
|
250
|
-
|
|
251
|
-
recommend_parser.add_argument(
|
|
252
|
-
"--no-reasoning",
|
|
253
|
-
dest="show_reasoning",
|
|
254
|
-
action="store_false",
|
|
255
|
-
help="Hide detailed reasoning for recommendations",
|
|
256
|
-
)
|
|
257
|
-
|
|
258
|
-
return recommend_parser
|