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,266 @@
/**
* ds-figma-plugin.js
* Interface for Figma plugin export and token management
* UX Team Tool #1
*/
import { createFormView, setupFormHandlers } from '../../utils/tool-templates.js';
import { ComponentHelpers } from '../../utils/component-helpers.js';
import contextStore from '../../stores/context-store.js';
import toolBridge from '../../services/tool-bridge.js';
class DSFigmaPlugin extends HTMLElement {
constructor() {
super();
this.exportHistory = [];
}
async connectedCallback() {
this.render();
this.setupEventListeners();
await this.loadExportHistory();
}
async loadExportHistory() {
try {
const context = contextStore.getMCPContext();
if (!context.project_id) return;
const cached = localStorage.getItem(`figma_exports_${context.project_id}`);
if (cached) {
this.exportHistory = JSON.parse(cached);
this.renderHistory();
}
} catch (error) {
console.error('[DSFigmaPlugin] Failed to load history:', error);
}
}
setupEventListeners() {
const exportBtn = this.querySelector('#export-figma-btn');
const fileKeyInput = this.querySelector('#figma-file-key');
const exportTypeSelect = this.querySelector('#export-type-select');
if (exportBtn) {
exportBtn.addEventListener('click', () => this.exportFromFigma());
}
}
async exportFromFigma() {
const fileKeyInput = this.querySelector('#figma-file-key');
const exportTypeSelect = this.querySelector('#export-type-select');
const formatSelect = this.querySelector('#export-format-select');
const fileKey = fileKeyInput?.value.trim() || '';
const exportType = exportTypeSelect?.value || 'tokens';
const format = formatSelect?.value || 'json';
if (!fileKey) {
ComponentHelpers.showToast?.('Please enter a Figma file key', 'error');
return;
}
const exportBtn = this.querySelector('#export-figma-btn');
if (exportBtn) {
exportBtn.disabled = true;
exportBtn.textContent = '⏳ Exporting...';
}
try {
let result;
if (exportType === 'tokens') {
// Export design tokens
result = await toolBridge.executeTool('dss_sync_figma', {
file_key: fileKey
});
} else if (exportType === 'assets') {
// Export assets (icons, images)
const response = await fetch('/api/figma/export-assets', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
projectId: contextStore.get('projectId'),
fileKey,
format
})
});
if (!response.ok) {
throw new Error(`Asset export failed: ${response.statusText}`);
}
result = await response.json();
} else if (exportType === 'components') {
// Export component definitions
const response = await fetch('/api/figma/export-components', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
projectId: contextStore.get('projectId'),
fileKey,
format
})
});
if (!response.ok) {
throw new Error(`Component export failed: ${response.statusText}`);
}
result = await response.json();
}
// Add to history
const exportEntry = {
timestamp: new Date().toISOString(),
fileKey,
type: exportType,
format,
itemCount: result.count || Object.keys(result.tokens || result.assets || result.components || {}).length
};
this.exportHistory.unshift(exportEntry);
this.exportHistory = this.exportHistory.slice(0, 10); // Keep last 10
// Cache history
const context = contextStore.getMCPContext();
if (context.project_id) {
localStorage.setItem(`figma_exports_${context.project_id}`, JSON.stringify(this.exportHistory));
}
this.renderHistory();
ComponentHelpers.showToast?.(`Exported ${exportEntry.itemCount} ${exportType}`, 'success');
} catch (error) {
console.error('[DSFigmaPlugin] Export failed:', error);
ComponentHelpers.showToast?.(`Export failed: ${error.message}`, 'error');
} finally {
if (exportBtn) {
exportBtn.disabled = false;
exportBtn.textContent = '📤 Export from Figma';
}
}
}
renderHistory() {
const historyContainer = this.querySelector('#export-history');
if (!historyContainer) return;
if (this.exportHistory.length === 0) {
historyContainer.innerHTML = ComponentHelpers.renderEmpty('No export history', '📋');
return;
}
historyContainer.innerHTML = `
<div style="display: flex; flex-direction: column; gap: 8px;">
${this.exportHistory.map((entry, idx) => `
<div style="background: var(--vscode-bg); border: 1px solid var(--vscode-border); border-radius: 2px; padding: 12px;">
<div style="display: flex; justify-content: space-between; align-items: start; margin-bottom: 6px;">
<div style="flex: 1;">
<div style="font-size: 11px; font-weight: 600; margin-bottom: 4px;">
${ComponentHelpers.escapeHtml(entry.type)} Export
</div>
<div style="font-size: 10px; color: var(--vscode-text-dim); font-family: monospace;">
${ComponentHelpers.escapeHtml(entry.fileKey)}
</div>
</div>
<div style="text-align: right;">
<div style="font-size: 10px; color: var(--vscode-text-dim);">
${ComponentHelpers.formatRelativeTime(new Date(entry.timestamp))}
</div>
<div style="font-size: 11px; font-weight: 600; margin-top: 2px;">
${entry.itemCount} items
</div>
</div>
</div>
<div style="display: flex; gap: 6px;">
<span style="padding: 2px 6px; background: var(--vscode-sidebar); border-radius: 2px; font-size: 9px;">
${entry.format.toUpperCase()}
</span>
</div>
</div>
`).join('')}
</div>
`;
}
render() {
this.innerHTML = `
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 16px; height: 100%;">
<!-- Export Panel -->
<div style="display: flex; flex-direction: column; height: 100%; border-right: 1px solid var(--vscode-border);">
<div style="padding: 16px; border-bottom: 1px solid var(--vscode-border); background: var(--vscode-sidebar);">
<h3 style="font-size: 12px; font-weight: 600; margin-bottom: 4px;">Figma Export</h3>
<p style="font-size: 10px; color: var(--vscode-text-dim);">
Export tokens, assets, or components from Figma files
</p>
</div>
<div style="flex: 1; overflow: auto; padding: 16px;">
<div style="display: flex; flex-direction: column; gap: 16px;">
<div>
<label style="display: block; font-size: 11px; font-weight: 600; margin-bottom: 6px;">
Figma File Key
</label>
<input
type="text"
id="figma-file-key"
placeholder="abc123def456..."
class="input"
style="width: 100%; font-size: 11px; font-family: monospace;"
/>
<div style="font-size: 10px; color: var(--vscode-text-dim); margin-top: 4px;">
Find this in your Figma file URL
</div>
</div>
<div>
<label style="display: block; font-size: 11px; font-weight: 600; margin-bottom: 6px;">
Export Type
</label>
<select id="export-type-select" class="input" style="width: 100%; font-size: 11px;">
<option value="tokens">Design Tokens</option>
<option value="assets">Assets (Icons, Images)</option>
<option value="components">Component Definitions</option>
</select>
</div>
<div>
<label style="display: block; font-size: 11px; font-weight: 600; margin-bottom: 6px;">
Export Format
</label>
<select id="export-format-select" class="input" style="width: 100%; font-size: 11px;">
<option value="json">JSON</option>
<option value="css">CSS</option>
<option value="scss">SCSS</option>
<option value="js">JavaScript</option>
</select>
</div>
<button id="export-figma-btn" class="button" style="font-size: 12px; padding: 8px;">
📤 Export from Figma
</button>
</div>
</div>
</div>
<!-- History Panel -->
<div style="display: flex; flex-direction: column; height: 100%;">
<div style="padding: 16px; border-bottom: 1px solid var(--vscode-border); background: var(--vscode-sidebar);">
<h3 style="font-size: 12px; font-weight: 600; margin-bottom: 4px;">Export History</h3>
<p style="font-size: 10px; color: var(--vscode-text-dim);">
Recent Figma exports for this project
</p>
</div>
<div id="export-history" style="flex: 1; overflow: auto; padding: 16px;">
${ComponentHelpers.renderLoading('Loading history...')}
</div>
</div>
</div>
`;
}
}
customElements.define('ds-figma-plugin', DSFigmaPlugin);
export default DSFigmaPlugin;