agentfootprint-lens 0.63.0 → 0.64.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/README.md +1 -1
- package/dist/{chunk-Y5ZHXZRE.js → chunk-RHXCHNS6.js} +491 -4
- package/dist/chunk-RHXCHNS6.js.map +1 -0
- package/dist/context.cjs +508 -15
- package/dist/context.cjs.map +1 -1
- package/dist/context.d.cts +192 -3
- package/dist/context.d.ts +192 -3
- package/dist/context.js +15 -3
- package/dist/index.cjs +797 -304
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +19 -7
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/chunk-Y5ZHXZRE.js.map +0 -1
package/README.md
CHANGED
|
@@ -78,7 +78,7 @@ changes.
|
|
|
78
78
|
|---|---|
|
|
79
79
|
| `agentfootprint-lens/why` | Replay a recording as the agent's own milestones. `<WhyLens recording={...} />` takes the recording straight (`recordRun()`'s `{ snapshot, events, structure }`, or the `persistRecording` envelope), validates it at mount, and mounts the shipped `<Lens>` shell on the milestone axis — plus the axis helpers (`scrubAxisFor`, `stepForCommitIdx`, `stepForRuntimeStageId`, `resolveNavigation`) for hosts holding one cursor across views. |
|
|
80
80
|
| `agentfootprint-lens/skillgraph` | Debug how a run routed through its skills. `<SkillGraphDebugger recorder={...} />` plus its headless selectors (`selectSkillRoute`, `selectSkillBeats`, `selectSkillTopology`, `selectSkillFrameContext`, `stepForRuntimeStageId`, `resolveNavigation`). |
|
|
81
|
-
| `agentfootprint-lens/context` | What the model HAD at a stop — the served document of that epoch on top (the Served tab itself: pieces, messages, tools, verdicts, delta since the previous call) — and what it was BUILT from beneath: the record key by key, who wrote each, what moved; a long value opens in place (0.54.0). `<ContextView runner={...} />` walks the milestone axis on its own; hand it `cursor` and it follows the ONE cursor (0.53.1). Under the record, the **Findings** band (0.61.0): on an armed run (`.findings()`, agentfootprint 9.101) the model's own ledger at the stop, folded for reading — facts, conflicts as first seen (each witness with its current standing, no verdict), open, ruled out, noise, undeclared — every string off the record, absent on an unarmed run. Beside it, the **Reasoning** lens (0.62.0): `<ReasoningLens runner={...} shared={shared} />` — the same ledger read BY CALL, one card per tool call at the cursor (basis before, result, current standing after, the model's words quoted) and an answer card; absent on an unarmed run. Its `exchange` view (0.63.0) lays the same beats out as the transcript between model and tools — the call with its `_findings` JSON, the result, the ticket served instead, the findings piece, the answer — only what crossed the wire. |
|
|
81
|
+
| `agentfootprint-lens/context` | What the model HAD at a stop — the served document of that epoch on top (the Served tab itself: pieces, messages, tools, verdicts, delta since the previous call) — and what it was BUILT from beneath: the record key by key, who wrote each, what moved; a long value opens in place (0.54.0). `<ContextView runner={...} />` walks the milestone axis on its own; hand it `cursor` and it follows the ONE cursor (0.53.1). Under the record, the **Findings** band (0.61.0): on an armed run (`.findings()`, agentfootprint 9.101) the model's own ledger at the stop, folded for reading — facts, conflicts as first seen (each witness with its current standing, no verdict), open, ruled out, noise, undeclared — every string off the record, absent on an unarmed run. Beside it, the **Reasoning** lens (0.62.0): `<ReasoningLens runner={...} shared={shared} />` — the same ledger read BY CALL, one card per tool call at the cursor (basis before, result, current standing after, the model's words quoted) and an answer card; absent on an unarmed run. Its `exchange` view (0.63.0) lays the same beats out as the transcript between model and tools — the call with its `_findings` JSON, the result, the ticket served instead, the findings piece, the answer — only what crossed the wire. Beside both, the **Ontology** view (0.64.0): `<OntologyView runner={...} shared={shared} />` — the map an agent declared (`.ontology(...)`, agentfootprint 9.106.0) drawn from the run constant on the record: sources, the terms they hold and via which tool, the terms no source holds under `known, not held here`, relations in the author's words — a chart and the same data as a list; absent on an agent that declared no map. |
|
|
82
82
|
|
|
83
83
|
The axis model in three sentences: one run leaves one causal trace, and each
|
|
84
84
|
lens replays one AXIS of it — the Why reading scrubs the milestones, the Flow
|
|
@@ -903,6 +903,7 @@ function ReasoningLens(props) {
|
|
|
903
903
|
llmLatestToolCalls: keyValue(context, "llmLatestToolCalls")
|
|
904
904
|
});
|
|
905
905
|
}, [context, rows]);
|
|
906
|
+
const mover = props.cursor === void 0 && shared !== void 0 && cursor.total > 0 && cursor.at.step >= 0;
|
|
906
907
|
if (exchange === void 0) return null;
|
|
907
908
|
const fold = exchange.reasoning;
|
|
908
909
|
return /* @__PURE__ */ jsxs3(
|
|
@@ -924,6 +925,16 @@ function ReasoningLens(props) {
|
|
|
924
925
|
] }),
|
|
925
926
|
/* @__PURE__ */ jsx3(ViewToggle, { view, onView: setView })
|
|
926
927
|
] }),
|
|
928
|
+
mover && /* @__PURE__ */ jsx3("div", { "data-testid": "reasoning-transport", children: /* @__PURE__ */ jsx3(
|
|
929
|
+
TimeTravel,
|
|
930
|
+
{
|
|
931
|
+
total: cursor.total,
|
|
932
|
+
focusSeq: Math.max(0, cursor.at.step),
|
|
933
|
+
onFocusChange: (n) => cursor.moveTo(n),
|
|
934
|
+
isLive: false,
|
|
935
|
+
compact: true
|
|
936
|
+
}
|
|
937
|
+
) }),
|
|
927
938
|
view === "cards" && /* @__PURE__ */ jsxs3("div", { style: column, "data-testid": "reasoning-cards", children: [
|
|
928
939
|
fold.cards.map((card) => /* @__PURE__ */ jsx3(Card, { card }, card.toolCallId)),
|
|
929
940
|
fold.answer !== void 0 && /* @__PURE__ */ jsx3(Answer, { answer: fold.answer })
|
|
@@ -1280,9 +1291,9 @@ function Chip({
|
|
|
1280
1291
|
children,
|
|
1281
1292
|
color,
|
|
1282
1293
|
testId,
|
|
1283
|
-
title:
|
|
1294
|
+
title: title4
|
|
1284
1295
|
}) {
|
|
1285
|
-
return /* @__PURE__ */ jsx3("span", { style: { ...chip, borderColor: color, color }, "data-testid": testId, ...
|
|
1296
|
+
return /* @__PURE__ */ jsx3("span", { style: { ...chip, borderColor: color, color }, "data-testid": testId, ...title4 !== void 0 ? { title: title4 } : {}, children });
|
|
1286
1297
|
}
|
|
1287
1298
|
var panel2 = {
|
|
1288
1299
|
display: "flex",
|
|
@@ -1339,6 +1350,476 @@ var summaryStyle = { cursor: "pointer", color: T.textMuted };
|
|
|
1339
1350
|
var detailsBody = { display: "flex", flexDirection: "column", gap: 2, paddingTop: 4 };
|
|
1340
1351
|
var list3 = { margin: "2px 0 0", paddingLeft: 18 };
|
|
1341
1352
|
|
|
1353
|
+
// src/react/components/OntologyView.tsx
|
|
1354
|
+
import { useMemo as useMemo4 } from "react";
|
|
1355
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1356
|
+
var LABELS4 = Object.freeze({
|
|
1357
|
+
view: "Ontology",
|
|
1358
|
+
version: "version",
|
|
1359
|
+
hash: "hash",
|
|
1360
|
+
nodes: "nodes",
|
|
1361
|
+
sources: "sources",
|
|
1362
|
+
edges: "edges",
|
|
1363
|
+
/** The declaration's own heading for a term with no source (the served piece's line). */
|
|
1364
|
+
unheld: "known, not held here",
|
|
1365
|
+
heldBy: "held by",
|
|
1366
|
+
relations: "relations",
|
|
1367
|
+
via: "via",
|
|
1368
|
+
unit: "unit",
|
|
1369
|
+
aliases: "aliases",
|
|
1370
|
+
coverage: "coverage",
|
|
1371
|
+
configured: "configured",
|
|
1372
|
+
chart: "chart",
|
|
1373
|
+
list: "list"
|
|
1374
|
+
});
|
|
1375
|
+
var isRecord3 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
1376
|
+
var isStringArray = (v) => Array.isArray(v) && v.every((s) => typeof s === "string");
|
|
1377
|
+
function ontologyRecordOf(value) {
|
|
1378
|
+
if (!isRecord3(value)) return void 0;
|
|
1379
|
+
const { id, version, hash, spec } = value;
|
|
1380
|
+
if (typeof id !== "string" || typeof version !== "string" || typeof hash !== "string" || !isRecord3(spec)) return void 0;
|
|
1381
|
+
if (!isRecord3(spec.nodes) || !isRecord3(spec.sources)) return void 0;
|
|
1382
|
+
return {
|
|
1383
|
+
id,
|
|
1384
|
+
version,
|
|
1385
|
+
hash,
|
|
1386
|
+
nodes: spec.nodes,
|
|
1387
|
+
sources: spec.sources,
|
|
1388
|
+
edges: Array.isArray(spec.edges) ? spec.edges : []
|
|
1389
|
+
};
|
|
1390
|
+
}
|
|
1391
|
+
function heldOf(node, value, sources) {
|
|
1392
|
+
if (!isRecord3(value) || typeof value.source !== "string" || !(value.source in sources)) return void 0;
|
|
1393
|
+
return {
|
|
1394
|
+
node,
|
|
1395
|
+
source: value.source,
|
|
1396
|
+
via: isStringArray(value.via) ? value.via : [],
|
|
1397
|
+
...typeof value.coverage === "string" ? { coverage: value.coverage } : {}
|
|
1398
|
+
};
|
|
1399
|
+
}
|
|
1400
|
+
function termOf(id, value, sources) {
|
|
1401
|
+
if (!isRecord3(value) || typeof value.meaning !== "string") return void 0;
|
|
1402
|
+
const held = Array.isArray(value.sources) ? value.sources.map((s) => heldOf(id, s, sources)).filter((h) => h !== void 0) : [];
|
|
1403
|
+
return {
|
|
1404
|
+
id,
|
|
1405
|
+
meaning: value.meaning,
|
|
1406
|
+
...typeof value.unit === "string" ? { unit: value.unit } : {},
|
|
1407
|
+
aliases: isStringArray(value.aliases) ? value.aliases : [],
|
|
1408
|
+
held
|
|
1409
|
+
};
|
|
1410
|
+
}
|
|
1411
|
+
function sourceOf(id, value) {
|
|
1412
|
+
if (!isRecord3(value) || typeof value.meaning !== "string") return void 0;
|
|
1413
|
+
return {
|
|
1414
|
+
id,
|
|
1415
|
+
meaning: value.meaning,
|
|
1416
|
+
...typeof value.coverage === "string" ? { coverage: value.coverage } : {},
|
|
1417
|
+
...typeof value.configured === "boolean" ? { configured: value.configured } : {}
|
|
1418
|
+
};
|
|
1419
|
+
}
|
|
1420
|
+
function relationOf(value) {
|
|
1421
|
+
if (!isRecord3(value) || typeof value.from !== "string" || typeof value.to !== "string" || typeof value.relation !== "string") return void 0;
|
|
1422
|
+
return {
|
|
1423
|
+
from: value.from,
|
|
1424
|
+
to: value.to,
|
|
1425
|
+
relation: value.relation,
|
|
1426
|
+
...typeof value.meaning === "string" ? { meaning: value.meaning } : {}
|
|
1427
|
+
};
|
|
1428
|
+
}
|
|
1429
|
+
var byId = (a, b) => a.id < b.id ? -1 : a.id > b.id ? 1 : 0;
|
|
1430
|
+
function foldOntology(record) {
|
|
1431
|
+
const terms = Object.entries(record.nodes).map(([id, v]) => termOf(id, v, record.sources)).filter((t) => t !== void 0).sort(byId);
|
|
1432
|
+
const sources = Object.entries(record.sources).map(([id, v]) => sourceOf(id, v)).filter((s) => s !== void 0).sort(byId);
|
|
1433
|
+
const relations = record.edges.map(relationOf).filter((r) => r !== void 0);
|
|
1434
|
+
return Object.freeze({
|
|
1435
|
+
id: record.id,
|
|
1436
|
+
version: record.version,
|
|
1437
|
+
hash: record.hash,
|
|
1438
|
+
terms: Object.freeze(terms),
|
|
1439
|
+
sources: Object.freeze(sources),
|
|
1440
|
+
held: Object.freeze(terms.flatMap((t) => t.held)),
|
|
1441
|
+
relations: Object.freeze(relations),
|
|
1442
|
+
unheld: Object.freeze(terms.filter((t) => t.held.length === 0).map((t) => t.id))
|
|
1443
|
+
});
|
|
1444
|
+
}
|
|
1445
|
+
var GEOMETRY = Object.freeze({
|
|
1446
|
+
nodeWidth: 168,
|
|
1447
|
+
nodeHeight: 44,
|
|
1448
|
+
rowGap: 18,
|
|
1449
|
+
columnGap: 96,
|
|
1450
|
+
/** The lane each relation elbow takes to the right of the term columns, per edge. */
|
|
1451
|
+
laneGap: 14,
|
|
1452
|
+
padding: 12,
|
|
1453
|
+
labelOffset: 4
|
|
1454
|
+
});
|
|
1455
|
+
var columnX = (column2) => GEOMETRY.padding + column2 * (GEOMETRY.nodeWidth + GEOMETRY.columnGap);
|
|
1456
|
+
var rowY = (row2) => GEOMETRY.padding + GEOMETRY.nodeHeight + row2 * (GEOMETRY.nodeHeight + GEOMETRY.rowGap);
|
|
1457
|
+
var centreY = (n) => n.y + GEOMETRY.nodeHeight / 2;
|
|
1458
|
+
function layoutOntology(fold) {
|
|
1459
|
+
const heldTerms = fold.terms.filter((t) => t.held.length > 0);
|
|
1460
|
+
const unheldTerms = fold.terms.filter((t) => t.held.length === 0);
|
|
1461
|
+
const nodes = [
|
|
1462
|
+
...fold.sources.map((s, i) => ({ id: s.id, kind: "source", column: 0, x: columnX(0), y: rowY(i) })),
|
|
1463
|
+
...heldTerms.map((t, i) => ({ id: t.id, kind: "term", column: 1, x: columnX(1), y: rowY(i) })),
|
|
1464
|
+
...unheldTerms.map((t, i) => ({ id: t.id, kind: "term", column: 2, x: columnX(2), y: rowY(i) }))
|
|
1465
|
+
];
|
|
1466
|
+
const at = new Map(nodes.map((n) => [`${n.kind}:${n.id}`, n]));
|
|
1467
|
+
const columns = unheldTerms.length > 0 ? 3 : heldTerms.length > 0 ? 2 : 1;
|
|
1468
|
+
const rightEdge = columnX(columns - 1) + GEOMETRY.nodeWidth;
|
|
1469
|
+
const edges = [];
|
|
1470
|
+
for (const h of fold.held) {
|
|
1471
|
+
const from = at.get(`source:${h.source}`);
|
|
1472
|
+
const to = at.get(`term:${h.node}`);
|
|
1473
|
+
if (from === void 0 || to === void 0) continue;
|
|
1474
|
+
const x1 = from.x + GEOMETRY.nodeWidth;
|
|
1475
|
+
const y1 = centreY(from);
|
|
1476
|
+
const x2 = to.x;
|
|
1477
|
+
const y2 = centreY(to);
|
|
1478
|
+
edges.push({
|
|
1479
|
+
kind: "held",
|
|
1480
|
+
from: h.source,
|
|
1481
|
+
to: h.node,
|
|
1482
|
+
path: `M ${x1} ${y1} L ${x2} ${y2}`,
|
|
1483
|
+
labelX: (x1 + x2) / 2,
|
|
1484
|
+
labelY: (y1 + y2) / 2 - GEOMETRY.labelOffset,
|
|
1485
|
+
label: h.via.join(", ")
|
|
1486
|
+
});
|
|
1487
|
+
}
|
|
1488
|
+
fold.relations.forEach((r, i) => {
|
|
1489
|
+
const from = at.get(`term:${r.from}`);
|
|
1490
|
+
const to = at.get(`term:${r.to}`);
|
|
1491
|
+
if (from === void 0 || to === void 0) return;
|
|
1492
|
+
const lane = rightEdge + GEOMETRY.laneGap * (i + 1);
|
|
1493
|
+
const x1 = from.x + GEOMETRY.nodeWidth;
|
|
1494
|
+
const y1 = centreY(from);
|
|
1495
|
+
const x2 = to.x + GEOMETRY.nodeWidth;
|
|
1496
|
+
const y2 = centreY(to);
|
|
1497
|
+
edges.push({
|
|
1498
|
+
kind: "relation",
|
|
1499
|
+
from: r.from,
|
|
1500
|
+
to: r.to,
|
|
1501
|
+
path: `M ${x1} ${y1} H ${lane} V ${y2} H ${x2}`,
|
|
1502
|
+
labelX: lane + GEOMETRY.labelOffset,
|
|
1503
|
+
labelY: (y1 + y2) / 2,
|
|
1504
|
+
label: r.relation,
|
|
1505
|
+
relation: r.relation
|
|
1506
|
+
});
|
|
1507
|
+
});
|
|
1508
|
+
const rows = Math.max(fold.sources.length, heldTerms.length, unheldTerms.length, 1);
|
|
1509
|
+
const lanes = fold.relations.length;
|
|
1510
|
+
return Object.freeze({
|
|
1511
|
+
width: rightEdge + GEOMETRY.laneGap * (lanes + 1) + GEOMETRY.padding + 120,
|
|
1512
|
+
height: rowY(rows) + GEOMETRY.padding,
|
|
1513
|
+
nodes: Object.freeze(nodes),
|
|
1514
|
+
edges: Object.freeze(edges),
|
|
1515
|
+
...unheldTerms.length > 0 ? { unheldX: columnX(2) } : {}
|
|
1516
|
+
});
|
|
1517
|
+
}
|
|
1518
|
+
function positionsOf3(snapshot) {
|
|
1519
|
+
return tagAxisPositions(snapshot, MILESTONE_AXIS, []) ?? [];
|
|
1520
|
+
}
|
|
1521
|
+
var noMove2 = () => void 0;
|
|
1522
|
+
function keyValue2(context, path) {
|
|
1523
|
+
return context.keys.find((k) => k.path === path)?.value;
|
|
1524
|
+
}
|
|
1525
|
+
function OntologyView(props) {
|
|
1526
|
+
const { runner, events, shared, recorder } = props;
|
|
1527
|
+
const fresh = snapshotOfRunner(runner);
|
|
1528
|
+
const logKey = snapshotLogKey(fresh);
|
|
1529
|
+
const snapshot = useMemo4(() => fresh, [runner, logKey]);
|
|
1530
|
+
const ownPositions = useMemo4(
|
|
1531
|
+
() => props.cursor !== void 0 ? void 0 : recorder !== void 0 ? scrubAxisFor(recorder, "group") : positionsOf3(snapshot),
|
|
1532
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- the recorder's axis moves with the log key
|
|
1533
|
+
[snapshot, props.cursor, recorder, logKey]
|
|
1534
|
+
);
|
|
1535
|
+
const positions = ownPositions ?? [];
|
|
1536
|
+
const cursor = props.cursor ?? (shared !== void 0 ? shared.over(positions) : lensCursorFrom(positions, Math.max(0, positions.length - 1), noMove2));
|
|
1537
|
+
const context = useMemo4(
|
|
1538
|
+
() => contextAt(snapshot, { runtimeStageId: cursor.at.runtimeStageId, commitIdx: cursor.at.commitIdx }, { events }),
|
|
1539
|
+
[snapshot, cursor.at.runtimeStageId, cursor.at.commitIdx, events]
|
|
1540
|
+
);
|
|
1541
|
+
const record = ontologyRecordOf(keyValue2(context, "ontology"));
|
|
1542
|
+
const fold = useMemo4(() => record === void 0 ? void 0 : foldOntology(record), [record]);
|
|
1543
|
+
const layout = useMemo4(() => fold === void 0 ? void 0 : layoutOntology(fold), [fold]);
|
|
1544
|
+
const mover = props.cursor === void 0 && shared !== void 0 && cursor.total > 0 && cursor.at.step >= 0;
|
|
1545
|
+
if (fold === void 0 || layout === void 0) return null;
|
|
1546
|
+
return /* @__PURE__ */ jsxs4(
|
|
1547
|
+
"div",
|
|
1548
|
+
{
|
|
1549
|
+
style: panel3,
|
|
1550
|
+
"data-testid": "ontology-view",
|
|
1551
|
+
"data-id": fold.id,
|
|
1552
|
+
"data-version": fold.version,
|
|
1553
|
+
"data-hash": fold.hash,
|
|
1554
|
+
"data-step": cursor.at.step,
|
|
1555
|
+
"data-commit": cursor.at.commitIdx,
|
|
1556
|
+
children: [
|
|
1557
|
+
/* @__PURE__ */ jsx4(Header, { fold }),
|
|
1558
|
+
mover && /* @__PURE__ */ jsx4("div", { "data-testid": "ontology-transport", children: /* @__PURE__ */ jsx4(
|
|
1559
|
+
TimeTravel,
|
|
1560
|
+
{
|
|
1561
|
+
total: cursor.total,
|
|
1562
|
+
focusSeq: Math.max(0, cursor.at.step),
|
|
1563
|
+
onFocusChange: (n) => cursor.moveTo(n),
|
|
1564
|
+
isLive: false,
|
|
1565
|
+
compact: true
|
|
1566
|
+
}
|
|
1567
|
+
) }),
|
|
1568
|
+
/* @__PURE__ */ jsxs4("div", { style: body, children: [
|
|
1569
|
+
/* @__PURE__ */ jsx4(Chart, { fold, layout }),
|
|
1570
|
+
/* @__PURE__ */ jsx4(List, { fold })
|
|
1571
|
+
] })
|
|
1572
|
+
]
|
|
1573
|
+
}
|
|
1574
|
+
);
|
|
1575
|
+
}
|
|
1576
|
+
var SHORT_HASH = 12;
|
|
1577
|
+
function Header({ fold }) {
|
|
1578
|
+
return /* @__PURE__ */ jsxs4("div", { style: header3, "data-testid": "ontology-header", children: [
|
|
1579
|
+
/* @__PURE__ */ jsx4("span", { style: title3, children: LABELS4.view }),
|
|
1580
|
+
/* @__PURE__ */ jsx4("code", { style: mono4, "data-testid": "ontology-id", children: fold.id }),
|
|
1581
|
+
/* @__PURE__ */ jsxs4("span", { style: dim4, children: [
|
|
1582
|
+
LABELS4.version,
|
|
1583
|
+
" ",
|
|
1584
|
+
/* @__PURE__ */ jsx4("code", { style: mono4, children: fold.version })
|
|
1585
|
+
] }),
|
|
1586
|
+
/* @__PURE__ */ jsxs4("span", { style: dim4, children: [
|
|
1587
|
+
LABELS4.hash,
|
|
1588
|
+
" ",
|
|
1589
|
+
/* @__PURE__ */ jsx4("code", { style: mono4, title: fold.hash, "data-testid": "ontology-hash", children: fold.hash.length > SHORT_HASH ? `${fold.hash.slice(0, SHORT_HASH)}\u2026` : fold.hash })
|
|
1590
|
+
] }),
|
|
1591
|
+
/* @__PURE__ */ jsxs4("span", { style: dim4, "data-testid": "ontology-counts", children: [
|
|
1592
|
+
fold.terms.length,
|
|
1593
|
+
" ",
|
|
1594
|
+
LABELS4.nodes,
|
|
1595
|
+
" \xB7 ",
|
|
1596
|
+
fold.sources.length,
|
|
1597
|
+
" ",
|
|
1598
|
+
LABELS4.sources,
|
|
1599
|
+
" \xB7 ",
|
|
1600
|
+
fold.held.length + fold.relations.length,
|
|
1601
|
+
" ",
|
|
1602
|
+
LABELS4.edges
|
|
1603
|
+
] })
|
|
1604
|
+
] });
|
|
1605
|
+
}
|
|
1606
|
+
var CLIP = 28;
|
|
1607
|
+
var ARROW = [
|
|
1608
|
+
[0, 0],
|
|
1609
|
+
[8, 4],
|
|
1610
|
+
[0, 8]
|
|
1611
|
+
];
|
|
1612
|
+
function arrowPoints() {
|
|
1613
|
+
return ARROW.map((p) => p.join(",")).join(" ");
|
|
1614
|
+
}
|
|
1615
|
+
function clip(text, max = CLIP) {
|
|
1616
|
+
return text.length > max ? `${text.slice(0, max - 1)}\u2026` : text;
|
|
1617
|
+
}
|
|
1618
|
+
function Chart({ fold, layout }) {
|
|
1619
|
+
const terms = new Map(fold.terms.map((t) => [t.id, t]));
|
|
1620
|
+
const sources = new Map(fold.sources.map((s) => [s.id, s]));
|
|
1621
|
+
const arrow = `ontology-arrow-${fold.hash.slice(0, SHORT_HASH)}`;
|
|
1622
|
+
const { nodeWidth, nodeHeight } = GEOMETRY;
|
|
1623
|
+
return /* @__PURE__ */ jsxs4(
|
|
1624
|
+
"svg",
|
|
1625
|
+
{
|
|
1626
|
+
role: "img",
|
|
1627
|
+
"aria-label": LABELS4.chart,
|
|
1628
|
+
width: layout.width,
|
|
1629
|
+
height: layout.height,
|
|
1630
|
+
viewBox: `0 0 ${layout.width} ${layout.height}`,
|
|
1631
|
+
style: chartStyle,
|
|
1632
|
+
"data-testid": "ontology-chart",
|
|
1633
|
+
children: [
|
|
1634
|
+
/* @__PURE__ */ jsx4("defs", { children: /* @__PURE__ */ jsx4("marker", { id: arrow, viewBox: "0 0 8 8", refX: "7", refY: "4", markerWidth: "7", markerHeight: "7", orient: "auto", children: /* @__PURE__ */ jsx4("polygon", { points: arrowPoints(), fill: T.textMuted }) }) }),
|
|
1635
|
+
/* @__PURE__ */ jsx4("text", { x: columnX(0), y: GEOMETRY.padding + 14, style: headingText, fill: T.textMuted, children: LABELS4.sources }),
|
|
1636
|
+
layout.nodes.some((n) => n.column === 1) && /* @__PURE__ */ jsx4("text", { x: columnX(1), y: GEOMETRY.padding + 14, style: headingText, fill: T.textMuted, children: LABELS4.nodes }),
|
|
1637
|
+
layout.unheldX !== void 0 && /* @__PURE__ */ jsx4("text", { x: layout.unheldX, y: GEOMETRY.padding + 14, style: headingText, fill: T.textMuted, "data-testid": "ontology-chart-unheld", children: LABELS4.unheld }),
|
|
1638
|
+
layout.edges.map((e, i) => /* @__PURE__ */ jsxs4(
|
|
1639
|
+
"g",
|
|
1640
|
+
{
|
|
1641
|
+
"data-testid": "ontology-chart-edge",
|
|
1642
|
+
"data-kind": e.kind,
|
|
1643
|
+
"data-from": e.from,
|
|
1644
|
+
"data-to": e.to,
|
|
1645
|
+
...e.relation !== void 0 ? { "data-relation": e.relation } : {},
|
|
1646
|
+
children: [
|
|
1647
|
+
/* @__PURE__ */ jsx4(
|
|
1648
|
+
"path",
|
|
1649
|
+
{
|
|
1650
|
+
d: e.path,
|
|
1651
|
+
fill: "none",
|
|
1652
|
+
stroke: e.kind === "held" ? T.srcTool : T.primary,
|
|
1653
|
+
strokeWidth: 1.25,
|
|
1654
|
+
strokeDasharray: e.kind === "held" ? void 0 : "4 3",
|
|
1655
|
+
markerEnd: `url(#${arrow})`
|
|
1656
|
+
}
|
|
1657
|
+
),
|
|
1658
|
+
e.label.length > 0 && /* @__PURE__ */ jsx4("text", { x: e.labelX, y: e.labelY, style: edgeText, fill: e.kind === "held" ? T.srcTool : T.primary, textAnchor: e.kind === "held" ? "middle" : "start", children: e.label })
|
|
1659
|
+
]
|
|
1660
|
+
},
|
|
1661
|
+
`${e.kind}:${e.from}:${e.to}:${i}`
|
|
1662
|
+
)),
|
|
1663
|
+
layout.nodes.map((n) => {
|
|
1664
|
+
const term = terms.get(n.id);
|
|
1665
|
+
const source = sources.get(n.id);
|
|
1666
|
+
const shape = n.kind === "source" ? source : term;
|
|
1667
|
+
const meaning = shape?.meaning ?? "";
|
|
1668
|
+
const held = n.kind === "term" && term !== void 0 && term.held.length > 0;
|
|
1669
|
+
return /* @__PURE__ */ jsxs4(
|
|
1670
|
+
"g",
|
|
1671
|
+
{
|
|
1672
|
+
transform: `translate(${n.x} ${n.y})`,
|
|
1673
|
+
"data-testid": "ontology-chart-node",
|
|
1674
|
+
"data-kind": n.kind,
|
|
1675
|
+
"data-node": n.id,
|
|
1676
|
+
...n.kind === "term" ? { "data-held": String(held) } : {},
|
|
1677
|
+
children: [
|
|
1678
|
+
/* @__PURE__ */ jsx4("title", { children: n.kind === "source" && source?.coverage !== void 0 ? `${meaning} \xB7 ${source.coverage}` : meaning }),
|
|
1679
|
+
/* @__PURE__ */ jsx4(
|
|
1680
|
+
"rect",
|
|
1681
|
+
{
|
|
1682
|
+
width: nodeWidth,
|
|
1683
|
+
height: nodeHeight,
|
|
1684
|
+
rx: n.kind === "source" ? 2 : 8,
|
|
1685
|
+
fill: T.bgSecondary,
|
|
1686
|
+
stroke: n.kind === "source" ? T.srcTool : held ? T.primary : T.textMuted,
|
|
1687
|
+
strokeWidth: n.kind === "source" ? 2 : 1.25,
|
|
1688
|
+
strokeDasharray: n.kind === "term" && !held ? "4 3" : void 0
|
|
1689
|
+
}
|
|
1690
|
+
),
|
|
1691
|
+
/* @__PURE__ */ jsx4("text", { x: 8, y: 17, style: nodeIdText, fill: T.textPrimary, children: clip(n.id, 20) }),
|
|
1692
|
+
n.kind === "term" && term?.unit !== void 0 && /* @__PURE__ */ jsx4("text", { x: nodeWidth - 8, y: 17, style: chipText, fill: T.warning, textAnchor: "end", children: clip(term.unit, 12) }),
|
|
1693
|
+
n.kind === "source" && source?.configured !== void 0 && /* @__PURE__ */ jsx4("text", { x: nodeWidth - 8, y: 17, style: chipText, fill: source.configured ? T.success : T.warning, textAnchor: "end", children: LABELS4.configured }),
|
|
1694
|
+
/* @__PURE__ */ jsx4("text", { x: 8, y: 34, style: nodeMeaningText, fill: T.textSecondary, children: clip(n.kind === "source" && source?.coverage !== void 0 ? `${meaning} \xB7 ${source.coverage}` : meaning) })
|
|
1695
|
+
]
|
|
1696
|
+
},
|
|
1697
|
+
`${n.kind}:${n.id}`
|
|
1698
|
+
);
|
|
1699
|
+
})
|
|
1700
|
+
]
|
|
1701
|
+
}
|
|
1702
|
+
);
|
|
1703
|
+
}
|
|
1704
|
+
function List({ fold }) {
|
|
1705
|
+
return /* @__PURE__ */ jsxs4("div", { style: listStyle, "data-testid": "ontology-list", "aria-label": LABELS4.list, children: [
|
|
1706
|
+
/* @__PURE__ */ jsx4(Group2, { label: LABELS4.nodes, count: fold.terms.length, testId: "ontology-nodes", children: fold.terms.map((t) => /* @__PURE__ */ jsxs4("li", { "data-testid": "ontology-node", "data-node": t.id, "data-held": String(t.held.length > 0), children: [
|
|
1707
|
+
/* @__PURE__ */ jsx4("code", { style: strong2, children: t.id }),
|
|
1708
|
+
" ",
|
|
1709
|
+
/* @__PURE__ */ jsx4("span", { children: t.meaning }),
|
|
1710
|
+
t.unit !== void 0 && /* @__PURE__ */ jsxs4(Chip2, { color: T.warning, testId: "ontology-unit", children: [
|
|
1711
|
+
LABELS4.unit,
|
|
1712
|
+
" ",
|
|
1713
|
+
t.unit
|
|
1714
|
+
] }),
|
|
1715
|
+
t.aliases.length > 0 && /* @__PURE__ */ jsxs4("span", { style: dim4, "data-testid": "ontology-aliases", children: [
|
|
1716
|
+
" ",
|
|
1717
|
+
LABELS4.aliases,
|
|
1718
|
+
" ",
|
|
1719
|
+
t.aliases.join(", ")
|
|
1720
|
+
] })
|
|
1721
|
+
] }, t.id)) }),
|
|
1722
|
+
/* @__PURE__ */ jsx4(Group2, { label: LABELS4.sources, count: fold.sources.length, testId: "ontology-sources", children: fold.sources.map((s) => /* @__PURE__ */ jsxs4("li", { "data-testid": "ontology-source", "data-source": s.id, ...s.configured !== void 0 ? { "data-configured": String(s.configured) } : {}, children: [
|
|
1723
|
+
/* @__PURE__ */ jsx4("code", { style: strong2, children: s.id }),
|
|
1724
|
+
" ",
|
|
1725
|
+
/* @__PURE__ */ jsx4("span", { children: s.meaning }),
|
|
1726
|
+
s.configured !== void 0 && /* @__PURE__ */ jsxs4(Chip2, { color: s.configured ? T.success : T.warning, testId: "ontology-configured", children: [
|
|
1727
|
+
LABELS4.configured,
|
|
1728
|
+
" ",
|
|
1729
|
+
String(s.configured)
|
|
1730
|
+
] }),
|
|
1731
|
+
s.coverage !== void 0 && /* @__PURE__ */ jsxs4("span", { style: dim4, "data-testid": "ontology-source-coverage", children: [
|
|
1732
|
+
" ",
|
|
1733
|
+
LABELS4.coverage,
|
|
1734
|
+
" ",
|
|
1735
|
+
/* @__PURE__ */ jsx4("q", { children: s.coverage })
|
|
1736
|
+
] })
|
|
1737
|
+
] }, s.id)) }),
|
|
1738
|
+
fold.held.length > 0 && /* @__PURE__ */ jsx4(Group2, { label: LABELS4.heldBy, count: fold.held.length, testId: "ontology-held-by", children: fold.held.map((h, i) => /* @__PURE__ */ jsxs4("li", { "data-testid": "ontology-held", "data-node": h.node, "data-source": h.source, children: [
|
|
1739
|
+
/* @__PURE__ */ jsx4("code", { style: strong2, children: h.node }),
|
|
1740
|
+
" ",
|
|
1741
|
+
/* @__PURE__ */ jsx4("span", { style: dim4, children: "\u2190" }),
|
|
1742
|
+
" ",
|
|
1743
|
+
/* @__PURE__ */ jsx4("code", { style: strong2, children: h.source }),
|
|
1744
|
+
h.via.length > 0 && /* @__PURE__ */ jsxs4("span", { style: dim4, "data-testid": "ontology-via", children: [
|
|
1745
|
+
" ",
|
|
1746
|
+
LABELS4.via,
|
|
1747
|
+
" ",
|
|
1748
|
+
/* @__PURE__ */ jsx4("code", { style: mono4, children: h.via.join(", ") })
|
|
1749
|
+
] }),
|
|
1750
|
+
h.coverage !== void 0 && /* @__PURE__ */ jsxs4("span", { style: dim4, "data-testid": "ontology-held-coverage", children: [
|
|
1751
|
+
" ",
|
|
1752
|
+
LABELS4.coverage,
|
|
1753
|
+
" ",
|
|
1754
|
+
/* @__PURE__ */ jsx4("q", { children: h.coverage })
|
|
1755
|
+
] })
|
|
1756
|
+
] }, `${h.node}:${h.source}:${i}`)) }),
|
|
1757
|
+
fold.relations.length > 0 && /* @__PURE__ */ jsx4(Group2, { label: LABELS4.relations, count: fold.relations.length, testId: "ontology-relations", children: fold.relations.map((r, i) => /* @__PURE__ */ jsxs4("li", { "data-testid": "ontology-edge", "data-from": r.from, "data-to": r.to, "data-relation": r.relation, children: [
|
|
1758
|
+
/* @__PURE__ */ jsx4("code", { style: strong2, children: r.from }),
|
|
1759
|
+
" ",
|
|
1760
|
+
/* @__PURE__ */ jsx4("code", { style: relationWord, children: r.relation }),
|
|
1761
|
+
" ",
|
|
1762
|
+
/* @__PURE__ */ jsx4("code", { style: strong2, children: r.to }),
|
|
1763
|
+
r.meaning !== void 0 && /* @__PURE__ */ jsxs4("span", { style: dim4, "data-testid": "ontology-edge-meaning", children: [
|
|
1764
|
+
" ",
|
|
1765
|
+
/* @__PURE__ */ jsx4("q", { children: r.meaning })
|
|
1766
|
+
] })
|
|
1767
|
+
] }, `${r.from}:${r.relation}:${r.to}:${i}`)) }),
|
|
1768
|
+
fold.unheld.length > 0 && /* @__PURE__ */ jsx4(Group2, { label: LABELS4.unheld, count: fold.unheld.length, testId: "ontology-unheld-group", children: fold.unheld.map((id) => /* @__PURE__ */ jsx4("li", { "data-testid": "ontology-unheld", "data-node": id, children: /* @__PURE__ */ jsx4("code", { style: strong2, children: id }) }, id)) })
|
|
1769
|
+
] });
|
|
1770
|
+
}
|
|
1771
|
+
function Group2({
|
|
1772
|
+
label,
|
|
1773
|
+
count,
|
|
1774
|
+
testId,
|
|
1775
|
+
children
|
|
1776
|
+
}) {
|
|
1777
|
+
return /* @__PURE__ */ jsxs4("div", { "data-testid": testId, "data-count": count, children: [
|
|
1778
|
+
/* @__PURE__ */ jsxs4("div", { style: groupHeading, children: [
|
|
1779
|
+
label,
|
|
1780
|
+
" \xB7 ",
|
|
1781
|
+
count
|
|
1782
|
+
] }),
|
|
1783
|
+
/* @__PURE__ */ jsx4("ul", { style: list4, children })
|
|
1784
|
+
] });
|
|
1785
|
+
}
|
|
1786
|
+
function Chip2({ children, color, testId }) {
|
|
1787
|
+
return /* @__PURE__ */ jsx4("span", { style: { ...chip2, borderColor: color, color }, "data-testid": testId, children });
|
|
1788
|
+
}
|
|
1789
|
+
var panel3 = {
|
|
1790
|
+
display: "flex",
|
|
1791
|
+
flexDirection: "column",
|
|
1792
|
+
gap: 8,
|
|
1793
|
+
padding: 10,
|
|
1794
|
+
fontSize: 13,
|
|
1795
|
+
fontFamily: T.fontSans,
|
|
1796
|
+
color: T.textPrimary
|
|
1797
|
+
};
|
|
1798
|
+
var header3 = { display: "flex", alignItems: "center", flexWrap: "wrap", gap: 10 };
|
|
1799
|
+
var title3 = { fontWeight: 600 };
|
|
1800
|
+
var strong2 = { fontWeight: 600, fontFamily: T.fontMono, fontSize: 12 };
|
|
1801
|
+
var dim4 = { color: T.textMuted };
|
|
1802
|
+
var mono4 = { fontFamily: T.fontMono, fontSize: 12, wordBreak: "break-word" };
|
|
1803
|
+
var relationWord = { fontFamily: T.fontMono, fontSize: 12, color: T.primary };
|
|
1804
|
+
var body = { display: "flex", flexWrap: "wrap", alignItems: "flex-start", gap: 16 };
|
|
1805
|
+
var chartStyle = { maxWidth: "100%", height: "auto", fontFamily: T.fontSans, background: T.bgPrimary, borderRadius: 6 };
|
|
1806
|
+
var headingText = { fontSize: 11, fontWeight: 600 };
|
|
1807
|
+
var edgeText = { fontSize: 10, fontFamily: T.fontMono };
|
|
1808
|
+
var nodeIdText = { fontSize: 12, fontWeight: 600, fontFamily: T.fontMono };
|
|
1809
|
+
var nodeMeaningText = { fontSize: 10 };
|
|
1810
|
+
var chipText = { fontSize: 9, fontFamily: T.fontMono };
|
|
1811
|
+
var listStyle = { display: "flex", flexDirection: "column", gap: 8, minWidth: 240, flex: 1 };
|
|
1812
|
+
var groupHeading = { fontWeight: 600, color: T.textSecondary, fontSize: 12 };
|
|
1813
|
+
var list4 = { margin: "2px 0 0", paddingLeft: 18, display: "flex", flexDirection: "column", gap: 2 };
|
|
1814
|
+
var chip2 = {
|
|
1815
|
+
marginLeft: 6,
|
|
1816
|
+
padding: "0 6px",
|
|
1817
|
+
borderRadius: 8,
|
|
1818
|
+
fontSize: 11,
|
|
1819
|
+
border: "1px solid",
|
|
1820
|
+
whiteSpace: "nowrap"
|
|
1821
|
+
};
|
|
1822
|
+
|
|
1342
1823
|
export {
|
|
1343
1824
|
LABELS2 as LABELS,
|
|
1344
1825
|
MILESTONE_AXIS,
|
|
@@ -1346,6 +1827,12 @@ export {
|
|
|
1346
1827
|
LABELS3 as LABELS2,
|
|
1347
1828
|
foldReasoning,
|
|
1348
1829
|
foldExchange,
|
|
1349
|
-
ReasoningLens
|
|
1830
|
+
ReasoningLens,
|
|
1831
|
+
LABELS4 as LABELS3,
|
|
1832
|
+
ontologyRecordOf,
|
|
1833
|
+
foldOntology,
|
|
1834
|
+
GEOMETRY,
|
|
1835
|
+
layoutOntology,
|
|
1836
|
+
OntologyView
|
|
1350
1837
|
};
|
|
1351
|
-
//# sourceMappingURL=chunk-
|
|
1838
|
+
//# sourceMappingURL=chunk-RHXCHNS6.js.map
|