Initial commit: Clean DSS implementation
Migrated from design-system-swarm with fresh git history.
Old project history preserved in /home/overbits/apps/design-system-swarm
Core components:
- MCP Server (Python FastAPI with mcp 1.23.1)
- Claude Plugin (agents, commands, skills, strategies, hooks, core)
- DSS Backend (dss-mvp1 - token translation, Figma sync)
- Admin UI (Node.js/React)
- Server (Node.js/Express)
- Storybook integration (dss-mvp1/.storybook)
Self-contained configuration:
- All paths relative or use DSS_BASE_PATH=/home/overbits/dss
- PYTHONPATH configured for dss-mvp1 and dss-claude-plugin
- .env file with all configuration
- Claude plugin uses ${CLAUDE_PLUGIN_ROOT} for portability
Migration completed: $(date)
🤖 Clean migration with full functionality preserved
This commit is contained in:
653
tools/api/design_system_registry.py
Normal file
653
tools/api/design_system_registry.py
Normal file
@@ -0,0 +1,653 @@
|
||||
"""
|
||||
Design System Registry - Knowledge base of popular design systems.
|
||||
|
||||
This module provides:
|
||||
- Built-in knowledge of 20+ popular design systems
|
||||
- Fuzzy matching for user queries
|
||||
- npm package information
|
||||
- Alternative ingestion methods (Figma, CSS, docs)
|
||||
"""
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
from typing import List, Optional, Dict, Any
|
||||
from enum import Enum
|
||||
import re
|
||||
|
||||
|
||||
class IngestionMethod(Enum):
|
||||
"""Available methods for ingesting design tokens."""
|
||||
NPM_PACKAGE = "npm_package"
|
||||
TAILWIND_CONFIG = "tailwind_config"
|
||||
CSS_VARIABLES = "css_variables"
|
||||
FIGMA = "figma"
|
||||
JSON_TOKENS = "json_tokens"
|
||||
SCSS_VARIABLES = "scss_variables"
|
||||
STYLE_DICTIONARY = "style_dictionary"
|
||||
|
||||
|
||||
@dataclass
|
||||
class DesignSystemInfo:
|
||||
"""Information about a known design system."""
|
||||
id: str
|
||||
name: str
|
||||
description: str
|
||||
aliases: List[str] = field(default_factory=list)
|
||||
npm_packages: List[str] = field(default_factory=list)
|
||||
primary_ingestion: IngestionMethod = IngestionMethod.NPM_PACKAGE
|
||||
figma_community_url: Optional[str] = None
|
||||
docs_url: Optional[str] = None
|
||||
github_url: Optional[str] = None
|
||||
token_paths: List[str] = field(default_factory=list) # Paths within npm package to tokens
|
||||
css_cdn_url: Optional[str] = None
|
||||
category: str = "component-library"
|
||||
framework: Optional[str] = None # react, vue, angular, html, etc.
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
"""Convert to dictionary for API responses."""
|
||||
return {
|
||||
"id": self.id,
|
||||
"name": self.name,
|
||||
"description": self.description,
|
||||
"aliases": self.aliases,
|
||||
"npm_packages": self.npm_packages,
|
||||
"primary_ingestion": self.primary_ingestion.value,
|
||||
"figma_community_url": self.figma_community_url,
|
||||
"docs_url": self.docs_url,
|
||||
"github_url": self.github_url,
|
||||
"token_paths": self.token_paths,
|
||||
"css_cdn_url": self.css_cdn_url,
|
||||
"category": self.category,
|
||||
"framework": self.framework,
|
||||
}
|
||||
|
||||
|
||||
# Built-in registry of popular design systems
|
||||
DESIGN_SYSTEMS: Dict[str, DesignSystemInfo] = {}
|
||||
|
||||
|
||||
def register_system(system: DesignSystemInfo) -> None:
|
||||
"""Register a design system in the registry."""
|
||||
DESIGN_SYSTEMS[system.id] = system
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Popular Design Systems Registry
|
||||
# =============================================================================
|
||||
|
||||
# HeroUI (NextUI successor)
|
||||
register_system(DesignSystemInfo(
|
||||
id="heroui",
|
||||
name="HeroUI",
|
||||
description="Beautiful, fast and modern React UI library (formerly NextUI)",
|
||||
aliases=["hero-ui", "hero ui", "nextui", "next-ui", "next ui"],
|
||||
npm_packages=["@heroui/react", "@heroui/theme"],
|
||||
primary_ingestion=IngestionMethod.TAILWIND_CONFIG,
|
||||
figma_community_url="https://www.figma.com/community/file/1267584376522720519",
|
||||
docs_url="https://www.heroui.com/docs",
|
||||
github_url="https://github.com/heroui-inc/heroui",
|
||||
token_paths=["@heroui/theme/dist/colors.js", "@heroui/theme/dist/default-layout.js"],
|
||||
category="component-library",
|
||||
framework="react",
|
||||
))
|
||||
|
||||
# Shadcn/ui
|
||||
register_system(DesignSystemInfo(
|
||||
id="shadcn",
|
||||
name="shadcn/ui",
|
||||
description="Beautifully designed components built with Radix UI and Tailwind CSS",
|
||||
aliases=["shadcn", "shadcn-ui", "shadcnui", "shad", "shad-cn"],
|
||||
npm_packages=["shadcn-ui"], # CLI tool, components are copy-pasted
|
||||
primary_ingestion=IngestionMethod.CSS_VARIABLES,
|
||||
figma_community_url="https://www.figma.com/community/file/1203061493325953101",
|
||||
docs_url="https://ui.shadcn.com/docs",
|
||||
github_url="https://github.com/shadcn-ui/ui",
|
||||
token_paths=[], # Tokens are in CSS variables
|
||||
css_cdn_url="https://ui.shadcn.com/registry/styles/default/index.json",
|
||||
category="component-library",
|
||||
framework="react",
|
||||
))
|
||||
|
||||
# Material UI (MUI)
|
||||
register_system(DesignSystemInfo(
|
||||
id="mui",
|
||||
name="Material UI",
|
||||
description="Google's Material Design implemented for React",
|
||||
aliases=["material-ui", "material ui", "materialui", "mui", "@mui"],
|
||||
npm_packages=["@mui/material", "@mui/system", "@emotion/react", "@emotion/styled"],
|
||||
primary_ingestion=IngestionMethod.NPM_PACKAGE,
|
||||
figma_community_url="https://www.figma.com/community/file/912837788133317724",
|
||||
docs_url="https://mui.com/material-ui/getting-started/",
|
||||
github_url="https://github.com/mui/material-ui",
|
||||
token_paths=["@mui/material/styles"],
|
||||
category="component-library",
|
||||
framework="react",
|
||||
))
|
||||
|
||||
# Chakra UI
|
||||
register_system(DesignSystemInfo(
|
||||
id="chakra",
|
||||
name="Chakra UI",
|
||||
description="Simple, modular and accessible component library for React",
|
||||
aliases=["chakra-ui", "chakra ui", "chakraui"],
|
||||
npm_packages=["@chakra-ui/react", "@chakra-ui/theme"],
|
||||
primary_ingestion=IngestionMethod.NPM_PACKAGE,
|
||||
figma_community_url="https://www.figma.com/community/file/971408767069651759",
|
||||
docs_url="https://chakra-ui.com/docs/getting-started",
|
||||
github_url="https://github.com/chakra-ui/chakra-ui",
|
||||
token_paths=["@chakra-ui/theme/dist/foundations"],
|
||||
category="component-library",
|
||||
framework="react",
|
||||
))
|
||||
|
||||
# Ant Design
|
||||
register_system(DesignSystemInfo(
|
||||
id="antd",
|
||||
name="Ant Design",
|
||||
description="Enterprise-class UI design language and React components",
|
||||
aliases=["ant-design", "ant design", "antdesign", "antd"],
|
||||
npm_packages=["antd", "@ant-design/icons"],
|
||||
primary_ingestion=IngestionMethod.NPM_PACKAGE,
|
||||
figma_community_url="https://www.figma.com/community/file/831698976089873405",
|
||||
docs_url="https://ant.design/docs/react/introduce",
|
||||
github_url="https://github.com/ant-design/ant-design",
|
||||
token_paths=["antd/dist/antd.variable.css"],
|
||||
css_cdn_url="https://unpkg.com/antd/dist/antd.variable.css",
|
||||
category="component-library",
|
||||
framework="react",
|
||||
))
|
||||
|
||||
# Tailwind CSS
|
||||
register_system(DesignSystemInfo(
|
||||
id="tailwind",
|
||||
name="Tailwind CSS",
|
||||
description="Utility-first CSS framework for rapid UI development",
|
||||
aliases=["tailwindcss", "tailwind css", "tw"],
|
||||
npm_packages=["tailwindcss"],
|
||||
primary_ingestion=IngestionMethod.TAILWIND_CONFIG,
|
||||
figma_community_url="https://www.figma.com/community/file/768809027799962739",
|
||||
docs_url="https://tailwindcss.com/docs",
|
||||
github_url="https://github.com/tailwindlabs/tailwindcss",
|
||||
token_paths=["tailwindcss/defaultTheme"],
|
||||
category="css-framework",
|
||||
framework="html",
|
||||
))
|
||||
|
||||
# Bootstrap
|
||||
register_system(DesignSystemInfo(
|
||||
id="bootstrap",
|
||||
name="Bootstrap",
|
||||
description="Popular HTML, CSS, and JS library for responsive design",
|
||||
aliases=["bootstrap5", "bootstrap 5", "bs", "bs5", "twbs"],
|
||||
npm_packages=["bootstrap"],
|
||||
primary_ingestion=IngestionMethod.SCSS_VARIABLES,
|
||||
figma_community_url="https://www.figma.com/community/file/876022745968684318",
|
||||
docs_url="https://getbootstrap.com/docs/5.3/getting-started/introduction/",
|
||||
github_url="https://github.com/twbs/bootstrap",
|
||||
token_paths=["bootstrap/scss/_variables.scss"],
|
||||
css_cdn_url="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css",
|
||||
category="css-framework",
|
||||
framework="html",
|
||||
))
|
||||
|
||||
# Radix UI
|
||||
register_system(DesignSystemInfo(
|
||||
id="radix",
|
||||
name="Radix UI",
|
||||
description="Unstyled, accessible components for building design systems",
|
||||
aliases=["radix-ui", "radix ui", "radixui", "@radix-ui"],
|
||||
npm_packages=["@radix-ui/themes", "@radix-ui/colors"],
|
||||
primary_ingestion=IngestionMethod.CSS_VARIABLES,
|
||||
figma_community_url="https://www.figma.com/community/file/1295954844895805217",
|
||||
docs_url="https://www.radix-ui.com/themes/docs/overview/getting-started",
|
||||
github_url="https://github.com/radix-ui/themes",
|
||||
token_paths=["@radix-ui/colors"],
|
||||
category="component-library",
|
||||
framework="react",
|
||||
))
|
||||
|
||||
# Mantine
|
||||
register_system(DesignSystemInfo(
|
||||
id="mantine",
|
||||
name="Mantine",
|
||||
description="React components library with native dark theme support",
|
||||
aliases=["mantine-ui", "mantineui"],
|
||||
npm_packages=["@mantine/core", "@mantine/hooks"],
|
||||
primary_ingestion=IngestionMethod.NPM_PACKAGE,
|
||||
figma_community_url="https://www.figma.com/community/file/1293978471602433537",
|
||||
docs_url="https://mantine.dev/getting-started/",
|
||||
github_url="https://github.com/mantinedev/mantine",
|
||||
token_paths=["@mantine/core/styles.css"],
|
||||
category="component-library",
|
||||
framework="react",
|
||||
))
|
||||
|
||||
# Fluent UI (Microsoft)
|
||||
register_system(DesignSystemInfo(
|
||||
id="fluent",
|
||||
name="Fluent UI",
|
||||
description="Microsoft's design system for building web experiences",
|
||||
aliases=["fluent-ui", "fluentui", "fluent ui", "@fluentui", "fabric"],
|
||||
npm_packages=["@fluentui/react-components", "@fluentui/tokens"],
|
||||
primary_ingestion=IngestionMethod.NPM_PACKAGE,
|
||||
figma_community_url="https://www.figma.com/community/file/836828295772957889",
|
||||
docs_url="https://react.fluentui.dev/",
|
||||
github_url="https://github.com/microsoft/fluentui",
|
||||
token_paths=["@fluentui/tokens"],
|
||||
category="component-library",
|
||||
framework="react",
|
||||
))
|
||||
|
||||
# IBM Carbon
|
||||
register_system(DesignSystemInfo(
|
||||
id="carbon",
|
||||
name="Carbon Design System",
|
||||
description="IBM's open source design system for products and experiences",
|
||||
aliases=["carbon-design", "ibm-carbon", "ibm carbon", "@carbon"],
|
||||
npm_packages=["@carbon/react", "@carbon/styles", "@carbon/colors"],
|
||||
primary_ingestion=IngestionMethod.SCSS_VARIABLES,
|
||||
figma_community_url="https://www.figma.com/community/file/1157761560874207208",
|
||||
docs_url="https://carbondesignsystem.com/",
|
||||
github_url="https://github.com/carbon-design-system/carbon",
|
||||
token_paths=["@carbon/colors", "@carbon/type", "@carbon/layout"],
|
||||
category="design-system",
|
||||
framework="react",
|
||||
))
|
||||
|
||||
# Primer (GitHub)
|
||||
register_system(DesignSystemInfo(
|
||||
id="primer",
|
||||
name="Primer",
|
||||
description="GitHub's design system with CSS and React components",
|
||||
aliases=["primer-css", "github-primer", "github primer", "@primer"],
|
||||
npm_packages=["@primer/react", "@primer/css", "@primer/primitives"],
|
||||
primary_ingestion=IngestionMethod.JSON_TOKENS,
|
||||
figma_community_url="https://www.figma.com/community/file/854767373644076713",
|
||||
docs_url="https://primer.style/",
|
||||
github_url="https://github.com/primer/primitives",
|
||||
token_paths=["@primer/primitives/dist/json"],
|
||||
category="design-system",
|
||||
framework="react",
|
||||
))
|
||||
|
||||
# Spectrum (Adobe)
|
||||
register_system(DesignSystemInfo(
|
||||
id="spectrum",
|
||||
name="Adobe Spectrum",
|
||||
description="Adobe's design system for creating seamless experiences",
|
||||
aliases=["adobe-spectrum", "adobe spectrum", "@spectrum", "@adobe/spectrum"],
|
||||
npm_packages=["@adobe/react-spectrum", "@spectrum-css/tokens"],
|
||||
primary_ingestion=IngestionMethod.JSON_TOKENS,
|
||||
figma_community_url="https://www.figma.com/community/file/1196015001498069893",
|
||||
docs_url="https://spectrum.adobe.com/",
|
||||
github_url="https://github.com/adobe/react-spectrum",
|
||||
token_paths=["@spectrum-css/tokens"],
|
||||
category="design-system",
|
||||
framework="react",
|
||||
))
|
||||
|
||||
# Salesforce Lightning
|
||||
register_system(DesignSystemInfo(
|
||||
id="lightning",
|
||||
name="Salesforce Lightning",
|
||||
description="Salesforce Lightning Design System for enterprise apps",
|
||||
aliases=["slds", "lightning-design", "salesforce-lightning", "salesforce lightning"],
|
||||
npm_packages=["@salesforce-ux/design-system"],
|
||||
primary_ingestion=IngestionMethod.SCSS_VARIABLES,
|
||||
figma_community_url="https://www.figma.com/community/file/877593312714992614",
|
||||
docs_url="https://www.lightningdesignsystem.com/",
|
||||
github_url="https://github.com/salesforce-ux/design-system",
|
||||
token_paths=["@salesforce-ux/design-system/design-tokens"],
|
||||
category="design-system",
|
||||
framework="html",
|
||||
))
|
||||
|
||||
# Atlassian Design System
|
||||
register_system(DesignSystemInfo(
|
||||
id="atlassian",
|
||||
name="Atlassian Design System",
|
||||
description="Atlassian's end-to-end design language for products",
|
||||
aliases=["atlaskit", "atlas-kit", "atlassian-design", "@atlaskit"],
|
||||
npm_packages=["@atlaskit/tokens", "@atlaskit/theme"],
|
||||
primary_ingestion=IngestionMethod.JSON_TOKENS,
|
||||
figma_community_url="https://www.figma.com/community/file/1189965498990866853",
|
||||
docs_url="https://atlassian.design/",
|
||||
github_url="https://bitbucket.org/atlassian/atlassian-frontend-mirror/src/master/",
|
||||
token_paths=["@atlaskit/tokens/dist/esm/artifacts/tokens-raw"],
|
||||
category="design-system",
|
||||
framework="react",
|
||||
))
|
||||
|
||||
# Shopify Polaris
|
||||
register_system(DesignSystemInfo(
|
||||
id="polaris",
|
||||
name="Shopify Polaris",
|
||||
description="Shopify's design system for building admin experiences",
|
||||
aliases=["shopify-polaris", "shopify polaris", "@shopify/polaris"],
|
||||
npm_packages=["@shopify/polaris", "@shopify/polaris-tokens"],
|
||||
primary_ingestion=IngestionMethod.JSON_TOKENS,
|
||||
figma_community_url="https://www.figma.com/community/file/1293611962331823010",
|
||||
docs_url="https://polaris.shopify.com/",
|
||||
github_url="https://github.com/Shopify/polaris",
|
||||
token_paths=["@shopify/polaris-tokens/dist/json"],
|
||||
category="design-system",
|
||||
framework="react",
|
||||
))
|
||||
|
||||
# Vuetify
|
||||
register_system(DesignSystemInfo(
|
||||
id="vuetify",
|
||||
name="Vuetify",
|
||||
description="Material Design component framework for Vue.js",
|
||||
aliases=["vuetify3", "vuetify 3"],
|
||||
npm_packages=["vuetify"],
|
||||
primary_ingestion=IngestionMethod.SCSS_VARIABLES,
|
||||
figma_community_url="https://www.figma.com/community/file/1181257898482695401",
|
||||
docs_url="https://vuetifyjs.com/en/getting-started/installation/",
|
||||
github_url="https://github.com/vuetifyjs/vuetify",
|
||||
token_paths=["vuetify/lib/styles/settings/_variables.scss"],
|
||||
category="component-library",
|
||||
framework="vue",
|
||||
))
|
||||
|
||||
# PrimeVue / PrimeReact
|
||||
register_system(DesignSystemInfo(
|
||||
id="primevue",
|
||||
name="PrimeVue",
|
||||
description="Rich set of open source UI components for Vue",
|
||||
aliases=["prime-vue", "prime vue", "primereact", "prime-react", "primefaces"],
|
||||
npm_packages=["primevue", "primeicons"],
|
||||
primary_ingestion=IngestionMethod.CSS_VARIABLES,
|
||||
figma_community_url="https://www.figma.com/community/file/890589747170608208",
|
||||
docs_url="https://primevue.org/",
|
||||
github_url="https://github.com/primefaces/primevue",
|
||||
token_paths=["primevue/resources/themes"],
|
||||
category="component-library",
|
||||
framework="vue",
|
||||
))
|
||||
|
||||
# DaisyUI
|
||||
register_system(DesignSystemInfo(
|
||||
id="daisyui",
|
||||
name="daisyUI",
|
||||
description="Tailwind CSS component library with semantic class names",
|
||||
aliases=["daisy-ui", "daisy ui", "daisy"],
|
||||
npm_packages=["daisyui"],
|
||||
primary_ingestion=IngestionMethod.TAILWIND_CONFIG,
|
||||
figma_community_url="https://www.figma.com/community/file/1098092815609260082",
|
||||
docs_url="https://daisyui.com/docs/install/",
|
||||
github_url="https://github.com/saadeghi/daisyui",
|
||||
token_paths=["daisyui/src/theming/themes.js"],
|
||||
category="component-library",
|
||||
framework="html",
|
||||
))
|
||||
|
||||
# Headless UI
|
||||
register_system(DesignSystemInfo(
|
||||
id="headlessui",
|
||||
name="Headless UI",
|
||||
description="Unstyled, accessible UI components for React and Vue",
|
||||
aliases=["headless-ui", "headless ui", "@headlessui"],
|
||||
npm_packages=["@headlessui/react", "@headlessui/vue"],
|
||||
primary_ingestion=IngestionMethod.CSS_VARIABLES,
|
||||
docs_url="https://headlessui.com/",
|
||||
github_url="https://github.com/tailwindlabs/headlessui",
|
||||
token_paths=[], # Unstyled, no tokens
|
||||
category="component-library",
|
||||
framework="react",
|
||||
))
|
||||
|
||||
# Open Props
|
||||
register_system(DesignSystemInfo(
|
||||
id="openprops",
|
||||
name="Open Props",
|
||||
description="Supercharged CSS variables for design systems",
|
||||
aliases=["open-props", "open props"],
|
||||
npm_packages=["open-props"],
|
||||
primary_ingestion=IngestionMethod.CSS_VARIABLES,
|
||||
figma_community_url="https://www.figma.com/community/file/1144820109792924498",
|
||||
docs_url="https://open-props.style/",
|
||||
github_url="https://github.com/argyleink/open-props",
|
||||
token_paths=["open-props/open-props.min.css"],
|
||||
css_cdn_url="https://unpkg.com/open-props",
|
||||
category="css-tokens",
|
||||
framework="html",
|
||||
))
|
||||
|
||||
# Pico CSS
|
||||
register_system(DesignSystemInfo(
|
||||
id="picocss",
|
||||
name="Pico CSS",
|
||||
description="Minimal CSS framework for semantic HTML",
|
||||
aliases=["pico-css", "pico css", "pico"],
|
||||
npm_packages=["@picocss/pico"],
|
||||
primary_ingestion=IngestionMethod.CSS_VARIABLES,
|
||||
docs_url="https://picocss.com/docs/",
|
||||
github_url="https://github.com/picocss/pico",
|
||||
token_paths=["@picocss/pico/css/pico.css"],
|
||||
css_cdn_url="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css",
|
||||
category="css-framework",
|
||||
framework="html",
|
||||
))
|
||||
|
||||
# Bulma
|
||||
register_system(DesignSystemInfo(
|
||||
id="bulma",
|
||||
name="Bulma",
|
||||
description="Modern CSS framework based on Flexbox",
|
||||
aliases=["bulma-css", "bulma css"],
|
||||
npm_packages=["bulma"],
|
||||
primary_ingestion=IngestionMethod.SCSS_VARIABLES,
|
||||
figma_community_url="https://www.figma.com/community/file/1145794431179045801",
|
||||
docs_url="https://bulma.io/documentation/",
|
||||
github_url="https://github.com/jgthms/bulma",
|
||||
token_paths=["bulma/sass/utilities/_variables.scss"],
|
||||
css_cdn_url="https://cdn.jsdelivr.net/npm/bulma@1.0.0/css/bulma.min.css",
|
||||
category="css-framework",
|
||||
framework="html",
|
||||
))
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Registry Search and Matching Functions
|
||||
# =============================================================================
|
||||
|
||||
def normalize_query(query: str) -> str:
|
||||
"""Normalize a search query for matching."""
|
||||
# Lowercase and remove special characters
|
||||
normalized = query.lower().strip()
|
||||
# Remove common prefixes
|
||||
normalized = re.sub(r'^(@|use |add |import |ingest |install )', '', normalized)
|
||||
# Remove common suffixes
|
||||
normalized = re.sub(r'( design system| ui| css| react| vue)$', '', normalized)
|
||||
# Remove special characters but keep hyphens
|
||||
normalized = re.sub(r'[^\w\s-]', '', normalized)
|
||||
# Collapse multiple spaces
|
||||
normalized = re.sub(r'\s+', ' ', normalized)
|
||||
return normalized.strip()
|
||||
|
||||
|
||||
def find_design_system(query: str) -> Optional[DesignSystemInfo]:
|
||||
"""
|
||||
Find a design system by name or alias.
|
||||
Returns the best match or None if not found.
|
||||
"""
|
||||
normalized = normalize_query(query)
|
||||
|
||||
# Exact match on ID
|
||||
if normalized in DESIGN_SYSTEMS:
|
||||
return DESIGN_SYSTEMS[normalized]
|
||||
|
||||
# Exact match on aliases
|
||||
for system in DESIGN_SYSTEMS.values():
|
||||
if normalized in [a.lower() for a in system.aliases]:
|
||||
return system
|
||||
if normalized == system.name.lower():
|
||||
return system
|
||||
|
||||
# Partial match on name or aliases
|
||||
for system in DESIGN_SYSTEMS.values():
|
||||
# Check if query is contained in system name
|
||||
if normalized in system.name.lower():
|
||||
return system
|
||||
# Check if query is contained in any alias
|
||||
for alias in system.aliases:
|
||||
if normalized in alias.lower():
|
||||
return system
|
||||
|
||||
# Fuzzy match - check if any word matches
|
||||
query_words = set(normalized.split())
|
||||
best_match = None
|
||||
best_score = 0
|
||||
|
||||
for system in DESIGN_SYSTEMS.values():
|
||||
# Create set of all searchable terms
|
||||
terms = {system.id.lower(), system.name.lower()}
|
||||
terms.update(a.lower() for a in system.aliases)
|
||||
|
||||
# Count matching words
|
||||
for term in terms:
|
||||
term_words = set(term.split())
|
||||
matches = len(query_words & term_words)
|
||||
if matches > best_score:
|
||||
best_score = matches
|
||||
best_match = system
|
||||
|
||||
if best_score > 0:
|
||||
return best_match
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def search_design_systems(query: str, limit: int = 5) -> List[DesignSystemInfo]:
|
||||
"""
|
||||
Search for design systems matching a query.
|
||||
Returns a list of matches sorted by relevance.
|
||||
"""
|
||||
normalized = normalize_query(query)
|
||||
results = []
|
||||
|
||||
for system in DESIGN_SYSTEMS.values():
|
||||
score = 0
|
||||
|
||||
# Exact match on ID or name
|
||||
if normalized == system.id.lower() or normalized == system.name.lower():
|
||||
score = 100
|
||||
# Exact alias match
|
||||
elif normalized in [a.lower() for a in system.aliases]:
|
||||
score = 90
|
||||
# Partial match in name
|
||||
elif normalized in system.name.lower():
|
||||
score = 70
|
||||
# Partial match in aliases
|
||||
elif any(normalized in a.lower() for a in system.aliases):
|
||||
score = 60
|
||||
# Word overlap
|
||||
else:
|
||||
query_words = set(normalized.split())
|
||||
all_terms = {system.id, system.name} | set(system.aliases)
|
||||
all_words = set()
|
||||
for term in all_terms:
|
||||
all_words.update(term.lower().split())
|
||||
|
||||
overlap = len(query_words & all_words)
|
||||
if overlap > 0:
|
||||
score = overlap * 20
|
||||
|
||||
if score > 0:
|
||||
results.append((score, system))
|
||||
|
||||
# Sort by score descending
|
||||
results.sort(key=lambda x: x[0], reverse=True)
|
||||
|
||||
return [system for _, system in results[:limit]]
|
||||
|
||||
|
||||
def get_all_systems() -> List[DesignSystemInfo]:
|
||||
"""Get all registered design systems."""
|
||||
return list(DESIGN_SYSTEMS.values())
|
||||
|
||||
|
||||
def get_systems_by_category(category: str) -> List[DesignSystemInfo]:
|
||||
"""Get design systems filtered by category."""
|
||||
return [s for s in DESIGN_SYSTEMS.values() if s.category == category]
|
||||
|
||||
|
||||
def get_systems_by_framework(framework: str) -> List[DesignSystemInfo]:
|
||||
"""Get design systems filtered by framework."""
|
||||
return [s for s in DESIGN_SYSTEMS.values() if s.framework == framework]
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Alternative Ingestion Suggestions
|
||||
# =============================================================================
|
||||
|
||||
def get_alternative_ingestion_options(system: Optional[DesignSystemInfo] = None) -> Dict[str, Any]:
|
||||
"""
|
||||
Get alternative ingestion options when primary method is unavailable.
|
||||
"""
|
||||
alternatives = {
|
||||
"figma": {
|
||||
"name": "Figma Import",
|
||||
"description": "Provide a Figma file URL to extract design tokens and components",
|
||||
"prompt": "Please provide the Figma file URL (e.g., https://www.figma.com/file/...)",
|
||||
"requires": "figma_url"
|
||||
},
|
||||
"css_url": {
|
||||
"name": "CSS/SCSS URL",
|
||||
"description": "Provide a URL to a CSS or SCSS file containing design tokens",
|
||||
"prompt": "Please provide the CSS/SCSS file URL",
|
||||
"requires": "css_url"
|
||||
},
|
||||
"image": {
|
||||
"name": "Image Analysis",
|
||||
"description": "Upload an image or screenshot of the design system for AI analysis",
|
||||
"prompt": "Please provide an image URL or upload a screenshot of your design system",
|
||||
"requires": "image_url"
|
||||
},
|
||||
"manual": {
|
||||
"name": "Manual Entry",
|
||||
"description": "Manually enter design tokens (colors, typography, spacing)",
|
||||
"prompt": "Describe your design tokens (e.g., 'primary color: #3b82f6, font: Inter')",
|
||||
"requires": "text_description"
|
||||
},
|
||||
"github": {
|
||||
"name": "GitHub Repository",
|
||||
"description": "Provide a GitHub repository URL containing design tokens",
|
||||
"prompt": "Please provide the GitHub repository URL",
|
||||
"requires": "github_url"
|
||||
}
|
||||
}
|
||||
|
||||
# If we have a known system, customize suggestions
|
||||
if system:
|
||||
result = {"known_system": system.to_dict(), "alternatives": []}
|
||||
|
||||
if system.figma_community_url:
|
||||
result["alternatives"].append({
|
||||
**alternatives["figma"],
|
||||
"suggested_url": system.figma_community_url
|
||||
})
|
||||
|
||||
if system.css_cdn_url:
|
||||
result["alternatives"].append({
|
||||
**alternatives["css_url"],
|
||||
"suggested_url": system.css_cdn_url
|
||||
})
|
||||
|
||||
if system.github_url:
|
||||
result["alternatives"].append({
|
||||
**alternatives["github"],
|
||||
"suggested_url": system.github_url
|
||||
})
|
||||
|
||||
# Always offer manual and image options
|
||||
result["alternatives"].append(alternatives["image"])
|
||||
result["alternatives"].append(alternatives["manual"])
|
||||
|
||||
return result
|
||||
|
||||
# Unknown system - offer all alternatives
|
||||
return {
|
||||
"known_system": None,
|
||||
"alternatives": list(alternatives.values())
|
||||
}
|
||||
Reference in New Issue
Block a user