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,128 @@
/**
* Configuration Loader - Secure Configuration Loading Pattern
*
* This implements the expert-recommended blocking initialization pattern:
* 1. loadConfig() fetches from /api/config and stores it
* 2. getConfig() returns config or throws if not loaded
* 3. Application only initializes after loadConfig() completes
*
* This prevents race conditions where components try to access config
* before it's been fetched from the server.
*/
/**
* Module-scoped variable to hold the fetched server configuration.
* @type {Object|null}
*/
let serverConfig = null;
/**
* Fetches configuration from the server and stores it.
* This MUST be called before the application initializes any components
* that depend on the configuration.
*
* @async
* @returns {Promise<void>}
* @throws {Error} If the config endpoint is unreachable or returns an error
*/
export async function loadConfig() {
// Prevent double-loading
if (serverConfig) {
console.warn('[ConfigLoader] Configuration already loaded.');
return;
}
try {
const response = await fetch('/api/config');
if (!response.ok) {
throw new Error(`Server returned status ${response.status}: ${response.statusText}`);
}
serverConfig = await response.json();
console.log('[ConfigLoader] Configuration loaded successfully', {
dssHost: serverConfig.dssHost,
dssPort: serverConfig.dssPort,
storybookPort: serverConfig.storybookPort,
});
} catch (error) {
console.error('[ConfigLoader] Failed to load configuration:', error);
// Re-throw to be caught by the bootstrap function
throw new Error(`Failed to load server configuration: ${error.message}`);
}
}
/**
* Returns the entire configuration object.
* MUST ONLY be called after loadConfig() has completed successfully.
*
* @returns {Object} The server configuration
* @throws {Error} If called before loadConfig() has completed
*/
export function getConfig() {
if (!serverConfig) {
throw new Error('[ConfigLoader] getConfig() called before configuration was loaded. Did you forget to await loadConfig()?');
}
return serverConfig;
}
/**
* Convenience getter for just the DSS host.
* @returns {string} The DSS host
*/
export function getDssHost() {
const config = getConfig();
return config.dssHost;
}
/**
* Convenience getter for DSS port.
* @returns {string} The DSS port
*/
export function getDssPort() {
const config = getConfig();
return config.dssPort;
}
/**
* Convenience getter for Storybook port.
* @returns {number} The Storybook port (always 6006)
*/
export function getStorybookPort() {
const config = getConfig();
return config.storybookPort;
}
/**
* Builds the full Storybook URL from config.
* Points to Storybook running on port 6006 on the current host.
*
* @returns {string} The full Storybook URL (e.g., "http://dss.overbits.luz.uy:6006")
*/
export function getStorybookUrl() {
const dssHost = getDssHost();
const protocol = window.location.protocol; // "http:" or "https:"
// Point to Storybook on port 6006
return `${protocol}//${dssHost}:6006`;
}
/**
* TESTING ONLY: Reset the configuration state
* This allows tests to load different configurations
* @internal
*/
export function __resetForTesting() {
serverConfig = null;
}
export default {
loadConfig,
getConfig,
getDssHost,
getDssPort,
getStorybookPort,
getStorybookUrl,
__resetForTesting,
};