@peasant-labs/fairtrade 0.0.25 → 0.0.27

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 (34) hide show
  1. package/dist/lib/{GraphLegend-sgixmPER.js → GraphLegend-kO2WP4yM.js} +1248 -1162
  2. package/dist/lib/analytics.css +1 -1
  3. package/dist/lib/analytics.js +29 -21
  4. package/dist/lib/base.css +4 -2
  5. package/dist/lib/commons.js +815 -829
  6. package/dist/lib/components.css +1 -1
  7. package/dist/lib/fonts.css +19 -21
  8. package/dist/lib/graph.css +1 -1
  9. package/dist/lib/graph.js +418 -420
  10. package/dist/lib/tokens.css +7 -4
  11. package/dist/lib/tokens.json +20 -7
  12. package/dist/lib/types/BrandMark.d.ts +2 -2
  13. package/dist/lib/types/ConnectionState.d.ts +2 -2
  14. package/dist/lib/types/DataTable.d.ts +74 -10
  15. package/dist/lib/types/DiffView.d.ts +1 -1
  16. package/dist/lib/types/GroupedMultiSelect.d.ts +1 -1
  17. package/dist/lib/types/HelperGroup.d.ts +3 -3
  18. package/dist/lib/types/Publish.d.ts +4 -4
  19. package/dist/lib/types/Redaction.d.ts +2 -2
  20. package/dist/lib/types/Settings.d.ts +6 -0
  21. package/dist/lib/types/Timeline.d.ts +5 -5
  22. package/dist/lib/types/analytics/format.d.ts +5 -5
  23. package/dist/lib/types/format.d.ts +4 -0
  24. package/dist/lib/types/index.d.ts +1 -1
  25. package/dist/lib/types/redaction-categories.d.ts +17 -0
  26. package/dist/lib/types/transcript/TurnCard.d.ts +3 -1
  27. package/dist/lib/types/transcript/scroll-position.d.ts +10 -0
  28. package/dist/lib/types/transcript/state-capabilities.d.ts +1 -1
  29. package/dist/lib/types/transcript/title.d.ts +1 -1
  30. package/dist/lib/types/transcript/view-model.d.ts +2 -2
  31. package/dist/lib/ui-Y-iKXft1.js +14076 -0
  32. package/dist/lib/ui.js +4 -4
  33. package/package.json +17 -9
  34. package/dist/lib/ui-C2WXsEFz.js +0 -23542
@@ -23,6 +23,8 @@
23
23
  --stroke-hairline: 1px;
24
24
  --stroke-emphasis: 2px;
25
25
  --focus-ring-width: 3px;
26
+ --focus-ring-offset: 2px;
27
+ --focus-ring-offset-inset: calc(-1 * var(--focus-ring-width));
26
28
  --ghost-node-size: 9px;
27
29
  --control-h: 36px;
28
30
  --control-h-sm: 28px;
@@ -43,7 +45,6 @@
43
45
  --fs-xl: 28px;
44
46
  --fs-hero: 40px;
45
47
  --fs-display: 52px;
46
- --fs-micro: 11px;
47
48
  --menu-min-w: 256px;
48
49
  --fs-group: clamp(34px, 4vw, 46px);
49
50
  --fs-section: clamp(27px, 2.9vw, 33px);
@@ -53,8 +54,8 @@
53
54
  --fs-min: 16px;
54
55
  --tracking-prose: 0.03em;
55
56
  --word-spacing-prose: 0.16em;
56
- --measure-prose: 66ch;
57
- --measure-read: 60ch;
57
+ --measure-prose: 58ch;
58
+ --measure-read: 48ch;
58
59
  --measure-code: 80ch;
59
60
  --target-min: 24px;
60
61
  --target-comfortable: 44px;
@@ -119,6 +120,7 @@
119
120
  --hero-tex: .16;
120
121
  --glow: 0 0 6px rgba(203,163,92,.22);
121
122
  --glow-soft: 0 0 4px rgba(203,163,92,.13);
123
+ --overlay-shadow: var(--glow), 0 24px 60px -20px rgba(0,0,0,.6);
122
124
  --glass-bg: rgba(245,243,235,.06);
123
125
  --glass-solid: rgba(20,20,18,.62);
124
126
  --glass-edge: rgba(245,243,235,.18);
@@ -135,7 +137,7 @@
135
137
  --dur-entrance: 900ms;
