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
@@ -15,6 +15,7 @@ import json
15
15
  from pathlib import Path
16
16
 
17
17
  from ...constants import AgentCommands
18
+ from ...core.enums import OutputFormat
18
19
  from ...services.cli.agent_cleanup_service import AgentCleanupService
19
20
  from ...services.cli.agent_dependency_service import AgentDependencyService
20
21
  from ...services.cli.agent_listing_service import AgentListingService
@@ -27,6 +28,14 @@ from ..shared import (
27
28
  from ..utils import get_agent_versions_display
28
29
 
29
30
 
31
+ def _is_structured_output(args) -> bool:
32
+ """Check if args specify structured output format (JSON/YAML)."""
33
+ if hasattr(args, "format"):
34
+ fmt = str(args.format).lower()
35
+ return fmt in (OutputFormat.JSON, OutputFormat.YAML)
36
+ return False
37
+
38
+
30
39
  class AgentsCommand(AgentCommand):
31
40
  """Agent management command using shared utilities."""
32
41
 
@@ -87,6 +96,31 @@ class AgentsCommand(AgentCommand):
87
96
  )
88
97
  return self._cleanup_service
89
98
 
99
+ def _get_output_format(self, args) -> str:
100
+ """
101
+ Get output format from args with enum default.
102
+
103
+ Args:
104
+ args: Command arguments
105
+
106
+ Returns:
107
+ Output format string (compatible with both enum and string usage)
108
+ """
109
+ return getattr(args, "format", OutputFormat.TEXT)
110
+
111
+ def _is_structured_format(self, format_str: str) -> bool:
112
+ """
113
+ Check if format is structured (JSON/YAML).
114
+
115
+ Args:
116
+ format_str: Format string to check
117
+
118
+ Returns:
119
+ True if format is JSON or YAML
120
+ """
121
+ fmt = str(format_str).lower()
122
+ return fmt in (OutputFormat.JSON, OutputFormat.YAML)
123
+
90
124
  def validate_args(self, args) -> str:
91
125
  """Validate command arguments."""
92
126
  # Most agent commands are optional, so basic validation
@@ -145,14 +179,14 @@ class AgentsCommand(AgentCommand):
145
179
  try:
146
180
  agent_versions = get_agent_versions_display()
147
181
 
148
- output_format = getattr(args, "format", "text")
149
- if output_format in ["json", "yaml"]:
182
+ output_format = self._get_output_format(args)
183
+ if self._is_structured_format(output_format):
150
184
  # Parse the agent versions display into structured data
151
185
  if agent_versions:
152
186
  data = {"agent_versions": agent_versions, "has_agents": True}
153
187
  formatted = (
154
188
  self._formatter.format_as_json(data)
155
- if output_format == "json"
189
+ if str(output_format).lower() == OutputFormat.JSON
156
190
  else self._formatter.format_as_yaml(data)
157
191
  )
158
192
  print(formatted)
@@ -166,7 +200,7 @@ class AgentsCommand(AgentCommand):
166
200
  }
167
201
  formatted = (
168
202
  self._formatter.format_as_json(data)
169
- if output_format == "json"
203
+ if str(output_format).lower() == OutputFormat.JSON
170
204
  else self._formatter.format_as_yaml(data)
171
205
  )
172
206
  print(formatted)
@@ -188,7 +222,7 @@ class AgentsCommand(AgentCommand):
188
222
  def _list_agents(self, args) -> CommandResult:
189
223
  """List available or deployed agents."""
190
224
  try:
191
- output_format = getattr(args, "format", "text")
225
+ output_format = self._get_output_format(args)
192
226
 
193
227
  if hasattr(args, "by_tier") and args.by_tier:
194
228
  return self._list_agents_by_tier(args)
@@ -199,7 +233,7 @@ class AgentsCommand(AgentCommand):
199
233
  # Default: show usage
200
234
  usage_msg = "Use --system to list system agents, --deployed to list deployed agents, or --by-tier to group by precedence"
201
235
 
