claude-mpm 4.7.4__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 (308) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_AGENT_TEMPLATE.md +118 -0
  3. claude_mpm/agents/BASE_ENGINEER.md +286 -0
  4. claude_mpm/agents/BASE_PM.md +106 -1
  5. claude_mpm/agents/OUTPUT_STYLE.md +329 -11
  6. claude_mpm/agents/PM_INSTRUCTIONS.md +397 -459
  7. claude_mpm/agents/agent_loader.py +17 -5
  8. claude_mpm/agents/frontmatter_validator.py +284 -253
  9. claude_mpm/agents/templates/README.md +465 -0
  10. claude_mpm/agents/templates/agent-manager.json +4 -1
  11. claude_mpm/agents/templates/agentic-coder-optimizer.json +13 -3
  12. claude_mpm/agents/templates/api_qa.json +11 -2
  13. claude_mpm/agents/templates/circuit_breakers.md +638 -0
  14. claude_mpm/agents/templates/clerk-ops.json +12 -2
  15. claude_mpm/agents/templates/code_analyzer.json +8 -2
  16. claude_mpm/agents/templates/content-agent.json +358 -0
  17. claude_mpm/agents/templates/dart_engineer.json +15 -2
  18. claude_mpm/agents/templates/data_engineer.json +15 -2
  19. claude_mpm/agents/templates/documentation.json +10 -2
  20. claude_mpm/agents/templates/engineer.json +21 -1
  21. claude_mpm/agents/templates/gcp_ops_agent.json +12 -2
  22. claude_mpm/agents/templates/git_file_tracking.md +584 -0
  23. claude_mpm/agents/templates/golang_engineer.json +270 -0
  24. claude_mpm/agents/templates/imagemagick.json +4 -1
  25. claude_mpm/agents/templates/java_engineer.json +346 -0
  26. claude_mpm/agents/templates/local_ops_agent.json +1227 -6
  27. claude_mpm/agents/templates/memory_manager.json +4 -1
  28. claude_mpm/agents/templates/nextjs_engineer.json +141 -133
  29. claude_mpm/agents/templates/ops.json +12 -2
  30. claude_mpm/agents/templates/php-engineer.json +270 -174
  31. claude_mpm/agents/templates/pm_examples.md +474 -0
  32. claude_mpm/agents/templates/pm_red_flags.md +240 -0
  33. claude_mpm/agents/templates/product_owner.json +338 -0
  34. claude_mpm/agents/templates/project_organizer.json +14 -4
  35. claude_mpm/agents/templates/prompt-engineer.json +13 -2
  36. claude_mpm/agents/templates/python_engineer.json +174 -81
  37. claude_mpm/agents/templates/qa.json +11 -2
  38. claude_mpm/agents/templates/react_engineer.json +16 -3
  39. claude_mpm/agents/templates/refactoring_engineer.json +12 -2
  40. claude_mpm/agents/templates/research.json +34 -21
  41. claude_mpm/agents/templates/response_format.md +583 -0
  42. claude_mpm/agents/templates/ruby-engineer.json +129 -192
  43. claude_mpm/agents/templates/rust_engineer.json +270 -0
  44. claude_mpm/agents/templates/security.json +10 -2
  45. claude_mpm/agents/templates/svelte-engineer.json +225 -0
  46. claude_mpm/agents/templates/ticketing.json +10 -2
  47. claude_mpm/agents/templates/typescript_engineer.json +116 -125
  48. claude_mpm/agents/templates/validation_templates.md +312 -0
  49. claude_mpm/agents/templates/vercel_ops_agent.json +12 -2
  50. claude_mpm/agents/templates/version_control.json +12 -2
  51. claude_mpm/agents/templates/web_qa.json +11 -2
  52. claude_mpm/agents/templates/web_ui.json +15 -2
  53. claude_mpm/cli/__init__.py +34 -614
  54. claude_mpm/cli/commands/agent_manager.py +25 -12
  55. claude_mpm/cli/commands/agent_state_manager.py +186 -0
  56. claude_mpm/cli/commands/agents.py +235 -148
  57. claude_mpm/cli/commands/agents_detect.py +380 -0
  58. claude_mpm/cli/commands/agents_recommend.py +309 -0
  59. claude_mpm/cli/commands/aggregate.py +7 -3
  60. claude_mpm/cli/commands/analyze.py +9 -4
  61. claude_mpm/cli/commands/analyze_code.py +7 -2
  62. claude_mpm/cli/commands/auto_configure.py +570 -0
  63. claude_mpm/cli/commands/config.py +47 -13
  64. claude_mpm/cli/commands/configure.py +419 -1571
  65. claude_mpm/cli/commands/configure_agent_display.py +261 -0
  66. claude_mpm/cli/commands/configure_behavior_manager.py +204 -0
  67. claude_mpm/cli/commands/configure_hook_manager.py +225 -0
  68. claude_mpm/cli/commands/configure_models.py +18 -0
  69. claude_mpm/cli/commands/configure_navigation.py +167 -0
  70. claude_mpm/cli/commands/configure_paths.py +104 -0
  71. claude_mpm/cli/commands/configure_persistence.py +254 -0
  72. claude_mpm/cli/commands/configure_startup_manager.py +646 -0
  73. claude_mpm/cli/commands/configure_template_editor.py +497 -0
  74. claude_mpm/cli/commands/configure_validators.py +73 -0
  75. claude_mpm/cli/commands/local_deploy.py +537 -0
  76. claude_mpm/cli/commands/memory.py +54 -20
  77. claude_mpm/cli/commands/mpm_init.py +585 -196
  78. claude_mpm/cli/commands/mpm_init_handler.py +37 -3
  79. claude_mpm/cli/commands/search.py +170 -4
  80. claude_mpm/cli/commands/upgrade.py +152 -0
  81. claude_mpm/cli/executor.py +202 -0
  82. claude_mpm/cli/helpers.py +105 -0
  83. claude_mpm/cli/interactive/__init__.py +3 -0
  84. claude_mpm/cli/interactive/skills_wizard.py +491 -0
  85. claude_mpm/cli/parsers/__init__.py +7 -1
  86. claude_mpm/cli/parsers/agents_parser.py +9 -0
  87. claude_mpm/cli/parsers/auto_configure_parser.py +245 -0
  88. claude_mpm/cli/parsers/base_parser.py +110 -3
  89. claude_mpm/cli/parsers/local_deploy_parser.py +227 -0
  90. claude_mpm/cli/parsers/mpm_init_parser.py +65 -5
  91. claude_mpm/cli/shared/output_formatters.py +28 -19
  92. claude_mpm/cli/startup.py +481 -0
  93. claude_mpm/cli/utils.py +52 -1
  94. claude_mpm/commands/mpm-agents-detect.md +168 -0
  95. claude_mpm/commands/mpm-agents-recommend.md +214 -0
  96. claude_mpm/commands/mpm-agents.md +75 -1
  97. claude_mpm/commands/mpm-auto-configure.md +217 -0
  98. claude_mpm/commands/mpm-help.md +163 -0
  99. claude_mpm/commands/mpm-init.md +148 -3
  100. claude_mpm/commands/mpm-version.md +113 -0
  101. claude_mpm/commands/mpm.md +1 -0
  102. claude_mpm/config/agent_config.py +2 -2
  103. claude_mpm/config/model_config.py +428 -0
  104. claude_mpm/constants.py +1 -0
  105. claude_mpm/core/base_service.py +13 -12
  106. claude_mpm/core/enums.py +452 -0
  107. claude_mpm/core/factories.py +1 -1
  108. claude_mpm/core/instruction_reinforcement_hook.py +2 -1
  109. claude_mpm/core/interactive_session.py +9 -3
  110. claude_mpm/core/log_manager.py +2 -0
  111. claude_mpm/core/logging_config.py +6 -2
  112. claude_mpm/core/oneshot_session.py +8 -4
  113. claude_mpm/core/optimized_agent_loader.py +3 -3
  114. claude_mpm/core/output_style_manager.py +12 -192
  115. claude_mpm/core/service_registry.py +5 -1
  116. claude_mpm/core/types.py +2 -9
  117. claude_mpm/core/typing_utils.py +7 -6
  118. claude_mpm/dashboard/static/js/dashboard.js +0 -14
  119. claude_mpm/dashboard/templates/index.html +3 -41
  120. claude_mpm/hooks/__init__.py +20 -0
  121. claude_mpm/hooks/claude_hooks/event_handlers.py +4 -2
  122. claude_mpm/hooks/claude_hooks/response_tracking.py +35 -1
  123. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +23 -2
  124. claude_mpm/hooks/failure_learning/__init__.py +60 -0
  125. claude_mpm/hooks/failure_learning/failure_detection_hook.py +235 -0
  126. claude_mpm/hooks/failure_learning/fix_detection_hook.py +217 -0
  127. claude_mpm/hooks/failure_learning/learning_extraction_hook.py +286 -0
  128. claude_mpm/hooks/instruction_reinforcement.py +7 -2
  129. claude_mpm/hooks/kuzu_enrichment_hook.py +263 -0
  130. claude_mpm/hooks/kuzu_memory_hook.py +37 -12
  131. claude_mpm/hooks/kuzu_response_hook.py +183 -0
  132. claude_mpm/models/resume_log.py +340 -0
  133. claude_mpm/services/agents/__init__.py +18 -5
  134. claude_mpm/services/agents/auto_config_manager.py +796 -0
  135. claude_mpm/services/agents/deployment/agent_configuration_manager.py +1 -1
  136. claude_mpm/services/agents/deployment/agent_record_service.py +1 -1
  137. claude_mpm/services/agents/deployment/agent_validator.py +17 -1
  138. claude_mpm/services/agents/deployment/async_agent_deployment.py +1 -1
  139. claude_mpm/services/agents/deployment/interface_adapter.py +3 -2
  140. claude_mpm/services/agents/deployment/local_template_deployment.py +1 -1
  141. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +7 -6
  142. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +7 -16
  143. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +4 -3
  144. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +5 -3
  145. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +6 -5
  146. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +9 -6
  147. claude_mpm/services/agents/deployment/validation/__init__.py +3 -1
  148. claude_mpm/services/agents/deployment/validation/validation_result.py +1 -9
  149. claude_mpm/services/agents/local_template_manager.py +1 -1
  150. claude_mpm/services/agents/memory/agent_memory_manager.py +5 -2
  151. claude_mpm/services/agents/observers.py +547 -0
  152. claude_mpm/services/agents/recommender.py +568 -0
  153. claude_mpm/services/agents/registry/modification_tracker.py +5 -2
  154. claude_mpm/services/command_handler_service.py +11 -5
  155. claude_mpm/services/core/__init__.py +33 -1
  156. claude_mpm/services/core/interfaces/__init__.py +90 -3
  157. claude_mpm/services/core/interfaces/agent.py +184 -0
  158. claude_mpm/services/core/interfaces/health.py +172 -0
  159. claude_mpm/services/core/interfaces/model.py +281 -0
  160. claude_mpm/services/core/interfaces/process.py +372 -0
  161. claude_mpm/services/core/interfaces/project.py +121 -0
  162. claude_mpm/services/core/interfaces/restart.py +307 -0
  163. claude_mpm/services/core/interfaces/stability.py +260 -0
  164. claude_mpm/services/core/memory_manager.py +11 -24
  165. claude_mpm/services/core/models/__init__.py +79 -0
  166. claude_mpm/services/core/models/agent_config.py +381 -0
  167. claude_mpm/services/core/models/health.py +162 -0
  168. claude_mpm/services/core/models/process.py +235 -0
  169. claude_mpm/services/core/models/restart.py +302 -0
  170. claude_mpm/services/core/models/stability.py +264 -0
  171. claude_mpm/services/core/models/toolchain.py +306 -0
  172. claude_mpm/services/core/path_resolver.py +23 -7
  173. claude_mpm/services/diagnostics/__init__.py +2 -2
  174. claude_mpm/services/diagnostics/checks/agent_check.py +25 -24
  175. claude_mpm/services/diagnostics/checks/claude_code_check.py +24 -23
  176. claude_mpm/services/diagnostics/checks/common_issues_check.py +25 -24
  177. claude_mpm/services/diagnostics/checks/configuration_check.py +24 -23
  178. claude_mpm/services/diagnostics/checks/filesystem_check.py +18 -17
  179. claude_mpm/services/diagnostics/checks/installation_check.py +30 -29
  180. claude_mpm/services/diagnostics/checks/instructions_check.py +20 -19
  181. claude_mpm/services/diagnostics/checks/mcp_check.py +50 -36
  182. claude_mpm/services/diagnostics/checks/mcp_services_check.py +38 -33
  183. claude_mpm/services/diagnostics/checks/monitor_check.py +23 -22
  184. claude_mpm/services/diagnostics/checks/startup_log_check.py +9 -8
  185. claude_mpm/services/diagnostics/diagnostic_runner.py +6 -5
  186. claude_mpm/services/diagnostics/doctor_reporter.py +28 -25
  187. claude_mpm/services/diagnostics/models.py +19 -24
  188. claude_mpm/services/infrastructure/monitoring/__init__.py +1 -1
  189. claude_mpm/services/infrastructure/monitoring/aggregator.py +12 -12
  190. claude_mpm/services/infrastructure/monitoring/base.py +5 -13
  191. claude_mpm/services/infrastructure/monitoring/network.py +7 -6
  192. claude_mpm/services/infrastructure/monitoring/process.py +13 -12
  193. claude_mpm/services/infrastructure/monitoring/resources.py +7 -6
  194. claude_mpm/services/infrastructure/monitoring/service.py +16 -15
  195. claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
  196. claude_mpm/services/local_ops/__init__.py +163 -0
  197. claude_mpm/services/local_ops/crash_detector.py +257 -0
  198. claude_mpm/services/local_ops/health_checks/__init__.py +28 -0
  199. claude_mpm/services/local_ops/health_checks/http_check.py +224 -0
  200. claude_mpm/services/local_ops/health_checks/process_check.py +236 -0
  201. claude_mpm/services/local_ops/health_checks/resource_check.py +255 -0
  202. claude_mpm/services/local_ops/health_manager.py +430 -0
  203. claude_mpm/services/local_ops/log_monitor.py +396 -0
  204. claude_mpm/services/local_ops/memory_leak_detector.py +294 -0
  205. claude_mpm/services/local_ops/process_manager.py +595 -0
  206. claude_mpm/services/local_ops/resource_monitor.py +331 -0
  207. claude_mpm/services/local_ops/restart_manager.py +401 -0
  208. claude_mpm/services/local_ops/restart_policy.py +387 -0
  209. claude_mpm/services/local_ops/state_manager.py +372 -0
  210. claude_mpm/services/local_ops/unified_manager.py +600 -0
  211. claude_mpm/services/mcp_config_manager.py +9 -4
  212. claude_mpm/services/mcp_gateway/core/__init__.py +1 -2
  213. claude_mpm/services/mcp_gateway/core/base.py +18 -31
  214. claude_mpm/services/mcp_gateway/main.py +30 -0
  215. claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +206 -32
  216. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +30 -28
  217. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +25 -5
  218. claude_mpm/services/mcp_service_verifier.py +1 -1
  219. claude_mpm/services/memory/failure_tracker.py +563 -0
  220. claude_mpm/services/memory_hook_service.py +165 -4
  221. claude_mpm/services/model/__init__.py +147 -0
  222. claude_mpm/services/model/base_provider.py +365 -0
  223. claude_mpm/services/model/claude_provider.py +412 -0
  224. claude_mpm/services/model/model_router.py +453 -0
  225. claude_mpm/services/model/ollama_provider.py +415 -0
  226. claude_mpm/services/monitor/daemon_manager.py +3 -2
  227. claude_mpm/services/monitor/handlers/dashboard.py +2 -1
  228. claude_mpm/services/monitor/handlers/hooks.py +2 -1
  229. claude_mpm/services/monitor/management/lifecycle.py +3 -2
  230. claude_mpm/services/monitor/server.py +2 -1
  231. claude_mpm/services/project/__init__.py +23 -0
  232. claude_mpm/services/project/detection_strategies.py +719 -0
  233. claude_mpm/services/project/toolchain_analyzer.py +581 -0
  234. claude_mpm/services/self_upgrade_service.py +342 -0
  235. claude_mpm/services/session_management_service.py +3 -2
  236. claude_mpm/services/session_manager.py +205 -1
  237. claude_mpm/services/shared/async_service_base.py +16 -27
  238. claude_mpm/services/shared/lifecycle_service_base.py +1 -14
  239. claude_mpm/services/socketio/handlers/__init__.py +5 -2
  240. claude_mpm/services/socketio/handlers/hook.py +13 -2
  241. claude_mpm/services/socketio/handlers/registry.py +4 -2
  242. claude_mpm/services/socketio/server/main.py +10 -8
  243. claude_mpm/services/subprocess_launcher_service.py +14 -5
  244. claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +8 -7
  245. claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +6 -5
  246. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +8 -7
  247. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +7 -6
  248. claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +5 -4
  249. claude_mpm/services/unified/config_strategies/validation_strategy.py +13 -9
  250. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +10 -3
  251. claude_mpm/services/unified/deployment_strategies/local.py +6 -5
  252. claude_mpm/services/unified/deployment_strategies/utils.py +6 -5
  253. claude_mpm/services/unified/deployment_strategies/vercel.py +7 -6
  254. claude_mpm/services/unified/interfaces.py +3 -1
  255. claude_mpm/services/unified/unified_analyzer.py +14 -10
  256. claude_mpm/services/unified/unified_config.py +2 -1
  257. claude_mpm/services/unified/unified_deployment.py +9 -4
  258. claude_mpm/services/version_service.py +104 -1
  259. claude_mpm/skills/__init__.py +21 -0
  260. claude_mpm/skills/bundled/__init__.py +6 -0
  261. claude_mpm/skills/bundled/api-documentation.md +393 -0
  262. claude_mpm/skills/bundled/async-testing.md +571 -0
  263. claude_mpm/skills/bundled/code-review.md +143 -0
  264. claude_mpm/skills/bundled/database-migration.md +199 -0
  265. claude_mpm/skills/bundled/docker-containerization.md +194 -0
  266. claude_mpm/skills/bundled/express-local-dev.md +1429 -0
  267. claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
  268. claude_mpm/skills/bundled/git-workflow.md +414 -0
  269. claude_mpm/skills/bundled/imagemagick.md +204 -0
  270. claude_mpm/skills/bundled/json-data-handling.md +223 -0
  271. claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
  272. claude_mpm/skills/bundled/pdf.md +141 -0
  273. claude_mpm/skills/bundled/performance-profiling.md +567 -0
  274. claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
  275. claude_mpm/skills/bundled/security-scanning.md +327 -0
  276. claude_mpm/skills/bundled/systematic-debugging.md +473 -0
  277. claude_mpm/skills/bundled/test-driven-development.md +378 -0
  278. claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
  279. claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
  280. claude_mpm/skills/bundled/xlsx.md +157 -0
  281. claude_mpm/skills/registry.py +286 -0
  282. claude_mpm/skills/skill_manager.py +310 -0
  283. claude_mpm/storage/state_storage.py +15 -15
  284. claude_mpm/tools/code_tree_analyzer.py +177 -141
  285. claude_mpm/tools/code_tree_events.py +4 -2
  286. claude_mpm/utils/agent_dependency_loader.py +40 -20
  287. claude_mpm/utils/display_helper.py +260 -0
  288. claude_mpm/utils/git_analyzer.py +407 -0
  289. claude_mpm/utils/robust_installer.py +73 -19
  290. {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/METADATA +129 -12
  291. {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/RECORD +295 -193
  292. claude_mpm/dashboard/static/css/code-tree.css +0 -1639
  293. claude_mpm/dashboard/static/index-hub-backup.html +0 -713
  294. claude_mpm/dashboard/static/js/components/code-tree/tree-breadcrumb.js +0 -353
  295. claude_mpm/dashboard/static/js/components/code-tree/tree-constants.js +0 -235
  296. claude_mpm/dashboard/static/js/components/code-tree/tree-search.js +0 -409
  297. claude_mpm/dashboard/static/js/components/code-tree/tree-utils.js +0 -435
  298. claude_mpm/dashboard/static/js/components/code-tree.js +0 -5869
  299. claude_mpm/dashboard/static/js/components/code-viewer.js +0 -1386
  300. claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +0 -425
  301. claude_mpm/hooks/claude_hooks/hook_handler_original.py +0 -1041
  302. claude_mpm/hooks/claude_hooks/hook_handler_refactored.py +0 -347
  303. claude_mpm/services/agents/deployment/agent_lifecycle_manager_refactored.py +0 -575
  304. claude_mpm/services/project/analyzer_refactored.py +0 -450
  305. {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/WHEEL +0 -0
  306. {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/entry_points.txt +0 -0
  307. {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/licenses/LICENSE +0 -0
  308. {claude_mpm-4.7.4.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
@@ -122,6 +156,9 @@ class AgentsCommand(AgentCommand):
122
156
  "delete": self._delete_local_agent,
123
157
  "manage": self._manage_local_agents,
124
158
  "configure": self._configure_deployment,
159
+ # Auto-configuration commands (TSK-0054 Phase 5)
160
+ "detect": self._detect_toolchain,
161
+ "recommend": self._recommend_agents,
125
162
  }
126
163
 
127
164
  if args.agents_command in command_map:
@@ -142,14 +179,14 @@ class AgentsCommand(AgentCommand):
142
179
  try:
143
180
  agent_versions = get_agent_versions_display()
144
181
 
145
- output_format = getattr(args, "format", "text")
146
- if output_format in ["json", "yaml"]:
182
+ output_format = self._get_output_format(args)
183
+ if self._is_structured_format(output_format):
147
184
  # Parse the agent versions display into structured data
148
185
  if agent_versions:
149
186
  data = {"agent_versions": agent_versions, "has_agents": True}
150
187
  formatted = (
151
188
  self._formatter.format_as_json(data)
152
- if output_format == "json"
189
+ if str(output_format).lower() == OutputFormat.JSON
153
190
  else self._formatter.format_as_yaml(data)
154
191
  )
155
192
  print(formatted)
@@ -163,7 +200,7 @@ class AgentsCommand(AgentCommand):
163
200
  }
164
201
  formatted = (
165
202
  self._formatter.format_as_json(data)
166
- if output_format == "json"
203
+ if str(output_format).lower() == OutputFormat.JSON
167
204
  else self._formatter.format_as_yaml(data)
168
205
  )
169
206
  print(formatted)
@@ -185,7 +222,7 @@ class AgentsCommand(AgentCommand):
185
222
  def _list_agents(self, args) -> CommandResult:
186
223
  """List available or deployed agents."""
187
224
  try:
188
- output_format = getattr(args, "format", "text")
225
+ output_format = self._get_output_format(args)
189
226
 
190
227
  if hasattr(args, "by_tier") and args.by_tier:
191
228
  return self._list_agents_by_tier(args)
@@ -196,7 +233,7 @@ class AgentsCommand(AgentCommand):
196
233
  # Default: show usage
197
234
  usage_msg = "Use --system to list system agents, --deployed to list deployed agents, or --by-tier to group by precedence"
198
235
 
199
- if output_format in ["json", "yaml"]:
236
+ if self._is_structured_format(output_format):
200
237
  return CommandResult.error_result(
201
238
  "No list option specified",
202
239
  data={
@@ -217,7 +254,7 @@ class AgentsCommand(AgentCommand):
217
254
  verbose = getattr(args, "verbose", False)
218
255
  agents = self.listing_service.list_system_agents(verbose=verbose)
219
256
 
220
- output_format = getattr(args, "format", "text")
257
+ output_format = self._get_output_format(args)
221
258
  quiet = getattr(args, "quiet", False)
222
259
 
223
260
  # Convert AgentInfo objects to dicts for formatter
@@ -256,7 +293,7 @@ class AgentsCommand(AgentCommand):
256
293
  verbose=verbose
257
294
  )
258
295
 
259
- output_format = getattr(args, "format", "text")
296
+ output_format = self._get_output_format(args)
260
297
  quiet = getattr(args, "quiet", False)
261
298
 
262
299
  # Convert AgentInfo objects to dicts for formatter
@@ -281,7 +318,7 @@ class AgentsCommand(AgentCommand):
281
318
  print(formatted)
282
319
 
283
320
  # Add warnings for text output
284
- if output_format == "text" and warnings:
321
+ if str(output_format).lower() == OutputFormat.TEXT and warnings:
285
322
  print("\nWarnings:")
286
323
  for warning in warnings:
287
324
  print(f" ⚠️ {warning}")
@@ -303,7 +340,7 @@ class AgentsCommand(AgentCommand):
303
340
  """List agents grouped by tier/precedence."""
304
341
  try:
305
342
  tier_info = self.listing_service.list_agents_by_tier()
306
- output_format = getattr(args, "format", "text")
343
+ output_format = self._get_output_format(args)
307
344
 
308
345
  # Convert to format expected by formatter
309
346
  agents_by_tier = {
@@ -386,7 +423,7 @@ class AgentsCommand(AgentCommand):
386
423
  or project_result.get("target_dir"),
387
424
  }
388
425
 
389
- output_format = getattr(args, "format", "text")
426
+ output_format = self._get_output_format(args)
390
427
  verbose = getattr(args, "verbose", False)
391
428
 
392
429
  formatted = self._formatter.format_deployment_result(
@@ -412,7 +449,7 @@ class AgentsCommand(AgentCommand):
412
449
  try:
413
450
  result = self.cleanup_service.clean_deployed_agents()
414
451
 
415
- output_format = getattr(args, "format", "text")
452
+ output_format = self._get_output_format(args)
416
453
  dry_run = False # Regular clean is not a dry run
417
454
 
418
455
  formatted = self._formatter.format_cleanup_result(
@@ -450,7 +487,7 @@ class AgentsCommand(AgentCommand):
450
487
  f"Could not retrieve details for agent '{agent_name}'"
451
488
  )
452
489
 
453
- output_format = getattr(args, "format", "text")
490
+ output_format = self._get_output_format(args)
454
491
  verbose = getattr(args, "verbose", False)
455
492
 
456
493
  formatted = self._formatter.format_agent_details(
@@ -472,148 +509,170 @@ class AgentsCommand(AgentCommand):
472
509
  dry_run = getattr(args, "dry_run", False)
473
510
  agent_name = getattr(args, "agent_name", None)
474
511
  fix_all = getattr(args, "all", False)
512
+ output_format = self._get_output_format(args)
475
513
 
476
- output_format = getattr(args, "format", "text")
477
-
478
- # Determine what to fix
514
+ # Route to appropriate handler based on input
479
515
  if fix_all:
480
- # Fix all agents
481
- result = self.validation_service.fix_all_agents(dry_run=dry_run)
482
-
483
- if output_format in ["json", "yaml"]:
484
- formatted = (
485
- self._formatter.format_as_json(result)
486
- if output_format == "json"
487
- else self._formatter.format_as_yaml(result)
488
- )
489
- print(formatted)
490
- else:
491
- # Text output
492
- mode = "DRY RUN" if dry_run else "FIX"
493
- print(
494
- f"\n🔧 {mode}: Checking {result.get('total_agents', 0)} agent(s) for frontmatter issues...\n"
495
- )
496
-
497
- if result.get("results"):
498
- for agent_result in result["results"]:
499
- print(f"📄 {agent_result['agent']}:")
500
- if agent_result.get("skipped"):
501
- print(
502
- f" ⚠️ Skipped: {agent_result.get('reason', 'Unknown reason')}"
503
- )
504
- elif agent_result.get("was_valid"):
505
- print(" ✓ No issues found")
506
- else:
507
- if agent_result.get("errors_found", 0) > 0:
508
- print(
509
- f" ❌ Errors found: {agent_result['errors_found']}"
510
- )
511
- if agent_result.get("warnings_found", 0) > 0:
512
- print(
513
- f" ⚠️ Warnings found: {agent_result['warnings_found']}"
514
- )
515
- if dry_run:
516
- if agent_result.get("corrections_available", 0) > 0:
517
- print(
518
- f" 🔧 Would fix: {agent_result['corrections_available']} issues"
519
- )
520
- elif agent_result.get("corrections_made", 0) > 0:
521
- print(
522
- f" ✓ Fixed: {agent_result['corrections_made']} issues"
523
- )
524
- print()
525
-
526
- # Summary
527
- print("=" * 80)
528
- print("SUMMARY:")
529
- print(f" Agents checked: {result.get('agents_checked', 0)}")
530
- print(
531
- f" Total issues found: {result.get('total_issues_found', 0)}"
532
- )
533
- if dry_run:
534
- print(
535
- f" Issues that would be fixed: {result.get('total_corrections_available', 0)}"
536
- )
537
- print("\n💡 Run without --dry-run to apply fixes")
538
- else:
539
- print(
540
- f" Issues fixed: {result.get('total_corrections_made', 0)}"
541
- )
542
- if result.get("total_corrections_made", 0) > 0:
543
- print("\n✓ Frontmatter issues have been fixed!")
544
- 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)
545
520
 
546
- msg = f"{'Would fix' if dry_run else 'Fixed'} {result.get('total_corrections_available' if dry_run else 'total_corrections_made', 0)} issues"
547
- 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}")
548
524
 
549
- if agent_name:
550
- # Fix specific agent
551
- result = self.validation_service.fix_agent_frontmatter(
552
- agent_name, dry_run=dry_run
553
- )
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)
554
528
 
555
- if not result.get("success"):
556
- return CommandResult.error_result(
557
- result.get("error", "Failed to fix agent")
558
- )
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)
559
533
 
560
- if output_format in ["json", "yaml"]:
561
- formatted = (
562
- self._formatter.format_as_json(result)
563
- if output_format == "json"
564
- else self._formatter.format_as_yaml(result)
565
- )
566
- print(formatted)
567
- else:
568
- # Text output
569
- mode = "DRY RUN" if dry_run else "FIX"
570
- print(
571
- f"\n🔧 {mode}: Checking agent '{agent_name}' for frontmatter issues...\n"
572
- )
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)
573
536
 
574
- print(f"📄 {agent_name}:")
575
- if result.get("was_valid"):
576
- print(" ✓ No issues found")
577
- else:
578
- if result.get("errors_found"):
579
- print(" ❌ Errors:")
580
- for error in result["errors_found"]:
581
- print(f" - {error}")
582
- if result.get("warnings_found"):
583
- print(" ⚠️ Warnings:")
584
- for warning in result["warnings_found"]:
585
- print(f" - {warning}")
586
- if dry_run:
587
- if result.get("corrections_available"):
588
- print(" 🔧 Would fix:")
589
- for correction in result["corrections_available"]:
590
- print(f" - {correction}")
591
- elif result.get("corrections_made"):
592
- print(" ✓ Fixed:")
593
- for correction in result["corrections_made"]:
594
- print(f" - {correction}")
595
- 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
+ )
596
544
 
597
- if dry_run and result.get("corrections_available"):
598
- print("💡 Run without --dry-run to apply fixes\n")
599
- elif not dry_run and result.get("corrections_made"):
600
- 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
+ )
601
549
 
