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
@@ -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
 
@@ -25,6 +27,39 @@ def manage_mpm_init(args):
25
27
  # Import the command implementation
26
28
  from .mpm_init import MPMInitCommand
27
29
 
30
+ # Handle context subcommands
31
+ subcommand = getattr(args, "subcommand", None)
32
+
33
+ if subcommand in ("context", "resume"):
34
+ # Show deprecation warning for 'resume'
35
+ if subcommand == "resume":
36
+ console.print(
37
+ "[yellow]⚠️ Warning: 'resume' is deprecated. Use 'context' instead.[/yellow]"
38
+ )
39
+ console.print("[dim]Run: claude-mpm mpm-init context[/dim]\n")
40
+
41
+ # Get project path
42
+ project_path = (
43
+ Path(args.project_path) if hasattr(args, "project_path") else Path.cwd()
44
+ )
45
+
46
+ # Create command instance
47
+ command = MPMInitCommand(project_path)
48
+
49
+ # Handle context with optional session ID and days
50
+ result = command.handle_context(
51
+ session_id=getattr(args, "session_id", None),
52
+ days=getattr(args, "days", 7),
53
+ )
54
+
55
+ # Return appropriate exit code
56
+ if result.get("status") in (
57
+ OperationResult.SUCCESS,
58
+ OperationResult.CONTEXT_READY,
59
+ ):
60
+ return 0
61
+ return 1
62
+
28
63
  # Handle special flags
29
64
  if getattr(args, "list_templates", False):
30
65
  # List available templates
@@ -55,7 +90,6 @@ def manage_mpm_init(args):
55
90
  "framework": getattr(args, "framework", None),
56
91
  "force": getattr(args, "force", False),
57
92
  "verbose": getattr(args, "verbose", False),
58
- "use_venv": getattr(args, "use_venv", False),
59
93
  "ast_analysis": getattr(args, "ast_analysis", True),
60
94
  "update_mode": getattr(args, "update", False),
61
95
  "review_only": getattr(args, "review", False),
@@ -73,9 +107,9 @@ def manage_mpm_init(args):
73
107
  result = command.initialize_project(**init_params)
74
108
 
75
109
  # Return appropriate exit code
76
- if result.get("status") == "success":
110
+ if result.get("status") == OperationResult.SUCCESS:
77
111
  return 0
78
- if result.get("status") == "cancelled":
112
+ if result.get("status") == OperationResult.CANCELLED:
79
113
  return 130 # User cancelled
80
114
  return 1 # Error
81
115
 
@@ -16,8 +16,7 @@ from rich.panel import Panel
16
16
  from rich.syntax import Syntax
17
17
  from rich.table import Table
18
18
 
19
- from claude_mpm.cli.utils import handle_async_errors
20
- from claude_mpm.services.service_container import get_service_container
19
+ from claude_mpm.services.core.service_container import get_global_container
21
20
 
22
21
  console = Console()
23
22
 
@@ -27,8 +26,9 @@ class MCPSearchInterface:
27
26
 
28
27
  def __init__(self):
29
28
  """Initialize the search interface."""
30
- self.container = get_service_container()
29
+ self.container = get_global_container()
31
30
  self.mcp_gateway = None
31
+ self.vector_search_available = False
32
32
 
33
33
  async def initialize(self):
34
34
  """Initialize the MCP gateway connection."""
@@ -39,10 +39,127 @@ class MCPSearchInterface:
39
39
  if not self.mcp_gateway:
40
40
  self.mcp_gateway = MCPGatewayService()
41
41
  await self.mcp_gateway.initialize()
42
+
43
+ # Check if vector search is available
44
+ self.vector_search_available = await self._check_vector_search_available()
45
+
42
46
  except Exception as e:
43
47
  console.print(f"[red]Failed to initialize MCP gateway: {e}[/red]")
44
48
  raise
45
49
 
