claude-mpm 4.10.0__py3-none-any.whl → 4.11.1__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 CHANGED
@@ -1 +1 @@
1
- 4.10.0
1
+ 4.11.1
@@ -1464,6 +1464,198 @@ preserving valuable project-specific information while refreshing standard secti
1464
1464
  logger.error(f"Initialization failed: {e}")
1465
1465
  return {"status": "error", "message": str(e)}
1466
1466
 
1467
+ def handle_context(
1468
+ self,
1469
+ session_id: Optional[str] = None,
1470
+ list_sessions: bool = False,
1471
+ days: int = 7,
1472
+ ) -> Dict[str, Any]:
1473
+ """
1474
+ Provide intelligent context for resuming work based on git history.
1475
+
1476
+ Analyzes recent commits to identify:
1477
+ - Active work streams (what was being worked on)
1478
+ - Intent and motivation (why this work)
1479
+ - Risks and blockers
1480
+ - Recommended next actions
1481
+
1482
+ This delegates to Research agent for deep analysis.
1483
+
1484
+ Args:
1485
+ session_id: Unused parameter (for compatibility)
1486
+ list_sessions: Unused parameter (for compatibility)
1487
+ days: Number of days of git history to analyze (default: 7)
1488
+
1489
+ Returns:
1490
+ Dict containing context result
1491
+ """
1492
+ from claude_mpm.utils.git_analyzer import analyze_recent_activity
1493
+
1494
+ # 1. Analyze git history
1495
+ console.print(f"\n🔍 Analyzing last {days} days of git history...\n")
1496
+ git_analysis = analyze_recent_activity(
1497
+ repo_path=str(self.project_path), days=days, max_commits=50
1498
+ )
1499
+
1500
+ if git_analysis.get("error"):
1501
+ console.print(
1502
+ f"[yellow]⚠️ Could not analyze git history: {git_analysis['error']}[/yellow]"
1503
+ )
1504
+ console.print(
1505
+ "[dim]Ensure this is a git repository with commit history.[/dim]\n"
1506
+ )
1507
+ return {
1508
+ "status": "error",
1509
+ "message": git_analysis["error"],
1510
+ }
1511
+
1512
+ if not git_analysis.get("has_activity"):
1513
+ console.print(
1514
+ f"[yellow]⚠️ No git activity found in the last {days} days.[/yellow]"
1515
+ )
1516
+ console.print("[dim]Try increasing the --days parameter.[/dim]\n")
1517
+ return {
1518
+ "status": "error",
1519
+ "message": f"No git activity in last {days} days",
1520
+ }
1521
+
1522
+ # 2. Build Research delegation prompt
1523
+ research_prompt = self._build_research_context_prompt(git_analysis, days)
1524
+
1525
+ # 3. Display prompt for PM to delegate
1526
+ console.print("\n" + "=" * 80)
1527
+ console.print("📋 DELEGATE TO RESEARCH AGENT:")
1528
+ console.print("=" * 80 + "\n")
1529
+ console.print(research_prompt)
1530
+ console.print("\n" + "=" * 80 + "\n")
1531
+
1532
+ return {
1533
+ "status": "context_ready",
1534
+ "git_analysis": git_analysis,
1535
+ "research_prompt": research_prompt,
1536
+ "recommendation": "PM should delegate this prompt to Research agent",
1537
+ }
1538
+
1539
+ def _build_research_context_prompt(
1540
+ self, git_analysis: Dict[str, Any], days: int
1541
+ ) -> str:
1542
+ """Build structured Research agent delegation prompt from git analysis."""
1543
+
1544
+ # Extract key data
1545
+ commits = git_analysis.get("commits", [])
1546
+ branches = git_analysis.get("branches", [])
1547
+ contributors = git_analysis.get("contributors", {})
1548
+ file_changes = git_analysis.get("file_changes", {})
1549
+
1550
+ # Build prompt following Prompt Engineer's template
1551
+ prompt = f"""# Project Context Analysis Mission
1552
+
1553
+ You are Research agent analyzing git history to provide PM with intelligent project context for resuming work.
1554
+
1555
+ ## Analysis Scope
1556
+ - **Time Range**: Last {days} days
1557
+ - **Commits Analyzed**: {len(commits)} commits
1558
+ - **Branches**: {', '.join(branches[:5]) if branches else 'main'}
1559
+ - **Contributors**: {', '.join(contributors.keys()) if contributors else 'Unknown'}
1560
+
1561
+ ## Your Mission
1562
+
1563
+ Analyze git history to answer these questions for PM:
1564
+
1565
+ 1. **What was being worked on?** (Active work streams)
1566
+ 2. **Why was this work happening?** (Intent and motivation)
1567
+ 3. **What's the natural next step?** (Continuation recommendations)
1568
+ 4. **What needs attention?** (Risks, stalls, conflicts)
1569
+
1570
+ ## Git Data Provided
1571
+
1572
+ ### Recent Commits ({min(len(commits), 10)} most recent):
1573
+ """
1574
+
1575
+ # Add recent commits
1576
+ for commit in commits[:10]:
1577
+ author = commit.get("author", "Unknown")
1578
+ timestamp = commit.get("timestamp", "Unknown date")
1579
+ message = commit.get("message", "No message")
1580
+ files = commit.get("files", [])
1581
+
1582
+ prompt += f"\n- **{timestamp}** by {author}"
1583
+ prompt += f"\n {message}"
1584
+ prompt += f"\n Files changed: {len(files)}\n"
1585
+
1586
+ # Add file change summary
1587
+ if file_changes:
1588
+ # Sort by modifications count
1589
+ sorted_files = sorted(
1590
+ file_changes.items(),
1591
+ key=lambda x: x[1].get("modifications", 0),
1592
+ reverse=True,
1593
+ )
1594
+ prompt += "\n### Most Changed Files:\n"
1595
+ for file_path, file_data in sorted_files[:10]:
1596
+ modifications = file_data.get("modifications", 0)
1597
+ file_contributors = file_data.get("contributors", [])
1598
+ prompt += f"- {file_path}: {modifications} changes ({len(file_contributors)} contributor{'s' if len(file_contributors) != 1 else ''})\n"
1599
+
1600
+ # Add contributor summary
1601
+ if contributors:
1602
+ prompt += "\n### Contributors:\n"
1603
+ sorted_contributors = sorted(
1604
+ contributors.items(),
1605
+ key=lambda x: x[1].get("commits", 0),
1606
+ reverse=True,
1607
+ )
1608
+ for name, info in sorted_contributors[:5]:
1609
+ commit_count = info.get("commits", 0)
1610
+ prompt += f"- {name}: {commit_count} commit{'s' if commit_count != 1 else ''}\n"
1611
+
1612
+ # Add analysis instructions
1613
+ prompt += """
1614
+
1615
+ ## Analysis Instructions
1616
+
1617
+ ### Phase 1: Work Stream Identification
1618
+ Group related commits into thematic work streams. For each stream:
1619
+ - **Name**: Infer from commit messages (e.g., "Authentication refactor")
1620
+ - **Status**: ongoing/completed/stalled
1621
+ - **Commits**: Count of commits in this stream
1622
+ - **Intent**: WHY this work (from commit bodies/messages)
1623
+ - **Key Files**: Most changed files in this stream
1624
+
1625
+ ### Phase 2: Risk Detection
1626
+ Identify:
1627
+ - **Stalled Work**: Work streams with no activity >3 days
1628
+ - **Anti-Patterns**: WIP commits, temp commits, debug commits
1629
+ - **Documentation Lag**: Code changes without doc updates
1630
+ - **Conflicts**: Merge conflicts or divergent branches
1631
+
1632
+ ### Phase 3: Recommendations
1633
+ Based on analysis:
1634
+ 1. **Primary Focus**: Most active/recent work to continue
1635
+ 2. **Quick Wins**: Small tasks that could be finished
1636
+ 3. **Blockers**: Issues preventing progress
1637
+ 4. **Next Steps**: Logical continuation points
1638
+
1639
+ ## Output Format
1640
+
1641
+ Provide a clear markdown summary with:
1642
+
1643
+ 1. **Active Work Streams** (What was being worked on)
1644
+ 2. **Intent Summary** (Why this work matters)
1645
+ 3. **Risks Detected** (What needs attention)
1646
+ 4. **Recommended Next Actions** (What to work on)
1647
+
1648
+ Keep it concise (<1000 words) but actionable.
1649
+
1650
+ ## Success Criteria
1651
+ - Work streams accurately reflect development themes
1652
+ - Intent captures the "why" not just "what"
1653
+ - Recommendations are specific and actionable
1654
+ - Risks are prioritized by impact
1655
+ """
1656
+
1657
+ return prompt
1658
+
1467
1659
  def _display_results(self, result: Dict, verbose: bool):