602
- msg = f"{'Would fix' if dry_run else 'Fixed'} agent '{agent_name}'"
603
- 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)
604
554
 
605
- # No agent specified and not --all
606
- usage_msg = "Please specify an agent name or use --all to fix all agents\nUsage: claude-mpm agents fix [agent_name] [--dry-run] [--all]"
607
- if output_format in ["json", "yaml"]:
608
- return CommandResult.error_result(
609
- "No agent specified", data={"usage": usage_msg}
610
- )
611
- print(f"❌ {usage_msg}")
612
- 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)
613
557
 
614
- except Exception as e:
615
- self.logger.error(f"Error fixing agents: {e}", exc_info=True)
616
- 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")
617
676
 
618
677
  def _check_agent_dependencies(self, args) -> CommandResult:
619
678
  """Check agent dependencies."""
@@ -693,7 +752,7 @@ class AgentsCommand(AgentCommand):
693
752
  def _list_agent_dependencies(self, args) -> CommandResult:
694
753
  """List agent dependencies."""
695
754
  try:
696
- output_format = getattr(args, "format", "text")
755
+ output_format = self._get_output_format(args)
697
756
  result = self.dependency_service.list_dependencies(
698
757
  format_type=output_format
699
758
  )
@@ -705,7 +764,7 @@ class AgentsCommand(AgentCommand):
705
764
  if output_format == "pip":
