footprint-explainable-ui 0.25.5 → 0.26.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.
package/dist/index.d.cts CHANGED
@@ -636,10 +636,9 @@ interface ExplainableShellProps extends BaseComponentProps {
636
636
  * and `resultData` are derived automatically. Pair with
637
637
  * `narrativeEntries` for rich per-stage narrative.
638
638
  *
639
- * Usage: `<ExplainableShell runtimeSnapshot={executor.getSnapshot()} narrativeEntries={executor.getNarrativeEntries()} spec={spec} />`
639
+ * Usage: `<ExplainableShell runtimeSnapshot={executor.getSnapshot()} narrativeEntries={executor.getNarrativeEntries()} traceGraph={graph} runtimeOverlay={overlay} />`
640
640
  */
641
641
  runtimeSnapshot?: RuntimeSnapshotInput | null;
642
- spec?: SpecNode | null;
643
642
  /**
644
643
  * Build-time graph captured live via `createTraceStructureRecorder`.
645
644
  * REQUIRED for chart rendering (v6+) — the legacy `spec` →
@@ -714,7 +713,7 @@ interface ExplainableShellProps extends BaseComponentProps {
714
713
  */
715
714
  showStageId?: boolean;
716
715
  }
717
- declare function ExplainableShell({ snapshots: snapshotsProp, runtimeSnapshot, spec, title, resultData: resultDataProp, logs, narrativeEntries, tabs, defaultTab, hideConsole, hideTabs: hideTabsProp, panelLabels, defaultExpanded, recorderViews, renderFlowchart, showStageId, traceGraph, runtimeOverlay, size, unstyled, className, style, }: ExplainableShellProps): react.JSX.Element;
716
+ declare function ExplainableShell({ snapshots: snapshotsProp, runtimeSnapshot, title, resultData: resultDataProp, logs, narrativeEntries, tabs, defaultTab, hideConsole, hideTabs: hideTabsProp, panelLabels, defaultExpanded, recorderViews, renderFlowchart, showStageId, traceGraph, runtimeOverlay, size, unstyled, className, style, }: ExplainableShellProps): react.JSX.Element;
718
717
 
719
718
  /**
720
719
  * TraceViewer — drop-in component that renders an `agentfootprint.exportTrace()`
package/dist/index.d.ts CHANGED
@@ -636,10 +636,9 @@ interface ExplainableShellProps extends BaseComponentProps {
636
636
  * and `resultData` are derived automatically. Pair with
637
637
  * `narrativeEntries` for rich per-stage narrative.
638
638
  *
639
- * Usage: `<ExplainableShell runtimeSnapshot={executor.getSnapshot()} narrativeEntries={executor.getNarrativeEntries()} spec={spec} />`
639
+ * Usage: `<ExplainableShell runtimeSnapshot={executor.getSnapshot()} narrativeEntries={executor.getNarrativeEntries()} traceGraph={graph} runtimeOverlay={overlay} />`
640
640
  */
641
641
  runtimeSnapshot?: RuntimeSnapshotInput | null;
642
- spec?: SpecNode | null;
643
642
  /**
644
643
  * Build-time graph captured live via `createTraceStructureRecorder`.
645
644
  * REQUIRED for chart rendering (v6+) — the legacy `spec` →
@@ -714,7 +713,7 @@ interface ExplainableShellProps extends BaseComponentProps {
714
713
  */
715
714
  showStageId?: boolean;
716
715
  }
717
- declare function ExplainableShell({ snapshots: snapshotsProp, runtimeSnapshot, spec, title, resultData: resultDataProp, logs, narrativeEntries, tabs, defaultTab, hideConsole, hideTabs: hideTabsProp, panelLabels, defaultExpanded, recorderViews, renderFlowchart, showStageId, traceGraph, runtimeOverlay, size, unstyled, className, style, }: ExplainableShellProps): react.JSX.Element;
716
+ declare function ExplainableShell({ snapshots: snapshotsProp, runtimeSnapshot, title, resultData: resultDataProp, logs, narrativeEntries, tabs, defaultTab, hideConsole, hideTabs: hideTabsProp, panelLabels, defaultExpanded, recorderViews, renderFlowchart, showStageId, traceGraph, runtimeOverlay, size, unstyled, className, style, }: ExplainableShellProps): react.JSX.Element;
718
717
 
