kirograph 0.20.1 → 0.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -3
- package/dist/bin/commands/data.js +52 -0
- package/dist/bin/commands/data.js.map +2 -2
- package/dist/bin/commands/docs.js +2 -1
- package/dist/bin/commands/docs.js.map +2 -2
- package/dist/bin/commands/gain.js +21 -1
- package/dist/bin/commands/gain.js.map +2 -2
- package/dist/bin/commands/status.js +23 -1
- package/dist/bin/commands/status.js.map +2 -2
- package/dist/bin/installer/config-prompt.js +30 -1
- package/dist/bin/installer/config-prompt.js.map +2 -2
- package/dist/bin/installer/index.js +108 -0
- package/dist/bin/installer/index.js.map +2 -2
- package/dist/bin/kirograph.js +1 -1
- package/dist/config.js +19 -2
- package/dist/config.js.map +2 -2
- package/dist/core/pipeline.js +3 -1
- package/dist/core/pipeline.js.map +2 -2
- package/dist/data/indexer.js +4 -4
- package/dist/data/indexer.js.map +2 -2
- package/dist/data/linker.js +9 -5
- package/dist/data/linker.js.map +2 -2
- package/dist/data/linker.test.js +60 -0
- package/dist/data/linker.test.js.map +7 -0
- package/dist/data/parsers/__fixtures__/pdf-inspector-stub.js +41 -0
- package/dist/data/parsers/__fixtures__/pdf-inspector-stub.js.map +7 -0
- package/dist/data/parsers/index.js +3 -1
- package/dist/data/parsers/index.js.map +2 -2
- package/dist/data/parsers/pdf.js +95 -0
- package/dist/data/parsers/pdf.js.map +7 -0
- package/dist/data/parsers/pdf.test.js +125 -0
- package/dist/data/parsers/pdf.test.js.map +7 -0
- package/dist/data/queries.js +39 -2
- package/dist/data/queries.js.map +2 -2
- package/dist/data/types.js.map +1 -1
- package/dist/db/data-schema.sql +2 -1
- package/dist/db/database.js +7 -0
- package/dist/db/database.js.map +2 -2
- package/dist/docs/indexer.js +2 -1
- package/dist/docs/indexer.js.map +2 -2
- package/dist/docs/queries.js +2 -1
- package/dist/docs/queries.js.map +2 -2
- package/dist/docs/vectors.js +46 -5
- package/dist/docs/vectors.js.map +2 -2
- package/dist/index.js +1 -0
- package/dist/index.js.map +2 -2
- package/dist/mcp/tools.js +1 -1
- package/dist/mcp/tools.js.map +2 -2
- package/dist/memory/index.js +2 -1
- package/dist/memory/index.js.map +2 -2
- package/dist/memory/vectors.js +52 -8
- package/dist/memory/vectors.js.map +3 -3
- package/dist/types.js.map +2 -2
- package/dist/vectors/index.js +66 -3
- package/dist/vectors/index.js.map +2 -2
- package/dist/vectors/turbovec-index.js +189 -0
- package/dist/vectors/turbovec-index.js.map +7 -0
- package/package.json +7 -1
package/dist/docs/vectors.js
CHANGED
|
@@ -32,6 +32,7 @@ __export(vectors_exports, {
|
|
|
32
32
|
});
|
|
33
33
|
module.exports = __toCommonJS(vectors_exports);
|
|
34
34
|
var import_errors = require("../errors");
|
|
35
|
+
var import_turboquant_index = require("../vectors/turboquant-index");
|
|
35
36
|
const MAX_TOKEN_CHARS = 2e3;
|
|
36
37
|
let transformers = null;
|
|
37
38
|
let pipeline = null;
|
|
@@ -69,13 +70,27 @@ function cosine(a, b) {
|
|
|
69
70
|
return denom === 0 ? 0 : dot / denom;
|
|
70
71
|
}
|
|
71
72
|
class DocsVectorManager {
|
|
72
|
-
constructor(config, db) {
|
|
73
|
+
constructor(config, db, kirographDir) {
|
|
74
|
+
this.tqIndex = null;
|
|
75
|
+
this.tqInitialized = false;
|
|
73
76
|
this.config = config;
|
|
74
77
|
this.db = db;
|
|
75
78
|
this.modelName = config.embeddingModel ?? "nomic-ai/nomic-embed-text-v1.5";
|
|
76
79
|
const { homedir } = require("os");
|
|
77
|
-
const
|
|
78
|
-
this.cacheDir =
|
|
80
|
+
const pathMod = require("path");
|
|
81
|
+
this.cacheDir = pathMod.join(homedir(), ".kirograph", "models");
|
|
82
|
+
if (kirographDir && config.turboquantMemDocs) {
|
|
83
|
+
const bits = config.turboquantBits ?? 3;
|
|
84
|
+
const dim = config.embeddingDim ?? 768;
|
|
85
|
+
this.tqIndex = new import_turboquant_index.TurboQuantIndex(kirographDir, "turboquant-doc.bin", dim, bits);
|
|
86
|
+
this._kirographDir = kirographDir;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/** Lazily initialize the TurboQuant index on first use. */
|
|
90
|
+
async ensureTQReady() {
|
|
91
|
+
if (this.tqInitialized) return;
|
|
92
|
+
this.tqInitialized = true;
|
|
93
|
+
if (this.tqIndex) await this.tqIndex.initialize();
|
|
79
94
|
}
|
|
80
95
|
/**
|
|
81
96
|
* Check if embeddings are enabled in config.
|
|
@@ -97,6 +112,10 @@ class DocsVectorManager {
|
|
|
97
112
|
"INSERT OR REPLACE INTO doc_vectors (section_id, embedding, model, created_at) VALUES (?, ?, ?, ?)",
|
|
98
113
|
[section.id, buffer, this.modelName, Date.now()]
|
|
99
114
|
);
|
|
115
|
+
if (this.tqIndex) {
|
|
116
|
+
await this.ensureTQReady();
|
|
117
|
+
this.tqIndex.upsert(section.id, embedding);
|
|
118
|
+
}
|
|
100
119
|
}
|
|
101
120
|
} catch (err) {
|
|
102
121
|
(0, import_errors.logWarn)(`Failed to embed doc section ${section.id}: ${err}`);
|
|
@@ -128,6 +147,13 @@ class DocsVectorManager {
|
|
|
128
147
|
try {
|
|
129
148
|
const queryEmbedding = await this.embed(query);
|
|
130
149
|
if (!queryEmbedding) return [];
|
|
150
|
+
if (this.tqIndex) {
|
|
151
|
+
await this.ensureTQReady();
|
|
152
|
+
if (this.tqIndex.isAvailable()) {
|
|
153
|
+
const hits = this.tqIndex.searchWithScores(queryEmbedding, limit);
|
|
154
|
+
return hits.map(({ id, score }) => ({ sectionId: id, score }));
|
|
155
|
+
}
|
|
156
|
+
}
|
|
131
157
|
const allVectors = this.db.all(
|
|
132
158
|
"SELECT section_id, embedding FROM doc_vectors WHERE model = ?",
|
|
133
159
|
[this.modelName]
|
|
@@ -140,8 +166,7 @@ class DocsVectorManager {
|
|
|
140
166
|
embedding.byteOffset,
|
|
141
167
|
embedding.byteLength / 4
|
|
142
168
|
);
|
|
143
|
-
|
|
144
|
-
scored.push({ sectionId: section_id, score });
|
|
169
|
+
scored.push({ sectionId: section_id, score: cosine(queryEmbedding, vec) });
|
|
145
170
|
}
|
|
146
171
|
scored.sort((a, b) => b.score - a.score);
|
|
147
172
|
return scored.slice(0, limit);
|
|
@@ -176,6 +201,10 @@ class DocsVectorManager {
|
|
|
176
201
|
*/
|
|
177
202
|
async reembed(batchSize = 32) {
|
|
178
203
|
this.db.run("DELETE FROM doc_vectors");
|
|
204
|
+
if (this.tqIndex) {
|
|
205
|
+
this.tqIndex.close();
|
|
206
|
+
this.tqInitialized = false;
|
|
207
|
+
}
|
|
179
208
|
const rows = this.db.all("SELECT * FROM doc_sections ORDER BY file_path, position");
|
|
180
209
|
const sections = rows.map((row) => ({
|
|
181
210
|
id: row.id,
|
|
@@ -196,6 +225,18 @@ class DocsVectorManager {
|
|
|
196
225
|
const batch = sections.slice(i, i + batchSize);
|
|
197
226
|
embedded += await this.embedBatch(batch);
|
|
198
227
|
}
|
|
228
|
+
if (this.tqIndex?.isAvailable() && this._kirographDir) {
|
|
229
|
+
await this.tqIndex.save();
|
|
230
|
+
const stats = this.tqIndex.memoryStats();
|
|
231
|
+
const dim = this.config.embeddingDim ?? 768;
|
|
232
|
+
const rawBytes = embedded * dim * 4;
|
|
233
|
+
(0, import_turboquant_index.writeTurboQuantStats)(this._kirographDir, {
|
|
234
|
+
docsEnabled: true,
|
|
235
|
+
docsCount: embedded,
|
|
236
|
+
docsActualBytes: stats.actualBytes,
|
|
237
|
+
docsRawBytes: rawBytes
|
|
238
|
+
});
|
|
239
|
+
}
|
|
199
240
|
return embedded;
|
|
200
241
|
}
|
|
201
242
|
// ── Private ────────────────────────────────────────────────────────────────
|
package/dist/docs/vectors.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/docs/vectors.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * KiroGraph Docs \u2014 Vector embedding and search\n *\n * Reuses the same embedding model and pipeline as the memory module,\n * but operates on doc_vectors table independently.\n */\n\nimport type { KiroGraphConfig } from '../config';\nimport type { DocSection, DocSearchResult } from './types';\nimport { logDebug, logWarn, logError } from '../errors';\n\nconst MAX_TOKEN_CHARS = 2000;\n\n// \u2500\u2500 Embedder (reuses the same pipeline as memory/code vectors) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nlet transformers: typeof import('@huggingface/transformers') | null = null;\nlet pipeline: any = null;\nlet pipelineModel: string | null = null;\n\nasync function getTransformers() {\n if (!transformers) {\n transformers = await import('@huggingface/transformers');\n }\n return transformers;\n}\n\nasync function getPipeline(modelName: string, cacheDir: string) {\n if (pipeline && pipelineModel === modelName) return pipeline;\n\n const tf = await getTransformers();\n pipeline = await tf.pipeline('feature-extraction', modelName, {\n cache_dir: cacheDir,\n dtype: 'fp32',\n } as any);\n pipelineModel = modelName;\n return pipeline;\n}\n\n/**\n * Build searchable text from a doc section.\n * Uses title + summary for embedding (concise, semantically rich).\n */\nfunction sectionToText(section: DocSection): string {\n const parts = [section.title];\n if (section.summary) parts.push(section.summary);\n const text = parts.join(': ');\n return text.length > MAX_TOKEN_CHARS ? text.slice(0, MAX_TOKEN_CHARS) : text;\n}\n\n/** Cosine similarity between two Float32Arrays */\nfunction cosine(a: Float32Array, b: Float32Array): number {\n let dot = 0, na = 0, nb = 0;\n for (let i = 0; i < a.length; i++) {\n dot += a[i] * b[i];\n na += a[i] * a[i];\n nb += b[i] * b[i];\n }\n const denom = Math.sqrt(na) * Math.sqrt(nb);\n return denom === 0 ? 0 : dot / denom;\n}\n\n// \u2500\u2500 DocsVectorManager \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport class DocsVectorManager {\n private config: KiroGraphConfig;\n private db: any; // raw SQLite handle\n private modelName: string;\n private cacheDir: string;\n\n constructor(config: KiroGraphConfig, db: any) {\n this.config = config;\n this.db = db;\n this.modelName = config.embeddingModel ?? 'nomic-ai/nomic-embed-text-v1.5';\n\n const { homedir } = require('os');\n const
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,oBAA4C;
|
|
4
|
+
"sourcesContent": ["/**\n * KiroGraph Docs \u2014 Vector embedding and search\n *\n * Reuses the same embedding model and pipeline as the memory module,\n * but operates on doc_vectors table independently.\n */\n\nimport type { KiroGraphConfig } from '../config';\nimport type { DocSection, DocSearchResult } from './types';\nimport { logDebug, logWarn, logError } from '../errors';\nimport { TurboQuantIndex, writeTurboQuantStats } from '../vectors/turboquant-index';\n\nconst MAX_TOKEN_CHARS = 2000;\n\n// \u2500\u2500 Embedder (reuses the same pipeline as memory/code vectors) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nlet transformers: typeof import('@huggingface/transformers') | null = null;\nlet pipeline: any = null;\nlet pipelineModel: string | null = null;\n\nasync function getTransformers() {\n if (!transformers) {\n transformers = await import('@huggingface/transformers');\n }\n return transformers;\n}\n\nasync function getPipeline(modelName: string, cacheDir: string) {\n if (pipeline && pipelineModel === modelName) return pipeline;\n\n const tf = await getTransformers();\n pipeline = await tf.pipeline('feature-extraction', modelName, {\n cache_dir: cacheDir,\n dtype: 'fp32',\n } as any);\n pipelineModel = modelName;\n return pipeline;\n}\n\n/**\n * Build searchable text from a doc section.\n * Uses title + summary for embedding (concise, semantically rich).\n */\nfunction sectionToText(section: DocSection): string {\n const parts = [section.title];\n if (section.summary) parts.push(section.summary);\n const text = parts.join(': ');\n return text.length > MAX_TOKEN_CHARS ? text.slice(0, MAX_TOKEN_CHARS) : text;\n}\n\n/** Cosine similarity between two Float32Arrays */\nfunction cosine(a: Float32Array, b: Float32Array): number {\n let dot = 0, na = 0, nb = 0;\n for (let i = 0; i < a.length; i++) {\n dot += a[i] * b[i];\n na += a[i] * a[i];\n nb += b[i] * b[i];\n }\n const denom = Math.sqrt(na) * Math.sqrt(nb);\n return denom === 0 ? 0 : dot / denom;\n}\n\n// \u2500\u2500 DocsVectorManager \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport class DocsVectorManager {\n private config: KiroGraphConfig;\n private db: any; // raw SQLite handle\n private modelName: string;\n private cacheDir: string;\n private tqIndex: TurboQuantIndex | null = null;\n private tqInitialized = false;\n private _kirographDir: string | undefined;\n\n constructor(config: KiroGraphConfig, db: any, kirographDir?: string) {\n this.config = config;\n this.db = db;\n this.modelName = config.embeddingModel ?? 'nomic-ai/nomic-embed-text-v1.5';\n\n const { homedir } = require('os');\n const pathMod = require('path');\n this.cacheDir = pathMod.join(homedir(), '.kirograph', 'models');\n\n if (kirographDir && (config as any).turboquantMemDocs) {\n const bits = (config as any).turboquantBits ?? 3;\n const dim = config.embeddingDim ?? 768;\n this.tqIndex = new TurboQuantIndex(kirographDir, 'turboquant-doc.bin', dim, bits);\n this._kirographDir = kirographDir;\n }\n }\n\n /** Lazily initialize the TurboQuant index on first use. */\n private async ensureTQReady(): Promise<void> {\n if (this.tqInitialized) return;\n this.tqInitialized = true;\n if (this.tqIndex) await this.tqIndex.initialize();\n }\n\n /**\n * Check if embeddings are enabled in config.\n */\n isEnabled(): boolean {\n return !!this.config.enableEmbeddings;\n }\n\n /**\n * Embed a single doc section and store in doc_vectors.\n */\n async embedSection(section: DocSection): Promise<void> {\n if (!this.isEnabled()) return;\n\n try {\n const text = sectionToText(section);\n const embedding = await this.embed(text);\n if (embedding) {\n const buffer = Buffer.from(embedding.buffer);\n this.db.run(\n 'INSERT OR REPLACE INTO doc_vectors (section_id, embedding, model, created_at) VALUES (?, ?, ?, ?)',\n [section.id, buffer, this.modelName, Date.now()],\n );\n if (this.tqIndex) {\n await this.ensureTQReady();\n this.tqIndex.upsert(section.id, embedding);\n }\n }\n } catch (err) {\n logWarn(`Failed to embed doc section ${section.id}: ${err}`);\n }\n }\n\n /**\n * Embed multiple sections in batch.\n */\n async embedBatch(sections: DocSection[]): Promise<number> {\n if (!this.isEnabled()) return 0;\n\n let embedded = 0;\n for (const section of sections) {\n try {\n await this.embedSection(section);\n embedded++;\n } catch (err) {\n logWarn(`Failed to embed doc section ${section.id}: ${err}`);\n }\n }\n return embedded;\n }\n\n /**\n * Vector search over doc sections.\n * Returns scored sections sorted by cosine similarity.\n * Falls back to empty results if embeddings are disabled.\n */\n async search(query: string, limit = 10): Promise<Array<{ sectionId: string; score: number }>> {\n if (!this.isEnabled()) return [];\n\n try {\n const queryEmbedding = await this.embed(query);\n if (!queryEmbedding) return [];\n\n // ANN path: TurboQuant index replaces the O(n) linear scan\n if (this.tqIndex) {\n await this.ensureTQReady();\n if (this.tqIndex.isAvailable()) {\n const hits = this.tqIndex.searchWithScores(queryEmbedding, limit);\n return hits.map(({ id, score }) => ({ sectionId: id, score }));\n }\n }\n\n // Fallback: linear cosine scan over all stored embeddings\n const allVectors = this.db.all(\n 'SELECT section_id, embedding FROM doc_vectors WHERE model = ?',\n [this.modelName],\n ) as Array<{ section_id: string; embedding: Buffer }>;\n\n if (allVectors.length === 0) return [];\n\n const scored: Array<{ sectionId: string; score: number }> = [];\n for (const { section_id, embedding } of allVectors) {\n const vec = new Float32Array(\n embedding.buffer,\n embedding.byteOffset,\n embedding.byteLength / 4,\n );\n scored.push({ sectionId: section_id, score: cosine(queryEmbedding, vec) });\n }\n\n scored.sort((a, b) => b.score - a.score);\n return scored.slice(0, limit);\n } catch (err) {\n logError('Docs vector search failed', { error: err });\n return [];\n }\n }\n\n /**\n * Check if there are vectors with a mismatched model.\n */\n hasModelMismatch(): boolean {\n const mismatch = this.db.get(\n 'SELECT COUNT(*) as cnt FROM doc_vectors WHERE model != ?',\n [this.modelName],\n )?.cnt ?? 0;\n return mismatch > 0;\n }\n\n /**\n * Get vector stats.\n */\n getStats(): { total: number; currentModel: number; mismatch: number } {\n const total = this.db.get('SELECT COUNT(*) as cnt FROM doc_vectors')?.cnt ?? 0;\n const currentModel = this.db.get(\n 'SELECT COUNT(*) as cnt FROM doc_vectors WHERE model = ?',\n [this.modelName],\n )?.cnt ?? 0;\n return { total, currentModel, mismatch: total - currentModel };\n }\n\n /**\n * Re-embed all doc sections with the current model.\n */\n async reembed(batchSize = 32): Promise<number> {\n // Delete all existing doc vectors\n this.db.run('DELETE FROM doc_vectors');\n\n // Reset TurboQuant index so it rebuilds from scratch\n if (this.tqIndex) {\n this.tqIndex.close();\n this.tqInitialized = false;\n }\n\n // Get all sections\n const rows = this.db.all('SELECT * FROM doc_sections ORDER BY file_path, position') as any[];\n const sections: DocSection[] = rows.map((row: any) => ({\n id: row.id,\n filePath: row.file_path,\n title: row.title,\n level: row.level,\n parentId: row.parent_id ?? null,\n summary: row.summary ?? null,\n byteStart: row.byte_start,\n byteEnd: row.byte_end,\n contentHash: row.content_hash,\n tags: row.tags ? JSON.parse(row.tags) : [],\n position: row.position,\n updatedAt: row.updated_at,\n }));\n\n let embedded = 0;\n for (let i = 0; i < sections.length; i += batchSize) {\n const batch = sections.slice(i, i + batchSize);\n embedded += await this.embedBatch(batch);\n }\n\n if (this.tqIndex?.isAvailable() && this._kirographDir) {\n await this.tqIndex.save();\n const stats = this.tqIndex.memoryStats();\n const dim = this.config.embeddingDim ?? 768;\n const rawBytes = embedded * dim * 4;\n writeTurboQuantStats(this._kirographDir, {\n docsEnabled: true,\n docsCount: embedded,\n docsActualBytes: stats.actualBytes,\n docsRawBytes: rawBytes,\n });\n }\n\n return embedded;\n }\n\n // \u2500\u2500 Private \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n private async embed(text: string): Promise<Float32Array | null> {\n try {\n const pipe = await getPipeline(this.modelName, this.cacheDir);\n const output = await pipe(text, { pooling: 'mean', normalize: true });\n return output.data as Float32Array;\n } catch (err) {\n logDebug(`Doc embedding failed: ${err}`);\n return null;\n }\n }\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,oBAA4C;AAC5C,8BAAsD;AAEtD,MAAM,kBAAkB;AAIxB,IAAI,eAAkE;AACtE,IAAI,WAAgB;AACpB,IAAI,gBAA+B;AAEnC,eAAe,kBAAkB;AAC/B,MAAI,CAAC,cAAc;AACjB,mBAAe,MAAM,OAAO,2BAA2B;AAAA,EACzD;AACA,SAAO;AACT;AAEA,eAAe,YAAY,WAAmB,UAAkB;AAC9D,MAAI,YAAY,kBAAkB,UAAW,QAAO;AAEpD,QAAM,KAAK,MAAM,gBAAgB;AACjC,aAAW,MAAM,GAAG,SAAS,sBAAsB,WAAW;AAAA,IAC5D,WAAW;AAAA,IACX,OAAO;AAAA,EACT,CAAQ;AACR,kBAAgB;AAChB,SAAO;AACT;AAMA,SAAS,cAAc,SAA6B;AAClD,QAAM,QAAQ,CAAC,QAAQ,KAAK;AAC5B,MAAI,QAAQ,QAAS,OAAM,KAAK,QAAQ,OAAO;AAC/C,QAAM,OAAO,MAAM,KAAK,IAAI;AAC5B,SAAO,KAAK,SAAS,kBAAkB,KAAK,MAAM,GAAG,eAAe,IAAI;AAC1E;AAGA,SAAS,OAAO,GAAiB,GAAyB;AACxD,MAAI,MAAM,GAAG,KAAK,GAAG,KAAK;AAC1B,WAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;AACjC,WAAO,EAAE,CAAC,IAAI,EAAE,CAAC;AACjB,UAAM,EAAE,CAAC,IAAI,EAAE,CAAC;AAChB,UAAM,EAAE,CAAC,IAAI,EAAE,CAAC;AAAA,EAClB;AACA,QAAM,QAAQ,KAAK,KAAK,EAAE,IAAI,KAAK,KAAK,EAAE;AAC1C,SAAO,UAAU,IAAI,IAAI,MAAM;AACjC;AAIO,MAAM,kBAAkB;AAAA,EAS7B,YAAY,QAAyB,IAAS,cAAuB;AAJrE,SAAQ,UAAkC;AAC1C,SAAQ,gBAAgB;AAItB,SAAK,SAAS;AACd,SAAK,KAAK;AACV,SAAK,YAAY,OAAO,kBAAkB;AAE1C,UAAM,EAAE,QAAQ,IAAI,QAAQ,IAAI;AAChC,UAAM,UAAU,QAAQ,MAAM;AAC9B,SAAK,WAAW,QAAQ,KAAK,QAAQ,GAAG,cAAc,QAAQ;AAE9D,QAAI,gBAAiB,OAAe,mBAAmB;AACrD,YAAM,OAAQ,OAAe,kBAAkB;AAC/C,YAAM,MAAM,OAAO,gBAAgB;AACnC,WAAK,UAAU,IAAI,wCAAgB,cAAc,sBAAsB,KAAK,IAAI;AAChF,WAAK,gBAAgB;AAAA,IACvB;AAAA,EACF;AAAA;AAAA,EAGA,MAAc,gBAA+B;AAC3C,QAAI,KAAK,cAAe;AACxB,SAAK,gBAAgB;AACrB,QAAI,KAAK,QAAS,OAAM,KAAK,QAAQ,WAAW;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA,EAKA,YAAqB;AACnB,WAAO,CAAC,CAAC,KAAK,OAAO;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAAa,SAAoC;AACrD,QAAI,CAAC,KAAK,UAAU,EAAG;AAEvB,QAAI;AACF,YAAM,OAAO,cAAc,OAAO;AAClC,YAAM,YAAY,MAAM,KAAK,MAAM,IAAI;AACvC,UAAI,WAAW;AACb,cAAM,SAAS,OAAO,KAAK,UAAU,MAAM;AAC3C,aAAK,GAAG;AAAA,UACN;AAAA,UACA,CAAC,QAAQ,IAAI,QAAQ,KAAK,WAAW,KAAK,IAAI,CAAC;AAAA,QACjD;AACA,YAAI,KAAK,SAAS;AAChB,gBAAM,KAAK,cAAc;AACzB,eAAK,QAAQ,OAAO,QAAQ,IAAI,SAAS;AAAA,QAC3C;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,iCAAQ,+BAA+B,QAAQ,EAAE,KAAK,GAAG,EAAE;AAAA,IAC7D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WAAW,UAAyC;AACxD,QAAI,CAAC,KAAK,UAAU,EAAG,QAAO;AAE9B,QAAI,WAAW;AACf,eAAW,WAAW,UAAU;AAC9B,UAAI;AACF,cAAM,KAAK,aAAa,OAAO;AAC/B;AAAA,MACF,SAAS,KAAK;AACZ,mCAAQ,+BAA+B,QAAQ,EAAE,KAAK,GAAG,EAAE;AAAA,MAC7D;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,OAAO,OAAe,QAAQ,IAA0D;AAC5F,QAAI,CAAC,KAAK,UAAU,EAAG,QAAO,CAAC;AAE/B,QAAI;AACF,YAAM,iBAAiB,MAAM,KAAK,MAAM,KAAK;AAC7C,UAAI,CAAC,eAAgB,QAAO,CAAC;AAG7B,UAAI,KAAK,SAAS;AAChB,cAAM,KAAK,cAAc;AACzB,YAAI,KAAK,QAAQ,YAAY,GAAG;AAC9B,gBAAM,OAAO,KAAK,QAAQ,iBAAiB,gBAAgB,KAAK;AAChE,iBAAO,KAAK,IAAI,CAAC,EAAE,IAAI,MAAM,OAAO,EAAE,WAAW,IAAI,MAAM,EAAE;AAAA,QAC/D;AAAA,MACF;AAGA,YAAM,aAAa,KAAK,GAAG;AAAA,QACzB;AAAA,QACA,CAAC,KAAK,SAAS;AAAA,MACjB;AAEA,UAAI,WAAW,WAAW,EAAG,QAAO,CAAC;AAErC,YAAM,SAAsD,CAAC;AAC7D,iBAAW,EAAE,YAAY,UAAU,KAAK,YAAY;AAClD,cAAM,MAAM,IAAI;AAAA,UACd,UAAU;AAAA,UACV,UAAU;AAAA,UACV,UAAU,aAAa;AAAA,QACzB;AACA,eAAO,KAAK,EAAE,WAAW,YAAY,OAAO,OAAO,gBAAgB,GAAG,EAAE,CAAC;AAAA,MAC3E;AAEA,aAAO,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AACvC,aAAO,OAAO,MAAM,GAAG,KAAK;AAAA,IAC9B,SAAS,KAAK;AACZ,kCAAS,6BAA6B,EAAE,OAAO,IAAI,CAAC;AACpD,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,mBAA4B;AAC1B,UAAM,WAAW,KAAK,GAAG;AAAA,MACvB;AAAA,MACA,CAAC,KAAK,SAAS;AAAA,IACjB,GAAG,OAAO;AACV,WAAO,WAAW;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA,EAKA,WAAsE;AACpE,UAAM,QAAQ,KAAK,GAAG,IAAI,yCAAyC,GAAG,OAAO;AAC7E,UAAM,eAAe,KAAK,GAAG;AAAA,MAC3B;AAAA,MACA,CAAC,KAAK,SAAS;AAAA,IACjB,GAAG,OAAO;AACV,WAAO,EAAE,OAAO,cAAc,UAAU,QAAQ,aAAa;AAAA,EAC/D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAQ,YAAY,IAAqB;AAE7C,SAAK,GAAG,IAAI,yBAAyB;AAGrC,QAAI,KAAK,SAAS;AAChB,WAAK,QAAQ,MAAM;AACnB,WAAK,gBAAgB;AAAA,IACvB;AAGA,UAAM,OAAO,KAAK,GAAG,IAAI,yDAAyD;AAClF,UAAM,WAAyB,KAAK,IAAI,CAAC,SAAc;AAAA,MACrD,IAAI,IAAI;AAAA,MACR,UAAU,IAAI;AAAA,MACd,OAAO,IAAI;AAAA,MACX,OAAO,IAAI;AAAA,MACX,UAAU,IAAI,aAAa;AAAA,MAC3B,SAAS,IAAI,WAAW;AAAA,MACxB,WAAW,IAAI;AAAA,MACf,SAAS,IAAI;AAAA,MACb,aAAa,IAAI;AAAA,MACjB,MAAM,IAAI,OAAO,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC;AAAA,MACzC,UAAU,IAAI;AAAA,MACd,WAAW,IAAI;AAAA,IACjB,EAAE;AAEF,QAAI,WAAW;AACf,aAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK,WAAW;AACnD,YAAM,QAAQ,SAAS,MAAM,GAAG,IAAI,SAAS;AAC7C,kBAAY,MAAM,KAAK,WAAW,KAAK;AAAA,IACzC;AAEA,QAAI,KAAK,SAAS,YAAY,KAAK,KAAK,eAAe;AACrD,YAAM,KAAK,QAAQ,KAAK;AACxB,YAAM,QAAQ,KAAK,QAAQ,YAAY;AACvC,YAAM,MAAM,KAAK,OAAO,gBAAgB;AACxC,YAAM,WAAW,WAAW,MAAM;AAClC,wDAAqB,KAAK,eAAe;AAAA,QACvC,aAAa;AAAA,QACb,WAAW;AAAA,QACX,iBAAiB,MAAM;AAAA,QACvB,cAAc;AAAA,MAChB,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT;AAAA;AAAA,EAIA,MAAc,MAAM,MAA4C;AAC9D,QAAI;AACF,YAAM,OAAO,MAAM,YAAY,KAAK,WAAW,KAAK,QAAQ;AAC5D,YAAM,SAAS,MAAM,KAAK,MAAM,EAAE,SAAS,QAAQ,WAAW,KAAK,CAAC;AACpE,aAAO,OAAO;AAAA,IAChB,SAAS,KAAK;AACZ,kCAAS,yBAAyB,GAAG,EAAE;AACvC,aAAO;AAAA,IACT;AAAA,EACF;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/index.js
CHANGED
|
@@ -246,6 +246,7 @@ class KiroGraph {
|
|
|
246
246
|
embeddingModel: this.config.embeddingModel,
|
|
247
247
|
useVecIndex: this.config.useVecIndex ?? false,
|
|
248
248
|
semanticEngine: this.config.semanticEngine ?? "cosine",
|
|
249
|
+
turbovecBits: this.config.turbovecBits,
|
|
249
250
|
vecIndexCount,
|
|
250
251
|
engineFallback: this.vectors.getEngineFallback(),
|
|
251
252
|
frameworks: this.config.frameworkHints ?? [],
|
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * KiroGraph \u2014 Semantic code knowledge graph for Kiro\n *\n * Pure facade. Every method delegates to a focused sub-system.\n * No business logic lives here.\n */\n\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport { GraphDatabase } from './db/database';\nimport { validatePathWithinRoot, validateProjectPath } from './utils';\nimport { loadConfig, createDefaultConfig, saveConfig } from './config';\nimport type { KiroGraphConfig } from './config';\nimport { GraphQueryManager } from './graph/queries';\nimport { ReferenceResolver } from './resolution/index';\nimport { VectorManager } from './vectors/index';\nimport { ContextBuilder } from './context/index';\nimport { ArchitectureAnalyzer } from './architecture/index';\nimport { LockManager } from './core/lock-manager';\nimport { IndexPipeline } from './core/pipeline';\nimport { buildFileTree } from './core/file-tree';\nimport { SnapshotManager } from './core/snapshot';\nimport { Searcher } from './search/searcher';\nimport type { FileTreeNode, FileTree } from './core/file-tree';\nimport type { GraphSnapshot, GraphDiff } from './core/snapshot';\n\nexport type { GraphSnapshot, GraphDiff };\nimport type {\n Node, Edge, NodeKind, IndexResult, IndexProgress, SyncResult, TaskContext,\n SearchResult, SearchOptions, NodeContext, NodeMetrics,\n} from './types';\nimport type { ArchitectureResult } from './architecture/types';\n\nexport type { FileTreeNode, FileTree };\n\nconst KIROGRAPH_DIR = '.kirograph';\n\nexport default class KiroGraph {\n private readonly db: GraphDatabase;\n private readonly config: KiroGraphConfig;\n private readonly projectRoot: string;\n private readonly queryManager: GraphQueryManager;\n private readonly resolver: ReferenceResolver;\n private readonly vectors: VectorManager;\n private readonly contextBuilder: ContextBuilder;\n private readonly arch: ArchitectureAnalyzer;\n private readonly lock: LockManager;\n private readonly pipeline: IndexPipeline;\n private readonly searcher: Searcher;\n\n private constructor(projectRoot: string, db: GraphDatabase, config: KiroGraphConfig) {\n this.projectRoot = projectRoot;\n this.db = db;\n this.config = config;\n this.queryManager = new GraphQueryManager(db);\n this.resolver = new ReferenceResolver(db, config, projectRoot);\n this.vectors = new VectorManager(db, config, projectRoot);\n this.contextBuilder = new ContextBuilder(db, this.resolver, this.vectors, projectRoot);\n this.arch = new ArchitectureAnalyzer(db, config, projectRoot);\n this.lock = new LockManager(projectRoot);\n this.pipeline = new IndexPipeline(db, this.vectors, this.resolver, this.arch, this.lock, config, projectRoot);\n this.searcher = new Searcher(db);\n }\n\n // \u2500\u2500 Factory \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n static async init(\n projectRoot: string,\n config?: Partial<KiroGraphConfig>,\n onModelProgress?: (file: string, loaded: number, total: number, done: boolean) => void,\n ): Promise<KiroGraph> {\n const resolved = path.resolve(projectRoot);\n validateProjectPath(resolved);\n fs.mkdirSync(path.join(resolved, KIROGRAPH_DIR), { recursive: true });\n const cfg = { ...createDefaultConfig(resolved), ...config };\n await saveConfig(resolved, cfg);\n const db = new GraphDatabase(resolved);\n const kg = new KiroGraph(resolved, db, cfg);\n await kg.vectors.initialize(onModelProgress);\n return kg;\n }\n\n static async open(\n projectRoot: string,\n onModelProgress?: (file: string, loaded: number, total: number, done: boolean) => void,\n ): Promise<KiroGraph> {\n const resolved = path.resolve(projectRoot);\n validateProjectPath(resolved);\n if (!fs.existsSync(path.join(resolved, KIROGRAPH_DIR))) {\n throw new Error(`KiroGraph not initialized at ${resolved}. Run: kirograph init`);\n }\n const cfg = await loadConfig(resolved);\n const db = new GraphDatabase(resolved);\n const kg = new KiroGraph(resolved, db, cfg);\n await kg.vectors.initialize(onModelProgress);\n return kg;\n }\n\n static isInitialized(projectRoot: string): boolean {\n return fs.existsSync(path.join(path.resolve(projectRoot), KIROGRAPH_DIR));\n }\n\n // \u2500\u2500 Lock / dirty marker \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n unlockForce(): void { this.lock.forceRelease(); }\n markDirty(): void { this.lock.markDirty(); }\n clearDirty(): void { this.lock.clearDirty(); }\n isDirty(): boolean { return this.lock.isDirty(); }\n isIndexLocked(): boolean { return this.lock.isLocked(); }\n\n async syncIfDirty(): Promise<SyncResult | null> {\n if (!this.isDirty()) return null;\n return this.sync();\n }\n\n /**\n * Returns the number of files that have changed on disk but are not yet\n * reflected in the index. Used by the MCP status tool to warn the agent\n * when the index may be stale.\n */\n async getPendingSyncCount(): Promise<number> {\n try {\n const { getChangedFiles, scanDirectory } = await Promise.resolve().then(() => require('./sync/index.js'));\n const gitChanged = await getChangedFiles(this.projectRoot, this.config);\n const hasGitChanges =\n gitChanged.added.length > 0 ||\n gitChanged.modified.length > 0 ||\n gitChanged.removed.length > 0;\n\n if (hasGitChanges) {\n return gitChanged.added.length + gitChanged.modified.length + gitChanged.removed.length;\n }\n\n // Fallback: compare indexed set vs current filesystem set\n const indexed = new Set(this.db.getAllFiles().map((f: { path: string }) => f.path));\n const current = new Set(\n (await scanDirectory(this.projectRoot, this.config))\n .map(f => require('path').relative(this.projectRoot, f).replace(/\\\\/g, '/'))\n );\n let pending = 0;\n for (const p of indexed) { if (!current.has(p)) pending++; }\n for (const p of current) { if (!indexed.has(p)) pending++; }\n return pending;\n } catch {\n return 0;\n }\n }\n\n // \u2500\u2500 Indexing \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n async indexAll(opts?: { onProgress?: (p: IndexProgress) => void; force?: boolean; signal?: AbortSignal }): Promise<IndexResult> {\n return this.pipeline.indexAll(opts);\n }\n\n async sync(changedFilesOrOpts?: string[] | { files?: string[]; onProgress?: (p: IndexProgress) => void }): Promise<SyncResult> {\n if (Array.isArray(changedFilesOrOpts)) {\n return this.pipeline.sync({ changedFiles: changedFilesOrOpts });\n }\n return this.pipeline.sync({\n changedFiles: changedFilesOrOpts?.files,\n onProgress: changedFilesOrOpts?.onProgress,\n });\n }\n\n // \u2500\u2500 Symbol search \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n searchNodes(query: string, kindOrOpts?: NodeKind | SearchOptions, limit = 20): SearchResult[] {\n return this.searcher.search(query, kindOrOpts, limit);\n }\n\n // \u2500\u2500 Graph queries \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n async getCallers(nodeId: string, limit = 30): Promise<Node[]> { return this.queryManager.getCallers(nodeId, limit); }\n async getCallees(nodeId: string, limit = 30): Promise<Node[]> { return this.queryManager.getCallees(nodeId, limit); }\n async getImpactRadius(nodeId: string, depth = 2): Promise<Node[]> { return this.queryManager.getImpactRadius(nodeId, depth); }\n getAllNodes(): Node[] { return this.db.getAllNodes(); }\n getAllEdges(): Edge[] { return this.db.getAllEdges(); }\n findDeadCode(limit = 50): Node[] { return this.db.findDeadCode(limit); }\n findCircularDependencies(): string[][] { return this.db.findCircularDependencies(); }\n async findPath(fromId: string, toId: string, maxDepth = 10): Promise<Node[]> { return this.queryManager.findPath(fromId, toId, maxDepth); }\n getTypeHierarchy(nodeId: string, direction: 'up' | 'down' | 'both' = 'both'): Node[] { return this.db.getTypeHierarchy(nodeId, direction); }\n getNode(id: string): Node | null { return this.db.getNode(id); }\n getNodeContext(nodeId: string): NodeContext | null { return this.db.getNodeContext(nodeId); }\n getNodeMetrics(nodeId: string): NodeMetrics { return this.db.getNodeMetrics(nodeId); }\n\n getNodeSource(node: Node): string | null {\n const absPath = validatePathWithinRoot(path.join(this.projectRoot, node.filePath), this.projectRoot);\n if (!absPath) return null;\n try {\n return fs.readFileSync(absPath, 'utf8').split('\\n').slice(node.startLine - 1, node.endLine).join('\\n');\n } catch { return null; }\n }\n\n // \u2500\u2500 Context building \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n async buildContext(task: string, opts?: { maxNodes?: number; includeCode?: boolean }): Promise<TaskContext> {\n return this.contextBuilder.buildTaskContext(task, opts);\n }\n\n // \u2500\u2500 File browsing \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n getFiles(opts?: { filterPath?: string; pattern?: string; maxDepth?: number }): FileTree {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const picomatch = opts?.pattern ? require('picomatch')(opts.pattern) : null;\n const filtered = this.db.getAllFiles().filter(f => {\n if (opts?.filterPath && !f.path.startsWith(opts.filterPath)) return false;\n if (picomatch && !picomatch(f.path)) return false;\n return true;\n });\n return buildFileTree(filtered, opts?.maxDepth);\n }\n\n getAffectedTests(changedFiles: string[], opts?: { depth?: number; testPattern?: string }): string[] {\n return this.queryManager.getAffectedTests(changedFiles, opts);\n }\n\n // \u2500\u2500 Graph insights \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n findHotspots(limit = 20): Array<Node & { degree: number; inDegree: number; outDegree: number }> {\n return this.db.findHotspots(limit);\n }\n\n findSurprisingConnections(limit = 20): Array<{ source: Node; target: Node; kind: string; score: number }> {\n return this.db.findSurprisingConnections(limit);\n }\n\n // \u2500\u2500 Snapshots \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n createSnapshotManager(): SnapshotManager {\n return new SnapshotManager(this.db, this.projectRoot);\n }\n\n // \u2500\u2500 Stats \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n async getStats() {\n const stats = this.db.getStats();\n const vecIndexCount = await this.vectors.vecIndexCount();\n const embeddingCount = vecIndexCount > 0 ? vecIndexCount : stats.embeddingCount;\n const EMBEDDABLE = ['function', 'method', 'class', 'interface', 'type_alias', 'component', 'module'];\n const embeddableNodeCount = EMBEDDABLE.reduce((sum, k) => sum + (stats.nodesByKind[k] ?? 0), 0);\n const pendingFiles = await this.getPendingSyncCount();\n const syncRunning = this.isIndexLocked();\n return {\n ...stats,\n embeddingCount,\n embeddableNodeCount,\n embeddingsEnabled: this.config.enableEmbeddings ?? false,\n embeddingModel: this.config.embeddingModel,\n useVecIndex: this.config.useVecIndex ?? false,\n semanticEngine: this.config.semanticEngine ?? 'cosine',\n vecIndexCount,\n engineFallback: this.vectors.getEngineFallback(),\n frameworks: this.config.frameworkHints ?? [],\n architectureEnabled: this.config.enableArchitecture ?? false,\n ...(this.config.enableArchitecture ? { architectureStats: this.db.getArchStats() } : {}),\n pendingFiles,\n syncRunning,\n syncWarningThreshold: this.config.syncWarningThreshold ?? 10,\n };\n }\n\n getEngineFallback(): string | null { return this.vectors.getEngineFallback(); }\n\n // \u2500\u2500 Architecture API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n getArchitecture(): ArchitectureResult & {\n filePackages: Record<string, string[]>;\n fileLayers: Record<string, Array<{ layerId: string; confidence: number; matchedPattern: string }>>;\n } {\n const base = this.db.getArchitectureResult();\n\n const filePackages: Record<string, string[]> = {};\n for (const { filePath, packageId } of this.db.getArchFilePackages()) {\n if (!filePackages[filePath]) filePackages[filePath] = [];\n filePackages[filePath].push(packageId);\n }\n\n const fileLayers: Record<string, Array<{ layerId: string; confidence: number; matchedPattern: string }>> = {};\n for (const row of this.db.getArchFileLayers()) {\n if (!fileLayers[row.filePath]) fileLayers[row.filePath] = [];\n fileLayers[row.filePath].push({ layerId: row.layerId, confidence: row.confidence, matchedPattern: row.matchedPattern });\n }\n\n return { ...base, filePackages, fileLayers };\n }\n\n isArchitectureEnabled(): boolean { return this.config.enableArchitecture ?? false; }\n\n // \u2500\u2500 Misc \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n getProjectRoot(): string { return this.projectRoot; }\n\n getDatabase(): GraphDatabase { return this.db; }\n\n close(): void {\n this.vectors.close();\n this.lock.release();\n this.db.close();\n }\n}\n\n// \u2500\u2500 Module-level helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Walk up directories to find the nearest .kirograph/ folder. */\nexport function findNearestKiroGraphRoot(startPath: string): string | null {\n let current = path.resolve(startPath);\n while (true) {\n if (fs.existsSync(path.join(current, KIROGRAPH_DIR))) return current;\n const parent = path.dirname(current);\n if (parent === current) return null;\n current = parent;\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/**\n * KiroGraph \u2014 Semantic code knowledge graph for Kiro\n *\n * Pure facade. Every method delegates to a focused sub-system.\n * No business logic lives here.\n */\n\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport { GraphDatabase } from './db/database';\nimport { validatePathWithinRoot, validateProjectPath } from './utils';\nimport { loadConfig, createDefaultConfig, saveConfig } from './config';\nimport type { KiroGraphConfig } from './config';\nimport { GraphQueryManager } from './graph/queries';\nimport { ReferenceResolver } from './resolution/index';\nimport { VectorManager } from './vectors/index';\nimport { ContextBuilder } from './context/index';\nimport { ArchitectureAnalyzer } from './architecture/index';\nimport { LockManager } from './core/lock-manager';\nimport { IndexPipeline } from './core/pipeline';\nimport { buildFileTree } from './core/file-tree';\nimport { SnapshotManager } from './core/snapshot';\nimport { Searcher } from './search/searcher';\nimport type { FileTreeNode, FileTree } from './core/file-tree';\nimport type { GraphSnapshot, GraphDiff } from './core/snapshot';\n\nexport type { GraphSnapshot, GraphDiff };\nimport type {\n Node, Edge, NodeKind, IndexResult, IndexProgress, SyncResult, TaskContext,\n SearchResult, SearchOptions, NodeContext, NodeMetrics,\n} from './types';\nimport type { ArchitectureResult } from './architecture/types';\n\nexport type { FileTreeNode, FileTree };\n\nconst KIROGRAPH_DIR = '.kirograph';\n\nexport default class KiroGraph {\n private readonly db: GraphDatabase;\n private readonly config: KiroGraphConfig;\n private readonly projectRoot: string;\n private readonly queryManager: GraphQueryManager;\n private readonly resolver: ReferenceResolver;\n private readonly vectors: VectorManager;\n private readonly contextBuilder: ContextBuilder;\n private readonly arch: ArchitectureAnalyzer;\n private readonly lock: LockManager;\n private readonly pipeline: IndexPipeline;\n private readonly searcher: Searcher;\n\n private constructor(projectRoot: string, db: GraphDatabase, config: KiroGraphConfig) {\n this.projectRoot = projectRoot;\n this.db = db;\n this.config = config;\n this.queryManager = new GraphQueryManager(db);\n this.resolver = new ReferenceResolver(db, config, projectRoot);\n this.vectors = new VectorManager(db, config, projectRoot);\n this.contextBuilder = new ContextBuilder(db, this.resolver, this.vectors, projectRoot);\n this.arch = new ArchitectureAnalyzer(db, config, projectRoot);\n this.lock = new LockManager(projectRoot);\n this.pipeline = new IndexPipeline(db, this.vectors, this.resolver, this.arch, this.lock, config, projectRoot);\n this.searcher = new Searcher(db);\n }\n\n // \u2500\u2500 Factory \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n static async init(\n projectRoot: string,\n config?: Partial<KiroGraphConfig>,\n onModelProgress?: (file: string, loaded: number, total: number, done: boolean) => void,\n ): Promise<KiroGraph> {\n const resolved = path.resolve(projectRoot);\n validateProjectPath(resolved);\n fs.mkdirSync(path.join(resolved, KIROGRAPH_DIR), { recursive: true });\n const cfg = { ...createDefaultConfig(resolved), ...config };\n await saveConfig(resolved, cfg);\n const db = new GraphDatabase(resolved);\n const kg = new KiroGraph(resolved, db, cfg);\n await kg.vectors.initialize(onModelProgress);\n return kg;\n }\n\n static async open(\n projectRoot: string,\n onModelProgress?: (file: string, loaded: number, total: number, done: boolean) => void,\n ): Promise<KiroGraph> {\n const resolved = path.resolve(projectRoot);\n validateProjectPath(resolved);\n if (!fs.existsSync(path.join(resolved, KIROGRAPH_DIR))) {\n throw new Error(`KiroGraph not initialized at ${resolved}. Run: kirograph init`);\n }\n const cfg = await loadConfig(resolved);\n const db = new GraphDatabase(resolved);\n const kg = new KiroGraph(resolved, db, cfg);\n await kg.vectors.initialize(onModelProgress);\n return kg;\n }\n\n static isInitialized(projectRoot: string): boolean {\n return fs.existsSync(path.join(path.resolve(projectRoot), KIROGRAPH_DIR));\n }\n\n // \u2500\u2500 Lock / dirty marker \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n unlockForce(): void { this.lock.forceRelease(); }\n markDirty(): void { this.lock.markDirty(); }\n clearDirty(): void { this.lock.clearDirty(); }\n isDirty(): boolean { return this.lock.isDirty(); }\n isIndexLocked(): boolean { return this.lock.isLocked(); }\n\n async syncIfDirty(): Promise<SyncResult | null> {\n if (!this.isDirty()) return null;\n return this.sync();\n }\n\n /**\n * Returns the number of files that have changed on disk but are not yet\n * reflected in the index. Used by the MCP status tool to warn the agent\n * when the index may be stale.\n */\n async getPendingSyncCount(): Promise<number> {\n try {\n const { getChangedFiles, scanDirectory } = await Promise.resolve().then(() => require('./sync/index.js'));\n const gitChanged = await getChangedFiles(this.projectRoot, this.config);\n const hasGitChanges =\n gitChanged.added.length > 0 ||\n gitChanged.modified.length > 0 ||\n gitChanged.removed.length > 0;\n\n if (hasGitChanges) {\n return gitChanged.added.length + gitChanged.modified.length + gitChanged.removed.length;\n }\n\n // Fallback: compare indexed set vs current filesystem set\n const indexed = new Set(this.db.getAllFiles().map((f: { path: string }) => f.path));\n const current = new Set(\n (await scanDirectory(this.projectRoot, this.config))\n .map(f => require('path').relative(this.projectRoot, f).replace(/\\\\/g, '/'))\n );\n let pending = 0;\n for (const p of indexed) { if (!current.has(p)) pending++; }\n for (const p of current) { if (!indexed.has(p)) pending++; }\n return pending;\n } catch {\n return 0;\n }\n }\n\n // \u2500\u2500 Indexing \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n async indexAll(opts?: { onProgress?: (p: IndexProgress) => void; force?: boolean; signal?: AbortSignal }): Promise<IndexResult> {\n return this.pipeline.indexAll(opts);\n }\n\n async sync(changedFilesOrOpts?: string[] | { files?: string[]; onProgress?: (p: IndexProgress) => void }): Promise<SyncResult> {\n if (Array.isArray(changedFilesOrOpts)) {\n return this.pipeline.sync({ changedFiles: changedFilesOrOpts });\n }\n return this.pipeline.sync({\n changedFiles: changedFilesOrOpts?.files,\n onProgress: changedFilesOrOpts?.onProgress,\n });\n }\n\n // \u2500\u2500 Symbol search \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n searchNodes(query: string, kindOrOpts?: NodeKind | SearchOptions, limit = 20): SearchResult[] {\n return this.searcher.search(query, kindOrOpts, limit);\n }\n\n // \u2500\u2500 Graph queries \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n async getCallers(nodeId: string, limit = 30): Promise<Node[]> { return this.queryManager.getCallers(nodeId, limit); }\n async getCallees(nodeId: string, limit = 30): Promise<Node[]> { return this.queryManager.getCallees(nodeId, limit); }\n async getImpactRadius(nodeId: string, depth = 2): Promise<Node[]> { return this.queryManager.getImpactRadius(nodeId, depth); }\n getAllNodes(): Node[] { return this.db.getAllNodes(); }\n getAllEdges(): Edge[] { return this.db.getAllEdges(); }\n findDeadCode(limit = 50): Node[] { return this.db.findDeadCode(limit); }\n findCircularDependencies(): string[][] { return this.db.findCircularDependencies(); }\n async findPath(fromId: string, toId: string, maxDepth = 10): Promise<Node[]> { return this.queryManager.findPath(fromId, toId, maxDepth); }\n getTypeHierarchy(nodeId: string, direction: 'up' | 'down' | 'both' = 'both'): Node[] { return this.db.getTypeHierarchy(nodeId, direction); }\n getNode(id: string): Node | null { return this.db.getNode(id); }\n getNodeContext(nodeId: string): NodeContext | null { return this.db.getNodeContext(nodeId); }\n getNodeMetrics(nodeId: string): NodeMetrics { return this.db.getNodeMetrics(nodeId); }\n\n getNodeSource(node: Node): string | null {\n const absPath = validatePathWithinRoot(path.join(this.projectRoot, node.filePath), this.projectRoot);\n if (!absPath) return null;\n try {\n return fs.readFileSync(absPath, 'utf8').split('\\n').slice(node.startLine - 1, node.endLine).join('\\n');\n } catch { return null; }\n }\n\n // \u2500\u2500 Context building \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n async buildContext(task: string, opts?: { maxNodes?: number; includeCode?: boolean }): Promise<TaskContext> {\n return this.contextBuilder.buildTaskContext(task, opts);\n }\n\n // \u2500\u2500 File browsing \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n getFiles(opts?: { filterPath?: string; pattern?: string; maxDepth?: number }): FileTree {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const picomatch = opts?.pattern ? require('picomatch')(opts.pattern) : null;\n const filtered = this.db.getAllFiles().filter(f => {\n if (opts?.filterPath && !f.path.startsWith(opts.filterPath)) return false;\n if (picomatch && !picomatch(f.path)) return false;\n return true;\n });\n return buildFileTree(filtered, opts?.maxDepth);\n }\n\n getAffectedTests(changedFiles: string[], opts?: { depth?: number; testPattern?: string }): string[] {\n return this.queryManager.getAffectedTests(changedFiles, opts);\n }\n\n // \u2500\u2500 Graph insights \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n findHotspots(limit = 20): Array<Node & { degree: number; inDegree: number; outDegree: number }> {\n return this.db.findHotspots(limit);\n }\n\n findSurprisingConnections(limit = 20): Array<{ source: Node; target: Node; kind: string; score: number }> {\n return this.db.findSurprisingConnections(limit);\n }\n\n // \u2500\u2500 Snapshots \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n createSnapshotManager(): SnapshotManager {\n return new SnapshotManager(this.db, this.projectRoot);\n }\n\n // \u2500\u2500 Stats \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n async getStats() {\n const stats = this.db.getStats();\n const vecIndexCount = await this.vectors.vecIndexCount();\n const embeddingCount = vecIndexCount > 0 ? vecIndexCount : stats.embeddingCount;\n const EMBEDDABLE = ['function', 'method', 'class', 'interface', 'type_alias', 'component', 'module'];\n const embeddableNodeCount = EMBEDDABLE.reduce((sum, k) => sum + (stats.nodesByKind[k] ?? 0), 0);\n const pendingFiles = await this.getPendingSyncCount();\n const syncRunning = this.isIndexLocked();\n return {\n ...stats,\n embeddingCount,\n embeddableNodeCount,\n embeddingsEnabled: this.config.enableEmbeddings ?? false,\n embeddingModel: this.config.embeddingModel,\n useVecIndex: this.config.useVecIndex ?? false,\n semanticEngine: this.config.semanticEngine ?? 'cosine',\n turbovecBits: this.config.turbovecBits,\n vecIndexCount,\n engineFallback: this.vectors.getEngineFallback(),\n frameworks: this.config.frameworkHints ?? [],\n architectureEnabled: this.config.enableArchitecture ?? false,\n ...(this.config.enableArchitecture ? { architectureStats: this.db.getArchStats() } : {}),\n pendingFiles,\n syncRunning,\n syncWarningThreshold: this.config.syncWarningThreshold ?? 10,\n };\n }\n\n getEngineFallback(): string | null { return this.vectors.getEngineFallback(); }\n\n // \u2500\u2500 Architecture API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n getArchitecture(): ArchitectureResult & {\n filePackages: Record<string, string[]>;\n fileLayers: Record<string, Array<{ layerId: string; confidence: number; matchedPattern: string }>>;\n } {\n const base = this.db.getArchitectureResult();\n\n const filePackages: Record<string, string[]> = {};\n for (const { filePath, packageId } of this.db.getArchFilePackages()) {\n if (!filePackages[filePath]) filePackages[filePath] = [];\n filePackages[filePath].push(packageId);\n }\n\n const fileLayers: Record<string, Array<{ layerId: string; confidence: number; matchedPattern: string }>> = {};\n for (const row of this.db.getArchFileLayers()) {\n if (!fileLayers[row.filePath]) fileLayers[row.filePath] = [];\n fileLayers[row.filePath].push({ layerId: row.layerId, confidence: row.confidence, matchedPattern: row.matchedPattern });\n }\n\n return { ...base, filePackages, fileLayers };\n }\n\n isArchitectureEnabled(): boolean { return this.config.enableArchitecture ?? false; }\n\n // \u2500\u2500 Misc \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n getProjectRoot(): string { return this.projectRoot; }\n\n getDatabase(): GraphDatabase { return this.db; }\n\n close(): void {\n this.vectors.close();\n this.lock.release();\n this.db.close();\n }\n}\n\n// \u2500\u2500 Module-level helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Walk up directories to find the nearest .kirograph/ folder. */\nexport function findNearestKiroGraphRoot(startPath: string): string | null {\n let current = path.resolve(startPath);\n while (true) {\n if (fs.existsSync(path.join(current, KIROGRAPH_DIR))) return current;\n const parent = path.dirname(current);\n if (parent === current) return null;\n current = parent;\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/mcp/tools.js
CHANGED
|
@@ -1466,7 +1466,7 @@ ${result.content}`;
|
|
|
1466
1466
|
const semanticLines = stats.embeddingsEnabled ? [
|
|
1467
1467
|
` Semantic search: enabled`,
|
|
1468
1468
|
` Semantic model: ${stats.embeddingModel}`,
|
|
1469
|
-
` Semantic engine: ${stats.semanticEngine === "sqlite-vec" ? `sqlite-vec (${stats.vecIndexCount} entries in ANN index)` : stats.semanticEngine === "orama" ? `orama hybrid (${stats.vecIndexCount} docs in index)` : stats.semanticEngine === "pglite" ? `pglite+pgvector (${stats.vecIndexCount} rows in DB)` : stats.semanticEngine === "lancedb" ? `lancedb (${stats.vecIndexCount} entries in ANN index)` : stats.semanticEngine === "qdrant" ? `qdrant (${stats.vecIndexCount} points in collection)` : stats.semanticEngine === "typesense" ? `typesense (${stats.vecIndexCount} documents in collection)` : "in-process cosine"}`,
|
|
1469
|
+
` Semantic engine: ${stats.semanticEngine === "turboquant" ? `turboquant (${stats.vecIndexCount} entries \xB7 ANN)` : stats.semanticEngine === "turbovec" ? `turbovec (${stats.vecIndexCount} entries \xB7 ${stats.turbovecBits ?? 4} bits \xB7 Rust/SIMD)` : stats.semanticEngine === "sqlite-vec" ? `sqlite-vec (${stats.vecIndexCount} entries in ANN index)` : stats.semanticEngine === "orama" ? `orama hybrid (${stats.vecIndexCount} docs in index)` : stats.semanticEngine === "pglite" ? `pglite+pgvector (${stats.vecIndexCount} rows in DB)` : stats.semanticEngine === "lancedb" ? `lancedb (${stats.vecIndexCount} entries in ANN index)` : stats.semanticEngine === "qdrant" ? `qdrant (${stats.vecIndexCount} points in collection)` : stats.semanticEngine === "typesense" ? `typesense (${stats.vecIndexCount} documents in collection)` : "in-process cosine"}`,
|
|
1470
1470
|
` Embeddings: ${stats.embeddingCount} / ${stats.embeddableNodeCount || stats.nodes} embeddable symbols`,
|
|
1471
1471
|
...stats.engineFallback ? [` \u26A0 Engine fallback: ${stats.engineFallback}`] : []
|
|
1472
1472
|
] : [` Semantic search: disabled`];
|