claude-mpm 4.18.3__py3-none-any.whl → 4.20.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.

@@ -0,0 +1,352 @@
1
+ """Session Resume Helper Service.
2
+
3
+ WHY: This service provides automatic session resume detection and prompting for PM startup.
4
+ It detects paused sessions, calculates git changes since pause, and presents resumption
5
+ context to users.
6
+
7
+ DESIGN DECISIONS:
8
+ - Project-specific session storage (.claude-mpm/sessions/pause/)
9
+ - Non-blocking detection with graceful degradation
10
+ - Git change detection for context updates
11
+ - User-friendly prompts with time elapsed information
12
+ - Integration with existing SessionManager infrastructure
13
+ """
14
+
15
+ import json
16
+ import subprocess
17
+ from datetime import datetime, timezone
18
+ from pathlib import Path
19
+ from typing import Any, Dict, List, Optional, Tuple
20
+
21
+ from claude_mpm.core.logger import get_logger
22
+
23
+ logger = get_logger(__name__)
24
+
25
+
26
+ class SessionResumeHelper:
27
+ """Helper for automatic session resume detection and prompting."""
28
+
29
+ def __init__(self, project_path: Optional[Path] = None):
30
+ """Initialize session resume helper.
31
+
32
+ Args:
33
+ project_path: Project root path (default: current directory)
34
+ """
35
+ self.project_path = project_path or Path.cwd()
36
+ self.pause_dir = self.project_path / ".claude-mpm" / "sessions" / "pause"
37
+
38
+ def has_paused_sessions(self) -> bool:
39
+ """Check if there are any paused sessions.
40
+
41
+ Returns:
42
+ True if paused sessions exist, False otherwise
43
+ """
44
+ if not self.pause_dir.exists():
45
+ return False
46
+
47
+ # Look for session JSON files
48
+ session_files = list(self.pause_dir.glob("session-*.json"))
49
+ return len(session_files) > 0
50
+
51
+ def get_most_recent_session(self) -> Optional[Dict[str, Any]]:
52
+ """Get the most recent paused session.
53
+
54
+ Returns:
55
+ Session data dictionary or None if no sessions found
56
+ """
57
+ if not self.pause_dir.exists():
58
+ return None
59
+
60
+ # Find all session files
61
+ session_files = list(self.pause_dir.glob("session-*.json"))
62
+ if not session_files:
63
+ return None
64
+
65
+ # Sort by modification time (most recent first)
66
+ session_files.sort(key=lambda p: p.stat().st_mtime, reverse=True)
67
+
68
+ # Load the most recent session
69
+ try:
70
+ with session_files[0].open("r") as f:
71
+ session_data = json.load(f)
72
+ session_data["file_path"] = session_files[0]
73
+ return session_data
74
+ except Exception as e:
75
+ logger.error(f"Failed to load session file {session_files[0]}: {e}")
76
+ return None
77
+
78
+ def get_git_changes_since_pause(
79
+ self, paused_at: str, recent_commits: List[Dict[str, str]]
80
+ ) -> Tuple[int, List[Dict[str, str]]]:
81
+ """Calculate git changes since session was paused.
82
+
83
+ Args:
84
+ paused_at: ISO-8601 timestamp when session was paused
85
+ recent_commits: List of recent commits from session data
86
+
87
+ Returns:
88
+ Tuple of (new_commit_count, new_commits_list)
89
+ """
90
+ try:
91
+ # Parse pause timestamp
92
+ pause_time = datetime.fromisoformat(paused_at)
93
+
94
+ # Get commits since pause time
95
+ cmd = [
96
+ "git",
97
+ "log",
98
+ f'--since="{pause_time.isoformat()}"',
99
+ "--pretty=format:%h|%an|%ai|%s",
100
+ "--all",
101
+ ]
102
+
103
+ result = subprocess.run(
104
+ cmd,
105
+ cwd=self.project_path,
106
+ capture_output=True,
107
+ text=True,
108
+ check=False,
109
+ )
110
+
111
+ if result.returncode != 0:
112
+ logger.warning(f"Git log command failed: {result.stderr}")
113
+ return 0, []
114
+
115
+ # Parse commit output
116
+ new_commits = []
117
+ for line in result.stdout.strip().split("\n"):
118
+ if line:
119
+ parts = line.split("|", 3)
120
+ if len(parts) == 4:
121
+ new_commits.append(
122
+ {
123
+ "sha": parts[0],
124
+ "author": parts[1],
125
+ "timestamp": parts[2],
126
+ "message": parts[3],
127
+ }
128
+ )
129
+
130
+ return len(new_commits), new_commits
131
+
132
+ except Exception as e:
133
+ logger.error(f"Failed to get git changes: {e}")
134
+ return 0, []
135
+
136
+ def get_time_elapsed(self, paused_at: str) -> str:
137
+ """Calculate human-readable time elapsed since pause.
138
+
139
+ Args:
140
+ paused_at: ISO-8601 timestamp when session was paused
141
+
142
+ Returns:
143
+ Human-readable time string (e.g., "2 hours ago", "3 days ago")
144
+ """
145
+ try:
146
+ pause_time = datetime.fromisoformat(paused_at)
147
+ now = datetime.now(timezone.utc)
148
+
149
+ # Ensure pause_time is timezone-aware
150
+ if pause_time.tzinfo is None:
151
+ pause_time = pause_time.replace(tzinfo=timezone.utc)
152
+
153
+ delta = now - pause_time
154
+
155
+ # Calculate time components
156
+ days = delta.days
157
+ hours = delta.seconds // 3600
158
+ minutes = (delta.seconds % 3600) // 60
159
+
160
+ # Format human-readable string
161
+ if days > 0:
162
+ if days == 1:
163
+ return "1 day ago"
164
+ return f"{days} days ago"
165
+ if hours > 0:
166
+ if hours == 1:
167
+ return "1 hour ago"
168
+ return f"{hours} hours ago"
169
+ if minutes > 0:
170
+ if minutes == 1:
171
+ return "1 minute ago"
172
+ return f"{minutes} minutes ago"
173
+ return "just now"
174
+
175
+ except Exception as e:
176
+ logger.error(f"Failed to calculate time elapsed: {e}")
177
+ return "unknown time ago"
178
+
179
+ def format_resume_prompt(self, session_data: Dict[str, Any]) -> str:
180
+ """Format a user-friendly resume prompt.
181
+
182
+ Args:
183
+ session_data: Session data dictionary
184
+
185
+ Returns:
186
+ Formatted prompt string for display
187
+ """
188
+ try:
189
+ # Extract session information
190
+ paused_at = session_data.get("paused_at", "")
191
+ conversation = session_data.get("conversation", {})
192
+ git_context = session_data.get("git_context", {})
193
+
194
+ summary = conversation.get("summary", "No summary available")
195
+ accomplishments = conversation.get("accomplishments", [])
196
+ next_steps = conversation.get("next_steps", [])
197
+
198
+ # Calculate time elapsed
199
+ time_ago = self.get_time_elapsed(paused_at)
200
+
201
+ # Get git changes
202
+ recent_commits = git_context.get("recent_commits", [])
203
+ new_commit_count, new_commits = self.get_git_changes_since_pause(
204
+ paused_at, recent_commits
205
+ )
206
+
207
+ # Build prompt
208
+ lines = []
209
+ lines.append("\n" + "=" * 80)
210
+ lines.append("📋 PAUSED SESSION FOUND")
211
+ lines.append("=" * 80)
212
+ lines.append(f"\nPaused: {time_ago}")
213
+ lines.append(f"\nLast working on: {summary}")
214
+
215
+ if accomplishments:
216
+ lines.append("\nCompleted:")
217
+ for item in accomplishments[:5]: # Limit to first 5
218
+ lines.append(f" ✓ {item}")
219
+ if len(accomplishments) > 5:
220
+ lines.append(f" ... and {len(accomplishments) - 5} more")
221
+
222
+ if next_steps:
223
+ lines.append("\nNext steps:")
224
+ for item in next_steps[:5]: # Limit to first 5
225
+ lines.append(f" • {item}")
226
+ if len(next_steps) > 5:
227
+ lines.append(f" ... and {len(next_steps) - 5} more")
228
+
229
+ # Git changes information
230
+ if new_commit_count > 0:
231
+ lines.append(f"\nGit changes since pause: {new_commit_count} commits")
232
+ if new_commits:
233
+ lines.append("\nRecent commits:")
234
+ for commit in new_commits[:3]: # Show first 3
235
+ lines.append(
236
+ f" {commit['sha']} - {commit['message']} ({commit['author']})"
237
+ )
238
+ if len(new_commits) > 3:
239
+ lines.append(f" ... and {len(new_commits) - 3} more")
240
+ else:
241
+ lines.append("\nNo git changes since pause")
242
+
243
+ lines.append("\n" + "=" * 80)
244
+ lines.append(
245
+ "Use this context to resume work, or start fresh if not relevant."
246
+ )
247
+ lines.append("=" * 80 + "\n")
248
+
249
+ return "\n".join(lines)
250
+
251
+ except Exception as e:
252
+ logger.error(f"Failed to format resume prompt: {e}")
253
+ return "\n📋 Paused session found, but failed to format details.\n"
254
+
255
+ def check_and_display_resume_prompt(self) -> Optional[Dict[str, Any]]:
256
+ """Check for paused sessions and display resume prompt if found.
257
+
258
+ This is the main entry point for PM startup integration.
259
+
260
+ Returns:
261
+ Session data if found and user should resume, None otherwise
262
+ """
263
+ if not self.has_paused_sessions():
264
+ logger.debug("No paused sessions found")
265
+ return None
266
+
267
+ # Get most recent session
268
+ session_data = self.get_most_recent_session()
269
+ if not session_data:
270
+ logger.debug("Failed to load paused session data")
271
+ return None
272
+
273
+ # Display resume prompt
274
+ prompt_text = self.format_resume_prompt(session_data)
275
+ print(prompt_text)
276
+
277
+ # Return session data for PM to use
278
+ return session_data
279
+
280
+ def clear_session(self, session_data: Dict[str, Any]) -> bool:
281
+ """Clear a paused session after successful resume.
282
+
283
+ Args:
284
+ session_data: Session data dictionary with 'file_path' key
285
+
286
+ Returns:
287
+ True if successfully cleared, False otherwise
288
+ """
289
+ try:
290
+ file_path = session_data.get("file_path")
291
+ if not file_path or not isinstance(file_path, Path):
292
+ logger.error("Invalid session file path")
293
+ return False
294
+
295
+ if file_path.exists():
296
+ file_path.unlink()
297
+ logger.info(f"Cleared paused session: {file_path}")
298
+
299
+ # Also remove SHA256 checksum file if exists
300
+ sha_file = file_path.parent / f".{file_path.name}.sha256"
301
+ if sha_file.exists():
302
+ sha_file.unlink()
303
+ logger.debug(f"Cleared session checksum: {sha_file}")
304
+
305
+ return True
306
+ logger.warning(f"Session file not found: {file_path}")
307
+ return False
308
+
309
+ except Exception as e:
310
+ logger.error(f"Failed to clear session: {e}")
311
+ return False
312
+
313
+ def get_session_count(self) -> int:
314
+ """Get count of paused sessions.
315
+
316
+ Returns:
317
+ Number of paused sessions
318
+ """
319
+ if not self.pause_dir.exists():
320
+ return 0
321
+
322
+ session_files = list(self.pause_dir.glob("session-*.json"))
323
+ return len(session_files)
324
+
325
+ def list_all_sessions(self) -> List[Dict[str, Any]]:
326
+ """List all paused sessions sorted by most recent.
327
+
328
+ Returns:
329
+ List of session data dictionaries
330
+ """
331
+ if not self.pause_dir.exists():
332
+ return []
333
+
334
+ session_files = list(self.pause_dir.glob("session-*.json"))
335
+ if not session_files:
336
+ return []
337
+
338
+ # Sort by modification time (most recent first)
339
+ session_files.sort(key=lambda p: p.stat().st_mtime, reverse=True)
340
+
341
+ sessions = []
342
+ for session_file in session_files:
343
+ try:
344
+ with session_file.open("r") as f:
345
+ session_data = json.load(f)
346
+ session_data["file_path"] = session_file
347
+ sessions.append(session_data)
348
+ except Exception as e:
349
+ logger.error(f"Failed to load session {session_file}: {e}")
350
+ continue
351
+
352
+ return sessions
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: claude-mpm
3
- Version: 4.18.3
3
+ Version: 4.20.0
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
@@ -31,7 +31,7 @@ Requires-Dist: requests>=2.25.0
31
31
  Requires-Dist: flask>=3.0.0