1468
1660
  """Display initialization results."""
1469
1661
  if result["status"] == "success":
@@ -1500,7 +1692,7 @@ preserving valuable project-specific information while refreshing standard secti
1500
1692
  self.display.display_success_panel("Success", success_content)
1501
1693
 
1502
1694
 
1503
- @click.command(name="mpm-init")
1695
+ @click.group(name="mpm-init", invoke_without_command=True)
1504
1696
  @click.option(
1505
1697
  "--project-type",
1506
1698
  type=click.Choice(
@@ -1589,7 +1781,9 @@ preserving valuable project-specific information while refreshing standard secti
1589
1781
  required=False,
1590
1782
  default=".",
1591
1783
  )
1784
+ @click.pass_context
1592
1785
  def mpm_init(
1786
+ ctx,
1593
1787
  project_type,
1594
1788
  framework,
1595
1789
  force,
@@ -1619,18 +1813,27 @@ def mpm_init(
1619
1813
  - Optimize for AI agent understanding
1620
1814
  - Perform AST analysis for enhanced developer documentation
1621
1815
 
1816
+ Context Management:
1817
+ - resume: Analyze git history to provide context for resuming work
1818
+ - --catchup: Show recent commit history for PM context
1819
+
1622
1820
  Update Mode:
1623
1821
  When CLAUDE.md exists, the command offers to update rather than recreate,
1624
1822
  preserving custom content while refreshing standard sections.
1625
1823
 
1626
1824
  Examples:
1627
1825
  claude-mpm mpm-init # Initialize/update current directory
1826
+ claude-mpm mpm-init --catchup # Show recent git history for context
1628
1827
  claude-mpm mpm-init --review # Review project state without changes
1629
1828
  claude-mpm mpm-init --update # Force update mode
1630
1829
  claude-mpm mpm-init --organize # Organize misplaced files
1631
1830
  claude-mpm mpm-init --project-type web # Initialize as web project
1632
1831
  claude-mpm mpm-init /path/to/project --force # Force reinitialize project
1633
1832
  """
1833
+ # If a subcommand is being invoked, don't run the main command
1834
+ if ctx.invoked_subcommand is not None:
1835
+ return
1836
+
1634
1837
  try:
1635
1838
  # Create command instance
1636
1839
  command = MPMInitCommand(Path(project_path))
@@ -1668,5 +1871,105 @@ def mpm_init(
1668
1871
  sys.exit(1)
1669
1872
 
1670
1873
 
1874
+ @mpm_init.command(name="context")
1875
+ @click.option(
1876
+ "--session-id",
1877
+ "-i",
1878
+ type=str,
1879
+ help="Unused (for compatibility) - will be removed in future version",
1880
+ )
1881
+ @click.option(
1882
+ "--days",
1883
+ type=int,
1884
+ default=7,
1885
+ help="Number of days of git history to analyze (default: 7)",
1886
+ )
1887
+ @click.argument(
1888
+ "project_path",
1889
+ type=click.Path(exists=True, file_okay=False, dir_okay=True),
1890
+ required=False,
1891
+ default=".",
1892
+ )
1893
+ def context_command(session_id, days, project_path):
1894
+ """
1895
+ Provide intelligent context for resuming work based on git history.
1896
+
1897
+ Analyzes recent git history and generates a Research agent delegation
1898
+ prompt for intelligent project context reconstruction.
1899
+
1900
+ Examples:
1901
+ claude-mpm mpm-init context # Analyze last 7 days
1902
+ claude-mpm mpm-init context --days 14 # Analyze last 14 days
1903
+ claude-mpm mpm-init context --days 30 # Analyze last 30 days
1904
+
1905
+ Note: 'resume' is deprecated, use 'context' instead.
1906
+ """
1907
+ try:
1908
+ command = MPMInitCommand(Path(project_path))
1909
+
1910
+ result = command.handle_context(session_id=session_id, days=days)
1911
+
1912
+ if result["status"] == "success" or result["status"] == "context_ready":
1913
+ sys.exit(0)
1914
+ else:
1915
+ sys.exit(1)
1916
+
1917
+ except KeyboardInterrupt:
1918
+ console.print("\n[yellow]Context analysis cancelled by user[/yellow]")
1919
+ sys.exit(130)
1920
+ except Exception as e:
1921
+ console.print(f"[red]Context analysis failed: {e}[/red]")
1922
+ sys.exit(1)
1923
+
1924
+
1925
+ # Add deprecated 'resume' alias for backward compatibility
1926
+ @mpm_init.command(name="resume", hidden=True)
1927
+ @click.option(
1928
+ "--session-id",
1929
+ "-i",
1930
+ type=str,
1931
+ help="Unused (for compatibility) - will be removed in future version",
1932
+ )
1933
+ @click.option(
1934
+ "--days",
1935
+ type=int,
1936
+ default=7,
1937
+ help="Number of days of git history to analyze (default: 7)",
1938
+ )
1939
+ @click.argument(
1940
+ "project_path",
1941
+ type=click.Path(exists=True, file_okay=False, dir_okay=True),
1942
+ required=False,
1943
+ default=".",
1944
+ )
1945
+ def resume_session(session_id, days, project_path):
1946
+ """
1947
+ [DEPRECATED] Use 'context' instead.
1948
+
1949
+ This command is deprecated and will be removed in a future version.
1950
+ Please use 'claude-mpm mpm-init context' instead.
1951
+ """
1952
+ console.print(
1953
+ "[yellow]⚠️ Warning: 'resume' is deprecated. Use 'context' instead.[/yellow]"
1954
+ )
1955
+ console.print("[dim]Run: claude-mpm mpm-init context[/dim]\n")
1956
+
1957
+ try:
1958
+ command = MPMInitCommand(Path(project_path))
1959
+ result = command.handle_context(session_id=session_id, days=days)
1960
+
1961
+ if result["status"] == "success" or result["status"] == "context_ready":
1962
+ sys.exit(0)
1963
+ else:
1964
+ sys.exit(1)
1965
+
1966
+ except KeyboardInterrupt:
1967
+ console.print("\n[yellow]Context analysis cancelled by user[/yellow]")
1968
+ sys.exit(130)
1969
+ except Exception as e:
1970
+ console.print(f"[red]Context analysis failed: {e}[/red]")
1971
+ sys.exit(1)
1972
+
1973
+
1671
1974
  # Export for CLI registration
1672
1975
  __all__ = ["mpm_init"]
@@ -25,6 +25,36 @@ def manage_mpm_init(args):
25
25
  # Import the command implementation
26
26
  from .mpm_init import MPMInitCommand
27
27
 
28
+ # Handle context subcommands
29
+ subcommand = getattr(args, "subcommand", None)
30
+
31
+ if subcommand in ("context", "resume"):
32
+ # Show deprecation warning for 'resume'
33
+ if subcommand == "resume":
34
+ console.print(
35
+ "[yellow]⚠️ Warning: 'resume' is deprecated. Use 'context' instead.[/yellow]"
36
+ )
37
+ console.print("[dim]Run: claude-mpm mpm-init context[/dim]\n")
38
+
39
+ # Get project path
40
+ project_path = (
41
+ Path(args.project_path) if hasattr(args, "project_path") else Path.cwd()
42
+ )
43
+
44
+ # Create command instance
45
+ command = MPMInitCommand(project_path)
46
+
47
+ # Handle context with optional session ID and days
48
+ result = command.handle_context(
49
+ session_id=getattr(args, "session_id", None),
50
+ days=getattr(args, "days", 7),
51
+ )
52
+
53
+ # Return appropriate exit code
54
+ if result.get("status") in ("success", "context_ready"):
55
+ return 0
56
+ return 1
57
+
28
58
  # Handle special flags
29
59
  if getattr(args, "list_templates", False):
30
60
  # List available templates
@@ -55,7 +85,6 @@ def manage_mpm_init(args):
55
85
  "framework": getattr(args, "framework", None),
56
86
  "force": getattr(args, "force", False),
57
87
  "verbose": getattr(args, "verbose", False),
58
- "use_venv": getattr(args, "use_venv", False),
59
88
  "ast_analysis": getattr(args, "ast_analysis", True),
60
89
  "update_mode": getattr(args, "update", False),
61
90
  "review_only": getattr(args, "review", False),
@@ -31,6 +31,7 @@ def add_mpm_init_subparser(subparsers: Any) -> None:
31
31
  epilog=(
32
32
  "Examples:\n"
33
33
  " claude-mpm mpm-init # Initialize/update current directory\n"
34
+ " claude-mpm mpm-init --catchup # Show recent git history for context\n"
34
35
  " claude-mpm mpm-init --review # Review project state without changes\n"
35
36
  " claude-mpm mpm-init --update # Update existing CLAUDE.md\n"
36
37
  " claude-mpm mpm-init --quick-update # Quick update based on recent git activity\n"
@@ -205,5 +206,64 @@ def add_mpm_init_subparser(subparsers: Any) -> None:
205
206
  help="Path to project directory (default: current directory)",
206
207
  )
207
208
 
209
+ # Add subparsers for context commands
210
+ subcommands = mpm_init_parser.add_subparsers(
211
+ dest="subcommand",
212
+ title="context management",
213
+ description="Commands for managing project context",
214
+ )
215
+
216
+ # Context subcommand (primary name)
217
+ context_parser = subcommands.add_parser(
218
+ "context",
219
+ help="Provide intelligent context for resuming work",
220
+ description="Analyze git history to provide context for resuming work",
221
+ epilog="Note: 'resume' is deprecated, use 'context' instead",
222
+ )
223
+ context_parser.add_argument(
224
+ "--session-id",
225
+ "-i",
226
+ type=str,
227
+ help="Unused (for compatibility) - will be removed in future version",
228
+ )
229
+ context_parser.add_argument(
230
+ "--days",
231
+ type=int,
232
+ default=7,
233
+ help="Number of days of git history to analyze (default: 7)",
234
+ )
235
+ context_parser.add_argument(
236
+ "project_path",
237
+ nargs="?",
238
+ default=".",
239
+ help="Path to project directory (default: current directory)",
240
+ )
241
+
242
+ # Resume subcommand (deprecated alias for backward compatibility)
243
+ resume_parser = subcommands.add_parser(
244
+ "resume",
245
+ help="[DEPRECATED] Use 'context' instead",
246
+ description="[DEPRECATED] This command is deprecated. Use 'context' instead.\n\n"
247
+ "Analyze git history to provide context for resuming work",
248
+ )
249
+ resume_parser.add_argument(
250
+ "--session-id",
251
+ "-i",
252
+ type=str,
253
+ help="Unused (for compatibility) - will be removed in future version",
254
+ )
255
+ resume_parser.add_argument(
256
+ "--days",
257
+ type=int,
258
+ default=7,
259
+ help="Number of days of git history to analyze (default: 7)",
260
+ )
261
+ resume_parser.add_argument(
262
+ "project_path",
263
+ nargs="?",
264
+ default=".",
265
+ help="Path to project directory (default: current directory)",
266
+ )
267
+
208
268
  # Set the command handler
209
269
  mpm_init_parser.set_defaults(command="mpm-init")
@@ -7,6 +7,9 @@ Initialize or intelligently update your project for optimal use with Claude Code
7
7
  ```
8
8
  /mpm-init # Auto-detects and offers update or create
9
9
  /mpm-init update # Lightweight update based on recent git activity
10
+ /mpm-init context # Intelligent context analysis from git history
11
+ /mpm-init context --days 14 # Analyze last 14 days of git history
12
+ /mpm-init catchup # Quick commit history display (no analysis)
10
13
  /mpm-init --review # Review project state without changes
11
14
  /mpm-init --update # Full update of existing CLAUDE.md
12
15
  /mpm-init --organize # Organize project structure
@@ -17,7 +20,11 @@ Initialize or intelligently update your project for optimal use with Claude Code
17
20
 
18
21
  ## Description
19
22
 
20
- This command delegates to the Agentic Coder Optimizer agent to establish clear, single-path project standards for documentation, tooling, and workflows.
23
+ This command has two primary modes:
24
+ - **Project initialization/updates**: Delegates to the Agentic Coder Optimizer agent for documentation, tooling, and workflow setup
25
+ - **Context analysis** (context/catchup): Provides intelligent project context from git history for resuming work
26
+
27
+ **Note**: The `resume` subcommand is deprecated. Use `context` instead. The `resume` command still works for backward compatibility but will be removed in a future version.
21
28
 
22
29
  **Quick Update Mode**: Running `/mpm-init update` performs a lightweight update focused on recent git activity. It analyzes recent commits, generates an activity report, and updates documentation with minimal changes. Perfect for quick refreshes after development sprints.
23
30
 
@@ -54,6 +61,46 @@ This command delegates to the Agentic Coder Optimizer agent to establish clear,
54
61
  - `--no-preserve-custom`: Don't preserve custom sections
55
62
  - `--skip-archive`: Skip archiving existing files before updating
56
63
 
64
+ ## Context Analysis
65
+
66
+ **Purpose**: Provide intelligent project context for resuming work by analyzing git history.
67
+
68
+ ### Commands
69
+
70
+ #### `/mpm-init context` (Primary)
71
+ ```bash
72
+ /mpm-init context # Analyze last 7 days of git history
73
+ /mpm-init context --days 14 # Analyze last 14 days
74
+ ```
75
+
76
+ Analyzes recent git commits to identify:
77
+ - **Active work streams**: What was being worked on (themes from commit patterns)
78
+ - **Intent and motivation**: Why this work matters (from commit messages)
79
+ - **Risks and blockers**: What needs attention (stalled work, conflicts, anti-patterns)
80
+ - **Recommended next actions**: What to work on next (logical continuations)
81
+
82
+ **How it works**:
83
+ 1. Parses git history (default: last 7 days)
84
+ 2. PM delegates to Research agent with structured prompt
85
+ 3. Research analyzes work streams, intent, risks, recommendations
86
+ 4. PM presents intelligent summary for seamless work resumption
87
+
88
+ **NOT session state**: This does NOT save/restore conversation state like Claude Code. Instead, it reconstructs project context from git history using conventional commits and commit message analysis.
89
+
90
+ #### `/mpm-init resume` [DEPRECATED]
91
+ Alias for `context`. Use `context` instead.
92
+
93
+ ### `/mpm-init catchup` (Simple Git History)
94
+ ```bash
95
+ /mpm-init catchup
96
+ ```
97
+
98
+ Quick display of last 25 commits across all branches. No analysis - just raw git log output with authors and dates. Use this for quick "what happened recently?" checks.
99
+
100
+ **Distinction**:
101
+ - **catchup**: Quick commit history (instant, no analysis)
102
+ - **context**: Intelligent work resumption (10-30s, deep analysis)
103
+
57
104
  ## What This Command Does
58
105
 
59
106
  ### Auto-Detection (NEW)
@@ -146,22 +193,52 @@ Fast update based on recent 30-day git activity. Generates activity report and u
146
193
 
147
194
  **Note**: Typing `/mpm-init update` executes `claude-mpm mpm-init --quick-update` automatically.
148
195
 
149
- ### Catchup Mode
196
+ ### Context Analysis (Intelligent Resumption)
197
+
198
+ Get intelligent context for resuming work based on git history analysis:
199
+
200
+ **Standard Context Analysis:**
201
+ ```bash
202
+ /mpm-init context # Analyze last 7 days (default)
203
+ /mpm-init context --days 14 # Analyze last 14 days
204
+ /mpm-init context --days 30 # Analyze last 30 days
205
+ ```
206
+
207
+ This provides intelligent analysis including:
208
+ - **Work stream identification** from commit patterns
209
+ - **Intent analysis** (why work was done)
210
+ - **Risk detection** (stalled work, conflicts, etc.)
211
+ - **Recommended next actions** for seamless continuation
212
+
213
+ **How it works:**
214
+ 1. Parses git history (7 days default)
215
+ 2. PM delegates to Research agent with structured prompt
216
+ 3. Research agent provides deep analysis
217
+ 4. PM presents intelligent summary
150
218
 
151
- Show recent commit history to provide PM with project context:
219
+ **NOT session state**: This reconstructs context from git history, not saved conversation state.
220
+
221
+ **Backward Compatibility:**
222
+ ```bash
223
+ /mpm-init resume # Still works but deprecated
224
+ ```
225
+
226
+ The old `resume` command redirects to `context` with a deprecation warning.
227
+
228
+ ### Quick Git History (Catchup)
229
+
230
+ Display recent commit history without analysis:
152
231
 
153
232
  ```bash
154
233
  /mpm-init catchup
155
234
  ```
156
235
 
157
- This displays:
236
+ Shows:
158
237
  - Last 25 commits from all branches
159
- - Author attribution (WHO did WHAT)
160
- - Temporal context (WHEN)
238
+ - Author attribution and timestamps
161
239
  - Contributor activity summary
162
- - PM recommendations based on commit patterns
163
240
 
164
- Useful for understanding recent development activity and getting PM up to speed on project changes.
241
+ Use this for quick "what happened recently?" checks. For intelligent analysis, use `context` instead.
165
242
 
166
243
  ### Review Project State
167
244
  ```bash
@@ -210,6 +287,49 @@ Quick initialization without code analysis.
210
287
 
211
288
  This command routes between different modes:
212
289
 
290
+ ### Context Analysis Commands
291
+
292
+ **IMPORTANT**: Context analysis commands (`/mpm-init context`, `/mpm-init catchup`) have distinct behaviors:
293
+
294
+ **`/mpm-init context` - Delegates to PM**:
295
+ ```bash
296
+ claude-mpm mpm-init context --days 7
297
+ ```
298
+
299
+ This command delegates work to the PM framework:
300
+ 1. Parses git history (7 days default)
301
+ 2. PM constructs structured Research delegation prompt
302
+ 3. PM presents prompt for Research agent to analyze
303
+ 4. Research identifies work streams, intent, risks, recommendations
304
+ 5. PM synthesizes for user
305
+
306
+ This is intelligent analysis requiring Research agent expertise.
307
+
308
+ **How the PM delegates to Research:**
309
+ The PM creates a delegation prompt that asks Research to analyze:
310
+ - **Work Stream Identification**: Groups related commits into themes
311
+ - **Intent Analysis**: Infers why work was done from commit messages
312
+ - **Risk Detection**: Identifies stalled work, conflicts, and blockers
313
+ - **Recommended Actions**: Suggests logical next steps for continuation
314
+
315
+ **`/mpm-init catchup` - Direct CLI execution**:
316
+ ```bash
317
+ claude-mpm mpm-init catchup
318
+ ```
319
+
320
+ This executes directly via CLI without agent delegation:
321
+ - Displays last 25 commits from all branches
322
+ - Shows authors, dates, commit messages
323
+ - Instant output (no analysis)
324
+
325
+ This is a simple git log display utility.
326
+
327
+ ---
328
+
329
+ ### Project Initialization/Update Commands
330
+
331
+ **IMPORTANT**: Standard initialization and update commands delegate to the Agentic Coder Optimizer agent.
332
+
213
333
  **Quick Update Mode** (`/mpm-init update`):
214
334
  ```bash
215
335
  claude-mpm mpm-init --quick-update
@@ -268,12 +388,20 @@ The command delegates to the Agentic Coder Optimizer agent which:
268
388
  ## Notes
269
389
 
270
390
  - **Quick Update vs Full Update**: Use `/mpm-init update` for fast activity-based updates (30 days), or `/mpm-init --update` for comprehensive doc refresh
391
+ - **Context Analysis**: Use `/mpm-init context` to analyze git history and get intelligent resumption context from Research agent
392
+ - **Quick History**: Use `/mpm-init catchup` for instant commit history display without analysis
393
+ - **Deprecation Notice**: The `resume` command is deprecated. Use `context` instead. The old command still works but shows a warning.
271
394
  - **Smart Mode**: Automatically detects existing CLAUDE.md and offers update vs recreate
272
395
  - **Safe Updates**: Previous versions always archived before updating
273
396
  - **Custom Content**: Your project-specific sections are preserved by default
274
- - **Git Integration**: Analyzes recent commits to understand project evolution
397
+ - **Git Integration**: Analyzes recent commits to understand project evolution and provide work context
398
+ - **Backward Compatibility**: All existing `resume` commands redirect to `context` with deprecation warning
275
399
  - **Argument Processing**: The slash command processes the `update` argument and routes to `--quick-update` flag
276
- - The command uses the Agentic Coder Optimizer agent for implementation
400
+ - **Agent Delegation**:
401
+ - Project initialization and updates use the Agentic Coder Optimizer agent
402
+ - Context analysis (`context`) delegates to PM, who coordinates with Research agent
403
+ - Simple git history (`catchup`) executes directly via CLI without agent delegation
404
+ - **NOT Session State**: Context analysis reconstructs project understanding from git history, not saved conversation state
277
405
  - AST analysis is enabled by default for comprehensive documentation
278
406
  - Priority rankings help AI agents focus on critical instructions first
279
407
  - The holistic review ensures documentation quality and completeness
@@ -86,7 +86,7 @@ class StateStorage:
86
86
  return True
87
87
 
88
88
  except Exception as e:
89
- self.logger.error(f"Failed to write JSON to {file_path}: {e}")
89
+ logger.error(f"Failed to write JSON to {file_path}: {e}")
90
90
  self.error_count += 1
91
91
  return False
92
92
 
@@ -106,7 +106,7 @@ class StateStorage:
106
106
  file_path = Path(file_path)
107
107
 
108
108
  if not file_path.exists():
109
- self.logger.debug(f"File not found: {file_path}")
109
+ logger.debug(f"File not found: {file_path}")
110
110
  return None
111
111
 
112
112
  # Auto-detect compression
@@ -125,7 +125,7 @@ class StateStorage:
125
125
  return data
126
126
 
127
127
  except Exception as e:
128
- self.logger.error(f"Failed to read JSON from {file_path}: {e}")
128
+ logger.error(f"Failed to read JSON from {file_path}: {e}")
129
129
  self.error_count += 1
130
130
  return None
131
131
 
@@ -166,7 +166,7 @@ class StateStorage:
166
166
  return True
167
167
 
168
168
  except Exception as e:
169
- self.logger.error(f"Failed to write pickle to {file_path}: {e}")
169
+ logger.error(f"Failed to write pickle to {file_path}: {e}")
170
170
  self.error_count += 1
171
171
  return False
172
172
 
@@ -186,7 +186,7 @@ class StateStorage:
186
186
  file_path = Path(file_path)
187
187
 
188
188
  if not file_path.exists():
189
- self.logger.debug(f"File not found: {file_path}")
189
+ logger.debug(f"File not found: {file_path}")
190
190
  return None
191
191
 
192
192
  # Auto-detect compression
@@ -205,7 +205,7 @@ class StateStorage:
205
205
  return data
206
206
 
207
207
  except Exception as e:
208
- self.logger.error(f"Failed to read pickle from {file_path}: {e}")
208
+ logger.error(f"Failed to read pickle from {file_path}: {e}")
209
209
  self.error_count += 1
210
210
  return None
211
211
 
@@ -262,7 +262,7 @@ class StateStorage:
262
262
  Path(temp_path).replace(file_path)
263
263
 
264
264
  self.write_count += 1
265
- self.logger.debug(f"Atomic write successful: {file_path}")
265
+ logger.debug(f"Atomic write successful: {file_path}")
266
266
  return True
267
267
 
268
268
  finally:
@@ -271,7 +271,7 @@ class StateStorage:
271
271
  Path(temp_path).unlink()
272
272
 
273
273
  except Exception as e:
274
- self.logger.error(f"Atomic write failed for {file_path}: {e}")
274
+ logger.error(f"Atomic write failed for {file_path}: {e}")
275
275
  self.error_count += 1
276
276
  return False
277
277
 
@@ -339,7 +339,7 @@ class StateStorage:
339
339
  f.write(checksum)
340
340
 
341
341
  except Exception as e:
342
- self.logger.warning(f"Could not add checksum: {e}")
342
+ logger.warning(f"Could not add checksum: {e}")
343
343
 
344
344
  def verify_checksum(self, file_path: Union[str, Path]) -> bool:
345
345
  """Verify file checksum for integrity.
@@ -370,13 +370,13 @@ class StateStorage:
370
370
  actual = hasher.hexdigest()
371
371
 
372
372
  if actual != expected:
373
- self.logger.error(f"Checksum mismatch for {file_path}")
373
+ logger.error(f"Checksum mismatch for {file_path}")
374
374
  return False
375
375
 
376
376
  return True
377
377
 
378
378
  except Exception as e:
379
- self.logger.warning(f"Could not verify checksum: {e}")
379
+ logger.warning(f"Could not verify checksum: {e}")
380
380
  return True # Assume valid if can't verify
381
381
 
382
382
  def cleanup_temp_files(self) -> int:
@@ -396,7 +396,7 @@ class StateStorage:
396
396
  if age > 3600:
397
397
  temp_file.unlink()
398
398
  cleaned += 1
399
- self.logger.debug(f"Cleaned up temp file: {temp_file}")
399
+ logger.debug(f"Cleaned up temp file: {temp_file}")
400
400
  except Exception:
401
401
  pass
402
402
 
@@ -408,12 +408,12 @@ class StateStorage:
408
408
  cleaned += 1
409
409
 
410
410
  if cleaned > 0:
411
- self.logger.info(f"Cleaned up {cleaned} temporary files")
411
+ logger.info(f"Cleaned up {cleaned} temporary files")
412
412
 
413
413
  return cleaned
414
414
 
415
415
  except Exception as e:
416
- self.logger.error(f"Error cleaning up temp files: {e}")
416
+ logger.error(f"Error cleaning up temp files: {e}")
417
417
  return 0
418
418
 
419
419
  def get_storage_info(self) -> Dict[str, Any]:
@@ -447,7 +447,7 @@ class StateStorage:
447
447
  }
448
448
 
449
449
  except Exception as e:
450
- self.logger.error(f"Error getting storage info: {e}")
450
+ logger.error(f"Error getting storage info: {e}")
451
451
  return {"storage_directory": str(self.storage_dir), "error": str(e)}
452
452
 
453
453
 
@@ -0,0 +1,305 @@
1
+ """
2
+ Git history analysis utilities for intelligent context reconstruction.
3
+
4
+ This module provides utilities to analyze git repository activity for
5
+ context reconstruction and project intelligence. Extracted from the
6
+ session management system to support git-based context approaches.
7
+ """
8
+
9
+ import subprocess
10
+ from pathlib import Path
11
+ from typing import Any, Dict, List, Optional
12
+
13
+ from claude_mpm.core.logging_utils import get_logger
14
+
15
+ logger = get_logger(__name__)
16
+
17
+
18
+ def analyze_recent_activity(
19
+ repo_path: str = ".", days: int = 7, max_commits: int = 50
20
+ ) -> Dict[str, Any]:
21
+ """
22
+ Analyze recent git activity for context reconstruction.
23
+
24
+ This function analyzes git history to provide comprehensive context about
25
+ recent project activity including commits, contributors, file changes,
26
+ and branch activity.
27
+
28
+ Args:
29
+ repo_path: Path to the git repository (default: current directory)
30
+ days: Number of days to look back (default: 7)
31
+ max_commits: Maximum number of commits to analyze (default: 50)
32
+
33
+ Returns:
34
+ Dict containing:
35
+ - time_range: str - Description of analysis period
36
+ - commits: List[Dict] - Recent commits with metadata
37
+ - branches: List[str] - Active branches in the repository
38
+ - contributors: Dict[str, Dict] - Contributor statistics
39
+ - file_changes: Dict[str, Dict] - File change statistics
40
+ - has_activity: bool - Whether any activity was found
41
+ - error: Optional[str] - Error message if analysis failed
42
+ """
43
+ repo_path_obj = Path(repo_path)
44
+ analysis = {
45
+ "time_range": f"last {days} days",
46
+ "commits": [],
47
+ "branches": [],
48
+ "contributors": {},
49
+ "file_changes": {},
50
+ "has_activity": False,
51
+ }
52
+
53
+ try:
54
+ # Get all branches
55
+ result = subprocess.run(
56
+ ["git", "branch", "-a"],
57
+ cwd=str(repo_path_obj),
58
+ capture_output=True,
59
+ text=True,
60
+ check=True,
61
+ )
62
+ branches = [
63
+ line.strip().replace("* ", "").replace("remotes/origin/", "")
64
+ for line in result.stdout.strip().split("\n")
65
+ if line.strip()
66
+ ]
67
+ analysis["branches"] = list(set(branches))
68
+
69
+ # Get recent commits from all branches
70
+ result = subprocess.run(
71
+ [
72
+ "git",
73
+ "log",
74
+ "--all",
75
+ f"--since={days} days ago",
76
+ f"--max-count={max_commits}",
77
+ "--format=%h|%an|%ae|%ai|%s",
78
+ "--name-status",
79
+ ],
80
+ cwd=str(repo_path_obj),
81
+ capture_output=True,
82
+ text=True,
83
+ check=True,
84
+ )
85
+
86
+ if not result.stdout.strip():
87
+ return analysis
88
+
89
+ analysis["has_activity"] = True
90
+
91
+ # Parse commit log
92
+ commits = []
93
+ current_commit = None
94
+ file_changes = {}
95
+
96
+ for line in result.stdout.strip().split("\n"):
97
+ if not line.strip():
98
+ continue
99
+
100
+ if "|" in line:
101
+ # Commit line
102
+ if current_commit:
103
+ commits.append(current_commit)
104
+
105
+ parts = line.split("|", 4)
106
+ if len(parts) == 5:
107
+ sha, author, email, timestamp, message = parts
108
+ current_commit = {
109
+ "sha": sha,
110
+ "author": author,
111
+ "email": email,
112
+ "timestamp": timestamp,
113
+ "message": message,
114
+ "files": [],
115
+ }
116
+
117
+ # Track contributors
118
+ if author not in analysis["contributors"]:
119
+ analysis["contributors"][author] = {
120
+ "email": email,
121
+ "commits": 0,
122
+ }
123
+ analysis["contributors"][author]["commits"] += 1
124
+ # File change line
125
+ elif current_commit and "\t" in line:
126
+ parts = line.split("\t", 1)
127
+ if len(parts) == 2:
128
+ status, file_path = parts
129
+ current_commit["files"].append(
130
+ {"status": status, "path": file_path}
131
+ )
132
+
133
+ # Track file changes
134
+ if file_path not in file_changes:
135
+ file_changes[file_path] = {
136
+ "modifications": 0,
137
+ "contributors": set(),
138
+ }
139
+ file_changes[file_path]["modifications"] += 1
140
+ file_changes[file_path]["contributors"].add(
141
+ current_commit["author"]
142
+ )
143
+
144
+ # Add last commit
145
+ if current_commit:
146
+ commits.append(current_commit)
147
+
148
+ analysis["commits"] = commits
149
+
150
+ # Convert file changes to serializable format
151
+ analysis["file_changes"] = {
152
+ path: {
153
+ "modifications": info["modifications"],
154
+ "contributors": list(info["contributors"]),
155
+ }
156
+ for path, info in file_changes.items()
157
+ }
158
+
159
+ except subprocess.CalledProcessError as e:
160
+ logger.warning(f"Git command failed: {e}")
161
+ analysis["error"] = f"Git command failed: {e}"
162
+ except Exception as e:
163
+ logger.warning(f"Could not analyze recent activity: {e}")
164
+ analysis["error"] = str(e)
165
+
166
+ return analysis
167
+
168
+
169
+ def get_current_branch(repo_path: str = ".") -> Optional[str]:
170
+ """
171
+ Get the current git branch name.
172
+
173
+ Args:
174
+ repo_path: Path to the git repository (default: current directory)
175
+
176
+ Returns:
177
+ Current branch name or None if not in a git repository
178
+ """
179
+ try:
180
+ result = subprocess.run(
181
+ ["git", "branch", "--show-current"],
182
+ cwd=str(Path(repo_path)),
183
+ capture_output=True,
184
+ text=True,
185
+ check=True,
186
+ )
187
+ return result.stdout.strip()
188
+ except Exception:
189
+ return None
190
+
191
+
192
+ def get_commits_since(since_sha: str, repo_path: str = ".") -> List[Dict[str, str]]:
193
+ """
194
+ Get commits since a specific SHA.
195
+
196
+ Args:
197
+ since_sha: The SHA to get commits after
198
+ repo_path: Path to the git repository (default: current directory)
199
+
200
+ Returns:
201
+ List of commit dicts with sha, author, timestamp, and message
202
+ """
203
+ try:
204
+ result = subprocess.run(
205
+ ["git", "log", f"{since_sha}..HEAD", "--format=%h|%an|%ai|%s"],
206
+ cwd=str(Path(repo_path)),
207
+ capture_output=True,
208
+ text=True,
209
+ check=True,
210
+ )
211
+
212
+ commits = []
213
+ for line in result.stdout.strip().split("\n"):
214
+ if not line:
215
+ continue
216
+ parts = line.split("|", 3)
217
+ if len(parts) == 4:
218
+ sha, author, timestamp, message = parts
219
+ commits.append(
220
+ {
221
+ "sha": sha,
222
+ "author": author,
223
+ "timestamp": timestamp,
224
+ "message": message,
225
+ }
226
+ )
227
+
228
+ return commits
229
+
230
+ except Exception as e:
231
+ logger.warning(f"Could not get commits: {e}")
232
+ return []
233
+
234
+
235
+ def get_current_status(repo_path: str = ".") -> Dict[str, Any]:
236
+ """
237
+ Get current git status.
238
+
239
+ Args:
240
+ repo_path: Path to the git repository (default: current directory)
241
+
242
+ Returns:
243
+ Dict with:
244
+ - clean: bool - Whether working directory is clean
245
+ - modified_files: List[str] - Modified files
246
+ - untracked_files: List[str] - Untracked files
247
+ """
248
+ status = {"clean": True, "modified_files": [], "untracked_files": []}
249
+
250
+ try:
251
+ result = subprocess.run(
252
+ ["git", "status", "--porcelain"],
253
+ cwd=str(Path(repo_path)),
254
+ capture_output=True,
255
+ text=True,
256
+ check=True,
257
+ )
258
+
259
+ modified_files = []
260
+ untracked_files = []
261
+
262
+ for line in result.stdout.strip().split("\n"):
263
+ if not line:
264
+ continue
265
+ status_code = line[:2]
266
+ file_path = line[3:]
267
+
268
+ if status_code.startswith("??"):
269
+ untracked_files.append(file_path)
270
+ else:
271
+ modified_files.append(file_path)
272
+
273
+ status = {
274
+ "clean": len(modified_files) == 0 and len(untracked_files) == 0,
275
+ "modified_files": modified_files,
276
+ "untracked_files": untracked_files,
277
+ }
278
+
279
+ except Exception as e:
280
+ logger.warning(f"Could not get status: {e}")
281
+
282
+ return status
283
+
284
+
285
+ def is_git_repository(repo_path: str = ".") -> bool:
286
+ """
287
+ Check if the given path is a git repository.
288
+
289
+ Args:
290
+ repo_path: Path to check (default: current directory)
291
+
292
+ Returns:
293
+ True if the path is a git repository, False otherwise
294
+ """
295
+ try:
296
+ result = subprocess.run(
297
+ ["git", "rev-parse", "--git-dir"],
298
+ cwd=str(Path(repo_path)),
299
+ capture_output=True,
300
+ text=True,
301
+ check=False,
302
+ )
303
+ return result.returncode == 0
304
+ except Exception:
305
+ return False
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: claude-mpm
3
- Version: 4.10.0
3
+ Version: 4.11.1
4
4
  Summary: Claude Multi-Agent Project Manager - Orchestrate Claude with agent delegation and ticket tracking
5
5
  Author-email: Bob Matsuoka <bob@matsuoka.com>
6
6
  Maintainer: Claude MPM Team
@@ -1,5 +1,5 @@
1
1
  claude_mpm/BUILD_NUMBER,sha256=9JfxhnDtr-8l3kCP2U5TVXSErptHoga8m7XA8zqgGOc,4
2
- claude_mpm/VERSION,sha256=9StPgaDGDNmI-MzJoDM-IGtffkHdD1KGxqtfe_LVM18,7
2
+ claude_mpm/VERSION,sha256=-pg3IRz2ArU7tcZ-4AUcxOirJEkowIcnQL1C8A2FelI,7
3
3
  claude_mpm/__init__.py,sha256=UCw6j9e_tZQ3kJtTqmdfNv7MHyw9nD1jkj80WurwM2g,2064
4
4
  claude_mpm/__main__.py,sha256=Ro5UBWBoQaSAIoSqWAr7zkbLyvi4sSy28WShqAhKJG0,723
5
5
  claude_mpm/constants.py,sha256=sLjJF6Kw7H4V9WWeaEYltM-77TgXqzEMX5vx4ukM5-0,5977
@@ -100,8 +100,8 @@ claude_mpm/cli/commands/mcp_setup_external.py,sha256=hfBHkaioNa0JRDhahNEc8agyrUw
100
100
  claude_mpm/cli/commands/mcp_tool_commands.py,sha256=q17GzlFT3JiLTrDqwPO2tz1-fKmPO5QU449syTnKTz4,1283
101
101
  claude_mpm/cli/commands/memory.py,sha256=O4T5HGL-Ob_QPt2dZHQvoOrVohnaDKrBjyngq1Mcv1w,26185
102
102
  claude_mpm/cli/commands/monitor.py,sha256=Fjb68hf3dEwTFek2LV8Nh6iU0qEkY7qYlOn32IwNaNg,9566
103
- claude_mpm/cli/commands/mpm_init.py,sha256=OtdJMsFn7E9Ck56wWPrCvqw6j5dsN_VI098C3bteitc,63888
104
- claude_mpm/cli/commands/mpm_init_handler.py,sha256=b1CSwZYJ89wMorKzPOKS-RVxOKR2kT9yv9KQLvKkd2U,3532
103
+ claude_mpm/cli/commands/mpm_init.py,sha256=oNEF_hwpu7LCvj06vqXbmVJpXm7yo4ebODyQcZN52nM,74346
104
+ claude_mpm/cli/commands/mpm_init_handler.py,sha256=FZRoo_zfEakLc_W1G_ej_bhxtaU6ybngyBP5GLxaKD4,4583
105
105
  claude_mpm/cli/commands/run.py,sha256=PB2H55piOPTy4yo4OBgbUCjMlcz9K79wbwpxQVc9m5Q,48225
106
106
  claude_mpm/cli/commands/search.py,sha256=alv6udvKcn-xkqeBlLuPRvfSDV1yxEX4n9mjjRT5uLM,16581
107
107
  claude_mpm/cli/commands/tickets.py,sha256=kl2dklTBnG3Y4jUUJ_PcEVsTx4CtVJfkGWboWBx_mQM,21234
@@ -123,7 +123,7 @@ claude_mpm/cli/parsers/debug_parser.py,sha256=F7MZdmiXiPfiIPMv21ZUqB2cMT8Ho1LDmp
123
123
  claude_mpm/cli/parsers/mcp_parser.py,sha256=2j6ULhdu55Z2k_-Gu2QxIsFoTQFbDCEMSGePXSuPoQQ,6532
124
124
  claude_mpm/cli/parsers/memory_parser.py,sha256=ZwCDxJEgp-w03L-1tZsWTgisiwamP42s424bA5bvDJc,4760
125
125
  claude_mpm/cli/parsers/monitor_parser.py,sha256=PeoznSi_5Bw6THK_Espl8M20o6dKvvBSmFzAbovkaFQ,4920
126
- claude_mpm/cli/parsers/mpm_init_parser.py,sha256=aGMwrHs7acB61sNDI0M7gf23yGDV4Q7b7iX7XnWC0yQ,7658
126
+ claude_mpm/cli/parsers/mpm_init_parser.py,sha256=EVyHc7KYpsyxhomZAUnlGS6kq43ix2wjrHLiM5Gf34E,9684
127
127
  claude_mpm/cli/parsers/run_parser.py,sha256=cs34qNonFZG8uYxTYEt0rXi2LcPz3pw8D8hxiywih6w,4927
128
128
  claude_mpm/cli/parsers/search_parser.py,sha256=L8-65kndg-zutSKpzj-eCvTNkeySCZ-WlSHdhk7pEak,6916
129
129
  claude_mpm/cli/parsers/tickets_parser.py,sha256=FYl-VNH7PrZzfZUCcjnf6F7g6JXnL8YDxwrmR5svIcg,6966
@@ -141,7 +141,7 @@ claude_mpm/commands/mpm-agents.md,sha256=JnYPJ-eWvIEEtiCB6iPu182P2xDBRvU3ArVXQ7h
141
141
  claude_mpm/commands/mpm-config.md,sha256=79Eb-srRpEVV3HCHDHZc8SKec6_LVP6HbXDEVkZKLgw,2929
142
142
  claude_mpm/commands/mpm-doctor.md,sha256=ut5LhFKVRw-2ecjMSPsnaTiRuFXa6Q9t-Wgl3CCnQvk,590
143
143
  claude_mpm/commands/mpm-help.md,sha256=zfhpE0Fd-wW5zWmYYAMRMT-xYK8saqbw-HXRD7csJHI,2850
144
- claude_mpm/commands/mpm-init.md,sha256=5Jqb99qqJ_hQ_41lGmyTyDUhm7V7wQiLCYvksd3tZEo,10696
144
+ claude_mpm/commands/mpm-init.md,sha256=wwYHkToq8U5ALdhu8bDPygqAsKZ77aMaai7ZJC3oBqU,16054
145
145
  claude_mpm/commands/mpm-monitor.md,sha256=onTHf9Yac1KkdZdENtY2Q5jyw0A-vZLYgoKkPCtZLUY,12193
146
146
  claude_mpm/commands/mpm-organize.md,sha256=T-ysjhwgfW9irjUj02vuY_1jeMdabO_zxcShyjmqsiM,10153
147
147
  claude_mpm/commands/mpm-status.md,sha256=oaM4ybL4ffp55nkT9F0mp_5H4tF-wX9mbqK-LEKEqUU,1919
@@ -766,7 +766,7 @@ claude_mpm/services/version_control/version_parser.py,sha256=DbNncYZKKy9--ZUCO9g
766
766
  claude_mpm/services/visualization/__init__.py,sha256=cTtWxRi07rSLXQKVZa7SKZsYfj6nRouw7HVO85Towfg,401
767
767
  claude_mpm/services/visualization/mermaid_generator.py,sha256=6QGgXtMg_N9rKeRn8wYs3IxuWGKdDVAwFMFWKfIw9s4,34277
768
768
  claude_mpm/storage/__init__.py,sha256=DXnmee6iGqC6ctFLW7_Ty1cVCjYDFuCMkwO4EV0i25k,274
769
- claude_mpm/storage/state_storage.py,sha256=YCkqifFbv-lm6zzb53WOoArKJDVsLlSgvAM3FoRwhz8,16886
769
+ claude_mpm/storage/state_storage.py,sha256=6jEZ4z35MjtAuTTUdqETTy4_dbMMK8EN_C2kVa62PjY,16811
770
770
  claude_mpm/tools/__init__.py,sha256=T3GuCYNAHtjVcKCeivY674PaDm48WX96AriQfTKUknY,347
771
771
  claude_mpm/tools/__main__.py,sha256=MtpJoWA2HEmRE_XDsSjjto6DND7Ft0MZoiY4ivNHh5A,5714
772
772
  claude_mpm/tools/code_tree_analyzer.py,sha256=BBkEuSVHd_P1jBlxpBfzsLqUyT01rid3r2_cQCBeGyQ,64818
@@ -787,6 +787,7 @@ claude_mpm/utils/environment_context.py,sha256=mCnRJqQLTyaAv-7M4bp9N9WqVgfSQb5xb
787
787
  claude_mpm/utils/error_handler.py,sha256=RWL7DnXttJKCgYhevUm9XlMC33rEhX2CXo1IiCtwV4g,7969
788
788
  claude_mpm/utils/file_utils.py,sha256=pv3MEKLsn4WIOra5JoHnCm_FaJbNcKMuS3EKuXAWyLc,7859
789
789
  claude_mpm/utils/framework_detection.py,sha256=dCY-N0HzuYS9KBg1BjDw8mJnNb22JqmKBoodjTMzd5w,1183
790
+ claude_mpm/utils/git_analyzer.py,sha256=JZwahnhgPXsITRnq7jJBNK4or82bZjazQI-VGyXocP4,9323
790
791
  claude_mpm/utils/import_migration_example.py,sha256=sKlV-apfkHDJzzez6uubHXjx91YF_5HPuzu2sLs_U0E,989
791
792
  claude_mpm/utils/imports.py,sha256=IGcW0W6V-2jTmkVlO-l0Zodo3LRA3zkaumD9J2qn7dE,6654
792
793
  claude_mpm/utils/log_cleanup.py,sha256=1d8K1V2uOFPGJJKFOk6E_AMj22sifAibOg-VQyGooWo,22301
@@ -797,9 +798,9 @@ claude_mpm/utils/subprocess_utils.py,sha256=D0izRT8anjiUb_JG72zlJR_JAw1cDkb7kalN
797
798
  claude_mpm/validation/__init__.py,sha256=YZhwE3mhit-lslvRLuwfX82xJ_k4haZeKmh4IWaVwtk,156
798
799
  claude_mpm/validation/agent_validator.py,sha256=GprtAvu80VyMXcKGsK_VhYiXWA6BjKHv7O6HKx0AB9w,20917
799
800
  claude_mpm/validation/frontmatter_validator.py,sha256=YpJlYNNYcV8u6hIOi3_jaRsDnzhbcQpjCBE6eyBKaFY,7076
800
- claude_mpm-4.10.0.dist-info/licenses/LICENSE,sha256=lpaivOlPuBZW1ds05uQLJJswy8Rp_HMNieJEbFlqvLk,1072
801
- claude_mpm-4.10.0.dist-info/METADATA,sha256=k0Zv4w5f9JRyt9zBPKr0C1Np9CetMfRascM9u-26Tgo,17967
802
- claude_mpm-4.10.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
803
- claude_mpm-4.10.0.dist-info/entry_points.txt,sha256=Vlw3GNi-OtTpKSrez04iNrPmxNxYDpIWxmJCxiZ5Tx8,526
804
- claude_mpm-4.10.0.dist-info/top_level.txt,sha256=1nUg3FEaBySgm8t-s54jK5zoPnu3_eY6EP6IOlekyHA,11
805
- claude_mpm-4.10.0.dist-info/RECORD,,
801
+ claude_mpm-4.11.1.dist-info/licenses/LICENSE,sha256=lpaivOlPuBZW1ds05uQLJJswy8Rp_HMNieJEbFlqvLk,1072
802
+ claude_mpm-4.11.1.dist-info/METADATA,sha256=Wgt4BuOeYfVIUCmhtlUQwLKtCF4RAC_AEnw1W0_5pmI,17967
803
+ claude_mpm-4.11.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
804
+ claude_mpm-4.11.1.dist-info/entry_points.txt,sha256=Vlw3GNi-OtTpKSrez04iNrPmxNxYDpIWxmJCxiZ5Tx8,526
805
+ claude_mpm-4.11.1.dist-info/top_level.txt,sha256=1nUg3FEaBySgm8t-s54jK5zoPnu3_eY6EP6IOlekyHA,11
806
+ claude_mpm-4.11.1.dist-info/RECORD,,