COD-121 unified session list: welcome list frontend (slice A, unit 2)

Backs the welcome-screen "Resume Conversation" list with the new
GET /api/sessions/unified endpoint instead of /api/history/sessions, so it
shows the COMPLETE set (live + persisted + non-Claude + closed history)
newest-first with richer context, rather than only Claude transcripts.

- terminal-ui.js: new _fetchUnifiedSessions(); loadHistorySessions() now uses
  it. _buildHistoryItem upgraded to the unified shape (kept backward-compatible
  with the folder-modal's old shape): title = name || firstPrompt || dir; a
  mode badge + a LIVE badge (sources includes 'live'); timestamp from
  lastActivityAt (falls back to lastModified); size only when present; detail
  panel + "View all in this folder" preserved (gated on projectKey). Resume
  branches: an open live session selects its tab, a closed one resumes.
- unified-session-service.ts + endpoint: pass projectKey through the history
  source so the folder drill-down survives.
- styles.css: .history-item-badges / -badge / -badge-live pills.

Verified: tsc 0, lint 0, frontend-syntax + public-asset format clean, service
tests 13/13 (+projectKey), route tests 4/4. Playwright on an isolated beta:
the welcome list renders real items from /api/sessions/unified, and the
renderer produces the tab-name title + codex mode badge + visible LIVE badge,
omits LIVE on closed items, keeps "View all in folder", and routes resume
correctly (open->select tab, closed->resume). Persistent panel + live SSE
status are later units.
This commit is contained in:
Aamer Akhter
2026-07-12 12:19:10 -04:00
parent 3f23621f8d
commit c9f37f2628
5 changed files with 122 additions and 14 deletions
@@ -147,6 +147,22 @@ describe('mergeUnifiedSessions', () => {
expect(merged).toHaveLength(1);
expect(merged[0].lastActivityAt).toBe(new Date('2026-01-01T00:00:00.000Z').getTime());
});
it('surfaces projectKey from a history input onto the merged item', () => {
const merged = mergeUnifiedSessions({
history: [
{
sessionId: 'h',
workingDir: '/w',
sizeBytes: 5000,
lastModified: '2026-01-01T00:00:00.000Z',
projectKey: '-repo-alpha',
},
],
});
expect(merged).toHaveLength(1);
expect(merged[0].projectKey).toBe('-repo-alpha');
});
});
describe('filterAndPaginate', () => {