706
765
  for dep in result["dependencies"]:
707
766
  print(dep)
708
- elif output_format == "json":
767
+ elif str(output_format).lower() == OutputFormat.JSON:
709
768
  print(json.dumps(result["data"], indent=2))
710
769
  else: # text format
711
770
  print("=" * 60)
@@ -863,7 +922,7 @@ class AgentsCommand(AgentCommand):
863
922
  agents_dir=agents_dir, dry_run=dry_run
864
923
  )
865
924
 
866
- output_format = getattr(args, "format", "text")
925
+ output_format = self._get_output_format(args)
867
926
 
868
927
  formatted = self._formatter.format_cleanup_result(
869
928
  results, output_format=output_format, dry_run=dry_run
@@ -1361,6 +1420,34 @@ class AgentsCommand(AgentCommand):
1361
1420
  f"Error in interactive configuration: {e}"
1362
1421
  )
1363
1422
 
1423
+ def _detect_toolchain(self, args) -> CommandResult:
1424
+ """Detect project toolchain without deploying agents.
1425
+
1426
+ Part of TSK-0054 Phase 5: Auto-configuration CLI integration.
1427
+ """
1428
+ try:
1429
+ from .agents_detect import AgentsDetectCommand
1430
+
1431
+ cmd = AgentsDetectCommand()
1432
+ return cmd.run(args)
1433
+ except Exception as e:
1434
+ self.logger.error(f"Error detecting toolchain: {e}", exc_info=True)
1435
+ return CommandResult.error_result(f"Error detecting toolchain: {e}")
1436
+
1437
+ def _recommend_agents(self, args) -> CommandResult:
1438
+ """Recommend agents based on project toolchain.
1439
+
1440
+ Part of TSK-0054 Phase 5: Auto-configuration CLI integration.
1441
+ """
1442
+ try:
1443
+ from .agents_recommend import AgentsRecommendCommand
1444
+
1445
+ cmd = AgentsRecommendCommand()
1446
+ return cmd.run(args)
1447
+ except Exception as e:
1448
+ self.logger.error(f"Error recommending agents: {e}", exc_info=True)
1449
+ return CommandResult.error_result(f"Error recommending agents: {e}")
1450
+
1364
1451
 
1365
1452
  def manage_agents(args):
1366
1453
  """
@@ -1372,7 +1459,7 @@ def manage_agents(args):
1372
1459
  result = command.execute(args)
1373
1460
 
1374
1461
  # Print result if structured output format is requested
1375
- if hasattr(args, "format") and args.format in ["json", "yaml"]:
1462
+ if _is_structured_output(args):
1376
1463
  command.print_result(result, args)
1377
1464
 
1378
1465
  return result.exit_code