@peasant-labs/fairtrade 0.0.40 → 0.0.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/THIRD_PARTY_NOTICES.md +14 -0
  2. package/dist/lib/{GraphLegend-nwqBLEcI.js → GraphLegend-CBKZsRta.js} +1259 -1399
  3. package/dist/lib/adapter-Dulh38C2.js +1214 -0
  4. package/dist/lib/commons.js +202 -201
  5. package/dist/lib/components.css +1 -1
  6. package/dist/lib/graph.js +474 -471
  7. package/dist/lib/share-fonts/AtkinsonHyperlegible-Bold.ttf +0 -0
  8. package/dist/lib/share-fonts/AtkinsonHyperlegible-Regular.ttf +0 -0
  9. package/dist/lib/share-fonts/AtkinsonHyperlegibleMono-Bold.ttf +0 -0
  10. package/dist/lib/share-fonts/AtkinsonHyperlegibleMono-Regular.ttf +0 -0
  11. package/dist/lib/share-fonts/OFL-AtkinsonHyperlegible.txt +92 -0
  12. package/dist/lib/share-fonts/OFL-AtkinsonHyperlegibleMono.txt +93 -0
  13. package/dist/lib/share.js +1311 -0
  14. package/dist/lib/time-CpVBzcqQ.js +157 -0
  15. package/dist/lib/types/AppSidebar.d.ts +2 -0
  16. package/dist/lib/types/BrandMark.d.ts +2 -6
  17. package/dist/lib/types/Menu.d.ts +7 -1
  18. package/dist/lib/types/brand-geometry.d.ts +22 -0
  19. package/dist/lib/types/commons/providers.d.ts +1 -1
  20. package/dist/lib/types/graph/CodeMapComposition.d.ts +4 -1
  21. package/dist/lib/types/graph/CodeMapNavigator.d.ts +5 -1
  22. package/dist/lib/types/share/ShareCard.d.ts +40 -0
  23. package/dist/lib/types/share/data.d.ts +54 -0
  24. package/dist/lib/types/share/fonts.d.ts +16 -0
  25. package/dist/lib/types/share/index.d.ts +5 -0
  26. package/dist/lib/types/share/marks.d.ts +23 -0
  27. package/dist/lib/types/share/metrics.d.ts +10 -0
  28. package/dist/lib/types/transcript/title.d.ts +21 -0
  29. package/dist/lib/types/ui/brand-geometry.d.ts +22 -0
  30. package/dist/lib/types/ui/format.d.ts +35 -0
  31. package/dist/lib/types/ui/provider-policy.d.ts +27 -0
  32. package/dist/lib/types/ui/transcript/adapter.d.ts +66 -0
  33. package/dist/lib/types/ui/transcript/adapter.parse.d.ts +103 -0
  34. package/dist/lib/types/ui/transcript/analytics.d.ts +213 -0
  35. package/dist/lib/types/ui/transcript/time.d.ts +47 -0
  36. package/dist/lib/types/ui/transcript/title.d.ts +84 -0
  37. package/dist/lib/types/ui/transcript/usage.d.ts +19 -0
  38. package/dist/lib/types/ui/transcript/view-model.d.ts +700 -0
  39. package/dist/lib/types/ui/transcript/wire-types.d.ts +63 -0
  40. package/dist/lib/{ui-DMUCYaeU.js → ui-BxiVcGs3.js} +3724 -4913
  41. package/dist/lib/ui.js +7 -5
  42. package/package.json +18 -6
@@ -0,0 +1,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 };
@@ -65,6 +65,8 @@ export function AppPage({ children, as: Tag, className, ...rest }: AppPageProps)
65
65
  * @typedef {Object} AppSidebarAccount
66
66
  * @property {string} handle shown as @handle; its first letter fills the square avatar.
67
67
  * @property {string} [href] makes the account row a link.
68
+ * @property {import('./Menu.jsx').MenuItem[]} [items] makes the account row its own menu (profile, settings, sign
69
+ * out), drawn as the same flat row with no caret and opening above the footer. Takes precedence over href.
68
70
  */
69
71
  /**
70
72
  * @typedef {Object} AppSidebarProps
@@ -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';
@@ -21,8 +21,12 @@
21
21
  * @param {React.ComponentType<any>} [props.icon] icon-only trigger: the glyph replaces the label and the caret
22
22
  * @param {string} [props.ariaLabel] the trigger's accessible name; required with `icon`, and the menu's name
23
23
  * @param {'sm'|'md'} [props.size='md'] `sm` uses the compact control height (header rows)
24
+ * @param {'bottom'|'top'} [props.side='bottom'] which side of the trigger the popout opens on; `top` for a
25
+ * trigger at the foot of a column (a sidebar's account row)
26
+ * @param {string} [props.triggerClassName] a host-drawn trigger: these classes replace the button's own,
27
+ * and the caret is left out, so a row can be its own menu trigger
24
28
  */
