@meldscience/meld
Version:
pipeable one-shot prompt scripting toolkit
143 lines • 5.43 kB
JavaScript
;
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