|
1 | 1 | import { stat, rm, writeFile, mkdir } from 'node:fs/promises'; |
2 | 2 | import * as path from 'node:path'; |
3 | 3 | import { homedir } from 'node:os'; |
| 4 | +import { createInterface } from 'node:readline/promises'; |
| 5 | +import { stdin as input, stdout as output } from 'node:process'; |
4 | 6 |
|
5 | 7 | import { expandHomeDir } from '../../../../shared/utils/index.js'; |
6 | 8 | import { metadata } from './metadata.js'; |
@@ -77,6 +79,18 @@ export function getCredentialsPath(configDir: string): string { |
77 | 79 | return path.join(vibeDir, '.env'); |
78 | 80 | } |
79 | 81 |
|
| 82 | +async function promptForApiKey(): Promise<string | null> { |
| 83 | + try { |
| 84 | + const rl = createInterface({ input, output }); |
| 85 | + const answer = await rl.question('Enter MISTRAL_API_KEY: '); |
| 86 | + rl.close(); |
| 87 | + const key = answer.trim(); |
| 88 | + return key ? key : null; |
| 89 | + } catch { |
| 90 | + return null; |
| 91 | + } |
| 92 | +} |
| 93 | + |
80 | 94 | /** |
81 | 95 | * Gets paths to all Mistral-related files that need to be cleaned up |
82 | 96 | * CodeMachine should not manage Vibe's credentials - it only checks if they exist. |
@@ -150,24 +164,31 @@ export async function ensureAuth(options?: MistralAuthOptions): Promise<boolean> |
150 | 164 | throw new Error(`${metadata.name} CLI is not installed.`); |
151 | 165 | } |
152 | 166 |
|
153 | | - // Mistral Vibe CLI manages its own authentication |
154 | | - // We should not interfere with its credentials file (~/.vibe/.env) |
155 | | - // Instead, guide the user to authenticate via Vibe CLI directly |
| 167 | + // CLI is present but no API key - prompt user and persist to ~/.vibe/.env |
156 | 168 | console.log(`\n────────────────────────────────────────────────────────────`); |
157 | 169 | console.log(` 🔐 ${metadata.name} Authentication`); |
158 | 170 | console.log(`────────────────────────────────────────────────────────────`); |
159 | | - console.log(`\n${metadata.name} CLI manages its own authentication.`); |
160 | | - console.log(`\nTo authenticate with ${metadata.name}:\n`); |
161 | | - console.log(`1. Run the Vibe CLI directly to set up your API key:`); |
162 | | - console.log(` vibe\n`); |
163 | | - console.log(`2. When prompted, enter your API key from: https://console.mistral.ai/api-keys`); |
164 | | - console.log(`3. Vibe will store your credentials at ~/.vibe/.env`); |
165 | | - console.log(`4. After authentication, CodeMachine will automatically detect it.\n`); |
166 | | - console.log(`Alternatively, you can set the MISTRAL_API_KEY environment variable:\n`); |
167 | | - console.log(` export MISTRAL_API_KEY=<your-api-key>\n`); |
| 171 | + console.log(`\n${metadata.name} CLI requires the MISTRAL_API_KEY.`); |
| 172 | + console.log(`You can paste it here and we'll save it to ~/.vibe/.env for you.\n`); |
| 173 | + |
| 174 | + const apiKey = await promptForApiKey(); |
| 175 | + if (apiKey) { |
| 176 | + const vibeDir = path.join(homedir(), '.vibe'); |
| 177 | + await mkdir(vibeDir, { recursive: true }); |
| 178 | + const envPath = path.join(vibeDir, '.env'); |
| 179 | + await writeFile(envPath, `MISTRAL_API_KEY=${apiKey}\n`, { encoding: 'utf8' }); |
| 180 | + process.env.MISTRAL_API_KEY = apiKey; // make available for this process |
| 181 | + console.log(`\nSaved API key to ${envPath}\n`); |
| 182 | + return true; |
| 183 | + } |
| 184 | + |
| 185 | + console.log(`\nNo API key provided. You can also set it manually:\n`); |
| 186 | + console.log(` export MISTRAL_API_KEY=<your-api-key>\n`); |
| 187 | + console.log(`or create ~/.vibe/.env with:\n`); |
| 188 | + console.log(` MISTRAL_API_KEY=<your-api-key>\n`); |
168 | 189 | console.log(`────────────────────────────────────────────────────────────\n`); |
169 | 190 |
|
170 | | - throw new Error('Authentication incomplete. Please authenticate via Vibe CLI or set MISTRAL_API_KEY environment variable.'); |
| 191 | + throw new Error('Authentication incomplete. Please set MISTRAL_API_KEY.'); |
171 | 192 | } |
172 | 193 |
|
173 | 194 | /** |
|
0 commit comments