UNPKG

recoder-shared

Version:

Shared types, utilities, and configurations for Recoder

363 lines 12 kB
"use strict"; /** * Unified Configuration System for Recoder.xyz Ecosystem * * Provides consistent configuration across CLI, Web Platform, and VS Code Extension */ Object.defineProperty(exports, "__esModule", { value: true }); exports.getAvailableProviders = exports.isConfigured = exports.getDefaultConfigPath = exports.extensionConfig = exports.webConfig = exports.cliConfig = exports.UnifiedConfigManager = void 0; const tslib_1 = require("tslib"); const os = tslib_1.__importStar(require("os")); const path = tslib_1.__importStar(require("path")); const fs = tslib_1.__importStar(require("fs")); class UnifiedConfigManager { constructor(platform) { this.platform = platform; this.configPath = this.getConfigPath(); this.config = this.loadConfig(); } static getInstance(platform) { if (!UnifiedConfigManager.instance) { UnifiedConfigManager.instance = new UnifiedConfigManager(platform); } return UnifiedConfigManager.instance; } /** * Get the configuration file path based on platform */ getConfigPath() { const homeDir = os.homedir(); const configDir = path.join(homeDir, '.recoder'); // Ensure config directory exists if (!fs.existsSync(configDir)) { fs.mkdirSync(configDir, { recursive: true }); } return path.join(configDir, 'config.json'); } /** * Load configuration from file or create default */ loadConfig() { try { if (fs.existsSync(this.configPath)) { const configData = fs.readFileSync(this.configPath, 'utf8'); const existingConfig = JSON.parse(configData); // Merge with defaults to ensure all properties exist return this.mergeWithDefaults(existingConfig); } } catch (error) { console.warn('Failed to load config, using defaults:', error); } return this.getDefaultConfig(); } /** * Get default configuration */ getDefaultConfig() { return { version: '1.0.0', lastUpdated: new Date().toISOString(), aiProviders: { claude: { enabled: !!process.env['ANTHROPIC_API_KEY'], apiKey: process.env['ANTHROPIC_API_KEY'], models: ['claude-3-5-sonnet-20241022', 'claude-3-5-haiku-20241022'], useCases: ['complex-logic', 'architecture', 'security', 'code-review'], priority: 1 }, groq: { enabled: !!process.env['GROQ_API_KEY'], apiKey: process.env['GROQ_API_KEY'], models: ['llama-3.1-70b-versatile', 'llama-3.1-8b-instant'], useCases: ['fast-generation', 'api-endpoints', 'prototyping', 'react'], priority: 2 }, gemini: { enabled: !!process.env['GOOGLE_API_KEY'], apiKey: process.env['GOOGLE_API_KEY'], models: ['gemini-2.0-flash-exp', 'gemini-1.5-pro'], useCases: ['large-codebases', 'multimodal', 'documentation', 'analysis'], priority: 3 }, ollama: { enabled: !!process.env['OLLAMA_BASE_URL'] || fs.existsSync('/usr/local/bin/ollama'), baseUrl: process.env['OLLAMA_BASE_URL'] || 'http://localhost:11434', models: ['llama3.2', 'codellama', 'deepseek-coder'], useCases: ['offline', 'privacy', 'local-development', 'custom-models'], priority: 4 } }, defaultProvider: 'claude', intelligentRouting: true, qualityValidation: true, realCodeOnly: true, vulnerabilityScanning: true, projectDefaults: { language: 'typescript', includeTests: true, includeDocs: false }, cli: { outputFormat: 'text', verboseLogging: false, autoUpdate: true, telemetry: true }, web: { theme: 'auto', autoSave: true, showPreview: true }, extension: { autoActivate: true, showInlineHints: true, ghostMode: true, keybindings: { 'focusInput': 'cmd+shift+a', 'generateCode': 'cmd+shift+g', 'explainCode': 'cmd+shift+e' } }, features: { sessionSharing: false, crossPlatformSync: false, agentMarketplace: true, collaborativeEditing: false }, security: { encryptApiKeys: true, allowRemoteExecution: false, trustedDomains: ['recoder.xyz', 'api.recoder.xyz', 'web.recoder.xyz'], maxTokenUsage: 1000000 } }; } /** * Merge existing config with defaults */ mergeWithDefaults(existingConfig) { const defaults = this.getDefaultConfig(); return { ...defaults, ...existingConfig, aiProviders: { ...defaults.aiProviders, ...existingConfig.aiProviders }, projectDefaults: { ...defaults.projectDefaults, ...existingConfig.projectDefaults }, cli: { ...defaults.cli, ...existingConfig.cli }, web: { ...defaults.web, ...existingConfig.web }, extension: { ...defaults.extension, ...existingConfig.extension }, features: { ...defaults.features, ...existingConfig.features }, security: { ...defaults.security, ...existingConfig.security } }; } /** * Save configuration to file */ saveConfig() { try { this.config.lastUpdated = new Date().toISOString(); const configData = JSON.stringify(this.config, null, 2); fs.writeFileSync(this.configPath, configData, 'utf8'); } catch (error) { console.error('Failed to save config:', error); throw new Error('Unable to save configuration'); } } /** * Get the full configuration */ getConfig() { return { ...this.config }; } /** * Get AI provider configuration */ getAIProviders() { return { ...this.config.aiProviders }; } /** * Get enabled AI providers sorted by priority */ getEnabledProviders() { return Object.entries(this.config.aiProviders) .filter(([_, config]) => config.enabled) .sort(([_, a], [__, b]) => a.priority - b.priority) .map(([name, config]) => ({ name, config })); } /** * Update AI provider configuration */ updateAIProvider(provider, config) { if (this.config.aiProviders[provider]) { this.config.aiProviders[provider] = { ...this.config.aiProviders[provider], ...config }; this.saveConfig(); } } /** * Set API key for a provider */ setAPIKey(provider, apiKey) { this.updateAIProvider(provider, { apiKey, enabled: true }); } /** * Get platform-specific configuration */ getPlatformConfig() { return this.config[this.platform]; } /** * Update platform-specific configuration */ updatePlatformConfig(updates) { this.config[this.platform] = { ...this.config[this.platform], ...updates }; this.saveConfig(); } /** * Get project defaults */ getProjectDefaults() { return { ...this.config.projectDefaults }; } /** * Update project defaults */ updateProjectDefaults(updates) { this.config.projectDefaults = { ...this.config.projectDefaults, ...updates }; this.saveConfig(); } /** * Check if a feature is enabled */ isFeatureEnabled(feature) { return this.config.features[feature]; } /** * Enable/disable a feature */ setFeature(feature, enabled) { this.config.features[feature] = enabled; this.saveConfig(); } /** * Get security settings */ getSecurityConfig() { return { ...this.config.security }; } /** * Validate configuration */ validateConfig() { const errors = []; // Check if at least one AI provider is enabled const enabledProviders = this.getEnabledProviders(); if (enabledProviders.length === 0) { errors.push('At least one AI provider must be enabled'); } // Validate API keys for enabled providers enabledProviders.forEach(({ name, config }) => { if (name !== 'ollama' && !config.apiKey) { errors.push(`API key required for ${name}`); } }); // Validate Ollama configuration const ollamaConfig = this.config.aiProviders.ollama; if (ollamaConfig.enabled && !ollamaConfig.baseUrl) { errors.push('Ollama base URL is required when Ollama is enabled'); } return { isValid: errors.length === 0, errors }; } /** * Reset configuration to defaults */ resetConfig() { this.config = this.getDefaultConfig(); this.saveConfig(); } /** * Export configuration for sharing */ exportConfig(includeSecrets = false) { const exportConfig = { ...this.config }; if (!includeSecrets) { // Remove sensitive information Object.keys(exportConfig.aiProviders).forEach(provider => { const providerConfig = exportConfig.aiProviders[provider]; if (providerConfig.apiKey) { providerConfig.apiKey = '***REDACTED***'; } }); } return JSON.stringify(exportConfig, null, 2); } /** * Import configuration from string */ importConfig(configString) { try { const importedConfig = JSON.parse(configString); this.config = this.mergeWithDefaults(importedConfig); this.saveConfig(); } catch (error) { throw new Error('Invalid configuration format'); } } } exports.UnifiedConfigManager = UnifiedConfigManager; // Export singleton instances for each platform const cliConfig = () => UnifiedConfigManager.getInstance('cli'); exports.cliConfig = cliConfig; const webConfig = () => UnifiedConfigManager.getInstance('web'); exports.webConfig = webConfig; const extensionConfig = () => UnifiedConfigManager.getInstance('extension'); exports.extensionConfig = extensionConfig; // Utility functions const getDefaultConfigPath = () => { return path.join(os.homedir(), '.recoder', 'config.json'); }; exports.getDefaultConfigPath = getDefaultConfigPath; const isConfigured = () => { return fs.existsSync((0, exports.getDefaultConfigPath)()); }; exports.isConfigured = isConfigured; const getAvailableProviders = () => { return ['claude', 'groq', 'gemini', 'ollama']; }; exports.getAvailableProviders = getAvailableProviders; exports.default = UnifiedConfigManager; //# sourceMappingURL=unified-config.js.map