feat(desktop): the call thread places each planning turn's work under the line that asked for it (call tab 2/3)
Merged
DA
6d ago+351+351+012345678901234567890123456789-16-16-01234567890123456789
Second of the Call tab rollout, stacked on #2368. A pure model and its tests; nothing draws it until 3/3.
call-thread.ts builds the Call tab's one thread: the plan's calls one after another, each line said on them, and each planning turn's work right under the line that asked for it. It works the way a ChatGPT Voice call lands in its chat thread, in the coding agent tab's style.
- The link is the row id a turn names its ask by (
asked, #2368) and a line names its row by (metadata.rowId). - An ask spanning two lines stands under the later one.
- A turn no line on screen asked for (typed, lines not read yet, or past what the transcript holds) stands where it started: inside its call after the lines, between calls once its call had ended, or ahead of every call.
- A turn is placed in any shape (
CallTurn<T>), as agreed with the one-agent-runtime rollout, so its later one-wire PR only swaps where the turns come from. - A line heard on the live call now names its row in
metadatathe way a stored line does (transcript-model.ts), so the thread reads one key.
Tests (call-thread.test.ts, through the public export):
- Work stands under its line, Luke's answer follows it, and a two-line ask stands under the later line.
- Unlinked turns are placed by time, in all three places.
- A heard live line links like a stored one. This test fails without the
heardRowchange.
There's no Mac UI in this PR. ./scripts/verify.sh was not run (Linux VM). CI cannot verify the Mac; LUKE-159 is the manual Mac pass.
š¤ Generated with Claude Code