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,278 @@
/**
* ds-quick-wins-script.js
* Quick Wins analyzer - finds low-effort, high-impact design system improvements
* MVP2: Identifies inconsistencies and suggests standardization opportunities
*/
export default class QuickWinsScript extends HTMLElement {
constructor() {
super();
this.analysisResults = null;
this.isAnalyzing = false;
}
connectedCallback() {
this.render();
this.setupEventListeners();
}
render() {
this.innerHTML = `
<div style="padding: 24px; height: 100%; overflow-y: auto;">
<div style="margin-bottom: 24px;">
<h1 style="margin: 0 0 8px 0; font-size: 24px;">Design System Quick Wins</h1>
<p style="margin: 0; color: var(--vscode-text-dim);">
Identify low-effort, high-impact improvements to your design system
</p>
</div>
<!-- Analysis Controls -->
<div style="background: var(--vscode-sidebar); border: 1px solid var(--vscode-border); border-radius: 4px; padding: 16px; margin-bottom: 24px;">
<div style="margin-bottom: 12px;">
<label style="display: block; font-size: 12px; font-weight: 500; margin-bottom: 8px;">
What to analyze
</label>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 8px;">
<label style="display: flex; align-items: center; gap: 6px; cursor: pointer; font-size: 12px;">
<input type="checkbox" id="check-tokens" checked />
Design Tokens
</label>
<label style="display: flex; align-items: center; gap: 6px; cursor: pointer; font-size: 12px;">
<input type="checkbox" id="check-colors" checked />
Color Usage
</label>
<label style="display: flex; align-items: center; gap: 6px; cursor: pointer; font-size: 12px;">
<input type="checkbox" id="check-spacing" checked />
Spacing Values
</label>
<label style="display: flex; align-items: center; gap: 6px; cursor: pointer; font-size: 12px;">
<input type="checkbox" id="check-typography" checked />
Typography
</label>
</div>
</div>
<button id="analyze-btn" aria-label="Analyze design system for improvement opportunities" style="
width: 100%;
padding: 8px 16px;
background: var(--vscode-button-background);
color: var(--vscode-button-foreground);
border: none;
border-radius: 4px;
cursor: pointer;
font-weight: 500;
font-size: 12px;
">Analyze Design System</button>
</div>
<!-- Loading State -->
<div id="loading-container" style="display: none; text-align: center; padding: 48px; background: var(--vscode-sidebar); border: 1px solid var(--vscode-border); border-radius: 4px;">
<div style="font-size: 24px; margin-bottom: 12px;">⏳</div>
<div style="font-size: 12px; color: var(--vscode-text-dim);">
Analyzing design system...
</div>
</div>
<!-- Results Container -->
<div id="results-container" style="display: none;">
<!-- Results will be inserted here -->
</div>
</div>
`;
}
setupEventListeners() {
const analyzeBtn = this.querySelector('#analyze-btn');
if (analyzeBtn) {
analyzeBtn.addEventListener('click', () => this.analyzeDesignSystem());
}
}
async analyzeDesignSystem() {
this.isAnalyzing = true;
const loadingContainer = this.querySelector('#loading-container');
const resultsContainer = this.querySelector('#results-container');
loadingContainer.style.display = 'block';
resultsContainer.style.display = 'none';
// Simulate analysis
await new Promise(resolve => setTimeout(resolve, 1500));
this.analysisResults = this.generateAnalysisResults();
this.renderResults();
loadingContainer.style.display = 'none';
resultsContainer.style.display = 'block';
this.isAnalyzing = false;
}
generateAnalysisResults() {
return [
{
title: 'Consolidate Color Palette',
impact: 'high',
effort: 'low',
description: 'Found 23 unique colors in codebase, but only 8 are documented tokens. Consolidate to reduce cognitive load.',
recommendation: 'Extract 15 undocumented colors and add to token library',
estimate: '2 hours',
files_affected: 34
},
{
title: 'Standardize Spacing Scale',
impact: 'high',
effort: 'low',
description: 'Spacing values are inconsistent (4px, 6px, 8px, 12px, 16px, 20px, 24px, 32px). Reduce to 6-8 standard values.',
recommendation: 'Use 4px, 8px, 12px, 16px, 24px, 32px as standard spacing scale',
estimate: '3 hours',
files_affected: 67
},
{
title: 'Create Typography System',
impact: 'high',
effort: 'medium',
description: 'Typography scales vary across components. Establish consistent type hierarchy.',
recommendation: 'Define 5 font sizes (12px, 14px, 16px, 18px, 24px) with line-height ratios',
estimate: '4 hours',
files_affected: 45
},
{
title: 'Document Component Variants',
impact: 'medium',
effort: 'low',
description: 'Button component has 7 undocumented variants in use. Update documentation.',
recommendation: 'Add variant definitions and usage guidelines to Storybook',
estimate: '1 hour',
files_affected: 12
},
{
title: 'Establish Naming Convention',
impact: 'medium',
effort: 'low',
description: 'Token names are inconsistent (color-primary vs primaryColor vs primary-color).',
recommendation: 'Adopt kebab-case convention: color-primary, spacing-sm, font-body',
estimate: '2 hours',
files_affected: 89
},
{
title: 'Create Shadow System',
impact: 'medium',
effort: 'medium',
description: 'Shadow values are hardcoded throughout. Create reusable shadow tokens.',
recommendation: 'Define 3-4 elevation levels: shadow-sm, shadow-md, shadow-lg, shadow-xl',
estimate: '2 hours',
files_affected: 23
}
];
}
renderResults() {
const container = this.querySelector('#results-container');
const results = this.analysisResults;
const highImpact = results.filter(r => r.impact === 'high');
const mediumImpact = results.filter(r => r.impact === 'medium');
const totalFiles = results.reduce((sum, r) => sum + r.files_affected, 0);
// Build stats efficiently
const statsHtml = this.buildStatsCards(results.length, highImpact.length, totalFiles);
// Build cards with memoization
const highImpactHtml = highImpact.map(win => this.renderWinCard(win)).join('');
const mediumImpactHtml = mediumImpact.map(win => this.renderWinCard(win)).join('');
let html = `
<div style="margin-bottom: 24px;">
${statsHtml}
</div>
<div style="margin-bottom: 24px;">
<h2 style="margin: 0 0 12px 0; font-size: 14px; color: #FF9800;">High Impact Opportunities</h2>
${highImpactHtml}
</div>
<div>
<h2 style="margin: 0 0 12px 0; font-size: 14px; color: #0066CC;">Medium Impact Opportunities</h2>
${mediumImpactHtml}
</div>
`;
container.innerHTML = html;
}
buildStatsCards(total, highCount, fileCount) {
return `
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; margin-bottom: 24px;">
<div style="background: var(--vscode-sidebar); padding: 12px; border-radius: 4px; text-align: center;">
<div style="font-size: 24px; font-weight: 600; color: #4CAF50;">${total}</div>
<div style="font-size: 11px; color: var(--vscode-text-dim);">Total Opportunities</div>
</div>
<div style="background: var(--vscode-sidebar); padding: 12px; border-radius: 4px; text-align: center;">
<div style="font-size: 24px; font-weight: 600; color: #FF9800;">${highCount}</div>
<div style="font-size: 11px; color: var(--vscode-text-dim);">High Impact</div>
</div>
<div style="background: var(--vscode-sidebar); padding: 12px; border-radius: 4px; text-align: center;">
<div style="font-size: 24px; font-weight: 600; color: #0066CC;">${fileCount}</div>
<div style="font-size: 11px; color: var(--vscode-text-dim);">Files Affected</div>
</div>
</div>
`;
}
renderWinCard(win) {
const impactColor = win.impact === 'high' ? '#FF9800' : '#0066CC';
const effortColor = win.effort === 'low' ? '#4CAF50' : win.effort === 'medium' ? '#FF9800' : '#F44336';
return `
<div style="
background: var(--vscode-sidebar);
border: 1px solid var(--vscode-border);
border-radius: 4px;
padding: 12px;
margin-bottom: 12px;
">
<div style="display: flex; justify-content: space-between; align-items: start; margin-bottom: 8px;">
<div style="font-weight: 500; font-size: 13px;">${win.title}</div>
<div style="display: flex; gap: 6px;">
<span style="
padding: 2px 8px;
border-radius: 2px;
font-size: 10px;
background: ${impactColor};
color: white;
">${win.impact} impact</span>
<span style="
padding: 2px 8px;
border-radius: 2px;
font-size: 10px;
background: ${effortColor};
color: white;
">${win.effort} effort</span>
</div>
</div>
<p style="margin: 0 0 8px 0; font-size: 12px; color: var(--vscode-text-dim);">
${win.description}
</p>
<div style="
background: var(--vscode-bg);
padding: 8px;
border-radius: 3px;
margin-bottom: 8px;
font-size: 11px;
color: #CE9178;
">
<strong>Recommendation:</strong> ${win.recommendation}
</div>
<div style="display: flex; justify-content: space-between; font-size: 10px; color: var(--vscode-text-dim);">
<span>⏱️ ${win.estimate}</span>
<span>📁 ${win.files_affected} files</span>
</div>
</div>
`;
}
}
customElements.define('ds-quick-wins-script', QuickWinsScript);