202
- if output_format in ["json", "yaml"]:
236
+ if self._is_structured_format(output_format):
203
237
  return CommandResult.error_result(
204
238
  "No list option specified",
205
239
  data={
@@ -220,7 +254,7 @@ class AgentsCommand(AgentCommand):
220
254
  verbose = getattr(args, "verbose", False)
221
255
  agents = self.listing_service.list_system_agents(verbose=verbose)
222
256
 
223
- output_format = getattr(args, "format", "text")
257
+ output_format = self._get_output_format(args)
224
258
  quiet = getattr(args, "quiet", False)
225
259
 
226
260
  # Convert AgentInfo objects to dicts for formatter
@@ -259,7 +293,7 @@ class AgentsCommand(AgentCommand):
259
293
  verbose=verbose
260
294
  )
261
295
 
262
- output_format = getattr(args, "format", "text")
296
+ output_format = self._get_output_format(args)
263
297
  quiet = getattr(args, "quiet", False)
264
298
 
265
299
  # Convert AgentInfo objects to dicts for formatter
@@ -284,7 +318,7 @@ class AgentsCommand(AgentCommand):
284
318
  print(formatted)
285
319
 
286
320
  # Add warnings for text output
287
- if output_format == "text" and warnings:
321
+ if str(output_format).lower() == OutputFormat.TEXT and warnings:
288
322
  print("\nWarnings:")
289
323
  for warning in warnings:
290
324
  print(f" ⚠️ {warning}")
@@ -306,7 +340,7 @@ class AgentsCommand(AgentCommand):
306
340
  """List agents grouped by tier/precedence."""
307
341
  try:
308
342
  tier_info = self.listing_service.list_agents_by_tier()
309
- output_format = getattr(args, "format", "text")
343
+ output_format = self._get_output_format(args)
310
344
 
311
345
  # Convert to format expected by formatter
312
346
  agents_by_tier = {
@@ -389,7 +423,7 @@ class AgentsCommand(AgentCommand):
389
423
  or project_result.get("target_dir"),
390
424
  }
391
425
 
392
- output_format = getattr(args, "format", "text")
426
+ output_format = self._get_output_format(args)
393
427
  verbose = getattr(args, "verbose", False)
394
428
 
395
429
  formatted = self._formatter.format_deployment_result(
@@ -415,7 +449,7 @@ class AgentsCommand(AgentCommand):
415
449
  try:
416
450
  result = self.cleanup_service.clean_deployed_agents()
417
451
 
418
- output_format = getattr(args, "format", "text")
452
+ output_format = self._get_output_format(args)
419
453
  dry_run = False # Regular clean is not a dry run
420
454
 
421
455
  formatted = self._formatter.format_cleanup_result(
@@ -453,7 +487,7 @@ class AgentsCommand(AgentCommand):
453
487
  f"Could not retrieve details for agent '{agent_name}'"
454
488
  )
455
489
 
456
- output_format = getattr(args, "format", "text")
490
+ output_format = self._get_output_format(args)
457
491
  verbose = getattr(args, "verbose", False)
458
492
 
459
493
  formatted = self._formatter.format_agent_details(
@@ -475,148 +509,170 @@ class AgentsCommand(AgentCommand):
475
509
  dry_run = getattr(args, "dry_run", False)
476
510
  agent_name = getattr(args, "agent_name", None)
477
511
  fix_all = getattr(args, "all", False)
512
+ output_format = self._get_output_format(args)
478
513
 
479
- output_format = getattr(args, "format", "text")
480
-
481
- # Determine what to fix
514
+ # Route to appropriate handler based on input
482
515
  if fix_all:
483
- # Fix all agents
484
- result = self.validation_service.fix_all_agents(dry_run=dry_run)
485
-
486
- if output_format in ["json", "yaml"]:
487
- formatted = (
488
- self._formatter.format_as_json(result)
489
- if output_format == "json"
490
- else self._formatter.format_as_yaml(result)
491
- )
492
- print(formatted)
493
- else:
494
- # Text output
495
- mode = "DRY RUN" if dry_run else "FIX"
496
- print(
497
- f"\n🔧 {mode}: Checking {result.get('total_agents', 0)} agent(s) for frontmatter issues...\n"
498
- )
499
-
500
- if result.get("results"):
501
- for agent_result in result["results"]:
502
- print(f"📄 {agent_result['agent']}:")
503
- if agent_result.get("skipped"):
504
- print(
505
- f" ⚠️ Skipped: {agent_result.get('reason', 'Unknown reason')}"
506
- )
507
- elif agent_result.get("was_valid"):
508
- print(" ✓ No issues found")
509
- else:
510
- if agent_result.get("errors_found", 0) > 0:
511
- print(
512
- f" ❌ Errors found: {agent_result['errors_found']}"
513
- )
514
- if agent_result.get("warnings_found", 0) > 0:
515
- print(
516
- f" ⚠️ Warnings found: {agent_result['warnings_found']}"
517
- )
518
- if dry_run:
519
- if agent_result.get("corrections_available", 0) > 0:
520
- print(
521
- f" 🔧 Would fix: {agent_result['corrections_available']} issues"
522
- )
523
- elif agent_result.get("corrections_made", 0) > 0:
524
- print(
525
- f" ✓ Fixed: {agent_result['corrections_made']} issues"
526
- )
527
- print()
528
-
529
- # Summary
530
- print("=" * 80)
531
- print("SUMMARY:")
532
- print(f" Agents checked: {result.get('agents_checked', 0)}")
533
- print(
534
- f" Total issues found: {result.get('total_issues_found', 0)}"
535
- )
536
- if dry_run:
537
- print(
538
- f" Issues that would be fixed: {result.get('total_corrections_available', 0)}"
539
- )
540
- print("\n💡 Run without --dry-run to apply fixes")
541
- else:
542
- print(
543
- f" Issues fixed: {result.get('total_corrections_made', 0)}"
544
- )
545
- if result.get("total_corrections_made", 0) > 0:
546
- print("\n✓ Frontmatter issues have been fixed!")
547
- print("=" * 80 + "\n")
516
+ return self._fix_all_agents(dry_run, output_format)
517
+ if agent_name:
518
+ return self._fix_single_agent(agent_name, dry_run, output_format)
519
+ return self._handle_no_agent_specified(output_format)
548
520
 
549
- msg = f"{'Would fix' if dry_run else 'Fixed'} {result.get('total_corrections_available' if dry_run else 'total_corrections_made', 0)} issues"
550
- return CommandResult.success_result(msg, data=result)
521
+ except Exception as e:
522
+ self.logger.error(f"Error fixing agents: {e}", exc_info=True)
523
+ return CommandResult.error_result(f"Error fixing agents: {e}")
551
524
 
552
- if agent_name:
553
- # Fix specific agent
554
- result = self.validation_service.fix_agent_frontmatter(
555
- agent_name, dry_run=dry_run
556
- )
525
+ def _fix_all_agents(self, dry_run: bool, output_format: str) -> CommandResult:
526
+ """Fix all agents' frontmatter issues."""
527
+ result = self.validation_service.fix_all_agents(dry_run=dry_run)
557
528
 
558
- if not result.get("success"):
559
- return CommandResult.error_result(
560
- result.get("error", "Failed to fix agent")
561
- )
529
+ if self._is_structured_format(output_format):
530
+ self._print_structured_output(result, output_format)
531
+ else:
532
+ self._print_all_agents_text_output(result, dry_run)
562
533
 
563
- if output_format in ["json", "yaml"]:
564
- formatted = (
565
- self._formatter.format_as_json(result)
566
- if output_format == "json"
567
- else self._formatter.format_as_yaml(result)
568
- )
569
- print(formatted)
570
- else:
571
- # Text output
572
- mode = "DRY RUN" if dry_run else "FIX"
573
- print(
574
- f"\n🔧 {mode}: Checking agent '{agent_name}' for frontmatter issues...\n"
575
- )
534
+ msg = f"{'Would fix' if dry_run else 'Fixed'} {result.get('total_corrections_available' if dry_run else 'total_corrections_made', 0)} issues"
535
+ return CommandResult.success_result(msg, data=result)
576
536
 
577
- print(f"📄 {agent_name}:")
578
- if result.get("was_valid"):
579
- print(" ✓ No issues found")
580
- else:
581
- if result.get("errors_found"):
582
- print(" ❌ Errors:")
583
- for error in result["errors_found"]:
584
- print(f" - {error}")
585
- if result.get("warnings_found"):
586
- print(" ⚠️ Warnings:")
587
- for warning in result["warnings_found"]:
588
- print(f" - {warning}")
589
- if dry_run:
590
- if result.get("corrections_available"):
591
- print(" 🔧 Would fix:")
592
- for correction in result["corrections_available"]:
593
- print(f" - {correction}")
594
- elif result.get("corrections_made"):
595
- print(" ✓ Fixed:")
596
- for correction in result["corrections_made"]:
597
- print(f" - {correction}")
598
- print()
537
+ def _fix_single_agent(
538
+ self, agent_name: str, dry_run: bool, output_format: str
539
+ ) -> CommandResult:
540
+ """Fix a single agent's frontmatter issues."""
541
+ result = self.validation_service.fix_agent_frontmatter(
542
+ agent_name, dry_run=dry_run
543
+ )
599
544
 
600
- if dry_run and result.get("corrections_available"):
601
- print("💡 Run without --dry-run to apply fixes\n")
602
- elif not dry_run and result.get("corrections_made"):
603
- print("✓ Frontmatter issues have been fixed!\n")
545
+ if not result.get("success"):
546
+ return CommandResult.error_result(
547
+ result.get("error", "Failed to fix agent")
548
+ )
604
549
 
605
- msg = f"{'Would fix' if dry_run else 'Fixed'} agent '{agent_name}'"
606
- return CommandResult.success_result(msg, data=result)
550
+ if self._is_structured_format(output_format):
551
+ self._print_structured_output(result, output_format)
552
+ else:
553
+ self._print_single_agent_text_output(agent_name, result, dry_run)
607
554
 
608
- # No agent specified and not --all
609
- usage_msg = "Please specify an agent name or use --all to fix all agents\nUsage: claude-mpm agents fix [agent_name] [--dry-run] [--all]"
610
- if output_format in ["json", "yaml"]:
611
- return CommandResult.error_result(
612
- "No agent specified", data={"usage": usage_msg}
613
- )
614
- print(f"❌ {usage_msg}")
615
- return CommandResult.error_result("No agent specified")
555
+ msg = f"{'Would fix' if dry_run else 'Fixed'} agent '{agent_name}'"
556
+ return CommandResult.success_result(msg, data=result)
616
557
 
617
- except Exception as e:
618
- self.logger.error(f"Error fixing agents: {e}", exc_info=True)
619
- return CommandResult.error_result(f"Error fixing agents: {e}")
558
+ def _handle_no_agent_specified(self, output_format: str) -> CommandResult:
559
+ """Handle case where no agent is specified."""
560
+ usage_msg = "Please specify an agent name or use --all to fix all agents\nUsage: claude-mpm agents fix [agent_name] [--dry-run] [--all]"
561
+ if self._is_structured_format(output_format):
562
+ return CommandResult.error_result(
563
+ "No agent specified", data={"usage": usage_msg}
564
+ )
565
+ print(f"❌ {usage_msg}")
566
+ return CommandResult.error_result("No agent specified")
567
+
568
+ def _print_structured_output(self, result: dict, output_format: str) -> None:
569
+ """Print result in JSON or YAML format."""
570
+ formatted = (
571
+ self._formatter.format_as_json(result)
572
+ if str(output_format).lower() == OutputFormat.JSON
573
+ else self._formatter.format_as_yaml(result)
574
+ )
575
+ print(formatted)
576
+
577
+ def _print_all_agents_text_output(self, result: dict, dry_run: bool) -> None:
578
+ """Print text output for all agents fix operation."""
579
+ mode = "DRY RUN" if dry_run else "FIX"
580
+ print(
581
+ f"\n🔧 {mode}: Checking {result.get('total_agents', 0)} agent(s) for frontmatter issues...\n"
582
+ )
583
+
584
+ if result.get("results"):
585
+ for agent_result in result["results"]:
586
+ self._print_agent_result(agent_result, dry_run)
587
+
588
+ self._print_all_agents_summary(result, dry_run)
589
+
590
+ def _print_agent_result(self, agent_result: dict, dry_run: bool) -> None:
591
+ """Print result for a single agent."""
592
+ print(f"📄 {agent_result['agent']}:")
593
+ if agent_result.get("skipped"):
594
+ print(f" ⚠️ Skipped: {agent_result.get('reason', 'Unknown reason')}")
595
+ elif agent_result.get("was_valid"):
596
+ print(" ✓ No issues found")
597
+ else:
598
+ self._print_agent_issues(agent_result, dry_run)
599
+ print()
600
+
601
+ def _print_agent_issues(self, agent_result: dict, dry_run: bool) -> None:
602
+ """Print issues found for an agent."""
603
+ if agent_result.get("errors_found", 0) > 0:
604
+ print(f" ❌ Errors found: {agent_result['errors_found']}")
605
+ if agent_result.get("warnings_found", 0) > 0:
606
+ print(f" ⚠️ Warnings found: {agent_result['warnings_found']}")
607
+
608
+ if dry_run:
609
+ if agent_result.get("corrections_available", 0) > 0:
610
+ print(f" 🔧 Would fix: {agent_result['corrections_available']} issues")
611
+ elif agent_result.get("corrections_made", 0) > 0:
612
+ print(f" ✓ Fixed: {agent_result['corrections_made']} issues")
613
+
614
+ def _print_all_agents_summary(self, result: dict, dry_run: bool) -> None:
615
+ """Print summary for all agents fix operation."""
616
+ print("=" * 80)
617
+ print("SUMMARY:")
618
+ print(f" Agents checked: {result.get('agents_checked', 0)}")
619
+ print(f" Total issues found: {result.get('total_issues_found', 0)}")
620
+
621
+ if dry_run:
622
+ print(
623
+ f" Issues that would be fixed: {result.get('total_corrections_available', 0)}"
624
+ )
625
+ print("\n💡 Run without --dry-run to apply fixes")
626
+ else:
627
+ print(f" Issues fixed: {result.get('total_corrections_made', 0)}")
628
+ if result.get("total_corrections_made", 0) > 0:
629
+ print("\n✓ Frontmatter issues have been fixed!")
630
+ print("=" * 80 + "\n")
631
+
632
+ def _print_single_agent_text_output(
633
+ self, agent_name: str, result: dict, dry_run: bool
634
+ ) -> None:
635
+ """Print text output for single agent fix operation."""
636
+ mode = "DRY RUN" if dry_run else "FIX"
637
+ print(f"\n🔧 {mode}: Checking agent '{agent_name}' for frontmatter issues...\n")
638
+
639
+ print(f"📄 {agent_name}:")
640
+ if result.get("was_valid"):
641
+ print(" ✓ No issues found")
642
+ else:
643
+ self._print_single_agent_issues(result, dry_run)
644
+ print()
645
+
646
+ self._print_single_agent_footer(result, dry_run)
647
+
648
+ def _print_single_agent_issues(self, result: dict, dry_run: bool) -> None:
649
+ """Print issues for a single agent."""
650
+ if result.get("errors_found"):
651
+ print(" ❌ Errors:")
652
+ for error in result["errors_found"]:
653
+ print(f" - {error}")
654
+
655
+ if result.get("warnings_found"):
656
+ print(" ⚠️ Warnings:")
657
+ for warning in result["warnings_found"]:
658
+ print(f" - {warning}")
659
+
660
+ if dry_run:
661
+ if result.get("corrections_available"):
662
+ print(" 🔧 Would fix:")
663
+ for correction in result["corrections_available"]:
664
+ print(f" - {correction}")
665
+ elif result.get("corrections_made"):
666
+ print(" ✓ Fixed:")
667
+ for correction in result["corrections_made"]:
668
+ print(f" - {correction}")
669
+
670
+ def _print_single_agent_footer(self, result: dict, dry_run: bool) -> None:
671
+ """Print footer message for single agent fix."""
672
+ if dry_run and result.get("corrections_available"):
673
+ print("💡 Run without --dry-run to apply fixes\n")
674
+ elif not dry_run and result.get("corrections_made"):
675
+ print("✓ Frontmatter issues have been fixed!\n")
620
676
 
621
677
  def _check_agent_dependencies(self, args) -> CommandResult:
622
678
  """Check agent dependencies."""
@@ -696,7 +752,7 @@ class AgentsCommand(AgentCommand):
696
752
  def _list_agent_dependencies(self, args) -> CommandResult:
697
753
  """List agent dependencies."""
698
754
  try:
699
- output_format = getattr(args, "format", "text")
755
+ output_format = self._get_output_format(args)
700
756
  result = self.dependency_service.list_dependencies(
701
757
  format_type=output_format
702
758
  )
@@ -708,7 +764,7 @@ class AgentsCommand(AgentCommand):
708
764
  if output_format == "pip":
709
765
  for dep in result["dependencies"]:
710
766
  print(dep)
711
- elif output_format == "json":
767
+ elif str(output_format).lower() == OutputFormat.JSON:
712
768
  print(json.dumps(result["data"], indent=2))
713
769
  else: # text format
714
770
  print("=" * 60)
@@ -866,7 +922,7 @@ class AgentsCommand(AgentCommand):
866
922
  agents_dir=agents_dir, dry_run=dry_run
867
923
  )
868
924
 
869
- output_format = getattr(args, "format", "text")
925
+ output_format = self._get_output_format(args)
870
926
 
871
927
  formatted = self._formatter.format_cleanup_result(
872
928
  results, output_format=output_format, dry_run=dry_run
@@ -1403,7 +1459,7 @@ def manage_agents(args):
1403
1459
  result = command.execute(args)
1404
1460
 
1405
1461
  # Print result if structured output format is requested
1406
- if hasattr(args, "format") and args.format in ["json", "yaml"]:
1462
+ if _is_structured_output(args):
1407
1463
  command.print_result(result, args)
1408
1464
 
1409
1465
  return result.exit_code
@@ -16,6 +16,7 @@ import json
16
16
  import sys
17
17
  from typing import Optional
18
18
 
19
+ from ...core.enums import OutputFormat
19
20
  from ...core.logger import get_logger
20
21
  from ...services.event_aggregator import (
21
22
  aggregator_status,
@@ -110,7 +111,10 @@ def aggregate_command(args):
110
111
  result = command.execute(args)
111
112
 
112
113
  # Print result if structured output format is requested
113
- if hasattr(args, "format") and args.format in ["json", "yaml"]:
114
+ if hasattr(args, "format") and str(args.format).lower() in (
115
+ OutputFormat.JSON,
116
+ OutputFormat.YAML,
117
+ ):
114
118
  command.print_result(result, args)
115
119
 
116
120
  return result.exit_code
@@ -407,7 +411,7 @@ def export_command_legacy(args):
407
411
  output_path = Path(f"session_{session.session_id[:8]}_export.json")
408
412
 
409
413
  # Export based on format
410
- if args.format == "json":
414
+ if str(args.format).lower() == OutputFormat.JSON:
411
415
  # Full JSON export
412
416
  with output_path.open("w") as f:
413
417
  json.dump(session.to_dict(), f, indent=2)
@@ -529,7 +533,7 @@ def add_aggregate_parser(subparsers):
529
533
  "--format",
530
534
  "-f",
531
535
  choices=["json", "summary", "events"],
532
- default="json",
536
+ default=OutputFormat.JSON,
533
537
  help="Export format (default: json)",
534
538
  )
535
539
 
@@ -23,6 +23,7 @@ from datetime import datetime, timezone
23
23
  from pathlib import Path
24
24
  from typing import Dict, List, Optional
25
25
 
26
+ from ...core.enums import OutputFormat
26
27
  from ...core.logging_config import get_logger
27
28
  from ...services.cli.session_manager import SessionManager
28
29
  from ..shared import BaseCommand, CommandResult
@@ -132,7 +133,11 @@ class AnalyzeCommand(BaseCommand):
132
133
  self._save_output(output, args.output)
133
134
 
134
135
  return CommandResult.success_result(
135
- message=output if args.format == "text" else "Analysis completed",
136
+ message=(
137
+ output
138
+ if str(args.format).lower() == OutputFormat.TEXT
139
+ else "Analysis completed"
140
+ ),
136
141
  data=result_data,
137
142
  )
138
143
 
@@ -422,7 +427,7 @@ class AnalyzeCommand(BaseCommand):
422
427
  Returns:
423
428
  Formatted output string
424
429
  """
425
- if format_type == "json":
430
+ if str(format_type).lower() == OutputFormat.JSON:
426
431
  result_data["diagrams"] = diagrams
427
432
  return json.dumps(result_data, indent=2)
428
433
 
@@ -516,7 +521,7 @@ def analyze_command(args):
516
521
  result = command.run(args)
517
522
 
518
523
  if result.success:
519
- if args.format == "json":
524
+ if str(args.format).lower() == OutputFormat.JSON:
520
525
  print(json.dumps(result.data, indent=2))
521
526
  else:
522
527
  print(result.message)
@@ -540,7 +545,7 @@ if __name__ == "__main__":
540
545
  parser.add_argument("--focus", nargs="+")
541
546
  parser.add_argument("--session-id", type=str)
542
547
  parser.add_argument("--no-session", action="store_true")
543
- parser.add_argument("--format", default="text")
548
+ parser.add_argument("--format", default=OutputFormat.TEXT)
544
549
  parser.add_argument("--output", type=Path)
545
550
  parser.add_argument("--verbose", action="store_true")
546
551
 
@@ -37,6 +37,7 @@ except ImportError:
37
37
  RICH_AVAILABLE = False
38
38
  Console = None
39
39
 
40
+ from ...core.enums import OutputFormat
40
41
  from ...core.logging_config import get_logger
41
42
  from ...tools.code_tree_analyzer import CodeTreeAnalyzer
42
43
  from ...tools.code_tree_builder import CodeTreeBuilder
@@ -73,7 +74,11 @@ class AnalyzeCodeCommand(BaseCommand):
73
74
  return f"Path is not a directory: {path}"
74
75
 
75
76
  # Validate output format
76
- if args.output and args.output not in ("json", "tree", "stats"):
77
+ if args.output and str(args.output).lower() not in (
78
+ OutputFormat.JSON,
79
+ "tree",
80
+ "stats",
81
+ ):
77
82
  return f"Invalid output format: {args.output}"
78
83
 
79
84
  return None
@@ -123,7 +128,7 @@ class AnalyzeCodeCommand(BaseCommand):
123
128
  )
124
129
 
125
130
  # Handle output format
126
- if args.output == "json":
131
+ if str(args.output).lower() == OutputFormat.JSON:
127
132
  # Output JSON to stdout
128
133
  json.dump(analysis_result, sys.stdout, indent=2, default=str)
129
134
  sys.stdout.write("\n")
@@ -26,12 +26,10 @@ try:
26
26
  except ImportError:
27
27
  RICH_AVAILABLE = False
28
28
 
29
+ from ...core.enums import OperationResult
29
30
  from ...services.agents.auto_config_manager import AutoConfigManagerService
30
31
  from ...services.agents.observers import NullObserver
31
- from ...services.core.models.agent_config import (
32
- ConfigurationResult,
33
- ConfigurationStatus,
34
- )
32
+ from ...services.core.models.agent_config import ConfigurationResult
35
33
  from ..shared import BaseCommand, CommandResult
36
34
 
37
35
 
@@ -419,7 +417,7 @@ class AutoConfigureCommand(BaseCommand):
419
417
  return self._display_result_plain(result)
420
418
 
421
419
  # Display summary
422
- if result.status == ConfigurationStatus.SUCCESS:
420
+ if result.status == OperationResult.SUCCESS:
423
421
  panel = Panel(
424
422
  f"✅ Auto-configuration completed successfully!\n\n"
425
423
  f"Deployed {len(result.deployed_agents)} agent(s)",
@@ -436,7 +434,7 @@ class AutoConfigureCommand(BaseCommand):
436
434
 
437
435
  return CommandResult.success_result()
438
436
 
439
- if result.status == ConfigurationStatus.PARTIAL_SUCCESS:
437
+ if result.status == OperationResult.WARNING:
440
438
  panel = Panel(
441
439
  f"⚠️ Auto-configuration partially completed\n\n"
442
440
  f"Deployed: {len(result.deployed_agents)}\n"
@@ -465,7 +463,7 @@ class AutoConfigureCommand(BaseCommand):
465
463
 
466
464
  def _display_result_plain(self, result: ConfigurationResult) -> CommandResult:
467
465
  """Display result in plain text (fallback)."""
468
- if result.status == ConfigurationStatus.SUCCESS:
466
+ if result.status == OperationResult.SUCCESS:
469
467
  print("\n✅ Auto-configuration completed successfully!")
470
468
  print(f"Deployed {len(result.deployed_agents)} agent(s)")
471
469
 
@@ -476,7 +474,7 @@ class AutoConfigureCommand(BaseCommand):
476
474
 
477
475
  return CommandResult.success_result()
478
476
 
479
- if result.status == ConfigurationStatus.PARTIAL_SUCCESS:
477
+ if result.status == OperationResult.WARNING:
480
478
  print("\n⚠️ Auto-configuration partially completed")
481
479
  print(f"Deployed: {len(result.deployed_agents)}")
482
480
  print(f"Failed: {len(result.failed_agents)}")
@@ -565,7 +563,7 @@ class AutoConfigureCommand(BaseCommand):
565
563
 
566
564
  print(json.dumps(output, indent=2))
567
565
 
568
- if result.status == ConfigurationStatus.SUCCESS:
566
+ if result.status == OperationResult.SUCCESS:
569
567
  return CommandResult.success_result(data=output)
570
568
  return CommandResult.error_result(
571
569
  "Configuration failed or partial", exit_code=1, data=output