@peasant-labs/fairtrade 0.0.40 → 0.0.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/THIRD_PARTY_NOTICES.md +14 -0
  2. package/dist/lib/{GraphLegend-nwqBLEcI.js → GraphLegend-CBKZsRta.js} +1259 -1399
  3. package/dist/lib/adapter-Dulh38C2.js +1214 -0
  4. package/dist/lib/commons.js +202 -201
  5. package/dist/lib/components.css +1 -1
  6. package/dist/lib/graph.js +474 -471
  7. package/dist/lib/share-fonts/AtkinsonHyperlegible-Bold.ttf +0 -0
  8. package/dist/lib/share-fonts/AtkinsonHyperlegible-Regular.ttf +0 -0
  9. package/dist/lib/share-fonts/AtkinsonHyperlegibleMono-Bold.ttf +0 -0
  10. package/dist/lib/share-fonts/AtkinsonHyperlegibleMono-Regular.ttf +0 -0
  11. package/dist/lib/share-fonts/OFL-AtkinsonHyperlegible.txt +92 -0
  12. package/dist/lib/share-fonts/OFL-AtkinsonHyperlegibleMono.txt +93 -0
  13. package/dist/lib/share.js +1311 -0
  14. package/dist/lib/time-CpVBzcqQ.js +157 -0
  15. package/dist/lib/types/AppSidebar.d.ts +2 -0
  16. package/dist/lib/types/BrandMark.d.ts +2 -6
  17. package/dist/lib/types/Menu.d.ts +7 -1
  18. package/dist/lib/types/brand-geometry.d.ts +22 -0
  19. package/dist/lib/types/commons/providers.d.ts +1 -1
  20. package/dist/lib/types/graph/CodeMapComposition.d.ts +4 -1
  21. package/dist/lib/types/graph/CodeMapNavigator.d.ts +5 -1
  22. package/dist/lib/types/share/ShareCard.d.ts +40 -0
  23. package/dist/lib/types/share/data.d.ts +54 -0
  24. package/dist/lib/types/share/fonts.d.ts +16 -0
  25. package/dist/lib/types/share/index.d.ts +5 -0
  26. package/dist/lib/types/share/marks.d.ts +23 -0
  27. package/dist/lib/types/share/metrics.d.ts +10 -0
  28. package/dist/lib/types/transcript/title.d.ts +21 -0
  29. package/dist/lib/types/ui/brand-geometry.d.ts +22 -0
  30. package/dist/lib/types/ui/format.d.ts +35 -0
  31. package/dist/lib/types/ui/provider-policy.d.ts +27 -0
  32. package/dist/lib/types/ui/transcript/adapter.d.ts +66 -0
  33. package/dist/lib/types/ui/transcript/adapter.parse.d.ts +103 -0
  34. package/dist/lib/types/ui/transcript/analytics.d.ts +213 -0
  35. package/dist/lib/types/ui/transcript/time.d.ts +47 -0
  36. package/dist/lib/types/ui/transcript/title.d.ts +84 -0
  37. package/dist/lib/types/ui/transcript/usage.d.ts +19 -0
  38. package/dist/lib/types/ui/transcript/view-model.d.ts +700 -0
  39. package/dist/lib/types/ui/transcript/wire-types.d.ts +63 -0
  40. package/dist/lib/{ui-DMUCYaeU.js → ui-BxiVcGs3.js} +3724 -4913
  41. package/dist/lib/ui.js +7 -5
  42. package/package.json +18 -6
