@peasant-labs/fairtrade 0.0.61 → 0.0.63

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.
package/dist/lib/share.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { _ as e, c as t, g as n, h as r, m as i, p as a, v as o } from "./time-CpVBzcqQ.js";
2
2
  import { r as s } from "./format-B3uT2wzU.js";
3
- import { c, s as l, t as u } from "./adapter-BSfSbqWE.js";
3
+ import { l as c, t as l, u } from "./adapter-ChziRV1K.js";
4
4
  import { jsx as d, jsxs as f } from "react/jsx-runtime";
5
5
  //#region public/tokens.json
6
6
  var p = {
@@ -556,7 +556,7 @@ function y(e) {
556
556
  return s(e);
557
557
  }
558
558
  function ce(e, t) {
559
- return l({
559
+ return c({
560
560
  title: typeof e.title == "string" && e.title.trim() !== "" ? e.title.trim() : void 0,
561
561
  hasNormalizedEvidence: t.session.hasNormalizedEvidence,
562
562
  firstTaskPrompt: t.tasks?.[0]?.prompt,
@@ -570,11 +570,11 @@ function le(e) {
570
570
  if (typeof n.harness != "string" || !Array.isArray(n.turns)) return null;
571
571
  let r;
572
572
  try {
573
- r = u(n);
573
+ r = l(n);
574
574
  } catch {
575
575
  return null;
576
576
  }
577
- let i = r.session, a = ce(n, r), o = typeof i.harness == "string" ? i.harness : "", s = oe(o) ? t[o] : null, l = n.turns.find((e) => e?.role === "user" && (e.depth ?? 0) === 0), d = typeof l?.content == "string" ? l.content : "", f = ae(i.harness === "cursor" ? c(d) : d).trim(), p = f || a, m = i.inputSubmissionCount, h = i.totalTokens, g = !r.usageScopes?.length && h != null, _ = m != null && g ? {
577
+ let i = r.session, a = ce(n, r), o = typeof i.harness == "string" ? i.harness : "", s = oe(o) ? t[o] : null, c = n.turns.find((e) => e?.role === "user" && (e.depth ?? 0) === 0), d = typeof c?.content == "string" ? c.content : "", f = ae(i.harness === "cursor" ? u(d) : d).trim(), p = f || a, m = i.inputSubmissionCount, h = i.totalTokens, g = !r.usageScopes?.length && h != null, _ = m != null && g ? {
578
578
  prompts: Number(m),
579
579
  tokens: Number(h)
580
580
  } : null;
@@ -0,0 +1,208 @@
1
+ /**
2
+ * A host column.
3
+ *
4
+ * `id` is the host's closed-set member, so the table keys the column by `.wire`
5
+ * and never by a raw string. `render(row)` returns the cell content; the table
6
+ * owns only the cell and its alignment.
7
+ *
8
+ * @template Row
9
+ * @template {import('./closed-value.js').ClosedValue<string, string>} ColumnId
10
+ * @typedef {object} TranscriptLibraryColumn
11
+ * @property {ColumnId} id
12
+ * @property {string} label
13
+ * @property {import('./table/column-align.js').ColumnAlign} align
14
+ * @property {boolean} [numeric] pair counts and durations with tabular figures.
15
+ * @property {(row: Row) => import('react').ReactNode} render
16
+ */
17
+ /**
18
+ * One composed saved view: `groupBy` from the URL and `visibleColumns`/`collapsed`
19
+ * from the device. The host composes it; the table receives it and reports
20
+ * changes back, never reading a URL or storage itself.
21
+ *
22
+ * `visibleColumns` holds the known column members the table shows; the first
23
+ * declared column is the row identity and always shows. An unknown member is
24
+ * dropped when the view is reported back, so the host can rewrite its stored
25
+ * value. `collapsed` lists the qualified group ids the reader closed; an empty
26
+ * list opens every group. The list is page-independent: a collapse recorded on
27
+ * one page is the same qualified id on every page, so it never closes an
28
+ * unrelated group. The host composes both fields from the device and clears
29
+ * `collapsed` when `groupBy` changes; the table reports it unchanged.
30
+ *
31
+ * @template {import('./closed-value.js').ClosedValue<string, string>} GroupBy
32
+ * @template {import('./closed-value.js').ClosedValue<string, string>} ColumnId
33
+ * @typedef {object} SavedView
34
+ * @property {GroupBy} groupBy
35
+ * @property {readonly ColumnId[]} visibleColumns
36
+ * @property {readonly string[]} collapsed
37
+ */
38
+ /**
39
+ * A host offset page. `index` is the 1-based page the server returns (`page` on
40
+ * the wire), `size` is a schema `PageSize` member, and `total` counts
41
+ * transcripts, not rendered rows. `null` means the host renders a complete list:
42
+ * the table hides the pager and renders every row.
43
+ *
44
+ * @typedef {object} TranscriptLibraryPage
45
+ * @property {number} index
46
+ * @property {import('@peasant-labs/schema').PageSize} size
47
+ * @property {number} total
48
+ */
49
+ /**
50
+ * @template Row
51
+ * @template {import('./closed-value.js').ClosedValue<string, string>} GroupBy
52
+ * @template {import('./closed-value.js').ClosedValue<string, string>} ColumnId
53
+ * @typedef {object} TranscriptLibraryTableProps
54
+ * @property {string} caption
55
+ * @property {readonly Row[]} rows
56
+ * @property {(row: Row) => string} rowKey required: the host supplies a stable key; the table never derives one.
57
+ * @property {readonly TranscriptLibraryColumn<Row, ColumnId>[]} columns every host column, in declaration order; the first column is the row identity and always shows.
58
+ * @property {GroupBy} groupBy the host default grouping, used when no saved view names a known member.
59
+ * @property {readonly GroupBy[]} [groupByOptions] the grouping members the picker offers; defaults to `[groupBy]`.
60
+ * @property {(row: Row) => readonly string[]} groupKeys bare keys, such as [row.projectHash].
61
+ * @property {(groupId: string) => string} groupLabel receives `${groupBy.wire}:${key}`.
62
+ * @property {readonly string[] | null} nextGroupKeys bare keys from `page.nextItems`, or null.
63
+ * @property {readonly string[] | null} continuedGroupKeys bare keys from the previous page, or null.
64
+ * @property {TranscriptLibraryPage | null} page
65
+ * @property {SavedView<GroupBy, ColumnId> | null} [viewState] the host's composed grouping, columns, and collapsed groups; a known saved view wins over the host default.
66
+ * @property {(view: SavedView<GroupBy, ColumnId>) => void} [onViewStateChange]
67
+ * @property {(index: number) => void} [onPageChange]
68
+ * @property {(size: import('@peasant-labs/schema').PageSize) => void} [onPageSizeChange]
69
+ * @property {import('react').ReactNode} [emptyState]
70
+ */
71
+ /**
72
+ * The resolved saved view the table renders: the host's saved view read against
73
+ * the columns and grouping members this table actually knows. An unknown member
74
+ * falls back to the host default rather than rendering an empty or broken view.
75
+ *
76
+ * @template {import('./closed-value.js').ClosedValue<string, string>} GroupBy
77
+ * @template {import('./closed-value.js').ClosedValue<string, string>} ColumnId
78
+ * @typedef {object} ResolvedSavedView
79
+ * @property {GroupBy} groupBy
80
+ * @property {readonly GroupBy[]} groupByOptions
81
+ * @property {readonly ColumnId[]} visibleColumns
82
+ * @property {readonly string[]} collapsed the qualified group ids the reader closed.
83
+ */
84
+ /**
85
+ * The canonical transcript library table: one real table with a caption, host
86
+ * columns, group header rows, a compact continuation row for a group that began
87
+ * on an earlier page, a numbered pager, and an end-of-page marker for a group
88
+ * that continues.
89
+ *
90
+ * The table is controlled. It renders the rows, page, and view it is given and
91
+ * reports changes; it holds no storage, reads no URL, and never resets a page.
92
+ * A saved view (when given) supplies the grouping, the visible columns, and the
93
+ * collapsed groups; without one every column shows, every group is open, and the two
94
+ * pickers are absent because they would have nothing to report to.
95
+ *
96
+ * @template Row
97
+ * @template {import('./closed-value.js').ClosedValue<string, string>} GroupBy
98
+ * @template {import('./closed-value.js').ClosedValue<string, string>} ColumnId
99
+ * @param {TranscriptLibraryTableProps<Row, GroupBy, ColumnId>} props
100
+ */
101
+ export function TranscriptLibraryTable<Row, GroupBy extends import("./closed-value.js").ClosedValue<string, string>, ColumnId extends import("./closed-value.js").ClosedValue<string, string>>({ caption, rows, rowKey, columns, groupBy, groupByOptions, groupKeys, groupLabel, nextGroupKeys, continuedGroupKeys, page, viewState, onViewStateChange, emptyState, onPageChange, onPageSizeChange, }: TranscriptLibraryTableProps<Row, GroupBy, ColumnId>): import("react").JSX.Element;
102
+ /**
103
+ * A host column.
104
+ *
105
+ * `id` is the host's closed-set member, so the table keys the column by `.wire`
106
+ * and never by a raw string. `render(row)` returns the cell content; the table
107
+ * owns only the cell and its alignment.
108
+ */
109
+ export type TranscriptLibraryColumn<Row, ColumnId extends import("./closed-value.js").ClosedValue<string, string>> = {
110
+ id: ColumnId;
111
+ label: string;
112
+ align: import("./table/column-align.js").ColumnAlign;
113
+ /**
114
+ * pair counts and durations with tabular figures.
115
+ */
116
+ numeric?: boolean;
117
+ render: (row: Row) => import("react").ReactNode;
118
+ };
119
+ /**
120
+ * One composed saved view: `groupBy` from the URL and `visibleColumns`/`collapsed`
121
+ * from the device. The host composes it; the table receives it and reports
122
+ * changes back, never reading a URL or storage itself.
123
+ *
124
+ * `visibleColumns` holds the known column members the table shows; the first
125
+ * declared column is the row identity and always shows. An unknown member is
126
+ * dropped when the view is reported back, so the host can rewrite its stored
127
+ * value. `collapsed` lists the qualified group ids the reader closed; an empty
128
+ * list opens every group. The list is page-independent: a collapse recorded on
129
+ * one page is the same qualified id on every page, so it never closes an
130
+ * unrelated group. The host composes both fields from the device and clears
131
+ * `collapsed` when `groupBy` changes; the table reports it unchanged.
132
+ */
133
+ export type SavedView<GroupBy extends import("./closed-value.js").ClosedValue<string, string>, ColumnId extends import("./closed-value.js").ClosedValue<string, string>> = {
134
+ groupBy: GroupBy;
135
+ visibleColumns: readonly ColumnId[];
136
+ collapsed: readonly string[];
137
+ };
138
+ /**
139
+ * A host offset page. `index` is the 1-based page the server returns (`page` on
140
+ * the wire), `size` is a schema `PageSize` member, and `total` counts
141
+ * transcripts, not rendered rows. `null` means the host renders a complete list:
142
+ * the table hides the pager and renders every row.
143
+ */
144
+ export type TranscriptLibraryPage = {
145
+ index: number;
146
+ size: import("@peasant-labs/schema").PageSize;
147
+ total: number;
148
+ };
149
+ export type TranscriptLibraryTableProps<Row, GroupBy extends import("./closed-value.js").ClosedValue<string, string>, ColumnId extends import("./closed-value.js").ClosedValue<string, string>> = {
150
+ caption: string;
151
+ rows: readonly Row[];
152
+ /**
153
+ * required: the host supplies a stable key; the table never derives one.
154
+ */
155
+ rowKey: (row: Row) => string;
156
+ /**
157
+ * every host column, in declaration order; the first column is the row identity and always shows.
158
+ */
159
+ columns: readonly TranscriptLibraryColumn<Row, ColumnId>[];
160
+ /**
161
+ * the host default grouping, used when no saved view names a known member.
162
+ */
163
+ groupBy: GroupBy;
164
+ /**
165
+ * the grouping members the picker offers; defaults to `[groupBy]`.
166
+ */
167
+ groupByOptions?: readonly GroupBy[];
168
+ /**
169
+ * bare keys, such as [row.projectHash].
170
+ */
171
+ groupKeys: (row: Row) => readonly string[];
172
+ /**
173
+ * receives `${groupBy.wire}:${key}`.
174
+ */
175
+ groupLabel: (groupId: string) => string;
176
+ /**
177
+ * bare keys from `page.nextItems`, or null.
178
+ */
179
+ nextGroupKeys: readonly string[] | null;
180
+ /**
181
+ * bare keys from the previous page, or null.
182
+ */
183
+ continuedGroupKeys: readonly string[] | null;
184
+ page: TranscriptLibraryPage | null;
185
+ /**
186
+ * the host's composed grouping, columns, and collapsed groups; a known saved view wins over the host default.
187
+ */
188
+ viewState?: SavedView<GroupBy, ColumnId> | null;
189
+ onViewStateChange?: (view: SavedView<GroupBy, ColumnId>) => void;
190
+ onPageChange?: (index: number) => void;
191
+ onPageSizeChange?: (size: import("@peasant-labs/schema").PageSize) => void;
192
+ emptyState?: import("react").ReactNode;
193
+ };
194
+ /**
195
+ * The resolved saved view the table renders: the host's saved view read against
196
+ * the columns and grouping members this table actually knows. An unknown member
197
+ * falls back to the host default rather than rendering an empty or broken view.
198
+ */
199
+ export type ResolvedSavedView<GroupBy extends import("./closed-value.js").ClosedValue<string, string>, ColumnId extends import("./closed-value.js").ClosedValue<string, string>> = {
200
+ groupBy: GroupBy;
201
+ groupByOptions: readonly GroupBy[];
202
+ visibleColumns: readonly ColumnId[];
203
+ /**
204
+ * the qualified group ids the reader closed.
205
+ */
206
+ collapsed: readonly string[];
207
+ };
208
+ export { groupPageRows, groupKeysFor } from "./groupPageRows.js";
@@ -0,0 +1,56 @@
1
+ /**
2
+ * One rendered group.
3
+ *
4
+ * - `id` is `${groupBy.wire}:${key}`, or `''` for rows that name no group.
5
+ * - `label` is what `groupLabel(id)` returned; `''` for the ungrouped bucket.
6
+ * - `continued` means this group began on the previous page.
7
+ * - `continues` means this group has rows on the next page.
8
+ *
9
+ * @template Row
10
+ * @typedef {object} TranscriptLibraryGroup
11
+ * @property {string} id
12
+ * @property {string} label
13
+ * @property {readonly Row[]} rows
14
+ * @property {boolean} continued
15
+ * @property {boolean} continues
16
+ */
17
+ /**
18
+ * Group one page of rows.
19
+ *
20
+ * @template Row
21
+ * @template {import('./closed-value.js').ClosedValue<string, string>} GroupBy
22
+ * @param {readonly Row[]} rows - the host's page rows, in display order.
23
+ * @param {GroupBy} groupBy - the host's grouping member; only `.wire` is read.
24
+ * @param {(row: Row) => readonly string[]} groupKeys - bare group keys for a row.
25
+ * @param {(groupId: string) => string} groupLabel - label for a qualified group id.
26
+ * @param {readonly string[] | null} nextGroupKeys - bare keys of `page.nextItems`, or null.
27
+ * @param {readonly string[] | null} [continuedGroupKeys] - bare keys of the previous page, or null.
28
+ * @returns {readonly TranscriptLibraryGroup<Row>[]}
29
+ */
30
+ export function groupPageRows<Row, GroupBy extends import("./closed-value.js").ClosedValue<string, string>>(rows: readonly Row[], groupBy: GroupBy, groupKeys: (row: Row) => readonly string[], groupLabel: (groupId: string) => string, nextGroupKeys: readonly string[] | null, continuedGroupKeys?: readonly string[] | null): readonly TranscriptLibraryGroup<Row>[];
31
+ /**
32
+ * The union of every row's bare group keys, de-duplicated in first-appearance
33
+ * order. A host uses it for `nextGroupKeys` (over `page.nextItems`) and for
34
+ * `continuedGroupKeys` (over the previous page it holds).
35
+ *
36
+ * @template Row
37
+ * @param {readonly Row[]} rows
38
+ * @param {(row: Row) => readonly string[]} groupKeys
39
+ * @returns {readonly string[]}
40
+ */
41
+ export function groupKeysFor<Row>(rows: readonly Row[], groupKeys: (row: Row) => readonly string[]): readonly string[];
42
+ /**
43
+ * One rendered group.
44
+ *
45
+ * - `id` is `${groupBy.wire}:${key}`, or `''` for rows that name no group.
46
+ * - `label` is what `groupLabel(id)` returned; `''` for the ungrouped bucket.
47
+ * - `continued` means this group began on the previous page.
48
+ * - `continues` means this group has rows on the next page.
49
+ */
50
+ export type TranscriptLibraryGroup<Row> = {
51
+ id: string;
52
+ label: string;
53
+ rows: readonly Row[];
54
+ continued: boolean;
55
+ continues: boolean;
56
+ };
@@ -30,6 +30,11 @@ export { default as RepoPicker } from "./RepoPicker.jsx";
30
30
  export { default as VillageObservations } from "./VillageObservations.jsx";
31
31
  export * from "./transcript/index.js";
32
32
  export * from "./transcript/graph/index.js";
33
+ export type SavedView<GroupBy extends import("./closed-value.js").ClosedValue<string, string>, ColumnId extends import("./closed-value.js").ClosedValue<string, string>> = import("./TranscriptLibraryTable.jsx").SavedView<GroupBy, ColumnId>;
34
+ export type TranscriptLibraryColumn<Row, ColumnId extends import("./closed-value.js").ClosedValue<string, string>> = import("./TranscriptLibraryTable.jsx").TranscriptLibraryColumn<Row, ColumnId>;
35
+ export type TranscriptLibraryTableProps<Row, GroupBy extends import("./closed-value.js").ClosedValue<string, string>, ColumnId extends import("./closed-value.js").ClosedValue<string, string>> = import("./TranscriptLibraryTable.jsx").TranscriptLibraryTableProps<Row, GroupBy, ColumnId>;
36
+ export type TranscriptLibraryPage = import("./TranscriptLibraryTable.jsx").TranscriptLibraryPage;
37
+ export type TranscriptLibraryGroup<Row> = import("./groupPageRows.js").TranscriptLibraryGroup<Row>;
33
38
  export type TimelineNavigationAction = import("./graph/timelineNavigation.js").TimelineNavigationAction;
34
39
  export type AppSidebarProps = import("./AppSidebar.jsx").AppSidebarProps;
35
40
  export type AppSidebarLayoutProps = import("./AppSidebar.jsx").AppSidebarLayoutProps;
@@ -59,6 +64,8 @@ export { formatCount, formatInteger, formatCost, formatDecimal, MISSING_NUMBER }
59
64
  export { providerAccent, providerDisplayName } from "./provider-policy.js";
60
65
  export { Skeleton, Progress, Spinner, Toast, FeedbackPanel } from "./Feedback.jsx";
61
66
  export { DataTableToolbar, DataTablePaginationControls } from "./DataTableControls.jsx";
67
+ export { TranscriptLibraryTable, groupPageRows, groupKeysFor } from "./TranscriptLibraryTable.jsx";
68
+ export { ColumnAlign, ALL_COLUMN_ALIGNS, parseColumnAlign } from "./table/column-align.js";
62
69
  export { default as HelperGroup, HelperGroupListItem, HelperThreadRow, useHelperSelection, helperOwnerState, helperSelectionIds, helperOwnerToggle, helperMemberToggle, HELPER_OWNER_STATE } from "./HelperGroup.jsx";
63
70
  export { default as Timeline, TimelineItem, ToolCall, ThinkingBlock } from "./Timeline.jsx";
64
71
  export { default as ToastProvider, useToast } from "./ToastHost.jsx";
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @param {string} base the cell or header class.
3
+ * @param {'left' | 'right' | 'center' | 'decimal'} align
4
+ * @returns {string}
5
+ */
6
+ export function alignClass(base: string, align: "left" | "right" | "center" | "decimal"): string;
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Resolve a persisted or host-supplied alignment to its member.
3
+ *
4
+ * Accepts a member (returned unchanged) or its wire value as a string. A label is
5
+ * not accepted: labels are chrome and may change, while the wire value is the
6
+ * stable identity. An unknown value throws rather than silently defaulting,
7
+ * because a silent default hides a host that drifted from this set.
8
+ *
9
+ * @param {unknown} raw - a `ColumnAlign` member or its wire value.
10
+ * @returns {ColumnAlign}
11
+ */
12
+ export function parseColumnAlign(raw: unknown): ColumnAlign;
13
+ /**
14
+ * The member type union; every value member is a `ColumnAlign`.
15
+ */
16
+ export type ColumnAlign = (typeof ColumnAlignValues)[keyof typeof ColumnAlignValues];
17
+ /**
18
+ * The alignment a host column declares.
19
+ *
20
+ * - `Start` is left-aligned in a left-to-right grid.
21
+ * - `End` is right-aligned; counts and durations pair it with `numeric`.
22
+ * - `Center` is centered.
23
+ * - `Decimal` right-aligns with tabular numbers. A decimal-point span is
24
+ * `DataTable`'s own; this table does not export it.
25
+ */
26
+ export const ColumnAlign: Readonly<{
27
+ Start: import("../closed-value.js").ClosedValue<"start", "start">;
28
+ End: import("../closed-value.js").ClosedValue<"end", "end">;
29
+ Center: import("../closed-value.js").ClosedValue<"center", "center">;
30
+ Decimal: import("../closed-value.js").ClosedValue<"decimal", "decimal">;
31
+ }>;
32
+ /**
33
+ * The member type union; every value member is a `ColumnAlign`.
34
+ * @typedef {(typeof ColumnAlignValues)[keyof typeof ColumnAlignValues]} ColumnAlign
35
+ */
36
+ /** Every alignment member, in the order a surface lists them. */
37
+ export const ALL_COLUMN_ALIGNS: readonly (import("../closed-value.js").ClosedValue<"start", "start"> | import("../closed-value.js").ClosedValue<"end", "end"> | import("../closed-value.js").ClosedValue<"center", "center"> | import("../closed-value.js").ClosedValue<"decimal", "decimal">)[];
38
+ declare const ColumnAlignValues: Readonly<{
39
+ Start: import("../closed-value.js").ClosedValue<"start", "start">;
40
+ End: import("../closed-value.js").ClosedValue<"end", "end">;
41
+ Center: import("../closed-value.js").ClosedValue<"center", "center">;
42
+ Decimal: import("../closed-value.js").ClosedValue<"decimal", "decimal">;
43
+ }>;
44
+ export {};
@@ -0,0 +1,50 @@
1
+ /**
2
+ * The group-by picker. The trigger names the current grouping, and each offered
3
+ * member is a native radio, so the chosen row is announced as checked.
4
+ *
5
+ * @param {object} props
6
+ * @param {readonly { wire: string, label: string }[]} props.options the host's grouping members.
7
+ * @param {{ wire: string, label: string }} props.value the active grouping member.
8
+ * @param {(next: { wire: string, label: string }) => void} props.onChange receives the chosen member.
9
+ */
10
+ export function GroupByPicker({ options, value, onChange }: {
11
+ options: readonly {
12
+ wire: string;
13
+ label: string;
14
+ }[];
15
+ value: {
16
+ wire: string;
17
+ label: string;
18
+ };
19
+ onChange: (next: {
20
+ wire: string;
21
+ label: string;
22
+ }) => void;
23
+ }): import("react").JSX.Element;
24
+ /**
25
+ * The column picker. The trigger names how many columns show, and every column is
26
+ * a native checkbox. The first declared column is the row identity and always
27
+ * shows, so its checkbox is checked and disabled; the label says why.
28
+ *
29
+ * @param {object} props
30
+ * @param {readonly { id: { wire: string }, label: string }[]} props.columns every host column, in declaration order.
31
+ * @param {readonly { wire: string }[]} props.visibleColumns the columns the saved view shows.
32
+ * @param {(column: { id: { wire: string }, label: string }, checked: boolean) => void} props.onChange receives the toggled column and whether it was checked before the change.
33
+ */
34
+ export function ColumnPicker({ columns, visibleColumns, onChange }: {
35
+ columns: readonly {
36
+ id: {
37
+ wire: string;
38
+ };
39
+ label: string;
40
+ }[];
41
+ visibleColumns: readonly {
42
+ wire: string;
43
+ }[];
44
+ onChange: (column: {
45
+ id: {
46
+ wire: string;
47
+ };
48
+ label: string;
49
+ }, checked: boolean) => void;
50
+ }): import("react").JSX.Element;
@@ -1,17 +1,31 @@
1
1
  /** @typedef {import('./view-model.js').TurnVM} TurnVM */
2
2
  /**
3
3
  * @param {object} props
4
- * @param {TurnVM[]} [props.turns]
4
+ * @param {TurnVM[]} [props.turns] legacy turn mode
5
+ * @param {ScrubberTick[]} [props.ticks] segment sample; takes precedence over `turns`
5
6
  * @param {number} [props.active] the active TURN INDEX (TurnVM.index)
7
+ * @param {number} [props.activeTick] the active SEGMENT INDEX when `ticks` is supplied
6
8
  * @param {(clientX: number, track: HTMLElement) => void} [props.onSeek]
9
+ * @param {(tick: ScrubberTick) => void} [props.onSeekTick]
7
10
  * @param {{ current: boolean }} [props.draggingRef] shared drag latch; defaults to an internal ref
8
11
  */
9
- export default function Scrubber({ turns, active, onSeek, draggingRef }: {
12
+ export default function Scrubber({ turns, ticks, active, activeTick, onSeek, onSeekTick, draggingRef }: {
10
13
  turns?: TurnVM[];
14
+ ticks?: ScrubberTick[];
11
15
  active?: number;
16
+ activeTick?: number;
12
17
  onSeek?: (clientX: number, track: HTMLElement) => void;
18
+ onSeekTick?: (tick: ScrubberTick) => void;
13
19
  draggingRef?: {
14
20
  current: boolean;
15
21
  };
16
22
  }): import("react").JSX.Element;
17
23
  export type TurnVM = import("./view-model.js").TurnVM;
24
+ export type ScrubberTick = {
25
+ key: string;
26
+ index: number;
27
+ firstTurn: number;
28
+ lastTurn: number;
29
+ label: string;
30
+ leftPct: number;
31
+ };
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @param {object} props
3
+ * @param {SegmentBoundaryVM} props.boundary
4
+ * @param {(segmentIndex: number) => void} [props.onLoadMore]
5
+ * @param {boolean} [props.loading] the host is fetching the adjacent segment
6
+ */
7
+ export default function TranscriptBoundary({ boundary, onLoadMore, loading }: {
8
+ boundary: SegmentBoundaryVM;
9
+ onLoadMore?: (segmentIndex: number) => void;
10
+ loading?: boolean;
11
+ }): import("react").JSX.Element;
12
+ /** @typedef {import('./segments.js').SegmentBoundaryVM} SegmentBoundaryVM */
13
+ /** Thrown when a host mounts the boundary without the unloaded-edge descriptor. */
14
+ export class TranscriptSegmentBoundaryError extends Error {
15
+ /**
16
+ * @param {string} message
17
+ */
18
+ constructor(message: string);
19
+ }
20
+ export type SegmentBoundaryVM = import("./segments.js").SegmentBoundaryVM;
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @param {TranscriptViewerProps} props
3
3
  */
4
- export default function TranscriptViewer({ viewModel, capabilities, callbacks, theme: themeProp, onThemeChange, graphSlot, activeTab: activeTabProp, onTabChange, viewMode: viewModeProp, onViewModeChange, sidebarLayout: sidebarLayoutProp, onSidebarLayoutChange, zen: zenProp, onZenChange, readerWidth: readerWidthProp, onReaderWidthChange, leftRailOpen: leftRailOpenProp, onLeftRailOpenChange, rightRailOpen: rightRailOpenProp, onRightRailOpenChange, openTools: openToolsProp, onOpenToolsChange, earlierHistoryOpen: earlierHistoryOpenProp, onEarlierHistoryOpenChange, initialPosition: initialPositionProp, activeTurn: activeTurnProp, onActiveTurnChange, search: searchProp, onSearchChange, filters: filtersProp, onFiltersChange, savedLabels: savedLabelsProp, onSavedLabelsChange, shareOpen: shareOpenProp, onShareOpenChange, moreOpen: moreOpenProp, onMoreOpenChange, breadcrumb, breadcrumbContext, beforeHeader, LinkComponent, renderTurnPanel, renderTurnActions, anchorHref, headerActions, utilityActions, streamPrelude, showTail, showOutcome, showSearchTrigger, footer, presentation, subtitle, pullRequests, headingLevel, integrity, transcriptContentHash, contentHash, }: TranscriptViewerProps): import("react").JSX.Element;
4
+ export default function TranscriptViewer({ viewModel, capabilities, callbacks, theme: themeProp, onThemeChange, graphSlot, activeTab: activeTabProp, onTabChange, viewMode: viewModeProp, onViewModeChange, sidebarLayout: sidebarLayoutProp, onSidebarLayoutChange, zen: zenProp, onZenChange, readerWidth: readerWidthProp, onReaderWidthChange, leftRailOpen: leftRailOpenProp, onLeftRailOpenChange, rightRailOpen: rightRailOpenProp, onRightRailOpenChange, openTools: openToolsProp, onOpenToolsChange, earlierHistoryOpen: earlierHistoryOpenProp, onEarlierHistoryOpenChange, initialPosition: initialPositionProp, activeTurn: activeTurnProp, onActiveTurnChange, search: searchProp, onSearchChange, filters: filtersProp, onFiltersChange, savedLabels: savedLabelsProp, onSavedLabelsChange, shareOpen: shareOpenProp, onShareOpenChange, moreOpen: moreOpenProp, onMoreOpenChange, breadcrumb, breadcrumbContext, beforeHeader, LinkComponent, renderTurnPanel, renderTurnActions, anchorHref, headerActions, utilityActions, streamPrelude, showTail, showOutcome, showSearchTrigger, footer, presentation, subtitle, pullRequests, headingLevel, integrity, transcriptContentHash, contentHash, directory, segments: segmentsProp, window: windowProp, onLoadSegment, onLoadWindow, }: TranscriptViewerProps): import("react").JSX.Element;
5
5
  export const READER_FULL: "full";
6
6
  export type TranscriptViewerProps = import("./state-capabilities.js").TranscriptViewerProps;
7
7
  export type TranscriptFilters = import("./state-capabilities.js").TranscriptFilters;
@@ -1,4 +1,8 @@
1
- /** Stable source user boundaries, followed by visibility projection. No hidden part is restored.
1
+ /** Runs follow the source prose, not the filtered projection, so a hidden turn never moves a
2
+ * later action forward. Each prose turn starts its own run; a wordless turn appends to the
3
+ * current run; a user turn closes it; a system turn stays where it is and does not split it.
4
+ * A run without a renderable prose anchor keeps its work at the run's first visible work turn,
5
+ * and a run with no work draws no block. No hidden part is restored.
2
6
  * @param {import('./view-model.js').TurnVM[]} turns
3
7
  * @param {import('./view-model.js').TurnVM[]} visibleTurns
4
8
  */
@@ -20,6 +20,22 @@ export function thinkingDurationMs(previous: TurnDetail | undefined, turn: TurnD
20
20
  * @returns {TurnDetail[]}
21
21
  */
22
22
  export function prefilterTurns(turns: TurnDetail[]): TurnDetail[];
23
+ /** @param {TurnVM[]} turnVMs @returns {FileEntryVM[]} */
24
+ /**
25
+ * Aggregate the per-file read/edit/write counts and churn from cooked turns. Shared
26
+ * by the whole-transcript view model and a segmented viewer's loaded regions, so the
27
+ * Files tab has one derivation.
28
+ * @param {TurnVM[]} turnVMs
29
+ * @returns {FileEntryVM[]}
30
+ */
31
+ export function buildFiles(turnVMs: TurnVM[]): FileEntryVM[];
32
+ /**
33
+ * Tool-group counts for a set of cooked turns. Shared by the full filter index and a
34
+ * segmented viewer's loaded regions.
35
+ * @param {TurnVM[]} turnVMs
36
+ * @returns {Record<ToolGroup, number>}
37
+ */
38
+ export function buildToolGroupCounts(turnVMs: TurnVM[]): Record<ToolGroup, number>;
23
39
  /**
24
40
  * Project the canonical wire payload (folded turns) into the cooked
25
41
  * `TranscriptViewModel` every dumb transcript component renders. The SOLE
@@ -22,6 +22,7 @@ export { default as TranscriptCheckRow } from "./CheckRow.jsx";
22
22
  export { default as TranscriptViewSwitch } from "./ViewSwitch.jsx";
23
23
  export { default as TranscriptMinimap } from "./Minimap.jsx";
24
24
  export { default as TranscriptScrubber } from "./Scrubber.jsx";
25
+ export { default as TranscriptSegmentBoundary } from "./TranscriptBoundary.jsx";
25
26
  export { default as TranscriptScorecard } from "./Scorecard.jsx";
26
27
  export { default as TranscriptLabelPopover } from "./LabelPopover.jsx";
27
28
  export { default as useTranscriptInitialPosition } from "./useTranscriptInitialPosition.jsx";
@@ -44,6 +45,12 @@ export type SessionScorecard = import("./wire-types.js").SessionScorecard;
44
45
  export type CommitInfo = import("./wire-types.js").CommitInfo;
45
46
  export type AnnotationSummary = import("./wire-types.js").AnnotationSummary;
46
47
  export type SessionDetailPayload = import("./wire-types.js").SessionDetailPayload;
48
+ export type TranscriptSegmentDirectory = import("./wire-types.js").TranscriptSegmentDirectory;
49
+ export type TranscriptSegmentRef = import("./wire-types.js").TranscriptSegmentRef;
50
+ export type TranscriptSegment = import("./wire-types.js").TranscriptSegment;
51
+ export type TranscriptTurn = import("./wire-types.js").TranscriptTurn;
52
+ export type TranscriptWindow = import("./wire-types.js").TranscriptWindow;
53
+ export type SessionDetailHeaderPayload = import("./wire-types.js").SessionDetailHeaderPayload;
47
54
  export type TranscriptWireInput = import("./wire-types.js").TranscriptWireInput;
48
55
  export type TranscriptViewerProps = import("./state-capabilities.js").TranscriptViewerProps;
49
56
  export type TranscriptInitialPosition = import("./state-capabilities.js").TranscriptInitialPosition;
@@ -59,6 +66,12 @@ export type Presentation = import("./state-capabilities.js").Presentation;
59
66
  export type TranscriptTab = import("./state-capabilities.js").TranscriptTab;
60
67
  export type ViewMode = import("./state-capabilities.js").ViewMode;
61
68
  export type TranscriptViewModel = import("./view-model.js").TranscriptViewModel;
69
+ export type SegmentDirectoryVM = import("./segments.js").SegmentDirectoryVM;
70
+ export type SegmentRefVM = import("./segments.js").SegmentRefVM;
71
+ export type SegmentVM = import("./segments.js").SegmentVM;
72
+ export type SegmentWindowVM = import("./segments.js").SegmentWindowVM;
73
+ export type SegmentRegionVM = import("./segments.js").SegmentRegionVM;
74
+ export type SegmentBoundaryVM = import("./segments.js").SegmentBoundaryVM;
62
75
  export type RelationshipVM = import("./view-model.js").RelationshipVM;
63
76
  export type EarlierHistoryVM = import("./view-model.js").EarlierHistoryVM;
64
77
  export type AdaptTranscriptOptions = import("./adapter.js").AdaptTranscriptOptions;
@@ -82,10 +95,11 @@ export type PhaseVM = import("./view-model.js").PhaseVM;
82
95
  export type ScorecardBandVM = import("./view-model.js").ScorecardBandVM;
83
96
  export type TranscriptAnalyticsVM = import("./view-model.js").TranscriptAnalyticsVM;
84
97
  export { ROLES, ENTRY_TYPES, TOOL_CALL_KINDS, STOP_REASONS, SESSION_OUTCOMES, HARNESSES } from "./wire-types.js";
85
- export { adaptTranscript, prefilterTurns, diffLines } from "./adapter.js";
98
+ export { adaptTranscript, prefilterTurns, diffLines, buildFiles, buildToolGroupCounts } from "./adapter.js";
86
99
  export { computeTasks, computeTurnLabels, buildTaskWaterfall, annotateTranscript, computePersonalMedians, detectPhases, assessScorecard, computeAnalytics, computeTaskGroups, phaseLabel } from "./analytics.js";
87
100
  export { formatRelative, formatDurationMins, formatDurationMs, formatDurationSeconds, formatDateLong, isKnownTime } from "./time.js";
88
101
  export { summarizePrompt, composeSessionTitle, projectLabel, cleanSessionTitle, unwrapUserQuery } from "./title.js";
89
102
  export { default as TranscriptDiffEntryCard, DiffHunks as TranscriptDiffHunks } from "./DiffEntryCard.jsx";
90
103
  export { default as TranscriptViewer, READER_FULL } from "./TranscriptViewer.jsx";
104
+ export { SEGMENT_SCRUBBER_TICKS, SEGMENT_OVERSCAN_TURNS, boundaryCaption, formatByteExtent, loadedFiles, loadedRegions, loadedScope, loadedToolGroupCounts, mountedCardBound, normaliseSegments, regionBoundaries, scrubberTicks, turnsFromSegments, windowCoverage } from "./segments.js";
91
105
  export { advanceTranscriptInitialPositionConsumption, normalizeTranscriptInitialPosition, resolveTranscriptInitialPosition, shouldApplyTranscriptInitialPosition, transcriptInitialPositionReadiness, transcriptInitialPositionToken } from "./initial-position.js";