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.
Files changed (52) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/LICENSE +21 -0
  3. package/README.md +205 -0
  4. package/dist/analytics.d.ts +24 -0
  5. package/dist/analytics.js +102 -0
  6. package/dist/analytics.js.map +1 -0
  7. package/dist/cli.d.ts +2 -0
  8. package/dist/cli.js +98 -0
  9. package/dist/cli.js.map +1 -0
  10. package/dist/config.d.ts +39 -0
  11. package/dist/config.js +80 -0
  12. package/dist/config.js.map +1 -0
  13. package/dist/embeddings.d.ts +26 -0
  14. package/dist/embeddings.js +534 -0
  15. package/dist/embeddings.js.map +1 -0
  16. package/dist/formatter.d.ts +51 -0
  17. package/dist/formatter.js +273 -0
  18. package/dist/formatter.js.map +1 -0
  19. package/dist/generate-embeddings.d.ts +8 -0
  20. package/dist/generate-embeddings.js +146 -0
  21. package/dist/generate-embeddings.js.map +1 -0
  22. package/dist/graph.d.ts +20 -0
  23. package/dist/graph.js +133 -0
  24. package/dist/graph.js.map +1 -0
  25. package/dist/index.d.ts +14 -0
  26. package/dist/index.js +481 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/init.d.ts +1 -0
  29. package/dist/init.js +65 -0
  30. package/dist/init.js.map +1 -0
  31. package/dist/loader.d.ts +26 -0
  32. package/dist/loader.js +151 -0
  33. package/dist/loader.js.map +1 -0
  34. package/dist/logger.d.ts +6 -0
  35. package/dist/logger.js +15 -0
  36. package/dist/logger.js.map +1 -0
  37. package/dist/query-classifier.d.ts +23 -0
  38. package/dist/query-classifier.js +111 -0
  39. package/dist/query-classifier.js.map +1 -0
  40. package/dist/reranker.d.ts +7 -0
  41. package/dist/reranker.js +38 -0
  42. package/dist/reranker.js.map +1 -0
  43. package/dist/search.d.ts +17 -0
  44. package/dist/search.js +299 -0
  45. package/dist/search.js.map +1 -0
  46. package/dist/validator.d.ts +23 -0
  47. package/dist/validator.js +97 -0
  48. package/dist/validator.js.map +1 -0
  49. package/dist/writer.d.ts +36 -0
  50. package/dist/writer.js +360 -0
  51. package/dist/writer.js.map +1 -0
  52. package/package.json +58 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,11 @@
