UNPKG

ai-team-orchestrator

Version:

🧠 AI Team Advanced - Maximum Quality Agent System avec 9 agents ultra-spĂ©cialisĂ©s et collaboration intelligente

465 lines (405 loc) ‱ 14.6 kB
#!/usr/bin/env node import fs from 'fs'; import chalk from 'chalk'; import inquirer from 'inquirer'; /** * Gestionnaire de configuration pour Together.ai API Key * SimplifiĂ© pour DeepSeek R1 */ export class APIKeyManager { constructor() { this.envFilePath = '.env'; this.apiKeyName = 'TOGETHER_AI_API_KEY'; } /** * VĂ©rifie si la clĂ© API est configurĂ©e */ isAPIKeyConfigured() { // VĂ©rifier d'abord le fichier .env if (fs.existsSync('.env')) { const envContent = fs.readFileSync('.env', 'utf8'); const apiKeyLine = envContent.split('\n').find(line => line.trim().startsWith('TOGETHER_AI_API_KEY=') && !line.trim().startsWith('#') ); if (apiKeyLine) { const keyValue = apiKeyLine.split('=')[1]; if (keyValue && keyValue.trim() !== '' && !keyValue.includes('votre-cle')) { return true; } } } // Fallback vers les variables d'environnement if (process.env[this.apiKeyName] && process.env[this.apiKeyName].trim() !== '') { return true; } // Fallback vers le fichier .env npm if (fs.existsSync(this.envFilePath)) { const envContent = fs.readFileSync(this.envFilePath, 'utf8'); const keyLine = envContent.split('\n').find(line => line.trim().startsWith(`${this.apiKeyName}=`) && !line.trim().startsWith('#') ); if (keyLine) { const keyValue = keyLine.split('=')[1]; return keyValue && keyValue.trim() !== '' && !keyValue.includes('votre-cle-api'); } } return false; } /** * Obtient la clĂ© API */ getAPIKey() { // 1. VĂ©rifier le fichier .env local if (fs.existsSync('.env')) { const envContent = fs.readFileSync('.env', 'utf8'); const apiKeyLine = envContent.split('\n').find(line => line.trim().startsWith('TOGETHER_AI_API_KEY=') && !line.trim().startsWith('#') ); if (apiKeyLine) { const keyValue = apiKeyLine.split('=')[1]; if (keyValue && keyValue.trim() !== '' && !keyValue.includes('votre-cle')) { return keyValue.trim(); } } } // 2. Variables d'environnement this.loadDotEnv(); const apiKey = process.env[this.apiKeyName]; if (apiKey && apiKey.trim() !== '') { return apiKey.trim(); } return null; } /** * Charge le fichier .env */ loadDotEnv() { if (fs.existsSync(this.envFilePath)) { const envContent = fs.readFileSync(this.envFilePath, 'utf8'); const lines = envContent.split('\n'); for (const line of lines) { const trimmed = line.trim(); if (trimmed && !trimmed.startsWith('#')) { const [key, ...valueParts] = trimmed.split('='); const value = valueParts.join('='); if (key && value) { process.env[key.trim()] = value.trim(); } } } } } /** * Assistant ultra-rapide pour configurer la clĂ© API */ async setupAPIKeyInteractively(options = {}) { console.log(chalk.cyan('\n🧠 Configuration DeepSeek R1 - IA de derniĂšre gĂ©nĂ©ration')); console.log(chalk.white('Together.ai offre DeepSeek R1 gratuitement !\n')); // Choix du mode de configuration const { configMode } = await inquirer.prompt([ { type: 'list', name: 'configMode', message: '🔧 Comment voulez-vous configurer les clĂ©s API ?', choices: [ { name: '📁 Fichier .env local (RECOMMANDÉ - Simple et rapide)', value: 'env_file' }, { name: '🔧 Configuration npm globale (Ancienne mĂ©thode)', value: 'npm_global' } ], default: 'env_file' } ]); if (configMode === 'env_file') { return await this.setupEnvFile(); } else { return await this.setupNpmGlobal(); } } /** * Configuration via fichier .env (nouveau et recommandĂ©) */ async setupEnvFile() { console.log(chalk.cyan('\n📁 Configuration via fichier .env')); console.log(chalk.white('CrĂ©ation d\'un fichier .env local pour vos clĂ©s API\n')); const { hasAccount } = await inquirer.prompt([ { type: 'confirm', name: 'hasAccount', message: '❓ Avez-vous dĂ©jĂ  un compte Together.ai ?', default: false } ]); if (!hasAccount) { console.log(chalk.cyan('\n🚀 CrĂ©ons votre compte Together.ai (gratuit) !')); console.log(chalk.white('1. 🌐 Allez sur: https://together.ai')); console.log(chalk.white('2. 📝 Inscription gratuite en 30 secondes')); console.log(chalk.white('3. ✅ AccĂšs immĂ©diat Ă  DeepSeek R1')); const { accountCreated } = await inquirer.prompt([ { type: 'confirm', name: 'accountCreated', message: '✅ Compte créé ?', default: false } ]); if (!accountCreated) { console.log(chalk.yellow('\n⏞ Revenez quand votre compte sera créé !')); return false; } } console.log(chalk.cyan('\n🔑 RĂ©cupĂ©ration de votre clĂ© API:')); console.log(chalk.white('1. 🏠 https://api.together.ai/settings/api-keys')); console.log(chalk.white('2. 🔑 "Create new API key"')); console.log(chalk.white('3. 📝 Nom: "AI Team DeepSeek R1"')); console.log(chalk.white('4. đŸ’Ÿ Copiez la clĂ©')); const { apiKey } = await inquirer.prompt([ { type: 'password', name: 'apiKey', message: '🔐 Collez votre clĂ© API Together.ai:', validate: (input) => { if (!input || input.trim() === '') { return 'La clĂ© API est obligatoire'; } if (input.length < 20) { return 'La clĂ© API semble trop courte'; } return true; } } ]); // Demander optionnellement le token GitHub const { wantsGitHubToken } = await inquirer.prompt([ { type: 'confirm', name: 'wantsGitHubToken', message: '🔐 Voulez-vous aussi configurer votre token GitHub ? (optionnel mais recommandĂ©)', default: true } ]); let githubToken = ''; if (wantsGitHubToken) { console.log(chalk.cyan('\n🔑 Configuration GitHub Token:')); console.log(chalk.white('1. 🌐 Allez sur: https://github.com/settings/tokens')); console.log(chalk.white('2. 🔑 "Generate new token (classic)"')); console.log(chalk.white('3. 📝 Permissions: repo + workflow')); console.log(chalk.white('4. đŸ’Ÿ Copiez le token')); const tokenInput = await inquirer.prompt([ { type: 'password', name: 'token', message: '🔐 Collez votre token GitHub (optionnel):', mask: '*', validate: (input) => { if (input && input.length > 0 && input.length < 20) { return 'Le token GitHub semble trop court'; } return true; } } ]); githubToken = tokenInput.token; } // CrĂ©er le fichier .env const success = this.createEnvFile(apiKey.trim(), githubToken.trim()); if (success) { console.log(chalk.green('\n🎉 Fichier .env créé avec succĂšs !')); console.log(chalk.cyan('📁 Localisation: .env (Ă  la racine de votre projet)')); console.log(chalk.white('\n📋 Contenu configurĂ©:')); console.log(chalk.gray(' ‱ TOGETHER_AI_API_KEY (DeepSeek R1)')); if (githubToken) { console.log(chalk.gray(' ‱ GITHUB_TOKEN (Permissions GitHub)')); } console.log(chalk.yellow('\n⚠ IMPORTANT: Ajoutez .env Ă  votre .gitignore !')); console.log(chalk.white('\n💡 Commandes prĂȘtes Ă  utiliser:')); console.log(chalk.white(' ‱ ai-team check - VĂ©rifier la configuration')); console.log(chalk.white(' ‱ ai-team init - Installer les workflows')); console.log(chalk.white(' ‱ ai-team issue "titre" - CrĂ©er une issue\n')); return true; } else { console.log(chalk.red('\n❌ Erreur lors de la crĂ©ation du fichier .env')); return false; } } /** * Configuration npm globale (ancienne mĂ©thode) */ async setupNpmGlobal() { console.log(chalk.cyan('\n🔧 Configuration npm globale (ancienne mĂ©thode)')); console.log(chalk.white('Cette mĂ©thode configure dans le dossier npm\n')); const { hasAccount } = await inquirer.prompt([ { type: 'confirm', name: 'hasAccount', message: '❓ Avez-vous dĂ©jĂ  un compte Together.ai ?', default: false } ]); if (!hasAccount) { console.log(chalk.cyan('\n🚀 CrĂ©ons votre compte Together.ai (gratuit) !')); console.log(chalk.white('1. 🌐 Allez sur: https://together.ai')); console.log(chalk.white('2. 📝 Inscription gratuite en 30 secondes')); console.log(chalk.white('3. ✅ AccĂšs immĂ©diat Ă  DeepSeek R1')); const { accountCreated } = await inquirer.prompt([ { type: 'confirm', name: 'accountCreated', message: '✅ Compte créé ?', default: false } ]); if (!accountCreated) { console.log(chalk.yellow('\n⏞ Revenez quand votre compte sera créé !')); return false; } } console.log(chalk.cyan('\n🔑 RĂ©cupĂ©ration de votre clĂ© API:')); console.log(chalk.white('1. 🏠 https://api.together.ai/settings/api-keys')); console.log(chalk.white('2. 🔑 "Create new API key"')); console.log(chalk.white('3. 📝 Nom: "AI Team DeepSeek R1"')); console.log(chalk.white('4. đŸ’Ÿ Copiez la clĂ©')); const { apiKey } = await inquirer.prompt([ { type: 'password', name: 'apiKey', message: '🔐 Collez votre clĂ© API Together.ai:', validate: (input) => { if (!input || input.trim() === '') { return 'La clĂ© API est obligatoire'; } if (input.length < 20) { return 'La clĂ© API semble trop courte'; } return true; } } ]); const success = this.saveAPIKey(apiKey.trim()); if (success) { console.log(chalk.green('\n✅ DeepSeek R1 configurĂ© avec succĂšs !')); console.log(chalk.cyan('🧠 Vous avez maintenant accĂšs Ă  l\'IA la plus avancĂ©e !')); console.log(chalk.white('\n💡 Commandes ultra-rapides:')); console.log(chalk.white(' ‱ ai-team issue "titre" - CrĂ©ation automatique')); console.log(chalk.white(' ‱ ai-team create "desc" - Mode rapide\n')); return true; } else { console.log(chalk.red('\n❌ Erreur lors de la sauvegarde')); return false; } } /** * CrĂ©e un fichier .env local avec les clĂ©s API */ createEnvFile(apiKey, githubToken = '') { try { let envContent = `# AI Team Orchestrator v2.2.0 - Configuration DeepSeek R1 # 🧠 ClĂ©s API pour l'IA la plus avancĂ©e # Together.ai API Key pour DeepSeek R1 (OBLIGATOIRE) TOGETHER_AI_API_KEY=${apiKey} `; if (githubToken && githubToken.length > 0) { envContent += `# GitHub Token pour les permissions Ă©tendues (OPTIONNEL) # Permissions requises: repo + workflow GITHUB_TOKEN=${githubToken} `; } else { envContent += `# GitHub Token pour les permissions Ă©tendues (OPTIONNEL) # DĂ©commentez et ajoutez votre token si nĂ©cessaire # GITHUB_TOKEN=ghp_votre_GITHUB_TOKEN `; } envContent += `# 💡 Instructions: # 1. Ajoutez .env Ă  votre .gitignore pour la sĂ©curitĂ© # 2. Utilisez 'ai-team check' pour vĂ©rifier la configuration # 3. Utilisez 'ai-team init' pour installer les workflows # 4. CrĂ©ez des issues avec 'ai-team issue "titre" --type frontend' # 🚀 AI Team Orchestrator - PropulsĂ© par DeepSeek R1`; fs.writeFileSync('.env', envContent); // Ajouter .env au .gitignore s'il existe this.addToGitignore(); return true; } catch (error) { console.error('Erreur lors de la crĂ©ation du fichier .env:', error.message); return false; } } /** * Ajoute .env au .gitignore si le fichier existe */ addToGitignore() { try { if (fs.existsSync('.gitignore')) { const gitignoreContent = fs.readFileSync('.gitignore', 'utf8'); if (!gitignoreContent.includes('.env')) { fs.appendFileSync('.gitignore', '\n# AI Team Orchestrator - Variables d\'environnement\n.env\n'); console.log(chalk.green('✅ .env ajoutĂ© au .gitignore')); } } else { // CrĂ©er un .gitignore si il n'existe pas fs.writeFileSync('.gitignore', '# AI Team Orchestrator - Variables d\'environnement\n.env\n'); console.log(chalk.green('✅ .gitignore créé avec .env')); } } catch (error) { console.log(chalk.yellow('⚠ Impossible de modifier .gitignore automatiquement')); console.log(chalk.white('💡 Ajoutez manuellement .env Ă  votre .gitignore')); } } /** * Sauvegarde rapide de la clĂ© API */ saveAPIKey(apiKey) { try { if (fs.existsSync(this.envFilePath)) { const currentContent = fs.readFileSync(this.envFilePath, 'utf8'); const lines = currentContent.split('\n'); let found = false; const newLines = lines.map(line => { if (line.trim().startsWith(`${this.apiKeyName}=`)) { found = true; return `${this.apiKeyName}=${apiKey}`; } return line; }); if (!found) { newLines.push(`${this.apiKeyName}=${apiKey}`); } fs.writeFileSync(this.envFilePath, newLines.join('\n')); } else { const envContent = `# AI Team Orchestrator v2.0 - DeepSeek R1 ${this.apiKeyName}=${apiKey} `; fs.writeFileSync(this.envFilePath, envContent); } // Mettre Ă  jour process.env immĂ©diatement process.env[this.apiKeyName] = apiKey; return true; } catch (error) { console.error('Erreur lors de la sauvegarde:', error.message); return false; } } /** * Test de la clĂ© API avec DeepSeek R1 */ async testAPIKey(apiKey) { try { const response = await fetch('https://api.together.xyz/v1/models', { headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' } }); return response.ok; } catch (error) { return false; } } }