footprint-explainable-ui 0.25.5 → 0.26.1
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.
- package/README.md +22 -14
- package/dist/index.cjs +47 -66
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -4
- package/dist/index.d.ts +25 -4
- package/dist/index.js +47 -66
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
|
|
11
11
|
Themeable React components for visualizing [footprintjs](https://github.com/footprintjs/footPrint) pipeline execution — time-travel debugging, flowchart overlays, subflow drill-down, and collapsible detail panels.
|
|
12
12
|
|
|
13
|
+
> Part of the **[footprintjs ecosystem](https://footprintjs.github.io/)** — the self-explaining stack.
|
|
14
|
+
|
|
13
15
|
## Install
|
|
14
16
|
|
|
15
17
|
```bash
|
|
@@ -52,25 +54,16 @@ const snapshots = toVisualizationSnapshots(
|
|
|
52
54
|
|
|
53
55
|
```tsx
|
|
54
56
|
import { ExplainableShell } from "footprint-explainable-ui";
|
|
55
|
-
import { TracedFlowchartView } from "footprint-explainable-ui/flowchart";
|
|
56
57
|
|
|
57
|
-
function DebugView({ snapshots,
|
|
58
|
+
function DebugView({ snapshots, narrativeEntries, traceGraph, runtimeOverlay }) {
|
|
58
59
|
return (
|
|
59
60
|
<ExplainableShell
|
|
60
61
|
snapshots={snapshots}
|
|
61
|
-
spec={spec}
|
|
62
|
-
narrative={narrative}
|
|
63
62
|
narrativeEntries={narrativeEntries}
|
|
63
|
+
traceGraph={traceGraph}
|
|
64
|
+
runtimeOverlay={runtimeOverlay}
|
|
64
65
|
title="My Pipeline"
|
|
65
66
|
panelLabels={{ topology: "What Ran", details: "What Happened", timeline: "How Long" }}
|
|
66
|
-
renderFlowchart={({ spec, snapshots, selectedIndex, onNodeClick }) => (
|
|
67
|
-
<TracedFlowchartView
|
|
68
|
-
spec={spec}
|
|
69
|
-
snapshots={snapshots}
|
|
70
|
-
snapshotIndex={selectedIndex}
|
|
71
|
-
onNodeClick={onNodeClick}
|
|
72
|
-
/>
|
|
73
|
-
)}
|
|
74
67
|
/>
|
|
75
68
|
);
|
|
76
69
|
}
|
|
@@ -132,7 +125,8 @@ The all-in-one orchestrator. Handles time-travel, subflow drill-down, memory/nar
|
|
|
132
125
|
| Prop | Type | Default | Description |
|
|
133
126
|
|---|---|---|---|
|
|
134
127
|
| `snapshots` | `StageSnapshot[]` | required | Visualization snapshots |
|
|
135
|
-
| `
|
|
128
|
+
| `traceGraph` | `TraceGraph \| null` | — | Build-time graph — drives the flowchart + subflow drill-down |
|
|
129
|
+
| `runtimeOverlay` | `RuntimeOverlay` | — | Per-step execution overlay — lights the executed path |
|
|
136
130
|
| `title` | `string` | `"Flowchart"` | Breadcrumb root label |
|
|
137
131
|
| `narrative` | `string[]` | — | Flat narrative lines |
|
|
138
132
|
| `narrativeEntries` | `NarrativeEntry[]` | — | Structured narrative (rich rendering) |
|
|
@@ -164,7 +158,7 @@ Control which panels start open. Desktop default: details panel open (flowchart
|
|
|
164
158
|
|
|
165
159
|
```tsx
|
|
166
160
|
// Desktop (default) — memory panel open
|
|
167
|
-
<ExplainableShell snapshots={...}
|
|
161
|
+
<ExplainableShell snapshots={...} traceGraph={...} runtimeOverlay={...} />
|
|
168
162
|
|
|
169
163
|
// Mobile — all collapsed, flowchart fills screen
|
|
170
164
|
<ExplainableShell
|
|
@@ -378,6 +372,20 @@ pipeline and snapshot-asserts the outputs in `test/golden/__snapshots__/`.
|
|
|
378
372
|
`footprintjs` is a devDependency used ONLY by the generator — the published
|
|
379
373
|
library still has zero footprintjs dependency (it consumes plain JSON shapes).
|
|
380
374
|
|
|
375
|
+
## The footprintjs ecosystem
|
|
376
|
+
|
|
377
|
+
The self-explaining stack — from backend pipelines to AI agents. → **[overview](https://footprintjs.github.io/)**
|
|
378
|
+
|
|
379
|
+
| Project | Role |
|
|
380
|
+
|---|---|
|
|
381
|
+
| [footprintjs](https://footprintjs.github.io/footPrint/) | the flowchart pattern (core engine) |
|
|
382
|
+
| [agentfootprint](https://footprintjs.github.io/agentfootprint/) | build self-explaining AI agents |
|
|
383
|
+
| **Explainable UI** ← you are here | visualize a footprintjs run |
|
|
384
|
+
| [Lens](https://github.com/footprintjs/agentfootprint-lens) | debug an agentfootprint run |
|
|
385
|
+
| [Thinking UI](https://footprintjs.github.io/agentThinkingUI/) | replay an agent run for non-devs |
|
|
386
|
+
|
|
387
|
+
---
|
|
388
|
+
|
|
381
389
|
## License
|
|
382
390
|
|
|
383
391
|
MIT
|
package/dist/index.cjs
CHANGED
|
@@ -5994,42 +5994,19 @@ var DetailsContent = (0, import_react31.memo)(function DetailsContent2({
|
|
|
5994
5994
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { style: { flex: 1, overflow: "auto" }, children: activeView?.render({ snapshots, selectedIndex }) })
|
|
5995
5995
|
] });
|
|
5996
5996
|
});
|
|
5997
|
-
function
|
|
5998
|
-
const
|
|
5999
|
-
|
|
6000
|
-
|
|
6001
|
-
|
|
6002
|
-
|
|
5997
|
+
function resolveSubflowFromRuntime(parentSnapshots, subflowId, narrativeEntries) {
|
|
5998
|
+
const localId = subflowId.split("/").pop() ?? subflowId;
|
|
5999
|
+
const parentSnap = parentSnapshots.find((s) => {
|
|
6000
|
+
if (!s.subflowResult) return false;
|
|
6001
|
+
const sfStageId = s.runtimeStageId?.split("#")[0]?.split("/").pop();
|
|
6002
|
+
return s.subflowId === subflowId || s.subflowId === localId || s.stageName === subflowId || s.stageLabel === subflowId || sfStageId === subflowId || sfStageId === localId;
|
|
6003
|
+
});
|
|
6003
6004
|
if (!parentSnap?.subflowResult) return null;
|
|
6004
|
-
const
|
|
6005
|
-
const
|
|
6006
|
-
const sfNarrative = narrativeEntries ? extractSubflowNarrative(narrativeEntries, sfId, sfDisplayName) : void 0;
|
|
6005
|
+
const label = parentSnap.stageLabel ?? parentSnap.stageName ?? localId;
|
|
6006
|
+
const sfNarrative = narrativeEntries ? extractSubflowNarrative(narrativeEntries, subflowId, label) : void 0;
|
|
6007
6007
|
const sfSnapshots = subflowResultToSnapshots(parentSnap.subflowResult, sfNarrative);
|
|
6008
6008
|
if (sfSnapshots.length === 0) return null;
|
|
6009
|
-
return {
|
|
6010
|
-
subflowId: specNode.subflowId ?? subflowNodeName,
|
|
6011
|
-
label: specNode.subflowName ?? specNode.name,
|
|
6012
|
-
spec: specNode.subflowStructure,
|
|
6013
|
-
snapshots: sfSnapshots
|
|
6014
|
-
};
|
|
6015
|
-
}
|
|
6016
|
-
function findSubflowSpecNode(node, name) {
|
|
6017
|
-
if ((node.name === name || node.id === name) && node.isSubflowRoot) return node;
|
|
6018
|
-
if (node.children) {
|
|
6019
|
-
for (const child of node.children) {
|
|
6020
|
-
const f = findSubflowSpecNode(child, name);
|
|
6021
|
-
if (f) return f;
|
|
6022
|
-
}
|
|
6023
|
-
}
|
|
6024
|
-
if (node.next) return findSubflowSpecNode(node.next, name);
|
|
6025
|
-
return null;
|
|
6026
|
-
}
|
|
6027
|
-
function hasSubflowNodes(node) {
|
|
6028
|
-
if (!node) return false;
|
|
6029
|
-
if (node.isSubflowRoot) return true;
|
|
6030
|
-
if (node.children?.some((c) => c && hasSubflowNodes(c))) return true;
|
|
6031
|
-
if (node.next && hasSubflowNodes(node.next)) return true;
|
|
6032
|
-
return false;
|
|
6009
|
+
return { subflowId, label, spec: null, snapshots: sfSnapshots, narrative: sfNarrative };
|
|
6033
6010
|
}
|
|
6034
6011
|
function buildDataTrace(commitLog, targetRuntimeStageId, maxDepth = 10) {
|
|
6035
6012
|
const log = commitLog;
|
|
@@ -6071,7 +6048,6 @@ var RightPanel = (0, import_react31.memo)(function RightPanel2({
|
|
|
6071
6048
|
snapshots,
|
|
6072
6049
|
selectedIndex,
|
|
6073
6050
|
runtimeSnapshot,
|
|
6074
|
-
spec,
|
|
6075
6051
|
activeTab,
|
|
6076
6052
|
allTabs,
|
|
6077
6053
|
activeNarrativeEntries,
|
|
@@ -6117,7 +6093,7 @@ var RightPanel = (0, import_react31.memo)(function RightPanel2({
|
|
|
6117
6093
|
id: tab.id,
|
|
6118
6094
|
name: insightName(tab.name),
|
|
6119
6095
|
render: () => {
|
|
6120
|
-
if (tab.id === "narrative") return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(NarrativePanel, { snapshots, selectedIndex, narrativeEntries: activeNarrativeEntries, runtimeSnapshot,
|
|
6096
|
+
if (tab.id === "narrative") return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(NarrativePanel, { snapshots, selectedIndex, narrativeEntries: activeNarrativeEntries, runtimeSnapshot, size, style: { height: "100%" } });
|
|
6121
6097
|
const customView = recorderViews?.find((v2) => v2.id === tab.id);
|
|
6122
6098
|
if (customView?.render) return customView.render({ snapshots, selectedIndex });
|
|
6123
6099
|
const autoView = autoRecorderViews.find((v2) => v2.id === tab.id);
|
|
@@ -6151,7 +6127,6 @@ function insightName(name) {
|
|
|
6151
6127
|
function ExplainableShell({
|
|
6152
6128
|
snapshots: snapshotsProp,
|
|
6153
6129
|
runtimeSnapshot,
|
|
6154
|
-
spec,
|
|
6155
6130
|
title,
|
|
6156
6131
|
resultData: resultDataProp,
|
|
6157
6132
|
logs = [],
|
|
@@ -6167,6 +6142,7 @@ function ExplainableShell({
|
|
|
6167
6142
|
showStageId = false,
|
|
6168
6143
|
traceGraph,
|
|
6169
6144
|
runtimeOverlay,
|
|
6145
|
+
traceTheme,
|
|
6170
6146
|
size = "default",
|
|
6171
6147
|
unstyled = false,
|
|
6172
6148
|
className,
|
|
@@ -6189,16 +6165,27 @@ function ExplainableShell({
|
|
|
6189
6165
|
const activeRsid = snapshots2[selectedIndex]?.runtimeStageId;
|
|
6190
6166
|
let overlayIdx = selectedIndex;
|
|
6191
6167
|
if (activeRsid && runtimeOverlay) {
|
|
6192
|
-
|
|
6168
|
+
let i = runtimeOverlay.executionOrder.findIndex(
|
|
6193
6169
|
(s) => s.runtimeStageId === activeRsid
|
|
6194
6170
|
);
|
|
6171
|
+
if (i < 0) {
|
|
6172
|
+
i = runtimeOverlay.executionOrder.findIndex(
|
|
6173
|
+
(s) => s.runtimeStageId?.endsWith("/" + activeRsid)
|
|
6174
|
+
);
|
|
6175
|
+
}
|
|
6195
6176
|
if (i >= 0) overlayIdx = i;
|
|
6196
6177
|
}
|
|
6178
|
+
const traceColors = traceTheme && {
|
|
6179
|
+
...traceTheme.visited !== void 0 && { done: traceTheme.visited },
|
|
6180
|
+
...traceTheme.current !== void 0 && { active: traceTheme.current },
|
|
6181
|
+
...traceTheme.mode !== void 0 && { default: traceTheme.mode === "dark" ? "#94a3b8" : "#64748b" }
|
|
6182
|
+
};
|
|
6197
6183
|
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
6198
6184
|
TracedFlow,
|
|
6199
6185
|
{
|
|
6200
6186
|
graph: traceGraph,
|
|
6201
6187
|
overlay: runtimeOverlay ?? void 0,
|
|
6188
|
+
colors: traceColors || void 0,
|
|
6202
6189
|
scrubIndex: overlayIdx,
|
|
6203
6190
|
onNodeClick: (stageId) => onNodeClick?.(stageId),
|
|
6204
6191
|
onSubflowChange: (mountId) => {
|
|
@@ -6207,7 +6194,7 @@ function ExplainableShell({
|
|
|
6207
6194
|
}
|
|
6208
6195
|
);
|
|
6209
6196
|
};
|
|
6210
|
-
}, [traceGraph, runtimeOverlay]);
|
|
6197
|
+
}, [traceGraph, runtimeOverlay, traceTheme]);
|
|
6211
6198
|
const effectiveRenderFlowchart = renderFlowchart ?? tracedFlowRenderer;
|
|
6212
6199
|
const leftLabel = panelLabels?.topology ?? "Topology";
|
|
6213
6200
|
const rightLabel = panelLabels?.details ?? "Details";
|
|
@@ -6287,24 +6274,23 @@ function ExplainableShell({
|
|
|
6287
6274
|
const currentLevel = (0, import_react31.useMemo)(() => {
|
|
6288
6275
|
if (drillDownStack.length > 0) {
|
|
6289
6276
|
const top = drillDownStack[drillDownStack.length - 1];
|
|
6290
|
-
return { spec: top.spec, snapshots: top.snapshots };
|
|
6277
|
+
return { spec: top.spec, snapshots: top.snapshots, narrative: top.narrative };
|
|
6291
6278
|
}
|
|
6292
|
-
return { spec:
|
|
6293
|
-
}, [drillDownStack,
|
|
6279
|
+
return { spec: null, snapshots, narrative: void 0 };
|
|
6280
|
+
}, [drillDownStack, snapshots]);
|
|
6294
6281
|
const activeSnapshots = currentLevel.snapshots;
|
|
6295
|
-
const activeSpec = currentLevel.spec;
|
|
6296
6282
|
const safeIdx = activeSnapshots.length > 0 ? Math.max(0, Math.min(snapshotIdx, activeSnapshots.length - 1)) : 0;
|
|
6297
|
-
const activeNarrativeEntries = isInSubflow ?
|
|
6283
|
+
const activeNarrativeEntries = isInSubflow ? currentLevel.narrative : narrativeEntries;
|
|
6298
6284
|
const breadcrumbs = (0, import_react31.useMemo)(() => {
|
|
6299
|
-
const root = { label: title || "Flowchart", spec, description:
|
|
6285
|
+
const root = { label: title || "Flowchart", spec: null, description: void 0 };
|
|
6300
6286
|
return [root, ...drillDownStack.map((e) => ({ label: e.label, spec: e.spec, description: void 0 }))];
|
|
6301
|
-
}, [
|
|
6287
|
+
}, [title, drillDownStack]);
|
|
6302
6288
|
const showTreeSidebar = (0, import_react31.useMemo)(() => {
|
|
6303
6289
|
if (traceGraph?.nodes?.length) {
|
|
6304
6290
|
return traceGraph.nodes.some((n) => n.data?.isSubflow === true);
|
|
6305
6291
|
}
|
|
6306
|
-
return
|
|
6307
|
-
}, [traceGraph
|
|
6292
|
+
return false;
|
|
6293
|
+
}, [traceGraph]);
|
|
6308
6294
|
const rootOverlay = (0, import_react31.useMemo)(() => {
|
|
6309
6295
|
if (isInSubflow || !snapshots.length) return { activeStage: void 0, doneStages: void 0 };
|
|
6310
6296
|
const doneStages = new Set(snapshots.slice(0, safeIdx).map((s) => s.stageLabel));
|
|
@@ -6320,14 +6306,13 @@ function ExplainableShell({
|
|
|
6320
6306
|
}, []);
|
|
6321
6307
|
const handleDrillDown = (0, import_react31.useCallback)(
|
|
6322
6308
|
(nodeName) => {
|
|
6323
|
-
|
|
6324
|
-
const entry = resolveSubflowLevel(activeSpec, activeSnapshots, nodeName, narrativeEntries);
|
|
6309
|
+
const entry = resolveSubflowFromRuntime(activeSnapshots, nodeName, narrativeEntries);
|
|
6325
6310
|
if (entry) {
|
|
6326
6311
|
setDrillDownStack((prev) => [...prev, { ...entry, parentSnapshotIdx: snapshotIdx }]);
|
|
6327
6312
|
setSnapshotIdx(0);
|
|
6328
6313
|
}
|
|
6329
6314
|
},
|
|
6330
|
-
[
|
|
6315
|
+
[activeSnapshots, narrativeEntries, snapshotIdx]
|
|
6331
6316
|
);
|
|
6332
6317
|
const handleBreadcrumbNavigate = (0, import_react31.useCallback)((level) => {
|
|
6333
6318
|
setDrillDownStack((prev) => {
|
|
@@ -6342,23 +6327,21 @@ function ExplainableShell({
|
|
|
6342
6327
|
setSnapshotIdx(indexOrId);
|
|
6343
6328
|
return;
|
|
6344
6329
|
}
|
|
6345
|
-
|
|
6346
|
-
|
|
6347
|
-
|
|
6348
|
-
|
|
6349
|
-
return;
|
|
6350
|
-
}
|
|
6330
|
+
const drillable = resolveSubflowFromRuntime(activeSnapshots, indexOrId, narrativeEntries);
|
|
6331
|
+
if (drillable) {
|
|
6332
|
+
handleDrillDown(indexOrId);
|
|
6333
|
+
return;
|
|
6351
6334
|
}
|
|
6352
6335
|
const idx = activeSnapshots.findIndex((s) => s.stageLabel === indexOrId);
|
|
6353
6336
|
if (idx >= 0) setSnapshotIdx(idx);
|
|
6354
6337
|
},
|
|
6355
|
-
[
|
|
6338
|
+
[activeSnapshots, narrativeEntries, handleDrillDown]
|
|
6356
6339
|
);
|
|
6357
6340
|
const handleTreeNodeSelect = (0, import_react31.useCallback)(
|
|
6358
6341
|
(name, isSubflow) => {
|
|
6359
|
-
if (isSubflow
|
|
6342
|
+
if (isSubflow) {
|
|
6360
6343
|
setDrillDownStack([]);
|
|
6361
|
-
const entry =
|
|
6344
|
+
const entry = resolveSubflowFromRuntime(snapshots, name, narrativeEntries);
|
|
6362
6345
|
if (entry) {
|
|
6363
6346
|
setDrillDownStack([{ ...entry, parentSnapshotIdx: snapshotIdx }]);
|
|
6364
6347
|
setSnapshotIdx(0);
|
|
@@ -6369,7 +6352,7 @@ function ExplainableShell({
|
|
|
6369
6352
|
if (idx >= 0) setSnapshotIdx(idx);
|
|
6370
6353
|
}
|
|
6371
6354
|
},
|
|
6372
|
-
[
|
|
6355
|
+
[snapshots, narrativeEntries, snapshotIdx]
|
|
6373
6356
|
);
|
|
6374
6357
|
const tabLabels = new Map(allTabs.map((t) => [t.id, t.name]));
|
|
6375
6358
|
if (unstyled) {
|
|
@@ -6380,7 +6363,7 @@ function ExplainableShell({
|
|
|
6380
6363
|
(activeTab === "explainable" || activeTab === "ai-compatible") && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
|
|
6381
6364
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(TimeTravelControls, { snapshots: activeSnapshots, selectedIndex: safeIdx, onIndexChange: handleSnapshotChange, unstyled: true }),
|
|
6382
6365
|
isInSubflow && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(SubflowBreadcrumb, { breadcrumbs, onNavigate: handleBreadcrumbNavigate }),
|
|
6383
|
-
|
|
6366
|
+
traceGraph && effectiveRenderFlowchart?.({ spec: null, snapshots: activeSnapshots, selectedIndex: safeIdx, onNodeClick: handleNodeClick, showStageId }),
|
|
6384
6367
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(MemoryPanel, { snapshots: activeSnapshots, selectedIndex: safeIdx, unstyled: true }),
|
|
6385
6368
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(NarrativePanel, { snapshots: activeSnapshots, selectedIndex: safeIdx, narrativeEntries: activeNarrativeEntries, unstyled: true }),
|
|
6386
6369
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(GanttTimeline, { snapshots: activeSnapshots, selectedIndex: safeIdx, onSelect: handleSnapshotChange, unstyled: true })
|
|
@@ -6388,7 +6371,7 @@ function ExplainableShell({
|
|
|
6388
6371
|
] })
|
|
6389
6372
|
] });
|
|
6390
6373
|
}
|
|
6391
|
-
const showTopology = !!effectiveRenderFlowchart && !!
|
|
6374
|
+
const showTopology = !!effectiveRenderFlowchart && !!traceGraph;
|
|
6392
6375
|
const detailsContent = (0, import_react31.useMemo)(() => {
|
|
6393
6376
|
if (activeTab === "result") {
|
|
6394
6377
|
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ResultPanel, { data: resultData ?? null, logs, hideConsole, size });
|
|
@@ -6485,7 +6468,7 @@ function ExplainableShell({
|
|
|
6485
6468
|
/* ── Mobile: stacked vertical ── */
|
|
6486
6469
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
|
|
6487
6470
|
showTopology && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { style: { height: 350, flexShrink: 0, overflow: "hidden" }, children: effectiveRenderFlowchart({
|
|
6488
|
-
spec:
|
|
6471
|
+
spec: null,
|
|
6489
6472
|
snapshots: activeSnapshots,
|
|
6490
6473
|
selectedIndex: safeIdx,
|
|
6491
6474
|
onNodeClick: handleNodeClick,
|
|
@@ -6525,7 +6508,7 @@ function ExplainableShell({
|
|
|
6525
6508
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(VLinePill, { label: "Topology", expanded: true, side: "left", onClick: () => toggleLeft(false) })
|
|
6526
6509
|
] }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(VLinePill, { label: "Topology", expanded: false, side: "left", onClick: () => toggleLeft(true) })),
|
|
6527
6510
|
showTopology ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { style: { flex: 1, overflow: "hidden", minWidth: 0 }, children: effectiveRenderFlowchart({
|
|
6528
|
-
spec:
|
|
6511
|
+
spec: null,
|
|
6529
6512
|
snapshots: activeSnapshots,
|
|
6530
6513
|
selectedIndex: safeIdx,
|
|
6531
6514
|
onNodeClick: handleNodeClick,
|
|
@@ -6540,7 +6523,6 @@ function ExplainableShell({
|
|
|
6540
6523
|
snapshots: activeSnapshots,
|
|
6541
6524
|
selectedIndex: safeIdx,
|
|
6542
6525
|
runtimeSnapshot,
|
|
6543
|
-
spec,
|
|
6544
6526
|
activeTab,
|
|
6545
6527
|
allTabs,
|
|
6546
6528
|
activeNarrativeEntries,
|
|
@@ -6657,7 +6639,6 @@ function TraceViewer({
|
|
|
6657
6639
|
ExplainableShell,
|
|
6658
6640
|
{
|
|
6659
6641
|
snapshots,
|
|
6660
|
-
spec: parsed.trace.spec,
|
|
6661
6642
|
narrativeEntries: parsed.trace.narrativeEntries,
|
|
6662
6643
|
tabs,
|
|
6663
6644
|
defaultTab,
|