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>
213 lines
8.0 KiB
JavaScript
213 lines
8.0 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;
|
|
}
|
|
|
|
/**
|
|
* Analyse pourquoi un Edit a été skippé
|
|
*/
|
|
function analyzeSkippedEdit(filePath, oldString) {
|
|
if (!fs.existsSync(filePath)) {
|
|
return { reason: 'FILE_NOT_EXIST', details: 'Fichier n\'existe pas' };
|
|
}
|
|
|
|
const content = fs.readFileSync(filePath, 'utf-8');
|
|
|
|
if (!content.includes(oldString)) {
|
|
// Vérifier si une partie de old_string existe
|
|
const oldLines = oldString.split('\n').filter(l => l.trim());
|
|
const matchingLines = oldLines.filter(line => content.includes(line.trim()));
|
|
|
|
if (matchingLines.length > 0) {
|
|
return {
|
|
reason: 'PARTIAL_MATCH',
|
|
details: `${matchingLines.length}/${oldLines.length} lignes trouvées - code probablement modifié`
|
|
};
|
|
} else {
|
|
return {
|
|
reason: 'NO_MATCH',
|
|
details: 'Code complètement différent - changement déjà appliqué ou code refactorisé'
|
|
};
|
|
}
|
|
}
|
|
|
|
return { reason: 'OK', details: 'Devrait fonctionner' };
|
|
}
|
|
|
|
/**
|
|
* Main
|
|
*/
|
|
function main() {
|
|
console.log('🔍 Analyse des exports Claude skippés...\n');
|
|
|
|
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;
|
|
});
|
|
|
|
const skippedAnalysis = {
|
|
FILE_NOT_EXIST: [],
|
|
PARTIAL_MATCH: [],
|
|
NO_MATCH: [],
|
|
FILE_EXISTS: [] // Pour les Write
|
|
};
|
|
|
|
let totalSkipped = 0;
|
|
|
|
for (const sessionFile of sessionFiles) {
|
|
const filePath = path.join(EXPORTS_DIR, sessionFile);
|
|
const tools = parseSessionFile(filePath);
|
|
|
|
for (const tool of tools) {
|
|
if (tool.name === 'Edit') {
|
|
const { file_path, old_string } = tool.input;
|
|
|
|
if (!fs.existsSync(file_path)) {
|
|
skippedAnalysis.FILE_NOT_EXIST.push({
|
|
session: sessionFile,
|
|
file: file_path,
|
|
preview: old_string.substring(0, 80)
|
|
});
|
|
totalSkipped++;
|
|
} else {
|
|
const content = fs.readFileSync(file_path, 'utf-8');
|
|
if (!content.includes(old_string)) {
|
|
const analysis = analyzeSkippedEdit(file_path, old_string);
|
|
|
|
if (analysis.reason === 'PARTIAL_MATCH') {
|
|
skippedAnalysis.PARTIAL_MATCH.push({
|
|
session: sessionFile,
|
|
file: file_path,
|
|
details: analysis.details,
|
|
preview: old_string.substring(0, 80)
|
|
});
|
|
} else {
|
|
skippedAnalysis.NO_MATCH.push({
|
|
session: sessionFile,
|
|
file: file_path,
|
|
preview: old_string.substring(0, 80)
|
|
});
|
|
}
|
|
totalSkipped++;
|
|
}
|
|
}
|
|
} else if (tool.name === 'Write') {
|
|
const { file_path } = tool.input;
|
|
if (fs.existsSync(file_path)) {
|
|
skippedAnalysis.FILE_EXISTS.push({
|
|
session: sessionFile,
|
|
file: file_path
|
|
});
|
|
totalSkipped++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
console.log(`📊 Total skippés: ${totalSkipped}\n`);
|
|
|
|
console.log('═══════════════════════════════════════════════════════');
|
|
console.log('🚫 FICHIERS N\'EXISTANT PAS (Edit)');
|
|
console.log(` ${skippedAnalysis.FILE_NOT_EXIST.length} cas\n`);
|
|
const fileNotExistByFile = {};
|
|
for (const item of skippedAnalysis.FILE_NOT_EXIST) {
|
|
if (!fileNotExistByFile[item.file]) {
|
|
fileNotExistByFile[item.file] = 0;
|
|
}
|
|
fileNotExistByFile[item.file]++;
|
|
}
|
|
Object.entries(fileNotExistByFile)
|
|
.sort((a, b) => b[1] - a[1])
|
|
.slice(0, 10)
|
|
.forEach(([file, count]) => {
|
|
console.log(` ${count}x - ${file}`);
|
|
});
|
|
|
|
console.log('\n═══════════════════════════════════════════════════════');
|
|
console.log('⚠️ CORRESPONDANCE PARTIELLE (Edit - code probablement modifié)');
|
|
console.log(` ${skippedAnalysis.PARTIAL_MATCH.length} cas\n`);
|
|
const partialByFile = {};
|
|
for (const item of skippedAnalysis.PARTIAL_MATCH) {
|
|
if (!partialByFile[item.file]) {
|
|
partialByFile[item.file] = 0;
|
|
}
|
|
partialByFile[item.file]++;
|
|
}
|
|
Object.entries(partialByFile)
|
|
.sort((a, b) => b[1] - a[1])
|
|
.slice(0, 10)
|
|
.forEach(([file, count]) => {
|
|
console.log(` ${count}x - ${file}`);
|
|
});
|
|
|
|
console.log('\n═══════════════════════════════════════════════════════');
|
|
console.log('❌ AUCUNE CORRESPONDANCE (Edit - changement déjà appliqué)');
|
|
console.log(` ${skippedAnalysis.NO_MATCH.length} cas\n`);
|
|
const noMatchByFile = {};
|
|
for (const item of skippedAnalysis.NO_MATCH) {
|
|
if (!noMatchByFile[item.file]) {
|
|
noMatchByFile[item.file] = 0;
|
|
}
|
|
noMatchByFile[item.file]++;
|
|
}
|
|
Object.entries(noMatchByFile)
|
|
.sort((a, b) => b[1] - a[1])
|
|
.slice(0, 10)
|
|
.forEach(([file, count]) => {
|
|
console.log(` ${count}x - ${file}`);
|
|
});
|
|
|
|
console.log('\n═══════════════════════════════════════════════════════');
|
|
console.log('✅ FICHIERS DÉJÀ EXISTANTS (Write - comportement normal)');
|
|
console.log(` ${skippedAnalysis.FILE_EXISTS.length} cas\n`);
|
|
skippedAnalysis.FILE_EXISTS.forEach(item => {
|
|
console.log(` ${item.session} → ${item.file}`);
|
|
});
|
|
|
|
console.log('\n═══════════════════════════════════════════════════════');
|
|
console.log('💡 CONCLUSION:\n');
|
|
console.log(` ✅ Write skippés: ${skippedAnalysis.FILE_EXISTS.length} (NORMAL - ne pas écraser)`);
|
|
console.log(` ❌ Edit skippés (NO_MATCH): ${skippedAnalysis.NO_MATCH.length} (changements déjà appliqués)`);
|
|
console.log(` ⚠️ Edit skippés (PARTIAL_MATCH): ${skippedAnalysis.PARTIAL_MATCH.length} (code modifié depuis)`);
|
|
console.log(` 🚫 Edit skippés (FILE_NOT_EXIST): ${skippedAnalysis.FILE_NOT_EXIST.length} (fichiers supprimés?)\n`);
|
|
}
|
|
|
|
main();
|