136
138
  --ease-standard: cubic-bezier(.2, 0, 0, 1);
137
139
  --ease-out: cubic-bezier(.16, 1, .3, 1);
138
- --ease-spring: cubic-bezier(.2, .82, .2, 1.12);
140
+ --ease-spring: cubic-bezier(.16, 1, .3, 1);
139
141
  }
140
142
  [data-theme="light"] {
141
143
  --canvas: #fbfaf7;
@@ -182,6 +184,7 @@
182
184
  --hero-tex: .06;
183
185
  --glow: none;
184
186
  --glow-soft: none;
187
+ --overlay-shadow: none;
185
188
  --glass-bg: rgba(255,255,255,.3);
186
189
  --glass-solid: rgba(255,255,255,.74);
187
190
  --glass-edge: rgba(20,16,9,.12);
@@ -448,10 +448,6 @@
448
448
  "$type": "dimension",
449
449
  "$value": "52px"
450
450
  },
451
- "fs-micro": {
452
- "$type": "dimension",
453
- "$value": "11px"
454
- },
455
451
  "fs-group": {
456
452
  "$type": "dimension",
457
453
  "$value": "clamp(34px, 4vw, 46px)"
@@ -500,7 +496,7 @@
500
496
  },
501
497
  "ease-spring": {
502
498
  "$type": "duration",
503
- "$value": "cubic-bezier(.2, .82, .2, 1.12)"
499
+ "$value": "cubic-bezier(.16, 1, .3, 1)"
504
500
  }
505
501
  },
506
502
  "font": {
@@ -582,6 +578,14 @@
582
578
  "$type": "other",
583
579
  "$value": "3px"
584
580
  },
581
+ "focus-ring-offset": {
582
+ "$type": "other",
583
+ "$value": "2px"
584
+ },
585
+ "focus-ring-offset-inset": {
586
+ "$type": "other",
587
+ "$value": "calc(-1 * var(--focus-ring-width))"
588
+ },
585
589
  "ghost-node-size": {
586
590
  "$type": "other",
587
591
  "$value": "9px"
@@ -608,11 +612,11 @@
608
612
  },
609
613
  "measure-prose": {
610
614
  "$type": "other",
611
- "$value": "66ch"
615
+ "$value": "58ch"
612
616
  },
613
617
  "measure-read": {
614
618
  "$type": "other",
615
- "$value": "60ch"
619
+ "$value": "48ch"
616
620
  },
617
621
  "measure-code": {
618
622
  "$type": "other",
@@ -748,6 +752,15 @@
748
752
  }
749
753
  }
750
754
  },