25
- export default function Menu({ label, items, align, caption, defaultOpen, icon: TriggerIcon, ariaLabel, size }: {
29
+ export default function Menu({ label, items, align, caption, defaultOpen, icon: TriggerIcon, ariaLabel, size, side, triggerClassName }: {
26
30
  label?: React.ReactNode;
27
31
  items?: MenuItem[];
28
32
  align?: "start" | "end";
@@ -31,6 +35,8 @@ export default function Menu({ label, items, align, caption, defaultOpen, icon:
31
35
  icon?: React.ComponentType<any>;
32
36
  ariaLabel?: string;
33
37
  size?: "sm" | "md";
38
+ side?: "bottom" | "top";
39
+ triggerClassName?: string;
34
40
  }): import("react").JSX.Element;
35
41
  export type MenuItem = {
36
42
  /**
@@ -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>>;
@@ -53,8 +53,10 @@
53
53
  * @param {import('./codeMapState.js').CodeMapState} [props.state] canonical controlled state
54
54
  * @param {Partial<import('./codeMapState.js').CodeMapState>} [props.defaultState] initial canonical uncontrolled state
55
55
  * @param {(state:import('./codeMapState.js').CodeMapState)=>void} [props.onStateChange]
56
+ * @param {'measured'|'unknown'} [props.lineCounts='measured'] passed to the navigator: 'unknown' leaves out every row's
57
+ * "N lines" figure when the host knows the payload's line counts were not measured
56
58
  */
57
- export default function CodeMapComposition({ payload, zoom, onZoomChange, selectedId, onSelect, onExpand, highlightedIds, nodeDeltas, structureEdgeDeltas, height, ariaLabel, canvasSlot, rail, toolbar, sheetTitle, sheetMeta, railSide, legend, canvasWrapperClassName, canvasWrapperStyle, className, presentation, navigatorSlot, onPresentationChange, viewport, onViewportChange, state, defaultState, onStateChange, }: {
59
+ export default function CodeMapComposition({ payload, zoom, onZoomChange, selectedId, onSelect, onExpand, highlightedIds, nodeDeltas, structureEdgeDeltas, height, ariaLabel, canvasSlot, rail, toolbar, sheetTitle, sheetMeta, railSide, legend, canvasWrapperClassName, canvasWrapperStyle, className, presentation, navigatorSlot, onPresentationChange, viewport, onViewportChange, state, defaultState, onStateChange, lineCounts, }: {
58
60
  payload?: import("./types.js").CodeMapPayload;
59
61
  zoom?: {
60
62
  level: "project" | "package" | "file";
@@ -98,6 +100,7 @@ export default function CodeMapComposition({ payload, zoom, onZoomChange, select
98
100
  state?: import("./codeMapState.js").CodeMapState;
99
101
  defaultState?: Partial<import("./codeMapState.js").CodeMapState>;
100
102
  onStateChange?: (state: import("./codeMapState.js").CodeMapState) => void;
103
+ lineCounts?: "measured" | "unknown";
101
104
  }): import("react").JSX.Element;
102
105
  /**
103
106
  * The persistent legend explaining the canvas's four orthogonal visual channels
@@ -17,8 +17,11 @@
17
17
  * @param {(id:string)=>void} [props.onOpenMap]
18
18
  * @param {(action:import('./codeMapState.js').CodeMapAction)=>void} [props.onStateAction]
19
19
  * @param {string} [props.ariaLabel='code map navigator']
20
+ * @param {'measured'|'unknown'} [props.lineCounts='measured'] whether the payload's line counts were measured.
21
+ * 'unknown' (the host could not read the project's languages, so every loc is an unmeasured 0) leaves the
22
+ * "N lines" figure out of every row instead of stating a false 0; a measured 0 still reads "0 lines".
20
23
  */
21
- export default function CodeMapNavigator({ payload, grain, expandedIds, onExpandedIdsChange, selectedId, onSelect, focusedId, onFocusChange, filter, onFilterChange, onOpenMap, onStateAction, ariaLabel, }: {
24
+ export default function CodeMapNavigator({ payload, grain, expandedIds, onExpandedIdsChange, selectedId, onSelect, focusedId, onFocusChange, filter, onFilterChange, onOpenMap, onStateAction, ariaLabel, lineCounts, }: {
22
25
  payload: import("./types.js").CodeMapPayload;
23
26
  grain?: "project" | "package" | "file";
24
27
  expandedIds?: Iterable<string>;
@@ -32,4 +35,5 @@ export default function CodeMapNavigator({ payload, grain, expandedIds, onExpand
32
35
  onOpenMap?: (id: string) => void;
33
36
  onStateAction?: (action: import("./codeMapState.js").CodeMapAction) => void;
34
37
  ariaLabel?: string;
38
+ lineCounts?: "measured" | "unknown";
35
39
  }): import("react").JSX.Element;
@@ -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';