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); // Find chapters array const chaptersArrayStart = aiResponse.indexOf('"chapters":['); console.log('Chapters array starts at:', chaptersArrayStart); if (chaptersArrayStart === -1) { console.log('No chapters array found!'); process.exit(1); } // Proper bracket counting that respects strings function findArrayEnd(jsonStr, startIdx) { let bracketDepth = 0; let inString = false; let escapeNext = false; for (let i = startIdx; i < jsonStr.length; i++) { const ch = jsonStr[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) return i; } } return -1; } const arrayEnd = findArrayEnd(aiResponse, chaptersArrayStart + 12); console.log('Chapters array ends at:', arrayEnd); if (arrayEnd === -1) { console.log('Could not find array end with proper string handling!'); 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, 150))); 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); // Try to parse the whole array try { const chapters = JSON.parse('[' + fixedContent + ']'); console.log('Parsed SUCCESS, chapters:', chapters.length); chapters.slice(0, 5).forEach((ch, i) => { console.log(' Chapter', i+1, ':', ch.title ? ch.title.substring(0, 40) : 'NO TITLE', 'number:', ch.number); }); } catch(e) { console.log('Array parse FAILED:', e.message.substring(0, 100)); // Try extracting chapter by chapter console.log('\n=== Trying chapter-by-chapter extraction ==='); // Use a regex to find all chapter objects const chapterRegex = /\{"number":\s*(\d+)[^}]*\}/g; let match; let validChapters = []; while ((match = chapterRegex.exec(fixedContent)) !== null) { try { const chapter = JSON.parse(match[0]); if (chapter && chapter.title) { validChapters.push(chapter); console.log(' Found chapter', chapter.number, ':', chapter.title.substring(0, 40)); } } catch(e) { // Try to extract just the number and title const numMatch = match[0].match(/"number":\s*(\d+)/); const titleMatch = match[0].match(/"title":\s*"([^"]+)"/); if (numMatch && titleMatch) { validChapters.push({ number: parseInt(numMatch[1]), title: titleMatch[1] }); console.log(' Found partial chapter', numMatch[1], ':', titleMatch[1].substring(0, 40)); } } } console.log('\nTotal valid chapters found:', validChapters.length); }