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
@@ -12,15 +12,15 @@ import contextlib
12
12
  import subprocess
13
13
  import sys
14
14
  from pathlib import Path
15
- from typing import Dict, List, Optional
15
+ from typing import Any, Dict, List, Optional
16
16
 
17
17
  import click
18
18
  from rich.console import Console
19
19
  from rich.panel import Panel
20
20
  from rich.progress import Progress, SpinnerColumn, TextColumn
21
21
  from rich.prompt import Prompt
22
- from rich.table import Table
23
22
 
23
+ from claude_mpm.core.enums import OperationResult
24
24
  from claude_mpm.core.logging_utils import get_logger
25
25
 
26
26
  # Import new services
@@ -28,6 +28,7 @@ from claude_mpm.services.project.archive_manager import ArchiveManager
28
28
  from claude_mpm.services.project.documentation_manager import DocumentationManager
29
29
  from claude_mpm.services.project.enhanced_analyzer import EnhancedProjectAnalyzer
30
30
  from claude_mpm.services.project.project_organizer import ProjectOrganizer
31
+ from claude_mpm.utils.display_helper import DisplayHelper
31
32
 
32
33
  logger = get_logger(__name__)
33
34
  console = Console()
@@ -46,6 +47,7 @@ class MPMInitCommand:
46
47
  self.organizer = ProjectOrganizer(self.project_path)
47
48
  self.archive_manager = ArchiveManager(self.project_path)
48
49
  self.analyzer = EnhancedProjectAnalyzer(self.project_path)
50
+ self.display = DisplayHelper(console)
49
51
 
