async function renderSessionReplay() {
const content = document.getElementById('pageContent');
content.innerHTML = `
`;
try {
const data = await api.listSessions();
const sessions = data.sessions || [];
const list = document.getElementById('sessionList');
if (sessions.length === 0) {
list.innerHTML = `๐ฌ
No sessions found
Sessions from opencode will appear here
`;
return;
}
list.innerHTML = `
| Session ID | Date | Size | |
${sessions.slice(0, 50).map(s => `
| ${escapeHtml(s.id)} |
${new Date(s.date).toLocaleString()} |
${formatSize(s.size || 0)} |
|
`).join('')}
${sessions.length > 50 ? `
Showing 50 of ${sessions.length} sessions
` : ''}
`;
} catch (err) {
document.getElementById('sessionList').innerHTML = `โ
Failed to load sessions
${escapeHtml(err.message)}
`;
}
}
async function replaySession(id) {
const detail = document.getElementById('sessionDetail');
detail.innerHTML = `Loading session ${escapeHtml(id)}... `;
try {
const data = await api.getSessionReplay(id);
const messages = data.messages || [];
const session = data.session || {};
detail.innerHTML = `
Session: ${escapeHtml(id)}
${messages.length} messages ยท ${new Date(session.created_at || Date.now()).toLocaleString()}
${messages.map(m => {
const isUser = m.role === 'user' || m.role === 'human';
return `
${isUser ? '๐ค You' : '๐ค Assistant'}
${escapeHtml((m.content || '').substring(0, 500))}${(m.content || '').length > 500 ? '...' : ''}
${new Date(m.timestamp || Date.now()).toLocaleTimeString()}
`;
}).join('')}
${messages.length === 0 ? '
Empty session
' : ''}
`;
} catch (err) {
detail.innerHTML = `โ Failed to replay session: ${escapeHtml(err.message)}
`;
}
}
function formatSize(bytes) {
if (bytes < 1024) return bytes + ' B';
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';
return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
}