claude-mpm 5.6.5__py3-none-any.whl → 5.6.8__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 (39) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/base_agent.json +1 -1
  3. claude_mpm/cli/commands/skill_source.py +51 -2
  4. claude_mpm/cli/commands/skills.py +5 -3
  5. claude_mpm/cli/parsers/skill_source_parser.py +4 -0
  6. claude_mpm/cli/parsers/skills_parser.py +5 -0
  7. claude_mpm/config/skill_sources.py +16 -0
  8. claude_mpm/core/config.py +27 -19
  9. claude_mpm/dashboard/static/svelte-build/_app/env.js +1 -1
  10. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BQaXIfA_.js +16 -16
  11. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-312.pyc +0 -0
  12. claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-312.pyc +0 -0
  13. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-312.pyc +0 -0
  14. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-312.pyc +0 -0
  15. claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
  16. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-312.pyc +0 -0
  17. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-312.pyc +0 -0
  18. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-312.pyc +0 -0
  19. claude_mpm/hooks/claude_hooks/installer.py +41 -0
  20. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-312.pyc +0 -0
  21. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-312.pyc +0 -0
  22. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-312.pyc +0 -0
  23. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-312.pyc +0 -0
  24. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-314.pyc +0 -0
  25. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-312.pyc +0 -0
  26. claude_mpm/scripts/claude-hook-handler.sh +5 -5
  27. claude_mpm/services/agents/agent_selection_service.py +2 -2
  28. claude_mpm/services/agents/single_tier_deployment_service.py +4 -4
  29. claude_mpm/services/skills/git_skill_source_manager.py +79 -8
  30. claude_mpm/services/skills/selective_skill_deployer.py +28 -0
  31. claude_mpm/services/skills/skill_discovery_service.py +17 -1
  32. claude_mpm/services/skills_deployer.py +31 -5
  33. {claude_mpm-5.6.5.dist-info → claude_mpm-5.6.8.dist-info}/METADATA +1 -1
  34. {claude_mpm-5.6.5.dist-info → claude_mpm-5.6.8.dist-info}/RECORD +39 -26
  35. {claude_mpm-5.6.5.dist-info → claude_mpm-5.6.8.dist-info}/WHEEL +0 -0
  36. {claude_mpm-5.6.5.dist-info → claude_mpm-5.6.8.dist-info}/entry_points.txt +0 -0
  37. {claude_mpm-5.6.5.dist-info → claude_mpm-5.6.8.dist-info}/licenses/LICENSE +0 -0
  38. {claude_mpm-5.6.5.dist-info → claude_mpm-5.6.8.dist-info}/licenses/LICENSE-FAQ.md +0 -0
  39. {claude_mpm-5.6.5.dist-info → claude_mpm-5.6.8.dist-info}/top_level.txt +0 -0
claude_mpm/VERSION CHANGED
@@ -1 +1 @@
1
- 5.6.5
1
+ 5.6.8
@@ -28,4 +28,4 @@
28
28
  "claude-4-opus"
29
29
  ]
30
30
  }
31
- }
31
+ }
@@ -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
- response = requests.get(api_url, timeout=10)
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": "Access denied (private repository or rate limit)",
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
- # Selective deployment is ALWAYS enabled (deploy only agent-referenced skills)
552
- # This ensures only skills linked to deployed agents are deployed
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=True, # Always use selective deployment
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(
@@ -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
- from ..utils.config_manager import ConfigurationManager
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
- # Catch any remaining unexpected errors and wrap them as configuration errors
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={
@@ -1 +1 @@
1
- export const env={}
1
+ export const env={}
@@ -43,10 +43,10 @@ https://github.com/jquery/jquery/blob/master/src/event.js
43
43
  vec2 v = ab*vec2(-cs.y,cs.x);
44
44
  w = w + dot(p-u,v)/(dot(p-u,u)+dot(v,v));
45
45
  }
46
-
46
+
47
47
  // compute final point and distance
48
48
  float d = length(p-ab*vec2(cos(w),sin(w)));
49
-
49
+
50
50
  // return signed distance
51
51
  return (dot(p/ab,p/ab)>1.0) ? d : -d;
52
52
  }
@@ -55,16 +55,16 @@ https://github.com/jquery/jquery/blob/master/src/event.js
55
55
 
56
56
  uniform mat3 uPanZoomMatrix;
