UNPKG

@meldscience/meld

Version:

pipeable one-shot prompt scripting toolkit

143 lines 5.43 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.RC_FILE = void 0; exports.loadConfig = loadConfig; exports.setupConfig = setupConfig; exports.checkAndPromptConfig = checkAndPromptConfig; const fs_1 = require("fs"); const os_1 = require("os"); const path_1 = require("path"); const errors_1 = require("./errors"); const child_process_1 = require("child_process"); exports.RC_FILE = '.meldrc'; function resolveSecretReference(value) { if (!value.startsWith('op://')) { return value; } try { return (0, child_process_1.execSync)(`op read "${value}"`, { encoding: 'utf-8' }).trim(); } catch (error) { throw new errors_1.ToolError(`Failed to resolve 1Password secret reference: ${error.message}`, 'SECRET_REFERENCE_ERROR'); } } function loadConfig(options) { // Start with empty config const config = {}; // Load from environment variables (lowest priority) if (process.env.DEFAULT_MODEL) { config.defaultModel = process.env.DEFAULT_MODEL; } if (process.env.ANTHROPIC_API_KEY) { config.anthropicApiKey = process.env.ANTHROPIC_API_KEY; } if (process.env.OPENAI_API_KEY) { config.openaiApiKey = process.env.OPENAI_API_KEY; } // Try to load .meldrc from home directory (middle priority) try { const rcPath = (0, path_1.join)((0, os_1.homedir)(), exports.RC_FILE); if ((0, fs_1.existsSync)(rcPath)) { const rcContent = (0, fs_1.readFileSync)(rcPath, 'utf-8'); const rcConfig = JSON.parse(rcContent); // Resolve any secret references in the config if (rcConfig.anthropicApiKey) { try { rcConfig.anthropicApiKey = resolveSecretReference(rcConfig.anthropicApiKey); } catch (error) { throw error; // Re-throw ToolError } } if (rcConfig.openaiApiKey) { try { rcConfig.openaiApiKey = resolveSecretReference(rcConfig.openaiApiKey); } catch (error) { throw error; // Re-throw ToolError } } Object.assign(config, rcConfig); } } catch (error) { if (error instanceof errors_1.ToolError) { throw error; // Re-throw our own errors } // Ignore other errors reading config file - it's optional } // Override with any passed options (highest priority) if (options) { Object.assign(config, options); } return config; } function setupConfig(options) { const rcPath = (0, path_1.join)((0, os_1.homedir)(), exports.RC_FILE); let config = {}; // Read existing config if it exists if ((0, fs_1.existsSync)(rcPath)) { try { const rcContent = (0, fs_1.readFileSync)(rcPath, 'utf-8'); config = JSON.parse(rcContent); } catch (error) { // If file exists but is invalid, we'll overwrite it console.warn('⚠️ Existing config file is invalid, creating new one'); } } // Update config with new values if (options.anthropicApiKey) config.anthropicApiKey = options.anthropicApiKey; if (options.openaiApiKey) config.openaiApiKey = options.openaiApiKey; if (options.defaultModel) config.defaultModel = options.defaultModel; // Write config file (0, fs_1.writeFileSync)(rcPath, JSON.stringify(config, null, 2)); } function checkAndPromptConfig(models) { const config = loadConfig(); const rcPath = (0, path_1.join)((0, os_1.homedir)(), exports.RC_FILE); const needsAnthropicKey = models.some(m => m.startsWith('claude')) && !config.anthropicApiKey; const needsOpenAIKey = models.some(m => m.startsWith('gpt')) && !config.openaiApiKey; if (!needsAnthropicKey && !needsOpenAIKey) { return; // All required keys are present } console.log('\n⚠️ Missing API key configuration'); console.log('--------------------------------'); if (needsAnthropicKey) { console.log('• Anthropic API key required for Claude models'); } if (needsOpenAIKey) { console.log('• OpenAI API key required for GPT models'); } console.log('\nTo configure your API keys, use:'); if (needsAnthropicKey) { console.log(' meld-config --anthropic-key <your-key>'); } if (needsOpenAIKey) { console.log(' meld-config --openai-key <your-key>'); } console.log('\nOr use 1Password CLI secret references in .meldrc:'); console.log(' {'); if (needsAnthropicKey) { console.log(' "anthropicApiKey": "op://vault-name/anthropic/api-key"'); } if (needsOpenAIKey) { console.log(' "openaiApiKey": "op://vault-name/openai/api-key"'); } console.log(' }'); console.log('\nOr set environment variables:'); if (needsAnthropicKey) { console.log(' export ANTHROPIC_API_KEY=<your-key>'); } if (needsOpenAIKey) { console.log(' export OPENAI_API_KEY=<your-key>'); } console.log(`\nConfiguration will be saved to: ${rcPath}`); console.log('\nFor more options, run: meld-config --help'); // Exit with error throw new errors_1.ToolError('API keys required', 'MISSING_API_KEYS'); } //# sourceMappingURL=config.js.map