claude-mpm 5.4.55__py3-none-any.whl → 5.4.85__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.
Files changed (173) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/CLAUDE_MPM_FOUNDERS_OUTPUT_STYLE.md +405 -0
  3. claude_mpm/agents/CLAUDE_MPM_OUTPUT_STYLE.md +63 -241
  4. claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +109 -1925
  5. claude_mpm/agents/PM_INSTRUCTIONS.md +36 -9
  6. claude_mpm/cli/__init__.py +5 -1
  7. claude_mpm/cli/commands/agents.py +2 -4
  8. claude_mpm/cli/commands/agents_reconcile.py +197 -0
  9. claude_mpm/cli/commands/configure.py +620 -21
  10. claude_mpm/cli/commands/skills.py +166 -14
  11. claude_mpm/cli/executor.py +1 -0
  12. claude_mpm/cli/interactive/__init__.py +10 -0
  13. claude_mpm/cli/interactive/agent_wizard.py +30 -50
  14. claude_mpm/cli/interactive/questionary_styles.py +65 -0
  15. claude_mpm/cli/interactive/skill_selector.py +481 -0
  16. claude_mpm/cli/parsers/base_parser.py +5 -0
  17. claude_mpm/cli/startup.py +223 -388
  18. claude_mpm/constants.py +1 -0
  19. claude_mpm/core/claude_runner.py +2 -2
  20. claude_mpm/core/interactive_session.py +7 -7
  21. claude_mpm/core/output_style_manager.py +21 -13
  22. claude_mpm/core/unified_config.py +50 -8
  23. claude_mpm/core/unified_paths.py +30 -13
  24. claude_mpm/scripts/start_activity_logging.py +0 -0
  25. claude_mpm/services/agents/deployment/agent_template_builder.py +8 -0
  26. claude_mpm/services/agents/deployment/deployment_reconciler.py +577 -0
  27. claude_mpm/services/agents/deployment/startup_reconciliation.py +138 -0
  28. claude_mpm/services/agents/sources/git_source_sync_service.py +7 -4
  29. claude_mpm/services/agents/startup_sync.py +5 -2
  30. claude_mpm/services/pm_skills_deployer.py +4 -0
  31. claude_mpm/services/skills/git_skill_source_manager.py +24 -8
  32. claude_mpm/services/skills/selective_skill_deployer.py +82 -83
  33. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
  34. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
  35. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
  36. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
  37. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
  38. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
  39. claude_mpm/skills/bundled/collaboration/git-worktrees.md +317 -0
  40. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
  41. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
  42. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
  43. claude_mpm/skills/bundled/collaboration/stacked-prs.md +251 -0
  44. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
  45. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
  46. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
  47. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
  48. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
  49. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
  50. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
  51. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
  52. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
  53. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
  54. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
  55. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
  56. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
  57. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
  58. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
  59. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
  60. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
  61. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
  62. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
  63. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
  64. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
  65. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
  66. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
  67. claude_mpm/skills/bundled/infrastructure/env-manager/INTEGRATION.md +611 -0
  68. claude_mpm/skills/bundled/infrastructure/env-manager/README.md +596 -0
  69. claude_mpm/skills/bundled/infrastructure/env-manager/SKILL.md +260 -0
  70. claude_mpm/skills/bundled/infrastructure/env-manager/examples/nextjs-env-structure.md +315 -0
  71. claude_mpm/skills/bundled/infrastructure/env-manager/references/frameworks.md +436 -0
  72. claude_mpm/skills/bundled/infrastructure/env-manager/references/security.md +433 -0
  73. claude_mpm/skills/bundled/infrastructure/env-manager/references/synchronization.md +452 -0
  74. claude_mpm/skills/bundled/infrastructure/env-manager/references/troubleshooting.md +404 -0
  75. claude_mpm/skills/bundled/infrastructure/env-manager/references/validation.md +420 -0
  76. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
  77. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
  78. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
  79. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
  80. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
  81. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
  82. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
  83. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
  84. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
  85. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
  86. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
  87. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
  88. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
  89. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
  90. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
  91. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
  92. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
  93. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
  94. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
  95. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
  96. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
  97. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
  98. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
  99. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
  100. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
  101. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
  102. claude_mpm/skills/bundled/pm/pm-bug-reporting/pm-bug-reporting.md +248 -0
  103. claude_mpm/skills/bundled/pm/pm-delegation-patterns/SKILL.md +167 -0
  104. claude_mpm/skills/bundled/pm/pm-git-file-tracking/SKILL.md +113 -0
  105. claude_mpm/skills/bundled/pm/pm-pr-workflow/SKILL.md +124 -0
  106. claude_mpm/skills/bundled/pm/pm-teaching-mode/SKILL.md +657 -0
  107. claude_mpm/skills/bundled/pm/pm-ticketing-integration/SKILL.md +154 -0
  108. claude_mpm/skills/bundled/pm/pm-verification-protocols/SKILL.md +198 -0
  109. claude_mpm/skills/bundled/react/flexlayout-react.md +742 -0
  110. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
  111. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
  112. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
  113. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
  114. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
  115. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
  116. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
  117. claude_mpm/skills/bundled/tauri/tauri-async-patterns.md +495 -0
  118. claude_mpm/skills/bundled/tauri/tauri-build-deploy.md +599 -0
  119. claude_mpm/skills/bundled/tauri/tauri-command-patterns.md +535 -0
  120. claude_mpm/skills/bundled/tauri/tauri-error-handling.md +613 -0
  121. claude_mpm/skills/bundled/tauri/tauri-event-system.md +648 -0
  122. claude_mpm/skills/bundled/tauri/tauri-file-system.md +673 -0
  123. claude_mpm/skills/bundled/tauri/tauri-frontend-integration.md +767 -0
  124. claude_mpm/skills/bundled/tauri/tauri-performance.md +669 -0
  125. claude_mpm/skills/bundled/tauri/tauri-state-management.md +573 -0
  126. claude_mpm/skills/bundled/tauri/tauri-testing.md +384 -0
  127. claude_mpm/skills/bundled/tauri/tauri-window-management.md +628 -0
  128. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
  129. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
  130. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
  131. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
  132. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
  133. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
  134. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
  135. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
  136. claude_mpm/skills/bundled/testing/test-quality-inspector/SKILL.md +458 -0
  137. claude_mpm/skills/bundled/testing/test-quality-inspector/examples/example-inspection-report.md +411 -0
  138. claude_mpm/skills/bundled/testing/test-quality-inspector/references/assertion-quality.md +317 -0
  139. claude_mpm/skills/bundled/testing/test-quality-inspector/references/inspection-checklist.md +270 -0
  140. claude_mpm/skills/bundled/testing/test-quality-inspector/references/red-flags.md +436 -0
  141. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
  142. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
  143. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
  144. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
  145. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
  146. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
  147. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
  148. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
  149. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
  150. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
  151. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
  152. claude_mpm/utils/agent_dependency_loader.py +103 -4
  153. claude_mpm/utils/robust_installer.py +45 -24
  154. {claude_mpm-5.4.55.dist-info → claude_mpm-5.4.85.dist-info}/METADATA +47 -23
  155. {claude_mpm-5.4.55.dist-info → claude_mpm-5.4.85.dist-info}/RECORD +159 -47
  156. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc +0 -0
  157. claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc +0 -0
  158. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
  159. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
  160. claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
  161. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
  162. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
  163. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-311.pyc +0 -0
  164. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
  165. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
  166. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-311.pyc +0 -0
  167. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
  168. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
  169. {claude_mpm-5.4.55.dist-info → claude_mpm-5.4.85.dist-info}/WHEEL +0 -0
  170. {claude_mpm-5.4.55.dist-info → claude_mpm-5.4.85.dist-info}/entry_points.txt +0 -0
  171. {claude_mpm-5.4.55.dist-info → claude_mpm-5.4.85.dist-info}/licenses/LICENSE +0 -0
  172. {claude_mpm-5.4.55.dist-info → claude_mpm-5.4.85.dist-info}/licenses/LICENSE-FAQ.md +0 -0
  173. {claude_mpm-5.4.55.dist-info → claude_mpm-5.4.85.dist-info}/top_level.txt +0 -0