1
+ # Changelog
2
+
3
+ ## 1.0.0
4
+
5
+ Initial release. Extracted from guitar-app project.
6
+
7
+ - MCP server with 8 tools: search, lookup, graph, list, write, delete, validate, stats
8
+ - BM25 full-text search with optional Voyage AI vector embeddings (hybrid RRF fusion)
9
+ - CLI with subcommands: serve, embeddings, init, validate
10
+ - Zero-config mode (works without knowledge.config.yaml)
11
+ - Programmatic API via `createKnowledgeServer()`
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ross Sheridan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,205 @@
1
+ # knowledge-mcp-server
2
+
3
+ MCP server for semantic search, CRUD, and graph operations over hierarchical knowledge bases stored as Markdown with YAML frontmatter.
4
+
5
+ Provides 8 tools via [Model Context Protocol](https://modelcontextprotocol.io/): `knowledge_search`, `knowledge_lookup`, `knowledge_graph`, `knowledge_list`, `knowledge_write`, `knowledge_delete`, `knowledge_validate`, and `knowledge_stats`.
6
+
7
+ ## Quick Start
8
+
9
+ ```bash
10
+ # Initialize a new knowledge directory
11
+ npx knowledge-mcp-server init
12
+
13
+ # Start the MCP server
14
+ npx knowledge-mcp-server
15
+ ```
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ npm install knowledge-mcp-server
21
+ ```
22
+
23
+ ## Claude Code Integration
24
+
25
+ Add to your `.mcp.json`:
26
+
27
+ ```json
28
+ {
29
+ "mcpServers": {
30
+ "knowledge": {
31
+ "type": "stdio",
32
+ "command": "npx",
33
+ "args": ["knowledge-mcp-server", "--knowledge-dir", "./knowledge"],
34
+ "env": {
35
+ "VOYAGE_API_KEY": "${VOYAGE_API_KEY}"
36
+ }
37
+ }
38
+ }
39
+ }
40
+ ```
41
+
42
+ The `VOYAGE_API_KEY` is optional — without it, the server uses BM25 full-text search only. With it, search results are improved via hybrid BM25 + vector scoring with Reciprocal Rank Fusion.
43
+
44
+ ## CLI Reference
45
+
46
+ ```
47
+ knowledge-mcp-server [command] [options]
48
+
49
+ Commands:
50
+ serve Start the MCP server over stdio (default)
51
+ embeddings Generate embeddings for all documents via Voyage AI
52
+ init Scaffold a new knowledge/ directory with config template
53
+ validate Run graph integrity checks and report issues
54
+
55
+ Options:
56
+ --knowledge-dir <path> Path to knowledge directory (default: ./knowledge)
57
+ --help, -h Show help
58
+ --version Show version
59
+ ```
60
+
61
+ ### Generate Embeddings
62
+
63
+ ```bash
64
+ VOYAGE_API_KEY=your-key npx knowledge-mcp-server embeddings
65
+ ```
66
+
67
+ Uses incremental hashing — only re-embeds documents whose content has changed.
68
+
69
+ ### Validate Graph
70
+
71
+ ```bash
72
+ npx knowledge-mcp-server validate
73
+ ```
74
+
75
+ Checks for: orphaned documents, broken references, circular parents, missing tags, empty summaries, stale documents (>6 months), and embedding coverage. Exits with code 1 if integrity issues are found.
76
+
77
+ ## Programmatic API
78
+
79
+ ```typescript
80
+ import { createKnowledgeServer } from "knowledge-mcp-server";
81
+
82
+ const { server, graph, tfidfIndex, config } = createKnowledgeServer("./knowledge");
83
+ ```
84
+
85
+ ### Exported Types
86
+
87
+ ```typescript
88
+ import type {
89
+ KnowledgeServerResult,
90
+ KnowledgeGraph,
91
+ KnowledgeDocument,
92
+ KnowledgeConfig,
93
+ } from "knowledge-mcp-server";
94
+ ```
95
+
96
+ ## Document Format
97
+
98
+ Knowledge documents are Markdown files with YAML frontmatter:
99
+
100
+ ```markdown
101
+ ---
102
+ id: technology/audio-detection/pitch-detection
103
+ title: Pitch Detection Pipeline
104
+ type: detail
105
+ domain: technology
106
+ subdomain: audio-detection
107
+ tags: [audio, ml, crepe, yin]
108
+ phase: [1]
109
+ related: [technology/audio-detection/chord-recognition]
110
+ ---
111
+
112
+ Your document content here in Markdown.
113
+ ```
114
+
115
+ ### Frontmatter Fields
116
+
117
+ | Field | Required | Description |
118
+ |-------|----------|-------------|
119
+ | `id` | yes | Unique document ID (lowercase, hyphens, slashes) |
120
+ | `title` | yes | Human-readable title |
121
+ | `type` | yes | `summary`, `detail`, `decision`, or `reference` |
122
+ | `domain` | yes | Top-level domain |
123
+ | `subdomain` | no | Subdomain within the domain |
124
+ | `tags` | yes | Array of searchable tags |
125
+ | `phase` | yes | Array of applicable phase numbers |
126
+ | `related` | no | Array of related document IDs |
127
+ | `status` | no | `active` (default), `draft`, or `deprecated` |
128
+
129
+ ### Directory Structure
130
+
131
+ ```
132
+ knowledge/
133
+ ├── knowledge.config.yaml # Configuration (optional)
134
+ ├── _summary.md # Root node
135
+ ├── .embeddings.json # Generated embeddings (optional)
136
+ ├── .embeddings-hashes.json # Content hashes for change detection
137
+ ├── .tags.json # Tag taxonomy (optional)
138
+ ├── technology/
139
+ │ ├── _summary.md
140
+ │ └── audio-detection/
141
+ │ ├── _summary.md
142
+ │ └── pitch-detection.md
143
+ └── business/
144
+ ├── _summary.md
145
+ └── pricing-tiers.md
146
+ ```
147
+
148
+ ## Configuration
149
+
150
+ `knowledge.config.yaml` is optional. Without it, the server runs in zero-config mode (permissive validation, auto-discovered domains).
151
+
152
+ ```yaml
153
+ name: "my-project"
154
+
155
+ # Strict domain validation (only these domains are accepted)
156
+ domains:
157
+ - technology
158
+ - architecture
159
+ - business
160
+
161
+ # Phase definitions with optional aliases
162
+ phases:
163
+ - id: 1
164
+ name: "Foundation"
165
+ aliases: ["launch", "mvp"]
166
+ - id: 2
167
+ name: "Growth"
168
+
169
+ # Query hints for domain classification
170
+ query_hints:
171
+ technology: ["api", "database", "framework", "library"]
172
+ business: ["pricing", "revenue", "market"]
173
+
174
+ # Synonym expansion for search
175
+ synonyms:
176
+ ml: ["machine learning"]
177
+ ai: ["artificial intelligence"]
178
+ dkt: ["deep knowledge tracing"]
179
+
180
+ # Embedding configuration
181
+ embeddings:
182
+ provider: "voyage"
183
+ model: "voyage-3-lite"
184
+ api_key_env: "VOYAGE_API_KEY"
185
+ ```
186
+
187
+ ## Search Architecture
188
+
189
+ The search pipeline uses a 4-stage hybrid approach:
190
+
191
+ 1. **Query Classification** — extracts domains, phases, and query type from natural language
192
+ 2. **Metadata Pre-filter** — O(1) lookups via in-memory indices (domain, phase, tag, type)
193
+ 3. **Hybrid Scoring** — BM25 full-text search (k1=1.2, b=0.75, title 3x boost) + optional Voyage AI vector embeddings, merged via Reciprocal Rank Fusion (RRF, k=60)
194
+ 4. **Hierarchical Expansion** — includes ancestor documents and cross-references within a word budget
195
+
196
+ ## Environment Variables
197
+
198
+ | Variable | Required | Description |
199
+ |----------|----------|-------------|
200
+ | `VOYAGE_API_KEY` | No | Voyage AI API key for semantic embeddings |
201
+ | `LOG_LEVEL` | No | Logging verbosity: `debug`, `info` (default), `warn`, `error` |
202
+
203
+ ## License
204
+
205
+ MIT
@@ -0,0 +1,24 @@
1
+ import type { KnowledgeGraph } from "./graph.js";
2
+ export interface GraphStats {
3
+ totalDocs: number;
4
+ byType: Map<string, number>;
5
+ byDomain: Map<string, number>;
6
+ byPhase: Map<string, number>;
7
+ topTags: Array<{
8
+ tag: string;
9
+ count: number;
10
+ }>;
11
+ crossLinkDensity: number;
12
+ mostConnected: Array<{
13
+ id: string;
14
+ connections: number;
15
+ }>;
16
+ orphanCount: number;
17
+ embeddingCoverage: {
18
+ total: number;
19
+ covered: number;
20
+ percent: number;
21
+ };
22
+ }
23
+ export declare function computeStats(graph: KnowledgeGraph): GraphStats;
24
+ export declare function formatStats(stats: GraphStats): string;
@@ -0,0 +1,102 @@
1
+ export function computeStats(graph) {
2
+ const byType = new Map();
3
+ const byDomain = new Map();
4
+ const byPhase = new Map();
5
+ const tagCounts = new Map();
6
+ const connectionCounts = new Map();
7
+ let totalRelated = 0;
8
+ let orphanCount = 0;
9
+ for (const doc of graph.documents.values()) {
10
+ // By type
11
+ byType.set(doc.type, (byType.get(doc.type) || 0) + 1);
12
+ // By domain
13
+ byDomain.set(doc.domain, (byDomain.get(doc.domain) || 0) + 1);
14
+ // By phase
15
+ for (const p of doc.phase) {
16
+ const key = `phase-${p}`;
17
+ byPhase.set(key, (byPhase.get(key) || 0) + 1);
18
+ }
19
+ // Tag counts
20
+ for (const tag of doc.tags) {
21
+ const lower = tag.toLowerCase();
22
+ tagCounts.set(lower, (tagCounts.get(lower) || 0) + 1);
23
+ }
24
+ // Connection counts (forward related + backlinks)
25
+ const forwardCount = doc.related.length;
26
+ const backlinks = graph.backlinkIndex.get(doc.id);
27
+ const backlinkCount = backlinks ? backlinks.size : 0;
28
+ const total = forwardCount + backlinkCount;
29
+ connectionCounts.set(doc.id, total);
30
+ totalRelated += forwardCount;
31
+ // Orphan: no related links in or out
32
+ if (forwardCount === 0 && backlinkCount === 0) {
33
+ orphanCount++;
34
+ }
35
+ }
36
+ // Top 20 tags by frequency
37
+ const topTags = [...tagCounts.entries()]
38
+ .sort((a, b) => b[1] - a[1])
39
+ .slice(0, 20)
40
+ .map(([tag, count]) => ({ tag, count }));
41
+ // Most connected docs (top 5)
42
+ const mostConnected = [...connectionCounts.entries()]
43
+ .sort((a, b) => b[1] - a[1])
44
+ .slice(0, 5)
45
+ .map(([id, connections]) => ({ id, connections }));
46
+ // Cross-link density
47
+ const totalDocs = graph.documents.size;
48
+ const crossLinkDensity = totalDocs > 0 ? Math.round((totalRelated / totalDocs) * 100) / 100 : 0;
49
+ // Embedding coverage
50
+ const covered = [...graph.documents.keys()].filter((id) => graph.embeddings.vectors.has(id)).length;
51
+ return {
52
+ totalDocs,
53
+ byType,
54
+ byDomain,
55
+ byPhase,
56
+ topTags,
57
+ crossLinkDensity,
58
+ mostConnected,
59
+ orphanCount,
60
+ embeddingCoverage: {
61
+ total: totalDocs,
62
+ covered,
63
+ percent: totalDocs > 0 ? Math.round((covered / totalDocs) * 100) : 0,
64
+ },
65
+ };
66
+ }
67
+ export function formatStats(stats) {
68
+ const lines = ["Knowledge Graph Statistics", "=".repeat(26), ""];
69
+ lines.push(`Total documents: ${stats.totalDocs}`);
70
+ lines.push("");
71
+ lines.push("By type:");
72
+ for (const [type, count] of [...stats.byType].sort((a, b) => b[1] - a[1])) {
73
+ lines.push(` ${type}: ${count}`);
74
+ }
75
+ lines.push("");
76
+ lines.push("By domain:");
77
+ for (const [domain, count] of [...stats.byDomain].sort((a, b) => b[1] - a[1])) {
78
+ lines.push(` ${domain}: ${count}`);
79
+ }
80
+ lines.push("");
81
+ lines.push("By phase:");
82
+ for (const [phase, count] of [...stats.byPhase].sort()) {
83
+ lines.push(` ${phase}: ${count}`);
84
+ }
85
+ lines.push("");
86
+ lines.push("Top tags:");
87
+ for (const { tag, count } of stats.topTags) {
88
+ lines.push(` ${tag}: ${count}`);
89
+ }
90
+ lines.push("");
91
+ lines.push(`Cross-link density: ${stats.crossLinkDensity} related links/doc (avg)`);
92
+ lines.push(`Unlinked documents: ${stats.orphanCount}`);
93
+ lines.push("");
94
+ lines.push("Most connected documents:");
95
+ for (const { id, connections } of stats.mostConnected) {
96
+ lines.push(` ${id}: ${connections} connections`);
97
+ }
98
+ lines.push("");
99
+ lines.push(`Embedding coverage: ${stats.embeddingCoverage.covered}/${stats.embeddingCoverage.total} (${stats.embeddingCoverage.percent}%)`);
100
+ return lines.join("\n");
101
+ }
102
+ //# sourceMappingURL=analytics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics.js","sourceRoot":"","sources":["../src/analytics.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env node
2
+ import { resolve } from "node:path";
3
+ import { existsSync } from "node:fs";
4
+ import { createKnowledgeServer } from "./index.js";
5
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
6
+ import { buildGraph } from "./graph.js";
7
+ import { validateGraph, formatValidationReport } from "./validator.js";
8
+ import { loadConfig, getEffectiveDomains } from "./config.js";
9
+ import { generateEmbeddings } from "./generate-embeddings.js";
10
+ import { initKnowledgeDir } from "./init.js";
11
+ import { log } from "./logger.js";
12
+ const VERSION = "1.0.0";
13
+ const COMMANDS = ["serve", "embeddings", "init", "validate"];
14
+ function printUsage() {
15
+ console.log(`knowledge-mcp-server v${VERSION}
16
+
17
+ Usage: knowledge-mcp-server [command] [options]
18
+
19
+ Commands:
20
+ serve Start the MCP server over stdio (default)
21
+ embeddings Generate embeddings for all documents via Voyage AI
22
+ init Scaffold a new knowledge/ directory with config template
23
+ validate Run graph integrity checks and report issues
24
+
25
+ Options:
26
+ --knowledge-dir <path> Path to knowledge directory (default: ./knowledge)
27
+ --help, -h Show this help message
28
+ --version Show version number`);
29
+ }
30
+ function parseArgs(argv) {
31
+ const args = argv.slice(2);
32
+ let command = "serve";
33
+ let knowledgeDir = resolve(process.cwd(), "knowledge");
34
+ // First non-flag argument is the command
35
+ if (args[0] && !args[0].startsWith("-") && COMMANDS.includes(args[0])) {
36
+ command = args.shift();
37
+ }
38
+ for (let i = 0; i < args.length; i++) {
39
+ if (args[i] === "--knowledge-dir" && args[i + 1]) {
40
+ knowledgeDir = resolve(args[++i]);
41
+ }
42
+ else if (args[i] === "--help" || args[i] === "-h") {
43
+ printUsage();
44
+ process.exit(0);
45
+ }
46
+ else if (args[i] === "--version") {
47
+ console.log(VERSION);
48
+ process.exit(0);
49
+ }
50
+ }
51
+ return { command, knowledgeDir };
52
+ }
53
+ async function serve(knowledgeDir) {
54
+ const { server } = createKnowledgeServer(knowledgeDir);
55
+ const transport = new StdioServerTransport();
56
+ await server.connect(transport);
57
+ log.info("server_started", { transport: "stdio" });
58
+ }
59
+ function validate(knowledgeDir) {
60
+ if (!existsSync(knowledgeDir)) {
61
+ console.error(`Error: Knowledge directory not found: ${knowledgeDir}`);
62
+ process.exit(1);
63
+ }
64
+ const config = loadConfig(knowledgeDir);
65
+ const validDomains = getEffectiveDomains(config, knowledgeDir);
66
+ const graph = buildGraph(knowledgeDir, validDomains);
67
+ const report = validateGraph(graph);
68
+ console.log(formatValidationReport(report));
69
+ const hasIssues = report.orphans.length > 0 ||
70
+ report.brokenRelated.length > 0 ||
71
+ report.brokenChildren.length > 0 ||
72
+ report.circularParents.length > 0;
73
+ if (hasIssues) {
74
+ process.exit(1);
75
+ }
76
+ }
77
+ async function main() {
78
+ const { command, knowledgeDir } = parseArgs(process.argv);
79
+ switch (command) {
80
+ case "serve":
81
+ await serve(knowledgeDir);
82
+ break;
83
+ case "embeddings":
84
+ await generateEmbeddings(knowledgeDir);
85
+ break;
86
+ case "init":
87
+ initKnowledgeDir(knowledgeDir);
88
+ break;
89
+ case "validate":
90
+ validate(knowledgeDir);
91
+ break;
92
+ }
93
+ }
94
+ main().catch((err) => {
95
+ log.error("fatal", { error: String(err) });
96
+ process.exit(1);
97
+ });
98
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ export interface PhaseConfig {
2
+ id: number;
3
+ name: string;
4
+ aliases?: string[];
5
+ }
6
+ export interface KnowledgeConfig {
7
+ name?: string;
8
+ domains?: string[];
9
+ phases?: PhaseConfig[];
10
+ query_hints?: Record<string, string[]>;
11
+ synonyms?: Record<string, string[]>;
12
+ embeddings?: {
13
+ provider?: string;
14
+ model?: string;
15
+ api_key_env?: string;
16
+ };
17
+ }
18
+ /**
19
+ * Load knowledge.config.yaml from the knowledge directory root.
20
+ * Returns null if the file is missing or invalid.
21
+ */
22
+ export declare function loadConfig(knowledgeDir: string): KnowledgeConfig | null;
23
+ /**
24
+ * Discover domains by scanning top-level directories in the knowledge directory.
25
+ * Excludes directories starting with ".".
26
+ */
27
+ export declare function discoverDomains(knowledgeDir: string): string[];
28
+ /**
29
+ * Return the effective domain list for validation.
30
+ * - If config specifies domains, return them (strict validation).
31
+ * - Otherwise return null (permissive — accept any domain).
32
+ */
33
+ export declare function getEffectiveDomains(config: KnowledgeConfig | null, _knowledgeDir: string): string[] | null;
34
+ /**
35
+ * Return the effective phase IDs for validation.
36
+ * - If config specifies phases, return their IDs (strict validation).
37
+ * - Otherwise return null (permissive — accept any positive integer).
38
+ */
39
+ export declare function getEffectivePhaseIds(config: KnowledgeConfig | null): number[] | null;
package/dist/config.js ADDED
@@ -0,0 +1,80 @@
1
+ import { readFileSync, readdirSync, statSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { parse as parseYaml } from "yaml";
4
+ import { log } from "./logger.js";
5
+ const CONFIG_FILENAME = "knowledge.config.yaml";
6
+ /**
7
+ * Load knowledge.config.yaml from the knowledge directory root.
8
+ * Returns null if the file is missing or invalid.
9
+ */
10
+ export function loadConfig(knowledgeDir) {
11
+ const configPath = join(knowledgeDir, CONFIG_FILENAME);
12
+ let raw;
13
+ try {
14
+ raw = readFileSync(configPath, "utf-8");
15
+ }
16
+ catch {
17
+ // File doesn't exist — zero-config mode
18
+ return null;
19
+ }
20
+ try {
21
+ const parsed = parseYaml(raw);
22
+ if (!parsed || typeof parsed !== "object") {
23
+ log.warn("config", { error: "Config file is empty or not an object" });
24
+ return null;
25
+ }
26
+ return parsed;
27
+ }
28
+ catch (err) {
29
+ log.warn("config", {
30
+ error: `Failed to parse ${CONFIG_FILENAME}: ${err instanceof Error ? err.message : String(err)}`,
31
+ });
32
+ return null;
33
+ }
34
+ }
35
+ /**
36
+ * Discover domains by scanning top-level directories in the knowledge directory.
37
+ * Excludes directories starting with ".".
38
+ */
39
+ export function discoverDomains(knowledgeDir) {
40
+ try {
41
+ return readdirSync(knowledgeDir)
42
+ .filter((entry) => {
43
+ if (entry.startsWith("."))
44
+ return false;
45
+ try {
46
+ return statSync(join(knowledgeDir, entry)).isDirectory();
47
+ }
48
+ catch {
49
+ return false;
50
+ }
51
+ })
52
+ .sort();
53
+ }
54
+ catch {
55
+ return [];
56
+ }
57
+ }
58
+ /**
59
+ * Return the effective domain list for validation.
60
+ * - If config specifies domains, return them (strict validation).
61
+ * - Otherwise return null (permissive — accept any domain).
62
+ */
63
+ export function getEffectiveDomains(config, _knowledgeDir) {
64
+ if (config?.domains && config.domains.length > 0) {
65
+ return config.domains;
66
+ }
67
+ return null;
68
+ }
69
+ /**
70
+ * Return the effective phase IDs for validation.
71
+ * - If config specifies phases, return their IDs (strict validation).
72
+ * - Otherwise return null (permissive — accept any positive integer).
73
+ */
74
+ export function getEffectivePhaseIds(config) {
75
+ if (config?.phases && config.phases.length > 0) {
76
+ return config.phases.map((p) => p.id);
77
+ }
78
+ return null;
79
+ }
80
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAqBlC,MAAM,eAAe,GAAG,uBAAuB,CAAC;AAEhD;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,YAAoB;IAC7C,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,eAAe,CAAC,CAAC;IACvD,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,wCAAwC;QACxC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAY,CAAC;QACzC,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC1C,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,uCAAuC,EAAE,CAAC,CAAC;YACvE,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,MAAyB,CAAC;IACnC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE;YACjB,KAAK,EAAE,mBAAmB,eAAe,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;SACjG,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,YAAoB;IAClD,IAAI,CAAC;QACH,OAAO,WAAW,CAAC,YAAY,CAAC;aAC7B,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YAChB,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,OAAO,KAAK,CAAC;YACxC,IAAI,CAAC;gBACH,OAAO,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;YAC3D,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC,CAAC;aACD,IAAI,EAAE,CAAC;IACZ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CACjC,MAA8B,EAC9B,aAAqB;IAErB,IAAI,MAAM,EAAE,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjD,OAAO,MAAM,CAAC,OAAO,CAAC;IACxB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAA8B;IACjE,IAAI,MAAM,EAAE,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/C,OAAO,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACxC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,26 @@
1
+ import type { KnowledgeDocument } from "./loader.js";
2
+ export interface EmbeddingsStore {
3
+ vectors: Map<string, number[]>;
4
+ available: boolean;
5
+ }
6
+ export declare function loadEmbeddings(knowledgeDir: string): EmbeddingsStore;
7
+ export declare function cosineSimilarity(a: number[], b: number[]): number;
8
+ export declare function embedQuery(query: string): Promise<number[] | null>;
9
+ export declare function tokenize(text: string): string[];
10
+ export interface Bm25Index {
11
+ docTermFreqs: Map<string, Map<string, number>>;
12
+ docFreq: Map<string, number>;
13
+ idf: Map<string, number>;
14
+ docLengths: Map<string, number>;
15
+ avgDocLength: number;
16
+ docCount: number;
17
+ }
18
+ /** @deprecated Use Bm25Index — kept for backward compatibility */
19
+ export type TfIdfIndex = Bm25Index;
20
+ export declare function buildTfIdfIndex(docs: Map<string, KnowledgeDocument>): Bm25Index;
21
+ export declare function bm25Score(query: string, docId: string, index: Bm25Index): number;
22
+ /** @deprecated Use bm25Score — kept for backward compatibility */
23
+ export declare const tfidfScore: typeof bm25Score;
24
+ export declare function updateBm25Index(index: Bm25Index, docId: string, doc: KnowledgeDocument | null): void;
25
+ export declare function embedSingleDocument(embeddingsStore: EmbeddingsStore, knowledgeDir: string, doc: KnowledgeDocument): Promise<void>;
26
+ export declare function removeEmbedding(embeddingsStore: EmbeddingsStore, knowledgeDir: string, docId: string): void;