claude-mpm 5.4.85__py3-none-any.whl → 5.4.87__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 (102) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/PM_INSTRUCTIONS.md +47 -5
  3. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.B7S5qgOx.css +1 -0
  4. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.D3t4z6uz.css +1 -0
  5. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DmxopI1J.js → 14Ru8gxt.js} +1 -1
  6. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CDuw-vjf.js → 7ZAeO_Uj.js} +1 -1
  7. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/AeivYILh.js +1 -0
  8. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DaimHw_p.js → B06ALsCS.js} +1 -1
  9. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{bTOqqlTd.js → BCWDw8BF.js} +1 -1
  10. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Cs_tUR18.js → BS0ej2w8.js} +1 -1
  11. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DwBR2MJi.js → BVFqgd56.js} +1 -1
  12. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CzeYkLYB.js → BXs4CVzO.js} +2 -2
  13. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{BovzEFCE.js → B_fnSNFx.js} +1 -1
  14. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{iEWssX7S.js → BfMC7wDI.js} +1 -1
  15. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CyWMqx4W.js → BfXd4Xj4.js} +1 -1
  16. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CBBdVcY8.js → BnFPFynJ.js} +1 -1
  17. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{B0uc0UOD.js → BwpSELyW.js} +3 -3
  18. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{BPYeabCQ.js → C5Dg_JxJ.js} +1 -1
  19. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DLVjFsZ3.js → C7i47te_.js} +1 -1
  20. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CnA0NrzZ.js → C86quetY.js} +1 -1
  21. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{ZGh7QtNv.js → CDNOxKrg.js} +1 -1
  22. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{BIF9m_hv.js → CDi5wzaD.js} +1 -1
  23. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Be7GpZd6.js → CQ94FMOU.js} +1 -1
  24. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CzZX-COe.js → CT5eAo1x.js} +1 -1
  25. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{GYwsonyD.js → C_l0vq62.js} +1 -1
  26. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cn4nXAfg.js +1 -0
  27. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DI7hHRFL.js → CvWciI1W.js} +1 -1
  28. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{sQeU3Y1z.js → CyrTH56Q.js} +1 -1
  29. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Bh0LDWpI.js → CzkNB1Vu.js} +2 -2
  30. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DUrLdbGD.js → D0Fj1OdD.js} +1 -1
  31. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Dle-35c7.js → D1ARDjz0.js} +2 -2
  32. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{C4B-KCzX.js → D2nGpDRe.js} +1 -1
  33. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{BofRWZRR.js → DJN4AVXS.js} +1 -1
  34. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{B7RN905-.js → DJuK4-OP.js} +1 -1
  35. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{C30mlcqg.js → DLeM8wSV.js} +1 -1
  36. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{uuIeMWc-.js → DNI1jw9S.js} +1 -1
  37. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{C4JcI4KD.js → DOViuQX_.js} +1 -1
  38. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{D3k0OPJN.js → DOeJfApz.js} +1 -1
  39. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Cfqx1Qun.js → DTgfNBV9.js} +1 -1
  40. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CiIAseT4.js → DWDi9IaK.js} +5 -5
  41. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D_vpdI7l.js +325 -0
  42. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Dhb8PKl3.js → DdIDcQsD.js} +1 -1
  43. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DnL7ky1O.js +1 -0
  44. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DGkLK5U1.js → Dqtg3hb8.js} +1 -1
  45. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{eNVUfhuA.js → EKp_wsKE.js} +1 -1
  46. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{D9lljYKQ.js → MJf6AOIJ.js} +1 -1
  47. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{B7xVLGWV.js → NsEh4Ivo.js} +1 -1
  48. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/URSAF6IJ.js +24 -0
  49. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DZX00Y4g.js → WiqB4NUY.js} +1 -1
  50. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{bT1r9zLR.js → s04HIjWg.js} +1 -1
  51. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{C_Usid8X.js → vJiSSdpk.js} +2 -2
  52. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/{app.D6-I5TpK.js → app.CnXU_fEX.js} +2 -2
  53. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.CUaAfoQJ.js +1 -0
  54. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/{1.CgNOuw-d.js → 1.znyTz9u3.js} +1 -1
  55. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.CLVHDDxl.js +1 -0
  56. claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -1
  57. claude_mpm/dashboard/static/svelte-build/index.html +7 -7
  58. claude_mpm/hooks/claude_hooks/INTEGRATION_EXAMPLE.md +243 -0
  59. claude_mpm/hooks/claude_hooks/README_AUTO_PAUSE.md +403 -0
  60. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc +0 -0
  61. claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-311.pyc +0 -0
  62. claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc +0 -0
  63. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
  64. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
  65. claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
  66. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
  67. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
  68. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-311.pyc +0 -0
  69. claude_mpm/hooks/claude_hooks/auto_pause_handler.py +486 -0
  70. claude_mpm/hooks/claude_hooks/event_handlers.py +74 -1
  71. claude_mpm/hooks/claude_hooks/hook_handler.py +25 -3
  72. claude_mpm/hooks/claude_hooks/response_tracking.py +17 -1
  73. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
  74. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager.cpython-311.pyc +0 -0
  75. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
  76. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-311.pyc +0 -0
  77. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
  78. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
  79. claude_mpm/hooks/claude_hooks/services/subagent_processor.py +30 -6
  80. claude_mpm/hooks/session_resume_hook.py +85 -1
  81. claude_mpm/services/cli/__init__.py +3 -0
  82. claude_mpm/services/cli/incremental_pause_manager.py +561 -0
  83. claude_mpm/services/infrastructure/__init__.py +4 -0
  84. claude_mpm/services/infrastructure/context_usage_tracker.py +291 -0
  85. claude_mpm/services/infrastructure/resume_log_generator.py +24 -5
  86. {claude_mpm-5.4.85.dist-info → claude_mpm-5.4.87.dist-info}/METADATA +1 -1
  87. {claude_mpm-5.4.85.dist-info → claude_mpm-5.4.87.dist-info}/RECORD +93 -73
  88. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.DWzvg0-y.css +0 -1
  89. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.ThTw9_ym.css +0 -1
  90. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/5shd3_w0.js +0 -24
  91. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BKjSRqUr.js +0 -1
  92. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Da0KfYnO.js +0 -1
  93. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dfy6j1xT.js +0 -323
  94. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/RJiighC3.js +0 -1
  95. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.NWzMBYRp.js +0 -1
  96. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.C0GcWctS.js +0 -1
  97. /claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/{0.m1gL8KXf.js → 0.BuxSUm_s.js} +0 -0
  98. {claude_mpm-5.4.85.dist-info → claude_mpm-5.4.87.dist-info}/WHEEL +0 -0
  99. {claude_mpm-5.4.85.dist-info → claude_mpm-5.4.87.dist-info}/entry_points.txt +0 -0
  100. {claude_mpm-5.4.85.dist-info → claude_mpm-5.4.87.dist-info}/licenses/LICENSE +0 -0
  101. {claude_mpm-5.4.85.dist-info → claude_mpm-5.4.87.dist-info}/licenses/LICENSE-FAQ.md +0 -0
  102. {claude_mpm-5.4.85.dist-info → claude_mpm-5.4.87.dist-info}/top_level.txt +0 -0
