feat: Add DSS infrastructure, remove legacy admin-ui code
Some checks failed
DSS Project Analysis / dss-context-update (push) Has been cancelled

- Remove legacy admin-ui/js/ vanilla JS components
- Add .dss/ directory with core tokens, skins, themes
- Add Storybook configuration and generated stories
- Add DSS management scripts (dss-services, dss-init, dss-setup, dss-reset)
- Add MCP command definitions for DSS plugin
- Add Figma sync architecture and scripts
- Update pre-commit hooks with documentation validation
- Fix JSON trailing commas in skin files

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
DSS
2025-12-10 22:15:11 -03:00
parent 71c6dc805a
commit 08ce228df1
205 changed files with 65666 additions and 47577 deletions

View File

@@ -66,13 +66,19 @@ except ImportError:
try:
import dss
from dss import (
# Analyze - Context generation & project graph
ProjectScanner, ReactAnalyzer, StyleAnalyzer, DependencyGraph, QuickWinFinder,
# Ingest - Token sources
CSSTokenSource, SCSSTokenSource, TailwindTokenSource, JSONTokenSource,
TokenMerger, MergeStrategy, TokenCollection,
StyleDictionaryWrapper, ShadcnWrapper, FigmaWrapper,
# Models
Theme, Project, ProjectMetadata,
# Storybook
StorybookScanner, StoryGenerator, ThemeGenerator,
DSSSettings, DSSManager, settings, manager
# Settings
DSSSettings, DSSManager, settings, manager,
# Figma
FigmaToolSuite,
)
DSS_AVAILABLE = True
except ImportError as e:
@@ -962,7 +968,10 @@ async def list_tools() -> List[Tool]:
async def call_tool(name: str, arguments: Dict[str, Any]) -> List[TextContent]:
"""Handle tool calls"""
if not DSS_AVAILABLE and name.startswith("dss_"):
# Tools that work without DSS module imports (use scripts directly)
DSS_INDEPENDENT_TOOLS = {"dss_sync_figma", "dss_get_status", "dss_list_themes"}
if not DSS_AVAILABLE and name.startswith("dss_") and name not in DSS_INDEPENDENT_TOOLS:
return [TextContent(
type="text",
text=json.dumps({
@@ -1430,19 +1439,90 @@ async def setup_storybook(path: str, action: str) -> Dict[str, Any]:
async def sync_figma(file_key: str) -> Dict[str, Any]:
"""Sync tokens from Figma"""
"""Sync tokens from Figma using intelligent sync v2.0
Features:
- Rate limiting with exponential backoff
- Caching with lastModified checks
- Figma Variables extraction
- W3C token format output
- Component variant classification
"""
if not file_key:
return {"success": False, "error": "file_key is required"}
figma_token = os.environ.get("FIGMA_TOKEN") or settings.FIGMA_TOKEN
# Get token from env or config
figma_token = os.environ.get("FIGMA_TOKEN")
if not figma_token:
return {"success": False, "error": "FIGMA_TOKEN not configured."}
config_path = Path(__file__).parent.parent.parent / ".dss/config/figma.json"
if config_path.exists():
try:
with open(config_path) as f:
config = json.load(f)
figma_token = config.get("token")
except Exception:
pass
if not figma_token:
return {"success": False, "error": "FIGMA_TOKEN not configured. Set env var or add to .dss/config/figma.json"}
try:
loop = asyncio.get_event_loop()
figma = FigmaWrapper(token=figma_token)
result = await loop.run_in_executor(None, lambda: figma.extract_tokens(file_key))
return {"success": True, "file_key": file_key, "tokens": safe_serialize(result)}
# Import intelligent sync from scripts
scripts_dir = Path(__file__).parent.parent.parent / "scripts"
sys.path.insert(0, str(scripts_dir))
from importlib import import_module
import importlib.util
spec = importlib.util.spec_from_file_location("figma_sync", scripts_dir / "figma-sync.py")
figma_sync_module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(figma_sync_module)
# Run intelligent sync
success = await figma_sync_module.intelligent_sync(
file_key=file_key,
token=figma_token,
force=True,
verbose=False
)
if success:
# Load results
tokens_path = Path(__file__).parent.parent.parent / ".dss/data/_system/tokens/figma-tokens.json"
components_path = Path(__file__).parent.parent.parent / ".dss/components/figma-registry.json"
tokens = {}
components = {}
if tokens_path.exists():
with open(tokens_path) as f:
tokens = json.load(f)
if components_path.exists():
with open(components_path) as f:
components = json.load(f)
token_count = sum(
len(v) for k, v in tokens.items()
if not k.startswith("$") and not k.startswith("_") and isinstance(v, dict)
)
return {
"success": True,
"file_key": file_key,
"tokens_extracted": token_count,
"components_extracted": components.get("component_count", 0),
"output_files": {
"tokens": str(tokens_path),
"components": str(components_path)
}
}
else:
return {"success": False, "error": "Sync failed - check logs"}
except Exception as e:
return {"success": False, "error": str(e)}
import traceback
return {"success": False, "error": str(e), "traceback": traceback.format_exc()}
async def find_quick_wins(path: str) -> Dict[str, Any]: