@peasant-labs/fairtrade 0.0.6 → 0.0.9

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 (50) hide show
  1. package/LICENSE +202 -21
  2. package/dist/lib/InUseShell-ClWg74-v.js +3388 -0
  3. package/dist/lib/commons.js +803 -838
  4. package/dist/lib/components.css +1 -1
  5. package/dist/lib/graph.css +1 -1
  6. package/dist/lib/graph.js +871 -276
  7. package/dist/lib/tokens.css +4 -0
  8. package/dist/lib/tokens.json +16 -0
  9. package/dist/lib/types/CommitGraph.d.ts +50 -3
  10. package/dist/lib/types/MapCanvas.d.ts +45 -2
  11. package/dist/lib/types/ProviderIcon.d.ts +23 -20
  12. package/dist/lib/types/commons/providers.d.ts +7 -8
  13. package/dist/lib/types/commons/types.d.ts +3 -6
  14. package/dist/lib/types/graph/Changes.d.ts +8 -4
  15. package/dist/lib/types/graph/CodeMap.d.ts +17 -1
  16. package/dist/lib/types/graph/CodeMapComposition.d.ts +25 -1
  17. package/dist/lib/types/graph/CodeMapNavigator.d.ts +35 -0
  18. package/dist/lib/types/graph/GhostCommitNode.d.ts +20 -0
  19. package/dist/lib/types/graph/GhostGroup.d.ts +21 -0
  20. package/dist/lib/types/graph/HighlightEdge.d.ts +16 -0
  21. package/dist/lib/types/graph/InsightPanel.d.ts +25 -0
  22. package/dist/lib/types/graph/RankModeControl.d.ts +13 -0
  23. package/dist/lib/types/graph/RankedRow.d.ts +15 -0
  24. package/dist/lib/types/graph/ScentTag.d.ts +15 -0
  25. package/dist/lib/types/graph/SessionLane.d.ts +29 -0
  26. package/dist/lib/types/graph/SessionOverflowDisclosure.d.ts +23 -0
  27. package/dist/lib/types/graph/TouchedFileCluster.d.ts +17 -0
  28. package/dist/lib/types/graph/changeGraph.d.ts +12 -0
  29. package/dist/lib/types/graph/codeMapState.d.ts +240 -0
  30. package/dist/lib/types/graph/graphContractPolicy.d.ts +24 -0
  31. package/dist/lib/types/graph/index.d.ts +35 -1
  32. package/dist/lib/types/graph/ranking.d.ts +222 -0
  33. package/dist/lib/types/graph/timelineNavigation.d.ts +33 -0
  34. package/dist/lib/types/graph/types.d.ts +67 -440
  35. package/dist/lib/types/index.d.ts +2 -0
  36. package/dist/lib/types/provider-policy.d.ts +27 -0
  37. package/dist/lib/types/transcript/TranscriptViewer.d.ts +1 -1
  38. package/dist/lib/types/transcript/adapter.d.ts +5 -40
  39. package/dist/lib/types/transcript/graph/GraphLegend.d.ts +3 -3
  40. package/dist/lib/types/transcript/graph/GraphTurnNode.d.ts +2 -2
  41. package/dist/lib/types/transcript/index.d.ts +3 -1
  42. package/dist/lib/types/transcript/initial-position.d.ts +80 -0
  43. package/dist/lib/types/transcript/state-capabilities.d.ts +22 -1
  44. package/dist/lib/types/transcript/useTranscriptInitialPosition.d.ts +26 -0
  45. package/dist/lib/types/transcript/view-model.d.ts +16 -16
  46. package/dist/lib/types/transcript/wire-types.d.ts +46 -308
  47. package/dist/lib/{ui-TG4XLhWL.js → ui-FKKOy92_.js} +3295 -3455
  48. package/dist/lib/ui.js +4 -4
  49. package/package.json +66 -26
  50. package/dist/lib/InUseShell-CjtqHauP.js +0 -1532
package/dist/lib/graph.js CHANGED
@@ -1,28 +1,29 @@
1
- import { d as e, l as t, n, r, s as i, t as a, u as o } from "./InUseShell-CjtqHauP.js";
2
- import { useMemo as s, useRef as c, useState as l } from "react";
3
- import { jsx as u, jsxs as d } from "react/jsx-runtime";
4
- import { Box as f, Check as p, ChevronDown as m, ChevronRight as h, Coins as g, CornerDownRight as _, FileDiff as v, FileText as y, GitMerge as b, Hash as x, MessageSquare as S, RotateCw as C, Share2 as w, Tag as T, TriangleAlert as E, X as D } from "lucide-react";
1
+ import { $ as e, A as t, B as n, C as r, D as i, E as a, F as o, G as s, H as c, I as l, J as u, K as d, L as f, M as p, N as m, O as h, P as g, Q as _, R as v, S as y, T as b, U as x, V as S, W as C, X as w, Y as T, Z as E, _ as D, at as O, b as k, ct as A, d as j, et as ee, f as M, g as N, h as P, j as F, k as I, l as te, m as L, n as R, p as z, q as B, r as ne, s as re, t as ie, tt as ae, u as oe, ut as se, v as ce, w as le, x as ue, y as de, z as fe } from "./InUseShell-ClWg74-v.js";
2
+ import { useCallback as pe, useEffect as me, useMemo as V, useRef as H, useState as U } from "react";
3
+ import { Fragment as he, jsx as W, jsxs as G } from "react/jsx-runtime";
4
+ import { Box as ge, Check as _e, ChevronDown as ve, ChevronRight as K, Coins as ye, CornerDownRight as be, FileCode as xe, FileDiff as Se, FileText as Ce, Folder as we, GitMerge as Te, Hash as Ee, Map as De, MessageSquare as Oe, RotateCw as ke, Search as Ae, Share2 as je, Tag as Me, TriangleAlert as Ne, X as Pe } from "lucide-react";
5
+ import { AllChangeBindings as Fe, AllDiffLineKinds as Ie, AllEdgeViolationKinds as Le, AllFileChangeStatuses as Re, AllInsightKinds as ze, AllInsightProvenances as Be, AllMapNodeKinds as Ve, AllReadAttributionStates as He, AllReadStateGrades as Ue, ChangeBinding as We, DiffLineKind as Ge, EdgeViolationKind as Ke, FileChangeStatus as qe, InsightKind as Je, InsightProvenance as Ye, MapNodeKind as Xe, ReadAttributionState as Ze, ReadStateGrade as Qe, isChangeBinding as $e, isDiffLineKind as et, isEdgeViolationKind as tt, isFileChangeStatus as nt, isInsightKind as rt, isInsightProvenance as it, isMapNodeKind as at, isReadAttributionState as ot, isReadStateGrade as st } from "@peasant-labs/schema";
5
6
  //#region src/ui/graph/changeGraph.js
