- Prevents connection hangs during initial join by immediately failing when a host rejects a guest prior to welcome.
- Short-circuits the connection welcome timeout upon receiving a pre-welcome error frame.
- Surfaces exact protocol mismatch and hello rejection reasons directly to the joining guest interface.
- Ensures `CollabGuestLink` and `GuestClient` transition immediately to ended/failed states with host error details.
The web guest cleared the welcome timeout as soon as metadata arrived,
but non-empty snapshots had no replacement progress clock while waiting
for snapshot-chunk.final. If the relay stalled after welcome or after a
partial chunk, the client stayed stuck in its loading phase forever.
Mirror the TUI guest's snapshot progress timeout: arm it for non-empty
welcome frames, reset it on each non-final chunk, clear it on final and
on close/end, and end the web session with the same session-snapshot
timeout reason when no chunk progress arrives.
Fixes#3144
The host used to ship the entire transcript inside a single welcome
frame, so a multi-MB session spent the guest's 30s first-welcome
timeout on the relay transfer itself: ~1.3 MB took ~3s, ~4.2 MB took
~12s, and ~13.6 MB never arrived before the guest gave up with
'timed out waiting for the host's welcome'.
Bump COLLAB_PROTO to 2 and split the welcome:
- welcome carries metadata only (header, state, agents, entryCount,
readOnly) and lands in well under one second.
- a train of snapshot-chunk frames (SNAPSHOT_CHUNK_BYTES = 512 KB,
oversize entries ship alone) carries the transcript. Last chunk
flips final: true; an empty snapshot still emits one final chunk.
- the host queues welcome + chunks synchronously inside #handleHello,
preserving the host comment's ordering invariant (later broadcast
frames cannot interleave between them).
- the TUI guest accumulates chunks under a SNAPSHOT_PROGRESS_TIMEOUT_MS
that resets per chunk; only after final does it write the replica
jsonl, switchSession, and render. The first-welcome timeout still
guards arrival of the small welcome.
- the collab-web GuestClient streams entries into the snapshot as
chunks arrive and flips phase to 'live' on final.
Includes a contract test (in-process relay) asserting the welcome is
metadata-only, the chunk train fans the 1.5 MB synthetic transcript
across multiple frames with only the last marked final, and the
flattened entries match the source snapshot.
Fixes#3144
- Extended `parseCollabLink` test coverage to reject 16-byte and 40-byte fragments instead of only rejecting short keys.
- Added coverage for full-link fragments to ensure key and write token are parsed when present.
- Updated `GuestClient` test setup so `welcomeFrame` carries a `readOnly` flag into snapshot assertions.
- Enabled read-only mode by wiring snapshot.readOnly through AgentDrawer and Composer to block prompts and controls.
- Added read-only indicators in the header and participant titles for view-only sessions.
- Added SEO and app metadata assets by updating index.html head tags, manifest, robots.txt, and sitemap.xml.
- Updated brand presentation by adding new favicon/OG assets and switching theme tokens to new OMP colors.