agentfootprint-lens 0.18.0 → 0.19.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.cjs CHANGED
@@ -416,6 +416,7 @@ __export(src_exports, {
416
416
  makeRootNodeId: () => makeRootNodeId,
417
417
  mergeOutputs: () => mergeOutputs,
418
418
  pinUnderParent: () => pinUnderParent,
419
+ routingPathTo: () => routingPathTo,
419
420
  selectAgentInstances: () => selectAgentInstances,
420
421
  selectCommentaryAt: () => selectCommentaryAt,
421
422
  selectCommentaryRanges: () => selectCommentaryRanges,
@@ -5815,7 +5816,7 @@ function shortType(type) {
5815
5816
  }
5816
5817
 
5817
5818
  // src/react/SkillGraphFlow.tsx
5818
- var import_react13 = require("react");
5819
+ var import_react13 = __toESM(require("react"), 1);
5819
5820
  var import_react14 = require("@xyflow/react");
5820
5821
  var import_style2 = require("@xyflow/react/dist/style.css");
5821
5822
 
@@ -5852,7 +5853,13 @@ function layoutSkillGraph(graph, opts = {}) {
5852
5853
  if (!g.hasNode(source) || !g.hasNode(e.to)) continue;
5853
5854
  const id = `sge${i++}:${source}->${e.to}`;
5854
5855
  g.setEdge(source, e.to, {}, id);
5855
- flowEdges.push({ id, source, target: e.to, label: e.label, dashed: e.kind === "model" });
5856
+ flowEdges.push({
5857
+ id,
5858
+ source,
5859
+ target: e.to,
5860
+ label: e.label,
5861
+ dashed: e.kind === "model"
5862
+ });
5856
5863
  }
5857
5864
  import_dagre2.default.layout(g);
5858
5865
  const toFlow = (id, kind, label) => {
@@ -5873,6 +5880,26 @@ function layoutSkillGraph(graph, opts = {}) {
5873
5880
  for (const n of graph.nodes) nodes.push(toFlow(n.id, n.kind, n.label ?? n.id));
5874
5881
  return { nodes, edges: flowEdges };
5875
5882
  }
5883
+ function routingPathTo(graph, nodeId) {
5884
+ const labelById = new Map(graph.nodes.map((n) => [n.id, n.label ?? n.id]));
5885
+ const incoming = /* @__PURE__ */ new Map();
5886
+ for (const e of graph.edges) incoming.set(e.to, { from: e.from, branch: e.label });
5887
+ const steps = [];
5888
+ const seen = /* @__PURE__ */ new Set([nodeId]);
5889
+ let cur = nodeId;
5890
+ while (cur) {
5891
+ const edge = incoming.get(cur);
5892
+ if (!edge || edge.from === null) break;
5893
+ if (seen.has(edge.from)) break;
5894
+ seen.add(edge.from);
5895
+ steps.push({
5896
+ predicate: labelById.get(edge.from) ?? edge.from,
5897
+ branch: edge.branch ?? ""
5898
+ });
5899
+ cur = edge.from;
5900
+ }
5901
+ return steps.reverse();
5902
+ }
5876
5903
 
5877
5904
  // src/react/SkillGraphFlow.tsx
5878
5905
  var import_jsx_runtime10 = require("react/jsx-runtime");
@@ -5947,7 +5974,17 @@ var SkillBoxNode = ({ data }) => {
5947
5974
  }
5948
5975
  }
5949
5976
  ),
5950
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { style: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: d.label }),
5977
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
5978
+ "span",
5979
+ {
5980
+ style: {
5981
+ overflow: "hidden",
5982
+ textOverflow: "ellipsis",
5983
+ whiteSpace: "nowrap"
5984
+ },
5985
+ children: d.label
5986
+ }
5987
+ ),
5951
5988
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react14.Handle, { type: "source", position: import_react14.Position.Bottom, style: HANDLE_STYLE, isConnectable: false })
5952
5989
  ]
5953
5990
  }
@@ -6000,9 +6037,34 @@ var NODE_TYPES = {
6000
6037
  sgPredicate: PredicateNode,
6001
6038
  sgSkill: SkillBoxNode
6002
6039
  };
