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 += 'Best | Score |
';
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');