const fs = require('fs'); const content = fs.readFileSync('temp/rich-outline-fail_57_1779022210168.txt', 'utf-8'); const marker = '========== AI εŽŸε§‹ε“εΊ” '; const markerIdx = content.indexOf(marker); const headerEndIdx = content.indexOf(' ==========', markerIdx); const aiStart = content.indexOf('\n', headerEndIdx) + 1; const aiEnd = content.indexOf('\n\n', aiStart); const aiResponse = content.substring(aiStart, aiEnd); console.log('AI response length:', aiResponse.length); // Extract mainTheme const mainThemeMatch = aiResponse.match(/"mainTheme"\s*:\s*"([^"]+)"/); console.log('mainTheme:', mainThemeMatch ? mainThemeMatch[1].substring(0, 50) : 'none'); // Extract structureLogic const structureLogicMatch = aiResponse.match(/"structureLogic"\s*:\s*"([^"]+)"/); console.log('structureLogic:', structureLogicMatch ? structureLogicMatch[1].substring(0, 50) : 'none'); // Find chapters array const chaptersArrayStart = aiResponse.indexOf('"chapters":['); console.log('\nChapters array starts at:', chaptersArrayStart); if (chaptersArrayStart === -1) { console.log('No chapters array found!'); process.exit(1); } // Find array end by counting brackets let bracketDepth = 0; let inString = false; let escapeNext = false; let arrayEnd = -1; for (let i = chaptersArrayStart + 12; i < aiResponse.length; i++) { const ch = aiResponse[i]; if (escapeNext) { escapeNext = false; continue; } if (ch === '\\') { escapeNext = true; continue; } if (ch === '"') { inString = !inString; continue; } if (inString) continue; if (ch === '[') bracketDepth++; else if (ch === ']') { bracketDepth--; if (bracketDepth === 0) { arrayEnd = i; break; } } } console.log('Chapters array ends at:', arrayEnd); if (arrayEnd === -1) { console.log('Could not find array end!'); process.exit(1); } const arrayContent = aiResponse.substring(chaptersArrayStart + 12, arrayEnd); console.log('Array content length:', arrayContent.length); console.log('Array content start:', JSON.stringify(arrayContent.substring(0, 100))); console.log('Array content end:', JSON.stringify(arrayContent.substring(arrayContent.length - 100))); // Fix missing quotes function fixMissingQuotes(jsonStr) { return jsonStr .replace(/\{number":/g, '{"number":') .replace(/\{title":/g, '{"title":') .replace(/\{summary":/g, '{"summary":') .replace(/\{opening":/g, '{"opening":') .replace(/\{structure":/g, '{"structure":') .replace(/\{mustCover":/g, '{"mustCover":') .replace(/\{mustNotRepeat":/g, '{"mustNotRepeat":') .replace(/\{toneAdjustment":/g, '{"toneAdjustment":') .replace(/\{keyTakeaway":/g, '{"keyTakeaway":') .replace(/\{keyPoints":/g, '{"keyPoints":') .replace(/\{estimatedWords":/g, '{"estimatedWords":') .replace(/\{writingInstructions":/g, '{"writingInstructions":') .replace(/\{number:/g, '{"number":') .replace(/\{title:/g, '{"title":') .replace(/\{summary:/g, '{"summary":') .replace(/\{opening:/g, '{"opening":') .replace(/\{structure:/g, '{"structure":') .replace(/\{mustCover:/g, '{"mustCover":') .replace(/\{mustNotRepeat:/g, '{"mustNotRepeat":') .replace(/\{toneAdjustment:/g, '{"toneAdjustment":') .replace(/\{keyTakeaway:/g, '{"keyTakeaway":') .replace(/\{keyPoints:/g, '{"keyPoints":') .replace(/\{estimatedWords:/g, '{"estimatedWords":') .replace(/\{writingInstructions:/g, '{"writingInstructions":'); } const fixedContent = fixMissingQuotes(arrayContent); console.log('\nFixed content start:', JSON.stringify(fixedContent.substring(0, 100))); // Try to parse try { const chapters = JSON.parse('[' + fixedContent + ']'); console.log('Parsed SUCCESS, chapters:', chapters.length); } catch(e) { console.log('Parse FAILED:', e.message.substring(0, 80)); // Try regex extraction const chapterMatches = fixedContent.match(/\{[^}]+\}/g) || []; console.log('Found', chapterMatches.length, 'chapter objects by regex'); let validChapters = 0; for (const chStr of chapterMatches) { try { const ch = JSON.parse(chStr); if (ch && ch.title && ch.number) { validChapters++; console.log(' Valid chapter:', ch.number, '-', ch.title.substring(0, 40)); } } catch(e) { // Skip } } console.log('Total valid chapters:', validChapters); }