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.

Files changed (103) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_AGENT.md +164 -0
  3. claude_mpm/agents/BASE_ENGINEER.md +658 -0
  4. claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +1 -1
  5. claude_mpm/agents/MEMORY.md +1 -1
  6. claude_mpm/agents/PM_INSTRUCTIONS.md +363 -817
  7. claude_mpm/agents/WORKFLOW.md +5 -254
  8. claude_mpm/agents/agent_loader.py +1 -1
  9. claude_mpm/agents/base_agent.json +31 -0
  10. claude_mpm/cli/chrome_devtools_installer.py +175 -0
  11. claude_mpm/cli/commands/agent_state_manager.py +10 -10
  12. claude_mpm/cli/commands/agents.py +9 -40
  13. claude_mpm/cli/commands/auto_configure.py +4 -4
  14. claude_mpm/cli/commands/configure.py +1 -1
  15. claude_mpm/cli/commands/postmortem.py +1 -1
  16. claude_mpm/cli/commands/skills.py +193 -187
  17. claude_mpm/cli/interactive/agent_wizard.py +2 -2
  18. claude_mpm/cli/parsers/agents_parser.py +0 -9
  19. claude_mpm/cli/parsers/auto_configure_parser.py +0 -138
  20. claude_mpm/cli/startup.py +330 -78
  21. claude_mpm/commands/mpm-config.md +1 -2
  22. claude_mpm/commands/mpm-help.md +14 -95
  23. claude_mpm/commands/mpm-organize.md +350 -153
  24. claude_mpm/core/config.py +2 -4
  25. claude_mpm/core/framework/loaders/agent_loader.py +1 -1
  26. claude_mpm/core/framework/loaders/instruction_loader.py +52 -11
  27. claude_mpm/core/unified_agent_registry.py +1 -1
  28. claude_mpm/dashboard/static/svelte-build/_app/env.js +1 -0
  29. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.B_FtCwCQ.css +1 -0
  30. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.Cl_eSA4x.css +1 -0
  31. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BgChzWQ1.js +1 -0
  32. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIXEwuWe.js +1 -0
  33. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWc5urbQ.js +1 -0
  34. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DMkZpdF2.js +2 -0
  35. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DjhvlsAc.js +1 -0
  36. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/N4qtv3Hx.js +2 -0
  37. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/uj46x2Wr.js +1 -0
  38. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.DTL5mJO-.js +2 -0
  39. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.DzuEhzqh.js +1 -0
  40. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/0.CAGBuiOw.js +1 -0
  41. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DFLC8jdE.js +1 -0
  42. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.DPvEihJJ.js +10 -0
  43. claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -0
  44. claude_mpm/dashboard/static/svelte-build/favicon.svg +7 -0
  45. claude_mpm/dashboard/static/svelte-build/index.html +36 -0
  46. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc +0 -0
  47. claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc +0 -0
  48. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
  49. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
  50. claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
  51. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
  52. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
  53. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-311.pyc +0 -0
  54. claude_mpm/hooks/claude_hooks/event_handlers.py +5 -0
  55. claude_mpm/hooks/claude_hooks/hook_handler.py +149 -1
  56. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
  57. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager.cpython-311.pyc +0 -0
  58. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
  59. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-311.pyc +0 -0
  60. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
  61. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
  62. claude_mpm/hooks/claude_hooks/services/connection_manager.py +26 -6
  63. claude_mpm/models/git_repository.py +3 -3
  64. claude_mpm/scripts/start_activity_logging.py +0 -0
  65. claude_mpm/services/agents/cache_git_manager.py +6 -6
  66. claude_mpm/services/agents/deployment/agent_deployment.py +7 -7
  67. claude_mpm/services/agents/deployment/agent_discovery_service.py +2 -2
  68. claude_mpm/services/agents/deployment/agent_template_builder.py +2 -2
  69. claude_mpm/services/agents/deployment/agents_directory_resolver.py +2 -2
  70. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +20 -22
  71. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +55 -53
  72. claude_mpm/services/agents/git_source_manager.py +2 -2
  73. claude_mpm/services/agents/recommender.py +5 -3
  74. claude_mpm/services/agents/single_tier_deployment_service.py +2 -2
  75. claude_mpm/services/agents/sources/git_source_sync_service.py +5 -5
  76. claude_mpm/services/agents/startup_sync.py +22 -2
  77. claude_mpm/services/command_deployment_service.py +10 -0
  78. claude_mpm/services/diagnostics/checks/agent_check.py +2 -2
  79. claude_mpm/services/diagnostics/checks/agent_sources_check.py +1 -1
  80. claude_mpm/services/git/git_operations_service.py +8 -8
  81. claude_mpm/services/monitor/server.py +473 -3
  82. claude_mpm/services/skills/selective_skill_deployer.py +475 -1
  83. claude_mpm/services/skills_deployer.py +62 -6
  84. claude_mpm/services/socketio/dashboard_server.py +1 -0
  85. claude_mpm/services/socketio/event_normalizer.py +37 -6
  86. claude_mpm/services/socketio/server/core.py +262 -123
  87. claude_mpm/utils/agent_dependency_loader.py +14 -2
  88. claude_mpm/utils/agent_filters.py +1 -1
  89. claude_mpm/utils/migration.py +4 -4
  90. claude_mpm/utils/robust_installer.py +47 -3
  91. {claude_mpm-5.4.14.dist-info → claude_mpm-5.4.36.dist-info}/METADATA +5 -3
  92. {claude_mpm-5.4.14.dist-info → claude_mpm-5.4.36.dist-info}/RECORD +96 -66
  93. claude_mpm/cli/commands/agents_detect.py +0 -380
  94. claude_mpm/cli/commands/agents_recommend.py +0 -309
  95. claude_mpm/commands/mpm-agents-auto-configure.md +0 -278
  96. claude_mpm/commands/mpm-agents-detect.md +0 -177
  97. claude_mpm/commands/mpm-agents-list.md +0 -131
  98. claude_mpm/commands/mpm-agents-recommend.md +0 -223
  99. {claude_mpm-5.4.14.dist-info → claude_mpm-5.4.36.dist-info}/WHEEL +0 -0
  100. {claude_mpm-5.4.14.dist-info → claude_mpm-5.4.36.dist-info}/entry_points.txt +0 -0
  101. {claude_mpm-5.4.14.dist-info → claude_mpm-5.4.36.dist-info}/licenses/LICENSE +0 -0
  102. {claude_mpm-5.4.14.dist-info → claude_mpm-5.4.36.dist-info}/licenses/LICENSE-FAQ.md +0 -0
  103. {claude_mpm-5.4.14.dist-info → claude_mpm-5.4.36.dist-info}/top_level.txt +0 -0
