Return an explicit remote transcript error when the host cannot fit a complete JSONL entry inside the fetch cap, and stop the guest viewer poll loop after surfacing that error.
Fixes#3931
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
- Added collab.webUrl and rendered browser links as web UI wrappers whose fragments carry relay links.
- Added one-shot /collab qrcode and /collab qrcode-view commands with terminal QR rendering.
- Updated coding-agent and collab-web parsers to prefer parseable wrapper fragments while preserving legacy links.
- Added regression tests and changelog entries for split-host collab links and QR commands.
- Added session-domain modules and exports for session-entries, context, listing, loader, and migrations.
- Changed persistence to async append writes plus writeTextAtomic, removing sync line APIs.
- Added compaction-aware session context rebuild with dangling tool-call cleanup.
- Added resumable session resolution with status inference, id/stem/suffix matching, and backup recovery.
- Changed the link grammar from `<roomId>#<key>` / `host[:port]/r/<roomId>#<key>` to dot-joined `<roomId>.<key>` in `formatCollabLink`/`parseCollabLink` (`packages/coding-agent/src/collab/protocol.ts`) and the collab-web mirror (`packages/collab-web/src/lib/link.ts`): RFC 3986 forbids a raw `#` inside a fragment, so strict URL stacks (macOS Foundation behind terminal click-to-open) percent-encoded the second `#`.
- Kept legacy `#`-joined links parseable via `BARE_LINK_RE` and added lenient `%23` → `#` decoding for mangled deep links.
- Updated the `ConnectScreen` placeholder, `app.tsx` deep-link comment, `DEFAULT_RELAY_URL` doc in `packages/wire`, `docs/collab.md` examples, and both package CHANGELOGs.
- Extended `crypto.test.ts` and `link.test.ts` with dot-joined, legacy-hash, and `%23`-mangled link coverage.
- Added write-token generation and validation to distinguish writable and read-only guests.
- Added deep-link support using `https://<relay>/#<link>` with 32/48-byte collab secrets.
- Added full-link and key-only semantics where full links grant writes and key-only links are view-only.
- Added /collab view/status/stop command updates with read-only participant status and join hints.