@tangle-network/sandbox-ui 2.0.21 → 3.0.0

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 (40) hide show
  1. package/README.md +23 -0
  2. package/dist/{record-CnxPRyxC.js → AgentTree-CJRVpgPq.js} +196 -83
  3. package/dist/ResearchReport-CSNpZ-pj.js +2063 -0
  4. package/dist/ResearchReport-CmFYqNVY.d.ts +36 -0
  5. package/dist/{WorkflowGraph-CADReIDl.js → WorkflowGraph-B8cRtVaw.js} +2 -2
  6. package/dist/{chat-BU39pb2j.js → chat-BrlLa4rg.js} +2 -2
  7. package/dist/chat.d.ts +1 -1
  8. package/dist/chat.js +1 -1
  9. package/dist/globals.css +5837 -419
  10. package/dist/hooks.d.ts +2 -2
  11. package/dist/hooks.js +2 -2
  12. package/dist/{index-Due7tY0w.d.ts → index-5zOVKgDT.d.ts} +2 -2
  13. package/dist/{index-DxMX-DlX.d.ts → index-YU_b9xCK.d.ts} +3 -3
  14. package/dist/{index-1qlc9-S2.d.ts → index-gXcuwPOX.d.ts} +5 -6
  15. package/dist/index.d.ts +5 -5
  16. package/dist/index.js +7 -6
  17. package/dist/record/ResearchReport.d.ts +2 -0
  18. package/dist/record/ResearchReport.js +1 -0
  19. package/dist/record-Ct_MZeZC.js +47 -0
  20. package/dist/record.d.ts +33 -0
  21. package/dist/record.js +270 -0
  22. package/dist/report-viewer.js +554 -0
  23. package/dist/run/live.js +14 -33
  24. package/dist/run/record.d.ts +2 -2
  25. package/dist/run/record.js +3 -2
  26. package/dist/run.d.ts +3 -3
  27. package/dist/run.js +5 -4
  28. package/dist/runtime-viewer/{AgentGraphCanvas-B74GN1o6-DC3EH_ss.js → AgentGraphCanvas-CcBWMidO-DIW8tof6.js} +1366 -1348
  29. package/dist/runtime-viewer/{latest-events-iiWwpIck-BTK0vSlR.js → latest-events-BfRc-7l9-QhJD89rn.js} +899 -748
  30. package/dist/runtime-viewer/sandbox-ui-CUj4Q1P_.css +2 -0
  31. package/dist/styles.css +5838 -420
  32. package/dist/tailwind.css +5677 -5
  33. package/dist/tokens.css +7 -1
  34. package/dist/{trace-workspace-DkakKRLV.js → trace-workspace-BiJbv9WQ.js} +2 -2
  35. package/dist/use-follow-tail-Ht7fZGQQ.js +1 -0
  36. package/dist/workflows.js +1 -1
  37. package/dist/workspace-viewer.js +8785 -11045
  38. package/package.json +30 -12
  39. package/dist/runtime-viewer/sandbox-ui-z5RGk327.css +0 -2
  40. package/dist/use-follow-tail-Ckx5ZSV2.js +0 -1