@@ -67,7 +67,9 @@ class SubagentResponseProcessor:
67
67
  print(" - No stored sessions in delegation_requests!", file=sys.stderr)
68
68
 
69
69
  # Get agent type and other basic info
70
- agent_type, agent_id, reason = self._extract_basic_info(event, session_id)
70
+ agent_type, agent_id, reason, agent_type_inferred = self._extract_basic_info(
71
+ event, session_id
72
+ )
71
73
 
72
74
  # Always log SubagentStop events for debugging
73
75
  if DEBUG or agent_type != "unknown":
@@ -108,6 +110,7 @@ class SubagentResponseProcessor:
108
110
  working_dir,
109
111
  git_branch,
110
112
  structured_response,
113
+ agent_type_inferred,
111
114
  )
112
115
 
113
116
  # Debug log the processed data
@@ -117,11 +120,20 @@ class SubagentResponseProcessor:
117
120
  file=sys.stderr,
118
121
  )
119
122
 
120
- # Emit to /hook namespace with high priority
121
- self.connection_manager.emit_event("/hook", "subagent_stop", subagent_stop_data)
123
+ # Emit to default namespace (consistent with subagent_start)
124
+ self.connection_manager.emit_event("", "subagent_stop", subagent_stop_data)
125
+
126
+ def _extract_basic_info(
127
+ self, event: dict, session_id: str
128
+ ) -> Tuple[str, str, str, bool]:
129
+ """Extract basic info from the event.
130
+
131
+ Returns:
132
+ Tuple of (agent_type, agent_id, reason, agent_type_inferred)
133
+ - agent_type_inferred is True when defaulted to "pm"
134
+ """
135
+ agent_type_inferred = False
122
136
 