32
32
  Requires-Dist: flask-cors>=4.0.0
33
33
  Requires-Dist: watchdog>=3.0.0
34
- Requires-Dist: python-socketio>=5.11.0
34
+ Requires-Dist: python-socketio>=5.14.0
35
35
  Requires-Dist: aiohttp>=3.9.0
36
36
  Requires-Dist: aiohttp-cors<0.8.0,>=0.7.0
37
37
  Requires-Dist: python-engineio>=4.8.0
@@ -75,7 +75,7 @@ Requires-Dist: sphinx>=7.2.0; extra == "docs"
75
75
  Requires-Dist: sphinx-rtd-theme>=1.3.0; extra == "docs"
76
76
  Requires-Dist: sphinx-autobuild>=2021.3.14; extra == "docs"
77
77
  Provides-Extra: monitor
78
- Requires-Dist: python-socketio>=5.11.0; extra == "monitor"
78
+ Requires-Dist: python-socketio>=5.14.0; extra == "monitor"
79
79
  Requires-Dist: aiohttp>=3.9.0; extra == "monitor"
80
80
  Requires-Dist: aiohttp-cors<0.8.0,>=0.7.0; extra == "monitor"
81
81
  Requires-Dist: python-engineio>=4.8.0; extra == "monitor"
@@ -281,11 +281,26 @@ Claude MPM includes 15 specialized agents:
281
281
 