@@ -157,9 +157,6 @@ class AgentsCommand(AgentCommand):
157
157
  "configure": self._configure_deployment,
158
158
  # Migration command (DEPRECATION support)
159
159
  "migrate-to-project": self._migrate_to_project,
160
- # Auto-configuration commands (TSK-0054 Phase 5)
161
- "detect": self._detect_toolchain,
162
- "recommend": self._recommend_agents,
163
160
  # Agent selection modes (Phase 3: 1M-382)
164
161
  "deploy-minimal": self._deploy_minimal_configuration,
165
162
  "deploy-auto": self._deploy_auto_configure,
@@ -564,7 +561,7 @@ class AgentsCommand(AgentCommand):
564
561
  """Deploy agents using two-phase sync: cache → deploy.
565
562
 
566
563
  Phase 3 Integration (1M-486): Uses Git sync service for deployment.
567
- - Phase 1: Sync agents to ~/.claude-mpm/cache/remote-agents/ (if needed)
564
+ - Phase 1: Sync agents to ~/.claude-mpm/cache/agents/ (if needed)
568
565
  - Phase 2: Deploy from cache to project .claude-mpm/agents/
569
566
 
570
567
  This replaces the old single-tier deployment with a multi-project
@@ -1825,34 +1822,6 @@ class AgentsCommand(AgentCommand):
1825
1822
  f"Error in interactive configuration: {e}"
1826
1823
  )
1827
1824
 
1828
- def _detect_toolchain(self, args) -> CommandResult:
1829
- """Detect project toolchain without deploying agents.
1830
-
1831
- Part of TSK-0054 Phase 5: Auto-configuration CLI integration.
1832
- """
1833
- try:
1834
- from .agents_detect import AgentsDetectCommand
1835
-
1836
- cmd = AgentsDetectCommand()
1837
- return cmd.run(args)
1838
- except Exception as e:
1839
- self.logger.error(f"Error detecting toolchain: {e}", exc_info=True)
1840
- return CommandResult.error_result(f"Error detecting toolchain: {e}")
1841
-
1842
- def _recommend_agents(self, args) -> CommandResult:
1843
- """Recommend agents based on project toolchain.
1844
-
1845
- Part of TSK-0054 Phase 5: Auto-configuration CLI integration.
1846
- """
1847
- try:
1848
- from .agents_recommend import AgentsRecommendCommand
1849
-
1850
- cmd = AgentsRecommendCommand()
1851
- return cmd.run(args)
1852
- except Exception as e:
1853
- self.logger.error(f"Error recommending agents: {e}", exc_info=True)
1854
- return CommandResult.error_result(f"Error recommending agents: {e}")
1855
-
1856
1825
  def _migrate_to_project(self, args) -> CommandResult:
1857
1826
  """Migrate user-level agents to project-level.
