📦 deps(skills): sync thirdparty skills

This commit is contained in:
ci[bot]
2026-07-03 16:04:18 +00:00
parent 2ba6cda440
commit 032d65368e
5 changed files with 257 additions and 25 deletions
+193 -21
View File
@@ -40,6 +40,39 @@ SEARCH_CONFIG = {
"typography": {"max_results": 2}
}
# ============ DESIGN DIALS (1-10) ============
# Inspired by taste-skill's DESIGN_VARIANCE / MOTION_INTENSITY / VISUAL_DENSITY
# knobs: three optional 1-10 sliders that bias the existing query-based search
# instead of replacing it. Each dial buckets into a low/mid/high tier.
DIAL_TIERS = {
"variance": [
(1, 3, {"label": "Centered / Minimal", "style_keywords": ["Minimalism", "Exaggerated Minimalism", "centered", "symmetric", "grid-based"]}),
(4, 7, {"label": "Balanced / Modern", "style_keywords": ["modern", "structured", "balanced"]}),
(8, 10, {"label": "Bold / Asymmetric", "style_keywords": ["Brutalism", "Bento Grids", "asymmetric", "experimental"]}),
],
"motion": [
(1, 3, {"label": "Subtle", "tier": "Subtle"}),
(4, 7, {"label": "Standard", "tier": "Standard"}),
(8, 10, {"label": "Complex", "tier": "Complex"}),
],
"density": [
(1, 3, {"label": "Spacious", "spacing": {"xs": "4px", "sm": "8px", "md": "24px", "lg": "32px", "xl": "48px", "2xl": "64px", "3xl": "96px"}}),
(4, 7, {"label": "Standard", "spacing": {"xs": "4px", "sm": "8px", "md": "16px", "lg": "24px", "xl": "32px", "2xl": "48px", "3xl": "64px"}}),
(8, 10, {"label": "Dense / Dashboard", "spacing": {"xs": "2px", "sm": "4px", "md": "8px", "lg": "12px", "xl": "16px", "2xl": "24px", "3xl": "32px"}}),
],
}
def _resolve_dial(dial_name: str, value) -> dict:
"""Bucket a 1-10 dial value into its tier config. Returns None if value is None."""
if value is None:
return None
value = max(1, min(10, int(value)))
for lo, hi, info in DIAL_TIERS[dial_name]:
if lo <= value <= hi:
return {**info, "value": value}
return None
# ============ DESIGN SYSTEM GENERATOR ============
class DesignSystemGenerator:
@@ -168,8 +201,18 @@ class DesignSystemGenerator:
"""Extract results list from search result dict."""
return search_result.get("results", [])
def generate(self, query: str, project_name: str = None) -> dict:
"""Generate complete design system recommendation."""
def generate(self, query: str, project_name: str = None,
variance: int = None, motion: int = None, density: int = None) -> dict:
"""Generate complete design system recommendation.
variance/motion/density are optional 1-10 dials (see DIAL_TIERS) that bias
style selection, pull in a matching motion.csv snippet, and override the
spacing scale, without changing behavior when left unset.
"""
variance_info = _resolve_dial("variance", variance)
motion_info = _resolve_dial("motion", motion)
density_info = _resolve_dial("density", density)
# Step 1: First search product to get category
product_result = search(query, "product", 1)
product_results = product_result.get("results", [])
@@ -181,8 +224,14 @@ class DesignSystemGenerator:
reasoning = self._apply_reasoning(category, {})
style_priority = reasoning.get("style_priority", [])
# DESIGN_VARIANCE dial: bias style retrieval/selection toward
# centered-minimal (low) or bold-asymmetric (high) keywords.
effective_style_priority = style_priority
if variance_info:
effective_style_priority = variance_info["style_keywords"] + style_priority
# Step 3: Multi-domain search with style priority hints
search_results = self._multi_domain_search(query, style_priority)
search_results = self._multi_domain_search(query, effective_style_priority)
search_results["product"] = product_result # Reuse product search
# Step 4: Select best matches from each domain using priority
@@ -191,11 +240,24 @@ class DesignSystemGenerator:
typography_results = self._extract_results(search_results.get("typography", {}))
landing_results = self._extract_results(search_results.get("landing", {}))
best_style = self._select_best_match(style_results, reasoning.get("style_priority", []))
best_style = self._select_best_match(style_results, effective_style_priority)
best_color = color_results[0] if color_results else {}
best_typography = typography_results[0] if typography_results else {}
best_landing = landing_results[0] if landing_results else {}
# MOTION_INTENSITY dial: pull a matching GSAP skeleton from motion.csv
# (domain key is "gsap", not "motion" - PR #296 already owns the "motion"
# domain for Emil Kowalski's motion-design principles, motion-principles.csv).
motion_snippet = {}
if motion_info:
motion_result = search(f"{query} {motion_info['tier']}", "gsap", 5)
motion_matches = motion_result.get("results", [])
tiered = [m for m in motion_matches if m.get("Intensity Tier") == motion_info["tier"]]
if tiered:
motion_snippet = tiered[0]
elif motion_matches:
motion_snippet = motion_matches[0]
# Step 5: Build final recommendation
# Combine effects from both reasoning and style search
style_effects = best_style.get("Effects & Animation", "")
@@ -250,7 +312,17 @@ class DesignSystemGenerator:
"key_effects": combined_effects,
"anti_patterns": reasoning.get("anti_patterns", ""),
"decision_rules": reasoning.get("decision_rules", {}),
"severity": reasoning.get("severity", "MEDIUM")
"severity": reasoning.get("severity", "MEDIUM"),
"dials": {
"variance": variance_info["value"] if variance_info else None,
"variance_label": variance_info["label"] if variance_info else None,
"motion": motion_info["value"] if motion_info else None,
"motion_label": motion_info["label"] if motion_info else None,
"density": density_info["value"] if density_info else None,
"density_label": density_info["label"] if density_info else None,
},
"motion_snippet": motion_snippet,
"spacing_scale": density_info["spacing"] if density_info else None,
}
@@ -296,6 +368,8 @@ def format_ascii_box(design_system: dict) -> str:
typography = design_system.get("typography", {})
effects = design_system.get("key_effects", "")
anti_patterns = design_system.get("anti_patterns", "")
dials = design_system.get("dials", {})
motion_snippet = design_system.get("motion_snippet", {})
def wrap_text(text: str, prefix: str, width: int) -> list:
"""Wrap long text into multiple lines."""
@@ -329,6 +403,16 @@ def format_ascii_box(design_system: dict) -> str:
lines.append("" + "" * w + "")
lines.append("" + "" * w + "")
# Design Dials section (only if at least one dial was set)
if any(dials.get(k) is not None for k in ("variance", "motion", "density")):
lines.append(section_header("DESIGN DIALS", BOX_WIDTH + 1))
if dials.get("variance") is not None:
lines.append(f"│ Variance: {dials['variance']}/10 — {dials['variance_label']}".ljust(BOX_WIDTH) + "")
if dials.get("motion") is not None:
lines.append(f"│ Motion: {dials['motion']}/10 — {dials['motion_label']}".ljust(BOX_WIDTH) + "")
if dials.get("density") is not None:
lines.append(f"│ Density: {dials['density']}/10 — {dials['density_label']}".ljust(BOX_WIDTH) + "")
# Pattern section
lines.append(section_header("PATTERN", BOX_WIDTH + 1))
lines.append(f"│ Name: {pattern.get('name', '')}".ljust(BOX_WIDTH) + "")
@@ -402,6 +486,17 @@ def format_ascii_box(design_system: dict) -> str:
for line in wrap_text(effects, "", BOX_WIDTH):
lines.append(line.ljust(BOX_WIDTH) + "")
# Motion section (GSAP skeleton, only if --motion dial was set)
if motion_snippet:
lines.append(section_header("MOTION", BOX_WIDTH + 1))
lines.append(f"{motion_snippet.get('Category', '')} ({motion_snippet.get('Intensity Tier', '')})".ljust(BOX_WIDTH) + "")
lines.append(f"│ Trigger: {motion_snippet.get('Trigger', '')} | Duration: {motion_snippet.get('Duration', '')} | Easing: {motion_snippet.get('Easing', '')}".ljust(BOX_WIDTH) + "")
for line in wrap_text(f"GSAP: {motion_snippet.get('GSAP Snippet', '')}", "", BOX_WIDTH):
lines.append(line.ljust(BOX_WIDTH) + "")
if motion_snippet.get("Framework Notes"):
for line in wrap_text(f"Framework: {motion_snippet.get('Framework Notes', '')}", "", BOX_WIDTH):
lines.append(line.ljust(BOX_WIDTH) + "")
# Anti-patterns section
if anti_patterns:
lines.append(section_header("AVOID", BOX_WIDTH + 1))
@@ -436,11 +531,24 @@ def format_markdown(design_system: dict) -> str:
typography = design_system.get("typography", {})
effects = design_system.get("key_effects", "")
anti_patterns = design_system.get("anti_patterns", "")
dials = design_system.get("dials", {})
motion_snippet = design_system.get("motion_snippet", {})
lines = []
lines.append(f"## Design System: {project}")
lines.append("")
# Design Dials section (only if at least one dial was set)
if any(dials.get(k) is not None for k in ("variance", "motion", "density")):
lines.append("### Design Dials")
if dials.get("variance") is not None:
lines.append(f"- **Variance:** {dials['variance']}/10 — {dials['variance_label']}")
if dials.get("motion") is not None:
lines.append(f"- **Motion:** {dials['motion']}/10 — {dials['motion_label']}")
if dials.get("density") is not None:
lines.append(f"- **Density:** {dials['density']}/10 — {dials['density_label']}")
lines.append("")
# Pattern section
lines.append("### Pattern")
lines.append(f"- **Name:** {pattern.get('name', '')}")
@@ -515,6 +623,23 @@ def format_markdown(design_system: dict) -> str:
lines.append(f"{effects}")
lines.append("")
# Motion section (GSAP skeleton, only if --motion dial was set)
if motion_snippet:
lines.append("### Motion")
lines.append(f"**{motion_snippet.get('Category', '')}** ({motion_snippet.get('Intensity Tier', '')}) — Trigger: {motion_snippet.get('Trigger', '')} | Duration: {motion_snippet.get('Duration', '')} | Easing: `{motion_snippet.get('Easing', '')}`")
lines.append("```js")
lines.append(motion_snippet.get("GSAP Snippet", ""))
lines.append("```")
if motion_snippet.get("Framework Notes"):
lines.append(f"*Framework notes: {motion_snippet.get('Framework Notes', '')}*")
motion_do = motion_snippet.get("Do", "")
motion_dont = motion_snippet.get("Don't", "")
if motion_do:
lines.append(f"- ✅ {motion_do}")
if motion_dont:
lines.append(f"- ❌ {motion_dont}")
lines.append("")
# Anti-patterns section
if anti_patterns:
lines.append("### Avoid (Anti-patterns)")
@@ -537,8 +662,9 @@ def format_markdown(design_system: dict) -> str:
# ============ MAIN ENTRY POINT ============
def generate_design_system(query: str, project_name: str = None, output_format: str = "ascii",
persist: bool = False, page: str = None, output_dir: str = None) -> str:
def generate_design_system(query: str, project_name: str = None, output_format: str = "ascii",
persist: bool = False, page: str = None, output_dir: str = None,
variance: int = None, motion: int = None, density: int = None) -> str:
"""
Main entry point for design system generation.
@@ -549,13 +675,16 @@ def generate_design_system(query: str, project_name: str = None, output_format:
persist: If True, save design system to design-system/ folder
page: Optional page name for page-specific override file
output_dir: Optional output directory (defaults to current working directory)
variance: Optional 1-10 DESIGN_VARIANCE dial (1=centered/minimal, 10=bold/asymmetric)
motion: Optional 1-10 MOTION_INTENSITY dial, pulls a matching GSAP snippet from motion.csv
density: Optional 1-10 VISUAL_DENSITY dial, overrides the spacing scale (1=spacious, 10=dense)
Returns:
Formatted design system string
"""
generator = DesignSystemGenerator()
design_system = generator.generate(query, project_name)
design_system = generator.generate(query, project_name, variance=variance, motion=motion, density=density)
# Persist to files if requested
if persist:
persist_design_system(design_system, page, output_dir, query)
@@ -627,11 +756,14 @@ def format_master_md(design_system: dict) -> str:
typography = design_system.get("typography", {})
effects = design_system.get("key_effects", "")
anti_patterns = design_system.get("anti_patterns", "")
dials = design_system.get("dials", {})
motion_snippet = design_system.get("motion_snippet", {})
spacing_scale = design_system.get("spacing_scale")
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
lines = []
# Logic header
lines.append("# Design System Master File")
lines.append("")
@@ -644,6 +776,15 @@ def format_master_md(design_system: dict) -> str:
lines.append(f"**Project:** {project}")
lines.append(f"**Generated:** {timestamp}")
lines.append(f"**Category:** {design_system.get('category', 'General')}")
if any(dials.get(k) is not None for k in ("variance", "motion", "density")):
dial_parts = []
if dials.get("variance") is not None:
dial_parts.append(f"Variance {dials['variance']}/10 ({dials['variance_label']})")
if dials.get("motion") is not None:
dial_parts.append(f"Motion {dials['motion']}/10 ({dials['motion_label']})")
if dials.get("density") is not None:
dial_parts.append(f"Density {dials['density']}/10 ({dials['density_label']})")
lines.append(f"**Design Dials:** {' | '.join(dial_parts)}")
lines.append("")
lines.append("---")
lines.append("")
@@ -695,18 +836,24 @@ def format_master_md(design_system: dict) -> str:
lines.append("```")
lines.append("")
# Spacing Variables
# Spacing Variables (overridden by the VISUAL_DENSITY dial when set)
default_spacing = DIAL_TIERS["density"][1][2]["spacing"] # mid-tier = the historical defaults
scale = spacing_scale or default_spacing
spacing_usage = {
"xs": "Tight gaps", "sm": "Icon gaps, inline spacing", "md": "Standard padding",
"lg": "Section padding", "xl": "Large gaps", "2xl": "Section margins", "3xl": "Hero padding",
}
lines.append("### Spacing Variables")
lines.append("")
if spacing_scale:
lines.append(f"*Density: {dials.get('density')}/10 — {dials.get('density_label')}*")
lines.append("")
lines.append("| Token | Value | Usage |")
lines.append("|-------|-------|-------|")
lines.append("| `--space-xs` | `4px` / `0.25rem` | Tight gaps |")
lines.append("| `--space-sm` | `8px` / `0.5rem` | Icon gaps, inline spacing |")
lines.append("| `--space-md` | `16px` / `1rem` | Standard padding |")
lines.append("| `--space-lg` | `24px` / `1.5rem` | Section padding |")
lines.append("| `--space-xl` | `32px` / `2rem` | Large gaps |")
lines.append("| `--space-2xl` | `48px` / `3rem` | Section margins |")
lines.append("| `--space-3xl` | `64px` / `4rem` | Hero padding |")
for token in ("xs", "sm", "md", "lg", "xl", "2xl", "3xl"):
px_value = scale[token]
rem_value = f"{int(px_value.rstrip('px')) / 16:g}rem"
lines.append(f"| `--space-{token}` | `{px_value}` / `{rem_value}` | {spacing_usage[token]} |")
lines.append("")
# Shadow Depths
@@ -848,7 +995,32 @@ def format_master_md(design_system: dict) -> str:
lines.append(f"- **CTA Placement:** {pattern.get('cta_placement', '')}")
lines.append(f"- **Section Order:** {pattern.get('sections', '')}")
lines.append("")
# Motion section (GSAP skeleton, only if --motion dial was set)
if motion_snippet:
lines.append("---")
lines.append("")
lines.append("## Motion")
lines.append("")
lines.append(f"**{motion_snippet.get('Category', '')}** ({motion_snippet.get('Intensity Tier', '')}) — Trigger: {motion_snippet.get('Trigger', '')} | Duration: {motion_snippet.get('Duration', '')} | Easing: `{motion_snippet.get('Easing', '')}`")
lines.append("")
lines.append("```js")
lines.append(motion_snippet.get("GSAP Snippet", ""))
lines.append("```")
lines.append("")
if motion_snippet.get("Framework Notes"):
lines.append(f"**Framework notes:** {motion_snippet.get('Framework Notes', '')}")
lines.append("")
motion_do = motion_snippet.get("Do", "")
motion_dont = motion_snippet.get("Don't", "")
if motion_do:
lines.append(f"- ✅ {motion_do}")
if motion_dont:
lines.append(f"- ❌ {motion_dont}")
if motion_snippet.get("Performance Notes"):
lines.append(f"- ⚡ {motion_snippet.get('Performance Notes', '')}")
lines.append("")
# Anti-Patterns section
lines.append("---")
lines.append("")