[FEATURE] TUI: numbered transcript blocks + per-block action menu (Reply / Repeat / Restore-here) — reviving the #64207 reply-to-block lineage
Problem
Steering the model at a specific earlier block — one finding out of five, a diff hunk, a Bash result, or my own earlier input — happens by prose ("the second option above"), which the model misresolves, or by copy-paste, which is doubly broken in the TUI: mouse capture kills native selection (#71826) and selection-copy routes through OSC 52 with silent clipboard failures on common terminals (#76902). There is currently no way to act on a transcript block without copying it.
Proposed
- Numbered transcript blocks
- Granularity: every user input and assistant message gets a session-monotonic index (
[12]); blocks within an assistant message — tool results, code fences, individual review findings — get sub-indices ([12.3]). "One finding out of five" needs sub-block resolution; a turn number alone is too coarse. - Rendering: a dim, gutter-style prefix at block start (editor line-number feel), applied at the rendering layer only — numbers never leak into copied text, logs, or the model's context unless a reference is actually made.
- Stability: indices anchor to transcript entries, not screen positions — they survive scrolling and
--resume; across/compact, a reference to a summarized-away block degrades gracefully because the anchored quote (excerpt) travels with the reference. - Keyboard parity (text addressing): numbers are usable in plain prompts ("re:
[12.3]") and as commands —/reply 12,/repeat 12,/restore 12— so the whole feature works without a mouse. Prior art: #12859 proposed exactly this shape ("message numbering +/edit x"). - Display control:
transcriptNumbers: on | off | auto—autoshows numbers only while block-select mode is active (on-demand, like relative line numbers), keeping the default UI clean.
- Per-block action menu — click/hover at a block's start (the TUI is already mouse-interactive) or keyboard block-select, opening:
- Reply — attach the block to the next prompt as a structured anchored reference (block id + excerpt), rendered as a collapsed messenger-style quote above the new input.
- Repeat — re-send that user input / re-run that step as-is.
- Restore convo here — rewind conversation state to that block.
- Multi-select for batch reply (several blocks anchored into one prompt) — the #64207 lineage was literally "deferred batch reply to specific blocks."
- Anchored reference semantics — the model receives block id + role + quoted excerpt structurally, not retyped text, so it cannot misresolve the target. The same ids should surface in headless
claude -pJSON and Agent SDK transcripts, and the model may emit references too (see [12.3], rendered as a jump-link) — one shared addressing scheme for humans, the model, hooks, and automation, making this a transcript primitive rather than TUI chrome.
Optional extensions (nice-to-have, not core)
- Copy / Copy-as-markdown menu action — makes the menu itself the copy affordance, sidestepping broken native selection (#71826) and OSC 52 silent clipboard failures (#76902) entirely: no text selection needed to copy a block.
- Fork from here — the non-destructive sibling of Restore: branch a new session at that block and keep both timelines (restore is rewind-and-discard).
- Pin — keep a block in a small working set and mark it must-survive
/compact— a direct user lever on what compaction preserves. - Plugin-contributed block actions — let plugins register custom per-block actions (e.g. "file this finding as an issue").
Accessibility & machine readability (ARIA-like block semantics)
Give each numbered block a machine-readable role (user-input / assistant-message / tool-result / finding), surfaced three ways:
- Web & VS Code surfaces: real ARIA roles/landmarks — screen readers navigate by block ("assistant message 12, tool result 12.2") instead of a wall of text.
- TUI: the visible numbers + consistent block chrome double as visual anchors that screenshot/VLM-driven tooling can lock onto reliably, instead of inferring block boundaries from raw pixels.
- Transcript JSON / SDK: the same roles + ids programmatically.
This makes voice and vision layers first-class consumers: e.g. our multimodal I/O bridge (qte77/cc-senses-plugin — TTS /speak, STT /listen, screen-vision /see; also distributed via the marketplace below) could speak block addresses aloud and accept "reply to twelve point three" by voice — block addressability is the missing primitive for hands-free steering.
Scoping note (what already exists)
The double-ESC rewind menu already offers targeted restore at an arbitrary message ("Restore code and conversation" via the message selector — cf. #63901). This FR does not ask for new random access; it asks to surface those actions inline per numbered block, unifying reply / repeat / restore into one visible interaction model instead of a modal.
Prior art / related
Revives the reply-to-block lineage consolidated in #64207 (closed for staleness, not on the merits; explicitly invited refiling) — canonical #45904, plus #58336, #26716, #60891, #47906. Numbering prior art: #12859 ("add message numbering + /edit x"). Open but differently-scoped: #70628 (Desktop GUI reply), #72301 (VS Code selection-as-context), #63901 (navigation only). Copy-pain context: #71826, #76902.
Why it matters at scale
Plugin-heavy sessions multiply distinct blocks per turn — e.g. workflows built on our plugin marketplace (qte77/claude-code-plugins) interleave skill outputs, hook messages, and multi-finding review results; "apply this finding, skip that one" has no precise anchor today.
Version: Claude Code 2.1.218 (CLI, Linux).