claude-mpm 4.13.2__py3-none-any.whl → 4.18.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (250) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_ENGINEER.md +286 -0
  3. claude_mpm/agents/BASE_PM.md +48 -17
  4. claude_mpm/agents/OUTPUT_STYLE.md +329 -11
  5. claude_mpm/agents/PM_INSTRUCTIONS.md +227 -8
  6. claude_mpm/agents/agent_loader.py +17 -5
  7. claude_mpm/agents/frontmatter_validator.py +284 -253
  8. claude_mpm/agents/templates/agentic-coder-optimizer.json +9 -2
  9. claude_mpm/agents/templates/api_qa.json +7 -1
  10. claude_mpm/agents/templates/clerk-ops.json +8 -1
  11. claude_mpm/agents/templates/code_analyzer.json +4 -1
  12. claude_mpm/agents/templates/dart_engineer.json +11 -1
  13. claude_mpm/agents/templates/data_engineer.json +11 -1
  14. claude_mpm/agents/templates/documentation.json +6 -1
  15. claude_mpm/agents/templates/engineer.json +18 -1
  16. claude_mpm/agents/templates/gcp_ops_agent.json +8 -1
  17. claude_mpm/agents/templates/golang_engineer.json +11 -1
  18. claude_mpm/agents/templates/java_engineer.json +12 -2
  19. claude_mpm/agents/templates/local_ops_agent.json +1217 -6
  20. claude_mpm/agents/templates/nextjs_engineer.json +11 -1
  21. claude_mpm/agents/templates/ops.json +8 -1
  22. claude_mpm/agents/templates/php-engineer.json +11 -1
  23. claude_mpm/agents/templates/project_organizer.json +10 -3
  24. claude_mpm/agents/templates/prompt-engineer.json +5 -1
  25. claude_mpm/agents/templates/python_engineer.json +11 -1
  26. claude_mpm/agents/templates/qa.json +7 -1
  27. claude_mpm/agents/templates/react_engineer.json +11 -1
  28. claude_mpm/agents/templates/refactoring_engineer.json +8 -1
  29. claude_mpm/agents/templates/research.json +4 -1
  30. claude_mpm/agents/templates/ruby-engineer.json +11 -1
  31. claude_mpm/agents/templates/rust_engineer.json +11 -1
  32. claude_mpm/agents/templates/security.json +6 -1
  33. claude_mpm/agents/templates/svelte-engineer.json +225 -0
  34. claude_mpm/agents/templates/ticketing.json +6 -1
  35. claude_mpm/agents/templates/typescript_engineer.json +11 -1
  36. claude_mpm/agents/templates/vercel_ops_agent.json +8 -1
  37. claude_mpm/agents/templates/version_control.json +8 -1
  38. claude_mpm/agents/templates/web_qa.json +7 -1
  39. claude_mpm/agents/templates/web_ui.json +11 -1
  40. claude_mpm/cli/__init__.py +34 -706
  41. claude_mpm/cli/commands/agent_manager.py +25 -12
  42. claude_mpm/cli/commands/agent_state_manager.py +186 -0
  43. claude_mpm/cli/commands/agents.py +204 -148
  44. claude_mpm/cli/commands/aggregate.py +7 -3
  45. claude_mpm/cli/commands/analyze.py +9 -4
  46. claude_mpm/cli/commands/analyze_code.py +7 -2
  47. claude_mpm/cli/commands/auto_configure.py +7 -9
  48. claude_mpm/cli/commands/config.py +47 -13
  49. claude_mpm/cli/commands/configure.py +294 -1788
  50. claude_mpm/cli/commands/configure_agent_display.py +261 -0
  51. claude_mpm/cli/commands/configure_behavior_manager.py +204 -0
  52. claude_mpm/cli/commands/configure_hook_manager.py +225 -0
  53. claude_mpm/cli/commands/configure_models.py +18 -0
  54. claude_mpm/cli/commands/configure_navigation.py +167 -0
  55. claude_mpm/cli/commands/configure_paths.py +104 -0
  56. claude_mpm/cli/commands/configure_persistence.py +254 -0
  57. claude_mpm/cli/commands/configure_startup_manager.py +646 -0
  58. claude_mpm/cli/commands/configure_template_editor.py +497 -0
  59. claude_mpm/cli/commands/configure_validators.py +73 -0
  60. claude_mpm/cli/commands/local_deploy.py +537 -0
  61. claude_mpm/cli/commands/memory.py +54 -20
  62. claude_mpm/cli/commands/mpm_init.py +39 -25
  63. claude_mpm/cli/commands/mpm_init_handler.py +8 -3
  64. claude_mpm/cli/executor.py +202 -0
  65. claude_mpm/cli/helpers.py +105 -0
  66. claude_mpm/cli/interactive/__init__.py +3 -0
  67. claude_mpm/cli/interactive/skills_wizard.py +491 -0
  68. claude_mpm/cli/parsers/__init__.py +7 -1
  69. claude_mpm/cli/parsers/base_parser.py +98 -3
  70. claude_mpm/cli/parsers/local_deploy_parser.py +227 -0
  71. claude_mpm/cli/shared/output_formatters.py +28 -19
  72. claude_mpm/cli/startup.py +481 -0
  73. claude_mpm/cli/utils.py +52 -1
  74. claude_mpm/commands/mpm-help.md +3 -0
  75. claude_mpm/commands/mpm-version.md +113 -0
  76. claude_mpm/commands/mpm.md +1 -0
  77. claude_mpm/config/agent_config.py +2 -2
  78. claude_mpm/config/model_config.py +428 -0
  79. claude_mpm/core/base_service.py +13 -12
  80. claude_mpm/core/enums.py +452 -0
  81. claude_mpm/core/factories.py +1 -1
  82. claude_mpm/core/instruction_reinforcement_hook.py +2 -1
  83. claude_mpm/core/interactive_session.py +9 -3
  84. claude_mpm/core/logging_config.py +6 -2
  85. claude_mpm/core/oneshot_session.py +8 -4
  86. claude_mpm/core/optimized_agent_loader.py +3 -3
  87. claude_mpm/core/output_style_manager.py +12 -192
  88. claude_mpm/core/service_registry.py +5 -1
  89. claude_mpm/core/types.py +2 -9
  90. claude_mpm/core/typing_utils.py +7 -6
  91. claude_mpm/dashboard/static/js/dashboard.js +0 -14
  92. claude_mpm/dashboard/templates/index.html +3 -41
  93. claude_mpm/hooks/claude_hooks/response_tracking.py +35 -1
  94. claude_mpm/hooks/instruction_reinforcement.py +7 -2
  95. claude_mpm/models/resume_log.py +340 -0
  96. claude_mpm/services/agents/auto_config_manager.py +10 -11
  97. claude_mpm/services/agents/deployment/agent_configuration_manager.py +1 -1
  98. claude_mpm/services/agents/deployment/agent_record_service.py +1 -1
  99. claude_mpm/services/agents/deployment/agent_validator.py +17 -1
  100. claude_mpm/services/agents/deployment/async_agent_deployment.py +1 -1
  101. claude_mpm/services/agents/deployment/interface_adapter.py +3 -2
  102. claude_mpm/services/agents/deployment/local_template_deployment.py +1 -1
  103. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +7 -6
  104. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +7 -16
  105. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +4 -3
  106. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +5 -3
  107. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +6 -5
  108. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +9 -6
  109. claude_mpm/services/agents/deployment/validation/__init__.py +3 -1
  110. claude_mpm/services/agents/deployment/validation/validation_result.py +1 -9
  111. claude_mpm/services/agents/local_template_manager.py +1 -1
  112. claude_mpm/services/agents/memory/agent_memory_manager.py +5 -2
  113. claude_mpm/services/agents/registry/modification_tracker.py +5 -2
  114. claude_mpm/services/command_handler_service.py +11 -5
  115. claude_mpm/services/core/interfaces/__init__.py +74 -2
  116. claude_mpm/services/core/interfaces/health.py +172 -0
  117. claude_mpm/services/core/interfaces/model.py +281 -0
  118. claude_mpm/services/core/interfaces/process.py +372 -0
  119. claude_mpm/services/core/interfaces/restart.py +307 -0
  120. claude_mpm/services/core/interfaces/stability.py +260 -0
  121. claude_mpm/services/core/models/__init__.py +33 -0
  122. claude_mpm/services/core/models/agent_config.py +12 -28
  123. claude_mpm/services/core/models/health.py +162 -0
  124. claude_mpm/services/core/models/process.py +235 -0
  125. claude_mpm/services/core/models/restart.py +302 -0
  126. claude_mpm/services/core/models/stability.py +264 -0
  127. claude_mpm/services/core/path_resolver.py +23 -7
  128. claude_mpm/services/diagnostics/__init__.py +2 -2
  129. claude_mpm/services/diagnostics/checks/agent_check.py +25 -24
  130. claude_mpm/services/diagnostics/checks/claude_code_check.py +24 -23
  131. claude_mpm/services/diagnostics/checks/common_issues_check.py +25 -24
  132. claude_mpm/services/diagnostics/checks/configuration_check.py +24 -23
  133. claude_mpm/services/diagnostics/checks/filesystem_check.py +18 -17
  134. claude_mpm/services/diagnostics/checks/installation_check.py +30 -29
  135. claude_mpm/services/diagnostics/checks/instructions_check.py +20 -19
  136. claude_mpm/services/diagnostics/checks/mcp_check.py +50 -36
  137. claude_mpm/services/diagnostics/checks/mcp_services_check.py +36 -31
  138. claude_mpm/services/diagnostics/checks/monitor_check.py +23 -22
  139. claude_mpm/services/diagnostics/checks/startup_log_check.py +9 -8
  140. claude_mpm/services/diagnostics/diagnostic_runner.py +6 -5
  141. claude_mpm/services/diagnostics/doctor_reporter.py +28 -25
  142. claude_mpm/services/diagnostics/models.py +19 -24
  143. claude_mpm/services/infrastructure/monitoring/__init__.py +1 -1
  144. claude_mpm/services/infrastructure/monitoring/aggregator.py +12 -12
  145. claude_mpm/services/infrastructure/monitoring/base.py +5 -13
  146. claude_mpm/services/infrastructure/monitoring/network.py +7 -6
  147. claude_mpm/services/infrastructure/monitoring/process.py +13 -12
  148. claude_mpm/services/infrastructure/monitoring/resources.py +7 -6
  149. claude_mpm/services/infrastructure/monitoring/service.py +16 -15
  150. claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
  151. claude_mpm/services/local_ops/__init__.py +163 -0
  152. claude_mpm/services/local_ops/crash_detector.py +257 -0
  153. claude_mpm/services/local_ops/health_checks/__init__.py +28 -0
  154. claude_mpm/services/local_ops/health_checks/http_check.py +224 -0
  155. claude_mpm/services/local_ops/health_checks/process_check.py +236 -0
  156. claude_mpm/services/local_ops/health_checks/resource_check.py +255 -0
  157. claude_mpm/services/local_ops/health_manager.py +430 -0
  158. claude_mpm/services/local_ops/log_monitor.py +396 -0
  159. claude_mpm/services/local_ops/memory_leak_detector.py +294 -0
  160. claude_mpm/services/local_ops/process_manager.py +595 -0
  161. claude_mpm/services/local_ops/resource_monitor.py +331 -0
  162. claude_mpm/services/local_ops/restart_manager.py +401 -0
  163. claude_mpm/services/local_ops/restart_policy.py +387 -0
  164. claude_mpm/services/local_ops/state_manager.py +372 -0
  165. claude_mpm/services/local_ops/unified_manager.py +600 -0
  166. claude_mpm/services/mcp_config_manager.py +9 -4
  167. claude_mpm/services/mcp_gateway/core/__init__.py +1 -2
  168. claude_mpm/services/mcp_gateway/core/base.py +18 -31
  169. claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +71 -24
  170. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +30 -28
  171. claude_mpm/services/memory_hook_service.py +4 -1
  172. claude_mpm/services/model/__init__.py +147 -0
  173. claude_mpm/services/model/base_provider.py +365 -0
  174. claude_mpm/services/model/claude_provider.py +412 -0
  175. claude_mpm/services/model/model_router.py +453 -0
  176. claude_mpm/services/model/ollama_provider.py +415 -0
  177. claude_mpm/services/monitor/daemon_manager.py +3 -2
  178. claude_mpm/services/monitor/handlers/dashboard.py +2 -1
  179. claude_mpm/services/monitor/handlers/hooks.py +2 -1
  180. claude_mpm/services/monitor/management/lifecycle.py +3 -2
  181. claude_mpm/services/monitor/server.py +2 -1
  182. claude_mpm/services/session_management_service.py +3 -2
  183. claude_mpm/services/session_manager.py +205 -1
  184. claude_mpm/services/shared/async_service_base.py +16 -27
  185. claude_mpm/services/shared/lifecycle_service_base.py +1 -14
  186. claude_mpm/services/socketio/handlers/__init__.py +5 -2
  187. claude_mpm/services/socketio/handlers/hook.py +13 -2
  188. claude_mpm/services/socketio/handlers/registry.py +4 -2
  189. claude_mpm/services/socketio/server/main.py +10 -8
  190. claude_mpm/services/subprocess_launcher_service.py +14 -5
  191. claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +8 -7
  192. claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +6 -5
  193. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +8 -7
  194. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +7 -6
  195. claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +5 -4
  196. claude_mpm/services/unified/config_strategies/validation_strategy.py +13 -9
  197. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +10 -3
  198. claude_mpm/services/unified/deployment_strategies/local.py +6 -5
  199. claude_mpm/services/unified/deployment_strategies/utils.py +6 -5
  200. claude_mpm/services/unified/deployment_strategies/vercel.py +7 -6
  201. claude_mpm/services/unified/interfaces.py +3 -1
  202. claude_mpm/services/unified/unified_analyzer.py +14 -10
  203. claude_mpm/services/unified/unified_config.py +2 -1
  204. claude_mpm/services/unified/unified_deployment.py +9 -4
  205. claude_mpm/services/version_service.py +104 -1
  206. claude_mpm/skills/__init__.py +21 -0
  207. claude_mpm/skills/bundled/__init__.py +6 -0
  208. claude_mpm/skills/bundled/api-documentation.md +393 -0
  209. claude_mpm/skills/bundled/async-testing.md +571 -0
  210. claude_mpm/skills/bundled/code-review.md +143 -0
  211. claude_mpm/skills/bundled/database-migration.md +199 -0
  212. claude_mpm/skills/bundled/docker-containerization.md +194 -0
  213. claude_mpm/skills/bundled/express-local-dev.md +1429 -0
  214. claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
  215. claude_mpm/skills/bundled/git-workflow.md +414 -0
  216. claude_mpm/skills/bundled/imagemagick.md +204 -0
  217. claude_mpm/skills/bundled/json-data-handling.md +223 -0
  218. claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
  219. claude_mpm/skills/bundled/pdf.md +141 -0
  220. claude_mpm/skills/bundled/performance-profiling.md +567 -0
  221. claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
  222. claude_mpm/skills/bundled/security-scanning.md +327 -0
  223. claude_mpm/skills/bundled/systematic-debugging.md +473 -0
  224. claude_mpm/skills/bundled/test-driven-development.md +378 -0
  225. claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
  226. claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
  227. claude_mpm/skills/bundled/xlsx.md +157 -0
  228. claude_mpm/skills/registry.py +286 -0
  229. claude_mpm/skills/skill_manager.py +310 -0
  230. claude_mpm/tools/code_tree_analyzer.py +177 -141
  231. claude_mpm/tools/code_tree_events.py +4 -2
  232. claude_mpm/utils/agent_dependency_loader.py +2 -2
  233. {claude_mpm-4.13.2.dist-info → claude_mpm-4.18.2.dist-info}/METADATA +117 -8
  234. {claude_mpm-4.13.2.dist-info → claude_mpm-4.18.2.dist-info}/RECORD +238 -174
  235. claude_mpm/dashboard/static/css/code-tree.css +0 -1639
  236. claude_mpm/dashboard/static/js/components/code-tree/tree-breadcrumb.js +0 -353
  237. claude_mpm/dashboard/static/js/components/code-tree/tree-constants.js +0 -235
  238. claude_mpm/dashboard/static/js/components/code-tree/tree-search.js +0 -409
  239. claude_mpm/dashboard/static/js/components/code-tree/tree-utils.js +0 -435
  240. claude_mpm/dashboard/static/js/components/code-tree.js +0 -5869
  241. claude_mpm/dashboard/static/js/components/code-viewer.js +0 -1386
  242. claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +0 -425
  243. claude_mpm/hooks/claude_hooks/hook_handler_original.py +0 -1041
  244. claude_mpm/hooks/claude_hooks/hook_handler_refactored.py +0 -347
  245. claude_mpm/services/agents/deployment/agent_lifecycle_manager_refactored.py +0 -575
  246. claude_mpm/services/project/analyzer_refactored.py +0 -450
  247. {claude_mpm-4.13.2.dist-info → claude_mpm-4.18.2.dist-info}/WHEEL +0 -0
  248. {claude_mpm-4.13.2.dist-info → claude_mpm-4.18.2.dist-info}/entry_points.txt +0 -0
  249. {claude_mpm-4.13.2.dist-info → claude_mpm-4.18.2.dist-info}/licenses/LICENSE +0 -0
  250. {claude_mpm-4.13.2.dist-info → claude_mpm-4.18.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,481 @@
1
+ """
2
+ CLI Startup Functions
3
+ =====================
4
+
5
+ This module contains initialization functions that run on CLI startup,
6
+ including project registry, MCP configuration, and update checks.
7
+
8
+ Part of cli/__init__.py refactoring to reduce file size and improve modularity.
9
+ """
10
+
11
+ import os
12
+ import sys
13
+
14
+
15
+ def setup_early_environment(argv):
16
+ """
17
+ Set up early environment variables and logging suppression.
18
+
19
+ WHY: Some commands need special environment handling before any logging
20
+ or service initialization occurs.
21
+
22
+ Args:
23
+ argv: Command line arguments
24
+
25
+ Returns:
26
+ Processed argv list
27
+ """
28
+ # Disable telemetry and set cleanup flags early
29
+ os.environ.setdefault("DISABLE_TELEMETRY", "1")
30
+ os.environ.setdefault("CLAUDE_MPM_SKIP_CLEANUP", "0")
31
+
32
+ # EARLY CHECK: Suppress logging for configure command
33
+ if argv is None:
34
+ argv = sys.argv[1:]
35
+ if "configure" in argv or (len(argv) > 0 and argv[0] == "configure"):
36
+ import logging
37
+
38
+ logging.getLogger("claude_mpm").setLevel(logging.WARNING)
39
+ os.environ["CLAUDE_MPM_SKIP_CLEANUP"] = "1"
40
+
41
+ return argv
42
+
43
+
44
+ def should_skip_background_services(args, processed_argv):
45
+ """
46
+ Determine if background services should be skipped for this command.
47
+
48
+ WHY: Some commands (help, version, configure, doctor) don't need
49
+ background services and should start faster.
50
+
51
+ Args:
52
+ args: Parsed arguments
53
+ processed_argv: Processed command line arguments
54
+
55
+ Returns:
56
+ bool: True if background services should be skipped
57
+ """
58
+ skip_commands = ["--version", "-v", "--help", "-h"]
59
+ return any(cmd in (processed_argv or sys.argv[1:]) for cmd in skip_commands) or (
60
+ hasattr(args, "command")
61
+ and args.command in ["info", "doctor", "config", "mcp", "configure"]
62
+ )
63
+
64
+
65
+ def setup_configure_command_environment(args):
66
+ """
67
+ Set up special environment for configure command.
68
+
69
+ WHY: Configure command needs clean state without background services
70
+ and with suppressed logging.
71
+
72
+ Args:
73
+ args: Parsed arguments
74
+ """
75
+ if hasattr(args, "command") and args.command == "configure":
76
+ os.environ["CLAUDE_MPM_SKIP_CLEANUP"] = "1"
77
+ import logging
78
+
79
+ logging.getLogger("claude_mpm").setLevel(logging.WARNING)
80
+
81
+
82
+ def discover_and_link_runtime_skills():
83
+ """
84
+ Discover and link runtime skills from user/project directories.
85
+
86
+ WHY: Automatically discover and link skills added to .claude/skills/
87
+ without requiring manual configuration.
88
+
89
+ DESIGN DECISION: Failures are logged but don't block startup to ensure
90
+ claude-mpm remains functional even if skills discovery fails.
91
+ """
92
+ try:
93
+ from ..cli.interactive.skills_wizard import (
94
+ discover_and_link_runtime_skills as discover_skills,
95
+ )
96
+
97
+ discover_skills()
98
+ except Exception as e:
99
+ # Import logger here to avoid circular imports
100
+ from ..core.logger import get_logger
101
+
102
+ logger = get_logger("cli")
103
+ logger.debug(f"Failed to discover runtime skills: {e}")
104
+ # Continue execution - skills discovery failure shouldn't block startup
105
+
106
+
107
+ def run_background_services():
108
+ """
109
+ Initialize all background services on startup.
110
+
111
+ WHY: Centralizes all startup service initialization for cleaner main().
112
+ """
113
+ initialize_project_registry()
114
+ check_mcp_auto_configuration()
115
+ verify_mcp_gateway_startup()
116
+ check_for_updates_async()
117
+ discover_and_link_runtime_skills()
118
+
119
+
120
+ def setup_mcp_server_logging(args):
121
+ """
122
+ Configure minimal logging for MCP server mode.
123
+
124
+ WHY: MCP server needs minimal stderr-only logging to avoid interfering
125
+ with stdout protocol communication.
126
+
127
+ Args:
128
+ args: Parsed arguments
129
+
130
+ Returns:
131
+ Configured logger
132
+ """
133
+ import logging
134
+
135
+ from ..cli.utils import setup_logging
136
+ from ..constants import CLICommands
137
+
138
+ if (
139
+ args.command == CLICommands.MCP.value
140
+ and getattr(args, "mcp_command", None) == "start"
141
+ ):
142
+ if not getattr(args, "test", False) and not getattr(
143
+ args, "instructions", False
144
+ ):
145
+ # Production MCP mode - minimal logging
146
+ logging.basicConfig(
147
+ level=logging.ERROR,
148
+ format="%(message)s",
149
+ stream=sys.stderr,
150
+ force=True,
151
+ )
152
+ return logging.getLogger("claude_mpm")
153
+ # Test or instructions mode - normal logging
154
+ return setup_logging(args)
155
+ # Normal logging for all other commands
156
+ return setup_logging(args)
157
+
158
+
159
+ def initialize_project_registry():
160
+ """
161
+ Initialize or update the project registry for the current session.
162
+
163
+ WHY: The project registry tracks all claude-mpm projects and their metadata
164
+ across sessions. This function ensures the current project is properly
165
+ registered and updates session information.
166
+
167
+ DESIGN DECISION: Registry failures are logged but don't prevent startup
168
+ to ensure claude-mpm remains functional even if registry operations fail.
169
+ """
170
+ try:
171
+ from ..services.project.registry import ProjectRegistry
172
+
173
+ registry = ProjectRegistry()
174
+ registry.get_or_create_project_entry()
175
+ except Exception as e:
176
+ # Import logger here to avoid circular imports
177
+ from ..core.logger import get_logger
178
+
179
+ logger = get_logger("cli")
180
+ logger.debug(f"Failed to initialize project registry: {e}")
181
+ # Continue execution - registry failure shouldn't block startup
182
+
183
+
184
+ def check_mcp_auto_configuration():
185
+ """
186
+ Check and potentially auto-configure MCP for pipx installations.
187
+
188
+ WHY: Users installing via pipx should have MCP work out-of-the-box with
189
+ minimal friction. This function offers one-time auto-configuration with
190
+ user consent.
191
+
192
+ DESIGN DECISION: This is blocking but quick - it only runs once and has
193
+ a 10-second timeout. We want to catch users on first run for the best
194
+ experience.
195
+ """
196
+ try:
197
+ from ..services.mcp_gateway.auto_configure import check_and_configure_mcp
198
+
199
+ # This function handles all the logic:
200
+ # - Checks if already configured
201
+ # - Checks if pipx installation
202
+ # - Checks if already asked before
203
+ # - Prompts user if needed
204
+ # - Configures if user agrees
205
+ check_and_configure_mcp()
206
+
207
+ except Exception as e:
208
+ # Non-critical - log but don't fail
209
+ from ..core.logger import get_logger
210
+
211
+ logger = get_logger("cli")
212
+ logger.debug(f"MCP auto-configuration check failed: {e}")
213
+
214
+ # Skip MCP service fixes for the doctor and configure commands
215
+ # The doctor command performs its own comprehensive MCP service check
216
+ # The configure command allows users to configure which services to enable
217
+ # Running both would cause duplicate checks and log messages (9 seconds apart)
218
+ if len(sys.argv) > 1 and sys.argv[1] in ("doctor", "configure"):
219
+ return
220
+
221
+ # Also ensure MCP services are properly configured in ~/.claude.json
222
+ # This fixes incorrect paths and adds missing services
223
+ try:
224
+ from ..core.logger import get_logger
225
+ from ..services.mcp_config_manager import MCPConfigManager
226
+
227
+ logger = get_logger("cli")
228
+ mcp_manager = MCPConfigManager()
229
+
230
+ # Fix any corrupted installations first
231
+ fix_success, fix_message = mcp_manager.fix_mcp_service_issues()
232
+ if fix_message and "Fixed:" in fix_message:
233
+ logger.info(f"MCP service fixes applied: {fix_message}")
234
+
235
+ # Ensure all services are configured correctly
236
+ config_success, config_message = mcp_manager.ensure_mcp_services_configured()
237
+ if config_message and "Added MCP services" in config_message:
238
+ logger.info(f"MCP services configured: {config_message}")
239
+
240
+ except Exception as e:
241
+ # Non-critical - log but don't fail
242
+ from ..core.logger import get_logger
243
+
244
+ logger = get_logger("cli")
245
+ logger.debug(f"MCP services configuration update failed: {e}")
246
+
247
+
248
+ def verify_mcp_gateway_startup():
249
+ """
250
+ Verify MCP Gateway configuration on startup and pre-warm MCP services.
251
+
252
+ WHY: The MCP gateway should be automatically configured and verified on startup
253
+ to provide a seamless experience with diagnostic tools, file summarizer, and
254
+ ticket service. Pre-warming MCP services eliminates the 11.9s delay on first use.
255
+
256
+ DESIGN DECISION: This is non-blocking - failures are logged but don't prevent
257
+ startup to ensure claude-mpm remains functional even if MCP gateway has issues.
258
+ """
259
+ # Quick verification of MCP services installation
260
+ try:
261
+ from ..core.logger import get_logger
262
+ from ..services.mcp_service_verifier import verify_mcp_services_on_startup
263
+
264
+ logger = get_logger("mcp_verify")
265
+ all_ok, message = verify_mcp_services_on_startup()
266
+ if not all_ok:
267
+ logger.warning(message)
268
+ except Exception:
269
+ # Non-critical - continue with startup
270
+ pass
271
+
272
+ try:
273
+ import asyncio
274
+ import time
275
+
276
+ from ..core.logger import get_logger
277
+ from ..services.mcp_gateway.core.startup_verification import (
278
+ is_mcp_gateway_configured,
279
+ verify_mcp_gateway_on_startup,
280
+ )
281
+
282
+ logger = get_logger("mcp_prewarm")
283
+
284
+ # Quick check first - if already configured, skip detailed verification
285
+ gateway_configured = is_mcp_gateway_configured()
286
+
287
+ # DISABLED: Pre-warming MCP servers can interfere with Claude Code's MCP management
288
+ # This was causing issues with MCP server initialization and stderr handling
289
+ # def run_pre_warming():
290
+ # loop = None
291
+ # try:
292
+ # start_time = time.time()
293
+ # loop = asyncio.new_event_loop()
294
+ # asyncio.set_event_loop(loop)
295
+ #
296
+ # # Pre-warm MCP servers (especially vector search)
297
+ # logger.info("Pre-warming MCP servers to eliminate startup delay...")
298
+ # loop.run_until_complete(pre_warm_mcp_servers())
299
+ #
300
+ # pre_warm_time = time.time() - start_time
301
+ # if pre_warm_time > 1.0:
302
+ # logger.info(f"MCP servers pre-warmed in {pre_warm_time:.2f}s")
303
+
304
+ # Dummy function to maintain structure
305
+ def run_pre_warming():
306
+ loop = None
307
+ try:
308
+ time.time()
309
+ loop = asyncio.new_event_loop()
310
+ asyncio.set_event_loop(loop)
311
+
312
+ # Also run gateway verification if needed
313
+ if not gateway_configured:
314
+ loop.run_until_complete(verify_mcp_gateway_on_startup())
315
+
316
+ except Exception as e:
317
+ # Non-blocking - log but don't fail
318
+ logger.debug(f"MCP pre-warming error (non-critical): {e}")
319
+ finally:
320
+ # Properly clean up event loop to prevent kqueue warnings
321
+ if loop is not None:
322
+ try:
323
+ # Cancel all running tasks
324
+ pending = asyncio.all_tasks(loop)
325
+ for task in pending:
326
+ task.cancel()
327
+ # Wait for tasks to complete cancellation
328
+ if pending:
329
+ loop.run_until_complete(
330
+ asyncio.gather(*pending, return_exceptions=True)
331
+ )
332
+ except Exception:
333
+ pass # Ignore cleanup errors
334
+ finally:
335
+ loop.close()
336
+ # Clear the event loop reference to help with cleanup
337
+ asyncio.set_event_loop(None)
338
+
339
+ # Run pre-warming in background thread
340
+ import threading
341
+
342
+ pre_warm_thread = threading.Thread(target=run_pre_warming, daemon=True)
343
+ pre_warm_thread.start()
344
+
345
+ return
346
+
347
+ # Run detailed verification in background if not configured
348
+ if not gateway_configured:
349
+ # Note: We don't await this to avoid blocking startup
350
+ def run_verification():
351
+ loop = None
352
+ try:
353
+ loop = asyncio.new_event_loop()
354
+ asyncio.set_event_loop(loop)
355
+ results = loop.run_until_complete(verify_mcp_gateway_on_startup())
356
+
357
+ # Log results but don't block
358
+ from ..core.logger import get_logger
359
+
360
+ logger = get_logger("cli")
361
+
362
+ if results.get("gateway_configured"):
363
+ logger.debug("MCP Gateway verification completed successfully")
364
+ else:
365
+ logger.debug("MCP Gateway verification completed with warnings")
366
+
367
+ except Exception as e:
368
+ from ..core.logger import get_logger
369
+
370
+ logger = get_logger("cli")
371
+ logger.debug(f"MCP Gateway verification failed: {e}")
372
+ finally:
373
+ # Properly clean up event loop to prevent kqueue warnings
374
+ if loop is not None:
375
+ try:
376
+ # Cancel all running tasks
377
+ pending = asyncio.all_tasks(loop)
378
+ for task in pending:
379
+ task.cancel()
380
+ # Wait for tasks to complete cancellation
381
+ if pending:
382
+ loop.run_until_complete(
383
+ asyncio.gather(*pending, return_exceptions=True)
384
+ )
385
+ except Exception:
386
+ pass # Ignore cleanup errors
387
+ finally:
388
+ loop.close()
389
+ # Clear the event loop reference to help with cleanup
390
+ asyncio.set_event_loop(None)
391
+
392
+ # Run in background thread to avoid blocking startup
393
+ import threading
394
+
395
+ verification_thread = threading.Thread(target=run_verification, daemon=True)
396
+ verification_thread.start()
397
+
398
+ except Exception as e:
399
+ # Import logger here to avoid circular imports
400
+ from ..core.logger import get_logger
401
+
402
+ logger = get_logger("cli")
403
+ logger.debug(f"Failed to start MCP Gateway verification: {e}")
404
+ # Continue execution - MCP gateway issues shouldn't block startup
405
+
406
+
407
+ def check_for_updates_async():
408
+ """
409
+ Check for updates in background thread (non-blocking).
410
+
411
+ WHY: Users should be notified of new versions and have an easy way to upgrade
412
+ without manually checking PyPI/npm. This runs asynchronously on startup to avoid
413
+ blocking the CLI.
414
+
415
+ DESIGN DECISION: This is non-blocking and non-critical - failures are logged
416
+ but don't prevent startup. Only runs for pip/pipx/npm installations, skips
417
+ editable/development installations.
418
+ """
419
+
420
+ def run_update_check():
421
+ """Inner function to run in background thread."""
422
+ loop = None
423
+ try:
424
+ import asyncio
425
+
426
+ from ..core.logger import get_logger
427
+ from ..services.self_upgrade_service import SelfUpgradeService
428
+
429
+ logger = get_logger("upgrade_check")
430
+
431
+ # Create new event loop for this thread
432
+ loop = asyncio.new_event_loop()
433
+ asyncio.set_event_loop(loop)
434
+
435
+ # Create upgrade service and check for updates
436
+ upgrade_service = SelfUpgradeService()
437
+
438
+ # Skip for editable installs (development mode)
439
+ from ..services.self_upgrade_service import InstallationMethod
440
+
441
+ if upgrade_service.installation_method == InstallationMethod.EDITABLE:
442
+ logger.debug("Skipping version check for editable installation")
443
+ return
444
+
445
+ # Check and prompt for upgrade if available (non-blocking)
446
+ loop.run_until_complete(upgrade_service.check_and_prompt_on_startup())
447
+
448
+ except Exception as e:
449
+ # Non-critical - log but don't fail startup
450
+ try:
451
+ from ..core.logger import get_logger
452
+
453
+ logger = get_logger("upgrade_check")
454
+ logger.debug(f"Update check failed (non-critical): {e}")
455
+ except Exception:
456
+ pass # Avoid any errors in error handling
457
+ finally:
458
+ # Properly clean up event loop
459
+ if loop is not None:
460
+ try:
461
+ # Cancel all running tasks
462
+ pending = asyncio.all_tasks(loop)
463
+ for task in pending:
464
+ task.cancel()
465
+ # Wait for tasks to complete cancellation
466
+ if pending:
467
+ loop.run_until_complete(
468
+ asyncio.gather(*pending, return_exceptions=True)
469
+ )
470
+ except Exception:
471
+ pass # Ignore cleanup errors
472
+ finally:
473
+ loop.close()
474
+ # Clear the event loop reference to help with cleanup
475
+ asyncio.set_event_loop(None)
476
+
477
+ # Run update check in background thread to avoid blocking startup
478
+ import threading
479
+
480
+ update_check_thread = threading.Thread(target=run_update_check, daemon=True)
481
+ update_check_thread.start()
claude_mpm/cli/utils.py CHANGED
@@ -6,9 +6,10 @@ Centralizing these functions reduces code duplication and provides a single plac
6
6
  for common CLI operations.
7
7
  """
8
8
 
9
+ import difflib
9
10
  import sys
10
11
  from pathlib import Path
11
- from typing import Optional
12
+ from typing import List, Optional
12
13
 
13
14
  from ..core.logger import get_logger
14
15
 
@@ -207,3 +208,53 @@ def ensure_directories() -> None:
207
208
  # Continue even if initialization fails
208
209
  # The individual commands will handle missing directories as needed
209
210
  pass
211
+
212
+
213
+ def suggest_similar_commands(
214
+ invalid_command: str,
215
+ valid_commands: List[str],
216
+ cutoff: float = 0.6,
217
+ max_suggestions: int = 3,
218
+ ) -> Optional[str]:
219
+ """
220
+ Suggest similar commands for an invalid command using fuzzy matching.
221
+
222
+ WHY: Helps users quickly identify typos and discover correct command names
223
+ by suggesting the most similar valid commands. Uses stdlib difflib for
224
+ zero-dependency fuzzy matching.
225
+
226
+ DESIGN DECISION: Using difflib.get_close_matches provides good results for
227
+ typos and partial matches while being simple and lightweight (no external deps).
228
+
229
+ Args:
230
+ invalid_command: The invalid command the user typed
231
+ valid_commands: List of valid commands to match against
232
+ cutoff: Similarity threshold (0.0-1.0), default 0.6
233
+ max_suggestions: Maximum number of suggestions to return, default 3
234
+
235
+ Returns:
236
+ Formatted suggestion string or None if no good matches found
237
+
238
+ Examples:
239
+ >>> suggest_similar_commands("tickts", ["tickets", "run", "agents"])
240
+ "Did you mean 'tickets'?"
241
+
242
+ >>> suggest_similar_commands("mem", ["memory", "monitor", "mcp"])
243
+ "Did you mean one of these?\n memory\n monitor\n mcp"
244
+
245
+ >>> suggest_similar_commands("xyz", ["tickets", "run"])
246
+ None # No good matches
247
+ """
248
+ # Use difflib to find close matches
249
+ matches = difflib.get_close_matches(
250
+ invalid_command, valid_commands, n=max_suggestions, cutoff=cutoff
251
+ )
252
+
253
+ if not matches:
254
+ return None
255
+
256
+ # Format suggestion message
257
+ if len(matches) == 1:
258
+ return f"Did you mean '{matches[0]}'?"
259
+ suggestions = "\n ".join(matches)
260
+ return f"Did you mean one of these?\n {suggestions}"
@@ -90,6 +90,9 @@ Available Commands:
90
90
  /mpm-monitor [start|stop|restart|status|port]
91
91
  Manage Socket.IO monitoring server and dashboard
92
92
 
93
+ /mpm-version
94
+ Display comprehensive version information including project version, all agents with versions, and all skills with versions
95
+
93
96
  Use '/mpm-help <command>' for detailed help on a specific command.
94
97
  ```
95
98
 
@@ -0,0 +1,113 @@
1
+ # Display Claude MPM Version Information
2
+
3
+ Show comprehensive version information for Claude MPM project, agents, and skills.
4
+
5
+ ## Usage
6
+
7
+ ```
8
+ /mpm-version
9
+ ```
10
+
11
+ ## Description
12
+
13
+ Display version information including:
14
+ - Project version and build number
15
+ - All deployed agents with their versions (grouped by tier: system/user/project)
16
+ - All available skills with their versions (grouped by source: bundled/user/project)
17
+ - Summary statistics
18
+
19
+ ## Implementation
20
+
21
+ When you run `/mpm-version`, the PM will:
22
+
23
+ 1. **Collect Version Information**
24
+ - Use VersionService to gather all version data
25
+ - Project version from pyproject.toml
26
+ - Build number from BUILD_NUMBER file
27
+ - Agent versions from AgentRegistry
28
+ - Skills versions from SkillRegistry
29
+
30
+ 2. **Format Output**
31
+ - Hierarchical display: Project → Agents → Skills
32
+ - Grouped by tier/source for clarity
33
+ - Sorted alphabetically within groups
34
+ - Summary statistics at the end
35
+
36
+ 3. **Display Results**
37
+ - Well-formatted tree structure
38
+ - Easy to scan and read
39
+ - Includes totals and counts
40
+
41
+ ## Example Output
42
+
43
+ ```
44
+ Claude MPM Version Information
45
+ ==============================
46
+
47
+ Project Version: 4.16.3
48
+ Build: 481
49
+
50
+ Agents (35 total)
51
+ -----------------
52
+
53
+ System Agents (30):
54
+ ├─ agent-manager (1.0.0)
55
+ ├─ engineer (3.9.1)
56
+ ├─ research-agent (4.5.1)
57
+ ├─ documentation (2.1.0)
58
+ ├─ qa (2.0.3)
59
+ └─ ... (25 more)
60
+
61
+ User Agents (3):
62
+ ├─ custom-agent (1.0.0)
63
+ ├─ testing-agent (0.5.0)
64
+ └─ prototype-agent (0.1.0)
65
+
66
+ Project Agents (2):
67
+ ├─ project-specific (2.0.0)
68
+ └─ domain-expert (1.1.0)
69
+
70
+ Skills (20 total)
71
+ -----------------
72
+
73
+ Bundled Skills (20):
74
+ ├─ test-driven-development (0.1.0)
75
+ ├─ systematic-debugging (0.1.0)
76
+ ├─ async-testing (0.1.0)
77
+ ├─ performance-profiling (0.1.0)
78
+ ├─ security-scanning (0.1.0)
79
+ └─ ... (15 more)
80
+
81
+ User Skills (0):
82
+ (none)
83
+
84
+ Project Skills (0):
85
+ (none)
86
+
87
+ Summary
88
+ -------
89
+ • Project: v4.16.3 (build 481)
90
+ • Agents: 35 total (30 system, 3 user, 2 project)
91
+ • Skills: 20 total (20 bundled, 0 user, 0 project)
92
+ ```
93
+
94
+ ## PM Implementation Instructions
95
+
96
+ To execute this command, PM should:
97
+
98
+ 1. Import and use VersionService:
99
+ ```python
100
+ from claude_mpm.services.version_service import VersionService
101
+
102
+ service = VersionService()
103
+ summary = service.get_version_summary()
104
+ ```
105
+
106
+ 2. Format output following the example structure above
107
+ 3. Handle missing data gracefully (show "unknown" for missing versions)
108
+ 4. Include all tiers/sources even if counts are zero
109
+
110
+ ## Related Commands
111
+
112
+ - `/mpm-help` - Show all available MPM commands
113
+ - `/mpm-status` - Show system status information
@@ -8,6 +8,7 @@ Available MPM commands:
8
8
  - /mpm-help - Show command help
9
9
  - /mpm-status - Show MPM status
10
10
  - /mpm-config - Manage configuration
11
+ - /mpm-version - Display version information for project, agents, and skills
11
12
 
12
13
  Claude MPM extends Claude Code with:
13
14
  - Multi-agent orchestration
@@ -242,7 +242,7 @@ class AgentConfig:
242
242
  Path.cwd() / get_path_manager().CONFIG_DIR / "agent_config.yaml"
243
243
  )
244
244
  if project_config.exists():
245
- logger.info(f"Loading project agent config from {project_config}")
245
+ logger.debug(f"Loading project agent config from {project_config}")
246
246
  file_config = cls.from_file(project_config)
247
247
  # Merge with environment config (env takes precedence)
248
248
  config = cls._merge_configs(config, file_config)
@@ -252,7 +252,7 @@ class AgentConfig:
252
252
  if user_config_dir:
253
253
  user_config = user_config_dir / "agent_config.yaml"
254
254
  if user_config.exists():
255
- logger.info(f"Loading user agent config from {user_config}")
255
+ logger.debug(f"Loading user agent config from {user_config}")
256
256
  file_config = cls.from_file(user_config)
257
257
  config = cls._merge_configs(config, file_config)
258
258