context-forge
Version:
AI orchestration platform with autonomous teams, enhancement planning, migration tools, 25+ slash commands, checkpoints & hooks. Multi-IDE: Claude, Cursor, Windsurf, Cline, Copilot
128 lines • 5.03 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ApiKeyManager = void 0;
const fs_extra_1 = __importDefault(require("fs-extra"));
const path_1 = __importDefault(require("path"));
const inquirer_1 = __importDefault(require("inquirer"));
const chalk_1 = __importDefault(require("chalk"));
class ApiKeyManager {
constructor(projectPath) {
this.projectPath = projectPath;
this.configPath = path_1.default.join(projectPath, '.context-forge-api');
this.gitignorePath = path_1.default.join(projectPath, '.gitignore');
}
async setupApiKey() {
// Check if config already exists
if (await fs_extra_1.default.pathExists(this.configPath)) {
const useExisting = await inquirer_1.default.prompt([
{
type: 'confirm',
name: 'useExisting',
message: 'Found existing API configuration. Use it?',
default: true,
},
]);
if (useExisting.useExisting) {
return this.loadConfig();
}
}
// Interactive API provider selection
const { provider } = await inquirer_1.default.prompt([
{
type: 'list',
name: 'provider',
message: 'Which AI provider would you like to use for analysis?',
choices: [
{ name: 'Anthropic Claude (Claude-3.5-Sonnet)', value: 'anthropic' },
{ name: 'OpenAI (GPT-4)', value: 'openai' },
{ name: 'Google Gemini (Gemini-1.5-Pro)', value: 'gemini' },
],
},
]);
// Get API key securely
const { apiKey } = await inquirer_1.default.prompt([
{
type: 'password',
name: 'apiKey',
message: `Enter your ${this.getProviderName(provider)} API key:`,
mask: '*',
validate: (input) => {
if (!input || input.trim().length === 0) {
return 'API key is required';
}
if (input.length < 10) {
return 'API key seems too short';
}
return true;
},
},
]);
const config = {
provider,
apiKey: apiKey.trim(),
model: this.getDefaultModel(provider),
};
// Save config
await this.saveConfig(config);
await this.updateGitignore();
console.log(chalk_1.default.green('\n✅ API configuration saved securely'));
console.log(chalk_1.default.gray('• Config stored in .context-forge-api'));
console.log(chalk_1.default.gray('• Added to .gitignore automatically\n'));
return config;
}
async loadConfig() {
try {
if (!(await fs_extra_1.default.pathExists(this.configPath))) {
return null;
}
const configData = await fs_extra_1.default.readFile(this.configPath, 'utf-8');
return JSON.parse(configData);
}
catch {
console.warn(chalk_1.default.yellow('Warning: Could not load API configuration'));
return null;
}
}
async saveConfig(config) {
await fs_extra_1.default.writeFile(this.configPath, JSON.stringify(config, null, 2), { mode: 0o600 });
}
async updateGitignore() {
const gitignoreEntry = '.context-forge-api';
try {
let gitignoreContent = '';
if (await fs_extra_1.default.pathExists(this.gitignorePath)) {
gitignoreContent = await fs_extra_1.default.readFile(this.gitignorePath, 'utf-8');
}
if (!gitignoreContent.includes(gitignoreEntry)) {
const newContent = gitignoreContent
? `${gitignoreContent.trimEnd()}\n\n# Context Forge API keys\n${gitignoreEntry}\n`
: `# Context Forge API keys\n${gitignoreEntry}\n`;
await fs_extra_1.default.writeFile(this.gitignorePath, newContent);
}
}
catch {
console.warn(chalk_1.default.yellow('Warning: Could not update .gitignore'));
}
}
getProviderName(provider) {
const names = {
anthropic: 'Anthropic',
openai: 'OpenAI',
gemini: 'Google',
};
return names[provider] || provider;
}
getDefaultModel(provider) {
const models = {
anthropic: 'claude-3-5-sonnet-20241022',
openai: 'gpt-4-turbo-preview',
gemini: 'gemini-1.5-pro',
};
return models[provider] || '';
}
}
exports.ApiKeyManager = ApiKeyManager;
//# sourceMappingURL=apiKeyManager.js.map