v1.0.383
feat(chat): keep all history, searchable behind "See more"
Chat history was capped at 20 threads / 80 messages / 900KB and silently
dropped everything past that. Retention is now unbounded.
Keeping everything rules out the old storage shape. The client used to hold
every transcript in memory and re-PUT the whole blob 1.5s after each change;
unbounded that means multi-megabyte writes per keystroke burst and a boot that
downloads every conversation before the first message paints. So:
- Storage splits into DATA_DIR/chat-threads/.json (one transcript each)
plus the existing root file, now a lightweight index of summaries. A legacy
single-blob file migrates itself on first read. - The client hydrates the index plus only the active transcript, writes only
the thread being edited, and lazy-loads others when opened. Save cost no
longer grows with how much history is kept. - New routes: GET/PUT/DELETE /api/chat/threads/:id, PUT .../active, and
GET .../search (q + date range, snippets, paging) which scans transcripts
server-side so the browser never holds the archive. The old bulk PUT stays
as a merging import for tabs on pre-split JS. - Sidebar lists the 15 most recent and hands the rest to a new chat-history
view: full-text search, date filters, highlighted snippets, open or delete. - Backup/restore now capture chat-threads/; the index alone would restore an
archive with no transcripts.
Pruning survives only for the localStorage offline fallback, which has a hard
quota and would throw rather than degrade.
Two bugs found while testing the new store, both fixed here: index rows were
re-normalized through the full-thread path, zeroing messageCount and preview on
every read (an unopened thread then looks empty rather than unfetched); and the
empty-index result was a shallow copy of a module-level constant that callers
mutate, so the first thread saved on a fresh install was welded into every
later empty read for the life of the process.
Claude-Session: https://claude.ai/code/session_01FbNUfdN67fEjpg7WdgQpLD