50
+ async def _check_vector_search_available(self) -> bool:
51
+ """Check if mcp-vector-search is available and offer installation if not."""
52
+ import importlib.util
53
+
54
+ # Check if package is installed
55
+ spec = importlib.util.find_spec("mcp_vector_search")
56
+ if spec is not None:
57
+ return True
58
+
59
+ # Package not found - offer installation
60
+ console.print("\n[yellow]⚠️ mcp-vector-search not found[/yellow]")
61
+ console.print("This package enables semantic code search (optional feature).")
62
+ console.print("\nInstallation options:")
63
+ console.print(" 1. Install via pip (recommended for this project)")
64
+ console.print(" 2. Install via pipx (isolated, system-wide)")
65
+ console.print(" 3. Skip (use traditional grep/glob instead)")
66
+
67
+ try:
68
+ choice = input("\nChoose option (1/2/3) [3]: ").strip() or "3"
69
+
70
+ if choice == "1":
71
+ return await self._install_via_pip()
72
+ if choice == "2":
73
+ return await self._install_via_pipx()
74
+ console.print(
75
+ "[dim]Continuing with fallback search methods (grep/glob)[/dim]"
76
+ )
77
+ return False
78
+
79
+ except (EOFError, KeyboardInterrupt):
80
+ console.print("\n[dim]Installation cancelled, using fallback methods[/dim]")
81
+ return False
82
+
83
+ async def _install_via_pip(self) -> bool:
84
+ """Install mcp-vector-search via pip."""
85
+ import subprocess
86
+
87
+ try:
88
+ console.print("\n[cyan]📦 Installing mcp-vector-search via pip...[/cyan]")
89
+ result = subprocess.run(
90
+ [sys.executable, "-m", "pip", "install", "mcp-vector-search"],
91
+ capture_output=True,
92
+ text=True,
93
+ timeout=120,
94
+ check=False,
95
+ )
96
+
97
+ if result.returncode == 0:
98
+ console.print(
99
+ "[green]✓ Successfully installed mcp-vector-search[/green]"
100
+ )
101
+ return True
102
+
103
+ error_msg = result.stderr.strip() if result.stderr else "Unknown error"
104
+ console.print(f"[red]✗ Installation failed: {error_msg}[/red]")
105
+ return False
106
+
107
+ except subprocess.TimeoutExpired:
108
+ console.print("[red]✗ Installation timed out[/red]")
109
+ return False
110
+ except Exception as e:
111
+ console.print(f"[red]✗ Installation error: {e}[/red]")
112
+ return False
113
+
114
+ async def _install_via_pipx(self) -> bool:
115
+ """Install mcp-vector-search via pipx."""
116
+ import subprocess
117
+
118
+ try:
119
+ # Check if pipx is available
120
+ pipx_check = subprocess.run(
121
+ ["pipx", "--version"],
122
+ capture_output=True,
123
+ text=True,
124
+ timeout=5,
125
+ check=False,
126
+ )
127
+
128
+ if pipx_check.returncode != 0:
129
+ console.print("[red]✗ pipx is not installed[/red]")
130
+ console.print("Install pipx first: python -m pip install pipx")
131
+ return False
132
+
133
+ console.print("\n[cyan]📦 Installing mcp-vector-search via pipx...[/cyan]")
134
+ result = subprocess.run(
135
+ ["pipx", "install", "mcp-vector-search"],
136
+ capture_output=True,
137
+ text=True,
138
+ timeout=120,
139
+ check=False,
140
+ )
141
+
142
+ if result.returncode == 0:
143
+ console.print(
144
+ "[green]✓ Successfully installed mcp-vector-search[/green]"
145
+ )
146
+ return True
147
+
148
+ error_msg = result.stderr.strip() if result.stderr else "Unknown error"
149
+ console.print(f"[red]✗ Installation failed: {error_msg}[/red]")
150
+ return False
151
+
152
+ except FileNotFoundError:
153
+ console.print("[red]✗ pipx command not found[/red]")
154
+ console.print("Install pipx first: python -m pip install pipx")
155
+ return False
156
+ except subprocess.TimeoutExpired:
157
+ console.print("[red]✗ Installation timed out[/red]")
158
+ return False
159
+ except Exception as e:
160
+ console.print(f"[red]✗ Installation error: {e}[/red]")
161
+ return False
162
+
46
163
  async def search_code(
47
164
  self,
48
165
  query: str,
@@ -125,6 +242,12 @@ class MCPSearchInterface:
125
242
  if not self.mcp_gateway:
126
243
  await self.initialize()
127
244
 
245
+ # Check if vector search is available
246
+ if not self.vector_search_available:
247
+ return {
248
+ "error": "mcp-vector-search is not available. Use traditional grep/glob tools instead, or run command again to install."
249
+ }
250
+
128
251
  try:
129
252
  return await self.mcp_gateway.call_tool(tool_name, params)
130
253
  except Exception as e:
@@ -196,7 +319,6 @@ def display_search_results(results: Dict[str, Any], output_format: str = "rich")
196
319
  @click.option("--focus", multiple=True, help="Focus areas (with --context)")
197
320
  @click.option("--force", is_flag=True, help="Force reindexing (with --index)")
198
321
  @click.option("--json", "output_json", is_flag=True, help="Output results as JSON")
199
- @handle_async_errors
200
322
  async def search_command(
201
323
  query: Optional[str],
202
324
  similar: Optional[str],
@@ -228,8 +350,24 @@ async def search_command(
228
350
  output_format = "json" if output_json else "rich"
229
351
 
230
352
  try:
353
+ # Show first-time usage tips if vector search is available
354
+ if search.vector_search_available and not (index or status):
355
+ console.print(
356
+ "\n[dim]💡 Tip: Vector search provides semantic code understanding.[/dim]"
357
+ )
358
+ console.print(
359
+ "[dim] Run with --index first to index your project.[/dim]\n"
360
+ )
361
+
231
362
  # Handle different operation modes
232
363
  if index:
364
+ if not search.vector_search_available:
365
+ console.print("[red]✗ mcp-vector-search is required for indexing[/red]")
366
+ console.print(
367
+ "[dim]Install it or use traditional grep/glob for search[/dim]"
368
+ )
369
+ sys.exit(1)
370
+
233
371
  console.print("[cyan]Indexing project...[/cyan]")
234
372
  result = await search.index_project(
235
373
  force=force, file_extensions=list(extensions) if extensions else None
@@ -239,10 +377,23 @@ async def search_command(
239
377
  display_search_results(result, output_format)
240
378
 
241
379
  elif status:
380
+ if not search.vector_search_available:
381
+ console.print(
382
+ "[red]✗ mcp-vector-search is required for status check[/red]"
383
+ )
384
+ console.print("[dim]Install it to use vector search features[/dim]")
385
+ sys.exit(1)
386
+
242
387
  result = await search.get_status()
243
388
  display_search_results(result, output_format)
244
389
 
245
390
  elif similar:
391
+ if not search.vector_search_available:
392
+ console.print("[yellow]⚠️ Vector search not available[/yellow]")
393
+ console.print("[dim]Similarity search requires mcp-vector-search[/dim]")
394
+ console.print("[dim]Falling back to basic file search...[/dim]")
395
+ sys.exit(1)
396
+
246
397
  result = await search.search_similar(
247
398
  file_path=similar,
248
399
  function_name=function,
@@ -252,6 +403,12 @@ async def search_command(
252
403
  display_search_results(result, output_format)
253
404
 
254
405
  elif context:
406
+ if not search.vector_search_available:
407
+ console.print("[yellow]⚠️ Vector search not available[/yellow]")
408
+ console.print("[dim]Context search requires mcp-vector-search[/dim]")
409
+ console.print("[dim]Try using grep for text-based search instead[/dim]")
410
+ sys.exit(1)
411
+
255
412
  result = await search.search_context(
256
413
  description=context,
257
414
  focus_areas=list(focus) if focus else None,
@@ -260,6 +417,15 @@ async def search_command(
260
417
  display_search_results(result, output_format)
261
418
 
262
419
  elif query:
420
+ if not search.vector_search_available:
421
+ console.print("[yellow]⚠️ Vector search not available[/yellow]")
422
+ console.print("[dim]Code search requires mcp-vector-search[/dim]")
423
+ console.print(
424
+ "\n[cyan]Alternative: Use grep for pattern matching:[/cyan]"
425
+ )
426
+ console.print(f" grep -r '{query}' .")
427
+ sys.exit(1)
428
+
263
429
  result = await search.search_code(
264
430
  query=query,
265
431
  limit=limit,
@@ -0,0 +1,152 @@
1
+ """
2
+ Upgrade command implementation for claude-mpm.
3
+
4
+ WHY: This module provides a manual upgrade command that allows users to check
5
+ for and install the latest version of claude-mpm without waiting for the
6
+ automatic startup check.
7
+
8
+ DESIGN DECISIONS:
9
+ - Use BaseCommand for consistent CLI patterns
10
+ - Leverage SelfUpgradeService for upgrade functionality
11
+ - Support multiple installation methods (pip, pipx, npm)
12
+ - Skip editable/development installations (must upgrade manually)
13
+ - Provide clear feedback on available updates and upgrade progress
14
+ """
15
+
16
+ import asyncio
17
+
18
+ from ..shared import BaseCommand, CommandResult
19
+
20
+
21
+ class UpgradeCommand(BaseCommand):
22
+ """Upgrade command using shared utilities."""
23
+
24
+ def __init__(self):
25
+ super().__init__("upgrade")
26
+
27
+ def validate_args(self, args) -> str:
28
+ """Validate command arguments."""
29
+ # Upgrade command doesn't require specific validation
30
+ return None
31
+
32
+ def run(self, args) -> CommandResult:
33
+ """Execute the upgrade command."""
34
+ try:
35
+ from ...services.self_upgrade_service import (
36
+ InstallationMethod,
37
+ SelfUpgradeService,
38
+ )
39
+
40
+ # Create upgrade service
41
+ upgrade_service = SelfUpgradeService()
42
+
43
+ # Check installation method
44
+ if upgrade_service.installation_method == InstallationMethod.EDITABLE:
45
+ self.logger.info(
46
+ "Editable installation detected - upgrade must be done manually"
47
+ )
48
+ print("\n⚠️ Editable Installation Detected")
49
+ print(
50
+ "\nYou are running claude-mpm from an editable installation (development mode)."
51
+ )
52
+ print("To upgrade, run:")
53
+ print(" cd /path/to/claude-mpm")
54
+ print(" git pull")
55
+ print(" pip install -e .")
56
+ return CommandResult.success_result(
57
+ "Upgrade information provided for editable installation"
58
+ )
59
+
60
+ # Check for updates
61
+ print("\n🔍 Checking for updates...")
62
+ loop = asyncio.new_event_loop()
63
+ asyncio.set_event_loop(loop)
64
+ try:
65
+ update_info = loop.run_until_complete(
66
+ upgrade_service.check_for_update()
67
+ )
68
+ finally:
69
+ loop.close()
70
+
71
+ if not update_info or not update_info.get("update_available"):
72
+ print(
73
+ f"\n✅ You are already on the latest version (v{upgrade_service.current_version})"
74
+ )
75
+ return CommandResult.success_result("Already on latest version")
76
+
77
+ # Display update information
78
+ current = update_info["current"]
79
+ latest = update_info["latest"]
80
+ method = update_info.get("installation_method", "unknown")
81
+
82
+ print("\n🎉 New version available!")
83
+ print(f" Current: v{current}")
84
+ print(f" Latest: v{latest}")
85
+ print(f" Installation method: {method}")
86
+
87
+ # Check if --yes flag is set for non-interactive upgrade
88
+ force_upgrade = getattr(args, "yes", False) or getattr(args, "force", False)
89
+
90
+ if not force_upgrade:
91
+ # Prompt user for confirmation
92
+ if not upgrade_service.prompt_for_upgrade(update_info):
93
+ print("\n⏸️ Upgrade cancelled by user")
94
+ return CommandResult.success_result("Upgrade cancelled by user")
95
+
96
+ # Perform upgrade
97
+ success, message = upgrade_service.perform_upgrade(update_info)
98
+ print(f"\n{message}")
99
+
100
+ if success:
101
+ # Restart after successful upgrade
102
+ upgrade_service.restart_after_upgrade()
103
+ # Note: This line won't be reached as restart replaces process
104
+ return CommandResult.success_result(f"Upgraded to v{latest}")
105
+ return CommandResult.error_result("Upgrade failed")
106
+
107
+ except Exception as e:
108
+ self.logger.error(f"Error during upgrade: {e}", exc_info=True)
109
+ return CommandResult.error_result(f"Error during upgrade: {e}")
110
+
111
+
112
+ def add_upgrade_parser(subparsers):
113
+ """
114
+ Add upgrade command parser.
115
+
116
+ WHY: This command helps users check for and install the latest version of
117
+ claude-mpm without waiting for the automatic startup check.
118
+
119
+ Args:
120
+ subparsers: The subparser action object to add the upgrade command to
121
+ """
122
+ parser = subparsers.add_parser(
123
+ "upgrade",
124
+ help="Check for and install latest claude-mpm version",
125
+ description="Check for updates and upgrade claude-mpm to the latest version from PyPI/npm",
126
+ )
127
+
128
+ parser.add_argument(
129
+ "-y",
130
+ "--yes",
131
+ action="store_true",
132
+ help="Skip confirmation prompt and upgrade immediately if available",
133
+ )
134
+
135
+ parser.add_argument(
136
+ "--force",
137
+ action="store_true",
138
+ help="Force upgrade even if already on latest version (alias for --yes)",
139
+ )
140
+
141
+ return parser
142
+
143
+
144
+ def upgrade(args):
145
+ """
146
+ Main entry point for upgrade command.
147
+
148
+ This function maintains backward compatibility while using the new BaseCommand pattern.
149
+ """
150
+ command = UpgradeCommand()
151
+ result = command.execute(args)
152
+ return result.exit_code
@@ -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