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
@@ -16,6 +16,7 @@ import os
16
16
  from pathlib import Path
17
17
  from typing import Any, Dict
18
18
 
19
+ from ...core.enums import OutputFormat
19
20
  from ...core.shared.config_loader import ConfigLoader
20
21
  from ...services.agents.memory import AgentMemoryManager
21
22
  from ...services.cli.memory_crud_service import MemoryCRUDService
@@ -23,6 +24,14 @@ from ...services.cli.memory_output_formatter import MemoryOutputFormatter
23
24
  from ..shared.base_command import CommandResult, MemoryCommand
24
25
 
25
26
 
27
+ def _is_structured_output(args) -> bool:
28
+ """Check if args specify structured output format (JSON/YAML)."""
29
+ if hasattr(args, "format"):
30
+ fmt = str(args.format).lower()
31
+ return fmt in (OutputFormat.JSON, OutputFormat.YAML)
32
+ return False
33
+
34
+
26
35
  class MemoryManagementCommand(MemoryCommand):
27
36
  """Memory management command using shared utilities."""
28
37
 
@@ -60,6 +69,31 @@ class MemoryManagementCommand(MemoryCommand):
60
69
  self._crud_service = MemoryCRUDService(memory_manager=self.memory_manager)
61
70
  return self._crud_service
62
71
 
72
+ def _get_output_format(self, args) -> str:
73
+ """
74
+ Get output format from args with enum default.
75
+
76
+ Args:
77
+ args: Command arguments
78
+
79
+ Returns:
80
+ Output format string (compatible with both enum and string usage)
81
+ """
82
+ return getattr(args, "format", OutputFormat.TEXT)
83
+
84
+ def _is_structured_format(self, format_str: str) -> bool:
85
+ """
86
+ Check if format is structured (JSON/YAML).
87
+
88
+ Args:
89
+ format_str: Format string to check
90
+
91
+ Returns:
92
+ True if format is JSON or YAML
93
+ """
94
+ fmt = str(format_str).lower()
95
+ return fmt in (OutputFormat.JSON, OutputFormat.YAML)
96
+
63
97
  def validate_args(self, args) -> str:
64
98
  """Validate command arguments."""
65
99
  # Check if memory command is valid
@@ -104,8 +138,8 @@ class MemoryManagementCommand(MemoryCommand):
104
138
  available_commands = list(command_map.keys())
105
139
  error_msg = f"Unknown memory command: {args.memory_command}"
106
140
 
107
- output_format = getattr(args, "format", "text")
108
- if output_format in ["json", "yaml"]:
141
+ output_format = self._get_output_format(args)
142
+ if self._is_structured_format(output_format):
109
143
  return CommandResult.error_result(
110
144
  error_msg, data={"available_commands": available_commands}
111
145
  )
@@ -120,9 +154,9 @@ class MemoryManagementCommand(MemoryCommand):
120
154
  def _show_status(self, args) -> CommandResult:
121
155
  """Show memory system status."""
122
156
  try:
123
- output_format = getattr(args, "format", "text")
157
+ output_format = self._get_output_format(args)
124
158
 
125
- if output_format in ["json", "yaml"]:
159
+ if self._is_structured_format(output_format):
126
160
  # Structured output
127
161
  status_data = self._get_status_data()
128
162
  return CommandResult.success_result(
@@ -175,7 +209,7 @@ class MemoryManagementCommand(MemoryCommand):
175
209
  def _show_memories(self, args) -> CommandResult:
176
210
  """Show agent memories."""
177
211
  try:
178
- output_format = getattr(args, "format", "text")
212
+ output_format = self._get_output_format(args)
179
213
  agent_id = getattr(args, "agent_id", None)
180
214
  raw_output = getattr(args, "raw", False)
181
215
 
@@ -245,7 +279,7 @@ class MemoryManagementCommand(MemoryCommand):
245
279
  def _init_memory(self, args) -> CommandResult:
246
280
  """Initialize project-specific memories."""
247
281
  try:
248
- output_format = getattr(args, "format", "text")
282
+ output_format = self._get_output_format(args)
249
283
 
250
284
  # Use CRUD service for initialization task
251
285
  result = self.crud_service.init_project_memories()
@@ -255,7 +289,7 @@ class MemoryManagementCommand(MemoryCommand):
255
289
  result.get("error", "Failed to create initialization task")
256
290
  )
