async function renderSessionReplay() { const content = document.getElementById('pageContent'); content.innerHTML = `
Loading sessions...
`; 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 = `
${sessions.slice(0, 50).map(s => ` `).join('')}
Session IDDateSize
${escapeHtml(s.id)} ${new Date(s.date).toLocaleString()} ${formatSize(s.size || 0)}
${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'; }