UNPKG

create-ai-chat-context-experimental

Version:

Phase 2: TypeScript rewrite - AI Chat Context & Memory System with conversation extraction and AICF format support (powered by aicf-core v2.1.0).

168 lines 6.48 kB
/** * This file is part of create-ai-chat-context-experimental. * Licensed under the GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later). * See LICENSE file for details. */ import fs from 'fs-extra'; import path from 'path'; import chalk from 'chalk'; const CONFIG_FILE = '.ai/config.json'; /** * Default configuration */ const DEFAULT_CONFIG = { preferredModel: null, showAllModels: false, useAiNativeFormat: false, }; /** * Get configuration file path */ export function getConfigPath(cwd = process.cwd()) { return path.join(cwd, CONFIG_FILE); } /** * Load configuration */ export async function loadConfig(cwd = process.cwd()) { const configPath = getConfigPath(cwd); try { if (await fs.pathExists(configPath)) { const config = await fs.readJson(configPath); return { ...DEFAULT_CONFIG, ...config }; } } catch { // If config is corrupted, return defaults console.warn(chalk.yellow('⚠️ Config file corrupted, using defaults')); } return { ...DEFAULT_CONFIG }; } /** * Save configuration */ export async function saveConfig(config, cwd = process.cwd()) { const configPath = getConfigPath(cwd); const aiDir = path.dirname(configPath); // Ensure .ai directory exists await fs.ensureDir(aiDir); // Merge with existing config const existingConfig = await loadConfig(cwd); const newConfig = { ...existingConfig, ...config }; await fs.writeJson(configPath, newConfig, { spaces: 2 }); return newConfig; } /** * Get a specific config value */ export async function getConfigValue(key, cwd = process.cwd()) { const config = await loadConfig(cwd); return config[key]; } /** * Set a specific config value */ export async function setConfigValue(key, value, cwd = process.cwd()) { const config = await loadConfig(cwd); config[key] = value; await saveConfig(config, cwd); return config; } /** * List all configuration */ export async function listConfig(cwd = process.cwd()) { const config = await loadConfig(cwd); console.log(chalk.bold.cyan('\n⚙️ Configuration\n')); if (config.preferredModel) { console.log(`${chalk.bold('Preferred Model:')} ${chalk.cyan(config.preferredModel)}`); } else { console.log(`${chalk.bold('Preferred Model:')} ${chalk.gray('(not set)')}`); } console.log(`${chalk.bold('Show All Models:')} ${config.showAllModels ? chalk.green('Yes') : chalk.gray('No')}`); console.log(`${chalk.bold('AI-Native Format:')} ${config.useAiNativeFormat ? chalk.green('Enabled') + chalk.gray(' (85% token reduction!)') : chalk.gray('Disabled') + chalk.gray(' (using YAML)')}`); console.log(); console.log(chalk.gray("💡 Tip: Use 'npx aic config set <key> <value>' to change settings")); console.log(); } /** * Handle config command */ export async function handleConfigCommand(action, key, value) { const cwd = process.cwd(); try { // Check if .ai directory exists const aiDir = path.join(cwd, '.ai'); if (!(await fs.pathExists(aiDir))) { console.log(chalk.yellow("\n⚠️ No .ai/ directory found. Run 'npx aic init' first.\n")); return; } if (!action || action === 'list') { // List all config await listConfig(cwd); return; } if (action === 'get') { // Get specific value if (!key) { console.log(chalk.red('\n❌ Error: Please specify a config key\n')); console.log(chalk.gray('Usage: npx aic config get <key>\n')); return; } const configValue = await getConfigValue(key, cwd); console.log(chalk.cyan(configValue || '(not set)')); return; } if (action === 'set') { // Set specific value if (!key || value === undefined) { console.log(chalk.red('\n❌ Error: Please specify both key and value\n')); console.log(chalk.gray('Usage: npx aic config set <key> <value>\n')); return; } // Validate known keys if (key === 'preferredModel') { await setConfigValue('preferredModel', value, cwd); console.log(chalk.green(`\n✅ Preferred model set to: ${chalk.cyan(value)}\n`)); console.log(chalk.gray("💡 Run 'npx aic tokens' to see how your context fits in this model\n")); } else if (key === 'showAllModels') { const boolValue = value === 'true' || value === '1' || value === 'yes'; await setConfigValue('showAllModels', boolValue, cwd); console.log(chalk.green(`\n✅ Show all models set to: ${chalk.cyan(String(boolValue))}\n`)); } else if (key === 'useAiNativeFormat') { const boolValue = value === 'true' || value === '1' || value === 'yes'; await setConfigValue('useAiNativeFormat', boolValue, cwd); console.log(chalk.green(`\n✅ AI-native format set to: ${chalk.cyan(String(boolValue))}\n`)); console.log(chalk.gray(boolValue ? '💡 chat-finish will now generate ultra-compact format (85% token reduction!)' : '💡 chat-finish will use YAML format (human-readable)')); console.log(chalk.gray('\n')); } else { console.log(chalk.yellow(`\n⚠️ Unknown config key: ${key}\n`)); console.log(chalk.gray('Available keys:')); console.log(chalk.gray(' - preferredModel')); console.log(chalk.gray(' - showAllModels')); console.log(chalk.gray(' - useAiNativeFormat\n')); } return; } // Unknown action console.log(chalk.red(`\n❌ Unknown action: ${action}\n`)); console.log(chalk.gray('Available actions:')); console.log(chalk.gray(' - list (default)')); console.log(chalk.gray(' - get <key>')); console.log(chalk.gray(' - set <key> <value>\n')); } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); console.error(chalk.red('\n❌ Error:'), errorMessage); console.log(); } } //# sourceMappingURL=Config.js.map