@peasant-labs/fairtrade 0.0.40 → 0.0.41

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 (37) 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/graph.js +477 -476
  6. package/dist/lib/share-fonts/AtkinsonHyperlegible-Bold.ttf +0 -0
  7. package/dist/lib/share-fonts/AtkinsonHyperlegible-Regular.ttf +0 -0
  8. package/dist/lib/share-fonts/AtkinsonHyperlegibleMono-Bold.ttf +0 -0
  9. package/dist/lib/share-fonts/AtkinsonHyperlegibleMono-Regular.ttf +0 -0
  10. package/dist/lib/share-fonts/OFL-AtkinsonHyperlegible.txt +92 -0
  11. package/dist/lib/share-fonts/OFL-AtkinsonHyperlegibleMono.txt +93 -0
  12. package/dist/lib/share.js +1311 -0
  13. package/dist/lib/time-CpVBzcqQ.js +157 -0
  14. package/dist/lib/types/BrandMark.d.ts +2 -6
  15. package/dist/lib/types/brand-geometry.d.ts +22 -0
  16. package/dist/lib/types/commons/providers.d.ts +1 -1
  17. package/dist/lib/types/share/ShareCard.d.ts +40 -0
  18. package/dist/lib/types/share/data.d.ts +54 -0
  19. package/dist/lib/types/share/fonts.d.ts +16 -0
  20. package/dist/lib/types/share/index.d.ts +5 -0
  21. package/dist/lib/types/share/marks.d.ts +23 -0
  22. package/dist/lib/types/share/metrics.d.ts +10 -0
  23. package/dist/lib/types/transcript/title.d.ts +21 -0
  24. package/dist/lib/types/ui/brand-geometry.d.ts +22 -0
  25. package/dist/lib/types/ui/format.d.ts +35 -0
  26. package/dist/lib/types/ui/provider-policy.d.ts +27 -0
  27. package/dist/lib/types/ui/transcript/adapter.d.ts +66 -0
  28. package/dist/lib/types/ui/transcript/adapter.parse.d.ts +103 -0
  29. package/dist/lib/types/ui/transcript/analytics.d.ts +213 -0
  30. package/dist/lib/types/ui/transcript/time.d.ts +47 -0
  31. package/dist/lib/types/ui/transcript/title.d.ts +84 -0
  32. package/dist/lib/types/ui/transcript/usage.d.ts +19 -0
  33. package/dist/lib/types/ui/transcript/view-model.d.ts +700 -0
  34. package/dist/lib/types/ui/transcript/wire-types.d.ts +63 -0
  35. package/dist/lib/{ui-DMUCYaeU.js → ui-Bhk29YuW.js} +3700 -4896
  36. package/dist/lib/ui.js +7 -5
  37. package/package.json +14 -4