@@ -18,7 +18,7 @@ ARCHITECTURE:
18
18
  """
19
19
 
20
20
  import os
21
- import subprocess
21
+ import subprocess # nosec B404
22
22
  from typing import Optional
23
23
 
24
24
  from rich.console import Console
@@ -84,6 +84,7 @@ class SkillsManagementCommand(BaseCommand):
84
84
  SkillsCommands.INFO.value: self._show_skill_info,
85
85
  SkillsCommands.CONFIG.value: self._manage_config,
86
86
  SkillsCommands.CONFIGURE.value: self._configure_skills,
87
+ SkillsCommands.SELECT.value: self._select_skills_interactive,
87
88
  # GitHub deployment commands
88
89
  SkillsCommands.DEPLOY_FROM_GITHUB.value: self._deploy_from_github,
89
90
  SkillsCommands.LIST_AVAILABLE.value: self._list_available_github_skills,
@@ -504,7 +505,7 @@ class SkillsManagementCommand(BaseCommand):
504
505
  # Open in editor
505
506
  editor = os.environ.get("EDITOR", "nano")
506
507
  try:
507
- subprocess.run([editor, str(config_path)], check=True)
508
+ subprocess.run([editor, str(config_path)], check=True) # nosec B603
508
509
  console.print(
509
510
  f"\n[green]Configuration saved to {config_path}[/green]\n"
510
511
  )
@@ -673,33 +674,91 @@ class SkillsManagementCommand(BaseCommand):
673
674
  def _check_deployed_skills(self, args) -> CommandResult:
674
675
  """Check currently deployed skills in ~/.claude/skills/."""
675
676
  try:
676
- result = self.skills_deployer.check_deployed_skills()
677
+ # Get deployed skills
678
+ deployed_result = self.skills_deployer.check_deployed_skills()
679
+ deployed_names = {skill["name"] for skill in deployed_result["skills"]}
677
680
 
678
681
  console.print("\n[bold cyan]Claude Code Skills Status:[/bold cyan]\n")
679
- console.print(f"[dim]Directory: {result['claude_skills_dir']}[/dim]\n")
682
+ console.print(
683
+ f"[dim]Directory: {deployed_result['claude_skills_dir']}[/dim]\n"
684
+ )
685
+
686
+ # Fetch available skills from GitHub to get full list
687
+ try:
688
+ available_result = self.skills_deployer.list_available_skills()
689
+ all_skills = available_result.get("skills", [])
690
+ except Exception as e:
691
+ console.print(
692
+ f"[yellow]Warning: Could not fetch available skills: {e}[/yellow]\n"
693
+ )
694
+ all_skills = []
680
695
 
681
- if result["deployed_count"] == 0:
682
- console.print("[yellow]No skills currently deployed.[/yellow]")
696
+ # Combine deployed and available skills
697
+ skill_map = {}
698
+
699
+ # Add available skills
700
+ for skill in all_skills:
701
+ skill_name = skill.get("name", "")
702
+ if skill_name:
703
+ skill_map[skill_name] = {
704
+ "name": skill.get("display_name")
705
+ or skill_name.replace("-", " ").title(),
706
+ "skill_id": skill_name,
707
+ "source": "MPM Skills",
708
+ "is_deployed": skill_name in deployed_names,
709
+ }
710
+
711
+ # Add any deployed skills not in available list (local/custom skills)
712
+ for skill in deployed_result["skills"]:
713
+ skill_name = skill["name"]
714
+ if skill_name not in skill_map:
715
+ skill_map[skill_name] = {
716
+ "name": skill_name.replace("-", " ").title(),
717
+ "skill_id": skill_name,
718
+ "source": "Local",
719
+ "is_deployed": True,
720
+ }
721
+
722
+ if not skill_map:
723
+ console.print("[yellow]No skills available.[/yellow]")
683
724
  console.print(
684
725
  "[dim]Use 'claude-mpm skills deploy-github' to deploy skills.[/dim]\n"
685
726
  )
686
727
  return CommandResult(success=True, exit_code=0)
687
728
 
688
- console.print(
689
- f"[green]{result['deployed_count']} skill(s) deployed:[/green]\n"
729
+ # Create table matching agent management format
730
+ table = Table(show_header=True, header_style="bold cyan")
731
+ table.add_column("#", style="bright_black", width=6, no_wrap=True)
732
+ table.add_column(
733
+ "Skill ID", style="bright_black", no_wrap=True, overflow="ellipsis"
690
734
  )
735
+ table.add_column(
736
+ "Name", style="bright_cyan", no_wrap=True, overflow="ellipsis"
737
+ )
738
+ table.add_column("Source", style="bright_yellow", no_wrap=True)
739
+ table.add_column("Status", style="bright_black", no_wrap=True)
691
740
 
692
- # Create table for deployed skills
693
- table = Table(show_header=True, header_style="bold cyan")
694
- table.add_column("Skill Name", style="green")
695
- table.add_column("Path", style="dim")
741
+ # Sort skills by name for consistent display
742
+ sorted_skills = sorted(skill_map.values(), key=lambda s: s["skill_id"])
696
743
 
697
- for skill in sorted(result["skills"], key=lambda s: s["name"]):
698
- table.add_row(skill["name"], skill["path"])
744
+ for idx, skill in enumerate(sorted_skills, 1):
745
+ status = (
746
+ "[green]Installed[/green]" if skill["is_deployed"] else "Available"
747
+ )
748
+ table.add_row(
749
+ str(idx), skill["skill_id"], skill["name"], skill["source"], status
750
+ )
699
751
 
700
752
  console.print(table)
701
753
  console.print()
702
754
 
755
+ # Show summary
756
+ deployed_count = sum(1 for s in skill_map.values() if s["is_deployed"])
757
+ console.print(
758
+ f"[dim]Showing {len(skill_map)} skills ({deployed_count} installed, "
759
+ f"{len(skill_map) - deployed_count} available)[/dim]\n"
760
+ )
761
+
703
762
  return CommandResult(success=True, exit_code=0)
704
763
 
705
764
  except Exception as e:
@@ -1222,6 +1281,99 @@ class SkillsManagementCommand(BaseCommand):
1222
1281
  console.print(f"[dim]{traceback.format_exc()}[/dim]")
1223
1282
  return CommandResult(success=False, message=str(e), exit_code=1)
1224
1283
 
1284
+ def _select_skills_interactive(self, args) -> CommandResult:
1285
+ """Interactive skill selection with topic grouping.
1286
+
1287
+ This command provides a two-tier selection interface:
1288
+ 1. Select topic groups (toolchains) to explore
1289
+ 2. Multi-select skills within each topic group
1290
+
1291
+ Features:
1292
+ - Groups skills by toolchain (universal, python, typescript, etc.)
1293
+ - Shows skills auto-included by agent dependencies
1294
+ - Displays token counts for each skill
1295
+ - Updates config and runs reconciliation
1296
+
1297
+ Returns:
1298
+ CommandResult with success/failure status
1299
+ """
1300
+ try:
1301
+ from ...cli.interactive.skill_selector import run_skill_selector
1302
+ from ...core.unified_config import UnifiedConfig
1303
+ from ...services.agents.deployment.deployment_reconciler import (
1304
+ DeploymentReconciler,
1305
+ )
1306
+
1307
+ console.print("\n[bold cyan]Interactive Skill Selector[/bold cyan]\n")
1308
+
1309
+ # Run skill selector
1310
+ selected_skills = run_skill_selector()
1311
+
1312
+ if selected_skills is None:
1313
+ console.print("\n[yellow]Skill selection cancelled[/yellow]")
1314
+ return CommandResult(success=True, exit_code=0)
1315
+
1316
+ # Update config with selected skills
1317
+ config = UnifiedConfig()
1318
+ config.skills.enabled = selected_skills
1319
+
1320
+ # Save config
1321
+ try:
1322
+ config.save()
1323
+ console.print(
1324
+ f"\n[green]✓ Saved {len(selected_skills)} skills to configuration[/green]"
1325
+ )
1326
+ except Exception as e:
1327
+ console.print(f"\n[red]Failed to save configuration: {e}[/red]")
1328
+ return CommandResult(success=False, message=str(e), exit_code=1)
1329
+
1330
+ # Run reconciliation to deploy skills
1331
+ console.print("\n[cyan]Running skill reconciliation...[/cyan]")
1332
+ reconciler = DeploymentReconciler(config)
1333
+
1334
+ try:
1335
+ from pathlib import Path
1336
+
1337
+ project_path = Path.cwd()
1338
+ result = reconciler.reconcile_skills(project_path)
1339
+
1340
+ if result.deployed:
1341
+ console.print(
1342
+ f" [green]✓ Deployed: {', '.join(result.deployed)}[/green]"
1343
+ )
1344
+ if result.removed:
1345
+ console.print(
1346
+ f" [yellow]✓ Removed: {', '.join(result.removed)}[/yellow]"
1347
+ )
1348
+ if result.errors:
1349
+ for error in result.errors:
1350
+ console.print(f" [red]✗ {error}[/red]")
1351
+
1352
+ if result.success:
1353
+ console.print(
1354
+ "\n[bold green]✓ Skill deployment complete![/bold green]"
1355
+ )
1356
+ return CommandResult(success=True, exit_code=0)
1357
+ console.print(
1358
+ f"\n[yellow]⚠ Deployment had {len(result.errors)} errors[/yellow]"
1359
+ )
1360
+ return CommandResult(
1361
+ success=False,
1362
+ message=f"{len(result.errors)} deployment errors",
1363
+ exit_code=1,
1364
+ )
1365
+
1366
+ except Exception as e:
1367
+ console.print(f"\n[red]Reconciliation failed: {e}[/red]")
1368
+ return CommandResult(success=False, message=str(e), exit_code=1)
1369
+
1370
+ except Exception as e:
1371
+ console.print(f"[red]Skill selection error: {e}[/red]")
1372
+ import traceback
1373
+
1374
+ console.print(f"[dim]{traceback.format_exc()}[/dim]")
1375
+ return CommandResult(success=False, message=str(e), exit_code=1)
1376
+
1225
1377
 
1226
1378
  def manage_skills(args) -> int:
1227
1379
  """
