const fs = require('fs'); const content = fs.readFileSync('temp/rich-outline-fail_57_1779015509994.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); // The issue: we have more opens than closes, meaning JSON is truncated // But the actual character at position 1624 looks correct: {"number":3 // Let me check if maybe there's a truncation recovery strategy that could work // We need to find where the valid JSON ends and try to make sense of it // Let me check if the response actually contains a valid prefix we can use // by scanning for valid property structures // First, let's see if there's any position where we have a COMPLETELY valid prefix let validUpTo = 0; for (let i = 1; i <= aiResponse.length; i++) { try { const sub = aiResponse.substring(0, i); JSON.parse(sub); validUpTo = i; } catch(e) { // continue } } console.log('Longest valid prefix length:', validUpTo); console.log('Valid prefix ends with:', JSON.stringify(aiResponse.substring(validUpTo - 30, validUpTo))); console.log('Valid prefix length vs total:', validUpTo, '/', aiResponse.length, '=', Math.round(validUpTo/aiResponse.length*100) + '%'); // If we have a long enough valid prefix, we might be able to extract chapters from it if (validUpTo > 1000) { console.log('\n=== Valid prefix analysis ==='); const prefix = aiResponse.substring(0, validUpTo); try { const data = JSON.parse(prefix); if (data.mainTheme) console.log('mainTheme found:', data.mainTheme.substring(0, 50)); if (data.chapters) console.log('chapters count in prefix:', data.chapters.length); } catch(e) { console.log('Parse failed:', e.message); } } // Now let me try a different approach: count closing braces needed to close the JSON // and try appending them to see if we can make it parse console.log('\n=== Trying to complete the truncated JSON ==='); // We have 39 more opens than closes, so we need 39 closing braces // Let's try to complete the JSON by finding where each unclosed brace should close // But actually, maybe the better approach is to find where chapters end // and just try to extract what we can // Let me try yet another approach: find all complete "chapters": [...] patterns const chaptersRegex = /"chapters"\s*:\s*\[([\s\S]*?)\]\s*\}/g; let match; let foundChapters = []; while ((match = chaptersRegex.exec(aiResponse)) !== null) { const inner = match[1]; console.log('Found chapters array at position', match.index, 'length', inner.length); // Try to parse the chapters array try { const arr = JSON.parse('[' + inner + ']'); if (Array.isArray(arr) && arr.length > 0) { console.log(' Parsed successfully!', arr.length, 'chapters'); foundChapters.push(...arr); } } catch(e) { // Try to extract chapter numbers const numMatches = inner.match(/"number":(\d+)/g); console.log(' Chapter numbers found:', numMatches ? numMatches.length : 0); } } console.log('\nTotal chapters found in arrays:', foundChapters.length);