282
282
  #### Core Development
283
283
  - **Engineer** - Software development and implementation
284
- - **Research** - Code analysis and research
284
+ - **Research** - Code analysis and research
285
285
  - **Documentation** - Documentation creation and maintenance
286
286
  - **QA** - Testing and quality assurance
287
287
  - **Security** - Security analysis and implementation
288
288
 
289
+ #### Language-Specific Engineers
290
+ - **Python Engineer (v2.3.0)** - Type-safe, async-first Python with SOA patterns for non-trivial applications
291
+ - Service-oriented architecture with ABC interfaces for applications
292
+ - Lightweight script patterns for automation and one-off tasks
293
+ - Clear decision criteria for when to use DI/SOA vs simple functions
294
+ - Dependency injection containers with auto-resolution
295
+ - Use for: Web applications, microservices, data pipelines (DI/SOA) or scripts, CLI tools, notebooks (simple functions)
296
+
297
+ - **Rust Engineer (v1.1.0)** - Memory-safe, high-performance systems with trait-based service architecture
298
+ - Dependency injection with traits (constructor injection, trait objects)
299
+ - Service-oriented architecture patterns (repository, builder)
300
+ - Decision criteria for when to use DI/SOA vs simple code
301
+ - Async programming with tokio and zero-cost abstractions
302
+ - Use for: Web services, microservices (DI/SOA) or CLI tools, scripts (simple code)
303
+
289
304
  #### Operations & Infrastructure