6
- var O = 6e4, k = 60 * O, A = 24 * k, j = 7 * A;
7
- function M(e, t) {
7
+ var ct = 6e4, q = 60 * ct, J = 24 * q, lt = 7 * J;
8
+ function Y(e, t) {
8
9
  if (e == null) return "";
9
10
  let n = Math.max(0, t - e);
10
- return n < k ? `${Math.max(1, Math.floor(n / O))}m ago` : n < A ? `${Math.floor(n / k)}h ago` : n < j ? `${Math.floor(n / A)}d ago` : `${Math.floor(n / j)}wk ago`;
11
+ return n < q ? `${Math.max(1, Math.floor(n / ct))}m ago` : n < J ? `${Math.floor(n / q)}h ago` : n < lt ? `${Math.floor(n / J)}d ago` : `${Math.floor(n / lt)}wk ago`;
11
12
  }
12
- function N(e, { nowMs: t }) {
13
- let n = e.recentCommits ?? [], r = e.changes ?? [], i = e.defaultBranch, a = r.filter((e) => !e.merged).slice().sort((e, t) => P(t) - P(e) || e.branch.localeCompare(t.branch)), o = r.filter((e) => e.merged && !e.reverted), s = r.filter((e) => e.merged && e.reverted), c = new Map(o.filter((e) => e.mergeCommitHash).map((e) => [e.mergeCommitHash, e])), l = a.map((e, t) => ({
13
+ function ut(e, { nowMs: t }) {
14
+ let n = e.recentCommits ?? [], r = e.changes ?? [], i = e.defaultBranch, a = e.sessions ?? [], o = new Map(a.map((e) => [e.sessionId, e])), s = new Set(n.flatMap((e) => e.sessionIds ?? [])), c = r.filter((e) => !e.merged).slice().sort((e, t) => dt(t) - dt(e) || e.branch.localeCompare(t.branch)), l = r.filter((e) => e.merged && !e.reverted), u = r.filter((e) => e.merged && e.reverted), d = new Map(l.filter((e) => e.mergeCommitHash).map((e) => [e.mergeCommitHash, e])), f = c.map((e, t) => ({
14
15
  change: e,
15
16
  lane: t + 1,
16
17
  baseHash: e.baseHash,
17
18
  tipMs: e.tipCommitMs ?? null
18
- })), u = [], d = /* @__PURE__ */ new Set(), f = (e) => {
19
- for (let n of l) {
20
- if (d.has(n.lane)) continue;
19
+ })), p = [], m = /* @__PURE__ */ new Set(), h = (e) => {
20
+ for (let n of f) {
21
+ if (m.has(n.lane)) continue;
21
22
  let r = n.tipMs;
22
23
  if (!(r == null ? e === null : e !== null && r >= e)) continue;
23
- d.add(n.lane);
24
+ m.add(n.lane);
24
25
  let i = n.change;
25
- u.push({
26
+ p.push({
26
27
  id: `tip:${i.branch}`,
27
28
  lane: n.lane,
28
29
  parents: n.baseHash ? [n.baseHash] : [],
@@ -30,94 +31,175 @@ function N(e, { nowMs: t }) {
30
31
  branch: i.branch,
31
32
  session: (i.sessionCount ?? 0) > 0,
32
33
  tip: !0,
33
- time: M(n.tipMs, t)
34
+ time: Y(n.tipMs, t)
34
35
  });
35
36
  }
36
37
  };
37
- return f(null), n.forEach((e, r) => {
38
- f(e.timeMs ?? -Infinity);
39
- let a = n[r + 1], o = a ? [a.hash] : [], s = c.get(e.hash);
40
- s && o.push(`tip:${s.branch}`), u.push({
38
+ h(null), n.forEach((e, r) => {
39
+ h(e.timeMs ?? -Infinity);
40
+ let a = n[r + 1], s = a ? [a.hash] : [], c = d.get(e.hash);
41
+ c && s.push(`tip:${c.branch}`), p.push({
41
42
  id: e.hash,
42
43
  lane: 0,
43
- parents: o,
44
+ parents: s,
44
45
  message: e.subject,
45
46
  branch: i,
46
47
  session: e.hasSession,
47
- merged: s ? !0 : void 0,
48
- time: M(e.timeMs, t)
48
+ sessionRefs: (e.sessionIds ?? []).flatMap((e) => {
49
+ let t = o.get(e);
50
+ return t ? [t] : [];
51
+ }),
52
+ merged: c ? !0 : void 0,
53
+ time: Y(e.timeMs, t)
49
54
  });
50
- }), f(-Infinity), {
51
- commits: u,
52
- reverted: s.map((e) => ({
53
- branch: e.branch,
54
- mergedAtMs: e.mergedAtMs ?? null,
55
- when: M(e.mergedAtMs, t)
56
- })),
57
- openCount: a.length,
58
- mergedCount: o.length + s.length
55
+ }), h(-Infinity);
56
+ let g = u.map((e) => ({
57
+ branch: e.branch,
58
+ mergedAtMs: e.mergedAtMs ?? null,
59
+ when: Y(e.mergedAtMs, t)
60
+ })), _ = a.filter((e) => e.hasCommitBinding === !0 && !s.has(e.sessionId));
61
+ return {
62
+ commits: p,
63
+ reverted: g,
64
+ openCount: c.length,
65
+ mergedCount: l.length + u.length,
66
+ unlinkedSessions: a.filter((e) => e.hasCommitBinding === !1 || e.hasCommitBinding === void 0 && !s.has(e.sessionId)),
67
+ outsideWindowSessions: _
59
68
  };
60
69
  }
61
- function P(e) {
70
+ function dt(e) {
62
71
  return e.tipCommitMs ?? Infinity;
63
72
  }
64
73
  //#endregion
65
74
  //#region src/ui/graph/Changes.jsx
66
- function F({ payload: t, projectLabel: n, selectedId: r, onSelectChange: i, onOpenMap: a, hasMore: o = !1, onShowOlder: c, nowMs: l }) {
67
- let p = l ?? Date.now(), { commits: m, reverted: h, openCount: g, mergedCount: _ } = s(() => N(t, { nowMs: p }), [t, p]), v = t.defaultBranch;
68
- return /* @__PURE__ */ d("div", {
75
+ function ft({ payload: e, projectLabel: t, selectedId: n, onNavigate: r, onSelectChange: i, onOpenMap: a, hasMore: o = !1, onShowOlder: s, onOpenSession: c, nowMs: l }) {
76
+ let u = l ?? Date.now(), { commits: d, reverted: f, unlinkedSessions: p, outsideWindowSessions: m, openCount: h, mergedCount: g } = V(() => ut(e, { nowMs: u }), [e, u]), _ = e.defaultBranch, v = V(() => new Set(d.filter((e) => (e.sessionRefs?.length ?? 0) > 2).map((e) => e.id)), [d]), [y, b] = U([]);
77
+ me(() => {
78
+ b((e) => {
79
+ let t = e.filter((e) => v.has(e));
80
+ return t.length === e.length ? e : t;
81
+ });
82
+ }, [v]);
83
+ let x = pe((e) => {
84
+ v.has(e) && b((t) => {
85
+ let n = new Set(t);
86
+ return n.has(e) ? n.delete(e) : n.add(e), [...n];
87
+ });
88
+ }, [v]);
89
+ return /* @__PURE__ */ G("div", {
69
90
  className: "gmp-root gmp-changes-root",
70
- children: [/* @__PURE__ */ d("div", {
91
+ children: [/* @__PURE__ */ G("div", {
71
92
  className: "gmp-changes-head",
72
- children: [/* @__PURE__ */ d("div", { children: [n && /* @__PURE__ */ d("span", {
93
+ children: [/* @__PURE__ */ G("div", { children: [t && /* @__PURE__ */ G("span", {
73
94
  className: "label",
74
- children: ["lines of work · ", n]
75
- }), /* @__PURE__ */ d("div", {
95
+ children: ["lines of work · ", t]
96
+ }), /* @__PURE__ */ G("div", {
76
97
  className: "gmp-changes-sub mono",
77
98
  children: [
78
- v ? `default branch ${v} · ` : "",
79
- g,
99
+ _ ? `default branch ${_} · ` : "",
100
+ h,
80
101
  " open · ",
81
- _,
102
+ g,
82
103
  " merged"
83
104
  ]
84
- })] }), /* @__PURE__ */ d("button", {
105
+ })] }), /* @__PURE__ */ G("button", {
85
106
  type: "button",
86
107
  className: "btn btn-secondary btn-sm",
87
- onClick: () => a?.(),
88
- children: [/* @__PURE__ */ u(f, {
108
+ onClick: () => {
109
+ r ? r({ type: "open-map" }) : a?.();
110
+ },
111
+ children: [/* @__PURE__ */ W(ge, {
89
112
  size: 14,
90
113
  "aria-hidden": "true"
91
114
  }), " open the map"]
92
115
  })]
93
- }), /* @__PURE__ */ d("div", {
116
+ }), /* @__PURE__ */ G("div", {
94
117
  className: "gmp-changes-body",
95
118
  children: [
96
- /* @__PURE__ */ u(e, {
119
+ /* @__PURE__ */ W(T, {
97
120
  className: "gmp-cg",
98
- commits: m,
99
- selectedId: r,
121
+ commits: d,
122
+ selectedId: n,
100
123
  label: "default-branch commit history",
124
+ onNavigate: r,
101
125
  onSelect: (e) => i?.(e),
126
+ onOpenSession: c,
102
127
  hasMore: o,
103
- onShowOlder: c
128
+ onShowOlder: s,
129
+ expandedCommitSessions: y,
130
+ onToggleCommitSessions: x
104
131
  }),
105
- h.length > 0 && /* @__PURE__ */ d("div", {
132
+ p.length > 0 && /* @__PURE__ */ G("section", {
133
+ className: "gmp-unlinked-sessions",
134
+ "aria-labelledby": "gmp-unlinked-sessions-heading",
135
+ children: [/* @__PURE__ */ W("h2", {
136
+ id: "gmp-unlinked-sessions-heading",
137
+ className: "sb-head gmp-unlinked-sessions-head",
138
+ children: "sessions not linked to a commit"
139
+ }), /* @__PURE__ */ W("div", {
140
+ className: "gmp-unlinked-sessions-list",
141
+ children: p.map((e) => /* @__PURE__ */ G("button", {
142
+ type: "button",
143
+ className: "gmp-unlinked-session",
144
+ onClick: () => {
145
+ r ? r({
146
+ type: "open-session",
147
+ sessionId: e.sessionId,
148
+ source: { kind: "unlinked" }
149
+ }) : c?.(e.sessionId);
150
+ },
151
+ children: [/* @__PURE__ */ W(O, { harness: e.harness }), /* @__PURE__ */ W("span", { children: e.title || e.sessionId })]
152
+ }, e.sessionId))
153
+ })]
154
+ }),
155
+ m.length > 0 && /* @__PURE__ */ G("section", {
156
+ className: "gmp-unlinked-sessions",
157
+ "aria-labelledby": "gmp-outside-window-sessions-heading",
158
+ children: [/* @__PURE__ */ W("h2", {
159
+ id: "gmp-outside-window-sessions-heading",
160
+ className: "sb-head gmp-unlinked-sessions-head",
161
+ children: "sessions linked outside this visible commit window"
162
+ }), /* @__PURE__ */ W("div", {
163
+ className: "gmp-unlinked-sessions-list",
164
+ children: m.map((e) => /* @__PURE__ */ G("button", {
165
+ type: "button",
166
+ className: "gmp-unlinked-session",
167
+ onClick: () => {
168
+ r ? r({
169
+ type: "open-session",
170
+ sessionId: e.sessionId,
171
+ source: { kind: "outside-window" }
172
+ }) : c?.(e.sessionId);
173
+ },
174
+ children: [/* @__PURE__ */ W(O, { harness: e.harness }), /* @__PURE__ */ W("span", { children: e.title || e.sessionId })]
175
+ }, e.sessionId))
176
+ })]
177
+ }),
178
+ f.length > 0 && /* @__PURE__ */ G("div", {
106
179
  className: "gmp-merged-sec",
107
- children: [/* @__PURE__ */ u("div", {
180
+ children: [/* @__PURE__ */ W("div", {
108
181
  className: "sb-head gmp-merged-head",
109
182
  children: "already merged in"
110
- }), /* @__PURE__ */ u("div", {
183
+ }), /* @__PURE__ */ W("div", {
111
184
  className: "gmp-merged-list",
112
- children: h.map((e) => /* @__PURE__ */ d("button", {
185
+ children: f.map((e) => /* @__PURE__ */ G("button", {
113
186
  type: "button",
114
187
  className: "gmp-merged-chip gmp-merged-revert",
115
- onClick: () => i?.({
116
- id: `revert:${e.branch}`,
117
- branch: e.branch
118
- }),
188
+ onClick: () => {
189
+ let t = {
190
+ id: `revert:${e.branch}`,
191
+ branch: e.branch
192
+ };
193
+ r ? r({
194
+ type: "open-change",
195
+ change: {
196
+ id: t.id,
197
+ branch: t.branch
198
+ }
199
+ }) : i?.(t);
200
+ },
119
201
  children: [
120
- /* @__PURE__ */ u(b, {
202
+ /* @__PURE__ */ W(Te, {
121
203
  size: 13,
122
204
  "aria-hidden": "true"
123
205
  }),
@@ -129,12 +211,12 @@ function F({ payload: t, projectLabel: n, selectedId: r, onSelectChange: i, onOp
129
211
  }, e.branch))
130
212
  })]
131
213
  }),
132
- /* @__PURE__ */ d("div", {
214
+ /* @__PURE__ */ G("div", {
133
215
  className: "gmp-changes-legend",
134
216
  children: [
135
- /* @__PURE__ */ d("span", {
217
+ /* @__PURE__ */ G("span", {
136
218
  className: "gmp-legend-item",
137
- children: [/* @__PURE__ */ u("span", {
219
+ children: [/* @__PURE__ */ W("span", {
138
220
  className: "cg-dot cg-dot-filled",
139
221
  style: {
140
222
  width: 9,
@@ -143,9 +225,9 @@ function F({ payload: t, projectLabel: n, selectedId: r, onSelectChange: i, onOp
143
225
  "aria-hidden": "true"
144
226
  }), " commit with a recorded session"]
145
227
  }),
146
- /* @__PURE__ */ d("span", {
228
+ /* @__PURE__ */ G("span", {
147
229
  className: "gmp-legend-item",
148
- children: [/* @__PURE__ */ u("span", {
230
+ children: [/* @__PURE__ */ W("span", {
149
231
  className: "cg-dot cg-dot-hollow",
150
232
  style: {
151
233
  width: 9,
@@ -154,7 +236,7 @@ function F({ payload: t, projectLabel: n, selectedId: r, onSelectChange: i, onOp
154
236
  "aria-hidden": "true"
155
237
  }), " no session captured"]
156
238
  }),
157
- /* @__PURE__ */ u("span", {
239
+ /* @__PURE__ */ W("span", {
158
240
  className: "gmp-legend-item gmp-legend-dim",
159
241
  children: "a filled dot also flies a sparkle · select a commit to open it"
160
242
  })
@@ -166,29 +248,29 @@ function F({ payload: t, projectLabel: n, selectedId: r, onSelectChange: i, onOp
166
248
  }
167
249
  //#endregion
168
250
  //#region src/ui/graph/ChangeDetail.jsx
169
- var I = {
251
+ var pt = {
170
252
  M: "changed",
171
253
  A: "added",
172
254
  D: "deleted",
173
255
  R: "renamed"
174
- }, L = {
256
+ }, mt = {
175
257
  A: "chip-ok",
176
258
  M: "",
177
259
  D: "chip-err",
178
260
  R: "chip-warn"
179
- }, R = {
261
+ }, ht = {
180
262
  context: "ctx",
181
263
  add: "add",
182
264
  del: "del"
183
265
  };
184
- function z(e) {
266
+ function gt(e) {
185
267
  let t = (e.split("/").pop() ?? e).replace(/[-_]+/g, " ").trim();
186
268
  return t.charAt(0).toUpperCase() + t.slice(1);
187
269
  }
188
- var B = (e) => e >= 1e3 ? `≈${(e / 1e3).toFixed(1)}k` : String(e);
189
- function V(e) {
270
+ var _t = (e) => e >= 1e3 ? `≈${(e / 1e3).toFixed(1)}k` : String(e);
271
+ function vt(e) {
190
272
  let t = e.oldStart, n = e.newStart, r = e.lines.map((e) => {
191
- let r = R[e.kind] ?? "ctx";
273
+ let r = ht[e.kind] ?? "ctx";
192
274
  return r === "add" ? {
193
275
  type: r,
194
276
  newNo: n++,
@@ -209,107 +291,109 @@ function V(e) {
209
291
  lines: r
210
292
  };
211
293
  }
212
- function H({ file: e, diff: t, open: n, onToggle: r }) {
294
+ function yt({ file: e, diff: t, open: n, onToggle: r }) {
295
+ t && d(t);
213
296
  let i = e.status, a = t ? new Set(t.hunks.map((e) => e.sessionId).filter(Boolean)).size : null;
214
- return /* @__PURE__ */ d("div", {
297
+ return /* @__PURE__ */ G("div", {
215
298
  className: "gmp-file",
216
- children: [/* @__PURE__ */ d("button", {
299
+ children: [/* @__PURE__ */ G("button", {
217
300
  type: "button",
218
301
  className: "gmp-file-head",
219
302
  "aria-expanded": n,
220
303
  onClick: r,
221
304
  children: [
222
- u(n ? m : h, {
305
+ W(n ? ve : K, {
223
306
  size: 14,
224
307
  "aria-hidden": "true"
225
308
  }),
226
- /* @__PURE__ */ u("span", {
309
+ /* @__PURE__ */ W("span", {
227
310
  className: "mono gmp-file-path",
228
311
  children: e.path
229
312
  }),
230
- /* @__PURE__ */ u("span", {
231
- className: "chip gmp-file-status " + (L[i] ?? ""),
232
- children: I[i] ?? i
313
+ /* @__PURE__ */ W("span", {
314
+ className: "chip gmp-file-status " + (mt[i] ?? ""),
315
+ children: pt[i] ?? i
233
316
  }),
234
- a != null && a > 0 && /* @__PURE__ */ d("span", {
317
+ a != null && a > 0 && /* @__PURE__ */ G("span", {
235
318
  className: "gmp-file-convos metaitem",
236
319
  children: [
237
- /* @__PURE__ */ u(S, {
320
+ /* @__PURE__ */ W(Oe, {
238
321
  size: 13,
239
322
  "aria-hidden": "true"
240
323
  }),
241
324
  " ",
242
- /* @__PURE__ */ u("span", {
325
+ /* @__PURE__ */ W("span", {
243
326
  className: "tnum",
244
327
  children: a
245
328
  })
246
329
  ]
247
330
  })
248
331
  ]
249
- }), n && /* @__PURE__ */ u("div", {
332
+ }), n && /* @__PURE__ */ W("div", {
250
333
  className: "gmp-file-body",
251
- children: t ? t.error ? /* @__PURE__ */ u("p", {
334
+ children: t ? t.error ? /* @__PURE__ */ W("p", {
252
335
  className: "gmp-diff-state gmp-diff-error mono",
253
336
  children: t.error
254
- }) : t.binary ? /* @__PURE__ */ u("p", {
337
+ }) : t.binary ? /* @__PURE__ */ W("p", {
255
338
  className: "gmp-diff-state mono",
256
339
  children: "binary file — no textual diff."
257
- }) : t.hunks.length === 0 ? /* @__PURE__ */ u("p", {
340
+ }) : t.hunks.length === 0 ? /* @__PURE__ */ W("p", {
258
341
  className: "gmp-diff-state mono",
259
342
  children: "no line changes."
260
- }) : t.hunks.map((e, n) => /* @__PURE__ */ d("div", {
343
+ }) : t.hunks.map((e, n) => /* @__PURE__ */ G("div", {
261
344
  className: "gmp-hunk",
262
345
  children: [
263
- e.sessionTitle && /* @__PURE__ */ d("div", {
346
+ e.sessionTitle && /* @__PURE__ */ G("div", {
264
347
  className: "gmp-hunk-attrib",
265
348
  children: [
266
- /* @__PURE__ */ u(_, {
349
+ /* @__PURE__ */ W(be, {
267
350
  size: 13,
268
351
  "aria-hidden": "true"
269
352
  }),
270
- /* @__PURE__ */ u("span", {
353
+ /* @__PURE__ */ W("span", {
271
354
  className: "gmp-hunk-from",
272
355
  children: "from"
273
356
  }),
274
- /* @__PURE__ */ u("span", {
357
+ /* @__PURE__ */ W("span", {
275
358
  className: "gmp-hunk-link",
276
359
  children: e.sessionTitle
277
360
  }),
278
- e.sessionId && /* @__PURE__ */ u("span", {
361
+ e.sessionId && /* @__PURE__ */ W("span", {
279
362
  className: "mono gmp-hunk-hash",
280
363
  children: e.sessionId.slice(0, 7)
281
364
  })
282
365
  ]
283
366
  }),
284
- /* @__PURE__ */ u(o, {
367
+ /* @__PURE__ */ W(u, {
285
368
  file: "",
286
- hunks: [V(e)],
369
+ hunks: [vt(e)],
287
370
  className: "gmp-hunk-diff"
288
371
  }),
289
- t.truncated && n === t.hunks.length - 1 && /* @__PURE__ */ u("p", {
372
+ t.truncated && n === t.hunks.length - 1 && /* @__PURE__ */ W("p", {
290
373
  className: "gmp-diff-state mono",
291
374
  children: "diff truncated (file exceeds the size cap)."
292
375
  })
293
376
  ]
294
- }, n)) : /* @__PURE__ */ u("p", {
377
+ }, n)) : /* @__PURE__ */ W("p", {
295
378
  className: "gmp-diff-state mono",
296
379
  children: "loading diff…"
297
380
  })
298
381
  })]
299
382
  });
300
383
  }
301
- function U({ payload: e, getDiff: t, title: n, annotation: r = "", onSaveAnnotation: i, onRemoveAnnotation: a, onOpenMap: o, onShare: s, onCopyRecap: m, initialOpenFiles: _ = {} }) {
302
- let [b, S] = l(_), [O, k] = l(null), [A, j] = l(!1), [M, N] = l(""), P = c({}), F = c(null), I = n ?? z(e.branch), L = e.work.length, R = e.newEdges.length, V = e.removedEdges.length, U = (e) => S((t) => ({
384
+ function bt({ payload: e, getDiff: t, title: n, annotation: r = "", onSaveAnnotation: i, onRemoveAnnotation: a, onOpenMap: o, onShare: c, onCopyRecap: l, initialOpenFiles: u = {} }) {
385
+ s(e);
386
+ let [d, f] = U(u), [p, m] = U(null), [h, g] = U(!1), [_, v] = U(""), y = H({}), b = H(null), x = n ?? gt(e.branch), S = e.work.length, C = e.newEdges.length, w = e.removedEdges.length, T = (e) => f((t) => ({
303
387
  ...t,
304
388
  [e]: !t[e]
305
389
  }));
306
- function W(e, t) {
307
- if (k(e), t) {
308
- S((e) => ({
390
+ function E(e, t) {
391
+ if (m(e), t) {
392
+ f((e) => ({
309
393
  ...e,
310
394
  [t]: !0
311
395
  }));
312
- let e = P.current[t], n = F.current;
396
+ let e = y.current[t], n = b.current;
313
397
  if (e && n) {
314
398
  let t = window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
315
399
  n.scrollTo({
@@ -319,106 +403,106 @@ function U({ payload: e, getDiff: t, title: n, annotation: r = "", onSaveAnnotat
319
403
  }
320
404
  }
321
405
  }
322
- function G(e) {
406
+ function D(e) {
323
407
  e.preventDefault();
324
- let t = M.trim();
325
- t && i?.(t), j(!1), N("");
408
+ let t = _.trim();
409
+ t && i?.(t), g(!1), v("");
326
410
  }
327
- let K = e.files[0]?.path;
328
- return /* @__PURE__ */ d("div", {
411
+ let O = e.files[0]?.path;
412
+ return /* @__PURE__ */ G("div", {
329
413
  className: "gmp-root gmp-detail-root",
330
- ref: F,
414
+ ref: b,
331
415
  children: [
332
- /* @__PURE__ */ d("div", {
416
+ /* @__PURE__ */ G("div", {
333
417
  className: "gmp-detail-head",
334
418
  children: [
335
- /* @__PURE__ */ d("div", {
419
+ /* @__PURE__ */ G("div", {
336
420
  className: "crumb",
337
421
  children: [
338
422
  "review ",
339
- /* @__PURE__ */ u(h, {
423
+ /* @__PURE__ */ W(K, {
340
424
  size: 13,
341
425
  "aria-hidden": "true"
342
426
  }),
343
427
  " ",
344
428
  e.defaultBranch,
345
429
  " ",
346
- /* @__PURE__ */ u(h, {
430
+ /* @__PURE__ */ W(K, {
347
431
  size: 13,
348
432
  "aria-hidden": "true"
349
433
  }),
350
434
  " ",
351
- /* @__PURE__ */ u("span", {
435
+ /* @__PURE__ */ W("span", {
352
436
  className: "cur",
353
437
  children: e.branch
354
438
  })
355
439
  ]
356
440
  }),
357
- /* @__PURE__ */ u("div", {
441
+ /* @__PURE__ */ W("div", {
358
442
  className: "gmp-detail-title",
359
- children: I
443
+ children: x
360
444
  }),
361
- /* @__PURE__ */ d("p", {
445
+ /* @__PURE__ */ G("p", {
362
446
  className: "gmp-caption",
363
447
  children: [
364
448
  "this line of work touched",
365
449
  " ",
366
- /* @__PURE__ */ d("button", {
450
+ /* @__PURE__ */ G("button", {
367
451
  type: "button",
368
- className: "gmp-frag" + (O === "files" ? " gmp-frag-on" : ""),
369
- onClick: () => W("files", K),
452
+ className: "gmp-frag" + (p === "files" ? " gmp-frag-on" : ""),
453
+ onClick: () => E("files", O),
370
454
  children: [e.filesChanged, " files"]
371
455
  }),
372
456
  " ",
373
457
  "across",
374
458
  " ",
375
- /* @__PURE__ */ d("button", {
459
+ /* @__PURE__ */ G("button", {
376
460
  type: "button",
377
- className: "gmp-frag" + (O === "conversations" ? " gmp-frag-on" : ""),
378
- onClick: () => W("conversations"),
379
- children: [L, " conversations"]
461
+ className: "gmp-frag" + (p === "conversations" ? " gmp-frag-on" : ""),
462
+ onClick: () => E("conversations"),
463
+ children: [S, " conversations"]
380
464
  }),
381
465
  ", reshaping",
382
466
  " ",
383
- /* @__PURE__ */ d("button", {
467
+ /* @__PURE__ */ G("button", {
384
468
  type: "button",
385
- className: "gmp-frag" + (O === "conn" ? " gmp-frag-on" : ""),
386
- onClick: () => W("conn"),
469
+ className: "gmp-frag" + (p === "conn" ? " gmp-frag-on" : ""),
470
+ onClick: () => E("conn"),
387
471
  children: [
388
472
  "+",
389
- R,
473
+ C,
390
474
  "/−",
391
- V,
475
+ w,
392
476
  " connections"
393
477
  ]
394
478
  }),
395
479
  "."
396
480
  ]
397
481
  }),
398
- /* @__PURE__ */ u("span", {
482
+ /* @__PURE__ */ W("span", {
399
483
  className: "gmp-caption-hint mono",
400
484
  children: "click any number to jump to its proof"
401
485
  })
402
486
  ]
403
487
  }),
404
- (e.frictions.length > 0 || e.violations.length > 0) && /* @__PURE__ */ d("div", {
488
+ (e.frictions.length > 0 || e.violations.length > 0) && /* @__PURE__ */ G("div", {
405
489
  className: "gmp-signals",
406
- children: [e.frictions.map((e, t) => /* @__PURE__ */ d("span", {
490
+ children: [e.frictions.map((e, t) => /* @__PURE__ */ G("span", {
407
491
  className: "gmp-signal",
408
492
  children: [
409
- /* @__PURE__ */ u(C, {
493
+ /* @__PURE__ */ W(ke, {
410
494
  size: 14,
411
495
  "aria-hidden": "true"
412
496
  }),
413
497
  " ",
414
498
  e.label,
415
499
  " · ",
416
- /* @__PURE__ */ u("span", {
500
+ /* @__PURE__ */ W("span", {
417
501
  className: "mono",
418
502
  children: e.file
419
503
  }),
420
504
  " ",
421
- /* @__PURE__ */ d("b", {
505
+ /* @__PURE__ */ G("b", {
422
506
  className: "tnum",
423
507
  children: [e.count, "×"]
424
508
  }),
@@ -426,15 +510,15 @@ function U({ payload: e, getDiff: t, title: n, annotation: r = "", onSaveAnnotat
426
510
  e.sessions,
427
511
  " conversations"
428
512
  ]
429
- }, t)), e.violations.length > 0 && /* @__PURE__ */ d("span", {
513
+ }, t)), e.violations.length > 0 && /* @__PURE__ */ G("span", {
430
514
  className: "gmp-signal gmp-signal-warn",
431
515
  children: [
432
- /* @__PURE__ */ u(E, {
516
+ /* @__PURE__ */ W(Ne, {
433
517
  size: 14,
434
518
  "aria-hidden": "true"
435
519
  }),
436
520
  " ",
437
- /* @__PURE__ */ u("b", {
521
+ /* @__PURE__ */ W("b", {
438
522
  className: "tnum",
439
523
  children: e.violations.length
440
524
  }),
@@ -442,13 +526,13 @@ function U({ payload: e, getDiff: t, title: n, annotation: r = "", onSaveAnnotat
442
526
  ]
443
527
  })]
444
528
  }),
445
- /* @__PURE__ */ d("div", {
529
+ /* @__PURE__ */ G("div", {
446
530
  className: "gmp-totals",
447
531
  children: [
448
- /* @__PURE__ */ d("span", {
532
+ /* @__PURE__ */ G("span", {
449
533
  className: "metaitem tnum",
450
534
  children: [
451
- /* @__PURE__ */ u(v, {
535
+ /* @__PURE__ */ W(Se, {
452
536
  size: 14,
453
537
  "aria-hidden": "true"
454
538
  }),
@@ -457,37 +541,37 @@ function U({ payload: e, getDiff: t, title: n, annotation: r = "", onSaveAnnotat
457
541
  " files touched"
458
542
  ]
459
543
  }),
460
- /* @__PURE__ */ d("span", {
544
+ /* @__PURE__ */ G("span", {
461
545
  className: "metaitem tnum",
462
546
  children: [
463
- /* @__PURE__ */ d("span", {
547
+ /* @__PURE__ */ G("span", {
464
548
  className: "gmp-add",
465
- children: ["+", R]
549
+ children: ["+", C]
466
550
  }),
467
551
  "/",
468
- /* @__PURE__ */ d("span", {
552
+ /* @__PURE__ */ G("span", {
469
553
  className: "gmp-del",
470
- children: ["−", V]
554
+ children: ["−", w]
471
555
  }),
472
556
  " connections"
473
557
  ]
474
558
  }),
475
- /* @__PURE__ */ d("span", {
559
+ /* @__PURE__ */ G("span", {
476
560
  className: "metaitem tnum",
477
561
  children: [
478
- /* @__PURE__ */ u(x, {
562
+ /* @__PURE__ */ W(Ee, {
479
563
  size: 14,
480
564
  "aria-hidden": "true"
481
565
  }),
482
566
  " ai wrote ",
483
- B(e.outputTokens),
567
+ _t(Number(e.outputTokens)),
484
568
  " tokens"
485
569
  ]
486
570
  }),
487
- e.costUsd != null && /* @__PURE__ */ d("span", {
571
+ e.costUsd != null && /* @__PURE__ */ G("span", {
488
572
  className: "metaitem tnum",
489
573
  children: [
490
- /* @__PURE__ */ u(g, {
574
+ /* @__PURE__ */ W(ye, {
491
575
  size: 14,
492
576
  "aria-hidden": "true"
493
577
  }),
@@ -497,62 +581,62 @@ function U({ payload: e, getDiff: t, title: n, annotation: r = "", onSaveAnnotat
497
581
  })
498
582
  ]
499
583
  }),
500
- /* @__PURE__ */ d("div", {
584
+ /* @__PURE__ */ G("div", {
501
585
  className: "gmp-detail-sec",
502
- children: [/* @__PURE__ */ u("div", {
586
+ children: [/* @__PURE__ */ W("div", {
503
587
  className: "sb-head gmp-detail-sechead",
504
588
  children: "files changed · click a path to open its diff"
505
- }), /* @__PURE__ */ u("div", {
589
+ }), /* @__PURE__ */ W("div", {
506
590
  className: "gmp-files",
507
- children: e.files.map((e) => /* @__PURE__ */ u("div", {
591
+ children: e.files.map((e) => /* @__PURE__ */ W("div", {
508
592
  ref: (t) => {
509
- P.current[e.path] = t;
593
+ y.current[e.path] = t;
510
594
  },
511
- children: /* @__PURE__ */ u(H, {
595
+ children: /* @__PURE__ */ W(yt, {
512
596
  file: e,
513
- diff: b[e.path] ? t?.(e) : void 0,
514
- open: !!b[e.path],
515
- onToggle: () => U(e.path)
597
+ diff: d[e.path] ? t?.(e) : void 0,
598
+ open: !!d[e.path],
599
+ onToggle: () => T(e.path)
516
600
  })
517
601
  }, e.path))
518
602
  })]
519
603
  }),
520
- /* @__PURE__ */ d("div", {
604
+ /* @__PURE__ */ G("div", {
521
605
  className: "gmp-detail-sec",
522
- children: [/* @__PURE__ */ u("div", {
606
+ children: [/* @__PURE__ */ W("div", {
523
607
  className: "sb-head gmp-detail-sechead",
524
608
  children: "your annotation"
525
- }), /* @__PURE__ */ d("div", {
609
+ }), /* @__PURE__ */ G("div", {
526
610
  className: "gmp-annot",
527
611
  children: [
528
- r && /* @__PURE__ */ d("span", {
612
+ r && /* @__PURE__ */ G("span", {
529
613
  className: "gmp-label-chip gmp-annot-chip",
530
614
  children: [
531
- /* @__PURE__ */ u(T, {
615
+ /* @__PURE__ */ W(Me, {
532
616
  size: 12,
533
617
  "aria-hidden": "true"
534
618
  }),
535
619
  " ",
536
620
  r,
537
- /* @__PURE__ */ u("button", {
621
+ /* @__PURE__ */ W("button", {
538
622
  type: "button",
539
623
  className: "gmp-annot-x",
540
624
  "aria-label": "remove annotation",
541
625
  onClick: () => a?.(),
542
- children: /* @__PURE__ */ u(D, {
626
+ children: /* @__PURE__ */ W(Pe, {
543
627
  size: 11,
544
628
  "aria-hidden": "true"
545
629
  })
546
630
  })
547
631
  ]
548
632
  }),
549
- /* @__PURE__ */ d("button", {
633
+ /* @__PURE__ */ G("button", {
550
634
  type: "button",
551
635
  className: "gmp-annot-add",
552
- "aria-expanded": A,
553
- onClick: () => j((e) => !e),
636
+ "aria-expanded": h,
637
+ onClick: () => g((e) => !e),
554
638
  children: [
555
- /* @__PURE__ */ u(T, {
639
+ /* @__PURE__ */ W(Me, {
556
640
  size: 13,
557
641
  "aria-hidden": "true"
558
642
  }),
@@ -560,34 +644,34 @@ function U({ payload: e, getDiff: t, title: n, annotation: r = "", onSaveAnnotat
560
644
  r ? "change label" : "add a label"
561
645
  ]
562
646
  }),
563
- A && /* @__PURE__ */ d("form", {
647
+ h && /* @__PURE__ */ G("form", {
564
648
  className: "gmp-annot-pop",
565
- onSubmit: G,
649
+ onSubmit: D,
566
650
  children: [
567
- /* @__PURE__ */ u("span", {
651
+ /* @__PURE__ */ W("span", {
568
652
  className: "label",
569
653
  children: "user.custom_label"
570
654
  }),
571
- /* @__PURE__ */ u("input", {
655
+ /* @__PURE__ */ W("input", {
572
656
  className: "input",
573
657
  type: "text",
574
658
  autoFocus: !0,
575
- value: M,
576
- onChange: (e) => N(e.target.value),
659
+ value: _,
660
+ onChange: (e) => v(e.target.value),
577
661
  placeholder: "e.g. good handoff",
578
662
  "aria-label": "annotation value"
579
663
  }),
580
- /* @__PURE__ */ d("div", {
664
+ /* @__PURE__ */ G("div", {
581
665
  className: "gmp-annot-pop-foot",
582
- children: [/* @__PURE__ */ u("button", {
666
+ children: [/* @__PURE__ */ W("button", {
583
667
  type: "button",
584
668
  className: "btn btn-ghost btn-sm",
585
- onClick: () => j(!1),
669
+ onClick: () => g(!1),
586
670
  children: "cancel"
587
- }), /* @__PURE__ */ d("button", {
671
+ }), /* @__PURE__ */ G("button", {
588
672
  type: "submit",
589
673
  className: "btn btn-primary btn-sm",
590
- children: [/* @__PURE__ */ u(p, {
674
+ children: [/* @__PURE__ */ W(_e, {
591
675
  size: 13,
592
676
  "aria-hidden": "true"
593
677
  }), " save"]
@@ -598,42 +682,42 @@ function U({ payload: e, getDiff: t, title: n, annotation: r = "", onSaveAnnotat
598
682
  ]
599
683
  })]
600
684
  }),
601
- /* @__PURE__ */ d("div", {
685
+ /* @__PURE__ */ G("div", {
602
686
  className: "gmp-exits",
603
687
  children: [
604
- /* @__PURE__ */ d("button", {
688
+ /* @__PURE__ */ G("button", {
605
689
  type: "button",
606
690
  className: "btn btn-secondary btn-sm",
607
691
  onClick: () => o?.(),
608
- children: [/* @__PURE__ */ u(f, {
692
+ children: [/* @__PURE__ */ W(ge, {
609
693
  size: 14,
610
694
  "aria-hidden": "true"
611
695
  }), " see this work on the code map"]
612
696
  }),
613
- /* @__PURE__ */ d("button", {
697
+ /* @__PURE__ */ G("button", {
614
698
  type: "button",
615
699
  className: "btn btn-secondary btn-sm",
616
- onClick: () => s?.(),
700
+ onClick: () => c?.(),
617
701
  children: [
618
- /* @__PURE__ */ u(w, {
702
+ /* @__PURE__ */ W(je, {
619
703
  size: 14,
620
704
  "aria-hidden": "true"
621
705
  }),
622
706
  " share ",
623
- L,
707
+ S,
624
708
  " conversations…"
625
709
  ]
626
710
  }),
627
- /* @__PURE__ */ d("button", {
711
+ /* @__PURE__ */ G("button", {
628
712
  type: "button",
629
713
  className: "btn btn-secondary btn-sm",
630
- onClick: () => m?.(),
631
- children: [/* @__PURE__ */ u(y, {
714
+ onClick: () => l?.(),
715
+ children: [/* @__PURE__ */ W(Ce, {
632
716
  size: 14,
633
717
  "aria-hidden": "true"
634
718
  }), " copy recap"]
635
719
  }),
636
- /* @__PURE__ */ d("code", {
720
+ /* @__PURE__ */ G("code", {
637
721
  className: "gmp-gitdiff mono",
638
722
  children: [
639
723
  "git diff ",
@@ -644,7 +728,7 @@ function U({ payload: e, getDiff: t, title: n, annotation: r = "", onSaveAnnotat
644
728
  })
645
729
  ]
646
730
  }),
647
- /* @__PURE__ */ u("p", {
731
+ /* @__PURE__ */ W("p", {
648
732
  className: "gmp-boundary mono",
649
733
  children: "shows what changed and the recorded work behind it, not whether the change is correct or secure."
650
734
  })
@@ -653,57 +737,77 @@ function U({ payload: e, getDiff: t, title: n, annotation: r = "", onSaveAnnotat
653
737
  }
654
738
  //#endregion
655
739
  //#region src/ui/graph/CodeMap.jsx
656
- var W = Object.freeze({
740
+ var xt = Object.freeze({
657
741
  project: "overview",
658
742
  package: "folders",
659
743
  file: "files"
660
- }), G = Object.freeze({
744
+ }), St = Object.freeze({
661
745
  overview: "project",
662
746
  folders: "package",
663
747
  files: "file"
664
748
  });
665
- function K({ payload: e, zoom: n, onZoomChange: r, selectedId: i, onSelect: a, onExpand: o, highlightedIds: l, nodeDeltas: d, structureEdgeDeltas: f, height: p = 520, ariaLabel: m = "code map", className: h = "" }) {
666
- let g = s(() => {
749
+ function Ct({ payload: e, zoom: t, onZoomChange: n, selectedId: r, onSelect: i, onExpand: a, highlightedIds: o, nodeDeltas: s, structureEdgeDeltas: c, height: l = 520, ariaLabel: u = "code map", className: d = "", viewport: f, onViewportChange: p, state: m, onStateChange: h }) {
750
+ let g = V(() => {
667
751
  let t = /* @__PURE__ */ new Map();
668
752
  for (let n of e?.nodes ?? []) t.set(n.id, n);
669
753
  return t;
670
- }, [e?.nodes]), _ = s(() => q(e), [e]), v = W[n?.level ?? "package"] ?? "folders", y = n?.expanded ?? [], b = n?.level !== void 0, x = c(v);
671
- return b && (x.current = v), /* @__PURE__ */ u(t, {
672
- data: _,
673
- grain: v,
674
- expandedIds: y,
675
- selectedId: i,
676
- highlightedIds: l,
677
- nodeDeltas: d,
678
- edgeDeltas: f,
679
- onSelect: (e) => a?.(e, e ? g.get(e) ?? null : null),
680
- onExpand: o,
754
+ }, [e?.nodes]), _ = V(() => m === void 0 ? null : z(m), [m]), v = V(() => _ ? L(e, _) : null, [e, _]), y = V(() => wt(e && {
755
+ ...e,
756
+ nodes: v?.canvas.allNodes ?? e.nodes
757
+ }), [e, v?.canvas.allNodes]), b = v ? xt[v.canvas.grain] ?? "folders" : xt[t?.level ?? "package"], x = v?.canvas.expandedIds ?? t?.expanded, S = H(b);
758
+ S.current = b;
759
+ function C(e) {
760
+ if (!_) return;
761
+ let t = D(_, e);
762
+ M(_, t) || h?.(t);
763
+ }
764
+ return /* @__PURE__ */ W(te, {
765
+ data: y,
766
+ grain: b,
767
+ expandedIds: x,
768
+ visibleIds: v?.canvas.visibleIds,
769
+ hierarchy: v?.canvas.hierarchy,
770
+ selectedId: v ? v.canvas.selectedId : r,
771
+ highlightedIds: o,
772
+ nodeDeltas: s,
773
+ edgeDeltas: c,
774
+ onSelect: (e) => {
775
+ i?.(e, e ? g.get(e) ?? null : null);
776
+ },
777
+ onExpand: a,
681
778
  onGrainChange: (e) => {
682
- x.current = e, r?.({
683
- level: G[e] ?? "package",
779
+ S.current = e, n?.({
780
+ level: St[e] ?? "package",
684
781
  expanded: []
685
782
  });
686
783
  },
687
784
  onExpandedIdsChange: (e) => {
688
- r?.({
689
- level: G[x.current] ?? "package",
785
+ n?.({
786
+ level: St[S.current] ?? "package",
690
787
  expanded: e
691
788
  });
692
789
  },
693
- height: p,
694
- ariaLabel: m,
695
- className: h
790
+ height: l,
791
+ ariaLabel: u,
792
+ className: d,
793
+ viewport: v ? v.canvas.viewport : f,
794
+ onViewportChange: (e) => {
795
+ p?.(e);
796
+ },
797
+ onStateAction: _ ? C : void 0,
798
+ canonicalControlled: _ !== null
696
799
  });
697
800
  }
698
- function q(e) {
699
- let t = e?.nodes ?? [], n = Y(e?.violations ?? []);
801
+ function wt(e) {
802
+ e && B(e);
803
+ let t = e?.nodes ?? [], n = Et(e?.violations ?? []);
700
804
  return {
701
805
  nodes: t.map((e) => ({
702
806
  id: e.id,
703
807
  label: e.name || e.id,
704
808
  kind: e.kind === "file" ? "file" : "folder",
705
809
  loc: e.loc ?? 0,
706
- coverage: J(e.recordedFiles, e.totalFiles),
810
+ coverage: Tt(e.recordedFiles, e.totalFiles),
707
811
  parent: e.parent || void 0,
708
812
  violations: n.get(e.id) ?? 0,
709
813
  layer: e.layer,
@@ -717,86 +821,380 @@ function q(e) {
717
821
  }))
718
822
  };
719
823
  }
720
- function J(e, t) {
824
+ function Tt(e, t) {
721
825
  let n = Number(t) || 0;
722
826
  if (n <= 0) return 0;
723
827
  let r = Math.max(0, Math.min(1, (Number(e) || 0) / n));
724
828
  return Math.max(0, Math.min(4, Math.round(r * 4)));
725
829
  }
726
- function Y(e) {
830
+ function Et(e) {
727
831
  let t = /* @__PURE__ */ new Map();
728
- for (let n of e) X(t, n.from), X(t, n.to);
832
+ for (let n of e) Dt(t, n.from), Dt(t, n.to);
729
833
  return t;
730
834
  }
731
- function X(e, t) {
835
+ function Dt(e, t) {
732
836
  t && e.set(t, (e.get(t) ?? 0) + 1);
733
837
  }
734
838
  //#endregion
839
+ //#region src/ui/graph/CodeMapNavigator.jsx
840
+ function Ot({ payload: e, grain: t = "package", expandedIds: n, onExpandedIdsChange: r, selectedId: i = null, onSelect: a, focusedId: o, onFocusChange: s, filter: c = "", onFilterChange: l, onOpenMap: u, onStateAction: d, ariaLabel: f = "code map navigator" }) {
841
+ let [p, m] = U(() => /* @__PURE__ */ new Set()), [h, g] = U(null), _ = n === void 0 ? p : new Set(n), v = o === void 0 ? h : o, y = H(/* @__PURE__ */ new Map()), b = V(() => L(e, z({
842
+ grain: t,
843
+ expandedIds: Array.from(_),
844
+ selectedId: i,
845
+ navigatorFocusedId: v,
846
+ navigatorFilter: c
847
+ })), [
848
+ e,
849
+ t,
850
+ At(_),
851
+ i,
852
+ v,
853
+ c
854
+ ]), x = b.rows, S = b.focusedId, C = b.selected, w = C ? x.find((e) => e.node.id === C.id) : null, T = !!w?.canExpand && !w.forcedOpen;
855
+ function E(e) {
856
+ n === void 0 && m(e), d?.({
857
+ type: "set-expanded",
858
+ ids: Array.from(e)
859
+ }), r?.(Array.from(e));
860
+ }
861
+ function D(e) {
862
+ let t = new Set(_);
863
+ t.has(e) ? t.delete(e) : t.add(e), E(t);
864
+ }
865
+ function O(e) {
866
+ o === void 0 && g(e), d?.({
867
+ type: "focus",
868
+ id: e
869
+ }), s?.(e), y.current.get(e)?.focus();
870
+ }
871
+ function k(e) {
872
+ o === void 0 && g(e.id), y.current.get(e.id)?.focus(), d?.({
873
+ type: "select",
874
+ id: e.id
875
+ }), s?.(e.id), a?.(e.id, e);
876
+ }
877
+ function A(e, t) {
878
+ let n = x[t];
879
+ if (!n) return;
880
+ let { node: r } = n, i = null;
881
+ if (e.key === "ArrowDown") i = x[Math.min(t + 1, x.length - 1)]?.node.id;
882
+ else if (e.key === "ArrowUp") i = x[Math.max(t - 1, 0)]?.node.id;
883
+ else if (e.key === "Home") i = x[0]?.node.id;
884
+ else if (e.key === "End") i = x[x.length - 1]?.node.id;
885
+ else if (e.key === "ArrowRight" && (n.canExpand || n.forcedOpen)) n.forcedOpen || n.expanded ? i = n.childIds[0] ?? null : _.has(r.id) || D(r.id);
886
+ else if (e.key === "ArrowLeft") !n.forcedOpen && n.canExpand && n.expanded ? D(r.id) : i = n.parentId;
887
+ else if (e.key === "Enter" || e.key === " ") {
888
+ k(r), e.preventDefault();
889
+ return;
890
+ } else return;
891
+ e.preventDefault(), i && O(i);
892
+ }
893
+ return /* @__PURE__ */ G("section", {
894
+ className: "gmp-navigator",
895
+ "aria-label": f,
896
+ children: [
897
+ /* @__PURE__ */ G("header", {
898
+ className: "gmp-navigator-head",
899
+ children: [/* @__PURE__ */ G("div", { children: [/* @__PURE__ */ W("p", {
900
+ className: "gmp-navigator-kicker",
901
+ children: "browse the codebase"
902
+ }), /* @__PURE__ */ W("p", {
903
+ className: "gmp-navigator-note",
904
+ children: "choose an area for its recorded work, then open the spatial map when relationships matter"
905
+ })] }), /* @__PURE__ */ G("label", {
906
+ className: "gmp-navigator-search",
907
+ children: [
908
+ /* @__PURE__ */ W(Ae, { "aria-hidden": "true" }),
909
+ /* @__PURE__ */ W("span", {
910
+ className: "mc-sr",
911
+ children: "filter code areas"
912
+ }),
913
+ /* @__PURE__ */ W("input", {
914
+ value: c,
915
+ onChange: (e) => {
916
+ d?.({
917
+ type: "set-filter",
918
+ filter: e.target.value
919
+ }), l?.(e.target.value);
920
+ },
921
+ placeholder: "filter paths"
922
+ })
923
+ ]
924
+ })]
925
+ }),
926
+ b.staleSelectedId ? /* @__PURE__ */ G("p", {
927
+ className: "gmp-navigator-missing",
928
+ role: "status",
929
+ children: [
930
+ "the selected code area is not present in this map.",
931
+ " ",
932
+ /* @__PURE__ */ W("button", {
933
+ type: "button",
934
+ onClick: () => {
935
+ d?.({ type: "clear-selection" }), a?.(null, null);
936
+ },
937
+ children: "clear selection"
938
+ })
939
+ ]
940
+ }) : null,
941
+ /* @__PURE__ */ G("div", {
942
+ className: "gmp-navigator-body",
943
+ children: [/* @__PURE__ */ W("div", {
944
+ role: "tree",
945
+ "aria-label": "code areas",
946
+ className: "gmp-navigator-tree",
947
+ "data-grain": t,
948
+ children: x.length === 0 ? /* @__PURE__ */ W("p", {
949
+ className: "gmp-navigator-empty",
950
+ role: "status",
951
+ children: "no code areas match this filter"
952
+ }) : x.map((e, t) => {
953
+ let n = e.canExpand || e.forcedOpen, r = e.expanded, a = S === e.node.id;
954
+ return /* @__PURE__ */ W(kt, {
955
+ row: e,
956
+ hasChildren: n,
957
+ isExpanded: r,
958
+ selected: i === e.node.id,
959
+ tabbable: a,
960
+ setRef: (t) => {
961
+ t ? y.current.set(e.node.id, t) : y.current.delete(e.node.id);
962
+ },
963
+ onFocus: () => {
964
+ o === void 0 && g(e.node.id);
965
+ },
966
+ onSelect: () => k(e.node),
967
+ onToggle: () => {
968
+ e.forcedOpen || D(e.node.id);
969
+ },
970
+ onKeyDown: (e) => A(e, t)
971
+ }, e.node.id);
972
+ })
973
+ }), /* @__PURE__ */ W("aside", {
974
+ className: "gmp-navigator-actions",
975
+ "aria-label": "selected code area",
976
+ children: C ? /* @__PURE__ */ G(he, { children: [
977
+ /* @__PURE__ */ W("p", {
978
+ className: "gmp-navigator-selected",
979
+ children: C.name || C.id
980
+ }),
981
+ /* @__PURE__ */ W("p", {
982
+ className: "gmp-navigator-selected-path",
983
+ children: C.id
984
+ }),
985
+ T ? /* @__PURE__ */ G("button", {
986
+ type: "button",
987
+ className: "gmp-navigator-action",
988
+ onClick: () => D(C.id),
989
+ children: [/* @__PURE__ */ W(K, { "aria-hidden": "true" }), _.has(C.id) ? "hide children" : "show children"]
990
+ }) : null,
991
+ /* @__PURE__ */ G("button", {
992
+ type: "button",
993
+ className: "gmp-navigator-action gmp-navigator-action--primary",
994
+ onClick: () => {
995
+ d?.({
996
+ type: "open-in-map",
997
+ id: C.id
998
+ }), u?.(C.id);
999
+ },
1000
+ children: [/* @__PURE__ */ W(De, { "aria-hidden": "true" }), " open in map"]
1001
+ })
1002
+ ] }) : /* @__PURE__ */ W("p", {
1003
+ className: "gmp-navigator-empty",
1004
+ children: "select an area to see its recorded work and map context"
1005
+ })
1006
+ })]
1007
+ })
1008
+ ]
1009
+ });
1010
+ }
1011
+ function kt({ row: e, hasChildren: t, isExpanded: n, selected: r, tabbable: i, setRef: a, onFocus: o, onSelect: s, onToggle: c, onKeyDown: l }) {
1012
+ return /* @__PURE__ */ G("div", {
1013
+ role: "none",
1014
+ className: "gmp-navigator-row-wrap",
1015
+ "data-selected": r,
1016
+ style: { "--gmp-tree-depth": e.depth },
1017
+ children: [t ? /* @__PURE__ */ W("button", {
1018
+ type: "button",
1019
+ className: "gmp-navigator-disclosure",
1020
+ tabIndex: -1,
1021
+ "aria-label": `${n ? "hide" : "show"} children for ${e.node.name || e.node.id}`,
1022
+ "aria-expanded": n,
1023
+ "aria-disabled": e.forcedOpen ? "true" : void 0,
1024
+ onKeyDown: (e) => e.stopPropagation(),
1025
+ onClick: (t) => {
1026
+ t.stopPropagation(), e.forcedOpen || c();
1027
+ },
1028
+ children: /* @__PURE__ */ W(K, {
1029
+ className: "gmp-navigator-chevron",
1030
+ "aria-hidden": "true"
1031
+ })
1032
+ }) : /* @__PURE__ */ W("span", {
1033
+ className: "gmp-navigator-disclosure-placeholder",
1034
+ "aria-hidden": "true"
1035
+ }), /* @__PURE__ */ G("div", {
1036
+ ref: a,
1037
+ role: "treeitem",
1038
+ "aria-level": e.depth + 1,
1039
+ "aria-selected": r,
1040
+ "aria-expanded": t ? n : void 0,
1041
+ tabIndex: i ? 0 : -1,
1042
+ className: "gmp-navigator-row",
1043
+ onFocus: o,
1044
+ onClick: s,
1045
+ onDoubleClick: () => {
1046
+ t && !e.forcedOpen && c();
1047
+ },
1048
+ onKeyDown: l,
1049
+ children: [
1050
+ e.node.kind === "file" ? /* @__PURE__ */ W(xe, { "aria-hidden": "true" }) : /* @__PURE__ */ W(we, { "aria-hidden": "true" }),
1051
+ /* @__PURE__ */ W("span", {
1052
+ className: "gmp-navigator-path",
1053
+ children: e.node.name || e.node.id
1054
+ }),
1055
+ /* @__PURE__ */ G("span", {
1056
+ className: "gmp-navigator-meta",
1057
+ children: [/* @__PURE__ */ G("span", { children: [jt(e.node.loc ?? 0), " lines"] }), /* @__PURE__ */ W("span", { children: Mt(e.node.recordedFiles, e.node.totalFiles) })]
1058
+ })
1059
+ ]
1060
+ })]
1061
+ });
1062
+ }
1063
+ function At(e) {
1064
+ return Array.from(e).sort().join("\0");
1065
+ }
1066
+ function jt(e) {
1067
+ return new Intl.NumberFormat("en", {
1068
+ notation: "compact",
1069
+ maximumFractionDigits: 1
1070
+ }).format(Number(e) || 0);
1071
+ }
1072
+ function Mt(e, t) {
1073
+ let n = Number(t) || 0;
1074
+ return n <= 0 ? "no coverage data" : `${Math.round((Number(e) || 0) / n * 100)}% recorded`;
1075
+ }
1076
+ //#endregion
735
1077
  //#region src/ui/graph/CodeMapComposition.jsx
736
- function Z({ payload: e, zoom: t, onZoomChange: n, selectedId: r, onSelect: a, onExpand: o, highlightedIds: s, nodeDeltas: c, structureEdgeDeltas: l, height: f = 480, ariaLabel: p = "code map", canvasSlot: m, rail: h, toolbar: g, sheetTitle: _ = "code area", sheetMeta: v, railSide: y = "right", legend: b, canvasWrapperClassName: x = "", canvasWrapperStyle: S, className: C = "" }) {
737
- return /* @__PURE__ */ u("div", {
738
- className: ["gmp-root", C].filter(Boolean).join(" "),
739
- children: /* @__PURE__ */ d(i, {
740
- toolbar: g,
741
- rail: h,
742
- sheetTitle: _,
743
- sheetMeta: v,
744
- railSide: y,
745
- children: [/* @__PURE__ */ u("div", {
746
- className: ["gmp-map-canvas-region", x].filter(Boolean).join(" "),
747
- style: S,
1078
+ function Nt({ payload: e, zoom: t, onZoomChange: n, selectedId: r, onSelect: i, onExpand: a, highlightedIds: o, nodeDeltas: s, structureEdgeDeltas: c, height: l = 480, ariaLabel: u = "code map", canvasSlot: d, rail: f, toolbar: p, sheetTitle: m = "code area", sheetMeta: h, railSide: g = "right", legend: _, canvasWrapperClassName: v = "", canvasWrapperStyle: y, className: b = "", presentation: x = "canvas", navigatorSlot: S, onPresentationChange: C, viewport: w, onViewportChange: T, state: E, defaultState: O, onStateChange: k }) {
1079
+ let A = E !== void 0 || O !== void 0, [j, ee] = U(() => z(O)), N = V(() => A ? z(E ?? j) : null, [
1080
+ A,
1081
+ E,
1082
+ j
1083
+ ]), P = N?.presentation ?? x;
1084
+ function F(e, t) {
1085
+ E === void 0 && ee(e), k?.(e), t?.(e);
1086
+ }
1087
+ function I(e, t) {
1088
+ if (!N) return;
1089
+ let n = D(N, e);
1090
+ M(N, n) || F(n, t);
1091
+ }
1092
+ let te = A || C ? /* @__PURE__ */ G(he, { children: [/* @__PURE__ */ G("div", {
1093
+ className: "gmp-presentation-switch",
1094
+ role: "group",
1095
+ "aria-label": "code map view",
1096
+ children: [/* @__PURE__ */ W("button", {
1097
+ type: "button",
1098
+ "aria-pressed": P === "navigator",
1099
+ onClick: () => A ? I({
1100
+ type: "set-presentation",
1101
+ presentation: "navigator"
1102
+ }, () => C?.("navigator")) : C?.("navigator"),
1103
+ children: P === "canvas" ? "back to browse" : "browse"
1104
+ }), /* @__PURE__ */ W("button", {
1105
+ type: "button",
1106
+ "aria-pressed": P === "canvas",
1107
+ onClick: () => A ? I({
1108
+ type: "set-presentation",
1109
+ presentation: "canvas"
1110
+ }, () => C?.("canvas")) : C?.("canvas"),
1111
+ children: "spatial map"
1112
+ })]
1113
+ }), p] }) : p, L = d ?? /* @__PURE__ */ W(Ct, {
1114
+ payload: e,
1115
+ zoom: N ? {
1116
+ level: N.grain,
1117
+ expanded: N.expandedIds
1118
+ } : t,
1119
+ onZoomChange: n,
1120
+ selectedId: N ? N.selectedId : r,
1121
+ onSelect: i,
1122
+ onExpand: a,
1123
+ highlightedIds: o,
1124
+ nodeDeltas: s,
1125
+ structureEdgeDeltas: c,
1126
+ height: l,
1127
+ ariaLabel: u,
1128
+ viewport: N ? N.viewport ?? void 0 : w,
1129
+ onViewportChange: T,
1130
+ state: N ?? void 0,
1131
+ onStateChange: N ? (e) => F(e) : void 0
1132
+ }), R = S ?? (N && e ? /* @__PURE__ */ W(Ot, {
1133
+ payload: e,
1134
+ grain: N.grain,
1135
+ expandedIds: N.expandedIds,
1136
+ selectedId: N.selectedId,
1137
+ focusedId: N.navigatorFocusedId,
1138
+ filter: N.navigatorFilter,
1139
+ onStateAction: (t) => I(t, () => {
1140
+ t.type === "select" ? i?.(t.id, e.nodes.find((e) => e.id === t.id) ?? null) : t.type === "clear-selection" ? i?.(null, null) : t.type === "set-expanded" ? n?.({
1141
+ level: N.grain,
1142
+ expanded: Array.from(t.ids)
1143
+ }) : t.type === "open-in-map" && (i?.(t.id, e.nodes.find((e) => e.id === t.id) ?? null), C?.("canvas"));
1144
+ }),
1145
+ ariaLabel: `browse ${u}`
1146
+ }) : null), B = P === "navigator" && R !== null;
1147
+ return /* @__PURE__ */ W("div", {
1148
+ className: ["gmp-root", b].filter(Boolean).join(" "),
1149
+ children: /* @__PURE__ */ G(re, {
1150
+ toolbar: te,
1151
+ rail: f,
1152
+ sheetTitle: m,
1153
+ sheetMeta: h,
1154
+ railSide: g,
1155
+ children: [/* @__PURE__ */ W("div", {
1156
+ className: ["gmp-map-canvas-region", v].filter(Boolean).join(" "),
1157
+ style: y,
748
1158
  "data-testid": "gmp-map-canvas-region",
749
- children: m ?? /* @__PURE__ */ u(K, {
750
- payload: e,
751
- zoom: t,
752
- onZoomChange: n,
753
- selectedId: r,
754
- onSelect: a,
755
- onExpand: o,
756
- highlightedIds: s,
757
- nodeDeltas: c,
758
- structureEdgeDeltas: l,
759
- height: f,
760
- ariaLabel: p
761
- })
762
- }), b !== !1 && (b ?? /* @__PURE__ */ u(Q, {}))]
1159
+ children: B ? R : L
1160
+ }), !B && _ !== !1 && (_ ?? /* @__PURE__ */ W(Pt, {}))]
763
1161
  })
764
1162
  });
765
1163
  }
766
- function Q() {
767
- return /* @__PURE__ */ d("p", {
1164
+ function Pt() {
1165
+ return /* @__PURE__ */ G("p", {
768
1166
  className: "gmp-map-legend",
769
1167
  children: [
770
- /* @__PURE__ */ d("span", {
1168
+ /* @__PURE__ */ G("span", {
771
1169
  className: "gmp-legend-item",
772
- children: [/* @__PURE__ */ u("span", {
1170
+ children: [/* @__PURE__ */ W("span", {
773
1171
  className: "gmp-map-swatch",
774
1172
  "aria-hidden": "true"
775
1173
  }), " code area (folder or file)"]
776
1174
  }),
777
- /* @__PURE__ */ d("span", {
1175
+ /* @__PURE__ */ G("span", {
778
1176
  className: "gmp-legend-item gmp-legend-dim",
779
- children: [/* @__PURE__ */ u("span", {
1177
+ children: [/* @__PURE__ */ W("span", {
780
1178
  className: "gmp-map-swatch gmp-map-swatch--empty",
781
1179
  "aria-hidden": "true"
782
1180
  }), " no saved conversation behind it"]
783
1181
  }),
784
- /* @__PURE__ */ u("span", {
1182
+ /* @__PURE__ */ W("span", {
785
1183
  className: "gmp-legend-item gmp-legend-dim",
786
1184
  children: "brighter = more of it built with AI on record"
787
1185
  }),
788
- /* @__PURE__ */ d("span", {
1186
+ /* @__PURE__ */ G("span", {
789
1187
  className: "gmp-legend-item gmp-legend-dim",
790
- children: [/* @__PURE__ */ u("span", {
1188
+ children: [/* @__PURE__ */ W("span", {
791
1189
  className: "gmp-map-swatch gmp-map-swatch--edge",
792
1190
  "aria-hidden": "true"
793
1191
  }), " one area uses another"]
794
1192
  }),
795
- /* @__PURE__ */ u("span", {
1193
+ /* @__PURE__ */ W("span", {
796
1194
  className: "gmp-legend-item gmp-map-legend-danger",
797
1195
  children: "⚠ tangle — two areas that depend on each other"
798
1196
  }),
799
- /* @__PURE__ */ u("span", {
1197
+ /* @__PURE__ */ W("span", {
800
1198
  className: "gmp-legend-item gmp-legend-dim",
801
1199
  children: "double-click a folder to open its files"
802
1200
  })
@@ -804,20 +1202,217 @@ function Q() {
804
1202
  });
805
1203
  }
806
1204
  //#endregion
807
- //#region src/ui/graph/types.js
808
- var $ = Object.freeze([
809
- "module",
810
- "package",
811
- "file"
812
- ]), ee = Object.freeze(["bound", "candidate"]), te = Object.freeze(["cycle", "wrong_way"]), ne = Object.freeze([
813
- "M",
814
- "A",
815
- "D",
816
- "R"
817
- ]), re = Object.freeze([
818
- "context",
819
- "add",
820
- "del"
821
- ]);
1205
+ //#region src/ui/graph/timelineNavigation.js
1206
+ function X(e) {
1207
+ return typeof e == "object" && !!e && !Array.isArray(e);
1208
+ }
1209
+ function Z(e, t) {
1210
+ let n = Object.keys(e).sort();
1211
+ return n.length === t.length && t.slice().sort().every((e, t) => e === n[t]);
1212
+ }
1213
+ function Q(e) {
1214
+ return typeof e == "string" && e.length > 0;
1215
+ }
1216
+ function Ft(e) {
1217
+ return e === null || Q(e);
1218
+ }
1219
+ function It(e) {
1220
+ let t = !1;
1221
+ if (X(e) && typeof e.type == "string" && (e.type === "open-change" && Z(e, ["type", "change"]) && X(e.change) ? t = Z(e.change, ["id", "branch"]) && Q(e.change.id) && Ft(e.change.branch) : e.type === "open-session" && Z(e, [
1222
+ "type",
1223
+ "sessionId",
1224
+ "source"
1225
+ ]) && Q(e.sessionId) && X(e.source) ? e.source.kind === "commit" && Z(e.source, ["kind", "commit"]) && X(e.source.commit) ? t = Z(e.source.commit, ["id", "branch"]) && Q(e.source.commit.id) && Ft(e.source.commit.branch) : (e.source.kind === "unlinked" || e.source.kind === "outside-window") && Z(e.source, ["kind"]) && (t = !0) : (e.type === "open-map" || e.type === "show-older") && Z(e, ["type"]) && (t = !0)), !t) throw TypeError([
1226
+ "Timeline navigation action rejected.",
1227
+ "What went wrong: the value is not an exact supported TimelineNavigationAction.",
1228
+ "Why it happened: an untyped caller supplied an unknown action, missing context, or extra fields.",
1229
+ "Where: assertTimelineNavigationAction in @peasant-labs/fairtrade/graph.",
1230
+ "When: while crossing a JavaScript timeline-navigation boundary.",
1231
+ "What it means: the host cannot safely choose a route for this user gesture.",
1232
+ "How to fix: emit one documented open-change, open-session, open-map, or show-older action with its exact required fields."
1233
+ ].join("\n"));
1234
+ }
1235
+ //#endregion
1236
+ //#region src/ui/graph/ScentTag.jsx
1237
+ function Lt({ tag: e, hoverText: t, active: n = !1, onToggle: r, className: i = "", ...a }) {
1238
+ if (!b.includes(e)) throw Error(`ScentTag render failed: what went wrong: unknown scent tag ${JSON.stringify(e)}; why: the value is not a member of the closed SCENT_TAGS set; where: src/ui/graph/ScentTag.jsx; when: rendering a ranked-list row; what it means: an upstream ranking derivation produced a value outside the frozen vocabulary; how to fix: only pass one of ${b.join(", ")}.`);
1239
+ return r ? /* @__PURE__ */ G("button", {
1240
+ type: "button",
1241
+ className: `tlp-scent tlp-scent-filter${n ? " tlp-scent-filter-active" : ""}${i ? ` ${i}` : ""}`,
1242
+ title: t || void 0,
1243
+ "aria-pressed": n,
1244
+ onClick: () => r(n ? null : e),
1245
+ ...a,
1246
+ children: [e, /* @__PURE__ */ W("span", {
1247
+ className: "tlp-sr",
1248
+ role: "status",
1249
+ "aria-live": "polite",
1250
+ children: n ? `filtering by ${e}` : ""
1251
+ })]
1252
+ }) : /* @__PURE__ */ W("span", {
1253
+ className: `tlp-scent${i ? ` ${i}` : ""}`,
1254
+ title: t || void 0,
1255
+ ...a,
1256
+ children: e
1257
+ });
1258
+ }
1259
+ //#endregion
1260
+ //#region src/ui/graph/RankedRow.jsx
1261
+ function Rt({ row: e, loc: t = 0, selected: n = !1, onSelect: r, className: i = "", ...a }) {
1262
+ return /* @__PURE__ */ G("button", {
1263
+ type: "button",
1264
+ className: [
1265
+ "tlp-ranked-row",
1266
+ n && "tlp-ranked-row-sel",
1267
+ i
1268
+ ].filter(Boolean).join(" "),
1269
+ "aria-pressed": n,
1270
+ onClick: () => r?.(e.id),
1271
+ ...a,
1272
+ children: [
1273
+ /* @__PURE__ */ W(A, {
1274
+ className: "tlp-ranked-doi-scope",
1275
+ children: /* @__PURE__ */ W(se, {
1276
+ label: e.name,
1277
+ loc: t,
1278
+ recorded: e.doi,
1279
+ total: 1,
1280
+ selected: n,
1281
+ as: "span",
1282
+ className: "tlp-ranked-doi"
1283
+ })
1284
+ }),
1285
+ /* @__PURE__ */ W("span", {
1286
+ className: "tlp-ranked-name",
1287
+ title: e.name,
1288
+ children: e.name
1289
+ }),
1290
+ /* @__PURE__ */ W("span", {
1291
+ className: "tlp-ranked-tags",
1292
+ "aria-label": "comprehension signals",
1293
+ children: e.scentTags.map((t) => /* @__PURE__ */ W(Lt, {
1294
+ tag: t,
1295
+ hoverText: t.startsWith("agent wrote:") ? e.hoverText ?? void 0 : void 0
1296
+ }, t))
1297
+ }),
1298
+ /* @__PURE__ */ W("span", {
1299
+ className: "tlp-ranked-doi-val tnum",
1300
+ "aria-hidden": "true",
1301
+ children: e.doi.toFixed(2)
1302
+ })
1303
+ ]
1304
+ });
1305
+ }
1306
+ //#endregion
1307
+ //#region src/ui/graph/RankModeControl.jsx
1308
+ var $ = [
1309
+ "relevance",
1310
+ "debt",
1311
+ "churn"
1312
+ ];
1313
+ function zt({ rankMode: e, onChange: t, className: n = "", ...r }) {
1314
+ let i = H([]), a = (e) => {
1315
+ let n = $[e];
1316
+ n && (t(n), i.current[e]?.focus());
1317
+ }, o = (e, t) => {
1318
+ let n;
1319
+ switch (e.key) {
1320
+ case "ArrowRight":
1321
+ case "ArrowDown":
1322
+ n = (t + 1) % $.length;
1323
+ break;
1324
+ case "ArrowLeft":
1325
+ case "ArrowUp":
1326
+ n = (t - 1 + $.length) % $.length;
1327
+ break;
1328
+ case "Home":
1329
+ n = 0;
1330
+ break;
1331
+ case "End":
1332
+ n = $.length - 1;
1333
+ break;
1334
+ default: return;
1335
+ }
1336
+ e.preventDefault(), a(n);
1337
+ };
1338
+ return /* @__PURE__ */ G("span", {
1339
+ className: `tlp-rank-mode${n ? ` ${n}` : ""}`,
1340
+ role: "radiogroup",
1341
+ "aria-label": "rank mode",
1342
+ ...r,
1343
+ children: [$.map((n, r) => /* @__PURE__ */ W("button", {
1344
+ type: "button",
1345
+ role: "radio",
1346
+ "aria-checked": e === n,
1347
+ tabIndex: e === n ? 0 : -1,
1348
+ ref: (e) => {
1349
+ i.current[r] = e;
1350
+ },
1351
+ className: `tlp-rank-mode-btn${e === n ? " tlp-rank-mode-btn-active" : ""}`,
1352
+ onClick: () => t(n),
1353
+ onKeyDown: (e) => o(e, r),
1354
+ children: n
1355
+ }, n)), /* @__PURE__ */ W("span", {
1356
+ className: "tlp-sr",
1357
+ role: "status",
1358
+ "aria-live": "polite",
1359
+ children: `rank mode: ${e}`
1360
+ })]
1361
+ });
1362
+ }
1363
+ //#endregion
1364
+ //#region src/ui/graph/InsightPanel.jsx
1365
+ function Bt({ insights: e, onOpenEvidence: t, className: n = "", ...r }) {
1366
+ if (fe(e), e.length === 0) return /* @__PURE__ */ W("p", {
1367
+ className: `tlp-insight-empty${n ? ` ${n}` : ""}`,
1368
+ ...r,
1369
+ children: "no insights recorded for this node yet."
1370
+ });
1371
+ let i = /* @__PURE__ */ new Map();
1372
+ for (let t of e) {
1373
+ let e = i.get(t.kind) ?? [];
1374
+ e.push(t), i.set(t.kind, e);
1375
+ }
1376
+ return /* @__PURE__ */ W("div", {
1377
+ className: `tlp-insight-panel${n ? ` ${n}` : ""}`,
1378
+ ...r,
1379
+ children: [...i.entries()].map(([e, n]) => /* @__PURE__ */ G("section", {
1380
+ className: "tlp-insight-group",
1381
+ "aria-label": f[e],
1382
+ children: [/* @__PURE__ */ W("h3", {
1383
+ className: "tlp-insight-group-title",
1384
+ children: f[e]
1385
+ }), /* @__PURE__ */ W("ul", {
1386
+ className: "tlp-insight-list",
1387
+ children: n.map((e, n) => /* @__PURE__ */ G("li", {
1388
+ className: "tlp-insight-item",
1389
+ children: [
1390
+ /* @__PURE__ */ W("span", {
1391
+ className: `tlp-insight-provenance ${v[e.provenance].markerClass}`,
1392
+ "aria-hidden": "true"
1393
+ }),
1394
+ /* @__PURE__ */ W("span", {
1395
+ className: "tlp-insight-title",
1396
+ children: e.title
1397
+ }),
1398
+ e.summary && /* @__PURE__ */ W("span", {
1399
+ className: "tlp-insight-summary",
1400
+ children: e.summary
1401
+ }),
1402
+ /* @__PURE__ */ W("span", {
1403
+ className: "tlp-insight-evidence",
1404
+ children: e.evidence.map((e, n) => /* @__PURE__ */ W("button", {
1405
+ type: "button",
1406
+ className: "tlp-insight-evidence-link",
1407
+ onClick: () => t?.(e.sessionId),
1408
+ children: e.file || e.sessionId
1409
+ }, n))
1410
+ })
1411
+ ]
1412
+ }, n))
1413
+ })]
1414
+ }, e))
1415
+ });
1416
+ }
822
1417
  //#endregion
823
- export { ee as CHANGE_BINDINGS, U as ChangeDetail, F as Changes, K as CodeMap, Z as CodeMapComposition, re as DIFF_LINE_KINDS, Q as DefaultMapLegend, te as EDGE_VIOLATION_KINDS, ne as FILE_CHANGE_STATUSES, a as GRAPH_APP_SECTIONS, n as GraphAppShell, r as GraphSectionNav, $ as MAP_NODE_KINDS, N as buildChangesGraph, q as codeMapPayloadToMapData, M as humanizeAge };
1418
+ export { Fe as AllChangeBindings, Ie as AllDiffLineKinds, Le as AllEdgeViolationKinds, Re as AllFileChangeStatuses, ze as AllInsightKinds, Be as AllInsightProvenances, Ve as AllMapNodeKinds, He as AllReadAttributionStates, Ue as AllReadStateGrades, n as CHANGE_BINDINGS, oe as CODE_MAP_STATE_VERSION, j as CODE_MAP_VIEWPORT_SCALE, de as COVERAGE_CAP, We as ChangeBinding, bt as ChangeDetail, ft as Changes, Ct as CodeMap, Nt as CodeMapComposition, Ot as CodeMapNavigator, k as DEBT_VIEWED, S as DIFF_LINE_KINDS, ue as DOI_WEIGHTS, Pt as DefaultMapLegend, Ge as DiffLineKind, c as EDGE_VIOLATION_KINDS, Ke as EdgeViolationKind, x as FILE_CHANGE_STATUSES, qe as FileChangeStatus, ie as GRAPH_APP_SECTIONS, ae as GhostCommitNode, e as GhostGroup, R as GraphAppShell, ne as GraphSectionNav, E as HighlightEdge, Je as InsightKind, Bt as InsightPanel, Ye as InsightProvenance, C as MAP_NODE_KINDS, Xe as MapNodeKind, y as RANK_CAP, r as RANK_FLOOR, le as RECENCY_HALF_LIFE_DAYS, zt as RankModeControl, Rt as RankedRow, Ze as ReadAttributionState, Qe as ReadStateGrade, b as SCENT_TAGS, Lt as ScentTag, ee as SessionLane, _ as SessionOverflowDisclosure, w as TouchedFileCluster, s as assertChangeDetailPayloadEnums, d as assertChangeDiffPayloadEnums, B as assertCodeMapPayloadEnums, It as assertTimelineNavigationAction, ut as buildChangesGraph, wt as codeMapPayloadToMapData, M as codeMapStatesEqual, a as coverage, z as createCodeMapState, i as debt, h as debtHoverText, I as debtState, L as deriveCodeMapView, t as deriveRankedRows, P as deriveTimelineHighlight, F as gateRankedRows, Y as humanizeAge, p as hunkClears, $e as isChangeBinding, N as isCodeMapViewportScale, et as isDiffLineKind, tt as isEdgeViolationKind, nt as isFileChangeStatus, rt as isInsightKind, it as isInsightProvenance, at as isMapNodeKind, ot as isReadAttributionState, st as isReadStateGrade, m as partialReadHoverText, g as rankMapNodes, o as rankMapNodesIntrinsic, D as reduceCodeMapState, ce as resolveEscapeAction, l as scentTagsFor };