claude-mpm 5.6.5__py3-none-any.whl → 5.6.9__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/commands/skill_source.py +51 -2
- claude_mpm/cli/commands/skills.py +5 -3
- claude_mpm/cli/parsers/skill_source_parser.py +4 -0
- claude_mpm/cli/parsers/skills_parser.py +5 -0
- claude_mpm/commander/api/errors.py +21 -0
- claude_mpm/commander/api/routes/sessions.py +18 -5
- claude_mpm/config/skill_sources.py +16 -0
- claude_mpm/core/config.py +27 -19
- claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-312.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-312.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-312.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-312.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-314.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-312.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-312.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-312.pyc +0 -0
- claude_mpm/hooks/claude_hooks/installer.py +41 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-312.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-312.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-312.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-312.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-314.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-312.pyc +0 -0
- claude_mpm/scripts/claude-hook-handler.sh +5 -5
- claude_mpm/services/agents/agent_selection_service.py +2 -2
- claude_mpm/services/agents/single_tier_deployment_service.py +4 -4
- claude_mpm/services/skills/git_skill_source_manager.py +79 -8
- claude_mpm/services/skills/selective_skill_deployer.py +28 -0
- claude_mpm/services/skills/skill_discovery_service.py +17 -1
- claude_mpm/services/skills_deployer.py +31 -5
- {claude_mpm-5.6.5.dist-info → claude_mpm-5.6.9.dist-info}/METADATA +1 -1
- {claude_mpm-5.6.5.dist-info → claude_mpm-5.6.9.dist-info}/RECORD +39 -26
- {claude_mpm-5.6.5.dist-info → claude_mpm-5.6.9.dist-info}/WHEEL +0 -0
- {claude_mpm-5.6.5.dist-info → claude_mpm-5.6.9.dist-info}/entry_points.txt +0 -0
- {claude_mpm-5.6.5.dist-info → claude_mpm-5.6.9.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-5.6.5.dist-info → claude_mpm-5.6.9.dist-info}/licenses/LICENSE-FAQ.md +0 -0
- {claude_mpm-5.6.5.dist-info → claude_mpm-5.6.9.dist-info}/top_level.txt +0 -0
claude_mpm/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
5.6.
|
|
1
|
+
5.6.9
|
|
@@ -11,6 +11,7 @@ for better UX. Handles errors gracefully with actionable messages.
|
|
|
11
11
|
|
|
12
12
|
import json
|
|
13
13
|
import logging
|
|
14
|
+
import os
|
|
14
15
|
import re
|
|
15
16
|
|
|
16
17
|
from ...config.skill_sources import SkillSource, SkillSourceConfiguration
|
|
@@ -20,6 +21,33 @@ from ...services.skills.skill_discovery_service import SkillDiscoveryService
|
|
|
20
21
|
logger = logging.getLogger(__name__)
|
|
21
22
|
|
|
22
23
|
|
|
24
|
+
def _get_github_token(source: SkillSource | None = None) -> str | None:
|
|
25
|
+
"""Get GitHub token with source-specific override support.
|
|
26
|
+
|
|
27
|
+
Priority: source.token > GITHUB_TOKEN > GH_TOKEN
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
source: Optional SkillSource to check for per-source token
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
GitHub token if found, None otherwise
|
|
34
|
+
|
|
35
|
+
Security Note:
|
|
36
|
+
Token is never logged or printed to avoid exposure.
|
|
37
|
+
"""
|
|
38
|
+
# Priority 1: Per-source token (env var reference or direct)
|
|
39
|
+
if source and source.token:
|
|
40
|
+
if source.token.startswith("$"):
|
|
41
|
+
# Env var reference: $VAR_NAME -> os.environ.get("VAR_NAME")
|
|
42
|
+
env_var_name = source.token[1:]
|
|
43
|
+
return os.environ.get(env_var_name)
|
|
44
|
+
# Direct token (not recommended but supported)
|
|
45
|
+
return source.token
|
|
46
|
+
|
|
47
|
+
# Priority 2-3: Global environment variables
|
|
48
|
+
return os.environ.get("GITHUB_TOKEN") or os.environ.get("GH_TOKEN")
|
|
49
|
+
|
|
50
|
+
|
|
23
51
|
def _test_skill_repository_access(source: SkillSource) -> dict:
|
|
24
52
|
"""Test if skill repository is accessible via GitHub API.
|
|
25
53
|
|
|
@@ -58,7 +86,13 @@ def _test_skill_repository_access(source: SkillSource) -> dict:
|
|
|
58
86
|
# Test GitHub API access
|
|
59
87
|
api_url = f"https://api.github.com/repos/{owner_repo}"
|
|
60
88
|
|
|
61
|
-
|
|
89
|
+
# Build headers with authentication if token available
|
|
90
|
+
headers = {"Accept": "application/vnd.github+json"}
|
|
91
|
+
token = _get_github_token(source)
|
|
92
|
+
if token:
|
|
93
|
+
headers["Authorization"] = f"token {token}"
|
|
94
|
+
|
|
95
|
+
response = requests.get(api_url, headers=headers, timeout=10)
|
|
62
96
|
|
|
63
97
|
if response.status_code == 200:
|
|
64
98
|
return {"accessible": True, "error": None}
|
|
@@ -68,9 +102,14 @@ def _test_skill_repository_access(source: SkillSource) -> dict:
|
|
|
68
102
|
"error": f"Repository not found: {owner_repo}",
|
|
69
103
|
}
|
|
70
104
|
if response.status_code == 403:
|
|
105
|
+
error_msg = "Access denied (private repository or rate limit)"
|
|
106
|
+
if not token:
|
|
107
|
+
error_msg += (
|
|
108
|
+
". Try setting GITHUB_TOKEN environment variable for private repos"
|
|
109
|
+
)
|
|
71
110
|
return {
|
|
72
111
|
"accessible": False,
|
|
73
|
-
"error":
|
|
112
|
+
"error": error_msg,
|
|
74
113
|
}
|
|
75
114
|
return {
|
|
76
115
|
"accessible": False,
|
|
@@ -263,6 +302,15 @@ def handle_add_skill_source(args) -> int:
|
|
|
263
302
|
|
|
264
303
|
# Create new source
|
|
265
304
|
enabled = not args.disabled
|
|
305
|
+
token = getattr(args, "token", None)
|
|
306
|
+
|
|
307
|
+
# Security warning for direct tokens
|
|
308
|
+
if token and not token.startswith("$"):
|
|
309
|
+
print("⚠️ Warning: Direct token values in config are not recommended")
|
|
310
|
+
print(" Consider using environment variable reference instead:")
|
|
311
|
+
print(" --token $MY_PRIVATE_TOKEN")
|
|
312
|
+
print()
|
|
313
|
+
|
|
266
314
|
source = SkillSource(
|
|
267
315
|
id=source_id,
|
|
268
316
|
type="git",
|
|
@@ -270,6 +318,7 @@ def handle_add_skill_source(args) -> int:
|
|
|
270
318
|
branch=args.branch,
|
|
271
319
|
priority=args.priority,
|
|
272
320
|
enabled=enabled,
|
|
321
|
+
token=token,
|
|
273
322
|
)
|
|
274
323
|
|
|
275
324
|
# Determine if we should test
|
|
@@ -538,6 +538,7 @@ class SkillsManagementCommand(BaseCommand):
|
|
|
538
538
|
toolchain = getattr(args, "toolchain", None)
|
|
539
539
|
categories = getattr(args, "categories", None)
|
|
540
540
|
force = getattr(args, "force", False)
|
|
541
|
+
deploy_all = getattr(args, "all", False)
|
|
541
542
|
|
|
542
543
|
if collection:
|
|
543
544
|
console.print(
|
|
@@ -548,14 +549,15 @@ class SkillsManagementCommand(BaseCommand):
|
|
|
548
549
|
"\n[bold cyan]Deploying skills from default collection...[/bold cyan]\n"
|
|
549
550
|
)
|
|
550
551
|
|
|
551
|
-
#
|
|
552
|
-
#
|
|
552
|
+
# Use selective deployment unless --all flag is provided
|
|
553
|
+
# Selective mode deploys only agent-referenced skills
|
|
554
|
+
# --all mode deploys all available skills from the collection
|
|
553
555
|
result = self.skills_deployer.deploy_skills(
|
|
554
556
|
collection=collection,
|
|
555
557
|
toolchain=toolchain,
|
|
556
558
|
categories=categories,
|
|
557
559
|
force=force,
|
|
558
|
-
selective=
|
|
560
|
+
selective=not deploy_all,
|
|
559
561
|
)
|
|
560
562
|
|
|
561
563
|
# Display results
|
|
@@ -76,6 +76,10 @@ def add_skill_source_subparser(subparsers) -> argparse.ArgumentParser:
|
|
|
76
76
|
dest="skip_test",
|
|
77
77
|
help="Skip immediate testing (not recommended)",
|
|
78
78
|
)
|
|
79
|
+
add_parser.add_argument(
|
|
80
|
+
"--token",
|
|
81
|
+
help="GitHub token or env var reference (e.g., ghp_xxx or $PRIVATE_TOKEN)",
|
|
82
|
+
)
|
|
79
83
|
|
|
80
84
|
# Remove repository
|
|
81
85
|
remove_parser = skill_source_subparsers.add_parser(
|
|
@@ -167,6 +167,11 @@ def add_skills_subparser(subparsers) -> argparse.ArgumentParser:
|
|
|
167
167
|
action="store_true",
|
|
168
168
|
help="Force redeployment of already deployed skills",
|
|
169
169
|
)
|
|
170
|
+
deploy_github_parser.add_argument(
|
|
171
|
+
"--all",
|
|
172
|
+
action="store_true",
|
|
173
|
+
help="Deploy all available skills, not just agent-referenced ones",
|
|
174
|
+
)
|
|
170
175
|
|
|
171
176
|
# List available GitHub skills
|
|
172
177
|
list_available_parser = skills_subparsers.add_parser(
|
|
@@ -110,3 +110,24 @@ class InvalidRuntimeError(CommanderAPIError):
|
|
|
110
110
|
f"Invalid runtime: {runtime}",
|
|
111
111
|
400,
|
|
112
112
|
)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
class TmuxNoSpaceError(CommanderAPIError):
|
|
116
|
+
"""Raised when tmux has no space for a new pane."""
|
|
117
|
+
|
|
118
|
+
def __init__(self, message: str | None = None):
|
|
119
|
+
"""Initialize tmux no space error.
|
|
120
|
+
|
|
121
|
+
Args:
|
|
122
|
+
message: Custom error message (optional)
|
|
123
|
+
"""
|
|
124
|
+
default_msg = (
|
|
125
|
+
"Unable to create session: tmux has no space for new pane. "
|
|
126
|
+
"Try closing some sessions or resize your terminal window. "
|
|
127
|
+
"You can also create a new tmux window with `tmux new-window`."
|
|
128
|
+
)
|
|
129
|
+
super().__init__(
|
|
130
|
+
"TMUX_NO_SPACE",
|
|
131
|
+
message or default_msg,
|
|
132
|
+
409,
|
|
133
|
+
)
|
|
@@ -5,13 +5,19 @@ This module implements REST endpoints for creating and managing tool sessions
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
import logging
|
|
8
|
+
import subprocess # nosec B404 - needed for tmux error handling
|
|
8
9
|
import uuid
|
|
9
10
|
from typing import List
|
|
10
11
|
|
|
11
12
|
from fastapi import APIRouter, Response
|
|
12
13
|
|
|
13
14
|
from ...models import ToolSession
|
|
14
|
-
from ..errors import
|
|
15
|
+
from ..errors import (
|
|
16
|
+
InvalidRuntimeError,
|
|
17
|
+
ProjectNotFoundError,
|
|
18
|
+
SessionNotFoundError,
|
|
19
|
+
TmuxNoSpaceError,
|
|
20
|
+
)
|
|
15
21
|
from ..schemas import CreateSessionRequest, SessionResponse
|
|
16
22
|
|
|
17
23
|
router = APIRouter()
|
|
@@ -112,6 +118,7 @@ async def create_session(project_id: str, req: CreateSessionRequest) -> SessionR
|
|
|
112
118
|
Raises:
|
|
113
119
|
ProjectNotFoundError: If project_id doesn't exist
|
|
114
120
|
InvalidRuntimeError: If runtime is not supported
|
|
121
|
+
TmuxNoSpaceError: If tmux has no space for new pane
|
|
115
122
|
|
|
116
123
|
Example:
|
|
117
124
|
POST /api/projects/abc-123/sessions
|
|
@@ -144,10 +151,16 @@ async def create_session(project_id: str, req: CreateSessionRequest) -> SessionR
|
|
|
144
151
|
session_id = str(uuid.uuid4())
|
|
145
152
|
|
|
146
153
|
# Create tmux pane for session
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
154
|
+
try:
|
|
155
|
+
tmux_target = tmux_orch.create_pane(
|
|
156
|
+
pane_id=f"{project.name}-{req.runtime}",
|
|
157
|
+
working_dir=project.path,
|
|
158
|
+
)
|
|
159
|
+
except subprocess.CalledProcessError as e:
|
|
160
|
+
stderr = e.stderr.decode() if e.stderr else ""
|
|
161
|
+
if "no space for new pane" in stderr.lower():
|
|
162
|
+
raise TmuxNoSpaceError() from None
|
|
163
|
+
raise # Re-raise other subprocess errors
|
|
151
164
|
|
|
152
165
|
# Create session object
|
|
153
166
|
session = ToolSession(
|
|
@@ -54,6 +54,7 @@ class SkillSource:
|
|
|
54
54
|
branch: Git branch to use (default: "main")
|
|
55
55
|
priority: Priority for skill resolution (lower = higher precedence)
|
|
56
56
|
enabled: Whether this source should be synced
|
|
57
|
+
token: Optional GitHub token or env var reference (e.g., "$MY_TOKEN")
|
|
57
58
|
|
|
58
59
|
Priority System:
|
|
59
60
|
- 0: Reserved for system repository (highest precedence)
|
|
@@ -61,6 +62,12 @@ class SkillSource:
|
|
|
61
62
|
- 100-999: Normal priority custom sources
|
|
62
63
|
- 1000+: Low priority custom sources
|
|
63
64
|
|
|
65
|
+
Token Authentication:
|
|
66
|
+
- Direct token: "ghp_xxxxx" (stored in config, not recommended)
|
|
67
|
+
- Env var reference: "$PRIVATE_REPO_TOKEN" (resolved at runtime)
|
|
68
|
+
- If None, falls back to GITHUB_TOKEN or GH_TOKEN env vars
|
|
69
|
+
- Priority: source.token > GITHUB_TOKEN > GH_TOKEN
|
|
70
|
+
|
|
64
71
|
Example:
|
|
65
72
|
>>> source = SkillSource(
|
|
66
73
|
... id="system",
|
|
@@ -70,6 +77,12 @@ class SkillSource:
|
|
|
70
77
|
... )
|
|
71
78
|
>>> source.validate()
|
|
72
79
|
[]
|
|
80
|
+
>>> private_source = SkillSource(
|
|
81
|
+
... id="private",
|
|
82
|
+
... type="git",
|
|
83
|
+
... url="https://github.com/myorg/private-skills",
|
|
84
|
+
... token="$PRIVATE_REPO_TOKEN"
|
|
85
|
+
... )
|
|
73
86
|
"""
|
|
74
87
|
|
|
75
88
|
id: str
|
|
@@ -78,6 +91,7 @@ class SkillSource:
|
|
|
78
91
|
branch: str = "main"
|
|
79
92
|
priority: int = 100
|
|
80
93
|
enabled: bool = True
|
|
94
|
+
token: Optional[str] = None
|
|
81
95
|
|
|
82
96
|
def __post_init__(self):
|
|
83
97
|
"""Validate skill source configuration after initialization.
|
|
@@ -262,6 +276,7 @@ class SkillSourceConfiguration:
|
|
|
262
276
|
branch=source_data.get("branch", "main"),
|
|
263
277
|
priority=source_data.get("priority", 100),
|
|
264
278
|
enabled=source_data.get("enabled", True),
|
|
279
|
+
token=source_data.get("token"),
|
|
265
280
|
)
|
|
266
281
|
sources.append(source)
|
|
267
282
|
except (KeyError, ValueError) as e:
|
|
@@ -326,6 +341,7 @@ class SkillSourceConfiguration:
|
|
|
326
341
|
"branch": source.branch,
|
|
327
342
|
"priority": source.priority,
|
|
328
343
|
"enabled": source.enabled,
|
|
344
|
+
**({"token": source.token} if source.token else {}),
|
|
329
345
|
}
|
|
330
346
|
for source in sources
|
|
331
347
|
]
|
claude_mpm/core/config.py
CHANGED
|
@@ -12,11 +12,10 @@ import threading
|
|
|
12
12
|
from pathlib import Path
|
|
13
13
|
from typing import Any, Dict, List, Optional, Tuple, Union
|
|
14
14
|
|
|
15
|
-
import yaml
|
|
16
|
-
|
|
17
15
|
from claude_mpm.core.logging_utils import get_logger
|
|
18
16
|
|
|
19
|
-
|
|
17
|
+
# Lazy import ConfigurationManager to avoid importing yaml at module level
|
|
18
|
+
# This prevents hook errors when yaml isn't available in the execution environment
|
|
20
19
|
from .exceptions import ConfigurationError, FileOperationError
|
|
21
20
|
from .unified_paths import get_path_manager
|
|
22
21
|
|
|
@@ -104,6 +103,9 @@ class Config:
|
|
|
104
103
|
Config._initialized = True
|
|
105
104
|
logger.debug("Initializing Config singleton for the first time")
|
|
106
105
|
|
|
106
|
+
# Lazy import ConfigurationManager at runtime to avoid yaml import at module level
|
|
107
|
+
from ..utils.config_manager import ConfigurationManager
|
|
108
|
+
|
|
107
109
|
# Initialize instance variables inside the lock to ensure thread safety
|
|
108
110
|
self._config: Dict[str, Any] = {}
|
|
109
111
|
self._env_prefix = env_prefix
|
|
@@ -224,21 +226,6 @@ class Config:
|
|
|
224
226
|
f"Response logging format: {response_logging.get('format', 'json')}"
|
|
225
227
|
)
|
|
226
228
|
|
|
227
|
-
except yaml.YAMLError as e:
|
|
228
|
-
logger.error(f"YAML syntax error in {file_path}: {e}")
|
|
229
|
-
if hasattr(e, "problem_mark"):
|
|
230
|
-
mark = e.problem_mark
|
|
231
|
-
logger.error(f"Error at line {mark.line + 1}, column {mark.column + 1}")
|
|
232
|
-
logger.info(
|
|
233
|
-
"TIP: Validate your YAML at https://www.yamllint.com/ or run: python scripts/validate_configuration.py"
|
|
234
|
-
)
|
|
235
|
-
logger.info(
|
|
236
|
-
"TIP: Common issue - YAML requires spaces, not tabs. Fix with: sed -i '' 's/\t/ /g' "
|
|
237
|
-
+ str(file_path)
|
|
238
|
-
)
|
|
239
|
-
# Store error for later retrieval
|
|
240
|
-
self._config["_load_error"] = str(e)
|
|
241
|
-
|
|
242
229
|
except json.JSONDecodeError as e:
|
|
243
230
|
logger.error(f"JSON syntax error in {file_path}: {e}")
|
|
244
231
|
logger.error(f"Error at line {e.lineno}, column {e.colno}")
|
|
@@ -255,7 +242,28 @@ class Config:
|
|
|
255
242
|
},
|
|
256
243
|
) from e
|
|
257
244
|
except Exception as e:
|
|
258
|
-
#
|
|
245
|
+
# Handle YAML errors without importing yaml at module level
|
|
246
|
+
# ConfigurationManager.load_yaml raises yaml.YAMLError, but we don't want to import yaml
|
|
247
|
+
# Check if it's a YAML error by class name to avoid import
|
|
248
|
+
if e.__class__.__name__ == "YAMLError":
|
|
249
|
+
logger.error(f"YAML syntax error in {file_path}: {e}")
|
|
250
|
+
if hasattr(e, "problem_mark"):
|
|
251
|
+
mark = e.problem_mark
|
|
252
|
+
logger.error(
|
|
253
|
+
f"Error at line {mark.line + 1}, column {mark.column + 1}"
|
|
254
|
+
)
|
|
255
|
+
logger.info(
|
|
256
|
+
"TIP: Validate your YAML at https://www.yamllint.com/ or run: python scripts/validate_configuration.py"
|
|
257
|
+
)
|
|
258
|
+
logger.info(
|
|
259
|
+
"TIP: Common issue - YAML requires spaces, not tabs. Fix with: sed -i '' 's/\t/ /g' "
|
|
260
|
+
+ str(file_path)
|
|
261
|
+
)
|
|
262
|
+
# Store error for later retrieval
|
|
263
|
+
self._config["_load_error"] = str(e)
|
|
264
|
+
return # Don't re-raise, we handled it
|
|
265
|
+
|
|
266
|
+
# Not a YAML error, wrap as configuration error
|
|
259
267
|
raise ConfigurationError(
|
|
260
268
|
f"Unexpected error loading configuration from {file_path}: {e}",
|
|
261
269
|
context={
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -537,6 +537,44 @@ main "$@"
|
|
|
537
537
|
except Exception as e:
|
|
538
538
|
self.logger.warning(f"Could not clean up old settings file: {e}")
|
|
539
539
|
|
|
540
|
+
def _fix_status_line(self, settings: Dict) -> None:
|
|
541
|
+
"""Fix statusLine command to handle both output style schema formats.
|
|
542
|
+
|
|
543
|
+
The statusLine command receives input in different formats:
|
|
544
|
+
- Newer format: {"activeOutputStyle": "Claude MPM", ...}
|
|
545
|
+
- Older format: {"output_style": {"name": "Claude MPM"}, ...}
|
|
546
|
+
|
|
547
|
+
This method ensures the jq expression checks both locations.
|
|
548
|
+
|
|
549
|
+
Args:
|
|
550
|
+
settings: The settings dictionary to update
|
|
551
|
+
"""
|
|
552
|
+
if "statusLine" not in settings:
|
|
553
|
+
return
|
|
554
|
+
|
|
555
|
+
status_line = settings.get("statusLine", {})
|
|
556
|
+
if "command" not in status_line:
|
|
557
|
+
return
|
|
558
|
+
|
|
559
|
+
command = status_line["command"]
|
|
560
|
+
|
|
561
|
+
# Pattern to match: '.output_style.name // "default"'
|
|
562
|
+
# We need to update it to: '.output_style.name // .activeOutputStyle // "default"'
|
|
563
|
+
old_pattern = r'\.output_style\.name\s*//\s*"default"'
|
|
564
|
+
new_pattern = '.output_style.name // .activeOutputStyle // "default"'
|
|
565
|
+
|
|
566
|
+
# Check if the command needs updating
|
|
567
|
+
if re.search(old_pattern, command) and ".activeOutputStyle" not in command:
|
|
568
|
+
updated_command = re.sub(old_pattern, new_pattern, command)
|
|
569
|
+
settings["statusLine"]["command"] = updated_command
|
|
570
|
+
self.logger.info(
|
|
571
|
+
"Fixed statusLine command to handle both output style schemas"
|
|
572
|
+
)
|
|
573
|
+
else:
|
|
574
|
+
self.logger.debug(
|
|
575
|
+
"StatusLine command already supports both schemas or not present"
|
|
576
|
+
)
|
|
577
|
+
|
|
540
578
|
def _update_claude_settings(self, hook_script_path: Path) -> None:
|
|
541
579
|
"""Update Claude settings to use the installed hook."""
|
|
542
580
|
self.logger.info("Updating Claude settings...")
|
|
@@ -598,6 +636,9 @@ main "$@"
|
|
|
598
636
|
}
|
|
599
637
|
]
|
|
600
638
|
|
|
639
|
+
# Fix statusLine command to handle both output style schemas
|
|
640
|
+
self._fix_status_line(settings)
|
|
641
|
+
|
|
601
642
|
# Write settings to settings.json
|
|
602
643
|
with self.settings_file.open("w") as f:
|
|
603
644
|
json.dump(settings, f, indent=2)
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -125,7 +125,7 @@ find_python_command() {
|
|
|
125
125
|
# 1. Check for UV project first (uv.lock or pyproject.toml with uv)
|
|
126
126
|
if [ -f "$CLAUDE_MPM_ROOT/uv.lock" ]; then
|
|
127
127
|
if command -v uv &> /dev/null; then
|
|
128
|
-
echo "uv run python"
|
|
128
|
+
echo "uv run --directory \"$CLAUDE_MPM_ROOT\" python"
|
|
129
129
|
return
|
|
130
130
|
fi
|
|
131
131
|
fi
|
|
@@ -219,8 +219,8 @@ log_debug() {
|
|
|
219
219
|
|
|
220
220
|
# Test Python works and module exists
|
|
221
221
|
# Handle UV's multi-word command specially
|
|
222
|
-
if [[ "$PYTHON_CMD" == "uv run
|
|
223
|
-
if ! uv run python -c "import claude_mpm" 2>/dev/null; then
|
|
222
|
+
if [[ "$PYTHON_CMD" == "uv run"* ]]; then
|
|
223
|
+
if ! uv run --directory "$CLAUDE_MPM_ROOT" python -c "import claude_mpm" 2>/dev/null; then
|
|
224
224
|
log_debug "claude_mpm module not available, continuing without hook"
|
|
225
225
|
echo '{"action": "continue"}'
|
|
226
226
|
exit 0
|
|
@@ -237,8 +237,8 @@ fi
|
|
|
237
237
|
# Use exec to replace the shell process with Python
|
|
238
238
|
# Handle UV's multi-word command specially
|
|
239
239
|
# Suppress RuntimeWarning to prevent stderr output (which causes hook errors)
|
|
240
|
-
if [[ "$PYTHON_CMD" == "uv run
|
|
241
|
-
exec uv run python -W ignore::RuntimeWarning -m claude_mpm.hooks.claude_hooks.hook_handler "$@" 2>/tmp/claude-mpm-hook-error.log
|
|
240
|
+
if [[ "$PYTHON_CMD" == "uv run"* ]]; then
|
|
241
|
+
exec uv run --directory "$CLAUDE_MPM_ROOT" python -W ignore::RuntimeWarning -m claude_mpm.hooks.claude_hooks.hook_handler "$@" 2>/tmp/claude-mpm-hook-error.log
|
|
242
242
|
else
|
|
243
243
|
exec "$PYTHON_CMD" -W ignore::RuntimeWarning -m claude_mpm.hooks.claude_hooks.hook_handler "$@" 2>/tmp/claude-mpm-hook-error.log
|
|
244
244
|
fi
|
|
@@ -39,10 +39,10 @@ import logging
|
|
|
39
39
|
from pathlib import Path
|
|
40
40
|
from typing import Any, Dict, List, Optional, Set, Tuple
|
|
41
41
|
|
|
42
|
-
from
|
|
42
|
+
from claude_mpm.services.agents.single_tier_deployment_service import (
|
|
43
43
|
SingleTierDeploymentService,
|
|
44
44
|
)
|
|
45
|
-
from
|
|
45
|
+
from claude_mpm.services.agents.toolchain_detector import ToolchainDetector
|
|
46
46
|
|
|
47
47
|
logger = logging.getLogger(__name__)
|
|
48
48
|
|
|
@@ -30,12 +30,12 @@ from datetime import datetime, timezone
|
|
|
30
30
|
from pathlib import Path
|
|
31
31
|
from typing import Any, Dict, List, Optional
|
|
32
32
|
|
|
33
|
-
from
|
|
34
|
-
from
|
|
35
|
-
from
|
|
33
|
+
from claude_mpm.config.agent_sources import AgentSourceConfiguration
|
|
34
|
+
from claude_mpm.models.git_repository import GitRepository
|
|
35
|
+
from claude_mpm.services.agents.deployment.remote_agent_discovery_service import (
|
|
36
36
|
RemoteAgentDiscoveryService,
|
|
37
37
|
)
|
|
38
|
-
from
|
|
38
|
+
from claude_mpm.services.agents.git_source_manager import GitSourceManager
|
|
39
39
|
|
|
40
40
|
logger = logging.getLogger(__name__)
|
|
41
41
|
|
|
@@ -16,6 +16,7 @@ Trade-offs:
|
|
|
16
16
|
- Flexibility: Easy to extend with skills-specific features
|
|
17
17
|
"""
|
|
18
18
|
|
|
19
|
+
import os
|
|
19
20
|
from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
20
21
|
from datetime import datetime, timezone
|
|
21
22
|
from pathlib import Path
|
|
@@ -32,6 +33,46 @@ from claude_mpm.services.skills.skill_discovery_service import SkillDiscoverySer
|
|
|
32
33
|
logger = get_logger(__name__)
|
|
33
34
|
|
|
34
35
|
|
|
36
|
+
def _get_github_token(source: Optional[SkillSource] = None) -> Optional[str]:
|
|
37
|
+
"""Get GitHub token with source-specific override support.
|
|
38
|
+
|
|
39
|
+
Priority: source.token > GITHUB_TOKEN > GH_TOKEN
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
source: Optional SkillSource to check for per-source token
|
|
43
|
+
|
|
44
|
+
Returns:
|
|
45
|
+
GitHub token if found, None otherwise
|
|
46
|
+
|
|
47
|
+
Token Resolution:
|
|
48
|
+
1. If source has token starting with "$", resolve as env var
|
|
49
|
+
2. If source has direct token, use it (not recommended for security)
|
|
50
|
+
3. Fall back to GITHUB_TOKEN env var
|
|
51
|
+
4. Fall back to GH_TOKEN env var
|
|
52
|
+
5. Return None if no token found
|
|
53
|
+
|
|
54
|
+
Security Note:
|
|
55
|
+
Token is never logged or printed to avoid exposure.
|
|
56
|
+
Direct tokens in config are discouraged - use env var refs ($VAR_NAME).
|
|
57
|
+
|
|
58
|
+
Example:
|
|
59
|
+
>>> source = SkillSource(..., token="$PRIVATE_TOKEN")
|
|
60
|
+
>>> token = _get_github_token(source) # Resolves $PRIVATE_TOKEN from env
|
|
61
|
+
>>> token = _get_github_token() # Falls back to GITHUB_TOKEN
|
|
62
|
+
"""
|
|
63
|
+
# Priority 1: Per-source token (env var reference or direct)
|
|
64
|
+
if source and source.token:
|
|
65
|
+
if source.token.startswith("$"):
|
|
66
|
+
# Env var reference: $VAR_NAME -> os.environ.get("VAR_NAME")
|
|
67
|
+
env_var_name = source.token[1:]
|
|
68
|
+
return os.environ.get(env_var_name)
|
|
69
|
+
# Direct token (not recommended but supported)
|
|
70
|
+
return source.token
|
|
71
|
+
|
|
72
|
+
# Priority 2-3: Global environment variables
|
|
73
|
+
return os.environ.get("GITHUB_TOKEN") or os.environ.get("GH_TOKEN")
|
|
74
|
+
|
|
75
|
+
|
|
35
76
|
class GitSkillSourceManager:
|
|
36
77
|
"""Manages multiple Git-based skill sources with priority resolution.
|
|
37
78
|
|
|
@@ -217,9 +258,21 @@ class GitSkillSourceManager:
|
|
|
217
258
|
)
|
|
218
259
|
|
|
219
260
|
# Discover skills in cache
|
|
261
|
+
self.logger.debug(f"Scanning cache path for skills: {cache_path}")
|
|
220
262
|
discovery_service = SkillDiscoveryService(cache_path)
|
|
221
263
|
discovered_skills = discovery_service.discover_skills()
|
|
222
264
|
|
|
265
|
+
# Log discovery results
|
|
266
|
+
if len(discovered_skills) == 0:
|
|
267
|
+
self.logger.info(
|
|
268
|
+
f"No SKILL.md files found in {cache_path}. "
|
|
269
|
+
"Ensure your skill source has SKILL.md files with valid frontmatter."
|
|
270
|
+
)
|
|
271
|
+
else:
|
|
272
|
+
self.logger.debug(
|
|
273
|
+
f"Successfully parsed {len(discovered_skills)} skills from {cache_path}"
|
|
274
|
+
)
|
|
275
|
+
|
|
223
276
|
# Build result
|
|
224
277
|
result = {
|
|
225
278
|
"synced": True,
|
|
@@ -469,7 +522,7 @@ class GitSkillSourceManager:
|
|
|
469
522
|
# Step 1: Discover all files via GitHub Tree API (single request)
|
|
470
523
|
# This discovers the COMPLETE repository structure (272 files for skills)
|
|
471
524
|
all_files = self._discover_repository_files_via_tree_api(
|
|
472
|
-
owner_repo, source.branch
|
|
525
|
+
owner_repo, source.branch, source
|
|
473
526
|
)
|
|
474
527
|
|
|
475
528
|
if not all_files:
|
|
@@ -504,7 +557,7 @@ class GitSkillSourceManager:
|
|
|
504
557
|
raw_url = f"https://raw.githubusercontent.com/{owner_repo}/{source.branch}/{file_path}"
|
|
505
558
|
cache_file = cache_path / file_path
|
|
506
559
|
future = executor.submit(
|
|
507
|
-
self._download_file_with_etag, raw_url, cache_file, force
|
|
560
|
+
self._download_file_with_etag, raw_url, cache_file, force, source
|
|
508
561
|
)
|
|
509
562
|
future_to_file[future] = file_path
|
|
510
563
|
|
|
@@ -533,7 +586,7 @@ class GitSkillSourceManager:
|
|
|
533
586
|
return files_updated, files_cached
|
|
534
587
|
|
|
535
588
|
def _discover_repository_files_via_tree_api(
|
|
536
|
-
self, owner_repo: str, branch: str
|
|
589
|
+
self, owner_repo: str, branch: str, source: Optional[SkillSource] = None
|
|
537
590
|
) -> List[str]:
|
|
538
591
|
"""Discover all files in repository using GitHub Git Tree API.
|
|
539
592
|
|
|
@@ -596,9 +649,17 @@ class GitSkillSourceManager:
|
|
|
596
649
|
)
|
|
597
650
|
self.logger.debug(f"Fetching commit SHA from {refs_url}")
|
|
598
651
|
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
)
|
|
652
|
+
# Build headers with authentication if token available
|
|
653
|
+
headers = {"Accept": "application/vnd.github+json"}
|
|
654
|
+
token = _get_github_token(source)
|
|
655
|
+
if token:
|
|
656
|
+
headers["Authorization"] = f"token {token}"
|
|
657
|
+
if source and source.token:
|
|
658
|
+
self.logger.debug(f"Using source-specific token for {source.id}")
|
|
659
|
+
else:
|
|
660
|
+
self.logger.debug("Using GitHub token for authentication")
|
|
661
|
+
|
|
662
|
+
refs_response = requests.get(refs_url, headers=headers, timeout=30)
|
|
602
663
|
|
|
603
664
|
# Check for rate limiting
|
|
604
665
|
if refs_response.status_code == 403:
|
|
@@ -621,7 +682,7 @@ class GitSkillSourceManager:
|
|
|
621
682
|
self.logger.debug(f"Fetching recursive tree from {tree_url}")
|
|
622
683
|
tree_response = requests.get(
|
|
623
684
|
tree_url,
|
|
624
|
-
headers=
|
|
685
|
+
headers=headers, # Reuse headers with auth from Step 1
|
|
625
686
|
params=params,
|
|
626
687
|
timeout=30,
|
|
627
688
|
)
|
|
@@ -652,7 +713,11 @@ class GitSkillSourceManager:
|
|
|
652
713
|
return all_files
|
|
653
714
|
|
|
654
715
|
def _download_file_with_etag(
|
|
655
|
-
self,
|
|
716
|
+
self,
|
|
717
|
+
url: str,
|
|
718
|
+
local_path: Path,
|
|
719
|
+
force: bool = False,
|
|
720
|
+
source: Optional[SkillSource] = None,
|
|
656
721
|
) -> bool:
|
|
657
722
|
"""Download file from URL with ETag caching (thread-safe).
|
|
658
723
|
|
|
@@ -660,6 +725,7 @@ class GitSkillSourceManager:
|
|
|
660
725
|
url: Raw GitHub URL
|
|
661
726
|
local_path: Local file path to save to
|
|
662
727
|
force: Force download even if cached
|
|
728
|
+
source: Optional SkillSource for token resolution
|
|
663
729
|
|
|
664
730
|
Returns:
|
|
665
731
|
True if file was updated, False if cached
|
|
@@ -692,6 +758,11 @@ class GitSkillSourceManager:
|
|
|
692
758
|
if cached_etag and not force:
|
|
693
759
|
headers["If-None-Match"] = cached_etag
|
|
694
760
|
|
|
761
|
+
# Add GitHub authentication if token available
|
|
762
|
+
token = _get_github_token(source)
|
|
763
|
+
if token:
|
|
764
|
+
headers["Authorization"] = f"token {token}"
|
|
765
|
+
|
|
695
766
|
try:
|
|
696
767
|
response = requests.get(url, headers=headers, timeout=30)
|
|
697
768
|
|
|
@@ -50,6 +50,22 @@ logger = get_logger(__name__)
|
|
|
50
50
|
# Deployment tracking index file
|
|
51
51
|
DEPLOYED_INDEX_FILE = ".mpm-deployed-skills.json"
|
|
52
52
|
|
|
53
|
+
# Core PM skills that should always be deployed
|
|
54
|
+
# These are referenced in PM_INSTRUCTIONS.md with [SKILL: name] markers
|
|
55
|
+
# Without these skills, PM only sees placeholders, not actual content
|
|
56
|
+
PM_CORE_SKILLS = {
|
|
57
|
+
"mpm-delegation-patterns",
|
|
58
|
+
"mpm-verification-protocols",
|
|
59
|
+
"mpm-tool-usage-guide",
|
|
60
|
+
"mpm-git-file-tracking",
|
|
61
|
+
"mpm-pr-workflow",
|
|
62
|
+
"mpm-ticketing-integration",
|
|
63
|
+
"mpm-teaching-mode",
|
|
64
|
+
"mpm-bug-reporting",
|
|
65
|
+
"mpm-circuit-breaker-enforcement",
|
|
66
|
+
"mpm-session-management",
|
|
67
|
+
}
|
|
68
|
+
|
|
53
69
|
# Core skills that are universally useful across all projects
|
|
54
70
|
# These are deployed when skill mapping returns too many skills (>60)
|
|
55
71
|
# Target: ~25-30 core skills for balanced functionality
|
|
@@ -376,6 +392,18 @@ def get_required_skills_from_agents(agents_dir: Path) -> Set[str]:
|
|
|
376
392
|
"(converted slashes to dashes)"
|
|
377
393
|
)
|
|
378
394
|
|
|
395
|
+
# Always include PM core skills to ensure PM_INSTRUCTIONS.md markers are resolved
|
|
396
|
+
# These skills are referenced in PM_INSTRUCTIONS.md and must be deployed
|
|
397
|
+
# for PM to see actual content instead of [SKILL: name] placeholders
|
|
398
|
+
before_pm_skills = len(normalized_skills)
|
|
399
|
+
normalized_skills = normalized_skills | PM_CORE_SKILLS
|
|
400
|
+
pm_skills_added = len(normalized_skills) - before_pm_skills
|
|
401
|
+
|
|
402
|
+
if pm_skills_added > 0:
|
|
403
|
+
logger.info(
|
|
404
|
+
f"Added {pm_skills_added} PM core skills to ensure PM_INSTRUCTIONS.md markers resolve"
|
|
405
|
+
)
|
|
406
|
+
|
|
379
407
|
return normalized_skills
|
|
380
408
|
|
|
381
409
|
|
|
@@ -188,6 +188,15 @@ class SkillDiscoveryService:
|
|
|
188
188
|
f"and {len(legacy_md_files)} legacy .md files in {self.skills_dir}"
|
|
189
189
|
)
|
|
190
190
|
|
|
191
|
+
# Log first few file paths for debugging
|
|
192
|
+
if all_skill_files:
|
|
193
|
+
sample_files = [
|
|
194
|
+
str(f.relative_to(self.skills_dir)) for f in all_skill_files[:5]
|
|
195
|
+
]
|
|
196
|
+
self.logger.debug(f"Sample skill files: {sample_files}")
|
|
197
|
+
else:
|
|
198
|
+
self.logger.debug(f"No SKILL.md or .md files found in {self.skills_dir}")
|
|
199
|
+
|
|
191
200
|
# Track deployment names to detect collisions
|
|
192
201
|
deployment_names = {}
|
|
193
202
|
|
|
@@ -226,7 +235,14 @@ class SkillDiscoveryService:
|
|
|
226
235
|
except Exception as e:
|
|
227
236
|
self.logger.warning(f"Failed to parse skill {skill_file}: {e}")
|
|
228
237
|
|
|
229
|
-
|
|
238
|
+
# Summary logging
|
|
239
|
+
parsed_count = len(skills)
|
|
240
|
+
failed_count = len(all_skill_files) - parsed_count
|
|
241
|
+
self.logger.info(
|
|
242
|
+
f"Discovered {parsed_count} skills from {self.skills_dir.name} "
|
|
243
|
+
f"({len(all_skill_files)} files found, {failed_count} failed to parse)"
|
|
244
|
+
)
|
|
245
|
+
|
|
230
246
|
return skills
|
|
231
247
|
|
|
232
248
|
def _parse_skill_file(self, skill_file: Path) -> Optional[Dict[str, Any]]:
|
|
@@ -28,7 +28,7 @@ References:
|
|
|
28
28
|
import json
|
|
29
29
|
import platform
|
|
30
30
|
import shutil
|
|
31
|
-
import subprocess
|
|
31
|
+
import subprocess # nosec B404 - subprocess needed for safe git operations
|
|
32
32
|
from pathlib import Path
|
|
33
33
|
from typing import Any, Dict, List, Optional
|
|
34
34
|
|
|
@@ -653,7 +653,7 @@ class SkillsDeployerService(LoggerMixin):
|
|
|
653
653
|
f"Updating existing collection '{collection_name}' at {target_dir}"
|
|
654
654
|
)
|
|
655
655
|
try:
|
|
656
|
-
result = subprocess.run(
|
|
656
|
+
result = subprocess.run( # nosec B603 B607 - Safe: hardcoded git command
|
|
657
657
|
["git", "pull"],
|
|
658
658
|
cwd=target_dir,
|
|
659
659
|
capture_output=True,
|
|
@@ -684,7 +684,7 @@ class SkillsDeployerService(LoggerMixin):
|
|
|
684
684
|
f"Installing new collection '{collection_name}' to {target_dir}"
|
|
685
685
|
)
|
|
686
686
|
try:
|
|
687
|
-
result = subprocess.run(
|
|
687
|
+
result = subprocess.run( # nosec B603 B607 - Safe: hardcoded git command
|
|
688
688
|
["git", "clone", repo_url, str(target_dir)],
|
|
689
689
|
capture_output=True,
|
|
690
690
|
text=True,
|
|
@@ -773,6 +773,32 @@ class SkillsDeployerService(LoggerMixin):
|
|
|
773
773
|
if isinstance(skills_data, dict):
|
|
774
774
|
flat_skills = []
|
|
775
775
|
|
|
776
|
+
# Define valid top-level categories
|
|
777
|
+
VALID_CATEGORIES = {"universal", "toolchains"}
|
|
778
|
+
|
|
779
|
+
# Check for unknown categories and warn user
|
|
780
|
+
unknown_categories = set(skills_data.keys()) - VALID_CATEGORIES
|
|
781
|
+
if unknown_categories:
|
|
782
|
+
# Count skills in unknown categories
|
|
783
|
+
skipped_count = 0
|
|
784
|
+
for cat in unknown_categories:
|
|
785
|
+
cat_data = skills_data.get(cat, [])
|
|
786
|
+
if isinstance(cat_data, list):
|
|
787
|
+
skipped_count += len(cat_data)
|
|
788
|
+
elif isinstance(cat_data, dict):
|
|
789
|
+
# If it's a dict like toolchains, count nested skills
|
|
790
|
+
for skills_list in cat_data.values():
|
|
791
|
+
if isinstance(skills_list, list):
|
|
792
|
+
skipped_count += len(skills_list)
|
|
793
|
+
|
|
794
|
+
self.logger.warning(
|
|
795
|
+
f"Unknown categories in manifest will be skipped: "
|
|
796
|
+
f"{', '.join(sorted(unknown_categories))} ({skipped_count} skills)"
|
|
797
|
+
)
|
|
798
|
+
self.logger.info(
|
|
799
|
+
f"Valid top-level categories: {', '.join(sorted(VALID_CATEGORIES))}"
|
|
800
|
+
)
|
|
801
|
+
|
|
776
802
|
# Add universal skills
|
|
777
803
|
universal_skills = skills_data.get("universal", [])
|
|
778
804
|
if isinstance(universal_skills, list):
|
|
@@ -1022,12 +1048,12 @@ class SkillsDeployerService(LoggerMixin):
|
|
|
1022
1048
|
"""
|
|
1023
1049
|
try:
|
|
1024
1050
|
if platform.system() == "Windows":
|
|
1025
|
-
result = subprocess.run(
|
|
1051
|
+
result = subprocess.run( # nosec B603 B607 - Safe: hardcoded tasklist command
|
|
1026
1052
|
["tasklist"], check=False, capture_output=True, text=True, timeout=5
|
|
1027
1053
|
)
|
|
1028
1054
|
return "claude" in result.stdout.lower()
|
|
1029
1055
|
# macOS and Linux
|
|
1030
|
-
result = subprocess.run(
|
|
1056
|
+
result = subprocess.run( # nosec B603 B607 - Safe: hardcoded ps command
|
|
1031
1057
|
["ps", "aux"], check=False, capture_output=True, text=True, timeout=5
|
|
1032
1058
|
)
|
|
1033
1059
|
# Look for "Claude Code" or "claude-code" process
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
claude_mpm/BUILD_NUMBER,sha256=9JfxhnDtr-8l3kCP2U5TVXSErptHoga8m7XA8zqgGOc,4
|
|
2
|
-
claude_mpm/VERSION,sha256=
|
|
2
|
+
claude_mpm/VERSION,sha256=nJST2g_21xhxfQk5QgAosXHOMTc1xwppJdB3d85to-g,6
|
|
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
|
|
@@ -98,8 +98,8 @@ claude_mpm/cli/commands/postmortem.py,sha256=QkEymFR43IyN2dHBlaEHxsrDVrmhApLNJCp
|
|
|
98
98
|
claude_mpm/cli/commands/profile.py,sha256=heXuBrrpIsu3JEsl7k-apUbxV0sVeDENF9Ct9aCJ5NM,10610
|
|
99
99
|
claude_mpm/cli/commands/run.py,sha256=fWDwyJ6huzG0nyTkbwfxb8IL4UUWGG5HRl2TJWLnWPA,47973
|
|
100
100
|
claude_mpm/cli/commands/search.py,sha256=alv6udvKcn-xkqeBlLuPRvfSDV1yxEX4n9mjjRT5uLM,16581
|
|
101
|
-
claude_mpm/cli/commands/skill_source.py,sha256=
|
|
102
|
-
claude_mpm/cli/commands/skills.py,sha256=
|
|
101
|
+
claude_mpm/cli/commands/skill_source.py,sha256=qhP2gtr-cnnoVABv84y_XRqktfG5n52zcjLZ-zmZvWE,24227
|
|
102
|
+
claude_mpm/cli/commands/skills.py,sha256=pcsbqD2vkql9gyDr01mZmeXOUiFcgRd9UXWFUwMDs1E,58300
|
|
103
103
|
claude_mpm/cli/commands/summarize.py,sha256=1eb6i3IEZ3DqLNBT_HRzEygQ3NPHvrLOTdvQI0pURso,12460
|
|
104
104
|
claude_mpm/cli/commands/tickets.py,sha256=kl2dklTBnG3Y4jUUJ_PcEVsTx4CtVJfkGWboWBx_mQM,21234
|
|
105
105
|
claude_mpm/cli/commands/uninstall.py,sha256=KGlVG6veEs1efLVjrZ3wSty7e1zVR9wpt-VXQA1RzWw,5945
|
|
@@ -138,8 +138,8 @@ claude_mpm/cli/parsers/mpm_init_parser.py,sha256=yIqsUeOtXsUTOD-pJCAEr3euSGxmN3w
|
|
|
138
138
|
claude_mpm/cli/parsers/profile_parser.py,sha256=HlPRekiPeDxqRYSpXoR3NlbOtupXww0mCSrRohHedzs,4414
|
|
139
139
|
claude_mpm/cli/parsers/run_parser.py,sha256=oUB5k3VmIxmsMUlOacfWJxesDw8h4ISf1WkikZLLyzQ,5249
|
|
140
140
|
claude_mpm/cli/parsers/search_parser.py,sha256=L8-65kndg-zutSKpzj-eCvTNkeySCZ-WlSHdhk7pEak,6916
|
|
141
|
-
claude_mpm/cli/parsers/skill_source_parser.py,sha256=
|
|
142
|
-
claude_mpm/cli/parsers/skills_parser.py,sha256=
|
|
141
|
+
claude_mpm/cli/parsers/skill_source_parser.py,sha256=82-ysrXTHJcJI_nOD5FdAUAMU5WeqXLU3Euia8_oojU,5012
|
|
142
|
+
claude_mpm/cli/parsers/skills_parser.py,sha256=rtpmBm-wMZiwvSluV_K3Efz7BVjwTl3ZpJM4J8Du53U,8908
|
|
143
143
|
claude_mpm/cli/parsers/source_parser.py,sha256=NUYpN6hh-yvL1IQ7or4Y8fs8kDX5Sw7E_rMLVjwwkpo,4023
|
|
144
144
|
claude_mpm/cli/parsers/tickets_parser.py,sha256=FYl-VNH7PrZzfZUCcjnf6F7g6JXnL8YDxwrmR5svIcg,6966
|
|
145
145
|
claude_mpm/cli/shared/__init__.py,sha256=c3Ff46Az3U-YpYgcjOowMcNUkSzDngflAJotv6Bs8TE,1019
|
|
@@ -165,14 +165,14 @@ claude_mpm/commander/adapters/claude_code.py,sha256=YGWZN9Y3QUdYC0mHQ-D5su7PDT6b
|
|
|
165
165
|
claude_mpm/commander/adapters/communication.py,sha256=Gs_vmQ630a_CQLS1x0B0lgcQCOfW82_VZeqto3a9ZYQ,11707
|
|
166
166
|
claude_mpm/commander/api/__init__.py,sha256=I73MajIx-r6iIEYVJ4eHo-InMwfKOruN78VXF_eMEIk,376
|
|
167
167
|
claude_mpm/commander/api/app.py,sha256=r7swU1wF0frST6zOObcBjq9VM45VfDHT4aNldAjEPKc,3129
|
|
168
|
-
claude_mpm/commander/api/errors.py,sha256=
|
|
168
|
+
claude_mpm/commander/api/errors.py,sha256=cBwHbC-rt543ZmE1DNLFv5XBqeUD58z7f4fGJF1x5uA,3590
|
|
169
169
|
claude_mpm/commander/api/schemas.py,sha256=VmoBRP4NUIIvkH0Do3af3nxXS3Q97sYCJpJurv20tXU,4933
|
|
170
170
|
claude_mpm/commander/api/routes/__init__.py,sha256=xI13W9tT4zYGaCotLMw4rKpGDhjkvi1YqNRoLh-8E5I,229
|
|
171
171
|
claude_mpm/commander/api/routes/events.py,sha256=XxSEpRdcty9cSrkRMjEMALktqZfcGGx5n-rHexGFZSs,4879
|
|
172
172
|
claude_mpm/commander/api/routes/inbox.py,sha256=edwse_fHITO_jICd3kOTGFim41tx2GbB0MN55Mg036M,5276
|
|
173
173
|
claude_mpm/commander/api/routes/messages.py,sha256=-jhR8jYd_CwhVW0WeM4un9WLzSMueLAhMrDrg080E5A,3916
|
|
174
174
|
claude_mpm/commander/api/routes/projects.py,sha256=rN27P4D45Qzp0kE49PCM1bonLI4ZS65-q-u-3HprRto,7226
|
|
175
|
-
claude_mpm/commander/api/routes/sessions.py,sha256=
|
|
175
|
+
claude_mpm/commander/api/routes/sessions.py,sha256=LWlehH534YVoPl_4Cfhxa_GePRbRnYQ49hXf3e70x0s,6275
|
|
176
176
|
claude_mpm/commander/api/routes/work.py,sha256=BKx9fd7iqvgxYUDm1stui7TGev6dfhuvP3X-_8pC2-U,7257
|
|
177
177
|
claude_mpm/commander/chat/__init__.py,sha256=5Iiya2YPkF54OvtZgL4NNT0zp5PCsZnnE7D6l19aYnA,243
|
|
178
178
|
claude_mpm/commander/chat/cli.py,sha256=mHWEXjDll7OFIi2frTwfMs0wnJ71aFkFHX3vJr_iEGM,3151
|
|
@@ -245,7 +245,7 @@ claude_mpm/config/experimental_features.py,sha256=cH95HqMUEQL-_Hs833dAAC33GHMUE5
|
|
|
245
245
|
claude_mpm/config/model_config.py,sha256=34JnIb_U19UYns3yLX-jjpuNywDnVZhiUSvvDzGzx0g,12410
|
|
246
246
|
claude_mpm/config/paths.py,sha256=wTZxXt6LjD-gK9lG4i2QSuSnFRXe5lFaVU4dIr22ap8,7643
|
|
247
247
|
claude_mpm/config/skill_presets.py,sha256=CReZz9CAGQnXdfSBIa0fN5S1vM5dDxh-9S-tG0WiY5M,13919
|
|
248
|
-
claude_mpm/config/skill_sources.py,sha256=
|
|
248
|
+
claude_mpm/config/skill_sources.py,sha256=apZDFdSlUFsewhDQWIjC_zwSMkmG2SGdf1go7pb55eo,20504
|
|
249
249
|
claude_mpm/config/socketio_config.py,sha256=Z8O438z2taOPX2Eh_so-WOvvv-IHiM_WFbf4UBQ4iqg,11342
|
|
250
250
|
claude_mpm/core/__init__.py,sha256=2bufzjbIXffZnSg5k-JH9czMDTkmtz-Jb9opgHmQY-0,2598
|
|
251
251
|
claude_mpm/core/agent_name_normalizer.py,sha256=ZvdQsToFqxLWEPbf8gU1Hl8h3M47DBPmZ8zSAkEp-fc,8939
|
|
@@ -255,7 +255,7 @@ claude_mpm/core/api_validator.py,sha256=zxeUykC2asy1KwHBDu5w3Eoo64E51PJyNe4PT7CT
|
|
|
255
255
|
claude_mpm/core/base_service.py,sha256=4Zrt-vQ6g_KVk4hEfvd4QccuItYoOf7wUHCimIW6zJQ,29953
|
|
256
256
|
claude_mpm/core/cache.py,sha256=orh8B40oYnRRGmXdANR4P4f-KVMIHV0vg7vrsemk0no,17232
|
|
257
257
|
claude_mpm/core/claude_runner.py,sha256=Wle-wI-ag25oC0EYX3n8dDC56I5GIdbpi5NtvT4IgBw,34263
|
|
258
|
-
claude_mpm/core/config.py,sha256=
|
|
258
|
+
claude_mpm/core/config.py,sha256=0R1ZLdwxTM2N3-uIBgcbr37jDiEe-G7h7x4YmYIVit0,43385
|
|
259
259
|
claude_mpm/core/config_aliases.py,sha256=QpNNECkTY4TYYAhVlFZvB-msPnZrui90g19u0-v0HDE,9703
|
|
260
260
|
claude_mpm/core/config_constants.py,sha256=MEF35Y2Lj5FMzRdhgSgZrZeTzHfCzistPGZVY8INta4,10073
|
|
261
261
|
claude_mpm/core/constants.py,sha256=tm6IkmDxnsEqdEImtdQOeWvvGEHrThWCgAz5FMjckCQ,11557
|
|
@@ -414,25 +414,33 @@ claude_mpm/hooks/claude_hooks/correlation_manager.py,sha256=3n-RxzqE8egG4max_Ncp
|
|
|
414
414
|
claude_mpm/hooks/claude_hooks/event_handlers.py,sha256=u7qkfthzAJxE5X4vAp5dCYhVDsadfC--vsqZVlmcrvE,45768
|
|
415
415
|
claude_mpm/hooks/claude_hooks/hook_handler.py,sha256=UOl5IVvz0Ro8Z0Owx4sKUWCxoIhvQpt7VTJ8lRC7Y8o,28266
|
|
416
416
|
claude_mpm/hooks/claude_hooks/hook_wrapper.sh,sha256=XYkdYtcM0nfnwYvMdyIFCasr80ry3uI5-fLYsLtDGw4,2214
|
|
417
|
-
claude_mpm/hooks/claude_hooks/installer.py,sha256=
|
|
417
|
+
claude_mpm/hooks/claude_hooks/installer.py,sha256=GgXqRjm_LpukrMl-eLw3cVDJqwwemNAaEKZvKM0QDYQ,34919
|
|
418
418
|
claude_mpm/hooks/claude_hooks/memory_integration.py,sha256=fj_d9N7aytLELomdphLLwYApXzmbhBxtwSK4xkmd55o,10759
|
|
419
419
|
claude_mpm/hooks/claude_hooks/response_tracking.py,sha256=2dyDOK9u-N4KcqWF7qq2T17bkps0grbs8MeWBRSC8vE,16323
|
|
420
420
|
claude_mpm/hooks/claude_hooks/tool_analysis.py,sha256=3_o2PP9D7wEMwLriCtIBOw0cj2fSZfepN7lI4P1meSQ,7862
|
|
421
421
|
claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc,sha256=EGpgXqhPM0iRRZtCqHaLVQ6wDH42OH_M7Gt5GiFLyro,346
|
|
422
|
+
claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-312.pyc,sha256=RdPlaoNPDoSlTFV36Ku4vxs7xYqh7t2038D4pyULy-g,322
|
|
422
423
|
claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-314.pyc,sha256=tBzcQ_3WxkmgPTQAPd7uKgFGtz-Yb6r2hEgF9Y_Flwc,319
|
|
423
424
|
claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-311.pyc,sha256=7YbusOM2EaL4NqIuNsLTJRCRJWRxo0DhVLXm9ZVFc7Y,20829
|
|
425
|
+
claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-312.pyc,sha256=aUV7xCwxrzM4iW4Jf0RbUskIs2whf7lXt6HppAEMp1g,18982
|
|
424
426
|
claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-314.pyc,sha256=vo_mPXj0KTtBz2_SAU4NZ7TEWPfgBZtLeXD3CMAvJ3M,21381
|
|
425
427
|
claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc,sha256=SQX5iiP9bQZkLL-cj_2tlGH7lpAzarO0mYal7btj3tc,3521
|
|
426
428
|
claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc,sha256=43y-O3fzE07cyJx1we9DfLeaIkL0GQR4KKpnzh_94uk,44526
|
|
429
|
+
claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-312.pyc,sha256=3ezkq2yC1cejVa-II4cl335SWCJhD8dv_NEDtVsCpUo,39235
|
|
427
430
|
claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-314.pyc,sha256=DC4owkvPyhcCT7ScUxlKS6pUygaUYEMj0k3eVYZHdMk,42528
|
|
428
431
|
claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc,sha256=vhJjvAMTdDWkB_qWaWr_PeDb4I8-h7UymR1wDVHeyYM,30789
|
|
432
|
+
claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-312.pyc,sha256=bj168CD_Md4vpYJfS9YvPafP7-nw1hAUnuuEpzSQNKY,27815
|
|
429
433
|
claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-314.pyc,sha256=RVz6WvW-sD7kLbh6S5a96WarpPvZv4_qfFMR5SN8WUo,30603
|
|
430
|
-
claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-
|
|
434
|
+
claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc,sha256=Tt3L5Ye7RJCLvIAaz6uLwKe3WGEaMLx6WElvqK60G0Q,38428
|
|
435
|
+
claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-314.pyc,sha256=Mlynkrh8uwlSOTCEH0LYbDM0gxqJmaCL9Gb5DIt_rJ4,38836
|
|
431
436
|
claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc,sha256=Xu_hwOf9AG0mZthl5gcDcVv68FiSo5KgZ6lDxdZXCfU,11185
|
|
437
|
+
claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-312.pyc,sha256=w9SKmvg60p6kvNzuOIddYE-X9LYt-ZQzX3LWiKs4nZY,10055
|
|
432
438
|
claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-314.pyc,sha256=oJhMGouqaFI1u3NZryHoRh6ucfPKHPe8GufcsPzi89o,11081
|
|
433
439
|
claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc,sha256=qJ5xY8yYwo8ZO7P-Gem_GK4VZdqyNeYvs8ANvC45jnw,16228
|
|
440
|
+
claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-312.pyc,sha256=uyjnluDUFQql1N2oYP6IYP8dxhxnHoSvrmUubEMRNXI,14000
|
|
434
441
|
claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-314.pyc,sha256=yu70SIPNsdECY8l_P971JPFuUPXqD4HmjuuGMU-nSAU,15820
|
|
435
442
|
claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-311.pyc,sha256=ZjcNfNY5Ht6FhalPeh7M7OzMffcey5iF4AVjDDg9kak,10694
|
|
443
|
+
claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-312.pyc,sha256=T98zonvVkllflFNw_pptXXAXbDrIgeBfY6aXvSY8el8,9071
|
|
436
444
|
claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-314.pyc,sha256=ck8ifVIoVPaMVVRcMgvsM8RfIHnQbwGBUVs25A-yQBw,10771
|
|
437
445
|
claude_mpm/hooks/claude_hooks/services/__init__.py,sha256=OIYOKsUNw1BHYawOCp-KFK5kmQKuj92cCqCEPO0nwo0,585
|
|
438
446
|
claude_mpm/hooks/claude_hooks/services/connection_manager.py,sha256=shpoCLJpM9qoCDMUuUhk6L9WEKdzLB_OsPtwtDyJMdk,10197
|
|
@@ -441,14 +449,19 @@ claude_mpm/hooks/claude_hooks/services/duplicate_detector.py,sha256=Fh9LmEMsVmQM
|
|
|
441
449
|
claude_mpm/hooks/claude_hooks/services/state_manager.py,sha256=PcEpAzwEnZRjw6JnbtbekDRdhIoaKql5VhhZJCEPNt4,10899
|
|
442
450
|
claude_mpm/hooks/claude_hooks/services/subagent_processor.py,sha256=unHGeU6PJxc00_3xnLyyZHeLa47x98knxn6cl-i8ALA,15040
|
|
443
451
|
claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc,sha256=xBfLBSqnpcKfcQBWfh7xUm454g1lq1LvbO7SxGvcOPc,644
|
|
452
|
+
claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-312.pyc,sha256=75pkmoqE7CeBOc2ZHTYfgSR-mtVjKrcKaOA6PxFGW64,565
|
|
444
453
|
claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-314.pyc,sha256=nZDxNz67tIFwbZNRqyCRX8cSi0v3JKCZS5U5FhwwApA,562
|
|
445
454
|
claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc,sha256=SydGEQ9oUWs161Ro4ULHfnPB0wiZgiB7V628B3V6N2U,9613
|
|
455
|
+
claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-312.pyc,sha256=qdBU-mDyJxcwjwxfGhqzvo_s7YMO4mva-8hdObDAOcY,8616
|
|
446
456
|
claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-314.pyc,sha256=PjdPDUyUQWm0FqYRdG2knPoZDSKS0g1vk-BDAXfzCi8,9627
|
|
447
457
|
claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-311.pyc,sha256=Yy_REAUhJCiFjOhxeDb4v0qyEvEbUtCmXD9PAz40dhw,5321
|
|
458
|
+
claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-312.pyc,sha256=ef_Tx9Uv1CvS18tC_PXmGVvIoMDsRnEUhKRUZaUdGBw,4751
|
|
448
459
|
claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-314.pyc,sha256=Xy9iNAtQMfXC_eW9rvumG9rFqK5t-QlLPmUahlqza_I,5341
|
|
449
460
|
claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc,sha256=P-Au2P5H0enEeKm7sP1eQv-SU6AAnCqjjOE5jhXcrgs,12352
|
|
450
|
-
claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-
|
|
461
|
+
claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-312.pyc,sha256=g_Lo7LUYOEgIqS_Rz-6hy_caraHW9nzVJ6f0W4Y14rg,11378
|
|
462
|
+
claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-314.pyc,sha256=2QqT8edjLqG8-9q446zpLJ347lzkgvJxPJG-A8u_HAU,13101
|
|
451
463
|
claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc,sha256=4SfbElFMcQK07Frewl9mQ0eB5yCqZUe-CGfGYNUUMh0,14931
|
|
464
|
+
claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-312.pyc,sha256=Cky-0tvyWmn9I44WdupIdJ4Qml0k-qlCs5E0x0Y130Q,13301
|
|
452
465
|
claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-314.pyc,sha256=o6Dc1-yyZjUdVh_JWZmEIvVt0qG0R1-aLhr7XTt-oX0,15104
|
|
453
466
|
claude_mpm/hooks/failure_learning/__init__.py,sha256=iJ80AKFHiT8DjIH2a72DQVJvL6nAFrizNA2yTKwZ4rw,1805
|
|
454
467
|
claude_mpm/hooks/failure_learning/failure_detection_hook.py,sha256=KENoB5N-dBm5hb0SxeIZtCvNKbmG2BKHOJSrSO-3Z_I,7500
|
|
@@ -463,7 +476,7 @@ claude_mpm/models/git_repository.py,sha256=Lp2I5tv4fu6idIXCTW50MCTWgjuIE-rwsgVIr
|
|
|
463
476
|
claude_mpm/models/resume_log.py,sha256=aDiFC_2FR7tue_Kn46ZDUiKmuw9a_W9yE9zE7gA6Hys,12515
|
|
464
477
|
claude_mpm/schemas/__init__.py,sha256=2SLpkojJq34KnwPkVxrsVmw_cEI66872i75QBT1C2To,446
|
|
465
478
|
claude_mpm/scripts/__init__.py,sha256=IffMdVD99Pxyw85yluRa0VDPi4dRQecIWce764pcfZE,553
|
|
466
|
-
claude_mpm/scripts/claude-hook-handler.sh,sha256=
|
|
479
|
+
claude_mpm/scripts/claude-hook-handler.sh,sha256=1e5ZsZJQdp9lKLwEmmAtqnEGZPf5UIAG2ReGfwmXtOE,10907
|
|
467
480
|
claude_mpm/scripts/launch_monitor.py,sha256=M0CSAYJp5UnoyXKnICZgrAFwqqP5XAWDCiii_IIcrCk,5348
|
|
468
481
|
claude_mpm/scripts/mpm_doctor.py,sha256=98vBiTIB4xpaSgOvTP9N3EU22V2Odxd9DivhQizG0VM,8822
|
|
469
482
|
claude_mpm/scripts/socketio_daemon.py,sha256=wWFcvKkHa_oR-NQwhvV-O8s3m1TgicBp9UQ-NR8AQmU,6041
|
|
@@ -497,7 +510,7 @@ claude_mpm/services/self_upgrade_service.py,sha256=O5-uqjdt9BHt0bxLNzuYdzlwgtWF_
|
|
|
497
510
|
claude_mpm/services/session_management_service.py,sha256=za_ljDawCJjOq5ezEdxw71MFFFFIbWlV6ujlWL3vImg,10723
|
|
498
511
|
claude_mpm/services/session_manager.py,sha256=ddVdINaHzBol24KvFCLOyM5SuBG_-Vd8_iT2YTBlGiU,12328
|
|
499
512
|
claude_mpm/services/skills_config.py,sha256=R9F3BV3BEVmjqlxBy2mZycH4cCH4Ieh3K1n_8w9a5zQ,18005
|
|
500
|
-
claude_mpm/services/skills_deployer.py,sha256=
|
|
513
|
+
claude_mpm/services/skills_deployer.py,sha256=iNT939b6akNEe0libu00fyYSceSKh4YYeu7ehb3v5F0,47270
|
|
501
514
|
claude_mpm/services/socketio_client_manager.py,sha256=cZjIsnoi2VPXFA-5pNhoz5Vv3qv0iuSTy510TgAJU4U,18179
|
|
502
515
|
claude_mpm/services/socketio_server.py,sha256=yE14_4pHERXBC5L1WQCpIBHuy0tpklsUY_icyl-nLkg,3033
|
|
503
516
|
claude_mpm/services/subprocess_launcher_service.py,sha256=lYSlg2G_oDAv1dHrOdHaOEIppDwisANCASuNFdp0WqY,11226
|
|
@@ -510,7 +523,7 @@ claude_mpm/services/agents/agent_builder.py,sha256=ehnzIgQ3OcF5ThqvbmS4c4ZyA-hbp
|
|
|
510
523
|
claude_mpm/services/agents/agent_preset_service.py,sha256=YpIKwaq52Pi4ox6ha3L9qTT4GHc-1nPeGgV0MWGRIAs,8588
|
|
511
524
|
claude_mpm/services/agents/agent_recommendation_service.py,sha256=f3F6LkPG1S42ZE52o8QnSdFwZFsv_7vgegJ6bCNbWWk,9846
|
|
512
525
|
claude_mpm/services/agents/agent_review_service.py,sha256=1meV6u8FGbYMx1vhSsCX8OembWbF3gXfl26hRdGd95Y,10001
|
|
513
|
-
claude_mpm/services/agents/agent_selection_service.py,sha256=
|
|
526
|
+
claude_mpm/services/agents/agent_selection_service.py,sha256=rhbLrwuNsofH-U6sfJIn7Zp0Ek3YDmznNEIQUlJe1tM,17943
|
|
514
527
|
claude_mpm/services/agents/auto_config_manager.py,sha256=WdrOaosxmK1iD-1Me7eZ-VJzMW-p8liei6iEjGkbodA,30706
|
|
515
528
|
claude_mpm/services/agents/auto_deploy_index_parser.py,sha256=-29NBjr6u8QEcFYfygt2CqqGtS1XEN6NoJtsM6cDUAU,19465
|
|
516
529
|
claude_mpm/services/agents/cache_git_manager.py,sha256=gfrcAZULY-oZDBuf20ubUE1STYLBu4c-UIjIu5cYsCA,23583
|
|
@@ -518,7 +531,7 @@ claude_mpm/services/agents/git_source_manager.py,sha256=SRGX4T-dUuLn2PDe1EkTL493
|
|
|
518
531
|
claude_mpm/services/agents/local_template_manager.py,sha256=v1vlukIVEpiw5u11KseJhEMkhi1tlm6FTp0FYwK9YFU,27980
|
|
519
532
|
claude_mpm/services/agents/observers.py,sha256=2OUEMc2TzHrME2AHHnBmquWmbhGEMTNpTc08sIoHno0,18484
|
|
520
533
|
claude_mpm/services/agents/recommender.py,sha256=TC8iLNi_uP0byj8w9jXHhl0PYn0JDfAgRMjbTgSwafE,23756
|
|
521
|
-
claude_mpm/services/agents/single_tier_deployment_service.py,sha256=
|
|
534
|
+
claude_mpm/services/agents/single_tier_deployment_service.py,sha256=M1ep-yTcwk8OLhnkg5p2vNsqynpP49rRAxPxvpsG7ac,25380
|
|
522
535
|
claude_mpm/services/agents/startup_sync.py,sha256=VoTSFtYF-BZZSCzoeAF6LpQ-tq3BjE4Ua-N9sdRikak,9310
|
|
523
536
|
claude_mpm/services/agents/toolchain_detector.py,sha256=eGzMprsD1M7DXHGN0RhhUz3diITbiXtHZw0uK7rZ6Nk,16854
|
|
524
537
|
claude_mpm/services/agents/deployment/__init__.py,sha256=iprW-Ww3LBtWu9pVFjAX45_CswfSqnPMoG0QoFPd1Dg,539
|
|
@@ -803,9 +816,9 @@ claude_mpm/services/shared/lifecycle_service_base.py,sha256=YJZHs2sUrnIsbHHjrd8l
|
|
|
803
816
|
claude_mpm/services/shared/manager_base.py,sha256=kmjhpVqgfYC1N4YQnPAilCfdrSpAh9Qz7wcQ602L4x4,9296
|
|
804
817
|
claude_mpm/services/shared/service_factory.py,sha256=9yvnD62urrNQCGmtk_3OcR5tVUCnoS6wHkaI5PK34mg,9891
|
|
805
818
|
claude_mpm/services/skills/__init__.py,sha256=X1fPRCGZjteLd35HlhWv2M6tAJ_WbYrEv84kbaqBAiU,742
|
|
806
|
-
claude_mpm/services/skills/git_skill_source_manager.py,sha256=
|
|
807
|
-
claude_mpm/services/skills/selective_skill_deployer.py,sha256=
|
|
808
|
-
claude_mpm/services/skills/skill_discovery_service.py,sha256=
|
|
819
|
+
claude_mpm/services/skills/git_skill_source_manager.py,sha256=92fz9I7zYemQ7tV3-s0wzmU5wV7KCMnd-MzKXq6ssfY,56857
|
|
820
|
+
claude_mpm/services/skills/selective_skill_deployer.py,sha256=tWWs2RLatD1cP4MnDcVN6J2-hk6GuYPKg9chTXyDXGM,30639
|
|
821
|
+
claude_mpm/services/skills/skill_discovery_service.py,sha256=uJUdjB54N6w9g8KFi7WmobA-R-pBh3ND12qA2HYxd5I,23003
|
|
809
822
|
claude_mpm/services/skills/skill_to_agent_mapper.py,sha256=4PRwcSDSNGS55lg4t-VmBK2ottE_cGFq1zsvjiumAlI,14847
|
|
810
823
|
claude_mpm/services/socketio/__init__.py,sha256=PS-2twllga-2mhSfKdu4MgpikfKp_730gMLAqU_9YX4,556
|
|
811
824
|
claude_mpm/services/socketio/client_proxy.py,sha256=DFPO5OIl-cHusldHPYWKSbnL0dxSLz8h07D9307FfzY,8853
|
|
@@ -1096,10 +1109,10 @@ claude_mpm/utils/subprocess_utils.py,sha256=D0izRT8anjiUb_JG72zlJR_JAw1cDkb7kalN
|
|
|
1096
1109
|
claude_mpm/validation/__init__.py,sha256=YZhwE3mhit-lslvRLuwfX82xJ_k4haZeKmh4IWaVwtk,156
|
|
1097
1110
|
claude_mpm/validation/agent_validator.py,sha256=GprtAvu80VyMXcKGsK_VhYiXWA6BjKHv7O6HKx0AB9w,20917
|
|
1098
1111
|
claude_mpm/validation/frontmatter_validator.py,sha256=YpJlYNNYcV8u6hIOi3_jaRsDnzhbcQpjCBE6eyBKaFY,7076
|
|
1099
|
-
claude_mpm-5.6.
|
|
1100
|
-
claude_mpm-5.6.
|
|
1101
|
-
claude_mpm-5.6.
|
|
1102
|
-
claude_mpm-5.6.
|
|
1103
|
-
claude_mpm-5.6.
|
|
1104
|
-
claude_mpm-5.6.
|
|
1105
|
-
claude_mpm-5.6.
|
|
1112
|
+
claude_mpm-5.6.9.dist-info/licenses/LICENSE,sha256=ca3y_Rk4aPrbF6f62z8Ht5MJM9OAvbGlHvEDcj9vUQ4,3867
|
|
1113
|
+
claude_mpm-5.6.9.dist-info/licenses/LICENSE-FAQ.md,sha256=TxfEkXVCK98RzDOer09puc7JVCP_q_bN4dHtZKHCMcM,5104
|
|
1114
|
+
claude_mpm-5.6.9.dist-info/METADATA,sha256=zFOkKrO7QsszgLAusCpXjQiG-wsHRWCsCsxOIYntIL0,14983
|
|
1115
|
+
claude_mpm-5.6.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
1116
|
+
claude_mpm-5.6.9.dist-info/entry_points.txt,sha256=n-Uk4vwHPpuvu-g_I7-GHORzTnN_m6iyOsoLveKKD0E,228
|
|
1117
|
+
claude_mpm-5.6.9.dist-info/top_level.txt,sha256=1nUg3FEaBySgm8t-s54jK5zoPnu3_eY6EP6IOlekyHA,11
|
|
1118
|
+
claude_mpm-5.6.9.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|