1858
1827
 
@@ -2175,7 +2144,7 @@ class AgentsCommand(AgentCommand):
2175
2144
  )
2176
2145
 
2177
2146
  # Get remote agents cache directory
2178
- cache_dir = Path.home() / ".claude-mpm" / "cache" / "remote-agents"
2147
+ cache_dir = Path.home() / ".claude-mpm" / "cache" / "agents"
2179
2148
 
2180
2149
  if not cache_dir.exists():
2181
2150
  return CommandResult.error_result(
@@ -2223,7 +2192,7 @@ class AgentsCommand(AgentCommand):
2223
2192
 
2224
2193
  # Get agents from collection
2225
2194
  service = MultiSourceAgentDeploymentService()
2226
- cache_dir = Path.home() / ".claude-mpm" / "cache" / "remote-agents"
2195
+ cache_dir = Path.home() / ".claude-mpm" / "cache" / "agents"
2227
2196
  agents = service.get_agents_by_collection(collection_id, cache_dir)
2228
2197
 
2229
2198
  if not agents:
@@ -2280,7 +2249,7 @@ class AgentsCommand(AgentCommand):
2280
2249
 
2281
2250
  # Get agents from collection
2282
2251
  service = MultiSourceAgentDeploymentService()
2283
- cache_dir = Path.home() / ".claude-mpm" / "cache" / "remote-agents"
2252
+ cache_dir = Path.home() / ".claude-mpm" / "cache" / "agents"
2284
2253
  agents = service.get_agents_by_collection(collection_id, cache_dir)
2285
2254
 
2286
2255
  if not agents:
@@ -2335,7 +2304,7 @@ class AgentsCommand(AgentCommand):
2335
2304
  try:
2336
2305
  from ...services.agents.cache_git_manager import CacheGitManager
2337
2306
 
2338
- cache_dir = Path.home() / ".claude-mpm" / "cache" / "remote-agents"
2307
+ cache_dir = Path.home() / ".claude-mpm" / "cache" / "agents"
2339
2308
  manager = CacheGitManager(cache_dir)
2340
2309
 
2341
2310
  if not manager.is_git_repo():
@@ -2408,7 +2377,7 @@ class AgentsCommand(AgentCommand):
2408
2377
  try:
2409
2378
  from ...services.agents.cache_git_manager import CacheGitManager
2410
2379
 
2411
- cache_dir = Path.home() / ".claude-mpm" / "cache" / "remote-agents"
2380
+ cache_dir = Path.home() / ".claude-mpm" / "cache" / "agents"
2412
2381
  manager = CacheGitManager(cache_dir)
2413
2382
 
2414
2383
  if not manager.is_git_repo():
@@ -2435,7 +2404,7 @@ class AgentsCommand(AgentCommand):
2435
2404
  try:
2436
2405
  from ...services.agents.cache_git_manager import CacheGitManager
2437
2406
 
2438
- cache_dir = Path.home() / ".claude-mpm" / "cache" / "remote-agents"
2407
+ cache_dir = Path.home() / ".claude-mpm" / "cache" / "agents"
2439
2408
  manager = CacheGitManager(cache_dir)
2440
2409
 
2441
2410
  if not manager.is_git_repo():
@@ -2467,7 +2436,7 @@ class AgentsCommand(AgentCommand):
2467
2436
  try:
2468
2437
  from ...services.agents.cache_git_manager import CacheGitManager
2469
2438
 
2470
- cache_dir = Path.home() / ".claude-mpm" / "cache" / "remote-agents"
2439
+ cache_dir = Path.home() / ".claude-mpm" / "cache" / "agents"
2471
2440
  manager = CacheGitManager(cache_dir)
2472
2441
 
2473
2442
  if not manager.is_git_repo():
@@ -2515,7 +2484,7 @@ class AgentsCommand(AgentCommand):
2515
2484
  try:
2516
2485
  from ...services.agents.cache_git_manager import CacheGitManager
2517
2486
 
2518
- cache_dir = Path.home() / ".claude-mpm" / "cache" / "remote-agents"
2487
+ cache_dir = Path.home() / ".claude-mpm" / "cache" / "agents"
2519
2488
  manager = CacheGitManager(cache_dir)
2520
2489
 
2521
2490
  if not manager.is_git_repo():
@@ -934,13 +934,13 @@ class AutoConfigureCommand(BaseCommand):
934
934
  )
