const fs = require('fs'); const path = require('path'); const INDEX = path.join(__dirname, '../index.standalone.html'); // 1. New renderHeatmap that reads real-fit data const newRenderHeatmap = `function renderHeatmap() { const esc = str => (str || '').replace(/[&<>"']/g, m => ({'&':'&','<':'<','>':'>','"':'"',"'":'''}[m])); const dd = window.dashboardData; // Merge real-fit if loaded const rf = window.realFitData || {}; const realAgents = rf.agents || {}; if (!dd || !dd.agents) { document.getElementById('hmTable').innerHTML = '⚠️ No data. Run analysis.'; return; } // Build model list from real-fit (cross-model) + current dashboard data const modelsSeen = new Set(); dd.agents.forEach(a => { modelsSeen.add(a.model_short); }); Object.values(realAgents).forEach(a => { Object.keys(a.evaluations || {}).forEach(m => modelsSeen.add(m)); }); const modelList = Array.from(modelsSeen).filter(m => m && m !== 'code-skeptic'); const t = document.getElementById('hmTable'); let h = 'Agent'; modelList.forEach(m => { h += '' + esc(m) + ''; }); h += 'BestScore'; dd.agents.forEach(a => { const realAgent = realAgents[a.name]; h += '' + esc(a.name) + ''; modelList.forEach(m => { let score = 0; if (realAgent && realAgent.evaluations && realAgent.evaluations[m] > 0) { score = Math.round(realAgent.evaluations[m]); } const isCurrent = a.model_short === m; let cls = 'na'; if (score >= 90) cls = 'high'; else if (score >= 75) cls = 'good'; else if (score >= 50) cls = 'med'; else if (score > 0) cls = 'low'; const display = score > 0 ? score : (isCurrent ? Math.round(a.fit_score || 0) : '·'); const curStyle = isCurrent ? 'box-shadow:inset 0 0 0 2px var(--accent-cyan)' : ''; h += '' + display + ''; }); const bestModel = realAgent ? (realAgent.best_model || a.model_short) : a.model_short; const bestScore = realAgent ? Math.round(realAgent.best_score || 0) : Math.round(a.fit_score || 0); h += '' + esc(bestModel) + '' + bestScore + ''; }); t.innerHTML = h + ''; }`; // 2. Add loadRealFitData script after dashboard load const loadRealFitData = ` // Load real-fit report for cross-model evaluation try { const rfRes = await fetch('data/real-fit-report.json'); if (rfRes.ok) window.realFitData = await rfRes.json(); } catch(e) { console.warn('real-fit-report.json not loaded:', e.message); } `; let html = fs.readFileSync(INDEX, 'utf-8'); // Patch A: replace renderHeatmap function const oldPattern = /\/\/ Render Heatmap[\s\S]*?function renderHeatmap\(\)\s*\{[^}]*\{[^}]*\}[^}]*\}/; const oldMatch = html.match(oldPattern); if (oldMatch) { html = html.substring(0, oldMatch.index) + '// Render Heatmap (real-fit enabled)\n' + newRenderHeatmap + html.substring(oldMatch.index + oldMatch[0].length); console.log('Patched renderHeatmap'); } else { console.log('Pattern A not found, trying fallback...'); // Fallback: find and replace the specific renderHeatmap block const start = html.indexOf('function renderHeatmap() {'); if (start !== -1) { let brace = 0, end = start; for (let i = start; i < html.length; i++) { if (html[i] === '{') brace++; else if (html[i] === '}') { brace--; if (brace === 0) { end = i + 1; break; } } } html = html.substring(0, start) + newRenderHeatmap + '\n' + html.substring(end); console.log('Patched renderHeatmap (fallback)'); } } // Patch B: insert real-fit loading after dashboard load const dashLoadPattern = /window\.dashboardData = await dashRes\.json\(\);/; if (dashLoadPattern.test(html)) { html = html.replace(dashLoadPattern, 'window.dashboardData = await dashRes.json();\n' + loadRealFitData.trim()); console.log('Patched init() to load real-fit data'); } fs.writeFileSync(INDEX, html); console.log('Done — ' + (fs.statSync(INDEX).size / 1024).toFixed(1) + ' KB');