290
305
  - **Ops** - Operations and deployment with advanced git commit authority and security verification (v2.2.2+)
291
306
  - **Version Control** - Git and version management
@@ -1,5 +1,5 @@
1
1
  claude_mpm/BUILD_NUMBER,sha256=9JfxhnDtr-8l3kCP2U5TVXSErptHoga8m7XA8zqgGOc,4
2
- claude_mpm/VERSION,sha256=Q5Zpc7PYaq2Bzb0frfdpC9P0XLSuxcM8tmuczgbBofk,7
2
+ claude_mpm/VERSION,sha256=C9gaUpftPvOukwiH7PjBD1e1du-u0JmCJYt7-K3-k9I,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
@@ -9,14 +9,14 @@ claude_mpm/agents/BASE_AGENT_TEMPLATE.md,sha256=wFqZssWaeCGaW04yy7eScYOlqJmsu1Vh
9
9
  claude_mpm/agents/BASE_DOCUMENTATION.md,sha256=iGub94w3IRURz2PwT0YrfNegMlEzgZ9mzeWa_WBk1rA,1504
10
10
  claude_mpm/agents/BASE_ENGINEER.md,sha256=I7BusSGQfuV0uSkRBro51qzCzagUEPrXnndIElypPJk,24434
11
11
  claude_mpm/agents/BASE_OPS.md,sha256=azAjZTrj77IZIBgZxX2hcjPOQMznV0v6B4ZWNUhAT9g,7636
