@dikolab/kbdb 0.6.3 → 0.6.4
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/cli.cjs +268 -144
- package/dist/cli.cjs.map +4 -4
- package/dist/cli.mjs +225 -101
- package/dist/cli.mjs.map +4 -4
- package/dist/mod.cjs +1 -1
- package/dist/mod.cjs.map +1 -1
- package/dist/mod.mjs +1 -1
- package/dist/mod.mjs.map +1 -1
- package/dist/src/shared/cli/functions/learn-markdown-document.function.d.ts +22 -0
- package/dist/src/shared/cli/functions/learn-target-content.function.d.ts +24 -0
- package/dist/src/shared/cli/functions/map-add-section-result.function.d.ts +12 -0
- package/dist/src/shared/cli/functions/run-agent-list.function.d.ts +13 -9
- package/dist/src/shared/cli/functions/run-learn.function.d.ts +10 -59
- package/dist/src/shared/cli/functions/run-skill-list.function.d.ts +11 -7
- package/dist/src/shared/cli/functions/split-markdown-sections.function.d.ts +12 -0
- package/dist/src/shared/cli/typings/learn-client.interface.d.ts +14 -28
- package/dist/src/shared/cli/typings/markdown-section.interface.d.ts +23 -0
- package/dist/src/shared/mcp/functions/handle-agent-list.function.d.ts +11 -21
- package/dist/src/shared/mcp/functions/handle-tool-call.function.d.ts +1 -15
- package/dist/src/shared/mcp/functions/handle-tool-skill-list.function.d.ts +13 -3
- package/dist/src/shared/query-filter/functions/matches-query.function.d.ts +17 -0
- package/dist/src/shared/version/constants/version.constant.d.ts +1 -1
- package/dist/wasm/default-embedding/kbdb_default_embedding_bg.wasm +0 -0
- package/dist/wasm/kb-worker/kbdb_worker_bg.wasm +0 -0
- package/dist/wasm/query-parser/kbdb_query_parser_bg.wasm +0 -0
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
// src/cli.ts
|
|
5
5
|
var import_node_fs10 = require("node:fs");
|
|
6
|
-
var
|
|
6
|
+
var import_node_path15 = require("node:path");
|
|
7
7
|
|
|
8
8
|
// src/shared/runtime/functions/detect-runtime.ts
|
|
9
9
|
function detectRuntime() {
|
|
@@ -745,6 +745,120 @@ function computeDirectoryLevel(filePath, basePath) {
|
|
|
745
745
|
return Math.min(depth + 1, MAX_LEVEL);
|
|
746
746
|
}
|
|
747
747
|
|
|
748
|
+
// src/shared/cli/functions/learn-markdown-document.function.ts
|
|
749
|
+
var import_node_path3 = require("node:path");
|
|
750
|
+
|
|
751
|
+
// src/shared/cli/functions/split-markdown-sections.function.ts
|
|
752
|
+
var HEADING_PATTERN = /^(#{1,6})\s+(.+)$/;
|
|
753
|
+
function splitMarkdownSections(content) {
|
|
754
|
+
const sections = [];
|
|
755
|
+
let draft = { lines: [] };
|
|
756
|
+
let inCodeBlock = false;
|
|
757
|
+
for (const line of content.split("\n")) {
|
|
758
|
+
if (line.startsWith("```") || line.startsWith("~~~")) {
|
|
759
|
+
inCodeBlock = !inCodeBlock;
|
|
760
|
+
draft.lines.push(line);
|
|
761
|
+
continue;
|
|
762
|
+
}
|
|
763
|
+
const heading = inCodeBlock ? null : HEADING_PATTERN.exec(line);
|
|
764
|
+
if (heading) {
|
|
765
|
+
flushSection(draft, sections);
|
|
766
|
+
draft = {
|
|
767
|
+
title: heading[2].trim(),
|
|
768
|
+
level: heading[1].length,
|
|
769
|
+
lines: []
|
|
770
|
+
};
|
|
771
|
+
continue;
|
|
772
|
+
}
|
|
773
|
+
draft.lines.push(line);
|
|
774
|
+
}
|
|
775
|
+
flushSection(draft, sections);
|
|
776
|
+
return sections.length > 0 ? sections : [{ content: content.trimEnd() }];
|
|
777
|
+
}
|
|
778
|
+
function flushSection(draft, sections) {
|
|
779
|
+
const body = draft.lines.join("\n").trimEnd();
|
|
780
|
+
if (draft.title === void 0 && body.length === 0) return;
|
|
781
|
+
sections.push(
|
|
782
|
+
draft.title === void 0 ? { content: body } : { title: draft.title, level: draft.level, content: body }
|
|
783
|
+
);
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
// src/shared/cli/functions/map-add-section-result.function.ts
|
|
787
|
+
function mapAddSectionResult(result, path, size, sectionType) {
|
|
788
|
+
return {
|
|
789
|
+
kbid: result.items[0] ?? "",
|
|
790
|
+
indexed_terms_count: 0,
|
|
791
|
+
type: sectionType,
|
|
792
|
+
path,
|
|
793
|
+
size,
|
|
794
|
+
skipped: false,
|
|
795
|
+
superseded: result.superseded ?? null,
|
|
796
|
+
warnings: result.warnings ?? [],
|
|
797
|
+
near_duplicates: result.near_duplicates ?? []
|
|
798
|
+
};
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
// src/shared/cli/functions/learn-markdown-document.function.ts
|
|
802
|
+
async function learnMarkdownDocument(client, options, path, content, sourcePath) {
|
|
803
|
+
const sections = splitMarkdownSections(content);
|
|
804
|
+
const titled = sections.filter((s) => s.title !== void 0);
|
|
805
|
+
if (sections.length < 2 || titled.length === 0) return void 0;
|
|
806
|
+
const docTitle = titled[0]?.title ?? (0, import_node_path3.basename)(path);
|
|
807
|
+
const kbids = [];
|
|
808
|
+
const results = [];
|
|
809
|
+
for (const section of sections) {
|
|
810
|
+
const added = await client.addSection({
|
|
811
|
+
sectionType: "text",
|
|
812
|
+
content: section.content,
|
|
813
|
+
title: section.title,
|
|
814
|
+
description: options.description,
|
|
815
|
+
docid: path,
|
|
816
|
+
tags: options.tags,
|
|
817
|
+
replace: options.replace,
|
|
818
|
+
sourcePath,
|
|
819
|
+
level: section.level
|
|
820
|
+
});
|
|
821
|
+
kbids.push(added.items[0] ?? "");
|
|
822
|
+
results.push(
|
|
823
|
+
mapAddSectionResult(
|
|
824
|
+
added,
|
|
825
|
+
path,
|
|
826
|
+
section.content.length,
|
|
827
|
+
"text"
|
|
828
|
+
)
|
|
829
|
+
);
|
|
830
|
+
}
|
|
831
|
+
await client.groupSections(docTitle, kbids);
|
|
832
|
+
return results;
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
// src/shared/cli/functions/learn-target-content.function.ts
|
|
836
|
+
async function learnTargetContent(client, options, path, content, sourcePath, level) {
|
|
837
|
+
const markdownEligible = (path === "-" || path.endsWith(".md")) && !options.title;
|
|
838
|
+
if (markdownEligible) {
|
|
839
|
+
const split = await learnMarkdownDocument(
|
|
840
|
+
client,
|
|
841
|
+
options,
|
|
842
|
+
path,
|
|
843
|
+
content,
|
|
844
|
+
sourcePath
|
|
845
|
+
);
|
|
846
|
+
if (split) return split;
|
|
847
|
+
}
|
|
848
|
+
const result = await client.addSection({
|
|
849
|
+
sectionType: "text",
|
|
850
|
+
content,
|
|
851
|
+
title: options.title,
|
|
852
|
+
description: options.description,
|
|
853
|
+
docid: options.docid,
|
|
854
|
+
tags: options.tags,
|
|
855
|
+
replace: options.replace,
|
|
856
|
+
sourcePath,
|
|
857
|
+
level
|
|
858
|
+
});
|
|
859
|
+
return [mapAddSectionResult(result, path, content.length, "text")];
|
|
860
|
+
}
|
|
861
|
+
|
|
748
862
|
// src/shared/cli/functions/run-learn.function.ts
|
|
749
863
|
async function runLearn(client, options, io) {
|
|
750
864
|
log(
|
|
@@ -759,37 +873,30 @@ async function runLearn(client, options, io) {
|
|
|
759
873
|
if (stdinConsumed) continue;
|
|
760
874
|
stdinConsumed = true;
|
|
761
875
|
const content = await readStdin();
|
|
762
|
-
const result = await client.addSection({
|
|
763
|
-
sectionType: "text",
|
|
764
|
-
content,
|
|
765
|
-
title: options.title,
|
|
766
|
-
description: options.description,
|
|
767
|
-
docid: options.docid,
|
|
768
|
-
tags: options.tags,
|
|
769
|
-
replace: options.replace,
|
|
770
|
-
level: options.level
|
|
771
|
-
});
|
|
772
876
|
results.push(
|
|
773
|
-
|
|
877
|
+
...await learnTargetContent(
|
|
878
|
+
client,
|
|
879
|
+
options,
|
|
880
|
+
"-",
|
|
881
|
+
content,
|
|
882
|
+
void 0,
|
|
883
|
+
options.level
|
|
884
|
+
)
|
|
774
885
|
);
|
|
775
886
|
continue;
|
|
776
887
|
}
|
|
777
888
|
const files = collectFiles(target);
|
|
778
889
|
for (const file of files) {
|
|
779
890
|
const content = (0, import_node_fs2.readFileSync)(file, "utf-8");
|
|
780
|
-
const result = await client.addSection({
|
|
781
|
-
sectionType: "text",
|
|
782
|
-
content,
|
|
783
|
-
title: options.title,
|
|
784
|
-
description: options.description,
|
|
785
|
-
docid: options.docid,
|
|
786
|
-
tags: options.tags,
|
|
787
|
-
replace: options.replace,
|
|
788
|
-
sourcePath: file,
|
|
789
|
-
level: options.level ?? computeDirectoryLevel(file, target)
|
|
790
|
-
});
|
|
791
891
|
results.push(
|
|
792
|
-
|
|
892
|
+
...await learnTargetContent(
|
|
893
|
+
client,
|
|
894
|
+
options,
|
|
895
|
+
file,
|
|
896
|
+
content,
|
|
897
|
+
file,
|
|
898
|
+
options.level ?? computeDirectoryLevel(file, target)
|
|
899
|
+
)
|
|
793
900
|
);
|
|
794
901
|
}
|
|
795
902
|
}
|
|
@@ -799,19 +906,6 @@ async function runLearn(client, options, io) {
|
|
|
799
906
|
);
|
|
800
907
|
return results;
|
|
801
908
|
}
|
|
802
|
-
function mapAddSectionResult(result, path, size, sectionType) {
|
|
803
|
-
return {
|
|
804
|
-
kbid: result.items[0] ?? "",
|
|
805
|
-
indexed_terms_count: 0,
|
|
806
|
-
type: sectionType,
|
|
807
|
-
path,
|
|
808
|
-
size,
|
|
809
|
-
skipped: false,
|
|
810
|
-
superseded: result.superseded ?? null,
|
|
811
|
-
warnings: result.warnings ?? [],
|
|
812
|
-
near_duplicates: result.near_duplicates ?? []
|
|
813
|
-
};
|
|
814
|
-
}
|
|
815
909
|
function readProcessStdin() {
|
|
816
910
|
return new Promise((resolve7) => {
|
|
817
911
|
const chunks = [];
|
|
@@ -906,32 +1000,32 @@ async function runRebuild(client, _options) {
|
|
|
906
1000
|
|
|
907
1001
|
// src/shared/cli/functions/find-db.function.ts
|
|
908
1002
|
var import_node_fs3 = require("node:fs");
|
|
909
|
-
var
|
|
1003
|
+
var import_node_path4 = require("node:path");
|
|
910
1004
|
function findDb(dbPath) {
|
|
911
1005
|
if (dbPath) {
|
|
912
|
-
const target = (0,
|
|
1006
|
+
const target = (0, import_node_path4.join)((0, import_node_path4.resolve)(dbPath), ".kbdb");
|
|
913
1007
|
return (0, import_node_fs3.existsSync)(target) ? target : null;
|
|
914
1008
|
}
|
|
915
1009
|
let current = process.cwd();
|
|
916
|
-
let parent = (0,
|
|
1010
|
+
let parent = (0, import_node_path4.dirname)(current);
|
|
917
1011
|
while (parent !== current) {
|
|
918
|
-
const candidate2 = (0,
|
|
1012
|
+
const candidate2 = (0, import_node_path4.join)(current, ".kbdb");
|
|
919
1013
|
if ((0, import_node_fs3.existsSync)(candidate2)) return candidate2;
|
|
920
1014
|
current = parent;
|
|
921
|
-
parent = (0,
|
|
1015
|
+
parent = (0, import_node_path4.dirname)(current);
|
|
922
1016
|
}
|
|
923
|
-
const candidate = (0,
|
|
1017
|
+
const candidate = (0, import_node_path4.join)(current, ".kbdb");
|
|
924
1018
|
return (0, import_node_fs3.existsSync)(candidate) ? candidate : null;
|
|
925
1019
|
}
|
|
926
1020
|
|
|
927
1021
|
// src/shared/cli/functions/run-init.function.ts
|
|
928
1022
|
var import_node_fs5 = require("node:fs");
|
|
929
|
-
var
|
|
1023
|
+
var import_node_path6 = require("node:path");
|
|
930
1024
|
|
|
931
1025
|
// src/shared/cli/functions/install-default-skills.function.ts
|
|
932
1026
|
var import_node_crypto = require("node:crypto");
|
|
933
1027
|
var import_node_fs4 = require("node:fs");
|
|
934
|
-
var
|
|
1028
|
+
var import_node_path5 = require("node:path");
|
|
935
1029
|
var BASE32_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
|
|
936
1030
|
function base32Encode(bytes) {
|
|
937
1031
|
let result = "";
|
|
@@ -992,8 +1086,8 @@ function installSkill(sectionsDir, skill) {
|
|
|
992
1086
|
});
|
|
993
1087
|
const kbid = computeSectionKbid("text/markdown", content);
|
|
994
1088
|
const prefix = kbid.slice(0, 2);
|
|
995
|
-
const shardDir = (0,
|
|
996
|
-
const filePath = (0,
|
|
1089
|
+
const shardDir = (0, import_node_path5.join)(sectionsDir, prefix);
|
|
1090
|
+
const filePath = (0, import_node_path5.join)(shardDir, `${kbid}.section`);
|
|
997
1091
|
if ((0, import_node_fs4.existsSync)(filePath)) {
|
|
998
1092
|
return;
|
|
999
1093
|
}
|
|
@@ -1021,7 +1115,7 @@ var DEFAULT_SKILLS = [
|
|
|
1021
1115
|
}
|
|
1022
1116
|
];
|
|
1023
1117
|
function installDefaultSkills(dbDir) {
|
|
1024
|
-
const sectionsDir = (0,
|
|
1118
|
+
const sectionsDir = (0, import_node_path5.join)(dbDir, "sections");
|
|
1025
1119
|
for (const skill of DEFAULT_SKILLS) {
|
|
1026
1120
|
installSkill(sectionsDir, skill);
|
|
1027
1121
|
}
|
|
@@ -1046,19 +1140,19 @@ var GITIGNORE = [
|
|
|
1046
1140
|
].join("\n");
|
|
1047
1141
|
function createScaffold(dbDir) {
|
|
1048
1142
|
(0, import_node_fs5.mkdirSync)(dbDir, { recursive: true });
|
|
1049
|
-
(0, import_node_fs5.mkdirSync)((0,
|
|
1050
|
-
(0, import_node_fs5.mkdirSync)((0,
|
|
1051
|
-
(0, import_node_fs5.writeFileSync)((0,
|
|
1052
|
-
(0, import_node_fs5.writeFileSync)((0,
|
|
1053
|
-
(0, import_node_fs5.writeFileSync)((0,
|
|
1054
|
-
(0, import_node_fs5.writeFileSync)((0,
|
|
1055
|
-
(0, import_node_fs5.writeFileSync)((0,
|
|
1056
|
-
(0, import_node_fs5.writeFileSync)((0,
|
|
1143
|
+
(0, import_node_fs5.mkdirSync)((0, import_node_path6.join)(dbDir, "sections"));
|
|
1144
|
+
(0, import_node_fs5.mkdirSync)((0, import_node_path6.join)(dbDir, "documents"));
|
|
1145
|
+
(0, import_node_fs5.writeFileSync)((0, import_node_path6.join)(dbDir, "catalog.toml"), CATALOG_TOML);
|
|
1146
|
+
(0, import_node_fs5.writeFileSync)((0, import_node_path6.join)(dbDir, "corpus.bin"), "");
|
|
1147
|
+
(0, import_node_fs5.writeFileSync)((0, import_node_path6.join)(dbDir, "inverted.idx"), "");
|
|
1148
|
+
(0, import_node_fs5.writeFileSync)((0, import_node_path6.join)(dbDir, "positional.idx"), "");
|
|
1149
|
+
(0, import_node_fs5.writeFileSync)((0, import_node_path6.join)(dbDir, "worker.toml"), WORKER_TOML);
|
|
1150
|
+
(0, import_node_fs5.writeFileSync)((0, import_node_path6.join)(dbDir, ".gitignore"), GITIGNORE);
|
|
1057
1151
|
}
|
|
1058
1152
|
function runInit(options) {
|
|
1059
1153
|
log("running init", 0 /* DEBUG */);
|
|
1060
|
-
const basePath = options.dbPath ? (0,
|
|
1061
|
-
const dbDir = (0,
|
|
1154
|
+
const basePath = options.dbPath ? (0, import_node_path6.resolve)(options.dbPath) : process.cwd();
|
|
1155
|
+
const dbDir = (0, import_node_path6.join)(basePath, ".kbdb");
|
|
1062
1156
|
try {
|
|
1063
1157
|
if ((0, import_node_fs5.existsSync)(dbDir)) {
|
|
1064
1158
|
return {
|
|
@@ -1199,28 +1293,27 @@ async function runSkillLearn(client, options) {
|
|
|
1199
1293
|
};
|
|
1200
1294
|
}
|
|
1201
1295
|
|
|
1296
|
+
// src/shared/query-filter/functions/matches-query.function.ts
|
|
1297
|
+
function matchesQuery(query, ...fields) {
|
|
1298
|
+
if (!query) return true;
|
|
1299
|
+
const needle = query.toLowerCase();
|
|
1300
|
+
return fields.some(
|
|
1301
|
+
(field) => typeof field === "string" && field.toLowerCase().includes(needle)
|
|
1302
|
+
);
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1202
1305
|
// src/shared/cli/functions/run-skill-list.function.ts
|
|
1203
|
-
async function runSkillList(client,
|
|
1306
|
+
async function runSkillList(client, options) {
|
|
1204
1307
|
log("running skill-list", 0 /* DEBUG */);
|
|
1205
1308
|
const records = await client.listByType("skill");
|
|
1206
|
-
const
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
}
|
|
1213
|
-
} catch {
|
|
1214
|
-
}
|
|
1215
|
-
return {
|
|
1216
|
-
kbid: r.kbid,
|
|
1217
|
-
name: r.title,
|
|
1218
|
-
description: r.description,
|
|
1219
|
-
argumentCount
|
|
1220
|
-
};
|
|
1221
|
-
});
|
|
1309
|
+
const query = options.args.join(" ").toLowerCase();
|
|
1310
|
+
const filtered = records.filter(
|
|
1311
|
+
(r) => matchesQuery(query, r.title, r.description)
|
|
1312
|
+
);
|
|
1313
|
+
const names = filtered.map((r) => r.title);
|
|
1314
|
+
const data = { items: names, total: names.length, offset: 0 };
|
|
1222
1315
|
return {
|
|
1223
|
-
output: JSON.stringify(
|
|
1316
|
+
output: JSON.stringify(data, null, 2),
|
|
1224
1317
|
exitCode: 0
|
|
1225
1318
|
};
|
|
1226
1319
|
}
|
|
@@ -1349,16 +1442,15 @@ async function runAgentCreate(client, options) {
|
|
|
1349
1442
|
}
|
|
1350
1443
|
|
|
1351
1444
|
// src/shared/cli/functions/run-agent-list.function.ts
|
|
1352
|
-
async function runAgentList(client,
|
|
1445
|
+
async function runAgentList(client, options) {
|
|
1353
1446
|
log("running agent-list", 0 /* DEBUG */);
|
|
1354
1447
|
const docs = await client.listDocumentsByType("agent");
|
|
1355
|
-
const
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
}));
|
|
1448
|
+
const query = options.args.join(" ").toLowerCase();
|
|
1449
|
+
const filtered = docs.filter((d) => matchesQuery(query, d.title));
|
|
1450
|
+
const names = filtered.map((d) => d.title);
|
|
1451
|
+
const data = { items: names, total: names.length, offset: 0 };
|
|
1360
1452
|
return {
|
|
1361
|
-
output: JSON.stringify(
|
|
1453
|
+
output: JSON.stringify(data, null, 2),
|
|
1362
1454
|
exitCode: 0
|
|
1363
1455
|
};
|
|
1364
1456
|
}
|
|
@@ -1464,7 +1556,7 @@ async function runAgentSearch(client, options) {
|
|
|
1464
1556
|
}
|
|
1465
1557
|
|
|
1466
1558
|
// src/shared/cli/functions/run-import.function.ts
|
|
1467
|
-
var
|
|
1559
|
+
var import_node_path7 = require("node:path");
|
|
1468
1560
|
async function runImport(client, options) {
|
|
1469
1561
|
const from = options.from;
|
|
1470
1562
|
if (!from) {
|
|
@@ -1473,7 +1565,7 @@ async function runImport(client, options) {
|
|
|
1473
1565
|
throw new Error(msg);
|
|
1474
1566
|
}
|
|
1475
1567
|
return client.import({
|
|
1476
|
-
from: (0,
|
|
1568
|
+
from: (0, import_node_path7.resolve)(process.cwd(), from),
|
|
1477
1569
|
dryRun: options.dryRun === true
|
|
1478
1570
|
});
|
|
1479
1571
|
}
|
|
@@ -1826,7 +1918,7 @@ async function handleTypedSearch(client, options, type) {
|
|
|
1826
1918
|
}
|
|
1827
1919
|
|
|
1828
1920
|
// src/shared/version/constants/version.constant.ts
|
|
1829
|
-
var VERSION = "0.6.
|
|
1921
|
+
var VERSION = "0.6.4";
|
|
1830
1922
|
|
|
1831
1923
|
// src/shared/cli/functions/generate-help.function.ts
|
|
1832
1924
|
var KNOWN_COMMANDS = /* @__PURE__ */ new Set([
|
|
@@ -1854,13 +1946,13 @@ var GROUP_SUBCOMMANDS = {
|
|
|
1854
1946
|
],
|
|
1855
1947
|
skill: [
|
|
1856
1948
|
["learn", "Create a new skill definition"],
|
|
1857
|
-
["list", "List
|
|
1949
|
+
["list", "List skills (filter by keyword)"],
|
|
1858
1950
|
["get", "Retrieve a skill by name or kbid"],
|
|
1859
1951
|
["delete", "Remove a skill"]
|
|
1860
1952
|
],
|
|
1861
1953
|
agent: [
|
|
1862
1954
|
["create", "Create an agent with skill refs"],
|
|
1863
|
-
["list", "List
|
|
1955
|
+
["list", "List agents (filter by keyword)"],
|
|
1864
1956
|
["get", "Retrieve an agent by docid"],
|
|
1865
1957
|
["delete", "Remove an agent"]
|
|
1866
1958
|
],
|
|
@@ -1905,9 +1997,9 @@ Usage: kbdb [options]
|
|
|
1905
1997
|
kbdb <command> <subcommand> [options] ...[params]
|
|
1906
1998
|
|
|
1907
1999
|
Knowledge Base:
|
|
1908
|
-
learn Import content
|
|
2000
|
+
learn Import content (splits .md on headings)
|
|
1909
2001
|
unlearn Remove sections by kbid
|
|
1910
|
-
search Query the knowledge base
|
|
2002
|
+
search Query the knowledge base (sibling boost)
|
|
1911
2003
|
recall Retrieve section context by kbid
|
|
1912
2004
|
content Compose rendered content from ids
|
|
1913
2005
|
|
|
@@ -1926,13 +2018,13 @@ Maintenance:
|
|
|
1926
2018
|
|
|
1927
2019
|
Skills:
|
|
1928
2020
|
skill learn Create a new skill definition
|
|
1929
|
-
skill list List
|
|
2021
|
+
skill list List skills (filter by keyword)
|
|
1930
2022
|
skill get Retrieve a skill by name or kbid
|
|
1931
2023
|
skill delete Remove a skill
|
|
1932
2024
|
|
|
1933
2025
|
Agents:
|
|
1934
2026
|
agent create Create an agent with skill refs
|
|
1935
|
-
agent list List
|
|
2027
|
+
agent list List agents (filter by keyword)
|
|
1936
2028
|
agent get Retrieve an agent by docid
|
|
1937
2029
|
agent delete Remove an agent
|
|
1938
2030
|
|
|
@@ -2004,9 +2096,17 @@ Options:
|
|
|
2004
2096
|
--replace Supersede existing section by source key
|
|
2005
2097
|
--db <path> Path to .kbdb directory
|
|
2006
2098
|
|
|
2099
|
+
Markdown splitting:
|
|
2100
|
+
.md files are automatically split on ATX
|
|
2101
|
+
headings (# through ######) into independent
|
|
2102
|
+
sections. Each section uses its heading as
|
|
2103
|
+
the title and shares a docid for document
|
|
2104
|
+
grouping. Providing --title imports the file
|
|
2105
|
+
as a single section (skips splitting).
|
|
2106
|
+
Non-.md files are never split.
|
|
2107
|
+
|
|
2007
2108
|
Output:
|
|
2008
|
-
|
|
2009
|
-
superseded, warnings, near_duplicates }
|
|
2109
|
+
{ items, total, offset } envelope
|
|
2010
2110
|
|
|
2011
2111
|
Examples:
|
|
2012
2112
|
kbdb learn README.md
|
|
@@ -2045,8 +2145,14 @@ Options:
|
|
|
2045
2145
|
--content, -c Hydrate results with section content
|
|
2046
2146
|
--db <path> Path to .kbdb directory
|
|
2047
2147
|
|
|
2148
|
+
Scoring:
|
|
2149
|
+
Results are ranked by BM25F. Sections from
|
|
2150
|
+
the same document (shared docid) receive a
|
|
2151
|
+
sibling score boost when multiple sections
|
|
2152
|
+
match the query.
|
|
2153
|
+
|
|
2048
2154
|
Output:
|
|
2049
|
-
|
|
2155
|
+
{ items, total, offset } envelope
|
|
2050
2156
|
|
|
2051
2157
|
Examples:
|
|
2052
2158
|
kbdb search "machine learning"
|
|
@@ -2255,16 +2361,20 @@ Examples:
|
|
|
2255
2361
|
`,
|
|
2256
2362
|
"skill-list": `kbdb skill list - List all skills
|
|
2257
2363
|
|
|
2258
|
-
Usage: kbdb skill list [options]
|
|
2364
|
+
Usage: kbdb skill list [options] [keywords...]
|
|
2365
|
+
|
|
2366
|
+
Arguments:
|
|
2367
|
+
[keywords...] Case-insensitive substring filter on name or description
|
|
2259
2368
|
|
|
2260
2369
|
Options:
|
|
2261
2370
|
--db <path> Path to .kbdb directory
|
|
2262
2371
|
|
|
2263
2372
|
Output:
|
|
2264
|
-
JSON
|
|
2373
|
+
JSON { items, total, offset }
|
|
2265
2374
|
|
|
2266
2375
|
Examples:
|
|
2267
2376
|
kbdb skill list
|
|
2377
|
+
kbdb skill list summarize
|
|
2268
2378
|
kbdb skill list --db /path/to/project
|
|
2269
2379
|
`,
|
|
2270
2380
|
"skill-get": `kbdb skill get - Retrieve a skill by name or kbid
|
|
@@ -2320,16 +2430,20 @@ Examples:
|
|
|
2320
2430
|
`,
|
|
2321
2431
|
"agent-list": `kbdb agent list - List all agents
|
|
2322
2432
|
|
|
2323
|
-
Usage: kbdb agent list [options]
|
|
2433
|
+
Usage: kbdb agent list [options] [keywords...]
|
|
2434
|
+
|
|
2435
|
+
Arguments:
|
|
2436
|
+
[keywords...] Case-insensitive substring filter on agent name
|
|
2324
2437
|
|
|
2325
2438
|
Options:
|
|
2326
2439
|
--db <path> Path to .kbdb directory
|
|
2327
2440
|
|
|
2328
2441
|
Output:
|
|
2329
|
-
JSON
|
|
2442
|
+
JSON { items, total, offset }
|
|
2330
2443
|
|
|
2331
2444
|
Examples:
|
|
2332
2445
|
kbdb agent list
|
|
2446
|
+
kbdb agent list reviewer
|
|
2333
2447
|
kbdb agent list --db /path/to/project
|
|
2334
2448
|
`,
|
|
2335
2449
|
"agent-get": `kbdb agent get - Retrieve an agent by docid
|
|
@@ -2468,7 +2582,7 @@ var import_node_net = require("node:net");
|
|
|
2468
2582
|
|
|
2469
2583
|
// src/shared/worker-client/functions/discover-daemon.function.ts
|
|
2470
2584
|
var import_node_fs6 = require("node:fs");
|
|
2471
|
-
var
|
|
2585
|
+
var import_node_path8 = require("node:path");
|
|
2472
2586
|
var import_node_os = require("node:os");
|
|
2473
2587
|
|
|
2474
2588
|
// src/shared/platform/functions/is-process-alive.function.ts
|
|
@@ -2484,7 +2598,7 @@ function isProcessAlive(pid) {
|
|
|
2484
2598
|
// src/shared/worker-client/functions/discover-daemon.function.ts
|
|
2485
2599
|
function discoverDaemon(contextId) {
|
|
2486
2600
|
log("discovering daemon for context: " + contextId, 0 /* DEBUG */);
|
|
2487
|
-
const pidPath = (0,
|
|
2601
|
+
const pidPath = (0, import_node_path8.join)((0, import_node_os.tmpdir)(), `kbdb-${contextId}.pid`);
|
|
2488
2602
|
if (!(0, import_node_fs6.existsSync)(pidPath)) {
|
|
2489
2603
|
log(
|
|
2490
2604
|
"no daemon PID file found for context: " + contextId,
|
|
@@ -2506,8 +2620,8 @@ function discoverDaemon(contextId) {
|
|
|
2506
2620
|
return null;
|
|
2507
2621
|
}
|
|
2508
2622
|
log("daemon found: pid=" + pid.toString(), 0 /* DEBUG */);
|
|
2509
|
-
const socketPath = (0,
|
|
2510
|
-
const crashPath = (0,
|
|
2623
|
+
const socketPath = (0, import_node_path8.join)((0, import_node_os.tmpdir)(), `kbdb-${contextId}.sock`);
|
|
2624
|
+
const crashPath = (0, import_node_path8.join)((0, import_node_os.tmpdir)(), `kbdb-${contextId}.crash`);
|
|
2511
2625
|
try {
|
|
2512
2626
|
(0, import_node_fs6.unlinkSync)(crashPath);
|
|
2513
2627
|
} catch {
|
|
@@ -3028,10 +3142,10 @@ var WorkerClient = class {
|
|
|
3028
3142
|
|
|
3029
3143
|
// src/shared/worker-client/functions/resolve-db-path.function.ts
|
|
3030
3144
|
var import_node_fs7 = require("node:fs");
|
|
3031
|
-
var
|
|
3145
|
+
var import_node_path9 = require("node:path");
|
|
3032
3146
|
function resolveDbPath(targetDir) {
|
|
3033
|
-
const base = targetDir ? (0,
|
|
3034
|
-
const dbPath = (0,
|
|
3147
|
+
const base = targetDir ? (0, import_node_path9.resolve)(targetDir) : process.cwd();
|
|
3148
|
+
const dbPath = (0, import_node_path9.join)(base, ".kbdb");
|
|
3035
3149
|
if (!(0, import_node_fs7.existsSync)(dbPath)) {
|
|
3036
3150
|
const msg = `database not found: ${dbPath}`;
|
|
3037
3151
|
log(msg, 3 /* ERROR */);
|
|
@@ -3098,13 +3212,13 @@ function spawnDaemon(contextPath, runtime, workerScript) {
|
|
|
3098
3212
|
|
|
3099
3213
|
// src/shared/worker-client/functions/wait-for-daemon.function.ts
|
|
3100
3214
|
var import_node_fs8 = require("node:fs");
|
|
3101
|
-
var
|
|
3215
|
+
var import_node_path10 = require("node:path");
|
|
3102
3216
|
var import_node_os2 = require("node:os");
|
|
3103
3217
|
var DEFAULT_TIMEOUT_MS = 1e4;
|
|
3104
3218
|
var POLL_INTERVAL_MS = 100;
|
|
3105
3219
|
async function waitForDaemon(contextId, timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
3106
3220
|
log("waiting for daemon: contextId=" + contextId, 0 /* DEBUG */);
|
|
3107
|
-
const pidPath = (0,
|
|
3221
|
+
const pidPath = (0, import_node_path10.join)((0, import_node_os2.tmpdir)(), `kbdb-${contextId}.pid`);
|
|
3108
3222
|
const start = Date.now();
|
|
3109
3223
|
let iteration = 0;
|
|
3110
3224
|
while (Date.now() - start < timeoutMs) {
|
|
@@ -3132,10 +3246,10 @@ async function waitForDaemon(contextId, timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
|
3132
3246
|
|
|
3133
3247
|
// src/shared/worker-client/functions/read-crash-reason.function.ts
|
|
3134
3248
|
var import_node_fs9 = require("node:fs");
|
|
3135
|
-
var
|
|
3249
|
+
var import_node_path11 = require("node:path");
|
|
3136
3250
|
var import_node_os3 = require("node:os");
|
|
3137
3251
|
function readCrashReason(contextId) {
|
|
3138
|
-
const crashPath = (0,
|
|
3252
|
+
const crashPath = (0, import_node_path11.join)((0, import_node_os3.tmpdir)(), `kbdb-${contextId}.crash`);
|
|
3139
3253
|
if (!(0, import_node_fs9.existsSync)(crashPath)) {
|
|
3140
3254
|
return "daemon failed to start (no details available)";
|
|
3141
3255
|
}
|
|
@@ -3150,11 +3264,11 @@ function readCrashReason(contextId) {
|
|
|
3150
3264
|
}
|
|
3151
3265
|
|
|
3152
3266
|
// src/shared/worker-client/functions/resolve-spawn-script.function.ts
|
|
3153
|
-
var
|
|
3267
|
+
var import_node_path13 = require("node:path");
|
|
3154
3268
|
var import_node_url = require("node:url");
|
|
3155
3269
|
|
|
3156
3270
|
// src/shared/dir-resolver/functions/join-path.function.ts
|
|
3157
|
-
var
|
|
3271
|
+
var import_node_path12 = require("node:path");
|
|
3158
3272
|
function isRemoteUrl(path) {
|
|
3159
3273
|
return path.startsWith("http://") || path.startsWith("https://");
|
|
3160
3274
|
}
|
|
@@ -3163,7 +3277,7 @@ function joinPath(base, ...segments) {
|
|
|
3163
3277
|
const trailing = base.endsWith("/") ? "" : "/";
|
|
3164
3278
|
return base + trailing + segments.join("/");
|
|
3165
3279
|
}
|
|
3166
|
-
return (0,
|
|
3280
|
+
return (0, import_node_path12.join)(base, ...segments);
|
|
3167
3281
|
}
|
|
3168
3282
|
|
|
3169
3283
|
// src/shared/dir-resolver/functions/resolve-worker-script.function.ts
|
|
@@ -3181,15 +3295,15 @@ function resolveSpawnScript(runtime) {
|
|
|
3181
3295
|
}
|
|
3182
3296
|
function resolveScriptDir2(runtime) {
|
|
3183
3297
|
if (typeof __dirname !== "undefined") return __dirname;
|
|
3184
|
-
const thisDir = (0,
|
|
3298
|
+
const thisDir = (0, import_node_path13.dirname)((0, import_node_url.fileURLToPath)(import_meta.url));
|
|
3185
3299
|
if (runtime === "deno") {
|
|
3186
|
-
return (0,
|
|
3300
|
+
return (0, import_node_path13.resolve)(thisDir, "..", "..", "..");
|
|
3187
3301
|
}
|
|
3188
3302
|
return thisDir;
|
|
3189
3303
|
}
|
|
3190
3304
|
|
|
3191
3305
|
// src/shared/platform/functions/get-ipc-path.function.ts
|
|
3192
|
-
var
|
|
3306
|
+
var import_node_path14 = require("node:path");
|
|
3193
3307
|
|
|
3194
3308
|
// src/shared/platform/functions/get-tmpdir.function.ts
|
|
3195
3309
|
var import_node_os4 = require("node:os");
|
|
@@ -3202,7 +3316,7 @@ function getIpcPath(ctx) {
|
|
|
3202
3316
|
if (process.platform === "win32") {
|
|
3203
3317
|
return `\\\\.\\pipe\\kbdb-${ctx}`;
|
|
3204
3318
|
}
|
|
3205
|
-
return (0,
|
|
3319
|
+
return (0, import_node_path14.join)(getTmpdir(), `kbdb-${ctx}.sock`);
|
|
3206
3320
|
}
|
|
3207
3321
|
|
|
3208
3322
|
// src/shared/worker-client/functions/create-worker-client.function.ts
|
|
@@ -3670,7 +3784,7 @@ function createToolDefinitions() {
|
|
|
3670
3784
|
return [
|
|
3671
3785
|
{
|
|
3672
3786
|
name: "search",
|
|
3673
|
-
description: "Query the knowledge base by keywords. Returns ranked results with heading, snippet, and matched terms. Use multiple short keyword queries for best coverage. Use recall
|
|
3787
|
+
description: "Query the knowledge base by keywords. Returns ranked results with heading, snippet, and matched terms. Sections from the same document receive a sibling score boost when multiple sections match. Use multiple short keyword queries for best coverage. Use recall for full content.",
|
|
3674
3788
|
inputSchema: {
|
|
3675
3789
|
type: "object",
|
|
3676
3790
|
properties: {
|
|
@@ -3713,7 +3827,7 @@ function createToolDefinitions() {
|
|
|
3713
3827
|
},
|
|
3714
3828
|
{
|
|
3715
3829
|
name: "learn",
|
|
3716
|
-
description: "Import content into the knowledge base.
|
|
3830
|
+
description: "Import content into the knowledge base. Markdown content is automatically split on ATX headings into independent sections that share a docid. Providing title imports as a single section (skips splitting). Use replace when updating existing knowledge. Attach tags for scoping.",
|
|
3717
3831
|
inputSchema: {
|
|
3718
3832
|
type: "object",
|
|
3719
3833
|
properties: {
|
|
@@ -3727,7 +3841,7 @@ function createToolDefinitions() {
|
|
|
3727
3841
|
},
|
|
3728
3842
|
title: {
|
|
3729
3843
|
type: "string",
|
|
3730
|
-
description: "Section title. Required for image/* types."
|
|
3844
|
+
description: "Section title. Skips markdown splitting when set. Required for image/* types."
|
|
3731
3845
|
},
|
|
3732
3846
|
description: {
|
|
3733
3847
|
type: "string",
|
|
@@ -3735,7 +3849,7 @@ function createToolDefinitions() {
|
|
|
3735
3849
|
},
|
|
3736
3850
|
docid: {
|
|
3737
3851
|
type: "string",
|
|
3738
|
-
description: "Document ID to group under"
|
|
3852
|
+
description: "Document ID to group sections under. Set automatically when markdown splitting is active."
|
|
3739
3853
|
},
|
|
3740
3854
|
tags: {
|
|
3741
3855
|
type: "array",
|
|
@@ -3964,10 +4078,15 @@ function createToolDefinitions() {
|
|
|
3964
4078
|
},
|
|
3965
4079
|
{
|
|
3966
4080
|
name: "skill-list",
|
|
3967
|
-
description: "List
|
|
4081
|
+
description: "List skill definitions stored in the knowledge base, optionally filtered by a substring query.",
|
|
3968
4082
|
inputSchema: {
|
|
3969
4083
|
type: "object",
|
|
3970
|
-
properties: {
|
|
4084
|
+
properties: {
|
|
4085
|
+
query: {
|
|
4086
|
+
type: "string",
|
|
4087
|
+
description: "Case-insensitive substring filter on skill name or description."
|
|
4088
|
+
}
|
|
4089
|
+
}
|
|
3971
4090
|
},
|
|
3972
4091
|
annotations: {
|
|
3973
4092
|
title: "List Skills",
|
|
@@ -4058,10 +4177,15 @@ function createToolDefinitions() {
|
|
|
4058
4177
|
},
|
|
4059
4178
|
{
|
|
4060
4179
|
name: "agent-list",
|
|
4061
|
-
description: "List
|
|
4180
|
+
description: "List agent documents in the knowledge base, optionally filtered by a substring query.",
|
|
4062
4181
|
inputSchema: {
|
|
4063
4182
|
type: "object",
|
|
4064
|
-
properties: {
|
|
4183
|
+
properties: {
|
|
4184
|
+
query: {
|
|
4185
|
+
type: "string",
|
|
4186
|
+
description: "Case-insensitive substring filter on agent name or description."
|
|
4187
|
+
}
|
|
4188
|
+
}
|
|
4065
4189
|
},
|
|
4066
4190
|
annotations: {
|
|
4067
4191
|
title: "List Agents",
|
|
@@ -4309,7 +4433,7 @@ async function readAgentDescription(client, sections) {
|
|
|
4309
4433
|
return "";
|
|
4310
4434
|
}
|
|
4311
4435
|
}
|
|
4312
|
-
async function handleAgentList(client) {
|
|
4436
|
+
async function handleAgentList(client, args = {}) {
|
|
4313
4437
|
const docs = await client.listDocumentsByType("agent");
|
|
4314
4438
|
const items = await Promise.all(
|
|
4315
4439
|
docs.map(async (d) => ({
|
|
@@ -4317,17 +4441,17 @@ async function handleAgentList(client) {
|
|
|
4317
4441
|
description: await readAgentDescription(client, d.sections)
|
|
4318
4442
|
}))
|
|
4319
4443
|
);
|
|
4320
|
-
const
|
|
4321
|
-
|
|
4322
|
-
|
|
4323
|
-
const text = [`${String(items.length)} agents:`, ...lines].join(
|
|
4324
|
-
"\n"
|
|
4444
|
+
const query = typeof args["query"] === "string" ? args["query"].toLowerCase() : "";
|
|
4445
|
+
const filtered = items.filter(
|
|
4446
|
+
(item) => matchesQuery(query, item.name, item.description)
|
|
4325
4447
|
);
|
|
4448
|
+
const names = filtered.map((item) => item.name);
|
|
4449
|
+
const data = { items: names, total: names.length, offset: 0 };
|
|
4326
4450
|
return {
|
|
4327
4451
|
content: [
|
|
4328
4452
|
{
|
|
4329
4453
|
type: "text",
|
|
4330
|
-
text
|
|
4454
|
+
text: JSON.stringify(data, null, 2)
|
|
4331
4455
|
}
|
|
4332
4456
|
]
|
|
4333
4457
|
};
|
|
@@ -4629,7 +4753,7 @@ async function handleToolCall(client, name, args) {
|
|
|
4629
4753
|
case "skill-learn":
|
|
4630
4754
|
return await handleSkillLearn(client, args);
|
|
4631
4755
|
case "skill-list":
|
|
4632
|
-
return await handleSkillList(client);
|
|
4756
|
+
return await handleSkillList(client, args);
|
|
4633
4757
|
case "skill-get":
|
|
4634
4758
|
return await handleSkillGet(client, args);
|
|
4635
4759
|
case "skill-delete":
|
|
@@ -4637,7 +4761,7 @@ async function handleToolCall(client, name, args) {
|
|
|
4637
4761
|
case "agent-create":
|
|
4638
4762
|
return await handleAgentCreate(client, args);
|
|
4639
4763
|
case "agent-list":
|
|
4640
|
-
return await handleAgentList(client);
|
|
4764
|
+
return await handleAgentList(client, args);
|
|
4641
4765
|
case "agent-get":
|
|
4642
4766
|
return await handleAgentGet(client, args);
|
|
4643
4767
|
case "agent-delete":
|
|
@@ -4878,17 +5002,17 @@ async function handleSkillLearn(client, args) {
|
|
|
4878
5002
|
]
|
|
4879
5003
|
};
|
|
4880
5004
|
}
|
|
4881
|
-
async function handleSkillList(client) {
|
|
5005
|
+
async function handleSkillList(client, args) {
|
|
4882
5006
|
const records = await client.listByType("skill");
|
|
4883
|
-
const
|
|
4884
|
-
|
|
4885
|
-
|
|
4886
|
-
return `${String(index + 1)}. ${label} (${r.kbid})${desc}`;
|
|
4887
|
-
});
|
|
4888
|
-
const text = [`${String(records.length)} skills:`, ...lines].join(
|
|
4889
|
-
"\n"
|
|
5007
|
+
const query = typeof args["query"] === "string" ? args["query"].toLowerCase() : "";
|
|
5008
|
+
const filtered = records.filter(
|
|
5009
|
+
(r) => matchesQuery(query, r.title, r.description)
|
|
4890
5010
|
);
|
|
4891
|
-
|
|
5011
|
+
const names = filtered.map((r) => r.title ?? "");
|
|
5012
|
+
const data = { items: names, total: names.length, offset: 0 };
|
|
5013
|
+
return {
|
|
5014
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
|
|
5015
|
+
};
|
|
4892
5016
|
}
|
|
4893
5017
|
async function handleSkillGet(client, args) {
|
|
4894
5018
|
const kbid = typeof args["kbid"] === "string" ? args["kbid"] : void 0;
|
|
@@ -5924,7 +6048,7 @@ var deps = {
|
|
|
5924
6048
|
log("starting MCP server", 1 /* INFO */);
|
|
5925
6049
|
const client = await createWorkerClient({ contextPath });
|
|
5926
6050
|
try {
|
|
5927
|
-
const tomlPath = (0,
|
|
6051
|
+
const tomlPath = (0, import_node_path15.join)(contextPath, "worker.toml");
|
|
5928
6052
|
let autoCaptureConfig;
|
|
5929
6053
|
try {
|
|
5930
6054
|
const tomlText = (0, import_node_fs10.readFileSync)(tomlPath, "utf-8");
|