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
91 lines
2.2 KiB
JavaScript
91 lines
2.2 KiB
JavaScript
/**
|
|
* Design System Server (DSS) - Discovery Service
|
|
*
|
|
* Project analysis interface for the admin dashboard.
|
|
* No mocks - requires backend connection.
|
|
*/
|
|
|
|
class DiscoveryService {
|
|
constructor() {
|
|
this.apiBase = '/api/discovery';
|
|
this.connected = null;
|
|
this.cache = new Map();
|
|
this.cacheExpiry = 5 * 60 * 1000; // 5 minutes
|
|
}
|
|
|
|
async checkConnection() {
|
|
try {
|
|
const response = await fetch('/health', { method: 'GET' });
|
|
this.connected = response.ok;
|
|
} catch {
|
|
this.connected = false;
|
|
}
|
|
return this.connected;
|
|
}
|
|
|
|
_requireConnection() {
|
|
if (this.connected === false) {
|
|
throw new Error('API unavailable. Start DSS server first.');
|
|
}
|
|
}
|
|
|
|
async discover(projectPath = '.', fullScan = false) {
|
|
const cacheKey = `${projectPath}:${fullScan}`;
|
|
|
|
// Check cache
|
|
if (this.cache.has(cacheKey)) {
|
|
const cached = this.cache.get(cacheKey);
|
|
if (Date.now() - cached.timestamp < this.cacheExpiry) {
|
|
return cached.data;
|
|
}
|
|
}
|
|
|
|
const response = await fetch(`${this.apiBase}/scan`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ path: projectPath, full_scan: fullScan })
|
|
});
|
|
|
|
if (!response.ok) {
|
|
const err = await response.json().catch(() => ({}));
|
|
throw new Error(err.detail || 'Discovery scan failed');
|
|
}
|
|
|
|
const result = await response.json();
|
|
this.cache.set(cacheKey, { data: result, timestamp: Date.now() });
|
|
return result;
|
|
}
|
|
|
|
async getHealth() {
|
|
const response = await fetch('/health');
|
|
if (!response.ok) {
|
|
throw new Error('Health check failed');
|
|
}
|
|
return response.json();
|
|
}
|
|
|
|
async getRecentActivity() {
|
|
const response = await fetch(`${this.apiBase}/activity`);
|
|
if (!response.ok) {
|
|
return { items: [] };
|
|
}
|
|
return response.json();
|
|
}
|
|
|
|
async getProjectStats() {
|
|
const response = await fetch(`${this.apiBase}/stats`);
|
|
if (!response.ok) {
|
|
return { projects: {}, tokens: {}, components: {}, syncs: {} };
|
|
}
|
|
return response.json();
|
|
}
|
|
|
|
invalidateCache() {
|
|
this.cache.clear();
|
|
}
|
|
}
|
|
|
|
const discoveryService = new DiscoveryService();
|
|
export { DiscoveryService };
|
|
export default discoveryService;
|