12
- claude_mpm/agents/BASE_PM.md,sha256=4asvm0xIxstAJFqZxC-eJKGSTGmgmzRQGWcoyzCfyQY,7292
12
+ claude_mpm/agents/BASE_PM.md,sha256=qUQKwQDfnvVgmfAyb159GezzD9DR61f9CyKG-4V_LK0,14549
13
13
  claude_mpm/agents/BASE_PROMPT_ENGINEER.md,sha256=DHw7KXA6Nw7RfTyQiY06B_hH6ng2meimhgUKpQp08MM,21736
14
14
  claude_mpm/agents/BASE_QA.md,sha256=YtaYJSjWDfmFS3B6PtNvog4L54_w5K1rvpV0yqLhP20,5347
15
15
  claude_mpm/agents/BASE_RESEARCH.md,sha256=2DZhDd5XxWWtsyNTBIwvtNWBu1JpFy5R5SAZDHh0otU,1690
16
16
  claude_mpm/agents/INSTRUCTIONS_OLD_DEPRECATED.md,sha256=zQZhrhVq9NLCtSjVX-aC0xcgueemSuPhKyv0SjEOyIQ,25852
17
17
  claude_mpm/agents/MEMORY.md,sha256=KbRwY_RYdOvTvFC2DD-ATfwjHkQWJ5PIjlGws_7RmjI,3307
18
18
  claude_mpm/agents/OUTPUT_STYLE.md,sha256=fF9ydZuOgewDUNmaqJR_O7QV-feKiJ9bgPgk0NNtg_w,14270
19
- claude_mpm/agents/PM_INSTRUCTIONS.md,sha256=_E-J-4USZcADyJZ2280gX-AO8mLgPmiO2Cyf-Klt-7k,37024
19
+ claude_mpm/agents/PM_INSTRUCTIONS.md,sha256=m8xKccB43RyghcuRA8ZUxxDCoiIJCz0OwC18a3BhRHI,38477
20
20
  claude_mpm/agents/WORKFLOW.md,sha256=vJ9iXCVqAaeM_yVlXxbcP3bsL210-1BI3ZAanvWv4hI,9085
21
21
  claude_mpm/agents/__init__.py,sha256=jRFxvV_DIZ-NdENa-703Xu3YpwvlQj6yv-mQ6FgmldM,3220
22
22
  claude_mpm/agents/agent-template.yaml,sha256=mRlz5Yd0SmknTeoJWgFkZXzEF5T7OmGBJGs2-KPT93k,1969
@@ -56,14 +56,14 @@ claude_mpm/agents/templates/pm_red_flags.md,sha256=spfVI3zO9hRFf50OgCn06Aa5opN-W
56
56
  claude_mpm/agents/templates/product_owner.json,sha256=l-o__umM5c8pNaLGyzkRlkUtnl73h_BkaMWnMlnrPr4,40177
57
57
  claude_mpm/agents/templates/project_organizer.json,sha256=J76f5g7SSkubs8hvN2h7GdSjvv-UDVYgQI1ozDFVfEc,9266
58
58
  claude_mpm/agents/templates/prompt-engineer.json,sha256=7aIGOEu1PnEsC32VpXu9k4RkM8H-QLBBtoQfNzHuONc,37666
59
- claude_mpm/agents/templates/python_engineer.json,sha256=iUkcpVbJeD72toU4I5HTcRP7SGPRfP3zyhZkHty0tlA,44199
59
+ claude_mpm/agents/templates/python_engineer.json,sha256=i_Q3rCZMM57h-m3KqsiAWZ__fBpED7Iaza2ZbdcyPKE,50088
60
60
  claude_mpm/agents/templates/qa.json,sha256=JBV9MNMaTatlwBQnB3hyeT0i9xkatrwC4-W8QNNcuWk,10788
