1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
//! egui widget: the §11 Altitude-2 Transcript tab.
//!
//! A scrollable list over the [`rows`] projection — one line per message,
//! per model text block, per thinking block, per tool call, per tool result,
//! per live tail — each folding open to its full payload under a `▶`/`▼`
//! disclosure toggle (§11 glyph doctrine: convention passes; the glyphs are
//! jsonview's, one home for the fold vocabulary). `raw` flips the whole tab
//! to verbatim bytes for every entry (§11: "every tab has a Raw toggle
//! showing verbatim bytes").
//!
//! **The step spine runs through it** (bl-1802). Every operable commit paints
//! as a horizontal rule across the chat, at the row where that model call's
//! reading began, with the children born there hanging under it — the [`spine`]
//! submodule, which is the whole of what the `history-rail` side panel used to
//! be. Where each rule sits and which notch it is arrives derived on the
//! [`Rail`] (`rail::place`), so the line, the pin behind it and the fold it
//! cuts to are one fact rather than three.
//!
//! The fold toggle is the jsonview exception (§11 widget-split discipline): a
//! self-contained widget whose interaction is *intrinsic* owns its tested
//! click, exercised under a simulated-pointer render test, rather than
//! smearing the flip across the excluded shell.
use HashSet;
use ;
use crate;
use crateRail;
use cratetheme;
/// Leaf marker for a row with nothing to fold — keeps its prefix aligned
/// under the toggles above it (jsonview's alignment convention).
const NO_FOLD_MARK: &str = "·";
/// How the chat is read: who the model turns ARE (§3.3 display name, bl-2335),
/// whether the Raw toggle is up, and which row classes arrive expanded (the
/// §4.1 knobs). One value because they are one question — *how to project this
/// transcript* — and the tab data already holds all three side by side.
/// Render the transcript. `folds` is the caller's RAM override set (§5.3),
/// which a toggle click mutates; `rail` is the step spine whose notches paint
/// as this chat's rules and whose cards hang under them; `selected` is the
/// caller-owned pinned-notch ephemeron a rule click flips. The return is the
/// child agent a card click asks to open — the same selection gesture the §11
/// descent-tree rows spend.
/// Verbatim backing bytes under a filename header — the Raw view of any entry.
/// Both seats are [`whole`]: Raw is the escape from a parse, and bytes cut at
/// the pane edge are not the bytes.
/// **Show `body` entire** — the seat that must not truncate, stated locally
/// (bl-7654).
///
/// `shell::row::bounded` puts §11 rule 1's `Truncate` at every bounded panel
/// root, the centre included, and a `Ui` inherits its parent's style — so an
/// expanded payload laid in the centre was a *one-line* galley ending in `…`,
/// 67 of a 400-character answer at 420x320. The fold's whole promise is that
/// turning the triangle shows the payload, and rule 1's own body names this
/// exemption: *"a seat that must not truncate (a wrapped prose block) can
/// still say so locally"*. Taken here, deliberately, in a scope: no ambient
/// default is set, so the rows around it keep truncating, and the seat depends
/// on no ambient state either — in a seat that declares none, egui's
/// horizontal default is `Extend` and the pane's clip rect slices the run
/// mid-glyph with no ellipsis at all.
/// One chrome line of a row — stripe, toggle, label, inline preview — with §11
/// rule 1 stated at the row rather than inherited: chrome is one line and
/// elides rather than running off the pane, wherever the transcript is seated.
/// What the prefix stands for, hovered (bl-2335) — the §11 glyph doctrine
/// applied to a name: the glance gets the agent, the hover gets the config fact
/// behind it. A label that says everything it has to say hovers nothing.
/// A row: the speaker's own line where somebody is speaking, then the payload
/// line — toggle, machinery label, and the payload inline as the preview while
/// contracted — with the full body below while expanded. A row whose payload
/// already fits the line has an empty body and shows it inline always, so
/// nothing is hidden behind a fold that would reveal nothing. A turn's
/// aggregate row has no payload of its own: what its fold reveals is the step
/// rows the projection puts after it.
///
/// **The speaker is not the output** (bl-f3fc, operator ruling). A speaking row
/// wore its label in the body's own ink on the body's own line, so the eye had
/// nothing to separate who spoke from what they said. The label now takes the
/// line above the payload and the role's hue — `theme::role_badge`, the one
/// mapping the stripe and the pending queue already read, so no hue is minted.
/// Machinery rows (`role: None` — thinking, tool calls, results, raw bytes, the
/// turn aggregate) are one line still: nobody is speaking, so there is no
/// speaker to set apart, and their tone-painted prefix keeps its seat.
///
/// **One fact decides three things** (bl-7654). `row.body.is_empty()` — the
/// projection's own spelling of *"is there anything behind this?"* — says
/// whether the inline seat is the payload entire or a stand-in for a body the
/// `▶` reveals, and the seat then wraps-or-truncates, paints solid-or-faded,
/// and wears a toggle-or-the-mark on that one answer. The operator's ruling is
/// that the three never disagree: **anything hidden is hidden behind a
/// triangle**, so a run that ends in `…` always has one beside it, and a run
/// with no triangle beside it is whole.
/// The inline payload seat. `abridged` is the row's one fact: a body is folded
/// away behind the `▶` beside this run.
///
/// **The fade means "there is more behind this", so it may only appear where
/// there is** (bl-7654). `ui.weak` was unconditional, which painted a payload
/// shown *whole* exactly as faded as a preview standing in for hidden text —
/// the surface saying the opposite of the truth precisely where it told the
/// whole truth. Inverted: complete content reads complete.
///
/// **Solidity, not a tone.** [`Tone`] is the projection's statement about what
/// kind of thing a row *is*, derived from the entry's bytes; abridgement is a
/// fact about this seat in this frame, and it flips when the operator turns
/// the triangle — so a row would have to wear two tones for one payload, which
/// is a category error. `theme::tone_solidity` is the palette's answer for
/// exactly this ("a statement that is not yet a statement"): one number, the
/// same 0.55 the §7.2 pending echo and the inbox queue spend, dimming the seat
/// rather than repainting it into a parallel palette.
/// The disclosure toggle, or the alignment mark when there is nothing to fold.
/// An aggregate row always folds — its steps are what it opens onto.
/// Paint `text` in the row's tone, handing back the label so the caller can
/// hang a hover on it. An in-flight tool call pulses and pulls a near-term
/// repaint, exactly as the git_tree tool indicator does.