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:
Digital Production Factory
2025-12-09 18:45:48 -03:00
commit 276ed71f31
884 changed files with 373737 additions and 0 deletions

View File

@@ -0,0 +1,374 @@
"""
Storybook Theme Generator
Generates Storybook theme configurations from design tokens.
"""
import json
from pathlib import Path
from typing import List, Dict, Any, Optional
from dataclasses import dataclass, field
@dataclass
class StorybookTheme:
"""Storybook theme configuration."""
name: str = "dss-theme"
base: str = "light" # 'light' or 'dark'
# Brand
brand_title: str = "Design System"
brand_url: str = ""
brand_image: str = ""
brand_target: str = "_self"
# Colors
color_primary: str = "#3B82F6"
color_secondary: str = "#10B981"
# UI Colors
app_bg: str = "#FFFFFF"
app_content_bg: str = "#FFFFFF"
app_border_color: str = "#E5E7EB"
# Text colors
text_color: str = "#1F2937"
text_inverse_color: str = "#FFFFFF"
text_muted_color: str = "#6B7280"
# Toolbar
bar_text_color: str = "#6B7280"
bar_selected_color: str = "#3B82F6"
bar_bg: str = "#FFFFFF"
# Form colors
input_bg: str = "#FFFFFF"
input_border: str = "#D1D5DB"
input_text_color: str = "#1F2937"
input_border_radius: int = 4
# Typography
font_base: str = '"Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'
font_code: str = '"Fira Code", "Monaco", monospace'
def to_dict(self) -> Dict[str, Any]:
return {
"base": self.base,
"brandTitle": self.brand_title,
"brandUrl": self.brand_url,
"brandImage": self.brand_image,
"brandTarget": self.brand_target,
"colorPrimary": self.color_primary,
"colorSecondary": self.color_secondary,
"appBg": self.app_bg,
"appContentBg": self.app_content_bg,
"appBorderColor": self.app_border_color,
"textColor": self.text_color,
"textInverseColor": self.text_inverse_color,
"textMutedColor": self.text_muted_color,
"barTextColor": self.bar_text_color,
"barSelectedColor": self.bar_selected_color,
"barBg": self.bar_bg,
"inputBg": self.input_bg,
"inputBorder": self.input_border,
"inputTextColor": self.input_text_color,
"inputBorderRadius": self.input_border_radius,
"fontBase": self.font_base,
"fontCode": self.font_code,
}
class ThemeGenerator:
"""
Generates Storybook theme configurations from design tokens.
"""
# Token name mappings to Storybook theme properties
TOKEN_MAPPINGS = {
# Primary/Secondary
"color.primary.500": "color_primary",
"color.primary.600": "color_primary",
"color.secondary.500": "color_secondary",
"color.accent.500": "color_secondary",
# Backgrounds
"color.neutral.50": "app_bg",
"color.background": "app_bg",
"color.surface": "app_content_bg",
# Borders
"color.neutral.200": "app_border_color",
"color.border": "app_border_color",
# Text
"color.neutral.900": "text_color",
"color.neutral.800": "text_color",
"color.foreground": "text_color",
"color.neutral.500": "text_muted_color",
"color.muted": "text_muted_color",
# Input
"color.neutral.300": "input_border",
"radius.md": "input_border_radius",
}
def __init__(self):
pass
def generate_from_tokens(
self,
tokens: List[Dict[str, Any]],
brand_title: str = "Design System",
base: str = "light",
) -> StorybookTheme:
"""
Generate Storybook theme from design tokens.
Args:
tokens: List of token dicts with 'name' and 'value'
brand_title: Brand title for Storybook
base: Base theme ('light' or 'dark')
Returns:
StorybookTheme configured from tokens
"""
theme = StorybookTheme(
name="dss-theme",
base=base,
brand_title=brand_title,
)
# Map tokens to theme properties
for token in tokens:
name = token.get("name", "")
value = token.get("value", "")
# Check direct mappings
if name in self.TOKEN_MAPPINGS:
prop = self.TOKEN_MAPPINGS[name]
setattr(theme, prop, value)
continue
# Check partial matches
name_lower = name.lower()
if "primary" in name_lower and "500" in name_lower:
theme.color_primary = value
elif "secondary" in name_lower and "500" in name_lower:
theme.color_secondary = value
elif "background" in name_lower and self._is_light_color(value):
theme.app_bg = value
elif "foreground" in name_lower or ("text" in name_lower and "color" in name_lower):
theme.text_color = value
# Adjust for dark mode
if base == "dark":
theme = self._adjust_for_dark_mode(theme)
return theme
def _is_light_color(self, value: str) -> bool:
"""Check if a color value is light (for background suitability)."""
if not value.startswith("#"):
return True # Assume light if not hex
# Parse hex color
hex_color = value.lstrip("#")
if len(hex_color) == 3:
hex_color = "".join(c * 2 for c in hex_color)
try:
r = int(hex_color[0:2], 16)
g = int(hex_color[2:4], 16)
b = int(hex_color[4:6], 16)
# Calculate luminance
luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255
return luminance > 0.5
except (ValueError, IndexError):
return True
def _adjust_for_dark_mode(self, theme: StorybookTheme) -> StorybookTheme:
"""Adjust theme for dark mode if colors aren't already dark."""
# Swap light/dark if needed
if self._is_light_color(theme.app_bg):
theme.app_bg = "#1F2937"
theme.app_content_bg = "#111827"
theme.app_border_color = "#374151"
theme.text_color = "#F9FAFB"
theme.text_muted_color = "#9CA3AF"
theme.bar_bg = "#1F2937"
theme.bar_text_color = "#9CA3AF"
theme.input_bg = "#374151"
theme.input_border = "#4B5563"
theme.input_text_color = "#F9FAFB"
return theme
def generate_theme_file(
self,
theme: StorybookTheme,
format: str = "ts",
) -> str:
"""
Generate Storybook theme file content.
Args:
theme: StorybookTheme to export
format: Output format ('ts', 'js', 'json')
Returns:
Theme file content as string
"""
if format == "json":
return json.dumps(theme.to_dict(), indent=2)
theme_dict = theme.to_dict()
if format == "ts":
lines = [
"import { create } from '@storybook/theming/create';",
"",
"export const dssTheme = create({",
]
else: # js
lines = [
"const { create } = require('@storybook/theming/create');",
"",
"module.exports = create({",
]
for key, value in theme_dict.items():
if isinstance(value, str):
lines.append(f" {key}: '{value}',")
else:
lines.append(f" {key}: {value},")
lines.extend([
"});",
"",
])
return "\n".join(lines)
def generate_manager_file(self, theme_import: str = "./dss-theme") -> str:
"""
Generate Storybook manager.ts file.
Args:
theme_import: Import path for theme
Returns:
Manager file content
"""
return f"""import {{ addons }} from '@storybook/manager-api';
import {{ dssTheme }} from '{theme_import}';
addons.setConfig({{
theme: dssTheme,
}});
"""
def generate_preview_file(
self,
tokens: List[Dict[str, Any]],
include_css_vars: bool = True,
) -> str:
"""
Generate Storybook preview.ts file with token CSS variables.
Args:
tokens: List of token dicts
include_css_vars: Include CSS variable injection
Returns:
Preview file content
"""
lines = [
"import type { Preview } from '@storybook/react';",
"",
]
if include_css_vars:
# Generate CSS variables from tokens
css_vars = []
for token in tokens:
name = token.get("name", "").replace(".", "-")
value = token.get("value", "")
css_vars.append(f" --{name}: {value};")
lines.extend([
"// Inject design tokens as CSS variables",
"const tokenStyles = `",
":root {",
])
lines.extend(css_vars)
lines.extend([
"}",
"`;",
"",
"// Add styles to document",
"const styleSheet = document.createElement('style');",
"styleSheet.textContent = tokenStyles;",
"document.head.appendChild(styleSheet);",
"",
])
lines.extend([
"const preview: Preview = {",
" parameters: {",
" controls: {",
" matchers: {",
" color: /(background|color)$/i,",
" date: /Date$/i,",
" },",
" },",
" backgrounds: {",
" default: 'light',",
" values: [",
" { name: 'light', value: '#FFFFFF' },",
" { name: 'dark', value: '#1F2937' },",
" ],",
" },",
" },",
"};",
"",
"export default preview;",
])
return "\n".join(lines)
def generate_full_config(
self,
tokens: List[Dict[str, Any]],
brand_title: str = "Design System",
output_dir: Optional[str] = None,
) -> Dict[str, str]:
"""
Generate complete Storybook configuration files.
Args:
tokens: List of token dicts
brand_title: Brand title
output_dir: Optional directory to write files
Returns:
Dict mapping filenames to content
"""
# Generate theme
theme = self.generate_from_tokens(tokens, brand_title)
files = {
"dss-theme.ts": self.generate_theme_file(theme, "ts"),
"manager.ts": self.generate_manager_file(),
"preview.ts": self.generate_preview_file(tokens),
}
# Write files if output_dir provided
if output_dir:
out_path = Path(output_dir)
out_path.mkdir(parents=True, exist_ok=True)
for filename, content in files.items():
(out_path / filename).write_text(content)
return files