@@ -0,0 +1,157 @@
1
+ import { Harness as e, isHarness as t } from "@peasant-labs/schema";
2
+ //#region src/ui/brand-geometry.js
3
+ var n = {
4
+ github: "M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.807 1.305 3.492.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.4 3-.405 1.02.005 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12",
5
+ claude: "m4.7144 15.9555 4.7174-2.6471.079-.2307-.079-.1275h-.2307l-.7893-.0486-2.6956-.0729-2.3375-.0971-2.2646-.1214-.5707-.1215-.5343-.7042.0546-.3522.4797-.3218.686.0608 1.5179.1032 2.2767.1578 1.6514.0972 2.4468.255h.3886l.0546-.1579-.1336-.0971-.1032-.0972L6.973 9.8356l-2.55-1.6879-1.3356-.9714-.7225-.4918-.3643-.4614-.1578-1.0078.6557-.7225.8803.0607.2246.0607.8925.686 1.9064 1.4754 2.4893 1.8336.3643.3035.1457-.1032.0182-.0728-.164-.2733-1.3539-2.4467-1.445-2.4893-.6435-1.032-.17-.6194c-.0607-.255-.1032-.4674-.1032-.7285L6.287.1335 6.6997 0l.9957.1336.419.3642.6192 1.4147 1.0018 2.2282 1.5543 3.0296.4553.8985.2429.8318.091.255h.1579v-.1457l.1275-1.706.2368-2.0947.2307-2.6957.0789-.7589.3764-.9107.7468-.4918.5828.2793.4797.686-.0668.4433-.2853 1.8517-.5586 2.9021-.3643 1.9429h.2125l.2429-.2429.9835-1.3053 1.6514-2.0643.7286-.8196.85-.9046.5464-.4311h1.0321l.759 1.1293-.34 1.1657-1.0625 1.3478-.8804 1.1414-1.2628 1.7-.7893 1.36.0729.1093.1882-.0183 2.8535-.607 1.5421-.2794 1.8396-.3157.8318.3886.091.3946-.3278.8075-1.967.4857-2.3072.4614-3.4364.8136-.0425.0304.0486.0607 1.5482.1457.6618.0364h1.621l3.0175.2247.7892.522.4736.6376-.079.4857-1.2142.6193-1.6393-.3886-3.825-.9107-1.3113-.3279h-.1822v.1093l1.0929 1.0686 2.0035 1.8092 2.5075 2.3314.1275.5768-.3218.4554-.34-.0486-2.2039-1.6575-.85-.7468-1.9246-1.621h-.1275v.17l.4432.6496 2.3436 3.5214.1214 1.0807-.17.3521-.6071.2125-.6679-.1214-1.3721-1.9246L14.38 17.959l-1.1414-1.9428-.1397.079-.674 7.2552-.3156.3703-.7286.2793-.6071-.4614-.3218-.7468.3218-1.4753.3886-1.9246.3157-1.53.2853-1.9004.17-.6314-.0121-.0425-.1397.0182-1.4328 1.9672-2.1796 2.9446-1.7243 1.8456-.4128.164-.7164-.3704.0667-.6618.4008-.5889 2.386-3.0357 1.4389-1.882.929-1.0868-.0062-.1579h-.0546l-6.3385 4.1164-1.1293.1457-.4857-.4554.0608-.7467.2307-.2429 1.9064-1.3114Z",
6
+ gemini: "M11.04 19.32Q12 21.51 12 24q0-2.49.93-4.68.96-2.19 2.58-3.81t3.81-2.55Q21.51 12 24 12q-2.49 0-4.68-.93a12.3 12.3 0 0 1-3.81-2.58 12.3 12.3 0 0 1-2.58-3.81Q12 2.49 12 0q0 2.49-.96 4.68-.93 2.19-2.55 3.81a12.3 12.3 0 0 1-3.81 2.58Q2.49 12 0 12q2.49 0 4.68.96 2.19.93 3.81 2.55t2.55 3.81",
7
+ openai: "M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3655-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8144 3.3543-2.0201 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364 15.1192 7.2a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.407-.667zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z",
8
+ opencode: "M22 24H2V0h20zM17 4.8H7v14.4h10z",
9
+ cursor: "M11.503.131 1.891 5.678a.84.84 0 0 0-.42.726v11.188c0 .3.162.575.42.724l9.609 5.55a1 1 0 0 0 .998 0l9.61-5.55a.84.84 0 0 0 .42-.724V6.404a.84.84 0 0 0-.42-.726L12.497.131a1.01 1.01 0 0 0-.996 0M2.657 6.338h18.55c.263 0 .43.287.297.515L12.23 22.918c-.062.107-.229.064-.229-.06V12.335a.59.59 0 0 0-.295-.51l-9.11-5.257c-.109-.063-.064-.23.061-.23",
10
+ strike: "M18.5 6L11 17.5h5.2L13.5 26 21 14.5h-5.2L18.5 6z",
11
+ pi: "M165.29 165.29 H517.36 V400 H400 V517.36 H282.65 V634.72 H165.29 Z M282.65 282.65 V400 H400 V282.65 Z M517.36 400 H634.72 V634.72 H517.36 Z"
12
+ }, r = {
13
+ strike: "6 6 20 20",
14
+ pi: "0 0 800 800"
15
+ }, i = { pi: "evenodd" }, a = {
16
+ anthropic: "claude",
17
+ "claude-code": "claude",
18
+ google: "gemini",
19
+ googlegemini: "gemini",
20
+ "gemini-cli": "gemini",
21
+ codex: "openai",
22
+ "codex-cli": "openai",
23
+ chatgpt: "openai",
24
+ gpt: "openai"
25
+ };
26
+ function o(e) {
27
+ if (!e) return null;
28
+ let t = String(e).toLowerCase().trim(), r = a[t] || t;
29
+ return n[r] ? r : null;
30
+ }
31
+ function s(e) {
32
+ return r[e] ?? "0 0 24 24";
33
+ }
34
+ var c = Object.freeze({
35
+ viewBox: "0 0 32 32",
36
+ strokeWidth: 2.1,
37
+ paths: Object.freeze([
38
+ "M16 27V8",
39
+ "M16 21l-5.5-6",
40
+ "M16 21l5.5-6",
41
+ "M16 15l-5-5.5",
42
+ "M16 15l5-5.5"
43
+ ])
44
+ }), l = Object.freeze(Object.values(e)), u = Object.freeze({
45
+ "claude-code": "Claude Code",
46
+ "gemini-cli": "Gemini CLI",
47
+ codex: "Codex",
48
+ opencode: "opencode",
49
+ cursor: "Cursor",
50
+ antigravity: "Google Antigravity",
51
+ strike: "Strike",
52
+ pi: "Pi"
53
+ }), d = Object.freeze({
54
+ "claude-code": "claude",
55
+ "gemini-cli": "gemini",
56
+ codex: "openai",
57
+ opencode: "opencode",
58
+ cursor: "cursor",
59
+ antigravity: "gemini",
60
+ strike: "strike",
61
+ pi: "pi"
62
+ }), f = Object.freeze({
63
+ "claude-code": "amber",
64
+ "gemini-cli": "teal",
65
+ codex: "olive",
66
+ opencode: "mauve",
67
+ cursor: "clay",
68
+ antigravity: "teal",
69
+ strike: "clay",
70
+ pi: "mauve"
71
+ });
72
+ function p(e, n) {
73
+ if (t(e)) return;
74
+ let r;
75
+ try {
76
+ r = JSON.stringify(e);
77
+ } catch {
78
+ r = String(e);
79
+ }
80
+ throw TypeError(`Provider harness validation failed for ${r} at src/ui/provider-policy.js during ${n}: the value is outside the canonical @peasant-labs/schema Harness, so Fairtrade cannot select a trustworthy provider identity; the caller must validate its wire boundary and pass one of ${l.join(", ")}.`);
81
+ }
82
+ function m(e) {
83
+ return p(e, "provider display-name resolution"), u[e];
84
+ }
85
+ function h(e) {
86
+ return p(e, "provider brand resolution"), d[e];
87
+ }
88
+ function g(e) {
89
+ return p(e, "provider accent resolution"), f[e];
90
+ }
91
+ //#endregion
92
+ //#region src/ui/transcript/time.js
93
+ function _(e) {
94
+ if (!e) return !1;
95
+ let t = new Date(e).getTime();
96
+ return Number.isFinite(t) && t > 0;
97
+ }
98
+ var v = [
99
+ "jan",
100
+ "feb",
101
+ "mar",
102
+ "apr",
103
+ "may",
104
+ "jun",
105
+ "jul",
106
+ "aug",
107
+ "sep",
108
+ "oct",
109
+ "nov",
110
+ "dec"
111
+ ];
112
+ function y(e, t) {
113
+ let n = new Date(e), r = `${v[n.getMonth()]} ${n.getDate()}`;
114
+ return n.getFullYear() === new Date(t).getFullYear() ? r : `${r}, ${n.getFullYear()}`;
115
+ }
116
+ function b(e, t = Date.now()) {
117
+ if (!_(e)) return "";
118
+ let n = new Date(e).getTime(), r = Math.max(0, Math.round((t - n) / 1e3));
119
+ if (r < 45) return "just now";
120
+ if (r < 90) return "1m ago";
121
+ let i = Math.round(r / 60);
122
+ if (i < 45) return `${i}m ago`;
123
+ if (i < 90) return "1h ago";
124
+ let a = Math.round(i / 60);
125
+ if (a < 24) return `${a}h ago`;
126
+ if (a < 36) return "1d ago";
127
+ let o = Math.round(a / 24);
128
+ return o <= 7 ? `${o}d ago` : y(n, t);
129
+ }
130
+ function x(e) {
131
+ if (e == null || !Number.isFinite(e) || e <= 0) return "";
132
+ if (e < 1) return "<1s";
133
+ let t = Math.round(e);
134
+ if (t < 60) return `${t}s`;
135
+ let n = Math.floor(t / 60), r = t % 60;
136
+ if (n < 60) return r ? `${n}m ${r}s` : `${n}m`;
137
+ let i = Math.floor(n / 60), a = n % 60;
138
+ return a ? `${i}h ${a}m` : `${i}h`;
139
+ }
140
+ function S(e) {
141
+ return e == null || !Number.isFinite(e) ? "" : x(e * 60);
142
+ }
143
+ function C(e) {
144
+ return e == null || !Number.isFinite(e) || e <= 0 ? "" : e < 1e3 ? `${Math.round(e)}ms` : e < 1e4 ? `${(e / 1e3).toFixed(1).replace(/\.0$/, "")}s` : x(e / 1e3);
145
+ }
146
+ function w(e) {
147
+ if (!e) return "";
148
+ let t = new Date(e);
149
+ return isFinite(t.getTime()) ? t.getTime() <= 0 ? "" : t.toLocaleString(void 0, {
150
+ month: "short",
151
+ day: "numeric",
152
+ hour: "numeric",
153
+ minute: "2-digit"
154
+ }) : e;
155
+ }
156
+ //#endregion
157
+ export { s as _, b as a, d as c, g as d, h as f, c as g, n as h, x as i, l, i as m, S as n, _ as o, m as p, C as r, f as s, w as t, p as u, o as v };
@@ -1,9 +1,3 @@
1
- /**
2
- * resolve any accepted name/alias to a canonical mark key, or null when unknown.
3
- * @param {string} name
4
- * @returns {('claude'|'gemini'|'openai'|'cursor'|'opencode'|'strike'|'pi'|'github')|null}
5
- */
6
- export function resolveBrand(name: string): ("claude" | "gemini" | "openai" | "cursor" | "opencode" | "strike" | "pi" | "github") | null;
7
1
  /**
8
2
  * BrandMark - a single-color, currentColor-tinted company/provider logo.
9
3
  *
@@ -23,3 +17,5 @@ export default function BrandMark({ name, size, label, className, ...rest }: {
23
17
  label?: string;
24
18
  className?: string;
25
19
  }): JSX.Element | null;
20
+ export { resolveBrand };
21
+ import { resolveBrand } from './brand-geometry.js';
@@ -0,0 +1,22 @@
1
+ /**
2
+ * resolve any accepted name/alias to a canonical mark key, or null when unknown.
3
+ * @param {string} name
4
+ * @returns {('claude'|'gemini'|'openai'|'cursor'|'opencode'|'strike'|'pi'|'github')|null}
5
+ */
6
+ export function resolveBrand(name: string): ("claude" | "gemini" | "openai" | "cursor" | "opencode" | "strike" | "pi" | "github") | null;
7
+ /** The view box a mark is drawn in. @param {string} key a canonical mark key */
8
+ export function brandViewBox(key: string): string;
9
+ /** @type {Record<string, string>} */
10
+ export const BRAND_PATHS: Record<string, string>;
11
+ /** @type {Record<string, string>} */
12
+ export const BRAND_VIEW_BOX: Record<string, string>;
13
+ export namespace BRAND_FILL_RULE {
14
+ let pi: string;
15
+ }
16
+ /** @type {Record<string, string>} */
17
+ export const BRAND_ALIAS: Record<string, string>;
18
+ export const WHEAT_LOGO: Readonly<{
19
+ viewBox: "0 0 32 32";
20
+ strokeWidth: 2.1;
21
+ paths: readonly string[];
22
+ }>;
@@ -4,4 +4,4 @@
4
4
  export function formatProvider(provider: unknown): string;
