claude-mpm 5.4.95__py3-none-any.whl → 5.4.97__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/{CLAUDE_MPM_FOUNDERS_OUTPUT_STYLE.md → CLAUDE_MPM_RESEARCH_OUTPUT_STYLE.md} +14 -6
  3. claude_mpm/agents/PM_INSTRUCTIONS.md +7 -4
  4. claude_mpm/agents/templates/circuit-breakers.md +26 -17
  5. claude_mpm/cli/commands/autotodos.py +526 -0
  6. claude_mpm/cli/executor.py +88 -0
  7. claude_mpm/cli/parsers/base_parser.py +54 -1
  8. claude_mpm/cli/startup.py +3 -2
  9. claude_mpm/core/hook_manager.py +51 -3
  10. claude_mpm/core/output_style_manager.py +15 -5
  11. claude_mpm/hooks/claude_hooks/event_handlers.py +79 -0
  12. claude_mpm/hooks/claude_hooks/hook_handler.py +4 -3
  13. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +14 -77
  14. claude_mpm/services/delegation_detector.py +175 -0
  15. claude_mpm/services/event_log.py +317 -0
  16. {claude_mpm-5.4.95.dist-info → claude_mpm-5.4.97.dist-info}/METADATA +4 -2
  17. {claude_mpm-5.4.95.dist-info → claude_mpm-5.4.97.dist-info}/RECORD +22 -34
  18. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc +0 -0
  19. claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-311.pyc +0 -0
  20. claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc +0 -0
  21. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
  22. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
  23. claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
  24. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
  25. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
  26. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-311.pyc +0 -0
  27. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
  28. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager.cpython-311.pyc +0 -0
  29. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
  30. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-311.pyc +0 -0
  31. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
  32. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
  33. {claude_mpm-5.4.95.dist-info → claude_mpm-5.4.97.dist-info}/WHEEL +0 -0
  34. {claude_mpm-5.4.95.dist-info → claude_mpm-5.4.97.dist-info}/entry_points.txt +0 -0
  35. {claude_mpm-5.4.95.dist-info → claude_mpm-5.4.97.dist-info}/licenses/LICENSE +0 -0
  36. {claude_mpm-5.4.95.dist-info → claude_mpm-5.4.97.dist-info}/licenses/LICENSE-FAQ.md +0 -0
  37. {claude_mpm-5.4.95.dist-info → claude_mpm-5.4.97.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,175 @@
1
+ """Delegation Pattern Detector for PM outputs.
2
+
3
+ WHY this is needed:
4
+ - Detect when PM asks user to do something manually instead of delegating
5
+ - Convert manual instructions into actionable autotodos
6
+ - Enforce delegation principle in PM workflow
7
+ - Help PM recognize delegation opportunities
8
+
9
+ DESIGN DECISION: Pattern-based detection
10
+ - Simple regex patterns to catch common delegation anti-patterns
11
+ - Extract action items from PM's output
12
+ - Format as autotodos for PM to see and delegate properly
13
+ - Non-invasive - just surfaces patterns for review
14
+
15
+ Examples of patterns to detect:
16
+ - "Make sure .env.local is in your .gitignore"
17
+ - "You'll need to run npm install"
18
+ - "Please run the tests manually"
19
+ - "Remember to update the README"
20
+ - "Don't forget to commit your changes"
21
+ """
22
+
23
+ import re
24
+ from typing import Any, Dict, List, Tuple
25
+
26
+ from ..core.logger import get_logger
27
+
28
+ # Delegation anti-patterns with capture groups for action extraction
29
+ # Each pattern is (regex_pattern, todo_template)
30
+ # {match} in template will be replaced with captured text
31
+ USER_DELEGATION_PATTERNS: List[Tuple[str, str]] = [
32
+ # "Make sure (to) X" → "Verify: X"
33
+ (r"(?i)make sure (?:to |that |you )?(.+)", "Verify: {match}"),
34
+ # "You'll/will need to X" → "Task: X"
35
+ (r"(?i)you(?:'ll| will)? need to (.+)", "Task: {match}"),
36
+ # "Please run/execute/do X" → "Execute: X"
37
+ (r"(?i)please (?:run|execute|do) (.+)", "Execute: {match}"),
38
+ # "Remember to X" → "Task: X"
39
+ (r"(?i)remember to (.+)", "Task: {match}"),
40
+ # "Don't forget to X" → "Task: X"
41
+ (r"(?i)don'?t forget to (.+)", "Task: {match}"),
42
+ # "You should/can/could X" → "Suggested: X"
43
+ (r"(?i)you (?:should|can|could) (.+)", "Suggested: {match}"),
44
+ # "Be sure to X" → "Task: X"
45
+ (r"(?i)be sure to (.+)", "Task: {match}"),
46
+ # "Don't forget X" (without 'to') → "Task: X"
47
+ (r"(?i)don'?t forget (.+)", "Task: {match}"),
48
+ # "You may want to X" → "Suggested: X"
49
+ (r"(?i)you may want to (.+)", "Suggested: {match}"),
50
+ # "It's important to X" → "Task: X"
51
+ (r"(?i)it'?s important to (.+)", "Task: {match}"),
52
+ ]
53
+
54
+
55
+ class DelegationDetector:
56
+ """Detects delegation anti-patterns in PM outputs.
57
+
58
+ WHY this design:
59
+ - Pattern-based detection for common manual instruction phrases
60
+ - Extract actionable tasks from PM's text
61
+ - Format as autotodos for PM visibility
62
+ - Simple and extensible (add new patterns easily)
63
+ """
64
+
65
+ def __init__(self):
66
+ self.logger = get_logger("delegation_detector")
67
+
68
+ def detect_user_delegation(self, text: str) -> List[Dict[str, Any]]:
69
+ """Detect delegation anti-patterns in text.
70
+
71
+ Scans text for patterns where PM is asking user to do something
72
+ manually instead of delegating to an agent.
73
+
74
+ Args:
75
+ text: PM output text to scan
76
+
77
+ Returns:
78
+ List of detected patterns with:
79
+ - pattern_type: Type of pattern matched
80
+ - original_text: Original sentence matched
81
+ - suggested_todo: Formatted todo text
82
+ - action: Extracted action text
83
+ """
84
+ detections = []
85
+
86
+ # Split into sentences for better pattern matching
87
+ # Split on period followed by space/newline, or just newline
88
+ # This avoids splitting on periods in filenames like .env.local
89
+ sentences = re.split(r"(?:\.\s+|\n+)", text)
90
+
91
+ for sentence in sentences:
92
+ sentence = sentence.strip()
93
+ if not sentence:
94
+ continue
95
+
96
+ # Try each pattern
97
+ for pattern, todo_template in USER_DELEGATION_PATTERNS:
98
+ match = re.search(pattern, sentence, re.IGNORECASE)
99
+ if match:
100
+ # Extract the captured action
101
+ action = match.group(1).strip()
102
+
103
+ # Skip if action is too short (likely false positive)
104
+ if len(action) < 5:
105
+ continue
106
+
107
+ # Format todo using template
108
+ suggested_todo = todo_template.format(match=action)
109
+
110
+ # Determine pattern type from template prefix
111
+ pattern_type = todo_template.split(":")[0]
112
+
113
+ detection = {
114
+ "pattern_type": pattern_type,
115
+ "original_text": sentence.strip(),
116
+ "suggested_todo": suggested_todo,
117
+ "action": action,
118
+ }
119
+
120
+ detections.append(detection)
121
+ self.logger.debug(
122
+ f"Detected delegation pattern: {pattern_type} - {action}"
123
+ )
124
+
125
+ # Only match first pattern per sentence
126
+ break
127
+
128
+ return detections
129
+
130
+ def format_as_autotodo(self, detection: Dict[str, Any]) -> Dict[str, str]:
131
+ """Format a detection as an autotodo.
132
+
133
+ Args:
134
+ detection: Detection dict from detect_user_delegation
135
+
136
+ Returns:
137
+ Dictionary with todo fields (content, activeForm, status)
138
+ """
139
+ pattern_type = detection["pattern_type"]
140
+ suggested_todo = detection["suggested_todo"]
141
+ action = detection["action"]
142
+
143
+ # Create todo content
144
+ content = f"[Delegation] {suggested_todo}"
145
+
146
+ # Active form for in-progress display
147
+ active_form = f"Delegating: {action[:30]}..."
148
+
149
+ return {
150
+ "content": content,
151
+ "activeForm": active_form,
152
+ "status": "pending",
153
+ "metadata": {
154
+ "pattern_type": pattern_type,
155
+ "original_text": detection["original_text"],
156
+ "action": action,
157
+ "source": "delegation_detector",
158
+ },
159
+ }
160
+
161
+
162
+ # Global instance
163
+ _delegation_detector: DelegationDetector | None = None
164
+
165
+
166
+ def get_delegation_detector() -> DelegationDetector:
167
+ """Get the global delegation detector instance.
168
+
169
+ Returns:
170
+ DelegationDetector instance
171
+ """
172
+ global _delegation_detector
173
+ if _delegation_detector is None:
174
+ _delegation_detector = DelegationDetector()
175
+ return _delegation_detector
@@ -0,0 +1,317 @@
1
+ """Event Log Service for persistent event storage.
2
+
3
+ WHY this is needed:
4
+ - Decouple event producers from consumers
5
+ - Persist events for later processing (e.g., autotodos CLI)
6
+ - Enable event-driven architecture patterns
7
+ - Provide audit trail of system events
8
+
9
+ DESIGN DECISION: Simple JSON file storage because:
10
+ - Human-readable and inspectable
11
+ - No additional database dependencies
12
+ - Fast for small event volumes
13
+ - Easy to clear and manage
14
+ - Follows existing pattern (hook_error_memory)
15
+ """
16
+
17
+ import json
18
+ from datetime import datetime, timezone
19
+ from pathlib import Path
20
+ from typing import Any, Dict, List, Literal, Optional
21
+
22
+ from ..core.logger import get_logger
23
+
24
+ # Event status types
25
+ EventStatus = Literal["pending", "resolved", "archived"]
26
+
27
+ # Max message length to prevent file bloat
28
+ MAX_MESSAGE_LENGTH = 2000
29
+
30
+
31
+ class EventLog:
32
+ """Persistent event log with simple JSON storage.
33
+
34
+ WHY this design:
35
+ - Store events with timestamp, type, payload, status
36
+ - Support filtering by status and event type
37
+ - Prevent file bloat with message truncation
38
+ - Enable mark-as-resolved workflow
39
+ - Keep it simple - no complex queries needed
40
+ """
41
+
42
+ def __init__(self, log_file: Optional[Path] = None):
43
+ """Initialize event log.
44
+
45
+ Args:
46
+ log_file: Path to event log file (default: .claude-mpm/event_log.json)
47
+ """
48
+ self.logger = get_logger("event_log")
49
+
50
+ # Use default location if not specified
51
+ if log_file is None:
52
+ log_file = Path.cwd() / ".claude-mpm" / "event_log.json"
53
+
54
+ self.log_file = log_file
55
+ self.events: List[Dict[str, Any]] = self._load_events()
56
+
57
+ def _load_events(self) -> List[Dict[str, Any]]:
58
+ """Load events from disk.
59
+
60
+ Returns:
61
+ List of event records
62
+ """
63
+ if not self.log_file.exists():
64
+ return []
65
+
66
+ try:
67
+ content = self.log_file.read_text()
68
+ if not content.strip():
69
+ return []
70
+ data = json.loads(content)
71
+
72
+ # Validate structure
73
+ if not isinstance(data, list):
74
+ self.logger.warning("Event log is not a list, resetting")
75
+ return []
76
+
77
+ return data
78
+ except json.JSONDecodeError as e:
79
+ self.logger.warning(f"Failed to parse event log: {e}, resetting")
80
+ return []
81
+ except Exception as e:
82
+ self.logger.error(f"Error loading event log: {e}")
83
+ return []
84
+
85
+ def _save_events(self):
86
+ """Persist events to disk."""
87
+ try:
88
+ # Ensure directory exists
89
+ self.log_file.parent.mkdir(parents=True, exist_ok=True)
90
+
91
+ # Write with pretty formatting for human readability
92
+ self.log_file.write_text(json.dumps(self.events, indent=2))
93
+ except Exception as e:
94
+ self.logger.error(f"Failed to save event log: {e}")
95
+
96
+ def _truncate_message(self, message: str) -> str:
97
+ """Truncate message to prevent file bloat.
98
+
99
+ Args:
100
+ message: Message to truncate
101
+
102
+ Returns:
103
+ Truncated message with ellipsis if needed
104
+ """
105
+ if len(message) <= MAX_MESSAGE_LENGTH:
106
+ return message
107
+
108
+ return message[:MAX_MESSAGE_LENGTH] + "... (truncated)"
109
+
110
+ def append_event(
111
+ self,
112
+ event_type: str,
113
+ payload: Dict[str, Any],
114
+ status: EventStatus = "pending",
115
+ ) -> str:
116
+ """Append a new event to the log.
117
+
118
+ Args:
119
+ event_type: Type of event (e.g., "autotodo.error", "hook.error")
120
+ payload: Event data (will be truncated if too large)
121
+ status: Event status (default: "pending")
122
+
123
+ Returns:
124
+ Event ID (timestamp-based for simplicity)
125
+ """
126
+ # Truncate any message fields in payload
127
+ truncated_payload = payload.copy()
128
+ if "message" in truncated_payload:
129
+ truncated_payload["message"] = self._truncate_message(
130
+ str(truncated_payload["message"])
131
+ )
132
+ if "full_message" in truncated_payload:
133
+ truncated_payload["full_message"] = self._truncate_message(
134
+ str(truncated_payload["full_message"])
135
+ )
136
+
137
+ # Create event record
138
+ timestamp = datetime.now(timezone.utc).isoformat()
139
+ event = {
140
+ "id": timestamp, # Use timestamp as ID for simplicity
141
+ "timestamp": timestamp,
142
+ "event_type": event_type,
143
+ "payload": truncated_payload,
144
+ "status": status,
145
+ }
146
+
147
+ # Append and save
148
+ self.events.append(event)
149
+ self._save_events()
150
+
151
+ self.logger.debug(f"Appended event: {event_type} (status: {status})")
152
+ return timestamp
153
+
154
+ def list_events(
155
+ self,
156
+ event_type: Optional[str] = None,
157
+ status: Optional[EventStatus] = None,
158
+ limit: Optional[int] = None,
159
+ ) -> List[Dict[str, Any]]:
160
+ """List events with optional filtering.
161
+
162
+ Args:
163
+ event_type: Filter by event type (e.g., "autotodo.error")
164
+ status: Filter by status (e.g., "pending")
165
+ limit: Maximum number of events to return (most recent first)
166
+
167
+ Returns:
168
+ List of matching events
169
+ """
170
+ # Filter events
171
+ filtered = self.events
172
+
173
+ if event_type:
174
+ filtered = [e for e in filtered if e["event_type"] == event_type]
175
+
176
+ if status:
177
+ filtered = [e for e in filtered if e["status"] == status]
178
+
179
+ # Sort by timestamp (most recent first)
180
+ filtered = sorted(filtered, key=lambda e: e["timestamp"], reverse=True)
181
+
182
+ # Apply limit
183
+ if limit:
184
+ filtered = filtered[:limit]
185
+
186
+ return filtered
187
+
188
+ def mark_resolved(self, event_id: str) -> bool:
189
+ """Mark an event as resolved.
190
+
191
+ Args:
192
+ event_id: Event ID (timestamp)
193
+
194
+ Returns:
195
+ True if event was found and updated
196
+ """
197
+ for event in self.events:
198
+ if event["id"] == event_id:
199
+ event["status"] = "resolved"
200
+ event["resolved_at"] = datetime.now(timezone.utc).isoformat()
201
+ self._save_events()
202
+ self.logger.debug(f"Marked event resolved: {event_id}")
203
+ return True
204
+
205
+ return False
206
+
207
+ def mark_all_resolved(
208
+ self, event_type: Optional[str] = None, status: EventStatus = "pending"
209
+ ) -> int:
210
+ """Mark multiple events as resolved.
211
+
212
+ Args:
213
+ event_type: Optional filter by event type
214
+ status: Filter by current status (default: "pending")
215
+
216
+ Returns:
217
+ Number of events marked as resolved
218
+ """
219
+ count = 0
220
+ now = datetime.now(timezone.utc).isoformat()
221
+
222
+ for event in self.events:
223
+ # Check filters
224
+ if event["status"] != status:
225
+ continue
226
+ if event_type and event["event_type"] != event_type:
227
+ continue
228
+
229
+ # Mark resolved
230
+ event["status"] = "resolved"
231
+ event["resolved_at"] = now
232
+ count += 1
233
+
234
+ if count > 0:
235
+ self._save_events()
236
+ self.logger.debug(f"Marked {count} events as resolved")
237
+
238
+ return count
239
+
240
+ def clear_resolved(self, older_than_days: Optional[int] = None) -> int:
241
+ """Remove resolved events from the log.
242
+
243
+ Args:
244
+ older_than_days: Only clear events older than N days
245
+
246
+ Returns:
247
+ Number of events removed
248
+ """
249
+ if older_than_days:
250
+ # Calculate cutoff timestamp
251
+ from datetime import timedelta
252
+
253
+ cutoff = datetime.now(timezone.utc) - timedelta(days=older_than_days)
254
+ cutoff_iso = cutoff.isoformat()
255
+
256
+ # Keep events that are NOT resolved OR are newer than cutoff
257
+ before_count = len(self.events)
258
+ self.events = [
259
+ e
260
+ for e in self.events
261
+ if e["status"] != "resolved" or e.get("resolved_at", "") > cutoff_iso
262
+ ]
263
+ removed = before_count - len(self.events)
264
+ else:
265
+ # Remove all resolved events
266
+ before_count = len(self.events)
267
+ self.events = [e for e in self.events if e["status"] != "resolved"]
268
+ removed = before_count - len(self.events)
269
+
270
+ if removed > 0:
271
+ self._save_events()
272
+ self.logger.debug(f"Cleared {removed} resolved events")
273
+
274
+ return removed
275
+
276
+ def get_stats(self) -> Dict[str, Any]:
277
+ """Get event log statistics.
278
+
279
+ Returns:
280
+ Dictionary with event counts by status and type
281
+ """
282
+ stats = {
283
+ "total_events": len(self.events),
284
+ "by_status": {"pending": 0, "resolved": 0, "archived": 0},
285
+ "by_type": {},
286
+ "log_file": str(self.log_file),
287
+ }
288
+
289
+ for event in self.events:
290
+ # Count by status
291
+ status = event["status"]
292
+ stats["by_status"][status] = stats["by_status"].get(status, 0) + 1
293
+
294
+ # Count by type
295
+ event_type = event["event_type"]
296
+ stats["by_type"][event_type] = stats["by_type"].get(event_type, 0) + 1
297
+
298
+ return stats
299
+
300
+
301
+ # Global instance
302
+ _event_log: Optional[EventLog] = None
303
+
304
+
305
+ def get_event_log(log_file: Optional[Path] = None) -> EventLog:
306
+ """Get the global event log instance.
307
+
308
+ Args:
309
+ log_file: Optional custom log file path
310
+
311
+ Returns:
312
+ EventLog instance
313
+ """
314
+ global _event_log
315
+ if _event_log is None:
316
+ _event_log = EventLog(log_file)
317
+ return _event_log
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: claude-mpm
3
- Version: 5.4.95
3
+ Version: 5.4.97
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
@@ -118,7 +118,7 @@ A powerful orchestration framework for **Claude Code (CLI)** that enables multi-
118
118
 
119
119
  ## Who Should Use Claude MPM?
120
120
 
121
- - 👥 **[Non-Technical Users (Founders/PMs)](docs/usecases/non-technical-users.md)** - Understand and oversee your technical projects without coding experience
121
+ - 👥 **[Non-Technical Users (Founders/PMs)](docs/usecases/non-technical-users.md)** - Research and understand codebases using Research Mode - no coding experience required
122
122
  - 💻 **[Developers](docs/usecases/developers.md)** - Multi-agent development workflows with semantic code search and advanced features
123
123
  - 🏢 **[Teams](docs/usecases/teams.md)** - Collaboration patterns, session management, and coordinated workflows
124
124
 
@@ -195,6 +195,8 @@ ls ~/.claude/agents/ # Should show 47+ agents
195
195
 
196
196
  **💡 Recommended Partners**: Install [kuzu-memory](https://github.com/bobmatnyc/kuzu-memory) (persistent context) and [mcp-vector-search](https://github.com/bobmatnyc/mcp-vector-search) (semantic search) for enhanced capabilities.
197
197
 
198
+ **💡 Tool Version Management**: Use [ASDF version manager](docs/guides/asdf-tool-versions.md) to avoid Python/uv version conflicts across projects.
199
+
198
200
  ---
199
201
 
200
202
  ## Key Features
@@ -1,5 +1,5 @@
1
1
  claude_mpm/BUILD_NUMBER,sha256=9JfxhnDtr-8l3kCP2U5TVXSErptHoga8m7XA8zqgGOc,4
2
- claude_mpm/VERSION,sha256=0JeoCFczIlLGH6CYn2GOrGoBwq9pGSLDjFG7vSMIAL0,7
2
+ claude_mpm/VERSION,sha256=BdiMNKt3O_zm2CNWcenla-qyFB2MItaHAgpbSdn2wrk,7
3
3
  claude_mpm/__init__.py,sha256=AGfh00BHKvLYD-UVFw7qbKtl7NMRIzRXOWw7vEuZ-h4,2214
4
4
  claude_mpm/__main__.py,sha256=Ro5UBWBoQaSAIoSqWAr7zkbLyvi4sSy28WShqAhKJG0,723
5
5
  claude_mpm/constants.py,sha256=pz3lTrZZR5HhV3eZzYtIbtBwWo7iM6pkBHP_ixxmI6Y,6827
@@ -7,11 +7,11 @@ claude_mpm/init.py,sha256=YSA2f0evX8FvqyI2Zx_4tvhaw18FPSMlf5yqTR_ilPE,26394
7
7
  claude_mpm/ticket_wrapper.py,sha256=qe5xY579t7_7fK5nyeAfHN_fr7CXdeOD3jfXEc8-7yo,828
8
8
  claude_mpm/agents/BASE_AGENT.md,sha256=UWvKX5S5L2l68F_sn54otC_HDX5kTt8G4ionUcTVpGo,5645
9
9
  claude_mpm/agents/BASE_ENGINEER.md,sha256=I7BusSGQfuV0uSkRBro51qzCzagUEPrXnndIElypPJk,24434
10
- claude_mpm/agents/CLAUDE_MPM_FOUNDERS_OUTPUT_STYLE.md,sha256=d4hZRc2wG2XzLaIxl2eQgdeuW6115C_pm6MtqNHVtOc,12997
11
10
  claude_mpm/agents/CLAUDE_MPM_OUTPUT_STYLE.md,sha256=C61nb8szGeeGaXQd9-VPpL1t79G2pDoYlDsGv_JLOLk,4349
11
+ claude_mpm/agents/CLAUDE_MPM_RESEARCH_OUTPUT_STYLE.md,sha256=OIVDU0Ypw5qrXix9rmMDG4u0V4ePnYDlsu5AoTmfZzs,13294
12
12
  claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md,sha256=vneNW5vHjfKsRIukkuGbAnvnyp_-EC3qpFzHDdsMOwc,4796
13
13
  claude_mpm/agents/MEMORY.md,sha256=V1mGx5oEaLdN9AYLX3Xetslmr2Ja6vnLPATeEoR6bvw,3303
14
- claude_mpm/agents/PM_INSTRUCTIONS.md,sha256=_PeWJGuXrtmJVCGjaoiZufvChjWhpLNiEL2Qe-nXZDQ,33224
14
+ claude_mpm/agents/PM_INSTRUCTIONS.md,sha256=A0TBjt4sxwahevpnubh2wgVzKOisX2AluBiqyuolQ0E,33500
15
15
  claude_mpm/agents/WORKFLOW.md,sha256=BD5V5wNgz4C2gHPn4ekRmj4i7nn56s1ZF8YnhWBPkFw,3331
16
16
  claude_mpm/agents/__init__.py,sha256=3cCQh2Hf_-2F9XDT5In533Bw7oKuGIqZvOdBW7af6dY,3403
17
17
  claude_mpm/agents/agent-template.yaml,sha256=mRlz5Yd0SmknTeoJWgFkZXzEF5T7OmGBJGs2-KPT93k,1969
@@ -24,7 +24,7 @@ claude_mpm/agents/frontmatter_validator.py,sha256=H0R7rCrNdaok5q7yCxEX2uiIcELU28
24
24
  claude_mpm/agents/system_agent_config.py,sha256=19axX46jzvY6svETjfMaFyAYtgbQO2PRXKJ-VYnCPDk,24137
25
25
  claude_mpm/agents/templates/README.md,sha256=qqhKh10y2CGuoytQmqlQtXCa_RD1ZmeT0m24S5VPQnI,18511
26
26
  claude_mpm/agents/templates/__init__.py,sha256=kghxAWs3KvcAA9Esk3NI7caumYgW6fiW8vRO1-MEndU,2735
27
- claude_mpm/agents/templates/circuit-breakers.md,sha256=Dkk6uDfuv7TceNMbQp_3SkFULnh9uxOt4UVG-H-s958,48780
27
+ claude_mpm/agents/templates/circuit-breakers.md,sha256=K7_nvXWG6PEUDLdj1pqOU3Lj8_snoVN9TPCUavIZ4TA,49497
28
28
  claude_mpm/agents/templates/context-management-examples.md,sha256=ySVsHKB9rh--yP3oNo6Q0cprYb7eKuKOkVl7uIGvzUs,15025
29
29
  claude_mpm/agents/templates/git-file-tracking.md,sha256=r8qckL8pS2nIvZAImFgbjAzpaEhzV44B1lzz6V8Jg8M,18842
30
30
  claude_mpm/agents/templates/pm-examples.md,sha256=Y_A5cqQHWLX7gbLQ9Z5uCLyrkoMS-ewR5POG42pW7ZQ,16804
@@ -39,10 +39,10 @@ claude_mpm/agents/templates/validation-templates.md,sha256=Y4_D7dphQaKigZWqKWvJ4
39
39
  claude_mpm/cli/__init__.py,sha256=j5x0uyJ4bRrKY1V4626cQI66OZsBzRz6JN26gQBxYSQ,4568
40
40
  claude_mpm/cli/__main__.py,sha256=KSy-J-vbTM2yXHOjsBJNZ60I2CJ2i5QP5zxsZV7-cjo,997
41
41
  claude_mpm/cli/chrome_devtools_installer.py,sha256=efA_ZX1iR3oaJi3222079BQw6DEG8KYr2HVGtgVj2Gs,5637
42
- claude_mpm/cli/executor.py,sha256=1MQdNPNoIewSR1q8nXjJuES3zKEi_IqVcZQzt9bsxw8,10601
42
+ claude_mpm/cli/executor.py,sha256=BswSkXHYbkBFuy0Wg7h1YpPExwK9KZZiev_630EB4Nc,14004
43
43
  claude_mpm/cli/helpers.py,sha256=CypEhw0tbNH6_GzVTaQdi4w7ThCWO43Ep92YbJzPR4I,3638
44
44
  claude_mpm/cli/parser.py,sha256=Vqx9n-6Xo1uNhXR4rThmgWpZXTr0nOtkgDf3oMS9b0g,5855
45
- claude_mpm/cli/startup.py,sha256=pOFS4qtVAvfUEEsgSMi7vW9M_5b_mYtNwADXikoa2Y4,62961
45
+ claude_mpm/cli/startup.py,sha256=JyNv5YZa_xC6B8fmw-mNxv0XK-XhIWFibJUz72Tg2H8,63021
46
46
  claude_mpm/cli/startup_display.py,sha256=2b7cIow39gUFdJyarh9lv4uvnicnCWml-onUbKnGGWY,17132
47
47
  claude_mpm/cli/startup_logging.py,sha256=wHokzcCA0AJPxAqFrpY5PMOBh1iOhdhgP1gY1OvD0gY,29392
48
48
  claude_mpm/cli/utils.py,sha256=FSMPftBZM8MeUyTtiB63Lz7oFOgkzwTetQs58RbRb_Q,8785
@@ -58,6 +58,7 @@ claude_mpm/cli/commands/aggregate.py,sha256=v5JzzoWf6Omc4DaWfx_3gm5EWiUmUp6ps3Bd
58
58
  claude_mpm/cli/commands/analyze.py,sha256=NuSreG9PINgf_1_41adMT_sOXz-z695Zqjwef4OEc9w,19162
59
59
  claude_mpm/cli/commands/analyze_code.py,sha256=5FAoubjZbEO_GlErj3xNgNbJXBjhtqSOWE2FkhAzTaM,17256
60
60
  claude_mpm/cli/commands/auto_configure.py,sha256=0Suzil6O0SBNeHUCwHOkt2q7gfuXRTyUu2UC99cCG4Y,40567
61
+ claude_mpm/cli/commands/autotodos.py,sha256=xJbSp1JXe-uK9OIFxKeQmFkbHyLTfyW_c34jCuPsIRQ,18126
61
62
  claude_mpm/cli/commands/cleanup.py,sha256=RQikOGLuLFWXzjeoHArdr5FA4Pf7tSK9w2NXL4vCrok,19769
62
63
  claude_mpm/cli/commands/cleanup_orphaned_agents.py,sha256=JR8crvgrz7Sa6d-SI-gKywok5S9rwc_DzDVk_h85sVs,4467
63
64
  claude_mpm/cli/commands/config.py,sha256=2M9VUPYcQkBUCIyyB-v1qTL3xYvao9YI2l_JGBUDauA,23374
@@ -122,7 +123,7 @@ claude_mpm/cli/parsers/agents_parser.py,sha256=lJ_9M1IRHoNU9-WLXLqinxEmDk1rRL6Eh
122
123
  claude_mpm/cli/parsers/analyze_code_parser.py,sha256=cpJSMFbc3mqB4qrMBIEZiikzPekC2IQX-cjt9U2fHW4,5356
123
124
  claude_mpm/cli/parsers/analyze_parser.py,sha256=E00Ao0zwzbJPchs_AJt-aoQ7LQEtJPXRCNQ6Piivb4o,3908
124
125
  claude_mpm/cli/parsers/auto_configure_parser.py,sha256=CZOk_nJZrNtRo8WnYWQKdfXywq6l6ZLMHU7U9hA7A_4,3699
125
- claude_mpm/cli/parsers/base_parser.py,sha256=uyNDetdxV5WPH2Xmv8NqYS8NNw0LATpH5Z8iCrdpXWg,20053
126
+ claude_mpm/cli/parsers/base_parser.py,sha256=5Y-4nbn5KUC0KR6MliNH2Nf-o_s9xR76tBPFUE6D_lc,21865
126
127
  claude_mpm/cli/parsers/config_parser.py,sha256=i8kv6XWhftzZlEBruAl58Fl6IcyeOb7QVkfPeEayjCk,6255
127
128
  claude_mpm/cli/parsers/configure_parser.py,sha256=t3cwAQX3BfljDDRJH3i0LplpRprw5jdKcI9Uy3M8xtE,4382
128
129
  claude_mpm/cli/parsers/dashboard_parser.py,sha256=JBCM6v_iZhADr_Fwtk_d3up9AOod1avMab-vkNE61gE,3460
@@ -191,7 +192,7 @@ claude_mpm/core/factories.py,sha256=oVyUzNqKKM6vEOIn5YV0r08TjLnLkUWLcCZPpj8W8b8,
191
192
  claude_mpm/core/file_utils.py,sha256=ycbmSl4JflNGG3qcEnCLDeRYV1nceHn2SJVfGO8x1Qg,19937
192
193
  claude_mpm/core/framework_loader.py,sha256=72z8e35ha1TI-5IVwB58VaVnogkozr51DgVHSJKLxR0,21028
193
194
  claude_mpm/core/hook_error_memory.py,sha256=PHiSQWU4ek9IoqeiY8UixQrcshfVDEfegVVe-nM22EM,12842
194
- claude_mpm/core/hook_manager.py,sha256=FI5wfa1zczm_SJQXOtpL7BYKxVZD4BMXRbqCBZQkDdA,12974
195
+ claude_mpm/core/hook_manager.py,sha256=y_e4a0gKsHbOtfaobwdhnBSr2raHHAhKszRYbKo4i_4,14947
195
196
  claude_mpm/core/hook_performance_config.py,sha256=e7a7oFctkRhA3aPXMO5Wavr-E6ku7ikLxMzPU7P1-yg,5779
196
197
  claude_mpm/core/injectable_service.py,sha256=9N4mHt6a_PwoP0pQo-QhVTnXLJlgDCCOg358d0jPEs4,7384
197
198
  claude_mpm/core/instruction_reinforcement_hook.py,sha256=hSYvUp_ducWnhcKTkUbUoCLUb_yCzbIgsqEp7VpF9h0,9542
@@ -207,7 +208,7 @@ claude_mpm/core/mixins.py,sha256=vmZ7Nu2ZOnKjbhN07Ixk4noIej9nsJiknrp-Sclfu0A,534
207
208
  claude_mpm/core/oneshot_session.py,sha256=nA86Zk7W3Rh_yIhPuegFL7Xgc9S63vQ_MqfLk52doV0,21994
208
209
  claude_mpm/core/optimized_agent_loader.py,sha256=yevEwTZWzVeZYEJhV3czD45OU7ukJIaJos4MGnFP7YQ,15857
209
210
  claude_mpm/core/optimized_startup.py,sha256=U5I4f7PNYXCBOLbCkbWT2V2sv01T8iWP2Bw-f928Q9M,17927
210
- claude_mpm/core/output_style_manager.py,sha256=ynFLUliYKPuw3CWtTcJR7h0TDBE_5z2gwDT-XT_-Owk,17491
211
+ claude_mpm/core/output_style_manager.py,sha256=K3EY4w5wvvdjfzNSEZQxSYhzBCxAEexXQHHYAYR9Jcw,17931
211
212
  claude_mpm/core/pm_hook_interceptor.py,sha256=92C8TrpK-XVQD8BiXbqs8lSCX72PU0KZG5oAjhf8GOQ,11197
212
213
  claude_mpm/core/service_registry.py,sha256=QpmAMWCov8XXaxQwE7WiNbgv6u_CRjpKPB64kLYvZKk,11722
213
214
  claude_mpm/core/session_manager.py,sha256=iEDZWKBYHSu001nFX8vFvH33RvQOW0eIgomWhFM53sw,12078
@@ -335,34 +336,19 @@ claude_mpm/hooks/claude_hooks/__init__.py,sha256=b4mud_g3S-3itHY_Dzpbb_SmdMEcJwt
335
336
  claude_mpm/hooks/claude_hooks/auto_pause_handler.py,sha256=xDAQZ33I5OhGvtWvA9mxwVSoir9tM-aCvrWkSRdnVmU,17465
336
337
  claude_mpm/hooks/claude_hooks/connection_pool.py,sha256=vpi-XbVf61GWhh85tHBzubbOgbJly_I-5-QmsleND2M,8658
337
338
  claude_mpm/hooks/claude_hooks/correlation_manager.py,sha256=3n-RxzqE8egG4max_NcpJgL9gzrBY6Ti529LrjleI1g,2033
338
- claude_mpm/hooks/claude_hooks/event_handlers.py,sha256=70F3Ij0yN-0uPnZll7DTi6q5LrVQKG5-eAFb_aoDF54,42196
339
- claude_mpm/hooks/claude_hooks/hook_handler.py,sha256=5xMBg1iys7l5nGQ0m24uKAQk7mu_0CTWjlWwaC1pYQs,28395
339
+ claude_mpm/hooks/claude_hooks/event_handlers.py,sha256=ryhpNe9c8wzGb2p3s0kBjFxY8BsVlHjwCo9Xc5RQnhc,45520
340
+ claude_mpm/hooks/claude_hooks/hook_handler.py,sha256=R2RhUoRvI0q_EGu-d5L9bH7cGg5_OLDskQoNrl3JsU0,28504
340
341
  claude_mpm/hooks/claude_hooks/hook_wrapper.sh,sha256=4lG3TlLVoVfTJipPj1X_ICUlS-KpnkbUp1U3oSq80Bw,2476
341
342
  claude_mpm/hooks/claude_hooks/installer.py,sha256=VbvVGMcrmCXQB3Pf9zOdjeGET2AFqbUDMHDy5KXuvz0,30463
342
343
  claude_mpm/hooks/claude_hooks/memory_integration.py,sha256=73w7A5-3s5i1oYdkbEgw7qhgalQvSuJjfx6OFqfaw64,9963
343
344
  claude_mpm/hooks/claude_hooks/response_tracking.py,sha256=bgX4iVQqmX0L3_GHyKs1q4CSIjnavdxYnJZT0GaT4gs,17148
344
345
  claude_mpm/hooks/claude_hooks/tool_analysis.py,sha256=3_o2PP9D7wEMwLriCtIBOw0cj2fSZfepN7lI4P1meSQ,7862
345
- claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc,sha256=EGpgXqhPM0iRRZtCqHaLVQ6wDH42OH_M7Gt5GiFLyro,346
346
- claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-311.pyc,sha256=X7A8O4KPXkuDaLDFbF7Izi1qVDyS0tQjHVo1xy_HzNQ,21172
347
- claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc,sha256=SQX5iiP9bQZkLL-cj_2tlGH7lpAzarO0mYal7btj3tc,3521
348
- claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc,sha256=HOJFN4bPVYKDDLzcnLMMn5MBy6rQS3cqveDS6Zh2ifg,40994
349
- claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc,sha256=oanjwor2IoiY_AKIqZcuz3ex-Mp2OndP7VlvAn_4hMQ,30603
350
- claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc,sha256=9mpAKY4gNcbU5VvZ5tGbf2UM0uIEWdreKSUvVr_BKcM,33917
351
- claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc,sha256=YbwauQDKSGvXkT1972faalJLuxwyvq328DYQhkCnel0,10513
352
- claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc,sha256=-L-n4xvi1eHY48MdZ-7v249UaNfkuiIwfwxdPgxwd80,16730
353
- claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-311.pyc,sha256=ZjcNfNY5Ht6FhalPeh7M7OzMffcey5iF4AVjDDg9kak,10694
354
346
  claude_mpm/hooks/claude_hooks/services/__init__.py,sha256=OIYOKsUNw1BHYawOCp-KFK5kmQKuj92cCqCEPO0nwo0,585
355
347
  claude_mpm/hooks/claude_hooks/services/connection_manager.py,sha256=6MhoPiSQSkG5Xsb9KjPk_eu60h6-v5uNXjn6ry255aA,10452
356
- claude_mpm/hooks/claude_hooks/services/connection_manager_http.py,sha256=n14k1byOBbviu0nFab3q0gb7p6eMqGO8hS0b7Gt2JRg,10262
348
+ claude_mpm/hooks/claude_hooks/services/connection_manager_http.py,sha256=7YKEsD45us5SNnj-jpSyFBYbU0KrZ8FWoIdZDUeU2gI,7795
357
349
  claude_mpm/hooks/claude_hooks/services/duplicate_detector.py,sha256=Fh9LmEMsVmQM9t0U1v2l_fuBwvNpVkl_0EF8Wu5KLHQ,3882
358
350
  claude_mpm/hooks/claude_hooks/services/state_manager.py,sha256=QB0JPJQThTVg0TGRO3Dc_3y3bac-hkulgMqqzo_71ng,11189
359
351
  claude_mpm/hooks/claude_hooks/services/subagent_processor.py,sha256=nJw1ERCMxq23ioZ5DKwprmwO0fuvuqpdFHJ03XaMiDo,16052
360
- claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc,sha256=xBfLBSqnpcKfcQBWfh7xUm454g1lq1LvbO7SxGvcOPc,644
361
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager.cpython-311.pyc,sha256=Q40QpUbg9q_QHgv8kuYdQmRVjqcjewzYUC5BoaHinFo,10152
362
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc,sha256=bvZ_QcuI0j125Ebv8RzeWUh1BkuRTUfufGi0NV7HjuY,12359
363
- claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-311.pyc,sha256=Yy_REAUhJCiFjOhxeDb4v0qyEvEbUtCmXD9PAz40dhw,5321
364
- claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc,sha256=TPkEc-Zi3oNS5dCXBpGbSZwg_8RQvzNzd4pVx9B3WeM,12364
365
- claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc,sha256=WffRFbZrgwiOypPUMgcm_LT18AtyGckgDny5IXhkogg,15554
366
352
  claude_mpm/hooks/failure_learning/__init__.py,sha256=iJ80AKFHiT8DjIH2a72DQVJvL6nAFrizNA2yTKwZ4rw,1805
367
353
  claude_mpm/hooks/failure_learning/failure_detection_hook.py,sha256=KENoB5N-dBm5hb0SxeIZtCvNKbmG2BKHOJSrSO-3Z_I,7500
368
354
  claude_mpm/hooks/failure_learning/fix_detection_hook.py,sha256=XUk1bnBVLdfhQ9AMQSvGsTSeFQsKsVud2wbWX-Jjor8,7164
@@ -387,7 +373,9 @@ claude_mpm/services/async_session_logger.py,sha256=u8yw3EAhOEvuZfky3Snb9JOaZ9TWQ
387
373
  claude_mpm/services/claude_session_logger.py,sha256=c2SPLhAq0JaUIyCmg6RsylZ2upaaqlb88ETneuYo8O0,11162
388
374
  claude_mpm/services/command_deployment_service.py,sha256=GgSxRehQY-PR-yeztz9WP8w6cT5_8NO9bXfn0aTN1Lc,16685
389
375
  claude_mpm/services/command_handler_service.py,sha256=8iru6eRdQloXrGiE75E1zoUbD_Ajldu3sw17Yx772Lw,7280
376
+ claude_mpm/services/delegation_detector.py,sha256=ZpElqjhTbuEeeTjTMUsl-G1lHMJ9m1g-6orM3t7wNfM,6168
390
377
  claude_mpm/services/event_aggregator.py,sha256=V_5Wln1RzozLMDZawIPl5gSjIN5KHniNPaaSP11Lihc,20251
378
+ claude_mpm/services/event_log.py,sha256=B5nSpAUOYEOTuP1V-rCdX3rONKwUejtR19aJKIzwTKQ,9661
391
379
  claude_mpm/services/exceptions.py,sha256=5lVZETr_6-xk0ItH7BTfYUiX5RlckS1e8ah_UalYG9c,26475
392
380
  claude_mpm/services/hook_installer_service.py,sha256=x3H3bFVlmhK4Ue1K279f44lwMEw3W1p3zoETGfjIH_w,19708
393
381
  claude_mpm/services/hook_service.py,sha256=I6JILbackBsdvrDNQ9TeGSB7XNqozNRP26T4E9_ROtU,15693
@@ -995,10 +983,10 @@ claude_mpm/utils/subprocess_utils.py,sha256=D0izRT8anjiUb_JG72zlJR_JAw1cDkb7kalN
995
983
  claude_mpm/validation/__init__.py,sha256=YZhwE3mhit-lslvRLuwfX82xJ_k4haZeKmh4IWaVwtk,156
996
984
  claude_mpm/validation/agent_validator.py,sha256=GprtAvu80VyMXcKGsK_VhYiXWA6BjKHv7O6HKx0AB9w,20917
997
985
  claude_mpm/validation/frontmatter_validator.py,sha256=YpJlYNNYcV8u6hIOi3_jaRsDnzhbcQpjCBE6eyBKaFY,7076
998
- claude_mpm-5.4.95.dist-info/licenses/LICENSE,sha256=ca3y_Rk4aPrbF6f62z8Ht5MJM9OAvbGlHvEDcj9vUQ4,3867
999
- claude_mpm-5.4.95.dist-info/licenses/LICENSE-FAQ.md,sha256=TxfEkXVCK98RzDOer09puc7JVCP_q_bN4dHtZKHCMcM,5104
1000
- claude_mpm-5.4.95.dist-info/METADATA,sha256=o550yzbHbpsC3B7Z57MlMLkuOyukfwr1GNax9OY3etk,14185
1001
- claude_mpm-5.4.95.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1002
- claude_mpm-5.4.95.dist-info/entry_points.txt,sha256=n-Uk4vwHPpuvu-g_I7-GHORzTnN_m6iyOsoLveKKD0E,228
1003
- claude_mpm-5.4.95.dist-info/top_level.txt,sha256=1nUg3FEaBySgm8t-s54jK5zoPnu3_eY6EP6IOlekyHA,11
1004
- claude_mpm-5.4.95.dist-info/RECORD,,
986
+ claude_mpm-5.4.97.dist-info/licenses/LICENSE,sha256=ca3y_Rk4aPrbF6f62z8Ht5MJM9OAvbGlHvEDcj9vUQ4,3867
987
+ claude_mpm-5.4.97.dist-info/licenses/LICENSE-FAQ.md,sha256=TxfEkXVCK98RzDOer09puc7JVCP_q_bN4dHtZKHCMcM,5104
988
+ claude_mpm-5.4.97.dist-info/METADATA,sha256=hlWS-oaVXxxH2ac2RGflbYhcb3ohULWQYotGwtsqTSc,14349
989
+ claude_mpm-5.4.97.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
990
+ claude_mpm-5.4.97.dist-info/entry_points.txt,sha256=n-Uk4vwHPpuvu-g_I7-GHORzTnN_m6iyOsoLveKKD0E,228
991
+ claude_mpm-5.4.97.dist-info/top_level.txt,sha256=1nUg3FEaBySgm8t-s54jK5zoPnu3_eY6EP6IOlekyHA,11
992
+ claude_mpm-5.4.97.dist-info/RECORD,,