755
+ "overlay-shadow": {
756
+ "$type": "other",
757
+ "$value": "var(--glow), 0 24px 60px -20px rgba(0,0,0,.6)",
758
+ "$extensions": {
759
+ "fairtrade.theme": {
760
+ "light": "none"
761
+ }
762
+ }
763
+ },
751
764
  "glass-bg": {
752
765
  "$type": "other",
753
766
  "$value": "rgba(245,243,235,.06)",
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * resolve any accepted name/alias to a canonical mark key, or null when unknown.
3
3
  * @param {string} name
4
- * @returns {('claude'|'gemini'|'openai'|'cursor'|'opencode'|'strike'|'pi')|null}
4
+ * @returns {('claude'|'gemini'|'openai'|'cursor'|'opencode'|'strike'|'pi'|'github')|null}
5
5
  */
6
- export function resolveBrand(name: string): ("claude" | "gemini" | "openai" | "cursor" | "opencode" | "strike" | "pi") | null;
6
+ export function resolveBrand(name: string): ("claude" | "gemini" | "openai" | "cursor" | "opencode" | "strike" | "pi" | "github") | null;
7
7
  /**
8
8
  * BrandMark - a single-color, currentColor-tinted company/provider logo.
9
9
  *
@@ -1,13 +1,13 @@
1
1
  /**
2
2
  * ConnectionPill — the small, glanceable connection indicator. a square hairline pill carrying an
3
- * icon and the word; the note ("on this computer · no internet") sits beside it as quiet mono
3
+ * icon and the word; the note ("on this computer, no internet") sits beside it as quiet mono
4
4
  * chrome. the state never rides on color alone: the icon and the word both encode it (no status
5
5
  * dot — a color-only dot would break that rule), and the whole pill is announced via role=status.
6
6
  * the per-tone icon color is a tint on top, only where color is welcome.
7
7
  *
8
8
  * @param {object} props
9
9
  * @param {'live'|'connecting'|'disconnected'} [props.status='live'] - the connection state.
10
- * @param {boolean} [props.showNote=true] - render the trailing "on this computer · no internet"
10
+ * @param {boolean} [props.showNote=true] - render the trailing "on this computer, no internet"
11
11
  * style note. set false for the tightest, word-only pill.
12
12
  * @param {string} [props.className]
13
13
  */
@@ -2,8 +2,8 @@
2
2
  * a sortable + selectable data table. square, hairline, mono headers; both themes
3
3
  * via tokens. sort + selection state/logic are powered by TanStack Table
4
4
  * (@tanstack/react-table, headless) while this component still renders its own markup
5
- * + token classes, so the look is unchanged and growth (filtering, pagination, column
6
- * sizing/visibility) is a config away. sorting cycles none -> asc -> desc -> none on a
5
+ * + token classes. Search, column filters and pagination can each be host-controlled
6
+ * or seeded by defaults. Sorting cycles none -> asc -> desc -> none on a
7
7
  * sortable header (a real <button>, so it is keyboard-operable), exposes aria-sort on the
8
8
  * <th>, and shows a lucide chevron indicator. selection reuses the existing .check-box control:
9
9
  * a header checkbox selects/clears all (with an indeterminate middle state) and
@@ -18,16 +18,19 @@
18
18
  * @property {string} key object key this column reads from each row.
19
19
  * @property {React.ReactNode} label header text (kept as passed; not forced-lowercase).
20
20
  * @property {boolean} [sortable] when true the header sorts; default false.
21
- * @property {'left'|'right'|'center'} [align] cell alignment; 'right' also gets tabular nums. default 'left'.
21
+ * @property {'left'|'right'|'center'|'decimal'} [align] default left. Decimal aligns plain dot-separated numbers; custom renderers and other formats fall back to right + tabular nums.
22
22
  * @property {string} [width] optional fixed column width (any css length, e.g. '12rem'); emits a <colgroup> entry so columns stay put as cell content changes.
23
23
  * @property {(value: any, row: Object) => React.ReactNode} [render] custom cell renderer; falls back to row[key].
24
24
  *
25
25
  * @typedef {{ key: string, dir: 'asc'|'desc' } | null} DataTableSort
26
+ * @typedef {{ id: string, value: string }[]} DataTableColumnFilters
27
+ * @typedef {{ pageIndex: number, pageSize: number }} DataTablePagination
26
28
  *
27
29
  * @param {Object} props
28
30
  * @param {DataTableColumn[]} props.columns column definitions.
29
31
  * @param {Object[]} props.rows row objects.
30
32
  * @param {boolean} [props.selectable=false] render the selection column.
33
+ * @param {boolean} [props.disabled=false] disable table controls while retaining keyboard scrolling.
31
34
  * @param {(row: Object, index: number) => (string|number)} [props.rowKey] stable key per row; defaults to row.id ?? index.
32
35
  * @param {DataTableSort} [props.defaultSort=null] initial sort (uncontrolled).
33
36
  * @param {DataTableSort} [props.sort] controlled sort.
@@ -37,11 +40,22 @@
37
40
  * @param {(keys: Array<string|number>) => void} [props.onSelectionChange] called with the next selection.
38
41
  * @param {string} [props.caption] accessible <caption> for the table (visually present, mono/quiet).
39
42
  * @param {string} [props.className] extra class on the scroll wrapper.
43
+ * @param {string} [props.search] controlled search.
44
+ * @param {string} [props.defaultSearch=''] initial search.
45
+ * @param {(next: string) => void} [props.onSearchChange] next search value.
46
+ * @param {DataTableColumnFilters} [props.columnFilters] controlled column filters (TanStack id/value shape).
47
+ * @param {DataTableColumnFilters} [props.defaultColumnFilters=[]] initial column filters.
48
+ * @param {(next: DataTableColumnFilters) => void} [props.onColumnFiltersChange] next filters.
49
+ * @param {DataTablePagination} [props.pagination] controlled pagination (zero-based pageIndex).
50
+ * @param {DataTablePagination} [props.defaultPagination] defaults to pageIndex 0, pageSize 10.
51
+ * @param {(next: DataTablePagination) => void} [props.onPaginationChange] next pagination.
52
+ * @param {number} [props.rowCount] host total for host-sliced data: pagination stays manual (the page count comes from rowCount) and sorting stays local, while search and column filters still apply to the rows given; with a partial window and an active filter the footer reports the loaded rows, never the host total.
40
53
  */
41
- export default function DataTable({ columns, rows, selectable, rowKey, defaultSort, sort: sortProp, onSortChange, defaultSelectedKeys, selectedKeys: selectedProp, onSelectionChange, caption, className, }: {
54
+ export default function DataTable({ columns, rows, selectable, disabled, rowKey, defaultSort, sort: sortProp, onSortChange, defaultSelectedKeys, selectedKeys: selectedProp, onSelectionChange, caption, className, search: searchProp, defaultSearch, onSearchChange, columnFilters: filtersProp, defaultColumnFilters, onColumnFiltersChange, pagination: paginationProp, defaultPagination, onPaginationChange, rowCount, }: {
42
55
  columns: DataTableColumn[];
43
56
  rows: any[];
44
57
  selectable?: boolean;
58
+ disabled?: boolean;
45
59
  rowKey?: (row: any, index: number) => (string | number);
46
60
  defaultSort?: DataTableSort;
47
61
  sort?: DataTableSort;
@@ -51,13 +65,23 @@ export default function DataTable({ columns, rows, selectable, rowKey, defaultSo
51
65
  onSelectionChange?: (keys: Array<string | number>) => void;
52
66
  caption?: string;
53
67
  className?: string;
68
+ search?: string;
69
+ defaultSearch?: string;
70
+ onSearchChange?: (next: string) => void;
71
+ columnFilters?: DataTableColumnFilters;
72
+ defaultColumnFilters?: DataTableColumnFilters;
73
+ onColumnFiltersChange?: (next: DataTableColumnFilters) => void;
74
+ pagination?: DataTablePagination;
75
+ defaultPagination?: DataTablePagination;
76
+ onPaginationChange?: (next: DataTablePagination) => void;
77
+ rowCount?: number;
54
78
  }): import("react").JSX.Element;
55
79
  /**
56
80
  * a sortable + selectable data table. square, hairline, mono headers; both themes
57
81
  * via tokens. sort + selection state/logic are powered by TanStack Table
58
82
  * (@tanstack/react-table, headless) while this component still renders its own markup
59
- * + token classes, so the look is unchanged and growth (filtering, pagination, column
60
- * sizing/visibility) is a config away. sorting cycles none -> asc -> desc -> none on a
83
+ * + token classes. Search, column filters and pagination can each be host-controlled
84
+ * or seeded by defaults. Sorting cycles none -> asc -> desc -> none on a
61
85
  * sortable header (a real <button>, so it is keyboard-operable), exposes aria-sort on the
62
86
  * <th>, and shows a lucide chevron indicator. selection reuses the existing .check-box control:
63
87
  * a header checkbox selects/clears all (with an indeterminate middle state) and
@@ -82,9 +106,9 @@ export type DataTableColumn = {
82
106
  */
83
107
  sortable?: boolean;
84
108
  /**
85
- * cell alignment; 'right' also gets tabular nums. default 'left'.
109
+ * default left. Decimal aligns plain dot-separated numbers; custom renderers and other formats fall back to right + tabular nums.
86
110
  */
87
- align?: "left" | "right" | "center";
111
+ align?: "left" | "right" | "center" | "decimal";
88
112
  /**
89
113
  * optional fixed column width (any css length, e.g. '12rem'); emits a <colgroup> entry so columns stay put as cell content changes.
90
114
  */
@@ -98,8 +122,8 @@ export type DataTableColumn = {
98
122
  * a sortable + selectable data table. square, hairline, mono headers; both themes
99
123
  * via tokens. sort + selection state/logic are powered by TanStack Table
100
124
  * (@tanstack/react-table, headless) while this component still renders its own markup
101
- * + token classes, so the look is unchanged and growth (filtering, pagination, column
102
- * sizing/visibility) is a config away. sorting cycles none -> asc -> desc -> none on a
125
+ * + token classes. Search, column filters and pagination can each be host-controlled
126
+ * or seeded by defaults. Sorting cycles none -> asc -> desc -> none on a
103
127
  * sortable header (a real <button>, so it is keyboard-operable), exposes aria-sort on the
104
128
  * <th>, and shows a lucide chevron indicator. selection reuses the existing .check-box control:
105
129
  * a header checkbox selects/clears all (with an indeterminate middle state) and
@@ -114,3 +138,43 @@ export type DataTableSort = {
114
138
  key: string;
115
139
  dir: "asc" | "desc";
116
140
  } | null;
141
+ /**
142
+ * a sortable + selectable data table. square, hairline, mono headers; both themes
143
+ * via tokens. sort + selection state/logic are powered by TanStack Table
144
+ * (@tanstack/react-table, headless) while this component still renders its own markup
145
+ * + token classes. Search, column filters and pagination can each be host-controlled
146
+ * or seeded by defaults. Sorting cycles none -> asc -> desc -> none on a
147
+ * sortable header (a real <button>, so it is keyboard-operable), exposes aria-sort on the
148
+ * <th>, and shows a lucide chevron indicator. selection reuses the existing .check-box control:
149
+ * a header checkbox selects/clears all (with an indeterminate middle state) and
150
+ * each row carries its own. selected rows get a subtle highlight.
151
+ *
152
+ * sort + selection are each independently controlled OR uncontrolled:
153
+ * - sort: pass `sort` + `onSortChange` to control; otherwise `defaultSort` seeds it.
154
+ * - selection: pass `selectedKeys` + `onSelectionChange` to control; otherwise
155
+ * `defaultSelectedKeys` seeds it.
156
+ */
157
+ export type DataTableColumnFilters = {
158
+ id: string;
159
+ value: string;
160
+ }[];
161
+ /**
162
+ * a sortable + selectable data table. square, hairline, mono headers; both themes
163
+ * via tokens. sort + selection state/logic are powered by TanStack Table
164
+ * (@tanstack/react-table, headless) while this component still renders its own markup
165
+ * + token classes. Search, column filters and pagination can each be host-controlled
166
+ * or seeded by defaults. Sorting cycles none -> asc -> desc -> none on a
167
+ * sortable header (a real <button>, so it is keyboard-operable), exposes aria-sort on the
168
+ * <th>, and shows a lucide chevron indicator. selection reuses the existing .check-box control:
169
+ * a header checkbox selects/clears all (with an indeterminate middle state) and
170
+ * each row carries its own. selected rows get a subtle highlight.
171
+ *
172
+ * sort + selection are each independently controlled OR uncontrolled:
173
+ * - sort: pass `sort` + `onSortChange` to control; otherwise `defaultSort` seeds it.
174
+ * - selection: pass `selectedKeys` + `onSelectionChange` to control; otherwise
175
+ * `defaultSelectedKeys` seeds it.
176
+ */
177
+ export type DataTablePagination = {
178
+ pageIndex: number;
179
+ pageSize: number;
180
+ };
@@ -5,7 +5,7 @@
5
5
  * renders a file header (path + +N/−N churn) then each hunk's `@@` row and lines.
6
6
  *
7
7
  * redaction: variant="redaction", pass `matches` = [{ category, confidence, original,
8
- * replacement, oldNo, newNo }]. each match is a del→add pair with a category·
8
+ * replacement, oldNo, newNo }]. each match is a del→add pair with a category/
9
9
  * confidence badge and a per-match keep/revert button.
10
10
  *
11
11
  * @param {object} props
@@ -13,7 +13,7 @@ export type GMSItem = {
13
13
  */
14
14
  label: import("react").ReactNode;
15
15
  /**
16
- * one-line secondary metadata (e.g. "42 turns · jun 3").
16
+ * one-line secondary metadata (e.g. "42 turns, jun 3").
17
17
  */
18
18
  meta?: import("react").ReactNode;
19
19
  /**
@@ -11,7 +11,7 @@
11
11
  * member rows those groups hold. The count chip sits ONE indent step inside the
12
12
  * tree, between the owner row and the members it discloses, and carries no
13
13
  * checkbox of its own. Members render only while the chip is open, each as a
14
- * row like the owner's: title, middot facts, an individual checkbox, and
14
+ * row like the owner's: title, comma-separated facts, an individual checkbox, and
15
15
  * host-authorized navigation.
16
16
  *
17
17
  * One continuous connector traces the centre of every MOUNTED row checkbox:
@@ -158,7 +158,7 @@ export function HelperGroupListItem({ owner, ownerStatus, children }: {
158
158
  }): import("react").JSX.Element;
159
159
  /**
160
160
  * One helper member drawn as the ordinary list row it is: title, a facts line
161
- * with middot separators, an optional individual checkbox, and host-authorized
161
+ * with comma separators, an optional individual checkbox, and host-authorized
162
162
  * navigation. Display-only when selection and navigation are both absent. The
163
163
  * two optional behaviors are individual-only: a per-thread checkbox and
164
164
  * host-authorized open navigation. No aggregate selection, no self-built links,
@@ -174,7 +174,7 @@ export function HelperGroupListItem({ owner, ownerStatus, children }: {
174
174
  * Facts that have no measured value state that honestly ("unknown input
175
175
  * submissions"), and a count of one singularizes: a row never claims "1 input
176
176
  * submissions" or "1 turns". The separator falls BETWEEN facts that survive, so
177
- * a row cannot open or end its facts line with a stray middot.
177
+ * a row cannot open or end its facts line with a stray separator.
178
178
  * @param {object} props
179
179
  * @param {string} props.id - individual transcript identity, never a group ID
180
180
  * @param {string} props.title - verbatim user content
@@ -17,7 +17,7 @@ export function PublishStateLabel({ state, collectives, newTurns, collective, cl
17
17
  }): import("react").JSX.Element;
18
18
  /**
19
19
  * PublishBar — the status and the one action for it, for a transcript header row. The action is
20
- * publish (not published, outside the saved lists), update (new turns) or manage (published,
20
+ * publish (not published, outside the saved lists) or update (published, new turns,
21
21
  * auto-publish on); while publishing it stays visible and busy.
22
22
  *
23
23
  * @param {object} props
@@ -117,8 +117,8 @@ export function CollectivePicker({ suggestions, onAdd, query: queryProp, onQuery
117
117
  * @param {(id: string) => void} [props.onRemove]
118
118
  * @param {(id: string) => void} [props.onRestore]
119
119
  * @param {object} [props.picker] - CollectivePicker props (suggestions, onAdd, query, onQueryChange).
120
- * @param {{ checked: boolean, onChange: (checked: boolean) => void, hint?: string }} [props.autoPublish]
121
- * @param {string} [props.accessSummary] - update mode: the access change in words ("adds ML Reading Group · removes nothing").
120
+ * @param {{ checked: boolean, onChange: (checked: boolean) => void, hint?: string }} [props.autoPublish] - hint replaces only the unchecked line; checked consent is always component-owned.
121
+ * @param {string} [props.accessSummary] - update mode: the access change in words ("adds ML Reading Group, removes nothing").
122
122
  * @param {string} [props.primaryLabel] - replaces the derived primary label.
123
123
  * @param {() => void} [props.onPublish]
124
124
  * @param {() => void} [props.onConnect] - `continue with github`.
@@ -196,7 +196,7 @@ export type AccessItem = {
196
196
  name: string;
197
197
  members?: number;
198
198
  /**
199
- * - why it is here ("suggested · repo acme/ingest-api is linked").
199
+ * - why it is here ("suggested, repo acme/ingest-api is linked").
200
200
  */
201
201
  note?: string;
202
202
  /**
@@ -8,7 +8,7 @@
8
8
  * empty input throws an actionable TypeError before the review renders.
9
9
  * @param {(level: 'minimal'|'standard'|'maximum') => void} [props.onLevel]
10
10
  * - called only with an available level on select
11
- * @param {Array<{id, category, confidence:number, before?:string, secret?:string, after:string, kept?:boolean}>} [props.matches]
11
+ * @param {Array<{id, category: import('./redaction-categories.js').RedactionCategory, confidence:number, before?:string, secret?:string, after:string, kept?:boolean}>} [props.matches]
12
12
  * - the flagged matches. `before`/`secret` is the original (one or the other), `after` the
13
13
  * redacted form. `kept` (controlled mode) = the user opted OUT, secret leaves as-is.
14
14
  * @param {(id: string, kept: boolean) => void} [props.onToggle] - called when a match is toggled;
@@ -26,7 +26,7 @@ export function RedactionReview({ level, availableLevels, onLevel, matches, onTo
26
26
  onLevel?: (level: "minimal" | "standard" | "maximum") => void;
27
27
  matches?: Array<{
28
28
  id: any;
29
- category: any;
29
+ category: import("./redaction-categories.js").RedactionCategory;
30
30
  confidence: number;
31
31
  before?: string;
32
32
  secret?: string;
@@ -1,3 +1,9 @@
1
+ /** Share one polite save-status region across a settings view. Standalone rows keep their own.
2
+ * @param {{children: import('react').ReactNode}} props
3
+ */
4
+ export function SettingStatus({ children }: {
5
+ children: import("react").ReactNode;
6
+ }): import("react").JSX.Element;
1
7
  /**
2
8
  * SettingRow — one setting: a label, optional help, and one control that saves on its own.
3
9
  *
@@ -111,7 +111,7 @@ export type TimelineItem = {
111
111
  */
112
112
  icon?: React.ComponentType<any>;
113
113
  /**
114
- * 'turns 3–4 · 1 error'
114
+ * 'turns 3–4, 1 error'
115
115
  */
116
116
  range?: string;
117
117
  /**
@@ -183,10 +183,10 @@ export type Tool = {
183
183
  duration?: string;
184
184
  /**
185
185
  * bash exit code; !== 0 surfaces an error pill + tints the dot
186
- * kind-specific payload: read{path,lines,excerpt} · grep{pattern,scope,glob,matches,results}
187
- * · edit{path,adds,dels,hunk[]} · bash{command,description,stdout,exit,duration}
188
- * · webfetch{url,prompt,result} · task{agent,status,task,owner,promptBody,result}
189
- * · default{args,result}
186
+ * kind-specific payload: read{path,lines,excerpt}, grep{pattern,scope,glob,matches,results}
187
+ * edit{path,adds,dels,hunk[]}, bash{command,description,stdout,exit,duration}
188
+ * webfetch{url,prompt,result}, task{agent,status,task,owner,promptBody,result}
189
+ * default{args,result}
190
190
  */
191
191
  exit?: number;
192
192
  };
@@ -29,17 +29,17 @@ export function formatDuration(mins: number | null | undefined): string;
29
29
  */
30
30
  export function shortWeek(week: string): string;
31
31
  /**
32
- * Format a median·p90 pair of plain numbers with MATCHED precision (the
33
- * identical-precision rule: "8.0 · 19.2", never "8 · 19.2"; two integers stay
34
- * "12 · 27"). Nulls render "—" individually.
32
+ * Format a median/p90 pair of plain numbers with MATCHED precision (the
33
+ * identical-precision rule: "8.0, 19.2", never "8, 19.2"; two integers stay
34
+ * "12, 27"). Nulls render "—" individually.
35
35
  * @param {number | null | undefined} a
36
36
  * @param {number | null | undefined} b
37
37
  * @returns {[string, string]}
38
38
  */
39
39
  export function formatNumberPair(a: number | null | undefined, b: number | null | undefined): [string, string];
40
40
  /**
41
- * Format a median·p90 pair of token counts with a SHARED unit and matched
42
- * precision ("10.5k · 23.0k", "62k · 106k"). Unit is picked from the larger
41
+ * Format a median/p90 pair of token counts with a SHARED unit and matched
42
+ * precision ("10.5k, 23.0k", "62k, 106k"). Unit is picked from the larger
43
43
  * value; nulls render "—" individually.
44
44
  * @param {number | null | undefined} a
45
45
  * @param {number | null | undefined} b
@@ -0,0 +1,4 @@
1
+ /** Compact counts use one decimal place and lowercase magnitude suffixes. */
2
+ export function formatCount(value: any): string;
3
+ /** Calendar dates are stable across host locales; date-only inputs stay on their UTC day. */
4
+ export function formatDate(value: any): string;
@@ -62,6 +62,6 @@ export { default as SignInProviders, HandleClaim, OnboardingCard } from "./SignI
62
62
  export { default as CliSteps, CommandBlock, GettingStarted } from "./CliOnboard.jsx";
63
63
  export { StatTile, StatGrid, GovTile, ProviderBars } from "./StatTiles.jsx";
64
64
  export { PublishStateLabel, PublishBar, AccessList, CollectivePicker, PublishDialog, PUBLISH_STATES, PUBLISH_DIALOG_STATES } from "./Publish.jsx";
65
- export { SettingRow, SettingGroup, SETTING_ROW_STATES } from "./Settings.jsx";
65
+ export { SettingRow, SettingGroup, SettingStatus, SETTING_ROW_STATES } from "./Settings.jsx";
66
66
  export { default as VisibilitySegmented, VisibilityEye, ScopeChip, FocusedModeToggle } from "./VisibilityControl.jsx";
67
67
  export { default as InUseShell, GraphAppShell, GraphSectionNav, IN_USE_APPS, LOCAL_APP_SECTIONS, GRAPH_APP_SECTIONS } from "./inuse/InUseShell.jsx";
@@ -0,0 +1,17 @@
1
+ /** @typedef {'secrets'|'pii'|'paths'|'project'} RedactionCategory */
2
+ /** @param {unknown} category */
3
+ export function redactionCategoryLabel(category: unknown): any;
4
+ /** @param {unknown} matches */
5
+ export function hasKnownRedactionCategories(matches: unknown): boolean;
6
+ /**
7
+ * Audited JS projection of github.com/peasant-labs/redact/category_string.go:
8
+ * Category.String maps wire categories to these exact rendered labels.
9
+ * Unknown input is never a trusted category or a display-label fallback.
10
+ */
11
+ export const REDACTION_CATEGORY_LABELS: Readonly<{
12
+ secrets: "CREDENTIAL";
13
+ pii: "PII";
14
+ paths: "PATH";
15
+ project: "INTERNAL";
16
+ }>;
17
+ export type RedactionCategory = "secrets" | "pii" | "paths" | "project";
@@ -12,8 +12,9 @@
12
12
  * @param {{ outcome: string, flag?: string }} [props.savedLabel]
13
13
  * @param {boolean} [props.compact]
14
14
  * @param {boolean} [props.expandAll]
15
+ * @param {number} [props.revealRequest] explicit search navigation sequence
15
16
  */
16
- export default function TurnCard({ turn, active, openTools, toggleTool, onCopyAnchor, copied, registerRef, onLabel, renderActions, savedLabel, compact, expandAll, }: {
17
+ export default function TurnCard({ turn, active, openTools, toggleTool, onCopyAnchor, copied, registerRef, onLabel, renderActions, savedLabel, compact, expandAll, revealRequest, }: {
17
18
  turn?: TurnVM;
18
19
  active?: boolean;
19
20
  openTools?: Record<string, boolean>;
@@ -29,5 +30,6 @@ export default function TurnCard({ turn, active, openTools, toggleTool, onCopyAn
29
30
  };
30
31
  compact?: boolean;
31
32
  expandAll?: boolean;
33
+ revealRequest?: number;
32
34
  }): import("react").JSX.Element;
33
35
  export type TurnVM = import("./view-model.js").TurnVM;
@@ -0,0 +1,10 @@
1
+ /** Find the last ordered turn at or before the reading line, reading logarithmically
2
+ * many offsets. Re-read live offsets so expanded tools and wrapping need no cache.
3
+ * @param {{index: number}[]} turns
4
+ * @param {(index: number) => number} topOf
5
+ * @param {number} readingLine
6
+ * @returns {number}
7
+ */
8
+ export function turnAtReadingLine(turns: {
9
+ index: number;
10
+ }[], topOf: (index: number) => number, readingLine: number): number;
@@ -219,7 +219,7 @@ export type TranscriptViewerProps = {
219
219
  */
220
220
  streamPrelude?: unknown;
221
221
  /**
222
- * default true: render the composite's share and more menus after `headerActions`; false removes both so the host's own actions stand alone
222
+ * default false: hosts opt in with true to retain the legacy share/contribute and more menus after `headerActions`
223
223
  */
224
224
  showTail?: boolean;
225
225
  /**
@@ -23,7 +23,7 @@ export function projectLabel(project: string | undefined): string;
23
23
  * Compose the session detail h1.
24
24
  *
25
25
  * • {project}: {Summary} — project + meaningful prompt
26
- * • {project} · {shortId} — project, no usable prompt
26
+ * • {project}, {shortId} — project, no usable prompt
27
27
  * • {shortId} — {Summary} — no project, but a prompt
28
28
  * • Session {shortId} — nothing useful at all
29
29
  *
@@ -478,7 +478,7 @@ export type TaskGroupVM = {
478
478
  */
479
479
  error?: string;
480
480
  /**
481
- * cooked churn/files summary, e.g. "2 files · +316 −25" (render-when-present)
481
+ * cooked churn/files summary, e.g. "2 files, +316 −25" (render-when-present)
482
482
  */
483
483
  stat?: string;
484
484
  };
@@ -500,7 +500,7 @@ export type HighlightVM = {
500
500
  */
501
501
  icon?: string;
502
502
  /**
503
- * e.g. "+312 −24 · 7 files"
503
+ * e.g. "+312 −24, 7 files"
504
504
  */
505
505
  stat?: string;
506
506
  time?: string;