claude-mpm 5.6.36__py3-none-any.whl → 5.6.37__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 +1 -1
- claude_mpm/cli/startup.py +73 -9
- claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +4 -65
- {claude_mpm-5.6.36.dist-info → claude_mpm-5.6.37.dist-info}/METADATA +1 -1
- {claude_mpm-5.6.36.dist-info → claude_mpm-5.6.37.dist-info}/RECORD +11 -11
- {claude_mpm-5.6.36.dist-info → claude_mpm-5.6.37.dist-info}/WHEEL +0 -0
- {claude_mpm-5.6.36.dist-info → claude_mpm-5.6.37.dist-info}/entry_points.txt +0 -0
- {claude_mpm-5.6.36.dist-info → claude_mpm-5.6.37.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-5.6.36.dist-info → claude_mpm-5.6.37.dist-info}/licenses/LICENSE-FAQ.md +0 -0
- {claude_mpm-5.6.36.dist-info → claude_mpm-5.6.37.dist-info}/top_level.txt +0 -0
claude_mpm/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
5.6.
|
|
1
|
+
5.6.37
|
claude_mpm/cli/startup.py
CHANGED
|
@@ -13,6 +13,44 @@ import sys
|
|
|
13
13
|
from pathlib import Path
|
|
14
14
|
|
|
15
15
|
|
|
16
|
+
def cleanup_user_level_hooks() -> None:
|
|
17
|
+
"""Remove stale user-level hooks directory.
|
|
18
|
+
|
|
19
|
+
WHY: claude-mpm previously deployed hooks to ~/.claude/hooks/claude-mpm/
|
|
20
|
+
(user-level). This is now deprecated in favor of project-level hooks
|
|
21
|
+
configured in .claude/settings.local.json. Stale user-level hooks can
|
|
22
|
+
cause conflicts and confusion.
|
|
23
|
+
|
|
24
|
+
DESIGN DECISION: Runs early in startup, before project hook sync.
|
|
25
|
+
Non-blocking - failures are logged at debug level but don't prevent startup.
|
|
26
|
+
"""
|
|
27
|
+
import shutil
|
|
28
|
+
|
|
29
|
+
user_hooks_dir = Path.home() / ".claude" / "hooks" / "claude-mpm"
|
|
30
|
+
|
|
31
|
+
if not user_hooks_dir.exists():
|
|
32
|
+
return
|
|
33
|
+
|
|
34
|
+
try:
|
|
35
|
+
from ..core.logger import get_logger
|
|
36
|
+
|
|
37
|
+
logger = get_logger("startup")
|
|
38
|
+
logger.debug(f"Removing stale user-level hooks directory: {user_hooks_dir}")
|
|
39
|
+
|
|
40
|
+
shutil.rmtree(user_hooks_dir)
|
|
41
|
+
|
|
42
|
+
logger.debug("User-level hooks cleanup complete")
|
|
43
|
+
except Exception as e:
|
|
44
|
+
# Non-critical - log but don't fail startup
|
|
45
|
+
try:
|
|
46
|
+
from ..core.logger import get_logger
|
|
47
|
+
|
|
48
|
+
logger = get_logger("startup")
|
|
49
|
+
logger.debug(f"Failed to cleanup user-level hooks (non-fatal): {e}")
|
|
50
|
+
except Exception: # nosec B110
|
|
51
|
+
pass # Avoid any errors in error handling
|
|
52
|
+
|
|
53
|
+
|
|
16
54
|
def sync_hooks_on_startup(quiet: bool = False) -> bool:
|
|
17
55
|
"""Ensure hooks are up-to-date on startup.
|
|
18
56
|
|
|
@@ -20,7 +58,12 @@ def sync_hooks_on_startup(quiet: bool = False) -> bool:
|
|
|
20
58
|
Reinstalling hooks ensures the hook format matches the current code.
|
|
21
59
|
|
|
22
60
|
DESIGN DECISION: Shows brief status message on success for user awareness.
|
|
23
|
-
Failures are logged but don't prevent startup to ensure claude-mpm
|
|
61
|
+
Failures are logged but don't prevent startup to ensure claude-mpm
|
|
62
|
+
remains functional.
|
|
63
|
+
|
|
64
|
+
Workflow:
|
|
65
|
+
1. Cleanup stale user-level hooks (~/.claude/hooks/claude-mpm/)
|
|
66
|
+
2. Reinstall project-level hooks to .claude/settings.local.json
|
|
24
67
|
|
|
25
68
|
Args:
|
|
26
69
|
quiet: If True, suppress all output (used internally)
|
|
@@ -28,6 +71,9 @@ def sync_hooks_on_startup(quiet: bool = False) -> bool:
|
|
|
28
71
|
Returns:
|
|
29
72
|
bool: True if hooks were synced successfully, False otherwise
|
|
30
73
|
"""
|
|
74
|
+
# Step 1: Cleanup stale user-level hooks first
|
|
75
|
+
cleanup_user_level_hooks()
|
|
76
|
+
|
|
31
77
|
try:
|
|
32
78
|
from ..hooks.claude_hooks.installer import HookInstaller
|
|
33
79
|
|
|
@@ -1386,6 +1432,28 @@ def auto_install_chrome_devtools_on_startup():
|
|
|
1386
1432
|
# Continue execution - chrome-devtools installation failure shouldn't block startup
|
|
1387
1433
|
|
|
1388
1434
|
|
|
1435
|
+
def sync_deployment_on_startup(force_sync: bool = False) -> None:
|
|
1436
|
+
"""Consolidated deployment block: hooks + agents.
|
|
1437
|
+
|
|
1438
|
+
WHY: Groups all deployment tasks into a single logical block for clarity.
|
|
1439
|
+
This ensures hooks and agents are deployed together before other services.
|
|
1440
|
+
|
|
1441
|
+
Order:
|
|
1442
|
+
1. Hook cleanup (remove ~/.claude/hooks/claude-mpm/)
|
|
1443
|
+
2. Hook reinstall (update .claude/settings.local.json)
|
|
1444
|
+
3. Agent sync from remote Git sources
|
|
1445
|
+
|
|
1446
|
+
Args:
|
|
1447
|
+
force_sync: Force download even if cache is fresh (bypasses ETag).
|
|
1448
|
+
"""
|
|
1449
|
+
# Step 1-2: Hooks (cleanup + reinstall handled by sync_hooks_on_startup)
|
|
1450
|
+
sync_hooks_on_startup() # Shows "Syncing Claude Code hooks... ✓"
|
|
1451
|
+
|
|
1452
|
+
# Step 3: Agents from remote sources
|
|
1453
|
+
sync_remote_agents_on_startup(force_sync=force_sync)
|
|
1454
|
+
show_agent_summary() # Display agent counts after deployment
|
|
1455
|
+
|
|
1456
|
+
|
|
1389
1457
|
def run_background_services(force_sync: bool = False):
|
|
1390
1458
|
"""
|
|
1391
1459
|
Initialize all background services on startup.
|
|
@@ -1401,19 +1469,15 @@ def run_background_services(force_sync: bool = False):
|
|
|
1401
1469
|
Args:
|
|
1402
1470
|
force_sync: Force download even if cache is fresh (bypasses ETag).
|
|
1403
1471
|
"""
|
|
1404
|
-
#
|
|
1405
|
-
# RATIONALE: Hooks
|
|
1406
|
-
# This
|
|
1407
|
-
|
|
1472
|
+
# Consolidated deployment block: hooks + agents
|
|
1473
|
+
# RATIONALE: Hooks and agents are deployed together before other services
|
|
1474
|
+
# This ensures the deployment phase is complete before configuration checks
|
|
1475
|
+
sync_deployment_on_startup(force_sync=force_sync)
|
|
1408
1476
|
|
|
1409
1477
|
initialize_project_registry()
|
|
1410
1478
|
check_mcp_auto_configuration()
|
|
1411
1479
|
verify_mcp_gateway_startup()
|
|
1412
1480
|
check_for_updates_async()
|
|
1413
|
-
sync_remote_agents_on_startup(
|
|
1414
|
-
force_sync=force_sync
|
|
1415
|
-
) # Sync agents from remote sources
|
|
1416
|
-
show_agent_summary() # Display agent counts after deployment
|
|
1417
1481
|
|
|
1418
1482
|
# Skills deployment order (precedence: remote > bundled)
|
|
1419
1483
|
# 1. Deploy bundled skills first (base layer from package)
|
|
Binary file
|
|
@@ -17,7 +17,7 @@ import subprocess # nosec B404 - subprocess used for safe claude CLI version ch
|
|
|
17
17
|
import uuid
|
|
18
18
|
from datetime import datetime, timezone
|
|
19
19
|
from pathlib import Path
|
|
20
|
-
from typing import Any,
|
|
20
|
+
from typing import Any, Optional
|
|
21
21
|
|
|
22
22
|
# Import _log helper to avoid stderr writes (which cause hook errors)
|
|
23
23
|
try:
|
|
@@ -109,25 +109,6 @@ def _get_config() -> Optional[Any]:
|
|
|
109
109
|
return _config
|
|
110
110
|
|
|
111
111
|
|
|
112
|
-
# Autotodos function (for pending todos injection)
|
|
113
|
-
_get_pending_todos_fn: Optional[Callable] = None
|
|
114
|
-
_get_pending_todos_loaded = False
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
def _get_pending_todos_func() -> Optional[Callable]:
|
|
118
|
-
"""Get get_pending_todos function with lazy loading."""
|
|
119
|
-
global _get_pending_todos_fn, _get_pending_todos_loaded
|
|
120
|
-
if not _get_pending_todos_loaded:
|
|
121
|
-
try:
|
|
122
|
-
from claude_mpm.cli.commands.autotodos import get_pending_todos
|
|
123
|
-
|
|
124
|
-
_get_pending_todos_fn = get_pending_todos
|
|
125
|
-
except ImportError:
|
|
126
|
-
_get_pending_todos_fn = None
|
|
127
|
-
_get_pending_todos_loaded = True
|
|
128
|
-
return _get_pending_todos_fn
|
|
129
|
-
|
|
130
|
-
|
|
131
112
|
# Delegation detector (for anti-pattern detection)
|
|
132
113
|
_delegation_detector: Optional[Any] = None
|
|
133
114
|
_delegation_detector_loaded = False
|
|
@@ -186,7 +167,6 @@ class EventHandlers:
|
|
|
186
167
|
config: Optional[Any] = None,
|
|
187
168
|
delegation_detector: Optional[Any] = None,
|
|
188
169
|
event_log: Optional[Any] = None,
|
|
189
|
-
get_pending_todos_fn: Optional[Callable] = None,
|
|
190
170
|
):
|
|
191
171
|
"""Initialize with reference to the main hook handler and optional services.
|
|
192
172
|
|
|
@@ -196,7 +176,6 @@ class EventHandlers:
|
|
|
196
176
|
config: Optional Config for autotodos configuration
|
|
197
177
|
delegation_detector: Optional DelegationDetector for anti-pattern detection
|
|
198
178
|
event_log: Optional EventLog for PM violation logging
|
|
199
|
-
get_pending_todos_fn: Optional function to get pending todos
|
|
200
179
|
"""
|
|
201
180
|
self.hook_handler = hook_handler
|
|
202
181
|
|
|
@@ -205,7 +184,6 @@ class EventHandlers:
|
|
|
205
184
|
self._config = config
|
|
206
185
|
self._delegation_detector = delegation_detector
|
|
207
186
|
self._event_log = event_log
|
|
208
|
-
self._get_pending_todos_fn = get_pending_todos_fn
|
|
209
187
|
|
|
210
188
|
@property
|
|
211
189
|
def log_manager(self) -> Optional[Any]:
|
|
@@ -235,18 +213,6 @@ class EventHandlers:
|
|
|
235
213
|
return self._event_log
|
|
236
214
|
return _get_event_log_service()
|
|
237
215
|
|
|
238
|
-
def get_pending_todos(
|
|
239
|
-
self, max_todos: int = 10, working_dir: Optional[Path] = None
|
|
240
|
-
) -> list:
|
|
241
|
-
"""Get pending todos (using injected function or lazy loaded)."""
|
|
242
|
-
fn = self._get_pending_todos_fn or _get_pending_todos_func()
|
|
243
|
-
if fn is None:
|
|
244
|
-
return []
|
|
245
|
-
try:
|
|
246
|
-
return fn(max_todos=max_todos, working_dir=working_dir)
|
|
247
|
-
except Exception:
|
|
248
|
-
return []
|
|
249
|
-
|
|
250
216
|
def handle_user_prompt_fast(self, event):
|
|
251
217
|
"""Handle user prompt with comprehensive data capture.
|
|
252
218
|
|
|
@@ -1119,7 +1085,9 @@ class EventHandlers:
|
|
|
1119
1085
|
- Provides visibility into new conversation sessions
|
|
1120
1086
|
- Enables tracking of session lifecycle and duration
|
|
1121
1087
|
- Useful for monitoring concurrent sessions and resource usage
|
|
1122
|
-
|
|
1088
|
+
|
|
1089
|
+
NOTE: This handler is intentionally lightweight - only event monitoring.
|
|
1090
|
+
All initialization/deployment logic runs in MPM CLI startup, not here.
|
|
1123
1091
|
"""
|
|
1124
1092
|
session_id = event.get("session_id", "")
|
|
1125
1093
|
working_dir = event.get("cwd", "")
|
|
@@ -1133,35 +1101,6 @@ class EventHandlers:
|
|
|
1133
1101
|
"hook_event_name": "SessionStart",
|
|
1134
1102
|
}
|
|
1135
1103
|
|
|
1136
|
-
# Auto-inject pending autotodos if enabled
|
|
1137
|
-
# Uses injected config and get_pending_todos or lazy-loaded instances
|
|
1138
|
-
config = self.config
|
|
1139
|
-
if config is not None:
|
|
1140
|
-
try:
|
|
1141
|
-
auto_inject_enabled = config.get(
|
|
1142
|
-
"autotodos.auto_inject_on_startup", True
|
|
1143
|
-
)
|
|
1144
|
-
max_todos = config.get("autotodos.max_todos_per_session", 10)
|
|
1145
|
-
|
|
1146
|
-
if auto_inject_enabled:
|
|
1147
|
-
# Pass working directory from event to avoid Path.cwd() issues
|
|
1148
|
-
working_dir_param = None
|
|
1149
|
-
if working_dir:
|
|
1150
|
-
working_dir_param = Path(working_dir)
|
|
1151
|
-
|
|
1152
|
-
pending_todos = self.get_pending_todos(
|
|
1153
|
-
max_todos=max_todos, working_dir=working_dir_param
|
|
1154
|
-
)
|
|
1155
|
-
if pending_todos:
|
|
1156
|
-
session_start_data["pending_autotodos"] = pending_todos
|
|
1157
|
-
session_start_data["autotodos_count"] = len(pending_todos)
|
|
1158
|
-
_log(
|
|
1159
|
-
f" - Auto-injected {len(pending_todos)} pending autotodos"
|
|
1160
|
-
)
|
|
1161
|
-
except Exception as e: # nosec B110
|
|
1162
|
-
# Auto-injection is optional - continue if it fails
|
|
1163
|
-
_log(f" - Failed to auto-inject autotodos: {e}")
|
|
1164
|
-
|
|
1165
1104
|
# Debug logging
|
|
1166
1105
|
_log(f"Hook handler: Processing SessionStart - session: '{session_id}'")
|
|
1167
1106
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
claude_mpm/BUILD_NUMBER,sha256=9JfxhnDtr-8l3kCP2U5TVXSErptHoga8m7XA8zqgGOc,4
|
|
2
|
-
claude_mpm/VERSION,sha256=
|
|
2
|
+
claude_mpm/VERSION,sha256=6wU_GWy-ocN_lZJMsDrvXWts8AcQ_8tGO-otGNlaDwg,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
|
|
@@ -42,7 +42,7 @@ claude_mpm/cli/chrome_devtools_installer.py,sha256=efA_ZX1iR3oaJi3222079BQw6DEG8
|
|
|
42
42
|
claude_mpm/cli/executor.py,sha256=eerqDVszBfTm8N2FgreLr-132Jb9BVZGNrrukvb_b-I,15106
|
|
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=
|
|
45
|
+
claude_mpm/cli/startup.py,sha256=yqq44doFdcrR8f1pCPOAeLG-3kzmdWHaMEmk_uAhc5E,70361
|
|
46
46
|
claude_mpm/cli/startup_display.py,sha256=KI4GZ0uVoK7FXeK5jsS4JAyaKaKf5rCkY3h5tNeEY7M,17209
|
|
47
47
|
claude_mpm/cli/startup_logging.py,sha256=wHokzcCA0AJPxAqFrpY5PMOBh1iOhdhgP1gY1OvD0gY,29392
|
|
48
48
|
claude_mpm/cli/utils.py,sha256=5e3v-ow1gd-5nlad9OWCsL-3SRJcPjBJ9HS3zygwkiQ,8988
|
|
@@ -429,7 +429,7 @@ claude_mpm/hooks/claude_hooks/__init__.py,sha256=b4mud_g3S-3itHY_Dzpbb_SmdMEcJwt
|
|
|
429
429
|
claude_mpm/hooks/claude_hooks/auto_pause_handler.py,sha256=Fm8d_a0KJ1GBPPQ3xmQo-xp-j8xU2TGHTDohbySu0Cg,17184
|
|
430
430
|
claude_mpm/hooks/claude_hooks/connection_pool.py,sha256=vpi-XbVf61GWhh85tHBzubbOgbJly_I-5-QmsleND2M,8658
|
|
431
431
|
claude_mpm/hooks/claude_hooks/correlation_manager.py,sha256=3n-RxzqE8egG4max_NcpJgL9gzrBY6Ti529LrjleI1g,2033
|
|
432
|
-
claude_mpm/hooks/claude_hooks/event_handlers.py,sha256=
|
|
432
|
+
claude_mpm/hooks/claude_hooks/event_handlers.py,sha256=VJ4kY_GMZkVv8WBAII4GTfY4qxFgoKdXpMdhEbzt980,50344
|
|
433
433
|
claude_mpm/hooks/claude_hooks/hook_handler.py,sha256=AH0z6D06bo02UGyEdYlzll2EcELl-gmt8D42MPqu_SU,30459
|
|
434
434
|
claude_mpm/hooks/claude_hooks/hook_wrapper.sh,sha256=XYkdYtcM0nfnwYvMdyIFCasr80ry3uI5-fLYsLtDGw4,2214
|
|
435
435
|
claude_mpm/hooks/claude_hooks/installer.py,sha256=SvIgxRMocQxnqNF3ZQfKH8zA-1b4lpiCA4vCI0vWOZI,38065
|
|
@@ -439,7 +439,7 @@ claude_mpm/hooks/claude_hooks/tool_analysis.py,sha256=3_o2PP9D7wEMwLriCtIBOw0cj2
|
|
|
439
439
|
claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc,sha256=EGpgXqhPM0iRRZtCqHaLVQ6wDH42OH_M7Gt5GiFLyro,346
|
|
440
440
|
claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-311.pyc,sha256=lw3g7dHPcJ258xtcmbXOk-tCqVz0JAc5PZ10LUfG4Zo,20829
|
|
441
441
|
claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc,sha256=SQX5iiP9bQZkLL-cj_2tlGH7lpAzarO0mYal7btj3tc,3521
|
|
442
|
-
claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc,sha256=
|
|
442
|
+
claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc,sha256=rUcbnsARIgWenNkPv8LlHJBXmxTOExqgcwtBaBfGzg4,49040
|
|
443
443
|
claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc,sha256=NQtvV9vs1OMKQTZWRQrAie83y4Q61mJ-QFawC2GnsUQ,32799
|
|
444
444
|
claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc,sha256=1llucgjrun0H6q8V8_BXTHtkTiYAwNGyptluhoIi7ss,11185
|
|
445
445
|
claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc,sha256=E_pRoKx-mAB5gEv2_5TneMC_K10zj7FYCPwQPnPd88g,16228
|
|
@@ -1106,10 +1106,10 @@ claude_mpm/utils/subprocess_utils.py,sha256=D0izRT8anjiUb_JG72zlJR_JAw1cDkb7kalN
|
|
|
1106
1106
|
claude_mpm/validation/__init__.py,sha256=YZhwE3mhit-lslvRLuwfX82xJ_k4haZeKmh4IWaVwtk,156
|
|
1107
1107
|
claude_mpm/validation/agent_validator.py,sha256=GprtAvu80VyMXcKGsK_VhYiXWA6BjKHv7O6HKx0AB9w,20917
|
|
1108
1108
|
claude_mpm/validation/frontmatter_validator.py,sha256=YpJlYNNYcV8u6hIOi3_jaRsDnzhbcQpjCBE6eyBKaFY,7076
|
|
1109
|
-
claude_mpm-5.6.
|
|
1110
|
-
claude_mpm-5.6.
|
|
1111
|
-
claude_mpm-5.6.
|
|
1112
|
-
claude_mpm-5.6.
|
|
1113
|
-
claude_mpm-5.6.
|
|
1114
|
-
claude_mpm-5.6.
|
|
1115
|
-
claude_mpm-5.6.
|
|
1109
|
+
claude_mpm-5.6.37.dist-info/licenses/LICENSE,sha256=ca3y_Rk4aPrbF6f62z8Ht5MJM9OAvbGlHvEDcj9vUQ4,3867
|
|
1110
|
+
claude_mpm-5.6.37.dist-info/licenses/LICENSE-FAQ.md,sha256=TxfEkXVCK98RzDOer09puc7JVCP_q_bN4dHtZKHCMcM,5104
|
|
1111
|
+
claude_mpm-5.6.37.dist-info/METADATA,sha256=9S9VFtM7YgENEHeksusZFEuIArHYOdUV2KTV0ut4T9E,15245
|
|
1112
|
+
claude_mpm-5.6.37.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
1113
|
+
claude_mpm-5.6.37.dist-info/entry_points.txt,sha256=n-Uk4vwHPpuvu-g_I7-GHORzTnN_m6iyOsoLveKKD0E,228
|
|
1114
|
+
claude_mpm-5.6.37.dist-info/top_level.txt,sha256=1nUg3FEaBySgm8t-s54jK5zoPnu3_eY6EP6IOlekyHA,11
|
|
1115
|
+
claude_mpm-5.6.37.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|