TranscriptFollow

works.iterative.claude.ui.transcript.TranscriptFollow

What a page showing one rendering of a transcript must do to be showing the next one.

Which part of a transcript may still change is decided by comparing the two renderings rather than by reasoning about which rows are allowed to move. Reasoning would have to be re-checked every time the rendering gains a rule — how a stretch of work gathers, when a pause is worth saying, which answer a notification belongs to. A comparison is true whatever the rules are, and it always names the smallest tail that will do.

Attributes

Graph
Supertypes
class Object
trait Matchable
class Any
Self type

Members list

Type members

Classlikes

final case class Following(entries: Vector[ConversationLogEntry], live: Vector[ConversationLogEntry], rows: List[Markup], reachesStart: Boolean)

What a host holds while it follows one session: the entries the file has given it, the ones the session has said and the file has not caught up with, and the rows it last rendered from both.

What a host holds while it follows one session: the entries the file has given it, the ones the session has said and the file has not caught up with, and the rows it last rendered from both.

All of it belongs to the one page being served and goes when it does. Nothing is written down, the same as on the reading path.

Attributes

Companion
object
Supertypes
trait Serializable
trait Product
trait Equals
class Object
trait Matchable
class Any
Show all
object Following

Attributes

Companion
class
Supertypes
trait Product
trait Mirror
class Object
trait Matchable
class Any
Self type
Following.type

Value members

Concrete methods

def beat(following: Following): TranscriptTail

What a host says when nothing has changed: keep everything, take nothing.

What a host says when nothing has changed: keep everything, take nothing.

Said on a beat rather than only on growth, so that a page hears from the host whether or not the session is busy — see TranscriptTail for why silence has to mean something is wrong.

Attributes

def heard(following: Following, batch: Seq[ConversationLogEntry], sessionId: String, clock: TranscriptClock): (Following, TranscriptTail)

The next thing a page is told when the session itself has said something the transcript does not hold yet.

The next thing a page is told when the session itself has said something the transcript does not hold yet.

This is the same conversation from the other side: a session speaks before the CLI has finished writing it down, and a page that waited for the file would be a turn behind for as long as the file took. What is heard renders through the same reader as what is read, so the page cannot tell which account a row came from — and when the file arrives, next drops the duplicate rather than drawing it again.

Attributes

def next(following: Following, batch: Seq[ConversationLogEntry], sessionId: String, clock: TranscriptClock): (Following, TranscriptTail)

The next thing a page is told when the transcript has grown, and what the host then holds.

The next thing a page is told when the transcript has grown, and what the host then holds.

The rows are rendered from every entry seen so far, not from the batch alone: a stretch of work that is still gathering renders as the whole stretch, and a pause is measured from the row before it. What of that the page already holds is then what it is not sent again.

A turn the page was shown from the live stream leaves the waiting list as the file catches up with it, so it is rendered once and the page never sees it twice.

Value parameters

batch

what the session has just been written, oldest first

clock

how this producer writes the wall-clock time of an entry

following

what the host held before this batch

sessionId

the session being followed, echoed onto its rows

Attributes

def tailOf(previous: List[Markup], current: List[Markup]): TranscriptTail

What a page holding previous must replace to be showing current.

What a page holding previous must replace to be showing current.

Attributes