5
5
  /** @param {import('@peasant-labs/schema').Harness} provider */
6
6
  export function providerLabel(provider: import("@peasant-labs/schema").Harness): string;
7
- export const PROVIDER_LABEL: Readonly<Record<"strike" | "cursor" | "claude-code" | "gemini-cli" | "codex" | "opencode" | "antigravity" | "pi", string>>;
7
+ export const PROVIDER_LABEL: Readonly<Record<"opencode" | "cursor" | "strike" | "pi" | "claude-code" | "gemini-cli" | "codex" | "antigravity", string>>;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * @typedef {object} PromptLine
3
+ * @property {string} text the line as drawn, single spaces between its words
4
+ * @property {boolean} breakSpace true when the line ends where the prompt has a space (the space is drawn zero wide)
5
+ */
6
+ /**
7
+ * The prompt as drawn: whitespace collapsed to single spaces, wrapped into the layout's lines, and
8
+ * cut with an ellipsis where it would run past three of them.
9
+ * @param {string} prompt
10
+ * @param {boolean} fullWidth true when there is no stats column
11
+ * @returns {PromptLine[]}
12
+ */
13
+ export function sharePromptLines(prompt: string, fullWidth: boolean): PromptLine[];
14
+ /**
15
+ * The share card for a transcript link preview.
16
+ * @param {object} props
17
+ * @param {ShareCardData | null} props.card the card data, or null for a transcript that is not public
18
+ * @param {600 | 630} [props.height=600] 600 for X's 2:1 card (the default), 630 for every other
19
+ * platform; any other value draws the 600 card
20
+ */
21
+ export function ShareCard({ card, height }: {
22
+ card: ShareCardData | null;
23
+ height?: 600 | 630;
24
+ }): import("react").JSX.Element;
25
+ /** @typedef {import('./data.js').ShareCardData} ShareCardData */
26
+ export const SHARE_CARD_WIDTH: 1200;
27
+ /** X's large card is 2:1; every other platform gets 1.91:1, the same card with more background */
28
+ export const SHARE_CARD_HEIGHTS: readonly [600, 630];
29
+ export default ShareCard;
30
+ export type PromptLine = {
31
+ /**
32
+ * the line as drawn, single spaces between its words
33
+ */
34
+ text: string;
35
+ /**
36
+ * true when the line ends where the prompt has a space (the space is drawn zero wide)
37
+ */
38
+ breakSpace: boolean;
39
+ };
40
+ export type ShareCardData = import("./data.js").ShareCardData;
@@ -0,0 +1,54 @@
1
+ /**
2
+ * The chip label: the harness display name, then the model in brackets in short form. An unknown
3
+ * harness shows its raw value; a missing model leaves the harness name alone.
4
+ * @param {string | undefined} harness
5
+ * @param {string | undefined} model
6
+ * @returns {string}
7
+ */
8
+ export function shareCardModelLabel(harness: string | undefined, model: string | undefined): string;
9
+ /** @param {number} n @returns {string} 84000 -> "84k", 1200000 -> "1.2M" */
10
+ export function formatShareCount(n: number): string;
11
+ /**
12
+ * The card data for a session detail payload, or null when the payload does not parse.
13
+ * @param {unknown} payload
14
+ * @returns {ShareCardData | null}
15
+ */
16
+ export function shareCardFromPayload(payload: unknown): ShareCardData | null;
17
+ /** @param {ShareCardData} card @returns {string} */
18
+ export function shareCardDescription(card: ShareCardData): string;
19
+ /** @param {ShareCardData} card @returns {string} */
20
+ export function shareCardAlt(card: ShareCardData): string;
21
+ export type ShareCardData = {
22
+ /**
23
+ * transcript title
24
+ */
25
+ title: string;
26
+ /**
27
+ * the harness value as recorded
28
+ */
29
+ harness: string;
30
+ /**
31
+ * BrandMark key, or null when the harness is not a known provider
32
+ */
33
+ brand: string | null;
34
+ /**
35
+ * harness display name with the model in brackets, e.g. "Claude Code (Opus 5.5)"
36
+ */
37
+ chip: string;
38
+ /**
39
+ * the published text of the first user turn, or the title when it has none
40
+ */
41
+ firstPrompt: string;
42
+ /**
43
+ * true when the first user turn has no text and `firstPrompt`
44
+ * is the title standing in for it; the card then draws it without the "user" label (absent reads as false)
45
+ */
46
+ firstPromptIsTitle?: boolean;
47
+ /**
48
+ * both figures or neither
49
+ */
50
+ figures: {
51
+ prompts: number;
52
+ tokens: number;
53
+ } | null;
54
+ };
@@ -0,0 +1,16 @@
1
+ /** @typedef {{ name: string, weight: 400 | 700, style: 'normal', file: string }} ShareCardFont */
2
+ /** The family names the card's styles ask for. */
3
+ export const SHARE_CARD_BODY_FONT: "Atkinson Hyperlegible";
4
+ export const SHARE_CARD_MONO_FONT: "Atkinson Hyperlegible Mono";
5
+ /**
6
+ * The card's faces. They cover Latin text: satori draws a CJK character or an emoji as an empty
7
+ * box (.notdef) unless the consumer passes its own fonts for those glyphs beside these.
8
+ * @type {ReadonlyArray<ShareCardFont>}
9
+ */
10
+ export const SHARE_CARD_FONTS: ReadonlyArray<ShareCardFont>;
11
+ export type ShareCardFont = {
12
+ name: string;
13
+ weight: 400 | 700;
14
+ style: "normal";
15
+ file: string;
16
+ };
@@ -0,0 +1,5 @@
1
+ export type ShareCardData = import("./data.js").ShareCardData;
2
+ export type ShareCardFont = import("./fonts.js").ShareCardFont;
3
+ export { ShareCard, SHARE_CARD_WIDTH, SHARE_CARD_HEIGHTS } from "./ShareCard.jsx";
4
+ export { shareCardFromPayload, shareCardDescription, shareCardAlt, shareCardModelLabel, formatShareCount } from "./data.js";
5
+ export { SHARE_CARD_FONTS, SHARE_CARD_BODY_FONT, SHARE_CARD_MONO_FONT } from "./fonts.js";
@@ -0,0 +1,23 @@
1
+ export const USER_ICON: Readonly<{
2
+ viewBox: "0 0 24 24";
3
+ strokeWidth: 2;
4
+ path: "M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2";
5
+ circle: Readonly<{
6
+ cx: 12;
7
+ cy: 7;
8
+ r: 4;
9
+ }>;
10
+ }>;
11
+ export const LOCK_ICON: Readonly<{
12
+ viewBox: "0 0 24 24";
13
+ strokeWidth: 2;
14
+ rect: Readonly<{
15
+ x: 3;
16
+ y: 11;
17
+ width: 18;
18
+ height: 11;
19
+ rx: 2;
20
+ }>;
21
+ path: "M7 11V7a5 5 0 0 1 10 0v4";
22
+ }>;
23
+ export { BRAND_FILL_RULE, BRAND_PATHS, WHEAT_LOGO, brandViewBox, resolveBrand } from "../ui/brand-geometry.js";
@@ -0,0 +1,10 @@
1
+ /**
2
+ * The advance of one character in thousandths of an em, or null when it is outside the table.
3
+ * @param {number} codePoint
4
+ * @returns {number | null}
5
+ */
6
+ export function bodyAdvance(codePoint: number): number | null;
7
+ /** the ellipsis, U+2026 */
8
+ export const ELLIPSIS_ADVANCE: 696;
9
+ /** the mono bold advance of every character a count can hold */
10
+ export const MONO_BOLD_ADVANCE: 632;
@@ -12,6 +12,27 @@ export function unwrapUserQuery(text: string | undefined): string;
12
12
  * @returns {string}