257
291
 
258
- if output_format in ["json", "yaml"]:
292
+ if self._is_structured_format(output_format):
259
293
  # Return structured task data
260
294
  return CommandResult.success_result(
261
295
  "Memory initialization task created", data=result.get("task_data")
@@ -293,7 +327,7 @@ class MemoryManagementCommand(MemoryCommand):
293
327
  def _add_learning(self, args) -> CommandResult:
294
328
  """Add learning to agent memory."""
295
329
  try:
296
- output_format = getattr(args, "format", "text")
330
+ output_format = self._get_output_format(args)
297
331
 
298
332
  # Extract arguments
299
333
  agent_id = getattr(args, "agent_id", None)
@@ -313,7 +347,7 @@ class MemoryManagementCommand(MemoryCommand):
313
347
  result.get("error", "Failed to add learning")
314
348
  )
315
349
 
316
- if output_format in ["json", "yaml"]:
350
+ if self._is_structured_format(output_format):
317
351
  # Return structured result
318
352
  return CommandResult.success_result(
319
353
  "Learning added to agent memory", data=result
@@ -333,7 +367,7 @@ class MemoryManagementCommand(MemoryCommand):
333
367
  def _clean_memory(self, args) -> CommandResult:
334
368
  """Clean up old/unused memory files."""
335
369
  try:
336
- output_format = getattr(args, "format", "text")
370
+ output_format = self._get_output_format(args)
337
371
  agent_id = getattr(args, "agent_id", None)
338
372
  dry_run = getattr(args, "dry_run", True)
339
373
 
@@ -343,7 +377,7 @@ class MemoryManagementCommand(MemoryCommand):
343
377
  if not result.get("success"):
344
378
  return CommandResult.error_result(result.get("error", "Cleanup failed"))
345
379
 
346
- if output_format in ["json", "yaml"]:
380
+ if self._is_structured_format(output_format):
347
381
  # Return structured cleanup results
348
382
  return CommandResult.success_result(
349
383
  result.get("message", "Memory cleanup completed"), data=result
@@ -384,10 +418,10 @@ class MemoryManagementCommand(MemoryCommand):
384
418
  def _optimize_memory(self, args) -> CommandResult:
385
419
  """Optimize memory files."""
386
420
  try:
387
- output_format = getattr(args, "format", "text")
421
+ output_format = self._get_output_format(args)
388
422
  agent_id = getattr(args, "agent_id", None)
389
423
 
390
- if output_format in ["json", "yaml"]:
424
+ if self._is_structured_format(output_format):
391
425
  # For structured output, perform optimization and return results
392
426
  if agent_id:
393
427
  result = self.memory_manager.optimize_memory(agent_id)
@@ -419,9 +453,9 @@ class MemoryManagementCommand(MemoryCommand):
419
453
  def _build_memory(self, args) -> CommandResult:
420
454
  """Build agent memories from project documentation."""
421
455
  try:
422
- output_format = getattr(args, "format", "text")
456
+ output_format = self._get_output_format(args)
423
457
 
424
- if output_format in ["json", "yaml"]:
458
+ if self._is_structured_format(output_format):
425
459
  # For structured output, return build results
426
460
  build_data = {
427
461
  "built_memories": [],
@@ -442,9 +476,9 @@ class MemoryManagementCommand(MemoryCommand):
442
476
  def _cross_reference_memory(self, args) -> CommandResult:
443
477
  """Find cross-references and common patterns."""
444
478
  try:
445
- output_format = getattr(args, "format", "text")
479
+ output_format = self._get_output_format(args)
446
480
 
447
- if output_format in ["json", "yaml"]:
481
+ if self._is_structured_format(output_format):
448
482
  # For structured output, return cross-reference results
449
483
  crossref_data = {
450
484
  "common_patterns": [],
@@ -465,9 +499,9 @@ class MemoryManagementCommand(MemoryCommand):
465
499
  def _route_memory_command(self, args) -> CommandResult:
466
500
  """Route memory command to appropriate agent."""
467
501
  try:
468
- output_format = getattr(args, "format", "text")
502
+ output_format = self._get_output_format(args)
469
503
 
470
- if output_format in ["json", "yaml"]:
504
+ if self._is_structured_format(output_format):
471
505
  # For structured output, return routing results
472
506
  routing_data = {
473
507
  "routed_to": "memory_agent",
@@ -495,7 +529,7 @@ def manage_memory(args) -> int:
495
529
  result = command.execute(args)
496
530
 
497
531
  # Print result if structured output format is requested
498
- if hasattr(args, "format") and args.format in ["json", "yaml"]:
532
+ if _is_structured_output(args):
499
533
  command.print_result(result, args)
500
534
 
501
535
  return result.exit_code
@@ -20,6 +20,7 @@ from rich.panel import Panel
20
20
  from rich.progress import Progress, SpinnerColumn, TextColumn
21
21
  from rich.prompt import Prompt
22
22
 
23
+ from claude_mpm.core.enums import OperationResult
23
24
  from claude_mpm.core.logging_utils import get_logger
24
25
 
25
26
  # Import new services
@@ -102,7 +103,11 @@ class MPMInitCommand:
102
103
  if catchup:
103
104
  data = self._catchup()
104
105
  self._display_catchup(data)
105
- return {"status": "success", "mode": "catchup", "catchup_data": data}
106
+ return {
107
+ "status": OperationResult.SUCCESS,
108
+ "mode": "catchup",
109
+ "catchup_data": data,
110
+ }
106
111
 
107
112
  if quick_update:
108
113
  return self._run_quick_update_mode(
@@ -139,7 +144,7 @@ class MPMInitCommand:
139
144
  return self._run_review_mode()
140
145
  else:
141
146
  return {
142
- "status": "cancelled",
147
+ "status": OperationResult.CANCELLED,
143
148
  "message": "Initialization cancelled",
144
149
  }
145
150
 
@@ -152,7 +157,7 @@ class MPMInitCommand:
152
157
  pre_check_result = self._run_pre_initialization_checks(
153
158
  organize_files, skip_archive, has_existing
154
159
  )
155
- if pre_check_result.get("status") == "error":
160
+ if pre_check_result.get("status") == OperationResult.ERROR:
156
161
  return pre_check_result
157
162
 
158
163
  # Build the delegation prompt
@@ -195,7 +200,7 @@ class MPMInitCommand:
195
200
  progress.update(task, description=complete_desc)
196
201
 
197
202
  # Post-processing for update mode
198
- if update_mode and result.get("status") == "success":
203
+ if update_mode and result.get("status") == OperationResult.SUCCESS:
199
204
  self._handle_update_post_processing()
200
205
 
201
206
  return result
@@ -203,7 +208,7 @@ class MPMInitCommand:
203
208
  except Exception as e:
204
209
  logger.error(f"Failed to initialize project: {e}")
205
210
  console.print(f"[red]❌ Error: {e}[/red]")
206
- return {"status": "error", "message": str(e)}
211
+ return {"status": OperationResult.ERROR, "message": str(e)}
207
212
 
208
213
  def _find_claude_mpm_script(self) -> Path:
209
214
  """Find the claude-mpm script location."""
@@ -484,7 +489,7 @@ The final CLAUDE.md should be a comprehensive, well-organized guide that any AI
484
489
  )
485
490
 
486
491
  return {
487
- "status": "success",
492
+ "status": OperationResult.SUCCESS,
488
493
  "mode": "review",
489
494
  "structure_report": structure_report,
490
495
  "documentation_analysis": doc_analysis,
@@ -576,7 +581,7 @@ The final CLAUDE.md should be a comprehensive, well-organized guide that any AI
576
581
  "[dim]Tip: Use `/mpm-init --review` for non-git projects.[/dim]\n"
577
582
  )
578
583
  return {
579
- "status": "error",
584
+ "status": OperationResult.ERROR,
580
585
  "message": "Quick update requires a git repository",
581
586
  }
582
587
 
@@ -589,7 +594,7 @@ The final CLAUDE.md should be a comprehensive, well-organized guide that any AI
589
594
  "[dim]Tip: Use `/mpm-init` to create initial documentation.[/dim]\n"
590
595
  )
591
596
  return {
592
- "status": "error",
597
+ "status": OperationResult.ERROR,
593
598
  "message": "Quick update requires existing CLAUDE.md",
594
599
  }
595
600
 
@@ -631,7 +636,7 @@ The final CLAUDE.md should be a comprehensive, well-organized guide that any AI
631
636
  "\n[cyan]ℹ️ Non-interactive mode: Report displayed, no changes made.[/cyan]"
632
637
  )
633
638
  return {
634
- "status": "success",
639
+ "status": OperationResult.SUCCESS,
635
640
  "mode": "quick_update",
636
641
  "activity_report": activity_report,
637
642
  "changes_made": False,
@@ -659,7 +664,7 @@ The final CLAUDE.md should be a comprehensive, well-organized guide that any AI
659
664
  )
660
665
 
661
666
  return {
662
- "status": "success",
667
+ "status": OperationResult.SUCCESS,
663
668
  "mode": "quick_update",
664
669
  "activity_report": activity_report,
665
670
  "changes_made": True,
@@ -667,13 +672,16 @@ The final CLAUDE.md should be a comprehensive, well-organized guide that any AI
667
672
  if choice == "2":
668
673
  console.print("\n[cyan]Report generated - no changes made[/cyan]")
669
674
  return {
670
- "status": "success",
675
+ "status": OperationResult.SUCCESS,
671
676
  "mode": "quick_update",
672
677
  "activity_report": activity_report,
673
678
  "changes_made": False,
674
679
  }
675
680
  console.print("\n[yellow]Quick update cancelled[/yellow]")
676
- return {"status": "cancelled", "message": "Quick update cancelled"}
681
+ return {
682
+ "status": OperationResult.CANCELLED,
683
+ "message": "Quick update cancelled",
684
+ }
677
685
 
678
686
  def _catchup(self) -> Dict[str, Any]:
679
687
  """Get recent commit history for PM context.
@@ -1150,7 +1158,7 @@ The final CLAUDE.md should be a comprehensive, well-organized guide that any AI
1150
1158
  console.print("\n[dim]Run without --dry-run to execute these changes.[/dim]\n")
1151
1159
 
1152
1160
  return {
1153
- "status": "success",
1161
+ "status": OperationResult.SUCCESS,
1154
1162
  "mode": "dry_run",
1155
1163
  "actions_planned": actions_planned,
1156
1164
  "message": "Dry run completed - no changes made",
@@ -1208,7 +1216,7 @@ The final CLAUDE.md should be a comprehensive, well-organized guide that any AI
1208
1216
  console.print()
1209
1217
 
1210
1218
  return {
1211
- "status": "success",
1219
+ "status": OperationResult.SUCCESS,
1212
1220
  "checks_passed": checks_passed,
1213
1221
  "warnings": warnings,
1214
1222
  }
@@ -1412,7 +1420,7 @@ preserving valuable project-specific information while refreshing standard secti
1412
1420
  # Check result - be more lenient with return codes
1413
1421
  if result.returncode == 0 or (self.project_path / "CLAUDE.md").exists():
1414
1422
  response = {
1415
- "status": "success",
1423
+ "status": OperationResult.SUCCESS,
1416
1424
  "message": "Project initialized successfully",
1417
1425
  "files_created": [],
1418
1426
  "files_updated": [],
@@ -1450,7 +1458,7 @@ preserving valuable project-specific information while refreshing standard secti
1450
1458
 
1451
1459
  logger.error(f"claude-mpm run failed: {error_msg}")
1452
1460
  return {
1453
- "status": "error",
1461
+ "status": OperationResult.ERROR,
1454
1462
  "message": f"Initialization failed: {error_msg}",
1455
1463
  }
1456
1464
 
@@ -1459,10 +1467,10 @@ preserving valuable project-specific information while refreshing standard secti
1459
1467
  console.print(
1460
1468
  "[red]Error: claude-mpm command not found. Ensure Claude MPM is properly installed.[/red]"
1461
1469
  )
1462
- return {"status": "error", "message": "claude-mpm not found"}
1470
+ return {"status": OperationResult.ERROR, "message": "claude-mpm not found"}
1463
1471
  except Exception as e:
1464
1472
  logger.error(f"Initialization failed: {e}")
1465
- return {"status": "error", "message": str(e)}
1473
+ return {"status": OperationResult.ERROR, "message": str(e)}
1466
1474
 
1467
1475
  def handle_context(
1468
1476
  self,
@@ -1516,7 +1524,7 @@ preserving valuable project-specific information while refreshing standard secti
1516
1524
  "[dim]Ensure this is a git repository with commit history.[/dim]\n"
1517
1525
  )
1518
1526
  return {
1519
- "status": "error",
1527
+ "status": OperationResult.ERROR,
1520
1528
  "message": git_analysis["error"],
1521
1529
  }
1522
1530
 
@@ -1526,7 +1534,7 @@ preserving valuable project-specific information while refreshing standard secti
1526
1534
  )
1527
1535
  console.print("[dim]Try increasing the --days parameter.[/dim]\n")
1528
1536
  return {
1529
- "status": "error",
1537
+ "status": OperationResult.ERROR,
1530
1538
  "message": f"No git activity in last {days} days",
1531
1539
  }
1532
1540
 
@@ -1541,7 +1549,7 @@ preserving valuable project-specific information while refreshing standard secti
1541
1549
  console.print("\n" + "=" * 80 + "\n")
1542
1550
 
1543
1551
  return {
1544
- "status": "context_ready",
1552
+ "status": OperationResult.CONTEXT_READY,
1545
1553
  "git_analysis": git_analysis,
1546
1554
  "research_prompt": research_prompt,
1547
1555
  "recommendation": "PM should delegate this prompt to Research agent",
@@ -1677,7 +1685,7 @@ Keep it concise (<1000 words) but actionable.
1677
1685
 
1678
1686
  def _display_results(self, result: Dict, verbose: bool):
1679
1687
  """Display initialization results."""
1680
- if result["status"] == "success":
1688
+ if result["status"] == OperationResult.SUCCESS:
1681
1689
  console.print("\n[green]✅ Project Initialization Complete![/green]\n")
1682
1690
 
1683
1691
  # Display files created
@@ -1877,7 +1885,7 @@ def mpm_init(
1877
1885
  )
1878
1886
 
1879
1887
  # Exit with appropriate code
1880
- if result["status"] == "success":
1888
+ if result["status"] == OperationResult.SUCCESS:
1881
1889
  sys.exit(0)
1882
1890
  else:
1883
1891
  sys.exit(1)
@@ -1928,7 +1936,10 @@ def context_command(session_id, days, project_path):
1928
1936
 
1929
1937
  result = command.handle_context(session_id=session_id, days=days)
1930
1938
 
1931
- if result["status"] == "success" or result["status"] == "context_ready":
1939
+ if (
1940
+ result["status"] == OperationResult.SUCCESS
1941
+ or result["status"] == OperationResult.CONTEXT_READY
1942
+ ):
1932
1943
  sys.exit(0)
1933
1944
  else:
1934
1945
  sys.exit(1)
@@ -1977,7 +1988,10 @@ def resume_session(session_id, days, project_path):
1977
1988
  command = MPMInitCommand(Path(project_path))
1978
1989
  result = command.handle_context(session_id=session_id, days=days)
1979
1990
 
1980
- if result["status"] == "success" or result["status"] == "context_ready":
1991
+ if (
1992
+ result["status"] == OperationResult.SUCCESS
1993
+ or result["status"] == OperationResult.CONTEXT_READY
1994
+ ):
1981
1995
  sys.exit(0)
1982
1996
  else:
1983
1997
  sys.exit(1)
@@ -8,6 +8,8 @@ from pathlib import Path
8
8
 
9
9
  from rich.console import Console
10
10
 
11
+ from claude_mpm.core.enums import OperationResult
12
+
11
13
  console = Console()
12
14
 
13
15
 
@@ -51,7 +53,10 @@ def manage_mpm_init(args):
51
53
  )
52
54
 
53
55
  # Return appropriate exit code
54
- if result.get("status") in ("success", "context_ready"):
56
+ if result.get("status") in (
57
+ OperationResult.SUCCESS,
58
+ OperationResult.CONTEXT_READY,
59
+ ):
55
60
  return 0
56
61
  return 1
57
62
 
@@ -102,9 +107,9 @@ def manage_mpm_init(args):
102
107
  result = command.initialize_project(**init_params)
103
108
 
104
109
  # Return appropriate exit code
105
- if result.get("status") == "success":
110
+ if result.get("status") == OperationResult.SUCCESS:
106
111
  return 0
107
- if result.get("status") == "cancelled":
112
+ if result.get("status") == OperationResult.CANCELLED:
108
113
  return 130 # User cancelled
109
114
  return 1 # Error
110
115
 
@@ -0,0 +1,202 @@
1
+ """
2
+ CLI Command Executor
3
+ ====================
4
+
5
+ This module handles command execution routing and argument preparation.
6
+
7
+ Part of cli/__init__.py refactoring to reduce file size and improve modularity.
8
+ """
9
+
10
+ from ..constants import CLICommands
11
+ from .commands import (
12
+ aggregate_command,
13
+ cleanup_memory,
14
+ manage_agent_manager,
15
+ manage_agents,
16
+ manage_config,
17
+ manage_configure,
18
+ manage_debug,
19
+ manage_mcp,
20
+ manage_memory,
21
+ manage_monitor,
22
+ manage_tickets,
23
+ run_doctor,
24
+ run_session,
25
+ show_info,
26
+ )
27
+ from .commands.analyze_code import manage_analyze_code
28
+ from .commands.dashboard import manage_dashboard
29
+ from .commands.upgrade import upgrade
30
+
31
+
32
+ def ensure_run_attributes(args):
33
+ """
34
+ Ensure run command attributes exist when defaulting to run.
35
+
36
+ WHY: When no command is specified, we default to 'run' but the args object
37
+ won't have run-specific attributes from the subparser. This function ensures
38
+ they exist with sensible defaults.
39
+
40
+ Args:
41
+ args: Parsed arguments object to update
42
+ """
43
+ # Set defaults for run command attributes
44
+ args.no_tickets = getattr(args, "no_tickets", False)
45
+ args.no_hooks = getattr(args, "no_hooks", False)
46
+ args.intercept_commands = getattr(args, "intercept_commands", False)
47
+ args.input = getattr(args, "input", None)
48
+ args.non_interactive = getattr(args, "non_interactive", False)
49
+ args.no_native_agents = getattr(args, "no_native_agents", False)
50
+
51
+ # Handle claude_args - if --resume flag is set, add it to claude_args
52
+ claude_args = getattr(args, "claude_args", [])
53
+ if getattr(args, "resume", False):
54
+ # Add --resume to claude_args if not already present
55
+ if "--resume" not in claude_args:
56
+ claude_args = ["--resume", *claude_args]
57
+ args.claude_args = claude_args
58
+
59
+ args.launch_method = getattr(args, "launch_method", "exec")
60
+ args.websocket = getattr(args, "websocket", False)
61
+ args.websocket_port = getattr(args, "websocket_port", 8765)
62
+ # CRITICAL: Include mpm_resume attribute for session resumption
63
+ args.mpm_resume = getattr(args, "mpm_resume", None)
64
+ # Also include monitor and force attributes
65
+ args.monitor = getattr(args, "monitor", False)
66
+ args.force = getattr(args, "force", False)
67
+ args.reload_agents = getattr(args, "reload_agents", False)
68
+ # Include dependency checking attributes
69
+ args.check_dependencies = getattr(args, "check_dependencies", True)
70
+ args.force_check_dependencies = getattr(args, "force_check_dependencies", False)
71
+ args.no_prompt = getattr(args, "no_prompt", False)
72
+ args.force_prompt = getattr(args, "force_prompt", False)
73
+
74
+
75
+ def execute_command(command: str, args) -> int:
76
+ """
77
+ Execute the specified command.
78
+
79
+ WHY: This function maps command names to their implementations, providing
80
+ a single place to manage command routing. Experimental commands are imported
81
+ lazily to avoid loading unnecessary code.
82
+
83
+ DESIGN DECISION: run_guarded is imported only when needed to maintain
84
+ separation between stable and experimental features. Command suggestions
85
+ are provided for unknown commands to improve user experience.
86
+
87
+ Args:
88
+ command: The command name to execute
89
+ args: Parsed command line arguments
90
+
91
+ Returns:
92
+ Exit code from the command
93
+ """
94
+ # Handle experimental run-guarded command separately with lazy import
95
+ if command == "run-guarded":
96
+ # Lazy import to avoid loading experimental code unless needed
97
+ from .commands.run_guarded import execute_run_guarded
98
+
99
+ result = execute_run_guarded(args)
100
+ return result if result is not None else 0
101
+
102
+ # Handle mpm-init command with lazy import
103
+ if command == "mpm-init":
104
+ # Lazy import to avoid loading unless needed
105
+ from .commands.mpm_init_handler import manage_mpm_init
106
+
107
+ result = manage_mpm_init(args)
108
+ return result if result is not None else 0
109
+
110
+ # Handle uninstall command with lazy import
111
+ if command == "uninstall":
112
+ # Lazy import to avoid loading unless needed
113
+ from .commands.uninstall import UninstallCommand
114
+
115
+ cmd = UninstallCommand()
116
+ result = cmd.execute(args)
117
+ # Convert CommandResult to exit code
118
+ return result.exit_code if result else 0
119
+
120
+ # Handle verify command with lazy import
121
+ if command == "verify":
122
+ # Lazy import to avoid loading unless needed
123
+ from .commands.verify import handle_verify
124
+
125
+ result = handle_verify(args)
126
+ return result if result is not None else 0
127
+
128
+ # Handle auto-configure command with lazy import
129
+ if command == "auto-configure":
130
+ # Lazy import to avoid loading unless needed
131
+ from .commands.auto_configure import AutoConfigureCommand
132
+
133
+ cmd = AutoConfigureCommand()
134
+ result = cmd.run(args)
135
+ # Convert CommandResult to exit code
136
+ return result.exit_code if result else 0
137
+
138
+ # Handle local-deploy command with lazy import
139
+ if command == "local-deploy":
140
+ # Lazy import to avoid loading unless needed
141
+ from .commands.local_deploy import LocalDeployCommand
142
+
143
+ cmd = LocalDeployCommand()
144
+ result = cmd.run(args)
145
+ # Convert CommandResult to exit code
146
+ return result.exit_code if result else 0
147
+
148
+ # Map stable commands to their implementations
149
+ command_map = {
150
+ CLICommands.RUN.value: run_session,
151
+ # CLICommands.RUN_GUARDED.value is handled above
152
+ CLICommands.TICKETS.value: manage_tickets,
153
+ CLICommands.INFO.value: show_info,
154
+ CLICommands.AGENTS.value: manage_agents,
155
+ CLICommands.AGENT_MANAGER.value: manage_agent_manager,
156
+ CLICommands.MEMORY.value: manage_memory,
157
+ CLICommands.MONITOR.value: manage_monitor,
158
+ CLICommands.DASHBOARD.value: manage_dashboard,
159
+ CLICommands.CONFIG.value: manage_config,
160
+ CLICommands.CONFIGURE.value: manage_configure,
161
+ CLICommands.AGGREGATE.value: aggregate_command,
162
+ CLICommands.ANALYZE_CODE.value: manage_analyze_code,
163
+ CLICommands.CLEANUP.value: cleanup_memory,
164
+ CLICommands.MCP.value: manage_mcp,
165
+ CLICommands.DOCTOR.value: run_doctor,
166
+ CLICommands.UPGRADE.value: upgrade,
167
+ "debug": manage_debug, # Add debug command
168
+ "mpm-init": None, # Will be handled separately with lazy import
169
+ }
170
+
171
+ # Execute command if found
172
+ if command in command_map:
173
+ result = command_map[command](args)
174
+ # Commands may return None (success) or an exit code
175
+ return result if result is not None else 0
176
+
177
+ # Unknown command - provide suggestions
178
+ from rich.console import Console
179
+
180
+ from .utils import suggest_similar_commands
181
+
182
+ console = Console(stderr=True)
183
+
184
+ console.print(f"\n[red]Error:[/red] Unknown command: {command}\n", style="bold")
185
+
186
+ # Get all valid commands for suggestions
187
+ all_commands = [
188
+ *command_map.keys(),
189
+ "run-guarded",
190
+ "uninstall",
191
+ "verify",
192
+ "auto-configure",
193
+ "local-deploy",
194
+ ]
195
+
196
+ suggestion = suggest_similar_commands(command, all_commands)
197
+ if suggestion:
198
+ console.print(f"[yellow]{suggestion}[/yellow]\n")
199
+
200
+ console.print("[dim]Run 'claude-mpm --help' for usage information.[/dim]\n")
201
+
202
+ return 1