123
- def _extract_basic_info(self, event: dict, session_id: str) -> Tuple[str, str, str]:
124
- """Extract basic info from the event."""
125
137
  # First try to get agent type from our tracking
126
138
  agent_type = (
127
139
  self.state_manager.get_delegation_agent_type(session_id)
@@ -146,7 +158,17 @@ class SubagentResponseProcessor:
146
158
  elif "pm" in task_desc or "project" in task_desc:
147
159
  agent_type = "pm"
148
160
 
149
- return agent_type, agent_id, reason
161
+ # Default to "pm" if still unknown (main conversation doesn't use Task tool)
162
+ if agent_type == "unknown":
163
+ agent_type = "pm"
164
+ agent_type_inferred = True
165
+ if DEBUG:
166
+ print(
167
+ " - Inferred agent_type='pm' (no explicit type found)",
168
+ file=sys.stderr,
169
+ )
170
+
171
+ return agent_type, agent_id, reason, agent_type_inferred
150
172
 
151
173
  def _extract_structured_response(
152
174
  self, output: str, agent_type: str
@@ -338,10 +360,12 @@ class SubagentResponseProcessor:
338
360
  working_dir: str,
339
361
  git_branch: str,
340
362
  structured_response: Optional[dict],
363
+ agent_type_inferred: bool,
341
364
  ) -> dict:
342
365
  """Build the subagent stop data for event emission."""
343
366
  subagent_stop_data = {
344
367
  "agent_type": agent_type,
368
+ "agent_type_inferred": agent_type_inferred,
345
369
  "agent_id": agent_id,
346
370
  "reason": reason,
347
371
  "session_id": session_id,
@@ -8,8 +8,11 @@ DESIGN DECISIONS:
8
8
  - Non-blocking: doesn't prevent PM from starting if check fails
9
9
  - Displays context to stdout for user visibility
10
10
  - Integrates with existing session pause/resume infrastructure
11
+ - Checks for ACTIVE-PAUSE.jsonl (incremental auto-pause) before regular paused sessions
11
12
  """
12
13
 
14
+ import json
15
+ import sys
13
16
  from pathlib import Path
14
17
  from typing import Any, Dict, Optional
15
18
 
@@ -31,10 +34,83 @@ class SessionResumeStartupHook:
31
34
  self.project_path = project_path or Path.cwd()
32
35
  self.resume_helper = SessionResumeHelper(self.project_path)
33
36
  self._session_displayed = False
37
+ self.sessions_dir = self.project_path / ".claude-mpm" / "sessions"
38
+
39
+ def check_for_active_pause(self) -> Optional[Dict[str, Any]]:
40
+ """Check for an active incremental pause session.
41
+
42
+ Returns:
43
+ Pause session metadata if ACTIVE-PAUSE.jsonl exists, None otherwise
44
+ """
45
+ active_pause_path = self.sessions_dir / "ACTIVE-PAUSE.jsonl"
46
+
47
+ if not active_pause_path.exists():
48
+ logger.debug("No ACTIVE-PAUSE.jsonl found")
49
+ return None
50
+
51
+ try:
52
+ # Read JSONL file to get first and last actions
53
+ with active_pause_path.open("r") as f:
54
+ lines = f.readlines()
55
+
56
+ if not lines:
57
+ logger.warning("ACTIVE-PAUSE.jsonl is empty")
58
+ return None
59
+
60
+ # Parse first action (session start)
61
+ first_action = json.loads(lines[0])
62
+
63
+ # Parse last action (most recent)
64
+ last_action = json.loads(lines[-1]) if len(lines) > 1 else first_action
65
+
66
+ # Extract metadata
67
+ return {
68
+ "is_incremental": True,
69
+ "session_id": first_action.get("session_id"),
70
+ "started_at": first_action.get("timestamp"),
71
+ "context_at_start": first_action.get("data", {}).get(
72
+ "context_percentage", 0
73
+ ),
74
+ "current_context": last_action.get("context_percentage", 0),
75
+ "action_count": len(lines),
76
+ "file_path": str(active_pause_path),
77
+ }
78
+
79
+ except (json.JSONDecodeError, OSError, KeyError) as e:
80
+ logger.error(f"Failed to parse ACTIVE-PAUSE.jsonl: {e}", exc_info=True)
81
+ return None
82
+
83
+ def display_active_pause_warning(self, pause_info: Dict[str, Any]) -> None:
84
+ """Display warning about active incremental pause session.
85
+
86
+ Args:
87
+ pause_info: Pause session metadata from check_for_active_pause()
88
+ """
89
+ print("\n" + "=" * 60, file=sys.stderr)
90
+ print("⚠️ ACTIVE AUTO-PAUSE SESSION DETECTED", file=sys.stderr)
91
+ print("=" * 60, file=sys.stderr)
92
+ print(f"Session ID: {pause_info['session_id']}", file=sys.stderr)
93
+ print(f"Started at: {pause_info['started_at']}", file=sys.stderr)
94
+ print(
95
+ f"Context at pause: {pause_info['context_at_start']:.1%}", file=sys.stderr
96
+ )
97
+ print(f"Actions recorded: {pause_info['action_count']}", file=sys.stderr)
98
+ print(
99
+ "\nThis session was auto-paused due to high context usage.", file=sys.stderr
100
+ )
101
+ print("Options:", file=sys.stderr)
102
+ print(" 1. Continue (actions will be appended)", file=sys.stderr)
103
+ print(" 2. Use /mpm-init pause --finalize to create snapshot", file=sys.stderr)
104
+ print(" 3. Use /mpm-init pause --discard to abandon", file=sys.stderr)
105
+ print("=" * 60 + "\n", file=sys.stderr)
34
106
 
35
107
  def on_pm_startup(self) -> Optional[Dict[str, Any]]:
36
108
  """Execute on PM startup to check for paused sessions.
37
109
 
110
+ Checks in priority order:
111
+ 1. ACTIVE-PAUSE.jsonl (incremental auto-pause)
112
+ 2. Regular paused sessions (session-*.json)
113
+
38
114
  Returns:
39
115
  Session data if paused session found, None otherwise
40
116
  """
@@ -44,7 +120,15 @@ class SessionResumeStartupHook:
44
120
  logger.debug("Session already displayed, skipping")
45
121
  return None
46
122
 
47
- # Check for paused sessions
123
+ # PRIORITY 1: Check for active incremental pause FIRST
124
+ active_pause_info = self.check_for_active_pause()
125
+ if active_pause_info:
126
+ self.display_active_pause_warning(active_pause_info)
127
+ self._session_displayed = True
128
+ logger.info("Active pause session detected and displayed")
129
+ return active_pause_info
130
+
131
+ # PRIORITY 2: Fall back to regular paused sessions
48
132
  session_data = self.resume_helper.check_and_display_resume_prompt()
49
133
 
50
134
  if session_data:
@@ -5,6 +5,7 @@ Services specifically for CLI command support and utilities.
5
5
 
6
6
  from .agent_dependency_service import AgentDependencyService, IAgentDependencyService
7
7
  from .agent_validation_service import AgentValidationService, IAgentValidationService
8
+ from .incremental_pause_manager import IncrementalPauseManager, PauseAction
8
9
  from .startup_checker import IStartupChecker, StartupCheckerService, StartupWarning
9
10
 
10
11
  __all__ = [
@@ -13,6 +14,8 @@ __all__ = [
13
14
  "IAgentDependencyService",
14
15
  "IAgentValidationService",
15
16
  "IStartupChecker",
17
+ "IncrementalPauseManager",
18
+ "PauseAction",
16
19
  "StartupCheckerService",
17
20
  "StartupWarning",
18
21
  ]