package/dist/record.js ADDED
@@ -0,0 +1,270 @@
1
+ import { n as AgentRecord, t as ResearchReport } from "./ResearchReport-CSNpZ-pj.js";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import { useMemo, useRef, useState } from "react";
4
+ import { useColorMode } from "@tangle-network/charts/react/agent-graph/presentation";
5
+ import { Controls, Handle, MarkerType, Position, ReactFlow } from "@xyflow/react";
6
+ import { NODE_H, NODE_W, PER_LANE, recordWorkGraphModel } from "@drewstone/agent-record/record";
7
+ // src/record/WorkGraph.tsx
8
+ function RecordCard({ data }) {
9
+ const node = data.record;
10
+ return /* @__PURE__ */ jsxs("div", {
11
+ title: node.title,
12
+ className: `graph-node kind-${node.kind}`,
13
+ children: [
14
+ /* @__PURE__ */ jsx(Handle, {
15
+ type: "target",
16
+ position: Position.Left,
17
+ className: "opacity-0"
18
+ }),
19
+ /* @__PURE__ */ jsx("span", {
20
+ className: "graph-node-title",
21
+ children: node.title
22
+ }),
23
+ /* @__PURE__ */ jsx("span", {
24
+ className: "graph-node-sub",
25
+ children: node.sub
26
+ }),
27
+ /* @__PURE__ */ jsx(Handle, {
28
+ type: "source",
29
+ position: Position.Right,
30
+ className: "opacity-0"
31
+ })
32
+ ]
33
+ });
34
+ }
35
+ const nodeTypes = { record: RecordCard };
36
+ /** Recorded evidence relationships keep their domain kinds; the maintained graph engine owns the camera and focus. */
37
+ function RecordWorkGraph({ record }) {
38
+ const graph = useMemo(() => recordWorkGraphModel(record), [record]);
39
+ const wrapperRef = useRef(null);
40
+ const colorMode = useColorMode(wrapperRef, graph.nodes.length > 0);
41
+ const [selected, setSelected] = useState(null);
42
+ const chosen = selected ? graph.byId.get(selected) : void 0;
43
+ const adjacent = new Set(chosen ? [chosen.id, ...graph.edges.filter((edge) => edge.from === chosen.id || edge.to === chosen.id).flatMap((edge) => [edge.from, edge.to])] : []);
44
+ const nodes = useMemo(() => graph.nodes.map((node) => ({
45
+ id: node.id,
46
+ type: "record",
47
+ position: {
48
+ x: node.x,
49
+ y: node.y
50
+ },
51
+ data: { record: node },
52
+ width: NODE_W,
53
+ height: NODE_H,
54
+ ariaLabel: `${node.kind}: ${node.title}`,
55
+ domAttributes: {
56
+ "data-graph-node-id": node.id,
57
+ "data-graph-node-kind": node.kind,
58
+ "aria-pressed": node.id === selected
59
+ },
60
+ selected: node.id === selected,
61
+ style: { opacity: selected && !adjacent.has(node.id) ? .35 : 1 }
62
+ })), [graph, selected]);
63
+ const edges = useMemo(() => graph.edges.map((edge, i) => ({
64
+ id: String(i),
65
+ source: edge.from,
66
+ target: edge.to,
67
+ label: edge.kind,
68
+ markerEnd: { type: MarkerType.ArrowClosed },
69
+ className: `edge-${edge.kind}`,
70
+ style: { opacity: selected && edge.from !== selected && edge.to !== selected ? .2 : 1 },
71
+ data: { kind: edge.kind }
72
+ })), [graph, selected]);
73
+ return /* @__PURE__ */ jsx("div", {
74
+ ref: wrapperRef,
75
+ className: "agent-record ar-ws",
76
+ children: /* @__PURE__ */ jsxs("section", {
77
+ className: "work-graph",
78
+ "aria-label": graph.title,
79
+ "data-work-graph": graph.nodes.length,
80
+ "data-graph-kind": "record",
81
+ children: [/* @__PURE__ */ jsxs("div", {
82
+ className: "graph-main",
83
+ children: [
84
+ /* @__PURE__ */ jsxs("header", {
85
+ className: "graph-head",
86
+ children: [/* @__PURE__ */ jsx("h2", { children: graph.title }), /* @__PURE__ */ jsx("span", {
87
+ className: "faint",
88
+ children: graph.summary
89
+ })]
90
+ }),
91
+ /* @__PURE__ */ jsx("div", {
92
+ className: "graph-viewport",
93
+ style: { height: 560 },
94
+ onKeyDownCapture: (event) => {
95
+ const target = event.target instanceof Element ? event.target.closest(".react-flow__node[data-id]") : null;
96
+ const from = target?.dataset.id ? graph.byId.get(target.dataset.id) : void 0;
97
+ if (!from) return;
98
+ if (event.key === "Enter" || event.key === " ") {
99
+ event.preventDefault();
100
+ event.stopPropagation();
101
+ setSelected(selected === from.id ? null : from.id);
102
+ return;
103
+ }
104
+ if (![
105
+ "ArrowLeft",
106
+ "ArrowRight",
107
+ "ArrowUp",
108
+ "ArrowDown"
109
+ ].includes(event.key)) return;
110
+ const horizontal = event.key === "ArrowLeft" || event.key === "ArrowRight", sign = event.key === "ArrowLeft" || event.key === "ArrowUp" ? -1 : 1;
111
+ const score = (node) => horizontal ? Math.abs(node.y - from.y) * 4 + Math.abs(node.x - from.x) : Math.abs(node.x - from.x) * 4 + Math.abs(node.y - from.y);
112
+ const next = graph.nodes.filter((node) => node.id !== from.id && (horizontal ? node.x - from.x : node.y - from.y) * sign > 0).sort((a, b) => score(a) - score(b) || a.id.localeCompare(b.id))[0];
113
+ if (next) {
114
+ event.preventDefault();
115
+ event.stopPropagation();
116
+ event.currentTarget.querySelector(`.react-flow__node[data-id="${CSS.escape(next.id)}"]`)?.focus();
117
+ }
118
+ },
119
+ children: /* @__PURE__ */ jsx(ReactFlow, {
120
+ colorMode,
121
+ nodes,
122
+ edges,
123
+ nodeTypes,
124
+ fitView: true,
125
+ nodesDraggable: false,
126
+ nodesConnectable: false,
127
+ minZoom: .12,
128
+ maxZoom: 2,
129
+ onNodeClick: (_, node) => setSelected(selected === node.id ? null : node.id),
130
+ onPaneClick: () => setSelected(null),
131
+ children: /* @__PURE__ */ jsx(Controls, { showInteractive: false })
132
+ }, record.runId)
133
+ }),
134
+ Object.keys(graph.hidden).length > 0 && /* @__PURE__ */ jsxs("p", {
135
+ className: "faint",
136
+ children: [
137
+ "Each lane shows its first ",
138
+ PER_LANE,
139
+ " results, claims and checks; ",
140
+ Object.values(graph.hidden).reduce((a, b) => a + b, 0),
141
+ " more are retained in the record."
142
+ ]
143
+ }),
144
+ /* @__PURE__ */ jsx("ul", {
145
+ className: "graph-legend",
146
+ children: graph.legend.map((entry) => /* @__PURE__ */ jsx("li", { children: entry.label }, entry.kind))
147
+ })
148
+ ]
149
+ }), /* @__PURE__ */ jsx("aside", {
150
+ className: "graph-side finding-card",
151
+ "aria-label": "Selected card",
152
+ children: chosen ? /* @__PURE__ */ jsxs(Fragment, { children: [
153
+ /* @__PURE__ */ jsx("h3", { children: chosen.kind }),
154
+ /* @__PURE__ */ jsx("div", {
155
+ className: "graph-side-title",
156
+ children: chosen.title
157
+ }),
158
+ /* @__PURE__ */ jsx("div", {
159
+ className: "faint",
160
+ children: chosen.sub
161
+ }),
162
+ chosen.summary && /* @__PURE__ */ jsx("p", { children: chosen.summary }),
163
+ /* @__PURE__ */ jsxs("div", {
164
+ className: "faint",
165
+ children: [
166
+ graph.edges.filter((edge) => edge.from === chosen.id).length,
167
+ " links out · ",
168
+ graph.edges.filter((edge) => edge.to === chosen.id).length,
169
+ " links in"
170
+ ]
171
+ }),
172
+ chosen.href && /* @__PURE__ */ jsx("a", {
173
+ href: chosen.href,
174
+ target: "_blank",
175
+ rel: "noopener noreferrer",
176
+ children: "Open source ↗"
177
+ })
178
+ ] }) : /* @__PURE__ */ jsx("p", {
179
+ className: "faint",
180
+ children: "Select a card to see its recorded relationships and details."
181
+ })
182
+ })]
183
+ })
184
+ });
185
+ }
186
+ // src/record/selection.ts
187
+ /** URL selections only name documents already supplied within the exact play. */
188
+ function readReportLocation(report, search) {
189
+ const params = new URLSearchParams(search);
190
+ if ([
191
+ "play",
192
+ "document",
193
+ "line",
194
+ "view",
195
+ "agent",
196
+ "event"
197
+ ].some((key) => params.getAll(key).length > 1)) return { error: "This citation contains an ambiguous selection." };
198
+ const viewText = params.get("view");
199
+ if (viewText !== null && ![
200
+ "results",
201
+ "activity",
202
+ "sources"
203
+ ].includes(viewText)) return { error: "Unknown research view." };
204
+ const view = viewText;
205
+ const viewOption = view ? { view } : {};
206
+ const playId = params.get("play") ?? void 0;
207
+ const path = params.get("document") ?? void 0;
208
+ const lineText = params.get("line") ?? void 0;
209
+ const agentId = params.get("agent") ?? void 0;
210
+ const eventId = params.get("event") ?? void 0;
211
+ if (!playId && (path !== void 0 || lineText !== void 0 || agentId !== void 0 || eventId !== void 0)) return { error: "A document citation must name its play." };
212
+ if (!playId) return viewOption;
213
+ const play = report.plays.find((item) => item.id === playId);
214
+ if (!play) return { error: "The cited play is not included in this report." };
215
+ if (agentId !== void 0 || eventId !== void 0) {
216
+ if (path !== void 0 || lineText !== void 0 || !play.record) return { error: "Activity citation does not match this play." };
217
+ const node = agentId ? play.record.nodes.find((item) => item.id === agentId) : void 0;
218
+ const event = eventId ? play.record.events.find((item) => item.id === eventId) : void 0;
219
+ if (agentId && !node || eventId && !event) return { error: "This activity is not retained in the selected play." };
220
+ if (event && node) {
221
+ const observed = play.record.nodes.find((item) => item.id === event.node);
222
+ if (event.node !== node.id && observed?.agentId !== node.id) return { error: "The event belongs to a different agent." };
223
+ }
224
+ return {
225
+ playId,
226
+ view: "activity",
227
+ activity: {
228
+ runId: play.record.runId,
229
+ ...agentId ? { nodeId: agentId } : {},
230
+ ...eventId ? { eventId } : {}
231
+ }
232
+ };
233
+ }
234
+ if (path === void 0) return lineText === void 0 ? {
235
+ playId,
236
+ ...viewOption
237
+ } : { error: "A line citation must name its document." };
238
+ if (!play.documents.some((item) => item.path === path)) return { error: "The cited document is not retained in this play." };
239
+ const line = lineText === void 0 ? void 0 : Number(lineText);
240
+ if (line !== void 0 && (!/^[1-9]\d*$/.test(lineText) || !Number.isSafeInteger(line))) return { error: "The cited source line must be a positive whole number." };
241
+ return {
242
+ playId,
243
+ ...viewOption,
244
+ document: {
245
+ playId,
246
+ path,
247
+ ...line === void 0 ? {} : { line }
248
+ }
249
+ };
250
+ }
251
+ function reportLocationSearch(search, playId, document, view, activity) {
252
+ const params = new URLSearchParams(search);
253
+ params.set("play", playId);
254
+ params.delete("document");
255
+ params.delete("line");
256
+ params.delete("view");
257
+ params.delete("agent");
258
+ params.delete("event");
259
+ if (activity) {
260
+ if (activity.nodeId) params.set("agent", activity.nodeId);
261
+ if (activity.eventId) params.set("event", activity.eventId);
262
+ }
263
+ if (view) params.set("view", view);
264
+ if (document && document.playId === playId) {
265
+ params.set("document", document.path);
266
+ if (document.line !== void 0) params.set("line", String(document.line));
267
+ }
268
+ return "?" + params.toString();
269
+ }
270
+ export { AgentRecord, RecordWorkGraph, ResearchReport, readReportLocation, reportLocationSearch };