61
61
  claude_mpm/agents/templates/react_engineer.json,sha256=O3gaWqQwpkVYxR7WJdnQ81ZuFAmLvIsGCinbARuQPBI,13370
62
62
  claude_mpm/agents/templates/refactoring_engineer.json,sha256=BybYP2ztusg4ehOv1JuAP0oAv8F3iwW_CV9gmboLTwU,12283
63
63
  claude_mpm/agents/templates/research.json,sha256=tbhNU-FU-KpTtrPru4dyjnyoRAhXahS4UgWo7ny1yWY,14382
64
64
  claude_mpm/agents/templates/response_format.md,sha256=p7TZBKaeJZsYWUmF7bB1TyMuYoWdf3--Pccttn-51gU,21354
65
65
  claude_mpm/agents/templates/ruby-engineer.json,sha256=_kNFYfJiH9Vgmuh2X3FeEC7JfZokriUU9UGH4FT3pHc,12631
66
- claude_mpm/agents/templates/rust_engineer.json,sha256=GMedaY3MFnUVYyCBVMHYK4LMZT7xLE1UxQ3rCaKQun8,12536
66
+ claude_mpm/agents/templates/rust_engineer.json,sha256=A5P46_ZQu64WW3dYMmQPGy2SF8DsY2L2tC2iU0l7Zpo,20227
67
67
  claude_mpm/agents/templates/security.json,sha256=c8_2hwccYOlrTlU97NH0RSg_8bA2dYT3U_FkGGnujNo,24646
68
68
  claude_mpm/agents/templates/svelte-engineer.json,sha256=laJkAr0LSMKCfXXwvOvlgQF5Wst9uAPrybTZMK49f3o,17900
69
69
  claude_mpm/agents/templates/ticketing.json,sha256=be4J8CUF4HY7pKo-MTSzrQB-Jqk1VXEoLta3t-25e5c,11985
@@ -127,7 +127,7 @@ claude_mpm/cli/commands/mcp_setup_external.py,sha256=hfBHkaioNa0JRDhahNEc8agyrUw
127
127
  claude_mpm/cli/commands/mcp_tool_commands.py,sha256=q17GzlFT3JiLTrDqwPO2tz1-fKmPO5QU449syTnKTz4,1283
128
128
  claude_mpm/cli/commands/memory.py,sha256=mMUedUGep-FL0bapjNCJbcLn0eDLsr4-bMVYtW3wSLE,27198
129
129
  claude_mpm/cli/commands/monitor.py,sha256=Fjb68hf3dEwTFek2LV8Nh6iU0qEkY7qYlOn32IwNaNg,9566
130
- claude_mpm/cli/commands/mpm_init.py,sha256=INqb5o07xiTfLUKcHMllI-fE7C10iJc1XQWFdlxMAxY,75833
130
+ claude_mpm/cli/commands/mpm_init.py,sha256=SE0UVhxguvQt7575Ci5re_tonNRYl0s_7HIlwJjZcps,78865
131
131
  claude_mpm/cli/commands/mpm_init_handler.py,sha256=zKAat8KD8evsodDxF5T_EXqWYYxVY7umO3Y5gwPU7WQ,4737
132
132
  claude_mpm/cli/commands/run.py,sha256=PB2H55piOPTy4yo4OBgbUCjMlcz9K79wbwpxQVc9m5Q,48225
133
133
  claude_mpm/cli/commands/search.py,sha256=alv6udvKcn-xkqeBlLuPRvfSDV1yxEX4n9mjjRT5uLM,16581
@@ -174,7 +174,7 @@ claude_mpm/commands/mpm-auto-configure.md,sha256=vJtXiaEiujmozhKhqU8GsO95gHLs0QQ
174
174
  claude_mpm/commands/mpm-config.md,sha256=79Eb-srRpEVV3HCHDHZc8SKec6_LVP6HbXDEVkZKLgw,2929
175
175
  claude_mpm/commands/mpm-doctor.md,sha256=ut5LhFKVRw-2ecjMSPsnaTiRuFXa6Q9t-Wgl3CCnQvk,590
