UNPKG

@yeepay/coderocket-mcp

Version:

CodeRocket MCP - Independent AI-powered code review server for Model Context Protocol

214 lines 6.57 kB
import { readFile } from 'fs/promises'; import { join } from 'path'; import { homedir } from 'os'; import { logger } from '../logger.js'; /** * 独立配置管理类 * * 支持多层级配置加载: * 1. 环境变量(最高优先级) * 2. 项目级 .env 文件 * 3. 全局 ~/.coderocket/env 文件 * 4. 默认值(最低优先级) */ export class ConfigManager { static config = {}; static initialized = false; /** * 初始化配置系统 */ static async initialize(force = false) { if (this.initialized && !force) return; // 如果强制重新初始化,重置状态 if (force) { this.initialized = false; this.config = {}; } // 加载默认配置 this.loadDefaults(); // 加载全局配置文件 await this.loadGlobalConfig(); // 加载项目配置文件 await this.loadProjectConfig(); // 加载环境变量(最高优先级) this.loadEnvironmentVariables(); this.initialized = true; logger.info('配置系统初始化完成', { config: this.getSafeConfig() }); } /** * 检查是否已初始化(安全方法) */ static isInitialized() { return this.initialized; } /** * 加载默认配置 */ static loadDefaults() { this.config = { AI_SERVICE: 'gemini', AI_AUTO_SWITCH: 'true', AI_TIMEOUT: '30', AI_MAX_RETRIES: '3', AI_RETRY_DELAY: '2', AI_LANGUAGE: 'zh-CN', NODE_ENV: 'production', DEBUG: 'false', GEMINI_MODEL: 'gemini-1.5-flash', CLAUDE_MODEL: 'claude-3-sonnet-20240229', FILE_CONTENT_CHAR_LIMIT: '5000', }; } static async loadGlobalConfig() { try { const globalConfigPath = join(homedir(), '.coderocket', 'env'); const content = await readFile(globalConfigPath, 'utf-8'); const globalConfig = this.parseEnvContent(content); Object.assign(this.config, globalConfig); logger.debug('全局配置加载成功', { path: globalConfigPath }); } catch (error) { // 全局配置文件不存在是正常的 logger.debug('全局配置文件不存在,跳过'); } } /** * 加载项目配置文件 .env */ static async loadProjectConfig() { try { const projectConfigPath = join(process.cwd(), '.env'); const content = await readFile(projectConfigPath, 'utf-8'); const projectConfig = this.parseEnvContent(content); Object.assign(this.config, projectConfig); logger.debug('项目配置加载成功', { path: projectConfigPath }); } catch (error) { // 项目配置文件不存在是正常的 logger.debug('项目配置文件不存在,跳过'); } } /** * 加载环境变量(最高优先级) */ static loadEnvironmentVariables() { const envKeys = [ 'AI_SERVICE', 'AI_AUTO_SWITCH', 'AI_TIMEOUT', 'AI_MAX_RETRIES', 'AI_RETRY_DELAY', 'GEMINI_API_KEY', 'CLAUDE_API_KEY', 'NODE_ENV', 'DEBUG', ]; envKeys.forEach(key => { if (process.env[key]) { this.config[key] = process.env[key]; } }); } /** * 解析 .env 文件内容 */ static parseEnvContent(content) { const config = {}; const lines = content.split('\n'); for (const line of lines) { const trimmedLine = line.trim(); if (trimmedLine && !trimmedLine.startsWith('#')) { const [key, ...valueParts] = trimmedLine.split('='); if (key && valueParts.length > 0) { const value = valueParts.join('=').trim(); // 移除引号 config[key.trim()] = value.replace(/^["']|["']$/g, ''); } } } return config; } /** * 获取配置值 */ static get(key, defaultValue) { if (!this.initialized) { throw new Error('ConfigManager 未初始化,请先调用 initialize()'); } return this.config[key] ?? defaultValue; } /** * 获取API密钥环境变量名 */ static getAPIKeyEnvVar(service) { const envVarMap = { gemini: 'GEMINI_API_KEY', claudecode: 'CLAUDE_API_KEY', }; return envVarMap[service]; } /** * 获取API密钥 */ static getAPIKey(service) { const envVar = this.getAPIKeyEnvVar(service); return this.get(envVar, ''); } /** * 获取AI服务配置 */ static getAIService() { const service = this.get('AI_SERVICE', 'gemini').toLowerCase(); if (['gemini', 'claudecode'].includes(service)) { return service; } return 'gemini'; } /** * 获取超时配置 */ static getTimeout() { return parseInt(this.get('AI_TIMEOUT', '30'), 10); } /** * 获取最大重试次数 */ static getMaxRetries() { return parseInt(this.get('AI_MAX_RETRIES', '3'), 10); } /** * 是否启用自动切换 */ static isAutoSwitchEnabled() { return this.get('AI_AUTO_SWITCH', 'true').toLowerCase() === 'true'; } /** * 获取AI服务语言设置 */ static getAILanguage() { return this.get('AI_LANGUAGE', 'zh-CN'); } /** * 获取安全的配置信息(隐藏敏感信息) */ static getSafeConfig() { const safeConfig = { ...this.config }; // 隐藏API密钥 Object.keys(safeConfig).forEach(key => { if (key.includes('API_KEY') || key.includes('TOKEN')) { safeConfig[key] = safeConfig[key] ? '***' : undefined; } }); return safeConfig; } /** * 获取配置文件路径(保持向后兼容) */ static getConfigPath(scope) { const configDir = scope === 'global' ? join(homedir(), '.coderocket') : process.cwd(); const configFile = scope === 'global' ? join(configDir, 'env') : join(configDir, '.env'); return { dir: configDir, file: configFile }; } } //# sourceMappingURL=ConfigManager.js.map