57
57
  uniform int uAtlasSize;
58
-
58
+
59
59
  // instanced
60
60
  in vec2 aPosition; // a vertex from the unit square
61
-
61
+
62
62
  in mat3 aTransform; // used to transform verticies, eg into a bounding box
63
63
  in int aVertType; // the type of thing we are rendering
64
64
 
65
65
  // the z-index that is output when using picking mode
66
66
  in vec4 aIndex;
67
-
67
+
68
68
  // For textures
69
69
  in int aAtlasId; // which shader unit/atlas to use
70
70
  in vec4 aTex; // x/y/w/h of texture in atlas
@@ -84,7 +84,7 @@ https://github.com/jquery/jquery/blob/master/src/event.js
84
84
  out vec4 vColor;
85
85
  out vec2 vPosition;
86
86
  // flat values are not interpolated
87
- flat out int vAtlasId;
87
+ flat out int vAtlasId;
88
88
  flat out int vVertType;
89
89
  flat out vec2 vTopRight;
90
90
  flat out vec2 vBotLeft;
@@ -92,7 +92,7 @@ https://github.com/jquery/jquery/blob/master/src/event.js
92
92
  flat out vec4 vBorderColor;
93
93
  flat out vec2 vBorderWidth;
94
94
  flat out vec4 vIndex;
95
-
95
+
96
96
  void main(void) {
97
97
  int vid = gl_VertexID;
98
98
  vec2 position = aPosition; // TODO make this a vec3, simplifies some code below
@@ -115,7 +115,7 @@ https://github.com/jquery/jquery/blob/master/src/event.js
115
115
 
116
116
  gl_Position = vec4(uPanZoomMatrix * aTransform * vec3(position, 1.0), 1.0);
117
117
  }
118
- else if(aVertType == `).concat(_t," || aVertType == ").concat(pa,`
118
+ else if(aVertType == `).concat(_t," || aVertType == ").concat(pa,`
119
119
  || aVertType == `).concat(sn," || aVertType == ").concat(ga,`) { // simple shapes
120
120
 
121
121
  // the bounding box is needed by the fragment shader
@@ -145,7 +145,7 @@ https://github.com/jquery/jquery/blob/master/src/event.js
145
145
 
146
146
  gl_Position = vec4(uPanZoomMatrix * vec3(point, 1.0), 1.0);
147
147
  vColor = aColor;
148
- }
148
+ }
149
149
  else if(aVertType == `).concat(Xl,`) {
150
150
  vec2 pointA = aPointAPointB.xy;
151
151
  vec2 pointB = aPointAPointB.zw;
@@ -194,7 +194,7 @@ https://github.com/jquery/jquery/blob/master/src/event.js
194
194
  }
195
195
 
196
196
  vColor = aColor;