13
13
  */
14
14
  export function cleanSessionTitle(text: string | undefined): string;
15
+ /**
16
+ * The transcript page's title, the one rule the viewer's header and the share card both use: a
17
+ * curated title (an empty one is kept), else, when the session has no normalized evidence, the
18
+ * first task's prompt or the first user turn's text, else the session id, else "transcript".
19
+ * Session titles are often a whole first prompt, so the title is bounded to 160 characters: a
20
+ * longer one is cut to 159 and "…", never through a surrogate pair.
21
+ * @param {object} parts
22
+ * @param {string} [parts.title] curated session title
23
+ * @param {boolean} [parts.hasNormalizedEvidence] true when a title must not be inferred from a prompt
24
+ * @param {string} [parts.firstTaskPrompt]
25
+ * @param {string} [parts.firstUserContent]
26
+ * @param {string} [parts.id] session id
27
+ * @returns {string}
28
+ */
29
+ export function transcriptTitle({ title, hasNormalizedEvidence, firstTaskPrompt, firstUserContent, id }: {
30
+ title?: string;
31
+ hasNormalizedEvidence?: boolean;
32
+ firstTaskPrompt?: string;
33
+ firstUserContent?: string;
34
+ id?: string;
35
+ }): string;
15
36
  /**
16
37
  * Produce a short, human-readable summary of a raw prompt. Heuristic, in order:
17
38
  * 0. Drop a harness's <user_query> wrapper (cleanSessionTitle's rule).
@@ -0,0 +1,22 @@
1
+ /**
2
+ * resolve any accepted name/alias to a canonical mark key, or null when unknown.
3
+ * @param {string} name
4
+ * @returns {('claude'|'gemini'|'openai'|'cursor'|'opencode'|'strike'|'pi'|'github')|null}
5
+ */
6
+ export function resolveBrand(name: string): ("claude" | "gemini" | "openai" | "cursor" | "opencode" | "strike" | "pi" | "github") | null;
7
+ /** The view box a mark is drawn in. @param {string} key a canonical mark key */
8
+ export function brandViewBox(key: string): string;
9
+ /** @type {Record<string, string>} */
10
+ export const BRAND_PATHS: Record<string, string>;
11
+ /** @type {Record<string, string>} */
12
+ export const BRAND_VIEW_BOX: Record<string, string>;
13
+ export namespace BRAND_FILL_RULE {
14
+ let pi: string;
15
+ }
16
+ /** @type {Record<string, string>} */
17
+ export const BRAND_ALIAS: Record<string, string>;
18
+ export const WHEAT_LOGO: Readonly<{
19
+ viewBox: "0 0 32 32";
20
+ strokeWidth: 2.1;
21
+ paths: readonly string[];
22
+ }>;
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Compact count, one decimal at most: 999 → "999", 1234 → "1.2k", 66_731_500_000 → "66.7B".
3
+ * @param {unknown} value
4
+ * @returns {string}
5
+ */
6
+ export function formatCount(value: unknown): string;
7
+ /**
8
+ * Exact grouped integer: 272000 → "272,000". A bigint or a string of digits stays exact past the
9
+ * JS-safe range; any other value is rounded.
10
+ * @param {unknown} value
11
+ * @returns {string}
12
+ */
13
+ export function formatInteger(value: unknown): string;
14
+ /**
15
+ * A cost in US dollars at cents: "$0.30", "$1,234.56", "$0.00" for zero, "<$0.01" for a positive
16
+ * amount under one cent. Accepts the recorded decimal string as it arrives.
17
+ * @param {unknown} value
18
+ * @returns {string}
19
+ */
20
+ export function formatCost(value: unknown): string;
21
+ /**
22
+ * A decimal at fixed places: 0.99 → "0.99", 0.5 with 2 places → "0.50".
23
+ * @param {unknown} value
24
+ * @param {number} places
25
+ * @returns {string}
26
+ */
27
+ export function formatDecimal(value: unknown, places: number): string;
28
+ /**
29
+ * Calendar dates are stable across host locales; date-only inputs stay on their UTC day.
30
+ * @param {string | number | Date} value
31
+ * @returns {string}
32
+ */
33
+ export function formatDate(value: string | number | Date): string;
34
+ /** What every formatter shows for a missing or unreadable value. */
35
+ export const MISSING_NUMBER: "\u2014";
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Validate an untrusted provider value before it enters canonical display APIs.
3
+ * @param {unknown} harness
4
+ * @param {string} operation
5
+ * @returns {asserts harness is Harness}
6
+ */
7
+ export function assertHarness(harness: unknown, operation: string): asserts harness is Harness;
8
+ /** @param {Harness} harness @returns {string} */
9
+ export function providerDisplayName(harness: Harness): string;
10
+ /** @param {Harness} harness @returns {ProviderBrand} */
11
+ export function providerBrand(harness: Harness): ProviderBrand;
12
+ /** @param {Harness} harness @returns {ProviderAccent} */
13
+ export function providerAccent(harness: Harness): ProviderAccent;
14
+ /** @typedef {import('@peasant-labs/schema').Harness} Harness */
15
+ /** @typedef {'claude'|'gemini'|'openai'|'opencode'|'cursor'|'strike'|'pi'} ProviderBrand */
16
+ /** @typedef {'amber'|'teal'|'olive'|'mauve'|'clay'} ProviderAccent */
17
+ /** @type {readonly Harness[]} */
18
+ export const PROVIDER_HARNESSES: readonly Harness[];
19
+ /** @type {Readonly<Record<Harness, string>>} */
20
+ export const PROVIDER_DISPLAY_NAMES: Readonly<Record<Harness, string>>;
21
+ /** @type {Readonly<Record<Harness, ProviderBrand>>} */
22
+ export const PROVIDER_BRANDS: Readonly<Record<Harness, ProviderBrand>>;
23
+ /** @type {Readonly<Record<Harness, ProviderAccent>>} */
24
+ export const PROVIDER_ACCENTS: Readonly<Record<Harness, ProviderAccent>>;
25
+ export type Harness = import("@peasant-labs/schema").Harness;
26
+ export type ProviderBrand = "claude" | "gemini" | "openai" | "opencode" | "cursor" | "strike" | "pi";
27
+ export type ProviderAccent = "amber" | "teal" | "olive" | "mauve" | "clay";
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Is this wire turn one of Claude Code's session metadata records rather than conversation?
3
+ * @param {TurnDetail} turn
4
+ * @param {string | undefined} harness the session's harness
5
+ * @returns {boolean}
6
+ */
7
+ export function isSessionMetadataTurn(turn: TurnDetail, harness: string | undefined): boolean;
8
+ /**
9
+ * Default turn prefilter the adapter applies independently per partition:
10
+ * preserve normalized evidence, including unknown provenance and folded refs.
11
+ * Only truly legacy rows lose empty/short banners or collapse equal adjacent
12
+ * content, preferring the tool-bearing copy. Pure, order-preserving. Exported
13
+ * so a host that pre-scopes turns can run the SAME filter.
14
+ * @param {TurnDetail[]} turns
15
+ * @returns {TurnDetail[]}
16
+ */
17
+ export function prefilterTurns(turns: TurnDetail[]): TurnDetail[];
18
+ /**
19
+ * Project the canonical wire payload (folded turns) into the cooked
20
+ * `TranscriptViewModel` every dumb transcript component renders. The SOLE
21
+ * wire-parse + legacy-git normalisation site.
22
+ *
23
+ * @param {TranscriptWireInput} payload canonical wire plus legacy git compatibility
24
+ * @param {AnnotationSummary[]} [annotations] separately-fetched entry annotations
25
+ * @param {TranscriptAnalyticsVM} [analytics] precomputed analytics; else derived on demand
26
+ * @param {AdaptTranscriptOptions} [options] optional post-resolution visible-turn projection
27
+ * @returns {TranscriptViewModel}
28
+ */
29
+ export function adaptTranscript(payload: TranscriptWireInput, annotations?: AnnotationSummary[], analytics?: TranscriptAnalyticsVM, options?: AdaptTranscriptOptions): TranscriptViewModel;
30
+ export { diffLines };
31
+ export type TranscriptWireInput = import("./wire-types.js").TranscriptWireInput;
32
+ export type SessionDetailPayload = import("./wire-types.js").SessionDetailPayload;
33
+ export type TurnDetail = import("./wire-types.js").TurnDetail;
34
+ export type ToolCallDetail = import("./wire-types.js").ToolCallDetail;
35
+ export type AnnotationSummary = import("./wire-types.js").AnnotationSummary;
36
+ export type CommitInfo = import("./wire-types.js").CommitInfo;
37
+ export type LegacyCommit = import("./wire-types.js").LegacyCommit;
38
+ export type LegacyGitContext = import("./wire-types.js").LegacyGitContext;
39
+ export type TranscriptViewModel = import("./view-model.js").TranscriptViewModel;
40
+ export type TranscriptAnalyticsVM = import("./view-model.js").TranscriptAnalyticsVM;
41
+ export type SessionVM = import("./view-model.js").SessionVM;
42
+ export type SessionGitVM = import("./view-model.js").SessionGitVM;
43
+ export type CommitVM = import("./view-model.js").CommitVM;
44
+ export type TurnVM = import("./view-model.js").TurnVM;
45
+ export type TaskGroupVM = import("./view-model.js").TaskGroupVM;
46
+ export type ToolCallVM = import("./view-model.js").ToolCallVM;
47
+ export type ToolGroup = import("./view-model.js").ToolGroup;
48
+ export type DiffLineVM = import("./view-model.js").DiffLineVM;
49
+ export type DiffHunkVM = import("./view-model.js").DiffHunkVM;
50
+ export type DiffEntryVM = import("./view-model.js").DiffEntryVM;
51
+ export type FileEntryVM = import("./view-model.js").FileEntryVM;
52
+ export type AnnotationVM = import("./view-model.js").AnnotationVM;
53
+ export type HighlightVM = import("./view-model.js").HighlightVM;
54
+ export type FilterIndexVM = import("./view-model.js").FilterIndexVM;
55
+ export type PhaseVM = import("./view-model.js").PhaseVM;
56
+ export type AdaptTranscriptOptions = {
57
+ /**
58
+ * post-resolution projection by canonical turn index
59
+ */
60
+ visibleTurnIndices?: readonly number[];
61
+ /**
62
+ * separately authorized read metadata; never durable content
63
+ */
64
+ relationshipNavigation?: import("@peasant-labs/schema").SessionRelationshipNavigation[];
65
+ };
66
+ import { diffLines } from './adapter.parse.js';
@@ -0,0 +1,103 @@
1
+ /** @typedef {import('./wire-types.js').ToolCallDetail} ToolCallDetail */
2
+ /** @typedef {import('./view-model.js').DiffLineVM} DiffLineVM */
3
+ /**
4
+ * The SOLE `JSON.parse` of a wire-encoded tool string in the lifted code. Every
5
+ * other parse helper here, the adapter, and the analytics util route through it,
6
+ * so a grep for `JSON.parse` of tool args/result yields exactly one hit. Returns
7
+ * `undefined` for empty or malformed input — callers degrade rather than throw.
8
+ *
9
+ * @param {string | undefined | null} raw
10
+ * @returns {unknown}
11
+ */
12
+ export function parseJson(raw: string | undefined | null): unknown;
13
+ /**
14
+ * Parse a tool call's `arguments` JSON string. Thin named entry point over the
15
+ * one `parseJson` site; the cooked `ToolCallVM.args` is this value (shape varies
16
+ * by tool, hence `unknown`).
17
+ * @param {string | undefined | null} raw
18
+ * @returns {unknown}
19
+ */
20
+ export function parseArgs(raw: string | undefined | null): unknown;
21
+ /**
22
+ * Parse a tool call's `result` JSON string. Thin named entry point over the one
23
+ * `parseJson` site; the cooked `ToolCallVM.output` is this value.
24
+ * @param {string | undefined | null} raw
25
+ * @returns {unknown}
26
+ */
27
+ export function parseResult(raw: string | undefined | null): unknown;
28
+ /**
29
+ * Extract the file path a tool call targets, preferring the wire `filePath`
30
+ * field and falling back to the common `file_path` / `path` / `notebook_path`
31
+ * argument keys. Consolidates the THREE duplicate `extractPath` definitions
32
+ * (tasks.ts, FilesView.tsx, file-rollup.ts) into one.
33
+ * @param {ToolCallDetail} call
34
+ * @returns {string | undefined}
35
+ */
36
+ export function extractPath(call: ToolCallDetail): string | undefined;
37
+ /**
38
+ * One old→new replacement inside an Edit / MultiEdit / NotebookEdit call.
39
+ * @typedef {object} EditPair
40
+ * @property {string} old_string
41
+ * @property {string} new_string
42
+ */
43
+ /**
44
+ * The list of old→new replacements for an edit-family tool call: the `edits[]`
45
+ * array for MultiEdit, else the single `old_string` / `new_string` pair. Used by
46
+ * BOTH the diff-hunk builder (adapter) and the churn counter (`countDiff`), so
47
+ * the argument shape is parsed in exactly one place.
48
+ * @param {ToolCallDetail} call
49
+ * @returns {EditPair[]}
50
+ */
51
+ export function editPairs(call: ToolCallDetail): EditPair[];
52
+ /**
53
+ * The full-file body a Write tool call lays down (its `content` argument).
54
+ * @param {ToolCallDetail} call
55
+ * @returns {string}
56
+ */
57
+ export function writeContent(call: ToolCallDetail): string;
58
+ /**
59
+ * Dependency-free line diff (LCS) → cooked `DiffLineVM[]`. fairtrade ships no
60
+ * `diff` package, so the adapter computes hunks itself. Line numbers are 1-based
61
+ * within the supplied snippet (the wire carries the edit snippet, not the file
62
+ * offset). Deterministic — no clock/randomness — so it is screenshot-stable.
63
+ * @param {string} oldText
64
+ * @param {string} newText
65
+ * @returns {DiffLineVM[]}
66
+ */
67
+ export function diffLines(oldText: string, newText: string): DiffLineVM[];
68
+ /**
69
+ * The cooked line diff of an edit-family or write tool call (one line list per replaced span) and
70
+ * its churn: the + and − lines of that same diff, so a rewrite of three lines counts +3 −3 and every
71
+ * count (the tool call, the diffs tab, a task's churn) agrees with the lines it heads. A span's
72
+ * trailing empty line is the newline artifact, not a line anyone wrote, so it is not counted, as the
73
+ * renderer does not show it. Undefined for any other kind, or an edit with no replacement. Memoised
74
+ * per call object, because the adapter and the analytics both ask and the line diff is quadratic in
75
+ * the span length.
76
+ * @param {ToolCallDetail} call
77
+ * @returns {{ spans: DiffLineVM[][], adds: number, dels: number } | undefined}
78
+ */
79
+ export function callDiff(call: ToolCallDetail): {
80
+ spans: DiffLineVM[][];
81
+ adds: number;
82
+ dels: number;
83
+ } | undefined;
84
+ /**
85
+ * Lines inserted / removed for an edit-family or write tool call: the churn of `callDiff`, zero
86
+ * for any other kind. Consolidates the THREE duplicate `countDiff` definitions. Pure: depends only
87
+ * on the parsed arguments, never a clock or the file system.
88
+ * @param {ToolCallDetail} call
89
+ * @returns {{ adds: number, dels: number }}
90
+ */
91
+ export function countDiff(call: ToolCallDetail): {
92
+ adds: number;
93
+ dels: number;
94
+ };
95
+ export type ToolCallDetail = import("./wire-types.js").ToolCallDetail;
96
+ export type DiffLineVM = import("./view-model.js").DiffLineVM;
97
+ /**
98
+ * One old→new replacement inside an Edit / MultiEdit / NotebookEdit call.
99
+ */
100
+ export type EditPair = {
101
+ old_string: string;
102
+ new_string: string;
103
+ };