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.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/BASE_AGENT_TEMPLATE.md +118 -0
- claude_mpm/agents/BASE_ENGINEER.md +286 -0
- claude_mpm/agents/BASE_PM.md +106 -1
- claude_mpm/agents/OUTPUT_STYLE.md +329 -11
- claude_mpm/agents/PM_INSTRUCTIONS.md +397 -459
- claude_mpm/agents/agent_loader.py +17 -5
- claude_mpm/agents/frontmatter_validator.py +284 -253
- claude_mpm/agents/templates/README.md +465 -0
- claude_mpm/agents/templates/agent-manager.json +4 -1
- claude_mpm/agents/templates/agentic-coder-optimizer.json +13 -3
- claude_mpm/agents/templates/api_qa.json +11 -2
- claude_mpm/agents/templates/circuit_breakers.md +638 -0
- claude_mpm/agents/templates/clerk-ops.json +12 -2
- claude_mpm/agents/templates/code_analyzer.json +8 -2
- claude_mpm/agents/templates/content-agent.json +358 -0
- claude_mpm/agents/templates/dart_engineer.json +15 -2
- claude_mpm/agents/templates/data_engineer.json +15 -2
- claude_mpm/agents/templates/documentation.json +10 -2
- claude_mpm/agents/templates/engineer.json +21 -1
- claude_mpm/agents/templates/gcp_ops_agent.json +12 -2
- claude_mpm/agents/templates/git_file_tracking.md +584 -0
- claude_mpm/agents/templates/golang_engineer.json +270 -0
- claude_mpm/agents/templates/imagemagick.json +4 -1
- claude_mpm/agents/templates/java_engineer.json +346 -0
- claude_mpm/agents/templates/local_ops_agent.json +1227 -6
- claude_mpm/agents/templates/memory_manager.json +4 -1
- claude_mpm/agents/templates/nextjs_engineer.json +141 -133
- claude_mpm/agents/templates/ops.json +12 -2
- claude_mpm/agents/templates/php-engineer.json +270 -174
- claude_mpm/agents/templates/pm_examples.md +474 -0
- claude_mpm/agents/templates/pm_red_flags.md +240 -0
- claude_mpm/agents/templates/product_owner.json +338 -0
- claude_mpm/agents/templates/project_organizer.json +14 -4
- claude_mpm/agents/templates/prompt-engineer.json +13 -2
- claude_mpm/agents/templates/python_engineer.json +174 -81
- claude_mpm/agents/templates/qa.json +11 -2
- claude_mpm/agents/templates/react_engineer.json +16 -3
- claude_mpm/agents/templates/refactoring_engineer.json +12 -2
- claude_mpm/agents/templates/research.json +34 -21
- claude_mpm/agents/templates/response_format.md +583 -0
- claude_mpm/agents/templates/ruby-engineer.json +129 -192
- claude_mpm/agents/templates/rust_engineer.json +270 -0
- claude_mpm/agents/templates/security.json +10 -2
- claude_mpm/agents/templates/svelte-engineer.json +225 -0
- claude_mpm/agents/templates/ticketing.json +10 -2
- claude_mpm/agents/templates/typescript_engineer.json +116 -125
- claude_mpm/agents/templates/validation_templates.md +312 -0
- claude_mpm/agents/templates/vercel_ops_agent.json +12 -2
- claude_mpm/agents/templates/version_control.json +12 -2
- claude_mpm/agents/templates/web_qa.json +11 -2
- claude_mpm/agents/templates/web_ui.json +15 -2
- claude_mpm/cli/__init__.py +34 -614
- claude_mpm/cli/commands/agent_manager.py +25 -12
- claude_mpm/cli/commands/agent_state_manager.py +186 -0
- claude_mpm/cli/commands/agents.py +235 -148
- claude_mpm/cli/commands/agents_detect.py +380 -0
- claude_mpm/cli/commands/agents_recommend.py +309 -0
- claude_mpm/cli/commands/aggregate.py +7 -3
- claude_mpm/cli/commands/analyze.py +9 -4
- claude_mpm/cli/commands/analyze_code.py +7 -2
- claude_mpm/cli/commands/auto_configure.py +570 -0
- claude_mpm/cli/commands/config.py +47 -13
- claude_mpm/cli/commands/configure.py +419 -1571
- claude_mpm/cli/commands/configure_agent_display.py +261 -0
- claude_mpm/cli/commands/configure_behavior_manager.py +204 -0
- claude_mpm/cli/commands/configure_hook_manager.py +225 -0
- claude_mpm/cli/commands/configure_models.py +18 -0
- claude_mpm/cli/commands/configure_navigation.py +167 -0
- claude_mpm/cli/commands/configure_paths.py +104 -0
- claude_mpm/cli/commands/configure_persistence.py +254 -0
- claude_mpm/cli/commands/configure_startup_manager.py +646 -0
- claude_mpm/cli/commands/configure_template_editor.py +497 -0
- claude_mpm/cli/commands/configure_validators.py +73 -0
- claude_mpm/cli/commands/local_deploy.py +537 -0
- claude_mpm/cli/commands/memory.py +54 -20
- claude_mpm/cli/commands/mpm_init.py +585 -196
- claude_mpm/cli/commands/mpm_init_handler.py +37 -3
- claude_mpm/cli/commands/search.py +170 -4
- claude_mpm/cli/commands/upgrade.py +152 -0
- claude_mpm/cli/executor.py +202 -0
- claude_mpm/cli/helpers.py +105 -0
- claude_mpm/cli/interactive/__init__.py +3 -0
- claude_mpm/cli/interactive/skills_wizard.py +491 -0
- claude_mpm/cli/parsers/__init__.py +7 -1
- claude_mpm/cli/parsers/agents_parser.py +9 -0
- claude_mpm/cli/parsers/auto_configure_parser.py +245 -0
- claude_mpm/cli/parsers/base_parser.py +110 -3
- claude_mpm/cli/parsers/local_deploy_parser.py +227 -0
- claude_mpm/cli/parsers/mpm_init_parser.py +65 -5
- claude_mpm/cli/shared/output_formatters.py +28 -19
- claude_mpm/cli/startup.py +481 -0
- claude_mpm/cli/utils.py +52 -1
- claude_mpm/commands/mpm-agents-detect.md +168 -0
- claude_mpm/commands/mpm-agents-recommend.md +214 -0
- claude_mpm/commands/mpm-agents.md +75 -1
- claude_mpm/commands/mpm-auto-configure.md +217 -0
- claude_mpm/commands/mpm-help.md +163 -0
- claude_mpm/commands/mpm-init.md +148 -3
- claude_mpm/commands/mpm-version.md +113 -0
- claude_mpm/commands/mpm.md +1 -0
- claude_mpm/config/agent_config.py +2 -2
- claude_mpm/config/model_config.py +428 -0
- claude_mpm/constants.py +1 -0
- claude_mpm/core/base_service.py +13 -12
- claude_mpm/core/enums.py +452 -0
- claude_mpm/core/factories.py +1 -1
- claude_mpm/core/instruction_reinforcement_hook.py +2 -1
- claude_mpm/core/interactive_session.py +9 -3
- claude_mpm/core/log_manager.py +2 -0
- claude_mpm/core/logging_config.py +6 -2
- claude_mpm/core/oneshot_session.py +8 -4
- claude_mpm/core/optimized_agent_loader.py +3 -3
- claude_mpm/core/output_style_manager.py +12 -192
- claude_mpm/core/service_registry.py +5 -1
- claude_mpm/core/types.py +2 -9
- claude_mpm/core/typing_utils.py +7 -6
- claude_mpm/dashboard/static/js/dashboard.js +0 -14
- claude_mpm/dashboard/templates/index.html +3 -41
- claude_mpm/hooks/__init__.py +20 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +4 -2
- claude_mpm/hooks/claude_hooks/response_tracking.py +35 -1
- claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +23 -2
- claude_mpm/hooks/failure_learning/__init__.py +60 -0
- claude_mpm/hooks/failure_learning/failure_detection_hook.py +235 -0
- claude_mpm/hooks/failure_learning/fix_detection_hook.py +217 -0
- claude_mpm/hooks/failure_learning/learning_extraction_hook.py +286 -0
- claude_mpm/hooks/instruction_reinforcement.py +7 -2
- claude_mpm/hooks/kuzu_enrichment_hook.py +263 -0
- claude_mpm/hooks/kuzu_memory_hook.py +37 -12
- claude_mpm/hooks/kuzu_response_hook.py +183 -0
- claude_mpm/models/resume_log.py +340 -0
- claude_mpm/services/agents/__init__.py +18 -5
- claude_mpm/services/agents/auto_config_manager.py +796 -0
- claude_mpm/services/agents/deployment/agent_configuration_manager.py +1 -1
- claude_mpm/services/agents/deployment/agent_record_service.py +1 -1
- claude_mpm/services/agents/deployment/agent_validator.py +17 -1
- claude_mpm/services/agents/deployment/async_agent_deployment.py +1 -1
- claude_mpm/services/agents/deployment/interface_adapter.py +3 -2
- claude_mpm/services/agents/deployment/local_template_deployment.py +1 -1
- claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +7 -6
- claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +7 -16
- claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +4 -3
- claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +5 -3
- claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +6 -5
- claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +9 -6
- claude_mpm/services/agents/deployment/validation/__init__.py +3 -1
- claude_mpm/services/agents/deployment/validation/validation_result.py +1 -9
- claude_mpm/services/agents/local_template_manager.py +1 -1
- claude_mpm/services/agents/memory/agent_memory_manager.py +5 -2
- claude_mpm/services/agents/observers.py +547 -0
- claude_mpm/services/agents/recommender.py +568 -0
- claude_mpm/services/agents/registry/modification_tracker.py +5 -2
- claude_mpm/services/command_handler_service.py +11 -5
- claude_mpm/services/core/__init__.py +33 -1
- claude_mpm/services/core/interfaces/__init__.py +90 -3
- claude_mpm/services/core/interfaces/agent.py +184 -0
- claude_mpm/services/core/interfaces/health.py +172 -0
- claude_mpm/services/core/interfaces/model.py +281 -0
- claude_mpm/services/core/interfaces/process.py +372 -0
- claude_mpm/services/core/interfaces/project.py +121 -0
- claude_mpm/services/core/interfaces/restart.py +307 -0
- claude_mpm/services/core/interfaces/stability.py +260 -0
- claude_mpm/services/core/memory_manager.py +11 -24
- claude_mpm/services/core/models/__init__.py +79 -0
- claude_mpm/services/core/models/agent_config.py +381 -0
- claude_mpm/services/core/models/health.py +162 -0
- claude_mpm/services/core/models/process.py +235 -0
- claude_mpm/services/core/models/restart.py +302 -0
- claude_mpm/services/core/models/stability.py +264 -0
- claude_mpm/services/core/models/toolchain.py +306 -0
- claude_mpm/services/core/path_resolver.py +23 -7
- claude_mpm/services/diagnostics/__init__.py +2 -2
- claude_mpm/services/diagnostics/checks/agent_check.py +25 -24
- claude_mpm/services/diagnostics/checks/claude_code_check.py +24 -23
- claude_mpm/services/diagnostics/checks/common_issues_check.py +25 -24
- claude_mpm/services/diagnostics/checks/configuration_check.py +24 -23
- claude_mpm/services/diagnostics/checks/filesystem_check.py +18 -17
- claude_mpm/services/diagnostics/checks/installation_check.py +30 -29
- claude_mpm/services/diagnostics/checks/instructions_check.py +20 -19
- claude_mpm/services/diagnostics/checks/mcp_check.py +50 -36
- claude_mpm/services/diagnostics/checks/mcp_services_check.py +38 -33
- claude_mpm/services/diagnostics/checks/monitor_check.py +23 -22
- claude_mpm/services/diagnostics/checks/startup_log_check.py +9 -8
- claude_mpm/services/diagnostics/diagnostic_runner.py +6 -5
- claude_mpm/services/diagnostics/doctor_reporter.py +28 -25
- claude_mpm/services/diagnostics/models.py +19 -24
- claude_mpm/services/infrastructure/monitoring/__init__.py +1 -1
- claude_mpm/services/infrastructure/monitoring/aggregator.py +12 -12
- claude_mpm/services/infrastructure/monitoring/base.py +5 -13
- claude_mpm/services/infrastructure/monitoring/network.py +7 -6
- claude_mpm/services/infrastructure/monitoring/process.py +13 -12
- claude_mpm/services/infrastructure/monitoring/resources.py +7 -6
- claude_mpm/services/infrastructure/monitoring/service.py +16 -15
- claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
- claude_mpm/services/local_ops/__init__.py +163 -0
- claude_mpm/services/local_ops/crash_detector.py +257 -0
- claude_mpm/services/local_ops/health_checks/__init__.py +28 -0
- claude_mpm/services/local_ops/health_checks/http_check.py +224 -0
- claude_mpm/services/local_ops/health_checks/process_check.py +236 -0
- claude_mpm/services/local_ops/health_checks/resource_check.py +255 -0
- claude_mpm/services/local_ops/health_manager.py +430 -0
- claude_mpm/services/local_ops/log_monitor.py +396 -0
- claude_mpm/services/local_ops/memory_leak_detector.py +294 -0
- claude_mpm/services/local_ops/process_manager.py +595 -0
- claude_mpm/services/local_ops/resource_monitor.py +331 -0
- claude_mpm/services/local_ops/restart_manager.py +401 -0
- claude_mpm/services/local_ops/restart_policy.py +387 -0
- claude_mpm/services/local_ops/state_manager.py +372 -0
- claude_mpm/services/local_ops/unified_manager.py +600 -0
- claude_mpm/services/mcp_config_manager.py +9 -4
- claude_mpm/services/mcp_gateway/core/__init__.py +1 -2
- claude_mpm/services/mcp_gateway/core/base.py +18 -31
- claude_mpm/services/mcp_gateway/main.py +30 -0
- claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +206 -32
- claude_mpm/services/mcp_gateway/tools/health_check_tool.py +30 -28
- claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +25 -5
- claude_mpm/services/mcp_service_verifier.py +1 -1
- claude_mpm/services/memory/failure_tracker.py +563 -0
- claude_mpm/services/memory_hook_service.py +165 -4
- claude_mpm/services/model/__init__.py +147 -0
- claude_mpm/services/model/base_provider.py +365 -0
- claude_mpm/services/model/claude_provider.py +412 -0
- claude_mpm/services/model/model_router.py +453 -0
- claude_mpm/services/model/ollama_provider.py +415 -0
- claude_mpm/services/monitor/daemon_manager.py +3 -2
- claude_mpm/services/monitor/handlers/dashboard.py +2 -1
- claude_mpm/services/monitor/handlers/hooks.py +2 -1
- claude_mpm/services/monitor/management/lifecycle.py +3 -2
- claude_mpm/services/monitor/server.py +2 -1
- claude_mpm/services/project/__init__.py +23 -0
- claude_mpm/services/project/detection_strategies.py +719 -0
- claude_mpm/services/project/toolchain_analyzer.py +581 -0
- claude_mpm/services/self_upgrade_service.py +342 -0
- claude_mpm/services/session_management_service.py +3 -2
- claude_mpm/services/session_manager.py +205 -1
- claude_mpm/services/shared/async_service_base.py +16 -27
- claude_mpm/services/shared/lifecycle_service_base.py +1 -14
- claude_mpm/services/socketio/handlers/__init__.py +5 -2
- claude_mpm/services/socketio/handlers/hook.py +13 -2
- claude_mpm/services/socketio/handlers/registry.py +4 -2
- claude_mpm/services/socketio/server/main.py +10 -8
- claude_mpm/services/subprocess_launcher_service.py +14 -5
- claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +8 -7
- claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +6 -5
- claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +8 -7
- claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +7 -6
- claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +5 -4
- claude_mpm/services/unified/config_strategies/validation_strategy.py +13 -9
- claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +10 -3
- claude_mpm/services/unified/deployment_strategies/local.py +6 -5
- claude_mpm/services/unified/deployment_strategies/utils.py +6 -5
- claude_mpm/services/unified/deployment_strategies/vercel.py +7 -6
- claude_mpm/services/unified/interfaces.py +3 -1
- claude_mpm/services/unified/unified_analyzer.py +14 -10
- claude_mpm/services/unified/unified_config.py +2 -1
- claude_mpm/services/unified/unified_deployment.py +9 -4
- claude_mpm/services/version_service.py +104 -1
- claude_mpm/skills/__init__.py +21 -0
- claude_mpm/skills/bundled/__init__.py +6 -0
- claude_mpm/skills/bundled/api-documentation.md +393 -0
- claude_mpm/skills/bundled/async-testing.md +571 -0
- claude_mpm/skills/bundled/code-review.md +143 -0
- claude_mpm/skills/bundled/database-migration.md +199 -0
- claude_mpm/skills/bundled/docker-containerization.md +194 -0
- claude_mpm/skills/bundled/express-local-dev.md +1429 -0
- claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
- claude_mpm/skills/bundled/git-workflow.md +414 -0
- claude_mpm/skills/bundled/imagemagick.md +204 -0
- claude_mpm/skills/bundled/json-data-handling.md +223 -0
- claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
- claude_mpm/skills/bundled/pdf.md +141 -0
- claude_mpm/skills/bundled/performance-profiling.md +567 -0
- claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
- claude_mpm/skills/bundled/security-scanning.md +327 -0
- claude_mpm/skills/bundled/systematic-debugging.md +473 -0
- claude_mpm/skills/bundled/test-driven-development.md +378 -0
- claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
- claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
- claude_mpm/skills/bundled/xlsx.md +157 -0
- claude_mpm/skills/registry.py +286 -0
- claude_mpm/skills/skill_manager.py +310 -0
- claude_mpm/storage/state_storage.py +15 -15
- claude_mpm/tools/code_tree_analyzer.py +177 -141
- claude_mpm/tools/code_tree_events.py +4 -2
- claude_mpm/utils/agent_dependency_loader.py +40 -20
- claude_mpm/utils/display_helper.py +260 -0
- claude_mpm/utils/git_analyzer.py +407 -0
- claude_mpm/utils/robust_installer.py +73 -19
- {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/METADATA +129 -12
- {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/RECORD +295 -193
- claude_mpm/dashboard/static/css/code-tree.css +0 -1639
- claude_mpm/dashboard/static/index-hub-backup.html +0 -713
- claude_mpm/dashboard/static/js/components/code-tree/tree-breadcrumb.js +0 -353
- claude_mpm/dashboard/static/js/components/code-tree/tree-constants.js +0 -235
- claude_mpm/dashboard/static/js/components/code-tree/tree-search.js +0 -409
- claude_mpm/dashboard/static/js/components/code-tree/tree-utils.js +0 -435
- claude_mpm/dashboard/static/js/components/code-tree.js +0 -5869
- claude_mpm/dashboard/static/js/components/code-viewer.js +0 -1386
- claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +0 -425
- claude_mpm/hooks/claude_hooks/hook_handler_original.py +0 -1041
- claude_mpm/hooks/claude_hooks/hook_handler_refactored.py +0 -347
- claude_mpm/services/agents/deployment/agent_lifecycle_manager_refactored.py +0 -575
- claude_mpm/services/project/analyzer_refactored.py +0 -450
- {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/WHEEL +0 -0
- {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/licenses/LICENSE +0 -0
- {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":
|
|
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") ==
|
|
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") ==
|
|
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":
|
|
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
|
-
|
|
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":
|
|
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
|
-
|
|
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
|
-
|
|
535
|
-
console.print(f" Phase: {state.get('phase', 'unknown')}")
|
|
507
|
+
state_data = {"Phase": state.get("phase", "unknown")}
|
|
536
508
|
if state.get("indicators"):
|
|
537
|
-
|
|
538
|
-
|
|
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
|
-
|
|
543
|
-
|
|
544
|
-
|
|
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
|
-
|
|
547
|
-
|
|
548
|
-
|
|
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
|
-
|
|
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
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
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
|
-
|
|
575
|
-
|
|
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
|
-
|
|
585
|
-
for rec in state["recommendations"][:5]:
|
|
586
|
-
console.print(f" → {rec}")
|
|
560
|
+
self.display.display_recommendations(state["recommendations"])
|
|
587
561
|
|
|
588
|
-
|
|
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":
|
|
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":
|
|
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":
|
|
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":
|
|
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":
|
|
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 {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
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
|
-
|
|
944
|
-
for rec in recommendations:
|
|
945
|
-
console.print(f" → {rec}")
|
|
1037
|
+
self.display.display_recommendations(recommendations)
|
|
946
1038
|
|
|
947
|
-
|
|
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":
|
|
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":
|
|
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
|
|
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":
|
|
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":
|
|
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":
|
|
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":
|
|
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"] ==
|
|
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
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
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
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
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
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
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.
|
|
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"] ==
|
|
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"]
|