knowledge-mcp-server 1.0.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/CHANGELOG.md +11 -0
- package/LICENSE +21 -0
- package/README.md +205 -0
- package/dist/analytics.d.ts +24 -0
- package/dist/analytics.js +102 -0
- package/dist/analytics.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +98 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +39 -0
- package/dist/config.js +80 -0
- package/dist/config.js.map +1 -0
- package/dist/embeddings.d.ts +26 -0
- package/dist/embeddings.js +534 -0
- package/dist/embeddings.js.map +1 -0
- package/dist/formatter.d.ts +51 -0
- package/dist/formatter.js +273 -0
- package/dist/formatter.js.map +1 -0
- package/dist/generate-embeddings.d.ts +8 -0
- package/dist/generate-embeddings.js +146 -0
- package/dist/generate-embeddings.js.map +1 -0
- package/dist/graph.d.ts +20 -0
- package/dist/graph.js +133 -0
- package/dist/graph.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +481 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +1 -0
- package/dist/init.js +65 -0
- package/dist/init.js.map +1 -0
- package/dist/loader.d.ts +26 -0
- package/dist/loader.js +151 -0
- package/dist/loader.js.map +1 -0
- package/dist/logger.d.ts +6 -0
- package/dist/logger.js +15 -0
- package/dist/logger.js.map +1 -0
- package/dist/query-classifier.d.ts +23 -0
- package/dist/query-classifier.js +111 -0
- package/dist/query-classifier.js.map +1 -0
- package/dist/reranker.d.ts +7 -0
- package/dist/reranker.js +38 -0
- package/dist/reranker.js.map +1 -0
- package/dist/search.d.ts +17 -0
- package/dist/search.js +299 -0
- package/dist/search.js.map +1 -0
- package/dist/validator.d.ts +23 -0
- package/dist/validator.js +97 -0
- package/dist/validator.js.map +1 -0
- package/dist/writer.d.ts +36 -0
- package/dist/writer.js +360 -0
- package/dist/writer.js.map +1 -0
- package/package.json +58 -0
package/dist/loader.js
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { readFileSync, readdirSync, statSync } from "node:fs";
|
|
2
|
+
import { join, relative } from "node:path";
|
|
3
|
+
import { parse as parseYaml } from "yaml";
|
|
4
|
+
import { log } from "./logger.js";
|
|
5
|
+
function parseFrontmatter(raw) {
|
|
6
|
+
const match = raw.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
|
|
7
|
+
if (!match) {
|
|
8
|
+
return { frontmatter: {}, body: raw };
|
|
9
|
+
}
|
|
10
|
+
try {
|
|
11
|
+
const frontmatter = parseYaml(match[1]);
|
|
12
|
+
const body = match[2].trim();
|
|
13
|
+
return { frontmatter, body };
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return { frontmatter: {}, body: raw };
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export const VALID_TYPES = ["summary", "detail", "decision", "reference"];
|
|
20
|
+
export function deriveParentId(id) {
|
|
21
|
+
if (id === "root")
|
|
22
|
+
return null;
|
|
23
|
+
const segments = id.split("/");
|
|
24
|
+
if (segments.length <= 1)
|
|
25
|
+
return "root";
|
|
26
|
+
return segments.slice(0, -1).join("/");
|
|
27
|
+
}
|
|
28
|
+
export function collectMarkdownFiles(dir) {
|
|
29
|
+
const files = [];
|
|
30
|
+
const entries = readdirSync(dir);
|
|
31
|
+
for (const entry of entries) {
|
|
32
|
+
if (entry.startsWith("."))
|
|
33
|
+
continue;
|
|
34
|
+
const fullPath = join(dir, entry);
|
|
35
|
+
const stat = statSync(fullPath);
|
|
36
|
+
if (stat.isDirectory()) {
|
|
37
|
+
files.push(...collectMarkdownFiles(fullPath));
|
|
38
|
+
}
|
|
39
|
+
else if (entry.endsWith(".md")) {
|
|
40
|
+
files.push(fullPath);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return files;
|
|
44
|
+
}
|
|
45
|
+
const ID_PATTERN = /^[a-z][a-z0-9-]*(\/[a-z][a-z0-9-]*)*$/;
|
|
46
|
+
function validateFrontmatter(fm, filePath, validDomains) {
|
|
47
|
+
const warnings = [];
|
|
48
|
+
if (!fm.id) {
|
|
49
|
+
warnings.push(`${filePath}: missing required field 'id'`);
|
|
50
|
+
return warnings; // Can't validate further without ID
|
|
51
|
+
}
|
|
52
|
+
if (!ID_PATTERN.test(fm.id)) {
|
|
53
|
+
warnings.push(`${filePath}: invalid ID format "${fm.id}"`);
|
|
54
|
+
}
|
|
55
|
+
if (fm.domain && validDomains && !validDomains.includes(fm.domain)) {
|
|
56
|
+
warnings.push(`${filePath}: invalid domain "${fm.domain}"`);
|
|
57
|
+
}
|
|
58
|
+
if (fm.type && !VALID_TYPES.includes(fm.type)) {
|
|
59
|
+
warnings.push(`${filePath}: invalid type "${fm.type}"`);
|
|
60
|
+
}
|
|
61
|
+
const phases = fm.phase ? (Array.isArray(fm.phase) ? fm.phase : [fm.phase]) : [];
|
|
62
|
+
for (const p of phases) {
|
|
63
|
+
if (p < 1 || !Number.isInteger(p)) {
|
|
64
|
+
warnings.push(`${filePath}: invalid phase value ${p}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (fm.type === "decision" && !fm.decision_status) {
|
|
68
|
+
warnings.push(`${filePath}: decision document missing 'decision_status' field`);
|
|
69
|
+
}
|
|
70
|
+
return warnings;
|
|
71
|
+
}
|
|
72
|
+
export function loadDocuments(knowledgeDir, validDomains) {
|
|
73
|
+
const docs = new Map();
|
|
74
|
+
const files = collectMarkdownFiles(knowledgeDir);
|
|
75
|
+
const childrenFromFrontmatter = new Map();
|
|
76
|
+
for (const filePath of files) {
|
|
77
|
+
const raw = readFileSync(filePath, "utf-8");
|
|
78
|
+
const { frontmatter, body } = parseFrontmatter(raw);
|
|
79
|
+
// Validate schema
|
|
80
|
+
const validationWarnings = validateFrontmatter(frontmatter, filePath, validDomains);
|
|
81
|
+
if (validationWarnings.length > 0) {
|
|
82
|
+
for (const w of validationWarnings)
|
|
83
|
+
log.warn("schema_validation", { warning: w });
|
|
84
|
+
}
|
|
85
|
+
if (!frontmatter.id)
|
|
86
|
+
continue;
|
|
87
|
+
const id = frontmatter.id;
|
|
88
|
+
// Check for duplicate IDs
|
|
89
|
+
if (docs.has(id)) {
|
|
90
|
+
log.warn("duplicate_id", { id, file: filePath, existingFile: docs.get(id).filePath });
|
|
91
|
+
}
|
|
92
|
+
const phase = frontmatter.phase
|
|
93
|
+
? Array.isArray(frontmatter.phase)
|
|
94
|
+
? frontmatter.phase
|
|
95
|
+
: [frontmatter.phase]
|
|
96
|
+
: [];
|
|
97
|
+
if (frontmatter.children) {
|
|
98
|
+
childrenFromFrontmatter.set(id, frontmatter.children);
|
|
99
|
+
}
|
|
100
|
+
// Parse status: support both "status" and legacy "decision_status" fields
|
|
101
|
+
const rawStatus = frontmatter.status ||
|
|
102
|
+
(frontmatter.decision_status === "deprecated" ? "deprecated" : undefined);
|
|
103
|
+
const status = rawStatus === "draft" ? "draft" : rawStatus === "deprecated" ? "deprecated" : "active";
|
|
104
|
+
// Parse decision_status into typed enum value
|
|
105
|
+
const rawDecisionStatus = frontmatter.decision_status;
|
|
106
|
+
const validDecisionStatuses = ["proposed", "accepted", "deprecated", "superseded", "finalized"];
|
|
107
|
+
const decisionStatus = rawDecisionStatus && validDecisionStatuses.includes(rawDecisionStatus)
|
|
108
|
+
? rawDecisionStatus
|
|
109
|
+
: undefined;
|
|
110
|
+
const doc = {
|
|
111
|
+
id,
|
|
112
|
+
title: frontmatter.title || id,
|
|
113
|
+
type: frontmatter.type || "detail",
|
|
114
|
+
domain: frontmatter.domain || id.split("/")[0],
|
|
115
|
+
subdomain: frontmatter.subdomain,
|
|
116
|
+
tags: frontmatter.tags || [],
|
|
117
|
+
phase,
|
|
118
|
+
related: frontmatter.related || [],
|
|
119
|
+
parentId: deriveParentId(id),
|
|
120
|
+
childrenIds: [],
|
|
121
|
+
contentBody: body,
|
|
122
|
+
filePath: relative(join(knowledgeDir, ".."), filePath),
|
|
123
|
+
wordCount: frontmatter.word_count || body.split(/\s+/).filter(Boolean).length,
|
|
124
|
+
status,
|
|
125
|
+
supersededBy: frontmatter.superseded_by,
|
|
126
|
+
lastUpdated: frontmatter.last_updated,
|
|
127
|
+
decisionStatus,
|
|
128
|
+
alternativesConsidered: frontmatter.alternatives_considered,
|
|
129
|
+
decisionDate: frontmatter.decision_date,
|
|
130
|
+
};
|
|
131
|
+
docs.set(id, doc);
|
|
132
|
+
}
|
|
133
|
+
// Populate childrenIds from frontmatter `children` fields
|
|
134
|
+
for (const [parentId, children] of childrenFromFrontmatter) {
|
|
135
|
+
const parent = docs.get(parentId);
|
|
136
|
+
if (parent) {
|
|
137
|
+
parent.childrenIds = children.filter((c) => docs.has(c));
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
// For docs without explicit children, derive from parentId
|
|
141
|
+
for (const doc of docs.values()) {
|
|
142
|
+
if (doc.parentId && docs.has(doc.parentId)) {
|
|
143
|
+
const parent = docs.get(doc.parentId);
|
|
144
|
+
if (!parent.childrenIds.includes(doc.id)) {
|
|
145
|
+
parent.childrenIds.push(doc.id);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return docs;
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AA8ClC,SAAS,gBAAgB,CAAC,GAAW;IACnC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;IAC7D,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;IACxC,CAAC;IACD,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAmB,CAAC;QAC1D,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7B,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;IACxC,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,CAAU,CAAC;AAEnF,MAAM,UAAU,cAAc,CAAC,EAAU;IACvC,IAAI,EAAE,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IAC/B,MAAM,QAAQ,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,QAAQ,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,MAAM,CAAC;IACxC,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,GAAW;IAC9C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IACjC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAClC,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAChC,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YACvB,KAAK,CAAC,IAAI,CAAC,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC,CAAC;QAChD,CAAC;aAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACjC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,GAAG,uCAAuC,CAAC;AAE3D,SAAS,mBAAmB,CAC1B,EAAkB,EAClB,QAAgB,EAChB,YAA8B;IAE9B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACX,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,+BAA+B,CAAC,CAAC;QAC1D,OAAO,QAAQ,CAAC,CAAC,oCAAoC;IACvD,CAAC;IACD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;QAC5B,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,wBAAwB,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;IAC7D,CAAC;IACD,IAAI,EAAE,CAAC,MAAM,IAAI,YAAY,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC;QACnE,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,qBAAqB,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;IAC9D,CAAC;IACD,IAAI,EAAE,CAAC,IAAI,IAAI,CAAE,WAAiC,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACrE,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,mBAAmB,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC;IAC1D,CAAC;IACD,MAAM,MAAM,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACjF,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;YAClC,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,yBAAyB,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IACD,IAAI,EAAE,CAAC,IAAI,KAAK,UAAU,IAAI,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC;QAClD,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,qDAAqD,CAAC,CAAC;IAClF,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,YAAoB,EACpB,YAA8B;IAE9B,MAAM,IAAI,GAAG,IAAI,GAAG,EAA6B,CAAC;IAClD,MAAM,KAAK,GAAG,oBAAoB,CAAC,YAAY,CAAC,CAAC;IACjD,MAAM,uBAAuB,GAAG,IAAI,GAAG,EAAoB,CAAC;IAE5D,KAAK,MAAM,QAAQ,IAAI,KAAK,EAAE,CAAC;QAC7B,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC5C,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;QAEpD,kBAAkB;QAClB,MAAM,kBAAkB,GAAG,mBAAmB,CAAC,WAAW,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;QACpF,IAAI,kBAAkB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClC,KAAK,MAAM,CAAC,IAAI,kBAAkB;gBAAE,GAAG,CAAC,IAAI,CAAC,mBAAmB,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;QACpF,CAAC;QACD,IAAI,CAAC,WAAW,CAAC,EAAE;YAAE,SAAS;QAE9B,MAAM,EAAE,GAAG,WAAW,CAAC,EAAE,CAAC;QAE1B,0BAA0B;QAC1B,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YACjB,GAAG,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;QACzF,CAAC;QACD,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK;YAC7B,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC;gBAChC,CAAC,CAAC,WAAW,CAAC,KAAK;gBACnB,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC;YACvB,CAAC,CAAC,EAAE,CAAC;QAEP,IAAI,WAAW,CAAC,QAAQ,EAAE,CAAC;YACzB,uBAAuB,CAAC,GAAG,CAAC,EAAE,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;QACxD,CAAC;QAED,0EAA0E;QAC1E,MAAM,SAAS,GACb,WAAW,CAAC,MAAM;YAClB,CAAC,WAAW,CAAC,eAAe,KAAK,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC5E,MAAM,MAAM,GACV,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,KAAK,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC;QAEzF,8CAA8C;QAC9C,MAAM,iBAAiB,GAAG,WAAW,CAAC,eAAqC,CAAC;QAC5E,MAAM,qBAAqB,GAAG,CAAC,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC;QAChG,MAAM,cAAc,GAClB,iBAAiB,IAAI,qBAAqB,CAAC,QAAQ,CAAC,iBAAiB,CAAC;YACpE,CAAC,CAAE,iBAAyD;YAC5D,CAAC,CAAC,SAAS,CAAC;QAEhB,MAAM,GAAG,GAAsB;YAC7B,EAAE;YACF,KAAK,EAAE,WAAW,CAAC,KAAK,IAAI,EAAE;YAC9B,IAAI,EAAG,WAAW,CAAC,IAAkC,IAAI,QAAQ;YACjE,MAAM,EAAE,WAAW,CAAC,MAAM,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAC9C,SAAS,EAAE,WAAW,CAAC,SAAS;YAChC,IAAI,EAAE,WAAW,CAAC,IAAI,IAAI,EAAE;YAC5B,KAAK;YACL,OAAO,EAAE,WAAW,CAAC,OAAO,IAAI,EAAE;YAClC,QAAQ,EAAE,cAAc,CAAC,EAAE,CAAC;YAC5B,WAAW,EAAE,EAAE;YACf,WAAW,EAAE,IAAI;YACjB,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC;YACtD,SAAS,EAAE,WAAW,CAAC,UAAU,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM;YAC7E,MAAM;YACN,YAAY,EAAE,WAAW,CAAC,aAAa;YACvC,WAAW,EAAE,WAAW,CAAC,YAAY;YACrC,cAAc;YACd,sBAAsB,EAAE,WAAW,CAAC,uBAAuB;YAC3D,YAAY,EAAE,WAAW,CAAC,aAAa;SACxC,CAAC;QAEF,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IACpB,CAAC;IAED,0DAA0D;IAC1D,KAAK,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,uBAAuB,EAAE,CAAC;QAC3D,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAClC,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,CAAC,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAED,2DAA2D;IAC3D,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;QAChC,IAAI,GAAG,CAAC,QAAQ,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAE,CAAC;YACvC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;gBACzC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/dist/logger.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const log: {
|
|
2
|
+
debug: (event: string, data?: Record<string, unknown>) => void;
|
|
3
|
+
info: (event: string, data?: Record<string, unknown>) => void;
|
|
4
|
+
warn: (event: string, data?: Record<string, unknown>) => void;
|
|
5
|
+
error: (event: string, data?: Record<string, unknown>) => void;
|
|
6
|
+
};
|
package/dist/logger.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
const LEVELS = { debug: 0, info: 1, warn: 2, error: 3 };
|
|
2
|
+
const currentLevel = process.env.LOG_LEVEL in LEVELS ? process.env.LOG_LEVEL : "info";
|
|
3
|
+
function emit(level, event, data) {
|
|
4
|
+
if (LEVELS[level] < LEVELS[currentLevel])
|
|
5
|
+
return;
|
|
6
|
+
const entry = { ts: new Date().toISOString(), level, event, ...data };
|
|
7
|
+
process.stderr.write(JSON.stringify(entry) + "\n");
|
|
8
|
+
}
|
|
9
|
+
export const log = {
|
|
10
|
+
debug: (event, data) => emit("debug", event, data),
|
|
11
|
+
info: (event, data) => emit("info", event, data),
|
|
12
|
+
warn: (event, data) => emit("warn", event, data),
|
|
13
|
+
error: (event, data) => emit("error", event, data),
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAW,CAAC;AAGjE,MAAM,YAAY,GACf,OAAO,CAAC,GAAG,CAAC,SAAmB,IAAI,MAAM,CAAC,CAAC,CAAE,OAAO,CAAC,GAAG,CAAC,SAAmB,CAAC,CAAC,CAAC,MAAM,CAAC;AAEzF,SAAS,IAAI,CAAC,KAAY,EAAE,KAAa,EAAE,IAA8B;IACvE,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,YAAY,CAAC;QAAE,OAAO;IACjD,MAAM,KAAK,GAAG,EAAE,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,CAAC;IACtE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,CAAC,MAAM,GAAG,GAAG;IACjB,KAAK,EAAE,CAAC,KAAa,EAAE,IAA8B,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC;IACpF,IAAI,EAAE,CAAC,KAAa,EAAE,IAA8B,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC;IAClF,IAAI,EAAE,CAAC,KAAa,EAAE,IAA8B,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC;IAClF,KAAK,EAAE,CAAC,KAAa,EAAE,IAA8B,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC;CACrF,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { KnowledgeConfig } from "./config.js";
|
|
2
|
+
export interface QueryClassification {
|
|
3
|
+
domains: string[];
|
|
4
|
+
phases: number[];
|
|
5
|
+
queryType: "broad" | "specific" | "decision";
|
|
6
|
+
}
|
|
7
|
+
export interface ClassifierConfig {
|
|
8
|
+
domainKeywords: Record<string, string[]>;
|
|
9
|
+
phasePatterns: Array<{
|
|
10
|
+
pattern: RegExp;
|
|
11
|
+
phase: number;
|
|
12
|
+
dynamic?: boolean;
|
|
13
|
+
}>;
|
|
14
|
+
synonymMap: Record<string, string[]>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Build a ClassifierConfig from a KnowledgeConfig.
|
|
18
|
+
* When config is null (zero-config mode), returns empty config —
|
|
19
|
+
* search still works via BM25 + embeddings, just without domain pre-filtering.
|
|
20
|
+
*/
|
|
21
|
+
export declare function buildClassifierConfig(config: KnowledgeConfig | null): ClassifierConfig;
|
|
22
|
+
export declare function expandSynonyms(query: string, synonymMap: Record<string, string[]>): string;
|
|
23
|
+
export declare function classifyQuery(query: string, config: ClassifierConfig): QueryClassification;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
function escapeRegex(s) {
|
|
2
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* Build a ClassifierConfig from a KnowledgeConfig.
|
|
6
|
+
* When config is null (zero-config mode), returns empty config —
|
|
7
|
+
* search still works via BM25 + embeddings, just without domain pre-filtering.
|
|
8
|
+
*/
|
|
9
|
+
export function buildClassifierConfig(config) {
|
|
10
|
+
const domainKeywords = config?.query_hints ?? {};
|
|
11
|
+
// Always include generic "phase N" pattern (dynamic extraction)
|
|
12
|
+
const phasePatterns = [
|
|
13
|
+
{ pattern: /\bphase\s*(\d+)\b/i, phase: 0, dynamic: true },
|
|
14
|
+
];
|
|
15
|
+
// Add configured phase name + alias patterns
|
|
16
|
+
if (config?.phases) {
|
|
17
|
+
for (const p of config.phases) {
|
|
18
|
+
phasePatterns.push({
|
|
19
|
+
pattern: new RegExp(`\\b${escapeRegex(p.name)}\\b`, "i"),
|
|
20
|
+
phase: p.id,
|
|
21
|
+
});
|
|
22
|
+
if (p.aliases) {
|
|
23
|
+
for (const alias of p.aliases) {
|
|
24
|
+
phasePatterns.push({
|
|
25
|
+
pattern: new RegExp(`\\b${escapeRegex(alias)}\\b`, "i"),
|
|
26
|
+
phase: p.id,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const synonymMap = config?.synonyms ?? {};
|
|
33
|
+
return { domainKeywords, phasePatterns, synonymMap };
|
|
34
|
+
}
|
|
35
|
+
// These are linguistically universal — not project-specific
|
|
36
|
+
const DECISION_KEYWORDS = [
|
|
37
|
+
"why did we",
|
|
38
|
+
"why do we",
|
|
39
|
+
"decision",
|
|
40
|
+
"chose",
|
|
41
|
+
"choose",
|
|
42
|
+
"trade-off",
|
|
43
|
+
"tradeoff",
|
|
44
|
+
"vs",
|
|
45
|
+
"versus",
|
|
46
|
+
"compared to",
|
|
47
|
+
"alternative",
|
|
48
|
+
"rationale",
|
|
49
|
+
];
|
|
50
|
+
export function expandSynonyms(query, synonymMap) {
|
|
51
|
+
const lower = query.toLowerCase();
|
|
52
|
+
const tokens = lower.split(/\s+/);
|
|
53
|
+
const expansions = [];
|
|
54
|
+
for (const token of tokens) {
|
|
55
|
+
const clean = token.replace(/[^a-z0-9-]/g, "");
|
|
56
|
+
const synonyms = synonymMap[clean];
|
|
57
|
+
if (synonyms) {
|
|
58
|
+
expansions.push(...synonyms);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (expansions.length === 0)
|
|
62
|
+
return query;
|
|
63
|
+
return `${query} ${expansions.join(" ")}`;
|
|
64
|
+
}
|
|
65
|
+
export function classifyQuery(query, config) {
|
|
66
|
+
const lower = query.toLowerCase();
|
|
67
|
+
const domains = [];
|
|
68
|
+
const phases = [];
|
|
69
|
+
// Domain classification from config keywords
|
|
70
|
+
for (const [domain, keywords] of Object.entries(config.domainKeywords)) {
|
|
71
|
+
for (const kw of keywords) {
|
|
72
|
+
if (lower.includes(kw.toLowerCase())) {
|
|
73
|
+
if (!domains.includes(domain)) {
|
|
74
|
+
domains.push(domain);
|
|
75
|
+
}
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Phase detection
|
|
81
|
+
for (const { pattern, phase, dynamic } of config.phasePatterns) {
|
|
82
|
+
if (dynamic) {
|
|
83
|
+
// Dynamic "phase N" pattern — extract the number
|
|
84
|
+
const match = pattern.exec(lower);
|
|
85
|
+
if (match) {
|
|
86
|
+
const n = parseInt(match[1], 10);
|
|
87
|
+
if (n > 0 && !phases.includes(n)) {
|
|
88
|
+
phases.push(n);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
else if (pattern.test(lower) && !phases.includes(phase)) {
|
|
93
|
+
phases.push(phase);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Query type detection (universal heuristics, not project-specific)
|
|
97
|
+
let queryType = "specific";
|
|
98
|
+
if (DECISION_KEYWORDS.some((kw) => lower.includes(kw))) {
|
|
99
|
+
queryType = "decision";
|
|
100
|
+
}
|
|
101
|
+
else if (lower.startsWith("how does") ||
|
|
102
|
+
lower.startsWith("what is") ||
|
|
103
|
+
lower.startsWith("overview") ||
|
|
104
|
+
lower.startsWith("explain") ||
|
|
105
|
+
lower.includes("tell me about") ||
|
|
106
|
+
domains.length === 0) {
|
|
107
|
+
queryType = "broad";
|
|
108
|
+
}
|
|
109
|
+
return { domains, phases, queryType };
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=query-classifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-classifier.js","sourceRoot":"","sources":["../src/query-classifier.ts"],"names":[],"mappings":"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"}
|
package/dist/reranker.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { tokenize } from "./embeddings.js";
|
|
2
|
+
const SIX_MONTHS_MS = 180 * 24 * 60 * 60 * 1000;
|
|
3
|
+
export function rerank(docs, query, queryType) {
|
|
4
|
+
if (docs.length === 0)
|
|
5
|
+
return docs;
|
|
6
|
+
const queryLower = query.toLowerCase().trim();
|
|
7
|
+
const queryTokens = tokenize(query);
|
|
8
|
+
const queryTokenSet = new Set(queryTokens);
|
|
9
|
+
const now = Date.now();
|
|
10
|
+
return docs
|
|
11
|
+
.map(({ doc, score }) => {
|
|
12
|
+
let adjusted = score;
|
|
13
|
+
// Title match bonus: query tokens found in title
|
|
14
|
+
const titleTokens = tokenize(doc.title);
|
|
15
|
+
const titleOverlap = titleTokens.filter((t) => queryTokenSet.has(t)).length;
|
|
16
|
+
if (titleOverlap > 0) {
|
|
17
|
+
adjusted += 0.15 * (titleOverlap / Math.max(queryTokenSet.size, 1));
|
|
18
|
+
}
|
|
19
|
+
// Decision-type boost when query is decision-oriented
|
|
20
|
+
if (queryType === "decision" && doc.type === "decision") {
|
|
21
|
+
adjusted += 0.1;
|
|
22
|
+
}
|
|
23
|
+
// Staleness penalty: docs older than 6 months get a small penalty
|
|
24
|
+
if (doc.lastUpdated) {
|
|
25
|
+
const docDate = new Date(doc.lastUpdated).getTime();
|
|
26
|
+
if (!isNaN(docDate) && now - docDate > SIX_MONTHS_MS) {
|
|
27
|
+
adjusted -= 0.05;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// Exact phrase bonus: query substring appears in content body
|
|
31
|
+
if (queryLower.length > 3 && doc.contentBody.toLowerCase().includes(queryLower)) {
|
|
32
|
+
adjusted += 0.1;
|
|
33
|
+
}
|
|
34
|
+
return { doc, score: adjusted };
|
|
35
|
+
})
|
|
36
|
+
.sort((a, b) => b.score - a.score);
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=reranker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reranker.js","sourceRoot":"","sources":["../src/reranker.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAO3C,MAAM,aAAa,GAAG,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAEhD,MAAM,UAAU,MAAM,CACpB,IAAiB,EACjB,KAAa,EACb,SAA4C;IAE5C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEnC,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;IAC9C,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACpC,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC;IAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEvB,OAAO,IAAI;SACR,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE;QACtB,IAAI,QAAQ,GAAG,KAAK,CAAC;QAErB,iDAAiD;QACjD,MAAM,WAAW,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACxC,MAAM,YAAY,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QAC5E,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;YACrB,QAAQ,IAAI,IAAI,GAAG,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACtE,CAAC;QAED,sDAAsD;QACtD,IAAI,SAAS,KAAK,UAAU,IAAI,GAAG,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YACxD,QAAQ,IAAI,GAAG,CAAC;QAClB,CAAC;QAED,kEAAkE;QAClE,IAAI,GAAG,CAAC,WAAW,EAAE,CAAC;YACpB,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,OAAO,EAAE,CAAC;YACpD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,GAAG,GAAG,OAAO,GAAG,aAAa,EAAE,CAAC;gBACrD,QAAQ,IAAI,IAAI,CAAC;YACnB,CAAC;QACH,CAAC;QAED,8DAA8D;QAC9D,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YAChF,QAAQ,IAAI,GAAG,CAAC;QAClB,CAAC;QAED,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClC,CAAC,CAAC;SACD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;AACvC,CAAC"}
|
package/dist/search.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { KnowledgeGraph } from "./graph.js";
|
|
2
|
+
import { type ClassifierConfig } from "./query-classifier.js";
|
|
3
|
+
import { type Bm25Index } from "./embeddings.js";
|
|
4
|
+
import { type DetailLevel } from "./formatter.js";
|
|
5
|
+
export type TfIdfIndex = Bm25Index;
|
|
6
|
+
interface SearchOptions {
|
|
7
|
+
query: string;
|
|
8
|
+
domains?: string[];
|
|
9
|
+
phases?: number[];
|
|
10
|
+
tags?: string[];
|
|
11
|
+
type?: string;
|
|
12
|
+
maxResults?: number;
|
|
13
|
+
detailLevel?: DetailLevel;
|
|
14
|
+
includeDrafts?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export declare function knowledgeSearch(graph: KnowledgeGraph, bm25Index: Bm25Index, options: SearchOptions, classifierConfig: ClassifierConfig): Promise<string>;
|
|
17
|
+
export {};
|