UNPKG

eslint-config-ai-swe

Version:

ESLint configuration optimized for AI Agents SWE with TypeScript and multi-framework support.

324 lines (281 loc) 11.4 kB
#!/usr/bin/env node import { Command } from 'commander'; import fs from 'fs'; import path from 'path'; import { detectFramework, suggestConfig } from './utils/framework-detector.js'; import { generateAgentsMd } from './utils/agents-md-generator.js'; import { installFrameworkDependencies, getMissingDependencies } from './utils/dependency-installer.js'; const program = new Command(); program .name('eslint-config-ai-swe') .description('CLI pour configurer et gérer le linter optimisé pour les AI Agents SWE.'); program .command('setup') .description('Génère un fichier eslint.config.js à la racine du projet.') .option('-f, --force', 'Écrase le fichier existant') .option('--ide', 'Configure également les paramètres IDE pour VS Code') .option('--agents', 'Génère également le fichier AGENTS.md pour les agents IA') .option('--install-deps', 'Installe automatiquement les dépendances optionnelles requises') .option('--dry-run', 'Simule l\'installation sans rien installer') .action(async (options) => { console.log('🚀 Configuration de eslint-config-ai-swe...'); const { framework } = detectFramework(); const suggestedConfigs = suggestConfig(framework); console.log(`📋 Framework détecté: ${framework}`); console.log(`📦 Configurations suggérées: ${suggestedConfigs.join(', ')}`); // Check for missing dependencies const missingDeps = getMissingDependencies(framework); if (missingDeps.length > 0) { console.log(`⚠️ Dépendances manquantes: ${missingDeps.join(', ')}`); if (options.installDeps || options.dryRun) { console.log('🔧 Installation des dépendances...'); const installSuccess = await installFrameworkDependencies(framework, { dryRun: options.dryRun, silent: false, }); if (!installSuccess && !options.dryRun) { console.warn('⚠️ Certaines dépendances n\'ont pas pu être installées automatiquement.'); console.log('💡 Vous pouvez les installer manuellement avec:'); console.log(` npm install ${missingDeps.join(' ')}`); } } else { console.log('💡 Installez-les avec: npm install --save-dev eslint-config-ai-swe'); console.log('💡 Ou utilisez --install-deps pour les installer automatiquement'); } } else { console.log('✅ Toutes les dépendances sont déjà installées'); } const configContent = `// eslint.config.js // Auto-généré par eslint-config-ai-swe // Framework détecté: ${framework} import aiSwe from 'eslint-config-ai-swe'; export default aiSwe({ ${suggestedConfigs.map(config => `${config}: true,`).join('\n ')} // Ajoutez ici vos configurations spécifiques supplémentaires }); `; const configPath = path.join(process.cwd(), 'eslint.config.js'); if (fs.existsSync(configPath) && !options.force) { console.warn('⚠️ Un fichier eslint.config.js existe déjà. Utilisez --force pour l\'écraser.'); return; } fs.writeFileSync(configPath, configContent); console.log('✅ Fichier eslint.config.js créé avec succès !'); // Configuration IDE si demandée if (options.ide) { setupIdeConfiguration(); } // Génération AGENTS.md si demandée if (options.agents) { console.log('📝 Génération du fichier AGENTS.md...'); const agentsMdContent = generateAgentsMd(suggestedConfigs); const agentsMdPath = path.join(process.cwd(), 'AGENTS.md'); if (fs.existsSync(agentsMdPath) && !options.force) { console.warn('⚠️ Un fichier AGENTS.md existe déjà. Utilisez --force pour l\'écraser.'); } else { fs.writeFileSync(agentsMdPath, agentsMdContent); console.log('✅ AGENTS.md créé avec des règles de guidage pour l\'IA !'); } } // Instructions supplémentaires selon le framework if (framework === 'react') { console.log('💡 Pour React, assurez-vous d\'avoir installé: eslint-plugin-react eslint-plugin-react-hooks'); } else if (framework === 'vue') { console.log('💡 Pour Vue, assurez-vous d\'avoir installé: eslint-plugin-vue'); } console.log("🎯 Exécutez 'npx eslint .' pour tester votre configuration !"); }); program .command('detect') .description('Détecte le framework et les dépendances du projet.') .action(() => { const { framework, dependencies } = detectFramework(); const suggestedConfigs = suggestConfig(framework); console.log('🔍 Analyse du projet:'); console.log(` Framework: ${framework}`); console.log(` Configurations suggérées: ${suggestedConfigs.join(', ')}`); console.log(` Dépendances détectées: ${dependencies.length}`); dependencies.forEach(dep => console.log(` - ${dep}`)); }); function createInitConfig(framework) { return `// eslint.config.js // Auto-généré par eslint-config-ai-swe // Framework détecté: ${framework} import aiSwe from 'eslint-config-ai-swe'; export default aiSwe({ typescript: true, ai: true, ${framework === 'react' ? 'react: true,' : ''} ${framework === 'vue' ? 'vue: true,' : ''} ${framework === 'node' ? 'node: true,' : ''} // Personnalisez vos règles ici }); `; } function createEslintIgnore() { return `# Auto-généré par eslint-config-ai-swe node_modules/ dist/ build/ coverage/ *.min.js *.test.js *.spec.js `; } program .command('init') .description('Initialise une configuration complète pour le projet.') .option('-f, --force', 'Écrase les fichiers existants') .option('--ide', 'Configure également les paramètres IDE pour VS Code') .option('--agents', 'Génère également le fichier AGENTS.md pour les agents IA') .option('--install-deps', 'Installe automatiquement les dépendances optionnelles requises') .option('--dry-run', 'Simule l\'installation sans rien installer') .action(async (options) => { console.log('🚀 Initialisation complète de eslint-config-ai-swe...'); const { framework } = detectFramework(); // const suggestedConfigs = suggestConfig(framework); // Check for missing dependencies const missingDeps = getMissingDependencies(framework); if (missingDeps.length > 0) { console.log(`⚠️ Dépendances manquantes: ${missingDeps.join(', ')}`); if (options.installDeps || options.dryRun) { console.log('🔧 Installation des dépendances...'); const installSuccess = await installFrameworkDependencies(framework, { dryRun: options.dryRun, silent: false, }); if (!installSuccess && !options.dryRun) { console.warn('⚠️ Certaines dépendances n\'ont pas pu être installées automatiquement.'); console.log('💡 Vous pouvez les installer manuellement avec:'); console.log(` npm install ${missingDeps.join(' ')}`); } } else { console.log('💡 Installez-les avec: npm install --save-dev eslint-config-ai-swe'); console.log('💡 Ou utilisez --install-deps pour les installer automatiquement'); } } else { console.log('✅ Toutes les dépendances sont déjà installées'); } // Créer eslint.config.js const configContent = createInitConfig(framework); const configPath = path.join(process.cwd(), 'eslint.config.js'); if (fs.existsSync(configPath) && !options.force) { console.warn('⚠️ eslint.config.js existe déjà. Utilisez --force pour l\'écraser.'); } else { fs.writeFileSync(configPath, configContent); console.log('✅ eslint.config.js créé'); } // Créer .eslintignore const ignoreContent = createEslintIgnore(); const ignorePath = path.join(process.cwd(), '.eslintignore'); if (fs.existsSync(ignorePath) && !options.force) { console.warn('⚠️ .eslintignore existe déjà. Utilisez --force pour l\'écraser.'); } else { fs.writeFileSync(ignorePath, ignoreContent); console.log('✅ .eslintignore créé'); } // Configuration IDE si demandée if (options.ide) { setupIdeConfiguration(); } // Génération AGENTS.md si demandée if (options.agents) { console.log('📝 Génération du fichier AGENTS.md...'); const agentsConfigs = suggestConfig(framework); const agentsMdContent = generateAgentsMd(agentsConfigs); const agentsMdPath = path.join(process.cwd(), 'AGENTS.md'); if (fs.existsSync(agentsMdPath) && !options.force) { console.warn('⚠️ Un fichier AGENTS.md existe déjà. Utilisez --force pour l\'écraser.'); } else { fs.writeFileSync(agentsMdPath, agentsMdContent); console.log('✅ AGENTS.md créé avec des règles de guidage pour l\'IA !'); } } console.log('🎯 Configuration terminée ! Exécutez "npx eslint ." pour tester.'); }); // Configuration IDE pour VS Code function setupIdeConfiguration() { const vscodeDir = path.join(process.cwd(), '.vscode'); const settingsPath = path.join(vscodeDir, 'settings.json'); // Créer le dossier .vscode s'il n'existe pas if (!fs.existsSync(vscodeDir)) { fs.mkdirSync(vscodeDir, { recursive: true }); } const settingsContent = getIdeSettingsContent(); if (fs.existsSync(settingsPath)) { console.log('⚠️ .vscode/settings.json existe déjà. Configuration IDE ignorée.'); console.log('💡 Utilisez --force pour écraser la configuration existante.'); } else { fs.writeFileSync(settingsPath, settingsContent); console.log('✅ .vscode/settings.json créé avec configuration ESLint'); console.log('🎯 Installez l\'extension ESLint pour VS Code: https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint'); } } function getIdeSettingsContent() { return `{ "editor.codeActionsOnSave": { "source.fixAll.eslint": "explicit" }, "editor.formatOnSave": false, "editor.defaultFormatter": "dbaeumer.vscode-eslint", "eslint.validate": [ "javascript", "javascriptreact", "typescript", "typescriptreact", "vue", "svelte", "astro", "json", "jsonc", "yaml", "toml", "markdown", "html" ], "eslint.packageManager": "npm", "eslint.run": "onType", "eslint.workingDirectories": [ { "mode": "auto" } ], "typescript.preferences.preferTypeOnlyAutoImports": true, "typescript.suggest.autoImports": true, "editor.quickSuggestions": { "strings": true, "comments": true, "other": true }, "editor.suggest.showStatusBar": true, "editor.tabSize": 2, "editor.insertSpaces": true, "files.associations": { "*.config.js": "javascript", "*.config.ts": "typescript" }, "search.exclude": { "**/node_modules": true, "**/dist": true, "**/build": true, "**/.git": true, "**/.cache": true }, "files.watcherExclude": { "**/node_modules/**": true, "**/dist/**": true, "**/build/**": true } }`; } // Commande interactive pour la configuration IDE program .command('ide') .description('Configure les paramètres IDE pour VS Code.') .option('-f, --force', 'Écrase le fichier existant') .action((_options) => { console.log('💻 Configuration IDE pour VS Code...'); setupIdeConfiguration(); }); program.parse(process.argv);