176
176
  claude_mpm/commands/mpm-help.md,sha256=8lo0mvhAjFI124hAGX4G8iwkz1k3xDv2QT2Jbyqeg_8,6891
177
- claude_mpm/commands/mpm-init.md,sha256=wwYHkToq8U5ALdhu8bDPygqAsKZ77aMaai7ZJC3oBqU,16054
177
+ claude_mpm/commands/mpm-init.md,sha256=ahPXWBR7x7_A028Bk9zrRk0Q36DbvCX2jhiMXTsdW7E,19716
178
178
  claude_mpm/commands/mpm-monitor.md,sha256=onTHf9Yac1KkdZdENtY2Q5jyw0A-vZLYgoKkPCtZLUY,12193
179
179
  claude_mpm/commands/mpm-organize.md,sha256=T-ysjhwgfW9irjUj02vuY_1jeMdabO_zxcShyjmqsiM,10153
180
180
  claude_mpm/commands/mpm-status.md,sha256=oaM4ybL4ffp55nkT9F0mp_5H4tF-wX9mbqK-LEKEqUU,1919
@@ -402,13 +402,14 @@ claude_mpm/experimental/__init__.py,sha256=R_aclOvWpvSTHWAx9QXyg9OIPVK2dXT5tQJhx
402
402
  claude_mpm/experimental/cli_enhancements.py,sha256=PfAt-SI-crBoE0Dtx1JecpS5_6OT_0apJbo28KS6HUI,11541
403
403
  claude_mpm/generators/__init__.py,sha256=rG8vwF_BjPmeMKvyMXpUA8uJ-7mtW2HTNfalZzgRlNk,153
404
404
  claude_mpm/generators/agent_profile_generator.py,sha256=yTEFdZPUt4lAfXlQuIIxzRwOrWMaJhEJ3Z6Ofm48Rlc,5740
405
- claude_mpm/hooks/__init__.py,sha256=lLRTE1jvnHAMzwl0W-g-hcjo7C9GS-N7lDpZdpHYcB8,953
405
+ claude_mpm/hooks/__init__.py,sha256=T8VQOEtVW434xeN5J0W8qxqmBj5uE7moLqZ4cm8Uub0,1182
406
406
  claude_mpm/hooks/base_hook.py,sha256=wKbT_0g3dhvkA48pTz4GJpZQw8URhaT0LpZnCc7CEas,5026
407
407
  claude_mpm/hooks/instruction_reinforcement.py,sha256=ez7HE-7w6h744iLGe6X2UKaqt2NGf93P03ZCEzFE15I,11193
408
408
  claude_mpm/hooks/kuzu_enrichment_hook.py,sha256=jghoEZX8fA6HZ1kM_5l93cuCyy-AMBjWp-nPW5EgaTk,8729
409
409
  claude_mpm/hooks/kuzu_memory_hook.py,sha256=mWQYcQt3_6s0EjjK1zZ6rv4EaUI-lCgiUu5bbNry2Zs,12696
410
410
  claude_mpm/hooks/kuzu_response_hook.py,sha256=iyVrsOrGpp-VFOjKC5GUnXro088Ftex-vHmfHsmAUv8,6136
411
411
  claude_mpm/hooks/memory_integration_hook.py,sha256=F8Hf35hmbmhxi-qHQJac4zoWIr60ob3PCHa4P_rbxO8,16635
412
+ claude_mpm/hooks/session_resume_hook.py,sha256=0D0Yn30IYXqYPLzHitqiZ3i3hwUIFQGJk6bxXfYb67E,3784
412
413
  claude_mpm/hooks/tool_call_interceptor.py,sha256=tYUBJHjbtaI5-HSWcz0aeUW0CaiQPypuDOTULQ0BCNI,7506
413
414
  claude_mpm/hooks/validation_hooks.py,sha256=i5uOaXifItwJfIdjjLCxAwrkKdkmo2Qa4qMc5-dwsKw,6465
414
415
  claude_mpm/hooks/claude_hooks/__init__.py,sha256=b4mud_g3S-3itHY_Dzpbb_SmdMEcJwtUU8fTcqpLqqs,130
