claude-mpm 4.15.6__py3-none-any.whl ā 4.21.0__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.
Potentially problematic release.
This version of claude-mpm might be problematic. Click here for more details.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/BASE_ENGINEER.md +286 -0
- claude_mpm/agents/BASE_PM.md +272 -23
- claude_mpm/agents/PM_INSTRUCTIONS.md +49 -0
- claude_mpm/agents/agent_loader.py +4 -4
- claude_mpm/agents/templates/engineer.json +5 -1
- claude_mpm/agents/templates/php-engineer.json +10 -4
- claude_mpm/agents/templates/python_engineer.json +8 -3
- claude_mpm/agents/templates/rust_engineer.json +12 -7
- claude_mpm/agents/templates/svelte-engineer.json +225 -0
- claude_mpm/cli/commands/__init__.py +2 -0
- claude_mpm/cli/commands/mpm_init/__init__.py +73 -0
- claude_mpm/cli/commands/mpm_init/core.py +525 -0
- claude_mpm/cli/commands/mpm_init/display.py +341 -0
- claude_mpm/cli/commands/mpm_init/git_activity.py +427 -0
- claude_mpm/cli/commands/mpm_init/modes.py +397 -0
- claude_mpm/cli/commands/mpm_init/prompts.py +442 -0
- claude_mpm/cli/commands/mpm_init_cli.py +396 -0
- claude_mpm/cli/commands/mpm_init_handler.py +67 -1
- claude_mpm/cli/commands/skills.py +488 -0
- claude_mpm/cli/executor.py +2 -0
- claude_mpm/cli/parsers/base_parser.py +7 -0
- claude_mpm/cli/parsers/mpm_init_parser.py +42 -0
- claude_mpm/cli/parsers/skills_parser.py +137 -0
- claude_mpm/cli/startup.py +57 -0
- claude_mpm/commands/mpm-auto-configure.md +52 -0
- claude_mpm/commands/mpm-help.md +3 -0
- claude_mpm/commands/mpm-init.md +112 -6
- 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/constants.py +12 -0
- claude_mpm/core/config.py +42 -0
- claude_mpm/core/factories.py +1 -1
- claude_mpm/core/interfaces.py +56 -1
- claude_mpm/core/optimized_agent_loader.py +3 -3
- claude_mpm/hooks/__init__.py +8 -0
- claude_mpm/hooks/claude_hooks/response_tracking.py +35 -1
- claude_mpm/hooks/session_resume_hook.py +121 -0
- claude_mpm/models/resume_log.py +340 -0
- claude_mpm/services/agents/auto_config_manager.py +1 -1
- 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/local_template_deployment.py +1 -1
- claude_mpm/services/agents/local_template_manager.py +1 -1
- claude_mpm/services/agents/recommender.py +47 -0
- claude_mpm/services/cli/resume_service.py +617 -0
- claude_mpm/services/cli/session_manager.py +87 -0
- claude_mpm/services/cli/session_pause_manager.py +504 -0
- claude_mpm/services/cli/session_resume_helper.py +372 -0
- claude_mpm/services/core/interfaces.py +56 -1
- claude_mpm/services/core/models/agent_config.py +3 -0
- claude_mpm/services/core/models/process.py +4 -0
- claude_mpm/services/core/path_resolver.py +1 -1
- claude_mpm/services/diagnostics/models.py +21 -0
- claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
- claude_mpm/services/local_ops/__init__.py +2 -0
- claude_mpm/services/mcp_config_manager.py +7 -131
- claude_mpm/services/mcp_gateway/auto_configure.py +31 -25
- claude_mpm/services/mcp_gateway/core/process_pool.py +19 -10
- claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +26 -21
- claude_mpm/services/session_manager.py +205 -1
- claude_mpm/services/unified/deployment_strategies/local.py +1 -1
- claude_mpm/services/version_service.py +104 -1
- claude_mpm/skills/__init__.py +21 -0
- claude_mpm/skills/agent_skills_injector.py +324 -0
- claude_mpm/skills/bundled/LICENSE_ATTRIBUTIONS.md +79 -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/collaboration/brainstorming/SKILL.md +79 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
- claude_mpm/skills/bundled/database-migration.md +199 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -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/main/artifacts-builder/SKILL.md +86 -0
- claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
- claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
- claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +157 -0
- claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +425 -0
- claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
- claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
- claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
- claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
- claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
- claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +303 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +113 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +72 -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/php/espocrm-development/SKILL.md +170 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
- claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
- claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -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/testing/condition-based-waiting/SKILL.md +119 -0
- claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
- claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
- claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
- claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +35 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +44 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +34 -0
- claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
- claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
- claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +129 -0
- claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
- claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -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 +97 -9
- claude_mpm/skills/skills_registry.py +348 -0
- claude_mpm/skills/skills_service.py +739 -0
- claude_mpm/utils/agent_dependency_loader.py +2 -2
- {claude_mpm-4.15.6.dist-info ā claude_mpm-4.21.0.dist-info}/METADATA +211 -33
- {claude_mpm-4.15.6.dist-info ā claude_mpm-4.21.0.dist-info}/RECORD +192 -60
- claude_mpm/agents/INSTRUCTIONS_OLD_DEPRECATED.md +0 -602
- claude_mpm/cli/commands/mpm_init.py +0 -2008
- {claude_mpm-4.15.6.dist-info ā claude_mpm-4.21.0.dist-info}/WHEEL +0 -0
- {claude_mpm-4.15.6.dist-info ā claude_mpm-4.21.0.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.15.6.dist-info ā claude_mpm-4.21.0.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.15.6.dist-info ā claude_mpm-4.21.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
"""Git analysis and activity tracking functions.
|
|
2
|
+
|
|
3
|
+
This module provides utilities for analyzing git repository activity,
|
|
4
|
+
including commit analysis, file change tracking, and contributor statistics.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import subprocess
|
|
8
|
+
from collections import Counter
|
|
9
|
+
from datetime import datetime, timezone
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from typing import Any, Dict, Optional
|
|
12
|
+
|
|
13
|
+
from rich.console import Console
|
|
14
|
+
|
|
15
|
+
from claude_mpm.core.enums import OperationResult
|
|
16
|
+
|
|
17
|
+
from . import prompts
|
|
18
|
+
|
|
19
|
+
console = Console()
|
|
20
|
+
|
|
21
|
+
__all__ = [
|
|
22
|
+
"append_activity_notes",
|
|
23
|
+
"catchup",
|
|
24
|
+
"export_activity_report",
|
|
25
|
+
"generate_activity_report",
|
|
26
|
+
"handle_context",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def catchup(project_path: Path) -> Dict[str, Any]:
|
|
31
|
+
"""Get recent commit history for PM context.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
project_path: Path to the project directory
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
Dict containing commit history and contributor stats
|
|
38
|
+
"""
|
|
39
|
+
try:
|
|
40
|
+
# Get last 25 commits from all branches with author info
|
|
41
|
+
result = subprocess.run(
|
|
42
|
+
["git", "log", "--all", "--format=%h|%an|%ai|%s", "-25"],
|
|
43
|
+
capture_output=True,
|
|
44
|
+
text=True,
|
|
45
|
+
check=True,
|
|
46
|
+
cwd=str(project_path),
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
commits = []
|
|
50
|
+
authors = []
|
|
51
|
+
|
|
52
|
+
for line in result.stdout.strip().split("\n"):
|
|
53
|
+
if not line:
|
|
54
|
+
continue
|
|
55
|
+
|
|
56
|
+
parts = line.split("|", 3)
|
|
57
|
+
if len(parts) == 4:
|
|
58
|
+
hash_val, author, date_str, message = parts
|
|
59
|
+
|
|
60
|
+
# Parse date
|
|
61
|
+
try:
|
|
62
|
+
dt = datetime.fromisoformat(date_str.replace(" ", "T", 1))
|
|
63
|
+
date_display = dt.strftime("%Y-%m-%d %H:%M")
|
|
64
|
+
except Exception:
|
|
65
|
+
date_display = date_str[:16]
|
|
66
|
+
|
|
67
|
+
commits.append(
|
|
68
|
+
{
|
|
69
|
+
"hash": hash_val,
|
|
70
|
+
"author": author,
|
|
71
|
+
"date": date_display,
|
|
72
|
+
"message": message,
|
|
73
|
+
}
|
|
74
|
+
)
|
|
75
|
+
authors.append(author)
|
|
76
|
+
|
|
77
|
+
# Calculate contributor stats
|
|
78
|
+
author_counts = Counter(authors)
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
"commits": commits,
|
|
82
|
+
"total_commits": len(commits),
|
|
83
|
+
"contributors": dict(author_counts),
|
|
84
|
+
"contributor_count": len(author_counts),
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
except Exception as e:
|
|
88
|
+
console.print(f"[yellow]Could not retrieve commit history: {e}[/yellow]")
|
|
89
|
+
return {
|
|
90
|
+
"commits": [],
|
|
91
|
+
"total_commits": 0,
|
|
92
|
+
"contributors": {},
|
|
93
|
+
"contributor_count": 0,
|
|
94
|
+
"error": str(e),
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def generate_activity_report(
|
|
99
|
+
git_analysis: Dict, doc_analysis: Dict, days: int = 30
|
|
100
|
+
) -> Dict:
|
|
101
|
+
"""Generate activity report from git analysis and documentation status.
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
git_analysis: Git repository analysis data
|
|
105
|
+
doc_analysis: Documentation analysis data
|
|
106
|
+
days: Number of days to analyze (default: 30)
|
|
107
|
+
|
|
108
|
+
Returns:
|
|
109
|
+
Dict containing comprehensive activity report
|
|
110
|
+
"""
|
|
111
|
+
report = {
|
|
112
|
+
"period": f"Last {days} days",
|
|
113
|
+
"generated_at": datetime.now(timezone.utc).isoformat(),
|
|
114
|
+
"summary": {},
|
|
115
|
+
"recommendations": [],
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
# Git activity summary
|
|
119
|
+
if git_analysis.get("git_available"):
|
|
120
|
+
recent_commits = git_analysis.get("recent_commits", [])
|
|
121
|
+
changed_files = git_analysis.get("changed_files", {})
|
|
122
|
+
authors = git_analysis.get("authors", {})
|
|
123
|
+
branch_info = git_analysis.get("branch_info", {})
|
|
124
|
+
|
|
125
|
+
report["summary"] = {
|
|
126
|
+
"total_commits": len(recent_commits),
|
|
127
|
+
"total_authors": authors.get("total_authors", 0),
|
|
128
|
+
"files_changed": changed_files.get("total_files", 0),
|
|
129
|
+
"current_branch": branch_info.get("current_branch", "unknown"),
|
|
130
|
+
"has_uncommitted": branch_info.get("has_uncommitted_changes", False),
|
|
131
|
+
"uncommitted_count": branch_info.get("uncommitted_files", 0),
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
# Recent commits (last 10)
|
|
135
|
+
report["recent_commits"] = recent_commits[:10]
|
|
136
|
+
|
|
137
|
+
# Most changed files
|
|
138
|
+
most_changed = changed_files.get("most_changed", {})
|
|
139
|
+
report["hot_files"] = list(most_changed.items())[:10]
|
|
140
|
+
|
|
141
|
+
# Active branches
|
|
142
|
+
branches = branch_info.get("branches", [])
|
|
143
|
+
report["active_branches"] = [
|
|
144
|
+
b for b in branches if not b.startswith("remotes/")
|
|
145
|
+
][:5]
|
|
146
|
+
|
|
147
|
+
# Generate recommendations
|
|
148
|
+
if len(recent_commits) > 20:
|
|
149
|
+
report["recommendations"].append(
|
|
150
|
+
"High activity detected - consider updating architecture docs"
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
if changed_files.get("total_files", 0) > 50:
|
|
154
|
+
report["recommendations"].append(
|
|
155
|
+
"Many files changed - review CLAUDE.md for accuracy"
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
if branch_info.get("has_uncommitted_changes"):
|
|
159
|
+
report["recommendations"].append(
|
|
160
|
+
"Uncommitted changes detected - commit before updating docs"
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
# Check for documentation changes
|
|
164
|
+
doc_changes = git_analysis.get("documentation_changes", {})
|
|
165
|
+
if not doc_changes.get("has_recent_doc_changes"):
|
|
166
|
+
report["recommendations"].append(
|
|
167
|
+
"No recent doc updates - CLAUDE.md may be outdated"
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
# Documentation freshness
|
|
171
|
+
if doc_analysis.get("exists"):
|
|
172
|
+
report["doc_status"] = {
|
|
173
|
+
"size": doc_analysis.get("size", 0),
|
|
174
|
+
"lines": doc_analysis.get("lines", 0),
|
|
175
|
+
"has_priority_index": doc_analysis.get("has_priority_index", False),
|
|
176
|
+
"has_priority_markers": doc_analysis.get("has_priority_markers", False),
|
|
177
|
+
"last_modified": doc_analysis.get("last_modified", "unknown"),
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if not doc_analysis.get("has_priority_markers"):
|
|
181
|
+
report["recommendations"].append(
|
|
182
|
+
"Add priority markers (š“š”š¢āŖ) to CLAUDE.md"
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
return report
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def export_activity_report(project_path: Path, report: Dict, export_path: str) -> Path:
|
|
189
|
+
"""Export activity report to a markdown file.
|
|
190
|
+
|
|
191
|
+
Args:
|
|
192
|
+
project_path: Path to the project directory
|
|
193
|
+
report: Activity report data
|
|
194
|
+
export_path: Path to export file ("auto" or specific path)
|
|
195
|
+
|
|
196
|
+
Returns:
|
|
197
|
+
Path to the exported file
|
|
198
|
+
"""
|
|
199
|
+
# Determine export path
|
|
200
|
+
if export_path == "auto":
|
|
201
|
+
# Generate default path with timestamp
|
|
202
|
+
timestamp = datetime.now(timezone.utc).strftime("%Y%m%d-%H%M%S")
|
|
203
|
+
reports_dir = project_path / "docs" / "reports"
|
|
204
|
+
reports_dir.mkdir(parents=True, exist_ok=True)
|
|
205
|
+
file_path = reports_dir / f"activity-report-{timestamp}.md"
|
|
206
|
+
else:
|
|
207
|
+
# Use provided path
|
|
208
|
+
file_path = Path(export_path)
|
|
209
|
+
if not file_path.is_absolute():
|
|
210
|
+
file_path = project_path / file_path
|
|
211
|
+
# Create parent directory if needed
|
|
212
|
+
file_path.parent.mkdir(parents=True, exist_ok=True)
|
|
213
|
+
|
|
214
|
+
# Generate markdown content
|
|
215
|
+
summary = report.get("summary", {})
|
|
216
|
+
timestamp = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S")
|
|
217
|
+
|
|
218
|
+
content = f"""# Activity Report
|
|
219
|
+
|
|
220
|
+
**Generated**: {timestamp}
|
|
221
|
+
**Analysis Period**: {report.get('period', 'Last 30 days')}
|
|
222
|
+
|
|
223
|
+
## Summary
|
|
224
|
+
|
|
225
|
+
- **Total Commits**: {summary.get('total_commits', 0)}
|
|
226
|
+
- **Active Contributors**: {summary.get('total_authors', 0)}
|
|
227
|
+
- **Files Modified**: {summary.get('files_changed', 0)}
|
|
228
|
+
- **Current Branch**: {summary.get('current_branch', 'unknown')}
|
|
229
|
+
"""
|
|
230
|
+
|
|
231
|
+
if summary.get("has_uncommitted"):
|
|
232
|
+
content += f"- **ā ļø Uncommitted Changes**: {summary.get('uncommitted_count', 0)} files\n"
|
|
233
|
+
|
|
234
|
+
# Recent commits
|
|
235
|
+
recent_commits = report.get("recent_commits", [])
|
|
236
|
+
if recent_commits:
|
|
237
|
+
content += "\n## Recent Commits\n\n"
|
|
238
|
+
for commit in recent_commits[:10]:
|
|
239
|
+
content += (
|
|
240
|
+
f"- `{commit['hash']}` {commit['message']} - {commit['author']}\n"
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
# Hot files
|
|
244
|
+
hot_files = report.get("hot_files", [])
|
|
245
|
+
if hot_files:
|
|
246
|
+
content += "\n## Most Changed Files\n\n"
|
|
247
|
+
for hot_file_path, changes in hot_files[:10]:
|
|
248
|
+
content += f"- `{hot_file_path}`: {changes} changes\n"
|
|
249
|
+
|
|
250
|
+
# Active branches
|
|
251
|
+
branches = report.get("active_branches", [])
|
|
252
|
+
if branches:
|
|
253
|
+
content += "\n## Active Branches\n\n"
|
|
254
|
+
for branch in branches:
|
|
255
|
+
marker = "ā" if branch == summary.get("current_branch") else " "
|
|
256
|
+
content += f"{marker} {branch}\n"
|
|
257
|
+
|
|
258
|
+
# Documentation status
|
|
259
|
+
doc_status = report.get("doc_status", {})
|
|
260
|
+
if doc_status:
|
|
261
|
+
content += "\n## CLAUDE.md Status\n\n"
|
|
262
|
+
content += f"- **Size**: {doc_status.get('size', 0):,} characters\n"
|
|
263
|
+
content += f"- **Lines**: {doc_status.get('lines', 0)}\n"
|
|
264
|
+
content += f"- **Priority Markers**: {'ā' if doc_status.get('has_priority_markers') else 'ā'}\n"
|
|
265
|
+
content += (
|
|
266
|
+
f"- **Last Modified**: {doc_status.get('last_modified', 'unknown')}\n"
|
|
267
|
+
)
|
|
268
|
+
|
|
269
|
+
# Recommendations
|
|
270
|
+
recommendations = report.get("recommendations", [])
|
|
271
|
+
if recommendations:
|
|
272
|
+
content += "\n## Recommendations\n\n"
|
|
273
|
+
for rec in recommendations:
|
|
274
|
+
content += f"- {rec}\n"
|
|
275
|
+
|
|
276
|
+
content += (
|
|
277
|
+
"\n---\n\n*Generated by Claude MPM `/mpm-init --quick-update --export`*\n"
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
# Write to file
|
|
281
|
+
file_path.write_text(content, encoding="utf-8")
|
|
282
|
+
|
|
283
|
+
return file_path
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
def append_activity_notes(claude_md_path: Path, report: Dict) -> None:
|
|
287
|
+
"""Append activity notes to CLAUDE.md.
|
|
288
|
+
|
|
289
|
+
Args:
|
|
290
|
+
claude_md_path: Path to CLAUDE.md file
|
|
291
|
+
report: Activity report data
|
|
292
|
+
"""
|
|
293
|
+
# Generate activity summary section
|
|
294
|
+
summary = report.get("summary", {})
|
|
295
|
+
timestamp = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S")
|
|
296
|
+
|
|
297
|
+
activity_section = f"""
|
|
298
|
+
|
|
299
|
+
---
|
|
300
|
+
|
|
301
|
+
## š Recent Activity Summary
|
|
302
|
+
|
|
303
|
+
**Last Updated**: {timestamp}
|
|
304
|
+
**Analysis Period**: {report.get('period', 'Last 30 days')}
|
|
305
|
+
|
|
306
|
+
### Activity Metrics
|
|
307
|
+
- **Commits**: {summary.get('total_commits', 0)}
|
|
308
|
+
- **Contributors**: {summary.get('total_authors', 0)}
|
|
309
|
+
- **Files Changed**: {summary.get('files_changed', 0)}
|
|
310
|
+
- **Current Branch**: {summary.get('current_branch', 'unknown')}
|
|
311
|
+
"""
|
|
312
|
+
|
|
313
|
+
if summary.get("has_uncommitted"):
|
|
314
|
+
activity_section += f"- **ā ļø Uncommitted Changes**: {summary.get('uncommitted_count', 0)} files\n"
|
|
315
|
+
|
|
316
|
+
# Add recent commits
|
|
317
|
+
recent_commits = report.get("recent_commits", [])
|
|
318
|
+
if recent_commits:
|
|
319
|
+
activity_section += "\n### Recent Commits\n"
|
|
320
|
+
for commit in recent_commits[:5]:
|
|
321
|
+
activity_section += (
|
|
322
|
+
f"- `{commit['hash']}` {commit['message'][:60]} ({commit['author']})\n"
|
|
323
|
+
)
|
|
324
|
+
|
|
325
|
+
# Add hot files
|
|
326
|
+
hot_files = report.get("hot_files", [])
|
|
327
|
+
if hot_files:
|
|
328
|
+
activity_section += "\n### Most Active Files\n"
|
|
329
|
+
for file_path, changes in hot_files[:5]:
|
|
330
|
+
activity_section += f"- `{file_path}`: {changes} changes\n"
|
|
331
|
+
|
|
332
|
+
# Add recommendations
|
|
333
|
+
recommendations = report.get("recommendations", [])
|
|
334
|
+
if recommendations:
|
|
335
|
+
activity_section += "\n### š” Recommendations\n"
|
|
336
|
+
for rec in recommendations:
|
|
337
|
+
activity_section += f"- {rec}\n"
|
|
338
|
+
|
|
339
|
+
activity_section += "\n---\n"
|
|
340
|
+
|
|
341
|
+
# Append to file
|
|
342
|
+
with open(claude_md_path, "a", encoding="utf-8") as f:
|
|
343
|
+
f.write(activity_section)
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
def handle_context(
|
|
347
|
+
project_path: Path,
|
|
348
|
+
session_id: Optional[str] = None,
|
|
349
|
+
list_sessions: bool = False,
|
|
350
|
+
days: int = 7,
|
|
351
|
+
) -> Dict[str, Any]:
|
|
352
|
+
"""Provide intelligent context for resuming work based on git history.
|
|
353
|
+
|
|
354
|
+
Analyzes recent commits to identify:
|
|
355
|
+
- Active work streams (what was being worked on)
|
|
356
|
+
- Intent and motivation (why this work)
|
|
357
|
+
- Risks and blockers
|
|
358
|
+
- Recommended next actions
|
|
359
|
+
|
|
360
|
+
This delegates to Research agent for deep analysis.
|
|
361
|
+
|
|
362
|
+
Args:
|
|
363
|
+
project_path: Path to the project directory
|
|
364
|
+
session_id: Unused parameter (for compatibility)
|
|
365
|
+
list_sessions: Unused parameter (for compatibility)
|
|
366
|
+
days: Number of days of git history to analyze (default: 7)
|
|
367
|
+
|
|
368
|
+
Returns:
|
|
369
|
+
Dict containing context result
|
|
370
|
+
"""
|
|
371
|
+
from claude_mpm.utils.git_analyzer import analyze_recent_activity
|
|
372
|
+
|
|
373
|
+
# 1. Analyze git history with adaptive window
|
|
374
|
+
console.print(f"\nš Analyzing last {days} days of git history...\n")
|
|
375
|
+
git_analysis = analyze_recent_activity(
|
|
376
|
+
repo_path=str(project_path), days=days, max_commits=50, min_commits=25
|
|
377
|
+
)
|
|
378
|
+
|
|
379
|
+
# Show adaptive behavior to user
|
|
380
|
+
if git_analysis.get("adaptive_mode"):
|
|
381
|
+
console.print(
|
|
382
|
+
f"[cyan]ā¹ļø Note: Analyzed {git_analysis.get('actual_time_span', 'extended period')} "
|
|
383
|
+
f"to get meaningful context[/cyan]"
|
|
384
|
+
)
|
|
385
|
+
if git_analysis.get("reason"):
|
|
386
|
+
console.print(f"[dim] Reason: {git_analysis['reason']}[/dim]\n")
|
|
387
|
+
else:
|
|
388
|
+
console.print()
|
|
389
|
+
|
|
390
|
+
if git_analysis.get("error"):
|
|
391
|
+
console.print(
|
|
392
|
+
f"[yellow]ā ļø Could not analyze git history: {git_analysis['error']}[/yellow]"
|
|
393
|
+
)
|
|
394
|
+
console.print(
|
|
395
|
+
"[dim]Ensure this is a git repository with commit history.[/dim]\n"
|
|
396
|
+
)
|
|
397
|
+
return {
|
|
398
|
+
"status": OperationResult.ERROR,
|
|
399
|
+
"message": git_analysis["error"],
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
if not git_analysis.get("has_activity"):
|
|
403
|
+
console.print(
|
|
404
|
+
f"[yellow]ā ļø No git activity found in the last {days} days.[/yellow]"
|
|
405
|
+
)
|
|
406
|
+
console.print("[dim]Try increasing the --days parameter.[/dim]\n")
|
|
407
|
+
return {
|
|
408
|
+
"status": OperationResult.ERROR,
|
|
409
|
+
"message": f"No git activity in last {days} days",
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
# 2. Build Research delegation prompt
|
|
413
|
+
research_prompt = prompts.build_research_context_prompt(git_analysis, days)
|
|
414
|
+
|
|
415
|
+
# 3. Display prompt for PM to delegate
|
|
416
|
+
console.print("\n" + "=" * 80)
|
|
417
|
+
console.print("š DELEGATE TO RESEARCH AGENT:")
|
|
418
|
+
console.print("=" * 80 + "\n")
|
|
419
|
+
console.print(research_prompt)
|
|
420
|
+
console.print("\n" + "=" * 80 + "\n")
|
|
421
|
+
|
|
422
|
+
return {
|
|
423
|
+
"status": OperationResult.CONTEXT_READY,
|
|
424
|
+
"git_analysis": git_analysis,
|
|
425
|
+
"research_prompt": research_prompt,
|
|
426
|
+
"recommendation": "PM should delegate this prompt to Research agent",
|
|
427
|
+
}
|