935
935
 
936
936
  # Get managed agents from cache
937
- remote_agents_dir = Path.home() / ".claude-mpm" / "cache" / "remote-agents"
938
- if not remote_agents_dir.exists():
939
- self.logger.debug("No remote agents cache found")
937
+ agents_cache_dir = Path.home() / ".claude-mpm" / "cache" / "agents"
938
+ if not agents_cache_dir.exists():
939
+ self.logger.debug("No agents cache found")
940
940
  return None
941
941
 
942
942
  # Discover managed agents
943
- discovery_service = RemoteAgentDiscoveryService(remote_agents_dir)
943
+ discovery_service = RemoteAgentDiscoveryService(agents_cache_dir)
944
944
  managed_agents = discovery_service.discover_remote_agents()
945
945
 
946
946
  if not managed_agents:
@@ -1015,7 +1015,7 @@ class ConfigureCommand(BaseCommand):
1015
1015
  # Count agents in cache
1016
1016
  # Note: identifier already includes subdirectory path (e.g., "bobmatnyc/claude-mpm-agents/agents")
1017
1017
  cache_dir = (
1018
- Path.home() / ".claude-mpm" / "cache" / "remote-agents" / identifier
1018
+ Path.home() / ".claude-mpm" / "cache" / "agents" / identifier
1019
1019
  )
1020
1020
  agent_count = 0
1021
1021
  if cache_dir.exists():
@@ -317,7 +317,7 @@ def _create_prs(report, verbose: bool) -> int:
317
317
  print(f"\n🤖 Creating {len(pr_actions)} PR(s) for agent improvements...")