@@ -577,7 +578,9 @@ claude_mpm/services/cli/agent_output_formatter.py,sha256=FcJ18m3CyeFr_wotJfEmIUR
577
578
  claude_mpm/services/cli/agent_validation_service.py,sha256=QtpP9GOwCD2wW40winh5NDrYXXLiFd_CXFUBWeYiMCk,21746
578
579
  claude_mpm/services/cli/memory_crud_service.py,sha256=tU0zegxba5lhpOCGqLijN2NfEMLwnEoYyjaF5cZ1A90,22863
579
580
  claude_mpm/services/cli/memory_output_formatter.py,sha256=iNXMSu-K24rkgVhJURS-B6GqUBxR1XEZg8ZewOll0SU,24796
581
+ claude_mpm/services/cli/resume_service.py,sha256=ENlx5ynuw1bBuPX6XOinOizLqWGNAlSUOu--oV_hrRs,21758
580
582
  claude_mpm/services/cli/session_manager.py,sha256=-zG0osFnDYyta9iPCwmL5Dxu6Z-4_LHylFfqQAnIEvY,20126
583
+ claude_mpm/services/cli/session_resume_helper.py,sha256=w42iyGatfWCQCB1JmaL-HMjICJvca-iPL6yIZpzstMM,12177
581
584
  claude_mpm/services/cli/startup_checker.py,sha256=MmztJ7yAnk5O5shArGDzRzwBDmx1WikhtE5s9P4IU9M,12251
582
585
  claude_mpm/services/cli/unified_dashboard_manager.py,sha256=LH45wbiKn5GqEZWPH-18TQnsisR3vQchvSnxa-_CDZI,15607
583
586
  claude_mpm/services/communication/__init__.py,sha256=b4qc7_Rqy4DE9q7BAUlfUZjoYG4uimAyUnE0irPcXyU,560
@@ -886,9 +889,9 @@ claude_mpm/utils/subprocess_utils.py,sha256=D0izRT8anjiUb_JG72zlJR_JAw1cDkb7kalN
886
889
  claude_mpm/validation/__init__.py,sha256=YZhwE3mhit-lslvRLuwfX82xJ_k4haZeKmh4IWaVwtk,156
887
890
  claude_mpm/validation/agent_validator.py,sha256=GprtAvu80VyMXcKGsK_VhYiXWA6BjKHv7O6HKx0AB9w,20917
888
891
  claude_mpm/validation/frontmatter_validator.py,sha256=YpJlYNNYcV8u6hIOi3_jaRsDnzhbcQpjCBE6eyBKaFY,7076
889
- claude_mpm-4.18.3.dist-info/licenses/LICENSE,sha256=lpaivOlPuBZW1ds05uQLJJswy8Rp_HMNieJEbFlqvLk,1072
890
- claude_mpm-4.18.3.dist-info/METADATA,sha256=Y03L0BmDQCSMbwp5WhxA8b1ZR-OjCMivxy2roQkXPPc,22476
891
- claude_mpm-4.18.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
892
- claude_mpm-4.18.3.dist-info/entry_points.txt,sha256=Vlw3GNi-OtTpKSrez04iNrPmxNxYDpIWxmJCxiZ5Tx8,526
893
- claude_mpm-4.18.3.dist-info/top_level.txt,sha256=1nUg3FEaBySgm8t-s54jK5zoPnu3_eY6EP6IOlekyHA,11
894
- claude_mpm-4.18.3.dist-info/RECORD,,
892
+ claude_mpm-4.20.0.dist-info/licenses/LICENSE,sha256=lpaivOlPuBZW1ds05uQLJJswy8Rp_HMNieJEbFlqvLk,1072
893
+ claude_mpm-4.20.0.dist-info/METADATA,sha256=-OduKfJpVe--_73SzHskXFsYxvA0TAZRrGb6DQHHs_E,23459
894
+ claude_mpm-4.20.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
895
+ claude_mpm-4.20.0.dist-info/entry_points.txt,sha256=Vlw3GNi-OtTpKSrez04iNrPmxNxYDpIWxmJCxiZ5Tx8,526
896
+ claude_mpm-4.20.0.dist-info/top_level.txt,sha256=1nUg3FEaBySgm8t-s54jK5zoPnu3_eY6EP6IOlekyHA,11
897
+ claude_mpm-4.20.0.dist-info/RECORD,,