claude-mpm 4.13.2__py3-none-any.whl → 4.18.2__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 (250) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_ENGINEER.md +286 -0
  3. claude_mpm/agents/BASE_PM.md +48 -17
  4. claude_mpm/agents/OUTPUT_STYLE.md +329 -11
  5. claude_mpm/agents/PM_INSTRUCTIONS.md +227 -8
  6. claude_mpm/agents/agent_loader.py +17 -5
  7. claude_mpm/agents/frontmatter_validator.py +284 -253
  8. claude_mpm/agents/templates/agentic-coder-optimizer.json +9 -2
  9. claude_mpm/agents/templates/api_qa.json +7 -1
  10. claude_mpm/agents/templates/clerk-ops.json +8 -1
  11. claude_mpm/agents/templates/code_analyzer.json +4 -1
  12. claude_mpm/agents/templates/dart_engineer.json +11 -1
  13. claude_mpm/agents/templates/data_engineer.json +11 -1
  14. claude_mpm/agents/templates/documentation.json +6 -1
  15. claude_mpm/agents/templates/engineer.json +18 -1
  16. claude_mpm/agents/templates/gcp_ops_agent.json +8 -1
  17. claude_mpm/agents/templates/golang_engineer.json +11 -1
  18. claude_mpm/agents/templates/java_engineer.json +12 -2
  19. claude_mpm/agents/templates/local_ops_agent.json +1217 -6
  20. claude_mpm/agents/templates/nextjs_engineer.json +11 -1
  21. claude_mpm/agents/templates/ops.json +8 -1
  22. claude_mpm/agents/templates/php-engineer.json +11 -1
  23. claude_mpm/agents/templates/project_organizer.json +10 -3
  24. claude_mpm/agents/templates/prompt-engineer.json +5 -1
  25. claude_mpm/agents/templates/python_engineer.json +11 -1
  26. claude_mpm/agents/templates/qa.json +7 -1
  27. claude_mpm/agents/templates/react_engineer.json +11 -1
  28. claude_mpm/agents/templates/refactoring_engineer.json +8 -1
  29. claude_mpm/agents/templates/research.json +4 -1
  30. claude_mpm/agents/templates/ruby-engineer.json +11 -1
  31. claude_mpm/agents/templates/rust_engineer.json +11 -1
  32. claude_mpm/agents/templates/security.json +6 -1
  33. claude_mpm/agents/templates/svelte-engineer.json +225 -0
  34. claude_mpm/agents/templates/ticketing.json +6 -1
  35. claude_mpm/agents/templates/typescript_engineer.json +11 -1
  36. claude_mpm/agents/templates/vercel_ops_agent.json +8 -1
  37. claude_mpm/agents/templates/version_control.json +8 -1
  38. claude_mpm/agents/templates/web_qa.json +7 -1
  39. claude_mpm/agents/templates/web_ui.json +11 -1
  40. claude_mpm/cli/__init__.py +34 -706
  41. claude_mpm/cli/commands/agent_manager.py +25 -12
  42. claude_mpm/cli/commands/agent_state_manager.py +186 -0
  43. claude_mpm/cli/commands/agents.py +204 -148
  44. claude_mpm/cli/commands/aggregate.py +7 -3
  45. claude_mpm/cli/commands/analyze.py +9 -4
  46. claude_mpm/cli/commands/analyze_code.py +7 -2
  47. claude_mpm/cli/commands/auto_configure.py +7 -9
  48. claude_mpm/cli/commands/config.py +47 -13
  49. claude_mpm/cli/commands/configure.py +294 -1788
  50. claude_mpm/cli/commands/configure_agent_display.py +261 -0
  51. claude_mpm/cli/commands/configure_behavior_manager.py +204 -0
  52. claude_mpm/cli/commands/configure_hook_manager.py +225 -0
  53. claude_mpm/cli/commands/configure_models.py +18 -0
  54. claude_mpm/cli/commands/configure_navigation.py +167 -0
  55. claude_mpm/cli/commands/configure_paths.py +104 -0
  56. claude_mpm/cli/commands/configure_persistence.py +254 -0
  57. claude_mpm/cli/commands/configure_startup_manager.py +646 -0
  58. claude_mpm/cli/commands/configure_template_editor.py +497 -0
  59. claude_mpm/cli/commands/configure_validators.py +73 -0
  60. claude_mpm/cli/commands/local_deploy.py +537 -0
  61. claude_mpm/cli/commands/memory.py +54 -20
  62. claude_mpm/cli/commands/mpm_init.py +39 -25
  63. claude_mpm/cli/commands/mpm_init_handler.py +8 -3
  64. claude_mpm/cli/executor.py +202 -0
  65. claude_mpm/cli/helpers.py +105 -0
  66. claude_mpm/cli/interactive/__init__.py +3 -0
  67. claude_mpm/cli/interactive/skills_wizard.py +491 -0
  68. claude_mpm/cli/parsers/__init__.py +7 -1
  69. claude_mpm/cli/parsers/base_parser.py +98 -3
  70. claude_mpm/cli/parsers/local_deploy_parser.py +227 -0
  71. claude_mpm/cli/shared/output_formatters.py +28 -19
  72. claude_mpm/cli/startup.py +481 -0
  73. claude_mpm/cli/utils.py +52 -1
  74. claude_mpm/commands/mpm-help.md +3 -0
  75. claude_mpm/commands/mpm-version.md +113 -0
  76. claude_mpm/commands/mpm.md +1 -0
  77. claude_mpm/config/agent_config.py +2 -2
  78. claude_mpm/config/model_config.py +428 -0
  79. claude_mpm/core/base_service.py +13 -12
  80. claude_mpm/core/enums.py +452 -0
  81. claude_mpm/core/factories.py +1 -1
  82. claude_mpm/core/instruction_reinforcement_hook.py +2 -1
  83. claude_mpm/core/interactive_session.py +9 -3
  84. claude_mpm/core/logging_config.py +6 -2
  85. claude_mpm/core/oneshot_session.py +8 -4
  86. claude_mpm/core/optimized_agent_loader.py +3 -3
  87. claude_mpm/core/output_style_manager.py +12 -192
  88. claude_mpm/core/service_registry.py +5 -1
  89. claude_mpm/core/types.py +2 -9
  90. claude_mpm/core/typing_utils.py +7 -6
  91. claude_mpm/dashboard/static/js/dashboard.js +0 -14
  92. claude_mpm/dashboard/templates/index.html +3 -41
  93. claude_mpm/hooks/claude_hooks/response_tracking.py +35 -1
  94. claude_mpm/hooks/instruction_reinforcement.py +7 -2
  95. claude_mpm/models/resume_log.py +340 -0
  96. claude_mpm/services/agents/auto_config_manager.py +10 -11
  97. claude_mpm/services/agents/deployment/agent_configuration_manager.py +1 -1
  98. claude_mpm/services/agents/deployment/agent_record_service.py +1 -1
  99. claude_mpm/services/agents/deployment/agent_validator.py +17 -1
  100. claude_mpm/services/agents/deployment/async_agent_deployment.py +1 -1
  101. claude_mpm/services/agents/deployment/interface_adapter.py +3 -2
  102. claude_mpm/services/agents/deployment/local_template_deployment.py +1 -1
  103. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +7 -6
  104. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +7 -16
  105. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +4 -3
  106. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +5 -3
  107. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +6 -5
  108. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +9 -6
  109. claude_mpm/services/agents/deployment/validation/__init__.py +3 -1
  110. claude_mpm/services/agents/deployment/validation/validation_result.py +1 -9
  111. claude_mpm/services/agents/local_template_manager.py +1 -1
  112. claude_mpm/services/agents/memory/agent_memory_manager.py +5 -2
  113. claude_mpm/services/agents/registry/modification_tracker.py +5 -2
  114. claude_mpm/services/command_handler_service.py +11 -5
  115. claude_mpm/services/core/interfaces/__init__.py +74 -2
  116. claude_mpm/services/core/interfaces/health.py +172 -0
  117. claude_mpm/services/core/interfaces/model.py +281 -0
  118. claude_mpm/services/core/interfaces/process.py +372 -0
  119. claude_mpm/services/core/interfaces/restart.py +307 -0
  120. claude_mpm/services/core/interfaces/stability.py +260 -0
  121. claude_mpm/services/core/models/__init__.py +33 -0
  122. claude_mpm/services/core/models/agent_config.py +12 -28
  123. claude_mpm/services/core/models/health.py +162 -0
  124. claude_mpm/services/core/models/process.py +235 -0
  125. claude_mpm/services/core/models/restart.py +302 -0
  126. claude_mpm/services/core/models/stability.py +264 -0
  127. claude_mpm/services/core/path_resolver.py +23 -7
  128. claude_mpm/services/diagnostics/__init__.py +2 -2
  129. claude_mpm/services/diagnostics/checks/agent_check.py +25 -24
  130. claude_mpm/services/diagnostics/checks/claude_code_check.py +24 -23
  131. claude_mpm/services/diagnostics/checks/common_issues_check.py +25 -24
  132. claude_mpm/services/diagnostics/checks/configuration_check.py +24 -23
  133. claude_mpm/services/diagnostics/checks/filesystem_check.py +18 -17
  134. claude_mpm/services/diagnostics/checks/installation_check.py +30 -29
  135. claude_mpm/services/diagnostics/checks/instructions_check.py +20 -19
  136. claude_mpm/services/diagnostics/checks/mcp_check.py +50 -36
  137. claude_mpm/services/diagnostics/checks/mcp_services_check.py +36 -31
  138. claude_mpm/services/diagnostics/checks/monitor_check.py +23 -22
  139. claude_mpm/services/diagnostics/checks/startup_log_check.py +9 -8
  140. claude_mpm/services/diagnostics/diagnostic_runner.py +6 -5
  141. claude_mpm/services/diagnostics/doctor_reporter.py +28 -25
  142. claude_mpm/services/diagnostics/models.py +19 -24
  143. claude_mpm/services/infrastructure/monitoring/__init__.py +1 -1
  144. claude_mpm/services/infrastructure/monitoring/aggregator.py +12 -12
  145. claude_mpm/services/infrastructure/monitoring/base.py +5 -13
  146. claude_mpm/services/infrastructure/monitoring/network.py +7 -6
  147. claude_mpm/services/infrastructure/monitoring/process.py +13 -12
  148. claude_mpm/services/infrastructure/monitoring/resources.py +7 -6
  149. claude_mpm/services/infrastructure/monitoring/service.py +16 -15
  150. claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
  151. claude_mpm/services/local_ops/__init__.py +163 -0
  152. claude_mpm/services/local_ops/crash_detector.py +257 -0
  153. claude_mpm/services/local_ops/health_checks/__init__.py +28 -0
  154. claude_mpm/services/local_ops/health_checks/http_check.py +224 -0
  155. claude_mpm/services/local_ops/health_checks/process_check.py +236 -0
  156. claude_mpm/services/local_ops/health_checks/resource_check.py +255 -0
  157. claude_mpm/services/local_ops/health_manager.py +430 -0
  158. claude_mpm/services/local_ops/log_monitor.py +396 -0
  159. claude_mpm/services/local_ops/memory_leak_detector.py +294 -0
  160. claude_mpm/services/local_ops/process_manager.py +595 -0
  161. claude_mpm/services/local_ops/resource_monitor.py +331 -0
  162. claude_mpm/services/local_ops/restart_manager.py +401 -0
  163. claude_mpm/services/local_ops/restart_policy.py +387 -0
  164. claude_mpm/services/local_ops/state_manager.py +372 -0
  165. claude_mpm/services/local_ops/unified_manager.py +600 -0
  166. claude_mpm/services/mcp_config_manager.py +9 -4
  167. claude_mpm/services/mcp_gateway/core/__init__.py +1 -2
  168. claude_mpm/services/mcp_gateway/core/base.py +18 -31
  169. claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +71 -24
  170. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +30 -28
  171. claude_mpm/services/memory_hook_service.py +4 -1
  172. claude_mpm/services/model/__init__.py +147 -0
  173. claude_mpm/services/model/base_provider.py +365 -0
  174. claude_mpm/services/model/claude_provider.py +412 -0
  175. claude_mpm/services/model/model_router.py +453 -0
  176. claude_mpm/services/model/ollama_provider.py +415 -0
  177. claude_mpm/services/monitor/daemon_manager.py +3 -2
  178. claude_mpm/services/monitor/handlers/dashboard.py +2 -1
  179. claude_mpm/services/monitor/handlers/hooks.py +2 -1
  180. claude_mpm/services/monitor/management/lifecycle.py +3 -2
  181. claude_mpm/services/monitor/server.py +2 -1
  182. claude_mpm/services/session_management_service.py +3 -2
  183. claude_mpm/services/session_manager.py +205 -1
  184. claude_mpm/services/shared/async_service_base.py +16 -27
  185. claude_mpm/services/shared/lifecycle_service_base.py +1 -14
  186. claude_mpm/services/socketio/handlers/__init__.py +5 -2
  187. claude_mpm/services/socketio/handlers/hook.py +13 -2
  188. claude_mpm/services/socketio/handlers/registry.py +4 -2
  189. claude_mpm/services/socketio/server/main.py +10 -8
  190. claude_mpm/services/subprocess_launcher_service.py +14 -5
  191. claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +8 -7
  192. claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +6 -5
  193. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +8 -7
  194. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +7 -6
  195. claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +5 -4
  196. claude_mpm/services/unified/config_strategies/validation_strategy.py +13 -9
  197. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +10 -3
  198. claude_mpm/services/unified/deployment_strategies/local.py +6 -5
  199. claude_mpm/services/unified/deployment_strategies/utils.py +6 -5
  200. claude_mpm/services/unified/deployment_strategies/vercel.py +7 -6
  201. claude_mpm/services/unified/interfaces.py +3 -1
  202. claude_mpm/services/unified/unified_analyzer.py +14 -10
  203. claude_mpm/services/unified/unified_config.py +2 -1
  204. claude_mpm/services/unified/unified_deployment.py +9 -4
  205. claude_mpm/services/version_service.py +104 -1
  206. claude_mpm/skills/__init__.py +21 -0
  207. claude_mpm/skills/bundled/__init__.py +6 -0
  208. claude_mpm/skills/bundled/api-documentation.md +393 -0
  209. claude_mpm/skills/bundled/async-testing.md +571 -0
  210. claude_mpm/skills/bundled/code-review.md +143 -0
  211. claude_mpm/skills/bundled/database-migration.md +199 -0
  212. claude_mpm/skills/bundled/docker-containerization.md +194 -0
  213. claude_mpm/skills/bundled/express-local-dev.md +1429 -0
  214. claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
  215. claude_mpm/skills/bundled/git-workflow.md +414 -0
  216. claude_mpm/skills/bundled/imagemagick.md +204 -0
  217. claude_mpm/skills/bundled/json-data-handling.md +223 -0
  218. claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
  219. claude_mpm/skills/bundled/pdf.md +141 -0
  220. claude_mpm/skills/bundled/performance-profiling.md +567 -0
  221. claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
  222. claude_mpm/skills/bundled/security-scanning.md +327 -0
  223. claude_mpm/skills/bundled/systematic-debugging.md +473 -0
  224. claude_mpm/skills/bundled/test-driven-development.md +378 -0
  225. claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
  226. claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
  227. claude_mpm/skills/bundled/xlsx.md +157 -0
  228. claude_mpm/skills/registry.py +286 -0
  229. claude_mpm/skills/skill_manager.py +310 -0
  230. claude_mpm/tools/code_tree_analyzer.py +177 -141
  231. claude_mpm/tools/code_tree_events.py +4 -2
  232. claude_mpm/utils/agent_dependency_loader.py +2 -2
  233. {claude_mpm-4.13.2.dist-info → claude_mpm-4.18.2.dist-info}/METADATA +117 -8
  234. {claude_mpm-4.13.2.dist-info → claude_mpm-4.18.2.dist-info}/RECORD +238 -174
  235. claude_mpm/dashboard/static/css/code-tree.css +0 -1639
  236. claude_mpm/dashboard/static/js/components/code-tree/tree-breadcrumb.js +0 -353
  237. claude_mpm/dashboard/static/js/components/code-tree/tree-constants.js +0 -235
  238. claude_mpm/dashboard/static/js/components/code-tree/tree-search.js +0 -409
  239. claude_mpm/dashboard/static/js/components/code-tree/tree-utils.js +0 -435
  240. claude_mpm/dashboard/static/js/components/code-tree.js +0 -5869
  241. claude_mpm/dashboard/static/js/components/code-viewer.js +0 -1386
  242. claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +0 -425
  243. claude_mpm/hooks/claude_hooks/hook_handler_original.py +0 -1041
  244. claude_mpm/hooks/claude_hooks/hook_handler_refactored.py +0 -347
  245. claude_mpm/services/agents/deployment/agent_lifecycle_manager_refactored.py +0 -575
  246. claude_mpm/services/project/analyzer_refactored.py +0 -450
  247. {claude_mpm-4.13.2.dist-info → claude_mpm-4.18.2.dist-info}/WHEEL +0 -0
  248. {claude_mpm-4.13.2.dist-info → claude_mpm-4.18.2.dist-info}/entry_points.txt +0 -0
  249. {claude_mpm-4.13.2.dist-info → claude_mpm-4.18.2.dist-info}/licenses/LICENSE +0 -0
  250. {claude_mpm-4.13.2.dist-info → claude_mpm-4.18.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,18 @@
1
+ """Data models for configure command.
2
+
3
+ This module contains data classes used by the configure command for
4
+ agent metadata and configuration state management.
5
+ """
6
+
7
+ from typing import List, Optional
8
+
9
+
10
+ class AgentConfig:
11
+ """Simple agent configuration model."""
12
+
13
+ def __init__(
14
+ self, name: str, description: str = "", dependencies: Optional[List[str]] = None
15
+ ):
16
+ self.name = name
17
+ self.description = description
18
+ self.dependencies = dependencies or []
@@ -0,0 +1,167 @@
1
+ """Navigation and scope management for configure command.
2
+
3
+ WHY: Separate navigation, scope switching, and menu display logic from main
4
+ configure command to improve modularity. This handles the TUI interface
5
+ elements that guide users through the configuration system.
6
+
7
+ DESIGN DECISIONS:
8
+ - Display header with version and scope info
9
+ - Main menu with numbered options and descriptions
10
+ - Scope switching between project and user configurations
11
+ - Launch integration to transition to Claude MPM run
12
+ """
13
+
14
+ import os
15
+ from pathlib import Path
16
+
17
+ from rich.box import ROUNDED
18
+ from rich.columns import Columns
19
+ from rich.console import Console
20
+ from rich.panel import Panel
21
+ from rich.prompt import Prompt
22
+ from rich.table import Table
23
+ from rich.text import Text
24
+
25
+
26
+ class ConfigNavigation:
27
+ """Handle scope switching and navigation for configure command.
28
+
29
+ This class manages:
30
+ - Header display with version and scope information
31
+ - Main menu rendering with options
32
+ - Scope switching (project ↔ user)
33
+ - Claude MPM launch integration
34
+ """
35
+
36
+ def __init__(self, console: Console, project_dir: Path):
37
+ """Initialize navigation handler.
38
+
39
+ Args:
40
+ console: Rich console for output
41
+ project_dir: Current project directory
42
+ """
43
+ self.console = console
44
+ self.project_dir = project_dir
45
+ self.current_scope = "project"
46
+
47
+ def display_header(self) -> None:
48
+ """Display the TUI header with version and scope information.
49
+
50
+ Shows:
51
+ - Claude MPM branding and version
52
+ - Current configuration scope (project/user)
53
+ - Working directory
54
+ """
55
+ self.console.clear()
56
+
57
+ # Get version for display
58
+ from claude_mpm import __version__
59
+
60
+ # Create header panel
61
+ header_text = Text()
62
+ header_text.append("Claude MPM ", style="bold blue")
63
+ header_text.append("Configuration Interface", style="bold")
64
+ header_text.append(f"\nv{__version__}", style="dim blue")
65
+
66
+ scope_text = Text(f"Scope: {self.current_scope.upper()}", style="bold blue")
67
+ dir_text = Text(f"Directory: {self.project_dir}", style="dim")
68
+
69
+ header_content = Columns([header_text], align="center")
70
+ subtitle_content = f"{scope_text} | {dir_text}"
71
+
72
+ header_panel = Panel(
73
+ header_content,
74
+ subtitle=subtitle_content,
75
+ box=ROUNDED,
76
+ style="blue",
77
+ padding=(1, 2),
78
+ )
79
+
80
+ self.console.print(header_panel)
81
+ self.console.print()
82
+
83
+ def show_main_menu(self) -> str:
84
+ """Show the main menu and get user choice.
85
+
86
+ Displays main configuration menu with options:
87
+ 1. Agent Management
88
+ 2. Skills Management
89
+ 3. Template Editing
90
+ 4. Behavior Files
91
+ 5. Startup Configuration
92
+ 6. Switch Scope
93
+ 7. Version Info
94
+ l. Save & Launch
95
+ q. Quit
96
+
97
+ Returns:
98
+ User's menu choice (lowercase, stripped)
99
+ """
100
+ menu_items = [
101
+ ("1", "Agent Management", "Enable/disable agents and customize settings"),
102
+ ("2", "Skills Management", "Configure skills for agents"),
103
+ ("3", "Template Editing", "Edit agent JSON templates"),
104
+ ("4", "Behavior Files", "Manage identity and workflow configurations"),
105
+ (
106
+ "5",
107
+ "Startup Configuration",
108
+ "Configure MCP services and agents to start",
109
+ ),
110
+ ("6", "Switch Scope", f"Current: {self.current_scope}"),
111
+ ("7", "Version Info", "Display MPM and Claude versions"),
112
+ ("l", "Save & Launch", "Save all changes and start Claude MPM"),
113
+ ("q", "Quit", "Exit without launching"),
114
+ ]
115
+
116
+ table = Table(show_header=False, box=None, padding=(0, 2))
117
+ table.add_column("Key", style="bold blue", width=4) # Bolder shortcuts
118
+ table.add_column("Option", style="bold", width=24) # Wider for titles
119
+ table.add_column("Description", style="") # Use default terminal color
120
+
121
+ for key, option, desc in menu_items:
122
+ table.add_row(f"\\[{key}]", option, desc)
123
+
124
+ menu_panel = Panel(
125
+ table, title="[bold]Main Menu[/bold]", box=ROUNDED, style="green"
126
+ )
127
+
128
+ self.console.print(menu_panel)
129
+ self.console.print()
130
+
131
+ choice = Prompt.ask("[bold blue]Select an option[/bold blue]", default="q")
132
+ # Strip whitespace to handle leading/trailing spaces
133
+ return choice.strip().lower()
134
+
135
+ def switch_scope(self) -> None:
136
+ """Switch between project and user scope.
137
+
138
+ Toggles current_scope between:
139
+ - "project": Project-level configuration (.claude-mpm in project dir)
140
+ - "user": User-level configuration (.claude-mpm in home dir)
141
+ """
142
+ self.current_scope = "user" if self.current_scope == "project" else "project"
143
+ self.console.print(f"[green]Switched to {self.current_scope} scope[/green]")
144
+ Prompt.ask("Press Enter to continue")
145
+
146
+ def launch_claude_mpm(self) -> None:
147
+ """Launch Claude MPM run command, replacing current process.
148
+
149
+ Uses os.execvp to replace the configure process with 'claude-mpm run',
150
+ providing a seamless transition from configuration to runtime.
151
+
152
+ If launch fails, displays instructions for manual launch.
153
+ """
154
+ self.console.print("\n[bold cyan]═══ Launching Claude MPM ═══[/bold cyan]\n")
155
+
156
+ try:
157
+ # Use execvp to replace the current process with claude-mpm run
158
+ # This ensures a clean transition from configurator to Claude MPM
159
+ os.execvp("claude-mpm", ["claude-mpm", "run"])
160
+ except Exception as e:
161
+ self.console.print(
162
+ f"[yellow]⚠ Could not launch Claude MPM automatically: {e}[/yellow]"
163
+ )
164
+ self.console.print(
165
+ "[cyan]→ Please run 'claude-mpm run' manually to start.[/cyan]"
166
+ )
167
+ Prompt.ask("\nPress Enter to exit")
@@ -0,0 +1,104 @@
1
+ """Path resolution utilities for configure command.
2
+
3
+ WHY: Centralizes path resolution logic for agent templates, configs, and system files.
4
+ Separates file system concerns from business logic.
5
+
6
+ DESIGN: Pure functions for path resolution without side effects (except mkdir).
7
+ """
8
+
9
+ from pathlib import Path
10
+
11
+
12
+ def get_agent_template_path(
13
+ agent_name: str,
14
+ scope: str,
15
+ project_dir: Path,
16
+ templates_dir: Path,
17
+ ) -> Path:
18
+ """Get the path to an agent's template file.
19
+
20
+ Args:
21
+ agent_name: Name of the agent
22
+ scope: Configuration scope ("project" or "user")
23
+ project_dir: Project directory path
24
+ templates_dir: System templates directory
25
+
26
+ Returns:
27
+ Path to the agent template file
28
+ """
29
+ # First check for custom template in project/user config
30
+ if scope == "project":
31
+ config_dir = project_dir / ".claude-mpm" / "agents"
32
+ else:
33
+ config_dir = Path.home() / ".claude-mpm" / "agents"
34
+
35
+ config_dir.mkdir(parents=True, exist_ok=True)
36
+ custom_template = config_dir / f"{agent_name}.json"
37
+
38
+ # If custom template exists, return it
39
+ if custom_template.exists():
40
+ return custom_template
41
+
42
+ # Otherwise, look for the system template
43
+ # Handle various naming conventions
44
+ possible_names = [
45
+ f"{agent_name}.json",
46
+ f"{agent_name.replace('-', '_')}.json",
47
+ f"{agent_name}-agent.json",
48
+ f"{agent_name.replace('-', '_')}_agent.json",
49
+ ]
50
+
51
+ for name in possible_names:
52
+ system_template = templates_dir / name
53
+ if system_template.exists():
54
+ return system_template
55
+
56
+ # Return the custom template path for new templates
57
+ return custom_template
58
+
59
+
60
+ def get_config_directory(scope: str, project_dir: Path) -> Path:
61
+ """Get configuration directory based on scope.
62
+
63
+ Args:
64
+ scope: Configuration scope ("project" or "user")
65
+ project_dir: Project directory path
66
+
67
+ Returns:
68
+ Path to configuration directory
69
+ """
70
+ if scope == "project":
71
+ return project_dir / ".claude-mpm"
72
+ return Path.home() / ".claude-mpm"
73
+
74
+
75
+ def get_agents_directory(scope: str, project_dir: Path) -> Path:
76
+ """Get agents directory based on scope.
77
+
78
+ Args:
79
+ scope: Configuration scope ("project" or "user")
80
+ project_dir: Project directory path
81
+
82
+ Returns:
83
+ Path to agents directory
84
+ """
85
+ config_dir = get_config_directory(scope, project_dir)
86
+ agents_dir = config_dir / "agents"
87
+ agents_dir.mkdir(parents=True, exist_ok=True)
88
+ return agents_dir
89
+
90
+
91
+ def get_behaviors_directory(scope: str, project_dir: Path) -> Path:
92
+ """Get behaviors directory based on scope.
93
+
94
+ Args:
95
+ scope: Configuration scope ("project" or "user")
96
+ project_dir: Project directory path
97
+
98
+ Returns:
99
+ Path to behaviors directory
100
+ """
101
+ config_dir = get_config_directory(scope, project_dir)
102
+ behaviors_dir = config_dir / "behaviors"
103
+ behaviors_dir.mkdir(parents=True, exist_ok=True)
104
+ return behaviors_dir
@@ -0,0 +1,254 @@
1
+ """Configuration persistence and version management for configure command.
2
+
3
+ WHY: Separate configuration import/export and version display logic from main
4
+ configure command to improve modularity. This handles all file I/O for
5
+ configuration backups and version information display.
6
+
7
+ DESIGN DECISIONS:
8
+ - Export/import configuration as JSON for portability
9
+ - Display version info for both MPM and Claude Code
10
+ - Support interactive and non-interactive modes
11
+ - Include validation for import operations
12
+ """
13
+
14
+ import json
15
+ import subprocess
16
+ import sys
17
+ from pathlib import Path
18
+
19
+ from rich.box import ROUNDED
20
+ from rich.console import Console
21
+ from rich.panel import Panel
22
+ from rich.prompt import Prompt
23
+
24
+ from ..shared import CommandResult
25
+
26
+
27
+ class ConfigPersistence:
28
+ """Handle configuration import/export and version information display.
29
+
30
+ This class manages:
31
+ - Exporting configuration to JSON files
32
+ - Importing configuration from JSON files
33
+ - Displaying version information (MPM, Claude Code, Python)
34
+ - Both interactive and non-interactive display modes
35
+ """
36
+
37
+ def __init__(
38
+ self,
39
+ console: Console,
40
+ version_service, # VersionService instance
41
+ agent_manager, # SimpleAgentManager instance (can be None for version operations)
42
+ get_template_path_fn, # Function to get template path
43
+ display_header_fn, # Function to display header
44
+ current_scope: str,
45
+ project_dir: Path,
46
+ ):
47
+ """Initialize persistence handler.
48
+
49
+ Args:
50
+ console: Rich console for output
51
+ version_service: VersionService for version info
52
+ agent_manager: SimpleAgentManager for agent states (can be None for version operations)
53
+ get_template_path_fn: Function(agent_name) -> Path
54
+ display_header_fn: Function() -> None to display header
55
+ current_scope: Current configuration scope (project/user)
56
+ project_dir: Current project directory
57
+ """
58
+ self.console = console
59
+ self.version_service = version_service
60
+ self.agent_manager = agent_manager
61
+ self._get_agent_template_path = get_template_path_fn
62
+ self._display_header = display_header_fn
63
+ self.current_scope = current_scope
64
+ self.project_dir = project_dir
65
+
66
+ def export_config(self, file_path: str) -> CommandResult:
67
+ """Export configuration to a JSON file.
68
+
69
+ Exports:
70
+ - Current scope (project/user)
71
+ - Agent enabled/disabled states
72
+ - Template paths for each agent
73
+
74
+ Args:
75
+ file_path: Path to export configuration to
76
+
77
+ Returns:
78
+ CommandResult indicating success or failure
79
+ """
80
+ try:
81
+ # Gather all configuration
82
+ config_data = {"scope": self.current_scope, "agents": {}, "behaviors": {}}
83
+
84
+ # Get agent states
85
+ agents = self.agent_manager.discover_agents()
86
+ for agent in agents:
87
+ config_data["agents"][agent.name] = {
88
+ "enabled": self.agent_manager.is_agent_enabled(agent.name),
89
+ "template_path": str(self._get_agent_template_path(agent.name)),
90
+ }
91
+
92
+ # Write to file
93
+ output_path = Path(file_path)
94
+ with output_path.open("w") as f:
95
+ json.dump(config_data, f, indent=2)
96
+
97
+ return CommandResult.success_result(
98
+ f"Configuration exported to {output_path}"
99
+ )
100
+
101
+ except Exception as e:
102
+ return CommandResult.error_result(f"Failed to export configuration: {e}")
103
+
104
+ def import_config(self, file_path: str) -> CommandResult:
105
+ """Import configuration from a JSON file.
106
+
107
+ Imports and applies:
108
+ - Agent enabled/disabled states
109
+ - (Future: behavior configurations)
110
+
111
+ Args:
112
+ file_path: Path to import configuration from
113
+
114
+ Returns:
115
+ CommandResult indicating success or failure
116
+ """
117
+ try:
118
+ input_path = Path(file_path)
119
+ if not input_path.exists():
120
+ return CommandResult.error_result(f"File not found: {file_path}")
121
+
122
+ with input_path.open() as f:
123
+ config_data = json.load(f)
124
+
125
+ # Apply agent states
126
+ if "agents" in config_data:
127
+ for agent_name, agent_config in config_data["agents"].items():
128
+ if "enabled" in agent_config:
129
+ self.agent_manager.set_agent_enabled(
130
+ agent_name, agent_config["enabled"]
131
+ )
132
+
133
+ return CommandResult.success_result(
134
+ f"Configuration imported from {input_path}"
135
+ )
136
+
137
+ except Exception as e:
138
+ return CommandResult.error_result(f"Failed to import configuration: {e}")
139
+
140
+ def show_version_info(self) -> CommandResult:
141
+ """Show version information in non-interactive mode.
142
+
143
+ Displays:
144
+ - Claude MPM version and build number
145
+ - Claude Code version (if available)
146
+ - Python version
147
+
148
+ Returns:
149
+ CommandResult with version data
150
+ """
151
+ mpm_version = self.version_service.get_version()
152
+ build_number = self.version_service.get_build_number()
153
+
154
+ data = {
155
+ "mpm_version": mpm_version,
156
+ "build_number": build_number,
157
+ "python_version": sys.version.split()[0],
158
+ }
159
+
160
+ # Try to get Claude version
161
+ try:
162
+ result = subprocess.run(
163
+ ["claude", "--version"],
164
+ capture_output=True,
165
+ text=True,
166
+ timeout=5,
167
+ check=False,
168
+ )
169
+ if result.returncode == 0:
170
+ data["claude_version"] = result.stdout.strip()
171
+ except Exception:
172
+ data["claude_version"] = "Unknown"
173
+
174
+ # Print formatted output
175
+ self.console.print(
176
+ f"[bold]Claude MPM:[/bold] {mpm_version} (build {build_number})"
177
+ )
178
+ self.console.print(
179
+ f"[bold]Claude Code:[/bold] {data.get('claude_version', 'Unknown')}"
180
+ )
181
+ self.console.print(f"[bold]Python:[/bold] {data['python_version']}")
182
+
183
+ return CommandResult.success_result("Version information displayed", data=data)
184
+
185
+ def show_version_info_interactive(self) -> None:
186
+ """Show version information in interactive mode with panel display.
187
+
188
+ Displays comprehensive version information in a formatted panel:
189
+ - Claude MPM version and build number
190
+ - Claude Code version with compatibility info
191
+ - Python version
192
+ - Current configuration scope and directory
193
+ """
194
+ self.console.clear()
195
+ self._display_header()
196
+
197
+ # Get version information
198
+ mpm_version = self.version_service.get_version()
199
+ build_number = self.version_service.get_build_number()
200
+
201
+ # Try to get Claude Code version using the installer's method
202
+ claude_version = "Unknown"
203
+ try:
204
+ from ...hooks.claude_hooks.installer import HookInstaller
205
+
206
+ installer = HookInstaller()
207
+ detected_version = installer.get_claude_version()
208
+ if detected_version:
209
+ is_compatible, _ = installer.is_version_compatible()
210
+ claude_version = f"{detected_version} (Claude Code)"
211
+ if not is_compatible:
212
+ claude_version += (
213
+ f" - Monitoring requires {installer.MIN_CLAUDE_VERSION}+"
214
+ )
215
+ else:
216
+ # Fallback to direct subprocess call
217
+ result = subprocess.run(
218
+ ["claude", "--version"],
219
+ capture_output=True,
220
+ text=True,
221
+ timeout=5,
222
+ check=False,
223
+ )
224
+ if result.returncode == 0:
225
+ claude_version = result.stdout.strip()
226
+ except Exception:
227
+ pass
228
+
229
+ # Create version panel
230
+ version_text = f"""
231
+ [bold cyan]Claude MPM[/bold cyan]
232
+ Version: {mpm_version}
233
+ Build: {build_number}
234
+
235
+ [bold cyan]Claude Code[/bold cyan]
236
+ Version: {claude_version}
237
+
238
+ [bold cyan]Python[/bold cyan]
239
+ Version: {sys.version.split()[0]}
240
+
241
+ [bold cyan]Configuration[/bold cyan]
242
+ Scope: {self.current_scope}
243
+ Directory: {self.project_dir}
244
+ """
245
+
246
+ panel = Panel(
247
+ version_text.strip(),
248
+ title="[bold]Version Information[/bold]",
249
+ box=ROUNDED,
250
+ style="green",
251
+ )
252
+
253
+ self.console.print(panel)
254
+ Prompt.ask("\nPress Enter to continue")