318
318
 
319
319
  # Check if we're in the agent cache git repo
320
- agent_cache_path = Path.home() / ".claude-mpm" / "cache" / "remote-agents"
320
+ agent_cache_path = Path.home() / ".claude-mpm" / "cache" / "agents"
321
321
 
322
322
  if not agent_cache_path.exists():
323
323
  print(f"❌ Agent cache not found at: {agent_cache_path}")
@@ -972,23 +972,37 @@ class SkillsManagementCommand(BaseCommand):
972
972
  console.print(f"[red]Unexpected error: {e}[/red]")
973
973
 
974
974
  def _configure_skills(self, args) -> CommandResult:
975
- """Interactive skills configuration with checkbox selection.
975
+ """Interactive skills configuration using configuration.yaml.
976
976
 
977
977
  Provides checkbox-based selection interface matching agents configure UX:
978
- - Status column showing Installed/Available
979
- - Pre-selection for installed skills
980
- - Apply/Adjust/Cancel menu
981
- - While loop for adjustment
982
- - Simplified labels (checkbox state only)
983
-
984
- This is Option 3 (Hybrid approach): Separate command for interactive mode
985
- while keeping deploy-github for CLI automation.
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
+ ```
986
993
  """
987
994
  try:
995
+ from pathlib import Path
996
+
988
997
  import questionary
998
+ import yaml
989
999
  from questionary import Choice, Style
990
1000
  from rich.prompt import Prompt
991
1001
 
1002
+ from ...services.skills.selective_skill_deployer import (
1003
+ get_skills_to_deploy,
1004
+ )
1005
+
992
1006
  # Questionary style (matching agents configure)
993
1007
  QUESTIONARY_STYLE = Style(
994
1008
  [
@@ -1013,203 +1027,197 @@ class SkillsManagementCommand(BaseCommand):
1013
1027
  ]
1014
1028
  )
1015
1029
 
1016
- console.print("\n[bold cyan]Interactive Skills Configuration[/bold cyan]\n")
1017
- console.print(
1018
- "[dim]Select skills to install/uninstall using checkboxes[/dim]"
1019
- )
1020
- console.print("[dim]● = Installed, ○ = Available[/dim]\n")
1030
+ console.print("\n[bold cyan]Skills Configuration Manager[/bold cyan]\n")
1021
1031
 
1022
- # Get deployed skills for status detection
1023
- deployed_result = self.skills_deployer.check_deployed_skills()
1024
- deployed_skills = {
1025
- skill["name"] for skill in deployed_result.get("skills", [])
1026
- }
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)
1027
1035
 
1028
- # Get available skills from GitHub
1029
- console.print("[dim]Fetching available skills from GitHub...[/dim]\n")
1030
- available_result = self.skills_deployer.list_available_skills()
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
+ )
1031
1041
 
1032
- if available_result.get("error"):
1033
- console.print(f"[red]Error: {available_result['error']}[/red]")
1034
- return CommandResult(
1035
- success=False, message=available_result["error"], exit_code=1
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"
1048
+ )
1049
+ else:
1050
+ console.print(
1051
+ "[dim]User mode: You've manually selected which skills to deploy[/dim]"
1036
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)
1037
1072
 
1038
- # Flatten skills by category
1039
- all_skills = []
1040
- for category, skills in available_result.get("by_category", {}).items():
1041
- for skill in skills:
1042
- skill_info = {
1043
- "name": skill.get("name", "unknown"),
1044
- "category": category,
1045
- "is_deployed": skill.get("name", "unknown") in deployed_skills,
1046
- }
1047
- all_skills.append(skill_info)
1048
-
1049
- # Sort by deployed status (deployed first), then by name
1050
- all_skills.sort(key=lambda s: (not s["is_deployed"], s["name"]))
1051
-
1052
- # Build checkbox choices with pre-selection
1053
- # Loop to allow adjusting selection
1054
- while True:
1055
- skill_choices = []
1056
- skill_map = {} # For lookup after selection
1057
-
1058
- for skill in all_skills:
1059
- skill_name = skill["name"]
1060
- category = skill["category"]
1061
- is_deployed = skill["is_deployed"]
1062
-
1063
- # Simple format: "skill-name (category)"
1064
- # Checkbox state (checked/unchecked) indicates installed status
1065
- choice_text = f"{skill_name} ({category})"
1066
-
1067
- # Pre-select if deployed
1068
- choice = Choice(
1069
- title=choice_text, value=skill_name, checked=is_deployed
1070
- )
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)
1071
1081
 
1072
- skill_choices.append(choice)
1073
- skill_map[skill_name] = skill
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 {}
1074
1086
 
1075
- # Display checkbox selection
1076
- selected_skills = questionary.checkbox(
1077
- "Select skills (Space to toggle, Enter to confirm):",
1078
- choices=skill_choices,
1079
- style=QUESTIONARY_STYLE,
1080
- ).ask()
1087
+ if "skills" not in config:
1088
+ config["skills"] = {}
1081
1089
 
1082
- if selected_skills is None:
1083
- # User cancelled (Ctrl+C)
1084
- console.print("[yellow]Skills configuration cancelled[/yellow]")
1085
- return CommandResult(success=True, exit_code=0)
1090
+ config["skills"]["user_defined"] = []
1086
1091
 
1087
- # Determine changes
1088
- to_install = []
1089
- 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)
1090
1094
 
1091
- for skill in all_skills:
1092
- skill_name = skill["name"]
1093
- is_deployed = skill["is_deployed"]
1094
- is_selected = skill_name in selected_skills
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)
1095
1100
 
1096
- if is_selected and not is_deployed:
1097
- to_install.append(skill_name)
1098
- elif not is_selected and is_deployed:
1099
- to_remove.append(skill_name)
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")
1100
1107
 
1101
- # Show summary of changes
1102
- console.print("\n[bold]Changes to apply:[/bold]")
1103
- if to_install:
1104
- console.print(
1105
- f"\n[green]✓ Install ({len(to_install)} skills):[/green]"
1106
- )
1107
- for skill in to_install:
1108
- console.print(f" • {skill}")
1108
+ # Get available skills
1109
+ available_result = self.skills_deployer.list_available_skills()
1109
1110
 
1110
- if to_remove:
1111
- console.print(
1112
- f"\n[yellow]✗ Remove ({len(to_remove)} skills):[/yellow]"
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
1113
1115
  )
1114
- for skill in to_remove:
1115
- console.print(f" • {skill}")
1116
1116
 
1117
- if not to_install and not to_remove:
1118
- console.print(
1119
- "\n[dim]No changes (selection matches current deployment)[/dim]"
1120
- )
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
+ )
1121
1149
 
1122
- console.print()
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)
1123
1208
 
1124
- # Ask user to confirm, adjust, or cancel
1125
- action = questionary.select(
1126
- "\nWhat would you like to do?",
1127
- choices=[
1128
- Choice("Apply these changes", value="apply"),
1129
- Choice("Adjust selection", value="adjust"),
1130
- Choice("Cancel", value="cancel"),
1131
- ],
1132
- default="apply",
1133
- style=QUESTIONARY_STYLE,
1134
- ).ask()
1135
-
1136
- if action == "cancel":
1137
- console.print("[yellow]Changes cancelled[/yellow]")
1138
- Prompt.ask("\nPress Enter to continue")
1139
- return CommandResult(success=True, exit_code=0)
1140
- if action == "adjust":
1141
- # Loop back to skill selection
1142
- console.print("\n[dim]Adjusting selection...[/dim]\n")
1143
- continue
1144
-
1145
- # Apply changes
1146
- success = True
1147
- errors = []
1148
-
1149
- # Install skills
1150
- if to_install:
1151
- console.print("\n[bold cyan]Installing skills...[/bold cyan]\n")
1152
- for skill_name in to_install:
1153
- try:
1154
- # Deploy single skill
1155
- result = self.skills_deployer.deploy_skills(
1156
- skill_names=[skill_name], force=False
1157
- )
1158
-
1159
- if result.get("errors"):
1160
- errors.extend(result["errors"])
1161
- success = False
1162
- else:
1163
- console.print(
1164
- f"[green]✓ Installed: {skill_name}[/green]"
1165
- )
1166
- except Exception as e:
1167
- errors.append(f"Failed to install {skill_name}: {e}")
1168
- success = False
1169
-
1170
- # Remove skills
1171
- if to_remove:
1172
- console.print("\n[bold yellow]Removing skills...[/bold yellow]\n")
1173
- for skill_name in to_remove:
1174
- try:
1175
- # Remove single skill
1176
- result = self.skills_deployer.remove_skills(
1177
- skill_names=[skill_name]
1178
- )
1179
-
1180
- if result.get("errors"):
1181
- errors.extend(result["errors"])
1182
- success = False
1183
- else:
1184
- console.print(
1185
- f"[yellow]✗ Removed: {skill_name}[/yellow]"
1186
- )
1187
- except Exception as e:
1188
- errors.append(f"Failed to remove {skill_name}: {e}")
1189
- success = False
1190
-
1191
- # Show errors if any
1192
- if errors:
1193
- console.print(f"\n[red]✗ {len(errors)} error(s):[/red]")
1194
- for error in errors:
1195
- console.print(f" • {error}")
1196
-
1197
- # Show restart instructions
1198
- if success and (to_install or to_remove):
1199
1209
  console.print(
1200
- "\n[bold green]✓ Changes applied successfully![/bold green]"
1210
+ f"\n[green]✓ Saved {len(selected_skills)} skills to user_defined mode[/green]"
1201
1211
  )
1202
- console.print("\n[yellow]⚠️ Important:[/yellow]")
1203
- console.print(" Restart Claude Code for changes to take effect")
1204
-
1205
- console.print()
1206
- 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")
1207
1216
 
1208
- # Exit the loop after successful execution
1209
- break
1217
+ # Exit the loop after successful save
1218
+ break
1210
1219
 
1211
- exit_code = 0 if success else 1
1212
- return CommandResult(success=success, exit_code=exit_code)
1220
+ return CommandResult(success=True, exit_code=0)
1213
1221
 
1214
1222
  except Exception as e:
1215
1223
  console.print(f"[red]Error in skills configuration: {e}[/red]")
@@ -1218,8 +1226,6 @@ class SkillsManagementCommand(BaseCommand):
1218
1226
  console.print(f"[dim]{traceback.format_exc()}[/dim]")
1219
1227
  return CommandResult(success=False, message=str(e), exit_code=1)
1220
1228
 
1221
- return CommandResult(success=False, message=str(e), exit_code=1)
1222
-
1223
1229
 
1224
1230
  def manage_skills(args) -> int:
1225
1231
  """
@@ -1374,7 +1374,7 @@ class AgentWizard:
1374
1374
  Path.home()
1375
1375
  / ".claude-mpm"
1376
1376
  / "cache"
1377
- / "remote-agents"
1377
+ / "agents"
1378
1378
  / "bobmatnyc"
1379
1379
  / "claude-mpm-agents"
1380
1380
  / "AUTO-DEPLOY-INDEX.md"
@@ -1419,7 +1419,7 @@ class AgentWizard:
1419
1419
  Path.home()
1420
1420
  / ".claude-mpm"
1421
1421
  / "cache"
1422
- / "remote-agents"
1422
+ / "agents"
1423
1423
  / "bobmatnyc"
1424
1424
  / "claude-mpm-agents"
1425
1425
  / "AUTO-DEPLOY-INDEX.md"
@@ -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(