feat(web/claw): open on the newest turn, walk back, and resume from the seq

A reload of a weeks-old session replayed the whole record before the
first pixel, and every reconnect reset the mirror and replayed it
again. The stream now names each frame's seq and the client keeps it,
so a retry sends since=<seq> and receives only the gap, and the mirror
is left alone: its items are still true.

A first open with no cursor gets the tail, cut to a turn boundary,
which paints the latest conversation at once. The turns above it come
from the history route, one whole turn per page, fetched when the
reader nears the top or when the transcript is too short to fill the
screen; a page folds through the same reducer as the live stream and
joins above, and the scroll position moves down by the page's height so
the reader keeps their place. A reset comment (the record no longer
holds the cursor) drops the mirror; the tail that follows rebuilds it.

The dev proxy rebuilt the upstream URL from the pathname alone, so
since and before never reached the daemon under nuxt dev: every resume
was a full replay and every history page was the tail. It forwards the
query string now.
This commit is contained in:
vhaudiquet committed 2026-11-08 18:01:30 +01:00
1 parent 744ba8b06c
commit ed79c0cf1b
6 files changed
+337 -49

No files matched your search

+6 -2
View File
@@ -14,7 +14,11 @@ import { proxyRequest } from 'h3'
export default defineEventHandler((event) => {
if (!import.meta.dev) return
const { pathname } = getRequestURL(event)
// The query string rides along: `since` on the event stream and
// `before`/`limit` on the history pages are the whole protocol, and a
// proxy that dropped them would quietly serve the tail to every
// request.
const { pathname, search } = getRequestURL(event)
if (pathname !== '/healthz' && !pathname.startsWith('/v1/')) return
return proxyRequest(event, useRuntimeConfig(event).clawUpstream + pathname)
return proxyRequest(event, useRuntimeConfig(event).clawUpstream + pathname + search)
})