@@ -66,6 +66,7 @@ def ensure_run_attributes(args):
66
66
  args.monitor = getattr(args, "monitor", False)
67
67
  args.force = getattr(args, "force", False)
68
68
  args.reload_agents = getattr(args, "reload_agents", False)
69
+ args.force_sync = getattr(args, "force_sync", False)
69
70
  # Include dependency checking attributes
70
71
  args.check_dependencies = getattr(args, "check_dependencies", True)
71
72
  args.force_check_dependencies = getattr(args, "force_check_dependencies", False)
@@ -10,12 +10,22 @@ from .agent_wizard import (
10
10
  run_interactive_agent_manager,
11
11
  run_interactive_agent_wizard,
12
12
  )
13
+ from .questionary_styles import (
14
+ BANNER_WIDTH,
15
+ MPM_STYLE,
16
+ print_banner,
17
+ print_section_header,
18
+ )
13
19
  from .skills_wizard import SkillsWizard, discover_and_link_runtime_skills
14
20
 
15
21
  __all__ = [
22
+ "BANNER_WIDTH",
23
+ "MPM_STYLE",
16
24
  "AgentWizard",
17
25
  "SkillsWizard",
18
26
  "discover_and_link_runtime_skills",
27
+ "print_banner",
28
+ "print_section_header",
19
29
  "run_interactive_agent_manager",
20
30
  "run_interactive_agent_wizard",
21
31
  ]