719
718
  /**
720
719
  * TraceViewer — drop-in component that renders an `agentfootprint.exportTrace()`
package/dist/index.js CHANGED
@@ -5927,42 +5927,19 @@ var DetailsContent = memo8(function DetailsContent2({
5927
5927
  /* @__PURE__ */ jsx26("div", { style: { flex: 1, overflow: "auto" }, children: activeView?.render({ snapshots, selectedIndex }) })
5928
5928
  ] });
5929
5929
  });
5930
- function resolveSubflowLevel(parentSpec, parentSnapshots, subflowNodeName, narrativeEntries) {
5931
- const specNode = findSubflowSpecNode(parentSpec, subflowNodeName);
5932
- if (!specNode?.subflowStructure) return null;
5933
- const parentSnap = parentSnapshots.find(
5934
- (s) => s.stageName === subflowNodeName || s.stageLabel === subflowNodeName
5935
- );
5930
+ function resolveSubflowFromRuntime(parentSnapshots, subflowId, narrativeEntries) {
5931
+ const localId = subflowId.split("/").pop() ?? subflowId;
5932
+ const parentSnap = parentSnapshots.find((s) => {
5933
+ if (!s.subflowResult) return false;
5934
+ const sfStageId = s.runtimeStageId?.split("#")[0]?.split("/").pop();
5935
+ return s.subflowId === subflowId || s.subflowId === localId || s.stageName === subflowId || s.stageLabel === subflowId || sfStageId === subflowId || sfStageId === localId;
5936
+ });
5936
5937
  if (!parentSnap?.subflowResult) return null;
5937
- const sfId = specNode.subflowId ?? subflowNodeName;
5938
- const sfDisplayName = specNode.subflowName ?? specNode.name;
5939
- const sfNarrative = narrativeEntries ? extractSubflowNarrative(narrativeEntries, sfId, sfDisplayName) : void 0;
5938
+ const label = parentSnap.stageLabel ?? parentSnap.stageName ?? localId;
5939
+ const sfNarrative = narrativeEntries ? extractSubflowNarrative(narrativeEntries, subflowId, label) : void 0;
5940
5940
  const sfSnapshots = subflowResultToSnapshots(parentSnap.subflowResult, sfNarrative);
5941
5941
  if (sfSnapshots.length === 0) return null;
5942
- return {
5943
- subflowId: specNode.subflowId ?? subflowNodeName,
5944
- label: specNode.subflowName ?? specNode.name,
5945
- spec: specNode.subflowStructure,
5946
- snapshots: sfSnapshots
5947
- };
5948
- }
5949
- function findSubflowSpecNode(node, name) {
5950
- if ((node.name === name || node.id === name) && node.isSubflowRoot) return node;
5951
- if (node.children) {
5952
- for (const child of node.children) {
5953
- const f = findSubflowSpecNode(child, name);
5954
- if (f) return f;
5955
- }
5956
- }
5957
- if (node.next) return findSubflowSpecNode(node.next, name);
5958
- return null;
5959
- }
5960
- function hasSubflowNodes(node) {
5961
- if (!node) return false;
5962
- if (node.isSubflowRoot) return true;
5963
- if (node.children?.some((c) => c && hasSubflowNodes(c))) return true;
5964
- if (node.next && hasSubflowNodes(node.next)) return true;
5965
- return false;
5942
+ return { subflowId, label, spec: null, snapshots: sfSnapshots, narrative: sfNarrative };
5966
5943
  }
5967
5944
  function buildDataTrace(commitLog, targetRuntimeStageId, maxDepth = 10) {
5968
5945
  const log = commitLog;
@@ -6004,7 +5981,6 @@ var RightPanel = memo8(function RightPanel2({
6004
5981
  snapshots,
6005
5982
  selectedIndex,
6006
5983
  runtimeSnapshot,
6007
- spec,
6008
5984
  activeTab,
6009
5985
  allTabs,
6010
5986
  activeNarrativeEntries,
@@ -6050,7 +6026,7 @@ var RightPanel = memo8(function RightPanel2({
6050
6026
  id: tab.id,
6051
6027
  name: insightName(tab.name),
6052
6028
  render: () => {
6053
- if (tab.id === "narrative") return /* @__PURE__ */ jsx26(NarrativePanel, { snapshots, selectedIndex, narrativeEntries: activeNarrativeEntries, runtimeSnapshot, spec, size, style: { height: "100%" } });
6029
+ if (tab.id === "narrative") return /* @__PURE__ */ jsx26(NarrativePanel, { snapshots, selectedIndex, narrativeEntries: activeNarrativeEntries, runtimeSnapshot, size, style: { height: "100%" } });
6054
6030
  const customView = recorderViews?.find((v2) => v2.id === tab.id);
6055
6031
  if (customView?.render) return customView.render({ snapshots, selectedIndex });
6056
6032
  const autoView = autoRecorderViews.find((v2) => v2.id === tab.id);
@@ -6084,7 +6060,6 @@ function insightName(name) {
6084
6060
  function ExplainableShell({
6085
6061
  snapshots: snapshotsProp,
6086
6062
  runtimeSnapshot,
6087
- spec,
6088
6063
  title,
6089
6064
  resultData: resultDataProp,
6090
6065
  logs = [],
@@ -6122,9 +6097,14 @@ function ExplainableShell({
6122
6097
  const activeRsid = snapshots2[selectedIndex]?.runtimeStageId;
6123
6098
  let overlayIdx = selectedIndex;
6124
6099
  if (activeRsid && runtimeOverlay) {
6125
- const i = runtimeOverlay.executionOrder.findIndex(
6100
+ let i = runtimeOverlay.executionOrder.findIndex(
6126
6101
  (s) => s.runtimeStageId === activeRsid
6127
6102
  );
6103
+ if (i < 0) {
6104
+ i = runtimeOverlay.executionOrder.findIndex(
6105
+ (s) => s.runtimeStageId?.endsWith("/" + activeRsid)
6106
+ );
6107
+ }
6128
6108
  if (i >= 0) overlayIdx = i;
6129
6109
  }
6130
6110
  return /* @__PURE__ */ jsx26(
@@ -6220,24 +6200,23 @@ function ExplainableShell({
6220
6200
  const currentLevel = useMemo12(() => {
6221
6201
  if (drillDownStack.length > 0) {
6222
6202
  const top = drillDownStack[drillDownStack.length - 1];
6223
- return { spec: top.spec, snapshots: top.snapshots };
6203
+ return { spec: top.spec, snapshots: top.snapshots, narrative: top.narrative };
6224
6204
  }
6225
- return { spec: spec ?? null, snapshots };
6226
- }, [drillDownStack, spec, snapshots]);
6205
+ return { spec: null, snapshots, narrative: void 0 };
6206
+ }, [drillDownStack, snapshots]);
6227
6207
  const activeSnapshots = currentLevel.snapshots;
6228
- const activeSpec = currentLevel.spec;
6229
6208
  const safeIdx = activeSnapshots.length > 0 ? Math.max(0, Math.min(snapshotIdx, activeSnapshots.length - 1)) : 0;
6230
- const activeNarrativeEntries = isInSubflow ? void 0 : narrativeEntries;
6209
+ const activeNarrativeEntries = isInSubflow ? currentLevel.narrative : narrativeEntries;
6231
6210
  const breadcrumbs = useMemo12(() => {
6232
- const root = { label: title || "Flowchart", spec, description: spec?.description };
6211
+ const root = { label: title || "Flowchart", spec: null, description: void 0 };
6233
6212
  return [root, ...drillDownStack.map((e) => ({ label: e.label, spec: e.spec, description: void 0 }))];
6234
- }, [spec, title, drillDownStack]);
6213
+ }, [title, drillDownStack]);
6235
6214
  const showTreeSidebar = useMemo12(() => {
6236
6215
  if (traceGraph?.nodes?.length) {
6237
6216
  return traceGraph.nodes.some((n) => n.data?.isSubflow === true);
6238
6217
  }
6239
- return !!spec && hasSubflowNodes(spec);
6240
- }, [traceGraph, spec]);
6218
+ return false;
6219
+ }, [traceGraph]);
6241
6220
  const rootOverlay = useMemo12(() => {
6242
6221
  if (isInSubflow || !snapshots.length) return { activeStage: void 0, doneStages: void 0 };
6243
6222
  const doneStages = new Set(snapshots.slice(0, safeIdx).map((s) => s.stageLabel));
@@ -6253,14 +6232,13 @@ function ExplainableShell({
6253
6232
  }, []);
6254
6233
  const handleDrillDown = useCallback8(
6255
6234
  (nodeName) => {
6256
- if (!activeSpec) return;
6257
- const entry = resolveSubflowLevel(activeSpec, activeSnapshots, nodeName, narrativeEntries);
6235
+ const entry = resolveSubflowFromRuntime(activeSnapshots, nodeName, narrativeEntries);
6258
6236
  if (entry) {
6259
6237
  setDrillDownStack((prev) => [...prev, { ...entry, parentSnapshotIdx: snapshotIdx }]);
6260
6238
  setSnapshotIdx(0);
6261
6239
  }
6262
6240
  },
6263
- [activeSpec, activeSnapshots, narrativeEntries, snapshotIdx]
6241
+ [activeSnapshots, narrativeEntries, snapshotIdx]
6264
6242
  );
6265
6243
  const handleBreadcrumbNavigate = useCallback8((level) => {
6266
6244
  setDrillDownStack((prev) => {
@@ -6275,23 +6253,21 @@ function ExplainableShell({
6275
6253
  setSnapshotIdx(indexOrId);
6276
6254
  return;
6277
6255
  }
6278
- if (activeSpec) {
6279
- const sfNode = findSubflowSpecNode(activeSpec, indexOrId);
6280
- if (sfNode?.subflowStructure) {
6281
- handleDrillDown(indexOrId);
6282
- return;
6283
- }
6256
+ const drillable = resolveSubflowFromRuntime(activeSnapshots, indexOrId, narrativeEntries);
6257
+ if (drillable) {
6258
+ handleDrillDown(indexOrId);
6259
+ return;
6284
6260
  }
6285
6261
  const idx = activeSnapshots.findIndex((s) => s.stageLabel === indexOrId);
6286
6262
  if (idx >= 0) setSnapshotIdx(idx);
6287
6263
  },
6288
- [activeSpec, activeSnapshots, handleDrillDown]
6264
+ [activeSnapshots, narrativeEntries, handleDrillDown]
6289
6265
  );
6290
6266
  const handleTreeNodeSelect = useCallback8(
6291
6267
  (name, isSubflow) => {
6292
- if (isSubflow && spec) {
6268
+ if (isSubflow) {
6293
6269
  setDrillDownStack([]);
6294
- const entry = resolveSubflowLevel(spec, snapshots, name, narrativeEntries);
6270
+ const entry = resolveSubflowFromRuntime(snapshots, name, narrativeEntries);
6295
6271
  if (entry) {
6296
6272
  setDrillDownStack([{ ...entry, parentSnapshotIdx: snapshotIdx }]);
6297
6273
  setSnapshotIdx(0);
@@ -6302,7 +6278,7 @@ function ExplainableShell({
6302
6278
  if (idx >= 0) setSnapshotIdx(idx);
6303
6279
  }
6304
6280
  },
6305
- [spec, snapshots, narrativeEntries, snapshotIdx]
6281
+ [snapshots, narrativeEntries, snapshotIdx]
6306
6282
  );
6307
6283
  const tabLabels = new Map(allTabs.map((t) => [t.id, t.name]));
6308
6284
  if (unstyled) {
@@ -6313,7 +6289,7 @@ function ExplainableShell({
6313
6289
  (activeTab === "explainable" || activeTab === "ai-compatible") && /* @__PURE__ */ jsxs23(Fragment6, { children: [
6314
6290
  /* @__PURE__ */ jsx26(TimeTravelControls, { snapshots: activeSnapshots, selectedIndex: safeIdx, onIndexChange: handleSnapshotChange, unstyled: true }),
6315
6291
  isInSubflow && /* @__PURE__ */ jsx26(SubflowBreadcrumb, { breadcrumbs, onNavigate: handleBreadcrumbNavigate }),
6316
- activeSpec && effectiveRenderFlowchart?.({ spec: activeSpec, snapshots: activeSnapshots, selectedIndex: safeIdx, onNodeClick: handleNodeClick, showStageId }),
6292
+ traceGraph && effectiveRenderFlowchart?.({ spec: null, snapshots: activeSnapshots, selectedIndex: safeIdx, onNodeClick: handleNodeClick, showStageId }),
6317
6293
  /* @__PURE__ */ jsx26(MemoryPanel, { snapshots: activeSnapshots, selectedIndex: safeIdx, unstyled: true }),
6318
6294
  /* @__PURE__ */ jsx26(NarrativePanel, { snapshots: activeSnapshots, selectedIndex: safeIdx, narrativeEntries: activeNarrativeEntries, unstyled: true }),
6319
6295
  /* @__PURE__ */ jsx26(GanttTimeline, { snapshots: activeSnapshots, selectedIndex: safeIdx, onSelect: handleSnapshotChange, unstyled: true })
@@ -6321,7 +6297,7 @@ function ExplainableShell({
6321
6297
  ] })
6322
6298
  ] });
6323
6299
  }
6324
- const showTopology = !!effectiveRenderFlowchart && !!activeSpec;
6300
+ const showTopology = !!effectiveRenderFlowchart && !!traceGraph;
6325
6301
  const detailsContent = useMemo12(() => {
6326
6302
  if (activeTab === "result") {
6327
6303
  return /* @__PURE__ */ jsx26(ResultPanel, { data: resultData ?? null, logs, hideConsole, size });
@@ -6418,7 +6394,7 @@ function ExplainableShell({
6418
6394
  /* ── Mobile: stacked vertical ── */
6419
6395
  /* @__PURE__ */ jsxs23(Fragment6, { children: [
6420
6396
  showTopology && /* @__PURE__ */ jsx26("div", { style: { height: 350, flexShrink: 0, overflow: "hidden" }, children: effectiveRenderFlowchart({
6421
- spec: activeSpec,
6397
+ spec: null,
6422
6398
  snapshots: activeSnapshots,
6423
6399
  selectedIndex: safeIdx,
6424
6400
  onNodeClick: handleNodeClick,
@@ -6458,7 +6434,7 @@ function ExplainableShell({
6458
6434
  /* @__PURE__ */ jsx26(VLinePill, { label: "Topology", expanded: true, side: "left", onClick: () => toggleLeft(false) })
6459
6435
  ] }) : /* @__PURE__ */ jsx26(VLinePill, { label: "Topology", expanded: false, side: "left", onClick: () => toggleLeft(true) })),
6460
6436
  showTopology ? /* @__PURE__ */ jsx26("div", { style: { flex: 1, overflow: "hidden", minWidth: 0 }, children: effectiveRenderFlowchart({
6461
- spec: activeSpec,
6437
+ spec: null,
6462
6438
  snapshots: activeSnapshots,
6463
6439
  selectedIndex: safeIdx,
6464
6440
  onNodeClick: handleNodeClick,
@@ -6473,7 +6449,6 @@ function ExplainableShell({
6473
6449
  snapshots: activeSnapshots,
6474
6450
  selectedIndex: safeIdx,
6475
6451
  runtimeSnapshot,
6476
- spec,
6477
6452
  activeTab,
6478
6453
  allTabs,
6479
6454
  activeNarrativeEntries,
@@ -6590,7 +6565,6 @@ function TraceViewer({
6590
6565
  ExplainableShell,
6591
6566
  {
6592
6567
  snapshots,
6593
- spec: parsed.trace.spec,
6594
6568
  narrativeEntries: parsed.trace.narrativeEntries,
6595
6569
  tabs,
6596
6570
  defaultTab,