Repository keeps one live Timeline per room and re-yields on its
onUpdate callback (fires for both live events AND requestHistory),
not just onSync which never fires for pagination. loadMoreMessages
now paginates that same instance; added canLoadMore.
Timeline widget requests older history when scrolled within 400px of
the oldest end, guarded against re-entry, with a top loading spinner.
Verified: widget test drives a drag-to-top and asserts loadMoreMessages
fires; live smoke test confirms the onUpdate delivery path (reused by
history) still shows new messages after the refactor.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>