@@ -12,8 +12,12 @@ from pathlib import Path
12
12
  from typing import Any, Dict, List, Optional, Tuple
13
13
 
14
14
  import questionary
15
- from questionary import Style
16
15
 
16
+ from claude_mpm.cli.interactive.questionary_styles import (
17
+ BANNER_WIDTH,
18
+ MPM_STYLE,
19
+ print_section_header,
20
+ )
17
21
  from claude_mpm.core.logging_config import get_logger
18
22
  from claude_mpm.services.agents.local_template_manager import (
19
23
  LocalAgentTemplate,
@@ -23,16 +27,6 @@ from claude_mpm.utils.agent_filters import apply_all_filters
23
27
 
24
28
  logger = get_logger(__name__)
25
29
 
26
- # Questionary style matching Rich cyan theme (consistent with configure.py)
27
- QUESTIONARY_STYLE = Style(
28
- [
29
- ("selected", "fg:cyan bold"),
30
- ("pointer", "fg:cyan bold"),
31
- ("highlighted", "fg:cyan"),
32
- ("question", "fg:cyan bold"),
33
- ]
34
- )
35
-
36
30
 
37
31
  class AgentWizard:
38
32
  """
@@ -113,9 +107,7 @@ class AgentWizard:
113
107
  Tuple of (success, message)
114
108
  """
115
109
  try:
116
- print("\n" + "=" * 60)
117
- print("🧙‍♂️ Agent Creation Wizard")
118
- print("=" * 60)
110
+ print_section_header("🧙‍♂️", "Agent Creation Wizard", width=BANNER_WIDTH)
119
111
  print("\nI'll guide you through creating a custom local agent.")
120
112
  print("Press Ctrl+C anytime to cancel.\n")
121
113
 
@@ -281,9 +273,7 @@ class AgentWizard:
281
273
  # Get merged agents from all sources
282
274
  all_agents = self._merge_agent_sources()
283
275
 
284
- print("\n" + "=" * 60)
285
- print("🔧 Agent Management Menu")
286
- print("=" * 60)
276
+ print_section_header("🔧", "Agent Management Menu", width=BANNER_WIDTH)
287
277
 
288
278
  if not all_agents:
289
279
  print(
@@ -384,7 +374,7 @@ class AgentWizard:
384
374
  choice = questionary.select(
385
375
  "Agent Management Menu:",
386
376
  choices=menu_choices,
387
- style=QUESTIONARY_STYLE,
377
+ style=MPM_STYLE,
388
378
  ).ask()
389
379
 
390
380
  if not choice: # User pressed Esc
@@ -776,9 +766,7 @@ class AgentWizard:
776
766
 
777
767
  def _confirm_creation(self, config: Dict[str, Any]) -> bool:
778
768
  """Show preview and get confirmation from user."""
779
- print("\n" + "=" * 60)
780
- print("📋 Agent Configuration Preview")
781
- print("=" * 60)
769
+ print_section_header("📋", "Agent Configuration Preview", width=BANNER_WIDTH)
782
770
 
783
771
  print(f"Agent ID: {config['agent_id']}")
784
772
  print(f"Name: {config['name']}")
@@ -795,7 +783,8 @@ class AgentWizard:
795
783
  print("\nInstructions Preview:")
796
784
  print(f" {config['instructions_preview']}")
797
785
 
798
- print("\n" + "=" * 60)
786
+ print()
787
+ print("=" * BANNER_WIDTH)
799
788
 
800
789
  while True:
801
790
  confirm = input("\nCreate this agent? [Y/n]: ").strip().lower()
@@ -1046,8 +1035,7 @@ class AgentWizard:
1046
1035
 
1047
1036
  def _interactive_delete_menu(self, templates: list) -> Tuple[bool, str]:
1048
1037
  """Interactive deletion menu for multiple agents."""
1049
- print("\n🗑️ Delete Agents")
1050
- print("=" * 50)
1038
+ print_section_header("🗑️", "Delete Agents", width=BANNER_WIDTH)
1051
1039
 
1052
1040
  if not templates:
1053
1041
  return False, "No agents available to delete"
@@ -1154,9 +1142,9 @@ class AgentWizard:
1154
1142
  Args:
1155
1143
  agent: Agent metadata dictionary
1156
1144
  """
1157
- print("\n" + "=" * 60)
1158
- print(f"📄 Agent Details: {agent['agent_id']}")
1159
- print("=" * 60)
1145
+ print_section_header(
1146
+ "📄", f"Agent Details: {agent['agent_id']}", width=BANNER_WIDTH
1147
+ )
1160
1148
  print(f"Name: {agent['name']}")
1161
1149
  print(f"Category: {agent['category'] or 'N/A'}")
1162
1150
  print(f"Source: [{agent['source_type']}] {agent['source_identifier']}")
@@ -1188,9 +1176,7 @@ class AgentWizard:
1188
1176
  input("\nPress Enter to continue...")
1189
1177
  return
1190
1178
 
1191
- print("\n" + "=" * 60)
1192
- print("📦 Deploy Agent")
1193
- print("=" * 60)
1179
+ print_section_header("📦", "Deploy Agent", width=BANNER_WIDTH)
1194
1180
  print(f"\n{len(deployable)} agent(s) available to deploy:\n")
1195
1181
 
1196
1182
  # Build agent selection choices with arrow-key navigation
@@ -1200,7 +1186,7 @@ class AgentWizard:
1200
1186
  ]
1201
1187
 
1202
1188
  choice = questionary.select(
1203
- "Select agent to deploy:", choices=agent_choices, style=QUESTIONARY_STYLE
1189
+ "Select agent to deploy:", choices=agent_choices, style=MPM_STYLE
1204
1190
  ).ask()
1205
1191
 
1206
1192
  if not choice: # User pressed Esc
@@ -1296,9 +1282,7 @@ class AgentWizard:
1296
1282
  return
1297
1283
 
1298
1284
  while True:
1299
- print("\n" + "=" * 60)
1300
- print("🔍 Browse & Filter Agents")
1301
- print("=" * 60)
1285
+ print_section_header("🔍", "Browse & Filter Agents", width=BANNER_WIDTH)
1302
1286
 
1303
1287
  # Show filter menu with arrow-key navigation
1304
1288
  print("\n[bold]Filter by:[/bold]")
@@ -1314,7 +1298,7 @@ class AgentWizard:
1314
1298
  choice = questionary.select(
1315
1299
  "Browse & Filter Agents:",
1316
1300
  choices=filter_choices,
1317
- style=QUESTIONARY_STYLE,
1301
+ style=MPM_STYLE,
1318
1302
  ).ask()
1319
1303
 
1320
1304
  if not choice or "Back" in choice:
@@ -1343,7 +1327,7 @@ class AgentWizard:
1343
1327
  cat_choices = [f"{idx}. {cat}" for idx, cat in enumerate(categories, 1)]
1344
1328
 
1345
1329
  cat_choice = questionary.select(
1346
- "Select category:", choices=cat_choices, style=QUESTIONARY_STYLE
1330
+ "Select category:", choices=cat_choices, style=MPM_STYLE
1347
1331
  ).ask()
1348
1332
 
1349
1333
  if not cat_choice: # User pressed Esc
@@ -1457,9 +1441,11 @@ class AgentWizard:
1457
1441
  continue
1458
1442
 
1459
1443
  # Display filtered results
1460
- print("\n" + "=" * 60)
1461
- print(f"📋 {filter_description} ({len(filtered_agents)} agents)")
1462
- print("=" * 60)
1444
+ print_section_header(
1445
+ "📋",
1446
+ f"{filter_description} ({len(filtered_agents)} agents)",
1447
+ width=BANNER_WIDTH,
1448
+ )
1463
1449
 
1464
1450
  if not filtered_agents:
1465
1451
  print("\n[yellow]No agents found matching filter[/yellow]")
@@ -1523,7 +1509,7 @@ class AgentWizard:
1523
1509
  ]
1524
1510
 
1525
1511
  agent_choice = questionary.select(
1526
- "Select agent to deploy:", choices=agent_choices, style=QUESTIONARY_STYLE
1512
+ "Select agent to deploy:", choices=agent_choices, style=MPM_STYLE
1527
1513
  ).ask()
1528
1514
 
1529
1515
  if not agent_choice: # User pressed Esc
@@ -1629,7 +1615,7 @@ class AgentWizard:
1629
1615
  ]
1630
1616
 
1631
1617
  agent_choice = questionary.select(
1632
- "Select agent to view:", choices=agent_choices, style=QUESTIONARY_STYLE
1618
+ "Select agent to view:", choices=agent_choices, style=MPM_STYLE
1633
1619
  ).ask()
1634
1620
 
1635
1621
  if not agent_choice: # User pressed Esc
@@ -1652,9 +1638,7 @@ class AgentWizard:
1652
1638
  preset_service = AgentPresetService(self.source_manager)
1653
1639
 
1654
1640
  while True:
1655
- print("\n" + "=" * 60)
1656
- print("📦 Deploy Agent Preset")
1657
- print("=" * 60)
1641
+ print_section_header("📦", "Deploy Agent Preset", width=BANNER_WIDTH)
1658
1642
 
1659
1643
  # List available presets
1660
1644
  presets = preset_service.list_presets()
@@ -1690,9 +1674,7 @@ class AgentWizard:
1690
1674
  preset_name = presets[idx]["name"]
1691
1675
 
1692
1676
  # Show preset details
1693
- print("\n" + "=" * 60)
1694
- print(f"📦 Preset: {preset_name}")
1695
- print("=" * 60)
1677
+ print_section_header("📦", f"Preset: {preset_name}", width=BANNER_WIDTH)
1696
1678
  print(f"\n[bold]Description:[/bold] {presets[idx]['description']}\n")
1697
1679
 
1698
1680
  # Resolve preset
@@ -1872,9 +1854,7 @@ class AgentWizard:
1872
1854
  input("\nPress Enter to continue...")
1873
1855
  return
1874
1856
 
1875
- print("\n" + "=" * 60)
1876
- print("🔗 Manage Agent Sources")
1877
- print("=" * 60)
1857
+ print_section_header("🔗", "Manage Agent Sources", width=BANNER_WIDTH)
1878
1858
 
1879
1859
  try:
1880
1860
  from claude_mpm.config.agent_sources import AgentSourceConfiguration
@@ -0,0 +1,65 @@
1
+ """Shared questionary styles for consistent TUI across Claude MPM.
2
+
3
+ This module provides unified styling for all interactive questionary interfaces
4
+ to ensure visual consistency across agent wizard, skill selector, and other TUI components.
5
+ """
6
+
7
+ from questionary import Style
8
+
9
+ # Standard cyan-themed style for all selectors
10
+ # Matches the pattern used in agent_wizard.py and skill_selector.py
11
+ MPM_STYLE = Style(
12
+ [
13
+ ("qmark", "fg:cyan bold"),
14
+ ("question", "bold"),
15
+ ("answer", "fg:cyan"),
16
+ ("pointer", "fg:cyan bold"),
17
+ ("highlighted", "fg:cyan bold"),
18
+ ("selected", "fg:cyan"),
19
+ ]
20
+ )
21
+
22
+ # Banner constants for consistent formatting
23
+ BANNER_WIDTH = 60
24
+ BANNER_CHAR = "="
25
+
26
+
27
+ def print_banner(title: str, width: int = BANNER_WIDTH) -> None:
28
+ """Print a styled banner matching agent selector format.
29
+
30
+ Args:
31
+ title: Title text to display in the banner
32
+ width: Total width of the banner in characters (default: 60)
33
+
34
+ Example:
35
+ >>> print_banner("Agent Creation Wizard")
36
+ ============================================================
37
+ Agent Creation Wizard
38
+ ============================================================
39
+ """
40
+ print()
41
+ print(BANNER_CHAR * width)
42
+ print(f"{title:^{width}}")
43
+ print(BANNER_CHAR * width)
44
+ print()
45
+
46
+
47
+ def print_section_header(emoji: str, title: str, width: int = BANNER_WIDTH) -> None:
48
+ """Print a section header with emoji and title.
49
+
50
+ Args:
51
+ emoji: Emoji to display before the title
52
+ title: Section title text
53
+ width: Total width of the header line (default: 60)
54
+
55
+ Example:
56
+ >>> print_section_header("🔧", "Agent Management Menu")
57
+
58
+ ============================================================
59
+ 🔧 Agent Management Menu
60
+ ============================================================
61
+ """
62
+ print()
63
+ print(BANNER_CHAR * width)
64
+ print(f"{emoji} {title}")
65
+ print(BANNER_CHAR * width)