6040
+ function RoutingPath({ steps }) {
6041
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: { marginTop: 12 }, children: [
6042
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { fontSize: 11, color: T.textMuted, marginBottom: 6 }, children: "REACHED WHEN" }),
6043
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
6044
+ "div",
6045
+ {
6046
+ style: {
6047
+ display: "flex",
6048
+ flexWrap: "wrap",
6049
+ alignItems: "center",
6050
+ gap: 6
6051
+ },
6052
+ children: steps.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react13.default.Fragment, { children: [
6053
+ i > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { style: { color: T.textMuted }, children: "\u2192" }),
6054
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { style: { fontSize: 12, color: T.textSecondary }, children: [
6055
+ s.predicate,
6056
+ " ",
6057
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("strong", { style: { color: s.branch === "yes" ? T.srcSkill : T.textMuted }, children: s.branch })
6058
+ ] })
6059
+ ] }, `${s.predicate}-${i}`))
6060
+ }
6061
+ )
6062
+ ] });
6063
+ }
6003
6064
  function DetailPanel({
6004
6065
  node,
6005
6066
  detail,
6067
+ routingPath,
6006
6068
  width
6007
6069
  }) {
6008
6070
  const panel = {
@@ -6022,19 +6084,30 @@ function DetailPanel({
6022
6084
  const isPredicate = node.kind === "predicate";
6023
6085
  const accent = isPredicate ? T.edgeDecision : T.srcSkill;
6024
6086
  return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("aside", { style: panel, "data-testid": "skill-graph-detail", children: [
6025
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { display: "flex", alignItems: "center", gap: 8, marginBottom: 4 }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
6026
- "span",
6087
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
6088
+ "div",
6027
6089
  {
6028
6090
  style: {
6029
- fontSize: 11,
6030
- fontWeight: 700,
6031
- textTransform: "uppercase",
6032
- letterSpacing: 0.5,
6033
- color: accent
6091
+ display: "flex",
6092
+ alignItems: "center",
6093
+ gap: 8,
6094
+ marginBottom: 4
6034
6095
  },
6035
- children: isPredicate ? "\u25C7 Decision" : "\u25A2 Skill"
6096
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
6097
+ "span",
6098
+ {
6099
+ style: {
6100
+ fontSize: 11,
6101
+ fontWeight: 700,
6102
+ textTransform: "uppercase",
6103
+ letterSpacing: 0.5,
6104
+ color: accent
6105
+ },
6106
+ children: isPredicate ? "\u25C7 Decision" : "\u25A2 Skill"
6107
+ }
6108
+ )
6036
6109
  }
6037
- ) }),
6110
+ ),
6038
6111
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { style: { margin: "0 0 12px", fontSize: 16 }, children: detail?.title ?? node.label ?? node.id }),
6039
6112
  isPredicate && !detail && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("p", { style: { color: T.textSecondary, fontSize: 13, margin: 0 }, children: [
6040
6113
  "Routes to its ",
@@ -6044,6 +6117,7 @@ function DetailPanel({
6044
6117
  " subtree based on this predicate, evaluated every iteration."
6045
6118
  ] }),
6046
6119
  detail?.description && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { style: { color: T.textSecondary, fontSize: 13, margin: "0 0 12px" }, children: detail.description }),
6120
+ routingPath.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(RoutingPath, { steps: routingPath }),
6047
6121
  detail?.meta?.map((row) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: { fontSize: 12, marginBottom: 6 }, children: [
6048
6122
  /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { style: { color: T.textMuted }, children: [
6049
6123
  row.label,
@@ -6149,7 +6223,10 @@ var SkillGraphFlow = ({
6149
6223
  height: n.height,
6150
6224
  draggable: false,
6151
6225
  selectable: n.kind !== "start",
6152
- data: { label: n.label, isSelected: n.id === selectedId }
6226
+ data: {
6227
+ label: n.label,
6228
+ isSelected: n.id === selectedId
6229
+ }
6153
6230
  }));
6154
6231
  const rfEdges2 = laid.edges.map((e) => ({
6155
6232
  id: e.id,
@@ -6163,7 +6240,12 @@ var SkillGraphFlow = ({
6163
6240
  },
6164
6241
  labelStyle: { fill: T.textMuted, fontFamily: T.fontSans, fontSize: 11 },
6165
6242
  labelBgStyle: { fill: T.bgPrimary, fillOpacity: 0.85 },
6166
- markerEnd: { type: import_react14.MarkerType.ArrowClosed, color: T.edgeDefault, width: 16, height: 16 }
6243
+ markerEnd: {
6244
+ type: import_react14.MarkerType.ArrowClosed,
6245
+ color: T.edgeDefault,
6246
+ width: 16,
6247
+ height: 16
6248
+ }
6167
6249
  }));
6168
6250
  return { rfNodes: rfNodes2, rfEdges: rfEdges2 };
6169
6251
  }, [graph, showStart, selectedId]);
@@ -6172,6 +6254,10 @@ var SkillGraphFlow = ({
6172
6254
  [graph.nodes, selectedId]
6173
6255
  );
6174
6256
  const detail = selectedNode && detailFor ? detailFor(selectedNode) : void 0;
6257
+ const routingPath = (0, import_react13.useMemo)(
6258
+ () => selectedNode ? routingPathTo(graph, selectedNode.id) : [],
6259
+ [graph, selectedNode]
6260
+ );
6175
6261
  return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
6176
6262
  "div",
6177
6263
  {
@@ -6227,7 +6313,15 @@ var SkillGraphFlow = ({
6227
6313
  }
6228
6314
  }
6229
6315
  ),
6230
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(DetailPanel, { node: selectedNode, detail, width: panelWidth })
6316
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
6317
+ DetailPanel,
6318
+ {
6319
+ node: selectedNode,
6320
+ detail,
6321
+ routingPath,
6322
+ width: panelWidth
6323
+ }
6324
+ )
6231
6325
  ] })
6232
6326
  ]
6233
6327
  }
@@ -6415,6 +6509,7 @@ function assertLensGroupOutput(value) {
6415
6509
  makeRootNodeId,
6416
6510
  mergeOutputs,
6417
6511
  pinUnderParent,
6512
+ routingPathTo,
6418
6513
  selectAgentInstances,
6419
6514
  selectCommentaryAt,
6420
6515
  selectCommentaryRanges,