seo-generator-server/tools/apply-claude-exports.js
StillHammer 64fb319e65 refactor: Synchronisation complète du codebase - Application de tous les patches
Application systématique et méthodique de tous les patches historiques.

##  FICHIERS SYNCHRONISÉS (19 fichiers)

### Core & Infrastructure:
- server.js (14 patches) - Lazy loading ModeManager, SIGINT hard kill, timing logs
- ModeManager.js (4 patches) - Instrumentation complète avec timing détaillé

### Pipeline System:
- PipelineDefinition.js (6 patches) - Source unique getLLMProvidersList()
- pipeline-builder.js (8 patches) - Standardisation LLM providers
- pipeline-runner.js (6 patches) - Affichage résultats structurés + debug console
- pipeline-builder.html (2 patches) - Fallback providers synchronisés
- pipeline-runner.html (3 patches) - UI améliorée résultats

### Enhancement Layers:
- TechnicalLayer.js (1 patch) - defaultLLM: 'gpt-4o-mini'
- StyleLayer.js (1 patch) - Type safety vocabulairePref
- PatternBreakingCore.js (1 patch) - Mapping modifications
- PatternBreakingLayers.js (1 patch) - LLM standardisé

### Validators & Tests:
- QualityMetrics.js (1 patch) - callLLM('gpt-4o-mini')
- PersonalityValidator.js (1 patch) - Provider gpt-4o-mini
- AntiDetectionValidator.js - Synchronisé

### Documentation:
- TODO.md (1 patch) - Section LiteLLM pour tracking coûts
- CLAUDE.md - Documentation à jour

### Tools:
- tools/analyze-skipped-exports.js (nouveau)
- tools/apply-claude-exports.js (nouveau)
- tools/apply-claude-exports-fuzzy.js (nouveau)

## 🎯 Changements principaux:
-  Standardisation LLM providers (openai → gpt-4o-mini, claude → claude-sonnet-4-5)
-  Lazy loading optimisé (ModeManager chargé à la demande)
-  SIGINT immediate exit (pas de graceful shutdown)
-  Type safety renforcé (conversions string explicites)
-  Instrumentation timing complète
-  Debug logging amélioré (console.log résultats pipeline)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-12 20:36:17 +08:00

147 lines
4.4 KiB
JavaScript

#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
const EXPORTS_DIR = path.join(__dirname, '../claude-exports-last-3-days');
/**
* Parse un fichier de session pour extraire les tool uses
*/
function parseSessionFile(filePath) {
const content = fs.readFileSync(filePath, 'utf-8');
const tools = [];
// Chercher tous les blocs JSON qui contiennent des tool uses
const jsonBlockRegex = /\[\s*\{[\s\S]*?"type":\s*"tool_use"[\s\S]*?\}\s*\]/g;
const matches = content.match(jsonBlockRegex);
if (!matches) return tools;
for (const match of matches) {
try {
const parsed = JSON.parse(match);
for (const item of parsed) {
if (item.type === 'tool_use' && (item.name === 'Edit' || item.name === 'Write')) {
tools.push({
name: item.name,
input: item.input
});
}
}
} catch (e) {
// Skip invalid JSON
}
}
return tools;
}
/**
* Applique un Edit sur un fichier
*/
function applyEdit(filePath, oldString, newString) {
try {
if (!fs.existsSync(filePath)) {
console.log(`⏭️ SKIP Edit - Fichier n'existe pas: ${filePath}`);
return false;
}
const content = fs.readFileSync(filePath, 'utf-8');
if (!content.includes(oldString)) {
console.log(`⏭️ SKIP Edit - old_string non trouvée dans: ${filePath}`);
return false;
}
const newContent = content.replace(oldString, newString);
fs.writeFileSync(filePath, newContent, 'utf-8');
console.log(`✅ EDIT appliqué: ${filePath}`);
return true;
} catch (e) {
console.log(`❌ ERREUR Edit sur ${filePath}: ${e.message}`);
return false;
}
}
/**
* Applique un Write sur un fichier
*/
function applyWrite(filePath, content) {
try {
if (fs.existsSync(filePath)) {
console.log(`⏭️ SKIP Write - Fichier existe déjà: ${filePath}`);
return false;
}
// Créer les dossiers parents si nécessaire
const dir = path.dirname(filePath);
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
fs.writeFileSync(filePath, content, 'utf-8');
console.log(`✅ WRITE appliqué: ${filePath}`);
return true;
} catch (e) {
console.log(`❌ ERREUR Write sur ${filePath}: ${e.message}`);
return false;
}
}
/**
* Main
*/
function main() {
console.log('🔄 Application des exports Claude...\n');
// Lire tous les fichiers de session
const sessionFiles = fs.readdirSync(EXPORTS_DIR)
.filter(f => f.endsWith('-session.md'))
.sort((a, b) => {
const numA = parseInt(a.split('-')[0]);
const numB = parseInt(b.split('-')[0]);
return numB - numA; // Ordre inverse: 15 -> 1
});
console.log(`📁 ${sessionFiles.length} fichiers de session trouvés`);
console.log(`📋 Ordre de traitement: ${sessionFiles.join(', ')}\n`);
let totalEdits = 0;
let totalWrites = 0;
let successEdits = 0;
let successWrites = 0;
for (const sessionFile of sessionFiles) {
const filePath = path.join(EXPORTS_DIR, sessionFile);
console.log(`\n📄 Traitement de: ${sessionFile}`);
const tools = parseSessionFile(filePath);
console.log(` ${tools.length} tool use(s) trouvé(s)`);
for (const tool of tools) {
if (tool.name === 'Edit') {
totalEdits++;
const { file_path, old_string, new_string } = tool.input;
if (applyEdit(file_path, old_string, new_string)) {
successEdits++;
}
} else if (tool.name === 'Write') {
totalWrites++;
const { file_path, content } = tool.input;
if (applyWrite(file_path, content)) {
successWrites++;
}
}
}
}
console.log('\n\n📊 RÉSUMÉ:');
console.log(` Edit: ${successEdits}/${totalEdits} appliqués`);
console.log(` Write: ${successWrites}/${totalWrites} appliqués`);
console.log(` Total: ${successEdits + successWrites}/${totalEdits + totalWrites} opérations réussies`);
console.log('\n✨ Terminé!');
}
main();