@saasontools/strauss-kb 0.1.5 → 0.1.7
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 +50 -3
- package/dist/{chunk-KQMGKSPZ.js → chunk-GKCG4P3L.js} +10 -3
- package/dist/chunk-GKCG4P3L.js.map +1 -0
- package/dist/{chunk-FZIMFPGR.js → chunk-GKUQOJEK.js} +436 -76
- package/dist/chunk-GKUQOJEK.js.map +1 -0
- package/dist/{chunk-VOJ6D6OX.js → chunk-LCQKARFK.js} +5 -4
- package/dist/chunk-LCQKARFK.js.map +1 -0
- package/dist/cli-main.cjs +438 -85
- package/dist/cli-main.cjs.map +1 -1
- package/dist/cli-main.js +2 -2
- package/dist/index.cjs +452 -75
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +136 -7
- package/dist/index.d.ts +136 -7
- package/dist/index.js +23 -3
- package/dist/index.js.map +1 -1
- package/dist/mcp-main.cjs +433 -86
- package/dist/mcp-main.cjs.map +1 -1
- package/dist/mcp-main.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-FZIMFPGR.js.map +0 -1
- package/dist/chunk-KQMGKSPZ.js.map +0 -1
- package/dist/chunk-VOJ6D6OX.js.map +0 -1
|
@@ -11,6 +11,11 @@ var kbActorStampSchema = z.object({
|
|
|
11
11
|
by: z.string().min(1),
|
|
12
12
|
at: z.string().min(1)
|
|
13
13
|
}).passthrough();
|
|
14
|
+
var kbVerifiedEventSchema = kbActorStampSchema.extend({
|
|
15
|
+
note: z.string().refine((s) => s.trim().length > 0, {
|
|
16
|
+
message: "note must say what the check found"
|
|
17
|
+
})
|
|
18
|
+
});
|
|
14
19
|
var kbAnchorSchema = z.object({
|
|
15
20
|
file: z.string().min(1),
|
|
16
21
|
symbol: z.string().min(1).optional()
|
|
@@ -978,41 +983,48 @@ function kbJsonSchemas() {
|
|
|
978
983
|
};
|
|
979
984
|
}
|
|
980
985
|
|
|
981
|
-
// src/
|
|
982
|
-
var
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
for (const
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
if (existing.depth > 0 && !existing.via.includes(edge)) {
|
|
1001
|
-
existing.via.push(edge);
|
|
1002
|
-
}
|
|
1003
|
-
continue;
|
|
1004
|
-
}
|
|
1005
|
-
reached.set(record.conceptId, { record, depth, via: [edge] });
|
|
1006
|
-
next.push(record);
|
|
1007
|
-
}
|
|
986
|
+
// src/kb-edges.ts
|
|
987
|
+
var KB_EDGE_KINDS = [
|
|
988
|
+
"body-link",
|
|
989
|
+
"supersession",
|
|
990
|
+
"anchor",
|
|
991
|
+
"source"
|
|
992
|
+
];
|
|
993
|
+
var BODY_LINK_TARGET = new RegExp(
|
|
994
|
+
`\\]\\((${KB_CONCEPT_ID_PATTERN.source.replace(/^\^|\$$/g, "")})\\.md\\)`,
|
|
995
|
+
"g"
|
|
996
|
+
);
|
|
997
|
+
function neighbours(from, bundle, kinds = KB_EDGE_KINDS) {
|
|
998
|
+
const found = /* @__PURE__ */ new Map();
|
|
999
|
+
for (const kind of kinds) {
|
|
1000
|
+
for (const record of edgeNeighbours(from, bundle, kind)) {
|
|
1001
|
+
const existing = found.get(record.conceptId);
|
|
1002
|
+
if (existing) {
|
|
1003
|
+
if (!existing.via.includes(kind)) existing.via.push(kind);
|
|
1004
|
+
continue;
|
|
1008
1005
|
}
|
|
1006
|
+
found.set(record.conceptId, { record, via: [kind] });
|
|
1009
1007
|
}
|
|
1010
|
-
frontier = next;
|
|
1011
1008
|
}
|
|
1012
|
-
return [...
|
|
1009
|
+
return [...found.values()];
|
|
1013
1010
|
}
|
|
1014
|
-
function
|
|
1015
|
-
switch (
|
|
1011
|
+
function edgeNeighbours(from, bundle, kind) {
|
|
1012
|
+
switch (kind) {
|
|
1013
|
+
// A link whose target is not in the bundle is legal per compose.ts —
|
|
1014
|
+
// records are routinely written before the ones they point at exist — so
|
|
1015
|
+
// missing targets are skipped, never an error.
|
|
1016
|
+
case "body-link": {
|
|
1017
|
+
const targets = new Set(
|
|
1018
|
+
[...from.body.matchAll(BODY_LINK_TARGET)].map((match) => match[1])
|
|
1019
|
+
);
|
|
1020
|
+
if (!targets.size) return [];
|
|
1021
|
+
return bundle.filter(
|
|
1022
|
+
(candidate) => candidate.conceptId !== from.conceptId && targets.has(candidate.conceptId)
|
|
1023
|
+
);
|
|
1024
|
+
}
|
|
1025
|
+
// Both directions and both pointers: `supersede()` writes the pair, but a
|
|
1026
|
+
// hand-edit can leave one side behind, and a walk trusting one pointer
|
|
1027
|
+
// would miss a replacement the bundle openly declares.
|
|
1016
1028
|
case "supersession":
|
|
1017
1029
|
return bundle.filter(
|
|
1018
1030
|
(candidate) => candidate.conceptId !== from.conceptId && (candidate.conceptId === from.frontmatter.strauss_superseded_by || from.frontmatter.strauss_supersedes?.includes(
|
|
@@ -1046,6 +1058,40 @@ function anchorsTouch(left, right) {
|
|
|
1046
1058
|
if (!left.symbol || !right.symbol) return true;
|
|
1047
1059
|
return left.symbol === right.symbol;
|
|
1048
1060
|
}
|
|
1061
|
+
|
|
1062
|
+
// src/trace.ts
|
|
1063
|
+
var TRACE_EDGES = ["supersession", "anchor", "source"];
|
|
1064
|
+
function trace(seedId, bundle, options = {}) {
|
|
1065
|
+
const edges = options.edges?.length ? options.edges : TRACE_EDGES;
|
|
1066
|
+
const maxDepth = options.depth ?? 3;
|
|
1067
|
+
const byId = new Map(bundle.map((record) => [record.conceptId, record]));
|
|
1068
|
+
const seed = byId.get(seedId);
|
|
1069
|
+
if (!seed) return [];
|
|
1070
|
+
const reached = /* @__PURE__ */ new Map([
|
|
1071
|
+
[seedId, { record: seed, depth: 0, via: [] }]
|
|
1072
|
+
]);
|
|
1073
|
+
let frontier = [seed];
|
|
1074
|
+
for (let depth = 1; depth <= maxDepth && frontier.length; depth += 1) {
|
|
1075
|
+
const next = [];
|
|
1076
|
+
for (const from of frontier) {
|
|
1077
|
+
for (const edge of edges) {
|
|
1078
|
+
for (const record of edgeNeighbours(from, bundle, edge)) {
|
|
1079
|
+
const existing = reached.get(record.conceptId);
|
|
1080
|
+
if (existing) {
|
|
1081
|
+
if (existing.depth > 0 && !existing.via.includes(edge)) {
|
|
1082
|
+
existing.via.push(edge);
|
|
1083
|
+
}
|
|
1084
|
+
continue;
|
|
1085
|
+
}
|
|
1086
|
+
reached.set(record.conceptId, { record, depth, via: [edge] });
|
|
1087
|
+
next.push(record);
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
frontier = next;
|
|
1092
|
+
}
|
|
1093
|
+
return [...reached.values()].sort(byGeneratedAt);
|
|
1094
|
+
}
|
|
1049
1095
|
function byGeneratedAt(left, right) {
|
|
1050
1096
|
const at = (step) => step.record.frontmatter.generated?.at ?? "";
|
|
1051
1097
|
return at(left).localeCompare(at(right)) || left.depth - right.depth;
|
|
@@ -1276,23 +1322,123 @@ var noDecisionCommand = define({
|
|
|
1276
1322
|
}
|
|
1277
1323
|
});
|
|
1278
1324
|
|
|
1279
|
-
// src/commands/
|
|
1325
|
+
// src/commands/pack.ts
|
|
1280
1326
|
import { z as z14 } from "zod";
|
|
1327
|
+
var packCommand = define({
|
|
1328
|
+
name: "pack",
|
|
1329
|
+
tool: "kb_pack",
|
|
1330
|
+
usage: "pack <conceptId> [--hops N] [--max-nodes N] [--budget N]",
|
|
1331
|
+
description: "The bounded neighbourhood around one record: everything within `hops` of the root, ranked and cut to `maxNodes`, with every cut record named under Excluded \u2014 a named gap is knowable, a silent one is not. Prefer this over kb_load when the base is too large to hold whole and the work centres on one record; prefer it over kb_query when the question needs the governed neighbourhood \u2014 what was settled and what binds near this record \u2014 rather than a lookup by wording. Superseded records arrive as name, replacement and date stubs exactly as kb_load emits them: their bodies no longer hold, and kb_trace has the history. Refuses outright rather than truncating when the pack would exceed its token budget \u2014 a partial pack is indistinguishable from a complete one \u2014 reporting the record count and every already-cut id so the caller can lower hops or maxNodes, or raise the budget. The header carries the bundle, root, budget and a timestamp; everything below the header is byte-identical across runs over an unchanged base, so two packs can be diffed and a changed byte means changed knowledge. This tool (with kb_load, kb_query and kb_trace) is the only supported way to read a base; a raw file read bypasses supersession resolution and returns replaced records as if current.",
|
|
1332
|
+
input: z14.object({
|
|
1333
|
+
bundlePath,
|
|
1334
|
+
conceptId,
|
|
1335
|
+
hops: z14.number().int().positive().optional().describe("How far from the root the walk may reach. Defaults to 2."),
|
|
1336
|
+
maxNodes: z14.number().int().positive().optional().describe(
|
|
1337
|
+
"How many records the pack may hold, root included. Defaults to 20."
|
|
1338
|
+
),
|
|
1339
|
+
budgetTokens: z14.number().int().positive().optional().describe(
|
|
1340
|
+
"Approximate token ceiling over what is actually emitted. Defaults to 25000."
|
|
1341
|
+
)
|
|
1342
|
+
}),
|
|
1343
|
+
fromArgv: (argv, path) => {
|
|
1344
|
+
const hops = argvFlag(argv, "--hops");
|
|
1345
|
+
const maxNodes = argvFlag(argv, "--max-nodes");
|
|
1346
|
+
const budget = argvFlag(argv, "--budget");
|
|
1347
|
+
return {
|
|
1348
|
+
bundlePath: path,
|
|
1349
|
+
conceptId: argv[1],
|
|
1350
|
+
...hops ? { hops: Number(hops) } : {},
|
|
1351
|
+
...maxNodes ? { maxNodes: Number(maxNodes) } : {},
|
|
1352
|
+
...budget ? { budgetTokens: Number(budget) } : {}
|
|
1353
|
+
};
|
|
1354
|
+
},
|
|
1355
|
+
run: async ({ store, now }, { bundlePath: path, conceptId: root, hops, maxNodes, budgetTokens }) => {
|
|
1356
|
+
const result = await store.pack(path, root, {
|
|
1357
|
+
...hops !== void 0 ? { hops } : {},
|
|
1358
|
+
...maxNodes !== void 0 ? { maxNodes } : {},
|
|
1359
|
+
...budgetTokens !== void 0 ? { budgetTokens } : {}
|
|
1360
|
+
});
|
|
1361
|
+
return render(result, path, now());
|
|
1362
|
+
}
|
|
1363
|
+
});
|
|
1364
|
+
function render(result, bundle, at) {
|
|
1365
|
+
const lines = [
|
|
1366
|
+
`# KB Pack \u2014 ${result.root}`,
|
|
1367
|
+
`bundle: ${bundle}`,
|
|
1368
|
+
`budget: ~${result.tokensLoaded} of ${result.budgetTokens} tokens, ${result.recordCount} records`,
|
|
1369
|
+
`packed: ${at}`,
|
|
1370
|
+
"",
|
|
1371
|
+
`## Records (${result.records.length})`
|
|
1372
|
+
];
|
|
1373
|
+
for (const record of result.records) {
|
|
1374
|
+
lines.push(
|
|
1375
|
+
"",
|
|
1376
|
+
`### ${record.conceptId}${record.title ? ` \u2014 ${record.title}` : ""} [${record.standing}]`
|
|
1377
|
+
);
|
|
1378
|
+
if (record.warnings.length) {
|
|
1379
|
+
lines.push(`warnings: ${record.warnings.map(warningLabel).join("; ")}`);
|
|
1380
|
+
}
|
|
1381
|
+
if (record.anchors.length) {
|
|
1382
|
+
lines.push(
|
|
1383
|
+
`anchors: ${record.anchors.map(
|
|
1384
|
+
(anchor) => anchor.symbol ? `${anchor.file}#${anchor.symbol}` : anchor.file
|
|
1385
|
+
).join(", ")}`
|
|
1386
|
+
);
|
|
1387
|
+
}
|
|
1388
|
+
lines.push("", record.body.trimEnd());
|
|
1389
|
+
}
|
|
1390
|
+
if (result.superseded.length) {
|
|
1391
|
+
lines.push("", `## Superseded (${result.superseded.length})`);
|
|
1392
|
+
for (const entry of result.superseded) {
|
|
1393
|
+
lines.push(
|
|
1394
|
+
`- ${entry.conceptId} \u2192 ${entry.supersededBy.join(", ") || "(no surviving head)"}${entry.at ? ` (${entry.at})` : ""}`
|
|
1395
|
+
);
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
if (result.excluded.length) {
|
|
1399
|
+
lines.push("", `## Excluded (${result.excluded.length})`);
|
|
1400
|
+
for (const cut of result.excluded) lines.push(`- ${cut}`);
|
|
1401
|
+
}
|
|
1402
|
+
return lines.join("\n");
|
|
1403
|
+
}
|
|
1404
|
+
function warningLabel(warning) {
|
|
1405
|
+
switch (warning.kind) {
|
|
1406
|
+
case "superseded":
|
|
1407
|
+
return `superseded by ${warning.by.join(", ")}`;
|
|
1408
|
+
case "unsettled":
|
|
1409
|
+
return `unsettled (${warning.status})`;
|
|
1410
|
+
case "broken-chain":
|
|
1411
|
+
return `broken chain \u2014 ${warning.missing} is not in the bundle`;
|
|
1412
|
+
case "chain-cycle":
|
|
1413
|
+
return `chain cycle through ${warning.through.join(" \u2192 ")}`;
|
|
1414
|
+
case "forked-chain":
|
|
1415
|
+
return `forked chain \u2014 heads ${warning.heads.join(", ")}`;
|
|
1416
|
+
case "stale":
|
|
1417
|
+
return `stale since ${warning.staleAfter}`;
|
|
1418
|
+
case "unresolved-question":
|
|
1419
|
+
return "unresolved question";
|
|
1420
|
+
default:
|
|
1421
|
+
return warning.kind;
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
|
|
1425
|
+
// src/commands/pin.ts
|
|
1426
|
+
import { z as z15 } from "zod";
|
|
1281
1427
|
var pinCommand = define({
|
|
1282
1428
|
name: "pin",
|
|
1283
1429
|
tool: "kb_pin",
|
|
1284
1430
|
usage: "pin [bundle-path] [--mode full|index] [--profiles a,b] [--local|--user] [--frozen|--unfreeze]",
|
|
1285
1431
|
description: "Pin a base into a workspace pin manifest, so `context` surfaces it at every context birth. Three layers, nearest wins: the committed project manifest (.strauss/kb-pins.json, the default), `--local` (.strauss/kb-pins.local.json, personal and gitignored), and `--user` (~/.strauss/kb-pins.json, every workspace). Idempotent \u2014 re-pinning changes nothing unless --mode, --profiles, or --frozen/--unfreeze are given, which update just those fields. `--mode full` preloads the whole base into the block regardless of the full-under threshold; `--mode index` never upgrades. `--profiles` scopes the pin to named context profiles. `--frozen` marks the base concluded: write commands against it refuse and `context` labels it read-only. A path with no records yet succeeds with a warning; bases are routinely pinned before they are populated. Pins are workspace state: the pinned base itself is never touched.",
|
|
1286
|
-
input:
|
|
1432
|
+
input: z15.object({
|
|
1287
1433
|
bundlePath,
|
|
1288
|
-
mode:
|
|
1434
|
+
mode: z15.enum(["full", "index"]).optional().describe(
|
|
1289
1435
|
"full: always emit this base's records whole (still under the block budget); index: never upgrade. Absent: the profile's full-under threshold decides."
|
|
1290
1436
|
),
|
|
1291
|
-
profiles:
|
|
1292
|
-
layer:
|
|
1437
|
+
profiles: z15.array(z15.string()).optional().describe("Context profiles this pin surfaces in. Absent: all of them."),
|
|
1438
|
+
layer: z15.enum(["project", "local", "user"]).optional().describe(
|
|
1293
1439
|
"Which manifest to write: project (committed, default), local (personal, gitignored), user (~/.strauss, every workspace)."
|
|
1294
1440
|
),
|
|
1295
|
-
frozen:
|
|
1441
|
+
frozen: z15.boolean().optional().describe(
|
|
1296
1442
|
"true: the base is concluded \u2014 writes against it refuse while pinned. false: lift a freeze."
|
|
1297
1443
|
)
|
|
1298
1444
|
}),
|
|
@@ -1321,29 +1467,29 @@ var pinCommand = define({
|
|
|
1321
1467
|
});
|
|
1322
1468
|
|
|
1323
1469
|
// src/commands/pins.ts
|
|
1324
|
-
import { z as
|
|
1470
|
+
import { z as z16 } from "zod";
|
|
1325
1471
|
var pinsCommand = define({
|
|
1326
1472
|
name: "pins",
|
|
1327
1473
|
tool: "kb_pins",
|
|
1328
1474
|
usage: "pins",
|
|
1329
1475
|
description: "Every pinned base across the manifest layers, each with its layer and whether it currently resolves to readable records. Reads the workspace manifests rather than any one base, like kb_context.",
|
|
1330
|
-
input:
|
|
1476
|
+
input: z16.object({}),
|
|
1331
1477
|
fromArgv: () => ({}),
|
|
1332
1478
|
run: ({ store }) => listPins(store, process.cwd())
|
|
1333
1479
|
});
|
|
1334
1480
|
|
|
1335
1481
|
// src/commands/query.ts
|
|
1336
|
-
import { z as
|
|
1482
|
+
import { z as z17 } from "zod";
|
|
1337
1483
|
var queryCommand = define({
|
|
1338
1484
|
name: "query",
|
|
1339
1485
|
tool: "kb_query",
|
|
1340
1486
|
usage: "query <text...>",
|
|
1341
1487
|
description: "Search and return each match with its standing. Results are flagged, never filtered: a superseded record comes back alongside whatever replaced it, and a rejected one is marked as something explicitly not adopted. Prefer kb_load when the base fits its budget: on this package's measurements, a reader holding the whole base answered eight of nine questions whose wording appears in no record, where embedding search answered four. Never read record files directly \u2014 this tool (with kb_load and kb_trace) is the only supported way to read a base; a file read bypasses supersession resolution and returns replaced records as if current.",
|
|
1342
|
-
input:
|
|
1488
|
+
input: z17.object({
|
|
1343
1489
|
bundlePath,
|
|
1344
|
-
text:
|
|
1345
|
-
type:
|
|
1346
|
-
includeNonCurrent:
|
|
1490
|
+
text: z17.string().optional(),
|
|
1491
|
+
type: z17.enum(KB_RECORD_TYPES).optional(),
|
|
1492
|
+
includeNonCurrent: z17.boolean().optional()
|
|
1347
1493
|
}),
|
|
1348
1494
|
fromArgv: (argv, path) => ({
|
|
1349
1495
|
bundlePath: path,
|
|
@@ -1365,40 +1511,40 @@ var queryCommand = define({
|
|
|
1365
1511
|
});
|
|
1366
1512
|
|
|
1367
1513
|
// src/commands/read-index.ts
|
|
1368
|
-
import { z as
|
|
1514
|
+
import { z as z18 } from "zod";
|
|
1369
1515
|
var readIndexCommand = define({
|
|
1370
1516
|
name: "index",
|
|
1371
1517
|
tool: "kb_index",
|
|
1372
1518
|
usage: "index",
|
|
1373
1519
|
description: "The index, rebuilt if it disagrees with the records. One call gives the whole shape of the base: title, type, status, and description per record. The cheap re-orientation call after compaction or deep in a long session \u2014 a few hundred tokens; call it (or kb_context, when bases are pinned) first, then kb_load or fetch by concept id.",
|
|
1374
|
-
input:
|
|
1520
|
+
input: z18.object({ bundlePath }),
|
|
1375
1521
|
fromArgv: (_argv, path) => ({ bundlePath: path }),
|
|
1376
1522
|
run: ({ store }, { bundlePath: path }) => store.readIndex(path)
|
|
1377
1523
|
});
|
|
1378
1524
|
|
|
1379
1525
|
// src/commands/schema.ts
|
|
1380
|
-
import { z as
|
|
1526
|
+
import { z as z19 } from "zod";
|
|
1381
1527
|
var schemaCommand = define({
|
|
1382
1528
|
name: "schema",
|
|
1383
1529
|
tool: "kb_schema",
|
|
1384
1530
|
usage: "schema",
|
|
1385
1531
|
description: "JSON Schema for the frontmatter, the write input, and log entries \u2014 generated from the code that enforces them, so it cannot drift from what a write will accept.",
|
|
1386
|
-
input:
|
|
1532
|
+
input: z19.object({}),
|
|
1387
1533
|
fromArgv: () => ({}),
|
|
1388
1534
|
run: () => Promise.resolve(kbJsonSchemas())
|
|
1389
1535
|
});
|
|
1390
1536
|
|
|
1391
1537
|
// src/commands/status.ts
|
|
1392
|
-
import { z as
|
|
1538
|
+
import { z as z20 } from "zod";
|
|
1393
1539
|
var statusCommand = define({
|
|
1394
1540
|
name: "status",
|
|
1395
1541
|
tool: "kb_status",
|
|
1396
1542
|
usage: "status <concept-id> <status>",
|
|
1397
1543
|
description: "Move a record's status, leaving everything else alone. Uses a compare-and-swap, so a concurrent change fails loudly rather than being overwritten.",
|
|
1398
|
-
input:
|
|
1544
|
+
input: z20.object({
|
|
1399
1545
|
bundlePath,
|
|
1400
1546
|
conceptId,
|
|
1401
|
-
status:
|
|
1547
|
+
status: z20.enum(KB_RECORD_STATUSES)
|
|
1402
1548
|
}),
|
|
1403
1549
|
fromArgv: (argv, path) => ({
|
|
1404
1550
|
bundlePath: path,
|
|
@@ -1413,13 +1559,13 @@ var statusCommand = define({
|
|
|
1413
1559
|
});
|
|
1414
1560
|
|
|
1415
1561
|
// src/commands/supersede.ts
|
|
1416
|
-
import { z as
|
|
1562
|
+
import { z as z21 } from "zod";
|
|
1417
1563
|
var supersedeCommand = define({
|
|
1418
1564
|
name: "supersede",
|
|
1419
1565
|
tool: "kb_supersede",
|
|
1420
1566
|
usage: "supersede <concept-id> <replacement-id>",
|
|
1421
1567
|
description: "Mark a record superseded by another, linking both directions. Use this rather than editing a record whose meaning changed \u2014 a record that quietly becomes something else invalidates every reference to it, and the earlier understanding is what a later trace needs.",
|
|
1422
|
-
input:
|
|
1568
|
+
input: z21.object({ bundlePath, conceptId, replacementId: conceptId }),
|
|
1423
1569
|
fromArgv: (argv, path) => ({
|
|
1424
1570
|
bundlePath: path,
|
|
1425
1571
|
conceptId: argv[1],
|
|
@@ -1433,16 +1579,16 @@ var supersedeCommand = define({
|
|
|
1433
1579
|
});
|
|
1434
1580
|
|
|
1435
1581
|
// src/commands/sync-instructions.ts
|
|
1436
|
-
import { z as
|
|
1582
|
+
import { z as z22 } from "zod";
|
|
1437
1583
|
var syncInstructionsCommand = define({
|
|
1438
1584
|
name: "sync-instructions",
|
|
1439
1585
|
usage: "sync-instructions <file> [--profile NAME] [--budget N] [--full-under N]",
|
|
1440
1586
|
description: "Idempotently plant the `context` block between sentinel comments in an instruction file (AGENTS.md, CLAUDE.md), creating the block when absent and leaving everything outside the sentinels alone. CLI-only: this is file plumbing for runtimes whose instruction files are re-read where their conversations are not, not an agent capability \u2014 the capability is kb_context.",
|
|
1441
|
-
input:
|
|
1442
|
-
file:
|
|
1443
|
-
budgetTokens:
|
|
1444
|
-
fullUnderTokens:
|
|
1445
|
-
profile:
|
|
1587
|
+
input: z22.object({
|
|
1588
|
+
file: z22.string().min(1).describe("The instruction file to edit in place."),
|
|
1589
|
+
budgetTokens: z22.number().int().positive().optional(),
|
|
1590
|
+
fullUnderTokens: z22.number().int().positive().optional(),
|
|
1591
|
+
profile: z22.string().optional()
|
|
1446
1592
|
}),
|
|
1447
1593
|
fromArgv: (argv) => {
|
|
1448
1594
|
const budget = argvFlag(argv, "--budget");
|
|
@@ -1468,17 +1614,17 @@ var syncInstructionsCommand = define({
|
|
|
1468
1614
|
});
|
|
1469
1615
|
|
|
1470
1616
|
// src/commands/trace.ts
|
|
1471
|
-
import { z as
|
|
1617
|
+
import { z as z23 } from "zod";
|
|
1472
1618
|
var traceCommand = define({
|
|
1473
1619
|
name: "trace",
|
|
1474
1620
|
tool: "kb_trace",
|
|
1475
1621
|
usage: "trace <concept-id> [edges...]",
|
|
1476
1622
|
description: 'How a position was arrived at, as a timeline ordered by when each record was written. Deliberately includes rejected, draft, and superseded records \u2014 in a history those are the content, not noise. Follows supersession, shared code anchors, and shared sources. Use when the question is "why is this the way it is" rather than "what do we hold now". This tool (with kb_load and kb_query) is the only supported way to read a base; a raw file read bypasses supersession resolution and returns replaced records as if current.',
|
|
1477
|
-
input:
|
|
1623
|
+
input: z23.object({
|
|
1478
1624
|
bundlePath,
|
|
1479
1625
|
conceptId,
|
|
1480
|
-
edges:
|
|
1481
|
-
depth:
|
|
1626
|
+
edges: z23.array(z23.enum(TRACE_EDGES)).optional(),
|
|
1627
|
+
depth: z23.number().int().positive().optional()
|
|
1482
1628
|
}),
|
|
1483
1629
|
fromArgv: (argv, path) => ({
|
|
1484
1630
|
bundlePath: path,
|
|
@@ -1500,44 +1646,73 @@ var traceCommand = define({
|
|
|
1500
1646
|
});
|
|
1501
1647
|
|
|
1502
1648
|
// src/commands/types.ts
|
|
1503
|
-
import { z as
|
|
1649
|
+
import { z as z24 } from "zod";
|
|
1504
1650
|
var typesCommand = define({
|
|
1505
1651
|
name: "types",
|
|
1506
1652
|
tool: "kb_types",
|
|
1507
1653
|
usage: "types",
|
|
1508
1654
|
description: "The twelve record types with their purpose, body sections, and starting status. Read this before writing rather than guessing headings \u2014 a section the type does not define is rejected.",
|
|
1509
|
-
input:
|
|
1655
|
+
input: z24.object({}),
|
|
1510
1656
|
fromArgv: () => ({}),
|
|
1511
1657
|
run: () => Promise.resolve(RECORD_TYPES)
|
|
1512
1658
|
});
|
|
1513
1659
|
|
|
1514
1660
|
// src/commands/unpin.ts
|
|
1515
|
-
import { z as
|
|
1661
|
+
import { z as z25 } from "zod";
|
|
1516
1662
|
var unpinCommand = define({
|
|
1517
1663
|
name: "unpin",
|
|
1518
1664
|
tool: "kb_unpin",
|
|
1519
1665
|
usage: "unpin [bundle-path]",
|
|
1520
1666
|
description: "Remove a base from every pin manifest layer that holds it \u2014 project, local, and user \u2014 because unpinned means gone, not still injected from another file. Reports which layers were touched.",
|
|
1521
|
-
input:
|
|
1667
|
+
input: z25.object({ bundlePath }),
|
|
1522
1668
|
fromArgv: (argv, path) => ({ bundlePath: argv[1] ?? path }),
|
|
1523
1669
|
run: (_ctx, { bundlePath: path }) => unpinBase(process.cwd(), path)
|
|
1524
1670
|
});
|
|
1525
1671
|
|
|
1526
1672
|
// src/commands/validate.ts
|
|
1527
|
-
import { z as
|
|
1673
|
+
import { z as z26 } from "zod";
|
|
1528
1674
|
var validateCommand = define({
|
|
1529
1675
|
name: "validate",
|
|
1530
1676
|
tool: "kb_validate",
|
|
1531
1677
|
usage: "validate",
|
|
1532
1678
|
description: "Check pointers no single record can see: supersession links that disagree between the two records, and assumptions that cite sources. Per-record shape is enforced on every read, so a problem here means someone edited a file by hand.",
|
|
1533
|
-
input:
|
|
1679
|
+
input: z26.object({ bundlePath }),
|
|
1534
1680
|
fromArgv: (_argv, path) => ({ bundlePath: path }),
|
|
1535
1681
|
run: async ({ store }, { bundlePath: path }) => validateBundle(await store.list(path)),
|
|
1536
1682
|
failsWhen: (result) => Array.isArray(result) && result.length > 0
|
|
1537
1683
|
});
|
|
1538
1684
|
|
|
1685
|
+
// src/commands/verify.ts
|
|
1686
|
+
import { z as z27 } from "zod";
|
|
1687
|
+
var verifyCommand = define({
|
|
1688
|
+
name: "verify",
|
|
1689
|
+
tool: "kb_verify",
|
|
1690
|
+
usage: "verify <concept-id> --note <text>",
|
|
1691
|
+
description: "Append one verified[] event \u2014 who checked the record, when, and what the check found. Appends only; prior events are never rewritten. A record's own generator is refused unless the actor is human: re-reading your own output is not an independent check.",
|
|
1692
|
+
input: z27.object({
|
|
1693
|
+
bundlePath,
|
|
1694
|
+
conceptId,
|
|
1695
|
+
note: z27.string().refine((s) => s.trim().length > 0, {
|
|
1696
|
+
message: "note must say what the check found"
|
|
1697
|
+
})
|
|
1698
|
+
}),
|
|
1699
|
+
fromArgv: (argv, path) => ({
|
|
1700
|
+
bundlePath: path,
|
|
1701
|
+
conceptId: argv[1],
|
|
1702
|
+
note: argvFlag(argv, "--note")
|
|
1703
|
+
}),
|
|
1704
|
+
run: async ({ store, actor, now }, { bundlePath: path, conceptId: id, note }) => {
|
|
1705
|
+
await assertBaseNotFrozen(process.cwd(), path);
|
|
1706
|
+
const record = await store.verify(path, id, note, actor, now());
|
|
1707
|
+
return {
|
|
1708
|
+
conceptId: record.conceptId,
|
|
1709
|
+
verified: record.frontmatter.verified?.length ?? 0
|
|
1710
|
+
};
|
|
1711
|
+
}
|
|
1712
|
+
});
|
|
1713
|
+
|
|
1539
1714
|
// src/commands/write.ts
|
|
1540
|
-
import { z as
|
|
1715
|
+
import { z as z28 } from "zod";
|
|
1541
1716
|
var writeCommand = define({
|
|
1542
1717
|
name: "write",
|
|
1543
1718
|
tool: "kb_write",
|
|
@@ -1551,9 +1726,9 @@ var writeCommand = define({
|
|
|
1551
1726
|
"- Prefer a new record over overloading an existing one, and keep each short. A record nobody finishes reading is not durable memory.",
|
|
1552
1727
|
"- Records are never deleted; supersede instead, so the earlier reasoning stays inspectable."
|
|
1553
1728
|
].join("\n"),
|
|
1554
|
-
input:
|
|
1729
|
+
input: z28.object({
|
|
1555
1730
|
bundlePath,
|
|
1556
|
-
type:
|
|
1731
|
+
type: z28.enum(KB_RECORD_TYPES),
|
|
1557
1732
|
input: composeInputSchema
|
|
1558
1733
|
}),
|
|
1559
1734
|
fromArgv: async (argv, path, stdin) => ({
|
|
@@ -1577,7 +1752,7 @@ var writeCommand = define({
|
|
|
1577
1752
|
});
|
|
1578
1753
|
|
|
1579
1754
|
// src/commands/write-decision.ts
|
|
1580
|
-
import { z as
|
|
1755
|
+
import { z as z29 } from "zod";
|
|
1581
1756
|
var writeDecisionCommand = define({
|
|
1582
1757
|
name: "write-decision",
|
|
1583
1758
|
tool: "kb_write_decision",
|
|
@@ -1590,7 +1765,7 @@ var writeDecisionCommand = define({
|
|
|
1590
1765
|
"- `alternative` is what you turned down and why, not a list of everything considered.",
|
|
1591
1766
|
"- A reference to material you read goes in `sources`; a reference to code goes in `anchors`; a reference to another record goes in `relatedConceptIds`."
|
|
1592
1767
|
].join("\n"),
|
|
1593
|
-
input:
|
|
1768
|
+
input: z29.object({ bundlePath, input: decisionInputSchema }),
|
|
1594
1769
|
fromArgv: async (_argv, path, stdin) => ({
|
|
1595
1770
|
bundlePath: path,
|
|
1596
1771
|
input: JSON.parse(await stdin())
|
|
@@ -1618,7 +1793,9 @@ var KB_COMMANDS = [
|
|
|
1618
1793
|
statusCommand,
|
|
1619
1794
|
supersedeCommand,
|
|
1620
1795
|
answerCommand,
|
|
1796
|
+
verifyCommand,
|
|
1621
1797
|
loadCommand,
|
|
1798
|
+
packCommand,
|
|
1622
1799
|
queryCommand,
|
|
1623
1800
|
traceCommand,
|
|
1624
1801
|
listCommand,
|
|
@@ -1672,7 +1849,9 @@ var Fault = /* @__PURE__ */ ((Fault2) => {
|
|
|
1672
1849
|
var ErrorTypes = /* @__PURE__ */ ((ErrorTypes2) => {
|
|
1673
1850
|
ErrorTypes2["KbRecordAlreadyExists"] = "KbRecordAlreadyExists";
|
|
1674
1851
|
ErrorTypes2["KbInvalidConceptId"] = "KbInvalidConceptId";
|
|
1852
|
+
ErrorTypes2["KbPackBudgetExceeded"] = "KbPackBudgetExceeded";
|
|
1675
1853
|
ErrorTypes2["KbRecordNotFound"] = "KbRecordNotFound";
|
|
1854
|
+
ErrorTypes2["KbSelfVerification"] = "KbSelfVerification";
|
|
1676
1855
|
ErrorTypes2["KbWriteConflict"] = "KbWriteConflict";
|
|
1677
1856
|
return ErrorTypes2;
|
|
1678
1857
|
})(ErrorTypes || {});
|
|
@@ -1741,6 +1920,46 @@ var KbWriteConflictError = class extends BaseError {
|
|
|
1741
1920
|
}
|
|
1742
1921
|
conceptId;
|
|
1743
1922
|
};
|
|
1923
|
+
var KbSelfVerificationError = class extends BaseError {
|
|
1924
|
+
constructor(conceptId2, actor, generatedBy) {
|
|
1925
|
+
super({
|
|
1926
|
+
message: `kb: ${conceptId2} was generated by ${generatedBy}, and a record's generator cannot verify it \u2014 only a human or a different actor can`,
|
|
1927
|
+
errorType: "KbSelfVerification" /* KbSelfVerification */,
|
|
1928
|
+
code: 400,
|
|
1929
|
+
fault: "User" /* User */,
|
|
1930
|
+
retriable: false,
|
|
1931
|
+
reportToUser: true,
|
|
1932
|
+
details: { conceptId: conceptId2, actor, generatedBy, action: "refused" }
|
|
1933
|
+
});
|
|
1934
|
+
this.conceptId = conceptId2;
|
|
1935
|
+
this.actor = actor;
|
|
1936
|
+
this.generatedBy = generatedBy;
|
|
1937
|
+
}
|
|
1938
|
+
conceptId;
|
|
1939
|
+
actor;
|
|
1940
|
+
generatedBy;
|
|
1941
|
+
};
|
|
1942
|
+
var KbPackBudgetExceededError = class extends BaseError {
|
|
1943
|
+
constructor(recordCount, approxTokens2, budgetTokens, excluded) {
|
|
1944
|
+
super({
|
|
1945
|
+
message: `kb: a pack of ${recordCount} records is ~${approxTokens2} tokens against a budget of ${budgetTokens} \u2014 lower hops or maxNodes, or raise the budget`,
|
|
1946
|
+
errorType: "KbPackBudgetExceeded" /* KbPackBudgetExceeded */,
|
|
1947
|
+
code: 400,
|
|
1948
|
+
fault: "User" /* User */,
|
|
1949
|
+
retriable: false,
|
|
1950
|
+
reportToUser: true,
|
|
1951
|
+
details: { recordCount, approxTokens: approxTokens2, budgetTokens, excluded }
|
|
1952
|
+
});
|
|
1953
|
+
this.recordCount = recordCount;
|
|
1954
|
+
this.approxTokens = approxTokens2;
|
|
1955
|
+
this.budgetTokens = budgetTokens;
|
|
1956
|
+
this.excluded = excluded;
|
|
1957
|
+
}
|
|
1958
|
+
recordCount;
|
|
1959
|
+
approxTokens;
|
|
1960
|
+
budgetTokens;
|
|
1961
|
+
excluded;
|
|
1962
|
+
};
|
|
1744
1963
|
var KbInvalidConceptIdError = class extends BaseError {
|
|
1745
1964
|
constructor(message, details) {
|
|
1746
1965
|
super({
|
|
@@ -1971,6 +2190,40 @@ var KbStore = class {
|
|
|
1971
2190
|
{ operation: `status:${status}`, by: actor }
|
|
1972
2191
|
);
|
|
1973
2192
|
}
|
|
2193
|
+
/**
|
|
2194
|
+
* Appends one `verified[]` event: who checked the record, when, and what the
|
|
2195
|
+
* check found. Append-only — prior events are history, and are spread into
|
|
2196
|
+
* the new array untouched rather than reshaped through the write schema.
|
|
2197
|
+
*
|
|
2198
|
+
* A record's generator cannot verify its own record unless the actor is
|
|
2199
|
+
* human: the generator re-reading its own output is not an independent
|
|
2200
|
+
* check. The rule runs before the mutation so a refusal never publishes,
|
|
2201
|
+
* and the refusal is logged under its own operation name — `mutate` only
|
|
2202
|
+
* logs what it publishes.
|
|
2203
|
+
*/
|
|
2204
|
+
async verify(bundlePath2, conceptId2, note, actor = "unknown", at = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
2205
|
+
const event = kbVerifiedEventSchema.parse({ by: actor, at, note });
|
|
2206
|
+
const existing = await this.read(bundlePath2, conceptId2);
|
|
2207
|
+
if (!existing) throw new KbRecordNotFoundError(conceptId2);
|
|
2208
|
+
const generatedBy = existing.frontmatter.generated?.by;
|
|
2209
|
+
if (generatedBy !== void 0 && actor.toLowerCase() === generatedBy.toLowerCase() && !normalizeActor(actor).startsWith("human:")) {
|
|
2210
|
+
await this.record(this.root(bundlePath2), {
|
|
2211
|
+
operation: "verify:refused",
|
|
2212
|
+
conceptId: conceptId2,
|
|
2213
|
+
by: actor
|
|
2214
|
+
});
|
|
2215
|
+
throw new KbSelfVerificationError(conceptId2, actor, generatedBy);
|
|
2216
|
+
}
|
|
2217
|
+
return this.mutate(
|
|
2218
|
+
bundlePath2,
|
|
2219
|
+
conceptId2,
|
|
2220
|
+
(frontmatter) => ({
|
|
2221
|
+
...frontmatter,
|
|
2222
|
+
verified: [...frontmatter.verified ?? [], event]
|
|
2223
|
+
}),
|
|
2224
|
+
{ operation: "verify", by: actor }
|
|
2225
|
+
);
|
|
2226
|
+
}
|
|
1974
2227
|
/**
|
|
1975
2228
|
* Marks `conceptId` superseded by `replacementId`, and links both directions.
|
|
1976
2229
|
*
|
|
@@ -2108,6 +2361,10 @@ ${answer}
|
|
|
2108
2361
|
async trace(bundlePath2, seedId, options = {}) {
|
|
2109
2362
|
return trace(seedId, await this.list(bundlePath2), options);
|
|
2110
2363
|
}
|
|
2364
|
+
/** A bounded neighbourhood around one record. See `pack.ts`. */
|
|
2365
|
+
async pack(bundlePath2, rootId, options = {}) {
|
|
2366
|
+
return pack(await this.list(bundlePath2), rootId, options);
|
|
2367
|
+
}
|
|
2111
2368
|
/**
|
|
2112
2369
|
* The stored index, rebuilt if it disagrees with the records.
|
|
2113
2370
|
*
|
|
@@ -2305,13 +2562,106 @@ function matches(record, needle) {
|
|
|
2305
2562
|
(field) => field?.toLowerCase().includes(needle)
|
|
2306
2563
|
);
|
|
2307
2564
|
}
|
|
2565
|
+
function normalizeActor(id) {
|
|
2566
|
+
const colon = id.indexOf(":");
|
|
2567
|
+
if (colon === -1) return id.toLowerCase();
|
|
2568
|
+
return id.slice(0, colon + 1).toLowerCase() + id.slice(colon + 1);
|
|
2569
|
+
}
|
|
2308
2570
|
function digest(contents) {
|
|
2309
2571
|
return createHash("sha256").update(contents).digest("hex");
|
|
2310
2572
|
}
|
|
2311
2573
|
|
|
2574
|
+
// src/pack.ts
|
|
2575
|
+
var DEFAULT_PACK_HOPS = 2;
|
|
2576
|
+
var DEFAULT_PACK_MAX_NODES = 20;
|
|
2577
|
+
var TYPE_PRIORITY = [
|
|
2578
|
+
"decision",
|
|
2579
|
+
"constraint",
|
|
2580
|
+
"requirement",
|
|
2581
|
+
...KB_RECORD_TYPES.filter(
|
|
2582
|
+
(type) => !["decision", "constraint", "requirement"].includes(type)
|
|
2583
|
+
)
|
|
2584
|
+
];
|
|
2585
|
+
function pack(bundle, rootId, options = {}) {
|
|
2586
|
+
const hops = options.hops ?? DEFAULT_PACK_HOPS;
|
|
2587
|
+
const maxNodes = options.maxNodes ?? DEFAULT_PACK_MAX_NODES;
|
|
2588
|
+
const budgetTokens = options.budgetTokens ?? DEFAULT_LOAD_BUDGET;
|
|
2589
|
+
const byId = new Map(bundle.map((record) => [record.conceptId, record]));
|
|
2590
|
+
const root = byId.get(rootId);
|
|
2591
|
+
if (!root) throw new KbRecordNotFoundError(rootId);
|
|
2592
|
+
const reached = [{ record: root, depth: 0 }];
|
|
2593
|
+
const seen = /* @__PURE__ */ new Set([rootId]);
|
|
2594
|
+
let frontier = [root];
|
|
2595
|
+
for (let depth = 1; frontier.length; depth += 1) {
|
|
2596
|
+
const next = [];
|
|
2597
|
+
for (const from of frontier) {
|
|
2598
|
+
for (const { record } of neighbours(from, bundle)) {
|
|
2599
|
+
if (seen.has(record.conceptId)) continue;
|
|
2600
|
+
seen.add(record.conceptId);
|
|
2601
|
+
reached.push({ record, depth });
|
|
2602
|
+
next.push(record);
|
|
2603
|
+
}
|
|
2604
|
+
}
|
|
2605
|
+
frontier = next;
|
|
2606
|
+
}
|
|
2607
|
+
reached.sort(byRank);
|
|
2608
|
+
const within = reached.filter((entry) => entry.depth <= hops);
|
|
2609
|
+
const kept = within.slice(0, maxNodes);
|
|
2610
|
+
const excluded = [
|
|
2611
|
+
...within.slice(maxNodes),
|
|
2612
|
+
...reached.filter((entry) => entry.depth > hops)
|
|
2613
|
+
].map((entry) => entry.record.conceptId).sort();
|
|
2614
|
+
const adjudicated = adjudicate(
|
|
2615
|
+
kept.map((entry) => entry.record),
|
|
2616
|
+
bundle
|
|
2617
|
+
);
|
|
2618
|
+
const superseded = adjudicated.filter((hit) => hit.standing === "superseded").map(stub);
|
|
2619
|
+
const whole = adjudicated.filter((hit) => hit.standing !== "superseded");
|
|
2620
|
+
const tokensLoaded = whole.reduce((total, hit) => total + estimateTokens(hit.record), 0) + superseded.reduce((total, entry) => total + estimateStubTokens(entry), 0);
|
|
2621
|
+
const recordCount = adjudicated.length;
|
|
2622
|
+
if (tokensLoaded > budgetTokens) {
|
|
2623
|
+
throw new KbPackBudgetExceededError(
|
|
2624
|
+
recordCount,
|
|
2625
|
+
tokensLoaded,
|
|
2626
|
+
budgetTokens,
|
|
2627
|
+
excluded
|
|
2628
|
+
);
|
|
2629
|
+
}
|
|
2630
|
+
return {
|
|
2631
|
+
root: rootId,
|
|
2632
|
+
records: whole.map((hit) => ({
|
|
2633
|
+
conceptId: hit.record.conceptId,
|
|
2634
|
+
title: hit.record.frontmatter.title ?? null,
|
|
2635
|
+
standing: hit.standing,
|
|
2636
|
+
supersededBy: hit.heads.map((head) => head.conceptId),
|
|
2637
|
+
warnings: hit.warnings,
|
|
2638
|
+
anchors: hit.record.frontmatter.strauss_anchors ?? [],
|
|
2639
|
+
body: hit.record.body
|
|
2640
|
+
})),
|
|
2641
|
+
superseded,
|
|
2642
|
+
excluded,
|
|
2643
|
+
recordCount,
|
|
2644
|
+
tokensLoaded,
|
|
2645
|
+
budgetTokens
|
|
2646
|
+
};
|
|
2647
|
+
}
|
|
2648
|
+
function byRank(left, right) {
|
|
2649
|
+
return left.depth - right.depth || typeRank(left.record) - typeRank(right.record) || (left.record.frontmatter.title ?? "").localeCompare(
|
|
2650
|
+
right.record.frontmatter.title ?? ""
|
|
2651
|
+
) || left.record.conceptId.localeCompare(right.record.conceptId);
|
|
2652
|
+
}
|
|
2653
|
+
function typeRank(record) {
|
|
2654
|
+
const index = TYPE_PRIORITY.indexOf(record.frontmatter.type);
|
|
2655
|
+
return index === -1 ? TYPE_PRIORITY.length : index;
|
|
2656
|
+
}
|
|
2657
|
+
|
|
2658
|
+
// src/version.ts
|
|
2659
|
+
var VERSION = true ? "0.1.7" : "0.0.0-dev";
|
|
2660
|
+
|
|
2312
2661
|
export {
|
|
2313
2662
|
kbSourceSchema,
|
|
2314
2663
|
kbActorStampSchema,
|
|
2664
|
+
kbVerifiedEventSchema,
|
|
2315
2665
|
kbAnchorSchema,
|
|
2316
2666
|
KB_RECORD_TYPES,
|
|
2317
2667
|
KB_SLUG_PATTERN,
|
|
@@ -2363,6 +2713,9 @@ export {
|
|
|
2363
2713
|
renderLogEntry,
|
|
2364
2714
|
parseLog,
|
|
2365
2715
|
kbJsonSchemas,
|
|
2716
|
+
KB_EDGE_KINDS,
|
|
2717
|
+
neighbours,
|
|
2718
|
+
edgeNeighbours,
|
|
2366
2719
|
TRACE_EDGES,
|
|
2367
2720
|
trace,
|
|
2368
2721
|
validateBundle,
|
|
@@ -2377,12 +2730,19 @@ export {
|
|
|
2377
2730
|
KbRecordAlreadyExistsError,
|
|
2378
2731
|
KbRecordNotFoundError,
|
|
2379
2732
|
KbWriteConflictError,
|
|
2733
|
+
KbSelfVerificationError,
|
|
2734
|
+
KbPackBudgetExceededError,
|
|
2380
2735
|
KbInvalidConceptIdError,
|
|
2381
2736
|
SEARCH_INDEX_FILE,
|
|
2382
2737
|
searchBase,
|
|
2383
2738
|
resolveHits,
|
|
2384
2739
|
loadQmd,
|
|
2740
|
+
DEFAULT_PACK_HOPS,
|
|
2741
|
+
DEFAULT_PACK_MAX_NODES,
|
|
2742
|
+
pack,
|
|
2385
2743
|
KB_DIR,
|
|
2386
|
-
|
|
2744
|
+
DEFAULT_LOAD_BUDGET,
|
|
2745
|
+
KbStore,
|
|
2746
|
+
VERSION
|
|
2387
2747
|
};
|
|
2388
|
-
//# sourceMappingURL=chunk-
|
|
2748
|
+
//# sourceMappingURL=chunk-GKUQOJEK.js.map
|