@@ -0,0 +1,700 @@
1
+ /**
2
+ * Cooked git chrome for the session header. Produced by the adapter from
3
+ * whichever wire shape is present — canonical flat git fields OR retired nested
4
+ * `gitContext` (see TranscriptWireInput in wire-types.js). Absent on the model
5
+ * ⇒ the git chips are omitted entirely (clean degrade). Every field is optional
6
+ * because the canonical session-detail wire carries only branch + remote today;
7
+ * the rest arrive only via legacy inputs and fixtures.
8
+ *
9
+ * @typedef {object} SessionGitVM
10
+ * @property {string} [branch]
11
+ * @property {string} [remote]
12
+ * @property {string} [author] cooked from legacy gitContext.user; absent on the canonical flat wire
13
+ * @property {CommitVM[]} [commits]
14
+ * @property {number} [filesChanged]
15
+ * @property {number} [insertions]
16
+ * @property {number} [deletions]
17
+ */
18
+ /**
19
+ * A cooked commit for the git chrome / commit chips. Mirrors CommitInfo
20
+ * (wire-types.js) with display-ready fields. The churn (`adds`/`dels`/`files`)
21
+ * and `turn` anchor are render-when-present: canonical CommitInfo carries
22
+ * no churn and commits are not on the session_detail payload (the deferred
23
+ * backend follow-up), so these light up from fixtures / the retired nested shape now
24
+ * and from the canonical wire when that follow-up lands.
25
+ *
26
+ * @typedef {object} CommitVM
27
+ * @property {string} hash
28
+ * @property {string} shortHash abbreviated hash for the chip label
29
+ * @property {string} message first line
30
+ * @property {string} [author]
31
+ * @property {number} [commitTime] Unix millis
32
+ * @property {boolean} [session] true if produced during this session
33
+ * @property {number} [adds] insertions for the checkpoint stat (render-when-present)
34
+ * @property {number} [dels] deletions for the checkpoint stat (render-when-present)
35
+ * @property {number} [files] files changed for the checkpoint stat (render-when-present)
36
+ * @property {number} [turn] turn index this checkpoint attaches to (adapter joins commitTime→nearest turn)
37
+ */
38
+ /**
39
+ * The cooked session header / meta / outcome / scorecard, plus optional git.
40
+ * The scorecard is passed through largely as-is (the wire scorecard is already
41
+ * flat numeric signals); the analytics util derives display BANDS from it
42
+ * separately (see `scorecardBands` on the analytics block).
43
+ *
44
+ * @typedef {object} SessionVM
45
+ * @property {string} id
46
+ * @property {import('./wire-types.js').Harness} harness
47
+ * @property {string} startTime
48
+ * @property {string} endTime
49
+ * @property {number} durationMins
50
+ * @property {number} totalTokens
51
+ * @property {number} tokensIn
52
+ * @property {number} tokensOut
53
+ * @property {number} turnCount
54
+ * @property {number} [inputSubmissionCount] absent means unmeasured, never inferred from turns
55
+ * @property {boolean} [hasNormalizedEvidence] prevents legacy prompt-derived title inference
56
+ * @property {import('@peasant-labs/schema').SessionPurpose} [purpose]
57
+ * @property {string} [rootSessionId]
58
+ * @property {number} toolCallCount
59
+ * @property {string} [title] editorial session title/summary (render-when-present; else the consumer derives one from the first prompt). Not a wire field — supplied by a curated consumer.
60
+ * @property {string} [project]
61
+ * @property {string} [model]
62
+ * @property {string} [workingDirectory]
63
+ * @property {import('./wire-types.js').SessionOutcome} [outcome]
64
+ * @property {import('./wire-types.js').SessionScorecard | null} [scorecard]
65
+ * @property {SessionGitVM} [git] render-when-present; never a wire field
66
+ */
67
+ /**
68
+ * A logical grouping for the filters rail, derived from `ToolCallKind`. The
69
+ * adapter classifies every tool call into exactly one group; counts roll up in
70
+ * `FilterIndexVM.toolGroupCounts`.
71
+ * @typedef {'edits' | 'bash' | 'read' | 'search' | 'fetch' | 'tasks' | 'other'} ToolGroup
72
+ */
73
+ /** Canonical ToolGroup ids, in the filters-rail display order. @type {readonly ToolGroup[]} */
74
+ export const TOOL_GROUPS: readonly ToolGroup[];
75
+ /**
76
+ * Cooked git chrome for the session header. Produced by the adapter from
77
+ * whichever wire shape is present — canonical flat git fields OR retired nested
78
+ * `gitContext` (see TranscriptWireInput in wire-types.js). Absent on the model
79
+ * ⇒ the git chips are omitted entirely (clean degrade). Every field is optional
80
+ * because the canonical session-detail wire carries only branch + remote today;
81
+ * the rest arrive only via legacy inputs and fixtures.
82
+ */
83
+ export type SessionGitVM = {
84
+ branch?: string;
85
+ remote?: string;
86
+ /**
87
+ * cooked from legacy gitContext.user; absent on the canonical flat wire
88
+ */
89
+ author?: string;
90
+ commits?: CommitVM[];
91
+ filesChanged?: number;
92
+ insertions?: number;
93
+ deletions?: number;
94
+ };
95
+ /**
96
+ * A cooked commit for the git chrome / commit chips. Mirrors CommitInfo
97
+ * (wire-types.js) with display-ready fields. The churn (`adds`/`dels`/`files`)
98
+ * and `turn` anchor are render-when-present: canonical CommitInfo carries
99
+ * no churn and commits are not on the session_detail payload (the deferred
100
+ * backend follow-up), so these light up from fixtures / the retired nested shape now
101
+ * and from the canonical wire when that follow-up lands.
102
+ */
103
+ export type CommitVM = {
104
+ hash: string;
105
+ /**
106
+ * abbreviated hash for the chip label
107
+ */
108
+ shortHash: string;
109
+ /**
110
+ * first line
111
+ */
112
+ message: string;
113
+ author?: string;
114
+ /**
115
+ * Unix millis
116
+ */
117
+ commitTime?: number;
118
+ /**
119
+ * true if produced during this session
120
+ */
121
+ session?: boolean;
122
+ /**
123
+ * insertions for the checkpoint stat (render-when-present)
124
+ */
125
+ adds?: number;
126
+ /**
127
+ * deletions for the checkpoint stat (render-when-present)
128
+ */
129
+ dels?: number;
130
+ /**
131
+ * files changed for the checkpoint stat (render-when-present)
132
+ */
133
+ files?: number;
134
+ /**
135
+ * turn index this checkpoint attaches to (adapter joins commitTime→nearest turn)
136
+ */
137
+ turn?: number;
138
+ };
139
+ /**
140
+ * The cooked session header / meta / outcome / scorecard, plus optional git.
141
+ * The scorecard is passed through largely as-is (the wire scorecard is already
142
+ * flat numeric signals); the analytics util derives display BANDS from it
143
+ * separately (see `scorecardBands` on the analytics block).
144
+ */
145
+ export type SessionVM = {
146
+ id: string;
147
+ harness: import("./wire-types.js").Harness;
148
+ startTime: string;
149
+ endTime: string;
150
+ durationMins: number;
151
+ totalTokens: number;
152
+ tokensIn: number;
153
+ tokensOut: number;
154
+ turnCount: number;
155
+ /**
156
+ * absent means unmeasured, never inferred from turns
157
+ */
158
+ inputSubmissionCount?: number;
159
+ /**
160
+ * prevents legacy prompt-derived title inference
161
+ */
162
+ hasNormalizedEvidence?: boolean;
163
+ purpose?: import("@peasant-labs/schema").SessionPurpose;
164
+ rootSessionId?: string;
165
+ toolCallCount: number;
166
+ /**
167
+ * editorial session title/summary (render-when-present; else the consumer derives one from the first prompt). Not a wire field — supplied by a curated consumer.
168
+ */
169
+ title?: string;
170
+ project?: string;
171
+ model?: string;
172
+ workingDirectory?: string;
173
+ outcome?: import("./wire-types.js").SessionOutcome;
174
+ scorecard?: import("./wire-types.js").SessionScorecard | null;
175
+ /**
176
+ * render-when-present; never a wire field
177
+ */
178
+ git?: SessionGitVM;
179
+ };
180
+ /**
181
+ * A logical grouping for the filters rail, derived from `ToolCallKind`. The
182
+ * adapter classifies every tool call into exactly one group; counts roll up in
183
+ * `FilterIndexVM.toolGroupCounts`.
184
+ */
185
+ export type ToolGroup = "edits" | "bash" | "read" | "search" | "fetch" | "tasks" | "other";
186
+ /**
187
+ * One line of a rendered diff hunk (cooked from a parsed edit/write result).
188
+ */
189
+ export type DiffLineVM = {
190
+ sign: "add" | "del" | "ctx";
191
+ /**
192
+ * old-file line number (gutter); absent for adds
193
+ */
194
+ oldNo?: string;
195
+ /**
196
+ * new-file line number (gutter); absent for dels
197
+ */
198
+ newNo?: string;
199
+ text: string;
200
+ };
201
+ /**
202
+ * A contiguous diff hunk for one file change.
203
+ */
204
+ export type DiffHunkVM = {
205
+ /**
206
+ * the hunk range header line, when present
207
+ */
208
+ header?: string;
209
+ lines: DiffLineVM[];
210
+ };
211
+ /**
212
+ * A fully cooked tool call. The adapter has ALREADY parsed the wire
213
+ * `arguments`/`result` JSON strings into `args`/`output`, derived a one-line
214
+ * `preview`, classified the `kind`/`group`, and (for edit/write) computed
215
+ * `diff`. Components render these fields directly — they NEVER JSON.parse.
216
+ */
217
+ export type ToolCallVM = {
218
+ id: string;
219
+ /**
220
+ * display name (e.g. "Read", "Bash")
221
+ */
222
+ name: string;
223
+ callEntryRef?: string;
224
+ resultEntryRef?: string;
225
+ callProvenance?: import("@peasant-labs/schema").ContentProvenance;
226
+ resultProvenance?: import("@peasant-labs/schema").ContentProvenance;
227
+ /**
228
+ * main or earlier-N, never a native coordinate
229
+ */
230
+ partition?: string;
231
+ /**
232
+ * separately recorded namespace; empty string remains present evidence
233
+ */
234
+ namespace?: string;
235
+ kind: import("./wire-types.js").ToolCallKind;
236
+ /**
237
+ * filters-rail grouping
238
+ */
239
+ group: ToolGroup;
240
+ /**
241
+ * the one-line summary shown collapsed
242
+ */
243
+ preview: string;
244
+ /**
245
+ * parsed `arguments` (shape varies by tool)
246
+ */
247
+ args?: unknown;
248
+ /**
249
+ * parsed `result` (shape varies by tool)
250
+ */
251
+ output?: unknown;
252
+ filePath?: string;
253
+ durationMs?: number;
254
+ exitCode?: number;
255
+ isError?: boolean;
256
+ /**
257
+ * validated owner evidence; cost strings remain verbatim
258
+ */
259
+ usage?: import("@peasant-labs/schema").UsageDetail;
260
+ /**
261
+ * attached structured details, excluded from conversation/search
262
+ */
263
+ nativeMetadata?: import("@peasant-labs/schema").NativeMetadataRecord[];
264
+ /**
265
+ * no recorded result; never a fabricated success
266
+ */
267
+ pending?: boolean;
268
+ /**
269
+ * present for edit/write kinds
270
+ */
271
+ diff?: DiffHunkVM[];
272
+ /**
273
+ * churn for edit/write
274
+ */
275
+ adds?: number;
276
+ dels?: number;
277
+ };
278
+ /**
279
+ * Cooked thinking content for a turn. The adapter extracts thinking from the
280
+ * folded `turn.content` (render-when-present); absent ⇒ no thinking block.
281
+ */
282
+ export type ThinkingVM = {
283
+ text: string;
284
+ /**
285
+ * precomputed word count for the toggle badge
286
+ */
287
+ words?: number;
288
+ };
289
+ /**
290
+ * One cooked turn. `toolCalls` here are the same `ToolCallVM` objects indexed in
291
+ * `toolCallsById` (shared identity — index once, reference everywhere).
292
+ */
293
+ export type TurnVM = {
294
+ index: number;
295
+ /**
296
+ * partition-scoped stable rendering key
297
+ */
298
+ identity?: string;
299
+ /**
300
+ * main or earlier-N; main index navigation stays unchanged
301
+ */
302
+ partition?: string;
303
+ sourceEntryRef?: string;
304
+ provenance?: import("@peasant-labs/schema").ContentProvenance;
305
+ role: import("./wire-types.js").Role;
306
+ /**
307
+ * display label, e.g. "1a" / "2"
308
+ */
309
+ label: string;
310
+ /**
311
+ * markdown body (thinking already extracted), as recorded
312
+ */
313
+ content: string;
314
+ /**
315
+ * the text the turn shows instead of `content`, present only
316
+ * when they differ (a cursor prompt's `<user_query>` wrapper
317
+ * removed); views render `displayContent ?? content`
318
+ */
319
+ displayContent?: string;
320
+ /**
321
+ * subagent nesting depth (0 = top level)
322
+ */
323
+ depth: number;
324
+ /**
325
+ * sticky model effective for this assistant turn; resolved over the complete ordered wire before projection
326
+ */
327
+ effectiveModel?: string;
328
+ /**
329
+ * prior root model when this turn carries the observation that changed it
330
+ */
331
+ modelChangedFrom?: string;
332
+ /**
333
+ * canonical provider identity for a top-level assistant turn
334
+ */
335
+ provider?: import("@peasant-labs/schema").Harness;
336
+ /**
337
+ * subagent name when depth > 0
338
+ */
339
+ agentName?: string;
340
+ thinking?: ThinkingVM;
341
+ usage?: import("@peasant-labs/schema").UsageDetail;
342
+ toolCalls: ToolCallVM[];
343
+ entryType?: import("./wire-types.js").EntryType;
344
+ stopReason?: import("./wire-types.js").StopReason | null;
345
+ isError?: boolean;
346
+ isFinal?: boolean;
347
+ tokens?: {
348
+ in: number;
349
+ out: number;
350
+ };
351
+ /**
352
+ * RFC3339 absolute time (drives commit anchoring); the visible label prefers `time`
353
+ */
354
+ timestamp?: string;
355
+ /**
356
+ * editorial display time, e.g. "8m ago" (render-when-present; else `timestamp`). Not derivable from the wire (relative to now) — a curated consumer supplies it.
357
+ */
358
+ time?: string;
359
+ /**
360
+ * editorial absolute time for the hover title (render-when-present; else `timestamp`)
361
+ */
362
+ timeTitle?: string;
363
+ /**
364
+ * annotations targeting this turn (may be empty)
365
+ */
366
+ annotations: AnnotationVM[];
367
+ };
368
+ /**
369
+ * A cooked annotation, already resolved to the turn it targets. The adapter maps
370
+ * the wire `AnnotationSummary` half-open entry range onto turn indices.
371
+ */
372
+ export type AnnotationVM = {
373
+ id: string;
374
+ /**
375
+ * e.g. "error" / "retry" / "revert" / "subagent"
376
+ */
377
+ kind: string;
378
+ /**
379
+ * target turn index
380
+ */
381
+ turn: number;
382
+ label: string;
383
+ preview?: string;
384
+ isPrimary?: boolean;
385
+ };
386
+ /**
387
+ * A manual label applied to a single turn (entry), in the general host-defined
388
+ * taxonomy shape (arbitrary `typeId`/`typeName`/`value`) — distinct from the
389
+ * composite viewer's own `SavedLabel` (state-capabilities.js), which is the
390
+ * narrower fixed outcome/flag shape `LabelPopover` writes into `savedLabels`.
391
+ * `TurnLabel` is the framework-agnostic wire shape a host app's own annotation
392
+ * model maps to/from when it manages labelling outside the composite viewer.
393
+ * `id` is empty for an optimistic, not-yet-persisted label.
394
+ */
395
+ export type TurnLabel = {
396
+ /**
397
+ * the entry index this label targets (`turn.index`)
398
+ */
399
+ entryIndex: number;
400
+ typeId: string;
401
+ typeName: string;
402
+ value: string;
403
+ /**
404
+ * host-assigned id; empty string for an optimistic pre-save
405
+ */
406
+ id: string;
407
+ };
408
+ /**
409
+ * One file in the Files tab, with cooked churn. The adapter aggregates per-file
410
+ * reads/writes/edits/deletes across all tool calls.
411
+ */
412
+ export type FileEntryVM = {
413
+ path: string;
414
+ /**
415
+ * basename for compact display
416
+ */
417
+ leaf: string;
418
+ reads: number;
419
+ writes: number;
420
+ edits: number;
421
+ deletes: number;
422
+ /**
423
+ * total insertions
424
+ */
425
+ adds: number;
426
+ /**
427
+ * total deletions
428
+ */
429
+ dels: number;
430
+ /**
431
+ * true if writes + edits > 0
432
+ */
433
+ edited: boolean;
434
+ /**
435
+ * first turn that touched the file
436
+ */
437
+ turn?: number;
438
+ };
439
+ /**
440
+ * One diff entry in the Diffs tab — a file change with its rendered hunks.
441
+ */
442
+ export type DiffEntryVM = {
443
+ path: string;
444
+ leaf: string;
445
+ adds: number;
446
+ dels: number;
447
+ hunks: DiffHunkVM[];
448
+ /**
449
+ * turn the edit happened on
450
+ */
451
+ turn?: number;
452
+ /**
453
+ * back-reference into toolCallsById
454
+ */
455
+ toolCallId?: string;
456
+ };
457
+ /**
458
+ * One task group for the trace outline / waterfall — a user-prompt boundary plus
459
+ * its derived per-task summary. The adapter computes boundaries off the turn
460
+ * stream; the optional analytics util can enrich this further.
461
+ */
462
+ export type TaskGroupVM = {
463
+ id: string;
464
+ /**
465
+ * 1-based task number
466
+ */
467
+ index: number;
468
+ /**
469
+ * user content for the task (case preserved)
470
+ */
471
+ prompt: string;
472
+ /**
473
+ * the prompt as its turn shows it, present only when it differs
474
+ */
475
+ displayPrompt?: string;
476
+ /**
477
+ * turns belonging to this task
478
+ */
479
+ turnIndices: number[];
480
+ durationMs?: number;
481
+ /**
482
+ * tool-call count in the task
483
+ */
484
+ tools?: number;
485
+ outcome?: "ok" | "error";
486
+ /**
487
+ * short error label when outcome === 'error'
488
+ */
489
+ error?: string;
490
+ /**
491
+ * cooked churn/files summary, e.g. "2 files, +316 −25" (render-when-present)
492
+ */
493
+ stat?: string;
494
+ };
495
+ /**
496
+ * One curated key-moment for the HIGHLIGHTS tab. `vm.highlights` BACKS this tab
497
+ * directly; the tab must render non-empty from it.
498
+ */
499
+ export type HighlightVM = {
500
+ id: string;
501
+ kind: "request" | "phase" | "error" | "checkpoint" | "final" | (string & {});
502
+ /**
503
+ * turn index this highlight points at
504
+ */
505
+ turn: number;
506
+ title: string;
507
+ sub?: string;
508
+ /**
509
+ * semantic icon key (consumer maps to a glyph)
510
+ */
511
+ icon?: string;
512
+ /**
513
+ * e.g. "+312 −24, 7 files"
514
+ */
515
+ stat?: string;
516
+ time?: string;
517
+ tokens?: string;
518
+ /**
519
+ * error styling
520
+ */
521
+ err?: boolean;
522
+ /**
523
+ * e.g. a phase id
524
+ */
525
+ tag?: string;
526
+ };
527
+ /**
528
+ * Precomputed indices the filters rail + search read, so no component recomputes
529
+ * counts or scans turns. Keyed maps are plain records (turn index / group id →
530
+ * value) for cheap, stable lookup.
531
+ */
532
+ export type FilterIndexVM = {
533
+ /**
534
+ * tool-group id → count
535
+ */
536
+ toolGroupCounts: Record<ToolGroup, number>;
537
+ /**
538
+ * turn index → annotations
539
+ */
540
+ annotationsByTurn: Record<number, AnnotationVM[]>;
541
+ /**
542
+ * semantic-tag ids present
543
+ */
544
+ tags: string[];
545
+ /**
546
+ * tag id → count
547
+ */
548
+ tagCounts: Record<string, number>;
549
+ totalTurns: number;
550
+ };
551
+ /**
552
+ * One scorecard axis band — the display verdict the analytics util derives from
553
+ * the raw `SessionScorecard` numeric signals.
554
+ */
555
+ export type ScorecardBandVM = {
556
+ /**
557
+ * axis id (e.g. token-efficiency)
558
+ */
559
+ id: string;
560
+ label: string;
561
+ band: "good" | "ok" | "watch" | "bad" | (string & {});
562
+ /**
563
+ * formatted headline value
564
+ */
565
+ value?: string;
566
+ /**
567
+ * single cooked sub-line (the lean analytics shape)
568
+ */
569
+ detail?: string;
570
+ /**
571
+ * semantic axis-icon key the consumer maps to a glyph (render-when-present)
572
+ */
573
+ icon?: string;
574
+ /**
575
+ * the per-axis flag LIST (render-when-present; richer than `detail` — a curated/backend nicety)
576
+ */
577
+ flags?: string[];
578
+ /**
579
+ * trend-vs-median delta (render-when-present)
580
+ */
581
+ delta?: {
582
+ dir: "up" | "down";
583
+ text: string;
584
+ };
585
+ };
586
+ /**
587
+ * One phase spanning a turn range, drawn as a divider in the trace.
588
+ */
589
+ export type PhaseVM = {
590
+ id: string;
591
+ label: string;
592
+ /**
593
+ * first turn index (inclusive)
594
+ */
595
+ from: number;
596
+ /**
597
+ * last turn index (inclusive)
598
+ */
599
+ to: number;
600
+ /**
601
+ * semantic icon key
602
+ */
603
+ icon?: string;
604
+ /**
605
+ * error count attributed to the phase
606
+ */
607
+ errors?: number;
608
+ };
609
+ /**
610
+ * The optional analytics block. The adapter accepts a precomputed
611
+ * `TranscriptAnalytics` (produced separately) OR derives it; when no
612
+ * analytics are available the WHOLE block is absent and every analytics-fed
613
+ * surface degrades cleanly. Each field is independently optional.
614
+ */
615
+ export type TranscriptAnalyticsVM = {
616
+ phases?: PhaseVM[];
617
+ scorecardBands?: ScorecardBandVM[];
618
+ /**
619
+ * detected patterns (errors/retries/reverts/subagents)
620
+ */
621
+ patternAnnotations?: AnnotationVM[];
622
+ /**
623
+ * analytics-enriched task grouping
624
+ */
625
+ taskGroups?: TaskGroupVM[];
626
+ };
627
+ /**
628
+ * The cooked transcript view model — the adapter's sole output and every
629
+ * component's prop contract. `analytics` and the git cluster are the only
630
+ * render-when-present pieces; everything else is always populated (possibly with
631
+ * empty arrays) so components never branch on existence for the core surfaces.
632
+ */
633
+ export type TranscriptViewModel = {
634
+ session: SessionVM;
635
+ turns: TurnVM[];
636
+ /**
637
+ * parsed once; turns reference the same objects
638
+ */
639
+ toolCallsById: Map<string, ToolCallVM>;
640
+ diffs: DiffEntryVM[];
641
+ files: FileEntryVM[];
642
+ tasks: TaskGroupVM[];
643
+ /**
644
+ * BACKS the HIGHLIGHTS tab (non-empty when present)
645
+ */
646
+ highlights: HighlightVM[];
647
+ filterIndex: FilterIndexVM;
648
+ /**
649
+ * render-when-present
650
+ */
651
+ analytics?: TranscriptAnalyticsVM;
652
+ /**
653
+ * authorized current-target navigation, cooked once
654
+ */
655
+ relationships?: RelationshipVM[];
656
+ /**
657
+ * separate index domains, collapsed by default
658
+ */
659
+ earlierHistory?: EarlierHistoryVM[];
660
+ /**
661
+ * non-conversational, including unattached records
662
+ */
663
+ nativeMetadata?: import("@peasant-labs/schema").NativeMetadataRecord[];
664
+ /**
665
+ * complete owner universe, before visible-turn filtering
666
+ */
667
+ usageScopes?: UsageScopeVM[];
668
+ };
669
+ export type UsageFieldVM = {
670
+ label: string;
671
+ /**
672
+ * exact known sum or unknown
673
+ */
674
+ value: string;
675
+ completeness: import("@peasant-labs/schema").UsageCompleteness;
676
+ };
677
+ export type UsageScopeVM = {
678
+ scope: import("@peasant-labs/schema").UsageScope;
679
+ ownerCount: number;
680
+ tokens: UsageFieldVM[];
681
+ cost: UsageFieldVM[];
682
+ };
683
+ export type RelationshipVM = {
684
+ kind: import("@peasant-labs/schema").SessionRelationshipKind;
685
+ label: string;
686
+ statusLabel: string;
687
+ note?: string;
688
+ /**
689
+ * only usable, authorized targets
690
+ */
691
+ navigation?: import("@peasant-labs/schema").SessionRelationshipNavigation;
692
+ };
693
+ export type EarlierHistoryVM = {
694
+ id: string;
695
+ state: import("@peasant-labs/schema").EarlierHistoryState;
696
+ explanation: string;
697
+ turns: TurnVM[];
698
+ nativeMetadata?: import("@peasant-labs/schema").NativeMetadataRecord[];
699
+ usageScopes: UsageScopeVM[];
700
+ };