197
- }
197
+ }
198
198
  else if(aVertType == `).concat(Ts,` && vid < 3) {
199
199
  // massage the first triangle into an edge arrow
200
200
  if(vid == 0)
@@ -246,16 +246,16 @@ https://github.com/jquery/jquery/blob/master/src/event.js
246
246
  `).concat(vm,`
247
247
 
248
248
  vec4 blend(vec4 top, vec4 bot) { // blend colors with premultiplied alpha
249
- return vec4(
249
+ return vec4(
250
250
  top.rgb + (bot.rgb * (1.0 - top.a)),
251
- top.a + (bot.a * (1.0 - top.a))
251
+ top.a + (bot.a * (1.0 - top.a))
252
252
  );
253
253
  }
254
254
 
255
255
  vec4 distInterp(vec4 cA, vec4 cB, float d) { // interpolate color using Signed Distance
256
256
  // scale to the zoom level so that borders don't look blurry when zoomed in
257
257
  // note 1.5 is an aribitrary value chosen because it looks good
258
- return mix(cA, cB, 1.0 - smoothstep(0.0, 1.5 / uZoom, abs(d)));
258
+ return mix(cA, cB, 1.0 - smoothstep(0.0, 1.5 / uZoom, abs(d)));
259
259
  }
260
260
 
261
261
  void main(void) {
@@ -263,7 +263,7 @@ https://github.com/jquery/jquery/blob/master/src/event.js
263
263
  // look up the texel from the texture unit
264
264
  `).concat(i.map(function(u){return"if(vAtlasId == ".concat(u,") outColor = texture(uTexture").concat(u,", vTexCoord);")}).join(`
265
265
  else `),`
266
- }
266
+ }
267
267
  else if(vVertType == `).concat(Ts,`) {
268
268
  // mimics how canvas renderer uses context.globalCompositeOperation = 'destination-out';
269
269
  outColor = blend(vColor, uBGColor);
@@ -272,7 +272,7 @@ https://github.com/jquery/jquery/blob/master/src/event.js
272
272
  else if(vVertType == `).concat(_t,` && vBorderWidth == vec2(0.0)) { // simple rectangle with no border
273
273
  outColor = vColor; // unit square is already transformed to the rectangle, nothing else needs to be done
274
274
  }
275
- else if(vVertType == `).concat(_t," || vVertType == ").concat(pa,`
275
+ else if(vVertType == `).concat(_t," || vVertType == ").concat(pa,`
276
276
  || vVertType == `).concat(sn," || vVertType == ").concat(ga,`) { // use SDF
277
277
 
278
278
  float outerBorder = vBorderWidth[0];
@@ -307,7 +307,7 @@ https://github.com/jquery/jquery/blob/master/src/event.js
307
307
  vec4 outerColor = outerBorder == 0.0 ? vec4(0) : vBorderColor;
308
308
  vec4 innerBorderColor = blend(vBorderColor, vColor);
309
309
  outColor = distInterp(innerBorderColor, outerColor, d);
310
- }
310
+ }
311
311
  else {
312
312
  vec4 outerColor;
313
313
  if(innerBorder == 0.0 && outerBorder == 0.0) {
@@ -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)
@@ -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 python" ]]; then
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 python" ]]; then
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 src.claude_mpm.services.agents.single_tier_deployment_service import (
42
+ from claude_mpm.services.agents.single_tier_deployment_service import (
43
43
  SingleTierDeploymentService,
44
44
  )
45
- from src.claude_mpm.services.agents.toolchain_detector import ToolchainDetector
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 src.claude_mpm.config.agent_sources import AgentSourceConfiguration
34
- from src.claude_mpm.models.git_repository import GitRepository
35
- from src.claude_mpm.services.agents.deployment.remote_agent_discovery_service import (
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 src.claude_mpm.services.agents.git_source_manager import GitSourceManager
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
- refs_response = requests.get(
600
- refs_url, headers={"Accept": "application/vnd.github+json"}, timeout=30
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={"Accept": "application/vnd.github+json"},
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, url: str, local_path: Path, force: bool = False
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
- self.logger.info(f"Discovered {len(skills)} skills from {self.skills_dir.name}")
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,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: claude-mpm
3
- Version: 5.6.5
3
+ Version: 5.6.8
4
4
  Summary: Claude Multi-Agent Project Manager - Orchestrate Claude with agent delegation and ticket tracking
5
5
  Author-email: Bob Matsuoka <bob@matsuoka.com>
6
6
  Maintainer: Claude MPM Team
@@ -1,5 +1,5 @@
1
1
  claude_mpm/BUILD_NUMBER,sha256=9JfxhnDtr-8l3kCP2U5TVXSErptHoga8m7XA8zqgGOc,4
2
- claude_mpm/VERSION,sha256=Wwas5xnKQTkqXgApeVHQvWZFinNkdNv7W6HjYbrwERA,6
2
+ claude_mpm/VERSION,sha256=TPELZ4bSYPd1-ct4QNuu3EP8d8XmrNtWst8upoSOwfY,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
@@ -19,7 +19,7 @@ claude_mpm/agents/agent_loader.py,sha256=lrE6IMmvFeGVFguNTmi8d6WYyMb8goqcXj6RmiP
19
19
  claude_mpm/agents/agent_loader_integration.py,sha256=cU1LKCYvopZn66UefwzZxJUdTSxn6HLxdbukTjmP-KM,7280
20
20
  claude_mpm/agents/agents_metadata.py,sha256=XklRSaYxKt8_2hnGn9xr-V15RMcm57Fi-QzPbAe4ZR4,9867
21
21
  claude_mpm/agents/async_agent_loader.py,sha256=w9zk88SZUBycQeTHKrUiUez0CY_BrWZi13-EF6IOwWU,14597
22
- claude_mpm/agents/base_agent.json,sha256=9bWj1sL1AjGcvXdF8AiFZy0S6q_sJa2Zo_NGg9v8wkM,27614
22
+ claude_mpm/agents/base_agent.json,sha256=CTy670tMO_U7KiVuqtjk4LNU-TDociRNHX_J6hfEcH4,27615
23
23
  claude_mpm/agents/frontmatter_validator.py,sha256=H0R7rCrNdaok5q7yCxEX2uiIcELU286tgGbTK05tRf0,27471
24
24
  claude_mpm/agents/system_agent_config.py,sha256=19axX46jzvY6svETjfMaFyAYtgbQO2PRXKJ-VYnCPDk,24137
25
25
  claude_mpm/agents/templates/README.md,sha256=qqhKh10y2CGuoytQmqlQtXCa_RD1ZmeT0m24S5VPQnI,18511
@@ -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=UlEA7O3rGT14zmqifMclSXyDJvp7lDUBc1pbZ4qp_0k,22436
102
- claude_mpm/cli/commands/skills.py,sha256=Q6VIPNgGCIB_YGYR7_lna78OIJSnYFS-SEaX6NDCsHM,58232
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=D1fMXfL-BDbuLOlznJ8zmwNuo9ixj_rERz6npLwla0Q,4874
142
- claude_mpm/cli/parsers/skills_parser.py,sha256=FGKuDzZkoOyW4vRsUYjd5B-Vqlm6LLrDP0BtDW9jRKM,8741
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
@@ -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=z9JIUfoE9zipAy2OSaLbjD0sk-Du8rSO--BbolhtXaM,19746
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=IGhNAkq8qtoIcayrIqGH0GY64S_J4nzQ1xN4p4LDpNw,42748
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
@@ -320,7 +320,7 @@ claude_mpm/dashboard/__init__.py,sha256=b5QKcz0kt_ZMCFkac7caRzA8DlMiICG9VzmunmxH
320
320
  claude_mpm/dashboard/api/simple_directory.py,sha256=b-ExWd9wutYIYa4dTYBW0y1s0hsElPn4_LLJglahUEY,7140
321
321
  claude_mpm/dashboard/static/svelte-build/favicon.svg,sha256=8WC8JPrjCWsajGxiyBr7WA7Sj896PtUZbYkVjNwd2K0,395
322
322
  claude_mpm/dashboard/static/svelte-build/index.html,sha256=QBZs_8cByu6lVPp5Upp1gxXDblACI74nlRjWIGqK6Pk,1173
323
- claude_mpm/dashboard/static/svelte-build/_app/env.js,sha256=PFiLdc3lIpkAIqcK3hezpttwaPaFrEy4sxoQT34lhwY,19
323
+ claude_mpm/dashboard/static/svelte-build/_app/env.js,sha256=Iu6wbiiLCcW1n9HhTsju7Y83nmMPQC3Myj_B4dOvWXM,20
324
324
  claude_mpm/dashboard/static/svelte-build/_app/version.json,sha256=SqUDoSw125-s8xi_Diq0Oy3VjnesiIuCvs7CTZgjwIE,28
325
325
  claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.C33zOoyM.css,sha256=BLNxSTDsHOlvyrjeUgRzDhb4A3kPpI1pnIayA6UNBPM,28444
326
326
  claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.CW1J-YuA.css,sha256=HC7G-CRMmKQWPd26CLlZAL1pa0oUXXQbZ6A88CbTqvg,15985
@@ -332,7 +332,7 @@ claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/9a6T2nm-.js,sha25
332
332
  claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B443AUzu.js,sha256=roecan2HnDRdCpfyDiBPgrwlIi5l5IEWT-CTweT5jDI,29257
333
333
  claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B8AwtY2H.js,sha256=7kfWcHYrVg1L5QidpYuUJJvy1YdmERs_srdTBnEad34,27498
334
334
  claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BF15LAsF.js,sha256=LAuNlMt2us_gAtGKbVup7j2MXE8emIrHx0I82WAe9Hk,571
335
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BQaXIfA_.js,sha256=3VAewprLyc27yeOkKh16A3YpviIhZ_ZQr2pw0Kfs7Rs,442442
335
+ claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BQaXIfA_.js,sha256=bc2Upkbz5NyfLBmTs6l1D25pzEVLAaFVnCglNqBdPqA,442400
336
336
  claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BRcwIQNr.js,sha256=n6_iC4k_7w0Rxpw3zt0p6KoyL3_2S0EOJ_Nw7MmEH2Y,11160
337
337
  claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BSNlmTZj.js,sha256=Pcz47MBoSVumz-ilxfVzQOSz67t1FtEb0lADSpVoad0,523
338
338
  claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BV6nKitt.js,sha256=GNpl2Q76B1KopKPiIz6MrmyucF0eoqMzRhQjeZ2bJ3w,5891
@@ -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=X6m0CQ9mjaESqUu9RF00uOopZx1u5VOeR0-ilyaP6Xg,33275
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
434
+ claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc,sha256=Tt3L5Ye7RJCLvIAaz6uLwKe3WGEaMLx6WElvqK60G0Q,38428
430
435
  claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-314.pyc,sha256=hxxLzkAFGV4sBK3NiYZ6zVlc1Cq9yTc8YPzp-mf5sxo,37219
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-314.pyc,sha256=-H3-oDao1c8Dy1reMR98kR1W556eNpPmRWOvKGszKz4,13101
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=B5DbrOcHNX4xUC5kqftsLaGLQXs64WxVjDue7yMAwsU,10824
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=TecmqbRPvC7-gZewAwcp8Mjjna_nr6eUFdadwHZMv00,45761
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=ItCXMuFv3XzBuZAVUvx74gMeRbXTCOBFh5vLlgurJKg,17951
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=PDkTJmtBdNMzvdlONzUgQ53ymAFTqOsL06vg4NuqpnQ,25396
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=DQ-Zw7O9_a9YWdRT3Os4Jzq2m7ihw2pyUMqOiNHE374,53990
807
- claude_mpm/services/skills/selective_skill_deployer.py,sha256=yUiciVynJ3WDTO-l7Oz6_y9NaqeQS4xwNVp3KXDOtgA,29565
808
- claude_mpm/services/skills/skill_discovery_service.py,sha256=guul1xME46hzHqTRIJeTDIKQz55AQlOX1CRALWvfnoI,22403
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.5.dist-info/licenses/LICENSE,sha256=ca3y_Rk4aPrbF6f62z8Ht5MJM9OAvbGlHvEDcj9vUQ4,3867
1100
- claude_mpm-5.6.5.dist-info/licenses/LICENSE-FAQ.md,sha256=TxfEkXVCK98RzDOer09puc7JVCP_q_bN4dHtZKHCMcM,5104
1101
- claude_mpm-5.6.5.dist-info/METADATA,sha256=G50Re3GrZttFycswLOr3Q_yl-JH3cuDqPMJu2UraWTE,14983
1102
- claude_mpm-5.6.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1103
- claude_mpm-5.6.5.dist-info/entry_points.txt,sha256=n-Uk4vwHPpuvu-g_I7-GHORzTnN_m6iyOsoLveKKD0E,228
1104
- claude_mpm-5.6.5.dist-info/top_level.txt,sha256=1nUg3FEaBySgm8t-s54jK5zoPnu3_eY6EP6IOlekyHA,11
1105
- claude_mpm-5.6.5.dist-info/RECORD,,
1112
+ claude_mpm-5.6.8.dist-info/licenses/LICENSE,sha256=ca3y_Rk4aPrbF6f62z8Ht5MJM9OAvbGlHvEDcj9vUQ4,3867
1113
+ claude_mpm-5.6.8.dist-info/licenses/LICENSE-FAQ.md,sha256=TxfEkXVCK98RzDOer09puc7JVCP_q_bN4dHtZKHCMcM,5104
1114
+ claude_mpm-5.6.8.dist-info/METADATA,sha256=8lS7j7tnOGNu9c1kzaDSZwcUK-D84gQbbCb_MoncT_4,14983
1115
+ claude_mpm-5.6.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1116
+ claude_mpm-5.6.8.dist-info/entry_points.txt,sha256=n-Uk4vwHPpuvu-g_I7-GHORzTnN_m6iyOsoLveKKD0E,228
1117
+ claude_mpm-5.6.8.dist-info/top_level.txt,sha256=1nUg3FEaBySgm8t-s54jK5zoPnu3_eY6EP6IOlekyHA,11
1118
+ claude_mpm-5.6.8.dist-info/RECORD,,