import * as readline from "readline" import chalk from "chalk" import { saveConfig, loadConfig, getConfigPath } from "../auth/config" function ask(question: string, defaultValue?: string): Promise { const rl = readline.createInterface({ input: process.stdin, output: process.stdout }) const prompt = defaultValue ? `${question} (${defaultValue})` : question return new Promise((resolve) => { rl.question(`${prompt}: `, (answer) => { rl.close() resolve(answer.trim() || defaultValue || "") }) }) } function askPassword(question: string): Promise { const rl = readline.createInterface({ input: process.stdin, output: process.stdout }) return new Promise((resolve) => { rl.question(`${question}: `, (answer) => { rl.close() resolve(answer.trim()) }) }) } function maskKey(key: string): string { if (key.length <= 12) return "sk_***" return `${key.slice(0, 5)}...${key.slice(-4)}` } export async function loginCommand(): Promise { console.log(chalk.blue.bold("\nLLMTune CLI - API Configuration\n")) const configPath = getConfigPath() const existing = loadConfig() const existingKey = (existing.apiKey as string) || "" const existingUrl = (existing.apiBase as string) || "https://api.llmtune.io/api/agent/v1" const existingModel = (existing.defaultModel as string) || "" console.log(chalk.dim(`Config file: ${configPath}\n`)) const key = await askPassword("Enter your LLMTune API key (sk_...)") if (!key) { console.log(chalk.red("\nAPI key is required.")) process.exit(1) } const apiBase = await ask("API base URL", existingUrl) const model = await ask("Default model (leave empty for auto)", existingModel || undefined) saveConfig({ apiKey: key, apiBase: apiBase.replace(/\/$/, ""), defaultModel: model || undefined, }) console.log(chalk.green("\nConfiguration saved!")) console.log(` API key: ${maskKey(key)}`) console.log(` API base: ${apiBase}`) console.log(` Model: ${model || "auto"}`) console.log(chalk.dim(`\nRun ${chalk.bold("llmtune chat")} to start.\n`)) }