50
52
  def initialize_project(
51
53
  self,
@@ -53,7 +55,6 @@ class MPMInitCommand:
53
55
  framework: Optional[str] = None,
54
56
  force: bool = False,
55
57
  verbose: bool = False,
56
- use_venv: bool = False,
57
58
  ast_analysis: bool = True,
58
59
  update_mode: bool = False,
59
60
  review_only: bool = False,
@@ -62,6 +63,7 @@ class MPMInitCommand:
62
63
  skip_archive: bool = False,
63
64
  dry_run: bool = False,
64
65
  quick_update: bool = False,
66
+ catchup: bool = False,
65
67
  non_interactive: bool = False,
66
68
  days: int = 30,
67
69
  export: Optional[str] = None,
@@ -74,7 +76,6 @@ class MPMInitCommand:
74
76
  framework: Specific framework if applicable
75
77
  force: Force initialization even if project already configured
76
78
  verbose: Show detailed output
77
- use_venv: Force use of venv instead of mamba
78
79
  ast_analysis: Enable AST analysis for enhanced documentation
79
80
  update_mode: Update existing CLAUDE.md instead of recreating
80
81
  review_only: Review project state without making changes
@@ -83,6 +84,7 @@ class MPMInitCommand:
83
84
  skip_archive: Skip archiving existing files
84
85
  dry_run: Show what would be done without making changes
85
86
  quick_update: Perform lightweight update based on recent git activity
87
+ catchup: Show recent commit history from all branches for PM context
86
88
  non_interactive: Non-interactive mode - display report only without prompting
87
89
  days: Number of days for git history analysis (7, 14, 30, 60, or 90)
88
90
  export: Export report to file (path or "auto" for default location)
@@ -98,6 +100,15 @@ class MPMInitCommand:
98
100
  if review_only:
99
101
  return self._run_review_mode()
100
102
 
103
+ if catchup:
104
+ data = self._catchup()
105
+ self._display_catchup(data)
106
+ return {
107
+ "status": OperationResult.SUCCESS,
108
+ "mode": "catchup",
109
+ "catchup_data": data,
110
+ }
111
+
101
112
  if quick_update:
102
113
  return self._run_quick_update_mode(
103
114
  days=days,
@@ -133,7 +144,7 @@ class MPMInitCommand:
133
144
  return self._run_review_mode()
134
145
  else:
135
146
  return {
136
- "status": "cancelled",
147
+ "status": OperationResult.CANCELLED,
137
148
  "message": "Initialization cancelled",
138
149
  }
139
150
 
@@ -146,7 +157,7 @@ class MPMInitCommand:
146
157
  pre_check_result = self._run_pre_initialization_checks(
147
158
  organize_files, skip_archive, has_existing
148
159
  )
149
- if pre_check_result.get("status") == "error":
160
+ if pre_check_result.get("status") == OperationResult.ERROR:
150
161
  return pre_check_result
151
162
 
152
163
  # Build the delegation prompt
@@ -179,9 +190,7 @@ class MPMInitCommand:
179
190
  task = progress.add_task(task_desc, total=None)
180
191
 
181
192
  # Run the initialization through subprocess
182
- result = self._run_initialization(
183
- prompt, verbose, use_venv, update_mode
184
- )
193
+ result = self._run_initialization(prompt, verbose, update_mode)
185
194
 
186
195
  complete_desc = (
187
196
  "[green]✓ Update complete"
@@ -191,7 +200,7 @@ class MPMInitCommand:
191
200
  progress.update(task, description=complete_desc)
192
201
 
193
202
  # Post-processing for update mode
194
- if update_mode and result.get("status") == "success":
203
+ if update_mode and result.get("status") == OperationResult.SUCCESS:
195
204
  self._handle_update_post_processing()
196
205
 
197
206
  return result
@@ -199,7 +208,7 @@ class MPMInitCommand:
199
208
  except Exception as e:
200
209
  logger.error(f"Failed to initialize project: {e}")
201
210
  console.print(f"[red]❌ Error: {e}[/red]")
202
- return {"status": "error", "message": str(e)}
211
+ return {"status": OperationResult.ERROR, "message": str(e)}
203
212
 
204
213
  def _find_claude_mpm_script(self) -> Path:
205
214
  """Find the claude-mpm script location."""
@@ -397,17 +406,10 @@ The final CLAUDE.md should be a comprehensive, well-organized guide that any AI
397
406
 
398
407
  return base_prompt
399
408
 
400
- def _build_claude_mpm_command(
401
- self, verbose: bool, use_venv: bool = False
402
- ) -> List[str]:
409
+ def _build_claude_mpm_command(self, verbose: bool) -> List[str]:
403
410
  """Build the claude-mpm run command with appropriate arguments."""
404
411
  cmd = [str(self.claude_mpm_script)]
405
412
 
406
- # Add venv flag if requested or if mamba issues detected
407
- # This goes BEFORE the subcommand
408
- if use_venv:
409
- cmd.append("--use-venv")
410
-
411
413
  # Add top-level flags that go before 'run' subcommand
412
414
  cmd.append("--no-check-dependencies")
413
415
 
@@ -426,34 +428,7 @@ The final CLAUDE.md should be a comprehensive, well-organized guide that any AI
426
428
 
427
429
  def _display_documentation_status(self, analysis: Dict) -> None:
428
430
  """Display current documentation status."""
429
- table = Table(title="Current CLAUDE.md Status", show_header=True)
430
- table.add_column("Property", style="cyan")
431
- table.add_column("Value", style="white")
432
-
433
- table.add_row("Size", f"{analysis.get('size', 0):,} characters")
434
- table.add_row("Lines", str(analysis.get("lines", 0)))
435
- table.add_row("Sections", str(len(analysis.get("sections", []))))
436
- table.add_row(
437
- "Has Priority Index", "✓" if analysis.get("has_priority_index") else "✗"
438
- )
439
- table.add_row(
440
- "Has Priority Markers", "✓" if analysis.get("has_priority_markers") else "✗"
441
- )
442
-
443
- if analysis.get("last_modified"):
444
- table.add_row("Last Modified", analysis["last_modified"])
445
-
446
- console.print(table)
447
-
448
- if analysis.get("outdated_patterns"):
449
- console.print("\n[yellow]⚠️ Outdated patterns detected:[/yellow]")
450
- for pattern in analysis["outdated_patterns"]:
451
- console.print(f" • {pattern}")
452
-
453
- if analysis.get("custom_sections"):
454
- console.print("\n[blue][INFO]️ Custom sections found:[/blue]")
455
- for section in analysis["custom_sections"][:5]:
456
- console.print(f" • {section}")
431
+ self.display.display_documentation_status(analysis)
457
432
 
458
433
  def _prompt_update_action(self) -> str:
459
434
  """Prompt user for update action."""
@@ -514,7 +489,7 @@ The final CLAUDE.md should be a comprehensive, well-organized guide that any AI
514
489
  )
515
490
 
516
491
  return {
517
- "status": "success",
492
+ "status": OperationResult.SUCCESS,
518
493
  "mode": "review",
519
494
  "structure_report": structure_report,
520
495
  "documentation_analysis": doc_analysis,
@@ -526,29 +501,26 @@ The final CLAUDE.md should be a comprehensive, well-organized guide that any AI
526
501
  self, structure: Dict, docs: Dict, git: Optional[Dict], state: Dict
527
502
  ) -> None:
528
503
  """Display comprehensive review report."""
529
- console.print("\n" + "=" * 60)
530
- console.print("[bold]PROJECT REVIEW REPORT[/bold]")
531
- console.print("=" * 60 + "\n")
504
+ self.display.display_header("PROJECT REVIEW REPORT")
532
505
 
533
506
  # Project State
534
- console.print("[bold cyan]📊 Project State[/bold cyan]")
535
- console.print(f" Phase: {state.get('phase', 'unknown')}")
507
+ state_data = {"Phase": state.get("phase", "unknown")}
536
508
  if state.get("indicators"):
537
- console.print(" Indicators:")
538
- for indicator in state["indicators"][:5]:
539
- console.print(f" • {indicator}")
509
+ state_data["Indicators"] = state["indicators"][:5]
510
+ self.display.display_report_section("📊 Project State", state_data)
540
511
 
541
512
  # Structure Report
542
- console.print("\n[bold cyan]📁 Project Structure[/bold cyan]")
543
- console.print(f" Existing directories: {len(structure.get('exists', []))}")
544
- console.print(f" Missing directories: {len(structure.get('missing', []))}")
513
+ structure_data = {
514
+ "Existing directories": len(structure.get("exists", [])),
515
+ "Missing directories": len(structure.get("missing", [])),
516
+ }
545
517
  if structure.get("issues"):
546
- console.print(f" Issues found: {len(structure['issues'])}")
547
- for issue in structure["issues"][:3]:
548
- console.print(f" ⚠️ {issue['description']}")
518
+ structure_data["Issues found"] = len(structure["issues"])
519
+ structure_data["Issues"] = structure["issues"][:3]
520
+ self.display.display_report_section("📁 Project Structure", structure_data)
549
521
 
550
522
  # Documentation Report
551
- console.print("\n[bold cyan]📚 Documentation Status[/bold cyan]")
523
+ self.display.display_section_title("📚 Documentation Status")
552
524
  if docs.get("exists"):
553
525
  console.print(f" CLAUDE.md: Found ({docs.get('size', 0):,} chars)")
554
526
  console.print(f" Sections: {len(docs.get('sections', []))}")
@@ -560,32 +532,34 @@ The final CLAUDE.md should be a comprehensive, well-organized guide that any AI
560
532
 
561
533
  # Git Analysis
562
534
  if git and git.get("git_available"):
563
- console.print("\n[bold cyan]📈 Recent Activity (30 days)[/bold cyan]")
564
- console.print(f" Commits: {len(git.get('recent_commits', []))}")
565
- console.print(
566
- f" Authors: {git.get('authors', {}).get('total_authors', 0)}"
567
- )
568
- console.print(
569
- f" Changed files: {git.get('changed_files', {}).get('total_files', 0)}"
570
- )
535
+ git_metrics = {
536
+ "Commits": len(git.get("recent_commits", [])),
537
+ "Authors": git.get("authors", {}).get("total_authors", 0),
538
+ "Changed files": git.get("changed_files", {}).get("total_files", 0),
539
+ }
571
540
 
572
541
  if git.get("branch_info"):
573
542
  branch_info = git["branch_info"]
574
- console.print(
575
- f" Current branch: {branch_info.get('current_branch', 'unknown')}"
543
+ git_metrics["Current branch"] = branch_info.get(
544
+ "current_branch", "unknown"
545
+ )
546
+
547
+ self.display.display_metrics_section(
548
+ "📈 Recent Activity (30 days)", git_metrics
549
+ )
550
+
551
+ if git.get("branch_info", {}).get("has_uncommitted_changes"):
552
+ self.display.display_metric_row(
553
+ "⚠️ Uncommitted changes",
554
+ f"{git['branch_info'].get('uncommitted_files', 0)} files",
555
+ warning=True,
576
556
  )
577
- if branch_info.get("has_uncommitted_changes"):
578
- console.print(
579
- f" ⚠️ Uncommitted changes: {branch_info.get('uncommitted_files', 0)} files"
580
- )
581
557
 
582
558
  # Recommendations
583
559
  if state.get("recommendations"):
584
- console.print("\n[bold cyan]💡 Recommendations[/bold cyan]")
585
- for rec in state["recommendations"][:5]:
586
- console.print(f" → {rec}")
560
+ self.display.display_recommendations(state["recommendations"])
587
561
 
588
- console.print("\n" + "=" * 60 + "\n")
562
+ self.display.display_separator()
589
563
 
590
564
  def _run_quick_update_mode(
591
565
  self,
@@ -607,7 +581,7 @@ The final CLAUDE.md should be a comprehensive, well-organized guide that any AI
607
581
  "[dim]Tip: Use `/mpm-init --review` for non-git projects.[/dim]\n"
608
582
  )
609
583
  return {
610
- "status": "error",
584
+ "status": OperationResult.ERROR,
611
585
  "message": "Quick update requires a git repository",
612
586
  }
613
587
 
@@ -620,7 +594,7 @@ The final CLAUDE.md should be a comprehensive, well-organized guide that any AI
620
594
  "[dim]Tip: Use `/mpm-init` to create initial documentation.[/dim]\n"
621
595
  )
622
596
  return {
623
- "status": "error",
597
+ "status": OperationResult.ERROR,
624
598
  "message": "Quick update requires existing CLAUDE.md",
625
599
  }
626
600
 
@@ -662,7 +636,7 @@ The final CLAUDE.md should be a comprehensive, well-organized guide that any AI
662
636
  "\n[cyan]ℹ️ Non-interactive mode: Report displayed, no changes made.[/cyan]"
663
637
  )
664
638
  return {
665
- "status": "success",
639
+ "status": OperationResult.SUCCESS,
666
640
  "mode": "quick_update",
667
641
  "activity_report": activity_report,
668
642
  "changes_made": False,
@@ -690,7 +664,7 @@ The final CLAUDE.md should be a comprehensive, well-organized guide that any AI
690
664
  )
691
665
 
692
666
  return {
693
- "status": "success",
667
+ "status": OperationResult.SUCCESS,
694
668
  "mode": "quick_update",
695
669
  "activity_report": activity_report,
696
670
  "changes_made": True,
@@ -698,13 +672,152 @@ The final CLAUDE.md should be a comprehensive, well-organized guide that any AI
698
672
  if choice == "2":
699
673
  console.print("\n[cyan]Report generated - no changes made[/cyan]")
700
674
  return {
701
- "status": "success",
675
+ "status": OperationResult.SUCCESS,
702
676
  "mode": "quick_update",
703
677
  "activity_report": activity_report,
704
678
  "changes_made": False,
705
679
  }
706
680
  console.print("\n[yellow]Quick update cancelled[/yellow]")
707
- return {"status": "cancelled", "message": "Quick update cancelled"}
681
+ return {
682
+ "status": OperationResult.CANCELLED,
683
+ "message": "Quick update cancelled",
684
+ }
685
+
686
+ def _catchup(self) -> Dict[str, Any]:
687
+ """Get recent commit history for PM context.
688
+
689
+ Returns:
690
+ Dict containing commit history and contributor stats
691
+ """
692
+ from collections import Counter
693
+ from datetime import datetime
694
+ from subprocess import run
695
+
696
+ try:
697
+ # Get last 25 commits from all branches with author info
698
+ result = run(
699
+ ["git", "log", "--all", "--format=%h|%an|%ai|%s", "-25"],
700
+ capture_output=True,
701
+ text=True,
702
+ check=True,
703
+ cwd=str(self.project_path),
704
+ )
705
+
706
+ commits = []
707
+ authors = []
708
+
709
+ for line in result.stdout.strip().split("\n"):
710
+ if not line:
711
+ continue
712
+
713
+ parts = line.split("|", 3)
714
+ if len(parts) == 4:
715
+ hash_val, author, date_str, message = parts
716
+
717
+ # Parse date
718
+ try:
719
+ dt = datetime.fromisoformat(date_str.replace(" ", "T", 1))
720
+ date_display = dt.strftime("%Y-%m-%d %H:%M")
721
+ except Exception:
722
+ date_display = date_str[:16]
723
+
724
+ commits.append(
725
+ {
726
+ "hash": hash_val,
727
+ "author": author,
728
+ "date": date_display,
729
+ "message": message,
730
+ }
731
+ )
732
+ authors.append(author)
733
+
734
+ # Calculate contributor stats
735
+ author_counts = Counter(authors)
736
+
737
+ return {
738
+ "commits": commits,
739
+ "total_commits": len(commits),
740
+ "contributors": dict(author_counts),
741
+ "contributor_count": len(author_counts),
742
+ }
743
+
744
+ except Exception as e:
745
+ console.print(f"[yellow]Could not retrieve commit history: {e}[/yellow]")
746
+ return {
747
+ "commits": [],
748
+ "total_commits": 0,
749
+ "contributors": {},
750
+ "contributor_count": 0,
751
+ "error": str(e),
752
+ }
753
+
754
+ def _display_catchup(self, data: Dict[str, Any]) -> None:
755
+ """Display catchup information to console.
756
+
757
+ Args:
758
+ data: Commit history data from _catchup()
759
+ """
760
+ from rich.panel import Panel
761
+ from rich.table import Table
762
+
763
+ if data.get("error"):
764
+ console.print(
765
+ Panel(
766
+ "[yellow]Not a git repository or no commits found[/yellow]",
767
+ title="⚠️ Catchup Status",
768
+ border_style="yellow",
769
+ )
770
+ )
771
+ return
772
+
773
+ # Display contributor summary
774
+ if data["contributors"]:
775
+ console.print("\n[bold cyan]👥 Active Contributors[/bold cyan]")
776
+ for author, count in sorted(
777
+ data["contributors"].items(), key=lambda x: x[1], reverse=True
778
+ ):
779
+ console.print(
780
+ f" • [green]{author}[/green]: {count} commit{'s' if count != 1 else ''}"
781
+ )
782
+
783
+ # Display commit history table
784
+ if data["commits"]:
785
+ console.print(
786
+ f"\n[bold cyan]📝 Last {data['total_commits']} Commits[/bold cyan]"
787
+ )
788
+
789
+ table = Table(
790
+ show_header=True, header_style="bold magenta", border_style="dim"
791
+ )
792
+ table.add_column("#", style="dim", width=3)
793
+ table.add_column("Hash", style="yellow", width=8)
794
+ table.add_column("Author", style="green", width=20)
795
+ table.add_column("Date", style="cyan", width=16)
796
+ table.add_column("Message", style="white")
797
+
798
+ for idx, commit in enumerate(data["commits"], 1):
799
+ # Truncate message if too long
800
+ msg = commit["message"]
801
+ if len(msg) > 80:
802
+ msg = msg[:77] + "..."
803
+
804
+ # Truncate author if too long
805
+ author = commit["author"]
806
+ if len(author) > 18:
807
+ author = author[:18] + "..."
808
+
809
+ table.add_row(str(idx), commit["hash"], author, commit["date"], msg)
810
+
811
+ console.print(table)
812
+
813
+ # Display PM recommendations
814
+ console.print("\n[bold cyan]💡 PM Recommendations[/bold cyan]")
815
+ console.print(
816
+ f" • Total activity: {data['total_commits']} commits from {data['contributor_count']} contributor{'s' if data['contributor_count'] != 1 else ''}"
817
+ )
818
+ console.print(" • Review commit messages for recent project context")
819
+ console.print(" • Identify development patterns and focus areas")
820
+ console.print(" • Use this context to inform current work priorities\n")
708
821
 
709
822
  def _generate_activity_report(
710
823
  self, git_analysis: Dict, doc_analysis: Dict, days: int = 30
@@ -881,70 +994,49 @@ The final CLAUDE.md should be a comprehensive, well-organized guide that any AI
881
994
 
882
995
  def _display_activity_report(self, report: Dict) -> None:
883
996
  """Display the activity report in a formatted manner."""
884
- console.print("\n" + "=" * 60)
885
- console.print("[bold]RECENT ACTIVITY SUMMARY[/bold]")
886
- console.print("=" * 60 + "\n")
997
+ self.display.display_header("RECENT ACTIVITY SUMMARY")
887
998
 
888
999
  summary = report.get("summary", {})
889
1000
  period = report.get("period", "Last 30 days")
890
1001
 
891
1002
  # Summary statistics
892
- console.print(f"[bold cyan]📊 Activity Overview ({period.lower()})[/bold cyan]")
893
- console.print(f" Total commits: {summary.get('total_commits', 0)}")
894
- console.print(f" Active contributors: {summary.get('total_authors', 0)}")
895
- console.print(f" Files modified: {summary.get('files_changed', 0)}")
896
- console.print(f" Current branch: {summary.get('current_branch', 'unknown')}")
897
-
898
- if summary.get("has_uncommitted"):
899
- console.print(
900
- f" [yellow]⚠️ Uncommitted changes: {summary.get('uncommitted_count', 0)} files[/yellow]"
901
- )
1003
+ self.display.display_activity_summary(summary, period)
902
1004
 
903
1005
  # Recent commits
904
1006
  recent_commits = report.get("recent_commits", [])
905
1007
  if recent_commits:
906
- console.print("\n[bold cyan]📝 Recent Commits (last 10)[/bold cyan]")
907
- for commit in recent_commits[:10]:
908
- console.print(
909
- f" [{commit['hash']}] {commit['message'][:60]} - {commit['author']}"
910
- )
1008
+ self.display.display_commit_list(recent_commits)
911
1009
 
912
1010
  # Hot files
913
1011
  hot_files = report.get("hot_files", [])
914
1012
  if hot_files:
915
- console.print("\n[bold cyan]🔥 Most Changed Files[/bold cyan]")
916
- for file_path, changes in hot_files[:10]:
917
- console.print(f" {file_path}: {changes} changes")
1013
+ self.display.display_file_change_list(hot_files)
918
1014
 
919
1015
  # Active branches
920
1016
  branches = report.get("active_branches", [])
1017
+ current_branch = summary.get("current_branch", "unknown")
921
1018
  if branches:
922
- console.print("\n[bold cyan]🌿 Active Branches[/bold cyan]")
923
- for branch in branches:
924
- marker = "→" if branch == summary.get("current_branch") else " "
925
- console.print(f" {marker} {branch}")
1019
+ self.display.display_branch_list(branches, current_branch)
926
1020
 
927
1021
  # Documentation status
928
1022
  doc_status = report.get("doc_status", {})
929
1023
  if doc_status:
930
- console.print("\n[bold cyan]📚 CLAUDE.md Status[/bold cyan]")
931
- console.print(f" Size: {doc_status.get('size', 0):,} characters")
932
- console.print(f" Lines: {doc_status.get('lines', 0)}")
933
- console.print(
934
- f" Priority markers: {'' if doc_status.get('has_priority_markers') else ''}"
935
- )
936
- console.print(
937
- f" Last modified: {doc_status.get('last_modified', 'unknown')}"
938
- )
1024
+ doc_metrics = {
1025
+ "Size": f"{doc_status.get('size', 0):,} characters",
1026
+ "Lines": doc_status.get("lines", 0),
1027
+ "Priority markers": (
1028
+ "✓" if doc_status.get("has_priority_markers") else "✗"
1029
+ ),
1030
+ "Last modified": doc_status.get("last_modified", "unknown"),
1031
+ }
1032
+ self.display.display_metrics_section("📚 CLAUDE.md Status", doc_metrics)
939
1033
 
940
1034
  # Recommendations
941
1035
  recommendations = report.get("recommendations", [])
942
1036
  if recommendations:
943
- console.print("\n[bold cyan]💡 Recommendations[/bold cyan]")
944
- for rec in recommendations:
945
- console.print(f" → {rec}")
1037
+ self.display.display_recommendations(recommendations)
946
1038
 
947
- console.print("\n" + "=" * 60 + "\n")
1039
+ self.display.display_separator()
948
1040
 
949
1041
  def _append_activity_notes(self, claude_md_path: Path, report: Dict) -> None:
950
1042
  """Append activity notes to CLAUDE.md."""
@@ -1066,7 +1158,7 @@ The final CLAUDE.md should be a comprehensive, well-organized guide that any AI
1066
1158
  console.print("\n[dim]Run without --dry-run to execute these changes.[/dim]\n")
1067
1159
 
1068
1160
  return {
1069
- "status": "success",
1161
+ "status": OperationResult.SUCCESS,
1070
1162
  "mode": "dry_run",
1071
1163
  "actions_planned": actions_planned,
1072
1164
  "message": "Dry run completed - no changes made",
@@ -1124,7 +1216,7 @@ The final CLAUDE.md should be a comprehensive, well-organized guide that any AI
1124
1216
  console.print()
1125
1217
 
1126
1218
  return {
1127
- "status": "success",
1219
+ "status": OperationResult.SUCCESS,
1128
1220
  "checks_passed": checks_passed,
1129
1221
  "warnings": warnings,
1130
1222
  }
@@ -1281,7 +1373,6 @@ preserving valuable project-specific information while refreshing standard secti
1281
1373
  self,
1282
1374
  prompt: str,
1283
1375
  verbose: bool,
1284
- use_venv: bool = False,
1285
1376
  update_mode: bool = False,
1286
1377
  ) -> Dict:
1287
1378
  """Run the initialization through subprocess calling claude-mpm."""
@@ -1297,7 +1388,7 @@ preserving valuable project-specific information while refreshing standard secti
1297
1388
 
1298
1389
  try:
1299
1390
  # Build the command
1300
- cmd = self._build_claude_mpm_command(verbose, use_venv)
1391
+ cmd = self._build_claude_mpm_command(verbose)
1301
1392
  # Add the input file flag
1302
1393
  cmd.extend(["-i", prompt_file])
1303
1394
 
@@ -1314,30 +1405,6 @@ preserving valuable project-specific information while refreshing standard secti
1314
1405
  cwd=str(self.project_path),
1315
1406
  check=False,
1316
1407
  )
1317
-
1318
- # Check for environment-specific errors
1319
- if "libmamba" in result.stderr or "tree-sitter" in result.stderr:
1320
- console.print(
1321
- "\n[yellow]⚠️ Environment dependency issue detected.[/yellow]"
1322
- )
1323
- console.print(
1324
- "[yellow]Attempting alternative initialization method...[/yellow]\n"
1325
- )
1326
-
1327
- # Try again with venv flag to bypass mamba
1328
- cmd_venv = self._build_claude_mpm_command(verbose, use_venv=True)
1329
- cmd_venv.extend(["-i", prompt_file])
1330
-
1331
- if verbose:
1332
- console.print(f"[dim]Retrying with: {' '.join(cmd_venv)}[/dim]")
1333
-
1334
- result = subprocess.run(
1335
- cmd_venv,
1336
- capture_output=not verbose,
1337
- text=True,
1338
- cwd=str(self.project_path),
1339
- check=False,
1340
- )
1341
1408
  finally:
1342
1409
  # Clean up temporary file
1343
1410
 
@@ -1353,7 +1420,7 @@ preserving valuable project-specific information while refreshing standard secti
1353
1420
  # Check result - be more lenient with return codes
1354
1421
  if result.returncode == 0 or (self.project_path / "CLAUDE.md").exists():
1355
1422
  response = {
1356
- "status": "success",
1423
+ "status": OperationResult.SUCCESS,
1357
1424
  "message": "Project initialized successfully",
1358
1425
  "files_created": [],
1359
1426
  "files_updated": [],
@@ -1388,19 +1455,10 @@ preserving valuable project-specific information while refreshing standard secti
1388
1455
  if result.stderr
1389
1456
  else result.stdout if result.stdout else "Unknown error occurred"
1390
1457
  )
1391
- # Clean up mamba warnings from error message
1392
- if "libmamba" in error_msg:
1393
- lines = error_msg.split("\n")
1394
- error_lines = [
1395
- line
1396
- for line in lines
1397
- if not line.startswith("warning") and line.strip()
1398
- ]
1399
- error_msg = "\n".join(error_lines) if error_lines else error_msg
1400
1458
 
1401
1459
  logger.error(f"claude-mpm run failed: {error_msg}")
1402
1460
  return {
1403
- "status": "error",
1461
+ "status": OperationResult.ERROR,
1404
1462
  "message": f"Initialization failed: {error_msg}",
1405
1463
  }
1406
1464
 
@@ -1409,52 +1467,259 @@ preserving valuable project-specific information while refreshing standard secti
1409
1467
  console.print(
1410
1468
  "[red]Error: claude-mpm command not found. Ensure Claude MPM is properly installed.[/red]"
1411
1469
  )
1412
- return {"status": "error", "message": "claude-mpm not found"}
1470
+ return {"status": OperationResult.ERROR, "message": "claude-mpm not found"}
1413
1471
  except Exception as e:
1414
1472
  logger.error(f"Initialization failed: {e}")
1415
- return {"status": "error", "message": str(e)}
1473
+ return {"status": OperationResult.ERROR, "message": str(e)}
1474
+
1475
+ def handle_context(
1476
+ self,
1477
+ session_id: Optional[str] = None,
1478
+ list_sessions: bool = False,
1479
+ days: int = 7,
1480
+ ) -> Dict[str, Any]:
1481
+ """
1482
+ Provide intelligent context for resuming work based on git history.
1483
+
1484
+ Analyzes recent commits to identify:
1485
+ - Active work streams (what was being worked on)
1486
+ - Intent and motivation (why this work)
1487
+ - Risks and blockers
1488
+ - Recommended next actions
1489
+
1490
+ This delegates to Research agent for deep analysis.
1491
+
1492
+ Args:
1493
+ session_id: Unused parameter (for compatibility)
1494
+ list_sessions: Unused parameter (for compatibility)
1495
+ days: Number of days of git history to analyze (default: 7)
1496
+
1497
+ Returns:
1498
+ Dict containing context result
1499
+ """
1500
+ from claude_mpm.utils.git_analyzer import analyze_recent_activity
1501
+
1502
+ # 1. Analyze git history with adaptive window
1503
+ console.print(f"\n🔍 Analyzing last {days} days of git history...\n")
1504
+ git_analysis = analyze_recent_activity(
1505
+ repo_path=str(self.project_path), days=days, max_commits=50, min_commits=25
1506
+ )
1507
+
1508
+ # Show adaptive behavior to user
1509
+ if git_analysis.get("adaptive_mode"):
1510
+ console.print(
1511
+ f"[cyan]ℹ️ Note: Analyzed {git_analysis.get('actual_time_span', 'extended period')} "
1512
+ f"to get meaningful context[/cyan]"
1513
+ )
1514
+ if git_analysis.get("reason"):
1515
+ console.print(f"[dim] Reason: {git_analysis['reason']}[/dim]\n")
1516
+ else:
1517
+ console.print()
1518
+
1519
+ if git_analysis.get("error"):
1520
+ console.print(
1521
+ f"[yellow]⚠️ Could not analyze git history: {git_analysis['error']}[/yellow]"
1522
+ )
1523
+ console.print(
1524
+ "[dim]Ensure this is a git repository with commit history.[/dim]\n"
1525
+ )
1526
+ return {
1527
+ "status": OperationResult.ERROR,
1528
+ "message": git_analysis["error"],
1529
+ }
1530
+
1531
+ if not git_analysis.get("has_activity"):
1532
+ console.print(
1533
+ f"[yellow]⚠️ No git activity found in the last {days} days.[/yellow]"
1534
+ )
1535
+ console.print("[dim]Try increasing the --days parameter.[/dim]\n")
1536
+ return {
1537
+ "status": OperationResult.ERROR,
1538
+ "message": f"No git activity in last {days} days",
1539
+ }
1540
+
1541
+ # 2. Build Research delegation prompt
1542
+ research_prompt = self._build_research_context_prompt(git_analysis, days)
1543
+
1544
+ # 3. Display prompt for PM to delegate
1545
+ console.print("\n" + "=" * 80)
1546
+ console.print("📋 DELEGATE TO RESEARCH AGENT:")
1547
+ console.print("=" * 80 + "\n")
1548
+ console.print(research_prompt)
1549
+ console.print("\n" + "=" * 80 + "\n")
1550
+
1551
+ return {
1552
+ "status": OperationResult.CONTEXT_READY,
1553
+ "git_analysis": git_analysis,
1554
+ "research_prompt": research_prompt,
1555
+ "recommendation": "PM should delegate this prompt to Research agent",
1556
+ }
1557
+
1558
+ def _build_research_context_prompt(
1559
+ self, git_analysis: Dict[str, Any], days: int
1560
+ ) -> str:
1561
+ """Build structured Research agent delegation prompt from git analysis."""
1562
+
1563
+ # Extract key data
1564
+ commits = git_analysis.get("commits", [])
1565
+ branches = git_analysis.get("branches", [])
1566
+ contributors = git_analysis.get("contributors", {})
1567
+ file_changes = git_analysis.get("file_changes", {})
1568
+
1569
+ # Build prompt following Prompt Engineer's template
1570
+ prompt = f"""# Project Context Analysis Mission
1571
+
1572
+ You are Research agent analyzing git history to provide PM with intelligent project context for resuming work.
1573
+
1574
+ ## Analysis Scope
1575
+ - **Time Range**: Last {days} days"""
1576
+
1577
+ # Add adaptive mode note if applicable
1578
+ if git_analysis.get("adaptive_mode"):
1579
+ actual_days = git_analysis.get("actual_time_span", "extended period")
1580
+ prompt += f""" (adaptive: {actual_days} days analyzed)
1581
+ - **Note**: {git_analysis.get('reason', 'Analysis window adjusted to ensure meaningful context')}"""
1582
+
1583
+ prompt += f"""
1584
+ - **Commits Analyzed**: {len(commits)} commits
1585
+ - **Branches**: {', '.join(branches[:5]) if branches else 'main'}
1586
+ - **Contributors**: {', '.join(contributors.keys()) if contributors else 'Unknown'}
1587
+
1588
+ ## Your Mission
1589
+
1590
+ Analyze git history to answer these questions for PM:
1591
+
1592
+ 1. **What was being worked on?** (Active work streams)
1593
+ 2. **Why was this work happening?** (Intent and motivation)
1594
+ 3. **What's the natural next step?** (Continuation recommendations)
1595
+ 4. **What needs attention?** (Risks, stalls, conflicts)
1596
+
1597
+ ## Git Data Provided
1598
+
1599
+ ### Recent Commits ({min(len(commits), 10)} most recent):
1600
+ """
1601
+
1602
+ # Add recent commits
1603
+ for commit in commits[:10]:
1604
+ author = commit.get("author", "Unknown")
1605
+ timestamp = commit.get("timestamp", "Unknown date")
1606
+ message = commit.get("message", "No message")
1607
+ files = commit.get("files", [])
1608
+
1609
+ prompt += f"\n- **{timestamp}** by {author}"
1610
+ prompt += f"\n {message}"
1611
+ prompt += f"\n Files changed: {len(files)}\n"
1612
+
1613
+ # Add file change summary
1614
+ if file_changes:
1615
+ # Sort by modifications count
1616
+ sorted_files = sorted(
1617
+ file_changes.items(),
1618
+ key=lambda x: x[1].get("modifications", 0),
1619
+ reverse=True,
1620
+ )
1621
+ prompt += "\n### Most Changed Files:\n"
1622
+ for file_path, file_data in sorted_files[:10]:
1623
+ modifications = file_data.get("modifications", 0)
1624
+ file_contributors = file_data.get("contributors", [])
1625
+ prompt += f"- {file_path}: {modifications} changes ({len(file_contributors)} contributor{'s' if len(file_contributors) != 1 else ''})\n"
1626
+
1627
+ # Add contributor summary
1628
+ if contributors:
1629
+ prompt += "\n### Contributors:\n"
1630
+ sorted_contributors = sorted(
1631
+ contributors.items(),
1632
+ key=lambda x: x[1].get("commits", 0),
1633
+ reverse=True,
1634
+ )
1635
+ for name, info in sorted_contributors[:5]:
1636
+ commit_count = info.get("commits", 0)
1637
+ prompt += f"- {name}: {commit_count} commit{'s' if commit_count != 1 else ''}\n"
1638
+
1639
+ # Add analysis instructions
1640
+ prompt += """
1641
+
1642
+ ## Analysis Instructions
1643
+
1644
+ ### Phase 1: Work Stream Identification
1645
+ Group related commits into thematic work streams. For each stream:
1646
+ - **Name**: Infer from commit messages (e.g., "Authentication refactor")
1647
+ - **Status**: ongoing/completed/stalled
1648
+ - **Commits**: Count of commits in this stream
1649
+ - **Intent**: WHY this work (from commit bodies/messages)
1650
+ - **Key Files**: Most changed files in this stream
1651
+
1652
+ ### Phase 2: Risk Detection
1653
+ Identify:
1654
+ - **Stalled Work**: Work streams with no activity >3 days
1655
+ - **Anti-Patterns**: WIP commits, temp commits, debug commits
1656
+ - **Documentation Lag**: Code changes without doc updates
1657
+ - **Conflicts**: Merge conflicts or divergent branches
1658
+
1659
+ ### Phase 3: Recommendations
1660
+ Based on analysis:
1661
+ 1. **Primary Focus**: Most active/recent work to continue
1662
+ 2. **Quick Wins**: Small tasks that could be finished
1663
+ 3. **Blockers**: Issues preventing progress
1664
+ 4. **Next Steps**: Logical continuation points
1665
+
1666
+ ## Output Format
1667
+
1668
+ Provide a clear markdown summary with:
1669
+
1670
+ 1. **Active Work Streams** (What was being worked on)
1671
+ 2. **Intent Summary** (Why this work matters)
1672
+ 3. **Risks Detected** (What needs attention)
1673
+ 4. **Recommended Next Actions** (What to work on)
1674
+
1675
+ Keep it concise (<1000 words) but actionable.
1676
+
1677
+ ## Success Criteria
1678
+ - Work streams accurately reflect development themes
1679
+ - Intent captures the "why" not just "what"
1680
+ - Recommendations are specific and actionable
1681
+ - Risks are prioritized by impact
1682
+ """
1683
+
1684
+ return prompt
1416
1685
 
1417
1686
  def _display_results(self, result: Dict, verbose: bool):
1418
1687
  """Display initialization results."""
1419
- if result["status"] == "success":
1688
+ if result["status"] == OperationResult.SUCCESS:
1420
1689
  console.print("\n[green]✅ Project Initialization Complete![/green]\n")
1421
1690
 
1691
+ # Display files created
1422
1692
  if result.get("files_created"):
1423
- console.print("[bold]Files Created:[/bold]")
1424
- for file in result["files_created"]:
1425
- console.print(f" • {file}")
1426
- console.print()
1693
+ self.display.display_files_list(
1694
+ "Files Created:", result["files_created"]
1695
+ )
1427
1696
 
1697
+ # Display files updated
1428
1698
  if result.get("files_updated"):
1429
- console.print("[bold]Files Updated:[/bold]")
1430
- for file in result["files_updated"]:
1431
- console.print(f" • {file}")
1432
- console.print()
1699
+ self.display.display_files_list(
1700
+ "Files Updated:", result["files_updated"]
1701
+ )
1433
1702
 
1703
+ # Display next steps
1434
1704
  if result.get("next_steps"):
1435
- console.print("[bold]Next Steps:[/bold]")
1436
- for step in result["next_steps"]:
1437
- console.print(f" → {step}")
1438
- console.print()
1439
-
1440
- console.print(
1441
- Panel(
1442
- "[green]Your project is now optimized for Claude Code and Claude MPM![/green]\n\n"
1443
- "Key files:\n"
1444
- "• [cyan]CLAUDE.md[/cyan] - Main documentation for AI agents\n"
1445
- " - Organized with priority rankings (🔴🟡🟢⚪)\n"
1446
- " - Instructions ranked by importance for AI understanding\n"
1447
- " - Holistic documentation review completed\n"
1448
- "• [cyan].claude-mpm/[/cyan] - Configuration and memories\n"
1449
- "• [cyan]CODE_STRUCTURE.md[/cyan] - AST-derived architecture documentation (if enabled)\n\n"
1450
- "[dim]Run 'claude-mpm run' to start using the optimized setup[/dim]",
1451
- title="Success",
1452
- border_style="green",
1453
- )
1705
+ self.display.display_next_steps(result["next_steps"])
1706
+
1707
+ # Display success panel
1708
+ success_content = (
1709
+ "[green]Your project is now optimized for Claude Code and Claude MPM![/green]\n\n"
1710
+ "Key files:\n"
1711
+ "• [cyan]CLAUDE.md[/cyan] - Main documentation for AI agents\n"
1712
+ " - Organized with priority rankings (🔴🟡🟢⚪)\n"
1713
+ " - Instructions ranked by importance for AI understanding\n"
1714
+ " - Holistic documentation review completed\n"
1715
+ "• [cyan].claude-mpm/[/cyan] - Configuration and memories\n"
1716
+ " [cyan]CODE_STRUCTURE.md[/cyan] - AST-derived architecture documentation (if enabled)\n\n"
1717
+ "[dim]Run 'claude-mpm run' to start using the optimized setup[/dim]"
1454
1718
  )
1719
+ self.display.display_success_panel("Success", success_content)
1455
1720
 
1456
1721
 
1457
- @click.command(name="mpm-init")
1722
+ @click.group(name="mpm-init", invoke_without_command=True)
1458
1723
  @click.option(
1459
1724
  "--project-type",
1460
1725
  type=click.Choice(
@@ -1515,6 +1780,11 @@ preserving valuable project-specific information while refreshing standard secti
1515
1780
  is_flag=True,
1516
1781
  help="Perform lightweight update based on recent git activity (default: 30 days)",
1517
1782
  )
1783
+ @click.option(
1784
+ "--catchup",
1785
+ is_flag=True,
1786
+ help="Show recent commit history from all branches for PM context",
1787
+ )
1518
1788
  @click.option(
1519
1789
  "--non-interactive",
1520
1790
  is_flag=True,
@@ -1538,7 +1808,9 @@ preserving valuable project-specific information while refreshing standard secti
1538
1808
  required=False,
1539
1809
  default=".",
1540
1810
  )
1811
+ @click.pass_context
1541
1812
  def mpm_init(
1813
+ ctx,
1542
1814
  project_type,
1543
1815
  framework,
1544
1816
  force,
@@ -1551,6 +1823,7 @@ def mpm_init(
1551
1823
  verbose,
1552
1824
  ast_analysis,
1553
1825
  quick_update,
1826
+ catchup,
1554
1827
  non_interactive,
1555
1828
  days,
1556
1829
  export,
@@ -1567,18 +1840,27 @@ def mpm_init(
1567
1840
  - Optimize for AI agent understanding
1568
1841
  - Perform AST analysis for enhanced developer documentation
1569
1842
 
1843
+ Context Management:
1844
+ - resume: Analyze git history to provide context for resuming work
1845
+ - --catchup: Show recent commit history for PM context
1846
+
1570
1847
  Update Mode:
1571
1848
  When CLAUDE.md exists, the command offers to update rather than recreate,
1572
1849
  preserving custom content while refreshing standard sections.
1573
1850
 
1574
1851
  Examples:
1575
1852
  claude-mpm mpm-init # Initialize/update current directory
1853
+ claude-mpm mpm-init --catchup # Show recent git history for context
1576
1854
  claude-mpm mpm-init --review # Review project state without changes
1577
1855
  claude-mpm mpm-init --update # Force update mode
1578
1856
  claude-mpm mpm-init --organize # Organize misplaced files
1579
1857
  claude-mpm mpm-init --project-type web # Initialize as web project
1580
1858
  claude-mpm mpm-init /path/to/project --force # Force reinitialize project
1581
1859
  """
1860
+ # If a subcommand is being invoked, don't run the main command
1861
+ if ctx.invoked_subcommand is not None:
1862
+ return
1863
+
1582
1864
  try:
1583
1865
  # Create command instance
1584
1866
  command = MPMInitCommand(Path(project_path))
@@ -1596,13 +1878,14 @@ def mpm_init(
1596
1878
  preserve_custom=preserve_custom,
1597
1879
  skip_archive=skip_archive,
1598
1880
  quick_update=quick_update,
1881
+ catchup=catchup,
1599
1882
  non_interactive=non_interactive,
1600
1883
  days=days,
1601
1884
  export=export,
1602
1885
  )
1603
1886
 
1604
1887
  # Exit with appropriate code
1605
- if result["status"] == "success":
1888
+ if result["status"] == OperationResult.SUCCESS:
1606
1889
  sys.exit(0)
1607
1890
  else:
1608
1891
  sys.exit(1)
@@ -1615,5 +1898,111 @@ def mpm_init(
1615
1898
  sys.exit(1)
1616
1899
 
1617
1900
 
1901
+ @mpm_init.command(name="context")
1902
+ @click.option(
1903
+ "--session-id",
1904
+ "-i",
1905
+ type=str,
1906
+ help="Unused (for compatibility) - will be removed in future version",
1907
+ )
1908
+ @click.option(
1909
+ "--days",
1910
+ type=int,
1911
+ default=7,
1912
+ help="Number of days of git history to analyze (default: 7)",
1913
+ )
1914
+ @click.argument(
1915
+ "project_path",
1916
+ type=click.Path(exists=True, file_okay=False, dir_okay=True),
1917
+ required=False,
1918
+ default=".",
1919
+ )
1920
+ def context_command(session_id, days, project_path):
1921
+ """
1922
+ Provide intelligent context for resuming work based on git history.
1923
+
1924
+ Analyzes recent git history and generates a Research agent delegation
1925
+ prompt for intelligent project context reconstruction.
1926
+
1927
+ Examples:
1928
+ claude-mpm mpm-init context # Analyze last 7 days
1929
+ claude-mpm mpm-init context --days 14 # Analyze last 14 days
1930
+ claude-mpm mpm-init context --days 30 # Analyze last 30 days
1931
+
1932
+ Note: 'resume' is deprecated, use 'context' instead.
1933
+ """
1934
+ try:
1935
+ command = MPMInitCommand(Path(project_path))
1936
+
1937
+ result = command.handle_context(session_id=session_id, days=days)
1938
+
1939
+ if (
1940
+ result["status"] == OperationResult.SUCCESS
1941
+ or result["status"] == OperationResult.CONTEXT_READY
1942
+ ):
1943
+ sys.exit(0)
1944
+ else:
1945
+ sys.exit(1)
1946
+
1947
+ except KeyboardInterrupt:
1948
+ console.print("\n[yellow]Context analysis cancelled by user[/yellow]")
1949
+ sys.exit(130)
1950
+ except Exception as e:
1951
+ console.print(f"[red]Context analysis failed: {e}[/red]")
1952
+ sys.exit(1)
1953
+
1954
+
1955
+ # Add deprecated 'resume' alias for backward compatibility
1956
+ @mpm_init.command(name="resume", hidden=True)
1957
+ @click.option(
1958
+ "--session-id",
1959
+ "-i",
1960
+ type=str,
1961
+ help="Unused (for compatibility) - will be removed in future version",
1962
+ )
1963
+ @click.option(
1964
+ "--days",
1965
+ type=int,
1966
+ default=7,
1967
+ help="Number of days of git history to analyze (default: 7)",
1968
+ )
1969
+ @click.argument(
1970
+ "project_path",
1971
+ type=click.Path(exists=True, file_okay=False, dir_okay=True),
1972
+ required=False,
1973
+ default=".",
1974
+ )
1975
+ def resume_session(session_id, days, project_path):
1976
+ """
1977
+ [DEPRECATED] Use 'context' instead.
1978
+
1979
+ This command is deprecated and will be removed in a future version.
1980
+ Please use 'claude-mpm mpm-init context' instead.
1981
+ """
1982
+ console.print(
1983
+ "[yellow]⚠️ Warning: 'resume' is deprecated. Use 'context' instead.[/yellow]"
1984
+ )
1985
+ console.print("[dim]Run: claude-mpm mpm-init context[/dim]\n")
1986
+
1987
+ try:
1988
+ command = MPMInitCommand(Path(project_path))
1989
+ result = command.handle_context(session_id=session_id, days=days)
1990
+
1991
+ if (
1992
+ result["status"] == OperationResult.SUCCESS
1993
+ or result["status"] == OperationResult.CONTEXT_READY
1994
+ ):
1995
+ sys.exit(0)
1996
+ else:
1997
+ sys.exit(1)
1998
+
1999
+ except KeyboardInterrupt:
2000
+ console.print("\n[yellow]Context analysis cancelled by user[/yellow]")
2001
+ sys.exit(130)
2002
+ except Exception as e:
2003
+ console.print(f"[red]Context analysis failed: {e}[/red]")
2004
+ sys.exit(1)
2005
+
2006
+
1618
2007
  # Export for CLI registration
1619
2008
  __all__ = ["mpm_init"]